iface-modem: fix invalid modem state consolidation
ModemManager has a bogus modem state transition from 'enabling' to 'disabled': ModemManager[26214]: <info> Modem fully enabled... ModemManager[26214]: <info> Modem /org/freedesktop/ModemManager1/Modem/2: state changed (enabling -> disabled) The root cause seems to be the following: get_current_consolidated_state() in MMIfaceModem returns MM_MODEM_STATE_DISABLED as the default fallback value. When mm_iface_modem_update_state() is invoked to transition the modem state from MM_MODEM_STATE_ENABLING to MM_MODEM_STATE_ENABLED, the following code can potentially cause the final state to be MM_MODEM_STATE_DISABLED instead. /* Enabled may really be searching or registered */ if (new_state == MM_MODEM_STATE_ENABLED) new_state = get_current_consolidated_state (self); https://code.google.com/p/chromium-os/issues/detail?id=38173
This commit is contained in:

committed by
Aleksander Morgado

parent
9d5794e9e4
commit
69aff6183a
@@ -205,7 +205,7 @@ mm_iface_modem_wait_for_final_state (MMIfaceModem *self,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static MMModemState get_current_consolidated_state (MMIfaceModem *self);
|
static MMModemState get_current_consolidated_state (MMIfaceModem *self, MMModemState modem_state);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
MMBearer *self;
|
MMBearer *self;
|
||||||
@@ -270,7 +270,7 @@ bearer_status_changed (MMBearer *bearer,
|
|||||||
new_state = MM_MODEM_STATE_DISCONNECTING;
|
new_state = MM_MODEM_STATE_DISCONNECTING;
|
||||||
break;
|
break;
|
||||||
case MM_BEARER_STATUS_DISCONNECTED:
|
case MM_BEARER_STATUS_DISCONNECTED:
|
||||||
new_state = get_current_consolidated_state (self);
|
new_state = get_current_consolidated_state (self, state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1184,7 +1184,7 @@ mm_iface_modem_update_state (MMIfaceModem *self,
|
|||||||
|
|
||||||
/* Enabled may really be searching or registered */
|
/* Enabled may really be searching or registered */
|
||||||
if (new_state == MM_MODEM_STATE_ENABLED)
|
if (new_state == MM_MODEM_STATE_ENABLED)
|
||||||
new_state = get_current_consolidated_state (self);
|
new_state = get_current_consolidated_state (self, new_state);
|
||||||
|
|
||||||
/* Update state only if different */
|
/* Update state only if different */
|
||||||
if (new_state != old_state) {
|
if (new_state != old_state) {
|
||||||
@@ -1260,9 +1260,9 @@ subsystem_state_array_free (GArray *array)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MMModemState
|
static MMModemState
|
||||||
get_current_consolidated_state (MMIfaceModem *self)
|
get_current_consolidated_state (MMIfaceModem *self, MMModemState modem_state)
|
||||||
{
|
{
|
||||||
MMModemState consolidated = MM_MODEM_STATE_DISABLED;
|
MMModemState consolidated = modem_state;
|
||||||
GArray *subsystem_states;
|
GArray *subsystem_states;
|
||||||
|
|
||||||
if (G_UNLIKELY (!state_update_context_quark))
|
if (G_UNLIKELY (!state_update_context_quark))
|
||||||
@@ -1293,6 +1293,7 @@ get_current_consolidated_state (MMIfaceModem *self)
|
|||||||
|
|
||||||
static MMModemState
|
static MMModemState
|
||||||
get_updated_consolidated_state (MMIfaceModem *self,
|
get_updated_consolidated_state (MMIfaceModem *self,
|
||||||
|
MMModemState modem_state,
|
||||||
const gchar *subsystem,
|
const gchar *subsystem,
|
||||||
MMModemState subsystem_state)
|
MMModemState subsystem_state)
|
||||||
{
|
{
|
||||||
@@ -1345,7 +1346,7 @@ get_updated_consolidated_state (MMIfaceModem *self,
|
|||||||
g_array_append_val (subsystem_states, s);
|
g_array_append_val (subsystem_states, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_current_consolidated_state (self);
|
return get_current_consolidated_state (self, modem_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1364,7 +1365,7 @@ mm_iface_modem_update_subsystem_state (MMIfaceModem *self,
|
|||||||
/* We may have different subsystems being handled (e.g. 3GPP and CDMA), and
|
/* We may have different subsystems being handled (e.g. 3GPP and CDMA), and
|
||||||
* the registration status value is unique, so if we get subsystem-specific
|
* the registration status value is unique, so if we get subsystem-specific
|
||||||
* state updates, we'll need to merge all to get a consolidated one. */
|
* state updates, we'll need to merge all to get a consolidated one. */
|
||||||
consolidated = get_updated_consolidated_state (self, subsystem, new_state);
|
consolidated = get_updated_consolidated_state (self, state, subsystem, new_state);
|
||||||
|
|
||||||
/* Don't update registration-related states while disabling/enabling */
|
/* Don't update registration-related states while disabling/enabling */
|
||||||
if (state == MM_MODEM_STATE_ENABLING ||
|
if (state == MM_MODEM_STATE_ENABLING ||
|
||||||
|
Reference in New Issue
Block a user