aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-04-20 15:05:18 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-07-03 15:47:22 +0200
commitf5085dc99235b00c1a8f63622b1c04af05b51952 (patch)
tree93c6e9a72ef97e5913ce85df2c69cb6798037e46
parent83afa8dcbce2ffabd80a6356f38313b77c5a4193 (diff)
downloadexternal_libqmi-f5085dc99235b00c1a8f63622b1c04af05b51952.zip
external_libqmi-f5085dc99235b00c1a8f63622b1c04af05b51952.tar.gz
external_libqmi-f5085dc99235b00c1a8f63622b1c04af05b51952.tar.bz2
client: ensure the services match in the CID allocation reply
-rw-r--r--src/Makefile.am2
-rw-r--r--src/qmi-client-ctl.c72
-rw-r--r--src/qmi-message-ctl.c18
-rw-r--r--src/qmi-message-ctl.h4
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