diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2021-10-23 22:41:06 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2021-10-24 23:25:59 +0200 |
commit | 25b17dc67c6d6b95ce3568a916fd44136e7eb604 (patch) | |
tree | ce4e873bb90db49b4d30cdfd4420d946bf80a4cb | |
parent | a5fbc67b2ff9b6456de1fd22f7507eb24adb52f2 (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.py | 42 | ||||
-rwxr-xr-x | docs/reference/libmbim-glib/libmbim-glib-common.sections | 2 | ||||
-rw-r--r-- | src/libmbim-glib/mbim-message-private.h | 37 | ||||
-rw-r--r-- | src/libmbim-glib/mbim-message.c | 25 | ||||
-rw-r--r-- | src/libmbim-glib/mbim-tlv.c | 66 | ||||
-rw-r--r-- | src/libmbim-glib/mbim-tlv.h | 27 |
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_ */ |