diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-modem-helpers-qmi.c | 175 |
1 files changed, 80 insertions, 95 deletions
diff --git a/src/mm-modem-helpers-qmi.c b/src/mm-modem-helpers-qmi.c index 76e437bc..5f5afb36 100644 --- a/src/mm-modem-helpers-qmi.c +++ b/src/mm-modem-helpers-qmi.c @@ -1804,20 +1804,17 @@ mm_qmi_uim_get_card_status_output_parse (gpointer log_ guint *o_puk2_retries, GError **error) { - GArray *cards; - QmiMessageUimGetCardStatusOutputCardStatusCardsElement *card; + QmiMessageUimGetCardStatusOutputCardStatusCardsElement *card; QmiMessageUimGetCardStatusOutputCardStatusCardsElementApplicationsElement *app; - MMModemLock lock = MM_MODEM_LOCK_UNKNOWN; - guint i; - gint card_i = -1; - gint application_j = -1; - guint n_absent = 0; - guint n_error = 0; - guint n_invalid = 0; + GArray *cards; + guint16 index_gw_primary = 0xFFFF; + guint8 gw_primary_slot_i = 0; + guint8 gw_primary_application_i = 0; + MMModemLock lock = MM_MODEM_LOCK_UNKNOWN; /* This command supports MULTIPLE cards with MULTIPLE applications each. For our - * purposes, we're going to consider as the SIM to use the first card present - * with a SIM/USIM application. */ + * purposes, we're going to consider as the SIM to use the one identified as + * 'primary GW' exclusively. We don't really support Dual Sim Dual Standby yet. */ if (!qmi_message_uim_get_card_status_output_get_result (output, error)) { g_prefix_error (error, "QMI operation failed: "); @@ -1826,7 +1823,7 @@ mm_qmi_uim_get_card_status_output_parse (gpointer log_ qmi_message_uim_get_card_status_output_get_card_status ( output, - NULL, /* index_gw_primary */ + &index_gw_primary, NULL, /* index_1x_primary */ NULL, /* index_gw_secondary */ NULL, /* index_1x_secondary */ @@ -1839,103 +1836,91 @@ mm_qmi_uim_get_card_status_output_parse (gpointer log_ return FALSE; } - if (cards->len > 1) - mm_obj_dbg (log_object, "multiple cards reported: %u", cards->len); - - /* All KNOWN applications in all cards will need to be in READY state for us - * to consider UNLOCKED */ - for (i = 0; i < cards->len; i++) { - card = &g_array_index (cards, QmiMessageUimGetCardStatusOutputCardStatusCardsElement, i); - - switch (card->card_state) { - case QMI_UIM_CARD_STATE_PRESENT: { - guint j; - gboolean sim_usim_found = FALSE; - - if (card->applications->len == 0) { - mm_obj_dbg (log_object, "no applications reported in card [%u]", i); - n_invalid++; - break; - } + /* Look for the primary GW slot and application. + * If we don't have valid GW primary slot index and application index, assume + * we're missing the SIM altogether */ + gw_primary_slot_i = ((index_gw_primary & 0xFF00) >> 8); + gw_primary_application_i = ((index_gw_primary & 0x00FF)); - if (card->applications->len > 1) - mm_obj_dbg (log_object, "multiple applications reported in card [%u]: %u", i, card->applications->len); + if (gw_primary_slot_i == 0xFF) { + g_set_error (error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED, + "GW primary session index unknown"); + return FALSE; + } + mm_obj_dbg (log_object, "GW primary session index: %u", gw_primary_slot_i); - for (j = 0; j < card->applications->len; j++) { - app = &g_array_index (card->applications, QmiMessageUimGetCardStatusOutputCardStatusCardsElementApplicationsElement, j); + if (gw_primary_application_i == 0xFF) { + g_set_error (error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED, + "GW primary application index unknown"); + return FALSE; + } + mm_obj_dbg (log_object, "GW primary application index: %u", gw_primary_application_i); - if (app->type == QMI_UIM_CARD_APPLICATION_TYPE_UNKNOWN) { - mm_obj_dbg (log_object, "mnknown application [%u] found in card [%u]: %s; ignored.", - j, i, qmi_uim_card_application_state_get_string (app->state)); - continue; - } + /* Validate slot index */ + if (gw_primary_slot_i >= cards->len) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Invalid GW primary session index: %u", + gw_primary_slot_i); + return FALSE; + } - mm_obj_dbg (log_object, "application '%s' [%u] in card [%u]: %s", - qmi_uim_card_application_type_get_string (app->type), j, i, qmi_uim_card_application_state_get_string (app->state)); + /* Get card at slot */ + card = &g_array_index (cards, QmiMessageUimGetCardStatusOutputCardStatusCardsElement, gw_primary_slot_i); - if (app->type == QMI_UIM_CARD_APPLICATION_TYPE_SIM || app->type == QMI_UIM_CARD_APPLICATION_TYPE_USIM) { - /* We found the card/app pair to use! Only keep the first found, - * but still, keep on looping to log about the remaining ones */ - if (card_i < 0 && application_j < 0) { - card_i = i; - application_j = j; - } + if (card->card_state == QMI_UIM_CARD_STATE_ABSENT) { + g_set_error (error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED, + "No card found"); + return FALSE; + } - sim_usim_found = TRUE; - } - } + if (card->card_state == QMI_UIM_CARD_STATE_ERROR) { + const gchar *card_error; - if (!sim_usim_found) { - mm_obj_dbg (log_object, "no SIM/USIM application found in card [%u]", i); - n_invalid++; - } + card_error = qmi_uim_card_error_get_string (card->error_code); + g_set_error (error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG, + "Card error: %s", card_error ? card_error : "unknown error"); + return FALSE; + } - break; - } + if (card->card_state != QMI_UIM_CARD_STATE_PRESENT) { + g_set_error (error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG, + "Card error: unexpected card state: 0x%x", card->card_state); + return FALSE; + } - case QMI_UIM_CARD_STATE_ABSENT: - mm_obj_dbg (log_object, "card '%u' is absent", i); - n_absent++; - break; + /* Card is present */ - case QMI_UIM_CARD_STATE_ERROR: - default: - n_error++; - if (qmi_uim_card_error_get_string (card->error_code) != NULL) - mm_obj_warn (log_object, "card '%u' is unusable: %s", i, qmi_uim_card_error_get_string (card->error_code)); - else - mm_obj_warn (log_object, "card '%u' is unusable: unknown error", i); - break; - } + if (card->applications->len == 0) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "No applications reported in card"); + return FALSE; + } - /* go on to next card */ - } - - /* If we found no card/app to use, we need to report an error */ - if (card_i < 0 || application_j < 0) { - /* If not a single card found, report SIM not inserted */ - if (n_absent > 0 && !n_error && !n_invalid) - g_set_error (error, - MM_MOBILE_EQUIPMENT_ERROR, - MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED, - "No card found"); - else if (n_error > 0) - g_set_error (error, - MM_MOBILE_EQUIPMENT_ERROR, - MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG, - "Card error"); - else - g_set_error (error, - MM_MOBILE_EQUIPMENT_ERROR, - MM_MOBILE_EQUIPMENT_ERROR_SIM_FAILURE, - "Card failure: %u absent, %u errors, %u invalid", - n_absent, n_error, n_invalid); + /* Validate application index */ + if (gw_primary_application_i >= card->applications->len) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Invalid GW primary application index: %u", + gw_primary_application_i); return FALSE; } - /* Get card/app to use */ - card = &g_array_index (cards, QmiMessageUimGetCardStatusOutputCardStatusCardsElement, card_i); - app = &g_array_index (card->applications, QmiMessageUimGetCardStatusOutputCardStatusCardsElementApplicationsElement, application_j); + app = &g_array_index (card->applications, QmiMessageUimGetCardStatusOutputCardStatusCardsElementApplicationsElement, gw_primary_application_i); + if ((app->type != QMI_UIM_CARD_APPLICATION_TYPE_SIM) && (app->type != QMI_UIM_CARD_APPLICATION_TYPE_USIM)) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Unsupported application type found in GW primary application index: %s", + qmi_uim_card_application_type_get_string (app->type)); + return FALSE; + } /* If card not ready yet, return RETRY error. * If the application state reports needing PIN/PUk, consider that ready as |