summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2007-05-01 13:56:28 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2007-05-01 13:56:28 +0000
commit701245f0971feee4f41ef8ec03a4f03265c3c9d9 (patch)
treef494c2c6d50b761642105d50357c50be0d1e2972
parent7c21f8711c39949419c35aba60b007d1b9d2b1d5 (diff)
serial: added port methods skeleton
-rw-r--r--serial/manager.c165
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;