Merge remote-tracking branch 'cros/upstream' into 'cros/master'
Change-Id: Id4ea6235247ff73f1378549a3078380332b83682
diff --git a/TODO b/TODO
index 7f089f7..d9b8d27 100644
--- a/TODO
+++ b/TODO
@@ -25,14 +25,6 @@
detailed sub-types, e.g.: the 'QmiNasRadioTechnologyPreference' flags type,
where the first two bits define the type of the next ones.
- * dms: Support 'Preferred Roaming List' TLV (0x13) in DMS/"Activate Manual".
- This TLV is based on an array of raw binary data which can be passed to the
- device over multiple messages, using a sequence number to identify each
- passed chunk. Probably not worth handling this specific case in qmi-codegen.
- Also, sending such a message should trigger internally multiple messages
- being sent automatically, not just one.
-
- * qmicli: Implement `--dms-activate-manual'.
* qmicli: Implement `--dms-set-time'.
* qmicli: Implement `--dms-get-alt-net-config'.
* qmicli: Implement `--dms-set-alt-net-config'.
diff --git a/build-aux/qmi-codegen/VariableArray.py b/build-aux/qmi-codegen/VariableArray.py
index c5aadf9..c402da1 100644
--- a/build-aux/qmi-codegen/VariableArray.py
+++ b/build-aux/qmi-codegen/VariableArray.py
@@ -72,6 +72,13 @@
default_array_size = { 'format' : 'guint8' }
self.array_size_element = VariableFactory.create_variable(default_array_size, '', self.container_type)
+ # Load variable type for the sequence prefix
+ if 'sequence-prefix-format' in dictionary:
+ sequence = { 'format' : dictionary['sequence-prefix-format'] }
+ self.array_sequence_element = VariableFactory.create_variable(sequence, '', self.container_type)
+ else:
+ self.array_sequence_element = ''
+
"""
Emit the type for the array element
@@ -150,15 +157,33 @@
f.write(string.Template(template).substitute(translations))
else:
translations['array_size_element_format'] = self.array_size_element.public_format
-
template = (
- '${lp} ${array_size_element_format} ${common_var_prefix}_n_items;\n'
+ '${lp} ${array_size_element_format} ${common_var_prefix}_n_items;\n')
+
+ if self.array_sequence_element != '':
+ translations['array_sequence_element_format'] = self.array_sequence_element.public_format
+ template += (
+ '${lp} ${array_sequence_element_format} ${common_var_prefix}_sequence;\n')
+
+ template += (
'\n'
'${lp} /* Read number of items in the array */\n')
f.write(string.Template(template).substitute(translations))
-
self.array_size_element.emit_buffer_read(f, line_prefix + ' ', common_var_prefix + '_n_items', buffer_name, buffer_len)
+ if self.array_sequence_element != '':
+ template = (
+ '\n'
+ '${lp} /* Read sequence in the array */\n')
+ f.write(string.Template(template).substitute(translations))
+ self.array_size_element.emit_buffer_read(f, line_prefix + ' ', common_var_prefix + '_sequence', buffer_name, buffer_len)
+
+ template = (
+ '\n'
+ '${lp} ${variable_name}_sequence = ${common_var_prefix}_sequence;\n')
+ f.write(string.Template(template).substitute(translations))
+
+
template = (
'\n'
'${lp} ${variable_name} = g_array_sized_new (\n'
@@ -202,15 +227,15 @@
template = (
'${lp}{\n'
- '${lp} guint ${common_var_prefix}_i;\n')
+ '${lp} guint ${common_var_prefix}_i;\n'
+ '\n')
f.write(string.Template(template).substitute(translations))
if self.fixed_size:
translations['fixed_size'] = self.fixed_size
template = (
- '${lp} guint16 ${common_var_prefix}_n_items = ${fixed_size};\n'
- '\n')
+ '${lp} guint16 ${common_var_prefix}_n_items = ${fixed_size};\n')
f.write(string.Template(template).substitute(translations))
else:
translations['array_size_element_format'] = self.array_size_element.public_format
@@ -228,13 +253,27 @@
'${lp} const guint8 *${common_var_prefix}_aux_buffer = &${buffer_name}[${variable_name}];\n'
'${lp} guint16 ${common_var_prefix}_aux_buffer_len = ${buffer_len} - ${variable_name};\n'
'\n'
- '${lp} ${variable_name} += ${array_size_element_size};\n'
- '\n')
+ '${lp} ${variable_name} += ${array_size_element_size};\n')
+
+ if self.array_sequence_element != '':
+ if self.array_sequence_element.public_format == 'guint8':
+ translations['array_sequence_element_size'] = '1'
+ elif self.array_sequence_element.public_format == 'guint16':
+ translations['array_sequence_element_size'] = '2'
+ elif self.array_sequence_element.public_format == 'guint32':
+ translations['array_sequence_element_size'] = '4'
+ else:
+ translations['array_sequence_element_size'] = '0'
+ template += (
+ '\n'
+ '${lp} ${variable_name} += ${array_sequence_element_size};\n')
+
f.write(string.Template(template).substitute(translations))
self.array_size_element.emit_buffer_read(f, line_prefix + ' ', common_var_prefix + '_n_items', common_var_prefix + '_aux_buffer', common_var_prefix + '_aux_buffer_len')
template = (
+ '\n'
'${lp} for (${common_var_prefix}_i = 0; ${common_var_prefix}_i < ${common_var_prefix}_n_items; ${common_var_prefix}_i++) {\n'
'\n')
f.write(string.Template(template).substitute(translations))
@@ -275,6 +314,10 @@
self.array_size_element.emit_buffer_write(f, line_prefix + ' ', common_var_prefix + '_n_items', buffer_name, buffer_len)
+ if self.array_sequence_element != '':
+ self.array_sequence_element.emit_buffer_write(f, line_prefix + ' ', variable_name + '_sequence', buffer_name, buffer_len)
+
+
template = (
'\n'
'${lp} for (${common_var_prefix}_i = 0; ${common_var_prefix}_i < ${variable_name}->len; ${common_var_prefix}_i++) {\n')
@@ -314,15 +357,31 @@
f.write(string.Template(template).substitute(translations))
else:
translations['array_size_element_format'] = self.array_size_element.public_format
-
template = (
- '${lp} ${array_size_element_format} ${common_var_prefix}_n_items;\n'
+ '${lp} ${array_size_element_format} ${common_var_prefix}_n_items;\n')
+
+ if self.array_sequence_element != '':
+ translations['array_sequence_element_format'] = self.array_sequence_element.public_format
+ template += (
+ '${lp} ${array_sequence_element_format} ${common_var_prefix}_sequence;\n')
+
+ template += (
'\n'
'${lp} /* Read number of items in the array */\n')
f.write(string.Template(template).substitute(translations))
-
self.array_size_element.emit_buffer_read(f, line_prefix + ' ', common_var_prefix + '_n_items', buffer_name, buffer_len)
+ if self.array_sequence_element != '':
+ template = (
+ '\n'
+ '${lp} /* Read sequence */\n')
+ f.write(string.Template(template).substitute(translations))
+ self.array_sequence_element.emit_buffer_read(f, line_prefix + ' ', common_var_prefix + '_sequence', buffer_name, buffer_len)
+ template = (
+ '\n'
+ '${lp} g_string_append_printf (${printable}, "[[Seq:%u]] ", ${common_var_prefix}_sequence);\n')
+ f.write(string.Template(template).substitute(translations))
+
template = (
'\n'
'${lp} g_string_append (${printable}, "{");\n'
@@ -349,7 +408,13 @@
translations = { 'lp' : line_prefix,
'name' : variable_name }
- template = (
+ template = ''
+ if self.array_sequence_element != '':
+ translations['array_sequence_element_format'] = self.array_sequence_element.public_format
+ template += (
+ '${lp}${array_sequence_element_format} ${name}_sequence;\n')
+
+ template += (
'${lp}GArray *${name};\n')
return string.Template(template).substitute(translations)
@@ -361,7 +426,13 @@
translations = { 'lp' : line_prefix,
'name' : variable_name }
- template = (
+ template = ''
+ if self.array_sequence_element != '':
+ translations['array_sequence_element_format'] = self.array_sequence_element.public_format
+ template += (
+ '${lp}${array_sequence_element_format} *${name}_sequence,\n')
+
+ template += (
'${lp}GArray **${name},\n')
return string.Template(template).substitute(translations)
@@ -374,7 +445,12 @@
'public_array_element_format' : self.array_element.public_format,
'name' : variable_name }
- template = (
+ template = ''
+ if self.array_sequence_element != '':
+ template += (
+ '${lp}@${name}_sequence: a placeholder for the output sequence number, or %NULL if not required.\n')
+
+ template += (
'${lp}@${name}: a placeholder for the output #GArray of #${public_array_element_format} elements, or %NULL if not required. Do not free it, it is owned by @self.\n')
return string.Template(template).substitute(translations)
@@ -387,15 +463,21 @@
'from' : variable_name_from,
'to' : variable_name_to }
+ template = ''
+ if self.array_sequence_element != '':
+ template += (
+ '${lp}if (${to}_sequence)\n'
+ '${lp} *${to}_sequence = ${from}_sequence;\n')
+
if to_is_reference:
- template = (
+ template += (
'${lp}if (${to})\n'
'${lp} *${to} = ${from};\n')
- return string.Template(template).substitute(translations)
else:
- template = (
+ template += (
'${lp}${to} = ${from};\n')
- return string.Template(template).substitute(translations)
+
+ return string.Template(template).substitute(translations)
"""
@@ -405,7 +487,13 @@
translations = { 'lp' : line_prefix,
'name' : variable_name }
- template = (
+ template = ''
+ if self.array_sequence_element != '':
+ translations['array_sequence_element_format'] = self.array_sequence_element.public_format
+ template += (
+ '${lp}${array_sequence_element_format} ${name}_sequence,\n')
+
+ template += (
'${lp}GArray *${name},\n')
return string.Template(template).substitute(translations)
@@ -418,7 +506,12 @@
'public_array_element_format' : self.array_element.public_format,
'name' : variable_name }
- template = (
+ template = ''
+ if self.array_sequence_element != '':
+ template += (
+ '${lp}@${name}_sequence: the sequence number.\n')
+
+ template += (
'${lp}@${name}: a #GArray of #${public_array_element_format} elements. A new reference to @${name} will be taken.\n')
return string.Template(template).substitute(translations)
@@ -431,7 +524,12 @@
'from' : variable_name_from,
'to' : variable_name_to }
- template = (
+ template = ''
+ if self.array_sequence_element != '':
+ template += (
+ '${lp}${to}_sequence = ${from}_sequence;\n')
+
+ template += (
'${lp}if (${to})\n'
'${lp} g_array_unref (${to});\n'
'${lp}${to} = g_array_ref (${from});\n')
@@ -446,7 +544,12 @@
'public_array_element_format' : self.array_element.public_format,
'name' : variable_name }
- template = (
+ template = ''
+ if self.array_sequence_element != '':
+ template += (
+ '${lp}@${name}_sequence: the sequence number.\n')
+
+ template += (
'${lp}@${name}: a #GArray of #${public_array_element_format} elements.\n')
return string.Template(template).substitute(translations)
diff --git a/build-aux/qmi-codegen/utils.py b/build-aux/qmi-codegen/utils.py
index e9d4ea1..cb12962 100644
--- a/build-aux/qmi-codegen/utils.py
+++ b/build-aux/qmi-codegen/utils.py
@@ -76,8 +76,8 @@
else:
template += (
"#include \"qmi-enums-private.h\"\n")
- # CTL, WDS, WMS and PDS don't have flags64
- if service != 'CTL' and service != 'WDS' and service != 'WMS' and service != 'PDS':
+ # CTL, WDS, WMS, PDS and PBM don't have flags64
+ if service != 'CTL' and service != 'WDS' and service != 'WMS' and service != 'PDS' and service != 'PBM':
template += (
"#include \"qmi-flags64-${service}.h\"\n")
template += (
diff --git a/cli/Makefile.am b/cli/Makefile.am
index fddf664..cc6e839 100644
--- a/cli/Makefile.am
+++ b/cli/Makefile.am
@@ -18,7 +18,8 @@
qmicli-helpers.h \
qmicli-dms.c \
qmicli-wds.c \
- qmicli-nas.c
+ qmicli-nas.c \
+ qmicli-pbm.c
qmicli_LDADD = \
$(QMICLI_LIBS) \
diff --git a/cli/qmicli-dms.c b/cli/qmicli-dms.c
index e94405b..0ad64a6 100644
--- a/cli/qmicli-dms.c
+++ b/cli/qmicli-dms.c
@@ -1716,6 +1716,7 @@
QmiMessageDmsActivateManualInput *input;
gchar **split;
GError *error = NULL;
+ gulong split_1_int;
split = g_strsplit (str, ",", -1);
if (g_strv_length (split) != 4) {
@@ -1724,11 +1725,18 @@
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],
- split[1],
+ (guint16)split_1_int,
split[2],
split[3],
&error)) {
diff --git a/cli/qmicli-pbm.c b/cli/qmicli-pbm.c
new file mode 100644
index 0000000..ca36068
--- /dev/null
+++ b/cli/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/cli/qmicli.c b/cli/qmicli.c
index 43401a5..1a19380 100644
--- a/cli/qmicli.c
+++ b/cli/qmicli.c
@@ -46,6 +46,7 @@
/* 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;
@@ -60,6 +61,10 @@
"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]"
@@ -191,7 +196,8 @@
if (checked)
return !!n_actions;
- n_actions = !!device_set_instance_id_str;
+ 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");
@@ -283,6 +289,9 @@
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;
default:
g_assert_not_reached ();
}
@@ -370,6 +379,57 @@
}
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)
{
@@ -386,6 +446,8 @@
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);
}
@@ -450,6 +512,12 @@
actions_enabled++;
}
+ /* PBM options? */
+ if (qmicli_pbm_options_enabled ()) {
+ service = QMI_SERVICE_PBM;
+ actions_enabled++;
+ }
+
/* Cannot mix actions from different services */
if (actions_enabled > 1) {
g_printerr ("error: cannot execute multiple actions of different services\n");
@@ -483,6 +551,8 @@
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_main_entries (context, main_entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error)) {
g_printerr ("error: %s\n",
diff --git a/cli/qmicli.h b/cli/qmicli.h
index 2517b7f..53a9c9e 100644
--- a/cli/qmicli.h
+++ b/cli/qmicli.h
@@ -47,4 +47,11 @@
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);
+
#endif /* __QMICLI_H__ */
diff --git a/data/Makefile.am b/data/Makefile.am
index 458dda5..d04a0d4 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -7,4 +7,5 @@
qmi-service-wds.json \
qmi-service-nas.json \
qmi-service-wms.json \
- qmi-service-pds.json
+ qmi-service-pds.json \
+ qmi-service-pbm.json
diff --git a/data/qmi-service-dms.json b/data/qmi-service-dms.json
index ad74755..1e48455 100644
--- a/data/qmi-service-dms.json
+++ b/data/qmi-service-dms.json
@@ -586,27 +586,40 @@
"contents" : [ { "name" : "Service Programming Code",
"format" : "string",
"fixed-size" : "6" },
- { "name" : "System Identification Number",
- "format" : "string",
- "fixed-size" : "2" },
+ { "name" : "System Identification Number",
+ "format" : "guint16" },
{ "name" : "Mobile Directory Number",
"format" : "string",
"max-size" : "15" },
{ "name" : "Mobile Identification Number",
"format" : "string",
"max-size" : "15" } ] },
- { "name" : "MN HA key",
- "id" : "0x11",
+ { "name" : "MN HA key",
+ "id" : "0x11",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "string",
+ "max-size" : "16",
+ "size-prefix-format" : "guint8" },
+ { "name" : "MN AAA key",
+ "id" : "0x12",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "string",
+ "max-size" : "16",
+ "size-prefix-format" : "guint8" },
+ { "name" : "PRL",
+ "id" : "0x13",
"mandatory" : "no",
"type" : "TLV",
- "format" : "string",
- "max-size" : "16" },
- { "name" : "MN AAA key",
- "id" : "0x12",
- "mandatory" : "no",
- "type" : "TLV",
- "format" : "string",
- "max-size" : "16" } ],
+ "format" : "sequence",
+ "contents" : [ { "name" : "PRL total length",
+ "format" : "guint16" },
+ { "name" : "PRL segment",
+ "format" : "array",
+ "size-prefix-format" : "guint16",
+ "sequence-prefix-format" : "guint8",
+ "array-element" : { "format" : "guint8" } } ] } ],
"output" : [ { "common-ref" : "Operation Result" } ] },
// *********************************************************************************
@@ -684,15 +697,14 @@
"service" : "DMS",
"id" : "0x0038",
"version" : "1.6",
- "input" : [ { "name" : "User Data",
- "id" : "0x01",
- "mandatory" : "yes",
- "type" : "TLV",
- "format" : "array",
- "size-prefix-format" : "guint16",
- "array-element" : { "format" : "guint8" },
- "prerequisites" : [ { "common-ref" : "Success" } ] } ],
- "output" : [ { "common-ref" : "Operation Result" } ] },
+ "input" : [ { "name" : "User Data",
+ "id" : "0x01",
+ "mandatory" : "yes",
+ "type" : "TLV",
+ "format" : "array",
+ "size-prefix-format" : "guint16",
+ "array-element" : { "format" : "guint8" } } ],
+ "output" : [ { "common-ref" : "Operation Result" } ] },
// *********************************************************************************
{ "name" : "Read ERI File",
@@ -878,7 +890,7 @@
"format" : "guint64",
"public-format" : "QmiDmsBandCapability",
"prerequisites": [ { "common-ref" : "Success" } ] },
- { "name" : "LTE Band Capability",
+ { "name" : "LTE Band Capability",
"id" : "0x10",
"mandatory" : "no",
"type" : "TLV",
diff --git a/data/qmi-service-pbm.json b/data/qmi-service-pbm.json
new file mode 100644
index 0000000..9296aea
--- /dev/null
+++ b/data/qmi-service-pbm.json
@@ -0,0 +1,298 @@
+
+[
+ // *********************************************************************************
+ { "name" : "PBM",
+ "type" : "Service" },
+
+ // *********************************************************************************
+ { "name" : "QMI Client PBM",
+ "type" : "Client" },
+
+ // *********************************************************************************
+ { "name" : "QMI Message PBM",
+ "type" : "Message-ID-Enum" },
+
+ // *********************************************************************************
+ { "name" : "Indication Register",
+ "type" : "Message",
+ "service" : "PBM",
+ "id" : "0x0001",
+ "version" : "1.0",
+ "input" : [ { "name" : "Event Registration Mask",
+ "id" : "0x01",
+ "mandatory" : "yes",
+ "type" : "TLV",
+ "format" : "guint32",
+ "public-format" : "QmiPbmEventRegistrationFlag" } ],
+ "output" : [ { "common-ref" : "Operation Result" },
+ { "name" : "Event Registration Mask",
+ "id" : "0x10",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "guint32",
+ "public-format" : "QmiPbmEventRegistrationFlag",
+ "prerequisites" : [ { "common-ref" : "Success" } ] } ] },
+
+ // *********************************************************************************
+ { "name" : "Get Capabilities",
+ "type" : "Message",
+ "service" : "PBM",
+ "id" : "0x0002",
+ "version" : "1.0",
+ "input" : [ { "name" : "Phonebook Information",
+ "id" : "0x01",
+ "mandatory" : "yes",
+ "type" : "TLV",
+ "format" : "sequence",
+ "contents" : [ { "name" : "Session Type",
+ "format" : "guint8",
+ "public-format" : "QmiPbmSessionType" },
+ { "name" : "Phonebook Type",
+ "format" : "guint16",
+ "public-format" : "QmiPbmPhonebookType" } ] } ],
+ "output" : [ { "common-ref" : "Operation Result" },
+ { "name" : "Capability Basic Information",
+ "id" : "0x10",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "sequence",
+ "contents" : [ { "name" : "Session Type",
+ "format" : "guint8",
+ "public-format" : "QmiPbmSessionType" },
+ { "name" : "Phonebook Type",
+ "format" : "guint16",
+ "public-format" : "QmiPbmPhonebookType" },
+ { "name" : "Used Records",
+ "format" : "guint16" },
+ { "name" : "Maximum Records",
+ "format" : "guint16" },
+ { "name" : "Maximum Number Length",
+ "format" : "guint8" },
+ { "name" : "Maximum Name Length",
+ "format" : "guint8" } ],
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Group Capability",
+ "id" : "0x11",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "sequence",
+ "contents" : [ { "name" : "Maximum Groups",
+ "format" : "guint8" },
+ { "name" : "Maximum Group Tag Length",
+ "format" : "guint8" } ],
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Additional Number Capability",
+ "id" : "0x12",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "sequence",
+ "contents" : [ { "name" : "Maximum Additional Numbers",
+ "format" : "guint8" },
+ { "name" : "Maximum Additional Number Length",
+ "format" : "guint8" },
+ { "name" : "Maximum Additional Number Tag Length",
+ "format" : "guint8" } ],
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Email Capability",
+ "id" : "0x13",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "sequence",
+ "contents" : [ { "name" : "Maximum Emails",
+ "format" : "guint8" },
+ { "name" : "Maximum Email Address Length",
+ "format" : "guint8" } ],
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Second Name Capability",
+ "id" : "0x14",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "sequence",
+ "contents" : [ { "name" : "Maximum Second Name Length",
+ "format" : "guint8" } ],
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Hidden Records Capability",
+ "id" : "0x15",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "sequence",
+ "contents" : [ { "name" : "Supported",
+ "format" : "guint8",
+ "public-format" : "gboolean" } ],
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Grouping Information Alpha String Capability",
+ "id" : "0x16",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "sequence",
+ "contents" : [ { "name" : "Maximum Records",
+ "format" : "guint8" },
+ { "name" : "Used Records",
+ "format" : "guint8" },
+ { "name" : "Maximum String Length",
+ "format" : "guint8" } ],
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Additional Number Alpha String Capability",
+ "id" : "0x17",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "sequence",
+ "contents" : [ { "name" : "Maximum Records",
+ "format" : "guint8" },
+ { "name" : "Used Records",
+ "format" : "guint8" },
+ { "name" : "Maximum String Length",
+ "format" : "guint8" } ],
+ "prerequisites" : [ { "common-ref" : "Success" } ] } ] },
+
+ // *********************************************************************************
+ { "name" : "Get All Capabilities",
+ "type" : "Message",
+ "service" : "PBM",
+ "id" : "0x0003",
+ "version" : "1.0",
+ "output" : [ { "common-ref" : "Operation Result" },
+ { "name" : "Capability Basic Information",
+ "id" : "0x10",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "array",
+ "size-prefix-format" : "guint8",
+ "array-element" : { "name" : "Element",
+ "format" : "struct",
+ "contents" : [ { "name" : "Session Type",
+ "format" : "guint8",
+ "public-format" : "QmiPbmSessionType" },
+ { "name" : "Phonebooks",
+ "format" : "array",
+ "size-prefix-format" : "guint8",
+ "array-element" : { "name" : "Element",
+ "format" : "struct",
+ "contents" : [ { "name" : "Phonebook Type",
+ "format" : "guint16",
+ "public-format" : "QmiPbmPhonebookType" },
+ { "name" : "Used Records",
+ "format" : "guint16" },
+ { "name" : "Maximum Records",
+ "format" : "guint16" },
+ { "name" : "Maximum Number Length",
+ "format" : "guint8" },
+ { "name" : "Maximum Name Length",
+ "format" : "guint8" } ] } } ] },
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Group Capability",
+ "id" : "0x11",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "array",
+ "size-prefix-format" : "guint8",
+ "array-element" : { "name" : "Element",
+ "format" : "struct",
+ "contents" : [ { "name" : "Session Type",
+ "format" : "guint8",
+ "public-format" : "QmiPbmSessionType" },
+ { "name" : "Maximum Groups",
+ "format" : "guint8" },
+ { "name" : "Maximum Group Tag Length",
+ "format" : "guint8" } ] },
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Additional Number Capability",
+ "id" : "0x12",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "array",
+ "size-prefix-format" : "guint8",
+ "array-element" : { "name" : "Element",
+ "format" : "struct",
+ "contents" : [ { "name" : "Session Type",
+ "format" : "guint8",
+ "public-format" : "QmiPbmSessionType" },
+ { "name" : "Maximum Additional Numbers",
+ "format" : "guint8" },
+ { "name" : "Maximum Additional Number Length",
+ "format" : "guint8" },
+ { "name" : "Maximum Additional Number Tag Length",
+ "format" : "guint8" } ] },
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Email Capability",
+ "id" : "0x13",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "array",
+ "size-prefix-format" : "guint8",
+ "array-element" : { "name" : "Element",
+ "format" : "struct",
+ "contents" : [ { "name" : "Session Type",
+ "format" : "guint8",
+ "public-format" : "QmiPbmSessionType" },
+ { "name" : "Maximum Emails",
+ "format" : "guint8" },
+ { "name" : "Maximum Email Address Length",
+ "format" : "guint8" } ] },
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Second Name Capability",
+ "id" : "0x14",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "array",
+ "size-prefix-format" : "guint8",
+ "array-element" : { "name" : "Element",
+ "format" : "struct",
+ "contents" : [ { "name" : "Session Type",
+ "format" : "guint8",
+ "public-format" : "QmiPbmSessionType" },
+ { "name" : "Maximum Second Name Length",
+ "format" : "guint8" } ] },
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Hidden Records Capability",
+ "id" : "0x15",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "array",
+ "size-prefix-format" : "guint8",
+ "array-element" : { "name" : "Element",
+ "format" : "struct",
+ "contents" : [ { "name" : "Session Type",
+ "format" : "guint8",
+ "public-format" : "QmiPbmSessionType" },
+ { "name" : "Supported",
+ "format" : "guint8",
+ "public-format" : "gboolean" } ] },
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Grouping Information Alpha String Capability",
+ "id" : "0x16",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "array",
+ "size-prefix-format" : "guint8",
+ "array-element" : { "name" : "Element",
+ "format" : "struct",
+ "contents" : [ { "name" : "Session Type",
+ "format" : "guint8",
+ "public-format" : "QmiPbmSessionType" },
+ { "name" : "Maximum Records",
+ "format" : "guint8" },
+ { "name" : "Used Records",
+ "format" : "guint8" },
+ { "name" : "Maximum String Length",
+ "format" : "guint8" } ] },
+ "prerequisites" : [ { "common-ref" : "Success" } ] },
+ { "name" : "Additional Number Alpha String Capability",
+ "id" : "0x17",
+ "mandatory" : "no",
+ "type" : "TLV",
+ "format" : "array",
+ "size-prefix-format" : "guint8",
+ "array-element" : { "name" : "Element",
+ "format" : "struct",
+ "contents" : [ { "name" : "Session Type",
+ "format" : "guint8",
+ "public-format" : "QmiPbmSessionType" },
+ { "name" : "Maximum Records",
+ "format" : "guint8" },
+ { "name" : "Used Records",
+ "format" : "guint8" },
+ { "name" : "Maximum String Length",
+ "format" : "guint8" } ] },
+ "prerequisites" : [ { "common-ref" : "Success" } ] } ] }
+]
diff --git a/docs/reference/libqmi-glib/Makefile.am b/docs/reference/libqmi-glib/Makefile.am
index dc60345..8bc6b2a 100644
--- a/docs/reference/libqmi-glib/Makefile.am
+++ b/docs/reference/libqmi-glib/Makefile.am
@@ -12,7 +12,8 @@
$(top_builddir)/libqmi-glib/generated/qmi-nas.sections \
$(top_builddir)/libqmi-glib/generated/qmi-wds.sections \
$(top_builddir)/libqmi-glib/generated/qmi-wms.sections \
- $(top_builddir)/libqmi-glib/generated/qmi-pds.sections
+ $(top_builddir)/libqmi-glib/generated/qmi-pds.sections \
+ $(top_builddir)/libqmi-glib/generated/qmi-pbm.sections
$(DOC_MODULE)-sections.mstamp: $(ALL_SECTIONS)
$(AM_V_GEN) \
diff --git a/docs/reference/libqmi-glib/libqmi-glib-common.sections b/docs/reference/libqmi-glib/libqmi-glib-common.sections
index dfc19b9..ea8f759 100644
--- a/docs/reference/libqmi-glib/libqmi-glib-common.sections
+++ b/docs/reference/libqmi-glib/libqmi-glib-common.sections
@@ -63,6 +63,9 @@
qmi_device_set_instance_id_finish
qmi_device_command
qmi_device_command_finish
+QmiDeviceServiceVersionInfo
+qmi_device_get_service_version_info
+qmi_device_get_service_version_info_finish
<SUBSECTION Standard>
QmiDeviceClass
QMI_DEVICE
@@ -622,6 +625,28 @@
</SECTION>
<SECTION>
+<FILE>qmi-enums-pbm</FILE>
+QmiPbmEventRegistrationFlag
+QmiPbmPhonebookType
+QmiPbmSessionType
+<SUBSECTION Methods>
+qmi_pbm_event_registration_flag_build_string_from_mask
+qmi_pbm_phonebook_type_build_string_from_mask
+qmi_pbm_session_type_get_string
+<SUBSECTION Private>
+qmi_pbm_event_registration_flag_get_string
+qmi_pbm_phonebook_type_get_string
+qmi_pbm_session_type_build_string_from_mask
+<SUBSECTION Standard>
+QMI_TYPE_PBM_EVENT_REGISTRATION_FLAG
+QMI_TYPE_PBM_PHONEBOOK_TYPE
+QMI_TYPE_PBM_SESSION_TYPE
+qmi_pbm_event_registration_flag_get_type
+qmi_pbm_phonebook_type_get_type
+qmi_pbm_session_type_get_type
+</SECTION>
+
+<SECTION>
<FILE>qmi-errors</FILE>
QmiCoreError
QmiProtocolError
diff --git a/docs/reference/libqmi-glib/libqmi-glib-docs.xml b/docs/reference/libqmi-glib/libqmi-glib-docs.xml
index 316f970..829a34d 100644
--- a/docs/reference/libqmi-glib/libqmi-glib-docs.xml
+++ b/docs/reference/libqmi-glib/libqmi-glib-docs.xml
@@ -206,6 +206,18 @@
</section>
</chapter>
+ <chapter>
+ <title>Phonebook Management Service (PBM)</title>
+ <xi:include href="xml/qmi-client-pbm.xml"/>
+ <xi:include href="xml/qmi-enums-pbm.xml"/>
+ <section>
+ <title>PDS Requests</title>
+ <xi:include href="xml/qmi-message-pbm-indication-register.xml"/>
+ <xi:include href="xml/qmi-message-pbm-get-capabilities.xml"/>
+ <xi:include href="xml/qmi-message-pbm-get-all-capabilities.xml"/>
+ </section>
+ </chapter>
+
<chapter id="object-tree">
<title>Object Hierarchy</title>
<xi:include href="xml/tree_index.sgml"/>
diff --git a/libqmi-glib/Makefile.am b/libqmi-glib/Makefile.am
index fdac069..20cb304 100644
--- a/libqmi-glib/Makefile.am
+++ b/libqmi-glib/Makefile.am
@@ -23,6 +23,7 @@
qmi-enums-nas.h qmi-flags64-nas.h\
qmi-enums-wms.h \
qmi-enums-pds.h \
+ qmi-enums-pbm.h \
qmi-enums.h qmi-enums-private.h \
qmi-utils.h qmi-utils.c \
qmi-message.h qmi-message.c \
@@ -48,6 +49,7 @@
qmi-enums-nas.h qmi-flags64-nas.h \
qmi-enums-wms.h \
qmi-enums-pds.h \
+ qmi-enums-pbm.h \
qmi-utils.h \
qmi-message.h \
qmi-device.h \
diff --git a/libqmi-glib/generated/Makefile.am b/libqmi-glib/generated/Makefile.am
index 25f4c48..a376ab2 100644
--- a/libqmi-glib/generated/Makefile.am
+++ b/libqmi-glib/generated/Makefile.am
@@ -11,7 +11,8 @@
qmi-nas.h \
qmi-wds.h \
qmi-wms.h \
- qmi-pds.h
+ qmi-pds.h \
+ qmi-pbm.h
GENERATED_C = \
qmi-error-types.c \
@@ -24,7 +25,8 @@
qmi-nas.c \
qmi-wds.c \
qmi-wms.c \
- qmi-pds.c
+ qmi-pds.c \
+ qmi-pbm.c
GENERATED_SECTIONS = \
qmi-ctl.sections \
@@ -32,7 +34,8 @@
qmi-nas.sections \
qmi-wds.sections \
qmi-wms.sections \
- qmi-pds.sections
+ qmi-pds.sections \
+ qmi-pbm.sections
# Error types
qmi-error-types.h: $(top_srcdir)/libqmi-glib/qmi-errors.h $(top_srcdir)/build-aux/templates/qmi-error-types-template.h
@@ -61,10 +64,11 @@
$(top_srcdir)/libqmi-glib/qmi-enums-dms.h \
$(top_srcdir)/libqmi-glib/qmi-enums-nas.h \
$(top_srcdir)/libqmi-glib/qmi-enums-wms.h \
- $(top_srcdir)/libqmi-glib/qmi-enums-pds.h
+ $(top_srcdir)/libqmi-glib/qmi-enums-pds.h \
+ $(top_srcdir)/libqmi-glib/qmi-enums-pbm.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" \
+ --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" \
--template $(top_srcdir)/build-aux/templates/qmi-enum-types-template.h \
--ftail "#endif /* __LIBQMI_GLIB_ENUM_TYPES_H__ */\n" \
$(ENUMS) > $@
@@ -166,6 +170,16 @@
--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
+
BUILT_SOURCES = $(GENERATED_H) $(GENERATED_C)
nodist_libqmi_glib_generated_la_SOURCES = \
@@ -193,6 +207,7 @@
qmi-nas.h \
qmi-wds.h \
qmi-wms.h \
- qmi-pds.h
+ qmi-pds.h \
+ qmi-pbm.h
CLEANFILES = $(GENERATED_H) $(GENERATED_C) $(GENERATED_SECTIONS)
diff --git a/libqmi-glib/libqmi-glib.h b/libqmi-glib/libqmi-glib.h
index 3d60111..c17685d 100644
--- a/libqmi-glib/libqmi-glib.h
+++ b/libqmi-glib/libqmi-glib.h
@@ -52,6 +52,9 @@
#include "qmi-enums-pds.h"
#include "qmi-pds.h"
+#include "qmi-enums-pbm.h"
+#include "qmi-pbm.h"
+
/* generated */
#include "qmi-error-types.h"
#include "qmi-enum-types.h"
diff --git a/libqmi-glib/qmi-device.c b/libqmi-glib/qmi-device.c
index 87e1c00..e96c4f7 100644
--- a/libqmi-glib/qmi-device.c
+++ b/libqmi-glib/qmi-device.c
@@ -35,6 +35,7 @@
#include "qmi-nas.h"
#include "qmi-wms.h"
#include "qmi-pds.h"
+#include "qmi-pbm.h"
#include "qmi-utils.h"
#include "qmi-error-types.h"
#include "qmi-enum-types.h"
@@ -284,6 +285,114 @@
}
/*****************************************************************************/
+/* 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 #QmiClientCtl.
+ * @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 *
@@ -739,6 +848,10 @@
ctx->client_type = QMI_TYPE_CLIENT_PDS;
break;
+ case QMI_SERVICE_PBM:
+ ctx->client_type = QMI_TYPE_CLIENT_PBM;
+ break;
+
default:
g_simple_async_result_set_error (ctx->result,
QMI_CORE_ERROR,
@@ -1428,9 +1541,9 @@
}
static void
-version_info_ready (QmiClientCtl *client_ctl,
- GAsyncResult *res,
- DeviceOpenContext *ctx)
+open_version_info_ready (QmiClientCtl *client_ctl,
+ GAsyncResult *res,
+ DeviceOpenContext *ctx)
{
GArray *service_list;
QmiMessageCtlGetVersionInfoOutput *output;
@@ -1450,7 +1563,7 @@
NULL,
1,
ctx->cancellable,
- (GAsyncReadyCallback)version_info_ready,
+ (GAsyncReadyCallback)open_version_info_ready,
ctx);
return;
}
@@ -1528,7 +1641,7 @@
NULL,
1,
ctx->cancellable,
- (GAsyncReadyCallback)version_info_ready,
+ (GAsyncReadyCallback)open_version_info_ready,
ctx);
return;
}
diff --git a/libqmi-glib/qmi-device.h b/libqmi-glib/qmi-device.h
index f00bd03..2912552 100644
--- a/libqmi-glib/qmi-device.h
+++ b/libqmi-glib/qmi-device.h
@@ -171,6 +171,29 @@
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/libqmi-glib/qmi-enums-pbm.h b/libqmi-glib/qmi-enums-pbm.h
new file mode 100644
index 0000000..2b10872
--- /dev/null
+++ b/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_ */