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")
42 #define TAG BLE_CLIENT_TAG
44 #define MICROSECS_PER_SEC 1000000
45 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
46 #define WAIT_TIME_SCAN_INTERVAL_DEFAULT 10
47 #define WAIT_TIME_SCANNED_CHECKING 30
49 #define GATT_CONNECTION_PRIORITY_BALANCED 0
50 #define GATT_FAILURE 257
51 #define GATT_INSUFFICIENT_AUTHENTICATION 5
52 #define GATT_INSUFFICIENT_ENCRYPTION 15
53 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
54 #define GATT_INVALID_OFFSET 7
55 #define GATT_READ_NOT_PERMITTED 2
56 #define GATT_REQUEST_NOT_SUPPORTED 6
57 #define GATT_WRITE_NOT_PERMITTED 3
60 #define BLE_SCAN_API_LEVEL (100) //(21)
61 #define BLE_MIN_API_LEVEL (18)
64 static ca_thread_pool_t g_threadPoolHandle = NULL;
67 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
68 static u_arraylist_t *g_gattObjectList = NULL;
69 static u_arraylist_t *g_deviceStateList = NULL;
71 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
72 static CABLEErrorHandleCallback g_clientErrorCallback;
73 static jobject g_leScanCallback = NULL;
74 static jobject g_leGattCallback = NULL;
75 static jobject g_context = NULL;
76 static jobjectArray g_uuidList = NULL;
78 // it will be prevent to start send logic when adapter has stopped.
79 static bool g_isStartedLEClient = false;
81 static jbyteArray g_sendBuffer = NULL;
82 static uint32_t g_targetCnt = 0;
83 static uint32_t g_currentSentCnt = 0;
84 static bool g_isFinishedSendData = false;
85 static oc_mutex g_SendFinishMutex = NULL;
86 static oc_mutex g_threadMutex = NULL;
87 static oc_cond g_threadCond = NULL;
88 static oc_cond g_deviceDescCond = NULL;
90 static oc_mutex g_threadSendMutex = NULL;
91 static oc_mutex g_threadWriteCharacteristicMutex = NULL;
92 static oc_cond g_threadWriteCharacteristicCond = NULL;
93 static bool g_isSignalSetFlag = false;
95 static oc_mutex g_bleReqRespClientCbMutex = NULL;
96 static oc_mutex g_bleServerBDAddressMutex = NULL;
98 static oc_mutex g_deviceListMutex = NULL;
99 static oc_mutex g_gattObjectMutex = NULL;
100 static oc_mutex g_deviceStateListMutex = NULL;
102 static oc_mutex g_deviceScanRetryDelayMutex = NULL;
103 static oc_cond g_deviceScanRetryDelayCond = NULL;
105 static oc_mutex g_threadScanIntervalMutex = NULL;
106 static oc_cond g_threadScanIntervalCond = NULL;
108 static oc_mutex g_threadSendStateMutex = NULL;
109 static oc_mutex g_setValueMutex = NULL;
111 static int32_t g_scanIntervalTime = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
112 static int32_t g_scanIntervalTimePrev = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
113 static int32_t g_intervalCount = 0;
114 static bool g_isWorkingScanThread = false;
115 static CALEScanState_t g_curScanningStep = BLE_SCAN_NONE;
116 static CALEScanState_t g_nextScanningStep = BLE_SCAN_ENABLE;
118 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
119 static int32_t g_jniIntSdk = -1;
121 static bool g_setHighQoS = true;
122 static bool g_setFullScanFlag = true;
123 jclass g_LEInterface = NULL;
125 * check if retry logic for connection routine has to be stopped or not.
126 * in case of error value including this method, connection routine has to be stopped.
127 * since there is no retry logic for this error reason in this client.
128 * @param state constant value of bluetoothgatt.
129 * @return true - waiting for background connection in BT platform.
130 * false - connection routine has to be stopped.
132 static bool CALECheckConnectionStateValue(jint state)
136 case GATT_CONNECTION_PRIORITY_BALANCED:
138 case GATT_INSUFFICIENT_AUTHENTICATION:
139 case GATT_INSUFFICIENT_ENCRYPTION:
140 case GATT_INVALID_ATTRIBUTE_LENGTH:
141 case GATT_INVALID_OFFSET:
142 case GATT_READ_NOT_PERMITTED:
143 case GATT_REQUEST_NOT_SUPPORTED:
144 case GATT_WRITE_NOT_PERMITTED:
152 * delete global reference for g_sendBuffer
153 * @param[in] env JNI interface pointer.
155 static void CALEDeleteSendBuffer(JNIEnv *env)
157 OIC_LOG(INFO, TAG, "CALEDeleteSendBuffer");
158 oc_mutex_lock(g_setValueMutex);
161 OIC_LOG(INFO, TAG, "delete send buffer");
162 (*env)->DeleteGlobalRef(env, g_sendBuffer);
165 oc_mutex_unlock(g_setValueMutex);
168 void CALEClientSetScanInterval(int32_t intervalTime, int32_t workingCount,
169 CALEScanState_t nextScanningStep)
171 OIC_LOG_V(DEBUG, TAG, "CALEClientSetScanInterval : %d -> %d, next scan state will be %d",
172 g_scanIntervalTime, intervalTime, nextScanningStep);
174 // previous time should be stored.
175 if (0 < workingCount)
177 g_scanIntervalTimePrev = g_scanIntervalTime;
179 g_scanIntervalTime = intervalTime;
180 g_intervalCount = workingCount;
181 g_nextScanningStep = nextScanningStep;
184 void CALERestartScanWithInterval(int32_t intervalTime, int32_t workingCount,
185 CALEScanState_t nextScanningStep)
187 if (intervalTime == g_scanIntervalTime
188 && workingCount == g_intervalCount
189 && nextScanningStep == g_nextScanningStep)
191 OIC_LOG(DEBUG, TAG, "setting duplicate interval time");
195 oc_mutex_lock(g_threadScanIntervalMutex);
196 CALEClientSetScanInterval(intervalTime, workingCount, nextScanningStep);
197 oc_cond_signal(g_threadScanIntervalCond);
198 oc_mutex_unlock(g_threadScanIntervalMutex);
201 static void CALEScanThread(void* object)
205 bool isAttached = false;
207 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
210 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
214 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
220 oc_mutex_lock(g_threadScanIntervalMutex);
221 while(g_isWorkingScanThread)
223 OIC_LOG(DEBUG, TAG, "scan waiting time out");
224 if (BLE_SCAN_ENABLE == g_curScanningStep)
227 CAResult_t ret = CALEClientStopScan();
228 if (CA_STATUS_OK != ret)
230 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
233 else if (BLE_SCAN_DISABLE == g_curScanningStep)
236 CAResult_t ret = CALEClientStartScan();
237 if (CA_STATUS_OK != ret)
239 OIC_LOG(INFO, TAG, "CALEClientStartScan has failed");
244 OIC_LOG(DEBUG, TAG, "scan thread is started");
246 CALEClientSetScanInterval(0, 0, BLE_SCAN_DISABLE);
249 OIC_LOG_V(DEBUG, TAG, "wait for Scan Interval Time during %d sec", g_scanIntervalTime);
250 if (OC_WAIT_SUCCESS == oc_cond_wait_for(g_threadScanIntervalCond,
251 g_threadScanIntervalMutex,
252 g_scanIntervalTime * MICROSECS_PER_SEC))
254 // called signal scan thread will be terminated
255 OIC_LOG(DEBUG, TAG, "signal scanInterval waiting");
256 if (BLE_SCAN_DISABLE == g_nextScanningStep)
258 g_curScanningStep = BLE_SCAN_ENABLE;
262 g_curScanningStep = BLE_SCAN_DISABLE;
267 if (BLE_SCAN_ENABLE == g_curScanningStep)
269 if (g_intervalCount > 0)
271 if (g_intervalCount == 1)
273 OIC_LOG(DEBUG, TAG, "reset default time");
274 CALEClientSetScanInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
277 OIC_LOG_V(DEBUG, TAG, "interval count : %d", g_intervalCount);
279 g_curScanningStep = BLE_SCAN_DISABLE;
283 g_curScanningStep = BLE_SCAN_ENABLE;
287 oc_mutex_unlock(g_threadScanIntervalMutex);
291 (*g_jvm)->DetachCurrentThread(g_jvm);
295 CAResult_t CALEClientStartScanWithInterval()
297 if (g_isWorkingScanThread)
299 OIC_LOG(DEBUG, TAG, "scan interval logic already running");
303 // initialize scan flags
304 g_curScanningStep = BLE_SCAN_NONE;
305 g_isWorkingScanThread = true;
307 g_scanIntervalTime = g_scanIntervalTimePrev;
308 g_nextScanningStep = BLE_SCAN_ENABLE;
310 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEScanThread, NULL, NULL))
312 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
313 g_isWorkingScanThread = false;
314 return CA_STATUS_FAILED;
320 void CALEClientStopScanWithInterval()
322 g_isWorkingScanThread = false;
323 oc_cond_signal(g_threadScanIntervalCond);
327 void CALEClientJniInit()
329 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
330 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
333 void CALEClientJNISetContext()
335 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
336 g_context = (jobject) CANativeJNIGetContext();
339 CAResult_t CALECreateJniInterfaceObject()
341 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
345 OIC_LOG(ERROR, TAG, "g_context is null");
346 return CA_STATUS_FAILED;
351 OIC_LOG(ERROR, TAG, "g_jvm is null");
352 return CA_STATUS_FAILED;
355 bool isAttached = false;
357 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
360 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
364 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
365 return CA_STATUS_FAILED;
370 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
371 "getApplicationContext",
372 "()Landroid/content/Context;");
374 if (!mid_getApplicationContext)
376 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
377 return CA_STATUS_FAILED;
380 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
381 mid_getApplicationContext);
382 if (!jApplicationContext)
384 OIC_LOG(ERROR, TAG, "Could not get application context");
388 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
389 if (!jni_LEInterface)
391 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
394 g_LEInterface = (jclass)((*env)->NewGlobalRef(env, jni_LEInterface));
396 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
397 "(Landroid/content/Context;)V");
398 if (!LeInterfaceConstructorMethod)
400 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
404 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
405 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
409 (*g_jvm)->DetachCurrentThread(g_jvm);
415 CACheckJNIException(env);
418 (*g_jvm)->DetachCurrentThread(g_jvm);
421 return CA_STATUS_FAILED;
424 CAResult_t CALEClientInitialize()
426 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
432 OIC_LOG(ERROR, TAG, "g_jvm is null");
433 return CA_STATUS_FAILED;
436 bool isAttached = false;
438 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
441 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
445 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
446 return CA_STATUS_FAILED;
451 g_jniIntSdk = CALEGetBuildVersion(env);
452 if (g_jniIntSdk < BLE_MIN_API_LEVEL)
454 OIC_LOG(ERROR, TAG, "it is not supported");
458 (*g_jvm)->DetachCurrentThread(g_jvm);
460 return CA_STATUS_FAILED;
463 CAResult_t ret = CALEClientInitGattMutexVaraibles();
464 if (CA_STATUS_OK != ret)
466 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
467 CALEClientTerminateGattMutexVariables();
471 (*g_jvm)->DetachCurrentThread(g_jvm);
477 g_deviceDescCond = oc_cond_new();
479 // init mutex for send logic
480 g_threadCond = oc_cond_new();
481 g_threadWriteCharacteristicCond = oc_cond_new();
482 g_deviceScanRetryDelayCond = oc_cond_new();
483 g_threadScanIntervalCond = oc_cond_new();
485 CALEClientCreateDeviceList();
486 CALEClientJNISetContext();
488 ret = CALEClientCreateUUIDList();
489 if (CA_STATUS_OK != ret)
491 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
495 (*g_jvm)->DetachCurrentThread(g_jvm);
501 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
502 if (CA_STATUS_OK != ret)
504 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
508 (*g_jvm)->DetachCurrentThread(g_jvm);
513 g_isStartedLEClient = true;
517 (*g_jvm)->DetachCurrentThread(g_jvm);
523 void CALEClientTerminate()
525 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
529 OIC_LOG(ERROR, TAG, "g_jvm is null");
533 bool isAttached = false;
535 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
538 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
542 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
549 CAResult_t ret = CALEClientStopScan();
550 if (CA_STATUS_OK != ret)
552 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
555 if (g_leScanCallback)
557 (*env)->DeleteGlobalRef(env, g_leScanCallback);
558 g_leScanCallback = NULL;
561 if (g_leGattCallback)
563 (*env)->DeleteGlobalRef(env, g_leGattCallback);
564 g_leGattCallback = NULL;
569 (*env)->DeleteGlobalRef(env, g_LEInterface);
570 g_LEInterface = NULL;
573 CALEDeleteSendBuffer(env);
577 (*env)->DeleteGlobalRef(env, g_uuidList);
581 ret = CALERemoveAllDeviceState(g_deviceStateList,
582 g_deviceStateListMutex);
583 if (CA_STATUS_OK != ret)
585 OIC_LOG(ERROR, TAG, "CALERemoveAllDeviceState has failed");
588 oc_mutex_lock(g_deviceStateListMutex);
589 OICFree(g_deviceStateList);
590 g_deviceStateList = NULL;
591 oc_mutex_unlock(g_deviceStateListMutex);
593 ret = CALEClientRemoveAllScanDevices(env);
594 if (CA_STATUS_OK != ret)
596 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
599 ret = CALEClientRemoveAllGattObjs(env);
600 if (CA_STATUS_OK != ret)
602 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
605 CALEClientSetSendFinishFlag(true);
607 CALEClientTerminateGattMutexVariables();
608 CALEClientDestroyJniInterface();
610 oc_cond_free(g_deviceDescCond);
611 oc_cond_free(g_threadCond);
612 oc_cond_free(g_threadWriteCharacteristicCond);
613 oc_cond_free(g_deviceScanRetryDelayCond);
614 oc_cond_free(g_threadScanIntervalCond);
616 g_deviceDescCond = NULL;
618 g_threadWriteCharacteristicCond = NULL;
619 g_deviceScanRetryDelayCond = NULL;
620 g_threadScanIntervalCond = NULL;
622 g_isSignalSetFlag = false;
625 CALEClientStopScanWithInterval();
629 (*g_jvm)->DetachCurrentThread(g_jvm);
633 jobject CALEClientHiddenConnectGatt(jobject btDevice, const char* address, jboolean autoconnect)
635 OIC_LOG(INFO, TAG, "IN - CALEClientHiddenConnectGatt");
639 OIC_LOG(ERROR, TAG, "g_jvm is null");
643 bool isAttached = false;
645 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
648 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
652 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
658 jstring jni_address = (*env)->NewStringUTF(env, address);
659 jmethodID jni_connectGattHiddenMethod = (*env)->GetStaticMethodID(env, g_LEInterface,
660 "connectGattforHidden",
661 "(Landroid/bluetooth/BluetoothDevice;"
662 "Ljava/lang/String;Z)"
663 "Landroid/bluetooth/BluetoothGatt;");
664 if (!jni_connectGattHiddenMethod)
666 OIC_LOG(ERROR, TAG, "Could not get jni_connectGatt Hidden Method");
670 jobject gatt = (*env)->CallStaticObjectMethod(env, g_LEInterface,
671 jni_connectGattHiddenMethod,
672 btDevice, jni_address, autoconnect);
674 if (CACheckJNIException(env))
676 OIC_LOG(ERROR, TAG, "connectGattforHidden has failed");
680 OIC_LOG(INFO, TAG, "OUT - CALEClientHiddenConnectGatt");
684 (*g_jvm)->DetachCurrentThread(g_jvm);
690 CACheckJNIException(env);
695 (*g_jvm)->DetachCurrentThread(g_jvm);
701 CAResult_t CALEClientDestroyJniInterface()
703 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
707 OIC_LOG(ERROR, TAG, "g_jvm is null");
708 return CA_STATUS_FAILED;
711 bool isAttached = false;
713 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
716 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
720 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
721 return CA_STATUS_FAILED;
726 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
727 if (!jni_LeInterface)
729 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
733 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
734 "destroyLeInterface",
736 if (!jni_InterfaceDestroyMethod)
738 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
742 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
744 if (CACheckJNIException(env))
746 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
750 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
754 (*g_jvm)->DetachCurrentThread(g_jvm);
760 CACheckJNIException(env);
765 (*g_jvm)->DetachCurrentThread(g_jvm);
768 return CA_STATUS_FAILED;
771 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
773 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
774 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
778 CAResult_t res = CALEClientDisconnect(env, gatt);
779 if (CA_STATUS_OK != res)
781 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
784 CALEClientUpdateSendCnt(env);
787 CAResult_t CALEClientSendNegotiationMessage(const char* address)
789 VERIFY_NON_NULL(address, TAG, "address is null");
791 return CALEClientSendUnicastMessageImpl(address, NULL, 0);
794 CAResult_t CALEClientSendUnicastMessage(const char* address,
796 const uint32_t dataLen)
798 VERIFY_NON_NULL(address, TAG, "address is null");
799 VERIFY_NON_NULL(data, TAG, "data is null");
801 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
804 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
805 const uint32_t dataLen)
807 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
808 VERIFY_NON_NULL(data, TAG, "data is null");
812 OIC_LOG(ERROR, TAG, "g_jvm is null");
813 return CA_STATUS_FAILED;
816 bool isAttached = false;
818 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
821 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
825 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
826 return CA_STATUS_FAILED;
831 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
832 if (CA_STATUS_OK != ret)
834 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
839 (*g_jvm)->DetachCurrentThread(g_jvm);
845 CAResult_t CALEClientStartUnicastServer(const char* address)
850 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
852 return CA_NOT_SUPPORTED;
855 CAResult_t CALEClientStartMulticastServer()
857 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
859 return CA_NOT_SUPPORTED;
862 void CALEClientStopUnicastServer()
864 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
867 void CALEClientStopMulticastServer()
869 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
872 void CALEClientSetCallback(CAPacketReceiveCallback callback)
874 g_packetReceiveCallback = callback;
877 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
879 g_clientErrorCallback = callback;
882 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
884 VERIFY_NON_NULL(env, TAG, "env");
888 OIC_LOG(ERROR, TAG, "g_deviceList is not available");
889 return CA_STATUS_FAILED;
892 if (0 == u_arraylist_length(g_deviceList) // multicast
893 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
895 // Wait for LE peripherals to be discovered.
897 // Number of times to wait for discovery to complete.
898 static size_t const RETRIES = 5;
900 static uint64_t const TIMEOUT =
901 2 * MICROSECS_PER_SEC; // Microseconds
903 // set scan interval and start scan
904 CALERestartScanWithInterval(WAIT_TIME_SCANNED_CHECKING, 1, BLE_SCAN_ENABLE);
906 bool devicesDiscovered = false;
907 for (size_t i = 0; i < RETRIES; ++i)
909 OIC_LOG(DEBUG, TAG, "waiting for target device");
910 if (oc_cond_wait_for(g_deviceDescCond,
912 TIMEOUT) == OC_WAIT_SUCCESS)
914 OIC_LOG(DEBUG, TAG, "time out");
915 oc_mutex_lock(g_deviceListMutex);
916 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
917 oc_mutex_unlock(g_deviceListMutex);
919 if (0 < scannedDeviceLen)
921 if (!address // multicast
922 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
924 devicesDiscovered = true;
931 OIC_LOG(INFO, TAG, "waiting..");
933 oc_mutex_lock(g_deviceScanRetryDelayMutex);
934 if (oc_cond_wait_for(g_deviceScanRetryDelayCond,
935 g_deviceScanRetryDelayMutex,
936 MICROSECS_PER_SEC) == OC_WAIT_SUCCESS)
938 OIC_LOG(INFO, TAG, "finish to waiting for target device");
939 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
942 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
945 // checking whether a target device is found while waiting for time-out.
946 if (CALEClientIsDeviceInScanDeviceList(env, address))
948 devicesDiscovered = true;
957 // reset scan interval time after checking scanned devices
958 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
960 // time out for scanning devices
961 if (!devicesDiscovered)
963 return CA_STATUS_FAILED;
968 OIC_LOG(DEBUG, TAG, "there is a target device in the scanned devices");
975 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
976 const uint32_t dataLen)
978 OIC_LOG(INFO, TAG, "CALEClientSendUnicastMessageImpl in");
979 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
981 VERIFY_NON_NULL(address, TAG, "address is null");
985 OIC_LOG(ERROR, TAG, "g_jvm is null");
986 return CA_STATUS_FAILED;
989 bool isAttached = false;
991 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
994 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
997 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
998 return CA_STATUS_FAILED;
1003 oc_mutex_lock(g_threadSendMutex);
1005 CALEClientSetSendFinishFlag(false);
1007 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
1008 if (CA_STATUS_OK != ret)
1010 OIC_LOG(INFO, TAG, "there is no scanned device");
1014 if (g_context && g_deviceList)
1016 uint32_t length = u_arraylist_length(g_deviceList);
1017 for (uint32_t index = 0; index < length; index++)
1019 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1022 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1026 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1027 if (!jni_setAddress)
1029 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1033 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1036 OIC_LOG(ERROR, TAG, "setAddress is null");
1037 CACheckJNIException(env);
1041 if (!strcasecmp(setAddress, address))
1043 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1044 (*env)->DeleteLocalRef(env, jni_setAddress);
1046 CALEDeleteSendBuffer(env);
1048 if (data && dataLen > 0)
1050 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1051 CACheckJNIException(env);
1052 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1053 CACheckJNIException(env);
1054 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1055 CACheckJNIException(env);
1058 // Target device to send message is just one.
1061 ret = CALEClientSendData(env, jarrayObj);
1062 if (CA_STATUS_OK != ret)
1064 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
1068 OIC_LOG(INFO, TAG, "wake up");
1071 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1072 (*env)->DeleteLocalRef(env, jni_setAddress);
1076 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
1078 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1079 // if there is no connection state.
1080 oc_mutex_lock(g_threadMutex);
1081 if (!g_isFinishedSendData)
1083 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1084 oc_cond_wait(g_threadCond, g_threadMutex);
1085 OIC_LOG(DEBUG, TAG, "connection / send is finished for unicast");
1087 oc_mutex_unlock(g_threadMutex);
1091 (*g_jvm)->DetachCurrentThread(g_jvm);
1094 oc_mutex_unlock(g_threadSendMutex);
1095 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
1096 if (CALEIsValidState(address, CA_LE_SEND_STATE,
1099 g_deviceStateListMutex))
1101 OIC_LOG(INFO, TAG, "send success");
1104 else if (CALEIsValidState(address, CA_LE_SEND_STATE,
1105 STATE_SEND_MTU_NEGO_SUCCESS,
1107 g_deviceStateListMutex))
1109 OIC_LOG(INFO, TAG, "mtu nego success");
1114 OIC_LOG(ERROR, TAG, "send failure");
1115 ret = CA_SEND_FAILED;
1119 CAResult_t resetRet = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
1122 g_deviceStateListMutex);
1123 if (CA_STATUS_OK != resetRet)
1125 OIC_LOG_V(ERROR, TAG, "CALEUpdateDeviceState has failed (%d)", resetRet);
1126 ret = CA_SEND_FAILED;
1135 (*g_jvm)->DetachCurrentThread(g_jvm);
1138 oc_mutex_unlock(g_threadSendMutex);
1139 return CA_SEND_FAILED;
1142 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
1143 const uint32_t dataLen)
1145 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
1146 VERIFY_NON_NULL(data, TAG, "data is null");
1147 VERIFY_NON_NULL(env, TAG, "env is null");
1151 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1152 return CA_STATUS_FAILED;
1155 oc_mutex_lock(g_threadSendMutex);
1157 CALEClientSetSendFinishFlag(false);
1159 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1160 CALEDeleteSendBuffer(env);
1162 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
1163 if (CA_STATUS_OK != res)
1165 OIC_LOG(INFO, TAG, "there is no scanned device");
1169 uint32_t length = u_arraylist_length(g_deviceList);
1170 g_targetCnt = length;
1172 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1173 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1174 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1176 for (uint32_t index = 0; index < length; index++)
1178 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1181 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
1185 res = CALEClientSendData(env, jarrayObj);
1186 if (res != CA_STATUS_OK)
1188 OIC_LOG(ERROR, TAG, "BT device - send has failed");
1192 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1194 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1195 oc_mutex_lock(g_threadMutex);
1196 if (!g_isFinishedSendData)
1198 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1199 oc_cond_wait(g_threadCond, g_threadMutex);
1200 OIC_LOG(DEBUG, TAG, "connection / send is finished for multicast");
1202 oc_mutex_unlock(g_threadMutex);
1203 oc_mutex_unlock(g_threadSendMutex);
1204 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1205 return CA_STATUS_OK;
1208 oc_mutex_unlock(g_threadSendMutex);
1209 OIC_LOG(ERROR, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1210 return CA_SEND_FAILED;
1213 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1215 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1216 VERIFY_NON_NULL(device, TAG, "device is null");
1217 VERIFY_NON_NULL(env, TAG, "env is null");
1219 // get BLE address from bluetooth device object.
1220 char* address = NULL;
1221 CALEState_t* state = NULL;
1222 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1225 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1226 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1229 OIC_LOG(ERROR, TAG, "address is not available");
1230 CACheckJNIException(env);
1231 return CA_STATUS_FAILED;
1233 oc_mutex_lock(g_deviceStateListMutex);
1234 state = CALEGetStateInfo(address, g_deviceStateList);
1235 oc_mutex_unlock(g_deviceStateListMutex);
1238 // Since disconnect event can be caused from BT stack while connection step is running.
1239 // DeviceState has to have current status for processing send failure.
1240 OIC_LOG(INFO, TAG, "set STATE_SEND_PREPARING");
1241 CAResult_t res = CALEClientUpdateDeviceStateWithBtDevice(env, device,
1243 STATE_SEND_PREPARING);
1244 if (CA_STATUS_OK != res)
1246 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceStateWithBtDevice has failed");
1249 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1251 return CA_STATUS_FAILED;
1256 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1258 // cancel previous connection request before connection
1259 // if there is gatt object in g_gattObjectList.
1262 jobject gatt = CALEClientGetGattObjInList(env, address);
1265 CAResult_t res = CALEClientDisconnect(env, gatt);
1266 if (CA_STATUS_OK != res)
1268 OIC_LOG(INFO, TAG, "there is no gatt object");
1271 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1274 // connection request
1275 jobject newGatt = CALEClientConnect(env, device,
1277 if (NULL == newGatt)
1279 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1280 return CA_STATUS_FAILED;
1285 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1286 STATE_SERVICE_CONNECTED,
1288 g_deviceStateListMutex))
1290 OIC_LOG(INFO, TAG, "GATT has already connected");
1292 jobject gatt = CALEClientGetGattObjInList(env, address);
1295 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1296 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1297 return CA_STATUS_FAILED;
1300 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1301 if (CA_STATUS_OK != ret)
1303 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1304 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1307 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1309 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1312 g_deviceStateListMutex))
1314 OIC_LOG(INFO, TAG, "service connecting...");
1316 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1319 g_deviceStateListMutex))
1321 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1323 // cancel previous connection request before connection
1324 // if there is gatt object in g_gattObjectList.
1327 jobject gatt = CALEClientGetGattObjInList(env, address);
1330 CAResult_t res = CALEClientDisconnect(env, gatt);
1331 if (CA_STATUS_OK != res)
1333 OIC_LOG(INFO, TAG, "there is no gatt object");
1336 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1339 OIC_LOG(DEBUG, TAG, "start to connect LE");
1340 jobject gatt = CALEClientConnect(env, device,
1341 CALEGetFlagFromState(env, jni_address,
1342 CA_LE_AUTO_CONNECT_FLAG,
1344 g_deviceStateListMutex));
1348 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1349 return CA_STATUS_FAILED;
1354 return CA_STATUS_OK;
1357 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1359 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1360 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1362 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1363 "()Landroid/bluetooth/BluetoothDevice;");
1364 if (!jni_mid_getDevice)
1366 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1370 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1371 if (!jni_obj_device)
1373 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1374 CACheckJNIException(env);
1378 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1381 OIC_LOG(ERROR, TAG, "jni_address is null");
1382 CACheckJNIException(env);
1392 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1395 OIC_LOG(DEBUG, TAG, "Gatt Close");
1396 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1397 VERIFY_NON_NULL(env, TAG, "env is null");
1399 // get BluetoothGatt method
1400 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1401 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1402 if (!jni_mid_closeGatt)
1404 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1405 return CA_STATUS_OK;
1408 // call disconnect gatt method
1409 OIC_LOG(DEBUG, TAG, "request to close GATT");
1410 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1412 if (CACheckJNIException(env))
1414 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1415 return CA_STATUS_FAILED;
1418 return CA_STATUS_OK;
1421 CAResult_t CALEClientStartScan()
1423 if (!g_isStartedLEClient)
1425 OIC_LOG(ERROR, TAG, "LE client is not started");
1426 return CA_STATUS_FAILED;
1431 OIC_LOG(ERROR, TAG, "g_jvm is null");
1432 return CA_STATUS_FAILED;
1435 bool isAttached = false;
1437 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1440 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1443 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1444 return CA_STATUS_FAILED;
1449 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1451 CAResult_t ret = CA_STATUS_OK;
1452 // scan gatt server with UUID
1453 if (g_leScanCallback && g_uuidList)
1455 if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
1457 if (!g_setFullScanFlag)
1459 //new uuid scan with callback
1460 ret = CALEClientStartScanWithUUIDImplForV21(env, g_uuidList, g_leScanCallback);
1464 //new full scan with callback
1465 ret = CALEClientStartScanImplForV21(env, g_leScanCallback);
1470 if (!g_setFullScanFlag)
1472 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1476 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1480 if (CA_STATUS_OK != ret)
1482 if (CA_ADAPTER_NOT_ENABLED == ret)
1484 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1488 OIC_LOG(ERROR, TAG, "start scan has failed");
1495 (*g_jvm)->DetachCurrentThread(g_jvm);
1501 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1503 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl IN");
1504 VERIFY_NON_NULL(callback, TAG, "callback is null");
1505 VERIFY_NON_NULL(env, TAG, "env is null");
1507 if (!CALEIsEnableBTAdapter(env))
1509 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1510 return CA_ADAPTER_NOT_ENABLED;
1513 // get default bt adapter class
1514 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1515 if (!jni_cid_BTAdapter)
1517 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1518 CACheckJNIException(env);
1519 return CA_STATUS_FAILED;
1522 // get remote bt adapter method
1523 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1524 "getDefaultAdapter",
1525 METHODID_OBJECTNONPARAM);
1526 if (!jni_mid_getDefaultAdapter)
1528 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1529 CACheckJNIException(env);
1530 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1531 return CA_STATUS_FAILED;
1534 // get start le scan method
1535 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1536 "(Landroid/bluetooth/BluetoothAdapter$"
1537 "LeScanCallback;)Z");
1538 if (!jni_mid_startLeScan)
1540 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1541 CACheckJNIException(env);
1542 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1543 return CA_STATUS_FAILED;
1546 // gat bt adapter object
1547 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1548 jni_mid_getDefaultAdapter);
1549 if (!jni_obj_BTAdapter)
1551 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1552 CACheckJNIException(env);
1553 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1554 return CA_STATUS_FAILED;
1557 // call start le scan method
1558 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1559 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1560 jni_mid_startLeScan, callback);
1561 if (!jni_obj_startLeScan)
1563 OIC_LOG(INFO, TAG, "startLeScan has failed");
1564 CACheckJNIException(env);
1568 OIC_LOG(DEBUG, TAG, "LeScan has started");
1571 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1572 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1573 return CA_STATUS_OK;
1576 CAResult_t CALEClientStartScanImplForV21(JNIEnv *env, jobject callback)
1578 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 IN");
1579 VERIFY_NON_NULL(callback, TAG, "callback is null");
1580 VERIFY_NON_NULL(env, TAG, "env is null");
1582 if (!CALEIsEnableBTAdapter(env))
1584 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1585 return CA_ADAPTER_NOT_ENABLED;
1588 CAResult_t res = CA_STATUS_FAILED;
1589 // get default bt adapter class
1590 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1591 if (!jni_cid_BTAdapter)
1593 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1594 CACheckJNIException(env);
1595 return CA_STATUS_FAILED;
1598 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1599 "getDefaultAdapter",
1600 "()Landroid/bluetooth/"
1601 "BluetoothAdapter;");
1602 if (!jni_mid_getDefaultAdapter)
1604 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1605 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1606 return CA_STATUS_FAILED;
1609 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1610 jni_mid_getDefaultAdapter);
1611 if (!jni_obj_BTAdapter)
1613 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1614 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1615 return CA_STATUS_FAILED;
1618 // get bluetoothLeScanner class
1619 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
1620 if (!jni_cid_leScanner)
1622 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
1623 CACheckJNIException(env);
1624 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1625 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1626 return CA_STATUS_FAILED;
1629 // get remote bt adapter method
1630 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1631 "getBluetoothLeScanner",
1632 "()Landroid/bluetooth/"
1633 "le/BluetoothLeScanner;");
1634 if (!jni_mid_getBluetoothLeScanner)
1636 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
1637 CACheckJNIException(env);
1641 // get startScan(ScanCallback callback) method
1642 jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner, "startScan",
1643 "(Landroid/bluetooth/le/ScanCallback;)V");
1644 if (!jni_mid_startScan)
1646 OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
1647 CACheckJNIException(env);
1651 // gat le scanner object
1652 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
1653 jni_mid_getBluetoothLeScanner);
1654 if (!jni_obj_leScanner)
1656 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
1657 CACheckJNIException(env);
1661 // call startScan method
1662 OIC_LOG(INFO, TAG, "CALL API - startScan(for level21)");
1663 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, callback);
1664 if (CACheckJNIException(env))
1666 OIC_LOG(INFO, TAG, "startScan has failed");
1667 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
1671 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
1674 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1675 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1676 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1680 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1682 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl IN");
1683 VERIFY_NON_NULL(callback, TAG, "callback is null");
1684 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1685 VERIFY_NON_NULL(env, TAG, "env is null");
1687 if (!CALEIsEnableBTAdapter(env))
1689 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1690 return CA_ADAPTER_NOT_ENABLED;
1693 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1694 if (!jni_cid_BTAdapter)
1696 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1697 CACheckJNIException(env);
1698 return CA_STATUS_FAILED;
1701 // get remote bt adapter method
1702 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1703 "getDefaultAdapter",
1704 METHODID_OBJECTNONPARAM);
1705 if (!jni_mid_getDefaultAdapter)
1707 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1708 CACheckJNIException(env);
1709 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1710 return CA_STATUS_FAILED;
1713 // get start le scan method
1714 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1715 "([Ljava/util/UUID;Landroid/bluetooth/"
1716 "BluetoothAdapter$LeScanCallback;)Z");
1717 if (!jni_mid_startLeScan)
1719 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1720 CACheckJNIException(env);
1721 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1722 return CA_STATUS_FAILED;
1725 // get bt adapter object
1726 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1727 jni_mid_getDefaultAdapter);
1728 if (!jni_obj_BTAdapter)
1730 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1731 CACheckJNIException(env);
1732 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1733 return CA_STATUS_FAILED;
1736 // call start le scan method
1737 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1738 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1739 jni_mid_startLeScan, uuids, callback);
1740 if (!jni_obj_startLeScan)
1742 OIC_LOG(INFO, TAG, "startLeScan has failed");
1743 CACheckJNIException(env);
1747 OIC_LOG(DEBUG, TAG, "LeScan has started");
1750 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1751 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1752 return CA_STATUS_OK;
1755 CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids, jobject callback)
1757 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 IN");
1758 VERIFY_NON_NULL(callback, TAG, "callback is null");
1759 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1760 VERIFY_NON_NULL(env, TAG, "env is null");
1762 if (!CALEIsEnableBTAdapter(env))
1764 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1765 return CA_ADAPTER_NOT_ENABLED;
1768 // get bluetoothLeScanner class
1769 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
1770 if (!jni_cid_leScanner)
1772 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
1773 CACheckJNIException(env);
1774 return CA_STATUS_FAILED;
1777 // get startScan(with UUID) method
1778 jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner,
1781 "Landroid/bluetooth/le/ScanSettings;"
1782 "Landroid/bluetooth/le/ScanCallback;"
1784 if (!jni_mid_startScan)
1786 OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
1787 CACheckJNIException(env);
1788 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1789 return CA_STATUS_FAILED;
1791 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1793 // get scanfilter.Builder class id
1794 jclass jni_cid_scanfilterBuilder = (*env)->FindClass(env,
1795 "android/bluetooth/le/"
1796 "ScanFilter$Builder");
1797 if (!jni_cid_scanfilterBuilder)
1799 OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilder is null");
1800 CACheckJNIException(env);
1801 return CA_STATUS_FAILED;
1804 // get scanfilter.Builder(ctor) method id
1805 jmethodID jni_mid_scanfilterBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1807 if (!jni_mid_scanfilterBuilderCtor)
1809 OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilderCtor is null");
1810 CACheckJNIException(env);
1811 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1812 return CA_STATUS_FAILED;
1815 // call scanfilter.Builder()
1816 jobject jni_obj_scanfilterBuilder = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
1817 jni_mid_scanfilterBuilderCtor);
1818 if (!jni_obj_scanfilterBuilder)
1820 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilterBuilder is null");
1821 CACheckJNIException(env);
1822 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1823 return CA_STATUS_FAILED;
1826 // get scanfilter.Builder.setServiceUuid method id
1827 jmethodID jni_mid_setServiceUuid = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1829 "(Landroid/os/ParcelUuid;)Landroid/"
1830 "bluetooth/le/ScanFilter$Builder;");
1831 if (!jni_mid_setServiceUuid)
1833 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setServiceUuid is null");
1834 CACheckJNIException(env);
1835 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1836 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1837 return CA_STATUS_FAILED;
1840 // get scanfilter.Builder.build method id
1841 jmethodID jni_mid_build_scanfilterBuilder = (*env)->GetMethodID(env,
1842 jni_cid_scanfilterBuilder,
1844 "()Landroid/bluetooth/le/"
1846 if (!jni_mid_build_scanfilterBuilder)
1848 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_build_scanfilterBuilder is null");
1849 CACheckJNIException(env);
1850 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1851 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1852 return CA_STATUS_FAILED;
1854 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1856 // call ParcelUuid.fromSting(uuid)
1857 jobject jni_obj_parcelUuid = CALEGetParcelUuidFromString(env, OIC_GATT_SERVICE_UUID);
1858 if (!jni_obj_parcelUuid)
1860 OIC_LOG(ERROR, TAG, "scanSettings: jni_obj_parcelUuid is null");
1861 CACheckJNIException(env);
1862 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1863 return CA_STATUS_FAILED;
1866 // call setServiceUuid(uuid)
1867 jobject jni_obj_setServiceUuid = (*env)->CallObjectMethod(env,
1868 jni_obj_scanfilterBuilder,
1869 jni_mid_setServiceUuid,
1870 jni_obj_parcelUuid);
1871 if (!jni_obj_setServiceUuid)
1873 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setServiceUuid is null");
1874 CACheckJNIException(env);
1875 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1876 (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
1877 return CA_STATUS_FAILED;
1879 (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
1880 (*env)->DeleteLocalRef(env, jni_obj_setServiceUuid);
1883 jobject jni_obj_scanfilter = (*env)->CallObjectMethod(env,
1884 jni_obj_scanfilterBuilder,
1885 jni_mid_build_scanfilterBuilder);
1886 if (!jni_obj_scanfilter)
1888 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilter is null");
1889 CACheckJNIException(env);
1890 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1891 return CA_STATUS_FAILED;
1893 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1895 // get scanSettings.Builder class id
1896 jclass jni_cid_scanSettingsBuilder = (*env)->FindClass(env,
1897 "android/bluetooth/le/"
1898 "ScanSettings$Builder");
1899 if (!jni_cid_scanSettingsBuilder)
1901 OIC_LOG(ERROR, TAG, "scanSettings: jni_cid_scanSettingsBuilder is null");
1902 CACheckJNIException(env);
1903 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1904 return CA_STATUS_FAILED;
1907 // get scanSettings.Builder(ctor) method id
1908 jmethodID jni_mid_scanSettingsBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
1910 if (!jni_mid_scanSettingsBuilderCtor)
1912 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_scanSettingsBuilderCtor is null");
1913 CACheckJNIException(env);
1914 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1915 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
1916 return CA_STATUS_FAILED;
1919 // get scanSettings.Builder.setScanMode method id
1920 jmethodID jni_mid_setScanMode = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
1923 "bluetooth/le/ScanSettings$Builder;");
1924 if (!jni_mid_setScanMode)
1926 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_setScanMode is null");
1927 CACheckJNIException(env);
1928 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1929 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
1930 return CA_STATUS_FAILED;
1933 // get scanSettings.Builder.build method id
1934 jmethodID jni_mid_build_scanSettings = (*env)->GetMethodID(env,
1935 jni_cid_scanSettingsBuilder,
1937 "()Landroid/bluetooth/le/"
1939 if (!jni_mid_build_scanSettings)
1941 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_build_scanSettings is null");
1942 CACheckJNIException(env);
1943 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1944 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
1945 return CA_STATUS_FAILED;
1948 // call scanSettings.Builder()
1949 jobject jni_obj_scanSettingBuilder = (*env)->NewObject(env, jni_cid_scanSettingsBuilder,
1950 jni_mid_scanSettingsBuilderCtor);
1951 if (!jni_obj_scanSettingBuilder)
1953 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettingBuilder is null");
1954 CACheckJNIException(env);
1955 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1956 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
1957 return CA_STATUS_FAILED;
1959 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
1961 jclass jni_cid_arrayList = (*env)->FindClass(env, "java/util/ArrayList");
1962 if (!jni_cid_arrayList)
1964 OIC_LOG(ERROR, TAG, "ArrayList: jni_cid_arrayList is null");
1965 CACheckJNIException(env);
1966 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1967 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
1968 return CA_STATUS_FAILED;
1971 jmethodID jni_mid_arrayListCtor = (*env)->GetMethodID(env, jni_cid_arrayList, "<init>", "()V");
1972 if (!jni_mid_arrayListCtor)
1974 OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListCtor is null");
1975 CACheckJNIException(env);
1976 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1977 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
1978 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
1979 return CA_STATUS_FAILED;
1982 jmethodID jni_mid_arrayListAdd = (*env)->GetMethodID(env, jni_cid_arrayList,
1983 "add", "(Ljava/lang/Object;)Z");
1984 if (!jni_mid_arrayListAdd)
1986 OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListAdd is null");
1987 CACheckJNIException(env);
1988 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1989 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
1990 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
1991 return CA_STATUS_FAILED;
1994 jobject jni_obj_filterList = (*env)->NewObject(env, jni_cid_arrayList, jni_mid_arrayListCtor);
1995 if (!jni_obj_filterList)
1997 OIC_LOG(ERROR, TAG, "ArrayList: jni_obj_filterList is null");
1998 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1999 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2000 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2001 return CA_STATUS_FAILED;
2003 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2005 jboolean jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
2006 jni_mid_arrayListAdd,
2007 jni_obj_scanfilter);
2008 if (!jni_bool_arrayListIsAdded)
2010 OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
2011 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2012 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2013 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2014 return CA_STATUS_FAILED;
2016 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2018 // get ScanSettings.SCAN_MODE_BALANCED jint value
2019 jint jni_int_scanBalancedMode = CALEGetConstantsValue(env, CLASSPATH_LE_SCANSETTINGS,
2020 "SCAN_MODE_BALANCED");
2021 CACheckJNIException(env);
2023 // call setScanMode(SCAN_MODE_BALANCED)
2024 jobject jni_obj_setScanMode = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
2025 jni_mid_setScanMode,
2026 jni_int_scanBalancedMode);
2027 if (!jni_obj_setScanMode)
2029 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setScanMode is null");
2030 CACheckJNIException(env);
2031 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2032 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2033 return CA_STATUS_FAILED;
2037 jobject jni_obj_scanSettings = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
2038 jni_mid_build_scanSettings);
2039 if (!jni_obj_scanSettings)
2041 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettings is null");
2042 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2043 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2044 return CA_STATUS_FAILED;
2046 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2048 CAResult_t res = CA_STATUS_FAILED;
2049 // get default bt adapter class
2050 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2051 if (!jni_cid_BTAdapter)
2053 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2054 CACheckJNIException(env);
2058 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2059 "getDefaultAdapter",
2060 "()Landroid/bluetooth/"
2061 "BluetoothAdapter;");
2062 if (!jni_mid_getDefaultAdapter)
2064 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2065 CACheckJNIException(env);
2066 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2070 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2071 jni_mid_getDefaultAdapter);
2072 if (!jni_obj_BTAdapter)
2074 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2075 CACheckJNIException(env);
2076 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2080 // get remote bt adapter method
2081 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2082 "getBluetoothLeScanner",
2083 "()Landroid/bluetooth/"
2084 "le/BluetoothLeScanner;");
2085 if (!jni_mid_getBluetoothLeScanner)
2087 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
2088 CACheckJNIException(env);
2089 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2090 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2094 // get le scanner object
2095 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
2096 jni_mid_getBluetoothLeScanner);
2097 if (!jni_obj_leScanner)
2099 OIC_LOG(ERROR, TAG, "jni_obj_leScanner is null");
2100 CACheckJNIException(env);
2101 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2102 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2105 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2106 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2108 // call startScan method
2109 OIC_LOG(INFO, TAG, "CALL API - startScanWithUUID(for level 21)");
2110 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, jni_obj_filterList,
2111 jni_obj_scanSettings, callback);
2112 if (CACheckJNIException(env))
2114 OIC_LOG(INFO, TAG, "startScan has failed");
2120 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2123 (*env)->DeleteLocalRef(env, jni_obj_scanSettings);
2124 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2128 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
2130 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
2131 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2134 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2137 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
2141 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
2142 "(Ljava/lang/String;)"
2143 "Ljava/util/UUID;");
2144 if (!jni_mid_fromString)
2146 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
2150 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
2151 CACheckJNIException(env);
2152 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
2156 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2160 return jni_obj_uuid;
2163 CACheckJNIException(env);
2167 CAResult_t CALEClientStopScan()
2171 OIC_LOG(ERROR, TAG, "g_jvm is null");
2172 return CA_STATUS_FAILED;
2175 bool isAttached = false;
2177 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2180 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2183 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2184 return CA_STATUS_FAILED;
2189 CAResult_t ret = CA_STATUS_FAILED;
2191 if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
2193 ret = CALEClientStopScanImplForV21(env, g_leScanCallback);
2197 ret = CALEClientStopScanImpl(env, g_leScanCallback);
2200 if (CA_STATUS_OK != ret)
2202 if (CA_ADAPTER_NOT_ENABLED == ret)
2204 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
2208 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
2214 (*g_jvm)->DetachCurrentThread(g_jvm);
2220 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
2222 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl IN");
2223 VERIFY_NON_NULL(callback, TAG, "callback is null");
2224 VERIFY_NON_NULL(env, TAG, "env is null");
2226 if (!CALEIsEnableBTAdapter(env))
2228 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2229 return CA_ADAPTER_NOT_ENABLED;
2232 // get default bt adapter class
2233 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2234 if (!jni_cid_BTAdapter)
2236 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2237 CACheckJNIException(env);
2238 return CA_STATUS_FAILED;
2241 // get remote bt adapter method
2242 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2243 "getDefaultAdapter",
2244 METHODID_OBJECTNONPARAM);
2245 if (!jni_mid_getDefaultAdapter)
2247 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2248 CACheckJNIException(env);
2249 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2250 return CA_STATUS_FAILED;
2253 // get start le scan method
2254 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
2255 "(Landroid/bluetooth/"
2256 "BluetoothAdapter$LeScanCallback;)V");
2257 if (!jni_mid_stopLeScan)
2259 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
2260 CACheckJNIException(env);
2261 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2262 return CA_STATUS_FAILED;
2265 // get bt adapter object
2266 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2267 jni_mid_getDefaultAdapter);
2268 if (!jni_obj_BTAdapter)
2270 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2271 CACheckJNIException(env);
2272 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2273 return CA_STATUS_FAILED;
2276 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
2277 // call start le scan method
2278 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
2279 if (CACheckJNIException(env))
2281 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
2282 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2283 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2284 return CA_STATUS_FAILED;
2287 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2288 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2289 return CA_STATUS_OK;
2292 CAResult_t CALEClientStopScanImplForV21(JNIEnv *env, jobject callback)
2294 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImplForV21 IN");
2295 VERIFY_NON_NULL(callback, TAG, "callback is null");
2296 VERIFY_NON_NULL(env, TAG, "env is null");
2298 if (!CALEIsEnableBTAdapter(env))
2300 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2301 return CA_ADAPTER_NOT_ENABLED;
2304 // get default bt adapter class
2305 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2306 if (!jni_cid_BTAdapter)
2308 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2309 CACheckJNIException(env);
2310 return CA_STATUS_FAILED;
2313 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2314 "getDefaultAdapter",
2315 "()Landroid/bluetooth/"
2316 "BluetoothAdapter;");
2317 if (!jni_mid_getDefaultAdapter)
2319 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2320 CACheckJNIException(env);
2321 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2322 return CA_STATUS_FAILED;
2325 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2326 jni_mid_getDefaultAdapter);
2327 if (!jni_obj_BTAdapter)
2329 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2330 CACheckJNIException(env);
2331 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2332 return CA_STATUS_FAILED;
2335 // get bluetoothLeScanner class
2336 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
2337 if (!jni_cid_leScanner)
2339 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
2340 CACheckJNIException(env);
2341 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2342 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2343 return CA_STATUS_FAILED;
2346 // get remote bt adapter method
2347 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2348 "getBluetoothLeScanner",
2349 "()Landroid/bluetooth/"
2350 "le/BluetoothLeScanner;");
2351 if (!jni_mid_getBluetoothLeScanner)
2353 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
2354 CACheckJNIException(env);
2355 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2356 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2357 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2358 return CA_STATUS_FAILED;
2360 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2362 // get stopScan(ScanCallback callback) method
2363 jmethodID jni_mid_stopScan = (*env)->GetMethodID(env, jni_cid_leScanner, "stopScan",
2364 "(Landroid/bluetooth/le/ScanCallback;)V");
2365 if (!jni_mid_stopScan)
2367 OIC_LOG(ERROR, TAG, "stopScan: jni_mid_stopScan is null");
2368 CACheckJNIException(env);
2369 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2370 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2371 return CA_STATUS_FAILED;
2373 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2375 // gat le scanner object
2376 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
2377 jni_mid_getBluetoothLeScanner);
2378 if (!jni_obj_leScanner)
2380 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
2381 CACheckJNIException(env);
2382 return CA_STATUS_FAILED;
2385 // call stopScan method
2386 OIC_LOG(INFO, TAG, "CALL API - stopScan for level 21");
2387 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_stopScan, callback);
2388 if (CACheckJNIException(env))
2390 OIC_LOG(INFO, TAG, "stopScan for level 21 has failed");
2391 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2392 return CA_STATUS_FAILED;
2395 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2396 return CA_STATUS_OK;
2399 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2401 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
2402 VERIFY_NON_NULL(env, TAG, "env is null");
2403 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
2405 oc_mutex_lock(g_threadSendMutex);
2407 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
2410 OIC_LOG(ERROR, TAG, "jni_address is not available");
2411 oc_mutex_unlock(g_threadSendMutex);
2412 return CA_STATUS_FAILED;
2415 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2418 OIC_LOG(ERROR, TAG, "address is not available");
2419 CACheckJNIException(env);
2420 oc_mutex_unlock(g_threadSendMutex);
2421 return CA_STATUS_FAILED;
2424 CAResult_t res = CA_STATUS_OK;
2425 if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2428 g_deviceStateListMutex))
2430 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
2431 if (NULL == newGatt)
2433 OIC_LOG(INFO, TAG, "newGatt is not available");
2434 res = CA_STATUS_FAILED;
2437 oc_mutex_unlock(g_threadSendMutex);
2442 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2444 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
2445 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2446 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
2448 // reset scan interval time after checking scanned devices
2449 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
2451 // since there is no callback related stop success
2452 // and scanning should be stopped before connectGatt is called.
2453 // it should wait a few micro seconds.
2456 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
2457 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
2460 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2463 OIC_LOG(ERROR, TAG, "address is not available");
2467 // close the gatt service
2468 jobject gatt = CALEClientGetGattObjInList(env, address);
2471 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
2472 if (CA_STATUS_OK != res)
2474 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
2475 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2479 // clean previous gatt object after close profile service
2480 res = CALEClientRemoveGattObjForAddr(env, jni_address);
2481 if (CA_STATUS_OK != res)
2483 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
2484 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2488 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2491 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
2494 OIC_LOG(DEBUG, TAG, "re-connection will be started");
2498 // add new gatt object into g_gattObjectList
2499 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
2500 if (CA_STATUS_OK != res)
2502 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
2509 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2511 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
2512 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2513 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
2515 if (!g_leGattCallback)
2517 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
2521 if (!CALEIsEnableBTAdapter(env))
2523 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2527 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
2530 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
2534 jobject jni_obj_connectGatt = NULL;
2535 jint jni_int_sdk = CALEGetBuildVersion(env);
2536 OIC_LOG_V(INFO, TAG, "API level is %d", jni_int_sdk);
2537 if (jni_int_sdk >= 23) // upper than API level 23
2539 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
2541 "(Landroid/content/Context;ZLandroid/"
2542 "bluetooth/BluetoothGattCallback;I)"
2543 "Landroid/bluetooth/BluetoothGatt;");
2544 if (!jni_mid_connectGatt)
2546 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
2550 jint jni_transport_le = CALEGetConstantsValue(env, CLASSPATH_BT_DEVICE, "TRANSPORT_LE");
2551 OIC_LOG_V(INFO, TAG, "CALL API - connectGatt with transport LE(%d)", jni_transport_le);
2552 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
2553 jni_mid_connectGatt, NULL,
2554 autoconnect, g_leGattCallback,
2556 if (!jni_obj_connectGatt)
2558 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
2559 CACheckJNIException(env);
2560 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
2561 CALEClientUpdateSendCnt(env);
2566 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
2569 else // lower than API level 23
2572 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2575 OIC_LOG(ERROR, TAG, "GetStringUTFChars has failed");
2578 OIC_LOG(INFO, TAG, "CALL API - connectGatt for hidden");
2579 jni_obj_connectGatt = CALEClientHiddenConnectGatt(bluetoothDevice, address, autoconnect);
2583 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
2585 "(Landroid/content/Context;ZLandroid/"
2586 "bluetooth/BluetoothGattCallback;)"
2587 "Landroid/bluetooth/BluetoothGatt;");
2588 if (!jni_mid_connectGatt)
2590 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
2594 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
2595 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
2596 jni_mid_connectGatt,
2598 autoconnect, g_leGattCallback);
2600 if (!jni_obj_connectGatt)
2602 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
2603 CACheckJNIException(env);
2604 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
2605 CALEClientUpdateSendCnt(env);
2610 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
2615 return jni_obj_connectGatt;
2618 bool CALEClientIsConnected(const char* address)
2620 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2621 STATE_SERVICE_CONNECTED,
2623 g_deviceStateListMutex))
2625 OIC_LOG(DEBUG, TAG, "current state is connected");
2628 OIC_LOG(DEBUG, TAG, "current state is not connected");
2632 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
2634 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
2636 VERIFY_NON_NULL(env, TAG, "env is null");
2637 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2639 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2640 if (!jni_cid_BTAdapter)
2642 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
2646 // get remote bt adapter method
2647 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2648 "getDefaultAdapter",
2649 METHODID_OBJECTNONPARAM);
2650 if (!jni_mid_getDefaultAdapter)
2652 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2656 // gat bt adapter object
2657 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2658 jni_mid_getDefaultAdapter);
2659 if (!jni_obj_BTAdapter)
2661 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2665 // get closeProfileProxy method
2666 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2667 "closeProfileProxy",
2668 "(ILandroid/bluetooth/"
2669 "BluetoothProfile;)V");
2670 if (!jni_mid_closeProfileProxy)
2672 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
2676 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
2677 if (!jni_cid_BTProfile)
2679 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
2683 // GATT - Constant value : 7 (0x00000007)
2684 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
2688 OIC_LOG(ERROR, TAG, "id_gatt is null");
2692 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
2693 CACheckJNIException(env);
2695 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
2696 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
2697 if (CACheckJNIException(env))
2699 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
2700 return CA_STATUS_FAILED;
2703 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
2704 return CA_STATUS_OK;
2707 CACheckJNIException(env);
2708 return CA_STATUS_FAILED;
2712 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
2714 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
2715 VERIFY_NON_NULL(env, TAG, "env is null");
2716 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2718 // get BluetoothGatt method
2719 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
2720 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2721 "disconnect", "()V");
2722 if (!jni_mid_disconnectGatt)
2724 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
2725 return CA_STATUS_FAILED;
2728 // call disconnect gatt method
2729 OIC_LOG(INFO, TAG, "CALL API - disconnect");
2730 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
2731 if (CACheckJNIException(env))
2733 OIC_LOG(ERROR, TAG, "disconnect has failed");
2734 return CA_STATUS_FAILED;
2737 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
2739 return CA_STATUS_OK;
2742 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
2744 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
2745 VERIFY_NON_NULL(env, TAG, "env is null");
2747 if (!g_gattObjectList)
2749 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2750 return CA_STATUS_OK;
2753 uint32_t length = u_arraylist_length(g_gattObjectList);
2754 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
2755 for (uint32_t index = 0; index < length; index++)
2757 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
2758 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2761 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2764 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2765 if (CA_STATUS_OK != res)
2767 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2772 return CA_STATUS_OK;
2775 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
2777 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
2778 VERIFY_NON_NULL(env, TAG, "env is null");
2780 if (!g_gattObjectList)
2782 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2783 return CA_STATUS_OK;
2786 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
2789 OIC_LOG(ERROR, TAG, "address is null");
2790 CACheckJNIException(env);
2791 return CA_STATUS_FAILED;
2794 uint32_t length = u_arraylist_length(g_gattObjectList);
2795 for (uint32_t index = 0; index < length; index++)
2797 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2800 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2804 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2805 if (!jni_setAddress)
2807 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2808 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2809 return CA_STATUS_FAILED;
2812 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2815 OIC_LOG(ERROR, TAG, "setAddress is null");
2816 CACheckJNIException(env);
2817 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2818 return CA_STATUS_FAILED;
2821 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
2822 if (!strcasecmp(address, setAddress))
2824 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2825 if (CA_STATUS_OK != res)
2827 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2828 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2829 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2830 return CA_STATUS_FAILED;
2832 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2833 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2834 return CA_STATUS_OK;
2836 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2838 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2840 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
2841 return CA_STATUS_OK;
2844 CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size)
2846 VERIFY_NON_NULL(env, TAG, "env is null");
2847 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2849 if (!CALEIsEnableBTAdapter(env))
2851 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2852 return CA_ADAPTER_NOT_ENABLED;
2855 // get BluetoothGatt.requestMtu method
2856 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.requestMtu method");
2857 jmethodID jni_mid_requestMtu = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2858 "requestMtu", "(I)Z");
2859 if (!jni_mid_requestMtu)
2861 OIC_LOG(ERROR, TAG, "jni_mid_requestMtu is null");
2862 return CA_STATUS_FAILED;
2866 OIC_LOG(INFO, TAG, "CALL API - requestMtu");
2867 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_requestMtu, size);
2870 OIC_LOG(ERROR, TAG, "requestMtu has failed");
2871 CACheckJNIException(env);
2872 return CA_STATUS_FAILED;
2875 return CA_STATUS_OK;
2878 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
2880 VERIFY_NON_NULL(env, TAG, "env is null");
2881 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2883 if (!CALEIsEnableBTAdapter(env))
2885 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2886 return CA_ADAPTER_NOT_ENABLED;
2889 // get BluetoothGatt.discoverServices method
2890 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
2891 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2892 "discoverServices", "()Z");
2893 if (!jni_mid_discoverServices)
2895 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
2896 return CA_STATUS_FAILED;
2899 // call disconnect gatt method
2900 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
2901 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
2904 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
2905 CACheckJNIException(env);
2906 return CA_STATUS_FAILED;
2909 return CA_STATUS_OK;
2912 static void CALEWriteCharacteristicThread(void* object)
2914 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
2916 bool isAttached = false;
2918 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2921 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2925 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2931 jobject gatt = (jobject)object;
2932 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2933 if (CA_STATUS_OK != ret)
2935 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2940 (*g_jvm)->DetachCurrentThread(g_jvm);
2944 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2946 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
2948 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2949 VERIFY_NON_NULL(env, TAG, "env is null");
2951 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
2954 CALEClientSendFinish(env, gatt);
2955 return CA_STATUS_FAILED;
2958 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2961 CACheckJNIException(env);
2962 CALEClientSendFinish(env, gatt);
2963 return CA_STATUS_FAILED;
2966 oc_mutex_lock(g_threadSendStateMutex);
2968 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING,
2970 g_deviceStateListMutex))
2972 OIC_LOG(INFO, TAG, "current state is SENDING");
2973 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2974 oc_mutex_unlock(g_threadSendStateMutex);
2975 return CA_STATUS_OK;
2978 if (CA_STATUS_OK != CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
2981 g_deviceStateListMutex))
2983 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
2984 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2985 CALEClientSendFinish(env, gatt);
2986 oc_mutex_unlock(g_threadSendStateMutex);
2987 return CA_STATUS_FAILED;
2990 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2992 oc_mutex_unlock(g_threadSendStateMutex);
2994 jbyteArray sendData = NULL;
2995 oc_mutex_lock(g_setValueMutex);
2998 OIC_LOG(INFO, TAG, "alloc local reference for data");
2999 sendData = (jbyteArray)(*env)->NewLocalRef(env, g_sendBuffer);
3003 OIC_LOG(ERROR, TAG, "send Buffer is empty");
3004 oc_mutex_unlock(g_setValueMutex);
3005 return CA_STATUS_FAILED;
3007 oc_mutex_unlock(g_setValueMutex);
3010 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, sendData);
3011 if (!jni_obj_character)
3015 (*env)->DeleteLocalRef(env, sendData);
3017 CALEClientSendFinish(env, gatt);
3018 return CA_STATUS_FAILED;
3023 (*env)->DeleteLocalRef(env, sendData);
3026 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
3027 if (CA_STATUS_OK != ret)
3029 CALEClientSendFinish(env, gatt);
3030 return CA_STATUS_FAILED;
3033 // wait for callback for write Characteristic with success to sent data
3034 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
3035 oc_mutex_lock(g_threadWriteCharacteristicMutex);
3036 if (!g_isSignalSetFlag)
3038 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
3039 if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
3040 g_threadWriteCharacteristicMutex,
3041 WAIT_TIME_WRITE_CHARACTERISTIC))
3043 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
3044 g_isSignalSetFlag = false;
3045 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3046 return CA_STATUS_FAILED;
3049 // reset flag set by writeCharacteristic Callback
3050 g_isSignalSetFlag = false;
3051 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3053 CALEClientUpdateSendCnt(env);
3055 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
3056 return CA_STATUS_OK;
3059 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
3061 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
3062 VERIFY_NON_NULL(env, TAG, "env is null");
3063 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3065 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
3066 CACheckJNIException(env);
3067 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEWriteCharacteristicThread,
3068 (void*)gattParam, NULL))
3070 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
3071 return CA_STATUS_FAILED;
3074 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
3075 return CA_STATUS_OK;
3078 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
3079 jobject gattCharacteristic)
3081 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
3082 VERIFY_NON_NULL(env, TAG, "env is null");
3083 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3084 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
3086 if (!CALEIsEnableBTAdapter(env))
3088 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3089 return CA_STATUS_FAILED;
3092 // get BluetoothGatt.write characteristic method
3093 OIC_LOG(DEBUG, TAG, "write characteristic method");
3094 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3095 "writeCharacteristic",
3096 "(Landroid/bluetooth/"
3097 "BluetoothGattCharacteristic;)Z");
3098 if (!jni_mid_writeCharacteristic)
3100 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
3101 return CA_STATUS_FAILED;
3104 // call disconnect gatt method
3105 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
3106 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
3107 jni_mid_writeCharacteristic,
3108 gattCharacteristic);
3111 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
3115 CACheckJNIException(env);
3116 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
3117 return CA_STATUS_FAILED;
3120 return CA_STATUS_OK;
3123 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
3125 VERIFY_NON_NULL(env, TAG, "env is null");
3126 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3128 if (!CALEIsEnableBTAdapter(env))
3130 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3131 return CA_STATUS_FAILED;
3134 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3137 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3138 CACheckJNIException(env);
3139 return CA_STATUS_FAILED;
3142 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
3143 if (!jni_obj_GattCharacteristic)
3145 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3146 return CA_STATUS_FAILED;
3149 OIC_LOG(DEBUG, TAG, "read characteristic method");
3150 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3151 "readCharacteristic",
3152 "(Landroid/bluetooth/"
3153 "BluetoothGattCharacteristic;)Z");
3154 if (!jni_mid_readCharacteristic)
3156 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
3157 return CA_STATUS_FAILED;
3160 // call disconnect gatt method
3161 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
3162 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
3163 jni_obj_GattCharacteristic);
3166 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
3170 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
3171 CACheckJNIException(env);
3172 return CA_STATUS_FAILED;
3175 return CA_STATUS_OK;
3178 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
3179 jobject characteristic)
3181 VERIFY_NON_NULL(env, TAG, "env is null");
3182 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3183 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
3185 if (!CALEIsEnableBTAdapter(env))
3187 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3188 return CA_ADAPTER_NOT_ENABLED;
3191 // get BluetoothGatt.setCharacteristicNotification method
3192 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
3193 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3194 "setCharacteristicNotification",
3195 "(Landroid/bluetooth/"
3196 "BluetoothGattCharacteristic;Z)Z");
3197 if (!jni_mid_setNotification)
3199 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
3200 return CA_STATUS_FAILED;
3203 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
3204 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
3205 characteristic, JNI_TRUE);
3206 if (JNI_TRUE == ret)
3208 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
3212 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
3213 CACheckJNIException(env);
3214 return CA_STATUS_FAILED;
3217 return CA_STATUS_OK;
3220 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
3222 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3223 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
3224 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
3226 if (!CALEIsEnableBTAdapter(env))
3228 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3232 // get BluetoothGatt.getService method
3233 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
3234 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3236 "(Ljava/util/UUID;)Landroid/bluetooth/"
3237 "BluetoothGattService;");
3238 if (!jni_mid_getService)
3240 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
3244 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
3245 if (!jni_obj_service_uuid)
3247 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
3251 // get bluetooth gatt service
3252 OIC_LOG(DEBUG, TAG, "request to get service");
3253 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
3254 jni_obj_service_uuid);
3255 if (!jni_obj_gattService)
3257 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
3258 CACheckJNIException(env);
3262 // get bluetooth gatt service method
3263 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
3264 "BluetoothGattService",
3265 "getCharacteristic",
3266 "(Ljava/util/UUID;)"
3267 "Landroid/bluetooth/"
3268 "BluetoothGattCharacteristic;");
3269 if (!jni_mid_getCharacteristic)
3271 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
3275 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
3278 OIC_LOG(ERROR, TAG, "uuid is null");
3279 CACheckJNIException(env);
3283 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
3284 if (!jni_obj_tx_uuid)
3286 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
3287 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
3291 OIC_LOG(DEBUG, TAG, "CALL API getCharacteristic");
3292 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
3293 jni_mid_getCharacteristic,
3295 if (!jni_obj_GattCharacteristic)
3297 OIC_LOG(ERROR, TAG, "getCharacteristic has failed");
3298 CACheckJNIException(env);
3302 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
3303 return jni_obj_GattCharacteristic;
3306 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
3308 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
3309 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3310 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
3311 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
3313 if (!CALEIsEnableBTAdapter(env))
3315 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3319 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
3322 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3326 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
3327 if (!jni_obj_GattCharacteristic)
3329 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3333 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
3334 "/BluetoothGattCharacteristic");
3335 if (!jni_cid_BTGattCharacteristic)
3337 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
3341 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
3342 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
3344 if (!jni_mid_setValue)
3346 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
3350 OIC_LOG(DEBUG, TAG, "CALL API - setValue");
3351 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
3353 if (JNI_TRUE == ret)
3355 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
3359 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
3365 OIC_LOG(DEBUG, TAG, "setWriteType with WRITE_TYPE_NO_RESPONSE");
3367 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
3368 "setWriteType", "(I)V");
3369 if (!jni_mid_setWriteType)
3371 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
3375 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
3376 "WRITE_TYPE_NO_RESPONSE", "I");
3377 if (!jni_fid_no_response)
3379 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
3383 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
3384 jni_fid_no_response);
3385 CACheckJNIException(env);
3387 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
3388 if (CACheckJNIException(env))
3390 OIC_LOG(ERROR, TAG, "setWriteType has failed");
3395 OIC_LOG(DEBUG, TAG, "It will run with response property");
3398 return jni_obj_GattCharacteristic;
3401 CACheckJNIException(env);
3405 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
3407 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
3408 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3410 if (!CALEIsEnableBTAdapter(env))
3412 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3416 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
3417 "BluetoothGattCharacteristic",
3418 "getValue", "()[B");
3419 if (!jni_mid_getValue)
3421 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
3425 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
3427 CACheckJNIException(env);
3428 return jni_obj_data_array;
3431 CAResult_t CALEClientCreateUUIDList()
3435 OIC_LOG(ERROR, TAG, "g_jvm is null");
3436 return CA_STATUS_FAILED;
3439 bool isAttached = false;
3441 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3444 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3448 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3449 return CA_STATUS_FAILED;
3454 // create new object array
3455 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
3456 if (!jni_cid_uuid_list)
3458 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
3459 CACheckJNIException(env);
3463 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
3464 jni_cid_uuid_list, NULL);
3465 if (!jni_obj_uuid_list)
3467 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
3468 CACheckJNIException(env);
3473 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
3476 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
3479 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
3481 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
3482 CACheckJNIException(env);
3486 (*g_jvm)->DetachCurrentThread(g_jvm);
3489 return CA_STATUS_OK;
3496 (*g_jvm)->DetachCurrentThread(g_jvm);
3498 return CA_STATUS_FAILED;
3501 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
3502 jobject characteristic)
3504 VERIFY_NON_NULL(env, TAG, "env is null");
3505 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3506 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
3508 if (!CALEIsEnableBTAdapter(env))
3510 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3511 return CA_ADAPTER_NOT_ENABLED;
3514 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
3515 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
3516 "BluetoothGattCharacteristic",
3518 "(Ljava/util/UUID;)Landroid/bluetooth/"
3519 "BluetoothGattDescriptor;");
3520 if (!jni_mid_getDescriptor)
3522 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
3523 return CA_STATUS_FAILED;
3526 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
3527 if (!jni_obj_cc_uuid)
3529 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
3532 OIC_LOG(DEBUG, TAG, "request to get descriptor");
3533 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
3534 jni_mid_getDescriptor, jni_obj_cc_uuid);
3535 if (!jni_obj_descriptor)
3537 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
3541 OIC_LOG(DEBUG, TAG, "set value in descriptor");
3542 jclass jni_cid_descriptor = (*env)->FindClass(env,
3543 "android/bluetooth/BluetoothGattDescriptor");
3544 if (!jni_cid_descriptor)
3546 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
3550 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
3551 if (!jni_mid_setValue)
3553 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
3557 jfieldID jni_fid_NotiValue = NULL;
3560 OIC_LOG(DEBUG, TAG, "get ENABLE_INDICATION_VALUE");
3561 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
3562 "ENABLE_INDICATION_VALUE", "[B");
3563 if (!jni_fid_NotiValue)
3565 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
3571 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
3572 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
3573 "ENABLE_NOTIFICATION_VALUE", "[B");
3574 if (!jni_fid_NotiValue)
3576 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
3581 jboolean jni_setvalue = (*env)->CallBooleanMethod(
3582 env, jni_obj_descriptor, jni_mid_setValue,
3583 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
3586 OIC_LOG(DEBUG, TAG, "setValue success");
3590 OIC_LOG(ERROR, TAG, "setValue has failed");
3594 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
3596 "(Landroid/bluetooth/"
3597 "BluetoothGattDescriptor;)Z");
3598 if (!jni_mid_writeDescriptor)
3600 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
3601 return CA_STATUS_FAILED;
3604 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
3605 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
3606 jni_obj_descriptor);
3609 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
3613 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
3617 return CA_STATUS_OK;
3620 CACheckJNIException(env);
3621 return CA_STATUS_FAILED;
3624 void CALEClientCreateScanDeviceList(JNIEnv *env)
3626 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
3627 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3629 oc_mutex_lock(g_deviceListMutex);
3630 // create new object array
3631 if (g_deviceList == NULL)
3633 OIC_LOG(DEBUG, TAG, "Create device list");
3635 g_deviceList = u_arraylist_create();
3637 oc_mutex_unlock(g_deviceListMutex);
3640 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
3642 VERIFY_NON_NULL(device, TAG, "device is null");
3643 VERIFY_NON_NULL(env, TAG, "env is null");
3645 oc_mutex_lock(g_deviceListMutex);
3649 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3650 oc_mutex_unlock(g_deviceListMutex);
3651 return CA_STATUS_FAILED;
3654 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
3655 if (!jni_remoteAddress)
3657 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3658 oc_mutex_unlock(g_deviceListMutex);
3659 return CA_STATUS_FAILED;
3662 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3665 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3666 CACheckJNIException(env);
3667 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3668 oc_mutex_unlock(g_deviceListMutex);
3669 return CA_STATUS_FAILED;
3672 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
3674 jobject gdevice = (*env)->NewGlobalRef(env, device);
3675 CACheckJNIException(env);
3676 u_arraylist_add(g_deviceList, gdevice);
3677 oc_cond_signal(g_deviceDescCond);
3678 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
3680 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3681 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3683 oc_mutex_unlock(g_deviceListMutex);
3685 return CA_STATUS_OK;
3688 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
3690 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
3691 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
3695 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
3699 uint32_t length = u_arraylist_length(g_deviceList);
3700 for (uint32_t index = 0; index < length; index++)
3702 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3705 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3709 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
3710 if (!jni_setAddress)
3712 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3716 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3719 OIC_LOG(ERROR, TAG, "setAddress is null");
3720 CACheckJNIException(env);
3721 (*env)->DeleteLocalRef(env, jni_setAddress);
3725 if (!strcasecmp(remoteAddress, setAddress))
3727 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3728 (*env)->DeleteLocalRef(env, jni_setAddress);
3732 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3733 (*env)->DeleteLocalRef(env, jni_setAddress);
3738 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
3740 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
3741 VERIFY_NON_NULL(env, TAG, "env is null");
3743 oc_mutex_lock(g_deviceListMutex);
3747 OIC_LOG(ERROR, TAG, "g_deviceList is null");
3748 oc_mutex_unlock(g_deviceListMutex);
3749 return CA_STATUS_FAILED;
3752 uint32_t length = u_arraylist_length(g_deviceList);
3753 for (uint32_t index = 0; index < length; index++)
3755 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3758 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3761 (*env)->DeleteGlobalRef(env, jarrayObj);
3765 OICFree(g_deviceList);
3766 g_deviceList = NULL;
3768 oc_mutex_unlock(g_deviceListMutex);
3769 return CA_STATUS_OK;
3772 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
3774 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
3775 VERIFY_NON_NULL(address, TAG, "address is null");
3776 VERIFY_NON_NULL(env, TAG, "env is null");
3778 oc_mutex_lock(g_deviceListMutex);
3782 OIC_LOG(ERROR, TAG, "g_deviceList is null");
3783 oc_mutex_unlock(g_deviceListMutex);
3784 return CA_STATUS_FAILED;
3787 uint32_t length = u_arraylist_length(g_deviceList);
3788 for (uint32_t index = 0; index < length; index++)
3790 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3793 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3794 oc_mutex_unlock(g_deviceListMutex);
3795 return CA_STATUS_FAILED;
3798 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
3799 if (!jni_setAddress)
3801 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3802 oc_mutex_unlock(g_deviceListMutex);
3803 return CA_STATUS_FAILED;
3806 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3809 OIC_LOG(ERROR, TAG, "setAddress is null");
3810 CACheckJNIException(env);
3811 oc_mutex_unlock(g_deviceListMutex);
3812 return CA_STATUS_FAILED;
3815 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
3818 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3819 CACheckJNIException(env);
3820 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3821 oc_mutex_unlock(g_deviceListMutex);
3822 return CA_STATUS_FAILED;
3825 if (!strcasecmp(setAddress, remoteAddress))
3827 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3828 (*env)->DeleteGlobalRef(env, jarrayObj);
3830 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3831 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
3833 if (NULL == u_arraylist_remove(g_deviceList, index))
3835 OIC_LOG(ERROR, TAG, "List removal failed.");
3836 oc_mutex_unlock(g_deviceListMutex);
3837 return CA_STATUS_FAILED;
3839 oc_mutex_unlock(g_deviceListMutex);
3840 return CA_STATUS_OK;
3842 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3843 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
3846 oc_mutex_unlock(g_deviceListMutex);
3847 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
3849 return CA_STATUS_OK;
3856 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
3858 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
3859 VERIFY_NON_NULL(env, TAG, "env is null");
3860 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3862 oc_mutex_lock(g_gattObjectMutex);
3864 if (!g_gattObjectList)
3866 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
3867 oc_mutex_unlock(g_gattObjectMutex);
3868 return CA_STATUS_FAILED;
3871 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3872 if (!jni_remoteAddress)
3874 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3875 oc_mutex_unlock(g_gattObjectMutex);
3876 return CA_STATUS_FAILED;
3879 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3882 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3883 CACheckJNIException(env);
3884 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3885 oc_mutex_unlock(g_gattObjectMutex);
3886 return CA_STATUS_FAILED;
3889 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
3890 if (!CALEClientIsGattObjInList(env, remoteAddress))
3892 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
3893 u_arraylist_add(g_gattObjectList, newGatt);
3894 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
3897 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3898 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3899 oc_mutex_unlock(g_gattObjectMutex);
3900 return CA_STATUS_OK;
3903 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
3905 VERIFY_NON_NULL(env, TAG, "env is null");
3906 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
3908 uint32_t length = u_arraylist_length(g_gattObjectList);
3909 for (uint32_t index = 0; index < length; index++)
3911 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3914 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3918 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3919 if (!jni_setAddress)
3921 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3925 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3928 OIC_LOG(ERROR, TAG, "setAddress is null");
3929 CACheckJNIException(env);
3930 (*env)->DeleteLocalRef(env, jni_setAddress);
3934 if (!strcasecmp(remoteAddress, setAddress))
3936 OIC_LOG(DEBUG, TAG, "the device is already set");
3937 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3938 (*env)->DeleteLocalRef(env, jni_setAddress);
3941 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3942 (*env)->DeleteLocalRef(env, jni_setAddress);
3945 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
3949 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
3951 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
3952 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3953 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3955 oc_mutex_lock(g_gattObjectMutex);
3956 uint32_t length = u_arraylist_length(g_gattObjectList);
3957 for (uint32_t index = 0; index < length; index++)
3959 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3962 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3963 oc_mutex_unlock(g_gattObjectMutex);
3967 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3968 if (!jni_setAddress)
3970 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3971 oc_mutex_unlock(g_gattObjectMutex);
3975 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3978 OIC_LOG(ERROR, TAG, "setAddress is null");
3979 CACheckJNIException(env);
3980 (*env)->DeleteLocalRef(env, jni_setAddress);
3981 oc_mutex_unlock(g_gattObjectMutex);
3985 if (!strcasecmp(remoteAddress, setAddress))
3987 OIC_LOG(DEBUG, TAG, "the device is already set");
3988 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3989 oc_mutex_unlock(g_gattObjectMutex);
3992 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3993 (*env)->DeleteLocalRef(env, jni_setAddress);
3996 oc_mutex_unlock(g_gattObjectMutex);
3997 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
4001 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
4003 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
4004 VERIFY_NON_NULL(env, TAG, "env is null");
4006 oc_mutex_lock(g_gattObjectMutex);
4007 if (!g_gattObjectList)
4009 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4010 oc_mutex_unlock(g_gattObjectMutex);
4011 return CA_STATUS_OK;
4014 uint32_t length = u_arraylist_length(g_gattObjectList);
4015 for (uint32_t index = 0; index < length; index++)
4017 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4020 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4023 (*env)->DeleteGlobalRef(env, jarrayObj);
4027 OICFree(g_gattObjectList);
4028 g_gattObjectList = NULL;
4029 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
4030 oc_mutex_unlock(g_gattObjectMutex);
4031 return CA_STATUS_OK;
4034 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
4036 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
4037 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
4038 VERIFY_NON_NULL(env, TAG, "env is null");
4040 oc_mutex_lock(g_gattObjectMutex);
4041 if (!g_gattObjectList)
4043 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4044 oc_mutex_unlock(g_gattObjectMutex);
4045 return CA_STATUS_OK;
4048 uint32_t length = u_arraylist_length(g_gattObjectList);
4049 for (uint32_t index = 0; index < length; index++)
4051 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4054 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4055 oc_mutex_unlock(g_gattObjectMutex);
4056 return CA_STATUS_FAILED;
4059 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4060 if (!jni_setAddress)
4062 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4063 oc_mutex_unlock(g_gattObjectMutex);
4064 return CA_STATUS_FAILED;
4067 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4070 OIC_LOG(ERROR, TAG, "setAddress is null");
4071 CACheckJNIException(env);
4072 oc_mutex_unlock(g_gattObjectMutex);
4073 return CA_STATUS_FAILED;
4076 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
4077 if (!jni_remoteAddress)
4079 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
4080 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4081 oc_mutex_unlock(g_gattObjectMutex);
4082 return CA_STATUS_FAILED;
4085 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
4088 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4089 CACheckJNIException(env);
4090 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4091 oc_mutex_unlock(g_gattObjectMutex);
4092 return CA_STATUS_FAILED;
4095 if (!strcasecmp(setAddress, remoteAddress))
4097 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4098 (*env)->DeleteGlobalRef(env, jarrayObj);
4100 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4101 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4103 if (NULL == u_arraylist_remove(g_gattObjectList, index))
4105 OIC_LOG(ERROR, TAG, "List removal failed.");
4106 oc_mutex_unlock(g_gattObjectMutex);
4107 return CA_STATUS_FAILED;
4109 oc_mutex_unlock(g_gattObjectMutex);
4110 return CA_STATUS_OK;
4112 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4113 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4116 oc_mutex_unlock(g_gattObjectMutex);
4117 OIC_LOG(DEBUG, TAG, "there are no target object");
4118 return CA_STATUS_OK;
4121 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
4123 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
4124 VERIFY_NON_NULL(addr, TAG, "addr is null");
4125 VERIFY_NON_NULL(env, TAG, "env is null");
4127 oc_mutex_lock(g_gattObjectMutex);
4128 if (!g_gattObjectList)
4130 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4131 oc_mutex_unlock(g_gattObjectMutex);
4132 return CA_STATUS_OK;
4135 uint32_t length = u_arraylist_length(g_gattObjectList);
4136 for (uint32_t index = 0; index < length; index++)
4138 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4141 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4142 oc_mutex_unlock(g_gattObjectMutex);
4143 return CA_STATUS_FAILED;
4146 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4147 if (!jni_setAddress)
4149 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4150 oc_mutex_unlock(g_gattObjectMutex);
4151 return CA_STATUS_FAILED;
4154 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4157 OIC_LOG(ERROR, TAG, "setAddress is null");
4158 CACheckJNIException(env);
4159 oc_mutex_unlock(g_gattObjectMutex);
4160 return CA_STATUS_FAILED;
4163 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
4166 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4167 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4168 oc_mutex_unlock(g_gattObjectMutex);
4169 return CA_STATUS_FAILED;
4172 if (!strcasecmp(setAddress, remoteAddress))
4174 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4175 (*env)->DeleteGlobalRef(env, jarrayObj);
4177 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4178 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
4179 if (NULL == u_arraylist_remove(g_gattObjectList, index))
4181 OIC_LOG(ERROR, TAG, "List removal failed.");
4182 oc_mutex_unlock(g_gattObjectMutex);
4183 return CA_STATUS_FAILED;
4185 oc_mutex_unlock(g_gattObjectMutex);
4186 return CA_STATUS_OK;
4188 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4189 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
4192 oc_mutex_unlock(g_gattObjectMutex);
4193 OIC_LOG(DEBUG, TAG, "there are no target object");
4194 return CA_STATUS_FAILED;
4197 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
4199 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
4200 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
4202 // get Bluetooth Address
4203 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
4204 if (!jni_btTargetAddress)
4206 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4210 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
4213 OIC_LOG(ERROR, TAG, "targetAddress is not available");
4214 CACheckJNIException(env);
4218 // get method ID of getDevice()
4219 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
4220 "getDevice", METHODID_BT_DEVICE);
4221 if (!jni_mid_getDevice)
4223 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4224 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4228 oc_mutex_lock(g_gattObjectMutex);
4230 size_t length = u_arraylist_length(g_gattObjectList);
4231 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
4232 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
4234 for (size_t index = 0; index < length; index++)
4236 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4239 oc_mutex_unlock(g_gattObjectMutex);
4240 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4241 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4245 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
4246 if (!jni_obj_device)
4248 CACheckJNIException(env);
4249 oc_mutex_unlock(g_gattObjectMutex);
4250 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4251 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4255 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
4258 oc_mutex_unlock(g_gattObjectMutex);
4259 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4260 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4261 (*env)->DeleteLocalRef(env, jni_obj_device);
4265 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
4268 CACheckJNIException(env);
4269 oc_mutex_unlock(g_gattObjectMutex);
4270 OIC_LOG(ERROR, TAG, "btAddress is not available");
4271 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4272 (*env)->DeleteLocalRef(env, jni_btAddress);
4273 (*env)->DeleteLocalRef(env, jni_obj_device);
4277 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
4278 if (!strcasecmp(targetAddress, btAddress))
4280 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
4283 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4286 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
4288 oc_mutex_unlock(g_gattObjectMutex);
4289 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4290 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
4291 (*env)->DeleteLocalRef(env, jni_btAddress);
4292 (*env)->DeleteLocalRef(env, jni_obj_device);
4293 return jni_LEAddress;
4295 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
4296 (*env)->DeleteLocalRef(env, jni_btAddress);
4297 (*env)->DeleteLocalRef(env, jni_obj_device);
4299 oc_mutex_unlock(g_gattObjectMutex);
4301 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4302 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
4309 CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env,
4311 uint16_t state_type,
4312 uint16_t target_state)
4314 VERIFY_NON_NULL(device, TAG, "device is null");
4316 // get Bluetooth Address
4317 jstring jni_Address = CALEGetAddressFromBTDevice(env, device);
4320 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4321 return CA_STATUS_FAILED;
4324 const char* address = (*env)->GetStringUTFChars(env, jni_Address, NULL);
4327 OIC_LOG(ERROR, TAG, "targetAddress is not available");
4328 CACheckJNIException(env);
4329 (*env)->DeleteLocalRef(env, jni_Address);
4330 return CA_STATUS_FAILED;
4333 if (CALEIsValidState(address, state_type, target_state,
4335 g_deviceStateListMutex))
4337 (*env)->DeleteLocalRef(env, jni_Address);
4338 return CA_STATUS_OK;
4341 CAResult_t res = CALEUpdateDeviceState(address, state_type,
4344 g_deviceStateListMutex);
4345 if (CA_STATUS_OK != res)
4347 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4349 (*env)->ReleaseStringUTFChars(env, jni_Address, address);
4350 (*env)->DeleteLocalRef(env, jni_Address);
4355 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
4356 jint state_idx, jboolean flag)
4358 return CALESetFlagToState(env, jni_address, state_idx, flag,
4359 g_deviceStateList, g_deviceStateListMutex);
4362 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
4364 return CALEGetFlagFromState(env, jni_address, state_idx, g_deviceStateList,
4365 g_deviceStateListMutex);
4368 uint16_t CALEClientGetMtuSize(const char* address)
4370 return CALEGetMtuSize(address, g_deviceStateList, g_deviceStateListMutex);
4373 void CALEClientCreateDeviceList()
4375 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
4377 // create new object array
4378 if (!g_gattObjectList)
4380 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
4382 g_gattObjectList = u_arraylist_create();
4385 if (!g_deviceStateList)
4387 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
4389 g_deviceStateList = u_arraylist_create();
4394 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
4396 g_deviceList = u_arraylist_create();
4400 CAResult_t CALEClientResetDeviceStateForAll()
4402 return CALEResetDeviceStateForAll(g_deviceStateList, g_deviceStateListMutex);
4406 * Check Sent Count for remove g_sendBuffer
4408 void CALEClientUpdateSendCnt(JNIEnv *env)
4410 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
4412 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4414 oc_mutex_lock(g_threadMutex);
4418 if (g_targetCnt <= g_currentSentCnt)
4421 g_currentSentCnt = 0;
4423 CALEDeleteSendBuffer(env);
4425 // notity the thread
4426 oc_cond_signal(g_threadCond);
4427 oc_cond_signal(g_threadWriteCharacteristicCond);
4429 CALEClientSetSendFinishFlag(true);
4430 OIC_LOG(DEBUG, TAG, "set signal for send data");
4433 #ifdef SCAN_INTERVAL
4434 // reset interval scan logic
4435 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
4439 oc_mutex_unlock(g_threadMutex);
4442 CAResult_t CALEClientInitGattMutexVaraibles()
4444 if (NULL == g_bleReqRespClientCbMutex)
4446 g_bleReqRespClientCbMutex = oc_mutex_new();
4447 if (NULL == g_bleReqRespClientCbMutex)
4449 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4450 return CA_STATUS_FAILED;
4454 if (NULL == g_bleServerBDAddressMutex)
4456 g_bleServerBDAddressMutex = oc_mutex_new();
4457 if (NULL == g_bleServerBDAddressMutex)
4459 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4460 return CA_STATUS_FAILED;
4464 if (NULL == g_threadMutex)
4466 g_threadMutex = oc_mutex_new();
4467 if (NULL == g_threadMutex)
4469 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4470 return CA_STATUS_FAILED;
4474 if (NULL == g_threadSendMutex)
4476 g_threadSendMutex = oc_mutex_new();
4477 if (NULL == g_threadSendMutex)
4479 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4480 return CA_STATUS_FAILED;
4484 if (NULL == g_deviceListMutex)
4486 g_deviceListMutex = oc_mutex_new();
4487 if (NULL == g_deviceListMutex)
4489 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4490 return CA_STATUS_FAILED;
4494 if (NULL == g_gattObjectMutex)
4496 g_gattObjectMutex = oc_mutex_new();
4497 if (NULL == g_gattObjectMutex)
4499 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4500 return CA_STATUS_FAILED;
4504 if (NULL == g_deviceStateListMutex)
4506 g_deviceStateListMutex = oc_mutex_new();
4507 if (NULL == g_deviceStateListMutex)
4509 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4510 return CA_STATUS_FAILED;
4514 if (NULL == g_SendFinishMutex)
4516 g_SendFinishMutex = oc_mutex_new();
4517 if (NULL == g_SendFinishMutex)
4519 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4520 return CA_STATUS_FAILED;
4524 if (NULL == g_threadWriteCharacteristicMutex)
4526 g_threadWriteCharacteristicMutex = oc_mutex_new();
4527 if (NULL == g_threadWriteCharacteristicMutex)
4529 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4530 return CA_STATUS_FAILED;
4534 if (NULL == g_deviceScanRetryDelayMutex)
4536 g_deviceScanRetryDelayMutex = oc_mutex_new();
4537 if (NULL == g_deviceScanRetryDelayMutex)
4539 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4540 return CA_STATUS_FAILED;
4544 if (NULL == g_threadSendStateMutex)
4546 g_threadSendStateMutex = oc_mutex_new();
4547 if (NULL == g_threadSendStateMutex)
4549 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4550 return CA_STATUS_FAILED;
4554 if (NULL == g_threadScanIntervalMutex)
4556 g_threadScanIntervalMutex = oc_mutex_new();
4557 if (NULL == g_threadScanIntervalMutex)
4559 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4560 return CA_STATUS_FAILED;
4564 if (NULL == g_setValueMutex)
4566 g_setValueMutex = oc_mutex_new();
4567 if (NULL == g_setValueMutex)
4569 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4570 return CA_STATUS_FAILED;
4574 return CA_STATUS_OK;
4577 void CALEClientTerminateGattMutexVariables()
4579 oc_mutex_free(g_bleReqRespClientCbMutex);
4580 g_bleReqRespClientCbMutex = NULL;
4582 oc_mutex_free(g_bleServerBDAddressMutex);
4583 g_bleServerBDAddressMutex = NULL;
4585 oc_mutex_free(g_threadMutex);
4586 g_threadMutex = NULL;
4588 oc_mutex_free(g_threadSendMutex);
4589 g_threadSendMutex = NULL;
4591 oc_mutex_free(g_deviceListMutex);
4592 g_deviceListMutex = NULL;
4594 oc_mutex_free(g_SendFinishMutex);
4595 g_SendFinishMutex = NULL;
4597 oc_mutex_free(g_threadWriteCharacteristicMutex);
4598 g_threadWriteCharacteristicMutex = NULL;
4600 oc_mutex_free(g_deviceScanRetryDelayMutex);
4601 g_deviceScanRetryDelayMutex = NULL;
4603 oc_mutex_free(g_threadSendStateMutex);
4604 g_threadSendStateMutex = NULL;
4606 oc_mutex_free(g_threadScanIntervalMutex);
4607 g_threadScanIntervalMutex = NULL;
4609 oc_mutex_free(g_gattObjectMutex);
4610 g_gattObjectMutex = NULL;
4612 oc_mutex_free(g_deviceStateListMutex);
4613 g_deviceStateListMutex = NULL;
4615 oc_mutex_free(g_setValueMutex);
4616 g_setValueMutex = NULL;
4619 void CALEClientSetSendFinishFlag(bool flag)
4621 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
4623 oc_mutex_lock(g_SendFinishMutex);
4624 g_isFinishedSendData = flag;
4625 oc_mutex_unlock(g_SendFinishMutex);
4632 CAResult_t CAStartLEGattClient()
4634 // init mutex for send logic
4635 if (!g_deviceDescCond)
4637 g_deviceDescCond = oc_cond_new();
4642 g_threadCond = oc_cond_new();
4645 if (!g_threadWriteCharacteristicCond)
4647 g_threadWriteCharacteristicCond = oc_cond_new();
4650 if (!g_threadScanIntervalCond)
4652 g_threadScanIntervalCond = oc_cond_new();
4655 CAResult_t ret = CALEClientStartScanWithInterval();
4656 if (CA_STATUS_OK != ret)
4658 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
4662 g_isStartedLEClient = true;
4663 return CA_STATUS_OK;
4666 void CAStopLEGattClient()
4668 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
4672 OIC_LOG(ERROR, TAG, "g_jvm is null");
4676 bool isAttached = false;
4678 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
4681 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
4685 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
4691 CAResult_t ret = CALEClientDisconnectAll(env);
4692 if (CA_STATUS_OK != ret)
4694 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
4697 CALEClientStopScanWithInterval();
4699 oc_mutex_lock(g_threadWriteCharacteristicMutex);
4700 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
4701 oc_cond_signal(g_threadWriteCharacteristicCond);
4702 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
4704 CALEClientSetSendFinishFlag(true);
4705 oc_mutex_lock(g_threadMutex);
4706 OIC_LOG(DEBUG, TAG, "signal - g_threadCond cond");
4707 oc_cond_signal(g_threadCond);
4708 oc_mutex_unlock(g_threadMutex);
4710 oc_mutex_lock(g_deviceScanRetryDelayMutex);
4711 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4712 oc_cond_signal(g_deviceScanRetryDelayCond);
4713 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
4715 oc_mutex_lock(g_threadScanIntervalMutex);
4716 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4717 oc_cond_signal(g_threadScanIntervalCond);
4718 oc_mutex_unlock(g_threadScanIntervalMutex);
4720 oc_mutex_lock(g_threadSendMutex);
4721 OIC_LOG(DEBUG, TAG, "signal - g_deviceDesc cond");
4722 oc_cond_signal(g_deviceDescCond);
4723 oc_mutex_unlock(g_threadSendMutex);
4725 oc_cond_free(g_deviceDescCond);
4726 oc_cond_free(g_threadCond);
4727 oc_cond_free(g_threadWriteCharacteristicCond);
4728 oc_cond_free(g_deviceScanRetryDelayCond);
4729 oc_cond_free(g_threadScanIntervalCond);
4731 g_deviceDescCond = NULL;
4732 g_threadCond = NULL;
4733 g_threadWriteCharacteristicCond = NULL;
4734 g_deviceScanRetryDelayCond = NULL;
4735 g_threadScanIntervalCond = NULL;
4739 (*g_jvm)->DetachCurrentThread(g_jvm);
4744 CAResult_t CAInitializeLEGattClient()
4746 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
4747 CALEClientInitialize();
4748 return CA_STATUS_OK;
4751 void CATerminateLEGattClient()
4753 OIC_LOG(INFO, TAG, "IN - Terminate GATT Client");
4754 CAStopLEGattClient();
4755 CALEClientTerminate();
4756 OIC_LOG(INFO, TAG, "OUT - Terminate GATT Client");
4759 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
4760 uint32_t dataLen, CALETransferType_t type,
4763 OIC_LOG(INFO, TAG, "call CALEClientSendUnicastMessage");
4764 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
4766 if (LE_UNICAST != type || position < 0)
4768 OIC_LOG(ERROR, TAG, "this request is not unicast");
4769 return CA_STATUS_INVALID_PARAM;
4772 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4775 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4777 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4778 VERIFY_NON_NULL(data, TAG, "data is null");
4780 return CALEClientSendMulticastMessage(data, dataLen);
4783 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4785 oc_mutex_lock(g_bleReqRespClientCbMutex);
4786 g_CABLEClientDataReceivedCallback = callback;
4787 oc_mutex_unlock(g_bleReqRespClientCbMutex);
4790 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4792 g_threadPoolHandle = handle;
4795 CAResult_t CAGetLEAddress(char **local_address)
4797 VERIFY_NON_NULL(local_address, TAG, "local_address");
4798 return CA_NOT_SUPPORTED;
4801 JNIEXPORT void JNICALL
4802 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4805 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4806 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4807 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4808 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4810 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4811 CACheckJNIException(env);
4814 JNIEXPORT void JNICALL
4815 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallbackForV21(JNIEnv *env,
4819 OIC_LOG(DEBUG, TAG, "caLeRegisterLeScanCallbackForV21");
4820 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4821 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4822 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4824 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4825 CACheckJNIException(env);
4828 JNIEXPORT void JNICALL
4829 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4832 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4833 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4834 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4835 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4837 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4838 CACheckJNIException(env);
4841 JNIEXPORT void JNICALL
4842 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4845 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4846 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4847 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4849 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4850 if (CA_STATUS_OK != res)
4852 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4856 JNIEXPORT void JNICALL
4857 Java_org_iotivity_ca_CaLeClientInterface_caLeScanFailedCallback(JNIEnv *env, jobject obj,
4860 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4861 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4866 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_ALREADY_STARTED");
4871 "BLE scan has failed, error is SCAN_FAILED_APPLICATION_REGISTRATION_FAILED");
4875 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_INTERNAL_ERROR");
4879 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_FEATURE_UNSUPPORTED");
4883 OIC_LOG(ERROR, TAG, "BLE scan has failed with unknown error");
4889 * Class: org_iotivity_ca_jar_caleinterface
4890 * Method: CALeGattConnectionStateChangeCallback
4891 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4893 JNIEXPORT void JNICALL
4894 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4900 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4902 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4903 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4904 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4906 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4908 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4911 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4915 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4918 OIC_LOG(ERROR, TAG, "address is null");
4919 CACheckJNIException(env);
4922 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
4924 if (state_connected == newstate)
4926 OIC_LOG(DEBUG, TAG, "LE is connected");
4927 if (GATT_SUCCESS == status)
4929 CAResult_t res = CALEUpdateDeviceState(address,
4930 CA_LE_CONNECTION_STATE,
4933 g_deviceStateListMutex);
4934 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4935 if (CA_STATUS_OK != res)
4937 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4941 res = CALEClientAddGattobjToList(env, gatt);
4942 if (CA_STATUS_OK != res)
4944 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4948 res = CALEClientDiscoverServices(env, gatt);
4949 if (CA_STATUS_OK != res)
4951 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4957 OIC_LOG(INFO, TAG, "unknown status");
4958 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4961 else // STATE_DISCONNECTED == newstate
4963 OIC_LOG(DEBUG, TAG, "LE is disconnected");
4965 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SEND_PREPARING,
4966 g_deviceStateList, g_deviceStateListMutex))
4968 OIC_LOG(INFO, TAG, "current state is STATE_SEND_PREPARING");
4969 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
4972 g_deviceStateListMutex);
4973 if (CA_STATUS_OK != res)
4975 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4979 CAResult_t res = CALEUpdateDeviceState(address,
4980 CA_LE_CONNECTION_STATE,
4983 g_deviceStateListMutex);
4984 if (CA_STATUS_OK != res)
4986 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4988 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4990 res = CALEClientGattClose(env, gatt);
4991 if (CA_STATUS_OK != res)
4993 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4996 if (CALECheckConnectionStateValue(status))
4998 // this state is unexpected reason to disconnect
4999 // if the reason is suitable, connection logic of the device will be destroyed.
5000 OIC_LOG(INFO, TAG, "connection logic destroy");
5004 // other reason except for gatt_success is expected to running
5005 // background connection in BT platform.
5006 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
5008 CALEClientUpdateSendCnt(env);
5014 CALEClientSendFinish(env, gatt);
5019 * Class: org_iotivity_ca_jar_caleinterface
5020 * Method: CALeGattServicesDiscoveredCallback
5021 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
5023 JNIEXPORT void JNICALL
5024 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
5029 OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status);
5030 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5031 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5032 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5034 if (GATT_SUCCESS != status) // discovery error
5036 CALEClientSendFinish(env, gatt);
5040 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5043 CALEClientSendFinish(env, gatt);
5047 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5050 CACheckJNIException(env);
5051 CALEClientSendFinish(env, gatt);
5055 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
5058 OIC_LOG(ERROR, TAG, "jni_uuid is null");
5062 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
5063 if (!jni_obj_GattCharacteristic)
5065 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
5069 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
5070 jni_obj_GattCharacteristic);
5071 if (CA_STATUS_OK != res)
5073 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
5077 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
5078 if (CA_STATUS_OK != res)
5080 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
5082 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE,
5083 g_deviceStateList, g_deviceStateListMutex);
5084 if (CA_STATUS_OK != res)
5086 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
5090 res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
5091 STATE_SERVICE_CONNECTED,
5093 g_deviceStateListMutex);
5094 if (CA_STATUS_OK != res)
5096 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5100 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
5101 if (CA_STATUS_OK != res)
5103 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
5109 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE,
5110 g_deviceStateList, g_deviceStateListMutex);
5111 if (CA_STATUS_OK != res)
5113 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
5118 #ifdef SCAN_INTERVAL
5119 // reset interval scan logic
5120 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
5123 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
5124 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5129 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
5130 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5131 CALEClientSendFinish(env, gatt);
5136 * Class: org_iotivity_ca_jar_caleinterface
5137 * Method: CALeGattCharacteristicWritjclasseCallback
5138 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
5140 JNIEXPORT void JNICALL
5141 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
5142 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status)
5144 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
5145 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5146 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5147 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5149 // send success & signal
5150 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5156 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5159 CACheckJNIException(env);
5163 if (GATT_SUCCESS != status) // error case
5165 OIC_LOG(ERROR, TAG, "send failure");
5168 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
5169 if (CA_STATUS_OK != res)
5171 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
5172 oc_mutex_lock(g_threadWriteCharacteristicMutex);
5173 g_isSignalSetFlag = true;
5174 oc_cond_signal(g_threadWriteCharacteristicCond);
5175 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
5177 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5180 g_deviceStateListMutex);
5181 if (CA_STATUS_OK != res)
5183 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5186 if (g_clientErrorCallback)
5188 jint length = (*env)->GetArrayLength(env, data);
5189 CACheckJNIException(env);
5190 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
5191 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, length,
5192 false, "writeChar failure");
5195 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5201 OIC_LOG(DEBUG, TAG, "send success");
5202 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5205 g_deviceStateListMutex);
5206 if (CA_STATUS_OK != res)
5208 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5211 oc_mutex_lock(g_threadWriteCharacteristicMutex);
5212 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
5213 g_isSignalSetFlag = true;
5214 oc_cond_signal(g_threadWriteCharacteristicCond);
5215 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
5217 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0,
5218 (*env)->GetArrayLength(env, data),
5219 true, "writeChar success");
5222 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5228 CALEClientSendFinish(env, gatt);
5233 * Class: org_iotivity_ca_jar_caleinterface
5234 * Method: CALeGattCharacteristicChangedCallback
5235 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
5237 JNIEXPORT void JNICALL
5238 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
5239 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
5241 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
5242 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5243 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5244 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5245 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
5247 // get Byte Array and convert to uint8_t*
5248 jint length = (*env)->GetArrayLength(env, data);
5251 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
5252 CACheckJNIException(env);
5254 uint8_t* receivedData = OICMalloc(length);
5257 OIC_LOG(ERROR, TAG, "receivedData is null");
5261 memcpy(receivedData, jni_byte_responseData, length);
5262 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
5264 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5267 OIC_LOG(ERROR, TAG, "jni_address is null");
5268 OICFree(receivedData);
5272 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5275 OIC_LOG(ERROR, TAG, "address is null");
5276 CACheckJNIException(env);
5277 OICFree(receivedData);
5281 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
5282 receivedData, length);
5284 uint32_t sentLength = 0;
5285 oc_mutex_lock(g_bleServerBDAddressMutex);
5286 g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
5287 oc_mutex_unlock(g_bleServerBDAddressMutex);
5289 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5293 * Class: org_iotivity_ca_jar_caleinterface
5294 * Method: CALeGattDescriptorWriteCallback
5295 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
5297 JNIEXPORT void JNICALL
5298 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
5302 OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status);
5303 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5304 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5305 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5307 if (GATT_SUCCESS != status) // error
5312 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5318 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5321 CACheckJNIException(env);
5325 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
5326 STATE_SERVICE_CONNECTED,
5328 g_deviceStateListMutex);
5329 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5330 if (CA_STATUS_OK != res)
5332 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5336 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
5337 if (CA_STATUS_OK != res)
5339 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
5347 CALEClientSendFinish(env, gatt);
5351 JNIEXPORT void JNICALL
5352 Java_org_iotivity_ca_CaLeClientInterface_caLeGattMtuChangedCallback(JNIEnv *env,
5358 OIC_LOG_V(INFO, TAG, "caLeGattMtuChangedCallback - status %d, "
5359 "mtu[%d-including Header size 3 byte]", status, mtu);
5363 if (0 == status || 133 == status)
5367 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
5368 if (CA_STATUS_OK != res)
5370 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
5375 OIC_LOG(INFO, TAG, "mtu nego is done");
5376 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5379 CALEClientSendFinish(env, gatt);
5383 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5386 CACheckJNIException(env);
5387 (*env)->DeleteLocalRef(env, jni_address);
5388 CALEClientSendFinish(env, gatt);
5393 CAResult_t res = CALESetMtuSize(address, mtu - CA_BLE_MTU_HEADER_SIZE,
5394 g_deviceStateList, g_deviceStateListMutex);
5395 if (CA_STATUS_OK != res)
5397 OIC_LOG(ERROR, TAG, "CALESetMtuSize has failed");
5400 res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5401 STATE_SEND_MTU_NEGO_SUCCESS,
5403 g_deviceStateListMutex);
5404 if (CA_STATUS_OK != res)
5406 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5408 CALEClientUpdateSendCnt(env);
5409 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5410 (*env)->DeleteLocalRef(env, jni_address);