diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2015-01-17 18:37:18 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2015-01-17 18:40:38 +0100 |
commit | 732918344d9994f9e87ec77ff3a052710ec84629 (patch) | |
tree | 185f914cc94077fa42b82135f0c578cc72382b21 | |
parent | c7611301e65ffe4d9f96b6ff9f8904d41a32cab1 (diff) | |
download | libmbim-732918344d9994f9e87ec77ff3a052710ec84629.tar.gz |
mbim-device: only return transaction if it gets released
And avoid segfault in weird situations....
E.g. if we send Open(3) and we get Close-Done(3) (as with a Telit LN930 device)
the logic was segfaulting. The reason being that device_release_transaction()
was returning a valid Transaction (that with ID 3) but wasn't being released
from the internal HT (as we were asking for Open-Done, not Close-Done or Invalid).
[17 ene 2015, 18:09:23] [Debug] [/dev/cdc-wdm0,3] transaction open: store
[17 ene 2015, 18:09:23] [Debug] [/dev/cdc-wdm0] Sent message...
<<<<<< RAW:
<<<<<< length = 16
<<<<<< data = 01:00:00:00:10:00:00:00:03:00:00:00:00:02:00:00
[17 ene 2015, 18:09:23] [Debug] [/dev/cdc-wdm0] Sent message (translated)...
<<<<<< Header:
<<<<<< length = 16
<<<<<< type = open (0x00000001)
<<<<<< transaction = 3
<<<<<< Contents:
<<<<<< max_control_transfer = 512
[17 ene 2015, 18:09:23] [Debug] [/dev/cdc-wdm0] Received message...
>>>>>> RAW:
>>>>>> length = 16
>>>>>> data = 02:00:00:80:10:00:00:00:03:00:00:00:00:00:00:00
[17 ene 2015, 18:09:23] [Debug] [/dev/cdc-wdm0,3] transaction open: complete: error
[17 ene 2015, 18:09:23] [Debug] getting open done result failed: closed
[17 ene 2015, 18:09:23] [Debug] Client (6) connection closed...
[17 ene 2015, 18:09:23] -Warning ** error opening device: Unexpected response message type: 0x80000002
**
Mbim:ERROR:mbim-device.c:2205:finalize: assertion failed: (g_hash_table_size (self->priv->transactions[i]) == 0)
Program received signal SIGABRT, Aborted.
0x00007ffff6f56a97 in raise () from /usr/lib/libc.so.6
(gdb) bt
#0 0x00007ffff6f56a97 in raise () from /usr/lib/libc.so.6
#1 0x00007ffff6f57e6a in abort () from /usr/lib/libc.so.6
#2 0x00007ffff73357f5 in g_assertion_message () from /usr/lib/libglib-2.0.so.0
#3 0x00007ffff733588a in g_assertion_message_expr () from /usr/lib/libglib-2.0.so.0
#4 0x00007ffff7bb44c3 in finalize (object=0x617100) at mbim-device.c:2205
#5 0x00007ffff75e925a in g_object_unref () from /usr/lib/libgobject-2.0.so.0
#6 0x00007ffff7bb4bd7 in client_set_device (client=0x607300, device=0x0) at mbim-proxy.c:172
#7 0x00007ffff7bb4cd8 in client_unref (client=0x607300) at mbim-proxy.c:199
#8 0x00007ffff7bb522f in request_complete_and_free (request=0x613350) at mbim-proxy.c:369
#9 0x00007ffff7bb59d1 in proxy_config_internal_device_open_ready (self=0x60f880, res=0x6494a0, request=0x613350) at mbim-proxy.c:616
#10 0x00007ffff78976d7 in g_simple_async_result_complete () from /usr/lib/libgio-2.0.so.0
#11 0x00007ffff7897739 in ?? () from /usr/lib/libgio-2.0.so.0
#12 0x00007ffff730f91d in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#13 0x00007ffff730fcf8 in ?? () from /usr/lib/libglib-2.0.so.0
#14 0x00007ffff7310022 in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#15 0x000000000040153b in main (argc=1, argv=0x7fffffffead8) at mbim-proxy.c:243
Conflicts:
src/libmbim-glib/mbim-device.c
-rw-r--r-- | src/libmbim-glib/mbim-device.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/src/libmbim-glib/mbim-device.c b/src/libmbim-glib/mbim-device.c index babc3d9..7f850a1 100644 --- a/src/libmbim-glib/mbim-device.c +++ b/src/libmbim-glib/mbim-device.c @@ -212,14 +212,17 @@ device_release_transaction (MbimDevice *self, { Transaction *tr = NULL; + /* Only return transaction if it was released from the HT */ if (self->priv->transactions[type]) { tr = g_hash_table_lookup (self->priv->transactions[type], GUINT_TO_POINTER (transaction_id)); - if (tr && ((tr->type == expected_type) || (expected_type == MBIM_MESSAGE_TYPE_INVALID))) + if (tr && ((tr->type == expected_type) || (expected_type == MBIM_MESSAGE_TYPE_INVALID))) { /* If found, remove it from the HT */ g_hash_table_remove (self->priv->transactions[type], GUINT_TO_POINTER (transaction_id)); + return tr; + } } - return tr; + return NULL; } static gboolean |