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:
@@ -115,12 +115,22 @@ create_connect_properties (NMConnection *connection)
|
|||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NMActStageReturn
|
static void
|
||||||
real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
|
||||||
{
|
{
|
||||||
|
NMDevice *device = NM_DEVICE (user_data);
|
||||||
|
GError *error = NULL;
|
||||||
NMConnection *connection;
|
NMConnection *connection;
|
||||||
GHashTable *properties;
|
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));
|
connection = nm_act_request_get_connection (nm_device_get_act_request (device));
|
||||||
g_assert (connection);
|
g_assert (connection);
|
||||||
|
|
||||||
@@ -130,6 +140,19 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
|||||||
device, NULL, 120000,
|
device, NULL, 120000,
|
||||||
DBUS_TYPE_G_MAP_OF_VARIANT, properties,
|
DBUS_TYPE_G_MAP_OF_VARIANT, properties,
|
||||||
G_TYPE_INVALID);
|
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;
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
||||||
}
|
}
|
||||||
|
@@ -247,6 +247,34 @@ create_connect_properties (NMConnection *connection)
|
|||||||
return properties;
|
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
|
static NMActStageReturn
|
||||||
real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
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);
|
setting_name = nm_connection_need_secrets (connection, &hints);
|
||||||
if (!setting_name) {
|
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),
|
||||||
dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (NM_MODEM (device), MM_DBUS_INTERFACE_MODEM_SIMPLE),
|
"Enable", stage1_enable_done,
|
||||||
"Connect", stage1_prepare_done,
|
device, NULL, 20000,
|
||||||
device, NULL, 120000,
|
G_TYPE_BOOLEAN, enable,
|
||||||
DBUS_TYPE_G_MAP_OF_VARIANT, properties,
|
|
||||||
G_TYPE_INVALID);
|
G_TYPE_INVALID);
|
||||||
|
|
||||||
return NM_ACT_STAGE_RETURN_POSTPONE;
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
||||||
|
@@ -425,6 +425,10 @@ device_state_changed (NMDeviceInterface *device,
|
|||||||
{
|
{
|
||||||
NMModem *self = NM_MODEM (user_data);
|
NMModem *self = NM_MODEM (user_data);
|
||||||
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
|
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 */
|
/* Make sure we don't leave the serial device open */
|
||||||
switch (new_state) {
|
switch (new_state) {
|
||||||
@@ -436,10 +440,11 @@ device_state_changed (NMDeviceInterface *device,
|
|||||||
case NM_DEVICE_STATE_UNAVAILABLE:
|
case NM_DEVICE_STATE_UNAVAILABLE:
|
||||||
case NM_DEVICE_STATE_FAILED:
|
case NM_DEVICE_STATE_FAILED:
|
||||||
case NM_DEVICE_STATE_DISCONNECTED:
|
case NM_DEVICE_STATE_DISCONNECTED:
|
||||||
dbus_g_proxy_call_no_reply (nm_modem_get_proxy (self, NULL),
|
if (was_connected) {
|
||||||
"Enable",
|
dbus_g_proxy_call_no_reply (nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM),
|
||||||
G_TYPE_BOOLEAN, FALSE,
|
"Disconnect",
|
||||||
G_TYPE_INVALID);
|
G_TYPE_INVALID);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user