diff options
Diffstat (limited to 'serial')
-rw-r--r-- | serial/manager.c | 280 |
1 files changed, 21 insertions, 259 deletions
diff --git a/serial/manager.c b/serial/manager.c index 4f7efdb4..fb4aaf5e 100644 --- a/serial/manager.c +++ b/serial/manager.c @@ -36,48 +36,13 @@ #include "manager.h" -#define SERIAL_MANAGER_PATH "/org/bluez/serial" -#define SERIAL_PORT_PATH "/org/bluez/serial/port" -#define SERIAL_MANAGER_INTERFACE "org.bluez.serial.Manager" -#define SERIAL_PORT_INTERFACE "org.bluez.serial.Port" -#define SERIAL_ERROR_INTERFACE "org.bluez.serial.Error" +#define SERIAL_MANAGER_PATH "/org/bluez/serial" +#define SERIAL_MANAGER_INTERFACE "org.bluez.serial.Manager" +#define SERIAL_ERROR_INTERFACE "org.bluez.serial.Error" #define PATH_LENGTH 32 static DBusConnection *connection = NULL; -static GSList *port_paths = NULL; -static unsigned int next_id = 0; - -struct serial_port { - char *owner; - int16_t id; /* Device id */ -}; - -static void serial_port_free(struct serial_port *sp) -{ - if (!sp) - return; - if (sp->owner) - g_free(sp->owner); - g_free(sp); -} - -static DBusHandlerResult err_does_not_exist(DBusConnection *conn, - DBusMessage *msg) -{ - return send_message_and_unref(conn, - dbus_message_new_error(msg, - SERIAL_ERROR_INTERFACE ".DoesNotExist", - "Port doesn't exist")); -} - -static DBusHandlerResult err_failed(DBusConnection *conn, - DBusMessage *msg, const char *str) -{ - return send_message_and_unref(conn, - dbus_message_new_error(msg, - SERIAL_ERROR_INTERFACE ".Failed", str)); -} static DBusHandlerResult err_invalid_args(DBusConnection *conn, DBusMessage *msg, const char *str) @@ -87,140 +52,15 @@ static DBusHandlerResult err_invalid_args(DBusConnection *conn, SERIAL_ERROR_INTERFACE ".InvalidArguments", str)); } -static DBusHandlerResult err_unknown_port(DBusConnection *conn, - DBusMessage *msg) -{ - return send_message_and_unref(conn, - dbus_message_new_error(msg, - SERIAL_ERROR_INTERFACE ".UnknownPort", - "Unknown port path")); -} - -static DBusHandlerResult port_connect(DBusConnection *conn, +static DBusHandlerResult connect_service(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult port_disconnect(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult port_message(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - const char *iface, *member; - - iface = dbus_message_get_interface(msg); - member = dbus_message_get_member(msg); - - /* Accept messages from the port interface only */ - if (strcmp(SERIAL_PORT_INTERFACE, iface)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (strcmp(member, "Connect") == 0) - return port_connect(conn, msg, data); - - if (strcmp(member, "Disconnect") == 0) - return port_disconnect(conn, msg, data); - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static void port_handler_unregister(DBusConnection *conn, void *data) -{ - /* FIXME: Disconnect if applied */ - serial_port_free(data); -} - -/* Virtual table to handle port object path hierarchy */ -static const DBusObjectPathVTable port_table = { - .message_function = port_message, - .unregister_function = port_handler_unregister, -}; - -static int port_register(DBusConnection *conn, - const char *path, const char *owner) -{ - struct serial_port *sp; - DBusMessage *signal; - - if (!conn || !owner) - return -EINVAL; - - sp = g_new0(struct serial_port, 1); - - /* FIXME: Create the RFCOMM device node */ - sp->id = -1; - sp->owner = g_strdup(owner); - - /* Register path */ - if (!dbus_connection_register_object_path(conn, path, - &port_table, sp)) { - serial_port_free(sp); - return -1; - } - - signal = dbus_message_new_signal(SERIAL_MANAGER_PATH, - SERIAL_MANAGER_INTERFACE, "PortCreated"); - - dbus_message_append_args(signal, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - send_message_and_unref(conn, signal); - - info("Registered serial port path:%s", path); - - return 0; -} - -static int port_unregister(DBusConnection *conn, - const char *path, const char *owner) -{ - struct serial_port *sp; - DBusMessage *signal; - - if (!conn || !owner) - return -EINVAL; - - if (!dbus_connection_get_object_path_data(conn, path, (void *) &sp) || !sp) - return -ENOENT; - - if (strcmp(sp->owner, owner) != 0) - return -EACCES; - - /* FIXME: If it is connected return EPERM or disconnect */ - - dbus_connection_unregister_object_path(conn, path); - - signal = dbus_message_new_signal(SERIAL_MANAGER_PATH, - SERIAL_MANAGER_INTERFACE, "PortRemoved"); - - dbus_message_append_args(signal, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - send_message_and_unref(conn, signal); - - info("Unregistered serial port path:%s", path); - - return 0; -} - -static DBusHandlerResult create_port(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - char port_path[PATH_LENGTH]; DBusMessage *reply; DBusError derr; const char *addr; const char *pattern; - const char *ppath = port_path; - /* FIXME: Check if it already exist */ + /* FIXME: Check if it already exist or if there is pending connect */ dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -232,7 +72,7 @@ static DBusHandlerResult create_port(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - /* Pattern can be a service or a channel */ + /* Pattern can be a UUID128, handle or a channel */ /* FIXME: Missing SDP search */ @@ -240,125 +80,48 @@ static DBusHandlerResult create_port(DBusConnection *conn, if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - snprintf(port_path, PATH_LENGTH, SERIAL_PORT_PATH"%d", next_id++); - - if (port_register(conn, port_path, dbus_message_get_sender(msg)) < 0) { - dbus_message_unref(reply); - return err_failed(conn, msg, "D-Bus path registration failed"); - } - - port_paths = g_slist_append(port_paths, g_strdup(port_path)); - - dbus_message_append_args(reply, - DBUS_TYPE_STRING, &ppath, - DBUS_TYPE_INVALID); - return send_message_and_unref(conn, reply); } -static DBusHandlerResult remove_port(DBusConnection *conn, +static DBusHandlerResult disconnect_service(DBusConnection *conn, DBusMessage *msg, void *data) { - DBusMessage *reply; - DBusError derr; - const char *path; - GSList *l; - int err; - - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID)) { - err_invalid_args(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } - - l = g_slist_find_custom(port_paths, path, (GCompareFunc) strcmp); - if (!l) - return err_does_not_exist(conn, msg); - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - err = port_unregister(conn, path, dbus_message_get_sender(msg)); - if (err < 0) { - dbus_message_unref(reply); - return err_failed(conn, msg, strerror(-err)); - } - - g_free(l->data); - port_paths = g_slist_remove(port_paths, l->data); - - return send_message_and_unref(conn, reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static DBusHandlerResult list_ports(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusHandlerResult cancel_connect_service(DBusConnection *conn, + DBusMessage *msg, void *data) { - DBusMessage *reply; - DBusMessageIter iter; - DBusMessageIter array_iter; - GSList *l; - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, - DBUS_TYPE_STRING_AS_STRING, &array_iter); - - for (l = port_paths; l; l= l->next) { - dbus_message_iter_append_basic(&array_iter, - DBUS_TYPE_STRING, &l->data); - } - - dbus_message_iter_close_container(&iter, &array_iter); - - return send_message_and_unref(conn, reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } static DBusHandlerResult manager_message(DBusConnection *conn, - DBusMessage *msg, void *data) + DBusMessage *msg, void *data) { - const char *path, *iface, *member; + const char *iface, *member; - path = dbus_message_get_path(msg); iface = dbus_message_get_interface(msg); member = dbus_message_get_member(msg); - /* Catching fallback paths */ - if (strcmp(SERIAL_MANAGER_PATH, path) != 0) - return err_unknown_port(conn, msg); - /* Accept messages from the manager interface only */ if (strcmp(SERIAL_MANAGER_INTERFACE, iface)) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - if (strcmp(member, "CreatePort") == 0) - return create_port(conn, msg, data); + if (strcmp(member, "ConnectService") == 0) + return connect_service(conn, msg, data); - if (strcmp(member, "RemovePort") == 0) - return remove_port(conn, msg, data); + if (strcmp(member, "DisconnectService") == 0) + return disconnect_service(conn, msg, data); - if (strcmp(member, "ListPorts") == 0) - return list_ports(conn, msg, data); + if (strcmp(member, "CancelConnectService") == 0) + return cancel_connect_service(conn, msg, data); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } static void manager_unregister(DBusConnection *conn, void *data) { - GSList *l; - - for (l = port_paths; l; l = l->next) - dbus_connection_unregister_object_path(conn, l->data); - g_slist_foreach(port_paths, (GFunc) g_free, NULL); - g_slist_free(port_paths); - port_paths = NULL; } /* Virtual table to handle manager object path hierarchy */ @@ -371,9 +134,8 @@ int serial_init(DBusConnection *conn) { connection = dbus_connection_ref(conn); - /* Fallback to catch invalid serial path */ - if (dbus_connection_register_fallback(connection, SERIAL_MANAGER_PATH, - &manager_table, NULL) == FALSE) { + if (dbus_connection_register_object_path(connection, + SERIAL_MANAGER_PATH, &manager_table, NULL) == FALSE) { error("D-Bus failed to register %s path", SERIAL_MANAGER_PATH); dbus_connection_unref(connection); |