aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-10-11 09:23:49 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-10-11 09:23:49 +0200
commit014d0688ff2eebd5ef821ef74e20ba704b52634d (patch)
tree164821926361d2670968c5e4e8e5d8de4eac870c /src
parentba64c49f3689f6fbc4dd740a39941b691768b04a (diff)
core,qmi: don't assume QMI port is always available
When the modem gets unplugged all ports disappear from the modem, so don't assume the port is always given. E.g. if the unplug happens in the middle of the initialization sequence we may end up with nasty segfaults: Crash reason: SIGSEGV Crash address: 0x0 Thread 0 (crashed) 0 ModemManager!mm_qmi_port_peek_client [mm-qmi-port.c : 50 + 0x0] rbx = 0x00007fbb5c1d8010 r12 = 0x0000000000000003 r13 = 0x00007fbb5c1f9880 r14 = 0x00007fbb59a30980 r15 = 0x00007fbb5c187a60 rip = 0x00007fbb5a1a54c0 rsp = 0x00007fffc6c0f628 rbp = 0x00007fffc6c0f650 Found by: given as instruction pointer in context 1 ModemManager!peek_qmi_client [mm-broadband-modem-qmi.c : 109 + 0x24] rbx = 0x00007fbb5c1d8010 r12 = 0x0000000000000003 r13 = 0x00007fbb5c1f9880 r14 = 0x00007fbb59a30980 r15 = 0x00007fbb5c187a60 rip = 0x00007fbb5a193851 rsp = 0x00007fffc6c0f630 rbp = 0x00007fffc6c0f650 Found by: call frame info 2 ModemManager!ensure_qmi_client [mm-broadband-modem-qmi.c : 132 + 0x4] rbx = 0x00007fbb5c1d8010 r12 = 0x00007fbb5a165140 r13 = 0x00007fbb5c1f9880 r14 = 0x00007fbb59a30980 r15 = 0x00007fbb5c187a60 rip = 0x00007fbb5a1938e4 rsp = 0x00007fffc6c0f650 rbp = 0x00007fffc6c0f690 Found by: call frame info ... Reported by: Ben Chan <benchan@chromium.org>
Diffstat (limited to 'src')
-rw-r--r--src/mm-broadband-modem-qmi.c45
-rw-r--r--src/mm-sim-qmi.c26
-rw-r--r--src/mm-sms-qmi.c26
3 files changed, 76 insertions, 21 deletions
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c
index d781301f..7a6f13ed 100644
--- a/src/mm-broadband-modem-qmi.c
+++ b/src/mm-broadband-modem-qmi.c
@@ -104,9 +104,19 @@ peek_qmi_client (MMBroadbandModemQmi *self,
QmiService service,
GError **error)
{
+ MMQmiPort *port;
QmiClient *client;
- client = mm_qmi_port_peek_client (mm_base_modem_peek_port_qmi (MM_BASE_MODEM (self)),
+ port = mm_base_modem_peek_port_qmi (MM_BASE_MODEM (self));
+ if (!port) {
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Couldn't peek QMI port");
+ return NULL;
+ }
+
+ client = mm_qmi_port_peek_client (port,
service,
MM_QMI_PORT_FLAG_DEFAULT);
if (!client)
@@ -4941,16 +4951,21 @@ messaging_check_support (MMIfaceModemMessaging *self,
{
GSimpleAsyncResult *result;
gboolean supported;
+ MMQmiPort *port;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
messaging_check_support);
- /* If we have support for the WMS client, messaging is supported */
- supported = !!mm_qmi_port_peek_client (mm_base_modem_peek_port_qmi (MM_BASE_MODEM (self)),
- QMI_SERVICE_WMS,
- MM_QMI_PORT_FLAG_DEFAULT);
+ port = mm_base_modem_peek_port_qmi (MM_BASE_MODEM (self));
+ if (!port)
+ supported = FALSE;
+ else
+ /* If we have support for the WMS client, messaging is supported */
+ supported = !!mm_qmi_port_peek_client (port,
+ QMI_SERVICE_WMS,
+ MM_QMI_PORT_FLAG_DEFAULT);
/* We only handle 3GPP messaging (PDU based) currently, so just ignore
* CDMA-only QMI modems */
@@ -5673,6 +5688,7 @@ parent_load_capabilities_ready (MMIfaceModemLocation *self,
{
MMModemLocationSource sources;
GError *error = NULL;
+ MMQmiPort *port;
sources = iface_modem_location_parent->load_capabilities_finish (self, res, &error);
if (error) {
@@ -5682,11 +5698,13 @@ parent_load_capabilities_ready (MMIfaceModemLocation *self,
return;
}
+ port = mm_base_modem_peek_port_qmi (MM_BASE_MODEM (self));
+
/* Now our own check.
* If we have support for the PDS client, GPS location is supported */
- if (mm_qmi_port_peek_client (mm_base_modem_peek_port_qmi (MM_BASE_MODEM (self)),
- QMI_SERVICE_PDS,
- MM_QMI_PORT_FLAG_DEFAULT))
+ if (port && mm_qmi_port_peek_client (port,
+ QMI_SERVICE_PDS,
+ MM_QMI_PORT_FLAG_DEFAULT))
sources |= (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | MM_MODEM_LOCATION_SOURCE_GPS_RAW);
/* So we're done, complete */
@@ -6931,7 +6949,16 @@ initialization_started (MMBroadbandModem *self,
user_data,
initialization_started);
ctx->qmi = mm_base_modem_get_port_qmi (MM_BASE_MODEM (self));
- g_assert (ctx->qmi);
+
+ /* This may happen if we unplug the modem unexpectedly */
+ if (!ctx->qmi) {
+ g_simple_async_result_set_error (ctx->result,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Cannot initialize: QMI port went missing");
+ initialization_started_context_complete_and_free (ctx);
+ return;
+ }
if (mm_qmi_port_is_open (ctx->qmi)) {
/* Nothing to be done, just launch parent's callback */
diff --git a/src/mm-sim-qmi.c b/src/mm-sim-qmi.c
index 63111b54..578bf774 100644
--- a/src/mm-sim-qmi.c
+++ b/src/mm-sim-qmi.c
@@ -40,16 +40,30 @@ ensure_qmi_client (MMSimQmi *self,
{
MMBaseModem *modem = NULL;
QmiClient *client;
+ MMQmiPort *port;
g_object_get (self,
MM_SIM_MODEM, &modem,
NULL);
g_assert (MM_IS_BASE_MODEM (modem));
- client = mm_qmi_port_peek_client (mm_base_modem_peek_port_qmi (modem),
+ port = mm_base_modem_peek_port_qmi (modem);
+ g_object_unref (modem);
+
+ if (!port) {
+ g_simple_async_report_error_in_idle (G_OBJECT (self),
+ callback,
+ user_data,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Couldn't peek QMI port");
+ return FALSE;
+ }
+
+ client = mm_qmi_port_peek_client (port,
service,
MM_QMI_PORT_FLAG_DEFAULT);
- if (!client)
+ if (!client) {
g_simple_async_report_error_in_idle (G_OBJECT (self),
callback,
user_data,
@@ -57,11 +71,11 @@ ensure_qmi_client (MMSimQmi *self,
MM_CORE_ERROR_FAILED,
"Couldn't peek client for service '%s'",
qmi_service_get_string (service));
- else
- *o_client = client;
+ return FALSE;
+ }
- g_object_unref (modem);
- return !!client;
+ *o_client = client;
+ return TRUE;
}
/*****************************************************************************/
diff --git a/src/mm-sms-qmi.c b/src/mm-sms-qmi.c
index 2b167ed2..fbdaeb02 100644
--- a/src/mm-sms-qmi.c
+++ b/src/mm-sms-qmi.c
@@ -43,16 +43,30 @@ ensure_qmi_client (MMSmsQmi *self,
{
MMBaseModem *modem = NULL;
QmiClient *client;
+ MMQmiPort *port;
g_object_get (self,
MM_SMS_MODEM, &modem,
NULL);
g_assert (MM_IS_BASE_MODEM (modem));
- client = mm_qmi_port_peek_client (mm_base_modem_peek_port_qmi (modem),
+ port = mm_base_modem_peek_port_qmi (modem);
+ g_object_unref (modem);
+
+ if (!port) {
+ g_simple_async_report_error_in_idle (G_OBJECT (self),
+ callback,
+ user_data,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Couldn't peek QMI port");
+ return FALSE;
+ }
+
+ client = mm_qmi_port_peek_client (port,
service,
MM_QMI_PORT_FLAG_DEFAULT);
- if (!client)
+ if (!client) {
g_simple_async_report_error_in_idle (G_OBJECT (self),
callback,
user_data,
@@ -60,11 +74,11 @@ ensure_qmi_client (MMSmsQmi *self,
MM_CORE_ERROR_FAILED,
"Couldn't peek client for service '%s'",
qmi_service_get_string (service));
- else
- *o_client = client;
+ return FALSE;
+ }
- g_object_unref (modem);
- return !!client;
+ *o_client = client;
+ return TRUE;
}
/*****************************************************************************/