modem: fix enable/disable/disconnect flow

NM shouldn't really be calling Enable(False) except in response to
direct user requests to turn off WWAN, much like rfkill, since
Enable(False) /is/ essentially rfkill for 3G.  Instead, we should
be powering up the modem before trying to use it, and only
disconnecting after we're done.  Let the user do enable/disable
when they want to.

This also fixes issues with other devices like GPS potentially
using the modem-manager at the same time as NM and ensures that NM
won't punch the modem in the face while GPS is using it.
This commit is contained in:
Dan Williams
2009-12-21 11:52:15 -08:00
parent d98c431c65
commit 7b10ec29a2
3 changed files with 67 additions and 12 deletions

View File

@@ -115,12 +115,22 @@ create_connect_properties (NMConnection *connection)
return properties;
}
static NMActStageReturn
real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
static void
stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
GError *error = NULL;
NMConnection *connection;
GHashTable *properties;
dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID);
if (error) {
nm_warning ("CDMA modem connection failed: %s", error->message);
g_error_free (error);
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE);
return;
}
connection = nm_act_request_get_connection (nm_device_get_act_request (device));
g_assert (connection);
@@ -130,6 +140,19 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
device, NULL, 120000,
DBUS_TYPE_G_MAP_OF_VARIANT, properties,
G_TYPE_INVALID);
g_hash_table_destroy (properties);
}
static NMActStageReturn
real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
{
gboolean enable = TRUE;
dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (NM_MODEM (device), MM_DBUS_INTERFACE_MODEM),
"Enable", stage1_enable_done,
device, NULL, 20000,
G_TYPE_BOOLEAN, enable,
G_TYPE_INVALID);
return NM_ACT_STAGE_RETURN_POSTPONE;
}

View File

@@ -247,6 +247,34 @@ create_connect_properties (NMConnection *connection)
return properties;
}
static void
stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
GError *error = NULL;
NMConnection *connection;
GHashTable *properties;
dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID);
if (error) {
nm_warning ("GSM modem connection failed: %s", error->message);
g_error_free (error);
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE);
return;
}
connection = nm_act_request_get_connection (nm_device_get_act_request (device));
g_assert (connection);
properties = create_connect_properties (connection);
dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (NM_MODEM (device), MM_DBUS_INTERFACE_MODEM_SIMPLE),
"Connect", stage1_prepare_done,
device, NULL, 120000,
DBUS_TYPE_G_MAP_OF_VARIANT, properties,
G_TYPE_INVALID);
g_hash_table_destroy (properties);
}
static NMActStageReturn
real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
{
@@ -264,13 +292,12 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
setting_name = nm_connection_need_secrets (connection, &hints);
if (!setting_name) {
GHashTable *properties;
gboolean enable = TRUE;
properties = create_connect_properties (connection);
dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (NM_MODEM (device), MM_DBUS_INTERFACE_MODEM_SIMPLE),
"Connect", stage1_prepare_done,
device, NULL, 120000,
DBUS_TYPE_G_MAP_OF_VARIANT, properties,
dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (NM_MODEM (device), MM_DBUS_INTERFACE_MODEM),
"Enable", stage1_enable_done,
device, NULL, 20000,
G_TYPE_BOOLEAN, enable,
G_TYPE_INVALID);
return NM_ACT_STAGE_RETURN_POSTPONE;

View File

@@ -425,6 +425,10 @@ device_state_changed (NMDeviceInterface *device,
{
NMModem *self = NM_MODEM (user_data);
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
gboolean was_connected = FALSE;
if (IS_ACTIVATING_STATE (old_state) || (old_state == NM_DEVICE_STATE_ACTIVATED))
was_connected = TRUE;
/* Make sure we don't leave the serial device open */
switch (new_state) {
@@ -436,10 +440,11 @@ device_state_changed (NMDeviceInterface *device,
case NM_DEVICE_STATE_UNAVAILABLE:
case NM_DEVICE_STATE_FAILED:
case NM_DEVICE_STATE_DISCONNECTED:
dbus_g_proxy_call_no_reply (nm_modem_get_proxy (self, NULL),
"Enable",
G_TYPE_BOOLEAN, FALSE,
G_TYPE_INVALID);
if (was_connected) {
dbus_g_proxy_call_no_reply (nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM),
"Disconnect",
G_TYPE_INVALID);
}
break;
default:
break;