about summary refs log tree commit diff
path: root/src/modem-manager/nm-modem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/modem-manager/nm-modem.c')
-rw-r--r--src/modem-manager/nm-modem.c217
1 files changed, 127 insertions, 90 deletions
diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c
index 9471ef87..33f10789 100644
--- a/src/modem-manager/nm-modem.c
+++ b/src/modem-manager/nm-modem.c
@@ -15,7 +15,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
+ * Copyright (C) 2009 - 2011 Red Hat, Inc.
  * Copyright (C) 2009 Novell, Inc.
  */
 
@@ -33,8 +33,6 @@
 #include "nm-device-interface.h"
 #include "nm-dbus-glib-types.h"
 
-#include "nm-serial-device-glue.h"
-
 G_DEFINE_TYPE (NMModem, nm_modem, G_TYPE_OBJECT)
 
 #define NM_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM, NMModemPrivate))
@@ -62,7 +60,9 @@ typedef struct {
 	char *device;
 	char *iface;
 
+	NMActRequest *act_request;
 	guint32 secrets_tries;
+	guint32 secrets_id;
 
 	DBusGProxyCall *call;
 
@@ -78,7 +78,8 @@ enum {
 	PPP_FAILED,
 	PREPARE_RESULT,
 	IP4_CONFIG_RESULT,
-	NEED_AUTH,
+	AUTH_REQUESTED,
+	AUTH_RESULT,
 
 	LAST_SIGNAL
 };
@@ -467,67 +468,60 @@ nm_modem_stage4_get_ip4_config (NMModem *self,
 	return ret;
 }
 
-gboolean
-nm_modem_connection_secrets_updated (NMModem *self,
-                                     NMActRequest *req,
-                                     NMConnection *connection,
-                                     GSList *updated_settings,
-                                     RequestSecretsCaller caller)
+static void
+cancel_get_secrets (NMModem *self)
 {
-	NMModemPrivate *priv;
-	gboolean found = FALSE;
-	const char *setting_name;
-	GSList *iter;
-
-	g_return_val_if_fail (self != NULL, FALSE);
-	g_return_val_if_fail (NM_IS_MODEM (self), FALSE);
-	g_return_val_if_fail (req != NULL, FALSE);
-	g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
-	g_return_val_if_fail (connection != NULL, FALSE);
-	g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
-
-	priv = NM_MODEM_GET_PRIVATE (self);
+	NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
 
-	if (caller == SECRETS_CALLER_PPP) {
-		const char *user = NULL;
-		const char *pass = NULL;
-
-		g_return_val_if_fail (priv->ppp_manager != NULL, FALSE);
-
-		if (!NM_MODEM_GET_CLASS (self)->get_user_pass (self, connection, &user, &pass)) {
-			/* Shouldn't ever happen */
-			nm_ppp_manager_update_secrets (priv->ppp_manager,
-										   priv->iface,
-										   NULL,
-										   NULL,
-										   "missing GSM/CDMA setting; no secrets could be found.");
-		} else {
-			nm_ppp_manager_update_secrets (priv->ppp_manager,
-										   priv->iface,
-										   user ? user : "",
-										   pass ? pass : "",
-										   NULL);
-		}
-		return TRUE;
+	if (priv->secrets_id) {
+		nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id);
+		priv->secrets_id = 0;
 	}
+}
 
-	g_return_val_if_fail (caller == SECRETS_CALLER_MOBILE_BROADBAND, FALSE);
+static void
+modem_secrets_cb (NMActRequest *req,
+                  guint32 call_id,
+                  NMConnection *connection,
+                  GError *error,
+                  gpointer user_data)
+{
+	NMModem *self = NM_MODEM (user_data);
+	NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
 
-	g_assert (NM_MODEM_GET_CLASS (self)->get_setting_name);
-	setting_name = NM_MODEM_GET_CLASS (self)->get_setting_name (self);
+	g_return_if_fail (call_id == priv->secrets_id);
 
-	for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
-		const char *candidate_setting_name = (const char *) iter->data;
+	priv->secrets_id = 0;
 
-		if (!strcmp (candidate_setting_name, setting_name))
-			found = TRUE;
-		else {
-			nm_log_warn (LOGD_MB, "ignoring updated secrets for setting '%s'.",
-			            candidate_setting_name);
-		}
-	}
+	if (error)
+		nm_log_warn (LOGD_MB, "%s", error->message);
 
-	return found;
+	g_signal_emit (self, signals[AUTH_RESULT], 0, error);
+}
+
+gboolean
+nm_modem_get_secrets (NMModem *self,
+                      const char *setting_name,
+                      gboolean request_new,
+                      const char *hint)
+{
+	NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
+	NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION;
+
+	cancel_get_secrets (self);
+
+	if (request_new)
+		flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW;
+	priv->secrets_id = nm_act_request_get_secrets (priv->act_request,
+	                                               setting_name,
+	                                               flags,
+	                                               hint,
+	                                               modem_secrets_cb,
+	                                               self);
+	if (priv->secrets_id)
+		g_signal_emit (self, signals[AUTH_REQUESTED], 0);
+
+	return !!(priv->secrets_id);
 }
 
 static NMActStageReturn
@@ -550,6 +544,11 @@ nm_modem_act_stage1_prepare (NMModem *self,
 	NMActStageReturn ret;
 	GPtrArray *hints = NULL;
 	const char *setting_name = NULL;
+	NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION;
+
+	if (priv->act_request)
+		g_object_unref (priv->act_request);
+	priv->act_request = g_object_ref (req);
 
 	ret = NM_MODEM_GET_CLASS (self)->act_stage1_prepare (self,
 	                                                     req,
@@ -557,23 +556,22 @@ nm_modem_act_stage1_prepare (NMModem *self,
 	                                                     &setting_name,
 	                                                     reason);
 	if ((ret == NM_ACT_STAGE_RETURN_POSTPONE) && setting_name) {
-		const char *hint1 = NULL, *hint2 = NULL;
-
-		/* Need some secrets */
-		if (hints) {
-			if (hints->len > 0)
-				hint1 = g_ptr_array_index (hints, 0);
-			if (hints->len > 1)
-				hint2 = g_ptr_array_index (hints, 1);
+		if (priv->secrets_tries++)
+			flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW;
+
+		priv->secrets_id = nm_act_request_get_secrets (req,
+		                                               setting_name,
+		                                               flags,
+		                                               hints ? g_ptr_array_index (hints, 0) : NULL,
+		                                               modem_secrets_cb,
+		                                               self);
+		if (priv->secrets_id)
+			g_signal_emit (self, signals[AUTH_REQUESTED], 0);
+		else {
+			*reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
+			ret = NM_ACT_STAGE_RETURN_FAILURE;
 		}
 
-		g_signal_emit (self, signals[NEED_AUTH], 0,
-		               setting_name, 
-	                   priv->secrets_tries++ ? TRUE : FALSE,
-	                   SECRETS_CALLER_MOBILE_BROADBAND,
-	                   hint1,
-	                   hint2);
-
 		if (hints)
 			g_ptr_array_free (hints, TRUE);
 	}
@@ -616,8 +614,19 @@ nm_modem_check_connection_compatible (NMModem *self,
 	return FALSE;
 }
 
+gboolean
+nm_modem_complete_connection (NMModem *self,
+                              NMConnection *connection,
+                              const GSList *existing_connections,
+                              GError **error)
+{
+	if (NM_MODEM_GET_CLASS (self)->complete_connection)
+		return NM_MODEM_GET_CLASS (self)->complete_connection (self, connection, existing_connections, error);
+	return FALSE;
+}
+
 static void
-real_deactivate_quickly (NMModem *self, NMDevice *device)
+real_deactivate (NMModem *self, NMDevice *device)
 {
 	NMModemPrivate *priv;
 	const char *iface;
@@ -631,6 +640,12 @@ real_deactivate_quickly (NMModem *self, NMDevice *device)
 
 	priv->secrets_tries = 0;
 
+	if (priv->act_request) {
+		cancel_get_secrets (self);
+		g_object_unref (priv->act_request);
+		priv->act_request = NULL;
+	}
+
 	if (priv->call) {
 		dbus_g_proxy_cancel_call (priv->proxy, priv->call);
 		priv->call = NULL;
@@ -666,9 +681,9 @@ real_deactivate_quickly (NMModem *self, NMDevice *device)
 }
 
 void
-nm_modem_deactivate_quickly (NMModem *self, NMDevice *device)
+nm_modem_deactivate (NMModem *self, NMDevice *device)
 {
-	NM_MODEM_GET_CLASS (self)->deactivate_quickly (self, device);
+	NM_MODEM_GET_CLASS (self)->deactivate (self, device);
 }
 
 static void
@@ -690,6 +705,7 @@ nm_modem_device_state_changed (NMModem *self,
                                NMDeviceStateReason reason)
 {
 	gboolean was_connected = FALSE;
+	NMModemPrivate *priv;
 
 	g_return_if_fail (self != NULL);
 	g_return_if_fail (NM_IS_MODEM (self));
@@ -697,16 +713,26 @@ nm_modem_device_state_changed (NMModem *self,
 	if (IS_ACTIVATING_STATE (old_state) || (old_state == NM_DEVICE_STATE_ACTIVATED))
 		was_connected = TRUE;
 
+	priv = NM_MODEM_GET_PRIVATE (self);
+
 	/* Make sure we don't leave the serial device open */
 	switch (new_state) {
 	case NM_DEVICE_STATE_NEED_AUTH:
-		if (NM_MODEM_GET_PRIVATE (self)->ppp_manager)
+		if (priv->ppp_manager)
 			break;
 		/* else fall through */
 	case NM_DEVICE_STATE_UNMANAGED:
 	case NM_DEVICE_STATE_UNAVAILABLE:
 	case NM_DEVICE_STATE_FAILED:
 	case NM_DEVICE_STATE_DISCONNECTED:
+		if (new_state != NM_DEVICE_STATE_NEED_AUTH) {
+			if (priv->act_request) {
+				cancel_get_secrets (self);
+				g_object_unref (priv->act_request);
+				priv->act_request = NULL;
+			}
+		}
+
 		if (was_connected) {
 			dbus_g_proxy_begin_call (nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM),
 			                         "Disconnect",
@@ -721,6 +747,12 @@ nm_modem_device_state_changed (NMModem *self,
 	}
 }
 
+static gboolean
+_state_is_active (NMDeviceState state)
+{
+	return (state >= NM_DEVICE_STATE_IP_CONFIG && state <= NM_DEVICE_STATE_DEACTIVATING);
+}
+
 gboolean
 nm_modem_hw_is_up (NMModem *self, NMDevice *device)
 {
@@ -731,7 +763,7 @@ nm_modem_hw_is_up (NMModem *self, NMDevice *device)
 		NMDeviceState state;
 
 		state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
-		if (priv->pending_ip4_config || state == NM_DEVICE_STATE_IP_CONFIG || state == NM_DEVICE_STATE_ACTIVATED)
+		if (priv->pending_ip4_config || _state_is_active (state))
 			return nm_system_device_is_up (device);
 	}
 
@@ -748,7 +780,7 @@ nm_modem_hw_bring_up (NMModem *self, NMDevice *device, gboolean *no_firmware)
 		NMDeviceState state;
 
 		state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
-		if (priv->pending_ip4_config || state == NM_DEVICE_STATE_IP_CONFIG || state == NM_DEVICE_STATE_ACTIVATED)
+		if (priv->pending_ip4_config || _state_is_active (state))
 			return nm_system_device_set_up_down (device, TRUE, no_firmware);
 	}
 
@@ -1015,6 +1047,9 @@ finalize (GObject *object)
 {
 	NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object);
 
+	if (priv->act_request)
+		g_object_unref (priv->act_request);
+
 	if (priv->proxy)
 		g_object_unref (priv->proxy);
 
@@ -1044,7 +1079,7 @@ nm_modem_class_init (NMModemClass *klass)
 	object_class->finalize = finalize;
 
 	klass->act_stage1_prepare = real_act_stage1_prepare;
-	klass->deactivate_quickly = real_deactivate_quickly;
+	klass->deactivate = real_deactivate;
 
 	/* Properties */
 	g_object_class_install_property
@@ -1127,20 +1162,22 @@ nm_modem_class_init (NMModemClass *klass)
 					  _nm_marshal_VOID__BOOLEAN_UINT,
 					  G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_UINT);
 
-	signals[NEED_AUTH] =
-		g_signal_new (NM_MODEM_NEED_AUTH,
+	signals[AUTH_REQUESTED] =
+		g_signal_new (NM_MODEM_AUTH_REQUESTED,
 					  G_OBJECT_CLASS_TYPE (object_class),
 					  G_SIGNAL_RUN_FIRST,
-					  G_STRUCT_OFFSET (NMModemClass, need_auth),
+					  G_STRUCT_OFFSET (NMModemClass, auth_requested),
 					  NULL, NULL,
-					  _nm_marshal_VOID__STRING_BOOLEAN_UINT_STRING_STRING,
-					  G_TYPE_NONE, 5,
-					  G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
-}
+					  g_cclosure_marshal_VOID__VOID,
+					  G_TYPE_NONE, 0);
 
-const DBusGObjectInfo *
-nm_modem_get_serial_dbus_info (void)
-{
-	return &dbus_glib_nm_serial_device_object_info;
+	signals[AUTH_RESULT] =
+		g_signal_new (NM_MODEM_AUTH_RESULT,
+					  G_OBJECT_CLASS_TYPE (object_class),
+					  G_SIGNAL_RUN_FIRST,
+					  G_STRUCT_OFFSET (NMModemClass, auth_result),
+					  NULL, NULL,
+					  g_cclosure_marshal_VOID__POINTER,
+					  G_TYPE_NONE, 1, G_TYPE_POINTER);
 }