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 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2162 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2165 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2170 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2172 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2173 VERIFY_NON_NULL(env, TAG, "env is null");
2175 ca_mutex_lock(g_deviceListMutex);
2179 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2180 ca_mutex_unlock(g_deviceListMutex);
2181 return CA_STATUS_FAILED;
2184 uint32_t length = u_arraylist_length(g_deviceList);
2185 for (uint32_t index = 0; index < length; index++)
2187 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2190 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2193 (*env)->DeleteGlobalRef(env, jarrayObj);
2196 OICFree(g_deviceList);
2197 g_deviceList = NULL;
2199 ca_mutex_unlock(g_deviceListMutex);
2200 return CA_STATUS_OK;
2203 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2205 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2206 VERIFY_NON_NULL(address, TAG, "address is null");
2207 VERIFY_NON_NULL(env, TAG, "env is null");
2209 ca_mutex_lock(g_deviceListMutex);
2213 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2214 ca_mutex_unlock(g_deviceListMutex);
2215 return CA_STATUS_FAILED;
2218 uint32_t length = u_arraylist_length(g_deviceList);
2219 for (uint32_t index = 0; index < length; index++)
2221 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2224 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2225 ca_mutex_unlock(g_deviceListMutex);
2226 return CA_STATUS_FAILED;
2229 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2230 if (!jni_setAddress)
2232 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2233 ca_mutex_unlock(g_deviceListMutex);
2234 return CA_STATUS_FAILED;
2237 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2240 OIC_LOG(ERROR, TAG, "setAddress is null");
2241 ca_mutex_unlock(g_deviceListMutex);
2242 return CA_STATUS_FAILED;
2245 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2248 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2249 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2250 ca_mutex_unlock(g_deviceListMutex);
2251 return CA_STATUS_FAILED;
2254 if (!strcmp(setAddress, remoteAddress))
2256 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2257 (*env)->DeleteGlobalRef(env, jarrayObj);
2258 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2259 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2261 if (NULL == u_arraylist_remove(g_deviceList, index))
2263 OIC_LOG(ERROR, TAG, "List removal failed.");
2264 ca_mutex_unlock(g_deviceListMutex);
2265 return CA_STATUS_FAILED;
2267 ca_mutex_unlock(g_deviceListMutex);
2268 return CA_STATUS_OK;
2270 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2271 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2274 ca_mutex_unlock(g_deviceListMutex);
2275 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2277 return CA_STATUS_OK;
2284 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2286 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2287 VERIFY_NON_NULL(env, TAG, "env is null");
2288 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2290 ca_mutex_lock(g_gattObjectMutex);
2292 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2293 if (!jni_remoteAddress)
2295 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2296 ca_mutex_unlock(g_gattObjectMutex);
2297 return CA_STATUS_FAILED;
2300 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2303 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2304 ca_mutex_unlock(g_gattObjectMutex);
2305 return CA_STATUS_FAILED;
2308 if (!CALEClientIsGattObjInList(env, remoteAddress))
2310 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2311 u_arraylist_add(g_gattObjectList, newGatt);
2312 OIC_LOG(DEBUG, TAG, "Set GATT Object to Array as Element");
2315 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2316 ca_mutex_unlock(g_gattObjectMutex);
2317 return CA_STATUS_OK;
2320 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2322 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2323 VERIFY_NON_NULL(env, TAG, "env is null");
2324 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2326 uint32_t length = u_arraylist_length(g_gattObjectList);
2327 for (uint32_t index = 0; index < length; index++)
2330 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2333 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2337 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2338 if (!jni_setAddress)
2340 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2344 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2347 OIC_LOG(ERROR, TAG, "setAddress is null");
2351 if (!strcmp(remoteAddress, setAddress))
2353 OIC_LOG(DEBUG, TAG, "the device is already set");
2354 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2359 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2364 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2368 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2370 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2371 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2372 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2374 ca_mutex_lock(g_gattObjectMutex);
2375 uint32_t length = u_arraylist_length(g_gattObjectList);
2376 for (uint32_t index = 0; index < length; index++)
2378 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2381 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2382 ca_mutex_unlock(g_gattObjectMutex);
2386 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2387 if (!jni_setAddress)
2389 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2390 ca_mutex_unlock(g_gattObjectMutex);
2394 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2397 OIC_LOG(ERROR, TAG, "setAddress is null");
2398 ca_mutex_unlock(g_gattObjectMutex);
2402 if (!strcmp(remoteAddress, setAddress))
2404 OIC_LOG(DEBUG, TAG, "the device is already set");
2405 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2406 ca_mutex_unlock(g_gattObjectMutex);
2409 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2412 ca_mutex_unlock(g_gattObjectMutex);
2413 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2417 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2419 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2420 VERIFY_NON_NULL(env, TAG, "env is null");
2422 ca_mutex_lock(g_gattObjectMutex);
2423 if (!g_gattObjectList)
2425 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2426 ca_mutex_unlock(g_gattObjectMutex);
2427 return CA_STATUS_FAILED;
2430 uint32_t length = u_arraylist_length(g_gattObjectList);
2431 for (uint32_t index = 0; index < length; index++)
2433 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2436 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2439 (*env)->DeleteGlobalRef(env, jarrayObj);
2442 OICFree(g_gattObjectList);
2443 g_gattObjectList = NULL;
2444 ca_mutex_unlock(g_gattObjectMutex);
2445 return CA_STATUS_OK;
2448 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2450 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2451 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2452 VERIFY_NON_NULL(env, TAG, "env is null");
2454 ca_mutex_lock(g_gattObjectMutex);
2455 if (!g_gattObjectList)
2457 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2458 ca_mutex_unlock(g_gattObjectMutex);
2459 return CA_STATUS_FAILED;
2462 uint32_t length = u_arraylist_length(g_gattObjectList);
2463 for (uint32_t index = 0; index < length; index++)
2465 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2468 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2469 ca_mutex_unlock(g_gattObjectMutex);
2470 return CA_STATUS_FAILED;
2473 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2474 if (!jni_setAddress)
2476 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2477 ca_mutex_unlock(g_gattObjectMutex);
2478 return CA_STATUS_FAILED;
2481 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2484 OIC_LOG(ERROR, TAG, "setAddress is null");
2485 ca_mutex_unlock(g_gattObjectMutex);
2486 return CA_STATUS_FAILED;
2489 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2490 if (!jni_remoteAddress)
2492 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2493 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2494 ca_mutex_unlock(g_gattObjectMutex);
2495 return CA_STATUS_FAILED;
2498 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2501 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2502 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2503 ca_mutex_unlock(g_gattObjectMutex);
2504 return CA_STATUS_FAILED;
2507 if (!strcmp(setAddress, remoteAddress))
2509 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2510 (*env)->DeleteGlobalRef(env, jarrayObj);
2511 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2512 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2514 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2516 OIC_LOG(ERROR, TAG, "List removal failed.");
2517 ca_mutex_unlock(g_gattObjectMutex);
2518 return CA_STATUS_FAILED;
2520 ca_mutex_unlock(g_gattObjectMutex);
2521 return CA_STATUS_OK;
2523 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2524 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2527 ca_mutex_unlock(g_gattObjectMutex);
2528 OIC_LOG(DEBUG, TAG, "there are no target object");
2529 return CA_STATUS_OK;
2532 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
2534 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2535 VERIFY_NON_NULL(addr, TAG, "addr is null");
2536 VERIFY_NON_NULL(env, TAG, "env is null");
2538 ca_mutex_lock(g_gattObjectMutex);
2539 if (!g_gattObjectList)
2541 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2542 ca_mutex_unlock(g_gattObjectMutex);
2543 return CA_STATUS_FAILED;
2546 uint32_t length = u_arraylist_length(g_gattObjectList);
2547 for (uint32_t index = 0; index < length; index++)
2549 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2552 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2553 ca_mutex_unlock(g_gattObjectMutex);
2554 return CA_STATUS_FAILED;
2557 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2558 if (!jni_setAddress)
2560 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2561 ca_mutex_unlock(g_gattObjectMutex);
2562 return CA_STATUS_FAILED;
2565 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2568 OIC_LOG(ERROR, TAG, "setAddress is null");
2569 ca_mutex_unlock(g_gattObjectMutex);
2570 return CA_STATUS_FAILED;
2573 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
2576 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2577 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2578 ca_mutex_unlock(g_gattObjectMutex);
2579 return CA_STATUS_FAILED;
2582 if (!strcmp(setAddress, remoteAddress))
2584 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2585 (*env)->DeleteGlobalRef(env, jarrayObj);
2587 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2588 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2589 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2591 OIC_LOG(ERROR, TAG, "List removal failed.");
2592 ca_mutex_unlock(g_gattObjectMutex);
2593 return CA_STATUS_FAILED;
2595 ca_mutex_unlock(g_gattObjectMutex);
2596 return CA_STATUS_OK;
2598 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2599 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2602 ca_mutex_unlock(g_gattObjectMutex);
2603 OIC_LOG(DEBUG, TAG, "there are no target object");
2604 return CA_STATUS_FAILED;
2611 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
2612 uint16_t notificationState, uint16_t sendState)
2614 VERIFY_NON_NULL(address, TAG, "address is null");
2616 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
2619 OIC_LOG(ERROR, TAG, "out of memory");
2620 return CA_MEMORY_ALLOC_FAILED;
2623 if (strlen(address) > CA_MACADDR_SIZE)
2625 OIC_LOG(ERROR, TAG, "address is not proper");
2627 return CA_STATUS_FAILED;
2630 OICStrcpy(newstate->address, sizeof(newstate->address), address);
2631 newstate->connectedState = connectedState;
2632 newstate->notificationState = notificationState;
2633 newstate->sendState = sendState;
2634 return CALEClientAddDeviceStateToList(newstate);
2637 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
2639 VERIFY_NON_NULL(state, TAG, "state is null");
2641 ca_mutex_lock(g_deviceStateListMutex);
2643 if (!g_deviceStateList)
2645 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2646 ca_mutex_unlock(g_deviceStateListMutex);
2647 return CA_STATUS_FAILED;
2650 if (CALEClientIsDeviceInList(state->address))
2652 CALEState_t* curState = CALEClientGetStateInfo(state->address);
2655 OIC_LOG(ERROR, TAG, "curState is null");
2656 ca_mutex_unlock(g_deviceStateListMutex);
2657 return CA_STATUS_FAILED;
2660 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
2662 state->notificationState = curState->notificationState;
2665 // delete previous state for update new state
2666 CAResult_t res = CALEClientRemoveDeviceState(state->address);
2667 if (CA_STATUS_OK != res)
2669 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
2670 ca_mutex_unlock(g_deviceStateListMutex);
2674 u_arraylist_add(g_deviceStateList, state); // update new state
2675 OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d, %d",
2676 state->connectedState, state->notificationState);
2678 ca_mutex_unlock(g_deviceStateListMutex);
2679 return CA_STATUS_OK;
2682 bool CALEClientIsDeviceInList(const char* remoteAddress)
2684 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2686 if (!g_deviceStateList)
2688 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2692 uint32_t length = u_arraylist_length(g_deviceStateList);
2693 for (uint32_t index = 0; index < length; index++)
2695 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2698 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2702 if (!strcmp(remoteAddress, state->address))
2704 OIC_LOG(DEBUG, TAG, "the device is already set");
2713 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
2717 CAResult_t CALEClientRemoveAllDeviceState()
2719 OIC_LOG(DEBUG, TAG, "CALENativeRemoveAllDevices");
2721 ca_mutex_lock(g_deviceStateListMutex);
2722 if (!g_deviceStateList)
2724 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2725 ca_mutex_unlock(g_deviceStateListMutex);
2726 return CA_STATUS_FAILED;
2729 uint32_t length = u_arraylist_length(g_deviceStateList);
2730 for (uint32_t index = 0; index < length; index++)
2732 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2735 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2741 OICFree(g_deviceStateList);
2742 g_deviceStateList = NULL;
2743 ca_mutex_unlock(g_deviceStateListMutex);
2745 return CA_STATUS_OK;
2748 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
2750 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
2751 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
2753 if (!g_deviceStateList)
2755 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2756 return CA_STATUS_FAILED;
2759 uint32_t length = u_arraylist_length(g_deviceStateList);
2760 for (uint32_t index = 0; index < length; index++)
2762 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2765 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2769 if (!strcmp(state->address, remoteAddress))
2771 OIC_LOG_V(DEBUG, TAG, "remove state : %s", remoteAddress);
2774 if (NULL == u_arraylist_remove(g_deviceStateList, index))
2776 OIC_LOG(ERROR, TAG, "List removal failed.");
2777 return CA_STATUS_FAILED;
2780 return CA_STATUS_OK;
2784 return CA_STATUS_FAILED;
2787 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
2789 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
2790 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2792 if (!g_deviceStateList)
2794 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2798 uint32_t length = u_arraylist_length(g_deviceStateList);
2799 for (uint32_t index = 0; index < length; index++)
2801 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2804 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2808 if (!strcmp(state->address, remoteAddress))
2810 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
2817 bool CALEClientIsConnectedDevice(const char* remoteAddress)
2819 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
2820 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2822 ca_mutex_lock(g_deviceStateListMutex);
2823 if (!g_deviceStateList)
2825 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2826 ca_mutex_unlock(g_deviceStateListMutex);
2830 uint32_t length = u_arraylist_length(g_deviceStateList);
2831 for (uint32_t index = 0; index < length; index++)
2833 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2836 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2840 if (!strcmp(state->address, remoteAddress))
2842 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
2844 if (STATE_CONNECTED == state->connectedState)
2846 ca_mutex_unlock(g_deviceStateListMutex);
2851 ca_mutex_unlock(g_deviceStateListMutex);
2856 ca_mutex_unlock(g_deviceStateListMutex);
2860 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
2862 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
2863 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2865 ca_mutex_lock(g_deviceStateListMutex);
2866 if (!g_deviceStateList)
2868 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2869 ca_mutex_unlock(g_deviceStateListMutex);
2873 uint32_t length = u_arraylist_length(g_deviceStateList);
2874 for (uint32_t index = 0; index < length; index++)
2876 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2879 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2883 if (!strcmp(state->address, remoteAddress))
2885 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
2887 if (STATE_CHARACTER_SET == state->notificationState)
2889 ca_mutex_unlock(g_deviceStateListMutex);
2894 ca_mutex_unlock(g_deviceStateListMutex);
2900 ca_mutex_unlock(g_deviceStateListMutex);
2904 void CALEClientCreateDeviceList()
2906 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
2908 // create new object array
2909 if (!g_gattObjectList)
2911 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
2913 g_gattObjectList = u_arraylist_create();
2916 if (!g_deviceStateList)
2918 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
2920 g_deviceStateList = u_arraylist_create();
2925 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
2927 g_deviceList = u_arraylist_create();
2932 * Check Sent Count for remove g_sendBuffer
2934 void CALEClientUpdateSendCnt(JNIEnv *env)
2936 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2938 ca_mutex_lock(g_threadMutex);
2942 if (g_targetCnt <= g_currentSentCnt)
2945 g_currentSentCnt = 0;
2949 (*env)->DeleteGlobalRef(env, g_sendBuffer);
2950 g_sendBuffer = NULL;
2952 // notity the thread
2953 ca_cond_signal(g_threadCond);
2954 CALEClientSetSendFinishFlag(true);
2955 OIC_LOG(DEBUG, TAG, "set signal for send data");
2958 ca_mutex_unlock(g_threadMutex);
2961 CAResult_t CALEClientInitGattMutexVaraibles()
2963 if (NULL == g_bleReqRespClientCbMutex)
2965 g_bleReqRespClientCbMutex = ca_mutex_new();
2966 if (NULL == g_bleReqRespClientCbMutex)
2968 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2969 return CA_STATUS_FAILED;
2973 if (NULL == g_bleServerBDAddressMutex)
2975 g_bleServerBDAddressMutex = ca_mutex_new();
2976 if (NULL == g_bleServerBDAddressMutex)
2978 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2979 return CA_STATUS_FAILED;
2983 if (NULL == g_threadMutex)
2985 g_threadMutex = ca_mutex_new();
2986 if (NULL == g_threadMutex)
2988 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2989 return CA_STATUS_FAILED;
2993 if (NULL == g_threadSendMutex)
2995 g_threadSendMutex = ca_mutex_new();
2996 if (NULL == g_threadSendMutex)
2998 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2999 return CA_STATUS_FAILED;
3003 if (NULL == g_deviceListMutex)
3005 g_deviceListMutex = ca_mutex_new();
3006 if (NULL == g_deviceListMutex)
3008 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3009 return CA_STATUS_FAILED;
3013 if (NULL == g_gattObjectMutex)
3015 g_gattObjectMutex = ca_mutex_new();
3016 if (NULL == g_gattObjectMutex)
3018 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3019 return CA_STATUS_FAILED;
3023 if (NULL == g_deviceStateListMutex)
3025 g_deviceStateListMutex = ca_mutex_new();
3026 if (NULL == g_deviceStateListMutex)
3028 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3029 return CA_STATUS_FAILED;
3033 if (NULL == g_SendFinishMutex)
3035 g_SendFinishMutex = ca_mutex_new();
3036 if (NULL == g_SendFinishMutex)
3038 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3039 return CA_STATUS_FAILED;
3043 if (NULL == g_scanMutex)
3045 g_scanMutex = ca_mutex_new();
3046 if (NULL == g_scanMutex)
3048 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3049 return CA_STATUS_FAILED;
3053 return CA_STATUS_OK;
3056 void CALEClientTerminateGattMutexVariables()
3058 ca_mutex_free(g_bleReqRespClientCbMutex);
3059 g_bleReqRespClientCbMutex = NULL;
3061 ca_mutex_free(g_bleServerBDAddressMutex);
3062 g_bleServerBDAddressMutex = NULL;
3064 ca_mutex_free(g_threadMutex);
3065 g_threadMutex = NULL;
3067 ca_mutex_free(g_threadSendMutex);
3068 g_threadSendMutex = NULL;
3070 ca_mutex_free(g_deviceListMutex);
3071 g_deviceListMutex = NULL;
3073 ca_mutex_free(g_SendFinishMutex);
3074 g_SendFinishMutex = NULL;
3076 ca_mutex_free(g_scanMutex);
3080 void CALEClientSetSendFinishFlag(bool flag)
3082 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3084 ca_mutex_lock(g_SendFinishMutex);
3085 g_isFinishedSendData = flag;
3086 ca_mutex_unlock(g_SendFinishMutex);
3093 CAResult_t CAStartLEGattClient()
3095 CAResult_t res = CALEClientStartMulticastServer();
3096 if (CA_STATUS_OK != res)
3098 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3102 g_isStartedLEClient = true;
3108 void CAStopLEGattClient()
3110 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3114 OIC_LOG(ERROR, TAG, "g_jvm is null");
3118 bool isAttached = false;
3120 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3123 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3124 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3128 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3134 CAResult_t ret = CALEClientDisconnectAll(env);
3135 if (CA_STATUS_OK != ret)
3137 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3140 ret = CALEClientStopScan();
3141 if(CA_STATUS_OK != ret)
3143 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3146 ca_cond_signal(g_threadCond);
3150 (*g_jvm)->DetachCurrentThread(g_jvm);
3155 void CATerminateLEGattClient()
3157 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3158 CALEClientTerminate();
3161 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3162 uint32_t dataLen, CALETransferType_t type,
3165 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3166 VERIFY_NON_NULL(data, TAG, "data is null");
3167 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3169 if (LE_UNICAST != type || position < 0)
3171 OIC_LOG(ERROR, TAG, "this request is not unicast");
3172 return CA_STATUS_INVALID_PARAM;
3175 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3178 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3180 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3181 VERIFY_NON_NULL(data, TAG, "data is null");
3183 return CALEClientSendMulticastMessage(data, dataLen);
3186 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3188 ca_mutex_lock(g_bleReqRespClientCbMutex);
3189 g_CABLEClientDataReceivedCallback = callback;
3190 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3193 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3195 CALEClientInitialize(handle);
3198 CAResult_t CAGetLEAddress(char **local_address)
3200 VERIFY_NON_NULL(local_address, TAG, "local_address");
3201 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3202 return CA_NOT_SUPPORTED;
3205 JNIEXPORT void JNICALL
3206 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3209 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3210 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3211 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3212 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3214 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3217 JNIEXPORT void JNICALL
3218 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3221 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3222 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3223 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3224 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3226 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3229 JNIEXPORT void JNICALL
3230 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3233 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3234 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3235 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3237 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3238 if (CA_STATUS_OK != res)
3240 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3245 * Class: org_iotivity_ca_jar_caleinterface
3246 * Method: CALeGattConnectionStateChangeCallback
3247 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3249 JNIEXPORT void JNICALL
3250 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3256 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3258 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3259 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3260 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3262 if (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
3264 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3270 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3273 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3274 STATE_CHARACTER_NO_CHANGE,
3276 if (CA_STATUS_OK != res)
3278 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3279 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3282 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3285 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3286 if (CA_STATUS_OK != res)
3288 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3292 res = CALEClientDiscoverServices(env, gatt);
3293 if (CA_STATUS_OK != res)
3295 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3299 else // le disconnected
3301 CAResult_t res = CALEClientStartScan();
3302 if (CA_STATUS_OK != res)
3304 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3308 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3311 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3315 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3318 res = CALEClientRemoveDeviceState(address);
3319 if (CA_STATUS_OK != res)
3321 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3325 res = CALEClientRemoveGattObjForAddr(env, jni_address);
3326 if (CA_STATUS_OK != res)
3328 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr 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");
3346 CALEClientSendFinish(env, gatt);
3351 * Class: org_iotivity_ca_jar_caleinterface
3352 * Method: CALeGattServicesDiscoveredCallback
3353 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3355 JNIEXPORT void JNICALL
3356 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
3361 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
3362 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3363 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3364 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3366 if (0 != status) // discovery error
3368 CALEClientSendFinish(env, gatt);
3372 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3375 CALEClientSendFinish(env, gatt);
3379 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3382 CALEClientSendFinish(env, gatt);
3386 if (!CALEClientIsSetCharacteristic(address))
3388 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3391 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3395 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
3396 if (!jni_obj_GattCharacteristic)
3398 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3402 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
3403 jni_obj_GattCharacteristic);
3404 if (CA_STATUS_OK != res)
3406 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
3410 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
3411 if (CA_STATUS_OK != res)
3413 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
3414 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3415 if (CA_STATUS_OK != res)
3417 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3422 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3424 if (CA_STATUS_OK != res)
3426 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3432 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3433 if (CA_STATUS_OK != res)
3435 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3439 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3444 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3445 CALEClientSendFinish(env, gatt);
3450 * Class: org_iotivity_ca_jar_caleinterface
3451 * Method: CALeGattCharacteristicWritjclasseCallback
3452 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
3454 JNIEXPORT void JNICALL
3455 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
3456 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
3459 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
3460 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3461 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3462 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3465 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
3467 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
3469 // send success & signal
3470 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3476 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3482 if (GATT_SUCCESS != status) // error case
3484 OIC_LOG(ERROR, TAG, "send failure");
3485 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3487 if (CA_STATUS_OK != res)
3489 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3492 if (g_clientErrorCallback)
3494 jint length = (*env)->GetArrayLength(env, data);
3495 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
3498 CALEClientSendFinish(env, gatt);
3502 OIC_LOG(DEBUG, TAG, "send success");
3503 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3504 STATE_SEND_SUCCESS);
3505 if (CA_STATUS_OK != res)
3507 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3509 CALEClientUpdateSendCnt(env);
3512 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3518 CALEClientSendFinish(env, gatt);
3523 * Class: org_iotivity_ca_jar_caleinterface
3524 * Method: CALeGattCharacteristicChangedCallback
3525 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
3527 JNIEXPORT void JNICALL
3528 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
3529 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
3531 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
3532 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3533 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3534 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3535 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
3537 // get Byte Array and convert to uint8_t*
3538 jint length = (*env)->GetArrayLength(env, data);
3541 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
3543 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
3544 jni_byte_responseData);
3546 uint8_t* receivedData = OICMalloc(length);
3549 OIC_LOG(ERROR, TAG, "receivedData is null");
3553 memcpy(receivedData, jni_byte_responseData, length);
3554 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
3556 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3559 OIC_LOG(ERROR, TAG, "jni_address is null");
3560 OICFree(receivedData);
3564 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3567 OIC_LOG(ERROR, TAG, "address is null");
3568 OICFree(receivedData);
3572 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
3573 receivedData, length);
3575 ca_mutex_lock(g_bleServerBDAddressMutex);
3576 uint32_t sentLength = 0;
3577 g_CABLEClientDataReceivedCallback(address, receivedData, length,
3579 ca_mutex_unlock(g_bleServerBDAddressMutex);
3581 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3585 * Class: org_iotivity_ca_jar_caleinterface
3586 * Method: CALeGattDescriptorWriteCallback
3587 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
3589 JNIEXPORT void JNICALL
3590 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
3594 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
3595 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3596 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3597 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3599 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3600 if (CA_STATUS_OK != res)
3602 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3610 CALEClientSendFinish(env, gatt);