diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:45 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:45 -0800 |
commit | d83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /core/jni/android_server_BluetoothEventLoop.cpp | |
parent | 076357b8567458d4b6dfdcf839ef751634cd2bfb (diff) | |
download | frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.zip frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.gz frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'core/jni/android_server_BluetoothEventLoop.cpp')
-rw-r--r-- | core/jni/android_server_BluetoothEventLoop.cpp | 821 |
1 files changed, 0 insertions, 821 deletions
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp deleted file mode 100644 index 9100e81..0000000 --- a/core/jni/android_server_BluetoothEventLoop.cpp +++ /dev/null @@ -1,821 +0,0 @@ -/* -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "BluetoothEventLoop.cpp" - -#include "android_bluetooth_common.h" -#include "android_runtime/AndroidRuntime.h" -#include "JNIHelp.h" -#include "jni.h" -#include "utils/Log.h" -#include "utils/misc.h" - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> - -#ifdef HAVE_BLUETOOTH -#include <dbus/dbus.h> -#endif - -namespace android { - -#ifdef HAVE_BLUETOOTH -static jfieldID field_mNativeData; - -static jmethodID method_onModeChanged; -static jmethodID method_onNameChanged; -static jmethodID method_onDiscoveryStarted; -static jmethodID method_onDiscoveryCompleted; -static jmethodID method_onRemoteDeviceFound; -static jmethodID method_onRemoteDeviceDisappeared; -static jmethodID method_onRemoteClassUpdated; -static jmethodID method_onRemoteNameUpdated; -static jmethodID method_onRemoteNameFailed; -static jmethodID method_onRemoteDeviceConnected; -static jmethodID method_onRemoteDeviceDisconnectRequested; -static jmethodID method_onRemoteDeviceDisconnected; -static jmethodID method_onBondingCreated; -static jmethodID method_onBondingRemoved; - -static jmethodID method_onCreateBondingResult; -static jmethodID method_onGetRemoteServiceChannelResult; - -static jmethodID method_onPasskeyAgentRequest; -static jmethodID method_onPasskeyAgentCancel; -static jmethodID method_onAuthAgentAuthorize; -static jmethodID method_onAuthAgentCancel; - -typedef event_loop_native_data_t native_data_t; - -// Only valid during waitForAndDispatchEventNative() -native_data_t *event_loop_nat; - -static inline native_data_t * get_native_data(JNIEnv *env, jobject object) { - return (native_data_t *)(env->GetIntField(object, - field_mNativeData)); -} - -#endif -static void classInitNative(JNIEnv* env, jclass clazz) { - LOGV(__FUNCTION__); - -#ifdef HAVE_BLUETOOTH - method_onModeChanged = env->GetMethodID(clazz, "onModeChanged", "(Ljava/lang/String;)V"); - method_onNameChanged = env->GetMethodID(clazz, "onNameChanged", "(Ljava/lang/String;)V"); - method_onDiscoveryStarted = env->GetMethodID(clazz, "onDiscoveryStarted", "()V"); - method_onDiscoveryCompleted = env->GetMethodID(clazz, "onDiscoveryCompleted", "()V"); - method_onRemoteDeviceFound = env->GetMethodID(clazz, "onRemoteDeviceFound", "(Ljava/lang/String;IS)V"); - method_onRemoteDeviceDisappeared = env->GetMethodID(clazz, "onRemoteDeviceDisappeared", "(Ljava/lang/String;)V"); - method_onRemoteClassUpdated = env->GetMethodID(clazz, "onRemoteClassUpdated", "(Ljava/lang/String;I)V"); - method_onRemoteNameUpdated = env->GetMethodID(clazz, "onRemoteNameUpdated", "(Ljava/lang/String;Ljava/lang/String;)V"); - method_onRemoteNameFailed = env->GetMethodID(clazz, "onRemoteNameFailed", "(Ljava/lang/String;)V"); - method_onRemoteDeviceConnected = env->GetMethodID(clazz, "onRemoteDeviceConnected", "(Ljava/lang/String;)V"); - method_onRemoteDeviceDisconnectRequested = env->GetMethodID(clazz, "onRemoteDeviceDisconnectRequested", "(Ljava/lang/String;)V"); - method_onRemoteDeviceDisconnected = env->GetMethodID(clazz, "onRemoteDeviceDisconnected", "(Ljava/lang/String;)V"); - method_onBondingCreated = env->GetMethodID(clazz, "onBondingCreated", "(Ljava/lang/String;)V"); - method_onBondingRemoved = env->GetMethodID(clazz, "onBondingRemoved", "(Ljava/lang/String;)V"); - - method_onCreateBondingResult = env->GetMethodID(clazz, "onCreateBondingResult", "(Ljava/lang/String;I)V"); - - method_onPasskeyAgentRequest = env->GetMethodID(clazz, "onPasskeyAgentRequest", "(Ljava/lang/String;I)V"); - method_onPasskeyAgentCancel = env->GetMethodID(clazz, "onPasskeyAgentCancel", "(Ljava/lang/String;)V"); - method_onAuthAgentAuthorize = env->GetMethodID(clazz, "onAuthAgentAuthorize", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z"); - method_onAuthAgentCancel = env->GetMethodID(clazz, "onAuthAgentCancel", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); - method_onGetRemoteServiceChannelResult = env->GetMethodID(clazz, "onGetRemoteServiceChannelResult", "(Ljava/lang/String;I)V"); - - field_mNativeData = env->GetFieldID(clazz, "mNativeData", "I"); -#endif -} - -static void initializeNativeDataNative(JNIEnv* env, jobject object) { - LOGV(__FUNCTION__); -#ifdef HAVE_BLUETOOTH - native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t)); - if (NULL == nat) { - LOGE("%s: out of memory!", __FUNCTION__); - return; - } - env->SetIntField(object, field_mNativeData, (jint)nat); - - { - DBusError err; - dbus_error_init(&err); - dbus_threads_init_default(); - nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); - if (dbus_error_is_set(&err)) { - LOGE("%s: Could not get onto the system bus!", __FUNCTION__); - dbus_error_free(&err); - } - } -#endif -} - -static void cleanupNativeDataNative(JNIEnv* env, jobject object) { - LOGV(__FUNCTION__); -#ifdef HAVE_BLUETOOTH - native_data_t *nat = - (native_data_t *)env->GetIntField(object, field_mNativeData); - if (nat) { - free(nat); - } -#endif -} - -#ifdef HAVE_BLUETOOTH -static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg, - void *data); -static DBusHandlerResult agent_event_filter(DBusConnection *conn, - DBusMessage *msg, - void *data); - -static const DBusObjectPathVTable agent_vtable = { - NULL, agent_event_filter, NULL, NULL, NULL, NULL -}; -#endif - -static jboolean setUpEventLoopNative(JNIEnv *env, jobject object) { -#ifdef HAVE_BLUETOOTH - LOGV(__FUNCTION__); - dbus_threads_init_default(); - native_data_t *nat = get_native_data(env, object); - DBusError err; - dbus_error_init(&err); - - if (nat != NULL && nat->conn != NULL) { - // Add a filter for all incoming messages - if (!dbus_connection_add_filter(nat->conn, event_filter, nat, NULL)){ - return JNI_FALSE; - } - - // Set which messages will be processed by this dbus connection - dbus_bus_add_match(nat->conn, - "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'", - &err); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - return JNI_FALSE; - } - dbus_bus_add_match(nat->conn, - "type='signal',interface='org.bluez.audio.Manager'", - &err); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - return JNI_FALSE; - } - dbus_bus_add_match(nat->conn, - "type='signal',interface='org.bluez.audio.Device'", - &err); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - return JNI_FALSE; - } - dbus_bus_add_match(nat->conn, - "type='signal',interface='org.bluez.audio.Sink'", - &err); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - return JNI_FALSE; - } - - // Add an object handler for passkey agent method calls - const char *path = "/android/bluetooth/Agent"; - if (!dbus_connection_register_object_path(nat->conn, path, - &agent_vtable, NULL)) { - LOGE("%s: Can't register object path %s for agent!", - __FUNCTION__, path); - return JNI_FALSE; - } - - // RegisterDefaultPasskeyAgent() will fail until hcid is up, so keep - // trying for 10 seconds. - int attempt; - for (attempt = 0; attempt < 1000; attempt++) { - DBusMessage *reply = dbus_func_args_error(env, nat->conn, &err, - BLUEZ_DBUS_BASE_PATH, - "org.bluez.Security", "RegisterDefaultPasskeyAgent", - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - if (reply) { - // Success - dbus_message_unref(reply); - LOGV("Registered agent on attempt %d of 1000\n", attempt); - break; - } else if (dbus_error_has_name(&err, - "org.freedesktop.DBus.Error.ServiceUnknown")) { - // hcid is still down, retry - dbus_error_free(&err); - usleep(10000); // 10 ms - } else { - // Some other error we weren't expecting - LOG_AND_FREE_DBUS_ERROR(&err); - return JNI_FALSE; - } - } - if (attempt == 1000) { - LOGE("Time-out trying to call RegisterDefaultPasskeyAgent(), " - "is hcid running?"); - return JNI_FALSE; - } - - // Now register the Auth agent - DBusMessage *reply = dbus_func_args_error(env, nat->conn, &err, - BLUEZ_DBUS_BASE_PATH, - "org.bluez.Security", "RegisterDefaultAuthorizationAgent", - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - if (!reply) { - LOG_AND_FREE_DBUS_ERROR(&err); - return JNI_FALSE; - } - - dbus_message_unref(reply); - return JNI_TRUE; - } - -#endif - return JNI_FALSE; -} - -static void tearDownEventLoopNative(JNIEnv *env, jobject object) { - LOGV(__FUNCTION__); -#ifdef HAVE_BLUETOOTH - native_data_t *nat = get_native_data(env, object); - if (nat != NULL && nat->conn != NULL) { - - DBusError err; - dbus_error_init(&err); - - const char *path = "/android/bluetooth/Agent"; - DBusMessage *reply = - dbus_func_args(env, nat->conn, BLUEZ_DBUS_BASE_PATH, - "org.bluez.Security", "UnregisterDefaultPasskeyAgent", - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - if (reply) dbus_message_unref(reply); - - reply = - dbus_func_args(env, nat->conn, BLUEZ_DBUS_BASE_PATH, - "org.bluez.Security", "UnregisterDefaultAuthorizationAgent", - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - if (reply) dbus_message_unref(reply); - - dbus_connection_unregister_object_path(nat->conn, path); - - dbus_bus_remove_match(nat->conn, - "type='signal',interface='org.bluez.audio.Sink'", - &err); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - } - dbus_bus_remove_match(nat->conn, - "type='signal',interface='org.bluez.audio.Device'", - &err); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - } - dbus_bus_remove_match(nat->conn, - "type='signal',interface='org.bluez.audio.Manager'", - &err); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - } - dbus_bus_remove_match(nat->conn, - "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'", - &err); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - } - - dbus_connection_remove_filter(nat->conn, event_filter, nat); - } -#endif -} - -#ifdef HAVE_BLUETOOTH -extern DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env); - -// Called by dbus during WaitForAndDispatchEventNative() -static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg, - void *data) { - native_data_t *nat; - JNIEnv *env; - DBusError err; - - dbus_error_init(&err); - - nat = (native_data_t *)data; - env = nat->env; - if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) { - LOGV("%s: not interested (not a signal).", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - LOGV("%s: Received signal %s:%s from %s", __FUNCTION__, - dbus_message_get_interface(msg), dbus_message_get_member(msg), - dbus_message_get_path(msg)); - - if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "RemoteDeviceFound")) { - char *c_address; - int n_class; - short n_rssi; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_UINT32, &n_class, - DBUS_TYPE_INT16, &n_rssi, - DBUS_TYPE_INVALID)) { - LOGV("... address = %s class = %#X rssi = %hd", c_address, n_class, - n_rssi); - env->CallVoidMethod(nat->me, - method_onRemoteDeviceFound, - env->NewStringUTF(c_address), - (jint)n_class, - (jshort)n_rssi); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "DiscoveryStarted")) { - LOGI("DiscoveryStarted signal received"); - env->CallVoidMethod(nat->me, method_onDiscoveryStarted); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "DiscoveryCompleted")) { - LOGI("DiscoveryCompleted signal received"); - env->CallVoidMethod(nat->me, method_onDiscoveryCompleted); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "RemoteDeviceDisappeared")) { - char *c_address; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_INVALID)) { - LOGV("... address = %s", c_address); - env->CallVoidMethod(nat->me, method_onRemoteDeviceDisappeared, - env->NewStringUTF(c_address)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "RemoteClassUpdated")) { - char *c_address; - int n_class; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_UINT32, &n_class, - DBUS_TYPE_INVALID)) { - LOGV("... address = %s", c_address); - env->CallVoidMethod(nat->me, method_onRemoteClassUpdated, - env->NewStringUTF(c_address), (jint)n_class); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "RemoteNameUpdated")) { - char *c_address; - char *c_name; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_STRING, &c_name, - DBUS_TYPE_INVALID)) { - LOGV("... address = %s, name = %s", c_address, c_name); - env->CallVoidMethod(nat->me, - method_onRemoteNameUpdated, - env->NewStringUTF(c_address), - env->NewStringUTF(c_name)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "RemoteNameFailed")) { - char *c_address; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_INVALID)) { - LOGV("... address = %s", c_address); - env->CallVoidMethod(nat->me, - method_onRemoteNameFailed, - env->NewStringUTF(c_address)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "RemoteDeviceConnected")) { - char *c_address; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_INVALID)) { - LOGV("... address = %s", c_address); - env->CallVoidMethod(nat->me, - method_onRemoteDeviceConnected, - env->NewStringUTF(c_address)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "RemoteDeviceDisconnectRequested")) { - char *c_address; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_INVALID)) { - LOGV("... address = %s", c_address); - env->CallVoidMethod(nat->me, - method_onRemoteDeviceDisconnectRequested, - env->NewStringUTF(c_address)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "RemoteDeviceDisconnected")) { - char *c_address; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_INVALID)) { - LOGV("... address = %s", c_address); - env->CallVoidMethod(nat->me, - method_onRemoteDeviceDisconnected, - env->NewStringUTF(c_address)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "BondingCreated")) { - char *c_address; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_INVALID)) { - LOGV("... address = %s", c_address); - env->CallVoidMethod(nat->me, - method_onBondingCreated, - env->NewStringUTF(c_address)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "BondingRemoved")) { - char *c_address; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_INVALID)) { - LOGV("... address = %s", c_address); - env->CallVoidMethod(nat->me, - method_onBondingRemoved, - env->NewStringUTF(c_address)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "ModeChanged")) { - char *c_mode; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_mode, - DBUS_TYPE_INVALID)) { - LOGV("... mode = %s", c_mode); - env->CallVoidMethod(nat->me, - method_onModeChanged, - env->NewStringUTF(c_mode)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "NameChanged")) { - char *c_name; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_name, - DBUS_TYPE_INVALID)) { - LOGV("... name = %s", c_name); - env->CallVoidMethod(nat->me, - method_onNameChanged, - env->NewStringUTF(c_name)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - return DBUS_HANDLER_RESULT_HANDLED; - } - - return a2dp_event_filter(msg, env); -} - -// Called by dbus during WaitForAndDispatchEventNative() -static DBusHandlerResult agent_event_filter(DBusConnection *conn, - DBusMessage *msg, void *data) { - native_data_t *nat = event_loop_nat; - JNIEnv *env; - - - env = nat->env; - if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_METHOD_CALL) { - LOGV("%s: not interested (not a method call).", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - LOGV("%s: Received method %s:%s", __FUNCTION__, - dbus_message_get_interface(msg), dbus_message_get_member(msg)); - - if (dbus_message_is_method_call(msg, - "org.bluez.PasskeyAgent", "Request")) { - - const char *adapter; - const char *address; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &adapter, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_INVALID)) { - LOGE("%s: Invalid arguments for Request() method", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - LOGV("... address = %s", address); - - dbus_message_ref(msg); // increment refcount because we pass to java - - env->CallVoidMethod(nat->me, method_onPasskeyAgentRequest, - env->NewStringUTF(address), (int)msg); - - return DBUS_HANDLER_RESULT_HANDLED; - - } else if (dbus_message_is_method_call(msg, - "org.bluez.PasskeyAgent", "Cancel")) { - - const char *adapter; - const char *address; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &adapter, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_INVALID)) { - LOGE("%s: Invalid arguments for Cancel() method", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - LOGV("... address = %s", address); - - env->CallVoidMethod(nat->me, method_onPasskeyAgentCancel, - env->NewStringUTF(address)); - - // reply - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) { - LOGE("%s: Cannot create message reply\n", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - dbus_connection_send(nat->conn, reply, NULL); - dbus_message_unref(reply); - return DBUS_HANDLER_RESULT_HANDLED; - - } else if (dbus_message_is_method_call(msg, - "org.bluez.PasskeyAgent", "Release")) { - LOGW("We are no longer the passkey agent!"); - - // reply - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) { - LOGE("%s: Cannot create message reply\n", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - dbus_connection_send(nat->conn, reply, NULL); - dbus_message_unref(reply); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_method_call(msg, - "org.bluez.AuthorizationAgent", "Authorize")) { - const char *adapter; - const char *address; - const char *service; - const char *uuid; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &adapter, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_STRING, &service, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID)) { - LOGE("%s: Invalid arguments for Authorize() method", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - LOGV("... address = %s", address); - LOGV("... service = %s", service); - LOGV("... uuid = %s", uuid); - - bool auth_granted = env->CallBooleanMethod(nat->me, - method_onAuthAgentAuthorize, env->NewStringUTF(address), - env->NewStringUTF(service), env->NewStringUTF(uuid)); - - // reply - if (auth_granted) { - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) { - LOGE("%s: Cannot create message reply\n", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - dbus_connection_send(nat->conn, reply, NULL); - dbus_message_unref(reply); - } else { - DBusMessage *reply = dbus_message_new_error(msg, - "org.bluez.Error.Rejected", "Authorization rejected"); - if (!reply) { - LOGE("%s: Cannot create message reply\n", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - dbus_connection_send(nat->conn, reply, NULL); - dbus_message_unref(reply); - } - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_method_call(msg, - "org.bluez.AuthorizationAgent", "Cancel")) { - const char *adapter; - const char *address; - const char *service; - const char *uuid; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &adapter, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_STRING, &service, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID)) { - LOGE("%s: Invalid arguments for Cancel() method", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - LOGV("... address = %s", address); - LOGV("... service = %s", service); - LOGV("... uuid = %s", uuid); - - env->CallVoidMethod(nat->me, - method_onAuthAgentCancel, env->NewStringUTF(address), - env->NewStringUTF(service), env->NewStringUTF(uuid)); - - // reply - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) { - LOGE("%s: Cannot create message reply\n", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - dbus_connection_send(nat->conn, reply, NULL); - dbus_message_unref(reply); - return DBUS_HANDLER_RESULT_HANDLED; - - } else if (dbus_message_is_method_call(msg, - "org.bluez.AuthorizationAgent", "Release")) { - LOGW("We are no longer the auth agent!"); - - // reply - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) { - LOGE("%s: Cannot create message reply\n", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - dbus_connection_send(nat->conn, reply, NULL); - dbus_message_unref(reply); - return DBUS_HANDLER_RESULT_HANDLED; - } else { - LOGV("... ignored"); - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} -#endif - -static jboolean waitForAndDispatchEventNative(JNIEnv *env, jobject object, - jint timeout_ms) { -#ifdef HAVE_BLUETOOTH - //LOGV("%s: %8d (pid %d tid %d)",__FUNCTION__, time(NULL), getpid(), gettid()); // too chatty - native_data_t *nat = get_native_data(env, object); - if (nat != NULL && nat->conn != NULL) { - jboolean ret; - nat->me = object; - nat->env = env; - event_loop_nat = nat; - ret = dbus_connection_read_write_dispatch_greedy(nat->conn, - timeout_ms) == TRUE ? - JNI_TRUE : JNI_FALSE; - event_loop_nat = NULL; - nat->me = NULL; - nat->env = NULL; - return ret; - } -#endif - return JNI_FALSE; -} - -#ifdef HAVE_BLUETOOTH -//TODO: Unify result codes in a header -#define BOND_RESULT_ERROR -1000 -#define BOND_RESULT_SUCCESS 0 -#define BOND_RESULT_AUTH_FAILED 1 -#define BOND_RESULT_AUTH_REJECTED 2 -#define BOND_RESULT_AUTH_CANCELED 3 -#define BOND_RESULT_REMOTE_DEVICE_DOWN 4 -void onCreateBondingResult(DBusMessage *msg, void *user) { - LOGV(__FUNCTION__); - - const char *address = (const char *)user; - DBusError err; - dbus_error_init(&err); - JNIEnv *env = event_loop_nat->env; - - LOGV("... address = %s", address); - - jint result = BOND_RESULT_SUCCESS; - if (dbus_set_error_from_message(&err, msg)) { - if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) { - // Pins did not match, or remote device did not respond to pin - // request in time - LOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_AUTH_FAILED; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationRejected")) { - // We rejected pairing, or the remote side rejected pairing. This - // happens if either side presses 'cancel' at the pairing dialog. - LOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_AUTH_REJECTED; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationCanceled")) { - // Not sure if this happens - LOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_AUTH_CANCELED; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.ConnectionAttemptFailed")) { - // Other device is not responding at all - LOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_REMOTE_DEVICE_DOWN; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AlreadyExists")) { - // already bonded - LOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_SUCCESS; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress")) { - // don't make the java callback - LOGV("... error = %s (%s)\n", err.name, err.message); - goto done; - } else { - LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message); - result = BOND_RESULT_ERROR; - } - } - - env->CallVoidMethod(event_loop_nat->me, - method_onCreateBondingResult, - env->NewStringUTF(address), - result); -done: - dbus_error_free(&err); - free(user); -} - -void onGetRemoteServiceChannelResult(DBusMessage *msg, void *user) { - LOGV(__FUNCTION__); - - const char *address = (const char *) user; - DBusError err; - dbus_error_init(&err); - JNIEnv *env = event_loop_nat->env; - jint channel = -2; - - LOGV("... address = %s", address); - - if (dbus_set_error_from_message(&err, msg) || - !dbus_message_get_args(msg, &err, - DBUS_TYPE_INT32, &channel, - DBUS_TYPE_INVALID)) { - /* if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) */ - LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message); - dbus_error_free(&err); - } - -done: - env->CallVoidMethod(event_loop_nat->me, - method_onGetRemoteServiceChannelResult, - env->NewStringUTF(address), - channel); - free(user); -} -#endif - -static JNINativeMethod sMethods[] = { - /* name, signature, funcPtr */ - {"classInitNative", "()V", (void *)classInitNative}, - {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative}, - {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative}, - {"setUpEventLoopNative", "()Z", (void *)setUpEventLoopNative}, - {"tearDownEventLoopNative", "()V", (void *)tearDownEventLoopNative}, - {"waitForAndDispatchEventNative", "(I)Z", (void *)waitForAndDispatchEventNative} -}; - -int register_android_server_BluetoothEventLoop(JNIEnv *env) { - return AndroidRuntime::registerNativeMethods(env, - "android/server/BluetoothEventLoop", sMethods, NELEM(sMethods)); -} - -} /* namespace android */ |