diff options
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/qmi-client-ctl.c | 72 | ||||
-rw-r--r-- | src/qmi-message-ctl.c | 18 | ||||
-rw-r--r-- | src/qmi-message-ctl.h | 4 |
4 files changed, 70 insertions, 26 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index d1be081..292eba7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,7 +39,7 @@ qmi-enum-types.c: qmi-enums.h qmi-enum-types.h $(top_srcdir)/build-aux/qmi-enum- # Additional dependencies qmi-device.c: qmi-error-types.h qmi-client.c: qmi-error-types.h qmi-enum-types.h -qmi-client-ctl.c: qmi-error-types.h +qmi-client-ctl.c: qmi-error-types.h qmi-enum-types.h qmi-message.c: qmi-error-types.h qmi-message-ctl.c: qmi-error-types.h diff --git a/src/qmi-client-ctl.c b/src/qmi-client-ctl.c index 2632ef3..16c37cc 100644 --- a/src/qmi-client-ctl.c +++ b/src/qmi-client-ctl.c @@ -23,6 +23,7 @@ #include <gio/gio.h> #include "qmi-error-types.h" +#include "qmi-enum-types.h" #include "qmi-client-ctl.h" G_DEFINE_TYPE (QmiClientCtl, qmi_client_ctl, QMI_TYPE_CLIENT); @@ -122,6 +123,21 @@ qmi_client_ctl_get_version_info (QmiClientCtl *self, /*****************************************************************************/ /* Allocate CID */ +typedef struct { + QmiClientCtl *self; + GSimpleAsyncResult *result; + QmiService service; +} AllocateCidContext; + +static void +allocate_cid_context_complete_and_free (AllocateCidContext *ctx) +{ + g_simple_async_result_complete (ctx->result); + g_object_unref (ctx->result); + g_object_unref (ctx->self); + g_slice_free (AllocateCidContext, ctx); +} + /** * qmi_client_ctl_allocate_cid_finish: * @self: a #QmiClientCtl. @@ -146,33 +162,48 @@ qmi_client_ctl_allocate_cid_finish (QmiClientCtl *self, static void allocate_cid_ready (QmiDevice *device, GAsyncResult *res, - GSimpleAsyncResult *simple) + AllocateCidContext *ctx) { GError *error = NULL; QmiMessage *reply; guint8 cid; + QmiService service; reply = qmi_device_command_finish (device, res, &error); if (!reply) { g_prefix_error (&error, "CID allocation failed: "); - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - g_object_unref (simple); + g_simple_async_result_take_error (ctx->result, error); + allocate_cid_context_complete_and_free (ctx); return; } /* Parse reply */ - cid = qmi_message_ctl_allocate_cid_reply_parse (reply, &error); - if (!cid) { + cid = 0; + service = QMI_SERVICE_UNKNOWN; + if (!qmi_message_ctl_allocate_cid_reply_parse (reply, &cid, &service, &error)) { g_prefix_error (&error, "CID allocation reply parsing failed: "); - g_simple_async_result_take_error (simple, error); - } else - g_simple_async_result_set_op_res_gpointer (simple, - GUINT_TO_POINTER ((guint)cid), - NULL); + g_simple_async_result_take_error (ctx->result, error); + allocate_cid_context_complete_and_free (ctx); + return; + } - g_simple_async_result_complete (simple); - g_object_unref (simple); + /* The service we got must match the one we requested */ + if (service != ctx->service) { + g_simple_async_result_set_error (ctx->result, + QMI_CORE_ERROR, + QMI_CORE_ERROR_FAILED, + "Service mismatch (%s vs %s)", + qmi_service_get_string (service), + qmi_service_get_string (ctx->service)); + allocate_cid_context_complete_and_free (ctx); + return; + } + + /* Set the CID as result */ + g_simple_async_result_set_op_res_gpointer (ctx->result, + GUINT_TO_POINTER ((guint)cid), + NULL); + allocate_cid_context_complete_and_free (ctx); } /** @@ -196,13 +227,16 @@ qmi_client_ctl_allocate_cid (QmiClientCtl *self, GAsyncReadyCallback callback, gpointer user_data) { - GSimpleAsyncResult *result; + AllocateCidContext *ctx; QmiMessage *request; - result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - qmi_client_ctl_allocate_cid); + ctx = g_slice_new (AllocateCidContext); + ctx->self = g_object_ref (self); + ctx->service = service; + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + qmi_client_ctl_allocate_cid); request = qmi_message_ctl_allocate_cid_new (qmi_client_get_next_transaction_id (QMI_CLIENT (self)), service); @@ -211,7 +245,7 @@ qmi_client_ctl_allocate_cid (QmiClientCtl *self, timeout, cancellable, (GAsyncReadyCallback)allocate_cid_ready, - result); + ctx); qmi_message_unref (request); } diff --git a/src/qmi-message-ctl.c b/src/qmi-message-ctl.c index 71e50ff..8879b25 100644 --- a/src/qmi-message-ctl.c +++ b/src/qmi-message-ctl.c @@ -131,23 +131,31 @@ qmi_message_ctl_allocate_cid_new (guint8 transaction_id, return message; } -struct qmi_ctl_allocate_cid { +struct qmi_ctl_cid { guint8 service_type; guint8 cid; } __attribute__((__packed__));; -guint8 +gboolean qmi_message_ctl_allocate_cid_reply_parse (QmiMessage *self, + guint8 *cid, + QmiService *service, GError **error) { - struct qmi_ctl_allocate_cid id; + struct qmi_ctl_cid id; g_assert (qmi_message_get_message_id (self) == QMI_CTL_MESSAGE_ALLOCATE_CLIENT_ID); if (!qmi_message_tlv_get (self, 0x01, sizeof (id), &id, error)) { g_prefix_error (error, "Couldn't get TLV: "); - return 0; + return FALSE; } - return id.cid; + if (cid) + *cid = id.cid; + if (service) + *service = (QmiService)id.service_type; + + return TRUE; +} } diff --git a/src/qmi-message-ctl.h b/src/qmi-message-ctl.h index 2d36cf8..322b6c5 100644 --- a/src/qmi-message-ctl.h +++ b/src/qmi-message-ctl.h @@ -48,7 +48,9 @@ GArray *qmi_message_ctl_version_info_reply_parse (QmiMessage *self, QmiMessage *qmi_message_ctl_allocate_cid_new (guint8 transaction_id, QmiService service); -guint8 qmi_message_ctl_allocate_cid_reply_parse (QmiMessage *self, +gboolean qmi_message_ctl_allocate_cid_reply_parse (QmiMessage *self, + guint8 *cid, + QmiService *service, GError **error); G_END_DECLS |