From 89c29c18c95f7f02481a4c620039c4c90d6c1889 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Sun, 7 Oct 2018 21:27:13 +0200 Subject: mbim-codegen: implement support for printing message fields in traces --- build-aux/mbim-codegen/Message.py | 343 ++++++++++++++++++++++++++++++++++- build-aux/mbim-codegen/ObjectList.py | 128 ++++++++++++- build-aux/mbim-codegen/Struct.py | 132 +++++++++++++- build-aux/mbim-codegen/mbim-codegen | 5 +- build-aux/mbim-codegen/utils.py | 4 +- src/libmbim-glib/mbim-message.c | 92 +++++++++- 6 files changed, 696 insertions(+), 8 deletions(-) diff --git a/build-aux/mbim-codegen/Message.py b/build-aux/mbim-codegen/Message.py index ddc1695..8ff58ea 100644 --- a/build-aux/mbim-codegen/Message.py +++ b/build-aux/mbim-codegen/Message.py @@ -14,7 +14,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., 51 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# Copyright (C) 2013 - 2014 Aleksander Morgado +# Copyright (C) 2013 - 2018 Aleksander Morgado # import string @@ -167,21 +167,25 @@ class Message: utils.add_separator(hfile, 'Message (Query)', self.fullname); utils.add_separator(cfile, 'Message (Query)', self.fullname); self._emit_message_creator(hfile, cfile, 'query', self.query) + self._emit_message_printable(cfile, 'query', self.query) if self.has_set: utils.add_separator(hfile, 'Message (Set)', self.fullname); utils.add_separator(cfile, 'Message (Set)', self.fullname); self._emit_message_creator(hfile, cfile, 'set', self.set) + self._emit_message_printable(cfile, 'set', self.set) if self.has_response: utils.add_separator(hfile, 'Message (Response)', self.fullname); utils.add_separator(cfile, 'Message (Response)', self.fullname); self._emit_message_parser(hfile, cfile, 'response', self.response) + self._emit_message_printable(cfile, 'response', self.response) if self.has_notification: utils.add_separator(hfile, 'Message (Notification)', self.fullname); utils.add_separator(cfile, 'Message (Notification)', self.fullname); self._emit_message_parser(hfile, cfile, 'notification', self.notification) + self._emit_message_printable(cfile, 'notification', self.notification) """ @@ -808,6 +812,343 @@ class Message: cfile.write(string.Template(template).substitute(translations)) + """ + Emit message printable + """ + def _emit_message_printable(self, cfile, message_type, fields): + translations = { 'message' : self.name, + 'underscore' : utils.build_underscore_name(self.name), + 'service' : self.service, + 'underscore' : utils.build_underscore_name (self.fullname), + 'message_type' : message_type, + 'message_type_upper' : message_type.upper(), + 'service_underscore_upper' : utils.build_underscore_name (self.service).upper() } + template = ( + '\n' + 'static gchar *\n' + '${underscore}_${message_type}_get_printable (\n' + ' const MbimMessage *message,\n' + ' const gchar *line_prefix,\n' + ' GError **error)\n' + '{\n' + ' GString *str;\n') + + if fields != []: + template += ( + ' guint32 offset = 0;\n') + + for field in fields: + if 'always-read' in field: + translations['field'] = utils.build_underscore_name_from_camelcase(field['name']) + inner_template = (' guint32 _${field};\n') + template += (string.Template(inner_template).substitute(translations)) + + template += ( + '\n' + ' str = g_string_new ("");\n') + + for field in fields: + translations['field'] = utils.build_underscore_name_from_camelcase(field['name']) + translations['field_format'] = field['format'] + translations['field_format_underscore'] = utils.build_underscore_name_from_camelcase(field['format']) + translations['public'] = field['public-format'] if 'public-format' in field else field['format'] + translations['public_underscore'] = utils.build_underscore_name_from_camelcase(field['public-format']) if 'public-format' in field else '' + translations['public_underscore_upper'] = utils.build_underscore_name_from_camelcase(field['public-format']).upper() if 'public-format' in field else '' + translations['field_name'] = field['name'] + translations['array_size_field'] = utils.build_underscore_name_from_camelcase(field['array-size-field']) if 'array-size-field' in field else '' + translations['struct_name'] = utils.build_underscore_name_from_camelcase(field['struct-type']) if 'struct-type' in field else '' + translations['struct_type'] = field['struct-type'] if 'struct-type' in field else '' + translations['array_size'] = field['array-size'] if 'array-size' in field else '' + + inner_template = ( + '\n' + ' g_string_append_printf (str, "%s ${field_name} = ", line_prefix);\n') + + if 'available-if' in field: + condition = field['available-if'] + translations['condition_field'] = utils.build_underscore_name_from_camelcase(condition['field']) + translations['condition_operation'] = condition['operation'] + translations['condition_value'] = condition['value'] + inner_template += ( + ' if (_${condition_field} ${condition_operation} ${condition_value}) {\n') + else: + inner_template += ( + ' {\n') + + if 'always-read' in field: + inner_template += ( + ' _${field} = _mbim_message_read_guint32 (message, offset);\n' + ' offset += 4;\n' + ' g_string_append_printf (str, "\'%" G_GUINT32_FORMAT "\'", _${field});\n') + + elif field['format'] == 'byte-array' or \ + field['format'] == 'unsized-byte-array' or \ + field['format'] == 'ref-byte-array' or \ + field['format'] == 'ref-byte-array-no-offset': + inner_template += ( + ' guint i;\n' + ' const guint8 *tmp;\n' + ' guint32 tmpsize;\n' + '\n') + if field['format'] == 'byte-array': + inner_template += ( + ' tmp = _mbim_message_read_byte_array (message, 0, offset, FALSE, FALSE, NULL);\n' + ' tmpsize = ${array_size};\n' + ' offset += ${array_size};\n') + elif field['format'] == 'unsized-byte-array': + inner_template += ( + ' tmp = _mbim_message_read_byte_array (message, 0, offset, FALSE, FALSE, &tmpsize);\n' + ' offset += tmpsize;\n') + + elif field['format'] == 'ref-byte-array': + inner_template += ( + ' tmp = _mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, &tmpsize);\n' + ' offset += 8;\n') + + elif field['format'] == 'ref-byte-array-no-offset': + inner_template += ( + ' tmp = _mbim_message_read_byte_array (message, 0, offset, FALSE, TRUE, &tmpsize);\n' + ' offset += 4;\n') + + inner_template += ( + ' g_string_append (str, "\'");\n' + ' for (i = 0; i < tmpsize; i++)\n' + ' g_string_append_printf (str, "%02x%s", tmp[i], (i == (tmpsize - 1)) ? "" : ":" );\n' + ' g_string_append (str, "\'");\n') + + elif field['format'] == 'uuid': + inner_template += ( + ' const MbimUuid *tmp;\n' + ' gchar *tmpstr;\n' + '\n' + ' tmp = _mbim_message_read_uuid (message, offset);\n' + ' offset += 16;\n' + ' tmpstr = mbim_uuid_get_printable (tmp);\n' + ' g_string_append_printf (str, "\'%s\'", tmpstr);\n' + ' g_free (tmpstr);\n') + + elif field['format'] == 'guint32' or \ + field['format'] == 'guint64': + inner_template += ( + ' ${public} tmp;\n' + '\n') + if field['format'] == 'guint32' : + inner_template += ( + ' tmp = (${public}) _mbim_message_read_guint32 (message, offset);\n' + ' offset += 4;\n') + elif field['format'] == 'guint64' : + inner_template += ( + ' tmp = (${public}) _mbim_message_read_guint64 (message, offset);\n' + ' offset += 8;\n') + + if 'public-format' in field: + inner_template += ( + '#if defined __${public_underscore_upper}_IS_ENUM__\n' + ' g_string_append_printf (str, "\'%s\'", ${public_underscore}_get_string (tmp));\n' + '#elif defined __${public_underscore_upper}_IS_FLAGS__\n' + ' {\n' + ' gchar *tmpstr;\n' + '\n' + ' tmpstr = ${public_underscore}_build_string_from_mask (tmp);\n' + ' g_string_append_printf (str, "\'%s\'", tmpstr);\n' + ' g_free (tmpstr);\n' + ' }\n' + '#else\n' + '# error neither enum nor flags\n' + '#endif\n' + '\n') + elif field['format'] == 'guint32': + inner_template += ( + ' g_string_append_printf (str, "\'%" G_GUINT32_FORMAT "\'", tmp);\n') + elif field['format'] == 'guint64': + inner_template += ( + ' g_string_append_printf (str, "\'%" G_GUINT64_FORMAT "\'", tmp);\n') + + elif field['format'] == 'string': + inner_template += ( + ' gchar *tmp;\n' + '\n' + ' tmp = _mbim_message_read_string (message, 0, offset);\n' + ' offset += 8;\n' + ' g_string_append_printf (str, "\'%s\'", tmp);\n' + ' g_free (tmp);\n') + + elif field['format'] == 'string-array': + inner_template += ( + ' gchar **tmp;\n' + ' guint i;\n' + '\n' + ' tmp = _mbim_message_read_string_array (message, _${array_size_field}, 0, offset);\n' + ' offset += (8 * _${array_size_field});\n' + '\n' + ' g_string_append (str, "\'");\n' + ' for (i = 0; i < _${array_size_field}; i++) {\n' + ' g_string_append (str, tmp[i]);\n' + ' if (i < (_${array_size_field} - 1))\n' + ' g_string_append (str, ", ");\n' + ' }\n' + ' g_string_append (str, "\'");\n' + ' g_strfreev (tmp);\n') + + elif field['format'] == 'struct': + inner_template += ( + ' ${struct_type} *tmp;\n' + ' guint32 bytes_read = 0;\n' + ' gchar *new_line_prefix;\n' + ' gchar *struct_str;\n' + '\n' + ' tmp = _mbim_message_read_${struct_name}_struct (message, offset, &bytes_read);\n' + ' offset += bytes_read;\n' + '\n' + ' g_string_append (str, "{\\n");\n' + ' new_line_prefix = g_strdup_printf ("%s ", line_prefix);\n' + ' struct_str = _mbim_message_print_${struct_name}_struct (tmp, new_line_prefix);\n' + ' g_string_append (str, struct_str);\n' + ' g_free (struct_str);\n' + ' g_string_append_printf (str, "%s }\\n", line_prefix);\n' + ' g_free (new_line_prefix);\n' + ' _${struct_name}_free (tmp);\n') + + elif field['format'] == 'struct-array' or field['format'] == 'ref-struct-array': + inner_template += ( + ' ${struct_type} **tmp;\n' + ' gchar *new_line_prefix;\n' + ' guint i;\n' + '\n') + + if field['format'] == 'struct-array': + inner_template += ( + ' tmp = _mbim_message_read_${struct_name}_struct_array (message, _${array_size_field}, offset, FALSE);\n' + ' offset += 4;\n') + elif field['format'] == 'ref-struct-array': + inner_template += ( + ' tmp = _mbim_message_read_${struct_name}_struct_array (message, _${array_size_field}, offset, TRUE);\n' + ' offset += (8 * _${array_size_field});\n') + + inner_template += ( + ' new_line_prefix = g_strdup_printf ("%s ", line_prefix);\n' + ' g_string_append (str, "\'{\\n");\n' + ' for (i = 0; i < _${array_size_field}; i++) {\n' + ' gchar *struct_str;\n' + '\n' + ' g_string_append_printf (str, "%s [%u] = {\\n", line_prefix, i);\n' + ' struct_str = _mbim_message_print_${struct_name}_struct (tmp[i], new_line_prefix);\n' + ' g_string_append (str, struct_str);\n' + ' g_free (struct_str);\n' + ' g_string_append_printf (str, "%s },\\n", line_prefix);\n' + ' }\n' + ' g_string_append_printf (str, "%s }\'", line_prefix);\n' + ' g_free (new_line_prefix);\n' + ' ${struct_name}_array_free (tmp);\n') + + elif field['format'] == 'ipv4' or \ + field['format'] == 'ref-ipv4' or \ + field['format'] == 'ipv4-array' or \ + field['format'] == 'ipv6' or \ + field['format'] == 'ref-ipv6' or \ + field['format'] == 'ipv6-array': + if field['format'] == 'ipv4' or \ + field['format'] == 'ref-ipv4': + inner_template += ( + ' const MbimIPv4 *tmp;\n') + elif field['format'] == 'ipv4-array': + inner_template += ( + ' MbimIPv4 *tmp;\n') + elif field['format'] == 'ipv6' or \ + field['format'] == 'ref-ipv6': + inner_template += ( + ' const MbimIPv6 *tmp;\n') + elif field['format'] == 'ipv6-array': + inner_template += ( + ' MbimIPv6 *tmp;\n') + + inner_template += ( + ' guint array_size;\n' + ' guint i;\n' + '\n') + + if field['format'] == 'ipv4': + inner_template += ( + ' array_size = 1;\n' + ' tmp = _mbim_message_read_ipv4 (message, offset, FALSE);\n' + ' offset += 4;\n') + elif field['format'] == 'ref-ipv4': + inner_template += ( + ' array_size = 1;\n' + ' tmp = _mbim_message_read_ipv4 (message, offset, TRUE);\n' + ' offset += 4;\n') + elif field['format'] == 'ipv4-array': + inner_template += ( + ' array_size = _${array_size_field};\n' + ' tmp = _mbim_message_read_ipv4_array (message, _${array_size_field}, offset);\n' + ' offset += 4;\n') + elif field['format'] == 'ipv6': + inner_template += ( + ' array_size = 1;\n' + ' tmp = _mbim_message_read_ipv6 (message, offset, FALSE);\n' + ' offset += 16;\n') + elif field['format'] == 'ref-ipv6': + inner_template += ( + ' array_size = 1;\n' + ' tmp = _mbim_message_read_ipv6 (message, offset, TRUE);\n' + ' offset += 4;\n') + elif field['format'] == 'ipv6-array': + inner_template += ( + ' array_size = _${array_size_field};\n' + ' tmp = _mbim_message_read_ipv6_array (message, _${array_size_field}, offset);\n' + ' offset += 4;\n') + + inner_template += ( + ' g_string_append (str, "\'");\n' + ' if (tmp) {\n' + ' for (i = 0; i < array_size; i++) {\n' + ' GInetAddress *addr;\n' + ' gchar *tmpstr;\n' + '\n') + + if field['format'] == 'ipv4' or \ + field['format'] == 'ref-ipv4' or \ + field['format'] == 'ipv4-array': + inner_template += ( + ' addr = g_inet_address_new_from_bytes ((guint8 *)&(tmp[i].addr), G_SOCKET_FAMILY_IPV4);\n') + elif field['format'] == 'ipv6' or \ + field['format'] == 'ref-ipv6' or \ + field['format'] == 'ipv6-array': + inner_template += ( + ' addr = g_inet_address_new_from_bytes ((guint8 *)&(tmp[i].addr), G_SOCKET_FAMILY_IPV6);\n') + + inner_template += ( + ' tmpstr = g_inet_address_to_string (addr);\n' + ' g_string_append_printf (str, "%s", tmpstr);\n' + ' g_free (tmpstr);\n' + ' g_object_unref (addr);\n' + ' if (i < (array_size - 1))\n' + ' g_string_append (str, ", ");\n' + ' }\n' + ' }\n' + ' g_string_append (str, "\'");\n') + + if field['format'] == 'ipv4-array' or \ + field['format'] == 'ipv6-array': + inner_template += ( + ' g_free (tmp);\n') + + else: + raise ValueError('Field format \'%s\' not printable' % field['format']) + + inner_template += ( + ' }\n' + ' g_string_append (str, "\\n");\n') + + template += (string.Template(inner_template).substitute(translations)) + + template += ( + '\n' + ' return g_string_free (str, FALSE);\n' + '}\n') + cfile.write(string.Template(template).substitute(translations)) + + """ Emit the section content """ diff --git a/build-aux/mbim-codegen/ObjectList.py b/build-aux/mbim-codegen/ObjectList.py index a23fc07..9271049 100644 --- a/build-aux/mbim-codegen/ObjectList.py +++ b/build-aux/mbim-codegen/ObjectList.py @@ -14,7 +14,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., 51 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# Copyright (C) 2013 - 2014 Aleksander Morgado +# Copyright (C) 2013 - 2018 Aleksander Morgado # import string @@ -87,6 +87,132 @@ class ObjectList: item.emit(hfile, cfile) + """ + Emit support for printing messages in this service + """ + def emit_printable(self, hfile, cfile): + translations = { 'service_underscore' : utils.build_underscore_name(self.service), + 'service' : self.service } + + + template = ( + '\n' + '/*****************************************************************************/\n' + '/* Service helper for printable fields */\n' + '\n' + '#if defined (LIBMBIM_GLIB_COMPILATION)\n' + '\n' + 'G_GNUC_INTERNAL\n' + 'gchar *\n' + '__mbim_message_${service_underscore}_get_printable_fields (\n' + ' const MbimMessage *message,\n' + ' const gchar *line_prefix,\n' + ' GError **error);\n' + '\n' + '#endif\n') + hfile.write(string.Template(template).substitute(translations)) + + template = ( + '\n' + 'typedef struct {\n' + ' gchar * (* query_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n' + ' gchar * (* set_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n' + ' gchar * (* response_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n' + ' gchar * (* notification_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n' + '} GetPrintableCallbacks;\n' + '\n' + 'static const GetPrintableCallbacks get_printable_callbacks[] = {\n') + + for item in self.command_list: + translations['message'] = utils.build_underscore_name (item.fullname) + translations['cid'] = item.cid_enum_name + inner_template = ( + ' [${cid}] = {\n') + if item.has_query: + inner_template += ( + ' .query_cb = ${message}_query_get_printable,\n') + if item.has_set: + inner_template += ( + ' .set_cb = ${message}_set_get_printable,\n') + if item.has_response: + inner_template += ( + ' .response_cb = ${message}_response_get_printable,\n') + if item.has_notification: + inner_template += ( + ' .notification_cb = ${message}_notification_get_printable,\n') + inner_template += ( + ' },\n') + template += (string.Template(inner_template).substitute(translations)) + + template += ( + '};\n' + '\n' + 'gchar *\n' + '__mbim_message_${service_underscore}_get_printable_fields (\n' + ' const MbimMessage *message,\n' + ' const gchar *line_prefix,\n' + ' GError **error)\n' + '{\n' + ' guint32 cid;\n' + '\n' + ' switch (mbim_message_get_message_type (message)) {\n' + ' case MBIM_MESSAGE_TYPE_COMMAND: {\n' + ' cid = mbim_message_command_get_cid (message);\n' + ' if (cid < G_N_ELEMENTS (get_printable_callbacks)) {\n' + ' switch (mbim_message_command_get_command_type (message)) {\n' + ' case MBIM_MESSAGE_COMMAND_TYPE_QUERY:\n' + ' if (get_printable_callbacks[cid].query_cb)\n' + ' return get_printable_callbacks[cid].query_cb (message, line_prefix, error);\n' + ' break;\n' + ' case MBIM_MESSAGE_COMMAND_TYPE_SET:\n' + ' if (get_printable_callbacks[cid].set_cb)\n' + ' return get_printable_callbacks[cid].set_cb (message, line_prefix, error);\n' + ' break;\n' + ' default:\n' + ' g_set_error (error,\n' + ' MBIM_CORE_ERROR,\n' + ' MBIM_CORE_ERROR_INVALID_MESSAGE,\n' + ' \"Invalid command type\");\n' + ' return NULL;\n' + ' }\n' + ' }\n' + ' break;\n' + ' }\n' + '\n' + ' case MBIM_MESSAGE_TYPE_COMMAND_DONE:\n' + ' cid = mbim_message_command_done_get_cid (message);\n' + ' if (cid < G_N_ELEMENTS (get_printable_callbacks)) {\n' + ' if (get_printable_callbacks[cid].response_cb)\n' + ' return get_printable_callbacks[cid].response_cb (message, line_prefix, error);\n' + ' }\n' + ' break;\n' + '\n' + ' case MBIM_MESSAGE_TYPE_INDICATE_STATUS:\n' + ' cid = mbim_message_indicate_status_get_cid (message);\n' + ' if (cid < G_N_ELEMENTS (get_printable_callbacks)) {\n' + ' if (get_printable_callbacks[cid].notification_cb)\n' + ' return get_printable_callbacks[cid].notification_cb (message, line_prefix, error);\n' + ' }\n' + ' break;\n' + '\n' + ' default:\n' + ' g_set_error (error,\n' + ' MBIM_CORE_ERROR,\n' + ' MBIM_CORE_ERROR_INVALID_MESSAGE,\n' + ' \"No contents expected in this message type\");\n' + ' return NULL;\n' + ' }\n' + '\n' + ' g_set_error (error,\n' + ' MBIM_CORE_ERROR,\n' + ' MBIM_CORE_ERROR_INVALID_MESSAGE,\n' + ' \"Unknown contents\");\n' + ' return NULL;\n' + '}\n') + + cfile.write(string.Template(template).substitute(translations)) + + """ Emit the sections """ diff --git a/build-aux/mbim-codegen/Struct.py b/build-aux/mbim-codegen/Struct.py index ed68e27..7e874d0 100644 --- a/build-aux/mbim-codegen/Struct.py +++ b/build-aux/mbim-codegen/Struct.py @@ -14,7 +14,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., 51 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# Copyright (C) 2013 - 2014 Aleksander Morgado +# Copyright (C) 2013 - 2018 Aleksander Morgado # import string @@ -268,6 +268,134 @@ class Struct: '}\n') cfile.write(string.Template(template).substitute(translations)) + """ + Emit the type's print methods + """ + def _emit_print(self, cfile): + translations = { 'name' : self.name, + 'name_underscore' : utils.build_underscore_name_from_camelcase(self.name), + 'struct_size' : self.size } + + template = ( + '\n' + 'static gchar *\n' + '_mbim_message_print_${name_underscore}_struct (\n' + ' const ${name} *self,\n' + ' const gchar *line_prefix)\n' + '{\n' + ' GString *str;\n' + '\n' + ' str = g_string_new ("");\n' + '\n') + + for field in self.contents: + translations['field_name'] = field['name'] + translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase(field['name']) + + inner_template = ( + ' g_string_append_printf (str, "%s ${field_name} = ", line_prefix);\n' + ' {\n') + + if field['format'] == 'uuid': + inner_template += ( + ' gchar *tmpstr;\n' + '\n' + ' tmpstr = mbim_uuid_get_printable (&(self->${field_name_underscore}));\n' + ' g_string_append_printf (str, "\'%s\'", tmpstr);\n' + ' g_free (tmpstr);\n') + + elif field['format'] in ['byte-array', 'ref-byte-array', 'ref-byte-array-no-offset', 'unsized-byte-array']: + inner_template += ( + ' guint i;\n' + ' guint array_size;\n' + '\n') + + if field['format'] == 'byte-array': + translations['array_size'] = field['array-size'] + inner_template += ( + ' array_size = ${array_size};\n') + elif 'array-size-field' in field: + translations['array_size_field_name_underscore'] = utils.build_underscore_name_from_camelcase(field['array-size-field']) + inner_template += ( + ' array_size = self->${array_size_field_name_underscore};\n') + else: + inner_template += ( + ' array_size = self->${field_name_underscore}_size;\n') + + inner_template += ( + ' g_string_append (str, "\'");\n' + ' for (i = 0; i < array_size; i++)\n' + ' g_string_append_printf (str, "%02x%s", self->${field_name_underscore}[i], (i == (array_size - 1)) ? "" : ":" );\n' + ' g_string_append (str, "\'");\n') + + elif field['format'] == 'guint32': + inner_template += ( + ' g_string_append_printf (str, "\'%" G_GUINT32_FORMAT "\'", self->${field_name_underscore});\n') + + elif field['format'] == 'guint64': + inner_template += ( + ' g_string_append_printf (str, "\'%" G_GUINT64_FORMAT "\'", self->${field_name_underscore});\n') + + elif field['format'] == 'guint32-array': + translations['array_size_field_name_underscore'] = utils.build_underscore_name_from_camelcase(field['array-size-field']) + inner_template += ( + ' guint i;\n' + '\n' + ' g_string_append (str, "\'");\n' + ' for (i = 0; i < self->${array_size_field_name_underscore}; i++)\n' + ' g_string_append_printf (str, "%" G_GUINT32_FORMAT "%s", self->${field_name_underscore}[i], (i == (self->${array_size_field_name_underscore} - 1)) ? "" : "," );\n' + ' g_string_append (str, "\'");\n') + + elif field['format'] == 'string': + inner_template += ( + ' g_string_append_printf (str, "\'%s\'", self->${field_name_underscore});\n') + + elif field['format'] == 'string-array': + translations['array_size_field_name_underscore'] = utils.build_underscore_name_from_camelcase(field['array-size-field']) + inner_template += ( + ' guint i;\n' + '\n' + ' g_string_append (str, "\'");\n' + ' for (i = 0; i < self->${array_size_field_name_underscore}; i++)\n' + ' g_string_append_printf (str, "%s%s", self->${field_name_underscore}[i], (i == (self->${array_size_field_name_underscore} - 1)) ? "" : "," );\n' + ' g_string_append (str, "\'");\n') + + elif field['format'] == 'ipv4' or \ + field['format'] == 'ref-ipv4' or \ + field['format'] == 'ipv6' or \ + field['format'] == 'ref-ipv6': + inner_template += ( + ' GInetAddress *addr;\n' + ' gchar *tmpstr;\n' + '\n') + + if field['format'] == 'ipv4' or \ + field['format'] == 'ref-ipv4': + inner_template += ( + ' addr = g_inet_address_new_from_bytes ((guint8 *)&(self->${field_name_underscore}.addr), G_SOCKET_FAMILY_IPV4);\n') + elif field['format'] == 'ipv6' or \ + field['format'] == 'ref-ipv6': + inner_template += ( + ' addr = g_inet_address_new_from_bytes ((guint8 *)&(self->${field_name_underscore}.addr), G_SOCKET_FAMILY_IPV6);\n') + + inner_template += ( + ' tmpstr = g_inet_address_to_string (addr);\n' + ' g_string_append_printf (str, "\'%s\'", tmpstr);\n' + ' g_free (tmpstr);\n' + ' g_object_unref (addr);\n') + + else: + raise ValueError('Cannot handle format \'%s\' in struct' % field['format']) + + inner_template += ( + ' }\n' + ' g_string_append (str, "\\n");\n') + template += (string.Template(inner_template).substitute(translations)) + + template += ( + ' return g_string_free (str, FALSE);\n' + '}\n') + cfile.write(string.Template(template).substitute(translations)) """ Emit the type's read methods @@ -634,6 +762,8 @@ class Struct: self._emit_free(hfile, cfile) # Emit type's read self._emit_read(cfile) + # Emit type's print + self._emit_print(cfile) # Emit type's append self._emit_append(cfile) diff --git a/build-aux/mbim-codegen/mbim-codegen b/build-aux/mbim-codegen/mbim-codegen index 4d01384..726d634 100755 --- a/build-aux/mbim-codegen/mbim-codegen +++ b/build-aux/mbim-codegen/mbim-codegen @@ -15,7 +15,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., 51 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# Copyright (C) 2013 Aleksander Morgado +# Copyright (C) 2013-2018 Aleksander Morgado # import os @@ -61,6 +61,9 @@ def codegen_main(): # Emit the message creation/parsing code object_list.emit(output_file_h, output_file_c) + # Emit the message printable support + object_list.emit_printable(output_file_h, output_file_c) + # Emit sections object_list.emit_sections(output_file_sections) diff --git a/build-aux/mbim-codegen/utils.py b/build-aux/mbim-codegen/utils.py index 0622eb3..ca0231e 100644 --- a/build-aux/mbim-codegen/utils.py +++ b/build-aux/mbim-codegen/utils.py @@ -15,7 +15,7 @@ # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # Copyright (C) 2012 Lanedo GmbH -# Copyright (C) 2013 - 2014 Aleksander Morgado +# Copyright (C) 2013 - 2018 Aleksander Morgado # # Implementation originally developed in 'libqmi'. # @@ -47,7 +47,7 @@ def add_copyright(f): " * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\n" " * Boston, MA 02110-1301 USA.\n" " *\n" - " * Copyright (C) 2013 - 2014 Aleksander Morgado \n" + " * Copyright (C) 2013 - 2018 Aleksander Morgado \n" " */\n" "\n"); diff --git a/src/libmbim-glib/mbim-message.c b/src/libmbim-glib/mbim-message.c index 4ae9b8d..99cb1fd 100644 --- a/src/libmbim-glib/mbim-message.c +++ b/src/libmbim-glib/mbim-message.c @@ -18,7 +18,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2013 - 2014 Aleksander Morgado + * Copyright (C) 2013 - 2018 Aleksander Morgado */ #include @@ -32,6 +32,21 @@ #include "mbim-error-types.h" #include "mbim-enum-types.h" +#include "mbim-atds.h" +#include "mbim-auth.h" +#include "mbim-basic-connect.h" +#include "mbim-basic-connect-extensions.h" +#include "mbim-dss.h" +#include "mbim-intel-firmware-update.h" +#include "mbim-ms-firmware-id.h" +#include "mbim-ms-host-shutdown.h" +#include "mbim-phonebook.h" +#include "mbim-proxy-control.h" +#include "mbim-qmi.h" +#include "mbim-sms.h" +#include "mbim-stk.h" +#include "mbim-ussd.h" + /** * SECTION:mbim-message * @title: MbimMessage @@ -1125,6 +1140,7 @@ mbim_message_get_printable (const MbimMessage *self, gboolean headers_only) { GString *printable; + MbimService service_read_fields = MBIM_SERVICE_INVALID; g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (line_prefix != NULL, NULL); @@ -1152,7 +1168,7 @@ mbim_message_get_printable (const MbimMessage *self, if (!headers_only) g_string_append_printf (printable, "%sContents:\n" - "%s max_control_transfer = %u\n", + "%s max control transfer = %u\n", line_prefix, line_prefix, mbim_message_open_get_max_control_transfer (self)); break; @@ -1212,6 +1228,8 @@ mbim_message_get_printable (const MbimMessage *self, gchar *uuid_printable; const gchar *cid_printable; + service_read_fields = mbim_message_command_get_service (self); + uuid_printable = mbim_uuid_get_printable (mbim_message_command_get_service_id (self)); cid_printable = mbim_cid_get_printable (mbim_message_command_get_service (self), mbim_message_command_get_cid (self)); @@ -1241,6 +1259,8 @@ mbim_message_get_printable (const MbimMessage *self, MbimStatusError status; const gchar *cid_printable; + service_read_fields = mbim_message_command_done_get_service (self); + status = mbim_message_command_done_get_status_code (self); uuid_printable = mbim_uuid_get_printable (mbim_message_command_done_get_service_id (self)); cid_printable = mbim_cid_get_printable (mbim_message_command_done_get_service (self), @@ -1270,6 +1290,8 @@ mbim_message_get_printable (const MbimMessage *self, gchar *uuid_printable; const gchar *cid_printable; + service_read_fields = mbim_message_indicate_status_get_service (self); + uuid_printable = mbim_uuid_get_printable (mbim_message_indicate_status_get_service_id (self)); cid_printable = mbim_cid_get_printable (mbim_message_indicate_status_get_service (self), mbim_message_indicate_status_get_cid (self)); @@ -1285,6 +1307,72 @@ mbim_message_get_printable (const MbimMessage *self, break; } + if (service_read_fields != MBIM_SERVICE_INVALID) { + gchar *fields_printable = NULL; + GError *error = NULL; + + switch (service_read_fields) { + case MBIM_SERVICE_BASIC_CONNECT: + fields_printable = __mbim_message_basic_connect_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_SMS: + fields_printable = __mbim_message_sms_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_USSD: + fields_printable = __mbim_message_ussd_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_PHONEBOOK: + fields_printable = __mbim_message_phonebook_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_STK: + fields_printable = __mbim_message_stk_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_AUTH: + fields_printable = __mbim_message_auth_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_DSS: + fields_printable = __mbim_message_dss_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_MS_FIRMWARE_ID: + fields_printable = __mbim_message_ms_firmware_id_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_MS_HOST_SHUTDOWN: + fields_printable = __mbim_message_ms_host_shutdown_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_PROXY_CONTROL: + fields_printable = __mbim_message_proxy_control_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_QMI: + fields_printable = __mbim_message_qmi_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_ATDS: + fields_printable = __mbim_message_atds_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_INTEL_FIRMWARE_UPDATE: + fields_printable = __mbim_message_intel_firmware_update_get_printable_fields (self, line_prefix, &error); + break; + case MBIM_SERVICE_BASIC_CONNECT_EXTENSIONS: + fields_printable = __mbim_message_basic_connect_extensions_get_printable_fields (self, line_prefix, &error); + break; + default: + break; + } + + if (error) { + g_string_append_printf (printable, + "%sFields: %s\n", + line_prefix, error->message); + g_error_free (error); + } else if (fields_printable) { + if (fields_printable[0]) + g_string_append_printf (printable, + "%sFields:\n" + "%s", + line_prefix, fields_printable); + g_free (fields_printable); + } + } + return g_string_free (printable, FALSE); } -- cgit v1.2.1