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)
215 bool isAttached = false;
217 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
220 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
224 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
230 oc_mutex_lock(g_threadScanIntervalMutex);
231 while(g_isWorkingScanThread)
233 OIC_LOG(DEBUG, TAG, "scan waiting time out");
234 if (BLE_SCAN_ENABLE == g_curScanningStep)
237 CAResult_t ret = CALEClientStopScan();
238 if (CA_STATUS_OK != ret)
240 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
243 else if (BLE_SCAN_DISABLE == g_curScanningStep)
246 CAResult_t ret = CALEClientStartScan();
247 if (CA_STATUS_OK != ret)
249 OIC_LOG(INFO, TAG, "CALEClientStartScan has failed");
254 OIC_LOG(DEBUG, TAG, "scan thread is started");
256 CALEClientSetScanInterval(0, 0, BLE_SCAN_DISABLE);
259 OIC_LOG_V(DEBUG, TAG, "wait for Scan Interval Time during %d sec", g_scanIntervalTime);
260 if (OC_WAIT_SUCCESS == oc_cond_wait_for(g_threadScanIntervalCond,
261 g_threadScanIntervalMutex,
262 g_scanIntervalTime * MICROSECS_PER_SEC))
264 // called signal scan thread will be terminated
265 OIC_LOG(DEBUG, TAG, "signal scanInterval waiting");
266 if (BLE_SCAN_DISABLE == g_nextScanningStep)
268 g_curScanningStep = BLE_SCAN_ENABLE;
272 g_curScanningStep = BLE_SCAN_DISABLE;
277 if (BLE_SCAN_ENABLE == g_curScanningStep)
279 if (g_intervalCount > 0)
281 if (g_intervalCount == 1)
283 OIC_LOG(DEBUG, TAG, "reset default time");
284 CALEClientSetScanInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
287 OIC_LOG_V(DEBUG, TAG, "interval count : %d", g_intervalCount);
289 g_curScanningStep = BLE_SCAN_DISABLE;
293 g_curScanningStep = BLE_SCAN_ENABLE;
297 oc_mutex_unlock(g_threadScanIntervalMutex);
301 (*g_jvm)->DetachCurrentThread(g_jvm);
305 CAResult_t CALEClientStartScanWithInterval()
307 if (g_isWorkingScanThread)
309 OIC_LOG(DEBUG, TAG, "scan interval logic already running");
313 // initialize scan flags
314 g_curScanningStep = BLE_SCAN_NONE;
315 g_isWorkingScanThread = true;
317 g_scanIntervalTime = g_scanIntervalTimePrev;
318 g_nextScanningStep = BLE_SCAN_ENABLE;
320 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEScanThread, NULL, NULL))
322 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
323 g_isWorkingScanThread = false;
324 return CA_STATUS_FAILED;
330 void CALEClientStopScanWithInterval()
332 g_isWorkingScanThread = false;
333 oc_cond_signal(g_threadScanIntervalCond);
337 void CALEClientJniInit()
339 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
340 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
343 void CALEClientJNISetContext()
345 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
346 g_context = (jobject) CANativeJNIGetContext();
349 CAResult_t CALECreateJniInterfaceObject()
351 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
355 OIC_LOG(ERROR, TAG, "g_context is null");
356 return CA_STATUS_FAILED;
361 OIC_LOG(ERROR, TAG, "g_jvm is null");
362 return CA_STATUS_FAILED;
365 bool isAttached = false;
367 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
370 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
374 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
375 return CA_STATUS_FAILED;
380 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
381 "getApplicationContext",
382 "()Landroid/content/Context;");
384 if (!mid_getApplicationContext)
386 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
387 return CA_STATUS_FAILED;
390 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
391 mid_getApplicationContext);
392 if (!jApplicationContext)
394 OIC_LOG(ERROR, TAG, "Could not get application context");
398 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
399 if (!jni_LEInterface)
401 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
404 g_LEInterface = (jclass)((*env)->NewGlobalRef(env, jni_LEInterface));
406 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
407 "(Landroid/content/Context;)V");
408 if (!LeInterfaceConstructorMethod)
410 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
414 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
415 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
419 (*g_jvm)->DetachCurrentThread(g_jvm);
425 CACheckJNIException(env);
428 (*g_jvm)->DetachCurrentThread(g_jvm);
431 return CA_STATUS_FAILED;
434 void CALEClientAddUuid(char* uuid, int uuid_type)
436 OIC_LOG(DEBUG, TAG, "CALEClientAddUuid");
437 VERIFY_NON_NULL_VOID(uuid, TAG, "uuid is null");
439 if (uuid_type == CA_LE_TYPE_CUSTOM_UUID)
441 if (g_manufactureDataCount == 0)
443 g_manufactureDataList = u_arraylist_create();
444 OIC_LOG(DEBUG, TAG, "List of manufacture data created");
446 for (int i = 0; i < g_manufactureDataCount; i++)
448 char *str = u_arraylist_get(g_manufactureDataList, i);
449 if (!strcmp(uuid, str))
451 OIC_LOG(DEBUG, TAG, "UUID already set before");
455 g_manufactureDataCount++;
456 bool result = u_arraylist_add(g_manufactureDataList, uuid);
457 OIC_LOG_V(DEBUG, TAG, "Adding manufacture data: %s", u_arraylist_get(g_manufactureDataList, g_manufactureDataCount - 1));
459 else //uuid_type == CA_LE_TYPE_SERVICE_UUID
461 if (g_serviceUuidCount == 0)
463 g_serviceUuidList = u_arraylist_create();
464 OIC_LOG(DEBUG, TAG, "List of service uuid created");
466 for (int i = 0; i < g_serviceUuidCount; i++)
468 char *str = u_arraylist_get(g_serviceUuidList, i);
469 if (!strcmp(uuid, str))
471 OIC_LOG(DEBUG, TAG, "UUID already set before");
475 g_serviceUuidCount++;
476 bool result = u_arraylist_add(g_serviceUuidList, uuid);
477 OIC_LOG_V(DEBUG, TAG, "Adding service UUID: %s", u_arraylist_get(g_serviceUuidList, g_serviceUuidCount - 1));
481 CAResult_t CALEClientInitialize()
483 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
486 CALEClientAddUuid(OIC_GATT_SERVICE_UUID, CA_LE_TYPE_SERVICE_UUID);
487 CALEClientAddUuid(OIC_GATT_CUSTOM_UUID, CA_LE_TYPE_CUSTOM_UUID);
488 CALEClientAddUuid(OIC_GATT_CUSTOM_UUID2, CA_LE_TYPE_CUSTOM_UUID);
489 CALEClientAddUuid(OIC_GATT_CUSTOM_UUID3, CA_LE_TYPE_CUSTOM_UUID);
493 OIC_LOG(ERROR, TAG, "g_jvm is null");
494 return CA_STATUS_FAILED;
497 bool isAttached = false;
499 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
502 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
506 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
507 return CA_STATUS_FAILED;
512 g_jniIntSdk = CALEGetBuildVersion(env);
513 if (g_jniIntSdk < BLE_MIN_API_LEVEL)
515 OIC_LOG(ERROR, TAG, "it is not supported");
519 (*g_jvm)->DetachCurrentThread(g_jvm);
521 return CA_STATUS_FAILED;
524 CAResult_t ret = CALEClientInitGattMutexVaraibles();
525 if (CA_STATUS_OK != ret)
527 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
528 CALEClientTerminateGattMutexVariables();
532 (*g_jvm)->DetachCurrentThread(g_jvm);
538 g_deviceDescCond = oc_cond_new();
540 // init mutex for send logic
541 g_threadCond = oc_cond_new();
542 g_threadWriteCharacteristicCond = oc_cond_new();
543 g_deviceScanRetryDelayCond = oc_cond_new();
544 g_threadScanIntervalCond = oc_cond_new();
546 CALEClientCreateDeviceList();
547 CALEClientJNISetContext();
549 ret = CALEClientCreateUUIDList();
550 if (CA_STATUS_OK != ret)
552 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
556 (*g_jvm)->DetachCurrentThread(g_jvm);
562 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
563 if (CA_STATUS_OK != ret)
565 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
569 (*g_jvm)->DetachCurrentThread(g_jvm);
574 g_isStartedLEClient = true;
578 (*g_jvm)->DetachCurrentThread(g_jvm);
584 void CALEClientTerminate()
586 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
590 OIC_LOG(ERROR, TAG, "g_jvm is null");
594 bool isAttached = false;
596 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
599 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
603 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
610 CAResult_t ret = CALEClientStopScan();
611 if (CA_STATUS_OK != ret)
613 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
616 if (g_leScanCallback)
618 (*env)->DeleteGlobalRef(env, g_leScanCallback);
619 g_leScanCallback = NULL;
622 if (g_leGattCallback)
624 (*env)->DeleteGlobalRef(env, g_leGattCallback);
625 g_leGattCallback = NULL;
630 (*env)->DeleteGlobalRef(env, g_LEInterface);
631 g_LEInterface = NULL;
634 u_arraylist_free(&g_serviceUuidList);
635 u_arraylist_free(&g_manufactureDataList);
637 CALEDeleteSendBuffer(env);
641 (*env)->DeleteGlobalRef(env, g_uuidList);
645 ret = CALERemoveAllDeviceState(g_deviceStateList,
646 g_deviceStateListMutex);
647 if (CA_STATUS_OK != ret)
649 OIC_LOG(ERROR, TAG, "CALERemoveAllDeviceState has failed");
652 oc_mutex_lock(g_deviceStateListMutex);
653 OICFree(g_deviceStateList);
654 g_deviceStateList = NULL;
655 oc_mutex_unlock(g_deviceStateListMutex);
657 ret = CALEClientRemoveAllScanDevices(env);
658 if (CA_STATUS_OK != ret)
660 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
663 ret = CALEClientRemoveAllGattObjs(env);
664 if (CA_STATUS_OK != ret)
666 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
669 CALEClientSetSendFinishFlag(true);
671 CALEClientTerminateGattMutexVariables();
672 CALEClientDestroyJniInterface();
674 oc_cond_free(g_deviceDescCond);
675 oc_cond_free(g_threadCond);
676 oc_cond_free(g_threadWriteCharacteristicCond);
677 oc_cond_free(g_deviceScanRetryDelayCond);
678 oc_cond_free(g_threadScanIntervalCond);
680 g_deviceDescCond = NULL;
682 g_threadWriteCharacteristicCond = NULL;
683 g_deviceScanRetryDelayCond = NULL;
684 g_threadScanIntervalCond = NULL;
686 g_isSignalSetFlag = false;
689 CALEClientStopScanWithInterval();
693 (*g_jvm)->DetachCurrentThread(g_jvm);
697 jobject CALEClientHiddenConnectGatt(jobject btDevice, const char* address, jboolean autoconnect)
699 OIC_LOG(INFO, TAG, "IN - CALEClientHiddenConnectGatt");
703 OIC_LOG(ERROR, TAG, "g_jvm is null");
707 bool isAttached = false;
709 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
712 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
716 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
722 jstring jni_address = (*env)->NewStringUTF(env, address);
723 jmethodID jni_connectGattHiddenMethod = (*env)->GetStaticMethodID(env, g_LEInterface,
724 "connectGattforHidden",
725 "(Landroid/bluetooth/BluetoothDevice;"
726 "Ljava/lang/String;Z)"
727 "Landroid/bluetooth/BluetoothGatt;");
728 if (!jni_connectGattHiddenMethod)
730 OIC_LOG(ERROR, TAG, "Could not get jni_connectGatt Hidden Method");
734 jobject gatt = (*env)->CallStaticObjectMethod(env, g_LEInterface,
735 jni_connectGattHiddenMethod,
736 btDevice, jni_address, autoconnect);
738 if (CACheckJNIException(env))
740 OIC_LOG(ERROR, TAG, "connectGattforHidden has failed");
744 OIC_LOG(INFO, TAG, "OUT - CALEClientHiddenConnectGatt");
748 (*g_jvm)->DetachCurrentThread(g_jvm);
754 CACheckJNIException(env);
759 (*g_jvm)->DetachCurrentThread(g_jvm);
765 CAResult_t CALEClientDestroyJniInterface()
767 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
771 OIC_LOG(ERROR, TAG, "g_jvm is null");
772 return CA_STATUS_FAILED;
775 bool isAttached = false;
777 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
780 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
784 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
785 return CA_STATUS_FAILED;
790 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
791 if (!jni_LeInterface)
793 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
797 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
798 "destroyLeInterface",
800 if (!jni_InterfaceDestroyMethod)
802 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
806 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
808 if (CACheckJNIException(env))
810 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
814 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
818 (*g_jvm)->DetachCurrentThread(g_jvm);
824 CACheckJNIException(env);
829 (*g_jvm)->DetachCurrentThread(g_jvm);
832 return CA_STATUS_FAILED;
835 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
837 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
838 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
842 CAResult_t res = CALEClientDisconnect(env, gatt);
843 if (CA_STATUS_OK != res)
845 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
848 CALEClientUpdateSendCnt(env);
851 CAResult_t CALEClientSendNegotiationMessage(const char* address)
853 VERIFY_NON_NULL(address, TAG, "address is null");
855 return CALEClientSendUnicastMessageImpl(address, NULL, 0);
858 CAResult_t CALEClientSendUnicastMessage(const char* address,
860 const uint32_t dataLen)
862 VERIFY_NON_NULL(address, TAG, "address is null");
863 VERIFY_NON_NULL(data, TAG, "data is null");
865 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
868 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
869 const uint32_t dataLen)
871 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
872 VERIFY_NON_NULL(data, TAG, "data is null");
876 OIC_LOG(ERROR, TAG, "g_jvm is null");
877 return CA_STATUS_FAILED;
880 bool isAttached = false;
882 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
885 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
889 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
890 return CA_STATUS_FAILED;
895 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
896 if (CA_STATUS_OK != ret)
898 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
903 (*g_jvm)->DetachCurrentThread(g_jvm);
909 CAResult_t CALEClientStartUnicastServer(const char* address)
914 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
916 return CA_NOT_SUPPORTED;
919 CAResult_t CALEClientStartMulticastServer()
921 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
923 return CA_NOT_SUPPORTED;
926 void CALEClientStopUnicastServer()
928 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
931 void CALEClientStopMulticastServer()
933 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
936 void CALEClientSetCallback(CAPacketReceiveCallback callback)
938 g_packetReceiveCallback = callback;
941 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
943 g_clientErrorCallback = callback;
946 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
948 VERIFY_NON_NULL(env, TAG, "env");
952 OIC_LOG(ERROR, TAG, "g_deviceList is not available");
953 return CA_STATUS_FAILED;
956 if (0 == u_arraylist_length(g_deviceList) // multicast
957 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
959 // Wait for LE peripherals to be discovered.
961 // Number of times to wait for discovery to complete.
962 static size_t const RETRIES = 5;
964 static uint64_t const TIMEOUT =
965 2 * MICROSECS_PER_SEC; // Microseconds
967 // set scan interval and start scan
968 CALERestartScanWithInterval(WAIT_TIME_SCANNED_CHECKING, 1, BLE_SCAN_ENABLE);
970 bool devicesDiscovered = false;
971 for (size_t i = 0; i < RETRIES; ++i)
973 OIC_LOG(DEBUG, TAG, "waiting for target device");
974 if (oc_cond_wait_for(g_deviceDescCond,
976 TIMEOUT) == OC_WAIT_SUCCESS)
978 OIC_LOG(DEBUG, TAG, "time out");
979 oc_mutex_lock(g_deviceListMutex);
980 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
981 oc_mutex_unlock(g_deviceListMutex);
983 if (0 < scannedDeviceLen)
985 if (!address // multicast
986 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
988 devicesDiscovered = true;
995 OIC_LOG(INFO, TAG, "waiting..");
997 oc_mutex_lock(g_deviceScanRetryDelayMutex);
998 if (oc_cond_wait_for(g_deviceScanRetryDelayCond,
999 g_deviceScanRetryDelayMutex,
1000 MICROSECS_PER_SEC) == OC_WAIT_SUCCESS)
1002 OIC_LOG(INFO, TAG, "finish to waiting for target device");
1003 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
1006 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
1009 // checking whether a target device is found while waiting for time-out.
1010 if (CALEClientIsDeviceInScanDeviceList(env, address))
1012 devicesDiscovered = true;
1021 // reset scan interval time after checking scanned devices
1022 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
1024 // time out for scanning devices
1025 if (!devicesDiscovered)
1027 return CA_STATUS_FAILED;
1032 OIC_LOG(DEBUG, TAG, "there is a target device in the scanned devices");
1035 return CA_STATUS_OK;
1039 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
1040 const uint32_t dataLen)
1042 OIC_LOG(INFO, TAG, "CALEClientSendUnicastMessageImpl in");
1043 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
1045 VERIFY_NON_NULL(address, TAG, "address is null");
1049 OIC_LOG(ERROR, TAG, "g_jvm is null");
1050 return CA_STATUS_FAILED;
1053 bool isAttached = false;
1055 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1058 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1061 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1062 return CA_STATUS_FAILED;
1067 oc_mutex_lock(g_threadSendMutex);
1069 CALEClientSetSendFinishFlag(false);
1071 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
1072 if (CA_STATUS_OK != ret)
1074 OIC_LOG(INFO, TAG, "there is no scanned device");
1078 if (g_context && g_deviceList)
1080 uint32_t length = u_arraylist_length(g_deviceList);
1081 for (uint32_t index = 0; index < length; index++)
1083 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1086 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1090 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1091 if (!jni_setAddress)
1093 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1097 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1100 OIC_LOG(ERROR, TAG, "setAddress is null");
1101 CACheckJNIException(env);
1105 if (!strcasecmp(setAddress, address))
1107 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1108 (*env)->DeleteLocalRef(env, jni_setAddress);
1110 CALEDeleteSendBuffer(env);
1112 if (data && dataLen > 0)
1114 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1115 CACheckJNIException(env);
1116 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1117 CACheckJNIException(env);
1118 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1119 CACheckJNIException(env);
1122 // Target device to send message is just one.
1125 ret = CALEClientSendData(env, jarrayObj);
1126 if (CA_STATUS_OK != ret)
1128 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
1132 OIC_LOG(INFO, TAG, "wake up");
1135 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1136 (*env)->DeleteLocalRef(env, jni_setAddress);
1140 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
1142 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1143 // if there is no connection state.
1144 oc_mutex_lock(g_threadMutex);
1145 if (!g_isFinishedSendData)
1147 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1148 oc_cond_wait(g_threadCond, g_threadMutex);
1149 OIC_LOG(DEBUG, TAG, "connection / send is finished for unicast");
1151 oc_mutex_unlock(g_threadMutex);
1155 (*g_jvm)->DetachCurrentThread(g_jvm);
1158 oc_mutex_unlock(g_threadSendMutex);
1159 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
1160 if (CALEIsValidState(address, CA_LE_SEND_STATE,
1163 g_deviceStateListMutex))
1165 OIC_LOG(INFO, TAG, "send success");
1168 else if (CALEIsValidState(address, CA_LE_SEND_STATE,
1169 STATE_SEND_MTU_NEGO_SUCCESS,
1171 g_deviceStateListMutex))
1173 OIC_LOG(INFO, TAG, "mtu nego success");
1178 OIC_LOG(ERROR, TAG, "send failure");
1179 ret = CA_SEND_FAILED;
1183 CAResult_t resetRet = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
1186 g_deviceStateListMutex);
1187 if (CA_STATUS_OK != resetRet)
1189 OIC_LOG_V(ERROR, TAG, "CALEUpdateDeviceState has failed (%d)", resetRet);
1190 ret = CA_SEND_FAILED;
1199 (*g_jvm)->DetachCurrentThread(g_jvm);
1202 oc_mutex_unlock(g_threadSendMutex);
1203 return CA_SEND_FAILED;
1206 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
1207 const uint32_t dataLen)
1209 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
1210 VERIFY_NON_NULL(data, TAG, "data is null");
1211 VERIFY_NON_NULL(env, TAG, "env is null");
1215 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1216 return CA_STATUS_FAILED;
1219 oc_mutex_lock(g_threadSendMutex);
1221 CALEClientSetSendFinishFlag(false);
1223 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1224 CALEDeleteSendBuffer(env);
1226 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
1227 if (CA_STATUS_OK != res)
1229 OIC_LOG(INFO, TAG, "there is no scanned device");
1233 uint32_t length = u_arraylist_length(g_deviceList);
1234 g_targetCnt = length;
1236 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1237 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1238 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1240 for (uint32_t index = 0; index < length; index++)
1242 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1245 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
1249 res = CALEClientSendData(env, jarrayObj);
1250 if (res != CA_STATUS_OK)
1252 OIC_LOG(ERROR, TAG, "BT device - send has failed");
1256 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1258 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1259 oc_mutex_lock(g_threadMutex);
1260 if (!g_isFinishedSendData)
1262 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1263 oc_cond_wait(g_threadCond, g_threadMutex);
1264 OIC_LOG(DEBUG, TAG, "connection / send is finished for multicast");
1266 oc_mutex_unlock(g_threadMutex);
1267 oc_mutex_unlock(g_threadSendMutex);
1268 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1269 return CA_STATUS_OK;
1272 oc_mutex_unlock(g_threadSendMutex);
1273 OIC_LOG(ERROR, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1274 return CA_SEND_FAILED;
1277 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1279 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1280 VERIFY_NON_NULL(device, TAG, "device is null");
1281 VERIFY_NON_NULL(env, TAG, "env is null");
1283 // get BLE address from bluetooth device object.
1284 char* address = NULL;
1285 CALEState_t* state = NULL;
1286 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1289 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1290 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1293 OIC_LOG(ERROR, TAG, "address is not available");
1294 CACheckJNIException(env);
1295 return CA_STATUS_FAILED;
1297 oc_mutex_lock(g_deviceStateListMutex);
1298 state = CALEGetStateInfo(address, g_deviceStateList);
1299 oc_mutex_unlock(g_deviceStateListMutex);
1302 // Since disconnect event can be caused from BT stack while connection step is running.
1303 // DeviceState has to have current status for processing send failure.
1304 OIC_LOG(INFO, TAG, "set STATE_SEND_PREPARING");
1305 CAResult_t res = CALEClientUpdateDeviceStateWithBtDevice(env, device,
1307 STATE_SEND_PREPARING);
1308 if (CA_STATUS_OK != res)
1310 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceStateWithBtDevice has failed");
1313 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1315 return CA_STATUS_FAILED;
1320 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1322 // cancel previous connection request before connection
1323 // if there is gatt object in g_gattObjectList.
1326 jobject gatt = CALEClientGetGattObjInList(env, address);
1329 CAResult_t res = CALEClientDisconnect(env, gatt);
1330 if (CA_STATUS_OK != res)
1332 OIC_LOG(INFO, TAG, "there is no gatt object");
1335 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1338 // connection request
1339 jobject newGatt = CALEClientConnect(env, device,
1341 if (NULL == newGatt)
1343 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1344 return CA_STATUS_FAILED;
1349 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1350 STATE_SERVICE_CONNECTED,
1352 g_deviceStateListMutex))
1354 OIC_LOG(INFO, TAG, "GATT has already connected");
1356 jobject gatt = CALEClientGetGattObjInList(env, address);
1359 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1360 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1361 return CA_STATUS_FAILED;
1364 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1365 if (CA_STATUS_OK != ret)
1367 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1368 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1371 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1373 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1376 g_deviceStateListMutex))
1378 OIC_LOG(INFO, TAG, "service connecting...");
1380 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1383 g_deviceStateListMutex))
1385 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1387 // cancel previous connection request before connection
1388 // if there is gatt object in g_gattObjectList.
1391 jobject gatt = CALEClientGetGattObjInList(env, address);
1394 CAResult_t res = CALEClientDisconnect(env, gatt);
1395 if (CA_STATUS_OK != res)
1397 OIC_LOG(INFO, TAG, "there is no gatt object");
1400 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1403 OIC_LOG(DEBUG, TAG, "start to connect LE");
1404 jobject gatt = CALEClientConnect(env, device,
1405 CALEGetFlagFromState(env, jni_address,
1406 CA_LE_AUTO_CONNECT_FLAG,
1408 g_deviceStateListMutex));
1412 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1413 return CA_STATUS_FAILED;
1418 return CA_STATUS_OK;
1421 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1423 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1424 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1426 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1427 "()Landroid/bluetooth/BluetoothDevice;");
1428 if (!jni_mid_getDevice)
1430 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1434 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1435 if (!jni_obj_device)
1437 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1438 CACheckJNIException(env);
1442 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1445 OIC_LOG(ERROR, TAG, "jni_address is null");
1446 CACheckJNIException(env);
1456 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1459 OIC_LOG(DEBUG, TAG, "Gatt Close");
1460 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1461 VERIFY_NON_NULL(env, TAG, "env is null");
1463 // get BluetoothGatt method
1464 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1465 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1466 if (!jni_mid_closeGatt)
1468 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1469 return CA_STATUS_OK;
1472 // call disconnect gatt method
1473 OIC_LOG(DEBUG, TAG, "request to close GATT");
1474 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1476 if (CACheckJNIException(env))
1478 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1479 return CA_STATUS_FAILED;
1482 return CA_STATUS_OK;
1485 CAResult_t CALEClientStartScan()
1487 if (!g_isStartedLEClient)
1489 OIC_LOG(ERROR, TAG, "LE client is not started");
1490 return CA_STATUS_FAILED;
1495 OIC_LOG(ERROR, TAG, "g_jvm is null");
1496 return CA_STATUS_FAILED;
1499 if(g_jniIntSdk < BLE_SCAN_API_LEVEL)
1501 g_setFullScanFlag = true;
1503 bool isAttached = false;
1505 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1508 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1511 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1512 return CA_STATUS_FAILED;
1517 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1519 CAResult_t ret = CA_STATUS_OK;
1520 // scan gatt server with UUID
1521 if (g_leScanCallback && g_uuidList)
1523 if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
1525 if (!g_setFullScanFlag)
1527 //new uuid scan with callback
1528 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 will be called");
1529 ret = CALEClientStartScanWithUUIDImplForV21(env, g_uuidList, g_leScanCallback);
1533 //new full scan with callback
1534 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 will be called");
1535 ret = CALEClientStartScanImplForV21(env, g_leScanCallback);
1540 if (!g_setFullScanFlag)
1542 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl will be called");
1543 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1547 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl will be called");
1548 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1552 if (CA_STATUS_OK != ret)
1554 if (CA_ADAPTER_NOT_ENABLED == ret)
1556 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1560 OIC_LOG(ERROR, TAG, "start scan has failed");
1567 (*g_jvm)->DetachCurrentThread(g_jvm);
1573 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1575 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl IN");
1576 VERIFY_NON_NULL(callback, TAG, "callback is null");
1577 VERIFY_NON_NULL(env, TAG, "env is null");
1579 if (!CALEIsEnableBTAdapter(env))
1581 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1582 return CA_ADAPTER_NOT_ENABLED;
1585 // get default bt adapter class
1586 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1587 if (!jni_cid_BTAdapter)
1589 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1590 CACheckJNIException(env);
1591 return CA_STATUS_FAILED;
1594 // get remote bt adapter method
1595 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1596 "getDefaultAdapter",
1597 METHODID_OBJECTNONPARAM);
1598 if (!jni_mid_getDefaultAdapter)
1600 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1601 CACheckJNIException(env);
1602 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1603 return CA_STATUS_FAILED;
1606 // get start le scan method
1607 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1608 "(Landroid/bluetooth/BluetoothAdapter$"
1609 "LeScanCallback;)Z");
1610 if (!jni_mid_startLeScan)
1612 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1613 CACheckJNIException(env);
1614 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1615 return CA_STATUS_FAILED;
1618 // gat bt adapter object
1619 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1620 jni_mid_getDefaultAdapter);
1621 if (!jni_obj_BTAdapter)
1623 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1624 CACheckJNIException(env);
1625 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1626 return CA_STATUS_FAILED;
1629 // call start le scan method
1630 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1631 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1632 jni_mid_startLeScan, callback);
1633 if (!jni_obj_startLeScan)
1635 OIC_LOG(INFO, TAG, "startLeScan has failed");
1636 CACheckJNIException(env);
1640 OIC_LOG(DEBUG, TAG, "LeScan has started");
1643 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1644 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1645 return CA_STATUS_OK;
1648 CAResult_t CALEClientStartScanImplForV21(JNIEnv *env, jobject callback)
1650 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 IN");
1651 VERIFY_NON_NULL(callback, TAG, "callback is null");
1652 VERIFY_NON_NULL(env, TAG, "env is null");
1654 if (!CALEIsEnableBTAdapter(env))
1656 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1657 return CA_ADAPTER_NOT_ENABLED;
1660 CAResult_t res = CA_STATUS_FAILED;
1661 // get default bt adapter class
1662 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1663 if (!jni_cid_BTAdapter)
1665 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1666 CACheckJNIException(env);
1667 return CA_STATUS_FAILED;
1670 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1671 "getDefaultAdapter",
1672 "()Landroid/bluetooth/"
1673 "BluetoothAdapter;");
1674 if (!jni_mid_getDefaultAdapter)
1676 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1677 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1678 return CA_STATUS_FAILED;
1681 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1682 jni_mid_getDefaultAdapter);
1683 if (!jni_obj_BTAdapter)
1685 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1686 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1687 return CA_STATUS_FAILED;
1690 // get bluetoothLeScanner class
1691 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
1692 if (!jni_cid_leScanner)
1694 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
1695 CACheckJNIException(env);
1696 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1697 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1698 return CA_STATUS_FAILED;
1701 // get remote bt adapter method
1702 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1703 "getBluetoothLeScanner",
1704 "()Landroid/bluetooth/"
1705 "le/BluetoothLeScanner;");
1706 if (!jni_mid_getBluetoothLeScanner)
1708 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
1709 CACheckJNIException(env);
1713 // get startScan(ScanCallback callback) method
1714 jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner, "startScan",
1715 "(Landroid/bluetooth/le/ScanCallback;)V");
1716 if (!jni_mid_startScan)
1718 OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
1719 CACheckJNIException(env);
1723 // gat le scanner object
1724 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
1725 jni_mid_getBluetoothLeScanner);
1726 if (!jni_obj_leScanner)
1728 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
1729 CACheckJNIException(env);
1733 // call startScan method
1734 OIC_LOG(INFO, TAG, "CALL API - startScan(for level21)");
1735 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, callback);
1736 if (CACheckJNIException(env))
1738 OIC_LOG(INFO, TAG, "startScan has failed");
1739 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
1743 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
1746 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1747 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1748 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1752 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1754 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl IN");
1755 VERIFY_NON_NULL(callback, TAG, "callback is null");
1756 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1757 VERIFY_NON_NULL(env, TAG, "env is null");
1759 if (!CALEIsEnableBTAdapter(env))
1761 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1762 return CA_ADAPTER_NOT_ENABLED;
1765 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1766 if (!jni_cid_BTAdapter)
1768 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1769 CACheckJNIException(env);
1770 return CA_STATUS_FAILED;
1773 // get remote bt adapter method
1774 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1775 "getDefaultAdapter",
1776 METHODID_OBJECTNONPARAM);
1777 if (!jni_mid_getDefaultAdapter)
1779 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1780 CACheckJNIException(env);
1781 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1782 return CA_STATUS_FAILED;
1785 // get start le scan method
1786 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1787 "([Ljava/util/UUID;Landroid/bluetooth/"
1788 "BluetoothAdapter$LeScanCallback;)Z");
1789 if (!jni_mid_startLeScan)
1791 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1792 CACheckJNIException(env);
1793 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1794 return CA_STATUS_FAILED;
1797 // get bt adapter object
1798 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1799 jni_mid_getDefaultAdapter);
1800 if (!jni_obj_BTAdapter)
1802 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1803 CACheckJNIException(env);
1804 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1805 return CA_STATUS_FAILED;
1808 // call start le scan method
1809 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1810 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1811 jni_mid_startLeScan, uuids, callback);
1812 if (!jni_obj_startLeScan)
1814 OIC_LOG(INFO, TAG, "startLeScan has failed");
1815 CACheckJNIException(env);
1819 OIC_LOG(DEBUG, TAG, "LeScan has started");
1822 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1823 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1824 return CA_STATUS_OK;
1827 CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids, jobject callback)
1829 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 IN");
1830 VERIFY_NON_NULL(callback, TAG, "callback is null");
1831 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1832 VERIFY_NON_NULL(env, TAG, "env is null");
1835 if (!CALEIsEnableBTAdapter(env))
1837 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1838 return CA_ADAPTER_NOT_ENABLED;
1841 // get bluetoothLeScanner class
1842 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
1843 if (!jni_cid_leScanner)
1845 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
1846 CACheckJNIException(env);
1847 return CA_STATUS_FAILED;
1850 // get startScan(with UUID) method
1851 jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner,
1854 "Landroid/bluetooth/le/ScanSettings;"
1855 "Landroid/bluetooth/le/ScanCallback;"
1857 if (!jni_mid_startScan)
1859 OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
1860 CACheckJNIException(env);
1861 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1862 return CA_STATUS_FAILED;
1864 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1866 // get scanfilter.Builder class id
1867 jclass jni_cid_scanfilterBuilder = (*env)->FindClass(env,
1868 "android/bluetooth/le/"
1869 "ScanFilter$Builder");
1870 if (!jni_cid_scanfilterBuilder)
1872 OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilder is null");
1873 CACheckJNIException(env);
1874 return CA_STATUS_FAILED;
1877 // get scanfilter.Builder(ctor) method id
1878 jmethodID jni_mid_scanfilterBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1880 if (!jni_mid_scanfilterBuilderCtor)
1882 OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilderCtor is null");
1883 CACheckJNIException(env);
1884 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1885 return CA_STATUS_FAILED;
1888 // call scanfilter.Builder()
1889 jobject jni_obj_servicescanfilterBuilder[g_serviceUuidCount];
1890 for (i = 0; i < g_serviceUuidCount; i++)
1892 jni_obj_servicescanfilterBuilder[i] = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
1893 jni_mid_scanfilterBuilderCtor);
1894 if (!jni_obj_servicescanfilterBuilder[i])
1896 OIC_LOG_V(ERROR, TAG, "scanfilter: jni_obj_servicescanfilterBuilder[%d] is null", i);
1897 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1898 for (j = 0; j < i; j++)
1899 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[j]);
1900 return CA_STATUS_FAILED;
1904 // call scanfilter.Builder()
1905 jobject jni_obj_customscanfilterBuilder[g_manufactureDataCount];
1906 for (i = 0; i < g_manufactureDataCount; i++)
1908 jni_obj_customscanfilterBuilder[i] = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
1909 jni_mid_scanfilterBuilderCtor);
1910 if (!jni_obj_customscanfilterBuilder[i])
1912 OIC_LOG_V(ERROR, TAG, "scanfilter: jni_obj_customscanfilterBuilder[%d] is null", i);
1913 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1914 for (j = 0; j < i; j++)
1915 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
1916 return CA_STATUS_FAILED;
1920 // get scanfilter.Builder.setServiceUuid method id
1921 jmethodID jni_mid_setServiceUuid = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1923 "(Landroid/os/ParcelUuid;)Landroid/"
1924 "bluetooth/le/ScanFilter$Builder;");
1925 if (!jni_mid_setServiceUuid)
1927 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setServiceUuid is null");
1928 CACheckJNIException(env);
1929 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1930 for (i = 0; i < g_serviceUuidCount; i++)
1932 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[i]);
1934 for (i = 0; i < g_manufactureDataCount; i++)
1936 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[i]);
1938 return CA_STATUS_FAILED;
1941 // get scanfilter.Builder.setManufacturerData method id
1942 jmethodID jni_mid_setManufacturerData = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1943 "setManufacturerData",
1945 "bluetooth/le/ScanFilter$Builder;");
1946 if (!jni_mid_setManufacturerData)
1948 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setManufacturerData is null");
1949 CACheckJNIException(env);
1950 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1951 for (i = 0; i < g_serviceUuidCount; i++)
1953 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[i]);
1955 for (i = 0; i < g_manufactureDataCount; i++)
1957 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[i]);
1959 return CA_STATUS_FAILED;
1961 // get scanfilter.Builder.build method id
1962 jmethodID jni_mid_build_scanfilterBuilder = (*env)->GetMethodID(env,
1963 jni_cid_scanfilterBuilder,
1965 "()Landroid/bluetooth/le/"
1967 if (!jni_mid_build_scanfilterBuilder)
1969 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_build_scanfilterBuilder is null");
1970 CACheckJNIException(env);
1971 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1972 for (i = 0; i < g_serviceUuidCount; i++)
1974 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[i]);
1976 for (i = 0; i < g_manufactureDataCount; i++)
1978 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[i]);
1980 return CA_STATUS_FAILED;
1982 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1984 jobject jni_obj_parcelUuid, jni_obj_setServiceUuid;
1985 jobject jni_obj_servicescanfilter[g_serviceUuidCount];
1987 for (i = 0; i < g_serviceUuidCount; i++)
1989 // call ParcelUuid.fromSting(uuid)
1990 jni_obj_parcelUuid = CALEGetParcelUuidFromString(env, u_arraylist_get(g_serviceUuidList, i));
1991 if (!jni_obj_parcelUuid)
1993 OIC_LOG(ERROR, TAG, "scanSettings: jni_obj_parcelUuid is null");
1994 CACheckJNIException(env);
1995 for (j = i; j < g_serviceUuidCount; j++)
1997 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[j]);
1999 for (j = 0; j < g_manufactureDataCount; j++)
2001 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
2003 return CA_STATUS_FAILED;
2006 // call setServiceUuid(uuid)
2007 jni_obj_setServiceUuid = (*env)->CallObjectMethod(env,
2008 jni_obj_servicescanfilterBuilder[i],
2009 jni_mid_setServiceUuid,
2010 jni_obj_parcelUuid);
2011 if (!jni_obj_setServiceUuid)
2013 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setServiceUuid is null");
2014 CACheckJNIException(env);
2015 for (j = i; j < g_serviceUuidCount; j++)
2017 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[j]);
2019 for (j = 0; j < g_manufactureDataCount; j++)
2021 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
2023 (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
2024 return CA_STATUS_FAILED;
2026 (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
2027 (*env)->DeleteLocalRef(env, jni_obj_setServiceUuid);
2030 jni_obj_servicescanfilter[i] = (*env)->CallObjectMethod(env,
2031 jni_obj_servicescanfilterBuilder[i],
2032 jni_mid_build_scanfilterBuilder);
2033 if (!jni_obj_servicescanfilter[i])
2035 OIC_LOG_V(ERROR, TAG, "scanfilter: jni_obj_scanfilter[%d] is null", i);
2036 CACheckJNIException(env);
2037 for (j = i; j < g_serviceUuidCount; j++)
2039 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[j]);
2041 for (j = 0; j < g_manufactureDataCount; j++)
2043 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
2045 return CA_STATUS_FAILED;
2047 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilterBuilder[i]);
2049 OIC_LOG_V(DEBUG, TAG, "Total %d Service UUID based scanfilter(s) created by now", i + 1);
2053 jbyteArray jni_byte_manData;
2054 jobject jni_obj_setManufacturerData;
2055 jobject jni_obj_customscanfilter[g_manufactureDataCount];
2056 // set manufactererId
2057 jni_int_manId = MANUFACTURE_ID;
2059 // set custom scanfilters
2060 for (i = 0; i < g_manufactureDataCount; i++)
2062 // call utility function to set manufacturerData
2063 jni_byte_manData = CALEGetManufacturerData(env, u_arraylist_get(g_manufactureDataList, i));
2064 if (!jni_byte_manData)
2066 OIC_LOG(ERROR, TAG, "scanSettings: jni_byte_manData is null");
2067 CACheckJNIException(env);
2068 for(j = i; j < g_manufactureDataCount; j++)
2070 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
2072 return CA_STATUS_FAILED;
2076 jni_obj_setManufacturerData = (*env)->CallObjectMethod(env,
2077 jni_obj_customscanfilterBuilder[i],
2078 jni_mid_setManufacturerData,
2081 if (!jni_obj_setManufacturerData)
2083 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setManufacturerData is null");
2084 CACheckJNIException(env);
2085 for (j = i; j < g_manufactureDataCount; j++)
2087 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
2089 return CA_STATUS_FAILED;
2091 (*env)->DeleteLocalRef(env, jni_byte_manData);
2092 (*env)->DeleteLocalRef(env, jni_obj_setManufacturerData);
2095 jni_obj_customscanfilter[i] = (*env)->CallObjectMethod(env,
2096 jni_obj_customscanfilterBuilder[i],
2097 jni_mid_build_scanfilterBuilder);
2098 if (!jni_obj_customscanfilter[i])
2100 OIC_LOG_V(ERROR, TAG, "scanfilter: jni_obj_customscanfilter[%d] is null", i);
2101 CACheckJNIException(env);
2102 for (j = i; j < g_manufactureDataCount; j++)
2104 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[j]);
2106 return CA_STATUS_FAILED;
2108 (*env)->DeleteLocalRef(env, jni_obj_customscanfilterBuilder[i]);
2110 OIC_LOG_V(DEBUG, TAG, "Total %d manufacture data based scanfilter(s) created by now", i + 1);
2113 // get scanSettings.Builder class id
2114 jclass jni_cid_scanSettingsBuilder = (*env)->FindClass(env,
2115 "android/bluetooth/le/"
2116 "ScanSettings$Builder");
2117 if (!jni_cid_scanSettingsBuilder)
2119 OIC_LOG(ERROR, TAG, "scanSettings: jni_cid_scanSettingsBuilder 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 return CA_STATUS_FAILED;
2132 // get scanSettings.Builder(ctor) method id
2133 jmethodID jni_mid_scanSettingsBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
2135 if (!jni_mid_scanSettingsBuilderCtor)
2137 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_scanSettingsBuilderCtor is null");
2138 CACheckJNIException(env);
2139 for (j = 0; j< g_serviceUuidCount; j++)
2141 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2143 for (j = 0; j< g_manufactureDataCount; j++)
2145 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2147 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2148 return CA_STATUS_FAILED;
2151 // get scanSettings.Builder.setScanMode method id
2152 jmethodID jni_mid_setScanMode = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
2155 "bluetooth/le/ScanSettings$Builder;");
2156 if (!jni_mid_setScanMode)
2158 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_setScanMode is null");
2159 CACheckJNIException(env);
2160 for (j = 0; j< g_serviceUuidCount; j++)
2162 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2164 for (j = 0; j< g_manufactureDataCount; j++)
2166 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2168 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2169 return CA_STATUS_FAILED;
2172 // get scanSettings.Builder.build method id
2173 jmethodID jni_mid_build_scanSettings = (*env)->GetMethodID(env,
2174 jni_cid_scanSettingsBuilder,
2176 "()Landroid/bluetooth/le/"
2178 if (!jni_mid_build_scanSettings)
2180 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_build_scanSettings is null");
2181 CACheckJNIException(env);
2182 for (j = 0; j< g_serviceUuidCount; j++)
2184 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2186 for (j = 0; j< g_manufactureDataCount; j++)
2188 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2190 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2191 return CA_STATUS_FAILED;
2194 // call scanSettings.Builder()
2195 jobject jni_obj_scanSettingBuilder = (*env)->NewObject(env, jni_cid_scanSettingsBuilder,
2196 jni_mid_scanSettingsBuilderCtor);
2197 if (!jni_obj_scanSettingBuilder)
2199 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettingBuilder is null");
2200 CACheckJNIException(env);
2201 for (j = 0; j< g_serviceUuidCount; j++)
2203 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2205 for (j = 0; j< g_manufactureDataCount; j++)
2207 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2209 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2210 return CA_STATUS_FAILED;
2212 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2214 jclass jni_cid_arrayList = (*env)->FindClass(env, "java/util/ArrayList");
2215 if (!jni_cid_arrayList)
2217 OIC_LOG(ERROR, TAG, "ArrayList: jni_cid_arrayList is null");
2218 CACheckJNIException(env);
2219 for (j = 0; j< g_serviceUuidCount; j++)
2221 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2223 for (j = 0; j< g_manufactureDataCount; j++)
2225 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2227 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2228 return CA_STATUS_FAILED;
2231 jmethodID jni_mid_arrayListCtor = (*env)->GetMethodID(env, jni_cid_arrayList, "<init>", "()V");
2232 if (!jni_mid_arrayListCtor)
2234 OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListCtor is null");
2235 CACheckJNIException(env);
2236 for (j = 0; j< g_serviceUuidCount; j++)
2238 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2240 for (j = 0; j< g_manufactureDataCount; j++)
2242 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2244 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2245 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2246 return CA_STATUS_FAILED;
2249 jmethodID jni_mid_arrayListAdd = (*env)->GetMethodID(env, jni_cid_arrayList,
2250 "add", "(Ljava/lang/Object;)Z");
2251 if (!jni_mid_arrayListAdd)
2253 OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListAdd is null");
2254 CACheckJNIException(env);
2255 for (j = 0; j< g_serviceUuidCount; j++)
2257 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2259 for (j = 0; j< g_manufactureDataCount; j++)
2261 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2263 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2264 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2265 return CA_STATUS_FAILED;
2268 jobject jni_obj_filterList = (*env)->NewObject(env, jni_cid_arrayList, jni_mid_arrayListCtor);
2269 if (!jni_obj_filterList)
2271 OIC_LOG(ERROR, TAG, "ArrayList: jni_obj_filterList is null");
2272 for (j = 0; j< g_serviceUuidCount; j++)
2274 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2276 for (j = 0; j< g_manufactureDataCount; j++)
2278 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2280 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2281 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2282 return CA_STATUS_FAILED;
2284 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2286 jboolean jni_bool_arrayListIsAdded;
2287 for (i = 0; i < g_serviceUuidCount; i++)
2289 jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
2290 jni_mid_arrayListAdd,
2291 jni_obj_servicescanfilter[i]);
2292 if (!jni_bool_arrayListIsAdded)
2294 OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
2295 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2296 for(j = i; j < g_serviceUuidCount; j++)
2298 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[j]);
2300 for(j = 0; j < g_manufactureDataCount; j++)
2302 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2304 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2305 return CA_STATUS_FAILED;
2307 (*env)->DeleteLocalRef(env, jni_obj_servicescanfilter[i]);
2308 OIC_LOG_V(INFO, TAG, "%d st/nd/th service uuid based scanFilters Added", i + 1);
2311 for (i = 0; i < g_manufactureDataCount; i++)
2313 jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
2314 jni_mid_arrayListAdd,
2315 jni_obj_customscanfilter[i]);
2316 if (!jni_bool_arrayListIsAdded)
2318 OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
2319 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2320 for(j = i; j < g_manufactureDataCount; j++)
2322 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[j]);
2324 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2325 return CA_STATUS_FAILED;
2327 (*env)->DeleteLocalRef(env, jni_obj_customscanfilter[i]);
2328 OIC_LOG_V(INFO, TAG, "%d st/nd/th manufacture data based scanFilters Added", i + 1);
2331 OIC_LOG(INFO, TAG, "All ScanFilters Added");
2332 // get ScanSettings.SCAN_MODE_BALANCED jint value
2333 jint jni_int_scanBalancedMode = CALEGetConstantsValue(env, CLASSPATH_LE_SCANSETTINGS,
2334 "SCAN_MODE_BALANCED");
2335 CACheckJNIException(env);
2337 // call setScanMode(SCAN_MODE_BALANCED)
2338 jobject jni_obj_setScanMode = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
2339 jni_mid_setScanMode,
2340 jni_int_scanBalancedMode);
2341 if (!jni_obj_setScanMode)
2343 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setScanMode is null");
2344 CACheckJNIException(env);
2345 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2346 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2347 return CA_STATUS_FAILED;
2351 jobject jni_obj_scanSettings = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
2352 jni_mid_build_scanSettings);
2353 if (!jni_obj_scanSettings)
2355 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettings is null");
2356 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2357 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2358 return CA_STATUS_FAILED;
2360 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2362 CAResult_t res = CA_STATUS_FAILED;
2364 // get default bt adapter class
2365 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2366 if (!jni_cid_BTAdapter)
2368 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2369 CACheckJNIException(env);
2373 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2374 "getDefaultAdapter",
2375 "()Landroid/bluetooth/"
2376 "BluetoothAdapter;");
2377 if (!jni_mid_getDefaultAdapter)
2379 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2380 CACheckJNIException(env);
2381 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2385 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2386 jni_mid_getDefaultAdapter);
2387 if (!jni_obj_BTAdapter)
2389 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2390 CACheckJNIException(env);
2391 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2395 // get remote bt adapter method
2396 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2397 "getBluetoothLeScanner",
2398 "()Landroid/bluetooth/"
2399 "le/BluetoothLeScanner;");
2400 if (!jni_mid_getBluetoothLeScanner)
2402 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
2403 CACheckJNIException(env);
2404 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2405 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2409 // get le scanner object
2410 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
2411 jni_mid_getBluetoothLeScanner);
2412 if (!jni_obj_leScanner)
2414 OIC_LOG(ERROR, TAG, "jni_obj_leScanner is null");
2415 CACheckJNIException(env);
2416 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2417 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2420 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2421 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2423 // call startScan method
2424 OIC_LOG(INFO, TAG, "CALL API - startScanWithUUID(for level 21)");
2425 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, jni_obj_filterList,
2426 jni_obj_scanSettings, callback);
2427 if (CACheckJNIException(env))
2429 OIC_LOG(INFO, TAG, "startScan has failed");
2435 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2438 (*env)->DeleteLocalRef(env, jni_obj_scanSettings);
2439 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2443 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
2445 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
2446 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2449 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2452 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
2456 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
2457 "(Ljava/lang/String;)"
2458 "Ljava/util/UUID;");
2459 if (!jni_mid_fromString)
2461 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
2465 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
2466 CACheckJNIException(env);
2467 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
2471 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2475 return jni_obj_uuid;
2478 CACheckJNIException(env);
2482 CAResult_t CALEClientStopScan()
2486 OIC_LOG(ERROR, TAG, "g_jvm is null");
2487 return CA_STATUS_FAILED;
2490 bool isAttached = false;
2492 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2495 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2498 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2499 return CA_STATUS_FAILED;
2504 CAResult_t ret = CA_STATUS_FAILED;
2506 if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
2508 ret = CALEClientStopScanImplForV21(env, g_leScanCallback);
2512 ret = CALEClientStopScanImpl(env, g_leScanCallback);
2515 if (CA_STATUS_OK != ret)
2517 if (CA_ADAPTER_NOT_ENABLED == ret)
2519 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
2523 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
2529 (*g_jvm)->DetachCurrentThread(g_jvm);
2535 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
2537 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl IN");
2538 VERIFY_NON_NULL(callback, TAG, "callback is null");
2539 VERIFY_NON_NULL(env, TAG, "env is null");
2541 if (!CALEIsEnableBTAdapter(env))
2543 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2544 return CA_ADAPTER_NOT_ENABLED;
2547 // get default bt adapter class
2548 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2549 if (!jni_cid_BTAdapter)
2551 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2552 CACheckJNIException(env);
2553 return CA_STATUS_FAILED;
2556 // get remote bt adapter method
2557 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2558 "getDefaultAdapter",
2559 METHODID_OBJECTNONPARAM);
2560 if (!jni_mid_getDefaultAdapter)
2562 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2563 CACheckJNIException(env);
2564 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2565 return CA_STATUS_FAILED;
2568 // get start le scan method
2569 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
2570 "(Landroid/bluetooth/"
2571 "BluetoothAdapter$LeScanCallback;)V");
2572 if (!jni_mid_stopLeScan)
2574 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
2575 CACheckJNIException(env);
2576 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2577 return CA_STATUS_FAILED;
2580 // get bt adapter object
2581 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2582 jni_mid_getDefaultAdapter);
2583 if (!jni_obj_BTAdapter)
2585 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2586 CACheckJNIException(env);
2587 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2588 return CA_STATUS_FAILED;
2591 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
2592 // call start le scan method
2593 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
2594 if (CACheckJNIException(env))
2596 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
2597 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2598 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2599 return CA_STATUS_FAILED;
2602 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2603 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2604 return CA_STATUS_OK;
2607 CAResult_t CALEClientStopScanImplForV21(JNIEnv *env, jobject callback)
2609 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImplForV21 IN");
2610 VERIFY_NON_NULL(callback, TAG, "callback is null");
2611 VERIFY_NON_NULL(env, TAG, "env is null");
2613 if (!CALEIsEnableBTAdapter(env))
2615 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2616 return CA_ADAPTER_NOT_ENABLED;
2619 // get default bt adapter class
2620 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2621 if (!jni_cid_BTAdapter)
2623 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2624 CACheckJNIException(env);
2625 return CA_STATUS_FAILED;
2628 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2629 "getDefaultAdapter",
2630 "()Landroid/bluetooth/"
2631 "BluetoothAdapter;");
2632 if (!jni_mid_getDefaultAdapter)
2634 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2635 CACheckJNIException(env);
2636 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2637 return CA_STATUS_FAILED;
2640 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2641 jni_mid_getDefaultAdapter);
2642 if (!jni_obj_BTAdapter)
2644 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2645 CACheckJNIException(env);
2646 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2647 return CA_STATUS_FAILED;
2650 // get bluetoothLeScanner class
2651 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
2652 if (!jni_cid_leScanner)
2654 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
2655 CACheckJNIException(env);
2656 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2657 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2658 return CA_STATUS_FAILED;
2661 // get remote bt adapter method
2662 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2663 "getBluetoothLeScanner",
2664 "()Landroid/bluetooth/"
2665 "le/BluetoothLeScanner;");
2666 if (!jni_mid_getBluetoothLeScanner)
2668 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
2669 CACheckJNIException(env);
2670 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2671 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2672 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2673 return CA_STATUS_FAILED;
2675 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2677 // get stopScan(ScanCallback callback) method
2678 jmethodID jni_mid_stopScan = (*env)->GetMethodID(env, jni_cid_leScanner, "stopScan",
2679 "(Landroid/bluetooth/le/ScanCallback;)V");
2680 if (!jni_mid_stopScan)
2682 OIC_LOG(ERROR, TAG, "stopScan: jni_mid_stopScan is null");
2683 CACheckJNIException(env);
2684 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2685 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2686 return CA_STATUS_FAILED;
2688 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2690 // gat le scanner object
2691 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
2692 jni_mid_getBluetoothLeScanner);
2693 if (!jni_obj_leScanner)
2695 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
2696 CACheckJNIException(env);
2697 return CA_STATUS_FAILED;
2700 // call stopScan method
2701 OIC_LOG(INFO, TAG, "CALL API - stopScan for level 21");
2702 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_stopScan, callback);
2703 if (CACheckJNIException(env))
2705 OIC_LOG(INFO, TAG, "stopScan for level 21 has failed");
2706 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2707 return CA_STATUS_FAILED;
2710 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2711 return CA_STATUS_OK;
2714 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2716 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
2717 VERIFY_NON_NULL(env, TAG, "env is null");
2718 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
2720 oc_mutex_lock(g_threadSendMutex);
2722 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
2725 OIC_LOG(ERROR, TAG, "jni_address is not available");
2726 oc_mutex_unlock(g_threadSendMutex);
2727 return CA_STATUS_FAILED;
2730 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2733 OIC_LOG(ERROR, TAG, "address is not available");
2734 CACheckJNIException(env);
2735 oc_mutex_unlock(g_threadSendMutex);
2736 return CA_STATUS_FAILED;
2739 CAResult_t res = CA_STATUS_OK;
2740 if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2743 g_deviceStateListMutex))
2745 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
2746 if (NULL == newGatt)
2748 OIC_LOG(INFO, TAG, "newGatt is not available");
2749 res = CA_STATUS_FAILED;
2752 oc_mutex_unlock(g_threadSendMutex);
2757 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2759 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
2760 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2761 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
2763 // reset scan interval time after checking scanned devices
2764 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
2766 // since there is no callback related stop success
2767 // and scanning should be stopped before connectGatt is called.
2768 // it should wait a few micro seconds.
2771 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
2772 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
2775 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2778 OIC_LOG(ERROR, TAG, "address is not available");
2782 // close the gatt service
2783 jobject gatt = CALEClientGetGattObjInList(env, address);
2786 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
2787 if (CA_STATUS_OK != res)
2789 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
2790 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2794 // clean previous gatt object after close profile service
2795 res = CALEClientRemoveGattObjForAddr(env, jni_address);
2796 if (CA_STATUS_OK != res)
2798 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
2799 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2803 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2806 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
2809 OIC_LOG(DEBUG, TAG, "re-connection will be started");
2813 // add new gatt object into g_gattObjectList
2814 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
2815 if (CA_STATUS_OK != res)
2817 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
2824 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2826 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
2827 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2828 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
2830 if (!g_leGattCallback)
2832 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
2836 if (!CALEIsEnableBTAdapter(env))
2838 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2842 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
2845 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
2849 jobject jni_obj_connectGatt = NULL;
2850 jint jni_int_sdk = CALEGetBuildVersion(env);
2851 OIC_LOG_V(INFO, TAG, "API level is %d", jni_int_sdk);
2852 if (jni_int_sdk >= 23) // upper than API level 23
2854 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
2856 "(Landroid/content/Context;ZLandroid/"
2857 "bluetooth/BluetoothGattCallback;I)"
2858 "Landroid/bluetooth/BluetoothGatt;");
2859 if (!jni_mid_connectGatt)
2861 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
2865 jint jni_transport_le = CALEGetConstantsValue(env, CLASSPATH_BT_DEVICE, "TRANSPORT_LE");
2866 OIC_LOG_V(INFO, TAG, "CALL API - connectGatt with transport LE(%d)", jni_transport_le);
2867 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
2868 jni_mid_connectGatt, NULL,
2869 autoconnect, g_leGattCallback,
2871 if (!jni_obj_connectGatt)
2873 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
2874 CACheckJNIException(env);
2875 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
2876 CALEClientUpdateSendCnt(env);
2881 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
2884 else // lower than API level 23
2887 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2890 OIC_LOG(ERROR, TAG, "GetStringUTFChars has failed");
2893 OIC_LOG(INFO, TAG, "CALL API - connectGatt for hidden");
2894 jni_obj_connectGatt = CALEClientHiddenConnectGatt(bluetoothDevice, address, autoconnect);
2898 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
2900 "(Landroid/content/Context;ZLandroid/"
2901 "bluetooth/BluetoothGattCallback;)"
2902 "Landroid/bluetooth/BluetoothGatt;");
2903 if (!jni_mid_connectGatt)
2905 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
2909 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
2910 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
2911 jni_mid_connectGatt,
2913 autoconnect, g_leGattCallback);
2915 if (!jni_obj_connectGatt)
2917 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
2918 CACheckJNIException(env);
2919 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
2920 CALEClientUpdateSendCnt(env);
2925 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
2930 return jni_obj_connectGatt;
2933 bool CALEClientIsConnected(const char* address)
2935 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2936 STATE_SERVICE_CONNECTED,
2938 g_deviceStateListMutex))
2940 OIC_LOG(DEBUG, TAG, "current state is connected");
2943 OIC_LOG(DEBUG, TAG, "current state is not connected");
2947 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
2949 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
2951 VERIFY_NON_NULL(env, TAG, "env is null");
2952 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2954 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2955 if (!jni_cid_BTAdapter)
2957 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
2961 // get remote bt adapter method
2962 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2963 "getDefaultAdapter",
2964 METHODID_OBJECTNONPARAM);
2965 if (!jni_mid_getDefaultAdapter)
2967 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2971 // gat bt adapter object
2972 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2973 jni_mid_getDefaultAdapter);
2974 if (!jni_obj_BTAdapter)
2976 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2980 // get closeProfileProxy method
2981 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2982 "closeProfileProxy",
2983 "(ILandroid/bluetooth/"
2984 "BluetoothProfile;)V");
2985 if (!jni_mid_closeProfileProxy)
2987 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
2991 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
2992 if (!jni_cid_BTProfile)
2994 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
2998 // GATT - Constant value : 7 (0x00000007)
2999 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
3003 OIC_LOG(ERROR, TAG, "id_gatt is null");
3007 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
3008 CACheckJNIException(env);
3010 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
3011 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
3012 if (CACheckJNIException(env))
3014 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
3015 return CA_STATUS_FAILED;
3018 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
3019 return CA_STATUS_OK;
3022 CACheckJNIException(env);
3023 return CA_STATUS_FAILED;
3027 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
3029 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
3030 VERIFY_NON_NULL(env, TAG, "env is null");
3031 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3033 // get BluetoothGatt method
3034 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
3035 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3036 "disconnect", "()V");
3037 if (!jni_mid_disconnectGatt)
3039 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
3040 return CA_STATUS_FAILED;
3043 // call disconnect gatt method
3044 OIC_LOG(INFO, TAG, "CALL API - disconnect");
3045 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
3046 if (CACheckJNIException(env))
3048 OIC_LOG(ERROR, TAG, "disconnect has failed");
3049 return CA_STATUS_FAILED;
3052 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
3054 return CA_STATUS_OK;
3057 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
3059 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
3060 VERIFY_NON_NULL(env, TAG, "env is null");
3062 if (!g_gattObjectList)
3064 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3065 return CA_STATUS_OK;
3068 uint32_t length = u_arraylist_length(g_gattObjectList);
3069 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
3070 for (uint32_t index = 0; index < length; index++)
3072 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
3073 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3076 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3079 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
3080 if (CA_STATUS_OK != res)
3082 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
3087 return CA_STATUS_OK;
3090 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
3092 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
3093 VERIFY_NON_NULL(env, TAG, "env is null");
3095 if (!g_gattObjectList)
3097 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3098 return CA_STATUS_OK;
3101 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
3104 OIC_LOG(ERROR, TAG, "address is null");
3105 CACheckJNIException(env);
3106 return CA_STATUS_FAILED;
3109 uint32_t length = u_arraylist_length(g_gattObjectList);
3110 for (uint32_t index = 0; index < length; index++)
3112 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3115 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3119 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3120 if (!jni_setAddress)
3122 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3123 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3124 return CA_STATUS_FAILED;
3127 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3130 OIC_LOG(ERROR, TAG, "setAddress is null");
3131 CACheckJNIException(env);
3132 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3133 return CA_STATUS_FAILED;
3136 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
3137 if (!strcasecmp(address, setAddress))
3139 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
3140 if (CA_STATUS_OK != res)
3142 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
3143 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3144 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3145 return CA_STATUS_FAILED;
3147 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3148 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3149 return CA_STATUS_OK;
3151 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3153 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3155 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
3156 return CA_STATUS_OK;
3159 CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size)
3161 VERIFY_NON_NULL(env, TAG, "env is null");
3162 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3164 if (!CALEIsEnableBTAdapter(env))
3166 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3167 return CA_ADAPTER_NOT_ENABLED;
3170 // get BluetoothGatt.requestMtu method
3171 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.requestMtu method");
3172 jmethodID jni_mid_requestMtu = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3173 "requestMtu", "(I)Z");
3174 if (!jni_mid_requestMtu)
3176 OIC_LOG(ERROR, TAG, "jni_mid_requestMtu is null");
3177 return CA_STATUS_FAILED;
3181 OIC_LOG(INFO, TAG, "CALL API - requestMtu");
3182 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_requestMtu, size);
3185 OIC_LOG(ERROR, TAG, "requestMtu has failed");
3186 CACheckJNIException(env);
3187 return CA_STATUS_FAILED;
3190 return CA_STATUS_OK;
3193 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
3195 VERIFY_NON_NULL(env, TAG, "env is null");
3196 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3198 if (!CALEIsEnableBTAdapter(env))
3200 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3201 return CA_ADAPTER_NOT_ENABLED;
3204 // get BluetoothGatt.discoverServices method
3205 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
3206 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3207 "discoverServices", "()Z");
3208 if (!jni_mid_discoverServices)
3210 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
3211 return CA_STATUS_FAILED;
3214 // call disconnect gatt method
3215 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
3216 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
3219 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
3220 CACheckJNIException(env);
3221 return CA_STATUS_FAILED;
3224 return CA_STATUS_OK;
3227 static void CALEWriteCharacteristicThread(void* object)
3229 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
3231 bool isAttached = false;
3233 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3236 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3240 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3246 jobject gatt = (jobject)object;
3247 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
3248 if (CA_STATUS_OK != ret)
3250 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
3255 (*g_jvm)->DetachCurrentThread(g_jvm);
3259 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
3261 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
3263 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3264 VERIFY_NON_NULL(env, TAG, "env is null");
3266 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3269 CALEClientSendFinish(env, gatt);
3270 return CA_STATUS_FAILED;
3273 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3276 CACheckJNIException(env);
3277 CALEClientSendFinish(env, gatt);
3278 return CA_STATUS_FAILED;
3281 oc_mutex_lock(g_threadSendStateMutex);
3283 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING,
3285 g_deviceStateListMutex))
3287 OIC_LOG(INFO, TAG, "current state is SENDING");
3288 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3289 oc_mutex_unlock(g_threadSendStateMutex);
3290 return CA_STATUS_OK;
3293 if (CA_STATUS_OK != CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
3296 g_deviceStateListMutex))
3298 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
3299 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3300 CALEClientSendFinish(env, gatt);
3301 oc_mutex_unlock(g_threadSendStateMutex);
3302 return CA_STATUS_FAILED;
3305 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3307 oc_mutex_unlock(g_threadSendStateMutex);
3309 jbyteArray sendData = NULL;
3310 oc_mutex_lock(g_setValueMutex);
3313 OIC_LOG(INFO, TAG, "alloc local reference for data");
3314 sendData = (jbyteArray)(*env)->NewLocalRef(env, g_sendBuffer);
3318 OIC_LOG(ERROR, TAG, "send Buffer is empty");
3319 oc_mutex_unlock(g_setValueMutex);
3320 return CA_STATUS_FAILED;
3322 oc_mutex_unlock(g_setValueMutex);
3325 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, sendData);
3326 if (!jni_obj_character)
3330 (*env)->DeleteLocalRef(env, sendData);
3332 CALEClientSendFinish(env, gatt);
3333 return CA_STATUS_FAILED;
3338 (*env)->DeleteLocalRef(env, sendData);
3341 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
3342 if (CA_STATUS_OK != ret)
3344 CALEClientSendFinish(env, gatt);
3345 return CA_STATUS_FAILED;
3348 // wait for callback for write Characteristic with success to sent data
3349 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
3350 oc_mutex_lock(g_threadWriteCharacteristicMutex);
3351 if (!g_isSignalSetFlag)
3353 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
3354 if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
3355 g_threadWriteCharacteristicMutex,
3356 WAIT_TIME_WRITE_CHARACTERISTIC))
3358 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
3359 g_isSignalSetFlag = false;
3360 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3361 return CA_STATUS_FAILED;
3364 // reset flag set by writeCharacteristic Callback
3365 g_isSignalSetFlag = false;
3366 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3368 CALEClientUpdateSendCnt(env);
3370 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
3371 return CA_STATUS_OK;
3374 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
3376 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
3377 VERIFY_NON_NULL(env, TAG, "env is null");
3378 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3380 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
3381 CACheckJNIException(env);
3382 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEWriteCharacteristicThread,
3383 (void*)gattParam, NULL))
3385 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
3386 return CA_STATUS_FAILED;
3389 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
3390 return CA_STATUS_OK;
3393 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
3394 jobject gattCharacteristic)
3396 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
3397 VERIFY_NON_NULL(env, TAG, "env is null");
3398 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3399 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
3401 if (!CALEIsEnableBTAdapter(env))
3403 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3404 return CA_STATUS_FAILED;
3407 // get BluetoothGatt.write characteristic method
3408 OIC_LOG(DEBUG, TAG, "write characteristic method");
3409 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3410 "writeCharacteristic",
3411 "(Landroid/bluetooth/"
3412 "BluetoothGattCharacteristic;)Z");
3413 if (!jni_mid_writeCharacteristic)
3415 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
3416 return CA_STATUS_FAILED;
3419 // call disconnect gatt method
3420 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
3421 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
3422 jni_mid_writeCharacteristic,
3423 gattCharacteristic);
3426 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
3430 CACheckJNIException(env);
3431 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
3432 return CA_STATUS_FAILED;
3435 return CA_STATUS_OK;
3438 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
3440 VERIFY_NON_NULL(env, TAG, "env is null");
3441 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3443 if (!CALEIsEnableBTAdapter(env))
3445 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3446 return CA_STATUS_FAILED;
3449 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3452 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3453 CACheckJNIException(env);
3454 return CA_STATUS_FAILED;
3457 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
3458 if (!jni_obj_GattCharacteristic)
3460 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3461 return CA_STATUS_FAILED;
3464 OIC_LOG(DEBUG, TAG, "read characteristic method");
3465 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3466 "readCharacteristic",
3467 "(Landroid/bluetooth/"
3468 "BluetoothGattCharacteristic;)Z");
3469 if (!jni_mid_readCharacteristic)
3471 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
3472 return CA_STATUS_FAILED;
3475 // call disconnect gatt method
3476 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
3477 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
3478 jni_obj_GattCharacteristic);
3481 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
3485 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
3486 CACheckJNIException(env);
3487 return CA_STATUS_FAILED;
3490 return CA_STATUS_OK;
3493 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
3494 jobject characteristic)
3496 VERIFY_NON_NULL(env, TAG, "env is null");
3497 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3498 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
3500 if (!CALEIsEnableBTAdapter(env))
3502 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3503 return CA_ADAPTER_NOT_ENABLED;
3506 // get BluetoothGatt.setCharacteristicNotification method
3507 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
3508 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3509 "setCharacteristicNotification",
3510 "(Landroid/bluetooth/"
3511 "BluetoothGattCharacteristic;Z)Z");
3512 if (!jni_mid_setNotification)
3514 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
3515 return CA_STATUS_FAILED;
3518 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
3519 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
3520 characteristic, JNI_TRUE);
3521 if (JNI_TRUE == ret)
3523 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
3527 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
3528 CACheckJNIException(env);
3529 return CA_STATUS_FAILED;
3532 return CA_STATUS_OK;
3535 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
3537 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3538 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
3539 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
3541 if (!CALEIsEnableBTAdapter(env))
3543 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3547 // get BluetoothGatt.getService method
3548 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
3549 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3551 "(Ljava/util/UUID;)Landroid/bluetooth/"
3552 "BluetoothGattService;");
3553 if (!jni_mid_getService)
3555 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
3559 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
3560 if (!jni_obj_service_uuid)
3562 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
3566 // get bluetooth gatt service
3567 OIC_LOG(DEBUG, TAG, "request to get service");
3568 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
3569 jni_obj_service_uuid);
3570 if (!jni_obj_gattService)
3572 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
3573 CACheckJNIException(env);
3577 // get bluetooth gatt service method
3578 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
3579 "BluetoothGattService",
3580 "getCharacteristic",
3581 "(Ljava/util/UUID;)"
3582 "Landroid/bluetooth/"
3583 "BluetoothGattCharacteristic;");
3584 if (!jni_mid_getCharacteristic)
3586 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
3590 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
3593 OIC_LOG(ERROR, TAG, "uuid is null");
3594 CACheckJNIException(env);
3598 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
3599 if (!jni_obj_tx_uuid)
3601 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
3602 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
3606 OIC_LOG(DEBUG, TAG, "CALL API getCharacteristic");
3607 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
3608 jni_mid_getCharacteristic,
3610 if (!jni_obj_GattCharacteristic)
3612 OIC_LOG(ERROR, TAG, "getCharacteristic has failed");
3613 CACheckJNIException(env);
3617 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
3618 return jni_obj_GattCharacteristic;
3621 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
3623 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
3624 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3625 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
3626 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
3628 if (!CALEIsEnableBTAdapter(env))
3630 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3634 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
3637 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3641 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
3642 if (!jni_obj_GattCharacteristic)
3644 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3648 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
3649 "/BluetoothGattCharacteristic");
3650 if (!jni_cid_BTGattCharacteristic)
3652 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
3656 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
3657 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
3659 if (!jni_mid_setValue)
3661 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
3665 OIC_LOG(DEBUG, TAG, "CALL API - setValue");
3666 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
3668 if (JNI_TRUE == ret)
3670 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
3674 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
3680 OIC_LOG(DEBUG, TAG, "setWriteType with WRITE_TYPE_NO_RESPONSE");
3682 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
3683 "setWriteType", "(I)V");
3684 if (!jni_mid_setWriteType)
3686 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
3690 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
3691 "WRITE_TYPE_NO_RESPONSE", "I");
3692 if (!jni_fid_no_response)
3694 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
3698 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
3699 jni_fid_no_response);
3700 CACheckJNIException(env);
3702 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
3703 if (CACheckJNIException(env))
3705 OIC_LOG(ERROR, TAG, "setWriteType has failed");
3710 OIC_LOG(DEBUG, TAG, "It will run with response property");
3713 return jni_obj_GattCharacteristic;
3716 CACheckJNIException(env);
3720 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
3722 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
3723 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3725 if (!CALEIsEnableBTAdapter(env))
3727 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3731 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
3732 "BluetoothGattCharacteristic",
3733 "getValue", "()[B");
3734 if (!jni_mid_getValue)
3736 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
3740 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
3742 CACheckJNIException(env);
3743 return jni_obj_data_array;
3746 CAResult_t CALEClientCreateUUIDList()
3750 OIC_LOG(ERROR, TAG, "g_jvm is null");
3751 return CA_STATUS_FAILED;
3754 bool isAttached = false;
3756 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3759 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3763 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3764 return CA_STATUS_FAILED;
3769 // create new object array
3770 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
3771 if (!jni_cid_uuid_list)
3773 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
3774 CACheckJNIException(env);
3778 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
3779 jni_cid_uuid_list, NULL);
3780 if (!jni_obj_uuid_list)
3782 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
3783 CACheckJNIException(env);
3788 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
3791 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
3794 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
3796 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
3797 CACheckJNIException(env);
3801 (*g_jvm)->DetachCurrentThread(g_jvm);
3804 return CA_STATUS_OK;
3811 (*g_jvm)->DetachCurrentThread(g_jvm);
3813 return CA_STATUS_FAILED;
3816 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
3817 jobject characteristic)
3819 VERIFY_NON_NULL(env, TAG, "env is null");
3820 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3821 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
3823 if (!CALEIsEnableBTAdapter(env))
3825 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3826 return CA_ADAPTER_NOT_ENABLED;
3829 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
3830 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
3831 "BluetoothGattCharacteristic",
3833 "(Ljava/util/UUID;)Landroid/bluetooth/"
3834 "BluetoothGattDescriptor;");
3835 if (!jni_mid_getDescriptor)
3837 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
3838 return CA_STATUS_FAILED;
3841 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
3842 if (!jni_obj_cc_uuid)
3844 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
3847 OIC_LOG(DEBUG, TAG, "request to get descriptor");
3848 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
3849 jni_mid_getDescriptor, jni_obj_cc_uuid);
3850 if (!jni_obj_descriptor)
3852 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
3856 OIC_LOG(DEBUG, TAG, "set value in descriptor");
3857 jclass jni_cid_descriptor = (*env)->FindClass(env,
3858 "android/bluetooth/BluetoothGattDescriptor");
3859 if (!jni_cid_descriptor)
3861 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
3865 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
3866 if (!jni_mid_setValue)
3868 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
3872 jfieldID jni_fid_NotiValue = NULL;
3875 OIC_LOG(DEBUG, TAG, "get ENABLE_INDICATION_VALUE");
3876 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
3877 "ENABLE_INDICATION_VALUE", "[B");
3878 if (!jni_fid_NotiValue)
3880 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
3886 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
3887 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
3888 "ENABLE_NOTIFICATION_VALUE", "[B");
3889 if (!jni_fid_NotiValue)
3891 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
3896 jboolean jni_setvalue = (*env)->CallBooleanMethod(
3897 env, jni_obj_descriptor, jni_mid_setValue,
3898 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
3901 OIC_LOG(DEBUG, TAG, "setValue success");
3905 OIC_LOG(ERROR, TAG, "setValue has failed");
3909 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
3911 "(Landroid/bluetooth/"
3912 "BluetoothGattDescriptor;)Z");
3913 if (!jni_mid_writeDescriptor)
3915 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
3916 return CA_STATUS_FAILED;
3919 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
3920 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
3921 jni_obj_descriptor);
3924 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
3928 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
3932 return CA_STATUS_OK;
3935 CACheckJNIException(env);
3936 return CA_STATUS_FAILED;
3939 void CALEClientCreateScanDeviceList(JNIEnv *env)
3941 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
3942 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3944 oc_mutex_lock(g_deviceListMutex);
3945 // create new object array
3946 if (g_deviceList == NULL)
3948 OIC_LOG(DEBUG, TAG, "Create device list");
3950 g_deviceList = u_arraylist_create();
3952 oc_mutex_unlock(g_deviceListMutex);
3955 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
3957 VERIFY_NON_NULL(device, TAG, "device is null");
3958 VERIFY_NON_NULL(env, TAG, "env is null");
3960 oc_mutex_lock(g_deviceListMutex);
3964 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3965 oc_mutex_unlock(g_deviceListMutex);
3966 return CA_STATUS_FAILED;
3969 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
3970 if (!jni_remoteAddress)
3972 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3973 oc_mutex_unlock(g_deviceListMutex);
3974 return CA_STATUS_FAILED;
3977 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3980 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3981 CACheckJNIException(env);
3982 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3983 oc_mutex_unlock(g_deviceListMutex);
3984 return CA_STATUS_FAILED;
3987 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
3989 jobject gdevice = (*env)->NewGlobalRef(env, device);
3990 CACheckJNIException(env);
3991 u_arraylist_add(g_deviceList, gdevice);
3992 oc_cond_signal(g_deviceDescCond);
3993 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
3995 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3996 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3998 oc_mutex_unlock(g_deviceListMutex);
4000 return CA_STATUS_OK;
4003 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
4005 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
4006 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
4010 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
4014 uint32_t length = u_arraylist_length(g_deviceList);
4015 for (uint32_t index = 0; index < length; index++)
4017 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
4020 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4024 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
4025 if (!jni_setAddress)
4027 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4031 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4034 OIC_LOG(ERROR, TAG, "setAddress is null");
4035 CACheckJNIException(env);
4036 (*env)->DeleteLocalRef(env, jni_setAddress);
4040 if (!strcasecmp(remoteAddress, setAddress))
4042 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4043 (*env)->DeleteLocalRef(env, jni_setAddress);
4047 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4048 (*env)->DeleteLocalRef(env, jni_setAddress);
4053 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
4055 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
4056 VERIFY_NON_NULL(env, TAG, "env is null");
4058 oc_mutex_lock(g_deviceListMutex);
4062 OIC_LOG(ERROR, TAG, "g_deviceList is null");
4063 oc_mutex_unlock(g_deviceListMutex);
4064 return CA_STATUS_FAILED;
4067 uint32_t length = u_arraylist_length(g_deviceList);
4068 for (uint32_t index = 0; index < length; index++)
4070 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
4073 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4076 (*env)->DeleteGlobalRef(env, jarrayObj);
4080 OICFree(g_deviceList);
4081 g_deviceList = NULL;
4083 oc_mutex_unlock(g_deviceListMutex);
4084 return CA_STATUS_OK;
4087 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
4089 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
4090 VERIFY_NON_NULL(address, TAG, "address is null");
4091 VERIFY_NON_NULL(env, TAG, "env is null");
4093 oc_mutex_lock(g_deviceListMutex);
4097 OIC_LOG(ERROR, TAG, "g_deviceList is null");
4098 oc_mutex_unlock(g_deviceListMutex);
4099 return CA_STATUS_FAILED;
4102 uint32_t length = u_arraylist_length(g_deviceList);
4103 for (uint32_t index = 0; index < length; index++)
4105 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
4108 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4109 oc_mutex_unlock(g_deviceListMutex);
4110 return CA_STATUS_FAILED;
4113 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
4114 if (!jni_setAddress)
4116 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4117 oc_mutex_unlock(g_deviceListMutex);
4118 return CA_STATUS_FAILED;
4121 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4124 OIC_LOG(ERROR, TAG, "setAddress is null");
4125 CACheckJNIException(env);
4126 oc_mutex_unlock(g_deviceListMutex);
4127 return CA_STATUS_FAILED;
4130 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
4133 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4134 CACheckJNIException(env);
4135 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4136 oc_mutex_unlock(g_deviceListMutex);
4137 return CA_STATUS_FAILED;
4140 if (!strcasecmp(setAddress, remoteAddress))
4142 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4143 (*env)->DeleteGlobalRef(env, jarrayObj);
4145 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4146 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
4148 if (NULL == u_arraylist_remove(g_deviceList, index))
4150 OIC_LOG(ERROR, TAG, "List removal failed.");
4151 oc_mutex_unlock(g_deviceListMutex);
4152 return CA_STATUS_FAILED;
4154 oc_mutex_unlock(g_deviceListMutex);
4155 return CA_STATUS_OK;
4157 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4158 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
4161 oc_mutex_unlock(g_deviceListMutex);
4162 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
4164 return CA_STATUS_OK;
4171 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
4173 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
4174 VERIFY_NON_NULL(env, TAG, "env is null");
4175 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
4177 oc_mutex_lock(g_gattObjectMutex);
4179 if (!g_gattObjectList)
4181 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
4182 oc_mutex_unlock(g_gattObjectMutex);
4183 return CA_STATUS_FAILED;
4186 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
4187 if (!jni_remoteAddress)
4189 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
4190 oc_mutex_unlock(g_gattObjectMutex);
4191 return CA_STATUS_FAILED;
4194 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
4197 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4198 CACheckJNIException(env);
4199 (*env)->DeleteLocalRef(env, jni_remoteAddress);
4200 oc_mutex_unlock(g_gattObjectMutex);
4201 return CA_STATUS_FAILED;
4204 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
4205 if (!CALEClientIsGattObjInList(env, remoteAddress))
4207 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
4208 u_arraylist_add(g_gattObjectList, newGatt);
4209 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
4212 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4213 (*env)->DeleteLocalRef(env, jni_remoteAddress);
4214 oc_mutex_unlock(g_gattObjectMutex);
4215 return CA_STATUS_OK;
4218 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
4220 VERIFY_NON_NULL(env, TAG, "env is null");
4221 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
4223 uint32_t length = u_arraylist_length(g_gattObjectList);
4224 for (uint32_t index = 0; index < length; index++)
4226 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4229 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4233 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4234 if (!jni_setAddress)
4236 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4240 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4243 OIC_LOG(ERROR, TAG, "setAddress is null");
4244 CACheckJNIException(env);
4245 (*env)->DeleteLocalRef(env, jni_setAddress);
4249 if (!strcasecmp(remoteAddress, setAddress))
4251 OIC_LOG(DEBUG, TAG, "the device is already set");
4252 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4253 (*env)->DeleteLocalRef(env, jni_setAddress);
4256 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4257 (*env)->DeleteLocalRef(env, jni_setAddress);
4260 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
4264 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
4266 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
4267 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4268 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
4270 oc_mutex_lock(g_gattObjectMutex);
4271 uint32_t length = u_arraylist_length(g_gattObjectList);
4272 for (uint32_t index = 0; index < length; index++)
4274 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4277 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4278 oc_mutex_unlock(g_gattObjectMutex);
4282 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4283 if (!jni_setAddress)
4285 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4286 oc_mutex_unlock(g_gattObjectMutex);
4290 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4293 OIC_LOG(ERROR, TAG, "setAddress is null");
4294 CACheckJNIException(env);
4295 (*env)->DeleteLocalRef(env, jni_setAddress);
4296 oc_mutex_unlock(g_gattObjectMutex);
4300 if (!strcasecmp(remoteAddress, setAddress))
4302 OIC_LOG(DEBUG, TAG, "the device is already set");
4303 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4304 oc_mutex_unlock(g_gattObjectMutex);
4307 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4308 (*env)->DeleteLocalRef(env, jni_setAddress);
4311 oc_mutex_unlock(g_gattObjectMutex);
4312 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
4316 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
4318 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
4319 VERIFY_NON_NULL(env, TAG, "env is null");
4321 oc_mutex_lock(g_gattObjectMutex);
4322 if (!g_gattObjectList)
4324 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4325 oc_mutex_unlock(g_gattObjectMutex);
4326 return CA_STATUS_OK;
4329 uint32_t length = u_arraylist_length(g_gattObjectList);
4330 for (uint32_t index = 0; index < length; index++)
4332 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4335 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4338 (*env)->DeleteGlobalRef(env, jarrayObj);
4342 OICFree(g_gattObjectList);
4343 g_gattObjectList = NULL;
4344 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
4345 oc_mutex_unlock(g_gattObjectMutex);
4346 return CA_STATUS_OK;
4349 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
4351 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
4352 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
4353 VERIFY_NON_NULL(env, TAG, "env is null");
4355 oc_mutex_lock(g_gattObjectMutex);
4356 if (!g_gattObjectList)
4358 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4359 oc_mutex_unlock(g_gattObjectMutex);
4360 return CA_STATUS_OK;
4363 uint32_t length = u_arraylist_length(g_gattObjectList);
4364 for (uint32_t index = 0; index < length; index++)
4366 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4369 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4370 oc_mutex_unlock(g_gattObjectMutex);
4371 return CA_STATUS_FAILED;
4374 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4375 if (!jni_setAddress)
4377 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4378 oc_mutex_unlock(g_gattObjectMutex);
4379 return CA_STATUS_FAILED;
4382 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4385 OIC_LOG(ERROR, TAG, "setAddress is null");
4386 CACheckJNIException(env);
4387 oc_mutex_unlock(g_gattObjectMutex);
4388 return CA_STATUS_FAILED;
4391 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
4392 if (!jni_remoteAddress)
4394 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
4395 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4396 oc_mutex_unlock(g_gattObjectMutex);
4397 return CA_STATUS_FAILED;
4400 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
4403 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4404 CACheckJNIException(env);
4405 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4406 oc_mutex_unlock(g_gattObjectMutex);
4407 return CA_STATUS_FAILED;
4410 if (!strcasecmp(setAddress, remoteAddress))
4412 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4413 (*env)->DeleteGlobalRef(env, jarrayObj);
4415 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4416 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4418 if (NULL == u_arraylist_remove(g_gattObjectList, index))
4420 OIC_LOG(ERROR, TAG, "List removal failed.");
4421 oc_mutex_unlock(g_gattObjectMutex);
4422 return CA_STATUS_FAILED;
4424 oc_mutex_unlock(g_gattObjectMutex);
4425 return CA_STATUS_OK;
4427 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4428 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4431 oc_mutex_unlock(g_gattObjectMutex);
4432 OIC_LOG(DEBUG, TAG, "there are no target object");
4433 return CA_STATUS_OK;
4436 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
4438 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
4439 VERIFY_NON_NULL(addr, TAG, "addr is null");
4440 VERIFY_NON_NULL(env, TAG, "env is null");
4442 oc_mutex_lock(g_gattObjectMutex);
4443 if (!g_gattObjectList)
4445 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4446 oc_mutex_unlock(g_gattObjectMutex);
4447 return CA_STATUS_OK;
4450 uint32_t length = u_arraylist_length(g_gattObjectList);
4451 for (uint32_t index = 0; index < length; index++)
4453 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4456 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4457 oc_mutex_unlock(g_gattObjectMutex);
4458 return CA_STATUS_FAILED;
4461 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4462 if (!jni_setAddress)
4464 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4465 oc_mutex_unlock(g_gattObjectMutex);
4466 return CA_STATUS_FAILED;
4469 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4472 OIC_LOG(ERROR, TAG, "setAddress is null");
4473 CACheckJNIException(env);
4474 oc_mutex_unlock(g_gattObjectMutex);
4475 return CA_STATUS_FAILED;
4478 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
4481 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4482 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4483 oc_mutex_unlock(g_gattObjectMutex);
4484 return CA_STATUS_FAILED;
4487 if (!strcasecmp(setAddress, remoteAddress))
4489 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4490 (*env)->DeleteGlobalRef(env, jarrayObj);
4492 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4493 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
4494 if (NULL == u_arraylist_remove(g_gattObjectList, index))
4496 OIC_LOG(ERROR, TAG, "List removal failed.");
4497 oc_mutex_unlock(g_gattObjectMutex);
4498 return CA_STATUS_FAILED;
4500 oc_mutex_unlock(g_gattObjectMutex);
4501 return CA_STATUS_OK;
4503 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4504 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
4507 oc_mutex_unlock(g_gattObjectMutex);
4508 OIC_LOG(DEBUG, TAG, "there are no target object");
4509 return CA_STATUS_FAILED;
4512 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
4514 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
4515 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
4517 // get Bluetooth Address
4518 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
4519 if (!jni_btTargetAddress)
4521 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4525 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
4528 OIC_LOG(ERROR, TAG, "targetAddress is not available");
4529 CACheckJNIException(env);
4533 // get method ID of getDevice()
4534 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
4535 "getDevice", METHODID_BT_DEVICE);
4536 if (!jni_mid_getDevice)
4538 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4539 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4543 oc_mutex_lock(g_gattObjectMutex);
4545 size_t length = u_arraylist_length(g_gattObjectList);
4546 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
4547 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
4549 for (size_t index = 0; index < length; index++)
4551 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4554 oc_mutex_unlock(g_gattObjectMutex);
4555 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4556 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4560 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
4561 if (!jni_obj_device)
4563 CACheckJNIException(env);
4564 oc_mutex_unlock(g_gattObjectMutex);
4565 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4566 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4570 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
4573 oc_mutex_unlock(g_gattObjectMutex);
4574 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4575 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4576 (*env)->DeleteLocalRef(env, jni_obj_device);
4580 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
4583 CACheckJNIException(env);
4584 oc_mutex_unlock(g_gattObjectMutex);
4585 OIC_LOG(ERROR, TAG, "btAddress is not available");
4586 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4587 (*env)->DeleteLocalRef(env, jni_btAddress);
4588 (*env)->DeleteLocalRef(env, jni_obj_device);
4592 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
4593 if (!strcasecmp(targetAddress, btAddress))
4595 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
4598 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4601 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
4603 oc_mutex_unlock(g_gattObjectMutex);
4604 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4605 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
4606 (*env)->DeleteLocalRef(env, jni_btAddress);
4607 (*env)->DeleteLocalRef(env, jni_obj_device);
4608 return jni_LEAddress;
4610 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
4611 (*env)->DeleteLocalRef(env, jni_btAddress);
4612 (*env)->DeleteLocalRef(env, jni_obj_device);
4614 oc_mutex_unlock(g_gattObjectMutex);
4616 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4617 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
4624 CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env,
4626 uint16_t state_type,
4627 uint16_t target_state)
4629 VERIFY_NON_NULL(device, TAG, "device is null");
4631 // get Bluetooth Address
4632 jstring jni_Address = CALEGetAddressFromBTDevice(env, device);
4635 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4636 return CA_STATUS_FAILED;
4639 const char* address = (*env)->GetStringUTFChars(env, jni_Address, NULL);
4642 OIC_LOG(ERROR, TAG, "targetAddress is not available");
4643 CACheckJNIException(env);
4644 (*env)->DeleteLocalRef(env, jni_Address);
4645 return CA_STATUS_FAILED;
4648 if (CALEIsValidState(address, state_type, target_state,
4650 g_deviceStateListMutex))
4652 (*env)->DeleteLocalRef(env, jni_Address);
4653 return CA_STATUS_OK;
4656 CAResult_t res = CALEUpdateDeviceState(address, state_type,
4659 g_deviceStateListMutex);
4660 if (CA_STATUS_OK != res)
4662 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4664 (*env)->ReleaseStringUTFChars(env, jni_Address, address);
4665 (*env)->DeleteLocalRef(env, jni_Address);
4670 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
4671 jint state_idx, jboolean flag)
4673 return CALESetFlagToState(env, jni_address, state_idx, flag,
4674 g_deviceStateList, g_deviceStateListMutex);
4677 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
4679 return CALEGetFlagFromState(env, jni_address, state_idx, g_deviceStateList,
4680 g_deviceStateListMutex);
4683 uint16_t CALEClientGetMtuSize(const char* address)
4685 return CALEGetMtuSize(address, g_deviceStateList, g_deviceStateListMutex);
4688 void CALEClientCreateDeviceList()
4690 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
4692 // create new object array
4693 if (!g_gattObjectList)
4695 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
4697 g_gattObjectList = u_arraylist_create();
4700 if (!g_deviceStateList)
4702 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
4704 g_deviceStateList = u_arraylist_create();
4709 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
4711 g_deviceList = u_arraylist_create();
4715 CAResult_t CALEClientResetDeviceStateForAll()
4717 return CALEResetDeviceStateForAll(g_deviceStateList, g_deviceStateListMutex);
4721 * Check Sent Count for remove g_sendBuffer
4723 void CALEClientUpdateSendCnt(JNIEnv *env)
4725 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
4727 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4729 oc_mutex_lock(g_threadMutex);
4733 if (g_targetCnt <= g_currentSentCnt)
4736 g_currentSentCnt = 0;
4738 CALEDeleteSendBuffer(env);
4740 // notity the thread
4741 oc_cond_signal(g_threadCond);
4742 oc_cond_signal(g_threadWriteCharacteristicCond);
4744 CALEClientSetSendFinishFlag(true);
4745 OIC_LOG(DEBUG, TAG, "set signal for send data");
4748 #ifdef SCAN_INTERVAL
4749 // reset interval scan logic
4750 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
4754 oc_mutex_unlock(g_threadMutex);
4757 CAResult_t CALEClientInitGattMutexVaraibles()
4759 if (NULL == g_bleServerBDAddressMutex)
4761 g_bleServerBDAddressMutex = oc_mutex_new();
4762 if (NULL == g_bleServerBDAddressMutex)
4764 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4765 return CA_STATUS_FAILED;
4769 if (NULL == g_threadMutex)
4771 g_threadMutex = oc_mutex_new();
4772 if (NULL == g_threadMutex)
4774 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4775 return CA_STATUS_FAILED;
4779 if (NULL == g_threadSendMutex)
4781 g_threadSendMutex = oc_mutex_new();
4782 if (NULL == g_threadSendMutex)
4784 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4785 return CA_STATUS_FAILED;
4789 if (NULL == g_deviceListMutex)
4791 g_deviceListMutex = oc_mutex_new();
4792 if (NULL == g_deviceListMutex)
4794 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4795 return CA_STATUS_FAILED;
4799 if (NULL == g_gattObjectMutex)
4801 g_gattObjectMutex = oc_mutex_new();
4802 if (NULL == g_gattObjectMutex)
4804 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4805 return CA_STATUS_FAILED;
4809 if (NULL == g_deviceStateListMutex)
4811 g_deviceStateListMutex = oc_mutex_new();
4812 if (NULL == g_deviceStateListMutex)
4814 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4815 return CA_STATUS_FAILED;
4819 if (NULL == g_SendFinishMutex)
4821 g_SendFinishMutex = oc_mutex_new();
4822 if (NULL == g_SendFinishMutex)
4824 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4825 return CA_STATUS_FAILED;
4829 if (NULL == g_threadWriteCharacteristicMutex)
4831 g_threadWriteCharacteristicMutex = oc_mutex_new();
4832 if (NULL == g_threadWriteCharacteristicMutex)
4834 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4835 return CA_STATUS_FAILED;
4839 if (NULL == g_deviceScanRetryDelayMutex)
4841 g_deviceScanRetryDelayMutex = oc_mutex_new();
4842 if (NULL == g_deviceScanRetryDelayMutex)
4844 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4845 return CA_STATUS_FAILED;
4849 if (NULL == g_threadSendStateMutex)
4851 g_threadSendStateMutex = oc_mutex_new();
4852 if (NULL == g_threadSendStateMutex)
4854 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4855 return CA_STATUS_FAILED;
4859 if (NULL == g_threadScanIntervalMutex)
4861 g_threadScanIntervalMutex = oc_mutex_new();
4862 if (NULL == g_threadScanIntervalMutex)
4864 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4865 return CA_STATUS_FAILED;
4869 if (NULL == g_setValueMutex)
4871 g_setValueMutex = oc_mutex_new();
4872 if (NULL == g_setValueMutex)
4874 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4875 return CA_STATUS_FAILED;
4879 return CA_STATUS_OK;
4882 void CALEClientTerminateGattMutexVariables()
4885 oc_mutex_free(g_bleServerBDAddressMutex);
4886 g_bleServerBDAddressMutex = NULL;
4888 oc_mutex_free(g_threadMutex);
4889 g_threadMutex = NULL;
4891 oc_mutex_free(g_threadSendMutex);
4892 g_threadSendMutex = NULL;
4894 oc_mutex_free(g_deviceListMutex);
4895 g_deviceListMutex = NULL;
4897 oc_mutex_free(g_SendFinishMutex);
4898 g_SendFinishMutex = NULL;
4900 oc_mutex_free(g_threadWriteCharacteristicMutex);
4901 g_threadWriteCharacteristicMutex = NULL;
4903 oc_mutex_free(g_deviceScanRetryDelayMutex);
4904 g_deviceScanRetryDelayMutex = NULL;
4906 oc_mutex_free(g_threadSendStateMutex);
4907 g_threadSendStateMutex = NULL;
4909 oc_mutex_free(g_threadScanIntervalMutex);
4910 g_threadScanIntervalMutex = NULL;
4912 oc_mutex_free(g_gattObjectMutex);
4913 g_gattObjectMutex = NULL;
4915 oc_mutex_free(g_deviceStateListMutex);
4916 g_deviceStateListMutex = NULL;
4918 oc_mutex_free(g_setValueMutex);
4919 g_setValueMutex = NULL;
4922 void CALEClientSetSendFinishFlag(bool flag)
4924 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
4926 oc_mutex_lock(g_SendFinishMutex);
4927 g_isFinishedSendData = flag;
4928 oc_mutex_unlock(g_SendFinishMutex);
4935 CAResult_t CAStartLEGattClient()
4937 // init mutex for send logic
4938 if (!g_deviceDescCond)
4940 g_deviceDescCond = oc_cond_new();
4945 g_threadCond = oc_cond_new();
4948 if (!g_threadWriteCharacteristicCond)
4950 g_threadWriteCharacteristicCond = oc_cond_new();
4953 if (!g_threadScanIntervalCond)
4955 g_threadScanIntervalCond = oc_cond_new();
4958 CAResult_t ret = CALEClientStartScanWithInterval();
4959 if (CA_STATUS_OK != ret)
4961 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
4965 g_isStartedLEClient = true;
4966 return CA_STATUS_OK;
4969 void CAStopLEGattClient()
4971 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
4975 OIC_LOG(ERROR, TAG, "g_jvm is null");
4979 bool isAttached = false;
4981 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
4984 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
4988 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
4994 CAResult_t ret = CALEClientDisconnectAll(env);
4995 if (CA_STATUS_OK != ret)
4997 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
5000 CALEClientStopScanWithInterval();
5002 oc_mutex_lock(g_threadWriteCharacteristicMutex);
5003 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
5004 oc_cond_signal(g_threadWriteCharacteristicCond);
5005 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
5007 CALEClientSetSendFinishFlag(true);
5008 oc_mutex_lock(g_threadMutex);
5009 OIC_LOG(DEBUG, TAG, "signal - g_threadCond cond");
5010 oc_cond_signal(g_threadCond);
5011 oc_mutex_unlock(g_threadMutex);
5013 oc_mutex_lock(g_deviceScanRetryDelayMutex);
5014 OIC_LOG(DEBUG, TAG, "signal - delay cond");
5015 oc_cond_signal(g_deviceScanRetryDelayCond);
5016 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
5018 oc_mutex_lock(g_threadScanIntervalMutex);
5019 OIC_LOG(DEBUG, TAG, "signal - delay cond");
5020 oc_cond_signal(g_threadScanIntervalCond);
5021 oc_mutex_unlock(g_threadScanIntervalMutex);
5023 oc_mutex_lock(g_threadSendMutex);
5024 OIC_LOG(DEBUG, TAG, "signal - g_deviceDesc cond");
5025 oc_cond_signal(g_deviceDescCond);
5026 oc_mutex_unlock(g_threadSendMutex);
5028 oc_cond_free(g_deviceDescCond);
5029 oc_cond_free(g_threadCond);
5030 oc_cond_free(g_threadWriteCharacteristicCond);
5031 oc_cond_free(g_deviceScanRetryDelayCond);
5032 oc_cond_free(g_threadScanIntervalCond);
5034 g_deviceDescCond = NULL;
5035 g_threadCond = NULL;
5036 g_threadWriteCharacteristicCond = NULL;
5037 g_deviceScanRetryDelayCond = NULL;
5038 g_threadScanIntervalCond = NULL;
5042 (*g_jvm)->DetachCurrentThread(g_jvm);
5047 CAResult_t CAInitializeLEGattClient()
5049 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
5050 CALEClientInitialize();
5051 return CA_STATUS_OK;
5054 void CATerminateLEGattClient()
5056 OIC_LOG(INFO, TAG, "IN - Terminate GATT Client");
5057 CAStopLEGattClient();
5058 CALEClientTerminate();
5059 OIC_LOG(INFO, TAG, "OUT - Terminate GATT Client");
5062 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
5063 uint32_t dataLen, CALETransferType_t type,
5066 OIC_LOG(INFO, TAG, "call CALEClientSendUnicastMessage");
5067 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
5069 if (LE_UNICAST != type || position < 0)
5071 OIC_LOG(ERROR, TAG, "this request is not unicast");
5072 return CA_STATUS_INVALID_PARAM;
5075 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
5078 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
5080 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
5081 VERIFY_NON_NULL(data, TAG, "data is null");
5083 return CALEClientSendMulticastMessage(data, dataLen);
5086 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
5089 g_CABLEClientDataReceivedCallback = callback;
5093 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
5095 g_threadPoolHandle = handle;
5098 CAResult_t CAGetLEAddress(char **local_address)
5100 VERIFY_NON_NULL(local_address, TAG, "local_address");
5101 return CA_NOT_SUPPORTED;
5104 JNIEXPORT void JNICALL
5105 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
5108 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
5109 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5110 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5111 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
5113 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
5114 CACheckJNIException(env);
5117 JNIEXPORT void JNICALL
5118 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallbackForV21(JNIEnv *env,
5122 OIC_LOG(DEBUG, TAG, "caLeRegisterLeScanCallbackForV21");
5123 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5124 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5125 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
5127 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
5128 CACheckJNIException(env);
5131 JNIEXPORT void JNICALL
5132 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
5135 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
5136 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5137 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5138 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
5140 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
5141 CACheckJNIException(env);
5144 JNIEXPORT void JNICALL
5145 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
5148 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5149 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5150 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
5152 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
5153 if (CA_STATUS_OK != res)
5155 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
5159 JNIEXPORT void JNICALL
5160 Java_org_iotivity_ca_CaLeClientInterface_caLeScanFailedCallback(JNIEnv *env, jobject obj,
5163 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5164 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5169 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_ALREADY_STARTED");
5174 "BLE scan has failed, error is SCAN_FAILED_APPLICATION_REGISTRATION_FAILED");
5178 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_INTERNAL_ERROR");
5182 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_FEATURE_UNSUPPORTED");
5186 OIC_LOG(ERROR, TAG, "BLE scan has failed with unknown error");
5192 * Class: org_iotivity_ca_jar_caleinterface
5193 * Method: CALeGattConnectionStateChangeCallback
5194 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
5196 JNIEXPORT void JNICALL
5197 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
5203 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
5205 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5206 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5207 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5209 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
5211 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5214 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
5218 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5221 OIC_LOG(ERROR, TAG, "address is null");
5222 CACheckJNIException(env);
5225 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
5227 if (state_connected == newstate)
5229 OIC_LOG(DEBUG, TAG, "LE is connected");
5230 if (GATT_SUCCESS == status)
5232 CAResult_t res = CALEUpdateDeviceState(address,
5233 CA_LE_CONNECTION_STATE,
5236 g_deviceStateListMutex);
5237 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5238 if (CA_STATUS_OK != res)
5240 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5244 res = CALEClientAddGattobjToList(env, gatt);
5245 if (CA_STATUS_OK != res)
5247 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
5251 res = CALEClientDiscoverServices(env, gatt);
5252 if (CA_STATUS_OK != res)
5254 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
5260 OIC_LOG(INFO, TAG, "unknown status");
5261 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5264 else // STATE_DISCONNECTED == newstate
5266 OIC_LOG(DEBUG, TAG, "LE is disconnected");
5268 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SEND_PREPARING,
5269 g_deviceStateList, g_deviceStateListMutex))
5271 OIC_LOG(INFO, TAG, "current state is STATE_SEND_PREPARING");
5272 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5275 g_deviceStateListMutex);
5276 if (CA_STATUS_OK != res)
5278 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5282 CAResult_t res = CALEUpdateDeviceState(address,
5283 CA_LE_CONNECTION_STATE,
5286 g_deviceStateListMutex);
5287 if (CA_STATUS_OK != res)
5289 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5291 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5293 res = CALEClientGattClose(env, gatt);
5294 if (CA_STATUS_OK != res)
5296 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
5299 if (CALECheckConnectionStateValue(status))
5301 // this state is unexpected reason to disconnect
5302 // if the reason is suitable, connection logic of the device will be destroyed.
5303 OIC_LOG(INFO, TAG, "connection logic destroy");
5307 // other reason except for gatt_success is expected to running
5308 // background connection in BT platform.
5309 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
5311 CALEClientUpdateSendCnt(env);
5317 CALEClientSendFinish(env, gatt);
5322 * Class: org_iotivity_ca_jar_caleinterface
5323 * Method: CALeGattServicesDiscoveredCallback
5324 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
5326 JNIEXPORT void JNICALL
5327 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
5332 OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status);
5333 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5334 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5335 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5337 if (GATT_SUCCESS != status) // discovery error
5339 CALEClientSendFinish(env, gatt);
5343 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5346 CALEClientSendFinish(env, gatt);
5350 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5353 CACheckJNIException(env);
5354 CALEClientSendFinish(env, gatt);
5358 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
5361 OIC_LOG(ERROR, TAG, "jni_uuid is null");
5365 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
5366 if (!jni_obj_GattCharacteristic)
5368 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
5372 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
5373 jni_obj_GattCharacteristic);
5374 if (CA_STATUS_OK != res)
5376 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
5380 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
5381 if (CA_STATUS_OK != res)
5383 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
5385 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE,
5386 g_deviceStateList, g_deviceStateListMutex);
5387 if (CA_STATUS_OK != res)
5389 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
5393 res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
5394 STATE_SERVICE_CONNECTED,
5396 g_deviceStateListMutex);
5397 if (CA_STATUS_OK != res)
5399 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5403 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
5404 if (CA_STATUS_OK != res)
5406 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
5412 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE,
5413 g_deviceStateList, g_deviceStateListMutex);
5414 if (CA_STATUS_OK != res)
5416 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
5421 #ifdef SCAN_INTERVAL
5422 // reset interval scan logic
5423 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
5426 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
5427 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5432 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
5433 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5434 CALEClientSendFinish(env, gatt);
5439 * Class: org_iotivity_ca_jar_caleinterface
5440 * Method: CALeGattCharacteristicWritjclasseCallback
5441 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
5443 JNIEXPORT void JNICALL
5444 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
5445 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status)
5447 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
5448 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5449 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5450 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5452 // send success & signal
5453 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5459 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5462 CACheckJNIException(env);
5466 if (GATT_SUCCESS != status) // error case
5468 OIC_LOG(ERROR, TAG, "send failure");
5471 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
5472 if (CA_STATUS_OK != res)
5474 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
5475 oc_mutex_lock(g_threadWriteCharacteristicMutex);
5476 g_isSignalSetFlag = true;
5477 oc_cond_signal(g_threadWriteCharacteristicCond);
5478 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
5480 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5483 g_deviceStateListMutex);
5484 if (CA_STATUS_OK != res)
5486 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5489 if (g_clientErrorCallback)
5491 jint length = (*env)->GetArrayLength(env, data);
5492 CACheckJNIException(env);
5493 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
5494 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, length,
5495 false, "writeChar failure");
5498 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5504 OIC_LOG(DEBUG, TAG, "send success");
5505 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5508 g_deviceStateListMutex);
5509 if (CA_STATUS_OK != res)
5511 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5514 oc_mutex_lock(g_threadWriteCharacteristicMutex);
5515 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
5516 g_isSignalSetFlag = true;
5517 oc_cond_signal(g_threadWriteCharacteristicCond);
5518 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
5520 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0,
5521 (*env)->GetArrayLength(env, data),
5522 true, "writeChar success");
5525 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5531 CALEClientSendFinish(env, gatt);
5536 * Class: org_iotivity_ca_jar_caleinterface
5537 * Method: CALeGattCharacteristicChangedCallback
5538 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
5540 JNIEXPORT void JNICALL
5541 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
5542 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
5544 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
5545 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5546 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5547 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5548 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
5550 // get Byte Array and convert to uint8_t*
5551 jint length = (*env)->GetArrayLength(env, data);
5554 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
5555 CACheckJNIException(env);
5557 uint8_t* receivedData = OICMalloc(length);
5560 OIC_LOG(ERROR, TAG, "receivedData is null");
5564 memcpy(receivedData, jni_byte_responseData, length);
5565 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
5567 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5570 OIC_LOG(ERROR, TAG, "jni_address is null");
5571 OICFree(receivedData);
5575 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5578 OIC_LOG(ERROR, TAG, "address is null");
5579 CACheckJNIException(env);
5580 OICFree(receivedData);
5584 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
5585 receivedData, length);
5587 uint32_t sentLength = 0;
5588 oc_mutex_lock(g_bleServerBDAddressMutex);
5589 g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
5590 oc_mutex_unlock(g_bleServerBDAddressMutex);
5592 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5596 * Class: org_iotivity_ca_jar_caleinterface
5597 * Method: CALeGattDescriptorWriteCallback
5598 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
5600 JNIEXPORT void JNICALL
5601 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
5605 OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status);
5606 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5607 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5608 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5610 if (GATT_SUCCESS != status) // error
5615 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5621 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5624 CACheckJNIException(env);
5628 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
5629 STATE_SERVICE_CONNECTED,
5631 g_deviceStateListMutex);
5632 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5633 if (CA_STATUS_OK != res)
5635 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5639 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
5640 if (CA_STATUS_OK != res)
5642 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
5650 CALEClientSendFinish(env, gatt);
5654 JNIEXPORT void JNICALL
5655 Java_org_iotivity_ca_CaLeClientInterface_caLeGattMtuChangedCallback(JNIEnv *env,
5661 OIC_LOG_V(INFO, TAG, "caLeGattMtuChangedCallback - status %d, "
5662 "mtu[%d-including Header size 3 byte]", status, mtu);
5666 if (0 == status || 133 == status)
5670 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
5671 if (CA_STATUS_OK != res)
5673 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
5678 OIC_LOG(INFO, TAG, "mtu nego is done");
5679 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5682 CALEClientSendFinish(env, gatt);
5686 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5689 CACheckJNIException(env);
5690 (*env)->DeleteLocalRef(env, jni_address);
5691 CALEClientSendFinish(env, gatt);
5696 CAResult_t res = CALESetMtuSize(address, mtu - CA_BLE_MTU_HEADER_SIZE,
5697 g_deviceStateList, g_deviceStateListMutex);
5698 if (CA_STATUS_OK != res)
5700 OIC_LOG(ERROR, TAG, "CALESetMtuSize has failed");
5703 res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5704 STATE_SEND_MTU_NEGO_SUCCESS,
5706 g_deviceStateListMutex);
5707 if (CA_STATUS_OK != res)
5709 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5711 CALEClientUpdateSendCnt(env);
5712 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5713 (*env)->DeleteLocalRef(env, jni_address);