summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build-aux/mbim-codegen/Container.py93
-rw-r--r--build-aux/mbim-codegen/Makefile.am9
-rw-r--r--build-aux/mbim-codegen/Message.py695
-rw-r--r--build-aux/mbim-codegen/Struct.py270
-rw-r--r--build-aux/mbim-codegen/Value.py70
-rw-r--r--build-aux/mbim-codegen/ValueString.py55
-rw-r--r--build-aux/mbim-codegen/ValueStringArray.py60
-rw-r--r--build-aux/mbim-codegen/ValueStruct.py60
-rw-r--r--build-aux/mbim-codegen/ValueStructArray.py63
-rw-r--r--build-aux/mbim-codegen/ValueUint32.py55
-rw-r--r--build-aux/mbim-codegen/ValueUint32Array.py57
-rw-r--r--build-aux/mbim-codegen/ValueUint64.py55
-rw-r--r--build-aux/mbim-codegen/ValueUuid.py55
-rw-r--r--data/mbim-service-basic-connect.json139
-rw-r--r--libmbim-glib/mbim-enums.h21
-rw-r--r--libmbim-glib/mbim-message.c300
-rw-r--r--libmbim-glib/mbim-message.h150
-rw-r--r--libmbim-glib/test/test-message-contents.c139
18 files changed, 1447 insertions, 899 deletions
diff --git a/build-aux/mbim-codegen/Container.py b/build-aux/mbim-codegen/Container.py
deleted file mode 100644
index 974eef5..0000000
--- a/build-aux/mbim-codegen/Container.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil -*-
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# 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 <aleksander@gnu.org>
-#
-
-import string
-import utils
-from ValueUuid import ValueUuid
-from ValueUint32 import ValueUint32
-from ValueUint32Array import ValueUint32Array
-from ValueUint64 import ValueUint64
-from ValueString import ValueString
-from ValueStringArray import ValueStringArray
-from ValueStruct import ValueStruct
-from ValueStructArray import ValueStructArray
-
-"""
-The Container class takes care of handling collections of Input or
-Output fields
-"""
-class Container:
-
- """
- Constructor
- """
- def __init__(self, message_type, dictionary):
- # We may have 'Query', 'Set' or 'Notify' message types
- if message_type == 'query':
- self.message_type_enum = 'MBIM_MESSAGE_TYPE_COMMAND'
- elif message_type == 'set':
- self.message_type_enum = 'MBIM_MESSAGE_TYPE_COMMAND'
- elif message_type == 'response':
- self.message_type_enum = 'MBIM_MESSAGE_TYPE_COMMAND_DONE'
- elif message_type == 'notification':
- self.message_type_enum = 'MBIM_MESSAGE_TYPE_INDICATE_STATUS'
- else:
- raise ValueError('Cannot handle message type \'%s\'' % message_type)
-
- self.fields = []
- for field in dictionary:
- if field['format'] == 'uuid':
- self.fields.append(ValueUuid(field))
- elif field['format'] == 'guint32':
- self.fields.append(ValueUint32(field))
- elif field['format'] == 'guint32-array':
- new_field = ValueUint32Array(field)
- self.mark_array_length(new_field.array_size_field)
- self.fields.append(new_field)
- elif field['format'] == 'guint64':
- self.fields.append(ValueUint64(field))
- elif field['format'] == 'string':
- self.fields.append(ValueString(field))
- elif field['format'] == 'string-array':
- new_field = ValueStringArray(field)
- self.mark_array_length(new_field.array_size_field)
- self.fields.append(new_field)
- elif field['format'] == 'struct':
- self.fields.append(ValueStruct(field))
- elif field['format'] == 'struct-array':
- new_field = ValueStructArray(field)
- self.mark_array_length(new_field.array_size_field)
- self.fields.append(new_field)
- else:
- raise ValueError('Cannot handle field type \'%s\'' % field['format'])
-
-
- """
- Flag the values which are used as length of arrays
- """
- def mark_array_length(self, array_size_field):
- found = False
- for field in self.fields:
- if field.name == array_size_field:
- field.is_array_size = True
- found = True
- break
- if found == False:
- raise ValueError('Couldn\'t find array size field \'%s\'' % array_size_field)
diff --git a/build-aux/mbim-codegen/Makefile.am b/build-aux/mbim-codegen/Makefile.am
index 1e9336a..9dc56aa 100644
--- a/build-aux/mbim-codegen/Makefile.am
+++ b/build-aux/mbim-codegen/Makefile.am
@@ -2,15 +2,6 @@
EXTRA_DIST = \
utils.py \
Struct.py \
- Value.py \
- ValueString.py \
- ValueStringArray.py \
- ValueStruct.py \
- ValueStructArray.py \
- ValueUint32.py \
- ValueUint32Array.py \
- ValueUuid.py \
- Container.py \
Message.py \
ObjectList.py \
mbim-codegen
diff --git a/build-aux/mbim-codegen/Message.py b/build-aux/mbim-codegen/Message.py
index d1f6a08..aae6784 100644
--- a/build-aux/mbim-codegen/Message.py
+++ b/build-aux/mbim-codegen/Message.py
@@ -19,10 +19,66 @@
#
import string
-
-from Container import Container
import utils
+
+"""
+Flag the values which are used as length of arrays
+"""
+def flag_array_length_field(fields, field_name):
+ for field in fields:
+ if field['name'] == field_name:
+ field['is-array-size'] = True
+ return
+ raise ValueError('Couldn\'t find array size field \'%s\'' % array_size_field)
+
+
+"""
+Validate fields in the dictionary
+"""
+def validate_fields(fields):
+ for field in fields:
+ if field['format'] == 'uuid':
+ pass
+ elif field['format'] == 'guint32':
+ pass
+ elif field['format'] == 'guint32-array':
+ flag_array_length_field(fields, field['array-size-field'])
+ elif field['format'] == 'guint64':
+ pass
+ elif field['format'] == 'guint64-array':
+ flag_array_length_field(fields, field['array-size-field'])
+ elif field['format'] == 'string':
+ pass
+ elif field['format'] == 'string-array':
+ flag_array_length_field(fields, field['array-size-field'])
+ elif field['format'] == 'struct':
+ if 'struct-type' not in field:
+ raise ValueError('Field type \'struct\' requires \'struct-type\' field')
+ elif field['format'] == 'struct-array':
+ flag_array_length_field(fields, field['array-size-field'])
+ if 'struct-type' not in field:
+ raise ValueError('Field type \'struct\' requires \'struct-type\' field')
+ elif field['format'] == 'ref-struct-array':
+ flag_array_length_field(fields, field['array-size-field'])
+ if 'struct-type' not in field:
+ raise ValueError('Field type \'struct\' requires \'struct-type\' field')
+ elif field['format'] == 'ipv4':
+ pass
+ elif field['format'] == 'ref-ipv4':
+ pass
+ elif field['format'] == 'ipv4-array':
+ flag_array_length_field(fields, field['array-size-field'])
+ elif field['format'] == 'ipv6':
+ pass
+ elif field['format'] == 'ref-ipv6':
+ pass
+ elif field['format'] == 'ipv6-array':
+ flag_array_length_field(fields, field['array-size-field'])
+ else:
+ raise ValueError('Cannot handle field type \'%s\'' % field['format'])
+
+
"""
The Message class takes care of all message handling
"""
@@ -34,14 +90,46 @@ class Message:
def __init__(self, dictionary):
# The message service, e.g. "Basic Connect"
self.service = dictionary['service']
+
# The name of the specific message, e.g. "Something"
self.name = dictionary['name']
- # Gather types of command
- self.query = True if 'query' in dictionary else False
- self.set = True if 'set' in dictionary else False
- self.response = True if 'response' in dictionary else False
- self.notification = True if 'notification' in dictionary else False
+ # Query
+ if 'query' in dictionary:
+ self.has_query = True
+ self.query = dictionary['query']
+ validate_fields(self.query)
+ else:
+ self.has_query = False
+ self.query = []
+
+ # Set
+ if 'set' in dictionary:
+ self.has_set = True
+ self.set = dictionary['set']
+ validate_fields(self.set)
+ else:
+ self.has_set = False
+ self.set = []
+
+
+ # Response
+ if 'response' in dictionary:
+ self.has_response = True
+ self.response = dictionary['response']
+ validate_fields(self.response)
+ else:
+ self.has_response = False
+ self.response = []
+
+ # Notification
+ if 'notification' in dictionary:
+ self.has_notification = True
+ self.notification = dictionary['notification']
+ validate_fields(self.notification)
+ else:
+ self.has_notification = False
+ self.notification = []
# Build Fullname
self.fullname = 'MBIM Message ' + self.name
@@ -49,29 +137,37 @@ class Message:
# Build CID enum
self.cid_enum_name = utils.build_underscore_name('MBIM CID' + self.service + ' ' + self.name).upper()
- # Build input containers
- self.query_container = None
- if self.query:
- self.query_container = Container('query', dictionary['query'])
- self.set_container = None
- if self.set:
- self.set_container = Container('set', dictionary['set'])
- self.notify_container = None
- # Build output containers
- self.response_container = None
- if self.response:
- self.response_container = Container('response', dictionary['response'])
- self.notification_container = None
- if self.notification:
- self.notification_container = Container('notification', dictionary['notification'])
+ """
+ Emit the message handling implementation
+ """
+ def emit(self, hfile, cfile):
+ if self.has_query:
+ 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)
+
+ 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)
+
+ 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)
+
+ 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)
"""
Emit message creator
"""
- def _emit_message_creator(self, hfile, cfile, message_type, container):
- translations = { 'name' : self.name,
+ def _emit_message_creator(self, hfile, cfile, message_type, fields):
+ translations = { 'message' : self.name,
'service' : self.service,
'underscore' : utils.build_underscore_name (self.fullname),
'message_type' : message_type,
@@ -82,13 +178,45 @@ class Message:
'\n'
'MbimMessage *${underscore}_${message_type}_new (\n')
- if container != None:
- for field in container.fields:
- translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase (field.name)
- translations['field_in_format'] = field.in_format
- inner_template = (
- ' ${field_in_format}${field_name_underscore},\n')
- template += (string.Template(inner_template).substitute(translations))
+ for field in fields:
+ translations['field'] = utils.build_underscore_name_from_camelcase (field['name'])
+ translations['struct'] = field['struct-type'] if 'struct-type' in field else ''
+ translations['public'] = field['public-format'] if 'public-format' in field else field['format']
+
+ if field['format'] == 'uuid':
+ inner_template = (' const MbimUuid *${field},\n')
+ elif field['format'] == 'guint32':
+ inner_template = (' ${public} ${field},\n')
+ elif field['format'] == 'guint32-array':
+ inner_template = (' const ${public} *${field},\n')
+ elif field['format'] == 'guint64':
+ inner_template = (' ${public} ${field},\n')
+ elif field['format'] == 'guint64-array':
+ inner_template = (' const ${public} *${field},\n')
+ elif field['format'] == 'string':
+ inner_template = (' const gchar *${field},\n')
+ elif field['format'] == 'string-array':
+ inner_template = (' const gchar *const *${field},\n')
+ elif field['format'] == 'struct':
+ inner_template = (' const ${struct} *${field},\n')
+ elif field['format'] == 'struct-array':
+ inner_template = (' const ${struct} *const *${field},\n')
+ elif field['format'] == 'ref-struct-array':
+ inner_template = (' const ${struct} *const *${field},\n')
+ elif field['format'] == 'ipv4':
+ inner_template = (' const MbimIPv4 *${field},\n')
+ elif field['format'] == 'ref-ipv4':
+ inner_template = (' const MbimIPv4 *${field},\n')
+ elif field['format'] == 'ipv4-array':
+ inner_template = (' const MbimIPv4 *${field},\n')
+ elif field['format'] == 'ipv6':
+ inner_template = (' const MbimIPv6 *${field},\n')
+ elif field['format'] == 'ref-ipv6':
+ inner_template = (' const MbimIPv6 *${field},\n')
+ elif field['format'] == 'ipv6-array':
+ inner_template = (' const MbimIPv6 *${field},\n')
+
+ template += (string.Template(inner_template).substitute(translations))
template += (
' GError **error);\n')
@@ -99,32 +227,96 @@ class Message:
'/**\n'
' * ${underscore}_${message_type}_new:\n')
- if container != None:
- for field in container.fields:
- translations['field_name'] = field.name
- translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase (field.name)
- translations['field_in_description'] = field.in_description
- inner_template = (
- ' * @${field_name_underscore}: the \'${field_name}\' field, given as ${field_in_description}\n')
- template += (string.Template(inner_template).substitute(translations))
+ for field in fields:
+ translations['name'] = field['name']
+ translations['field'] = utils.build_underscore_name_from_camelcase (field['name'])
+ translations['struct'] = field['struct-type'] if 'struct-type' in field else ''
+ translations['public'] = field['public-format'] if 'public-format' in field else field['format']
+
+ if field['format'] == 'uuid':
+ inner_template = (' * @${field}: the \'${name}\' field, given as a #MbimUuid.\n')
+ elif field['format'] == 'guint32':
+ inner_template = (' * @${field}: the \'${name}\' field, given as a #${public}.\n')
+ elif field['format'] == 'guint32-array':
+ inner_template = (' * @${field}: the \'${name}\' field, given as an array of #${public}.\n')
+ elif field['format'] == 'guint64':
+ inner_template = (' * @${field}: the \'${name}\' field, given as a #${public}.\n')
+ elif field['format'] == 'guint64-array':
+ inner_template = (' * @${field}: the \'${name}\' field, given as an array of #${public}.\n')
+ elif field['format'] == 'string':
+ inner_template = (' * @${field}: the \'${name}\' field, given as a string.\n')
+ elif field['format'] == 'string-array':
+ inner_template = (' * @${field}: the \'${name}\' field, given as an array of strings.\n')
+ elif field['format'] == 'struct':
+ inner_template = (' * @${field}: the \'${name}\' field, given as a #${struct}.\n')
+ elif field['format'] == 'struct-array':
+ inner_template = (' * @${field}: the \'${name}\' field, given as an array of #${struct}s.\n')
+ elif field['format'] == 'ref-struct-array':
+ inner_template = (' * @${field}: the \'${name}\' field, given as an array of #${struct}s.\n')
+ elif field['format'] == 'ipv4':
+ inner_template = (' * @${field}: the \'${name}\' field, given as a #MbimIPv4.\n')
+ elif field['format'] == 'ref-ipv4':
+ inner_template = (' * @${field}: the \'${name}\' field, given as a #MbimIPv4.\n')
+ elif field['format'] == 'ipv4-array':
+ inner_template = (' * @${field}: the \'${name}\' field, given as an array of #MbimIPv4.\n')
+ elif field['format'] == 'ipv6':
+ inner_template = (' * @${field}: the \'${name}\' field, given as a #MbimIPv6.\n')
+ elif field['format'] == 'ref-ipv6':
+ inner_template = (' * @${field}: the \'${name}\' field, given as a #MbimIPv6.\n')
+ elif field['format'] == 'ipv6-array':
+ inner_template = (' * @${field}: the \'${name}\' field, given as an array of #MbimIPv6.\n')
+
+ template += (string.Template(inner_template).substitute(translations))
template += (
' * @error: return location for error or %NULL.\n'
' *\n'
- ' * Create a new request for the \'${name}\' ${message_type} command in the \'${service}\' service.\n'
+ ' * Create a new request for the \'${message}\' ${message_type} command in the \'${service}\' service.\n'
' *\n'
' * Returns: a newly allocated #MbimMessage, which should be freed with mbim_message_unref().\n'
' */\n'
'MbimMessage *\n'
'${underscore}_${message_type}_new (\n')
- if container != None:
- for field in container.fields:
- translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase (field.name)
- translations['field_in_format'] = field.in_format
- inner_template = (
- ' ${field_in_format}${field_name_underscore},\n')
- template += (string.Template(inner_template).substitute(translations))
+ for field in fields:
+ translations['field'] = utils.build_underscore_name_from_camelcase (field['name'])
+ translations['struct'] = field['struct-type'] if 'struct-type' in field else ''
+ translations['public'] = field['public-format'] if 'public-format' in field else field['format']
+
+ if field['format'] == 'uuid':
+ inner_template = (' const MbimUuid *${field},\n')
+ elif field['format'] == 'guint32':
+ inner_template = (' ${public} ${field},\n')
+ elif field['format'] == 'guint32-array':
+ inner_template = (' const ${public} *${field},\n')
+ elif field['format'] == 'guint64':
+ inner_template = (' ${public} ${field},\n')
+ elif field['format'] == 'guint64-array':
+ inner_template = (' const ${public} *${field},\n')
+ elif field['format'] == 'string':
+ inner_template = (' const gchar *${field},\n')
+ elif field['format'] == 'string-array':
+ inner_template = (' const gchar *const *${field},\n')
+ elif field['format'] == 'struct':
+ inner_template = (' const ${struct} *${field},\n')
+ elif field['format'] == 'struct-array':
+ inner_template = (' const ${struct} *const *${field},\n')
+ elif field['format'] == 'ref-struct-array':
+ inner_template = (' const ${struct} *const *${field},\n')
+ elif field['format'] == 'ipv4':
+ inner_template = (' const MbimIPv4 *${field},\n')
+ elif field['format'] == 'ref-ipv4':
+ inner_template = (' const MbimIPv4 *${field},\n')
+ elif field['format'] == 'ipv4-array':
+ inner_template = (' const MbimIPv4 *${field},\n')
+ elif field['format'] == 'ipv6':
+ inner_template = (' const MbimIPv6 *${field},\n')
+ elif field['format'] == 'ref-ipv6':
+ inner_template = (' const MbimIPv6 *${field},\n')
+ elif field['format'] == 'ipv6-array':
+ inner_template = (' const MbimIPv6 *${field},\n')
+
+ template += (string.Template(inner_template).substitute(translations))
template += (
' GError **error)\n'
@@ -136,14 +328,45 @@ class Message:
' MBIM_CID_${service_underscore_upper}_${name_underscore_upper},\n'
' MBIM_MESSAGE_COMMAND_TYPE_${message_type_upper});\n')
- if container != None:
- template += ('\n')
- for field in container.fields:
- translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase(field.name)
- translations['field_format_underscore'] = utils.build_underscore_name(field.format)
- inner_template = (
- ' _mbim_message_command_builder_append_${field_format_underscore} (builder, ${field_name_underscore});\n')
- template += (string.Template(inner_template).substitute(translations))
+ for field in fields:
+ translations['field'] = utils.build_underscore_name_from_camelcase(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'] = field['struct-type'] if 'struct-type' in field else ''
+ translations['struct_underscore'] = utils.build_underscore_name_from_camelcase (translations['struct'])
+
+ inner_template = (' ')
+ if field['format'] == 'uuid':
+ inner_template = (' _mbim_message_command_builder_append_uuid (builder, ${field});\n')
+ elif field['format'] == 'guint32':
+ inner_template = (' _mbim_message_command_builder_append_guint32 (builder, ${field});\n')
+ elif field['format'] == 'guint32-array':
+ inner_template = (' _mbim_message_command_builder_append_guint32_array (builder, ${field}, ${array_size_field});\n')
+ elif field['format'] == 'guint64':
+ inner_template = (' _mbim_message_command_builder_append_guint64 (builder, ${field});\n')
+ elif field['format'] == 'string':
+ inner_template = (' _mbim_message_command_builder_append_string (builder, ${field});\n')
+ elif field['format'] == 'string-array':
+ inner_template = (' _mbim_message_command_builder_append_string_array (builder, ${field}, ${array_size_field});\n')
+ elif field['format'] == 'struct':
+ inner_template = (' _mbim_message_command_builder_append_${struct_underscore}_struct (builder, ${field});\n')
+ elif field['format'] == 'struct-array':
+ inner_template = (' _mbim_message_command_builder_append_${struct_underscore}_struct_array (builder, ${field}, ${array_size_field}, FALSE);\n')
+ elif field['format'] == 'ref-struct-array':
+ inner_template = (' _mbim_message_command_builder_append_${struct_underscore}_struct_array (builder, ${field}, ${array_size_field}, TRUE);\n')
+ elif field['format'] == 'ipv4':
+ inner_template = (' _mbim_message_command_builder_append_ipv4 (builder, ${field}, FALSE);\n')
+ elif field['format'] == 'ref-ipv4':
+ inner_template = (' _mbim_message_command_builder_append_ipv4 (builder, ${field}, TRUE);\n')
+ elif field['format'] == 'ipv4-array':
+ inner_template = (' _mbim_message_command_builder_append_ipv4_array (builder, ${field}, ${array_size_field});\n')
+ elif field['format'] == 'ipv6':
+ inner_template = (' _mbim_message_command_builder_append_ipv6 (builder, ${field}, FALSE);\n')
+ elif field['format'] == 'ref-ipv6':
+ inner_template = (' _mbim_message_command_builder_append_ipv6 (builder, ${field}, TRUE);\n')
+ elif field['format'] == 'ipv6-array':
+ inner_template = (' _mbim_message_command_builder_append_ipv6_array (builder, ${field}, ${array_size_field});\n')
+
+ template += (string.Template(inner_template).substitute(translations))
template += (
'\n'
@@ -155,7 +378,7 @@ class Message:
"""
Emit message parser
"""
- def _emit_message_parser(self, hfile, cfile, message_type, container):
+ def _emit_message_parser(self, hfile, cfile, message_type, fields):
translations = { 'name' : self.name,
'service' : self.service,
'underscore' : utils.build_underscore_name (self.fullname),
@@ -168,13 +391,45 @@ class Message:
'gboolean ${underscore}_${message_type}_parse (\n'
' const MbimMessage *message,\n')
- if container != None:
- for field in container.fields:
- translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase(field.name)
- translations['field_out_format'] = field.out_format
- inner_template = (
- ' ${field_out_format}${field_name_underscore},\n')
- template += (string.Template(inner_template).substitute(translations))
+ for field in fields:
+ translations['field'] = utils.build_underscore_name_from_camelcase(field['name'])
+ translations['public'] = field['public-format'] if 'public-format' in field else field['format']
+ translations['struct'] = field['struct-type'] if 'struct-type' in field else ''
+
+ if field['format'] == 'uuid':
+ inner_template = (' const MbimUuid **${field},\n')
+ elif field['format'] == 'guint32':
+ inner_template = (' ${public} *${field},\n')
+ elif field['format'] == 'guint32-array':
+ inner_template = (' ${public} **${field},\n')
+ elif field['format'] == 'guint64':
+ inner_template = (' ${public} *${field},\n')
+ elif field['format'] == 'guint64-array':
+ inner_template = (' ${public} **${field},\n')
+ elif field['format'] == 'string':
+ inner_template = (' gchar **${field},\n')
+ elif field['format'] == 'string-array':
+ inner_template = (' gchar ***${field},\n')
+ elif field['format'] == 'struct':
+ inner_template = (' ${struct} **${field},\n')
+ elif field['format'] == 'struct-array':
+ inner_template = (' ${struct} ***${field},\n')
+ elif field['format'] == 'ref-struct-array':
+ inner_template = (' ${struct} ***${field},\n')
+ elif field['format'] == 'ipv4':
+ inner_template = (' const MbimIPv4 **${field},\n')
+ elif field['format'] == 'ref-ipv4':
+ inner_template = (' const MbimIPv4 **${field},\n')
+ elif field['format'] == 'ipv4-array':
+ inner_template = (' MbimIPv4 **${field},\n')
+ elif field['format'] == 'ipv6':
+ inner_template = (' const MbimIPv6 **${field},\n')
+ elif field['format'] == 'ref-ipv6':
+ inner_template = (' const MbimIPv6 **${field},\n')
+ elif field['format'] == 'ipv6-array':
+ inner_template = (' MbimIPv6 **${field},\n')
+
+ template += (string.Template(inner_template).substitute(translations))
template += (
' GError **error);\n')
@@ -186,14 +441,47 @@ class Message:
' * ${underscore}_${message_type}_parse:\n'
' * @message: the #MbimMessage.\n')
- if container != None:
- for field in container.fields:
- translations['field_name'] = field.name
- translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase(field.name)
- translations['field_out_description'] = field.out_description
- inner_template = (
- ' * @${field_name_underscore}: ${field_out_description}\n')
- template += (string.Template(inner_template).substitute(translations))
+ for field in fields:
+ translations['field'] = utils.build_underscore_name_from_camelcase(field['name'])
+ translations['name'] = field['name']
+ translations['public'] = field['public-format'] if 'public-format' in field else field['format']
+ translations['struct'] = field['struct-type'] if 'struct-type' in field else ''
+ translations['struct_underscore'] = utils.build_underscore_name_from_camelcase (translations['struct'])
+
+ if field['format'] == 'uuid':
+ inner_template = (' * @${field}: return location for a #MbimUuid, or %NULL if the \'${name}\' field is not needed. Do not free the returned value, it is owned by @message.\n')
+ elif field['format'] == 'guint32':
+ inner_template = (' * @${field}: return location for a #${public}, or %NULL if the \'${name}\' field is not needed.\n')
+ elif field['format'] == 'guint32-array':
+ inner_template = (' * @${field}: return location for a newly allocated array of #${public}s, or %NULL if the \'${name}\' field is not needed. Free the returned value with g_free().\n')
+ elif field['format'] == 'guint64':
+ inner_template = (' * @${field}: return location for a #guint64, or %NULL if the \'${name}\' field is not needed.\n')
+ elif field['format'] == 'guint64-array':
+ inner_template = (' * @${field}: return location for a newly allocated array of #guint64s, or %NULL if the \'${name}\' field is not needed. Free the returned value with g_free().\n')
+ elif field['format'] == 'string':
+ inner_template = (' * @${field}: return location for a newly allocated string, or %NULL if the \'${name}\' field is not needed. Free the returned value with g_free().\n')
+ elif field['format'] == 'string-array':
+ inner_template = (' * @${field}: return location for a newly allocated array of strings, or %NULL if the \'${name}\' field is not needed. Free the returned value with g_strfreev().\n')
+ elif field['format'] == 'struct':
+ inner_template = (' * @${field}: return location for a newly allocated #${struct}, or %NULL if the \'${name}\' field is not needed. Free the returned value with ${struct_underscore}_free().\n')
+ elif field['format'] == 'struct-array':
+ inner_template = (' * @${field}: return location for a newly allocated array of #${struct}s, or %NULL if the \'${name}\' field is not needed. Free the returned value with ${struct_underscore}_array_free().\n')
+ elif field['format'] == 'ref-struct-array':
+ inner_template = (' * @${field}: return location for a newly allocated array of #${struct}s, or %NULL if the \'${name}\' field is not needed. Free the returned value with ${struct_underscore}_array_free().\n')
+ elif field['format'] == 'ipv4':
+ inner_template = (' * @${field}: return location for a #MbimIPv4, or %NULL if the \'${name}\' field is not needed. Do not free the returned value, it is owned by @message.\n')
+ elif field['format'] == 'ref-ipv4':
+ inner_template = (' * @${field}: return location for a #MbimIPv4, or %NULL if the \'${name}\' field is not needed. Do not free the returned value, it is owned by @message.\n')
+ elif field['format'] == 'ipv4-array':
+ inner_template = (' * @${field}: return location for a newly allocated array of #MbimIPv4s, or %NULL if the \'${name}\' field is not needed. Free the returned value with g_free().\n')
+ elif field['format'] == 'ipv6':
+ inner_template = (' * @${field}: return location for a #MbimIPv6, or %NULL if the \'${name}\' field is not needed. Do not free the returned value, it is owned by @message.\n')
+ elif field['format'] == 'ref-ipv6':
+ inner_template = (' * @${field}: return location for a #MbimIPv6, or %NULL if the \'${name}\' field is not needed. Do not free the returned value, it is owned by @message.\n')
+ elif field['format'] == 'ipv6-array':
+ inner_template = (' * @${field}: return location for a newly allocated array of #MbimIPv6s, or %NULL if the \'${name}\' field is not needed. Free the returned value with g_free().\n')
+
+ template += (string.Template(inner_template).substitute(translations))
template += (
' * @error: return location for error or %NULL.\n'
@@ -206,107 +494,161 @@ class Message:
'${underscore}_${message_type}_parse (\n'
' const MbimMessage *message,\n')
- if container != None:
- for field in container.fields:
- translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase(field.name)
- translations['field_out_format'] = field.out_format
- inner_template = (
- ' ${field_out_format}${field_name_underscore},\n')
- template += (string.Template(inner_template).substitute(translations))
+ for field in fields:
+ translations['field'] = utils.build_underscore_name_from_camelcase(field['name'])
+ translations['public'] = field['public-format'] if 'public-format' in field else field['format']
+ translations['struct'] = field['struct-type'] if 'struct-type' in field else ''
+
+ if field['format'] == 'uuid':
+ inner_template = (' const MbimUuid **${field},\n')
+ elif field['format'] == 'guint32':
+ inner_template = (' ${public} *${field},\n')
+ elif field['format'] == 'guint32-array':
+ inner_template = (' ${public} **${field},\n')
+ elif field['format'] == 'guint64':
+ inner_template = (' ${public} *${field},\n')
+ elif field['format'] == 'guint64-array':
+ inner_template = (' ${public} **${field},\n')
+ elif field['format'] == 'string':
+ inner_template = (' gchar **${field},\n')
+ elif field['format'] == 'string-array':
+ inner_template = (' gchar ***${field},\n')
+ elif field['format'] == 'struct':
+ inner_template = (' ${struct} **${field},\n')
+ elif field['format'] == 'struct-array':
+ inner_template = (' ${struct} ***${field},\n')
+ elif field['format'] == 'ref-struct-array':
+ inner_template = (' ${struct} ***${field},\n')
+ elif field['format'] == 'ipv4':
+ inner_template = (' const MbimIPv4 **${field},\n')
+ elif field['format'] == 'ref-ipv4':
+ inner_template = (' const MbimIPv4 **${field},\n')
+ elif field['format'] == 'ipv4-array':
+ inner_template = (' MbimIPv4 **${field},\n')
+ elif field['format'] == 'ipv6':
+ inner_template = (' const MbimIPv6 **${field},\n')
+ elif field['format'] == 'ref-ipv6':
+ inner_template = (' const MbimIPv6 **${field},\n')
+ elif field['format'] == 'ipv6-array':
+ inner_template = (' MbimIPv6 **${field},\n')
+
+ template += (string.Template(inner_template).substitute(translations))
template += (
' GError **error)\n'
'{\n'
' guint32 offset = 0;\n')
- if container != None:
- for field in container.fields:
- if field.is_array_size:
- translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase(field.name)
- inner_template = (
- ' guint32 _${field_name_underscore};\n')
- template += (string.Template(inner_template).substitute(translations))
-
- if container != None:
- for field in container.fields:
- translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase(field.name)
- translations['field_format_underscore'] = utils.build_underscore_name(field.format)
- translations['field_size'] = field.size
- translations['field_size_string'] = field.size_string
- translations['field_name'] = field.name
-
- inner_template = (
- '\n'
- ' /* Read the \'${field_name}\' variable */\n'
- ' {\n')
-
- if field.is_array_size:
- inner_template += (
- ' _${field_name_underscore} = _mbim_message_read_guint32 (message, offset);\n'
- ' if (${field_name_underscore} != NULL)\n'
- ' *${field_name_underscore} = _${field_name_underscore};\n'
- ' offset += 4;\n')
- elif field.format == 'uuid':
- inner_template += (
- ' if (${field_name_underscore} != NULL)\n'
- ' *${field_name_underscore} = _mbim_message_read_uuid (message, offset);\n'
- ' offset += 16;\n')
- elif field.format == 'guint32':
- inner_template += (
- ' if (${field_name_underscore} != NULL)\n'
- ' *${field_name_underscore} = _mbim_message_read_guint32 (message, offset);\n'
- ' offset += 4;\n')
- elif field.format == 'guint32-array':
- translations['array_size_field_name_underscore'] = utils.build_underscore_name_from_camelcase(field.array_size_field)
- inner_template += (
- ' if (${field_name_underscore} != NULL)\n'
- ' *${field_name_underscore} = _mbim_message_read_guint32_array (message, _{array_size_field_name_underscore}, offset);\n'
- ' offset += (4 * _${array_size_field_name_underscore});\n')
- elif field.format == 'guint64':
- inner_template += (
- ' if (${field_name_underscore} != NULL)\n'
- ' *${field_name_underscore} = _mbim_message_read_guint64 (message, offset);\n'
- ' offset += 8;\n')
- elif field.format == 'string':
- inner_template += (
- ' if (${field_name_underscore} != NULL)\n'
- ' *${field_name_underscore} = _mbim_message_read_string (message, offset);\n'
- ' offset += 8;\n')
- elif field.format == 'string-array':
- translations['array_size_field_name_underscore'] = utils.build_underscore_name_from_camelcase(field.array_size_field)
- inner_template += (
- ' if (${field_name_underscore} != NULL)\n'
- ' *${field_name_underscore} = _mbim_message_read_string_array (message, _${array_size_field_name_underscore}, offset);\n'
- ' offset += (8 * _${array_size_field_name_underscore});\n')
- elif field.format == 'struct':
- translations['struct_name'] = field.struct_type_underscore
- translations['struct_type'] = field.struct_type
-
- inner_template += (
- ' ${struct_type} *tmp;\n'
- ' guint32 bytes_read = 0;\n'
- '\n'
- ' tmp = _mbim_message_read_${struct_name}_struct (message, offset, &bytes_read);\n'
- ' if (${field_name_underscore} != NULL)\n'
- ' *${field_name_underscore} = tmp;\n'
- ' else\n'
- ' ${struct_name}_free (tmp);\n'
- ' offset += bytes_read;\n')
- elif field.format == 'struct-array':
- translations['array_size_field_name_underscore'] = utils.build_underscore_name_from_camelcase (field.array_size_field)
- translations['array_member_size'] = str(field.array_member_size)
- translations['struct_name'] = field.struct_type_underscore
-
- inner_template += (
- ' if (${field_name_underscore} != NULL)\n'
- ' *${field_name_underscore} = _mbim_message_read_${struct_name}_struct_array (message, _${array_size_field_name_underscore}, offset);\n'
- ' offset += (${array_member_size} * _${array_size_field_name_underscore});\n')
- else:
- raise ValueError('Cannot handle format \'%s\' as a field' % field.format)
+ for field in fields:
+ if 'is-array-size' in field:
+ translations['field'] = utils.build_underscore_name_from_camelcase(field['name'])
+ inner_template = (' guint32 _${field};\n')
+ template += (string.Template(inner_template).substitute(translations))
+ for field in fields:
+ translations['field'] = utils.build_underscore_name_from_camelcase(field['name'])
+ translations['field_format_underscore'] = utils.build_underscore_name_from_camelcase(field['format'])
+ 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 ''
+
+ inner_template = (
+ '\n'
+ ' /* Read the \'${field_name}\' variable */\n'
+ ' {\n')
+
+ if 'is-array-size' in field:
+ inner_template += (
+ ' _${field} = _mbim_message_read_guint32 (message, offset);\n'
+ ' if (${field} != NULL)\n'
+ ' *${field} = _${field};\n'
+ ' offset += 4;\n')
+ elif field['format'] == 'uuid':
+ inner_template += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_uuid (message, offset);\n'
+ ' offset += 16;\n')
+ elif field['format'] == 'guint32':
+ inner_template += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_guint32 (message, offset);\n'
+ ' offset += 4;\n')
+ elif field['format'] == 'guint32-array':
inner_template += (
- ' }\n')
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_guint32_array (message, _{array_size_field}, offset);\n'
+ ' offset += (4 * _${array_size_field});\n')
+ elif field['format'] == 'guint64':
+ inner_template += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_guint64 (message, offset);\n'
+ ' offset += 8;\n')
+ elif field['format'] == 'string':
+ inner_template += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_string (message, offset);\n'
+ ' offset += 8;\n')
+ elif field['format'] == 'string-array':
+ inner_template += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_string_array (message, _${array_size_field}, offset);\n'
+ ' offset += (8 * _${array_size_field});\n')
+ elif field['format'] == 'struct':
+ inner_template += (
+ ' ${struct_type} *tmp;\n'
+ ' guint32 bytes_read = 0;\n'
+ '\n'
+ ' tmp = _mbim_message_read_${struct_name}_struct (message, offset, &bytes_read);\n'
+ ' if (${field} != NULL)\n'
+ ' *${field} = tmp;\n'
+ ' else\n'
+ ' ${struct_name}_free (tmp);\n'
+ ' offset += bytes_read;\n')
+ elif field['format'] == 'struct-array':
+ inner_template += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _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 += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_${struct_name}_struct_array (message, _${array_size_field}, offset, TRUE);\n'
+ ' offset += (8 * _${array_size_field});\n')
+ elif field['format'] == 'ipv4':
+ inner_template += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_ipv4 (message, offset, FALSE);\n'
+ ' offset += 4;\n')
+ elif field['format'] == 'ref-ipv4':
+ inner_template += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_ipv4 (message, offset, TRUE);\n'
+ ' offset += 4;\n')
+ elif field['format'] == 'ipv4-array':
+ inner_template += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_ipv4_array (message, _${array_size_field}, offset);\n'
+ ' offset += 4;\n')
+ elif field['format'] == 'ipv6':
+ inner_template += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_ipv6 (message, offset, FALSE);\n'
+ ' offset += 4;\n')
+ elif field['format'] == 'ref-ipv6':
+ inner_template += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_ipv6 (message, offset, TRUE);\n'
+ ' offset += 4;\n')
+ elif field['format'] == 'ipv6-array':
+ inner_template += (
+ ' if (${field} != NULL)\n'
+ ' *${field} = _mbim_message_read_ipv6_array (message, _${array_size_field}, offset);\n'
+ ' offset += 4;\n')
- template += (string.Template(inner_template).substitute(translations))
+ inner_template += (
+ ' }\n')
+
+ template += (string.Template(inner_template).substitute(translations))
template += (
'\n'
@@ -316,31 +658,6 @@ class Message:
"""
- Emit the message handling implementation
- """
- def emit(self, hfile, cfile):
- if self.query:
- 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_container)
-
- if self.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_container)
-
- if self.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_container)
-
- if self.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_container)
-
-
- """
Emit the sections
"""
def emit_sections(self, sfile):
diff --git a/build-aux/mbim-codegen/Struct.py b/build-aux/mbim-codegen/Struct.py
index a01858a..30a3a90 100644
--- a/build-aux/mbim-codegen/Struct.py
+++ b/build-aux/mbim-codegen/Struct.py
@@ -34,6 +34,24 @@ class Struct:
self.name = dictionary['name']
self.contents = dictionary['contents']
+ # Check whether the struct is composed of fixed-sized fields
+ self.size = 0
+ for field in self.contents:
+ if field['format'] == 'guint32':
+ self.size += 4
+ elif field['format'] == 'guint64':
+ self.size += 8
+ elif field['format'] == 'uuid':
+ self.size += 16
+ elif field['format'] == 'ipv4':
+ self.size += 4
+ elif field['format'] == 'ipv6':
+ self.size += 16
+ else:
+ self.size = 0
+ break
+
+
"""
Emit the new struct type
"""
@@ -62,6 +80,24 @@ class Struct:
elif field['format'] == 'string-array':
inner_template = (
' gchar **${field_name_underscore};\n')
+ elif field['format'] == 'ipv4':
+ inner_template = (
+ ' MbimIPv4 ${field_name_underscore};\n')
+ elif field['format'] == 'ref-ipv4':
+ inner_template = (
+ ' MbimIPv4 ${field_name_underscore};\n')
+ elif field['format'] == 'ipv4-array':
+ inner_template = (
+ ' MbimIPv4 *${field_name_underscore};\n')
+ elif field['format'] == 'ipv6':
+ inner_template = (
+ ' MbimIPv6 ${field_name_underscore};\n')
+ elif field['format'] == 'ref-ipv6':
+ inner_template = (
+ ' MbimIPv6 ${field_name_underscore};\n')
+ elif field['format'] == 'ipv6-array':
+ inner_template = (
+ ' MbimIPv6 *${field_name_underscore};\n')
else:
raise ValueError('Cannot handle format \'%s\' in struct' % field['format'])
template += string.Template(inner_template).substitute(translations)
@@ -92,7 +128,10 @@ class Struct:
' */\n'
'void\n'
'${name_underscore}_free (${name} *var)\n'
- '{\n')
+ '{\n'
+ ' if (!var)\n'
+ ' return;\n'
+ '\n')
for field in self.contents:
translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase(field['name'])
@@ -112,6 +151,20 @@ class Struct:
elif field['format'] == 'string-array':
inner_template += (
' g_strfreev (var->${field_name_underscore});\n')
+ elif field['format'] == 'ipv4':
+ pass
+ elif field['format'] == 'ref-ipv4':
+ pass
+ elif field['format'] == 'ipv4-array':
+ inner_template += (
+ ' g_free (var->${field_name_underscore});\n')
+ elif field['format'] == 'ipv6':
+ pass
+ elif field['format'] == 'ref-ipv6':
+ pass
+ elif field['format'] == 'ipv6-array':
+ inner_template += (
+ ' g_free (var->${field_name_underscore});\n')
else:
raise ValueError('Cannot handle format \'%s\' in struct clear' % field['format'])
template += string.Template(inner_template).substitute(translations)
@@ -131,6 +184,9 @@ class Struct:
'{\n'
' guint32 i;\n'
'\n'
+ ' if (!array)\n'
+ ' return;\n'
+ '\n'
' for (i = 0; array[i]; i++)\n'
' ${name_underscore}_free (array[i]);\n'
' g_free (array);\n'
@@ -142,13 +198,9 @@ class Struct:
Emit the type's read methods
"""
def _emit_read(self, cfile):
- # Setup offset for reading fields
- offset = 0
- # Additional offset string computation
- additional_offset_str = ''
-
translations = { 'name' : self.name,
- 'name_underscore' : utils.build_underscore_name_from_camelcase(self.name) }
+ 'name_underscore' : utils.build_underscore_name_from_camelcase(self.name),
+ 'struct_size' : self.size }
template = (
'\n'
@@ -167,14 +219,12 @@ class Struct:
for field in self.contents:
translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase(field['name'])
- translations['format_underscore'] = utils.build_underscore_name(field['format'])
- translations['offset'] = offset
inner_template = ''
if field['format'] == 'uuid':
inner_template += (
'\n'
- ' memcpy (&out->${field_name_underscore}, _mbim_message_read_uuid (self, offset), 16);\n'
+ ' memcpy (&(out->${field_name_underscore}), _mbim_message_read_uuid (self, offset), 16);\n'
' offset += 16;\n')
elif field['format'] == 'guint32':
inner_template += (
@@ -203,6 +253,36 @@ class Struct:
'\n'
' out->${field_name_underscore} = _mbim_message_read_string_array (self, out->${array_size_field_name_underscore}, offset);\n'
' offset += (8 * out->${array_size_field_name_underscore});\n')
+ elif field['format'] == 'ipv4':
+ inner_template += (
+ '\n'
+ ' memcpy (&(out->${field_name_underscore}), _mbim_message_read_ipv4 (self, offset, FALSE), 4);\n'
+ ' offset += 4;\n')
+ elif field['format'] == 'ref-ipv4':
+ inner_template += (
+ '\n'
+ ' memcpy (&(out->${field_name_underscore}), _mbim_message_read_ipv4 (self, offset, TRUE), 4);\n'
+ ' offset += 4;\n')
+ elif field['format'] == 'ipv4-array':
+ inner_template += (
+ '\n'
+ ' out->${field_name_underscore} =_mbim_message_read_ipv4_array (self, out->${array_size_field_name_underscore}, offset);\n'
+ ' offset += 4;\n')
+ elif field['format'] == 'ipv6':
+ inner_template += (
+ '\n'
+ ' memcpy (&(out->${field_name_underscore}), _mbim_message_read_ipv6 (self, offset, FALSE), 16);\n'
+ ' offset += 4;\n')
+ elif field['format'] == 'ref-ipv6':
+ inner_template += (
+ '\n'
+ ' memcpy (&(out->${field_name_underscore}), _mbim_message_read_ipv6 (self, offset, TRUE), 16);\n'
+ ' offset += 4;\n')
+ elif field['format'] == 'ipv6-array':
+ inner_template += (
+ '\n'
+ ' out->${field_name_underscore} =_mbim_message_read_ipv6_array (self, out->${array_size_field_name_underscore}, offset);\n'
+ ' offset += 4;\n')
else:
raise ValueError('Cannot handle format \'%s\' in struct' % field['format'])
@@ -217,23 +297,33 @@ class Struct:
'}\n')
cfile.write(string.Template(template).substitute(translations))
-
template = (
'\n'
'static ${name} **\n'
'_mbim_message_read_${name_underscore}_struct_array (\n'
' const MbimMessage *self,\n'
' guint32 array_size,\n'
- ' guint32 relative_offset_array_start)\n'
+ ' guint32 relative_offset_array_start,\n'
+ ' gboolean refs)\n'
'{\n'
' ${name} **out;\n'
' guint32 i;\n'
' guint32 offset;\n'
'\n'
+ ' if (!array_size)\n'
+ ' return NULL;\n'
+ '\n'
' out = g_new (${name} *, array_size + 1);\n'
- ' offset = relative_offset_array_start;\n'
- ' for (i = 0; i < array_size; i++, offset += 8)\n'
- ' out[i] = _mbim_message_read_${name_underscore}_struct (self, _mbim_message_read_guint32 (self, offset), NULL);\n'
+ '\n'
+ ' if (!refs) {\n'
+ ' offset = _mbim_message_read_guint32 (self, relative_offset_array_start);\n'
+ ' for (i = 0; i < array_size; i++, offset += ${struct_size})\n'
+ ' out[i] = _mbim_message_read_${name_underscore}_struct (self, offset, NULL);\n'
+ ' } else {\n'
+ ' offset = relative_offset_array_start;\n'
+ ' for (i = 0; i < array_size; i++, offset += 8)\n'
+ ' out[i] = _mbim_message_read_${name_underscore}_struct (self, _mbim_message_read_guint32 (self, offset), NULL);\n'
+ ' }\n'
' out[array_size] = NULL;\n'
'\n'
' return out;\n'
@@ -242,6 +332,154 @@ class Struct:
"""
+ Emit the type's append methods
+ """
+ def _emit_append(self, cfile):
+ translations = { 'name' : self.name,
+ 'name_underscore' : utils.build_underscore_name_from_camelcase(self.name),
+ 'struct_size' : self.size }
+
+ template = (
+ '\n'
+ 'static GByteArray *\n'
+ '_${name_underscore}_struct_new (const ${name} *value)\n'
+ '{\n'
+ ' MbimStructBuilder *builder;\n'
+ '\n'
+ ' g_assert (value != NULL);\n'
+ '\n'
+ ' builder = _mbim_struct_builder_new ();\n')
+
+ for field in self.contents:
+ translations['field'] = utils.build_underscore_name_from_camelcase(field['name'])
+ translations['array_size_field'] = utils.build_underscore_name_from_camelcase(field['array-size-field']) if 'array-size-field' in field else ''
+
+ if field['format'] == 'uuid':
+ inner_template = (' _mbim_struct_builder_append_uuid (builder, &value->${field});\n')
+ elif field['format'] == 'guint32':
+ inner_template = (' _mbim_struct_builder_append_guint32 (builder, value->${field});\n')
+ elif field['format'] == 'guint32-array':
+ inner_template = (' _mbim_struct_builder_append_guint32_array (builder, value->${field}, value->${array_size_field});\n')
+ elif field['format'] == 'guint64':
+ inner_template = (' _mbim_struct_builder_append_guint64 (builder, value->${field});\n')
+ elif field['format'] == 'guint64-array':
+ inner_template = (' _mbim_struct_builder_append_guint64_array (builder, value->${field}, value->${array_size_field});\n')
+ elif field['format'] == 'string':
+ inner_template = (' _mbim_struct_builder_append_string (builder, value->${field});\n')
+ elif field['format'] == 'string-array':
+ inner_template = (' _mbim_struct_builder_append_string_array (builder, value->${field}, value->${array_size_field});\n')
+ elif field['format'] == 'ipv4':
+ inner_template = (' _mbim_struct_builder_append_ipv4 (builder, &value->${field}, FALSE);\n')
+ elif field['format'] == 'ref-ipv4':
+ inner_template = (' _mbim_struct_builder_append_ipv4 (builder, &value->${field}, TRUE);\n')
+ elif field['format'] == 'ipv4-array':
+ inner_template = (' _mbim_struct_builder_append_ipv4_array (builder, value->${field}, value->${array_size_field});\n')
+ elif field['format'] == 'ipv6':
+ inner_template = (' _mbim_struct_builder_append_ipv6 (builder, &value->${field}, FALSE);\n')
+ elif field['format'] == 'ref-ipv6':
+ inner_template = (' _mbim_struct_builder_append_ipv6 (builder, &value->${field}, TRUE);\n')
+ elif field['format'] == 'ipv6-array':
+ inner_template = (' _mbim_struct_builder_append_ipv6_array (builder, value->${field}, value->${array_size_field});\n')
+ else:
+ raise ValueError('Cannot handle format \'%s\' in struct' % field['format'])
+
+ template += string.Template(inner_template).substitute(translations)
+
+ template += (
+ '\n'
+ ' return _mbim_struct_builder_complete (builder);\n'
+ '}\n')
+ cfile.write(string.Template(template).substitute(translations))
+
+ template = (
+ '\n'
+ 'static void\n'
+ '_mbim_struct_builder_append_${name_underscore}_struct (\n'
+ ' MbimStructBuilder *builder,\n'
+ ' const ${name} *value)\n'
+ '{\n'
+ ' GByteArray *raw;\n'
+ '\n'
+ ' raw = _${name_underscore}_struct_new (value);\n'
+ ' g_byte_array_append (builder->fixed_buffer, raw->data, raw->len);\n'
+ ' g_byte_array_unref (raw);\n'
+ '}\n'
+ '\n'
+ 'static void\n'
+ '_mbim_message_command_builder_append_${name_underscore}_struct (\n'
+ ' MbimMessageCommandBuilder *builder,\n'
+ ' const ${name} *value)\n'
+ '{\n'
+ ' _mbim_struct_builder_append_${name_underscore}_struct (builder->contents_builder, value);\n'
+ '}\n')
+ cfile.write(string.Template(template).substitute(translations))
+
+ template = (
+ '\n'
+ 'static void\n'
+ '_mbim_struct_builder_append_${name_underscore}_struct_array (\n'
+ ' MbimStructBuilder *builder,\n'
+ ' const ${name} *const *values,\n'
+ ' guint32 n_values,\n'
+ ' gboolean refs)\n'
+ '{\n'
+ ' guint32 offset;\n'
+ ' guint32 i;\n'
+ ' GByteArray *raw_all = NULL;\n'
+ '\n'
+ ' if (!refs) {\n'
+ ' for (i = 0; i < n_values; i++) {\n'
+ ' GByteArray *raw;\n'
+ '\n'
+ ' raw = _${name_underscore}_struct_new (values[i]);\n'
+ ' if (!raw_all)\n'
+ ' raw_all = raw;\n'
+ ' else {\n'
+ ' g_byte_array_append (raw_all, raw->data, raw->len);\n'
+ ' g_byte_array_unref (raw);\n'
+ ' }\n'
+ ' }\n'
+ '\n'
+ ' if (!raw_all) {\n'
+ ' offset = 0;\n'
+ ' g_byte_array_append (builder->fixed_buffer, (guint8 *)&offset, sizeof (offset));\n'
+ ' } else {\n'
+ ' guint32 offset_offset;\n'
+ '\n'
+ ' /* Offset of the offset */\n'
+ ' offset_offset = builder->fixed_buffer->len;\n'
+ ' /* Length *not* in LE yet */\n'
+ ' offset = builder->variable_buffer->len;\n'
+ ' /* Add the offset value */\n'
+ ' g_byte_array_append (builder->fixed_buffer, (guint8 *)&offset, sizeof (offset));\n'
+ ' /* Configure the value to get updated */\n'
+ ' g_array_append_val (builder->offsets, offset_offset);\n'
+ ' /* Add the final array itself */\n'
+ ' g_byte_array_append (builder->variable_buffer, raw_all->data, raw_all->len);\n'
+ ' g_byte_array_unref (raw_all);\n'
+ ' }\n'
+ ' } else {\n'
+ ' /* TODO */\n'
+ ' g_assert_not_reached ();\n'
+ ' }\n'
+ '}\n')
+ cfile.write(string.Template(template).substitute(translations))
+
+ template = (
+ '\n'
+ 'static void\n'
+ '_mbim_message_command_builder_append_${name_underscore}_struct_array (\n'
+ ' MbimMessageCommandBuilder *builder,\n'
+ ' const ${name} *const *values,\n'
+ ' guint32 n_values,\n'
+ ' gboolean refs)\n'
+ '{\n'
+ ' _mbim_struct_builder_append_${name_underscore}_struct_array (builder->contents_builder, values, n_values, refs);\n'
+ '}\n')
+ cfile.write(string.Template(template).substitute(translations))
+
+
+ """
Emit the struct handling implementation
"""
def emit(self, hfile, cfile):
@@ -254,3 +492,5 @@ class Struct:
self._emit_free(hfile, cfile)
# Emit type's read
self._emit_read(cfile)
+ # Emit type's append
+ self._emit_append(cfile)
diff --git a/build-aux/mbim-codegen/Value.py b/build-aux/mbim-codegen/Value.py
deleted file mode 100644
index 389a9ba..0000000
--- a/build-aux/mbim-codegen/Value.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil -*-
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# 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 <aleksander@gnu.org>
-#
-
-"""
-The Value class takes care of all kind of variables
-"""
-class Value:
-
- """
- Constructor
- """
- def __init__(self, dictionary):
-
- self.dictionary = dictionary
-
- """ The name of the variable """
- self.name = dictionary['name']
-
- """ The type of the variable """
- self.format = dictionary['format']
-
- """ Whether this field is visible or not """
- self.visible = False if 'visibility' in dictionary and dictionary['visibility'] == 'private' else True
-
- """ The public format of the value """
- self.public_format = ''
-
- """ Type of the value when used as input parameter """
- self.in_format = ''
- self.in_description = ''
-
- """ Type of the value when used as output parameter """
- self.out_format = ''
- self.out_description = ''
-
- """ Flag to identify this value as being used as an array size """
- self.is_array_size = False
-
- """ The name of the method used to read the value """
- self.reader_method_name = ''
-
- """ The size of this variable """
- self.size = 0
- self.size_string = ''
-
- """ Whether this value is an array """
- self.is_array = False
-
- """ The size of a member of the array """
- self.array_member_size = 0
-
- """ The field giving the size of the array """
- self.array_size_field = ''
diff --git a/build-aux/mbim-codegen/ValueString.py b/build-aux/mbim-codegen/ValueString.py
deleted file mode 100644
index b1578a5..0000000
--- a/build-aux/mbim-codegen/ValueString.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil -*-
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# 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 <aleksander@gnu.org>
-#
-
-from Value import Value
-
-"""
-The ValueString class takes care of STRING variables
-"""
-class ValueString(Value):
-
- """
- Constructor
- """
- def __init__(self, dictionary):
-
- # Call the parent constructor
- Value.__init__(self, dictionary)
-
- """ The public format of the value """
- self.public_format = 'gchar *'
-
- """ Type of the value when used as input parameter """
- self.in_format = 'const gchar *'
- self.in_description = 'The \'' + self.name + '\' field, given as a constant string.'
-
- """ Type of the value when used as output parameter """
- self.out_format = 'gchar **'
- self.out_description = 'Return location for a newly allocated string, or %NULL if the \'' + self.name + '\' field is not needed. Free the returned value with g_free().'
-
- """ The name of the method used to read the value """
- self.reader_method_name = '_mbim_message_read_string'
-
- """ The size of this variable """
- self.size = 8
- self.size_string = ''
-
- """ Whether this value is an array """
- self.is_array = False
diff --git a/build-aux/mbim-codegen/ValueStringArray.py b/build-aux/mbim-codegen/ValueStringArray.py
deleted file mode 100644
index d6650a8..0000000
--- a/build-aux/mbim-codegen/ValueStringArray.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil -*-
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# 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 <aleksander@gnu.org>
-#
-
-from Value import Value
-
-"""
-The ValueStringArray class takes care of string array variables
-"""
-class ValueStringArray(Value):
-
- """
- Constructor
- """
- def __init__(self, dictionary):
-
- # Call the parent constructor
- Value.__init__(self, dictionary)
-
- """ The type of the variable """
- self.type = 'string_array'
-
- """ The public format of the value """
- self.public_format = 'gchar **'
-
- """ Type of the value when used as input parameter """
- self.in_format = 'const gchar *const *'
- self.in_description = 'The \'' + self.name + '\' field, given as an array of strings.'
-
- """ Type of the value when used as output parameter """
- self.out_format = 'gchar ***'
- self.out_description = 'Return location for a newly allocated array of strings, or %NULL if the \'' + self.name + '\' field is not needed. Free the returned value with g_strfreev().'
-
- """ The name of the method used to read the value """
- self.reader_method_name = '_mbim_message_read_string_array'
-
- """ Whether this value is an array """
- self.is_array = True
-
- """ The size of a member of the array """
- self.array_member_size = 8
-
- """ The field giving the size of the array """
- self.array_size_field = dictionary['array-size-field']
diff --git a/build-aux/mbim-codegen/ValueStruct.py b/build-aux/mbim-codegen/ValueStruct.py
deleted file mode 100644
index 55e081c..0000000
--- a/build-aux/mbim-codegen/ValueStruct.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil -*-
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# 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 <aleksander@gnu.org>
-#
-
-import utils
-from Value import Value
-
-"""
-The ValueStruct class takes care of STRUCT variables
-"""
-class ValueStruct(Value):
-
- """
- Constructor
- """
- def __init__(self, dictionary):
-
- # Call the parent constructor
- Value.__init__(self, dictionary)
-
- """ The struct type """
- self.struct_type = dictionary['struct-type']
- self.struct_type_underscore = utils.build_underscore_name_from_camelcase (self.struct_type)
-
- """ The public format of the value """
- self.public_format = self.struct_type
-
- """ Type of the value when used as input parameter """
- self.in_format = 'const ' + self.struct_type + ' *'
- self.in_description = 'The \'' + self.name + '\' field, given as a #' + self.struct_type + '.'
-
- """ Type of the value when used as output parameter """
- self.out_format = self.struct_type + ' **'
- self.out_description = 'Return location for a newly allocated #' + self.struct_type + ', or %NULL if the \'' + self.name + '\' field is not needed. Free the returned value with ' + self.struct_type_underscore + '_free().'
-
- """ The name of the method used to read the value """
- self.reader_method_name = '_mbim_message_read_' + self.struct_type_underscore + '_struct'
-
- """ The size of this variable """
- self.size = 0
- self.size_string = '(_' + self.struct_type_underscore + '_size (message, offset))'
-
- """ Whether this value is an array """
- self.is_array = False
diff --git a/build-aux/mbim-codegen/ValueStructArray.py b/build-aux/mbim-codegen/ValueStructArray.py
deleted file mode 100644
index 2ff19be..0000000
--- a/build-aux/mbim-codegen/ValueStructArray.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil -*-
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# 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 <aleksander@gnu.org>
-#
-
-import utils
-
-from Value import Value
-
-"""
-The ValueStructArray class takes care of struct array variables
-"""
-class ValueStructArray(Value):
-
- """
- Constructor
- """
- def __init__(self, dictionary):
-
- # Call the parent constructor
- Value.__init__(self, dictionary)
-
- """ The struct type """
- self.struct_type = dictionary['struct-type']
- self.struct_type_underscore = utils.build_underscore_name_from_camelcase (self.struct_type)
-
- """ The public format of the value """
- self.public_format = self.struct_type + ' **'
-
- """ Type of the value when used as input parameter """
- self.in_format = 'const ' + self.struct_type + ' * const *'
- self.in_description = 'The \'' + self.name + '\' field, given as an array of #' + self.struct_type + 's.'
-
- """ Type of the value when used as output parameter """
- self.out_format = self.struct_type + ' ***'
- self.out_description = 'Return location for a newly allocated array of #' + self.struct_type + 's, or %NULL if the \'' + self.name + '\' field is not needed. Free the returned value with ' + self.struct_type_underscore + '_free_array().'
-
- """ The name of the method used to read the value """
- self.reader_method_name = '_' + self.struct_type_underscore + '_read_array'
-
- """ Whether this value is an array """
- self.is_array = True
-
- """ The size of a member of the array """
- self.array_member_size = 8
-
- """ The field giving the size of the array """
- self.array_size_field = dictionary['array-size-field']
diff --git a/build-aux/mbim-codegen/ValueUint32.py b/build-aux/mbim-codegen/ValueUint32.py
deleted file mode 100644
index cabb29d..0000000
--- a/build-aux/mbim-codegen/ValueUint32.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil -*-
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# 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 <aleksander@gnu.org>
-#
-
-from Value import Value
-
-"""
-The ValueUint32 class takes care of UINT32 variables
-"""
-class ValueUint32(Value):
-
- """
- Constructor
- """
- def __init__(self, dictionary):
-
- # Call the parent constructor
- Value.__init__(self, dictionary)
-
- """ The public format of the value """
- self.public_format = dictionary['public-format'] if 'public-format' in dictionary else 'guint32'
-
- """ Type of the value when used as input parameter """
- self.in_format = self.public_format + ' '
- self.in_description = 'The \'' + self.name + '\' field, given as a #' + self.public_format + '.'
-
- """ Type of the value when used as output parameter """
- self.out_format = self.public_format + ' *'
- self.out_description = 'Return location for a #' + self.public_format + ', or %NULL if the \'' + self.name + '\' field is not needed.'
-
- """ The name of the method used to read the value """
- self.reader_method_name = '_mbim_message_read_guint32'
-
- """ The size of this variable """
- self.size = 4
- self.size_string = ''
-
- """ Whether this value is an array """
- self.is_array = False
diff --git a/build-aux/mbim-codegen/ValueUint32Array.py b/build-aux/mbim-codegen/ValueUint32Array.py
deleted file mode 100644
index 615ba62..0000000
--- a/build-aux/mbim-codegen/ValueUint32Array.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil -*-
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# 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 <aleksander@gnu.org>
-#
-
-from Value import Value
-
-"""
-The ValueUint32Array class takes care of uint32 array variables
-"""
-class ValueUint32Array(Value):
-
- """
- Constructor
- """
- def __init__(self, dictionary):
-
- # Call the parent constructor
- Value.__init__(self, dictionary)
-
- """ The public format of the value """
- self.public_format = dictionary['public-format'] if 'public-format' in dictionary else 'guint32'
-
- """ Type of the value when used as input parameter """
- self.in_format = 'const ' + self.public_format + ' *'
- self.in_description = 'The \'' + self.name + '\' field, given as an array of #' + self.public_format + 's.'
-
- """ Type of the value when used as output parameter """
- self.out_format = self.public_format + ' **'
- self.out_description = 'Return location for a newly allocated array of #' + self.public_format + 's, or %NULL if the \'' + self.name + '\' field is not needed. Free the returned value with g_free().'
-
- """ The name of the method used to read the value """
- self.reader_method_name = '_mbim_message_read_guint32_array'
-
- """ Whether this value is an array """
- self.is_array = True
-
- """ The size of a member of the array """
- self.array_member_size = 0
-
- """ The field giving the size of the array """
- self.array_size_field = dictionary['array-size-field']
diff --git a/build-aux/mbim-codegen/ValueUint64.py b/build-aux/mbim-codegen/ValueUint64.py
deleted file mode 100644
index 989c003..0000000
--- a/build-aux/mbim-codegen/ValueUint64.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil -*-
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# 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 <aleksander@gnu.org>
-#
-
-from Value import Value
-
-"""
-The ValueUint64 class takes care of UINT64 variables
-"""
-class ValueUint64(Value):
-
- """
- Constructor
- """
- def __init__(self, dictionary):
-
- # Call the parent constructor
- Value.__init__(self, dictionary)
-
- """ The public format of the value """
- self.public_format = dictionary['public-format'] if 'public-format' in dictionary else 'guint64'
-
- """ Type of the value when used as input parameter """
- self.in_format = self.public_format + ' '
- self.in_description = 'The \'' + self.name + '\' field, given as a #' + self.public_format + '.'
-
- """ Type of the value when used as output parameter """
- self.out_format = self.public_format + ' *'
- self.out_description = 'Return location for a #' + self.public_format + ', or %NULL if the \'' + self.name + '\' field is not needed.'
-
- """ The name of the method used to read the value """
- self.reader_method_name = '_mbim_message_read_guint64'
-
- """ The size of this variable """
- self.size = 4
- self.size_string = ''
-
- """ Whether this value is an array """
- self.is_array = False
diff --git a/build-aux/mbim-codegen/ValueUuid.py b/build-aux/mbim-codegen/ValueUuid.py
deleted file mode 100644
index 92e4e9e..0000000
--- a/build-aux/mbim-codegen/ValueUuid.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil -*-
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# 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 <aleksander@gnu.org>
-#
-
-from Value import Value
-
-"""
-The ValueUuid class takes care of UUID variables
-"""
-class ValueUuid(Value):
-
- """
- Constructor
- """
- def __init__(self, dictionary):
-
- # Call the parent constructor
- Value.__init__(self, dictionary)
-
- """ The public format of the value """
- self.public_format = 'MbimUuid'
-
- """ Type of the value when used as input parameter """
- self.in_format = 'const MbimUuid *'
- self.in_description = 'The \'' + self.name + '\' field, given as a #MbimUuid.'
-
- """ Type of the value when used as output parameter """
- self.out_format = 'const MbimUuid **'
- self.out_description = 'Return location for a #MbimUuid, or %NULL if the \'' + self.name + '\' field is not needed. Do not free the returned value.'
-
- """ The name of the method used to read the value """
- self.reader_method_name = '_mbim_message_read_uuid'
-
- """ The size of this variable """
- self.size = 16
- self.size_string = ''
-
- """ Whether this value is an array """
- self.is_array = False
diff --git a/data/mbim-service-basic-connect.json b/data/mbim-service-basic-connect.json
index b58b1fa..eb5a8b4 100644
--- a/data/mbim-service-basic-connect.json
+++ b/data/mbim-service-basic-connect.json
@@ -401,17 +401,150 @@
"response" : [ { "name" : "ProvisionedContextsCount",
"format" : "guint32" },
{ "name" : "ProvisionedContexts",
- "format" : "struct-array",
+ "format" : "ref-struct-array",
"struct-type" : "MbimProvisionedContextElement",
"array-size-field" : "ProvisionedContextsCount" } ],
"notification" : [ { "name" : "ProvisionedContextsCount",
"format" : "guint32" },
{ "name" : "ProvisionedContexts",
- "format" : "struct-array",
+ "format" : "ref-struct-array",
"struct-type" : "MbimProvisionedContextElement",
"array-size-field" : "ProvisionedContextsCount" } ] },
// *********************************************************************************
+ { "name" : "MbimIPv4Element",
+ "type" : "Struct",
+ "contents" : [ { "name" : "OnLinkPrefixLength",
+ "format" : "guint32" },
+ { "name" : "IPv4Address",
+ "format" : "ipv4" } ] },
+
+ { "name" : "MbimIPv6Element",
+ "type" : "Struct",
+ "contents" : [ { "name" : "OnLinkPrefixLength",
+ "format" : "guint32" },
+ { "name" : "IPv6Address",
+ "format" : "ipv6" } ] },
+
+ { "name" : "IP Configuration",
+ "service" : "Basic Connect",
+ "type" : "Command",
+ "query" : [ { "name" : "SessionId",
+ "format" : "guint32" },
+ { "name" : "IPv4ConfigurationAvailable",
+ "format" : "guint32",
+ "public-format" : "MbimIPConfigurationAvailableFlag" },
+ { "name" : "IPv6ConfigurationAvailable",
+ "format" : "guint32",
+ "public-format" : "MbimIPConfigurationAvailableFlag" },
+ { "name" : "IPv4AddressCount",
+ "format" : "guint32" },
+ { "name" : "IPv4Address",
+ "format" : "struct-array",
+ "struct-type" : "MbimIPv4Element",
+ "array-size-field" : "IPv4AddressCount" },
+ { "name" : "IPv6AddressCount",
+ "format" : "guint32" },
+ { "name" : "IPv6Address",
+ "format" : "struct-array",
+ "struct-type" : "MbimIPv6Element",
+ "array-size-field" : "IPv6AddressCount" },
+ { "name" : "IPv4Gateway",
+ "format" : "ref-ipv4" },
+ { "name" : "IPv6Gateway",
+ "format" : "ref-ipv6" },
+ { "name" : "IPv4DnsServerCount",
+ "format" : "guint32" },
+ { "name" : "IPv4DnsServer",
+ "format" : "ipv4-array",
+ "array-size-field" : "IPv4DnsServerCount" },
+ { "name" : "IPv6DnsServerCount",
+ "format" : "guint32" },
+ { "name" : "IPv6DnsServer",
+ "format" : "ipv6-array",
+ "array-size-field" : "IPv6DnsServerCount" },
+ { "name" : "IPv4Mtu",
+ "format" : "guint32" },
+ { "name" : "IPv6Mtu",
+ "format" : "guint32" } ],
+ "response" : [ { "name" : "SessionId",
+ "format" : "guint32" },
+ { "name" : "IPv4ConfigurationAvailable",
+ "format" : "guint32",
+ "public-format" : "MbimIPConfigurationAvailableFlag" },
+ { "name" : "IPv6ConfigurationAvailable",
+ "format" : "guint32",
+ "public-format" : "MbimIPConfigurationAvailableFlag" },
+ { "name" : "IPv4AddressCount",
+ "format" : "guint32" },
+ { "name" : "IPv4Address",
+ "format" : "struct-array",
+ "struct-type" : "MbimIPv4Element",
+ "array-size-field" : "IPv4AddressCount" },
+ { "name" : "IPv6AddressCount",
+ "format" : "guint32" },
+ { "name" : "IPv6Address",
+ "format" : "struct-array",
+ "struct-type" : "MbimIPv6Element",
+ "array-size-field" : "IPv6AddressCount" },
+ { "name" : "IPv4Gateway",
+ "format" : "ref-ipv4" },
+ { "name" : "IPv6Gateway",
+ "format" : "ref-ipv6" },
+ { "name" : "IPv4DnsServerCount",
+ "format" : "guint32" },
+ { "name" : "IPv4DnsServer",
+ "format" : "ipv4-array",
+ "array-size-field" : "IPv4DnsServerCount" },
+ { "name" : "IPv6DnsServerCount",
+ "format" : "guint32" },
+ { "name" : "IPv6DnsServer",
+ "format" : "ipv6-array",
+ "array-size-field" : "IPv6DnsServerCount" },
+ { "name" : "IPv4Mtu",
+ "format" : "guint32" },
+ { "name" : "IPv6Mtu",
+ "format" : "guint32" } ],
+ "notification" : [ { "name" : "SessionId",
+ "format" : "guint32" },
+ { "name" : "IPv4ConfigurationAvailable",
+ "format" : "guint32",
+ "public-format" : "MbimIPConfigurationAvailableFlag" },
+ { "name" : "IPv6ConfigurationAvailable",
+ "format" : "guint32",
+ "public-format" : "MbimIPConfigurationAvailableFlag" },
+ { "name" : "IPv4AddressCount",
+ "format" : "guint32" },
+ { "name" : "IPv4Address",
+ "format" : "struct-array",
+ "struct-type" : "MbimIPv4Element",
+ "array-size-field" : "IPv4AddressCount" },
+ { "name" : "IPv6AddressCount",
+ "format" : "guint32" },
+ { "name" : "IPv6Address",
+ "format" : "struct-array",
+ "struct-type" : "MbimIPv6Element",
+ "array-size-field" : "IPv6AddressCount" },
+ { "name" : "IPv4Gateway",
+ "format" : "ref-ipv4" },
+ { "name" : "IPv6Gateway",
+ "format" : "ref-ipv6" },
+ { "name" : "IPv4DnsServerCount",
+ "format" : "guint32" },
+ { "name" : "IPv4DnsServer",
+ "format" : "ipv4-array",
+ "array-size-field" : "IPv4DnsServerCount" },
+ { "name" : "IPv6DnsServerCount",
+ "format" : "guint32" },
+ { "name" : "IPv6DnsServer",
+ "format" : "ipv6-array",
+ "array-size-field" : "IPv6DnsServerCount" },
+ { "name" : "IPv4Mtu",
+ "format" : "guint32" },
+ { "name" : "IPv6Mtu",
+ "format" : "guint32" } ] },
+
+ // *********************************************************************************
{ "name" : "MbimDeviceServiceElement",
"type" : "Struct",
"contents" : [ { "name" : "DeviceServiceId",
@@ -435,7 +568,7 @@
{ "name" : "MaxDssSessions",
"format" : "guint32" },
{ "name" : "DeviceServices",
- "format" : "struct-array",
+ "format" : "ref-struct-array",
"struct-type" : "MbimDeviceServiceElement",
"array-size-field" : "DeviceServicesCount" } ] }
]
diff --git a/libmbim-glib/mbim-enums.h b/libmbim-glib/mbim-enums.h
index 8a3b69c..bfe4c65 100644
--- a/libmbim-glib/mbim-enums.h
+++ b/libmbim-glib/mbim-enums.h
@@ -534,6 +534,27 @@ typedef enum {
MBIM_VOICE_CALL_STATE_HANG_UP = 2
} MbimVoiceCallState;
+/*****************************************************************************/
+/* 'IP Configuration' enums */
+
+/**
+ * MbimIPConfigurationAvailableFlag:
+ * @MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_NONE: No info available.
+ * @MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS: Address info available.
+ * @MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_GATEWAY: Gateway info available.
+ * @MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS: DNS info available.
+ * @MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU: MTU info available.
+ *
+ * Mask of available information about an IP address.
+ */
+typedef enum { /*< underscore_name=mbim_ip_configuration_available_flag >*/
+ MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_NONE = 0,
+ MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS = 1 << 0,
+ MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_GATEWAY = 1 << 1,
+ MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS = 1 << 2,
+ MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU = 1 << 3,
+} MbimIPConfigurationAvailableFlag;
+
G_END_DECLS
#endif /* _LIBMBIM_GLIB_MBIM_ENUMS_H_ */
diff --git a/libmbim-glib/mbim-message.c b/libmbim-glib/mbim-message.c
index f7db79f..7a60da3 100644
--- a/libmbim-glib/mbim-message.c
+++ b/libmbim-glib/mbim-message.c
@@ -133,6 +133,9 @@ _mbim_message_read_guint32_array (const MbimMessage *self,
guint32 *out;
guint32 information_buffer_offset;
+ if (!array_size)
+ return NULL;
+
information_buffer_offset = _mbim_message_get_information_buffer_offset (self);
out = g_new (guint32, array_size + 1);
@@ -213,6 +216,9 @@ _mbim_message_read_string_array (const MbimMessage *self,
guint32 i;
guint32 information_buffer_offset;
+ if (!array_size)
+ return NULL;
+
information_buffer_offset = _mbim_message_get_information_buffer_offset (self);
array = g_new (gchar *, array_size + 1);
@@ -258,6 +264,113 @@ _mbim_message_read_uuid (const MbimMessage *self,
(information_buffer_offset + relative_offset));
}
+const MbimIPv4 *
+_mbim_message_read_ipv4 (const MbimMessage *self,
+ guint32 relative_offset,
+ gboolean ref)
+{
+ guint32 information_buffer_offset;
+ guint32 offset;
+
+ information_buffer_offset = _mbim_message_get_information_buffer_offset (self);
+
+ if (ref) {
+ offset = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32,
+ self->data,
+ (information_buffer_offset + relative_offset)));
+ if (!offset)
+ return NULL;
+ } else
+ offset = relative_offset;
+
+ return (const MbimIPv4 *) G_STRUCT_MEMBER_P (self->data,
+ (information_buffer_offset + offset));
+}
+
+MbimIPv4 *
+_mbim_message_read_ipv4_array (const MbimMessage *self,
+ guint32 array_size,
+ guint32 relative_offset_array_start)
+{
+ MbimIPv4 *array;
+ guint32 offset;
+ guint32 i;
+ guint32 information_buffer_offset;
+
+ if (!array_size)
+ return NULL;
+
+ information_buffer_offset = _mbim_message_get_information_buffer_offset (self);
+
+ array = g_new (MbimIPv4, array_size);
+ offset = GUINT32_FROM_LE (G_STRUCT_MEMBER (
+ guint32,
+ self->data,
+ (information_buffer_offset + relative_offset_array_start)));
+
+ for (i = 0; i < array_size; i++, offset += 4) {
+ memcpy (&array[i],
+ G_STRUCT_MEMBER_P (self->data,
+ (information_buffer_offset + offset)),
+ 4);
+ }
+
+ return array;
+}
+
+const MbimIPv6 *
+_mbim_message_read_ipv6 (const MbimMessage *self,
+ guint32 relative_offset,
+ gboolean ref)
+{
+ guint32 information_buffer_offset;
+ guint32 offset;
+
+ information_buffer_offset = _mbim_message_get_information_buffer_offset (self);
+
+ if (ref) {
+ offset = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32,
+ self->data,
+ (information_buffer_offset + relative_offset)));
+ if (!offset)
+ return NULL;
+ } else
+ offset = relative_offset;
+
+ return (const MbimIPv6 *) G_STRUCT_MEMBER_P (self->data,
+ (information_buffer_offset + offset));
+}
+
+MbimIPv6 *
+_mbim_message_read_ipv6_array (const MbimMessage *self,
+ guint32 array_size,
+ guint32 relative_offset_array_start)
+{
+ MbimIPv6 *array;
+ guint32 offset;
+ guint32 i;
+ guint32 information_buffer_offset;
+
+ if (!array_size)
+ return NULL;
+
+ information_buffer_offset = _mbim_message_get_information_buffer_offset (self);
+
+ array = g_new (MbimIPv6, array_size);
+ offset = GUINT32_FROM_LE (G_STRUCT_MEMBER (
+ guint32,
+ self->data,
+ (information_buffer_offset + relative_offset_array_start)));
+ for (i = 0; i < array_size; i++, offset += 16) {
+ memcpy (&array[i],
+ G_STRUCT_MEMBER_P (self->data,
+ (information_buffer_offset + offset)),
+ 16);
+ }
+
+ return array;
+}
+
/*****************************************************************************/
/* Struct builder interface
*
@@ -265,12 +378,6 @@ _mbim_message_read_uuid (const MbimMessage *self,
* data buffer. Items of variable size are usually given as an offset (with
* respect to the start of the struct) plus a size field. */
-struct _MbimStructBuilder {
- GByteArray *fixed_buffer;
- GByteArray *variable_buffer;
- GArray *offsets;
-};
-
MbimStructBuilder *
_mbim_struct_builder_new (void)
{
@@ -320,8 +427,18 @@ void
_mbim_struct_builder_append_uuid (MbimStructBuilder *builder,
const MbimUuid *value)
{
+ static const MbimUuid uuid_invalid = {
+ .a = { 0x00, 0x00, 0x00, 0x00 },
+ .b = { 0x00, 0x00 },
+ .c = { 0x00, 0x00 },
+ .d = { 0x00, 0x00 },
+ .e = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+ };
+
/* uuids are added in the static buffer only */
- g_byte_array_append (builder->fixed_buffer, (guint8 *)value, sizeof (MbimUuid));
+ g_byte_array_append (builder->fixed_buffer,
+ value ? (guint8 *)value : (guint8 *)&uuid_invalid,
+ sizeof (MbimUuid));
}
void
@@ -336,6 +453,15 @@ _mbim_struct_builder_append_guint32 (MbimStructBuilder *builder,
}
void
+_mbim_struct_builder_append_guint32_array (MbimStructBuilder *builder,
+ const guint32 *values,
+ guint32 n_values)
+{
+ /* TODO */
+ g_assert_not_reached ();
+}
+
+void
_mbim_struct_builder_append_guint64 (MbimStructBuilder *builder,
guint64 value)
{
@@ -347,6 +473,15 @@ _mbim_struct_builder_append_guint64 (MbimStructBuilder *builder,
}
void
+_mbim_struct_builder_append_guint64_array (MbimStructBuilder *builder,
+ const guint64 *values,
+ guint32 n_values)
+{
+ /* TODO */
+ g_assert_not_reached ();
+}
+
+void
_mbim_struct_builder_append_string (MbimStructBuilder *builder,
const gchar *value)
{
@@ -405,21 +540,99 @@ _mbim_struct_builder_append_string (MbimStructBuilder *builder,
}
void
-_mbim_struct_builder_append_struct (MbimStructBuilder *builder,
- const GByteArray *value)
+_mbim_struct_builder_append_string_array (MbimStructBuilder *builder,
+ const gchar *const *values,
+ guint32 n_values)
+{
+ /* TODO */
+ g_assert_not_reached ();
+}
+
+void
+_mbim_struct_builder_append_ipv4 (MbimStructBuilder *builder,
+ const MbimIPv4 *value,
+ gboolean ref)
+{
+ if (ref)
+ _mbim_struct_builder_append_ipv4_array (builder, value, value ? 1 : 0);
+ else
+ g_byte_array_append (builder->fixed_buffer, (guint8 *)value, sizeof (MbimIPv4));
+}
+
+void
+_mbim_struct_builder_append_ipv4_array (MbimStructBuilder *builder,
+ const MbimIPv4 *values,
+ guint32 n_values)
{
- /* structs are added in the static buffer only */
- g_byte_array_append (builder->fixed_buffer, value->data, value->len);
+ guint32 offset;
+
+ if (!n_values) {
+ offset = 0;
+ g_byte_array_append (builder->fixed_buffer, (guint8 *)&offset, sizeof (offset));
+ } else {
+ guint32 offset_offset;
+
+ /* 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);
+
+ /* NOTE: length of the array must be given in a separate variable */
+
+ /* And finally, the array of IPs itself to the variable buffer */
+ g_byte_array_append (builder->variable_buffer, (guint8 *)values, n_values * sizeof (MbimIPv4));
+ }
+}
+
+void
+_mbim_struct_builder_append_ipv6 (MbimStructBuilder *builder,
+ const MbimIPv6 *value,
+ gboolean ref)
+{
+ if (ref)
+ _mbim_struct_builder_append_ipv6_array (builder, value, value ? 1 : 0);
+ else
+ g_byte_array_append (builder->fixed_buffer, (guint8 *)value, sizeof (MbimIPv6));
+}
+
+void
+_mbim_struct_builder_append_ipv6_array (MbimStructBuilder *builder,
+ const MbimIPv6 *values,
+ guint32 n_values)
+{
+ guint32 offset;
+
+ if (!n_values) {
+ offset = 0;
+ g_byte_array_append (builder->fixed_buffer, (guint8 *)&offset, sizeof (offset));
+ } else {
+ guint32 offset_offset;
+
+ /* 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);
+
+ /* NOTE: length of the array must be given in a separate variable */
+
+ /* And finally, the array of IPs itself to the variable buffer */
+ g_byte_array_append (builder->variable_buffer, (guint8 *)values, n_values * sizeof (MbimIPv6));
+ }
}
/*****************************************************************************/
/* Command message builder interface */
-struct _MbimMessageCommandBuilder {
- MbimMessage *message;
- MbimStructBuilder *contents_builder;
-};
-
MbimMessageCommandBuilder *
_mbim_message_command_builder_new (guint32 transaction_id,
MbimService service,
@@ -473,6 +686,14 @@ _mbim_message_command_builder_append_guint32 (MbimMessageCommandBuilder *builder
}
void
+_mbim_message_command_builder_append_guint32_array (MbimMessageCommandBuilder *builder,
+ const guint32 *values,
+ guint32 n_values)
+{
+ _mbim_struct_builder_append_guint32_array (builder->contents_builder, values, n_values);
+}
+
+void
_mbim_message_command_builder_append_guint64 (MbimMessageCommandBuilder *builder,
guint64 value)
{
@@ -480,6 +701,14 @@ _mbim_message_command_builder_append_guint64 (MbimMessageCommandBuilder *builder
}
void
+_mbim_message_command_builder_append_guint64_array (MbimMessageCommandBuilder *builder,
+ const guint64 *values,
+ guint32 n_values)
+{
+ _mbim_struct_builder_append_guint64_array (builder->contents_builder, values, n_values);
+}
+
+void
_mbim_message_command_builder_append_string (MbimMessageCommandBuilder *builder,
const gchar *value)
{
@@ -487,10 +716,43 @@ _mbim_message_command_builder_append_string (MbimMessageCommandBuilder *builder,
}
void
-_mbim_message_command_builder_append_struct (MbimMessageCommandBuilder *builder,
- const GByteArray *value)
+_mbim_message_command_builder_append_string_array (MbimMessageCommandBuilder *builder,
+ const gchar *const *values,
+ guint32 n_values)
+{
+ _mbim_struct_builder_append_string_array (builder->contents_builder, values, n_values);
+}
+
+void
+_mbim_message_command_builder_append_ipv4 (MbimMessageCommandBuilder *builder,
+ const MbimIPv4 *value,
+ gboolean ref)
+{
+ _mbim_struct_builder_append_ipv4 (builder->contents_builder, value, ref);
+}
+
+void
+_mbim_message_command_builder_append_ipv4_array (MbimMessageCommandBuilder *builder,
+ const MbimIPv4 *values,
+ guint32 n_values)
+{
+ _mbim_struct_builder_append_ipv4_array (builder->contents_builder, values, n_values);
+}
+
+void
+_mbim_message_command_builder_append_ipv6 (MbimMessageCommandBuilder *builder,
+ const MbimIPv6 *value,
+ gboolean ref)
+{
+ _mbim_struct_builder_append_ipv6 (builder->contents_builder, value, ref);
+}
+
+void
+_mbim_message_command_builder_append_ipv6_array (MbimMessageCommandBuilder *builder,
+ const MbimIPv6 *values,
+ guint32 n_values)
{
- _mbim_struct_builder_append_struct (builder->contents_builder, value);
+ _mbim_struct_builder_append_ipv6_array (builder->contents_builder, values, n_values);
}
/*****************************************************************************/
diff --git a/libmbim-glib/mbim-message.h b/libmbim-glib/mbim-message.h
index db44aa0..5e4f9b9 100644
--- a/libmbim-glib/mbim-message.h
+++ b/libmbim-glib/mbim-message.h
@@ -47,6 +47,26 @@ GType mbim_message_get_type (void) G_GNUC_CONST;
#define MBIM_TYPE_MESSAGE (mbim_message_get_type ())
/**
+ * MbimIPv4:
+ *
+ * An IPv4 address.
+ */
+typedef struct _MbimIPv4 MbimIPv4;
+struct _MbimIPv4 {
+ guint8 addr[4];
+};
+
+/**
+ * MbimIPv6:
+ *
+ * An IPv6 address.
+ */
+typedef struct _MbimIPv6 MbimIPv6;
+struct _MbimIPv6 {
+ guint8 addr[16];
+};
+
+/**
* MbimMessageType:
* @MBIM_MESSAGE_TYPE_INVALID: Invalid MBIM message.
* @MBIM_MESSAGE_TYPE_OPEN: Initialization request.
@@ -114,6 +134,18 @@ gchar **_mbim_message_read_string_array (const MbimMessage *self,
guint32 relative_offset_array_start);
const MbimUuid *_mbim_message_read_uuid (const MbimMessage *self,
guint32 relative_offset);
+const MbimIPv4 *_mbim_message_read_ipv4 (const MbimMessage *self,
+ guint32 relative_offset,
+ gboolean ref);
+MbimIPv4 *_mbim_message_read_ipv4_array (const MbimMessage *self,
+ guint32 array_size,
+ guint32 relative_offset_array_start);
+const MbimIPv6 *_mbim_message_read_ipv6 (const MbimMessage *self,
+ guint32 relative_offset,
+ gboolean ref);
+MbimIPv6 *_mbim_message_read_ipv6_array (const MbimMessage *self,
+ guint32 array_size,
+ guint32 relative_offset_array_start);
#endif
/*****************************************************************************/
@@ -183,48 +215,84 @@ const guint8 *mbim_message_command_get_raw_information_buffer (const M
guint32 *length);
#if defined (LIBMBIM_GLIB_COMPILATION)
-/**
- * MbimStruct:
- *
- * An opaque type representing a struct within a MBIM message command.
- */
-typedef struct _MbimStructBuilder MbimStructBuilder;
-
-MbimStructBuilder *_mbim_struct_builder_new (void);
-GByteArray *_mbim_struct_builder_complete (MbimStructBuilder *builder);
-void _mbim_struct_builder_append_uuid (MbimStructBuilder *builder,
- const MbimUuid *value);
-void _mbim_struct_builder_append_guint32 (MbimStructBuilder *builder,
- guint32 value);
-void _mbim_struct_builder_append_guint64 (MbimStructBuilder *builder,
- guint64 value);
-void _mbim_struct_builder_append_string (MbimStructBuilder *builder,
- const gchar *value);
-void _mbim_struct_builder_append_struct (MbimStructBuilder *builder,
- const GByteArray *value);
-/**
- * MbimMessageCommandBuilder:
- *
- * An opaque type representing a MBIM message command builder.
- */
-typedef struct _MbimMessageCommandBuilder MbimMessageCommandBuilder;
-
-MbimMessageCommandBuilder *_mbim_message_command_builder_new (guint32 transaction_id,
- MbimService service,
- guint32 cid,
- MbimMessageCommandType command_type);
-MbimMessage *_mbim_message_command_builder_complete (MbimMessageCommandBuilder *builder);
-void _mbim_message_command_builder_append_uuid (MbimMessageCommandBuilder *builder,
- const MbimUuid *value);
-void _mbim_message_command_builder_append_guint32 (MbimMessageCommandBuilder *builder,
- guint32 value);
-void _mbim_message_command_builder_append_guint64 (MbimMessageCommandBuilder *builder,
- guint64 value);
-void _mbim_message_command_builder_append_string (MbimMessageCommandBuilder *builder,
- const gchar *value);
-void _mbim_message_command_builder_append_struct (MbimMessageCommandBuilder *builder,
- const GByteArray *value);
+typedef struct {
+ GByteArray *fixed_buffer;
+ GByteArray *variable_buffer;
+ GArray *offsets;
+} MbimStructBuilder;
+
+MbimStructBuilder *_mbim_struct_builder_new (void);
+GByteArray *_mbim_struct_builder_complete (MbimStructBuilder *builder);
+void _mbim_struct_builder_append_uuid (MbimStructBuilder *builder,
+ const MbimUuid *value);
+void _mbim_struct_builder_append_guint32 (MbimStructBuilder *builder,
+ guint32 value);
+void _mbim_struct_builder_append_guint32_array (MbimStructBuilder *builder,
+ const guint32 *values,
+ guint32 n_values);
+void _mbim_struct_builder_append_guint64 (MbimStructBuilder *builder,
+ guint64 value);
+void _mbim_struct_builder_append_guint64_array (MbimStructBuilder *builder,
+ const guint64 *values,
+ guint32 n_values);
+void _mbim_struct_builder_append_string (MbimStructBuilder *builder,
+ const gchar *value);
+void _mbim_struct_builder_append_string_array (MbimStructBuilder *builder,
+ const gchar *const *values,
+ guint32 n_values);
+void _mbim_struct_builder_append_ipv4 (MbimStructBuilder *builder,
+ const MbimIPv4 *value,
+ gboolean ref);
+void _mbim_struct_builder_append_ipv4_array (MbimStructBuilder *builder,
+ const MbimIPv4 *values,
+ guint32 n_values);
+void _mbim_struct_builder_append_ipv6 (MbimStructBuilder *builder,
+ const MbimIPv6 *value,
+ gboolean ref);
+void _mbim_struct_builder_append_ipv6_array (MbimStructBuilder *builder,
+ const MbimIPv6 *values,
+ guint32 n_values);
+
+typedef struct {
+ MbimMessage *message;
+ MbimStructBuilder *contents_builder;
+} MbimMessageCommandBuilder;
+
+MbimMessageCommandBuilder *_mbim_message_command_builder_new (guint32 transaction_id,
+ MbimService service,
+ guint32 cid,
+ MbimMessageCommandType command_type);
+MbimMessage *_mbim_message_command_builder_complete (MbimMessageCommandBuilder *builder);
+void _mbim_message_command_builder_append_uuid (MbimMessageCommandBuilder *builder,
+ const MbimUuid *value);
+void _mbim_message_command_builder_append_guint32 (MbimMessageCommandBuilder *builder,
+ guint32 value);
+void _mbim_message_command_builder_append_guint32_array (MbimMessageCommandBuilder *builder,
+ const guint32 *values,
+ guint32 n_values);
+void _mbim_message_command_builder_append_guint64 (MbimMessageCommandBuilder *builder,
+ guint64 value);
+void _mbim_message_command_builder_append_guint64_array (MbimMessageCommandBuilder *builder,
+ const guint64 *values,
+ guint32 n_values);
+void _mbim_message_command_builder_append_string (MbimMessageCommandBuilder *builder,
+ const gchar *value);
+void _mbim_message_command_builder_append_string_array (MbimMessageCommandBuilder *builder,
+ const gchar *const *values,
+ guint32 n_values);
+void _mbim_message_command_builder_append_ipv4 (MbimMessageCommandBuilder *builder,
+ const MbimIPv4 *value,
+ gboolean ref);
+void _mbim_message_command_builder_append_ipv4_array (MbimMessageCommandBuilder *builder,
+ const MbimIPv4 *values,
+ guint32 n_values);
+void _mbim_message_command_builder_append_ipv6 (MbimMessageCommandBuilder *builder,
+ const MbimIPv6 *value,
+ gboolean ref);
+void _mbim_message_command_builder_append_ipv6_array (MbimMessageCommandBuilder *builder,
+ const MbimIPv6 *values,
+ guint32 n_values);
#endif
/*****************************************************************************/
diff --git a/libmbim-glib/test/test-message-contents.c b/libmbim-glib/test/test-message-contents.c
index cb847db..63df00e 100644
--- a/libmbim-glib/test/test-message-contents.c
+++ b/libmbim-glib/test/test-message-contents.c
@@ -135,11 +135,150 @@ test_message_contents_basic_connect_device_caps (void)
mbim_message_unref (response);
}
+static void
+test_message_contents_basic_connect_ip_configuration (void)
+{
+ MbimMessage *response;
+ guint32 session_id;
+ MbimIPConfigurationAvailableFlag ipv4configurationavailable;
+ MbimIPConfigurationAvailableFlag ipv6configurationavailable;
+ guint32 ipv4addresscount;
+ MbimIPv4Element **ipv4address;
+ guint32 ipv6addresscount;
+ MbimIPv6Element **ipv6address;
+ const MbimIPv4 *ipv4gateway;
+ const MbimIPv6 *ipv6gateway;
+ guint32 ipv4dnsservercount;
+ MbimIPv4 *ipv4dnsserver;
+ guint32 ipv6dnsservercount;
+ MbimIPv6 *ipv6dnsserver;
+ guint32 ipv4mtu;
+ guint32 ipv6mtu;
+ GError *error = NULL;
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0x80, 0x00, 0x00, 0x00, /* length */
+ 0x1A, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0xA2, 0x89, 0xCC, 0x33, /* service id */
+ 0xBC, 0xBB, 0x8B, 0x4F,
+ 0xB6, 0xB0, 0x13, 0x3E,
+ 0xC2, 0xAA, 0xE6, 0xDF,
+ 0x0F, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x50, 0x00, 0x00, 0x00, /* buffer length */
+ /* information buffer */
+ 0x00, 0x00, 0x00, 0x00, /* session id */
+ 0x0F, 0x00, 0x00, 0x00, /* IPv4ConfigurationAvailable */
+ 0x00, 0x00, 0x00, 0x00, /* IPv6ConfigurationAvailable */
+ 0x01, 0x00, 0x00, 0x00, /* IPv4 element count */
+ 0x3C, 0x00, 0x00, 0x00, /* IPv4 element offset */
+ 0x00, 0x00, 0x00, 0x00, /* IPv6 element count */
+ 0x00, 0x00, 0x00, 0x00, /* IPv6 element offset */
+ 0x44, 0x00, 0x00, 0x00, /* IPv4 gateway offset */
+ 0x00, 0x00, 0x00, 0x00, /* IPv6 gateway offset */
+ 0x02, 0x00, 0x00, 0x00, /* IPv4 DNS count */
+ 0x48, 0x00, 0x00, 0x00, /* IPv4 DNS offset */
+ 0x00, 0x00, 0x00, 0x00, /* IPv6 DNS count */
+ 0x00, 0x00, 0x00, 0x00, /* IPv6 DNS offset */
+ 0xDC, 0x05, 0x00, 0x00, /* IPv4 MTU */
+ 0x00, 0x00, 0x00, 0x00, /* IPv6 MTU */
+ /* data buffer */
+ 0x1C, 0x00, 0x00, 0x00, /* IPv4 element (netmask) */
+ 0xD4, 0x49, 0x22, 0xF8, /* IPv4 element (address) */
+ 0xD4, 0x49, 0x22, 0xF1, /* IPv4 gateway */
+ 0xD4, 0xA6, 0xD2, 0x50, /* IPv4 DNS1 */
+ 0xD4, 0x49, 0x20, 0x43 /* IPv4 DNS2 */
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+
+ g_assert (mbim_message_ip_configuration_response_parse (
+ response,
+ &session_id,
+ &ipv4configurationavailable,
+ &ipv6configurationavailable,
+ &ipv4addresscount,
+ &ipv4address,
+ &ipv6addresscount,
+ &ipv6address,
+ &ipv4gateway,
+ &ipv6gateway,
+ &ipv4dnsservercount,
+ &ipv4dnsserver,
+ &ipv6dnsservercount,
+ &ipv6dnsserver,
+ &ipv4mtu,
+ &ipv6mtu,
+ &error));
+
+ /*
+ * IPv4 configuration available: 'address, gateway, dns, mtu'
+ * IP addresses (1)
+ * IP [0]: '212.166.228.25/28'
+ * Gateway: '212.166.228.26'
+ * DNS addresses (2)
+ * DNS [0]: '212.166.210.80'
+ * DNS [1]: '212.73.32.67'
+ * MTU: '1500'
+ */
+
+ g_assert_cmpuint (session_id, ==, 0);
+ g_assert_cmpuint (ipv4configurationavailable, ==, (MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS |
+ MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_GATEWAY |
+ MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS |
+ MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU));
+ g_assert_cmpuint (ipv6configurationavailable, ==, MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_NONE);
+
+ {
+ MbimIPv4 addr = { .addr = { 0xD4, 0x49, 0x22, 0xF8 } };
+
+ g_assert_cmpuint (ipv4addresscount, ==, 1);
+ g_assert_cmpuint (ipv4address[0]->on_link_prefix_length, ==, 28);
+ g_assert (memcmp (&addr, &(ipv4address[0]->ipv4_address), 4) == 0);
+ }
+
+ {
+ MbimIPv4 gateway_addr = { .addr = { 0xD4, 0x49, 0x22, 0xF1 } };
+
+ g_assert (memcmp (&gateway_addr, ipv4gateway, 4) == 0);
+ }
+
+ {
+ MbimIPv4 dns_addr_1 = { .addr = { 0xD4, 0xA6, 0xD2, 0x50 } };
+ MbimIPv4 dns_addr_2 = { .addr = { 0xD4, 0x49, 0x20, 0x43 } };
+
+ g_assert_cmpuint (ipv4dnsservercount, ==, 2);
+ g_assert (memcmp (&dns_addr_1, &ipv4dnsserver[0], 4) == 0);
+ g_assert (memcmp (&dns_addr_2, &ipv4dnsserver[1], 4) == 0);
+ }
+
+ g_assert_cmpuint (ipv4mtu, ==, 1500);
+
+ g_assert_cmpuint (ipv6addresscount, ==, 0);
+ g_assert (ipv6address == NULL);
+ g_assert (ipv6gateway == NULL);
+ g_assert_cmpuint (ipv6dnsservercount, ==, 0);
+ g_assert (ipv6dnsserver == NULL);
+
+ mbim_ipv4_element_array_free (ipv4address);
+ mbim_ipv6_element_array_free (ipv6address);
+ g_free (ipv4dnsserver);
+ g_free (ipv6dnsserver);
+
+ mbim_message_unref (response);
+}
+
int main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/libmbim-glib/message-contents/basic-connect/device-caps", test_message_contents_basic_connect_device_caps);
+ g_test_add_func ("/libmbim-glib/message-contents/basic-connect/ip-configuration", test_message_contents_basic_connect_ip_configuration);
return g_test_run ();
}