diff options
| author | Luiz Augusto von Dentz <luiz.dentz@indt.org.br> | 2008-07-23 18:45:34 -0300 | 
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.dentz@indt.org.br> | 2008-07-28 10:49:02 -0300 | 
| commit | 56f867d9b7a018d582d87f31c87d1ecb7c7a12bc (patch) | |
| tree | 178f2a4fdb5240763ceb762c6ce64d0001cf8a89 | |
| parent | debc2efd75e3211934c2f4262140e7c28f574945 (diff) | |
Fix network plugin to reflect the api documentation.
| -rw-r--r-- | network/connection.c | 280 | ||||
| -rw-r--r-- | network/main.c | 1 | ||||
| -rw-r--r-- | network/manager.c | 61 | 
3 files changed, 181 insertions, 161 deletions
| diff --git a/network/connection.c b/network/connection.c index 3e99a865..d0b60c82 100644 --- a/network/connection.c +++ b/network/connection.c @@ -52,9 +52,7 @@  #include "common.h"  #include "connection.h" -#define NETWORK_PANU_INTERFACE "org.bluez.network.Peer" -#define NETWORK_GN_INTERFACE "org.bluez.network.Hub" -#define NETWORK_NAP_INTERFACE "org.bluez.network.Router" +#define NETWORK_PEER_INTERFACE "org.bluez.network.Peer"  typedef enum {  	CONNECTED, @@ -62,15 +60,20 @@ typedef enum {  	DISCONNECTED  } conn_state; -struct network_conn { -	DBusMessage	*msg; +struct network_peer {  	bdaddr_t	src;  	bdaddr_t	dst;  	char		*path;		/* D-Bus path */ +	GSList		*connections; +}; + +struct network_conn { +	DBusMessage	*msg;  	char		dev[16];	/* Interface name */  	uint16_t	id;		/* Role: Service Class Identifier */  	conn_state	state;  	int		sk; +	struct network_peer *peer;  };  struct __service_16 { @@ -80,14 +83,34 @@ struct __service_16 {  static DBusConnection *connection = NULL;  static const char *prefix = NULL; -static GSList *connections = NULL; +static GSList *peers = NULL; + +static struct network_peer *find_peer(GSList *list, const char *path) +{ +	GSList *l; + +	for (l = list; l; l = l->next) { +		struct network_peer *peer = l->data; + +		if (!strcmp(peer->path, path)) +			return peer; +	} + +	return NULL; +} -gint find_connection(gconstpointer a, gconstpointer b) +static struct network_conn *find_connection(GSList *list, uint16_t id)  { -	const struct network_conn *nc = a; -	const char *path = b; +	GSList *l; + +	for (l = list; l; l = l->next) { +		struct network_conn *nc = l->data; -	return strcmp(nc->path, path); +		if (nc->id == id) +			return nc; +	} + +	return NULL;  }  static inline DBusMessage *not_supported(DBusMessage *msg) @@ -120,35 +143,17 @@ static inline DBusMessage *connection_attempt_failed(DBusMessage *msg, int err)  				err ? strerror(err) : "Connection attempt failed");  } -static const char *id2iface(uint16_t id) -{ -	switch (id) { -	case BNEP_SVC_PANU: -		return NETWORK_PANU_INTERFACE; -		break; -	case BNEP_SVC_GN: -		return NETWORK_GN_INTERFACE; -		break; -	case BNEP_SVC_NAP: -		return NETWORK_NAP_INTERFACE; -		break; -	default: -		return NULL; -	} -} -  static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,  				gpointer data)  {  	struct network_conn *nc = data;  	if (connection != NULL) { -		const char *interface = id2iface(nc->id); - -		g_dbus_emit_signal(connection, nc->path, -						interface, -						"Disconnected", -						DBUS_TYPE_INVALID); +		const char *device = nc->dev; +		g_dbus_emit_signal(connection, nc->peer->path, +				NETWORK_PEER_INTERFACE, "Disconnected", +				DBUS_TYPE_STRING, &device, +				DBUS_TYPE_INVALID);  	}  	info("%s disconnected", nc->dev); @@ -171,7 +176,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond,  	gsize r;  	int sk;  	DBusMessage *reply; -	const char *pdev; +	const char *pdev, *uuid;  	if (cond & G_IO_NVAL)  		return FALSE; @@ -224,16 +229,18 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond,  	}  	bnep_if_up(nc->dev, nc->id); -	g_dbus_emit_signal(connection, nc->path, -					id2iface(nc->id), -					"Connected", -					DBUS_TYPE_INVALID); -  	pdev = nc->dev; +	uuid = bnep_uuid(nc->id); -	reply = g_dbus_create_reply(nc->msg, DBUS_TYPE_STRING, &pdev, -							DBUS_TYPE_INVALID); -	g_dbus_send_message(connection, reply); +	g_dbus_send_reply(connection, nc->msg, +			DBUS_TYPE_STRING, &pdev, +			DBUS_TYPE_INVALID); + +	g_dbus_emit_signal(connection, nc->peer->path, +			NETWORK_PEER_INTERFACE, "Connected", +			DBUS_TYPE_STRING, &pdev, +			DBUS_TYPE_STRING, &uuid, +			DBUS_TYPE_INVALID);  	nc->state = CONNECTED; @@ -317,33 +324,32 @@ failed:  	g_dbus_send_message(connection, reply);  } -static DBusMessage *get_interface(DBusConnection *conn, -					DBusMessage *msg, void *data) -{ -	struct network_conn *nc = data; -	const char *pdev = nc->dev; - -	if (nc->state != CONNECTED) -		return not_connected(msg); - -	return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &pdev, -						DBUS_TYPE_INVALID); -} -  /* Connect and initiate BNEP session */  static DBusMessage *connection_connect(DBusConnection *conn,  						DBusMessage *msg, void *data)  { -	struct network_conn *nc = data; +	struct network_peer *peer = data; +	struct network_conn *nc; +	const char *svc; +	uint16_t id;  	int err; +	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &svc, +						DBUS_TYPE_INVALID) == FALSE) +		return NULL; + +	id = bnep_service_id(svc); +	nc = find_connection(peer->connections, id); +	if (!nc) +		return not_supported(msg); +  	if (nc->state != DISCONNECTED)  		return already_connected(msg);  	nc->state = CONNECTING;  	nc->msg = dbus_message_ref(msg); -	err = bt_l2cap_connect(&nc->src, &nc->dst, BNEP_PSM, BNEP_MTU, +	err = bt_l2cap_connect(&peer->src, &peer->dst, BNEP_PSM, BNEP_MTU,  							connect_cb, nc);  	if (err < 0) {  		error("Connect failed. %s(%d)", strerror(errno), errno); @@ -361,11 +367,11 @@ static DBusMessage *connection_cancel(DBusConnection *conn,  {  	struct network_conn *nc = data; -	if (nc->state != CONNECTING) -		return no_pending_connect(msg); - -	close(nc->sk); -	nc->state = DISCONNECTED; +	if (nc->state == CONNECTED) { +		bnep_if_down(nc->dev); +		bnep_kill_connection(&nc->peer->dst); +	} else +		close(nc->sk);  	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);  } @@ -373,22 +379,36 @@ static DBusMessage *connection_cancel(DBusConnection *conn,  static DBusMessage *connection_disconnect(DBusConnection *conn,  					DBusMessage *msg, void *data)  { -	struct network_conn *nc = data; +	struct network_peer *peer = data; +	GSList *l; -	if (nc->state != CONNECTED) -		return not_connected(msg); +	for (l = peer->connections; l; l = l->next) { +		struct network_conn *nc = l->data; -	bnep_if_down(nc->dev); -	bnep_kill_connection(&nc->dst); +		if (nc->state == DISCONNECTED) +			continue; -	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); +		return connection_cancel(conn, msg, nc); +	} + +	return not_connected(msg);  }  static DBusMessage *is_connected(DBusConnection *conn,  				DBusMessage *msg, void *data)  { -	struct network_conn *nc = data; -	gboolean up = (nc->state == CONNECTED); +	struct network_peer *peer = data; +	GSList *l; +	dbus_bool_t up = FALSE; + +	for (l = peer->connections; l; l = l->next) { +		struct network_conn *nc = l->data; + +		if (nc->state != CONNECTED) +			continue; + +		up = TRUE; +	}  	return g_dbus_create_reply(msg, DBUS_TYPE_BOOLEAN, &up,  						DBUS_TYPE_INVALID); @@ -396,94 +416,126 @@ static DBusMessage *is_connected(DBusConnection *conn,  static void connection_free(struct network_conn *nc)  { -	if (!nc) -		return; - -	if (nc->path) -		g_free(nc->path); -  	if (nc->state == CONNECTED) {  		bnep_if_down(nc->dev); -		bnep_kill_connection(&nc->dst); -	} +		bnep_kill_connection(&nc->peer->dst); +	} else if (nc->state == CONNECTING) +		close(nc->sk);  	g_free(nc);  	nc = NULL;  } +static void peer_free(struct network_peer *peer) +{ +	g_slist_foreach(peer->connections, (GFunc) connection_free, NULL); +	g_slist_free(peer->connections); +	g_free(peer->path); +	g_free(peer); +} +  static void path_unregister(void *data)  { -	struct network_conn *nc = data; -	const char *interface = id2iface(nc->id); +	struct network_peer *peer = data; -	info("Unregistered interface %s on path %s", interface, nc->path); +	info("Unregistered interface %s on path %s", +		NETWORK_PEER_INTERFACE, peer->path); -	connections = g_slist_remove(connections, nc); -	connection_free(nc); +	peers = g_slist_remove(peers, peer); +	peer_free(peer);  }  static GDBusMethodTable connection_methods[] = { -	{ "GetInterface",	"",	"s",	get_interface		}, -	{ "Connect",		"",	"s",	connection_connect, +	{ "Connect",		"s",	"s",	connection_connect,  						G_DBUS_METHOD_FLAG_ASYNC }, -	{ "CancelConnect",	"",	"",	connection_cancel	},  	{ "Disconnect",		"",	"",	connection_disconnect	},  	{ "IsConnected",	"",	"b",	is_connected		},  	{ }  };  static GDBusSignalTable connection_signals[] = { -	{ "Connected",		""	}, -	{ "Disconnected",	""	}, +	{ "Connected",		"ss"	}, +	{ "Disconnected",	"s"	},  	{ }  };  void connection_unregister(const char *path, uint16_t id)  { -	const char *interface = id2iface(id); +	struct network_peer *peer; +	struct network_conn *nc; + +	peer = find_peer(peers, path); +	if (!peer) +		return; + +	nc = find_connection(peer->connections, id); +	if (!nc) +		return; + +	peer->connections = g_slist_remove(peer->connections, nc); +	connection_free(nc); +	if (peer->connections) +		return; + +	g_dbus_unregister_interface(connection, path, NETWORK_PEER_INTERFACE); +} + +static struct network_peer *create_peer(const char *path, bdaddr_t *src, +				bdaddr_t *dst) +{ +	struct network_peer *peer; + +	peer = g_new0(struct network_peer, 1); +	peer->path = g_strdup(path); +	bacpy(&peer->src, src); +	bacpy(&peer->dst, dst); + +	if (g_dbus_register_interface(connection, path, +					NETWORK_PEER_INTERFACE, +					connection_methods, +					connection_signals, NULL, +					peer, path_unregister) == FALSE) { +		error("D-Bus failed to register %s interface", +			NETWORK_PEER_INTERFACE); +		g_free(peer); +		return NULL; +	} + +	info("Registered interface %s on path %s", +		NETWORK_PEER_INTERFACE, path); -	g_dbus_unregister_interface(connection, path, interface); +	return peer;  }  int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst,  			uint16_t id)  { +	struct network_peer *peer;  	struct network_conn *nc; -	bdaddr_t default_src; -	int dev_id; -	const char *interface;  	if (!path)  		return -EINVAL; -	bacpy(&default_src, BDADDR_ANY); -	dev_id = hci_get_route(&default_src); -	if (dev_id < 0 || hci_devba(dev_id, &default_src) < 0) -		return -1; - -	nc = g_new0(struct network_conn, 1); -	interface = id2iface(id); - -	if (g_dbus_register_interface(connection, path, -					interface, -					connection_methods, -					connection_signals, NULL, -					nc, path_unregister) == FALSE) { -		error("D-Bus failed to register %s interface", interface); -		return -1; +	peer = find_peer(peers, path); +	if (!peer) { +		peer = create_peer(path, src, dst); +		if (!peer) +			return -1; +		peers = g_slist_append(peers, peer);  	} -	nc->path = g_strdup(path); -	bacpy(&nc->src, src); -	bacpy(&nc->dst, dst); +	nc = find_connection(peer->connections, id); +	if (nc) +		return 0; + +	nc = g_new0(struct network_conn, 1);  	nc->id = id;  	memset(nc->dev, 0, 16);  	strncpy(nc->dev, prefix, strlen(prefix));  	nc->state = DISCONNECTED; +	nc->peer = peer; -	connections = g_slist_append(connections, nc); - -	info("Registered interface %s on path %s", interface, path); +	peer->connections = g_slist_append(peer->connections, nc);  	return 0;  } diff --git a/network/main.c b/network/main.c index e4220928..414ff938 100644 --- a/network/main.c +++ b/network/main.c @@ -33,7 +33,6 @@  #include <gdbus.h>  #include "plugin.h" -#include "device.h"  #include "logging.h"  #include "manager.h" diff --git a/network/manager.c b/network/manager.c index b3ba1cdb..22a6e70c 100644 --- a/network/manager.c +++ b/network/manager.c @@ -45,8 +45,8 @@  #include "textfile.h"  #include "glib-helper.h" -#include "../hcid/adapter.h" -#include "../hcid/device.h" +#include "adapter.h" +#include "device.h"  #include "error.h"  #include "bridge.h"  #include "manager.h" @@ -80,12 +80,14 @@ static void register_server(uint16_t id)  	server_store(path);  } -static int network_probe(struct btd_device *device, uint16_t id) +static int network_probe(struct btd_device_driver *driver, +			struct btd_device *device, GSList *records)  {  	struct adapter *adapter = device_get_adapter(device);  	const gchar *path = device_get_path(device);  	const char *source, *destination;  	bdaddr_t src, dst; +	uint16_t id;  	DBG("path %s", path); @@ -94,74 +96,41 @@ static int network_probe(struct btd_device *device, uint16_t id)  	str2ba(source, &src);  	str2ba(destination, &dst); +	id = bnep_service_id(driver->uuids[0]);  	return connection_register(path, &src, &dst, id);  } -static int panu_probe(struct btd_device_driver *driver, -			struct btd_device *device, GSList *records) -{ -	return network_probe(device, BNEP_SVC_PANU); -} - -static int gn_probe(struct btd_device_driver *driver, -			struct btd_device *device, GSList *records) -{ -	return network_probe(device, BNEP_SVC_GN); -} - -static int nap_probe(struct btd_device_driver *driver, -			struct btd_device *device, GSList *records) -{ -	return network_probe(device, BNEP_SVC_NAP); -} - -static void network_remove(struct btd_device *device, uint16_t id) +static void network_remove(struct btd_device_driver *driver, +			struct btd_device *device)  {  	const gchar *path = device_get_path(device); +	uint16_t id = bnep_service_id(driver->uuids[0]);  	DBG("path %s", path);  	connection_unregister(path, id);  } -static void panu_remove(struct btd_device_driver *driver, -			struct btd_device *device) -{ -	network_remove(device, BNEP_SVC_PANU); -} - -static void gn_remove(struct btd_device_driver *driver, -			struct btd_device *device) -{ -	network_remove(device, BNEP_SVC_GN); -} - -static void nap_remove(struct btd_device_driver *driver, -			struct btd_device *device) -{ -	network_remove(device, BNEP_SVC_NAP); -} -  static struct btd_device_driver network_panu_driver = {  	.name	= "network-panu",  	.uuids	= BTD_UUIDS(PANU_UUID), -	.probe	= panu_probe, -	.remove	= panu_remove, +	.probe	= network_probe, +	.remove	= network_remove,  };  static struct btd_device_driver network_gn_driver = {  	.name	= "network-gn",  	.uuids	= BTD_UUIDS(GN_UUID), -	.probe	= gn_probe, -	.remove	= gn_remove, +	.probe	= network_probe, +	.remove	= network_remove,  };  static struct btd_device_driver network_nap_driver = {  	.name	= "network-nap",  	.uuids	= BTD_UUIDS(NAP_UUID), -	.probe	= nap_probe, -	.remove	= nap_remove, +	.probe	= network_probe, +	.remove	= network_remove,  };  int network_manager_init(DBusConnection *conn, struct network_conf *service_conf) | 
