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.
If the SMS part is from a multipart message we'll need to create a PDU with a
proper User Data Header.
This patch is based on a previous implementation by:
Roberto Majadas <roberto.majadas@openshine.com>