CAResult_t CAManagerConnectGatt(JNIEnv *env, jstring remote_le_address) { VERIFY_NON_NULL(env, TAG, "env"); VERIFY_NON_NULL(remote_le_address, TAG, "remote_le_address"); OIC_LOG(DEBUG, TAG, "IN - CAManagerConnectGatt"); jobject jni_bluetooth = CAManagerGetRemoteDevice(env, remote_le_address); if (!jni_bluetooth) { OIC_LOG(ERROR, TAG, "jni_bluetooth is null"); return CA_STATUS_FAILED; } if (!CAManagerIsDeviceBonded(env, jni_bluetooth)) { OIC_LOG(INFO, TAG, "device is BONDED_NONE"); } // request to connection with AutoConnection Flag OIC_LOG(INFO, TAG, "request to gatt connection for auto connection"); CAResult_t res = CALEClientDirectConnect(env, jni_bluetooth, JNI_TRUE); if (CA_STATUS_OK != res) { OIC_LOG(INFO, TAG, "re-connection will be started"); return res; } // set flag auto connection is requested. CAManagerSetAutoConnectionFlag(env, remote_le_address, true); OIC_LOG(DEBUG, TAG, "OUT - CAManagerConnectGatt"); return CA_STATUS_OK; }
JNIEXPORT void JNICALL Java_org_iotivity_ca_CaLeClientInterface_caManagerLeGattConnectionStateChangeCB( JNIEnv *env, jobject obj, jobject gatt, jint status, jint newState) { OIC_LOG_V(DEBUG, TAG, "caManagerLeGattConnectionStateChangeCB-status(%d), newState(%d)", status, newState); VERIFY_NON_NULL_VOID(env, TAG, "env"); VERIFY_NON_NULL_VOID(obj, TAG, "obj"); VERIFY_NON_NULL_VOID(gatt, TAG, "gatt"); jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED"); jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED"); jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS"); jstring jni_address = CAManagerGetAddressFromGatt(env, gatt); if (!jni_address) { OIC_LOG(ERROR, TAG, "CAManagerGetAddressFromGatt is null"); return; } char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL); if (!address) { OIC_LOG(ERROR, TAG, "address is null"); return; } OIC_LOG_V(INFO, TAG, "connection state : status(%d), addr:(%s), newState(%d)", status, address, newState); if (gatt_success == status && state_connected == newState) // le connected { OIC_LOG(DEBUG, TAG, "LE is connected"); CAResult_t res = CAManagerReadRemoteRssi(env, gatt); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "CAManagerReadRemoteRssi has failed"); (*env)->ReleaseStringUTFChars(env, jni_address, address); return; } } else if (state_disconnected == newState)// le disconnected { if (LINK_LOSS == status || REMOTE_DISCONNECT == status) { OIC_LOG(DEBUG, TAG, "LE is disconnected"); if (g_connStateCB) { OIC_LOG_V(DEBUG, TAG, "LE Disconnected state is %d, %s", newState, address); g_connStateCB(CA_ADAPTER_GATT_BTLE, address, false); OIC_LOG(DEBUG, TAG, "LE Disconnected state callback is called"); } if (!CAManagerIsMatchedACData(env, jni_address)) { OIC_LOG_V(DEBUG, TAG, "this[%s] is not target address for Auto Connection", address); (*env)->ReleaseStringUTFChars(env, jni_address, address); return; } CAManagerSetAutoConnectionFlag(env, jni_address, false); CAResult_t res = CAManagerStartAutoConnection(env, jni_address); if (CA_STATUS_OK != res) { (*env)->ReleaseStringUTFChars(env, jni_address, address); OIC_LOG(ERROR, TAG, "CAManagerStartAutoConnection has failed"); return; } } else if (ACCEPT_TIMEOUT_EXCEPTION == status) { CAManagerProcessRecovery(env, START_RECOVERY); } } (*env)->ReleaseStringUTFChars(env, jni_address, address); (*env)->DeleteLocalRef(env, jni_address); }
/* * Class: org_iotivity_ca_jar_caleinterface * Method: caManagerLeServicesDiscoveredCallback * Signature: (Landroid/bluetooth/BluetoothGatt;I)V */ JNIEXPORT void JNICALL Java_org_iotivity_ca_CaLeClientInterface_caManagerLeServicesDiscoveredCallback(JNIEnv *env, jobject obj, jobject gatt, jint status) { OIC_LOG_V(DEBUG, TAG, "caManagerLeServicesDiscoveredCallback - status %d: ", status); VERIFY_NON_NULL_VOID(env, TAG, "env"); VERIFY_NON_NULL_VOID(obj, TAG, "obj"); VERIFY_NON_NULL_VOID(gatt, TAG, "gatt"); if (GATT_SUCCESS == status) { jstring jni_address = CAManagerGetAddressFromGatt(env, gatt); if (!jni_address) { OIC_LOG(ERROR, TAG, "CAManagerGetAddressFromGatt is null"); return; } char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL); if (!address) { OIC_LOG(ERROR, TAG, "address is null"); return; } OIC_LOG_V(DEBUG, TAG, "ServicesDiscovered device : %s", address); // target address for auto connection will be set in device list. // check set connected address information by user jclass jni_cls_set = (*env)->FindClass(env, "java/util/HashSet"); if (!jni_cls_set) { OIC_LOG(ERROR, TAG, "jni_cls_set is null"); return; } jmethodID jni_mid_iterator = (*env)->GetMethodID(env, jni_cls_set, "iterator", "()Ljava/util/Iterator;"); if (!jni_mid_iterator) { OIC_LOG(ERROR, TAG, "jni_mid_iterator is null"); return; } jobject jni_obj_iter = (*env)->CallObjectMethod(env, g_connectedDeviceSet, jni_mid_iterator); if (!jni_obj_iter) { OIC_LOG(ERROR, TAG, "jni_obj_iter is null"); return; } // Get the Iterator method IDs jclass jni_cls_iterator = (*env)->FindClass(env, "java/util/Iterator"); if (!jni_cls_iterator) { OIC_LOG(ERROR, TAG, "jni_cls_iterator is null"); return; } jmethodID jni_mid_hasNext = (*env)->GetMethodID(env, jni_cls_iterator, "hasNext", "()Z"); if (!jni_mid_hasNext) { OIC_LOG(ERROR, TAG, "jni_mid_hasNext is null"); return; } jmethodID jni_mid_next = (*env)->GetMethodID(env, jni_cls_iterator, "next", "()Ljava/lang/Object;"); if (!jni_mid_next) { OIC_LOG(ERROR, TAG, "jni_mid_next is null"); return; } // Iterate over the entry Set while ((*env)->CallBooleanMethod(env, jni_obj_iter, jni_mid_hasNext)) { jstring jni_str_entry = (jstring)(*env)->CallObjectMethod(env, jni_obj_iter, jni_mid_next); const char* foundAddress = (*env)->GetStringUTFChars(env, jni_str_entry, NULL); if (!foundAddress) { OIC_LOG(ERROR, TAG, "addr is null"); return; } OIC_LOG_V(INFO, TAG, "found last connected address [%s] from SharedPreferences", foundAddress); if (!strcmp(foundAddress, address)) { // if BLE address is matched each other // this address will be added into auto connection list. OIC_LOG(INFO, TAG, "AC list - address will be added into ACData list"); CAManagerAddACData(env, jni_address); CAManagerSetAutoConnectionFlag(env, jni_address, false); // next connection will be requested as JNI_TRUE flag // after first connection CALEClientSetAutoConnectFlag(env, jni_str_entry, JNI_TRUE); } else { OIC_LOG(INFO, TAG, "AC list - device is not matched"); } (*env)->ReleaseStringUTFChars(env, jni_str_entry, foundAddress); (*env)->DeleteLocalRef(env, jni_str_entry); } if (g_connStateCB) { g_connStateCB(CA_ADAPTER_GATT_BTLE, address, true); OIC_LOG(DEBUG, TAG, "LE Connected callback is called"); } (*env)->ReleaseStringUTFChars(env, jni_address, address); (*env)->DeleteLocalRef(env, jni_address); (*env)->DeleteLocalRef(env, jni_cls_set); (*env)->DeleteLocalRef(env, jni_obj_iter); (*env)->DeleteLocalRef(env, jni_cls_iterator); OIC_LOG(INFO, TAG, "ServicesDiscovery is successful"); } else { OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed"); } }
JNIEXPORT void JNICALL Java_org_iotivity_ca_CaLeClientInterface_caManagerAdapterStateChangedCallback( JNIEnv *env, jobject obj, jint state) { OIC_LOG(DEBUG, TAG, "caManagerAdapterStateChangedCallback"); VERIFY_NON_NULL_VOID(env, TAG, "env"); VERIFY_NON_NULL_VOID(obj, TAG, "obj"); jint state_on = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_ON"); jint state_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_OFF"); jint state_turning_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_TURNING_OFF"); if (state_on == state) { OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_on"); if (g_adapterStateCB) { g_adapterStateCB(CA_ADAPTER_GATT_BTLE, true); } // when BT state is on. recovery flag has to be reset. CAManagerSetBTRecovery(false); // find target device for autoconnect size_t length = CAManagerGetACDataLength(); OIC_LOG_V(DEBUG, TAG, "target device : %d", length); for (size_t idx = 0; idx < length; idx++) { jstring leAddress = CAManagerGetLEAddressFromACData(env, idx); if (leAddress) { CAResult_t res = CAManagerStartAutoConnection(env, leAddress); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "CAManagerStartAutoConnection has failed"); return; } } } } else if (state_off == state) { OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_off"); if (g_adapterStateCB) { g_adapterStateCB(CA_ADAPTER_GATT_BTLE, false); } // reset autoconnect flag for all target devices size_t length = CAManagerGetACDataLength(); for (size_t idx = 0; idx < length; idx++) { jstring address = CAManagerGetLEAddressFromACData(env, idx); if (address) { CAManagerSetAutoConnectionFlag(env, address, false); } } // check whether BT recovery is needed or not if (CAManagerIsRecoveryFlagSet()) { CAManagerProcessRecovery(env, STATE_OFF); } } else if (state_turning_off == state) { OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_turning_off"); return; } else { OIC_LOG(INFO, TAG, "AdapterStateChangedCallback state is not available"); return; } }