summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2018-11-04 23:34:21 +0100
committerAleksander Morgado <aleksander@aleksander.es>2018-11-04 23:48:28 +0100
commit5f5e7e9b6e1bde31c23b5152a33caba72fa9c0fe (patch)
tree980312c198ffeaa89ea2412c0d1213676c54894d
parent6a29467070bc7ad5fcfcfe7f4a6bec92285ac389 (diff)
downloadlibqmi-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.c247
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);