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 "calestate.h"
27 #include "caleclient.h"
28 #include "caleserver.h"
29 #include "caleutils.h"
30 #include "caleinterface.h"
31 #include "caadapterutils.h"
34 #include "oic_malloc.h"
35 #include "oic_string.h"
36 #include "cathreadpool.h" /* for thread pool */
38 #include "uarraylist.h"
39 #include "org_iotivity_ca_CaLeClientInterface.h"
41 #define TAG PCF("OIC_CA_LE_CLIENT")
43 #define MICROSECS_PER_SEC 1000000
44 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
45 #define WAIT_TIME_SCAN_INTERVAL_DEFAULT 10
46 #define WAIT_TIME_SCANNED_CHECKING 30
48 #define GATT_CONNECTION_PRIORITY_BALANCED 0
49 #define GATT_FAILURE 257
50 #define GATT_INSUFFICIENT_AUTHENTICATION 5
51 #define GATT_INSUFFICIENT_ENCRYPTION 15
52 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
53 #define GATT_INVALID_OFFSET 7
54 #define GATT_READ_NOT_PERMITTED 2
55 #define GATT_REQUEST_NOT_SUPPORTED 6
56 #define GATT_WRITE_NOT_PERMITTED 3
58 static ca_thread_pool_t g_threadPoolHandle = NULL;
61 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
62 static u_arraylist_t *g_gattObjectList = NULL;
63 static u_arraylist_t *g_deviceStateList = NULL;
65 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
66 static CABLEErrorHandleCallback g_clientErrorCallback;
67 static jobject g_leScanCallback = NULL;
68 static jobject g_leGattCallback = NULL;
69 static jobject g_context = NULL;
70 static jobjectArray g_uuidList = NULL;
72 // it will be prevent to start send logic when adapter has stopped.
73 static bool g_isStartedLEClient = false;
75 static jbyteArray g_sendBuffer = NULL;
76 static uint32_t g_targetCnt = 0;
77 static uint32_t g_currentSentCnt = 0;
78 static bool g_isFinishedSendData = false;
79 static oc_mutex g_SendFinishMutex = NULL;
80 static oc_mutex g_threadMutex = NULL;
81 static oc_cond g_threadCond = NULL;
82 static oc_cond g_deviceDescCond = NULL;
84 static oc_mutex g_threadSendMutex = NULL;
85 static oc_mutex g_threadWriteCharacteristicMutex = NULL;
86 static oc_cond g_threadWriteCharacteristicCond = NULL;
87 static bool g_isSignalSetFlag = false;
89 static oc_mutex g_bleReqRespClientCbMutex = NULL;
90 static oc_mutex g_bleServerBDAddressMutex = NULL;
92 static oc_mutex g_deviceListMutex = NULL;
93 static oc_mutex g_gattObjectMutex = NULL;
94 static oc_mutex g_deviceStateListMutex = NULL;
96 static oc_mutex g_deviceScanRetryDelayMutex = NULL;
97 static oc_cond g_deviceScanRetryDelayCond = NULL;
99 static oc_mutex g_threadScanIntervalMutex = NULL;
100 static oc_cond g_threadScanIntervalCond = NULL;
102 static oc_mutex g_threadSendStateMutex = NULL;
104 static int32_t g_scanIntervalTime = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
105 static int32_t g_scanIntervalTimePrev = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
106 static int32_t g_intervalCount = 0;
107 static bool g_isWorkingScanThread = false;
108 static CALEScanState_t g_curScanningStep = BLE_SCAN_NONE;
109 static CALEScanState_t g_nextScanningStep = BLE_SCAN_ENABLE;
111 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
113 static bool g_setHighQoS = true;
116 * check if retry logic for connection routine has to be stopped or not.
117 * in case of error value including this method, connection routine has to be stopped.
118 * since there is no retry logic for this error reason in this client.
119 * @param state constant value of bluetoothgatt.
120 * @return true - waiting for background connection in BT platform.
121 * false - connection routine has to be stopped.
123 static bool CALECheckConnectionStateValue(jint state)
127 case GATT_CONNECTION_PRIORITY_BALANCED:
129 case GATT_INSUFFICIENT_AUTHENTICATION:
130 case GATT_INSUFFICIENT_ENCRYPTION:
131 case GATT_INVALID_ATTRIBUTE_LENGTH:
132 case GATT_INVALID_OFFSET:
133 case GATT_READ_NOT_PERMITTED:
134 case GATT_REQUEST_NOT_SUPPORTED:
135 case GATT_WRITE_NOT_PERMITTED:
142 void CALEClientSetScanInterval(int32_t intervalTime, int32_t workingCount,
143 CALEScanState_t nextScanningStep)
145 OIC_LOG_V(DEBUG, TAG, "CALEClientSetScanInterval : %d -> %d, next scan state will be %d",
146 g_scanIntervalTime, intervalTime, nextScanningStep);
148 // previous time should be stored.
149 if (0 < workingCount)
151 g_scanIntervalTimePrev = g_scanIntervalTime;
153 g_scanIntervalTime = intervalTime;
154 g_intervalCount = workingCount;
155 g_nextScanningStep = nextScanningStep;
158 void CALERestartScanWithInterval(int32_t intervalTime, int32_t workingCount,
159 CALEScanState_t nextScanningStep)
161 if (intervalTime == g_scanIntervalTime
162 && workingCount == g_intervalCount
163 && nextScanningStep == g_nextScanningStep)
165 OIC_LOG(DEBUG, TAG, "setting duplicate interval time");
169 CALEClientSetScanInterval(intervalTime, workingCount, nextScanningStep);
170 oc_cond_signal(g_threadScanIntervalCond);
173 static void CALEScanThread(void* object)
177 bool isAttached = false;
179 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
182 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
183 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
187 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
193 oc_mutex_lock(g_threadScanIntervalMutex);
194 while(g_isWorkingScanThread)
196 OIC_LOG(DEBUG, TAG, "scan waiting time out");
197 if (BLE_SCAN_ENABLE == g_curScanningStep)
200 CAResult_t ret = CALEClientStopScan();
201 if (CA_STATUS_OK != ret)
203 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
206 else if (BLE_SCAN_DISABLE == g_curScanningStep)
209 CAResult_t ret = CALEClientStartScan();
210 if (CA_STATUS_OK != ret)
212 OIC_LOG(INFO, TAG, "CALEClientStartScan has failed");
217 OIC_LOG(DEBUG, TAG, "scan thread is started");
219 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
222 OIC_LOG_V(DEBUG, TAG, "wait for Scan Interval Time during %d sec", g_scanIntervalTime);
223 if (OC_WAIT_SUCCESS == oc_cond_wait_for(g_threadScanIntervalCond,
224 g_threadScanIntervalMutex,
225 g_scanIntervalTime * MICROSECS_PER_SEC))
227 // called signal scan thread will be terminated
228 OIC_LOG(DEBUG, TAG, "signal scanInterval waiting");
229 if (BLE_SCAN_DISABLE == g_nextScanningStep)
231 g_curScanningStep = BLE_SCAN_ENABLE;
235 g_curScanningStep = BLE_SCAN_DISABLE;
240 if (BLE_SCAN_ENABLE == g_curScanningStep)
242 if (g_intervalCount > 0)
244 if (g_intervalCount == 1)
246 OIC_LOG(DEBUG, TAG, "reset default time");
247 CALEClientSetScanInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
250 OIC_LOG_V(DEBUG, TAG, "interval count : %d", g_intervalCount);
252 g_curScanningStep = BLE_SCAN_DISABLE;
256 g_curScanningStep = BLE_SCAN_ENABLE;
260 oc_mutex_unlock(g_threadScanIntervalMutex);
264 (*g_jvm)->DetachCurrentThread(g_jvm);
268 CAResult_t CALEClientStartScanWithInterval()
270 OIC_LOG(DEBUG, TAG, "IN - CALEClientStartScanWithInterval");
272 if (g_isWorkingScanThread)
274 OIC_LOG(DEBUG, TAG, "scan interval logic already running");
278 // initialize scan flags
279 g_curScanningStep = BLE_SCAN_NONE;
280 g_isWorkingScanThread = true;
282 g_scanIntervalTime = g_scanIntervalTimePrev;
283 g_nextScanningStep = BLE_SCAN_ENABLE;
285 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
286 CALEScanThread, NULL))
288 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
289 g_isWorkingScanThread = false;
290 return CA_STATUS_FAILED;
293 OIC_LOG(DEBUG, TAG, "OUT - CALEClientStartScanWithInterval");
297 void CALEClientStopScanWithInterval()
299 g_isWorkingScanThread = false;
300 oc_cond_signal(g_threadScanIntervalCond);
304 void CALEClientJniInit()
306 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
307 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
310 void CALEClientJNISetContext()
312 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
313 g_context = (jobject) CANativeJNIGetContext();
316 CAResult_t CALECreateJniInterfaceObject()
318 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
322 OIC_LOG(ERROR, TAG, "g_context is null");
323 return CA_STATUS_FAILED;
328 OIC_LOG(ERROR, TAG, "g_jvm is null");
329 return CA_STATUS_FAILED;
332 bool isAttached = false;
334 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
337 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
338 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
342 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
343 return CA_STATUS_FAILED;
348 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
349 "getApplicationContext",
350 "()Landroid/content/Context;");
352 if (!mid_getApplicationContext)
354 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
355 return CA_STATUS_FAILED;
358 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
359 mid_getApplicationContext);
360 if (!jApplicationContext)
362 OIC_LOG(ERROR, TAG, "Could not get application context");
366 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
367 if (!jni_LEInterface)
369 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
373 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
374 "(Landroid/content/Context;)V");
375 if (!LeInterfaceConstructorMethod)
377 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
381 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
382 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
386 (*g_jvm)->DetachCurrentThread(g_jvm);
392 CACheckJNIException(env);
395 (*g_jvm)->DetachCurrentThread(g_jvm);
398 return CA_STATUS_FAILED;
401 CAResult_t CALEClientInitialize()
403 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
409 OIC_LOG(ERROR, TAG, "g_jvm is null");
410 return CA_STATUS_FAILED;
413 bool isAttached = false;
415 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
418 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
419 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
423 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
424 return CA_STATUS_FAILED;
429 CAResult_t ret = CALECheckPlatformVersion(env, 18);
430 if (CA_STATUS_OK != ret)
432 OIC_LOG(ERROR, TAG, "it is not supported");
436 (*g_jvm)->DetachCurrentThread(g_jvm);
442 ret = CALEClientInitGattMutexVaraibles();
443 if (CA_STATUS_OK != ret)
445 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
446 CALEClientTerminateGattMutexVariables();
450 (*g_jvm)->DetachCurrentThread(g_jvm);
456 g_deviceDescCond = oc_cond_new();
458 // init mutex for send logic
459 g_threadCond = oc_cond_new();
460 g_threadWriteCharacteristicCond = oc_cond_new();
461 g_deviceScanRetryDelayCond = oc_cond_new();
462 g_threadScanIntervalCond = oc_cond_new();
464 CALEClientCreateDeviceList();
465 CALEClientJNISetContext();
467 ret = CALEClientCreateUUIDList();
468 if (CA_STATUS_OK != ret)
470 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
474 (*g_jvm)->DetachCurrentThread(g_jvm);
480 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
481 if (CA_STATUS_OK != ret)
483 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
487 (*g_jvm)->DetachCurrentThread(g_jvm);
492 g_isStartedLEClient = true;
496 (*g_jvm)->DetachCurrentThread(g_jvm);
502 void CALEClientTerminate()
504 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
508 OIC_LOG(ERROR, TAG, "g_jvm is null");
512 bool isAttached = false;
514 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
517 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
518 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
522 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
529 CAResult_t ret = CALEClientStopScan();
530 if (CA_STATUS_OK != ret)
532 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
535 if (g_leScanCallback)
537 (*env)->DeleteGlobalRef(env, g_leScanCallback);
538 g_leScanCallback = NULL;
541 if (g_leGattCallback)
543 (*env)->DeleteGlobalRef(env, g_leGattCallback);
544 g_leGattCallback = NULL;
549 (*env)->DeleteGlobalRef(env, g_sendBuffer);
555 (*env)->DeleteGlobalRef(env, g_uuidList);
559 ret = CALERemoveAllDeviceState(g_deviceStateList,
560 g_deviceStateListMutex);
561 if (CA_STATUS_OK != ret)
563 OIC_LOG(ERROR, TAG, "CALERemoveAllDeviceState has failed");
566 ret = CALEClientRemoveAllScanDevices(env);
567 if (CA_STATUS_OK != ret)
569 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
572 ret = CALEClientRemoveAllGattObjs(env);
573 if (CA_STATUS_OK != ret)
575 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
578 CALEClientSetSendFinishFlag(true);
580 CALEClientTerminateGattMutexVariables();
581 CALEClientDestroyJniInterface();
583 oc_cond_free(g_deviceDescCond);
584 oc_cond_free(g_threadCond);
585 oc_cond_free(g_threadWriteCharacteristicCond);
586 oc_cond_free(g_deviceScanRetryDelayCond);
587 oc_cond_free(g_threadScanIntervalCond);
589 g_deviceDescCond = NULL;
591 g_threadWriteCharacteristicCond = NULL;
592 g_deviceScanRetryDelayCond = NULL;
593 g_threadScanIntervalCond = NULL;
595 g_isSignalSetFlag = false;
598 CALEClientStopScanWithInterval();
602 (*g_jvm)->DetachCurrentThread(g_jvm);
606 CAResult_t CALEClientDestroyJniInterface()
608 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
612 OIC_LOG(ERROR, TAG, "g_jvm is null");
613 return CA_STATUS_FAILED;
616 bool isAttached = false;
618 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
621 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
622 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
626 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
627 return CA_STATUS_FAILED;
632 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
633 if (!jni_LeInterface)
635 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
639 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
640 "destroyLeInterface",
642 if (!jni_InterfaceDestroyMethod)
644 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
648 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
650 if (CACheckJNIException(env))
652 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
656 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
660 (*g_jvm)->DetachCurrentThread(g_jvm);
666 CACheckJNIException(env);
671 (*g_jvm)->DetachCurrentThread(g_jvm);
674 return CA_STATUS_FAILED;
677 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
679 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
680 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
684 CAResult_t res = CALEClientDisconnect(env, gatt);
685 if (CA_STATUS_OK != res)
687 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
690 CALEClientUpdateSendCnt(env);
693 CAResult_t CALEClientSendNegotiationMessage(const char* address)
695 OIC_LOG_V(DEBUG, TAG, "CALEClientSendNegotiationMessage(%s)", address);
696 VERIFY_NON_NULL(address, TAG, "address is null");
698 return CALEClientSendUnicastMessageImpl(address, NULL, 0);
701 CAResult_t CALEClientSendUnicastMessage(const char* address,
703 const uint32_t dataLen)
705 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
706 VERIFY_NON_NULL(address, TAG, "address is null");
707 VERIFY_NON_NULL(data, TAG, "data is null");
709 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
712 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
713 const uint32_t dataLen)
715 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
716 VERIFY_NON_NULL(data, TAG, "data is null");
720 OIC_LOG(ERROR, TAG, "g_jvm is null");
721 return CA_STATUS_FAILED;
724 bool isAttached = false;
726 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
729 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
730 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
734 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
735 return CA_STATUS_FAILED;
740 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
741 if (CA_STATUS_OK != ret)
743 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
748 (*g_jvm)->DetachCurrentThread(g_jvm);
754 CAResult_t CALEClientStartUnicastServer(const char* address)
759 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
761 return CA_NOT_SUPPORTED;
764 CAResult_t CALEClientStartMulticastServer()
766 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
768 return CA_NOT_SUPPORTED;
771 void CALEClientStopUnicastServer()
773 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
776 void CALEClientStopMulticastServer()
778 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
781 void CALEClientSetCallback(CAPacketReceiveCallback callback)
783 g_packetReceiveCallback = callback;
786 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
788 g_clientErrorCallback = callback;
791 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
793 VERIFY_NON_NULL(env, TAG, "env");
797 OIC_LOG(ERROR, TAG, "g_deviceList is not available");
798 return CA_STATUS_FAILED;
801 if (0 == u_arraylist_length(g_deviceList) // multicast
802 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
804 // Wait for LE peripherals to be discovered.
806 // Number of times to wait for discovery to complete.
807 static size_t const RETRIES = 5;
809 static uint64_t const TIMEOUT =
810 2 * MICROSECS_PER_SEC; // Microseconds
812 // set scan interval and start scan
813 CALERestartScanWithInterval(WAIT_TIME_SCANNED_CHECKING, 1, BLE_SCAN_ENABLE);
815 bool devicesDiscovered = false;
816 for (size_t i = 0; i < RETRIES; ++i)
818 OIC_LOG(DEBUG, TAG, "waiting for target device");
819 if (oc_cond_wait_for(g_deviceDescCond,
821 TIMEOUT) == OC_WAIT_SUCCESS)
823 OIC_LOG(DEBUG, TAG, "time out");
824 oc_mutex_lock(g_deviceListMutex);
825 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
826 oc_mutex_unlock(g_deviceListMutex);
828 if (0 < scannedDeviceLen)
830 if (!address // multicast
831 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
833 devicesDiscovered = true;
840 OIC_LOG(INFO, TAG, "waiting..");
842 oc_mutex_lock(g_deviceScanRetryDelayMutex);
843 if (oc_cond_wait_for(g_deviceScanRetryDelayCond,
844 g_deviceScanRetryDelayMutex,
845 MICROSECS_PER_SEC) == OC_WAIT_SUCCESS)
847 OIC_LOG(INFO, TAG, "finish to waiting for target device");
848 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
851 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
854 // checking whether a target device is found while waiting for time-out.
855 if (CALEClientIsDeviceInScanDeviceList(env, address))
857 devicesDiscovered = true;
866 // reset scan interval time after checking scanned devices
867 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
869 // time out for scanning devices
870 if (!devicesDiscovered)
872 return CA_STATUS_FAILED;
877 OIC_LOG(DEBUG, TAG, "there is a target device in the scanned devices");
884 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
885 const uint32_t dataLen)
887 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
889 VERIFY_NON_NULL(address, TAG, "address is null");
893 OIC_LOG(ERROR, TAG, "g_jvm is null");
894 return CA_STATUS_FAILED;
897 bool isAttached = false;
899 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
902 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
903 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
906 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
907 return CA_STATUS_FAILED;
912 oc_mutex_lock(g_threadSendMutex);
914 CALEClientSetSendFinishFlag(false);
916 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
917 if (CA_STATUS_OK != ret)
919 OIC_LOG(INFO, TAG, "there is no scanned device");
923 if (g_context && g_deviceList)
925 uint32_t length = u_arraylist_length(g_deviceList);
926 for (uint32_t index = 0; index < length; index++)
928 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
931 OIC_LOG(ERROR, TAG, "jarrayObj is null");
935 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
938 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
942 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
945 OIC_LOG(ERROR, TAG, "setAddress is null");
946 CACheckJNIException(env);
950 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
952 if (!strcmp(setAddress, address))
954 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
955 (*env)->DeleteLocalRef(env, jni_setAddress);
959 (*env)->DeleteGlobalRef(env, g_sendBuffer);
963 if (data && dataLen > 0)
965 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
966 CACheckJNIException(env);
967 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
968 CACheckJNIException(env);
969 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
970 CACheckJNIException(env);
973 // Target device to send message is just one.
976 ret = CALEClientSendData(env, jarrayObj);
977 if (CA_STATUS_OK != ret)
979 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
983 OIC_LOG(INFO, TAG, "wake up");
986 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
987 (*env)->DeleteLocalRef(env, jni_setAddress);
991 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
993 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
994 // if there is no connection state.
995 oc_mutex_lock(g_threadMutex);
996 if (!g_isFinishedSendData)
998 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
999 oc_cond_wait(g_threadCond, g_threadMutex);
1000 OIC_LOG(DEBUG, TAG, "connection / send is finished for unicast");
1002 oc_mutex_unlock(g_threadMutex);
1006 (*g_jvm)->DetachCurrentThread(g_jvm);
1009 oc_mutex_unlock(g_threadSendMutex);
1010 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
1011 if (CALEIsValidState(address, CA_LE_SEND_STATE,
1014 g_deviceStateListMutex))
1016 OIC_LOG(INFO, TAG, "send success");
1019 else if (CALEIsValidState(address, CA_LE_SEND_STATE,
1020 STATE_SEND_MTU_NEGO_SUCCESS,
1022 g_deviceStateListMutex))
1024 OIC_LOG(INFO, TAG, "mtu nego success");
1029 OIC_LOG(ERROR, TAG, "send failure");
1030 ret = CA_SEND_FAILED;
1034 CAResult_t resetRet = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
1037 g_deviceStateListMutex);
1038 if (CA_STATUS_OK != resetRet)
1040 OIC_LOG_V(ERROR, TAG, "CALEUpdateDeviceState has failed (%d)", resetRet);
1041 ret = CA_SEND_FAILED;
1050 (*g_jvm)->DetachCurrentThread(g_jvm);
1053 oc_mutex_unlock(g_threadSendMutex);
1054 return CA_SEND_FAILED;
1057 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
1058 const uint32_t dataLen)
1060 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
1061 VERIFY_NON_NULL(data, TAG, "data is null");
1062 VERIFY_NON_NULL(env, TAG, "env is null");
1066 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1067 return CA_STATUS_FAILED;
1070 oc_mutex_lock(g_threadSendMutex);
1072 CALEClientSetSendFinishFlag(false);
1074 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1077 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1078 g_sendBuffer = NULL;
1081 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
1082 if (CA_STATUS_OK != res)
1084 OIC_LOG(INFO, TAG, "there is no scanned device");
1088 uint32_t length = u_arraylist_length(g_deviceList);
1089 g_targetCnt = length;
1091 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1092 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1093 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1095 for (uint32_t index = 0; index < length; index++)
1097 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1100 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
1104 res = CALEClientSendData(env, jarrayObj);
1105 if (res != CA_STATUS_OK)
1107 OIC_LOG(ERROR, TAG, "BT device - send has failed");
1111 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1113 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1114 oc_mutex_lock(g_threadMutex);
1115 if (!g_isFinishedSendData)
1117 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1118 oc_cond_wait(g_threadCond, g_threadMutex);
1119 OIC_LOG(DEBUG, TAG, "connection / send is finished for multicast");
1121 oc_mutex_unlock(g_threadMutex);
1122 oc_mutex_unlock(g_threadSendMutex);
1123 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1124 return CA_STATUS_OK;
1127 oc_mutex_unlock(g_threadSendMutex);
1128 OIC_LOG(ERROR, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1129 return CA_SEND_FAILED;
1132 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1134 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1135 VERIFY_NON_NULL(device, TAG, "device is null");
1136 VERIFY_NON_NULL(env, TAG, "env is null");
1138 // get BLE address from bluetooth device object.
1139 char* address = NULL;
1140 CALEState_t* state = NULL;
1141 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1144 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1145 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1148 OIC_LOG(ERROR, TAG, "address is not available");
1149 CACheckJNIException(env);
1150 return CA_STATUS_FAILED;
1152 oc_mutex_lock(g_deviceStateListMutex);
1153 state = CALEGetStateInfo(address, g_deviceStateList);
1154 oc_mutex_unlock(g_deviceStateListMutex);
1157 // Since disconnect event can be caused from BT stack while connection step is running.
1158 // DeviceState has to have current status for processing send failure.
1159 OIC_LOG(INFO, TAG, "set STATE_SEND_PREPARING");
1160 CAResult_t res = CALEClientUpdateDeviceStateWithBtDevice(env, device,
1162 STATE_SEND_PREPARING);
1163 if (CA_STATUS_OK != res)
1165 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceStateWithBtDevice has failed");
1168 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1170 return CA_STATUS_FAILED;
1175 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1177 // cancel previous connection request before connection
1178 // if there is gatt object in g_gattObjectList.
1181 jobject gatt = CALEClientGetGattObjInList(env, address);
1184 CAResult_t res = CALEClientDisconnect(env, gatt);
1185 if (CA_STATUS_OK != res)
1187 OIC_LOG(INFO, TAG, "there is no gatt object");
1190 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1193 // connection request
1194 jobject newGatt = CALEClientConnect(env, device,
1196 if (NULL == newGatt)
1198 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1199 return CA_STATUS_FAILED;
1204 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1205 STATE_SERVICE_CONNECTED,
1207 g_deviceStateListMutex))
1209 OIC_LOG(INFO, TAG, "GATT has already connected");
1211 jobject gatt = CALEClientGetGattObjInList(env, address);
1214 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1215 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1216 return CA_STATUS_FAILED;
1219 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1220 if (CA_STATUS_OK != ret)
1222 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1223 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1226 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1228 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1231 g_deviceStateListMutex))
1233 OIC_LOG(INFO, TAG, "service connecting...");
1235 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1238 g_deviceStateListMutex))
1240 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1242 // cancel previous connection request before connection
1243 // if there is gatt object in g_gattObjectList.
1246 jobject gatt = CALEClientGetGattObjInList(env, address);
1249 CAResult_t res = CALEClientDisconnect(env, gatt);
1250 if (CA_STATUS_OK != res)
1252 OIC_LOG(INFO, TAG, "there is no gatt object");
1255 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1258 OIC_LOG(DEBUG, TAG, "start to connect LE");
1259 jobject gatt = CALEClientConnect(env, device,
1260 CALEGetFlagFromState(env, jni_address,
1261 CA_LE_AUTO_CONNECT_FLAG,
1263 g_deviceStateListMutex));
1267 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1268 return CA_STATUS_FAILED;
1273 return CA_STATUS_OK;
1276 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1278 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1279 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1281 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1282 "()Landroid/bluetooth/BluetoothDevice;");
1283 if (!jni_mid_getDevice)
1285 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1289 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1290 if (!jni_obj_device)
1292 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1293 CACheckJNIException(env);
1297 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1300 OIC_LOG(ERROR, TAG, "jni_address is null");
1301 CACheckJNIException(env);
1311 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1314 OIC_LOG(DEBUG, TAG, "Gatt Close");
1315 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1316 VERIFY_NON_NULL(env, TAG, "env is null");
1318 // get BluetoothGatt method
1319 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1320 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1321 if (!jni_mid_closeGatt)
1323 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1324 return CA_STATUS_OK;
1327 // call disconnect gatt method
1328 OIC_LOG(DEBUG, TAG, "request to close GATT");
1329 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1331 if (CACheckJNIException(env))
1333 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1334 return CA_STATUS_FAILED;
1337 return CA_STATUS_OK;
1340 CAResult_t CALEClientStartScan()
1342 if (!g_isStartedLEClient)
1344 OIC_LOG(ERROR, TAG, "LE client is not started");
1345 return CA_STATUS_FAILED;
1350 OIC_LOG(ERROR, TAG, "g_jvm is null");
1351 return CA_STATUS_FAILED;
1354 bool isAttached = false;
1356 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1359 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1361 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1364 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1365 return CA_STATUS_FAILED;
1370 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1372 CAResult_t ret = CA_STATUS_OK;
1373 // scan gatt server with UUID
1374 if (g_leScanCallback && g_uuidList)
1377 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1379 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1381 if (CA_STATUS_OK != ret)
1383 if (CA_ADAPTER_NOT_ENABLED == ret)
1385 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1389 OIC_LOG(ERROR, TAG, "start scan has failed");
1396 (*g_jvm)->DetachCurrentThread(g_jvm);
1402 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1404 VERIFY_NON_NULL(callback, TAG, "callback is null");
1405 VERIFY_NON_NULL(env, TAG, "env is null");
1407 if (!CALEIsEnableBTAdapter(env))
1409 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1410 return CA_ADAPTER_NOT_ENABLED;
1413 // get default bt adapter class
1414 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1415 if (!jni_cid_BTAdapter)
1417 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1418 CACheckJNIException(env);
1419 return CA_STATUS_FAILED;
1422 // get remote bt adapter method
1423 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1424 "getDefaultAdapter",
1425 METHODID_OBJECTNONPARAM);
1426 if (!jni_mid_getDefaultAdapter)
1428 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1429 CACheckJNIException(env);
1430 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1431 return CA_STATUS_FAILED;
1434 // get start le scan method
1435 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1436 "(Landroid/bluetooth/BluetoothAdapter$"
1437 "LeScanCallback;)Z");
1438 if (!jni_mid_startLeScan)
1440 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1441 CACheckJNIException(env);
1442 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1443 return CA_STATUS_FAILED;
1446 // gat bt adapter object
1447 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1448 jni_mid_getDefaultAdapter);
1449 if (!jni_obj_BTAdapter)
1451 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1452 CACheckJNIException(env);
1453 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1454 return CA_STATUS_FAILED;
1457 // call start le scan method
1458 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1459 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1460 jni_mid_startLeScan, callback);
1461 if (!jni_obj_startLeScan)
1463 OIC_LOG(INFO, TAG, "startLeScan has failed");
1464 CACheckJNIException(env);
1468 OIC_LOG(DEBUG, TAG, "LeScan has started");
1471 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1472 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1473 return CA_STATUS_OK;
1476 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1478 VERIFY_NON_NULL(callback, TAG, "callback is null");
1479 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1480 VERIFY_NON_NULL(env, TAG, "env is null");
1482 if (!CALEIsEnableBTAdapter(env))
1484 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1485 return CA_ADAPTER_NOT_ENABLED;
1488 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1489 if (!jni_cid_BTAdapter)
1491 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1492 CACheckJNIException(env);
1493 return CA_STATUS_FAILED;
1496 // get remote bt adapter method
1497 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1498 "getDefaultAdapter",
1499 METHODID_OBJECTNONPARAM);
1500 if (!jni_mid_getDefaultAdapter)
1502 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1503 CACheckJNIException(env);
1504 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1505 return CA_STATUS_FAILED;
1508 // get start le scan method
1509 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1510 "([Ljava/util/UUID;Landroid/bluetooth/"
1511 "BluetoothAdapter$LeScanCallback;)Z");
1512 if (!jni_mid_startLeScan)
1514 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1515 CACheckJNIException(env);
1516 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1517 return CA_STATUS_FAILED;
1520 // get bt adapter object
1521 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1522 jni_mid_getDefaultAdapter);
1523 if (!jni_obj_BTAdapter)
1525 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1526 CACheckJNIException(env);
1527 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1528 return CA_STATUS_FAILED;
1531 // call start le scan method
1532 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1533 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1534 jni_mid_startLeScan, uuids, callback);
1535 if (!jni_obj_startLeScan)
1537 OIC_LOG(INFO, TAG, "startLeScan has failed");
1538 CACheckJNIException(env);
1542 OIC_LOG(DEBUG, TAG, "LeScan has started");
1545 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1546 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1547 return CA_STATUS_OK;
1550 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1552 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1553 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1556 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1559 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1563 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1564 "(Ljava/lang/String;)"
1565 "Ljava/util/UUID;");
1566 if (!jni_mid_fromString)
1568 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1572 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1573 CACheckJNIException(env);
1574 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1578 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1582 return jni_obj_uuid;
1585 CACheckJNIException(env);
1589 CAResult_t CALEClientStopScan()
1593 OIC_LOG(ERROR, TAG, "g_jvm is null");
1594 return CA_STATUS_FAILED;
1597 bool isAttached = false;
1599 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1602 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1603 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1606 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1607 return CA_STATUS_FAILED;
1612 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1613 if (CA_STATUS_OK != ret)
1615 if (CA_ADAPTER_NOT_ENABLED == ret)
1617 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1621 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1627 (*g_jvm)->DetachCurrentThread(g_jvm);
1633 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1635 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1636 VERIFY_NON_NULL(callback, TAG, "callback is null");
1637 VERIFY_NON_NULL(env, TAG, "env is null");
1639 if (!CALEIsEnableBTAdapter(env))
1641 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1642 return CA_ADAPTER_NOT_ENABLED;
1645 // get default bt adapter class
1646 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1647 if (!jni_cid_BTAdapter)
1649 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1650 CACheckJNIException(env);
1651 return CA_STATUS_FAILED;
1654 // get remote bt adapter method
1655 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1656 "getDefaultAdapter",
1657 METHODID_OBJECTNONPARAM);
1658 if (!jni_mid_getDefaultAdapter)
1660 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1661 CACheckJNIException(env);
1662 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1663 return CA_STATUS_FAILED;
1666 // get start le scan method
1667 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1668 "(Landroid/bluetooth/"
1669 "BluetoothAdapter$LeScanCallback;)V");
1670 if (!jni_mid_stopLeScan)
1672 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1673 CACheckJNIException(env);
1674 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1675 return CA_STATUS_FAILED;
1678 // gat bt adapter object
1679 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1680 jni_mid_getDefaultAdapter);
1681 if (!jni_obj_BTAdapter)
1683 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1684 CACheckJNIException(env);
1685 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1686 return CA_STATUS_FAILED;
1689 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
1690 // call start le scan method
1691 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1692 if (CACheckJNIException(env))
1694 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1695 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1696 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1697 return CA_STATUS_FAILED;
1700 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1701 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1702 return CA_STATUS_OK;
1705 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1707 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
1708 VERIFY_NON_NULL(env, TAG, "env is null");
1709 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1711 oc_mutex_lock(g_threadSendMutex);
1713 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1716 OIC_LOG(ERROR, TAG, "jni_address is not available");
1717 oc_mutex_unlock(g_threadSendMutex);
1718 return CA_STATUS_FAILED;
1721 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1724 OIC_LOG(ERROR, TAG, "address is not available");
1725 CACheckJNIException(env);
1726 oc_mutex_unlock(g_threadSendMutex);
1727 return CA_STATUS_FAILED;
1730 CAResult_t res = CA_STATUS_OK;
1731 if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1734 g_deviceStateListMutex))
1736 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
1737 if (NULL == newGatt)
1739 OIC_LOG(INFO, TAG, "newGatt is not available");
1740 res = CA_STATUS_FAILED;
1743 oc_mutex_unlock(g_threadSendMutex);
1748 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1750 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1751 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1752 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1754 // reset scan interval time after checking scanned devices
1755 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
1757 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1758 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1761 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1764 OIC_LOG(ERROR, TAG, "address is not available");
1768 // close the gatt service
1769 jobject gatt = CALEClientGetGattObjInList(env, address);
1772 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1773 if (CA_STATUS_OK != res)
1775 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1776 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1780 // clean previous gatt object after close profile service
1781 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1782 if (CA_STATUS_OK != res)
1784 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1785 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1789 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1792 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1795 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1799 // add new gatt object into g_gattObjectList
1800 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1801 if (CA_STATUS_OK != res)
1803 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1810 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1812 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1813 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1814 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1816 if (!g_leGattCallback)
1818 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1822 if (!CALEIsEnableBTAdapter(env))
1824 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1828 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1831 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1835 jobject jni_obj_connectGatt = NULL;
1836 jint jni_int_sdk = CALEGetBuildVersion(env);
1837 OIC_LOG_V(INFO, TAG, "API level is %d", jni_int_sdk);
1838 if (jni_int_sdk >= 23) // upper than API level 23
1840 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1842 "(Landroid/content/Context;ZLandroid/"
1843 "bluetooth/BluetoothGattCallback;I)"
1844 "Landroid/bluetooth/BluetoothGatt;");
1845 if (!jni_mid_connectGatt)
1847 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1851 jint jni_transport_le = CALEGetConstantsValue(env, CLASSPATH_BT_DEVICE, "TRANSPORT_LE");
1852 OIC_LOG_V(INFO, TAG, "CALL API - connectGatt with transport LE(%d)", jni_transport_le);
1853 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1854 jni_mid_connectGatt, NULL,
1855 autoconnect, g_leGattCallback,
1857 if (!jni_obj_connectGatt)
1859 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1860 CACheckJNIException(env);
1861 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1862 CALEClientUpdateSendCnt(env);
1867 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1870 else // lower than API level 23
1872 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1874 "(Landroid/content/Context;ZLandroid/"
1875 "bluetooth/BluetoothGattCallback;)"
1876 "Landroid/bluetooth/BluetoothGatt;");
1877 if (!jni_mid_connectGatt)
1879 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1883 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1884 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1885 jni_mid_connectGatt,
1887 autoconnect, g_leGattCallback);
1888 if (!jni_obj_connectGatt)
1890 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1891 CACheckJNIException(env);
1892 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1893 CALEClientUpdateSendCnt(env);
1898 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1902 return jni_obj_connectGatt;
1905 bool CALEClientIsConnected(const char* address)
1907 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1908 STATE_SERVICE_CONNECTED,
1910 g_deviceStateListMutex))
1912 OIC_LOG(DEBUG, TAG, "current state is connected");
1915 OIC_LOG(DEBUG, TAG, "current state is not connected");
1919 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1921 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1923 VERIFY_NON_NULL(env, TAG, "env is null");
1924 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1926 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1927 if (!jni_cid_BTAdapter)
1929 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1933 // get remote bt adapter method
1934 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1935 "getDefaultAdapter",
1936 METHODID_OBJECTNONPARAM);
1937 if (!jni_mid_getDefaultAdapter)
1939 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1943 // gat bt adapter object
1944 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1945 jni_mid_getDefaultAdapter);
1946 if (!jni_obj_BTAdapter)
1948 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1952 // get closeProfileProxy method
1953 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1954 "closeProfileProxy",
1955 "(ILandroid/bluetooth/"
1956 "BluetoothProfile;)V");
1957 if (!jni_mid_closeProfileProxy)
1959 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1963 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1964 if (!jni_cid_BTProfile)
1966 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1970 // GATT - Constant value : 7 (0x00000007)
1971 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1975 OIC_LOG(ERROR, TAG, "id_gatt is null");
1979 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1980 CACheckJNIException(env);
1982 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1983 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1984 if (CACheckJNIException(env))
1986 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1987 return CA_STATUS_FAILED;
1990 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1991 return CA_STATUS_OK;
1994 CACheckJNIException(env);
1995 return CA_STATUS_FAILED;
1999 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
2001 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
2002 VERIFY_NON_NULL(env, TAG, "env is null");
2003 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2005 // get BluetoothGatt method
2006 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
2007 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2008 "disconnect", "()V");
2009 if (!jni_mid_disconnectGatt)
2011 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
2012 return CA_STATUS_FAILED;
2015 // call disconnect gatt method
2016 OIC_LOG(INFO, TAG, "CALL API - disconnect");
2017 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
2018 if (CACheckJNIException(env))
2020 OIC_LOG(ERROR, TAG, "disconnect has failed");
2021 return CA_STATUS_FAILED;
2024 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
2026 return CA_STATUS_OK;
2029 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
2031 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
2032 VERIFY_NON_NULL(env, TAG, "env is null");
2034 if (!g_gattObjectList)
2036 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2037 return CA_STATUS_OK;
2040 uint32_t length = u_arraylist_length(g_gattObjectList);
2041 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
2042 for (uint32_t index = 0; index < length; index++)
2044 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
2045 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2048 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2051 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2052 if (CA_STATUS_OK != res)
2054 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2059 return CA_STATUS_OK;
2062 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
2064 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
2065 VERIFY_NON_NULL(env, TAG, "env is null");
2067 if (!g_gattObjectList)
2069 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2070 return CA_STATUS_OK;
2073 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
2076 OIC_LOG(ERROR, TAG, "address is null");
2077 CACheckJNIException(env);
2078 return CA_STATUS_FAILED;
2081 uint32_t length = u_arraylist_length(g_gattObjectList);
2082 for (uint32_t index = 0; index < length; index++)
2084 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2087 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2091 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2092 if (!jni_setAddress)
2094 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2095 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2096 return CA_STATUS_FAILED;
2099 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2102 OIC_LOG(ERROR, TAG, "setAddress is null");
2103 CACheckJNIException(env);
2104 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2105 return CA_STATUS_FAILED;
2108 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
2109 if (!strcmp(address, setAddress))
2111 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2112 if (CA_STATUS_OK != res)
2114 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2115 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2116 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2117 return CA_STATUS_FAILED;
2119 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2120 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2121 return CA_STATUS_OK;
2123 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2125 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2127 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
2128 return CA_STATUS_OK;
2131 CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size)
2133 VERIFY_NON_NULL(env, TAG, "env is null");
2134 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2136 if (!CALEIsEnableBTAdapter(env))
2138 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2139 return CA_ADAPTER_NOT_ENABLED;
2142 // get BluetoothGatt.requestMtu method
2143 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.requestMtu method");
2144 jmethodID jni_mid_requestMtu = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2145 "requestMtu", "(I)Z");
2146 if (!jni_mid_requestMtu)
2148 OIC_LOG(ERROR, TAG, "jni_mid_requestMtu is null");
2149 return CA_STATUS_FAILED;
2153 OIC_LOG(INFO, TAG, "CALL API - requestMtu");
2154 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_requestMtu, size);
2157 OIC_LOG(ERROR, TAG, "requestMtu has failed");
2158 CACheckJNIException(env);
2159 return CA_STATUS_FAILED;
2162 return CA_STATUS_OK;
2165 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
2167 VERIFY_NON_NULL(env, TAG, "env is null");
2168 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2170 if (!CALEIsEnableBTAdapter(env))
2172 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2173 return CA_ADAPTER_NOT_ENABLED;
2176 // get BluetoothGatt.discoverServices method
2177 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
2178 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2179 "discoverServices", "()Z");
2180 if (!jni_mid_discoverServices)
2182 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
2183 return CA_STATUS_FAILED;
2186 // call disconnect gatt method
2187 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
2188 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
2191 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
2192 CACheckJNIException(env);
2193 return CA_STATUS_FAILED;
2196 return CA_STATUS_OK;
2199 static void CALEWriteCharacteristicThread(void* object)
2201 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
2203 bool isAttached = false;
2205 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2208 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2209 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2213 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2219 jobject gatt = (jobject)object;
2220 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2221 if (CA_STATUS_OK != ret)
2223 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2228 (*g_jvm)->DetachCurrentThread(g_jvm);
2232 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2234 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
2236 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2237 VERIFY_NON_NULL(env, TAG, "env is null");
2239 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
2242 CALEClientSendFinish(env, gatt);
2243 return CA_STATUS_FAILED;
2246 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2249 CACheckJNIException(env);
2250 CALEClientSendFinish(env, gatt);
2251 return CA_STATUS_FAILED;
2254 oc_mutex_lock(g_threadSendStateMutex);
2256 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING,
2258 g_deviceStateListMutex))
2260 OIC_LOG(INFO, TAG, "current state is SENDING");
2261 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2262 oc_mutex_unlock(g_threadSendStateMutex);
2263 return CA_STATUS_OK;
2266 if (CA_STATUS_OK != CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
2269 g_deviceStateListMutex))
2271 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
2272 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2273 CALEClientSendFinish(env, gatt);
2274 oc_mutex_unlock(g_threadSendStateMutex);
2275 return CA_STATUS_FAILED;
2278 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2280 oc_mutex_unlock(g_threadSendStateMutex);
2283 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2284 if (!jni_obj_character)
2286 CALEClientSendFinish(env, gatt);
2287 return CA_STATUS_FAILED;
2290 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2291 if (CA_STATUS_OK != ret)
2293 CALEClientSendFinish(env, gatt);
2294 return CA_STATUS_FAILED;
2297 // wait for callback for write Characteristic with success to sent data
2298 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2299 oc_mutex_lock(g_threadWriteCharacteristicMutex);
2300 if (!g_isSignalSetFlag)
2302 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2303 if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
2304 g_threadWriteCharacteristicMutex,
2305 WAIT_TIME_WRITE_CHARACTERISTIC))
2307 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2308 g_isSignalSetFlag = false;
2309 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
2310 return CA_STATUS_FAILED;
2313 // reset flag set by writeCharacteristic Callback
2314 g_isSignalSetFlag = false;
2315 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
2317 CALEClientUpdateSendCnt(env);
2319 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2320 return CA_STATUS_OK;
2323 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2325 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2326 VERIFY_NON_NULL(env, TAG, "env is null");
2327 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2329 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2330 CACheckJNIException(env);
2331 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2332 CALEWriteCharacteristicThread, (void*)gattParam))
2334 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2335 return CA_STATUS_FAILED;
2338 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2339 return CA_STATUS_OK;
2342 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2343 jobject gattCharacteristic)
2345 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2346 VERIFY_NON_NULL(env, TAG, "env is null");
2347 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2348 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2350 if (!CALEIsEnableBTAdapter(env))
2352 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2353 return CA_STATUS_FAILED;
2356 // get BluetoothGatt.write characteristic method
2357 OIC_LOG(DEBUG, TAG, "write characteristic method");
2358 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2359 "writeCharacteristic",
2360 "(Landroid/bluetooth/"
2361 "BluetoothGattCharacteristic;)Z");
2362 if (!jni_mid_writeCharacteristic)
2364 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2365 return CA_STATUS_FAILED;
2368 // call disconnect gatt method
2369 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
2370 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2371 jni_mid_writeCharacteristic,
2372 gattCharacteristic);
2375 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2379 CACheckJNIException(env);
2380 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2381 return CA_STATUS_FAILED;
2384 return CA_STATUS_OK;
2387 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2389 VERIFY_NON_NULL(env, TAG, "env is null");
2390 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2392 if (!CALEIsEnableBTAdapter(env))
2394 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2395 return CA_STATUS_FAILED;
2398 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2401 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2402 CACheckJNIException(env);
2403 return CA_STATUS_FAILED;
2406 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2407 if (!jni_obj_GattCharacteristic)
2409 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2410 return CA_STATUS_FAILED;
2413 OIC_LOG(DEBUG, TAG, "read characteristic method");
2414 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2415 "readCharacteristic",
2416 "(Landroid/bluetooth/"
2417 "BluetoothGattCharacteristic;)Z");
2418 if (!jni_mid_readCharacteristic)
2420 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2421 return CA_STATUS_FAILED;
2424 // call disconnect gatt method
2425 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
2426 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2427 jni_obj_GattCharacteristic);
2430 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2434 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2435 CACheckJNIException(env);
2436 return CA_STATUS_FAILED;
2439 return CA_STATUS_OK;
2442 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2443 jobject characteristic)
2445 VERIFY_NON_NULL(env, TAG, "env is null");
2446 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2447 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2449 if (!CALEIsEnableBTAdapter(env))
2451 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2452 return CA_ADAPTER_NOT_ENABLED;
2455 // get BluetoothGatt.setCharacteristicNotification method
2456 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2457 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2458 "setCharacteristicNotification",
2459 "(Landroid/bluetooth/"
2460 "BluetoothGattCharacteristic;Z)Z");
2461 if (!jni_mid_setNotification)
2463 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2464 return CA_STATUS_FAILED;
2467 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
2468 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2469 characteristic, JNI_TRUE);
2470 if (JNI_TRUE == ret)
2472 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
2476 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
2477 CACheckJNIException(env);
2478 return CA_STATUS_FAILED;
2481 return CA_STATUS_OK;
2484 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2486 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2487 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2488 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2490 if (!CALEIsEnableBTAdapter(env))
2492 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2496 // get BluetoothGatt.getService method
2497 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2498 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2500 "(Ljava/util/UUID;)Landroid/bluetooth/"
2501 "BluetoothGattService;");
2502 if (!jni_mid_getService)
2504 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2508 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2509 if (!jni_obj_service_uuid)
2511 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2515 // get bluetooth gatt service
2516 OIC_LOG(DEBUG, TAG, "request to get service");
2517 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2518 jni_obj_service_uuid);
2519 if (!jni_obj_gattService)
2521 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2522 CACheckJNIException(env);
2526 // get bluetooth gatt service method
2527 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
2528 "BluetoothGattService",
2529 "getCharacteristic",
2530 "(Ljava/util/UUID;)"
2531 "Landroid/bluetooth/"
2532 "BluetoothGattCharacteristic;");
2533 if (!jni_mid_getCharacteristic)
2535 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2539 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2542 OIC_LOG(ERROR, TAG, "uuid is null");
2543 CACheckJNIException(env);
2547 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2548 if (!jni_obj_tx_uuid)
2550 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2551 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2555 OIC_LOG(DEBUG, TAG, "CALL API getCharacteristic");
2556 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2557 jni_mid_getCharacteristic,
2559 if (!jni_obj_GattCharacteristic)
2561 OIC_LOG(ERROR, TAG, "getCharacteristic has failed");
2562 CACheckJNIException(env);
2566 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2567 return jni_obj_GattCharacteristic;
2570 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2572 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2573 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2574 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2575 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2577 if (!CALEIsEnableBTAdapter(env))
2579 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2583 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2586 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2590 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2591 if (!jni_obj_GattCharacteristic)
2593 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2597 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2598 "/BluetoothGattCharacteristic");
2599 if (!jni_cid_BTGattCharacteristic)
2601 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2605 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2606 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2608 if (!jni_mid_setValue)
2610 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2614 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2616 if (JNI_TRUE == ret)
2618 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2622 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2628 OIC_LOG(DEBUG, TAG, "setWriteType with WRITE_TYPE_NO_RESPONSE");
2630 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2631 "setWriteType", "(I)V");
2632 if (!jni_mid_setWriteType)
2634 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2638 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2639 "WRITE_TYPE_NO_RESPONSE", "I");
2640 if (!jni_fid_no_response)
2642 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2646 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2647 jni_fid_no_response);
2648 CACheckJNIException(env);
2650 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2651 if (CACheckJNIException(env))
2653 OIC_LOG(ERROR, TAG, "setWriteType has failed");
2658 OIC_LOG(DEBUG, TAG, "It will run with response property");
2661 return jni_obj_GattCharacteristic;
2664 CACheckJNIException(env);
2668 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2670 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2671 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2673 if (!CALEIsEnableBTAdapter(env))
2675 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2679 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
2680 "BluetoothGattCharacteristic",
2681 "getValue", "()[B");
2682 if (!jni_mid_getValue)
2684 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2688 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2690 CACheckJNIException(env);
2691 return jni_obj_data_array;
2694 CAResult_t CALEClientCreateUUIDList()
2698 OIC_LOG(ERROR, TAG, "g_jvm is null");
2699 return CA_STATUS_FAILED;
2702 bool isAttached = false;
2704 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2707 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2708 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2712 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2713 return CA_STATUS_FAILED;
2718 // create new object array
2719 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2720 if (!jni_cid_uuid_list)
2722 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2723 CACheckJNIException(env);
2727 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2728 jni_cid_uuid_list, NULL);
2729 if (!jni_obj_uuid_list)
2731 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2732 CACheckJNIException(env);
2737 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2740 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2743 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2745 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2746 CACheckJNIException(env);
2750 (*g_jvm)->DetachCurrentThread(g_jvm);
2753 return CA_STATUS_OK;
2760 (*g_jvm)->DetachCurrentThread(g_jvm);
2762 return CA_STATUS_FAILED;
2765 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2766 jobject characteristic)
2768 VERIFY_NON_NULL(env, TAG, "env is null");
2769 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2770 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2772 if (!CALEIsEnableBTAdapter(env))
2774 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2775 return CA_ADAPTER_NOT_ENABLED;
2778 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2779 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
2780 "BluetoothGattCharacteristic",
2782 "(Ljava/util/UUID;)Landroid/bluetooth/"
2783 "BluetoothGattDescriptor;");
2784 if (!jni_mid_getDescriptor)
2786 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2787 return CA_STATUS_FAILED;
2790 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2791 if (!jni_obj_cc_uuid)
2793 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2796 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2797 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2798 jni_mid_getDescriptor, jni_obj_cc_uuid);
2799 if (!jni_obj_descriptor)
2801 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2805 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2806 jclass jni_cid_descriptor = (*env)->FindClass(env,
2807 "android/bluetooth/BluetoothGattDescriptor");
2808 if (!jni_cid_descriptor)
2810 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2814 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2815 if (!jni_mid_setValue)
2817 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2821 jfieldID jni_fid_NotiValue = NULL;
2824 OIC_LOG(DEBUG, TAG, "get ENABLE_INDICATION_VALUE");
2825 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2826 "ENABLE_INDICATION_VALUE", "[B");
2827 if (!jni_fid_NotiValue)
2829 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2835 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2836 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2837 "ENABLE_NOTIFICATION_VALUE", "[B");
2838 if (!jni_fid_NotiValue)
2840 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2845 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2846 env, jni_obj_descriptor, jni_mid_setValue,
2847 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2850 OIC_LOG(DEBUG, TAG, "setValue success");
2854 OIC_LOG(ERROR, TAG, "setValue has failed");
2858 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2860 "(Landroid/bluetooth/"
2861 "BluetoothGattDescriptor;)Z");
2862 if (!jni_mid_writeDescriptor)
2864 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2865 return CA_STATUS_FAILED;
2868 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
2869 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2870 jni_obj_descriptor);
2873 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2877 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2881 return CA_STATUS_OK;
2884 CACheckJNIException(env);
2885 return CA_STATUS_FAILED;
2888 void CALEClientCreateScanDeviceList(JNIEnv *env)
2890 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2891 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2893 oc_mutex_lock(g_deviceListMutex);
2894 // create new object array
2895 if (g_deviceList == NULL)
2897 OIC_LOG(DEBUG, TAG, "Create device list");
2899 g_deviceList = u_arraylist_create();
2901 oc_mutex_unlock(g_deviceListMutex);
2904 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2906 VERIFY_NON_NULL(device, TAG, "device is null");
2907 VERIFY_NON_NULL(env, TAG, "env is null");
2909 oc_mutex_lock(g_deviceListMutex);
2913 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2914 oc_mutex_unlock(g_deviceListMutex);
2915 return CA_STATUS_FAILED;
2918 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2919 if (!jni_remoteAddress)
2921 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2922 oc_mutex_unlock(g_deviceListMutex);
2923 return CA_STATUS_FAILED;
2926 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2929 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2930 CACheckJNIException(env);
2931 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2932 oc_mutex_unlock(g_deviceListMutex);
2933 return CA_STATUS_FAILED;
2936 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2938 jobject gdevice = (*env)->NewGlobalRef(env, device);
2939 CACheckJNIException(env);
2940 u_arraylist_add(g_deviceList, gdevice);
2941 oc_cond_signal(g_deviceDescCond);
2942 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
2944 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2945 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2947 oc_mutex_unlock(g_deviceListMutex);
2949 return CA_STATUS_OK;
2952 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2954 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2955 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2959 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2963 uint32_t length = u_arraylist_length(g_deviceList);
2964 for (uint32_t index = 0; index < length; index++)
2966 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2969 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2973 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2974 if (!jni_setAddress)
2976 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2980 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2983 OIC_LOG(ERROR, TAG, "setAddress is null");
2984 CACheckJNIException(env);
2985 (*env)->DeleteLocalRef(env, jni_setAddress);
2989 if (!strcmp(remoteAddress, setAddress))
2991 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2992 (*env)->DeleteLocalRef(env, jni_setAddress);
2996 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2997 (*env)->DeleteLocalRef(env, jni_setAddress);
3000 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in scanned device list", remoteAddress);
3005 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
3007 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
3008 VERIFY_NON_NULL(env, TAG, "env is null");
3010 oc_mutex_lock(g_deviceListMutex);
3014 OIC_LOG(ERROR, TAG, "g_deviceList is null");
3015 oc_mutex_unlock(g_deviceListMutex);
3016 return CA_STATUS_FAILED;
3019 uint32_t length = u_arraylist_length(g_deviceList);
3020 for (uint32_t index = 0; index < length; index++)
3022 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3025 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3028 (*env)->DeleteGlobalRef(env, jarrayObj);
3032 OICFree(g_deviceList);
3033 g_deviceList = NULL;
3035 oc_mutex_unlock(g_deviceListMutex);
3036 return CA_STATUS_OK;
3039 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
3041 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
3042 VERIFY_NON_NULL(address, TAG, "address is null");
3043 VERIFY_NON_NULL(env, TAG, "env is null");
3045 oc_mutex_lock(g_deviceListMutex);
3049 OIC_LOG(ERROR, TAG, "g_deviceList is null");
3050 oc_mutex_unlock(g_deviceListMutex);
3051 return CA_STATUS_FAILED;
3054 uint32_t length = u_arraylist_length(g_deviceList);
3055 for (uint32_t index = 0; index < length; index++)
3057 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3060 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3061 oc_mutex_unlock(g_deviceListMutex);
3062 return CA_STATUS_FAILED;
3065 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
3066 if (!jni_setAddress)
3068 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3069 oc_mutex_unlock(g_deviceListMutex);
3070 return CA_STATUS_FAILED;
3073 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3076 OIC_LOG(ERROR, TAG, "setAddress is null");
3077 CACheckJNIException(env);
3078 oc_mutex_unlock(g_deviceListMutex);
3079 return CA_STATUS_FAILED;
3082 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
3085 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3086 CACheckJNIException(env);
3087 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3088 oc_mutex_unlock(g_deviceListMutex);
3089 return CA_STATUS_FAILED;
3092 if (!strcmp(setAddress, remoteAddress))
3094 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3095 (*env)->DeleteGlobalRef(env, jarrayObj);
3097 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3098 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
3100 if (NULL == u_arraylist_remove(g_deviceList, index))
3102 OIC_LOG(ERROR, TAG, "List removal failed.");
3103 oc_mutex_unlock(g_deviceListMutex);
3104 return CA_STATUS_FAILED;
3106 oc_mutex_unlock(g_deviceListMutex);
3107 return CA_STATUS_OK;
3109 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3110 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
3113 oc_mutex_unlock(g_deviceListMutex);
3114 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
3116 return CA_STATUS_OK;
3123 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
3125 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
3126 VERIFY_NON_NULL(env, TAG, "env is null");
3127 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3129 oc_mutex_lock(g_gattObjectMutex);
3131 if (!g_gattObjectList)
3133 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
3134 oc_mutex_unlock(g_gattObjectMutex);
3135 return CA_STATUS_FAILED;
3138 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3139 if (!jni_remoteAddress)
3141 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3142 oc_mutex_unlock(g_gattObjectMutex);
3143 return CA_STATUS_FAILED;
3146 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3149 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3150 CACheckJNIException(env);
3151 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3152 oc_mutex_unlock(g_gattObjectMutex);
3153 return CA_STATUS_FAILED;
3156 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
3157 if (!CALEClientIsGattObjInList(env, remoteAddress))
3159 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
3160 u_arraylist_add(g_gattObjectList, newGatt);
3161 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
3164 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3165 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3166 oc_mutex_unlock(g_gattObjectMutex);
3167 return CA_STATUS_OK;
3170 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
3172 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
3173 VERIFY_NON_NULL(env, TAG, "env is null");
3174 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
3176 uint32_t length = u_arraylist_length(g_gattObjectList);
3177 for (uint32_t index = 0; index < length; index++)
3179 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3182 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3186 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3187 if (!jni_setAddress)
3189 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3193 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3196 OIC_LOG(ERROR, TAG, "setAddress is null");
3197 CACheckJNIException(env);
3198 (*env)->DeleteLocalRef(env, jni_setAddress);
3202 if (!strcmp(remoteAddress, setAddress))
3204 OIC_LOG(DEBUG, TAG, "the device is already set");
3205 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3206 (*env)->DeleteLocalRef(env, jni_setAddress);
3209 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3210 (*env)->DeleteLocalRef(env, jni_setAddress);
3213 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
3217 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
3219 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
3220 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3221 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3223 oc_mutex_lock(g_gattObjectMutex);
3224 uint32_t length = u_arraylist_length(g_gattObjectList);
3225 for (uint32_t index = 0; index < length; index++)
3227 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3230 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3231 oc_mutex_unlock(g_gattObjectMutex);
3235 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3236 if (!jni_setAddress)
3238 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3239 oc_mutex_unlock(g_gattObjectMutex);
3243 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3246 OIC_LOG(ERROR, TAG, "setAddress is null");
3247 CACheckJNIException(env);
3248 (*env)->DeleteLocalRef(env, jni_setAddress);
3249 oc_mutex_unlock(g_gattObjectMutex);
3253 if (!strcmp(remoteAddress, setAddress))
3255 OIC_LOG(DEBUG, TAG, "the device is already set");
3256 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3257 oc_mutex_unlock(g_gattObjectMutex);
3260 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3261 (*env)->DeleteLocalRef(env, jni_setAddress);
3264 oc_mutex_unlock(g_gattObjectMutex);
3265 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
3269 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
3271 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
3272 VERIFY_NON_NULL(env, TAG, "env is null");
3274 oc_mutex_lock(g_gattObjectMutex);
3275 if (!g_gattObjectList)
3277 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3278 oc_mutex_unlock(g_gattObjectMutex);
3279 return CA_STATUS_OK;
3282 uint32_t length = u_arraylist_length(g_gattObjectList);
3283 for (uint32_t index = 0; index < length; index++)
3285 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3288 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3291 (*env)->DeleteGlobalRef(env, jarrayObj);
3295 OICFree(g_gattObjectList);
3296 g_gattObjectList = NULL;
3297 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3298 oc_mutex_unlock(g_gattObjectMutex);
3299 return CA_STATUS_OK;
3302 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3304 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3305 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3306 VERIFY_NON_NULL(env, TAG, "env is null");
3308 oc_mutex_lock(g_gattObjectMutex);
3309 if (!g_gattObjectList)
3311 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3312 oc_mutex_unlock(g_gattObjectMutex);
3313 return CA_STATUS_OK;
3316 uint32_t length = u_arraylist_length(g_gattObjectList);
3317 for (uint32_t index = 0; index < length; index++)
3319 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3322 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3323 oc_mutex_unlock(g_gattObjectMutex);
3324 return CA_STATUS_FAILED;
3327 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3328 if (!jni_setAddress)
3330 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3331 oc_mutex_unlock(g_gattObjectMutex);
3332 return CA_STATUS_FAILED;
3335 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3338 OIC_LOG(ERROR, TAG, "setAddress is null");
3339 CACheckJNIException(env);
3340 oc_mutex_unlock(g_gattObjectMutex);
3341 return CA_STATUS_FAILED;
3344 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3345 if (!jni_remoteAddress)
3347 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3348 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3349 oc_mutex_unlock(g_gattObjectMutex);
3350 return CA_STATUS_FAILED;
3353 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3356 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3357 CACheckJNIException(env);
3358 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3359 oc_mutex_unlock(g_gattObjectMutex);
3360 return CA_STATUS_FAILED;
3363 if (!strcmp(setAddress, remoteAddress))
3365 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3366 (*env)->DeleteGlobalRef(env, jarrayObj);
3368 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3369 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3371 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3373 OIC_LOG(ERROR, TAG, "List removal failed.");
3374 oc_mutex_unlock(g_gattObjectMutex);
3375 return CA_STATUS_FAILED;
3377 oc_mutex_unlock(g_gattObjectMutex);
3378 return CA_STATUS_OK;
3380 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3381 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3384 oc_mutex_unlock(g_gattObjectMutex);
3385 OIC_LOG(DEBUG, TAG, "there are no target object");
3386 return CA_STATUS_OK;
3389 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3391 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3392 VERIFY_NON_NULL(addr, TAG, "addr is null");
3393 VERIFY_NON_NULL(env, TAG, "env is null");
3395 oc_mutex_lock(g_gattObjectMutex);
3396 if (!g_gattObjectList)
3398 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3399 oc_mutex_unlock(g_gattObjectMutex);
3400 return CA_STATUS_OK;
3403 uint32_t length = u_arraylist_length(g_gattObjectList);
3404 for (uint32_t index = 0; index < length; index++)
3406 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3409 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3410 oc_mutex_unlock(g_gattObjectMutex);
3411 return CA_STATUS_FAILED;
3414 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3415 if (!jni_setAddress)
3417 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3418 oc_mutex_unlock(g_gattObjectMutex);
3419 return CA_STATUS_FAILED;
3422 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3425 OIC_LOG(ERROR, TAG, "setAddress is null");
3426 CACheckJNIException(env);
3427 oc_mutex_unlock(g_gattObjectMutex);
3428 return CA_STATUS_FAILED;
3431 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3434 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3435 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3436 oc_mutex_unlock(g_gattObjectMutex);
3437 return CA_STATUS_FAILED;
3440 if (!strcmp(setAddress, remoteAddress))
3442 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3443 (*env)->DeleteGlobalRef(env, jarrayObj);
3445 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3446 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3447 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3449 OIC_LOG(ERROR, TAG, "List removal failed.");
3450 oc_mutex_unlock(g_gattObjectMutex);
3451 return CA_STATUS_FAILED;
3453 oc_mutex_unlock(g_gattObjectMutex);
3454 return CA_STATUS_OK;
3456 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3457 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3460 oc_mutex_unlock(g_gattObjectMutex);
3461 OIC_LOG(DEBUG, TAG, "there are no target object");
3462 return CA_STATUS_FAILED;
3465 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3467 OIC_LOG(DEBUG, TAG, "CALEClientGetLEAddressFromBTDevice");
3469 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3470 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3472 // get Bluetooth Address
3473 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3474 if (!jni_btTargetAddress)
3476 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3480 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3483 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3484 CACheckJNIException(env);
3488 // get method ID of getDevice()
3489 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3490 "getDevice", METHODID_BT_DEVICE);
3491 if (!jni_mid_getDevice)
3493 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3494 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3498 oc_mutex_lock(g_gattObjectMutex);
3500 size_t length = u_arraylist_length(g_gattObjectList);
3501 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
3502 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3504 for (size_t index = 0; index < length; index++)
3506 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3509 oc_mutex_unlock(g_gattObjectMutex);
3510 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3511 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3515 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3516 if (!jni_obj_device)
3518 CACheckJNIException(env);
3519 oc_mutex_unlock(g_gattObjectMutex);
3520 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3521 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3525 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3528 oc_mutex_unlock(g_gattObjectMutex);
3529 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3530 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3531 (*env)->DeleteLocalRef(env, jni_obj_device);
3535 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3538 CACheckJNIException(env);
3539 oc_mutex_unlock(g_gattObjectMutex);
3540 OIC_LOG(ERROR, TAG, "btAddress is not available");
3541 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3542 (*env)->DeleteLocalRef(env, jni_btAddress);
3543 (*env)->DeleteLocalRef(env, jni_obj_device);
3547 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
3548 if (!strcmp(targetAddress, btAddress))
3550 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3553 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3556 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3558 oc_mutex_unlock(g_gattObjectMutex);
3559 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3560 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3561 (*env)->DeleteLocalRef(env, jni_btAddress);
3562 (*env)->DeleteLocalRef(env, jni_obj_device);
3563 return jni_LEAddress;
3565 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3566 (*env)->DeleteLocalRef(env, jni_btAddress);
3567 (*env)->DeleteLocalRef(env, jni_obj_device);
3569 oc_mutex_unlock(g_gattObjectMutex);
3571 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3572 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
3579 CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env,
3581 uint16_t state_type,
3582 uint16_t target_state)
3584 VERIFY_NON_NULL(device, TAG, "device is null");
3586 // get Bluetooth Address
3587 jstring jni_Address = CALEGetAddressFromBTDevice(env, device);
3590 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3591 return CA_STATUS_FAILED;
3594 const char* address = (*env)->GetStringUTFChars(env, jni_Address, NULL);
3597 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3598 CACheckJNIException(env);
3599 (*env)->DeleteLocalRef(env, jni_Address);
3600 return CA_STATUS_FAILED;
3603 if (CALEIsValidState(address, state_type, target_state,
3605 g_deviceStateListMutex))
3607 (*env)->DeleteLocalRef(env, jni_Address);
3608 return CA_STATUS_OK;
3611 CAResult_t res = CALEUpdateDeviceState(address, state_type,
3614 g_deviceStateListMutex);
3615 if (CA_STATUS_OK != res)
3617 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
3619 (*env)->ReleaseStringUTFChars(env, jni_Address, address);
3620 (*env)->DeleteLocalRef(env, jni_Address);
3625 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
3626 jint state_idx, jboolean flag)
3628 return CALESetFlagToState(env, jni_address, state_idx, flag,
3629 g_deviceStateList, g_deviceStateListMutex);
3632 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
3634 return CALEGetFlagFromState(env, jni_address, state_idx, g_deviceStateList,
3635 g_deviceStateListMutex);
3638 uint16_t CALEClientGetMtuSize(const char* address)
3640 return CALEGetMtuSize(address, g_deviceStateList, g_deviceStateListMutex);
3643 void CALEClientCreateDeviceList()
3645 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3647 // create new object array
3648 if (!g_gattObjectList)
3650 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3652 g_gattObjectList = u_arraylist_create();
3655 if (!g_deviceStateList)
3657 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3659 g_deviceStateList = u_arraylist_create();
3664 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3666 g_deviceList = u_arraylist_create();
3670 CAResult_t CALEClientResetDeviceStateForAll()
3672 return CALEResetDeviceStateForAll(g_deviceStateList, g_deviceStateListMutex);
3676 * Check Sent Count for remove g_sendBuffer
3678 void CALEClientUpdateSendCnt(JNIEnv *env)
3680 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3682 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3684 oc_mutex_lock(g_threadMutex);
3688 if (g_targetCnt <= g_currentSentCnt)
3691 g_currentSentCnt = 0;
3695 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3696 g_sendBuffer = NULL;
3698 // notity the thread
3699 oc_cond_signal(g_threadCond);
3701 CALEClientSetSendFinishFlag(true);
3702 OIC_LOG(DEBUG, TAG, "set signal for send data");
3705 #ifdef SCAN_INTERVAL
3706 // reset interval scan logic
3707 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
3711 oc_mutex_unlock(g_threadMutex);
3714 CAResult_t CALEClientInitGattMutexVaraibles()
3716 if (NULL == g_bleReqRespClientCbMutex)
3718 g_bleReqRespClientCbMutex = oc_mutex_new();
3719 if (NULL == g_bleReqRespClientCbMutex)
3721 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3722 return CA_STATUS_FAILED;
3726 if (NULL == g_bleServerBDAddressMutex)
3728 g_bleServerBDAddressMutex = oc_mutex_new();
3729 if (NULL == g_bleServerBDAddressMutex)
3731 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3732 return CA_STATUS_FAILED;
3736 if (NULL == g_threadMutex)
3738 g_threadMutex = oc_mutex_new();
3739 if (NULL == g_threadMutex)
3741 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3742 return CA_STATUS_FAILED;
3746 if (NULL == g_threadSendMutex)
3748 g_threadSendMutex = oc_mutex_new();
3749 if (NULL == g_threadSendMutex)
3751 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3752 return CA_STATUS_FAILED;
3756 if (NULL == g_deviceListMutex)
3758 g_deviceListMutex = oc_mutex_new();
3759 if (NULL == g_deviceListMutex)
3761 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3762 return CA_STATUS_FAILED;
3766 if (NULL == g_gattObjectMutex)
3768 g_gattObjectMutex = oc_mutex_new();
3769 if (NULL == g_gattObjectMutex)
3771 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3772 return CA_STATUS_FAILED;
3776 if (NULL == g_deviceStateListMutex)
3778 g_deviceStateListMutex = oc_mutex_new();
3779 if (NULL == g_deviceStateListMutex)
3781 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3782 return CA_STATUS_FAILED;
3786 if (NULL == g_SendFinishMutex)
3788 g_SendFinishMutex = oc_mutex_new();
3789 if (NULL == g_SendFinishMutex)
3791 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3792 return CA_STATUS_FAILED;
3796 if (NULL == g_threadWriteCharacteristicMutex)
3798 g_threadWriteCharacteristicMutex = oc_mutex_new();
3799 if (NULL == g_threadWriteCharacteristicMutex)
3801 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3802 return CA_STATUS_FAILED;
3806 if (NULL == g_deviceScanRetryDelayMutex)
3808 g_deviceScanRetryDelayMutex = oc_mutex_new();
3809 if (NULL == g_deviceScanRetryDelayMutex)
3811 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3812 return CA_STATUS_FAILED;
3816 if (NULL == g_threadSendStateMutex)
3818 g_threadSendStateMutex = oc_mutex_new();
3819 if (NULL == g_threadSendStateMutex)
3821 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3822 return CA_STATUS_FAILED;
3826 if (NULL == g_threadScanIntervalMutex)
3828 g_threadScanIntervalMutex = oc_mutex_new();
3829 if (NULL == g_threadScanIntervalMutex)
3831 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3832 return CA_STATUS_FAILED;
3836 return CA_STATUS_OK;
3839 void CALEClientTerminateGattMutexVariables()
3841 oc_mutex_free(g_bleReqRespClientCbMutex);
3842 g_bleReqRespClientCbMutex = NULL;
3844 oc_mutex_free(g_bleServerBDAddressMutex);
3845 g_bleServerBDAddressMutex = NULL;
3847 oc_mutex_free(g_threadMutex);
3848 g_threadMutex = NULL;
3850 oc_mutex_free(g_threadSendMutex);
3851 g_threadSendMutex = NULL;
3853 oc_mutex_free(g_deviceListMutex);
3854 g_deviceListMutex = NULL;
3856 oc_mutex_free(g_SendFinishMutex);
3857 g_SendFinishMutex = NULL;
3859 oc_mutex_free(g_threadWriteCharacteristicMutex);
3860 g_threadWriteCharacteristicMutex = NULL;
3862 oc_mutex_free(g_deviceScanRetryDelayMutex);
3863 g_deviceScanRetryDelayMutex = NULL;
3865 oc_mutex_free(g_threadSendStateMutex);
3866 g_threadSendStateMutex = NULL;
3868 oc_mutex_free(g_threadScanIntervalMutex);
3869 g_threadScanIntervalMutex = NULL;
3872 void CALEClientSetSendFinishFlag(bool flag)
3874 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3876 oc_mutex_lock(g_SendFinishMutex);
3877 g_isFinishedSendData = flag;
3878 oc_mutex_unlock(g_SendFinishMutex);
3885 CAResult_t CAStartLEGattClient()
3887 // init mutex for send logic
3888 if (!g_deviceDescCond)
3890 g_deviceDescCond = oc_cond_new();
3895 g_threadCond = oc_cond_new();
3898 if (!g_threadWriteCharacteristicCond)
3900 g_threadWriteCharacteristicCond = oc_cond_new();
3903 if (!g_threadScanIntervalCond)
3905 g_threadScanIntervalCond = oc_cond_new();
3908 CAResult_t ret = CALEClientStartScanWithInterval();
3909 if (CA_STATUS_OK != ret)
3911 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
3915 g_isStartedLEClient = true;
3916 return CA_STATUS_OK;
3919 void CAStopLEGattClient()
3921 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3925 OIC_LOG(ERROR, TAG, "g_jvm is null");
3929 bool isAttached = false;
3931 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3934 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3935 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3939 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3945 CAResult_t ret = CALEClientDisconnectAll(env);
3946 if (CA_STATUS_OK != ret)
3948 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3951 CALEClientStopScanWithInterval();
3953 oc_mutex_lock(g_threadMutex);
3954 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3955 oc_cond_signal(g_threadCond);
3956 CALEClientSetSendFinishFlag(true);
3957 oc_mutex_unlock(g_threadMutex);
3959 oc_mutex_lock(g_threadSendMutex);
3960 OIC_LOG(DEBUG, TAG, "signal - g_deviceDesc cond");
3961 oc_cond_signal(g_deviceDescCond);
3962 oc_mutex_unlock(g_threadSendMutex);
3964 oc_mutex_lock(g_threadWriteCharacteristicMutex);
3965 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3966 oc_cond_signal(g_threadWriteCharacteristicCond);
3967 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3969 oc_mutex_lock(g_deviceScanRetryDelayMutex);
3970 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3971 oc_cond_signal(g_deviceScanRetryDelayCond);
3972 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
3974 oc_mutex_lock(g_threadScanIntervalMutex);
3975 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3976 oc_cond_signal(g_threadScanIntervalCond);
3977 oc_mutex_unlock(g_threadScanIntervalMutex);
3979 oc_cond_free(g_deviceDescCond);
3980 oc_cond_free(g_threadCond);
3981 oc_cond_free(g_threadWriteCharacteristicCond);
3982 oc_cond_free(g_deviceScanRetryDelayCond);
3983 oc_cond_free(g_threadScanIntervalCond);
3985 g_deviceDescCond = NULL;
3986 g_threadCond = NULL;
3987 g_threadWriteCharacteristicCond = NULL;
3988 g_deviceScanRetryDelayCond = NULL;
3989 g_threadScanIntervalCond = NULL;
3993 (*g_jvm)->DetachCurrentThread(g_jvm);
3998 CAResult_t CAInitializeLEGattClient()
4000 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
4001 CALEClientInitialize();
4002 return CA_STATUS_OK;
4005 void CATerminateLEGattClient()
4007 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
4008 CAStopLEGattClient();
4009 CALEClientTerminate();
4012 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
4013 uint32_t dataLen, CALETransferType_t type,
4016 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
4017 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
4019 if (LE_UNICAST != type || position < 0)
4021 OIC_LOG(ERROR, TAG, "this request is not unicast");
4022 return CA_STATUS_INVALID_PARAM;
4025 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4028 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4030 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4031 VERIFY_NON_NULL(data, TAG, "data is null");
4033 return CALEClientSendMulticastMessage(data, dataLen);
4036 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4038 oc_mutex_lock(g_bleReqRespClientCbMutex);
4039 g_CABLEClientDataReceivedCallback = callback;
4040 oc_mutex_unlock(g_bleReqRespClientCbMutex);
4043 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4045 g_threadPoolHandle = handle;
4048 CAResult_t CAGetLEAddress(char **local_address)
4050 VERIFY_NON_NULL(local_address, TAG, "local_address");
4051 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
4052 return CA_NOT_SUPPORTED;
4055 JNIEXPORT void JNICALL
4056 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4059 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4060 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4061 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4062 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4064 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4065 CACheckJNIException(env);
4068 JNIEXPORT void JNICALL
4069 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4072 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4073 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4074 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4075 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4077 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4078 CACheckJNIException(env);
4081 JNIEXPORT void JNICALL
4082 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4085 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4086 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4087 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4089 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4090 if (CA_STATUS_OK != res)
4092 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4097 * Class: org_iotivity_ca_jar_caleinterface
4098 * Method: CALeGattConnectionStateChangeCallback
4099 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4101 JNIEXPORT void JNICALL
4102 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4108 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4110 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4111 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4112 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4114 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4116 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4119 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4123 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4126 OIC_LOG(ERROR, TAG, "address is null");
4127 CACheckJNIException(env);
4130 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
4132 if (state_connected == newstate)
4134 OIC_LOG(DEBUG, TAG, "LE is connected");
4135 if (GATT_SUCCESS == status)
4137 CAResult_t res = CALEUpdateDeviceState(address,
4138 CA_LE_CONNECTION_STATE,
4141 g_deviceStateListMutex);
4142 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4143 if (CA_STATUS_OK != res)
4145 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4149 res = CALEClientAddGattobjToList(env, gatt);
4150 if (CA_STATUS_OK != res)
4152 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4156 res = CALEClientDiscoverServices(env, gatt);
4157 if (CA_STATUS_OK != res)
4159 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4165 OIC_LOG(INFO, TAG, "unknown status");
4166 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4169 else // STATE_DISCONNECTED == newstate
4171 OIC_LOG(DEBUG, TAG, "LE is disconnected");
4173 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SEND_PREPARING,
4174 g_deviceStateList, g_deviceStateListMutex))
4176 OIC_LOG(INFO, TAG, "current state is STATE_SEND_PREPARING");
4177 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
4180 g_deviceStateListMutex);
4181 if (CA_STATUS_OK != res)
4183 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4187 CAResult_t res = CALEUpdateDeviceState(address,
4188 CA_LE_CONNECTION_STATE,
4191 g_deviceStateListMutex);
4192 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4193 if (CA_STATUS_OK != res)
4195 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4199 res = CALEClientGattClose(env, gatt);
4200 if (CA_STATUS_OK != res)
4202 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4205 if (CALECheckConnectionStateValue(status))
4207 // this state is unexpected reason to disconnect
4208 // if the reason is suitable, connection logic of the device will be destroyed.
4209 OIC_LOG(INFO, TAG, "connection logic destroy");
4214 // other reason except for gatt_success is expected to running
4215 // background connection in BT platform.
4216 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
4217 CALEClientUpdateSendCnt(env);
4225 CALEClientSendFinish(env, gatt);
4230 * Class: org_iotivity_ca_jar_caleinterface
4231 * Method: CALeGattServicesDiscoveredCallback
4232 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4234 JNIEXPORT void JNICALL
4235 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4240 OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status);
4241 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4242 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4243 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4245 if (GATT_SUCCESS != status) // discovery error
4247 CALEClientSendFinish(env, gatt);
4251 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4254 CALEClientSendFinish(env, gatt);
4258 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4261 CACheckJNIException(env);
4262 CALEClientSendFinish(env, gatt);
4266 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4269 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4273 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4274 if (!jni_obj_GattCharacteristic)
4276 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4280 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4281 jni_obj_GattCharacteristic);
4282 if (CA_STATUS_OK != res)
4284 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4288 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4289 if (CA_STATUS_OK != res)
4291 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4293 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE,
4294 g_deviceStateList, g_deviceStateListMutex);
4295 if (CA_STATUS_OK != res)
4297 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
4301 res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4302 STATE_SERVICE_CONNECTED,
4304 g_deviceStateListMutex);
4305 if (CA_STATUS_OK != res)
4307 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4311 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
4312 if (CA_STATUS_OK != res)
4314 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
4320 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE,
4321 g_deviceStateList, g_deviceStateListMutex);
4322 if (CA_STATUS_OK != res)
4324 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
4329 #ifdef SCAN_INTERVAL
4330 // reset interval scan logic
4331 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
4334 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4335 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4340 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4341 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4342 CALEClientSendFinish(env, gatt);
4347 * Class: org_iotivity_ca_jar_caleinterface
4348 * Method: CALeGattCharacteristicWritjclasseCallback
4349 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4351 JNIEXPORT void JNICALL
4352 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4353 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status)
4355 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4356 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4357 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4358 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4360 // send success & signal
4361 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4367 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4370 CACheckJNIException(env);
4374 if (GATT_SUCCESS != status) // error case
4376 OIC_LOG(ERROR, TAG, "send failure");
4379 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4380 if (CA_STATUS_OK != res)
4382 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4383 oc_mutex_lock(g_threadWriteCharacteristicMutex);
4384 g_isSignalSetFlag = true;
4385 oc_cond_signal(g_threadWriteCharacteristicCond);
4386 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
4388 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
4391 g_deviceStateListMutex);
4392 if (CA_STATUS_OK != res)
4394 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4397 if (g_clientErrorCallback)
4399 jint length = (*env)->GetArrayLength(env, data);
4400 CACheckJNIException(env);
4401 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4402 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, length,
4403 false, "writeChar failure");
4406 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4412 OIC_LOG(DEBUG, TAG, "send success");
4413 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
4416 g_deviceStateListMutex);
4417 if (CA_STATUS_OK != res)
4419 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4422 oc_mutex_lock(g_threadWriteCharacteristicMutex);
4423 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4424 g_isSignalSetFlag = true;
4425 oc_cond_signal(g_threadWriteCharacteristicCond);
4426 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
4428 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0,
4429 (*env)->GetArrayLength(env, data),
4430 true, "writeChar success");
4433 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4439 CALEClientSendFinish(env, gatt);
4444 * Class: org_iotivity_ca_jar_caleinterface
4445 * Method: CALeGattCharacteristicChangedCallback
4446 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4448 JNIEXPORT void JNICALL
4449 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4450 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4452 OIC_LOG(INFO, TAG, "CALeGattCharacteristicChangedCallback");
4453 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4454 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4455 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4456 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4458 // get Byte Array and convert to uint8_t*
4459 jint length = (*env)->GetArrayLength(env, data);
4462 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4463 CACheckJNIException(env);
4465 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4466 jni_byte_responseData);
4468 uint8_t* receivedData = OICMalloc(length);
4471 OIC_LOG(ERROR, TAG, "receivedData is null");
4475 memcpy(receivedData, jni_byte_responseData, length);
4476 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4478 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4481 OIC_LOG(ERROR, TAG, "jni_address is null");
4482 OICFree(receivedData);
4486 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4489 OIC_LOG(ERROR, TAG, "address is null");
4490 CACheckJNIException(env);
4491 OICFree(receivedData);
4495 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4496 receivedData, length);
4498 uint32_t sentLength = 0;
4499 oc_mutex_lock(g_bleServerBDAddressMutex);
4500 g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
4501 oc_mutex_unlock(g_bleServerBDAddressMutex);
4503 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4507 * Class: org_iotivity_ca_jar_caleinterface
4508 * Method: CALeGattDescriptorWriteCallback
4509 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4511 JNIEXPORT void JNICALL
4512 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4516 OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status);
4517 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4518 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4519 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4521 if (GATT_SUCCESS != status) // error
4526 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4532 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4535 CACheckJNIException(env);
4539 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4540 STATE_SERVICE_CONNECTED,
4542 g_deviceStateListMutex);
4543 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4544 if (CA_STATUS_OK != res)
4546 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4550 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
4551 if (CA_STATUS_OK != res)
4553 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
4561 CALEClientSendFinish(env, gatt);
4565 JNIEXPORT void JNICALL
4566 Java_org_iotivity_ca_CaLeClientInterface_caLeGattMtuChangedCallback(JNIEnv *env,
4572 OIC_LOG_V(INFO, TAG, "caLeGattMtuChangedCallback - mtu[%d-including Header size 3 byte)", mtu);
4573 OIC_LOG_V(INFO, TAG, "caLeGattMtuChangedCallback - status %d", status);
4581 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4582 if (CA_STATUS_OK != res)
4584 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4589 OIC_LOG(INFO, TAG, "mtu nego is done");
4590 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4593 CALEClientSendFinish(env, gatt);
4597 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4600 CACheckJNIException(env);
4601 (*env)->DeleteLocalRef(env, jni_address);
4602 CALEClientSendFinish(env, gatt);
4607 CAResult_t res = CALESetMtuSize(address, mtu - CA_BLE_MTU_HEADER_SIZE,
4608 g_deviceStateList, g_deviceStateListMutex);
4609 if (CA_STATUS_OK != res)
4611 OIC_LOG(ERROR, TAG, "CALESetMtuSize has failed");
4614 res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
4615 STATE_SEND_MTU_NEGO_SUCCESS,
4617 g_deviceStateListMutex);
4618 if (CA_STATUS_OK != res)
4620 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4622 CALEClientUpdateSendCnt(env);
4623 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4624 (*env)->DeleteLocalRef(env, jni_address);