static jboolean discoverServicesNative(JNIEnv *env, jobject object, jstring path, jstring pattern) { LOGV(__FUNCTION__); #ifdef HAVE_BLUETOOTH native_data_t *nat = get_native_data(env, object); jobject eventLoop = env->GetObjectField(object, field_mEventLoop); struct event_loop_native_data_t *eventLoopNat = get_EventLoop_native_data(env, eventLoop); if (nat && eventLoopNat) { const char *c_path = env->GetStringUTFChars(path, NULL); const char *c_pattern = env->GetStringUTFChars(pattern, NULL); int len = env->GetStringLength(path) + 1; char *context_path = (char *)calloc(len, sizeof(char)); strlcpy(context_path, c_path, len); // for callback LOGV("... Object Path = %s", c_path); LOGV("... Pattern = %s, strlen = %d", c_pattern, strlen(c_pattern)); bool ret = dbus_func_args_async(env, nat->conn, -1, onDiscoverServicesResult, context_path, eventLoopNat, c_path, DBUS_DEVICE_IFACE, "DiscoverServices", DBUS_TYPE_STRING, &c_pattern, DBUS_TYPE_INVALID); env->ReleaseStringUTFChars(path, c_path); env->ReleaseStringUTFChars(pattern, c_pattern); return ret ? JNI_TRUE : JNI_FALSE; } #endif return JNI_FALSE; }
static jboolean createDeviceNative(JNIEnv *env, jobject object, jstring address) { LOGV(__FUNCTION__); #ifdef HAVE_BLUETOOTH native_data_t *nat = get_native_data(env, object); jobject eventLoop = env->GetObjectField(object, field_mEventLoop); struct event_loop_native_data_t *eventLoopNat = get_EventLoop_native_data(env, eventLoop); if (nat && eventLoopNat) { const char *c_address = env->GetStringUTFChars(address, NULL); LOGV("... address = %s", c_address); char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char)); strlcpy(context_address, c_address, BTADDR_SIZE); // for callback bool ret = dbus_func_args_async(env, nat->conn, -1, onCreateDeviceResult, context_address, eventLoopNat, get_adapter_path(env, object), DBUS_ADAPTER_IFACE, "CreateDevice", DBUS_TYPE_STRING, &c_address, DBUS_TYPE_INVALID); env->ReleaseStringUTFChars(address, c_address); return ret ? JNI_TRUE : JNI_FALSE; } #endif return JNI_FALSE; }
static jint getDeviceServiceChannelNative(JNIEnv *env, jobject object, jstring path, jstring pattern, jint attr_id) { #ifdef HAVE_BLUETOOTH LOGV(__FUNCTION__); native_data_t *nat = get_native_data(env, object); jobject eventLoop = env->GetObjectField(object, field_mEventLoop); struct event_loop_native_data_t *eventLoopNat = get_EventLoop_native_data(env, eventLoop); if (nat && eventLoopNat) { const char *c_pattern = env->GetStringUTFChars(pattern, NULL); const char *c_path = env->GetStringUTFChars(path, NULL); LOGV("... pattern = %s", c_pattern); LOGV("... attr_id = %#X", attr_id); DBusMessage *reply = dbus_func_args(env, nat->conn, c_path, DBUS_DEVICE_IFACE, "GetServiceAttributeValue", DBUS_TYPE_STRING, &c_pattern, DBUS_TYPE_UINT16, &attr_id, DBUS_TYPE_INVALID); env->ReleaseStringUTFChars(pattern, c_pattern); env->ReleaseStringUTFChars(path, c_path); return reply ? dbus_returns_int32(env, reply) : -1; } #endif return -1; }
static jboolean createPairedDeviceOutOfBandNative(JNIEnv *env, jobject object, jstring address, jint timeout_ms) { LOGV(__FUNCTION__); #ifdef HAVE_BLUETOOTH native_data_t *nat = get_native_data(env, object); jobject eventLoop = env->GetObjectField(object, field_mEventLoop); struct event_loop_native_data_t *eventLoopNat = get_EventLoop_native_data(env, eventLoop); if (nat && eventLoopNat) { const char *c_address = env->GetStringUTFChars(address, NULL); LOGV("... address = %s", c_address); char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char)); const char *capabilities = "DisplayYesNo"; const char *agent_path = "/android/bluetooth/remote_device_agent"; strlcpy(context_address, c_address, BTADDR_SIZE); // for callback bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms, onCreatePairedDeviceResult, // callback context_address, eventLoopNat, get_adapter_path(env, object), DBUS_ADAPTER_IFACE, "CreatePairedDeviceOutOfBand", DBUS_TYPE_STRING, &c_address, DBUS_TYPE_OBJECT_PATH, &agent_path, DBUS_TYPE_STRING, &capabilities, DBUS_TYPE_INVALID); env->ReleaseStringUTFChars(address, c_address); return ret ? JNI_TRUE : JNI_FALSE; } #endif return JNI_FALSE; }
static const char *get_adapter_path(JNIEnv* env, jobject object) { #ifdef HAVE_BLUETOOTH event_loop_native_data_t *event_nat = get_EventLoop_native_data(env, env->GetObjectField(object, field_mEventLoop)); if (event_nat == NULL) return NULL; return event_nat->adapter; #else return NULL; #endif }
// This function is called when the adapter is enabled. static jboolean setupNativeDataNative(JNIEnv* env, jobject object) { LOGV(__FUNCTION__); #ifdef HAVE_BLUETOOTH native_data_t *nat = (native_data_t *)env->GetIntField(object, field_mNativeData); event_loop_native_data_t *event_nat = get_EventLoop_native_data(env, env->GetObjectField(object, field_mEventLoop)); // Register agent for remote devices. const char *device_agent_path = "/android/bluetooth/remote_device_agent"; static const DBusObjectPathVTable agent_vtable = { NULL, agent_event_filter, NULL, NULL, NULL, NULL }; if (!dbus_connection_register_object_path(nat->conn, device_agent_path, &agent_vtable, event_nat)) { LOGE("%s: Can't register object path %s for remote device agent!", __FUNCTION__, device_agent_path); return JNI_FALSE; } #endif /*HAVE_BLUETOOTH*/ return JNI_TRUE; }