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 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(ca_thread_pool_t handle)
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 g_threadPoolHandle = handle;
212 ret = CALEClientInitGattMutexVaraibles();
213 if (CA_STATUS_OK != ret)
215 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
216 CALEClientTerminateGattMutexVariables();
220 (*g_jvm)->DetachCurrentThread(g_jvm);
226 g_deviceDescCond = ca_cond_new();
228 // init mutex for send logic
229 g_threadCond = ca_cond_new();
231 CALEClientCreateDeviceList();
232 CALEClientJNISetContext();
234 ret = CALEClientCreateUUIDList();
235 if (CA_STATUS_OK != ret)
237 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
241 (*g_jvm)->DetachCurrentThread(g_jvm);
247 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
248 if (CA_STATUS_OK != ret)
250 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
254 (*g_jvm)->DetachCurrentThread(g_jvm);
259 g_isStartedLEClient = true;
263 (*g_jvm)->DetachCurrentThread(g_jvm);
269 void CALEClientTerminate()
271 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
275 OIC_LOG(ERROR, TAG, "g_jvm is null");
279 bool isAttached = false;
281 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
284 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
285 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
289 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
295 if (g_leScanCallback)
297 (*env)->DeleteGlobalRef(env, g_leScanCallback);
300 if (g_leGattCallback)
302 (*env)->DeleteGlobalRef(env, g_leGattCallback);
307 (*env)->DeleteGlobalRef(env, g_sendBuffer);
312 (*env)->DeleteGlobalRef(env, g_uuidList);
315 CAResult_t ret = CALEClientRemoveAllDeviceState();
316 if (CA_STATUS_OK != ret)
318 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
321 ret = CALEClientRemoveAllScanDevices(env);
322 if (CA_STATUS_OK != ret)
324 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
327 ret = CALEClientRemoveAllGattObjs(env);
328 if (CA_STATUS_OK != ret)
330 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
333 g_isStartedMulticastServer = false;
334 CALEClientSetScanFlag(false);
335 CALEClientSetSendFinishFlag(false);
337 CALEClientTerminateGattMutexVariables();
339 ca_cond_free(g_deviceDescCond);
340 ca_cond_free(g_threadCond);
342 g_deviceDescCond = NULL;
347 (*g_jvm)->DetachCurrentThread(g_jvm);
351 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
353 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
354 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
358 CAResult_t res = CALEClientDisconnect(env, gatt);
359 if (CA_STATUS_OK != res)
361 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
364 CALEClientUpdateSendCnt(env);
367 CAResult_t CALEClientSendUnicastMessage(const char* address,
369 const uint32_t dataLen)
371 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
372 VERIFY_NON_NULL(address, TAG, "address is null");
373 VERIFY_NON_NULL(data, TAG, "data is null");
375 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
378 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
379 const uint32_t dataLen)
381 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
382 VERIFY_NON_NULL(data, TAG, "data is null");
386 OIC_LOG(ERROR, TAG, "g_jvm is null");
387 return CA_STATUS_FAILED;
390 bool isAttached = false;
392 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
395 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
396 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
400 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
401 return CA_STATUS_FAILED;
406 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
407 if (CA_STATUS_OK != ret)
409 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
414 (*g_jvm)->DetachCurrentThread(g_jvm);
420 CAResult_t CALEClientStartUnicastServer(const char* address)
422 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
424 return CA_NOT_SUPPORTED;
427 CAResult_t CALEClientStartMulticastServer()
429 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
431 if (g_isStartedMulticastServer)
433 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
434 return CA_STATUS_FAILED;
439 OIC_LOG(ERROR, TAG, "g_jvm is null");
440 return CA_STATUS_FAILED;
443 bool isAttached = false;
445 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
448 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
449 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
453 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
454 return CA_STATUS_FAILED;
459 g_isStartedMulticastServer = true;
460 CAResult_t ret = CALEClientStartScan();
461 if (CA_STATUS_OK != ret)
463 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
468 (*g_jvm)->DetachCurrentThread(g_jvm);
474 void CALEClientStopUnicastServer()
476 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
479 void CALEClientStopMulticastServer()
481 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
482 g_isStartedMulticastServer = false;
483 CAResult_t res = CALEClientStopScan();
484 if (CA_STATUS_OK != res)
486 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
491 void CALEClientSetCallback(CAPacketReceiveCallback callback)
493 g_packetReceiveCallback = callback;
496 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
498 g_clientErrorCallback = callback;
501 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
502 const uint32_t dataLen)
504 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
506 VERIFY_NON_NULL(address, TAG, "address is null");
507 VERIFY_NON_NULL(data, TAG, "data is null");
511 OIC_LOG(ERROR, TAG, "g_jvm is null");
512 return CA_STATUS_FAILED;
515 bool isAttached = false;
517 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
520 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
521 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
524 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
525 return CA_STATUS_FAILED;
530 ca_mutex_lock(g_threadSendMutex);
532 CAResult_t ret = CA_STATUS_OK;
533 if (g_context && g_deviceList)
535 uint32_t length = u_arraylist_length(g_deviceList);
536 for (uint32_t index = 0; index < length; index++)
538 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
541 OIC_LOG(ERROR, TAG, "jarrayObj is null");
545 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
548 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
552 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
555 OIC_LOG(ERROR, TAG, "setAddress is null");
559 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
561 if (!strcmp(setAddress, address))
563 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
565 // connect to gatt server
566 ret = CALEClientStopScan();
567 if (CA_STATUS_OK != ret)
569 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
575 (*env)->DeleteGlobalRef(env, g_sendBuffer);
577 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
578 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
579 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
581 ret = CALEClientSendData(env, jarrayObj);
582 if (CA_STATUS_OK != ret)
584 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
588 OIC_LOG(INFO, TAG, "wake up");
591 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
597 (*g_jvm)->DetachCurrentThread(g_jvm);
600 // start LE Scan again
601 ret = CALEClientStartScan();
602 if (CA_STATUS_OK != ret)
604 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
605 ca_mutex_unlock(g_threadSendMutex);
609 ca_mutex_unlock(g_threadSendMutex);
610 OIC_LOG(INFO, TAG, "unicast - send success");
616 // start LE Scan again
617 ret = CALEClientStartScan();
618 if (CA_STATUS_OK != ret)
620 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
621 ca_mutex_unlock(g_threadSendMutex);
624 (*g_jvm)->DetachCurrentThread(g_jvm);
631 (*g_jvm)->DetachCurrentThread(g_jvm);
634 if (g_clientErrorCallback)
636 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
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 size_t 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 (*env)->ReleaseStringUTFChars(env, jni_address, address);
741 OIC_LOG(DEBUG, TAG, "connection routine is finished");
743 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
744 if (!g_isFinishedSendData)
746 ca_mutex_lock(g_threadMutex);
747 ca_cond_wait(g_threadCond, g_threadMutex);
748 OIC_LOG(DEBUG, TAG, "the data was sent for All devices");
749 ca_mutex_unlock(g_threadMutex);
752 // start LE Scan again
753 res = CALEClientStartScan();
754 if (CA_STATUS_OK != res)
756 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
757 ca_mutex_unlock(g_threadSendMutex);
761 ca_mutex_unlock(g_threadSendMutex);
762 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
766 res = CALEClientStartScan();
767 if (CA_STATUS_OK != res)
769 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
770 ca_mutex_unlock(g_threadSendMutex);
774 ca_mutex_unlock(g_threadSendMutex);
775 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
776 return CA_SEND_FAILED;
779 CAResult_t CALECheckSendState(const char* address)
781 VERIFY_NON_NULL(address, TAG, "address is null");
783 ca_mutex_lock(g_deviceStateListMutex);
784 CALEState_t* state = CALEClientGetStateInfo(address);
787 OIC_LOG(ERROR, TAG, "state is null");
788 ca_mutex_unlock(g_deviceStateListMutex);
789 return CA_SEND_FAILED;
792 if (STATE_SEND_SUCCESS != state->sendState)
794 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
795 ca_mutex_unlock(g_deviceStateListMutex);
796 return CA_SEND_FAILED;
798 ca_mutex_unlock(g_deviceStateListMutex);
802 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
804 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
805 VERIFY_NON_NULL(device, TAG, "device is null");
806 VERIFY_NON_NULL(env, TAG, "env is null");
808 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
811 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
812 return CA_STATUS_FAILED;
815 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
818 OIC_LOG(ERROR, TAG, "address is not available");
819 return CA_STATUS_FAILED;
822 ca_mutex_lock(g_deviceStateListMutex);
823 CALEState_t* state = CALEClientGetStateInfo(address);
824 ca_mutex_unlock(g_deviceStateListMutex);
827 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
828 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
829 if (CA_STATUS_OK != ret)
831 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
832 (*env)->ReleaseStringUTFChars(env, jni_address, address);
838 if (STATE_CONNECTED == state->connectedState)
840 OIC_LOG(INFO, TAG, "GATT has already connected");
841 jobject gatt = CALEClientGetGattObjInList(env, address);
844 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
845 (*env)->ReleaseStringUTFChars(env, jni_address, address);
846 return CA_STATUS_FAILED;
849 CAResult_t ret = CALEClientWriteCharacteristic(env, gatt);
850 if (CA_STATUS_OK != ret)
852 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
853 (*env)->ReleaseStringUTFChars(env, jni_address, address);
859 OIC_LOG(DEBUG, TAG, "start to connect LE");
860 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
861 if (CA_STATUS_OK != ret)
863 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
864 (*env)->ReleaseStringUTFChars(env, jni_address, address);
870 (*env)->ReleaseStringUTFChars(env, jni_address, address);
874 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
876 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
877 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
879 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
880 if (!jni_cid_gattdevice_list)
882 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
886 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
887 "()Landroid/bluetooth/BluetoothDevice;");
888 if (!jni_mid_getDevice)
890 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
894 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
897 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
901 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
904 OIC_LOG(ERROR, TAG, "jni_address is null");
914 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
917 OIC_LOG(DEBUG, TAG, "Gatt Close");
918 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
919 VERIFY_NON_NULL(env, TAG, "env is null");
921 // get BluetoothGatt class
922 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
923 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
924 if (!jni_cid_BluetoothGatt)
926 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
927 return CA_STATUS_FAILED;
930 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
931 if (!jni_mid_closeGatt)
933 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
937 // call disconnect gatt method
938 OIC_LOG(DEBUG, TAG, "request to close GATT");
939 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
941 if ((*env)->ExceptionCheck(env))
943 OIC_LOG(ERROR, TAG, "closeGATT has failed");
944 (*env)->ExceptionDescribe(env);
945 (*env)->ExceptionClear(env);
946 return CA_STATUS_FAILED;
952 CAResult_t CALEClientStartScan()
954 if (!g_isStartedMulticastServer)
956 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
957 return CA_STATUS_FAILED;
960 if (!g_isStartedLEClient)
962 OIC_LOG(ERROR, TAG, "LE client is not started");
963 return CA_STATUS_FAILED;
968 OIC_LOG(ERROR, TAG, "g_jvm is null");
969 return CA_STATUS_FAILED;
974 OIC_LOG(INFO, TAG, "scanning is already started");
978 bool isAttached = false;
980 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
983 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
985 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
988 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
989 return CA_STATUS_FAILED;
994 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
996 CAResult_t ret = CA_STATUS_OK;
997 // scan gatt server with UUID
998 if (g_leScanCallback && g_uuidList)
1001 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1002 if(CA_STATUS_OK != ret)
1004 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithUUIDImpl has failed");
1007 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1008 if (CA_STATUS_OK != ret)
1010 OIC_LOG(ERROR, TAG, "CALEClientStartScanImpl has failed");
1017 (*g_jvm)->DetachCurrentThread(g_jvm);
1023 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1025 VERIFY_NON_NULL(callback, TAG, "callback is null");
1026 VERIFY_NON_NULL(env, TAG, "env is null");
1028 if (!CALEIsEnableBTAdapter(env))
1030 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1031 return CA_ADAPTER_NOT_ENABLED;
1034 // get default bt adapter class
1035 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1036 if (!jni_cid_BTAdapter)
1038 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1039 return CA_STATUS_FAILED;
1042 // get remote bt adapter method
1043 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1044 "getDefaultAdapter",
1045 METHODID_OBJECTNONPARAM);
1046 if (!jni_mid_getDefaultAdapter)
1048 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1049 return CA_STATUS_FAILED;
1052 // get start le scan method
1053 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1054 "(Landroid/bluetooth/BluetoothAdapter$"
1055 "LeScanCallback;)Z");
1056 if (!jni_mid_startLeScan)
1058 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1059 return CA_STATUS_FAILED;
1062 // gat bt adapter object
1063 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1064 jni_mid_getDefaultAdapter);
1065 if (!jni_obj_BTAdapter)
1067 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1068 return CA_STATUS_FAILED;
1071 // call start le scan method
1072 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1073 jni_mid_startLeScan, callback);
1074 if (!jni_obj_startLeScan)
1076 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1077 return CA_STATUS_FAILED;
1081 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1082 CALEClientSetScanFlag(true);
1085 return CA_STATUS_OK;
1088 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1090 VERIFY_NON_NULL(callback, TAG, "callback is null");
1091 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1092 VERIFY_NON_NULL(env, TAG, "env is null");
1094 if (!CALEIsEnableBTAdapter(env))
1096 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1097 return CA_ADAPTER_NOT_ENABLED;
1100 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1101 if (!jni_cid_BTAdapter)
1103 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1104 return CA_STATUS_FAILED;
1107 // get remote bt adapter method
1108 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1109 "getDefaultAdapter",
1110 METHODID_OBJECTNONPARAM);
1111 if (!jni_mid_getDefaultAdapter)
1113 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1114 return CA_STATUS_FAILED;
1117 // get start le scan method
1118 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1119 "([Ljava/util/UUID;Landroid/bluetooth/"
1120 "BluetoothAdapter$LeScanCallback;)Z");
1121 if (!jni_mid_startLeScan)
1123 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1124 return CA_STATUS_FAILED;
1127 // get bt adapter object
1128 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1129 jni_mid_getDefaultAdapter);
1130 if (!jni_obj_BTAdapter)
1132 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1133 return CA_STATUS_FAILED;
1136 // call start le scan method
1137 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1138 jni_mid_startLeScan, uuids, callback);
1139 if (!jni_obj_startLeScan)
1141 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1142 return CA_STATUS_FAILED;
1146 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1147 CALEClientSetScanFlag(true);
1150 return CA_STATUS_OK;
1153 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1155 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1156 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1159 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1162 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1166 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1167 "(Ljava/lang/String;)"
1168 "Ljava/util/UUID;");
1169 if (!jni_mid_fromString)
1171 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1175 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1176 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1180 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1184 return jni_obj_uuid;
1187 CAResult_t CALEClientStopScan()
1191 OIC_LOG(ERROR, TAG, "g_jvm is null");
1192 return CA_STATUS_FAILED;
1195 if (!g_isStartedScan)
1197 OIC_LOG(INFO, TAG, "scanning is already stopped");
1198 return CA_STATUS_OK;
1201 bool isAttached = false;
1203 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1206 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1207 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1210 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1211 return CA_STATUS_FAILED;
1216 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1217 if (CA_STATUS_OK != ret)
1219 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1223 CALEClientSetScanFlag(false);
1228 (*g_jvm)->DetachCurrentThread(g_jvm);
1234 void CALEClientSetScanFlag(bool flag)
1236 ca_mutex_lock(g_scanMutex);
1237 g_isStartedScan = flag;
1238 ca_mutex_unlock(g_scanMutex);
1241 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1243 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1244 VERIFY_NON_NULL(callback, TAG, "callback is null");
1245 VERIFY_NON_NULL(env, TAG, "env is null");
1247 if (!CALEIsEnableBTAdapter(env))
1249 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1250 return CA_ADAPTER_NOT_ENABLED;
1253 // get default bt adapter class
1254 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1255 if (!jni_cid_BTAdapter)
1257 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1258 return CA_STATUS_FAILED;
1261 // get remote bt adapter method
1262 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1263 "getDefaultAdapter",
1264 METHODID_OBJECTNONPARAM);
1265 if (!jni_mid_getDefaultAdapter)
1267 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1268 return CA_STATUS_FAILED;
1271 // get start le scan method
1272 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1273 "(Landroid/bluetooth/"
1274 "BluetoothAdapter$LeScanCallback;)V");
1275 if (!jni_mid_stopLeScan)
1277 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1278 return CA_STATUS_FAILED;
1281 // gat bt adapter object
1282 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1283 jni_mid_getDefaultAdapter);
1284 if (!jni_obj_BTAdapter)
1286 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1287 return CA_STATUS_FAILED;
1290 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1291 // call start le scan method
1292 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1293 if ((*env)->ExceptionCheck(env))
1295 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1296 (*env)->ExceptionDescribe(env);
1297 (*env)->ExceptionClear(env);
1298 return CA_STATUS_FAILED;
1301 return CA_STATUS_OK;
1304 CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
1307 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1308 VERIFY_NON_NULL(env, TAG, "env is null");
1309 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1310 VERIFY_NON_NULL(callback, TAG, "callback is null");
1312 if (!CALEIsEnableBTAdapter(env))
1314 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1315 return CA_ADAPTER_NOT_ENABLED;
1318 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1321 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1322 return CA_STATUS_FAILED;
1325 // get BluetoothDevice class
1326 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1327 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1328 if (!jni_cid_BluetoothDevice)
1330 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1331 return CA_STATUS_FAILED;
1334 // get connectGatt method
1335 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1336 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1337 "(Landroid/content/Context;ZLandroid/"
1338 "bluetooth/BluetoothGattCallback;)"
1339 "Landroid/bluetooth/BluetoothGatt;");
1340 if (!jni_mid_connectGatt)
1342 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1343 return CA_STATUS_FAILED;
1346 OIC_LOG(DEBUG, TAG, "Call object method - connectGatt");
1347 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1348 jni_mid_connectGatt,
1350 autoconnect, callback);
1351 if (!jni_obj_connectGatt)
1353 OIC_LOG(ERROR, TAG, "CALL API - connectGatt was failed..it will be removed");
1354 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1355 CALEClientUpdateSendCnt(env);
1356 return CA_STATUS_FAILED;
1360 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1362 return CA_STATUS_OK;
1365 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1367 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1368 VERIFY_NON_NULL(env, TAG, "env is null");
1369 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1371 if (!CALEIsEnableBTAdapter(env))
1373 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1374 return CA_ADAPTER_NOT_ENABLED;
1377 // get BluetoothGatt class
1378 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1379 if (!jni_cid_BluetoothGatt)
1381 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1382 return CA_STATUS_FAILED;
1385 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1386 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1387 "disconnect", "()V");
1388 if (!jni_mid_disconnectGatt)
1390 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1391 return CA_STATUS_FAILED;
1394 // call disconnect gatt method
1395 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1396 if ((*env)->ExceptionCheck(env))
1398 OIC_LOG(ERROR, TAG, "disconnect has failed");
1399 (*env)->ExceptionDescribe(env);
1400 (*env)->ExceptionClear(env);
1401 return CA_STATUS_FAILED;
1404 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1406 return CA_STATUS_OK;
1409 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1411 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1412 VERIFY_NON_NULL(env, TAG, "env is null");
1414 if (!g_gattObjectList)
1416 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
1417 return CA_STATUS_FAILED;
1420 uint32_t length = u_arraylist_length(g_gattObjectList);
1421 for (uint32_t index = 0; index < length; index++)
1423 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1426 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1429 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1430 if (CA_STATUS_OK != res)
1432 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1437 OICFree(g_gattObjectList);
1438 g_gattObjectList = NULL;
1440 return CA_STATUS_OK;
1443 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1445 VERIFY_NON_NULL(env, TAG, "env is null");
1446 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1448 if (!CALEIsEnableBTAdapter(env))
1450 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1451 return CA_ADAPTER_NOT_ENABLED;
1454 // get BluetoothGatt class
1455 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1456 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1457 if (!jni_cid_BluetoothGatt)
1459 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1460 return CA_STATUS_FAILED;
1463 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1464 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1465 "discoverServices", "()Z");
1466 if (!jni_mid_discoverServices)
1468 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1469 return CA_STATUS_FAILED;
1471 // call disconnect gatt method
1472 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1473 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1476 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1477 return CA_STATUS_FAILED;
1480 return CA_STATUS_OK;
1483 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1485 VERIFY_NON_NULL(env, TAG, "env is null");
1486 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1489 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1490 if (!jni_obj_character)
1492 CALEClientSendFinish(env, gatt);
1493 return CA_STATUS_FAILED;
1496 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1497 if (CA_STATUS_OK != ret)
1499 CALEClientSendFinish(env, gatt);
1503 return CA_STATUS_OK;
1506 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1507 jobject gattCharacteristic)
1509 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1510 VERIFY_NON_NULL(env, TAG, "env is null");
1511 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1512 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1514 if (!CALEIsEnableBTAdapter(env))
1516 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1517 return CA_STATUS_FAILED;
1520 // get BluetoothGatt class
1521 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1522 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1523 if (!jni_cid_BluetoothGatt)
1525 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1526 return CA_STATUS_FAILED;
1529 OIC_LOG(DEBUG, TAG, "write characteristic method");
1530 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1531 "writeCharacteristic",
1532 "(Landroid/bluetooth/"
1533 "BluetoothGattCharacteristic;)Z");
1534 if (!jni_mid_writeCharacteristic)
1536 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
1537 return CA_STATUS_FAILED;
1540 // call disconnect gatt method
1541 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
1542 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
1543 jni_mid_writeCharacteristic,
1544 gattCharacteristic);
1547 OIC_LOG(DEBUG, TAG, "writeCharacteristic success");
1551 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
1552 return CA_STATUS_FAILED;
1555 return CA_STATUS_OK;
1558 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1560 VERIFY_NON_NULL(env, TAG, "env is null");
1561 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1563 if (!CALEIsEnableBTAdapter(env))
1565 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1566 return CA_STATUS_FAILED;
1569 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1570 if (!jni_cid_BluetoothGatt)
1572 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1573 return CA_STATUS_FAILED;
1576 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1579 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1580 return CA_STATUS_FAILED;
1583 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1584 if (!jni_obj_GattCharacteristic)
1586 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1587 return CA_STATUS_FAILED;
1590 OIC_LOG(DEBUG, TAG, "read characteristic method");
1591 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1592 "readCharacteristic",
1593 "(Landroid/bluetooth/"
1594 "BluetoothGattCharacteristic;)Z");
1595 if (!jni_mid_readCharacteristic)
1597 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
1598 return CA_STATUS_FAILED;
1601 // call disconnect gatt method
1602 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
1603 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
1604 jni_obj_GattCharacteristic);
1607 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
1611 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
1612 return CA_STATUS_FAILED;
1615 return CA_STATUS_OK;
1618 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
1619 jobject characteristic)
1621 VERIFY_NON_NULL(env, TAG, "env is null");
1622 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1623 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1625 if (!CALEIsEnableBTAdapter(env))
1627 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1628 return CA_ADAPTER_NOT_ENABLED;
1631 // get BluetoothGatt class
1632 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
1633 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1634 if (!jni_cid_BluetoothGatt)
1636 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1637 return CA_STATUS_FAILED;
1640 // set Characteristic Notification
1641 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1642 "setCharacteristicNotification",
1643 "(Landroid/bluetooth/"
1644 "BluetoothGattCharacteristic;Z)Z");
1645 if (!jni_mid_setNotification)
1647 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1648 return CA_STATUS_FAILED;
1651 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
1652 characteristic, JNI_TRUE);
1653 if (JNI_TRUE == ret)
1655 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
1659 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
1660 return CA_STATUS_FAILED;
1663 return CA_STATUS_OK;
1666 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
1668 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1669 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1670 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
1672 if (!CALEIsEnableBTAdapter(env))
1674 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1678 // get BluetoothGatt class
1679 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
1680 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1681 if (!jni_cid_BluetoothGatt)
1683 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1687 jmethodID jni_mid_getService = (*env)->GetMethodID(
1688 env, jni_cid_BluetoothGatt, "getService",
1689 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
1690 if (!jni_mid_getService)
1692 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1696 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1697 if (!jni_obj_service_uuid)
1699 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
1703 // get bluetooth gatt service
1704 OIC_LOG(DEBUG, TAG, "request to get service");
1705 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
1706 jni_obj_service_uuid);
1707 if (!jni_obj_gattService)
1709 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
1713 // get bluetooth gatt service class
1714 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
1715 env, "android/bluetooth/BluetoothGattService");
1716 if (!jni_cid_BluetoothGattService)
1718 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
1722 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
1723 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
1724 "getCharacteristic",
1725 "(Ljava/util/UUID;)"
1726 "Landroid/bluetooth/"
1727 "BluetoothGattCharacteristic;");
1728 if (!jni_mid_getCharacteristic)
1730 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
1734 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
1737 OIC_LOG(ERROR, TAG, "uuid is null");
1741 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
1742 if (!jni_obj_tx_uuid)
1744 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
1745 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1749 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
1750 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
1751 jni_mid_getCharacteristic,
1754 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1755 return jni_obj_GattCharacteristic;
1758 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
1760 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
1761 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1762 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1763 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
1765 if (!CALEIsEnableBTAdapter(env))
1767 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1771 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1774 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1778 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1779 if (!jni_obj_GattCharacteristic)
1781 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1785 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
1786 "/BluetoothGattCharacteristic");
1787 if (!jni_cid_BTGattCharacteristic)
1789 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1793 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1794 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
1796 if (!jni_mid_setValue)
1798 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1802 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
1804 if (JNI_TRUE == ret)
1806 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
1810 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
1815 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1816 "setWriteType", "(I)V");
1817 if (!jni_mid_setWriteType)
1819 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
1823 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
1824 "WRITE_TYPE_NO_RESPONSE", "I");
1825 if (!jni_fid_no_response)
1827 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
1831 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
1832 jni_fid_no_response);
1834 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
1836 return jni_obj_GattCharacteristic;
1839 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
1841 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
1842 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1844 if (!CALEIsEnableBTAdapter(env))
1846 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1850 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1851 "BluetoothGattCharacteristic");
1852 if (!jni_cid_BTGattCharacteristic)
1854 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1858 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
1859 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
1861 if (!jni_mid_getValue)
1863 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
1867 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
1869 return jni_obj_data_array;
1872 CAResult_t CALEClientCreateUUIDList()
1876 OIC_LOG(ERROR, TAG, "g_jvm is null");
1877 return CA_STATUS_FAILED;
1880 bool isAttached = false;
1882 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1885 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1886 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1890 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1891 return CA_STATUS_FAILED;
1896 // create new object array
1897 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1898 if (!jni_cid_uuid_list)
1900 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
1904 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
1905 jni_cid_uuid_list, NULL);
1906 if (!jni_obj_uuid_list)
1908 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
1913 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1916 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1919 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
1921 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
1925 (*g_jvm)->DetachCurrentThread(g_jvm);
1928 return CA_STATUS_OK;
1935 (*g_jvm)->DetachCurrentThread(g_jvm);
1937 return CA_STATUS_FAILED;
1940 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
1941 jobject characteristic)
1943 VERIFY_NON_NULL(env, TAG, "env is null");
1944 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1945 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1947 if (!CALEIsEnableBTAdapter(env))
1949 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1950 return CA_ADAPTER_NOT_ENABLED;
1953 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
1954 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1955 "BluetoothGattCharacteristic");
1956 if (!jni_cid_BTGattCharacteristic)
1958 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1959 return CA_STATUS_FAILED;
1962 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1963 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1965 "(Ljava/util/UUID;)Landroid/bluetooth/"
1966 "BluetoothGattDescriptor;");
1967 if (!jni_mid_getDescriptor)
1969 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
1970 return CA_STATUS_FAILED;
1973 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1974 if (!jni_obj_cc_uuid)
1976 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
1977 return CA_STATUS_FAILED;
1980 OIC_LOG(DEBUG, TAG, "request to get descriptor");
1981 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
1982 jni_mid_getDescriptor, jni_obj_cc_uuid);
1983 if (!jni_obj_descriptor)
1985 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
1986 return CA_NOT_SUPPORTED;
1989 OIC_LOG(DEBUG, TAG, "set value in descriptor");
1990 jclass jni_cid_descriptor = (*env)->FindClass(env,
1991 "android/bluetooth/BluetoothGattDescriptor");
1992 if (!jni_cid_descriptor)
1994 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
1995 return CA_STATUS_FAILED;
1998 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
1999 if (!jni_mid_setValue)
2001 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2002 return CA_STATUS_FAILED;
2005 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2006 "ENABLE_NOTIFICATION_VALUE", "[B");
2007 if (!jni_fid_NotiValue)
2009 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2010 return CA_STATUS_FAILED;
2013 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2015 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2016 env, jni_obj_descriptor, jni_mid_setValue,
2017 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2020 OIC_LOG(DEBUG, TAG, "setValue success");
2024 OIC_LOG(ERROR, TAG, "setValue has failed");
2025 return CA_STATUS_FAILED;
2028 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2031 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2032 return CA_STATUS_FAILED;
2035 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2036 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2037 "(Landroid/bluetooth/"
2038 "BluetoothGattDescriptor;)Z");
2039 if (!jni_mid_writeDescriptor)
2041 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2042 return CA_STATUS_FAILED;
2045 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2046 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2047 jni_obj_descriptor);
2050 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2054 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2055 return CA_STATUS_FAILED;
2058 return CA_STATUS_OK;
2061 void CALEClientCreateScanDeviceList(JNIEnv *env)
2063 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2064 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2066 ca_mutex_lock(g_deviceListMutex);
2067 // create new object array
2068 if (g_deviceList == NULL)
2070 OIC_LOG(DEBUG, TAG, "Create device list");
2072 g_deviceList = u_arraylist_create();
2074 ca_mutex_unlock(g_deviceListMutex);
2077 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2079 VERIFY_NON_NULL(device, TAG, "device is null");
2080 VERIFY_NON_NULL(env, TAG, "env is null");
2082 ca_mutex_lock(g_deviceListMutex);
2086 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2087 ca_mutex_unlock(g_deviceListMutex);
2088 return CA_STATUS_FAILED;
2091 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2092 if (!jni_remoteAddress)
2094 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2095 ca_mutex_unlock(g_deviceListMutex);
2096 return CA_STATUS_FAILED;
2099 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2102 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2103 ca_mutex_unlock(g_deviceListMutex);
2104 return CA_STATUS_FAILED;
2107 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2109 jobject gdevice = (*env)->NewGlobalRef(env, device);
2110 u_arraylist_add(g_deviceList, gdevice);
2111 ca_cond_signal(g_deviceDescCond);
2112 OIC_LOG_V(DEBUG, TAG, "Added this Device[%d] in the List", remoteAddress);
2114 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2116 ca_mutex_unlock(g_deviceListMutex);
2118 return CA_STATUS_OK;
2121 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2123 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2124 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2128 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2132 uint32_t length = u_arraylist_length(g_deviceList);
2133 for (uint32_t index = 0; index < length; index++)
2135 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2138 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2142 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2143 if (!jni_setAddress)
2145 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2149 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2152 OIC_LOG(ERROR, TAG, "setAddress is null");
2156 if (!strcmp(remoteAddress, setAddress))
2158 OIC_LOG(DEBUG, TAG, "the device is already set");
2159 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2163 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2166 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2171 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2173 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2174 VERIFY_NON_NULL(env, TAG, "env is null");
2176 ca_mutex_lock(g_deviceListMutex);
2180 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2181 ca_mutex_unlock(g_deviceListMutex);
2182 return CA_STATUS_FAILED;
2185 uint32_t length = u_arraylist_length(g_deviceList);
2186 for (uint32_t index = 0; index < length; index++)
2188 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2191 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2194 (*env)->DeleteGlobalRef(env, jarrayObj);
2197 OICFree(g_deviceList);
2198 g_deviceList = NULL;
2200 ca_mutex_unlock(g_deviceListMutex);
2201 return CA_STATUS_OK;
2204 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2206 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2207 VERIFY_NON_NULL(address, TAG, "address is null");
2208 VERIFY_NON_NULL(env, TAG, "env is null");
2210 ca_mutex_lock(g_deviceListMutex);
2214 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2215 ca_mutex_unlock(g_deviceListMutex);
2216 return CA_STATUS_FAILED;
2219 uint32_t length = u_arraylist_length(g_deviceList);
2220 for (uint32_t index = 0; index < length; index++)
2222 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2225 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2226 ca_mutex_unlock(g_deviceListMutex);
2227 return CA_STATUS_FAILED;
2230 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2231 if (!jni_setAddress)
2233 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2234 ca_mutex_unlock(g_deviceListMutex);
2235 return CA_STATUS_FAILED;
2238 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2241 OIC_LOG(ERROR, TAG, "setAddress is null");
2242 ca_mutex_unlock(g_deviceListMutex);
2243 return CA_STATUS_FAILED;
2246 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2249 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2250 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2251 ca_mutex_unlock(g_deviceListMutex);
2252 return CA_STATUS_FAILED;
2255 if (!strcmp(setAddress, remoteAddress))
2257 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2258 (*env)->DeleteGlobalRef(env, jarrayObj);
2259 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2260 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2262 if (NULL == u_arraylist_remove(g_deviceList, index))
2264 OIC_LOG(ERROR, TAG, "List removal failed.");
2265 ca_mutex_unlock(g_deviceListMutex);
2266 return CA_STATUS_FAILED;
2268 ca_mutex_unlock(g_deviceListMutex);
2269 return CA_STATUS_OK;
2271 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2272 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2275 ca_mutex_unlock(g_deviceListMutex);
2276 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2278 return CA_STATUS_OK;
2285 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2287 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2288 VERIFY_NON_NULL(env, TAG, "env is null");
2289 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2291 ca_mutex_lock(g_gattObjectMutex);
2293 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2294 if (!jni_remoteAddress)
2296 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2297 ca_mutex_unlock(g_gattObjectMutex);
2298 return CA_STATUS_FAILED;
2301 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2304 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2305 ca_mutex_unlock(g_gattObjectMutex);
2306 return CA_STATUS_FAILED;
2309 if (!CALEClientIsGattObjInList(env, remoteAddress))
2311 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2312 u_arraylist_add(g_gattObjectList, newGatt);
2313 OIC_LOG(DEBUG, TAG, "Set GATT Object to Array as Element");
2316 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2317 ca_mutex_unlock(g_gattObjectMutex);
2318 return CA_STATUS_OK;
2321 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2323 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2324 VERIFY_NON_NULL(env, TAG, "env is null");
2325 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2327 uint32_t length = u_arraylist_length(g_gattObjectList);
2328 for (uint32_t index = 0; index < length; index++)
2331 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2334 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2338 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2339 if (!jni_setAddress)
2341 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2345 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2348 OIC_LOG(ERROR, TAG, "setAddress is null");
2352 if (!strcmp(remoteAddress, setAddress))
2354 OIC_LOG(DEBUG, TAG, "the device is already set");
2355 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2360 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2365 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2369 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2371 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2372 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2373 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2375 ca_mutex_lock(g_gattObjectMutex);
2376 uint32_t length = u_arraylist_length(g_gattObjectList);
2377 for (uint32_t index = 0; index < length; index++)
2379 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2382 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2383 ca_mutex_unlock(g_gattObjectMutex);
2387 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2388 if (!jni_setAddress)
2390 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2391 ca_mutex_unlock(g_gattObjectMutex);
2395 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2398 OIC_LOG(ERROR, TAG, "setAddress is null");
2399 ca_mutex_unlock(g_gattObjectMutex);
2403 if (!strcmp(remoteAddress, setAddress))
2405 OIC_LOG(DEBUG, TAG, "the device is already set");
2406 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2407 ca_mutex_unlock(g_gattObjectMutex);
2410 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2413 ca_mutex_unlock(g_gattObjectMutex);
2414 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2418 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2420 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2421 VERIFY_NON_NULL(env, TAG, "env is null");
2423 ca_mutex_lock(g_gattObjectMutex);
2424 if (!g_gattObjectList)
2426 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2427 ca_mutex_unlock(g_gattObjectMutex);
2428 return CA_STATUS_FAILED;
2431 uint32_t length = u_arraylist_length(g_gattObjectList);
2432 for (uint32_t index = 0; index < length; index++)
2434 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2437 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2440 (*env)->DeleteGlobalRef(env, jarrayObj);
2443 OICFree(g_gattObjectList);
2444 g_gattObjectList = NULL;
2445 ca_mutex_unlock(g_gattObjectMutex);
2446 return CA_STATUS_OK;
2449 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2451 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2452 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2453 VERIFY_NON_NULL(env, TAG, "env is null");
2455 ca_mutex_lock(g_gattObjectMutex);
2456 if (!g_gattObjectList)
2458 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2459 ca_mutex_unlock(g_gattObjectMutex);
2460 return CA_STATUS_FAILED;
2463 uint32_t length = u_arraylist_length(g_gattObjectList);
2464 for (uint32_t index = 0; index < length; index++)
2466 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2469 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2470 ca_mutex_unlock(g_gattObjectMutex);
2471 return CA_STATUS_FAILED;
2474 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2475 if (!jni_setAddress)
2477 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2478 ca_mutex_unlock(g_gattObjectMutex);
2479 return CA_STATUS_FAILED;
2482 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2485 OIC_LOG(ERROR, TAG, "setAddress is null");
2486 ca_mutex_unlock(g_gattObjectMutex);
2487 return CA_STATUS_FAILED;
2490 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2491 if (!jni_remoteAddress)
2493 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2494 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2495 ca_mutex_unlock(g_gattObjectMutex);
2496 return CA_STATUS_FAILED;
2499 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2502 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2503 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2504 ca_mutex_unlock(g_gattObjectMutex);
2505 return CA_STATUS_FAILED;
2508 if (!strcmp(setAddress, remoteAddress))
2510 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2511 (*env)->DeleteGlobalRef(env, jarrayObj);
2512 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2513 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2515 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2517 OIC_LOG(ERROR, TAG, "List removal failed.");
2518 ca_mutex_unlock(g_gattObjectMutex);
2519 return CA_STATUS_FAILED;
2521 ca_mutex_unlock(g_gattObjectMutex);
2522 return CA_STATUS_OK;
2524 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2525 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2528 ca_mutex_unlock(g_gattObjectMutex);
2529 OIC_LOG(DEBUG, TAG, "there are no target object");
2530 return CA_STATUS_OK;
2533 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
2535 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2536 VERIFY_NON_NULL(addr, TAG, "addr is null");
2537 VERIFY_NON_NULL(env, TAG, "env is null");
2539 ca_mutex_lock(g_gattObjectMutex);
2540 if (!g_gattObjectList)
2542 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2543 ca_mutex_unlock(g_gattObjectMutex);
2544 return CA_STATUS_FAILED;
2547 uint32_t length = u_arraylist_length(g_gattObjectList);
2548 for (uint32_t index = 0; index < length; index++)
2550 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2553 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2554 ca_mutex_unlock(g_gattObjectMutex);
2555 return CA_STATUS_FAILED;
2558 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2559 if (!jni_setAddress)
2561 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2562 ca_mutex_unlock(g_gattObjectMutex);
2563 return CA_STATUS_FAILED;
2566 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2569 OIC_LOG(ERROR, TAG, "setAddress is null");
2570 ca_mutex_unlock(g_gattObjectMutex);
2571 return CA_STATUS_FAILED;
2574 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
2577 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2578 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2579 ca_mutex_unlock(g_gattObjectMutex);
2580 return CA_STATUS_FAILED;
2583 if (!strcmp(setAddress, remoteAddress))
2585 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2586 (*env)->DeleteGlobalRef(env, jarrayObj);
2588 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2589 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2590 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2592 OIC_LOG(ERROR, TAG, "List removal failed.");
2593 ca_mutex_unlock(g_gattObjectMutex);
2594 return CA_STATUS_FAILED;
2596 ca_mutex_unlock(g_gattObjectMutex);
2597 return CA_STATUS_OK;
2599 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2600 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2603 ca_mutex_unlock(g_gattObjectMutex);
2604 OIC_LOG(DEBUG, TAG, "there are no target object");
2605 return CA_STATUS_FAILED;
2612 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
2613 uint16_t notificationState, uint16_t sendState)
2615 VERIFY_NON_NULL(address, TAG, "address is null");
2617 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
2620 OIC_LOG(ERROR, TAG, "out of memory");
2621 return CA_MEMORY_ALLOC_FAILED;
2624 if (strlen(address) > CA_MACADDR_SIZE)
2626 OIC_LOG(ERROR, TAG, "address is not proper");
2628 return CA_STATUS_FAILED;
2631 OICStrcpy(newstate->address, sizeof(newstate->address), address);
2632 newstate->connectedState = connectedState;
2633 newstate->notificationState = notificationState;
2634 newstate->sendState = sendState;
2635 return CALEClientAddDeviceStateToList(newstate);
2638 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
2640 VERIFY_NON_NULL(state, TAG, "state is null");
2642 ca_mutex_lock(g_deviceStateListMutex);
2644 if (!g_deviceStateList)
2646 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2647 ca_mutex_unlock(g_deviceStateListMutex);
2648 return CA_STATUS_FAILED;
2651 if (CALEClientIsDeviceInList(state->address))
2653 CALEState_t* curState = CALEClientGetStateInfo(state->address);
2656 OIC_LOG(ERROR, TAG, "curState is null");
2657 ca_mutex_unlock(g_deviceStateListMutex);
2658 return CA_STATUS_FAILED;
2661 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
2663 state->notificationState = curState->notificationState;
2666 // delete previous state for update new state
2667 CAResult_t res = CALEClientRemoveDeviceState(state->address);
2668 if (CA_STATUS_OK != res)
2670 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
2671 ca_mutex_unlock(g_deviceStateListMutex);
2675 u_arraylist_add(g_deviceStateList, state); // update new state
2676 OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d, %d",
2677 state->connectedState, state->notificationState);
2679 ca_mutex_unlock(g_deviceStateListMutex);
2680 return CA_STATUS_OK;
2683 bool CALEClientIsDeviceInList(const char* remoteAddress)
2685 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2687 if (!g_deviceStateList)
2689 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2693 uint32_t length = u_arraylist_length(g_deviceStateList);
2694 for (uint32_t index = 0; index < length; index++)
2696 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2699 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2703 if (!strcmp(remoteAddress, state->address))
2705 OIC_LOG(DEBUG, TAG, "the device is already set");
2714 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
2718 CAResult_t CALEClientRemoveAllDeviceState()
2720 OIC_LOG(DEBUG, TAG, "CALENativeRemoveAllDevices");
2722 ca_mutex_lock(g_deviceStateListMutex);
2723 if (!g_deviceStateList)
2725 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2726 ca_mutex_unlock(g_deviceStateListMutex);
2727 return CA_STATUS_FAILED;
2730 uint32_t length = u_arraylist_length(g_deviceStateList);
2731 for (uint32_t index = 0; index < length; index++)
2733 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2736 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2742 OICFree(g_deviceStateList);
2743 g_deviceStateList = NULL;
2744 ca_mutex_unlock(g_deviceStateListMutex);
2746 return CA_STATUS_OK;
2749 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
2751 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
2752 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
2754 if (!g_deviceStateList)
2756 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2757 return CA_STATUS_FAILED;
2760 uint32_t length = u_arraylist_length(g_deviceStateList);
2761 for (uint32_t index = 0; index < length; index++)
2763 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2766 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2770 if (!strcmp(state->address, remoteAddress))
2772 OIC_LOG_V(DEBUG, TAG, "remove state : %s", remoteAddress);
2775 if (NULL == u_arraylist_remove(g_deviceStateList, index))
2777 OIC_LOG(ERROR, TAG, "List removal failed.");
2778 return CA_STATUS_FAILED;
2781 return CA_STATUS_OK;
2785 return CA_STATUS_FAILED;
2788 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
2790 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
2791 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2793 if (!g_deviceStateList)
2795 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2799 uint32_t length = u_arraylist_length(g_deviceStateList);
2800 for (uint32_t index = 0; index < length; index++)
2802 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2805 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2809 if (!strcmp(state->address, remoteAddress))
2811 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
2818 bool CALEClientIsConnectedDevice(const char* remoteAddress)
2820 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
2821 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2823 ca_mutex_lock(g_deviceStateListMutex);
2824 if (!g_deviceStateList)
2826 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2827 ca_mutex_unlock(g_deviceStateListMutex);
2831 uint32_t length = u_arraylist_length(g_deviceStateList);
2832 for (uint32_t index = 0; index < length; index++)
2834 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2837 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2841 if (!strcmp(state->address, remoteAddress))
2843 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
2845 if (STATE_CONNECTED == state->connectedState)
2847 ca_mutex_unlock(g_deviceStateListMutex);
2852 ca_mutex_unlock(g_deviceStateListMutex);
2857 ca_mutex_unlock(g_deviceStateListMutex);
2861 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
2863 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
2864 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2866 ca_mutex_lock(g_deviceStateListMutex);
2867 if (!g_deviceStateList)
2869 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2870 ca_mutex_unlock(g_deviceStateListMutex);
2874 uint32_t length = u_arraylist_length(g_deviceStateList);
2875 for (uint32_t index = 0; index < length; index++)
2877 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2880 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2884 if (!strcmp(state->address, remoteAddress))
2886 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
2888 if (STATE_CHARACTER_SET == state->notificationState)
2890 ca_mutex_unlock(g_deviceStateListMutex);
2895 ca_mutex_unlock(g_deviceStateListMutex);
2901 ca_mutex_unlock(g_deviceStateListMutex);
2905 void CALEClientCreateDeviceList()
2907 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
2909 // create new object array
2910 if (!g_gattObjectList)
2912 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
2914 g_gattObjectList = u_arraylist_create();
2917 if (!g_deviceStateList)
2919 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
2921 g_deviceStateList = u_arraylist_create();
2926 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
2928 g_deviceList = u_arraylist_create();
2933 * Check Sent Count for remove g_sendBuffer
2935 void CALEClientUpdateSendCnt(JNIEnv *env)
2937 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2939 ca_mutex_lock(g_threadMutex);
2943 if (g_targetCnt <= g_currentSentCnt)
2946 g_currentSentCnt = 0;
2950 (*env)->DeleteGlobalRef(env, g_sendBuffer);
2951 g_sendBuffer = NULL;
2953 // notity the thread
2954 ca_cond_signal(g_threadCond);
2955 CALEClientSetSendFinishFlag(true);
2956 OIC_LOG(DEBUG, TAG, "set signal for send data");
2959 ca_mutex_unlock(g_threadMutex);
2962 CAResult_t CALEClientInitGattMutexVaraibles()
2964 if (NULL == g_bleReqRespClientCbMutex)
2966 g_bleReqRespClientCbMutex = ca_mutex_new();
2967 if (NULL == g_bleReqRespClientCbMutex)
2969 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2970 return CA_STATUS_FAILED;
2974 if (NULL == g_bleServerBDAddressMutex)
2976 g_bleServerBDAddressMutex = ca_mutex_new();
2977 if (NULL == g_bleServerBDAddressMutex)
2979 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2980 return CA_STATUS_FAILED;
2984 if (NULL == g_threadMutex)
2986 g_threadMutex = ca_mutex_new();
2987 if (NULL == g_threadMutex)
2989 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2990 return CA_STATUS_FAILED;
2994 if (NULL == g_threadSendMutex)
2996 g_threadSendMutex = ca_mutex_new();
2997 if (NULL == g_threadSendMutex)
2999 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3000 return CA_STATUS_FAILED;
3004 if (NULL == g_deviceListMutex)
3006 g_deviceListMutex = ca_mutex_new();
3007 if (NULL == g_deviceListMutex)
3009 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3010 return CA_STATUS_FAILED;
3014 if (NULL == g_gattObjectMutex)
3016 g_gattObjectMutex = ca_mutex_new();
3017 if (NULL == g_gattObjectMutex)
3019 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3020 return CA_STATUS_FAILED;
3024 if (NULL == g_deviceStateListMutex)
3026 g_deviceStateListMutex = ca_mutex_new();
3027 if (NULL == g_deviceStateListMutex)
3029 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3030 return CA_STATUS_FAILED;
3034 if (NULL == g_SendFinishMutex)
3036 g_SendFinishMutex = ca_mutex_new();
3037 if (NULL == g_SendFinishMutex)
3039 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3040 return CA_STATUS_FAILED;
3044 if (NULL == g_scanMutex)
3046 g_scanMutex = ca_mutex_new();
3047 if (NULL == g_scanMutex)
3049 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3050 return CA_STATUS_FAILED;
3054 return CA_STATUS_OK;
3057 void CALEClientTerminateGattMutexVariables()
3059 ca_mutex_free(g_bleReqRespClientCbMutex);
3060 g_bleReqRespClientCbMutex = NULL;
3062 ca_mutex_free(g_bleServerBDAddressMutex);
3063 g_bleServerBDAddressMutex = NULL;
3065 ca_mutex_free(g_threadMutex);
3066 g_threadMutex = NULL;
3068 ca_mutex_free(g_threadSendMutex);
3069 g_threadSendMutex = NULL;
3071 ca_mutex_free(g_deviceListMutex);
3072 g_deviceListMutex = NULL;
3074 ca_mutex_free(g_SendFinishMutex);
3075 g_SendFinishMutex = NULL;
3077 ca_mutex_free(g_scanMutex);
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 ca_mutex_lock(g_bleReqRespClientCbMutex);
3190 g_CABLEClientDataReceivedCallback = callback;
3191 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3194 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3196 CALEClientInitialize(handle);
3199 CAResult_t CAGetLEAddress(char **local_address)
3201 VERIFY_NON_NULL(local_address, TAG, "local_address");
3202 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3203 return CA_NOT_SUPPORTED;
3206 JNIEXPORT void JNICALL
3207 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3210 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3211 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3212 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3213 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3215 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3218 JNIEXPORT void JNICALL
3219 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3222 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3223 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3224 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3225 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3227 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3230 JNIEXPORT void JNICALL
3231 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3234 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3235 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3236 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3238 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3239 if (CA_STATUS_OK != res)
3241 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3246 * Class: org_iotivity_ca_jar_caleinterface
3247 * Method: CALeGattConnectionStateChangeCallback
3248 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3250 JNIEXPORT void JNICALL
3251 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3257 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3259 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3260 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3261 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3263 if (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
3265 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3271 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3274 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3275 STATE_CHARACTER_NO_CHANGE,
3277 if (CA_STATUS_OK != res)
3279 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3280 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3283 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3286 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3287 if (CA_STATUS_OK != res)
3289 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3293 res = CALEClientDiscoverServices(env, gatt);
3294 if (CA_STATUS_OK != res)
3296 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3300 else // le disconnected
3302 CAResult_t res = CALEClientStartScan();
3303 if (CA_STATUS_OK != res)
3305 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3309 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3312 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3316 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3319 res = CALEClientRemoveDeviceState(address);
3320 if (CA_STATUS_OK != res)
3322 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3326 res = CALEClientRemoveGattObjForAddr(env, jni_address);
3327 if (CA_STATUS_OK != res)
3329 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
3333 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3336 res = CALEClientGattClose(env, gatt);
3337 if (CA_STATUS_OK != res)
3339 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3347 CALEClientSendFinish(env, gatt);
3352 * Class: org_iotivity_ca_jar_caleinterface
3353 * Method: CALeGattServicesDiscoveredCallback
3354 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3356 JNIEXPORT void JNICALL
3357 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
3362 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
3363 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3364 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3365 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3367 if (0 != status) // discovery error
3369 CALEClientSendFinish(env, gatt);
3373 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3376 CALEClientSendFinish(env, gatt);
3380 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3383 CALEClientSendFinish(env, gatt);
3387 if (!CALEClientIsSetCharacteristic(address))
3389 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3392 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3396 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
3397 if (!jni_obj_GattCharacteristic)
3399 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3403 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
3404 jni_obj_GattCharacteristic);
3405 if (CA_STATUS_OK != res)
3407 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
3411 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
3412 if (CA_STATUS_OK != res)
3414 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
3415 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3416 if (CA_STATUS_OK != res)
3418 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3423 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3425 if (CA_STATUS_OK != res)
3427 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3433 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3434 if (CA_STATUS_OK != res)
3436 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3440 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3445 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3446 CALEClientSendFinish(env, gatt);
3451 * Class: org_iotivity_ca_jar_caleinterface
3452 * Method: CALeGattCharacteristicWritjclasseCallback
3453 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
3455 JNIEXPORT void JNICALL
3456 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
3457 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
3460 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
3461 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3462 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3463 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3466 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
3468 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
3470 // send success & signal
3471 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3477 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3483 if (GATT_SUCCESS != status) // error case
3485 OIC_LOG(ERROR, TAG, "send failure");
3486 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3488 if (CA_STATUS_OK != res)
3490 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3493 if (g_clientErrorCallback)
3495 jint length = (*env)->GetArrayLength(env, data);
3496 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
3499 CALEClientSendFinish(env, gatt);
3503 OIC_LOG(DEBUG, TAG, "send success");
3504 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3505 STATE_SEND_SUCCESS);
3506 if (CA_STATUS_OK != res)
3508 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3510 CALEClientUpdateSendCnt(env);
3513 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3519 CALEClientSendFinish(env, gatt);
3524 * Class: org_iotivity_ca_jar_caleinterface
3525 * Method: CALeGattCharacteristicChangedCallback
3526 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
3528 JNIEXPORT void JNICALL
3529 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
3530 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
3532 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
3533 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3534 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3535 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3536 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
3538 // get Byte Array and convert to uint8_t*
3539 jint length = (*env)->GetArrayLength(env, data);
3542 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
3544 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
3545 jni_byte_responseData);
3547 uint8_t* receivedData = OICMalloc(length);
3550 OIC_LOG(ERROR, TAG, "receivedData is null");
3554 memcpy(receivedData, jni_byte_responseData, length);
3555 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
3557 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3560 OIC_LOG(ERROR, TAG, "jni_address is null");
3561 OICFree(receivedData);
3565 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3568 OIC_LOG(ERROR, TAG, "address is null");
3569 OICFree(receivedData);
3573 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
3574 receivedData, length);
3576 ca_mutex_lock(g_bleServerBDAddressMutex);
3577 uint32_t sentLength = 0;
3578 g_CABLEClientDataReceivedCallback(address, receivedData, length,
3580 ca_mutex_unlock(g_bleServerBDAddressMutex);
3582 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3586 * Class: org_iotivity_ca_jar_caleinterface
3587 * Method: CALeGattDescriptorWriteCallback
3588 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
3590 JNIEXPORT void JNICALL
3591 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
3595 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
3596 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3597 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3598 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3600 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3601 if (CA_STATUS_OK != res)
3603 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3611 CALEClientSendFinish(env, gatt);