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"
33 #include "uarraylist.h"
35 #include "oic_malloc.h"
36 #include "oic_string.h"
37 #include "cathreadpool.h" /* for thread pool */
39 #include "uarraylist.h"
40 #include "org_iotivity_ca_CaLeClientInterface.h"
41 #include "caleclient_utils.h"
43 //#define TAG PCF("OIC_CA_LE_CLIENT")
44 #define TAG BLE_CLIENT_TAG
46 #define MICROSECS_PER_SEC 1000000
47 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
48 #define WAIT_TIME_SCAN_INTERVAL_DEFAULT 10
49 #define WAIT_TIME_SCANNED_CHECKING 30
51 #define GATT_CONNECTION_PRIORITY_BALANCED 0
52 #define GATT_FAILURE 257
53 #define GATT_INSUFFICIENT_AUTHENTICATION 5
54 #define GATT_INSUFFICIENT_ENCRYPTION 15
55 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
56 #define GATT_INVALID_OFFSET 7
57 #define GATT_READ_NOT_PERMITTED 2
58 #define GATT_REQUEST_NOT_SUPPORTED 6
59 #define GATT_WRITE_NOT_PERMITTED 3
62 #define BLE_SCAN_API_LEVEL (21) //(21)
63 #define BLE_MIN_API_LEVEL (18)
65 #define MANUFACTURE_ID 117
67 static ca_thread_pool_t g_threadPoolHandle = NULL;
70 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
71 static u_arraylist_t *g_gattObjectList = NULL;
73 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
74 static jobject g_context = NULL;
75 static jobjectArray g_uuidList = NULL;
77 // it will be prevent to start send logic when adapter has stopped.
78 static bool g_isStartedLEClient = false;
80 static uint32_t g_targetCnt = 0;
81 static uint32_t g_currentSentCnt = 0;
82 static bool g_isFinishedSendData = false;
83 static oc_mutex g_SendFinishMutex = NULL;
84 static oc_mutex g_threadMutex = NULL;
85 static oc_cond g_threadCond = NULL;
86 static oc_cond g_deviceDescCond = NULL;
88 static oc_mutex g_threadSendMutex = NULL;
90 static oc_mutex g_deviceListMutex = NULL;
91 static oc_mutex g_gattObjectMutex = NULL;
93 static oc_mutex g_deviceScanRetryDelayMutex = NULL;
94 static oc_cond g_deviceScanRetryDelayCond = NULL;
96 static oc_mutex g_threadScanIntervalMutex = NULL;
97 static oc_cond g_threadScanIntervalCond = NULL;
99 static oc_mutex g_threadSendStateMutex = NULL;
100 static oc_mutex g_setValueMutex = NULL;
102 static int32_t g_scanIntervalTime = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
103 static int32_t g_scanIntervalTimePrev = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
104 static int32_t g_intervalCount = 0;
105 static bool g_isWorkingScanThread = false;
106 static CALEScanState_t g_curScanningStep = BLE_SCAN_NONE;
107 static CALEScanState_t g_nextScanningStep = BLE_SCAN_ENABLE;
109 static int32_t g_jniIntSdk = -1;
111 static bool g_setHighQoS = true;
112 static bool g_setFullScanFlag = false;
113 jclass g_LEInterface = NULL;
114 static int g_manufactureDataCount = 0;
115 static int g_serviceUuidCount = 0;
117 // List of Service UUIDs
118 static u_arraylist_t* g_serviceUuidList = NULL;
120 // List of Manufacture Data
121 static u_arraylist_t* g_manufactureDataList = NULL;
123 //Variables are defined as extern in other file so using it as non-static here
124 u_arraylist_t *g_deviceStateList = NULL;
125 oc_mutex g_deviceStateListMutex = NULL;
127 oc_mutex g_threadWriteCharacteristicMutex = NULL;
128 oc_cond g_threadWriteCharacteristicCond = NULL;
129 oc_mutex g_bleServerBDAddressMutex = NULL;
131 CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
133 jobject g_leScanCallback = NULL;
134 jobject g_leGattCallback = NULL;
136 bool g_isSignalSetFlag = false;
138 jbyteArray g_sendBuffer = NULL;
140 CABLEErrorHandleCallback g_clientErrorCallback = NULL;
143 * check if retry logic for connection routine has to be stopped or not.
144 * in case of error value including this method, connection routine has to be stopped.
145 * since there is no retry logic for this error reason in this client.
146 * @param state constant value of bluetoothgatt.
147 * @return true - waiting for background connection in BT platform.
148 * false - connection routine has to be stopped.
150 bool CALECheckConnectionStateValue(jint state)
154 case GATT_CONNECTION_PRIORITY_BALANCED:
156 case GATT_INSUFFICIENT_AUTHENTICATION:
157 case GATT_INSUFFICIENT_ENCRYPTION:
158 case GATT_INVALID_ATTRIBUTE_LENGTH:
159 case GATT_INVALID_OFFSET:
160 case GATT_READ_NOT_PERMITTED:
161 case GATT_REQUEST_NOT_SUPPORTED:
162 case GATT_WRITE_NOT_PERMITTED:
170 * delete global reference for g_sendBuffer
171 * @param[in] env JNI interface pointer.
173 static void CALEDeleteSendBuffer(JNIEnv *env)
175 OIC_LOG(INFO, TAG, "CALEDeleteSendBuffer");
176 oc_mutex_lock(g_setValueMutex);
179 OIC_LOG(INFO, TAG, "delete send buffer");
180 (*env)->DeleteGlobalRef(env, g_sendBuffer);
183 oc_mutex_unlock(g_setValueMutex);
186 void CALEClientSetScanInterval(int32_t intervalTime, int32_t workingCount,
187 CALEScanState_t nextScanningStep)
189 OIC_LOG_V(DEBUG, TAG, "CALEClientSetScanInterval : %d -> %d, next scan state will be %d",
190 g_scanIntervalTime, intervalTime, nextScanningStep);
192 // previous time should be stored.
193 if (0 < workingCount)
195 g_scanIntervalTimePrev = g_scanIntervalTime;
197 g_scanIntervalTime = intervalTime;
198 g_intervalCount = workingCount;
199 g_nextScanningStep = nextScanningStep;
202 void CALERestartScanWithInterval(int32_t intervalTime, int32_t workingCount,
203 CALEScanState_t nextScanningStep)
205 if (intervalTime == g_scanIntervalTime
206 && workingCount == g_intervalCount
207 && nextScanningStep == g_nextScanningStep)
209 OIC_LOG(DEBUG, TAG, "setting duplicate interval time");
213 oc_mutex_lock(g_threadScanIntervalMutex);
214 CALEClientSetScanInterval(intervalTime, workingCount, nextScanningStep);
215 oc_cond_signal(g_threadScanIntervalCond);
216 oc_mutex_unlock(g_threadScanIntervalMutex);
219 static void CALEScanThread(void* object)
224 bool isAttached = false;
225 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
229 oc_mutex_lock(g_threadScanIntervalMutex);
230 while(g_isWorkingScanThread)
232 OIC_LOG(DEBUG, TAG, "scan waiting time out");
233 if (BLE_SCAN_ENABLE == g_curScanningStep)
236 CAResult_t ret = CALEClientStopScan();
237 if (CA_STATUS_OK != ret)
239 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
242 else if (BLE_SCAN_DISABLE == g_curScanningStep)
245 CAResult_t ret = CALEClientStartScan();
246 if (CA_STATUS_OK != ret)
248 OIC_LOG(INFO, TAG, "CALEClientStartScan has failed");
253 OIC_LOG(DEBUG, TAG, "scan thread is started");
255 CALEClientSetScanInterval(0, 0, BLE_SCAN_DISABLE);
258 OIC_LOG_V(DEBUG, TAG, "wait for Scan Interval Time during %d sec", g_scanIntervalTime);
259 if (OC_WAIT_SUCCESS == oc_cond_wait_for(g_threadScanIntervalCond,
260 g_threadScanIntervalMutex,
261 g_scanIntervalTime * MICROSECS_PER_SEC))
263 // called signal scan thread will be terminated
264 OIC_LOG(DEBUG, TAG, "signal scanInterval waiting");
265 if (BLE_SCAN_DISABLE == g_nextScanningStep)
267 g_curScanningStep = BLE_SCAN_ENABLE;
271 g_curScanningStep = BLE_SCAN_DISABLE;
276 if (BLE_SCAN_ENABLE == g_curScanningStep)
278 if (g_intervalCount > 0)
280 if (g_intervalCount == 1)
282 OIC_LOG(DEBUG, TAG, "reset default time");
283 CALEClientSetScanInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
286 OIC_LOG_V(DEBUG, TAG, "interval count : %d", g_intervalCount);
288 g_curScanningStep = BLE_SCAN_DISABLE;
292 g_curScanningStep = BLE_SCAN_ENABLE;
296 oc_mutex_unlock(g_threadScanIntervalMutex);
300 (*g_jvm)->DetachCurrentThread(g_jvm);
304 CAResult_t CALEClientStartScanWithInterval()
306 if (g_isWorkingScanThread)
308 OIC_LOG(DEBUG, TAG, "scan interval logic already running");
312 // initialize scan flags
313 g_curScanningStep = BLE_SCAN_NONE;
314 g_isWorkingScanThread = true;
316 g_scanIntervalTime = g_scanIntervalTimePrev;
317 g_nextScanningStep = BLE_SCAN_ENABLE;
319 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEScanThread, NULL, NULL))
321 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
322 g_isWorkingScanThread = false;
323 return CA_STATUS_FAILED;
329 void CALEClientStopScanWithInterval()
331 g_isWorkingScanThread = false;
332 oc_cond_signal(g_threadScanIntervalCond);
336 void CALEClientJniInit()
338 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
339 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
342 void CALEClientJNISetContext()
344 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
345 g_context = (jobject) CANativeJNIGetContext();
348 CAResult_t CALECreateJniInterfaceObject()
350 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
352 VERIFY_NON_NULL_RET(g_context, TAG, "g_context is null", CA_STATUS_FAILED);
353 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
356 bool isAttached = false;
357 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
358 return CA_STATUS_FAILED;
361 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
362 "getApplicationContext",
363 "()Landroid/content/Context;");
365 if (!mid_getApplicationContext)
367 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
368 return CA_STATUS_FAILED;
371 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
372 mid_getApplicationContext);
373 if (!jApplicationContext)
375 OIC_LOG(ERROR, TAG, "Could not get application context");
379 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
380 if (!jni_LEInterface)
382 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
385 g_LEInterface = (jclass)((*env)->NewGlobalRef(env, jni_LEInterface));
387 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
388 "(Landroid/content/Context;)V");
389 if (!LeInterfaceConstructorMethod)
391 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
395 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
396 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
400 (*g_jvm)->DetachCurrentThread(g_jvm);
406 CACheckJNIException(env);
409 (*g_jvm)->DetachCurrentThread(g_jvm);
412 return CA_STATUS_FAILED;
415 void CALEClientAddUuid(char* uuid, int uuid_type)
417 OIC_LOG(DEBUG, TAG, "CALEClientAddUuid");
418 VERIFY_NON_NULL_VOID(uuid, TAG, "uuid is null");
420 if (uuid_type == CA_LE_TYPE_CUSTOM_UUID)
422 if (g_manufactureDataCount == 0)
424 g_manufactureDataList = u_arraylist_create();
425 OIC_LOG(DEBUG, TAG, "List of manufacture data created");
427 for (int i = 0; i < g_manufactureDataCount; i++)
429 char *str = u_arraylist_get(g_manufactureDataList, i);
430 if (!strcmp(uuid, str))
432 OIC_LOG(DEBUG, TAG, "UUID already set before");
436 g_manufactureDataCount++;
437 bool result = u_arraylist_add(g_manufactureDataList, uuid);
438 OIC_LOG_V(DEBUG, TAG, "Adding manufacture data: %s", u_arraylist_get(g_manufactureDataList, g_manufactureDataCount - 1));
440 else //uuid_type == CA_LE_TYPE_SERVICE_UUID
442 if (g_serviceUuidCount == 0)
444 g_serviceUuidList = u_arraylist_create();
445 OIC_LOG(DEBUG, TAG, "List of service uuid created");
447 for (int i = 0; i < g_serviceUuidCount; i++)
449 char *str = u_arraylist_get(g_serviceUuidList, i);
450 if (!strcmp(uuid, str))
452 OIC_LOG(DEBUG, TAG, "UUID already set before");
456 g_serviceUuidCount++;
457 bool result = u_arraylist_add(g_serviceUuidList, uuid);
458 OIC_LOG_V(DEBUG, TAG, "Adding service UUID: %s", u_arraylist_get(g_serviceUuidList, g_serviceUuidCount - 1));
462 CAResult_t CALEClientInitialize()
464 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
467 CALEClientAddUuid(OIC_GATT_SERVICE_UUID, CA_LE_TYPE_SERVICE_UUID);
468 CALEClientAddUuid(OIC_GATT_CUSTOM_UUID, CA_LE_TYPE_CUSTOM_UUID);
469 CALEClientAddUuid(OIC_GATT_CUSTOM_UUID2, CA_LE_TYPE_CUSTOM_UUID);
470 CALEClientAddUuid(OIC_GATT_CUSTOM_UUID3, CA_LE_TYPE_CUSTOM_UUID);
472 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
475 bool isAttached = false;
476 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
477 return CA_STATUS_FAILED;
480 g_jniIntSdk = CALEGetBuildVersion(env);
481 if (g_jniIntSdk < BLE_MIN_API_LEVEL)
483 OIC_LOG(ERROR, TAG, "it is not supported");
487 (*g_jvm)->DetachCurrentThread(g_jvm);
489 return CA_STATUS_FAILED;
492 CAResult_t ret = CALEClientInitGattMutexVaraibles();
493 if (CA_STATUS_OK != ret)
495 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
496 CALEClientTerminateGattMutexVariables();
500 (*g_jvm)->DetachCurrentThread(g_jvm);
506 g_deviceDescCond = oc_cond_new();
508 // init mutex for send logic
509 g_threadCond = oc_cond_new();
510 g_threadWriteCharacteristicCond = oc_cond_new();
511 g_deviceScanRetryDelayCond = oc_cond_new();
512 g_threadScanIntervalCond = oc_cond_new();
514 CALEClientCreateDeviceList();
515 CALEClientJNISetContext();
517 ret = CALEClientCreateUUIDList();
518 if (CA_STATUS_OK != ret)
520 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
524 (*g_jvm)->DetachCurrentThread(g_jvm);
530 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
531 if (CA_STATUS_OK != ret)
533 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
537 (*g_jvm)->DetachCurrentThread(g_jvm);
542 g_isStartedLEClient = true;
546 (*g_jvm)->DetachCurrentThread(g_jvm);
552 void CALEClientTerminate()
554 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
556 VERIFY_NON_NULL_VOID(g_jvm, TAG, "g_jvm is null");
559 bool isAttached = false;
560 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
565 CAResult_t ret = CALEClientStopScan();
566 if (CA_STATUS_OK != ret)
568 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
571 if (g_leScanCallback)
573 (*env)->DeleteGlobalRef(env, g_leScanCallback);
574 g_leScanCallback = NULL;
577 if (g_leGattCallback)
579 (*env)->DeleteGlobalRef(env, g_leGattCallback);
580 g_leGattCallback = NULL;
585 (*env)->DeleteGlobalRef(env, g_LEInterface);
586 g_LEInterface = NULL;
589 u_arraylist_free(&g_serviceUuidList);
590 u_arraylist_free(&g_manufactureDataList);
592 CALEDeleteSendBuffer(env);
596 (*env)->DeleteGlobalRef(env, g_uuidList);
600 ret = CALERemoveAllDeviceState(g_deviceStateList,
601 g_deviceStateListMutex);
602 if (CA_STATUS_OK != ret)
604 OIC_LOG(ERROR, TAG, "CALERemoveAllDeviceState has failed");
607 oc_mutex_lock(g_deviceStateListMutex);
608 OICFree(g_deviceStateList);
609 g_deviceStateList = NULL;
610 oc_mutex_unlock(g_deviceStateListMutex);
612 ret = CALEClientRemoveAllScanDevices(env);
613 if (CA_STATUS_OK != ret)
615 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
618 ret = CALEClientRemoveAllGattObjs(env);
619 if (CA_STATUS_OK != ret)
621 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
624 CALEClientSetSendFinishFlag(true);
626 CALEClientTerminateGattMutexVariables();
627 CALEClientDestroyJniInterface();
629 oc_cond_free(g_deviceDescCond);
630 oc_cond_free(g_threadCond);
631 oc_cond_free(g_threadWriteCharacteristicCond);
632 oc_cond_free(g_deviceScanRetryDelayCond);
633 oc_cond_free(g_threadScanIntervalCond);
635 g_deviceDescCond = NULL;
637 g_threadWriteCharacteristicCond = NULL;
638 g_deviceScanRetryDelayCond = NULL;
639 g_threadScanIntervalCond = NULL;
641 g_isSignalSetFlag = false;
644 CALEClientStopScanWithInterval();
648 (*g_jvm)->DetachCurrentThread(g_jvm);
652 jobject CALEClientHiddenConnectGatt(jobject btDevice, const char* address, jboolean autoconnect)
654 OIC_LOG(INFO, TAG, "IN - CALEClientHiddenConnectGatt");
656 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", NULL);
659 bool isAttached = false;
660 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
664 jstring jni_address = (*env)->NewStringUTF(env, address);
665 jmethodID jni_connectGattHiddenMethod = (*env)->GetStaticMethodID(env, g_LEInterface,
666 "connectGattforHidden",
667 "(Landroid/bluetooth/BluetoothDevice;"
668 "Ljava/lang/String;Z)"
669 "Landroid/bluetooth/BluetoothGatt;");
670 if (!jni_connectGattHiddenMethod)
672 OIC_LOG(ERROR, TAG, "Could not get jni_connectGatt Hidden Method");
676 jobject gatt = (*env)->CallStaticObjectMethod(env, g_LEInterface,
677 jni_connectGattHiddenMethod,
678 btDevice, jni_address, autoconnect);
680 if (CACheckJNIException(env))
682 OIC_LOG(ERROR, TAG, "connectGattforHidden has failed");
686 OIC_LOG(INFO, TAG, "OUT - CALEClientHiddenConnectGatt");
690 (*g_jvm)->DetachCurrentThread(g_jvm);
696 CACheckJNIException(env);
701 (*g_jvm)->DetachCurrentThread(g_jvm);
707 CAResult_t CALEClientDestroyJniInterface()
709 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
711 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
714 bool isAttached = false;
715 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
716 return CA_STATUS_FAILED;
719 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
720 if (!jni_LeInterface)
722 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
726 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
727 "destroyLeInterface",
729 if (!jni_InterfaceDestroyMethod)
731 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
735 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
737 if (CACheckJNIException(env))
739 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
743 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
747 (*g_jvm)->DetachCurrentThread(g_jvm);
753 CACheckJNIException(env);
758 (*g_jvm)->DetachCurrentThread(g_jvm);
761 return CA_STATUS_FAILED;
764 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
766 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
767 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
771 CAResult_t res = CALEClientDisconnect(env, gatt);
772 if (CA_STATUS_OK != res)
774 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
777 CALEClientUpdateSendCnt(env);
780 CAResult_t CALEClientSendNegotiationMessage(const char* address)
782 VERIFY_NON_NULL(address, TAG, "address is null");
784 return CALEClientSendUnicastMessageImpl(address, NULL, 0);
787 CAResult_t CALEClientSendUnicastMessage(const char* address,
789 const uint32_t dataLen)
791 VERIFY_NON_NULL(address, TAG, "address is null");
792 VERIFY_NON_NULL(data, TAG, "data is null");
794 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
797 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
798 const uint32_t dataLen)
800 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
801 VERIFY_NON_NULL(data, TAG, "data is null");
803 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
806 bool isAttached = false;
807 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
808 return CA_STATUS_FAILED;
811 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
812 if (CA_STATUS_OK != ret)
814 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
819 (*g_jvm)->DetachCurrentThread(g_jvm);
825 CAResult_t CALEClientStartUnicastServer(const char* address)
830 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
832 return CA_NOT_SUPPORTED;
835 CAResult_t CALEClientStartMulticastServer()
837 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
839 return CA_NOT_SUPPORTED;
842 void CALEClientStopUnicastServer()
844 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
847 void CALEClientStopMulticastServer()
849 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
852 void CALEClientSetCallback(CAPacketReceiveCallback callback)
854 g_packetReceiveCallback = callback;
857 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
859 g_clientErrorCallback = callback;
862 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
864 VERIFY_NON_NULL(env, TAG, "env");
868 OIC_LOG(ERROR, TAG, "g_deviceList is not available");
869 return CA_STATUS_FAILED;
872 if (0 == u_arraylist_length(g_deviceList) // multicast
873 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
875 // Wait for LE peripherals to be discovered.
877 // Number of times to wait for discovery to complete.
878 static size_t const RETRIES = 5;
880 static uint64_t const TIMEOUT =
881 2 * MICROSECS_PER_SEC; // Microseconds
883 // set scan interval and start scan
884 CALERestartScanWithInterval(WAIT_TIME_SCANNED_CHECKING, 1, BLE_SCAN_ENABLE);
886 bool devicesDiscovered = false;
887 for (size_t i = 0; i < RETRIES; ++i)
889 OIC_LOG(DEBUG, TAG, "waiting for target device");
890 if (oc_cond_wait_for(g_deviceDescCond,
892 TIMEOUT) == OC_WAIT_SUCCESS)
894 OIC_LOG(DEBUG, TAG, "time out");
895 oc_mutex_lock(g_deviceListMutex);
896 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
897 oc_mutex_unlock(g_deviceListMutex);
899 if (0 < scannedDeviceLen)
901 if (!address // multicast
902 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
904 devicesDiscovered = true;
911 OIC_LOG(INFO, TAG, "waiting..");
913 oc_mutex_lock(g_deviceScanRetryDelayMutex);
914 if (oc_cond_wait_for(g_deviceScanRetryDelayCond,
915 g_deviceScanRetryDelayMutex,
916 MICROSECS_PER_SEC) == OC_WAIT_SUCCESS)
918 OIC_LOG(INFO, TAG, "finish to waiting for target device");
919 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
922 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
925 // checking whether a target device is found while waiting for time-out.
926 if (CALEClientIsDeviceInScanDeviceList(env, address))
928 devicesDiscovered = true;
937 // reset scan interval time after checking scanned devices
938 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
940 // time out for scanning devices
941 if (!devicesDiscovered)
943 return CA_STATUS_FAILED;
948 OIC_LOG(DEBUG, TAG, "there is a target device in the scanned devices");
955 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
956 const uint32_t dataLen)
958 OIC_LOG(INFO, TAG, "CALEClientSendUnicastMessageImpl in");
959 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
961 VERIFY_NON_NULL(address, TAG, "address is null");
963 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
966 bool isAttached = false;
967 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
968 return CA_STATUS_FAILED;
971 oc_mutex_lock(g_threadSendMutex);
973 CALEClientSetSendFinishFlag(false);
975 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
976 if (CA_STATUS_OK != ret)
978 OIC_LOG(INFO, TAG, "there is no scanned device");
982 if (g_context && g_deviceList)
984 uint32_t length = u_arraylist_length(g_deviceList);
985 for (uint32_t index = 0; index < length; index++)
987 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
990 OIC_LOG(ERROR, TAG, "jarrayObj is null");
994 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
997 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1001 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1004 OIC_LOG(ERROR, TAG, "setAddress is null");
1005 CACheckJNIException(env);
1009 if (!strcasecmp(setAddress, address))
1011 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1012 (*env)->DeleteLocalRef(env, jni_setAddress);
1014 CALEDeleteSendBuffer(env);
1016 if (data && dataLen > 0)
1018 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1019 CACheckJNIException(env);
1020 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1021 CACheckJNIException(env);
1022 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1023 CACheckJNIException(env);
1026 // Target device to send message is just one.
1029 ret = CALEClientSendData(env, jarrayObj);
1030 if (CA_STATUS_OK != ret)
1032 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
1036 OIC_LOG(INFO, TAG, "wake up");
1039 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1040 (*env)->DeleteLocalRef(env, jni_setAddress);
1044 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
1046 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1047 // if there is no connection state.
1048 oc_mutex_lock(g_threadMutex);
1049 if (!g_isFinishedSendData)
1051 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1052 oc_cond_wait(g_threadCond, g_threadMutex);
1053 OIC_LOG(DEBUG, TAG, "connection / send is finished for unicast");
1055 oc_mutex_unlock(g_threadMutex);
1059 (*g_jvm)->DetachCurrentThread(g_jvm);
1062 oc_mutex_unlock(g_threadSendMutex);
1063 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
1064 if (CALEIsValidState(address, CA_LE_SEND_STATE,
1067 g_deviceStateListMutex))
1069 OIC_LOG(INFO, TAG, "send success");
1072 else if (CALEIsValidState(address, CA_LE_SEND_STATE,
1073 STATE_SEND_MTU_NEGO_SUCCESS,
1075 g_deviceStateListMutex))
1077 OIC_LOG(INFO, TAG, "mtu nego success");
1082 OIC_LOG(ERROR, TAG, "send failure");
1083 ret = CA_SEND_FAILED;
1087 CAResult_t resetRet = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
1090 g_deviceStateListMutex);
1091 if (CA_STATUS_OK != resetRet)
1093 OIC_LOG_V(ERROR, TAG, "CALEUpdateDeviceState has failed (%d)", resetRet);
1094 ret = CA_SEND_FAILED;
1103 (*g_jvm)->DetachCurrentThread(g_jvm);
1106 oc_mutex_unlock(g_threadSendMutex);
1107 return CA_SEND_FAILED;
1110 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
1111 const uint32_t dataLen)
1113 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
1114 VERIFY_NON_NULL(data, TAG, "data is null");
1115 VERIFY_NON_NULL(env, TAG, "env is null");
1119 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1120 return CA_STATUS_FAILED;
1123 oc_mutex_lock(g_threadSendMutex);
1125 CALEClientSetSendFinishFlag(false);
1127 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1128 CALEDeleteSendBuffer(env);
1130 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
1131 if (CA_STATUS_OK != res)
1133 OIC_LOG(INFO, TAG, "there is no scanned device");
1137 uint32_t length = u_arraylist_length(g_deviceList);
1138 g_targetCnt = length;
1140 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1141 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1142 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1144 for (uint32_t index = 0; index < length; index++)
1146 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1149 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
1153 res = CALEClientSendData(env, jarrayObj);
1154 if (res != CA_STATUS_OK)
1156 OIC_LOG(ERROR, TAG, "BT device - send has failed");
1160 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1162 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1163 oc_mutex_lock(g_threadMutex);
1164 if (!g_isFinishedSendData)
1166 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1167 oc_cond_wait(g_threadCond, g_threadMutex);
1168 OIC_LOG(DEBUG, TAG, "connection / send is finished for multicast");
1170 oc_mutex_unlock(g_threadMutex);
1171 oc_mutex_unlock(g_threadSendMutex);
1172 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1173 return CA_STATUS_OK;
1176 oc_mutex_unlock(g_threadSendMutex);
1177 OIC_LOG(ERROR, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1178 return CA_SEND_FAILED;
1181 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1183 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1184 VERIFY_NON_NULL(device, TAG, "device is null");
1185 VERIFY_NON_NULL(env, TAG, "env is null");
1187 // get BLE address from bluetooth device object.
1188 char* address = NULL;
1189 CALEState_t* state = NULL;
1190 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1193 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1194 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1197 OIC_LOG(ERROR, TAG, "address is not available");
1198 CACheckJNIException(env);
1199 return CA_STATUS_FAILED;
1201 oc_mutex_lock(g_deviceStateListMutex);
1202 state = CALEGetStateInfo(address, g_deviceStateList);
1203 oc_mutex_unlock(g_deviceStateListMutex);
1206 // Since disconnect event can be caused from BT stack while connection step is running.
1207 // DeviceState has to have current status for processing send failure.
1208 OIC_LOG(INFO, TAG, "set STATE_SEND_PREPARING");
1209 CAResult_t res = CALEClientUpdateDeviceStateWithBtDevice(env, device,
1211 STATE_SEND_PREPARING);
1212 if (CA_STATUS_OK != res)
1214 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceStateWithBtDevice has failed");
1217 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1219 return CA_STATUS_FAILED;
1224 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1226 // cancel previous connection request before connection
1227 // if there is gatt object in g_gattObjectList.
1230 jobject gatt = CALEClientGetGattObjInList(env, address);
1233 CAResult_t res = CALEClientDisconnect(env, gatt);
1234 if (CA_STATUS_OK != res)
1236 OIC_LOG(INFO, TAG, "there is no gatt object");
1239 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1242 // connection request
1243 jobject newGatt = CALEClientConnect(env, device,
1245 if (NULL == newGatt)
1247 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1248 return CA_STATUS_FAILED;
1253 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1254 STATE_SERVICE_CONNECTED,
1256 g_deviceStateListMutex))
1258 OIC_LOG(INFO, TAG, "GATT has already connected");
1260 jobject gatt = CALEClientGetGattObjInList(env, address);
1263 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1264 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1265 return CA_STATUS_FAILED;
1268 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1269 if (CA_STATUS_OK != ret)
1271 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1272 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1275 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1277 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1280 g_deviceStateListMutex))
1282 OIC_LOG(INFO, TAG, "service connecting...");
1284 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1287 g_deviceStateListMutex))
1289 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1291 // cancel previous connection request before connection
1292 // if there is gatt object in g_gattObjectList.
1295 jobject gatt = CALEClientGetGattObjInList(env, address);
1298 CAResult_t res = CALEClientDisconnect(env, gatt);
1299 if (CA_STATUS_OK != res)
1301 OIC_LOG(INFO, TAG, "there is no gatt object");
1304 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1307 OIC_LOG(DEBUG, TAG, "start to connect LE");
1308 jobject gatt = CALEClientConnect(env, device,
1309 CALEGetFlagFromState(env, jni_address,
1310 CA_LE_AUTO_CONNECT_FLAG,
1312 g_deviceStateListMutex));
1316 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1317 return CA_STATUS_FAILED;
1322 return CA_STATUS_OK;
1325 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1327 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1328 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1330 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1331 "()Landroid/bluetooth/BluetoothDevice;");
1332 if (!jni_mid_getDevice)
1334 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1338 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1339 if (!jni_obj_device)
1341 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1342 CACheckJNIException(env);
1346 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1349 OIC_LOG(ERROR, TAG, "jni_address is null");
1350 CACheckJNIException(env);
1360 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1363 OIC_LOG(DEBUG, TAG, "Gatt Close");
1364 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1365 VERIFY_NON_NULL(env, TAG, "env is null");
1367 // get BluetoothGatt method
1368 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1369 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1370 if (!jni_mid_closeGatt)
1372 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1373 return CA_STATUS_OK;
1376 // call disconnect gatt method
1377 OIC_LOG(DEBUG, TAG, "request to close GATT");
1378 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1380 if (CACheckJNIException(env))
1382 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1383 return CA_STATUS_FAILED;
1386 return CA_STATUS_OK;
1389 CAResult_t CALEClientStartScan()
1391 if (!g_isStartedLEClient)
1393 OIC_LOG(ERROR, TAG, "LE client is not started");
1394 return CA_STATUS_FAILED;
1397 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
1400 bool isAttached = false;
1401 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
1402 return CA_STATUS_FAILED;
1405 if(g_jniIntSdk < BLE_SCAN_API_LEVEL)
1407 g_setFullScanFlag = true;
1410 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1412 CAResult_t ret = CA_STATUS_OK;
1413 // scan gatt server with UUID
1414 if (g_leScanCallback && g_uuidList)
1416 if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
1418 if (!g_setFullScanFlag)
1420 //new uuid scan with callback
1421 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 will be called");
1422 ret = CALEClientStartScanWithUUIDImplForV21(env, g_uuidList, g_leScanCallback);
1426 //new full scan with callback
1427 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 will be called");
1428 ret = CALEClientStartScanImplForV21(env, g_leScanCallback);
1433 if (!g_setFullScanFlag)
1435 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl will be called");
1436 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1440 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl will be called");
1441 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1445 if (CA_STATUS_OK != ret)
1447 if (CA_ADAPTER_NOT_ENABLED == ret)
1449 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1453 OIC_LOG(ERROR, TAG, "start scan has failed");
1460 (*g_jvm)->DetachCurrentThread(g_jvm);
1466 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1468 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl IN");
1469 VERIFY_NON_NULL(callback, TAG, "callback is null");
1470 VERIFY_NON_NULL(env, TAG, "env is null");
1472 if (!CALEIsEnableBTAdapter(env))
1474 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1475 return CA_ADAPTER_NOT_ENABLED;
1478 // get default bt adapter class
1479 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1480 if (!jni_cid_BTAdapter)
1482 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1483 CACheckJNIException(env);
1484 return CA_STATUS_FAILED;
1487 // get remote bt adapter method
1488 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1489 "getDefaultAdapter",
1490 METHODID_OBJECTNONPARAM);
1491 if (!jni_mid_getDefaultAdapter)
1493 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1494 CACheckJNIException(env);
1495 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1496 return CA_STATUS_FAILED;
1499 // get start le scan method
1500 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1501 "(Landroid/bluetooth/BluetoothAdapter$"
1502 "LeScanCallback;)Z");
1503 if (!jni_mid_startLeScan)
1505 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1506 CACheckJNIException(env);
1507 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1508 return CA_STATUS_FAILED;
1511 // gat bt adapter object
1512 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1513 jni_mid_getDefaultAdapter);
1514 if (!jni_obj_BTAdapter)
1516 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1517 CACheckJNIException(env);
1518 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1519 return CA_STATUS_FAILED;
1522 // call start le scan method
1523 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1524 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1525 jni_mid_startLeScan, callback);
1526 if (!jni_obj_startLeScan)
1528 OIC_LOG(INFO, TAG, "startLeScan has failed");
1529 CACheckJNIException(env);
1533 OIC_LOG(DEBUG, TAG, "LeScan has started");
1536 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1537 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1538 return CA_STATUS_OK;
1541 CAResult_t CALEClientStartScanImplForV21(JNIEnv *env, jobject callback)
1543 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 IN");
1544 VERIFY_NON_NULL(callback, TAG, "callback is null");
1545 VERIFY_NON_NULL(env, TAG, "env is null");
1547 if (!CALEIsEnableBTAdapter(env))
1549 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1550 return CA_ADAPTER_NOT_ENABLED;
1553 CAResult_t res = CA_STATUS_FAILED;
1554 // get default bt adapter class
1555 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1556 if (!jni_cid_BTAdapter)
1558 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1559 CACheckJNIException(env);
1560 return CA_STATUS_FAILED;
1563 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1564 "getDefaultAdapter",
1565 "()Landroid/bluetooth/"
1566 "BluetoothAdapter;");
1567 if (!jni_mid_getDefaultAdapter)
1569 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1570 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1571 return CA_STATUS_FAILED;
1574 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1575 jni_mid_getDefaultAdapter);
1576 if (!jni_obj_BTAdapter)
1578 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1579 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1580 return CA_STATUS_FAILED;
1583 // get bluetoothLeScanner class
1584 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
1585 if (!jni_cid_leScanner)
1587 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
1588 CACheckJNIException(env);
1589 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1590 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1591 return CA_STATUS_FAILED;
1594 // get remote bt adapter method
1595 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1596 "getBluetoothLeScanner",
1597 "()Landroid/bluetooth/"
1598 "le/BluetoothLeScanner;");
1599 if (!jni_mid_getBluetoothLeScanner)
1601 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
1602 CACheckJNIException(env);
1606 // get startScan(ScanCallback callback) method
1607 jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner, "startScan",
1608 "(Landroid/bluetooth/le/ScanCallback;)V");
1609 if (!jni_mid_startScan)
1611 OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
1612 CACheckJNIException(env);
1616 // gat le scanner object
1617 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
1618 jni_mid_getBluetoothLeScanner);
1619 if (!jni_obj_leScanner)
1621 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
1622 CACheckJNIException(env);
1626 // call startScan method
1627 OIC_LOG(INFO, TAG, "CALL API - startScan(for level21)");
1628 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, callback);
1629 if (CACheckJNIException(env))
1631 OIC_LOG(INFO, TAG, "startScan has failed");
1632 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
1636 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
1639 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1640 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1641 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1645 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1647 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl IN");
1648 VERIFY_NON_NULL(callback, TAG, "callback is null");
1649 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1650 VERIFY_NON_NULL(env, TAG, "env is null");
1652 if (!CALEIsEnableBTAdapter(env))
1654 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1655 return CA_ADAPTER_NOT_ENABLED;
1658 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1659 if (!jni_cid_BTAdapter)
1661 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1662 CACheckJNIException(env);
1663 return CA_STATUS_FAILED;
1666 // get remote bt adapter method
1667 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1668 "getDefaultAdapter",
1669 METHODID_OBJECTNONPARAM);
1670 if (!jni_mid_getDefaultAdapter)
1672 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1673 CACheckJNIException(env);
1674 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1675 return CA_STATUS_FAILED;
1678 // get start le scan method
1679 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1680 "([Ljava/util/UUID;Landroid/bluetooth/"
1681 "BluetoothAdapter$LeScanCallback;)Z");
1682 if (!jni_mid_startLeScan)
1684 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1685 CACheckJNIException(env);
1686 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1687 return CA_STATUS_FAILED;
1690 // get bt adapter object
1691 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1692 jni_mid_getDefaultAdapter);
1693 if (!jni_obj_BTAdapter)
1695 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1696 CACheckJNIException(env);
1697 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1698 return CA_STATUS_FAILED;
1701 // call start le scan method
1702 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1703 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1704 jni_mid_startLeScan, uuids, callback);
1705 if (!jni_obj_startLeScan)
1707 OIC_LOG(INFO, TAG, "startLeScan has failed");
1708 CACheckJNIException(env);
1712 OIC_LOG(DEBUG, TAG, "LeScan has started");
1715 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1716 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1717 return CA_STATUS_OK;
1720 CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids, jobject callback)
1722 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 IN");
1723 VERIFY_NON_NULL(callback, TAG, "callback is null");
1724 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1725 VERIFY_NON_NULL(env, TAG, "env is null");
1728 if (!CALEIsEnableBTAdapter(env))
1730 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1731 return CA_ADAPTER_NOT_ENABLED;
1734 // get bluetoothLeScanner class
1735 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
1736 if (!jni_cid_leScanner)
1738 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
1739 CACheckJNIException(env);
1740 return CA_STATUS_FAILED;
1743 // get startScan(with UUID) method
1744 jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner,
1747 "Landroid/bluetooth/le/ScanSettings;"
1748 "Landroid/bluetooth/le/ScanCallback;"
1750 if (!jni_mid_startScan)
1752 OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
1753 CACheckJNIException(env);
1754 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1755 return CA_STATUS_FAILED;
1757 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1759 // get scanfilter.Builder class id
1760 jclass jni_cid_scanfilterBuilder = (*env)->FindClass(env,
1761 "android/bluetooth/le/"
1762 "ScanFilter$Builder");
1763 if (!jni_cid_scanfilterBuilder)
1765 OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilder is null");
1766 CACheckJNIException(env);
1767 return CA_STATUS_FAILED;
1770 // get scanfilter.Builder(ctor) method id
1771 jmethodID jni_mid_scanfilterBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1773 if (!jni_mid_scanfilterBuilderCtor)
1775 OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilderCtor is null");
1776 CACheckJNIException(env);
1777 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1778 return CA_STATUS_FAILED;
1781 // call scanfilter.Builder()
1782 jobject jni_obj_servicescanfilterBuilder[g_serviceUuidCount];
1783 for (i = 0; i < g_serviceUuidCount; i++)
1785 jni_obj_servicescanfilterBuilder[i] = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
1786 jni_mid_scanfilterBuilderCtor);
1787 if (!jni_obj_servicescanfilterBuilder[i])
1789 OIC_LOG_V(ERROR, TAG, "scanfilter: jni_obj_servicescanfilterBuilder[%d] is null", i);
1790 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1791 for (j = 0; j < i; j++)
1792 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[j]);
1793 return CA_STATUS_FAILED;
1797 // call scanfilter.Builder()
1798 jobject jni_obj_customscanfilterBuilder[g_manufactureDataCount];
1799 for (i = 0; i < g_manufactureDataCount; i++)
1801 jni_obj_customscanfilterBuilder[i] = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
1802 jni_mid_scanfilterBuilderCtor);
1803 if (!jni_obj_customscanfilterBuilder[i])
1805 OIC_LOG_V(ERROR, TAG, "scanfilter: jni_obj_customscanfilterBuilder[%d] is null", i);
1806 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1807 for (j = 0; j < i; j++)
1808 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1809 return CA_STATUS_FAILED;
1813 // get scanfilter.Builder.setServiceUuid method id
1814 jmethodID jni_mid_setServiceUuid = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1816 "(Landroid/os/ParcelUuid;)Landroid/"
1817 "bluetooth/le/ScanFilter$Builder;");
1818 if (!jni_mid_setServiceUuid)
1820 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setServiceUuid is null");
1821 CACheckJNIException(env);
1822 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1823 for (i = 0; i < g_serviceUuidCount; i++)
1825 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[i]);
1827 for (i = 0; i < g_manufactureDataCount; i++)
1829 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[i]);
1831 return CA_STATUS_FAILED;
1834 // get scanfilter.Builder.setManufacturerData method id
1835 jmethodID jni_mid_setManufacturerData = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1836 "setManufacturerData",
1838 "bluetooth/le/ScanFilter$Builder;");
1839 if (!jni_mid_setManufacturerData)
1841 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setManufacturerData is null");
1842 CACheckJNIException(env);
1843 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1844 for (i = 0; i < g_serviceUuidCount; i++)
1846 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[i]);
1848 for (i = 0; i < g_manufactureDataCount; i++)
1850 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[i]);
1852 return CA_STATUS_FAILED;
1854 // get scanfilter.Builder.build method id
1855 jmethodID jni_mid_build_scanfilterBuilder = (*env)->GetMethodID(env,
1856 jni_cid_scanfilterBuilder,
1858 "()Landroid/bluetooth/le/"
1860 if (!jni_mid_build_scanfilterBuilder)
1862 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_build_scanfilterBuilder is null");
1863 CACheckJNIException(env);
1864 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1865 for (i = 0; i < g_serviceUuidCount; i++)
1867 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[i]);
1869 for (i = 0; i < g_manufactureDataCount; i++)
1871 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[i]);
1873 return CA_STATUS_FAILED;
1875 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1877 jobject jni_obj_parcelUuid, jni_obj_setServiceUuid;
1878 jobject jni_obj_servicescanfilter[g_serviceUuidCount];
1880 for (i = 0; i < g_serviceUuidCount; i++)
1882 // call ParcelUuid.fromSting(uuid)
1883 jni_obj_parcelUuid = CALEGetParcelUuidFromString(env, u_arraylist_get(g_serviceUuidList, i));
1884 if (!jni_obj_parcelUuid)
1886 OIC_LOG(ERROR, TAG, "scanSettings: jni_obj_parcelUuid is null");
1887 CACheckJNIException(env);
1888 for (j = i; j < g_serviceUuidCount; j++)
1890 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[j]);
1892 for (j = 0; j < g_manufactureDataCount; j++)
1894 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1896 return CA_STATUS_FAILED;
1899 // call setServiceUuid(uuid)
1900 jni_obj_setServiceUuid = (*env)->CallObjectMethod(env,
1901 jni_obj_servicescanfilterBuilder[i],
1902 jni_mid_setServiceUuid,
1903 jni_obj_parcelUuid);
1904 if (!jni_obj_setServiceUuid)
1906 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setServiceUuid is null");
1907 CACheckJNIException(env);
1908 for (j = i; j < g_serviceUuidCount; j++)
1910 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[j]);
1912 for (j = 0; j < g_manufactureDataCount; j++)
1914 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1916 (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
1917 return CA_STATUS_FAILED;
1919 (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
1920 (*env)->DeleteLocalRef(env, jni_obj_setServiceUuid);
1923 jni_obj_servicescanfilter[i] = (*env)->CallObjectMethod(env,
1924 jni_obj_servicescanfilterBuilder[i],
1925 jni_mid_build_scanfilterBuilder);
1926 if (!jni_obj_servicescanfilter[i])
1928 OIC_LOG_V(ERROR, TAG, "scanfilter: jni_obj_scanfilter[%d] is null", i);
1929 CACheckJNIException(env);
1930 for (j = i; j < g_serviceUuidCount; j++)
1932 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[j]);
1934 for (j = 0; j < g_manufactureDataCount; j++)
1936 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1938 return CA_STATUS_FAILED;
1940 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[i]);
1942 OIC_LOG_V(DEBUG, TAG, "Total %d Service UUID based scanfilter(s) created by now", i + 1);
1946 jbyteArray jni_byte_manData;
1947 jobject jni_obj_setManufacturerData;
1948 jobject jni_obj_customscanfilter[g_manufactureDataCount];
1949 // set manufactererId
1950 jni_int_manId = MANUFACTURE_ID;
1952 // set custom scanfilters
1953 for (i = 0; i < g_manufactureDataCount; i++)
1955 // call utility function to set manufacturerData
1956 jni_byte_manData = CALEGetManufacturerData(env, u_arraylist_get(g_manufactureDataList, i));
1957 if (!jni_byte_manData)
1959 OIC_LOG(ERROR, TAG, "scanSettings: jni_byte_manData is null");
1960 CACheckJNIException(env);
1961 for(j = i; j < g_manufactureDataCount; j++)
1963 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1965 return CA_STATUS_FAILED;
1969 jni_obj_setManufacturerData = (*env)->CallObjectMethod(env,
1970 jni_obj_customscanfilterBuilder[i],
1971 jni_mid_setManufacturerData,
1974 if (!jni_obj_setManufacturerData)
1976 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setManufacturerData is null");
1977 CACheckJNIException(env);
1978 for (j = i; j < g_manufactureDataCount; j++)
1980 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1982 return CA_STATUS_FAILED;
1984 (*env)->DeleteLocalRef(env, jni_byte_manData);
1985 (*env)->DeleteLocalRef(env, jni_obj_setManufacturerData);
1988 jni_obj_customscanfilter[i] = (*env)->CallObjectMethod(env,
1989 jni_obj_customscanfilterBuilder[i],
1990 jni_mid_build_scanfilterBuilder);
1991 if (!jni_obj_customscanfilter[i])
1993 OIC_LOG_V(ERROR, TAG, "scanfilter: jni_obj_customscanfilter[%d] is null", i);
1994 CACheckJNIException(env);
1995 for (j = i; j < g_manufactureDataCount; j++)
1997 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1999 return CA_STATUS_FAILED;
2001 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[i]);
2003 OIC_LOG_V(DEBUG, TAG, "Total %d manufacture data based scanfilter(s) created by now", i + 1);
2006 // get scanSettings.Builder class id
2007 jclass jni_cid_scanSettingsBuilder = (*env)->FindClass(env,
2008 "android/bluetooth/le/"
2009 "ScanSettings$Builder");
2010 if (!jni_cid_scanSettingsBuilder)
2012 OIC_LOG(ERROR, TAG, "scanSettings: jni_cid_scanSettingsBuilder is null");
2013 CACheckJNIException(env);
2014 for (j = 0; j< g_serviceUuidCount; j++)
2016 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2018 for (j = 0; j< g_manufactureDataCount; j++)
2020 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2022 return CA_STATUS_FAILED;
2025 // get scanSettings.Builder(ctor) method id
2026 jmethodID jni_mid_scanSettingsBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
2028 if (!jni_mid_scanSettingsBuilderCtor)
2030 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_scanSettingsBuilderCtor is null");
2031 CACheckJNIException(env);
2032 for (j = 0; j< g_serviceUuidCount; j++)
2034 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2036 for (j = 0; j< g_manufactureDataCount; j++)
2038 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2040 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2041 return CA_STATUS_FAILED;
2044 // get scanSettings.Builder.setScanMode method id
2045 jmethodID jni_mid_setScanMode = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
2048 "bluetooth/le/ScanSettings$Builder;");
2049 if (!jni_mid_setScanMode)
2051 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_setScanMode is null");
2052 CACheckJNIException(env);
2053 for (j = 0; j< g_serviceUuidCount; j++)
2055 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2057 for (j = 0; j< g_manufactureDataCount; j++)
2059 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2061 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2062 return CA_STATUS_FAILED;
2065 // get scanSettings.Builder.build method id
2066 jmethodID jni_mid_build_scanSettings = (*env)->GetMethodID(env,
2067 jni_cid_scanSettingsBuilder,
2069 "()Landroid/bluetooth/le/"
2071 if (!jni_mid_build_scanSettings)
2073 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_build_scanSettings is null");
2074 CACheckJNIException(env);
2075 for (j = 0; j< g_serviceUuidCount; j++)
2077 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2079 for (j = 0; j< g_manufactureDataCount; j++)
2081 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2083 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2084 return CA_STATUS_FAILED;
2087 // call scanSettings.Builder()
2088 jobject jni_obj_scanSettingBuilder = (*env)->NewObject(env, jni_cid_scanSettingsBuilder,
2089 jni_mid_scanSettingsBuilderCtor);
2090 if (!jni_obj_scanSettingBuilder)
2092 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettingBuilder is null");
2093 CACheckJNIException(env);
2094 for (j = 0; j< g_serviceUuidCount; j++)
2096 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2098 for (j = 0; j< g_manufactureDataCount; j++)
2100 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2102 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2103 return CA_STATUS_FAILED;
2105 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2107 jclass jni_cid_arrayList = (*env)->FindClass(env, "java/util/ArrayList");
2108 if (!jni_cid_arrayList)
2110 OIC_LOG(ERROR, TAG, "ArrayList: jni_cid_arrayList is null");
2111 CACheckJNIException(env);
2112 for (j = 0; j< g_serviceUuidCount; j++)
2114 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2116 for (j = 0; j< g_manufactureDataCount; j++)
2118 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2120 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2121 return CA_STATUS_FAILED;
2124 jmethodID jni_mid_arrayListCtor = (*env)->GetMethodID(env, jni_cid_arrayList, "<init>", "()V");
2125 if (!jni_mid_arrayListCtor)
2127 OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListCtor is null");
2128 CACheckJNIException(env);
2129 for (j = 0; j< g_serviceUuidCount; j++)
2131 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2133 for (j = 0; j< g_manufactureDataCount; j++)
2135 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2137 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2138 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2139 return CA_STATUS_FAILED;
2142 jmethodID jni_mid_arrayListAdd = (*env)->GetMethodID(env, jni_cid_arrayList,
2143 "add", "(Ljava/lang/Object;)Z");
2144 if (!jni_mid_arrayListAdd)
2146 OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListAdd is null");
2147 CACheckJNIException(env);
2148 for (j = 0; j< g_serviceUuidCount; j++)
2150 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2152 for (j = 0; j< g_manufactureDataCount; j++)
2154 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2156 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2157 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2158 return CA_STATUS_FAILED;
2161 jobject jni_obj_filterList = (*env)->NewObject(env, jni_cid_arrayList, jni_mid_arrayListCtor);
2162 if (!jni_obj_filterList)
2164 OIC_LOG(ERROR, TAG, "ArrayList: jni_obj_filterList is null");
2165 for (j = 0; j< g_serviceUuidCount; j++)
2167 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2169 for (j = 0; j< g_manufactureDataCount; j++)
2171 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2173 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2174 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2175 return CA_STATUS_FAILED;
2177 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2179 jboolean jni_bool_arrayListIsAdded;
2180 for (i = 0; i < g_serviceUuidCount; i++)
2182 jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
2183 jni_mid_arrayListAdd,
2184 jni_obj_servicescanfilter[i]);
2185 if (!jni_bool_arrayListIsAdded)
2187 OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
2188 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2189 for(j = i; j < g_serviceUuidCount; j++)
2191 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2193 for(j = 0; j < g_manufactureDataCount; j++)
2195 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2197 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2198 return CA_STATUS_FAILED;
2200 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[i]);
2201 OIC_LOG_V(INFO, TAG, "%d st/nd/th service uuid based scanFilters Added", i + 1);
2204 for (i = 0; i < g_manufactureDataCount; i++)
2206 jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
2207 jni_mid_arrayListAdd,
2208 jni_obj_customscanfilter[i]);
2209 if (!jni_bool_arrayListIsAdded)
2211 OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
2212 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2213 for(j = i; j < g_manufactureDataCount; j++)
2215 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2217 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2218 return CA_STATUS_FAILED;
2220 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[i]);
2221 OIC_LOG_V(INFO, TAG, "%d st/nd/th manufacture data based scanFilters Added", i + 1);
2224 OIC_LOG(INFO, TAG, "All ScanFilters Added");
2225 // get ScanSettings.SCAN_MODE_BALANCED jint value
2226 jint jni_int_scanBalancedMode = CALEGetConstantsValue(env, CLASSPATH_LE_SCANSETTINGS,
2227 "SCAN_MODE_BALANCED");
2228 CACheckJNIException(env);
2230 // call setScanMode(SCAN_MODE_BALANCED)
2231 jobject jni_obj_setScanMode = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
2232 jni_mid_setScanMode,
2233 jni_int_scanBalancedMode);
2234 if (!jni_obj_setScanMode)
2236 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setScanMode is null");
2237 CACheckJNIException(env);
2238 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2239 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2240 return CA_STATUS_FAILED;
2244 jobject jni_obj_scanSettings = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
2245 jni_mid_build_scanSettings);
2246 if (!jni_obj_scanSettings)
2248 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettings is null");
2249 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2250 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2251 return CA_STATUS_FAILED;
2253 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2255 CAResult_t res = CA_STATUS_FAILED;
2257 // get default bt adapter class
2258 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2259 if (!jni_cid_BTAdapter)
2261 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2262 CACheckJNIException(env);
2266 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2267 "getDefaultAdapter",
2268 "()Landroid/bluetooth/"
2269 "BluetoothAdapter;");
2270 if (!jni_mid_getDefaultAdapter)
2272 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2273 CACheckJNIException(env);
2274 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2278 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2279 jni_mid_getDefaultAdapter);
2280 if (!jni_obj_BTAdapter)
2282 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2283 CACheckJNIException(env);
2284 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2288 // get remote bt adapter method
2289 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2290 "getBluetoothLeScanner",
2291 "()Landroid/bluetooth/"
2292 "le/BluetoothLeScanner;");
2293 if (!jni_mid_getBluetoothLeScanner)
2295 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
2296 CACheckJNIException(env);
2297 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2298 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2302 // get le scanner object
2303 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
2304 jni_mid_getBluetoothLeScanner);
2305 if (!jni_obj_leScanner)
2307 OIC_LOG(ERROR, TAG, "jni_obj_leScanner is null");
2308 CACheckJNIException(env);
2309 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2310 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2313 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2314 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2316 // call startScan method
2317 OIC_LOG(INFO, TAG, "CALL API - startScanWithUUID(for level 21)");
2318 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, jni_obj_filterList,
2319 jni_obj_scanSettings, callback);
2320 if (CACheckJNIException(env))
2322 OIC_LOG(INFO, TAG, "startScan has failed");
2328 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2331 (*env)->DeleteLocalRef(env, jni_obj_scanSettings);
2332 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2336 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
2338 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
2339 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2342 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2345 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
2349 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
2350 "(Ljava/lang/String;)"
2351 "Ljava/util/UUID;");
2352 if (!jni_mid_fromString)
2354 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
2358 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
2359 CACheckJNIException(env);
2360 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
2364 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2368 return jni_obj_uuid;
2371 CACheckJNIException(env);
2375 CAResult_t CALEClientStopScan()
2377 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
2380 bool isAttached = false;
2381 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
2382 return CA_STATUS_FAILED;
2385 CAResult_t ret = CA_STATUS_FAILED;
2387 if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
2389 ret = CALEClientStopScanImplForV21(env, g_leScanCallback);
2393 ret = CALEClientStopScanImpl(env, g_leScanCallback);
2396 if (CA_STATUS_OK != ret)
2398 if (CA_ADAPTER_NOT_ENABLED == ret)
2400 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
2404 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
2410 (*g_jvm)->DetachCurrentThread(g_jvm);
2416 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
2418 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl IN");
2419 VERIFY_NON_NULL(callback, TAG, "callback is null");
2420 VERIFY_NON_NULL(env, TAG, "env is null");
2422 if (!CALEIsEnableBTAdapter(env))
2424 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2425 return CA_ADAPTER_NOT_ENABLED;
2428 // get default bt adapter class
2429 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2430 if (!jni_cid_BTAdapter)
2432 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2433 CACheckJNIException(env);
2434 return CA_STATUS_FAILED;
2437 // get remote bt adapter method
2438 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2439 "getDefaultAdapter",
2440 METHODID_OBJECTNONPARAM);
2441 if (!jni_mid_getDefaultAdapter)
2443 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2444 CACheckJNIException(env);
2445 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2446 return CA_STATUS_FAILED;
2449 // get start le scan method
2450 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
2451 "(Landroid/bluetooth/"
2452 "BluetoothAdapter$LeScanCallback;)V");
2453 if (!jni_mid_stopLeScan)
2455 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
2456 CACheckJNIException(env);
2457 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2458 return CA_STATUS_FAILED;
2461 // get bt adapter object
2462 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2463 jni_mid_getDefaultAdapter);
2464 if (!jni_obj_BTAdapter)
2466 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2467 CACheckJNIException(env);
2468 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2469 return CA_STATUS_FAILED;
2472 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
2473 // call start le scan method
2474 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
2475 if (CACheckJNIException(env))
2477 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
2478 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2479 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2480 return CA_STATUS_FAILED;
2483 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2484 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2485 return CA_STATUS_OK;
2488 CAResult_t CALEClientStopScanImplForV21(JNIEnv *env, jobject callback)
2490 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImplForV21 IN");
2491 VERIFY_NON_NULL(callback, TAG, "callback is null");
2492 VERIFY_NON_NULL(env, TAG, "env is null");
2494 if (!CALEIsEnableBTAdapter(env))
2496 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2497 return CA_ADAPTER_NOT_ENABLED;
2500 // get default bt adapter class
2501 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2502 if (!jni_cid_BTAdapter)
2504 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2505 CACheckJNIException(env);
2506 return CA_STATUS_FAILED;
2509 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2510 "getDefaultAdapter",
2511 "()Landroid/bluetooth/"
2512 "BluetoothAdapter;");
2513 if (!jni_mid_getDefaultAdapter)
2515 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2516 CACheckJNIException(env);
2517 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2518 return CA_STATUS_FAILED;
2521 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2522 jni_mid_getDefaultAdapter);
2523 if (!jni_obj_BTAdapter)
2525 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2526 CACheckJNIException(env);
2527 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2528 return CA_STATUS_FAILED;
2531 // get bluetoothLeScanner class
2532 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
2533 if (!jni_cid_leScanner)
2535 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
2536 CACheckJNIException(env);
2537 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2538 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2539 return CA_STATUS_FAILED;
2542 // get remote bt adapter method
2543 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2544 "getBluetoothLeScanner",
2545 "()Landroid/bluetooth/"
2546 "le/BluetoothLeScanner;");
2547 if (!jni_mid_getBluetoothLeScanner)
2549 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
2550 CACheckJNIException(env);
2551 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2552 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2553 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2554 return CA_STATUS_FAILED;
2556 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2558 // get stopScan(ScanCallback callback) method
2559 jmethodID jni_mid_stopScan = (*env)->GetMethodID(env, jni_cid_leScanner, "stopScan",
2560 "(Landroid/bluetooth/le/ScanCallback;)V");
2561 if (!jni_mid_stopScan)
2563 OIC_LOG(ERROR, TAG, "stopScan: jni_mid_stopScan is null");
2564 CACheckJNIException(env);
2565 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2566 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2567 return CA_STATUS_FAILED;
2569 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2571 // gat le scanner object
2572 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
2573 jni_mid_getBluetoothLeScanner);
2574 if (!jni_obj_leScanner)
2576 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
2577 CACheckJNIException(env);
2578 return CA_STATUS_FAILED;
2581 // call stopScan method
2582 OIC_LOG(INFO, TAG, "CALL API - stopScan for level 21");
2583 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_stopScan, callback);
2584 if (CACheckJNIException(env))
2586 OIC_LOG(INFO, TAG, "stopScan for level 21 has failed");
2587 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2588 return CA_STATUS_FAILED;
2591 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2592 return CA_STATUS_OK;
2595 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2597 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
2598 VERIFY_NON_NULL(env, TAG, "env is null");
2599 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
2601 oc_mutex_lock(g_threadSendMutex);
2603 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
2606 OIC_LOG(ERROR, TAG, "jni_address is not available");
2607 oc_mutex_unlock(g_threadSendMutex);
2608 return CA_STATUS_FAILED;
2611 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2614 OIC_LOG(ERROR, TAG, "address is not available");
2615 CACheckJNIException(env);
2616 oc_mutex_unlock(g_threadSendMutex);
2617 return CA_STATUS_FAILED;
2620 CAResult_t res = CA_STATUS_OK;
2621 if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2624 g_deviceStateListMutex))
2626 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
2627 if (NULL == newGatt)
2629 OIC_LOG(INFO, TAG, "newGatt is not available");
2630 res = CA_STATUS_FAILED;
2633 oc_mutex_unlock(g_threadSendMutex);
2638 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2640 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
2641 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2642 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
2644 // reset scan interval time after checking scanned devices
2645 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
2647 // since there is no callback related stop success
2648 // and scanning should be stopped before connectGatt is called.
2649 // it should wait a few micro seconds.
2652 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
2653 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
2656 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2659 OIC_LOG(ERROR, TAG, "address is not available");
2663 // close the gatt service
2664 jobject gatt = CALEClientGetGattObjInList(env, address);
2667 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
2668 if (CA_STATUS_OK != res)
2670 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
2671 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2675 // clean previous gatt object after close profile service
2676 res = CALEClientRemoveGattObjForAddr(env, jni_address);
2677 if (CA_STATUS_OK != res)
2679 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
2680 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2684 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2687 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
2690 OIC_LOG(DEBUG, TAG, "re-connection will be started");
2694 // add new gatt object into g_gattObjectList
2695 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
2696 if (CA_STATUS_OK != res)
2698 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
2705 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2707 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
2708 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2709 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
2711 if (!g_leGattCallback)
2713 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
2717 if (!CALEIsEnableBTAdapter(env))
2719 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2723 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
2726 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
2730 jobject jni_obj_connectGatt = NULL;
2731 jint jni_int_sdk = CALEGetBuildVersion(env);
2732 OIC_LOG_V(INFO, TAG, "API level is %d", jni_int_sdk);
2733 if (jni_int_sdk >= 23) // upper than API level 23
2735 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
2737 "(Landroid/content/Context;ZLandroid/"
2738 "bluetooth/BluetoothGattCallback;I)"
2739 "Landroid/bluetooth/BluetoothGatt;");
2740 if (!jni_mid_connectGatt)
2742 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
2746 jint jni_transport_le = CALEGetConstantsValue(env, CLASSPATH_BT_DEVICE, "TRANSPORT_LE");
2747 OIC_LOG_V(INFO, TAG, "CALL API - connectGatt with transport LE(%d)", jni_transport_le);
2748 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
2749 jni_mid_connectGatt, NULL,
2750 autoconnect, g_leGattCallback,
2752 if (!jni_obj_connectGatt)
2754 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
2755 CACheckJNIException(env);
2756 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
2757 CALEClientUpdateSendCnt(env);
2762 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
2765 else // lower than API level 23
2768 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2771 OIC_LOG(ERROR, TAG, "GetStringUTFChars has failed");
2774 OIC_LOG(INFO, TAG, "CALL API - connectGatt for hidden");
2775 jni_obj_connectGatt = CALEClientHiddenConnectGatt(bluetoothDevice, address, autoconnect);
2779 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
2781 "(Landroid/content/Context;ZLandroid/"
2782 "bluetooth/BluetoothGattCallback;)"
2783 "Landroid/bluetooth/BluetoothGatt;");
2784 if (!jni_mid_connectGatt)
2786 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
2790 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
2791 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
2792 jni_mid_connectGatt,
2794 autoconnect, g_leGattCallback);
2796 if (!jni_obj_connectGatt)
2798 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
2799 CACheckJNIException(env);
2800 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
2801 CALEClientUpdateSendCnt(env);
2806 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
2811 return jni_obj_connectGatt;
2814 bool CALEClientIsConnected(const char* address)
2816 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2817 STATE_SERVICE_CONNECTED,
2819 g_deviceStateListMutex))
2821 OIC_LOG(DEBUG, TAG, "current state is connected");
2824 OIC_LOG(DEBUG, TAG, "current state is not connected");
2828 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
2830 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
2832 VERIFY_NON_NULL(env, TAG, "env is null");
2833 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2835 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2836 if (!jni_cid_BTAdapter)
2838 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
2842 // get remote bt adapter method
2843 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2844 "getDefaultAdapter",
2845 METHODID_OBJECTNONPARAM);
2846 if (!jni_mid_getDefaultAdapter)
2848 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2852 // gat bt adapter object
2853 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2854 jni_mid_getDefaultAdapter);
2855 if (!jni_obj_BTAdapter)
2857 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2861 // get closeProfileProxy method
2862 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2863 "closeProfileProxy",
2864 "(ILandroid/bluetooth/"
2865 "BluetoothProfile;)V");
2866 if (!jni_mid_closeProfileProxy)
2868 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
2872 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
2873 if (!jni_cid_BTProfile)
2875 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
2879 // GATT - Constant value : 7 (0x00000007)
2880 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
2884 OIC_LOG(ERROR, TAG, "id_gatt is null");
2888 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
2889 CACheckJNIException(env);
2891 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
2892 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
2893 if (CACheckJNIException(env))
2895 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
2896 return CA_STATUS_FAILED;
2899 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
2900 return CA_STATUS_OK;
2903 CACheckJNIException(env);
2904 return CA_STATUS_FAILED;
2908 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
2910 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
2911 VERIFY_NON_NULL(env, TAG, "env is null");
2912 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2914 // get BluetoothGatt method
2915 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
2916 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2917 "disconnect", "()V");
2918 if (!jni_mid_disconnectGatt)
2920 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
2921 return CA_STATUS_FAILED;
2924 // call disconnect gatt method
2925 OIC_LOG(INFO, TAG, "CALL API - disconnect");
2926 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
2927 if (CACheckJNIException(env))
2929 OIC_LOG(ERROR, TAG, "disconnect has failed");
2930 return CA_STATUS_FAILED;
2933 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
2935 return CA_STATUS_OK;
2938 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
2940 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
2941 VERIFY_NON_NULL(env, TAG, "env is null");
2943 if (!g_gattObjectList)
2945 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2946 return CA_STATUS_OK;
2949 uint32_t length = u_arraylist_length(g_gattObjectList);
2950 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
2951 for (uint32_t index = 0; index < length; index++)
2953 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
2954 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2957 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2960 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2961 if (CA_STATUS_OK != res)
2963 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2968 return CA_STATUS_OK;
2971 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
2973 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
2974 VERIFY_NON_NULL(env, TAG, "env is null");
2976 if (!g_gattObjectList)
2978 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2979 return CA_STATUS_OK;
2982 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
2985 OIC_LOG(ERROR, TAG, "address is null");
2986 CACheckJNIException(env);
2987 return CA_STATUS_FAILED;
2990 uint32_t length = u_arraylist_length(g_gattObjectList);
2991 for (uint32_t index = 0; index < length; index++)
2993 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2996 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3000 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3001 if (!jni_setAddress)
3003 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3004 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3005 return CA_STATUS_FAILED;
3008 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3011 OIC_LOG(ERROR, TAG, "setAddress is null");
3012 CACheckJNIException(env);
3013 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3014 return CA_STATUS_FAILED;
3017 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
3018 if (!strcasecmp(address, setAddress))
3020 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
3021 if (CA_STATUS_OK != res)
3023 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
3024 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3025 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3026 return CA_STATUS_FAILED;
3028 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3029 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3030 return CA_STATUS_OK;
3032 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3034 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3036 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
3037 return CA_STATUS_OK;
3040 CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size)
3042 VERIFY_NON_NULL(env, TAG, "env is null");
3043 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3045 if (!CALEIsEnableBTAdapter(env))
3047 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3048 return CA_ADAPTER_NOT_ENABLED;
3051 // get BluetoothGatt.requestMtu method
3052 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.requestMtu method");
3053 jmethodID jni_mid_requestMtu = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3054 "requestMtu", "(I)Z");
3055 if (!jni_mid_requestMtu)
3057 OIC_LOG(ERROR, TAG, "jni_mid_requestMtu is null");
3058 return CA_STATUS_FAILED;
3062 OIC_LOG(INFO, TAG, "CALL API - requestMtu");
3063 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_requestMtu, size);
3066 OIC_LOG(ERROR, TAG, "requestMtu has failed");
3067 CACheckJNIException(env);
3068 return CA_STATUS_FAILED;
3071 return CA_STATUS_OK;
3074 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
3076 VERIFY_NON_NULL(env, TAG, "env is null");
3077 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3079 if (!CALEIsEnableBTAdapter(env))
3081 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3082 return CA_ADAPTER_NOT_ENABLED;
3085 // get BluetoothGatt.discoverServices method
3086 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
3087 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3088 "discoverServices", "()Z");
3089 if (!jni_mid_discoverServices)
3091 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
3092 return CA_STATUS_FAILED;
3095 // call disconnect gatt method
3096 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
3097 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
3100 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
3101 CACheckJNIException(env);
3102 return CA_STATUS_FAILED;
3105 return CA_STATUS_OK;
3108 static void CALEWriteCharacteristicThread(void* object)
3110 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
3111 VERIFY_NON_NULL_VOID(g_jvm, TAG, "g_jvm is null");
3114 bool isAttached = false;
3115 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
3119 jobject gatt = (jobject)object;
3120 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
3121 if (CA_STATUS_OK != ret)
3123 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
3128 (*g_jvm)->DetachCurrentThread(g_jvm);
3132 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
3134 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
3136 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3137 VERIFY_NON_NULL(env, TAG, "env is null");
3139 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3142 CALEClientSendFinish(env, gatt);
3143 return CA_STATUS_FAILED;
3146 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3149 CACheckJNIException(env);
3150 CALEClientSendFinish(env, gatt);
3151 return CA_STATUS_FAILED;
3154 oc_mutex_lock(g_threadSendStateMutex);
3156 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING,
3158 g_deviceStateListMutex))
3160 OIC_LOG(INFO, TAG, "current state is SENDING");
3161 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3162 oc_mutex_unlock(g_threadSendStateMutex);
3163 return CA_STATUS_OK;
3166 if (CA_STATUS_OK != CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
3169 g_deviceStateListMutex))
3171 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
3172 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3173 CALEClientSendFinish(env, gatt);
3174 oc_mutex_unlock(g_threadSendStateMutex);
3175 return CA_STATUS_FAILED;
3178 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3180 oc_mutex_unlock(g_threadSendStateMutex);
3182 jbyteArray sendData = NULL;
3183 oc_mutex_lock(g_setValueMutex);
3186 OIC_LOG(INFO, TAG, "alloc local reference for data");
3187 sendData = (jbyteArray)(*env)->NewLocalRef(env, g_sendBuffer);
3191 OIC_LOG(ERROR, TAG, "send Buffer is empty");
3192 oc_mutex_unlock(g_setValueMutex);
3193 return CA_STATUS_FAILED;
3195 oc_mutex_unlock(g_setValueMutex);
3198 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, sendData);
3199 if (!jni_obj_character)
3203 (*env)->DeleteLocalRef(env, sendData);
3205 CALEClientSendFinish(env, gatt);
3206 return CA_STATUS_FAILED;
3211 (*env)->DeleteLocalRef(env, sendData);
3214 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
3215 if (CA_STATUS_OK != ret)
3217 CALEClientSendFinish(env, gatt);
3218 return CA_STATUS_FAILED;
3221 // wait for callback for write Characteristic with success to sent data
3222 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
3223 oc_mutex_lock(g_threadWriteCharacteristicMutex);
3224 if (!g_isSignalSetFlag)
3226 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
3227 if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
3228 g_threadWriteCharacteristicMutex,
3229 WAIT_TIME_WRITE_CHARACTERISTIC))
3231 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
3232 g_isSignalSetFlag = false;
3233 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3234 return CA_STATUS_FAILED;
3237 // reset flag set by writeCharacteristic Callback
3238 g_isSignalSetFlag = false;
3239 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3241 CALEClientUpdateSendCnt(env);
3243 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
3244 return CA_STATUS_OK;
3247 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
3249 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
3250 VERIFY_NON_NULL(env, TAG, "env is null");
3251 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3253 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
3254 CACheckJNIException(env);
3255 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEWriteCharacteristicThread,
3256 (void*)gattParam, NULL))
3258 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
3259 return CA_STATUS_FAILED;
3262 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
3263 return CA_STATUS_OK;
3266 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
3267 jobject gattCharacteristic)
3269 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
3270 VERIFY_NON_NULL(env, TAG, "env is null");
3271 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3272 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
3274 if (!CALEIsEnableBTAdapter(env))
3276 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3277 return CA_STATUS_FAILED;
3280 // get BluetoothGatt.write characteristic method
3281 OIC_LOG(DEBUG, TAG, "write characteristic method");
3282 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3283 "writeCharacteristic",
3284 "(Landroid/bluetooth/"
3285 "BluetoothGattCharacteristic;)Z");
3286 if (!jni_mid_writeCharacteristic)
3288 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
3289 return CA_STATUS_FAILED;
3292 // call disconnect gatt method
3293 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
3294 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
3295 jni_mid_writeCharacteristic,
3296 gattCharacteristic);
3299 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
3303 CACheckJNIException(env);
3304 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
3305 return CA_STATUS_FAILED;
3308 return CA_STATUS_OK;
3311 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
3313 VERIFY_NON_NULL(env, TAG, "env is null");
3314 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3316 if (!CALEIsEnableBTAdapter(env))
3318 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3319 return CA_STATUS_FAILED;
3322 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3325 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3326 CACheckJNIException(env);
3327 return CA_STATUS_FAILED;
3330 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
3331 if (!jni_obj_GattCharacteristic)
3333 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3334 return CA_STATUS_FAILED;
3337 OIC_LOG(DEBUG, TAG, "read characteristic method");
3338 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3339 "readCharacteristic",
3340 "(Landroid/bluetooth/"
3341 "BluetoothGattCharacteristic;)Z");
3342 if (!jni_mid_readCharacteristic)
3344 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
3345 return CA_STATUS_FAILED;
3348 // call disconnect gatt method
3349 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
3350 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
3351 jni_obj_GattCharacteristic);
3354 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
3358 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
3359 CACheckJNIException(env);
3360 return CA_STATUS_FAILED;
3363 return CA_STATUS_OK;
3366 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
3367 jobject characteristic)
3369 VERIFY_NON_NULL(env, TAG, "env is null");
3370 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3371 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
3373 if (!CALEIsEnableBTAdapter(env))
3375 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3376 return CA_ADAPTER_NOT_ENABLED;
3379 // get BluetoothGatt.setCharacteristicNotification method
3380 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
3381 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3382 "setCharacteristicNotification",
3383 "(Landroid/bluetooth/"
3384 "BluetoothGattCharacteristic;Z)Z");
3385 if (!jni_mid_setNotification)
3387 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
3388 return CA_STATUS_FAILED;
3391 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
3392 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
3393 characteristic, JNI_TRUE);
3394 if (JNI_TRUE == ret)
3396 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
3400 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
3401 CACheckJNIException(env);
3402 return CA_STATUS_FAILED;
3405 return CA_STATUS_OK;
3408 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
3410 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3411 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
3412 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
3414 if (!CALEIsEnableBTAdapter(env))
3416 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3420 // get BluetoothGatt.getService method
3421 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
3422 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3424 "(Ljava/util/UUID;)Landroid/bluetooth/"
3425 "BluetoothGattService;");
3426 if (!jni_mid_getService)
3428 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
3432 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
3433 if (!jni_obj_service_uuid)
3435 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
3439 // get bluetooth gatt service
3440 OIC_LOG(DEBUG, TAG, "request to get service");
3441 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
3442 jni_obj_service_uuid);
3443 if (!jni_obj_gattService)
3445 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
3446 CACheckJNIException(env);
3450 // get bluetooth gatt service method
3451 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
3452 "BluetoothGattService",
3453 "getCharacteristic",
3454 "(Ljava/util/UUID;)"
3455 "Landroid/bluetooth/"
3456 "BluetoothGattCharacteristic;");
3457 if (!jni_mid_getCharacteristic)
3459 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
3463 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
3466 OIC_LOG(ERROR, TAG, "uuid is null");
3467 CACheckJNIException(env);
3471 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
3472 if (!jni_obj_tx_uuid)
3474 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
3475 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
3479 OIC_LOG(DEBUG, TAG, "CALL API getCharacteristic");
3480 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
3481 jni_mid_getCharacteristic,
3483 if (!jni_obj_GattCharacteristic)
3485 OIC_LOG(ERROR, TAG, "getCharacteristic has failed");
3486 CACheckJNIException(env);
3490 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
3491 return jni_obj_GattCharacteristic;
3494 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
3496 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
3497 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3498 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
3499 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
3501 if (!CALEIsEnableBTAdapter(env))
3503 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3507 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
3510 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3514 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
3515 if (!jni_obj_GattCharacteristic)
3517 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3521 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
3522 "/BluetoothGattCharacteristic");
3523 if (!jni_cid_BTGattCharacteristic)
3525 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
3529 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
3530 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
3532 if (!jni_mid_setValue)
3534 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
3538 OIC_LOG(DEBUG, TAG, "CALL API - setValue");
3539 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
3541 if (JNI_TRUE == ret)
3543 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
3547 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
3553 OIC_LOG(DEBUG, TAG, "setWriteType with WRITE_TYPE_NO_RESPONSE");
3555 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
3556 "setWriteType", "(I)V");
3557 if (!jni_mid_setWriteType)
3559 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
3563 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
3564 "WRITE_TYPE_NO_RESPONSE", "I");
3565 if (!jni_fid_no_response)
3567 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
3571 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
3572 jni_fid_no_response);
3573 CACheckJNIException(env);
3575 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
3576 if (CACheckJNIException(env))
3578 OIC_LOG(ERROR, TAG, "setWriteType has failed");
3583 OIC_LOG(DEBUG, TAG, "It will run with response property");
3586 return jni_obj_GattCharacteristic;
3589 CACheckJNIException(env);
3593 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
3595 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
3596 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3598 if (!CALEIsEnableBTAdapter(env))
3600 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3604 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
3605 "BluetoothGattCharacteristic",
3606 "getValue", "()[B");
3607 if (!jni_mid_getValue)
3609 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
3613 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
3615 CACheckJNIException(env);
3616 return jni_obj_data_array;
3619 CAResult_t CALEClientCreateUUIDList()
3621 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
3624 bool isAttached = false;
3625 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
3626 return CA_STATUS_FAILED;
3629 // create new object array
3630 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
3631 if (!jni_cid_uuid_list)
3633 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
3634 CACheckJNIException(env);
3638 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
3639 jni_cid_uuid_list, NULL);
3640 if (!jni_obj_uuid_list)
3642 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
3643 CACheckJNIException(env);
3648 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
3651 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
3654 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
3656 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
3657 CACheckJNIException(env);
3661 (*g_jvm)->DetachCurrentThread(g_jvm);
3664 return CA_STATUS_OK;
3671 (*g_jvm)->DetachCurrentThread(g_jvm);
3673 return CA_STATUS_FAILED;
3676 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
3677 jobject characteristic)
3679 VERIFY_NON_NULL(env, TAG, "env is null");
3680 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3681 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
3683 if (!CALEIsEnableBTAdapter(env))
3685 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3686 return CA_ADAPTER_NOT_ENABLED;
3689 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
3690 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
3691 "BluetoothGattCharacteristic",
3693 "(Ljava/util/UUID;)Landroid/bluetooth/"
3694 "BluetoothGattDescriptor;");
3695 if (!jni_mid_getDescriptor)
3697 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
3698 return CA_STATUS_FAILED;
3701 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
3702 if (!jni_obj_cc_uuid)
3704 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
3707 OIC_LOG(DEBUG, TAG, "request to get descriptor");
3708 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
3709 jni_mid_getDescriptor, jni_obj_cc_uuid);
3710 if (!jni_obj_descriptor)
3712 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
3716 OIC_LOG(DEBUG, TAG, "set value in descriptor");
3717 jclass jni_cid_descriptor = (*env)->FindClass(env,
3718 "android/bluetooth/BluetoothGattDescriptor");
3719 if (!jni_cid_descriptor)
3721 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
3725 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
3726 if (!jni_mid_setValue)
3728 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
3732 jfieldID jni_fid_NotiValue = NULL;
3735 OIC_LOG(DEBUG, TAG, "get ENABLE_INDICATION_VALUE");
3736 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
3737 "ENABLE_INDICATION_VALUE", "[B");
3738 if (!jni_fid_NotiValue)
3740 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
3746 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
3747 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
3748 "ENABLE_NOTIFICATION_VALUE", "[B");
3749 if (!jni_fid_NotiValue)
3751 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
3756 jboolean jni_setvalue = (*env)->CallBooleanMethod(
3757 env, jni_obj_descriptor, jni_mid_setValue,
3758 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
3761 OIC_LOG(DEBUG, TAG, "setValue success");
3765 OIC_LOG(ERROR, TAG, "setValue has failed");
3769 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
3771 "(Landroid/bluetooth/"
3772 "BluetoothGattDescriptor;)Z");
3773 if (!jni_mid_writeDescriptor)
3775 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
3776 return CA_STATUS_FAILED;
3779 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
3780 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
3781 jni_obj_descriptor);
3784 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
3788 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
3792 return CA_STATUS_OK;
3795 CACheckJNIException(env);
3796 return CA_STATUS_FAILED;
3799 void CALEClientCreateScanDeviceList(JNIEnv *env)
3801 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
3802 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3804 oc_mutex_lock(g_deviceListMutex);
3805 // create new object array
3806 if (g_deviceList == NULL)
3808 OIC_LOG(DEBUG, TAG, "Create device list");
3810 g_deviceList = u_arraylist_create();
3812 oc_mutex_unlock(g_deviceListMutex);
3815 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
3817 VERIFY_NON_NULL(device, TAG, "device is null");
3818 VERIFY_NON_NULL(env, TAG, "env is null");
3820 oc_mutex_lock(g_deviceListMutex);
3824 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3825 oc_mutex_unlock(g_deviceListMutex);
3826 return CA_STATUS_FAILED;
3829 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
3830 if (!jni_remoteAddress)
3832 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3833 oc_mutex_unlock(g_deviceListMutex);
3834 return CA_STATUS_FAILED;
3837 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3840 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3841 CACheckJNIException(env);
3842 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3843 oc_mutex_unlock(g_deviceListMutex);
3844 return CA_STATUS_FAILED;
3847 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
3849 jobject gdevice = (*env)->NewGlobalRef(env, device);
3850 CACheckJNIException(env);
3851 u_arraylist_add(g_deviceList, gdevice);
3852 oc_cond_signal(g_deviceDescCond);
3853 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
3855 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3856 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3858 oc_mutex_unlock(g_deviceListMutex);
3860 return CA_STATUS_OK;
3863 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
3865 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
3866 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
3870 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
3874 uint32_t length = u_arraylist_length(g_deviceList);
3875 for (uint32_t index = 0; index < length; index++)
3877 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3880 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3884 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
3885 if (!jni_setAddress)
3887 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3891 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3894 OIC_LOG(ERROR, TAG, "setAddress is null");
3895 CACheckJNIException(env);
3896 (*env)->DeleteLocalRef(env, jni_setAddress);
3900 if (!strcasecmp(remoteAddress, setAddress))
3902 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3903 (*env)->DeleteLocalRef(env, jni_setAddress);
3907 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3908 (*env)->DeleteLocalRef(env, jni_setAddress);
3913 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
3915 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
3916 VERIFY_NON_NULL(env, TAG, "env is null");
3918 oc_mutex_lock(g_deviceListMutex);
3922 OIC_LOG(ERROR, TAG, "g_deviceList is null");
3923 oc_mutex_unlock(g_deviceListMutex);
3924 return CA_STATUS_FAILED;
3927 uint32_t length = u_arraylist_length(g_deviceList);
3928 for (uint32_t index = 0; index < length; index++)
3930 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3933 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3936 (*env)->DeleteGlobalRef(env, jarrayObj);
3940 OICFree(g_deviceList);
3941 g_deviceList = NULL;
3943 oc_mutex_unlock(g_deviceListMutex);
3944 return CA_STATUS_OK;
3947 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
3949 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
3950 VERIFY_NON_NULL(address, TAG, "address is null");
3951 VERIFY_NON_NULL(env, TAG, "env is null");
3953 oc_mutex_lock(g_deviceListMutex);
3957 OIC_LOG(ERROR, TAG, "g_deviceList is null");
3958 oc_mutex_unlock(g_deviceListMutex);
3959 return CA_STATUS_FAILED;
3962 uint32_t length = u_arraylist_length(g_deviceList);
3963 for (uint32_t index = 0; index < length; index++)
3965 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3968 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3969 oc_mutex_unlock(g_deviceListMutex);
3970 return CA_STATUS_FAILED;
3973 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
3974 if (!jni_setAddress)
3976 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3977 oc_mutex_unlock(g_deviceListMutex);
3978 return CA_STATUS_FAILED;
3981 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3984 OIC_LOG(ERROR, TAG, "setAddress is null");
3985 CACheckJNIException(env);
3986 oc_mutex_unlock(g_deviceListMutex);
3987 return CA_STATUS_FAILED;
3990 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
3993 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3994 CACheckJNIException(env);
3995 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3996 oc_mutex_unlock(g_deviceListMutex);
3997 return CA_STATUS_FAILED;
4000 if (!strcasecmp(setAddress, remoteAddress))
4002 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4003 (*env)->DeleteGlobalRef(env, jarrayObj);
4005 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4006 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
4008 if (NULL == u_arraylist_remove(g_deviceList, index))
4010 OIC_LOG(ERROR, TAG, "List removal failed.");
4011 oc_mutex_unlock(g_deviceListMutex);
4012 return CA_STATUS_FAILED;
4014 oc_mutex_unlock(g_deviceListMutex);
4015 return CA_STATUS_OK;
4017 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4018 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
4021 oc_mutex_unlock(g_deviceListMutex);
4022 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
4024 return CA_STATUS_OK;
4031 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
4033 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
4034 VERIFY_NON_NULL(env, TAG, "env is null");
4035 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
4037 oc_mutex_lock(g_gattObjectMutex);
4039 if (!g_gattObjectList)
4041 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
4042 oc_mutex_unlock(g_gattObjectMutex);
4043 return CA_STATUS_FAILED;
4046 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
4047 if (!jni_remoteAddress)
4049 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
4050 oc_mutex_unlock(g_gattObjectMutex);
4051 return CA_STATUS_FAILED;
4054 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
4057 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4058 CACheckJNIException(env);
4059 (*env)->DeleteLocalRef(env, jni_remoteAddress);
4060 oc_mutex_unlock(g_gattObjectMutex);
4061 return CA_STATUS_FAILED;
4064 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
4065 if (!CALEClientIsGattObjInList(env, remoteAddress))
4067 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
4068 u_arraylist_add(g_gattObjectList, newGatt);
4069 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
4072 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4073 (*env)->DeleteLocalRef(env, jni_remoteAddress);
4074 oc_mutex_unlock(g_gattObjectMutex);
4075 return CA_STATUS_OK;
4078 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
4080 VERIFY_NON_NULL(env, TAG, "env is null");
4081 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
4083 uint32_t length = u_arraylist_length(g_gattObjectList);
4084 for (uint32_t index = 0; index < length; index++)
4086 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4089 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4093 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4094 if (!jni_setAddress)
4096 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4100 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4103 OIC_LOG(ERROR, TAG, "setAddress is null");
4104 CACheckJNIException(env);
4105 (*env)->DeleteLocalRef(env, jni_setAddress);
4109 if (!strcasecmp(remoteAddress, setAddress))
4111 OIC_LOG(DEBUG, TAG, "the device is already set");
4112 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4113 (*env)->DeleteLocalRef(env, jni_setAddress);
4116 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4117 (*env)->DeleteLocalRef(env, jni_setAddress);
4120 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
4124 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
4126 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
4127 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4128 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
4130 oc_mutex_lock(g_gattObjectMutex);
4131 uint32_t length = u_arraylist_length(g_gattObjectList);
4132 for (uint32_t index = 0; index < length; index++)
4134 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4137 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4138 oc_mutex_unlock(g_gattObjectMutex);
4142 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4143 if (!jni_setAddress)
4145 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4146 oc_mutex_unlock(g_gattObjectMutex);
4150 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4153 OIC_LOG(ERROR, TAG, "setAddress is null");
4154 CACheckJNIException(env);
4155 (*env)->DeleteLocalRef(env, jni_setAddress);
4156 oc_mutex_unlock(g_gattObjectMutex);
4160 if (!strcasecmp(remoteAddress, setAddress))
4162 OIC_LOG(DEBUG, TAG, "the device is already set");
4163 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4164 oc_mutex_unlock(g_gattObjectMutex);
4167 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4168 (*env)->DeleteLocalRef(env, jni_setAddress);
4171 oc_mutex_unlock(g_gattObjectMutex);
4172 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
4176 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
4178 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
4179 VERIFY_NON_NULL(env, TAG, "env is null");
4181 oc_mutex_lock(g_gattObjectMutex);
4182 if (!g_gattObjectList)
4184 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4185 oc_mutex_unlock(g_gattObjectMutex);
4186 return CA_STATUS_OK;
4189 uint32_t length = u_arraylist_length(g_gattObjectList);
4190 for (uint32_t index = 0; index < length; index++)
4192 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4195 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4198 (*env)->DeleteGlobalRef(env, jarrayObj);
4202 OICFree(g_gattObjectList);
4203 g_gattObjectList = NULL;
4204 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
4205 oc_mutex_unlock(g_gattObjectMutex);
4206 return CA_STATUS_OK;
4209 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
4211 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
4212 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
4213 VERIFY_NON_NULL(env, TAG, "env is null");
4215 oc_mutex_lock(g_gattObjectMutex);
4216 if (!g_gattObjectList)
4218 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4219 oc_mutex_unlock(g_gattObjectMutex);
4220 return CA_STATUS_OK;
4223 uint32_t length = u_arraylist_length(g_gattObjectList);
4224 for (uint32_t index = 0; index < length; index++)
4226 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4229 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4230 oc_mutex_unlock(g_gattObjectMutex);
4231 return CA_STATUS_FAILED;
4234 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4235 if (!jni_setAddress)
4237 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4238 oc_mutex_unlock(g_gattObjectMutex);
4239 return CA_STATUS_FAILED;
4242 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4245 OIC_LOG(ERROR, TAG, "setAddress is null");
4246 CACheckJNIException(env);
4247 oc_mutex_unlock(g_gattObjectMutex);
4248 return CA_STATUS_FAILED;
4251 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
4252 if (!jni_remoteAddress)
4254 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
4255 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4256 oc_mutex_unlock(g_gattObjectMutex);
4257 return CA_STATUS_FAILED;
4260 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
4263 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4264 CACheckJNIException(env);
4265 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4266 oc_mutex_unlock(g_gattObjectMutex);
4267 return CA_STATUS_FAILED;
4270 if (!strcasecmp(setAddress, remoteAddress))
4272 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4273 (*env)->DeleteGlobalRef(env, jarrayObj);
4275 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4276 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4278 if (NULL == u_arraylist_remove(g_gattObjectList, index))
4280 OIC_LOG(ERROR, TAG, "List removal failed.");
4281 oc_mutex_unlock(g_gattObjectMutex);
4282 return CA_STATUS_FAILED;
4284 oc_mutex_unlock(g_gattObjectMutex);
4285 return CA_STATUS_OK;
4287 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4288 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4291 oc_mutex_unlock(g_gattObjectMutex);
4292 OIC_LOG(DEBUG, TAG, "there are no target object");
4293 return CA_STATUS_OK;
4296 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
4298 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
4299 VERIFY_NON_NULL(addr, TAG, "addr is null");
4300 VERIFY_NON_NULL(env, TAG, "env is null");
4302 oc_mutex_lock(g_gattObjectMutex);
4303 if (!g_gattObjectList)
4305 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4306 oc_mutex_unlock(g_gattObjectMutex);
4307 return CA_STATUS_OK;
4310 uint32_t length = u_arraylist_length(g_gattObjectList);
4311 for (uint32_t index = 0; index < length; index++)
4313 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4316 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4317 oc_mutex_unlock(g_gattObjectMutex);
4318 return CA_STATUS_FAILED;
4321 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4322 if (!jni_setAddress)
4324 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4325 oc_mutex_unlock(g_gattObjectMutex);
4326 return CA_STATUS_FAILED;
4329 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4332 OIC_LOG(ERROR, TAG, "setAddress is null");
4333 CACheckJNIException(env);
4334 oc_mutex_unlock(g_gattObjectMutex);
4335 return CA_STATUS_FAILED;
4338 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
4341 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4342 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4343 oc_mutex_unlock(g_gattObjectMutex);
4344 return CA_STATUS_FAILED;
4347 if (!strcasecmp(setAddress, remoteAddress))
4349 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4350 (*env)->DeleteGlobalRef(env, jarrayObj);
4352 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4353 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
4354 if (NULL == u_arraylist_remove(g_gattObjectList, index))
4356 OIC_LOG(ERROR, TAG, "List removal failed.");
4357 oc_mutex_unlock(g_gattObjectMutex);
4358 return CA_STATUS_FAILED;
4360 oc_mutex_unlock(g_gattObjectMutex);
4361 return CA_STATUS_OK;
4363 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4364 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
4367 oc_mutex_unlock(g_gattObjectMutex);
4368 OIC_LOG(DEBUG, TAG, "there are no target object");
4369 return CA_STATUS_FAILED;
4372 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
4374 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
4375 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
4377 // get Bluetooth Address
4378 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
4379 if (!jni_btTargetAddress)
4381 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4385 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
4388 OIC_LOG(ERROR, TAG, "targetAddress is not available");
4389 CACheckJNIException(env);
4393 // get method ID of getDevice()
4394 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
4395 "getDevice", METHODID_BT_DEVICE);
4396 if (!jni_mid_getDevice)
4398 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4399 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4403 oc_mutex_lock(g_gattObjectMutex);
4405 size_t length = u_arraylist_length(g_gattObjectList);
4406 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
4407 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
4409 for (size_t index = 0; index < length; index++)
4411 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4414 oc_mutex_unlock(g_gattObjectMutex);
4415 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4416 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4420 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
4421 if (!jni_obj_device)
4423 CACheckJNIException(env);
4424 oc_mutex_unlock(g_gattObjectMutex);
4425 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4426 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4430 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
4433 oc_mutex_unlock(g_gattObjectMutex);
4434 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4435 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4436 (*env)->DeleteLocalRef(env, jni_obj_device);
4440 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
4443 CACheckJNIException(env);
4444 oc_mutex_unlock(g_gattObjectMutex);
4445 OIC_LOG(ERROR, TAG, "btAddress is not available");
4446 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4447 (*env)->DeleteLocalRef(env, jni_btAddress);
4448 (*env)->DeleteLocalRef(env, jni_obj_device);
4452 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
4453 if (!strcasecmp(targetAddress, btAddress))
4455 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
4458 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4461 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
4463 oc_mutex_unlock(g_gattObjectMutex);
4464 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4465 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
4466 (*env)->DeleteLocalRef(env, jni_btAddress);
4467 (*env)->DeleteLocalRef(env, jni_obj_device);
4468 return jni_LEAddress;
4470 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
4471 (*env)->DeleteLocalRef(env, jni_btAddress);
4472 (*env)->DeleteLocalRef(env, jni_obj_device);
4474 oc_mutex_unlock(g_gattObjectMutex);
4476 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4477 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
4484 CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env,
4486 uint16_t state_type,
4487 uint16_t target_state)
4489 VERIFY_NON_NULL(device, TAG, "device is null");
4491 // get Bluetooth Address
4492 jstring jni_Address = CALEGetAddressFromBTDevice(env, device);
4495 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4496 return CA_STATUS_FAILED;
4499 const char* address = (*env)->GetStringUTFChars(env, jni_Address, NULL);
4502 OIC_LOG(ERROR, TAG, "targetAddress is not available");
4503 CACheckJNIException(env);
4504 (*env)->DeleteLocalRef(env, jni_Address);
4505 return CA_STATUS_FAILED;
4508 if (CALEIsValidState(address, state_type, target_state,
4510 g_deviceStateListMutex))
4512 (*env)->DeleteLocalRef(env, jni_Address);
4513 return CA_STATUS_OK;
4516 CAResult_t res = CALEUpdateDeviceState(address, state_type,
4519 g_deviceStateListMutex);
4520 if (CA_STATUS_OK != res)
4522 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4524 (*env)->ReleaseStringUTFChars(env, jni_Address, address);
4525 (*env)->DeleteLocalRef(env, jni_Address);
4530 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
4531 jint state_idx, jboolean flag)
4533 return CALESetFlagToState(env, jni_address, state_idx, flag,
4534 g_deviceStateList, g_deviceStateListMutex);
4537 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
4539 return CALEGetFlagFromState(env, jni_address, state_idx, g_deviceStateList,
4540 g_deviceStateListMutex);
4543 uint16_t CALEClientGetMtuSize(const char* address)
4545 return CALEGetMtuSize(address, g_deviceStateList, g_deviceStateListMutex);
4548 void CALEClientCreateDeviceList()
4550 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
4552 // create new object array
4553 if (!g_gattObjectList)
4555 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
4557 g_gattObjectList = u_arraylist_create();
4560 if (!g_deviceStateList)
4562 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
4564 g_deviceStateList = u_arraylist_create();
4569 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
4571 g_deviceList = u_arraylist_create();
4575 CAResult_t CALEClientResetDeviceStateForAll()
4577 return CALEResetDeviceStateForAll(g_deviceStateList, g_deviceStateListMutex);
4581 * Check Sent Count for remove g_sendBuffer
4583 void CALEClientUpdateSendCnt(JNIEnv *env)
4585 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
4587 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4589 oc_mutex_lock(g_threadMutex);
4593 if (g_targetCnt <= g_currentSentCnt)
4596 g_currentSentCnt = 0;
4598 CALEDeleteSendBuffer(env);
4600 // notity the thread
4601 oc_cond_signal(g_threadCond);
4602 oc_cond_signal(g_threadWriteCharacteristicCond);
4604 CALEClientSetSendFinishFlag(true);
4605 OIC_LOG(DEBUG, TAG, "set signal for send data");
4608 #ifdef SCAN_INTERVAL
4609 // reset interval scan logic
4610 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
4614 oc_mutex_unlock(g_threadMutex);
4617 CAResult_t CALEClientInitGattMutexVaraibles()
4619 if (NULL == g_bleServerBDAddressMutex)
4621 g_bleServerBDAddressMutex = oc_mutex_new();
4622 if (NULL == g_bleServerBDAddressMutex)
4624 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4625 return CA_STATUS_FAILED;
4629 if (NULL == g_threadMutex)
4631 g_threadMutex = oc_mutex_new();
4632 if (NULL == g_threadMutex)
4634 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4635 return CA_STATUS_FAILED;
4639 if (NULL == g_threadSendMutex)
4641 g_threadSendMutex = oc_mutex_new();
4642 if (NULL == g_threadSendMutex)
4644 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4645 return CA_STATUS_FAILED;
4649 if (NULL == g_deviceListMutex)
4651 g_deviceListMutex = oc_mutex_new();
4652 if (NULL == g_deviceListMutex)
4654 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4655 return CA_STATUS_FAILED;
4659 if (NULL == g_gattObjectMutex)
4661 g_gattObjectMutex = oc_mutex_new();
4662 if (NULL == g_gattObjectMutex)
4664 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4665 return CA_STATUS_FAILED;
4669 if (NULL == g_deviceStateListMutex)
4671 g_deviceStateListMutex = oc_mutex_new();
4672 if (NULL == g_deviceStateListMutex)
4674 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4675 return CA_STATUS_FAILED;
4679 if (NULL == g_SendFinishMutex)
4681 g_SendFinishMutex = oc_mutex_new();
4682 if (NULL == g_SendFinishMutex)
4684 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4685 return CA_STATUS_FAILED;
4689 if (NULL == g_threadWriteCharacteristicMutex)
4691 g_threadWriteCharacteristicMutex = oc_mutex_new();
4692 if (NULL == g_threadWriteCharacteristicMutex)
4694 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4695 return CA_STATUS_FAILED;
4699 if (NULL == g_deviceScanRetryDelayMutex)
4701 g_deviceScanRetryDelayMutex = oc_mutex_new();
4702 if (NULL == g_deviceScanRetryDelayMutex)
4704 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4705 return CA_STATUS_FAILED;
4709 if (NULL == g_threadSendStateMutex)
4711 g_threadSendStateMutex = oc_mutex_new();
4712 if (NULL == g_threadSendStateMutex)
4714 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4715 return CA_STATUS_FAILED;
4719 if (NULL == g_threadScanIntervalMutex)
4721 g_threadScanIntervalMutex = oc_mutex_new();
4722 if (NULL == g_threadScanIntervalMutex)
4724 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4725 return CA_STATUS_FAILED;
4729 if (NULL == g_setValueMutex)
4731 g_setValueMutex = oc_mutex_new();
4732 if (NULL == g_setValueMutex)
4734 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4735 return CA_STATUS_FAILED;
4739 return CA_STATUS_OK;
4742 void CALEClientTerminateGattMutexVariables()
4745 oc_mutex_free(g_bleServerBDAddressMutex);
4746 g_bleServerBDAddressMutex = NULL;
4748 oc_mutex_free(g_threadMutex);
4749 g_threadMutex = NULL;
4751 oc_mutex_free(g_threadSendMutex);
4752 g_threadSendMutex = NULL;
4754 oc_mutex_free(g_deviceListMutex);
4755 g_deviceListMutex = NULL;
4757 oc_mutex_free(g_SendFinishMutex);
4758 g_SendFinishMutex = NULL;
4760 oc_mutex_free(g_threadWriteCharacteristicMutex);
4761 g_threadWriteCharacteristicMutex = NULL;
4763 oc_mutex_free(g_deviceScanRetryDelayMutex);
4764 g_deviceScanRetryDelayMutex = NULL;
4766 oc_mutex_free(g_threadSendStateMutex);
4767 g_threadSendStateMutex = NULL;
4769 oc_mutex_free(g_threadScanIntervalMutex);
4770 g_threadScanIntervalMutex = NULL;
4772 oc_mutex_free(g_gattObjectMutex);
4773 g_gattObjectMutex = NULL;
4775 oc_mutex_free(g_deviceStateListMutex);
4776 g_deviceStateListMutex = NULL;
4778 oc_mutex_free(g_setValueMutex);
4779 g_setValueMutex = NULL;
4782 void CALEClientSetSendFinishFlag(bool flag)
4784 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
4786 oc_mutex_lock(g_SendFinishMutex);
4787 g_isFinishedSendData = flag;
4788 oc_mutex_unlock(g_SendFinishMutex);
4795 CAResult_t CAStartLEGattClient()
4797 // init mutex for send logic
4798 if (!g_deviceDescCond)
4800 g_deviceDescCond = oc_cond_new();
4805 g_threadCond = oc_cond_new();
4808 if (!g_threadWriteCharacteristicCond)
4810 g_threadWriteCharacteristicCond = oc_cond_new();
4813 if (!g_threadScanIntervalCond)
4815 g_threadScanIntervalCond = oc_cond_new();
4818 CAResult_t ret = CALEClientStartScanWithInterval();
4819 if (CA_STATUS_OK != ret)
4821 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
4825 g_isStartedLEClient = true;
4826 return CA_STATUS_OK;
4829 void CAStopLEGattClient()
4831 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
4833 VERIFY_NON_NULL_VOID(g_jvm, TAG, "g_jvm is null");
4836 bool isAttached = false;
4837 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
4841 CAResult_t ret = CALEClientDisconnectAll(env);
4842 if (CA_STATUS_OK != ret)
4844 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
4847 CALEClientStopScanWithInterval();
4849 oc_mutex_lock(g_threadWriteCharacteristicMutex);
4850 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
4851 oc_cond_signal(g_threadWriteCharacteristicCond);
4852 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
4854 CALEClientSetSendFinishFlag(true);
4855 oc_mutex_lock(g_threadMutex);
4856 OIC_LOG(DEBUG, TAG, "signal - g_threadCond cond");
4857 oc_cond_signal(g_threadCond);
4858 oc_mutex_unlock(g_threadMutex);
4860 oc_mutex_lock(g_deviceScanRetryDelayMutex);
4861 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4862 oc_cond_signal(g_deviceScanRetryDelayCond);
4863 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
4865 oc_mutex_lock(g_threadScanIntervalMutex);
4866 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4867 oc_cond_signal(g_threadScanIntervalCond);
4868 oc_mutex_unlock(g_threadScanIntervalMutex);
4870 oc_mutex_lock(g_threadSendMutex);
4871 OIC_LOG(DEBUG, TAG, "signal - g_deviceDesc cond");
4872 oc_cond_signal(g_deviceDescCond);
4873 oc_mutex_unlock(g_threadSendMutex);
4875 oc_cond_free(g_deviceDescCond);
4876 oc_cond_free(g_threadCond);
4877 oc_cond_free(g_threadWriteCharacteristicCond);
4878 oc_cond_free(g_deviceScanRetryDelayCond);
4879 oc_cond_free(g_threadScanIntervalCond);
4881 g_deviceDescCond = NULL;
4882 g_threadCond = NULL;
4883 g_threadWriteCharacteristicCond = NULL;
4884 g_deviceScanRetryDelayCond = NULL;
4885 g_threadScanIntervalCond = NULL;
4889 (*g_jvm)->DetachCurrentThread(g_jvm);
4894 CAResult_t CAInitializeLEGattClient()
4896 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
4897 CALEClientInitialize();
4898 return CA_STATUS_OK;
4901 void CATerminateLEGattClient()
4903 OIC_LOG(INFO, TAG, "IN - Terminate GATT Client");
4904 CAStopLEGattClient();
4905 CALEClientTerminate();
4906 OIC_LOG(INFO, TAG, "OUT - Terminate GATT Client");
4909 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
4910 uint32_t dataLen, CALETransferType_t type,
4913 OIC_LOG(INFO, TAG, "call CALEClientSendUnicastMessage");
4914 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
4916 if (LE_UNICAST != type || position < 0)
4918 OIC_LOG(ERROR, TAG, "this request is not unicast");
4919 return CA_STATUS_INVALID_PARAM;
4922 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4925 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4927 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4928 VERIFY_NON_NULL(data, TAG, "data is null");
4930 return CALEClientSendMulticastMessage(data, dataLen);
4933 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4936 g_CABLEClientDataReceivedCallback = callback;
4940 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4942 g_threadPoolHandle = handle;
4945 CAResult_t CAGetLEAddress(char **local_address)
4947 VERIFY_NON_NULL(local_address, TAG, "local_address");
4948 return CA_NOT_SUPPORTED;