We will look for the part being notified in the CMTI indication directly in the
list of processed parts; and if we have it there already we won't re-process it.
Still, we may get several CMTI indications for the same part one after the
other, so it may still happen that the second CMTI comes *before* we have parsed
and created the part in the SMS list. For that case, the SMS list will reject
taking the part if there is already a part with the same storage+index already
processed.
This fix removes the `known_sms_parts' hash table, which was being handled
incorrectly.
This should fix https://bugzilla.gnome.org/show_bug.cgi?id=675175
If we get an error when telling the SMS list to take the new PDU, the caller is
the one responsible for freeing the part, so avoid doing it twice.
Relevant valgrind log:
==7287== Invalid read of size 8
==7287== at 0x437CE1: mm_sms_part_free (mm-sms-part.c:344)
==7287== by 0x454D11: mm_iface_modem_messaging_take_part (mm-iface-modem-messaging.c:359)
==7287== by 0x461234: cds_received (mm-broadband-modem.c:4626)
==7287== by 0x48A305: parse_unsolicited (mm-at-serial-port.c:256)
==7287== by 0x48723D: parse_response (mm-serial-port.c:731)
==7287== by 0x48759B: data_available (mm-serial-port.c:801)
==7287== by 0x36ADC47694: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3200.4)
==7287== by 0x36ADC479C7: ??? (in /usr/lib64/libglib-2.0.so.0.3200.4)
==7287== by 0x36ADC47DC1: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3200.4)
==7287== by 0x421398: main (main.c:150)
==7287== Address 0x9840b78 is 24 bytes inside a block of size 104 free'd
==7287== at 0x4A079AE: free (vg_replace_malloc.c:427)
==7287== by 0x36ADC4D37E: g_free (in /usr/lib64/libglib-2.0.so.0.3200.4)
==7287== by 0x36ADC61CCE: g_slice_free1 (in /usr/lib64/libglib-2.0.so.0.3200.4)
==7287== by 0x437D5A: mm_sms_part_free (mm-sms-part.c:351)
==7287== by 0x36ADC449EC: g_list_foreach (in /usr/lib64/libglib-2.0.so.0.3200.4)
==7287== by 0x36ADC44A0A: g_list_free_full (in /usr/lib64/libglib-2.0.so.0.3200.4)
==7287== by 0x43D8A1: finalize (mm-sms.c:1629)
==7287== by 0x36AE8145DA: g_object_unref (in /usr/lib64/libgobject-2.0.so.0.3200.4)
==7287== by 0x43CD52: mm_sms_singlepart_new (mm-sms.c:1376)
==7287== by 0x43E223: take_singlepart (mm-sms-list.c:236)
==7287== by 0x43E60D: mm_sms_list_take_part (mm-sms-list.c:338)
==7287== by 0x454CC7: mm_iface_modem_messaging_take_part (mm-iface-modem-messaging.c:353)
... or Valgrind will complain:
==4834== Invalid read of size 1
==4834== at 0x43904C: mm_sms_part_new_from_binary_pdu (mm-sms-part.c:783)
==4834== by 0x4382C9: mm_sms_part_new_from_pdu (mm-sms-part.c:485)
==4834== by 0x461D85: sms_pdu_part_list_ready (mm-broadband-modem.c:5004)
==4834== by 0x3161A6CFB6: g_simple_async_result_complete (in /usr/lib64/libgio-2.0.so.0.3200.4)
==4834== by 0x432F82: at_command_parse_response (mm-base-modem-at.c:490)
==4834== by 0x489F96: handle_response (mm-at-serial-port.c:161)
==4834== by 0x486D0A: mm_serial_port_got_response (mm-serial-port.c:588)
==4834== by 0x48758B: data_available (mm-serial-port.c:804)
==4834== by 0x36ADC47694: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3200.4)
==4834== by 0x36ADC479C7: ??? (in /usr/lib64/libglib-2.0.so.0.3200.4)
==4834== by 0x36ADC47DC1: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3200.4)
==4834== by 0x421398: main (main.c:150)
==4834== Address 0x927e489 is 0 bytes after a block of size 25 alloc'd
==4834== at 0x4A06F18: calloc (vg_replace_malloc.c:566)
==4834== by 0x36ADC4D2C6: g_malloc0 (in /usr/lib64/libglib-2.0.so.0.3200.4)
==4834== by 0x4844B2: utils_hexstr2bin (mm-utils.c:63)
==4834== by 0x438284: mm_sms_part_new_from_pdu (mm-sms-part.c:476)
==4834== by 0x461D85: sms_pdu_part_list_ready (mm-broadband-modem.c:5004)
==4834== by 0x3161A6CFB6: g_simple_async_result_complete (in /usr/lib64/libgio-2.0.so.0.3200.4)
==4834== by 0x432F82: at_command_parse_response (mm-base-modem-at.c:490)
==4834== by 0x489F96: handle_response (mm-at-serial-port.c:161)
==4834== by 0x486D0A: mm_serial_port_got_response (mm-serial-port.c:588)
==4834== by 0x48758B: data_available (mm-serial-port.c:804)
==4834== by 0x36ADC47694: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3200.4)
==4834== by 0x36ADC479C7: ??? (in /usr/lib64/libglib-2.0.so.0.3200.4)
Instead of letting the plugins specify a default storage to use, just look at
the supported ones and use the best one.
"MT is preferred over "ME" or "SM", as "MT=ME+SM"
There is no point in specifying a default 'mem1' memory storage, which is used
for reading/listing/deleting, as those are operations that need a specific
'mem1' set each time.
Also, there is no point in specifying separate default 'mem2' and 'mem3' memory
storages, specially because now we allow Sms.Store() to specify a storage.
So, we will now only have a 'default' memory storage, which is applicable for
both 'mem2' and 'mem3' (storing, sending from storage and deleting).
The default AT commands to play with SMS rely on AT+CPMS to select the default
memory storages for different operations. AT+CPMS defines 3 different storages,
called 'mem1' (for reading/listing/deleting), 'mem2' (for storing or sending
from storage) and 'mem3' (for receiving).
For example, when an SMS is to be deleted, we first need to select with AT+CPMS
the proper 'mem1' storage before issuing the command to delete the SMS part.
But, in order to do this properly we need to synchronize the access to the
currently set storages, so that no more than one action is run in the storages
at the same time (e.g. don't store an SMS while another SMS is being deleted).
In order to synchronize this access, we now provide commands to lock()/unlock()
the storages, which should be used when we want to do some operation on them.
Note that this logic is only required because we cannot specify the storage
explicitly in the specific AT command operations. With QMI we don't need this
locking/unlocking.