aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAliaksandr Barouski <alex.borovsky@gmail.com>2016-07-07 15:47:20 -0700
committerAleksander Morgado <aleksander@aleksander.es>2016-10-26 14:59:43 +0200
commit24cdbd32e97373626f977b7bbb4bdf1b92b2d513 (patch)
tree5d3847d156a68fd082a34ff5223b53d49d974cd8
parentfa39dc14a6b8bdea736239da9fee59a65e289b1d (diff)
pdc: new PDC service implementation
Added calls for configure hp4120 LTE modem
-rw-r--r--data/Makefile.am1
-rw-r--r--data/qmi-service-pdc.json364
-rw-r--r--docs/reference/libqmi-glib/Makefile.am1
-rw-r--r--docs/reference/libqmi-glib/libqmi-glib-common.sections12
-rw-r--r--docs/reference/libqmi-glib/libqmi-glib-docs.xml32
-rw-r--r--src/libqmi-glib/generated/Makefile.am16
-rw-r--r--src/libqmi-glib/libqmi-glib.h3
-rw-r--r--src/libqmi-glib/qmi-device.c5
-rw-r--r--src/libqmi-glib/qmi-enums-pdc.h54
-rw-r--r--src/libqmi-glib/qmi-message.c4
-rw-r--r--src/qmicli/Makefile.am1
-rw-r--r--src/qmicli/qmicli-helpers.c105
-rw-r--r--src/qmicli/qmicli-helpers.h8
-rw-r--r--src/qmicli/qmicli-pdc.c1407
-rw-r--r--src/qmicli/qmicli.c11
-rw-r--r--src/qmicli/qmicli.h7
16 files changed, 2030 insertions, 1 deletions
diff --git a/data/Makefile.am b/data/Makefile.am
index 0d74955..9c4b99b 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -7,6 +7,7 @@ EXTRA_DIST = \
qmi-service-wds.json \
qmi-service-nas.json \
qmi-service-wms.json \
+ qmi-service-pdc.json \
qmi-service-pds.json \
qmi-service-pbm.json \
qmi-service-uim.json \
diff --git a/data/qmi-service-pdc.json b/data/qmi-service-pdc.json
new file mode 100644
index 0000000..99ef2ce
--- /dev/null
+++ b/data/qmi-service-pdc.json
@@ -0,0 +1,364 @@
+[
+ // *********************************************************************************
+ { "name" : "PDC",
+ "type" : "Service" },
+
+ // *********************************************************************************
+ { "name" : "QMI Client PDC",
+ "type" : "Client" },
+
+ // *********************************************************************************
+ { "name" : "QMI Message PDC",
+ "type" : "Message-ID-Enum" },
+
+ // *********************************************************************************
+ { "name" : "QMI Indication PDC",
+ "type" : "Indication-ID-Enum" },
+
+ // *********************************************************************************
+ { "common-ref" : "Config Type",
+ "name" : "Config Type",
+ "id" : "0x1",
+ "mandatory" : "yes",
+ "type" : "TLV",
+ "format" : "guint32",
+ "public-format" : "QmiPdcConfigurationType" },
+
+ { "common-ref" : "Indication Result",
+ "name" : "Indication Result",
+ "id" : "0x01",
+ "mandatory" : "yes",
+ "type" : "TLV",
+ "format" : "guint16" },
+
+ // *********************************************************************************
+ { "common-ref" : "Config Type And Id",
+ "name" : "Type With Id",
+ "fullname" : "Qmi Config Type And Id",
+ "id" : "0x01",
+ "mandatory" : "yes",
+ "type" : "TLV",
+ "format" : "struct",
+ "contents" : [ { "name" : "Config Type",
+ "format" : "guint32",
+ "public-format" : "QmiPdcConfigurationType"},
+ { "name" : "Id",
+ "format" : "array",
+ "array-element" : { "format" : "guint8" }} ]},
+
+ // *********************************************************************************
+ { "common-ref" : "Token",
+ "name" : "Token",
+ "id" : "0x10",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "guint32"},
+
+ // *********************************************************************************
+ { "name" : "Reset",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x0000",
+ "version" : "1.15",
+ "output" : [ { "common-ref" : "Operation Result" } ] },
+
+ // *********************************************************************************
+ { "name" : "Register",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x20",
+ "version" : "1.15",
+ "input" : [ { "name" : "EnableReporting",
+ "id" : "0x10",
+ "mandatory" : "yes",
+ "type" : "TLV",
+ "format" : "guint8",
+ "public-format" : "gboolean"}],
+ "output" : [ { "common-ref" : "Operation Result" } ] },
+
+ // *********************************************************************************
+ { "name" : "Config Change",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x21",
+ "version" : "1.15",
+ "input" : [ { "common-ref" : "Config Type And Id" } ],
+ "output" : [ { "common-ref" : "Operation Result" },
+ { "common-ref" : "Config Type And Id"}] },
+
+ // *********************************************************************************
+ { "name" : "Get Selected Config",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x22",
+ "version" : "1.15",
+ "input" : [ { "common-ref" : "Config Type"},
+ { "common-ref" : "Token"}],
+ "output" : [ { "common-ref" : "Operation Result" },
+ { "common-ref" : "Token"}]},
+
+ { "name" : "Get Selected Config",
+ "type" : "Indication",
+ "service" : "PDC",
+ "id" : "0x22",
+ "version" : "1.15",
+ "output" : [ { "common-ref" : "Token"},
+ { "common-ref" : "Indication Result"},
+ { "name" : "Active Id",
+ "id" : "0x11",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "array",
+ "array-element" : { "format" : "guint8" } },
+ { "name" : "Pending Id",
+ "id" : "0x12",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "array",
+ "array-element" : { "format" : "guint8" } }]},
+
+ // *********************************************************************************
+ { "name" : "Set Selected Config",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x23",
+ "version" : "1.15",
+ "input" : [ { "common-ref" : "Config Type And Id" },
+ { "common-ref" : "Token" }],
+ "output" : [ { "common-ref" : "Operation Result" },
+ { "common-ref" : "Token"}] },
+
+ { "name" : "Set Selected Config",
+ "type" : "Indication",
+ "service" : "PDC",
+ "id" : "0x23",
+ "version" : "1.15",
+ "output" : [ { "common-ref" : "Indication Result" },
+ { "common-ref" : "Token"}] },
+
+ // *********************************************************************************
+ { "name" : "List Configs",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x24",
+ "version" : "1.15",
+ "input" : [ { "common-ref" : "Token" },
+ { "name" : "Config Type",
+ "id" : "0x11",
+ "mandatory" : "yes",
+ "type" : "TLV",
+ "format" : "guint32",
+ "public-format" : "QmiPdcConfigurationType" }],
+ "output" : [ { "common-ref" : "Operation Result" } ] },
+
+ { "name" : "List Configs",
+ "type" : "Indication",
+ "service" : "PDC",
+ "id" : "0x24",
+ "output" : [ { "common-ref" : "Token" },
+ { "common-ref" : "Indication Result"},
+ { "name" : "Configs",
+ "id" : "0x11",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "array",
+ "size-prefix-format" : "guint8",
+ "array-element" : { "name" : "Element",
+ "format" : "struct",
+ "contents" : [ { "name" : "Config Type",
+ "format" : "guint32",
+ "public-format" : "QmiPdcConfigurationType" },
+ { "name" : "Id",
+ "format" : "array",
+ "array-element" : { "format" : "guint8" }}]}}]},
+
+ // *********************************************************************************
+ { "name" : "Delete Config",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x25",
+ "version" : "1.15",
+ "input" : [ { "common-ref" : "Config Type" },
+ { "common-ref" : "Token" },
+ { "name" : "Id",
+ "id" : "0x11",
+ "mandatory" : "yes",
+ "type" : "TLV",
+ "format" : "array",
+ "array-element" : { "format" : "guint8" }}],
+ "output" : [ { "common-ref" : "Operation Result" },
+ { "common-ref" : "Token"}] },
+
+ // *********************************************************************************
+ { "name" : "Load Config",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x26",
+ "version" : "1.15",
+ "input" : [ { "name" : "Config Chunk",
+ "id" : "0x1",
+ "mandatory" : "yes",
+ "type" : "TLV",
+ "format" : "sequence",
+ "contents" : [ { "name" : "Type",
+ "format" : "guint32",
+ "public-format" : "QmiPdcConfigurationType"},
+ { "name" : "Id",
+ "format" : "array",
+ "array-element" : { "format" : "guint8" }},
+ { "name" : "Total Size",
+ "format" : "guint32" },
+ { "name" : "Chunk",
+ "format" : "array",
+ "size-prefix-format" : "guint16",
+ "array-element" : { "format" : "guint8" }}]},
+ { "common-ref" : "Token"}],
+ "output" : [ { "common-ref" : "Operation Result" },
+ { "common-ref" : "Token"}] },
+
+ { "name" : "Load Config",
+ "type" : "Indication",
+ "service" : "PDC",
+ "id" : "0x26",
+ "version" : "1.15",
+ "output" : [ { "common-ref" : "Token"},
+ { "common-ref" : "Indication Result"},
+ { "name" : "Received",
+ "id" : "0x11",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "guint32" },
+ { "name" : "Remaining Size",
+ "id" : "0x12",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "guint32" },
+ { "name" : "Frame Reset",
+ "id" : "0x13",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "guint8",
+ "public-format" : "gboolean" }
+ ] },
+
+ // *********************************************************************************
+ { "name" : "Activate Config",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x27",
+ "version" : "1.15",
+ "input" : [ { "common-ref" : "Config Type" },
+ { "common-ref" : "Token" }],
+ "output" : [ { "common-ref" : "Operation Result" },
+ { "common-ref" : "Token" }] },
+
+ { "name" : "Activate Config",
+ "type" : "Indication",
+ "service" : "PDC",
+ "id" : "0x27",
+ "version" : "1.15",
+ "output" : [ { "common-ref" : "Indication Result" },
+ { "common-ref" : "Token" }] },
+
+ // *********************************************************************************
+ { "name" : "Get Config Info",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x28",
+ "version" : "1.15",
+ "input" : [ { "common-ref" : "Config Type And Id" },
+ { "common-ref" : "Token"}],
+ "output" : [ { "common-ref" : "Operation Result" } ] },
+
+ { "name" : "Get Config Info",
+ "type" : "Indication",
+ "service" : "PDC",
+ "id" : "0x28",
+ "version" : "1.15",
+ "output" : [ { "common-ref" : "Token"},
+ { "common-ref" : "Indication Result"},
+ { "name" : "Total Size",
+ "id" : "0x11",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "guint32" },
+ { "name" : "Description",
+ "id" : "0x12",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "string",
+ "size-prefix-format" : "guint8"},
+ { "name" : "Version",
+ "id" : "0x13",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "guint32" }
+ ] },
+
+ // *********************************************************************************
+ { "name" : "Get Config Limits",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x29",
+ "version" : "1.15",
+ "input" : [ { "common-ref" : "Config Type" },
+ { "common-ref" : "Token" }],
+ "output" : [ { "common-ref" : "Operation Result" },
+ { "common-ref" : "Token" },
+ { "name" : "Maximum Size",
+ "id" : "0x11",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "guint64" },
+ { "name" : "Current Size",
+ "id" : "0x12",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "guint64" }] },
+
+ // *********************************************************************************
+ { "name" : "Get Default Config Info",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x2A",
+ "version" : "1.15",
+ "input" : [ { "common-ref" : "Config Type" },
+ { "common-ref" : "Token" }],
+ "output" : [ { "common-ref" : "Operation Result" },
+ { "common-ref" : "Token" },
+ { "name" : "Version",
+ "id" : "0x11",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "guint32" },
+ { "name" : "Total Size",
+ "id" : "0x12",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "guint32" },
+ { "name" : "Description",
+ "id" : "0x13",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "string" }
+ ] },
+
+ // *********************************************************************************
+ { "name" : "Deactivate Config",
+ "type" : "Message",
+ "service" : "PDC",
+ "id" : "0x2B",
+ "version" : "1.15",
+ "input" : [ { "common-ref" : "Config Type" },
+ { "common-ref" : "Token" }],
+ "output" : [ { "common-ref" : "Operation Result" },
+ { "common-ref" : "Token" }] },
+
+ { "name" : "Deactivate Config",
+ "type" : "Indication",
+ "service" : "PDC",
+ "id" : "0x2B",
+ "version" : "1.15",
+ "output" : [ { "common-ref" : "Indication Result" },
+ { "common-ref" : "Token" }] }
+]
diff --git a/docs/reference/libqmi-glib/Makefile.am b/docs/reference/libqmi-glib/Makefile.am
index deb5e8b..6f5cfd1 100644
--- a/docs/reference/libqmi-glib/Makefile.am
+++ b/docs/reference/libqmi-glib/Makefile.am
@@ -12,6 +12,7 @@ ALL_SECTIONS = \
$(top_builddir)/src/libqmi-glib/generated/qmi-nas.sections \
$(top_builddir)/src/libqmi-glib/generated/qmi-wds.sections \
$(top_builddir)/src/libqmi-glib/generated/qmi-wms.sections \
+ $(top_builddir)/src/libqmi-glib/generated/qmi-pdc.sections \
$(top_builddir)/src/libqmi-glib/generated/qmi-pds.sections \
$(top_builddir)/src/libqmi-glib/generated/qmi-pbm.sections \
$(top_builddir)/src/libqmi-glib/generated/qmi-uim.sections \
diff --git a/docs/reference/libqmi-glib/libqmi-glib-common.sections b/docs/reference/libqmi-glib/libqmi-glib-common.sections
index 053bd66..f7e3cc9 100644
--- a/docs/reference/libqmi-glib/libqmi-glib-common.sections
+++ b/docs/reference/libqmi-glib/libqmi-glib-common.sections
@@ -765,6 +765,18 @@ qmi_wms_transfer_indication_get_type
</SECTION>
<SECTION>
+<FILE>qmi-enums-pdc</FILE>
+QmiPdcConfigurationType
+<SUBSECTION Methods>
+qmi_pdc_configuration_type_get_string
+<SUBSECTION Private>
+qmi_pdc_configuration_type_build_string_from_mask
+<SUBSECTION Standard>
+QMI_TYPE_PDC_CONFIGURATION_TYPE
+qmi_pdc_configuration_type_get_type
+</SECTION>
+
+<SECTION>
<FILE>qmi-enums-pds</FILE>
QmiPdsOperationMode
QmiPdsPositionSessionStatus
diff --git a/docs/reference/libqmi-glib/libqmi-glib-docs.xml b/docs/reference/libqmi-glib/libqmi-glib-docs.xml
index 1567e22..5e7bbf0 100644
--- a/docs/reference/libqmi-glib/libqmi-glib-docs.xml
+++ b/docs/reference/libqmi-glib/libqmi-glib-docs.xml
@@ -221,6 +221,38 @@
</chapter>
<chapter>
+ <title>Persistent Device Configuration (PDC)</title>
+ <xi:include href="xml/qmi-client-pdc.xml"/>
+ <xi:include href="xml/qmi-enums-pdc.xml"/>
+ <section>
+ <title>PDC Indications</title>
+ <xi:include href="xml/qmi-indication-pdc-activate-config.xml"/>
+ <xi:include href="xml/qmi-indication-pdc-deactivate-config.xml"/>
+ <xi:include href="xml/qmi-indication-pdc-get-config-info.xml"/>
+ <xi:include href="xml/qmi-indication-pdc-get-selected-config.xml"/>
+ <xi:include href="xml/qmi-indication-pdc-list-configs.xml"/>
+ <xi:include href="xml/qmi-indication-pdc-load-config.xml"/>
+ <xi:include href="xml/qmi-indication-pdc-set-selected-config.xml"/>
+ </section>
+ <section>
+ <title>PDC Requests</title>
+ <xi:include href="xml/qmi-message-pdc-reset.xml"/>
+ <xi:include href="xml/qmi-message-pdc-register.xml"/>
+ <xi:include href="xml/qmi-message-pdc-config-change.xml"/>
+ <xi:include href="xml/qmi-message-pdc-get-selected-config.xml"/>
+ <xi:include href="xml/qmi-message-pdc-set-selected-config.xml"/>
+ <xi:include href="xml/qmi-message-pdc-list-configs.xml"/>
+ <xi:include href="xml/qmi-message-pdc-delete-config.xml"/>
+ <xi:include href="xml/qmi-message-pdc-load-config.xml"/>
+ <xi:include href="xml/qmi-message-pdc-activate-config.xml"/>
+ <xi:include href="xml/qmi-message-pdc-get-config-info.xml"/>
+ <xi:include href="xml/qmi-message-pdc-get-config-limits.xml"/>
+ <xi:include href="xml/qmi-message-pdc-get-default-config-info.xml"/>
+ <xi:include href="xml/qmi-message-pdc-deactivate-config.xml"/>
+ </section>
+ </chapter>
+
+ <chapter>
<title>Position Determination Service (PDS)</title>
<xi:include href="xml/qmi-client-pds.xml"/>
<xi:include href="xml/qmi-enums-pds.xml"/>
diff --git a/src/libqmi-glib/generated/Makefile.am b/src/libqmi-glib/generated/Makefile.am
index 2eda73b..23c7259 100644
--- a/src/libqmi-glib/generated/Makefile.am
+++ b/src/libqmi-glib/generated/Makefile.am
@@ -12,6 +12,7 @@ GENERATED_H = \
qmi-wds.h \
qmi-wms.h \
qmi-pds.h \
+ qmi-pdc.h \
qmi-pbm.h \
qmi-uim.h \
qmi-oma.h \
@@ -30,6 +31,7 @@ GENERATED_C = \
qmi-wds.c \
qmi-wms.c \
qmi-pds.c \
+ qmi-pdc.c \
qmi-pbm.c \
qmi-uim.c \
qmi-oma.c \
@@ -43,6 +45,7 @@ GENERATED_SECTIONS = \
qmi-wds.sections \
qmi-wms.sections \
qmi-pds.sections \
+ qmi-pdc.sections \
qmi-pbm.sections \
qmi-uim.sections \
qmi-oma.sections \
@@ -76,6 +79,7 @@ ENUMS = \
$(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-pdc.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 \
@@ -85,7 +89,7 @@ ENUMS = \
$(top_srcdir)/src/libqmi-glib/qmi-device.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#include \"qmi-enums-wda.h\"\n#include \"qmi-enums-voice.h\"\n#include \"qmi-device.h\"\n" \
+ --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-pdc.h\"\n#include \"qmi-enums-pbm.h\"\n#include \"qmi-enums-uim.h\"\n#include \"qmi-enums-oma.h\"\n#include \"qmi-enums-wda.h\"\n#include \"qmi-enums-voice.h\"\n#include \"qmi-device.h\"\n" \
--template $(top_srcdir)/build-aux/templates/qmi-enum-types-template.h \
--ftail "#endif /* __LIBQMI_GLIB_ENUM_TYPES_H__ */\n" \
$(ENUMS) > $@
@@ -187,6 +191,16 @@ qmi-pds.h qmi-pds.c qmi-pds.sections: $(top_srcdir)/data/qmi-service-pds.json $(
--include $(top_srcdir)/data/qmi-common.json \
--output qmi-pds
+# PDC service
+qmi-pdc.h qmi-pdc.c qmi-pdc.sections: $(top_srcdir)/data/qmi-service-pdc.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+ $(AM_V_GEN) \
+ rm -f qmi-pdc.h && \
+ rm -f qmi-pdc.c && \
+ $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
+ --input $(top_srcdir)/data/qmi-service-pdc.json \
+ --include $(top_srcdir)/data/qmi-common.json \
+ --output qmi-pdc
+
# 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) \
diff --git a/src/libqmi-glib/libqmi-glib.h b/src/libqmi-glib/libqmi-glib.h
index 12f9974..f954342 100644
--- a/src/libqmi-glib/libqmi-glib.h
+++ b/src/libqmi-glib/libqmi-glib.h
@@ -55,6 +55,9 @@
#include "qmi-enums-pds.h"
#include "qmi-pds.h"
+#include "qmi-enums-pdc.h"
+#include "qmi-pdc.h"
+
#include "qmi-enums-pbm.h"
#include "qmi-pbm.h"
diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c
index ef636f0..cf2dfd0 100644
--- a/src/libqmi-glib/qmi-device.c
+++ b/src/libqmi-glib/qmi-device.c
@@ -45,6 +45,7 @@
#include "qmi-wds.h"
#include "qmi-nas.h"
#include "qmi-wms.h"
+#include "qmi-pdc.h"
#include "qmi-pds.h"
#include "qmi-pbm.h"
#include "qmi-uim.h"
@@ -1184,6 +1185,10 @@ qmi_device_allocate_client (QmiDevice *self,
ctx->client_type = QMI_TYPE_CLIENT_PDS;
break;
+ case QMI_SERVICE_PDC:
+ ctx->client_type = QMI_TYPE_CLIENT_PDC;
+ break;
+
case QMI_SERVICE_PBM:
ctx->client_type = QMI_TYPE_CLIENT_PBM;
break;
diff --git a/src/libqmi-glib/qmi-enums-pdc.h b/src/libqmi-glib/qmi-enums-pdc.h
new file mode 100644
index 0000000..a3ae19e
--- /dev/null
+++ b/src/libqmi-glib/qmi-enums-pdc.h
@@ -0,0 +1,54 @@
+/* -*- 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_PDC_H_
+#define _LIBQMI_GLIB_QMI_ENUMS_PDC_H_
+
+#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION)
+#error "Only <libqmi-glib.h> can be included directly."
+#endif
+
+/**
+ * SECTION: qmi-enums-pdc
+ * @title: PDC enumerations and flags
+ *
+ * This section defines enumerations and flags used in the PDC service
+ * interface.
+ */
+
+/*****************************************************************************/
+/* Helper enums for the 'QMI PDC' calls */
+
+/**
+ * QmiPdcConfigurationType:
+ * @QMI_PDC_CONFIGURATION_TYPE_PLATFORM: Platform
+ * @QMI_PDC_CONFIGURATION_TYPE_SOFTWARE: Software
+ *
+ * Configuration type for change/load configuration.
+ */
+typedef enum {
+ QMI_PDC_CONFIGURATION_TYPE_PLATFORM = 0,
+ QMI_PDC_CONFIGURATION_TYPE_SOFTWARE = 1,
+} QmiPdcConfigurationType;
+
+
+#endif /* _LIBQMI_GLIB_QMI_ENUMS_PDC_H_ */
diff --git a/src/libqmi-glib/qmi-message.c b/src/libqmi-glib/qmi-message.c
index 2f58432..23afa29 100644
--- a/src/libqmi-glib/qmi-message.c
+++ b/src/libqmi-glib/qmi-message.c
@@ -45,6 +45,7 @@
#include "qmi-wds.h"
#include "qmi-nas.h"
#include "qmi-wms.h"
+#include "qmi-pdc.h"
#include "qmi-pds.h"
#include "qmi-pbm.h"
#include "qmi-uim.h"
@@ -2147,6 +2148,9 @@ qmi_message_get_printable (QmiMessage *self,
case QMI_SERVICE_WMS:
contents = __qmi_message_wms_get_printable (self, line_prefix);
break;
+ case QMI_SERVICE_PDC:
+ contents = __qmi_message_pdc_get_printable (self, line_prefix);
+ break;
case QMI_SERVICE_PDS:
contents = __qmi_message_pds_get_printable (self, line_prefix);
break;
diff --git a/src/qmicli/Makefile.am b/src/qmicli/Makefile.am
index 9583b41..90d0e53 100644
--- a/src/qmicli/Makefile.am
+++ b/src/qmicli/Makefile.am
@@ -20,6 +20,7 @@ qmicli_SOURCES = \
qmicli-wds.c \
qmicli-nas.c \
qmicli-pbm.c \
+ qmicli-pdc.c \
qmicli-uim.c \
qmicli-wms.c \
qmicli-wda.c \
diff --git a/src/qmicli/qmicli-helpers.c b/src/qmicli/qmicli-helpers.c
index 5443cad..801e7fd 100644
--- a/src/qmicli/qmicli-helpers.c
+++ b/src/qmicli/qmicli-helpers.c
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <ctype.h>
#include "qmicli-helpers.h"
@@ -315,6 +316,64 @@ qmicli_read_firmware_id_from_string (const gchar *str,
}
gboolean
+qmicli_read_binary_array_from_string (const gchar *str,
+ GArray **out) {
+ char a;
+ gsize i,len;
+ if (!str) return FALSE;
+
+ if((len = strlen(str)) & 1) return FALSE;
+
+ *out = g_array_sized_new(FALSE, TRUE, 1, len >> 1);
+ g_array_set_size(*out, len >> 1);
+
+ for (i = 0; i < len; i++) {
+ a = toupper(str[i]);
+ if (!isxdigit(a))
+ break;
+ if (isdigit(a)) {
+ a -= '0';
+ } else {
+ a = a - 'A' + 10;
+ }
+
+ if (i & 1) {
+ g_array_index(*out, gchar, i >> 1) |= a;
+ } else {
+ g_array_index(*out, gchar, i >> 1) = a<<4;
+ }
+ }
+ if (i < len) {
+ g_free(out);
+ out = NULL;
+ }
+
+ return TRUE;
+}
+
+
+gboolean
+qmicli_read_pdc_configuration_type_from_string (const gchar *str,
+ QmiPdcConfigurationType *out)
+{
+ GType type;
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+
+ type = qmi_pdc_configuration_type_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 = (QmiPdcConfigurationType)enum_value->value;
+ else
+ g_printerr ("error: invalid configuration type value given: '%s'\n", str);
+
+ g_type_class_unref (enum_class);
+ return !!enum_value;
+}
+
+gboolean
qmicli_read_radio_interface_from_string (const gchar *str,
QmiNasRadioInterface *out)
{
@@ -522,6 +581,52 @@ qmicli_read_uint_from_string (const gchar *str,
return FALSE;
}
+gboolean
+qmicli_read_uint16_from_string (const gchar *str,
+ guint16 *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_MAXUINT16) {
+ *out = (guint16)num;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+qmicli_read_uint8_from_string (const gchar *str,
+ guint8 *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_MAXUINT8) {
+ *out = (guint8)num;
+ return TRUE;
+ }
+ return FALSE;
+}
+
gchar *
qmicli_get_supported_messages_list (const guint8 *data,
gsize len)
diff --git a/src/qmicli/qmicli-helpers.h b/src/qmicli/qmicli-helpers.h
index 1a2a78c..0bf9e76 100644
--- a/src/qmicli/qmicli-helpers.h
+++ b/src/qmicli/qmicli-helpers.h
@@ -45,6 +45,10 @@ gboolean qmicli_read_enable_disable_from_string (const gchar *str,
gboolean qmicli_read_firmware_id_from_string (const gchar *str,
QmiDmsFirmwareImageType *out_type,
guint *out_index);
+gboolean qmicli_read_binary_array_from_string (const gchar *str,
+ GArray **out);
+gboolean qmicli_read_pdc_configuration_type_from_string (const gchar *str,
+ QmiPdcConfigurationType *out);
gboolean qmicli_read_radio_interface_from_string (const gchar *str,
QmiNasRadioInterface *out);
gboolean qmicli_read_net_open_flags_from_string (const gchar *str,
@@ -65,6 +69,10 @@ gboolean qmicli_read_non_empty_string (const gchar *str,
gchar **out);
gboolean qmicli_read_uint_from_string (const gchar *str,
guint *out);
+gboolean qmicli_read_uint16_from_string (const gchar *str,
+ guint16 *out);
+gboolean qmicli_read_uint8_from_string (const gchar *str,
+ guint8 *out);
gboolean qmicli_read_yes_no_from_string (const gchar *str,
gboolean *out);
diff --git a/src/qmicli/qmicli-pdc.c b/src/qmicli/qmicli-pdc.c
new file mode 100644
index 0000000..caa2386
--- /dev/null
+++ b/src/qmicli/qmicli-pdc.c
@@ -0,0 +1,1407 @@
+/* -*- 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-2015 Aleksander Morgado <aleksander@aleksander.es>
+ */
+
+#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"
+#include "qmicli-helpers.h"
+
+#define LOAD_CONFIG_CHUNK_SIZE 0x400
+
+/* Info about config */
+typedef struct {
+ GArray *id;
+ QmiPdcConfigurationType config_type;
+ guint32 token;
+ guint32 version;
+ gchar *description;
+ guint32 total_size;
+} ConfigInfo;
+
+/* Info about loading config */
+typedef struct {
+ GMappedFile *mapped_file;
+ GArray *checksum;
+ gsize offset;
+} LoadConfigFileData;
+
+/* Context */
+typedef struct {
+ QmiDevice *device;
+ QmiClientPdc *client;
+ GCancellable *cancellable;
+
+ /* local data */
+ GArray *config_list;
+ gint configs_loaded;
+ GArray *active_config_id;
+ GArray *pending_config_id;
+ gboolean ids_loaded;
+ guint list_configs_indication_id;
+ guint get_selected_config_indication_id;
+
+ LoadConfigFileData *load_config_file_data;
+ guint load_config_indication_id;
+ guint get_config_info_indication_id;
+
+ guint set_selected_config_indication_id;
+ guint activate_config_indication_id;
+ guint deactivate_config_indication_id;
+
+ guint token;
+} Context;
+static Context *ctx;
+
+/* Options */
+static gchar *list_configs_str;
+static gchar *delete_config_str;
+static gchar *activate_config_str;
+static gchar *deactivate_config_str;
+static gchar *load_config_str;
+static gboolean noop_flag;
+
+static GOptionEntry entries[] = {
+ {"pdc-list-configs", 0, 0, G_OPTION_ARG_STRING, &list_configs_str,
+ "List all configs",
+ "[(platform|software)]"},
+ {"pdc-delete-config", 0, 0, G_OPTION_ARG_STRING, &delete_config_str,
+ "Delete config",
+ "[(platform|software),ConfigId]"},
+ {"pdc-activate-config", 0, 0, G_OPTION_ARG_STRING, &activate_config_str,
+ "Activate config",
+ "[(platform|software),ConfigId]"},
+ {"pdc-deactivate-config", 0, 0, G_OPTION_ARG_STRING, &deactivate_config_str,
+ "Deactivate config",
+ "[(platform|software),ConfigId]"},
+ {"pdc-load-config", 0, 0, G_OPTION_ARG_STRING, &load_config_str,
+ "Load config to device",
+ "[Path to config]"},
+ {"pdc-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
+ "Just allocate or release a PDC client. Use with `--client-no-release-cid' and/or `--client-cid'",
+ NULL},
+ {NULL}
+};
+
+GOptionGroup *
+qmicli_pdc_get_option_group (
+ void)
+{
+ GOptionGroup *group;
+
+ group = g_option_group_new ("pdc",
+ "PDC options",
+ "Show platform device configurations options", NULL, NULL);
+ g_option_group_add_entries (group, entries);
+
+ return group;
+}
+
+gboolean
+qmicli_pdc_options_enabled (
+ void)
+{
+ static guint n_actions = 0;
+ static gboolean checked = FALSE;
+
+ if (checked)
+ return !!n_actions;
+
+ n_actions = !!list_configs_str +
+ !!delete_config_str +
+ !!activate_config_str + !!deactivate_config_str + !!load_config_str + noop_flag;
+
+ if (n_actions > 1) {
+ g_printerr ("error: too many PDC actions requested\n");
+ exit (EXIT_FAILURE);
+ }
+
+ checked = TRUE;
+ return !!n_actions;
+}
+
+static Context *
+context_new (
+ QmiDevice * device,
+ QmiClientPdc * client,
+ GCancellable * cancellable)
+{
+ Context *context;
+
+ context = g_slice_new (Context);
+ context->device = g_object_ref (device);
+ context->client = g_object_ref (client);
+ context->cancellable = g_object_ref (cancellable);
+
+ context->config_list = NULL;
+ context->configs_loaded = 0;
+ context->active_config_id = NULL;
+ context->pending_config_id = NULL;
+ context->ids_loaded = FALSE;
+ context->list_configs_indication_id = 0;
+ context->get_selected_config_indication_id = 0;
+
+ context->load_config_file_data = NULL;
+ context->load_config_indication_id = 0;
+ context->get_config_info_indication_id = 0;
+
+ context->set_selected_config_indication_id = 0;
+ context->activate_config_indication_id = 0;
+ context->deactivate_config_indication_id = 0;
+
+ context->token = 0;
+ return context;
+}
+
+static void
+context_free (
+ Context * context)
+{
+ int i;
+ ConfigInfo *current_config;
+
+ if (!context)
+ return;
+
+ if (context->config_list) {
+ for (i = 0; i < context->config_list->len; i++) {
+ current_config = &g_array_index (context->config_list, ConfigInfo, i);
+ if (current_config->description)
+ g_free (current_config->description);
+ if (current_config->id)
+ g_array_unref (current_config->id);
+ }
+ g_array_unref (context->config_list);
+ g_signal_handler_disconnect (context->client, context->list_configs_indication_id);
+ g_signal_handler_disconnect (context->client, context->get_config_info_indication_id);
+ g_signal_handler_disconnect (context->client, context->get_selected_config_indication_id);
+ }
+ if (context->load_config_file_data) {
+ g_array_unref (context->load_config_file_data->checksum);
+ g_mapped_file_unref (context->load_config_file_data->mapped_file);
+ g_slice_free (LoadConfigFileData, context->load_config_file_data);
+ g_signal_handler_disconnect (context->client, context->load_config_indication_id);
+ }
+ if (context->client)
+ g_object_unref (context->client);
+ if (context->set_selected_config_indication_id) {
+ g_signal_handler_disconnect (context->client, context->set_selected_config_indication_id);
+ }
+ if (context->activate_config_indication_id) {
+ g_signal_handler_disconnect (context->client, context->activate_config_indication_id);
+ }
+ if (context->deactivate_config_indication_id) {
+ g_signal_handler_disconnect (context->client, context->deactivate_config_indication_id);
+ }
+ g_object_unref (context->cancellable);
+ g_object_unref (context->device);
+
+ g_slice_free (Context, context);
+}
+
+static void
+operation_shutdown (
+ gboolean operation_status)
+{
+ /* Cleanup context and finish async operation */
+ context_free (ctx);
+ ctx = NULL;
+ qmicli_async_operation_done (operation_status);
+}
+
+/****************************************************************************************
+ * List configs
+ ****************************************************************************************/
+static const char *
+printable_config_type (
+ QmiPdcConfigurationType type)
+{
+ if (type == QMI_PDC_CONFIGURATION_TYPE_PLATFORM) {
+ return "Platform";
+ } else if (type == QMI_PDC_CONFIGURATION_TYPE_SOFTWARE) {
+ return "Software";
+ } else {
+ return "Unknown";
+ }
+}
+
+static char *
+printable_id (
+ GArray * id)
+{
+ if (!id) {
+ return g_strdup ("Id is NULL?");
+ } else if (id->len == 0) {
+ return g_strdup ("Id is empty");
+ } else {
+ GString *printable;
+ int i;
+
+ printable = g_string_new ("");
+ for (i = 0; i < id->len; i++) {
+ guint8 ch = g_array_index (id, guint8, i);
+
+ g_string_append_printf (printable, "%02hhX", ch);
+ }
+ return g_string_free (printable, FALSE);
+ }
+}
+
+static gboolean
+is_array_equals (
+ GArray * a,
+ GArray * b)
+{
+ int i;
+
+ if (a == NULL && b == NULL) {
+ return TRUE;
+ } else if (a == NULL || b == NULL) {
+ return FALSE;
+ } else if (a->len != b->len) {
+ return FALSE;
+ }
+ for (i = 0; i < a->len; i++) {
+ if (g_array_index (a, guint8, i) != g_array_index (b, guint8, i)) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static const
+char *status_string (
+ GArray * id)
+{
+ if (!id) {
+ return "UNKNOWN";
+ } else if (is_array_equals (id, ctx->active_config_id)) {
+ return "Active";
+ } else if (is_array_equals (id, ctx->pending_config_id)) {
+ return "Pending";
+ }
+ return "Inactive";
+}
+
+static void
+print_configs (
+ GArray * configs)
+{
+ ConfigInfo *current_config = NULL;
+ int i;
+
+ g_printf ("CONFIGS: %d\n", ctx->config_list->len);
+ for (i = 0; i < ctx->config_list->len; i++) {
+ char *id_str;
+
+ current_config = &g_array_index (ctx->config_list, ConfigInfo, i);
+
+ g_printf ("START_CONFIG\n");
+ g_printf ("Config Index : %i\n", i);
+ g_printf ("Description : %s\n", current_config->description);
+ g_printf ("Type : %s\n", printable_config_type (current_config->config_type));
+ g_printf ("Size : %u\n", current_config->total_size);
+ g_printf ("Status : %s\n", status_string (current_config->id));
+ g_printf ("Version : 0x%x\n", current_config->version);
+ id_str = printable_id (current_config->id);
+ g_printf ("ID : %s\n", id_str);
+ g_free (id_str);
+ g_printf ("END_CONFIG\n\n");
+
+ }
+}
+
+static void
+get_config_info_ready (
+ QmiClientPdc * client,
+ GAsyncResult * res)
+{
+ GError *error = NULL;
+ QmiMessagePdcGetConfigInfoOutput *output;
+
+ output = qmi_client_pdc_get_config_info_finish (client, res, &error);
+
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_pdc_get_config_info_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get config info: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_get_config_info_output_unref (output);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_pdc_get_config_info_output_unref (output);
+}
+
+static void
+get_config_info_ready_indication (
+ QmiClientPdc * client,
+ QmiIndicationPdcGetConfigInfoOutput * output)
+{
+ GError *error = NULL;
+ ConfigInfo *current_config = NULL;
+ guint32 token;
+ const gchar *description;
+ int i;
+ guint16 error_code;
+
+ if (!qmi_indication_pdc_get_config_info_output_get_indication_result (output,
+ &error_code, &error)) {
+ g_printerr ("error: couldn't get config info: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ } else if (error_code != 0) {
+ g_printerr ("error: couldn't get config info: %s\n",
+ qmi_protocol_error_get_string ((QmiProtocolError) error_code));
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_indication_pdc_get_config_info_output_get_token (output, &token, &error)) {
+ g_printerr ("error: couldn't get config info: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ for (i = 0; i < ctx->config_list->len; i++) {
+ current_config = &g_array_index (ctx->config_list, ConfigInfo, i);
+ if (current_config->token == token)
+ break;
+ }
+
+ if (!qmi_indication_pdc_get_config_info_output_get_total_size (output,
+ &current_config->total_size,
+ &error) ||
+ !qmi_indication_pdc_get_config_info_output_get_version (output,
+ &current_config->version,
+ &error) ||
+ !qmi_indication_pdc_get_config_info_output_get_description (output, &description, &error)) {
+ g_printerr ("error: couldn't get config info: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+ current_config->description = g_strdup (description);
+
+ ctx->configs_loaded++;
+ if (ctx->configs_loaded == ctx->config_list->len && ctx->ids_loaded) {
+ print_configs (ctx->config_list);
+ operation_shutdown (TRUE);
+ }
+}
+
+static void
+list_configs_ready (
+ QmiClientPdc * client,
+ GAsyncResult * res)
+{
+ GError *error = NULL;
+ QmiMessagePdcListConfigsOutput *output;
+
+ output = qmi_client_pdc_list_configs_finish (client, res, &error);
+
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_pdc_list_configs_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't list configs: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_list_configs_output_unref (output);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_pdc_list_configs_output_unref (output);
+}
+
+static void
+list_configs_ready_indication (
+ QmiClientPdc * client,
+ QmiIndicationPdcListConfigsOutput * output)
+{
+ GError *error = NULL;
+ GArray *configs = NULL;
+ int i;
+ guint16 error_code;
+
+ if (!qmi_indication_pdc_list_configs_output_get_indication_result (output, &error_code, &error)) {
+ g_printerr ("error: couldn't list configs: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ } else if (error_code != 0) {
+ g_printerr ("error: couldn't list config: %s\n",
+ qmi_protocol_error_get_string ((QmiProtocolError) error_code));
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_indication_pdc_list_configs_output_get_configs (output, &configs, &error)) {
+ g_printerr ("error: couldn't list configs: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ ctx->config_list = g_array_sized_new (FALSE, TRUE, sizeof (ConfigInfo), configs->len);
+ g_array_set_size (ctx->config_list, configs->len);
+ for (i = 0; i < configs->len; i++) {
+ ConfigInfo *current_info;
+ QmiIndicationPdcListConfigsOutputConfigsElement *element;
+ QmiConfigTypeAndId type_with_id;
+ QmiMessagePdcGetConfigInfoInput *input;
+ guint32 token = ctx->token++;
+
+ element = &g_array_index (configs, QmiIndicationPdcListConfigsOutputConfigsElement, i);
+
+ current_info = &g_array_index (ctx->config_list, ConfigInfo, i);
+
+ input = qmi_message_pdc_get_config_info_input_new ();
+ current_info->token = token;
+ current_info->id = g_array_ref (element->id);
+ current_info->config_type = element->config_type;
+ type_with_id.config_type = element->config_type;
+ type_with_id.id = current_info->id;
+ g_printerr ("Fetching config type: %d\n", current_info->config_type);
+ if (!qmi_message_pdc_get_config_info_input_set_type_with_id (input, &type_with_id, &error)) {
+ g_printerr ("error: couldn't set type with id: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+ if (!qmi_message_pdc_get_config_info_input_set_token (input, token, &error)) {
+ g_printerr ("error: couldn't set token: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ qmi_client_pdc_get_config_info (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback) get_config_info_ready, NULL);
+
+ }
+
+ g_print ("Loaded configs: %d\n", ctx->config_list->len);
+ if (ctx->configs_loaded == ctx->config_list->len && ctx->ids_loaded) {
+ print_configs (ctx->config_list);
+ operation_shutdown (TRUE);
+ }
+}
+
+static void
+get_selected_config_ready (
+ QmiClientPdc * client,
+ GAsyncResult * res)
+{
+ GError *error = NULL;
+ QmiMessagePdcGetSelectedConfigOutput *output;
+
+ output = qmi_client_pdc_get_selected_config_finish (client, res, &error);
+
+ if (!qmi_message_pdc_get_selected_config_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't get selected config: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_get_selected_config_output_unref (output);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_pdc_get_selected_config_output_unref (output);
+}
+
+static void
+get_selected_config_ready_indication (
+ QmiClientPdc * client,
+ QmiIndicationPdcGetSelectedConfigOutput * output)
+{
+ GArray *pending_id = NULL;
+ GArray *active_id = NULL;
+ GError *error = NULL;
+ guint16 error_code;
+
+ if (!qmi_indication_pdc_get_selected_config_output_get_indication_result (output,
+ &error_code,
+ &error)) {
+ g_printerr ("error: couldn't get selected config: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ } else if (error_code != 0) {
+ g_printerr ("error: couldn't get selected config: %s\n",
+ qmi_protocol_error_get_string ((QmiProtocolError) error_code));
+ }
+
+ qmi_indication_pdc_get_selected_config_output_get_pending_id (output, &pending_id, NULL);
+ qmi_indication_pdc_get_selected_config_output_get_active_id (output, &active_id, NULL);
+ if (active_id) {
+ ctx->active_config_id = g_array_ref (active_id);
+ }
+ if (pending_id) {
+ ctx->pending_config_id = g_array_ref (pending_id);
+ }
+
+ ctx->ids_loaded = TRUE;
+ if (ctx->configs_loaded == ctx->config_list->len && ctx->ids_loaded) {
+ print_configs (ctx->config_list);
+ operation_shutdown (TRUE);
+ }
+}
+
+static void
+activate_config_ready_indication (
+ QmiClientPdc * client,
+ QmiIndicationPdcActivateConfigOutput * output)
+{
+ GError *error = NULL;
+ guint16 error_code;
+
+ if (!qmi_indication_pdc_activate_config_output_get_indication_result (output,
+ &error_code, &error)) {
+ g_printerr ("error: couldn't activate config: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ } else if (error_code != 0) {
+ g_printerr ("error: couldn't activate config: %s\n",
+ qmi_protocol_error_get_string ((QmiProtocolError) error_code));
+ operation_shutdown (FALSE);
+ }
+
+ operation_shutdown (TRUE);
+}
+
+static void
+deactivate_config_ready_indication (
+ QmiClientPdc * client,
+ QmiIndicationPdcDeactivateConfigOutput * output)
+{
+ GError *error = NULL;
+ guint16 error_code;
+
+ if (!qmi_indication_pdc_deactivate_config_output_get_indication_result (output,
+ &error_code, &error)) {
+ g_printerr ("error: couldn't deactivate config: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ } else if (error_code != 0) {
+ g_printerr ("error: couldn't deactivate config: %s\n",
+ qmi_protocol_error_get_string ((QmiProtocolError) error_code));
+ operation_shutdown (FALSE);
+ }
+
+ operation_shutdown (TRUE);
+}
+
+static QmiMessagePdcListConfigsInput *
+list_configs_input_create (
+ const gchar * str)
+{
+ QmiMessagePdcListConfigsInput *input = NULL;
+ QmiPdcConfigurationType configType;
+
+ if (qmicli_read_pdc_configuration_type_from_string (str, &configType)) {
+ GError *error = NULL;
+
+ input = qmi_message_pdc_list_configs_input_new ();
+ if (!qmi_message_pdc_list_configs_input_set_config_type (input, configType, &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_list_configs_input_unref (input);
+ input = NULL;
+ }
+ if (!qmi_message_pdc_list_configs_input_set_token (input, ctx->token++, &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_list_configs_input_unref (input);
+ input = NULL;
+ }
+
+ }
+
+ return input;
+}
+
+/****************************************************************************************
+ * Activate and deactivate configs
+ ****************************************************************************************/
+static QmiConfigTypeAndId *
+parse_type_and_id (
+ const gchar * str)
+{
+ GArray *id = NULL;
+ int num_parts;
+ gchar **substrings = g_strsplit (str, ",", -1);
+ QmiPdcConfigurationType config_type;
+ QmiConfigTypeAndId *result = NULL;
+
+ for (num_parts = 0; substrings[num_parts]; num_parts++) ;
+ if (num_parts != 2) {
+ g_printerr ("Expected 2 parameters, but found: '%d'\n", num_parts);
+ g_strfreev (substrings);
+ return NULL;
+ }
+
+ if (!qmicli_read_pdc_configuration_type_from_string (substrings[0], &config_type)) {
+ g_printerr ("Incorrect id specified: %s\n", substrings[0]);
+ g_strfreev (substrings);
+ return NULL;
+ }
+
+ if (!qmicli_read_binary_array_from_string (substrings[1], &id)) {
+ g_printerr ("Incorrect config type specified: %s\n", substrings[1]);
+ g_strfreev (substrings);
+ return NULL;
+ }
+
+ result = g_slice_new0 (QmiConfigTypeAndId);
+ if (!result) {
+ g_printerr ("Error allocating QmiConfigTypeAndId\n");
+ g_strfreev (substrings);
+ g_array_unref (id);
+ return NULL;
+ }
+ result->config_type = config_type;
+ result->id = id;
+
+ return result;
+}
+
+static QmiMessagePdcGetSelectedConfigInput *
+get_selected_config_input_create (
+ const gchar * str)
+{
+ QmiMessagePdcGetSelectedConfigInput *input = NULL;
+ QmiPdcConfigurationType configType;
+
+ if (qmicli_read_pdc_configuration_type_from_string (str, &configType)) {
+ GError *error = NULL;
+
+ input = qmi_message_pdc_get_selected_config_input_new ();
+ if (!qmi_message_pdc_get_selected_config_input_set_config_type (input, configType, &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_get_selected_config_input_unref (input);
+ input = NULL;
+ }
+ if (!qmi_message_pdc_get_selected_config_input_set_token (input, ctx->token++, &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_get_selected_config_input_unref (input);
+ input = NULL;
+ }
+
+ }
+
+ return input;
+}
+
+static QmiMessagePdcDeleteConfigInput *
+delete_config_input_create (
+ const gchar * str)
+{
+ QmiMessagePdcDeleteConfigInput *input = NULL;
+ QmiConfigTypeAndId *type_and_id;
+
+ type_and_id = parse_type_and_id (str);
+
+ if (type_and_id) {
+ GError *error = NULL;
+
+ input = qmi_message_pdc_delete_config_input_new ();
+ if (!qmi_message_pdc_delete_config_input_set_config_type (input,
+ type_and_id->config_type,
+ &error) ||
+ !qmi_message_pdc_delete_config_input_set_token (input,
+ ctx->token++,
+ &error) ||
+ !qmi_message_pdc_delete_config_input_set_id (input, type_and_id->id, &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+ g_error_free (error);
+ g_free (type_and_id);
+ qmi_message_pdc_delete_config_input_unref (input);
+ input = NULL;
+ }
+ g_slice_free (QmiConfigTypeAndId, type_and_id);
+ }
+
+ return input;
+}
+
+static void
+delete_config_ready (
+ QmiClientPdc * client,
+ GAsyncResult * res)
+{
+ GError *error = NULL;
+ QmiMessagePdcDeleteConfigOutput *output;
+
+ output = qmi_client_pdc_delete_config_finish (client, res, &error);
+
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_pdc_delete_config_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't delete config: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_delete_config_output_unref (output);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ operation_shutdown (TRUE);
+ qmi_message_pdc_delete_config_output_unref (output);
+}
+
+static QmiMessagePdcActivateConfigInput *
+activate_config_input_create (
+ const gchar * str)
+{
+ QmiMessagePdcActivateConfigInput *input = NULL;
+ QmiConfigTypeAndId *type_and_id;
+
+ type_and_id = parse_type_and_id (str);
+
+ if (type_and_id) {
+ GError *error = NULL;
+
+ input = qmi_message_pdc_activate_config_input_new ();
+ if (!qmi_message_pdc_activate_config_input_set_config_type (input,
+ type_and_id->config_type,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_activate_config_input_unref (input);
+ g_free (type_and_id);
+ input = NULL;
+ }
+ if (!qmi_message_pdc_activate_config_input_set_token (input, ctx->token++, &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_activate_config_input_unref (input);
+ g_free (type_and_id);
+ input = NULL;
+ }
+ }
+
+ return input;
+}
+
+static void
+activate_config_ready (
+ QmiClientPdc * client,
+ GAsyncResult * res)
+{
+ GError *error = NULL;
+ QmiMessagePdcActivateConfigOutput *output;
+
+ output = qmi_client_pdc_activate_config_finish (client, res, &error);
+
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_pdc_activate_config_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't activate config: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_activate_config_output_unref (output);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_pdc_activate_config_output_unref (output);
+}
+
+static void
+deactivate_config_ready (
+ QmiClientPdc * client,
+ GAsyncResult * res)
+{
+ GError *error = NULL;
+ QmiMessagePdcDeactivateConfigOutput *output;
+
+ output = qmi_client_pdc_deactivate_config_finish (client, res, &error);
+
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_pdc_deactivate_config_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't activate config: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_deactivate_config_output_unref (output);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_pdc_deactivate_config_output_unref (output);
+}
+
+static void
+set_selected_config_ready_indication_activation (
+ QmiClientPdc * client,
+ QmiIndicationPdcSetSelectedConfigOutput * output)
+{
+ GError *error = NULL;
+ QmiMessagePdcActivateConfigInput *input;
+ guint16 error_code;
+
+ if (!qmi_indication_pdc_set_selected_config_output_get_indication_result (output,
+ &error_code,
+ &error)) {
+ g_printerr ("error: couldn't set selected config: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ } else if (error_code != 0) {
+ g_printerr ("error: couldn't set selected config: %s\n",
+ qmi_protocol_error_get_string ((QmiProtocolError) error_code));
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ input = activate_config_input_create (activate_config_str);
+ if (!input) {
+ operation_shutdown (FALSE);
+ return;
+ }
+ qmi_client_pdc_activate_config (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback) activate_config_ready, NULL);
+ qmi_message_pdc_activate_config_input_unref (input);
+}
+
+static void
+set_selected_config_ready (
+ QmiClientPdc * client,
+ GAsyncResult * res)
+{
+ GError *error = NULL;
+ QmiMessagePdcSetSelectedConfigOutput *output;
+
+ output = qmi_client_pdc_set_selected_config_finish (client, res, &error);
+
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_pdc_set_selected_config_output_unref (output);
+}
+
+static QmiMessagePdcDeactivateConfigInput *
+deactivate_config_input_create (
+ const gchar * str)
+{
+ QmiMessagePdcDeactivateConfigInput *input = NULL;
+ QmiConfigTypeAndId *type_and_id;
+
+ type_and_id = parse_type_and_id (str);
+
+ if (type_and_id) {
+ GError *error = NULL;
+
+ input = qmi_message_pdc_deactivate_config_input_new ();
+ if (!qmi_message_pdc_deactivate_config_input_set_config_type (input,
+ type_and_id->config_type,
+ &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_deactivate_config_input_unref (input);
+ g_free (type_and_id);
+ input = NULL;
+ }
+ if (!qmi_message_pdc_deactivate_config_input_set_token (input, ctx->token++, &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_deactivate_config_input_unref (input);
+ g_free (type_and_id);
+ input = NULL;
+ }
+ }
+
+ return input;
+}
+
+static void
+set_selected_config_ready_indication_deactivation (
+ QmiClientPdc * client,
+ QmiIndicationPdcSetSelectedConfigOutput * output)
+{
+ GError *error = NULL;
+ QmiMessagePdcDeactivateConfigInput *input;
+ guint16 error_code;
+
+ if (!qmi_indication_pdc_set_selected_config_output_get_indication_result (output,
+ &error_code,
+ &error)) {
+ g_printerr ("error: couldn't set selected config: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ } else if (error_code != 0) {
+ g_printerr ("error: couldn't set selected config: %s\n",
+ qmi_protocol_error_get_string ((QmiProtocolError) error_code));
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ input = deactivate_config_input_create (activate_config_str);
+ if (!input) {
+ operation_shutdown (FALSE);
+ return;
+ }
+ qmi_client_pdc_deactivate_config (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback) deactivate_config_ready, NULL);
+ qmi_message_pdc_deactivate_config_input_unref (input);
+}
+
+static QmiMessagePdcSetSelectedConfigInput *
+set_selected_config_input_create (
+ const gchar * str)
+{
+ QmiMessagePdcSetSelectedConfigInput *input = NULL;
+ QmiConfigTypeAndId *type_and_id;
+
+ type_and_id = parse_type_and_id (str);
+
+ if (type_and_id) {
+ GError *error = NULL;
+
+ input = qmi_message_pdc_set_selected_config_input_new ();
+ if (!qmi_message_pdc_set_selected_config_input_set_type_with_id (input,
+ type_and_id, &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+ g_error_free (error);
+ g_free (type_and_id);
+ qmi_message_pdc_set_selected_config_input_unref (input);
+ input = NULL;
+ }
+ if (!qmi_message_pdc_set_selected_config_input_set_token (input, ctx->token++, &error)) {
+ g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+ g_error_free (error);
+ g_free (type_and_id);
+ qmi_message_pdc_set_selected_config_input_unref (input);
+ input = NULL;
+ }
+
+ }
+
+ return input;
+}
+
+/****************************************************************************************
+ * Load config
+ ****************************************************************************************/
+
+static LoadConfigFileData *
+load_config_file_from_string (
+ const gchar * str)
+{
+ GError *error = NULL;
+ GMappedFile *mapped_file;
+ LoadConfigFileData *data;
+ guchar *file_contents;
+ GChecksum *checksum;
+ gsize file_size;
+ gsize hash_size;
+
+ if (!(mapped_file = g_mapped_file_new (str, FALSE, &error))) {
+ g_printerr ("error: couldn't map config file: '%s'\n", error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ if (!(file_contents = (guchar *) g_mapped_file_get_contents (mapped_file))) {
+ g_printerr ("error: couldn't get file content\n");
+ g_mapped_file_unref (mapped_file);
+ return NULL;
+ }
+ file_size = g_mapped_file_get_length (mapped_file);
+ hash_size = g_checksum_type_get_length (G_CHECKSUM_SHA1);
+ g_info ("File opened: %lu, %lu", file_size, hash_size);
+ checksum = g_checksum_new (G_CHECKSUM_SHA1);
+ g_checksum_update (checksum, file_contents, file_size);
+
+ data = g_slice_new (LoadConfigFileData);
+ data->mapped_file = mapped_file;
+ data->checksum = g_array_sized_new (FALSE, FALSE, sizeof (guint8), hash_size);
+ g_array_set_size (data->checksum, hash_size);
+ data->offset = 0;
+ g_checksum_get_digest (checksum, &g_array_index (data->checksum, guint8, 0), &hash_size);
+ g_info ("Checksum: %lu, %lu", file_size, hash_size);
+
+ return data;
+}
+
+static QmiMessagePdcLoadConfigInput *
+load_config_input_create_chunk (
+ LoadConfigFileData * config_file)
+{
+ QmiMessagePdcLoadConfigInput *input = NULL;
+
+ if (config_file) {
+ GError *error = NULL;
+ GArray *chunk;
+ gsize full_size;
+ gsize chunk_size;
+ guchar *file_content;
+
+ input = qmi_message_pdc_load_config_input_new ();
+ if (!qmi_message_pdc_load_config_input_set_token (input, ctx->token++, &error)) {
+ g_printerr ("error: couldn't set token: '%s'\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_load_config_input_unref (input);
+ input = NULL;
+ }
+
+ chunk = g_array_new (FALSE, FALSE, 1);
+ full_size = g_mapped_file_get_length (config_file->mapped_file);
+ chunk_size = config_file->offset + LOAD_CONFIG_CHUNK_SIZE > full_size ?
+ full_size - config_file->offset : LOAD_CONFIG_CHUNK_SIZE;
+ file_content = (guchar *) g_mapped_file_get_contents (config_file->mapped_file);
+ g_array_append_vals (chunk, file_content + config_file->offset, chunk_size);
+ g_print ("Uploaded %lu of %lu\n", config_file->offset, full_size);
+
+ if (!qmi_message_pdc_load_config_input_set_config_chunk (input,
+ QMI_PDC_CONFIGURATION_TYPE_SOFTWARE,
+ config_file->checksum,
+ g_mapped_file_get_length
+ (config_file->mapped_file), chunk,
+ &error)) {
+ g_printerr ("error: couldn't set chunk: '%s'\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_load_config_input_unref (input);
+ input = NULL;
+ } else {
+ config_file->offset += chunk_size;
+ }
+ }
+ return input;
+}
+
+static QmiMessagePdcLoadConfigInput *
+load_config_input_create (
+ const gchar * str)
+{
+ LoadConfigFileData *config_file;
+ QmiMessagePdcLoadConfigInput *input = NULL;
+
+ if ((config_file = load_config_file_from_string (str))) {
+ if ((input = load_config_input_create_chunk (config_file))) {
+ ctx->load_config_file_data = config_file;
+ }
+ }
+
+ return input;
+}
+
+static void
+load_config_ready (
+ QmiClientPdc * client,
+ GAsyncResult * res)
+{
+ GError *error = NULL;
+ QmiMessagePdcLoadConfigOutput *output;
+
+ output = qmi_client_pdc_load_config_finish (client, res, &error);
+
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_pdc_load_config_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't load config: %s\n", error->message);
+ g_error_free (error);
+ qmi_message_pdc_load_config_output_unref (output);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ qmi_message_pdc_load_config_output_unref (output);
+}
+
+static void
+load_config_ready_indication (
+ QmiClientPdc * client,
+ QmiIndicationPdcLoadConfigOutput * output)
+{
+ GError *error = NULL;
+ QmiMessagePdcLoadConfigInput *input;
+ gboolean frame_reset;
+ guint32 remaining_size;
+ guint16 error_code;
+
+ if (!qmi_indication_pdc_load_config_output_get_indication_result (output, &error_code, &error)) {
+ g_printerr ("error: couldn't load config: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ } else if (error_code != 0) {
+ g_printerr ("error: couldn't load config: %s\n",
+ qmi_protocol_error_get_string ((QmiProtocolError) error_code));
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ if (qmi_indication_pdc_load_config_output_get_frame_reset (output, &frame_reset, &error)) {
+ if (frame_reset) {
+ g_printerr ("error: frame reset requested\n");
+ operation_shutdown (FALSE);
+ return;
+ }
+ } else {
+ g_error_free (error);
+ error = NULL;
+ }
+
+ if (!qmi_indication_pdc_load_config_output_get_remaining_size (output, &remaining_size, &error)) {
+ g_printerr ("error: couldn't load config: %s\n", error->message);
+ g_error_free (error);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ g_print ("Remaining %d\n", remaining_size);
+ if (remaining_size > 0) {
+ g_print ("Loading next\n");
+ input = load_config_input_create_chunk (ctx->load_config_file_data);
+ if (!input) {
+ g_printerr ("Input is null\n");
+ operation_shutdown (FALSE);
+ return;
+ }
+ qmi_client_pdc_load_config (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback) load_config_ready, NULL);
+ qmi_message_pdc_load_config_input_unref (input);
+ } else {
+ operation_shutdown (TRUE);
+ }
+}
+
+/****************************************************************************************
+ * Common logic
+ ****************************************************************************************/
+
+static gboolean
+noop_cb (
+ gpointer unused)
+{
+ operation_shutdown (TRUE);
+ return FALSE;
+}
+
+void
+qmicli_pdc_run (
+ QmiDevice * device,
+ QmiClientPdc * client,
+ GCancellable * cancellable)
+{
+ /* Initialize context */
+ ctx = context_new (device, client, cancellable);
+
+ /* Request to get all configs */
+ if (list_configs_str) {
+ QmiMessagePdcListConfigsInput *input;
+ QmiMessagePdcGetSelectedConfigInput *get_selected_config_input;
+
+ g_debug ("Listing configs asynchroniously...");
+ ctx->list_configs_indication_id = g_signal_connect (client,
+ "list-configs",
+ G_CALLBACK
+ (list_configs_ready_indication), NULL);
+ ctx->get_selected_config_indication_id =
+ g_signal_connect (client, "get-selected-config",
+ G_CALLBACK (get_selected_config_ready_indication), NULL);
+ ctx->get_config_info_indication_id =
+ g_signal_connect (client, "get-config-info",
+ G_CALLBACK (get_config_info_ready_indication), NULL);
+ input = list_configs_input_create (list_configs_str);
+ if (!input) {
+ operation_shutdown (FALSE);
+ return;
+ }
+ get_selected_config_input = get_selected_config_input_create (list_configs_str);
+ if (!get_selected_config_input) {
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ qmi_client_pdc_list_configs (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback) list_configs_ready, NULL);
+ qmi_message_pdc_list_configs_input_unref (input);
+
+ qmi_client_pdc_get_selected_config (ctx->client,
+ get_selected_config_input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback) get_selected_config_ready, NULL);
+ qmi_message_pdc_get_selected_config_input_unref (get_selected_config_input);
+ return;
+ }
+
+ /* Request to delete config */
+ if (delete_config_str) {
+ QmiMessagePdcDeleteConfigInput *input;
+
+ g_debug ("Deleting config asynchroniously...");
+ input = delete_config_input_create (delete_config_str);
+ if (!input) {
+ operation_shutdown (FALSE);
+ return;
+ }
+ qmi_client_pdc_delete_config (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback) delete_config_ready, NULL);
+ qmi_message_pdc_delete_config_input_unref (input);
+ return;
+ }
+
+ /* Request to activate config */
+ if (activate_config_str) {
+ QmiMessagePdcSetSelectedConfigInput *input;
+
+ g_debug ("Activating config asynchroniously...");
+ input = set_selected_config_input_create (activate_config_str);
+ if (!input) {
+ operation_shutdown (FALSE);
+ return;
+ }
+ ctx->set_selected_config_indication_id =
+ g_signal_connect (client,
+ "set-selected-config",
+ G_CALLBACK (set_selected_config_ready_indication_activation), NULL);
+ ctx->activate_config_indication_id = g_signal_connect (client,
+ "activate-config",
+ G_CALLBACK
+ (activate_config_ready_indication),
+ NULL);
+ qmi_client_pdc_set_selected_config (ctx->client, input, 10, ctx->cancellable,
+ (GAsyncReadyCallback) set_selected_config_ready, NULL);
+ qmi_message_pdc_set_selected_config_input_unref (input);
+ return;
+ }
+
+ /* Request to deactivate config */
+ if (deactivate_config_str) {
+ QmiMessagePdcSetSelectedConfigInput *input;
+
+ g_debug ("Deactivating config asynchroniously...");
+ input = set_selected_config_input_create (activate_config_str);
+ if (!input) {
+ operation_shutdown (FALSE);
+ return;
+ }
+ ctx->set_selected_config_indication_id =
+ g_signal_connect (client,
+ "set-selected-config",
+ G_CALLBACK (set_selected_config_ready_indication_deactivation), NULL);
+ ctx->deactivate_config_indication_id = g_signal_connect (client,
+ "deactivate-config",
+ G_CALLBACK
+ (deactivate_config_ready_indication),
+ NULL);
+ qmi_client_pdc_set_selected_config (ctx->client, input, 10, ctx->cancellable,
+ (GAsyncReadyCallback) set_selected_config_ready, NULL);
+ qmi_message_pdc_set_selected_config_input_unref (input);
+ return;
+ }
+
+ if (load_config_str) {
+ QmiMessagePdcLoadConfigInput *input;
+
+ g_debug ("Loading config asynchroniously...");
+ input = load_config_input_create (load_config_str);
+ if (!input) {
+ operation_shutdown (FALSE);
+ return;
+ }
+ ctx->load_config_indication_id = g_signal_connect (client,
+ "load-config",
+ G_CALLBACK
+ (load_config_ready_indication), NULL);
+ qmi_client_pdc_load_config (ctx->client, input, 10, ctx->cancellable,
+ (GAsyncReadyCallback) load_config_ready, NULL);
+ qmi_message_pdc_load_config_input_unref (input);
+ 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
index 705d9bc..2208609 100644
--- a/src/qmicli/qmicli.c
+++ b/src/qmicli/qmicli.c
@@ -326,6 +326,9 @@ allocate_client_ready (QmiDevice *dev,
case QMI_SERVICE_PBM:
qmicli_pbm_run (dev, QMI_CLIENT_PBM (client), cancellable);
return;
+ case QMI_SERVICE_PDC:
+ qmicli_pdc_run (dev, QMI_CLIENT_PDC (client), cancellable);
+ return;
case QMI_SERVICE_UIM:
qmicli_uim_run (dev, QMI_CLIENT_UIM (client), cancellable);
return;
@@ -660,6 +663,12 @@ parse_actions (void)
actions_enabled++;
}
+ /* PDC options? */
+ if (qmicli_pdc_options_enabled ()) {
+ service = QMI_SERVICE_PDC;
+ actions_enabled++;
+ }
+
/* UIM options? */
if (qmicli_uim_options_enabled ()) {
service = QMI_SERVICE_UIM;
@@ -720,6 +729,8 @@ int main (int argc, char **argv)
g_option_context_add_group (context,
qmicli_pbm_get_option_group ());
g_option_context_add_group (context,
+ qmicli_pdc_get_option_group ());
+ g_option_context_add_group (context,
qmicli_uim_get_option_group ());
g_option_context_add_group (context,
qmicli_wms_get_option_group ());
diff --git a/src/qmicli/qmicli.h b/src/qmicli/qmicli.h
index 6ba7ec9..2cc7d28 100644
--- a/src/qmicli/qmicli.h
+++ b/src/qmicli/qmicli.h
@@ -54,6 +54,13 @@ void qmicli_pbm_run (QmiDevice *device,
QmiClientPbm *client,
GCancellable *cancellable);
+/* PBM group */
+GOptionGroup *qmicli_pdc_get_option_group (void);
+gboolean qmicli_pdc_options_enabled (void);
+void qmicli_pdc_run (QmiDevice *device,
+ QmiClientPdc *client,
+ GCancellable *cancellable);
+
/* UIM group */
GOptionGroup *qmicli_uim_get_option_group (void);
gboolean qmicli_uim_options_enabled (void);