aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2013-07-10 22:04:48 +0200
committerAleksander Morgado <aleksander@lanedo.com>2013-09-05 15:36:34 +0200
commitdd71f8404b670980372bf0585fc278575d1625b5 (patch)
treeb7406aea29b3207c74b4a28ff2d58b96117a8010 /src
parent02e03eae044565b10175bb30b872ec4fdeaab738 (diff)
downloadexternal_libqmi-dd71f8404b670980372bf0585fc278575d1625b5.zip
external_libqmi-dd71f8404b670980372bf0585fc278575d1625b5.tar.gz
external_libqmi-dd71f8404b670980372bf0585fc278575d1625b5.tar.bz2
build: move source code under src/
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/libqmi-glib/Makefile.am63
-rw-r--r--src/libqmi-glib/generated/Makefile.am243
-rw-r--r--src/libqmi-glib/libqmi-glib.h69
-rw-r--r--src/libqmi-glib/qmi-client.c374
-rw-r--r--src/libqmi-glib/qmi-client.h99
-rw-r--r--src/libqmi-glib/qmi-device.c2331
-rw-r--r--src/libqmi-glib/qmi-device.h199
-rw-r--r--src/libqmi-glib/qmi-enums-dms.h341
-rw-r--r--src/libqmi-glib/qmi-enums-nas.h875
-rw-r--r--src/libqmi-glib/qmi-enums-oma.h124
-rw-r--r--src/libqmi-glib/qmi-enums-pbm.h112
-rw-r--r--src/libqmi-glib/qmi-enums-pds.h154
-rw-r--r--src/libqmi-glib/qmi-enums-private.h85
-rw-r--r--src/libqmi-glib/qmi-enums-uim.h124
-rw-r--r--src/libqmi-glib/qmi-enums-wds.c53
-rw-r--r--src/libqmi-glib/qmi-enums-wds.h971
-rw-r--r--src/libqmi-glib/qmi-enums-wms.h429
-rw-r--r--src/libqmi-glib/qmi-enums.h105
-rw-r--r--src/libqmi-glib/qmi-errors.h279
-rw-r--r--src/libqmi-glib/qmi-flags64-dms.h204
-rw-r--r--src/libqmi-glib/qmi-flags64-nas.h200
-rw-r--r--src/libqmi-glib/qmi-message.c923
-rw-r--r--src/libqmi-glib/qmi-message.h114
-rw-r--r--src/libqmi-glib/qmi-utils.c1024
-rw-r--r--src/libqmi-glib/qmi-utils.h166
-rw-r--r--src/libqmi-glib/qmi-version.h.in69
-rw-r--r--src/libqmi-glib/test/Makefile.am36
-rw-r--r--src/libqmi-glib/test/test-message.c150
-rw-r--r--src/libqmi-glib/test/test-utils.c1265
-rw-r--r--src/qmicli/Makefile.am27
-rw-r--r--src/qmicli/qmicli-dms.c3579
-rw-r--r--src/qmicli/qmicli-helpers.c308
-rw-r--r--src/qmicli/qmicli-helpers.h55
-rw-r--r--src/qmicli/qmicli-nas.c2427
-rw-r--r--src/qmicli/qmicli-pbm.c312
-rw-r--r--src/qmicli/qmicli-uim.c556
-rw-r--r--src/qmicli/qmicli-wds.c827
-rw-r--r--src/qmicli/qmicli.c620
-rw-r--r--src/qmicli/qmicli.h64
-rw-r--r--src/qmicli/test/Makefile.am24
-rw-r--r--src/qmicli/test/test-helpers.c125
42 files changed, 20107 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..6d08b9c
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,2 @@
+
+SUBDIRS = libqmi-glib qmicli
diff --git a/src/libqmi-glib/Makefile.am b/src/libqmi-glib/Makefile.am
new file mode 100644
index 0000000..bb958a1
--- /dev/null
+++ b/src/libqmi-glib/Makefile.am
@@ -0,0 +1,63 @@
+
+SUBDIRS = generated . test
+
+lib_LTLIBRARIES = libqmi-glib.la
+
+libqmi_glib_la_CPPFLAGS = \
+ $(LIBQMI_GLIB_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/src/libqmi-glib \
+ -I$(top_srcdir)/src/libqmi-glib/generated \
+ -I$(top_builddir)/src/libqmi-glib \
+ -I$(top_builddir)/src/libqmi-glib/generated \
+ -DLIBQMI_GLIB_COMPILATION \
+ -DG_LOG_DOMAIN=\"Qmi\"
+
+libqmi_glib_la_SOURCES = \
+ libqmi-glib.h \
+ qmi-version.h \
+ qmi-errors.h \
+ qmi-enums-wds.h qmi-enums-wds.c \
+ qmi-enums-dms.h qmi-flags64-dms.h \
+ qmi-enums-nas.h qmi-flags64-nas.h\
+ qmi-enums-wms.h \
+ qmi-enums-pds.h \
+ qmi-enums-pbm.h \
+ qmi-enums-uim.h \
+ qmi-enums-oma.h \
+ qmi-enums.h qmi-enums-private.h \
+ qmi-utils.h qmi-utils.c \
+ qmi-message.h qmi-message.c \
+ qmi-device.h qmi-device.c \
+ qmi-client.h qmi-client.c
+
+libqmi_glib_la_LIBADD = \
+ ${top_builddir}/src/libqmi-glib/generated/libqmi-glib-generated.la \
+ $(LIBQMI_GLIB_LIBS)
+
+libqmi_glib_la_LDFLAGS = \
+ -version-info $(QMI_GLIB_LT_CURRENT):$(QMI_GLIB_LT_REVISION):$(QMI_GLIB_LT_AGE)
+
+includedir = @includedir@/libqmi-glib
+include_HEADERS = \
+ libqmi-glib.h \
+ qmi-version.h \
+ qmi-errors.h \
+ qmi-enums.h \
+ qmi-enums-private.h \
+ qmi-enums-dms.h qmi-flags64-dms.h \
+ qmi-enums-wds.h \
+ qmi-enums-nas.h qmi-flags64-nas.h \
+ qmi-enums-wms.h \
+ qmi-enums-pds.h \
+ qmi-enums-pbm.h \
+ qmi-enums-uim.h \
+ qmi-enums-oma.h \
+ qmi-utils.h \
+ qmi-message.h \
+ qmi-device.h \
+ qmi-client.h
+
+EXTRA_DIST = \
+ qmi-version.h.in
diff --git a/src/libqmi-glib/generated/Makefile.am b/src/libqmi-glib/generated/Makefile.am
new file mode 100644
index 0000000..6701bf9
--- /dev/null
+++ b/src/libqmi-glib/generated/Makefile.am
@@ -0,0 +1,243 @@
+
+noinst_LTLIBRARIES = libqmi-glib-generated.la
+
+GENERATED_H = \
+ qmi-error-types.h \
+ qmi-enum-types.h \
+ qmi-enum-types-private.h \
+ qmi-flags64-types.h \
+ qmi-ctl.h \
+ qmi-dms.h \
+ qmi-nas.h \
+ qmi-wds.h \
+ qmi-wms.h \
+ qmi-pds.h \
+ qmi-pbm.h \
+ qmi-uim.h \
+ qmi-oma.h
+
+GENERATED_C = \
+ qmi-error-types.c \
+ qmi-error-quarks.c \
+ qmi-enum-types.c \
+ qmi-enum-types-private.c \
+ qmi-flags64-types.c \
+ qmi-ctl.c \
+ qmi-dms.c \
+ qmi-nas.c \
+ qmi-wds.c \
+ qmi-wms.c \
+ qmi-pds.c \
+ qmi-pbm.c \
+ qmi-uim.c \
+ qmi-oma.c
+
+GENERATED_SECTIONS = \
+ qmi-ctl.sections \
+ qmi-dms.sections \
+ qmi-nas.sections \
+ qmi-wds.sections \
+ qmi-wms.sections \
+ qmi-pds.sections \
+ qmi-pbm.sections \
+ qmi-uim.sections \
+ qmi-oma.sections
+
+# Error types
+qmi-error-types.h: $(top_srcdir)/src/libqmi-glib/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" \
+ $(top_srcdir)/src/libqmi-glib/qmi-errors.h > $@
+
+qmi-error-types.c: $(top_srcdir)/src/libqmi-glib/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 \
+ $(top_srcdir)/src/libqmi-glib/qmi-errors.h > $@
+
+qmi-error-quarks.c: $(top_srcdir)/src/libqmi-glib/qmi-errors.h qmi-error-types.h $(top_srcdir)/build-aux/templates/qmi-error-quarks-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-quarks-template.c \
+ $(top_srcdir)/src/libqmi-glib/qmi-errors.h > $@
+
+# Enum/Flag types
+ENUMS = \
+ $(top_srcdir)/src/libqmi-glib/qmi-enums.h \
+ $(top_srcdir)/src/libqmi-glib/qmi-enums-wds.h \
+ $(top_srcdir)/src/libqmi-glib/qmi-enums-dms.h \
+ $(top_srcdir)/src/libqmi-glib/qmi-enums-nas.h \
+ $(top_srcdir)/src/libqmi-glib/qmi-enums-wms.h \
+ $(top_srcdir)/src/libqmi-glib/qmi-enums-pds.h \
+ $(top_srcdir)/src/libqmi-glib/qmi-enums-pbm.h \
+ $(top_srcdir)/src/libqmi-glib/qmi-enums-uim.h \
+ $(top_srcdir)/src/libqmi-glib/qmi-enums-oma.h
+qmi-enum-types.h: $(ENUMS) $(top_srcdir)/build-aux/templates/qmi-enum-types-template.h
+ $(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-enums-nas.h\"\n#include \"qmi-enums-wms.h\"\n#include \"qmi-enums-pds.h\"\n#include \"qmi-enums-pbm.h\"\n#include \"qmi-enums-uim.h\"\n#include \"qmi-enums-oma.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) > $@
+
+# Private Enum/Flag types
+PRIVATE_ENUMS = \
+ $(top_srcdir)/src/libqmi-glib/qmi-enums-private.h
+qmi-enum-types-private.h: $(PRIVATE_ENUMS) $(top_srcdir)/build-aux/templates/qmi-enum-types-template.h
+ $(AM_V_GEN) $(GLIB_MKENUMS) \
+ --fhead "#ifndef __LIBQMI_GLIB_ENUM_TYPES_PRIVATE_H__\n#define __LIBQMI_GLIB_ENUM_TYPES_PRIVATE_H__\n#include \"qmi-enums-private.h\"\n" \
+ --template $(top_srcdir)/build-aux/templates/qmi-enum-types-template.h \
+ --ftail "#endif /* __LIBQMI_GLIB_ENUM_TYPES_PRIVATE_H__ */\n" \
+ $(PRIVATE_ENUMS) > $@
+
+qmi-enum-types-private.c: $(PRIVATE_ENUMS) qmi-enum-types-private.h $(top_srcdir)/build-aux/templates/qmi-enum-types-template.c
+ $(AM_V_GEN) $(GLIB_MKENUMS) \
+ --fhead "#include \"qmi-enum-types-private.h\"\n" \
+ --template $(top_srcdir)/build-aux/templates/qmi-enum-types-template.c \
+ $(PRIVATE_ENUMS) > $@
+
+# 64bit flag types
+FLAGS64 = $(top_srcdir)/src/libqmi-glib/qmi-flags64-dms.h $(top_srcdir)/src/libqmi-glib/qmi-flags64-nas.h
+qmi-flags64-types.h: $(FLAGS64) $(top_srcdir)/build-aux/templates/qmi-flags64-types-template.h
+ $(AM_V_GEN) $(GLIB_MKENUMS) \
+ --fhead "#ifndef __LIBQMI_GLIB_FLAGS64_TYPES_H__\n#define __LIBQMI_GLIB_FLAGS64_TYPES_H__\n#include \"qmi-flags64-dms.h\"\n#include \"qmi-flags64-nas.h\"\n" \
+ --template $(top_srcdir)/build-aux/templates/qmi-flags64-types-template.h \
+ --ftail "#endif /* __LIBQMI_GLIB_FLAGS64_TYPES_H__ */\n" \
+ $(FLAGS64) > $@
+
+qmi-flags64-types.c: $(FLAGS64) qmi-flags64-types.h $(top_srcdir)/build-aux/templates/qmi-flags64-types-template.c
+ $(AM_V_GEN) $(GLIB_MKENUMS) \
+ --fhead "#include \"qmi-flags64-types.h\"\n" \
+ --template $(top_srcdir)/build-aux/templates/qmi-flags64-types-template.c \
+ $(FLAGS64) > $@
+
+# CTL service
+qmi-ctl.h qmi-ctl.c qmi-ctl.sections: $(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
+
+# DMS service
+qmi-dms.h qmi-dms.c qmi-dms.sections: $(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
+
+# WDS service
+qmi-wds.h qmi-wds.c qmi-wds.sections: $(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
+
+# NAS service
+qmi-nas.h qmi-nas.c qmi-nas.sections: $(top_srcdir)/data/qmi-service-nas.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+ $(AM_V_GEN) \
+ rm -f qmi-nas.h && \
+ rm -f qmi-nas.c && \
+ $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
+ --input $(top_srcdir)/data/qmi-service-nas.json \
+ --include $(top_srcdir)/data/qmi-common.json \
+ --output qmi-nas
+
+# WMS service
+qmi-wms.h qmi-wms.c qmi-wms.sections: $(top_srcdir)/data/qmi-service-wms.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+ $(AM_V_GEN) \
+ rm -f qmi-wms.h && \
+ rm -f qmi-wms.c && \
+ $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
+ --input $(top_srcdir)/data/qmi-service-wms.json \
+ --include $(top_srcdir)/data/qmi-common.json \
+ --output qmi-wms
+
+# PDS service
+qmi-pds.h qmi-pds.c qmi-pds.sections: $(top_srcdir)/data/qmi-service-pds.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+ $(AM_V_GEN) \
+ rm -f qmi-pds.h && \
+ rm -f qmi-pds.c && \
+ $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
+ --input $(top_srcdir)/data/qmi-service-pds.json \
+ --include $(top_srcdir)/data/qmi-common.json \
+ --output qmi-pds
+
+# PBM service
+qmi-pbm.h qmi-pbm.c qmi-pbm.sections: $(top_srcdir)/data/qmi-service-pbm.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+ $(AM_V_GEN) \
+ rm -f qmi-pbm.h && \
+ rm -f qmi-pbm.c && \
+ $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
+ --input $(top_srcdir)/data/qmi-service-pbm.json \
+ --include $(top_srcdir)/data/qmi-common.json \
+ --output qmi-pbm
+
+# UIM service
+qmi-uim.h qmi-uim.c qmi-uim.sections: $(top_srcdir)/data/qmi-service-uim.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+ $(AM_V_GEN) \
+ rm -f qmi-uim.h && \
+ rm -f qmi-uim.c && \
+ $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
+ --input $(top_srcdir)/data/qmi-service-uim.json \
+ --include $(top_srcdir)/data/qmi-common.json \
+ --output qmi-uim
+
+# OMA service
+qmi-oma.h qmi-oma.c qmi-oma.sections: $(top_srcdir)/data/qmi-service-oma.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+ $(AM_V_GEN) \
+ rm -f qmi-oma.h && \
+ rm -f qmi-oma.c && \
+ $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
+ --input $(top_srcdir)/data/qmi-service-oma.json \
+ --include $(top_srcdir)/data/qmi-common.json \
+ --output qmi-oma
+
+BUILT_SOURCES = $(GENERATED_H) $(GENERATED_C)
+
+nodist_libqmi_glib_generated_la_SOURCES = \
+ $(GENERATED_H) \
+ $(GENERATED_C)
+
+libqmi_glib_generated_la_CPPFLAGS = \
+ $(LIBQMI_GLIB_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src/libqmi-glib \
+ -I$(top_builddir)/src/libqmi-glib \
+ -DLIBQMI_GLIB_COMPILATION \
+ -DG_LOG_DOMAIN=\"Qmi\" \
+ -Wno-unused-function
+
+libqmi_glib_generated_la_LIBADD = \
+ $(LIBQMI_GLIB_LIBS)
+
+includedir = @includedir@/libqmi-glib
+nodist_include_HEADERS = \
+ qmi-error-types.h \
+ qmi-enum-types.h \
+ qmi-flags64-types.h \
+ qmi-dms.h \
+ qmi-nas.h \
+ qmi-wds.h \
+ qmi-wms.h \
+ qmi-pds.h \
+ qmi-pbm.h \
+ qmi-uim.h \
+ qmi-oma.h
+
+CLEANFILES = $(GENERATED_H) $(GENERATED_C) $(GENERATED_SECTIONS)
diff --git a/src/libqmi-glib/libqmi-glib.h b/src/libqmi-glib/libqmi-glib.h
new file mode 100644
index 0000000..2143e86
--- /dev/null
+++ b/src/libqmi-glib/libqmi-glib.h
@@ -0,0 +1,69 @@
+/* -*- 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>
+ * Copyright (C) 2012 Google, Inc.
+ */
+
+#ifndef _LIBQMI_GLIB_H_
+#define _LIBQMI_GLIB_H_
+
+#define __LIBQMI_GLIB_H_INSIDE__
+
+/* libqmi-glib headers */
+
+#include "qmi-version.h"
+#include "qmi-device.h"
+#include "qmi-client.h"
+#include "qmi-message.h"
+#include "qmi-enums.h"
+#include "qmi-utils.h"
+
+#include "qmi-enums-dms.h"
+#include "qmi-flags64-dms.h"
+#include "qmi-dms.h"
+
+#include "qmi-flags64-nas.h"
+#include "qmi-enums-nas.h"
+#include "qmi-nas.h"
+
+#include "qmi-enums-wds.h"
+#include "qmi-wds.h"
+
+#include "qmi-enums-wms.h"
+#include "qmi-wms.h"
+
+#include "qmi-enums-pds.h"
+#include "qmi-pds.h"
+
+#include "qmi-enums-pbm.h"
+#include "qmi-pbm.h"
+
+#include "qmi-enums-uim.h"
+#include "qmi-uim.h"
+
+#include "qmi-enums-oma.h"
+#include "qmi-oma.h"
+
+/* generated */
+#include "qmi-error-types.h"
+#include "qmi-enum-types.h"
+#include "qmi-flags64-types.h"
+
+#endif /* _LIBQMI_GLIB_H_ */
diff --git a/src/libqmi-glib/qmi-client.c b/src/libqmi-glib/qmi-client.c
new file mode 100644
index 0000000..aec7299
--- /dev/null
+++ b/src/libqmi-glib/qmi-client.c
@@ -0,0 +1,374 @@
+/* -*- 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"
+
+/**
+ * SECTION:qmi-client
+ * @title: QmiClient
+ * @short_description: Generic QMI client handling routines
+ *
+ * #QmiClient is a generic type representing a QMI client for any kind of
+ * #QmiService.
+ *
+ * These objects are created by a #QmiDevice with qmi_device_allocate_client(),
+ * and before completely disposing them qmi_device_release_client() needs to be
+ * called in order to release the unique client ID reserved.
+ */
+
+G_DEFINE_ABSTRACT_TYPE (QmiClient, qmi_client, G_TYPE_OBJECT);
+
+enum {
+ PROP_0,
+ PROP_DEVICE,
+ PROP_SERVICE,
+ PROP_CID,
+ PROP_VERSION_MAJOR,
+ PROP_VERSION_MINOR,
+ PROP_LAST
+};
+
+static GParamSpec *properties[PROP_LAST];
+
+struct _QmiClientPrivate {
+ QmiDevice *device;
+ QmiService service;
+ guint8 cid;
+ guint version_major;
+ guint version_minor;
+
+ 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_version:
+ * @self: A #QmiClient
+ * @major: placeholder for the output major version.
+ * @minor: placeholder for the output minor version.
+ *
+ * Get the version of the service handled by this #QmiClient.
+ *
+ * Returns: %TRUE if the version was properly reported, %FALSE otherwise.
+ */
+gboolean
+qmi_client_get_version (QmiClient *self,
+ guint *major,
+ guint *minor)
+{
+ g_return_val_if_fail (QMI_IS_CLIENT (self), FALSE);
+
+ /* If the major version is greater than zero, assume it was
+ * set properly */
+ if (!self->priv->version_major)
+ return FALSE;
+
+ *major = self->priv->version_major;
+ *minor = self->priv->version_minor;
+ return TRUE;
+}
+
+/**
+ * qmi_client_check_version:
+ * @self: A #QmiClient
+ * @major: a major version.
+ * @minor: a minor version.
+ *
+ * Checks if the version of the service handled by this #QmiClient is greater
+ * or equal than the given version.
+ *
+ * Returns: %TRUE if the version of the service is greater or equal than the one given, %FALSE otherwise.
+ */
+gboolean
+qmi_client_check_version (QmiClient *self,
+ guint major,
+ guint minor)
+{
+ g_return_val_if_fail (QMI_IS_CLIENT (self), FALSE);
+
+ /* If the major version is greater than zero, assume it was
+ * set properly */
+ if (!self->priv->version_major)
+ return FALSE;
+
+ if (self->priv->version_major > major ||
+ (self->priv->version_major == major &&
+ self->priv->version_minor >= minor))
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
+ * 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;
+ case PROP_VERSION_MAJOR:
+ self->priv->version_major = g_value_get_uint (value);
+ break;
+ case PROP_VERSION_MINOR:
+ self->priv->version_minor = 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;
+ case PROP_VERSION_MAJOR:
+ g_value_set_uint (value, self->priv->version_major);
+ break;
+ case PROP_VERSION_MINOR:
+ g_value_set_uint (value, self->priv->version_minor);
+ 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;
+ self->priv->version_major = 0;
+ self->priv->version_minor = 0;
+}
+
+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]);
+
+ properties[PROP_VERSION_MAJOR] =
+ g_param_spec_uint (QMI_CLIENT_VERSION_MAJOR,
+ "Version major",
+ "Major version of the service handled by this client",
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_VERSION_MAJOR, properties[PROP_VERSION_MAJOR]);
+
+ properties[PROP_VERSION_MINOR] =
+ g_param_spec_uint (QMI_CLIENT_VERSION_MINOR,
+ "Version minor",
+ "Minor version of the service handled by this client",
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_VERSION_MINOR, properties[PROP_VERSION_MINOR]);
+}
diff --git a/src/libqmi-glib/qmi-client.h b/src/libqmi-glib/qmi-client.h
new file mode 100644
index 0000000..1305f15
--- /dev/null
+++ b/src/libqmi-glib/qmi-client.h
@@ -0,0 +1,99 @@
+/* -*- 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_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+#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"
+#define QMI_CLIENT_VERSION_MAJOR "client-version-major"
+#define QMI_CLIENT_VERSION_MINOR "client-version-minor"
+
+/**
+ * QmiClient:
+ *
+ * The #QmiClient structure contains private data and should only be accessed
+ * using the provided API.
+ */
+struct _QmiClient {
+ /*< private >*/
+ GObject parent;
+ QmiClientPrivate *priv;
+};
+
+struct _QmiClientClass {
+ /*< private >*/
+ 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);
+gboolean qmi_client_get_version (QmiClient *self,
+ guint *major,
+ guint *minor);
+gboolean qmi_client_check_version (QmiClient *self,
+ guint major,
+ guint minor);
+
+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/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c
new file mode 100644
index 0000000..2a04d4b
--- /dev/null
+++ b/src/libqmi-glib/qmi-device.c
@@ -0,0 +1,2331 @@
+/* -*- 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-nas.h"
+#include "qmi-wms.h"
+#include "qmi-pds.h"
+#include "qmi-pbm.h"
+#include "qmi-uim.h"
+#include "qmi-oma.h"
+#include "qmi-utils.h"
+#include "qmi-error-types.h"
+#include "qmi-enum-types.h"
+
+/**
+ * SECTION:qmi-device
+ * @title: QmiDevice
+ * @short_description: Generic QMI device handling routines
+ *
+ * #QmiDevice is a generic type in charge of controlling the access of multiple
+ * #QmiClient objects to the managed QMI port.
+ *
+ * A #QmiDevice can only handle one single QMI port.
+ */
+
+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_LAST
+};
+
+static GParamSpec *properties[PROP_LAST];
+
+struct _QmiDevicePrivate {
+ /* File */
+ GFile *file;
+ gchar *path;
+ gchar *path_display;
+
+ /* Implicit CTL client */
+ QmiClientCtl *client_ctl;
+ guint sync_indication_id;
+
+ /* 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 {
+ QmiDevice *self;
+ gpointer key;
+} TransactionWaitContext;
+
+typedef struct {
+ QmiMessage *message;
+ GSimpleAsyncResult *result;
+ guint timeout_id;
+ GCancellable *cancellable;
+ gulong cancellable_id;
+ TransactionWaitContext *wait_ctx;
+} Transaction;
+
+static Transaction *
+transaction_new (QmiDevice *self,
+ QmiMessage *message,
+ GCancellable *cancellable,
+ 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);
+ if (cancellable)
+ tr->cancellable = g_object_ref (cancellable);
+
+ 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 (tr->cancellable) {
+ if (tr->cancellable_id)
+ g_cancellable_disconnect (tr->cancellable, tr->cancellable_id);
+ g_object_unref (tr->cancellable);
+ }
+
+ if (tr->wait_ctx)
+ g_slice_free (TransactionWaitContext, tr->wait_ctx);
+
+ 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);
+
+ 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;
+}
+
+static gboolean
+transaction_timed_out (TransactionWaitContext *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
+transaction_cancelled (GCancellable *cancellable,
+ TransactionWaitContext *ctx)
+{
+ Transaction *tr;
+ GError *error = NULL;
+
+ tr = device_release_transaction (ctx->self, ctx->key);
+ tr->cancellable_id = 0;
+
+ /* Complete transaction with an abort error */
+ error = g_error_new (QMI_PROTOCOL_ERROR,
+ QMI_PROTOCOL_ERROR_ABORTED,
+ "Transaction aborted");
+ transaction_complete_and_free (tr, NULL, error);
+ g_error_free (error);
+}
+
+static gboolean
+device_store_transaction (QmiDevice *self,
+ Transaction *tr,
+ guint timeout,
+ GError **error)
+{
+ 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);
+
+ /* Setup the timeout and cancellation */
+
+ tr->wait_ctx = g_slice_new (TransactionWaitContext);
+ tr->wait_ctx->self = self;
+ tr->wait_ctx->key = key; /* valid as long as the transaction is in the HT */
+
+ tr->timeout_id = g_timeout_add_seconds (timeout,
+ (GSourceFunc)transaction_timed_out,
+ tr->wait_ctx);
+
+ if (tr->cancellable) {
+ tr->cancellable_id = g_cancellable_connect (tr->cancellable,
+ (GCallback)transaction_cancelled,
+ tr->wait_ctx,
+ NULL);
+ if (!tr->cancellable_id) {
+ g_set_error (error,
+ QMI_PROTOCOL_ERROR,
+ QMI_PROTOCOL_ERROR_ABORTED,
+ "Request is already cancelled");
+ return FALSE;
+ }
+ }
+
+ /* Keep in the HT */
+ g_hash_table_insert (self->priv->transactions, key, tr);
+
+ return TRUE;
+}
+
+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));
+}
+
+/*****************************************************************************/
+/* Version info request */
+
+/**
+ * qmi_device_get_service_version_info_finish:
+ * @self: a #QmiDevice.
+ * @res: a #GAsyncResult.
+ * @error: Return location for error or %NULL.
+ *
+ * Finishes an operation started with qmi_device_get_service_version_info().
+ *
+ * Returns: a #GArray of #QmiDeviceServiceVersionInfo elements, or #NULL if @error is set. The returned value should be freed with g_array_unref().
+ */
+GArray *
+qmi_device_get_service_version_info_finish (QmiDevice *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+version_info_ready (QmiClientCtl *client_ctl,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GArray *service_list = NULL;
+ GArray *out;
+ 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) {
+ g_simple_async_result_take_error (simple, error);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ return;
+ }
+
+ /* Check result of the QMI operation */
+ if (!qmi_message_ctl_get_version_info_output_get_result (output, &error)) {
+ qmi_message_ctl_get_version_info_output_unref (output);
+ g_simple_async_result_take_error (simple, error);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ return;
+ }
+
+ /* QMI operation succeeded, we can now get the outputs */
+ qmi_message_ctl_get_version_info_output_get_service_list (output, &service_list, NULL);
+ out = g_array_sized_new (FALSE, FALSE, sizeof (QmiDeviceServiceVersionInfo), service_list->len);
+ for (i = 0; i < service_list->len; i++) {
+ QmiMessageCtlGetVersionInfoOutputServiceListService *info;
+ QmiDeviceServiceVersionInfo outinfo;
+
+ info = &g_array_index (service_list,
+ QmiMessageCtlGetVersionInfoOutputServiceListService,
+ i);
+ outinfo.service = info->service;
+ outinfo.major_version = info->major_version;
+ outinfo.minor_version = info->minor_version;
+ g_array_append_val (out, outinfo);
+ }
+
+ qmi_message_ctl_get_version_info_output_unref (output);
+ g_simple_async_result_set_op_res_gpointer (simple, out, (GDestroyNotify)g_array_unref);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
+/**
+ * qmi_device_get_service_version_info:
+ * @self: a #QmiDevice.
+ * @timeout: maximum time to wait for the method to complete, in seconds.
+ * @cancellable: a #GCancellable or %NULL.
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied.
+ * @user_data: user data to pass to @callback.
+ *
+ * Asynchronously requests the service version information of the device.
+ *
+ * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from.
+ *
+ * You can then call qmi_device_get_service_version_info_finish() to get the result of the operation.
+ */
+void
+qmi_device_get_service_version_info (QmiDevice *self,
+ guint timeout,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ qmi_client_ctl_get_version_info (
+ self->priv->client_ctl,
+ NULL,
+ timeout,
+ cancellable,
+ (GAsyncReadyCallback)version_info_ready,
+ g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ qmi_device_get_service_version_info));
+}
+
+/*****************************************************************************/
+/* Version info checks (private) */
+
+static const QmiMessageCtlGetVersionInfoOutputServiceListService *
+find_service_version_info (QmiDevice *self,
+ QmiService service)
+{
+ guint i;
+
+ if (!self->priv->supported_services)
+ return NULL;
+
+ for (i = 0; i < self->priv->supported_services->len; i++) {
+ const QmiMessageCtlGetVersionInfoOutputServiceListService *info;
+
+ info = &g_array_index (self->priv->supported_services,
+ QmiMessageCtlGetVersionInfoOutputServiceListService,
+ i);
+
+ if (service == info->service)
+ return info;
+ }
+
+ return NULL;
+}
+
+static gboolean
+check_service_supported (QmiDevice *self,
+ QmiService service)
+{
+ /* If we didn't check supported services, just assume it is supported */
+ if (!self->priv->supported_services) {
+ g_debug ("[%s] Assuming service '%s' is supported...",
+ self->priv->path_display,
+ qmi_service_get_string (service));
+ return TRUE;
+ }
+
+ return !!find_service_version_info (self, service);
+}
+
+static gboolean
+check_message_supported (QmiDevice *self,
+ QmiMessage *message,
+ GError **error)
+{
+ const QmiMessageCtlGetVersionInfoOutputServiceListService *info;
+ guint major = 0;
+ guint minor = 0;
+
+ /* If we didn't check supported services, just assume it is supported */
+ if (!self->priv->supported_services)
+ return TRUE;
+
+ /* For CTL, we assume all are supported */
+ if (qmi_message_get_service (message) == QMI_SERVICE_CTL)
+ return TRUE;
+
+ /* If we cannot get in which version this message was introduced, we'll just
+ * assume it's supported */
+ if (!qmi_message_get_version_introduced (message, &major, &minor))
+ return TRUE;
+
+ /* Get version info. It MUST exist because we allowed creating a client
+ * of this service type */
+ info = find_service_version_info (self, qmi_message_get_service (message));
+ g_assert (info != NULL);
+ g_assert (info->service == qmi_message_get_service (message));
+
+ /* If the version of the message is greater than the version of the service,
+ * report unsupported */
+ if (major > info->major_version ||
+ (major == info->major_version &&
+ minor > info->minor_version)) {
+ g_set_error (error,
+ QMI_CORE_ERROR,
+ QMI_CORE_ERROR_UNSUPPORTED,
+ "QMI service '%s' version '%u.%u' required, got version '%u.%u'",
+ qmi_service_get_string (qmi_message_get_service (message)),
+ major, minor,
+ info->major_version,
+ info->minor_version);
+ return FALSE;
+ }
+
+ /* Supported! */
+ return TRUE;
+}
+
+/*****************************************************************************/
+
+/**
+ * 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: Return location for error or %NULL.
+ *
+ * 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)
+{
+ gchar *version_string = NULL;
+ QmiClient *client;
+ GError *error = NULL;
+ const QmiMessageCtlGetVersionInfoOutputServiceListService *version_info;
+
+ /* 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);
+
+ /* Add version info to the client if it was retrieved */
+ version_info = find_service_version_info (ctx->self, ctx->service);
+ if (version_info)
+ g_object_set (client,
+ QMI_CLIENT_VERSION_MAJOR, version_info->major_version,
+ QMI_CLIENT_VERSION_MINOR, version_info->minor_version,
+ 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;
+ }
+
+ /* Build version string for the logging */
+ if (ctx->self->priv->supported_services) {
+ const QmiMessageCtlGetVersionInfoOutputServiceListService *info;
+
+ info = find_service_version_info (ctx->self, ctx->service);
+ if (info)
+ version_string = g_strdup_printf ("%u.%u", info->major_version, info->minor_version);
+ }
+
+ g_debug ("[%s] Registered '%s' (version %s) client with ID '%u'",
+ ctx->self->priv->path_display,
+ qmi_service_get_string (ctx->service),
+ version_string ? version_string : "unknown",
+ ctx->cid);
+
+ g_free (version_string);
+
+ /* 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);
+}
+
+/**
+ * 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;
+
+ case QMI_SERVICE_NAS:
+ ctx->client_type = QMI_TYPE_CLIENT_NAS;
+ break;
+
+ case QMI_SERVICE_WMS:
+ ctx->client_type = QMI_TYPE_CLIENT_WMS;
+ break;
+
+ case QMI_SERVICE_PDS:
+ ctx->client_type = QMI_TYPE_CLIENT_PDS;
+ break;
+
+ case QMI_SERVICE_PBM:
+ ctx->client_type = QMI_TYPE_CLIENT_PBM;
+ break;
+
+ case QMI_SERVICE_UIM:
+ ctx->client_type = QMI_TYPE_CLIENT_UIM;
+ break;
+
+ case QMI_SERVICE_OMA:
+ ctx->client_type = QMI_TYPE_CLIENT_OMA;
+ 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 ("[%s] Allocating new client ID...",
+ ctx->self->priv->path_display);
+ 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 ("[%s] Reusing client CID '%u'...",
+ ctx->self->priv->path_display,
+ 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: Return location for error or %NULL.
+ *
+ * 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 ("[%s] Unregistered '%s' client with ID '%u'",
+ self->priv->path_display,
+ 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;
+}
+
+/*****************************************************************************/
+/* Set instance ID */
+
+/**
+ * qmi_device_set_instance_id_finish:
+ * @self: a #QmiDevice.
+ * @res: a #GAsyncResult.
+ * @link_id: a placeholder for the output #guint16, or #NULL if not required.
+ * @error: Return location for error or %NULL.
+ *
+ * Finishes an operation started with qmi_device_set_instance_id().
+ *
+ * Returns: %TRUE if successful, %FALSE if @error is set.
+ */
+gboolean
+qmi_device_set_instance_id_finish (QmiDevice *self,
+ GAsyncResult *res,
+ guint16 *link_id,
+ GError **error)
+{
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ return FALSE;
+
+ if (link_id)
+ *link_id = ((guint16) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))));
+ return TRUE;
+}
+
+static void
+set_instance_id_ready (QmiClientCtl *client_ctl,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ QmiMessageCtlSetInstanceIdOutput *output;
+ GError *error = NULL;
+
+ /* Check result of the async operation */
+ output = qmi_client_ctl_set_instance_id_finish (client_ctl, res, &error);
+ if (!output)
+ g_simple_async_result_take_error (simple, error);
+ else {
+ /* Check result of the QMI operation */
+ if (!qmi_message_ctl_set_instance_id_output_get_result (output, &error))
+ g_simple_async_result_take_error (simple, error);
+ else {
+ guint16 link_id;
+
+ qmi_message_ctl_set_instance_id_output_get_link_id (output, &link_id, NULL);
+ g_simple_async_result_set_op_res_gpointer (simple, GUINT_TO_POINTER ((guint)link_id), NULL);
+ }
+ qmi_message_ctl_set_instance_id_output_unref (output);
+ }
+
+ g_simple_async_result_complete (simple);
+}
+
+/**
+ * qmi_device_set_instance_id:
+ * @self: a #QmiDevice.
+ * @instance_id: the instance ID.
+ * @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.
+ *
+ * Sets the instance ID of the #QmiDevice.
+ *
+ * When the operation is finished @callback will be called. You can then call
+ * qmi_device_set_instance_id_finish() to get the result of the operation.
+ */
+void
+qmi_device_set_instance_id (QmiDevice *self,
+ guint8 instance_id,
+ guint timeout,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+ QmiMessageCtlSetInstanceIdInput *input;
+
+
+ result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ qmi_device_set_instance_id);
+
+ input = qmi_message_ctl_set_instance_id_input_new ();
+ qmi_message_ctl_set_instance_id_input_set_id (
+ input,
+ instance_id,
+ NULL);
+ qmi_client_ctl_set_instance_id (self->priv->client_ctl,
+ input,
+ timeout,
+ cancellable,
+ (GAsyncReadyCallback)set_instance_id_ready,
+ result);
+ qmi_message_ctl_set_instance_id_input_unref (input);
+}
+
+/*****************************************************************************/
+/* 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)
+{
+ if (qmi_utils_get_traces_enabled ()) {
+ gchar *printable;
+
+ printable = __qmi_utils_str_hex (((GByteArray *)message)->data,
+ ((GByteArray *)message)->len,
+ ':');
+ g_debug ("[%s] Received message...\n"
+ ">>>>>> RAW:\n"
+ ">>>>>> length = %u\n"
+ ">>>>>> data = %s\n",
+ self->priv->path_display,
+ ((GByteArray *)message)->len,
+ printable);
+ g_free (printable);
+
+ printable = qmi_message_get_printable (message, ">>>>>> ");
+ g_debug ("[%s] Received message (translated)...\n%s",
+ self->priv->path_display,
+ printable);
+ g_free (printable);
+ }
+
+ 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 {
+ GError *error = NULL;
+ 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 ("[%s] QMI framing error detected",
+ self->priv->path_display);
+ return;
+ }
+
+ message = qmi_message_new_from_raw (self->priv->response, &error);
+ if (!message) {
+ if (!error)
+ /* More data we need */
+ return;
+
+ /* Warn about the issue */
+ g_warning ("[%s] Invalid QMI message received: '%s'",
+ self->priv->path_display,
+ error->message);
+ g_error_free (error);
+ } else {
+ /* 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 ("[%s] error reading from the IOChannel: '%s'",
+ self->priv->path_display,
+ 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;
+ gint 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: Return location for error or %NULL.
+ *
+ * Finishes an asynchronous open operation started with qmi_device_open().
+ *
+ * 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
+ctl_set_data_format_ready (QmiClientCtl *client,
+ GAsyncResult *res,
+ DeviceOpenContext *ctx)
+{
+ QmiMessageCtlSetDataFormatOutput *output = NULL;
+ GError *error = NULL;
+
+ output = qmi_client_ctl_set_data_format_finish (client, res, &error);
+ /* Check result of the async operation */
+ 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_set_data_format_output_get_result (output, &error)) {
+ g_simple_async_result_take_error (ctx->result, error);
+ device_open_context_complete_and_free (ctx);
+ qmi_message_ctl_set_data_format_output_unref (output);
+ return;
+ }
+
+ g_debug ("[%s] Network port data format operation finished",
+ ctx->self->priv->path_display);
+
+ /* Keep on with next flags */
+ process_open_flags (ctx);
+ qmi_message_ctl_set_data_format_output_unref (output);
+}
+
+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
+open_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) {
+ g_error_free (error);
+ qmi_client_ctl_get_version_info (ctx->self->priv->client_ctl,
+ NULL,
+ 1,
+ ctx->cancellable,
+ (GAsyncReadyCallback)open_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;
+ const gchar *service_str;
+
+ info = &g_array_index (ctx->self->priv->supported_services,
+ QmiMessageCtlGetVersionInfoOutputServiceListService,
+ i);
+ service_str = qmi_service_get_string (info->service);
+ if (service_str)
+ g_debug ("[%s] %s (%u.%u)",
+ ctx->self->priv->path_display,
+ service_str,
+ info->major_version,
+ info->minor_version);
+ else
+ g_debug ("[%s] unknown [0x%02x] (%u.%u)",
+ ctx->self->priv->path_display,
+ 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);
+}
+
+#define NETPORT_FLAGS (QMI_DEVICE_OPEN_FLAGS_NET_802_3 | \
+ QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP | \
+ QMI_DEVICE_OPEN_FLAGS_NET_QOS_HEADER | \
+ QMI_DEVICE_OPEN_FLAGS_NET_NO_QOS_HEADER)
+
+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 ("[%s] Checking version info (%u retries)...",
+ ctx->self->priv->path_display,
+ ctx->version_check_retries);
+ qmi_client_ctl_get_version_info (ctx->self->priv->client_ctl,
+ NULL,
+ 1,
+ ctx->cancellable,
+ (GAsyncReadyCallback)open_version_info_ready,
+ ctx);
+ return;
+ }
+
+ /* Sync? */
+ if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_SYNC) {
+ g_debug ("[%s] Running sync...",
+ ctx->self->priv->path_display);
+ 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;
+ }
+
+ /* Network port setup */
+ if (ctx->flags & NETPORT_FLAGS) {
+ QmiMessageCtlSetDataFormatInput *input;
+ QmiCtlDataFormat qos = QMI_CTL_DATA_FORMAT_QOS_FLOW_HEADER_ABSENT;
+ QmiCtlDataLinkProtocol link_protocol = QMI_CTL_DATA_LINK_PROTOCOL_802_3;
+
+ g_debug ("[%s] Setting network port data format...",
+ ctx->self->priv->path_display);
+
+ input = qmi_message_ctl_set_data_format_input_new ();
+
+ if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_NET_QOS_HEADER)
+ qos = QMI_CTL_DATA_FORMAT_QOS_FLOW_HEADER_PRESENT;
+ qmi_message_ctl_set_data_format_input_set_format (input, qos, NULL);
+
+ if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP)
+ link_protocol = QMI_CTL_DATA_LINK_PROTOCOL_RAW_IP;
+ qmi_message_ctl_set_data_format_input_set_protocol (input, link_protocol, NULL);
+
+ ctx->flags &= ~NETPORT_FLAGS;
+ qmi_client_ctl_set_data_format (ctx->self->priv->client_ctl,
+ input,
+ 5,
+ NULL,
+ (GAsyncReadyCallback)ctl_set_data_format_ready,
+ ctx);
+ qmi_message_ctl_set_data_format_input_unref (input);
+ 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;
+
+ /* Raw IP and 802.3 are mutually exclusive */
+ g_return_if_fail (!((flags & QMI_DEVICE_OPEN_FLAGS_NET_802_3) &&
+ (flags & QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP)));
+ /* QoS and no QoS are mutually exclusive */
+ g_return_if_fail (!((flags & QMI_DEVICE_OPEN_FLAGS_NET_QOS_HEADER) &&
+ (flags & QMI_DEVICE_OPEN_FLAGS_NET_NO_QOS_HEADER)));
+ /* At least one of both link protocol and QoS must be specified */
+ if (flags & (QMI_DEVICE_OPEN_FLAGS_NET_802_3 | QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP))
+ g_return_if_fail (flags & (QMI_DEVICE_OPEN_FLAGS_NET_QOS_HEADER | QMI_DEVICE_OPEN_FLAGS_NET_NO_QOS_HEADER));
+ if (flags & (QMI_DEVICE_OPEN_FLAGS_NET_QOS_HEADER | QMI_DEVICE_OPEN_FLAGS_NET_NO_QOS_HEADER))
+ g_return_if_fail (flags & (QMI_DEVICE_OPEN_FLAGS_NET_802_3 | QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP));
+
+ 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: Return location for error or %NULL.
+ *
+ * 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 */
+
+/**
+ * qmi_device_command_finish:
+ * @self: a #QmiDevice.
+ * @res: a #GAsyncResult.
+ * @error: Return location for error or %NULL.
+ *
+ * Finishes an operation started with qmi_device_command().
+ *
+ * Returns: a #QmiMessage response, or #NULL if @error is set. The returned value should be freed with qmi_message_unref().
+ */
+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)));
+}
+
+/**
+ * qmi_device_command:
+ * @self: a #QmiDevice.
+ * @message: the message to send.
+ * @timeout: maximum time, in seconds, to wait for the response.
+ * @cancellable: a #GCancellable, or %NULL.
+ * @callback: a #GAsyncReadyCallback to call when the operation is finished.
+ * @user_data: the data to pass to callback function.
+ *
+ * Asynchronously sends a #QmiMessage to the device.
+ *
+ * When the operation is finished @callback will be called. You can then call
+ * qmi_device_command_finish() to get the result of the operation.
+ */
+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, cancellable, 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;
+ }
+
+ /* Check if the message to be sent is supported by the device
+ * (only applicable if we did version info check when opening) */
+ if (!check_message_supported (self, message, &error)) {
+ g_prefix_error (&error, "Cannot send message: ");
+ transaction_complete_and_free (tr, NULL, error);
+ g_error_free (error);
+ return;
+ }
+
+ /* 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 */
+ if (!device_store_transaction (self, tr, timeout, &error)) {
+ g_prefix_error (&error, "Cannot store transaction: ");
+ transaction_complete_and_free (tr, NULL, error);
+ g_error_free (error);
+ return;
+ }
+
+ if (qmi_utils_get_traces_enabled ()) {
+ gchar *printable;
+
+ printable = __qmi_utils_str_hex (((GByteArray *)message)->data,
+ ((GByteArray *)message)->len,
+ ':');
+ g_debug ("[%s] Sent message...\n"
+ "<<<<<< RAW:\n"
+ "<<<<<< length = %u\n"
+ "<<<<<< data = %s\n",
+ self->priv->path_display,
+ ((GByteArray *)message)->len,
+ printable);
+ g_free (printable);
+
+ printable = qmi_message_get_printable (message, "<<<<<< ");
+ g_debug ("[%s] Sent message (translated)...\n%s",
+ self->priv->path_display,
+ printable);
+ g_free (printable);
+ }
+
+ 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: Return location for error or %NULL.
+ *
+ * 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
+sync_indication_cb (QmiClientCtl *client_ctl,
+ QmiDevice *self)
+{
+ /* Just log about it */
+ g_debug ("[%s] Sync indication received",
+ self->priv->path_display);
+}
+
+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);
+
+ /* Connect to 'Sync' indications */
+ ctx->self->priv->sync_indication_id =
+ g_signal_connect (ctx->self->priv->client_ctl,
+ "sync",
+ G_CALLBACK (sync_indication_cb),
+ ctx->self);
+
+ /* 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;
+ 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;
+ 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 ("[%s] QMI client for service '%s' with CID '%u' wasn't released",
+ self->priv->path_display,
+ 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 */
+ if (self->priv->client_ctl)
+ 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);
+
+ if (self->priv->sync_indication_id &&
+ self->priv->client_ctl) {
+ g_signal_handler_disconnect (self->priv->client_ctl,
+ self->priv->sync_indication_id);
+ self->priv->sync_indication_id = 0;
+ }
+ 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->watch_id)
+ g_source_remove (self->priv->watch_id);
+ 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]);
+}
diff --git a/src/libqmi-glib/qmi-device.h b/src/libqmi-glib/qmi-device.h
new file mode 100644
index 0000000..2912552
--- /dev/null
+++ b/src/libqmi-glib/qmi-device.h
@@ -0,0 +1,199 @@
+/* -*- 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_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+#include <gio/gio.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"
+
+/**
+ * QmiDevice:
+ *
+ * The #QmiDevice structure contains private data and should only be accessed
+ * using the provided API.
+ */
+struct _QmiDevice {
+ /*< private >*/
+ GObject parent;
+ QmiDevicePrivate *priv;
+};
+
+struct _QmiDeviceClass {
+ /*< private >*/
+ 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.
+ * @QMI_DEVICE_OPEN_FLAGS_NET_802_3: set network port to "802.3" mode; mutually exclusive with @QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP
+ * @QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP: set network port to "raw IP" mode; mutally exclusive with @QMI_DEVICE_OPEN_FLAGS_NET_802_3
+ * @QMI_DEVICE_OPEN_FLAGS_NET_QOS_HEADER: set network port to transmit/receive QoS headers; mutually exclusive with @QMI_DEVICE_OPEN_FLAGS_NET_NO_QOS_HEADER
+ * @QMI_DEVICE_OPEN_FLAGS_NET_NO_QOS_HEADER: set network port to not transmit/receive QoS headers; mutually exclusive with @QMI_DEVICE_OPEN_FLAGS_NET_QOS_HEADER
+ *
+ * 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,
+ QMI_DEVICE_OPEN_FLAGS_NET_802_3 = 1 << 2,
+ QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP = 1 << 3,
+ QMI_DEVICE_OPEN_FLAGS_NET_QOS_HEADER = 1 << 4,
+ QMI_DEVICE_OPEN_FLAGS_NET_NO_QOS_HEADER = 1 << 5
+} 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_set_instance_id (QmiDevice *self,
+ guint8 instance_id,
+ guint timeout,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean qmi_device_set_instance_id_finish (QmiDevice *self,
+ GAsyncResult *res,
+ guint16 *link_id,
+ 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);
+
+/**
+ * QmiDeviceServiceVersionInfo:
+ * @service: a #QmiService.
+ * @major_version: major version of the service.
+ * @minor_version: minor version of the service.
+ *
+ * Version information for a service.
+ */
+typedef struct {
+ QmiService service;
+ guint16 major_version;
+ guint16 minor_version;
+} QmiDeviceServiceVersionInfo;
+
+void qmi_device_get_service_version_info (QmiDevice *self,
+ guint timeout,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GArray *qmi_device_get_service_version_info_finish (QmiDevice *self,
+ GAsyncResult *res,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* _LIBQMI_GLIB_QMI_DEVICE_H_ */
diff --git a/src/libqmi-glib/qmi-enums-dms.h b/src/libqmi-glib/qmi-enums-dms.h
new file mode 100644
index 0000000..3476c4d
--- /dev/null
+++ b/src/libqmi-glib/qmi-enums-dms.h
@@ -0,0 +1,341 @@
+/* -*- 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_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+/**
+ * SECTION: qmi-enums-dms
+ * @title: DMS enumerations and flags
+ *
+ * This section defines enumerations and flags used in the DMS service
+ * interface.
+ */
+
+/*****************************************************************************/
+/* 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 */
+
+/**
+ * QmiDmsUimPinStatus:
+ * @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_RESET: 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.
+ * @QMI_DMS_OPERATING_MODE_UNKNOWN: Unknown.
+ *
+ * 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_RESET = 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,
+ QMI_DMS_OPERATING_MODE_UNKNOWN = 0xFF
+} 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;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI DMS Get Time' message */
+
+/**
+ * QmiDmsTimeSource:
+ * @QMI_DMS_TIME_SOURCE_DEVICE: 32 kHz device clock.
+ * @QMI_DMS_TIME_SOURCE_CDMA_NETWORK: CDMA network.
+ * @QMI_DMS_TIME_SOURCE_HDR_NETWORK: HDR network.
+ *
+ * Source of the timestamp.
+ */
+typedef enum {
+ QMI_DMS_TIME_SOURCE_DEVICE = 0,
+ QMI_DMS_TIME_SOURCE_CDMA_NETWORK = 1,
+ QMI_DMS_TIME_SOURCE_HDR_NETWORK = 2,
+} QmiDmsTimeSource;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI DMS Get Activation State' message */
+
+/**
+ * QmiDmsActivationState:
+ * @QMI_DMS_ACTIVATION_STATE_NOT_ACTIVATED: Service not activated.
+ * @QMI_DMS_ACTIVATION_STATE_ACTIVATED: Service is activated.
+ * @QMI_DMS_ACTIVATION_STATE_CONNECTING: Connection in progress for automatic activation.
+ * @QMI_DMS_ACTIVATION_STATE_CONNECTED: Connection connected for automatic activation.
+ * @QMI_DMS_ACTIVATION_STATE_OTASP_AUTHENTICATED: OTASP security authenticated.
+ * @QMI_DMS_ACTIVATION_STATE_OTASP_NAM: OTASP NAM downloaded.
+ * @QMI_DMS_ACTIVATION_STATE_OTASP_MDN: OTASP MDN downloaded.
+ * @QMI_DMS_ACTIVATION_STATE_OTASP_IMSI: OTASP IMSI downloaded.
+ * @QMI_DMS_ACTIVATION_STATE_OTASP_PRL: OTASP PRL downloaded.
+ * @QMI_DMS_ACTIVATION_STATE_OTASP_SPC: OTASP SPC downloaded.
+ * @QMI_DMS_ACTIVATION_STATE_OTASP_COMMITED: OTASP settings committed.
+ *
+ * State of the service activation.
+ */
+typedef enum {
+ QMI_DMS_ACTIVATION_STATE_NOT_ACTIVATED = 0x00,
+ QMI_DMS_ACTIVATION_STATE_ACTIVATED = 0x01,
+ QMI_DMS_ACTIVATION_STATE_CONNECTING = 0x02,
+ QMI_DMS_ACTIVATION_STATE_CONNECTED = 0x03,
+ QMI_DMS_ACTIVATION_STATE_OTASP_AUTHENTICATED = 0x04,
+ QMI_DMS_ACTIVATION_STATE_OTASP_NAM = 0x05,
+ QMI_DMS_ACTIVATION_STATE_OTASP_MDN = 0x06,
+ QMI_DMS_ACTIVATION_STATE_OTASP_IMSI = 0x07,
+ QMI_DMS_ACTIVATION_STATE_OTASP_PRL = 0x08,
+ QMI_DMS_ACTIVATION_STATE_OTASP_SPC = 0x09,
+ QMI_DMS_ACTIVATION_STATE_OTASP_COMMITED = 0x0A
+} QmiDmsActivationState;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI DMS UIM Get CK Status' message */
+
+/**
+ * QmiDmsUimFacility:
+ * @QMI_DMS_UIM_FACILITY_PN: Network personalization facility.
+ * @QMI_DMS_UIM_FACILITY_PU: Network subset personalization facility.
+ * @QMI_DMS_UIM_FACILITY_PP: Service provider facility.
+ * @QMI_DMS_UIM_FACILITY_PC: Corporate personalization facility.
+ * @QMI_DMS_UIM_FACILITY_PF: UIM personalization facility.
+ *
+ * UIM personalization facilities.
+ */
+typedef enum {
+ QMI_DMS_UIM_FACILITY_PN = 0,
+ QMI_DMS_UIM_FACILITY_PU = 1,
+ QMI_DMS_UIM_FACILITY_PP = 2,
+ QMI_DMS_UIM_FACILITY_PC = 3,
+ QMI_DMS_UIM_FACILITY_PF = 4
+} QmiDmsUimFacility;
+
+/**
+ * QmiDmsUimFacilityState:
+ * @QMI_DMS_UIM_FACILITY_STATE_DEACTIVATED: Facility is deactivated.
+ * @QMI_DMS_UIM_FACILITY_STATE_ACTIVATED: Facility is activated.
+ * @QMI_DMS_UIM_FACILITY_STATE_BLOCKED: Facility is blocked.
+ */
+typedef enum {
+ QMI_DMS_UIM_FACILITY_STATE_DEACTIVATED = 0,
+ QMI_DMS_UIM_FACILITY_STATE_ACTIVATED = 1,
+ QMI_DMS_UIM_FACILITY_STATE_BLOCKED = 2
+} QmiDmsUimFacilityState;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI DMS UIM Get State' message */
+
+/**
+ * QmiDmsUimState:
+ * @QMI_DMS_UIM_STATE_INITIALIZATION_COMPLETED: UIM initialization completed.
+ * @QMI_DMS_UIM_STATE_LOCKED_OR_FAILED: UIM is locked or failed.
+ * @QMI_DMS_UIM_STATE_NOT_PRESENT: No UIM in the device.
+ * @QMI_DMS_UIM_STATE_RESERVED: Reserved, unknown.
+ * @QMI_DMS_UIM_STATE_UNKNOWN: UIM state currently unavailable.
+ *
+ * State of the UIM.
+ */
+typedef enum {
+ QMI_DMS_UIM_STATE_INITIALIZATION_COMPLETED = 0x00,
+ QMI_DMS_UIM_STATE_LOCKED_OR_FAILED = 0x01,
+ QMI_DMS_UIM_STATE_NOT_PRESENT = 0x02,
+ QMI_DMS_UIM_STATE_RESERVED = 0x03,
+ QMI_DMS_UIM_STATE_UNKNOWN = 0xFF
+} QmiDmsUimState;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI DMS Set Time' message */
+
+/**
+ * QmiDmsTimeReferenceType:
+ * @QMI_DMS_TIME_REFERENCE_TYPE_USER: User time.
+ *
+ * Time reference type.
+ */
+typedef enum {
+ QMI_DMS_TIME_REFERENCE_TYPE_USER = 0
+} QmiDmsTimeReferenceType;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI DMS Get Firmware Preference' message */
+
+/**
+ * QmiDmsFirmwareImageType:
+ * @QMI_DMS_FIRMWARE_IMAGE_TYPE_MODEM: Modem image.
+ * @QMI_DMS_FIRMWARE_IMAGE_TYPE_PRI: PRI image.
+ *
+ * Type of firmware image.
+ */
+typedef enum {
+ QMI_DMS_FIRMWARE_IMAGE_TYPE_MODEM = 0,
+ QMI_DMS_FIRMWARE_IMAGE_TYPE_PRI = 1
+} QmiDmsFirmwareImageType;
+
+#endif /* _LIBQMI_GLIB_QMI_ENUMS_DMS_H_ */
diff --git a/src/libqmi-glib/qmi-enums-nas.h b/src/libqmi-glib/qmi-enums-nas.h
new file mode 100644
index 0000000..0b333d1
--- /dev/null
+++ b/src/libqmi-glib/qmi-enums-nas.h
@@ -0,0 +1,875 @@
+/* -*- 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 Google Inc.
+ */
+
+#ifndef _LIBQMI_GLIB_QMI_ENUMS_NAS_H_
+#define _LIBQMI_GLIB_QMI_ENUMS_NAS_H_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+/**
+ * SECTION: qmi-enums-nas
+ * @title: NAS enumerations and flags
+ *
+ * This section defines enumerations and flags used in the NAS service
+ * interface.
+ */
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI NAS Event Report' indication */
+
+/**
+ * QmiNasRadioInterface:
+ * @QMI_NAS_RADIO_INTERFACE_UNKNOWN: Not known or not needed.
+ * @QMI_NAS_RADIO_INTERFACE_NONE: None, no service.
+ * @QMI_NAS_RADIO_INTERFACE_CDMA_1X: CDMA2000 1X.
+ * @QMI_NAS_RADIO_INTERFACE_CDMA_1XEVDO: CDMA2000 HRPD (1xEV-DO).
+ * @QMI_NAS_RADIO_INTERFACE_AMPS: AMPS.
+ * @QMI_NAS_RADIO_INTERFACE_GSM: GSM.
+ * @QMI_NAS_RADIO_INTERFACE_UMTS: UMTS.
+ * @QMI_NAS_RADIO_INTERFACE_LTE: LTE.
+ * @QMI_NAS_RADIO_INTERFACE_TD_SCDMA: TD-SCDMA.
+ *
+ * Radio interface technology.
+ */
+typedef enum {
+ QMI_NAS_RADIO_INTERFACE_UNKNOWN = -1,
+ QMI_NAS_RADIO_INTERFACE_NONE = 0x00,
+ QMI_NAS_RADIO_INTERFACE_CDMA_1X = 0x01,
+ QMI_NAS_RADIO_INTERFACE_CDMA_1XEVDO = 0x02,
+ QMI_NAS_RADIO_INTERFACE_AMPS = 0x03,
+ QMI_NAS_RADIO_INTERFACE_GSM = 0x04,
+ QMI_NAS_RADIO_INTERFACE_UMTS = 0x05,
+ QMI_NAS_RADIO_INTERFACE_LTE = 0x08,
+ QMI_NAS_RADIO_INTERFACE_TD_SCDMA = 0x09
+} QmiNasRadioInterface;
+
+/**
+ * QmiNasActiveBand:
+ * @QMI_NAS_ACTIVE_BAND_BC_0: Band class 0.
+ * @QMI_NAS_ACTIVE_BAND_BC_1: Band class 1.
+ * @QMI_NAS_ACTIVE_BAND_BC_2: Band class 2.
+ * @QMI_NAS_ACTIVE_BAND_BC_3: Band class 3.
+ * @QMI_NAS_ACTIVE_BAND_BC_4: Band class 4.
+ * @QMI_NAS_ACTIVE_BAND_BC_5: Band class 5.
+ * @QMI_NAS_ACTIVE_BAND_BC_6: Band class 6.
+ * @QMI_NAS_ACTIVE_BAND_BC_7: Band class 7.
+ * @QMI_NAS_ACTIVE_BAND_BC_8: Band class 8.
+ * @QMI_NAS_ACTIVE_BAND_BC_9: Band class 9.
+ * @QMI_NAS_ACTIVE_BAND_BC_10: Band class 10.
+ * @QMI_NAS_ACTIVE_BAND_BC_11: Band class 11.
+ * @QMI_NAS_ACTIVE_BAND_BC_12: Band class 12.
+ * @QMI_NAS_ACTIVE_BAND_BC_13: Band class 13.
+ * @QMI_NAS_ACTIVE_BAND_BC_14: Band class 14.
+ * @QMI_NAS_ACTIVE_BAND_BC_15: Band class 15.
+ * @QMI_NAS_ACTIVE_BAND_BC_16: Band class 16.
+ * @QMI_NAS_ACTIVE_BAND_BC_17: Band class 17.
+ * @QMI_NAS_ACTIVE_BAND_BC_18: Band class 18.
+ * @QMI_NAS_ACTIVE_BAND_BC_19: Band class 19.
+ * @QMI_NAS_ACTIVE_BAND_GSM_450: GSM 450.
+ * @QMI_NAS_ACTIVE_BAND_GSM_480: GSM 480.
+ * @QMI_NAS_ACTIVE_BAND_GSM_750: GSM 750.
+ * @QMI_NAS_ACTIVE_BAND_GSM_850: GSM 850.
+ * @QMI_NAS_ACTIVE_BAND_GSM_900_EXTENDED: GSM 900 (Extended).
+ * @QMI_NAS_ACTIVE_BAND_GSM_900_PRIMARY: GSM 900 (Primary).
+ * @QMI_NAS_ACTIVE_BAND_GSM_900_RAILWAYS: GSM 900 (Railways).
+ * @QMI_NAS_ACTIVE_BAND_GSM_DCS_1800: GSM 1800.
+ * @QMI_NAS_ACTIVE_BAND_GSM_PCS_1900: GSM 1900.
+ * @QMI_NAS_ACTIVE_BAND_WCDMA_2100: WCDMA 2100.
+ * @QMI_NAS_ACTIVE_BAND_WCDMA_PCS_1900: WCDMA PCS 1900.
+ * @QMI_NAS_ACTIVE_BAND_WCDMA_DCS_1800: WCDMA DCS 1800.
+ * @QMI_NAS_ACTIVE_BAND_WCDMA_1700_US: WCDMA 1700 (U.S.).
+ * @QMI_NAS_ACTIVE_BAND_WCDMA_850: WCDMA 850.
+ * @QMI_NAS_ACTIVE_BAND_WCDMA_800: WCDMA 800.
+ * @QMI_NAS_ACTIVE_BAND_WCDMA_2600: WCDMA 2600.
+ * @QMI_NAS_ACTIVE_BAND_WCDMA_900: WCDMA 900.
+ * @QMI_NAS_ACTIVE_BAND_WCDMA_1700_JAPAN: WCDMA 1700 (Japan).
+ * @QMI_NAS_ACTIVE_BAND_WCDMA_1500_JAPAN: WCDMA 1500 (Japan).
+ * @QMI_NAS_ACTIVE_BAND_WCDMA_850_JAPAN: WCDMA 850 (Japan).
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_1: EUTRAN band 1.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_2: EUTRAN band 2.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_3: EUTRAN band 3.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_4: EUTRAN band 4.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_5: EUTRAN band 5.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_6: EUTRAN band 6.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_7: EUTRAN band 7.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_8: EUTRAN band 8.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_9: EUTRAN band 9.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_10: EUTRAN band 10.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_11: EUTRAN band 11.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_12: EUTRAN band 12.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_13: EUTRAN band 13.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_14: EUTRAN band 14.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_17: EUTRAN band 17.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_18: EUTRAN band 18.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_19: EUTRAN band 19.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_20: EUTRAN band 20.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_21: EUTRAN band 21.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_24: EUTRAN band 24.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_25: EUTRAN band 25.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_33: EUTRAN band 33.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_34: EUTRAN band 34.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_35: EUTRAN band 35.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_36: EUTRAN band 36.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_37: EUTRAN band 37.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_38: EUTRAN band 38.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_39: EUTRAN band 39.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_40: EUTRAN band 40.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_41: EUTRAN band 41.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_42: EUTRAN band 42.
+ * @QMI_NAS_ACTIVE_BAND_EUTRAN_43: EUTRAN band 43.
+ * @QMI_NAS_ACTIVE_BAND_TDSCDMA_A: TD-SCDMA Band A.
+ * @QMI_NAS_ACTIVE_BAND_TDSCDMA_B: TD-SCDMA Band B.
+ * @QMI_NAS_ACTIVE_BAND_TDSCDMA_C: TD-SCDMA Band C.
+ * @QMI_NAS_ACTIVE_BAND_TDSCDMA_D: TD-SCDMA Band D.
+ * @QMI_NAS_ACTIVE_BAND_TDSCDMA_E: TD-SCDMA Band E.
+ * @QMI_NAS_ACTIVE_BAND_TDSCDMA_F: TD-SCDMA Band F.
+ *
+ * Band classes.
+ */
+typedef enum {
+ QMI_NAS_ACTIVE_BAND_BC_0 = 0,
+ QMI_NAS_ACTIVE_BAND_BC_1 = 1,
+ QMI_NAS_ACTIVE_BAND_BC_2 = 2,
+ QMI_NAS_ACTIVE_BAND_BC_3 = 3,
+ QMI_NAS_ACTIVE_BAND_BC_4 = 4,
+ QMI_NAS_ACTIVE_BAND_BC_5 = 5,
+ QMI_NAS_ACTIVE_BAND_BC_6 = 6,
+ QMI_NAS_ACTIVE_BAND_BC_7 = 7,
+ QMI_NAS_ACTIVE_BAND_BC_8 = 8,
+ QMI_NAS_ACTIVE_BAND_BC_9 = 9,
+ QMI_NAS_ACTIVE_BAND_BC_10 = 10,
+ QMI_NAS_ACTIVE_BAND_BC_11 = 11,
+ QMI_NAS_ACTIVE_BAND_BC_12 = 12,
+ QMI_NAS_ACTIVE_BAND_BC_13 = 13,
+ QMI_NAS_ACTIVE_BAND_BC_14 = 14,
+ QMI_NAS_ACTIVE_BAND_BC_15 = 15,
+ QMI_NAS_ACTIVE_BAND_BC_16 = 16,
+ QMI_NAS_ACTIVE_BAND_BC_17 = 17,
+ QMI_NAS_ACTIVE_BAND_BC_18 = 18,
+ QMI_NAS_ACTIVE_BAND_BC_19 = 19,
+ QMI_NAS_ACTIVE_BAND_GSM_450 = 40,
+ QMI_NAS_ACTIVE_BAND_GSM_480 = 41,
+ QMI_NAS_ACTIVE_BAND_GSM_750 = 42,
+ QMI_NAS_ACTIVE_BAND_GSM_850 = 43,
+ QMI_NAS_ACTIVE_BAND_GSM_900_EXTENDED = 44,
+ QMI_NAS_ACTIVE_BAND_GSM_900_PRIMARY = 45,
+ QMI_NAS_ACTIVE_BAND_GSM_900_RAILWAYS = 46,
+ QMI_NAS_ACTIVE_BAND_GSM_DCS_1800 = 47,
+ QMI_NAS_ACTIVE_BAND_GSM_PCS_1900 = 48,
+ QMI_NAS_ACTIVE_BAND_WCDMA_2100 = 80,
+ QMI_NAS_ACTIVE_BAND_WCDMA_PCS_1900 = 81,
+ QMI_NAS_ACTIVE_BAND_WCDMA_DCS_1800 = 82,
+ QMI_NAS_ACTIVE_BAND_WCDMA_1700_US = 83,
+ QMI_NAS_ACTIVE_BAND_WCDMA_850 = 84,
+ QMI_NAS_ACTIVE_BAND_WCDMA_800 = 85,
+ QMI_NAS_ACTIVE_BAND_WCDMA_2600 = 86,
+ QMI_NAS_ACTIVE_BAND_WCDMA_900 = 87,
+ QMI_NAS_ACTIVE_BAND_WCDMA_1700_JAPAN = 88,
+ QMI_NAS_ACTIVE_BAND_WCDMA_1500_JAPAN = 90,
+ QMI_NAS_ACTIVE_BAND_WCDMA_850_JAPAN = 91,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_1 = 120,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_2 = 121,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_3 = 122,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_4 = 123,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_5 = 124,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_6 = 125,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_7 = 126,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_8 = 127,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_9 = 128,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_10 = 129,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_11 = 130,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_12 = 131,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_13 = 132,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_14 = 133,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_17 = 134,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_18 = 143,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_19 = 144,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_20 = 145,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_21 = 146,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_24 = 147,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_25 = 148,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_33 = 135,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_34 = 136,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_35 = 137,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_36 = 138,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_37 = 139,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_38 = 140,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_39 = 141,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_40 = 142,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_41 = 149,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_42 = 150,
+ QMI_NAS_ACTIVE_BAND_EUTRAN_43 = 151,
+ QMI_NAS_ACTIVE_BAND_TDSCDMA_A = 200,
+ QMI_NAS_ACTIVE_BAND_TDSCDMA_B = 201,
+ QMI_NAS_ACTIVE_BAND_TDSCDMA_C = 202,
+ QMI_NAS_ACTIVE_BAND_TDSCDMA_D = 203,
+ QMI_NAS_ACTIVE_BAND_TDSCDMA_E = 204,
+ QMI_NAS_ACTIVE_BAND_TDSCDMA_F = 205
+} QmiNasActiveBand;
+
+/**
+ * QmiNasNetworkServiceDomain:
+ * @QMI_NAS_NETWORK_SERVICE_DOMAIN_NONE: No service.
+ * @QMI_NAS_NETWORK_SERVICE_DOMAIN_CS: Circuit switched.
+ * @QMI_NAS_NETWORK_SERVICE_DOMAIN_PS: Packet switched.
+ * @QMI_NAS_NETWORK_SERVICE_DOMAIN_CS_PS: Circuit and packet switched.
+ * @QMI_NAS_NETWORK_SERVICE_DOMAIN_UNKNOWN: Unknown service.
+ *
+ * Network Service Domain.
+ */
+typedef enum {
+ QMI_NAS_NETWORK_SERVICE_DOMAIN_NONE = 0x00,
+ QMI_NAS_NETWORK_SERVICE_DOMAIN_CS = 0x01,
+ QMI_NAS_NETWORK_SERVICE_DOMAIN_PS = 0x02,
+ QMI_NAS_NETWORK_SERVICE_DOMAIN_CS_PS = 0x03,
+ QMI_NAS_NETWORK_SERVICE_DOMAIN_UNKNOWN = 0x04,
+} QmiNasNetworkServiceDomain;
+
+/**
+ * QmiNasEvdoSinrLevel:
+ * @QMI_NAS_EVDO_SINR_LEVEL_0: -9 dB.
+ * @QMI_NAS_EVDO_SINR_LEVEL_1: -6 dB.
+ * @QMI_NAS_EVDO_SINR_LEVEL_2: -4.5 dB.
+ * @QMI_NAS_EVDO_SINR_LEVEL_3: -3 dB.
+ * @QMI_NAS_EVDO_SINR_LEVEL_4: -2 dB.
+ * @QMI_NAS_EVDO_SINR_LEVEL_5: +1 dB.
+ * @QMI_NAS_EVDO_SINR_LEVEL_6: +3 dB.
+ * @QMI_NAS_EVDO_SINR_LEVEL_7: +6 dB.
+ * @QMI_NAS_EVDO_SINR_LEVEL_8: +9 dB.
+ *
+ * EV-DO SINR level.
+ */
+typedef enum {
+ QMI_NAS_EVDO_SINR_LEVEL_0 = 0,
+ QMI_NAS_EVDO_SINR_LEVEL_1 = 1,
+ QMI_NAS_EVDO_SINR_LEVEL_2 = 2,
+ QMI_NAS_EVDO_SINR_LEVEL_3 = 3,
+ QMI_NAS_EVDO_SINR_LEVEL_4 = 4,
+ QMI_NAS_EVDO_SINR_LEVEL_5 = 5,
+ QMI_NAS_EVDO_SINR_LEVEL_6 = 6,
+ QMI_NAS_EVDO_SINR_LEVEL_7 = 7,
+ QMI_NAS_EVDO_SINR_LEVEL_8 = 8
+} QmiNasEvdoSinrLevel;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI NAS Get Signal Strength' request/response */
+
+/**
+ * QmiNasSignalStrengthRequest:
+ * @QMI_NAS_SIGNAL_STRENGTH_REQUEST_NONE: None.
+ * @QMI_NAS_SIGNAL_STRENGTH_REQUEST_RSSI: Request RSSI information.
+ * @QMI_NAS_SIGNAL_STRENGTH_REQUEST_ECIO: Request ECIO information.
+ * @QMI_NAS_SIGNAL_STRENGTH_REQUEST_IO: Request IO information.
+ * @QMI_NAS_SIGNAL_STRENGTH_REQUEST_SINR: Request SINR information.
+ * @QMI_NAS_SIGNAL_STRENGTH_REQUEST_ERROR_RATE: Request error rate information.
+ * @QMI_NAS_SIGNAL_STRENGTH_REQUEST_RSRQ: Request RSRQ information.
+ * @QMI_NAS_SIGNAL_STRENGTH_REQUEST_LTE_SNR: Request LTE SNR information.
+ * @QMI_NAS_SIGNAL_STRENGTH_REQUEST_LTE_RSRP: Request LTE RSRP information.
+ *
+ * Extra information to request when gathering Signal Strength.
+ */
+typedef enum {
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_NONE = 0,
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_RSSI = 1 << 0,
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_ECIO = 1 << 1,
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_IO = 1 << 2,
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_SINR = 1 << 3,
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_ERROR_RATE = 1 << 4,
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_RSRQ = 1 << 5,
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_LTE_SNR = 1 << 6,
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_LTE_RSRP = 1 << 7
+} QmiNasSignalStrengthRequest;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI NAS Network Scan' request/response */
+
+/**
+ * QmiNasNetworkScanType:
+ * @QMI_NAS_NETWORK_SCAN_TYPE_GSM: GSM network.
+ * @QMI_NAS_NETWORK_SCAN_TYPE_UMTS: UMTS network.
+ * @QMI_NAS_NETWORK_SCAN_TYPE_LTE: LTE network.
+ * @QMI_NAS_NETWORK_SCAN_TYPE_TD_SCDMA: TD-SCDMA network.
+ *
+ * Flags to use when specifying which networks to scan.
+ */
+typedef enum {
+ QMI_NAS_NETWORK_SCAN_TYPE_GSM = 1 << 0,
+ QMI_NAS_NETWORK_SCAN_TYPE_UMTS = 1 << 1,
+ QMI_NAS_NETWORK_SCAN_TYPE_LTE = 1 << 2,
+ QMI_NAS_NETWORK_SCAN_TYPE_TD_SCDMA = 1 << 3
+} QmiNasNetworkScanType;
+
+/**
+ * QmiNasNetworkStatus:
+ * @QMI_NAS_NETWORK_STATUS_CURRENT_SERVING: Network is in use, current serving.
+ * @QMI_NAS_NETWORK_STATUS_AVAILABLE: Network is vailable.
+ * @QMI_NAS_NETWORK_STATUS_HOME: Network is home network.
+ * @QMI_NAS_NETWORK_STATUS_ROAMING: Network is a roaming network.
+ * @QMI_NAS_NETWORK_STATUS_FORBIDDEN: Network is forbidden.
+ * @QMI_NAS_NETWORK_STATUS_NOT_FORBIDDEN: Network is not forbidden.
+ * @QMI_NAS_NETWORK_STATUS_PREFERRED: Network is preferred.
+ * @QMI_NAS_NETWORK_STATUS_NOT_PREFERRED: Network is not preferred.
+ *
+ * Flags to specify the status of a given network.
+ */
+typedef enum {
+ QMI_NAS_NETWORK_STATUS_CURRENT_SERVING = 1 << 0,
+ QMI_NAS_NETWORK_STATUS_AVAILABLE = 1 << 1,
+ QMI_NAS_NETWORK_STATUS_HOME = 1 << 2,
+ QMI_NAS_NETWORK_STATUS_ROAMING = 1 << 3,
+ QMI_NAS_NETWORK_STATUS_FORBIDDEN = 1 << 4,
+ QMI_NAS_NETWORK_STATUS_NOT_FORBIDDEN = 1 << 5,
+ QMI_NAS_NETWORK_STATUS_PREFERRED = 1 << 6,
+ QMI_NAS_NETWORK_STATUS_NOT_PREFERRED = 1 << 7
+} QmiNasNetworkStatus;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI NAS Initiate Network Register' request/response */
+
+/**
+ * QmiNasNetworkRegisterType:
+ * @QMI_NAS_NETWORK_REGISTER_TYPE_AUTOMATIC: Automatic network registration.
+ * @QMI_NAS_NETWORK_REGISTER_TYPE_MANUAL: Manual network registration.
+ *
+ * Type of network registration.
+ */
+typedef enum {
+ QMI_NAS_NETWORK_REGISTER_TYPE_AUTOMATIC = 0x01,
+ QMI_NAS_NETWORK_REGISTER_TYPE_MANUAL = 0x02
+} QmiNasNetworkRegisterType;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI NAS Get Serving System' request/response */
+
+/**
+ * QmiNasRegistrationState:
+ * @QMI_NAS_REGISTRATION_STATE_NOT_REGISTERED: Not registered.
+ * @QMI_NAS_REGISTRATION_STATE_REGISTERED: Registered.
+ * @QMI_NAS_REGISTRATION_STATE_NOT_REGISTERED_SEARCHING: Searching.
+ * @QMI_NAS_REGISTRATION_STATE_REGISTRATION_DENIED: Registration denied.
+ * @QMI_NAS_REGISTRATION_STATE_UNKNOWN: Unknown.
+ *
+ * Status of the network registration.
+ */
+typedef enum {
+ QMI_NAS_REGISTRATION_STATE_NOT_REGISTERED = 0x00,
+ QMI_NAS_REGISTRATION_STATE_REGISTERED = 0x01,
+ QMI_NAS_REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 0x02,
+ QMI_NAS_REGISTRATION_STATE_REGISTRATION_DENIED = 0x03,
+ QMI_NAS_REGISTRATION_STATE_UNKNOWN = 0x04
+} QmiNasRegistrationState;
+
+/**
+ * QmiNasAttachState:
+ * @QMI_NAS_ATTACH_STATE_UNKNOWN: Unknown attach state.
+ * @QMI_NAS_ATTACH_STATE_ATTACHED: Attached.
+ * @QMI_NAS_ATTACH_STATE_DETACHED: Detached.
+ *
+ * Domain attach state.
+ */
+typedef enum {
+ QMI_NAS_ATTACH_STATE_UNKNOWN = 0x00,
+ QMI_NAS_ATTACH_STATE_ATTACHED = 0x01,
+ QMI_NAS_ATTACH_STATE_DETACHED = 0x02,
+} QmiNasAttachState;
+
+/**
+ * QmiNasNetworkType:
+ * @QMI_NAS_NETWORK_TYPE_UNKNOWN: Unknown.
+ * @QMI_NAS_NETWORK_TYPE_3GPP2: 3GPP2 network.
+ * @QMI_NAS_NETWORK_TYPE_3GPP: 3GPP network.
+ *
+ * Type of network.
+ */
+typedef enum {
+ QMI_NAS_NETWORK_TYPE_UNKNOWN = 0x00,
+ QMI_NAS_NETWORK_TYPE_3GPP2 = 0x01,
+ QMI_NAS_NETWORK_TYPE_3GPP = 0x02,
+} QmiNasNetworkType;
+
+/**
+ * QmiNasRoamingIndicatorStatus:
+ * @QMI_NAS_ROAMING_INDICATOR_STATUS_ON: Roaming.
+ * @QMI_NAS_ROAMING_INDICATOR_STATUS_OFF: Home.
+ *
+ * Status of the roaming indication.
+ */
+typedef enum {
+ QMI_NAS_ROAMING_INDICATOR_STATUS_ON = 0x00,
+ QMI_NAS_ROAMING_INDICATOR_STATUS_OFF = 0x01,
+ /* next values only for 3GPP2 */
+} QmiNasRoamingIndicatorStatus;
+
+/**
+ * QmiNasDataCapability:
+ * @QMI_NAS_DATA_CAPABILITY_NONE: None or unknown.
+ * @QMI_NAS_DATA_CAPABILITY_GPRS: GPRS.
+ * @QMI_NAS_DATA_CAPABILITY_EDGE: EDGE.
+ * @QMI_NAS_DATA_CAPABILITY_HSDPA: HSDPA.
+ * @QMI_NAS_DATA_CAPABILITY_HSUPA: HSUPA.
+ * @QMI_NAS_DATA_CAPABILITY_WCDMA: WCDMA.
+ * @QMI_NAS_DATA_CAPABILITY_CDMA: CDMA.
+ * @QMI_NAS_DATA_CAPABILITY_EVDO_REV_0: EV-DO revision 0.
+ * @QMI_NAS_DATA_CAPABILITY_EVDO_REV_A: EV-DO revision A.
+ * @QMI_NAS_DATA_CAPABILITY_GSM: GSM.
+ * @QMI_NAS_DATA_CAPABILITY_EVDO_REV_B: EV-DO revision B.
+ * @QMI_NAS_DATA_CAPABILITY_LTE: LTE.
+ * @QMI_NAS_DATA_CAPABILITY_HSDPA_PLUS: HSDPA+.
+ * @QMI_NAS_DATA_CAPABILITY_DC_HSDPA_PLUS: DC-HSDPA+.
+ *
+ * Data capability of the network.
+ */
+typedef enum {
+ QMI_NAS_DATA_CAPABILITY_NONE = 0x00,
+ QMI_NAS_DATA_CAPABILITY_GPRS = 0x01,
+ QMI_NAS_DATA_CAPABILITY_EDGE = 0x02,
+ QMI_NAS_DATA_CAPABILITY_HSDPA = 0x03,
+ QMI_NAS_DATA_CAPABILITY_HSUPA = 0x04,
+ QMI_NAS_DATA_CAPABILITY_WCDMA = 0x05,
+ QMI_NAS_DATA_CAPABILITY_CDMA = 0x06,
+ QMI_NAS_DATA_CAPABILITY_EVDO_REV_0 = 0x07,
+ QMI_NAS_DATA_CAPABILITY_EVDO_REV_A = 0x08,
+ QMI_NAS_DATA_CAPABILITY_GSM = 0x09,
+ QMI_NAS_DATA_CAPABILITY_EVDO_REV_B = 0x0A,
+ QMI_NAS_DATA_CAPABILITY_LTE = 0x0B,
+ QMI_NAS_DATA_CAPABILITY_HSDPA_PLUS = 0x0C,
+ QMI_NAS_DATA_CAPABILITY_DC_HSDPA_PLUS = 0x0D
+} QmiNasDataCapability;
+
+/**
+ * QmiNasServiceStatus:
+ * @QMI_NAS_SERVICE_STATUS_NONE: No service.
+ * @QMI_NAS_SERVICE_STATUS_LIMITED: Limited service.
+ * @QMI_NAS_SERVICE_STATUS_AVAILABLE: Service available.
+ * @QMI_NAS_SERVICE_STATUS_LIMITED_REGIONAL: Limited regional service.
+ * @QMI_NAS_SERVICE_STATUS_POWER_SAVE: Device in power save mode.
+ *
+ * Status of the service.
+ */
+typedef enum {
+ QMI_NAS_SERVICE_STATUS_NONE = 0x00,
+ QMI_NAS_SERVICE_STATUS_LIMITED = 0x01,
+ QMI_NAS_SERVICE_STATUS_AVAILABLE = 0x02,
+ QMI_NAS_SERVICE_STATUS_LIMITED_REGIONAL = 0x03,
+ QMI_NAS_SERVICE_STATUS_POWER_SAVE = 0x04
+} QmiNasServiceStatus;
+
+/**
+ * QmiNasHdrPersonality:
+ * @QMI_NAS_HDR_PERSONALITY_UNKNOWN: Unknown.
+ * @QMI_NAS_HDR_PERSONALITY_HRPD: HRPD.
+ * @QMI_NAS_HDR_PERSONALITY_EHRPD: eHRPD.
+ *
+ * HDR personality type.
+ */
+typedef enum {
+ QMI_NAS_HDR_PERSONALITY_UNKNOWN = 0x00,
+ QMI_NAS_HDR_PERSONALITY_HRPD = 0x01,
+ QMI_NAS_HDR_PERSONALITY_EHRPD = 0x02,
+} QmiNasHdrPersonality;
+
+/**
+ * QmiNasCallBarringStatus:
+ * @QMI_NAS_CALL_BARRING_STATUS_NORMAL_ONLY: Normal calls only.
+ * @QMI_NAS_CALL_BARRING_STATUS_EMERGENCY_ONLY: Emergency calls only.
+ * @QMI_NAS_CALL_BARRING_STATUS_NO_CALLS: No calls allowed.
+ * @QMI_NAS_CALL_BARRING_STATUS_ALL_CALLS: All calls allowed.
+ * @QMI_NAS_CALL_BARRING_STATUS_UNKNOWN: Unknown.
+ *
+ * Status of the call barring functionality.
+ */
+typedef enum {
+ QMI_NAS_CALL_BARRING_STATUS_NORMAL_ONLY = 0x00,
+ QMI_NAS_CALL_BARRING_STATUS_EMERGENCY_ONLY = 0x01,
+ QMI_NAS_CALL_BARRING_STATUS_NO_CALLS = 0x02,
+ QMI_NAS_CALL_BARRING_STATUS_ALL_CALLS = 0x03,
+ QMI_NAS_CALL_BARRING_STATUS_UNKNOWN = -1
+} QmiNasCallBarringStatus;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI NAS Get Home Network' request/response */
+
+/**
+ * QmiNasNetworkDescriptionDisplay:
+ * @QMI_NAS_NETWORK_DESCRIPTION_DISPLAY_NO: Don't display.
+ * @QMI_NAS_NETWORK_DESCRIPTION_DISPLAY_YES: Display.
+ * @QMI_NAS_NETWORK_DESCRIPTION_DISPLAY_UNKNOWN: Unknown.
+ *
+ * Setup to define whether the network description should be displayed.
+ */
+typedef enum {
+ QMI_NAS_NETWORK_DESCRIPTION_DISPLAY_NO = 0x00,
+ QMI_NAS_NETWORK_DESCRIPTION_DISPLAY_YES = 0x01,
+ QMI_NAS_NETWORK_DESCRIPTION_DISPLAY_UNKNOWN = 0xFF
+} QmiNasNetworkDescriptionDisplay;
+
+/**
+ * QmiNasNetworkDescriptionEncoding:
+ * @QMI_NAS_NETWORK_DESCRIPTION_ENCODING_UNSPECIFIED: Unspecified.
+ * @QMI_NAS_NETWORK_DESCRIPTION_ENCODING_ASCII7: ASCII-7.
+ * @QMI_NAS_NETWORK_DESCRIPTION_ENCODING_UNICODE: Unicode.
+ * @QMI_NAS_NETWORK_DESCRIPTION_ENCODING_GSM: GSM 7-bit.
+ *
+ * Type of encoding used in the network description.
+ */
+typedef enum {
+ QMI_NAS_NETWORK_DESCRIPTION_ENCODING_UNSPECIFIED = 0x00,
+ QMI_NAS_NETWORK_DESCRIPTION_ENCODING_ASCII7 = 0x01,
+ QMI_NAS_NETWORK_DESCRIPTION_ENCODING_UNICODE = 0x04,
+ QMI_NAS_NETWORK_DESCRIPTION_ENCODING_GSM = 0x09
+} QmiNasNetworkDescriptionEncoding;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI NAS Get Technology Preference' request/response */
+
+/**
+ * QmiNasRadioTechnologyPreference:
+ * @QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_AUTO: Automatic selection.
+ * @QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_3GPP2: 3GPP2 technology.
+ * @QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_3GPP: 3GPP technology.
+ * @QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_AMPS_OR_GSM: AMPS if 3GPP2, GSM if 3GPP.
+ * @QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_CDMA_OR_WCDMA: CDMA if 3GPP2, WCDMA if 3GPP.
+ * @QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_HDR: CDMA EV-DO.
+ * @QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_LTE: LTE.
+ *
+ * Flags to specify the radio technology preference.
+ */
+typedef enum {
+ QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_AUTO = 0,
+ QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_3GPP2 = 1 << 0,
+ QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_3GPP = 1 << 1,
+ QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_AMPS_OR_GSM = 1 << 2,
+ QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_CDMA_OR_WCDMA = 1 << 3,
+ QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_HDR = 1 << 4,
+ QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_LTE = 1 << 5
+} QmiNasRadioTechnologyPreference;
+
+/**
+ * QmiNasPreferenceDuration:
+ * @QMI_NAS_PREFERENCE_DURATION_PERMANENT: Permanent.
+ * @QMI_NAS_PREFERENCE_DURATION_POWER_CYCLE: Until the next power cycle.
+ * @QMI_NAS_PREFERENCE_DURATION_ONE_CALL: Until end of call.
+ * @QMI_NAS_PREFERENCE_DURATION_ONE_CALL_OR_TIME: Until end of call or a specified time.
+ * @QMI_NAS_PREFERENCE_DURATION_INTERNAL_ONE_CALL_1: Internal reason 1, one call.
+ * @QMI_NAS_PREFERENCE_DURATION_INTERNAL_ONE_CALL_2: Internal reason 2, one call.
+ * @QMI_NAS_PREFERENCE_DURATION_INTERNAL_ONE_CALL_3: Internal reason 3, one call.
+ *
+ * Duration of the preference setting.
+ */
+typedef enum {
+ QMI_NAS_PREFERENCE_DURATION_PERMANENT = 0x00,
+ QMI_NAS_PREFERENCE_DURATION_POWER_CYCLE = 0x01,
+ QMI_NAS_PREFERENCE_DURATION_ONE_CALL = 0x02,
+ QMI_NAS_PREFERENCE_DURATION_ONE_CALL_OR_TIME = 0x03,
+ QMI_NAS_PREFERENCE_DURATION_INTERNAL_ONE_CALL_1 = 0x04,
+ QMI_NAS_PREFERENCE_DURATION_INTERNAL_ONE_CALL_2 = 0x05,
+ QMI_NAS_PREFERENCE_DURATION_INTERNAL_ONE_CALL_3 = 0x06
+} QmiNasPreferenceDuration;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI NAS Get/Set System Selection Preference'
+ * requests/responses */
+
+/**
+ * QmiNasRatModePreference:
+ * @QMI_NAS_RAT_MODE_PREFERENCE_CDMA_1X: CDMA2000 1X.
+ * @QMI_NAS_RAT_MODE_PREFERENCE_CDMA_1XEVDO: CDMA2000 HRPD (1xEV-DO).
+ * @QMI_NAS_RAT_MODE_PREFERENCE_GSM: GSM.
+ * @QMI_NAS_RAT_MODE_PREFERENCE_UMTS: UMTS.
+ * @QMI_NAS_RAT_MODE_PREFERENCE_LTE: LTE.
+ * @QMI_NAS_RAT_MODE_PREFERENCE_TD_SCDMA: TD-SCDMA.
+ *
+ * Flags specifying radio access technology mode preference.
+ */
+typedef enum {
+ QMI_NAS_RAT_MODE_PREFERENCE_CDMA_1X = 1 << 0,
+ QMI_NAS_RAT_MODE_PREFERENCE_CDMA_1XEVDO = 1 << 1,
+ QMI_NAS_RAT_MODE_PREFERENCE_GSM = 1 << 2,
+ QMI_NAS_RAT_MODE_PREFERENCE_UMTS = 1 << 3,
+ QMI_NAS_RAT_MODE_PREFERENCE_LTE = 1 << 4,
+ QMI_NAS_RAT_MODE_PREFERENCE_TD_SCDMA = 1 << 5
+} QmiNasRatModePreference;
+
+/**
+ * QmiNasCdmaPrlPreference:
+ * @QMI_NAS_CDMA_PRL_PREFERENCE_A_SIDE_ONLY: System A only.
+ * @QMI_NAS_CDMA_PRL_PREFERENCE_B_SIDE_ONLY: System B only.
+ * @QMI_NAS_CDMA_PRL_PREFERENCE_ANY: Any system.
+ *
+ * Flags specifying the preference when using CDMA Band Class 0.
+ */
+typedef enum {
+ QMI_NAS_CDMA_PRL_PREFERENCE_A_SIDE_ONLY = 0x0001,
+ QMI_NAS_CDMA_PRL_PREFERENCE_B_SIDE_ONLY = 0x0002,
+ QMI_NAS_CDMA_PRL_PREFERENCE_ANY = 0x3FFF
+} QmiNasCdmaPrlPreference;
+
+/**
+ * QmiNasRoamingPreference:
+ * @QMI_NAS_ROAMING_PREFERENCE_OFF: Only non-roaming networks.
+ * @QMI_NAS_ROAMING_PREFERENCE_NOT_OFF: Only roaming networks.
+ * @QMI_NAS_ROAMING_PREFERENCE_NOT_FLASHING: Only non-roaming networks or not flashing.
+ * @QMI_NAS_ROAMING_PREFERENCE_ANY: Don't filter by roaming when acquiring networks.
+ *
+ * Roaming preference.
+ */
+typedef enum {
+ QMI_NAS_ROAMING_PREFERENCE_OFF = 0x01,
+ QMI_NAS_ROAMING_PREFERENCE_NOT_OFF = 0x02,
+ QMI_NAS_ROAMING_PREFERENCE_NOT_FLASHING = 0x03,
+ QMI_NAS_ROAMING_PREFERENCE_ANY = 0xFF
+} QmiNasRoamingPreference;
+
+/**
+ * QmiNasNetworkSelectionPreference:
+ * @QMI_NAS_NETWORK_SELECTION_PREFERENCE_AUTOMATIC: Automatic.
+ * @QMI_NAS_NETWORK_SELECTION_PREFERENCE_MANUAL: Manual.
+ *
+ * Network selection preference.
+ */
+typedef enum {
+ QMI_NAS_NETWORK_SELECTION_PREFERENCE_AUTOMATIC = 0x00,
+ QMI_NAS_NETWORK_SELECTION_PREFERENCE_MANUAL = 0x01
+} QmiNasNetworkSelectionPreference;
+
+/**
+ * QmiNasChangeDuration:
+ * @QMI_NAS_CHANGE_DURATION_PERMANENT: Permanent.
+ * @QMI_NAS_CHANGE_DURATION_POWER_CYCLE: Until the next power cycle.
+ *
+ * Duration of the change setting.
+ */
+typedef enum {
+ QMI_NAS_CHANGE_DURATION_POWER_CYCLE = 0x00,
+ QMI_NAS_CHANGE_DURATION_PERMANENT = 0x01
+} QmiNasChangeDuration;
+
+/**
+ * QmiNasServiceDomainPreference:
+ * @QMI_NAS_SERVICE_DOMAIN_PREFERENCE_CS_ONLY: Circuit-switched only.
+ * @QMI_NAS_SERVICE_DOMAIN_PREFERENCE_PS_ONLY: Packet-switched only.
+ * @QMI_NAS_SERVICE_DOMAIN_PREFERENCE_CS_PS: Circuit-switched and packet-switched.
+ * @QMI_NAS_SERVICE_DOMAIN_PREFERENCE_PS_ATTACH: Packet-switched attach.
+ * @QMI_NAS_SERVICE_DOMAIN_PREFERENCE_PS_DETACH:Packet-switched dettach.
+ *
+ * Service domain preference.
+ */
+typedef enum {
+ QMI_NAS_SERVICE_DOMAIN_PREFERENCE_CS_ONLY = 0x00,
+ QMI_NAS_SERVICE_DOMAIN_PREFERENCE_PS_ONLY = 0x01,
+ QMI_NAS_SERVICE_DOMAIN_PREFERENCE_CS_PS = 0x02,
+ QMI_NAS_SERVICE_DOMAIN_PREFERENCE_PS_ATTACH = 0x03,
+ QMI_NAS_SERVICE_DOMAIN_PREFERENCE_PS_DETACH = 0x04,
+} QmiNasServiceDomainPreference;
+
+/**
+ * QmiNasGsmWcdmaAcquisitionOrderPreference:
+ * @QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_AUTOMATIC: Automatic.
+ * @QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_GSM: GSM first, then WCDMA.
+ * @QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_WCDMA: WCDMA first, then GSM.
+ *
+ * GSM/WCDMA acquisition order preference.
+ */
+typedef enum {
+ QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_AUTOMATIC = 0x00,
+ QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_GSM = 0x01,
+ QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_WCDMA = 0x02
+} QmiNasGsmWcdmaAcquisitionOrderPreference;
+
+/**
+ * QmiNasTdScdmaBandPreference:
+ * @QMI_NAS_TD_SCDMA_BAND_PREFERENCE_A: Band A.
+ * @QMI_NAS_TD_SCDMA_BAND_PREFERENCE_B: Band B.
+ * @QMI_NAS_TD_SCDMA_BAND_PREFERENCE_C: Band C.
+ * @QMI_NAS_TD_SCDMA_BAND_PREFERENCE_D: Band D.
+ * @QMI_NAS_TD_SCDMA_BAND_PREFERENCE_E: Band E.
+ * @QMI_NAS_TD_SCDMA_BAND_PREFERENCE_F: Band F.
+ *
+ * Flags to specify TD-SCDMA-specific frequency band preferences.
+ */
+typedef enum {
+ QMI_NAS_TD_SCDMA_BAND_PREFERENCE_A = 1 << 0,
+ QMI_NAS_TD_SCDMA_BAND_PREFERENCE_B = 1 << 1,
+ QMI_NAS_TD_SCDMA_BAND_PREFERENCE_C = 1 << 2,
+ QMI_NAS_TD_SCDMA_BAND_PREFERENCE_D = 1 << 3,
+ QMI_NAS_TD_SCDMA_BAND_PREFERENCE_E = 1 << 4,
+ QMI_NAS_TD_SCDMA_BAND_PREFERENCE_F = 1 << 5
+} QmiNasTdScdmaBandPreference;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI NAS Get System Info' request/response */
+
+/**
+ * QmiNasRoamingStatus:
+ * @QMI_NAS_ROAMING_STATUS_OFF: Off.
+ * @QMI_NAS_ROAMING_STATUS_ON: On.
+ * @QMI_NAS_ROAMING_STATUS_BLINK: Blinking.
+ * @QMI_NAS_ROAMING_STATUS_OUT_OF_NEIGHBORHOOD: Out of neighborhood.
+ * @QMI_NAS_ROAMING_STATUS_OUT_OF_BUILDING: Out of building.
+ * @QMI_NAS_ROAMING_STATUS_PREFERRED_SYSTEM: Preferred system.
+ * @QMI_NAS_ROAMING_STATUS_AVAILABLE_SYSTEM: Available system.
+ * @QMI_NAS_ROAMING_STATUS_ALLIANCE_PARTNER: Alliance partner.
+ * @QMI_NAS_ROAMING_STATUS_PREMIUM_PARTNER: Premium partner.
+ * @QMI_NAS_ROAMING_STATUS_FULL_SERVICE: Full service.
+ * @QMI_NAS_ROAMING_STATUS_PARTIAL_SERVICE: Partial service.
+ * @QMI_NAS_ROAMING_STATUS_BANNER_ON: Banner on.
+ * @QMI_NAS_ROAMING_STATUS_BANNER_OFF: Banner off.
+*/
+typedef enum {
+ QMI_NAS_ROAMING_STATUS_OFF = 0x00,
+ QMI_NAS_ROAMING_STATUS_ON = 0x01,
+ /* Next ones only for 3GPP2 */
+ QMI_NAS_ROAMING_STATUS_BLINK = 0x02,
+ QMI_NAS_ROAMING_STATUS_OUT_OF_NEIGHBORHOOD = 0x03,
+ QMI_NAS_ROAMING_STATUS_OUT_OF_BUILDING = 0x04,
+ QMI_NAS_ROAMING_STATUS_PREFERRED_SYSTEM = 0x05,
+ QMI_NAS_ROAMING_STATUS_AVAILABLE_SYSTEM = 0x06,
+ QMI_NAS_ROAMING_STATUS_ALLIANCE_PARTNER = 0x07,
+ QMI_NAS_ROAMING_STATUS_PREMIUM_PARTNER = 0x08,
+ QMI_NAS_ROAMING_STATUS_FULL_SERVICE = 0x09,
+ QMI_NAS_ROAMING_STATUS_PARTIAL_SERVICE = 0x0A,
+ QMI_NAS_ROAMING_STATUS_BANNER_ON = 0x0B,
+ QMI_NAS_ROAMING_STATUS_BANNER_OFF = 0x0C
+} QmiNasRoamingStatus;
+
+/**
+ * QmiNasHdrProtocolRevision:
+ * @QMI_NAS_HDR_PROTOCOL_REVISION_NONE: None.
+ * @QMI_NAS_HDR_PROTOCOL_REVISION_REL_0: HDR Rel 0.
+ * @QMI_NAS_HDR_PROTOCOL_REVISION_REL_A: HDR Rel A.
+ * @QMI_NAS_HDR_PROTOCOL_REVISION_REL_B: HDR Rel B.
+ *
+ * HDR protocol revision.
+ */
+typedef enum {
+ QMI_NAS_HDR_PROTOCOL_REVISION_NONE = 0x00,
+ QMI_NAS_HDR_PROTOCOL_REVISION_REL_0 = 0x01,
+ QMI_NAS_HDR_PROTOCOL_REVISION_REL_A = 0x02,
+ QMI_NAS_HDR_PROTOCOL_REVISION_REL_B = 0x03
+} QmiNasHdrProtocolRevision;
+
+/**
+ * QmiNasWcdmaHsService:
+ * @QMI_NAS_WCDMA_HS_SERVICE_HSDPA_HSUPA_UNSUPPORTED: HSDPA and HSUPA not supported.
+ * @QMI_NAS_WCDMA_HS_SERVICE_HSDPA_SUPPORTED: HSDPA supported.
+ * @QMI_NAS_WCDMA_HS_SERVICE_HSUPA_SUPPORTED: HSUPA supported.
+ * @QMI_NAS_WCDMA_HS_SERVICE_HSDPA_HSUPA_SUPPORTED: HSDPA and HSUPA supported.
+ * @QMI_NAS_WCDMA_HS_SERVICE_HSDPA_PLUS_SUPPORTED: HSDPA+ supported.
+ * @QMI_NAS_WCDMA_HS_SERVICE_HSDPA_PLUS_HSUPA_SUPPORTED: HSDPA+ and HSUPA supported.
+ * @QMI_NAS_WCDMA_HS_SERVICE_DC_HSDPA_PLUS_SUPPORTED: DC-HSDPA+ supported.
+ * @QMI_NAS_WCDMA_HS_SERVICE_DC_HSDPA_PLUS_HSUPA_SUPPORTED: DC-HSDPA+ and HSUPA supported.
+ * Call status on high speed.
+ */
+typedef enum {
+ QMI_NAS_WCDMA_HS_SERVICE_HSDPA_HSUPA_UNSUPPORTED = 0x00,
+ QMI_NAS_WCDMA_HS_SERVICE_HSDPA_SUPPORTED = 0x01,
+ QMI_NAS_WCDMA_HS_SERVICE_HSUPA_SUPPORTED = 0x02,
+ QMI_NAS_WCDMA_HS_SERVICE_HSDPA_HSUPA_SUPPORTED = 0x03,
+ QMI_NAS_WCDMA_HS_SERVICE_HSDPA_PLUS_SUPPORTED = 0x04,
+ QMI_NAS_WCDMA_HS_SERVICE_HSDPA_PLUS_HSUPA_SUPPORTED = 0x05,
+ QMI_NAS_WCDMA_HS_SERVICE_DC_HSDPA_PLUS_SUPPORTED = 0x06,
+ QMI_NAS_WCDMA_HS_SERVICE_DC_HSDPA_PLUS_HSUPA_SUPPORTED = 0x07
+} QmiNasWcdmaHsService;
+
+/**
+ * QmiNasCellBroadcastCapability:
+ * @QMI_NAS_CELL_BROADCAST_CAPABILITY_UNKNOWN: Unknown.
+ * @QMI_NAS_CELL_BROADCAST_CAPABILITY_OFF: Cell broadcast not supported.
+ * @QMI_NAS_CELL_BROADCAST_CAPABILITY_ON: Cell broadcast supported.
+ *
+ * Cell broadcast support.
+ */
+typedef enum {
+ QMI_NAS_CELL_BROADCAST_CAPABILITY_UNKNOWN = 0x00,
+ QMI_NAS_CELL_BROADCAST_CAPABILITY_OFF = 0x01,
+ QMI_NAS_CELL_BROADCAST_CAPABILITY_ON = 0x02
+} QmiNasCellBroadcastCapability;
+
+/**
+ * QmiNasSimRejectState:
+ * @QMI_NAS_SIM_REJECT_STATE_SIM_UNAVAILABLE: SIM not available.
+ * @QMI_NAS_SIM_REJECT_STATE_SIM_VAILABLE: SIM available.
+ * @QMI_NAS_SIM_REJECT_STATE_SIM_CS_INVALID: SIM invalid for circuit-switched connections.
+ * @QMI_NAS_SIM_REJECT_STATE_SIM_PS_INVALID: SIM invalid for packet-switched connections.
+ * @QMI_NAS_SIM_REJECT_STATE_SIM_CS_PS_INVALID: SIM invalid for circuit-switched and packet-switched connections.
+ *
+ * Reject information of the SIM.
+ */
+typedef enum {
+ QMI_NAS_SIM_REJECT_STATE_SIM_UNAVAILABLE = 0,
+ QMI_NAS_SIM_REJECT_STATE_SIM_VAILABLE = 1,
+ QMI_NAS_SIM_REJECT_STATE_SIM_CS_INVALID = 2,
+ QMI_NAS_SIM_REJECT_STATE_SIM_PS_INVALID = 3,
+ QMI_NAS_SIM_REJECT_STATE_SIM_CS_PS_INVALID = 4
+} QmiNasSimRejectState;
+
+/**
+ * QmiNasCdmaPilotType:
+ * @QMI_NAS_CDMA_PILOT_TYPE_ACTIVE: the pilot is part of the active set.
+ * @QMI_NAS_CDMA_PILOT_TYPE_NEIGHBOR: the pilot is part of the neighbor set.
+ *
+ * The pilot set the pilot belongs to.
+ */
+typedef enum {
+ QMI_NAS_CDMA_PILOT_TYPE_ACTIVE = 0,
+ QMI_NAS_CDMA_PILOT_TYPE_NEIGHBOR = 1,
+} QmiNasCdmaPilotType;
+
+/**
+ * QmiNasDayOfWeek:
+ * @QMI_NAS_DAY_OF_WEEK_MONDAY: Monday
+ * @QMI_NAS_DAY_OF_WEEK_TUESDAY: Tuesday
+ * @QMI_NAS_DAY_OF_WEEK_WEDNESDAY: Wednesday
+ * @QMI_NAS_DAY_OF_WEEK_THURSDAY: Thursday
+ * @QMI_NAS_DAY_OF_WEEK_FRIDAY: Friday
+ * @QMI_NAS_DAY_OF_WEEK_SATURDAY: Saturday
+ * @QMI_NAS_DAY_OF_WEEK_SUNDAY: Sunday
+ *
+ * The day of the week.
+ */
+typedef enum {
+ QMI_NAS_DAY_OF_WEEK_MONDAY = 0,
+ QMI_NAS_DAY_OF_WEEK_TUESDAY = 1,
+ QMI_NAS_DAY_OF_WEEK_WEDNESDAY = 2,
+ QMI_NAS_DAY_OF_WEEK_THURSDAY = 3,
+ QMI_NAS_DAY_OF_WEEK_FRIDAY = 4,
+ QMI_NAS_DAY_OF_WEEK_SATURDAY = 5,
+ QMI_NAS_DAY_OF_WEEK_SUNDAY = 6
+} QmiNasDayOfWeek;
+
+/**
+ * QmiNasDaylightSavingsAdjustment:
+ * @QMI_NAS_DAYLIGHT_SAVINGS_ADJUSTMENT_NONE: no adjustment
+ * @QMI_NAS_DAYLIGHT_SAVINGS_ADJUSTMENT_ONE_HOUR: one hour adjustment
+ * @QMI_NAS_DAYLIGHT_SAVINGS_ADJUSTMENT_TWO_HOURS: two hours adjustment
+ *
+ * The number of hours a time is adjusted for daylight savings.
+ */
+typedef enum {
+ QMI_NAS_DAYLIGHT_SAVINGS_ADJUSTMENT_NONE = 0,
+ QMI_NAS_DAYLIGHT_SAVINGS_ADJUSTMENT_ONE_HOUR = 1,
+ QMI_NAS_DAYLIGHT_SAVINGS_ADJUSTMENT_TWO_HOURS = 2
+} QmiNasDaylightSavingsAdjustment;
+
+#endif /* _LIBQMI_GLIB_QMI_ENUMS_NAS_H_ */
diff --git a/src/libqmi-glib/qmi-enums-oma.h b/src/libqmi-glib/qmi-enums-oma.h
new file mode 100644
index 0000000..6d4e826
--- /dev/null
+++ b/src/libqmi-glib/qmi-enums-oma.h
@@ -0,0 +1,124 @@
+/* -*- 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) 2013 Google Inc.
+ */
+
+#ifndef _LIBQMI_GLIB_QMI_ENUMS_OMA_H_
+#define _LIBQMI_GLIB_QMI_ENUMS_OMA_H_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+/**
+ * SECTION: qmi-enums-oma
+ * @title: OMA enumerations and flags
+ *
+ * This section defines enumerations and flags used in the OMA service
+ * interface.
+ */
+
+/**
+ * QmiOmaSessionType:
+ * @QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_DEVICE_CONFIGURE: Client-initiated device configure.
+ * @QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_PRL_UPDATE: Client-initiated PRL update.
+ * @QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_HANDS_FREE_ACTIVATION: Client-initiated hands free activation.
+ * @QMI_OMA_SESSION_TYPE_DEVICE_INITIATED_HANDS_FREE_ACTIVATION: Device-initiated hands free activation.
+ * @QMI_OMA_SESSION_TYPE_NETWORK_INITIATED_PRL_UPDATE: Network-initiated PRL update.
+ * @QMI_OMA_SESSION_TYPE_NETWORK_INITIATED_DEVICE_CONFIGURE: Network-initiated device configure.
+ * @QMI_OMA_SESSION_TYPE_DEVICE_INITIATED_PRL_UPDATE: Device-initiated PRL update.
+ *
+ * Type of OMA-DM session.
+ */
+typedef enum {
+ QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_DEVICE_CONFIGURE = 0,
+ QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_PRL_UPDATE = 1,
+ QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_HANDS_FREE_ACTIVATION = 2,
+ QMI_OMA_SESSION_TYPE_DEVICE_INITIATED_HANDS_FREE_ACTIVATION = 3,
+ QMI_OMA_SESSION_TYPE_NETWORK_INITIATED_PRL_UPDATE = 4,
+ QMI_OMA_SESSION_TYPE_NETWORK_INITIATED_DEVICE_CONFIGURE = 5,
+ QMI_OMA_SESSION_TYPE_DEVICE_INITIATED_PRL_UPDATE = 6
+} QmiOmaSessionType;
+
+/**
+ * QmiOmaSessionState:
+ * @QMI_OMA_SESSION_STATE_COMPLETE_INFORMATION_UPDATED: Session complete and information updated.
+ * @QMI_OMA_SESSION_STATE_COMPLETE_UPDATED_INFORMATION_UNAVAILABLE: Session complete but updated information not available.
+ * @QMI_OMA_SESSION_STATE_FAILED: Session failed.
+ * @QMI_OMA_SESSION_STATE_RETRYING: Session retrying.
+ * @QMI_OMA_SESSION_STATE_CONNECTING: Session connecting.
+ * @QMI_OMA_SESSION_STATE_CONNECTED: Session connected.
+ * @QMI_OMA_SESSION_STATE_AUTHENTICATED: Session authenticated.
+ * @QMI_OMA_SESSION_STATE_MDN_DOWNLOADED: MDN downloaded.
+ * @QMI_OMA_SESSION_STATE_MSID_DOWNLOADED: MSID downloaded.
+ * @QMI_OMA_SESSION_STATE_PRL_DOWNLOADED: PRL downloaded.
+ * @QMI_OMA_SESSION_STATE_MIP_PROFILE_DOWNLOADED: MIP profile downloaded.
+ *
+ * State of the OMA-DM session.
+ */
+typedef enum {
+ QMI_OMA_SESSION_STATE_COMPLETE_INFORMATION_UPDATED = 0,
+ QMI_OMA_SESSION_STATE_COMPLETE_UPDATED_INFORMATION_UNAVAILABLE = 1,
+ QMI_OMA_SESSION_STATE_FAILED = 2,
+ QMI_OMA_SESSION_STATE_RETRYING = 3,
+ QMI_OMA_SESSION_STATE_CONNECTING = 4,
+ QMI_OMA_SESSION_STATE_CONNECTED = 5,
+ QMI_OMA_SESSION_STATE_AUTHENTICATED = 6,
+ QMI_OMA_SESSION_STATE_MDN_DOWNLOADED = 7,
+ QMI_OMA_SESSION_STATE_MSID_DOWNLOADED = 8,
+ QMI_OMA_SESSION_STATE_PRL_DOWNLOADED = 9,
+ QMI_OMA_SESSION_STATE_MIP_PROFILE_DOWNLOADED = 10
+} QmiOmaSessionState;
+
+/**
+ * QmiOmaSessionFailedReason:
+ * @QMI_OMA_SESSION_FAILED_REASON_UNKNOWN: Unknown reason.
+ * @QMI_OMA_SESSION_FAILED_REASON_NETWORK_UNAVAILABLE: Network unavailable.
+ * @QMI_OMA_SESSION_FAILED_REASON_SERVER_UNAVAILABLE: Server unavailable.
+ * @QMI_OMA_SESSION_FAILED_REASON_AUTHENTICATION_FAILED: Authentication failed.
+ * @QMI_OMA_SESSION_FAILED_REASON_MAX_RETRY_EXCEEDED: Maximum retries exceeded.
+ * @QMI_OMA_SESSION_FAILED_REASON_SESSION_CANCELLED: Session cancelled.
+ *
+ * Session failure reason.
+ */
+typedef enum {
+ QMI_OMA_SESSION_FAILED_REASON_UNKNOWN = 0,
+ QMI_OMA_SESSION_FAILED_REASON_NETWORK_UNAVAILABLE = 1,
+ QMI_OMA_SESSION_FAILED_REASON_SERVER_UNAVAILABLE = 2,
+ QMI_OMA_SESSION_FAILED_REASON_AUTHENTICATION_FAILED = 3,
+ QMI_OMA_SESSION_FAILED_REASON_MAX_RETRY_EXCEEDED = 4,
+ QMI_OMA_SESSION_FAILED_REASON_SESSION_CANCELLED = 5
+} QmiOmaSessionFailedReason;
+
+/**
+ * QmiOmaHfaFeatureDoneState:
+ * @QMI_OMA_HFA_FEATURE_DONE_STATE_NONE: None.
+ * @QMI_OMA_HFA_FEATURE_DONE_STATE_SUCCEEDED: Succeeded.
+ * @QMI_OMA_HFA_FEATURE_DONE_STATE_FAILED: Failed.
+ *
+ * HFA feature done state.
+ */
+typedef enum {
+ QMI_OMA_HFA_FEATURE_DONE_STATE_NONE = 0,
+ QMI_OMA_HFA_FEATURE_DONE_STATE_SUCCEEDED = 1,
+ QMI_OMA_HFA_FEATURE_DONE_STATE_FAILED = 2
+} QmiOmaHfaFeatureDoneState;
+
+#endif /* _LIBQMI_GLIB_QMI_ENUMS_OMA_H_ */
diff --git a/src/libqmi-glib/qmi-enums-pbm.h b/src/libqmi-glib/qmi-enums-pbm.h
new file mode 100644
index 0000000..2b10872
--- /dev/null
+++ b/src/libqmi-glib/qmi-enums-pbm.h
@@ -0,0 +1,112 @@
+/* -*- 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 Google Inc.
+ */
+
+#ifndef _LIBQMI_GLIB_QMI_ENUMS_PBM_H_
+#define _LIBQMI_GLIB_QMI_ENUMS_PBM_H_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+/**
+ * SECTION: qmi-enums-pbm
+ * @title: PBM enumerations and flags
+ *
+ * This section defines enumerations and flags used in the PBM service
+ * interface.
+ */
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI PBM Indication Register' indication */
+
+/**
+ * QmiPbmEventRegistrationFlag:
+ * @QMI_PBM_EVENT_REGISTRATION_FLAG_RECORD_UPDATE: Request indications when records are added/edited/deleted.
+ * @QMI_PBM_EVENT_REGISTRATION_FLAG_PHONEBOOK_READY: Request indications when phonebooks are ready.
+ * @QMI_PBM_EVENT_REGISTRATION_FLAG_EMERGENCY_NUMBER_LIST: Request indications when emergency numbers are changed.
+ * @QMI_PBM_EVENT_REGISTRATION_FLAG_HIDDEN_RECORD_STATUS: Request indications when hidden record status is changed.
+ * @QMI_PBM_EVENT_REGISTRATION_FLAG_AAS_UPDATE: Request indications when Additional number Alpha String records are added/edited/deleted.
+ * @QMI_PBM_EVENT_REGISTRATION_FLAG_GAS_UPDATE: Request indications when Grouping information Alpha String records are added/edited/deleted.
+ *
+ * Flags to use to register to phonebook indications.
+ */
+typedef enum {
+ QMI_PBM_EVENT_REGISTRATION_FLAG_RECORD_UPDATE = 1 << 0,
+ QMI_PBM_EVENT_REGISTRATION_FLAG_PHONEBOOK_READY = 1 << 1,
+ QMI_PBM_EVENT_REGISTRATION_FLAG_EMERGENCY_NUMBER_LIST = 1 << 2,
+ QMI_PBM_EVENT_REGISTRATION_FLAG_HIDDEN_RECORD_STATUS = 1 << 3,
+ QMI_PBM_EVENT_REGISTRATION_FLAG_AAS_UPDATE = 1 << 4,
+ QMI_PBM_EVENT_REGISTRATION_FLAG_GAS_UPDATE = 1 << 5,
+} QmiPbmEventRegistrationFlag;
+
+/*****************************************************************************/
+/* Helper enums for the 'Get Capabilities' request */
+
+/**
+ * QmiPbmPhonebookType:
+ * @QMI_PBM_PHONEBOOK_TYPE_ADN: Abbreviated Dialing Number.
+ * @QMI_PBM_PHONEBOOK_TYPE_FDN: Fixed Dialing Number.
+ * @QMI_PBM_PHONEBOOK_TYPE_MSISDN: Mobile Subscriber Integrated Services Digital Network.
+ * @QMI_PBM_PHONEBOOK_TYPE_MBDN: Mail Box Dialing Number.
+ * @QMI_PBM_PHONEBOOK_TYPE_SDN: Service Dialing Number.
+ * @QMI_PBM_PHONEBOOK_TYPE_BDN: Barred Dialing Number.
+ * @QMI_PBM_PHONEBOOK_TYPE_LND: Last Number Dialed.
+ * @QMI_PBM_PHONEBOOK_TYPE_MBN: Mail Box Number.
+ *
+ * Phonebook type.
+ */
+typedef enum {
+ QMI_PBM_PHONEBOOK_TYPE_ADN = 1 << 0,
+ QMI_PBM_PHONEBOOK_TYPE_FDN = 1 << 1,
+ QMI_PBM_PHONEBOOK_TYPE_MSISDN = 1 << 2,
+ QMI_PBM_PHONEBOOK_TYPE_MBDN = 1 << 3,
+ QMI_PBM_PHONEBOOK_TYPE_SDN = 1 << 4,
+ QMI_PBM_PHONEBOOK_TYPE_BDN = 1 << 5,
+ QMI_PBM_PHONEBOOK_TYPE_LND = 1 << 6,
+ QMI_PBM_PHONEBOOK_TYPE_MBN = 1 << 7,
+} QmiPbmPhonebookType;
+
+/**
+ * QmiPbmSessionType:
+ * @QMI_PBM_SESSION_TYPE_GW_PRIMARY: Access phonebooks under GSM DF (ICC) or USIM application (UICC).
+ * @QMI_PBM_SESSION_TYPE_1X_PRIMARY: Access phonebooks under CDMA DF (ICC) or CSIM application (UICC).
+ * @QMI_PBM_SESSION_TYPE_GW_SECONDARY: Access phonebooks under GSM DF (ICC) or USIM application (UICC). Dual standby.
+ * @QMI_PBM_SESSION_TYPE_1X_SECONDARY: Access phonebooks under CDMA DF (ICC) or CSIM application (UICC). Dual standby.
+ * @QMI_PBM_SESSION_TYPE_NONPROVISIONING_SLOT_1: Access phonebooks under a nonprovisioning application in slot 1.
+ * @QMI_PBM_SESSION_TYPE_NONPROVISIONING_SLOT_2: Access phonebooks under a nonprovisioning application in slot 2.
+ * @QMI_PBM_SESSION_TYPE_GLOBAL_PHONEBOOK_SLOT_1: Access phonebooks that are not in any application of the card in slot 1.
+ * @QMI_PBM_SESSION_TYPE_GLOBAL_PHONEBOOK_SLOT_2: Access phonebooks that are not in any application of the card in slot 2.
+ *
+ * Type of phonebook management session.
+ */
+typedef enum {
+ QMI_PBM_SESSION_TYPE_GW_PRIMARY = 0,
+ QMI_PBM_SESSION_TYPE_1X_PRIMARY = 1,
+ QMI_PBM_SESSION_TYPE_GW_SECONDARY = 2,
+ QMI_PBM_SESSION_TYPE_1X_SECONDARY = 3,
+ QMI_PBM_SESSION_TYPE_NONPROVISIONING_SLOT_1 = 4,
+ QMI_PBM_SESSION_TYPE_NONPROVISIONING_SLOT_2 = 5,
+ QMI_PBM_SESSION_TYPE_GLOBAL_PHONEBOOK_SLOT_1 = 6,
+ QMI_PBM_SESSION_TYPE_GLOBAL_PHONEBOOK_SLOT_2 = 7,
+} QmiPbmSessionType;
+
+#endif /* _LIBQMI_GLIB_QMI_ENUMS_PBM_H_ */
diff --git a/src/libqmi-glib/qmi-enums-pds.h b/src/libqmi-glib/qmi-enums-pds.h
new file mode 100644
index 0000000..c6382cc
--- /dev/null
+++ b/src/libqmi-glib/qmi-enums-pds.h
@@ -0,0 +1,154 @@
+/* -*- 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 Google Inc.
+ */
+
+#ifndef _LIBQMI_GLIB_QMI_ENUMS_PDS_H_
+#define _LIBQMI_GLIB_QMI_ENUMS_PDS_H_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+/**
+ * SECTION: qmi-enums-pds
+ * @title: PDS enumerations and flags
+ *
+ * This section defines enumerations and flags used in the PDS service
+ * interface.
+ */
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI PDS Event Report' indication */
+
+/**
+ * QmiPdsOperationMode:
+ * @QMI_PDS_OPERATION_MODE_UNKNOWN: Unknown (position not fixed yet).
+ * @QMI_PDS_OPERATION_MODE_STANDALONE: Standalone.
+ * @QMI_PDS_OPERATION_MODE_MS_BASED: MS based.
+ * @QMI_PDS_OPERATION_MODE_MS_ASSISTED: MS assisted.
+ *
+ * Operation mode used to compute the position.
+ */
+typedef enum {
+ QMI_PDS_OPERATION_MODE_UNKNOWN = -1,
+ QMI_PDS_OPERATION_MODE_STANDALONE = 0,
+ QMI_PDS_OPERATION_MODE_MS_BASED = 1,
+ QMI_PDS_OPERATION_MODE_MS_ASSISTED = 2
+} QmiPdsOperationMode;
+
+/**
+ * QmiPdsPositionSessionStatus:
+ * @QMI_PDS_POSITION_SESSION_STATUS_SUCCESS: Success.
+ * @QMI_PDS_POSITION_SESSION_STATUS_IN_PROGRESS: In progress.
+ * @QMI_PDS_POSITION_SESSION_STATUS_GENERAL_FAILURE: General failure.
+ * @QMI_PDS_POSITION_SESSION_STATUS_TIMEOUT: Timeout.
+ * @QMI_PDS_POSITION_SESSION_STATUS_USER_ENDED_SESSION: User ended session.
+ * @QMI_PDS_POSITION_SESSION_STATUS_BAD_PARAMETER: Bad parameter.
+ * @QMI_PDS_POSITION_SESSION_STATUS_PHONE_OFFLINE: Phone is offline.
+ * @QMI_PDS_POSITION_SESSION_STATUS_ENGINE_LOCKED: Engine locked.
+ * @QMI_PDS_POSITION_SESSION_STATUS_E911_SESSION_IN_PROGRESS: Emergency call in progress.
+ *
+ * Status of the positioning session.
+ */
+typedef enum {
+ QMI_PDS_POSITION_SESSION_STATUS_SUCCESS = 0x00,
+ QMI_PDS_POSITION_SESSION_STATUS_IN_PROGRESS = 0x01,
+ QMI_PDS_POSITION_SESSION_STATUS_GENERAL_FAILURE = 0x02,
+ QMI_PDS_POSITION_SESSION_STATUS_TIMEOUT = 0x03,
+ QMI_PDS_POSITION_SESSION_STATUS_USER_ENDED_SESSION = 0x04,
+ QMI_PDS_POSITION_SESSION_STATUS_BAD_PARAMETER = 0x05,
+ QMI_PDS_POSITION_SESSION_STATUS_PHONE_OFFLINE = 0x06,
+ QMI_PDS_POSITION_SESSION_STATUS_ENGINE_LOCKED = 0x07,
+ QMI_PDS_POSITION_SESSION_STATUS_E911_SESSION_IN_PROGRESS = 0x08
+} QmiPdsPositionSessionStatus;
+
+/**
+ * QmiPdsDataValid:
+ * @QMI_PDS_DATA_VALID_TIMESTAMP_CALENDAR: Timestamp calendar (GPS time).
+ * @QMI_PDS_DATA_VALID_TIMESTAMP_UTC: Timestamp (UTC).
+ * @QMI_PDS_DATA_VALID_LEAP_SECONDS: Leap seconds.
+ * @QMI_PDS_DATA_VALID_TIME_UNCERTAINTY: Time uncertainty.
+ * @QMI_PDS_DATA_VALID_LATITUDE: Latitude.
+ * @QMI_PDS_DATA_VALID_LONGITUDE: Longitude.
+ * @QMI_PDS_DATA_VALID_ELLIPSOID_ALTITUDE: Ellipsoid altitude.
+ * @QMI_PDS_DATA_VALID_MEAN_SEA_LEVEL_ALTITUDE: Mean sea level altitude.
+ * @QMI_PDS_DATA_VALID_HORIZONTAL_SPEED: Horizontal speed.
+ * @QMI_PDS_DATA_VALID_VERTICAL_SPEED: Vertical speed.
+ * @QMI_PDS_DATA_VALID_HEADING: Heading.
+ * @QMI_PDS_DATA_VALID_HORIZONTAL_UNCERTAINTY_CIRCULAR: Horizontal uncertainty circular.
+ * @QMI_PDS_DATA_VALID_HORIZONTAL_UNCERTAINTY_ELLIPSE_SEMI_MAJOR: Horizontal uncertainty ellipse semi-major.
+ * @QMI_PDS_DATA_VALID_HORIZONTAL_UNCERTAINTY_ELLIPSE_SEMI_MINOR: Horizontal uncertainty ellipse semi-minor.
+ * @QMI_PDS_DATA_VALID_HORIZONTAL_UNCERTAINTY_ELLIPSE_ORIENT_AZIMUTH: Horizontal uncertainty ellipse orient azimuth.
+ * @QMI_PDS_DATA_VALID_VERTICAL_UNCERTAINTY: Vertical uncertainty.
+ * @QMI_PDS_DATA_VALID_HORIZONTAL_VELOCITY_UNCERTAINTY: Horizontal velocity uncertainty.
+ * @QMI_PDS_DATA_VALID_VERTICAL_VELOCITY_UNCERTAINTY: Vertical velocity uncertainty.
+ * @QMI_PDS_DATA_VALID_HORIZONTAL_CONFIDENCE: Horizontal confidence.
+ * @QMI_PDS_DATA_VALID_POSITION_DOP: Position dillution of precision.
+ * @QMI_PDS_DATA_VALID_HORIZONTAL_DOP: Horizontal dillution of precision.
+ * @QMI_PDS_DATA_VALID_VERTICAL_DOP: Vertical dillution of precision.
+ * @QMI_PDS_DATA_VALID_OPERATING_MODE: Operating mode.
+ *
+ * Flags to indicate which position data parameters are valid.
+ */
+typedef enum {
+ QMI_PDS_DATA_VALID_TIMESTAMP_CALENDAR = 1 << 0,
+ QMI_PDS_DATA_VALID_TIMESTAMP_UTC = 1 << 1,
+ QMI_PDS_DATA_VALID_LEAP_SECONDS = 1 << 2,
+ QMI_PDS_DATA_VALID_TIME_UNCERTAINTY = 1 << 3,
+ QMI_PDS_DATA_VALID_LATITUDE = 1 << 4,
+ QMI_PDS_DATA_VALID_LONGITUDE = 1 << 5,
+ QMI_PDS_DATA_VALID_ELLIPSOID_ALTITUDE = 1 << 6,
+ QMI_PDS_DATA_VALID_MEAN_SEA_LEVEL_ALTITUDE = 1 << 7,
+ QMI_PDS_DATA_VALID_HORIZONTAL_SPEED = 1 << 8,
+ QMI_PDS_DATA_VALID_VERTICAL_SPEED = 1 << 9,
+ QMI_PDS_DATA_VALID_HEADING = 1 << 10,
+ QMI_PDS_DATA_VALID_HORIZONTAL_UNCERTAINTY_CIRCULAR = 1 << 11,
+ QMI_PDS_DATA_VALID_HORIZONTAL_UNCERTAINTY_ELLIPSE_SEMI_MAJOR = 1 << 12,
+ QMI_PDS_DATA_VALID_HORIZONTAL_UNCERTAINTY_ELLIPSE_SEMI_MINOR = 1 << 13,
+ QMI_PDS_DATA_VALID_HORIZONTAL_UNCERTAINTY_ELLIPSE_ORIENT_AZIMUTH = 1 << 14,
+ QMI_PDS_DATA_VALID_VERTICAL_UNCERTAINTY = 1 << 15,
+ QMI_PDS_DATA_VALID_HORIZONTAL_VELOCITY_UNCERTAINTY = 1 << 16,
+ QMI_PDS_DATA_VALID_VERTICAL_VELOCITY_UNCERTAINTY = 1 << 17,
+ QMI_PDS_DATA_VALID_HORIZONTAL_CONFIDENCE = 1 << 18,
+ QMI_PDS_DATA_VALID_POSITION_DOP = 1 << 19,
+ QMI_PDS_DATA_VALID_HORIZONTAL_DOP = 1 << 20,
+ QMI_PDS_DATA_VALID_VERTICAL_DOP = 1 << 21,
+ QMI_PDS_DATA_VALID_OPERATING_MODE = 1 << 22
+} QmiPdsDataValid;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI PDS Get GPS Service State' request/response */
+
+/**
+ * QmiPdsTrackingSessionState:
+ * @QMI_PDS_TRACKING_SESSION_STATE_UNKNOWN: Unknown state.
+ * @QMI_PDS_TRACKING_SESSION_STATE_INACTIVE: Session inactive.
+ * @QMI_PDS_TRACKING_SESSION_STATE_ACTIVE: Session active.
+ *
+ * State of the tracking session.
+ */
+typedef enum {
+ QMI_PDS_TRACKING_SESSION_STATE_UNKNOWN = 0,
+ QMI_PDS_TRACKING_SESSION_STATE_INACTIVE = 1,
+ QMI_PDS_TRACKING_SESSION_STATE_ACTIVE = 2
+} QmiPdsTrackingSessionState;
+
+#endif /* _LIBQMI_GLIB_QMI_ENUMS_PDS_H_ */
diff --git a/src/libqmi-glib/qmi-enums-private.h b/src/libqmi-glib/qmi-enums-private.h
new file mode 100644
index 0000000..21afead
--- /dev/null
+++ b/src/libqmi-glib/qmi-enums-private.h
@@ -0,0 +1,85 @@
+/* -*- 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 Google Inc.
+ */
+
+#ifndef _LIBQMI_GLIB_QMI_ENUMS_PRIVATE_H_
+#define _LIBQMI_GLIB_QMI_ENUMS_PRIVATE_H_
+
+/*****************************************************************************/
+/* QMI Control */
+
+/**
+ * QmiCtlDataFormat:
+ * @QMI_CTL_DATA_FORMAT_QOS_FLOW_HEADER_ABSENT: QoS header absent
+ * @QMI_CTL_DATA_FORMAT_QOS_FLOW_HEADER_PRESENT: QoS header present
+ *
+ * Controls whether the network port data format includes a QoS header or not.
+ * Should normally be set to ABSENT.
+ */
+typedef enum {
+ QMI_CTL_DATA_FORMAT_QOS_FLOW_HEADER_ABSENT = 0,
+ QMI_CTL_DATA_FORMAT_QOS_FLOW_HEADER_PRESENT = 1,
+} QmiCtlDataFormat;
+
+/**
+ * QmiCtlDataLinkProtocol:
+ * @QMI_CTL_DATA_LINK_PROTOCOL_802_3: data frames formatted as 802.3 Ethernet
+ * @QMI_CTL_DATA_LINK_PROTOCOL_RAW_IP: data frames are raw IP packets
+ *
+ * Determines the network port data format.
+ */
+typedef enum {
+ QMI_CTL_DATA_LINK_PROTOCOL_UNKNOWN = 0,
+ QMI_CTL_DATA_LINK_PROTOCOL_802_3 = 1,
+ QMI_CTL_DATA_LINK_PROTOCOL_RAW_IP = 2,
+} QmiCtlDataLinkProtocol;
+
+/**
+ * QmiCtlFlag:
+ * @QMI_CTL_FLAG_NONE: None.
+ * @QMI_CTL_FLAG_RESPONSE: Message is a response.
+ * @QMI_CTL_FLAG_INDICATION: Message is an indication.
+ *
+ * QMI flags in messages of the %QMI_SERVICE_CTL service.
+ */
+typedef enum {
+ QMI_CTL_FLAG_NONE = 0,
+ QMI_CTL_FLAG_RESPONSE = 1 << 0,
+ QMI_CTL_FLAG_INDICATION = 1 << 1
+} QmiCtlFlag;
+
+/**
+ * QmiServiceFlag:
+ * @QMI_SERVICE_FLAG_NONE: None.
+ * @QMI_SERVICE_FLAG_COMPOUND: Message is compound.
+ * @QMI_SERVICE_FLAG_RESPONSE: Message is a response.
+ * @QMI_SERVICE_FLAG_INDICATION: Message is an indication.
+ *
+ * QMI flags in messages which are not of the %QMI_SERVICE_CTL service.
+ */
+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_PRIVATE_H_ */
diff --git a/src/libqmi-glib/qmi-enums-uim.h b/src/libqmi-glib/qmi-enums-uim.h
new file mode 100644
index 0000000..ec89d31
--- /dev/null
+++ b/src/libqmi-glib/qmi-enums-uim.h
@@ -0,0 +1,124 @@
+/* -*- 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 Google Inc.
+ */
+
+#ifndef _LIBQMI_GLIB_QMI_ENUMS_UIM_H_
+#define _LIBQMI_GLIB_QMI_ENUMS_UIM_H_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+/**
+ * SECTION: qmi-enums-uim
+ * @title: UIM enumerations and flags
+ *
+ * This section defines enumerations and flags used in the UIM service
+ * interface.
+ */
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI UIM Read Record' request/response */
+
+/**
+ * QmiUimSessionType:
+ * @QMI_UIM_SESSION_TYPE_PRIMARY_GW_PROVISIONING: Primary GSM/WCDMA provisioning.
+ * @QMI_UIM_SESSION_TYPE_PRIMARY_1X_PROVISIONING: Primary CDMA1x provisioning.
+ * @QMI_UIM_SESSION_TYPE_SECONDARY_GW_PROVISIONING: Secondary GSM/WCDMA provisioning.
+ * @QMI_UIM_SESSION_TYPE_SECONDARY_1X_PROVISIONING: Secondary CDMA1x provisioning.
+ * @QMI_UIM_SESSION_TYPE_NONPROVISIONING_SLOT_1: Nonprovisioning on slot 1.
+ * @QMI_UIM_SESSION_TYPE_NONPROVISIONING_SLOT_2: Nonprovisioning on slot 2.
+ * @QMI_UIM_SESSION_TYPE_CARD_SLOT_1: Card on slot 1.
+ * @QMI_UIM_SESSION_TYPE_CARD_SLOT_2: Card on slot 2.
+ * @QMI_UIM_SESSION_TYPE_LOGICAL_CHANNEL_SLOT_1: Logical channel on slot 1.
+ * @QMI_UIM_SESSION_TYPE_LOGICAL_CHANNEL_SLOT_2: Logical channel on slot 2.
+ *
+ * Type of UIM session.
+ */
+typedef enum {
+ QMI_UIM_SESSION_TYPE_PRIMARY_GW_PROVISIONING = 0,
+ QMI_UIM_SESSION_TYPE_PRIMARY_1X_PROVISIONING = 1,
+ QMI_UIM_SESSION_TYPE_SECONDARY_GW_PROVISIONING = 2,
+ QMI_UIM_SESSION_TYPE_SECONDARY_1X_PROVISIONING = 3,
+ QMI_UIM_SESSION_TYPE_NONPROVISIONING_SLOT_1 = 4,
+ QMI_UIM_SESSION_TYPE_NONPROVISIONING_SLOT_2 = 5,
+ QMI_UIM_SESSION_TYPE_CARD_SLOT_1 = 6,
+ QMI_UIM_SESSION_TYPE_CARD_SLOT_2 = 7,
+ QMI_UIM_SESSION_TYPE_LOGICAL_CHANNEL_SLOT_1 = 8,
+ QMI_UIM_SESSION_TYPE_LOGICAL_CHANNEL_SLOT_2 = 9
+} QmiUimSessionType;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI UIM Get File Attributes' request/response */
+
+/**
+ * QmiUimFileType:
+ * @QMI_UIM_FILE_TYPE_TRANSPARENT: Transparent.
+ * @QMI_UIM_FILE_TYPE_CYCLIC: Cyclic.
+ * @QMI_UIM_FILE_TYPE_LINEAR_FIXED: Linear fixed.
+ * @QMI_UIM_FILE_TYPE_DEDICATED_FILE: Dedicated file.
+ * @QMI_UIM_FILE_TYPE_MASTER_FILE: Master file.
+ *
+ * Type of UIM file.
+ */
+typedef enum {
+ QMI_UIM_FILE_TYPE_TRANSPARENT = 0,
+ QMI_UIM_FILE_TYPE_CYCLIC = 1,
+ QMI_UIM_FILE_TYPE_LINEAR_FIXED = 2,
+ QMI_UIM_FILE_TYPE_DEDICATED_FILE = 3,
+ QMI_UIM_FILE_TYPE_MASTER_FILE = 4
+} QmiUimFileType;
+
+/**
+ * QmiUimSecurityAttributeLogic:
+ * @QMI_UIM_SECURITY_ATTRIBUTE_LOGIC_ALWAYS: Always.
+ * @QMI_UIM_SECURITY_ATTRIBUTE_LOGIC_NEVER: Never.
+ * @QMI_UIM_SECURITY_ATTRIBUTE_LOGIC_AND: And.
+ * @QMI_UIM_SECURITY_ATTRIBUTE_LOGIC_OR: Or.
+ * @QMI_UIM_SECURITY_ATTRIBUTE_LOGIC_SINGLE: Single.
+ *
+ * Logic applicable to security attributes.
+ */
+typedef enum {
+ QMI_UIM_SECURITY_ATTRIBUTE_LOGIC_ALWAYS = 0,
+ QMI_UIM_SECURITY_ATTRIBUTE_LOGIC_NEVER = 1,
+ QMI_UIM_SECURITY_ATTRIBUTE_LOGIC_AND = 2,
+ QMI_UIM_SECURITY_ATTRIBUTE_LOGIC_OR = 3,
+ QMI_UIM_SECURITY_ATTRIBUTE_LOGIC_SINGLE = 4
+} QmiUimSecurityAttributeLogic;
+
+/**
+ * QmiUimSecurityAttribute:
+ * @QMI_UIM_SECURITY_ATTRIBUTE_PIN1: PIN1.
+ * @QMI_UIM_SECURITY_ATTRIBUTE_PIN2: PIN2.
+ * @QMI_UIM_SECURITY_ATTRIBUTE_UPIN: UPIN.
+ * @QMI_UIM_SECURITY_ATTRIBUTE_ADM: ADM.
+ *
+ * Security Attributes.
+ */
+typedef enum {
+ QMI_UIM_SECURITY_ATTRIBUTE_PIN1 = 1 << 0,
+ QMI_UIM_SECURITY_ATTRIBUTE_PIN2 = 1 << 1,
+ QMI_UIM_SECURITY_ATTRIBUTE_UPIN = 1 << 2,
+ QMI_UIM_SECURITY_ATTRIBUTE_ADM = 1 << 3
+} QmiUimSecurityAttribute;
+
+#endif /* _LIBQMI_GLIB_QMI_ENUMS_UIM_H_ */
diff --git a/src/libqmi-glib/qmi-enums-wds.c b/src/libqmi-glib/qmi-enums-wds.c
new file mode 100644
index 0000000..8539271
--- /dev/null
+++ b/src/libqmi-glib/qmi-enums-wds.c
@@ -0,0 +1,53 @@
+/* -*- 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-enums-wds.h"
+#include "qmi-enum-types.h"
+
+const gchar *
+qmi_wds_verbose_call_end_reason_get_string (QmiWdsVerboseCallEndReasonType type,
+ gint16 reason)
+{
+ switch (type) {
+ case QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_MIP:
+ return qmi_wds_verbose_call_end_reason_mip_get_string ((QmiWdsVerboseCallEndReasonMip)reason);
+ case QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_INTERNAL:
+ return qmi_wds_verbose_call_end_reason_internal_get_string ((QmiWdsVerboseCallEndReasonInternal)reason);
+ case QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_CM:
+ return qmi_wds_verbose_call_end_reason_cm_get_string ((QmiWdsVerboseCallEndReasonCm)reason);
+ case QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_3GPP:
+ return qmi_wds_verbose_call_end_reason_3gpp_get_string ((QmiWdsVerboseCallEndReason3gpp)reason);
+ case QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_PPP:
+ return qmi_wds_verbose_call_end_reason_ppp_get_string ((QmiWdsVerboseCallEndReasonPpp)reason);
+ case QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_EHRPD:
+ return qmi_wds_verbose_call_end_reason_ehrpd_get_string ((QmiWdsVerboseCallEndReasonEhrpd)reason);
+ case QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_IPV6:
+ return qmi_wds_verbose_call_end_reason_ipv6_get_string ((QmiWdsVerboseCallEndReasonIpv6)reason);
+ default:
+ return NULL;
+ }
+}
diff --git a/src/libqmi-glib/qmi-enums-wds.h b/src/libqmi-glib/qmi-enums-wds.h
new file mode 100644
index 0000000..2bfc624
--- /dev/null
+++ b/src/libqmi-glib/qmi-enums-wds.h
@@ -0,0 +1,971 @@
+/* -*- 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_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+/**
+ * SECTION: qmi-enums-wds
+ * @title: WDS enumerations and flags
+ *
+ * This section defines enumerations and flags used in the WDS service
+ * interface.
+ */
+
+#include <glib.h>
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI WDS Start Network' message */
+
+/**
+ * QmiWdsIpFamily:
+ * @QMI_WDS_IP_FAMILY_IPV4: IPv4.
+ * @QMI_WDS_IP_FAMILY_IPV6: IPv6.
+ * @QMI_WDS_IP_FAMILY_UNSPECIFIED: None specified.
+ *
+ * Type of IP family preference.
+ */
+typedef enum {
+ QMI_WDS_IP_FAMILY_IPV4 = 4,
+ QMI_WDS_IP_FAMILY_IPV6 = 6,
+ QMI_WDS_IP_FAMILY_UNSPECIFIED = 8
+} QmiWdsIpFamily;
+
+/**
+ * QmiWdsTechnologyPreference:
+ * @QMI_WDS_TECHNOLOGY_PREFERENCE_ALLOW_3GPP: 3GPP allowed.
+ * @QMI_WDS_TECHNOLOGY_PREFERENCE_ALLOW_3GPP2: 3GPP2 allowed.
+ *
+ * Type of network allowed when trying to connect.
+ */
+typedef enum {
+ QMI_WDS_TECHNOLOGY_PREFERENCE_ALLOW_3GPP = 1 << 0,
+ QMI_WDS_TECHNOLOGY_PREFERENCE_ALLOW_3GPP2 = 1 << 1
+} QmiWdsTechnologyPreference;
+
+/**
+ * QmiWdsExtendedTechnologyPreference:
+ * @QMI_WDS_EXTENDED_TECHNOLOGY_PREFERENCE_CDMA: Use CDMA.
+ * @QMI_WDS_EXTENDED_TECHNOLOGY_PREFERENCE_UMTS: Use UMTS.
+ * @QMI_WDS_EXTENDED_TECHNOLOGY_PREFERENCE_EPC: Use EPC (LTE).
+ * @QMI_WDS_EXTENDED_TECHNOLOGY_PREFERENCE_EMBMS: Use eMBMS.
+ * @QMI_WDS_EXTENDED_TECHNOLOGY_PREFERENCE_MODEM_LINK_LOCAL: Use modem link-local.
+ *
+ * Type of network allowed when trying to connect.
+ */
+typedef enum {
+ QMI_WDS_EXTENDED_TECHNOLOGY_PREFERENCE_CDMA = 32769,
+ QMI_WDS_EXTENDED_TECHNOLOGY_PREFERENCE_UMTS = 32772,
+ QMI_WDS_EXTENDED_TECHNOLOGY_PREFERENCE_EPC = 34944,
+ QMI_WDS_EXTENDED_TECHNOLOGY_PREFERENCE_EMBMS = 34946,
+ QMI_WDS_EXTENDED_TECHNOLOGY_PREFERENCE_MODEM_LINK_LOCAL = 34952,
+} QmiWdsExtendedTechnologyPreference;
+
+/**
+ * QmiWdsCallType:
+ * @QMI_WDS_CALL_TYPE_LAPTOP: Laptop call.
+ * @QMI_WDS_CALL_TYPE_EMBEDDED: Embedded call.
+ *
+ * Type of call to originate.
+ */
+typedef enum {
+ QMI_WDS_CALL_TYPE_LAPTOP = 0,
+ QMI_WDS_CALL_TYPE_EMBEDDED = 1
+} QmiWdsCallType;
+
+/**
+ * QmiWdsCallEndReason:
+ * @QMI_WDS_CALL_END_REASON_GENERIC_UNSPECIFIED: Unspecified reason.
+ * @QMI_WDS_CALL_END_REASON_GENERIC_CLIENT_END: Client end.
+ * @QMI_WDS_CALL_END_REASON_GENERIC_NO_SERVICE: No service.
+ * @QMI_WDS_CALL_END_REASON_GENERIC_FADE: Fade.
+ * @QMI_WDS_CALL_END_REASON_GENERIC_RELEASE_NORMAL: Release normal.
+ * @QMI_WDS_CALL_END_REASON_GENERIC_ACCESS_ATTEMPT_IN_PROGRESS: Access attempt in progress.
+ * @QMI_WDS_CALL_END_REASON_GENERIC_ACCESS_FAILURE: Access Failure.
+ * @QMI_WDS_CALL_END_REASON_GENERIC_REDIRECTION_OR_HANDOFF: Redirection or handoff.
+ * @QMI_WDS_CALL_END_REASON_GENERIC_CLOSE_IN_PROGRESS: Close in progress.
+ * @QMI_WDS_CALL_END_REASON_GENERIC_AUTHENTICATION_FAILED: Authentication failed.
+ * @QMI_WDS_CALL_END_REASON_GENERIC_INTERNAL_ERROR: Internal error.
+ * @QMI_WDS_CALL_END_REASON_CDMA_LOCK: (CDMA) Phone is CDMA-locked.
+ * @QMI_WDS_CALL_END_REASON_CDMA_INTERCEPT: (CDMA) Received intercept from the BS.
+ * @QMI_WDS_CALL_END_REASON_CDMA_REORDER: (CDMA) Received reorder from the BS.
+ * @QMI_WDS_CALL_END_REASON_CDMA_RELEASE_SO_REJECT: (CDMA) Received release from the BS, SO reject.
+ * @QMI_WDS_CALL_END_REASON_CDMA_INCOMING_CALL: (CDMA) Received incoming call from the BS.
+ * @QMI_WDS_CALL_END_REASON_CDMA_ALERT_STOP: (CDMA) Received alert stop from the BS.
+ * @QMI_WDS_CALL_END_REASON_CDMA_ACTIVATION: (CDMA) Received end activation.
+ * @QMI_WDS_CALL_END_REASON_CDMA_MAX_ACCESS_PROBES: (CDMA) Maximum access probes transmitted.
+ * @QMI_WDS_CALL_END_REASON_CDMA_CCS_NOT_SUPPORTED_BY_BS: (CDMA) Concurrent service not supported by the BS.
+ * @QMI_WDS_CALL_END_REASON_CDMA_NO_RESPONSE_FROM_BS: (CDMA) No response received from the BS.
+ * @QMI_WDS_CALL_END_REASON_CDMA_REJECTED_BY_BS: (CDMA) Rejected by the BS.
+ * @QMI_WDS_CALL_END_REASON_CDMA_INCOMPATIBLE: (CDMA) Concurrent services requested are incompatible.
+ * @QMI_WDS_CALL_END_REASON_CDMA_ALREADY_IN_TC: (CDMA) Already in TC.
+ * @QMI_WDS_CALL_END_REASON_CDMA_USER_CALL_ORIGINATED_DURING_GPS: (CDMA) Call originated during GPS.
+ * @QMI_WDS_CALL_END_REASON_CDMA_USER_CALL_ORIGINATED_DURING_SMS: (CDMA) Call originated during SMS.
+ * @QMI_WDS_CALL_END_REASON_CDMA_NO_SERVICE: (CDMA) No service.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_CONFERENCE_FAILED: (GSM/WCDMA) Call origination request failed.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_INCOMING_REJECTED: (GSM/WCDMA) Client rejected incoming call.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_NO_SERVICE: (GSM/WCDMA) No service.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_NETWORK_END: (GSM/WCDMA) Network ended the call.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_LLC_SNDCP_FAILURE: (GSM/WCDMA) LLC or SNDCP failure.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_INSUFFICIENT_RESOURCES: (GSM/WCDMA) Insufficient resources.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_OPTION_TEMPORARILY_OUT_OF_ORDER: (GSM/WCDMA) Service option temporarily out of order.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_NSAPI_ALREADY_USED: (GSM/WCDMA) NSAPI already used.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_REGULAR_DEACTIVATION: (GSM/WCDMA) Regular PDP context deactivation.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_NETWORK_FAILURE: (GSM/WCDMA) Network failure.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_REATTACH_REQUIRED: (GSM/WCDMA) Reattach required.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_PROTOCOL_ERROR: (GSM/WCDMA) Protocol error.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_OPERATOR_DETERMINED_BARRING: (GSM/WCDMA) Operator-determined barring.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_UNKNOWN_APN: (GSM/WCDMA) Unknown or missing APN.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_UNKNOWN_PDP: (GSM/WCDMA) Unknown PDP address or type.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_GGSN_REJECT: (GSM/WCDMA) Activation rejected by GGSN.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_ACTIVATION_REJECT: (GSM/WCDMA) Activation rejected.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_OPTION_NOT_SUPPORTED: (GSM/WCDMA) Service option not supported.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_OPTION_UNSUBSCRIBED: (GSM/WCDMA) Service option not subscribed.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_QOS_NOT_ACCEPTED: (GSM/WCDMA) QoS not accepted.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_TFT_SEMANTIC_ERROR: (GSM/WCDMA) Semantic error in TFT operation.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_TFT_SYNTAX_ERROR: (GSM/WCDMA) Syntax error in TFT operation.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_UNKNOWN_PDP_CONTEXT: (GSM/WCDMA) Unknown PDP context.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_FILTER_SEMANTIC_ERROR: (GSM/WCDMA) Semantic error in packet filters.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_FILTER_SYNTAX_ERROR: (GSM/WCDMA) Syntax error in packet filters.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_PDP_WITHOUT_ACTIVE_TFT: (GSM/WCDMA) PDP context without TFT activated.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_INVALID_TRANSACTION_ID: (GSM/WCDMA) Invalid transaction ID.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_MESSAGE_INCORRECT_SEMANTIC: (GSM/WCDMA) Message incorrect semantically.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_INVALID_MANDATORY_INFO: (GSM/WCDMA) Invalid mandatory information.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_MESSAGE_TYPE_UNSUPPORTED: (GSM/WCDMA) Message type not implemented.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_MESSAGE_TYPE_NONCOMPATIBLE_STATE: (GSM/WCDMA) Message not compatible with state.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_UNKNOWN_INFO_ELEMENT: (GSM/WCDMA) Information element unknown.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_CONDITIONAL_IE_ERROR: (GSM/WCDMA) Conditional IE error.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_MESSAGE_AND_PROTOCOL_STATE_UNCOMPATIBLE: (GSM/WCDMA) Message and protocol state uncompatible.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_APN_TYPE_CONFLICT: (GSM/WCDMA) APN type conflict.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_NO_GPRS_CONTEXT: (GSM/WCDMA) No GPRS context.
+ * @QMI_WDS_CALL_END_REASON_GSM_WCDMA_FEATURE_NOT_SUPPORTED: (GSM/WCDMA) Feature not supported.
+ * @QMI_WDS_CALL_END_REASON_EVDO_CONNECTION_DENY_GENERAL_OR_BUSY: (EV-DO) Received Connection Deny (General or Network busy).
+ * @QMI_WDS_CALL_END_REASON_EVDO_CONNECTION_DENY_BILLING_OR_AUTHENTICATION_FAILURE: (EV-DO) Received Connection Deny (Billing or Authentication failure).
+ * @QMI_WDS_CALL_END_REASON_EVDO_HDR_CHANGE: (EV-DO) Change HDR.
+ * @QMI_WDS_CALL_END_REASON_EVDO_HDR_EXIT: (EV-DO) Exit HDR.
+ * @QMI_WDS_CALL_END_REASON_EVDO_HDR_NO_SESSION: (EV-DO) No HDR session.
+ * @QMI_WDS_CALL_END_REASON_EVDO_HDR_ORIGINATION_DURING_GPS_FIX: (EV-DO) HDR call ended in favor of a GPS fix.
+ * @QMI_WDS_CALL_END_REASON_EVDO_HDR_CONNECTION_SETUP_TIMEOUT: (EV-DO) Connection setup timeout.
+ * @QMI_WDS_CALL_END_REASON_EVDO_HDR_RELEASED_BY_CM: (EV-DO) Released HDR call by call manager.
+ *
+ * Reason for ending the call.
+ */
+typedef enum {
+ /* Generic reasons */
+ QMI_WDS_CALL_END_REASON_GENERIC_UNSPECIFIED = 1,
+ QMI_WDS_CALL_END_REASON_GENERIC_CLIENT_END = 2,
+ QMI_WDS_CALL_END_REASON_GENERIC_NO_SERVICE = 3,
+ QMI_WDS_CALL_END_REASON_GENERIC_FADE = 4,
+ QMI_WDS_CALL_END_REASON_GENERIC_RELEASE_NORMAL = 5,
+ QMI_WDS_CALL_END_REASON_GENERIC_ACCESS_ATTEMPT_IN_PROGRESS = 6,
+ QMI_WDS_CALL_END_REASON_GENERIC_ACCESS_FAILURE = 7,
+ QMI_WDS_CALL_END_REASON_GENERIC_REDIRECTION_OR_HANDOFF = 8,
+ QMI_WDS_CALL_END_REASON_GENERIC_CLOSE_IN_PROGRESS = 9,
+ QMI_WDS_CALL_END_REASON_GENERIC_AUTHENTICATION_FAILED = 10,
+ QMI_WDS_CALL_END_REASON_GENERIC_INTERNAL_ERROR = 11,
+
+ /* CDMA specific reasons */
+ QMI_WDS_CALL_END_REASON_CDMA_LOCK = 500,
+ QMI_WDS_CALL_END_REASON_CDMA_INTERCEPT = 501,
+ QMI_WDS_CALL_END_REASON_CDMA_REORDER = 502,
+ QMI_WDS_CALL_END_REASON_CDMA_RELEASE_SO_REJECT = 503,
+ QMI_WDS_CALL_END_REASON_CDMA_INCOMING_CALL = 504,
+ QMI_WDS_CALL_END_REASON_CDMA_ALERT_STOP = 505,
+ QMI_WDS_CALL_END_REASON_CDMA_ACTIVATION = 506,
+ QMI_WDS_CALL_END_REASON_CDMA_MAX_ACCESS_PROBES = 507,
+ QMI_WDS_CALL_END_REASON_CDMA_CCS_NOT_SUPPORTED_BY_BS = 508,
+ QMI_WDS_CALL_END_REASON_CDMA_NO_RESPONSE_FROM_BS = 509,
+ QMI_WDS_CALL_END_REASON_CDMA_REJECTED_BY_BS = 510,
+ QMI_WDS_CALL_END_REASON_CDMA_INCOMPATIBLE = 511,
+ QMI_WDS_CALL_END_REASON_CDMA_ALREADY_IN_TC = 512,
+ QMI_WDS_CALL_END_REASON_CDMA_USER_CALL_ORIGINATED_DURING_GPS = 513,
+ QMI_WDS_CALL_END_REASON_CDMA_USER_CALL_ORIGINATED_DURING_SMS = 514,
+ QMI_WDS_CALL_END_REASON_CDMA_NO_SERVICE = 515,
+
+ /* GSM/WCDMA specific reasons */
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_CONFERENCE_FAILED = 1000,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_INCOMING_REJECTED = 1001,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_NO_SERVICE = 1002,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_NETWORK_END = 1003,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_LLC_SNDCP_FAILURE = 1004,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_INSUFFICIENT_RESOURCES = 1005,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_OPTION_TEMPORARILY_OUT_OF_ORDER = 1006,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_NSAPI_ALREADY_USED = 1007,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_REGULAR_DEACTIVATION = 1008,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_NETWORK_FAILURE = 1009,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_REATTACH_REQUIRED = 1010,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_PROTOCOL_ERROR = 1011,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_OPERATOR_DETERMINED_BARRING = 1012,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_UNKNOWN_APN = 1013,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_UNKNOWN_PDP = 1014,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_GGSN_REJECT = 1015,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_ACTIVATION_REJECT = 1016,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_OPTION_NOT_SUPPORTED = 1017,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_OPTION_UNSUBSCRIBED = 1018,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_QOS_NOT_ACCEPTED = 1019,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_TFT_SEMANTIC_ERROR = 1020,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_TFT_SYNTAX_ERROR = 1021,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_UNKNOWN_PDP_CONTEXT = 1022,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_FILTER_SEMANTIC_ERROR = 1023,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_FILTER_SYNTAX_ERROR = 1024,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_PDP_WITHOUT_ACTIVE_TFT = 1025,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_INVALID_TRANSACTION_ID = 1026,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_MESSAGE_INCORRECT_SEMANTIC = 1027,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_INVALID_MANDATORY_INFO = 1028,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_MESSAGE_TYPE_UNSUPPORTED = 1029,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_MESSAGE_TYPE_NONCOMPATIBLE_STATE = 1030,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_UNKNOWN_INFO_ELEMENT = 1031,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_CONDITIONAL_IE_ERROR = 1032,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_MESSAGE_AND_PROTOCOL_STATE_UNCOMPATIBLE = 1033,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_APN_TYPE_CONFLICT = 1034,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_NO_GPRS_CONTEXT = 1035,
+ QMI_WDS_CALL_END_REASON_GSM_WCDMA_FEATURE_NOT_SUPPORTED = 1036,
+
+ /* EV-DO specific reasons */
+ QMI_WDS_CALL_END_REASON_EVDO_CONNECTION_DENY_GENERAL_OR_BUSY = 1500,
+ QMI_WDS_CALL_END_REASON_EVDO_CONNECTION_DENY_BILLING_OR_AUTHENTICATION_FAILURE = 1501,
+ QMI_WDS_CALL_END_REASON_EVDO_HDR_CHANGE = 1502,
+ QMI_WDS_CALL_END_REASON_EVDO_HDR_EXIT = 1503,
+ QMI_WDS_CALL_END_REASON_EVDO_HDR_NO_SESSION = 1504,
+ QMI_WDS_CALL_END_REASON_EVDO_HDR_ORIGINATION_DURING_GPS_FIX = 1505,
+ QMI_WDS_CALL_END_REASON_EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 1506,
+ QMI_WDS_CALL_END_REASON_EVDO_HDR_RELEASED_BY_CM = 1507
+} QmiWdsCallEndReason;
+
+/**
+ * QmiWdsVerboseCallEndReasonType:
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_MIP: Mobile IP.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_INTERNAL: Internal.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_CM: Call manager.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_3GPP: 3GPP.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_PPP: PPP.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_EHRPD: eHRPD.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_IPV6: IPv6.
+ *
+ * Type of verbose call end reason.
+ */
+typedef enum {
+ QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_MIP = 1,
+ QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_INTERNAL = 2,
+ QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_CM = 3,
+ QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_3GPP = 6,
+ QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_PPP = 7,
+ QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_EHRPD = 8,
+ QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_IPV6 = 9
+} QmiWdsVerboseCallEndReasonType;
+
+const gchar *qmi_wds_verbose_call_end_reason_get_string (QmiWdsVerboseCallEndReasonType type,
+ gint16 reason);
+
+/**
+ * QmiWdsVerboseCallEndReasonMip:
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_ERROR_REASON_UNKNOWN: Unknown reason.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_REASON_UNSPECIFIED: (FA error) Reason unspecified.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_ADMINISTRATIVELY_PROHIBITED: (FA error) Administratively prohibited.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_INSUFFICIENT_RESOURCES: (FA error) Insufficient resources.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MOBILE_NODE_AUTHENTICATION_FAILURE: (FA error) Mobile node authenticatin failure.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_HA_AUTHENTICATION_FAILURE: (FA error) HA authentication failure.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_REQUESTED_LIFETIME_TOO_LONG: (FA error) Requested lifetime too long.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MALFORMED_REQUEST: (FA error) Malformed request.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MALFORMED_REPLY: (FA error) Malformed reply.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_ENCAPSULATION_UNAVAILABLE: (FA error) Encapsulation unavailable.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_VJHC_UNAVAILABLE: (FA error) VJHC unavailable.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_REVERSE_TUNNEL_UNAVAILABLE: (FA error) Reverse tunnel unavailable.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_REVERSE_TUNNEL_MANDATORY_AND_T_BIT_NOT_SET: (FA error) Reverse tunnel mandatory and T bit not set.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_DELIVERY_STYLE_NOT_SUPPORTED: (FA error) Delivery style not supported.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MISSING_NAI: (FA error) Missing NAI.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MISSING_HA: (FA error) Missing HA.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MISSING_HOME_ADDRESS: (FA error) Missing home address.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_UNKNOWN_CHALLENGE: (FA error) Unknown challenge.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MISSING_CHALLENGE: (FA error) Missing challenge.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_STALE_CHALLENGE: (FA error) Stale challenge.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_REASON_UNSPECIFIED: (HA error) Reason unspecified.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_ADMINISTRATIVELY_PROHIBITED: (HA error) Administratively prohibited.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_INSUFFICIENT_RESOURCES: (HA error) Insufficient resources.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_MOBILE_NODE_AUTHENTICATION_FAILURE: (HA error) Mobile node authentication failure.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_FA_AUTHENTICATION_FAILURE: (HA error) FA authentication failure.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_REGISTRATION_ID_MISMATCH: (HA error) Registration ID mismatch.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_MALFORMED_REQUEST: (HA error) Malformed request.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_UNKNOWN_HA_ADDRESS: (HA error) Unknown HA address.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_REVERSE_TUNNEL_UNAVAILABLE: (HA error) Reverse tunnel unavailable.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_REVERSE_TUNNEL_MANDATORY_AND_T_BIT_NOT_SET: (HA error) Reverse tunnel mandatory and T bit not set.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_ENCAPSULATION_UNAVAILABLE: (HA error) Encapsulation unavailable.
+ *
+ * Mobile IP specific call end reasons, given when the @QmiWdsVerboseCallEndReasonType is #QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_MIP.
+ */
+typedef enum {
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_ERROR_REASON_UNKNOWN = -1,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_REASON_UNSPECIFIED = 64,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_ADMINISTRATIVELY_PROHIBITED = 65,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_INSUFFICIENT_RESOURCES = 66,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MOBILE_NODE_AUTHENTICATION_FAILURE = 67,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_HA_AUTHENTICATION_FAILURE = 68,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_REQUESTED_LIFETIME_TOO_LONG = 69,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MALFORMED_REQUEST = 70,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MALFORMED_REPLY = 71,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_ENCAPSULATION_UNAVAILABLE = 72,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_VJHC_UNAVAILABLE = 73,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_REVERSE_TUNNEL_UNAVAILABLE = 74,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_REVERSE_TUNNEL_MANDATORY_AND_T_BIT_NOT_SET = 75,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_DELIVERY_STYLE_NOT_SUPPORTED = 79,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MISSING_NAI = 97,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MISSING_HA = 98,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MISSING_HOME_ADDRESS = 99,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_UNKNOWN_CHALLENGE = 104,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_MISSING_CHALLENGE = 105,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_FA_ERROR_STALE_CHALLENGE = 106,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_REASON_UNSPECIFIED = 128,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_ADMINISTRATIVELY_PROHIBITED = 129,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_INSUFFICIENT_RESOURCES = 130,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_MOBILE_NODE_AUTHENTICATION_FAILURE = 131,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_FA_AUTHENTICATION_FAILURE = 132,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_REGISTRATION_ID_MISMATCH = 133,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_MALFORMED_REQUEST = 134,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_UNKNOWN_HA_ADDRESS = 136,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_REVERSE_TUNNEL_UNAVAILABLE = 137,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_REVERSE_TUNNEL_MANDATORY_AND_T_BIT_NOT_SET = 138,
+ QMI_WDS_VERBOSE_CALL_END_REASON_MIP_HA_ERROR_ENCAPSULATION_UNAVAILABLE = 139
+} QmiWdsVerboseCallEndReasonMip;
+
+/**
+ * QmiWdsVerboseCallEndReasonInternal:
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_ERROR: Internal error.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_CALL_ENDED: Call ended.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_UNKNOWN_INTERNAL_CAUSE: Unknown internal cause.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_UNKNOWN_CAUSE: Unknown cause.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_CLOSE_IN_PROGRESS: Close in progress.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_NETWORK_INITIATED_TERMINATION: Network initiated termination.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_APP_PREEMPTED: App preempted.
+ *
+ * Internal call end reasons, given when the @QmiWdsVerboseCallEndReasonType is #QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_INTERNAL.
+ */
+typedef enum {
+ QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_ERROR = 201,
+ QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_CALL_ENDED = 202,
+ QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_UNKNOWN_INTERNAL_CAUSE = 203,
+ QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_UNKNOWN_CAUSE = 204,
+ QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_CLOSE_IN_PROGRESS = 205,
+ QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_NETWORK_INITIATED_TERMINATION = 206,
+ QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_APP_PREEMPTED = 207
+} QmiWdsVerboseCallEndReasonInternal;
+
+/**
+ * QmiWdsVerboseCallEndReasonCm:
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CDMA_LOCK: (CDMA) Phone is CDMA-locked.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_INTERCEPT: (CDMA) Received intercept from the BS.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_REORDER: (CDMA) Received reorder from the BS.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_RELEASE_SO_REJECT: (CDMA) Received release from the BS, SO reject.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_INCOMING_CALL: (CDMA) Received incoming call from the BS.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ALERT_STOP: (CDMA) Received alert stop from the BS.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACTIVATION: (CDMA) Received end activation.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_MAX_ACCESS_PROBES: (CDMA) Maximum access probes transmitted.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CCS_NOT_SUPPORTED_BY_BS: (CDMA) Concurrent service not supported by the BS.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_RESPONSE_FROM_BS: (CDMA) No response received from the BS.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_REJECTED_BY_BS: (CDMA) Rejected by the BS.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_INCOMPATIBLE: (CDMA) Concurrent services requested are incompatible.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ALREADY_IN_TC: (CDMA) Already in TC.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_USER_CALL_ORIGINATED_DURING_GPS: (CDMA) Call originated during GPS.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_USER_CALL_ORIGINATED_DURING_SMS: (CDMA) Call originated during SMS.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_CDMA_SERVICE: (CDMA) No service.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_RETRY_ORDER: Retry order.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONFIGURATION_FAILED: Configuration failed.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_INCOMING_REJECTED: Incoming rejected.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_GATEWAY_SERVICE: No gateway service.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_GPRS_CONTEXT: No GPRS context.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ILLEGAL_MS: Illegal MS.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ILLEGAL_ME: Illegal ME.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_GPRS_AND_NON_GPRS_SERVICES_NOT_ALLOWED: GPRS and non GPRS services not allowed.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_GPRS_SERVICES_NOT_ALLOWED: GPRS services not allowed.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_MS_IDENTITY_NOT_DERIVED_BY_THE_NETWORK: MS identity not derived by the network.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_IMPLICITLY_DETACHED: Implicitly detached.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_PLMN_NOT_ALLOWED: PLMN not allowed.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LA_NOT_ALLOWED: LA not allowed.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_GPRS_SERVICES_NOT_ALLOWED_IN_PLMN: GPRS services not allowed in PLMN.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_PDP_DUPLICATE: PDP duplicate.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_UE_RAT_CHANGE: UE radio access technology change.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONGESTION: Congestion.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_PDP_CONTEXT_ACTIVATED: No PDP context activated.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_CLASS_DSAC_REJECTION: Access class DSAC rejection.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONNECTION_DENY_GENERAL_OR_BUSY: (EV-DO) Received Connection Deny (General or Network busy).
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONNECTION_DENY_BILLING_OR_AUTHENTICATION_FAILURE: (EV-DO) Received Connection Deny (Billing or Authentication failure).
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_CHANGE: (EV-DO) Change HDR.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_EXIT: (EV-DO) Exit HDR.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_NO_SESSION: (EV-DO) No HDR session.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_ORIGINATION_DURING_GPS_FIX: (EV-DO) HDR call ended in favor of a GPS fix.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_CONNECTION_SETUP_TIMEOUT: (EV-DO) Connection setup timeout.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_RELEASED_BY_CM: (EV-DO) Released HDR call by call manager.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_HYBRID_HDR_SERVICE: (EV-DO) No hybrid HDR service.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CLIENT_END: Client end.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_SERVICE: No service.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_FADE: Fade.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_RELEASE_NORMAL: Release normal.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_ATTEMPT_IN_PROGRESS: Access attempt in progress.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_FAILURE: Access Failure.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_REDIRECTION_OR_HANDOFF: Redirection or handoff.
+ *
+ * Call manager specific call end reasons, given when the @QmiWdsVerboseCallEndReasonType is #QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_CM.
+ */
+typedef enum {
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_CDMA_LOCK = 500,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_INTERCEPT = 501,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_REORDER = 502,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_RELEASE_SO_REJECT = 503,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_INCOMING_CALL = 504,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_ALERT_STOP = 505,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACTIVATION = 506,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_MAX_ACCESS_PROBES = 507,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_CCS_NOT_SUPPORTED_BY_BS = 508,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_RESPONSE_FROM_BS = 509,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_REJECTED_BY_BS = 510,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_INCOMPATIBLE = 511,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_ALREADY_IN_TC = 512,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_USER_CALL_ORIGINATED_DURING_GPS = 513,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_USER_CALL_ORIGINATED_DURING_SMS = 514,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_CDMA_SERVICE = 515,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_RETRY_ORDER = 519,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONFIGURATION_FAILED = 1000,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_INCOMING_REJECTED = 1001,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_GATEWAY_SERVICE = 1002,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_GPRS_CONTEXT = 1003,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_ILLEGAL_MS = 1004,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_ILLEGAL_ME = 1005,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_GPRS_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 1006,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_GPRS_SERVICES_NOT_ALLOWED = 1007,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_MS_IDENTITY_NOT_DERIVED_BY_THE_NETWORK = 1008,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_IMPLICITLY_DETACHED = 1009,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_PLMN_NOT_ALLOWED = 1010,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_LA_NOT_ALLOWED = 1011,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_GPRS_SERVICES_NOT_ALLOWED_IN_PLMN = 1012,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_PDP_DUPLICATE = 1013,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_UE_RAT_CHANGE = 1014,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONGESTION = 1015,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_PDP_CONTEXT_ACTIVATED = 1016,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_CLASS_DSAC_REJECTION = 1017,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONNECTION_DENY_GENERAL_OR_BUSY = 1500,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONNECTION_DENY_BILLING_OR_AUTHENTICATION_FAILURE = 1501,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_CHANGE = 1502,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_EXIT = 1503,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_NO_SESSION = 1504,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_ORIGINATION_DURING_GPS_FIX = 1505,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_CONNECTION_SETUP_TIMEOUT = 1506,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_RELEASED_BY_CM = 1507,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_HYBRID_HDR_SERVICE = 1510,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_CLIENT_END = 2000,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_SERVICE = 2001,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_FADE = 2002,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_RELEASE_NORMAL = 2003,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_ATTEMPT_IN_PROGRESS = 2004,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_FAILURE = 2005,
+ QMI_WDS_VERBOSE_CALL_END_REASON_CM_REDIRECTION_OR_HANDOFF = 2006
+} QmiWdsVerboseCallEndReasonCm;
+
+/**
+ * QmiWdsVerboseCallEndReason3gpp:
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_OPERATOR_DETERMINED_BARRING: Operator-determined barring.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_LLC_SNDCP_FAILURE: LLC or SNDCP failure.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_INSUFFICIENT_RESOURCES: Insufficient resources.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_UNKNOWN_APN: Unknown or missing APN.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_UNKNOWN_PDP: Unknown PDP address or type.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_AUTHENTICATION_FAILED: Authentication failed.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_GGSN_REJECT: Activation rejected by GGSN.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_ACTIVATION_REJECT: Activation rejected.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_OPTION_NOT_SUPPORTED: Service option not supported.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_OPTION_UNSUBSCRIBED: Service option not subscribed.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_OPTION_TEMPORARILY_OUT_OF_ORDER: Service option temporarily out of order.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_NSAPI_ALREADY_USED: NSAPI already used.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_REGULAR_DEACTIVATION: Regular PDP context deactivation.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_QOS_NOT_ACCEPTED: QoS not accepted.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_NETWORK_FAILURE: Network failure.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_REATTACH_REQUIRED: Reattach required.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_FEATURE_NOT_SUPPORTED: Feature not supported.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_TFT_SEMANTIC_ERROR: Semantic error in TFT operation.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_TFT_SYNTAX_ERROR: Syntax error in TFT operation.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_UNKNOWN_PDP_CONTEXT: Unknown PDP context.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_FILTER_SEMANTIC_ERROR: Semantic error in packet filters.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_FILTER_SYNTAX_ERROR: Syntax error in packet filters.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_PDP_WITHOUT_ACTIVE_TFT: PDP context without TFT activated.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_IPV4_ONLY_ALLOWED: IPv4 only allowed.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_IPV6_ONLY_ALLOWED: IPv6 only allowed.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_SINGLE_ADDRESS_BEARER_ONLY: Single address bearer only.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_ESM_INFO_NOT_RECEIVED: ESM information not received.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_PDN_CONNECTION_DOES_NOT_EXIST: PDN connection does not exist.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MULTIPLE_CONNECTION_TO_SAME_PDN_NOT_ALLOWED: Multiple connection to same PDN not allowed.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_INVALID_TRANSACTION_ID: Invalid transaction ID.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_INCORRECT_SEMANTIC: Message incorrect semantically.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_INVALID_MANDATORY_INFO: Invalid mandatory information.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_TYPE_UNSUPPORTED: Message type not implemented.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_TYPE_NONCOMPATIBLE_STATE: Message not compatible with state.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_UNKNOWN_INFO_ELEMENT: Information element unknown.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_CONDITIONAL_IE_ERROR: Conditional IE error.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_AND_PROTOCOL_STATE_UNCOMPATIBLE: Message and protocol state uncompatible.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_PROTOCOL_ERROR: Protocol error.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_APN_TYPE_CONFLICT: APN type conflict.
+ *
+ * 3GPP-specific call end reasons, given when the @QmiWdsVerboseCallEndReasonType is #QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_3GPP.
+ */
+typedef enum { /*< underscore_name=qmi_wds_verbose_call_end_reason_3gpp >*/
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_OPERATOR_DETERMINED_BARRING = 8,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_LLC_SNDCP_FAILURE = 25,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_INSUFFICIENT_RESOURCES = 26,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_UNKNOWN_APN = 27,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_UNKNOWN_PDP = 28,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_AUTHENTICATION_FAILED = 29,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_GGSN_REJECT = 30,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_ACTIVATION_REJECT = 31,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_OPTION_NOT_SUPPORTED = 32,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_OPTION_UNSUBSCRIBED = 33,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_OPTION_TEMPORARILY_OUT_OF_ORDER = 34,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_NSAPI_ALREADY_USED = 35,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_REGULAR_DEACTIVATION = 36,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_QOS_NOT_ACCEPTED = 37,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_NETWORK_FAILURE = 38,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_REATTACH_REQUIRED = 39,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_FEATURE_NOT_SUPPORTED = 40,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_TFT_SEMANTIC_ERROR = 41,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_TFT_SYNTAX_ERROR = 42,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_UNKNOWN_PDP_CONTEXT = 43,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_FILTER_SEMANTIC_ERROR = 44,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_FILTER_SYNTAX_ERROR = 45,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_PDP_WITHOUT_ACTIVE_TFT = 46,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_IPV4_ONLY_ALLOWED = 50,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_IPV6_ONLY_ALLOWED = 51,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_SINGLE_ADDRESS_BEARER_ONLY = 52,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_ESM_INFO_NOT_RECEIVED = 53,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_PDN_CONNECTION_DOES_NOT_EXIST = 54,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MULTIPLE_CONNECTION_TO_SAME_PDN_NOT_ALLOWED = 55,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_INVALID_TRANSACTION_ID = 81,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_INCORRECT_SEMANTIC = 95,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_INVALID_MANDATORY_INFO = 96,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_TYPE_UNSUPPORTED = 97,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_TYPE_NONCOMPATIBLE_STATE = 98,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_UNKNOWN_INFO_ELEMENT = 99,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_CONDITIONAL_IE_ERROR = 100,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_AND_PROTOCOL_STATE_UNCOMPATIBLE = 101,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_PROTOCOL_ERROR = 111,
+ QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_APN_TYPE_CONFLICT = 112
+} QmiWdsVerboseCallEndReason3gpp;
+
+/**
+ * QmiWdsVerboseCallEndReasonPpp:
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_PPP_UNKNOWN: Unknown error.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_PPP_TIMEOUT: Timeout.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_PPP_AUTHENTICATION_FAILURE: Authentication failure.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_PPP_OPTION_MISMATCH: Option mismatch.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_PPP_PAP_FAILURE: PAP failure.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_PPP_CHAP_FAILURE: CHAP failure.
+ *
+ * PPP-specific call end reasons, given when the @QmiWdsVerboseCallEndReasonType is #QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_PPP.
+ */
+typedef enum {
+ QMI_WDS_VERBOSE_CALL_END_REASON_PPP_UNKNOWN = -1,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_PPP_TIMEOUT = 1,
+ QMI_WDS_VERBOSE_CALL_END_REASON_PPP_AUTHENTICATION_FAILURE = 2,
+ QMI_WDS_VERBOSE_CALL_END_REASON_PPP_OPTION_MISMATCH = 3,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_PPP_PAP_FAILURE = 31,
+ QMI_WDS_VERBOSE_CALL_END_REASON_PPP_CHAP_FAILURE = 32
+} QmiWdsVerboseCallEndReasonPpp;
+
+/**
+ * QmiWdsVerboseCallEndReasonEhrpd:
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_SUBSCRIPTION_LIMITED_TO_IPV4: Subscription limited to IPv4.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_SUBSCRIPTION_LIMITED_TO_IPV6: Subscription limited to IPv6.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_TIMEOUT: (VSNCP) timeout.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_FAILURE: (VSNCP) failure.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_GENERAL_ERROR: (VSCNP) 3GPP2 general error.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_UNAUTHENTICATED_APN: (VSCNP) 3GPP2 unauthenticated APN.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_PDN_LIMIT_EXCEEDED: (VSCNP) 3GPP2 PDN limit exceeded.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_NO_PDN_GATEWAY: (VSCNP) 3GPP2 no PDN gateway.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_PDN_GATEWAY_UNREACHABLE: (VSCNP) 3GPP2 PDN gateway unreachable.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_PDN_GATEWAY_REJECTED: (VSCNP) 3GPP2 PDN gateway rejected.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_INSUFFICIENT_PARAMETERS: (VSCNP) 3GPP2 insufficient parameters.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_RESOURCE_UNAVAILABLE: (VSCNP) 3GPP2 resource unavailable.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_ADMINISTRATIVELY_PROHIBITED: (VSCNP) 3GPP2 administratively prohibited.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_PDN_ID_IN_USE: (VSCNP) 3GPP2 PDN ID in use.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_SUBSCRIPTION_LIMITATION: (VSCNP) 3GPP2 subscription limitation.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_PDN_EXISTS_FOR_THIS_APN: (VSCNP) 3GPP2 PDN exists for this APN.
+ *
+ * eHRPD-specific call end reasons, given when the @QmiWdsVerboseCallEndReasonType is #QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_EHRPD.
+ */
+typedef enum {
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_SUBSCRIPTION_LIMITED_TO_IPV4 = 1,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_SUBSCRIPTION_LIMITED_TO_IPV6 = 2,
+
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_TIMEOUT = 4,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_FAILURE = 5,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_GENERAL_ERROR = 6,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_UNAUTHENTICATED_APN = 7,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_PDN_LIMIT_EXCEEDED = 8,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_NO_PDN_GATEWAY = 9,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_PDN_GATEWAY_UNREACHABLE = 10,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_PDN_GATEWAY_REJECTED = 11,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_INSUFFICIENT_PARAMETERS = 12,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_RESOURCE_UNAVAILABLE = 13,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_ADMINISTRATIVELY_PROHIBITED = 14,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_PDN_ID_IN_USE = 15,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_SUBSCRIPTION_LIMITATION = 16,
+ QMI_WDS_VERBOSE_CALL_END_REASON_EHRPD_VSNCP_3GPP2_PDN_EXISTS_FOR_THIS_APN = 17
+} QmiWdsVerboseCallEndReasonEhrpd;
+
+/**
+ * QmiWdsVerboseCallEndReasonIpv6:
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_IPV6_PREFIX_UNAVAILABLE: Prefix unavailable.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_IPV6_HRPD_IPV6_DISABLED: HRDP IPv6 disabled.
+ *
+ * IPv6-specific call end reasons, given when the @QmiWdsVerboseCallEndReasonType is #QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_IPV6.
+ */
+typedef enum {
+ QMI_WDS_VERBOSE_CALL_END_REASON_IPV6_PREFIX_UNAVAILABLE = 1,
+ QMI_WDS_VERBOSE_CALL_END_REASON_IPV6_HRPD_IPV6_DISABLED = 2
+} QmiWdsVerboseCallEndReasonIpv6;
+
+/*****************************************************************************/
+/* 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_NONE: 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;
+
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI WDS Get Current Settings' message */
+
+/**
+ * QmiWdsGetCurrentSettingsRequestedSettings:
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_NONE: no settings requested
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PROFILE_ID: request profile ID
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PROFILE_NAME: request profile name
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PDP_TYPE: request PDP context type
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_APN_NAME: request APN name
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DNS_ADDRESS: request DNS server addresses
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GRANTED_QOS: request granted QoS
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_USERNAME: request username
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_AUTH_PROTOCOL: request authentication protocol (ie PAP/CHAP/none)
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_ADDRESS: request IP address
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GATEWAY_INFO: request gateway address
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PCSCF_ADDRESS: request PCSCF address
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PCSCF_SERVER_ADDRESS_LIST: request PCSCF server address list
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PCSCF_DOMAIN_NAME_LIST: request PCSCF domain name list
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_MTU: request MTU
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DOMAIN_NAME_LIST: request domain name list
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_FAMILY: request IP family (ie IPv4 or IPv6)
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IMCN_FLAG: request IMCN flag
+ * @QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_EXTENDED_TECHNOLOGY: request extended technology info
+ *
+ * Flags specifying which specific settings to return when requesting the
+ * current WDS bearer settings.
+ */
+typedef enum { /*< underscore_name=qmi_wds_get_current_settings_requested_settings >*/
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_NONE = 0,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PROFILE_ID = 1 << 0,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PROFILE_NAME = 1 << 1,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PDP_TYPE = 1 << 2,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_APN_NAME = 1 << 3,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DNS_ADDRESS = 1 << 4,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GRANTED_QOS = 1 << 5,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_USERNAME = 1 << 6,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_AUTH_PROTOCOL = 1 << 7,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_ADDRESS = 1 << 8,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GATEWAY_INFO = 1 << 9,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PCSCF_ADDRESS = 1 << 10,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PCSCF_SERVER_ADDRESS_LIST = 1 << 11,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PCSCF_DOMAIN_NAME_LIST = 1 << 12,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_MTU = 1 << 13,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DOMAIN_NAME_LIST = 1 << 14,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_FAMILY = 1 << 15,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IMCN_FLAG = 1 << 16,
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_EXTENDED_TECHNOLOGY = 1 << 17,
+} QmiWdsGetCurrentSettingsRequestedSettings;
+
+/**
+ * QmiWdsPdpType:
+ * @QMI_WDS_PDP_TYPE_IPV4: IPv4
+ * @QMI_WDS_PDP_TYPE_PPP: PPP
+ * @QMI_WDS_PDP_TYPE_IPV6: IPv6
+ * @QMI_WDS_PDP_TYPE_IPV4_OR_IPV6: IPv4 and IPv6 combined context
+ *
+ * PDP context type.
+ */
+typedef enum { /*< underscore_name=qmi_wds_pdp_type >*/
+ QMI_WDS_PDP_TYPE_IPV4 = 0,
+ QMI_WDS_PDP_TYPE_PPP = 1,
+ QMI_WDS_PDP_TYPE_IPV6 = 2,
+ QMI_WDS_PDP_TYPE_IPV4_OR_IPV6 = 3
+} QmiWdsPdpType;
+
+/**
+ * QmiWdsTrafficClass:
+ * @QMI_WDS_TRAFFIC_CLASS_SUBSCRIBED: default (?) class, best-effort
+ * @QMI_WDS_TRAFFIC_CLASS_CONVERSATIONAL: two-way video/voice, most delay sensitive
+ * @QMI_WDS_TRAFFIC_CLASS_STREAMING: one-way video/audio, delay sensitive
+ * @QMI_WDS_TRAFFIC_CLASS_INTERACTIVE: delay-insensitive (browsing, SSH)
+ * @QMI_WDS_TRAFFIC_CLASS_BACKGROUND: delay-insensitive (downloads, email)
+ *
+ * QoS Traffic Classes.
+ */
+typedef enum { /*< underscore_name=qmi_wds_traffic_class >*/
+ QMI_WDS_TRAFFIC_CLASS_SUBSCRIBED = 0,
+ QMI_WDS_TRAFFIC_CLASS_CONVERSATIONAL = 1,
+ QMI_WDS_TRAFFIC_CLASS_STREAMING = 2,
+ QMI_WDS_TRAFFIC_CLASS_INTERACTIVE = 3,
+ QMI_WDS_TRAFFIC_CLASS_BACKGROUND = 4
+} QmiWdsTrafficClass;
+
+/**
+ * QmiWdsAuthentication:
+ * @QMI_WDS_AUTHENTICATION_NONE: no authentication
+ * @QMI_WDS_AUTHENTICATION_PAP: PAP authentication
+ * @QMI_WDS_AUTHENTICATION_CHAP: CHAP authentication
+ *
+ * PDP context authentication protocols.
+ */
+typedef enum { /*< underscore_name=qmi_wds_authentication >*/
+ QMI_WDS_AUTHENTICATION_NONE = 0,
+ QMI_WDS_AUTHENTICATION_PAP = 1 << 0,
+ QMI_WDS_AUTHENTICATION_CHAP = 1 << 1
+} QmiWdsAuthentication;
+
+/**
+ * QmiWdsProfileType:
+ * @QMI_WDS_PROFILE_TYPE_3GPP: 3GPP profile type.
+ * @QMI_WDS_PROFILE_TYPE_3GPP2: 3GPP2 profile type.
+ *
+ * Profile network type family.
+ */
+typedef enum {
+ QMI_WDS_PROFILE_TYPE_3GPP = 0,
+ QMI_WDS_PROFILE_TYPE_3GPP2 = 1
+} QmiWdsProfileType;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI WDS Get Packet Statistics' message */
+
+/**
+ * QmiWdsPacketStatisticsMaskFlag:
+ * @QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_PACKETS_OK: Request count of correctly sent packets.
+ * @QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_PACKETS_OK: Request count of correctly received packets.
+ * @QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_PACKETS_ERROR: Request count of sent packets with error.
+ * @QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_PACKETS_ERROR: Request count of received packets with error.
+ * @QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_OVERFLOWS: Request count of transmitter overflows.
+ * @QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_OVERFLOWS: Request count of receiver overflows.
+ * @QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_BYTES_OK: Request count of correctly sent bytes.
+ * @QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_BYTES_OK: Request count of correctly received bytes.
+ * @QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_PACKETS_DROPPED: Request count of dropped packets in transmission.
+ * @QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_PACKETS_DROPPED: Request count of dropped packets in reception.
+ *
+ * Mask to use when requesting packet statistics.
+ */
+typedef enum {
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_PACKETS_OK = 1 << 0,
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_PACKETS_OK = 1 << 1,
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_PACKETS_ERROR = 1 << 2,
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_PACKETS_ERROR = 1 << 3,
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_OVERFLOWS = 1 << 4,
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_OVERFLOWS = 1 << 5,
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_BYTES_OK = 1 << 6,
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_BYTES_OK = 1 << 7,
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_PACKETS_DROPPED = 1 << 8,
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_PACKETS_DROPPED = 1 << 9
+} QmiWdsPacketStatisticsMaskFlag;
+
+#endif /* _LIBQMI_GLIB_QMI_ENUMS_WDS_H_ */
diff --git a/src/libqmi-glib/qmi-enums-wms.h b/src/libqmi-glib/qmi-enums-wms.h
new file mode 100644
index 0000000..d2df5bc
--- /dev/null
+++ b/src/libqmi-glib/qmi-enums-wms.h
@@ -0,0 +1,429 @@
+/* -*- 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 Google Inc.
+ */
+
+#ifndef _LIBQMI_GLIB_QMI_ENUMS_WMS_H_
+#define _LIBQMI_GLIB_QMI_ENUMS_WMS_H_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+/**
+ * SECTION: qmi-enums-wms
+ * @title: WMS enumerations and flags
+ *
+ * This section defines enumerations and flags used in the WMS service
+ * interface.
+ */
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI WMS Event Report' indication */
+
+/**
+ * QmiWmsStorageType:
+ * @QMI_WMS_STORAGE_TYPE_UIM: Message stored in UIM.
+ * @QMI_WMS_STORAGE_TYPE_NV: Message stored in non-volatile memory.
+ * @QMI_WMS_STORAGE_TYPE_NONE: None.
+ *
+ * Type of messaging storage
+ */
+typedef enum {
+ QMI_WMS_STORAGE_TYPE_UIM = 0x00,
+ QMI_WMS_STORAGE_TYPE_NV = 0x01,
+ QMI_WMS_STORAGE_TYPE_NONE = 0xFF
+} QmiWmsStorageType;
+
+/**
+ * QmiWmsAckIndicator:
+ * @QMI_WMS_ACK_INDICATOR_SEND: ACK needs to be sent.
+ * @QMI_WMS_ACK_INDICATOR_DO_NOT_SEND: ACK doesn't need to be sent.
+ *
+ * Indication of whether ACK needs to be sent or not.
+ */
+typedef enum {
+ QMI_WMS_ACK_INDICATOR_SEND = 0x00,
+ QMI_WMS_ACK_INDICATOR_DO_NOT_SEND = 0x01
+} QmiWmsAckIndicator;
+
+/**
+ * QmiWmsMessageFormat:
+ * @QMI_WMS_MESSAGE_FORMAT_CDMA: CDMA message.
+ * @QMI_WMS_MESSAGE_FORMAT_GSM_WCDMA_POINT_TO_POINT: Point-to-point 3GPP message.
+ * @QMI_WMS_MESSAGE_FORMAT_GSM_WCDMA_BROADCAST: Broadcast 3GPP message.
+ * @QMI_WMS_MESSAGE_FORMAT_MWI: Message Waiting Indicator.
+ *
+ * Type of message.
+ */
+typedef enum {
+ QMI_WMS_MESSAGE_FORMAT_CDMA = 0x00,
+ QMI_WMS_MESSAGE_FORMAT_GSM_WCDMA_POINT_TO_POINT = 0x06,
+ QMI_WMS_MESSAGE_FORMAT_GSM_WCDMA_BROADCAST = 0x07,
+ QMI_WMS_MESSAGE_FORMAT_MWI = 0x08
+} QmiWmsMessageFormat;
+
+/**
+ * QmiWmsMessageMode:
+ * @QMI_WMS_MESSAGE_MODE_CDMA: Message sent using 3GPP2 technologies.
+ * @QMI_WMS_MESSAGE_MODE_GSM_WCDMA: Message sent using 3GPP technologies.
+ *
+ * Message mode.
+ */
+typedef enum {
+ QMI_WMS_MESSAGE_MODE_CDMA = 0x00,
+ QMI_WMS_MESSAGE_MODE_GSM_WCDMA = 0x01
+} QmiWmsMessageMode;
+
+/**
+ * QmiWmsNotificationType:
+ * @QMI_WMS_NOTIFICATION_TYPE_PRIMARY: Primary.
+ * @QMI_WMS_NOTIFICATION_TYPE_SECONDARY_GSM: Secondary GSM.
+ * @QMI_WMS_NOTIFICATION_TYPE_SECONDARY_UMTS: Secondary UMTS.
+ *
+ * Type of notification.
+ */
+typedef enum {
+ QMI_WMS_NOTIFICATION_TYPE_PRIMARY = 0x00,
+ QMI_WMS_NOTIFICATION_TYPE_SECONDARY_GSM = 0x01,
+ QMI_WMS_NOTIFICATION_TYPE_SECONDARY_UMTS = 0x02
+} QmiWmsNotificationType;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI WMS Raw Send' request/response */
+
+/**
+ * QmiWmsCdmaServiceOption:
+ * @QMI_WMS_CDMA_SERVICE_OPTION_AUTO: Automatic selection of service option.
+ * @QMI_WMS_CDMA_SERVICE_OPTION_6: Use service option 6.
+ * @QMI_WMS_CDMA_SERVICE_OPTION_14: Use service option 14.
+ *
+ * CDMA service option selection.
+ */
+typedef enum {
+ QMI_WMS_CDMA_SERVICE_OPTION_AUTO = 0x00,
+ QMI_WMS_CDMA_SERVICE_OPTION_6 = 0x06,
+ QMI_WMS_CDMA_SERVICE_OPTION_14 = 0x0E
+} QmiWmsCdmaServiceOption;
+
+/**
+ * QmiWmsCdmaCauseCode:
+ * @QMI_WDS_CDMA_CAUSE_CODE_NETWORK_ADDRESS_VACANT: Address is valid but not yet allocated.
+ * @QMI_WDS_CDMA_CAUSE_CODE_NETWORK_ADDRESS_TRANSLATION_FAILURE: Address is invalid.
+ * @QMI_WDS_CDMA_CAUSE_CODE_NETWORK_RESOURCE_SHORTAGE: Network resource shortage.
+ * @QMI_WDS_CDMA_CAUSE_CODE_NETWORK_FAILURE: Network failed.
+ * @QMI_WDS_CDMA_CAUSE_CODE_NETWORK_INVALID_TELESERVICE_ID: SMS teleservice ID is invalid.
+ * @QMI_WDS_CDMA_CAUSE_CODE_NETWORK_OTHER: Other network error.
+ * @QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_NO_PAGE_RESPONSE: No page response from destination.
+ * @QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_BUSY: Destination is busy.
+ * @QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_NO_ACK: No acknowledge from destination.
+ * @QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_RESOURCE_SHORTAGE: Destination resource shortage.
+ * @QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_SMS_DELIVERY_POSTPONED: SMS deliver postponed.
+ * @QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_OUT_OF_SERVICE: Destination out of service.
+ * @QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_NOT_AT_ADDRESS: Destination not at address.
+ * @QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_OTHER: Other destination error.
+ * @QMI_WDS_CDMA_CAUSE_CODE_RADIO_INTERFACE_RESOURCE_SHORTAGE: Radio interface resource shortage.
+ * @QMI_WDS_CDMA_CAUSE_CODE_RADIO_INTERFACE_INCOMPATIBILITY: Radio interface incompatibility.
+ * @QMI_WDS_CDMA_CAUSE_CODE_RADIO_INTERFACE_OTHER: Other radio interface error.
+ * @QMI_WDS_CDMA_CAUSE_CODE_GENERAL_ENCODING: Encoding error.
+ * @QMI_WDS_CDMA_CAUSE_CODE_GENERAL_SMS_ORIGIN_DENIED: SMS origin denied.
+ * @QMI_WDS_CDMA_CAUSE_CODE_GENERAL_SMS_DESTINATION_DENIED: SMS destination denied.
+ * @QMI_WDS_CDMA_CAUSE_CODE_GENERAL_SUPPLEMENTARY_SERVICE_NOT_SUPPORTED: Supplementary service not supported.
+ * @QMI_WDS_CDMA_CAUSE_CODE_GENERAL_SMS_NOT_SUPPORTED: SMS not supported.
+ * @QMI_WDS_CDMA_CAUSE_CODE_GENERAL_MISSING_EXPECTED_PARAMETER: Missing optional expected parameter.
+ * @QMI_WDS_CDMA_CAUSE_CODE_GENERAL_MISSING_MANDATORY_PARAMETER: Missing mandatory parameter.
+ * @QMI_WDS_CDMA_CAUSE_CODE_GENERAL_UNRECOGNIZED_PARAMETER_VALUE: Unrecognized parameter value.
+ * @QMI_WDS_CDMA_CAUSE_CODE_GENERAL_UNEXPECTED_PARAMETER_VALUE: Unexpected parameter value.
+ * @QMI_WDS_CDMA_CAUSE_CODE_GENERAL_USER_DATA_SIZE_ERROR: user data size error.
+ * @QMI_WDS_CDMA_CAUSE_CODE_GENERAL_OTHER: Other general error.
+ *
+ * Cause codes when failed to send an SMS in CDMA.
+ */
+typedef enum {
+ /* Network errors */
+ QMI_WDS_CDMA_CAUSE_CODE_NETWORK_ADDRESS_VACANT = 0x00,
+ QMI_WDS_CDMA_CAUSE_CODE_NETWORK_ADDRESS_TRANSLATION_FAILURE = 0x01,
+ QMI_WDS_CDMA_CAUSE_CODE_NETWORK_RESOURCE_SHORTAGE = 0x02,
+ QMI_WDS_CDMA_CAUSE_CODE_NETWORK_FAILURE = 0x03,
+ QMI_WDS_CDMA_CAUSE_CODE_NETWORK_INVALID_TELESERVICE_ID = 0x04,
+ QMI_WDS_CDMA_CAUSE_CODE_NETWORK_OTHER = 0x05,
+
+ /* Destination errors */
+ QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_NO_PAGE_RESPONSE = 0x20,
+ QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_BUSY = 0x21,
+ QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_NO_ACK = 0x22,
+ QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_RESOURCE_SHORTAGE = 0x23,
+ QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_SMS_DELIVERY_POSTPONED = 0x24,
+ QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_OUT_OF_SERVICE = 0x25,
+ QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_NOT_AT_ADDRESS = 0x26,
+ QMI_WDS_CDMA_CAUSE_CODE_DESTINATION_OTHER = 0x27,
+
+ /* Radio Interface errors */
+ QMI_WDS_CDMA_CAUSE_CODE_RADIO_INTERFACE_RESOURCE_SHORTAGE = 0x40,
+ QMI_WDS_CDMA_CAUSE_CODE_RADIO_INTERFACE_INCOMPATIBILITY = 0x41,
+ QMI_WDS_CDMA_CAUSE_CODE_RADIO_INTERFACE_OTHER = 0x42,
+
+ /* General errors */
+ QMI_WDS_CDMA_CAUSE_CODE_GENERAL_ENCODING = 0x60,
+ QMI_WDS_CDMA_CAUSE_CODE_GENERAL_SMS_ORIGIN_DENIED = 0x61,
+ QMI_WDS_CDMA_CAUSE_CODE_GENERAL_SMS_DESTINATION_DENIED = 0x62,
+ QMI_WDS_CDMA_CAUSE_CODE_GENERAL_SUPPLEMENTARY_SERVICE_NOT_SUPPORTED = 0x63,
+ QMI_WDS_CDMA_CAUSE_CODE_GENERAL_SMS_NOT_SUPPORTED = 0x64,
+ QMI_WDS_CDMA_CAUSE_CODE_GENERAL_MISSING_EXPECTED_PARAMETER = 0x65,
+ QMI_WDS_CDMA_CAUSE_CODE_GENERAL_MISSING_MANDATORY_PARAMETER = 0x66,
+ QMI_WDS_CDMA_CAUSE_CODE_GENERAL_UNRECOGNIZED_PARAMETER_VALUE = 0x67,
+ QMI_WDS_CDMA_CAUSE_CODE_GENERAL_UNEXPECTED_PARAMETER_VALUE = 0x68,
+ QMI_WDS_CDMA_CAUSE_CODE_GENERAL_USER_DATA_SIZE_ERROR = 0x69,
+ QMI_WDS_CDMA_CAUSE_CODE_GENERAL_OTHER = 0x6A
+} QmiWmsCdmaCauseCode;
+
+/**
+ * QmiWmsCdmaErrorClass:
+ * @QMI_WMS_CDMA_ERROR_CLASS_TEMPORARY: Temporary error.
+ * @QMI_WMS_CDMA_ERROR_CLASS_PERMANENT: Permanent error.
+ *
+ * Error class when failed to send an SMS in CDMA.
+ */
+typedef enum {
+ QMI_WMS_CDMA_ERROR_CLASS_TEMPORARY = 0x00,
+ QMI_WMS_CDMA_ERROR_CLASS_PERMANENT = 0x01
+} QmiWmsCdmaErrorClass;
+
+/**
+ * QmiWmsGsmUmtsRpCause:
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_UNASSIGNED_NUMBER: Unassigned number.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_OPERATOR_DETERMINED_BARRING: Operator determined barring.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_CALL_BARRED: Call barred.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_RESERVED: Reserved.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_SMS_TRANSFER_REJECTED: SMS transfer rejected.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_MEMORY_CAPACITY_EXCEEDED: Memory capacity exceeded.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_DESTINATION_OUT_OF_ORDER: Destination out of order.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_UNIDENTIFIED_SUBSCRIBER: Unidentified subscriber.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_FACILITY_REJECTED: Facility rejected.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_UNKNOWN_SUBSCRIBER: Unknown subscriber.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_NETWORK_OUF_OF_ORDER: Network out of order.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_TEMPORARY_FAILURE: Temporary failure.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_CONGESTION: Congestion.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_RESOURCES_UNAVAILABLE: Resources unavailable.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_FACILITY_NOT_SUBSCRIBED: Facility not subscribed.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_FACILITY_NOT_IMPLEMENTED: Facility not implemented.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_INVALID_SMS_TRANSFER_REFERENCE_VALUE: Invalid SMS transfer reference value.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE: Semantically incorrect message.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_INVALID_MANDATORY_INFO: Invalid mandatory info.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_MESSAGE_TYPE_NOT_IMPLEMENTED: Message type not implemented.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_SMS: Message not compatible with SMS.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_INFORMATION_ELEMENT_NOT_IMPLEMENTED: Information element not implemented.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_PROTOCOL_ERROR: Protocol error.
+ * @QMI_WMS_GSM_UMTS_RP_CAUSE_INTERWORKING: Interworking error.
+ *
+ * RP cause codes when failed to send an SMS in GSM/WCDMA.
+ */
+typedef enum {
+ QMI_WMS_GSM_UMTS_RP_CAUSE_UNASSIGNED_NUMBER = 0x01,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_OPERATOR_DETERMINED_BARRING = 0x08,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_CALL_BARRED = 0x0A,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_RESERVED = 0x0B,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_SMS_TRANSFER_REJECTED = 0x15,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_MEMORY_CAPACITY_EXCEEDED = 0x16,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_DESTINATION_OUT_OF_ORDER = 0x1B,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_UNIDENTIFIED_SUBSCRIBER = 0x1C,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_FACILITY_REJECTED = 0x1D,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_UNKNOWN_SUBSCRIBER = 0x1E,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_NETWORK_OUF_OF_ORDER = 0x20,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_TEMPORARY_FAILURE = 0x21,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_CONGESTION = 0x2A,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_RESOURCES_UNAVAILABLE = 0x2F,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_FACILITY_NOT_SUBSCRIBED = 0x32,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_FACILITY_NOT_IMPLEMENTED = 0x45,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_INVALID_SMS_TRANSFER_REFERENCE_VALUE = 0x51,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE = 0x5F,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_INVALID_MANDATORY_INFO = 0x60,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_MESSAGE_TYPE_NOT_IMPLEMENTED = 0x61,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_SMS = 0x62,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_INFORMATION_ELEMENT_NOT_IMPLEMENTED = 0x63,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_PROTOCOL_ERROR = 0x6F,
+ QMI_WMS_GSM_UMTS_RP_CAUSE_INTERWORKING = 0x7F
+} QmiWmsGsmUmtsRpCause;
+
+/**
+ * QmiWmsGsmUmtsTpCause:
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_TELE_INTERWORKING_NOT_SUPPORTED: Tele interworking not supported.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_SHORT_MESSAGE_TYPE_0_NOT_SUPPORTED: Short message type 0 not supported.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_SHORT_MESSAGE_CANNOT_BE_REPLACED: Short message cannot be replaced.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_UNSPECIFIED_PID_ERROR: Unspecified TP-PID error.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_DCS_NOT_SUPPORTED: Data coding scheme not supported.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_MESSAGE_CLASS_NOT_SUPPORTED: Message class not supported.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_UNSPECIFIED_DCS_ERROR: Unspecified data coding scheme error.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_COMMAND_CANNOT_BE_ACTIONED: Command cannot be actioned.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_COMMAND_UNSUPPORTED: Command unsupported.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_UNSPECIFIED_COMMAND_ERROR: Unspecified command error.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_TPDU_NOT_SUPPORTED: TPDU not supported.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_SC_BUSY: SC busy.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_NO_SC_SUBSCRIPTION: No SC subscription.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_SC_SYSTEM_FAILURE: SC system failure.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_INVALID_SME_ADDRESS: Invalid SME address.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_DESTINATION_SME_BARRED: Destination SME barred.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_SM_REJECTED_OR_DUPLICATE: SM rejected or duplicate.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_VPF_NOT_SUPPORTED: TP-VPF not supported.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_VP_NOT_SUPPORTED: TP-VP not supported.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_SIM_SMS_STORAGE_FULL: SIM SMS storage full.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_NO_SMS_STORAGE_CAPABILITY_IN_SIM: No SMS storage capability in SIM.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_MS_ERROR: MS error.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_MEMORY_CAPACITY_EXCEEDED: Memory capacity exceeded.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_SIM_APPLICATION_TOOLKIT_BUSY: SIM application toolkit busy.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_SIM_DATA_DOWNLOAD_ERROR: SIM data download error.
+ * @QMI_WMS_GSM_UMTS_TP_CAUSE_UNSPECIFIED_ERROR: Unspecified error.
+ *
+ * RT cause codes when failed to send an SMS in GSM/WCDMA.
+ */
+typedef enum {
+ QMI_WMS_GSM_UMTS_TP_CAUSE_TELE_INTERWORKING_NOT_SUPPORTED = 0x80,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_SHORT_MESSAGE_TYPE_0_NOT_SUPPORTED = 0x81,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_SHORT_MESSAGE_CANNOT_BE_REPLACED = 0x82,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_UNSPECIFIED_PID_ERROR = 0x8F,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_DCS_NOT_SUPPORTED = 0x90,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_MESSAGE_CLASS_NOT_SUPPORTED = 0x91,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_UNSPECIFIED_DCS_ERROR = 0x9F,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_COMMAND_CANNOT_BE_ACTIONED = 0xA0,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_COMMAND_UNSUPPORTED = 0xA1,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_UNSPECIFIED_COMMAND_ERROR = 0xAF,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_TPDU_NOT_SUPPORTED = 0xB0,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_SC_BUSY = 0xC0,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_NO_SC_SUBSCRIPTION = 0xC1,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_SC_SYSTEM_FAILURE = 0xC2,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_INVALID_SME_ADDRESS = 0xC3,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_DESTINATION_SME_BARRED = 0xC4,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_SM_REJECTED_OR_DUPLICATE = 0xC5,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_VPF_NOT_SUPPORTED = 0xC6,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_VP_NOT_SUPPORTED = 0xC7,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_SIM_SMS_STORAGE_FULL = 0xD0,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_NO_SMS_STORAGE_CAPABILITY_IN_SIM = 0xD1,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_MS_ERROR = 0xD2,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_MEMORY_CAPACITY_EXCEEDED = 0xD3,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_SIM_APPLICATION_TOOLKIT_BUSY = 0xD4,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_SIM_DATA_DOWNLOAD_ERROR = 0xD5,
+ QMI_WMS_GSM_UMTS_TP_CAUSE_UNSPECIFIED_ERROR = 0xFF
+} QmiWmsGsmUmtsTpCause;
+
+/**
+ * QmiWmsMessageDeliveryFailureType:
+ * @QMI_WMS_MESSAGE_DELIVERY_FAILURE_TYPE_TEMPORARY: Temporary failure.
+ * @QMI_WMS_MESSAGE_DELIVERY_FAILURE_TYPE_PERMANENT: Permanent failure.
+ *
+ * Type of message delivery failure.
+ */
+typedef enum {
+ QMI_WMS_MESSAGE_DELIVERY_FAILURE_TYPE_TEMPORARY = 0x00,
+ QMI_WMS_MESSAGE_DELIVERY_FAILURE_TYPE_PERMANENT = 0x01
+} QmiWmsMessageDeliveryFailureType;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI WMS Read Raw' request/response */
+
+/**
+ * QmiWmsMessageTagType:
+ * @QMI_WMS_MESSAGE_TAG_TYPE_MT_READ: Received SMS, already read.
+ * @QMI_WMS_MESSAGE_TAG_TYPE_MT_NOT_READ: Received SMS, not read.
+ * @QMI_WMS_MESSAGE_TAG_TYPE_MO_SENT: Sent SMS.
+ * @QMI_WMS_MESSAGE_TAG_TYPE_MO_NOT_SENT: Not yet sent SMS.
+ *
+ * Type of message tag.
+ */
+typedef enum {
+ QMI_WMS_MESSAGE_TAG_TYPE_MT_READ = 0x00,
+ QMI_WMS_MESSAGE_TAG_TYPE_MT_NOT_READ = 0x01,
+ QMI_WMS_MESSAGE_TAG_TYPE_MO_SENT = 0x02,
+ QMI_WMS_MESSAGE_TAG_TYPE_MO_NOT_SENT = 0x03
+} QmiWmsMessageTagType;
+
+/**
+ * QmiWmsMessageProtocol:
+ * @QMI_WMS_MESSAGE_PROTOCOL_CDMA: CDMA.
+ * @QMI_WMS_MESSAGE_PROTOCOL_WCDMA: WCDMA.
+ *
+ * Type of message protocol.
+ */
+typedef enum {
+ QMI_WMS_MESSAGE_PROTOCOL_CDMA = 0x00,
+ QMI_WMS_MESSAGE_PROTOCOL_WCDMA = 0x01
+} QmiWmsMessageProtocol;
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI WMS Set Routes' request/response */
+
+/**
+ * QmiWmsMessageType:
+ * @QMI_WMS_MESSAGE_TYPE_POINT_TO_POINT: Point to point message.
+ *
+ * Type of message.
+ */
+typedef enum {
+ QMI_WMS_MESSAGE_TYPE_POINT_TO_POINT = 0x00
+} QmiWmsMessageType;
+
+/**
+ * QmiWmsMessageClass:
+ * @QMI_WMS_MESSAGE_CLASS_0: Class 0.
+ * @QMI_WMS_MESSAGE_CLASS_1: Class 1.
+ * @QMI_WMS_MESSAGE_CLASS_2: Class 2.
+ * @QMI_WMS_MESSAGE_CLASS_3: Class 3.
+ * @QMI_WMS_MESSAGE_CLASS_NONE: Class none.
+ * @QMI_WMS_MESSAGE_CLASS_CDMA: Class CDMA.
+ *
+ * Message class.
+ */
+typedef enum {
+ QMI_WMS_MESSAGE_CLASS_0 = 0x00,
+ QMI_WMS_MESSAGE_CLASS_1 = 0x01,
+ QMI_WMS_MESSAGE_CLASS_2 = 0x02,
+ QMI_WMS_MESSAGE_CLASS_3 = 0x03,
+ QMI_WMS_MESSAGE_CLASS_NONE = 0x04,
+ QMI_WMS_MESSAGE_CLASS_CDMA = 0x05
+} QmiWmsMessageClass;
+
+/**
+ * QmiWmsReceiptAction:
+ * @QMI_WMS_RECEIPT_ACTION_DISCARD: Discard message.
+ * @QMI_WMS_RECEIPT_ACTION_STORE_AND_NOTIFY: Store and notify to client.
+ * @QMI_WMS_RECEIPT_ACTION_TRANSFER_ONLY: Notify to client, which should send back ACK.
+ * @QMI_WMS_RECEIPT_ACTION_TRANSFER_AND_ACK: Notify to client and send back ACK.
+ * @QMI_WMS_RECEIPT_ACTION_UNKNOWN: Unknown action.
+ *
+ * Action to perform when a message is received.
+ */
+typedef enum {
+ QMI_WMS_RECEIPT_ACTION_DISCARD = 0x00,
+ QMI_WMS_RECEIPT_ACTION_STORE_AND_NOTIFY = 0x01,
+ QMI_WMS_RECEIPT_ACTION_TRANSFER_ONLY = 0x02,
+ QMI_WMS_RECEIPT_ACTION_TRANSFER_AND_ACK = 0x03,
+ QMI_WMS_RECEIPT_ACTION_UNKNOWN = 0xFF
+} QmiWmsReceiptAction;
+
+/**
+ * QmiWmsTransferIndication:
+ * @QMI_WMS_TRANSFER_INDICATION_CLIENT: Status reports transferred to the client.
+ *
+ * Transfer indication actions.
+ */
+typedef enum {
+ QMI_WMS_TRANSFER_INDICATION_CLIENT = 0x01
+} QmiWmsTransferIndication;
+
+#endif /* _LIBQMI_GLIB_QMI_ENUMS_WMS_H_ */
diff --git a/src/libqmi-glib/qmi-enums.h b/src/libqmi-glib/qmi-enums.h
new file mode 100644
index 0000000..e3cba79
--- /dev/null
+++ b/src/libqmi-glib/qmi-enums.h
@@ -0,0 +1,105 @@
+/* -*- 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 Google, Inc.
+ */
+
+#ifndef _LIBQMI_GLIB_QMI_ENUMS_H_
+#define _LIBQMI_GLIB_QMI_ENUMS_H_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+/**
+ * SECTION: qmi-enums
+ * @title: Common enumerations and flags
+ *
+ * This section defines common enumerations and flags used in the interface.
+ */
+
+/**
+ * QmiService:
+ * @QMI_SERVICE_UNKNOWN: Unknown service.
+ * @QMI_SERVICE_CTL: Control service.
+ * @QMI_SERVICE_WDS: Wireless Data Service.
+ * @QMI_SERVICE_DMS: Device Management Service.
+ * @QMI_SERVICE_NAS: Network Access Service.
+ * @QMI_SERVICE_QOS: Quality Of Service service.
+ * @QMI_SERVICE_WMS: Wireless Messaging Service.
+ * @QMI_SERVICE_PDS: Position Determination Service.
+ * @QMI_SERVICE_AUTH: Authentication service.
+ * @QMI_SERVICE_AT: AT service.
+ * @QMI_SERVICE_VOICE: Voice service.
+ * @QMI_SERVICE_CAT2: Card Application Toolkit service (v2).
+ * @QMI_SERVICE_UIM: User Identity Module service.
+ * @QMI_SERVICE_PBM: Phonebook Management service.
+ * @QMI_SERVICE_LOC: Location service (~ PDS v2).
+ * @QMI_SERVICE_SAR: SAR.
+ * @QMI_SERVICE_RMTFS: Remote Filesystem service.
+ * @QMI_SERVICE_CAT: Card Application Toolkit service (v1).
+ * @QMI_SERVICE_RMS: Remote Management Service.
+ * @QMI_SERVICE_OMA: Open Mobile Alliance device management service.
+ *
+ * QMI services.
+ */
+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,
+ /* Card Application Toolkit service (major version 2) */
+ QMI_SERVICE_CAT2 = 0x0A,
+ /* User Identity Module service */
+ QMI_SERVICE_UIM = 0x0B,
+ /* Phonebook Management service */
+ QMI_SERVICE_PBM = 0x0C,
+ /* Location service (~ PDS major version 2) */
+ QMI_SERVICE_LOC = 0x10,
+ /* No idea what this one means.. Search And Rescue? */
+ QMI_SERVICE_SAR = 0x11,
+ /* Remote Filesystem service */
+ 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;
+
+#endif /* _LIBQMI_GLIB_QMI_ENUMS_H_ */
diff --git a/src/libqmi-glib/qmi-errors.h b/src/libqmi-glib/qmi-errors.h
new file mode 100644
index 0000000..d8e36b2
--- /dev/null
+++ b/src/libqmi-glib/qmi-errors.h
@@ -0,0 +1,279 @@
+/* -*- 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_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+/**
+ * SECTION: qmi-errors
+ * @title: Errors
+ *
+ * This section defines common error types used in the interface.
+ */
+
+/* Prefixes for errors registered in DBus */
+#define QMI_DBUS_ERROR_PREFIX "org.freedesktop.libqmi.Error"
+#define QMI_CORE_ERROR_DBUS_PREFIX QMI_DBUS_ERROR_PREFIX ".Core"
+#define QMI_PROTOCOL_ERROR_DBUS_PREFIX QMI_DBUS_ERROR_PREFIX ".Protocol"
+
+/**
+ * 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 { /*< underscore_name=qmi_core_error >*/
+ QMI_CORE_ERROR_FAILED = 0, /*< nick=Failed >*/
+ QMI_CORE_ERROR_WRONG_STATE = 1, /*< nick=WrongState >*/
+ QMI_CORE_ERROR_TIMEOUT = 2, /*< nick=Timeout >*/
+ QMI_CORE_ERROR_INVALID_ARGS = 3, /*< nick=InvalidArgs >*/
+ QMI_CORE_ERROR_INVALID_MESSAGE = 4, /*< nick=InvalidMessage >*/
+ QMI_CORE_ERROR_TLV_NOT_FOUND = 5, /*< nick=TlvNotFound >*/
+ QMI_CORE_ERROR_TLV_TOO_LONG = 6, /*< nick=TlvTooLong >*/
+ QMI_CORE_ERROR_UNSUPPORTED = 7 /*< nick=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_T_PDU_TYPE: WMS T-PDU 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_POLICY_MISMATCH: Policy mismatch.
+ * @QMI_PROTOCOL_ERROR_SIM_FILE_NOT_FOUND: SIM file not found.
+ * @QMI_PROTOCOL_ERROR_EXTENDED_INTERNAL: Extended internal error.
+ * @QMI_PROTOCOL_ERROR_ACCESS_DENIED: Access denied.
+ * @QMI_PROTOCOL_ERROR_HARDWARE_RESTRICTED: Hardware restricted.
+ * @QMI_PROTOCOL_ERROR_ACK_NOT_SENT: ACK not sent.
+ * @QMI_PROTOCOL_ERROR_INJECT_TIMEOUT: Inject timeout.
+ * @QMI_PROTOCOL_ERROR_INCOMPATIBLE_STATE: Incompatible state.
+ * @QMI_PROTOCOL_ERROR_FDN_RESTRICT: FDN restrict.
+ * @QMI_PROTOCOL_ERROR_SUPS_FAILURE_CASE: SUPS failure case.
+ * @QMI_PROTOCOL_ERROR_NO_RADIO: No radio.
+ * @QMI_PROTOCOL_ERROR_NOT_SUPPORTED: Not supported.
+ * @QMI_PROTOCOL_ERROR_NO_SUBSCRIPTION: No subscription.
+ * @QMI_PROTOCOL_ERROR_CARD_CALL_CONTROL_FAILED: Card call control failed.
+ * @QMI_PROTOCOL_ERROR_NETWORK_ABORTED: Network aborted.
+ * @QMI_PROTOCOL_ERROR_MSG_BLOCKED: Message blocked.
+ * @QMI_PROTOCOL_ERROR_INVALID_SESSION_TYPE: Invalid session type.
+ * @QMI_PROTOCOL_ERROR_INVALID_PB_TYPE: Invalid PB type.
+ * @QMI_PROTOCOL_ERROR_NO_SIM: No SIM.
+ * @QMI_PROTOCOL_ERROR_PB_NOT_READY: PB not ready.
+ * @QMI_PROTOCOL_ERROR_PIN_RESTRICTION: PIN restriction.
+ * @QMI_PROTOCOL_ERROR_PIN2_RESTRICTION: PIN2 restriction.
+ * @QMI_PROTOCOL_ERROR_PUK_RESTRICTION: PUK restriction.
+ * @QMI_PROTOCOL_ERROR_PUK2_RESTRICTION: PUK2 restriction.
+ * @QMI_PROTOCOL_ERROR_PB_ACCESS_RESTRICTED: PB access restricted.
+ * @QMI_PROTOCOL_ERROR_PB_TEXT_TOO_LONG: PB text too long.
+ * @QMI_PROTOCOL_ERROR_PB_NUMBER_TOO_LONG: PB number too long.
+ * @QMI_PROTOCOL_ERROR_PB_HIDDEN_KEY_RESTRICTION: PB hidden key restriction.
+ * @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 { /*< underscore_name=qmi_protocol_error >*/
+ QMI_PROTOCOL_ERROR_NONE = 0, /*< nick=None >*/
+ QMI_PROTOCOL_ERROR_MALFORMED_MESSAGE = 1, /*< nick=MalformedMessage >*/
+ QMI_PROTOCOL_ERROR_NO_MEMORY = 2, /*< nick=NoMemory >*/
+ QMI_PROTOCOL_ERROR_INTERNAL = 3, /*< nick=Internal >*/
+ QMI_PROTOCOL_ERROR_ABORTED = 4, /*< nick=Aborted >*/
+ QMI_PROTOCOL_ERROR_CLIENT_IDS_EXHAUSTED = 5, /*< nick=ClientIdsExhausted >*/
+ QMI_PROTOCOL_ERROR_UNABORTABLE_TRANSACTION = 6, /*< nick=UnabortableTransaction >*/
+ QMI_PROTOCOL_ERROR_INVALID_CLIENT_ID = 7, /*< nick=InvalidClientId >*/
+ QMI_PROTOCOL_ERROR_NO_THRESHOLDS_PROVIDED = 8, /*< nick=NoThresholdsProvided >*/
+ QMI_PROTOCOL_ERROR_INVALID_HANDLE = 9, /*< nick=InvalidHandle >*/
+ QMI_PROTOCOL_ERROR_INVALID_PROFILE = 10, /*< nick=InvalidProfile >*/
+ QMI_PROTOCOL_ERROR_INVALID_PIN_ID = 11, /*< nick=InvalidPinId >*/
+ QMI_PROTOCOL_ERROR_INCORRECT_PIN = 12, /*< nick=IncorrectPin >*/
+ QMI_PROTOCOL_ERROR_NO_NETWORK_FOUND = 13, /*< nick=NoNetworkFound >*/
+ QMI_PROTOCOL_ERROR_CALL_FAILED = 14, /*< nick=CallFailed >*/
+ QMI_PROTOCOL_ERROR_OUT_OF_CALL = 15, /*< nick=OutOfCall >*/
+ QMI_PROTOCOL_ERROR_NOT_PROVISIONED = 16, /*< nick=NotProvisioned >*/
+ QMI_PROTOCOL_ERROR_MISSING_ARGUMENT = 17, /*< nick=MissingArgument >*/
+ QMI_PROTOCOL_ERROR_ARGUMENT_TOO_LONG = 19, /*< nick=ArgumentTooLong >*/
+ QMI_PROTOCOL_ERROR_INVALID_TRANSACTION_ID = 22, /*< nick=InvalidTransactionId >*/
+ QMI_PROTOCOL_ERROR_DEVICE_IN_USE = 23, /*< nick=DeviceInUse >*/
+ QMI_PROTOCOL_ERROR_NETWORK_UNSUPPORTED = 24, /*< nick=NetworkUnsupported >*/
+ QMI_PROTOCOL_ERROR_DEVICE_UNSUPPORTED = 25, /*< nick=DeviceUnsupported >*/
+ QMI_PROTOCOL_ERROR_NO_EFFECT = 26, /*< nick=NoEffect >*/
+ QMI_PROTOCOL_ERROR_NO_FREE_PROFILE = 27, /*< nick=NoFreeProfile >*/
+ QMI_PROTOCOL_ERROR_INVALID_PDP_TYPE = 28, /*< nick=InvalidPdpType >*/
+ QMI_PROTOCOL_ERROR_INVALID_TECHNOLOGY_PREFERENCE = 29, /*< nick=InvalidTechnologyPreference >*/
+ QMI_PROTOCOL_ERROR_INVALID_PROFILE_TYPE = 30, /*< nick=InvalidProfileType >*/
+ QMI_PROTOCOL_ERROR_INVALID_SERVICE_TYPE = 31, /*< nick=InvalidServiceType >*/
+ QMI_PROTOCOL_ERROR_INVALID_REGISTER_ACTION = 32, /*< nick=InvalidRegisterAction >*/
+ QMI_PROTOCOL_ERROR_INVALID_PS_ATTACH_ACTION = 33, /*< nick=InvalidPsAttachAction >*/
+ QMI_PROTOCOL_ERROR_AUTHENTICATION_FAILED = 34, /*< nick=AuthenticationFailed >*/
+ QMI_PROTOCOL_ERROR_PIN_BLOCKED = 35, /*< nick=PinBlocked >*/
+ QMI_PROTOCOL_ERROR_PIN_ALWAYS_BLOCKED = 36, /*< nick=PinAlwaysBlocked >*/
+ QMI_PROTOCOL_ERROR_UIM_UNINITIALIZED = 37, /*< nick=UimUninitialized >*/
+ QMI_PROTOCOL_ERROR_MAXIMUM_QOS_REQUESTS_IN_USE = 38, /*< nick=MaximumQosRequestsInUse >*/
+ QMI_PROTOCOL_ERROR_INCORRECT_FLOW_FILTER = 39, /*< nick=IncorrectFlowFilter >*/
+ QMI_PROTOCOL_ERROR_NETWORK_QOS_UNAWARE = 40, /*< nick= NetworkQosUnaware >*/
+ QMI_PROTOCOL_ERROR_INVALID_QOS_ID = 41, /*< nick=InvalidQosId >*/
+ QMI_PROTOCOL_ERROR_QOS_UNAVAILABLE = 42, /*< nick=QosUnavailable >*/
+ QMI_PROTOCOL_ERROR_FLOW_SUSPENDED = 43, /*< nick=FlowSuspended >*/
+ QMI_PROTOCOL_ERROR_GENERAL_ERROR = 46, /*< nick=GeneralError >*/
+ QMI_PROTOCOL_ERROR_UNKNOWN_ERROR = 47, /*< nick=UnknownError >*/
+ QMI_PROTOCOL_ERROR_INVALID_ARGUMENT = 48, /*< nick=InvalidArgument >*/
+ QMI_PROTOCOL_ERROR_INVALID_INDEX = 49, /*< nick=InvalidIndex >*/
+ QMI_PROTOCOL_ERROR_NO_ENTRY = 50, /*< nick=NoEntry >*/
+ QMI_PROTOCOL_ERROR_DEVICE_STORAGE_FULL = 51, /*< nick=DeviceStorageFull >*/
+ QMI_PROTOCOL_ERROR_DEVICE_NOT_READY = 52, /*< nick=DeviceNotReady >*/
+ QMI_PROTOCOL_ERROR_NETWORK_NOT_READY = 53, /*< nick=NetworkNotReady >*/
+ QMI_PROTOCOL_ERROR_WMS_CAUSE_CODE = 54, /*< nick=Wms.CauseCode >*/
+ QMI_PROTOCOL_ERROR_WMS_MESSAGE_NOT_SENT = 55, /*< nick=Wms.MessageNotSent >*/
+ QMI_PROTOCOL_ERROR_WMS_MESSAGE_DELIVERY_FAILURE = 56, /*< nick=Wms.MessageDeliveryFailure >*/
+ QMI_PROTOCOL_ERROR_WMS_INVALID_MESSAGE_ID = 57, /*< nick=Wms.InvalidMessageId >*/
+ QMI_PROTOCOL_ERROR_WMS_ENCODING = 58, /*< nick=Wms.Encoding >*/
+ QMI_PROTOCOL_ERROR_AUTHENTICATION_LOCK = 59, /*< nick=AuthenticationLock >*/
+ QMI_PROTOCOL_ERROR_INVALID_TRANSITION = 60, /*< nick=InvalidTransaction >*/
+ QMI_PROTOCOL_ERROR_SESSION_INACTIVE = 65, /*< nick=SessionInactive >*/
+ QMI_PROTOCOL_ERROR_SESSION_INVALID = 66, /*< nick=SessionInvalid >*/
+ QMI_PROTOCOL_ERROR_SESSION_OWNERSHIP = 67, /*< nick=SessionOwnership >*/
+ QMI_PROTOCOL_ERROR_INSUFFICIENT_RESOURCES = 68, /*< nick=InsufficientResources >*/
+ QMI_PROTOCOL_ERROR_DISABLED = 69, /*< nick=Disabled >*/
+ QMI_PROTOCOL_ERROR_INVALID_OPERATION = 70, /*< nick=InvalidOperation >*/
+ QMI_PROTOCOL_ERROR_INVALID_QMI_COMMAND = 71, /*< nick=InvalidQmiCommand >*/
+ QMI_PROTOCOL_ERROR_WMS_T_PDU_TYPE = 72, /*< nick=Wms.TPduType >*/
+ QMI_PROTOCOL_ERROR_WMS_SMSC_ADDRESS = 73, /*< nick=Wms.SmscAddress >*/
+ QMI_PROTOCOL_ERROR_INFORMATION_UNAVAILABLE = 74, /*< nick=InformationUnavailable >*/
+ QMI_PROTOCOL_ERROR_SEGMENT_TOO_LONG = 75, /*< nick=SegmentTooLong >*/
+ QMI_PROTOCOL_ERROR_SEGMENT_ORDER = 76, /*< nick=SegmentOrder >*/
+ QMI_PROTOCOL_ERROR_BUNDLING_NOT_SUPPORTED = 77, /*< nick=BundlingNotSupported >*/
+ /* 0x004E, 78: unused */
+ QMI_PROTOCOL_ERROR_POLICY_MISMATCH = 79, /*< nick=PolicyMismatch >*/
+ QMI_PROTOCOL_ERROR_SIM_FILE_NOT_FOUND = 80, /*< nick=SimFileNotFound >*/
+ QMI_PROTOCOL_ERROR_EXTENDED_INTERNAL = 81, /*< nick=ExtendedInternal >*/
+ QMI_PROTOCOL_ERROR_ACCESS_DENIED = 82, /*< nick=AccessDenied >*/
+ QMI_PROTOCOL_ERROR_HARDWARE_RESTRICTED = 83, /*< nick=HardwareRestricted >*/
+ QMI_PROTOCOL_ERROR_ACK_NOT_SENT = 84, /*< nick=AckNotSent >*/
+ QMI_PROTOCOL_ERROR_INJECT_TIMEOUT = 85, /*< nick=InjectTimeout >*/
+ QMI_PROTOCOL_ERROR_INCOMPATIBLE_STATE = 90, /*< nick=IncompatibleState >*/
+ QMI_PROTOCOL_ERROR_FDN_RESTRICT = 91, /*< nick=FdnRestrict >*/
+ QMI_PROTOCOL_ERROR_SUPS_FAILURE_CASE = 92, /*< nick=SupsFailureCase >*/
+ QMI_PROTOCOL_ERROR_NO_RADIO = 93, /*< nick=NoRadio >*/
+ QMI_PROTOCOL_ERROR_NOT_SUPPORTED = 94, /*< nick=NotSupported >*/
+ QMI_PROTOCOL_ERROR_NO_SUBSCRIPTION = 95, /*< nick=NoSubscription >*/
+ QMI_PROTOCOL_ERROR_CARD_CALL_CONTROL_FAILED = 96, /*< nick=CardCallControlFailed >*/
+ QMI_PROTOCOL_ERROR_NETWORK_ABORTED = 97, /*< nick=NetworkAborted >*/
+ QMI_PROTOCOL_ERROR_MSG_BLOCKED = 98, /*< nick=MsgBlocked >*/
+ QMI_PROTOCOL_ERROR_INVALID_SESSION_TYPE = 100, /*< nick=InvalidSessionType >*/
+ QMI_PROTOCOL_ERROR_INVALID_PB_TYPE = 101, /*< nick=InvalidPbType >*/
+ QMI_PROTOCOL_ERROR_NO_SIM = 102, /*< nick=NoSim >*/
+ QMI_PROTOCOL_ERROR_PB_NOT_READY = 103, /*< nick=PbNotReady >*/
+ QMI_PROTOCOL_ERROR_PIN_RESTRICTION = 104, /*< nick=PinRestriction >*/
+ QMI_PROTOCOL_ERROR_PIN2_RESTRICTION = 105, /*< nick=Pin1Restriction >*/
+ QMI_PROTOCOL_ERROR_PUK_RESTRICTION = 106, /*< nick=PukRestriction >*/
+ QMI_PROTOCOL_ERROR_PUK2_RESTRICTION = 107, /*< nick=Puk2Restriction >*/
+ QMI_PROTOCOL_ERROR_PB_ACCESS_RESTRICTED = 108, /*< nick=PbAccessRestricted >*/
+ QMI_PROTOCOL_ERROR_PB_TEXT_TOO_LONG = 109, /*< nick=PbTextTooLong >*/
+ QMI_PROTOCOL_ERROR_PB_NUMBER_TOO_LONG = 110, /*< nick=PbNumberTooLong >*/
+ QMI_PROTOCOL_ERROR_PB_HIDDEN_KEY_RESTRICTION = 111, /*< nick=PbHiddenKeyRestriction >*/
+ QMI_PROTOCOL_ERROR_CAT_EVENT_REGISTRATION_FAILED = 61441, /*< nick=Cat.EventRegistrationFailed >*/
+ QMI_PROTOCOL_ERROR_CAT_INVALID_TERMINAL_RESPONSE = 61442, /*< nick=Cat.InvalidTerminalResponse >*/
+ QMI_PROTOCOL_ERROR_CAT_INVALID_ENVELOPE_COMMAND = 61443, /*< nick=Cat.InvalidEnvelopeCommand >*/
+ QMI_PROTOCOL_ERROR_CAT_ENVELOPE_COMMAND_BUSY = 61444, /*< nick=Cat.EnvelopCommandBusy >*/
+ QMI_PROTOCOL_ERROR_CAT_ENVELOPE_COMMAND_FAILED = 61445 /*< nick=Cat.EnvelopeCommandFailed >*/
+} QmiProtocolError;
+
+#endif /* _LIBQMI_GLIB_QMI_ERRORS_H_ */
diff --git a/src/libqmi-glib/qmi-flags64-dms.h b/src/libqmi-glib/qmi-flags64-dms.h
new file mode 100644
index 0000000..23dd67c
--- /dev/null
+++ b/src/libqmi-glib/qmi-flags64-dms.h
@@ -0,0 +1,204 @@
+/* -*- 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>
+ * Copyright (C) 2012 Google, Inc.
+ */
+
+#ifndef _LIBQMI_GLIB_QMI_FLAGS64_DMS_H_
+#define _LIBQMI_GLIB_QMI_FLAGS64_DMS_H_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+#include <glib.h>
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI DMS Get Band Capability' message */
+
+/**
+ * QmiDmsBandCapability:
+ * @QMI_DMS_BAND_CAPABILITY_BC_0_A_SYSTEM: Band class 0, A-system.
+ * @QMI_DMS_BAND_CAPABILITY_BC_0_B_SYSTEM: Band class 0, B-system.
+ * @QMI_DMS_BAND_CAPABILITY_BC_1_ALL_BLOCKS: Band class 1, all blocks.
+ * @QMI_DMS_BAND_CAPABILITY_BC_2: Band class 2.
+ * @QMI_DMS_BAND_CAPABILITY_BC_3_A_SYSTEM: Band class 3, A-system.
+ * @QMI_DMS_BAND_CAPABILITY_BC_4_ALL_BLOCKS: Band class 4, all blocks.
+ * @QMI_DMS_BAND_CAPABILITY_BC_5_ALL_BLOCKS: Band class 5, all blocks.
+ * @QMI_DMS_BAND_CAPABILITY_BC_6: Band class 6.
+ * @QMI_DMS_BAND_CAPABILITY_BC_7: Band class 7.
+ * @QMI_DMS_BAND_CAPABILITY_BC_8: Band class 8.
+ * @QMI_DMS_BAND_CAPABILITY_BC_9: Band class 9.
+ * @QMI_DMS_BAND_CAPABILITY_BC_10: Band class 10.
+ * @QMI_DMS_BAND_CAPABILITY_BC_11: Band class 11.
+ * @QMI_DMS_BAND_CAPABILITY_BC_12: Band class 12.
+ * @QMI_DMS_BAND_CAPABILITY_BC_14: Band class 14.
+ * @QMI_DMS_BAND_CAPABILITY_BC_15: Band class 15.
+ * @QMI_DMS_BAND_CAPABILITY_BC_16: Band class 16.
+ * @QMI_DMS_BAND_CAPABILITY_BC_17: Band class 17.
+ * @QMI_DMS_BAND_CAPABILITY_BC_18: Band class 18.
+ * @QMI_DMS_BAND_CAPABILITY_BC_19: Band class 19.
+ * @QMI_DMS_BAND_CAPABILITY_GSM_DCS_1800: GSM DCS band.
+ * @QMI_DMS_BAND_CAPABILITY_GSM_900_EXTENDED: GSM Extended GSM band (900).
+ * @QMI_DMS_BAND_CAPABILITY_GSM_900_PRIMARY: GSM Primary GSM band (900).
+ * @QMI_DMS_BAND_CAPABILITY_GSM_450: GSM 450 band.
+ * @QMI_DMS_BAND_CAPABILITY_GSM_480: GSM 480 band.
+ * @QMI_DMS_BAND_CAPABILITY_GSM_750: GSM 750 band.
+ * @QMI_DMS_BAND_CAPABILITY_GSM_850: GSM 850 band.
+ * @QMI_DMS_BAND_CAPABILITY_GSM_900_RAILWAYS: GSM railways band (900).
+ * @QMI_DMS_BAND_CAPABILITY_GSM_PCS_1900: GSM PCS band (1900).
+ * @QMI_DMS_BAND_CAPABILITY_WCDMA_2100: WCDMA 2100 band (Europe, Japan, China).
+ * @QMI_DMS_BAND_CAPABILITY_WCDMA_PCS_1900: WCDMA PCS 1900 band (US).
+ * @QMI_DMS_BAND_CAPABILITY_WCDMA_DCS_1800: WCDMA DCS 1800 band (Europe, China).
+ * @QMI_DMS_BAND_CAPABILITY_WCDMA_1700_US: WCDMA 1700 band (US).
+ * @QMI_DMS_BAND_CAPABILITY_WCDMA_850_US: WCDMA 850 band (US).
+ * @QMI_DMS_BAND_CAPABILITY_WCDMA_800: QWCDMA 850 band (Japan).
+ * @QMI_DMS_BAND_CAPABILITY_WCDMA_2600: WCDMA 2600 band (Europe).
+ * @QMI_DMS_BAND_CAPABILITY_WCDMA_900: WCDMA 900 band (Europe, Japan).
+ * @QMI_DMS_BAND_CAPABILITY_WCDMA_1700_JAPAN: WCDMA 1700 band (Japan).
+ * @QMI_DMS_BAND_CAPABILITY_WCDMA_850_JAPAN: WCDMA 850 band (Japan)
+ * @QMI_DMS_BAND_CAPABILITY_WCDMA_1500: WCDMA 1500 band.
+ *
+ * Frequency band capabilities.
+ */
+typedef enum {
+ QMI_DMS_BAND_CAPABILITY_BC_0_A_SYSTEM = 1 << 0,
+ QMI_DMS_BAND_CAPABILITY_BC_0_B_SYSTEM = 1 << 1,
+ QMI_DMS_BAND_CAPABILITY_BC_1_ALL_BLOCKS = 1 << 2,
+ QMI_DMS_BAND_CAPABILITY_BC_2 = 1 << 3,
+ QMI_DMS_BAND_CAPABILITY_BC_3_A_SYSTEM = 1 << 4,
+ QMI_DMS_BAND_CAPABILITY_BC_4_ALL_BLOCKS = 1 << 5,
+ QMI_DMS_BAND_CAPABILITY_BC_5_ALL_BLOCKS = 1 << 6,
+ QMI_DMS_BAND_CAPABILITY_GSM_DCS_1800 = 1 << 7,
+ QMI_DMS_BAND_CAPABILITY_GSM_900_EXTENDED = 1 << 8,
+ QMI_DMS_BAND_CAPABILITY_GSM_900_PRIMARY = 1 << 9,
+ QMI_DMS_BAND_CAPABILITY_BC_6 = 1 << 10,
+ QMI_DMS_BAND_CAPABILITY_BC_7 = 1 << 11,
+ QMI_DMS_BAND_CAPABILITY_BC_8 = 1 << 12,
+ QMI_DMS_BAND_CAPABILITY_BC_9 = 1 << 13,
+ QMI_DMS_BAND_CAPABILITY_BC_10 = 1 << 14,
+ QMI_DMS_BAND_CAPABILITY_BC_11 = 1 << 15,
+ QMI_DMS_BAND_CAPABILITY_GSM_450 = 1 << 16,
+ QMI_DMS_BAND_CAPABILITY_GSM_480 = 1 << 17,
+ QMI_DMS_BAND_CAPABILITY_GSM_750 = 1 << 18,
+ QMI_DMS_BAND_CAPABILITY_GSM_850 = 1 << 19,
+ QMI_DMS_BAND_CAPABILITY_GSM_900_RAILWAYS = 1 << 20,
+ QMI_DMS_BAND_CAPABILITY_GSM_PCS_1900 = 1 << 21,
+ QMI_DMS_BAND_CAPABILITY_WCDMA_2100 = 1 << 22,
+ QMI_DMS_BAND_CAPABILITY_WCDMA_PCS_1900 = 1 << 23,
+ QMI_DMS_BAND_CAPABILITY_WCDMA_DCS_1800 = 1 << 24,
+ QMI_DMS_BAND_CAPABILITY_WCDMA_1700_US = 1 << 25,
+ QMI_DMS_BAND_CAPABILITY_WCDMA_850_US = 1 << 26,
+ QMI_DMS_BAND_CAPABILITY_WCDMA_800 = 1 << 27,
+ QMI_DMS_BAND_CAPABILITY_BC_12 = 1 << 28,
+ QMI_DMS_BAND_CAPABILITY_BC_14 = 1 << 29,
+ /* Bit 30 reserved */
+ QMI_DMS_BAND_CAPABILITY_BC_15 = 1 << 31,
+ /* Bits 32-47 reserved */
+ QMI_DMS_BAND_CAPABILITY_WCDMA_2600 = ((guint64) 1) << 48,
+ QMI_DMS_BAND_CAPABILITY_WCDMA_900 = ((guint64) 1) << 49,
+ QMI_DMS_BAND_CAPABILITY_WCDMA_1700_JAPAN = ((guint64) 1) << 50,
+ /* Bits 51-55 reserved */
+ QMI_DMS_BAND_CAPABILITY_BC_16 = ((guint64) 1) << 56,
+ QMI_DMS_BAND_CAPABILITY_BC_17 = ((guint64) 1) << 57,
+ QMI_DMS_BAND_CAPABILITY_BC_18 = ((guint64) 1) << 58,
+ QMI_DMS_BAND_CAPABILITY_BC_19 = ((guint64) 1) << 59,
+ QMI_DMS_BAND_CAPABILITY_WCDMA_850_JAPAN = ((guint64) 1) << 60,
+ QMI_DMS_BAND_CAPABILITY_WCDMA_1500 = ((guint64) 1) << 61
+ /* Bits 62-63 reserved */
+} QmiDmsBandCapability;
+
+/**
+ * QmiDmsLteBandCapability:
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_1: LTE EUTRAN Band 1
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_2: LTE EUTRAN Band 2.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_3: LTE EUTRAN Band 3.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_4: LTE EUTRAN Band 4.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_5: LTE EUTRAN Band 5.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_6: LTE EUTRAN Band 6.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_7: LTE EUTRAN Band 7.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_8: LTE EUTRAN Band 8.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_9: LTE EUTRAN Band 9.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_10: LTE EUTRAN Band 10.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_11: LTE EUTRAN Band 11.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_12: LTE EUTRAN Band 12.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_13: LTE EUTRAN Band 13.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_14: LTE EUTRAN Band 14.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_17: LTE EUTRAN Band 17.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_18: LTE EUTRAN Band 18.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_19: LTE EUTRAN Band 19.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_20: LTE EUTRAN Band 20.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_21: LTE EUTRAN Band 21.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_24: LTE EUTRAN Band 24.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_25: LTE EUTRAN Band 25.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_33: LTE EUTRAN Band 33.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_34: LTE EUTRAN Band 34.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_35: LTE EUTRAN Band 35.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_36: LTE EUTRAN Band 36.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_37: LTE EUTRAN Band 37.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_38: LTE EUTRAN Band 38.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_39: LTE EUTRAN Band 39.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_40: LTE EUTRAN Band 40.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_41: LTE EUTRAN Band 41.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_42: LTE EUTRAN Band 42.
+ * @QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_43: LTE EUTRAN Band 43.
+ *
+ * LTE-specific Frequency bands.
+ */
+typedef enum {
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_1 = 1 << 0,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_2 = 1 << 1,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_3 = 1 << 2,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_4 = 1 << 3,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_5 = 1 << 4,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_6 = 1 << 5,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_7 = 1 << 6,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_8 = 1 << 7,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_9 = 1 << 8,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_10 = 1 << 9,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_11 = 1 << 10,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_12 = 1 << 11,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_13 = 1 << 12,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_14 = 1 << 13,
+ /* Bit 14-15 reserved */
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_17 = 1 << 16,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_18 = 1 << 17,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_19 = 1 << 18,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_20 = 1 << 19,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_21 = 1 << 20,
+ /* Bit 21-22 reserved */
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_24 = 1 << 23,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_25 = 1 << 24,
+ /* Bit 25-31 reserved */
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_33 = ((guint64) 1) << 32,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_34 = ((guint64) 1) << 33,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_35 = ((guint64) 1) << 34,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_36 = ((guint64) 1) << 35,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_37 = ((guint64) 1) << 36,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_38 = ((guint64) 1) << 37,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_39 = ((guint64) 1) << 38,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_40 = ((guint64) 1) << 39,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_41 = ((guint64) 1) << 40,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_42 = ((guint64) 1) << 41,
+ QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_43 = ((guint64) 1) << 42
+ /* Bit 43-64 reserved */
+} QmiDmsLteBandCapability;
+
+#endif /* _LIBQMI_GLIB_QMI_FLAGS64_DMS_H_ */
diff --git a/src/libqmi-glib/qmi-flags64-nas.h b/src/libqmi-glib/qmi-flags64-nas.h
new file mode 100644
index 0000000..b76f8f2
--- /dev/null
+++ b/src/libqmi-glib/qmi-flags64-nas.h
@@ -0,0 +1,200 @@
+/* -*- 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 Google Inc.
+ */
+
+#ifndef _LIBQMI_GLIB_QMI_FLAGS64_NAS_H_
+#define _LIBQMI_GLIB_QMI_FLAGS64_NAS_H_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+#include <glib.h>
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI NAS Get System Selection Preference'
+ * request/response */
+
+/**
+ * QmiNasBandPreference:
+ * @QMI_NAS_BAND_PREFERENCE_BC_0_A_SYSTEM: Band class 0, A system.
+ * @QMI_NAS_BAND_PREFERENCE_BC_0_B_SYSTEM: Band class 0, B system.
+ * @QMI_NAS_BAND_PREFERENCE_BC_1_ALL_BLOCKS: Band class 1.
+ * @QMI_NAS_BAND_PREFERENCE_BC_2: Band class 2.
+ * @QMI_NAS_BAND_PREFERENCE_BC_3_A_SYSTEM: Band class 3, A system.
+ * @QMI_NAS_BAND_PREFERENCE_BC_4_ALL_BLOCKS: Band class 4, all blocks.
+ * @QMI_NAS_BAND_PREFERENCE_BC_5_ALL_BLOCKS: Band class 5, all blocks.
+ * @QMI_NAS_BAND_PREFERENCE_BC_6: Band class 6.
+ * @QMI_NAS_BAND_PREFERENCE_BC_7: Band class 7.
+ * @QMI_NAS_BAND_PREFERENCE_BC_8: Band class 8.
+ * @QMI_NAS_BAND_PREFERENCE_BC_9: Band class 9.
+ * @QMI_NAS_BAND_PREFERENCE_BC_10: Band class 10.
+ * @QMI_NAS_BAND_PREFERENCE_BC_11: Band class 11.
+ * @QMI_NAS_BAND_PREFERENCE_BC_12: Band class 12.
+ * @QMI_NAS_BAND_PREFERENCE_BC_14: Band class 14.
+ * @QMI_NAS_BAND_PREFERENCE_BC_15: Band class 15.
+ * @QMI_NAS_BAND_PREFERENCE_BC_16: Band class 16.
+ * @QMI_NAS_BAND_PREFERENCE_BC_17: Band class 17.
+ * @QMI_NAS_BAND_PREFERENCE_BC_18: Band class 18.
+ * @QMI_NAS_BAND_PREFERENCE_BC_19: Band class 19.
+ * @QMI_NAS_BAND_PREFERENCE_GSM_DCS_1800: GSM DCS 1800 band.
+ * @QMI_NAS_BAND_PREFERENCE_GSM_900_EXTENDED: Extended GSM 900 band.
+ * @QMI_NAS_BAND_PREFERENCE_GSM_900_PRIMARY: Primary GSM 900 band.
+ * @QMI_NAS_BAND_PREFERENCE_GSM_450: GSM 450.
+ * @QMI_NAS_BAND_PREFERENCE_GSM_480: GSM 480.
+ * @QMI_NAS_BAND_PREFERENCE_GSM_750: GSM 750.
+ * @QMI_NAS_BAND_PREFERENCE_GSM_850: GSM 850.
+ * @QMI_NAS_BAND_PREFERENCE_GSM_900_RAILWAYS: GSM 900 (Railways).
+ * @QMI_NAS_BAND_PREFERENCE_GSM_PCS_1900: GSM 1900.
+ * @QMI_NAS_BAND_PREFERENCE_WCDMA_2100: WCDMA 2100.
+ * @QMI_NAS_BAND_PREFERENCE_WCDMA_PCS_1900: WCDMA PCS 1900.
+ * @QMI_NAS_BAND_PREFERENCE_WCDMA_DCS_1800: WCDMA DCS 1800.
+ * @QMI_NAS_BAND_PREFERENCE_WCDMA_1700_US: WCDMA 1700 (U.S.).
+ * @QMI_NAS_BAND_PREFERENCE_WCDMA_850_US: WCDMA 850.
+ * @QMI_NAS_BAND_PREFERENCE_WCDMA_800: WCDMA 800.
+ * @QMI_NAS_BAND_PREFERENCE_WCDMA_2600: WCDMA 2600.
+ * @QMI_NAS_BAND_PREFERENCE_WCDMA_900: WCDMA 900.
+ * @QMI_NAS_BAND_PREFERENCE_WCDMA_1700_JAPAN: WCDMA 1700 (Japan).
+ *
+ * Flags to specify frequency band preferences.
+ */
+typedef enum {
+ QMI_NAS_BAND_PREFERENCE_BC_0_A_SYSTEM = 1 << 0,
+ QMI_NAS_BAND_PREFERENCE_BC_0_B_SYSTEM = 1 << 1,
+ QMI_NAS_BAND_PREFERENCE_BC_1_ALL_BLOCKS = 1 << 2,
+ QMI_NAS_BAND_PREFERENCE_BC_2 = 1 << 3,
+ QMI_NAS_BAND_PREFERENCE_BC_3_A_SYSTEM = 1 << 4,
+ QMI_NAS_BAND_PREFERENCE_BC_4_ALL_BLOCKS = 1 << 5,
+ QMI_NAS_BAND_PREFERENCE_BC_5_ALL_BLOCKS = 1 << 6,
+ QMI_NAS_BAND_PREFERENCE_GSM_DCS_1800 = 1 << 7,
+ QMI_NAS_BAND_PREFERENCE_GSM_900_EXTENDED = 1 << 8,
+ QMI_NAS_BAND_PREFERENCE_GSM_900_PRIMARY = 1 << 9,
+ QMI_NAS_BAND_PREFERENCE_BC_6 = 1 << 10,
+ QMI_NAS_BAND_PREFERENCE_BC_7 = 1 << 11,
+ QMI_NAS_BAND_PREFERENCE_BC_8 = 1 << 12,
+ QMI_NAS_BAND_PREFERENCE_BC_9 = 1 << 13,
+ QMI_NAS_BAND_PREFERENCE_BC_10 = 1 << 14,
+ QMI_NAS_BAND_PREFERENCE_BC_11 = 1 << 15,
+ QMI_NAS_BAND_PREFERENCE_GSM_450 = 1 << 16,
+ QMI_NAS_BAND_PREFERENCE_GSM_480 = 1 << 17,
+ QMI_NAS_BAND_PREFERENCE_GSM_750 = 1 << 18,
+ QMI_NAS_BAND_PREFERENCE_GSM_850 = 1 << 19,
+ QMI_NAS_BAND_PREFERENCE_GSM_900_RAILWAYS = 1 << 20,
+ QMI_NAS_BAND_PREFERENCE_GSM_PCS_1900 = 1 << 21,
+ QMI_NAS_BAND_PREFERENCE_WCDMA_2100 = 1 << 22,
+ QMI_NAS_BAND_PREFERENCE_WCDMA_PCS_1900 = 1 << 23,
+ QMI_NAS_BAND_PREFERENCE_WCDMA_DCS_1800 = 1 << 24,
+ QMI_NAS_BAND_PREFERENCE_WCDMA_1700_US = 1 << 25,
+ QMI_NAS_BAND_PREFERENCE_WCDMA_850_US = 1 << 26,
+ QMI_NAS_BAND_PREFERENCE_WCDMA_800 = 1 << 27,
+ QMI_NAS_BAND_PREFERENCE_BC_12 = 1 << 28,
+ QMI_NAS_BAND_PREFERENCE_BC_14 = 1 << 29,
+ /* Bit 30 reserved */
+ QMI_NAS_BAND_PREFERENCE_BC_15 = 1 << 31,
+ /* Bits 32-47 reserved */
+ QMI_NAS_BAND_PREFERENCE_WCDMA_2600 = ((guint64) 1) << 48,
+ QMI_NAS_BAND_PREFERENCE_WCDMA_900 = ((guint64) 1) << 49,
+ QMI_NAS_BAND_PREFERENCE_WCDMA_1700_JAPAN = ((guint64) 1) << 50,
+ /* Bits 51-55 reserved */
+ QMI_NAS_BAND_PREFERENCE_BC_16 = ((guint64) 1) << 56,
+ QMI_NAS_BAND_PREFERENCE_BC_17 = ((guint64) 1) << 57,
+ QMI_NAS_BAND_PREFERENCE_BC_18 = ((guint64) 1) << 58,
+ QMI_NAS_BAND_PREFERENCE_BC_19 = ((guint64) 1) << 59
+ /* Bits 60-63 reserved */
+} QmiNasBandPreference;
+
+/**
+ * QmiNasLteBandPreference:
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_1: LTE EUTRAN Band 1
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_2: LTE EUTRAN Band 2.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_3: LTE EUTRAN Band 3.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_4: LTE EUTRAN Band 4.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_5: LTE EUTRAN Band 5.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_6: LTE EUTRAN Band 6.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_7: LTE EUTRAN Band 7.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_8: LTE EUTRAN Band 8.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_9: LTE EUTRAN Band 9.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_10: LTE EUTRAN Band 10.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_11: LTE EUTRAN Band 11.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_12: LTE EUTRAN Band 12.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_13: LTE EUTRAN Band 13.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_14: LTE EUTRAN Band 14.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_17: LTE EUTRAN Band 17.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_18: LTE EUTRAN Band 18.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_19: LTE EUTRAN Band 19.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_20: LTE EUTRAN Band 20.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_21: LTE EUTRAN Band 21.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_24: LTE EUTRAN Band 24.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_25: LTE EUTRAN Band 25.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_33: LTE EUTRAN Band 33.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_34: LTE EUTRAN Band 34.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_35: LTE EUTRAN Band 35.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_36: LTE EUTRAN Band 36.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_37: LTE EUTRAN Band 37.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_38: LTE EUTRAN Band 38.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_39: LTE EUTRAN Band 39.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_40: LTE EUTRAN Band 40.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_41: LTE EUTRAN Band 41.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_42: LTE EUTRAN Band 42.
+ * @QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_43: LTE EUTRAN Band 43.
+ *
+ * Flags to specify LTE-specific frequency band preferences.
+ */
+typedef enum {
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_1 = 1 << 0,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_2 = 1 << 1,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_3 = 1 << 2,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_4 = 1 << 3,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_5 = 1 << 4,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_6 = 1 << 5,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_7 = 1 << 6,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_8 = 1 << 7,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_9 = 1 << 8,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_10 = 1 << 9,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_11 = 1 << 10,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_12 = 1 << 11,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_13 = 1 << 12,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_14 = 1 << 13,
+ /* Bit 14-15 reserved */
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_17 = 1 << 16,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_18 = 1 << 17,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_19 = 1 << 18,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_20 = 1 << 19,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_21 = 1 << 20,
+ /* Bit 21-22 reserved */
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_24 = 1 << 23,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_25 = 1 << 24,
+ /* Bit 25-31 reserved */
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_33 = ((guint64) 1) << 32,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_34 = ((guint64) 1) << 33,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_35 = ((guint64) 1) << 34,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_36 = ((guint64) 1) << 35,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_37 = ((guint64) 1) << 36,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_38 = ((guint64) 1) << 37,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_39 = ((guint64) 1) << 38,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_40 = ((guint64) 1) << 39,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_41 = ((guint64) 1) << 40,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_42 = ((guint64) 1) << 41,
+ QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_43 = ((guint64) 1) << 42
+ /* Bit 43-64 reserved */
+} QmiNasLteBandPreference;
+
+#endif /* _LIBQMI_GLIB_QMI_FLAGS64_NAS_H_ */
diff --git a/src/libqmi-glib/qmi-message.c b/src/libqmi-glib/qmi-message.c
new file mode 100644
index 0000000..c3bd6e0
--- /dev/null
+++ b/src/libqmi-glib/qmi-message.c
@@ -0,0 +1,923 @@
+/* -*- 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-enums-private.h"
+#include "qmi-enum-types-private.h"
+#include "qmi-enum-types.h"
+#include "qmi-error-types.h"
+
+#include "qmi-ctl.h"
+#include "qmi-dms.h"
+#include "qmi-wds.h"
+#include "qmi-nas.h"
+#include "qmi-wms.h"
+#include "qmi-pds.h"
+#include "qmi-uim.h"
+
+/**
+ * SECTION:qmi-message
+ * @title: QmiMessage
+ * @short_description: Generic QMI message handling routines
+ *
+ * #QmiMessage is a generic type representing a QMI message of any kind
+ * (request, response, indication) or service (including #QMI_SERVICE_CTL).
+ *
+ * This set of generic routines help in handling these message types, and
+ * allow creating any kind of message with any kind of TLV.
+ **/
+
+#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;
+
+static inline gboolean
+message_is_control (QmiMessage *self)
+{
+ return ((struct full_message *)(self->data))->qmux.service == QMI_SERVICE_CTL;
+}
+
+static inline guint16
+get_qmux_length (QmiMessage *self)
+{
+ return GUINT16_FROM_LE (((struct full_message *)(self->data))->qmux.length);
+}
+
+static inline void
+set_qmux_length (QmiMessage *self,
+ guint16 length)
+{
+ ((struct full_message *)(self->data))->qmux.length = GUINT16_TO_LE (length);
+}
+
+static inline guint8
+get_qmux_flags (QmiMessage *self)
+{
+ return ((struct full_message *)(self->data))->qmux.flags;
+}
+
+static inline guint8
+get_qmi_flags (QmiMessage *self)
+{
+ if (message_is_control (self))
+ return ((struct full_message *)(self->data))->qmi.control.header.flags;
+
+ return ((struct full_message *)(self->data))->qmi.service.header.flags;
+}
+
+/**
+ * qmi_message_is_response:
+ * @self: a #QmiMessage.
+ *
+ * Checks whether the given #QmiMessage is a response.
+ *
+ * Returns: %TRUE if @self is a response message, %FALSE otherwise.
+ */
+gboolean
+qmi_message_is_response (QmiMessage *self)
+{
+ if (message_is_control (self)) {
+ if (((struct full_message *)(self->data))->qmi.control.header.flags & QMI_CTL_FLAG_RESPONSE)
+ return TRUE;
+ } else {
+ if (((struct full_message *)(self->data))->qmi.service.header.flags & QMI_SERVICE_FLAG_RESPONSE)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * qmi_message_is_indication:
+ * @self: a #QmiMessage.
+ *
+ * Checks whether the given #QmiMessage is an indication.
+ *
+ * Returns: %TRUE if @self is an indication message, %FALSE otherwise.
+ */
+gboolean
+qmi_message_is_indication (QmiMessage *self)
+{
+ if (message_is_control (self)) {
+ if (((struct full_message *)(self->data))->qmi.control.header.flags & QMI_CTL_FLAG_INDICATION)
+ return TRUE;
+ } else {
+ if (((struct full_message *)(self->data))->qmi.service.header.flags & QMI_SERVICE_FLAG_INDICATION)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * qmi_message_get_service:
+ * @self: a #QmiMessage.
+ *
+ * Gets the service corresponding to the given #QmiMessage.
+ *
+ * Returns: a #QmiService.
+ */
+QmiService
+qmi_message_get_service (QmiMessage *self)
+{
+ g_return_val_if_fail (self != NULL, QMI_SERVICE_UNKNOWN);
+
+ return (QmiService)((struct full_message *)(self->data))->qmux.service;
+}
+
+/**
+ * qmi_message_get_client_id:
+ * @self: a #QmiMessage.
+ *
+ * Gets the client ID of the message.
+ *
+ * Returns: the client ID.
+ */
+guint8
+qmi_message_get_client_id (QmiMessage *self)
+{
+ g_return_val_if_fail (self != NULL, 0);
+
+ return ((struct full_message *)(self->data))->qmux.client;
+}
+
+/**
+ * qmi_message_get_transaction_id:
+ * @self: a #QmiMessage.
+ *
+ * Gets the transaction ID of the message.
+ *
+ * Returns: the transaction ID.
+ */
+guint16
+qmi_message_get_transaction_id (QmiMessage *self)
+{
+ g_return_val_if_fail (self != NULL, 0);
+
+ if (message_is_control (self))
+ /* note: only 1 byte for transaction in CTL message */
+ return (guint16)((struct full_message *)(self->data))->qmi.control.header.transaction;
+
+ return GUINT16_FROM_LE (((struct full_message *)(self->data))->qmi.service.header.transaction);
+}
+
+/**
+ * qmi_message_get_message_id:
+ * @self: a #QmiMessage.
+ *
+ * Gets the ID of the message.
+ *
+ * Returns: the ID.
+ */
+guint16
+qmi_message_get_message_id (QmiMessage *self)
+{
+ g_return_val_if_fail (self != NULL, 0);
+
+ if (message_is_control (self))
+ return GUINT16_FROM_LE (((struct full_message *)(self->data))->qmi.control.header.message);
+
+ return GUINT16_FROM_LE (((struct full_message *)(self->data))->qmi.service.header.message);
+}
+
+/**
+ * qmi_message_get_length:
+ * @self: a #QmiMessage.
+ *
+ * Gets the length of the raw data corresponding to the given #QmiMessage.
+ *
+ * Returns: the length of the raw data.
+ */
+gsize
+qmi_message_get_length (QmiMessage *self)
+{
+ g_return_val_if_fail (self != NULL, 0);
+
+ return self->len;
+}
+
+static inline guint16
+get_all_tlvs_length (QmiMessage *self)
+{
+ if (message_is_control (self))
+ return GUINT16_FROM_LE (((struct full_message *)(self->data))->qmi.control.header.tlv_length);
+
+ return GUINT16_FROM_LE (((struct full_message *)(self->data))->qmi.service.header.tlv_length);
+}
+
+static inline void
+set_all_tlvs_length (QmiMessage *self,
+ guint16 length)
+{
+ if (message_is_control (self))
+ ((struct full_message *)(self->data))->qmi.control.header.tlv_length = GUINT16_TO_LE (length);
+ else
+ ((struct full_message *)(self->data))->qmi.service.header.tlv_length = GUINT16_TO_LE (length);
+}
+
+static inline struct tlv *
+qmi_tlv (QmiMessage *self)
+{
+ if (message_is_control (self))
+ return ((struct full_message *)(self->data))->qmi.control.tlv;
+
+ return ((struct full_message *)(self->data))->qmi.service.tlv;
+}
+
+static inline guint8 *
+qmi_end (QmiMessage *self)
+{
+ return (guint8 *) self->data + self->len;
+}
+
+static inline struct tlv *
+tlv_next (struct tlv *tlv)
+{
+ return (struct tlv *)((guint8 *)tlv + sizeof(struct tlv) + GUINT16_FROM_LE (tlv->length));
+}
+
+static inline struct tlv *
+qmi_tlv_first (QmiMessage *self)
+{
+ if (get_all_tlvs_length (self))
+ return qmi_tlv (self);
+
+ return NULL;
+}
+
+static inline 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: %TRUE if the message is valid, %FALSE otherwise.
+ */
+static gboolean
+message_check (QmiMessage *self,
+ GError **error)
+{
+ gsize header_length;
+ guint8 *end;
+ struct tlv *tlv;
+
+ if (((struct full_message *)(self->data))->marker != QMI_MESSAGE_QMUX_MARKER) {
+ g_set_error (error,
+ QMI_CORE_ERROR,
+ QMI_CORE_ERROR_INVALID_MESSAGE,
+ "Marker is incorrect");
+ return FALSE;
+ }
+
+ if (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 ")",
+ 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 (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 != %u)",
+ get_qmux_length (self), self->len - 1);
+ return FALSE;
+ }
+
+ header_length = sizeof (struct qmux) + (message_is_control (self) ?
+ sizeof (struct control_header) :
+ sizeof (struct service_header));
+
+ if (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 ")",
+ get_qmux_length (self), header_length);
+ return FALSE;
+ }
+
+ if (get_qmux_length (self) - header_length != get_all_tlvs_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)",
+ get_qmux_length (self), header_length, get_all_tlvs_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 + GUINT16_FROM_LE (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, GUINT16_FROM_LE (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;
+}
+
+/**
+ * qmi_message_new:
+ * @service: a #QmiService
+ * @client_id: client ID of the originating control point.
+ * @transaction_id: transaction ID.
+ * @message_id: message ID.
+ *
+ * Create a new #QmiMessage with the specified parameters.
+ *
+ * Note that @transaction_id must be less than #G_MAXUINT8 if @service is
+ * #QMI_SERVICE_CTL.
+ *
+ * Returns: (transfer full): a newly created #QmiMessage. The returned value should be freed with qmi_message_unref().
+ */
+QmiMessage *
+qmi_message_new (QmiService service,
+ guint8 client_id,
+ guint16 transaction_id,
+ guint16 message_id)
+{
+ GByteArray *self;
+ struct full_message *buffer;
+ gsize buffer_len;
+
+ /* Transaction ID in the control service is 8bit only */
+ g_return_val_if_fail ((service != QMI_SERVICE_CTL || transaction_id <= G_MAXUINT8),
+ NULL);
+
+ /* Create array with enough size for the QMUX marker, the QMUX header and
+ * the QMI header */
+ buffer_len = (1 +
+ sizeof (struct qmux) +
+ (service == QMI_SERVICE_CTL ? sizeof (struct control_header) : sizeof (struct service_header)));
+ buffer = g_malloc (buffer_len);
+
+ buffer->marker = QMI_MESSAGE_QMUX_MARKER;
+ buffer->qmux.flags = 0;
+ buffer->qmux.service = service;
+ buffer->qmux.client = client_id;
+
+ if (service == QMI_SERVICE_CTL) {
+ buffer->qmi.control.header.flags = 0;
+ buffer->qmi.control.header.transaction = (guint8)transaction_id;
+ buffer->qmi.control.header.message = GUINT16_TO_LE (message_id);
+ } else {
+ buffer->qmi.service.header.flags = 0;
+ buffer->qmi.service.header.transaction = GUINT16_TO_LE (transaction_id);
+ buffer->qmi.service.header.message = GUINT16_TO_LE (message_id);
+ }
+
+ /* Create the GByteArray */
+ self = g_byte_array_new_take ((guint8 *)buffer, buffer_len);
+
+ /* Update length fields. */
+ set_qmux_length (self, buffer_len - 1); /* QMUX marker not included in length */
+ set_all_tlvs_length (self, 0);
+
+ /* We shouldn't create invalid empty messages */
+ g_assert (message_check (self, NULL));
+
+ return (QmiMessage *)self;
+}
+
+/**
+ * qmi_message_ref:
+ * @self: a #QmiMessage.
+ *
+ * Atomically increments the reference count of @self by one.
+ *
+ * Returns: (transfer full) the new reference to @self.
+ */
+QmiMessage *
+qmi_message_ref (QmiMessage *self)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+
+ return (QmiMessage *)g_byte_array_ref (self);
+}
+
+/**
+ * qmi_message_unref:
+ * @self: a #QmiMessage.
+ *
+ * Atomically decrements the reference count of @self by one.
+ * If the reference count drops to 0, @self is completely disposed.
+ */
+void
+qmi_message_unref (QmiMessage *self)
+{
+ g_return_if_fail (self != NULL);
+
+ g_byte_array_unref (self);
+}
+
+/**
+ * qmi_message_get_raw:
+ * @self: a #QmiMessage.
+ * @length: (out): return location for the size of the output buffer.
+ * @error: return location for error or %NULL.
+ *
+ * Gets the raw data buffer of the #QmiMessage.
+ *
+ * Returns: (transfer none): The raw data buffer, or #NULL if @error is set.
+ */
+const guint8 *
+qmi_message_get_raw (QmiMessage *self,
+ gsize *length,
+ GError **error)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (length != NULL, NULL);
+
+ *length = self->len;
+ return self->data;
+}
+
+/**
+ * qmi_message_get_raw_tlv:
+ * @self: a #QmiMessage.
+ * @type: specific ID of the TLV to get.
+ * @length: (out): return location for the length of the TLV.
+ *
+ * Get the raw data buffer of a specific TLV within the #QmiMessage.
+ *
+ * Returns: (transfer none): The raw data buffer of the TLV, or #NULL if not found.
+ */
+const guint8 *
+qmi_message_get_raw_tlv (QmiMessage *self,
+ guint8 type,
+ guint16 *length)
+{
+ struct tlv *tlv;
+
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (length != NULL, NULL);
+
+ for (tlv = qmi_tlv_first (self); tlv; tlv = qmi_tlv_next (self, tlv)) {
+ if (tlv->type == type) {
+ *length = GUINT16_FROM_LE (tlv->length);
+ return (guint8 *)&(tlv->value[0]);
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * qmi_message_foreach_raw_tlv:
+ * @self: a #QmiMessage.
+ * @func: the function to call for each TLV.
+ * @user_data: user data to pass to the function.
+ *
+ * Calls the given function for each TLV found within the #QmiMessage.
+ */
+void
+qmi_message_foreach_raw_tlv (QmiMessage *self,
+ QmiMessageForeachRawTlvFn func,
+ gpointer user_data)
+{
+ struct tlv *tlv;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (func != NULL);
+
+ for (tlv = qmi_tlv_first (self); tlv; tlv = qmi_tlv_next (self, tlv)) {
+ func (tlv->type,
+ (const guint8 *)tlv->value,
+ (gsize)(GUINT16_FROM_LE (tlv->length)),
+ user_data);
+ }
+}
+
+/**
+ * qmi_message_add_raw_tlv:
+ * @self: a #QmiMessage.
+ * @type: specific ID of the TLV to add.
+ * @raw: raw data buffer with the value of the TLV.
+ * @length: length of the raw data buffer.
+ * @error: return location for error or %NULL.
+ *
+ * Creates a new @type TLV with the value given in @raw, and adds it to the #QmiMessage.
+ *
+ * Returns: %TRUE if the TLV as successfully added, otherwise %FALSE is returned and @error is set.
+ */
+gboolean
+qmi_message_add_raw_tlv (QmiMessage *self,
+ guint8 type,
+ const guint8 *raw,
+ gsize length,
+ GError **error)
+{
+ size_t tlv_len;
+ struct tlv *tlv;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+ g_return_val_if_fail (raw != NULL, FALSE);
+ g_return_val_if_fail (length > 0, FALSE);
+
+ /* Find length of new TLV */
+ tlv_len = sizeof (struct tlv) + length;
+
+ /* Check for overflow of message size. */
+ if (get_qmux_length (self) + tlv_len > G_MAXUINT16) {
+ g_set_error (error,
+ QMI_CORE_ERROR,
+ QMI_CORE_ERROR_TLV_TOO_LONG,
+ "TLV to add is too long");
+ return FALSE;
+ }
+
+ /* Resize buffer. */
+ g_byte_array_set_size (self, self->len + tlv_len);
+
+ /* Fill in new TLV. */
+ tlv = (struct tlv *)(qmi_end (self) - tlv_len);
+ tlv->type = type;
+ tlv->length = GUINT16_TO_LE (length);
+ memcpy (tlv->value, raw, length);
+
+ /* Update length fields. */
+ set_qmux_length (self, (guint16)(get_qmux_length (self) + tlv_len));
+ set_all_tlvs_length (self, (guint16)(get_all_tlvs_length (self) + tlv_len));
+
+ /* Make sure we didn't break anything. */
+ g_assert (message_check (self, error));
+
+ return TRUE;
+}
+
+/**
+ * qmi_message_new_from_raw:
+ * @raw: (inout): raw data buffer.
+ * @error: return location for error or %NULL.
+ *
+ * Create a new #QmiMessage from the given raw data buffer.
+ *
+ * Whenever a complete QMI message is read, its raw data gets removed from the @raw buffer.
+ *
+ * Returns: (transfer full): a newly created #QmiMessage, which should be freed with qmi_message_unref(). If @raw doesn't contain a complete QMI message #NULL is returned. If there is a complete QMI message but it appears not to be valid, #NULL is returned and @error is set.
+ */
+QmiMessage *
+qmi_message_new_from_raw (GByteArray *raw,
+ GError **error)
+{
+ GByteArray *self;
+ gsize message_len;
+
+ g_return_val_if_fail (raw != NULL, NULL);
+
+ /* If we didn't even read the QMUX header (comes after the 1-byte marker),
+ * leave */
+ if (raw->len < (sizeof (struct qmux) + 1))
+ return NULL;
+
+ /* We need to have read the length reported by the QMUX header (plus the
+ * initial 1-byte marker) */
+ message_len = GUINT16_FROM_LE (((struct full_message *)raw->data)->qmux.length);
+ if (raw->len < (message_len + 1)) {
+ g_printerr ("\ngot '%u' bytes, need '%u' bytes\n",
+ (guint)raw->len,
+ (guint)(message_len + 1));
+ return NULL;
+ }
+
+ /* Ok, so we should have all the data available already */
+ self = g_byte_array_sized_new (message_len + 1);
+ g_byte_array_prepend (self, raw->data, message_len + 1);
+
+ /* We got a complete QMI message, remove from input buffer */
+ g_byte_array_remove_range (raw, 0, self->len);
+
+ /* Check input message validity as soon as we create the QmiMessage */
+ if (!message_check (self, error)) {
+ /* Yes, we lose the whole message here */
+ qmi_message_unref (self);
+ return NULL;
+ }
+
+ return (QmiMessage *)self;
+}
+
+/**
+ * qmi_message_get_tlv_printable:
+ * @self: a #QmiMessage.
+ * @line_prefix: prefix string to use in each new generated line.
+ * @type: type of the TLV.
+ * @raw: raw data buffer with the value of the TLV.
+ * @raw_length: length of the raw data buffer.
+ *
+ * Gets a printable string with the contents of the TLV.
+ *
+ * This method is the most generic one and doesn't try to translate the TLV contents.
+ *
+ * Returns: (transfer full): a newly allocated string, which should be freed with g_free().
+ */
+gchar *
+qmi_message_get_tlv_printable (QmiMessage *self,
+ const gchar *line_prefix,
+ guint8 type,
+ const guint8 *raw,
+ gsize raw_length)
+{
+ gchar *printable;
+ gchar *value_hex;
+
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (line_prefix != NULL, NULL);
+ g_return_val_if_fail (raw != NULL, NULL);
+ g_return_val_if_fail (raw_length > 0, NULL);
+
+ value_hex = __qmi_utils_str_hex (raw, raw_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, raw_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->value,
+ tlv->length);
+ g_string_append (printable, printable_tlv);
+ g_free (printable_tlv);
+ }
+
+ return g_string_free (printable, FALSE);
+}
+
+/**
+ * qmi_message_get_printable:
+ * @self: a #QmiMessage.
+ * @line_prefix: prefix string to use in each new generated line.
+ *
+ * Gets a printable string with the contents of the whole QMI message.
+ *
+ * If known, the printable string will contain translated TLV values as well as the raw
+ * data buffer contents.
+ *
+ * Returns: (transfer full): a newly allocated string, which should be freed with g_free().
+ */
+gchar *
+qmi_message_get_printable (QmiMessage *self,
+ const gchar *line_prefix)
+{
+ GString *printable;
+ gchar *qmi_flags_str;
+ gchar *contents;
+
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (line_prefix != NULL, 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, get_qmux_length (self),
+ line_prefix, 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 (get_qmi_flags (self));
+ else
+ qmi_flags_str = qmi_service_flag_build_string_from_mask (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, get_all_tlvs_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;
+ case QMI_SERVICE_NAS:
+ contents = __qmi_message_nas_get_printable (self, line_prefix);
+ break;
+ case QMI_SERVICE_WMS:
+ contents = __qmi_message_wms_get_printable (self, line_prefix);
+ break;
+ case QMI_SERVICE_PDS:
+ contents = __qmi_message_pds_get_printable (self, line_prefix);
+ break;
+ case QMI_SERVICE_UIM:
+ contents = __qmi_message_uim_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);
+}
+
+/**
+ * qmi_message_get_version_introduced:
+ * @self: a #QmiMessage.
+ * @major: (out) return location for the major version.
+ * @minor: (out) return location for the minor version.
+ *
+ * Gets, if known, the service version in which the given message was first introduced.
+ *
+ * Returns: %TRUE if @major and @minor are set, %FALSE otherwise.
+ */
+gboolean
+qmi_message_get_version_introduced (QmiMessage *self,
+ guint *major,
+ guint *minor)
+{
+ switch (qmi_message_get_service (self)) {
+ case QMI_SERVICE_CTL:
+ /* For CTL service, we'll assume the minimum one */
+ *major = 0;
+ *minor = 0;
+ return TRUE;
+
+ case QMI_SERVICE_DMS:
+ return __qmi_message_dms_get_version_introduced (self, major, minor);
+
+ case QMI_SERVICE_WDS:
+ return __qmi_message_wds_get_version_introduced (self, major, minor);
+
+ case QMI_SERVICE_NAS:
+ return __qmi_message_nas_get_version_introduced (self, major, minor);
+
+ case QMI_SERVICE_WMS:
+ return __qmi_message_wms_get_version_introduced (self, major, minor);
+
+ case QMI_SERVICE_PDS:
+ return __qmi_message_pds_get_version_introduced (self, major, minor);
+
+ case QMI_SERVICE_UIM:
+ return __qmi_message_uim_get_version_introduced (self, major, minor);
+
+ default:
+ /* For the still unsupported services, cannot do anything */
+ return FALSE;
+ }
+}
diff --git a/src/libqmi-glib/qmi-message.h b/src/libqmi-glib/qmi-message.h
new file mode 100644
index 0000000..ae88671
--- /dev/null
+++ b/src/libqmi-glib/qmi-message.h
@@ -0,0 +1,114 @@
+/* -*- 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_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+#include <glib.h>
+
+#include "qmi-enums.h"
+
+G_BEGIN_DECLS
+
+#define QMI_MESSAGE_QMUX_MARKER (guint8)0x01
+
+/**
+ * QmiMessage:
+ *
+ * An opaque type representing a QMI message.
+ */
+typedef GByteArray QmiMessage;
+
+/*****************************************************************************/
+/* QMI Message life cycle */
+
+QmiMessage *qmi_message_new (QmiService service,
+ guint8 client_id,
+ guint16 transaction_id,
+ guint16 message_id);
+QmiMessage *qmi_message_new_from_raw (GByteArray *raw,
+ GError **error);
+QmiMessage *qmi_message_ref (QmiMessage *self);
+void qmi_message_unref (QmiMessage *self);
+
+/*****************************************************************************/
+/* QMI Message content getters */
+
+gboolean qmi_message_is_response (QmiMessage *self);
+gboolean qmi_message_is_indication (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);
+guint16 qmi_message_get_message_id (QmiMessage *self);
+gsize qmi_message_get_length (QmiMessage *self);
+const guint8 *qmi_message_get_raw (QmiMessage *self,
+ gsize *length,
+ GError **error);
+gboolean qmi_message_get_version_introduced (QmiMessage *self,
+ guint *major,
+ guint *minor);
+
+/*****************************************************************************/
+/* Raw TLV handling */
+
+typedef void (* QmiMessageForeachRawTlvFn) (guint8 type,
+ const guint8 *value,
+ gsize length,
+ gpointer user_data);
+void qmi_message_foreach_raw_tlv (QmiMessage *self,
+ QmiMessageForeachRawTlvFn func,
+ gpointer user_data);
+const guint8 *qmi_message_get_raw_tlv (QmiMessage *self,
+ guint8 type,
+ guint16 *length);
+gboolean qmi_message_add_raw_tlv (QmiMessage *self,
+ guint8 type,
+ const guint8 *raw,
+ gsize length,
+ GError **error);
+
+/*****************************************************************************/
+/* Printable helpers */
+
+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,
+ const guint8 *raw,
+ gsize raw_length);
+
+G_END_DECLS
+
+#endif /* _LIBQMI_GLIB_QMI_MESSAGE_H_ */
diff --git a/src/libqmi-glib/qmi-utils.c b/src/libqmi-glib/qmi-utils.c
new file mode 100644
index 0000000..8482277
--- /dev/null
+++ b/src/libqmi-glib/qmi-utils.c
@@ -0,0 +1,1024 @@
+/* -*- 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>
+ * Copyright (C) 2012 Dan Williams <dcbw@redhat.com>
+ */
+
+#include <config.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "qmi-utils.h"
+
+/**
+ * SECTION:qmi-utils
+ * @title: Common utilities
+ *
+ * This section exposes a set of common utilities that may be used to work
+ * with the QMI library.
+ **/
+
+/*****************************************************************************/
+
+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;
+}
+
+/*****************************************************************************/
+
+#if defined UTILS_ENABLE_TRACE
+static void
+print_read_bytes_trace (const gchar *type,
+ gconstpointer buffer,
+ gconstpointer out,
+ guint n_bytes)
+{
+ gchar *str1;
+ gchar *str2;
+
+ str1 = __qmi_utils_str_hex (buffer, n_bytes, ':');
+ str2 = __qmi_utils_str_hex (out, n_bytes, ':');
+
+ g_debug ("Read %s (%s) --> (%s)", type, str1, str2);
+ g_warn_if_fail (g_str_equal (str1, str2));
+
+ g_free (str1);
+ g_free (str2);
+}
+#else
+#define print_read_bytes_trace(...)
+#endif
+
+/**
+ * qmi_utils_read_guint8_from_buffer:
+ * @buffer: a buffer with raw binary data.
+ * @buffer_size: size of @buffer.
+ * @out: return location for the read variable.
+ *
+ * Reads an unsigned byte from the buffer.
+ *
+ * The user needs to make sure that at least 1 byte is available
+ * in the buffer.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 1 byte
+ * read.
+ */
+void
+qmi_utils_read_guint8_from_buffer (const 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];
+
+ print_read_bytes_trace ("guint8", &(*buffer)[0], out, 1);
+
+ *buffer = &((*buffer)[1]);
+ *buffer_size = (*buffer_size) - 1;
+}
+
+/**
+ * qmi_utils_read_gint8_from_buffer:
+ * @buffer: a buffer with raw binary data.
+ * @buffer_size: size of @buffer.
+ * @out: return location for the read variable.
+ *
+ * Reads a signed byte from the buffer.
+ *
+ * The user needs to make sure that at least 1 byte is available
+ * in the buffer.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 1 byte
+ * read.
+ */
+void
+qmi_utils_read_gint8_from_buffer (const 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];
+
+ print_read_bytes_trace ("gint8", &(*buffer)[0], out, 1);
+
+ *buffer = &((*buffer)[1]);
+ *buffer_size = (*buffer_size) - 1;
+}
+
+/**
+ * qmi_utils_read_guint16_from_buffer:
+ * @buffer: a buffer with raw binary data.
+ * @buffer_size: size of @buffer.
+ * @endian: endianness of firmware value; swapped to host byte order if necessary
+ * @out: return location for the read variable.
+ *
+ * Reads an unsigned 16-bit integer from the buffer. The number in the buffer is
+ * expected to be given in the byte order specificed by @endian, and this method
+ * takes care of converting the read value to the proper host endianness.
+ *
+ * The user needs to make sure that at least 2 bytes are available
+ * in the buffer.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 2 bytes
+ * read.
+ */
+void
+qmi_utils_read_guint16_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ guint16 *out)
+{
+ g_assert (out != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= 2);
+
+ memcpy (out, &((*buffer)[0]), 2);
+ if (endian == QMI_ENDIAN_BIG)
+ *out = GUINT16_FROM_BE (*out);
+ else
+ *out = GUINT16_FROM_LE (*out);
+
+ print_read_bytes_trace ("guint16", &(*buffer)[0], out, 2);
+
+ *buffer = &((*buffer)[2]);
+ *buffer_size = (*buffer_size) - 2;
+}
+
+/**
+ * qmi_utils_read_gint16_from_buffer:
+ * @buffer: a buffer with raw binary data.
+ * @buffer_size: size of @buffer.
+ * @endian: endianness of firmware value; swapped to host byte order if necessary
+ * @out: return location for the read variable.
+ *
+ * Reads a signed 16-bit integer from the buffer. The number in the buffer is
+ * expected to be given in the byte order specified by @endian, and this method
+ * takes care of converting the read value to the proper host endianness.
+ *
+ * The user needs to make sure that at least 2 bytes are available
+ * in the buffer.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 2 bytes
+ * read.
+ */
+void
+qmi_utils_read_gint16_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ gint16 *out)
+{
+ g_assert (out != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= 2);
+
+ memcpy (out, &((*buffer)[0]), 2);
+ if (endian == QMI_ENDIAN_BIG)
+ *out = GINT16_FROM_BE (*out);
+ else
+ *out = GINT16_FROM_LE (*out);
+
+ print_read_bytes_trace ("gint16", &(*buffer)[0], out, 2);
+
+ *buffer = &((*buffer)[2]);
+ *buffer_size = (*buffer_size) - 2;
+}
+
+/**
+ * qmi_utils_read_guint32_from_buffer:
+ * @buffer: a buffer with raw binary data.
+ * @buffer_size: size of @buffer.
+ * @endian: endianness of firmware value; swapped to host byte order if necessary
+ * @out: return location for the read variable.
+ *
+ * Reads an unsigned 32-bit integer from the buffer. The number in the buffer is
+ * expected to be given in the byte order specified by @endian, and this method
+ * takes care of converting the read value to the proper host endianness.
+ *
+ * The user needs to make sure that at least 4 bytes are available
+ * in the buffer.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 4 bytes
+ * read.
+ */
+void
+qmi_utils_read_guint32_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ guint32 *out)
+{
+ g_assert (out != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= 4);
+
+ memcpy (out, &((*buffer)[0]), 4);
+ if (endian == QMI_ENDIAN_BIG)
+ *out = GUINT32_FROM_BE (*out);
+ else
+ *out = GUINT32_FROM_LE (*out);
+
+ print_read_bytes_trace ("guint32", &(*buffer)[0], out, 4);
+
+ *buffer = &((*buffer)[4]);
+ *buffer_size = (*buffer_size) - 4;
+}
+
+/**
+ * qmi_utils_read_gint32_from_buffer:
+ * @buffer: a buffer with raw binary data.
+ * @buffer_size: size of @buffer.
+ * @endian: endianness of firmware value; swapped to host byte order if necessary
+ * @out: return location for the read variable.
+ *
+ * Reads a signed 32-bit integer from the buffer. The number in the buffer is
+ * expected to be given in the byte order specified by @endian, and this method
+ * takes care of converting the read value to the proper host endianness.
+ *
+ * The user needs to make sure that at least 4 bytes are available
+ * in the buffer.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 4 bytes
+ * read.
+ */
+void
+qmi_utils_read_gint32_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ gint32 *out)
+{
+ g_assert (out != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= 4);
+
+ memcpy (out, &((*buffer)[0]), 4);
+ if (endian == QMI_ENDIAN_BIG)
+ *out = GINT32_FROM_BE (*out);
+ else
+ *out = GINT32_FROM_LE (*out);
+
+ print_read_bytes_trace ("gint32", &(*buffer)[0], out, 4);
+
+ *buffer = &((*buffer)[4]);
+ *buffer_size = (*buffer_size) - 4;
+}
+
+/**
+ * qmi_utils_read_guint64_from_buffer:
+ * @buffer: a buffer with raw binary data.
+ * @buffer_size: size of @buffer.
+ * @endian: endianness of firmware value; swapped to host byte order if necessary
+ * @out: return location for the read variable.
+ *
+ * Reads an unsigned 64-bit integer from the buffer. The number in the buffer is
+ * expected to be given in the byte order specified by @endian, and this method
+ * takes care of converting the read value to the proper host endianness.
+ *
+ * The user needs to make sure that at least 8 bytes are available
+ * in the buffer.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 8 bytes
+ * read.
+ */
+void
+qmi_utils_read_guint64_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ guint64 *out)
+{
+ g_assert (out != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= 8);
+
+ memcpy (out, &((*buffer)[0]), 8);
+ if (endian == QMI_ENDIAN_BIG)
+ *out = GUINT64_FROM_BE (*out);
+ else
+ *out = GUINT64_FROM_LE (*out);
+
+ print_read_bytes_trace ("guint64", &(*buffer)[0], out, 8);
+
+ *buffer = &((*buffer)[8]);
+ *buffer_size = (*buffer_size) - 8;
+}
+
+/**
+ * qmi_utils_read_gint64_from_buffer:
+ * @buffer: a buffer with raw binary data.
+ * @buffer_size: size of @buffer.
+ * @endian: endianness of firmware value; swapped to host byte order if necessary
+ * @out: return location for the read variable.
+ *
+ * Reads a signed 64-bit integer from the buffer. The number in the buffer is
+ * expected to be given in the byte order specified by @endian, and this method
+ * takes care of converting the read value to the proper host endianness.
+ *
+ * The user needs to make sure that at least 8 bytes are available
+ * in the buffer.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 8 bytes
+ * read.
+ */
+void
+qmi_utils_read_gint64_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ gint64 *out)
+{
+ g_assert (out != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= 8);
+
+ memcpy (out, &((*buffer)[0]), 8);
+ if (endian == QMI_ENDIAN_BIG)
+ *out = GINT64_FROM_BE (*out);
+ else
+ *out = GINT64_FROM_LE (*out);
+
+ print_read_bytes_trace ("gint64", &(*buffer)[0], out, 8);
+
+ *buffer = &((*buffer)[8]);
+ *buffer_size = (*buffer_size) - 8;
+}
+
+/**
+ * qmi_utils_read_sized_guint_from_buffer:
+ * @buffer: a buffer with raw binary data.
+ * @buffer_size: size of @buffer.
+ * @n_bytes: number of bytes to read.
+ * @endian: endianness of firmware value; swapped to host byte order if necessary
+ * @out: return location for the read variable.
+ *
+ * Reads a @n_bytes-sized unsigned integer from the buffer. The number in the
+ * buffer is expected to be given in the byte order specified by @endian, and
+ * this method takes care of converting the read value to the proper host
+ * endianness.
+ *
+ * The user needs to make sure that at least @n_bytes bytes are available
+ * in the buffer.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the @n_bytes
+ * bytes read.
+ */
+void
+qmi_utils_read_sized_guint_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ guint n_bytes,
+ QmiEndian endian,
+ guint64 *out)
+{
+ g_assert (out != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= n_bytes);
+ g_assert (n_bytes <= 8);
+
+ *out = 0;
+
+ /* In Little Endian, we copy the bytes to the beginning of the output
+ * buffer. */
+ if (endian == QMI_ENDIAN_LITTLE) {
+ memcpy (out, *buffer, n_bytes);
+ *out = GUINT64_FROM_LE (*out);
+ }
+ /* In Big Endian, we copy the bytes to the end of the output buffer */
+ else {
+ guint8 tmp[8] = { 0 };
+
+ memcpy (&tmp[8 - n_bytes], *buffer, n_bytes);
+ memcpy (out, &tmp[0], 8);
+ *out = GUINT64_FROM_BE (*out);
+ }
+
+ *buffer = &((*buffer)[n_bytes]);
+ *buffer_size = (*buffer_size) - n_bytes;
+}
+
+/**
+ * qmi_utils_write_guint8_to_buffer:
+ * @buffer: a buffer.
+ * @buffer_size: size of @buffer.
+ * @in: location of the variable to be written.
+ *
+ * Writes an unsigned byte into the buffer.
+ *
+ * The user needs to make sure that the buffer is at least 1 byte long.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 1 byte
+ * write.
+ */
+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);
+
+ memcpy (&(*buffer)[0], in, sizeof (*in));
+
+ *buffer = &((*buffer)[1]);
+ *buffer_size = (*buffer_size) - 1;
+}
+
+/**
+ * qmi_utils_write_gint8_to_buffer:
+ * @buffer: a buffer.
+ * @buffer_size: size of @buffer.
+ * @in: location of the variable to be written.
+ *
+ * Writes a signed byte into the buffer.
+ *
+ * The user needs to make sure that the buffer is at least 1 byte long.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 1 byte
+ * write.
+ */
+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);
+
+ memcpy (&(*buffer)[0], in, sizeof (*in));
+
+ *buffer = &((*buffer)[1]);
+ *buffer_size = (*buffer_size) - 1;
+}
+
+/**
+ * qmi_utils_write_guint16_to_buffer:
+ * @buffer: a buffer.
+ * @buffer_size: size of @buffer.
+ * @endian: endianness of firmware value; swapped from host byte order if necessary
+ * @in: location of the variable to be written.
+ *
+ * Writes an unsigned 16-bit integer into the buffer. The number to be written
+ * is expected to be given in host endianness, and this method takes care of
+ * converting the value written to the byte order specified by @endian.
+ *
+ * The user needs to make sure that the buffer is at least 2 bytes long.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 2 bytes
+ * write.
+ */
+void
+qmi_utils_write_guint16_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ guint16 *in)
+{
+ guint16 tmp;
+
+ g_assert (in != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= 2);
+
+ if (endian == QMI_ENDIAN_BIG)
+ tmp = GUINT16_TO_BE (*in);
+ else
+ tmp = GUINT16_TO_LE (*in);
+ memcpy (&(*buffer)[0], &tmp, sizeof (tmp));
+
+ *buffer = &((*buffer)[2]);
+ *buffer_size = (*buffer_size) - 2;
+}
+
+/**
+ * qmi_utils_write_gint16_to_buffer:
+ * @buffer: a buffer.
+ * @buffer_size: size of @buffer.
+ * @endian: endianness of firmware value; swapped from host byte order if necessary
+ * @in: location of the variable to be written.
+ *
+ * Writes a signed 16-bit integer into the buffer. The number to be written
+ * is expected to be given in host endianness, and this method takes care of
+ * converting the value written to the byte order specified by @endian.
+ *
+ * The user needs to make sure that the buffer is at least 2 bytes long.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 2 bytes
+ * write.
+ */
+void
+qmi_utils_write_gint16_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ gint16 *in)
+{
+ gint16 tmp;
+
+ g_assert (in != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= 2);
+
+ if (endian == QMI_ENDIAN_BIG)
+ tmp = GINT16_TO_BE (*in);
+ else
+ tmp = GINT16_TO_LE (*in);
+ memcpy (&(*buffer)[0], &tmp, sizeof (tmp));
+
+ *buffer = &((*buffer)[2]);
+ *buffer_size = (*buffer_size) - 2;
+}
+
+/**
+ * qmi_utils_write_guint32_to_buffer:
+ * @buffer: a buffer.
+ * @buffer_size: size of @buffer.
+ * @endian: endianness of firmware value; swapped from host byte order if necessary
+ * @in: location of the variable to be written.
+ *
+ * Writes an unsigned 32-bit integer into the buffer. The number to be written
+ * is expected to be given in host endianness, and this method takes care of
+ * converting the value written to the byte order specified by @endian.
+ *
+ * The user needs to make sure that the buffer is at least 4 bytes long.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 4 bytes
+ * write.
+ */
+void
+qmi_utils_write_guint32_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ guint32 *in)
+{
+ guint32 tmp;
+
+ g_assert (in != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= 4);
+
+ if (endian == QMI_ENDIAN_BIG)
+ tmp = GUINT32_TO_BE (*in);
+ else
+ tmp = GUINT32_TO_LE (*in);
+ memcpy (&(*buffer)[0], &tmp, sizeof (tmp));
+
+ *buffer = &((*buffer)[4]);
+ *buffer_size = (*buffer_size) - 4;
+}
+
+/**
+ * qmi_utils_write_gint32_to_buffer:
+ * @buffer: a buffer.
+ * @buffer_size: size of @buffer.
+ * @endian: endianness of firmware value; swapped from host byte order if necessary
+ * @in: location of the variable to be written.
+ *
+ * Writes a signed 32-bit integer into the buffer. The number to be written
+ * is expected to be given in host endianness, and this method takes care of
+ * converting the value written to the byte order specified by @endian.
+ *
+ * The user needs to make sure that the buffer is at least 4 bytes long.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 4 bytes
+ * write.
+ */
+void
+qmi_utils_write_gint32_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ gint32 *in)
+{
+ gint32 tmp;
+
+ g_assert (in != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= 4);
+
+ if (endian == QMI_ENDIAN_BIG)
+ tmp = GINT32_TO_BE (*in);
+ else
+ tmp = GINT32_TO_LE (*in);
+ memcpy (&(*buffer)[0], &tmp, sizeof (tmp));
+
+ *buffer = &((*buffer)[4]);
+ *buffer_size = (*buffer_size) - 4;
+}
+
+/**
+ * qmi_utils_write_guint64_to_buffer:
+ * @buffer: a buffer.
+ * @buffer_size: size of @buffer.
+ * @endian: endianness of firmware value; swapped from host byte order if necessary
+ * @in: location of the variable to be written.
+ *
+ * Writes an unsigned 64-bit integer into the buffer. The number to be written
+ * is expected to be given in host endianness, and this method takes care of
+ * converting the value written to the byte order specified by @endian.
+ *
+ * The user needs to make sure that the buffer is at least 8 bytes long.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 8 bytes
+ * write.
+ */
+void
+qmi_utils_write_guint64_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ guint64 *in)
+{
+ guint64 tmp;
+
+ g_assert (in != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= 8);
+
+ if (endian == QMI_ENDIAN_BIG)
+ tmp = GUINT64_TO_BE (*in);
+ else
+ tmp = GUINT64_TO_LE (*in);
+ memcpy (&(*buffer)[0], &tmp, sizeof (tmp));
+
+ *buffer = &((*buffer)[8]);
+ *buffer_size = (*buffer_size) - 8;
+}
+
+/**
+ * qmi_utils_write_gint64_to_buffer:
+ * @buffer: a buffer.
+ * @buffer_size: size of @buffer.
+ * @endian: endianness of firmware value; swapped from host byte order if necessary
+ * @in: location of the variable to be written.
+ *
+ * Writes a signed 64-bit integer into the buffer. The number to be written
+ * is expected to be given in host endianness, and this method takes care of
+ * converting the value written to the byte order specified by @endian.
+ *
+ * The user needs to make sure that the buffer is at least 8 bytes long.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the 8 bytes
+ * write.
+ */
+void
+qmi_utils_write_gint64_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ gint64 *in)
+{
+ gint64 tmp;
+
+ g_assert (in != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= 8);
+
+ if (endian == QMI_ENDIAN_BIG)
+ tmp = GINT64_TO_BE (*in);
+ else
+ tmp = GINT64_TO_LE (*in);
+ memcpy (&(*buffer)[0], &tmp, sizeof (tmp));
+
+ *buffer = &((*buffer)[8]);
+ *buffer_size = (*buffer_size) - 8;
+}
+
+/**
+ * qmi_utils_write_sized_guint_to_buffer:
+ * @buffer: a buffer.
+ * @buffer_size: size of @buffer.
+ * @n_bytes: number of bytes to write.
+ * @endian: endianness of firmware value; swapped from host byte order if necessary
+ * @in: location of the variable to be written.
+ *
+ * Writes a @n_bytes-sized unsigned integer into the buffer. The number to be
+ * written is expected to be given in host endianness, and this method takes
+ * care of converting the value written to the byte order specified by @endian.
+ *
+ * The user needs to make sure that the buffer is at least @n_bytes bytes long.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the @n_bytes
+ * bytes write.
+ */
+void
+qmi_utils_write_sized_guint_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ guint n_bytes,
+ QmiEndian endian,
+ guint64 *in)
+{
+ guint64 tmp;
+
+ g_assert (in != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (*buffer_size >= n_bytes);
+ g_assert (n_bytes <= 8);
+
+ if (endian == QMI_ENDIAN_BIG)
+ tmp = GUINT64_TO_BE (*in);
+ else
+ tmp = GUINT64_TO_LE (*in);
+
+ /* In Little Endian, we read the bytes from the beginning of the buffer */
+ if (endian == QMI_ENDIAN_LITTLE) {
+ memcpy (*buffer, &tmp, n_bytes);
+ }
+ /* In Big Endian, we read the bytes from the end of the buffer */
+ else {
+ guint8 tmp_buffer[8];
+
+ memcpy (&tmp_buffer[0], &tmp, 8);
+ memcpy (*buffer, &tmp_buffer[8 - n_bytes], n_bytes);
+ }
+
+ *buffer = &((*buffer)[n_bytes]);
+ *buffer_size = (*buffer_size) - n_bytes;
+}
+
+/**
+ * qmi_utils_read_string_from_buffer:
+ * @buffer: a buffer with raw binary data.
+ * @buffer_size: size of @buffer.
+ * @length_prefix_size: size of the length prefix integer in bits.
+ * @max_size: maximum number of bytes to read, or 0 to read all available bytes.
+ * @out: return location for the read string. The returned value should be freed with g_free().
+ *
+ * Reads a string from the buffer.
+ *
+ * If @length_prefix_size is greater than 0, only the amount of bytes given
+ * there will be read. Otherwise, up to @buffer_size bytes will be read.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the write.
+ */
+void
+qmi_utils_read_string_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ guint8 length_prefix_size,
+ guint16 max_size,
+ gchar **out)
+{
+ guint16 string_length;
+ guint16 valid_string_length;
+ guint8 string_length_8;
+ guint16 string_length_16;
+
+ g_assert (out != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (length_prefix_size == 0 ||
+ length_prefix_size == 8 ||
+ length_prefix_size == 16);
+
+ switch (length_prefix_size) {
+ case 0:
+ /* If no length prefix given, read the whole buffer into a string */
+ string_length = *buffer_size;
+ break;
+ case 8:
+ qmi_utils_read_guint8_from_buffer (buffer,
+ buffer_size,
+ &string_length_8);
+ string_length = string_length_8;
+ break;
+ case 16:
+ qmi_utils_read_guint16_from_buffer (buffer,
+ buffer_size,
+ QMI_ENDIAN_LITTLE,
+ &string_length_16);
+ string_length = string_length_16;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (max_size > 0 && string_length > max_size)
+ valid_string_length = max_size;
+ else
+ valid_string_length = string_length;
+
+ /* Read 'valid_string_length' bytes */
+ *out = g_malloc (valid_string_length + 1);
+ memcpy (*out, *buffer, valid_string_length);
+ (*out)[valid_string_length] = '\0';
+
+ /* And walk 'string_length' bytes */
+ *buffer = &((*buffer)[string_length]);
+ *buffer_size = (*buffer_size) - string_length;
+}
+
+/**
+ * qmi_utils_read_fixed_size_string_from_buffer:
+ * @buffer: a buffer with raw binary data.
+ * @buffer_size: size of @buffer.
+ * @fixed_size: number of bytes to read.
+ * @out: return location for the read string. The returned value should be freed with g_free().
+ *
+ * Reads a @fixed_size-sized string from the buffer.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the
+ * @fixed_size bytes read.
+ */
+void
+qmi_utils_read_fixed_size_string_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ guint16 fixed_size,
+ gchar *out)
+{
+ g_assert (out != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (fixed_size > 0);
+
+ memcpy (out, *buffer, fixed_size);
+
+ *buffer = &((*buffer)[fixed_size]);
+ *buffer_size = (*buffer_size) - fixed_size;
+}
+
+/**
+ * qmi_utils_write_string_to_buffer:
+ * @buffer: a buffer.
+ * @buffer_size: size of @buffer.
+ * @length_prefix_size: size of the length prefix integer in bits.
+ * @in: string to write.
+ *
+ * Writes a string to the buffer.
+ *
+ * If @length_prefix_size is greater than 0, a length prefix integer will be
+ * included in the write operation.
+ *
+ * The user needs to make sure that the buffer has enough space for both the
+ * whole string and the length prefix.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the write.
+ */
+void
+qmi_utils_write_string_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ guint8 length_prefix_size,
+ const gchar *in)
+{
+ guint16 len;
+ guint8 len_8;
+ guint16 len_16;
+
+ g_assert (in != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (length_prefix_size == 0 ||
+ length_prefix_size == 8 ||
+ length_prefix_size == 16);
+
+ len = (guint16) strlen (in);
+
+ switch (length_prefix_size) {
+ case 0:
+ break;
+ case 8:
+ g_warn_if_fail (len <= G_MAXUINT8);
+ len_8 = (guint8)len;
+ qmi_utils_write_guint8_to_buffer (buffer,
+ buffer_size,
+ &len_8);
+ break;
+ case 16:
+ g_warn_if_fail (len <= G_MAXUINT16);
+ len_16 = (guint16)len;
+ qmi_utils_write_guint16_to_buffer (buffer,
+ buffer_size,
+ QMI_ENDIAN_LITTLE,
+ &len_16);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ memcpy (*buffer, in, len);
+ *buffer = &((*buffer)[len]);
+ *buffer_size = (*buffer_size) - len;
+}
+
+/**
+ * qmi_utils_write_fixed_size_string_to_buffer:
+ * @buffer: a buffer.
+ * @buffer_size: size of @buffer.
+ * @fixed_size: number of bytes to write.
+ * @in: string to write.
+ *
+ * Writes a @fixed_size-sized string to the buffer, without any length prefix.
+ *
+ * The user needs to make sure that the buffer is at least @fixed_size bytes
+ * long.
+ *
+ * Also note that both @buffer and @buffer_size get updated after the
+ * @fixed_size bytes write.
+ */
+void
+qmi_utils_write_fixed_size_string_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ guint16 fixed_size,
+ const gchar *in)
+{
+ g_assert (in != NULL);
+ g_assert (buffer != NULL);
+ g_assert (buffer_size != NULL);
+ g_assert (fixed_size > 0);
+
+ memcpy (*buffer, in, fixed_size);
+ *buffer = &((*buffer)[fixed_size]);
+ *buffer_size = (*buffer_size) - fixed_size;
+}
+
+/*****************************************************************************/
+
+static volatile gint __traces_enabled = FALSE;
+
+/**
+ * qmi_utils_get_traces_enabled:
+ *
+ * Checks whether QMI message traces are currently enabled.
+ *
+ * Returns: %TRUE if traces are enabled, %FALSE otherwise.
+ */
+gboolean
+qmi_utils_get_traces_enabled (void)
+{
+ return (gboolean) g_atomic_int_get (&__traces_enabled);
+}
+
+/**
+ * qmi_utils_set_traces_enabled:
+ * @enabled: %TRUE to enable traces, %FALSE to disable them.
+ *
+ * Sets whether QMI message traces are enabled or disabled.
+ */
+void
+qmi_utils_set_traces_enabled (gboolean enabled)
+{
+ g_atomic_int_set (&__traces_enabled, enabled);
+}
diff --git a/src/libqmi-glib/qmi-utils.h b/src/libqmi-glib/qmi-utils.h
new file mode 100644
index 0000000..3f39182
--- /dev/null
+++ b/src/libqmi-glib/qmi-utils.h
@@ -0,0 +1,166 @@
+/* -*- 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>
+ * Copyright (C) 2012 Dan Williams <dcbw@redhat.com>
+ */
+
+#ifndef _LIBQMI_GLIB_QMI_UTILS_H_
+#define _LIBQMI_GLIB_QMI_UTILS_H_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/**
+ * QmiEndian:
+ * @QMI_ENDIAN_LITTLE: Little endian.
+ * @QMI_ENDIAN_BIG: Big endian.
+ *
+ * Type of endianness
+ */
+typedef enum {
+ QMI_ENDIAN_LITTLE = 0,
+ QMI_ENDIAN_BIG = 1
+} QmiEndian;
+
+/* Reading/Writing integer variables */
+
+void qmi_utils_read_guint8_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ guint8 *out);
+void qmi_utils_read_gint8_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ gint8 *out);
+
+void qmi_utils_read_guint16_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ guint16 *out);
+void qmi_utils_read_gint16_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ gint16 *out);
+
+void qmi_utils_read_guint32_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ guint32 *out);
+void qmi_utils_read_gint32_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ gint32 *out);
+
+void qmi_utils_read_guint64_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ guint64 *out);
+void qmi_utils_read_gint64_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ gint64 *out);
+
+void qmi_utils_read_sized_guint_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ guint n_bytes,
+ QmiEndian endian,
+ guint64 *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,
+ QmiEndian endian,
+ guint16 *in);
+void qmi_utils_write_gint16_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ gint16 *in);
+
+void qmi_utils_write_guint32_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ guint32 *in);
+void qmi_utils_write_gint32_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ gint32 *in);
+
+void qmi_utils_write_guint64_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ guint64 *in);
+void qmi_utils_write_gint64_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ QmiEndian endian,
+ gint64 *in);
+
+void qmi_utils_write_sized_guint_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ guint n_bytes,
+ QmiEndian endian,
+ guint64 *in);
+
+/* Reading/Writing string variables */
+
+void qmi_utils_read_string_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ guint8 length_prefix_size,
+ guint16 max_size,
+ gchar **out);
+void qmi_utils_write_string_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ guint8 length_prefix_size,
+ const gchar *in);
+
+void qmi_utils_read_fixed_size_string_from_buffer (const guint8 **buffer,
+ guint16 *buffer_size,
+ guint16 fixed_size,
+ gchar *out);
+void qmi_utils_write_fixed_size_string_to_buffer (guint8 **buffer,
+ guint16 *buffer_size,
+ guint16 fixed_size,
+ const gchar *in);
+
+/* Enabling/Disabling traces */
+gboolean qmi_utils_get_traces_enabled (void);
+void qmi_utils_set_traces_enabled (gboolean enabled);
+
+/* Other private methods */
+
+#if defined (LIBQMI_GLIB_COMPILATION)
+G_GNUC_INTERNAL
+gchar *__qmi_utils_str_hex (gconstpointer mem,
+ gsize size,
+ gchar delimiter);
+#endif
+
+G_END_DECLS
+
+#endif /* _LIBQMI_GLIB_QMI_UTILS_H_ */
diff --git a/src/libqmi-glib/qmi-version.h.in b/src/libqmi-glib/qmi-version.h.in
new file mode 100644
index 0000000..22dda01
--- /dev/null
+++ b/src/libqmi-glib/qmi-version.h.in
@@ -0,0 +1,69 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * 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) 2013 Lanedo GmbH
+ */
+
+#ifndef _QMI_VERSION_H_
+#define _QMI_VERSION_H_
+
+/**
+ * SECTION:qmi-version
+ * @short_description: Version information in the API.
+ *
+ * This section defines types that are used to identify the libqmi-glib version.
+ **/
+
+/**
+ * QMI_MAJOR_VERSION:
+ *
+ * Evaluates to the major version number of libqmi-glib which this source
+ * is compiled against.
+ */
+#define QMI_MAJOR_VERSION (@QMI_MAJOR_VERSION@)
+
+/**
+ * QMI_MINOR_VERSION:
+ *
+ * Evaluates to the minor version number of libqmi-glib which this source
+ * is compiled against.
+ */
+#define QMI_MINOR_VERSION (@QMI_MINOR_VERSION@)
+
+/**
+ * QMI_MICRO_VERSION:
+ *
+ * Evaluates to the micro version number of libqmi-glib which this source
+ * compiled against.
+ */
+#define QMI_MICRO_VERSION (@QMI_MICRO_VERSION@)
+
+/**
+ * QMI_CHECK_VERSION:
+ * @major: major version (e.g. 1 for version 1.2.5)
+ * @minor: minor version (e.g. 2 for version 1.2.5)
+ * @micro: micro version (e.g. 5 for version 1.2.5)
+ *
+ * Returns: %TRUE if the version of the libqmi-glib header files
+ * is the same as or newer than the passed-in version.
+ */
+#define QMI_CHECK_VERSION(major,minor,micro) \
+ (QMI_MAJOR_VERSION > (major) || \
+ (QMI_MAJOR_VERSION == (major) && QMI_MINOR_VERSION > (minor)) || \
+ (QMI_MAJOR_VERSION == (major) && QMI_MINOR_VERSION == (minor) && QMI_MICRO_VERSION >= (micro)))
+
+#endif /* _QMI_VERSION_H_ */
diff --git a/src/libqmi-glib/test/Makefile.am b/src/libqmi-glib/test/Makefile.am
new file mode 100644
index 0000000..4d48e4d
--- /dev/null
+++ b/src/libqmi-glib/test/Makefile.am
@@ -0,0 +1,36 @@
+include $(top_srcdir)/gtester.make
+
+noinst_PROGRAMS = \
+ test-utils \
+ test-message
+
+TEST_PROGS += $(noinst_PROGRAMS)
+
+
+test_utils_SOURCES = \
+ test-utils.c
+test_utils_CPPFLAGS = \
+ $(LIBQMI_GLIB_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src/libqmi-glib \
+ -I$(top_srcdir)/src/libqmi-glib/generated \
+ -I$(top_builddir)/src/libqmi-glib \
+ -I$(top_builddir)/src/libqmi-glib/generated \
+ -DLIBQMI_GLIB_COMPILATION
+test_utils_LDADD = \
+ $(top_builddir)/src/libqmi-glib/libqmi-glib.la \
+ $(LIBQMI_GLIB_LIBS)
+
+test_message_SOURCES = \
+ test-message.c
+test_message_CPPFLAGS = \
+ $(LIBQMI_GLIB_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src/libqmi-glib \
+ -I$(top_srcdir)/src/libqmi-glib/generated \
+ -I$(top_builddir)/src/libqmi-glib \
+ -I$(top_builddir)/src/libqmi-glib/generated \
+ -DLIBQMI_GLIB_COMPILATION
+test_message_LDADD = \
+ $(top_builddir)/src/libqmi-glib/libqmi-glib.la \
+ $(LIBQMI_GLIB_LIBS)
diff --git a/src/libqmi-glib/test/test-message.c b/src/libqmi-glib/test/test-message.c
new file mode 100644
index 0000000..86fed8a
--- /dev/null
+++ b/src/libqmi-glib/test/test-message.c
@@ -0,0 +1,150 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details:
+ *
+ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
+ */
+
+#include <config.h>
+#include <glib-object.h>
+#include <string.h>
+#include "qmi-message.h"
+
+static void
+test_message_parse_common (const guint8 *buffer,
+ guint buffer_len,
+ guint n_expected_messages)
+{
+ GError *error = NULL;
+ GByteArray *array;
+ guint n_messages = 0;
+
+ array = g_byte_array_sized_new (buffer_len);
+ g_byte_array_append (array, buffer, buffer_len);
+
+ do {
+ QmiMessage *message;
+ gchar *printable;
+
+ message = qmi_message_new_from_raw (array, &error);
+ if (!message) {
+ if (error) {
+ if (n_messages < n_expected_messages)
+ g_printerr ("error creating message from raw data: '%s'\n", error->message);
+ g_error_free (error);
+ }
+ break;
+ }
+
+ printable = qmi_message_get_printable (message, "");
+ g_print ("\n%s\n", printable);
+ g_free (printable);
+
+ n_messages++;
+ qmi_message_unref (message);
+ } while (array->len > 0);
+
+ g_assert_cmpuint (n_messages, ==, n_expected_messages);
+}
+
+static void
+test_message_parse_short (void)
+{
+ const guint8 buffer[] = {
+ 0x01, 0x26, 0x00, 0x80, 0x03, 0x01, 0x02, 0x01, 0x00, 0x20, 0x00, 0x1a,
+ 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x9b,
+ 0x05, 0x11, 0x04, 0x00, 0x01, 0x00, 0x66, 0x05
+ };
+
+ test_message_parse_common (buffer, sizeof (buffer), 0);
+}
+
+static void
+test_message_parse_complete (void)
+{
+ const guint8 buffer[] = {
+ 0x01, 0x26, 0x00, 0x80, 0x03, 0x01, 0x02, 0x01, 0x00, 0x20, 0x00, 0x1a,
+ 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x9b,
+ 0x05, 0x11, 0x04, 0x00, 0x01, 0x00, 0x65, 0x05, 0x12, 0x04, 0x00, 0x01,
+ 0x00, 0x11, 0x05
+ };
+
+ test_message_parse_common (buffer, sizeof (buffer), 1);
+}
+
+static void
+test_message_parse_complete_and_short (void)
+{
+ const guint8 buffer[] = {
+ 0x01, 0x26, 0x00, 0x80, 0x03, 0x01, 0x02, 0x01, 0x00, 0x20, 0x00, 0x1a,
+ 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x9b,
+ 0x05, 0x11, 0x04, 0x00, 0x01, 0x00, 0x65, 0x05, 0x12, 0x04, 0x00, 0x01,
+ 0x00, 0x11, 0x05, 0x01, 0x26, 0x00, 0x80, 0x03, 0x01, 0x02, 0x01, 0x00,
+ 0x20, 0x00, 0x1a, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x02, 0x00, 0x9b, 0x05, 0x11, 0x04, 0x00, 0x01, 0x00, 0x66, 0x05
+ };
+
+ test_message_parse_common (buffer, sizeof (buffer), 1);
+}
+
+static void
+test_message_parse_complete_and_complete (void)
+{
+ const guint8 buffer[] = {
+ 0x01, 0x26, 0x00, 0x80, 0x03, 0x01, 0x02, 0x01, 0x00, 0x20, 0x00, 0x1a,
+ 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x9b,
+ 0x05, 0x11, 0x04, 0x00, 0x01, 0x00, 0x65, 0x05, 0x12, 0x04, 0x00, 0x01,
+ 0x00, 0x11, 0x05, 0x01, 0x26, 0x00, 0x80, 0x03, 0x01, 0x02, 0x01, 0x00,
+ 0x20, 0x00, 0x1a, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x02, 0x00, 0x9b, 0x05, 0x11, 0x04, 0x00, 0x01, 0x00, 0x65, 0x05, 0x12,
+ 0x04, 0x00, 0x01, 0x00, 0x11, 0x05
+ };
+
+ test_message_parse_common (buffer, sizeof (buffer), 2);
+}
+
+#if GLIB_CHECK_VERSION (2,34,0)
+static void
+test_message_parse_wrong_tlv (void)
+{
+ const guint8 buffer[] = {
+ 0x01, 0x4F, 0x00, 0x80, 0x03, 0x03, 0x02, 0x01, 0x00, 0x24, 0x00, 0x43,
+ 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x04, 0x00, 0x02,
+ 0x03, 0x00, 0x00, 0x1D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x02,
+ 0x00, 0x00, 0x00, 0x15, 0x03, 0x00, 0x01, 0x05, 0x01, 0x12, 0x0E, 0x00,
+ 0x36, 0x01, 0x04, 0x01, 0x09, 0x20, 0x54, 0x2D, 0x4D, 0x6F, 0x62, 0x69,
+ 0x6C, 0x65, 0x11, 0x02, 0x00, 0x01, 0x05, 0x10, 0x01, 0x00, 0x01, 0x01,
+ 0x06, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x05
+ };
+
+ g_test_expect_message ("Qmi",
+ G_LOG_LEVEL_WARNING,
+ "Cannot read the '*' TLV: expected '*' bytes, but only got '*' bytes");
+ test_message_parse_common (buffer, sizeof (buffer), 1);
+ g_test_assert_expected_messages ();
+}
+#endif
+
+int main (int argc, char **argv)
+{
+ g_type_init ();
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/libqmi-glib/message/parse/short", test_message_parse_short);
+ g_test_add_func ("/libqmi-glib/message/parse/complete", test_message_parse_complete);
+ g_test_add_func ("/libqmi-glib/message/parse/complete-and-short", test_message_parse_complete_and_short);
+ g_test_add_func ("/libqmi-glib/message/parse/complete-and-complete", test_message_parse_complete_and_complete);
+#if GLIB_CHECK_VERSION (2,34,0)
+ g_test_add_func ("/libqmi-glib/message/parse/wrong-tlv", test_message_parse_wrong_tlv);
+#endif
+
+ return g_test_run ();
+}
diff --git a/src/libqmi-glib/test/test-utils.c b/src/libqmi-glib/test/test-utils.c
new file mode 100644
index 0000000..04f552f
--- /dev/null
+++ b/src/libqmi-glib/test/test-utils.c
@@ -0,0 +1,1265 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details:
+ *
+ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
+ */
+
+#include <glib-object.h>
+#include <string.h>
+#include "qmi-utils.h"
+
+static void
+test_utils_uint8 (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+
+ while (in_buffer_size) {
+ guint8 tmp;
+
+ qmi_utils_read_guint8_from_buffer (&in_buffer_walker, &in_buffer_size, &tmp);
+ qmi_utils_write_guint8_to_buffer (&out_buffer_walker, &out_buffer_size, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_int8 (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+
+ while (in_buffer_size) {
+ gint8 tmp;
+
+ qmi_utils_read_gint8_from_buffer (&in_buffer_walker, &in_buffer_size, &tmp);
+ qmi_utils_write_gint8_to_buffer (&out_buffer_walker, &out_buffer_size, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_uint16_le (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static const guint16 values[4] = {
+ 0x500F, 0xE2EB, 0x00B6, 0x0000
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ guint16 tmp;
+
+ qmi_utils_read_guint16_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpuint (tmp, ==, values[i++]);
+ qmi_utils_write_guint16_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_uint16_be (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0x50, 0x0F, 0xE2, 0xEB, 0x00, 0xB6, 0x00, 0x00
+ };
+ static const guint16 values[4] = {
+ 0x500F, 0xE2EB, 0x00B6, 0x0000
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ guint16 tmp;
+
+ qmi_utils_read_guint16_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpuint (tmp, ==, values[i++]);
+ qmi_utils_write_guint16_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_int16_le (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static const gint16 values[4] = {
+ 0x500F, 0xE2EB, 0x00B6, 0x0000
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ gint16 tmp;
+
+ qmi_utils_read_gint16_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpint (tmp, ==, values[i++]);
+ qmi_utils_write_gint16_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_int16_be (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0x50, 0x0F, 0xE2, 0xEB, 0x00, 0xB6, 0x00, 0x00
+ };
+ static const gint16 values[4] = {
+ 0x500F, 0xE2EB, 0x00B6, 0x0000
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ gint16 tmp;
+
+ qmi_utils_read_gint16_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpint (tmp, ==, values[i++]);
+ qmi_utils_write_gint16_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_uint16_unaligned_le (void)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static guint16 values[4] = {
+ 0x500F, 0xE2EB, 0x00B6, 0x0000
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ guint16 tmp;
+
+ qmi_utils_read_guint16_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpuint (tmp, ==, values[i++]);
+ qmi_utils_write_guint16_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (&in_buffer[1], out_buffer, sizeof (in_buffer) - 1) == 0);
+}
+
+static void
+test_utils_uint16_unaligned_be (void)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0x50, 0x0F, 0xE2, 0xEB, 0x00, 0xB6, 0x00, 0x00
+ };
+ static guint16 values[4] = {
+ 0x500F, 0xE2EB, 0x00B6, 0x0000
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ guint16 tmp;
+
+ qmi_utils_read_guint16_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpuint (tmp, ==, values[i++]);
+ qmi_utils_write_guint16_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (&in_buffer[1], out_buffer, sizeof (in_buffer) - 1) == 0);
+}
+
+static void
+test_utils_int16_unaligned_le (void)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static gint16 values[4] = {
+ 0x500F, 0xE2EB, 0x00B6, 0x0000
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ gint16 tmp;
+
+ qmi_utils_read_gint16_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpint (tmp, ==, values[i++]);
+ qmi_utils_write_gint16_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (&in_buffer[1], out_buffer, sizeof (in_buffer) - 1) == 0);
+}
+
+static void
+test_utils_int16_unaligned_be (void)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0x50, 0x0F, 0xE2, 0xEB, 0x00, 0xB6, 0x00, 0x00
+ };
+ static gint16 values[4] = {
+ 0x500F, 0xE2EB, 0x00B6, 0x0000
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ gint16 tmp;
+
+ qmi_utils_read_gint16_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpint (tmp, ==, values[i++]);
+ qmi_utils_write_gint16_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (&in_buffer[1], out_buffer, sizeof (in_buffer) - 1) == 0);
+}
+
+static void
+test_utils_uint32_le (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static const guint32 values[2] = {
+ 0xE2EB500F, 0x000000B6
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ guint32 tmp;
+
+ qmi_utils_read_guint32_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpuint (tmp, ==, values[i++]);
+ qmi_utils_write_guint32_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_uint32_be (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0xE2, 0xEB, 0x50, 0x0F, 0x00, 0x00, 0x00, 0xB6
+ };
+ static const guint32 values[2] = {
+ 0xE2EB500F, 0x000000B6
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ guint32 tmp;
+
+ qmi_utils_read_guint32_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpuint (tmp, ==, values[i++]);
+ qmi_utils_write_guint32_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_int32_le (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static const gint32 values[2] = {
+ 0xE2EB500F, 0x000000B6
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ gint32 tmp;
+
+ qmi_utils_read_gint32_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpint (tmp, ==, values[i++]);
+ qmi_utils_write_gint32_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_int32_be (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0xE2, 0xEB, 0x50, 0x0F, 0x00, 0x00, 0x00, 0xB6
+ };
+ static const gint32 values[2] = {
+ 0xE2EB500F, 0x000000B6
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ gint32 tmp;
+
+ qmi_utils_read_gint32_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpint (tmp, ==, values[i++]);
+ qmi_utils_write_gint32_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_uint32_unaligned_le (void)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static guint32 values[2] = {
+ 0xE2EB500F, 0x000000B6
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ guint32 tmp;
+
+ qmi_utils_read_guint32_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpuint (tmp, ==, values[i++]);
+ qmi_utils_write_guint32_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (&in_buffer[1], out_buffer, sizeof (in_buffer) - 1) == 0);
+}
+
+static void
+test_utils_uint32_unaligned_be (void)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0xE2, 0xEB, 0x50, 0x0F, 0x00, 0x00, 0x00, 0xB6
+ };
+ static guint32 values[2] = {
+ 0xE2EB500F, 0x000000B6
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ guint32 tmp;
+
+ qmi_utils_read_guint32_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpuint (tmp, ==, values[i++]);
+ qmi_utils_write_guint32_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (&in_buffer[1], out_buffer, sizeof (in_buffer) - 1) == 0);
+}
+
+static void
+test_utils_int32_unaligned_le (void)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static gint32 values[2] = {
+ 0xE2EB500F, 0x000000B6
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ gint32 tmp;
+
+ qmi_utils_read_gint32_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpint (tmp, ==, values[i++]);
+ qmi_utils_write_gint32_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (&in_buffer[1], out_buffer, sizeof (in_buffer) - 1) == 0);
+}
+
+static void
+test_utils_int32_unaligned_be (void)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0xE2, 0xEB, 0x50, 0x0F, 0x00, 0x00, 0x00, 0xB6
+ };
+ static gint32 values[2] = {
+ 0xE2EB500F, 0x000000B6
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ gint32 tmp;
+
+ qmi_utils_read_gint32_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpint (tmp, ==, values[i++]);
+ qmi_utils_write_gint32_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (&in_buffer[1], out_buffer, sizeof (in_buffer) - 1) == 0);
+}
+
+static void
+test_utils_uint64_le (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static const guint64 values[1] = {
+ 0x000000B6E2EB500FULL
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ guint64 tmp;
+
+ qmi_utils_read_guint64_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpuint (tmp, ==, values[i++]);
+ qmi_utils_write_guint64_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_uint64_be (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0x00, 0x00, 0x00, 0xB6, 0xE2, 0xEB, 0x50, 0x0F
+ };
+ static const guint64 values[1] = {
+ 0x000000B6E2EB500FULL
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ guint64 tmp;
+
+ qmi_utils_read_guint64_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpuint (tmp, ==, values[i++]);
+ qmi_utils_write_guint64_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_int64_le (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static const gint64 values[1] = {
+ 0x000000B6E2EB500FLL
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ gint64 tmp;
+
+ qmi_utils_read_gint64_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpint (tmp, ==, values[i++]);
+ qmi_utils_write_gint64_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_int64_be (void)
+{
+ static const guint8 in_buffer[8] = {
+ 0x00, 0x00, 0x00, 0xB6, 0xE2, 0xEB, 0x50, 0x0F
+ };
+ static const gint64 values[1] = {
+ 0x000000B6E2EB500FLL
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ gint64 tmp;
+
+ qmi_utils_read_gint64_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpint (tmp, ==, values[i++]);
+ qmi_utils_write_gint64_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (in_buffer, out_buffer, sizeof (in_buffer)) == 0);
+}
+
+static void
+test_utils_uint64_unaligned_le (void)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static guint64 values[1] = {
+ 0x000000B6E2EB500FULL
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ guint64 tmp;
+
+ qmi_utils_read_guint64_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpuint (tmp, ==, values[i++]);
+ qmi_utils_write_guint64_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (&in_buffer[1], out_buffer, sizeof (in_buffer) - 1) == 0);
+}
+
+static void
+test_utils_uint64_unaligned_be (void)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0x00, 0x00, 0x00, 0xB6, 0xE2, 0xEB, 0x50, 0x0F
+ };
+ static guint64 values[1] = {
+ 0x000000B6E2EB500FULL
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ guint64 tmp;
+
+ qmi_utils_read_guint64_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpuint (tmp, ==, values[i++]);
+ qmi_utils_write_guint64_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (&in_buffer[1], out_buffer, sizeof (in_buffer) - 1) == 0);
+}
+
+static void
+test_utils_int64_unaligned_le (void)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static gint64 values[1] = {
+ 0x000000B6E2EB500FLL
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ gint64 tmp;
+
+ qmi_utils_read_gint64_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpint (tmp, ==, values[i++]);
+ qmi_utils_write_gint64_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_LITTLE, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (&in_buffer[1], out_buffer, sizeof (in_buffer) - 1) == 0);
+}
+
+static void
+test_utils_int64_unaligned_be (void)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0x00, 0x00, 0x00, 0xB6, 0xE2, 0xEB, 0x50, 0x0F
+ };
+ static gint64 values[1] = {
+ 0x000000B6E2EB500FLL
+ };
+ guint8 out_buffer[8] = { 0 };
+
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ while (in_buffer_size) {
+ gint64 tmp;
+
+ qmi_utils_read_gint64_from_buffer (&in_buffer_walker, &in_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpint (tmp, ==, values[i++]);
+ qmi_utils_write_gint64_to_buffer (&out_buffer_walker, &out_buffer_size, QMI_ENDIAN_BIG, &tmp);
+ }
+
+ g_assert_cmpuint (out_buffer_size, ==, 0);
+ g_assert (memcmp (&in_buffer[1], out_buffer, sizeof (in_buffer) - 1) == 0);
+}
+
+static void
+common_test_utils_uint_sized_le (guint n_bytes)
+{
+ static const guint8 in_buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ guint64 value = 0x000000B6E2EB500FULL;
+ guint8 expected_out_buffer[8] = { 0 };
+ guint8 out_buffer[8] = { 0 };
+
+ guint64 tmp;
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ /* Build expected intermediate value */
+ tmp = 0xFF;
+ for (i = 1; i < n_bytes; i++) {
+ tmp <<= 8;
+ tmp |= 0xFF;
+ }
+ value &= tmp;
+
+ /* Build expected output buffer */
+ memcpy (expected_out_buffer, in_buffer, n_bytes);
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ qmi_utils_read_sized_guint_from_buffer (&in_buffer_walker, &in_buffer_size, n_bytes, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpuint (tmp, ==, value);
+ qmi_utils_write_sized_guint_to_buffer (&out_buffer_walker, &out_buffer_size, n_bytes, QMI_ENDIAN_LITTLE, &tmp);
+
+ g_assert_cmpuint (out_buffer_size, ==, 8 - n_bytes);
+ g_assert (memcmp (expected_out_buffer, out_buffer, sizeof (expected_out_buffer)) == 0);
+}
+
+static void
+test_utils_uint_sized_1_le (void)
+{
+ common_test_utils_uint_sized_le (1);
+}
+
+static void
+test_utils_uint_sized_2_le (void)
+{
+ common_test_utils_uint_sized_le (2);
+}
+
+static void
+test_utils_uint_sized_4_le (void)
+{
+ common_test_utils_uint_sized_le (4);
+}
+
+static void
+test_utils_uint_sized_8_le (void)
+{
+ common_test_utils_uint_sized_le (8);
+}
+
+static void
+common_test_utils_uint_sized_be (guint n_bytes)
+{
+ static const guint8 in_buffer[8] = {
+ 0x00, 0x00, 0x00, 0xB6, 0xE2, 0xEB, 0x50, 0x0F
+ };
+ guint64 value = 0x000000B6E2EB500FULL;
+ guint8 expected_out_buffer[8] = { 0 };
+ guint8 out_buffer[8] = { 0 };
+ guint8 in_buffer_aux[8] = { 0 };
+
+ guint64 tmp;
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ /* Build expected intermediate value */
+ tmp = 0xFF;
+ for (i = 1; i < n_bytes; i++) {
+ tmp <<= 8;
+ tmp |= 0xFF;
+ }
+ value &= tmp;
+
+ /* In BIG ENDIAN buffers, let's read only the bytes we want, starting from
+ * the byte we want, not from the beginning of the input buffer. But we do
+ * want to be aligned while reading, so we copy the bytes to read to the
+ * beginning of an aux buffer */
+ g_assert (n_bytes <= sizeof (in_buffer));
+ memcpy (&in_buffer_aux[0], &in_buffer[sizeof (in_buffer) - n_bytes], n_bytes);
+
+ /* Build expected output buffer */
+ memcpy (&expected_out_buffer[0], &in_buffer_aux[0], n_bytes);
+
+ in_buffer_size = sizeof (in_buffer);
+ in_buffer_walker = &in_buffer_aux[0];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+
+ qmi_utils_read_sized_guint_from_buffer (&in_buffer_walker, &in_buffer_size, n_bytes, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpuint (tmp, ==, value);
+ qmi_utils_write_sized_guint_to_buffer (&out_buffer_walker, &out_buffer_size, n_bytes, QMI_ENDIAN_BIG, &tmp);
+
+ g_assert_cmpuint (out_buffer_size, ==, 8 - n_bytes);
+ if (memcmp (expected_out_buffer, out_buffer, sizeof (expected_out_buffer)) != 0) {
+ g_print ("OUTPUT: %x, %x, %x, %x, %x, %x, %x, %x\n",
+ out_buffer[0], out_buffer[1], out_buffer[2], out_buffer[3],
+ out_buffer[4], out_buffer[5], out_buffer[6], out_buffer[7]);
+ g_print ("EXPECTED: %x, %x, %x, %x, %x, %x, %x, %x\n",
+ expected_out_buffer[0], expected_out_buffer[1], expected_out_buffer[2], expected_out_buffer[3],
+ expected_out_buffer[4], expected_out_buffer[5], expected_out_buffer[6], expected_out_buffer[7]);
+ }
+ g_assert (memcmp (expected_out_buffer, out_buffer, sizeof (expected_out_buffer)) == 0);
+}
+
+static void
+test_utils_uint_sized_1_be (void)
+{
+ common_test_utils_uint_sized_be (1);
+}
+
+static void
+test_utils_uint_sized_2_be (void)
+{
+ common_test_utils_uint_sized_be (2);
+}
+
+static void
+test_utils_uint_sized_4_be (void)
+{
+ common_test_utils_uint_sized_be (4);
+}
+
+static void
+test_utils_uint_sized_8_be (void)
+{
+ common_test_utils_uint_sized_be (8);
+}
+
+static void
+common_test_utils_uint_sized_unaligned_le (guint n_bytes)
+{
+ static const guint8 in_buffer[9] = {
+ 0x00, 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ guint64 value = 0x000000B6E2EB500FULL;
+ guint8 expected_out_buffer[8] = { 0 };
+ guint8 out_buffer[8] = { 0 };
+
+ guint64 tmp;
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ /* Build expected intermediate value */
+ tmp = 0xFF;
+ for (i = 1; i < n_bytes; i++) {
+ tmp <<= 8;
+ tmp |= 0xFF;
+ }
+ value &= tmp;
+
+ /* Build expected output buffer */
+ memcpy (expected_out_buffer, &in_buffer[1], n_bytes);
+
+ in_buffer_size = sizeof (in_buffer) - 1;
+ in_buffer_walker = &in_buffer[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+
+ qmi_utils_read_sized_guint_from_buffer (&in_buffer_walker, &in_buffer_size, n_bytes, QMI_ENDIAN_LITTLE, &tmp);
+ g_assert_cmpuint (tmp, ==, value);
+ qmi_utils_write_sized_guint_to_buffer (&out_buffer_walker, &out_buffer_size, n_bytes, QMI_ENDIAN_LITTLE, &tmp);
+
+ g_assert_cmpuint (out_buffer_size, ==, 8 - n_bytes);
+ g_assert (memcmp (expected_out_buffer, out_buffer, sizeof (expected_out_buffer)) == 0);
+}
+
+static void
+test_utils_uint_sized_1_unaligned_le (void)
+{
+ common_test_utils_uint_sized_unaligned_le (1);
+}
+
+static void
+test_utils_uint_sized_2_unaligned_le (void)
+{
+ common_test_utils_uint_sized_unaligned_le (2);
+}
+
+static void
+test_utils_uint_sized_4_unaligned_le (void)
+{
+ common_test_utils_uint_sized_unaligned_le (4);
+}
+
+static void
+test_utils_uint_sized_8_unaligned_le (void)
+{
+ common_test_utils_uint_sized_unaligned_le (8);
+}
+
+static void
+common_test_utils_uint_sized_unaligned_be (guint n_bytes)
+{
+ static const guint8 in_buffer[8] = {
+ 0x00, 0x00, 0x00, 0xB6, 0xE2, 0xEB, 0x50, 0x0F
+ };
+ guint64 value = 0x000000B6E2EB500FULL;
+ guint8 expected_out_buffer[8] = { 0 };
+ guint8 out_buffer[8] = { 0 };
+ guint8 in_buffer_aux[9] = { 0 };
+
+ guint64 tmp;
+ guint i;
+ guint16 in_buffer_size;
+ const guint8 *in_buffer_walker;
+ guint16 out_buffer_size;
+ guint8 *out_buffer_walker;
+
+ /* Build expected intermediate value */
+ tmp = 0xFF;
+ for (i = 1; i < n_bytes; i++) {
+ tmp <<= 8;
+ tmp |= 0xFF;
+ }
+ value &= tmp;
+
+ /* In BIG ENDIAN buffers, let's read only the bytes we want, starting from
+ * the byte we want, not from the beginning of the input buffer. But we do
+ * not want to be aligned while reading, so we copy the bytes to read to
+ * almost the beginning of an aux buffer */
+ g_assert (n_bytes <= (sizeof (in_buffer)));
+ memcpy (&in_buffer_aux[1], &in_buffer[sizeof (in_buffer) - n_bytes], n_bytes);
+
+ /* Build expected output buffer */
+ memcpy (expected_out_buffer, &in_buffer_aux[1], n_bytes);
+
+ in_buffer_size = sizeof (in_buffer_aux) - 1;
+ in_buffer_walker = &in_buffer_aux[1];
+ out_buffer_size = sizeof (out_buffer);
+ out_buffer_walker = &out_buffer[0];
+ i = 0;
+
+ qmi_utils_read_sized_guint_from_buffer (&in_buffer_walker, &in_buffer_size, n_bytes, QMI_ENDIAN_BIG, &tmp);
+ g_assert_cmpuint (tmp, ==, value);
+ qmi_utils_write_sized_guint_to_buffer (&out_buffer_walker, &out_buffer_size, n_bytes, QMI_ENDIAN_BIG, &tmp);
+
+ g_assert_cmpuint (out_buffer_size, ==, 8 - n_bytes);
+ if (memcmp (expected_out_buffer, out_buffer, sizeof (expected_out_buffer)) != 0) {
+ g_print ("OUTPUT: %x, %x, %x, %x, %x, %x, %x, %x\n",
+ out_buffer[0], out_buffer[1], out_buffer[2], out_buffer[3],
+ out_buffer[4], out_buffer[5], out_buffer[6], out_buffer[7]);
+ g_print ("EXPECTED: %x, %x, %x, %x, %x, %x, %x, %x\n",
+ expected_out_buffer[0], expected_out_buffer[1], expected_out_buffer[2], expected_out_buffer[3],
+ expected_out_buffer[4], expected_out_buffer[5], expected_out_buffer[6], expected_out_buffer[7]);
+ }
+ g_assert (memcmp (expected_out_buffer, out_buffer, sizeof (expected_out_buffer)) == 0);
+}
+
+static void
+test_utils_uint_sized_1_unaligned_be (void)
+{
+ common_test_utils_uint_sized_unaligned_be (1);
+}
+
+static void
+test_utils_uint_sized_2_unaligned_be (void)
+{
+ common_test_utils_uint_sized_unaligned_be (2);
+}
+
+static void
+test_utils_uint_sized_4_unaligned_be (void)
+{
+ common_test_utils_uint_sized_unaligned_be (4);
+}
+
+static void
+test_utils_uint_sized_8_unaligned_be (void)
+{
+ common_test_utils_uint_sized_unaligned_be (8);
+}
+
+int main (int argc, char **argv)
+{
+ g_type_init ();
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/libqmi-glib/utils/uint8", test_utils_uint8);
+ g_test_add_func ("/libqmi-glib/utils/int8", test_utils_int8);
+
+ g_test_add_func ("/libqmi-glib/utils/uint16-LE", test_utils_uint16_le);
+ g_test_add_func ("/libqmi-glib/utils/uint16-BE", test_utils_uint16_be);
+ g_test_add_func ("/libqmi-glib/utils/int16-LE", test_utils_int16_le);
+ g_test_add_func ("/libqmi-glib/utils/int16-BE", test_utils_int16_be);
+ g_test_add_func ("/libqmi-glib/utils/uint16-unaligned-LE", test_utils_uint16_unaligned_le);
+ g_test_add_func ("/libqmi-glib/utils/uint16-unaligned-Be", test_utils_uint16_unaligned_be);
+ g_test_add_func ("/libqmi-glib/utils/int16-unaligned-LE", test_utils_int16_unaligned_le);
+ g_test_add_func ("/libqmi-glib/utils/int16-unaligned-BE", test_utils_int16_unaligned_be);
+
+ g_test_add_func ("/libqmi-glib/utils/uint32-LE", test_utils_uint32_le);
+ g_test_add_func ("/libqmi-glib/utils/uint32-BE", test_utils_uint32_be);
+ g_test_add_func ("/libqmi-glib/utils/int32-LE", test_utils_int32_le);
+ g_test_add_func ("/libqmi-glib/utils/int32-BE", test_utils_int32_be);
+ g_test_add_func ("/libqmi-glib/utils/uint32/unaligned-LE", test_utils_uint32_unaligned_le);
+ g_test_add_func ("/libqmi-glib/utils/uint32/unaligned-BE", test_utils_uint32_unaligned_be);
+ g_test_add_func ("/libqmi-glib/utils/int32/unaligned-LE", test_utils_int32_unaligned_le);
+ g_test_add_func ("/libqmi-glib/utils/int32/unaligned-BE", test_utils_int32_unaligned_be);
+
+ g_test_add_func ("/libqmi-glib/utils/uint64-LE", test_utils_uint64_le);
+ g_test_add_func ("/libqmi-glib/utils/uint64-BE", test_utils_uint64_be);
+ g_test_add_func ("/libqmi-glib/utils/int64-LE", test_utils_int64_le);
+ g_test_add_func ("/libqmi-glib/utils/int64-BE", test_utils_int64_be);
+ g_test_add_func ("/libqmi-glib/utils/uint64/unaligned-LE", test_utils_uint64_unaligned_le);
+ g_test_add_func ("/libqmi-glib/utils/uint64/unaligned-BE", test_utils_uint64_unaligned_be);
+ g_test_add_func ("/libqmi-glib/utils/int64/unaligned-LE", test_utils_int64_unaligned_le);
+ g_test_add_func ("/libqmi-glib/utils/int64/unaligned-BE", test_utils_int64_unaligned_be);
+
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-1-LE", test_utils_uint_sized_1_le);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-2-LE", test_utils_uint_sized_2_le);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-4-LE", test_utils_uint_sized_4_le);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-8-LE", test_utils_uint_sized_8_le);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-1-BE", test_utils_uint_sized_1_be);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-2-BE", test_utils_uint_sized_2_be);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-4-BE", test_utils_uint_sized_4_be);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-8-BE", test_utils_uint_sized_8_be);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-1-unaligned-LE", test_utils_uint_sized_1_unaligned_le);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-2-unaligned-LE", test_utils_uint_sized_2_unaligned_le);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-4-unaligned-LE", test_utils_uint_sized_4_unaligned_le);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-8-unaligned-LE", test_utils_uint_sized_8_unaligned_le);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-1-unaligned-BE", test_utils_uint_sized_1_unaligned_be);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-2-unaligned-BE", test_utils_uint_sized_2_unaligned_be);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-4-unaligned-BE", test_utils_uint_sized_4_unaligned_be);
+ g_test_add_func ("/libqmi-glib/utils/uint-sized-8-unaligned-BE", test_utils_uint_sized_8_unaligned_be);
+
+ return g_test_run ();
+}
diff --git a/src/qmicli/Makefile.am b/src/qmicli/Makefile.am
new file mode 100644
index 0000000..7b7e61f
--- /dev/null
+++ b/src/qmicli/Makefile.am
@@ -0,0 +1,27 @@
+
+SUBDIRS = . test
+
+bin_PROGRAMS = qmicli
+
+qmicli_CPPFLAGS = \
+ $(QMICLI_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src/libqmi-glib \
+ -I$(top_srcdir)/src/libqmi-glib/generated \
+ -I$(top_builddir)/src/libqmi-glib \
+ -I$(top_builddir)/src/libqmi-glib/generated
+
+qmicli_SOURCES = \
+ qmicli.c \
+ qmicli.h \
+ qmicli-helpers.c \
+ qmicli-helpers.h \
+ qmicli-dms.c \
+ qmicli-wds.c \
+ qmicli-nas.c \
+ qmicli-pbm.c \
+ qmicli-uim.c
+
+qmicli_LDADD = \
+ $(QMICLI_LIBS) \
+ $(top_builddir)/src/libqmi-glib/libqmi-glib.la
diff --git a/src/qmicli/qmicli-dms.c b/src/qmicli/qmicli-dms.c
new file mode 100644
index 0000000..0ad64a6
--- /dev/null
+++ b/src/qmicli/qmicli-dms.c
@@ -0,0 +1,3579 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * qmicli -- Command line interface to control QMI devices
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <libqmi-glib.h>
+
+#include "qmicli.h"
+#include "qmicli-helpers.h"
+
+/* Context */
+typedef struct {
+ QmiDevice *device;
+ QmiClientDms *client;
+ GCancellable *cancellable;
+} Context;
+static Context *ctx;
+
+/* Options */
+static gboolean get_ids_flag;
+static gboolean get_capabilities_flag;
+static gboolean get_manufacturer_flag;
+static gboolean get_model_flag;
+static gboolean get_revision_flag;
+static gboolean get_msisdn_flag;
+static gboolean get_power_state_flag;
+static gchar *uim_set_pin_protection_str;
+static gchar *uim_verify_pin_str;
+static gchar *uim_unblock_pin_str;
+static gchar *uim_change_pin_str;
+static gboolean uim_get_pin_status_flag;
+static gboolean uim_get_iccid_flag;
+static gboolean uim_get_imsi_flag;
+static gboolean uim_get_state_flag;
+static gchar *uim_get_ck_status_str;
+static gchar *uim_set_ck_protection_str;
+static gchar *uim_unblock_ck_str;
+static gboolean get_hardware_revision_flag;
+static gboolean get_operating_mode_flag;
+static gchar *set_operating_mode_str;
+static gboolean get_time_flag;
+static gboolean get_prl_version_flag;
+static gboolean get_activation_state_flag;
+static gchar *activate_automatic_str;
+static gchar *activate_manual_str;
+static gboolean get_user_lock_state_flag;
+static gchar *set_user_lock_state_str;
+static gchar *set_user_lock_code_str;
+static gboolean read_user_data_flag;
+static gchar *write_user_data_str;
+static gboolean read_eri_file_flag;
+static gchar *restore_factory_defaults_str;
+static gchar *validate_service_programming_code_str;
+static gboolean get_band_capabilities_flag;
+static gboolean get_factory_sku_flag;
+static gboolean list_stored_images_flag;
+static gchar *select_stored_image_str;
+static gchar *delete_stored_image_str;
+static gboolean reset_flag;
+static gboolean noop_flag;
+
+static GOptionEntry entries[] = {
+ { "dms-get-ids", 0, 0, G_OPTION_ARG_NONE, &get_ids_flag,
+ "Get IDs",
+ NULL
+ },
+ { "dms-get-capabilities", 0, 0, G_OPTION_ARG_NONE, &get_capabilities_flag,
+ "Get capabilities",
+ NULL
+ },
+ { "dms-get-manufacturer", 0, 0, G_OPTION_ARG_NONE, &get_manufacturer_flag,
+ "Get manufacturer",
+ NULL
+ },
+ { "dms-get-model", 0, 0, G_OPTION_ARG_NONE, &get_model_flag,
+ "Get model",
+ NULL
+ },
+ { "dms-get-revision", 0, 0, G_OPTION_ARG_NONE, &get_revision_flag,
+ "Get revision",
+ NULL
+ },
+ { "dms-get-msisdn", 0, 0, G_OPTION_ARG_NONE, &get_msisdn_flag,
+ "Get MSISDN",
+ NULL
+ },
+ { "dms-get-power-state", 0, 0, G_OPTION_ARG_NONE, &get_power_state_flag,
+ "Get power state",
+ NULL
+ },
+ { "dms-uim-set-pin-protection", 0, 0, G_OPTION_ARG_STRING, &uim_set_pin_protection_str,
+ "Set PIN protection in the UIM",
+ "[(PIN|PIN2),(disable|enable),(current PIN)]",
+ },
+ { "dms-uim-verify-pin", 0, 0, G_OPTION_ARG_STRING, &uim_verify_pin_str,
+ "Verify PIN",
+ "[(PIN|PIN2),(current PIN)]",
+ },
+ { "dms-uim-unblock-pin", 0, 0, G_OPTION_ARG_STRING, &uim_unblock_pin_str,
+ "Unblock PIN",
+ "[(PIN|PIN2),(PUK),(new PIN)]",
+ },
+ { "dms-uim-change-pin", 0, 0, G_OPTION_ARG_STRING, &uim_change_pin_str,
+ "Change PIN",
+ "[(PIN|PIN2),(old PIN),(new PIN)]",
+ },
+ { "dms-uim-get-pin-status", 0, 0, G_OPTION_ARG_NONE, &uim_get_pin_status_flag,
+ "Get PIN status",
+ NULL
+ },
+ { "dms-uim-get-iccid", 0, 0, G_OPTION_ARG_NONE, &uim_get_iccid_flag,
+ "Get ICCID",
+ NULL
+ },
+ { "dms-uim-get-imsi", 0, 0, G_OPTION_ARG_NONE, &uim_get_imsi_flag,
+ "Get IMSI",
+ NULL
+ },
+ { "dms-uim-get-state", 0, 0, G_OPTION_ARG_NONE, &uim_get_state_flag,
+ "Get UIM State",
+ NULL
+ },
+ { "dms-uim-get-ck-status", 0, 0, G_OPTION_ARG_STRING, &uim_get_ck_status_str,
+ "Get CK Status",
+ "[(pn|pu|pp|pc|pf)]"
+ },
+ { "dms-uim-set-ck-protection", 0, 0, G_OPTION_ARG_STRING, &uim_set_ck_protection_str,
+ "Disable CK protection",
+ "[(pn|pu|pp|pc|pf),(disable),(key)]"
+ },
+ { "dms-uim-unblock-ck", 0, 0, G_OPTION_ARG_STRING, &uim_unblock_ck_str,
+ "Unblock CK",
+ "[(pn|pu|pp|pc|pf),(key)]"
+ },
+ { "dms-get-hardware-revision", 0, 0, G_OPTION_ARG_NONE, &get_hardware_revision_flag,
+ "Get the HW revision",
+ NULL
+ },
+ { "dms-get-operating-mode", 0, 0, G_OPTION_ARG_NONE, &get_operating_mode_flag,
+ "Get the device operating mode",
+ NULL
+ },
+ { "dms-set-operating-mode", 0, 0, G_OPTION_ARG_STRING, &set_operating_mode_str,
+ "Set the device operating mode",
+ "[(Operating mode)]"
+ },
+ { "dms-get-time", 0, 0, G_OPTION_ARG_NONE, &get_time_flag,
+ "Get the device time",
+ NULL,
+ },
+ { "dms-get-prl-version", 0, 0, G_OPTION_ARG_NONE, &get_prl_version_flag,
+ "Get the PRL version",
+ NULL,
+ },
+ { "dms-get-activation-state", 0, 0, G_OPTION_ARG_NONE, &get_activation_state_flag,
+ "Get the state of the service activation",
+ NULL,
+ },
+ { "dms-activate-automatic", 0, 0, G_OPTION_ARG_STRING, &activate_automatic_str,
+ "Request automatic service activation",
+ "[Activation Code]"
+ },
+ { "dms-activate-manual", 0, 0, G_OPTION_ARG_STRING, &activate_manual_str,
+ "Request manual service activation",
+ "[SPC,SID,MDN,MIN]"
+ },
+ { "dms-get-user-lock-state", 0, 0, G_OPTION_ARG_NONE, &get_user_lock_state_flag,
+ "Get the state of the user lock",
+ NULL,
+ },
+ { "dms-set-user-lock-state", 0, 0, G_OPTION_ARG_STRING, &set_user_lock_state_str,
+ "Set the state of the user lock",
+ "[(disable|enable),(current lock code)]",
+ },
+ { "dms-set-user-lock-code", 0, 0, G_OPTION_ARG_STRING, &set_user_lock_code_str,
+ "Change the user lock code",
+ "[(old lock code),(new lock code)]",
+ },
+ { "dms-read-user-data", 0, 0, G_OPTION_ARG_NONE, &read_user_data_flag,
+ "Read user data",
+ NULL,
+ },
+ { "dms-write-user-data", 0, 0, G_OPTION_ARG_STRING, &write_user_data_str,
+ "Write user data",
+ "[(User data)]",
+ },
+ { "dms-read-eri-file", 0, 0, G_OPTION_ARG_NONE, &read_eri_file_flag,
+ "Read ERI file",
+ NULL,
+ },
+ { "dms-restore-factory-defaults", 0, 0, G_OPTION_ARG_STRING, &restore_factory_defaults_str,
+ "Restore factory defaults",
+ "[(Service Programming Code)]",
+ },
+ { "dms-validate-service-programming-code", 0, 0, G_OPTION_ARG_STRING, &validate_service_programming_code_str,
+ "Validate the Service Programming Code",
+ "[(Service Programming Code)]",
+ },
+ { "dms-get-band-capabilities", 0, 0, G_OPTION_ARG_NONE, &get_band_capabilities_flag,
+ "Get band capabilities",
+ NULL
+ },
+ { "dms-get-factory-sku", 0, 0, G_OPTION_ARG_NONE, &get_factory_sku_flag,
+ "Get factory stock keeping unit",
+ NULL
+ },
+ { "dms-list-stored-images", 0, 0, G_OPTION_ARG_NONE, &list_stored_images_flag,
+ "List stored images",
+ NULL
+ },
+ { "dms-select-stored-image", 0, 0, G_OPTION_ARG_STRING, &select_stored_image_str,
+ "Select stored image",
+ "[modem#,pri#] where # is the index"
+ },
+ { "dms-delete-stored-image", 0, 0, G_OPTION_ARG_STRING, &delete_stored_image_str,
+ "Delete stored image",
+ "[modem#|pri#] where # is the index"
+ },
+ { "dms-reset", 0, 0, G_OPTION_ARG_NONE, &reset_flag,
+ "Reset the service state",
+ NULL
+ },
+ { "dms-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
+ "Just allocate or release a DMS client. Use with `--client-no-release-cid' and/or `--client-cid'",
+ NULL
+ },
+ { NULL }
+};
+
+GOptionGroup *
+qmicli_dms_get_option_group (void)
+{
+ GOptionGroup *group;
+
+ group = g_option_group_new ("dms",
+ "DMS options",
+ "Show Device Management Service options",
+ NULL,
+ NULL);
+ g_option_group_add_entries (group, entries);
+
+ return group;
+}
+
+gboolean
+qmicli_dms_options_enabled (void)
+{
+ static guint n_actions = 0;
+ static gboolean checked = FALSE;
+
+ if (checked)
+ return !!n_actions;
+
+ n_actions = (get_ids_flag +
+ get_capabilities_flag +
+ get_manufacturer_flag +
+ get_model_flag +
+ get_revision_flag +
+ get_msisdn_flag +
+ get_power_state_flag +
+ !!uim_set_pin_protection_str +
+ !!uim_verify_pin_str +
+ !!uim_unblock_pin_str +
+ !!uim_change_pin_str +
+ uim_get_pin_status_flag +
+ uim_get_iccid_flag +
+ uim_get_imsi_flag +
+ uim_get_state_flag +
+ !!uim_get_ck_status_str +
+ !!uim_set_ck_protection_str +
+ !!uim_unblock_ck_str +
+ get_hardware_revision_flag +
+ get_operating_mode_flag +
+ !!set_operating_mode_str +
+ get_time_flag +
+ get_prl_version_flag +
+ get_activation_state_flag +
+ !!activate_automatic_str +
+ !!activate_manual_str +
+ get_user_lock_state_flag +
+ !!set_user_lock_state_str +
+ !!set_user_lock_code_str +
+ read_user_data_flag +
+ !!write_user_data_str +
+ read_eri_file_flag +
+ !!restore_factory_defaults_str +
+ !!validate_service_programming_code_str +
+ get_band_capabilities_flag +
+ get_factory_sku_flag +
+ list_stored_images_flag +
+ !!select_stored_image_str +
+ !!delete_stored_image_str +
+ reset_flag +
+ noop_flag);
+
+ if (n_actions > 1) {
+ g_printerr ("error: too many DMS actions requested\n");
+ exit (EXIT_FAILURE);
+ }
+
+ checked = TRUE;
+ return !!n_actions;
+}
+
+static void
+context_free (Context *context)
+{
+ if (!context)
+ return;
+
+ if (context->cancellable)
+ g_object_unref (context->cancellable);
+ if (context->device)
+ g_object_unref (context->device);
+ if (context->client)
+ g_object_unref (context->client);
+ g_slice_free (Context, context);
+}
+
+static void
+shutdown (gboolean operation_status)
+{
+ /* Cleanup context and finish async operation */
+ context_free (ctx);
+ qmicli_async_operation_done (operation_status);
+}
+
+static void
+get_ids_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ const gchar *esn = NULL;
+ const gchar *imei = NULL;
+ const gchar *meid = NULL;
+ QmiMessageDmsGetIdsOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_ids_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_ids_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get IDs: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_ids_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ qmi_message_dms_get_ids_output_get_esn (output, &esn, NULL);
+ qmi_message_dms_get_ids_output_get_imei (output, &imei, NULL);
+ qmi_message_dms_get_ids_output_get_meid (output, &meid, NULL);
+
+ g_print ("[%s] Device IDs retrieved:\n"
+ "\t ESN: '%s'\n"
+ "\tIMEI: '%s'\n"
+ "\tMEID: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ VALIDATE_UNKNOWN (esn),
+ VALIDATE_UNKNOWN (imei),
+ VALIDATE_UNKNOWN (meid));
+
+ qmi_message_dms_get_ids_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_capabilities_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsGetCapabilitiesOutput *output;
+ guint32 max_tx_channel_rate;
+ guint32 max_rx_channel_rate;
+ QmiDmsDataServiceCapability data_service_capability;
+ QmiDmsSimCapability sim_capability;
+ GArray *radio_interface_list;
+ GError *error = NULL;
+ GString *networks;
+ guint i;
+
+ output = qmi_client_dms_get_capabilities_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_capabilities_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get capabilities: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_capabilities_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_get_capabilities_output_get_info (output,
+ &max_tx_channel_rate,
+ &max_rx_channel_rate,
+ &data_service_capability,
+ &sim_capability,
+ &radio_interface_list,
+ NULL);
+
+ networks = g_string_new ("");
+ for (i = 0; i < radio_interface_list->len; i++) {
+ g_string_append (networks,
+ qmi_dms_radio_interface_get_string (
+ g_array_index (radio_interface_list,
+ QmiDmsRadioInterface,
+ i)));
+ if (i != radio_interface_list->len - 1)
+ g_string_append (networks, ", ");
+ }
+
+ g_print ("[%s] Device capabilities retrieved:\n"
+ "\tMax TX channel rate: '%u'\n"
+ "\tMax RX channel rate: '%u'\n"
+ "\t Data Service: '%s'\n"
+ "\t SIM: '%s'\n"
+ "\t Networks: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ max_tx_channel_rate,
+ max_rx_channel_rate,
+ qmi_dms_data_service_capability_get_string (data_service_capability),
+ qmi_dms_sim_capability_get_string (sim_capability),
+ networks->str);
+
+ g_string_free (networks, TRUE);
+ qmi_message_dms_get_capabilities_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_manufacturer_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ const gchar *str = NULL;
+ QmiMessageDmsGetManufacturerOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_manufacturer_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_manufacturer_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get manufacturer: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_manufacturer_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ qmi_message_dms_get_manufacturer_output_get_manufacturer (output, &str, NULL);
+
+ g_print ("[%s] Device manufacturer retrieved:\n"
+ "\tManufacturer: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ VALIDATE_UNKNOWN (str));
+
+ qmi_message_dms_get_manufacturer_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_model_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ const gchar *str = NULL;
+ QmiMessageDmsGetModelOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_model_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_model_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get model: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_model_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ qmi_message_dms_get_model_output_get_model (output, &str, NULL);
+
+ g_print ("[%s] Device model retrieved:\n"
+ "\tModel: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ VALIDATE_UNKNOWN (str));
+
+ qmi_message_dms_get_model_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_revision_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ const gchar *str = NULL;
+ QmiMessageDmsGetRevisionOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_revision_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_revision_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get revision: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_revision_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ qmi_message_dms_get_revision_output_get_revision (output, &str, NULL);
+
+ g_print ("[%s] Device revision retrieved:\n"
+ "\tRevision: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ VALIDATE_UNKNOWN (str));
+
+ qmi_message_dms_get_revision_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_msisdn_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ const gchar *str = NULL;
+ QmiMessageDmsGetMsisdnOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_msisdn_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_msisdn_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get MSISDN: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_msisdn_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ qmi_message_dms_get_msisdn_output_get_msisdn (output, &str, NULL);
+
+ g_print ("[%s] Device MSISDN retrieved:\n"
+ "\tMSISDN: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ VALIDATE_UNKNOWN (str));
+
+ qmi_message_dms_get_msisdn_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_power_state_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ gchar *power_state_str;
+ guint8 power_state_flags;
+ guint8 battery_level;
+ QmiMessageDmsGetPowerStateOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_power_state_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_power_state_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get power state: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_power_state_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_get_power_state_output_get_info (output,
+ &power_state_flags,
+ &battery_level,
+ NULL);
+ power_state_str = qmi_dms_power_state_build_string_from_mask ((QmiDmsPowerState)power_state_flags);
+
+ g_print ("[%s] Device power state retrieved:\n"
+ "\tPower state: '%s'\n"
+ "\tBattery level: '%u %%'\n",
+ qmi_device_get_path_display (ctx->device),
+ power_state_str,
+ (guint)battery_level);
+
+ g_free (power_state_str);
+ qmi_message_dms_get_power_state_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsUimSetPinProtectionInput *
+uim_set_pin_protection_input_create (const gchar *str)
+{
+ QmiMessageDmsUimSetPinProtectionInput *input = NULL;
+ gchar **split;
+ QmiDmsUimPinId pin_id;
+ gboolean enable_disable;
+ gchar *current_pin;
+
+ /* Prepare inputs.
+ * Format of the string is:
+ * "[(PIN|PIN2),(disable|enable),(current PIN)]"
+ */
+ split = g_strsplit (str, ",", -1);
+ if (qmicli_read_pin_id_from_string (split[0], &pin_id) &&
+ qmicli_read_enable_disable_from_string (split[1], &enable_disable) &&
+ qmicli_read_non_empty_string (split[2], "current PIN", &current_pin)) {
+ GError *error = NULL;
+
+ input = qmi_message_dms_uim_set_pin_protection_input_new ();
+ if (!qmi_message_dms_uim_set_pin_protection_input_set_info (
+ input,
+ pin_id,
+ enable_disable,
+ current_pin,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_uim_set_pin_protection_input_unref (input);
+ input = NULL;
+ }
+ }
+ g_strfreev (split);
+
+ return input;
+}
+
+static void
+uim_set_pin_protection_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsUimSetPinProtectionOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_uim_set_pin_protection_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_uim_set_pin_protection_output_get_result (output, &error)) {
+ guint8 verify_retries_left;
+ guint8 unblock_retries_left;
+
+ g_printerr ("error: couldn't set PIN protection: %s\n", error->message);
+ g_error_free (error);
+
+ if (qmi_message_dms_uim_set_pin_protection_output_get_pin_retries_status (
+ output,
+ &verify_retries_left,
+ &unblock_retries_left,
+ NULL)) {
+ g_printerr ("[%s] Retries left:\n"
+ "\tVerify: %u\n"
+ "\tUnblock: %u\n",
+ qmi_device_get_path_display (ctx->device),
+ verify_retries_left,
+ unblock_retries_left);
+ }
+
+ qmi_message_dms_uim_set_pin_protection_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] PIN protection updated\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_uim_set_pin_protection_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsUimVerifyPinInput *
+uim_verify_pin_input_create (const gchar *str)
+{
+ QmiMessageDmsUimVerifyPinInput *input = NULL;
+ gchar **split;
+ QmiDmsUimPinId pin_id;
+ gchar *current_pin;
+
+ /* Prepare inputs.
+ * Format of the string is:
+ * "[(PIN|PIN2),(current PIN)]"
+ */
+ split = g_strsplit (str, ",", -1);
+ if (qmicli_read_pin_id_from_string (split[0], &pin_id) &&
+ qmicli_read_non_empty_string (split[1], "current PIN", &current_pin)) {
+ GError *error = NULL;
+
+ input = qmi_message_dms_uim_verify_pin_input_new ();
+ if (!qmi_message_dms_uim_verify_pin_input_set_info (
+ input,
+ pin_id,
+ current_pin,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_uim_verify_pin_input_unref (input);
+ input = NULL;
+ }
+ }
+ g_strfreev (split);
+
+ return input;
+}
+
+static void
+uim_verify_pin_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsUimVerifyPinOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_uim_verify_pin_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_uim_verify_pin_output_get_result (output, &error)) {
+ guint8 verify_retries_left;
+ guint8 unblock_retries_left;
+
+ g_printerr ("error: couldn't verify PIN: %s\n", error->message);
+ g_error_free (error);
+
+ if (qmi_message_dms_uim_verify_pin_output_get_pin_retries_status (
+ output,
+ &verify_retries_left,
+ &unblock_retries_left,
+ NULL)) {
+ g_printerr ("[%s] Retries left:\n"
+ "\tVerify: %u\n"
+ "\tUnblock: %u\n",
+ qmi_device_get_path_display (ctx->device),
+ verify_retries_left,
+ unblock_retries_left);
+ }
+
+ qmi_message_dms_uim_verify_pin_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] PIN verified successfully\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_uim_verify_pin_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsUimUnblockPinInput *
+uim_unblock_pin_input_create (const gchar *str)
+{
+ QmiMessageDmsUimUnblockPinInput *input = NULL;
+ gchar **split;
+ QmiDmsUimPinId pin_id;
+ gchar *puk;
+ gchar *new_pin;
+
+ /* Prepare inputs.
+ * Format of the string is:
+ * "[(PIN|PIN2),(PUK),(new PIN)]"
+ */
+ split = g_strsplit (str, ",", -1);
+ if (qmicli_read_pin_id_from_string (split[0], &pin_id) &&
+ qmicli_read_non_empty_string (split[1], "PUK", &puk) &&
+ qmicli_read_non_empty_string (split[2], "new PIN", &new_pin)) {
+ GError *error = NULL;
+
+ input = qmi_message_dms_uim_unblock_pin_input_new ();
+ if (!qmi_message_dms_uim_unblock_pin_input_set_info (
+ input,
+ pin_id,
+ puk,
+ new_pin,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_uim_unblock_pin_input_unref (input);
+ input = NULL;
+ }
+ }
+ g_strfreev (split);
+
+ return input;
+}
+
+static void
+uim_unblock_pin_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsUimUnblockPinOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_uim_unblock_pin_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_uim_unblock_pin_output_get_result (output, &error)) {
+ guint8 verify_retries_left;
+ guint8 unblock_retries_left;
+
+ g_printerr ("error: couldn't unblock PIN: %s\n", error->message);
+ g_error_free (error);
+
+ if (qmi_message_dms_uim_unblock_pin_output_get_pin_retries_status (
+ output,
+ &verify_retries_left,
+ &unblock_retries_left,
+ NULL)) {
+ g_printerr ("[%s] Retries left:\n"
+ "\tVerify: %u\n"
+ "\tUnblock: %u\n",
+ qmi_device_get_path_display (ctx->device),
+ verify_retries_left,
+ unblock_retries_left);
+ }
+
+ qmi_message_dms_uim_unblock_pin_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] PIN unblocked successfully\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_uim_unblock_pin_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsUimChangePinInput *
+uim_change_pin_input_create (const gchar *str)
+{
+ QmiMessageDmsUimChangePinInput *input = NULL;
+ gchar **split;
+ QmiDmsUimPinId pin_id;
+ gchar *old_pin;
+ gchar *new_pin;
+
+ /* Prepare inputs.
+ * Format of the string is:
+ * "[(PIN|PIN2),(old PIN),(new PIN)]"
+ */
+ split = g_strsplit (str, ",", -1);
+ if (qmicli_read_pin_id_from_string (split[0], &pin_id) &&
+ qmicli_read_non_empty_string (split[1], "old PIN", &old_pin) &&
+ qmicli_read_non_empty_string (split[2], "new PIN", &new_pin)) {
+ GError *error = NULL;
+
+ input = qmi_message_dms_uim_change_pin_input_new ();
+ if (!qmi_message_dms_uim_change_pin_input_set_info (
+ input,
+ pin_id,
+ old_pin,
+ new_pin,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_uim_change_pin_input_unref (input);
+ input = NULL;
+ }
+ }
+ g_strfreev (split);
+
+ return input;
+}
+
+static void
+uim_change_pin_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsUimChangePinOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_uim_change_pin_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_uim_change_pin_output_get_result (output, &error)) {
+ guint8 verify_retries_left;
+ guint8 unblock_retries_left;
+
+ g_printerr ("error: couldn't change PIN: %s\n", error->message);
+ g_error_free (error);
+
+ if (qmi_message_dms_uim_change_pin_output_get_pin_retries_status (
+ output,
+ &verify_retries_left,
+ &unblock_retries_left,
+ NULL)) {
+ g_printerr ("[%s] Retries left:\n"
+ "\tVerify: %u\n"
+ "\tUnblock: %u\n",
+ qmi_device_get_path_display (ctx->device),
+ verify_retries_left,
+ unblock_retries_left);
+ }
+
+ qmi_message_dms_uim_change_pin_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] PIN changed successfully\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_uim_change_pin_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+uim_get_pin_status_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ guint8 verify_retries_left;
+ guint8 unblock_retries_left;
+ QmiDmsUimPinStatus current_status;
+ QmiMessageDmsUimGetPinStatusOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_uim_get_pin_status_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_uim_get_pin_status_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get PIN status: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_uim_get_pin_status_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] PIN status retrieved successfully\n",
+ qmi_device_get_path_display (ctx->device));
+
+ if (qmi_message_dms_uim_get_pin_status_output_get_pin1_status (
+ output,
+ &current_status,
+ &verify_retries_left,
+ &unblock_retries_left,
+ NULL)) {
+ g_print ("[%s] PIN1:\n"
+ "\tStatus: %s\n"
+ "\tVerify: %u\n"
+ "\tUnblock: %u\n",
+ qmi_device_get_path_display (ctx->device),
+ qmi_dms_uim_pin_status_get_string (current_status),
+ verify_retries_left,
+ unblock_retries_left);
+ }
+
+ if (qmi_message_dms_uim_get_pin_status_output_get_pin2_status (
+ output,
+ &current_status,
+ &verify_retries_left,
+ &unblock_retries_left,
+ NULL)) {
+ g_print ("[%s] PIN2:\n"
+ "\tStatus: %s\n"
+ "\tVerify: %u\n"
+ "\tUnblock: %u\n",
+ qmi_device_get_path_display (ctx->device),
+ qmi_dms_uim_pin_status_get_string (current_status),
+ verify_retries_left,
+ unblock_retries_left);
+ }
+
+ qmi_message_dms_uim_get_pin_status_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+uim_get_iccid_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ const gchar *str = NULL;
+ QmiMessageDmsUimGetIccidOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_uim_get_iccid_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_uim_get_iccid_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get ICCID: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_uim_get_iccid_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ qmi_message_dms_uim_get_iccid_output_get_iccid (output, &str, NULL);
+
+ g_print ("[%s] UIM ICCID retrieved:\n"
+ "\tICCID: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ VALIDATE_UNKNOWN (str));
+
+ qmi_message_dms_uim_get_iccid_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+uim_get_imsi_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ const gchar *str = NULL;
+ QmiMessageDmsUimGetImsiOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_uim_get_imsi_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_uim_get_imsi_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get IMSI: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_uim_get_imsi_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ qmi_message_dms_uim_get_imsi_output_get_imsi (output, &str, NULL);
+
+ g_print ("[%s] UIM IMSI retrieved:\n"
+ "\tIMSI: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ VALIDATE_UNKNOWN (str));
+
+ qmi_message_dms_uim_get_imsi_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+uim_get_state_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiDmsUimState state;
+ QmiMessageDmsUimGetStateOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_uim_get_state_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_uim_get_state_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get UIM state: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_uim_get_state_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_uim_get_state_output_get_state (output, &state, NULL);
+
+ g_print ("[%s] UIM state retrieved:\n"
+ "\tState: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ qmi_dms_uim_state_get_string (state));
+
+ qmi_message_dms_uim_get_state_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsUimGetCkStatusInput *
+uim_get_ck_status_input_create (const gchar *str)
+{
+ QmiMessageDmsUimGetCkStatusInput *input = NULL;
+ QmiDmsUimFacility facility;
+
+ if (qmicli_read_facility_from_string (str, &facility)) {
+ GError *error = NULL;
+
+ input = qmi_message_dms_uim_get_ck_status_input_new ();
+ if (!qmi_message_dms_uim_get_ck_status_input_set_facility (
+ input,
+ facility,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_uim_get_ck_status_input_unref (input);
+ input = NULL;
+ }
+ }
+
+ return input;
+}
+
+static void
+uim_get_ck_status_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsUimGetCkStatusOutput *output;
+ GError *error = NULL;
+ QmiDmsUimFacilityState state;
+ guint8 verify_retries_left;
+ guint8 unblock_retries_left;
+ gboolean blocking;
+
+ output = qmi_client_dms_uim_get_ck_status_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_uim_get_ck_status_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get UIM CK status: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_uim_get_ck_status_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_uim_get_ck_status_output_get_ck_status (
+ output,
+ &state,
+ &verify_retries_left,
+ &unblock_retries_left,
+ NULL);
+
+ g_print ("[%s] UIM facility state retrieved:\n"
+ "\tState: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ qmi_dms_uim_facility_state_get_string (state));
+ g_print ("[%s] Retries left:\n"
+ "\tVerify: %u\n"
+ "\tUnblock: %u\n",
+ qmi_device_get_path_display (ctx->device),
+ verify_retries_left,
+ unblock_retries_left);
+
+ if (qmi_message_dms_uim_get_ck_status_output_get_operation_blocking_facility (
+ output,
+ &blocking,
+ NULL) &&
+ blocking) {
+ g_print ("[%s] Facility is blocking operation\n",
+ qmi_device_get_path_display (ctx->device));
+ }
+
+ qmi_message_dms_uim_get_ck_status_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsUimSetCkProtectionInput *
+uim_set_ck_protection_input_create (const gchar *str)
+{
+ QmiMessageDmsUimSetCkProtectionInput *input = NULL;
+ gchar **split;
+ QmiDmsUimFacility facility;
+ gboolean enable_disable;
+ gchar *key;
+
+ /* Prepare inputs.
+ * Format of the string is:
+ * "[(facility),disable,(key)]"
+ */
+ split = g_strsplit (str, ",", -1);
+ if (qmicli_read_facility_from_string (split[0], &facility) &&
+ qmicli_read_enable_disable_from_string (split[1], &enable_disable) &&
+ qmicli_read_non_empty_string (split[2], "control key", &key)) {
+
+ /* We should only allow 'disable' here */
+ if (enable_disable) {
+ g_printerr ("error: only 'disable' action is allowed\n");
+ } else {
+ GError *error = NULL;
+
+ input = qmi_message_dms_uim_set_ck_protection_input_new ();
+ if (!qmi_message_dms_uim_set_ck_protection_input_set_facility (
+ input,
+ facility,
+ (QmiDmsUimFacilityState)enable_disable, /* 0 == DISABLE */
+ key,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_uim_set_ck_protection_input_unref (input);
+ input = NULL;
+ }
+ }
+ }
+ g_strfreev (split);
+
+ return input;
+}
+
+static void
+uim_set_ck_protection_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsUimSetCkProtectionOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_uim_set_ck_protection_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_uim_set_ck_protection_output_get_result (output, &error)) {
+ guint8 verify_retries_left;
+
+ g_printerr ("error: couldn't set UIM CK protection: %s\n", error->message);
+ g_error_free (error);
+
+ if (qmi_message_dms_uim_set_ck_protection_output_get_verify_retries_left (
+ output,
+ &verify_retries_left,
+ NULL)) {
+ g_printerr ("[%s] Retries left:\n"
+ "\tVerify: %u\n",
+ qmi_device_get_path_display (ctx->device),
+ verify_retries_left);
+ }
+
+ qmi_message_dms_uim_set_ck_protection_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] UIM CK protection set\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_uim_set_ck_protection_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsUimUnblockCkInput *
+uim_unblock_ck_input_create (const gchar *str)
+{
+ QmiMessageDmsUimUnblockCkInput *input = NULL;
+ gchar **split;
+ QmiDmsUimFacility facility;
+ gchar *key;
+
+ /* Prepare inputs.
+ * Format of the string is:
+ * "[(facility),(key)]"
+ */
+ split = g_strsplit (str, ",", -1);
+ if (qmicli_read_facility_from_string (split[0], &facility) &&
+ qmicli_read_non_empty_string (split[1], "control key", &key)) {
+ GError *error = NULL;
+
+ input = qmi_message_dms_uim_unblock_ck_input_new ();
+ if (!qmi_message_dms_uim_unblock_ck_input_set_facility (
+ input,
+ facility,
+ key,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_uim_unblock_ck_input_unref (input);
+ input = NULL;
+ }
+ }
+ g_strfreev (split);
+
+ return input;
+}
+
+static void
+uim_unblock_ck_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsUimUnblockCkOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_uim_unblock_ck_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_uim_unblock_ck_output_get_result (output, &error)) {
+ guint8 unblock_retries_left;
+
+ g_printerr ("error: couldn't unblock CK: %s\n", error->message);
+ g_error_free (error);
+
+ if (qmi_message_dms_uim_unblock_ck_output_get_unblock_retries_left (
+ output,
+ &unblock_retries_left,
+ NULL)) {
+ g_printerr ("[%s] Retries left:\n"
+ "\tUnblock: %u\n",
+ qmi_device_get_path_display (ctx->device),
+ unblock_retries_left);
+ }
+
+ qmi_message_dms_uim_unblock_ck_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] UIM CK unblocked\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_uim_unblock_ck_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_hardware_revision_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ const gchar *str = NULL;
+ QmiMessageDmsGetHardwareRevisionOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_hardware_revision_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_hardware_revision_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get the HW revision: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_hardware_revision_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ qmi_message_dms_get_hardware_revision_output_get_revision (output, &str, NULL);
+
+ g_print ("[%s] Hardware revision retrieved:\n"
+ "\tRevision: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ VALIDATE_UNKNOWN (str));
+
+ qmi_message_dms_get_hardware_revision_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_operating_mode_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsGetOperatingModeOutput *output;
+ QmiDmsOperatingMode mode;
+ gboolean hw_restricted = FALSE;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_operating_mode_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_operating_mode_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get the HW revision: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_operating_mode_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ qmi_message_dms_get_operating_mode_output_get_mode (output, &mode, NULL);
+
+ g_print ("[%s] Operating mode retrieved:\n"
+ "\tMode: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ qmi_dms_operating_mode_get_string (mode));
+
+ if (mode == QMI_DMS_OPERATING_MODE_OFFLINE) {
+ QmiDmsOfflineReason reason;
+ gchar *reason_str = NULL;
+
+ if (qmi_message_dms_get_operating_mode_output_get_offline_reason (output, &reason, NULL)) {
+ reason_str = qmi_dms_offline_reason_build_string_from_mask (reason);
+ }
+
+ g_print ("\tReason: '%s'\n", VALIDATE_UNKNOWN (reason_str));
+ g_free (reason_str);
+ }
+
+ qmi_message_dms_get_operating_mode_output_get_hardware_restricted_mode (output, &hw_restricted, NULL);
+ g_print ("\tHW restricted: '%s'\n", hw_restricted ? "yes" : "no");
+
+ qmi_message_dms_get_operating_mode_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsSetOperatingModeInput *
+set_operating_mode_input_create (const gchar *str)
+{
+ QmiMessageDmsSetOperatingModeInput *input = NULL;
+ QmiDmsOperatingMode mode;
+
+ if (qmicli_read_operating_mode_from_string (str, &mode)) {
+ GError *error = NULL;
+
+ input = qmi_message_dms_set_operating_mode_input_new ();
+ if (!qmi_message_dms_set_operating_mode_input_set_mode (
+ input,
+ mode,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_set_operating_mode_input_unref (input);
+ input = NULL;
+ }
+ }
+
+ return input;
+}
+
+static void
+set_operating_mode_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsSetOperatingModeOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_set_operating_mode_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_set_operating_mode_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't set operating mode: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_set_operating_mode_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Operating mode set successfully\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_set_operating_mode_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_time_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsGetTimeOutput *output;
+ guint64 time_count;
+ QmiDmsTimeSource time_source;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_time_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_time_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get the device time: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_time_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_get_time_output_get_device_time (
+ output,
+ &time_count,
+ &time_source,
+ NULL);
+
+ g_print ("[%s] Time retrieved:\n"
+ "\tTime count: '%" G_GUINT64_FORMAT " (x 1.25ms)'\n"
+ "\tTime source: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ time_count,
+ qmi_dms_time_source_get_string (time_source));
+
+ if (qmi_message_dms_get_time_output_get_system_time (
+ output,
+ &time_count,
+ NULL)){
+ g_print ("\tSystem time: '%" G_GUINT64_FORMAT " (ms)'\n",
+ time_count);
+ }
+
+ if (qmi_message_dms_get_time_output_get_user_time (
+ output,
+ &time_count,
+ NULL)){
+ g_print ("\tUser time: '%" G_GUINT64_FORMAT " (ms)'\n",
+ time_count);
+ }
+
+ qmi_message_dms_get_time_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_prl_version_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsGetPrlVersionOutput *output;
+ guint16 prl_version;
+ gboolean prl_only;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_prl_version_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_prl_version_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get the PRL version: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_prl_version_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_get_prl_version_output_get_version (
+ output,
+ &prl_version,
+ NULL);
+
+ g_print ("[%s] PRL version retrieved:\n"
+ "\tPRL version: '%" G_GUINT16_FORMAT "'\n",
+ qmi_device_get_path_display (ctx->device),
+ prl_version);
+
+ if (qmi_message_dms_get_prl_version_output_get_prl_only_preference (
+ output,
+ &prl_only,
+ NULL)){
+ g_print ("\tPRL only preference: '%s'\n",
+ prl_only ? "yes" : "no");
+ }
+
+ qmi_message_dms_get_prl_version_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_activation_state_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsGetActivationStateOutput *output;
+ QmiDmsActivationState activation_state;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_activation_state_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_activation_state_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get the state of the service activation: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_activation_state_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_get_activation_state_output_get_info (
+ output,
+ &activation_state,
+ NULL);
+
+ g_print ("[%s] Activation state retrieved:\n"
+ "\tState: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ qmi_dms_activation_state_get_string (activation_state));
+
+ qmi_message_dms_get_activation_state_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsActivateManualInput *
+activate_manual_input_create (const gchar *str)
+{
+ QmiMessageDmsActivateManualInput *input;
+ gchar **split;
+ GError *error = NULL;
+ gulong split_1_int;
+
+ split = g_strsplit (str, ",", -1);
+ if (g_strv_length (split) != 4) {
+ g_printerr ("error: incorrect number of arguments given\n");
+ g_strfreev (split);
+ return NULL;
+ }
+
+ split_1_int = strtoul (split[1], NULL, 10);
+ if (split_1_int > G_MAXUINT16) {
+ g_printerr ("error: invalid SID given '%s'\n",
+ split[1]);
+ return NULL;
+ }
+
+ input = qmi_message_dms_activate_manual_input_new ();
+ if (!qmi_message_dms_activate_manual_input_set_info (
+ input,
+ split[0],
+ (guint16)split_1_int,
+ split[2],
+ split[3],
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_activate_manual_input_unref (input);
+ input = NULL;
+ }
+
+ g_strfreev(split);
+ return input;
+}
+
+static void
+activate_manual_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsActivateManualOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_activate_manual_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_activate_manual_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't request manual service activation: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_activate_manual_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_activate_manual_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsActivateAutomaticInput *
+activate_automatic_input_create (const gchar *str)
+{
+ QmiMessageDmsActivateAutomaticInput *input;
+ GError *error = NULL;
+
+ input = qmi_message_dms_activate_automatic_input_new ();
+ if (!qmi_message_dms_activate_automatic_input_set_activation_code (
+ input,
+ str,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_activate_automatic_input_unref (input);
+ input = NULL;
+ }
+
+ return input;
+}
+
+static void
+activate_automatic_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsActivateAutomaticOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_activate_automatic_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_activate_automatic_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't request automatic service activation: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_activate_automatic_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_activate_automatic_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_user_lock_state_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsGetUserLockStateOutput *output;
+ gboolean enabled;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_user_lock_state_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_user_lock_state_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get the state of the user lock: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_user_lock_state_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_get_user_lock_state_output_get_enabled (
+ output,
+ &enabled,
+ NULL);
+
+ g_print ("[%s] User lock state retrieved:\n"
+ "\tEnabled: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ enabled ? "yes" : "no");
+
+ qmi_message_dms_get_user_lock_state_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsSetUserLockStateInput *
+set_user_lock_state_input_create (const gchar *str)
+{
+ QmiMessageDmsSetUserLockStateInput *input = NULL;
+ gchar **split;
+ gboolean enable_disable;
+ gchar *code;
+
+ /* Prepare inputs.
+ * Format of the string is:
+ * "[(disable|enable),(current lock code)]"
+ */
+ split = g_strsplit (str, ",", -1);
+
+ if (qmicli_read_enable_disable_from_string (split[0], &enable_disable) &&
+ qmicli_read_non_empty_string (split[1], "current lock code", &code)) {
+ GError *error = NULL;
+
+ input = qmi_message_dms_set_user_lock_state_input_new ();
+ if (!qmi_message_dms_set_user_lock_state_input_set_info (
+ input,
+ enable_disable,
+ code,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_set_user_lock_state_input_unref (input);
+ input = NULL;
+ }
+ }
+ g_strfreev (split);
+
+ return input;
+}
+
+static void
+set_user_lock_state_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsSetUserLockStateOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_set_user_lock_state_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_set_user_lock_state_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't set state of the user lock: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_set_user_lock_state_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] User lock state updated\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_set_user_lock_state_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsSetUserLockCodeInput *
+set_user_lock_code_input_create (const gchar *str)
+{
+ QmiMessageDmsSetUserLockCodeInput *input = NULL;
+ gchar **split;
+ gchar *old_code;
+ gchar *new_code;
+
+ /* Prepare inputs.
+ * Format of the string is:
+ * "[(old lock code),(new lock code)]"
+ */
+ split = g_strsplit (str, ",", -1);
+ if (qmicli_read_non_empty_string (split[0], "old lock code", &old_code) &&
+ qmicli_read_non_empty_string (split[1], "new lock code", &new_code)) {
+ GError *error = NULL;
+
+ input = qmi_message_dms_set_user_lock_code_input_new ();
+ if (!qmi_message_dms_set_user_lock_code_input_set_info (
+ input,
+ old_code,
+ new_code,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_set_user_lock_code_input_unref (input);
+ input = NULL;
+ }
+ }
+ g_strfreev (split);
+
+ return input;
+}
+
+static void
+set_user_lock_code_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsSetUserLockCodeOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_set_user_lock_code_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_set_user_lock_code_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't change user lock code: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_set_user_lock_code_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] User lock code changed\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_set_user_lock_code_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+read_user_data_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsReadUserDataOutput *output;
+ GArray *user_data = NULL;
+ gchar *user_data_printable;
+ GError *error = NULL;
+
+ output = qmi_client_dms_read_user_data_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_read_user_data_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't read user data: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_read_user_data_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_read_user_data_output_get_user_data (
+ output,
+ &user_data,
+ NULL);
+ user_data_printable = qmicli_get_raw_data_printable (user_data, 80, "\t\t");
+
+ g_print ("[%s] User data read:\n"
+ "\tSize: '%u' bytes\n"
+ "\tContents:\n"
+ "%s",
+ qmi_device_get_path_display (ctx->device),
+ user_data->len,
+ user_data_printable);
+ g_free (user_data_printable);
+
+ qmi_message_dms_read_user_data_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsWriteUserDataInput *
+write_user_data_input_create (const gchar *str)
+{
+ QmiMessageDmsWriteUserDataInput *input;
+ GArray *array;
+ GError *error = NULL;
+
+ /* Prepare inputs. Just assume we'll get some text string here, although
+ * nobody said this had to be text. Read User Data actually treats the
+ * contents of the user data as raw binary data. */
+ array = g_array_sized_new (FALSE, FALSE, 1, strlen (str));
+ g_array_insert_vals (array, 0, str, strlen (str));
+ input = qmi_message_dms_write_user_data_input_new ();
+ if (!qmi_message_dms_write_user_data_input_set_user_data (
+ input,
+ array,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_write_user_data_input_unref (input);
+ input = NULL;
+ }
+ g_array_unref (array);
+
+ return input;
+}
+
+static void
+write_user_data_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsWriteUserDataOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_write_user_data_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_write_user_data_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't write user data: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_write_user_data_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] User data written",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_write_user_data_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+read_eri_file_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsReadEriFileOutput *output;
+ GArray *eri_file = NULL;
+ gchar *eri_file_printable;
+ GError *error = NULL;
+
+ output = qmi_client_dms_read_eri_file_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_read_eri_file_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't read eri file: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_read_eri_file_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_read_eri_file_output_get_eri_file (
+ output,
+ &eri_file,
+ NULL);
+ eri_file_printable = qmicli_get_raw_data_printable (eri_file, 80, "\t\t");
+
+ g_print ("[%s] ERI file read:\n"
+ "\tSize: '%u' bytes\n"
+ "\tContents:\n"
+ "%s",
+ qmi_device_get_path_display (ctx->device),
+ eri_file->len,
+ eri_file_printable);
+ g_free (eri_file_printable);
+
+ qmi_message_dms_read_eri_file_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsRestoreFactoryDefaultsInput *
+restore_factory_defaults_input_create (const gchar *str)
+{
+ QmiMessageDmsRestoreFactoryDefaultsInput *input;
+ GError *error = NULL;
+
+ input = qmi_message_dms_restore_factory_defaults_input_new ();
+ if (!qmi_message_dms_restore_factory_defaults_input_set_service_programming_code (
+ input,
+ str,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_restore_factory_defaults_input_unref (input);
+ input = NULL;
+ }
+
+ return input;
+}
+
+static void
+restore_factory_defaults_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsRestoreFactoryDefaultsOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_restore_factory_defaults_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_restore_factory_defaults_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't restores factory defaults: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_restore_factory_defaults_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Factory defaults restored\n"
+ "Device needs to get power-cycled for reset to take effect.\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_restore_factory_defaults_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageDmsValidateServiceProgrammingCodeInput *
+validate_service_programming_code_input_create (const gchar *str)
+{
+ QmiMessageDmsValidateServiceProgrammingCodeInput *input;
+ GError *error = NULL;
+
+ input = qmi_message_dms_validate_service_programming_code_input_new ();
+ if (!qmi_message_dms_validate_service_programming_code_input_set_service_programming_code (
+ input,
+ str,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_dms_validate_service_programming_code_input_unref (input);
+ input = NULL;
+ }
+
+ return input;
+}
+
+static void
+validate_service_programming_code_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsValidateServiceProgrammingCodeOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_validate_service_programming_code_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_validate_service_programming_code_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't validate Service Programming Code: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_validate_service_programming_code_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Service Programming Code validated\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_validate_service_programming_code_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_band_capabilities_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsGetBandCapabilitiesOutput *output;
+ QmiDmsBandCapability band_capability;
+ QmiDmsLteBandCapability lte_band_capability;
+ GError *error = NULL;
+ gchar *str;
+
+ output = qmi_client_dms_get_band_capabilities_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_band_capabilities_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get band capabilities: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_band_capabilities_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_get_band_capabilities_output_get_band_capability (
+ output,
+ &band_capability,
+ NULL);
+
+ str = qmi_dms_band_capability_build_string_from_mask (band_capability);
+ g_print ("[%s] Device band capabilities retrieved:\n"
+ "\tBands: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ str);
+ g_free (str);
+
+ if (qmi_message_dms_get_band_capabilities_output_get_lte_band_capability (
+ output,
+ &lte_band_capability,
+ NULL)) {
+ str = qmi_dms_lte_band_capability_build_string_from_mask (lte_band_capability);
+ g_print ("\tLTE bands: '%s'\n", str);
+ g_free (str);
+ }
+
+ qmi_message_dms_get_band_capabilities_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_factory_sku_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ const gchar *str = NULL;
+ QmiMessageDmsGetFactorySkuOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_factory_sku_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_get_factory_sku_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get factory SKU: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_get_factory_sku_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ qmi_message_dms_get_factory_sku_output_get_sku (output, &str, NULL);
+
+ g_print ("[%s] Device factory SKU retrieved:\n"
+ "\tSKU: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ VALIDATE_UNKNOWN (str));
+
+ qmi_message_dms_get_factory_sku_output_unref (output);
+ shutdown (TRUE);
+}
+
+typedef struct {
+ QmiMessageDmsListStoredImagesOutput *list_images_output;
+ guint i;
+ guint j;
+} ListImagesContext;
+
+static void
+list_images_context_free (ListImagesContext *operation_ctx)
+{
+ qmi_message_dms_list_stored_images_output_unref (operation_ctx->list_images_output);
+ g_slice_free (ListImagesContext, operation_ctx);
+}
+
+static void get_image_info (ListImagesContext *operation_ctx);
+
+static void
+get_stored_image_info_ready (QmiClientDms *client,
+ GAsyncResult *res,
+ ListImagesContext *operation_ctx)
+{
+ GArray *array;
+ QmiMessageDmsGetStoredImageInfoOutput *output;
+ GError *error = NULL;
+ QmiMessageDmsListStoredImagesOutputListImage *image;
+ QmiMessageDmsListStoredImagesOutputListImageSublistSublistElement *subimage;
+ gchar *unique_id_str;
+
+ output = qmi_client_dms_get_stored_image_info_finish (client, res, &error);
+ if (!output) {
+ /* Fully ignore errors */
+ g_error_free (error);
+ } else if (!qmi_message_dms_get_stored_image_info_output_get_result (output, &error)) {
+ /* Fully ignore errors */
+ g_error_free (error);
+ }
+
+ qmi_message_dms_list_stored_images_output_get_list (
+ operation_ctx->list_images_output,
+ &array,
+ NULL);
+ image = &g_array_index (array, QmiMessageDmsListStoredImagesOutputListImage, operation_ctx->i);
+ subimage = &g_array_index (image->sublist,
+ QmiMessageDmsListStoredImagesOutputListImageSublistSublistElement,
+ operation_ctx->j);
+
+ unique_id_str = qmicli_get_raw_data_printable (subimage->unique_id, 80, "");
+ unique_id_str[strlen(unique_id_str) - 1] = '\0';
+
+ g_print ("%s"
+ "\t\t[%s%u]\n"
+ "\t\tUnique ID: '%s'\n"
+ "\t\tBuild ID: '%s'\n",
+ operation_ctx->j == image->index_of_running_image ? "\t\t>>>>>>>>>> [CURRENT] <<<<<<<<<<\n" : "",
+ qmi_dms_firmware_image_type_get_string (image->type),
+ operation_ctx->j,
+ unique_id_str,
+ subimage->build_id);
+
+ if (subimage->storage_index != 255)
+ g_print ("\t\tStorage index: '%u'\n", subimage->storage_index);
+
+ if (subimage->failure_count != 255)
+ g_print ("\t\tFailure count: '%u'\n", subimage->failure_count);
+
+ if (output) {
+ /* Boot version (optional) */
+ {
+ guint16 boot_major_version;
+ guint16 boot_minor_version;
+
+ if (qmi_message_dms_get_stored_image_info_output_get_boot_version (
+ output,
+ &boot_major_version,
+ &boot_minor_version,
+ NULL)) {
+ g_print ("\t\tBoot version: '%u.%u'\n",
+ boot_major_version,
+ boot_minor_version);
+ }
+ }
+
+ /* PRI version (optional) */
+ {
+ guint32 pri_version;
+ const gchar *pri_info;
+
+ if (qmi_message_dms_get_stored_image_info_output_get_pri_version (
+ output,
+ &pri_version,
+ &pri_info,
+ NULL)) {
+ g_print ("\t\tPRI version: '%u'\n"
+ "\t\tPRI info: '%s'\n",
+ pri_version,
+ pri_info);
+ }
+ }
+
+ /* OEM lock ID (optional) */
+ {
+ guint32 lock_id;
+
+ if (qmi_message_dms_get_stored_image_info_output_get_oem_lock_id (
+ output,
+ &lock_id,
+ NULL)) {
+ g_print ("\t\tOEM lock ID: '%u'\n",
+ lock_id);
+ }
+ }
+
+ qmi_message_dms_get_stored_image_info_output_unref (output);
+ }
+
+ g_print ("\n");
+ g_free (unique_id_str);
+
+ /* Go on to the next one */
+ operation_ctx->j++;
+ get_image_info (operation_ctx);
+}
+
+static void
+get_image_info (ListImagesContext *operation_ctx)
+{
+ GArray *array;
+ QmiMessageDmsListStoredImagesOutputListImage *image;
+ QmiMessageDmsListStoredImagesOutputListImageSublistSublistElement *subimage;
+ QmiMessageDmsGetStoredImageInfoInputImage image_id;
+ QmiMessageDmsGetStoredImageInfoInput *input;
+
+ qmi_message_dms_list_stored_images_output_get_list (
+ operation_ctx->list_images_output,
+ &array,
+ NULL);
+
+ if (operation_ctx->i >= array->len) {
+ /* We're done */
+ list_images_context_free (operation_ctx);
+ shutdown (TRUE);
+ return;
+ }
+
+ image = &g_array_index (array,
+ QmiMessageDmsListStoredImagesOutputListImage,
+ operation_ctx->i);
+
+ if (operation_ctx->j >= image->sublist->len) {
+ /* No more images in the sublist, go to next image type */
+ operation_ctx->j = 0;
+ operation_ctx->i++;
+ get_image_info (operation_ctx);
+ return;
+ }
+
+ /* Print info of the image type */
+ if (operation_ctx->j == 0) {
+ g_print ("\t[%u] Type: '%s'\n"
+ "\t Maximum: '%u'\n"
+ "\n",
+ operation_ctx->i,
+ qmi_dms_firmware_image_type_get_string (image->type),
+ image->maximum_images);
+ }
+
+ subimage = &g_array_index (image->sublist,
+ QmiMessageDmsListStoredImagesOutputListImageSublistSublistElement,
+ operation_ctx->j);
+
+ /* Query image info */
+ image_id.type = image->type;
+ image_id.unique_id = subimage->unique_id;
+ image_id.build_id = subimage->build_id;
+ input = qmi_message_dms_get_stored_image_info_input_new ();
+ qmi_message_dms_get_stored_image_info_input_set_image (input, &image_id, NULL);
+
+ qmi_client_dms_get_stored_image_info (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_stored_image_info_ready,
+ operation_ctx);
+ qmi_message_dms_get_stored_image_info_input_unref (input);
+}
+
+static void
+list_stored_images_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsListStoredImagesOutput *output;
+ GError *error = NULL;
+ ListImagesContext *operation_ctx;
+
+ output = qmi_client_dms_list_stored_images_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_list_stored_images_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't list stored images: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_list_stored_images_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Device list of stored images retrieved:\n\n",
+ qmi_device_get_path_display (ctx->device));
+
+ operation_ctx = g_slice_new0 (ListImagesContext);
+ operation_ctx->list_images_output = output;
+ operation_ctx->i = 0;
+ operation_ctx->j = 0;
+
+ get_image_info (operation_ctx);
+}
+
+typedef struct {
+ QmiClientDms *client;
+ GSimpleAsyncResult *result;
+ gint modem_index;
+ gint pri_index;
+} GetStoredImageContext;
+
+typedef struct {
+ GArray *modem_unique_id;
+ gchar *modem_build_id;
+ GArray *pri_unique_id;
+ gchar *pri_build_id;
+} GetStoredImageResult;
+
+static void
+get_stored_image_context_complete_and_free (GetStoredImageContext *operation_ctx)
+{
+ g_simple_async_result_complete (operation_ctx->result);
+ g_object_unref (operation_ctx->result);
+ g_object_unref (operation_ctx->client);
+ g_slice_free (GetStoredImageContext, operation_ctx);
+}
+
+static void
+get_stored_image_finish (QmiClientDms *client,
+ GAsyncResult *res,
+ GArray **modem_unique_id,
+ gchar **modem_build_id,
+ GArray **pri_unique_id,
+ gchar **pri_build_id)
+{
+ GetStoredImageResult *result;
+
+ result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
+
+ *modem_unique_id = result->modem_unique_id ? g_array_ref (result->modem_unique_id) : NULL;
+ *modem_build_id = g_strdup (result->modem_build_id);
+ *pri_unique_id = result->pri_unique_id ? g_array_ref (result->pri_unique_id) : NULL;
+ *pri_build_id = g_strdup (result->pri_build_id);
+}
+
+static void
+get_stored_image_list_stored_images_ready (QmiClientDms *client,
+ GAsyncResult *res,
+ GetStoredImageContext *operation_ctx)
+{
+ GetStoredImageResult result = { NULL, NULL, NULL, NULL };
+ GArray *array;
+ QmiMessageDmsListStoredImagesOutput *output;
+ GError *error = NULL;
+ guint i;
+
+ output = qmi_client_dms_list_stored_images_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_list_stored_images_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't list stored images: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_list_stored_images_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_dms_list_stored_images_output_get_list (
+ output,
+ &array,
+ NULL);
+
+ for (i = 0; i < array->len; i++) {
+ QmiMessageDmsListStoredImagesOutputListImageSublistSublistElement *subimage;
+ QmiMessageDmsListStoredImagesOutputListImage *image;
+ gchar *unique_id_str;
+ gint image_index;
+
+ image = &g_array_index (array,
+ QmiMessageDmsListStoredImagesOutputListImage,
+ i);
+
+ if (image->type == QMI_DMS_FIRMWARE_IMAGE_TYPE_MODEM)
+ image_index = operation_ctx->modem_index;
+ else if (image->type == QMI_DMS_FIRMWARE_IMAGE_TYPE_PRI)
+ image_index = operation_ctx->pri_index;
+ else
+ g_assert_not_reached ();
+
+ /* If not looking for the specific image type, go on */
+ if (image_index < 0)
+ continue;
+
+ if (image_index >= image->sublist->len) {
+ g_printerr ("error: couldn't find '%s' image at index '%d'\n",
+ qmi_dms_firmware_image_type_get_string (image->type),
+ image_index);
+ qmi_message_dms_list_stored_images_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ subimage = &g_array_index (image->sublist,
+ QmiMessageDmsListStoredImagesOutputListImageSublistSublistElement,
+ image_index);
+
+ unique_id_str = qmicli_get_raw_data_printable (subimage->unique_id, 80, "");
+ unique_id_str[strlen (unique_id_str) - 1] = '\0';
+ g_debug ("Found [%s%d]: Unique ID: '%s', Build ID: '%s'",
+ qmi_dms_firmware_image_type_get_string (image->type),
+ image_index,
+ unique_id_str,
+ subimage->build_id);
+ g_free (unique_id_str);
+
+ /* Build result */
+ if (image->type == QMI_DMS_FIRMWARE_IMAGE_TYPE_MODEM) {
+ result.modem_unique_id = subimage->unique_id;
+ result.modem_build_id = subimage->build_id;
+ } else if (image->type == QMI_DMS_FIRMWARE_IMAGE_TYPE_PRI) {
+ result.pri_unique_id = subimage->unique_id;
+ result.pri_build_id = subimage->build_id;
+ } else
+ g_assert_not_reached ();
+ }
+
+ /* Complete */
+ g_simple_async_result_set_op_res_gpointer (operation_ctx->result, &result, NULL);
+ get_stored_image_context_complete_and_free (operation_ctx);
+ qmi_message_dms_list_stored_images_output_unref (output);
+}
+
+static void
+get_stored_image (QmiClientDms *client,
+ const gchar *str,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GetStoredImageContext *operation_ctx;
+ gchar **split;
+ guint i = 0;
+ gint modem_index = -1;
+ gint pri_index = -1;
+
+ split = g_strsplit (str, ",", -1);
+ while (split[i]) {
+ QmiDmsFirmwareImageType type;
+ guint image_index;
+
+ if (i >= 3) {
+ g_printerr ("A maximum of 2 images should be given: '%s'\n", str);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmicli_read_firmware_id_from_string (split[i], &type, &image_index)) {
+ g_printerr ("Couldn't parse input string as firmware index info: '%s'\n", str);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (type == QMI_DMS_FIRMWARE_IMAGE_TYPE_MODEM) {
+ if (modem_index >= 0) {
+ g_printerr ("Couldn't two 'modem' type firwmare indexes: '%s'\n", str);
+ shutdown (FALSE);
+ return;
+ }
+ modem_index = (gint)image_index;
+ } else if (type == QMI_DMS_FIRMWARE_IMAGE_TYPE_PRI) {
+ if (pri_index >= 0) {
+ g_printerr ("Couldn't two 'pri' type firwmare indexes: '%s'\n", str);
+ shutdown (FALSE);
+ return;
+ }
+ pri_index = (gint)image_index;
+ }
+
+ i++;
+ }
+
+ operation_ctx = g_slice_new (GetStoredImageContext);
+ operation_ctx->client = g_object_ref (client);
+ operation_ctx->result = g_simple_async_result_new (G_OBJECT (client),
+ callback,
+ user_data,
+ get_stored_image);
+ operation_ctx->modem_index = modem_index;
+ operation_ctx->pri_index = pri_index;
+
+ qmi_client_dms_list_stored_images (
+ ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_stored_image_list_stored_images_ready,
+ operation_ctx);
+}
+
+static void
+select_stored_image_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsSetFirmwarePreferenceOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_set_firmware_preference_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_set_firmware_preference_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't select stored image: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_set_firmware_preference_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Stored image successfully selected\n"
+ "\n"
+ "\tYou may want to power-cycle the modem now, or just set it offline and reset it:\n"
+ "\t\t$> sudo qmicli ... --dms-set-operating-mode=offline\n"
+ "\t\t$> sudo qmicli ... --dms-set-operating-mode=reset\n"
+ "\n"
+ "\tYou should check that the modem|pri image pair is valid by checking the current operating mode:\n"
+ "\t\t$> sudo qmicli .... --dms-get-operating-mode\n"
+ "\tIf the Mode is reported as 'online', you're good to go.\n"
+ "\tIf the Mode is reported as 'offline' with a 'pri-version-incompatible' reason, you chose an incorrect pair\n"
+ "\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_set_firmware_preference_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_stored_image_select_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsSetFirmwarePreferenceInput *input;
+ GArray *array;
+ QmiMessageDmsSetFirmwarePreferenceInputListImage modem_image_id;
+ QmiMessageDmsSetFirmwarePreferenceInputListImage pri_image_id;
+
+ modem_image_id.type = QMI_DMS_FIRMWARE_IMAGE_TYPE_MODEM;
+ pri_image_id.type = QMI_DMS_FIRMWARE_IMAGE_TYPE_PRI;
+
+ get_stored_image_finish (client,
+ res,
+ &modem_image_id.unique_id,
+ &modem_image_id.build_id,
+ &pri_image_id.unique_id,
+ &pri_image_id.build_id);
+
+ if (!modem_image_id.unique_id || !modem_image_id.build_id ||
+ !pri_image_id.unique_id || !pri_image_id.build_id) {
+ g_printerr ("error: must specify a pair of 'modem' and 'pri' images to select\n");
+ shutdown (FALSE);
+ return;
+ }
+
+ array = g_array_sized_new (FALSE, FALSE, sizeof (QmiMessageDmsSetFirmwarePreferenceInputListImage), 2);
+ g_array_append_val (array, modem_image_id);
+ g_array_append_val (array, pri_image_id);
+
+ input = qmi_message_dms_set_firmware_preference_input_new ();
+ qmi_message_dms_set_firmware_preference_input_set_list (input, array, NULL);
+
+ qmi_client_dms_set_firmware_preference (
+ client,
+ input,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)select_stored_image_ready,
+ NULL);
+ qmi_message_dms_set_firmware_preference_input_unref (input);
+
+ g_free (modem_image_id.build_id);
+ if (modem_image_id.unique_id)
+ g_array_unref (modem_image_id.unique_id);
+ g_free (pri_image_id.build_id);
+ if (pri_image_id.unique_id)
+ g_array_unref (pri_image_id.unique_id);
+}
+
+static void
+delete_stored_image_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsDeleteStoredImageOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_delete_stored_image_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_delete_stored_image_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't delete stored image: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_delete_stored_image_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Stored image successfully deleted\n",
+ qmi_device_get_path_display (ctx->device));
+ qmi_message_dms_delete_stored_image_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_stored_image_delete_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsDeleteStoredImageInput *input;
+ QmiMessageDmsDeleteStoredImageInputImage modem_image_id;
+ QmiMessageDmsDeleteStoredImageInputImage pri_image_id;
+
+ modem_image_id.type = QMI_DMS_FIRMWARE_IMAGE_TYPE_MODEM;
+ pri_image_id.type = QMI_DMS_FIRMWARE_IMAGE_TYPE_PRI;
+
+ get_stored_image_finish (client,
+ res,
+ &modem_image_id.unique_id,
+ &modem_image_id.build_id,
+ &pri_image_id.unique_id,
+ &pri_image_id.build_id);
+
+ if (modem_image_id.unique_id && modem_image_id.build_id &&
+ pri_image_id.unique_id && pri_image_id.build_id) {
+ g_printerr ("error: cannot specify multiple images to delete\n");
+ shutdown (FALSE);
+ return;
+ }
+
+ input = qmi_message_dms_delete_stored_image_input_new ();
+ if (modem_image_id.unique_id && modem_image_id.build_id)
+ qmi_message_dms_delete_stored_image_input_set_image (input, &modem_image_id, NULL);
+ else if (pri_image_id.unique_id && pri_image_id.build_id)
+ qmi_message_dms_delete_stored_image_input_set_image (input, &pri_image_id, NULL);
+ else {
+ g_printerr ("error: didn't specify correctly an image to delete\n");
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_client_dms_delete_stored_image (
+ client,
+ input,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)delete_stored_image_ready,
+ NULL);
+ qmi_message_dms_delete_stored_image_input_unref (input);
+
+ g_free (modem_image_id.build_id);
+ if (modem_image_id.unique_id)
+ g_array_unref (modem_image_id.unique_id);
+ g_free (pri_image_id.build_id);
+ if (pri_image_id.unique_id)
+ g_array_unref (pri_image_id.unique_id);
+}
+
+static void
+reset_ready (QmiClientDms *client,
+ GAsyncResult *res)
+{
+ QmiMessageDmsResetOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_reset_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_dms_reset_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't reset the DMS service: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_dms_reset_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully performed DMS service reset\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_dms_reset_output_unref (output);
+ shutdown (TRUE);
+}
+
+static gboolean
+noop_cb (gpointer unused)
+{
+ shutdown (TRUE);
+ return FALSE;
+}
+
+void
+qmicli_dms_run (QmiDevice *device,
+ QmiClientDms *client,
+ GCancellable *cancellable)
+{
+ /* Initialize context */
+ ctx = g_slice_new (Context);
+ ctx->device = g_object_ref (device);
+ ctx->client = g_object_ref (client);
+ if (cancellable)
+ ctx->cancellable = g_object_ref (cancellable);
+
+ /* Request to get IDs? */
+ if (get_ids_flag) {
+ g_debug ("Asynchronously getting IDs...");
+ qmi_client_dms_get_ids (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_ids_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get capabilities? */
+ if (get_capabilities_flag) {
+ g_debug ("Asynchronously getting capabilities...");
+ qmi_client_dms_get_capabilities (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_capabilities_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get manufacturer? */
+ if (get_manufacturer_flag) {
+ g_debug ("Asynchronously getting manufacturer...");
+ qmi_client_dms_get_manufacturer (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_manufacturer_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get model? */
+ if (get_model_flag) {
+ g_debug ("Asynchronously getting model...");
+ qmi_client_dms_get_model (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_model_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get revision? */
+ if (get_revision_flag) {
+ g_debug ("Asynchronously getting revision...");
+ qmi_client_dms_get_revision (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_revision_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get msisdn? */
+ if (get_msisdn_flag) {
+ g_debug ("Asynchronously getting msisdn...");
+ qmi_client_dms_get_msisdn (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_msisdn_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get power status? */
+ if (get_power_state_flag) {
+ g_debug ("Asynchronously getting power status...");
+ qmi_client_dms_get_power_state (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_power_state_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to set PIN protection? */
+ if (uim_set_pin_protection_str) {
+ QmiMessageDmsUimSetPinProtectionInput *input;
+
+ g_debug ("Asynchronously setting PIN protection...");
+ input = uim_set_pin_protection_input_create (uim_set_pin_protection_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_uim_set_pin_protection (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)uim_set_pin_protection_ready,
+ NULL);
+ qmi_message_dms_uim_set_pin_protection_input_unref (input);
+ return;
+ }
+
+ /* Request to verify PIN? */
+ if (uim_verify_pin_str) {
+ QmiMessageDmsUimVerifyPinInput *input;
+
+ g_debug ("Asynchronously verifying PIN...");
+ input = uim_verify_pin_input_create (uim_verify_pin_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_uim_verify_pin (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)uim_verify_pin_ready,
+ NULL);
+ qmi_message_dms_uim_verify_pin_input_unref (input);
+ return;
+ }
+
+ /* Request to unblock PIN? */
+ if (uim_unblock_pin_str) {
+ QmiMessageDmsUimUnblockPinInput *input;
+
+ g_debug ("Asynchronously unblocking PIN...");
+ input = uim_unblock_pin_input_create (uim_unblock_pin_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_uim_unblock_pin (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)uim_unblock_pin_ready,
+ NULL);
+ qmi_message_dms_uim_unblock_pin_input_unref (input);
+ return;
+ }
+
+ /* Request to change the PIN? */
+ if (uim_change_pin_str) {
+ QmiMessageDmsUimChangePinInput *input;
+
+ g_debug ("Asynchronously changing PIN...");
+ input = uim_change_pin_input_create (uim_change_pin_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_uim_change_pin (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)uim_change_pin_ready,
+ NULL);
+ qmi_message_dms_uim_change_pin_input_unref (input);
+ return;
+ }
+
+ /* Request to get PIN status? */
+ if (uim_get_pin_status_flag) {
+ g_debug ("Asynchronously getting PIN status...");
+ qmi_client_dms_uim_get_pin_status (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)uim_get_pin_status_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get UIM ICCID? */
+ if (uim_get_iccid_flag) {
+ g_debug ("Asynchronously getting UIM ICCID...");
+ qmi_client_dms_uim_get_iccid (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)uim_get_iccid_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get UIM IMSI? */
+ if (uim_get_imsi_flag) {
+ g_debug ("Asynchronously getting UIM IMSI...");
+ qmi_client_dms_uim_get_imsi (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)uim_get_imsi_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get UIM state? */
+ if (uim_get_state_flag) {
+ g_debug ("Asynchronously getting UIM state...");
+ qmi_client_dms_uim_get_state (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)uim_get_state_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get hardware revision? */
+ if (get_hardware_revision_flag) {
+ g_debug ("Asynchronously getting hardware revision...");
+ qmi_client_dms_get_hardware_revision (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_hardware_revision_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get operating mode? */
+ if (get_operating_mode_flag) {
+ g_debug ("Asynchronously getting operating mode...");
+ qmi_client_dms_get_operating_mode (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_operating_mode_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to set operating mode? */
+ if (set_operating_mode_str) {
+ QmiMessageDmsSetOperatingModeInput *input;
+
+ g_debug ("Asynchronously setting operating mode...");
+ input = set_operating_mode_input_create (set_operating_mode_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_set_operating_mode (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)set_operating_mode_ready,
+ NULL);
+ qmi_message_dms_set_operating_mode_input_unref (input);
+ return;
+ }
+
+ /* Request to get time? */
+ if (get_time_flag) {
+ g_debug ("Asynchronously getting time...");
+ qmi_client_dms_get_time (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_time_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get the PRL version? */
+ if (get_prl_version_flag) {
+ g_debug ("Asynchronously getting PRL version...");
+ qmi_client_dms_get_prl_version (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_prl_version_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get the activation state? */
+ if (get_activation_state_flag) {
+ g_debug ("Asynchronously getting activation state...");
+ qmi_client_dms_get_activation_state (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_activation_state_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to activate automatically? */
+ if (activate_automatic_str) {
+ QmiMessageDmsActivateAutomaticInput *input;
+
+ g_debug ("Asynchronously requesting automatic activation...");
+ input = activate_automatic_input_create (activate_automatic_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_activate_automatic (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)activate_automatic_ready,
+ NULL);
+ qmi_message_dms_activate_automatic_input_unref (input);
+ return;
+ }
+
+ /* Request to activate manually? */
+ if (activate_manual_str) {
+ QmiMessageDmsActivateManualInput *input;
+
+ g_debug ("Asynchronously requesting manual activation...");
+ input = activate_manual_input_create (activate_manual_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_activate_manual (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)activate_manual_ready,
+ NULL);
+ qmi_message_dms_activate_manual_input_unref (input);
+ return;
+ }
+
+ /* Request to get the activation state? */
+ if (get_user_lock_state_flag) {
+ g_debug ("Asynchronously getting user lock state...");
+ qmi_client_dms_get_user_lock_state (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_user_lock_state_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to set user lock state? */
+ if (set_user_lock_state_str) {
+ QmiMessageDmsSetUserLockStateInput *input;
+
+ g_debug ("Asynchronously setting user lock state...");
+ input = set_user_lock_state_input_create (set_user_lock_state_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_set_user_lock_state (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)set_user_lock_state_ready,
+ NULL);
+ qmi_message_dms_set_user_lock_state_input_unref (input);
+ return;
+ }
+
+ /* Request to set user lock code? */
+ if (set_user_lock_code_str) {
+ QmiMessageDmsSetUserLockCodeInput *input;
+
+ g_debug ("Asynchronously changing user lock code...");
+ input = set_user_lock_code_input_create (set_user_lock_code_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_set_user_lock_code (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)set_user_lock_code_ready,
+ NULL);
+ qmi_message_dms_set_user_lock_code_input_unref (input);
+ return;
+ }
+
+ /* Request to read user data? */
+ if (read_user_data_flag) {
+ g_debug ("Asynchronously reading user data...");
+ qmi_client_dms_read_user_data (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)read_user_data_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to write user data? */
+ if (write_user_data_str) {
+ QmiMessageDmsWriteUserDataInput *input;
+
+ g_debug ("Asynchronously writing user data...");
+ input = write_user_data_input_create (write_user_data_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_write_user_data (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)write_user_data_ready,
+ NULL);
+ qmi_message_dms_write_user_data_input_unref (input);
+ return;
+ }
+
+ /* Request to read ERI file? */
+ if (read_eri_file_flag) {
+ g_debug ("Asynchronously reading ERI file...");
+ qmi_client_dms_read_eri_file (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)read_eri_file_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to restore factory defaults? */
+ if (restore_factory_defaults_str) {
+ QmiMessageDmsRestoreFactoryDefaultsInput *input;
+
+ g_debug ("Asynchronously restoring factory defaults...");
+ input = restore_factory_defaults_input_create (restore_factory_defaults_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_restore_factory_defaults (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)restore_factory_defaults_ready,
+ NULL);
+ qmi_message_dms_restore_factory_defaults_input_unref (input);
+ return;
+ }
+
+ /* Request to validate SPC? */
+ if (validate_service_programming_code_str) {
+ QmiMessageDmsValidateServiceProgrammingCodeInput *input;
+
+ g_debug ("Asynchronously validating SPC...");
+ input = validate_service_programming_code_input_create (validate_service_programming_code_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_validate_service_programming_code (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)validate_service_programming_code_ready,
+ NULL);
+ qmi_message_dms_validate_service_programming_code_input_unref (input);
+ return;
+ }
+
+ /* Request to get CK status? */
+ if (uim_get_ck_status_str) {
+ QmiMessageDmsUimGetCkStatusInput *input;
+
+ g_debug ("Asynchronously getting CK status...");
+ input = uim_get_ck_status_input_create (uim_get_ck_status_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_uim_get_ck_status (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)uim_get_ck_status_ready,
+ NULL);
+ qmi_message_dms_uim_get_ck_status_input_unref (input);
+ return;
+ }
+
+ /* Request to set CK protection? */
+ if (uim_set_ck_protection_str) {
+ QmiMessageDmsUimSetCkProtectionInput *input;
+
+ g_debug ("Asynchronously setting CK protection...");
+ input = uim_set_ck_protection_input_create (uim_set_ck_protection_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_uim_set_ck_protection (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)uim_set_ck_protection_ready,
+ NULL);
+ qmi_message_dms_uim_set_ck_protection_input_unref (input);
+ return;
+ }
+
+ /* Request to set CK protection? */
+ if (uim_unblock_ck_str) {
+ QmiMessageDmsUimUnblockCkInput *input;
+
+ g_debug ("Asynchronously unblocking CK...");
+ input = uim_unblock_ck_input_create (uim_unblock_ck_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+ qmi_client_dms_uim_unblock_ck (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)uim_unblock_ck_ready,
+ NULL);
+ qmi_message_dms_uim_unblock_ck_input_unref (input);
+ return;
+ }
+
+ /* Request to get band capabilities? */
+ if (get_band_capabilities_flag) {
+ g_debug ("Asynchronously getting band capabilities...");
+ qmi_client_dms_get_band_capabilities (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_band_capabilities_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get factory SKU? */
+ if (get_factory_sku_flag) {
+ g_debug ("Asynchronously getting factory SKU...");
+ qmi_client_dms_get_factory_sku (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_factory_sku_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to list stored images? */
+ if (list_stored_images_flag) {
+ g_debug ("Asynchronously listing stored images...");
+ qmi_client_dms_list_stored_images (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)list_stored_images_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to select stored image? */
+ if (select_stored_image_str) {
+ g_debug ("Asynchronously selecting stored image...");
+ get_stored_image (ctx->client,
+ select_stored_image_str,
+ (GAsyncReadyCallback)get_stored_image_select_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to delete stored image? */
+ if (delete_stored_image_str) {
+ g_debug ("Asynchronously deleting stored image...");
+ get_stored_image (ctx->client,
+ delete_stored_image_str,
+ (GAsyncReadyCallback)get_stored_image_delete_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to reset DMS service? */
+ if (reset_flag) {
+ g_debug ("Asynchronously resetting DMS service...");
+ qmi_client_dms_reset (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)reset_ready,
+ NULL);
+ return;
+ }
+
+ /* Just client allocate/release? */
+ if (noop_flag) {
+ g_idle_add (noop_cb, NULL);
+ return;
+ }
+
+ g_warn_if_reached ();
+}
diff --git a/src/qmicli/qmicli-helpers.c b/src/qmicli/qmicli-helpers.c
new file mode 100644
index 0000000..10f654c
--- /dev/null
+++ b/src/qmicli/qmicli-helpers.c
@@ -0,0 +1,308 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * qmicli -- Command line interface to control QMI devices
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "qmicli-helpers.h"
+
+gchar *
+qmicli_get_raw_data_printable (const GArray *data,
+ gsize max_line_length,
+ const gchar *line_prefix)
+{
+ gsize i;
+ gsize j;
+ gsize k;
+ gsize new_str_length;
+ gchar *new_str;
+ gsize prefix_len;
+ guint n_lines;
+ gboolean is_new_line;
+
+ g_return_val_if_fail (max_line_length >= 3, NULL);
+
+ if (!data)
+ return g_strdup ("");
+
+ /* 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 * data->len;
+
+ /* Effective max line length needs to be multiple of 3, we don't want to
+ * split in half a given byte representation */
+ while (max_line_length % 3 != 0)
+ max_line_length--;
+
+ /* Prefix len includes the newline character plus the length of the input
+ * prefix */
+ prefix_len = strlen (line_prefix) + 1;
+ /* We don't consider the last NUL byte when counting lines to generate */
+ n_lines = (new_str_length - 1) / max_line_length;
+ if ((new_str_length - 1) % max_line_length != 0)
+ n_lines++;
+
+ /* Build new str length expected when we prefix the string and we limit the
+ * line length */
+ new_str_length += (n_lines * prefix_len);
+
+ /* Allocate memory for new array and initialize contents to NUL */
+ new_str = g_malloc0 (new_str_length);
+
+ /* Print hexadecimal representation of each byte... */
+ is_new_line = TRUE;
+ for (i = 0, j = 0, k = 0; i < data->len; i++) {
+ if (is_new_line) {
+ strcpy (&new_str[j], line_prefix);
+ j += strlen (line_prefix);
+ is_new_line = FALSE;
+ }
+
+ /* Print character in output string... */
+ snprintf (&new_str[j], 3, "%02X", g_array_index (data, guint8, i));
+ j+=2;
+ k+=2;
+
+ if (i != (data->len - 1) ) {
+ new_str[j] = ':';
+ j++;
+ k++;
+ }
+
+ if (k % max_line_length == 0 ||
+ i == (data->len -1)) {
+ new_str[j] = '\n';
+ j++;
+ is_new_line = TRUE;
+ }
+ }
+
+ /* Set output string */
+ return new_str;
+}
+
+gboolean
+qmicli_read_pin_id_from_string (const gchar *str,
+ QmiDmsUimPinId *out)
+{
+ if (!str || str[0] == '\0') {
+ g_printerr ("error: expected 'PIN' or 'PIN2', got: none\n");
+ return FALSE;
+ }
+
+ if (g_str_equal (str, "PIN")) {
+ *out = QMI_DMS_UIM_PIN_ID_PIN;
+ return TRUE;
+ }
+
+ if (g_str_equal (str, "PIN2")) {
+ *out = QMI_DMS_UIM_PIN_ID_PIN2;
+ return TRUE;
+ }
+
+ g_printerr ("error: expected 'PIN' or 'PIN2', got: '%s'\n", str);
+ return FALSE;
+}
+
+gboolean
+qmicli_read_operating_mode_from_string (const gchar *str,
+ QmiDmsOperatingMode *out)
+{
+ GType type;
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+
+ type = qmi_dms_operating_mode_get_type ();
+ enum_class = G_ENUM_CLASS (g_type_class_ref (type));
+ enum_value = g_enum_get_value_by_nick (enum_class, str);
+
+ if (enum_value)
+ *out = (QmiDmsOperatingMode)enum_value->value;
+ else
+ g_printerr ("error: invalid operating mode value given: '%s'\n", str);
+
+ g_type_class_unref (enum_class);
+ return !!enum_value;
+}
+
+gboolean
+qmicli_read_rat_mode_pref_from_string (const gchar *str,
+ QmiNasRatModePreference *out)
+{
+ GType type;
+ GFlagsClass *flags_class;
+ GFlagsValue *flags_value;
+ gboolean success = TRUE, set = FALSE;
+ char **items, **iter;
+
+ type = qmi_nas_rat_mode_preference_get_type ();
+ flags_class = G_FLAGS_CLASS (g_type_class_ref (type));
+
+ items = g_strsplit_set (str, "|", 0);
+ for (iter = items; iter && *iter && success; iter++) {
+ if (!*iter[0])
+ continue;
+
+ flags_value = g_flags_get_value_by_nick (flags_class, *iter);
+ if (flags_value) {
+ *out |= (QmiNasRatModePreference)flags_value->value;
+ set = TRUE;
+ } else {
+ g_printerr ("error: invalid rat mode pref value given: '%s'\n", *iter);
+ success = FALSE;
+ }
+ }
+
+ if (!set)
+ g_printerr ("error: invalid rat mode pref input given: '%s'\n", str);
+
+ if (items)
+ g_strfreev (items);
+ g_type_class_unref (flags_class);
+ return success && set;
+}
+
+gboolean
+qmicli_read_facility_from_string (const gchar *str,
+ QmiDmsUimFacility *out)
+{
+ GType type;
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+
+ type = qmi_dms_uim_facility_get_type ();
+ enum_class = G_ENUM_CLASS (g_type_class_ref (type));
+ enum_value = g_enum_get_value_by_nick (enum_class, str);
+
+ if (enum_value)
+ *out = (QmiDmsUimFacility)enum_value->value;
+ else
+ g_printerr ("error: invalid facility value given: '%s'\n", str);
+
+ g_type_class_unref (enum_class);
+ return !!enum_value;
+}
+
+gboolean
+qmicli_read_enable_disable_from_string (const gchar *str,
+ gboolean *out)
+{
+ if (!str || str[0] == '\0') {
+ g_printerr ("error: expected 'disable' or 'enable', got: none\n");
+ return FALSE;
+ }
+
+ if (g_str_equal (str, "disable")) {
+ *out = FALSE;
+ return TRUE;
+ }
+
+ if (g_str_equal (str, "enable")) {
+ *out = TRUE;
+ return TRUE;
+ }
+
+ g_printerr ("error: expected 'disable' or 'enable', got: '%s'\n", str);
+ return FALSE;
+}
+
+gboolean
+qmicli_read_non_empty_string (const gchar *str,
+ const gchar *description,
+ gchar **out)
+{
+ if (!str || str[0] == '\0') {
+ g_printerr ("error: empty %s given\n", description);
+ return FALSE;
+ }
+
+ *out = (gchar *)str;
+ return TRUE;
+}
+
+gboolean
+qmicli_read_firmware_id_from_string (const gchar *str,
+ QmiDmsFirmwareImageType *out_type,
+ guint *out_index)
+{
+ const gchar *index_str;
+
+ if (g_str_has_prefix (str, "modem")) {
+ *out_type = QMI_DMS_FIRMWARE_IMAGE_TYPE_MODEM;
+ index_str = &str[5];
+ } else if (g_str_has_prefix (str, "pri")) {
+ *out_type = QMI_DMS_FIRMWARE_IMAGE_TYPE_PRI;
+ index_str = &str[3];
+ } else {
+ g_printerr ("error: invalid firmware image type value given: '%s'\n", str);
+ return FALSE;
+ }
+
+ return qmicli_read_uint_from_string (index_str, out_index);
+}
+
+gboolean
+qmicli_read_radio_interface_from_string (const gchar *str,
+ QmiNasRadioInterface *out)
+{
+ GType type;
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+
+ type = qmi_nas_radio_interface_get_type ();
+ enum_class = G_ENUM_CLASS (g_type_class_ref (type));
+ enum_value = g_enum_get_value_by_nick (enum_class, str);
+
+ if (enum_value)
+ *out = (QmiNasRadioInterface)enum_value->value;
+ else
+ g_printerr ("error: invalid radio interface value given: '%s'\n", str);
+
+ g_type_class_unref (enum_class);
+ return !!enum_value;
+}
+
+gboolean
+qmicli_read_uint_from_string (const gchar *str,
+ guint *out)
+{
+ gulong num;
+
+ if (!str || !str[0])
+ return FALSE;
+
+ for (num = 0; str[num]; num++) {
+ if (!g_ascii_isdigit (str[num]))
+ return FALSE;
+ }
+
+ errno = 0;
+ num = strtoul (str, NULL, 10);
+ if (!errno && num <= G_MAXUINT) {
+ *out = (guint)num;
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/src/qmicli/qmicli-helpers.h b/src/qmicli/qmicli-helpers.h
new file mode 100644
index 0000000..d33f442
--- /dev/null
+++ b/src/qmicli/qmicli-helpers.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * qmicli -- Command line interface to control QMI devices
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
+ */
+
+#include <glib.h>
+
+#include <libqmi-glib.h>
+
+#ifndef __QMICLI_HELPERS_H__
+#define __QMICLI_HELPERS_H__
+
+gchar *qmicli_get_raw_data_printable (const GArray *data,
+ gsize max_line_length,
+ const gchar *new_line_prefix);
+
+gboolean qmicli_read_pin_id_from_string (const gchar *str,
+ QmiDmsUimPinId *out);
+gboolean qmicli_read_operating_mode_from_string (const gchar *str,
+ QmiDmsOperatingMode *out);
+gboolean qmicli_read_rat_mode_pref_from_string (const gchar *str,
+ QmiNasRatModePreference *out);
+gboolean qmicli_read_facility_from_string (const gchar *str,
+ QmiDmsUimFacility *out);
+gboolean qmicli_read_enable_disable_from_string (const gchar *str,
+ gboolean *out);
+gboolean qmicli_read_firmware_id_from_string (const gchar *str,
+ QmiDmsFirmwareImageType *out_type,
+ guint *out_index);
+
+gboolean qmicli_read_radio_interface_from_string (const gchar *str,
+ QmiNasRadioInterface *out);
+
+gboolean qmicli_read_non_empty_string (const gchar *str,
+ const gchar *description,
+ gchar **out);
+gboolean qmicli_read_uint_from_string (const gchar *str,
+ guint *out);
+
+#endif /* __QMICLI_H__ */
diff --git a/src/qmicli/qmicli-nas.c b/src/qmicli/qmicli-nas.c
new file mode 100644
index 0000000..77c8b25
--- /dev/null
+++ b/src/qmicli/qmicli-nas.c
@@ -0,0 +1,2427 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * qmicli -- Command line interface to control QMI devices
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <libqmi-glib.h>
+
+#include "qmicli.h"
+#include "qmicli-helpers.h"
+
+/* Context */
+typedef struct {
+ QmiDevice *device;
+ QmiClientNas *client;
+ GCancellable *cancellable;
+} Context;
+static Context *ctx;
+
+/* Options */
+static gboolean get_signal_strength_flag;
+static gboolean get_signal_info_flag;
+static gchar *get_tx_rx_info_str;
+static gboolean get_home_network_flag;
+static gboolean get_serving_system_flag;
+static gboolean get_system_info_flag;
+static gboolean get_technology_preference_flag;
+static gboolean get_system_selection_preference_flag;
+static gchar *set_system_selection_preference_str;
+static gboolean network_scan_flag;
+static gboolean reset_flag;
+static gboolean noop_flag;
+
+static GOptionEntry entries[] = {
+ { "nas-get-signal-strength", 0, 0, G_OPTION_ARG_NONE, &get_signal_strength_flag,
+ "Get signal strength",
+ NULL
+ },
+ { "nas-get-signal-info", 0, 0, G_OPTION_ARG_NONE, &get_signal_info_flag,
+ "Get signal info",
+ NULL
+ },
+ { "nas-get-tx-rx-info", 0, 0, G_OPTION_ARG_STRING, &get_tx_rx_info_str,
+ "Get TX/RX info",
+ "[(Radio Interface)]",
+ },
+ { "nas-get-home-network", 0, 0, G_OPTION_ARG_NONE, &get_home_network_flag,
+ "Get home network",
+ NULL
+ },
+ { "nas-get-serving-system", 0, 0, G_OPTION_ARG_NONE, &get_serving_system_flag,
+ "Get serving system",
+ NULL
+ },
+ { "nas-get-system-info", 0, 0, G_OPTION_ARG_NONE, &get_system_info_flag,
+ "Get system info",
+ NULL
+ },
+ { "nas-get-technology-preference", 0, 0, G_OPTION_ARG_NONE, &get_technology_preference_flag,
+ "Get technology preference",
+ NULL
+ },
+ { "nas-get-system-selection-preference", 0, 0, G_OPTION_ARG_NONE, &get_system_selection_preference_flag,
+ "Get system selection preference",
+ NULL
+ },
+ { "nas-set-system-selection-preference", 0, 0, G_OPTION_ARG_STRING, &set_system_selection_preference_str,
+ "Set system selection preference",
+ "[cdma-1x|cdma-1xevdo|gsm|umts|lte|td-scdma]"
+ },
+ { "nas-network-scan", 0, 0, G_OPTION_ARG_NONE, &network_scan_flag,
+ "Scan networks",
+ NULL
+ },
+ { "nas-reset", 0, 0, G_OPTION_ARG_NONE, &reset_flag,
+ "Reset the service state",
+ NULL
+ },
+ { "nas-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
+ "Just allocate or release a NAS client. Use with `--client-no-release-cid' and/or `--client-cid'",
+ NULL
+ },
+ { NULL }
+};
+
+GOptionGroup *
+qmicli_nas_get_option_group (void)
+{
+ GOptionGroup *group;
+
+ group = g_option_group_new ("nas",
+ "NAS options",
+ "Show Network Access Service options",
+ NULL,
+ NULL);
+ g_option_group_add_entries (group, entries);
+
+ return group;
+}
+
+gboolean
+qmicli_nas_options_enabled (void)
+{
+ static guint n_actions = 0;
+ static gboolean checked = FALSE;
+
+ if (checked)
+ return !!n_actions;
+
+ n_actions = (get_signal_strength_flag +
+ get_signal_info_flag +
+ !!get_tx_rx_info_str +
+ get_home_network_flag +
+ get_serving_system_flag +
+ get_system_info_flag +
+ get_technology_preference_flag +
+ get_system_selection_preference_flag +
+ !!set_system_selection_preference_str +
+ network_scan_flag +
+ reset_flag +
+ noop_flag);
+
+ if (n_actions > 1) {
+ g_printerr ("error: too many NAS actions requested\n");
+ exit (EXIT_FAILURE);
+ }
+
+ checked = TRUE;
+ return !!n_actions;
+}
+
+static void
+context_free (Context *context)
+{
+ if (!context)
+ return;
+
+ if (context->cancellable)
+ g_object_unref (context->cancellable);
+ if (context->device)
+ g_object_unref (context->device);
+ if (context->client)
+ g_object_unref (context->client);
+ g_slice_free (Context, context);
+}
+
+static void
+shutdown (gboolean operation_status)
+{
+ /* Cleanup context and finish async operation */
+ context_free (ctx);
+ qmicli_async_operation_done (operation_status);
+}
+
+static gdouble
+get_db_from_sinr_level (QmiNasEvdoSinrLevel level)
+{
+ switch (level) {
+ case QMI_NAS_EVDO_SINR_LEVEL_0: return -9.0;
+ case QMI_NAS_EVDO_SINR_LEVEL_1: return -6;
+ case QMI_NAS_EVDO_SINR_LEVEL_2: return -4.5;
+ case QMI_NAS_EVDO_SINR_LEVEL_3: return -3;
+ case QMI_NAS_EVDO_SINR_LEVEL_4: return -2;
+ case QMI_NAS_EVDO_SINR_LEVEL_5: return 1;
+ case QMI_NAS_EVDO_SINR_LEVEL_6: return 3;
+ case QMI_NAS_EVDO_SINR_LEVEL_7: return 6;
+ case QMI_NAS_EVDO_SINR_LEVEL_8: return +9;
+ default:
+ g_warning ("Invalid SINR level '%u'", level);
+ return -G_MAXDOUBLE;
+ }
+}
+
+static void
+get_signal_info_ready (QmiClientNas *client,
+ GAsyncResult *res)
+{
+ QmiMessageNasGetSignalInfoOutput *output;
+ GError *error = NULL;
+ gint8 rssi;
+ gint16 ecio;
+ QmiNasEvdoSinrLevel sinr_level;
+ gint32 io;
+ gint8 rsrq;
+ gint16 rsrp;
+ gint16 snr;
+ gint8 rscp;
+
+ output = qmi_client_nas_get_signal_info_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_nas_get_signal_info_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get signal info: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_nas_get_signal_info_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully got signal info\n",
+ qmi_device_get_path_display (ctx->device));
+
+ /* CDMA... */
+ if (qmi_message_nas_get_signal_info_output_get_cdma_signal_strength (output,
+ &rssi,
+ &ecio,
+ NULL)) {
+ g_print ("CDMA:\n"
+ "\tRSSI: '%d dBm'\n"
+ "\tECIO: '%.1lf dBm'\n",
+ rssi,
+ (-0.5)*((gdouble)ecio));
+ }
+
+ /* HDR... */
+ if (qmi_message_nas_get_signal_info_output_get_hdr_signal_strength (output,
+ &rssi,
+ &ecio,
+ &sinr_level,
+ &io,
+ NULL)) {
+ g_print ("HDR:\n"
+ "\tRSSI: '%d dBm'\n"
+ "\tECIO: '%.1lf dBm'\n"
+ "\tSINR (%u): '%.1lf dB'\n"
+ "\tIO: '%d dBm'\n",
+ rssi,
+ (-0.5)*((gdouble)ecio),
+ sinr_level, get_db_from_sinr_level (sinr_level),
+ io);
+ }
+
+ /* GSM */
+ if (qmi_message_nas_get_signal_info_output_get_gsm_signal_strength (output,
+ &rssi,
+ NULL)) {
+ g_print ("GSM:\n"
+ "\tRSSI: '%d dBm'\n",
+ rssi);
+ }
+
+ /* WCDMA... */
+ if (qmi_message_nas_get_signal_info_output_get_wcdma_signal_strength (output,
+ &rssi,
+ &ecio,
+ NULL)) {
+ g_print ("WCDMA:\n"
+ "\tRSSI: '%d dBm'\n"
+ "\tECIO: '%.1lf dBm'\n",
+ rssi,
+ (-0.5)*((gdouble)ecio));
+ }
+
+ /* LTE... */
+ if (qmi_message_nas_get_signal_info_output_get_lte_signal_strength (output,
+ &rssi,
+ &rsrq,
+ &rsrp,
+ &snr,
+ NULL)) {
+ g_print ("LTE:\n"
+ "\tRSSI: '%d dBm'\n"
+ "\tRSRQ: '%d dB'\n"
+ "\tRSRP: '%d dBm'\n"
+ "\tSNR: '%.1lf dBm'\n",
+ rssi,
+ rsrq,
+ rsrp,
+ (0.1) * ((gdouble)snr));
+ }
+
+ /* TDMA */
+ if (qmi_message_nas_get_signal_info_output_get_tdma_signal_strength (output,
+ &rscp,
+ NULL)) {
+ g_print ("TDMA:\n"
+ "\tRSCP: '%d dBm'\n",
+ rscp);
+ }
+
+ qmi_message_nas_get_signal_info_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageNasGetSignalStrengthInput *
+get_signal_strength_input_create (void)
+{
+ GError *error = NULL;
+ QmiMessageNasGetSignalStrengthInput *input;
+ QmiNasSignalStrengthRequest mask;
+
+ mask = (QMI_NAS_SIGNAL_STRENGTH_REQUEST_RSSI |
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_ECIO |
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_IO |
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_SINR |
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_RSRQ |
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_LTE_SNR |
+ QMI_NAS_SIGNAL_STRENGTH_REQUEST_LTE_RSRP);
+
+ input = qmi_message_nas_get_signal_strength_input_new ();
+ if (!qmi_message_nas_get_signal_strength_input_set_request_mask (
+ input,
+ mask,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_nas_get_signal_strength_input_unref (input);
+ input = NULL;
+ }
+
+ return input;
+}
+
+static void
+get_signal_strength_ready (QmiClientNas *client,
+ GAsyncResult *res)
+{
+ QmiMessageNasGetSignalStrengthOutput *output;
+ GError *error = NULL;
+ GArray *array;
+ QmiNasRadioInterface radio_interface;
+ gint8 strength;
+ gint32 io;
+ QmiNasEvdoSinrLevel sinr_level;
+ gint8 rsrq;
+ gint16 rsrp;
+ gint16 snr;
+
+ output = qmi_client_nas_get_signal_strength_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_nas_get_signal_strength_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get signal strength: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_nas_get_signal_strength_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_nas_get_signal_strength_output_get_signal_strength (output,
+ &strength,
+ &radio_interface,
+ NULL);
+
+ g_print ("[%s] Successfully got signal strength\n"
+ "Current:\n"
+ "\tNetwork '%s': '%d dBm'\n",
+ qmi_device_get_path_display (ctx->device),
+ qmi_nas_radio_interface_get_string (radio_interface),
+ strength);
+
+ /* Other signal strengths in other networks... */
+ if (qmi_message_nas_get_signal_strength_output_get_strength_list (output, &array, NULL)) {
+ guint i;
+
+ g_print ("Other:\n");
+ for (i = 0; i < array->len; i++) {
+ QmiMessageNasGetSignalStrengthOutputStrengthListElement *element;
+
+ element = &g_array_index (array, QmiMessageNasGetSignalStrengthOutputStrengthListElement, i);
+ g_print ("\tNetwork '%s': '%d dBm'\n",
+ qmi_nas_radio_interface_get_string (element->radio_interface),
+ element->strength);
+ }
+ }
+
+ /* RSSI... */
+ if (qmi_message_nas_get_signal_strength_output_get_rssi_list (output, &array, NULL)) {
+ guint i;
+
+ g_print ("RSSI:\n");
+ for (i = 0; i < array->len; i++) {
+ QmiMessageNasGetSignalStrengthOutputRssiListElement *element;
+
+ element = &g_array_index (array, QmiMessageNasGetSignalStrengthOutputRssiListElement, i);
+ g_print ("\tNetwork '%s': '%d dBm'\n",
+ qmi_nas_radio_interface_get_string (element->radio_interface),
+ (-1) * element->rssi);
+ }
+ }
+
+ /* ECIO... */
+ if (qmi_message_nas_get_signal_strength_output_get_ecio_list (output, &array, NULL)) {
+ guint i;
+
+ g_print ("ECIO:\n");
+ for (i = 0; i < array->len; i++) {
+ QmiMessageNasGetSignalStrengthOutputEcioListElement *element;
+
+ element = &g_array_index (array, QmiMessageNasGetSignalStrengthOutputEcioListElement, i);
+ g_print ("\tNetwork '%s': '%.1lf dBm'\n",
+ qmi_nas_radio_interface_get_string (element->radio_interface),
+ (-0.5) * ((gdouble)element->ecio));
+ }
+ }
+
+ /* IO... */
+ if (qmi_message_nas_get_signal_strength_output_get_io (output, &io, NULL)) {
+ g_print ("IO: '%d dBm'\n", io);
+ }
+
+ /* SINR level */
+ if (qmi_message_nas_get_signal_strength_output_get_sinr (output, &sinr_level, NULL)) {
+ g_print ("SINR: (%u) '%.1lf dB'\n",
+ sinr_level, get_db_from_sinr_level (sinr_level));
+ }
+
+ /* RSRQ */
+ if (qmi_message_nas_get_signal_strength_output_get_rsrq (output, &rsrq, &radio_interface, NULL)) {
+ g_print ("RSRQ:\n"
+ "\tNetwork '%s': '%d dB'\n",
+ qmi_nas_radio_interface_get_string (radio_interface),
+ rsrq);
+ }
+
+ /* LTE SNR */
+ if (qmi_message_nas_get_signal_strength_output_get_lte_snr (output, &snr, NULL)) {
+ g_print ("SNR:\n"
+ "\tNetwork '%s': '%.1lf dB'\n",
+ qmi_nas_radio_interface_get_string (QMI_NAS_RADIO_INTERFACE_LTE),
+ (0.1) * ((gdouble)snr));
+ }
+
+ /* LTE RSRP */
+ if (qmi_message_nas_get_signal_strength_output_get_lte_rsrp (output, &rsrp, NULL)) {
+ g_print ("RSRP:\n"
+ "\tNetwork '%s': '%d dBm'\n",
+ qmi_nas_radio_interface_get_string (QMI_NAS_RADIO_INTERFACE_LTE),
+ rsrp);
+ }
+
+ /* Just skip others for now */
+
+ qmi_message_nas_get_signal_strength_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_tx_rx_info_ready (QmiClientNas *client,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ QmiNasRadioInterface interface;
+ QmiMessageNasGetTxRxInfoOutput *output;
+ GError *error = NULL;
+ gboolean is_radio_tuned;
+ gboolean is_in_traffic;
+ gint32 power;
+ gint32 ecio;
+ gint32 rscp;
+ gint32 rsrp;
+ guint32 phase;
+
+ interface = GPOINTER_TO_UINT (user_data);
+
+ output = qmi_client_nas_get_tx_rx_info_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_nas_get_tx_rx_info_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get TX/RX info: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_nas_get_tx_rx_info_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully got TX/RX info\n",
+ qmi_device_get_path_display (ctx->device));
+
+ /* RX Channel 0 */
+ if (qmi_message_nas_get_tx_rx_info_output_get_rx_chain_0_info (
+ output,
+ &is_radio_tuned,
+ &power,
+ &ecio,
+ &rscp,
+ &rsrp,
+ &phase,
+ NULL)) {
+ g_print ("RX Chain 0:\n"
+ "\tRadio tuned: '%s'\n"
+ "\tPower: '%.1lf dBm'\n",
+ is_radio_tuned ? "yes" : "no",
+ (0.1) * ((gdouble)power));
+ if (interface == QMI_NAS_RADIO_INTERFACE_CDMA_1X ||
+ interface == QMI_NAS_RADIO_INTERFACE_CDMA_1XEVDO ||
+ interface == QMI_NAS_RADIO_INTERFACE_GSM ||
+ interface == QMI_NAS_RADIO_INTERFACE_UMTS ||
+ interface == QMI_NAS_RADIO_INTERFACE_LTE)
+ g_print ("\tECIO: '%.1lf dB'\n", (0.1) * ((gdouble)ecio));
+
+ if (interface == QMI_NAS_RADIO_INTERFACE_UMTS)
+ g_print ("\tRSCP: '%.1lf dBm'\n", (0.1) * ((gdouble)rscp));
+
+ if (interface == QMI_NAS_RADIO_INTERFACE_LTE)
+ g_print ("\tRSRP: '%.1lf dBm'\n", (0.1) * ((gdouble)rsrp));
+
+ if (interface == QMI_NAS_RADIO_INTERFACE_LTE) {
+ if (phase == 0xFFFFFFFF)
+ g_print ("\tPhase: 'unknown'\n");
+ else
+ g_print ("\tPhase: '%.2lf degrees'\n", (0.01) * ((gdouble)phase));
+ }
+ }
+
+ /* RX Channel 1 */
+ if (qmi_message_nas_get_tx_rx_info_output_get_rx_chain_1_info (
+ output,
+ &is_radio_tuned,
+ &power,
+ &ecio,
+ &rscp,
+ &rsrp,
+ &phase,
+ NULL)) {
+ g_print ("RX Chain 1:\n"
+ "\tRadio tuned: '%s'\n"
+ "\tPower: '%.1lf dBm'\n",
+ is_radio_tuned ? "yes" : "no",
+ (0.1) * ((gdouble)power));
+ if (interface == QMI_NAS_RADIO_INTERFACE_CDMA_1X ||
+ interface == QMI_NAS_RADIO_INTERFACE_CDMA_1XEVDO ||
+ interface == QMI_NAS_RADIO_INTERFACE_GSM ||
+ interface == QMI_NAS_RADIO_INTERFACE_UMTS ||
+ interface == QMI_NAS_RADIO_INTERFACE_LTE)
+ g_print ("\tECIO: '%.1lf dB'\n", (0.1) * ((gdouble)ecio));
+
+ if (interface == QMI_NAS_RADIO_INTERFACE_UMTS)
+ g_print ("\tRSCP: '%.1lf dBm'\n", (0.1) * ((gdouble)rscp));
+
+ if (interface == QMI_NAS_RADIO_INTERFACE_LTE)
+ g_print ("\tRSRP: '%.1lf dBm'\n", (0.1) * ((gdouble)rsrp));
+
+ if (interface == QMI_NAS_RADIO_INTERFACE_LTE) {
+ if (phase == 0xFFFFFFFF)
+ g_print ("\tPhase: 'unknown'\n");
+ else
+ g_print ("\tPhase: '%.2lf degrees'\n", (0.01) * ((gdouble)phase));
+ }
+ }
+
+ /* TX Channel */
+ if (qmi_message_nas_get_tx_rx_info_output_get_tx_info (
+ output,
+ &is_in_traffic,
+ &power,
+ NULL)) {
+ g_print ("TX:\n");
+ if (is_in_traffic)
+ g_print ("\tIn traffic: 'yes'\n"
+ "\tPower: '%.1lf dBm'\n",
+ (0.1) * ((gdouble)power));
+ else
+ g_print ("\tIn traffic: 'no'\n");
+ }
+
+ qmi_message_nas_get_tx_rx_info_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageNasGetTxRxInfoInput *
+get_tx_rx_info_input_create (const gchar *str,
+ QmiNasRadioInterface *interface)
+{
+ QmiMessageNasGetTxRxInfoInput *input = NULL;
+
+ g_assert (interface != NULL);
+
+ if (qmicli_read_radio_interface_from_string (str, interface)) {
+ GError *error = NULL;
+
+ input = qmi_message_nas_get_tx_rx_info_input_new ();
+ if (!qmi_message_nas_get_tx_rx_info_input_set_radio_interface (
+ input,
+ *interface,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_nas_get_tx_rx_info_input_unref (input);
+ input = NULL;
+ }
+ }
+
+ return input;
+}
+
+static void
+get_home_network_ready (QmiClientNas *client,
+ GAsyncResult *res)
+{
+ QmiMessageNasGetHomeNetworkOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_nas_get_home_network_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_nas_get_home_network_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get home network: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_nas_get_home_network_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully got home network:\n",
+ qmi_device_get_path_display (ctx->device));
+
+ {
+ guint16 mcc;
+ guint16 mnc;
+ const gchar *description;
+
+ qmi_message_nas_get_home_network_output_get_home_network (
+ output,
+ &mcc,
+ &mnc,
+ &description,
+ NULL);
+
+ g_print ("\tHome network:\n"
+ "\t\tMCC: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tMNC: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tDescription: '%s'\n",
+ mcc,
+ mnc,
+ description);
+ }
+
+ {
+ guint16 sid;
+ guint16 nid;
+
+ if (qmi_message_nas_get_home_network_output_get_home_system_id (
+ output,
+ &sid,
+ &nid,
+ NULL)) {
+ g_print ("\t\tSID: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tNID: '%" G_GUINT16_FORMAT"'\n",
+ sid,
+ nid);
+ }
+ }
+
+ {
+ guint16 mcc;
+ guint16 mnc;
+
+ if (qmi_message_nas_get_home_network_output_get_home_network_3gpp2 (
+ output,
+ &mcc,
+ &mnc,
+ NULL, /* display_description */
+ NULL, /* description_encoding */
+ NULL, /* description */
+ NULL)) {
+ g_print ("\t3GPP2 Home network (extended):\n"
+ "\t\tMCC: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tMNC: '%" G_GUINT16_FORMAT"'\n",
+ mcc,
+ mnc);
+
+ /* TODO: convert description to UTF-8 and display */
+ }
+ }
+
+ qmi_message_nas_get_home_network_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_serving_system_ready (QmiClientNas *client,
+ GAsyncResult *res)
+{
+ QmiMessageNasGetServingSystemOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_nas_get_serving_system_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_nas_get_serving_system_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get serving system: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_nas_get_serving_system_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully got serving system:\n",
+ qmi_device_get_path_display (ctx->device));
+
+ {
+ QmiNasRegistrationState registration_state;
+ QmiNasAttachState cs_attach_state;
+ QmiNasAttachState ps_attach_state;
+ QmiNasNetworkType selected_network;
+ GArray *radio_interfaces;
+ guint i;
+
+ qmi_message_nas_get_serving_system_output_get_serving_system (
+ output,
+ &registration_state,
+ &cs_attach_state,
+ &ps_attach_state,
+ &selected_network,
+ &radio_interfaces,
+ NULL);
+
+ g_print ("\tRegistration state: '%s'\n"
+ "\tCS: '%s'\n"
+ "\tPS: '%s'\n"
+ "\tSelected network: '%s'\n"
+ "\tRadio interfaces: '%u'\n",
+ qmi_nas_registration_state_get_string (registration_state),
+ qmi_nas_attach_state_get_string (cs_attach_state),
+ qmi_nas_attach_state_get_string (ps_attach_state),
+ qmi_nas_network_type_get_string (selected_network),
+ radio_interfaces->len);
+
+ for (i = 0; i < radio_interfaces->len; i++) {
+ QmiNasRadioInterface iface;
+
+ iface = g_array_index (radio_interfaces, QmiNasRadioInterface, i);
+ g_print ("\t\t[%u]: '%s'\n", i, qmi_nas_radio_interface_get_string (iface));
+ }
+ }
+
+ {
+ QmiNasRoamingIndicatorStatus roaming;
+
+ if (qmi_message_nas_get_serving_system_output_get_roaming_indicator (
+ output,
+ &roaming,
+ NULL)) {
+ g_print ("\tRoaming status: '%s'\n",
+ qmi_nas_roaming_indicator_status_get_string (roaming));
+ }
+ }
+
+ {
+ GArray *data_service_capability;
+
+ if (qmi_message_nas_get_serving_system_output_get_data_service_capability (
+ output,
+ &data_service_capability,
+ NULL)) {
+ guint i;
+
+ g_print ("\tData service capabilities: '%u'\n",
+ data_service_capability->len);
+
+ for (i = 0; i < data_service_capability->len; i++) {
+ QmiNasDataCapability cap;
+
+ cap = g_array_index (data_service_capability, QmiNasDataCapability, i);
+ g_print ("\t\t[%u]: '%s'\n", i, qmi_nas_data_capability_get_string (cap));
+ }
+ }
+ }
+
+ {
+ guint16 current_plmn_mcc;
+ guint16 current_plmn_mnc;
+ const gchar *current_plmn_description;
+
+ if (qmi_message_nas_get_serving_system_output_get_current_plmn (
+ output,
+ &current_plmn_mcc,
+ &current_plmn_mnc,
+ &current_plmn_description,
+ NULL)) {
+ g_print ("\tCurrent PLMN:\n"
+ "\t\tMCC: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tMNC: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tDescription: '%s'\n",
+ current_plmn_mcc,
+ current_plmn_mnc,
+ current_plmn_description);
+ }
+ }
+
+ {
+ guint16 sid;
+ guint16 nid;
+
+ if (qmi_message_nas_get_serving_system_output_get_cdma_system_id (
+ output,
+ &sid,
+ &nid,
+ NULL)) {
+ g_print ("\tCDMA System ID:\n"
+ "\t\tSID: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tNID: '%" G_GUINT16_FORMAT"'\n",
+ sid, nid);
+ }
+ }
+
+ {
+ guint16 id;
+ gint32 latitude;
+ gint32 longitude;
+
+ if (qmi_message_nas_get_serving_system_output_get_cdma_base_station_info (
+ output,
+ &id,
+ &latitude,
+ &longitude,
+ NULL)) {
+ gdouble latitude_degrees;
+ gdouble longitude_degrees;
+
+ /* TODO: give degrees, minutes, seconds */
+ latitude_degrees = ((gdouble)latitude * 0.25)/3600.0;
+ longitude_degrees = ((gdouble)longitude * 0.25)/3600.0;
+
+ g_print ("\tCDMA Base station info:\n"
+ "\t\tBase station ID: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tLatitude: '%lf'º\n"
+ "\t\tLongitude: '%lf'º\n",
+ id, latitude_degrees, longitude_degrees);
+ }
+ }
+
+ {
+ GArray *roaming_indicators;
+
+ if (qmi_message_nas_get_serving_system_output_get_roaming_indicator_list (
+ output,
+ &roaming_indicators,
+ NULL)) {
+ guint i;
+
+ g_print ("\tRoaming indicators: '%u'\n",
+ roaming_indicators->len);
+
+ for (i = 0; i < roaming_indicators->len; i++) {
+ QmiMessageNasGetServingSystemOutputRoamingIndicatorListElement *element;
+
+ element = &g_array_index (roaming_indicators, QmiMessageNasGetServingSystemOutputRoamingIndicatorListElement, i);
+ g_print ("\t\t[%u]: '%s' (%s)\n",
+ i,
+ qmi_nas_roaming_indicator_status_get_string (element->roaming_indicator),
+ qmi_nas_radio_interface_get_string (element->radio_interface));
+ }
+ }
+ }
+
+ {
+ QmiNasRoamingIndicatorStatus roaming;
+
+ if (qmi_message_nas_get_serving_system_output_get_default_roaming_indicator (
+ output,
+ &roaming,
+ NULL)) {
+ g_print ("\tDefault roaming status: '%s'\n",
+ qmi_nas_roaming_indicator_status_get_string (roaming));
+ }
+ }
+
+ {
+ guint8 leap_seconds;
+ gint8 local_time_offset;
+ gboolean daylight_saving_time;
+
+ if (qmi_message_nas_get_serving_system_output_get_time_zone_3gpp2 (
+ output,
+ &leap_seconds,
+ &local_time_offset,
+ &daylight_saving_time,
+ NULL)) {
+ g_print ("\t3GPP2 time zone:\n"
+ "\t\tLeap seconds: '%u' seconds\n"
+ "\t\tLocal time offset: '%d' minutes\n"
+ "\t\tDaylight saving time: '%s'\n",
+ leap_seconds,
+ (gint)local_time_offset * 30,
+ daylight_saving_time ? "yes" : "no");
+ }
+ }
+
+ {
+ guint8 cdma_p_rev;
+
+ if (qmi_message_nas_get_serving_system_output_get_cdma_p_rev (
+ output,
+ &cdma_p_rev,
+ NULL)) {
+ g_print ("\tCDMA P_Rev: '%u'\n", cdma_p_rev);
+ }
+ }
+
+ {
+ gint8 time_zone;
+
+ if (qmi_message_nas_get_serving_system_output_get_time_zone_3gpp (
+ output,
+ &time_zone,
+ NULL)) {
+ g_print ("\t3GPP time zone offset: '%d' minutes\n",
+ (gint)time_zone * 15);
+ }
+ }
+
+ {
+ guint8 adjustment;
+
+ if (qmi_message_nas_get_serving_system_output_get_daylight_saving_time_adjustment_3gpp (
+ output,
+ &adjustment,
+ NULL)) {
+ g_print ("\t3GPP daylight saving time adjustment: '%u' hours\n",
+ adjustment);
+ }
+ }
+
+ {
+ guint16 lac;
+
+ if (qmi_message_nas_get_serving_system_output_get_lac_3gpp (
+ output,
+ &lac,
+ NULL)) {
+ g_print ("\t3GPP location area code: '%" G_GUINT16_FORMAT"'\n", lac);
+ }
+ }
+
+ {
+ guint32 cid;
+
+ if (qmi_message_nas_get_serving_system_output_get_cid_3gpp (
+ output,
+ &cid,
+ NULL)) {
+ g_print ("\t3GPP cell ID: '%u'\n", cid);
+ }
+ }
+
+ {
+ gboolean concurrent;
+
+ if (qmi_message_nas_get_serving_system_output_get_concurrent_service_info_3gpp2 (
+ output,
+ &concurrent,
+ NULL)) {
+ g_print ("\t3GPP2 concurrent service info: '%s'\n",
+ concurrent ? "available" : "not available");
+ }
+ }
+
+ {
+ gboolean prl;
+
+ if (qmi_message_nas_get_serving_system_output_get_prl_indicator_3gpp2 (
+ output,
+ &prl,
+ NULL)) {
+ g_print ("\t3GPP2 PRL indicator: '%s'\n",
+ prl ? "system in PRL" : "system not in PRL");
+ }
+ }
+
+ {
+ gboolean supported;
+
+ if (qmi_message_nas_get_serving_system_output_get_dtm_support (
+ output,
+ &supported,
+ NULL)) {
+ g_print ("\tDual transfer mode: '%s'\n",
+ supported ? "supported" : "not supported");
+ }
+ }
+
+ {
+ QmiNasServiceStatus status;
+ QmiNasNetworkServiceDomain capability;
+ QmiNasServiceStatus hdr_status;
+ gboolean hdr_hybrid;
+ gboolean forbidden;
+
+ if (qmi_message_nas_get_serving_system_output_get_detailed_service_status (
+ output,
+ &status,
+ &capability,
+ &hdr_status,
+ &hdr_hybrid,
+ &forbidden,
+ NULL)) {
+ g_print ("\tDetailed status:\n"
+ "\t\tStatus: '%s'\n"
+ "\t\tCapability: '%s'\n"
+ "\t\tHDR Status: '%s'\n"
+ "\t\tHDR Hybrid: '%s'\n"
+ "\t\tForbidden: '%s'\n",
+ qmi_nas_service_status_get_string (status),
+ qmi_nas_network_service_domain_get_string (capability),
+ qmi_nas_service_status_get_string (hdr_status),
+ hdr_hybrid ? "yes" : "no",
+ forbidden ? "yes" : "no");
+ }
+ }
+
+ {
+ guint16 mcc;
+ guint8 imsi_11_12;
+
+ if (qmi_message_nas_get_serving_system_output_get_cdma_system_info (
+ output,
+ &mcc,
+ &imsi_11_12,
+ NULL)) {
+ g_print ("\tCDMA system info:\n"
+ "\t\tMCC: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tIMSI_11_12: '%u'\n",
+ mcc,
+ imsi_11_12);
+ }
+ }
+
+ {
+ QmiNasHdrPersonality personality;
+
+ if (qmi_message_nas_get_serving_system_output_get_hdr_personality (
+ output,
+ &personality,
+ NULL)) {
+ g_print ("\tHDR personality: '%s'\n",
+ qmi_nas_hdr_personality_get_string (personality));
+ }
+ }
+
+ {
+ guint16 tac;
+
+ if (qmi_message_nas_get_serving_system_output_get_lte_tac (
+ output,
+ &tac,
+ NULL)) {
+ g_print ("\tLTE tracking area code: '%" G_GUINT16_FORMAT"'\n", tac);
+ }
+ }
+
+ {
+ QmiNasCallBarringStatus cs_status;
+ QmiNasCallBarringStatus ps_status;
+
+ if (qmi_message_nas_get_serving_system_output_get_call_barring_status (
+ output,
+ &cs_status,
+ &ps_status,
+ NULL)) {
+ g_print ("\tCall barring status:\n"
+ "\t\tCircuit switched: '%s'\n"
+ "\t\tPacket switched: '%s'\n",
+ qmi_nas_call_barring_status_get_string (cs_status),
+ qmi_nas_call_barring_status_get_string (ps_status));
+ }
+ }
+
+ {
+ guint16 code;
+
+ if (qmi_message_nas_get_serving_system_output_get_umts_primary_scrambling_code (
+ output,
+ &code,
+ NULL)) {
+ g_print ("\tUMTS primary scrambling code: '%" G_GUINT16_FORMAT"'\n", code);
+ }
+ }
+
+ {
+ guint16 mcc;
+ guint16 mnc;
+ gboolean has_pcs_digit;
+
+ if (qmi_message_nas_get_serving_system_output_get_mnc_pcs_digit_include_status (
+ output,
+ &mcc,
+ &mnc,
+ &has_pcs_digit,
+ NULL)) {
+ g_print ("\tFull operator code info:\n"
+ "\t\tMCC: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tMNC: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tMNC with PCS digit: '%s'\n",
+ mcc,
+ mnc,
+ has_pcs_digit ? "yes" : "no");
+ }
+ }
+
+ qmi_message_nas_get_serving_system_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_system_info_ready (QmiClientNas *client,
+ GAsyncResult *res)
+{
+ QmiMessageNasGetSystemInfoOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_nas_get_system_info_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_nas_get_system_info_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get system info: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_nas_get_system_info_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully got system info:\n",
+ qmi_device_get_path_display (ctx->device));
+
+ /* CDMA 1x */
+ {
+ QmiNasServiceStatus service_status;
+ gboolean preferred_data_path;
+ gboolean domain_valid;
+ QmiNasNetworkServiceDomain domain;
+ gboolean service_capability_valid;
+ QmiNasNetworkServiceDomain service_capability;
+ gboolean roaming_status_valid;
+ QmiNasRoamingStatus roaming_status;
+ gboolean forbidden_valid;
+ gboolean forbidden;
+ gboolean prl_match_valid;
+ gboolean prl_match;
+ gboolean p_rev_valid;
+ guint8 p_rev;
+ gboolean base_station_p_rev_valid;
+ guint8 base_station_p_rev;
+ gboolean concurrent_service_support_valid;
+ gboolean concurrent_service_support;
+ gboolean cdma_system_id_valid;
+ guint16 sid;
+ guint16 nid;
+ gboolean base_station_info_valid;
+ guint16 base_station_id;
+ gint32 base_station_latitude;
+ gint32 base_station_longitude;
+ gboolean packet_zone_valid;
+ guint16 packet_zone;
+ gboolean network_id_valid;
+ const gchar *mcc;
+ const gchar *mnc;
+ guint16 geo_system_index;
+ guint16 registration_period;
+
+ if (qmi_message_nas_get_system_info_output_get_cdma_service_status (
+ output,
+ &service_status,
+ &preferred_data_path,
+ NULL)) {
+ g_print ("\tCDMA 1x service:\n"
+ "\t\tStatus: '%s'\n"
+ "\t\tPreferred data path: '%s'\n",
+ qmi_nas_service_status_get_string (service_status),
+ preferred_data_path ? "yes" : "no");
+
+ if (qmi_message_nas_get_system_info_output_get_cdma_system_info (
+ output,
+ &domain_valid, &domain,
+ &service_capability_valid, &service_capability,
+ &roaming_status_valid, &roaming_status,
+ &forbidden_valid, &forbidden,
+ &prl_match_valid, &prl_match,
+ &p_rev_valid, &p_rev,
+ &base_station_p_rev_valid, &base_station_p_rev,
+ &concurrent_service_support_valid, &concurrent_service_support,
+ &cdma_system_id_valid, &sid, &nid,
+ &base_station_info_valid, &base_station_id, &base_station_longitude, &base_station_latitude,
+ &packet_zone_valid, &packet_zone,
+ &network_id_valid, &mcc, &mnc,
+ NULL)) {
+ if (domain_valid)
+ g_print ("\t\tDomain: '%s'\n", qmi_nas_network_service_domain_get_string (domain));
+ if (service_capability_valid)
+ g_print ("\t\tService capability: '%s'\n", qmi_nas_network_service_domain_get_string (service_capability));
+ if (roaming_status_valid)
+ g_print ("\t\tRoaming status: '%s'\n", qmi_nas_roaming_status_get_string (roaming_status));
+ if (forbidden_valid)
+ g_print ("\t\tForbidden: '%s'\n", forbidden ? "yes" : "no");
+ if (prl_match_valid)
+ g_print ("\t\tPRL match: '%s'\n", prl_match ? "yes" : "no");
+ if (p_rev_valid)
+ g_print ("\t\tP-Rev: '%u'\n", p_rev);
+ if (base_station_p_rev_valid)
+ g_print ("\t\tBase station P-Rev: '%u'\n", base_station_p_rev);
+ if (concurrent_service_support_valid)
+ g_print ("\t\tConcurrent service support: '%s'\n", concurrent_service_support ? "yes" : "no");
+ if (cdma_system_id_valid) {
+ g_print ("\t\tSID: '%" G_GUINT16_FORMAT"'\n", sid);
+ g_print ("\t\tNID: '%" G_GUINT16_FORMAT"'\n", nid);
+ }
+ if (base_station_info_valid) {
+ gdouble latitude_degrees;
+ gdouble longitude_degrees;
+
+ /* TODO: give degrees, minutes, seconds */
+ latitude_degrees = ((gdouble)base_station_latitude * 0.25)/3600.0;
+ longitude_degrees = ((gdouble)base_station_longitude * 0.25)/3600.0;
+ g_print ("\t\tBase station ID: '%" G_GUINT16_FORMAT"'\n", base_station_id);
+ g_print ("\t\tBase station latitude: '%lf'º\n", latitude_degrees);
+ g_print ("\t\tBase station longitude: '%lf'º\n", longitude_degrees);
+ }
+ if (packet_zone_valid)
+ g_print ("\t\tPacket zone: '%" G_GUINT16_FORMAT "'\n", packet_zone);
+ if (network_id_valid) {
+ g_print ("\t\tMCC: '%s'\n", mcc);
+ if ((guchar)mnc[2] == 0xFF)
+ g_print ("\t\tMNC: '%.2s'\n", mnc);
+ else
+ g_print ("\t\tMNC: '%.3s'\n", mnc);
+ }
+ }
+
+ if (qmi_message_nas_get_system_info_output_get_additional_cdma_system_info (
+ output,
+ &geo_system_index,
+ &registration_period,
+ NULL)) {
+ if (geo_system_index != 0xFFFF)
+ g_print ("\t\tGeo system index: '%" G_GUINT16_FORMAT "'\n", geo_system_index);
+ if (registration_period != 0xFFFF)
+ g_print ("\t\tRegistration period: '%" G_GUINT16_FORMAT "'\n", registration_period);
+ }
+ }
+ }
+
+ /* CDMA 1xEV-DO */
+ {
+ QmiNasServiceStatus service_status;
+ gboolean preferred_data_path;
+ gboolean domain_valid;
+ QmiNasNetworkServiceDomain domain;
+ gboolean service_capability_valid;
+ QmiNasNetworkServiceDomain service_capability;
+ gboolean roaming_status_valid;
+ QmiNasRoamingStatus roaming_status;
+ gboolean forbidden_valid;
+ gboolean forbidden;
+ gboolean prl_match_valid;
+ gboolean prl_match;
+ gboolean personality_valid;
+ QmiNasHdrPersonality personality;
+ gboolean protocol_revision_valid;
+ QmiNasHdrProtocolRevision protocol_revision;
+ gboolean is_856_system_id_valid;
+ const gchar *is_856_system_id;
+ guint16 geo_system_index;
+
+ if (qmi_message_nas_get_system_info_output_get_hdr_service_status (
+ output,
+ &service_status,
+ &preferred_data_path,
+ NULL)) {
+ g_print ("\tCDMA 1xEV-DO (HDR) service:\n"
+ "\t\tStatus: '%s'\n"
+ "\t\tPreferred data path: '%s'\n",
+ qmi_nas_service_status_get_string (service_status),
+ preferred_data_path ? "yes" : "no");
+
+ if (qmi_message_nas_get_system_info_output_get_hdr_system_info (
+ output,
+ &domain_valid, &domain,
+ &service_capability_valid, &service_capability,
+ &roaming_status_valid, &roaming_status,
+ &forbidden_valid, &forbidden,
+ &prl_match_valid, &prl_match,
+ &personality_valid, &personality,
+ &protocol_revision_valid, &protocol_revision,
+ &is_856_system_id_valid, &is_856_system_id,
+ NULL)) {
+ if (domain_valid)
+ g_print ("\t\tDomain: '%s'\n", qmi_nas_network_service_domain_get_string (domain));
+ if (service_capability_valid)
+ g_print ("\t\tService capability: '%s'\n", qmi_nas_network_service_domain_get_string (service_capability));
+ if (roaming_status_valid)
+ g_print ("\t\tRoaming status: '%s'\n", qmi_nas_roaming_status_get_string (roaming_status));
+ if (forbidden_valid)
+ g_print ("\t\tForbidden: '%s'\n", forbidden ? "yes" : "no");
+ if (prl_match_valid)
+ g_print ("\t\tPRL match: '%s'\n", prl_match ? "yes" : "no");
+ if (personality_valid)
+ g_print ("\t\tPersonality: '%s'\n", qmi_nas_hdr_personality_get_string (personality));
+ if (protocol_revision_valid)
+ g_print ("\t\tProtocol revision: '%s'\n", qmi_nas_hdr_protocol_revision_get_string (protocol_revision));
+ if (is_856_system_id_valid)
+ g_print ("\t\tIS-856 system ID: '%s'\n", is_856_system_id);
+ }
+
+ if (qmi_message_nas_get_system_info_output_get_additional_hdr_system_info (
+ output,
+ &geo_system_index,
+ NULL)) {
+ if (geo_system_index != 0xFFFF)
+ g_print ("\t\tGeo system index: '%" G_GUINT16_FORMAT "'\n", geo_system_index);
+ }
+ }
+ }
+
+ /* GSM */
+ {
+ QmiNasServiceStatus service_status;
+ QmiNasServiceStatus true_service_status;
+ gboolean preferred_data_path;
+ gboolean domain_valid;
+ QmiNasNetworkServiceDomain domain;
+ gboolean service_capability_valid;
+ QmiNasNetworkServiceDomain service_capability;
+ gboolean roaming_status_valid;
+ QmiNasRoamingStatus roaming_status;
+ gboolean forbidden_valid;
+ gboolean forbidden;
+ gboolean lac_valid;
+ guint16 lac;
+ gboolean cid_valid;
+ guint32 cid;
+ gboolean registration_reject_info_valid;
+ QmiNasNetworkServiceDomain registration_reject_domain;
+ guint8 registration_reject_cause;
+ gboolean network_id_valid;
+ const gchar *mcc;
+ const gchar *mnc;
+ gboolean egprs_support_valid;
+ gboolean egprs_support;
+ gboolean dtm_support_valid;
+ gboolean dtm_support;
+ guint16 geo_system_index;
+ QmiNasCellBroadcastCapability cell_broadcast_support;
+ QmiNasCallBarringStatus call_barring_status_cs;
+ QmiNasCallBarringStatus call_barring_status_ps;
+ QmiNasNetworkServiceDomain cipher_domain;
+
+ if (qmi_message_nas_get_system_info_output_get_gsm_service_status (
+ output,
+ &service_status,
+ &true_service_status,
+ &preferred_data_path,
+ NULL)) {
+ g_print ("\tGSM service:\n"
+ "\t\tStatus: '%s'\n"
+ "\t\tTrue Status: '%s'\n"
+ "\t\tPreferred data path: '%s'\n",
+ qmi_nas_service_status_get_string (service_status),
+ qmi_nas_service_status_get_string (true_service_status),
+ preferred_data_path ? "yes" : "no");
+
+ if (qmi_message_nas_get_system_info_output_get_gsm_system_info (
+ output,
+ &domain_valid, &domain,
+ &service_capability_valid, &service_capability,
+ &roaming_status_valid, &roaming_status,
+ &forbidden_valid, &forbidden,
+ &lac_valid, &lac,
+ &cid_valid, &cid,
+ &registration_reject_info_valid, &registration_reject_domain, &registration_reject_cause,
+ &network_id_valid, &mcc, &mnc,
+ &egprs_support_valid, &egprs_support,
+ &dtm_support_valid, &dtm_support,
+ NULL)) {
+ if (domain_valid)
+ g_print ("\t\tDomain: '%s'\n", qmi_nas_network_service_domain_get_string (domain));
+ if (service_capability_valid)
+ g_print ("\t\tService capability: '%s'\n", qmi_nas_network_service_domain_get_string (service_capability));
+ if (roaming_status_valid)
+ g_print ("\t\tRoaming status: '%s'\n", qmi_nas_roaming_status_get_string (roaming_status));
+ if (forbidden_valid)
+ g_print ("\t\tForbidden: '%s'\n", forbidden ? "yes" : "no");
+ if (lac_valid)
+ g_print ("\t\tLocation Area Code: '%" G_GUINT16_FORMAT"'\n", lac);
+ if (cid_valid)
+ g_print ("\t\tCell ID: '%u'\n", cid);
+ if (registration_reject_info_valid)
+ g_print ("\t\tRegistration reject: '%s' (%u)\n",
+ qmi_nas_network_service_domain_get_string (registration_reject_domain),
+ registration_reject_cause);
+ if (network_id_valid) {
+ g_print ("\t\tMCC: '%s'\n", mcc);
+ if ((guchar)mnc[2] == 0xFF)
+ g_print ("\t\tMNC: '%.2s'\n", mnc);
+ else
+ g_print ("\t\tMNC: '%.3s'\n", mnc);
+ }
+ if (egprs_support_valid)
+ g_print ("\t\tE-GPRS supported: '%s'\n", egprs_support ? "yes" : "no");
+ if (dtm_support_valid)
+ g_print ("\t\tDual Transfer Mode supported: '%s'\n", dtm_support ? "yes" : "no");
+ }
+
+ if (qmi_message_nas_get_system_info_output_get_additional_gsm_system_info (
+ output,
+ &geo_system_index,
+ &cell_broadcast_support,
+ NULL)) {
+ if (geo_system_index != 0xFFFF)
+ g_print ("\t\tGeo system index: '%" G_GUINT16_FORMAT "'\n", geo_system_index);
+ g_print ("\t\tCell broadcast support: '%s'\n", qmi_nas_cell_broadcast_capability_get_string (cell_broadcast_support));
+ }
+
+ if (qmi_message_nas_get_system_info_output_get_gsm_call_barring_status (
+ output,
+ &call_barring_status_cs,
+ &call_barring_status_ps,
+ NULL)) {
+ g_print ("\t\tCall barring status (CS): '%s'\n", qmi_nas_call_barring_status_get_string (call_barring_status_cs));
+ g_print ("\t\tCall barring status (PS): '%s'\n", qmi_nas_call_barring_status_get_string (call_barring_status_ps));
+ }
+
+ if (qmi_message_nas_get_system_info_output_get_gsm_cipher_domain (
+ output,
+ &cipher_domain,
+ NULL)) {
+ g_print ("\t\tCipher Domain: '%s'\n", qmi_nas_network_service_domain_get_string (cipher_domain));
+ }
+ }
+ }
+
+ /* WCDMA */
+ {
+ QmiNasServiceStatus service_status;
+ QmiNasServiceStatus true_service_status;
+ gboolean preferred_data_path;
+ gboolean domain_valid;
+ QmiNasNetworkServiceDomain domain;
+ gboolean service_capability_valid;
+ QmiNasNetworkServiceDomain service_capability;
+ gboolean roaming_status_valid;
+ QmiNasRoamingStatus roaming_status;
+ gboolean forbidden_valid;
+ gboolean forbidden;
+ gboolean lac_valid;
+ guint16 lac;
+ gboolean cid_valid;
+ guint32 cid;
+ gboolean registration_reject_info_valid;
+ QmiNasNetworkServiceDomain registration_reject_domain;
+ guint8 registration_reject_cause;
+ gboolean network_id_valid;
+ const gchar *mcc;
+ const gchar *mnc;
+ gboolean hs_call_status_valid;
+ QmiNasWcdmaHsService hs_call_status;
+ gboolean hs_service_valid;
+ QmiNasWcdmaHsService hs_service;
+ gboolean primary_scrambling_code_valid;
+ guint16 primary_scrambling_code;
+ guint16 geo_system_index;
+ QmiNasCellBroadcastCapability cell_broadcast_support;
+ QmiNasCallBarringStatus call_barring_status_cs;
+ QmiNasCallBarringStatus call_barring_status_ps;
+ QmiNasNetworkServiceDomain cipher_domain;
+
+ if (qmi_message_nas_get_system_info_output_get_wcdma_service_status (
+ output,
+ &service_status,
+ &true_service_status,
+ &preferred_data_path,
+ NULL)) {
+ g_print ("\tWCDMA service:\n"
+ "\t\tStatus: '%s'\n"
+ "\t\tTrue Status: '%s'\n"
+ "\t\tPreferred data path: '%s'\n",
+ qmi_nas_service_status_get_string (service_status),
+ qmi_nas_service_status_get_string (true_service_status),
+ preferred_data_path ? "yes" : "no");
+
+ if (qmi_message_nas_get_system_info_output_get_wcdma_system_info (
+ output,
+ &domain_valid, &domain,
+ &service_capability_valid, &service_capability,
+ &roaming_status_valid, &roaming_status,
+ &forbidden_valid, &forbidden,
+ &lac_valid, &lac,
+ &cid_valid, &cid,
+ &registration_reject_info_valid, &registration_reject_domain, &registration_reject_cause,
+ &network_id_valid, &mcc, &mnc,
+ &hs_call_status_valid, &hs_call_status,
+ &hs_service_valid, &hs_service,
+ &primary_scrambling_code_valid, &primary_scrambling_code,
+ NULL)) {
+ if (domain_valid)
+ g_print ("\t\tDomain: '%s'\n", qmi_nas_network_service_domain_get_string (domain));
+ if (service_capability_valid)
+ g_print ("\t\tService capability: '%s'\n", qmi_nas_network_service_domain_get_string (service_capability));
+ if (roaming_status_valid)
+ g_print ("\t\tRoaming status: '%s'\n", qmi_nas_roaming_status_get_string (roaming_status));
+ if (forbidden_valid)
+ g_print ("\t\tForbidden: '%s'\n", forbidden ? "yes" : "no");
+ if (lac_valid)
+ g_print ("\t\tLocation Area Code: '%" G_GUINT16_FORMAT"'\n", lac);
+ if (cid_valid)
+ g_print ("\t\tCell ID: '%u'\n", cid);
+ if (registration_reject_info_valid)
+ g_print ("\t\tRegistration reject: '%s' (%u)\n",
+ qmi_nas_network_service_domain_get_string (registration_reject_domain),
+ registration_reject_cause);
+ if (network_id_valid) {
+ g_print ("\t\tMCC: '%s'\n", mcc);
+ if ((guchar)mnc[2] == 0xFF)
+ g_print ("\t\tMNC: '%.2s'\n", mnc);
+ else
+ g_print ("\t\tMNC: '%.3s'\n", mnc);
+ }
+ if (hs_call_status_valid)
+ g_print ("\t\tHS call status: '%s'\n", qmi_nas_wcdma_hs_service_get_string (hs_call_status));
+ if (hs_service_valid)
+ g_print ("\t\tHS service: '%s'\n", qmi_nas_wcdma_hs_service_get_string (hs_service));
+ if (primary_scrambling_code_valid)
+ g_print ("\t\tPrimary scrambling code: '%" G_GUINT16_FORMAT"'\n", primary_scrambling_code);
+ }
+
+ if (qmi_message_nas_get_system_info_output_get_additional_wcdma_system_info (
+ output,
+ &geo_system_index,
+ &cell_broadcast_support,
+ NULL)) {
+ if (geo_system_index != 0xFFFF)
+ g_print ("\t\tGeo system index: '%" G_GUINT16_FORMAT "'\n", geo_system_index);
+ g_print ("\t\tCell broadcast support: '%s'\n", qmi_nas_cell_broadcast_capability_get_string (cell_broadcast_support));
+ }
+
+ if (qmi_message_nas_get_system_info_output_get_wcdma_call_barring_status (
+ output,
+ &call_barring_status_cs,
+ &call_barring_status_ps,
+ NULL)) {
+ g_print ("\t\tCall barring status (CS): '%s'\n", qmi_nas_call_barring_status_get_string (call_barring_status_cs));
+ g_print ("\t\tCall barring status (PS): '%s'\n", qmi_nas_call_barring_status_get_string (call_barring_status_ps));
+ }
+
+ if (qmi_message_nas_get_system_info_output_get_wcdma_cipher_domain (
+ output,
+ &cipher_domain,
+ NULL)) {
+ g_print ("\t\tCipher Domain: '%s'\n", qmi_nas_network_service_domain_get_string (cipher_domain));
+ }
+ }
+ }
+
+ /* LTE */
+ {
+ QmiNasServiceStatus service_status;
+ QmiNasServiceStatus true_service_status;
+ gboolean preferred_data_path;
+ gboolean domain_valid;
+ QmiNasNetworkServiceDomain domain;
+ gboolean service_capability_valid;
+ QmiNasNetworkServiceDomain service_capability;
+ gboolean roaming_status_valid;
+ QmiNasRoamingStatus roaming_status;
+ gboolean forbidden_valid;
+ gboolean forbidden;
+ gboolean lac_valid;
+ guint16 lac;
+ gboolean cid_valid;
+ guint32 cid;
+ gboolean registration_reject_info_valid;
+ QmiNasNetworkServiceDomain registration_reject_domain;
+ guint8 registration_reject_cause;
+ gboolean network_id_valid;
+ const gchar *mcc;
+ const gchar *mnc;
+ gboolean tac_valid;
+ guint16 tac;
+ guint16 geo_system_index;
+ gboolean voice_support;
+ gboolean embms_coverage_info_support;
+
+ if (qmi_message_nas_get_system_info_output_get_lte_service_status (
+ output,
+ &service_status,
+ &true_service_status,
+ &preferred_data_path,
+ NULL)) {
+ g_print ("\tLTE service:\n"
+ "\t\tStatus: '%s'\n"
+ "\t\tTrue Status: '%s'\n"
+ "\t\tPreferred data path: '%s'\n",
+ qmi_nas_service_status_get_string (service_status),
+ qmi_nas_service_status_get_string (true_service_status),
+ preferred_data_path ? "yes" : "no");
+
+ if (qmi_message_nas_get_system_info_output_get_lte_system_info (
+ output,
+ &domain_valid, &domain,
+ &service_capability_valid, &service_capability,
+ &roaming_status_valid, &roaming_status,
+ &forbidden_valid, &forbidden,
+ &lac_valid, &lac,
+ &cid_valid, &cid,
+ &registration_reject_info_valid,&registration_reject_domain,&registration_reject_cause,
+ &network_id_valid, &mcc, &mnc,
+ &tac_valid, &tac,
+ NULL)) {
+ if (domain_valid)
+ g_print ("\t\tDomain: '%s'\n", qmi_nas_network_service_domain_get_string (domain));
+ if (service_capability_valid)
+ g_print ("\t\tService capability: '%s'\n", qmi_nas_network_service_domain_get_string (service_capability));
+ if (roaming_status_valid)
+ g_print ("\t\tRoaming status: '%s'\n", qmi_nas_roaming_status_get_string (roaming_status));
+ if (forbidden_valid)
+ g_print ("\t\tForbidden: '%s'\n", forbidden ? "yes" : "no");
+ if (lac_valid)
+ g_print ("\t\tLocation Area Code: '%" G_GUINT16_FORMAT"'\n", lac);
+ if (cid_valid)
+ g_print ("\t\tCell ID: '%u'\n", cid);
+ if (registration_reject_info_valid)
+ g_print ("\t\tRegistration reject: '%s' (%u)\n",
+ qmi_nas_network_service_domain_get_string (registration_reject_domain),
+ registration_reject_cause);
+ if (network_id_valid) {
+ g_print ("\t\tMCC: '%s'\n", mcc);
+ if ((guchar)mnc[2] == 0xFF)
+ g_print ("\t\tMNC: '%.2s'\n", mnc);
+ else
+ g_print ("\t\tMNC: '%.3s'\n", mnc);
+ }
+ if (tac_valid)
+ g_print ("\t\tTracking Area Code: '%" G_GUINT16_FORMAT"'\n", tac);
+ }
+
+ if (qmi_message_nas_get_system_info_output_get_additional_lte_system_info (
+ output,
+ &geo_system_index,
+ NULL)) {
+ if (geo_system_index != 0xFFFF)
+ g_print ("\t\tGeo system index: '%" G_GUINT16_FORMAT "'\n", geo_system_index);
+ }
+
+ if (qmi_message_nas_get_system_info_output_get_lte_voice_support (
+ output,
+ &voice_support,
+ NULL)) {
+ g_print ("\t\tVoice support: '%s'\n", voice_support ? "yes" : "no");
+ }
+
+ if (qmi_message_nas_get_system_info_output_get_lte_embms_coverage_info_support (
+ output,
+ &embms_coverage_info_support,
+ NULL)) {
+ g_print ("\t\teMBMS coverage info support: '%s'\n", embms_coverage_info_support ? "yes" : "no");
+ }
+ }
+ }
+
+ /* TD-SCDMA */
+ {
+ QmiNasServiceStatus service_status;
+ QmiNasServiceStatus true_service_status;
+ gboolean preferred_data_path;
+ gboolean domain_valid;
+ QmiNasNetworkServiceDomain domain;
+ gboolean service_capability_valid;
+ QmiNasNetworkServiceDomain service_capability;
+ gboolean roaming_status_valid;
+ QmiNasRoamingStatus roaming_status;
+ gboolean forbidden_valid;
+ gboolean forbidden;
+ gboolean lac_valid;
+ guint16 lac;
+ gboolean cid_valid;
+ guint32 cid;
+ gboolean registration_reject_info_valid;
+ QmiNasNetworkServiceDomain registration_reject_domain;
+ guint8 registration_reject_cause;
+ gboolean network_id_valid;
+ const gchar *mcc;
+ const gchar *mnc;
+ gboolean hs_call_status_valid;
+ QmiNasWcdmaHsService hs_call_status;
+ gboolean hs_service_valid;
+ QmiNasWcdmaHsService hs_service;
+ gboolean cell_parameter_id_valid;
+ guint16 cell_parameter_id;
+ gboolean cell_broadcast_support_valid;
+ QmiNasCellBroadcastCapability cell_broadcast_support;
+ gboolean call_barring_status_cs_valid;
+ QmiNasCallBarringStatus call_barring_status_cs;
+ gboolean call_barring_status_ps_valid;
+ QmiNasCallBarringStatus call_barring_status_ps;
+ gboolean cipher_domain_valid;
+ QmiNasNetworkServiceDomain cipher_domain;
+
+ if (qmi_message_nas_get_system_info_output_get_td_scdma_service_status (
+ output,
+ &service_status,
+ &true_service_status,
+ &preferred_data_path,
+ NULL)) {
+ g_print ("\tTD-SCDMA service:\n"
+ "\t\tStatus: '%s'\n"
+ "\t\tTrue Status: '%s'\n"
+ "\t\tPreferred data path: '%s'\n",
+ qmi_nas_service_status_get_string (service_status),
+ qmi_nas_service_status_get_string (true_service_status),
+ preferred_data_path ? "yes" : "no");
+
+ if (qmi_message_nas_get_system_info_output_get_td_scdma_system_info (
+ output,
+ &domain_valid, &domain,
+ &service_capability_valid, &service_capability,
+ &roaming_status_valid, &roaming_status,
+ &forbidden_valid, &forbidden,
+ &lac_valid, &lac,
+ &cid_valid, &cid,
+ &registration_reject_info_valid, &registration_reject_domain, &registration_reject_cause,
+ &network_id_valid, &mcc, &mnc,
+ &hs_call_status_valid, &hs_call_status,
+ &hs_service_valid, &hs_service,
+ &cell_parameter_id_valid, &cell_parameter_id,
+ &cell_broadcast_support_valid, &cell_broadcast_support,
+ &call_barring_status_cs_valid, &call_barring_status_cs,
+ &call_barring_status_ps_valid, &call_barring_status_ps,
+ &cipher_domain_valid, &cipher_domain,
+ NULL)) {
+ if (domain_valid)
+ g_print ("\t\tDomain: '%s'\n", qmi_nas_network_service_domain_get_string (domain));
+ if (service_capability_valid)
+ g_print ("\t\tService capability: '%s'\n", qmi_nas_network_service_domain_get_string (service_capability));
+ if (roaming_status_valid)
+ g_print ("\t\tRoaming status: '%s'\n", qmi_nas_roaming_status_get_string (roaming_status));
+ if (forbidden_valid)
+ g_print ("\t\tForbidden: '%s'\n", forbidden ? "yes" : "no");
+ if (lac_valid)
+ g_print ("\t\tLocation Area Code: '%" G_GUINT16_FORMAT"'\n", lac);
+ if (cid_valid)
+ g_print ("\t\tCell ID: '%u'\n", cid);
+ if (registration_reject_info_valid)
+ g_print ("\t\tRegistration reject: '%s' (%u)\n",
+ qmi_nas_network_service_domain_get_string (registration_reject_domain),
+ registration_reject_cause);
+ if (network_id_valid) {
+ g_print ("\t\tMCC: '%s'\n", mcc);
+ if ((guchar)mnc[2] == 0xFF)
+ g_print ("\t\tMNC: '%.2s'\n", mnc);
+ else
+ g_print ("\t\tMNC: '%.3s'\n", mnc);
+ }
+ if (hs_call_status_valid)
+ g_print ("\t\tHS call status: '%s'\n", qmi_nas_wcdma_hs_service_get_string (hs_call_status));
+ if (hs_service_valid)
+ g_print ("\t\tHS service: '%s'\n", qmi_nas_wcdma_hs_service_get_string (hs_service));
+ if (cell_parameter_id_valid)
+ g_print ("\t\tCell parameter ID: '%" G_GUINT16_FORMAT"'\n", cell_parameter_id);
+ if (cell_broadcast_support_valid)
+ g_print ("\t\tCell broadcast support: '%s'\n", qmi_nas_cell_broadcast_capability_get_string (cell_broadcast_support));
+ if (call_barring_status_cs_valid)
+ g_print ("\t\tCall barring status (CS): '%s'\n", qmi_nas_call_barring_status_get_string (call_barring_status_cs));
+ if (call_barring_status_ps_valid)
+ g_print ("\t\tCall barring status (PS): '%s'\n", qmi_nas_call_barring_status_get_string (call_barring_status_ps));
+ if (cipher_domain_valid)
+ g_print ("\t\tCipher Domain: '%s'\n", qmi_nas_network_service_domain_get_string (cipher_domain));
+ }
+ }
+
+ /* Common */
+ {
+ QmiNasSimRejectState sim_reject_info;
+
+ if (qmi_message_nas_get_system_info_output_get_sim_reject_info (
+ output,
+ &sim_reject_info,
+ NULL)) {
+ g_print ("\tSIM reject info: '%s'\n", qmi_nas_sim_reject_state_get_string (sim_reject_info));
+ }
+ }
+ }
+
+ qmi_message_nas_get_system_info_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_technology_preference_ready (QmiClientNas *client,
+ GAsyncResult *res)
+{
+ QmiMessageNasGetTechnologyPreferenceOutput *output;
+ GError *error = NULL;
+ QmiNasRadioTechnologyPreference preference;
+ QmiNasPreferenceDuration duration;
+ gchar *preference_string;
+
+ output = qmi_client_nas_get_technology_preference_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_nas_get_technology_preference_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get technology preference: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_nas_get_technology_preference_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_nas_get_technology_preference_output_get_active (
+ output,
+ &preference,
+ &duration,
+ NULL);
+
+ preference_string = qmi_nas_radio_technology_preference_build_string_from_mask (preference);
+ g_print ("[%s] Successfully got technology preference\n"
+ "\tActive: '%s', duration: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ preference_string,
+ qmi_nas_preference_duration_get_string (duration));
+ g_free (preference_string);
+
+ if (qmi_message_nas_get_technology_preference_output_get_persistent (
+ output,
+ &preference,
+ NULL)) {
+ preference_string = qmi_nas_radio_technology_preference_build_string_from_mask (preference);
+ g_print ("\tPersistent: '%s'\n",
+ preference_string);
+ g_free (preference_string);
+ }
+
+ qmi_message_nas_get_technology_preference_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_system_selection_preference_ready (QmiClientNas *client,
+ GAsyncResult *res)
+{
+ QmiMessageNasGetSystemSelectionPreferenceOutput *output;
+ GError *error = NULL;
+ gboolean emergency_mode;
+ QmiNasRatModePreference mode_preference;
+ QmiNasBandPreference band_preference;
+ QmiNasLteBandPreference lte_band_preference;
+ QmiNasTdScdmaBandPreference td_scdma_band_preference;
+ QmiNasCdmaPrlPreference cdma_prl_preference;
+ QmiNasRoamingPreference roaming_preference;
+ QmiNasNetworkSelectionPreference network_selection_preference;
+ QmiNasServiceDomainPreference service_domain_preference;
+ QmiNasGsmWcdmaAcquisitionOrderPreference gsm_wcdma_acquisition_order_preference;
+ guint16 mcc;
+ guint16 mnc;
+ gboolean has_pcs_digit;
+
+ output = qmi_client_nas_get_system_selection_preference_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_nas_get_system_selection_preference_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get system_selection preference: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_nas_get_system_selection_preference_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully got system selection preference\n",
+ qmi_device_get_path_display (ctx->device));
+
+ if (qmi_message_nas_get_system_selection_preference_output_get_emergency_mode (
+ output,
+ &emergency_mode,
+ NULL)) {
+ g_print ("\tEmergency mode: '%s'\n",
+ emergency_mode ? "yes" : "no");
+ }
+
+ if (qmi_message_nas_get_system_selection_preference_output_get_mode_preference (
+ output,
+ &mode_preference,
+ NULL)) {
+ gchar *str;
+
+ str = qmi_nas_rat_mode_preference_build_string_from_mask (mode_preference);
+ g_print ("\tMode preference: '%s'\n", str);
+ g_free (str);
+ }
+
+ if (qmi_message_nas_get_system_selection_preference_output_get_band_preference (
+ output,
+ &band_preference,
+ NULL)) {
+ gchar *str;
+
+ str = qmi_nas_band_preference_build_string_from_mask (band_preference);
+ g_print ("\tBand preference: '%s'\n", str);
+ g_free (str);
+ }
+
+ if (qmi_message_nas_get_system_selection_preference_output_get_lte_band_preference (
+ output,
+ &lte_band_preference,
+ NULL)) {
+ gchar *str;
+
+ str = qmi_nas_lte_band_preference_build_string_from_mask (lte_band_preference);
+ g_print ("\tLTE band preference: '%s'\n", str);
+ g_free (str);
+ }
+
+ if (qmi_message_nas_get_system_selection_preference_output_get_td_scdma_band_preference (
+ output,
+ &td_scdma_band_preference,
+ NULL)) {
+ gchar *str;
+
+ str = qmi_nas_td_scdma_band_preference_build_string_from_mask (td_scdma_band_preference);
+ g_print ("\tTD-SCDMA band preference: '%s'\n", str);
+ g_free (str);
+ }
+
+ if (qmi_message_nas_get_system_selection_preference_output_get_cdma_prl_preference (
+ output,
+ &cdma_prl_preference,
+ NULL)) {
+ g_print ("\tCDMA PRL preference: '%s'\n",
+ qmi_nas_cdma_prl_preference_get_string (cdma_prl_preference));
+ }
+
+ if (qmi_message_nas_get_system_selection_preference_output_get_roaming_preference (
+ output,
+ &roaming_preference,
+ NULL)) {
+ g_print ("\tRoaming preference: '%s'\n",
+ qmi_nas_roaming_preference_get_string (roaming_preference));
+ }
+
+ if (qmi_message_nas_get_system_selection_preference_output_get_network_selection_preference (
+ output,
+ &network_selection_preference,
+ NULL)) {
+ g_print ("\tNetwork selection preference: '%s'\n",
+ qmi_nas_network_selection_preference_get_string (network_selection_preference));
+ }
+
+
+ if (qmi_message_nas_get_system_selection_preference_output_get_service_domain_preference (
+ output,
+ &service_domain_preference,
+ NULL)) {
+ g_print ("\tService domain preference: '%s'\n",
+ qmi_nas_service_domain_preference_get_string (service_domain_preference));
+ }
+
+ if (qmi_message_nas_get_system_selection_preference_output_get_gsm_wcdma_acquisition_order_preference (
+ output,
+ &gsm_wcdma_acquisition_order_preference,
+ NULL)) {
+ g_print ("\tService selection preference: '%s'\n",
+ qmi_nas_gsm_wcdma_acquisition_order_preference_get_string (gsm_wcdma_acquisition_order_preference));
+ }
+
+ if (qmi_message_nas_get_system_selection_preference_output_get_manual_network_selection (
+ output,
+ &mcc,
+ &mnc,
+ &has_pcs_digit,
+ NULL)) {
+ g_print ("\tManual network selection:\n"
+ "\t\tMCC: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tMNC: '%" G_GUINT16_FORMAT"'\n"
+ "\t\tMCC with PCS digit: '%s'\n",
+ mcc,
+ mnc,
+ has_pcs_digit ? "yes" : "no");
+ }
+
+ qmi_message_nas_get_system_selection_preference_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageNasSetSystemSelectionPreferenceInput *
+set_system_selection_preference_input_create (const gchar *str)
+{
+ QmiMessageNasSetSystemSelectionPreferenceInput *input = NULL;
+ QmiNasRatModePreference pref;
+ GError *error = NULL;
+
+ if (!qmicli_read_rat_mode_pref_from_string (str, &pref)) {
+ g_printerr ("error: failed to parse mode pref\n");
+ return NULL;
+ }
+
+ input = qmi_message_nas_set_system_selection_preference_input_new ();
+ if (!qmi_message_nas_set_system_selection_preference_input_set_mode_preference (
+ input,
+ pref,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_nas_set_system_selection_preference_input_unref (input);
+ return NULL;
+ }
+
+ if (!qmi_message_nas_set_system_selection_preference_input_set_change_duration (
+ input,
+ QMI_NAS_CHANGE_DURATION_PERMANENT,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_nas_set_system_selection_preference_input_unref (input);
+ return NULL;
+ }
+
+ if (pref & (QMI_NAS_RAT_MODE_PREFERENCE_GSM |
+ QMI_NAS_RAT_MODE_PREFERENCE_UMTS |
+ QMI_NAS_RAT_MODE_PREFERENCE_LTE)) {
+ if (!qmi_message_nas_set_system_selection_preference_input_set_gsm_wcdma_acquisition_order_preference (
+ input,
+ QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_AUTOMATIC,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n",
+ error->message);
+ g_error_free (error);
+ qmi_message_nas_set_system_selection_preference_input_unref (input);
+ return NULL;
+ }
+ }
+
+ return input;
+}
+
+static void
+set_system_selection_preference_ready (QmiClientNas *client,
+ GAsyncResult *res)
+{
+ QmiMessageNasSetSystemSelectionPreferenceOutput *output = NULL;
+ GError *error = NULL;
+
+ output = qmi_client_nas_set_system_selection_preference_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_nas_set_system_selection_preference_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't set operating mode: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_nas_set_system_selection_preference_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] System selection preference set successfully; replug your device.\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_nas_set_system_selection_preference_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+network_scan_ready (QmiClientNas *client,
+ GAsyncResult *res)
+{
+ QmiMessageNasNetworkScanOutput *output;
+ GError *error = NULL;
+ GArray *array;
+
+ output = qmi_client_nas_network_scan_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_nas_network_scan_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't scan networks: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_nas_network_scan_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully scanned networks\n",
+ qmi_device_get_path_display (ctx->device));
+
+ array = NULL;
+ if (qmi_message_nas_network_scan_output_get_network_information (output, &array, NULL)) {
+ guint i;
+
+ for (i = 0; i < array->len; i++) {
+ QmiMessageNasNetworkScanOutputNetworkInformationElement *element;
+ gchar *status_str;
+
+ element = &g_array_index (array, QmiMessageNasNetworkScanOutputNetworkInformationElement, i);
+ status_str = qmi_nas_network_status_build_string_from_mask (element->network_status);
+ g_print ("Network [%u]:\n"
+ "\tMCC: '%" G_GUINT16_FORMAT"'\n"
+ "\tMNC: '%" G_GUINT16_FORMAT"'\n"
+ "\tStatus: '%s'\n"
+ "\tDescription: '%s'\n",
+ i,
+ element->mcc,
+ element->mnc,
+ status_str,
+ element->description);
+ g_free (status_str);
+ }
+ }
+
+ array = NULL;
+ if (qmi_message_nas_network_scan_output_get_radio_access_technology (output, &array, NULL)) {
+ guint i;
+
+ for (i = 0; i < array->len; i++) {
+ QmiMessageNasNetworkScanOutputRadioAccessTechnologyElement *element;
+
+ element = &g_array_index (array, QmiMessageNasNetworkScanOutputRadioAccessTechnologyElement, i);
+ g_print ("Network [%u]:\n"
+ "\tMCC: '%" G_GUINT16_FORMAT"'\n"
+ "\tMNC: '%" G_GUINT16_FORMAT"'\n"
+ "\tRAT: '%s'\n",
+ i,
+ element->mcc,
+ element->mnc,
+ qmi_nas_radio_interface_get_string (element->radio_interface));
+ }
+ }
+
+ array = NULL;
+ if (qmi_message_nas_network_scan_output_get_mnc_pcs_digit_include_status (output, &array, NULL)) {
+ guint i;
+
+ for (i = 0; i < array->len; i++) {
+ QmiMessageNasNetworkScanOutputMncPcsDigitIncludeStatusElement *element;
+
+ element = &g_array_index (array, QmiMessageNasNetworkScanOutputMncPcsDigitIncludeStatusElement, i);
+ g_print ("Network [%u]:\n"
+ "\tMCC: '%" G_GUINT16_FORMAT"'\n"
+ "\tMNC: '%" G_GUINT16_FORMAT"'\n"
+ "\tMCC with PCS digit: '%s'\n",
+ i,
+ element->mcc,
+ element->mnc,
+ element->includes_pcs_digit ? "yes" : "no");
+ }
+ }
+
+ qmi_message_nas_network_scan_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+reset_ready (QmiClientNas *client,
+ GAsyncResult *res)
+{
+ QmiMessageNasResetOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_nas_reset_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_nas_reset_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't reset the NAS service: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_nas_reset_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully performed NAS service reset\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_nas_reset_output_unref (output);
+ shutdown (TRUE);
+}
+
+static gboolean
+noop_cb (gpointer unused)
+{
+ shutdown (TRUE);
+ return FALSE;
+}
+
+void
+qmicli_nas_run (QmiDevice *device,
+ QmiClientNas *client,
+ GCancellable *cancellable)
+{
+ /* Initialize context */
+ ctx = g_slice_new (Context);
+ ctx->device = g_object_ref (device);
+ ctx->client = g_object_ref (client);
+ if (cancellable)
+ ctx->cancellable = g_object_ref (cancellable);
+
+ /* Request to get signal strength? */
+ if (get_signal_strength_flag) {
+ QmiMessageNasGetSignalStrengthInput *input;
+
+ input = get_signal_strength_input_create ();
+
+ g_debug ("Asynchronously getting signal strength...");
+ qmi_client_nas_get_signal_strength (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_signal_strength_ready,
+ NULL);
+ qmi_message_nas_get_signal_strength_input_unref (input);
+ return;
+ }
+
+ /* Request to get signal info? */
+ if (get_signal_info_flag) {
+ g_debug ("Asynchronously getting signal info...");
+ qmi_client_nas_get_signal_info (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_signal_info_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get tx/rx info? */
+ if (get_tx_rx_info_str) {
+ QmiMessageNasGetTxRxInfoInput *input;
+ QmiNasRadioInterface interface;
+
+ input = get_tx_rx_info_input_create (get_tx_rx_info_str,
+ &interface);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+
+ g_debug ("Asynchronously getting TX/RX info...");
+ qmi_client_nas_get_tx_rx_info (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_tx_rx_info_ready,
+ GUINT_TO_POINTER (interface));
+ qmi_message_nas_get_tx_rx_info_input_unref (input);
+ return;
+ }
+
+ /* Request to get home network? */
+ if (get_home_network_flag) {
+ g_debug ("Asynchronously getting home network...");
+ qmi_client_nas_get_home_network (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_home_network_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get serving system? */
+ if (get_serving_system_flag) {
+ g_debug ("Asynchronously getting serving system...");
+ qmi_client_nas_get_serving_system (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_serving_system_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get system info? */
+ if (get_system_info_flag) {
+ g_debug ("Asynchronously getting system info...");
+ qmi_client_nas_get_system_info (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_system_info_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get technology preference? */
+ if (get_technology_preference_flag) {
+ g_debug ("Asynchronously getting technology preference...");
+ qmi_client_nas_get_technology_preference (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_technology_preference_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get system_selection preference? */
+ if (get_system_selection_preference_flag) {
+ g_debug ("Asynchronously getting system selection preference...");
+ qmi_client_nas_get_system_selection_preference (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_system_selection_preference_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to set system_selection preference? */
+ if (set_system_selection_preference_str) {
+ QmiMessageNasSetSystemSelectionPreferenceInput *input;
+ g_debug ("Asynchronously setting system selection preference...");
+
+ input = set_system_selection_preference_input_create (set_system_selection_preference_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_client_nas_set_system_selection_preference (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)set_system_selection_preference_ready,
+ NULL);
+ qmi_message_nas_set_system_selection_preference_input_unref (input);
+ return;
+ }
+
+ /* Request to scan networks? */
+ if (network_scan_flag) {
+ g_debug ("Asynchronously scanning networks...");
+ qmi_client_nas_network_scan (ctx->client,
+ NULL,
+ 300, /* this operation takes a lot of time! */
+ ctx->cancellable,
+ (GAsyncReadyCallback)network_scan_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to reset NAS service? */
+ if (reset_flag) {
+ g_debug ("Asynchronously resetting NAS service...");
+ qmi_client_nas_reset (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)reset_ready,
+ NULL);
+ return;
+ }
+
+ /* Just client allocate/release? */
+ if (noop_flag) {
+ g_idle_add (noop_cb, NULL);
+ return;
+ }
+
+ g_warn_if_reached ();
+}
diff --git a/src/qmicli/qmicli-pbm.c b/src/qmicli/qmicli-pbm.c
new file mode 100644
index 0000000..ca36068
--- /dev/null
+++ b/src/qmicli/qmicli-pbm.c
@@ -0,0 +1,312 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * qmicli -- Command line interface to control QMI devices
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2013 Aleksander Morgado <aleksander@gnu.org>
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <libqmi-glib.h>
+
+#include "qmicli.h"
+
+/* Context */
+typedef struct {
+ QmiDevice *device;
+ QmiClientPbm *client;
+ GCancellable *cancellable;
+} Context;
+static Context *ctx;
+
+/* Options */
+static gboolean get_all_capabilities_flag;
+static gboolean noop_flag;
+
+static GOptionEntry entries[] = {
+ { "pbm-get-all-capabilities", 0, 0, G_OPTION_ARG_NONE, &get_all_capabilities_flag,
+ "Get all phonebook capabilities",
+ NULL
+ },
+ { "pbm-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
+ "Just allocate or release a PBM client. Use with `--client-no-release-cid' and/or `--client-cid'",
+ NULL
+ },
+ { NULL }
+};
+
+GOptionGroup *
+qmicli_pbm_get_option_group (void)
+{
+ GOptionGroup *group;
+
+ group = g_option_group_new ("pbm",
+ "PBM options",
+ "Show Phonebook Management options",
+ NULL,
+ NULL);
+ g_option_group_add_entries (group, entries);
+
+ return group;
+}
+
+gboolean
+qmicli_pbm_options_enabled (void)
+{
+ static guint n_actions = 0;
+ static gboolean checked = FALSE;
+
+ if (checked)
+ return !!n_actions;
+
+ n_actions = (get_all_capabilities_flag +
+ noop_flag);
+
+ if (n_actions > 1) {
+ g_printerr ("error: too many PBM actions requested\n");
+ exit (EXIT_FAILURE);
+ }
+
+ checked = TRUE;
+ return !!n_actions;
+}
+
+static void
+context_free (Context *context)
+{
+ if (!context)
+ return;
+
+ if (context->client)
+ g_object_unref (context->client);
+ g_object_unref (context->cancellable);
+ g_object_unref (context->device);
+ g_slice_free (Context, context);
+}
+
+static void
+shutdown (gboolean operation_status)
+{
+ /* Cleanup context and finish async operation */
+ context_free (ctx);
+ qmicli_async_operation_done (operation_status);
+}
+
+static void
+get_all_capabilities_ready (QmiClientPbm *client,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+ QmiMessagePbmGetAllCapabilitiesOutput *output;
+ GArray *array = NULL;
+ guint i, j;
+
+ output = qmi_client_pbm_get_all_capabilities_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n",
+ error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_pbm_get_all_capabilities_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get capabilities: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_pbm_get_all_capabilities_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Phonebook capabilities:\n",
+ qmi_device_get_path_display (ctx->device));
+
+ if (qmi_message_pbm_get_all_capabilities_output_get_capability_basic_information (output, &array, NULL)) {
+ g_print ("Capability basic information:\n");
+ for (i = 0; i < array->len; i++) {
+ QmiMessagePbmGetAllCapabilitiesOutputCapabilityBasicInformationElement *session;
+
+ session = &g_array_index (array,
+ QmiMessagePbmGetAllCapabilitiesOutputCapabilityBasicInformationElement,
+ i);
+ g_print ("\t[%s]:\n", qmi_pbm_session_type_get_string (session->session_type));
+ for (j = 0; j < session->phonebooks->len; j++) {
+ QmiMessagePbmGetAllCapabilitiesOutputCapabilityBasicInformationElementPhonebooksElement *phonebook;
+ gchar *phonebook_type_str;
+
+ phonebook = &g_array_index (session->phonebooks,
+ QmiMessagePbmGetAllCapabilitiesOutputCapabilityBasicInformationElementPhonebooksElement,
+ j);
+ phonebook_type_str = qmi_pbm_phonebook_type_build_string_from_mask (phonebook->phonebook_type);
+ g_print ("\t\t[%s]:\n", phonebook_type_str);
+ g_print ("\t\t\tUsed records: %" G_GUINT16_FORMAT "\n", phonebook->used_records);
+ g_print ("\t\t\tMaximum records: %" G_GUINT16_FORMAT "\n", phonebook->maximum_records);
+ g_print ("\t\t\tMaximum number length: %u\n", phonebook->maximum_number_length);
+ g_print ("\t\t\tMaximum name length: %u\n", phonebook->maximum_name_length);
+ g_free (phonebook_type_str);
+ }
+ }
+ }
+
+ if (qmi_message_pbm_get_all_capabilities_output_get_group_capability (output, &array, NULL)) {
+ g_print ("Group capability:\n");
+ for (i = 0; i < array->len; i++) {
+ QmiMessagePbmGetAllCapabilitiesOutputGroupCapabilityElement *session;
+
+ session = &g_array_index (array,
+ QmiMessagePbmGetAllCapabilitiesOutputGroupCapabilityElement,
+ i);
+ g_print ("\t[%s]:\n", qmi_pbm_session_type_get_string (session->session_type));
+ g_print ("\t\tMaximum groups: %u\n", session->maximum_groups);
+ g_print ("\t\tMaximum group tag length: %u\n", session->maximum_group_tag_length);
+ }
+ }
+
+ if (qmi_message_pbm_get_all_capabilities_output_get_additional_number_capability (output, &array, NULL)) {
+ g_print ("Additional number capability:\n");
+ for (i = 0; i < array->len; i++) {
+ QmiMessagePbmGetAllCapabilitiesOutputAdditionalNumberCapabilityElement *session;
+
+ session = &g_array_index (array,
+ QmiMessagePbmGetAllCapabilitiesOutputAdditionalNumberCapabilityElement,
+ i);
+ g_print ("\t[%s]:\n", qmi_pbm_session_type_get_string (session->session_type));
+ g_print ("\t\tMaximum additional numbers: %u\n", session->maximum_additional_numbers);
+ g_print ("\t\tMaximum additional number length: %u\n", session->maximum_additional_number_length);
+ g_print ("\t\tMaximum additional number tag length: %u\n", session->maximum_additional_number_tag_length);
+ }
+ }
+
+ if (qmi_message_pbm_get_all_capabilities_output_get_email_capability (output, &array, NULL)) {
+ g_print ("Email capability:\n");
+ for (i = 0; i < array->len; i++) {
+ QmiMessagePbmGetAllCapabilitiesOutputEmailCapabilityElement *session;
+
+ session = &g_array_index (array,
+ QmiMessagePbmGetAllCapabilitiesOutputEmailCapabilityElement,
+ i);
+ g_print ("\t[%s]:\n", qmi_pbm_session_type_get_string (session->session_type));
+ g_print ("\t\tMaximum emails: %u\n", session->maximum_emails);
+ g_print ("\t\tMaximum email address length: %u\n", session->maximum_email_address_length);
+ }
+ }
+
+ if (qmi_message_pbm_get_all_capabilities_output_get_second_name_capability (output, &array, NULL)) {
+ g_print ("Second name capability:\n");
+ for (i = 0; i < array->len; i++) {
+ QmiMessagePbmGetAllCapabilitiesOutputSecondNameCapabilityElement *session;
+
+ session = &g_array_index (array,
+ QmiMessagePbmGetAllCapabilitiesOutputSecondNameCapabilityElement,
+ i);
+ g_print ("\t[%s]:\n", qmi_pbm_session_type_get_string (session->session_type));
+ g_print ("\t\tMaximum second name length: %u\n", session->maximum_second_name_length);
+ }
+ }
+
+ if (qmi_message_pbm_get_all_capabilities_output_get_hidden_records_capability (output, &array, NULL)) {
+ g_print ("Hidden records capability:\n");
+ for (i = 0; i < array->len; i++) {
+ QmiMessagePbmGetAllCapabilitiesOutputHiddenRecordsCapabilityElement *session;
+
+ session = &g_array_index (array,
+ QmiMessagePbmGetAllCapabilitiesOutputHiddenRecordsCapabilityElement,
+ i);
+ g_print ("\t[%s]:\n", qmi_pbm_session_type_get_string (session->session_type));
+ g_print ("\t\tSupported: %s\n", session->supported ? "yes" : "no");
+ }
+ }
+
+ if (qmi_message_pbm_get_all_capabilities_output_get_grouping_information_alpha_string_capability (output, &array, NULL)) {
+ g_print ("Alpha string capability:\n");
+ for (i = 0; i < array->len; i++) {
+ QmiMessagePbmGetAllCapabilitiesOutputGroupingInformationAlphaStringCapabilityElement *session;
+
+ session = &g_array_index (array,
+ QmiMessagePbmGetAllCapabilitiesOutputGroupingInformationAlphaStringCapabilityElement,
+ i);
+ g_print ("\t[%s]:\n", qmi_pbm_session_type_get_string (session->session_type));
+ g_print ("\t\tMaximum records: %u\n", session->maximum_records);
+ g_print ("\t\tUsed records: %u\n", session->used_records);
+ g_print ("\t\tMaximum string length: %u\n", session->maximum_string_length);
+ }
+ }
+
+ if (qmi_message_pbm_get_all_capabilities_output_get_additional_number_alpha_string_capability (output, &array, NULL)) {
+ g_print ("Additional number alpha string capability:\n");
+ for (i = 0; i < array->len; i++) {
+ QmiMessagePbmGetAllCapabilitiesOutputAdditionalNumberAlphaStringCapabilityElement *session;
+
+ session = &g_array_index (array,
+ QmiMessagePbmGetAllCapabilitiesOutputAdditionalNumberAlphaStringCapabilityElement,
+ i);
+ g_print ("\t[%s]:\n", qmi_pbm_session_type_get_string (session->session_type));
+ g_print ("\t\tMaximum records: %u\n", session->maximum_records);
+ g_print ("\t\tUsed records: %u\n", session->used_records);
+ g_print ("\t\tMaximum string length: %u\n", session->maximum_string_length);
+ }
+ }
+
+ qmi_message_pbm_get_all_capabilities_output_unref (output);
+ shutdown (TRUE);
+}
+
+static gboolean
+noop_cb (gpointer unused)
+{
+ shutdown (TRUE);
+ return FALSE;
+}
+
+void
+qmicli_pbm_run (QmiDevice *device,
+ QmiClientPbm *client,
+ GCancellable *cancellable)
+{
+ /* Initialize context */
+ ctx = g_slice_new (Context);
+ ctx->device = g_object_ref (device);
+ ctx->client = g_object_ref (client);
+ ctx->cancellable = g_object_ref (cancellable);
+
+ /* Request to get all capabilities? */
+ if (get_all_capabilities_flag) {
+ g_debug ("Asynchronously getting phonebook capabilities...");
+ qmi_client_pbm_get_all_capabilities (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_all_capabilities_ready,
+ NULL);
+ return;
+ }
+
+ /* Just client allocate/release? */
+ if (noop_flag) {
+ g_idle_add (noop_cb, NULL);
+ return;
+ }
+
+ g_warn_if_reached ();
+}
diff --git a/src/qmicli/qmicli-uim.c b/src/qmicli/qmicli-uim.c
new file mode 100644
index 0000000..ffe9366
--- /dev/null
+++ b/src/qmicli/qmicli-uim.c
@@ -0,0 +1,556 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * qmicli -- Command line interface to control QMI devices
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <libqmi-glib.h>
+
+#include "qmicli.h"
+#include "qmicli-helpers.h"
+
+/* Context */
+typedef struct {
+ QmiDevice *device;
+ QmiClientUim *client;
+ GCancellable *cancellable;
+} Context;
+static Context *ctx;
+
+/* Options */
+static gchar *read_transparent_str;
+static gchar *get_file_attributes_str;
+static gboolean reset_flag;
+static gboolean noop_flag;
+
+static GOptionEntry entries[] = {
+ { "uim-read-transparent", 0, 0, G_OPTION_ARG_STRING, &read_transparent_str,
+ "Read a transparent file given the file path",
+ "[0xNNNN,0xNNNN,...]"
+ },
+ { "uim-get-file-attributes", 0, 0, G_OPTION_ARG_STRING, &get_file_attributes_str,
+ "Get the attributes of a given file",
+ "[0xNNNN,0xNNNN,...]"
+ },
+ { "uim-reset", 0, 0, G_OPTION_ARG_NONE, &reset_flag,
+ "Reset the service state",
+ NULL
+ },
+ { "uim-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
+ "Just allocate or release a UIM client. Use with `--client-no-release-cid' and/or `--client-cid'",
+ NULL
+ },
+ { NULL }
+};
+
+GOptionGroup *
+qmicli_uim_get_option_group (void)
+{
+ GOptionGroup *group;
+
+ group = g_option_group_new ("uim",
+ "UIM options",
+ "Show User Identity Module options",
+ NULL,
+ NULL);
+ g_option_group_add_entries (group, entries);
+
+ return group;
+}
+
+gboolean
+qmicli_uim_options_enabled (void)
+{
+ static guint n_actions = 0;
+ static gboolean checked = FALSE;
+
+ if (checked)
+ return !!n_actions;
+
+ n_actions = (!!read_transparent_str +
+ !!get_file_attributes_str +
+ reset_flag +
+ noop_flag);
+
+ if (n_actions > 1) {
+ g_printerr ("error: too many UIM actions requested\n");
+ exit (EXIT_FAILURE);
+ }
+
+ checked = TRUE;
+ return !!n_actions;
+}
+
+static void
+context_free (Context *context)
+{
+ if (!context)
+ return;
+
+ if (context->client)
+ g_object_unref (context->client);
+ g_object_unref (context->cancellable);
+ g_object_unref (context->device);
+ g_slice_free (Context, context);
+}
+
+static void
+shutdown (gboolean operation_status)
+{
+ /* Cleanup context and finish async operation */
+ context_free (ctx);
+ qmicli_async_operation_done (operation_status);
+}
+
+static void
+reset_ready (QmiClientUim *client,
+ GAsyncResult *res)
+{
+ QmiMessageUimResetOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_uim_reset_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_uim_reset_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't reset the UIM service: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_uim_reset_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully performed UIM service reset\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_uim_reset_output_unref (output);
+ shutdown (TRUE);
+}
+
+static gboolean
+noop_cb (gpointer unused)
+{
+ shutdown (TRUE);
+ return FALSE;
+}
+
+static gboolean
+get_sim_file_id_and_path (const gchar *file_path_str,
+ guint16 *file_id,
+ GArray **file_path)
+{
+ guint i;
+ gchar **split;
+
+ split = g_strsplit (file_path_str, ",", -1);
+ if (!split) {
+ g_printerr ("error: invalid file path given: '%s'\n", file_path_str);
+ return FALSE;
+ }
+
+ *file_path = g_array_sized_new (FALSE,
+ FALSE,
+ sizeof (guint8),
+ g_strv_length (split) - 1);
+
+ *file_id = 0;
+ for (i = 0; split[i]; i++) {
+ gulong path_item;
+
+ path_item = (strtoul (split[i], NULL, 16)) & 0xFFFF;
+
+ /* If there are more fields, this is part of the path; otherwise it's
+ * the file id */
+ if (split[i + 1]) {
+ guint8 val;
+
+ val = path_item & 0xFF;
+ g_array_append_val (*file_path, val);
+ val = (path_item >> 8) & 0xFF;
+ g_array_append_val (*file_path, val);
+ } else {
+ *file_id = path_item;
+ }
+ }
+
+ g_strfreev (split);
+
+ if (*file_id == 0) {
+ g_array_unref (*file_path);
+ g_printerr ("error: invalid file path given: '%s'\n", file_path_str);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+read_transparent_ready (QmiClientUim *client,
+ GAsyncResult *res)
+{
+ QmiMessageUimReadTransparentOutput *output;
+ GError *error = NULL;
+ guint8 sw1 = 0;
+ guint8 sw2 = 0;
+ GArray *read_result = NULL;
+
+ output = qmi_client_uim_read_transparent_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_uim_read_transparent_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't read transparent file from the UIM: %s\n", error->message);
+ g_error_free (error);
+
+ /* Card result */
+ if (qmi_message_uim_read_transparent_output_get_card_result (
+ output,
+ &sw1,
+ &sw2,
+ NULL)) {
+ g_print ("Card result:\n"
+ "\tSW1: '0x%02x'\n"
+ "\tSW2: '0x%02x'\n",
+ sw1, sw2);
+ }
+
+ qmi_message_uim_read_transparent_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully read information from the UIM:\n",
+ qmi_device_get_path_display (ctx->device));
+
+ /* Card result */
+ if (qmi_message_uim_read_transparent_output_get_card_result (
+ output,
+ &sw1,
+ &sw2,
+ NULL)) {
+ g_print ("Card result:\n"
+ "\tSW1: '0x%02x'\n"
+ "\tSW2: '0x%02x'\n",
+ sw1, sw2);
+ }
+
+ /* Read result */
+ if (qmi_message_uim_read_transparent_output_get_read_result (
+ output,
+ &read_result,
+ NULL)) {
+ gchar *str;
+
+ str = qmicli_get_raw_data_printable (read_result, 80, "\t");
+ g_print ("Read result:\n"
+ "%s\n",
+ str);
+ g_free (str);
+ }
+
+ qmi_message_uim_read_transparent_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageUimReadTransparentInput *
+read_transparent_build_input (const gchar *file_path_str)
+{
+ QmiMessageUimReadTransparentInput *input;
+ guint16 file_id = 0;
+ GArray *file_path = NULL;
+
+ if (!get_sim_file_id_and_path (file_path_str, &file_id, &file_path))
+ return NULL;
+
+ input = qmi_message_uim_read_transparent_input_new ();
+ qmi_message_uim_read_transparent_input_set_session_information (
+ input,
+ QMI_UIM_SESSION_TYPE_PRIMARY_GW_PROVISIONING,
+ "",
+ NULL);
+ qmi_message_uim_read_transparent_input_set_file (
+ input,
+ file_id,
+ file_path,
+ NULL);
+ qmi_message_uim_read_transparent_input_set_read_information (input, 0, 0, NULL);
+ g_array_unref (file_path);
+ return input;
+}
+
+static void
+get_file_attributes_ready (QmiClientUim *client,
+ GAsyncResult *res,
+ gchar *file_name)
+{
+ QmiMessageUimGetFileAttributesOutput *output;
+ GError *error = NULL;
+ guint8 sw1 = 0;
+ guint8 sw2 = 0;
+ guint16 file_size;
+ guint16 file_id;
+ QmiUimFileType file_type;
+ guint16 record_size;
+ guint16 record_count;
+ QmiUimSecurityAttributeLogic read_security_attributes_logic;
+ QmiUimSecurityAttribute read_security_attributes;
+ QmiUimSecurityAttributeLogic write_security_attributes_logic;
+ QmiUimSecurityAttribute write_security_attributes;
+ QmiUimSecurityAttributeLogic increase_security_attributes_logic;
+ QmiUimSecurityAttribute increase_security_attributes;
+ QmiUimSecurityAttributeLogic deactivate_security_attributes_logic;
+ QmiUimSecurityAttribute deactivate_security_attributes;
+ QmiUimSecurityAttributeLogic activate_security_attributes_logic;
+ QmiUimSecurityAttribute activate_security_attributes;
+ GArray *raw = NULL;
+
+ output = qmi_client_uim_get_file_attributes_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ g_free (file_name);
+ return;
+ }
+
+ if (!qmi_message_uim_get_file_attributes_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get '%s' file attributes from the UIM: %s\n",
+ file_name,
+ error->message);
+ g_error_free (error);
+
+ /* Card result */
+ if (qmi_message_uim_get_file_attributes_output_get_card_result (
+ output,
+ &sw1,
+ &sw2,
+ NULL)) {
+ g_print ("Card result:\n"
+ "\tSW1: '0x%02x'\n"
+ "\tSW2: '0x%02x'\n",
+ sw1, sw2);
+ }
+
+ qmi_message_uim_get_file_attributes_output_unref (output);
+ shutdown (FALSE);
+ g_free (file_name);
+ return;
+ }
+
+ g_print ("[%s] Successfully got file '%s' attributes from the UIM:\n",
+ file_name,
+ qmi_device_get_path_display (ctx->device));
+
+ /* Card result */
+ if (qmi_message_uim_get_file_attributes_output_get_card_result (
+ output,
+ &sw1,
+ &sw2,
+ NULL)) {
+ g_print ("Card result:\n"
+ "\tSW1: '0x%02x'\n"
+ "\tSW2: '0x%02x'\n",
+ sw1, sw2);
+ }
+
+ /* File attributes */
+ if (qmi_message_uim_get_file_attributes_output_get_file_attributes (
+ output,
+ &file_size,
+ &file_id,
+ &file_type,
+ &record_size,
+ &record_count,
+ &read_security_attributes_logic,
+ &read_security_attributes,
+ &write_security_attributes_logic,
+ &write_security_attributes,
+ &increase_security_attributes_logic,
+ &increase_security_attributes,
+ &deactivate_security_attributes_logic,
+ &deactivate_security_attributes,
+ &activate_security_attributes_logic,
+ &activate_security_attributes,
+ &raw,
+ NULL)) {
+ gchar *str;
+
+ g_print ("File attributes:\n");
+ g_print ("\tFile size: %u\n", (guint)file_size);
+ g_print ("\tFile ID: %u\n", (guint)file_id);
+ g_print ("\tFile type: %s\n", qmi_uim_file_type_get_string (file_type));
+ g_print ("\tRecord size: %u\n", (guint)record_size);
+ g_print ("\tRecord count: %u\n", (guint)record_count);
+
+ str = qmi_uim_security_attribute_build_string_from_mask (read_security_attributes);
+ g_print ("\tRead security attributes: (%s) %s\n",
+ qmi_uim_security_attribute_logic_get_string (read_security_attributes_logic),
+ str);
+ g_free (str);
+
+ str = qmi_uim_security_attribute_build_string_from_mask (write_security_attributes);
+ g_print ("\tWrite security attributes: (%s) %s\n",
+ qmi_uim_security_attribute_logic_get_string (write_security_attributes_logic),
+ str);
+ g_free (str);
+
+ str = qmi_uim_security_attribute_build_string_from_mask (increase_security_attributes);
+ g_print ("\tIncrease security attributes: (%s) %s\n",
+ qmi_uim_security_attribute_logic_get_string (increase_security_attributes_logic),
+ str);
+ g_free (str);
+
+ str = qmi_uim_security_attribute_build_string_from_mask (deactivate_security_attributes);
+ g_print ("\tDeactivate security attributes: (%s) %s\n",
+ qmi_uim_security_attribute_logic_get_string (deactivate_security_attributes_logic),
+ str);
+ g_free (str);
+
+ str = qmi_uim_security_attribute_build_string_from_mask (activate_security_attributes);
+ g_print ("\tActivate security attributes: (%s) %s\n",
+ qmi_uim_security_attribute_logic_get_string (activate_security_attributes_logic),
+ str);
+ g_free (str);
+
+ str = qmicli_get_raw_data_printable (raw, 80, "\t");
+ g_print ("\tRaw: %s\n", str);
+ g_free (str);
+ }
+
+ qmi_message_uim_get_file_attributes_output_unref (output);
+ shutdown (TRUE);
+}
+
+static QmiMessageUimGetFileAttributesInput *
+get_file_attributes_build_input (const gchar *file_path_str)
+{
+ QmiMessageUimGetFileAttributesInput *input;
+ guint16 file_id = 0;
+ GArray *file_path = NULL;
+
+ if (!get_sim_file_id_and_path (file_path_str, &file_id, &file_path))
+ return NULL;
+
+ input = qmi_message_uim_get_file_attributes_input_new ();
+ qmi_message_uim_get_file_attributes_input_set_session_information (
+ input,
+ QMI_UIM_SESSION_TYPE_PRIMARY_GW_PROVISIONING,
+ "",
+ NULL);
+ qmi_message_uim_get_file_attributes_input_set_file (
+ input,
+ file_id,
+ file_path,
+ NULL);
+ g_array_unref (file_path);
+ return input;
+}
+
+void
+qmicli_uim_run (QmiDevice *device,
+ QmiClientUim *client,
+ GCancellable *cancellable)
+{
+ /* Initialize context */
+ ctx = g_slice_new (Context);
+ ctx->device = g_object_ref (device);
+ ctx->client = g_object_ref (client);
+ ctx->cancellable = g_object_ref (cancellable);
+
+ /* Request to read a transparent file? */
+ if (read_transparent_str) {
+ QmiMessageUimReadTransparentInput *input;
+
+ input = read_transparent_build_input (read_transparent_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+
+ g_debug ("Asynchronously reading transparent file at '%s'...",
+ read_transparent_str);
+ qmi_client_uim_read_transparent (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)read_transparent_ready,
+ NULL);
+ qmi_message_uim_read_transparent_input_unref (input);
+ return;
+ }
+
+ /* Request to get file attributes? */
+ if (get_file_attributes_str) {
+ QmiMessageUimGetFileAttributesInput *input;
+
+ input = get_file_attributes_build_input (get_file_attributes_str);
+ if (!input) {
+ shutdown (FALSE);
+ return;
+ }
+
+ g_debug ("Asynchronously reading attributes of file '%s'...",
+ get_file_attributes_str);
+ qmi_client_uim_get_file_attributes (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_file_attributes_ready,
+ NULL);
+ qmi_message_uim_get_file_attributes_input_unref (input);
+ return;
+ }
+
+ /* Request to reset UIM service? */
+ if (reset_flag) {
+ g_debug ("Asynchronously resetting UIM service...");
+ qmi_client_uim_reset (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)reset_ready,
+ NULL);
+ return;
+ }
+
+ /* Just client allocate/release? */
+ if (noop_flag) {
+ g_idle_add (noop_cb, NULL);
+ return;
+ }
+
+ g_warn_if_reached ();
+}
diff --git a/src/qmicli/qmicli-wds.c b/src/qmicli/qmicli-wds.c
new file mode 100644
index 0000000..3abc6ab
--- /dev/null
+++ b/src/qmicli/qmicli-wds.c
@@ -0,0 +1,827 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * qmicli -- Command line interface to control QMI devices
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <libqmi-glib.h>
+
+#include "qmicli.h"
+
+/* Context */
+typedef struct {
+ QmiDevice *device;
+ QmiClientWds *client;
+ GCancellable *cancellable;
+
+ /* Helpers for the wds-start-network command */
+ gulong network_started_id;
+ guint packet_status_timeout_id;
+ guint32 packet_data_handle;
+} Context;
+static Context *ctx;
+
+/* Options */
+static gchar *start_network_str;
+static gboolean follow_network_flag;
+static gchar *stop_network_str;
+static gboolean get_packet_service_status_flag;
+static gboolean get_packet_statistics_flag;
+static gboolean get_data_bearer_technology_flag;
+static gboolean get_current_data_bearer_technology_flag;
+static gboolean reset_flag;
+static gboolean noop_flag;
+
+static GOptionEntry entries[] = {
+ { "wds-start-network", 0, 0, G_OPTION_ARG_STRING, &start_network_str,
+ "Start network (Authentication, Username and Password are optional)",
+ "[(APN),(PAP|CHAP|BOTH),(Username),(Password)]"
+ },
+ { "wds-follow-network", 0, 0, G_OPTION_ARG_NONE, &follow_network_flag,
+ "Follow the network status until disconnected. Use with `--wds-start-network'",
+ NULL
+ },
+ { "wds-stop-network", 0, 0, G_OPTION_ARG_STRING, &stop_network_str,
+ "Stop network",
+ "[Packet data handle]"
+ },
+ { "wds-get-packet-service-status", 0, 0, G_OPTION_ARG_NONE, &get_packet_service_status_flag,
+ "Get packet service status",
+ NULL
+ },
+ { "wds-get-packet-statistics", 0, 0, G_OPTION_ARG_NONE, &get_packet_statistics_flag,
+ "Get packet statistics",
+ NULL
+ },
+ { "wds-get-data-bearer-technology", 0, 0, G_OPTION_ARG_NONE, &get_data_bearer_technology_flag,
+ "Get data bearer technology",
+ NULL
+ },
+ { "wds-get-current-data-bearer-technology", 0, 0, G_OPTION_ARG_NONE, &get_current_data_bearer_technology_flag,
+ "Get current data bearer technology",
+ NULL
+ },
+ { "wds-reset", 0, 0, G_OPTION_ARG_NONE, &reset_flag,
+ "Reset the service state",
+ NULL
+ },
+ { "wds-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
+ "Just allocate or release a WDS client. Use with `--client-no-release-cid' and/or `--client-cid'",
+ NULL
+ },
+ { NULL }
+};
+
+GOptionGroup *
+qmicli_wds_get_option_group (void)
+{
+ GOptionGroup *group;
+
+ group = g_option_group_new ("wds",
+ "WDS options",
+ "Show Wireless Data Service options",
+ NULL,
+ NULL);
+ g_option_group_add_entries (group, entries);
+
+ return group;
+}
+
+gboolean
+qmicli_wds_options_enabled (void)
+{
+ static guint n_actions = 0;
+ static gboolean checked = FALSE;
+
+ if (checked)
+ return !!n_actions;
+
+ n_actions = (!!start_network_str +
+ !!stop_network_str +
+ get_packet_service_status_flag +
+ get_packet_statistics_flag +
+ get_data_bearer_technology_flag +
+ get_current_data_bearer_technology_flag +
+ reset_flag +
+ noop_flag);
+
+ if (n_actions > 1) {
+ g_printerr ("error: too many WDS actions requested\n");
+ exit (EXIT_FAILURE);
+ } else if (n_actions == 0 &&
+ follow_network_flag) {
+ g_printerr ("error: `--wds-follow-network' must be used with `--wds-start-network'\n");
+ exit (EXIT_FAILURE);
+ }
+
+ checked = TRUE;
+ return !!n_actions;
+}
+
+static void
+context_free (Context *context)
+{
+ if (!context)
+ return;
+
+ if (context->client)
+ g_object_unref (context->client);
+ if (context->network_started_id)
+ g_cancellable_disconnect (context->cancellable, context->network_started_id);
+ if (context->packet_status_timeout_id)
+ g_source_remove (context->packet_status_timeout_id);
+ g_object_unref (context->cancellable);
+ g_object_unref (context->device);
+ g_slice_free (Context, context);
+}
+
+static void
+shutdown (gboolean operation_status)
+{
+ /* Cleanup context and finish async operation */
+ context_free (ctx);
+ qmicli_async_operation_done (operation_status);
+}
+
+static void
+stop_network_ready (QmiClientWds *client,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+ QmiMessageWdsStopNetworkOutput *output;
+
+ output = qmi_client_wds_stop_network_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n",
+ error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_wds_stop_network_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't stop network: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_wds_stop_network_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ g_print ("[%s] Network stopped\n",
+ qmi_device_get_path_display (ctx->device));
+ qmi_message_wds_stop_network_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+internal_stop_network (GCancellable *cancellable,
+ guint32 packet_data_handle)
+{
+ QmiMessageWdsStopNetworkInput *input;
+
+ input = qmi_message_wds_stop_network_input_new ();
+ qmi_message_wds_stop_network_input_set_packet_data_handle (input, packet_data_handle, NULL);
+
+ g_print ("Network cancelled... releasing resources\n");
+ qmi_client_wds_stop_network (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)stop_network_ready,
+ NULL);
+ qmi_message_wds_stop_network_input_unref (input);
+}
+
+static void
+network_cancelled (GCancellable *cancellable)
+{
+ ctx->network_started_id = 0;
+
+ /* Remove the timeout right away */
+ if (ctx->packet_status_timeout_id) {
+ g_source_remove (ctx->packet_status_timeout_id);
+ ctx->packet_status_timeout_id = 0;
+ }
+
+ g_print ("Network cancelled... releasing resources\n");
+ internal_stop_network (cancellable, ctx->packet_data_handle);
+}
+
+static void
+timeout_get_packet_service_status_ready (QmiClientWds *client,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+ QmiMessageWdsGetPacketServiceStatusOutput *output;
+ QmiWdsConnectionStatus status;
+
+ output = qmi_client_wds_get_packet_service_status_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (!qmi_message_wds_get_packet_service_status_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get packet service status: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_wds_get_packet_service_status_output_unref (output);
+ return;
+ }
+
+ qmi_message_wds_get_packet_service_status_output_get_connection_status (
+ output,
+ &status,
+ NULL);
+
+ g_print ("[%s] Connection status: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ qmi_wds_connection_status_get_string (status));
+ qmi_message_wds_get_packet_service_status_output_unref (output);
+
+ /* If packet service checks detect disconnection, halt --wds-follow-network */
+ if (status != QMI_WDS_CONNECTION_STATUS_CONNECTED) {
+ g_print ("[%s] Stopping after detecting disconnection\n",
+ qmi_device_get_path_display (ctx->device));
+ internal_stop_network (NULL, ctx->packet_data_handle);
+ }
+}
+
+static gboolean
+packet_status_timeout (void)
+{
+ qmi_client_wds_get_packet_service_status (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)timeout_get_packet_service_status_ready,
+ NULL);
+
+ return TRUE;
+}
+
+static void
+start_network_ready (QmiClientWds *client,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+ QmiMessageWdsStartNetworkOutput *output;
+
+ output = qmi_client_wds_start_network_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n",
+ error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_wds_start_network_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't start network: %s\n", error->message);
+ if (g_error_matches (error,
+ QMI_PROTOCOL_ERROR,
+ QMI_PROTOCOL_ERROR_CALL_FAILED)) {
+ QmiWdsCallEndReason cer;
+ QmiWdsVerboseCallEndReasonType verbose_cer_type;
+ gint16 verbose_cer_reason;
+
+ if (qmi_message_wds_start_network_output_get_call_end_reason (
+ output,
+ &cer,
+ NULL))
+ g_printerr ("call end reason (%u): %s\n",
+ cer,
+ qmi_wds_call_end_reason_get_string (cer));
+
+ if (qmi_message_wds_start_network_output_get_verbose_call_end_reason (
+ output,
+ &verbose_cer_type,
+ &verbose_cer_reason,
+ NULL))
+ g_printerr ("verbose call end reason (%u,%d): [%s] %s\n",
+ verbose_cer_type,
+ verbose_cer_reason,
+ qmi_wds_verbose_call_end_reason_type_get_string (verbose_cer_type),
+ qmi_wds_verbose_call_end_reason_get_string (verbose_cer_type, verbose_cer_reason));
+ }
+
+ g_error_free (error);
+ qmi_message_wds_start_network_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_wds_start_network_output_get_packet_data_handle (output, &ctx->packet_data_handle, NULL);
+ qmi_message_wds_start_network_output_unref (output);
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ g_print ("[%s] Network started\n"
+ "\tPacket data handle: '%u'\n",
+ qmi_device_get_path_display (ctx->device),
+ (guint)ctx->packet_data_handle);
+
+ if (follow_network_flag) {
+ g_print ("\nCtrl+C will stop the network\n");
+ ctx->network_started_id = g_cancellable_connect (ctx->cancellable,
+ G_CALLBACK (network_cancelled),
+ NULL,
+ NULL);
+
+ ctx->packet_status_timeout_id = g_timeout_add_seconds (20,
+ (GSourceFunc)packet_status_timeout,
+ NULL);
+ return;
+ }
+
+ /* Nothing else to do */
+ shutdown (TRUE);
+}
+
+static void
+get_packet_service_status_ready (QmiClientWds *client,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+ QmiMessageWdsGetPacketServiceStatusOutput *output;
+ QmiWdsConnectionStatus status;
+
+ output = qmi_client_wds_get_packet_service_status_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n",
+ error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_wds_get_packet_service_status_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get packet service status: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_wds_get_packet_service_status_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_wds_get_packet_service_status_output_get_connection_status (
+ output,
+ &status,
+ NULL);
+
+ g_print ("[%s] Connection status: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ qmi_wds_connection_status_get_string (status));
+
+ qmi_message_wds_get_packet_service_status_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_packet_statistics_ready (QmiClientWds *client,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+ QmiMessageWdsGetPacketStatisticsOutput *output;
+ guint32 val32;
+ guint64 val64;
+
+ output = qmi_client_wds_get_packet_statistics_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n",
+ error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_wds_get_packet_statistics_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get packet statistics: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_wds_get_packet_statistics_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Connection statistics:\n",
+ qmi_device_get_path_display (ctx->device));
+
+ if (qmi_message_wds_get_packet_statistics_output_get_tx_packets_ok (output, &val32, NULL) &&
+ val32 != 0xFFFFFFFF)
+ g_print ("\tTX packets OK: %u\n", val32);
+ if (qmi_message_wds_get_packet_statistics_output_get_rx_packets_ok (output, &val32, NULL) &&
+ val32 != 0xFFFFFFFF)
+ g_print ("\tRX packets OK: %u\n", val32);
+ if (qmi_message_wds_get_packet_statistics_output_get_tx_packets_error (output, &val32, NULL) &&
+ val32 != 0xFFFFFFFF)
+ g_print ("\tTX packets error: %u\n", val32);
+ if (qmi_message_wds_get_packet_statistics_output_get_rx_packets_error (output, &val32, NULL) &&
+ val32 != 0xFFFFFFFF)
+ g_print ("\tRX packets error: %u\n", val32);
+ if (qmi_message_wds_get_packet_statistics_output_get_tx_overflows (output, &val32, NULL) &&
+ val32 != 0xFFFFFFFF)
+ g_print ("\tTX overflows: %u\n", val32);
+ if (qmi_message_wds_get_packet_statistics_output_get_rx_overflows (output, &val32, NULL) &&
+ val32 != 0xFFFFFFFF)
+ g_print ("\tRX overflows: %u\n", val32);
+ if (qmi_message_wds_get_packet_statistics_output_get_tx_packets_dropped (output, &val32, NULL) &&
+ val32 != 0xFFFFFFFF)
+ g_print ("\tTX packets dropped: %u\n", val32);
+ if (qmi_message_wds_get_packet_statistics_output_get_rx_packets_dropped (output, &val32, NULL) &&
+ val32 != 0xFFFFFFFF)
+ g_print ("\tRX packets dropped: %u\n", val32);
+
+ if (qmi_message_wds_get_packet_statistics_output_get_tx_bytes_ok (output, &val64, NULL))
+ g_print ("\tTX bytes OK: %" G_GUINT64_FORMAT "\n", val64);
+ if (qmi_message_wds_get_packet_statistics_output_get_rx_bytes_ok (output, &val64, NULL))
+ g_print ("\tRX bytes OK: %" G_GUINT64_FORMAT "\n", val64);
+ if (qmi_message_wds_get_packet_statistics_output_get_last_call_tx_bytes_ok (output, &val64, NULL))
+ g_print ("\tTX bytes OK (last): %" G_GUINT64_FORMAT "\n", val64);
+ if (qmi_message_wds_get_packet_statistics_output_get_last_call_rx_bytes_ok (output, &val64, NULL))
+ g_print ("\tRX bytes OK (last): %" G_GUINT64_FORMAT "\n", val64);
+
+ qmi_message_wds_get_packet_statistics_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+get_data_bearer_technology_ready (QmiClientWds *client,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+ QmiMessageWdsGetDataBearerTechnologyOutput *output;
+ QmiWdsDataBearerTechnology current;
+
+ output = qmi_client_wds_get_data_bearer_technology_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n",
+ error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_wds_get_data_bearer_technology_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get data bearer technology: %s\n", error->message);
+
+ if (g_error_matches (error,
+ QMI_PROTOCOL_ERROR,
+ QMI_PROTOCOL_ERROR_OUT_OF_CALL)) {
+ QmiWdsDataBearerTechnology last = QMI_WDS_DATA_BEARER_TECHNOLOGY_UNKNOWN;
+
+ if (qmi_message_wds_get_data_bearer_technology_output_get_last (
+ output,
+ &last,
+ NULL))
+ g_print ("[%s] Data bearer technology (last): '%s'(%d)\n",
+ qmi_device_get_path_display (ctx->device),
+ qmi_wds_data_bearer_technology_get_string (last), last);
+ }
+
+ g_error_free (error);
+ qmi_message_wds_get_data_bearer_technology_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_wds_get_data_bearer_technology_output_get_last (
+ output,
+ &current,
+ NULL);
+ g_print ("[%s] Data bearer technology (current): '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ qmi_wds_data_bearer_technology_get_string (current));
+ qmi_message_wds_get_data_bearer_technology_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+print_current_data_bearer_technology_results (const gchar *which,
+ QmiWdsNetworkType network_type,
+ guint32 rat_mask,
+ guint32 so_mask)
+{
+ gchar *rat_string = NULL;
+ gchar *so_string = NULL;
+
+ if (network_type == QMI_WDS_NETWORK_TYPE_3GPP2) {
+ rat_string = qmi_wds_rat_3gpp2_build_string_from_mask (rat_mask);
+ if (rat_mask & QMI_WDS_RAT_3GPP2_CDMA1X)
+ so_string = qmi_wds_so_cdma1x_build_string_from_mask (so_mask);
+ else if (rat_mask & QMI_WDS_RAT_3GPP2_EVDO_REVA)
+ so_string = qmi_wds_so_evdo_reva_build_string_from_mask (so_mask);
+ } else if (network_type == QMI_WDS_NETWORK_TYPE_3GPP) {
+ rat_string = qmi_wds_rat_3gpp_build_string_from_mask (rat_mask);
+ }
+
+ g_print ("[%s] Data bearer technology (%s):\n"
+ " Network type: '%s'\n"
+ " Radio Access Technology: '%s'\n"
+ " Service Option: '%s'\n",
+ qmi_device_get_path_display (ctx->device),
+ which,
+ qmi_wds_network_type_get_string (network_type),
+ VALIDATE_UNKNOWN (rat_string),
+ VALIDATE_UNKNOWN (so_string));
+ g_free (rat_string);
+ g_free (so_string);
+}
+
+static void
+get_current_data_bearer_technology_ready (QmiClientWds *client,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+ QmiMessageWdsGetCurrentDataBearerTechnologyOutput *output;
+ QmiWdsNetworkType network_type;
+ guint32 rat_mask;
+ guint32 so_mask;
+
+ output = qmi_client_wds_get_current_data_bearer_technology_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n",
+ error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+#undef VALIDATE_UNKNOWN
+#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
+
+ if (!qmi_message_wds_get_current_data_bearer_technology_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get current data bearer technology: %s\n", error->message);
+
+ if (qmi_message_wds_get_current_data_bearer_technology_output_get_last (
+ output,
+ &network_type,
+ &rat_mask,
+ &so_mask,
+ NULL)) {
+ print_current_data_bearer_technology_results (
+ "last",
+ network_type,
+ rat_mask,
+ so_mask);
+ }
+
+ g_error_free (error);
+ qmi_message_wds_get_current_data_bearer_technology_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ /* Retrieve CURRENT */
+ if (qmi_message_wds_get_current_data_bearer_technology_output_get_current (
+ output,
+ &network_type,
+ &rat_mask,
+ &so_mask,
+ NULL)) {
+ print_current_data_bearer_technology_results (
+ "current",
+ network_type,
+ rat_mask,
+ so_mask);
+ }
+
+ qmi_message_wds_get_current_data_bearer_technology_output_unref (output);
+ shutdown (TRUE);
+}
+
+static void
+reset_ready (QmiClientWds *client,
+ GAsyncResult *res)
+{
+ QmiMessageWdsResetOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_wds_reset_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_wds_reset_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't reset the WDS service: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_wds_reset_output_unref (output);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully performed WDS service reset\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_wds_reset_output_unref (output);
+ shutdown (TRUE);
+}
+
+static gboolean
+noop_cb (gpointer unused)
+{
+ shutdown (TRUE);
+ return FALSE;
+}
+
+void
+qmicli_wds_run (QmiDevice *device,
+ QmiClientWds *client,
+ GCancellable *cancellable)
+{
+ /* Initialize context */
+ ctx = g_slice_new (Context);
+ ctx->device = g_object_ref (device);
+ ctx->client = g_object_ref (client);
+ ctx->cancellable = g_object_ref (cancellable);
+ ctx->network_started_id = 0;
+ ctx->packet_status_timeout_id = 0;
+
+ /* Request to start network? */
+ if (start_network_str) {
+ QmiMessageWdsStartNetworkInput *input = NULL;
+
+ /* Use the input string as APN */
+ if (start_network_str[0]) {
+ gchar **split;
+
+ split = g_strsplit (start_network_str, ",", 0);
+
+ input = qmi_message_wds_start_network_input_new ();
+ qmi_message_wds_start_network_input_set_apn (input, split[0], NULL);
+
+ if (split[1]) {
+ QmiWdsAuthentication qmiwdsauth;
+
+ /* Use authentication method */
+ if (g_ascii_strcasecmp (split[1], "PAP") == 0) {
+ qmiwdsauth = QMI_WDS_AUTHENTICATION_PAP;
+ } else if (g_ascii_strcasecmp (split[1], "CHAP") == 0) {
+ qmiwdsauth = QMI_WDS_AUTHENTICATION_CHAP;
+ } else if (g_ascii_strcasecmp (split[1], "BOTH") == 0) {
+ qmiwdsauth = (QMI_WDS_AUTHENTICATION_PAP | QMI_WDS_AUTHENTICATION_CHAP);
+ } else {
+ qmiwdsauth = QMI_WDS_AUTHENTICATION_NONE;
+ }
+
+ qmi_message_wds_start_network_input_set_authentication_preference (input, qmiwdsauth, NULL);
+
+ /* Username */
+ if (split[2] && strlen (split[2])) {
+ qmi_message_wds_start_network_input_set_username (input, split[2], NULL);
+
+ /* Password */
+ if (split[3] && strlen (split[3])) {
+ qmi_message_wds_start_network_input_set_password (input, split[3], NULL);
+ }
+ }
+ }
+ g_strfreev (split);
+ }
+
+ g_debug ("Asynchronously starting network...");
+ qmi_client_wds_start_network (ctx->client,
+ input,
+ 45,
+ ctx->cancellable,
+ (GAsyncReadyCallback)start_network_ready,
+ NULL);
+ if (input)
+ qmi_message_wds_start_network_input_unref (input);
+ return;
+ }
+
+ /* Request to stop network? */
+ if (stop_network_str) {
+ gulong packet_data_handle;
+
+ packet_data_handle = strtoul (stop_network_str, NULL, 10);
+ if (!packet_data_handle ||
+ packet_data_handle > G_MAXUINT32) {
+ g_printerr ("error: invalid packet data handle given '%s'\n",
+ stop_network_str);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_debug ("Asynchronously stopping network...");
+ internal_stop_network (ctx->cancellable, (guint32)packet_data_handle);
+ return;
+ }
+
+ /* Request to get packet service status? */
+ if (get_packet_service_status_flag) {
+ g_debug ("Asynchronously getting packet service status...");
+ qmi_client_wds_get_packet_service_status (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_packet_service_status_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get packet statistics? */
+ if (get_packet_statistics_flag) {
+ QmiMessageWdsGetPacketStatisticsInput *input;
+
+ input = qmi_message_wds_get_packet_statistics_input_new ();
+ qmi_message_wds_get_packet_statistics_input_set_mask (
+ input,
+ (QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_PACKETS_OK |
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_PACKETS_OK |
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_PACKETS_ERROR |
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_PACKETS_ERROR |
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_OVERFLOWS |
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_OVERFLOWS |
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_BYTES_OK |
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_BYTES_OK |
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_TX_PACKETS_DROPPED |
+ QMI_WDS_PACKET_STATISTICS_MASK_FLAG_RX_PACKETS_DROPPED),
+ NULL);
+
+ g_debug ("Asynchronously getting packet statistics...");
+ qmi_client_wds_get_packet_statistics (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_packet_statistics_ready,
+ NULL);
+ qmi_message_wds_get_packet_statistics_input_unref (input);
+ return;
+ }
+
+ /* Request to get data bearer technology? */
+ if (get_data_bearer_technology_flag) {
+ g_debug ("Asynchronously getting data bearer technology...");
+ qmi_client_wds_get_data_bearer_technology (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_data_bearer_technology_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to get current data bearer technology? */
+ if (get_current_data_bearer_technology_flag) {
+ g_debug ("Asynchronously getting current data bearer technology...");
+ qmi_client_wds_get_current_data_bearer_technology (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_current_data_bearer_technology_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to reset WDS service? */
+ if (reset_flag) {
+ g_debug ("Asynchronously resetting WDS service...");
+ qmi_client_wds_reset (ctx->client,
+ NULL,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)reset_ready,
+ NULL);
+ return;
+ }
+
+ /* Just client allocate/release? */
+ if (noop_flag) {
+ g_idle_add (noop_cb, NULL);
+ return;
+ }
+
+ g_warn_if_reached ();
+}
diff --git a/src/qmicli/qmicli.c b/src/qmicli/qmicli.c
new file mode 100644
index 0000000..c992bd6
--- /dev/null
+++ b/src/qmicli/qmicli.c
@@ -0,0 +1,620 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * qmicli -- Command line interface to control QMI devices
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2012 Aleksander Morgado <aleksander@lanedo.com>
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <gio/gio.h>
+
+#include <libqmi-glib.h>
+
+#include "qmicli.h"
+
+#define PROGRAM_NAME "qmicli"
+#define PROGRAM_VERSION PACKAGE_VERSION
+
+/* Globals */
+static GMainLoop *loop;
+static GCancellable *cancellable;
+static QmiDevice *device;
+static QmiClient *client;
+static QmiService service;
+static gboolean operation_status;
+
+/* Main options */
+static gchar *device_str;
+static gboolean get_service_version_info_flag;
+static gchar *device_set_instance_id_str;
+static gboolean device_open_version_info_flag;
+static gboolean device_open_sync_flag;
+static gchar *client_cid_str;
+static gboolean client_no_release_cid_flag;
+static gboolean verbose_flag;
+static gboolean silent_flag;
+static gboolean version_flag;
+
+static GOptionEntry main_entries[] = {
+ { "device", 'd', 0, G_OPTION_ARG_STRING, &device_str,
+ "Specify device path",
+ "[PATH]"
+ },
+ { "get-service-version-info", 0, 0, G_OPTION_ARG_NONE, &get_service_version_info_flag,
+ "Get service version info",
+ NULL
+ },
+ { "device-set-instance-id", 0, 0, G_OPTION_ARG_STRING, &device_set_instance_id_str,
+ "Set instance ID",
+ "[Instance ID]"
+ },
+ { "device-open-version-info", 0, 0, G_OPTION_ARG_NONE, &device_open_version_info_flag,
+ "Run version info check when opening device",
+ NULL
+ },
+ { "device-open-sync", 0, 0, G_OPTION_ARG_NONE, &device_open_sync_flag,
+ "Run sync operation when opening device",
+ NULL
+ },
+ { "client-cid", 0, 0, G_OPTION_ARG_STRING, &client_cid_str,
+ "Use the given CID, don't allocate a new one",
+ "[CID]"
+ },
+ { "client-no-release-cid", 0, 0, G_OPTION_ARG_NONE, &client_no_release_cid_flag,
+ "Do not release the CID when exiting",
+ NULL
+ },
+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose_flag,
+ "Run action with verbose logs, including the debug ones",
+ NULL
+ },
+ { "silent", 0, 0, G_OPTION_ARG_NONE, &silent_flag,
+ "Run action with no logs; not even the error/warning ones",
+ NULL
+ },
+ { "version", 'V', 0, G_OPTION_ARG_NONE, &version_flag,
+ "Print version",
+ NULL
+ },
+ { NULL }
+};
+
+static void
+signals_handler (int signum)
+{
+ if (cancellable) {
+ /* Ignore consecutive requests of cancellation */
+ if (!g_cancellable_is_cancelled (cancellable)) {
+ g_printerr ("%s\n",
+ "cancelling the operation...\n");
+ g_cancellable_cancel (cancellable);
+ }
+ return;
+ }
+
+ if (loop &&
+ g_main_loop_is_running (loop)) {
+ g_printerr ("%s\n",
+ "cancelling the main loop...\n");
+ g_main_loop_quit (loop);
+ }
+}
+
+static void
+log_handler (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ const gchar *log_level_str;
+ time_t now;
+ gchar time_str[64];
+ struct tm *local_time;
+ gboolean err;
+
+ /* Nothing to do if we're silent */
+ if (silent_flag)
+ return;
+
+ now = time ((time_t *) NULL);
+ local_time = localtime (&now);
+ strftime (time_str, 64, "%d %b %Y, %H:%M:%S", local_time);
+ err = FALSE;
+
+ switch (log_level) {
+ case G_LOG_LEVEL_WARNING:
+ log_level_str = "-Warning **";
+ err = TRUE;
+ break;
+
+ case G_LOG_LEVEL_CRITICAL:
+ case G_LOG_FLAG_FATAL:
+ case G_LOG_LEVEL_ERROR:
+ log_level_str = "-Error **";
+ err = TRUE;
+ break;
+
+ case G_LOG_LEVEL_DEBUG:
+ log_level_str = "[Debug]";
+ break;
+
+ default:
+ log_level_str = "";
+ break;
+ }
+
+ if (!verbose_flag && !err)
+ return;
+
+ g_fprintf (err ? stderr : stdout,
+ "[%s] %s %s\n",
+ time_str,
+ log_level_str,
+ message);
+}
+
+static void
+print_version_and_exit (void)
+{
+ g_print ("\n"
+ PROGRAM_NAME " " PROGRAM_VERSION "\n"
+ "Copyright (2012) Aleksander Morgado\n"
+ "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n"
+ "\n");
+ exit (EXIT_SUCCESS);
+}
+
+static gboolean
+generic_options_enabled (void)
+{
+ static guint n_actions = 0;
+ static gboolean checked = FALSE;
+
+ if (checked)
+ return !!n_actions;
+
+ n_actions = (!!device_set_instance_id_str +
+ get_service_version_info_flag);
+
+ if (n_actions > 1) {
+ g_printerr ("error: too many generic actions requested\n");
+ exit (EXIT_FAILURE);
+ }
+
+ checked = TRUE;
+ return !!n_actions;
+}
+
+/*****************************************************************************/
+/* Running asynchronously */
+
+static void
+release_client_ready (QmiDevice *dev,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+
+ if (!qmi_device_release_client_finish (dev, res, &error)) {
+ g_printerr ("error: couldn't release client: %s", error->message);
+ g_error_free (error);
+ } else
+ g_debug ("Client released");
+
+ g_main_loop_quit (loop);
+}
+
+void
+qmicli_async_operation_done (gboolean reported_operation_status)
+{
+ QmiDeviceReleaseClientFlags flags = QMI_DEVICE_RELEASE_CLIENT_FLAGS_NONE;
+
+ /* Keep the result of the operation */
+ operation_status = reported_operation_status;
+
+ if (cancellable) {
+ g_object_unref (cancellable);
+ cancellable = NULL;
+ }
+
+ /* If no client was allocated (e.g. generic action), just quit */
+ if (!client) {
+ g_main_loop_quit (loop);
+ return;
+ }
+
+ if (!client_no_release_cid_flag)
+ flags |= QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID;
+ else
+ g_print ("[%s] Client ID not released:\n"
+ "\tService: '%s'\n"
+ "\t CID: '%u'\n",
+ qmi_device_get_path_display (device),
+ qmi_service_get_string (service),
+ qmi_client_get_cid (client));
+
+ qmi_device_release_client (device,
+ client,
+ flags,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)release_client_ready,
+ NULL);
+}
+
+static void
+allocate_client_ready (QmiDevice *dev,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+
+ client = qmi_device_allocate_client_finish (dev, res, &error);
+ if (!client) {
+ g_printerr ("error: couldn't create client for the '%s' service: %s\n",
+ qmi_service_get_string (service),
+ error->message);
+ exit (EXIT_FAILURE);
+ }
+
+ /* Run the service-specific action */
+ switch (service) {
+ case QMI_SERVICE_DMS:
+ qmicli_dms_run (dev, QMI_CLIENT_DMS (client), cancellable);
+ return;
+ case QMI_SERVICE_NAS:
+ qmicli_nas_run (dev, QMI_CLIENT_NAS (client), cancellable);
+ return;
+ case QMI_SERVICE_WDS:
+ qmicli_wds_run (dev, QMI_CLIENT_WDS (client), cancellable);
+ return;
+ case QMI_SERVICE_PBM:
+ qmicli_pbm_run (dev, QMI_CLIENT_PBM (client), cancellable);
+ return;
+ case QMI_SERVICE_UIM:
+ qmicli_uim_run (dev, QMI_CLIENT_UIM (client), cancellable);
+ return;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+device_allocate_client (QmiDevice *dev)
+{
+ guint8 cid = QMI_CID_NONE;
+
+ if (client_cid_str) {
+ guint32 cid32;
+
+ cid32 = atoi (client_cid_str);
+ if (!cid32 || cid32 > G_MAXUINT8) {
+ g_printerr ("error: invalid CID given '%s'\n",
+ client_cid_str);
+ exit (EXIT_FAILURE);
+ }
+
+ cid = (guint8)cid32;
+ g_debug ("Reusing CID '%u'", cid);
+ }
+
+ /* As soon as we get the QmiDevice, create a client for the requested
+ * service */
+ qmi_device_allocate_client (dev,
+ service,
+ cid,
+ 10,
+ cancellable,
+ (GAsyncReadyCallback)allocate_client_ready,
+ NULL);
+}
+
+static void
+set_instance_id_ready (QmiDevice *dev,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+ guint16 link_id;
+
+ if (!qmi_device_set_instance_id_finish (dev, res, &link_id, &error)) {
+ g_printerr ("error: couldn't set instance ID: %s\n",
+ error->message);
+ exit (EXIT_FAILURE);
+ }
+
+ g_print ("[%s] Instance ID set:\n"
+ "\tLink ID: '%" G_GUINT16_FORMAT "'\n",
+ qmi_device_get_path_display (dev),
+ link_id);
+
+ /* We're done now */
+ qmicli_async_operation_done (TRUE);
+}
+
+static void
+device_set_instance_id (QmiDevice *dev)
+{
+ gint instance_id;
+
+ if (g_str_equal (device_set_instance_id_str, "0"))
+ instance_id = 0;
+ else {
+ instance_id = atoi (device_set_instance_id_str);
+ if (instance_id == 0) {
+ g_printerr ("error: invalid instance ID given: '%s'\n", device_set_instance_id_str);
+ exit (EXIT_FAILURE);
+ } else if (instance_id < 0 || instance_id > G_MAXUINT8) {
+ g_printerr ("error: given instance ID is out of range [0,%u]: '%s'\n",
+ G_MAXUINT8,
+ device_set_instance_id_str);
+ exit (EXIT_FAILURE);
+ }
+ }
+
+ g_debug ("Setting instance ID '%d'...", instance_id);
+ qmi_device_set_instance_id (dev,
+ (guint8)instance_id,
+ 10,
+ cancellable,
+ (GAsyncReadyCallback)set_instance_id_ready,
+ NULL);
+}
+
+static void
+get_service_version_info_ready (QmiDevice *dev,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+ GArray *services;
+ guint i;
+
+ services = qmi_device_get_service_version_info_finish (dev, res, &error);
+ if (!services) {
+ g_printerr ("error: couldn't get service version info: %s\n",
+ error->message);
+ exit (EXIT_FAILURE);
+ }
+
+ g_print ("[%s] Supported versions:\n",
+ qmi_device_get_path_display (dev));
+ for (i = 0; i < services->len; i++) {
+ QmiDeviceServiceVersionInfo *info;
+ const gchar *service_str;
+
+ info = &g_array_index (services, QmiDeviceServiceVersionInfo, i);
+ service_str = qmi_service_get_string (info->service);
+ if (service_str)
+ g_print ("\t%s (%u.%u)\n",
+ service_str,
+ info->major_version,
+ info->minor_version);
+ else
+ g_print ("\tunknown [0x%02x] (%u.%u)\n",
+ info->service,
+ info->major_version,
+ info->minor_version);
+ }
+ g_array_unref (services);
+
+ /* We're done now */
+ qmicli_async_operation_done (TRUE);
+}
+
+static void
+device_get_service_version_info (QmiDevice *dev)
+{
+ g_debug ("Getting service version info...");
+ qmi_device_get_service_version_info (dev,
+ 10,
+ cancellable,
+ (GAsyncReadyCallback)get_service_version_info_ready,
+ NULL);
+}
+
+static void
+device_open_ready (QmiDevice *dev,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+
+ if (!qmi_device_open_finish (dev, res, &error)) {
+ g_printerr ("error: couldn't open the QmiDevice: %s\n",
+ error->message);
+ exit (EXIT_FAILURE);
+ }
+
+ g_debug ("QMI Device at '%s' ready",
+ qmi_device_get_path_display (dev));
+
+ if (device_set_instance_id_str)
+ device_set_instance_id (dev);
+ else if (get_service_version_info_flag)
+ device_get_service_version_info (dev);
+ else
+ device_allocate_client (dev);
+}
+
+static void
+device_new_ready (GObject *unused,
+ GAsyncResult *res)
+{
+ QmiDeviceOpenFlags open_flags = QMI_DEVICE_OPEN_FLAGS_NONE;
+ GError *error = NULL;
+
+ device = qmi_device_new_finish (res, &error);
+ if (!device) {
+ g_printerr ("error: couldn't create QmiDevice: %s\n",
+ error->message);
+ exit (EXIT_FAILURE);
+ }
+
+ /* Setup device open flags */
+ if (device_open_version_info_flag)
+ open_flags |= QMI_DEVICE_OPEN_FLAGS_VERSION_INFO;
+ if (device_open_sync_flag)
+ open_flags |= QMI_DEVICE_OPEN_FLAGS_SYNC;
+
+ /* Open the device */
+ qmi_device_open (device,
+ open_flags,
+ 15,
+ cancellable,
+ (GAsyncReadyCallback)device_open_ready,
+ NULL);
+}
+
+/*****************************************************************************/
+
+static void
+parse_actions (void)
+{
+ guint actions_enabled = 0;
+
+ /* Generic options? */
+ if (generic_options_enabled ()) {
+ service = QMI_SERVICE_CTL;
+ actions_enabled++;
+ }
+
+ /* DMS options? */
+ if (qmicli_dms_options_enabled ()) {
+ service = QMI_SERVICE_DMS;
+ actions_enabled++;
+ }
+
+ /* NAS options? */
+ if (qmicli_nas_options_enabled ()) {
+ service = QMI_SERVICE_NAS;
+ actions_enabled++;
+ }
+
+ /* WDS options? */
+ if (qmicli_wds_options_enabled ()) {
+ service = QMI_SERVICE_WDS;
+ actions_enabled++;
+ }
+
+ /* PBM options? */
+ if (qmicli_pbm_options_enabled ()) {
+ service = QMI_SERVICE_PBM;
+ actions_enabled++;
+ }
+
+ /* UIM options? */
+ if (qmicli_uim_options_enabled ()) {
+ service = QMI_SERVICE_UIM;
+ actions_enabled++;
+ }
+
+ /* Cannot mix actions from different services */
+ if (actions_enabled > 1) {
+ g_printerr ("error: cannot execute multiple actions of different services\n");
+ exit (EXIT_FAILURE);
+ }
+
+ /* No options? */
+ if (actions_enabled == 0) {
+ g_printerr ("error: no actions specified\n");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Go on! */
+}
+
+int main (int argc, char **argv)
+{
+ GError *error = NULL;
+ GFile *file;
+ GOptionContext *context;
+
+ setlocale (LC_ALL, "");
+
+ g_type_init ();
+
+ /* Setup option context, process it and destroy it */
+ context = g_option_context_new ("- Control QMI devices");
+ g_option_context_add_group (context,
+ qmicli_dms_get_option_group ());
+ g_option_context_add_group (context,
+ qmicli_nas_get_option_group ());
+ g_option_context_add_group (context,
+ qmicli_wds_get_option_group ());
+ g_option_context_add_group (context,
+ qmicli_pbm_get_option_group ());
+ g_option_context_add_group (context,
+ qmicli_uim_get_option_group ());
+ g_option_context_add_main_entries (context, main_entries, NULL);
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_printerr ("error: %s\n",
+ error->message);
+ exit (EXIT_FAILURE);
+ }
+ g_option_context_free (context);
+
+ if (version_flag)
+ print_version_and_exit ();
+
+ g_log_set_handler (NULL, G_LOG_LEVEL_MASK, log_handler, NULL);
+ g_log_set_handler ("Qmi", G_LOG_LEVEL_MASK, log_handler, NULL);
+ if (verbose_flag)
+ qmi_utils_set_traces_enabled (TRUE);
+
+ /* No device path given? */
+ if (!device_str) {
+ g_printerr ("error: no device path specified\n");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Build new GFile from the commandline arg */
+ file = g_file_new_for_commandline_arg (device_str);
+
+ /* Setup signals */
+ signal (SIGINT, signals_handler);
+ signal (SIGHUP, signals_handler);
+ signal (SIGTERM, signals_handler);
+
+ parse_actions ();
+
+ /* Create requirements for async options */
+ cancellable = g_cancellable_new ();
+ loop = g_main_loop_new (NULL, FALSE);
+
+ /* Launch QmiDevice creation */
+ qmi_device_new (file,
+ cancellable,
+ (GAsyncReadyCallback)device_new_ready,
+ GUINT_TO_POINTER (service));
+ g_main_loop_run (loop);
+
+ if (cancellable)
+ g_object_unref (cancellable);
+ if (client)
+ g_object_unref (client);
+ if (device)
+ g_object_unref (device);
+ g_main_loop_unref (loop);
+ g_object_unref (file);
+
+ return (operation_status ? EXIT_SUCCESS : EXIT_FAILURE);
+}
diff --git a/src/qmicli/qmicli.h b/src/qmicli/qmicli.h
new file mode 100644
index 0000000..26a2d16
--- /dev/null
+++ b/src/qmicli/qmicli.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * qmicli -- Command line interface to control QMI devices
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
+ */
+
+#include <glib.h>
+
+#ifndef __QMICLI_H__
+#define __QMICLI_H__
+
+/* Common */
+void qmicli_async_operation_done (gboolean operation_status);
+
+/* DMS group */
+GOptionGroup *qmicli_dms_get_option_group (void);
+gboolean qmicli_dms_options_enabled (void);
+void qmicli_dms_run (QmiDevice *device,
+ QmiClientDms *client,
+ GCancellable *cancellable);
+
+/* WDS group */
+GOptionGroup *qmicli_wds_get_option_group (void);
+gboolean qmicli_wds_options_enabled (void);
+void qmicli_wds_run (QmiDevice *device,
+ QmiClientWds *client,
+ GCancellable *cancellable);
+
+/* NAS group */
+GOptionGroup *qmicli_nas_get_option_group (void);
+gboolean qmicli_nas_options_enabled (void);
+void qmicli_nas_run (QmiDevice *device,
+ QmiClientNas *client,
+ GCancellable *cancellable);
+
+/* PBM group */
+GOptionGroup *qmicli_pbm_get_option_group (void);
+gboolean qmicli_pbm_options_enabled (void);
+void qmicli_pbm_run (QmiDevice *device,
+ QmiClientPbm *client,
+ GCancellable *cancellable);
+
+/* UIM group */
+GOptionGroup *qmicli_uim_get_option_group (void);
+gboolean qmicli_uim_options_enabled (void);
+void qmicli_uim_run (QmiDevice *device,
+ QmiClientUim *client,
+ GCancellable *cancellable);
+
+#endif /* __QMICLI_H__ */
diff --git a/src/qmicli/test/Makefile.am b/src/qmicli/test/Makefile.am
new file mode 100644
index 0000000..a583692
--- /dev/null
+++ b/src/qmicli/test/Makefile.am
@@ -0,0 +1,24 @@
+include $(top_srcdir)/gtester.make
+
+noinst_PROGRAMS = \
+ test-helpers
+
+TEST_PROGS += $(noinst_PROGRAMS)
+
+test_helpers_SOURCES = \
+ test-helpers.c \
+ $(top_srcdir)/src/qmicli/qmicli-helpers.h \
+ $(top_srcdir)/src/qmicli/qmicli-helpers.c
+
+test_helpers_CPPFLAGS = \
+ $(QMICLI_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src/qmicli \
+ -I$(top_srcdir)/src/libqmi-glib \
+ -I$(top_srcdir)/src/libqmi-glib/generated \
+ -I$(top_builddir)/src/libqmi-glib \
+ -I$(top_builddir)/src/libqmi-glib/generated
+
+test_helpers_LDADD = \
+ $(QMICLI_LIBS) \
+ $(top_builddir)/src/libqmi-glib/libqmi-glib.la
diff --git a/src/qmicli/test/test-helpers.c b/src/qmicli/test/test-helpers.c
new file mode 100644
index 0000000..824ed3e
--- /dev/null
+++ b/src/qmicli/test/test-helpers.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details:
+ *
+ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
+ */
+
+#include <glib.h>
+#include "qmicli-helpers.h"
+
+static void
+test_helpers_raw_printable_1 (void)
+{
+ GArray *array;
+ gchar *printable;
+ static guint8 buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static const gchar *expected =
+ "0F:\n"
+ "50:\n"
+ "EB:\n"
+ "E2:\n"
+ "B6:\n"
+ "00:\n"
+ "00:\n"
+ "00\n";
+
+ array = g_array_sized_new (FALSE, FALSE, 1, 8);
+ g_array_insert_vals (array, 0, buffer, 8);
+
+ printable = qmicli_get_raw_data_printable (array, 3, "");
+
+ g_assert_cmpstr (printable, ==, expected);
+ g_free (printable);
+ g_array_unref (array);
+}
+
+static void
+test_helpers_raw_printable_2 (void)
+{
+ GArray *array;
+ gchar *printable;
+ static guint8 buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static const gchar *expected =
+ "\t0F:50:\n"
+ "\tEB:E2:\n"
+ "\tB6:00:\n"
+ "\t00:00\n";
+
+ array = g_array_sized_new (FALSE, FALSE, 1, 8);
+ g_array_insert_vals (array, 0, buffer, 8);
+
+ /* When passing 7, we'll be really getting 6 (the closest lower multiple of 3) */
+ printable = qmicli_get_raw_data_printable (array, 7, "\t");
+
+ g_assert_cmpstr (printable, ==, expected);
+ g_free (printable);
+ g_array_unref (array);
+}
+
+static void
+test_helpers_raw_printable_3 (void)
+{
+ GArray *array;
+ gchar *printable;
+ static guint8 buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static const gchar *expected =
+ "\t\t\t0F:50:EB:E2:\n"
+ "\t\t\tB6:00:00:00\n";
+
+ array = g_array_sized_new (FALSE, FALSE, 1, 8);
+ g_array_insert_vals (array, 0, buffer, 8);
+
+ printable = qmicli_get_raw_data_printable (array, 12, "\t\t\t");
+
+ g_assert_cmpstr (printable, ==, expected);
+ g_free (printable);
+ g_array_unref (array);
+}
+
+static void
+test_helpers_raw_printable_4 (void)
+{
+ GArray *array;
+ gchar *printable;
+ static guint8 buffer[8] = {
+ 0x0F, 0x50, 0xEB, 0xE2, 0xB6, 0x00, 0x00, 0x00
+ };
+ static const gchar *expected =
+ "\t0F:50:EB:E2:B6:00:00:00\n";
+
+ array = g_array_sized_new (FALSE, FALSE, 1, 8);
+ g_array_insert_vals (array, 0, buffer, 8);
+
+ printable = qmicli_get_raw_data_printable (array, 24, "\t");
+
+ g_assert_cmpstr (printable, ==, expected);
+ g_free (printable);
+ g_array_unref (array);
+}
+
+int main (int argc, char **argv)
+{
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/qmicli/helpers/raw-printable/1", test_helpers_raw_printable_1);
+ g_test_add_func ("/qmicli/helpers/raw-printable/2", test_helpers_raw_printable_2);
+ g_test_add_func ("/qmicli/helpers/raw-printable/3", test_helpers_raw_printable_3);
+ g_test_add_func ("/qmicli/helpers/raw-printable/4", test_helpers_raw_printable_4);
+
+ return g_test_run ();
+}