diff options
author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-05-01 13:56:28 +0000 |
---|---|---|
committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-05-01 13:56:28 +0000 |
commit | 701245f0971feee4f41ef8ec03a4f03265c3c9d9 (patch) | |
tree | f494c2c6d50b761642105d50357c50be0d1e2972 | |
parent | 7c21f8711c39949419c35aba60b007d1b9d2b1d5 (diff) |
serial: added port methods skeleton
-rw-r--r-- | serial/manager.c | 165 |
1 files changed, 155 insertions, 10 deletions
diff --git a/serial/manager.c b/serial/manager.c index ee250b37..b93069e2 100644 --- a/serial/manager.c +++ b/serial/manager.c @@ -26,20 +26,60 @@ #endif #include <errno.h> +#include <stdint.h> +#include <stdio.h> #include <string.h> +#include <glib.h> #include "dbus.h" #include "logging.h" #include "manager.h" -#define SERIAL_PATH "/org/bluez/serial" +#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 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); +} + +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)); +} -DBusHandlerResult err_unknown_port(DBusConnection *conn, DBusMessage *msg) +static DBusHandlerResult err_invalid_args(DBusConnection *conn, + DBusMessage *msg, const char *str) +{ + return send_message_and_unref(conn, + dbus_message_new_error(msg, + 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, @@ -47,12 +87,117 @@ DBusHandlerResult err_unknown_port(DBusConnection *conn, DBusMessage *msg) "Unknown port path")); } -static DBusHandlerResult create_port(DBusConnection *conn, +static DBusHandlerResult port_connect(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_unregister(DBusConnection *conn, void *data) +{ + serial_port_free(data); +} + +/* Virtual table to handle port object path hierarchy */ +static const DBusObjectPathVTable port_table = { + .message_function = port_message, + .unregister_function = port_unregister, +}; + +static int port_register(DBusConnection *conn, + const char *path, const char *owner) +{ + struct serial_port *sp; + + if (!conn) + return -1; + + 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; + } + + info("Registered 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; + + /* FIXME: Check if it already exist */ + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &addr, + DBUS_TYPE_STRING, &pattern, + DBUS_TYPE_INVALID)) { + err_invalid_args(conn, msg, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + /* Pattern can be a service or a channel */ + + /* FIXME: Missing SDP search */ + + reply = dbus_message_new_method_return(msg); + 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)); + + return send_message_and_unref(conn, reply); +} + static DBusHandlerResult remove_port(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -75,7 +220,7 @@ static DBusHandlerResult manager_message(DBusConnection *conn, member = dbus_message_get_member(msg); /* Catching fallback paths */ - if (strcmp(SERIAL_PATH, path) != 0) + if (strcmp(SERIAL_MANAGER_PATH, path) != 0) return err_unknown_port(conn, msg); /* Accept messages from the manager interface only */ @@ -100,8 +245,8 @@ static void manager_unregister(DBusConnection *conn, void *data) /* Virtual table to handle manager object path hierarchy */ static const DBusObjectPathVTable manager_table = { - .message_function = manager_message, - .unregister_function = manager_unregister, + .message_function = manager_message, + .unregister_function = manager_unregister, }; int serial_init(DBusConnection *conn) @@ -109,22 +254,22 @@ int serial_init(DBusConnection *conn) connection = dbus_connection_ref(conn); /* Fallback to catch invalid serial path */ - if (dbus_connection_register_fallback(connection, SERIAL_PATH, + if (dbus_connection_register_fallback(connection, SERIAL_MANAGER_PATH, &manager_table, NULL) == FALSE) { - error("D-Bus failed to register %s path", SERIAL_PATH); + error("D-Bus failed to register %s path", SERIAL_MANAGER_PATH); dbus_connection_unref(connection); return -1; } - info("Registered manager path:%s", SERIAL_PATH); + info("Registered manager path:%s", SERIAL_MANAGER_PATH); return 0; } void serial_exit(void) { - dbus_connection_unregister_object_path(connection, SERIAL_PATH); + dbus_connection_unregister_object_path(connection, SERIAL_MANAGER_PATH); dbus_connection_unref(connection); connection = NULL; |