ModemManager: ensure response array is empty before setting cached response

Hi all,

ModemManager will cache responses of commands when requested to do so,
so that the next time the same command is issued the cached response can
be used instead of resending it to the modem (useful for example when a
single port is used and the modem is connected). This is done by
appending the cached response to the internal response array. Now, if
for any reason the response array has some not-consumed data, appending
the cached response into the response array may end up in really
undesired situations [1].

The attached patch prevents this situation, by making sure that when
using a cached response, the response array is always empty. It's
probably quite safe to assume that whenever we want to use a cached
reply, there shouldn't be any previous data in the response array. 



[1] I've got a case where there is some non-UTF-8 data added to the
response array just after the CONNECT reply. If we then we GetImei() via
d-bus, the cached reply of +CGSN is appended to the array, and once we
try to send the whole response back through d-bus, dbus-daemon
disconnects us because we sent non-UTF-8 data (the one which got added
to the array before our cached reply), and the ModemManager process
nicely exit()s (or abort()s, depending on who packages d-bus).

>From af98190831564949d584b07051d5b6c53e6de7a2 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander lanedo com>
Date: Tue, 12 Apr 2011 16:32:11 +0200
Subject: [PATCH] serial: ensure response array is empty before setting cached reply

 src/mm-serial-port.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/src/mm-serial-port.c b/src/mm-serial-port.c
index f05a1ae..de0da27 100644
--- a/src/mm-serial-port.c
+++ b/src/mm-serial-port.c
@@ -569,6 +569,17 @@ mm_serial_port_queue_process (gpointer data)
         const GByteArray *cached = mm_serial_port_get_cached_reply (self, info->command);
         if (cached) {
+            /* Ensure the response array is fully empty before setting the
+             * cached response.  */
+            if (priv->response->len > 0) {
+                g_warning ("%s: (%s) response array is not empty when using "
+                           "cached reply, cleaning up %u bytes",
+                           __func__,
+                           mm_port_get_device (MM_PORT (self)),
+                           priv->response->len);
+                g_byte_array_set_size (priv->response, 0);
+            }
             g_byte_array_append (priv->response, cached->data, cached->len);
             mm_serial_port_got_response (self, NULL);
             return FALSE;

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]