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 ******************************************************************/
23 #include <android/log.h>
25 #include "calenwmonitor.h"
26 #include "caleclient.h"
27 #include "caleserver.h"
28 #include "caleutils.h"
29 #include "caleinterface.h"
30 #include "caadapterutils.h"
34 #include "org_iotivity_ca_CaLeClientInterface.h"
35 #include "org_iotivity_ca_CaLeServerInterface.h"
37 #define TAG PCF("OIC_CA_LE_MONITOR")
39 static const jint CONNECTION_FAILED_TO_BE_EASTABLISHED = 62;
44 * @var g_bleDeviceStateChangedCallback
45 * @brief Maintains the callback to be notified on device state changed.
47 static CALEDeviceStateChangedCallback g_bleDeviceStateChangedCallback = NULL;
50 * @var g_bleConnectionStateChangedCallback
51 * @brief Maintains the callback to be notified on device state changed.
53 static CALEConnectionStateChangedCallback g_bleConnectionStateChangedCallback = NULL;
56 * @var g_bleDeviceStateChangedCbMutex
57 * @brief Mutex to synchronize access to the deviceStateChanged Callback when the state
58 * of the LE adapter gets change.
60 static oc_mutex g_bleDeviceStateChangedCbMutex = NULL;
63 * @var g_bleConnectionStateChangedCbMutex
64 * @brief Mutex to synchronize access to the LE ConnectionStateChanged Callback when the state
65 * of the LE adapter gets change.
67 static oc_mutex g_bleConnectionStateChangedCbMutex = NULL;
70 void CALENetworkMonitorJNISetContext()
72 OIC_LOG(DEBUG, TAG, "CALENetworkMonitorJNISetContext - it is not supported");
76 void CALENetworkMonitorJniInit()
78 OIC_LOG(DEBUG, TAG, "CALENetworkMonitorJniInit");
79 g_jvm = CANativeJNIGetJavaVM();
82 void CALESetAdapterStateCallback(CALEDeviceStateChangedCallback callback)
84 OIC_LOG(DEBUG, TAG, "CALESetAdapterStateCallback");
85 g_bleDeviceStateChangedCallback = callback;
88 CAResult_t CAInitializeLEAdapter()
95 CAResult_t CAStartLEAdapter()
102 CAResult_t CAStopLEAdapter()
109 CAResult_t CAInitLENwkMonitorMutexVaraibles()
111 OIC_LOG(DEBUG, TAG, "IN");
112 if (NULL == g_bleDeviceStateChangedCbMutex)
114 g_bleDeviceStateChangedCbMutex = oc_mutex_new();
115 if (NULL == g_bleDeviceStateChangedCbMutex)
117 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
118 return CA_STATUS_FAILED;
122 if (NULL == g_bleConnectionStateChangedCbMutex)
124 g_bleConnectionStateChangedCbMutex = oc_mutex_new();
125 if (NULL == g_bleConnectionStateChangedCbMutex)
127 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
128 oc_mutex_free(g_bleDeviceStateChangedCbMutex);
129 return CA_STATUS_FAILED;
133 OIC_LOG(DEBUG, TAG, "OUT");
137 void CATerminateLENwkMonitorMutexVaraibles()
139 OIC_LOG(DEBUG, TAG, "IN");
141 oc_mutex_free(g_bleDeviceStateChangedCbMutex);
142 g_bleDeviceStateChangedCbMutex = NULL;
144 oc_mutex_free(g_bleConnectionStateChangedCbMutex);
145 g_bleConnectionStateChangedCbMutex = NULL;
147 OIC_LOG(DEBUG, TAG, "OUT");
150 CAResult_t CAGetLEAdapterState()
152 OIC_LOG(DEBUG, TAG, "IN");
156 OIC_LOG(ERROR, TAG, "g_jvm is null");
157 return CA_STATUS_FAILED;
160 bool isAttached = false;
162 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
165 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
166 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
170 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
171 return CA_STATUS_FAILED;
176 if (!CALEIsEnableBTAdapter(env))
178 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
181 (*g_jvm)->DetachCurrentThread(g_jvm);
183 return CA_ADAPTER_NOT_ENABLED;
188 (*g_jvm)->DetachCurrentThread(g_jvm);
191 OIC_LOG(DEBUG, TAG, "OUT");
195 CAResult_t CAInitializeLENetworkMonitor()
197 OIC_LOG(DEBUG, TAG, "IN");
199 CAResult_t res = CAInitLENwkMonitorMutexVaraibles();
200 if (CA_STATUS_OK != res)
202 OIC_LOG(ERROR, TAG, "CAInitLENwkMonitorMutexVaraibles has failed");
203 return CA_STATUS_FAILED;
206 CALENetworkMonitorJNISetContext();
207 CALENetworkMonitorJniInit();
209 OIC_LOG(DEBUG, TAG, "OUT");
215 void CATerminateLENetworkMonitor()
217 OIC_LOG(DEBUG, TAG, "IN");
219 CATerminateLENwkMonitorMutexVaraibles();
221 OIC_LOG(DEBUG, TAG, "OUT");
224 CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
226 OIC_LOG(DEBUG, TAG, "IN");
228 OIC_LOG(DEBUG, TAG, "Setting CALEDeviceStateChangedCallback");
230 oc_mutex_lock(g_bleDeviceStateChangedCbMutex);
231 CALESetAdapterStateCallback(callback);
232 oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
234 OIC_LOG(DEBUG, TAG, "OUT");
238 CAResult_t CAUnSetLEAdapterStateChangedCb()
240 OIC_LOG(DEBUG, TAG, "it is not required in this platform");
244 CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback callback)
246 OIC_LOG(DEBUG, TAG, "IN");
247 oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
248 g_bleConnectionStateChangedCallback = callback;
249 oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
250 OIC_LOG(DEBUG, TAG, "OUT");
254 CAResult_t CAUnsetLENWConnectionStateChangedCb()
256 OIC_LOG(DEBUG, TAG, "IN");
257 oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
258 g_bleConnectionStateChangedCallback = NULL;
259 oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
260 OIC_LOG(DEBUG, TAG, "OUT");
264 static CAResult_t CALEStateConnectedCallback(JNIEnv *env, jstring jni_address,
265 jboolean isDescriptorFound)
267 VERIFY_NON_NULL(env, TAG, "env");
268 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
270 if (CALEClientGetFlagFromState(env, jni_address, CA_LE_DESCRIPTOR_FOUND) == isDescriptorFound)
272 if (g_bleConnectionStateChangedCallback)
274 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
277 OIC_LOG(ERROR, TAG, "address is null");
278 CACheckJNIException(env);
279 return CA_STATUS_FAILED;
282 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, true);
283 OIC_LOG(DEBUG, TAG, "BLE is connected");
285 (*env)->ReleaseStringUTFChars(env, jni_address, address);
292 JNIEXPORT void JNICALL
293 Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, jobject obj,
296 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
297 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
299 OIC_LOG_V(DEBUG, TAG, "CaLeClientInterface - Network State Changed : status(%d)", status);
301 if (!g_bleDeviceStateChangedCallback)
303 OIC_LOG(ERROR, TAG, "gNetworkChangeCb is null");
307 jint state_on = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_ON");
308 jint state_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_OFF");
309 jint state_turning_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_TURNING_OFF");
311 if (state_on == status) // STATE_ON:12
313 CANetworkStatus_t newStatus = CA_INTERFACE_UP;
314 CALEClientCreateDeviceList();
316 if (!(caglobals.bleFlags & CA_LE_SERVER_DISABLE))
318 CALEServerCreateCachedDeviceList();
321 g_bleDeviceStateChangedCallback(newStatus);
323 else if (state_turning_off == status) // BT_STATE_TURNING_OFF:13
325 // gatt Device list will be removed.
326 // so it is need to create list again when adapter is enabled.
327 CAStopLEGattClient();
329 else if (state_off == status) // STATE_OFF:10
331 // remove obj for client
332 CAResult_t res = CALEClientRemoveAllGattObjs(env);
333 if (CA_STATUS_OK != res)
335 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
338 res = CALEClientResetDeviceStateForAll();
339 if (CA_STATUS_OK != res)
341 OIC_LOG(ERROR, TAG, "CALEClientResetDeviceStateForAll has failed");
344 // remove obj for server
345 res = CALEServerRemoveAllDevices(env);
346 if (CA_STATUS_OK != res)
348 OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
351 CANetworkStatus_t newStatus = CA_INTERFACE_DOWN;
352 g_bleDeviceStateChangedCallback(newStatus);
356 JNIEXPORT void JNICALL
357 Java_org_iotivity_ca_CaLeClientInterface_caLeBondStateChangedCallback(JNIEnv *env, jobject obj,
360 OIC_LOG(DEBUG, TAG, "CaLeClientInterface - Bond State Changed");
361 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
362 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
363 VERIFY_NON_NULL_VOID(jaddr, TAG, "jaddr is null");
365 // geneally 'addr' parameter will be not ble address, if you didn't bond for BLE.
366 // below logics will be needed when ble pairing is set.
368 CAResult_t res = CALEClientDisconnectforAddress(env, jaddr);
369 if (CA_STATUS_OK != res)
371 OIC_LOG(ERROR, TAG, "CALEClientDisconnectforAddress has failed");
374 // remove obj for client
375 res = CALEClientRemoveGattObjForAddr(env, jaddr);
376 if (CA_STATUS_OK != res)
378 OIC_LOG(ERROR, TAG, "CANativeRemoveGattObjForAddr has failed");
381 res = CALEClientRemoveDeviceInScanDeviceList(env, jaddr);
382 if (CA_STATUS_OK != res)
384 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceInScanDeviceList has failed");
387 // remove obej for server
388 res = CALEServerRemoveDevice(env, jaddr);
389 if (CA_STATUS_OK != res)
391 OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
395 JNIEXPORT void JNICALL
396 Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWConnectionStateChangeCallback(JNIEnv *env,
402 OIC_LOG_V(DEBUG, TAG, "CALeGattNWConnectionStateChangeCallback - status %d, newstate %d",
404 VERIFY_NON_NULL_VOID(env, TAG, "env");
405 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
406 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
408 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE,
409 "STATE_DISCONNECTED");
410 if (state_disconnected == newState)
412 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
415 OIC_LOG(ERROR, TAG, "jni_address is null");
419 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
422 OIC_LOG(ERROR, TAG, "address is null");
423 CACheckJNIException(env);
427 if (CONNECTION_FAILED_TO_BE_EASTABLISHED != status)
429 if (g_bleConnectionStateChangedCallback)
431 OIC_LOG_V(DEBUG, TAG, "LE Disconnected state is %d, %s", newState, address);
432 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, false);
436 (*env)->ReleaseStringUTFChars(env, jni_address, address);
440 JNIEXPORT void JNICALL
441 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNWConnectionStateChangeCallback(
442 JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
444 OIC_LOG_V(DEBUG, TAG, "caLeGattServerNWConnectionStateChangeCallback - status %d, newstate %d",
446 VERIFY_NON_NULL_VOID(env, TAG, "env");
447 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
448 VERIFY_NON_NULL_VOID(device, TAG, "device");
450 if (CONNECTION_FAILED_TO_BE_EASTABLISHED != status)
452 if (g_bleConnectionStateChangedCallback)
454 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
455 if (!jni_remoteAddress)
457 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
461 const char* address = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
464 OIC_LOG(ERROR, TAG, "address is null");
465 CACheckJNIException(env);
469 // STATE_DISCONNECTED
470 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE,
471 "STATE_DISCONNECTED");
474 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE,
477 if (state_disconnected == newState)
479 OIC_LOG_V(DEBUG, TAG, "LE Disconnected state is %d, %s", newState, address);
480 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, false);
482 else if (state_connected == newState)
484 OIC_LOG_V(DEBUG, TAG, "LE Connected state is %d, %s", newState, address);
485 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, true);
489 OIC_LOG_V(DEBUG, TAG, "Unknown state : %d, %s", newState, address);
492 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, address);
497 JNIEXPORT void JNICALL
498 Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWServicesDiscoveredCallback(JNIEnv *env,
503 OIC_LOG_V(DEBUG, TAG, "caLeGattNWServicesDiscoveredCallback - status %d", status);
504 VERIFY_NON_NULL_VOID(env, TAG, "env");
505 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
506 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
508 if (GATT_SUCCESS == status)
510 jstring jni_address = CALEGetAddressFromGatt(env, gatt);
513 OIC_LOG(ERROR, TAG, "jni_address is null");
517 if (CA_STATUS_OK != CALEStateConnectedCallback(env, jni_address, JNI_FALSE))
519 OIC_LOG(ERROR, TAG, "CALEStateConnectedCallback has failed");
522 (*env)->DeleteLocalRef(env, jni_address);
526 JNIEXPORT void JNICALL
527 Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWDescriptorWriteCallback(JNIEnv *env,
532 OIC_LOG_V(DEBUG, TAG, "caLeGattNWDescriptorWriteCallback - status %d", status);
533 VERIFY_NON_NULL_VOID(env, TAG, "env");
534 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
535 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
537 if (GATT_SUCCESS == status)
539 jstring jni_address = CALEGetAddressFromGatt(env, gatt);
542 OIC_LOG(ERROR, TAG, "jni_address is null");
546 if (CA_STATUS_OK != CALEStateConnectedCallback(env, jni_address, JNI_TRUE))
548 OIC_LOG(ERROR, TAG, "CALEStateConnectedCallback has failed");
551 (*env)->DeleteLocalRef(env, jni_address);