diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2018-11-04 23:34:21 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2018-11-04 23:48:28 +0100 |
commit | 5f5e7e9b6e1bde31c23b5152a33caba72fa9c0fe (patch) | |
tree | 980312c198ffeaa89ea2412c0d1213676c54894d | |
parent | 6a29467070bc7ad5fcfcfe7f4a6bec92285ac389 (diff) | |
download | libqmi-5f5e7e9b6e1bde31c23b5152a33caba72fa9c0fe.tar.gz |
libqmi,mbim: only enable QMI over MBIM indications if QMI-capable devicealeksander/qmi-over-mbim-notifications
Otherwise, all service subscribe list operations including the
unsupported service may fail:
[04 nov 2018, 23:02:16] [Debug] [/dev/cdc-wdm2] Received message (translated)...
>>>>>> Header:
>>>>>> length = 48
>>>>>> type = command-done (0x80000003)
>>>>>> transaction = 19
>>>>>> Fragment header:
>>>>>> total = 1
>>>>>> current = 0
>>>>>> Contents:
>>>>>> status error = 'InvalidDeviceServiceOperation' (0x00000022)
>>>>>> service = 'basic-connect' (a289cc33-bcbb-8b4f-b6b0-133ec2aae6df)
>>>>>> cid = 'device-service-subscribe-list' (0x00000013)
-rw-r--r-- | src/libqmi-glib/qmi-device.c | 247 |
1 files changed, 129 insertions, 118 deletions
diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index 8bfe25c6..a4511ede 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -1809,6 +1809,9 @@ typedef enum { DEVICE_OPEN_CONTEXT_STEP_FLAGS_VERSION_INFO, DEVICE_OPEN_CONTEXT_STEP_FLAGS_SYNC, DEVICE_OPEN_CONTEXT_STEP_FLAGS_NETPORT, +#if defined MBIM_QMUX_ENABLED + DEVICE_OPEN_CONTEXT_STEP_FLAGS_EXPECT_INDICATIONS, +#endif DEVICE_OPEN_CONTEXT_STEP_LAST } DeviceOpenContextStep; @@ -1837,6 +1840,96 @@ qmi_device_open_finish (QmiDevice *self, static void device_open_step (GTask *task); +#if defined MBIM_QMUX_ENABLED + +static void +mbim_qmi_notification_cb (MbimDevice *device, + MbimMessage *notification, + QmiDevice *self) +{ + GByteArray *bytearray; + QmiMessage *message; + MbimService service; + const guint8 *buf; + guint32 len; + GError *error = NULL; + + service = mbim_message_indicate_status_get_service (notification); + if (service != MBIM_SERVICE_QMI) + return; + + buf = mbim_message_indicate_status_get_raw_information_buffer (notification, &len); + bytearray = g_byte_array_append (g_byte_array_sized_new (len), buf, len); + + message = qmi_message_new_from_raw (bytearray, &error); + if (!message) { + if (error) { + g_warning ("[%s] couldn't create QMI message: %s", + self->priv->path_display, error->message); + g_free (error); + } else + g_warning ("[%s] couldn't create QMI message: missing data", + self->priv->path_display); + + if (qmi_utils_get_traces_enabled ()) { + gchar *printable; + + printable = __qmi_utils_str_hex (buf, len, ':'); + g_debug ("<<<<<< RAW INVALID MESSAGE:\n" + "<<<<<< length = %u\n" + "<<<<<< data = %s\n", + len, + printable); + g_free (printable); + } + + goto out; + } + + process_message (self, message); + qmi_message_unref (message); +out: + g_byte_array_unref (bytearray); +} + +static void +mbim_subscribe_list_set_ready_cb (MbimDevice *device, + GAsyncResult *res, + GTask *task) +{ + QmiDevice *self; + DeviceOpenContext *ctx; + MbimMessage *response; + GError *error = NULL; + + self = g_task_get_source_object (task); + + response = mbim_device_command_finish (device, res, &error); + if (response) { + mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error); + mbim_message_unref (response); + } + + if (error) { + g_warning ("[%s] couldn't enable QMI indications via MBIM: %s", + self->priv->path_display, error->message); + g_error_free (error); + } else { + g_debug ("[%s] enabled QMI indications via MBIM", self->priv->path_display); + self->priv->mbim_notification_id = g_signal_connect (device, + MBIM_DEVICE_SIGNAL_INDICATE_STATUS, + G_CALLBACK (mbim_qmi_notification_cb), + self); + } + + /* Go on */ + ctx = g_task_get_task_data (task); + ctx->step++; + device_open_step (task); +} + +#endif + static void ctl_set_data_format_ready (QmiClientCtl *client, GAsyncResult *res, @@ -2058,92 +2151,6 @@ create_iostream_ready (QmiDevice *self, #if defined MBIM_QMUX_ENABLED static void -mbim_qmi_notification_cb (MbimDevice *device, - MbimMessage *notification, - QmiDevice *self) -{ - GByteArray *bytearray; - QmiMessage *message; - MbimService service; - const guint8 *buf; - guint32 len; - GError *error = NULL; - - service = mbim_message_indicate_status_get_service (notification); - if (service != MBIM_SERVICE_QMI) - return; - - buf = mbim_message_indicate_status_get_raw_information_buffer (notification, &len); - bytearray = g_byte_array_append (g_byte_array_sized_new (len), buf, len); - - message = qmi_message_new_from_raw (bytearray, &error); - if (!message) { - if (error) { - g_warning ("[%s] couldn't create QMI message: %s", - self->priv->path_display, error->message); - g_free (error); - } else - g_warning ("[%s] couldn't create QMI message: missing data", - self->priv->path_display); - - if (qmi_utils_get_traces_enabled ()) { - gchar *printable; - - printable = __qmi_utils_str_hex (buf, len, ':'); - g_debug ("<<<<<< RAW INVALID MESSAGE:\n" - "<<<<<< length = %u\n" - "<<<<<< data = %s\n", - len, - printable); - g_free (printable); - } - - goto out; - } - - process_message (self, message); - qmi_message_unref (message); -out: - g_byte_array_unref (bytearray); -} - -static void -mbim_subscribe_list_set_ready_cb (MbimDevice *device, - GAsyncResult *res, - GTask *task) -{ - QmiDevice *self; - DeviceOpenContext *ctx; - MbimMessage *response; - GError *error = NULL; - - self = g_task_get_source_object (task); - - response = mbim_device_command_finish (device, res, &error); - if (response) { - mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error); - mbim_message_unref (response); - } - - if (error) { - g_warning ("[%s] couldn't enable QMI indications via MBIM: %s", - self->priv->path_display, error->message); - g_error_free (error); - } else { - g_debug ("[%s] enabled QMI indications via MBIM", self->priv->path_display); - self->priv->mbim_notification_id = g_signal_connect (device, - MBIM_DEVICE_SIGNAL_INDICATE_STATUS, - G_CALLBACK (mbim_qmi_notification_cb), - self); - } - - /* Go on */ - ctx = g_task_get_task_data (task); - ctx->step++; - device_open_step (task); -} - -static void mbim_device_open_ready (MbimDevice *dev, GAsyncResult *res, GTask *task) @@ -2161,38 +2168,6 @@ mbim_device_open_ready (MbimDevice *dev, self = g_task_get_source_object (task); g_debug ("[%s] MBIM device open", self->priv->path_display); - ctx = g_task_get_task_data (task); - - /* Are indications expected */ - if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_EXPECT_INDICATIONS) { - MbimEventEntry **entries; - guint n_entries = 0; - MbimMessage *request; - - g_debug ("[%s] Enabling QMI indications via MBIM...", self->priv->path_display); - entries = g_new0 (MbimEventEntry *, 2); - entries[n_entries] = g_new (MbimEventEntry, 1); - memcpy (&(entries[n_entries]->device_service_id), MBIM_UUID_QMI, sizeof (MbimUuid)); - entries[n_entries]->cids_count = 1; - entries[n_entries]->cids = g_new0 (guint32, 1); - entries[n_entries]->cids[0] = MBIM_CID_QMI_MSG; - n_entries++; - - request = mbim_message_device_service_subscribe_list_set_new ( - n_entries, - (const MbimEventEntry *const *)entries, - NULL); - mbim_device_command (dev, - request, - 10, - NULL, - (GAsyncReadyCallback)mbim_subscribe_list_set_ready_cb, - task); - mbim_message_unref (request); - mbim_event_entry_array_free (entries); - return; - } - /* Go on */ ctx = g_task_get_task_data (task); ctx->step++; @@ -2465,6 +2440,42 @@ device_open_step (GTask *task) ctx->step++; /* Fall down */ +#if defined MBIM_QMUX_ENABLED + case DEVICE_OPEN_CONTEXT_STEP_FLAGS_EXPECT_INDICATIONS: + /* Enable MBIM indications explicitly ONLY after knowing this is + * a QMI-capable MBIM device. */ + if (self->priv->mbimdev && ctx->flags & QMI_DEVICE_OPEN_FLAGS_EXPECT_INDICATIONS) { + MbimEventEntry **entries; + guint n_entries = 0; + MbimMessage *request; + + g_debug ("[%s] Enabling QMI indications via MBIM...", self->priv->path_display); + entries = g_new0 (MbimEventEntry *, 2); + entries[n_entries] = g_new (MbimEventEntry, 1); + memcpy (&(entries[n_entries]->device_service_id), MBIM_UUID_QMI, sizeof (MbimUuid)); + entries[n_entries]->cids_count = 1; + entries[n_entries]->cids = g_new0 (guint32, 1); + entries[n_entries]->cids[0] = MBIM_CID_QMI_MSG; + n_entries++; + + request = mbim_message_device_service_subscribe_list_set_new ( + n_entries, + (const MbimEventEntry *const *)entries, + NULL); + mbim_device_command (self->priv->mbimdev, + request, + 10, + NULL, + (GAsyncReadyCallback)mbim_subscribe_list_set_ready_cb, + task); + mbim_message_unref (request); + mbim_event_entry_array_free (entries); + return; + } + ctx->step++; + /* Fall down */ +#endif + case DEVICE_OPEN_CONTEXT_STEP_LAST: /* Nothing else to process, done we are */ g_task_return_boolean (task, TRUE); |