Commit Graph
2886 Commits
Author SHA1 Message Date
Ben Chan f8a375b1fa broadband-modem-mbim: use device manufacturer information when available
MBIM modems can be supported by the 'generic' plugin. Instead of
treating the plugin name (i.e. Generic) as the manufacturer, it's more
useful to use the manufacturer information reported by the underlying
USB device if that is available.
2017-10-07 10:05:40 +02:00
Ben Chan 3a0d658b5d kerneldevice: add method to retrieve manufacturer information
A USB device may report its manufacturer through the Manufacturer String
Descriptor. That information can sometimes be useful, e.g. MBIM doesn't
define a standard command to query the manufacturer. This patch adds a
method to MMKernelDevice to retrieve the manufacturer information from
the underlying physical device, which can later be used by
MMBroadbandModemMbim to report the manufacturer of a MBIM modem.
2017-10-07 10:05:40 +02:00
Aleksander Morgado efaa780de2 port-qmi: don't allow client allocation if port is closed
The internal QmiDevice will be gone when the port is closed, so we
cannot really do anything.

This avoid an issue happening when the modem goes away in the middle
of the client allocation logic performed by MMBroadbandModemQmi:

    ModemManager[24820]: <debug> [1507279407.225777] Couldn't allocate client for service 'wms': Couldn't create client for service 'wms': CID allocation failed in the CTL client: Transaction timed out
    ModemManager[24820]: qmi_device_allocate_client: assertion 'QMI_IS_DEVICE (self)' failed
    ==24820==
    ==24820== Process terminating with default action of signal 5 (SIGTRAP): dumping core
    ==24820==    at 0x66E3411: ??? (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==24820==    by 0x66E46FA: g_logv (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==24820==    by 0x66E484E: g_log (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==24820==    by 0x538E259: qmi_device_allocate_client (qmi-device.c:1008)
    ==24820==    by 0x1F5690: mm_port_qmi_allocate_client (mm-port-qmi.c:157)
    ==24820==    by 0x1D20BA: allocate_next_client (mm-broadband-modem-qmi.c:11319)
    ==24820==    by 0x1D2027: qmi_port_allocate_client_ready (mm-broadband-modem-qmi.c:11306)
    ==24820==    by 0x612FD52: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==24820==    by 0x6130775: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==24820==    by 0x1F54E8: allocate_client_ready (mm-port-qmi.c:113)
    ==24820==    by 0x612FD52: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==24820==    by 0x6130775: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
2017-10-06 10:51:01 +02:00
Aleksander Morgado 4bd15362c5 kerneldevice,generic: plug memleak
==5075== 198 bytes in 18 blocks are definitely lost in loss record 4,486 of 4,761
    ==5075==    at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==5075==    by 0x66E3028: g_malloc (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==5075==    by 0x66CAD42: g_path_get_basename (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==5075==    by 0x20BB7B: preload_interface_sysfs_path (mm-kernel-device-generic.c:184)
    ==5075==    by 0x20C885: preload_contents (mm-kernel-device-generic.c:383)
    ==5075==    by 0x20E2E1: check_preload (mm-kernel-device-generic.c:830)
    ==5075==    by 0x20EA6F: set_property (mm-kernel-device-generic.c:953)
    ==5075==    by 0x6455359: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==5075==    by 0x6456DBC: g_object_new_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==5075==    by 0x6105E95: g_initable_new_valist (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==5075==    by 0x6105F58: g_initable_new (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==5075==    by 0x20E848: mm_kernel_device_generic_new_with_rules (mm-kernel-device-generic.c:901)
2017-10-05 23:46:42 +02:00
Aleksander Morgado 8cd21e439d kerneldevice,generic: plug memleak
==5075== 333 bytes in 37 blocks are definitely lost in loss record 4,612 of 4,761
    ==5075==    at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==5075==    by 0x66E3028: g_malloc (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==5075==    by 0x66CAD42: g_path_get_basename (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==5075==    by 0x20BE20: preload_driver (mm-kernel-device-generic.c:242)
    ==5075==    by 0x20C8E5: preload_contents (mm-kernel-device-generic.c:391)
    ==5075==    by 0x20E2E1: check_preload (mm-kernel-device-generic.c:830)
    ==5075==    by 0x20EA6F: set_property (mm-kernel-device-generic.c:953)
    ==5075==    by 0x6455359: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==5075==    by 0x6456DBC: g_object_new_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==5075==    by 0x6105E95: g_initable_new_valist (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==5075==    by 0x6105F58: g_initable_new (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==5075==    by 0x20E848: mm_kernel_device_generic_new_with_rules (mm-kernel-device-generic.c:901)
2017-10-05 23:46:42 +02:00
Aleksander Morgado 2dc13fd964 plugin-manager: allow multiple calls to port_context_complete()
Only the first one will work.
2017-10-05 23:46:42 +02:00
Aleksander Morgado bbe5064591 plugin-manager: ensure valid reference during cancellation
Cancelling the port_context->cancellable may end up finishing the
async task and completing the last reference of the port
context. Avoid that by making sure we hold a valid reference for as
long as we may need it.

    ==2277== Invalid read of size 4
    ==2277==    at 0x14ACE2: port_context_cancel (mm-plugin-manager.c:547)
    ==2277==    by 0x14C32E: device_context_port_released (mm-plugin-manager.c:1142)
    ==2277==    by 0x83831C7: ffi_call_unix64 (in /usr/lib/libffi.so.6.0.4)
    ==2277==    by 0x8382C29: ffi_call (in /usr/lib/libffi.so.6.0.4)
    ==2277==    by 0x64506A8: g_cclosure_marshal_generic (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==2277==    by 0x644FEAC: g_closure_invoke (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==2277==    by 0x64624AD: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==2277==    by 0x646AC84: g_signal_emit_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==2277==    by 0x646B69E: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==2277==    by 0x1483E7: mm_device_release_port (mm-device.c:196)
    ==2277==    by 0x145D5D: device_removed (mm-base-manager.c:217)
    ==2277==    by 0x1464A9: handle_kernel_event (mm-base-manager.c:401)
    ==2277==  Address 0xf677d18 is 88 bytes inside a block of size 96 free'd
    ==2277==    at 0x4C2E14B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==2277==    by 0x14A1B7: port_context_unref (mm-plugin-manager.c:234)
    ==2277==    by 0x14AB51: plugin_supports_port_ready (mm-plugin-manager.c:492)
    ==2277==    by 0x612FD52: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==2277==    by 0x6130775: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==2277==    by 0x1AFDF8: port_probe_run_ready (mm-plugin.c:624)
    ==2277==    by 0x612FD52: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==2277==    by 0x6130775: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==2277==    by 0x6131367: g_task_return_error_if_cancelled (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==2277==    by 0x1A9EDA: port_probe_task_return_error_if_cancelled (mm-port-probe.c:109)
    ==2277==    by 0x1ABCD2: serial_probe_at_parse_response (mm-port-probe.c:900)
    ==2277==    by 0x611E475: g_simple_async_result_complete (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==2277==  Block was alloc'd at
    ==2277==    at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==2277==    by 0x66E3028: g_malloc (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==2277==    by 0x66FAB25: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==2277==    by 0x66FAFB8: g_slice_alloc0 (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==2277==    by 0x14B18D: port_context_new (mm-plugin-manager.c:649)
    ==2277==    by 0x14C4A7: device_context_port_grabbed (mm-plugin-manager.c:1182)
    ==2277==    by 0x83831C7: ffi_call_unix64 (in /usr/lib/libffi.so.6.0.4)
    ==2277==    by 0x8382C29: ffi_call (in /usr/lib/libffi.so.6.0.4)
    ==2277==    by 0x64506A8: g_cclosure_marshal_generic (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==2277==    by 0x644FEAC: g_closure_invoke (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==2277==    by 0x64624AD: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==2277==    by 0x646AC84: g_signal_emit_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
2017-10-05 23:46:41 +02:00
Aleksander Morgado 48850f21b4 port-serial: avoid invalid memory write on cancellation logic
If the GCancellable is already cancelled when trying to connect a
signal, the callback given will be run right away, and that may end up
completing the async task and removing the last MMPortSerial
reference.

    ==30627== Invalid write of size 8
    ==30627==    at 0x1ED43B: port_serial_queue_process (mm-port-serial.c:812)
    ==30627==    by 0x66DE342: ??? (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==30627==    by 0x66DD8C4: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==30627==    by 0x66DDC87: ??? (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==30627==    by 0x66DDFA1: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==30627==    by 0x143F9B: main (main.c:180)
    ==30627==  Address 0xf6f0e98 is 200 bytes inside a block of size 328 free'd
    ==30627==    at 0x4C2E14B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==30627==    by 0x64742B2: g_type_free_instance (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==30627==    by 0x1ED0F2: port_serial_got_response (mm-port-serial.c:704)
    ==30627==    by 0x1ED21B: port_serial_response_wait_cancelled (mm-port-serial.c:757)
    ==30627==    by 0x60E1A81: g_cancellable_connect (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==30627==    by 0x1ED43A: port_serial_queue_process (mm-port-serial.c:812)
    ==30627==    by 0x66DE342: ??? (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==30627==    by 0x66DD8C4: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==30627==    by 0x66DDC87: ??? (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==30627==    by 0x66DDFA1: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==30627==    by 0x143F9B: main (main.c:180)
    ==30627==  Block was alloc'd at
    ==30627==    at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==30627==    by 0x66E3028: g_malloc (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==30627==    by 0x66FAB25: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==30627==    by 0x66FAFB8: g_slice_alloc0 (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==30627==    by 0x6473FB5: g_type_create_instance (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==30627==    by 0x6455027: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==30627==    by 0x6456DBC: g_object_new_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==30627==    by 0x6457200: g_object_new (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==30627==    by 0x1F253A: mm_port_serial_at_new (mm-port-serial-at.c:533)
    ==30627==    by 0x1AC7E7: serial_open_at (mm-port-probe.c:1210)
    ==30627==    by 0x66DD8C4: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==30627==    by 0x66DDC87: ??? (in /usr/lib/libglib-2.0.so.0.5200.3)
2017-10-05 23:19:22 +02:00
Aleksander Morgado 54b21292b1 base-manager: plug memleak
==28888== 622 (280 direct, 342 indirect) bytes in 7 blocks are definitely lost in loss record 2,515 of 2,548
    ==28888==    at 0x6474014: g_type_create_instance (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==28888==    by 0x6455027: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==28888==    by 0x6456A54: g_object_newv (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==28888==    by 0x6457213: g_object_new (in /usr/lib/libgobject-2.0.so.0.5200.3)
    ==28888==    by 0x4E9DD7D: mm_kernel_event_properties_new (mm-kernel-event-properties.c:422)
    ==28888==    by 0x4E9D8BC: mm_kernel_event_properties_new_from_string (mm-kernel-event-properties.c:283)
    ==28888==    by 0x1465D7: process_initial_kernel_events (mm-base-manager.c:555)
    ==28888==    by 0x14679E: mm_base_manager_start (mm-base-manager.c:581)
    ==28888==    by 0x143CF3: name_acquired_cb (main.c:110)
    ==28888==    by 0x616B805: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==28888==    by 0x616BA47: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
    ==28888==    by 0x612FD52: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
2017-10-05 22:59:55 +02:00
Aleksander Morgado 5bb205d351 kerneldevice,generic: avoid segfault when reported device doesn't exist
Could be a user error or a race condition. In any case, we shouldn't
crash.

    ModemManager[19677]: <debug> [1507235472.301934] Kernel event reported:
    ModemManager[19677]: <debug> [1507235472.301944]   action:    add
    ModemManager[19677]: <debug> [1507235472.301953]   subsystem: usbmisc
    ModemManager[19677]: <debug> [1507235472.301962]   name:      cdc-wdm0
    ModemManager[19677]: <debug> [1507235472.301970]   uid:       n/a
    ModemManager[19677]: <debug> [1507235472.301984] (usbmisc/cdc-wdm0) preloading contents and properties...
    ModemManager[19677]: <warn>  [1507235472.302007] Invalid sysfs path read for usbmisc/cdc-wdm0
    ModemManager[19677]: <debug> [1507235472.302017] (usbmisc/cdc-wdm0) interface class: 0x00
    ModemManager[19677]: <debug> [1507235472.302027] (usbmisc/cdc-wdm0) interface subclass: 0x00
    ModemManager[19677]: <debug> [1507235472.302037] (usbmisc/cdc-wdm0) interface protocol: 0x00
    ModemManager[19677]: <debug> [1507235472.302046] (usbmisc/cdc-wdm0) interface number (ID_USB_INTERFACE_NUM): 0x00
    ModemManager[19677]: <debug> [1507235472.302059] (usbmisc/cdc-wdm0) manufacturer: unknown
    ModemManager[19677]: <debug> [1507235472.302069] (usbmisc/cdc-wdm0) product: unknown
    ModemManager[19677]: <debug> [1507235472.302078] (usbmisc/cdc-wdm0) vid: unknown
    ModemManager[19677]: <debug> [1507235472.302088] (usbmisc/cdc-wdm0) pid: unknown

    (ModemManager:19677): GLib-CRITICAL **: g_str_has_prefix: assertion 'str != NULL' failed

    (ModemManager:19677): GLib-CRITICAL **: g_str_has_prefix: assertion 'str != NULL' failed

    (ModemManager:19677): GLib-CRITICAL **: g_str_has_prefix: assertion 'str != NULL' failed

    (ModemManager:19677): GLib-CRITICAL **: g_str_has_prefix: assertion 'str != NULL' failed

    Thread 1 "ModemManager" received signal SIGSEGV, Segmentation fault.
2017-10-05 22:50:11 +02:00
Aleksander Morgado 71730509ee port-probe: avoid deadlock trying to disconnect cancellable
We cannot in any way try to disconnect a GCancellable from within a
cancellation handler, or we'll deadlock.

    Thread 1 (Thread 0x7fe98bf25700 (LWP 12079)):
    #0  0x00007fe98a355f36 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0
    #1  0x00007fe98a7f5ac0 in g_cond_wait () from /usr/lib/libglib-2.0.so.0
    #2  0x00007fe98ad14650 in g_cancellable_disconnect () from /usr/lib/libgio-2.0.so.0
    #3  0x000000000045be5d in port_probe_run_context_free ()
    #4  0x00007fe98ad519ed in g_task_finalize () from /usr/lib/libgio-2.0.so.0
    #5  0x00007fe98aaaa7b3 in g_object_unref () from /usr/lib/libgobject-2.0.so.0
    #6  0x000000000045b5f8 in port_probe_task_return_error_if_cancelled ()
    #7  0x000000000045c57d in serial_probe_at_parse_response ()
    #8  0x00007fe98ad42ed2 in g_simple_async_result_complete () from /usr/lib/libgio-2.0.so.0
    #9  0x0000000000485c7d in serial_command_ready ()
    #10 0x00007fe98ad42ed2 in g_simple_async_result_complete () from /usr/lib/libgio-2.0.so.0
    #11 0x0000000000482345 in command_context_complete_and_free ()
    #12 0x0000000000482fa5 in port_serial_got_response ()
    #13 0x00000000004830f5 in port_serial_response_wait_cancelled ()
    #14 0x00007fe98aaa70c5 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
    #15 0x00007fe98aab47ce in signal_emit_unlocked_R () from /usr/lib/libgobject-2.0.so.0
    #16 0x00007fe98aabb595 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
    #17 0x00007fe98aabb662 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
    #18 0x00007fe98ad144c5 in g_cancellable_cancel () from /usr/lib/libgio-2.0.so.0
    #19 0x00007fe98aaa70c5 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
    #20 0x00007fe98aab47ce in signal_emit_unlocked_R () from /usr/lib/libgobject-2.0.so.0
    #21 0x00007fe98aabb595 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
    #22 0x00007fe98aabb662 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
    #23 0x00007fe98ad144c5 in g_cancellable_cancel () from /usr/lib/libgio-2.0.so.0
    #24 0x000000000042e9f6 in port_context_cancel ()
    #25 0x00007fe989b99a4c in ffi_call_unix64 () at ../src/x86/unix64.S:75
    #26 0x00007fe989b994b9 in ffi_call (cif=0x7fffc41dcdb0, fn=0x42ea40 <device_context_port_released>, rvalue=<optimized out>, avalue=0x7fffc41dccd0) at ../src/x86/ffi64.c:492
    #27 0x00007fe98aaa7700 in g_cclosure_marshal_generic () from /usr/lib/libgobject-2.0.so.0
    #28 0x00007fe98aaa70c5 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
    #29 0x00007fe98aab47ce in signal_emit_unlocked_R () from /usr/lib/libgobject-2.0.so.0
    #30 0x00007fe98aabb595 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
    #31 0x00007fe98aabb662 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
    #32 0x000000000042c8f0 in mm_device_release_port ()
    #33 0x000000000042a6cb in device_removed ()
    #34 0x000000000042af94 in handle_kernel_event ()
    #35 0x000000000042b356 in report_kernel_event_auth_ready ()
    #36 0x00007fe98ad51783 in g_task_return_now () from /usr/lib/libgio-2.0.so.0
    #37 0x00007fe98ad517b9 in complete_in_idle_cb () from /usr/lib/libgio-2.0.so.0
    #38 0x00007fe98a7bda5e in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
    #39 0x00007fe98a7bddb8 in g_main_context_iterate.isra () from /usr/lib/libglib-2.0.so.0
    #40 0x00007fe98a7be042 in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
    #41 0x0000000000428dc4 in main ()

So, just clear the cancellation id before going on with the handler logic.
2017-10-05 12:37:12 +02:00
Dan Williams 3e15dc15ef bearer-mbim: don't crash when modem doesn't send gateways
When the Ericsson F5321 with firmware R3C11/R4D04 is told to make
an IPv6-only connection, it reports that it has IPv4 configuration
but then returns no actual addresses.  Check both the flags and
actual data before trying to use them.

ModemManager[25850]: <debug> [1506958721.914717] IPv4 configuration available: 'address, gateway, dns, mtu'
ModemManager[25850]: <debug> [1506958721.914731]   IP addresses (0)
ModemManager[25850]: <debug> [1506958721.914741]   DNS addresses (0)
ModemManager[25850]: <debug> [1506958721.914748]   MTU: '0'
ModemManager[25850]: <debug> [1506958721.914758] IPv6 configuration available: 'address, dns, mtu'
ModemManager[25850]: <debug> [1506958721.914767]   IP addresses (1)
ModemManager[25850]: <debug> [1506958721.914852]     IP [0]: 'fe80::39:f622:7d01/64'
ModemManager[25850]: <debug> [1506958721.914866]   DNS addresses (2)
ModemManager[25850]: <debug> [1506958721.914883]     DNS [0]: 'fd00:976a::9'
ModemManager[25850]: <debug> [1506958721.914896]   MTU: '1500'
ModemManager[25850]: <debug> [1506958721.914947] (wwp0s20u1i6): port now connected
2017-10-02 10:49:32 -05:00
Aleksander Morgado b252ab668f build,tests: make sure tests are rebuilt if helper libs are updated 2017-09-28 23:13:12 +02:00
Aleksander Morgado 1e318bec54 broadband-bearer: fix object types in connect_3gpp() steps
All the steps in the connect_3gpp() sequence are implemented as
methods in the MMBroadbandBearer class, and therefore the objects
received in the corresponding ready() methods are all bearers, not
modems.

This issue wasn't found before because the objects received were not
really being used after all, as we were relying on the ones kept in
the context or lately in the GTask itself.
2017-09-26 10:03:17 +02:00
Ben Chan 9f9c88a72a broadband-modem-qmi: support loading hardware revision
This patch implements hardware revision loading in MMBroadbandModemQmi
using QMI DMS 'Get Hardware Revision' command.
2017-09-20 09:56:23 -07:00
Ben Chan a848b6c368 broadband-modem-mbim: support loading hardware revision
This patch implements hardware revision loading in MMBroadbandModemMbim
by extracting the HardwareInfo field from the response to a
MBIM_CID_DEVICE_CAPS query.
2017-09-20 09:56:23 -07:00
Ben Chan daa59aeb4c iface-modem: add hook to load hardware revision 2017-09-20 09:56:23 -07:00
Ben Chan 4cb6f0e5aa broadband-modem-mbim: fix preservation logic for PIN1 unlock retries
This patches fixes commit 334273979 "broadband-modem-mbim: preserve
unlock retries for PIN1 when appropriate", which doesn't correctly
propagate the unlock retries information for PIN1 observed from
responses to MBIM_CID_PIN set operations (see commit eb9ec1b61
"sim-mbim: update unlock retries information after PIN operations").
2017-09-20 09:28:16 -07:00
Ben Chan 4f8e9e2e1c iface-modem: add mm_iface_modem_get_unlock_retries helper
This patch adds a mm_iface_modem_get_unlock_retries helper for getting
the current MMUnlockRetries value of a MMIfaceModem object, which later
allows us to partially update (e.g. a specific MMModemLock) the
MMUnlockRetries value of a MMIfaceModem object.
2017-09-20 09:28:12 -07:00
Aleksander Morgado 2ed9706148 bearer-qmi: cleanup indication handlers on network-initiated disconnects
Otherwise, they'll end up queueing up and each time we get a new
indication the signal will get called multiple times:

    [/dev/cdc-wdm0] received message...
    <<<<<< RAW:
    <<<<<<   length = 20
    <<<<<<   data   = 01:13:00:80:01:09:04:00:00:01:00:07:00:20:04:00:05:00:00:00
    [/dev/cdc-wdm0] received generic indication (translated)...
    <<<<<< QMUX:
    <<<<<<   length  = 19
    <<<<<<   flags   = 0x80
    <<<<<<   service = "wds"
    <<<<<<   client  = 9
    <<<<<< QMI:
    <<<<<<   flags       = "indication"
    <<<<<<   transaction = 0
    <<<<<<   tlv_length  = 7
    <<<<<<   message     = "Event Report" (0x0001)
    <<<<<< TLV:
    <<<<<<   type       = "Preferred Data System" (0x20)
    <<<<<<   length     = 4
    <<<<<<   value      = 05:00:00:00
    <<<<<<   translated = lte
    <debug> [1504578559.592891] Got QMI WDS event report
    <debug> [1504578559.598212] Got QMI WDS event report
    <debug> [1504578559.601694] Got QMI WDS event report
2017-09-16 12:24:07 -07:00
Daniele Palmas 3f9417be43 blacklist: ignore Intel coredump downloader device 2017-09-14 22:03:06 -07:00
Aleksander Morgado 0c7f3380ae bearer-mbim: ensure session is disconnected before trying to connect
If a suspend/resume cycle happens or ModemManager is restarted (e.g.
after a crash) the modem may be left with a given session id
connected. With this change we're forcing a session disconnection
before we attempt a session connection.

https://bugs.freedesktop.org/show_bug.cgi?id=102231
2017-09-12 10:22:04 -05:00
Arto Jantunen abfd8d3b08 Blacklist Garmin ANT+ sticks 2017-09-10 08:20:29 +02:00
Ben Chan 3342739798 broadband-modem-mbim: preserve unlock retries for PIN1 when appropriate
If PIN1 is disabled and we have tried to enable it with a wrong PIN, a
MBIM modem would have indicated the number of remaining attempts for
PIN1 (unless PUK1 is engaged) in the response to the failed MBIM_CID_PIN
set operation.

However, a MBIM_CID_PIN query may be issued (e.g.  MMBaseSim calls
mm_iface_modem_update_lock_info()) after the MBIM_CID_PIN set operation
to query the number of remaining attempts for a PIN type. Unfortunately,
we can't specify a particular PIN type in a MBIM_CID_PIN query. The
modem may not reply with information about PIN1 if PIN1 is disabled.
When that happens, we would like to preserve our knowledge about the
number of remaining attempts for PIN1.

This patch modifies MMBroadbandModemMbim's load_unlock_retries()
operation to carry over any previously observed information on PIN1 if
the MBIM_CID_PIN query reports something other than PIN1.
2017-09-07 19:07:01 +02:00
Ben Chan eb9ec1b617 sim-mbim: update unlock retries information after PIN operations
After MMSimMbim performs a MBIM_CID_PIN set operation, it calls
mm_iface_modem_update_lock_info() (through its base class MMBaseSim) to
refresh the unlock retries information, which results in a MBIM_CID_PIN
query. However, a MBIM_CID_PIN query reports only the information of one
PIN type and the PIN type can't be specified, we need to deduce the
number of retries left for a specific PIN type from the response of a
MBIM_CID_PIN set operation for that PIN type. To allow that, this patch
modifies MMSimMbim to update the unlock retries information after a PIN
operation based on the response to the MBIM_CID_PIN set operation.
2017-09-07 19:06:55 +02:00
Ben Chan d4ff05af5e iface-modem: export update_unlock_retries outside MMIfaceModem
This patch exports the internal function update_unlock_retries() in
MMIfaceModem as mm_iface_modem_update_unlock_retries(), which later
allows us to call it from other classes.
2017-09-07 19:06:50 +02:00
Aleksander Morgado c41f7215a1 qmi: update frequency bands support
Several changes here:
  * Updated to use the non-deprecated MMModemBand values.
  * Added support for GSM 450, GSM 480 and GSM 750.
  * Added support for UMTS bands 11 and 19.
2017-09-07 10:55:16 +02:00
Aleksander Morgado a29610f25d plugin,port-probe: always cast SEND_DELAY value to guint64
Program received signal SIGSEGV, Segmentation fault.
    strchr () at ../sysdeps/arm/armv6/strchr.S:28
    28    ../sysdeps/arm/armv6/strchr.S: No such file or directory.
    (gdb) bt
    #0  strchr () at ../sysdeps/arm/armv6/strchr.S:28
    #1  0x76b121c8 in g_param_spec_pool_lookup () from ~/buildroot/output/staging/lib/libgobject-2.0.so.0
    #2  0x76b0cf44 in g_object_new_valist () from ~/buildroot/output/staging/lib/libgobject-2.0.so.0
    #3  0x76b0d39c in g_object_new () from ~/buildroot/output/staging/lib/libgobject-2.0.so.0
    #4  0x75f75e40 in mm_plugin_create () at ublox/mm-plugin-ublox.c:99
    #5  0x00031550 in load_plugin (path=0xe9b68 "/usr/lib/ModemManager/libmm-plugin-ublox.so") at mm-plugin-manager.c:1521
    #6  load_plugins (error=0x7efffa68, self=0xdc4f0) at mm-plugin-manager.c:1574
    #7  initable_init (initable=<optimized out>, cancellable=<optimized out>, error=0x7efffa68) at mm-plugin-manager.c:1679
    #8  0x76b9b278 in g_initable_new_valist () from ~/buildroot/output/staging/lib/libgio-2.0.so.0
    #9  0x76b9b2e0 in g_initable_new () from ~/buildroot/output/staging/lib/libgio-2.0.so.0
    #10 0x000324d0 in mm_plugin_manager_new (plugin_dir=0xe9c40 "/usr/lib/ModemManager", error=error@entry=0x7efffa68) at mm-plugin-manager.c:1620
    #11 0x0002da08 in initable_init (initable=0xddb40, cancellable=<optimized out>, error=0x7efffa68) at mm-base-manager.c:1113
    #12 0x76b9b278 in g_initable_new_valist () from ~/buildroot/output/staging/lib/libgio-2.0.so.0
    #13 0x76b9b2e0 in g_initable_new () from ~/buildroot/output/staging/lib/libgio-2.0.so.0
    #14 0x0002e81c in mm_base_manager_new (connection=connection@entry=0xe1070, plugin_dir=plugin_dir@entry=0x9efb0 "/usr/lib/ModemManager",
        auto_scan=auto_scan@entry=1, initial_kernel_events=initial_kernel_events@entry=0x0, enable_test=0, error=0x7efffa68, error@entry=0x7efffa60)
        at mm-base-manager.c:957
    #15 0x0002b6ec in bus_acquired_cb (connection=0xe1070, name=<optimized out>, user_data=<optimized out>) at main.c:87
    #16 0x76c26864 in connection_get_cb () from ~/buildroot/output/staging/lib/libgio-2.0.so.0
    #17 0x76bc76cc in g_task_return_now () from ~/buildroot/output/staging/lib/libgio-2.0.so.0
    #18 0x76bc7d50 in g_task_return () from
    ~/buildroot/output/staging/lib/libgio-2.0.so.0

See similar bug in GStreamer:
https://bugzilla.gnome.org/show_bug.cgi?id=740191
2017-09-05 20:16:18 +02:00
Aleksander Morgado 52aa393d40 base-sim: wrap in its own GTask the SIM id loading from the subclass
Instead of reusing the caller GTask, use a new GTask to wrap the
execution of the subclass' async method implementation.

Also, rename the _ready() methods implemented in the GObject
initialization flow so that we can use the load_sim_identifier_ready()
function name.
2017-09-04 17:59:59 +02:00
Carlo Lobrano 76916de313 telit-plugin: handle QSS unsolicited due to power state transitions
When transitioning between power-low and power-on modes, Telit modems
switch the SIM off/on, which leads to the emission of #QSS unsolicited not
related to actual SIM swaps.

To handle this #QSS unsolicited, this patch:

* disables reacting on #QSS unsolicited when modem_power_down is received
* implements modem_after_power_up that:
    - checks whether the SIM has been changed, matching cached SIM
      Identifier with the value in the current SIM. If SIM Identifier,
      is different, sim hot swap ports detected is called.
    - re-enables reacting on #QSS unsolicited
2017-09-04 17:59:59 +02:00
Carlo Lobrano 5014cf3976 broadband-modem: do not release SIM swap port contexts on disable
Currently when the modem is disabled, it releases SIM hot swap ports context,
and is not able to receive any notification about the SIM status.

This patch keeps these ports opened when Modem is disabled and released them
only when SIM swap is detected or when modem is released.
2017-08-29 11:17:47 +02:00
Mario Limonciello 2439900fd3 blacklist: ignore Silicon Labs USB Zigbee dongles 2017-08-29 07:36:41 +02:00
Ben Chan 76c1a1119c base-manager: avoid events of USB interface from removing MMDevice
When a USB modem is switching its USB configuration, udev may deliver
the remove events of USB interfaces associated with the old USB
configuration and the add events of USB interfaces associated with the new USB
configuration in an interleaved fashion. An interleaved remove event of USB
interface could trigger the special case handling code in
mm-base-manager.c:device_removed() and incorrectly remove a MMDevice under
probing.

See https://lists.freedesktop.org/archives/modemmanager-devel/2017-August/005626.html
for more details.

This patch adds a check to ensure that only remove events of USB
device (i.e. not interface) can trigger the special handling code.
2017-08-22 13:54:32 +02:00
Aleksander Morgado 5a01e54066 charsets: simplify check to see if conversion to charset possible
Instead of having a method that returns the expected length after the
conversion and the amount of input UTF-8 characters that couldn't be
converted to the given charset, simplify the logic and just define a
method that returns a boolean specifying whether the conversion is
possible or not.

Also, include unit tests.
2017-08-16 16:27:42 +02:00
Aleksander Morgado 1f2bb64028 charsets: ensure all methods are prefixed with 'mm_' 2017-08-16 16:08:15 +02:00
Aleksander Morgado 06fef77cc0 charsets,test: refactor unit tests
These tests don't need fixtures, so use the simpler g_test_add_func()
methods to add tests associated to a test path.
2017-08-16 16:08:15 +02:00
Eric Caruso 439d58a55c mm-broadband-modem-mbim: reprobe on mbim-proxy death
In case mbim-proxy crashes, ModemManager needs to be able to
recognize this and respawn the proxy so we don't lose access
to the modem. Do this by subscribing to the device removal
signal on MbimDevice and reprobing the modem when we lose the
connection to mbim-proxy.

We can't just restart mbim-proxy because the reopened mbim-proxy
will give us a different client ID, and so unsolicitied
notifications will fail and MM gets very confused otherwise.
2017-08-15 22:19:40 +02:00
Aleksander Morgado eb64d39e52 kernel-device: assert 'vendor' and 'product' in get_device_ids()
These two parameters must always be given.
2017-08-15 18:18:45 +02:00
Ben Chan 7e22696b34 kernel-device: expect non-NULL 'vendor' and 'product' argument in get_device_ids()
get_device_ids() in mm-kernel-device-udev.c accepts a NULL 'vendor' or
'product' argument, but the current implementation could result in a
potential NULL dereferences of the 'vendor' argument. Given that
get_device_ids() is a local helper and its only caller provides a
non-NULL 'vendor' and 'product' argument, this patch removes the NULL
checks (i.e. get_device_ids() expects non-NULL 'vendor' and 'product').

This patch also rearranges the code such that the 'vendor' argument is
updated only when the function returns TRUE, just like how the 'product'
argument is handled.
2017-08-15 18:15:53 +02:00
Ben Chan 7ae32d6c61 charset: fix mm_charset_get_encoded_len
The while loop in mm_charset_get_encoded_len() iterates through each
valid UTF-8 encoded character in the given NULL-terminated UTF-8 string.
It uses g_utf8_find_next_char() to find the position of the next
character. In case, g_utf8_find_next_char() returns NULL, it tries to
find the end (i.e. the NULL character) of the string.

This patch fixes the following issues in the while loop:

1. The loop uses both 'next' and 'end' to track the position of the next
   character in the string.

   When g_utf8_find_next_char() returns a non-NULL value, 'next' is
   essentially the same as 'end'.

   When g_utf8_find_next_char() returns NULL, 'next' remains NULL while
   'end' is adjusted to track the end of the string (but is done
   incorrectly as described in #2). After the 'p = next' assignment, the
   'while (*p)' check results in a NULL dereference. 'p' should thus be
   set to 'end' instead of 'next'.

   'next' is thus redundant and can be removed.

2. When g_utf8_find_next_char() returns NULL and 'end' is adjusted to
   track the end of string, the 'while (*end++)' loop stops when finding
   the NULL character, but 'end' is advanced past the NULL character.
   After the 'p = end' assignment, the 'while (*p)' check results in a
   dereference of out-of-bounds pointer.

   'while (*++end)' should be used instead given that 'p' doesn't point
   to a NULL character when 'end = p' happens. 'end' will be updated to
   point to the NULL character. After the 'p = end' assignment (fixed in
   #1), the 'while (*p)' check will properly stop the loop.
2017-08-15 09:37:24 +02:00
Aleksander Morgado d7d2c320d3 broadband-modem-mbim: explicitly remove notification handler on unref
When we remove the last object reference, make sure the notification
handler is also removed, or we may end up using an already freed
object.

https://retrace.fedoraproject.org/faf/reports/1815001/
2017-08-12 00:57:34 +02:00
Ben Chan 36e7cd50ce plugin: fix forbidden_product_strings check in apply_post_probing_filters
This patch fixes a bug in apply_post_probing_filters() where it iterates
through `self->priv->forbidden_product_strings' but incorrectly accesses
`self->priv->product_strings[i]' inside the loop.
`self->priv->forbidden_product_strings[i]' should be accessed instead.
2017-08-11 17:09:18 -05:00
Aleksander Morgado dec53d6ef6 modem-helpers: allow unquoted strings in +CCLK responses
Also:
  * define the leading '+' as a escaped value
  * allow any number of spaces between '+CCLK' and the string value.
2017-08-09 21:59:31 +02:00
Aleksander Morgado 9528450684 bearer-mbim: stop trying to reload stats on OperationNotAllowed
The Sierra Wireless EM7345 reports OperationNotAllowed when trying to
load stats, just cancel stats reloading if so.

    ModemManager[8318]: [/dev/cdc-wdm1] Received message (translated)...
    >>>>>> Header:
    >>>>>>   length      = 48
    >>>>>>   type        = command-done (0x80000003)
    >>>>>>   transaction = 24
    >>>>>> Fragment header:
    >>>>>>   total   = 1
    >>>>>>   current = 0
    >>>>>> Contents:
    >>>>>>   status error = 'OperationNotAllowed' (0x0000001c)
    >>>>>>   service      = 'basic-connect' (a289cc33-bcbb-8b4f-b6b0-133ec2aae6df)
    >>>>>>   cid          = 'packet-statistics' (0x00000014)
2017-08-09 12:04:59 +02:00
Ben Chan 05a1097a27 iface-modem: remove unnecessary error check
This patch removes an unnecessary error check in the
update_unlock_retries() where the error is never set.
2017-08-08 09:23:55 +02:00
Aleksander Morgado 75036a4658 bearer-mbim: refactor disconnect_set_ready()
Try to make it more clear which are the different branches in the
logic, and jump out as soon as the branch is finished.
2017-08-06 13:18:15 +02:00
Aleksander Morgado e51ee31d50 broadband-bearer: run init sequence after flashing in disconnection
The init-sequence configured for the TTY that is being used as data
port must not be launched during the port reopen() sequence; instead
we must run it manually after the port flashing has finished.
2017-08-04 19:47:45 +02:00
Ben Chan 5828435b46 port-probe: remove unused variable 2017-08-04 15:17:31 +02:00
Ben Chan f7eca732f9 sim-qmi: remove unused variables 2017-08-04 15:17:31 +02:00
Ben Chan 941a41d30f broadband-modem: ensure `match_info' is always initialized
This patch initializes `match_info' in registration_status_check_ready()
to NULL by default, such that `match_info' is always initialized even if
`self->priv->modem_3gpp_registration_regex' contains no elements.
Though `self->priv->modem_3gpp_registration_regex' always contains some
elements in the current implementation, it's better not to rely on that.
2017-08-04 15:15:41 +02:00