[PATCH v9 03/10] mbimmodem: add support for appending TLVs in messages

Muhammad Asif <[email protected]> Fri, 26 Dec 2025 19:13:03 +0500
Newsgroups dev.linux.lists.ofono
Message-ID <[email protected]>
So far only UTF16 strings in TLVs are supported, and no support for
reading them (not needed yet)
---
 drivers/mbimmodem/mbim-message.c | 44 ++++++++++++++++++++++++++++++++
 drivers/mbimmodem/mbim-message.h |  5 ++++
 drivers/mbimmodem/mbim-private.h |  7 +++++
 3 files changed, 56 insertions(+)

diff --git a/drivers/mbimmodem/mbim-message.c b/drivers/mbimmodem/mbim-mess=
age.c
index 65cdc73f..413abe5c 100644
--- a/drivers/mbimmodem/mbim-message.c
+++ b/drivers/mbimmodem/mbim-message.c
@@ -1669,6 +1669,50 @@ static bool append_arguments(struct mbim_message *me=
ssage,
 =09=09=09}
=20
 =09=09=09break;
+=09=09case 'T':
+=09=09{
+=09=09=09/* TLV value */
+=09=09=09struct mbim_tlv_header header =3D {0};
+=09=09=09uint16_t tlv_type =3D (uint16_t) va_arg(args, int);
+
+=09=09=09if (tlv_type =3D=3D MBIM_TLV_TYPE_INVALID)
+=09=09=09=09break;
+
+=09=09=09header.type =3D L_CPU_TO_LE16(tlv_type);
+
+=09=09=09switch (tlv_type) {
+=09=09=09case MBIM_TLV_TYPE_WCHAR_STR: {
+=09=09=09=09size_t utf16_len =3D 0;
+
+=09=09=09=09str =3D va_arg(args, const char *);
+=09=09=09=09L_AUTO_FREE_VAR(void *, val) =3D l_utf8_to_utf16(str, &utf16_l=
en);
+
+=09=09=09=09if (utf16_len % 4)
+=09=09=09=09=09header.padding_len =3D 4 - (utf16_len % 4);
+
+=09=09=09=09header.data_length =3D L_CPU_TO_LE32(utf16_len);
+
+=09=09=09=09if (!mbim_message_builder_append_bytes(builder,
+=09=09=09=09=09=09sizeof(header), (uint8_t *)&header))
+=09=09=09=09=09goto error;
+
+=09=09=09=09if (val)
+=09=09=09=09=09if (!mbim_message_builder_append_bytes(builder,
+=09=09=09=09=09=09=09utf16_len, val))
+=09=09=09=09=09=09goto error;
+=09=09=09}
+=09=09=09}
+
+=09=09=09if (header.padding_len) {
+=09=09=09=09struct container *cont =3D &builder->stack[builder->index];
+=09=09=09=09size_t start =3D GROW_SBUF(cont, header.padding_len, 1);
+
+=09=09=09=09memset(cont->sbuf + start, 0, header.padding_len);
+=09=09=09}
+
+=09=09=09break;
+=09=09}
+
 =09=09default:
 =09=09=09goto error;
 =09=09}
diff --git a/drivers/mbimmodem/mbim-message.h b/drivers/mbimmodem/mbim-mess=
age.h
index 885cc433..c28ab9b3 100644
--- a/drivers/mbimmodem/mbim-message.h
+++ b/drivers/mbimmodem/mbim-message.h
@@ -17,6 +17,11 @@ enum mbim_command_type {
 =09MBIM_COMMAND_TYPE_SET =3D 1,
 };
=20
+enum mbim_tlv_type {
+=09MBIM_TLV_TYPE_INVALID =3D 0,
+=09MBIM_TLV_TYPE_WCHAR_STR =3D 10,
+};
+
 struct mbim_message_iter {
 =09const char *sig_start;
 =09uint8_t sig_len;
diff --git a/drivers/mbimmodem/mbim-private.h b/drivers/mbimmodem/mbim-priv=
ate.h
index 6a9e0b2d..c62e0655 100644
--- a/drivers/mbimmodem/mbim-private.h
+++ b/drivers/mbimmodem/mbim-private.h
@@ -32,6 +32,13 @@ struct mbim_fragment_header {
 =09__le32 cur_frag;
 } __attribute__ ((packed));
=20
+struct mbim_tlv_header {
+=09__le16 type;
+=09uint8_t reserved;
+=09uint8_t padding_len;
+=09__le32 data_length;
+} __attribute__ ((packed));
+
 struct mbim_message *_mbim_message_build(const void *header,
 =09=09=09=09=09=09struct iovec *frags,
 =09=09=09=09=09=09uint32_t n_frags);
--=20
2.52.0