diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-07-03 15:58:43 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-07-03 16:08:59 +0200 |
commit | cb6985816bdafc40fee6d57c6320e18906990ba7 (patch) | |
tree | 87be9a395a77365a516afa0f4d4015cdf3e8e37b /src | |
parent | 4b8910554d91768db711c9f05ad992b8a70c590e (diff) | |
download | external_libqmi-cb6985816bdafc40fee6d57c6320e18906990ba7.zip external_libqmi-cb6985816bdafc40fee6d57c6320e18906990ba7.tar.gz external_libqmi-cb6985816bdafc40fee6d57c6320e18906990ba7.tar.bz2 |
build: prepare sources to treat `libqmi-glib' not as the only library
Instead of keeping the libqmi-glib sources under `src', we'll have a more
specific `libqmi-glib' directory instead.
Also, update autotools to reflect as `libqmi' the name of the project.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 118 | ||||
-rw-r--r-- | src/libqmi-glib.h | 35 | ||||
-rw-r--r-- | src/qmi-client.c | 265 | ||||
-rw-r--r-- | src/qmi-client.h | 79 | ||||
-rw-r--r-- | src/qmi-device.c | 1812 | ||||
-rw-r--r-- | src/qmi-device.h | 145 | ||||
-rw-r--r-- | src/qmi-enums-dms.h | 195 | ||||
-rw-r--r-- | src/qmi-enums-wds.h | 197 | ||||
-rw-r--r-- | src/qmi-enums.h | 86 | ||||
-rw-r--r-- | src/qmi-errors.h | 212 | ||||
-rw-r--r-- | src/qmi-message.c | 707 | ||||
-rw-r--r-- | src/qmi-message.h | 104 | ||||
-rw-r--r-- | src/qmi-utils.c | 312 | ||||
-rw-r--r-- | src/qmi-utils.h | 95 |
14 files changed, 0 insertions, 4362 deletions
diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index e5b1156..0000000 --- a/src/Makefile.am +++ /dev/null @@ -1,118 +0,0 @@ - -lib_LTLIBRARIES = libqmi-glib.la - -libqmi_glib_la_CPPFLAGS = \ - $(LIBQMI_GLIB_CFLAGS) \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(top_srcdir)/src \ - -I$(top_builddir)/src - -# Error types -qmi-error-types.h: qmi-errors.h $(top_srcdir)/build-aux/templates/qmi-error-types-template.h - $(AM_V_GEN) $(GLIB_MKENUMS) \ - --fhead "#ifndef __LIBQMI_GLIB_ERROR_TYPES_H__\n#define __LIBQMI_GLIB_ERROR_TYPES_H__\n#include \"qmi-errors.h\"\n" \ - --template $(top_srcdir)/build-aux/templates/qmi-error-types-template.h \ - --ftail "#endif /* __LIBQMI_GLIB_ERROR_TYPES_H__ */\n" \ - qmi-errors.h > $@ - -qmi-error-types.c: qmi-errors.h qmi-error-types.h $(top_srcdir)/build-aux/templates/qmi-error-types-template.c - $(AM_V_GEN) $(GLIB_MKENUMS) \ - --fhead "#include \"qmi-errors.h\"\n#include \"qmi-error-types.h\"\n" \ - --template $(top_srcdir)/build-aux/templates/qmi-error-types-template.c \ - qmi-errors.h > $@ - -# Enum types -ENUMS = qmi-enums.h qmi-enums-wds.h qmi-enums-dms.h qmi-dms.h qmi-wds.h qmi-ctl.h -qmi-enum-types.h: $(ENUMS) $(top_srcdir)/build-aux/templates/qmi-enum-types-template.h qmi-ctl.stamp qmi-dms.stamp qmi-wds.stamp - $(AM_V_GEN) $(GLIB_MKENUMS) \ - --fhead "#ifndef __LIBQMI_GLIB_ENUM_TYPES_H__\n#define __LIBQMI_GLIB_ENUM_TYPES_H__\n#include \"qmi-enums.h\"\n#include \"qmi-enums-wds.h\"\n#include \"qmi-enums-dms.h\"\n#include \"qmi-ctl.h\"\n#include \"qmi-dms.h\"\n#include \"qmi-wds.h\"\n" \ - --template $(top_srcdir)/build-aux/templates/qmi-enum-types-template.h \ - --ftail "#endif /* __LIBQMI_GLIB_ENUM_TYPES_H__ */\n" \ - $(ENUMS) > $@ - -qmi-enum-types.c: $(ENUMS) qmi-enum-types.h $(top_srcdir)/build-aux/templates/qmi-enum-types-template.c - $(AM_V_GEN) $(GLIB_MKENUMS) \ - --fhead "#include \"qmi-enum-types.h\"\n" \ - --template $(top_srcdir)/build-aux/templates/qmi-enum-types-template.c \ - $(ENUMS) > $@ - -# CTL service -qmi-ctl.stamp: $(top_srcdir)/data/qmi-service-ctl.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen - $(AM_V_GEN) \ - rm -f qmi-ctl.h && \ - rm -f qmi-ctl.c && \ - $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \ - --input $(top_srcdir)/data/qmi-service-ctl.json \ - --include $(top_srcdir)/data/qmi-common.json \ - --output qmi-ctl && \ - touch $@ - -# DMS service -qmi-dms.stamp: $(top_srcdir)/data/qmi-service-dms.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen - $(AM_V_GEN) \ - rm -f qmi-dms.h && \ - rm -f qmi-dms.c && \ - $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \ - --input $(top_srcdir)/data/qmi-service-dms.json \ - --include $(top_srcdir)/data/qmi-common.json \ - --output qmi-dms && \ - touch $@ - -# WDS service -qmi-wds.stamp: $(top_srcdir)/data/qmi-service-wds.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen - $(AM_V_GEN) \ - rm -f qmi-wds.h && \ - rm -f qmi-wds.c && \ - $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \ - --input $(top_srcdir)/data/qmi-service-wds.json \ - --include $(top_srcdir)/data/qmi-common.json \ - --output qmi-wds && \ - touch $@ - -# Additional dependencies -qmi-device.c: qmi-error-types.h qmi-enum-types.h -qmi-client.c: qmi-error-types.h qmi-enum-types.h -qmi-message.c: qmi-error-types.h qmi-enum-types.h qmi-ctl.h qmi-dms.h qmi-wds.h -qmi-ctl.h: qmi-ctl.stamp -qmi-ctl.c: qmi-error-types.h qmi-enum-types.h qmi-ctl.stamp -qmi-dms.h: qmi-dms.stamp -qmi-dms.c: qmi-error-types.h qmi-enum-types.h qmi-dms.stamp -qmi-wds.h: qmi-wds.stamp -qmi-wds.c: qmi-error-types.h qmi-enum-types.h qmi-wds.stamp - -libqmi_glib_la_SOURCES = \ - libqmi-glib.h \ - qmi-errors.h qmi-error-types.h qmi-error-types.c \ - qmi-enums-wds.h \ - qmi-enums-dms.h \ - qmi-enums.h qmi-enum-types.h qmi-enum-types.c \ - qmi-utils.h qmi-utils.c \ - qmi-message.h qmi-message.c \ - qmi-device.h qmi-device.c \ - qmi-client.h qmi-client.c - -nodist_libqmi_glib_la_SOURCES = \ - qmi-ctl.c qmi-ctl.h \ - qmi-dms.c qmi-dms.h \ - qmi-wds.c qmi-wds.h - -libqmi_glib_la_LIBADD = \ - $(LIBQMI_GLIB_LIBS) - -includedir = @includedir@/libqmi-glib -include_HEADERS = \ - libqmi-glib.h \ - qmi-errors.h qmi-error-types.h \ - qmi-enums.h qmi-enum-types.h \ - qmi-message.h \ - qmi-device.h \ - qmi-client.h \ - qmi-ctl.h \ - qmi-enums-dms.h qmi-dms.h \ - qmi-enums-wds.h qmi-wds.h - -CLEANFILES = \ - qmi-ctl.h qmi-ctl.c qmi-ctl.stamp \ - qmi-dms.h qmi-dms.c qmi-dms.stamp \ - qmi-wds.h qmi-wds.c qmi-wds.stamp diff --git a/src/libqmi-glib.h b/src/libqmi-glib.h deleted file mode 100644 index c6d6a65..0000000 --- a/src/libqmi-glib.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- 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_H_ -#define _LIBQMI_GLIB_H_ - -#include "qmi-errors.h" -#include "qmi-error-types.h" -#include "qmi-enum-types.h" - -#include "qmi-device.h" -#include "qmi-client.h" -#include "qmi-dms.h" -#include "qmi-wds.h" - -#endif /* _LIBQMI_GLIB_H_ */ diff --git a/src/qmi-client.c b/src/qmi-client.c deleted file mode 100644 index f3e6bab..0000000 --- a/src/qmi-client.c +++ /dev/null @@ -1,265 +0,0 @@ -/* -*- 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-device.h" -#include "qmi-client.h" -#include "qmi-ctl.h" - -G_DEFINE_ABSTRACT_TYPE (QmiClient, qmi_client, G_TYPE_OBJECT); - -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 #GObject that must be freed with g_object_unref(). - */ -GObject * -qmi_client_get_device (QmiClient *self) -{ - GObject *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 #GObject. Do not free the returned object, it is owned by @self. - */ -GObject * -qmi_client_peek_device (QmiClient *self) -{ - g_return_val_if_fail (QMI_IS_CLIENT (self), NULL); - - return G_OBJECT (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), QMI_CID_NONE); - - 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 next; -} - -/*****************************************************************************/ - -void -qmi_client_process_indication (QmiClient *self, - QmiMessage *message) -{ - if (QMI_CLIENT_GET_CLASS (self)->process_indication) - QMI_CLIENT_GET_CLASS (self)->process_indication (self, message); -} - -/*****************************************************************************/ - -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: - /* NOTE!! We do NOT keep a reference to the device here. - * Clients are OWNED by the device */ - self->priv->device = g_value_get_object (value); - break; - case PROP_SERVICE: - self->priv->service = g_value_get_enum (value); - break; - case PROP_CID: - self->priv->cid = (guint8)g_value_get_uint (value); - 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; - self->priv->cid = QMI_CID_NONE; -} - -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; - - properties[PROP_DEVICE] = - g_param_spec_object (QMI_CLIENT_DEVICE, - "Device", - "The QMI device", - QMI_TYPE_DEVICE, - G_PARAM_READWRITE); - 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_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, - QMI_CID_NONE, - G_PARAM_READWRITE); - g_object_class_install_property (object_class, PROP_CID, properties[PROP_CID]); -} diff --git a/src/qmi-client.h b/src/qmi-client.h deleted file mode 100644 index 828211e..0000000 --- a/src/qmi-client.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- 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-message.h" - -G_BEGIN_DECLS - -#define QMI_CID_NONE 0x00 -#define QMI_CID_BROADCAST 0xFF - -#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; - - /* Virtual method to get indications processed */ - void (* process_indication) (QmiClient *self, - QmiMessage *message); -}; - -GType qmi_client_get_type (void); - -GObject *qmi_client_get_device (QmiClient *self); -GObject *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); - -/* not part of the public API */ -void qmi_client_process_indication (QmiClient *self, - QmiMessage *message); - -G_END_DECLS - -#endif /* _LIBQMI_GLIB_QMI_CLIENT_H_ */ diff --git a/src/qmi-device.c b/src/qmi-device.c deleted file mode 100644 index 170795d..0000000 --- a/src/qmi-device.c +++ /dev/null @@ -1,1812 +0,0 @@ -/* -*- 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 <errno.h> -#include <string.h> -#include <fcntl.h> -#include <termios.h> -#include <unistd.h> -#include <gio/gio.h> - -#include "qmi-device.h" -#include "qmi-message.h" -#include "qmi-ctl.h" -#include "qmi-dms.h" -#include "qmi-wds.h" -#include "qmi-utils.h" -#include "qmi-error-types.h" -#include "qmi-enum-types.h" - -static void async_initable_iface_init (GAsyncInitableIface *iface); - -G_DEFINE_TYPE_EXTENDED (QmiDevice, qmi_device, G_TYPE_OBJECT, 0, - G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)) - -enum { - PROP_0, - PROP_FILE, - PROP_CLIENT_CTL, - PROP_LAST -}; - -static GParamSpec *properties[PROP_LAST]; - -struct _QmiDevicePrivate { - /* File */ - GFile *file; - gchar *path; - gchar *path_display; - - /* Implicit CTL client */ - QmiClientCtl *client_ctl; - - /* Supported services */ - GArray *supported_services; - - /* I/O channel, set when the file is open */ - GIOChannel *iochannel; - guint watch_id; - GByteArray *response; - - /* HT to keep track of ongoing transactions */ - GHashTable *transactions; - - /* HT of clients that want to get indications */ - GHashTable *registered_clients; -}; - -#define BUFFER_SIZE 2048 - -/*****************************************************************************/ -/* Message transactions (private) */ - -typedef struct { - QmiMessage *message; - GSimpleAsyncResult *result; - guint timeout_id; -} Transaction; - -static Transaction * -transaction_new (QmiDevice *self, - QmiMessage *message, - GAsyncReadyCallback callback, - gpointer user_data) -{ - Transaction *tr; - - tr = g_slice_new0 (Transaction); - tr->message = qmi_message_ref (message); - tr->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - transaction_new); - - return tr; -} - -static void -transaction_complete_and_free (Transaction *tr, - QmiMessage *reply, - const GError *error) -{ - g_assert (reply != NULL || error != NULL); - - if (tr->timeout_id) - g_source_remove (tr->timeout_id); - - if (reply) - g_simple_async_result_set_op_res_gpointer (tr->result, - qmi_message_ref (reply), - (GDestroyNotify)qmi_message_unref); - else - g_simple_async_result_set_from_error (tr->result, error); - - g_simple_async_result_complete_in_idle (tr->result); - g_object_unref (tr->result); - qmi_message_unref (tr->message); - g_slice_free (Transaction, tr); -} - -static inline gpointer -build_transaction_key (QmiMessage *message) -{ - gpointer key; - guint8 service; - guint8 client_id; - guint16 transaction_id; - - service = (guint8)qmi_message_get_service (message); - client_id = qmi_message_get_client_id (message); - transaction_id = qmi_message_get_transaction_id (message); - - /* We're putting a 32 bit value into a gpointer */ - key = GUINT_TO_POINTER ((((service << 8) | client_id) << 16) | transaction_id); - -#ifdef MESSAGE_ENABLE_TRACE - { - gchar *hex; - - hex = qmi_utils_str_hex (&key, sizeof (key), ':'); - g_debug ("KEY: %s", hex); - g_free (hex); - - hex = qmi_utils_str_hex (&service, sizeof (service), ':'); - g_debug (" Service: %s", hex); - g_free (hex); - - hex = qmi_utils_str_hex (&client_id, sizeof (client_id), ':'); - g_debug (" Client ID: %s", hex); - g_free (hex); - - hex = qmi_utils_str_hex (&transaction_id, sizeof (transaction_id), ':'); - g_debug (" Transaction ID: %s", hex); - g_free (hex); - } -#endif /* MESSAGE_ENABLE_TRACE */ - - return key; -} - -static Transaction * -device_release_transaction (QmiDevice *self, - gpointer key) -{ - Transaction *tr = NULL; - - if (self->priv->transactions) { - tr = g_hash_table_lookup (self->priv->transactions, key); - if (tr) - /* If found, remove it from the HT */ - g_hash_table_remove (self->priv->transactions, key); - } - - return tr; -} - -typedef struct { - QmiDevice *self; - gpointer key; -} TransactionTimeoutContext; - -static void -transaction_timeout_context_free (TransactionTimeoutContext *ctx) -{ - g_slice_free (TransactionTimeoutContext, ctx); -} - -static gboolean -transaction_timed_out (TransactionTimeoutContext *ctx) -{ - Transaction *tr; - GError *error = NULL; - - tr = device_release_transaction (ctx->self, ctx->key); - tr->timeout_id = 0; - - /* Complete transaction with a timeout error */ - error = g_error_new (QMI_CORE_ERROR, - QMI_CORE_ERROR_TIMEOUT, - "Transaction timed out"); - transaction_complete_and_free (tr, NULL, error); - g_error_free (error); - - return FALSE; -} - -static void -device_store_transaction (QmiDevice *self, - Transaction *tr, - guint timeout) -{ - TransactionTimeoutContext *timeout_ctx; - gpointer key; - - if (G_UNLIKELY (!self->priv->transactions)) - self->priv->transactions = g_hash_table_new (g_direct_hash, - g_direct_equal); - - key = build_transaction_key (tr->message); - g_hash_table_insert (self->priv->transactions, key, tr); - - /* Once it gets into the HT, setup the timeout */ - timeout_ctx = g_slice_new (TransactionTimeoutContext); - timeout_ctx->self = self; - timeout_ctx->key = key; /* valid as long as the transaction is in the HT */ - tr->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, - timeout, - (GSourceFunc)transaction_timed_out, - timeout_ctx, - (GDestroyNotify)transaction_timeout_context_free); -} - -static Transaction * -device_match_transaction (QmiDevice *self, - QmiMessage *message) -{ - /* msg can be either the original message or the response */ - return device_release_transaction (self, build_transaction_key (message)); -} - -/*****************************************************************************/ - -/** - * qmi_device_get_file: - * @self: a #QmiDevice. - * - * Get the #GFile associated with this #QmiDevice. - * - * Returns: a #GFile that must be freed with g_object_unref(). - */ -GFile * -qmi_device_get_file (QmiDevice *self) -{ - GFile *file = NULL; - - g_return_val_if_fail (QMI_IS_DEVICE (self), NULL); - - g_object_get (G_OBJECT (self), - QMI_DEVICE_FILE, &file, - NULL); - return file; -} - -/** - * qmi_device_peek_file: - * @self: a #QmiDevice. - * - * Get the #GFile associated with this #QmiDevice, without increasing the reference count - * on the returned object. - * - * Returns: a #GFile. Do not free the returned object, it is owned by @self. - */ -GFile * -qmi_device_peek_file (QmiDevice *self) -{ - g_return_val_if_fail (QMI_IS_DEVICE (self), NULL); - - return self->priv->file; -} - -/** - * qmi_device_get_path: - * @self: a #QmiDevice. - * - * Get the system path of the underlying QMI device. - * - * Returns: the system path of the device. - */ -const gchar * -qmi_device_get_path (QmiDevice *self) -{ - g_return_val_if_fail (QMI_IS_DEVICE (self), NULL); - - return self->priv->path; -} - -/** - * qmi_device_get_path_display: - * @self: a #QmiDevice. - * - * Get the system path of the underlying QMI device in UTF-8. - * - * Returns: UTF-8 encoded system path of the device. - */ -const gchar * -qmi_device_get_path_display (QmiDevice *self) -{ - g_return_val_if_fail (QMI_IS_DEVICE (self), NULL); - - return self->priv->path_display; -} - -/** - * qmi_device_is_open: - * @self: a #QmiDevice. - * - * Checks whether the #QmiDevice is open for I/O. - * - * Returns: #TRUE if @self is open, #FALSE otherwise. - */ -gboolean -qmi_device_is_open (QmiDevice *self) -{ - g_return_val_if_fail (QMI_IS_DEVICE (self), FALSE); - - return !!self->priv->iochannel; -} - -/*****************************************************************************/ -/* Register/Unregister clients that want to receive indications */ - -static gpointer -build_registered_client_key (guint8 cid, - QmiService service) -{ - return GUINT_TO_POINTER (((guint8)service << 8) | cid); -} - -static gboolean -register_client (QmiDevice *self, - QmiClient *client, - GError **error) -{ - gpointer key; - - key = build_registered_client_key (qmi_client_get_cid (client), - qmi_client_get_service (client)); - /* Only add the new client if not already registered one with the same CID - * for the same service */ - if (g_hash_table_lookup (self->priv->registered_clients, key)) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_FAILED, - "A client with CID '%u' and service '%s' is already registered", - qmi_client_get_cid (client), - qmi_service_get_string (qmi_client_get_service (client))); - return FALSE; - } - - g_hash_table_insert (self->priv->registered_clients, - key, - g_object_ref (client)); - return TRUE; -} - -static void -unregister_client (QmiDevice *self, - QmiClient *client) -{ - g_hash_table_remove (self->priv->registered_clients, - build_registered_client_key (qmi_client_get_cid (client), - qmi_client_get_service (client))); -} - -/*****************************************************************************/ -/* Allocate new client */ - -typedef struct { - QmiDevice *self; - GSimpleAsyncResult *result; - QmiService service; - GType client_type; - guint8 cid; -} AllocateClientContext; - -static void -allocate_client_context_complete_and_free (AllocateClientContext *ctx) -{ - g_simple_async_result_complete_in_idle (ctx->result); - g_object_unref (ctx->result); - g_object_unref (ctx->self); - g_slice_free (AllocateClientContext, ctx); -} - -/** - * qmi_device_allocate_client_finish: - * @self: a #QmiDevice. - * @res: a #GAsyncResult. - * @error: a #GError. - * - * Finishes an operation started with qmi_device_allocate_client(). - * - * Returns: a newly allocated #QmiClient, or #NULL if @error is set. - */ -QmiClient * -qmi_device_allocate_client_finish (QmiDevice *self, - GAsyncResult *res, - GError **error) -{ - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) - return NULL; - - return QMI_CLIENT (g_object_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)))); -} - -static void -build_client_object (AllocateClientContext *ctx) -{ - QmiClient *client; - GError *error = NULL; - - /* We now have a proper CID for the client, we should be able to create it - * right away */ - client = g_object_new (ctx->client_type, - QMI_CLIENT_DEVICE, ctx->self, - QMI_CLIENT_SERVICE, ctx->service, - QMI_CLIENT_CID, ctx->cid, - NULL); - - /* Register the client to get indications */ - if (!register_client (ctx->self, client, &error)) { - g_prefix_error (&error, - "Cannot register new client with CID '%u' and service '%s'", - ctx->cid, - qmi_service_get_string (ctx->service)); - g_simple_async_result_take_error (ctx->result, error); - allocate_client_context_complete_and_free (ctx); - g_object_unref (client); - return; - } - - g_debug ("Registered '%s' client with ID '%u'", - qmi_service_get_string (ctx->service), - ctx->cid); - - /* Client created and registered, complete successfully */ - g_simple_async_result_set_op_res_gpointer (ctx->result, - client, - (GDestroyNotify)g_object_unref); - allocate_client_context_complete_and_free (ctx); -} - -static void -allocate_cid_ready (QmiClientCtl *client_ctl, - GAsyncResult *res, - AllocateClientContext *ctx) -{ - QmiMessageCtlAllocateCidOutput *output; - QmiService service; - guint8 cid; - GError *error = NULL; - - /* Check result of the async operation */ - output = qmi_client_ctl_allocate_cid_finish (client_ctl, res, &error); - if (!output) { - g_prefix_error (&error, "CID allocation failed in the CTL client: "); - g_simple_async_result_take_error (ctx->result, error); - allocate_client_context_complete_and_free (ctx); - return; - } - - /* Check result of the QMI operation */ - if (!qmi_message_ctl_allocate_cid_output_get_result (output, &error)) { - g_simple_async_result_take_error (ctx->result, error); - allocate_client_context_complete_and_free (ctx); - qmi_message_ctl_allocate_cid_output_unref (output); - return; - } - - /* Allocation info is mandatory when result is success */ - g_assert (qmi_message_ctl_allocate_cid_output_get_allocation_info (output, &service, &cid, NULL)); - - if (service != ctx->service) { - g_simple_async_result_set_error ( - ctx->result, - QMI_CORE_ERROR, - QMI_CORE_ERROR_FAILED, - "CID allocation failed in the CTL client: " - "Service mismatch (requested '%s', got '%s')", - qmi_service_get_string (ctx->service), - qmi_service_get_string (service)); - allocate_client_context_complete_and_free (ctx); - qmi_message_ctl_allocate_cid_output_unref (output); - return; - } - - ctx->cid = cid; - build_client_object (ctx); - qmi_message_ctl_allocate_cid_output_unref (output); -} - -static gboolean -check_service_supported (QmiDevice *self, - QmiService service) -{ - guint i; - - /* If we didn't check supported services, just assume it is supported */ - if (!self->priv->supported_services) { - g_debug ("Assuming service '%s' is supported...", - qmi_service_get_string (service)); - return TRUE; - } - - for (i = 0; i < self->priv->supported_services->len; i++) { - QmiMessageCtlGetVersionInfoOutputServiceListService *info; - - info = &g_array_index (self->priv->supported_services, - QmiMessageCtlGetVersionInfoOutputServiceListService, - i); - - if (service == info->service) - return TRUE; - } - - return FALSE; -} - -/** - * qmi_device_allocate_client: - * @self: a #QmiDevice. - * @service: a valid #QmiService. - * @cid: a valid client ID, or #QMI_CID_NONE. - * @timeout: maximum time to wait. - * @cancellable: optional #GCancellable object, #NULL to ignore. - * @callback: a #GAsyncReadyCallback to call when the operation is finished. - * @user_data: the data to pass to callback function. - * - * Asynchronously allocates a new #QmiClient in @self. - * - * If #QMI_CID_NONE is given in @cid, a new client ID will be allocated; - * otherwise a client with the given @cid will be generated. - * - * When the operation is finished @callback will be called. You can then call - * qmi_device_allocate_client_finish() to get the result of the operation. - * - * Note: Clients for the #QMI_SERVICE_CTL cannot be created with this method; - * instead get/peek the implicit one from @self. - */ -void -qmi_device_allocate_client (QmiDevice *self, - QmiService service, - guint8 cid, - guint timeout, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - AllocateClientContext *ctx; - - g_return_if_fail (QMI_IS_DEVICE (self)); - g_return_if_fail (service != QMI_SERVICE_UNKNOWN); - - ctx = g_slice_new0 (AllocateClientContext); - ctx->self = g_object_ref (self); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - qmi_device_allocate_client); - ctx->service = service; - - /* Check if the requested service is supported by the device */ - if (!check_service_supported (self, service)) { - g_simple_async_result_set_error (ctx->result, - QMI_CORE_ERROR, - QMI_CORE_ERROR_UNSUPPORTED, - "Service '%s' not supported by the device", - qmi_service_get_string (service)); - allocate_client_context_complete_and_free (ctx); - return; - } - - switch (service) { - case QMI_SERVICE_CTL: - g_simple_async_result_set_error (ctx->result, - QMI_CORE_ERROR, - QMI_CORE_ERROR_INVALID_ARGS, - "Cannot create additional clients for the CTL service"); - allocate_client_context_complete_and_free (ctx); - return; - - case QMI_SERVICE_DMS: - ctx->client_type = QMI_TYPE_CLIENT_DMS; - break; - - case QMI_SERVICE_WDS: - ctx->client_type = QMI_TYPE_CLIENT_WDS; - break; - - default: - g_simple_async_result_set_error (ctx->result, - QMI_CORE_ERROR, - QMI_CORE_ERROR_INVALID_ARGS, - "Clients for service '%s' not yet supported", - qmi_service_get_string (service)); - allocate_client_context_complete_and_free (ctx); - return; - } - - /* Allocate a new CID for the client to be created */ - if (cid == QMI_CID_NONE) { - QmiMessageCtlAllocateCidInput *input; - - input = qmi_message_ctl_allocate_cid_input_new (); - qmi_message_ctl_allocate_cid_input_set_service (input, ctx->service, NULL); - - g_debug ("Allocating new client ID..."); - qmi_client_ctl_allocate_cid (self->priv->client_ctl, - input, - timeout, - cancellable, - (GAsyncReadyCallback)allocate_cid_ready, - ctx); - - qmi_message_ctl_allocate_cid_input_unref (input); - return; - } - - /* Reuse the given CID */ - g_debug ("Reusing client CID '%u'...", cid); - ctx->cid = cid; - build_client_object (ctx); -} - -/*****************************************************************************/ -/* Release client */ - -typedef struct { - QmiClient *client; - GSimpleAsyncResult *result; -} ReleaseClientContext; - -static void -release_client_context_complete_and_free (ReleaseClientContext *ctx) -{ - g_simple_async_result_complete_in_idle (ctx->result); - g_object_unref (ctx->result); - g_object_unref (ctx->client); - g_slice_free (ReleaseClientContext, ctx); -} - -/** - * qmi_device_release_client_finish: - * @self: a #QmiDevice. - * @res: a #GAsyncResult. - * @error: a #GError. - * - * Finishes an operation started with qmi_device_release_client(). - * - * Note that even if the release operation returns an error, the client should - * anyway be considered released, and shouldn't be used afterwards. - * - * Returns: #TRUE if successful, or #NULL if @error is set. - */ -gboolean -qmi_device_release_client_finish (QmiDevice *self, - GAsyncResult *res, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - -static void -client_ctl_release_cid_ready (QmiClientCtl *client_ctl, - GAsyncResult *res, - ReleaseClientContext *ctx) -{ - GError *error = NULL; - QmiMessageCtlReleaseCidOutput *output; - - /* Note: even if we return an error, the client is to be considered - * released! (so shouldn't be used) */ - - /* Check result of the async operation */ - output = qmi_client_ctl_release_cid_finish (client_ctl, res, &error); - if (!output) { - g_simple_async_result_take_error (ctx->result, error); - release_client_context_complete_and_free (ctx); - return; - } - - /* Check result of the QMI operation */ - if (!qmi_message_ctl_release_cid_output_get_result (output, &error)) { - g_simple_async_result_take_error (ctx->result, error); - release_client_context_complete_and_free (ctx); - qmi_message_ctl_release_cid_output_unref (output); - return; - } - - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - release_client_context_complete_and_free (ctx); - qmi_message_ctl_release_cid_output_unref (output); -} - -/** - * qmi_device_release_client: - * @self: a #QmiDevice. - * @client: the #QmiClient to release. - * @flags: mask of #QmiDeviceReleaseClientFlags specifying how the client should be released. - * @timeout: maximum time to wait. - * @cancellable: optional #GCancellable object, #NULL to ignore. - * @callback: a #GAsyncReadyCallback to call when the operation is finished. - * @user_data: the data to pass to callback function. - * - * Asynchronously releases the #QmiClient from the #QmiDevice. - * - * Once the #QmiClient has been released, it cannot be used any more to - * perform operations. - * - * - * When the operation is finished @callback will be called. You can then call - * qmi_device_release_client_finish() to get the result of the operation. - */ -void -qmi_device_release_client (QmiDevice *self, - QmiClient *client, - QmiDeviceReleaseClientFlags flags, - guint timeout, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - ReleaseClientContext *ctx; - QmiService service; - guint8 cid; - - g_return_if_fail (QMI_IS_DEVICE (self)); - g_return_if_fail (QMI_IS_CLIENT (client)); - - /* The CTL client should not have been created out of the QmiDevice */ - g_assert (qmi_client_get_service (client) != QMI_SERVICE_CTL); - - /* NOTE! The operation must not take a reference to self, or we won't be - * able to use it implicitly from our dispose() */ - - ctx = g_slice_new0 (ReleaseClientContext); - ctx->client = g_object_ref (client); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - qmi_device_release_client); - - cid = qmi_client_get_cid (client); - service = (guint8)qmi_client_get_service (client); - - /* Do not try to release an already released client */ - if (cid == QMI_CID_NONE) { - g_simple_async_result_set_error (ctx->result, - QMI_CORE_ERROR, - QMI_CORE_ERROR_INVALID_ARGS, - "Client is already released"); - release_client_context_complete_and_free (ctx); - return; - } - - /* Unregister from device */ - unregister_client (self, client); - - g_debug ("Unregistered '%s' client with ID '%u'", - qmi_service_get_string (service), - cid); - - /* Reset the contents of the client object, making it unusable */ - g_object_set (client, - QMI_CLIENT_CID, QMI_CID_NONE, - QMI_CLIENT_SERVICE, QMI_SERVICE_UNKNOWN, - QMI_CLIENT_DEVICE, NULL, - NULL); - - if (flags & QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID) { - QmiMessageCtlReleaseCidInput *input; - - /* And now, really try to release the CID */ - input = qmi_message_ctl_release_cid_input_new (); - qmi_message_ctl_release_cid_input_set_release_info (input, service,cid, NULL); - - /* And now, really try to release the CID */ - qmi_client_ctl_release_cid (self->priv->client_ctl, - input, - timeout, - cancellable, - (GAsyncReadyCallback)client_ctl_release_cid_ready, - ctx); - - qmi_message_ctl_release_cid_input_unref (input); - return; - } - - /* No need to release the CID, so just done */ - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - release_client_context_complete_and_free (ctx); - return; -} - -/*****************************************************************************/ -/* Open device */ - -typedef struct { - QmiClient *client; - QmiMessage *message; -} IdleIndicationContext; - -static gboolean -process_indication_idle (IdleIndicationContext *ctx) -{ - g_assert (ctx->client != NULL); - g_assert (ctx->message != NULL); - - qmi_client_process_indication (ctx->client, ctx->message); - - g_object_unref (ctx->client); - qmi_message_unref (ctx->message); - g_slice_free (IdleIndicationContext, ctx); - return FALSE; -} - -static void -report_indication (QmiClient *client, - QmiMessage *message) -{ - IdleIndicationContext *ctx; - - /* Setup an idle to Pass the indication down to the client */ - ctx = g_slice_new (IdleIndicationContext); - ctx->client = g_object_ref (client); - ctx->message = qmi_message_ref (message); - g_idle_add ((GSourceFunc)process_indication_idle, ctx); -} - -static void -process_message (QmiDevice *self, - QmiMessage *message) -{ - GError *error = NULL; - - /* Ensure the read message is valid */ - if (!qmi_message_check (message, &error)) { - g_warning ("Invalid QMI message received: %s", - error->message); - g_error_free (error); - return; - } - -#ifdef MESSAGE_ENABLE_TRACE - { - gchar *printable; - - printable = qmi_message_get_printable (message, ">>>>>> "); - g_debug ("[%s] Received message...\n%s", - self->priv->path_display, - printable); - g_free (printable); - } -#endif /* MESSAGE_ENABLE_TRACE */ - - if (qmi_message_is_indication (message)) { - if (qmi_message_get_client_id (message) == QMI_CID_BROADCAST) { - GHashTableIter iter; - gpointer key; - QmiClient *client; - - g_hash_table_iter_init (&iter, self->priv->registered_clients); - while (g_hash_table_iter_next (&iter, &key, (gpointer *)&client)) { - /* For broadcast messages, report them just if the service matches */ - if (qmi_message_get_service (message) == qmi_client_get_service (client)) - report_indication (client, message); - } - } else { - QmiClient *client; - - client = g_hash_table_lookup (self->priv->registered_clients, - build_registered_client_key (qmi_message_get_client_id (message), - qmi_message_get_service (message))); - if (client) - report_indication (client, message); - } - - return; - } - - if (qmi_message_is_response (message)) { - Transaction *tr; - - tr = device_match_transaction (self, message); - if (!tr) - g_debug ("[%s] No transaction matched in received message", - self->priv->path_display); - else - /* Report the reply message */ - transaction_complete_and_free (tr, message, NULL); - - return; - } - - g_debug ("[%s] Message received but it is neither an indication nor a response. Skipping it.", - self->priv->path_display); -} - -static void -parse_response (QmiDevice *self) -{ - do { - QmiMessage *message; - - /* Every message received must start with the QMUX marker. - * If it doesn't, we broke framing :-/ - * If we broke framing, an error should be reported and the device - * should get closed */ - if (self->priv->response->len > 0 && - self->priv->response->data[0] != QMI_MESSAGE_QMUX_MARKER) { - /* TODO: Report fatal error */ - g_warning ("QMI framing error detected"); - return; - } - - message = qmi_message_new_from_raw (self->priv->response->data, - self->priv->response->len); - if (!message) - /* More data we need */ - return; - - /* Remove the read data from the response buffer */ - g_byte_array_remove_range (self->priv->response, - 0, - qmi_message_get_length (message)); - - /* Play with the received message */ - process_message (self, message); - - qmi_message_unref (message); - } while (self->priv->response->len > 0); -} - -static gboolean -data_available (GIOChannel *source, - GIOCondition condition, - QmiDevice *self) -{ - gsize bytes_read; - GIOStatus status; - gchar buffer[BUFFER_SIZE + 1]; - - if (condition & G_IO_HUP) { - g_debug ("[%s] unexpected port hangup!", - self->priv->path_display); - - if (self->priv->response && - self->priv->response->len) - g_byte_array_remove_range (self->priv->response, 0, self->priv->response->len); - - qmi_device_close (self, NULL); - return FALSE; - } - - if (condition & G_IO_ERR) { - if (self->priv->response && - self->priv->response->len) - g_byte_array_remove_range (self->priv->response, 0, self->priv->response->len); - return TRUE; - } - - /* If not ready yet, prepare the response with default initial size. */ - if (G_UNLIKELY (!self->priv->response)) - self->priv->response = g_byte_array_sized_new (500); - - do { - GError *error = NULL; - - status = g_io_channel_read_chars (source, - buffer, - BUFFER_SIZE, - &bytes_read, - &error); - if (status == G_IO_STATUS_ERROR) { - if (error) { - g_warning ("error reading from the IOChannel: '%s'", error->message); - g_error_free (error); - } - - /* Port is closed; we're done */ - if (self->priv->watch_id == 0) - break; - } - - /* If no bytes read, just let g_io_channel wait for more data */ - if (bytes_read == 0) - break; - - if (bytes_read > 0) - g_byte_array_append (self->priv->response, (const guint8 *)buffer, bytes_read); - - /* Try to parse what we already got */ - parse_response (self); - - /* And keep on if we were told to keep on */ - } while (bytes_read == BUFFER_SIZE || status == G_IO_STATUS_AGAIN); - - return TRUE; -} - -static gboolean -create_iochannel (QmiDevice *self, - GError **error) -{ - GError *inner_error = NULL; - guint fd; - - if (self->priv->iochannel) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_WRONG_STATE, - "Already open"); - return FALSE; - } - - g_assert (self->priv->file); - g_assert (self->priv->path); - - errno = 0; - fd = open (self->priv->path, O_RDWR | O_EXCL | O_NONBLOCK | O_NOCTTY); - if (fd < 0) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_FAILED, - "Cannot open device file '%s': %s", - self->priv->path_display, - strerror (errno)); - return FALSE; - } - - /* Create new GIOChannel */ - self->priv->iochannel = g_io_channel_unix_new (fd); - - /* We don't want UTF-8 encoding, we're playing with raw binary data */ - g_io_channel_set_encoding (self->priv->iochannel, NULL, NULL); - - /* We don't want to get the channel buffered */ - g_io_channel_set_buffered (self->priv->iochannel, FALSE); - - /* Let the GIOChannel own the FD */ - g_io_channel_set_close_on_unref (self->priv->iochannel, TRUE); - - /* We don't want to get blocked while writing stuff */ - if (!g_io_channel_set_flags (self->priv->iochannel, - G_IO_FLAG_NONBLOCK, - &inner_error)) { - g_prefix_error (&inner_error, "Cannot set non-blocking channel: "); - g_propagate_error (error, inner_error); - g_io_channel_shutdown (self->priv->iochannel, FALSE, NULL); - g_io_channel_unref (self->priv->iochannel); - self->priv->iochannel = NULL; - return FALSE; - } - - self->priv->watch_id = g_io_add_watch (self->priv->iochannel, - G_IO_IN | G_IO_ERR | G_IO_HUP, - (GIOFunc)data_available, - self); - - return !!self->priv->iochannel; -} - -typedef struct { - QmiDevice *self; - GSimpleAsyncResult *result; - GCancellable *cancellable; - QmiDeviceOpenFlags flags; - guint timeout; - guint version_check_retries; -} DeviceOpenContext; - -static void -device_open_context_complete_and_free (DeviceOpenContext *ctx) -{ - g_simple_async_result_complete_in_idle (ctx->result); - g_object_unref (ctx->result); - if (ctx->cancellable) - g_object_unref (ctx->cancellable); - g_object_unref (ctx->self); - g_slice_free (DeviceOpenContext, ctx); -} - -/** - * qmi_device_open_finish: - * @self: a #QmiDevice. - * @res: a #GAsyncResult. - * @error: a #GError. - * - * Finishes an asynchronous open operation started with qmi_device_open_async(). - * - * Returns: #TRUE if successful, #FALSE if @error is set. - */ -gboolean -qmi_device_open_finish (QmiDevice *self, - GAsyncResult *res, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - -static void process_open_flags (DeviceOpenContext *ctx); - -static void -sync_ready (QmiClientCtl *client_ctl, - GAsyncResult *res, - DeviceOpenContext *ctx) -{ - GError *error = NULL; - QmiMessageCtlSyncOutput *output; - - /* Check result of the async operation */ - output = qmi_client_ctl_sync_finish (client_ctl, res, &error); - if(!output) { - g_simple_async_result_take_error (ctx->result, error); - device_open_context_complete_and_free (ctx); - return; - } - - /* Check result of the QMI operation */ - if (!qmi_message_ctl_sync_output_get_result (output, &error)) { - g_simple_async_result_take_error (ctx->result, error); - device_open_context_complete_and_free (ctx); - qmi_message_ctl_sync_output_unref (output); - return; - } - - g_debug ("[%s] Sync operation finished", - ctx->self->priv->path_display); - - /* Keep on with next flags */ - process_open_flags (ctx); - qmi_message_ctl_sync_output_unref (output); -} - -static void -version_info_ready (QmiClientCtl *client_ctl, - GAsyncResult *res, - DeviceOpenContext *ctx) -{ - GArray *service_list; - QmiMessageCtlGetVersionInfoOutput *output; - GError *error = NULL; - guint i; - - /* Check result of the async operation */ - output = qmi_client_ctl_get_version_info_finish (client_ctl, res, &error); - if (!output) { - if (g_error_matches (error, QMI_CORE_ERROR, QMI_CORE_ERROR_TIMEOUT)) { - /* Update retries... */ - ctx->version_check_retries--; - /* If retries left, retry */ - if (ctx->version_check_retries > 0) { - qmi_client_ctl_get_version_info (ctx->self->priv->client_ctl, - NULL, - 1, - ctx->cancellable, - (GAsyncReadyCallback)version_info_ready, - ctx); - return; - } - - /* Otherwise, propagate the error */ - } - - g_simple_async_result_take_error (ctx->result, error); - device_open_context_complete_and_free (ctx); - return; - } - - /* Check result of the QMI operation */ - if (!qmi_message_ctl_get_version_info_output_get_result (output, &error)) { - g_simple_async_result_take_error (ctx->result, error); - device_open_context_complete_and_free (ctx); - qmi_message_ctl_get_version_info_output_unref (output); - return; - } - - /* QMI operation succeeded, we can now get the outputs */ - service_list = NULL; - qmi_message_ctl_get_version_info_output_get_service_list (output, - &service_list, - NULL); - ctx->self->priv->supported_services = g_array_ref (service_list); - - g_debug ("[%s] QMI Device supports %u services:", - ctx->self->priv->path_display, - ctx->self->priv->supported_services->len); - for (i = 0; i < ctx->self->priv->supported_services->len; i++) { - QmiMessageCtlGetVersionInfoOutputServiceListService *info; - - info = &g_array_index (ctx->self->priv->supported_services, - QmiMessageCtlGetVersionInfoOutputServiceListService, - i); - g_debug ("[%s] %s (%u.%u)", - ctx->self->priv->path_display, - qmi_service_get_string (info->service), - info->major_version, - info->minor_version); - } - - /* Keep on with next flags */ - process_open_flags (ctx); - qmi_message_ctl_get_version_info_output_unref (output); -} - -static void -process_open_flags (DeviceOpenContext *ctx) -{ - /* Query version info? */ - if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_VERSION_INFO) { - ctx->flags &= ~QMI_DEVICE_OPEN_FLAGS_VERSION_INFO; - /* Setup how many times to retry... We'll retry once per second */ - ctx->version_check_retries = ctx->timeout > 0 ? ctx->timeout : 1; - g_debug ("Checking version info (%u retries)...", ctx->version_check_retries); - qmi_client_ctl_get_version_info (ctx->self->priv->client_ctl, - NULL, - 1, - ctx->cancellable, - (GAsyncReadyCallback)version_info_ready, - ctx); - return; - } - - /* Sync? */ - if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_SYNC) { - g_debug ("Running sync..."); - ctx->flags &= ~QMI_DEVICE_OPEN_FLAGS_SYNC; - qmi_client_ctl_sync (ctx->self->priv->client_ctl, - NULL, - ctx->timeout, - ctx->cancellable, - (GAsyncReadyCallback)sync_ready, - ctx); - return; - } - - /* No more flags to process, done we are */ - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - device_open_context_complete_and_free (ctx); -} - -/** - * qmi_device_open: - * @self: a #QmiDevice. - * @flags: mask of #QmiDeviceOpenFlags specifying how the device should be opened. - * @timeout: maximum time, in seconds, to wait for the device to be opened. - * @cancellable: optional #GCancellable object, #NULL to ignore. - * @callback: a #GAsyncReadyCallback to call when the operation is finished. - * @user_data: the data to pass to callback function. - * - * Asynchronously opens a #QmiDevice for I/O. - * - * When the operation is finished @callback will be called. You can then call - * qmi_device_open_finish() to get the result of the operation. - */ -void -qmi_device_open (QmiDevice *self, - QmiDeviceOpenFlags flags, - guint timeout, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - DeviceOpenContext *ctx; - GError *error = NULL; - - g_return_if_fail (QMI_IS_DEVICE (self)); - - ctx = g_slice_new (DeviceOpenContext); - ctx->self = g_object_ref (self); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - qmi_device_open); - ctx->flags = flags; - ctx->timeout = timeout; - ctx->cancellable = (cancellable ? g_object_ref (cancellable) : NULL); - - if (!create_iochannel (self, &error)) { - g_prefix_error (&error, - "Cannot open QMI device: "); - g_simple_async_result_take_error (ctx->result, error); - device_open_context_complete_and_free (ctx); - return; - } - - /* Process all open flags */ - process_open_flags (ctx); -} - -/*****************************************************************************/ -/* Close channel */ - -static gboolean -destroy_iochannel (QmiDevice *self, - GError **error) -{ - GError *inner_error = NULL; - - /* Already closed? */ - if (!self->priv->iochannel) - return TRUE; - - g_io_channel_shutdown (self->priv->iochannel, TRUE, &inner_error); - - /* Failures when closing still make the device to get closed */ - g_io_channel_unref (self->priv->iochannel); - self->priv->iochannel = NULL; - - if (self->priv->watch_id) { - g_source_remove (self->priv->watch_id); - self->priv->watch_id = 0; - } - - if (self->priv->response) { - g_byte_array_unref (self->priv->response); - self->priv->response = NULL; - } - - if (inner_error) { - g_propagate_error (error, inner_error); - return FALSE; - } - - return TRUE; -} - -/** - * qmi_device_close: - * @self: a #QmiDevice - * @error: a #GError - * - * Synchronously closes a #QmiDevice, preventing any further I/O. - * - * Closing a #QmiDevice multiple times will not return an error. - * - * Returns: #TRUE if successful, #FALSE if @error is set. - */ -gboolean -qmi_device_close (QmiDevice *self, - GError **error) -{ - g_return_val_if_fail (QMI_IS_DEVICE (self), FALSE); - - if (!destroy_iochannel (self, error)) { - g_prefix_error (error, - "Cannot close QMI device: "); - return FALSE; - } - - return TRUE; -} - -/*****************************************************************************/ -/* Command */ - -QmiMessage * -qmi_device_command_finish (QmiDevice *self, - GAsyncResult *res, - GError **error) -{ - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) - return NULL; - - return qmi_message_ref (g_simple_async_result_get_op_res_gpointer ( - G_SIMPLE_ASYNC_RESULT (res))); -} - -void -qmi_device_command (QmiDevice *self, - QmiMessage *message, - guint timeout, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GError *error = NULL; - Transaction *tr; - gconstpointer raw_message; - gsize raw_message_len; - gsize written; - GIOStatus write_status; - - g_return_if_fail (QMI_IS_DEVICE (self)); - g_return_if_fail (message != NULL); - - tr = transaction_new (self, message, callback, user_data); - - /* Device must be open */ - if (!self->priv->iochannel) { - error = g_error_new (QMI_CORE_ERROR, - QMI_CORE_ERROR_WRONG_STATE, - "Device must be open to send commands"); - transaction_complete_and_free (tr, NULL, error); - g_error_free (error); - return; - } - - /* Non-CTL services should use a proper CID */ - if (qmi_message_get_service (message) != QMI_SERVICE_CTL && - qmi_message_get_client_id (message) == 0) { - error = g_error_new (QMI_CORE_ERROR, - QMI_CORE_ERROR_FAILED, - "Cannot send message in service '%s' without a CID", - qmi_service_get_string (qmi_message_get_service (message))); - transaction_complete_and_free (tr, NULL, error); - g_error_free (error); - return; - } - -#ifdef MESSAGE_ENABLE_TRACE - { - gchar *printable; - - printable = qmi_message_get_printable (message, "<<<<<< "); - g_debug ("[%s] Sending message...\n%s", - self->priv->path_display, - printable); - g_free (printable); - } -#endif /* MESSAGE_ENABLE_TRACE */ - - /* Get raw message */ - raw_message = qmi_message_get_raw (message, &raw_message_len, &error); - if (!raw_message) { - g_prefix_error (&error, "Cannot get raw message: "); - transaction_complete_and_free (tr, NULL, error); - g_error_free (error); - return; - } - - /* Setup context to match response */ - device_store_transaction (self, tr, timeout); - - written = 0; - write_status = G_IO_STATUS_AGAIN; - while (write_status == G_IO_STATUS_AGAIN) { - write_status = g_io_channel_write_chars (self->priv->iochannel, - raw_message, - (gssize)raw_message_len, - &written, - &error); - switch (write_status) { - case G_IO_STATUS_ERROR: - g_prefix_error (&error, "Cannot write message: "); - - /* Match transaction so that we remove it from our tracking table */ - tr = device_match_transaction (self, message); - transaction_complete_and_free (tr, NULL, error); - g_error_free (error); - return; - - case G_IO_STATUS_EOF: - /* We shouldn't get EOF when writing */ - g_assert_not_reached (); - break; - - case G_IO_STATUS_NORMAL: - /* All good, we'll exit the loop now */ - break; - - case G_IO_STATUS_AGAIN: - /* We're in a non-blocking channel and therefore we're up to receive - * EAGAIN; just retry in this case. TODO: in an idle? */ - break; - } - } - - /* Just return, we'll get response asynchronously */ -} - -/*****************************************************************************/ -/* New QMI device */ - -/** - * qmi_device_new_finish: - * @res: a #GAsyncResult. - * @error: a #GError. - * - * Finishes an operation started with qmi_device_new(). - * - * Returns: A newly created #QmiDevice, or #NULL if @error is set. - */ -QmiDevice * -qmi_device_new_finish (GAsyncResult *res, - GError **error) -{ - GObject *ret; - GObject *source_object; - - source_object = g_async_result_get_source_object (res); - ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error); - g_object_unref (source_object); - - return (ret ? QMI_DEVICE (ret) : NULL); -} - -/** - * qmi_device_new: - * @file: a #GFile. - * @cancellable: optional #GCancellable object, #NULL to ignore. - * @callback: a #GAsyncReadyCallback to call when the initialization is finished. - * @user_data: the data to pass to callback function. - * - * Asynchronously creates a #QmiDevice object to manage @file. - * When the operation is finished, @callback will be invoked. You can then call - * qmi_device_new_finish() to get the result of the operation. - */ -void -qmi_device_new (GFile *file, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - g_async_initable_new_async (QMI_TYPE_DEVICE, - G_PRIORITY_DEFAULT, - cancellable, - callback, - user_data, - QMI_DEVICE_FILE, file, - NULL); -} - -/*****************************************************************************/ -/* Async init */ - -typedef struct { - QmiDevice *self; - GSimpleAsyncResult *result; - GCancellable *cancellable; -} InitContext; - -static void -init_context_complete_and_free (InitContext *ctx) -{ - g_simple_async_result_complete_in_idle (ctx->result); - if (ctx->cancellable) - g_object_unref (ctx->cancellable); - g_object_unref (ctx->result); - g_object_unref (ctx->self); - g_slice_free (InitContext, ctx); -} - -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 -query_info_async_ready (GFile *file, - GAsyncResult *res, - InitContext *ctx) -{ - GError *error = NULL; - GFileInfo *info; - - info = g_file_query_info_finish (file, res, &error); - if (!info) { - g_prefix_error (&error, - "Couldn't query file info: "); - g_simple_async_result_take_error (ctx->result, error); - init_context_complete_and_free (ctx); - return; - } - - /* Our QMI device must be of SPECIAL type */ - if (g_file_info_get_file_type (info) != G_FILE_TYPE_SPECIAL) { - g_simple_async_result_set_error (ctx->result, - QMI_CORE_ERROR, - QMI_CORE_ERROR_FAILED, - "Wrong file type"); - init_context_complete_and_free (ctx); - return; - } - g_object_unref (info); - - /* Create the implicit CTL client */ - ctx->self->priv->client_ctl = g_object_new (QMI_TYPE_CLIENT_CTL, - QMI_CLIENT_DEVICE, ctx->self, - QMI_CLIENT_SERVICE, QMI_SERVICE_CTL, - QMI_CLIENT_CID, QMI_CID_NONE, - NULL); - - /* Register the CTL client to get indications */ - register_client (ctx->self, - QMI_CLIENT (ctx->self->priv->client_ctl), - &error); - g_assert_no_error (error); - - /* Done we are */ - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - init_context_complete_and_free (ctx); -} - -static void -initable_init_async (GAsyncInitable *initable, - int io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - InitContext *ctx; - - ctx = g_slice_new0 (InitContext); - ctx->self = g_object_ref (initable); - if (cancellable) - ctx->cancellable = g_object_ref (cancellable); - ctx->result = g_simple_async_result_new (G_OBJECT (initable), - callback, - user_data, - initable_init_async); - - /* We need a proper file to initialize */ - if (!ctx->self->priv->file) { - g_simple_async_result_set_error (ctx->result, - QMI_CORE_ERROR, - QMI_CORE_ERROR_INVALID_ARGS, - "Cannot initialize QMI device: No file given"); - init_context_complete_and_free (ctx); - return; - } - - /* Check the file type. Note that this is just a quick check to avoid - * creating QmiDevices pointing to a location already known not to be a QMI - * device. */ - g_file_query_info_async (ctx->self->priv->file, - G_FILE_ATTRIBUTE_STANDARD_TYPE, - G_FILE_QUERY_INFO_NONE, - G_PRIORITY_DEFAULT, - ctx->cancellable, - (GAsyncReadyCallback)query_info_async_ready, - ctx); -} - -/*****************************************************************************/ - -static void -set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - QmiDevice *self = QMI_DEVICE (object); - - switch (prop_id) { - case PROP_FILE: - g_assert (self->priv->file == NULL); - self->priv->file = g_value_dup_object (value); - self->priv->path = g_file_get_path (self->priv->file); - self->priv->path_display = g_filename_display_name (self->priv->path); - break; - case PROP_CLIENT_CTL: - /* 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) -{ - QmiDevice *self = QMI_DEVICE (object); - - switch (prop_id) { - case PROP_FILE: - g_value_set_object (value, self->priv->file); - break; - case PROP_CLIENT_CTL: - g_value_set_object (value, self->priv->client_ctl); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -qmi_device_init (QmiDevice *self) -{ - self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), - QMI_TYPE_DEVICE, - QmiDevicePrivate); - - self->priv->registered_clients = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - g_object_unref); -} - -static gboolean -foreach_warning (gpointer key, - QmiClient *client, - QmiDevice *self) -{ - g_warning ("QMI client for service '%s' with CID '%u' wasn't released", - qmi_service_get_string (qmi_client_get_service (client)), - qmi_client_get_cid (client)); - - return TRUE; -} - -static void -dispose (GObject *object) -{ - QmiDevice *self = QMI_DEVICE (object); - - g_clear_object (&self->priv->file); - - /* unregister our CTL client */ - unregister_client (self, QMI_CLIENT (self->priv->client_ctl)); - - /* If clients were left unreleased, we'll just warn about it. - * There is no point in trying to request CID releases, as the device - * itself is being disposed. */ - g_hash_table_foreach_remove (self->priv->registered_clients, - (GHRFunc)foreach_warning, - self); - - g_clear_object (&self->priv->client_ctl); - - G_OBJECT_CLASS (qmi_device_parent_class)->dispose (object); -} - -static void -finalize (GObject *object) -{ - QmiDevice *self = QMI_DEVICE (object); - - /* Transactions keep refs to the device, so it's actually - * impossible to have any content in the HT */ - if (self->priv->transactions) { - g_assert (g_hash_table_size (self->priv->transactions) == 0); - g_hash_table_unref (self->priv->transactions); - } - - g_hash_table_unref (self->priv->registered_clients); - - if (self->priv->supported_services) - g_array_unref (self->priv->supported_services); - - g_free (self->priv->path); - g_free (self->priv->path_display); - if (self->priv->response) - g_byte_array_unref (self->priv->response); - if (self->priv->iochannel) - g_io_channel_unref (self->priv->iochannel); - - G_OBJECT_CLASS (qmi_device_parent_class)->finalize (object); -} - -static void -async_initable_iface_init (GAsyncInitableIface *iface) -{ - iface->init_async = initable_init_async; - iface->init_finish = initable_init_finish; -} - -static void -qmi_device_class_init (QmiDeviceClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (QmiDevicePrivate)); - - object_class->get_property = get_property; - object_class->set_property = set_property; - object_class->finalize = finalize; - object_class->dispose = dispose; - - properties[PROP_FILE] = - g_param_spec_object (QMI_DEVICE_FILE, - "Device file", - "File to the underlying QMI device", - G_TYPE_FILE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property (object_class, PROP_FILE, properties[PROP_FILE]); - - properties[PROP_CLIENT_CTL] = - g_param_spec_object (QMI_DEVICE_CLIENT_CTL, - "CTL client", - "Implicit CTL client", - QMI_TYPE_CLIENT_CTL, - G_PARAM_READABLE); - g_object_class_install_property (object_class, PROP_CLIENT_CTL, properties[PROP_CLIENT_CTL]); -} diff --git a/src/qmi-device.h b/src/qmi-device.h deleted file mode 100644 index 79272d8..0000000 --- a/src/qmi-device.h +++ /dev/null @@ -1,145 +0,0 @@ -/* -*- 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_DEVICE_H_ -#define _LIBQMI_GLIB_QMI_DEVICE_H_ - -#include <glib-object.h> - -#include "qmi-enums.h" -#include "qmi-message.h" -#include "qmi-client.h" - -G_BEGIN_DECLS - -#define QMI_TYPE_DEVICE (qmi_device_get_type ()) -#define QMI_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), QMI_TYPE_DEVICE, QmiDevice)) -#define QMI_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), QMI_TYPE_DEVICE, QmiDeviceClass)) -#define QMI_IS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), QMI_TYPE_DEVICE)) -#define QMI_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), QMI_TYPE_DEVICE)) -#define QMI_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), QMI_TYPE_DEVICE, QmiDeviceClass)) - -typedef struct _QmiDevice QmiDevice; -typedef struct _QmiDeviceClass QmiDeviceClass; -typedef struct _QmiDevicePrivate QmiDevicePrivate; - -#define QMI_DEVICE_FILE "device-file" -#define QMI_DEVICE_CLIENT_CTL "device-client-ctl" - -struct _QmiDevice { - GObject parent; - QmiDevicePrivate *priv; -}; - -struct _QmiDeviceClass { - GObjectClass parent; -}; - -GType qmi_device_get_type (void); - -void qmi_device_new (GFile *file, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -QmiDevice *qmi_device_new_finish (GAsyncResult *res, - GError **error); - -GFile *qmi_device_get_file (QmiDevice *self); -GFile *qmi_device_peek_file (QmiDevice *self); -const gchar *qmi_device_get_path (QmiDevice *self); -const gchar *qmi_device_get_path_display (QmiDevice *self); -gboolean qmi_device_is_open (QmiDevice *self); - -/** - * QmiDeviceOpenFlags: - * @QMI_DEVICE_OPEN_FLAGS_NONE: No flags. - * @QMI_DEVICE_OPEN_FLAGS_VERSION_INFO: Run version info check when opening. - * @QMI_DEVICE_OPEN_FLAGS_SYNC: Synchronize with endpoint once the device is open. Will release any previously allocated client ID. - * - * Flags to specify which actions to be performed when the device is open. - */ -typedef enum { - QMI_DEVICE_OPEN_FLAGS_NONE = 0, - QMI_DEVICE_OPEN_FLAGS_VERSION_INFO = 1 << 0, - QMI_DEVICE_OPEN_FLAGS_SYNC = 1 << 1 -} QmiDeviceOpenFlags; - -void qmi_device_open (QmiDevice *self, - QmiDeviceOpenFlags flags, - guint timeout, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean qmi_device_open_finish (QmiDevice *self, - GAsyncResult *res, - GError **error); - -gboolean qmi_device_close (QmiDevice *self, - GError **error); - -void qmi_device_allocate_client (QmiDevice *self, - QmiService service, - guint8 cid, - guint timeout, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -QmiClient *qmi_device_allocate_client_finish (QmiDevice *self, - GAsyncResult *res, - GError **error); - -/** - * QmiDeviceReleaseClientFlags: - * @QMI_DEVICE_RELEASE_CLIENT_FLAGS_NONE: No flags. - * @QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID: Release the CID when releasing the client. - * - * Flags to specify which actions to be performed when releasing the client. - */ -typedef enum { - QMI_DEVICE_RELEASE_CLIENT_FLAGS_NONE = 0, - QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID = 1 << 0 -} QmiDeviceReleaseClientFlags; - -void qmi_device_release_client (QmiDevice *self, - QmiClient *client, - QmiDeviceReleaseClientFlags flags, - guint timeout, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean qmi_device_release_client_finish (QmiDevice *self, - GAsyncResult *res, - GError **error); - -void qmi_device_command (QmiDevice *self, - QmiMessage *message, - guint timeout, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -QmiMessage *qmi_device_command_finish (QmiDevice *self, - GAsyncResult *res, - GError **error); - -G_END_DECLS - -#endif /* _LIBQMI_GLIB_QMI_DEVICE_H_ */ diff --git a/src/qmi-enums-dms.h b/src/qmi-enums-dms.h deleted file mode 100644 index 5103599..0000000 --- a/src/qmi-enums-dms.h +++ /dev/null @@ -1,195 +0,0 @@ -/* -*- 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 Lanedo GmbH <aleksander@lanedo.com> - */ - -#ifndef _LIBQMI_GLIB_QMI_ENUMS_DMS_H_ -#define _LIBQMI_GLIB_QMI_ENUMS_DMS_H_ - -/*****************************************************************************/ -/* Helper enums for the 'QMI DMS Get Capabilities' message */ - -/** - * QmiDmsDataServiceCapability: - * @QMI_DMS_DATA_SERVICE_CAPABILITY_NONE: No data services supported. - * @QMI_DMS_DATA_SERVICE_CAPABILITY_CS: Only CS supported. - * @QMI_DMS_DATA_SERVICE_CAPABILITY_PS: Only PS supported. - * @QMI_DMS_DATA_SERVICE_CAPABILITY_SIMULTANEOUS_CS_PS: Simultaneous CS and PS supported. - * @QMI_DMS_DATA_SERVICE_CAPABILITY_NON_SIMULTANEOUS_CS_PS: Non simultaneous CS and PS supported. - * - * Data service capability. - */ -typedef enum { - QMI_DMS_DATA_SERVICE_CAPABILITY_NONE = 0, - QMI_DMS_DATA_SERVICE_CAPABILITY_CS = 1, - QMI_DMS_DATA_SERVICE_CAPABILITY_PS = 2, - QMI_DMS_DATA_SERVICE_CAPABILITY_SIMULTANEOUS_CS_PS = 3, - QMI_DMS_DATA_SERVICE_CAPABILITY_NON_SIMULTANEOUS_CS_PS = 4 -} QmiDmsDataServiceCapability; - -/** - * QmiDmsSimCapability: - * @QMI_DMS_SIM_CAPABILITY_NOT_SUPPORTED: SIM not supported. - * @QMI_DMS_SIM_CAPABILITY_SUPPORTED: SIM is supported. - * - * SIM capability. - */ -typedef enum { - QMI_DMS_SIM_CAPABILITY_NOT_SUPPORTED = 1, - QMI_DMS_SIM_CAPABILITY_SUPPORTED = 2 -} QmiDmsSimCapability; - -/** - * QmiDmsRadioInterface: - * @QMI_DMS_RADIO_INTERFACE_CDMA20001X: CDMA2000 1x. - * @QMI_DMS_RADIO_INTERFACE_EVDO: CDMA2000 HRPD (1xEV-DO) - * @QMI_DMS_RADIO_INTERFACE_GSM: GSM. - * @QMI_DMS_RADIO_INTERFACE_UMTS: UMTS. - * @QMI_DMS_RADIO_INTERFACE_LTE: LTE. - * - * Radio interface type. - */ -typedef enum { - QMI_DMS_RADIO_INTERFACE_CDMA20001X = 1, - QMI_DMS_RADIO_INTERFACE_EVDO = 2, - QMI_DMS_RADIO_INTERFACE_GSM = 4, - QMI_DMS_RADIO_INTERFACE_UMTS = 5, - QMI_DMS_RADIO_INTERFACE_LTE = 8 -} QmiDmsRadioInterface; - - -/*****************************************************************************/ -/* Helper enums for the 'QMI DMS Get Power State' message */ - -/** - * QmiDmsPowerState: - * @QMI_DMS_POWER_STATE_EXTERNAL_SOURCE: Powered by an external source. - * @QMI_DMS_POWER_STATE_BATTERY_CONNECTED: Battery is connected. - * @QMI_DMS_POWER_STATE_BATTERY_CHARGING: Battery is currently being charged. - * @QMI_DMS_POWER_STATE_FAULT: Recognized power fault. - * - * Flags specifying the current power state. - * - * If @QMI_DMS_POWER_STATE_EXTERNAL_SOURCE is set, the device is powerered by an - * external source; otherwise it is powered by a battery. - * - * If @QMI_DMS_POWER_STATE_BATTERY_CONNECTED is set, the battery is connected; - * otherwise the battery is not connected. - * - * If @QMI_DMS_POWER_STATE_BATTERY_CHARGING is set, the battery is being charged; - * otherwise the battery is not being charged. - * - * If @QMI_DMS_POWER_STATE_FAULT is set, a power fault has been detected. - */ -typedef enum { - QMI_DMS_POWER_STATE_EXTERNAL_SOURCE = 1 << 0, - QMI_DMS_POWER_STATE_BATTERY_CONNECTED = 1 << 1, - QMI_DMS_POWER_STATE_BATTERY_CHARGING = 1 << 2, - QMI_DMS_POWER_STATE_FAULT = 1 << 3, -} QmiDmsPowerState; - - -/*****************************************************************************/ -/* Helper enums for the 'QMI DMS UIM Set PIN Protection' message */ - -/** - * QmiDmsUimPinId: - * @QMI_DMS_UIM_PIN_ID_PIN: PIN. - * @QMI_DMS_UIM_PIN_ID_PIN2: PIN2. - * - * The PIN identifier. - */ -typedef enum { - QMI_DMS_UIM_PIN_ID_PIN = 1, - QMI_DMS_UIM_PIN_ID_PIN2 = 2 -} QmiDmsUimPinId; - - -/*****************************************************************************/ -/* Helper enums for the 'QMI DMS UIM Get PIN Status' message */ - -/** - * QmiDmsPinStatus: - * @QMI_DMS_UIM_PIN_STATUS_NOT_INITIALIZED: Not initialized. - * @QMI_DMS_UIM_PIN_STATUS_ENABLED_NOT_VERIFIED: Enabled, not verified. - * @QMI_DMS_UIM_PIN_STATUS_ENABLED_VERIFIED: Enabled, verified. - * @QMI_DMS_UIM_PIN_STATUS_DISABLED: Disabled. - * @QMI_DMS_UIM_PIN_STATUS_BLOCKED: Blocked. - * @QMI_DMS_UIM_PIN_STATUS_PERMANENTLY_BLOCKED: Permanently Blocked. - * @QMI_DMS_UIM_PIN_STATUS_UNBLOCKED: Unblocked. - * @QMI_DMS_UIM_PIN_STATUS_CHANGED: Changed. - * - * The PIN status. - */ -typedef enum { - QMI_DMS_UIM_PIN_STATUS_NOT_INITIALIZED = 0, - QMI_DMS_UIM_PIN_STATUS_ENABLED_NOT_VERIFIED = 1, - QMI_DMS_UIM_PIN_STATUS_ENABLED_VERIFIED = 2, - QMI_DMS_UIM_PIN_STATUS_DISABLED = 3, - QMI_DMS_UIM_PIN_STATUS_BLOCKED = 4, - QMI_DMS_UIM_PIN_STATUS_PERMANENTLY_BLOCKED = 5, - QMI_DMS_UIM_PIN_STATUS_UNBLOCKED = 6, - QMI_DMS_UIM_PIN_STATUS_CHANGED = 7, -} QmiDmsUimPinStatus; - -/*****************************************************************************/ -/* Helper enums for the 'QMI DMS Get Operating Mode' message */ - -/** - * QmiDmsOperatingMode: - * @QMI_DMS_OPERATING_MODE_ONLINE: Device can acquire a system and make calls. - * @QMI_DMS_OPERATING_MODE_LOW_POWER: Device has temporarily disabled RF. - * @QMI_DMS_OPERATING_MODE_PERSISTENT_LOW_POWER: Device has disabled RF and state persists even after a reset. - * @QMI_DMS_OPERATING_MODE_FACTORY_TEST: Special mode for manufacturer tests. - * @QMI_DMS_OPERATING_MODE_OFFLINE: Device has deactivated RF and is partially shutdown. - * @QMI_DMS_OPERATING_MODE_RESETTING: Device is in the process of power cycling. - * @QMI_DMS_OPERATING_MODE_SHUTTING_DOWN: Device is in the process of shutting down. - * @QMI_DMS_OPERATING_MODE_MODE_ONLY_LOW_POWER: Mode-only Low Power. - * - * Operating mode of the device. - */ -typedef enum { - QMI_DMS_OPERATING_MODE_ONLINE = 0, - QMI_DMS_OPERATING_MODE_LOW_POWER = 1, - QMI_DMS_OPERATING_MODE_FACTORY_TEST = 2, - QMI_DMS_OPERATING_MODE_OFFLINE = 3, - QMI_DMS_OPERATING_MODE_RESETTING = 4, - QMI_DMS_OPERATING_MODE_SHUTTING_DOWN = 5, - QMI_DMS_OPERATING_MODE_PERSISTENT_LOW_POWER = 6, - QMI_DMS_OPERATING_MODE_MODE_ONLY_LOW_POWER = 7 -} QmiDmsOperatingMode; - -/** - * QmiDmsOfflineReason: - * @QMI_DMS_OFFLINE_REASON_HOST_IMAGE_MISCONFIGURATION: Host image misconfiguration. - * @QMI_DMS_OFFLINE_REASON_PRI_IMAGE_MISCONFIGURATION: PRI image misconfiguration. - * @QMI_DMS_OFFLINE_REASON_PRI_VERSION_INCOMPATIBLE: PRI version incompatible. - * @QMI_DMS_OFFLINE_REASON_DEVICE_MEMORY_FULL: Memory full, cannot copy PRI information. - * - * Reasons for being in Offline (@QMI_DMS_OPERATING_MODE_OFFLINE) state. - */ -typedef enum { - QMI_DMS_OFFLINE_REASON_HOST_IMAGE_MISCONFIGURATION = 1 << 0, - QMI_DMS_OFFLINE_REASON_PRI_IMAGE_MISCONFIGURATION = 1 << 1, - QMI_DMS_OFFLINE_REASON_PRI_VERSION_INCOMPATIBLE = 1 << 2, - QMI_DMS_OFFLINE_REASON_DEVICE_MEMORY_FULL = 1 << 3 -} QmiDmsOfflineReason; - -#endif /* _LIBQMI_GLIB_QMI_ENUMS_DMS_H_ */ diff --git a/src/qmi-enums-wds.h b/src/qmi-enums-wds.h deleted file mode 100644 index 79ab360..0000000 --- a/src/qmi-enums-wds.h +++ /dev/null @@ -1,197 +0,0 @@ -/* -*- 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 Lanedo GmbH <aleksander@lanedo.com> - */ - -#ifndef _LIBQMI_GLIB_QMI_ENUMS_WDS_H_ -#define _LIBQMI_GLIB_QMI_ENUMS_WDS_H_ - -/*****************************************************************************/ -/* Helper enums for the 'QMI WDS Get Packet Service Status' message */ - -/** - * QmiWdsConnectionStatus: - * @QMI_WDS_CONNECTION_STATUS_UNKNOWN: Unknown status. - * @QMI_WDS_CONNECTION_STATUS_DISCONNECTED: Network is disconnected - * @QMI_WDS_CONNECTION_STATUS_CONNECTED: Network is connected. - * @QMI_WDS_CONNECTION_STATUS_SUSPENDED: Network connection is suspended. - * @QMI_WDS_CONNECTION_STATUS_AUTHENTICATING: Network authentication is ongoing. - * - * Status of the network connection. - */ -typedef enum { - QMI_WDS_CONNECTION_STATUS_UNKNOWN = 0, - QMI_WDS_CONNECTION_STATUS_DISCONNECTED = 1, - QMI_WDS_CONNECTION_STATUS_CONNECTED = 2, - QMI_WDS_CONNECTION_STATUS_SUSPENDED = 3, - QMI_WDS_CONNECTION_STATUS_AUTHENTICATING = 4 -} QmiWdsConnectionStatus; - - -/*****************************************************************************/ -/* Helper enums for the 'QMI WDS Get Data Bearer Technology' message */ - -/** - * QmiWdsDataBearerTechnology: - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_UNKNOWN: Unknown. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_CDMA20001X: CDMA2000 1x. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_1xEVDO: CDMA2000 HRPD 1xEV-DO. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_GSM: GSM. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_UMTS: UMTS. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_1xEVDO_REVA: CDMA2000 HRPD 1xEV-DO RevA. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_EDGE: EDGE. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_HSDPA: HSDPA and WCDMA. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_HSUPA: WCDMA and HSUPA. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_HSDPA_HSUPDA: HSDPA and HSUPA. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_LTE: LTE. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_EHRPD: CDMA2000 eHRPD. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_HSDPAPLUS: HSDPA+ and WCDMA. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_HSDPAPLUS_HSUPA: HSDPA+ and HSUPA. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_DCHSDPAPLUS: DC-HSDPA+ and WCDMA. - * @QMI_WDS_DATA_BEARER_TECHNOLOGY_DCHSDPAPLUS_HSUPA: DC-HSDPA+ and HSUPA. - * - * Data bearer technology. - */ -typedef enum { - QMI_WDS_DATA_BEARER_TECHNOLOGY_UNKNOWN = -1, - QMI_WDS_DATA_BEARER_TECHNOLOGY_CDMA20001X = 0x01, - QMI_WDS_DATA_BEARER_TECHNOLOGY_1xEVDO = 0x02, - QMI_WDS_DATA_BEARER_TECHNOLOGY_GSM = 0x03, - QMI_WDS_DATA_BEARER_TECHNOLOGY_UMTS = 0x04, - QMI_WDS_DATA_BEARER_TECHNOLOGY_1xEVDO_REVA = 0x05, - QMI_WDS_DATA_BEARER_TECHNOLOGY_EDGE = 0x06, - QMI_WDS_DATA_BEARER_TECHNOLOGY_HSDPA = 0x07, - QMI_WDS_DATA_BEARER_TECHNOLOGY_HSUPA = 0x08, - QMI_WDS_DATA_BEARER_TECHNOLOGY_HSDPA_HSUPDA = 0x09, - QMI_WDS_DATA_BEARER_TECHNOLOGY_LTE = 0x0A, - QMI_WDS_DATA_BEARER_TECHNOLOGY_EHRPD = 0x0B, - QMI_WDS_DATA_BEARER_TECHNOLOGY_HSDPAPLUS = 0x0C, - QMI_WDS_DATA_BEARER_TECHNOLOGY_HSDPAPLUS_HSUPA = 0x0D, - QMI_WDS_DATA_BEARER_TECHNOLOGY_DCHSDPAPLUS = 0x0E, - QMI_WDS_DATA_BEARER_TECHNOLOGY_DCHSDPAPLUS_HSUPA = 0x0F -} QmiWdsDataBearerTechnology; - - -/*****************************************************************************/ -/* Helper enums for the 'QMI WDS Get Current Data Bearer Technology' message */ - -/** - * QmiWdsNetworkType: - * @QMI_WDS_NETWORK_TYPE_UNKNOWN: Unknown. - * @QMI_WDS_NETWORK_TYPE_3GPP2: 3GPP2 network type. - * @QMI_WDS_NETWORK_TYPE_3GPP: 3GPP network type. - * - * Network type of the data bearer. - */ -typedef enum { - QMI_WDS_NETWORK_TYPE_UNKNOWN = 0, - QMI_WDS_NETWORK_TYPE_3GPP2 = 1, - QMI_WDS_NETWORK_TYPE_3GPP = 2 -} QmiWdsNetworkType; - -/** - * QmiWdsRat3gpp2: - * @QMI_WDS_RAT_3GPP2_UNKNOWN: Unknown, to be ignored. - * @QMI_WDS_RAT_3GPP2_CDMA1X: CDMA 1x. - * @QMI_WDS_RAT_3GPP2_EVDO_REV0: EVDO Rev0. - * @QMI_WDS_RAT_3GPP2_EVDO_REVA: EVDO RevA. - * @QMI_WDS_RAT_3GPP2_EVDO_REVB: EVDO RevB. - * @QMI_WDS_RAT_3GPP2_NULL_BEARER: No bearer. - * - * Flags specifying the 3GPP2-specific Radio Access Technology, when the data - * bearer network type is @QMI_WDS_NETWORK_TYPE_3GPP2. - */ -typedef enum { /*< underscore_name=qmi_wds_rat_3gpp2 >*/ - QMI_WDS_RAT_3GPP2_NONE = 0, - QMI_WDS_RAT_3GPP2_CDMA1X = 1 << 0, - QMI_WDS_RAT_3GPP2_EVDO_REV0 = 1 << 1, - QMI_WDS_RAT_3GPP2_EVDO_REVA = 1 << 2, - QMI_WDS_RAT_3GPP2_EVDO_REVB = 1 << 3, - QMI_WDS_RAT_3GPP2_NULL_BEARER = 1 << 15 -} QmiWdsRat3gpp2; - -/** - * QmiWdsRat3gpp: - * @QMI_WDS_RAT_3GPP_NONE: Unknown, to be ignored. - * @QMI_WDS_RAT_3GPP_WCDMA: WCDMA. - * @QMI_WDS_RAT_3GPP_GPRS: GPRS. - * @QMI_WDS_RAT_3GPP_HSDPA: HSDPA. - * @QMI_WDS_RAT_3GPP_HSUPA: HSUPA. - * @QMI_WDS_RAT_3GPP_EDGE: EDGE. - * @QMI_WDS_RAT_3GPP_LTE: LTE. - * @QMI_WDS_RAT_3GPP_HSDPAPLUS: HSDPA+. - * @QMI_WDS_RAT_3GPP_DCHSDPAPLUS: DC-HSDPA+ - * @QMI_WDS_RAT_3GPP_NULL_BEARER: No bearer. - * - * Flags specifying the 3GPP-specific Radio Access Technology, when the data - * bearer network type is @QMI_WDS_NETWORK_TYPE_3GPP. - */ -typedef enum { /*< underscore_name=qmi_wds_rat_3gpp >*/ - QMI_WDS_RAT_3GPP_NONE = 0, - QMI_WDS_RAT_3GPP_WCDMA = 1 << 0, - QMI_WDS_RAT_3GPP_GPRS = 1 << 1, - QMI_WDS_RAT_3GPP_HSDPA = 1 << 2, - QMI_WDS_RAT_3GPP_HSUPA = 1 << 3, - QMI_WDS_RAT_3GPP_EDGE = 1 << 4, - QMI_WDS_RAT_3GPP_LTE = 1 << 5, - QMI_WDS_RAT_3GPP_HSDPAPLUS = 1 << 6, - QMI_WDS_RAT_3GPP_DCHSDPAPLUS = 1 << 7, - QMI_WDS_RAT_3GPP_NULL_BEARER = 1 << 15 -} QmiWdsRat3gpp; - -/** - * QmiWdsSoCdma1x: - * @QMI_WDS_SO_CDMA1X_NONE: Unknown, to be ignored. - * @QMI_WDS_SO_CDMA1X_IS95: IS95. - * @QMI_WDS_SO_CDMA1X_IS2000: IS2000. - * @QMI_WDS_SO_CDMA1X_IS2000_REL_A: IS2000 RelA. - * - * Flags specifying the Service Option when the bearer network type is - * @QMI_WDS_NETWORK_TYPE_3GPP2 and when the Radio Access Technology mask - * contains @QMI_WDS_RAT_3GPP2_CDMA1X. - */ -typedef enum { - QMI_WDS_SO_CDMA1X_NONE = 0, - QMI_WDS_SO_CDMA1X_IS95 = 1 << 0, - QMI_WDS_SO_CDMA1X_IS2000 = 1 << 1, - QMI_WDS_SO_CDMA1X_IS2000_REL_A = 1 << 2 -} QmiWdsSoCdma1x; - -/** - * QmiWdsSoEvdoRevA: - * @QMI_WDS_SO_EVDO_REVA_NONE: Unknown, to be ignored. - * @QMI_WDS_SO_EVDO_REVA_DPA: DPA. - * @QMI_WDS_SO_EVDO_REVA_MFPA: MFPA. - * @QMI_WDS_SO_EVDO_REVA_EMPA: EMPA. - * @QMI_WDS_SO_EVDO_REVA_EMPA_EHRPD: EMPA EHRPD. - * - * Flags specifying the Service Option when the bearer network type is - * @QMI_WDS_NETWORK_TYPE_3GPP2 and when the Radio Access Technology mask - * contains @QMI_WDS_RAT_3GPP2_EVDO_REVA. - */ -typedef enum { /*< underscore_name=qmi_wds_so_evdo_reva >*/ - QMI_WDS_SO_EVDO_REVA_NONE = 0, - QMI_WDS_SO_EVDO_REVA_DPA = 1 << 0, - QMI_WDS_SO_EVDO_REVA_MFPA = 1 << 1, - QMI_WDS_SO_EVDO_REVA_EMPA = 1 << 2, - QMI_WDS_SO_EVDO_REVA_EMPA_EHRPD = 1 << 3 -} QmiWdsSoEvdoRevA; - -#endif /* _LIBQMI_GLIB_QMI_ENUMS_WDS_H_ */ diff --git a/src/qmi-enums.h b/src/qmi-enums.h deleted file mode 100644 index 5710eba..0000000 --- a/src/qmi-enums.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- 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 "qmi-enums-wds.h" - -#ifndef _LIBQMI_GLIB_QMI_ENUMS_H_ -#define _LIBQMI_GLIB_QMI_ENUMS_H_ - -typedef enum { - /* Unknown service */ - QMI_SERVICE_UNKNOWN = -1, - /* Control service */ - QMI_SERVICE_CTL = 0x00, - /* Wireless Data Service */ - QMI_SERVICE_WDS = 0x01, - /* Device Management Service */ - QMI_SERVICE_DMS = 0x02, - /* Network Access Service */ - QMI_SERVICE_NAS = 0x03, - /* Quality Of Service service */ - QMI_SERVICE_QOS = 0x04, - /* Wireless Messaging Service */ - QMI_SERVICE_WMS = 0x05, - /* Position Determination Service */ - QMI_SERVICE_PDS = 0x06, - /* Authentication service */ - QMI_SERVICE_AUTH = 0x07, - /* AT service */ - QMI_SERVICE_AT = 0x08, - /* Voice service */ - QMI_SERVICE_VOICE = 0x09, - - QMI_SERVICE_CAT2 = 0x0A, - QMI_SERVICE_UIM = 0x0B, - QMI_SERVICE_PBM = 0x0C, - QMI_SERVICE_LOC = 0x10, - QMI_SERVICE_SAR = 0x11, - QMI_SERVICE_RMTFS = 0x14, - - /* Card Application Toolkit service */ - QMI_SERVICE_CAT = 0xE0, - /* Remote Management Service */ - QMI_SERVICE_RMS = 0xE1, - /* Open Mobile Alliance device management service */ - QMI_SERVICE_OMA = 0xE2 -} QmiService; - -/*****************************************************************************/ -/* QMI Control */ - -typedef enum { - QMI_CTL_FLAG_NONE = 0, - QMI_CTL_FLAG_RESPONSE = 1 << 0, - QMI_CTL_FLAG_INDICATION = 1 << 1 -} QmiCtlFlag; - -/*****************************************************************************/ -/* QMI Services */ - -typedef enum { - QMI_SERVICE_FLAG_NONE = 0, - QMI_SERVICE_FLAG_COMPOUND = 1 << 0, - QMI_SERVICE_FLAG_RESPONSE = 1 << 1, - QMI_SERVICE_FLAG_INDICATION = 1 << 2 -} QmiServiceFlag; - -#endif /* _LIBQMI_GLIB_QMI_ENUMS_H_ */ diff --git a/src/qmi-errors.h b/src/qmi-errors.h deleted file mode 100644 index cff53be..0000000 --- a/src/qmi-errors.h +++ /dev/null @@ -1,212 +0,0 @@ -/* -*- 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_ERRORS_H_ -#define _LIBQMI_GLIB_QMI_ERRORS_H_ - -/** - * QmiCoreError: - * @QMI_CORE_ERROR_FAILED: Operation failed. - * @QMI_CORE_ERROR_WRONG_STATE: Operation cannot be executed in the current state. - * @QMI_CORE_ERROR_TIMEOUT: Operation timed out. - * @QMI_CORE_ERROR_INVALID_ARGS: Invalid arguments given. - * @QMI_CORE_ERROR_INVALID_MESSAGE: QMI message is invalid. - * @QMI_CORE_ERROR_TLV_NOT_FOUND: TLV not found. - * @QMI_CORE_ERROR_TLV_TOO_LONG: TLV is too long. - * @QMI_CORE_ERROR_UNSUPPORTED: Not supported. - * - * Common errors that may be reported by libqmi-glib. - */ -typedef enum { - QMI_CORE_ERROR_FAILED, - QMI_CORE_ERROR_WRONG_STATE, - QMI_CORE_ERROR_TIMEOUT, - QMI_CORE_ERROR_INVALID_ARGS, - QMI_CORE_ERROR_INVALID_MESSAGE, - QMI_CORE_ERROR_TLV_NOT_FOUND, - QMI_CORE_ERROR_TLV_TOO_LONG, - QMI_CORE_ERROR_UNSUPPORTED -} QmiCoreError; - -/** - * QmiProtocolError: - * @QMI_PROTOCOL_ERROR_NONE: No error. - * @QMI_PROTOCOL_ERROR_MALFORMED_MESSAGE: Malformed message. - * @QMI_PROTOCOL_ERROR_NO_MEMORY: No memory. - * @QMI_PROTOCOL_ERROR_INTERNAL: Internal. - * @QMI_PROTOCOL_ERROR_ABORTED: Aborted. - * @QMI_PROTOCOL_ERROR_CLIENT_IDS_EXHAUSTED: Client IDs exhausted. - * @QMI_PROTOCOL_ERROR_UNABORTABLE_TRANSACTION: Unabortable transaction. - * @QMI_PROTOCOL_ERROR_INVALID_CLIENT_ID: Invalid client ID. - * @QMI_PROTOCOL_ERROR_NO_THRESHOLDS_PROVIDED: No thresholds provided. - * @QMI_PROTOCOL_ERROR_INVALID_HANDLE: Invalid handle. - * @QMI_PROTOCOL_ERROR_INVALID_PROFILE: Invalid profile. - * @QMI_PROTOCOL_ERROR_INVALID_PIN_ID: Invalid PIN ID. - * @QMI_PROTOCOL_ERROR_INCORRECT_PIN: Incorrect PIN. - * @QMI_PROTOCOL_ERROR_NO_NETWORK_FOUND: No network found. - * @QMI_PROTOCOL_ERROR_CALL_FAILED: Call failed. - * @QMI_PROTOCOL_ERROR_OUT_OF_CALL: Out of call. - * @QMI_PROTOCOL_ERROR_NOT_PROVISIONED: Not provisioned. - * @QMI_PROTOCOL_ERROR_MISSING_ARGUMENT: Missing argument. - * @QMI_PROTOCOL_ERROR_ARGUMENT_TOO_LONG: Argument too long. - * @QMI_PROTOCOL_ERROR_INVALID_TRANSACTION_ID: Invalid transaction ID. - * @QMI_PROTOCOL_ERROR_DEVICE_IN_USE: Device in use. - * @QMI_PROTOCOL_ERROR_NETWORK_UNSUPPORTED: Network unsupported. - * @QMI_PROTOCOL_ERROR_DEVICE_UNSUPPORTED Device unsupported. - * @QMI_PROTOCOL_ERROR_NO_EFFECT: No effect. - * @QMI_PROTOCOL_ERROR_NO_FREE_PROFILE: No free profile. - * @QMI_PROTOCOL_ERROR_INVALID_PDP_TYPE: Invalid PDP type. - * @QMI_PROTOCOL_ERROR_INVALID_TECHNOLOGY_PREFERENCE: Invalid technology preference. - * @QMI_PROTOCOL_ERROR_INVALID_PROFILE_TYPE: Invalid profile type. - * @QMI_PROTOCOL_ERROR_INVALID_SERVICE_TYPE: Invalid service type. - * @QMI_PROTOCOL_ERROR_INVALID_REGISTER_ACTION: Invalid register action. - * @QMI_PROTOCOL_ERROR_INVALID_PS_ATTACH_ACTION: Invalid PS attach action. - * @QMI_PROTOCOL_ERROR_AUTHENTICATION_FAILED: Authentication failed. - * @QMI_PROTOCOL_ERROR_PIN_BLOCKED: PIN blocked. - * @QMI_PROTOCOL_ERROR_PIN_ALWAYS_BLOCKED: PIN always blocked. - * @QMI_PROTOCOL_ERROR_UIM_UNINITIALIZED: UIM uninitialized. - * @QMI_PROTOCOL_ERROR_MAXIMUM_QOS_REQUESTS_IN_USE: Maximum QoS requests in use. - * @QMI_PROTOCOL_ERROR_INCORRECT_FLOW_FILTER: Incorrect flow filter. - * @QMI_PROTOCOL_ERROR_NETWORK_QOS_UNAWARE: Network QoS unaware. - * @QMI_PROTOCOL_ERROR_INVALID_QOS_ID: Invalid QoS ID. - * @QMI_PROTOCOL_ERROR_QOS_UNAVAILABLE: QoS unavailable. - * @QMI_PROTOCOL_ERROR_FLOW_SUSPENDED: Flow suspended. - * @QMI_PROTOCOL_ERROR_GENERAL_ERROR: General error. - * @QMI_PROTOCOL_ERROR_UNKNOWN_ERROR: Unknown error. - * @QMI_PROTOCOL_ERROR_INVALID_ARGUMENT: Invalid argument. - * @QMI_PROTOCOL_ERROR_INVALID_INDEX: Invalid index. - * @QMI_PROTOCOL_ERROR_NO_ENTRY: No entry. - * @QMI_PROTOCOL_ERROR_DEVICE_STORAGE_FULL: Device storage full. - * @QMI_PROTOCOL_ERROR_DEVICE_NOT_READY: Device not ready. - * @QMI_PROTOCOL_ERROR_NETWORK_NOT_READY: Network not ready. - * @QMI_PROTOCOL_ERROR_WMS_CAUSE_CODE: WMS cause code. - * @QMI_PROTOCOL_ERROR_WMS_MESSAGE_NOT_SENT: WMS message not sent. - * @QMI_PROTOCOL_ERROR_WMS_MESSAGE_DELIVERY_FAILURE: WMS message delivery failure. - * @QMI_PROTOCOL_ERROR_WMS_INVALID_MESSAGE_ID: WMS invalid message ID. - * @QMI_PROTOCOL_ERROR_WMS_ENCODING: WMS encoding. - * @QMI_PROTOCOL_ERROR_AUTHENTICATION_LOCK: Authentication lock. - * @QMI_PROTOCOL_ERROR_INVALID_TRANSITION: Invalid transition. - * @QMI_PROTOCOL_ERROR_SESSION_INACTIVE: Session inactive. - * @QMI_PROTOCOL_ERROR_SESSION_INVALID: Session invalid. - * @QMI_PROTOCOL_ERROR_SESSION_OWNERSHIP: Session ownership. - * @QMI_PROTOCOL_ERROR_INSUFFICIENT_RESOURCES: Insufficient resources. - * @QMI_PROTOCOL_ERROR_DISABLED: Disabled. - * @QMI_PROTOCOL_ERROR_INVALID_OPERATION: Invalid operation. - * @QMI_PROTOCOL_ERROR_INVALID_QMI_COMMAND: Invalid QMI command. - * @QMI_PROTOCOL_ERROR_WMS_TPDU_TYPE: WMS TPDU type. - * @QMI_PROTOCOL_ERROR_WMS_SMSC_ADDRESS: WMS SMSC address. - * @QMI_PROTOCOL_ERROR_INFORMATION_UNAVAILABLE: Information unavailable. - * @QMI_PROTOCOL_ERROR_SEGMENT_TOO_LONG: Segment too long. - * @QMI_PROTOCOL_ERROR_SEGMENT_ORDER: Segment order. - * @QMI_PROTOCOL_ERROR_BUNDLING_NOT_SUPPORTED: Bundling not supported. - * @QMI_PROTOCOL_ERROR_SIM_FILE_NOT_FOUND: SIM file not found. - * @QMI_PROTOCOL_ERROR_ACCESS_DENIED: Access denied. - * @QMI_PROTOCOL_ERROR_HARDWARE_RESTRICTED: Hardware restricted. - * @QMI_PROTOCOL_ERROR_CAT_EVENT_REGISTRATION_FAILED: Event registration failed. - * @QMI_PROTOCOL_ERROR_CAT_INVALID_TERMINAL_RESPONSE: Invalid terminal response. - * @QMI_PROTOCOL_ERROR_CAT_INVALID_ENVELOPE_COMMAND: Invalid envelope command. - * @QMI_PROTOCOL_ERROR_CAT_ENVELOPE_COMMAND_BUSY: Envelope command busy. - * @QMI_PROTOCOL_ERROR_CAT_ENVELOPE_COMMAND_FAILED: Envelope command failed. - * - * QMI protocol errors. - */ -typedef enum { - QMI_PROTOCOL_ERROR_NONE = 0, - QMI_PROTOCOL_ERROR_MALFORMED_MESSAGE = 1, - QMI_PROTOCOL_ERROR_NO_MEMORY = 2, - QMI_PROTOCOL_ERROR_INTERNAL = 3, - QMI_PROTOCOL_ERROR_ABORTED = 4, - QMI_PROTOCOL_ERROR_CLIENT_IDS_EXHAUSTED = 5, - QMI_PROTOCOL_ERROR_UNABORTABLE_TRANSACTION = 6, - QMI_PROTOCOL_ERROR_INVALID_CLIENT_ID = 7, - QMI_PROTOCOL_ERROR_NO_THRESHOLDS_PROVIDED = 8, - QMI_PROTOCOL_ERROR_INVALID_HANDLE = 9, - QMI_PROTOCOL_ERROR_INVALID_PROFILE = 10, - QMI_PROTOCOL_ERROR_INVALID_PIN_ID = 11, - QMI_PROTOCOL_ERROR_INCORRECT_PIN = 12, - QMI_PROTOCOL_ERROR_NO_NETWORK_FOUND = 13, - QMI_PROTOCOL_ERROR_CALL_FAILED = 14, - QMI_PROTOCOL_ERROR_OUT_OF_CALL = 15, - QMI_PROTOCOL_ERROR_NOT_PROVISIONED = 16, - QMI_PROTOCOL_ERROR_MISSING_ARGUMENT = 17, - QMI_PROTOCOL_ERROR_ARGUMENT_TOO_LONG = 19, - QMI_PROTOCOL_ERROR_INVALID_TRANSACTION_ID = 22, - QMI_PROTOCOL_ERROR_DEVICE_IN_USE = 23, - QMI_PROTOCOL_ERROR_NETWORK_UNSUPPORTED = 24, - QMI_PROTOCOL_ERROR_DEVICE_UNSUPPORTED = 25, - QMI_PROTOCOL_ERROR_NO_EFFECT = 26, - QMI_PROTOCOL_ERROR_NO_FREE_PROFILE = 27, - QMI_PROTOCOL_ERROR_INVALID_PDP_TYPE = 28, - QMI_PROTOCOL_ERROR_INVALID_TECHNOLOGY_PREFERENCE = 29, - QMI_PROTOCOL_ERROR_INVALID_PROFILE_TYPE = 30, - QMI_PROTOCOL_ERROR_INVALID_SERVICE_TYPE = 31, - QMI_PROTOCOL_ERROR_INVALID_REGISTER_ACTION = 32, - QMI_PROTOCOL_ERROR_INVALID_PS_ATTACH_ACTION = 33, - QMI_PROTOCOL_ERROR_AUTHENTICATION_FAILED = 34, - QMI_PROTOCOL_ERROR_PIN_BLOCKED = 35, - QMI_PROTOCOL_ERROR_PIN_ALWAYS_BLOCKED = 36, - QMI_PROTOCOL_ERROR_UIM_UNINITIALIZED = 37, - QMI_PROTOCOL_ERROR_MAXIMUM_QOS_REQUESTS_IN_USE = 38, - QMI_PROTOCOL_ERROR_INCORRECT_FLOW_FILTER = 39, - QMI_PROTOCOL_ERROR_NETWORK_QOS_UNAWARE = 40, - QMI_PROTOCOL_ERROR_INVALID_QOS_ID = 41, - QMI_PROTOCOL_ERROR_QOS_UNAVAILABLE = 42, - QMI_PROTOCOL_ERROR_FLOW_SUSPENDED = 43, - QMI_PROTOCOL_ERROR_GENERAL_ERROR = 46, - QMI_PROTOCOL_ERROR_UNKNOWN_ERROR = 47, - QMI_PROTOCOL_ERROR_INVALID_ARGUMENT = 48, - QMI_PROTOCOL_ERROR_INVALID_INDEX = 49, - QMI_PROTOCOL_ERROR_NO_ENTRY = 50, - QMI_PROTOCOL_ERROR_DEVICE_STORAGE_FULL = 51, - QMI_PROTOCOL_ERROR_DEVICE_NOT_READY = 52, - QMI_PROTOCOL_ERROR_NETWORK_NOT_READY = 53, - QMI_PROTOCOL_ERROR_WMS_CAUSE_CODE = 54, - QMI_PROTOCOL_ERROR_WMS_MESSAGE_NOT_SENT = 55, - QMI_PROTOCOL_ERROR_WMS_MESSAGE_DELIVERY_FAILURE = 56, - QMI_PROTOCOL_ERROR_WMS_INVALID_MESSAGE_ID = 57, - QMI_PROTOCOL_ERROR_WMS_ENCODING = 58, - QMI_PROTOCOL_ERROR_AUTHENTICATION_LOCK = 59, - QMI_PROTOCOL_ERROR_INVALID_TRANSITION = 60, - QMI_PROTOCOL_ERROR_SESSION_INACTIVE = 65, - QMI_PROTOCOL_ERROR_SESSION_INVALID = 66, - QMI_PROTOCOL_ERROR_SESSION_OWNERSHIP = 67, - QMI_PROTOCOL_ERROR_INSUFFICIENT_RESOURCES = 68, - QMI_PROTOCOL_ERROR_DISABLED = 69, - QMI_PROTOCOL_ERROR_INVALID_OPERATION = 70, - QMI_PROTOCOL_ERROR_INVALID_QMI_COMMAND = 71, - QMI_PROTOCOL_ERROR_WMS_T_PDU_TYPE = 72, - QMI_PROTOCOL_ERROR_WMS_SMSC_ADDRESS = 73, - QMI_PROTOCOL_ERROR_INFORMATION_UNAVAILABLE = 74, - QMI_PROTOCOL_ERROR_SEGMENT_TOO_LONG = 75, - QMI_PROTOCOL_ERROR_SEGMENT_ORDER = 76, - QMI_PROTOCOL_ERROR_BUNDLING_NOT_SUPPORTED = 77, - QMI_PROTOCOL_ERROR_SIM_FILE_NOT_FOUND = 80, - QMI_PROTOCOL_ERROR_ACCESS_DENIED = 82, - QMI_PROTOCOL_ERROR_HARDWARE_RESTRICTED = 83, - QMI_PROTOCOL_ERROR_CAT_EVENT_REGISTRATION_FAILED = 61441, - QMI_PROTOCOL_ERROR_CAT_INVALID_TERMINAL_RESPONSE = 61442, - QMI_PROTOCOL_ERROR_CAT_INVALID_ENVELOPE_COMMAND = 61443, - QMI_PROTOCOL_ERROR_CAT_ENVELOPE_COMMAND_BUSY = 61444, - QMI_PROTOCOL_ERROR_CAT_ENVELOPE_COMMAND_FAILED = 61445 -} QmiProtocolError; - -#endif /* _LIBQMI_GLIB_QMI_ERRORS_H_ */ diff --git a/src/qmi-message.c b/src/qmi-message.c deleted file mode 100644 index 8d3abee..0000000 --- a/src/qmi-message.c +++ /dev/null @@ -1,707 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* - * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file of the libqmi library. - */ - -/* - * 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 <glib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <endian.h> - -#include "qmi-message.h" -#include "qmi-utils.h" -#include "qmi-enum-types.h" -#include "qmi-error-types.h" - -#include "qmi-ctl.h" -#include "qmi-dms.h" -#include "qmi-wds.h" - -#define PACKED __attribute__((packed)) - -struct qmux { - guint16 length; - guint8 flags; - guint8 service; - guint8 client; -} PACKED; - -struct control_header { - guint8 flags; - guint8 transaction; - guint16 message; - guint16 tlv_length; -} PACKED; - -struct service_header { - guint8 flags; - guint16 transaction; - guint16 message; - guint16 tlv_length; -} PACKED; - -struct tlv { - guint8 type; - guint16 length; - guint8 value[]; -} PACKED; - -struct control_message { - struct control_header header; - struct tlv tlv[]; -} PACKED; - -struct service_message { - struct service_header header; - struct tlv tlv[]; -} PACKED; - -struct full_message { - guint8 marker; - struct qmux qmux; - union { - struct control_message control; - struct service_message service; - } qmi; -} PACKED; - -struct _QmiMessage { - /* TODO: avoid memory split here */ - struct full_message *buf; /* buf allocated using g_malloc, not g_slice_alloc */ - gsize len; /* cached size of *buf; not part of message. */ - volatile gint ref_count; /* the ref count */ -}; - -guint16 -qmi_message_get_qmux_length (QmiMessage *self) -{ - return GUINT16_FROM_LE (self->buf->qmux.length); -} - -static inline void -set_qmux_length (QmiMessage *self, - guint16 length) -{ - self->buf->qmux.length = GUINT16_TO_LE (length); -} - -gboolean -qmi_message_is_control (QmiMessage *self) -{ - g_return_val_if_fail (self != NULL, FALSE); - - return self->buf->qmux.service == QMI_SERVICE_CTL; -} - -guint8 -qmi_message_get_qmux_flags (QmiMessage *self) -{ - g_return_val_if_fail (self != NULL, 0); - - return self->buf->qmux.flags; -} - -QmiService -qmi_message_get_service (QmiMessage *self) -{ - g_return_val_if_fail (self != NULL, QMI_SERVICE_UNKNOWN); - - return (QmiService)self->buf->qmux.service; -} - -guint8 -qmi_message_get_client_id (QmiMessage *self) -{ - g_return_val_if_fail (self != NULL, 0); - - return self->buf->qmux.client; -} - -guint8 -qmi_message_get_qmi_flags (QmiMessage *self) -{ - g_return_val_if_fail (self != NULL, 0); - - if (qmi_message_is_control (self)) - return self->buf->qmi.control.header.flags; - - return self->buf->qmi.service.header.flags; -} - -gboolean -qmi_message_is_response (QmiMessage *self) -{ - if (qmi_message_is_control (self)) { - if (self->buf->qmi.control.header.flags & QMI_CTL_FLAG_RESPONSE) - return TRUE; - } else { - if (self->buf->qmi.service.header.flags & QMI_SERVICE_FLAG_RESPONSE) - return TRUE; - } - - return FALSE; -} - -gboolean -qmi_message_is_indication (QmiMessage *self) -{ - if (qmi_message_is_control (self)) { - if (self->buf->qmi.control.header.flags & QMI_CTL_FLAG_INDICATION) - return TRUE; - } else { - if (self->buf->qmi.service.header.flags & QMI_SERVICE_FLAG_INDICATION) - return TRUE; - } - - return FALSE; -} - -guint16 -qmi_message_get_transaction_id (QmiMessage *self) -{ - g_return_val_if_fail (self != NULL, 0); - - if (qmi_message_is_control (self)) - /* note: only 1 byte for transaction in CTL message */ - return (guint16)self->buf->qmi.control.header.transaction; - - return le16toh (self->buf->qmi.service.header.transaction); -} - -guint16 -qmi_message_get_message_id (QmiMessage *self) -{ - g_return_val_if_fail (self != NULL, 0); - - if (qmi_message_is_control (self)) - return le16toh (self->buf->qmi.control.header.message); - - return le16toh (self->buf->qmi.service.header.message); -} - -gsize -qmi_message_get_length (QmiMessage *self) -{ - g_return_val_if_fail (self != NULL, 0); - - return self->len; -} - -guint16 -qmi_message_get_tlv_length (QmiMessage *self) -{ - if (qmi_message_is_control (self)) - return GUINT16_FROM_LE (self->buf->qmi.control.header.tlv_length); - - return GUINT16_FROM_LE (self->buf->qmi.service.header.tlv_length); -} - -static void -set_qmi_message_get_tlv_length (QmiMessage *self, - guint16 length) -{ - if (qmi_message_is_control (self)) - self->buf->qmi.control.header.tlv_length = GUINT16_TO_LE (length); - else - self->buf->qmi.service.header.tlv_length = GUINT16_TO_LE (length); -} - -static struct tlv * -qmi_tlv (QmiMessage *self) -{ - if (qmi_message_is_control (self)) - return self->buf->qmi.control.tlv; - - return self->buf->qmi.service.tlv; -} - -static guint8 * -qmi_end (QmiMessage *self) -{ - return (guint8 *) self->buf + self->len; -} - -static struct tlv * -tlv_next (struct tlv *tlv) -{ - return (struct tlv *)((guint8 *)tlv + sizeof(struct tlv) + le16toh (tlv->length)); -} - -static struct tlv * -qmi_tlv_first (QmiMessage *self) -{ - if (qmi_message_get_tlv_length (self)) - return qmi_tlv (self); - - return NULL; -} - -static struct tlv * -qmi_tlv_next (QmiMessage *self, - struct tlv *tlv) -{ - struct tlv *end; - struct tlv *next; - - end = (struct tlv *) qmi_end (self); - next = tlv_next (tlv); - - return (next < end ? next : NULL); -} - -/** - * Checks the validity of a QMI message. - * - * In particular, checks: - * 1. The message has space for all required headers. - * 2. The length of the buffer, the qmux length field, and the QMI tlv_length - * field are all consistent. - * 3. The TLVs in the message fit exactly in the payload size. - * - * Returns non-zero if the message is valid, zero if invalid. - */ -gboolean -qmi_message_check (QmiMessage *self, - GError **error) -{ - gsize header_length; - guint8 *end; - struct tlv *tlv; - - g_assert (self != NULL); - g_assert (self->buf != NULL); - - if (self->buf->marker != QMI_MESSAGE_QMUX_MARKER) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_INVALID_MESSAGE, - "Marker is incorrect"); - return FALSE; - } - - if (qmi_message_get_qmux_length (self) < sizeof (struct qmux)) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_INVALID_MESSAGE, - "QMUX length too short for QMUX header (%u < %" G_GSIZE_FORMAT ")", - qmi_message_get_qmux_length (self), sizeof (struct qmux)); - return FALSE; - } - - /* - * qmux length is one byte shorter than buffer length because qmux - * length does not include the qmux frame marker. - */ - if (qmi_message_get_qmux_length (self) != self->len - 1) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_INVALID_MESSAGE, - "QMUX length and buffer length don't match (%u != %" G_GSIZE_FORMAT ")", - qmi_message_get_qmux_length (self), self->len - 1); - return FALSE; - } - - header_length = sizeof (struct qmux) + (qmi_message_is_control (self) ? - sizeof (struct control_header) : - sizeof (struct service_header)); - - if (qmi_message_get_qmux_length (self) < header_length) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_INVALID_MESSAGE, - "QMUX length too short for QMI header (%u < %" G_GSIZE_FORMAT ")", - qmi_message_get_qmux_length (self), header_length); - return FALSE; - } - - if (qmi_message_get_qmux_length (self) - header_length != qmi_message_get_tlv_length (self)) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_INVALID_MESSAGE, - "QMUX length and QMI TLV lengths don't match (%u - %" G_GSIZE_FORMAT " != %u)", - qmi_message_get_qmux_length (self), header_length, qmi_message_get_tlv_length (self)); - return FALSE; - } - - end = qmi_end (self); - for (tlv = qmi_tlv (self); tlv < (struct tlv *)end; tlv = tlv_next (tlv)) { - if (tlv->value > end) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_INVALID_MESSAGE, - "TLV header runs over buffer (%p > %p)", - tlv->value, end); - return FALSE; - } - if (tlv->value + le16toh (tlv->length) > end) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_INVALID_MESSAGE, - "TLV value runs over buffer (%p + %u > %p)", - tlv->value, le16toh (tlv->length), end); - return FALSE; - } - } - - /* - * If this assert triggers, one of the if statements in the loop is wrong. - * (It shouldn't be reached on malformed QMI messages.) - */ - g_assert (tlv == (struct tlv *)end); - - return TRUE; -} - -QmiMessage * -qmi_message_new (QmiService service, - guint8 client_id, - guint16 transaction_id, - guint16 message_id) -{ - QmiMessage *self; - - /* Transaction ID in the control service is 8bit only */ - g_assert (service != QMI_SERVICE_CTL || - transaction_id <= G_MAXUINT8); - - self = g_slice_new (QmiMessage); - self->ref_count = 1; - - self->len = 1 + sizeof (struct qmux) + (service == QMI_SERVICE_CTL ? - sizeof (struct control_header) : - sizeof (struct service_header)); - - /* TODO: Allocate both the message and the buffer together */ - self->buf = g_malloc (self->len); - - self->buf->marker = QMI_MESSAGE_QMUX_MARKER; - self->buf->qmux.flags = 0; - self->buf->qmux.service = service; - self->buf->qmux.client = client_id; - set_qmux_length (self, self->len - 1); - - if (service == QMI_SERVICE_CTL) { - self->buf->qmi.control.header.flags = 0; - self->buf->qmi.control.header.transaction = (guint8)transaction_id; - self->buf->qmi.control.header.message = htole16 (message_id); - } else { - self->buf->qmi.service.header.flags = 0; - self->buf->qmi.service.header.transaction = htole16 (transaction_id); - self->buf->qmi.service.header.message = htole16 (message_id); - } - - set_qmi_message_get_tlv_length (self, 0); - - g_assert (qmi_message_check (self, NULL)); - - return self; -} - -QmiMessage * -qmi_message_ref (QmiMessage *self) -{ - g_assert (self != NULL); - - g_atomic_int_inc (&self->ref_count); - return self; -} - -void -qmi_message_unref (QmiMessage *self) -{ - g_assert (self != NULL); - - if (g_atomic_int_dec_and_test (&self->ref_count)) { - g_free (self->buf); - g_slice_free (QmiMessage, self); - } -} - -gconstpointer -qmi_message_get_raw (QmiMessage *self, - gsize *len, - GError **error) -{ - g_assert (self != NULL); - g_assert (len != NULL); - - if (!qmi_message_check (self, error)) - return NULL; - - *len = self->len; - return self->buf; -} - -gboolean -qmi_message_tlv_get (QmiMessage *self, - guint8 type, - guint16 *length, - guint8 **value, - GError **error) -{ - struct tlv *tlv; - - g_assert (self != NULL); - g_assert (self->buf != NULL); - g_assert (length != NULL); - /* note: we allow querying only for the exact length */ - - for (tlv = qmi_tlv_first (self); tlv; tlv = qmi_tlv_next (self, tlv)) { - if (tlv->type == type) { - *length = GUINT16_FROM_LE (tlv->length); - if (value) - *value = &(tlv->value[0]); - return TRUE; - } - } - - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_TLV_TOO_LONG, - "TLV not found"); - return FALSE; -} - -void -qmi_message_tlv_foreach (QmiMessage *self, - QmiMessageForeachTlvFn callback, - gpointer user_data) -{ - struct tlv *tlv; - - g_assert (self != NULL); - g_assert (callback != NULL); - - for (tlv = qmi_tlv_first (self); tlv; tlv = qmi_tlv_next (self, tlv)) { - callback (tlv->type, - (gsize)(le16toh (tlv->length)), - (gconstpointer)tlv->value, - user_data); - } -} - -gboolean -qmi_message_tlv_add (QmiMessage *self, - guint8 type, - gsize length, - gconstpointer value, - GError **error) -{ - size_t tlv_len; - struct tlv *tlv; - - g_assert (self != NULL); - g_assert ((length == 0) || value != NULL); - - /* Make sure nothing's broken to start. */ - if (!qmi_message_check (self, error)) { - g_prefix_error (error, "Invalid QMI message detected: "); - return FALSE; - } - - /* Find length of new TLV. */ - tlv_len = sizeof (struct tlv) + length; - - /* Check for overflow of message size. */ - if (qmi_message_get_qmux_length (self) + tlv_len > UINT16_MAX) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_TLV_TOO_LONG, - "TLV to add is too long"); - return FALSE; - } - - /* Resize buffer. */ - self->len += tlv_len; - self->buf = g_realloc (self->buf, self->len); - - /* Fill in new TLV. */ - tlv = (struct tlv *)(qmi_end (self) - tlv_len); - tlv->type = type; - tlv->length = htole16 (length); - if (value) - memcpy (tlv->value, value, length); - - /* Update length fields. */ - set_qmux_length (self, (guint16)(qmi_message_get_qmux_length (self) + tlv_len)); - set_qmi_message_get_tlv_length (self, (guint16)(qmi_message_get_tlv_length(self) + tlv_len)); - - /* Make sure we didn't break anything. */ - if (!qmi_message_check (self, error)) { - g_prefix_error (error, "Invalid QMI message built: "); - return FALSE; - } - - return TRUE; -} - -QmiMessage * -qmi_message_new_from_raw (const guint8 *raw, - gsize raw_len) -{ - QmiMessage *self; - gsize message_len; - - /* If we didn't even read the header, leave */ - if (raw_len < (sizeof (struct qmux) + 1)) - return NULL; - - /* We need to have read the length reported by the header. - * Otherwise, return. */ - message_len = le16toh (((struct full_message *)raw)->qmux.length); - if (raw_len < (message_len - 1)) - return NULL; - - /* Ok, so we should have all the data available already */ - self = g_slice_new (QmiMessage); - self->ref_count = 1; - self->len = message_len + 1; - self->buf = g_malloc (self->len); - memcpy (self->buf, raw, self->len); - - /* NOTE: we don't check if the message is valid here, let the caller do it */ - - return self; -} - -gchar * -qmi_message_get_tlv_printable (QmiMessage *self, - const gchar *line_prefix, - guint8 type, - gsize length, - gconstpointer value) -{ - gchar *printable; - gchar *value_hex; - - value_hex = qmi_utils_str_hex (value, length, ':'); - printable = g_strdup_printf ("%sTLV:\n" - "%s type = 0x%02x\n" - "%s length = %" G_GSIZE_FORMAT "\n" - "%s value = %s\n", - line_prefix, - line_prefix, type, - line_prefix, length, - line_prefix, value_hex); - g_free (value_hex); - return printable; -} - -static gchar * -get_generic_printable (QmiMessage *self, - const gchar *line_prefix) -{ - GString *printable; - struct tlv *tlv; - - printable = g_string_new (""); - - g_string_append_printf (printable, - "%s message = (0x%04x)\n", - line_prefix, qmi_message_get_message_id (self)); - - for (tlv = qmi_tlv_first (self); tlv; tlv = qmi_tlv_next (self, tlv)) { - gchar *printable_tlv; - - printable_tlv = qmi_message_get_tlv_printable (self, - line_prefix, - tlv->type, - tlv->length, - tlv->value); - g_string_append (printable, printable_tlv); - g_free (printable_tlv); - } - - return g_string_free (printable, FALSE); -} - -gchar * -qmi_message_get_printable (QmiMessage *self, - const gchar *line_prefix) -{ - GString *printable; - gchar *qmi_flags_str; - gchar *contents; - - if (!qmi_message_check (self, NULL)) - return NULL; - - if (!line_prefix) - line_prefix = ""; - - printable = g_string_new (""); - g_string_append_printf (printable, - "%sQMUX:\n" - "%s length = %u\n" - "%s flags = 0x%02x\n" - "%s service = \"%s\"\n" - "%s client = %u\n", - line_prefix, - line_prefix, qmi_message_get_qmux_length (self), - line_prefix, qmi_message_get_qmux_flags (self), - line_prefix, qmi_service_get_string (qmi_message_get_service (self)), - line_prefix, qmi_message_get_client_id (self)); - - if (qmi_message_get_service (self) == QMI_SERVICE_CTL) - qmi_flags_str = qmi_ctl_flag_build_string_from_mask (qmi_message_get_qmi_flags (self)); - else - qmi_flags_str = qmi_service_flag_build_string_from_mask (qmi_message_get_qmi_flags (self)); - - g_string_append_printf (printable, - "%sQMI:\n" - "%s flags = \"%s\"\n" - "%s transaction = %u\n" - "%s tlv_length = %u\n", - line_prefix, - line_prefix, qmi_flags_str, - line_prefix, qmi_message_get_transaction_id (self), - line_prefix, qmi_message_get_tlv_length (self)); - g_free (qmi_flags_str); - - contents = NULL; - switch (qmi_message_get_service (self)) { - case QMI_SERVICE_CTL: - contents = qmi_message_ctl_get_printable (self, line_prefix); - break; - case QMI_SERVICE_DMS: - contents = qmi_message_dms_get_printable (self, line_prefix); - break; - case QMI_SERVICE_WDS: - contents = qmi_message_wds_get_printable (self, line_prefix); - break; - default: - break; - } - - if (!contents) - contents = get_generic_printable (self, line_prefix); - g_string_append (printable, contents); - g_free (contents); - - return g_string_free (printable, FALSE); -} diff --git a/src/qmi-message.h b/src/qmi-message.h deleted file mode 100644 index ff64a91..0000000 --- a/src/qmi-message.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* - * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* - * 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_MESSAGE_H_ -#define _LIBQMI_GLIB_QMI_MESSAGE_H_ - -#include <glib.h> - -#include "qmi-enums.h" - -G_BEGIN_DECLS - -#define QMI_MESSAGE_QMUX_MARKER (guint8)0x01 -typedef struct _QmiMessage QmiMessage; - -QmiMessage *qmi_message_new (QmiService service, - guint8 client_id, - guint16 transaction_id, - guint16 message_id); -QmiMessage *qmi_message_new_from_raw (const guint8 *raw, - gsize raw_len); -QmiMessage *qmi_message_ref (QmiMessage *self); -void qmi_message_unref (QmiMessage *self); - -typedef void (* QmiMessageForeachTlvFn) (guint8 type, - gsize length, - gconstpointer value, - gpointer user_data); -void qmi_message_tlv_foreach (QmiMessage *self, - QmiMessageForeachTlvFn callback, - gpointer user_data); - -gboolean qmi_message_tlv_get (QmiMessage *self, - guint8 type, - guint16 *length, - guint8 **value, - GError **error); - -gboolean qmi_message_tlv_add (QmiMessage *self, - guint8 type, - gsize length, - gconstpointer value, - GError **error); - -gconstpointer qmi_message_get_raw (QmiMessage *self, - gsize *length, - GError **error); - -guint16 qmi_message_get_qmux_length (QmiMessage *self); -guint16 qmi_message_get_tlv_length (QmiMessage *self); -gsize qmi_message_get_length (QmiMessage *self); - -gchar *qmi_message_get_printable (QmiMessage *self, - const gchar *line_prefix); - -gchar *qmi_message_get_tlv_printable (QmiMessage *self, - const gchar *line_prefix, - guint8 type, - gsize length, - gconstpointer value); - -gboolean qmi_message_check (QmiMessage *self, - GError **error); - -gboolean qmi_message_is_control (QmiMessage *self); -gboolean qmi_message_is_response (QmiMessage *self); -gboolean qmi_message_is_indication (QmiMessage *self); - -guint16 qmi_message_get_message_id (QmiMessage *self); -QmiService qmi_message_get_service (QmiMessage *self); -guint8 qmi_message_get_client_id (QmiMessage *self); -guint16 qmi_message_get_transaction_id (QmiMessage *self); -guint8 qmi_message_get_qmux_flags (QmiMessage *self); -guint8 qmi_message_get_qmi_flags (QmiMessage *self); - -G_END_DECLS - -#endif /* _LIBQMI_GLIB_QMI_MESSAGE_H_ */ diff --git a/src/qmi-utils.c b/src/qmi-utils.c deleted file mode 100644 index d1e50f0..0000000 --- a/src/qmi-utils.c +++ /dev/null @@ -1,312 +0,0 @@ -/* -*- 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 <string.h> -#include <stdint.h> -#include <stdio.h> - -#include "qmi-utils.h" - -gchar * -qmi_utils_str_hex (gconstpointer mem, - gsize size, - gchar delimiter) -{ - const guint8 *data = mem; - gsize i; - gsize j; - gsize new_str_length; - gchar *new_str; - - /* Get new string length. If input string has N bytes, we need: - * - 1 byte for last NUL char - * - 2N bytes for hexadecimal char representation of each byte... - * - N-1 bytes for the separator ':' - * So... a total of (1+2N+N-1) = 3N bytes are needed... */ - new_str_length = 3 * size; - - /* Allocate memory for new array and initialize contents to NUL */ - new_str = g_malloc0 (new_str_length); - - /* Print hexadecimal representation of each byte... */ - for (i = 0, j = 0; i < size; i++, j += 3) { - /* Print character in output string... */ - snprintf (&new_str[j], 3, "%02X", data[i]); - /* And if needed, add separator */ - if (i != (size - 1) ) - new_str[j + 2] = delimiter; - } - - /* Set output string */ - return new_str; -} - -void -qmi_utils_read_guint8_from_buffer (guint8 **buffer, - guint16 *buffer_size, - guint8 *out) -{ - g_assert (out != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - g_assert (*buffer_size >= 1); - - *out = (*buffer)[0]; - - *buffer = &((*buffer)[1]); - *buffer_size = (*buffer_size) - 1; -} - -void -qmi_utils_read_gint8_from_buffer (guint8 **buffer, - guint16 *buffer_size, - gint8 *out) -{ - g_assert (out != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - g_assert (*buffer_size >= 1); - - *out = *((gint8 *)(&((*buffer)[0]))); - - *buffer = &((*buffer)[1]); - *buffer_size = (*buffer_size) - 1; -} - -void -qmi_utils_read_guint16_from_buffer (guint8 **buffer, - guint16 *buffer_size, - guint16 *out) -{ - g_assert (out != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - g_assert (*buffer_size >= 2); - - *out = GUINT16_FROM_LE (*((guint16 *)&((*buffer)[0]))); - - *buffer = &((*buffer)[2]); - *buffer_size = (*buffer_size) - 2; -} - -void -qmi_utils_read_gint16_from_buffer (guint8 **buffer, - guint16 *buffer_size, - gint16 *out) -{ - g_assert (out != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - g_assert (*buffer_size >= 2); - - *out = GINT16_FROM_LE (*((guint16 *)&((*buffer)[0]))); - - *buffer = &((*buffer)[2]); - *buffer_size = (*buffer_size) - 2; -} - -void -qmi_utils_read_guint32_from_buffer (guint8 **buffer, - guint16 *buffer_size, - guint32 *out) -{ - g_assert (out != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - g_assert (*buffer_size >= 4); - - *out = GUINT32_FROM_LE (*((guint32 *)&((*buffer)[0]))); - - *buffer = &((*buffer)[4]); - *buffer_size = (*buffer_size) - 4; -} - -void -qmi_utils_read_gint32_from_buffer (guint8 **buffer, - guint16 *buffer_size, - gint32 *out) -{ - g_assert (out != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - g_assert (*buffer_size >= 4); - - *out = GUINT32_FROM_LE (*((guint32 *)&((*buffer)[0]))); - - *buffer = &((*buffer)[4]); - *buffer_size = (*buffer_size) - 4; -} - -void -qmi_utils_write_guint8_to_buffer (guint8 **buffer, - guint16 *buffer_size, - guint8 *in) -{ - g_assert (in != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - g_assert (*buffer_size >= 1); - - (*buffer)[0] = *in; - - *buffer = &((*buffer)[1]); - *buffer_size = (*buffer_size) - 1; -} - -void -qmi_utils_write_gint8_to_buffer (guint8 **buffer, - guint16 *buffer_size, - gint8 *in) -{ - g_assert (in != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - g_assert (*buffer_size >= 1); - - *((gint8 *)(&((*buffer)[0]))) = *in; - - *buffer = &((*buffer)[1]); - *buffer_size = (*buffer_size) - 1; -} - -void -qmi_utils_write_guint16_to_buffer (guint8 **buffer, - guint16 *buffer_size, - guint16 *in) -{ - g_assert (in != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - g_assert (*buffer_size >= 2); - - *((guint16 *)(&((*buffer)[0]))) = GUINT16_TO_LE (*in); - - *buffer = &((*buffer)[2]); - *buffer_size = (*buffer_size) - 2; -} - -void -qmi_utils_write_gint16_to_buffer (guint8 **buffer, - guint16 *buffer_size, - gint16 *in) -{ - g_assert (in != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - g_assert (*buffer_size >= 2); - - *((gint16 *)(&((*buffer)[0]))) = GINT16_TO_LE (*in); - - *buffer = &((*buffer)[2]); - *buffer_size = (*buffer_size) - 2; -} - -void -qmi_utils_write_guint32_to_buffer (guint8 **buffer, - guint16 *buffer_size, - guint32 *in) -{ - g_assert (in != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - g_assert (*buffer_size >= 4); - - *((guint32 *)(&((*buffer)[0]))) = GUINT32_TO_LE (*in); - - *buffer = &((*buffer)[4]); - *buffer_size = (*buffer_size) - 4; -} - -void -qmi_utils_write_gint32_to_buffer (guint8 **buffer, - guint16 *buffer_size, - gint32 *in) -{ - g_assert (in != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - g_assert (*buffer_size >= 4); - - *((gint32 *)(&((*buffer)[0]))) = GINT32_TO_LE (*in); - - *buffer = &((*buffer)[4]); - *buffer_size = (*buffer_size) - 4; -} - -void -qmi_utils_read_string_from_buffer (guint8 **buffer, - guint16 *buffer_size, - gboolean length_prefix, - gchar **out) -{ - guint16 string_length; - - g_assert (out != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - - /* If no length prefix given, read the whole buffer into a string */ - if (!length_prefix) - string_length = *buffer_size; - else { - /* We assume the length prefix is always a guint8 */ - guint8 string_length_8; - - qmi_utils_read_guint8_from_buffer (buffer, buffer_size, &string_length_8); - string_length = string_length_8; - } - - *out = g_malloc (string_length + 1); - (*out)[string_length] = '\0'; - memcpy (*out, *buffer, string_length); - - *buffer = &((*buffer)[string_length]); - *buffer_size = (*buffer_size) - string_length; -} - -void -qmi_utils_write_string_to_buffer (guint8 **buffer, - guint16 *buffer_size, - gboolean length_prefix, - gchar **in) -{ - guint16 len; - - g_assert (in != NULL); - g_assert (buffer != NULL); - g_assert (buffer_size != NULL); - - len = (guint16) strlen (*in); - - if (length_prefix) { - guint8 len_8; - - g_warn_if_fail (len <= G_MAXUINT8); - len_8 = (guint8)len; - qmi_utils_write_guint8_to_buffer (buffer, buffer_size, &len_8); - } - - memcpy (*buffer, *in, len); - *buffer = &((*buffer)[len]); - *buffer_size = (*buffer_size) - len; -} diff --git a/src/qmi-utils.h b/src/qmi-utils.h deleted file mode 100644 index 7c098a0..0000000 --- a/src/qmi-utils.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- 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> - */ - -/* NOTE: this is a private non-installable header */ - -#ifndef _LIBQMI_GLIB_QMI_UTILS_H_ -#define _LIBQMI_GLIB_QMI_UTILS_H_ - -#include <glib.h> - -G_BEGIN_DECLS - -gchar *qmi_utils_str_hex (gconstpointer mem, - gsize size, - gchar delimiter); - -/* Reading/Writing integer variables */ - -void qmi_utils_read_guint8_from_buffer (guint8 **buffer, - guint16 *buffer_size, - guint8 *out); -void qmi_utils_read_gint8_from_buffer (guint8 **buffer, - guint16 *buffer_size, - gint8 *out); - -void qmi_utils_read_guint16_from_buffer (guint8 **buffer, - guint16 *buffer_size, - guint16 *out); -void qmi_utils_read_gint16_from_buffer (guint8 **buffer, - guint16 *buffer_size, - gint16 *out); - -void qmi_utils_read_guint32_from_buffer (guint8 **buffer, - guint16 *buffer_size, - guint32 *out); -void qmi_utils_read_gint32_from_buffer (guint8 **buffer, - guint16 *buffer_size, - gint32 *out); - -void qmi_utils_write_guint8_to_buffer (guint8 **buffer, - guint16 *buffer_size, - guint8 *in); -void qmi_utils_write_gint8_to_buffer (guint8 **buffer, - guint16 *buffer_size, - gint8 *in); - -void qmi_utils_write_guint16_to_buffer (guint8 **buffer, - guint16 *buffer_size, - guint16 *in); -void qmi_utils_write_gint16_to_buffer (guint8 **buffer, - guint16 *buffer_size, - gint16 *in); - -void qmi_utils_write_guint32_to_buffer (guint8 **buffer, - guint16 *buffer_size, - guint32 *in); -void qmi_utils_write_gint32_to_buffer (guint8 **buffer, - guint16 *buffer_size, - gint32 *in); - -/* Reading/Writing string variables */ - -void qmi_utils_read_string_from_buffer (guint8 **buffer, - guint16 *buffer_size, - gboolean length_prefix, - gchar **out); - -void qmi_utils_write_string_to_buffer (guint8 **buffer, - guint16 *buffer_size, - gboolean length_prefix, - gchar **in); - -G_END_DECLS - -#endif /* _LIBQMI_GLIB_QMI_UTILS_H_ */ |