1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
26 #include "calestate.h"
27 #include "caleclient.h"
28 #include "caleserver.h"
29 #include "caleutils.h"
30 #include "caleinterface.h"
31 #include "caadapterutils.h"
34 #include "oic_malloc.h"
35 #include "oic_string.h"
36 #include "cathreadpool.h" /* for thread pool */
38 #include "uarraylist.h"
39 #include "org_iotivity_ca_CaLeClientInterface.h"
41 //#define TAG PCF("OIC_CA_LE_CLIENT")
42 #define TAG BLE_CLIENT_TAG
44 #define MICROSECS_PER_SEC 1000000
45 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
46 #define WAIT_TIME_SCAN_INTERVAL_DEFAULT 10
47 #define WAIT_TIME_SCANNED_CHECKING 30
49 #define GATT_CONNECTION_PRIORITY_BALANCED 0
50 #define GATT_FAILURE 257
51 #define GATT_INSUFFICIENT_AUTHENTICATION 5
52 #define GATT_INSUFFICIENT_ENCRYPTION 15
53 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
54 #define GATT_INVALID_OFFSET 7
55 #define GATT_READ_NOT_PERMITTED 2
56 #define GATT_REQUEST_NOT_SUPPORTED 6
57 #define GATT_WRITE_NOT_PERMITTED 3
60 #define BLE_SCAN_API_LEVEL (21) //(21)
61 #define BLE_MIN_API_LEVEL (18)
63 #define MANUFACTURE_ID 117
65 static ca_thread_pool_t g_threadPoolHandle = NULL;
68 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
69 static u_arraylist_t *g_gattObjectList = NULL;
70 static u_arraylist_t *g_deviceStateList = NULL;
72 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
73 static CABLEErrorHandleCallback g_clientErrorCallback;
74 static jobject g_leScanCallback = NULL;
75 static jobject g_leGattCallback = NULL;
76 static jobject g_context = NULL;
77 static jobjectArray g_uuidList = NULL;
79 // it will be prevent to start send logic when adapter has stopped.
80 static bool g_isStartedLEClient = false;
82 static jbyteArray g_sendBuffer = NULL;
83 static uint32_t g_targetCnt = 0;
84 static uint32_t g_currentSentCnt = 0;
85 static bool g_isFinishedSendData = false;
86 static oc_mutex g_SendFinishMutex = NULL;
87 static oc_mutex g_threadMutex = NULL;
88 static oc_cond g_threadCond = NULL;
89 static oc_cond g_deviceDescCond = NULL;
91 static oc_mutex g_threadSendMutex = NULL;
92 static oc_mutex g_threadWriteCharacteristicMutex = NULL;
93 static oc_cond g_threadWriteCharacteristicCond = NULL;
94 static bool g_isSignalSetFlag = false;
96 static oc_mutex g_bleServerBDAddressMutex = NULL;
98 static oc_mutex g_deviceListMutex = NULL;
99 static oc_mutex g_gattObjectMutex = NULL;
100 static oc_mutex g_deviceStateListMutex = NULL;
102 static oc_mutex g_deviceScanRetryDelayMutex = NULL;
103 static oc_cond g_deviceScanRetryDelayCond = NULL;
105 static oc_mutex g_threadScanIntervalMutex = NULL;
106 static oc_cond g_threadScanIntervalCond = NULL;
108 static oc_mutex g_threadSendStateMutex = NULL;
109 static oc_mutex g_setValueMutex = NULL;
111 static int32_t g_scanIntervalTime = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
112 static int32_t g_scanIntervalTimePrev = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
113 static int32_t g_intervalCount = 0;
114 static bool g_isWorkingScanThread = false;
115 static CALEScanState_t g_curScanningStep = BLE_SCAN_NONE;
116 static CALEScanState_t g_nextScanningStep = BLE_SCAN_ENABLE;
118 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
119 static int32_t g_jniIntSdk = -1;
121 static bool g_setHighQoS = true;
122 static bool g_setFullScanFlag = false;
123 jclass g_LEInterface = NULL;
125 * check if retry logic for connection routine has to be stopped or not.
126 * in case of error value including this method, connection routine has to be stopped.
127 * since there is no retry logic for this error reason in this client.
128 * @param state constant value of bluetoothgatt.
129 * @return true - waiting for background connection in BT platform.
130 * false - connection routine has to be stopped.
132 static bool CALECheckConnectionStateValue(jint state)
136 case GATT_CONNECTION_PRIORITY_BALANCED:
138 case GATT_INSUFFICIENT_AUTHENTICATION:
139 case GATT_INSUFFICIENT_ENCRYPTION:
140 case GATT_INVALID_ATTRIBUTE_LENGTH:
141 case GATT_INVALID_OFFSET:
142 case GATT_READ_NOT_PERMITTED:
143 case GATT_REQUEST_NOT_SUPPORTED:
144 case GATT_WRITE_NOT_PERMITTED:
152 * delete global reference for g_sendBuffer
153 * @param[in] env JNI interface pointer.
155 static void CALEDeleteSendBuffer(JNIEnv *env)
157 OIC_LOG(INFO, TAG, "CALEDeleteSendBuffer");
158 oc_mutex_lock(g_setValueMutex);
161 OIC_LOG(INFO, TAG, "delete send buffer");
162 (*env)->DeleteGlobalRef(env, g_sendBuffer);
165 oc_mutex_unlock(g_setValueMutex);
168 void CALEClientSetScanInterval(int32_t intervalTime, int32_t workingCount,
169 CALEScanState_t nextScanningStep)
171 OIC_LOG_V(DEBUG, TAG, "CALEClientSetScanInterval : %d -> %d, next scan state will be %d",
172 g_scanIntervalTime, intervalTime, nextScanningStep);
174 // previous time should be stored.
175 if (0 < workingCount)
177 g_scanIntervalTimePrev = g_scanIntervalTime;
179 g_scanIntervalTime = intervalTime;
180 g_intervalCount = workingCount;
181 g_nextScanningStep = nextScanningStep;
184 void CALERestartScanWithInterval(int32_t intervalTime, int32_t workingCount,
185 CALEScanState_t nextScanningStep)
187 if (intervalTime == g_scanIntervalTime
188 && workingCount == g_intervalCount
189 && nextScanningStep == g_nextScanningStep)
191 OIC_LOG(DEBUG, TAG, "setting duplicate interval time");
195 oc_mutex_lock(g_threadScanIntervalMutex);
196 CALEClientSetScanInterval(intervalTime, workingCount, nextScanningStep);
197 oc_cond_signal(g_threadScanIntervalCond);
198 oc_mutex_unlock(g_threadScanIntervalMutex);
201 static void CALEScanThread(void* object)
205 bool isAttached = false;
207 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
210 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
214 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
220 oc_mutex_lock(g_threadScanIntervalMutex);
221 while(g_isWorkingScanThread)
223 OIC_LOG(DEBUG, TAG, "scan waiting time out");
224 if (BLE_SCAN_ENABLE == g_curScanningStep)
227 CAResult_t ret = CALEClientStopScan();
228 if (CA_STATUS_OK != ret)
230 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
233 else if (BLE_SCAN_DISABLE == g_curScanningStep)
236 CAResult_t ret = CALEClientStartScan();
237 if (CA_STATUS_OK != ret)
239 OIC_LOG(INFO, TAG, "CALEClientStartScan has failed");
244 OIC_LOG(DEBUG, TAG, "scan thread is started");
246 CALEClientSetScanInterval(0, 0, BLE_SCAN_DISABLE);
249 OIC_LOG_V(DEBUG, TAG, "wait for Scan Interval Time during %d sec", g_scanIntervalTime);
250 if (OC_WAIT_SUCCESS == oc_cond_wait_for(g_threadScanIntervalCond,
251 g_threadScanIntervalMutex,
252 g_scanIntervalTime * MICROSECS_PER_SEC))
254 // called signal scan thread will be terminated
255 OIC_LOG(DEBUG, TAG, "signal scanInterval waiting");
256 if (BLE_SCAN_DISABLE == g_nextScanningStep)
258 g_curScanningStep = BLE_SCAN_ENABLE;
262 g_curScanningStep = BLE_SCAN_DISABLE;
267 if (BLE_SCAN_ENABLE == g_curScanningStep)
269 if (g_intervalCount > 0)
271 if (g_intervalCount == 1)
273 OIC_LOG(DEBUG, TAG, "reset default time");
274 CALEClientSetScanInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
277 OIC_LOG_V(DEBUG, TAG, "interval count : %d", g_intervalCount);
279 g_curScanningStep = BLE_SCAN_DISABLE;
283 g_curScanningStep = BLE_SCAN_ENABLE;
287 oc_mutex_unlock(g_threadScanIntervalMutex);
291 (*g_jvm)->DetachCurrentThread(g_jvm);
295 CAResult_t CALEClientStartScanWithInterval()
297 if (g_isWorkingScanThread)
299 OIC_LOG(DEBUG, TAG, "scan interval logic already running");
303 // initialize scan flags
304 g_curScanningStep = BLE_SCAN_NONE;
305 g_isWorkingScanThread = true;
307 g_scanIntervalTime = g_scanIntervalTimePrev;
308 g_nextScanningStep = BLE_SCAN_ENABLE;
310 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEScanThread, NULL, NULL))
312 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
313 g_isWorkingScanThread = false;
314 return CA_STATUS_FAILED;
320 void CALEClientStopScanWithInterval()
322 g_isWorkingScanThread = false;
323 oc_cond_signal(g_threadScanIntervalCond);
327 void CALEClientJniInit()
329 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
330 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
333 void CALEClientJNISetContext()
335 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
336 g_context = (jobject) CANativeJNIGetContext();
339 CAResult_t CALECreateJniInterfaceObject()
341 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
345 OIC_LOG(ERROR, TAG, "g_context is null");
346 return CA_STATUS_FAILED;
351 OIC_LOG(ERROR, TAG, "g_jvm is null");
352 return CA_STATUS_FAILED;
355 bool isAttached = false;
357 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
360 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
364 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
365 return CA_STATUS_FAILED;
370 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
371 "getApplicationContext",
372 "()Landroid/content/Context;");
374 if (!mid_getApplicationContext)
376 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
377 return CA_STATUS_FAILED;
380 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
381 mid_getApplicationContext);
382 if (!jApplicationContext)
384 OIC_LOG(ERROR, TAG, "Could not get application context");
388 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
389 if (!jni_LEInterface)
391 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
394 g_LEInterface = (jclass)((*env)->NewGlobalRef(env, jni_LEInterface));
396 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
397 "(Landroid/content/Context;)V");
398 if (!LeInterfaceConstructorMethod)
400 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
404 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
405 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
409 (*g_jvm)->DetachCurrentThread(g_jvm);
415 CACheckJNIException(env);
418 (*g_jvm)->DetachCurrentThread(g_jvm);
421 return CA_STATUS_FAILED;
424 CAResult_t CALEClientInitialize()
426 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
432 OIC_LOG(ERROR, TAG, "g_jvm is null");
433 return CA_STATUS_FAILED;
436 bool isAttached = false;
438 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
441 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
445 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
446 return CA_STATUS_FAILED;
451 g_jniIntSdk = CALEGetBuildVersion(env);
452 if (g_jniIntSdk < BLE_MIN_API_LEVEL)
454 OIC_LOG(ERROR, TAG, "it is not supported");
458 (*g_jvm)->DetachCurrentThread(g_jvm);
460 return CA_STATUS_FAILED;
463 CAResult_t ret = CALEClientInitGattMutexVaraibles();
464 if (CA_STATUS_OK != ret)
466 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
467 CALEClientTerminateGattMutexVariables();
471 (*g_jvm)->DetachCurrentThread(g_jvm);
477 g_deviceDescCond = oc_cond_new();
479 // init mutex for send logic
480 g_threadCond = oc_cond_new();
481 g_threadWriteCharacteristicCond = oc_cond_new();
482 g_deviceScanRetryDelayCond = oc_cond_new();
483 g_threadScanIntervalCond = oc_cond_new();
485 CALEClientCreateDeviceList();
486 CALEClientJNISetContext();
488 ret = CALEClientCreateUUIDList();
489 if (CA_STATUS_OK != ret)
491 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
495 (*g_jvm)->DetachCurrentThread(g_jvm);
501 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
502 if (CA_STATUS_OK != ret)
504 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
508 (*g_jvm)->DetachCurrentThread(g_jvm);
513 g_isStartedLEClient = true;
517 (*g_jvm)->DetachCurrentThread(g_jvm);
523 void CALEClientTerminate()
525 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
529 OIC_LOG(ERROR, TAG, "g_jvm is null");
533 bool isAttached = false;
535 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
538 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
542 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
549 CAResult_t ret = CALEClientStopScan();
550 if (CA_STATUS_OK != ret)
552 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
555 if (g_leScanCallback)
557 (*env)->DeleteGlobalRef(env, g_leScanCallback);
558 g_leScanCallback = NULL;
561 if (g_leGattCallback)
563 (*env)->DeleteGlobalRef(env, g_leGattCallback);
564 g_leGattCallback = NULL;
569 (*env)->DeleteGlobalRef(env, g_LEInterface);
570 g_LEInterface = NULL;
573 CALEDeleteSendBuffer(env);
577 (*env)->DeleteGlobalRef(env, g_uuidList);
581 ret = CALERemoveAllDeviceState(g_deviceStateList,
582 g_deviceStateListMutex);
583 if (CA_STATUS_OK != ret)
585 OIC_LOG(ERROR, TAG, "CALERemoveAllDeviceState has failed");
588 oc_mutex_lock(g_deviceStateListMutex);
589 OICFree(g_deviceStateList);
590 g_deviceStateList = NULL;
591 oc_mutex_unlock(g_deviceStateListMutex);
593 ret = CALEClientRemoveAllScanDevices(env);
594 if (CA_STATUS_OK != ret)
596 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
599 ret = CALEClientRemoveAllGattObjs(env);
600 if (CA_STATUS_OK != ret)
602 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
605 CALEClientSetSendFinishFlag(true);
607 CALEClientTerminateGattMutexVariables();
608 CALEClientDestroyJniInterface();
610 oc_cond_free(g_deviceDescCond);
611 oc_cond_free(g_threadCond);
612 oc_cond_free(g_threadWriteCharacteristicCond);
613 oc_cond_free(g_deviceScanRetryDelayCond);
614 oc_cond_free(g_threadScanIntervalCond);
616 g_deviceDescCond = NULL;
618 g_threadWriteCharacteristicCond = NULL;
619 g_deviceScanRetryDelayCond = NULL;
620 g_threadScanIntervalCond = NULL;
622 g_isSignalSetFlag = false;
625 CALEClientStopScanWithInterval();
629 (*g_jvm)->DetachCurrentThread(g_jvm);
633 jobject CALEClientHiddenConnectGatt(jobject btDevice, const char* address, jboolean autoconnect)
635 OIC_LOG(INFO, TAG, "IN - CALEClientHiddenConnectGatt");
639 OIC_LOG(ERROR, TAG, "g_jvm is null");
643 bool isAttached = false;
645 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
648 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
652 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
658 jstring jni_address = (*env)->NewStringUTF(env, address);
659 jmethodID jni_connectGattHiddenMethod = (*env)->GetStaticMethodID(env, g_LEInterface,
660 "connectGattforHidden",
661 "(Landroid/bluetooth/BluetoothDevice;"
662 "Ljava/lang/String;Z)"
663 "Landroid/bluetooth/BluetoothGatt;");
664 if (!jni_connectGattHiddenMethod)
666 OIC_LOG(ERROR, TAG, "Could not get jni_connectGatt Hidden Method");
670 jobject gatt = (*env)->CallStaticObjectMethod(env, g_LEInterface,
671 jni_connectGattHiddenMethod,
672 btDevice, jni_address, autoconnect);
674 if (CACheckJNIException(env))
676 OIC_LOG(ERROR, TAG, "connectGattforHidden has failed");
680 OIC_LOG(INFO, TAG, "OUT - CALEClientHiddenConnectGatt");
684 (*g_jvm)->DetachCurrentThread(g_jvm);
690 CACheckJNIException(env);
695 (*g_jvm)->DetachCurrentThread(g_jvm);
701 CAResult_t CALEClientDestroyJniInterface()
703 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
707 OIC_LOG(ERROR, TAG, "g_jvm is null");
708 return CA_STATUS_FAILED;
711 bool isAttached = false;
713 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
716 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
720 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
721 return CA_STATUS_FAILED;
726 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
727 if (!jni_LeInterface)
729 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
733 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
734 "destroyLeInterface",
736 if (!jni_InterfaceDestroyMethod)
738 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
742 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
744 if (CACheckJNIException(env))
746 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
750 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
754 (*g_jvm)->DetachCurrentThread(g_jvm);
760 CACheckJNIException(env);
765 (*g_jvm)->DetachCurrentThread(g_jvm);
768 return CA_STATUS_FAILED;
771 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
773 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
774 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
778 CAResult_t res = CALEClientDisconnect(env, gatt);
779 if (CA_STATUS_OK != res)
781 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
784 CALEClientUpdateSendCnt(env);
787 CAResult_t CALEClientSendNegotiationMessage(const char* address)
789 VERIFY_NON_NULL(address, TAG, "address is null");
791 return CALEClientSendUnicastMessageImpl(address, NULL, 0);
794 CAResult_t CALEClientSendUnicastMessage(const char* address,
796 const uint32_t dataLen)
798 VERIFY_NON_NULL(address, TAG, "address is null");
799 VERIFY_NON_NULL(data, TAG, "data is null");
801 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
804 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
805 const uint32_t dataLen)
807 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
808 VERIFY_NON_NULL(data, TAG, "data is null");
812 OIC_LOG(ERROR, TAG, "g_jvm is null");
813 return CA_STATUS_FAILED;
816 bool isAttached = false;
818 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
821 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
825 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
826 return CA_STATUS_FAILED;
831 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
832 if (CA_STATUS_OK != ret)
834 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
839 (*g_jvm)->DetachCurrentThread(g_jvm);
845 CAResult_t CALEClientStartUnicastServer(const char* address)
850 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
852 return CA_NOT_SUPPORTED;
855 CAResult_t CALEClientStartMulticastServer()
857 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
859 return CA_NOT_SUPPORTED;
862 void CALEClientStopUnicastServer()
864 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
867 void CALEClientStopMulticastServer()
869 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
872 void CALEClientSetCallback(CAPacketReceiveCallback callback)
874 g_packetReceiveCallback = callback;
877 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
879 g_clientErrorCallback = callback;
882 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
884 VERIFY_NON_NULL(env, TAG, "env");
888 OIC_LOG(ERROR, TAG, "g_deviceList is not available");
889 return CA_STATUS_FAILED;
892 if (0 == u_arraylist_length(g_deviceList) // multicast
893 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
895 // Wait for LE peripherals to be discovered.
897 // Number of times to wait for discovery to complete.
898 static size_t const RETRIES = 5;
900 static uint64_t const TIMEOUT =
901 2 * MICROSECS_PER_SEC; // Microseconds
903 // set scan interval and start scan
904 CALERestartScanWithInterval(WAIT_TIME_SCANNED_CHECKING, 1, BLE_SCAN_ENABLE);
906 bool devicesDiscovered = false;
907 for (size_t i = 0; i < RETRIES; ++i)
909 OIC_LOG(DEBUG, TAG, "waiting for target device");
910 if (oc_cond_wait_for(g_deviceDescCond,
912 TIMEOUT) == OC_WAIT_SUCCESS)
914 OIC_LOG(DEBUG, TAG, "time out");
915 oc_mutex_lock(g_deviceListMutex);
916 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
917 oc_mutex_unlock(g_deviceListMutex);
919 if (0 < scannedDeviceLen)
921 if (!address // multicast
922 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
924 devicesDiscovered = true;
931 OIC_LOG(INFO, TAG, "waiting..");
933 oc_mutex_lock(g_deviceScanRetryDelayMutex);
934 if (oc_cond_wait_for(g_deviceScanRetryDelayCond,
935 g_deviceScanRetryDelayMutex,
936 MICROSECS_PER_SEC) == OC_WAIT_SUCCESS)
938 OIC_LOG(INFO, TAG, "finish to waiting for target device");
939 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
942 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
945 // checking whether a target device is found while waiting for time-out.
946 if (CALEClientIsDeviceInScanDeviceList(env, address))
948 devicesDiscovered = true;
957 // reset scan interval time after checking scanned devices
958 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
960 // time out for scanning devices
961 if (!devicesDiscovered)
963 return CA_STATUS_FAILED;
968 OIC_LOG(DEBUG, TAG, "there is a target device in the scanned devices");
975 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
976 const uint32_t dataLen)
978 OIC_LOG(INFO, TAG, "CALEClientSendUnicastMessageImpl in");
979 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
981 VERIFY_NON_NULL(address, TAG, "address is null");
985 OIC_LOG(ERROR, TAG, "g_jvm is null");
986 return CA_STATUS_FAILED;
989 bool isAttached = false;
991 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
994 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
997 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
998 return CA_STATUS_FAILED;
1003 oc_mutex_lock(g_threadSendMutex);
1005 CALEClientSetSendFinishFlag(false);
1007 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
1008 if (CA_STATUS_OK != ret)
1010 OIC_LOG(INFO, TAG, "there is no scanned device");
1014 if (g_context && g_deviceList)
1016 uint32_t length = u_arraylist_length(g_deviceList);
1017 for (uint32_t index = 0; index < length; index++)
1019 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1022 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1026 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1027 if (!jni_setAddress)
1029 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1033 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1036 OIC_LOG(ERROR, TAG, "setAddress is null");
1037 CACheckJNIException(env);
1041 if (!strcasecmp(setAddress, address))
1043 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1044 (*env)->DeleteLocalRef(env, jni_setAddress);
1046 CALEDeleteSendBuffer(env);
1048 if (data && dataLen > 0)
1050 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1051 CACheckJNIException(env);
1052 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1053 CACheckJNIException(env);
1054 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1055 CACheckJNIException(env);
1058 // Target device to send message is just one.
1061 ret = CALEClientSendData(env, jarrayObj);
1062 if (CA_STATUS_OK != ret)
1064 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
1068 OIC_LOG(INFO, TAG, "wake up");
1071 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1072 (*env)->DeleteLocalRef(env, jni_setAddress);
1076 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
1078 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1079 // if there is no connection state.
1080 oc_mutex_lock(g_threadMutex);
1081 if (!g_isFinishedSendData)
1083 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1084 oc_cond_wait(g_threadCond, g_threadMutex);
1085 OIC_LOG(DEBUG, TAG, "connection / send is finished for unicast");
1087 oc_mutex_unlock(g_threadMutex);
1091 (*g_jvm)->DetachCurrentThread(g_jvm);
1094 oc_mutex_unlock(g_threadSendMutex);
1095 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
1096 if (CALEIsValidState(address, CA_LE_SEND_STATE,
1099 g_deviceStateListMutex))
1101 OIC_LOG(INFO, TAG, "send success");
1104 else if (CALEIsValidState(address, CA_LE_SEND_STATE,
1105 STATE_SEND_MTU_NEGO_SUCCESS,
1107 g_deviceStateListMutex))
1109 OIC_LOG(INFO, TAG, "mtu nego success");
1114 OIC_LOG(ERROR, TAG, "send failure");
1115 ret = CA_SEND_FAILED;
1119 CAResult_t resetRet = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
1122 g_deviceStateListMutex);
1123 if (CA_STATUS_OK != resetRet)
1125 OIC_LOG_V(ERROR, TAG, "CALEUpdateDeviceState has failed (%d)", resetRet);
1126 ret = CA_SEND_FAILED;
1135 (*g_jvm)->DetachCurrentThread(g_jvm);
1138 oc_mutex_unlock(g_threadSendMutex);
1139 return CA_SEND_FAILED;
1142 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
1143 const uint32_t dataLen)
1145 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
1146 VERIFY_NON_NULL(data, TAG, "data is null");
1147 VERIFY_NON_NULL(env, TAG, "env is null");
1151 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1152 return CA_STATUS_FAILED;
1155 oc_mutex_lock(g_threadSendMutex);
1157 CALEClientSetSendFinishFlag(false);
1159 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1160 CALEDeleteSendBuffer(env);
1162 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
1163 if (CA_STATUS_OK != res)
1165 OIC_LOG(INFO, TAG, "there is no scanned device");
1169 uint32_t length = u_arraylist_length(g_deviceList);
1170 g_targetCnt = length;
1172 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1173 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1174 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1176 for (uint32_t index = 0; index < length; index++)
1178 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1181 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
1185 res = CALEClientSendData(env, jarrayObj);
1186 if (res != CA_STATUS_OK)
1188 OIC_LOG(ERROR, TAG, "BT device - send has failed");
1192 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1194 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1195 oc_mutex_lock(g_threadMutex);
1196 if (!g_isFinishedSendData)
1198 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1199 oc_cond_wait(g_threadCond, g_threadMutex);
1200 OIC_LOG(DEBUG, TAG, "connection / send is finished for multicast");
1202 oc_mutex_unlock(g_threadMutex);
1203 oc_mutex_unlock(g_threadSendMutex);
1204 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1205 return CA_STATUS_OK;
1208 oc_mutex_unlock(g_threadSendMutex);
1209 OIC_LOG(ERROR, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1210 return CA_SEND_FAILED;
1213 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1215 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1216 VERIFY_NON_NULL(device, TAG, "device is null");
1217 VERIFY_NON_NULL(env, TAG, "env is null");
1219 // get BLE address from bluetooth device object.
1220 char* address = NULL;
1221 CALEState_t* state = NULL;
1222 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1225 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1226 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1229 OIC_LOG(ERROR, TAG, "address is not available");
1230 CACheckJNIException(env);
1231 return CA_STATUS_FAILED;
1233 oc_mutex_lock(g_deviceStateListMutex);
1234 state = CALEGetStateInfo(address, g_deviceStateList);
1235 oc_mutex_unlock(g_deviceStateListMutex);
1238 // Since disconnect event can be caused from BT stack while connection step is running.
1239 // DeviceState has to have current status for processing send failure.
1240 OIC_LOG(INFO, TAG, "set STATE_SEND_PREPARING");
1241 CAResult_t res = CALEClientUpdateDeviceStateWithBtDevice(env, device,
1243 STATE_SEND_PREPARING);
1244 if (CA_STATUS_OK != res)
1246 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceStateWithBtDevice has failed");
1249 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1251 return CA_STATUS_FAILED;
1256 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1258 // cancel previous connection request before connection
1259 // if there is gatt object in g_gattObjectList.
1262 jobject gatt = CALEClientGetGattObjInList(env, address);
1265 CAResult_t res = CALEClientDisconnect(env, gatt);
1266 if (CA_STATUS_OK != res)
1268 OIC_LOG(INFO, TAG, "there is no gatt object");
1271 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1274 // connection request
1275 jobject newGatt = CALEClientConnect(env, device,
1277 if (NULL == newGatt)
1279 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1280 return CA_STATUS_FAILED;
1285 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1286 STATE_SERVICE_CONNECTED,
1288 g_deviceStateListMutex))
1290 OIC_LOG(INFO, TAG, "GATT has already connected");
1292 jobject gatt = CALEClientGetGattObjInList(env, address);
1295 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1296 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1297 return CA_STATUS_FAILED;
1300 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1301 if (CA_STATUS_OK != ret)
1303 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1304 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1307 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1309 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1312 g_deviceStateListMutex))
1314 OIC_LOG(INFO, TAG, "service connecting...");
1316 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1319 g_deviceStateListMutex))
1321 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1323 // cancel previous connection request before connection
1324 // if there is gatt object in g_gattObjectList.
1327 jobject gatt = CALEClientGetGattObjInList(env, address);
1330 CAResult_t res = CALEClientDisconnect(env, gatt);
1331 if (CA_STATUS_OK != res)
1333 OIC_LOG(INFO, TAG, "there is no gatt object");
1336 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1339 OIC_LOG(DEBUG, TAG, "start to connect LE");
1340 jobject gatt = CALEClientConnect(env, device,
1341 CALEGetFlagFromState(env, jni_address,
1342 CA_LE_AUTO_CONNECT_FLAG,
1344 g_deviceStateListMutex));
1348 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1349 return CA_STATUS_FAILED;
1354 return CA_STATUS_OK;
1357 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1359 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1360 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1362 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1363 "()Landroid/bluetooth/BluetoothDevice;");
1364 if (!jni_mid_getDevice)
1366 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1370 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1371 if (!jni_obj_device)
1373 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1374 CACheckJNIException(env);
1378 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1381 OIC_LOG(ERROR, TAG, "jni_address is null");
1382 CACheckJNIException(env);
1392 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1395 OIC_LOG(DEBUG, TAG, "Gatt Close");
1396 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1397 VERIFY_NON_NULL(env, TAG, "env is null");
1399 // get BluetoothGatt method
1400 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1401 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1402 if (!jni_mid_closeGatt)
1404 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1405 return CA_STATUS_OK;
1408 // call disconnect gatt method
1409 OIC_LOG(DEBUG, TAG, "request to close GATT");
1410 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1412 if (CACheckJNIException(env))
1414 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1415 return CA_STATUS_FAILED;
1418 return CA_STATUS_OK;
1421 CAResult_t CALEClientStartScan()
1423 if (!g_isStartedLEClient)
1425 OIC_LOG(ERROR, TAG, "LE client is not started");
1426 return CA_STATUS_FAILED;
1431 OIC_LOG(ERROR, TAG, "g_jvm is null");
1432 return CA_STATUS_FAILED;
1435 if(g_jniIntSdk < BLE_SCAN_API_LEVEL)
1437 g_setFullScanFlag = true;
1439 bool isAttached = false;
1441 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1444 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1447 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1448 return CA_STATUS_FAILED;
1453 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1455 CAResult_t ret = CA_STATUS_OK;
1456 // scan gatt server with UUID
1457 if (g_leScanCallback && g_uuidList)
1459 if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
1461 if (!g_setFullScanFlag)
1463 //new uuid scan with callback
1464 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 will be called");
1465 ret = CALEClientStartScanWithUUIDImplForV21(env, g_uuidList, g_leScanCallback);
1469 //new full scan with callback
1470 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 will be called");
1471 ret = CALEClientStartScanImplForV21(env, g_leScanCallback);
1476 if (!g_setFullScanFlag)
1478 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl will be called");
1479 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1483 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl will be called");
1484 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1488 if (CA_STATUS_OK != ret)
1490 if (CA_ADAPTER_NOT_ENABLED == ret)
1492 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1496 OIC_LOG(ERROR, TAG, "start scan has failed");
1503 (*g_jvm)->DetachCurrentThread(g_jvm);
1509 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1511 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl IN");
1512 VERIFY_NON_NULL(callback, TAG, "callback is null");
1513 VERIFY_NON_NULL(env, TAG, "env is null");
1515 if (!CALEIsEnableBTAdapter(env))
1517 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1518 return CA_ADAPTER_NOT_ENABLED;
1521 // get default bt adapter class
1522 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1523 if (!jni_cid_BTAdapter)
1525 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1526 CACheckJNIException(env);
1527 return CA_STATUS_FAILED;
1530 // get remote bt adapter method
1531 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1532 "getDefaultAdapter",
1533 METHODID_OBJECTNONPARAM);
1534 if (!jni_mid_getDefaultAdapter)
1536 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1537 CACheckJNIException(env);
1538 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1539 return CA_STATUS_FAILED;
1542 // get start le scan method
1543 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1544 "(Landroid/bluetooth/BluetoothAdapter$"
1545 "LeScanCallback;)Z");
1546 if (!jni_mid_startLeScan)
1548 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1549 CACheckJNIException(env);
1550 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1551 return CA_STATUS_FAILED;
1554 // gat bt adapter object
1555 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1556 jni_mid_getDefaultAdapter);
1557 if (!jni_obj_BTAdapter)
1559 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1560 CACheckJNIException(env);
1561 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1562 return CA_STATUS_FAILED;
1565 // call start le scan method
1566 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1567 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1568 jni_mid_startLeScan, callback);
1569 if (!jni_obj_startLeScan)
1571 OIC_LOG(INFO, TAG, "startLeScan has failed");
1572 CACheckJNIException(env);
1576 OIC_LOG(DEBUG, TAG, "LeScan has started");
1579 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1580 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1581 return CA_STATUS_OK;
1584 CAResult_t CALEClientStartScanImplForV21(JNIEnv *env, jobject callback)
1586 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 IN");
1587 VERIFY_NON_NULL(callback, TAG, "callback is null");
1588 VERIFY_NON_NULL(env, TAG, "env is null");
1590 if (!CALEIsEnableBTAdapter(env))
1592 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1593 return CA_ADAPTER_NOT_ENABLED;
1596 CAResult_t res = CA_STATUS_FAILED;
1597 // get default bt adapter class
1598 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1599 if (!jni_cid_BTAdapter)
1601 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1602 CACheckJNIException(env);
1603 return CA_STATUS_FAILED;
1606 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1607 "getDefaultAdapter",
1608 "()Landroid/bluetooth/"
1609 "BluetoothAdapter;");
1610 if (!jni_mid_getDefaultAdapter)
1612 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1613 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1614 return CA_STATUS_FAILED;
1617 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1618 jni_mid_getDefaultAdapter);
1619 if (!jni_obj_BTAdapter)
1621 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1622 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1623 return CA_STATUS_FAILED;
1626 // get bluetoothLeScanner class
1627 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
1628 if (!jni_cid_leScanner)
1630 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
1631 CACheckJNIException(env);
1632 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1633 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1634 return CA_STATUS_FAILED;
1637 // get remote bt adapter method
1638 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1639 "getBluetoothLeScanner",
1640 "()Landroid/bluetooth/"
1641 "le/BluetoothLeScanner;");
1642 if (!jni_mid_getBluetoothLeScanner)
1644 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
1645 CACheckJNIException(env);
1649 // get startScan(ScanCallback callback) method
1650 jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner, "startScan",
1651 "(Landroid/bluetooth/le/ScanCallback;)V");
1652 if (!jni_mid_startScan)
1654 OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
1655 CACheckJNIException(env);
1659 // gat le scanner object
1660 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
1661 jni_mid_getBluetoothLeScanner);
1662 if (!jni_obj_leScanner)
1664 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
1665 CACheckJNIException(env);
1669 // call startScan method
1670 OIC_LOG(INFO, TAG, "CALL API - startScan(for level21)");
1671 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, callback);
1672 if (CACheckJNIException(env))
1674 OIC_LOG(INFO, TAG, "startScan has failed");
1675 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
1679 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
1682 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1683 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1684 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1688 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1690 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl IN");
1691 VERIFY_NON_NULL(callback, TAG, "callback is null");
1692 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1693 VERIFY_NON_NULL(env, TAG, "env is null");
1695 if (!CALEIsEnableBTAdapter(env))
1697 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1698 return CA_ADAPTER_NOT_ENABLED;
1701 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1702 if (!jni_cid_BTAdapter)
1704 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1705 CACheckJNIException(env);
1706 return CA_STATUS_FAILED;
1709 // get remote bt adapter method
1710 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1711 "getDefaultAdapter",
1712 METHODID_OBJECTNONPARAM);
1713 if (!jni_mid_getDefaultAdapter)
1715 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1716 CACheckJNIException(env);
1717 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1718 return CA_STATUS_FAILED;
1721 // get start le scan method
1722 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1723 "([Ljava/util/UUID;Landroid/bluetooth/"
1724 "BluetoothAdapter$LeScanCallback;)Z");
1725 if (!jni_mid_startLeScan)
1727 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1728 CACheckJNIException(env);
1729 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1730 return CA_STATUS_FAILED;
1733 // get bt adapter object
1734 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1735 jni_mid_getDefaultAdapter);
1736 if (!jni_obj_BTAdapter)
1738 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1739 CACheckJNIException(env);
1740 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1741 return CA_STATUS_FAILED;
1744 // call start le scan method
1745 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1746 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1747 jni_mid_startLeScan, uuids, callback);
1748 if (!jni_obj_startLeScan)
1750 OIC_LOG(INFO, TAG, "startLeScan has failed");
1751 CACheckJNIException(env);
1755 OIC_LOG(DEBUG, TAG, "LeScan has started");
1758 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1759 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1760 return CA_STATUS_OK;
1763 CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids, jobject callback)
1765 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 IN");
1766 VERIFY_NON_NULL(callback, TAG, "callback is null");
1767 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1768 VERIFY_NON_NULL(env, TAG, "env is null");
1770 if (!CALEIsEnableBTAdapter(env))
1772 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1773 return CA_ADAPTER_NOT_ENABLED;
1776 // get bluetoothLeScanner class
1777 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
1778 if (!jni_cid_leScanner)
1780 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
1781 CACheckJNIException(env);
1782 return CA_STATUS_FAILED;
1785 // get startScan(with UUID) method
1786 jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner,
1789 "Landroid/bluetooth/le/ScanSettings;"
1790 "Landroid/bluetooth/le/ScanCallback;"
1792 if (!jni_mid_startScan)
1794 OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
1795 CACheckJNIException(env);
1796 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1797 return CA_STATUS_FAILED;
1799 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1801 // get scanfilter.Builder class id
1802 jclass jni_cid_scanfilterBuilder = (*env)->FindClass(env,
1803 "android/bluetooth/le/"
1804 "ScanFilter$Builder");
1805 if (!jni_cid_scanfilterBuilder)
1807 OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilder is null");
1808 CACheckJNIException(env);
1809 return CA_STATUS_FAILED;
1812 // get scanfilter.Builder(ctor) method id
1813 jmethodID jni_mid_scanfilterBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1815 if (!jni_mid_scanfilterBuilderCtor)
1817 OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilderCtor is null");
1818 CACheckJNIException(env);
1819 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1820 return CA_STATUS_FAILED;
1823 // call scanfilter.Builder()
1824 jobject jni_obj_scanfilterBuilder = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
1825 jni_mid_scanfilterBuilderCtor);
1826 if (!jni_obj_scanfilterBuilder)
1828 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilterBuilder is null");
1829 CACheckJNIException(env);
1830 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1831 return CA_STATUS_FAILED;
1834 // call scanfilter.Builder()
1835 jobject jni_obj_scanfilterBuilder2 = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
1836 jni_mid_scanfilterBuilderCtor);
1837 if (!jni_obj_scanfilterBuilder2)
1839 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilterBuilder2 is null");
1840 CACheckJNIException(env);
1841 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1842 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1843 return CA_STATUS_FAILED;
1846 // call scanfilter.Builder()
1847 jobject jni_obj_scanfilterBuilder3 = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
1848 jni_mid_scanfilterBuilderCtor);
1849 if (!jni_obj_scanfilterBuilder3)
1851 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilterBuilder3 is null");
1852 CACheckJNIException(env);
1853 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1854 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1855 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
1856 return CA_STATUS_FAILED;
1859 // call scanfilter.Builder()
1860 jobject jni_obj_scanfilterBuilder4 = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
1861 jni_mid_scanfilterBuilderCtor);
1862 if (!jni_obj_scanfilterBuilder4)
1864 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilterBuilder4 is null");
1865 CACheckJNIException(env);
1866 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1867 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1868 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
1869 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
1870 return CA_STATUS_FAILED;
1873 // get scanfilter.Builder.setServiceUuid method id
1874 jmethodID jni_mid_setServiceUuid = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1876 "(Landroid/os/ParcelUuid;)Landroid/"
1877 "bluetooth/le/ScanFilter$Builder;");
1878 if (!jni_mid_setServiceUuid)
1880 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setServiceUuid is null");
1881 CACheckJNIException(env);
1882 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1883 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1884 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
1885 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
1886 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
1887 return CA_STATUS_FAILED;
1890 // get scanfilter.Builder.setManufacturerData method id
1891 jmethodID jni_mid_setManufacturerData = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1892 "setManufacturerData",
1894 "bluetooth/le/ScanFilter$Builder;");
1895 if (!jni_mid_setManufacturerData)
1897 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setManufacturerData is null");
1898 CACheckJNIException(env);
1899 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1900 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1901 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
1902 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
1903 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
1904 return CA_STATUS_FAILED;
1906 // get scanfilter.Builder.build method id
1907 jmethodID jni_mid_build_scanfilterBuilder = (*env)->GetMethodID(env,
1908 jni_cid_scanfilterBuilder,
1910 "()Landroid/bluetooth/le/"
1912 if (!jni_mid_build_scanfilterBuilder)
1914 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_build_scanfilterBuilder is null");
1915 CACheckJNIException(env);
1916 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1917 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1918 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
1919 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
1920 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
1921 return CA_STATUS_FAILED;
1923 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1925 // call ParcelUuid.fromSting(uuid)
1926 jobject jni_obj_parcelUuid = CALEGetParcelUuidFromString(env, OIC_GATT_SERVICE_UUID);
1927 if (!jni_obj_parcelUuid)
1929 OIC_LOG(ERROR, TAG, "scanSettings: jni_obj_parcelUuid is null");
1930 CACheckJNIException(env);
1931 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1932 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
1933 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
1934 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
1935 return CA_STATUS_FAILED;
1938 // call setServiceUuid(uuid)
1939 jobject jni_obj_setServiceUuid = (*env)->CallObjectMethod(env,
1940 jni_obj_scanfilterBuilder,
1941 jni_mid_setServiceUuid,
1942 jni_obj_parcelUuid);
1943 if (!jni_obj_setServiceUuid)
1945 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setServiceUuid is null");
1946 CACheckJNIException(env);
1947 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1948 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
1949 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
1950 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
1951 (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
1952 return CA_STATUS_FAILED;
1954 (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
1955 (*env)->DeleteLocalRef(env, jni_obj_setServiceUuid);
1958 jobject jni_obj_scanfilter = (*env)->CallObjectMethod(env,
1959 jni_obj_scanfilterBuilder,
1960 jni_mid_build_scanfilterBuilder);
1961 if (!jni_obj_scanfilter)
1963 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilter is null");
1964 CACheckJNIException(env);
1965 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1966 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
1967 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
1968 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
1969 return CA_STATUS_FAILED;
1971 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1973 OIC_LOG(DEBUG, TAG, "Service UUID scanfilter set");
1976 jbyteArray jni_byte_manData;
1977 // set manufactererId
1978 jni_int_manId = MANUFACTURE_ID;
1980 // call utility function to set manufacturerData
1981 jni_byte_manData = CALEGetManufacturerData(env, OIC_GATT_CUSTOM_UUID);
1982 if(!jni_byte_manData)
1984 OIC_LOG(ERROR, TAG, "scanSettings: jni_byte_manData is null");
1985 CACheckJNIException(env);
1986 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
1987 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
1988 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
1989 return CA_STATUS_FAILED;
1993 jobject jni_obj_setManufacturerData = (*env)->CallObjectMethod(env,
1994 jni_obj_scanfilterBuilder2,
1995 jni_mid_setManufacturerData,
1998 if (!jni_obj_setManufacturerData)
2000 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setManufacturerData is null");
2001 CACheckJNIException(env);
2002 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
2003 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
2004 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
2005 return CA_STATUS_FAILED;
2007 (*env)->DeleteLocalRef(env, jni_byte_manData);
2008 (*env)->DeleteLocalRef(env, jni_obj_setManufacturerData);
2011 jobject jni_obj_scanfilter2 = (*env)->CallObjectMethod(env,
2012 jni_obj_scanfilterBuilder2,
2013 jni_mid_build_scanfilterBuilder);
2014 if (!jni_obj_scanfilter2)
2016 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilter2 is null");
2017 CACheckJNIException(env);
2018 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
2019 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
2020 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
2021 return CA_STATUS_FAILED;
2023 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
2025 OIC_LOG(DEBUG, TAG, "First custom UUID scanfilter set");
2027 // call utility function to set manufacturerData
2028 jni_byte_manData = CALEGetManufacturerData(env, OIC_GATT_CUSTOM_UUID2);
2029 if(!jni_byte_manData)
2031 OIC_LOG(ERROR, TAG, "scanSettings: jni_byte_manData is null");
2032 CACheckJNIException(env);
2033 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
2034 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
2035 return CA_STATUS_FAILED;
2039 jni_obj_setManufacturerData = (*env)->CallObjectMethod(env,
2040 jni_obj_scanfilterBuilder3,
2041 jni_mid_setManufacturerData,
2045 if (!jni_obj_setManufacturerData)
2047 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setManufacturerData is null");
2048 CACheckJNIException(env);
2049 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
2050 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
2051 return CA_STATUS_FAILED;
2053 (*env)->DeleteLocalRef(env, jni_byte_manData);
2054 (*env)->DeleteLocalRef(env, jni_obj_setManufacturerData);
2057 jobject jni_obj_scanfilter3 = (*env)->CallObjectMethod(env,
2058 jni_obj_scanfilterBuilder3,
2059 jni_mid_build_scanfilterBuilder);
2060 if (!jni_obj_scanfilter3)
2062 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilter3 is null");
2063 CACheckJNIException(env);
2064 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
2065 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
2066 return CA_STATUS_FAILED;
2068 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
2069 OIC_LOG(DEBUG, TAG, "Second custom UUID scanfilter set");
2071 // call utility function to set manufacturerData
2072 jni_byte_manData = CALEGetManufacturerData(env, OIC_GATT_CUSTOM_UUID3);
2073 if(!jni_byte_manData)
2075 OIC_LOG(ERROR, TAG, "scanSettings: jni_byte_manData is null");
2076 CACheckJNIException(env);
2077 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
2078 return CA_STATUS_FAILED;
2082 jni_obj_setManufacturerData = (*env)->CallObjectMethod(env,
2083 jni_obj_scanfilterBuilder4,
2084 jni_mid_setManufacturerData,
2088 if (!jni_obj_setManufacturerData)
2090 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setManufacturerData is null");
2091 CACheckJNIException(env);
2092 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
2093 return CA_STATUS_FAILED;
2095 (*env)->DeleteLocalRef(env, jni_byte_manData);
2096 (*env)->DeleteLocalRef(env, jni_obj_setManufacturerData);
2099 jobject jni_obj_scanfilter4 = (*env)->CallObjectMethod(env,
2100 jni_obj_scanfilterBuilder4,
2101 jni_mid_build_scanfilterBuilder);
2102 if (!jni_obj_scanfilter4)
2104 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilter4 is null");
2105 CACheckJNIException(env);
2106 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
2107 return CA_STATUS_FAILED;
2109 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
2110 OIC_LOG(DEBUG, TAG, "Third custom UUID scanfilter set");
2112 // get scanSettings.Builder class id
2113 jclass jni_cid_scanSettingsBuilder = (*env)->FindClass(env,
2114 "android/bluetooth/le/"
2115 "ScanSettings$Builder");
2116 if (!jni_cid_scanSettingsBuilder)
2118 OIC_LOG(ERROR, TAG, "scanSettings: jni_cid_scanSettingsBuilder is null");
2119 CACheckJNIException(env);
2120 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2121 return CA_STATUS_FAILED;
2124 // get scanSettings.Builder(ctor) method id
2125 jmethodID jni_mid_scanSettingsBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
2127 if (!jni_mid_scanSettingsBuilderCtor)
2129 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_scanSettingsBuilderCtor is null");
2130 CACheckJNIException(env);
2131 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2132 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2133 return CA_STATUS_FAILED;
2136 // get scanSettings.Builder.setScanMode method id
2137 jmethodID jni_mid_setScanMode = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
2140 "bluetooth/le/ScanSettings$Builder;");
2141 if (!jni_mid_setScanMode)
2143 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_setScanMode is null");
2144 CACheckJNIException(env);
2145 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2146 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2147 return CA_STATUS_FAILED;
2150 // get scanSettings.Builder.build method id
2151 jmethodID jni_mid_build_scanSettings = (*env)->GetMethodID(env,
2152 jni_cid_scanSettingsBuilder,
2154 "()Landroid/bluetooth/le/"
2156 if (!jni_mid_build_scanSettings)
2158 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_build_scanSettings is null");
2159 CACheckJNIException(env);
2160 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2161 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2162 return CA_STATUS_FAILED;
2165 // call scanSettings.Builder()
2166 jobject jni_obj_scanSettingBuilder = (*env)->NewObject(env, jni_cid_scanSettingsBuilder,
2167 jni_mid_scanSettingsBuilderCtor);
2168 if (!jni_obj_scanSettingBuilder)
2170 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettingBuilder is null");
2171 CACheckJNIException(env);
2172 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2173 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2174 return CA_STATUS_FAILED;
2176 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
2178 jclass jni_cid_arrayList = (*env)->FindClass(env, "java/util/ArrayList");
2179 if (!jni_cid_arrayList)
2181 OIC_LOG(ERROR, TAG, "ArrayList: jni_cid_arrayList is null");
2182 CACheckJNIException(env);
2183 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2184 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2185 return CA_STATUS_FAILED;
2188 jmethodID jni_mid_arrayListCtor = (*env)->GetMethodID(env, jni_cid_arrayList, "<init>", "()V");
2189 if (!jni_mid_arrayListCtor)
2191 OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListCtor is null");
2192 CACheckJNIException(env);
2193 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2194 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2195 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2196 return CA_STATUS_FAILED;
2199 jmethodID jni_mid_arrayListAdd = (*env)->GetMethodID(env, jni_cid_arrayList,
2200 "add", "(Ljava/lang/Object;)Z");
2201 if (!jni_mid_arrayListAdd)
2203 OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListAdd is null");
2204 CACheckJNIException(env);
2205 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2206 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2207 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2208 return CA_STATUS_FAILED;
2211 jobject jni_obj_filterList = (*env)->NewObject(env, jni_cid_arrayList, jni_mid_arrayListCtor);
2212 if (!jni_obj_filterList)
2214 OIC_LOG(ERROR, TAG, "ArrayList: jni_obj_filterList is null");
2215 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2216 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2217 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2218 return CA_STATUS_FAILED;
2220 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2222 jboolean jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
2223 jni_mid_arrayListAdd,
2224 jni_obj_scanfilter);
2225 if (!jni_bool_arrayListIsAdded)
2227 OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
2228 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2229 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2230 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2231 return CA_STATUS_FAILED;
2233 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2235 jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
2236 jni_mid_arrayListAdd,
2237 jni_obj_scanfilter2);
2238 if (!jni_bool_arrayListIsAdded)
2240 OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
2241 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2242 (*env)->DeleteLocalRef(env, jni_obj_scanfilter2);
2243 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2244 return CA_STATUS_FAILED;
2246 (*env)->DeleteLocalRef(env, jni_obj_scanfilter2);
2248 jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
2249 jni_mid_arrayListAdd,
2250 jni_obj_scanfilter3);
2251 if (!jni_bool_arrayListIsAdded)
2253 OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
2254 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2255 (*env)->DeleteLocalRef(env, jni_obj_scanfilter3);
2256 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2257 return CA_STATUS_FAILED;
2259 (*env)->DeleteLocalRef(env, jni_obj_scanfilter3);
2261 jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
2262 jni_mid_arrayListAdd,
2263 jni_obj_scanfilter4);
2264 if (!jni_bool_arrayListIsAdded)
2266 OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
2267 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2268 (*env)->DeleteLocalRef(env, jni_obj_scanfilter4);
2269 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2270 return CA_STATUS_FAILED;
2272 (*env)->DeleteLocalRef(env, jni_obj_scanfilter4);
2274 OIC_LOG(INFO, TAG, "ScanFilters Added");
2275 // get ScanSettings.SCAN_MODE_BALANCED jint value
2276 jint jni_int_scanBalancedMode = CALEGetConstantsValue(env, CLASSPATH_LE_SCANSETTINGS,
2277 "SCAN_MODE_BALANCED");
2278 CACheckJNIException(env);
2280 // call setScanMode(SCAN_MODE_BALANCED)
2281 jobject jni_obj_setScanMode = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
2282 jni_mid_setScanMode,
2283 jni_int_scanBalancedMode);
2284 if (!jni_obj_setScanMode)
2286 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setScanMode is null");
2287 CACheckJNIException(env);
2288 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2289 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2290 return CA_STATUS_FAILED;
2294 jobject jni_obj_scanSettings = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
2295 jni_mid_build_scanSettings);
2296 if (!jni_obj_scanSettings)
2298 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettings is null");
2299 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2300 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2301 return CA_STATUS_FAILED;
2303 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2305 CAResult_t res = CA_STATUS_FAILED;
2307 // get default bt adapter class
2308 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2309 if (!jni_cid_BTAdapter)
2311 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2312 CACheckJNIException(env);
2316 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2317 "getDefaultAdapter",
2318 "()Landroid/bluetooth/"
2319 "BluetoothAdapter;");
2320 if (!jni_mid_getDefaultAdapter)
2322 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2323 CACheckJNIException(env);
2324 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2328 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2329 jni_mid_getDefaultAdapter);
2330 if (!jni_obj_BTAdapter)
2332 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2333 CACheckJNIException(env);
2334 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2338 // get remote bt adapter method
2339 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2340 "getBluetoothLeScanner",
2341 "()Landroid/bluetooth/"
2342 "le/BluetoothLeScanner;");
2343 if (!jni_mid_getBluetoothLeScanner)
2345 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
2346 CACheckJNIException(env);
2347 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2348 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2352 // get le scanner object
2353 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
2354 jni_mid_getBluetoothLeScanner);
2355 if (!jni_obj_leScanner)
2357 OIC_LOG(ERROR, TAG, "jni_obj_leScanner is null");
2358 CACheckJNIException(env);
2359 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2360 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2363 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2364 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2366 // call startScan method
2367 OIC_LOG(INFO, TAG, "CALL API - startScanWithUUID(for level 21)");
2368 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, jni_obj_filterList,
2369 jni_obj_scanSettings, callback);
2370 if (CACheckJNIException(env))
2372 OIC_LOG(INFO, TAG, "startScan has failed");
2378 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2381 (*env)->DeleteLocalRef(env, jni_obj_scanSettings);
2382 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2386 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
2388 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
2389 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2392 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2395 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
2399 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
2400 "(Ljava/lang/String;)"
2401 "Ljava/util/UUID;");
2402 if (!jni_mid_fromString)
2404 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
2408 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
2409 CACheckJNIException(env);
2410 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
2414 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2418 return jni_obj_uuid;
2421 CACheckJNIException(env);
2425 CAResult_t CALEClientStopScan()
2429 OIC_LOG(ERROR, TAG, "g_jvm is null");
2430 return CA_STATUS_FAILED;
2433 bool isAttached = false;
2435 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2438 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2441 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2442 return CA_STATUS_FAILED;
2447 CAResult_t ret = CA_STATUS_FAILED;
2449 if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
2451 ret = CALEClientStopScanImplForV21(env, g_leScanCallback);
2455 ret = CALEClientStopScanImpl(env, g_leScanCallback);
2458 if (CA_STATUS_OK != ret)
2460 if (CA_ADAPTER_NOT_ENABLED == ret)
2462 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
2466 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
2472 (*g_jvm)->DetachCurrentThread(g_jvm);
2478 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
2480 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl IN");
2481 VERIFY_NON_NULL(callback, TAG, "callback is null");
2482 VERIFY_NON_NULL(env, TAG, "env is null");
2484 if (!CALEIsEnableBTAdapter(env))
2486 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2487 return CA_ADAPTER_NOT_ENABLED;
2490 // get default bt adapter class
2491 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2492 if (!jni_cid_BTAdapter)
2494 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2495 CACheckJNIException(env);
2496 return CA_STATUS_FAILED;
2499 // get remote bt adapter method
2500 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2501 "getDefaultAdapter",
2502 METHODID_OBJECTNONPARAM);
2503 if (!jni_mid_getDefaultAdapter)
2505 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2506 CACheckJNIException(env);
2507 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2508 return CA_STATUS_FAILED;
2511 // get start le scan method
2512 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
2513 "(Landroid/bluetooth/"
2514 "BluetoothAdapter$LeScanCallback;)V");
2515 if (!jni_mid_stopLeScan)
2517 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
2518 CACheckJNIException(env);
2519 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2520 return CA_STATUS_FAILED;
2523 // get bt adapter object
2524 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2525 jni_mid_getDefaultAdapter);
2526 if (!jni_obj_BTAdapter)
2528 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2529 CACheckJNIException(env);
2530 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2531 return CA_STATUS_FAILED;
2534 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
2535 // call start le scan method
2536 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
2537 if (CACheckJNIException(env))
2539 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
2540 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2541 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2542 return CA_STATUS_FAILED;
2545 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2546 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2547 return CA_STATUS_OK;
2550 CAResult_t CALEClientStopScanImplForV21(JNIEnv *env, jobject callback)
2552 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImplForV21 IN");
2553 VERIFY_NON_NULL(callback, TAG, "callback is null");
2554 VERIFY_NON_NULL(env, TAG, "env is null");
2556 if (!CALEIsEnableBTAdapter(env))
2558 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2559 return CA_ADAPTER_NOT_ENABLED;
2562 // get default bt adapter class
2563 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2564 if (!jni_cid_BTAdapter)
2566 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2567 CACheckJNIException(env);
2568 return CA_STATUS_FAILED;
2571 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2572 "getDefaultAdapter",
2573 "()Landroid/bluetooth/"
2574 "BluetoothAdapter;");
2575 if (!jni_mid_getDefaultAdapter)
2577 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2578 CACheckJNIException(env);
2579 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2580 return CA_STATUS_FAILED;
2583 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2584 jni_mid_getDefaultAdapter);
2585 if (!jni_obj_BTAdapter)
2587 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2588 CACheckJNIException(env);
2589 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2590 return CA_STATUS_FAILED;
2593 // get bluetoothLeScanner class
2594 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
2595 if (!jni_cid_leScanner)
2597 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
2598 CACheckJNIException(env);
2599 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2600 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2601 return CA_STATUS_FAILED;
2604 // get remote bt adapter method
2605 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2606 "getBluetoothLeScanner",
2607 "()Landroid/bluetooth/"
2608 "le/BluetoothLeScanner;");
2609 if (!jni_mid_getBluetoothLeScanner)
2611 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
2612 CACheckJNIException(env);
2613 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2614 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2615 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2616 return CA_STATUS_FAILED;
2618 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2620 // get stopScan(ScanCallback callback) method
2621 jmethodID jni_mid_stopScan = (*env)->GetMethodID(env, jni_cid_leScanner, "stopScan",
2622 "(Landroid/bluetooth/le/ScanCallback;)V");
2623 if (!jni_mid_stopScan)
2625 OIC_LOG(ERROR, TAG, "stopScan: jni_mid_stopScan is null");
2626 CACheckJNIException(env);
2627 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2628 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2629 return CA_STATUS_FAILED;
2631 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2633 // gat le scanner object
2634 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
2635 jni_mid_getBluetoothLeScanner);
2636 if (!jni_obj_leScanner)
2638 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
2639 CACheckJNIException(env);
2640 return CA_STATUS_FAILED;
2643 // call stopScan method
2644 OIC_LOG(INFO, TAG, "CALL API - stopScan for level 21");
2645 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_stopScan, callback);
2646 if (CACheckJNIException(env))
2648 OIC_LOG(INFO, TAG, "stopScan for level 21 has failed");
2649 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2650 return CA_STATUS_FAILED;
2653 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2654 return CA_STATUS_OK;
2657 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2659 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
2660 VERIFY_NON_NULL(env, TAG, "env is null");
2661 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
2663 oc_mutex_lock(g_threadSendMutex);
2665 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
2668 OIC_LOG(ERROR, TAG, "jni_address is not available");
2669 oc_mutex_unlock(g_threadSendMutex);
2670 return CA_STATUS_FAILED;
2673 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2676 OIC_LOG(ERROR, TAG, "address is not available");
2677 CACheckJNIException(env);
2678 oc_mutex_unlock(g_threadSendMutex);
2679 return CA_STATUS_FAILED;
2682 CAResult_t res = CA_STATUS_OK;
2683 if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2686 g_deviceStateListMutex))
2688 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
2689 if (NULL == newGatt)
2691 OIC_LOG(INFO, TAG, "newGatt is not available");
2692 res = CA_STATUS_FAILED;
2695 oc_mutex_unlock(g_threadSendMutex);
2700 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2702 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
2703 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2704 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
2706 // reset scan interval time after checking scanned devices
2707 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
2709 // since there is no callback related stop success
2710 // and scanning should be stopped before connectGatt is called.
2711 // it should wait a few micro seconds.
2714 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
2715 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
2718 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2721 OIC_LOG(ERROR, TAG, "address is not available");
2725 // close the gatt service
2726 jobject gatt = CALEClientGetGattObjInList(env, address);
2729 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
2730 if (CA_STATUS_OK != res)
2732 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
2733 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2737 // clean previous gatt object after close profile service
2738 res = CALEClientRemoveGattObjForAddr(env, jni_address);
2739 if (CA_STATUS_OK != res)
2741 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
2742 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2746 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2749 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
2752 OIC_LOG(DEBUG, TAG, "re-connection will be started");
2756 // add new gatt object into g_gattObjectList
2757 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
2758 if (CA_STATUS_OK != res)
2760 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
2767 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2769 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
2770 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2771 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
2773 if (!g_leGattCallback)
2775 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
2779 if (!CALEIsEnableBTAdapter(env))
2781 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2785 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
2788 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
2792 jobject jni_obj_connectGatt = NULL;
2793 jint jni_int_sdk = CALEGetBuildVersion(env);
2794 OIC_LOG_V(INFO, TAG, "API level is %d", jni_int_sdk);
2795 if (jni_int_sdk >= 23) // upper than API level 23
2797 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
2799 "(Landroid/content/Context;ZLandroid/"
2800 "bluetooth/BluetoothGattCallback;I)"
2801 "Landroid/bluetooth/BluetoothGatt;");
2802 if (!jni_mid_connectGatt)
2804 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
2808 jint jni_transport_le = CALEGetConstantsValue(env, CLASSPATH_BT_DEVICE, "TRANSPORT_LE");
2809 OIC_LOG_V(INFO, TAG, "CALL API - connectGatt with transport LE(%d)", jni_transport_le);
2810 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
2811 jni_mid_connectGatt, NULL,
2812 autoconnect, g_leGattCallback,
2814 if (!jni_obj_connectGatt)
2816 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
2817 CACheckJNIException(env);
2818 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
2819 CALEClientUpdateSendCnt(env);
2824 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
2827 else // lower than API level 23
2830 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2833 OIC_LOG(ERROR, TAG, "GetStringUTFChars has failed");
2836 OIC_LOG(INFO, TAG, "CALL API - connectGatt for hidden");
2837 jni_obj_connectGatt = CALEClientHiddenConnectGatt(bluetoothDevice, address, autoconnect);
2841 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
2843 "(Landroid/content/Context;ZLandroid/"
2844 "bluetooth/BluetoothGattCallback;)"
2845 "Landroid/bluetooth/BluetoothGatt;");
2846 if (!jni_mid_connectGatt)
2848 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
2852 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
2853 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
2854 jni_mid_connectGatt,
2856 autoconnect, g_leGattCallback);
2858 if (!jni_obj_connectGatt)
2860 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
2861 CACheckJNIException(env);
2862 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
2863 CALEClientUpdateSendCnt(env);
2868 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
2873 return jni_obj_connectGatt;
2876 bool CALEClientIsConnected(const char* address)
2878 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2879 STATE_SERVICE_CONNECTED,
2881 g_deviceStateListMutex))
2883 OIC_LOG(DEBUG, TAG, "current state is connected");
2886 OIC_LOG(DEBUG, TAG, "current state is not connected");
2890 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
2892 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
2894 VERIFY_NON_NULL(env, TAG, "env is null");
2895 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2897 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2898 if (!jni_cid_BTAdapter)
2900 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
2904 // get remote bt adapter method
2905 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2906 "getDefaultAdapter",
2907 METHODID_OBJECTNONPARAM);
2908 if (!jni_mid_getDefaultAdapter)
2910 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2914 // gat bt adapter object
2915 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2916 jni_mid_getDefaultAdapter);
2917 if (!jni_obj_BTAdapter)
2919 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2923 // get closeProfileProxy method
2924 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2925 "closeProfileProxy",
2926 "(ILandroid/bluetooth/"
2927 "BluetoothProfile;)V");
2928 if (!jni_mid_closeProfileProxy)
2930 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
2934 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
2935 if (!jni_cid_BTProfile)
2937 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
2941 // GATT - Constant value : 7 (0x00000007)
2942 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
2946 OIC_LOG(ERROR, TAG, "id_gatt is null");
2950 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
2951 CACheckJNIException(env);
2953 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
2954 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
2955 if (CACheckJNIException(env))
2957 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
2958 return CA_STATUS_FAILED;
2961 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
2962 return CA_STATUS_OK;
2965 CACheckJNIException(env);
2966 return CA_STATUS_FAILED;
2970 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
2972 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
2973 VERIFY_NON_NULL(env, TAG, "env is null");
2974 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2976 // get BluetoothGatt method
2977 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
2978 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2979 "disconnect", "()V");
2980 if (!jni_mid_disconnectGatt)
2982 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
2983 return CA_STATUS_FAILED;
2986 // call disconnect gatt method
2987 OIC_LOG(INFO, TAG, "CALL API - disconnect");
2988 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
2989 if (CACheckJNIException(env))
2991 OIC_LOG(ERROR, TAG, "disconnect has failed");
2992 return CA_STATUS_FAILED;
2995 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
2997 return CA_STATUS_OK;
3000 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
3002 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
3003 VERIFY_NON_NULL(env, TAG, "env is null");
3005 if (!g_gattObjectList)
3007 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3008 return CA_STATUS_OK;
3011 uint32_t length = u_arraylist_length(g_gattObjectList);
3012 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
3013 for (uint32_t index = 0; index < length; index++)
3015 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
3016 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3019 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3022 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
3023 if (CA_STATUS_OK != res)
3025 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
3030 return CA_STATUS_OK;
3033 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
3035 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
3036 VERIFY_NON_NULL(env, TAG, "env is null");
3038 if (!g_gattObjectList)
3040 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3041 return CA_STATUS_OK;
3044 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
3047 OIC_LOG(ERROR, TAG, "address is null");
3048 CACheckJNIException(env);
3049 return CA_STATUS_FAILED;
3052 uint32_t length = u_arraylist_length(g_gattObjectList);
3053 for (uint32_t index = 0; index < length; index++)
3055 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3058 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3062 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3063 if (!jni_setAddress)
3065 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3066 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3067 return CA_STATUS_FAILED;
3070 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3073 OIC_LOG(ERROR, TAG, "setAddress is null");
3074 CACheckJNIException(env);
3075 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3076 return CA_STATUS_FAILED;
3079 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
3080 if (!strcasecmp(address, setAddress))
3082 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
3083 if (CA_STATUS_OK != res)
3085 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
3086 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3087 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3088 return CA_STATUS_FAILED;
3090 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3091 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3092 return CA_STATUS_OK;
3094 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3096 (*env)->ReleaseStringUTFChars(env, remote_address, address);
3098 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
3099 return CA_STATUS_OK;
3102 CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size)
3104 VERIFY_NON_NULL(env, TAG, "env is null");
3105 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3107 if (!CALEIsEnableBTAdapter(env))
3109 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3110 return CA_ADAPTER_NOT_ENABLED;
3113 // get BluetoothGatt.requestMtu method
3114 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.requestMtu method");
3115 jmethodID jni_mid_requestMtu = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3116 "requestMtu", "(I)Z");
3117 if (!jni_mid_requestMtu)
3119 OIC_LOG(ERROR, TAG, "jni_mid_requestMtu is null");
3120 return CA_STATUS_FAILED;
3124 OIC_LOG(INFO, TAG, "CALL API - requestMtu");
3125 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_requestMtu, size);
3128 OIC_LOG(ERROR, TAG, "requestMtu has failed");
3129 CACheckJNIException(env);
3130 return CA_STATUS_FAILED;
3133 return CA_STATUS_OK;
3136 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
3138 VERIFY_NON_NULL(env, TAG, "env is null");
3139 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3141 if (!CALEIsEnableBTAdapter(env))
3143 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3144 return CA_ADAPTER_NOT_ENABLED;
3147 // get BluetoothGatt.discoverServices method
3148 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
3149 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3150 "discoverServices", "()Z");
3151 if (!jni_mid_discoverServices)
3153 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
3154 return CA_STATUS_FAILED;
3157 // call disconnect gatt method
3158 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
3159 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
3162 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
3163 CACheckJNIException(env);
3164 return CA_STATUS_FAILED;
3167 return CA_STATUS_OK;
3170 static void CALEWriteCharacteristicThread(void* object)
3172 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
3174 bool isAttached = false;
3176 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3179 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3183 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3189 jobject gatt = (jobject)object;
3190 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
3191 if (CA_STATUS_OK != ret)
3193 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
3198 (*g_jvm)->DetachCurrentThread(g_jvm);
3202 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
3204 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
3206 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3207 VERIFY_NON_NULL(env, TAG, "env is null");
3209 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3212 CALEClientSendFinish(env, gatt);
3213 return CA_STATUS_FAILED;
3216 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3219 CACheckJNIException(env);
3220 CALEClientSendFinish(env, gatt);
3221 return CA_STATUS_FAILED;
3224 oc_mutex_lock(g_threadSendStateMutex);
3226 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING,
3228 g_deviceStateListMutex))
3230 OIC_LOG(INFO, TAG, "current state is SENDING");
3231 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3232 oc_mutex_unlock(g_threadSendStateMutex);
3233 return CA_STATUS_OK;
3236 if (CA_STATUS_OK != CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
3239 g_deviceStateListMutex))
3241 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
3242 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3243 CALEClientSendFinish(env, gatt);
3244 oc_mutex_unlock(g_threadSendStateMutex);
3245 return CA_STATUS_FAILED;
3248 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3250 oc_mutex_unlock(g_threadSendStateMutex);
3252 jbyteArray sendData = NULL;
3253 oc_mutex_lock(g_setValueMutex);
3256 OIC_LOG(INFO, TAG, "alloc local reference for data");
3257 sendData = (jbyteArray)(*env)->NewLocalRef(env, g_sendBuffer);
3261 OIC_LOG(ERROR, TAG, "send Buffer is empty");
3262 oc_mutex_unlock(g_setValueMutex);
3263 return CA_STATUS_FAILED;
3265 oc_mutex_unlock(g_setValueMutex);
3268 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, sendData);
3269 if (!jni_obj_character)
3273 (*env)->DeleteLocalRef(env, sendData);
3275 CALEClientSendFinish(env, gatt);
3276 return CA_STATUS_FAILED;
3281 (*env)->DeleteLocalRef(env, sendData);
3284 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
3285 if (CA_STATUS_OK != ret)
3287 CALEClientSendFinish(env, gatt);
3288 return CA_STATUS_FAILED;
3291 // wait for callback for write Characteristic with success to sent data
3292 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
3293 oc_mutex_lock(g_threadWriteCharacteristicMutex);
3294 if (!g_isSignalSetFlag)
3296 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
3297 if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
3298 g_threadWriteCharacteristicMutex,
3299 WAIT_TIME_WRITE_CHARACTERISTIC))
3301 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
3302 g_isSignalSetFlag = false;
3303 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3304 return CA_STATUS_FAILED;
3307 // reset flag set by writeCharacteristic Callback
3308 g_isSignalSetFlag = false;
3309 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3311 CALEClientUpdateSendCnt(env);
3313 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
3314 return CA_STATUS_OK;
3317 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
3319 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
3320 VERIFY_NON_NULL(env, TAG, "env is null");
3321 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3323 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
3324 CACheckJNIException(env);
3325 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEWriteCharacteristicThread,
3326 (void*)gattParam, NULL))
3328 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
3329 return CA_STATUS_FAILED;
3332 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
3333 return CA_STATUS_OK;
3336 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
3337 jobject gattCharacteristic)
3339 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
3340 VERIFY_NON_NULL(env, TAG, "env is null");
3341 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3342 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
3344 if (!CALEIsEnableBTAdapter(env))
3346 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3347 return CA_STATUS_FAILED;
3350 // get BluetoothGatt.write characteristic method
3351 OIC_LOG(DEBUG, TAG, "write characteristic method");
3352 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3353 "writeCharacteristic",
3354 "(Landroid/bluetooth/"
3355 "BluetoothGattCharacteristic;)Z");
3356 if (!jni_mid_writeCharacteristic)
3358 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
3359 return CA_STATUS_FAILED;
3362 // call disconnect gatt method
3363 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
3364 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
3365 jni_mid_writeCharacteristic,
3366 gattCharacteristic);
3369 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
3373 CACheckJNIException(env);
3374 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
3375 return CA_STATUS_FAILED;
3378 return CA_STATUS_OK;
3381 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
3383 VERIFY_NON_NULL(env, TAG, "env is null");
3384 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3386 if (!CALEIsEnableBTAdapter(env))
3388 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3389 return CA_STATUS_FAILED;
3392 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3395 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3396 CACheckJNIException(env);
3397 return CA_STATUS_FAILED;
3400 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
3401 if (!jni_obj_GattCharacteristic)
3403 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3404 return CA_STATUS_FAILED;
3407 OIC_LOG(DEBUG, TAG, "read characteristic method");
3408 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3409 "readCharacteristic",
3410 "(Landroid/bluetooth/"
3411 "BluetoothGattCharacteristic;)Z");
3412 if (!jni_mid_readCharacteristic)
3414 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
3415 return CA_STATUS_FAILED;
3418 // call disconnect gatt method
3419 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
3420 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
3421 jni_obj_GattCharacteristic);
3424 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
3428 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
3429 CACheckJNIException(env);
3430 return CA_STATUS_FAILED;
3433 return CA_STATUS_OK;
3436 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
3437 jobject characteristic)
3439 VERIFY_NON_NULL(env, TAG, "env is null");
3440 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3441 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
3443 if (!CALEIsEnableBTAdapter(env))
3445 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3446 return CA_ADAPTER_NOT_ENABLED;
3449 // get BluetoothGatt.setCharacteristicNotification method
3450 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
3451 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3452 "setCharacteristicNotification",
3453 "(Landroid/bluetooth/"
3454 "BluetoothGattCharacteristic;Z)Z");
3455 if (!jni_mid_setNotification)
3457 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
3458 return CA_STATUS_FAILED;
3461 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
3462 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
3463 characteristic, JNI_TRUE);
3464 if (JNI_TRUE == ret)
3466 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
3470 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
3471 CACheckJNIException(env);
3472 return CA_STATUS_FAILED;
3475 return CA_STATUS_OK;
3478 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
3480 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3481 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
3482 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
3484 if (!CALEIsEnableBTAdapter(env))
3486 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3490 // get BluetoothGatt.getService method
3491 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
3492 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3494 "(Ljava/util/UUID;)Landroid/bluetooth/"
3495 "BluetoothGattService;");
3496 if (!jni_mid_getService)
3498 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
3502 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
3503 if (!jni_obj_service_uuid)
3505 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
3509 // get bluetooth gatt service
3510 OIC_LOG(DEBUG, TAG, "request to get service");
3511 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
3512 jni_obj_service_uuid);
3513 if (!jni_obj_gattService)
3515 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
3516 CACheckJNIException(env);
3520 // get bluetooth gatt service method
3521 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
3522 "BluetoothGattService",
3523 "getCharacteristic",
3524 "(Ljava/util/UUID;)"
3525 "Landroid/bluetooth/"
3526 "BluetoothGattCharacteristic;");
3527 if (!jni_mid_getCharacteristic)
3529 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
3533 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
3536 OIC_LOG(ERROR, TAG, "uuid is null");
3537 CACheckJNIException(env);
3541 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
3542 if (!jni_obj_tx_uuid)
3544 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
3545 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
3549 OIC_LOG(DEBUG, TAG, "CALL API getCharacteristic");
3550 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
3551 jni_mid_getCharacteristic,
3553 if (!jni_obj_GattCharacteristic)
3555 OIC_LOG(ERROR, TAG, "getCharacteristic has failed");
3556 CACheckJNIException(env);
3560 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
3561 return jni_obj_GattCharacteristic;
3564 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
3566 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
3567 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3568 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
3569 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
3571 if (!CALEIsEnableBTAdapter(env))
3573 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3577 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
3580 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3584 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
3585 if (!jni_obj_GattCharacteristic)
3587 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3591 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
3592 "/BluetoothGattCharacteristic");
3593 if (!jni_cid_BTGattCharacteristic)
3595 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
3599 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
3600 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
3602 if (!jni_mid_setValue)
3604 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
3608 OIC_LOG(DEBUG, TAG, "CALL API - setValue");
3609 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
3611 if (JNI_TRUE == ret)
3613 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
3617 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
3623 OIC_LOG(DEBUG, TAG, "setWriteType with WRITE_TYPE_NO_RESPONSE");
3625 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
3626 "setWriteType", "(I)V");
3627 if (!jni_mid_setWriteType)
3629 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
3633 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
3634 "WRITE_TYPE_NO_RESPONSE", "I");
3635 if (!jni_fid_no_response)
3637 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
3641 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
3642 jni_fid_no_response);
3643 CACheckJNIException(env);
3645 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
3646 if (CACheckJNIException(env))
3648 OIC_LOG(ERROR, TAG, "setWriteType has failed");
3653 OIC_LOG(DEBUG, TAG, "It will run with response property");
3656 return jni_obj_GattCharacteristic;
3659 CACheckJNIException(env);
3663 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
3665 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
3666 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3668 if (!CALEIsEnableBTAdapter(env))
3670 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3674 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
3675 "BluetoothGattCharacteristic",
3676 "getValue", "()[B");
3677 if (!jni_mid_getValue)
3679 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
3683 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
3685 CACheckJNIException(env);
3686 return jni_obj_data_array;
3689 CAResult_t CALEClientCreateUUIDList()
3693 OIC_LOG(ERROR, TAG, "g_jvm is null");
3694 return CA_STATUS_FAILED;
3697 bool isAttached = false;
3699 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3702 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3706 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3707 return CA_STATUS_FAILED;
3712 // create new object array
3713 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
3714 if (!jni_cid_uuid_list)
3716 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
3717 CACheckJNIException(env);
3721 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
3722 jni_cid_uuid_list, NULL);
3723 if (!jni_obj_uuid_list)
3725 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
3726 CACheckJNIException(env);
3731 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
3734 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
3737 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
3739 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
3740 CACheckJNIException(env);
3744 (*g_jvm)->DetachCurrentThread(g_jvm);
3747 return CA_STATUS_OK;
3754 (*g_jvm)->DetachCurrentThread(g_jvm);
3756 return CA_STATUS_FAILED;
3759 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
3760 jobject characteristic)
3762 VERIFY_NON_NULL(env, TAG, "env is null");
3763 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3764 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
3766 if (!CALEIsEnableBTAdapter(env))
3768 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3769 return CA_ADAPTER_NOT_ENABLED;
3772 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
3773 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
3774 "BluetoothGattCharacteristic",
3776 "(Ljava/util/UUID;)Landroid/bluetooth/"
3777 "BluetoothGattDescriptor;");
3778 if (!jni_mid_getDescriptor)
3780 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
3781 return CA_STATUS_FAILED;
3784 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
3785 if (!jni_obj_cc_uuid)
3787 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
3790 OIC_LOG(DEBUG, TAG, "request to get descriptor");
3791 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
3792 jni_mid_getDescriptor, jni_obj_cc_uuid);
3793 if (!jni_obj_descriptor)
3795 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
3799 OIC_LOG(DEBUG, TAG, "set value in descriptor");
3800 jclass jni_cid_descriptor = (*env)->FindClass(env,
3801 "android/bluetooth/BluetoothGattDescriptor");
3802 if (!jni_cid_descriptor)
3804 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
3808 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
3809 if (!jni_mid_setValue)
3811 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
3815 jfieldID jni_fid_NotiValue = NULL;
3818 OIC_LOG(DEBUG, TAG, "get ENABLE_INDICATION_VALUE");
3819 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
3820 "ENABLE_INDICATION_VALUE", "[B");
3821 if (!jni_fid_NotiValue)
3823 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
3829 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
3830 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
3831 "ENABLE_NOTIFICATION_VALUE", "[B");
3832 if (!jni_fid_NotiValue)
3834 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
3839 jboolean jni_setvalue = (*env)->CallBooleanMethod(
3840 env, jni_obj_descriptor, jni_mid_setValue,
3841 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
3844 OIC_LOG(DEBUG, TAG, "setValue success");
3848 OIC_LOG(ERROR, TAG, "setValue has failed");
3852 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
3854 "(Landroid/bluetooth/"
3855 "BluetoothGattDescriptor;)Z");
3856 if (!jni_mid_writeDescriptor)
3858 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
3859 return CA_STATUS_FAILED;
3862 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
3863 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
3864 jni_obj_descriptor);
3867 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
3871 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
3875 return CA_STATUS_OK;
3878 CACheckJNIException(env);
3879 return CA_STATUS_FAILED;
3882 void CALEClientCreateScanDeviceList(JNIEnv *env)
3884 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
3885 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3887 oc_mutex_lock(g_deviceListMutex);
3888 // create new object array
3889 if (g_deviceList == NULL)
3891 OIC_LOG(DEBUG, TAG, "Create device list");
3893 g_deviceList = u_arraylist_create();
3895 oc_mutex_unlock(g_deviceListMutex);
3898 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
3900 VERIFY_NON_NULL(device, TAG, "device is null");
3901 VERIFY_NON_NULL(env, TAG, "env is null");
3903 oc_mutex_lock(g_deviceListMutex);
3907 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3908 oc_mutex_unlock(g_deviceListMutex);
3909 return CA_STATUS_FAILED;
3912 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
3913 if (!jni_remoteAddress)
3915 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3916 oc_mutex_unlock(g_deviceListMutex);
3917 return CA_STATUS_FAILED;
3920 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3923 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3924 CACheckJNIException(env);
3925 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3926 oc_mutex_unlock(g_deviceListMutex);
3927 return CA_STATUS_FAILED;
3930 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
3932 jobject gdevice = (*env)->NewGlobalRef(env, device);
3933 CACheckJNIException(env);
3934 u_arraylist_add(g_deviceList, gdevice);
3935 oc_cond_signal(g_deviceDescCond);
3936 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
3938 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3939 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3941 oc_mutex_unlock(g_deviceListMutex);
3943 return CA_STATUS_OK;
3946 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
3948 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
3949 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
3953 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
3957 uint32_t length = u_arraylist_length(g_deviceList);
3958 for (uint32_t index = 0; index < length; index++)
3960 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3963 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3967 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
3968 if (!jni_setAddress)
3970 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3974 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3977 OIC_LOG(ERROR, TAG, "setAddress is null");
3978 CACheckJNIException(env);
3979 (*env)->DeleteLocalRef(env, jni_setAddress);
3983 if (!strcasecmp(remoteAddress, setAddress))
3985 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3986 (*env)->DeleteLocalRef(env, jni_setAddress);
3990 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3991 (*env)->DeleteLocalRef(env, jni_setAddress);
3996 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
3998 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
3999 VERIFY_NON_NULL(env, TAG, "env is null");
4001 oc_mutex_lock(g_deviceListMutex);
4005 OIC_LOG(ERROR, TAG, "g_deviceList is null");
4006 oc_mutex_unlock(g_deviceListMutex);
4007 return CA_STATUS_FAILED;
4010 uint32_t length = u_arraylist_length(g_deviceList);
4011 for (uint32_t index = 0; index < length; index++)
4013 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
4016 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4019 (*env)->DeleteGlobalRef(env, jarrayObj);
4023 OICFree(g_deviceList);
4024 g_deviceList = NULL;
4026 oc_mutex_unlock(g_deviceListMutex);
4027 return CA_STATUS_OK;
4030 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
4032 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
4033 VERIFY_NON_NULL(address, TAG, "address is null");
4034 VERIFY_NON_NULL(env, TAG, "env is null");
4036 oc_mutex_lock(g_deviceListMutex);
4040 OIC_LOG(ERROR, TAG, "g_deviceList is null");
4041 oc_mutex_unlock(g_deviceListMutex);
4042 return CA_STATUS_FAILED;
4045 uint32_t length = u_arraylist_length(g_deviceList);
4046 for (uint32_t index = 0; index < length; index++)
4048 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
4051 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4052 oc_mutex_unlock(g_deviceListMutex);
4053 return CA_STATUS_FAILED;
4056 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
4057 if (!jni_setAddress)
4059 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4060 oc_mutex_unlock(g_deviceListMutex);
4061 return CA_STATUS_FAILED;
4064 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4067 OIC_LOG(ERROR, TAG, "setAddress is null");
4068 CACheckJNIException(env);
4069 oc_mutex_unlock(g_deviceListMutex);
4070 return CA_STATUS_FAILED;
4073 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
4076 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4077 CACheckJNIException(env);
4078 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4079 oc_mutex_unlock(g_deviceListMutex);
4080 return CA_STATUS_FAILED;
4083 if (!strcasecmp(setAddress, remoteAddress))
4085 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4086 (*env)->DeleteGlobalRef(env, jarrayObj);
4088 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4089 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
4091 if (NULL == u_arraylist_remove(g_deviceList, index))
4093 OIC_LOG(ERROR, TAG, "List removal failed.");
4094 oc_mutex_unlock(g_deviceListMutex);
4095 return CA_STATUS_FAILED;
4097 oc_mutex_unlock(g_deviceListMutex);
4098 return CA_STATUS_OK;
4100 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4101 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
4104 oc_mutex_unlock(g_deviceListMutex);
4105 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
4107 return CA_STATUS_OK;
4114 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
4116 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
4117 VERIFY_NON_NULL(env, TAG, "env is null");
4118 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
4120 oc_mutex_lock(g_gattObjectMutex);
4122 if (!g_gattObjectList)
4124 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
4125 oc_mutex_unlock(g_gattObjectMutex);
4126 return CA_STATUS_FAILED;
4129 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
4130 if (!jni_remoteAddress)
4132 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
4133 oc_mutex_unlock(g_gattObjectMutex);
4134 return CA_STATUS_FAILED;
4137 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
4140 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4141 CACheckJNIException(env);
4142 (*env)->DeleteLocalRef(env, jni_remoteAddress);
4143 oc_mutex_unlock(g_gattObjectMutex);
4144 return CA_STATUS_FAILED;
4147 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
4148 if (!CALEClientIsGattObjInList(env, remoteAddress))
4150 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
4151 u_arraylist_add(g_gattObjectList, newGatt);
4152 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
4155 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4156 (*env)->DeleteLocalRef(env, jni_remoteAddress);
4157 oc_mutex_unlock(g_gattObjectMutex);
4158 return CA_STATUS_OK;
4161 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
4163 VERIFY_NON_NULL(env, TAG, "env is null");
4164 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
4166 uint32_t length = u_arraylist_length(g_gattObjectList);
4167 for (uint32_t index = 0; index < length; index++)
4169 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4172 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4176 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4177 if (!jni_setAddress)
4179 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4183 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4186 OIC_LOG(ERROR, TAG, "setAddress is null");
4187 CACheckJNIException(env);
4188 (*env)->DeleteLocalRef(env, jni_setAddress);
4192 if (!strcasecmp(remoteAddress, setAddress))
4194 OIC_LOG(DEBUG, TAG, "the device is already set");
4195 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4196 (*env)->DeleteLocalRef(env, jni_setAddress);
4199 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4200 (*env)->DeleteLocalRef(env, jni_setAddress);
4203 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
4207 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
4209 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
4210 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4211 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
4213 oc_mutex_lock(g_gattObjectMutex);
4214 uint32_t length = u_arraylist_length(g_gattObjectList);
4215 for (uint32_t index = 0; index < length; index++)
4217 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4220 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4221 oc_mutex_unlock(g_gattObjectMutex);
4225 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4226 if (!jni_setAddress)
4228 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4229 oc_mutex_unlock(g_gattObjectMutex);
4233 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4236 OIC_LOG(ERROR, TAG, "setAddress is null");
4237 CACheckJNIException(env);
4238 (*env)->DeleteLocalRef(env, jni_setAddress);
4239 oc_mutex_unlock(g_gattObjectMutex);
4243 if (!strcasecmp(remoteAddress, setAddress))
4245 OIC_LOG(DEBUG, TAG, "the device is already set");
4246 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4247 oc_mutex_unlock(g_gattObjectMutex);
4250 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4251 (*env)->DeleteLocalRef(env, jni_setAddress);
4254 oc_mutex_unlock(g_gattObjectMutex);
4255 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
4259 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
4261 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
4262 VERIFY_NON_NULL(env, TAG, "env is null");
4264 oc_mutex_lock(g_gattObjectMutex);
4265 if (!g_gattObjectList)
4267 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4268 oc_mutex_unlock(g_gattObjectMutex);
4269 return CA_STATUS_OK;
4272 uint32_t length = u_arraylist_length(g_gattObjectList);
4273 for (uint32_t index = 0; index < length; index++)
4275 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4278 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4281 (*env)->DeleteGlobalRef(env, jarrayObj);
4285 OICFree(g_gattObjectList);
4286 g_gattObjectList = NULL;
4287 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
4288 oc_mutex_unlock(g_gattObjectMutex);
4289 return CA_STATUS_OK;
4292 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
4294 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
4295 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
4296 VERIFY_NON_NULL(env, TAG, "env is null");
4298 oc_mutex_lock(g_gattObjectMutex);
4299 if (!g_gattObjectList)
4301 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4302 oc_mutex_unlock(g_gattObjectMutex);
4303 return CA_STATUS_OK;
4306 uint32_t length = u_arraylist_length(g_gattObjectList);
4307 for (uint32_t index = 0; index < length; index++)
4309 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4312 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4313 oc_mutex_unlock(g_gattObjectMutex);
4314 return CA_STATUS_FAILED;
4317 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4318 if (!jni_setAddress)
4320 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4321 oc_mutex_unlock(g_gattObjectMutex);
4322 return CA_STATUS_FAILED;
4325 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4328 OIC_LOG(ERROR, TAG, "setAddress is null");
4329 CACheckJNIException(env);
4330 oc_mutex_unlock(g_gattObjectMutex);
4331 return CA_STATUS_FAILED;
4334 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
4335 if (!jni_remoteAddress)
4337 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
4338 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4339 oc_mutex_unlock(g_gattObjectMutex);
4340 return CA_STATUS_FAILED;
4343 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
4346 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4347 CACheckJNIException(env);
4348 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4349 oc_mutex_unlock(g_gattObjectMutex);
4350 return CA_STATUS_FAILED;
4353 if (!strcasecmp(setAddress, remoteAddress))
4355 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4356 (*env)->DeleteGlobalRef(env, jarrayObj);
4358 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4359 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4361 if (NULL == u_arraylist_remove(g_gattObjectList, index))
4363 OIC_LOG(ERROR, TAG, "List removal failed.");
4364 oc_mutex_unlock(g_gattObjectMutex);
4365 return CA_STATUS_FAILED;
4367 oc_mutex_unlock(g_gattObjectMutex);
4368 return CA_STATUS_OK;
4370 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4371 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4374 oc_mutex_unlock(g_gattObjectMutex);
4375 OIC_LOG(DEBUG, TAG, "there are no target object");
4376 return CA_STATUS_OK;
4379 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
4381 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
4382 VERIFY_NON_NULL(addr, TAG, "addr is null");
4383 VERIFY_NON_NULL(env, TAG, "env is null");
4385 oc_mutex_lock(g_gattObjectMutex);
4386 if (!g_gattObjectList)
4388 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4389 oc_mutex_unlock(g_gattObjectMutex);
4390 return CA_STATUS_OK;
4393 uint32_t length = u_arraylist_length(g_gattObjectList);
4394 for (uint32_t index = 0; index < length; index++)
4396 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4399 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4400 oc_mutex_unlock(g_gattObjectMutex);
4401 return CA_STATUS_FAILED;
4404 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4405 if (!jni_setAddress)
4407 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4408 oc_mutex_unlock(g_gattObjectMutex);
4409 return CA_STATUS_FAILED;
4412 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4415 OIC_LOG(ERROR, TAG, "setAddress is null");
4416 CACheckJNIException(env);
4417 oc_mutex_unlock(g_gattObjectMutex);
4418 return CA_STATUS_FAILED;
4421 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
4424 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4425 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4426 oc_mutex_unlock(g_gattObjectMutex);
4427 return CA_STATUS_FAILED;
4430 if (!strcasecmp(setAddress, remoteAddress))
4432 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4433 (*env)->DeleteGlobalRef(env, jarrayObj);
4435 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4436 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
4437 if (NULL == u_arraylist_remove(g_gattObjectList, index))
4439 OIC_LOG(ERROR, TAG, "List removal failed.");
4440 oc_mutex_unlock(g_gattObjectMutex);
4441 return CA_STATUS_FAILED;
4443 oc_mutex_unlock(g_gattObjectMutex);
4444 return CA_STATUS_OK;
4446 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4447 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
4450 oc_mutex_unlock(g_gattObjectMutex);
4451 OIC_LOG(DEBUG, TAG, "there are no target object");
4452 return CA_STATUS_FAILED;
4455 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
4457 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
4458 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
4460 // get Bluetooth Address
4461 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
4462 if (!jni_btTargetAddress)
4464 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4468 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
4471 OIC_LOG(ERROR, TAG, "targetAddress is not available");
4472 CACheckJNIException(env);
4476 // get method ID of getDevice()
4477 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
4478 "getDevice", METHODID_BT_DEVICE);
4479 if (!jni_mid_getDevice)
4481 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4482 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4486 oc_mutex_lock(g_gattObjectMutex);
4488 size_t length = u_arraylist_length(g_gattObjectList);
4489 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
4490 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
4492 for (size_t index = 0; index < length; index++)
4494 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4497 oc_mutex_unlock(g_gattObjectMutex);
4498 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4499 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4503 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
4504 if (!jni_obj_device)
4506 CACheckJNIException(env);
4507 oc_mutex_unlock(g_gattObjectMutex);
4508 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4509 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4513 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
4516 oc_mutex_unlock(g_gattObjectMutex);
4517 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4518 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4519 (*env)->DeleteLocalRef(env, jni_obj_device);
4523 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
4526 CACheckJNIException(env);
4527 oc_mutex_unlock(g_gattObjectMutex);
4528 OIC_LOG(ERROR, TAG, "btAddress is not available");
4529 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4530 (*env)->DeleteLocalRef(env, jni_btAddress);
4531 (*env)->DeleteLocalRef(env, jni_obj_device);
4535 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
4536 if (!strcasecmp(targetAddress, btAddress))
4538 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
4541 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4544 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
4546 oc_mutex_unlock(g_gattObjectMutex);
4547 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4548 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
4549 (*env)->DeleteLocalRef(env, jni_btAddress);
4550 (*env)->DeleteLocalRef(env, jni_obj_device);
4551 return jni_LEAddress;
4553 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
4554 (*env)->DeleteLocalRef(env, jni_btAddress);
4555 (*env)->DeleteLocalRef(env, jni_obj_device);
4557 oc_mutex_unlock(g_gattObjectMutex);
4559 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4560 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
4567 CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env,
4569 uint16_t state_type,
4570 uint16_t target_state)
4572 VERIFY_NON_NULL(device, TAG, "device is null");
4574 // get Bluetooth Address
4575 jstring jni_Address = CALEGetAddressFromBTDevice(env, device);
4578 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4579 return CA_STATUS_FAILED;
4582 const char* address = (*env)->GetStringUTFChars(env, jni_Address, NULL);
4585 OIC_LOG(ERROR, TAG, "targetAddress is not available");
4586 CACheckJNIException(env);
4587 (*env)->DeleteLocalRef(env, jni_Address);
4588 return CA_STATUS_FAILED;
4591 if (CALEIsValidState(address, state_type, target_state,
4593 g_deviceStateListMutex))
4595 (*env)->DeleteLocalRef(env, jni_Address);
4596 return CA_STATUS_OK;
4599 CAResult_t res = CALEUpdateDeviceState(address, state_type,
4602 g_deviceStateListMutex);
4603 if (CA_STATUS_OK != res)
4605 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4607 (*env)->ReleaseStringUTFChars(env, jni_Address, address);
4608 (*env)->DeleteLocalRef(env, jni_Address);
4613 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
4614 jint state_idx, jboolean flag)
4616 return CALESetFlagToState(env, jni_address, state_idx, flag,
4617 g_deviceStateList, g_deviceStateListMutex);
4620 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
4622 return CALEGetFlagFromState(env, jni_address, state_idx, g_deviceStateList,
4623 g_deviceStateListMutex);
4626 uint16_t CALEClientGetMtuSize(const char* address)
4628 return CALEGetMtuSize(address, g_deviceStateList, g_deviceStateListMutex);
4631 void CALEClientCreateDeviceList()
4633 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
4635 // create new object array
4636 if (!g_gattObjectList)
4638 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
4640 g_gattObjectList = u_arraylist_create();
4643 if (!g_deviceStateList)
4645 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
4647 g_deviceStateList = u_arraylist_create();
4652 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
4654 g_deviceList = u_arraylist_create();
4658 CAResult_t CALEClientResetDeviceStateForAll()
4660 return CALEResetDeviceStateForAll(g_deviceStateList, g_deviceStateListMutex);
4664 * Check Sent Count for remove g_sendBuffer
4666 void CALEClientUpdateSendCnt(JNIEnv *env)
4668 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
4670 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4672 oc_mutex_lock(g_threadMutex);
4676 if (g_targetCnt <= g_currentSentCnt)
4679 g_currentSentCnt = 0;
4681 CALEDeleteSendBuffer(env);
4683 // notity the thread
4684 oc_cond_signal(g_threadCond);
4685 oc_cond_signal(g_threadWriteCharacteristicCond);
4687 CALEClientSetSendFinishFlag(true);
4688 OIC_LOG(DEBUG, TAG, "set signal for send data");
4691 #ifdef SCAN_INTERVAL
4692 // reset interval scan logic
4693 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
4697 oc_mutex_unlock(g_threadMutex);
4700 CAResult_t CALEClientInitGattMutexVaraibles()
4702 if (NULL == g_bleServerBDAddressMutex)
4704 g_bleServerBDAddressMutex = oc_mutex_new();
4705 if (NULL == g_bleServerBDAddressMutex)
4707 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4708 return CA_STATUS_FAILED;
4712 if (NULL == g_threadMutex)
4714 g_threadMutex = oc_mutex_new();
4715 if (NULL == g_threadMutex)
4717 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4718 return CA_STATUS_FAILED;
4722 if (NULL == g_threadSendMutex)
4724 g_threadSendMutex = oc_mutex_new();
4725 if (NULL == g_threadSendMutex)
4727 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4728 return CA_STATUS_FAILED;
4732 if (NULL == g_deviceListMutex)
4734 g_deviceListMutex = oc_mutex_new();
4735 if (NULL == g_deviceListMutex)
4737 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4738 return CA_STATUS_FAILED;
4742 if (NULL == g_gattObjectMutex)
4744 g_gattObjectMutex = oc_mutex_new();
4745 if (NULL == g_gattObjectMutex)
4747 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4748 return CA_STATUS_FAILED;
4752 if (NULL == g_deviceStateListMutex)
4754 g_deviceStateListMutex = oc_mutex_new();
4755 if (NULL == g_deviceStateListMutex)
4757 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4758 return CA_STATUS_FAILED;
4762 if (NULL == g_SendFinishMutex)
4764 g_SendFinishMutex = oc_mutex_new();
4765 if (NULL == g_SendFinishMutex)
4767 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4768 return CA_STATUS_FAILED;
4772 if (NULL == g_threadWriteCharacteristicMutex)
4774 g_threadWriteCharacteristicMutex = oc_mutex_new();
4775 if (NULL == g_threadWriteCharacteristicMutex)
4777 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4778 return CA_STATUS_FAILED;
4782 if (NULL == g_deviceScanRetryDelayMutex)
4784 g_deviceScanRetryDelayMutex = oc_mutex_new();
4785 if (NULL == g_deviceScanRetryDelayMutex)
4787 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4788 return CA_STATUS_FAILED;
4792 if (NULL == g_threadSendStateMutex)
4794 g_threadSendStateMutex = oc_mutex_new();
4795 if (NULL == g_threadSendStateMutex)
4797 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4798 return CA_STATUS_FAILED;
4802 if (NULL == g_threadScanIntervalMutex)
4804 g_threadScanIntervalMutex = oc_mutex_new();
4805 if (NULL == g_threadScanIntervalMutex)
4807 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4808 return CA_STATUS_FAILED;
4812 if (NULL == g_setValueMutex)
4814 g_setValueMutex = oc_mutex_new();
4815 if (NULL == g_setValueMutex)
4817 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4818 return CA_STATUS_FAILED;
4822 return CA_STATUS_OK;
4825 void CALEClientTerminateGattMutexVariables()
4828 oc_mutex_free(g_bleServerBDAddressMutex);
4829 g_bleServerBDAddressMutex = NULL;
4831 oc_mutex_free(g_threadMutex);
4832 g_threadMutex = NULL;
4834 oc_mutex_free(g_threadSendMutex);
4835 g_threadSendMutex = NULL;
4837 oc_mutex_free(g_deviceListMutex);
4838 g_deviceListMutex = NULL;
4840 oc_mutex_free(g_SendFinishMutex);
4841 g_SendFinishMutex = NULL;
4843 oc_mutex_free(g_threadWriteCharacteristicMutex);
4844 g_threadWriteCharacteristicMutex = NULL;
4846 oc_mutex_free(g_deviceScanRetryDelayMutex);
4847 g_deviceScanRetryDelayMutex = NULL;
4849 oc_mutex_free(g_threadSendStateMutex);
4850 g_threadSendStateMutex = NULL;
4852 oc_mutex_free(g_threadScanIntervalMutex);
4853 g_threadScanIntervalMutex = NULL;
4855 oc_mutex_free(g_gattObjectMutex);
4856 g_gattObjectMutex = NULL;
4858 oc_mutex_free(g_deviceStateListMutex);
4859 g_deviceStateListMutex = NULL;
4861 oc_mutex_free(g_setValueMutex);
4862 g_setValueMutex = NULL;
4865 void CALEClientSetSendFinishFlag(bool flag)
4867 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
4869 oc_mutex_lock(g_SendFinishMutex);
4870 g_isFinishedSendData = flag;
4871 oc_mutex_unlock(g_SendFinishMutex);
4878 CAResult_t CAStartLEGattClient()
4880 // init mutex for send logic
4881 if (!g_deviceDescCond)
4883 g_deviceDescCond = oc_cond_new();
4888 g_threadCond = oc_cond_new();
4891 if (!g_threadWriteCharacteristicCond)
4893 g_threadWriteCharacteristicCond = oc_cond_new();
4896 if (!g_threadScanIntervalCond)
4898 g_threadScanIntervalCond = oc_cond_new();
4901 CAResult_t ret = CALEClientStartScanWithInterval();
4902 if (CA_STATUS_OK != ret)
4904 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
4908 g_isStartedLEClient = true;
4909 return CA_STATUS_OK;
4912 void CAStopLEGattClient()
4914 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
4918 OIC_LOG(ERROR, TAG, "g_jvm is null");
4922 bool isAttached = false;
4924 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
4927 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
4931 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
4937 CAResult_t ret = CALEClientDisconnectAll(env);
4938 if (CA_STATUS_OK != ret)
4940 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
4943 CALEClientStopScanWithInterval();
4945 oc_mutex_lock(g_threadWriteCharacteristicMutex);
4946 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
4947 oc_cond_signal(g_threadWriteCharacteristicCond);
4948 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
4950 CALEClientSetSendFinishFlag(true);
4951 oc_mutex_lock(g_threadMutex);
4952 OIC_LOG(DEBUG, TAG, "signal - g_threadCond cond");
4953 oc_cond_signal(g_threadCond);
4954 oc_mutex_unlock(g_threadMutex);
4956 oc_mutex_lock(g_deviceScanRetryDelayMutex);
4957 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4958 oc_cond_signal(g_deviceScanRetryDelayCond);
4959 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
4961 oc_mutex_lock(g_threadScanIntervalMutex);
4962 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4963 oc_cond_signal(g_threadScanIntervalCond);
4964 oc_mutex_unlock(g_threadScanIntervalMutex);
4966 oc_mutex_lock(g_threadSendMutex);
4967 OIC_LOG(DEBUG, TAG, "signal - g_deviceDesc cond");
4968 oc_cond_signal(g_deviceDescCond);
4969 oc_mutex_unlock(g_threadSendMutex);
4971 oc_cond_free(g_deviceDescCond);
4972 oc_cond_free(g_threadCond);
4973 oc_cond_free(g_threadWriteCharacteristicCond);
4974 oc_cond_free(g_deviceScanRetryDelayCond);
4975 oc_cond_free(g_threadScanIntervalCond);
4977 g_deviceDescCond = NULL;
4978 g_threadCond = NULL;
4979 g_threadWriteCharacteristicCond = NULL;
4980 g_deviceScanRetryDelayCond = NULL;
4981 g_threadScanIntervalCond = NULL;
4985 (*g_jvm)->DetachCurrentThread(g_jvm);
4990 CAResult_t CAInitializeLEGattClient()
4992 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
4993 CALEClientInitialize();
4994 return CA_STATUS_OK;
4997 void CATerminateLEGattClient()
4999 OIC_LOG(INFO, TAG, "IN - Terminate GATT Client");
5000 CAStopLEGattClient();
5001 CALEClientTerminate();
5002 OIC_LOG(INFO, TAG, "OUT - Terminate GATT Client");
5005 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
5006 uint32_t dataLen, CALETransferType_t type,
5009 OIC_LOG(INFO, TAG, "call CALEClientSendUnicastMessage");
5010 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
5012 if (LE_UNICAST != type || position < 0)
5014 OIC_LOG(ERROR, TAG, "this request is not unicast");
5015 return CA_STATUS_INVALID_PARAM;
5018 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
5021 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
5023 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
5024 VERIFY_NON_NULL(data, TAG, "data is null");
5026 return CALEClientSendMulticastMessage(data, dataLen);
5029 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
5032 g_CABLEClientDataReceivedCallback = callback;
5036 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
5038 g_threadPoolHandle = handle;
5041 CAResult_t CAGetLEAddress(char **local_address)
5043 VERIFY_NON_NULL(local_address, TAG, "local_address");
5044 return CA_NOT_SUPPORTED;
5047 JNIEXPORT void JNICALL
5048 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
5051 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
5052 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5053 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5054 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
5056 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
5057 CACheckJNIException(env);
5060 JNIEXPORT void JNICALL
5061 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallbackForV21(JNIEnv *env,
5065 OIC_LOG(DEBUG, TAG, "caLeRegisterLeScanCallbackForV21");
5066 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5067 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5068 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
5070 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
5071 CACheckJNIException(env);
5074 JNIEXPORT void JNICALL
5075 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
5078 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
5079 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5080 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5081 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
5083 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
5084 CACheckJNIException(env);
5087 JNIEXPORT void JNICALL
5088 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
5091 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5092 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5093 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
5095 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
5096 if (CA_STATUS_OK != res)
5098 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
5102 JNIEXPORT void JNICALL
5103 Java_org_iotivity_ca_CaLeClientInterface_caLeScanFailedCallback(JNIEnv *env, jobject obj,
5106 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5107 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5112 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_ALREADY_STARTED");
5117 "BLE scan has failed, error is SCAN_FAILED_APPLICATION_REGISTRATION_FAILED");
5121 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_INTERNAL_ERROR");
5125 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_FEATURE_UNSUPPORTED");
5129 OIC_LOG(ERROR, TAG, "BLE scan has failed with unknown error");
5135 * Class: org_iotivity_ca_jar_caleinterface
5136 * Method: CALeGattConnectionStateChangeCallback
5137 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
5139 JNIEXPORT void JNICALL
5140 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
5146 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
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(gatt, TAG, "gatt is null");
5152 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
5154 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5157 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
5161 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5164 OIC_LOG(ERROR, TAG, "address is null");
5165 CACheckJNIException(env);
5168 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
5170 if (state_connected == newstate)
5172 OIC_LOG(DEBUG, TAG, "LE is connected");
5173 if (GATT_SUCCESS == status)
5175 CAResult_t res = CALEUpdateDeviceState(address,
5176 CA_LE_CONNECTION_STATE,
5179 g_deviceStateListMutex);
5180 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5181 if (CA_STATUS_OK != res)
5183 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5187 res = CALEClientAddGattobjToList(env, gatt);
5188 if (CA_STATUS_OK != res)
5190 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
5194 res = CALEClientDiscoverServices(env, gatt);
5195 if (CA_STATUS_OK != res)
5197 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
5203 OIC_LOG(INFO, TAG, "unknown status");
5204 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5207 else // STATE_DISCONNECTED == newstate
5209 OIC_LOG(DEBUG, TAG, "LE is disconnected");
5211 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SEND_PREPARING,
5212 g_deviceStateList, g_deviceStateListMutex))
5214 OIC_LOG(INFO, TAG, "current state is STATE_SEND_PREPARING");
5215 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5218 g_deviceStateListMutex);
5219 if (CA_STATUS_OK != res)
5221 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5225 CAResult_t res = CALEUpdateDeviceState(address,
5226 CA_LE_CONNECTION_STATE,
5229 g_deviceStateListMutex);
5230 if (CA_STATUS_OK != res)
5232 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5234 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5236 res = CALEClientGattClose(env, gatt);
5237 if (CA_STATUS_OK != res)
5239 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
5242 if (CALECheckConnectionStateValue(status))
5244 // this state is unexpected reason to disconnect
5245 // if the reason is suitable, connection logic of the device will be destroyed.
5246 OIC_LOG(INFO, TAG, "connection logic destroy");
5250 // other reason except for gatt_success is expected to running
5251 // background connection in BT platform.
5252 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
5254 CALEClientUpdateSendCnt(env);
5260 CALEClientSendFinish(env, gatt);
5265 * Class: org_iotivity_ca_jar_caleinterface
5266 * Method: CALeGattServicesDiscoveredCallback
5267 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
5269 JNIEXPORT void JNICALL
5270 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
5275 OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status);
5276 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5277 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5278 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5280 if (GATT_SUCCESS != status) // discovery error
5282 CALEClientSendFinish(env, gatt);
5286 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5289 CALEClientSendFinish(env, gatt);
5293 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5296 CACheckJNIException(env);
5297 CALEClientSendFinish(env, gatt);
5301 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
5304 OIC_LOG(ERROR, TAG, "jni_uuid is null");
5308 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
5309 if (!jni_obj_GattCharacteristic)
5311 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
5315 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
5316 jni_obj_GattCharacteristic);
5317 if (CA_STATUS_OK != res)
5319 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
5323 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
5324 if (CA_STATUS_OK != res)
5326 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
5328 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE,
5329 g_deviceStateList, g_deviceStateListMutex);
5330 if (CA_STATUS_OK != res)
5332 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
5336 res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
5337 STATE_SERVICE_CONNECTED,
5339 g_deviceStateListMutex);
5340 if (CA_STATUS_OK != res)
5342 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5346 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
5347 if (CA_STATUS_OK != res)
5349 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
5355 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE,
5356 g_deviceStateList, g_deviceStateListMutex);
5357 if (CA_STATUS_OK != res)
5359 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
5364 #ifdef SCAN_INTERVAL
5365 // reset interval scan logic
5366 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
5369 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
5370 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5375 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
5376 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5377 CALEClientSendFinish(env, gatt);
5382 * Class: org_iotivity_ca_jar_caleinterface
5383 * Method: CALeGattCharacteristicWritjclasseCallback
5384 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
5386 JNIEXPORT void JNICALL
5387 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
5388 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status)
5390 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
5391 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5392 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5393 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5395 // send success & signal
5396 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5402 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5405 CACheckJNIException(env);
5409 if (GATT_SUCCESS != status) // error case
5411 OIC_LOG(ERROR, TAG, "send failure");
5414 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
5415 if (CA_STATUS_OK != res)
5417 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
5418 oc_mutex_lock(g_threadWriteCharacteristicMutex);
5419 g_isSignalSetFlag = true;
5420 oc_cond_signal(g_threadWriteCharacteristicCond);
5421 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
5423 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5426 g_deviceStateListMutex);
5427 if (CA_STATUS_OK != res)
5429 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5432 if (g_clientErrorCallback)
5434 jint length = (*env)->GetArrayLength(env, data);
5435 CACheckJNIException(env);
5436 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
5437 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, length,
5438 false, "writeChar failure");
5441 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5447 OIC_LOG(DEBUG, TAG, "send success");
5448 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5451 g_deviceStateListMutex);
5452 if (CA_STATUS_OK != res)
5454 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5457 oc_mutex_lock(g_threadWriteCharacteristicMutex);
5458 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
5459 g_isSignalSetFlag = true;
5460 oc_cond_signal(g_threadWriteCharacteristicCond);
5461 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
5463 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0,
5464 (*env)->GetArrayLength(env, data),
5465 true, "writeChar success");
5468 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5474 CALEClientSendFinish(env, gatt);
5479 * Class: org_iotivity_ca_jar_caleinterface
5480 * Method: CALeGattCharacteristicChangedCallback
5481 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
5483 JNIEXPORT void JNICALL
5484 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
5485 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
5487 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
5488 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5489 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5490 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5491 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
5493 // get Byte Array and convert to uint8_t*
5494 jint length = (*env)->GetArrayLength(env, data);
5497 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
5498 CACheckJNIException(env);
5500 uint8_t* receivedData = OICMalloc(length);
5503 OIC_LOG(ERROR, TAG, "receivedData is null");
5507 memcpy(receivedData, jni_byte_responseData, length);
5508 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
5510 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5513 OIC_LOG(ERROR, TAG, "jni_address is null");
5514 OICFree(receivedData);
5518 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5521 OIC_LOG(ERROR, TAG, "address is null");
5522 CACheckJNIException(env);
5523 OICFree(receivedData);
5527 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
5528 receivedData, length);
5530 uint32_t sentLength = 0;
5531 oc_mutex_lock(g_bleServerBDAddressMutex);
5532 g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
5533 oc_mutex_unlock(g_bleServerBDAddressMutex);
5535 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5539 * Class: org_iotivity_ca_jar_caleinterface
5540 * Method: CALeGattDescriptorWriteCallback
5541 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
5543 JNIEXPORT void JNICALL
5544 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
5548 OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status);
5549 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5550 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5551 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5553 if (GATT_SUCCESS != status) // error
5558 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5564 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5567 CACheckJNIException(env);
5571 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
5572 STATE_SERVICE_CONNECTED,
5574 g_deviceStateListMutex);
5575 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5576 if (CA_STATUS_OK != res)
5578 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5582 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
5583 if (CA_STATUS_OK != res)
5585 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
5593 CALEClientSendFinish(env, gatt);
5597 JNIEXPORT void JNICALL
5598 Java_org_iotivity_ca_CaLeClientInterface_caLeGattMtuChangedCallback(JNIEnv *env,
5604 OIC_LOG_V(INFO, TAG, "caLeGattMtuChangedCallback - status %d, "
5605 "mtu[%d-including Header size 3 byte]", status, mtu);
5609 if (0 == status || 133 == status)
5613 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
5614 if (CA_STATUS_OK != res)
5616 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
5621 OIC_LOG(INFO, TAG, "mtu nego is done");
5622 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5625 CALEClientSendFinish(env, gatt);
5629 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5632 CACheckJNIException(env);
5633 (*env)->DeleteLocalRef(env, jni_address);
5634 CALEClientSendFinish(env, gatt);
5639 CAResult_t res = CALESetMtuSize(address, mtu - CA_BLE_MTU_HEADER_SIZE,
5640 g_deviceStateList, g_deviceStateListMutex);
5641 if (CA_STATUS_OK != res)
5643 OIC_LOG(ERROR, TAG, "CALESetMtuSize has failed");
5646 res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5647 STATE_SEND_MTU_NEGO_SUCCESS,
5649 g_deviceStateListMutex);
5650 if (CA_STATUS_OK != res)
5652 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5654 CALEClientUpdateSendCnt(env);
5655 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5656 (*env)->DeleteLocalRef(env, jni_address);