summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2021-10-23 22:41:06 +0200
committerAleksander Morgado <aleksander@aleksander.es>2021-10-24 23:25:59 +0200
commit25b17dc67c6d6b95ce3568a916fd44136e7eb604 (patch)
treece4e873bb90db49b4d30cdfd4420d946bf80a4cb
parenta5fbc67b2ff9b6456de1fd22f7507eb24adb52f2 (diff)
build-aux,codegen: new 'tlv-guint16-array' field type
This is a TLV that contains an array of guint16 values. For now we only add reading support,
-rw-r--r--build-aux/mbim-codegen/Message.py42
-rwxr-xr-xdocs/reference/libmbim-glib/libmbim-glib-common.sections2
-rw-r--r--src/libmbim-glib/mbim-message-private.h37
-rw-r--r--src/libmbim-glib/mbim-message.c25
-rw-r--r--src/libmbim-glib/mbim-tlv.c66
-rw-r--r--src/libmbim-glib/mbim-tlv.h27
6 files changed, 182 insertions, 17 deletions
diff --git a/build-aux/mbim-codegen/Message.py b/build-aux/mbim-codegen/Message.py
index 66d621e..0e24cac 100644
--- a/build-aux/mbim-codegen/Message.py
+++ b/build-aux/mbim-codegen/Message.py
@@ -90,6 +90,8 @@ def validate_fields(fields):
pass
elif field['format'] == 'tlv-string':
pass
+ elif field['format'] == 'tlv-guint16-array':
+ pass
elif field['format'] == 'tlv-list':
pass
else:
@@ -288,6 +290,8 @@ class Message:
inner_template = (' * @${field}: (in)(transfer none): the \'${name}\' field, given as a #${struct} item.\n')
elif field['format'] == 'tlv-string':
inner_template = (' * @${field}: (in): the \'${name}\' field, given as a string.\n')
+ elif field['format'] == 'tlv-guint16-array':
+ raise ValueError('type \'tlv-guint16-array\' unsupported as input')
elif field['format'] == 'tlv-list':
inner_template = (' * @${field}: (in)(element-type MbimTlv)(transfer none): the \'${name}\' field, given as a list of #${struct} items.\n')
@@ -356,6 +360,8 @@ class Message:
inner_template = (' const MbimTlv *${field},\n')
elif field['format'] == 'tlv-string':
inner_template = (' const gchar *${field},\n')
+ elif field['format'] == 'tlv-guint16-array':
+ raise ValueError('type \'tlv-guint16-array\' unsupported as input')
elif field['format'] == 'tlv-list':
inner_template = (' const GList *${field},\n')
@@ -423,6 +429,8 @@ class Message:
inner_template = (' const MbimTlv *${field},\n')
elif field['format'] == 'tlv-string':
inner_template = (' const gchar *${field},\n')
+ elif field['format'] == 'tlv-guint16-array':
+ raise ValueError('type \'tlv-guint16-array\' unsupported as input')
elif field['format'] == 'tlv-list':
inner_template = (' const GList *${field},\n')
@@ -505,6 +513,8 @@ class Message:
inner_template += (' _mbim_message_command_builder_append_tlv (builder, ${field});\n')
elif field['format'] == 'tlv-string':
inner_template += (' _mbim_message_command_builder_append_tlv_string (builder, ${field});\n')
+ elif field['format'] == 'tlv-guint16-array':
+ raise ValueError('type \'tlv-guint16-array\' unsupported as input')
elif field['format'] == 'tlv-list':
inner_template += (' _mbim_message_command_builder_append_tlv_list (builder, ${field});\n')
@@ -592,6 +602,9 @@ class Message:
inner_template = (' * @out_${field}: (out)(optional)(transfer full): return location for a newly allocated #MbimTlv, or %NULL if the \'${name}\' field is not needed. Free the returned value with mbim_tlv_unref().\n')
elif field['format'] == 'tlv-string':
inner_template = (' * @out_${field}: (out)(optional)(transfer full): return location for a newly allocated string, or %NULL if the \'${name}\' field is not needed. Free the returned value with g_free().\n')
+ elif field['format'] == 'tlv-guint16-array':
+ inner_template = (' * @out_${field}_count: (out)(optional)(transfer none): return location for a #guint32, or %NULL if the field is not needed.\n'
+ ' * @out_${field}: (out)(optional)(nullable)(transfer full): return location for a newly allocated array of #guint16 items, or %NULL if the \'${name}\' field is not needed. The availability of this field is not always guaranteed, and therefore %NULL may be given as a valid output. Free the returned value with g_free().\n')
elif field['format'] == 'tlv-list':
inner_template = (' * @out_${field}: (out)(optional)(element-type MbimTlv)(transfer full): return location for a newly allocated list of #MbimTlv items, or %NULL if the \'${name}\' field is not needed. Free the returned value with g_list_free_full() using mbim_tlv_unref() as #GDestroyNotify.\n')
@@ -659,6 +672,9 @@ class Message:
inner_template = (' MbimTlv **out_${field},\n')
elif field['format'] == 'tlv-string':
inner_template = (' gchar **out_${field},\n')
+ elif field['format'] == 'tlv-guint16-array':
+ inner_template = (' guint32 *out_${field}_count,\n'
+ ' guint16 **out_${field},\n')
elif field['format'] == 'tlv-list':
inner_template = (' GList **out_${field},\n')
else:
@@ -726,6 +742,9 @@ class Message:
inner_template = (' MbimTlv **out_${field},\n')
elif field['format'] == 'tlv-string':
inner_template = (' gchar **out_${field},\n')
+ elif field['format'] == 'tlv-guint16-array':
+ inner_template = (' guint32 *out_${field}_count,\n'
+ ' guint16 **out_${field},\n')
elif field['format'] == 'tlv-list':
inner_template = (' GList **out_${field},\n')
@@ -782,6 +801,9 @@ class Message:
elif field['format'] == 'tlv-string':
count_allocated_variables += 1
inner_template = (' gchar *_${field} = NULL;\n')
+ elif field['format'] == 'tlv-guint16-array':
+ count_allocated_variables += 1
+ inner_template = (' guint16 *_${field} = NULL;\n')
elif field['format'] == 'tlv-list':
count_allocated_variables += 1
inner_template = (' GList *_${field} = NULL;\n')
@@ -1104,6 +1126,18 @@ class Message:
' else\n'
' g_free (tmp);\n'
' offset += bytes_read;\n')
+ elif field['format'] == 'tlv-guint16-array':
+ inner_template += (
+ ' guint16 *tmp = NULL;\n'
+ ' guint32 bytes_read = 0;\n'
+ '\n'
+ ' if (!_mbim_message_read_tlv_guint16_array (message, offset, out_${field}_count, &tmp, &bytes_read, error))\n'
+ ' goto out;\n'
+ ' if (out_${field} != NULL)\n'
+ ' _${field} = tmp;\n'
+ ' else\n'
+ ' g_free (tmp);\n'
+ ' offset += bytes_read;\n')
elif field['format'] == 'tlv-list':
inner_template += (
' GList *tmp = NULL;\n'
@@ -1150,6 +1184,7 @@ class Message:
field['format'] == 'ipv6-array' or \
field['format'] == 'tlv' or \
field['format'] == 'tlv-string' or \
+ field['format'] == 'tlv-guint16-array' or \
field['format'] == 'tlv-list':
inner_template = (' if (out_${field} != NULL)\n'
' *out_${field} = _${field};\n')
@@ -1164,7 +1199,8 @@ class Message:
if field['format'] == 'string' or \
field['format'] == 'ipv4-array' or \
field['format'] == 'ipv6-array' or \
- field['format'] == 'tlv-string':
+ field['format'] == 'tlv-string' or \
+ field['format'] == 'tlv-guint16-array':
inner_template = (' g_free (_${field});\n')
elif field['format'] == 'string-array':
inner_template = (' g_strfreev (_${field});\n')
@@ -1579,7 +1615,9 @@ class Message:
' }\n'
' g_string_append (str, "\'");\n')
- elif field['format'] == 'tlv' or field['format'] == 'tlv-string':
+ elif field['format'] == 'tlv' or \
+ field['format'] == 'tlv-string' or \
+ field['format'] == 'tlv-guint16-array':
inner_template += (
' g_autoptr(MbimTlv) tmp = NULL;\n'
' guint32 bytes_read = 0;\n'
diff --git a/docs/reference/libmbim-glib/libmbim-glib-common.sections b/docs/reference/libmbim-glib/libmbim-glib-common.sections
index 0531a25..2f0de68 100755
--- a/docs/reference/libmbim-glib/libmbim-glib-common.sections
+++ b/docs/reference/libmbim-glib/libmbim-glib-common.sections
@@ -776,6 +776,8 @@ mbim_tlv_type_get_string
<SUBSECTION TlvString>
mbim_tlv_string_new
mbim_tlv_string_get
+<SUBSECTION TlvUint16Array>
+mbim_tlv_guint16_array_get
<SUBSECTION Private>
mbim_tlv_type_build_string_from_mask
<SUBSECTION Standard>
diff --git a/src/libmbim-glib/mbim-message-private.h b/src/libmbim-glib/mbim-message-private.h
index 80db730..99e878c 100644
--- a/src/libmbim-glib/mbim-message-private.h
+++ b/src/libmbim-glib/mbim-message-private.h
@@ -324,21 +324,28 @@ gboolean _mbim_message_read_ipv6_array (const MbimMessage *self,
guint32 relative_offset_array_start,
MbimIPv6 **array,
GError **error);
-gboolean _mbim_message_read_tlv (const MbimMessage *self,
- guint32 relative_offset,
- MbimTlv **tlv,
- guint32 *bytes_read,
- GError **error);
-gboolean _mbim_message_read_tlv_string (const MbimMessage *self,
- guint32 relative_offset,
- gchar **str,
- guint32 *bytes_read,
- GError **error);
-gboolean _mbim_message_read_tlv_list (const MbimMessage *self,
- guint32 relative_offset,
- GList **tlv,
- guint32 *bytes_read,
- GError **error);
+
+gboolean _mbim_message_read_tlv (const MbimMessage *self,
+ guint32 relative_offset,
+ MbimTlv **tlv,
+ guint32 *bytes_read,
+ GError **error);
+gboolean _mbim_message_read_tlv_string (const MbimMessage *self,
+ guint32 relative_offset,
+ gchar **str,
+ guint32 *bytes_read,
+ GError **error);
+gboolean _mbim_message_read_tlv_guint16_array (const MbimMessage *self,
+ guint32 relative_offset,
+ guint32 *array_size,
+ guint16 **array,
+ guint32 *bytes_read,
+ GError **error);
+gboolean _mbim_message_read_tlv_list (const MbimMessage *self,
+ guint32 relative_offset,
+ GList **tlv,
+ guint32 *bytes_read,
+ GError **error);
G_END_DECLS
diff --git a/src/libmbim-glib/mbim-message.c b/src/libmbim-glib/mbim-message.c
index 0eee7c6..7b6699d 100644
--- a/src/libmbim-glib/mbim-message.c
+++ b/src/libmbim-glib/mbim-message.c
@@ -874,6 +874,31 @@ _mbim_message_read_tlv_string (const MbimMessage *self,
}
gboolean
+_mbim_message_read_tlv_guint16_array (const MbimMessage *self,
+ guint32 relative_offset,
+ guint32 *array_size,
+ guint16 **array,
+ guint32 *bytes_read,
+ GError **error)
+{
+ g_autoptr(MbimTlv) tlv = NULL;
+ guint32 tlv_bytes_read = 0;
+
+ if (!_mbim_message_read_tlv (self,
+ relative_offset,
+ &tlv,
+ &tlv_bytes_read,
+ error))
+ return FALSE;
+
+ if (!mbim_tlv_guint16_array_get (tlv, array_size, array, error))
+ return FALSE;
+
+ *bytes_read = tlv_bytes_read;
+ return TRUE;
+}
+
+gboolean
_mbim_message_read_tlv_list (const MbimMessage *self,
guint32 relative_offset,
GList **tlv_list,
diff --git a/src/libmbim-glib/mbim-tlv.c b/src/libmbim-glib/mbim-tlv.c
index ca87edd..b347d0f 100644
--- a/src/libmbim-glib/mbim-tlv.c
+++ b/src/libmbim-glib/mbim-tlv.c
@@ -70,6 +70,25 @@ _mbim_tlv_print (const MbimTlv *tlv,
if (!tlv_data_string_str)
tlv_data_string_str = g_strdup_printf ("*** error: %s", error->message);
g_string_append_printf (str, "%s tlv string = %s\n", line_prefix, tlv_data_string_str ? tlv_data_string_str : "");
+ } else if (tlv_type == MBIM_TLV_TYPE_UINT16_TBL) {
+ g_autoptr(GError) error = NULL;
+ guint32 array_size = 0;
+ g_autofree guint16 *array = NULL;
+ g_autofree gchar *tlv_data_string_str = NULL;
+
+ if (!mbim_tlv_guint16_array_get (tlv, &array_size, &array, &error))
+ tlv_data_string_str = g_strdup_printf ("*** error: %s", error->message);
+ else {
+ GString *aux;
+ guint32 i;
+
+ aux = g_string_new ("[");
+ for (i = 0; i < array_size; i++)
+ g_string_append_printf (aux, "%s%" G_GUINT16_FORMAT, (i == 0) ? "" : ",", array[i]);
+ g_string_append (aux, "]");
+ tlv_data_string_str = g_string_free (aux, FALSE);
+ }
+ g_string_append_printf (str, "%s tlv uint16 array = %s\n", line_prefix, tlv_data_string_str ? tlv_data_string_str : "");
}
g_string_append_printf (str, "%s}", line_prefix);
@@ -257,3 +276,50 @@ mbim_tlv_string_get (const MbimTlv *self,
NULL,
error);
}
+
+/*****************************************************************************/
+
+gboolean
+mbim_tlv_guint16_array_get (const MbimTlv *self,
+ guint32 *array_size,
+ guint16 **array,
+ GError **error)
+{
+ guint32 size;
+ g_autofree guint16 *tmp = NULL;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ if (MBIM_TLV_GET_TLV_TYPE (self) != MBIM_TLV_TYPE_UINT16_TBL) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "TLV is not a UINT16 array");
+ return FALSE;
+ }
+
+ size = MBIM_TLV_GET_DATA_LENGTH (self);
+ if (size % 2 != 0) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "Invalid TLV data length, must be multiple of 2: %u",
+ size);
+ return FALSE;
+ }
+
+ if (size) {
+ tmp = (guint16 *) g_memdup ((const guint16 *)MBIM_TLV_FIELD_DATA (self), size);
+
+ /* For BE systems, convert from LE to BE */
+ if (G_BYTE_ORDER == G_BIG_ENDIAN) {
+ guint i;
+
+ for (i = 0; i < (size / 2); i++)
+ tmp[i] = GUINT16_FROM_LE (tmp[i]);
+ }
+ }
+
+ if (array_size)
+ *array_size = size / 2;
+ if (array)
+ *array = g_steal_pointer (&tmp);
+
+ return TRUE;
+}
diff --git a/src/libmbim-glib/mbim-tlv.h b/src/libmbim-glib/mbim-tlv.h
index 3b7feff..cfafb4a 100644
--- a/src/libmbim-glib/mbim-tlv.h
+++ b/src/libmbim-glib/mbim-tlv.h
@@ -220,6 +220,33 @@ MbimTlv *mbim_tlv_string_new (const gchar *str,
gchar *mbim_tlv_string_get (const MbimTlv *self,
GError **error);
+/*****************************************************************************/
+/* guint16 array type helpers */
+
+/**
+ * mbim_tlv_guint16_array_get:
+ * @self: a #MbimTlv of type %MBIM_TLV_TYPE_UINT16_TBL.
+ * @array_size: (out)(optional)(transfer none): return location for a #guint32,
+ * or %NULL if the field is not needed.
+ * @array: (out)(optional)(transfer full)(type guint16): return location for a
+ * newly allocated array of #guint16 values, or %NULL if the field is not
+ * needed. Free the returned value with g_free().
+ * @error: return location for error or %NULL.
+ *
+ * Get an array of #guint16 values with the contents in the #MbimTlv.
+ *
+ * The method may return a successful return even with on empty arrays (i.e.
+ * with @array_size set to 0 and @array set to %NULL).
+ *
+ * Returns: %TRUE if on success, %FALSE if @error is set.
+ *
+ * Since: 1.28
+ */
+gboolean mbim_tlv_guint16_array_get (const MbimTlv *self,
+ guint32 *array_size,
+ guint16 **array,
+ GError **error);
+
G_END_DECLS
#endif /* _LIBMBIM_GLIB_MBIM_TLV_H_ */