summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2006-03-10 21:27:51 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2006-03-10 21:27:51 +0000
commit6508cdb8cd4ecf53c21826a878ec57d0dbb9205c (patch)
tree874e5c61c5894f1b2fa9c2908c4c4b7c503c3975
parent1c37ee6736011106383c591cb387c724b0ff494e (diff)
Break everything
-rw-r--r--hcid/dbus-adapter.c128
-rw-r--r--hcid/dbus-common.c16
-rw-r--r--hcid/dbus-manager.c58
-rw-r--r--hcid/dbus-security.c159
-rw-r--r--hcid/dbus.h8
5 files changed, 255 insertions, 114 deletions
diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c
index 06eb40f6..e1627a6e 100644
--- a/hcid/dbus-adapter.c
+++ b/hcid/dbus-adapter.c
@@ -1310,68 +1310,59 @@ static DBusMessage *handle_dev_discover_service_req(DBusMessage *msg, void *data
}
static const struct service_data dev_services[] = {
- { DEV_GET_ADDRESS, handle_dev_get_address_req, DEV_GET_ADDRESS_SIGNATURE },
- { DEV_GET_VERSION, handle_dev_get_version_req, DEV_GET_VERSION_SIGNATURE },
- { DEV_GET_REVISION, handle_dev_get_revision_req, DEV_GET_REVISION_SIGNATURE },
- { DEV_GET_MANUFACTURER, handle_dev_get_manufacturer_req, DEV_GET_MANUFACTURER_SIGNATURE },
- { DEV_GET_COMPANY, handle_dev_get_company_req, DEV_GET_COMPANY_SIGNATURE },
- { DEV_GET_FEATURES, handle_dev_get_features_req, DEV_GET_FEATURES_SIGNATURE },
- { DEV_GET_MODE, handle_dev_get_mode_req, DEV_GET_MODE_SIGNATURE },
- { DEV_LIST_MINOR_CLASSES, handle_dev_list_minor_classes_req, DEV_LIST_MINOR_CLASSES_SIGNATURE },
- { DEV_SET_MODE, handle_dev_set_mode_req, DEV_SET_MODE_SIGNATURE },
- { DEV_GET_DISCOVERABLE_TO, handle_dev_get_discoverable_to_req, DEV_GET_DISCOVERABLE_TO_SIGNATURE },
- { DEV_SET_DISCOVERABLE_TO, handle_dev_set_discoverable_to_req, DEV_SET_DISCOVERABLE_TO_SIGNATURE },
- { DEV_IS_CONNECTABLE, handle_dev_is_connectable_req, DEV_IS_CONNECTABLE_SIGNATURE },
- { DEV_IS_DISCOVERABLE, handle_dev_is_discoverable_req, DEV_IS_DISCOVERABLE_SIGNATURE },
- { DEV_GET_MAJOR_CLASS, handle_dev_get_major_class_req, DEV_GET_MAJOR_CLASS_SIGNATURE },
- { DEV_GET_MINOR_CLASS, handle_dev_get_minor_class_req, DEV_GET_MINOR_CLASS_SIGNATURE },
- { DEV_SET_MINOR_CLASS, handle_dev_set_minor_class_req, DEV_SET_MINOR_CLASS_SIGNATURE },
- { DEV_GET_SERVICE_CLASSES, handle_dev_get_service_classes_req, DEV_GET_SERVICE_CLASSES_SIGNATURE },
- { DEV_GET_NAME, handle_dev_get_name_req, DEV_GET_NAME_SIGNATURE },
- { DEV_SET_NAME, handle_dev_set_name_req, DEV_SET_NAME_SIGNATURE },
+ { DEV_GET_ADDRESS, handle_dev_get_address_req, },
+ { DEV_GET_VERSION, handle_dev_get_version_req, },
+ { DEV_GET_REVISION, handle_dev_get_revision_req, },
+ { DEV_GET_MANUFACTURER, handle_dev_get_manufacturer_req, },
+ { DEV_GET_COMPANY, handle_dev_get_company_req, },
+ { DEV_GET_FEATURES, handle_dev_get_features_req, },
+ { DEV_GET_MODE, handle_dev_get_mode_req, },
+ { DEV_LIST_MINOR_CLASSES, handle_dev_list_minor_classes_req, },
+ { DEV_SET_MODE, handle_dev_set_mode_req, },
+ { DEV_GET_DISCOVERABLE_TO, handle_dev_get_discoverable_to_req, },
+ { DEV_SET_DISCOVERABLE_TO, handle_dev_set_discoverable_to_req, },
+ { DEV_IS_CONNECTABLE, handle_dev_is_connectable_req, },
+ { DEV_IS_DISCOVERABLE, handle_dev_is_discoverable_req, },
+ { DEV_GET_MAJOR_CLASS, handle_dev_get_major_class_req, },
+ { DEV_GET_MINOR_CLASS, handle_dev_get_minor_class_req, },
+ { DEV_SET_MINOR_CLASS, handle_dev_set_minor_class_req, },
+ { DEV_GET_SERVICE_CLASSES, handle_dev_get_service_classes_req, },
+ { DEV_GET_NAME, handle_dev_get_name_req, },
+ { DEV_SET_NAME, handle_dev_set_name_req, },
- { DEV_GET_REMOTE_VERSION, handle_dev_get_remote_version_req, DEV_GET_REMOTE_VERSION_SIGNATURE },
- { DEV_GET_REMOTE_REVISION, handle_dev_get_remote_revision_req, DEV_GET_REMOTE_REVISION_SIGNATURE },
- { DEV_GET_REMOTE_MANUFACTURER, handle_dev_get_remote_manufacturer_req, DEV_GET_REMOTE_MANUFACTURER_SIGNATURE },
- { DEV_GET_REMOTE_COMPANY, handle_dev_get_remote_company_req, DEV_GET_REMOTE_COMPANY_SIGNATURE },
- { DEV_GET_REMOTE_NAME, handle_dev_get_remote_name_req, DEV_GET_REMOTE_NAME_SIGNATURE },
- { DEV_GET_REMOTE_ALIAS, handle_dev_get_remote_alias_req, DEV_GET_REMOTE_ALIAS_SIGNATURE },
- { DEV_SET_REMOTE_ALIAS, handle_dev_set_remote_alias_req, DEV_SET_REMOTE_ALIAS_SIGNATURE },
-
- { DEV_LAST_SEEN, handle_dev_last_seen_req, DEV_LAST_SEEN_SIGNATURE },
- { DEV_LAST_USED, handle_dev_last_used_req, DEV_LAST_USED_SIGNATURE },
-
- { DEV_CREATE_BONDING, handle_dev_create_bonding_req, DEV_CREATE_BONDING_SIGNATURE },
- { DEV_REMOVE_BONDING, handle_dev_remove_bonding_req, DEV_REMOVE_BONDING_SIGNATURE },
- { DEV_HAS_BONDING_NAME, handle_dev_has_bonding_req, DEV_HAS_BONDING_SIGNATURE },
- { DEV_LIST_BONDINGS, handle_dev_list_bondings_req, DEV_LIST_BONDINGS_SIGNATURE },
- { DEV_GET_PIN_CODE_LENGTH, handle_dev_get_pin_code_length_req, DEV_GET_PIN_CODE_LENGTH_SIGNATURE },
- { DEV_GET_ENCRYPTION_KEY_SIZE, handle_dev_get_encryption_key_size_req, DEV_GET_ENCRYPTION_KEY_SIZE_SIGNATURE },
-
- { DEV_DISCOVER_DEVICES, handle_dev_discover_devices_req, DEV_DISCOVER_DEVICES_SIGNATURE },
- { DEV_CANCEL_DISCOVERY, handle_dev_cancel_discovery_req, DEV_CANCEL_DISCOVERY_SIGNATURE },
- { DEV_DISCOVER_CACHE, handle_dev_discover_cache_req, DEV_DISCOVER_CACHE_SIGNATURE },
- { DEV_DISCOVER_SERVICE, handle_dev_discover_service_req, DEV_DISCOVER_SERVICE_SIGNATURE },
-
- { NULL, NULL, NULL}
+ { DEV_GET_REMOTE_VERSION, handle_dev_get_remote_version_req, },
+ { DEV_GET_REMOTE_REVISION, handle_dev_get_remote_revision_req, },
+ { DEV_GET_REMOTE_MANUFACTURER, handle_dev_get_remote_manufacturer_req, },
+ { DEV_GET_REMOTE_COMPANY, handle_dev_get_remote_company_req, },
+ { DEV_GET_REMOTE_NAME, handle_dev_get_remote_name_req, },
+ { DEV_GET_REMOTE_ALIAS, handle_dev_get_remote_alias_req, },
+ { DEV_SET_REMOTE_ALIAS, handle_dev_set_remote_alias_req, },
+
+ { DEV_LAST_SEEN, handle_dev_last_seen_req, },
+ { DEV_LAST_USED, handle_dev_last_used_req, },
+
+ { DEV_CREATE_BONDING, handle_dev_create_bonding_req, },
+ { DEV_REMOVE_BONDING, handle_dev_remove_bonding_req, },
+ { DEV_HAS_BONDING_NAME, handle_dev_has_bonding_req, },
+ { DEV_LIST_BONDINGS, handle_dev_list_bondings_req, },
+ { DEV_GET_PIN_CODE_LENGTH, handle_dev_get_pin_code_length_req, },
+ { DEV_GET_ENCRYPTION_KEY_SIZE, handle_dev_get_encryption_key_size_req, },
+
+ { DEV_DISCOVER_DEVICES, handle_dev_discover_devices_req, },
+ { DEV_CANCEL_DISCOVERY, handle_dev_cancel_discovery_req, },
+ { DEV_DISCOVER_CACHE, handle_dev_discover_cache_req, },
+ { DEV_DISCOVER_SERVICE, handle_dev_discover_service_req, },
+
+ { NULL, NULL }
};
DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data)
{
- const struct service_data *handlers = dev_services;
- DBusMessage *reply = NULL;
struct hci_dbus_data *dbus_data = data;
- const char *method;
- const char *signature;
const char *iface;
- uint32_t err = BLUEZ_EDBUS_UNKNOWN_METHOD;
- method = dbus_message_get_member(msg);
- signature = dbus_message_get_signature(msg);
iface = dbus_message_get_interface(msg);
- info("Adapter path:%s iface:%s method:%s", dbus_message_get_path(msg), iface, method);
-
if (strcmp(ADAPTER_INTERFACE, iface))
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -1381,33 +1372,22 @@ DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *
goto failed;
}
- /* It's a device path id */
- for (; handlers->name != NULL; handlers++) {
- if (strcmp(handlers->name, method))
- continue;
+ handler = find_service_handler(dev_services, msg);
+ if (!handler)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- if (!strcmp(handlers->signature, signature)) {
- reply = handlers->handler_func(msg, data);
- err = 0;
- break;
- } else {
- /* Set the error, but continue looping incase there is
- * another method with the same name but a different
- * signature */
- err = BLUEZ_EDBUS_WRONG_SIGNATURE;
- continue;
- }
- }
+ return handler(conn, msg, data);
failed:
- if (err)
- reply = bluez_new_failure_msg(msg, err);
+ if (err) {
+ DBusMessage *reply = bluez_new_failure_msg(msg, err);
- if (reply) {
- if (!dbus_connection_send (conn, reply, NULL))
- error("Can't send reply message");
+ if (reply) {
+ if (!dbus_connection_send(conn, reply, NULL))
+ error("Can't send reply message");
- dbus_message_unref(reply);
+ dbus_message_unref(reply);
+ }
}
return DBUS_HANDLER_RESULT_HANDLED;
diff --git a/hcid/dbus-common.c b/hcid/dbus-common.c
index 45cc6246..41a9ce3e 100644
--- a/hcid/dbus-common.c
+++ b/hcid/dbus-common.c
@@ -281,3 +281,19 @@ int name_listener_remove(DBusConnection *connection, const char *name,
return 0;
}
+
+service_hanbdler_func_t *find_service_handler(const service_data *handlers, DBusMessage *msg)
+{
+ struct service_data *current;
+ const char *name, *sig;
+
+ member = dbus_message_get_member(msg);
+
+ for (current = handlers; current->name != NULL; current++) {
+ if (!strcmp(current->name, member))
+ return current->handler_func;
+ }
+
+ return NULL;
+}
+
diff --git a/hcid/dbus-manager.c b/hcid/dbus-manager.c
index ad04f862..ffbdc943 100644
--- a/hcid/dbus-manager.c
+++ b/hcid/dbus-manager.c
@@ -127,53 +127,35 @@ static DBusMessage *handle_mgr_default_device_req(DBusMessage *msg, void *data)
}
static const struct service_data mgr_services[] = {
- { MGR_LIST_ADAPTERS, handle_mgr_list_devices_req, MGR_LIST_ADAPTERS_SIGNATURE },
- { MGR_DEFAULT_ADAPTER, handle_mgr_default_device_req, MGR_DEFAULT_ADAPTER_SIGNATURE },
- { NULL, NULL, NULL }
+ { MGR_LIST_ADAPTERS, handle_mgr_list_devices_req },
+ { MGR_DEFAULT_ADAPTER, handle_mgr_default_device_req },
+ { NULL, NULL }
};
-DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data)
+static DBusHandlerResult handle_manager_method(DBusConnection *conn,
+ DBusMessage *msg, void *data)
{
- const struct service_data *handlers;
- DBusMessage *reply = NULL;
- const char *iface;
- const char *method;
- const char *signature;
- uint32_t err = BLUEZ_EDBUS_UNKNOWN_METHOD;
- DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- iface = dbus_message_get_interface(msg);
- method = dbus_message_get_member(msg);
- signature = dbus_message_get_signature(msg);
+ service_handler_func_t *handler;
- info("Manager path:%s method:%s", dbus_message_get_path(msg), method);
+ handler = find_service_handler(mgr_services, msg);
- if (strcmp(iface, MANAGER_INTERFACE))
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ if (handler)
+ return handler(conn, msg, data);
- for (handlers = mgr_services; handlers->name != NULL; handlers++) {
- if (strcmp(handlers->name, method))
- continue;
-
- if (strcmp(handlers->signature, signature) != 0)
- err = BLUEZ_EDBUS_WRONG_SIGNATURE;
- else {
- reply = handlers->handler_func(msg, data);
- err = 0;
- }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
- ret = DBUS_HANDLER_RESULT_HANDLED;
- }
+DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+ const char *iface;
- if (err)
- reply = bluez_new_failure_msg(msg, err);
+ iface = dbus_message_get_interface(msg);
- if (reply) {
- if (!dbus_connection_send (conn, reply, NULL))
- error("Can't send reply message");
+ if (!strcmp(iface, MANAGER_INTERFACE))
+ return handle_manager_method(conn, msg, data);
- dbus_message_unref(reply);
- }
+ if (!strcmp(iface, SECURITY_INTERFACE))
+ return handle_security_method(conn, msg, data);
- return ret;
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
diff --git a/hcid/dbus-security.c b/hcid/dbus-security.c
index f3bf47c4..eec34272 100644
--- a/hcid/dbus-security.c
+++ b/hcid/dbus-security.c
@@ -27,3 +27,162 @@
#include <stdio.h>
#include <errno.h>
+
+#include <dbus/dbus.h>
+
+#include "dbus.h"
+#include "dbus-error.h"
+#include "dbus-common.h"
+
+static struct passkey_agent *default_agent = NULL;
+
+static const struct service_data sec_services[] = {
+ { "RegisterDefault", register_default_agent },
+ { "UnregisterDefault", unregister_default_agent },
+ { NULL, NULL }
+};
+
+static void default_agent_exited(const char *name, void *data)
+{
+ debug("%s exited without unregistering the default passkey agent", name);
+
+ if (!default_agent || strcmp(name, default_agent->name)) {
+ /* This should never happen (there's a bug in the code if it does */
+ debug("default_agent_exited: mismatch with actual default_agent");
+ return;
+ }
+
+ free(default_agent->path);
+ free(default_agent->name);
+ free(default_agent);
+ default_agent = NULL;
+}
+
+static DBusHandlerResult register_default_agent(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ char *path;
+ DBusMessage *reply;
+
+ if (default_agent) {
+ reply = error_passkey_agent_already_exists(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+ goto done;
+ }
+
+ if (!dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_STRING, &path,
+ DBUS_TYPE_INVALID)) {
+ reply = error_invalid_arguments(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+ goto done;
+ }
+
+ default_agent = malloc(sizeof(struct passkey_agent));
+ if (!default_agent)
+ goto need_memory;
+
+ memset(default_agent, 0, sizeof(struct passkey_agent));
+
+ default_agent->name = strdup(dbus_message_get_sender(msg));
+ if (!default_agent->name)
+ goto need_memory;
+
+ default_agent->path = strdup(path);
+ if (!default_agent->path)
+ goto need_memory;
+
+ reply = dbus_message_new_method_return();
+ if (!reply)
+ goto need_memory;
+
+ name_listener_add(conn, default_agent->name,
+ (name_cb_t)default_agent_exited, NULL);
+
+ info("Default passkey agent (%s, %s) registered",
+ default_agent->name, default_agent->path);
+
+done:
+ dbus_connection_send(conn, reply, NULL);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+
+need_memory:
+ if (default_agent) {
+ if (default_agent->name)
+ free(default_agent->name);
+ if (default_agent->path)
+ free(default_agent->path);
+ free(default_agent);
+ default_agent = NULL;
+ }
+
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+static DBusHandlerResult unregister_default_agent(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ DBusMessage *reply;
+ char *name, *path;
+
+ if (!default_agent) {
+ reply = error_does_not_exist(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+ goto done;
+ }
+
+ if (!dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_STRING, &path,
+ DBUS_TYPE_INVALID)) {
+ reply = error_invalid_arguments(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+ goto done;
+ }
+
+ if (strcmp(name, default_agent->name) || strcmp(path, default_agent->path)) {
+ reply = error_does_not_exist(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+ goto done;
+ }
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+ name_listener_remove(conn, default_agent->name,
+ (name_cb_t)default_agent_exited, NULL);
+
+ info("Default passkey agent (%s, %s) unregistered",
+ default_agent->name, default_agent->path);
+
+ free(default_agent->path);
+ free(default_agent->name);
+ free(default_agent);
+ default_agent = NULL;
+
+done:
+ dbus_connection_send(conn, reply, NULL);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+DBusHandlerResult handle_security_method(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+ service_handler_func_t *handler;
+
+ handler = find_service_handler(sec_services, msg);
+
+ if (handler)
+ return handler(conn, msg, data);
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
diff --git a/hcid/dbus.h b/hcid/dbus.h
index f833a421..3ae122fb 100644
--- a/hcid/dbus.h
+++ b/hcid/dbus.h
@@ -56,12 +56,13 @@
#define MAX_PATH_LENGTH 64
-typedef DBusMessage* (service_handler_func_t) (DBusMessage *, void *);
+typedef DBusMessage* (service_handler_func_t) (DBusConnection *conn,
+ DBusMessage *msg,
+ void *user_data);
struct service_data {
const char *name;
service_handler_func_t *handler_func;
- const char *signature;
};
typedef int (timeout_handler_func_t) (void *data);
@@ -121,6 +122,9 @@ int name_listener_add(DBusConnection *connection, const char *name,
int name_listener_remove(DBusConnection *connection, const char *name,
name_cb_t func, void *user_data);
+DBusHandlerResult handle_security_method(DBusConnection *conn, DBusMessage *msg, void *data);
+
+service_hanbdler_func_t *find_service_handler(service_data *services, DBusMessage *msg);
/*========================================================================
BlueZ D-Bus Manager service definitions "/org/bluez/Manager"