cdma: fix subclass registration state checking in error paths (rh #569067)

The generic CDMA superclass already checks minimal registration state,
and when some of the additional query_registration_state() subclass checks
were being performed, if the device returned an error (if it didn't support
the subclass' specific registration command like *STATE or ^SYSINFO) the
superclass' registration state checks would be thrown away.

Fix that by specifying the behavior of the subclass'
query_registration_state() methods to ignore most errors and leave the
superclass' registration state intact if a non-critical error occurs.
This commit is contained in:
Dan Williams
2010-04-05 18:46:53 -07:00
parent 49c363d83a
commit f3dd034aad
5 changed files with 153 additions and 120 deletions
+12 -33
View File
@@ -123,15 +123,8 @@ evdo_state_done (MMAtSerialPort *port,
GRegex *r;
GMatchInfo *match_info;
info->error = mm_modem_check_removed (info->modem, error);
if (info->error) {
if (info->modem) {
/* If HSTATE returned an error, assume the device is not EVDO capable
* or EVDO is not registered.
*/
mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
}
if (error) {
/* Leave superclass' reg state alone if AT*HSTATE isn't supported */
mm_callback_info_schedule (info);
return;
}
@@ -143,13 +136,8 @@ evdo_state_done (MMAtSerialPort *port,
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
if (!r) {
/* Parse error; warn about it and assume EVDO is not available */
g_warning ("AnyData(%s): failed to create EVDO state regex: (%d) %s",
__func__,
error ? error->code : -1,
error && error->message ? error->message : "(unknown)");
mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
mm_callback_info_schedule (info);
return;
g_warning ("AnyDATA(%s): *HSTATE parse regex creation failed.", __func__);
goto done;
}
g_regex_match (r, reply, 0, &match_info);
@@ -185,8 +173,8 @@ evdo_state_done (MMAtSerialPort *port,
}
}
done:
mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, reg_state);
mm_callback_info_schedule (info);
}
@@ -202,17 +190,8 @@ state_done (MMAtSerialPort *port,
GRegex *r;
GMatchInfo *match_info;
info->error = mm_modem_check_removed (info->modem, error);
if (info->error) {
if (info->modem) {
/* Assume if we got this far, we're registered even if an error
* occurred. We're not sure if all AnyData CDMA modems support
* the *STATE and *HSTATE commands.
*/
mm_generic_cdma_query_reg_state_set_callback_1x_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED);
mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
}
if (error) {
/* Leave superclass' reg state alone if AT*STATE isn't supported */
mm_callback_info_schedule (info);
return;
}
@@ -223,9 +202,7 @@ state_done (MMAtSerialPort *port,
r = g_regex_new ("\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*([^,\\)]*)\\s*,.*",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
if (!r) {
info->error = g_error_new_literal (MM_MODEM_ERROR,
MM_MODEM_ERROR_GENERAL,
"Could not parse sysinfo results (regex creation failed).");
g_warning ("AnyDATA(%s): *STATE parse regex creation failed.", __func__);
mm_callback_info_schedule (info);
return;
}
@@ -254,7 +231,7 @@ state_done (MMAtSerialPort *port,
reg_state = MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED;
break;
default:
g_message ("ANYDATA: unknown *STATE (%d); assuming no service.", val);
g_warning ("ANYDATA: unknown *STATE (%d); assuming no service.", val);
/* fall through */
case 0: /* NO SERVICE */
break;
@@ -270,13 +247,15 @@ state_done (MMAtSerialPort *port,
static void
query_registration_state (MMGenericCdma *cdma,
MMModemCdmaRegistrationState cur_cdma_state,
MMModemCdmaRegistrationState cur_evdo_state,
MMModemCdmaRegistrationStateFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
MMAtSerialPort *port;
info = mm_generic_cdma_query_reg_state_callback_info_new (cdma, callback, user_data);
info = mm_generic_cdma_query_reg_state_callback_info_new (cdma, cur_cdma_state, cur_evdo_state, callback, user_data);
port = mm_generic_cdma_get_best_at_port (cdma, &info->error);
if (!port) {
+9 -17
View File
@@ -161,12 +161,10 @@ sysinfo_done (MMAtSerialPort *port,
GRegex *r;
GMatchInfo *match_info;
const char *reply;
gboolean success = FALSE;
if (error) {
info->error = g_error_copy (error);
mm_callback_info_schedule (info);
return;
/* Leave superclass' reg state alone if AT^SYSINFO isn't supported */
goto done;
}
reply = strip_response (response->str, "^SYSINFO:");
@@ -175,9 +173,7 @@ sysinfo_done (MMAtSerialPort *port,
r = g_regex_new ("\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
if (!r) {
info->error = g_error_new_literal (MM_MODEM_ERROR,
MM_MODEM_ERROR_GENERAL,
"Could not parse sysinfo results (regex creation failed).");
g_warning ("Huawei(%s): ^SYSINFO parse regex creation failed.", __func__);
goto done;
}
@@ -217,31 +213,27 @@ sysinfo_done (MMAtSerialPort *port,
/* Say we're registered to something even though sysmode parsing failed */
mm_generic_cdma_query_reg_state_set_callback_1x_state (info, reg_state);
}
success = TRUE;
}
} else
g_warning ("Huawei(%s): failed to parse ^SYSINFO response.", __func__);
done:
g_match_info_free (match_info);
g_regex_unref (r);
if (!success && !info->error) {
info->error = g_error_new_literal (MM_MODEM_ERROR,
MM_MODEM_ERROR_GENERAL,
"Could not parse sysinfo results.");
}
done:
mm_callback_info_schedule (info);
}
static void
query_registration_state (MMGenericCdma *cdma,
MMModemCdmaRegistrationState cur_cdma_state,
MMModemCdmaRegistrationState cur_evdo_state,
MMModemCdmaRegistrationStateFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
MMAtSerialPort *port;
info = mm_generic_cdma_query_reg_state_callback_info_new (cdma, callback, user_data);
info = mm_generic_cdma_query_reg_state_callback_info_new (cdma, cur_cdma_state, cur_evdo_state, callback, user_data);
port = mm_generic_cdma_get_best_at_port (cdma, &info->error);
if (!port) {
+5 -3
View File
@@ -125,13 +125,13 @@ status_done (MMAtSerialPort *port,
gboolean cdma_1x_set = FALSE, evdo_set = FALSE;
if (error) {
info->error = g_error_copy (error);
/* Leave superclass' reg state alone if AT!STATUS isn't supported */
goto done;
}
lines = g_strsplit_set (response->str, "\n\r", 0);
if (!lines) {
/* Whatever, just use default registration state */
/* Whatever, just use superclass' registration state */
goto done;
}
@@ -289,13 +289,15 @@ done:
static void
query_registration_state (MMGenericCdma *cdma,
MMModemCdmaRegistrationState cur_cdma_state,
MMModemCdmaRegistrationState cur_evdo_state,
MMModemCdmaRegistrationStateFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
MMAtSerialPort *port;
info = mm_generic_cdma_query_reg_state_callback_info_new (cdma, callback, user_data);
info = mm_generic_cdma_query_reg_state_callback_info_new (cdma, cur_cdma_state, cur_evdo_state, callback, user_data);
port = mm_generic_cdma_get_best_at_port (cdma, &info->error);
if (!port) {