When qmi_device_shutdown is used and the callback provided utilizes
qmi_device_unref, an access into already freed memory is triggered.
Sequence of events is:
1. timeout fires
2. glib calls timeout callback (e.g. shutdown_callback) which in turn
calls shutdown_func (gobi shutdown_cb) which in turn calls
qmi_device_unref()
3. qmi_device_unref calls g_source_remove, which doesn't call the
destroy callback (it is blocked)
4. qmi_device_unref then frees the memory used by device
5. glib then calls the source destroy callback (e.g. shutdown_destroy)
which results in just freed memory being used.
glib appears to always call the destroy callback, even if the source has
been removed previously. So to work around the issue, delay the actual
g_free until the destroy callback is invoked.
qmi_device_shutdown allocated a new orphaned data structure and kicked
off a timeout to wait for the shutdown to complete. The logic was quite
racy, but the main issue was that the timeouts could not be canceled
when the underlying qmi_device object was destroyed. This resulted in
crashes.
This patch switches to first-past-the-gate mechanism. Since only the
modem driver should be issuing a qmi_device_shutdown call, this should
not be a limitation. The shutdown source is then tracked on the
qmi_device object itself and is canceled when the qmi_device object is
freed.
As an added bonus, the shutdown_destroy callback should now actually
function. Before it was simply never called.
struct discovery was allocated for every discovery procedure that was
kicked off, which itself allocated a structure. This patch uses a
class/subclass concept to only allocate a single structure per discovery
procedure.
This function was never removing discovery instances because it was looking
them up in the wrong list. This led to some strangeness with the discovery
callbacks being invoked after the "failure" timeout of 5 seconds and
consequent failures with everything getting out of sync.
With this patch we fix the lookup to use the correct queue. There's also
a double-free in the function that was never being hit before because the
lookups never succeeded; fix that as well.
With this, service discovery and creation work as expected when testing with
an EC21.
There are various device & service discovery tasks that are initiated
based on a qmi_device object. qmi_device object does not currently
keep track of these tasks. Unfortunately the qmi_device object can
go away at any time, and these tasks can become orphaned.
The result of this can lead to crashes. E.g. a discovery task timeout fires
after the qmi_device object has been destroyed. Since the object is no
longer valid, any accesses to it will likely result in a SEGFAULT.
This patch attempts to track all discovery tasks on the qmi_device
object itself, so that they can be cleaned up properly. This patch does
not handle the qmi_device_shutdown functionality.
Add a way to get and set data format expected by kernel device driver.
This is inspired by what is done in qmicli (package libqmi).
It does not use QMI protocol but a sysfs exported by kernel driver.
To use this feature, kernel version must be equal or more than 4.5.
QMI notification messages handlers are never called on MC7430 without this fix.
- Do not test transaction id before calling notification handler. On MC7430,
notification messages contain a not null transaction id (starts with 1,
increased at each message for a particular client).
- On MC7304 transaction id in notification messages is always 0.