diff options
| author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-05-09 14:02:11 +0000 | 
|---|---|---|
| committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-05-09 14:02:11 +0000 | 
| commit | f0f6c6e23591320ce33f748ecbde483d431df46c (patch) | |
| tree | c0f2c02f6b25dab192e943e354fdb88c0a6d04c7 | |
| parent | 6f6bdcb3ae048fafa7d711d164757f2c05cbe40f (diff) | |
serial: added CancelConnectService
| -rw-r--r-- | serial/manager.c | 92 | 
1 files changed, 86 insertions, 6 deletions
| diff --git a/serial/manager.c b/serial/manager.c index 9fbf1f39..0032a995 100644 --- a/serial/manager.c +++ b/serial/manager.c @@ -71,12 +71,14 @@ struct rfcomm_node {  struct pending_connect {  	DBusConnection	*conn;  	DBusMessage	*msg; -	char		*bda;		/* Destination address */ -	char		*adapter_path;	/* Adapter D-Bus path */ +	char		*bda;		/* Destination address  */ +	char		*adapter_path;	/* Adapter D-Bus path   */ +	char		*pattern;	/* Connection request pattern */  	bdaddr_t	src;  	uint8_t		channel;  	int		id;		/* RFCOMM device id */  	int		ntries;		/* Open attempts */ +	int 		canceled;	/* Operation canceled */  };  /* FIXME: Common file required */ @@ -111,6 +113,8 @@ static void pending_connect_free(struct pending_connect *pc)  		dbus_message_unref(pc->msg);  	if (pc->bda)  		g_free(pc->bda); +	if (pc->pattern) +		g_free(pc->pattern);  	if (pc->adapter_path)  		g_free(pc->adapter_path);  	g_free(pc); @@ -159,6 +163,22 @@ static struct pending_connect *find_pending_connect_by_channel(const char *bda,  	return NULL;  } +static struct pending_connect *find_pending_connect_by_pattern(const char *bda, +							const char *pattern) +{ +	GSList *l; + +	/* Pattern can be friendly name, uuid128, record handle or channel */ +	for (l = pending_connects; l != NULL; l = l->next) { +		struct pending_connect *pending = l->data; +		if (!strcasecmp(pending->bda, bda) && +				!strcasecmp(pending->pattern, pattern)) +			return pending; +	} + +	return NULL; +} +  static uint16_t str2class(const char *pattern)  {  	int i; @@ -179,6 +199,15 @@ static DBusHandlerResult err_connection_failed(DBusConnection *conn,  			SERIAL_ERROR_INTERFACE".ConnectionAttemptFailed", str));  } +static DBusHandlerResult err_connection_canceled(DBusConnection *conn, +							DBusMessage *msg) +{ +	return send_message_and_unref(conn, +			dbus_message_new_error(msg, +			SERIAL_ERROR_INTERFACE".ConnectionCanceled", +			"Connection creation canceled")); +} +  static DBusHandlerResult err_connection_in_progress(DBusConnection *conn,  							DBusMessage *msg)  { @@ -188,6 +217,15 @@ static DBusHandlerResult err_connection_in_progress(DBusConnection *conn,  			"Connection creation in progress"));  } +static DBusHandlerResult err_connection_not_in_progress(DBusConnection *conn, +							DBusMessage *msg) +{ +	return send_message_and_unref(conn, +			dbus_message_new_error(msg, +			SERIAL_ERROR_INTERFACE".ConnectionNotInProgress", +			"Connection creation not in progress")); +} +  static DBusHandlerResult err_does_not_exist(DBusConnection *conn,  					DBusMessage *msg, const char *str)  { @@ -328,7 +366,11 @@ static gboolean rfcomm_connect_cb_continue(struct pending_connect *pc)  	const char *pname = node_name;  	int fd; -	/* FIXME: Check if it was canceled */ +	if (pc->canceled) { +		rfcomm_release(pc->id); +		err_connection_canceled(pc->conn, pc->msg); +		goto fail; +	}  	/* Check if the caller is still present */  	if (!dbus_bus_name_has_owner(pc->conn, owner, NULL)) { @@ -380,7 +422,10 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan,  	int sk, ret, err, fd;  	socklen_t len; -	/* FIXME: Check if it was canceled */ +	if (pc->canceled) { +		err_connection_canceled(pc->conn, pc->msg); +		goto fail; +	}  	sk = g_io_channel_unix_get_fd(chan); @@ -503,6 +548,11 @@ static void record_reply(DBusPendingCall *call, void *data)  	DBusError derr;  	int len, scanned, ch, err; +	if (pc->canceled) { +		err_connection_canceled(pc->conn, pc->msg); +		goto fail; +	} +  	dbus_error_init(&derr);  	if (dbus_set_error_from_message(&derr, reply)) {  		if (dbus_error_has_name(&derr, @@ -613,6 +663,11 @@ static void handles_reply(DBusPendingCall *call, void *data)  	uint32_t *phandle;  	int len; +	if (pc->canceled) { +		err_connection_canceled(pc->conn, pc->msg); +		goto fail; +	} +  	dbus_error_init(&derr);  	if (dbus_set_error_from_message(&derr, reply)) {  		if (dbus_error_has_name(&derr, @@ -713,6 +768,7 @@ static DBusHandlerResult connect_service(DBusConnection *conn,  	pc->conn = dbus_connection_ref(conn);  	pc->msg = dbus_message_ref(msg);  	pc->bda = g_strdup(bda); +	pc->pattern = g_strdup(pattern);  	pc->adapter_path = g_malloc0(16);  	snprintf(pc->adapter_path, 16, "/org/bluez/hci%d", dev_id); @@ -731,7 +787,6 @@ static DBusHandlerResult connect_service(DBusConnection *conn,  			pending_connect_free(pc);  			return err_not_supported(conn, msg);  		} -  		return DBUS_HANDLER_RESULT_HANDLED;  	} @@ -848,7 +903,32 @@ static DBusHandlerResult disconnect_service(DBusConnection *conn,  static DBusHandlerResult cancel_connect_service(DBusConnection *conn,  						DBusMessage *msg, void *data)  { -	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +	struct pending_connect *pending; +	DBusMessage *reply; +	DBusError derr; +	const char *bda, *pattern; + +	dbus_error_init(&derr); +	if (!dbus_message_get_args(msg, &derr, +				DBUS_TYPE_STRING, &bda, +				DBUS_TYPE_STRING, &pattern, +				DBUS_TYPE_INVALID)) { +		err_invalid_args(conn, msg, derr.message); +		dbus_error_free(&derr); +		return DBUS_HANDLER_RESULT_HANDLED; +	} + +	pending = find_pending_connect_by_pattern(bda, pattern); +	if (!pending) +		return err_connection_not_in_progress(conn, msg); + +	reply = dbus_message_new_method_return(msg); +	if (!reply) +		return DBUS_HANDLER_RESULT_NEED_MEMORY; + +	pending->canceled = 1; + +	return send_message_and_unref(conn, reply);  }  static DBusHandlerResult manager_message(DBusConnection *conn, | 
