diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-04-20 10:07:24 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-07-03 15:47:21 +0200 |
commit | 02467a15bdca99c6cd80cac62414ca725fd3a277 (patch) | |
tree | fd4804b4910a6f4911c8d57df7a08b2448de73a1 /src | |
parent | 3e44d7164179ec3e4d8873e95423d2550de4d08b (diff) | |
download | external_libqmi-02467a15bdca99c6cd80cac62414ca725fd3a277.zip external_libqmi-02467a15bdca99c6cd80cac62414ca725fd3a277.tar.gz external_libqmi-02467a15bdca99c6cd80cac62414ca725fd3a277.tar.bz2 |
client: new base generic client
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/libqmi-glib.h | 2 | ||||
-rw-r--r-- | src/qmi-client.c | 314 | ||||
-rw-r--r-- | src/qmi-client.h | 68 |
4 files changed, 389 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 8525e39..b7326c5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -38,6 +38,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-message.c: qmi-error-types.h qmi-message-ctl.c: qmi-error-types.h @@ -48,7 +49,8 @@ libqmi_glib_la_SOURCES = \ qmi-utils.h qmi-utils.c \ qmi-message.h qmi-message.c \ qmi-message-ctl.h qmi-message-ctl.c \ - qmi-device.h qmi-device.c + qmi-device.h qmi-device.c \ + qmi-client.h qmi-client.c libqmi_glib_la_LIBADD = \ $(LIBQMI_GLIB_LIBS) @@ -58,4 +60,5 @@ include_HEADERS = \ libqmi-glib.h \ qmi-errors.h qmi-error-types.h \ qmi-enums.h qmi-enum-types.h \ - qmi-device.h + qmi-device.h \ + qmi-client.h diff --git a/src/libqmi-glib.h b/src/libqmi-glib.h index 9644b0d..7a73a0c 100644 --- a/src/libqmi-glib.h +++ b/src/libqmi-glib.h @@ -26,6 +26,8 @@ #include "qmi-errors.h" #include "qmi-error-types.h" #include "qmi-enum-types.h" + #include "qmi-device.h" +#include "qmi-client.h" #endif /* _LIBQMI_GLIB_H_ */ diff --git a/src/qmi-client.c b/src/qmi-client.c new file mode 100644 index 0000000..e17c673 --- /dev/null +++ b/src/qmi-client.c @@ -0,0 +1,314 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * libqmi-glib -- GLib/GIO based library to control QMI devices + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright (C) 2012 Aleksander Morgado <aleksander@lanedo.com> + */ + +#include <gio/gio.h> + +#include "qmi-error-types.h" +#include "qmi-enum-types.h" +#include "qmi-client.h" + +static void async_initable_iface_init (GAsyncInitableIface *iface); + +G_DEFINE_TYPE_EXTENDED (QmiClient, qmi_client, G_TYPE_OBJECT, G_TYPE_FLAG_ABSTRACT, + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)); + +enum { + PROP_0, + PROP_DEVICE, + PROP_SERVICE, + PROP_CID, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +struct _QmiClientPrivate { + QmiDevice *device; + QmiService service; + guint8 cid; + + guint16 transaction_id; +}; + +/*****************************************************************************/ + +/** + * qmi_client_get_device: + * @self: a #QmiClient + * + * Get the #QmiDevice associated with this #QmiClient. + * + * Returns: a #QmiClient that must be freed with g_object_unref(). + */ +QmiDevice * +qmi_client_get_device (QmiClient *self) +{ + QmiDevice *device; + + g_return_val_if_fail (QMI_IS_CLIENT (self), NULL); + + g_object_get (G_OBJECT (self), + QMI_CLIENT_DEVICE, &device, + NULL); + + return device; +} + +/** + * qmi_client_peek_device: + * @self: a #QmiClient. + * + * Get the #QmiDevice associated with this #QmiClient, without increasing the reference count + * on the returned object. + * + * Returns: a #QmiDevice. Do not free the returned object, it is owned by @self. + */ +QmiDevice * +qmi_client_peek_device (QmiClient *self) +{ + g_return_val_if_fail (QMI_IS_CLIENT (self), NULL); + + return self->priv->device; +} + +/** + * qmi_client_get_service: + * @self: A #QmiClient + * + * Get the service being used by this #QmiClient. + * + * Returns: a #QmiService. + */ +QmiService +qmi_client_get_service (QmiClient *self) +{ + g_return_val_if_fail (QMI_IS_CLIENT (self), QMI_SERVICE_UNKNOWN); + + return self->priv->service; +} + +/** + * qmi_client_get_cid: + * @self: A #QmiClient + * + * Get the client ID of this #QmiClient. + * + * Returns: the client ID. + */ +guint8 +qmi_client_get_cid (QmiClient *self) +{ + g_return_val_if_fail (QMI_IS_CLIENT (self), 0); + + return self->priv->cid; +} + +/** + * qmi_client_get_next_transaction_id: + * @self: A #QmiClient + * + * Acquire the next transaction ID of this #QmiClient. + * The internal transaction ID gets incremented. + * + * Returns: the next transaction ID. + */ +guint16 +qmi_client_get_next_transaction_id (QmiClient *self) +{ + guint16 next; + + g_return_val_if_fail (QMI_IS_CLIENT (self), 0); + + next = self->priv->transaction_id; + + /* Don't go further than 8bits in the CTL service */ + if ((self->priv->service == QMI_SERVICE_CTL && + self->priv->transaction_id == G_MAXUINT8) || + self->priv->transaction_id == G_MAXUINT16) + /* Reset! */ + self->priv->transaction_id = 0x01; + else + self->priv->transaction_id++; + + return self->priv->transaction_id; +} + +/*****************************************************************************/ +/* Init */ + +static gboolean +initable_init_finish (GAsyncInitable *initable, + GAsyncResult *result, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error); +} + +static void +initable_init_async (GAsyncInitable *initable, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + QmiClient *self = QMI_CLIENT (initable); + GSimpleAsyncResult *result; + GError *error = NULL; + + result = g_simple_async_result_new (G_OBJECT (initable), + callback, + user_data, + initable_init_async); + + /* We need a proper service set to initialize */ + g_assert (self->priv->service != QMI_SERVICE_UNKNOWN); + /* We need a proper device to initialize */ + g_assert (QMI_IS_DEVICE (self->priv->device)); + + if (self->priv->service != QMI_SERVICE_CTL) { + /* TODO: allocate CID */ + } + + g_simple_async_result_set_op_res_gboolean (result, TRUE); + g_simple_async_result_complete_in_idle (result); + g_object_unref (result); +} + +/*****************************************************************************/ + +static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + QmiClient *self = QMI_CLIENT (object); + + switch (prop_id) { + case PROP_DEVICE: + g_assert (self->priv->device == NULL); + self->priv->device = g_value_dup_object (value); + break; + case PROP_SERVICE: + self->priv->service = g_value_get_enum (value); + break; + case PROP_CID: + /* Not writable */ + g_assert_not_reached (); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + QmiClient *self = QMI_CLIENT (object); + + switch (prop_id) { + case PROP_DEVICE: + g_value_set_object (value, self->priv->device); + break; + case PROP_SERVICE: + g_value_set_enum (value, self->priv->service); + break; + case PROP_CID: + g_value_set_uint (value, (guint)self->priv->cid); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +qmi_client_init (QmiClient *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), + QMI_TYPE_CLIENT, + QmiClientPrivate); + + /* Defaults */ + self->priv->service = QMI_SERVICE_UNKNOWN; + self->priv->transaction_id = 0x01; +} + +static void +dispose (GObject *object) +{ + QmiClient *self = QMI_CLIENT (object); + + g_clear_object (&self->priv->device); + + G_OBJECT_CLASS (qmi_client_parent_class)->dispose (object); +} + +static void +async_initable_iface_init (GAsyncInitableIface *iface) +{ + iface->init_async = initable_init_async; + iface->init_finish = initable_init_finish; +} + +static void +qmi_client_class_init (QmiClientClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (QmiClientPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + + properties[PROP_DEVICE] = + g_param_spec_object (QMI_CLIENT_DEVICE, + "Device", + "The QMI device", + QMI_TYPE_DEVICE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_DEVICE, properties[PROP_DEVICE]); + + properties[PROP_SERVICE] = + g_param_spec_enum (QMI_CLIENT_SERVICE, + "Service", + "QMI service this client is using", + QMI_TYPE_SERVICE, + QMI_SERVICE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_SERVICE, properties[PROP_SERVICE]); + + properties[PROP_CID] = + g_param_spec_uint (QMI_CLIENT_CID, + "Client ID", + "ID of the client registered into the QMI device", + 0, + G_MAXUINT8, + 0, + G_PARAM_READABLE); + g_object_class_install_property (object_class, PROP_CID, properties[PROP_CID]); +} diff --git a/src/qmi-client.h b/src/qmi-client.h new file mode 100644 index 0000000..092362c --- /dev/null +++ b/src/qmi-client.h @@ -0,0 +1,68 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * libqmi-glib -- GLib/GIO based library to control QMI devices + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright (C) 2012 Aleksander Morgado <aleksander@lanedo.com> + */ + +#ifndef _LIBQMI_GLIB_QMI_CLIENT_H_ +#define _LIBQMI_GLIB_QMI_CLIENT_H_ + +#include <glib-object.h> + +#include "qmi-enums.h" +#include "qmi-device.h" + +G_BEGIN_DECLS + +#define QMI_TYPE_CLIENT (qmi_client_get_type ()) +#define QMI_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), QMI_TYPE_CLIENT, QmiClient)) +#define QMI_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), QMI_TYPE_CLIENT, QmiClientClass)) +#define QMI_IS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), QMI_TYPE_CLIENT)) +#define QMI_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), QMI_TYPE_CLIENT)) +#define QMI_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), QMI_TYPE_CLIENT, QmiClientClass)) + +typedef struct _QmiClient QmiClient; +typedef struct _QmiClientClass QmiClientClass; +typedef struct _QmiClientPrivate QmiClientPrivate; + +#define QMI_CLIENT_DEVICE "client-device" +#define QMI_CLIENT_SERVICE "client-service" +#define QMI_CLIENT_CID "client-cid" + +struct _QmiClient { + GObject parent; + QmiClientPrivate *priv; +}; + +struct _QmiClientClass { + GObjectClass parent; +}; + +GType qmi_client_get_type (void); + +QmiDevice *qmi_client_get_device (QmiClient *self); +QmiDevice *qmi_client_peek_device (QmiClient *self); +QmiService qmi_client_get_service (QmiClient *self); +guint8 qmi_client_get_cid (QmiClient *self); + +guint16 qmi_client_get_next_transaction_id (QmiClient *self); + +G_END_DECLS + +#endif /* _LIBQMI_GLIB_QMI_CLIENT_H_ */ |