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"
42 //#define TAG PCF("OIC_CA_LE_CLIENT")
43 #define TAG BLE_CLIENT_TAG
45 #define MICROSECS_PER_SEC 1000000
46 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
47 #define WAIT_TIME_SCAN_INTERVAL_DEFAULT 10
48 #define WAIT_TIME_SCANNED_CHECKING 30
50 #define GATT_CONNECTION_PRIORITY_BALANCED 0
51 #define GATT_FAILURE 257
52 #define GATT_INSUFFICIENT_AUTHENTICATION 5
53 #define GATT_INSUFFICIENT_ENCRYPTION 15
54 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
55 #define GATT_INVALID_OFFSET 7
56 #define GATT_READ_NOT_PERMITTED 2
57 #define GATT_REQUEST_NOT_SUPPORTED 6
58 #define GATT_WRITE_NOT_PERMITTED 3
61 #define BLE_SCAN_API_LEVEL (21) //(21)
62 #define BLE_MIN_API_LEVEL (18)
64 #define MANUFACTURE_ID 117
66 static ca_thread_pool_t g_threadPoolHandle = NULL;
69 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
70 static u_arraylist_t *g_gattObjectList = NULL;
71 static u_arraylist_t *g_deviceStateList = NULL;
73 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
74 static CABLEErrorHandleCallback g_clientErrorCallback;
75 static jobject g_leScanCallback = NULL;
76 static jobject g_leGattCallback = NULL;
77 static jobject g_context = NULL;
78 static jobjectArray g_uuidList = NULL;
80 // it will be prevent to start send logic when adapter has stopped.
81 static bool g_isStartedLEClient = false;
83 static jbyteArray g_sendBuffer = NULL;
84 static uint32_t g_targetCnt = 0;
85 static uint32_t g_currentSentCnt = 0;
86 static bool g_isFinishedSendData = false;
87 static oc_mutex g_SendFinishMutex = NULL;
88 static oc_mutex g_threadMutex = NULL;
89 static oc_cond g_threadCond = NULL;
90 static oc_cond g_deviceDescCond = NULL;
92 static oc_mutex g_threadSendMutex = NULL;
93 static oc_mutex g_threadWriteCharacteristicMutex = NULL;
94 static oc_cond g_threadWriteCharacteristicCond = NULL;
95 static bool g_isSignalSetFlag = false;
97 static oc_mutex g_bleServerBDAddressMutex = NULL;
99 static oc_mutex g_deviceListMutex = NULL;
100 static oc_mutex g_gattObjectMutex = NULL;
101 static oc_mutex g_deviceStateListMutex = NULL;
103 static oc_mutex g_deviceScanRetryDelayMutex = NULL;
104 static oc_cond g_deviceScanRetryDelayCond = NULL;
106 static oc_mutex g_threadScanIntervalMutex = NULL;
107 static oc_cond g_threadScanIntervalCond = NULL;
109 static oc_mutex g_threadSendStateMutex = NULL;
110 static oc_mutex g_setValueMutex = NULL;
112 static int32_t g_scanIntervalTime = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
113 static int32_t g_scanIntervalTimePrev = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
114 static int32_t g_intervalCount = 0;
115 static bool g_isWorkingScanThread = false;
116 static CALEScanState_t g_curScanningStep = BLE_SCAN_NONE;
117 static CALEScanState_t g_nextScanningStep = BLE_SCAN_ENABLE;
119 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
120 static int32_t g_jniIntSdk = -1;
122 static bool g_setHighQoS = true;
123 static bool g_setFullScanFlag = false;
124 jclass g_LEInterface = NULL;
125 static int g_manufactureDataCount = 0;
126 static int g_serviceUuidCount = 0;
128 // List of Service UUIDs
129 static u_arraylist_t* g_serviceUuidList = NULL;
131 // List of Manufacture Data
132 static u_arraylist_t* g_manufactureDataList = NULL;
135 * check if retry logic for connection routine has to be stopped or not.
136 * in case of error value including this method, connection routine has to be stopped.
137 * since there is no retry logic for this error reason in this client.
138 * @param state constant value of bluetoothgatt.
139 * @return true - waiting for background connection in BT platform.
140 * false - connection routine has to be stopped.
142 static bool CALECheckConnectionStateValue(jint state)
146 case GATT_CONNECTION_PRIORITY_BALANCED:
148 case GATT_INSUFFICIENT_AUTHENTICATION:
149 case GATT_INSUFFICIENT_ENCRYPTION:
150 case GATT_INVALID_ATTRIBUTE_LENGTH:
151 case GATT_INVALID_OFFSET:
152 case GATT_READ_NOT_PERMITTED:
153 case GATT_REQUEST_NOT_SUPPORTED:
154 case GATT_WRITE_NOT_PERMITTED:
162 * delete global reference for g_sendBuffer
163 * @param[in] env JNI interface pointer.
165 static void CALEDeleteSendBuffer(JNIEnv *env)
167 OIC_LOG(INFO, TAG, "CALEDeleteSendBuffer");
168 oc_mutex_lock(g_setValueMutex);
171 OIC_LOG(INFO, TAG, "delete send buffer");
172 (*env)->DeleteGlobalRef(env, g_sendBuffer);
175 oc_mutex_unlock(g_setValueMutex);
178 void CALEClientSetScanInterval(int32_t intervalTime, int32_t workingCount,
179 CALEScanState_t nextScanningStep)
181 OIC_LOG_V(DEBUG, TAG, "CALEClientSetScanInterval : %d -> %d, next scan state will be %d",
182 g_scanIntervalTime, intervalTime, nextScanningStep);
184 // previous time should be stored.
185 if (0 < workingCount)
187 g_scanIntervalTimePrev = g_scanIntervalTime;
189 g_scanIntervalTime = intervalTime;
190 g_intervalCount = workingCount;
191 g_nextScanningStep = nextScanningStep;
194 void CALERestartScanWithInterval(int32_t intervalTime, int32_t workingCount,
195 CALEScanState_t nextScanningStep)
197 if (intervalTime == g_scanIntervalTime
198 && workingCount == g_intervalCount
199 && nextScanningStep == g_nextScanningStep)
201 OIC_LOG(DEBUG, TAG, "setting duplicate interval time");
205 oc_mutex_lock(g_threadScanIntervalMutex);
206 CALEClientSetScanInterval(intervalTime, workingCount, nextScanningStep);
207 oc_cond_signal(g_threadScanIntervalCond);
208 oc_mutex_unlock(g_threadScanIntervalMutex);
211 static void CALEScanThread(void* object)
216 bool isAttached = false;
217 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
221 oc_mutex_lock(g_threadScanIntervalMutex);
222 while(g_isWorkingScanThread)
224 OIC_LOG(DEBUG, TAG, "scan waiting time out");
225 if (BLE_SCAN_ENABLE == g_curScanningStep)
228 CAResult_t ret = CALEClientStopScan();
229 if (CA_STATUS_OK != ret)
231 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
234 else if (BLE_SCAN_DISABLE == g_curScanningStep)
237 CAResult_t ret = CALEClientStartScan();
238 if (CA_STATUS_OK != ret)
240 OIC_LOG(INFO, TAG, "CALEClientStartScan has failed");
245 OIC_LOG(DEBUG, TAG, "scan thread is started");
247 CALEClientSetScanInterval(0, 0, BLE_SCAN_DISABLE);
250 OIC_LOG_V(DEBUG, TAG, "wait for Scan Interval Time during %d sec", g_scanIntervalTime);
251 if (OC_WAIT_SUCCESS == oc_cond_wait_for(g_threadScanIntervalCond,
252 g_threadScanIntervalMutex,
253 g_scanIntervalTime * MICROSECS_PER_SEC))
255 // called signal scan thread will be terminated
256 OIC_LOG(DEBUG, TAG, "signal scanInterval waiting");
257 if (BLE_SCAN_DISABLE == g_nextScanningStep)
259 g_curScanningStep = BLE_SCAN_ENABLE;
263 g_curScanningStep = BLE_SCAN_DISABLE;
268 if (BLE_SCAN_ENABLE == g_curScanningStep)
270 if (g_intervalCount > 0)
272 if (g_intervalCount == 1)
274 OIC_LOG(DEBUG, TAG, "reset default time");
275 CALEClientSetScanInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
278 OIC_LOG_V(DEBUG, TAG, "interval count : %d", g_intervalCount);
280 g_curScanningStep = BLE_SCAN_DISABLE;
284 g_curScanningStep = BLE_SCAN_ENABLE;
288 oc_mutex_unlock(g_threadScanIntervalMutex);
292 (*g_jvm)->DetachCurrentThread(g_jvm);
296 CAResult_t CALEClientStartScanWithInterval()
298 if (g_isWorkingScanThread)
300 OIC_LOG(DEBUG, TAG, "scan interval logic already running");
304 // initialize scan flags
305 g_curScanningStep = BLE_SCAN_NONE;
306 g_isWorkingScanThread = true;
308 g_scanIntervalTime = g_scanIntervalTimePrev;
309 g_nextScanningStep = BLE_SCAN_ENABLE;
311 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEScanThread, NULL, NULL))
313 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
314 g_isWorkingScanThread = false;
315 return CA_STATUS_FAILED;
321 void CALEClientStopScanWithInterval()
323 g_isWorkingScanThread = false;
324 oc_cond_signal(g_threadScanIntervalCond);
328 void CALEClientJniInit()
330 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
331 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
334 void CALEClientJNISetContext()
336 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
337 g_context = (jobject) CANativeJNIGetContext();
340 CAResult_t CALECreateJniInterfaceObject()
342 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
344 VERIFY_NON_NULL_RET(g_context, TAG, "g_context is null", CA_STATUS_FAILED);
345 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
348 bool isAttached = false;
349 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
350 return CA_STATUS_FAILED;
353 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
354 "getApplicationContext",
355 "()Landroid/content/Context;");
357 if (!mid_getApplicationContext)
359 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
360 return CA_STATUS_FAILED;
363 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
364 mid_getApplicationContext);
365 if (!jApplicationContext)
367 OIC_LOG(ERROR, TAG, "Could not get application context");
371 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
372 if (!jni_LEInterface)
374 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
377 g_LEInterface = (jclass)((*env)->NewGlobalRef(env, jni_LEInterface));
379 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
380 "(Landroid/content/Context;)V");
381 if (!LeInterfaceConstructorMethod)
383 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
387 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
388 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
392 (*g_jvm)->DetachCurrentThread(g_jvm);
398 CACheckJNIException(env);
401 (*g_jvm)->DetachCurrentThread(g_jvm);
404 return CA_STATUS_FAILED;
407 void CALEClientAddUuid(char* uuid, int uuid_type)
409 OIC_LOG(DEBUG, TAG, "CALEClientAddUuid");
410 VERIFY_NON_NULL_VOID(uuid, TAG, "uuid is null");
412 if (uuid_type == CA_LE_TYPE_CUSTOM_UUID)
414 if (g_manufactureDataCount == 0)
416 g_manufactureDataList = u_arraylist_create();
417 OIC_LOG(DEBUG, TAG, "List of manufacture data created");
419 for (int i = 0; i < g_manufactureDataCount; i++)
421 char *str = u_arraylist_get(g_manufactureDataList, i);
422 if (!strcmp(uuid, str))
424 OIC_LOG(DEBUG, TAG, "UUID already set before");
428 g_manufactureDataCount++;
429 bool result = u_arraylist_add(g_manufactureDataList, uuid);
430 OIC_LOG_V(DEBUG, TAG, "Adding manufacture data: %s", u_arraylist_get(g_manufactureDataList, g_manufactureDataCount - 1));
432 else //uuid_type == CA_LE_TYPE_SERVICE_UUID
434 if (g_serviceUuidCount == 0)
436 g_serviceUuidList = u_arraylist_create();
437 OIC_LOG(DEBUG, TAG, "List of service uuid created");
439 for (int i = 0; i < g_serviceUuidCount; i++)
441 char *str = u_arraylist_get(g_serviceUuidList, i);
442 if (!strcmp(uuid, str))
444 OIC_LOG(DEBUG, TAG, "UUID already set before");
448 g_serviceUuidCount++;
449 bool result = u_arraylist_add(g_serviceUuidList, uuid);
450 OIC_LOG_V(DEBUG, TAG, "Adding service UUID: %s", u_arraylist_get(g_serviceUuidList, g_serviceUuidCount - 1));
454 CAResult_t CALEClientInitialize()
456 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
459 CALEClientAddUuid(OIC_GATT_SERVICE_UUID, CA_LE_TYPE_SERVICE_UUID);
460 CALEClientAddUuid(OIC_GATT_CUSTOM_UUID, CA_LE_TYPE_CUSTOM_UUID);
461 CALEClientAddUuid(OIC_GATT_CUSTOM_UUID2, CA_LE_TYPE_CUSTOM_UUID);
462 CALEClientAddUuid(OIC_GATT_CUSTOM_UUID3, CA_LE_TYPE_CUSTOM_UUID);
464 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
467 bool isAttached = false;
468 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
469 return CA_STATUS_FAILED;
472 g_jniIntSdk = CALEGetBuildVersion(env);
473 if (g_jniIntSdk < BLE_MIN_API_LEVEL)
475 OIC_LOG(ERROR, TAG, "it is not supported");
479 (*g_jvm)->DetachCurrentThread(g_jvm);
481 return CA_STATUS_FAILED;
484 CAResult_t ret = CALEClientInitGattMutexVaraibles();
485 if (CA_STATUS_OK != ret)
487 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
488 CALEClientTerminateGattMutexVariables();
492 (*g_jvm)->DetachCurrentThread(g_jvm);
498 g_deviceDescCond = oc_cond_new();
500 // init mutex for send logic
501 g_threadCond = oc_cond_new();
502 g_threadWriteCharacteristicCond = oc_cond_new();
503 g_deviceScanRetryDelayCond = oc_cond_new();
504 g_threadScanIntervalCond = oc_cond_new();
506 CALEClientCreateDeviceList();
507 CALEClientJNISetContext();
509 ret = CALEClientCreateUUIDList();
510 if (CA_STATUS_OK != ret)
512 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
516 (*g_jvm)->DetachCurrentThread(g_jvm);
522 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
523 if (CA_STATUS_OK != ret)
525 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
529 (*g_jvm)->DetachCurrentThread(g_jvm);
534 g_isStartedLEClient = true;
538 (*g_jvm)->DetachCurrentThread(g_jvm);
544 void CALEClientTerminate()
546 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
548 VERIFY_NON_NULL_VOID(g_jvm, TAG, "g_jvm is null");
551 bool isAttached = false;
552 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
557 CAResult_t ret = CALEClientStopScan();
558 if (CA_STATUS_OK != ret)
560 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
563 if (g_leScanCallback)
565 (*env)->DeleteGlobalRef(env, g_leScanCallback);
566 g_leScanCallback = NULL;
569 if (g_leGattCallback)
571 (*env)->DeleteGlobalRef(env, g_leGattCallback);
572 g_leGattCallback = NULL;
577 (*env)->DeleteGlobalRef(env, g_LEInterface);
578 g_LEInterface = NULL;
581 u_arraylist_free(&g_serviceUuidList);
582 u_arraylist_free(&g_manufactureDataList);
584 CALEDeleteSendBuffer(env);
588 (*env)->DeleteGlobalRef(env, g_uuidList);
592 ret = CALERemoveAllDeviceState(g_deviceStateList,
593 g_deviceStateListMutex);
594 if (CA_STATUS_OK != ret)
596 OIC_LOG(ERROR, TAG, "CALERemoveAllDeviceState has failed");
599 oc_mutex_lock(g_deviceStateListMutex);
600 OICFree(g_deviceStateList);
601 g_deviceStateList = NULL;
602 oc_mutex_unlock(g_deviceStateListMutex);
604 ret = CALEClientRemoveAllScanDevices(env);
605 if (CA_STATUS_OK != ret)
607 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
610 ret = CALEClientRemoveAllGattObjs(env);
611 if (CA_STATUS_OK != ret)
613 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
616 CALEClientSetSendFinishFlag(true);
618 CALEClientTerminateGattMutexVariables();
619 CALEClientDestroyJniInterface();
621 oc_cond_free(g_deviceDescCond);
622 oc_cond_free(g_threadCond);
623 oc_cond_free(g_threadWriteCharacteristicCond);
624 oc_cond_free(g_deviceScanRetryDelayCond);
625 oc_cond_free(g_threadScanIntervalCond);
627 g_deviceDescCond = NULL;
629 g_threadWriteCharacteristicCond = NULL;
630 g_deviceScanRetryDelayCond = NULL;
631 g_threadScanIntervalCond = NULL;
633 g_isSignalSetFlag = false;
636 CALEClientStopScanWithInterval();
640 (*g_jvm)->DetachCurrentThread(g_jvm);
644 jobject CALEClientHiddenConnectGatt(jobject btDevice, const char* address, jboolean autoconnect)
646 OIC_LOG(INFO, TAG, "IN - CALEClientHiddenConnectGatt");
648 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", NULL);
651 bool isAttached = false;
652 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
656 jstring jni_address = (*env)->NewStringUTF(env, address);
657 jmethodID jni_connectGattHiddenMethod = (*env)->GetStaticMethodID(env, g_LEInterface,
658 "connectGattforHidden",
659 "(Landroid/bluetooth/BluetoothDevice;"
660 "Ljava/lang/String;Z)"
661 "Landroid/bluetooth/BluetoothGatt;");
662 if (!jni_connectGattHiddenMethod)
664 OIC_LOG(ERROR, TAG, "Could not get jni_connectGatt Hidden Method");
668 jobject gatt = (*env)->CallStaticObjectMethod(env, g_LEInterface,
669 jni_connectGattHiddenMethod,
670 btDevice, jni_address, autoconnect);
672 if (CACheckJNIException(env))
674 OIC_LOG(ERROR, TAG, "connectGattforHidden has failed");
678 OIC_LOG(INFO, TAG, "OUT - CALEClientHiddenConnectGatt");
682 (*g_jvm)->DetachCurrentThread(g_jvm);
688 CACheckJNIException(env);
693 (*g_jvm)->DetachCurrentThread(g_jvm);
699 CAResult_t CALEClientDestroyJniInterface()
701 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
703 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
706 bool isAttached = false;
707 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
708 return CA_STATUS_FAILED;
711 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
712 if (!jni_LeInterface)
714 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
718 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
719 "destroyLeInterface",
721 if (!jni_InterfaceDestroyMethod)
723 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
727 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
729 if (CACheckJNIException(env))
731 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
735 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
739 (*g_jvm)->DetachCurrentThread(g_jvm);
745 CACheckJNIException(env);
750 (*g_jvm)->DetachCurrentThread(g_jvm);
753 return CA_STATUS_FAILED;
756 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
758 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
759 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
763 CAResult_t res = CALEClientDisconnect(env, gatt);
764 if (CA_STATUS_OK != res)
766 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
769 CALEClientUpdateSendCnt(env);
772 CAResult_t CALEClientSendNegotiationMessage(const char* address)
774 VERIFY_NON_NULL(address, TAG, "address is null");
776 return CALEClientSendUnicastMessageImpl(address, NULL, 0);
779 CAResult_t CALEClientSendUnicastMessage(const char* address,
781 const uint32_t dataLen)
783 VERIFY_NON_NULL(address, TAG, "address is null");
784 VERIFY_NON_NULL(data, TAG, "data is null");
786 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
789 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
790 const uint32_t dataLen)
792 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
793 VERIFY_NON_NULL(data, TAG, "data is null");
795 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
798 bool isAttached = false;
799 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
800 return CA_STATUS_FAILED;
803 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
804 if (CA_STATUS_OK != ret)
806 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
811 (*g_jvm)->DetachCurrentThread(g_jvm);
817 CAResult_t CALEClientStartUnicastServer(const char* address)
822 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
824 return CA_NOT_SUPPORTED;
827 CAResult_t CALEClientStartMulticastServer()
829 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
831 return CA_NOT_SUPPORTED;
834 void CALEClientStopUnicastServer()
836 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
839 void CALEClientStopMulticastServer()
841 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
844 void CALEClientSetCallback(CAPacketReceiveCallback callback)
846 g_packetReceiveCallback = callback;
849 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
851 g_clientErrorCallback = callback;
854 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
856 VERIFY_NON_NULL(env, TAG, "env");
860 OIC_LOG(ERROR, TAG, "g_deviceList is not available");
861 return CA_STATUS_FAILED;
864 if (0 == u_arraylist_length(g_deviceList) // multicast
865 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
867 // Wait for LE peripherals to be discovered.
869 // Number of times to wait for discovery to complete.
870 static size_t const RETRIES = 5;
872 static uint64_t const TIMEOUT =
873 2 * MICROSECS_PER_SEC; // Microseconds
875 // set scan interval and start scan
876 CALERestartScanWithInterval(WAIT_TIME_SCANNED_CHECKING, 1, BLE_SCAN_ENABLE);
878 bool devicesDiscovered = false;
879 for (size_t i = 0; i < RETRIES; ++i)
881 OIC_LOG(DEBUG, TAG, "waiting for target device");
882 if (oc_cond_wait_for(g_deviceDescCond,
884 TIMEOUT) == OC_WAIT_SUCCESS)
886 OIC_LOG(DEBUG, TAG, "time out");
887 oc_mutex_lock(g_deviceListMutex);
888 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
889 oc_mutex_unlock(g_deviceListMutex);
891 if (0 < scannedDeviceLen)
893 if (!address // multicast
894 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
896 devicesDiscovered = true;
903 OIC_LOG(INFO, TAG, "waiting..");
905 oc_mutex_lock(g_deviceScanRetryDelayMutex);
906 if (oc_cond_wait_for(g_deviceScanRetryDelayCond,
907 g_deviceScanRetryDelayMutex,
908 MICROSECS_PER_SEC) == OC_WAIT_SUCCESS)
910 OIC_LOG(INFO, TAG, "finish to waiting for target device");
911 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
914 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
917 // checking whether a target device is found while waiting for time-out.
918 if (CALEClientIsDeviceInScanDeviceList(env, address))
920 devicesDiscovered = true;
929 // reset scan interval time after checking scanned devices
930 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
932 // time out for scanning devices
933 if (!devicesDiscovered)
935 return CA_STATUS_FAILED;
940 OIC_LOG(DEBUG, TAG, "there is a target device in the scanned devices");
947 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
948 const uint32_t dataLen)
950 OIC_LOG(INFO, TAG, "CALEClientSendUnicastMessageImpl in");
951 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
953 VERIFY_NON_NULL(address, TAG, "address is null");
955 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
958 bool isAttached = false;
959 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
960 return CA_STATUS_FAILED;
963 oc_mutex_lock(g_threadSendMutex);
965 CALEClientSetSendFinishFlag(false);
967 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
968 if (CA_STATUS_OK != ret)
970 OIC_LOG(INFO, TAG, "there is no scanned device");
974 if (g_context && g_deviceList)
976 uint32_t length = u_arraylist_length(g_deviceList);
977 for (uint32_t index = 0; index < length; index++)
979 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
982 OIC_LOG(ERROR, TAG, "jarrayObj is null");
986 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
989 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
993 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
996 OIC_LOG(ERROR, TAG, "setAddress is null");
997 CACheckJNIException(env);
1001 if (!strcasecmp(setAddress, address))
1003 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1004 (*env)->DeleteLocalRef(env, jni_setAddress);
1006 CALEDeleteSendBuffer(env);
1008 if (data && dataLen > 0)
1010 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1011 CACheckJNIException(env);
1012 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1013 CACheckJNIException(env);
1014 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1015 CACheckJNIException(env);
1018 // Target device to send message is just one.
1021 ret = CALEClientSendData(env, jarrayObj);
1022 if (CA_STATUS_OK != ret)
1024 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
1028 OIC_LOG(INFO, TAG, "wake up");
1031 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1032 (*env)->DeleteLocalRef(env, jni_setAddress);
1036 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
1038 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1039 // if there is no connection state.
1040 oc_mutex_lock(g_threadMutex);
1041 if (!g_isFinishedSendData)
1043 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1044 oc_cond_wait(g_threadCond, g_threadMutex);
1045 OIC_LOG(DEBUG, TAG, "connection / send is finished for unicast");
1047 oc_mutex_unlock(g_threadMutex);
1051 (*g_jvm)->DetachCurrentThread(g_jvm);
1054 oc_mutex_unlock(g_threadSendMutex);
1055 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
1056 if (CALEIsValidState(address, CA_LE_SEND_STATE,
1059 g_deviceStateListMutex))
1061 OIC_LOG(INFO, TAG, "send success");
1064 else if (CALEIsValidState(address, CA_LE_SEND_STATE,
1065 STATE_SEND_MTU_NEGO_SUCCESS,
1067 g_deviceStateListMutex))
1069 OIC_LOG(INFO, TAG, "mtu nego success");
1074 OIC_LOG(ERROR, TAG, "send failure");
1075 ret = CA_SEND_FAILED;
1079 CAResult_t resetRet = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
1082 g_deviceStateListMutex);
1083 if (CA_STATUS_OK != resetRet)
1085 OIC_LOG_V(ERROR, TAG, "CALEUpdateDeviceState has failed (%d)", resetRet);
1086 ret = CA_SEND_FAILED;
1095 (*g_jvm)->DetachCurrentThread(g_jvm);
1098 oc_mutex_unlock(g_threadSendMutex);
1099 return CA_SEND_FAILED;
1102 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
1103 const uint32_t dataLen)
1105 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
1106 VERIFY_NON_NULL(data, TAG, "data is null");
1107 VERIFY_NON_NULL(env, TAG, "env is null");
1111 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1112 return CA_STATUS_FAILED;
1115 oc_mutex_lock(g_threadSendMutex);
1117 CALEClientSetSendFinishFlag(false);
1119 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1120 CALEDeleteSendBuffer(env);
1122 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
1123 if (CA_STATUS_OK != res)
1125 OIC_LOG(INFO, TAG, "there is no scanned device");
1129 uint32_t length = u_arraylist_length(g_deviceList);
1130 g_targetCnt = length;
1132 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1133 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1134 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1136 for (uint32_t index = 0; index < length; index++)
1138 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1141 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
1145 res = CALEClientSendData(env, jarrayObj);
1146 if (res != CA_STATUS_OK)
1148 OIC_LOG(ERROR, TAG, "BT device - send has failed");
1152 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1154 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1155 oc_mutex_lock(g_threadMutex);
1156 if (!g_isFinishedSendData)
1158 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1159 oc_cond_wait(g_threadCond, g_threadMutex);
1160 OIC_LOG(DEBUG, TAG, "connection / send is finished for multicast");
1162 oc_mutex_unlock(g_threadMutex);
1163 oc_mutex_unlock(g_threadSendMutex);
1164 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1165 return CA_STATUS_OK;
1168 oc_mutex_unlock(g_threadSendMutex);
1169 OIC_LOG(ERROR, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1170 return CA_SEND_FAILED;
1173 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1175 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1176 VERIFY_NON_NULL(device, TAG, "device is null");
1177 VERIFY_NON_NULL(env, TAG, "env is null");
1179 // get BLE address from bluetooth device object.
1180 char* address = NULL;
1181 CALEState_t* state = NULL;
1182 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1185 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1186 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1189 OIC_LOG(ERROR, TAG, "address is not available");
1190 CACheckJNIException(env);
1191 return CA_STATUS_FAILED;
1193 oc_mutex_lock(g_deviceStateListMutex);
1194 state = CALEGetStateInfo(address, g_deviceStateList);
1195 oc_mutex_unlock(g_deviceStateListMutex);
1198 // Since disconnect event can be caused from BT stack while connection step is running.
1199 // DeviceState has to have current status for processing send failure.
1200 OIC_LOG(INFO, TAG, "set STATE_SEND_PREPARING");
1201 CAResult_t res = CALEClientUpdateDeviceStateWithBtDevice(env, device,
1203 STATE_SEND_PREPARING);
1204 if (CA_STATUS_OK != res)
1206 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceStateWithBtDevice has failed");
1209 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1211 return CA_STATUS_FAILED;
1216 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1218 // cancel previous connection request before connection
1219 // if there is gatt object in g_gattObjectList.
1222 jobject gatt = CALEClientGetGattObjInList(env, address);
1225 CAResult_t res = CALEClientDisconnect(env, gatt);
1226 if (CA_STATUS_OK != res)
1228 OIC_LOG(INFO, TAG, "there is no gatt object");
1231 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1234 // connection request
1235 jobject newGatt = CALEClientConnect(env, device,
1237 if (NULL == newGatt)
1239 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1240 return CA_STATUS_FAILED;
1245 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1246 STATE_SERVICE_CONNECTED,
1248 g_deviceStateListMutex))
1250 OIC_LOG(INFO, TAG, "GATT has already connected");
1252 jobject gatt = CALEClientGetGattObjInList(env, address);
1255 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1256 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1257 return CA_STATUS_FAILED;
1260 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1261 if (CA_STATUS_OK != ret)
1263 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1264 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1267 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1269 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1272 g_deviceStateListMutex))
1274 OIC_LOG(INFO, TAG, "service connecting...");
1276 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1279 g_deviceStateListMutex))
1281 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1283 // cancel previous connection request before connection
1284 // if there is gatt object in g_gattObjectList.
1287 jobject gatt = CALEClientGetGattObjInList(env, address);
1290 CAResult_t res = CALEClientDisconnect(env, gatt);
1291 if (CA_STATUS_OK != res)
1293 OIC_LOG(INFO, TAG, "there is no gatt object");
1296 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1299 OIC_LOG(DEBUG, TAG, "start to connect LE");
1300 jobject gatt = CALEClientConnect(env, device,
1301 CALEGetFlagFromState(env, jni_address,
1302 CA_LE_AUTO_CONNECT_FLAG,
1304 g_deviceStateListMutex));
1308 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1309 return CA_STATUS_FAILED;
1314 return CA_STATUS_OK;
1317 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1319 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1320 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1322 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1323 "()Landroid/bluetooth/BluetoothDevice;");
1324 if (!jni_mid_getDevice)
1326 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1330 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1331 if (!jni_obj_device)
1333 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1334 CACheckJNIException(env);
1338 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1341 OIC_LOG(ERROR, TAG, "jni_address is null");
1342 CACheckJNIException(env);
1352 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1355 OIC_LOG(DEBUG, TAG, "Gatt Close");
1356 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1357 VERIFY_NON_NULL(env, TAG, "env is null");
1359 // get BluetoothGatt method
1360 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1361 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1362 if (!jni_mid_closeGatt)
1364 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1365 return CA_STATUS_OK;
1368 // call disconnect gatt method
1369 OIC_LOG(DEBUG, TAG, "request to close GATT");
1370 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1372 if (CACheckJNIException(env))
1374 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1375 return CA_STATUS_FAILED;
1378 return CA_STATUS_OK;
1381 CAResult_t CALEClientStartScan()
1383 if (!g_isStartedLEClient)
1385 OIC_LOG(ERROR, TAG, "LE client is not started");
1386 return CA_STATUS_FAILED;
1389 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
1392 bool isAttached = false;
1393 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
1394 return CA_STATUS_FAILED;
1397 if(g_jniIntSdk < BLE_SCAN_API_LEVEL)
1399 g_setFullScanFlag = true;
1402 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1404 CAResult_t ret = CA_STATUS_OK;
1405 // scan gatt server with UUID
1406 if (g_leScanCallback && g_uuidList)
1408 if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
1410 if (!g_setFullScanFlag)
1412 //new uuid scan with callback
1413 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 will be called");
1414 ret = CALEClientStartScanWithUUIDImplForV21(env, g_uuidList, g_leScanCallback);
1418 //new full scan with callback
1419 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 will be called");
1420 ret = CALEClientStartScanImplForV21(env, g_leScanCallback);
1425 if (!g_setFullScanFlag)
1427 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl will be called");
1428 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1432 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl will be called");
1433 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1437 if (CA_STATUS_OK != ret)
1439 if (CA_ADAPTER_NOT_ENABLED == ret)
1441 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1445 OIC_LOG(ERROR, TAG, "start scan has failed");
1452 (*g_jvm)->DetachCurrentThread(g_jvm);
1458 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1460 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl IN");
1461 VERIFY_NON_NULL(callback, TAG, "callback is null");
1462 VERIFY_NON_NULL(env, TAG, "env is null");
1464 if (!CALEIsEnableBTAdapter(env))
1466 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1467 return CA_ADAPTER_NOT_ENABLED;
1470 // get default bt adapter class
1471 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1472 if (!jni_cid_BTAdapter)
1474 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1475 CACheckJNIException(env);
1476 return CA_STATUS_FAILED;
1479 // get remote bt adapter method
1480 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1481 "getDefaultAdapter",
1482 METHODID_OBJECTNONPARAM);
1483 if (!jni_mid_getDefaultAdapter)
1485 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1486 CACheckJNIException(env);
1487 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1488 return CA_STATUS_FAILED;
1491 // get start le scan method
1492 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1493 "(Landroid/bluetooth/BluetoothAdapter$"
1494 "LeScanCallback;)Z");
1495 if (!jni_mid_startLeScan)
1497 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1498 CACheckJNIException(env);
1499 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1500 return CA_STATUS_FAILED;
1503 // gat bt adapter object
1504 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1505 jni_mid_getDefaultAdapter);
1506 if (!jni_obj_BTAdapter)
1508 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1509 CACheckJNIException(env);
1510 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1511 return CA_STATUS_FAILED;
1514 // call start le scan method
1515 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1516 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1517 jni_mid_startLeScan, callback);
1518 if (!jni_obj_startLeScan)
1520 OIC_LOG(INFO, TAG, "startLeScan has failed");
1521 CACheckJNIException(env);
1525 OIC_LOG(DEBUG, TAG, "LeScan has started");
1528 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1529 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1530 return CA_STATUS_OK;
1533 CAResult_t CALEClientStartScanImplForV21(JNIEnv *env, jobject callback)
1535 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 IN");
1536 VERIFY_NON_NULL(callback, TAG, "callback is null");
1537 VERIFY_NON_NULL(env, TAG, "env is null");
1539 if (!CALEIsEnableBTAdapter(env))
1541 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1542 return CA_ADAPTER_NOT_ENABLED;
1545 CAResult_t res = CA_STATUS_FAILED;
1546 // get default bt adapter class
1547 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1548 if (!jni_cid_BTAdapter)
1550 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1551 CACheckJNIException(env);
1552 return CA_STATUS_FAILED;
1555 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1556 "getDefaultAdapter",
1557 "()Landroid/bluetooth/"
1558 "BluetoothAdapter;");
1559 if (!jni_mid_getDefaultAdapter)
1561 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1562 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1563 return CA_STATUS_FAILED;
1566 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1567 jni_mid_getDefaultAdapter);
1568 if (!jni_obj_BTAdapter)
1570 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1571 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1572 return CA_STATUS_FAILED;
1575 // get bluetoothLeScanner class
1576 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
1577 if (!jni_cid_leScanner)
1579 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
1580 CACheckJNIException(env);
1581 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1582 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1583 return CA_STATUS_FAILED;
1586 // get remote bt adapter method
1587 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1588 "getBluetoothLeScanner",
1589 "()Landroid/bluetooth/"
1590 "le/BluetoothLeScanner;");
1591 if (!jni_mid_getBluetoothLeScanner)
1593 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
1594 CACheckJNIException(env);
1598 // get startScan(ScanCallback callback) method
1599 jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner, "startScan",
1600 "(Landroid/bluetooth/le/ScanCallback;)V");
1601 if (!jni_mid_startScan)
1603 OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
1604 CACheckJNIException(env);
1608 // gat le scanner object
1609 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
1610 jni_mid_getBluetoothLeScanner);
1611 if (!jni_obj_leScanner)
1613 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
1614 CACheckJNIException(env);
1618 // call startScan method
1619 OIC_LOG(INFO, TAG, "CALL API - startScan(for level21)");
1620 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, callback);
1621 if (CACheckJNIException(env))
1623 OIC_LOG(INFO, TAG, "startScan has failed");
1624 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
1628 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
1631 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1632 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1633 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1637 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1639 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl IN");
1640 VERIFY_NON_NULL(callback, TAG, "callback is null");
1641 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1642 VERIFY_NON_NULL(env, TAG, "env is null");
1644 if (!CALEIsEnableBTAdapter(env))
1646 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1647 return CA_ADAPTER_NOT_ENABLED;
1650 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1651 if (!jni_cid_BTAdapter)
1653 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1654 CACheckJNIException(env);
1655 return CA_STATUS_FAILED;
1658 // get remote bt adapter method
1659 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1660 "getDefaultAdapter",
1661 METHODID_OBJECTNONPARAM);
1662 if (!jni_mid_getDefaultAdapter)
1664 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1665 CACheckJNIException(env);
1666 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1667 return CA_STATUS_FAILED;
1670 // get start le scan method
1671 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1672 "([Ljava/util/UUID;Landroid/bluetooth/"
1673 "BluetoothAdapter$LeScanCallback;)Z");
1674 if (!jni_mid_startLeScan)
1676 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1677 CACheckJNIException(env);
1678 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1679 return CA_STATUS_FAILED;
1682 // get bt adapter object
1683 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1684 jni_mid_getDefaultAdapter);
1685 if (!jni_obj_BTAdapter)
1687 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1688 CACheckJNIException(env);
1689 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1690 return CA_STATUS_FAILED;
1693 // call start le scan method
1694 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1695 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1696 jni_mid_startLeScan, uuids, callback);
1697 if (!jni_obj_startLeScan)
1699 OIC_LOG(INFO, TAG, "startLeScan has failed");
1700 CACheckJNIException(env);
1704 OIC_LOG(DEBUG, TAG, "LeScan has started");
1707 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1708 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1709 return CA_STATUS_OK;
1712 CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids, jobject callback)
1714 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 IN");
1715 VERIFY_NON_NULL(callback, TAG, "callback is null");
1716 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1717 VERIFY_NON_NULL(env, TAG, "env is null");
1720 if (!CALEIsEnableBTAdapter(env))
1722 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1723 return CA_ADAPTER_NOT_ENABLED;
1726 // get bluetoothLeScanner class
1727 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
1728 if (!jni_cid_leScanner)
1730 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
1731 CACheckJNIException(env);
1732 return CA_STATUS_FAILED;
1735 // get startScan(with UUID) method
1736 jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner,
1739 "Landroid/bluetooth/le/ScanSettings;"
1740 "Landroid/bluetooth/le/ScanCallback;"
1742 if (!jni_mid_startScan)
1744 OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
1745 CACheckJNIException(env);
1746 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1747 return CA_STATUS_FAILED;
1749 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1751 // get scanfilter.Builder class id
1752 jclass jni_cid_scanfilterBuilder = (*env)->FindClass(env,
1753 "android/bluetooth/le/"
1754 "ScanFilter$Builder");
1755 if (!jni_cid_scanfilterBuilder)
1757 OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilder is null");
1758 CACheckJNIException(env);
1759 return CA_STATUS_FAILED;
1762 // get scanfilter.Builder(ctor) method id
1763 jmethodID jni_mid_scanfilterBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1765 if (!jni_mid_scanfilterBuilderCtor)
1767 OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilderCtor is null");
1768 CACheckJNIException(env);
1769 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1770 return CA_STATUS_FAILED;
1773 // call scanfilter.Builder()
1774 jobject jni_obj_servicescanfilterBuilder[g_serviceUuidCount];
1775 for (i = 0; i < g_serviceUuidCount; i++)
1777 jni_obj_servicescanfilterBuilder[i] = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
1778 jni_mid_scanfilterBuilderCtor);
1779 if (!jni_obj_servicescanfilterBuilder[i])
1781 OIC_LOG_V(ERROR, TAG, "scanfilter: jni_obj_servicescanfilterBuilder[%d] is null", i);
1782 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1783 for (j = 0; j < i; j++)
1784 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[j]);
1785 return CA_STATUS_FAILED;
1789 // call scanfilter.Builder()
1790 jobject jni_obj_customscanfilterBuilder[g_manufactureDataCount];
1791 for (i = 0; i < g_manufactureDataCount; i++)
1793 jni_obj_customscanfilterBuilder[i] = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
1794 jni_mid_scanfilterBuilderCtor);
1795 if (!jni_obj_customscanfilterBuilder[i])
1797 OIC_LOG_V(ERROR, TAG, "scanfilter: jni_obj_customscanfilterBuilder[%d] is null", i);
1798 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1799 for (j = 0; j < i; j++)
1800 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1801 return CA_STATUS_FAILED;
1805 // get scanfilter.Builder.setServiceUuid method id
1806 jmethodID jni_mid_setServiceUuid = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1808 "(Landroid/os/ParcelUuid;)Landroid/"
1809 "bluetooth/le/ScanFilter$Builder;");
1810 if (!jni_mid_setServiceUuid)
1812 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setServiceUuid is null");
1813 CACheckJNIException(env);
1814 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1815 for (i = 0; i < g_serviceUuidCount; i++)
1817 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[i]);
1819 for (i = 0; i < g_manufactureDataCount; i++)
1821 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[i]);
1823 return CA_STATUS_FAILED;
1826 // get scanfilter.Builder.setManufacturerData method id
1827 jmethodID jni_mid_setManufacturerData = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1828 "setManufacturerData",
1830 "bluetooth/le/ScanFilter$Builder;");
1831 if (!jni_mid_setManufacturerData)
1833 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setManufacturerData is null");
1834 CACheckJNIException(env);
1835 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1836 for (i = 0; i < g_serviceUuidCount; i++)
1838 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[i]);
1840 for (i = 0; i < g_manufactureDataCount; i++)
1842 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[i]);
1844 return CA_STATUS_FAILED;
1846 // get scanfilter.Builder.build method id
1847 jmethodID jni_mid_build_scanfilterBuilder = (*env)->GetMethodID(env,
1848 jni_cid_scanfilterBuilder,
1850 "()Landroid/bluetooth/le/"
1852 if (!jni_mid_build_scanfilterBuilder)
1854 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_build_scanfilterBuilder is null");
1855 CACheckJNIException(env);
1856 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1857 for (i = 0; i < g_serviceUuidCount; i++)
1859 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[i]);
1861 for (i = 0; i < g_manufactureDataCount; i++)
1863 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[i]);
1865 return CA_STATUS_FAILED;
1867 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1869 jobject jni_obj_parcelUuid, jni_obj_setServiceUuid;
1870 jobject jni_obj_servicescanfilter[g_serviceUuidCount];
1872 for (i = 0; i < g_serviceUuidCount; i++)
1874 // call ParcelUuid.fromSting(uuid)
1875 jni_obj_parcelUuid = CALEGetParcelUuidFromString(env, u_arraylist_get(g_serviceUuidList, i));
1876 if (!jni_obj_parcelUuid)
1878 OIC_LOG(ERROR, TAG, "scanSettings: jni_obj_parcelUuid is null");
1879 CACheckJNIException(env);
1880 for (j = i; j < g_serviceUuidCount; j++)
1882 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[j]);
1884 for (j = 0; j < g_manufactureDataCount; j++)
1886 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1888 return CA_STATUS_FAILED;
1891 // call setServiceUuid(uuid)
1892 jni_obj_setServiceUuid = (*env)->CallObjectMethod(env,
1893 jni_obj_servicescanfilterBuilder[i],
1894 jni_mid_setServiceUuid,
1895 jni_obj_parcelUuid);
1896 if (!jni_obj_setServiceUuid)
1898 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setServiceUuid is null");
1899 CACheckJNIException(env);
1900 for (j = i; j < g_serviceUuidCount; j++)
1902 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[j]);
1904 for (j = 0; j < g_manufactureDataCount; j++)
1906 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1908 (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
1909 return CA_STATUS_FAILED;
1911 (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
1912 (*env)->DeleteLocalRef(env, jni_obj_setServiceUuid);
1915 jni_obj_servicescanfilter[i] = (*env)->CallObjectMethod(env,
1916 jni_obj_servicescanfilterBuilder[i],
1917 jni_mid_build_scanfilterBuilder);
1918 if (!jni_obj_servicescanfilter[i])
1920 OIC_LOG_V(ERROR, TAG, "scanfilter: jni_obj_scanfilter[%d] is null", i);
1921 CACheckJNIException(env);
1922 for (j = i; j < g_serviceUuidCount; j++)
1924 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[j]);
1926 for (j = 0; j < g_manufactureDataCount; j++)
1928 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1930 return CA_STATUS_FAILED;
1932 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[i]);
1934 OIC_LOG_V(DEBUG, TAG, "Total %d Service UUID based scanfilter(s) created by now", i + 1);
1938 jbyteArray jni_byte_manData;
1939 jobject jni_obj_setManufacturerData;
1940 jobject jni_obj_customscanfilter[g_manufactureDataCount];
1941 // set manufactererId
1942 jni_int_manId = MANUFACTURE_ID;
1944 // set custom scanfilters
1945 for (i = 0; i < g_manufactureDataCount; i++)
1947 // call utility function to set manufacturerData
1948 jni_byte_manData = CALEGetManufacturerData(env, u_arraylist_get(g_manufactureDataList, i));
1949 if (!jni_byte_manData)
1951 OIC_LOG(ERROR, TAG, "scanSettings: jni_byte_manData is null");
1952 CACheckJNIException(env);
1953 for(j = i; j < g_manufactureDataCount; j++)
1955 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1957 return CA_STATUS_FAILED;
1961 jni_obj_setManufacturerData = (*env)->CallObjectMethod(env,
1962 jni_obj_customscanfilterBuilder[i],
1963 jni_mid_setManufacturerData,
1966 if (!jni_obj_setManufacturerData)
1968 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setManufacturerData is null");
1969 CACheckJNIException(env);
1970 for (j = i; j < g_manufactureDataCount; j++)
1972 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1974 return CA_STATUS_FAILED;
1976 (*env)->DeleteLocalRef(env, jni_byte_manData);
1977 (*env)->DeleteLocalRef(env, jni_obj_setManufacturerData);
1980 jni_obj_customscanfilter[i] = (*env)->CallObjectMethod(env,
1981 jni_obj_customscanfilterBuilder[i],
1982 jni_mid_build_scanfilterBuilder);
1983 if (!jni_obj_customscanfilter[i])
1985 OIC_LOG_V(ERROR, TAG, "scanfilter: jni_obj_customscanfilter[%d] is null", i);
1986 CACheckJNIException(env);
1987 for (j = i; j < g_manufactureDataCount; j++)
1989 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1991 return CA_STATUS_FAILED;
1993 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[i]);
1995 OIC_LOG_V(DEBUG, TAG, "Total %d manufacture data based scanfilter(s) created by now", i + 1);
1998 // get scanSettings.Builder class id
1999 jclass jni_cid_scanSettingsBuilder = (*env)->FindClass(env,
2000 "android/bluetooth/le/"
2001 "ScanSettings$Builder");
2002 if (!jni_cid_scanSettingsBuilder)
2004 OIC_LOG(ERROR, TAG, "scanSettings: jni_cid_scanSettingsBuilder is null");
2005 CACheckJNIException(env);
2006 for (j = 0; j< g_serviceUuidCount; j++)
2008 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2010 for (j = 0; j< g_manufactureDataCount; j++)
2012 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2014 return CA_STATUS_FAILED;
2017 // get scanSettings.Builder(ctor) method id
2018 jmethodID jni_mid_scanSettingsBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
2020 if (!jni_mid_scanSettingsBuilderCtor)
2022 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_scanSettingsBuilderCtor is null");
2023 CACheckJNIException(env);
2024 for (j = 0; j< g_serviceUuidCount; j++)
2026 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2028 for (j = 0; j< g_manufactureDataCount; j++)
2030 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2032 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2033 return CA_STATUS_FAILED;
2036 // get scanSettings.Builder.setScanMode method id
2037 jmethodID jni_mid_setScanMode = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
2040 "bluetooth/le/ScanSettings$Builder;");
2041 if (!jni_mid_setScanMode)
2043 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_setScanMode is null");
2044 CACheckJNIException(env);
2045 for (j = 0; j< g_serviceUuidCount; j++)
2047 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2049 for (j = 0; j< g_manufactureDataCount; j++)
2051 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2053 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2054 return CA_STATUS_FAILED;
2057 // get scanSettings.Builder.build method id
2058 jmethodID jni_mid_build_scanSettings = (*env)->GetMethodID(env,
2059 jni_cid_scanSettingsBuilder,
2061 "()Landroid/bluetooth/le/"
2063 if (!jni_mid_build_scanSettings)
2065 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_build_scanSettings is null");
2066 CACheckJNIException(env);
2067 for (j = 0; j< g_serviceUuidCount; j++)
2069 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2071 for (j = 0; j< g_manufactureDataCount; j++)
2073 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2075 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2076 return CA_STATUS_FAILED;
2079 // call scanSettings.Builder()
2080 jobject jni_obj_scanSettingBuilder = (*env)->NewObject(env, jni_cid_scanSettingsBuilder,
2081 jni_mid_scanSettingsBuilderCtor);
2082 if (!jni_obj_scanSettingBuilder)
2084 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettingBuilder is null");
2085 CACheckJNIException(env);
2086 for (j = 0; j< g_serviceUuidCount; j++)
2088 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2090 for (j = 0; j< g_manufactureDataCount; j++)
2092 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2094 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2095 return CA_STATUS_FAILED;
2097 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2099 jclass jni_cid_arrayList = (*env)->FindClass(env, "java/util/ArrayList");
2100 if (!jni_cid_arrayList)
2102 OIC_LOG(ERROR, TAG, "ArrayList: jni_cid_arrayList is null");
2103 CACheckJNIException(env);
2104 for (j = 0; j< g_serviceUuidCount; j++)
2106 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2108 for (j = 0; j< g_manufactureDataCount; j++)
2110 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2112 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2113 return CA_STATUS_FAILED;
2116 jmethodID jni_mid_arrayListCtor = (*env)->GetMethodID(env, jni_cid_arrayList, "<init>", "()V");
2117 if (!jni_mid_arrayListCtor)
2119 OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListCtor is null");
2120 CACheckJNIException(env);
2121 for (j = 0; j< g_serviceUuidCount; j++)
2123 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2125 for (j = 0; j< g_manufactureDataCount; j++)
2127 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2129 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2130 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2131 return CA_STATUS_FAILED;
2134 jmethodID jni_mid_arrayListAdd = (*env)->GetMethodID(env, jni_cid_arrayList,
2135 "add", "(Ljava/lang/Object;)Z");
2136 if (!jni_mid_arrayListAdd)
2138 OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListAdd is null");
2139 CACheckJNIException(env);
2140 for (j = 0; j< g_serviceUuidCount; j++)
2142 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2144 for (j = 0; j< g_manufactureDataCount; j++)
2146 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2148 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2149 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2150 return CA_STATUS_FAILED;
2153 jobject jni_obj_filterList = (*env)->NewObject(env, jni_cid_arrayList, jni_mid_arrayListCtor);
2154 if (!jni_obj_filterList)
2156 OIC_LOG(ERROR, TAG, "ArrayList: jni_obj_filterList is null");
2157 for (j = 0; j< g_serviceUuidCount; j++)
2159 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2161 for (j = 0; j< g_manufactureDataCount; j++)
2163 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2165 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2166 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2167 return CA_STATUS_FAILED;
2169 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2171 jboolean jni_bool_arrayListIsAdded;
2172 for (i = 0; i < g_serviceUuidCount; i++)
2174 jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
2175 jni_mid_arrayListAdd,
2176 jni_obj_servicescanfilter[i]);
2177 if (!jni_bool_arrayListIsAdded)
2179 OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
2180 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2181 for(j = i; j < g_serviceUuidCount; j++)
2183 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2185 for(j = 0; j < g_manufactureDataCount; j++)
2187 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2189 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2190 return CA_STATUS_FAILED;
2192 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[i]);
2193 OIC_LOG_V(INFO, TAG, "%d st/nd/th service uuid based scanFilters Added", i + 1);
2196 for (i = 0; i < g_manufactureDataCount; i++)
2198 jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
2199 jni_mid_arrayListAdd,
2200 jni_obj_customscanfilter[i]);
2201 if (!jni_bool_arrayListIsAdded)
2203 OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
2204 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2205 for(j = i; j < g_manufactureDataCount; j++)
2207 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2209 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2210 return CA_STATUS_FAILED;
2212 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[i]);
2213 OIC_LOG_V(INFO, TAG, "%d st/nd/th manufacture data based scanFilters Added", i + 1);
2216 OIC_LOG(INFO, TAG, "All ScanFilters Added");
2217 // get ScanSettings.SCAN_MODE_BALANCED jint value
2218 jint jni_int_scanBalancedMode = CALEGetConstantsValue(env, CLASSPATH_LE_SCANSETTINGS,
2219 "SCAN_MODE_BALANCED");
2220 CACheckJNIException(env);
2222 // call setScanMode(SCAN_MODE_BALANCED)
2223 jobject jni_obj_setScanMode = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
2224 jni_mid_setScanMode,
2225 jni_int_scanBalancedMode);
2226 if (!jni_obj_setScanMode)
2228 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setScanMode is null");
2229 CACheckJNIException(env);
2230 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2231 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2232 return CA_STATUS_FAILED;
2236 jobject jni_obj_scanSettings = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
2237 jni_mid_build_scanSettings);
2238 if (!jni_obj_scanSettings)
2240 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettings is null");
2241 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2242 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2243 return CA_STATUS_FAILED;
2245 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2247 CAResult_t res = CA_STATUS_FAILED;
2249 // get default bt adapter class
2250 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2251 if (!jni_cid_BTAdapter)
2253 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2254 CACheckJNIException(env);
2258 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2259 "getDefaultAdapter",
2260 "()Landroid/bluetooth/"
2261 "BluetoothAdapter;");
2262 if (!jni_mid_getDefaultAdapter)
2264 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2265 CACheckJNIException(env);
2266 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2270 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2271 jni_mid_getDefaultAdapter);
2272 if (!jni_obj_BTAdapter)
2274 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2275 CACheckJNIException(env);
2276 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2280 // get remote bt adapter method
2281 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2282 "getBluetoothLeScanner",
2283 "()Landroid/bluetooth/"
2284 "le/BluetoothLeScanner;");
2285 if (!jni_mid_getBluetoothLeScanner)
2287 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
2288 CACheckJNIException(env);
2289 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2290 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2294 // get le scanner object
2295 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
2296 jni_mid_getBluetoothLeScanner);
2297 if (!jni_obj_leScanner)
2299 OIC_LOG(ERROR, TAG, "jni_obj_leScanner is null");
2300 CACheckJNIException(env);
2301 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2302 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2305 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2306 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2308 // call startScan method
2309 OIC_LOG(INFO, TAG, "CALL API - startScanWithUUID(for level 21)");
2310 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, jni_obj_filterList,
2311 jni_obj_scanSettings, callback);
2312 if (CACheckJNIException(env))
2314 OIC_LOG(INFO, TAG, "startScan has failed");
2320 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2323 (*env)->DeleteLocalRef(env, jni_obj_scanSettings);
2324 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2328 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
2330 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
2331 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2334 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2337 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
2341 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
2342 "(Ljava/lang/String;)"
2343 "Ljava/util/UUID;");
2344 if (!jni_mid_fromString)
2346 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
2350 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
2351 CACheckJNIException(env);
2352 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
2356 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2360 return jni_obj_uuid;
2363 CACheckJNIException(env);
2367 CAResult_t CALEClientStopScan()
2369 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
2372 bool isAttached = false;
2373 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
2374 return CA_STATUS_FAILED;
2377 CAResult_t ret = CA_STATUS_FAILED;
2379 if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
2381 ret = CALEClientStopScanImplForV21(env, g_leScanCallback);
2385 ret = CALEClientStopScanImpl(env, g_leScanCallback);
2388 if (CA_STATUS_OK != ret)
2390 if (CA_ADAPTER_NOT_ENABLED == ret)
2392 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
2396 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
2402 (*g_jvm)->DetachCurrentThread(g_jvm);
2408 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
2410 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl IN");
2411 VERIFY_NON_NULL(callback, TAG, "callback is null");
2412 VERIFY_NON_NULL(env, TAG, "env is null");
2414 if (!CALEIsEnableBTAdapter(env))
2416 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2417 return CA_ADAPTER_NOT_ENABLED;
2420 // get default bt adapter class
2421 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2422 if (!jni_cid_BTAdapter)
2424 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2425 CACheckJNIException(env);
2426 return CA_STATUS_FAILED;
2429 // get remote bt adapter method
2430 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2431 "getDefaultAdapter",
2432 METHODID_OBJECTNONPARAM);
2433 if (!jni_mid_getDefaultAdapter)
2435 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2436 CACheckJNIException(env);
2437 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2438 return CA_STATUS_FAILED;
2441 // get start le scan method
2442 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
2443 "(Landroid/bluetooth/"
2444 "BluetoothAdapter$LeScanCallback;)V");
2445 if (!jni_mid_stopLeScan)
2447 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
2448 CACheckJNIException(env);
2449 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2450 return CA_STATUS_FAILED;
2453 // get bt adapter object
2454 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2455 jni_mid_getDefaultAdapter);
2456 if (!jni_obj_BTAdapter)
2458 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2459 CACheckJNIException(env);
2460 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2461 return CA_STATUS_FAILED;
2464 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
2465 // call start le scan method
2466 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
2467 if (CACheckJNIException(env))
2469 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
2470 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2471 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2472 return CA_STATUS_FAILED;
2475 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2476 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2477 return CA_STATUS_OK;
2480 CAResult_t CALEClientStopScanImplForV21(JNIEnv *env, jobject callback)
2482 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImplForV21 IN");
2483 VERIFY_NON_NULL(callback, TAG, "callback is null");
2484 VERIFY_NON_NULL(env, TAG, "env is null");
2486 if (!CALEIsEnableBTAdapter(env))
2488 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2489 return CA_ADAPTER_NOT_ENABLED;
2492 // get default bt adapter class
2493 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2494 if (!jni_cid_BTAdapter)
2496 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2497 CACheckJNIException(env);
2498 return CA_STATUS_FAILED;
2501 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2502 "getDefaultAdapter",
2503 "()Landroid/bluetooth/"
2504 "BluetoothAdapter;");
2505 if (!jni_mid_getDefaultAdapter)
2507 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2508 CACheckJNIException(env);
2509 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2510 return CA_STATUS_FAILED;
2513 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2514 jni_mid_getDefaultAdapter);
2515 if (!jni_obj_BTAdapter)
2517 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2518 CACheckJNIException(env);
2519 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2520 return CA_STATUS_FAILED;
2523 // get bluetoothLeScanner class
2524 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
2525 if (!jni_cid_leScanner)
2527 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
2528 CACheckJNIException(env);
2529 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2530 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2531 return CA_STATUS_FAILED;
2534 // get remote bt adapter method
2535 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2536 "getBluetoothLeScanner",
2537 "()Landroid/bluetooth/"
2538 "le/BluetoothLeScanner;");
2539 if (!jni_mid_getBluetoothLeScanner)
2541 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
2542 CACheckJNIException(env);
2543 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2544 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2545 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2546 return CA_STATUS_FAILED;
2548 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2550 // get stopScan(ScanCallback callback) method
2551 jmethodID jni_mid_stopScan = (*env)->GetMethodID(env, jni_cid_leScanner, "stopScan",
2552 "(Landroid/bluetooth/le/ScanCallback;)V");
2553 if (!jni_mid_stopScan)
2555 OIC_LOG(ERROR, TAG, "stopScan: jni_mid_stopScan is null");
2556 CACheckJNIException(env);
2557 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2558 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2559 return CA_STATUS_FAILED;
2561 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2563 // gat le scanner object
2564 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
2565 jni_mid_getBluetoothLeScanner);
2566 if (!jni_obj_leScanner)
2568 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
2569 CACheckJNIException(env);
2570 return CA_STATUS_FAILED;
2573 // call stopScan method
2574 OIC_LOG(INFO, TAG, "CALL API - stopScan for level 21");
2575 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_stopScan, callback);
2576 if (CACheckJNIException(env))
2578 OIC_LOG(INFO, TAG, "stopScan for level 21 has failed");
2579 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2580 return CA_STATUS_FAILED;
2583 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2584 return CA_STATUS_OK;
2587 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2589 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
2590 VERIFY_NON_NULL(env, TAG, "env is null");
2591 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
2593 oc_mutex_lock(g_threadSendMutex);
2595 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
2598 OIC_LOG(ERROR, TAG, "jni_address is not available");
2599 oc_mutex_unlock(g_threadSendMutex);
2600 return CA_STATUS_FAILED;
2603 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2606 OIC_LOG(ERROR, TAG, "address is not available");
2607 CACheckJNIException(env);
2608 oc_mutex_unlock(g_threadSendMutex);
2609 return CA_STATUS_FAILED;
2612 CAResult_t res = CA_STATUS_OK;
2613 if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2616 g_deviceStateListMutex))
2618 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
2619 if (NULL == newGatt)
2621 OIC_LOG(INFO, TAG, "newGatt is not available");
2622 res = CA_STATUS_FAILED;
2625 oc_mutex_unlock(g_threadSendMutex);
2630 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2632 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
2633 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2634 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
2636 // reset scan interval time after checking scanned devices
2637 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
2639 // since there is no callback related stop success
2640 // and scanning should be stopped before connectGatt is called.
2641 // it should wait a few micro seconds.
2644 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
2645 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
2648 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2651 OIC_LOG(ERROR, TAG, "address is not available");
2655 // close the gatt service
2656 jobject gatt = CALEClientGetGattObjInList(env, address);
2659 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
2660 if (CA_STATUS_OK != res)
2662 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
2663 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2667 // clean previous gatt object after close profile service
2668 res = CALEClientRemoveGattObjForAddr(env, jni_address);
2669 if (CA_STATUS_OK != res)
2671 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
2672 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2676 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2679 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
2682 OIC_LOG(DEBUG, TAG, "re-connection will be started");
2686 // add new gatt object into g_gattObjectList
2687 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
2688 if (CA_STATUS_OK != res)
2690 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
2697 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2699 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
2700 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2701 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
2703 if (!g_leGattCallback)
2705 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
2709 if (!CALEIsEnableBTAdapter(env))
2711 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2715 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
2718 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
2722 jobject jni_obj_connectGatt = NULL;
2723 jint jni_int_sdk = CALEGetBuildVersion(env);
2724 OIC_LOG_V(INFO, TAG, "API level is %d", jni_int_sdk);
2725 if (jni_int_sdk >= 23) // upper than API level 23
2727 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
2729 "(Landroid/content/Context;ZLandroid/"
2730 "bluetooth/BluetoothGattCallback;I)"
2731 "Landroid/bluetooth/BluetoothGatt;");
2732 if (!jni_mid_connectGatt)
2734 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
2738 jint jni_transport_le = CALEGetConstantsValue(env, CLASSPATH_BT_DEVICE, "TRANSPORT_LE");
2739 OIC_LOG_V(INFO, TAG, "CALL API - connectGatt with transport LE(%d)", jni_transport_le);
2740 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
2741 jni_mid_connectGatt, NULL,
2742 autoconnect, g_leGattCallback,
2744 if (!jni_obj_connectGatt)
2746 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
2747 CACheckJNIException(env);
2748 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
2749 CALEClientUpdateSendCnt(env);
2754 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
2757 else // lower than API level 23
2760 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2763 OIC_LOG(ERROR, TAG, "GetStringUTFChars has failed");
2766 OIC_LOG(INFO, TAG, "CALL API - connectGatt for hidden");
2767 jni_obj_connectGatt = CALEClientHiddenConnectGatt(bluetoothDevice, address, autoconnect);
2771 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
2773 "(Landroid/content/Context;ZLandroid/"
2774 "bluetooth/BluetoothGattCallback;)"
2775 "Landroid/bluetooth/BluetoothGatt;");
2776 if (!jni_mid_connectGatt)
2778 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
2782 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
2783 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
2784 jni_mid_connectGatt,
2786 autoconnect, g_leGattCallback);
2788 if (!jni_obj_connectGatt)
2790 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
2791 CACheckJNIException(env);
2792 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
2793 CALEClientUpdateSendCnt(env);
2798 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
2803 return jni_obj_connectGatt;
2806 bool CALEClientIsConnected(const char* address)
2808 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2809 STATE_SERVICE_CONNECTED,
2811 g_deviceStateListMutex))
2813 OIC_LOG(DEBUG, TAG, "current state is connected");
2816 OIC_LOG(DEBUG, TAG, "current state is not connected");
2820 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
2822 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
2824 VERIFY_NON_NULL(env, TAG, "env is null");
2825 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2827 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2828 if (!jni_cid_BTAdapter)
2830 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
2834 // get remote bt adapter method
2835 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2836 "getDefaultAdapter",
2837 METHODID_OBJECTNONPARAM);
2838 if (!jni_mid_getDefaultAdapter)
2840 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2844 // gat bt adapter object
2845 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2846 jni_mid_getDefaultAdapter);
2847 if (!jni_obj_BTAdapter)
2849 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2853 // get closeProfileProxy method
2854 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2855 "closeProfileProxy",
2856 "(ILandroid/bluetooth/"
2857 "BluetoothProfile;)V");
2858 if (!jni_mid_closeProfileProxy)
2860 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
2864 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
2865 if (!jni_cid_BTProfile)
2867 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
2871 // GATT - Constant value : 7 (0x00000007)
2872 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
2876 OIC_LOG(ERROR, TAG, "id_gatt is null");
2880 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
2881 CACheckJNIException(env);
2883 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
2884 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
2885 if (CACheckJNIException(env))
2887 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
2888 return CA_STATUS_FAILED;
2891 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
2892 return CA_STATUS_OK;
2895 CACheckJNIException(env);
2896 return CA_STATUS_FAILED;
2900 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
2902 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
2903 VERIFY_NON_NULL(env, TAG, "env is null");
2904 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2906 // get BluetoothGatt method
2907 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
2908 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2909 "disconnect", "()V");
2910 if (!jni_mid_disconnectGatt)
2912 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
2913 return CA_STATUS_FAILED;
2916 // call disconnect gatt method
2917 OIC_LOG(INFO, TAG, "CALL API - disconnect");
2918 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
2919 if (CACheckJNIException(env))
2921 OIC_LOG(ERROR, TAG, "disconnect has failed");
2922 return CA_STATUS_FAILED;
2925 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
2927 return CA_STATUS_OK;
2930 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
2932 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
2933 VERIFY_NON_NULL(env, TAG, "env is null");
2935 if (!g_gattObjectList)
2937 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2938 return CA_STATUS_OK;
2941 uint32_t length = u_arraylist_length(g_gattObjectList);
2942 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
2943 for (uint32_t index = 0; index < length; index++)
2945 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
2946 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2949 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2952 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2953 if (CA_STATUS_OK != res)
2955 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2960 return CA_STATUS_OK;
2963 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
2965 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
2966 VERIFY_NON_NULL(env, TAG, "env is null");
2968 if (!g_gattObjectList)
2970 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2971 return CA_STATUS_OK;
2974 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
2977 OIC_LOG(ERROR, TAG, "address is null");
2978 CACheckJNIException(env);
2979 return CA_STATUS_FAILED;
2982 uint32_t length = u_arraylist_length(g_gattObjectList);
2983 for (uint32_t index = 0; index < length; index++)
2985 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2988 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2992 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2993 if (!jni_setAddress)
2995 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2996 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2997 return CA_STATUS_FAILED;
3000 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3003 OIC_LOG(ERROR, TAG, "setAddress is null");
3004 CACheckJNIException(env);
3005 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3006 return CA_STATUS_FAILED;
3009 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
3010 if (!strcasecmp(address, setAddress))
3012 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
3013 if (CA_STATUS_OK != res)
3015 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
3016 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3017 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3018 return CA_STATUS_FAILED;
3020 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3021 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3022 return CA_STATUS_OK;
3024 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3026 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3028 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
3029 return CA_STATUS_OK;
3032 CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size)
3034 VERIFY_NON_NULL(env, TAG, "env is null");
3035 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3037 if (!CALEIsEnableBTAdapter(env))
3039 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3040 return CA_ADAPTER_NOT_ENABLED;
3043 // get BluetoothGatt.requestMtu method
3044 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.requestMtu method");
3045 jmethodID jni_mid_requestMtu = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3046 "requestMtu", "(I)Z");
3047 if (!jni_mid_requestMtu)
3049 OIC_LOG(ERROR, TAG, "jni_mid_requestMtu is null");
3050 return CA_STATUS_FAILED;
3054 OIC_LOG(INFO, TAG, "CALL API - requestMtu");
3055 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_requestMtu, size);
3058 OIC_LOG(ERROR, TAG, "requestMtu has failed");
3059 CACheckJNIException(env);
3060 return CA_STATUS_FAILED;
3063 return CA_STATUS_OK;
3066 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
3068 VERIFY_NON_NULL(env, TAG, "env is null");
3069 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3071 if (!CALEIsEnableBTAdapter(env))
3073 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3074 return CA_ADAPTER_NOT_ENABLED;
3077 // get BluetoothGatt.discoverServices method
3078 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
3079 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3080 "discoverServices", "()Z");
3081 if (!jni_mid_discoverServices)
3083 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
3084 return CA_STATUS_FAILED;
3087 // call disconnect gatt method
3088 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
3089 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
3092 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
3093 CACheckJNIException(env);
3094 return CA_STATUS_FAILED;
3097 return CA_STATUS_OK;
3100 static void CALEWriteCharacteristicThread(void* object)
3102 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
3103 VERIFY_NON_NULL_VOID(g_jvm, TAG, "g_jvm is null");
3106 bool isAttached = false;
3107 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
3111 jobject gatt = (jobject)object;
3112 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
3113 if (CA_STATUS_OK != ret)
3115 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
3120 (*g_jvm)->DetachCurrentThread(g_jvm);
3124 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
3126 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
3128 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3129 VERIFY_NON_NULL(env, TAG, "env is null");
3131 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3134 CALEClientSendFinish(env, gatt);
3135 return CA_STATUS_FAILED;
3138 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3141 CACheckJNIException(env);
3142 CALEClientSendFinish(env, gatt);
3143 return CA_STATUS_FAILED;
3146 oc_mutex_lock(g_threadSendStateMutex);
3148 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING,
3150 g_deviceStateListMutex))
3152 OIC_LOG(INFO, TAG, "current state is SENDING");
3153 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3154 oc_mutex_unlock(g_threadSendStateMutex);
3155 return CA_STATUS_OK;
3158 if (CA_STATUS_OK != CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
3161 g_deviceStateListMutex))
3163 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
3164 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3165 CALEClientSendFinish(env, gatt);
3166 oc_mutex_unlock(g_threadSendStateMutex);
3167 return CA_STATUS_FAILED;
3170 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3172 oc_mutex_unlock(g_threadSendStateMutex);
3174 jbyteArray sendData = NULL;
3175 oc_mutex_lock(g_setValueMutex);
3178 OIC_LOG(INFO, TAG, "alloc local reference for data");
3179 sendData = (jbyteArray)(*env)->NewLocalRef(env, g_sendBuffer);
3183 OIC_LOG(ERROR, TAG, "send Buffer is empty");
3184 oc_mutex_unlock(g_setValueMutex);
3185 return CA_STATUS_FAILED;
3187 oc_mutex_unlock(g_setValueMutex);
3190 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, sendData);
3191 if (!jni_obj_character)
3195 (*env)->DeleteLocalRef(env, sendData);
3197 CALEClientSendFinish(env, gatt);
3198 return CA_STATUS_FAILED;
3203 (*env)->DeleteLocalRef(env, sendData);
3206 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
3207 if (CA_STATUS_OK != ret)
3209 CALEClientSendFinish(env, gatt);
3210 return CA_STATUS_FAILED;
3213 // wait for callback for write Characteristic with success to sent data
3214 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
3215 oc_mutex_lock(g_threadWriteCharacteristicMutex);
3216 if (!g_isSignalSetFlag)
3218 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
3219 if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
3220 g_threadWriteCharacteristicMutex,
3221 WAIT_TIME_WRITE_CHARACTERISTIC))
3223 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
3224 g_isSignalSetFlag = false;
3225 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3226 return CA_STATUS_FAILED;
3229 // reset flag set by writeCharacteristic Callback
3230 g_isSignalSetFlag = false;
3231 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3233 CALEClientUpdateSendCnt(env);
3235 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
3236 return CA_STATUS_OK;
3239 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
3241 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
3242 VERIFY_NON_NULL(env, TAG, "env is null");
3243 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3245 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
3246 CACheckJNIException(env);
3247 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEWriteCharacteristicThread,
3248 (void*)gattParam, NULL))
3250 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
3251 return CA_STATUS_FAILED;
3254 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
3255 return CA_STATUS_OK;
3258 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
3259 jobject gattCharacteristic)
3261 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
3262 VERIFY_NON_NULL(env, TAG, "env is null");
3263 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3264 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
3266 if (!CALEIsEnableBTAdapter(env))
3268 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3269 return CA_STATUS_FAILED;
3272 // get BluetoothGatt.write characteristic method
3273 OIC_LOG(DEBUG, TAG, "write characteristic method");
3274 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3275 "writeCharacteristic",
3276 "(Landroid/bluetooth/"
3277 "BluetoothGattCharacteristic;)Z");
3278 if (!jni_mid_writeCharacteristic)
3280 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
3281 return CA_STATUS_FAILED;
3284 // call disconnect gatt method
3285 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
3286 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
3287 jni_mid_writeCharacteristic,
3288 gattCharacteristic);
3291 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
3295 CACheckJNIException(env);
3296 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
3297 return CA_STATUS_FAILED;
3300 return CA_STATUS_OK;
3303 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
3305 VERIFY_NON_NULL(env, TAG, "env is null");
3306 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3308 if (!CALEIsEnableBTAdapter(env))
3310 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3311 return CA_STATUS_FAILED;
3314 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3317 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3318 CACheckJNIException(env);
3319 return CA_STATUS_FAILED;
3322 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
3323 if (!jni_obj_GattCharacteristic)
3325 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3326 return CA_STATUS_FAILED;
3329 OIC_LOG(DEBUG, TAG, "read characteristic method");
3330 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3331 "readCharacteristic",
3332 "(Landroid/bluetooth/"
3333 "BluetoothGattCharacteristic;)Z");
3334 if (!jni_mid_readCharacteristic)
3336 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
3337 return CA_STATUS_FAILED;
3340 // call disconnect gatt method
3341 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
3342 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
3343 jni_obj_GattCharacteristic);
3346 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
3350 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
3351 CACheckJNIException(env);
3352 return CA_STATUS_FAILED;
3355 return CA_STATUS_OK;
3358 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
3359 jobject characteristic)
3361 VERIFY_NON_NULL(env, TAG, "env is null");
3362 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3363 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
3365 if (!CALEIsEnableBTAdapter(env))
3367 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3368 return CA_ADAPTER_NOT_ENABLED;
3371 // get BluetoothGatt.setCharacteristicNotification method
3372 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
3373 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3374 "setCharacteristicNotification",
3375 "(Landroid/bluetooth/"
3376 "BluetoothGattCharacteristic;Z)Z");
3377 if (!jni_mid_setNotification)
3379 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
3380 return CA_STATUS_FAILED;
3383 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
3384 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
3385 characteristic, JNI_TRUE);
3386 if (JNI_TRUE == ret)
3388 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
3392 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
3393 CACheckJNIException(env);
3394 return CA_STATUS_FAILED;
3397 return CA_STATUS_OK;
3400 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
3402 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3403 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
3404 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
3406 if (!CALEIsEnableBTAdapter(env))
3408 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3412 // get BluetoothGatt.getService method
3413 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
3414 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3416 "(Ljava/util/UUID;)Landroid/bluetooth/"
3417 "BluetoothGattService;");
3418 if (!jni_mid_getService)
3420 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
3424 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
3425 if (!jni_obj_service_uuid)
3427 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
3431 // get bluetooth gatt service
3432 OIC_LOG(DEBUG, TAG, "request to get service");
3433 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
3434 jni_obj_service_uuid);
3435 if (!jni_obj_gattService)
3437 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
3438 CACheckJNIException(env);
3442 // get bluetooth gatt service method
3443 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
3444 "BluetoothGattService",
3445 "getCharacteristic",
3446 "(Ljava/util/UUID;)"
3447 "Landroid/bluetooth/"
3448 "BluetoothGattCharacteristic;");
3449 if (!jni_mid_getCharacteristic)
3451 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
3455 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
3458 OIC_LOG(ERROR, TAG, "uuid is null");
3459 CACheckJNIException(env);
3463 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
3464 if (!jni_obj_tx_uuid)
3466 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
3467 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
3471 OIC_LOG(DEBUG, TAG, "CALL API getCharacteristic");
3472 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
3473 jni_mid_getCharacteristic,
3475 if (!jni_obj_GattCharacteristic)
3477 OIC_LOG(ERROR, TAG, "getCharacteristic has failed");
3478 CACheckJNIException(env);
3482 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
3483 return jni_obj_GattCharacteristic;
3486 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
3488 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
3489 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3490 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
3491 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
3493 if (!CALEIsEnableBTAdapter(env))
3495 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3499 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
3502 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3506 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
3507 if (!jni_obj_GattCharacteristic)
3509 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3513 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
3514 "/BluetoothGattCharacteristic");
3515 if (!jni_cid_BTGattCharacteristic)
3517 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
3521 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
3522 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
3524 if (!jni_mid_setValue)
3526 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
3530 OIC_LOG(DEBUG, TAG, "CALL API - setValue");
3531 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
3533 if (JNI_TRUE == ret)
3535 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
3539 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
3545 OIC_LOG(DEBUG, TAG, "setWriteType with WRITE_TYPE_NO_RESPONSE");
3547 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
3548 "setWriteType", "(I)V");
3549 if (!jni_mid_setWriteType)
3551 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
3555 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
3556 "WRITE_TYPE_NO_RESPONSE", "I");
3557 if (!jni_fid_no_response)
3559 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
3563 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
3564 jni_fid_no_response);
3565 CACheckJNIException(env);
3567 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
3568 if (CACheckJNIException(env))
3570 OIC_LOG(ERROR, TAG, "setWriteType has failed");
3575 OIC_LOG(DEBUG, TAG, "It will run with response property");
3578 return jni_obj_GattCharacteristic;
3581 CACheckJNIException(env);
3585 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
3587 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
3588 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3590 if (!CALEIsEnableBTAdapter(env))
3592 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3596 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
3597 "BluetoothGattCharacteristic",
3598 "getValue", "()[B");
3599 if (!jni_mid_getValue)
3601 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
3605 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
3607 CACheckJNIException(env);
3608 return jni_obj_data_array;
3611 CAResult_t CALEClientCreateUUIDList()
3613 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
3616 bool isAttached = false;
3617 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
3618 return CA_STATUS_FAILED;
3621 // create new object array
3622 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
3623 if (!jni_cid_uuid_list)
3625 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
3626 CACheckJNIException(env);
3630 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
3631 jni_cid_uuid_list, NULL);
3632 if (!jni_obj_uuid_list)
3634 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
3635 CACheckJNIException(env);
3640 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
3643 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
3646 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
3648 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
3649 CACheckJNIException(env);
3653 (*g_jvm)->DetachCurrentThread(g_jvm);
3656 return CA_STATUS_OK;
3663 (*g_jvm)->DetachCurrentThread(g_jvm);
3665 return CA_STATUS_FAILED;
3668 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
3669 jobject characteristic)
3671 VERIFY_NON_NULL(env, TAG, "env is null");
3672 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3673 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
3675 if (!CALEIsEnableBTAdapter(env))
3677 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3678 return CA_ADAPTER_NOT_ENABLED;
3681 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
3682 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
3683 "BluetoothGattCharacteristic",
3685 "(Ljava/util/UUID;)Landroid/bluetooth/"
3686 "BluetoothGattDescriptor;");
3687 if (!jni_mid_getDescriptor)
3689 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
3690 return CA_STATUS_FAILED;
3693 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
3694 if (!jni_obj_cc_uuid)
3696 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
3699 OIC_LOG(DEBUG, TAG, "request to get descriptor");
3700 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
3701 jni_mid_getDescriptor, jni_obj_cc_uuid);
3702 if (!jni_obj_descriptor)
3704 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
3708 OIC_LOG(DEBUG, TAG, "set value in descriptor");
3709 jclass jni_cid_descriptor = (*env)->FindClass(env,
3710 "android/bluetooth/BluetoothGattDescriptor");
3711 if (!jni_cid_descriptor)
3713 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
3717 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
3718 if (!jni_mid_setValue)
3720 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
3724 jfieldID jni_fid_NotiValue = NULL;
3727 OIC_LOG(DEBUG, TAG, "get ENABLE_INDICATION_VALUE");
3728 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
3729 "ENABLE_INDICATION_VALUE", "[B");
3730 if (!jni_fid_NotiValue)
3732 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
3738 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
3739 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
3740 "ENABLE_NOTIFICATION_VALUE", "[B");
3741 if (!jni_fid_NotiValue)
3743 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
3748 jboolean jni_setvalue = (*env)->CallBooleanMethod(
3749 env, jni_obj_descriptor, jni_mid_setValue,
3750 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
3753 OIC_LOG(DEBUG, TAG, "setValue success");
3757 OIC_LOG(ERROR, TAG, "setValue has failed");
3761 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
3763 "(Landroid/bluetooth/"
3764 "BluetoothGattDescriptor;)Z");
3765 if (!jni_mid_writeDescriptor)
3767 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
3768 return CA_STATUS_FAILED;
3771 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
3772 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
3773 jni_obj_descriptor);
3776 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
3780 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
3784 return CA_STATUS_OK;
3787 CACheckJNIException(env);
3788 return CA_STATUS_FAILED;
3791 void CALEClientCreateScanDeviceList(JNIEnv *env)
3793 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
3794 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3796 oc_mutex_lock(g_deviceListMutex);
3797 // create new object array
3798 if (g_deviceList == NULL)
3800 OIC_LOG(DEBUG, TAG, "Create device list");
3802 g_deviceList = u_arraylist_create();
3804 oc_mutex_unlock(g_deviceListMutex);
3807 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
3809 VERIFY_NON_NULL(device, TAG, "device is null");
3810 VERIFY_NON_NULL(env, TAG, "env is null");
3812 oc_mutex_lock(g_deviceListMutex);
3816 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3817 oc_mutex_unlock(g_deviceListMutex);
3818 return CA_STATUS_FAILED;
3821 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
3822 if (!jni_remoteAddress)
3824 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3825 oc_mutex_unlock(g_deviceListMutex);
3826 return CA_STATUS_FAILED;
3829 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3832 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3833 CACheckJNIException(env);
3834 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3835 oc_mutex_unlock(g_deviceListMutex);
3836 return CA_STATUS_FAILED;
3839 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
3841 jobject gdevice = (*env)->NewGlobalRef(env, device);
3842 CACheckJNIException(env);
3843 u_arraylist_add(g_deviceList, gdevice);
3844 oc_cond_signal(g_deviceDescCond);
3845 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
3847 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3848 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3850 oc_mutex_unlock(g_deviceListMutex);
3852 return CA_STATUS_OK;
3855 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
3857 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
3858 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
3862 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
3866 uint32_t length = u_arraylist_length(g_deviceList);
3867 for (uint32_t index = 0; index < length; index++)
3869 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3872 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3876 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
3877 if (!jni_setAddress)
3879 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3883 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3886 OIC_LOG(ERROR, TAG, "setAddress is null");
3887 CACheckJNIException(env);
3888 (*env)->DeleteLocalRef(env, jni_setAddress);
3892 if (!strcasecmp(remoteAddress, setAddress))
3894 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3895 (*env)->DeleteLocalRef(env, jni_setAddress);
3899 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3900 (*env)->DeleteLocalRef(env, jni_setAddress);
3905 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
3907 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
3908 VERIFY_NON_NULL(env, TAG, "env is null");
3910 oc_mutex_lock(g_deviceListMutex);
3914 OIC_LOG(ERROR, TAG, "g_deviceList is null");
3915 oc_mutex_unlock(g_deviceListMutex);
3916 return CA_STATUS_FAILED;
3919 uint32_t length = u_arraylist_length(g_deviceList);
3920 for (uint32_t index = 0; index < length; index++)
3922 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3925 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3928 (*env)->DeleteGlobalRef(env, jarrayObj);
3932 OICFree(g_deviceList);
3933 g_deviceList = NULL;
3935 oc_mutex_unlock(g_deviceListMutex);
3936 return CA_STATUS_OK;
3939 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
3941 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
3942 VERIFY_NON_NULL(address, TAG, "address is null");
3943 VERIFY_NON_NULL(env, TAG, "env is null");
3945 oc_mutex_lock(g_deviceListMutex);
3949 OIC_LOG(ERROR, TAG, "g_deviceList is null");
3950 oc_mutex_unlock(g_deviceListMutex);
3951 return CA_STATUS_FAILED;
3954 uint32_t length = u_arraylist_length(g_deviceList);
3955 for (uint32_t index = 0; index < length; index++)
3957 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3960 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3961 oc_mutex_unlock(g_deviceListMutex);
3962 return CA_STATUS_FAILED;
3965 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
3966 if (!jni_setAddress)
3968 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3969 oc_mutex_unlock(g_deviceListMutex);
3970 return CA_STATUS_FAILED;
3973 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3976 OIC_LOG(ERROR, TAG, "setAddress is null");
3977 CACheckJNIException(env);
3978 oc_mutex_unlock(g_deviceListMutex);
3979 return CA_STATUS_FAILED;
3982 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
3985 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3986 CACheckJNIException(env);
3987 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3988 oc_mutex_unlock(g_deviceListMutex);
3989 return CA_STATUS_FAILED;
3992 if (!strcasecmp(setAddress, remoteAddress))
3994 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3995 (*env)->DeleteGlobalRef(env, jarrayObj);
3997 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3998 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
4000 if (NULL == u_arraylist_remove(g_deviceList, index))
4002 OIC_LOG(ERROR, TAG, "List removal failed.");
4003 oc_mutex_unlock(g_deviceListMutex);
4004 return CA_STATUS_FAILED;
4006 oc_mutex_unlock(g_deviceListMutex);
4007 return CA_STATUS_OK;
4009 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4010 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
4013 oc_mutex_unlock(g_deviceListMutex);
4014 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
4016 return CA_STATUS_OK;
4023 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
4025 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
4026 VERIFY_NON_NULL(env, TAG, "env is null");
4027 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
4029 oc_mutex_lock(g_gattObjectMutex);
4031 if (!g_gattObjectList)
4033 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
4034 oc_mutex_unlock(g_gattObjectMutex);
4035 return CA_STATUS_FAILED;
4038 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
4039 if (!jni_remoteAddress)
4041 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
4042 oc_mutex_unlock(g_gattObjectMutex);
4043 return CA_STATUS_FAILED;
4046 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
4049 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4050 CACheckJNIException(env);
4051 (*env)->DeleteLocalRef(env, jni_remoteAddress);
4052 oc_mutex_unlock(g_gattObjectMutex);
4053 return CA_STATUS_FAILED;
4056 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
4057 if (!CALEClientIsGattObjInList(env, remoteAddress))
4059 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
4060 u_arraylist_add(g_gattObjectList, newGatt);
4061 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
4064 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4065 (*env)->DeleteLocalRef(env, jni_remoteAddress);
4066 oc_mutex_unlock(g_gattObjectMutex);
4067 return CA_STATUS_OK;
4070 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
4072 VERIFY_NON_NULL(env, TAG, "env is null");
4073 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
4075 uint32_t length = u_arraylist_length(g_gattObjectList);
4076 for (uint32_t index = 0; index < length; index++)
4078 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4081 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4085 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4086 if (!jni_setAddress)
4088 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4092 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4095 OIC_LOG(ERROR, TAG, "setAddress is null");
4096 CACheckJNIException(env);
4097 (*env)->DeleteLocalRef(env, jni_setAddress);
4101 if (!strcasecmp(remoteAddress, setAddress))
4103 OIC_LOG(DEBUG, TAG, "the device is already set");
4104 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4105 (*env)->DeleteLocalRef(env, jni_setAddress);
4108 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4109 (*env)->DeleteLocalRef(env, jni_setAddress);
4112 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
4116 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
4118 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
4119 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4120 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
4122 oc_mutex_lock(g_gattObjectMutex);
4123 uint32_t length = u_arraylist_length(g_gattObjectList);
4124 for (uint32_t index = 0; index < length; index++)
4126 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4129 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4130 oc_mutex_unlock(g_gattObjectMutex);
4134 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4135 if (!jni_setAddress)
4137 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4138 oc_mutex_unlock(g_gattObjectMutex);
4142 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4145 OIC_LOG(ERROR, TAG, "setAddress is null");
4146 CACheckJNIException(env);
4147 (*env)->DeleteLocalRef(env, jni_setAddress);
4148 oc_mutex_unlock(g_gattObjectMutex);
4152 if (!strcasecmp(remoteAddress, setAddress))
4154 OIC_LOG(DEBUG, TAG, "the device is already set");
4155 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4156 oc_mutex_unlock(g_gattObjectMutex);
4159 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4160 (*env)->DeleteLocalRef(env, jni_setAddress);
4163 oc_mutex_unlock(g_gattObjectMutex);
4164 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
4168 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
4170 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
4171 VERIFY_NON_NULL(env, TAG, "env is null");
4173 oc_mutex_lock(g_gattObjectMutex);
4174 if (!g_gattObjectList)
4176 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4177 oc_mutex_unlock(g_gattObjectMutex);
4178 return CA_STATUS_OK;
4181 uint32_t length = u_arraylist_length(g_gattObjectList);
4182 for (uint32_t index = 0; index < length; index++)
4184 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4187 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4190 (*env)->DeleteGlobalRef(env, jarrayObj);
4194 OICFree(g_gattObjectList);
4195 g_gattObjectList = NULL;
4196 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
4197 oc_mutex_unlock(g_gattObjectMutex);
4198 return CA_STATUS_OK;
4201 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
4203 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
4204 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
4205 VERIFY_NON_NULL(env, TAG, "env is null");
4207 oc_mutex_lock(g_gattObjectMutex);
4208 if (!g_gattObjectList)
4210 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4211 oc_mutex_unlock(g_gattObjectMutex);
4212 return CA_STATUS_OK;
4215 uint32_t length = u_arraylist_length(g_gattObjectList);
4216 for (uint32_t index = 0; index < length; index++)
4218 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4221 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4222 oc_mutex_unlock(g_gattObjectMutex);
4223 return CA_STATUS_FAILED;
4226 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4227 if (!jni_setAddress)
4229 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4230 oc_mutex_unlock(g_gattObjectMutex);
4231 return CA_STATUS_FAILED;
4234 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4237 OIC_LOG(ERROR, TAG, "setAddress is null");
4238 CACheckJNIException(env);
4239 oc_mutex_unlock(g_gattObjectMutex);
4240 return CA_STATUS_FAILED;
4243 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
4244 if (!jni_remoteAddress)
4246 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
4247 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4248 oc_mutex_unlock(g_gattObjectMutex);
4249 return CA_STATUS_FAILED;
4252 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
4255 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4256 CACheckJNIException(env);
4257 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4258 oc_mutex_unlock(g_gattObjectMutex);
4259 return CA_STATUS_FAILED;
4262 if (!strcasecmp(setAddress, remoteAddress))
4264 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4265 (*env)->DeleteGlobalRef(env, jarrayObj);
4267 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4268 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4270 if (NULL == u_arraylist_remove(g_gattObjectList, index))
4272 OIC_LOG(ERROR, TAG, "List removal failed.");
4273 oc_mutex_unlock(g_gattObjectMutex);
4274 return CA_STATUS_FAILED;
4276 oc_mutex_unlock(g_gattObjectMutex);
4277 return CA_STATUS_OK;
4279 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4280 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4283 oc_mutex_unlock(g_gattObjectMutex);
4284 OIC_LOG(DEBUG, TAG, "there are no target object");
4285 return CA_STATUS_OK;
4288 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
4290 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
4291 VERIFY_NON_NULL(addr, TAG, "addr is null");
4292 VERIFY_NON_NULL(env, TAG, "env is null");
4294 oc_mutex_lock(g_gattObjectMutex);
4295 if (!g_gattObjectList)
4297 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4298 oc_mutex_unlock(g_gattObjectMutex);
4299 return CA_STATUS_OK;
4302 uint32_t length = u_arraylist_length(g_gattObjectList);
4303 for (uint32_t index = 0; index < length; index++)
4305 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4308 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4309 oc_mutex_unlock(g_gattObjectMutex);
4310 return CA_STATUS_FAILED;
4313 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4314 if (!jni_setAddress)
4316 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4317 oc_mutex_unlock(g_gattObjectMutex);
4318 return CA_STATUS_FAILED;
4321 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4324 OIC_LOG(ERROR, TAG, "setAddress is null");
4325 CACheckJNIException(env);
4326 oc_mutex_unlock(g_gattObjectMutex);
4327 return CA_STATUS_FAILED;
4330 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
4333 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4334 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4335 oc_mutex_unlock(g_gattObjectMutex);
4336 return CA_STATUS_FAILED;
4339 if (!strcasecmp(setAddress, remoteAddress))
4341 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4342 (*env)->DeleteGlobalRef(env, jarrayObj);
4344 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4345 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
4346 if (NULL == u_arraylist_remove(g_gattObjectList, index))
4348 OIC_LOG(ERROR, TAG, "List removal failed.");
4349 oc_mutex_unlock(g_gattObjectMutex);
4350 return CA_STATUS_FAILED;
4352 oc_mutex_unlock(g_gattObjectMutex);
4353 return CA_STATUS_OK;
4355 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4356 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
4359 oc_mutex_unlock(g_gattObjectMutex);
4360 OIC_LOG(DEBUG, TAG, "there are no target object");
4361 return CA_STATUS_FAILED;
4364 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
4366 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
4367 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
4369 // get Bluetooth Address
4370 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
4371 if (!jni_btTargetAddress)
4373 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4377 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
4380 OIC_LOG(ERROR, TAG, "targetAddress is not available");
4381 CACheckJNIException(env);
4385 // get method ID of getDevice()
4386 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
4387 "getDevice", METHODID_BT_DEVICE);
4388 if (!jni_mid_getDevice)
4390 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4391 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4395 oc_mutex_lock(g_gattObjectMutex);
4397 size_t length = u_arraylist_length(g_gattObjectList);
4398 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
4399 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
4401 for (size_t index = 0; index < length; index++)
4403 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4406 oc_mutex_unlock(g_gattObjectMutex);
4407 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4408 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4412 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
4413 if (!jni_obj_device)
4415 CACheckJNIException(env);
4416 oc_mutex_unlock(g_gattObjectMutex);
4417 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4418 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4422 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
4425 oc_mutex_unlock(g_gattObjectMutex);
4426 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4427 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4428 (*env)->DeleteLocalRef(env, jni_obj_device);
4432 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
4435 CACheckJNIException(env);
4436 oc_mutex_unlock(g_gattObjectMutex);
4437 OIC_LOG(ERROR, TAG, "btAddress is not available");
4438 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4439 (*env)->DeleteLocalRef(env, jni_btAddress);
4440 (*env)->DeleteLocalRef(env, jni_obj_device);
4444 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
4445 if (!strcasecmp(targetAddress, btAddress))
4447 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
4450 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4453 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
4455 oc_mutex_unlock(g_gattObjectMutex);
4456 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4457 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
4458 (*env)->DeleteLocalRef(env, jni_btAddress);
4459 (*env)->DeleteLocalRef(env, jni_obj_device);
4460 return jni_LEAddress;
4462 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
4463 (*env)->DeleteLocalRef(env, jni_btAddress);
4464 (*env)->DeleteLocalRef(env, jni_obj_device);
4466 oc_mutex_unlock(g_gattObjectMutex);
4468 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4469 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
4476 CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env,
4478 uint16_t state_type,
4479 uint16_t target_state)
4481 VERIFY_NON_NULL(device, TAG, "device is null");
4483 // get Bluetooth Address
4484 jstring jni_Address = CALEGetAddressFromBTDevice(env, device);
4487 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4488 return CA_STATUS_FAILED;
4491 const char* address = (*env)->GetStringUTFChars(env, jni_Address, NULL);
4494 OIC_LOG(ERROR, TAG, "targetAddress is not available");
4495 CACheckJNIException(env);
4496 (*env)->DeleteLocalRef(env, jni_Address);
4497 return CA_STATUS_FAILED;
4500 if (CALEIsValidState(address, state_type, target_state,
4502 g_deviceStateListMutex))
4504 (*env)->DeleteLocalRef(env, jni_Address);
4505 return CA_STATUS_OK;
4508 CAResult_t res = CALEUpdateDeviceState(address, state_type,
4511 g_deviceStateListMutex);
4512 if (CA_STATUS_OK != res)
4514 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4516 (*env)->ReleaseStringUTFChars(env, jni_Address, address);
4517 (*env)->DeleteLocalRef(env, jni_Address);
4522 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
4523 jint state_idx, jboolean flag)
4525 return CALESetFlagToState(env, jni_address, state_idx, flag,
4526 g_deviceStateList, g_deviceStateListMutex);
4529 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
4531 return CALEGetFlagFromState(env, jni_address, state_idx, g_deviceStateList,
4532 g_deviceStateListMutex);
4535 uint16_t CALEClientGetMtuSize(const char* address)
4537 return CALEGetMtuSize(address, g_deviceStateList, g_deviceStateListMutex);
4540 void CALEClientCreateDeviceList()
4542 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
4544 // create new object array
4545 if (!g_gattObjectList)
4547 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
4549 g_gattObjectList = u_arraylist_create();
4552 if (!g_deviceStateList)
4554 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
4556 g_deviceStateList = u_arraylist_create();
4561 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
4563 g_deviceList = u_arraylist_create();
4567 CAResult_t CALEClientResetDeviceStateForAll()
4569 return CALEResetDeviceStateForAll(g_deviceStateList, g_deviceStateListMutex);
4573 * Check Sent Count for remove g_sendBuffer
4575 void CALEClientUpdateSendCnt(JNIEnv *env)
4577 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
4579 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4581 oc_mutex_lock(g_threadMutex);
4585 if (g_targetCnt <= g_currentSentCnt)
4588 g_currentSentCnt = 0;
4590 CALEDeleteSendBuffer(env);
4592 // notity the thread
4593 oc_cond_signal(g_threadCond);
4594 oc_cond_signal(g_threadWriteCharacteristicCond);
4596 CALEClientSetSendFinishFlag(true);
4597 OIC_LOG(DEBUG, TAG, "set signal for send data");
4600 #ifdef SCAN_INTERVAL
4601 // reset interval scan logic
4602 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
4606 oc_mutex_unlock(g_threadMutex);
4609 CAResult_t CALEClientInitGattMutexVaraibles()
4611 if (NULL == g_bleServerBDAddressMutex)
4613 g_bleServerBDAddressMutex = oc_mutex_new();
4614 if (NULL == g_bleServerBDAddressMutex)
4616 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4617 return CA_STATUS_FAILED;
4621 if (NULL == g_threadMutex)
4623 g_threadMutex = oc_mutex_new();
4624 if (NULL == g_threadMutex)
4626 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4627 return CA_STATUS_FAILED;
4631 if (NULL == g_threadSendMutex)
4633 g_threadSendMutex = oc_mutex_new();
4634 if (NULL == g_threadSendMutex)
4636 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4637 return CA_STATUS_FAILED;
4641 if (NULL == g_deviceListMutex)
4643 g_deviceListMutex = oc_mutex_new();
4644 if (NULL == g_deviceListMutex)
4646 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4647 return CA_STATUS_FAILED;
4651 if (NULL == g_gattObjectMutex)
4653 g_gattObjectMutex = oc_mutex_new();
4654 if (NULL == g_gattObjectMutex)
4656 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4657 return CA_STATUS_FAILED;
4661 if (NULL == g_deviceStateListMutex)
4663 g_deviceStateListMutex = oc_mutex_new();
4664 if (NULL == g_deviceStateListMutex)
4666 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4667 return CA_STATUS_FAILED;
4671 if (NULL == g_SendFinishMutex)
4673 g_SendFinishMutex = oc_mutex_new();
4674 if (NULL == g_SendFinishMutex)
4676 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4677 return CA_STATUS_FAILED;
4681 if (NULL == g_threadWriteCharacteristicMutex)
4683 g_threadWriteCharacteristicMutex = oc_mutex_new();
4684 if (NULL == g_threadWriteCharacteristicMutex)
4686 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4687 return CA_STATUS_FAILED;
4691 if (NULL == g_deviceScanRetryDelayMutex)
4693 g_deviceScanRetryDelayMutex = oc_mutex_new();
4694 if (NULL == g_deviceScanRetryDelayMutex)
4696 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4697 return CA_STATUS_FAILED;
4701 if (NULL == g_threadSendStateMutex)
4703 g_threadSendStateMutex = oc_mutex_new();
4704 if (NULL == g_threadSendStateMutex)
4706 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4707 return CA_STATUS_FAILED;
4711 if (NULL == g_threadScanIntervalMutex)
4713 g_threadScanIntervalMutex = oc_mutex_new();
4714 if (NULL == g_threadScanIntervalMutex)
4716 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4717 return CA_STATUS_FAILED;
4721 if (NULL == g_setValueMutex)
4723 g_setValueMutex = oc_mutex_new();
4724 if (NULL == g_setValueMutex)
4726 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4727 return CA_STATUS_FAILED;
4731 return CA_STATUS_OK;
4734 void CALEClientTerminateGattMutexVariables()
4737 oc_mutex_free(g_bleServerBDAddressMutex);
4738 g_bleServerBDAddressMutex = NULL;
4740 oc_mutex_free(g_threadMutex);
4741 g_threadMutex = NULL;
4743 oc_mutex_free(g_threadSendMutex);
4744 g_threadSendMutex = NULL;
4746 oc_mutex_free(g_deviceListMutex);
4747 g_deviceListMutex = NULL;
4749 oc_mutex_free(g_SendFinishMutex);
4750 g_SendFinishMutex = NULL;
4752 oc_mutex_free(g_threadWriteCharacteristicMutex);
4753 g_threadWriteCharacteristicMutex = NULL;
4755 oc_mutex_free(g_deviceScanRetryDelayMutex);
4756 g_deviceScanRetryDelayMutex = NULL;
4758 oc_mutex_free(g_threadSendStateMutex);
4759 g_threadSendStateMutex = NULL;
4761 oc_mutex_free(g_threadScanIntervalMutex);
4762 g_threadScanIntervalMutex = NULL;
4764 oc_mutex_free(g_gattObjectMutex);
4765 g_gattObjectMutex = NULL;
4767 oc_mutex_free(g_deviceStateListMutex);
4768 g_deviceStateListMutex = NULL;
4770 oc_mutex_free(g_setValueMutex);
4771 g_setValueMutex = NULL;
4774 void CALEClientSetSendFinishFlag(bool flag)
4776 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
4778 oc_mutex_lock(g_SendFinishMutex);
4779 g_isFinishedSendData = flag;
4780 oc_mutex_unlock(g_SendFinishMutex);
4787 CAResult_t CAStartLEGattClient()
4789 // init mutex for send logic
4790 if (!g_deviceDescCond)
4792 g_deviceDescCond = oc_cond_new();
4797 g_threadCond = oc_cond_new();
4800 if (!g_threadWriteCharacteristicCond)
4802 g_threadWriteCharacteristicCond = oc_cond_new();
4805 if (!g_threadScanIntervalCond)
4807 g_threadScanIntervalCond = oc_cond_new();
4810 CAResult_t ret = CALEClientStartScanWithInterval();
4811 if (CA_STATUS_OK != ret)
4813 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
4817 g_isStartedLEClient = true;
4818 return CA_STATUS_OK;
4821 void CAStopLEGattClient()
4823 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
4825 VERIFY_NON_NULL_VOID(g_jvm, TAG, "g_jvm is null");
4828 bool isAttached = false;
4829 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
4833 CAResult_t ret = CALEClientDisconnectAll(env);
4834 if (CA_STATUS_OK != ret)
4836 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
4839 CALEClientStopScanWithInterval();
4841 oc_mutex_lock(g_threadWriteCharacteristicMutex);
4842 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
4843 oc_cond_signal(g_threadWriteCharacteristicCond);
4844 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
4846 CALEClientSetSendFinishFlag(true);
4847 oc_mutex_lock(g_threadMutex);
4848 OIC_LOG(DEBUG, TAG, "signal - g_threadCond cond");
4849 oc_cond_signal(g_threadCond);
4850 oc_mutex_unlock(g_threadMutex);
4852 oc_mutex_lock(g_deviceScanRetryDelayMutex);
4853 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4854 oc_cond_signal(g_deviceScanRetryDelayCond);
4855 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
4857 oc_mutex_lock(g_threadScanIntervalMutex);
4858 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4859 oc_cond_signal(g_threadScanIntervalCond);
4860 oc_mutex_unlock(g_threadScanIntervalMutex);
4862 oc_mutex_lock(g_threadSendMutex);
4863 OIC_LOG(DEBUG, TAG, "signal - g_deviceDesc cond");
4864 oc_cond_signal(g_deviceDescCond);
4865 oc_mutex_unlock(g_threadSendMutex);
4867 oc_cond_free(g_deviceDescCond);
4868 oc_cond_free(g_threadCond);
4869 oc_cond_free(g_threadWriteCharacteristicCond);
4870 oc_cond_free(g_deviceScanRetryDelayCond);
4871 oc_cond_free(g_threadScanIntervalCond);
4873 g_deviceDescCond = NULL;
4874 g_threadCond = NULL;
4875 g_threadWriteCharacteristicCond = NULL;
4876 g_deviceScanRetryDelayCond = NULL;
4877 g_threadScanIntervalCond = NULL;
4881 (*g_jvm)->DetachCurrentThread(g_jvm);
4886 CAResult_t CAInitializeLEGattClient()
4888 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
4889 CALEClientInitialize();
4890 return CA_STATUS_OK;
4893 void CATerminateLEGattClient()
4895 OIC_LOG(INFO, TAG, "IN - Terminate GATT Client");
4896 CAStopLEGattClient();
4897 CALEClientTerminate();
4898 OIC_LOG(INFO, TAG, "OUT - Terminate GATT Client");
4901 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
4902 uint32_t dataLen, CALETransferType_t type,
4905 OIC_LOG(INFO, TAG, "call CALEClientSendUnicastMessage");
4906 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
4908 if (LE_UNICAST != type || position < 0)
4910 OIC_LOG(ERROR, TAG, "this request is not unicast");
4911 return CA_STATUS_INVALID_PARAM;
4914 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4917 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4919 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4920 VERIFY_NON_NULL(data, TAG, "data is null");
4922 return CALEClientSendMulticastMessage(data, dataLen);
4925 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4928 g_CABLEClientDataReceivedCallback = callback;
4932 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4934 g_threadPoolHandle = handle;
4937 CAResult_t CAGetLEAddress(char **local_address)
4939 VERIFY_NON_NULL(local_address, TAG, "local_address");
4940 return CA_NOT_SUPPORTED;
4943 JNIEXPORT void JNICALL
4944 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4947 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4948 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4949 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4950 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4952 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4953 CACheckJNIException(env);
4956 JNIEXPORT void JNICALL
4957 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallbackForV21(JNIEnv *env,
4961 OIC_LOG(DEBUG, TAG, "caLeRegisterLeScanCallbackForV21");
4962 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4963 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4964 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4966 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4967 CACheckJNIException(env);
4970 JNIEXPORT void JNICALL
4971 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4974 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4975 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4976 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4977 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4979 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4980 CACheckJNIException(env);
4983 JNIEXPORT void JNICALL
4984 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4987 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4988 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4989 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4991 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4992 if (CA_STATUS_OK != res)
4994 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4998 JNIEXPORT void JNICALL
4999 Java_org_iotivity_ca_CaLeClientInterface_caLeScanFailedCallback(JNIEnv *env, jobject obj,
5002 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5003 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5008 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_ALREADY_STARTED");
5013 "BLE scan has failed, error is SCAN_FAILED_APPLICATION_REGISTRATION_FAILED");
5017 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_INTERNAL_ERROR");
5021 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_FEATURE_UNSUPPORTED");
5025 OIC_LOG(ERROR, TAG, "BLE scan has failed with unknown error");
5031 * Class: org_iotivity_ca_jar_caleinterface
5032 * Method: CALeGattConnectionStateChangeCallback
5033 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
5035 JNIEXPORT void JNICALL
5036 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
5042 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
5044 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5045 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5046 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5048 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
5050 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5053 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
5057 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5060 OIC_LOG(ERROR, TAG, "address is null");
5061 CACheckJNIException(env);
5064 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
5066 if (state_connected == newstate)
5068 OIC_LOG(DEBUG, TAG, "LE is connected");
5069 if (GATT_SUCCESS == status)
5071 CAResult_t res = CALEUpdateDeviceState(address,
5072 CA_LE_CONNECTION_STATE,
5075 g_deviceStateListMutex);
5076 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5077 if (CA_STATUS_OK != res)
5079 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5083 res = CALEClientAddGattobjToList(env, gatt);
5084 if (CA_STATUS_OK != res)
5086 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
5090 res = CALEClientDiscoverServices(env, gatt);
5091 if (CA_STATUS_OK != res)
5093 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
5099 OIC_LOG(INFO, TAG, "unknown status");
5100 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5103 else // STATE_DISCONNECTED == newstate
5105 OIC_LOG(DEBUG, TAG, "LE is disconnected");
5107 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SEND_PREPARING,
5108 g_deviceStateList, g_deviceStateListMutex))
5110 OIC_LOG(INFO, TAG, "current state is STATE_SEND_PREPARING");
5111 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5114 g_deviceStateListMutex);
5115 if (CA_STATUS_OK != res)
5117 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5121 CAResult_t res = CALEUpdateDeviceState(address,
5122 CA_LE_CONNECTION_STATE,
5125 g_deviceStateListMutex);
5126 if (CA_STATUS_OK != res)
5128 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5130 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5132 res = CALEClientGattClose(env, gatt);
5133 if (CA_STATUS_OK != res)
5135 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
5138 if (CALECheckConnectionStateValue(status))
5140 // this state is unexpected reason to disconnect
5141 // if the reason is suitable, connection logic of the device will be destroyed.
5142 OIC_LOG(INFO, TAG, "connection logic destroy");
5146 // other reason except for gatt_success is expected to running
5147 // background connection in BT platform.
5148 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
5150 CALEClientUpdateSendCnt(env);
5156 CALEClientSendFinish(env, gatt);
5161 * Class: org_iotivity_ca_jar_caleinterface
5162 * Method: CALeGattServicesDiscoveredCallback
5163 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
5165 JNIEXPORT void JNICALL
5166 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
5171 OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status);
5172 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5173 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5174 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5176 if (GATT_SUCCESS != status) // discovery error
5178 CALEClientSendFinish(env, gatt);
5182 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5185 CALEClientSendFinish(env, gatt);
5189 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5192 CACheckJNIException(env);
5193 CALEClientSendFinish(env, gatt);
5197 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
5200 OIC_LOG(ERROR, TAG, "jni_uuid is null");
5204 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
5205 if (!jni_obj_GattCharacteristic)
5207 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
5211 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
5212 jni_obj_GattCharacteristic);
5213 if (CA_STATUS_OK != res)
5215 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
5219 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
5220 if (CA_STATUS_OK != res)
5222 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
5224 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE,
5225 g_deviceStateList, g_deviceStateListMutex);
5226 if (CA_STATUS_OK != res)
5228 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
5232 res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
5233 STATE_SERVICE_CONNECTED,
5235 g_deviceStateListMutex);
5236 if (CA_STATUS_OK != res)
5238 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5242 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
5243 if (CA_STATUS_OK != res)
5245 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
5251 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE,
5252 g_deviceStateList, g_deviceStateListMutex);
5253 if (CA_STATUS_OK != res)
5255 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
5260 #ifdef SCAN_INTERVAL
5261 // reset interval scan logic
5262 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
5265 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
5266 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5271 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
5272 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5273 CALEClientSendFinish(env, gatt);
5278 * Class: org_iotivity_ca_jar_caleinterface
5279 * Method: CALeGattCharacteristicWritjclasseCallback
5280 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
5282 JNIEXPORT void JNICALL
5283 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
5284 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status)
5286 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
5287 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5288 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5289 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5291 // send success & signal
5292 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5298 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5301 CACheckJNIException(env);
5305 if (GATT_SUCCESS != status) // error case
5307 OIC_LOG(ERROR, TAG, "send failure");
5310 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
5311 if (CA_STATUS_OK != res)
5313 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
5314 oc_mutex_lock(g_threadWriteCharacteristicMutex);
5315 g_isSignalSetFlag = true;
5316 oc_cond_signal(g_threadWriteCharacteristicCond);
5317 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
5319 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5322 g_deviceStateListMutex);
5323 if (CA_STATUS_OK != res)
5325 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5328 if (g_clientErrorCallback)
5330 jint length = (*env)->GetArrayLength(env, data);
5331 CACheckJNIException(env);
5332 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
5333 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, length,
5334 false, "writeChar failure");
5337 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5343 OIC_LOG(DEBUG, TAG, "send success");
5344 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5347 g_deviceStateListMutex);
5348 if (CA_STATUS_OK != res)
5350 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5353 oc_mutex_lock(g_threadWriteCharacteristicMutex);
5354 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
5355 g_isSignalSetFlag = true;
5356 oc_cond_signal(g_threadWriteCharacteristicCond);
5357 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
5359 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0,
5360 (*env)->GetArrayLength(env, data),
5361 true, "writeChar success");
5364 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5370 CALEClientSendFinish(env, gatt);
5375 * Class: org_iotivity_ca_jar_caleinterface
5376 * Method: CALeGattCharacteristicChangedCallback
5377 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
5379 JNIEXPORT void JNICALL
5380 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
5381 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
5383 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
5384 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5385 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5386 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5387 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
5389 // get Byte Array and convert to uint8_t*
5390 jint length = (*env)->GetArrayLength(env, data);
5393 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
5394 CACheckJNIException(env);
5396 uint8_t* receivedData = OICMalloc(length);
5399 OIC_LOG(ERROR, TAG, "receivedData is null");
5403 memcpy(receivedData, jni_byte_responseData, length);
5404 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
5406 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5409 OIC_LOG(ERROR, TAG, "jni_address is null");
5410 OICFree(receivedData);
5414 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5417 OIC_LOG(ERROR, TAG, "address is null");
5418 CACheckJNIException(env);
5419 OICFree(receivedData);
5423 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
5424 receivedData, length);
5426 uint32_t sentLength = 0;
5427 oc_mutex_lock(g_bleServerBDAddressMutex);
5428 g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
5429 oc_mutex_unlock(g_bleServerBDAddressMutex);
5431 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5435 * Class: org_iotivity_ca_jar_caleinterface
5436 * Method: CALeGattDescriptorWriteCallback
5437 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
5439 JNIEXPORT void JNICALL
5440 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
5444 OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status);
5445 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5446 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5447 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5449 if (GATT_SUCCESS != status) // error
5454 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5460 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5463 CACheckJNIException(env);
5467 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
5468 STATE_SERVICE_CONNECTED,
5470 g_deviceStateListMutex);
5471 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5472 if (CA_STATUS_OK != res)
5474 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5478 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
5479 if (CA_STATUS_OK != res)
5481 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
5489 CALEClientSendFinish(env, gatt);
5493 JNIEXPORT void JNICALL
5494 Java_org_iotivity_ca_CaLeClientInterface_caLeGattMtuChangedCallback(JNIEnv *env,
5500 OIC_LOG_V(INFO, TAG, "caLeGattMtuChangedCallback - status %d, "
5501 "mtu[%d-including Header size 3 byte]", status, mtu);
5505 if (0 == status || 133 == status)
5509 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
5510 if (CA_STATUS_OK != res)
5512 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
5517 OIC_LOG(INFO, TAG, "mtu nego is done");
5518 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5521 CALEClientSendFinish(env, gatt);
5525 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5528 CACheckJNIException(env);
5529 (*env)->DeleteLocalRef(env, jni_address);
5530 CALEClientSendFinish(env, gatt);
5535 CAResult_t res = CALESetMtuSize(address, mtu - CA_BLE_MTU_HEADER_SIZE,
5536 g_deviceStateList, g_deviceStateListMutex);
5537 if (CA_STATUS_OK != res)
5539 OIC_LOG(ERROR, TAG, "CALESetMtuSize has failed");
5542 res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5543 STATE_SEND_MTU_NEGO_SUCCESS,
5545 g_deviceStateListMutex);
5546 if (CA_STATUS_OK != res)
5548 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5550 CALEClientUpdateSendCnt(env);
5551 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5552 (*env)->DeleteLocalRef(env, jni_address);