From b94d1033b7c6919ca4705cf11139fb8224c3ecde Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:19:21 +0000 Subject: Add bridge name support. --- network/connection.c | 95 +++++++++++++++++++++++++++++++++------------------- network/connection.h | 19 ++++++----- network/main.c | 2 +- network/manager.c | 49 ++++++++++++++++----------- network/manager.h | 2 +- network/server.c | 44 +++++++++++++++++------- network/server.h | 3 +- 7 files changed, 134 insertions(+), 80 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 18bba87c..e6a6c151 100644 --- a/network/connection.c +++ b/network/connection.c @@ -55,14 +55,14 @@ typedef enum { } conn_state; struct network_conn { - DBusConnection *conn; DBusMessage *msg; bdaddr_t src; bdaddr_t dst; char *path; /* D-Bus path */ - char dev[16]; /* BNEP interface name */ - char *name; - char *desc; + char dev[16]; /* Interface name */ + char *name; /* Service Name */ + char *desc; /* Service Description*/ + char *script; /* Interface up script*/ uint16_t id; /* Role: Service Class Identifier */ conn_state state; int sk; @@ -73,15 +73,17 @@ struct __service_16 { uint16_t src; } __attribute__ ((packed)); -static char netdev[16] = "bnep%d"; +static DBusConnection *connection = NULL; +static struct connection_conf *conf = NULL; +static const char *prefix = NULL; static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, gpointer data) { struct network_conn *nc = data; - if (nc->conn != NULL) { - dbus_connection_emit_signal(nc->conn, nc->path, + if (connection != NULL) { + dbus_connection_emit_signal(connection, nc->path, NETWORK_CONNECTION_INTERFACE, "Disconnected", DBUS_TYPE_INVALID); @@ -89,7 +91,7 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, info("%s disconnected", nc->dev); nc->state = DISCONNECTED; memset(nc->dev, 0, 16); - strncpy(nc->dev, netdev, 16); + strncpy(nc->dev, prefix, strlen(prefix)); g_io_channel_close(chan); return FALSE; } @@ -156,7 +158,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, } bnep_if_up(nc->dev, TRUE); - dbus_connection_emit_signal(nc->conn, nc->path, + dbus_connection_emit_signal(connection, nc->path, NETWORK_CONNECTION_INTERFACE, "Connected", DBUS_TYPE_INVALID); @@ -166,7 +168,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, pdev = nc->dev; dbus_message_append_args(reply, DBUS_TYPE_STRING, &pdev, DBUS_TYPE_INVALID); - send_message_and_unref(nc->conn, reply); + send_message_and_unref(connection, reply); nc->state = CONNECTED; @@ -178,7 +180,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, failed: if (nc->state != DISCONNECTED) { nc->state = DISCONNECTED; - err_connection_failed(nc->conn, nc->msg, "bnep failed"); + err_connection_failed(connection, nc->msg, "bnep failed"); g_io_channel_close(chan); } return FALSE; @@ -251,7 +253,7 @@ static gboolean l2cap_connect_cb(GIOChannel *chan, return FALSE; failed: nc->state = DISCONNECTED; - err_connection_failed(nc->conn, nc->msg, strerror(errno)); + err_connection_failed(connection, nc->msg, strerror(errno)); g_io_channel_close(chan); return FALSE; } @@ -597,7 +599,7 @@ static void connection_free(struct network_conn *nc) if (nc->desc) g_free(nc->desc); - + g_free(nc); nc = NULL; } @@ -632,30 +634,27 @@ static DBusSignalVTable connection_signals[] = { { NULL, NULL } }; -int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, - bdaddr_t *dst, uint16_t id, const char *name, const char *desc) +int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, + uint16_t id, const char *name, const char *desc) { struct network_conn *nc; - if (!conn) - return -1; - nc = g_new0(struct network_conn, 1); /* register path */ - if (!dbus_connection_create_object_path(conn, path, nc, + if (!dbus_connection_create_object_path(connection, path, nc, connection_unregister)) { connection_free(nc); return -1; } - if (!dbus_connection_register_interface(conn, path, + if (!dbus_connection_register_interface(connection, path, NETWORK_CONNECTION_INTERFACE, connection_methods, connection_signals, NULL)) { error("D-Bus failed to register %s interface", NETWORK_CONNECTION_INTERFACE); - dbus_connection_destroy_object_path(conn, path); + dbus_connection_destroy_object_path(connection, path); return -1; } @@ -666,17 +665,21 @@ int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, nc->name = g_strdup(name); nc->desc = g_strdup(desc); memset(nc->dev, 0, 16); - strncpy(nc->dev, netdev, 16); + strncpy(nc->dev, prefix, strlen(prefix)); + if (id == BNEP_SVC_PANU) + nc->script = conf->panu_script; + else if (id == BNEP_SVC_GN) + nc->script = conf->gn_script; + else + nc->script = conf->nap_script; nc->state = DISCONNECTED; - nc->conn = conn; info("Registered connection path:%s", path); return 0; } -int connection_store(DBusConnection *conn, const char *path, - gboolean default_path) +int connection_store(const char *path, gboolean default_path) { struct network_conn *nc; const char *role; @@ -685,7 +688,8 @@ int connection_store(DBusConnection *conn, const char *path, char src_addr[18], dst_addr[18]; int len, err; - if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, path, + (void *) &nc)) return -ENOENT; if (!nc->name || !nc->desc) @@ -714,14 +718,14 @@ int connection_store(DBusConnection *conn, const char *path, return err; } -int connection_find_data(DBusConnection *conn, - const char *path, const char *pattern) +int connection_find_data(const char *path, const char *pattern) { struct network_conn *nc; char addr[18], key[32]; const char *role; - if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, path, + (void *) &nc)) return -1; if (strcasecmp(pattern, nc->dev) == 0) @@ -744,17 +748,18 @@ int connection_find_data(DBusConnection *conn, return -1; } -gboolean connection_has_pending(DBusConnection *conn, const char *path) +gboolean connection_has_pending(const char *path) { struct network_conn *nc; - if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, path, + (void *) &nc)) return FALSE; return (nc->state == CONNECTING); } -int connection_remove_stored(DBusConnection *conn, const char *path) +int connection_remove_stored(const char *path) { struct network_conn *nc; const char *role; @@ -763,7 +768,8 @@ int connection_remove_stored(DBusConnection *conn, const char *path) char src_addr[18], dst_addr[18]; int err; - if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, path, + (void *) &nc)) return -ENOENT; ba2str(&nc->dst, dst_addr); @@ -778,12 +784,31 @@ int connection_remove_stored(DBusConnection *conn, const char *path) return err; } -gboolean connection_is_connected(DBusConnection *conn, const char *path) +gboolean connection_is_connected(const char *path) { struct network_conn *nc; - if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, path, + (void *) &nc)) return FALSE; return (nc->state == CONNECTED); } + +int connection_init(DBusConnection *conn, const char *iface_prefix, + struct connection_conf *conn_conf) +{ + connection = dbus_connection_ref(conn); + conf = conn_conf; + prefix = iface_prefix; + + return 0; +} + +void connection_exit() +{ + dbus_connection_unref(connection); + connection = NULL; + conf = NULL; + prefix = NULL; +} diff --git a/network/connection.h b/network/connection.h index 35726732..7cafa122 100644 --- a/network/connection.h +++ b/network/connection.h @@ -27,12 +27,13 @@ struct connection_conf { char *nap_script; }; -int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, - bdaddr_t *dst, uint16_t id, const char *name, const char *desc); -int connection_store(DBusConnection *conn, const char *path, - gboolean default_path); -int connection_remove_stored(DBusConnection *conn, const char *path); -int connection_find_data(DBusConnection *conn, const char *path, - const char *pattern); -gboolean connection_has_pending(DBusConnection *conn, const char *path); -gboolean connection_is_connected(DBusConnection *conn, const char *path); +int connection_init(DBusConnection *conn, const char *iface_prefix, + struct connection_conf *conn_conf); +void connection_exit(); +int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, + uint16_t id, const char *name, const char *desc); +int connection_store(const char *path, gboolean default_path); +int connection_remove_stored(const char *path); +int connection_find_data(const char *path, const char *pattern); +gboolean connection_has_pending(const char *path); +gboolean connection_is_connected(const char *path); diff --git a/network/main.c b/network/main.c index 5d1f5013..6260ac4e 100644 --- a/network/main.c +++ b/network/main.c @@ -196,7 +196,7 @@ int main(int argc, char *argv[]) hal_create_device(NULL); - if (network_init(conn) < 0) { + if (network_init(conn, &conf) < 0) { dbus_connection_unref(conn); g_main_loop_unref(main_loop); exit(1); diff --git a/network/manager.c b/network/manager.c index 2bf76e03..6ca36955 100644 --- a/network/manager.c +++ b/network/manager.c @@ -65,14 +65,14 @@ struct pending_reply { uint16_t id; /* Role */ }; +static struct network_conf *conf = NULL;/* Network service configuration */ static GSList *server_paths = NULL; /* Network registered servers paths */ static GSList *connection_paths = NULL; /* Network registered connections paths */ static int default_index = -1; /* Network default connection path index */ +static int net_uid = 0; /* Network objects identifier */ static DBusConnection *connection = NULL; -static int net_uid = 0; /* Network objects identifier */ - static void pending_reply_free(struct pending_reply *pr) { @@ -145,7 +145,7 @@ static const char * last_connection_used(DBusConnection *conn) for (i = g_slist_length (connection_paths) -1; i > -1; i--) { path = g_slist_nth_data (connection_paths, i); - if (connection_is_connected(conn, path)) + if (connection_is_connected(path)) break; } @@ -182,16 +182,16 @@ static DBusHandlerResult remove_path(DBusConnection *conn, /* Remove references from the storage */ if (*list == connection_paths) { - if (connection_has_pending(conn, path)) + if (connection_has_pending(path)) return err_failed(conn, msg, "Connection is Busy"); - connection_remove_stored(conn, path); + connection_remove_stored(path); /* Reset default connection */ if (l == g_slist_nth(*list, default_index)) { const char *dpath; dpath = last_connection_used(conn); - connection_store(conn, dpath, TRUE); + connection_store(dpath, TRUE); } } @@ -274,13 +274,13 @@ static void pan_record_reply(DBusPendingCall *call, void *data) d->unitSize, d->val.str); } - if (connection_register(pr->conn, pr->path, &pr->src, - &pr->dst, pr->id, name, desc) < 0) { + if (connection_register(pr->path, &pr->src, &pr->dst, pr->id, name, + desc) < 0) { err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); goto fail; } - connection_store(pr->conn, pr->path, FALSE); + connection_store(pr->path, FALSE); connection_paths = g_slist_append(connection_paths, g_strdup(pr->path)); create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated"); @@ -463,7 +463,7 @@ static GSList * find_connection_pattern(DBusConnection *conn, for (list = connection_paths; list; list = list->next) { path = (const char *) list->data; - if (connection_find_data(conn, path, pattern) == 0) + if (connection_find_data(path, pattern) == 0) break; } @@ -538,7 +538,7 @@ static DBusHandlerResult create_connection(DBusConnection *conn, /* Checks if the connection was already been made */ for (l = connection_paths; l; l = l->next) { - if (connection_find_data(conn, l->data, key) == 0) { + if (connection_find_data(l->data, key) == 0) { err_already_exists(conn, msg, "Connection Already exists"); return DBUS_HANDLER_RESULT_HANDLED; @@ -616,7 +616,7 @@ static DBusHandlerResult default_connection(DBusConnection *conn, if (path == NULL) { path = last_connection_used(conn); - connection_store(conn, path, TRUE); + connection_store(path, TRUE); } reply = dbus_message_new_method_return(msg); @@ -670,7 +670,7 @@ static DBusHandlerResult change_default_connection(DBusConnection *conn, path = list->data; default_index = g_slist_position (connection_paths, list); - connection_store(connection, path, TRUE); + connection_store(path, TRUE); dbus_connection_emit_signal(connection, NETWORK_PATH, NETWORK_MANAGER_INTERFACE, @@ -760,8 +760,7 @@ static void parse_stored_connection(char *key, char *value, void *data) return; } - if (connection_register(connection, path, src, - &dst, id, name, ptr) == 0) { + if (connection_register(path, src, &dst, id, name, ptr) == 0) { char *rpath = g_strdup(path); connection_paths = g_slist_append(connection_paths, rpath); } @@ -920,15 +919,23 @@ static DBusSignalVTable manager_signals[] = { { NULL, NULL } }; -int network_init(DBusConnection *conn) +int network_init(DBusConnection *conn, struct network_conf *service_conf) { + conf = service_conf; + if (bridge_init() < 0) { error("Can't init bridge module"); return -1; } - if (bridge_create("pan0") < 0) - error("Can't create bridge"); + if (bridge_create(conf->server.panu_iface) < 0) + error("Can't create PANU bridge"); + + if (bridge_create(conf->server.gn_iface) < 0) + error("Can't create GN bridge"); + + if (bridge_create(conf->server.nap_iface) < 0) + error("Can't create NAP bridge"); if (bnep_init()) { error("Can't init bnep module"); @@ -941,9 +948,11 @@ int network_init(DBusConnection *conn) * (setup connection request) contains the destination service * field that defines which service the source is connecting to. */ - if (server_init(conn) < 0) { + if (server_init(conn, conf->iface_prefix, &conf->server) < 0) return -1; - } + + if (connection_init(conn, conf->iface_prefix, &conf->conn) < 0) + return -1; if (!dbus_connection_create_object_path(conn, NETWORK_PATH, NULL, manager_unregister)) { diff --git a/network/manager.h b/network/manager.h index 45c7ada4..0efacc14 100644 --- a/network/manager.h +++ b/network/manager.h @@ -35,7 +35,7 @@ struct network_conf { struct server_conf server; }; -int network_init(DBusConnection *conn); +int network_init(DBusConnection *conn, struct network_conf *service_conf); void network_exit(void); int network_del_stored_info(bdaddr_t *src, uint16_t uuid); diff --git a/network/server.c b/network/server.c index 39cb4067..76be55b3 100644 --- a/network/server.c +++ b/network/server.c @@ -73,22 +73,24 @@ struct setup_session { /* Main server structure */ struct network_server { - bdaddr_t src; /* Bluetooth Local Address */ - char *iface; /* Routing interface */ - char *name; /* Server service name */ - char *range; /* IP Address range */ - char *path; /* D-Bus path */ - gboolean enable; /* Enable flag*/ - gboolean secure; /* Security flag*/ - uint32_t record_id; /* Service record id */ - uint16_t id; /* Service class identifier */ - GSList *clients; /* Active connections */ + bdaddr_t src; /* Bluetooth Local Address */ + char *bridge; /* Bridge interface */ + char *iface; /* Routing interface */ + char *name; /* Server service name */ + char *range; /* IP Address range */ + char *path; /* D-Bus path */ + gboolean enable; /* Enable flag */ + gboolean secure; /* Security flag */ + uint32_t record_id; /* Service record id */ + uint16_t id; /* Service class identifier */ + GSList *clients; /* Active connections */ }; -static char netdev[16] = "bnep%d"; +static struct server_conf *conf = NULL; static GIOChannel *bnep_io = NULL; static DBusConnection *connection = NULL; static GSList *setup_sessions = NULL; +static const char *prefix = NULL; static int store_property(bdaddr_t *src, uint16_t id, const char *key, const char *value) @@ -327,7 +329,7 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) } memset(devname, 0, 16); - strncpy(devname, netdev, 16); + strncpy(devname, prefix, strlen(prefix)); if (bnep_connadd(s->nsk, s->dst_role, devname) < 0) goto failed; @@ -592,7 +594,8 @@ static gboolean connect_event(GIOChannel *chan, return TRUE; } -int server_init(DBusConnection *conn) +int server_init(DBusConnection *conn, const char *iface_prefix, + struct server_conf *server_conf) { struct l2cap_options l2o; struct sockaddr_l2 l2a; @@ -653,6 +656,8 @@ int server_init(DBusConnection *conn) } connection = dbus_connection_ref(conn); + conf = server_conf; + prefix = iface_prefix; bnep_io = g_io_channel_unix_new(sk); g_io_channel_set_close_on_unref(bnep_io, FALSE); @@ -682,6 +687,7 @@ void server_exit() dbus_connection_unref(connection); connection = NULL; + conf = NULL; } static uint32_t add_server_record(struct network_server *ns) @@ -1190,6 +1196,12 @@ int server_register(const char *path, bdaddr_t *src, uint16_t id) ns->path = g_strdup(path); ns->id = id; + if (id == BNEP_SVC_NAP) + ns->bridge = conf->nap_iface; + else if (id == BNEP_SVC_GN) + ns->bridge = conf->gn_iface; + else + ns->bridge = conf->panu_iface; bacpy(&ns->src, src); info("Registered server path:%s", path); @@ -1208,6 +1220,12 @@ int server_register_from_file(const char *path, const bdaddr_t *src, bacpy(&ns->src, src); ns->path = g_strdup(path); ns->id = id; + if (id == BNEP_SVC_NAP) + ns->bridge = conf->nap_iface; + else if (id == BNEP_SVC_GN) + ns->bridge = conf->gn_iface; + else + ns->bridge = conf->panu_iface; ns->name = textfile_get(filename, "name"); if (!ns->name) { /* Name is mandatory */ diff --git a/network/server.h b/network/server.h index 2b148081..233c7837 100644 --- a/network/server.h +++ b/network/server.h @@ -28,7 +28,8 @@ struct server_conf { gboolean disable_security; }; -int server_init(DBusConnection *conn); +int server_init(DBusConnection *conn, const char *iface_prefix, + struct server_conf *server_conf); void server_exit(); int server_register(const char *path, bdaddr_t *src, uint16_t id); int server_register_from_file(const char *path, const bdaddr_t *src, -- cgit