summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2014-12-27 12:08:49 +0100
committerAleksander Morgado <aleksander@aleksander.es>2014-12-27 12:08:49 +0100
commit946b0a1975149813added3377d269412e2ffa07f (patch)
tree3775b6dc6fa083c65f7e6cec80d28dcae7307dea
parenta982b30d94f1755d501f09f384bf16ad26369add (diff)
downloadModemManager-aleksander/mbim-not-open-2.tar.gz
mbim: if not-opened errors are detected or more than 2 consecutive timeouts, reset the modemaleksander/mbim-not-open-2
When suspending, ModemManager keeps the state of the modem (MBIM open), but the modem itself gets fully reseted and needs an explicit new MBIM open, or otherwise the MBIM port will keep on saying that it was not opened: [/dev/cdc-wdm1] Received message (translated)... >>>>>> Header: >>>>>> length = 16 >>>>>> type = function-error (0x80000004) >>>>>> transaction = 12 >>>>>> Contents: >>>>>> error = 'NotOpened' (0x00000005) Or worse, just timing out. In order to avoid this, we will mark the modem as requesting a reset, so that the Manager object removes all port information and also launches a full automatic reprobing. https://bugs.freedesktop.org/show_bug.cgi?id=84994
-rw-r--r--src/mm-bearer-mbim.c15
-rw-r--r--src/mm-broadband-modem-mbim.c45
-rw-r--r--src/mm-modem-helpers-mbim.c53
-rw-r--r--src/mm-modem-helpers-mbim.h10
-rw-r--r--src/mm-sim-mbim.c25
-rw-r--r--src/mm-sms-mbim.c6
6 files changed, 154 insertions, 0 deletions
diff --git a/src/mm-bearer-mbim.c b/src/mm-bearer-mbim.c
index c554c527c..5d0fc5c94 100644
--- a/src/mm-bearer-mbim.c
+++ b/src/mm-bearer-mbim.c
@@ -181,6 +181,9 @@ ip_configuration_query_ready (MbimDevice *device,
guint32 ipv6mtu;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_BEARER_MODEM, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_ip_configuration_response_parse (
@@ -458,6 +461,9 @@ connect_set_ready (MbimDevice *device,
guint32 nw_error;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_BEARER_MODEM, response, error);
+
if (response &&
(mbim_message_command_done_get_result (response, &error) ||
error->code == MBIM_STATUS_ERROR_FAILURE)) {
@@ -517,6 +523,9 @@ provisioned_contexts_query_ready (MbimDevice *device,
MbimProvisionedContextElement **provisioned_contexts;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_BEARER_MODEM, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_provisioned_contexts_response_parse (
@@ -570,6 +579,9 @@ packet_service_set_ready (MbimDevice *device,
guint64 downlink_speed;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_BEARER_MODEM, response, error);
+
if (response &&
(mbim_message_command_done_get_result (response, &error) ||
error->code == MBIM_STATUS_ERROR_FAILURE)) {
@@ -973,6 +985,9 @@ disconnect_set_ready (MbimDevice *device,
guint32 nw_error;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_BEARER_MODEM, response, error);
+
if (response) {
GError *inner_error = NULL;
gboolean result = FALSE, parsed_result = FALSE;
diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c
index f6891278c..530faf0ee 100644
--- a/src/mm-broadband-modem-mbim.c
+++ b/src/mm-broadband-modem-mbim.c
@@ -168,6 +168,9 @@ device_caps_query_ready (MbimDevice *device,
GError *error = NULL;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_device_caps_response_parse (
@@ -550,6 +553,9 @@ pin_query_ready (MbimDevice *device,
MbimPinState pin_state;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_pin_response_parse (
@@ -595,6 +601,9 @@ unlock_required_subscriber_ready_state_ready (MbimDevice *device,
MbimSubscriberReadyState ready_state = MBIM_SUBSCRIBER_READY_STATE_NOT_INITIALIZED;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_subscriber_ready_status_response_parse (
@@ -743,6 +752,9 @@ pin_query_unlock_retries_ready (MbimDevice *device,
guint32 remaining_attempts;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_pin_response_parse (
@@ -822,6 +834,9 @@ own_numbers_subscriber_ready_state_ready (MbimDevice *device,
gchar **telephone_numbers;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_subscriber_ready_status_response_parse (
@@ -894,6 +909,9 @@ radio_state_query_ready (MbimDevice *device,
MbimRadioSwitchState software_radio_state;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_radio_state_response_parse (
@@ -966,6 +984,9 @@ radio_state_set_down_ready (MbimDevice *device,
GError *error = NULL;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response)
mbim_message_command_done_get_result (response, &error);
@@ -990,6 +1011,9 @@ radio_state_set_up_ready (MbimDevice *device,
MbimRadioSwitchState software_radio_state;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_radio_state_response_parse (
@@ -1440,6 +1464,9 @@ pin_list_query_ready (MbimDevice *device,
MbimPinDesc *pin_desc_corporate_pin;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_pin_list_response_parse (
@@ -1835,6 +1862,9 @@ alert_sms_read_query_ready (MbimDevice *device,
MbimSmsPduReadRecord **pdu_messages;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (self, NULL, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_sms_read_response_parse (
@@ -2082,6 +2112,9 @@ subscribe_list_set_ready_cb (MbimDevice *device,
GError *error = NULL;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response)
mbim_message_command_done_get_result (response, &error);
@@ -2341,6 +2374,9 @@ register_state_query_ready (MbimDevice *device,
gchar *provider_name;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_register_state_response_parse (
@@ -2419,6 +2455,9 @@ register_state_set_ready (MbimDevice *device,
MbimNwError nw_error;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_register_state_response_parse (
@@ -2525,6 +2564,9 @@ visible_providers_query_ready (MbimDevice *device,
GError *error = NULL;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response)
g_simple_async_result_set_op_res_gpointer (ctx->result, response, (GDestroyNotify)mbim_message_unref);
else
@@ -2685,6 +2727,9 @@ sms_read_query_ready (MbimDevice *device,
MbimSmsPduReadRecord **pdu_messages;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, NULL, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_sms_read_response_parse (
diff --git a/src/mm-modem-helpers-mbim.c b/src/mm-modem-helpers-mbim.c
index 36d55023b..d0d44bf75 100644
--- a/src/mm-modem-helpers-mbim.c
+++ b/src/mm-modem-helpers-mbim.c
@@ -18,6 +18,59 @@
#include "mm-enums-types.h"
#include "mm-errors-types.h"
#include "mm-log.h"
+#include "mm-broadband-modem-mbim.h"
+
+/*****************************************************************************/
+
+#define CONSECUTIVE_TIMEOUTS_DATA "consecutive-timeouts"
+#define CONSECUTIVE_TIMEOUTS_MAX 2
+
+void
+mm_track_mbim_status (gpointer obj,
+ const gchar *modem_property_name,
+ const MbimMessage *response,
+ const GError *error)
+{
+ MMBaseModem *modem = NULL;
+
+ g_assert (obj);
+
+ /* Gather modem object */
+ if (modem_property_name) {
+ g_object_get (G_OBJECT (obj), modem_property_name, &modem, NULL);
+ if (!modem)
+ return;
+ } else
+ modem = MM_BASE_MODEM (g_object_ref (obj));
+
+ /* Timeout errors happen directly in the incoming error */
+ if (error && g_error_matches (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_TIMEOUT)) {
+ guint consecutive_timeouts;
+
+ consecutive_timeouts = 1 + GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (modem), CONSECUTIVE_TIMEOUTS_DATA));
+ g_object_set_data (G_OBJECT (modem), CONSECUTIVE_TIMEOUTS_DATA, GUINT_TO_POINTER (consecutive_timeouts));
+ if (consecutive_timeouts >= CONSECUTIVE_TIMEOUTS_MAX) {
+ mm_warn ("MBIM transactions timed out, reporting invalid modem...");
+ mm_base_modem_reset (modem);
+ }
+ } else {
+ GError *inner_error = NULL;
+
+ /* If no timeout, clear consecutive timeout errors */
+ g_object_set_data (G_OBJECT (modem), CONSECUTIVE_TIMEOUTS_DATA, NULL);
+
+ /* Not-opened errors are reported by the modem in a MBIM message */
+ if (response && !mbim_message_command_done_get_result (response, &inner_error)) {
+ if (g_error_matches (inner_error, MBIM_PROTOCOL_ERROR, MBIM_PROTOCOL_ERROR_NOT_OPENED)) {
+ mm_warn ("MBIM device is not opened, reporting invalid modem...");
+ mm_base_modem_reset (modem);
+ }
+ g_error_free (inner_error);
+ }
+ }
+
+ g_object_unref (modem);
+}
/*****************************************************************************/
diff --git a/src/mm-modem-helpers-mbim.h b/src/mm-modem-helpers-mbim.h
index 67b6b57f0..a2d4c32a3 100644
--- a/src/mm-modem-helpers-mbim.h
+++ b/src/mm-modem-helpers-mbim.h
@@ -22,6 +22,16 @@
#include <libmbim-glib.h>
/*****************************************************************************/
+/* Helper to track state of the MBIM device based on command response/errors.
+ * When an invalid state is found in the responses, the modem is directly
+ * reseted. */
+
+void mm_track_mbim_status (gpointer obj,
+ const gchar *modem_property_name,
+ const MbimMessage *response,
+ const GError *error);
+
+/*****************************************************************************/
/* MBIM/BasicConnect to MM translations */
MMModemLock mm_modem_lock_from_mbim_pin_type (MbimPinType pin_type);
diff --git a/src/mm-sim-mbim.c b/src/mm-sim-mbim.c
index e01a3bad2..5d744821c 100644
--- a/src/mm-sim-mbim.c
+++ b/src/mm-sim-mbim.c
@@ -27,6 +27,7 @@
#include "mm-error-helpers.h"
#include "mm-log.h"
#include "mm-sim-mbim.h"
+#include "mm-modem-helpers-mbim.h"
G_DEFINE_TYPE (MMSimMbim, mm_sim_mbim, MM_TYPE_BASE_SIM)
@@ -116,6 +117,9 @@ simid_subscriber_ready_state_ready (MbimDevice *device,
gchar *sim_iccid;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_SIM_MODEM, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_subscriber_ready_status_response_parse (
@@ -183,6 +187,9 @@ imsi_subscriber_ready_state_ready (MbimDevice *device,
gchar *subscriber_id;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_SIM_MODEM, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_subscriber_ready_status_response_parse (
@@ -254,6 +261,9 @@ load_operator_identifier_ready (MbimDevice *device,
MbimProvider *provider;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_SIM_MODEM, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_home_provider_response_parse (
@@ -320,6 +330,9 @@ load_operator_name_ready (MbimDevice *device,
MbimProvider *provider;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_SIM_MODEM, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_home_provider_response_parse (
@@ -381,6 +394,9 @@ pin_set_enter_ready (MbimDevice *device,
MbimPinState pin_state;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_SIM_MODEM, response, error);
+
if (response &&
!mbim_message_command_done_get_result (response, &error)) {
/* Sending PIN failed, build a better error to report */
@@ -471,6 +487,9 @@ puk_set_enter_ready (MbimDevice *device,
guint32 remaining_attempts;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_SIM_MODEM, response, error);
+
if (response &&
!mbim_message_command_done_get_result (response, &error)) {
/* Sending PUK failed, build a better error to report */
@@ -559,6 +578,9 @@ pin_set_enable_ready (MbimDevice *device,
MbimMessage *response;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_SIM_MODEM, response, error);
+
if (response) {
mbim_message_command_done_get_result (response, &error);
mbim_message_unref (response);
@@ -636,6 +658,9 @@ pin_set_change_ready (MbimDevice *device,
MbimMessage *response;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_SIM_MODEM, response, error);
+
if (response) {
mbim_message_command_done_get_result (response, &error);
mbim_message_unref (response);
diff --git a/src/mm-sms-mbim.c b/src/mm-sms-mbim.c
index 3bdd68a93..441723ceb 100644
--- a/src/mm-sms-mbim.c
+++ b/src/mm-sms-mbim.c
@@ -112,6 +112,9 @@ sms_send_set_ready (MbimDevice *device,
guint32 message_reference;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_SMS_MODEM, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error) &&
mbim_message_sms_send_response_parse (
@@ -247,6 +250,9 @@ sms_delete_set_ready (MbimDevice *device,
GError *error = NULL;
response = mbim_device_command_finish (device, res, &error);
+
+ mm_track_mbim_status (ctx->self, MM_BASE_SMS_MODEM, response, error);
+
if (response &&
mbim_message_command_done_get_result (response, &error))
mbim_message_sms_delete_response_parse (response, &error);