
/* GENERATED CODE... DO NOT EDIT */

/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2013 - 2018 Aleksander Morgado <aleksander@aleksander.es>
 */


#include <string.h>

#include "mbim-ms-uicc-low-level-access.h"
#include "mbim-message-private.h"
#include "mbim-tlv-private.h"
#include "mbim-enum-types.h"
#include "mbim-flag-types.h"
#include "mbim-error-types.h"
#include "mbim-device.h"
#include "mbim-utils.h"

/*****************************************************************************/
/* Struct: MbimTerminalCapabilityInfo */

static void
_mbim_terminal_capability_info_free (MbimTerminalCapabilityInfo *var)
{
    if (!var)
        return;

    g_free (var->terminal_capability_data);
    g_free (var);
}

void
mbim_terminal_capability_info_array_free (MbimTerminalCapabilityInfoArray *array)
{
    guint32 i;

    if (!array)
        return;

    for (i = 0; array[i]; i++)
        _mbim_terminal_capability_info_free (array[i]);
    g_free (array);
}

static MbimTerminalCapabilityInfo *
_mbim_message_read_mbim_terminal_capability_info_struct (
    const MbimMessage *self,
    guint32 relative_offset,
    guint32 explicit_struct_size,
    guint32 *bytes_read,
    GError **error)
{
    gboolean success = FALSE;
    MbimTerminalCapabilityInfo *out;
    guint32 offset = relative_offset;

    g_assert (self != NULL);

    out = g_new0 (MbimTerminalCapabilityInfo, 1);


    {
        const guint8 *tmp;

        out->terminal_capability_data_size = explicit_struct_size - (offset - relative_offset);
        if (!_mbim_message_read_byte_array (self, relative_offset, offset, FALSE, FALSE, out->terminal_capability_data_size, &tmp, NULL, error, FALSE))
                goto out;
        out->terminal_capability_data = g_malloc (out->terminal_capability_data_size);
        memcpy (out->terminal_capability_data, tmp, out->terminal_capability_data_size);
        offset += out->terminal_capability_data_size;
    }

    success = TRUE;

 out:
    if (success) {
        guint32 total_bytes_read = (offset - relative_offset);

        if (!explicit_struct_size || total_bytes_read <= explicit_struct_size) {
            if (bytes_read)
                *bytes_read = total_bytes_read;
            return out;
        }
        g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Read %u bytes from struct with size %u", total_bytes_read, explicit_struct_size);
    }

    _mbim_terminal_capability_info_free (out);
    return NULL;
}

static gboolean
_mbim_message_read_mbim_terminal_capability_info_ref_struct_array (
    const MbimMessage *self,
    guint32 array_size,
    guint32 relative_offset_array_start,
    MbimTerminalCapabilityInfoArray **out_array,
    GError **error)
{
    g_autoptr(GPtrArray) out = NULL;
    guint32 i;
    guint32 offset;

    if (!array_size) {
        *out_array = NULL;
        return TRUE;
    }

    out = g_ptr_array_new_with_free_func ((GDestroyNotify)_mbim_terminal_capability_info_free);

    offset = relative_offset_array_start;
    for (i = 0; i < array_size; i++, offset += 8) {
        guint32 tmp_offset;
        guint32 tmp_length;
        MbimTerminalCapabilityInfo *array_item;

        if (!_mbim_message_read_guint32 (self, offset, &tmp_offset, error)) 
            return FALSE;
        if (!_mbim_message_read_guint32 (self, offset + 4, &tmp_length, error)) 
            return FALSE;

        array_item = _mbim_message_read_mbim_terminal_capability_info_struct (self, tmp_offset, tmp_length, NULL, error);
        if (!array_item)
            return FALSE;
        g_ptr_array_add (out, array_item);
    }

    g_ptr_array_add (out, NULL);
    *out_array = (MbimTerminalCapabilityInfoArray *) g_ptr_array_free (g_steal_pointer (&out), FALSE);
    return TRUE;
}

static gchar *
_mbim_message_print_mbim_terminal_capability_info_struct (
    const MbimTerminalCapabilityInfo *self,
    const gchar *line_prefix)
{
    GString *str;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  TerminalCapabilityData = ", line_prefix);
    {
        {
            guint i;
            guint array_size;

            array_size = self->terminal_capability_data_size;
            g_string_append (str, "'");
            for (i = 0; i < array_size; i++)
                g_string_append_printf (str, "%02x%s", self->terminal_capability_data[i], (i == (array_size - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");
    return g_string_free (str, FALSE);
}

static GByteArray *
_mbim_terminal_capability_info_struct_new (const MbimTerminalCapabilityInfo *value)
{
    MbimStructBuilder *builder;

    g_assert (value != NULL);

    builder = _mbim_struct_builder_new ();
    _mbim_struct_builder_append_byte_array (builder, FALSE, FALSE, FALSE, value->terminal_capability_data, value->terminal_capability_data_size, FALSE);

    return _mbim_struct_builder_complete (builder);
}

static void
_mbim_struct_builder_append_mbim_terminal_capability_info_struct (
    MbimStructBuilder *builder,
    const MbimTerminalCapabilityInfo *value)
{
    GByteArray *raw;

    raw = _mbim_terminal_capability_info_struct_new (value);
    g_byte_array_append (builder->fixed_buffer, raw->data, raw->len);
    g_byte_array_unref (raw);
}

static void
_mbim_message_command_builder_append_mbim_terminal_capability_info_struct (
    MbimMessageCommandBuilder *builder,
    const MbimTerminalCapabilityInfo *value)
{
    _mbim_struct_builder_append_mbim_terminal_capability_info_struct (builder->contents_builder, value);
}

static void
_mbim_struct_builder_append_mbim_terminal_capability_info_ref_struct_array (
    MbimStructBuilder *builder,
    const MbimTerminalCapabilityInfo *const *values,
    guint32 n_values)
{
    guint32 offset;
    guint32 i;

    for (i = 0; i < n_values; i++) {
        guint32 length;
        guint32 offset_offset;
        GByteArray *raw;
        static const guint8 padding = 0x00;

        raw = _mbim_terminal_capability_info_struct_new (values[i]);
        g_assert (raw->len > 0);

        /* Offset of the offset */
        offset_offset = builder->fixed_buffer->len;

        /* Length *not* in LE yet */
        offset = builder->variable_buffer->len;
        /* Add the offset value */
        g_byte_array_append (builder->fixed_buffer, (guint8 *)&offset, sizeof (offset));
        /* Configure the value to get updated */
        g_array_append_val (builder->offsets, offset_offset);

        /* Add the length value */
        length = GUINT32_TO_LE (raw->len);
        g_byte_array_append (builder->fixed_buffer, (guint8 *)&length, sizeof (length));

        /* And finally, the bytearray itself to the variable buffer */
        g_byte_array_append (builder->variable_buffer, (const guint8 *)raw->data, (guint)raw->len);
        /* Align the structs at 4 byte boundary, as we may have unsized byte arrays */
        while (builder->variable_buffer->len % 4 != 0)
            g_byte_array_append (builder->variable_buffer, &padding, sizeof (padding));
        g_byte_array_unref (raw);
    }
}

static void
_mbim_message_command_builder_append_mbim_terminal_capability_info_ref_struct_array (
    MbimMessageCommandBuilder *builder,
    const MbimTerminalCapabilityInfo *const *values,
    guint32 n_values)
{
    _mbim_struct_builder_append_mbim_terminal_capability_info_ref_struct_array (builder->contents_builder, values, n_values);
}

/*****************************************************************************/
/* Struct: MbimUiccApplication */

static void
_mbim_uicc_application_free (MbimUiccApplication *var)
{
    if (!var)
        return;

    g_free (var->application_id);
    g_free (var->application_name);
    g_free (var->pin_key_references);
    g_free (var);
}

void
mbim_uicc_application_array_free (MbimUiccApplicationArray *array)
{
    guint32 i;

    if (!array)
        return;

    for (i = 0; array[i]; i++)
        _mbim_uicc_application_free (array[i]);
    g_free (array);
}

static MbimUiccApplication *
_mbim_message_read_mbim_uicc_application_struct (
    const MbimMessage *self,
    guint32 relative_offset,
    guint32 explicit_struct_size,
    guint32 *bytes_read,
    GError **error)
{
    gboolean success = FALSE;
    MbimUiccApplication *out;
    guint32 offset = relative_offset;

    g_assert (self != NULL);

    out = g_new0 (MbimUiccApplication, 1);


    if (!_mbim_message_read_guint32 (self, offset, &out->application_type, error))
        goto out;
    offset += 4;

    {
        const guint8 *tmp;

        if (!_mbim_message_read_byte_array (self, relative_offset, offset, TRUE, TRUE, 0, &tmp, &(out->application_id_size), error, FALSE))
            goto out;
        out->application_id = g_malloc (out->application_id_size);
        memcpy (out->application_id, tmp, out->application_id_size);
        offset += 8;
    }

    if (!_mbim_message_read_string (self, relative_offset, offset, MBIM_STRING_ENCODING_UTF8, &out->application_name, NULL, error))
        goto out;
    offset += 8;

    if (!_mbim_message_read_guint32 (self, offset, &out->pin_key_reference_count, error))
        goto out;
    offset += 4;

    {
        const guint8 *tmp;

        if (!_mbim_message_read_byte_array (self, relative_offset, offset, TRUE, TRUE, 0, &tmp, &(out->pin_key_references_size), error, FALSE))
            goto out;
        out->pin_key_references = g_malloc (out->pin_key_references_size);
        memcpy (out->pin_key_references, tmp, out->pin_key_references_size);
        offset += 8;
    }

    success = TRUE;

 out:
    if (success) {
        guint32 total_bytes_read = (offset - relative_offset);

        if (!explicit_struct_size || total_bytes_read <= explicit_struct_size) {
            if (bytes_read)
                *bytes_read = total_bytes_read;
            return out;
        }
        g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Read %u bytes from struct with size %u", total_bytes_read, explicit_struct_size);
    }

    _mbim_uicc_application_free (out);
    return NULL;
}

static gboolean
_mbim_message_read_mbim_uicc_application_ref_struct_array (
    const MbimMessage *self,
    guint32 array_size,
    guint32 relative_offset_array_start,
    MbimUiccApplicationArray **out_array,
    GError **error)
{
    g_autoptr(GPtrArray) out = NULL;
    guint32 i;
    guint32 offset;

    if (!array_size) {
        *out_array = NULL;
        return TRUE;
    }

    out = g_ptr_array_new_with_free_func ((GDestroyNotify)_mbim_uicc_application_free);

    offset = relative_offset_array_start;
    for (i = 0; i < array_size; i++, offset += 8) {
        guint32 tmp_offset;
        guint32 tmp_length;
        MbimUiccApplication *array_item;

        if (!_mbim_message_read_guint32 (self, offset, &tmp_offset, error)) 
            return FALSE;
        if (!_mbim_message_read_guint32 (self, offset + 4, &tmp_length, error)) 
            return FALSE;

        array_item = _mbim_message_read_mbim_uicc_application_struct (self, tmp_offset, tmp_length, NULL, error);
        if (!array_item)
            return FALSE;
        g_ptr_array_add (out, array_item);
    }

    g_ptr_array_add (out, NULL);
    *out_array = (MbimUiccApplicationArray *) g_ptr_array_free (g_steal_pointer (&out), FALSE);
    return TRUE;
}

static gchar *
_mbim_message_print_mbim_uicc_application_struct (
    const MbimUiccApplication *self,
    const gchar *line_prefix)
{
    GString *str;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  ApplicationType = ", line_prefix);
    {
        {
#if defined __MBIM_UICC_APPLICATION_TYPE_IS_ENUM__
            g_string_append_printf (str, "'%s'", mbim_uicc_application_type_get_string ((MbimUiccApplicationType)self->application_type));
#elif defined __MBIM_UICC_APPLICATION_TYPE_IS_FLAGS__
            g_autofree gchar *tmpstr = NULL;

            tmpstr = mbim_uicc_application_type_build_string_from_mask ((MbimUiccApplicationType)self->application_type);
            g_string_append_printf (str, "'%s'", tmpstr);
#else
# error neither enum nor flags
#endif
        }

    }
    g_string_append (str, "\n");
    g_string_append_printf (str, "%s  ApplicationId = ", line_prefix);
    {
        {
            guint i;
            guint array_size;

            array_size = self->application_id_size;
            g_string_append (str, "'");
            for (i = 0; i < array_size; i++)
                g_string_append_printf (str, "%02x%s", self->application_id[i], (i == (array_size - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");
    g_string_append_printf (str, "%s  ApplicationName = ", line_prefix);
    {
        {
            g_string_append_printf (str, "'%s'", self->application_name);
        }
    }
    g_string_append (str, "\n");
    g_string_append_printf (str, "%s  PinKeyReferenceCount = ", line_prefix);
    {
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", self->pin_key_reference_count);
        }
    }
    g_string_append (str, "\n");
    g_string_append_printf (str, "%s  PinKeyReferences = ", line_prefix);
    {
        {
            guint i;
            guint array_size;

            array_size = self->pin_key_references_size;
            g_string_append (str, "'");
            for (i = 0; i < array_size; i++)
                g_string_append_printf (str, "%02x%s", self->pin_key_references[i], (i == (array_size - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");
    return g_string_free (str, FALSE);
}

static GByteArray *
_mbim_uicc_application_struct_new (const MbimUiccApplication *value)
{
    MbimStructBuilder *builder;

    g_assert (value != NULL);

    builder = _mbim_struct_builder_new ();
    _mbim_struct_builder_append_guint32 (builder, value->application_type);
    _mbim_struct_builder_append_byte_array (builder, TRUE, TRUE, TRUE, value->application_id, value->application_id_size, FALSE);
    _mbim_struct_builder_append_string (builder, value->application_name);
    _mbim_struct_builder_append_guint32 (builder, value->pin_key_reference_count);
    _mbim_struct_builder_append_byte_array (builder, TRUE, TRUE, TRUE, value->pin_key_references, value->pin_key_references_size, FALSE);

    return _mbim_struct_builder_complete (builder);
}

static void
_mbim_struct_builder_append_mbim_uicc_application_struct (
    MbimStructBuilder *builder,
    const MbimUiccApplication *value)
{
    GByteArray *raw;

    raw = _mbim_uicc_application_struct_new (value);
    g_byte_array_append (builder->fixed_buffer, raw->data, raw->len);
    g_byte_array_unref (raw);
}

static void
_mbim_message_command_builder_append_mbim_uicc_application_struct (
    MbimMessageCommandBuilder *builder,
    const MbimUiccApplication *value)
{
    _mbim_struct_builder_append_mbim_uicc_application_struct (builder->contents_builder, value);
}

static void
_mbim_struct_builder_append_mbim_uicc_application_ref_struct_array (
    MbimStructBuilder *builder,
    const MbimUiccApplication *const *values,
    guint32 n_values)
{
    guint32 offset;
    guint32 i;

    for (i = 0; i < n_values; i++) {
        guint32 length;
        guint32 offset_offset;
        GByteArray *raw;
        static const guint8 padding = 0x00;

        raw = _mbim_uicc_application_struct_new (values[i]);
        g_assert (raw->len > 0);

        /* Offset of the offset */
        offset_offset = builder->fixed_buffer->len;

        /* Length *not* in LE yet */
        offset = builder->variable_buffer->len;
        /* Add the offset value */
        g_byte_array_append (builder->fixed_buffer, (guint8 *)&offset, sizeof (offset));
        /* Configure the value to get updated */
        g_array_append_val (builder->offsets, offset_offset);

        /* Add the length value */
        length = GUINT32_TO_LE (raw->len);
        g_byte_array_append (builder->fixed_buffer, (guint8 *)&length, sizeof (length));

        /* And finally, the bytearray itself to the variable buffer */
        g_byte_array_append (builder->variable_buffer, (const guint8 *)raw->data, (guint)raw->len);
        /* Align the structs at 4 byte boundary, as we may have unsized byte arrays */
        while (builder->variable_buffer->len % 4 != 0)
            g_byte_array_append (builder->variable_buffer, &padding, sizeof (padding));
        g_byte_array_unref (raw);
    }
}

static void
_mbim_message_command_builder_append_mbim_uicc_application_ref_struct_array (
    MbimMessageCommandBuilder *builder,
    const MbimUiccApplication *const *values,
    guint32 n_values)
{
    _mbim_struct_builder_append_mbim_uicc_application_ref_struct_array (builder->contents_builder, values, n_values);
}

/*****************************************************************************/
/* Message (Query): MBIM Message MS UICC Low Level Access ATR */

MbimMessage *
mbim_message_ms_uicc_low_level_access_atr_query_new (
    GError **error)
{
    MbimMessageCommandBuilder *builder;

    builder = _mbim_message_command_builder_new (0,
                                                 MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS,
                                                 MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_ATR,
                                                 MBIM_MESSAGE_COMMAND_TYPE_QUERY);

    return _mbim_message_command_builder_complete (builder);
}

static gchar *
mbim_message_ms_uicc_low_level_access_atr_query_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;

    str = g_string_new ("");

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Response): MBIM Message MS UICC Low Level Access ATR */

gboolean
mbim_message_ms_uicc_low_level_access_atr_response_parse (
    const MbimMessage *message,
    guint32 *out_atr_size,
    const guint8 **out_atr,
    GError **error)
{
    gboolean success = FALSE;
    guint32 offset = 0;

    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_COMMAND_DONE) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message is not a response");
        return FALSE;
    }

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL)) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message does not have information buffer");
        return FALSE;
    }

    /* Read the 'atr' variable */
    {
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, error, TRUE))
            goto out;
        if (out_atr != NULL)
            *out_atr = tmp;
        if (out_atr_size != NULL)
            *out_atr_size = tmpsize;
        offset += 8;
    }

    /* All variables successfully parsed */
    success = TRUE;

 out:


    return success;
}

static gchar *
mbim_message_ms_uicc_low_level_access_atr_response_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  atr = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, TRUE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Set): MBIM Message MS UICC Low Level Access Open Channel */

MbimMessage *
mbim_message_ms_uicc_low_level_access_open_channel_set_new (
    const guint32 app_id_size,
    const guint8 *app_id,
    guint32 select_p2_arg,
    guint32 channel_group,
    GError **error)
{
    MbimMessageCommandBuilder *builder;

    builder = _mbim_message_command_builder_new (0,
                                                 MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS,
                                                 MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_OPEN_CHANNEL,
                                                 MBIM_MESSAGE_COMMAND_TYPE_SET);
    {
        _mbim_message_command_builder_append_byte_array (builder, TRUE, TRUE, TRUE, app_id, app_id_size, TRUE);
    }
    {
        _mbim_message_command_builder_append_guint32 (builder, select_p2_arg);
    }
    {
        _mbim_message_command_builder_append_guint32 (builder, channel_group);
    }

    return _mbim_message_command_builder_complete (builder);
}

static gchar *
mbim_message_ms_uicc_low_level_access_open_channel_set_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  AppId = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, TRUE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  SelectP2Arg = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  ChannelGroup = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Response): MBIM Message MS UICC Low Level Access Open Channel */

gboolean
mbim_message_ms_uicc_low_level_access_open_channel_response_parse (
    const MbimMessage *message,
    guint32 *out_status,
    guint32 *out_channel,
    guint32 *out_response_size,
    const guint8 **out_response,
    GError **error)
{
    gboolean success = FALSE;
    guint32 offset = 0;

    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_COMMAND_DONE) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message is not a response");
        return FALSE;
    }

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL)) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message does not have information buffer");
        return FALSE;
    }

    /* Read the 'Status' variable */
    {
        if ((out_status != NULL) && !_mbim_message_read_guint32 (message, offset, out_status, error))
            goto out;
        offset += 4;
    }

    /* Read the 'Channel' variable */
    {
        if ((out_channel != NULL) && !_mbim_message_read_guint32 (message, offset, out_channel, error))
            goto out;
        offset += 4;
    }

    /* Read the 'Response' variable */
    {
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, error, TRUE))
            goto out;
        if (out_response != NULL)
            *out_response = tmp;
        if (out_response_size != NULL)
            *out_response_size = tmpsize;
        offset += 8;
    }

    /* All variables successfully parsed */
    success = TRUE;

 out:


    return success;
}

static gchar *
mbim_message_ms_uicc_low_level_access_open_channel_response_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  Status = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  Channel = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  Response = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, TRUE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Set): MBIM Message MS UICC Low Level Access Close Channel */

MbimMessage *
mbim_message_ms_uicc_low_level_access_close_channel_set_new (
    guint32 channel,
    guint32 channel_group,
    GError **error)
{
    MbimMessageCommandBuilder *builder;

    builder = _mbim_message_command_builder_new (0,
                                                 MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS,
                                                 MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_CLOSE_CHANNEL,
                                                 MBIM_MESSAGE_COMMAND_TYPE_SET);
    {
        _mbim_message_command_builder_append_guint32 (builder, channel);
    }
    {
        _mbim_message_command_builder_append_guint32 (builder, channel_group);
    }

    return _mbim_message_command_builder_complete (builder);
}

static gchar *
mbim_message_ms_uicc_low_level_access_close_channel_set_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  Channel = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  ChannelGroup = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Response): MBIM Message MS UICC Low Level Access Close Channel */

gboolean
mbim_message_ms_uicc_low_level_access_close_channel_response_parse (
    const MbimMessage *message,
    guint32 *out_status,
    GError **error)
{
    gboolean success = FALSE;
    guint32 offset = 0;

    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_COMMAND_DONE) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message is not a response");
        return FALSE;
    }

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL)) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message does not have information buffer");
        return FALSE;
    }

    /* Read the 'Status' variable */
    {
        if ((out_status != NULL) && !_mbim_message_read_guint32 (message, offset, out_status, error))
            goto out;
        offset += 4;
    }

    /* All variables successfully parsed */
    success = TRUE;

 out:


    return success;
}

static gchar *
mbim_message_ms_uicc_low_level_access_close_channel_response_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  Status = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Set): MBIM Message MS UICC Low Level Access APDU */

MbimMessage *
mbim_message_ms_uicc_low_level_access_apdu_set_new (
    guint32 channel,
    MbimUiccSecureMessaging secure_messaging,
    MbimUiccClassByteType class_byte_type,
    const guint32 command_size,
    const guint8 *command,
    GError **error)
{
    MbimMessageCommandBuilder *builder;

    builder = _mbim_message_command_builder_new (0,
                                                 MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS,
                                                 MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_APDU,
                                                 MBIM_MESSAGE_COMMAND_TYPE_SET);
    {
        _mbim_message_command_builder_append_guint32 (builder, channel);
    }
    {
        _mbim_message_command_builder_append_guint32 (builder, secure_messaging);
    }
    {
        _mbim_message_command_builder_append_guint32 (builder, class_byte_type);
    }
    {
        _mbim_message_command_builder_append_byte_array (builder, TRUE, TRUE, TRUE, command, command_size, TRUE);
    }

    return _mbim_message_command_builder_complete (builder);
}

static gchar *
mbim_message_ms_uicc_low_level_access_apdu_set_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  Channel = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  SecureMessaging = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
#if defined __MBIM_UICC_SECURE_MESSAGING_IS_ENUM__
            g_string_append_printf (str, "'%s'", mbim_uicc_secure_messaging_get_string ((MbimUiccSecureMessaging)tmp));
#elif defined __MBIM_UICC_SECURE_MESSAGING_IS_FLAGS__
            g_autofree gchar *tmpstr = NULL;

            tmpstr = mbim_uicc_secure_messaging_build_string_from_mask ((MbimUiccSecureMessaging)tmp);
            g_string_append_printf (str, "'%s'", tmpstr);
#else
# error neither enum nor flags
#endif
        }

    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  ClassByteType = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
#if defined __MBIM_UICC_CLASS_BYTE_TYPE_IS_ENUM__
            g_string_append_printf (str, "'%s'", mbim_uicc_class_byte_type_get_string ((MbimUiccClassByteType)tmp));
#elif defined __MBIM_UICC_CLASS_BYTE_TYPE_IS_FLAGS__
            g_autofree gchar *tmpstr = NULL;

            tmpstr = mbim_uicc_class_byte_type_build_string_from_mask ((MbimUiccClassByteType)tmp);
            g_string_append_printf (str, "'%s'", tmpstr);
#else
# error neither enum nor flags
#endif
        }

    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  Command = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, TRUE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Response): MBIM Message MS UICC Low Level Access APDU */

gboolean
mbim_message_ms_uicc_low_level_access_apdu_response_parse (
    const MbimMessage *message,
    guint32 *out_status,
    guint32 *out_response_size,
    const guint8 **out_response,
    GError **error)
{
    gboolean success = FALSE;
    guint32 offset = 0;

    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_COMMAND_DONE) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message is not a response");
        return FALSE;
    }

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL)) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message does not have information buffer");
        return FALSE;
    }

    /* Read the 'Status' variable */
    {
        if ((out_status != NULL) && !_mbim_message_read_guint32 (message, offset, out_status, error))
            goto out;
        offset += 4;
    }

    /* Read the 'Response' variable */
    {
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, error, TRUE))
            goto out;
        if (out_response != NULL)
            *out_response = tmp;
        if (out_response_size != NULL)
            *out_response_size = tmpsize;
        offset += 8;
    }

    /* All variables successfully parsed */
    success = TRUE;

 out:


    return success;
}

static gchar *
mbim_message_ms_uicc_low_level_access_apdu_response_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  Status = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  Response = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, TRUE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Query): MBIM Message MS UICC Low Level Access Terminal Capability */

MbimMessage *
mbim_message_ms_uicc_low_level_access_terminal_capability_query_new (
    GError **error)
{
    MbimMessageCommandBuilder *builder;

    builder = _mbim_message_command_builder_new (0,
                                                 MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS,
                                                 MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_TERMINAL_CAPABILITY,
                                                 MBIM_MESSAGE_COMMAND_TYPE_QUERY);

    return _mbim_message_command_builder_complete (builder);
}

static gchar *
mbim_message_ms_uicc_low_level_access_terminal_capability_query_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;

    str = g_string_new ("");

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Set): MBIM Message MS UICC Low Level Access Terminal Capability */

MbimMessage *
mbim_message_ms_uicc_low_level_access_terminal_capability_set_new (
    guint32 terminal_capability_count,
    const MbimTerminalCapabilityInfo *const *terminal_capability,
    GError **error)
{
    MbimMessageCommandBuilder *builder;

    builder = _mbim_message_command_builder_new (0,
                                                 MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS,
                                                 MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_TERMINAL_CAPABILITY,
                                                 MBIM_MESSAGE_COMMAND_TYPE_SET);
    {
        _mbim_message_command_builder_append_guint32 (builder, terminal_capability_count);
    }
    {
        _mbim_message_command_builder_append_mbim_terminal_capability_info_ref_struct_array (builder, terminal_capability, terminal_capability_count);
    }

    return _mbim_message_command_builder_complete (builder);
}

static gchar *
mbim_message_ms_uicc_low_level_access_terminal_capability_set_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;
    guint32 _terminal_capability_count;

    if (!mbim_message_command_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  TerminalCapabilityCount = ", line_prefix);
    {
        if (!_mbim_message_read_guint32 (message, offset, &_terminal_capability_count, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", _terminal_capability_count);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  TerminalCapability = ", line_prefix);
    {
        g_autoptr(MbimTerminalCapabilityInfoArray) tmp = NULL;

        if (!_mbim_message_read_mbim_terminal_capability_info_ref_struct_array (message, _terminal_capability_count, offset, &tmp, &inner_error))
            goto out;
        offset += (8 * _terminal_capability_count);
        {
            guint i;
            g_autofree gchar *new_line_prefix = NULL;

            new_line_prefix = g_strdup_printf ("%s        ", line_prefix);
            g_string_append (str, "'{\n");
            for (i = 0; i < _terminal_capability_count; i++) {
                g_autofree gchar *struct_str = NULL;

                g_string_append_printf (str, "%s    [%u] = {\n", line_prefix, i);
                struct_str = _mbim_message_print_mbim_terminal_capability_info_struct (tmp[i], new_line_prefix);
                g_string_append (str, struct_str);
                g_string_append_printf (str, "%s    },\n", line_prefix);
            }
            g_string_append_printf (str, "%s  }'", line_prefix);
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Response): MBIM Message MS UICC Low Level Access Terminal Capability */

gboolean
mbim_message_ms_uicc_low_level_access_terminal_capability_response_parse (
    const MbimMessage *message,
    guint32 *out_terminal_capability_count,
    MbimTerminalCapabilityInfoArray **out_terminal_capability,
    GError **error)
{
    gboolean success = FALSE;
    guint32 offset = 0;
    guint32 _terminal_capability_count;
    MbimTerminalCapabilityInfo **_terminal_capability = NULL;

    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_COMMAND_DONE) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message is not a response");
        return FALSE;
    }

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL)) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message does not have information buffer");
        return FALSE;
    }

    /* Read the 'TerminalCapabilityCount' variable */
    {
        if (!_mbim_message_read_guint32 (message, offset, &_terminal_capability_count, error))
            goto out;
        if (out_terminal_capability_count != NULL)
            *out_terminal_capability_count = _terminal_capability_count;
        offset += 4;
    }

    /* Read the 'TerminalCapability' variable */
    {
        if ((out_terminal_capability != NULL) && !_mbim_message_read_mbim_terminal_capability_info_ref_struct_array (message, _terminal_capability_count, offset, &_terminal_capability, error))
            goto out;
        offset += (8 * _terminal_capability_count);
    }

    /* All variables successfully parsed */
    success = TRUE;

 out:

    if (success) {
        /* Memory allocated variables as output */
        if (out_terminal_capability != NULL)
            *out_terminal_capability = _terminal_capability;
    } else {
        mbim_terminal_capability_info_array_free (_terminal_capability);
    }

    return success;
}

static gchar *
mbim_message_ms_uicc_low_level_access_terminal_capability_response_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;
    guint32 _terminal_capability_count;

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  TerminalCapabilityCount = ", line_prefix);
    {
        if (!_mbim_message_read_guint32 (message, offset, &_terminal_capability_count, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", _terminal_capability_count);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  TerminalCapability = ", line_prefix);
    {
        g_autoptr(MbimTerminalCapabilityInfoArray) tmp = NULL;

        if (!_mbim_message_read_mbim_terminal_capability_info_ref_struct_array (message, _terminal_capability_count, offset, &tmp, &inner_error))
            goto out;
        offset += (8 * _terminal_capability_count);
        {
            guint i;
            g_autofree gchar *new_line_prefix = NULL;

            new_line_prefix = g_strdup_printf ("%s        ", line_prefix);
            g_string_append (str, "'{\n");
            for (i = 0; i < _terminal_capability_count; i++) {
                g_autofree gchar *struct_str = NULL;

                g_string_append_printf (str, "%s    [%u] = {\n", line_prefix, i);
                struct_str = _mbim_message_print_mbim_terminal_capability_info_struct (tmp[i], new_line_prefix);
                g_string_append (str, struct_str);
                g_string_append_printf (str, "%s    },\n", line_prefix);
            }
            g_string_append_printf (str, "%s  }'", line_prefix);
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Query): MBIM Message MS UICC Low Level Access Reset */

MbimMessage *
mbim_message_ms_uicc_low_level_access_reset_query_new (
    GError **error)
{
    MbimMessageCommandBuilder *builder;

    builder = _mbim_message_command_builder_new (0,
                                                 MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS,
                                                 MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_RESET,
                                                 MBIM_MESSAGE_COMMAND_TYPE_QUERY);

    return _mbim_message_command_builder_complete (builder);
}

static gchar *
mbim_message_ms_uicc_low_level_access_reset_query_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;

    str = g_string_new ("");

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Set): MBIM Message MS UICC Low Level Access Reset */

MbimMessage *
mbim_message_ms_uicc_low_level_access_reset_set_new (
    MbimUiccPassThroughAction pass_through_action,
    GError **error)
{
    MbimMessageCommandBuilder *builder;

    builder = _mbim_message_command_builder_new (0,
                                                 MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS,
                                                 MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_RESET,
                                                 MBIM_MESSAGE_COMMAND_TYPE_SET);
    {
        _mbim_message_command_builder_append_guint32 (builder, pass_through_action);
    }

    return _mbim_message_command_builder_complete (builder);
}

static gchar *
mbim_message_ms_uicc_low_level_access_reset_set_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  PassThroughAction = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
#if defined __MBIM_UICC_PASS_THROUGH_ACTION_IS_ENUM__
            g_string_append_printf (str, "'%s'", mbim_uicc_pass_through_action_get_string ((MbimUiccPassThroughAction)tmp));
#elif defined __MBIM_UICC_PASS_THROUGH_ACTION_IS_FLAGS__
            g_autofree gchar *tmpstr = NULL;

            tmpstr = mbim_uicc_pass_through_action_build_string_from_mask ((MbimUiccPassThroughAction)tmp);
            g_string_append_printf (str, "'%s'", tmpstr);
#else
# error neither enum nor flags
#endif
        }

    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Response): MBIM Message MS UICC Low Level Access Reset */

gboolean
mbim_message_ms_uicc_low_level_access_reset_response_parse (
    const MbimMessage *message,
    MbimUiccPassThroughStatus *out_pass_through_status,
    GError **error)
{
    gboolean success = FALSE;
    guint32 offset = 0;

    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_COMMAND_DONE) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message is not a response");
        return FALSE;
    }

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL)) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message does not have information buffer");
        return FALSE;
    }

    /* Read the 'PassThroughStatus' variable */
    {
        if (out_pass_through_status != NULL) {
            guint32 aux;

            if (!_mbim_message_read_guint32 (message, offset, &aux, error))
                goto out;
            *out_pass_through_status = (MbimUiccPassThroughStatus)aux;
        }
        offset += 4;
    }

    /* All variables successfully parsed */
    success = TRUE;

 out:


    return success;
}

static gchar *
mbim_message_ms_uicc_low_level_access_reset_response_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  PassThroughStatus = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
#if defined __MBIM_UICC_PASS_THROUGH_STATUS_IS_ENUM__
            g_string_append_printf (str, "'%s'", mbim_uicc_pass_through_status_get_string ((MbimUiccPassThroughStatus)tmp));
#elif defined __MBIM_UICC_PASS_THROUGH_STATUS_IS_FLAGS__
            g_autofree gchar *tmpstr = NULL;

            tmpstr = mbim_uicc_pass_through_status_build_string_from_mask ((MbimUiccPassThroughStatus)tmp);
            g_string_append_printf (str, "'%s'", tmpstr);
#else
# error neither enum nor flags
#endif
        }

    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Query): MBIM Message MS UICC Low Level Access Application List */

MbimMessage *
mbim_message_ms_uicc_low_level_access_application_list_query_new (
    GError **error)
{
    MbimMessageCommandBuilder *builder;

    builder = _mbim_message_command_builder_new (0,
                                                 MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS,
                                                 MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_APPLICATION_LIST,
                                                 MBIM_MESSAGE_COMMAND_TYPE_QUERY);

    return _mbim_message_command_builder_complete (builder);
}

static gchar *
mbim_message_ms_uicc_low_level_access_application_list_query_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;

    str = g_string_new ("");

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Response): MBIM Message MS UICC Low Level Access Application List */

gboolean
mbim_message_ms_uicc_low_level_access_application_list_response_parse (
    const MbimMessage *message,
    guint32 *out_version,
    guint32 *out_application_count,
    guint32 *out_active_application_index,
    guint32 *out_application_list_size_bytes,
    MbimUiccApplicationArray **out_applications,
    GError **error)
{
    gboolean success = FALSE;
    guint32 offset = 0;
    guint32 _application_count;
    MbimUiccApplication **_applications = NULL;

    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_COMMAND_DONE) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message is not a response");
        return FALSE;
    }

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL)) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message does not have information buffer");
        return FALSE;
    }

    /* Read the 'Version' variable */
    {
        if ((out_version != NULL) && !_mbim_message_read_guint32 (message, offset, out_version, error))
            goto out;
        offset += 4;
    }

    /* Read the 'ApplicationCount' variable */
    {
        if (!_mbim_message_read_guint32 (message, offset, &_application_count, error))
            goto out;
        if (out_application_count != NULL)
            *out_application_count = _application_count;
        offset += 4;
    }

    /* Read the 'ActiveApplicationIndex' variable */
    {
        if ((out_active_application_index != NULL) && !_mbim_message_read_guint32 (message, offset, out_active_application_index, error))
            goto out;
        offset += 4;
    }

    /* Read the 'ApplicationListSizeBytes' variable */
    {
        if ((out_application_list_size_bytes != NULL) && !_mbim_message_read_guint32 (message, offset, out_application_list_size_bytes, error))
            goto out;
        offset += 4;
    }

    /* Read the 'Applications' variable */
    {
        if ((out_applications != NULL) && !_mbim_message_read_mbim_uicc_application_ref_struct_array (message, _application_count, offset, &_applications, error))
            goto out;
        offset += (8 * _application_count);
    }

    /* All variables successfully parsed */
    success = TRUE;

 out:

    if (success) {
        /* Memory allocated variables as output */
        if (out_applications != NULL)
            *out_applications = _applications;
    } else {
        mbim_uicc_application_array_free (_applications);
    }

    return success;
}

static gchar *
mbim_message_ms_uicc_low_level_access_application_list_response_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;
    guint32 _application_count;

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  Version = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  ApplicationCount = ", line_prefix);
    {
        if (!_mbim_message_read_guint32 (message, offset, &_application_count, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", _application_count);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  ActiveApplicationIndex = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  ApplicationListSizeBytes = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  Applications = ", line_prefix);
    {
        g_autoptr(MbimUiccApplicationArray) tmp = NULL;

        if (!_mbim_message_read_mbim_uicc_application_ref_struct_array (message, _application_count, offset, &tmp, &inner_error))
            goto out;
        offset += (8 * _application_count);
        {
            guint i;
            g_autofree gchar *new_line_prefix = NULL;

            new_line_prefix = g_strdup_printf ("%s        ", line_prefix);
            g_string_append (str, "'{\n");
            for (i = 0; i < _application_count; i++) {
                g_autofree gchar *struct_str = NULL;

                g_string_append_printf (str, "%s    [%u] = {\n", line_prefix, i);
                struct_str = _mbim_message_print_mbim_uicc_application_struct (tmp[i], new_line_prefix);
                g_string_append (str, struct_str);
                g_string_append_printf (str, "%s    },\n", line_prefix);
            }
            g_string_append_printf (str, "%s  }'", line_prefix);
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Query): MBIM Message MS UICC Low Level Access File Status */

MbimMessage *
mbim_message_ms_uicc_low_level_access_file_status_query_new (
    guint32 version,
    const guint32 application_id_size,
    const guint8 *application_id,
    const guint32 file_path_size,
    const guint8 *file_path,
    GError **error)
{
    MbimMessageCommandBuilder *builder;

    builder = _mbim_message_command_builder_new (0,
                                                 MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS,
                                                 MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_FILE_STATUS,
                                                 MBIM_MESSAGE_COMMAND_TYPE_QUERY);
    {
        _mbim_message_command_builder_append_guint32 (builder, version);
    }
    {
        _mbim_message_command_builder_append_byte_array (builder, TRUE, TRUE, TRUE, application_id, application_id_size, FALSE);
    }
    {
        _mbim_message_command_builder_append_byte_array (builder, TRUE, TRUE, TRUE, file_path, file_path_size, FALSE);
    }

    return _mbim_message_command_builder_complete (builder);
}

static gchar *
mbim_message_ms_uicc_low_level_access_file_status_query_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  Version = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  ApplicationId = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, FALSE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  FilePath = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, FALSE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Response): MBIM Message MS UICC Low Level Access File Status */

gboolean
mbim_message_ms_uicc_low_level_access_file_status_response_parse (
    const MbimMessage *message,
    guint32 *out_version,
    guint32 *out_status_word1,
    guint32 *out_status_word2,
    MbimUiccFileAccessibility *out_file_accessibility,
    MbimUiccFileType *out_file_type,
    MbimUiccFileStructure *out_file_structure,
    guint32 *out_file_item_count,
    guint32 *out_file_item_size,
    MbimPinType *out_access_condition_read,
    MbimPinType *out_access_condition_update,
    MbimPinType *out_access_condition_activate,
    MbimPinType *out_access_condition_deactivate,
    GError **error)
{
    gboolean success = FALSE;
    guint32 offset = 0;

    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_COMMAND_DONE) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message is not a response");
        return FALSE;
    }

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL)) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message does not have information buffer");
        return FALSE;
    }

    /* Read the 'Version' variable */
    {
        if ((out_version != NULL) && !_mbim_message_read_guint32 (message, offset, out_version, error))
            goto out;
        offset += 4;
    }

    /* Read the 'StatusWord1' variable */
    {
        if ((out_status_word1 != NULL) && !_mbim_message_read_guint32 (message, offset, out_status_word1, error))
            goto out;
        offset += 4;
    }

    /* Read the 'StatusWord2' variable */
    {
        if ((out_status_word2 != NULL) && !_mbim_message_read_guint32 (message, offset, out_status_word2, error))
            goto out;
        offset += 4;
    }

    /* Read the 'FileAccessibility' variable */
    {
        if (out_file_accessibility != NULL) {
            guint32 aux;

            if (!_mbim_message_read_guint32 (message, offset, &aux, error))
                goto out;
            *out_file_accessibility = (MbimUiccFileAccessibility)aux;
        }
        offset += 4;
    }

    /* Read the 'FileType' variable */
    {
        if (out_file_type != NULL) {
            guint32 aux;

            if (!_mbim_message_read_guint32 (message, offset, &aux, error))
                goto out;
            *out_file_type = (MbimUiccFileType)aux;
        }
        offset += 4;
    }

    /* Read the 'FileStructure' variable */
    {
        if (out_file_structure != NULL) {
            guint32 aux;

            if (!_mbim_message_read_guint32 (message, offset, &aux, error))
                goto out;
            *out_file_structure = (MbimUiccFileStructure)aux;
        }
        offset += 4;
    }

    /* Read the 'FileItemCount' variable */
    {
        if ((out_file_item_count != NULL) && !_mbim_message_read_guint32 (message, offset, out_file_item_count, error))
            goto out;
        offset += 4;
    }

    /* Read the 'FileItemSize' variable */
    {
        if ((out_file_item_size != NULL) && !_mbim_message_read_guint32 (message, offset, out_file_item_size, error))
            goto out;
        offset += 4;
    }

    /* Read the 'AccessConditionRead' variable */
    {
        if (out_access_condition_read != NULL) {
            guint32 aux;

            if (!_mbim_message_read_guint32 (message, offset, &aux, error))
                goto out;
            *out_access_condition_read = (MbimPinType)aux;
        }
        offset += 4;
    }

    /* Read the 'AccessConditionUpdate' variable */
    {
        if (out_access_condition_update != NULL) {
            guint32 aux;

            if (!_mbim_message_read_guint32 (message, offset, &aux, error))
                goto out;
            *out_access_condition_update = (MbimPinType)aux;
        }
        offset += 4;
    }

    /* Read the 'AccessConditionActivate' variable */
    {
        if (out_access_condition_activate != NULL) {
            guint32 aux;

            if (!_mbim_message_read_guint32 (message, offset, &aux, error))
                goto out;
            *out_access_condition_activate = (MbimPinType)aux;
        }
        offset += 4;
    }

    /* Read the 'AccessConditionDeactivate' variable */
    {
        if (out_access_condition_deactivate != NULL) {
            guint32 aux;

            if (!_mbim_message_read_guint32 (message, offset, &aux, error))
                goto out;
            *out_access_condition_deactivate = (MbimPinType)aux;
        }
        offset += 4;
    }

    /* All variables successfully parsed */
    success = TRUE;

 out:


    return success;
}

static gchar *
mbim_message_ms_uicc_low_level_access_file_status_response_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  Version = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  StatusWord1 = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  StatusWord2 = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  FileAccessibility = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
#if defined __MBIM_UICC_FILE_ACCESSIBILITY_IS_ENUM__
            g_string_append_printf (str, "'%s'", mbim_uicc_file_accessibility_get_string ((MbimUiccFileAccessibility)tmp));
#elif defined __MBIM_UICC_FILE_ACCESSIBILITY_IS_FLAGS__
            g_autofree gchar *tmpstr = NULL;

            tmpstr = mbim_uicc_file_accessibility_build_string_from_mask ((MbimUiccFileAccessibility)tmp);
            g_string_append_printf (str, "'%s'", tmpstr);
#else
# error neither enum nor flags
#endif
        }

    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  FileType = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
#if defined __MBIM_UICC_FILE_TYPE_IS_ENUM__
            g_string_append_printf (str, "'%s'", mbim_uicc_file_type_get_string ((MbimUiccFileType)tmp));
#elif defined __MBIM_UICC_FILE_TYPE_IS_FLAGS__
            g_autofree gchar *tmpstr = NULL;

            tmpstr = mbim_uicc_file_type_build_string_from_mask ((MbimUiccFileType)tmp);
            g_string_append_printf (str, "'%s'", tmpstr);
#else
# error neither enum nor flags
#endif
        }

    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  FileStructure = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
#if defined __MBIM_UICC_FILE_STRUCTURE_IS_ENUM__
            g_string_append_printf (str, "'%s'", mbim_uicc_file_structure_get_string ((MbimUiccFileStructure)tmp));
#elif defined __MBIM_UICC_FILE_STRUCTURE_IS_FLAGS__
            g_autofree gchar *tmpstr = NULL;

            tmpstr = mbim_uicc_file_structure_build_string_from_mask ((MbimUiccFileStructure)tmp);
            g_string_append_printf (str, "'%s'", tmpstr);
#else
# error neither enum nor flags
#endif
        }

    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  FileItemCount = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  FileItemSize = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  AccessConditionRead = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
#if defined __MBIM_PIN_TYPE_IS_ENUM__
            g_string_append_printf (str, "'%s'", mbim_pin_type_get_string ((MbimPinType)tmp));
#elif defined __MBIM_PIN_TYPE_IS_FLAGS__
            g_autofree gchar *tmpstr = NULL;

            tmpstr = mbim_pin_type_build_string_from_mask ((MbimPinType)tmp);
            g_string_append_printf (str, "'%s'", tmpstr);
#else
# error neither enum nor flags
#endif
        }

    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  AccessConditionUpdate = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
#if defined __MBIM_PIN_TYPE_IS_ENUM__
            g_string_append_printf (str, "'%s'", mbim_pin_type_get_string ((MbimPinType)tmp));
#elif defined __MBIM_PIN_TYPE_IS_FLAGS__
            g_autofree gchar *tmpstr = NULL;

            tmpstr = mbim_pin_type_build_string_from_mask ((MbimPinType)tmp);
            g_string_append_printf (str, "'%s'", tmpstr);
#else
# error neither enum nor flags
#endif
        }

    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  AccessConditionActivate = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
#if defined __MBIM_PIN_TYPE_IS_ENUM__
            g_string_append_printf (str, "'%s'", mbim_pin_type_get_string ((MbimPinType)tmp));
#elif defined __MBIM_PIN_TYPE_IS_FLAGS__
            g_autofree gchar *tmpstr = NULL;

            tmpstr = mbim_pin_type_build_string_from_mask ((MbimPinType)tmp);
            g_string_append_printf (str, "'%s'", tmpstr);
#else
# error neither enum nor flags
#endif
        }

    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  AccessConditionDeactivate = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
#if defined __MBIM_PIN_TYPE_IS_ENUM__
            g_string_append_printf (str, "'%s'", mbim_pin_type_get_string ((MbimPinType)tmp));
#elif defined __MBIM_PIN_TYPE_IS_FLAGS__
            g_autofree gchar *tmpstr = NULL;

            tmpstr = mbim_pin_type_build_string_from_mask ((MbimPinType)tmp);
            g_string_append_printf (str, "'%s'", tmpstr);
#else
# error neither enum nor flags
#endif
        }

    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Query): MBIM Message MS UICC Low Level Access Read Binary */

MbimMessage *
mbim_message_ms_uicc_low_level_access_read_binary_query_new (
    guint32 version,
    const guint32 application_id_size,
    const guint8 *application_id,
    const guint32 file_path_size,
    const guint8 *file_path,
    guint32 read_offset,
    guint32 read_size,
    const gchar *local_pin,
    const guint32 data_size,
    const guint8 *data,
    GError **error)
{
    MbimMessageCommandBuilder *builder;

    builder = _mbim_message_command_builder_new (0,
                                                 MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS,
                                                 MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_BINARY,
                                                 MBIM_MESSAGE_COMMAND_TYPE_QUERY);
    {
        _mbim_message_command_builder_append_guint32 (builder, version);
    }
    {
        _mbim_message_command_builder_append_byte_array (builder, TRUE, TRUE, TRUE, application_id, application_id_size, FALSE);
    }
    {
        _mbim_message_command_builder_append_byte_array (builder, TRUE, TRUE, TRUE, file_path, file_path_size, FALSE);
    }
    {
        _mbim_message_command_builder_append_guint32 (builder, read_offset);
    }
    {
        _mbim_message_command_builder_append_guint32 (builder, read_size);
    }
    {
        _mbim_message_command_builder_append_string (builder, local_pin);
    }
    {
        _mbim_message_command_builder_append_byte_array (builder, TRUE, TRUE, TRUE, data, data_size, FALSE);
    }

    return _mbim_message_command_builder_complete (builder);
}

static gchar *
mbim_message_ms_uicc_low_level_access_read_binary_query_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  Version = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  ApplicationId = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, FALSE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  FilePath = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, FALSE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  ReadOffset = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  ReadSize = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  LocalPin = ", line_prefix);
    {
        g_autofree gchar *tmp = NULL;

        if (!_mbim_message_read_string (message, 0, offset, MBIM_STRING_ENCODING_UTF16, &tmp, NULL, &inner_error))
            goto out;
        offset += 8;
        {
            g_string_append_printf (str, "'%s'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  Data = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, FALSE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Response): MBIM Message MS UICC Low Level Access Read Binary */

gboolean
mbim_message_ms_uicc_low_level_access_read_binary_response_parse (
    const MbimMessage *message,
    guint32 *out_version,
    guint32 *out_status_word1,
    guint32 *out_status_word2,
    guint32 *out_data_size,
    const guint8 **out_data,
    GError **error)
{
    gboolean success = FALSE;
    guint32 offset = 0;

    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_COMMAND_DONE) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message is not a response");
        return FALSE;
    }

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL)) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message does not have information buffer");
        return FALSE;
    }

    /* Read the 'Version' variable */
    {
        if ((out_version != NULL) && !_mbim_message_read_guint32 (message, offset, out_version, error))
            goto out;
        offset += 4;
    }

    /* Read the 'StatusWord1' variable */
    {
        if ((out_status_word1 != NULL) && !_mbim_message_read_guint32 (message, offset, out_status_word1, error))
            goto out;
        offset += 4;
    }

    /* Read the 'StatusWord2' variable */
    {
        if ((out_status_word2 != NULL) && !_mbim_message_read_guint32 (message, offset, out_status_word2, error))
            goto out;
        offset += 4;
    }

    /* Read the 'Data' variable */
    {
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, error, FALSE))
            goto out;
        if (out_data != NULL)
            *out_data = tmp;
        if (out_data_size != NULL)
            *out_data_size = tmpsize;
        offset += 8;
    }

    /* All variables successfully parsed */
    success = TRUE;

 out:


    return success;
}

static gchar *
mbim_message_ms_uicc_low_level_access_read_binary_response_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  Version = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  StatusWord1 = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  StatusWord2 = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  Data = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, FALSE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Query): MBIM Message MS UICC Low Level Access Read Record */

MbimMessage *
mbim_message_ms_uicc_low_level_access_read_record_query_new (
    guint32 version,
    const guint32 application_id_size,
    const guint8 *application_id,
    const guint32 file_path_size,
    const guint8 *file_path,
    guint32 record_number,
    const gchar *local_pin,
    const guint32 data_size,
    const guint8 *data,
    GError **error)
{
    MbimMessageCommandBuilder *builder;

    builder = _mbim_message_command_builder_new (0,
                                                 MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS,
                                                 MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_RECORD,
                                                 MBIM_MESSAGE_COMMAND_TYPE_QUERY);
    {
        _mbim_message_command_builder_append_guint32 (builder, version);
    }
    {
        _mbim_message_command_builder_append_byte_array (builder, TRUE, TRUE, TRUE, application_id, application_id_size, FALSE);
    }
    {
        _mbim_message_command_builder_append_byte_array (builder, TRUE, TRUE, TRUE, file_path, file_path_size, FALSE);
    }
    {
        _mbim_message_command_builder_append_guint32 (builder, record_number);
    }
    {
        _mbim_message_command_builder_append_string (builder, local_pin);
    }
    {
        _mbim_message_command_builder_append_byte_array (builder, TRUE, TRUE, TRUE, data, data_size, FALSE);
    }

    return _mbim_message_command_builder_complete (builder);
}

static gchar *
mbim_message_ms_uicc_low_level_access_read_record_query_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  Version = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  ApplicationId = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, FALSE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  FilePath = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, FALSE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  RecordNumber = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  LocalPin = ", line_prefix);
    {
        g_autofree gchar *tmp = NULL;

        if (!_mbim_message_read_string (message, 0, offset, MBIM_STRING_ENCODING_UTF16, &tmp, NULL, &inner_error))
            goto out;
        offset += 8;
        {
            g_string_append_printf (str, "'%s'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  Data = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, FALSE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

/*****************************************************************************/
/* Message (Response): MBIM Message MS UICC Low Level Access Read Record */

gboolean
mbim_message_ms_uicc_low_level_access_read_record_response_parse (
    const MbimMessage *message,
    guint32 *out_version,
    guint32 *out_status_word1,
    guint32 *out_status_word2,
    guint32 *out_data_size,
    const guint8 **out_data,
    GError **error)
{
    gboolean success = FALSE;
    guint32 offset = 0;

    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_COMMAND_DONE) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message is not a response");
        return FALSE;
    }

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL)) {
        g_set_error (error,
                     MBIM_CORE_ERROR,
                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                     "Message does not have information buffer");
        return FALSE;
    }

    /* Read the 'Version' variable */
    {
        if ((out_version != NULL) && !_mbim_message_read_guint32 (message, offset, out_version, error))
            goto out;
        offset += 4;
    }

    /* Read the 'StatusWord1' variable */
    {
        if ((out_status_word1 != NULL) && !_mbim_message_read_guint32 (message, offset, out_status_word1, error))
            goto out;
        offset += 4;
    }

    /* Read the 'StatusWord2' variable */
    {
        if ((out_status_word2 != NULL) && !_mbim_message_read_guint32 (message, offset, out_status_word2, error))
            goto out;
        offset += 4;
    }

    /* Read the 'Data' variable */
    {
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, error, FALSE))
            goto out;
        if (out_data != NULL)
            *out_data = tmp;
        if (out_data_size != NULL)
            *out_data_size = tmpsize;
        offset += 8;
    }

    /* All variables successfully parsed */
    success = TRUE;

 out:


    return success;
}

static gchar *
mbim_message_ms_uicc_low_level_access_read_record_response_get_printable (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    GString *str;
    GError *inner_error = NULL;
    guint32 offset = 0;

    if (!mbim_message_command_done_get_raw_information_buffer (message, NULL))
        return NULL;

    str = g_string_new ("");

    g_string_append_printf (str, "%s  Version = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  StatusWord1 = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  StatusWord2 = ", line_prefix);
    {
        guint32 tmp;

        if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))
            goto out;
        offset += 4;
        {
            g_string_append_printf (str, "'%" G_GUINT32_FORMAT "'", tmp);
        }
    }
    g_string_append (str, "\n");

    g_string_append_printf (str, "%s  Data = ", line_prefix);
    {
        guint i;
        const guint8 *tmp;
        guint32 tmpsize;

        if (!_mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, 0, &tmp, &tmpsize, &inner_error, FALSE))
            goto out;
        offset += 8;
        {
            g_string_append (str, "'");
            for (i = 0; i  < tmpsize; i++)
                g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );
            g_string_append (str, "'");
        }
    }
    g_string_append (str, "\n");

 out:
    if (inner_error) {
        g_string_append_printf (str, "n/a: %s", inner_error->message);
        g_clear_error (&inner_error);
    }

    return g_string_free (str, FALSE);
}

typedef struct {
  gchar * (* query_cb)        (const MbimMessage *message, const gchar *line_prefix, GError **error);
  gchar * (* set_cb)          (const MbimMessage *message, const gchar *line_prefix, GError **error);
  gchar * (* response_cb)     (const MbimMessage *message, const gchar *line_prefix, GError **error);
  gchar * (* notification_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);
} GetPrintableCallbacks;

static const GetPrintableCallbacks ms_uicc_low_level_access_get_printable_callbacks[] = {
    [MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_ATR] = {
        .query_cb = mbim_message_ms_uicc_low_level_access_atr_query_get_printable,
        .response_cb = mbim_message_ms_uicc_low_level_access_atr_response_get_printable,
    },
    [MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_OPEN_CHANNEL] = {
        .set_cb = mbim_message_ms_uicc_low_level_access_open_channel_set_get_printable,
        .response_cb = mbim_message_ms_uicc_low_level_access_open_channel_response_get_printable,
    },
    [MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_CLOSE_CHANNEL] = {
        .set_cb = mbim_message_ms_uicc_low_level_access_close_channel_set_get_printable,
        .response_cb = mbim_message_ms_uicc_low_level_access_close_channel_response_get_printable,
    },
    [MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_APDU] = {
        .set_cb = mbim_message_ms_uicc_low_level_access_apdu_set_get_printable,
        .response_cb = mbim_message_ms_uicc_low_level_access_apdu_response_get_printable,
    },
    [MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_TERMINAL_CAPABILITY] = {
        .query_cb = mbim_message_ms_uicc_low_level_access_terminal_capability_query_get_printable,
        .set_cb = mbim_message_ms_uicc_low_level_access_terminal_capability_set_get_printable,
        .response_cb = mbim_message_ms_uicc_low_level_access_terminal_capability_response_get_printable,
    },
    [MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_RESET] = {
        .query_cb = mbim_message_ms_uicc_low_level_access_reset_query_get_printable,
        .set_cb = mbim_message_ms_uicc_low_level_access_reset_set_get_printable,
        .response_cb = mbim_message_ms_uicc_low_level_access_reset_response_get_printable,
    },
    [MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_APPLICATION_LIST] = {
        .query_cb = mbim_message_ms_uicc_low_level_access_application_list_query_get_printable,
        .response_cb = mbim_message_ms_uicc_low_level_access_application_list_response_get_printable,
    },
    [MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_FILE_STATUS] = {
        .query_cb = mbim_message_ms_uicc_low_level_access_file_status_query_get_printable,
        .response_cb = mbim_message_ms_uicc_low_level_access_file_status_response_get_printable,
    },
    [MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_BINARY] = {
        .query_cb = mbim_message_ms_uicc_low_level_access_read_binary_query_get_printable,
        .response_cb = mbim_message_ms_uicc_low_level_access_read_binary_response_get_printable,
    },
    [MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_RECORD] = {
        .query_cb = mbim_message_ms_uicc_low_level_access_read_record_query_get_printable,
        .response_cb = mbim_message_ms_uicc_low_level_access_read_record_response_get_printable,
    },
};

gchar *
__mbim_message_ms_uicc_low_level_access_get_printable_fields (
    const MbimMessage *message,
    const gchar *line_prefix,
    GError **error)
{
    guint32 cid;

    switch (mbim_message_get_message_type (message)) {
        case MBIM_MESSAGE_TYPE_COMMAND: {
            cid = mbim_message_command_get_cid (message);
            if (cid < G_N_ELEMENTS (ms_uicc_low_level_access_get_printable_callbacks)) {
                switch (mbim_message_command_get_command_type (message)) {
                    case MBIM_MESSAGE_COMMAND_TYPE_QUERY:
                        if (ms_uicc_low_level_access_get_printable_callbacks[cid].query_cb)
                            return ms_uicc_low_level_access_get_printable_callbacks[cid].query_cb (message, line_prefix, error);
                        break;
                    case MBIM_MESSAGE_COMMAND_TYPE_SET:
                        if (ms_uicc_low_level_access_get_printable_callbacks[cid].set_cb)
                            return ms_uicc_low_level_access_get_printable_callbacks[cid].set_cb (message, line_prefix, error);
                        break;
                    case MBIM_MESSAGE_COMMAND_TYPE_UNKNOWN:
                    default:
                        g_set_error (error,
                                     MBIM_CORE_ERROR,
                                     MBIM_CORE_ERROR_INVALID_MESSAGE,
                                     "Invalid command type");
                        return NULL;
                }
            }
            break;
        }

        case MBIM_MESSAGE_TYPE_COMMAND_DONE:
            cid = mbim_message_command_done_get_cid (message);
            if (cid < G_N_ELEMENTS (ms_uicc_low_level_access_get_printable_callbacks)) {
                if (ms_uicc_low_level_access_get_printable_callbacks[cid].response_cb)
                    return ms_uicc_low_level_access_get_printable_callbacks[cid].response_cb (message, line_prefix, error);
            }
            break;

        case MBIM_MESSAGE_TYPE_INDICATE_STATUS:
            cid = mbim_message_indicate_status_get_cid (message);
            if (cid < G_N_ELEMENTS (ms_uicc_low_level_access_get_printable_callbacks)) {
                if (ms_uicc_low_level_access_get_printable_callbacks[cid].notification_cb)
                    return ms_uicc_low_level_access_get_printable_callbacks[cid].notification_cb (message, line_prefix, error);
            }
            break;

        case MBIM_MESSAGE_TYPE_OPEN: 
        case MBIM_MESSAGE_TYPE_CLOSE: 
        case MBIM_MESSAGE_TYPE_INVALID: 
        case MBIM_MESSAGE_TYPE_HOST_ERROR: 
        case MBIM_MESSAGE_TYPE_OPEN_DONE: 
        case MBIM_MESSAGE_TYPE_CLOSE_DONE: 
        case MBIM_MESSAGE_TYPE_FUNCTION_ERROR: 
        default:
            g_set_error (error,
                         MBIM_CORE_ERROR,
                         MBIM_CORE_ERROR_INVALID_MESSAGE,
                         "No contents expected in this message type");
            return NULL;
    }

    g_set_error (error,
                 MBIM_CORE_ERROR,
                 MBIM_CORE_ERROR_UNSUPPORTED,
                 "Unsupported message");
    return NULL;
}
