Ejemplo n.º 1
0
    def __emit_get_printable(self, hfile, cfile):
        translations = { 'service'    : self.service.lower() }

        template = (
            '\n'
            '#if defined (LIBQMI_GLIB_COMPILATION)\n'
            '\n'
            'G_GNUC_INTERNAL\n'
            'gchar *__qmi_message_${service}_get_printable (\n'
            '    QmiMessage *self,\n'
            '    const gchar *line_prefix);\n'
            '\n'
            '#endif\n'
            '\n')
        hfile.write(string.Template(template).substitute(translations))

        template = (
            '\n'
            'gchar *\n'
            '__qmi_message_${service}_get_printable (\n'
            '    QmiMessage *self,\n'
            '    const gchar *line_prefix)\n'
            '{\n'
            '    if (qmi_message_is_indication (self)) {\n'
            '        switch (qmi_message_get_message_id (self)) {\n')

        for message in self.list:
            if message.type == 'Indication':
                translations['enum_name'] = message.id_enum_name
                translations['message_underscore'] = utils.build_underscore_name (message.name)
                translations['enum_value'] = message.id
                inner_template = (
                    '        case ${enum_name}:\n'
                    '            return indication_${message_underscore}_get_printable (self, line_prefix);\n')
                template += string.Template(inner_template).substitute(translations)

        template += (
            '         default:\n'
            '             return NULL;\n'
            '        }\n'
            '    } else {\n'
            '        switch (qmi_message_get_message_id (self)) {\n')

        for message in self.list:
            if message.type == 'Message':
                translations['enum_name'] = message.id_enum_name
                translations['message_underscore'] = utils.build_underscore_name (message.name)
                translations['enum_value'] = message.id
                inner_template = (
                    '        case ${enum_name}:\n'
                    '            return message_${message_underscore}_get_printable (self, line_prefix);\n')
                template += string.Template(inner_template).substitute(translations)

        template += (
            '         default:\n'
            '             return NULL;\n'
            '        }\n'
            '    }\n'
            '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 2
0
    def emit_getter(self, hfile, cfile):
        input_variable_name = utils.build_underscore_name(self.name)
        variable_getter_dec = self.variable.build_getter_declaration('    ', input_variable_name)
        variable_getter_doc = self.variable.build_getter_documentation(' * ', input_variable_name)
        variable_getter_imp = self.variable.build_getter_implementation('    ', 'self->' + self.variable_name, input_variable_name, True)
        translations = { 'name'                : self.name,
                         'variable_name'       : self.variable_name,
                         'variable_getter_dec' : variable_getter_dec,
                         'variable_getter_doc' : variable_getter_doc,
                         'variable_getter_imp' : variable_getter_imp,
                         'underscore'          : utils.build_underscore_name(self.name),
                         'prefix_camelcase'    : utils.build_camelcase_name(self.prefix),
                         'prefix_underscore'   : utils.build_underscore_name(self.prefix),
                         'static'              : 'static ' if self.static else '' }

        # Emit the getter header
        template = (
            '\n'
            '${static}gboolean ${prefix_underscore}_get_${underscore} (\n'
            '    ${prefix_camelcase} *self,\n'
            '${variable_getter_dec}'
            '    GError **error);\n')
        hfile.write(string.Template(template).substitute(translations))

        # Emit the getter source
        template = (
            '\n'
            '/**\n'
            ' * ${prefix_underscore}_get_${underscore}:\n'
            ' * @self: a #${prefix_camelcase}.\n'
            '${variable_getter_doc}'
            ' * @error: Return location for error or %NULL.\n'
            ' *\n'
            ' * Get the \'${name}\' field from @self.\n'
            ' *\n'
            ' * Returns: %TRUE if the field is found, %FALSE otherwise.\n'
            ' */\n'
            '${static}gboolean\n'
            '${prefix_underscore}_get_${underscore} (\n'
            '    ${prefix_camelcase} *self,\n'
            '${variable_getter_dec}'
            '    GError **error)\n'
            '{\n'
            '    g_return_val_if_fail (self != NULL, FALSE);\n'
            '\n'
            '    if (!self->${variable_name}_set) {\n'
            '        g_set_error (error,\n'
            '                     QMI_CORE_ERROR,\n'
            '                     QMI_CORE_ERROR_TLV_NOT_FOUND,\n'
            '                     "Field \'${name}\' was not found in the message");\n'
            '        return FALSE;\n'
            '    }\n'
            '\n'
            '${variable_getter_imp}'
            '\n'
            '    return TRUE;\n'
            '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 3
0
    def emit_output_tlv_get(self, f, line_prefix):
        tlv_out = utils.build_underscore_name (self.fullname) + '_out'
        error = 'error' if self.mandatory else 'NULL'
        translations = { 'name'                 : self.name,
                         'container_underscore' : utils.build_underscore_name (self.prefix),
                         'tlv_out'              : tlv_out,
                         'tlv_id'               : self.id_enum_name,
                         'variable_name'        : self.variable_name,
                         'lp'                   : line_prefix,
                         'error'                : error }

        template = (
            '${lp}gsize offset = 0;\n'
            '${lp}gsize init_offset;\n'
            '\n'
            '${lp}if ((init_offset = qmi_message_tlv_read_init (message, ${tlv_id}, NULL, ${error})) == 0) {\n')

        if self.mandatory:
            template += (
                '${lp}    g_prefix_error (${error}, "Couldn\'t get the mandatory ${name} TLV: ");\n'
                '${lp}    ${container_underscore}_unref (self);\n'
                '${lp}    return NULL;\n')
        else:
            template += (
                '${lp}    goto ${tlv_out};\n')

        template += (
            '${lp}}\n')

        f.write(string.Template(template).substitute(translations))

        # Now, read the contents of the buffer into the variable
        self.variable.emit_buffer_read(f, line_prefix, tlv_out, error, 'self->' + self.variable_name)

        template = (
            '\n'
            '${lp}/* The remaining size of the buffer needs to be 0 if we successfully read the TLV */\n'
            '${lp}if ((offset = __qmi_message_tlv_read_remaining_size (message, init_offset, offset)) > 0) {\n'
            '${lp}    g_warning ("Left \'%" G_GSIZE_FORMAT "\' bytes unread when getting the \'${name}\' TLV", offset);\n'
            '${lp}}\n'
            '\n'
            '${lp}self->${variable_name}_set = TRUE;\n'
            '\n'
            '${tlv_out}:\n')
        if self.mandatory:
            template += (
                '${lp}if (!self->${variable_name}_set) {\n'
                '${lp}    ${container_underscore}_unref (self);\n'
                '${lp}    return NULL;\n'
                '${lp}}\n')
        else:
            template += (
                '${lp};\n')
        f.write(string.Template(template).substitute(translations))
Ejemplo n.º 4
0
    def add_sections(self, sections):
        translations = { 'underscore'        : utils.build_underscore_name(self.name),
                         'prefix_camelcase'  : utils.build_camelcase_name(self.prefix),
                         'prefix_underscore' : utils.build_underscore_name(self.prefix) }

        # Public methods
        template = (
            '${prefix_underscore}_get_${underscore}\n')
        if self.container_type == 'Input':
            template += (
                '${prefix_underscore}_set_${underscore}\n')
        sections['public-methods'] += string.Template(template).substitute(translations)
Ejemplo n.º 5
0
    def emit_setter(self, hfile, cfile):
        input_variable_name = utils.build_underscore_name(self.name)
        variable_setter_dec = self.variable.build_setter_declaration('    ', input_variable_name)
        variable_setter_doc = self.variable.build_setter_documentation(' * ', input_variable_name)
        variable_setter_imp = self.variable.build_setter_implementation('    ', input_variable_name, 'self->' + self.variable_name)
        translations = { 'name'                : self.name,
                         'variable_name'       : self.variable_name,
                         'variable_setter_dec' : variable_setter_dec,
                         'variable_setter_doc' : variable_setter_doc,
                         'variable_setter_imp' : variable_setter_imp,
                         'underscore'          : utils.build_underscore_name(self.name),
                         'prefix_camelcase'    : utils.build_camelcase_name(self.prefix),
                         'prefix_underscore'   : utils.build_underscore_name(self.prefix),
                         'static'              : 'static ' if self.static else '' }

        # Emit the setter header
        template = (
            '\n'
            '${static}gboolean ${prefix_underscore}_set_${underscore} (\n'
            '    ${prefix_camelcase} *self,\n'
            '${variable_setter_dec}'
            '    GError **error);\n')
        hfile.write(string.Template(template).substitute(translations))

        # Emit the setter source
        template = (
            '\n'
            '/**\n'
            ' * ${prefix_underscore}_set_${underscore}:\n'
            ' * @self: a #${prefix_camelcase}.\n'
            '${variable_setter_doc}'
            ' * @error: Return location for error or %NULL.\n'
            ' *\n'
            ' * Set the \'${name}\' field in the message.\n'
            ' *\n'
            ' * Returns: %TRUE if @value was successfully set, %FALSE otherwise.\n'
            ' */\n'
            '${static}gboolean\n'
            '${prefix_underscore}_set_${underscore} (\n'
            '    ${prefix_camelcase} *self,\n'
            '${variable_setter_dec}'
            '    GError **error)\n'
            '{\n'
            '    g_return_val_if_fail (self != NULL, FALSE);\n'
            '\n'
            '${variable_setter_imp}'
            '    self->${variable_name}_set = TRUE;\n'
            '\n'
            '    return TRUE;\n'
            '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 6
0
    def emit_section_content(self, sfile):
        translations = { 'name_dashed' : utils.build_dashed_name(self.name),
                         'underscore'  : utils.build_underscore_name(self.fullname) }

        template = (
            '\n'
            '<SUBSECTION ${name_dashed}>\n')
        sfile.write(string.Template(template).substitute(translations))

        if self.has_query:
            template = (
                '${underscore}_query_new\n')
            sfile.write(string.Template(template).substitute(translations))

        if self.has_set:
            template = (
                '${underscore}_set_new\n')
            sfile.write(string.Template(template).substitute(translations))

        if self.has_response:
            template = (
                '${underscore}_response_parse\n')
            sfile.write(string.Template(template).substitute(translations))

        if self.has_notification:
            template = (
                '${underscore}_notification_parse\n')
            sfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 7
0
    def __init__(self, dictionary, struct_type_name, container_type):

        # Call the parent constructor
        Variable.__init__(self, dictionary)

        # The public format of the struct is built directly from the suggested
        # struct type name
        self.public_format = utils.build_camelcase_name(struct_type_name)
        self.private_format = self.public_format
        self.container_type = container_type

        # Load members of this struct
        self.members = []
        for member_dictionary in dictionary["contents"]:
            member = {}
            member["name"] = utils.build_underscore_name(member_dictionary["name"])
            member["object"] = VariableFactory.create_variable(
                member_dictionary, struct_type_name + " " + member["name"], self.container_type
            )
            self.members.append(member)

        # We'll need to dispose if at least one of the members needs it
        for member in self.members:
            if member["object"].needs_dispose == True:
                self.needs_dispose = True
Ejemplo n.º 8
0
 def clear_func_name(self):
     # element public format might be a base type like 'gchar *' rather
     # than a structure name like QmiFooBar
     elt_name = self.array_element.public_format.replace('*', 'pointer')
     return utils.build_underscore_name(self.name) + \
          '_' + \
          utils.build_underscore_name_from_camelcase(utils.build_camelcase_name(elt_name))
Ejemplo n.º 9
0
    def add_sections(self, sections):
        translations = { 'underscore'        : utils.build_underscore_name(self.name),
                         'prefix_camelcase'  : utils.build_camelcase_name(self.prefix),
                         'prefix_underscore' : utils.build_underscore_name(self.prefix) }

        if TypeFactory.is_section_emitted(self.fullname) is False:
            TypeFactory.set_section_emitted(self.fullname)
            self.variable.add_sections(sections)

        # Public methods
        template = (
            '${prefix_underscore}_get_${underscore}\n')
        if self.container_type == 'Input':
            template += (
                '${prefix_underscore}_set_${underscore}\n')
        sections['public-methods'] += string.Template(template).substitute(translations)
Ejemplo n.º 10
0
    def emit(self, hfile, cfile):
        translations = { 'name'       : self.name,
                         'camelcase'  : utils.build_camelcase_name (self.fullname),
                         'underscore' : utils.build_underscore_name (self.fullname),
                         'static'     : 'static ' if self.static else '' }

        auxfile = cfile if self.static else hfile

        if self.fields is None:
            template = ('\n'
                        '/* Note: no fields in the ${name} container */\n')
            auxfile.write(string.Template(template).substitute(translations))
            cfile.write(string.Template(template).substitute(translations))
            return

        # Emit the container and field  types
        # Emit field getter/setter
        if self.fields is not None:
            for field in self.fields:
                field.emit_types(auxfile, cfile)
        self.__emit_types(auxfile, cfile, translations)

        # Emit TLV enums
        self.__emit_tlv_ids_enum(cfile)

        # Emit fields
        if self.fields is not None:
            for field in self.fields:
                field.emit_getter(auxfile, cfile)
                if self.readonly == False:
                    field.emit_setter(auxfile, cfile)

        # Emit the container core
        self.__emit_core(auxfile, cfile, translations)
Ejemplo n.º 11
0
    def add_sections(self, sections):
        if self.fields is None:
            return

        translations = { 'name'       : self.name,
                         'camelcase'  : utils.build_camelcase_name (self.fullname),
                         'underscore' : utils.build_underscore_name (self.fullname),
                         'type_macro' : 'QMI_TYPE_' + utils.remove_prefix(utils.build_underscore_uppercase_name(self.fullname), 'QMI_') }

        # Standard
        template = (
            '${underscore}_get_type\n'
            '${type_macro}\n')
        sections['standard'] += string.Template(template).substitute(translations)

        # Public types
        template = (
            '${camelcase}\n')
        sections['public-types'] += string.Template(template).substitute(translations)

        # Public methods
        template = '<SUBSECTION ${camelcase}Methods>\n'
        if self.readonly == False:
            template += (
                '${underscore}_new\n')
        template += (
            '${underscore}_ref\n'
            '${underscore}_unref\n')
        sections['public-methods'] += string.Template(template).substitute(translations)

        for field in self.fields:
            field.add_sections(sections)
Ejemplo n.º 12
0
    def __init__(self, prefix, dictionary, common_objects_dictionary, container_type, static):
        # The field prefix, usually the name of the Container,
        #  e.g. "Qmi Message Ctl Something Output"
        self.prefix = prefix
        # The name of the specific field, e.g. "Result"
        self.name = dictionary['name']
        # The specific TLV ID
        self.id = dictionary['id']
        # Whether the field is to be considered mandatory in the message
        self.mandatory = True if dictionary['mandatory'] == 'yes' else False
        # The type, which must always be "TLV"
        self.type = dictionary['type']
        # The container type, which must be either "Input" or "Output"
        self.container_type = container_type
        # Whether the whole field is internally used only
        self.static = static

        # Create the composed full name (prefix + name),
        #  e.g. "Qmi Message Ctl Something Output Result"
        self.fullname = dictionary['fullname'] if 'fullname' in dictionary else self.prefix + ' ' + self.name

        # Create our variable object
        self.variable = VariableFactory.create_variable(dictionary, self.fullname, self.container_type)

        # Create the variable name within the Container
        self.variable_name = 'arg_' + utils.build_underscore_name(self.name).lower()

        # Create the ID enumeration name
        self.id_enum_name = utils.build_underscore_name(self.prefix + ' TLV ' + self.name).upper()

        # Output Fields may have prerequisites
        self.prerequisites = []
        if 'prerequisites' in dictionary:
            self.prerequisites = dictionary['prerequisites']
            # First, look for references to common types
            for prerequisite_dictionary in self.prerequisites:
                if 'common-ref' in prerequisite_dictionary:
                    for common in common_objects_dictionary:
                        if common['type'] == 'prerequisite' and \
                           common['common-ref'] == prerequisite_dictionary['common-ref']:
                           # Replace the reference with a copy of the common dictionary
                           copy = dict(common)
                           self.prerequisites.remove(prerequisite_dictionary)
                           self.prerequisites.append(copy)
                           break
                    else:
                        raise RuntimeError('Common type \'%s\' not found' % prerequisite_dictionary['name'])
Ejemplo n.º 13
0
    def emit_sections(self, sfile):
        if self.static:
            return

        translations = { 'hyphened'            : utils.build_dashed_name (self.fullname),
                         'fullname_underscore' : utils.build_underscore_name(self.fullname),
                         'camelcase'           : utils.build_camelcase_name (self.fullname),
                         'service'             : utils.build_underscore_name (self.service),
                         'name_underscore'     : utils.build_underscore_name (self.name),
                         'fullname'            : self.service + ' ' + self.name,
                         'type'                : 'response' if self.type == 'Message' else 'indication' }

        sections = { 'public-types'   : '',
                     'public-methods' : '',
                     'standard'       : '',
                     'private'        : '' }

        if self.input:
            self.input.add_sections (sections)
        self.output.add_sections (sections)

        if self.type == 'Message':
            template = (
                '<SUBSECTION ${camelcase}ClientMethods>\n'
                'qmi_client_${service}_${name_underscore}\n'
                'qmi_client_${service}_${name_underscore}_finish\n')
            sections['public-methods'] += string.Template(template).substitute(translations)

        translations['public_types']   = sections['public-types']
        translations['public_methods'] = sections['public-methods']
        translations['standard']       = sections['standard']
        translations['private']        = sections['private']

        template = (
            '<SECTION>\n'
            '<FILE>${hyphened}</FILE>\n'
            '<TITLE>${fullname}</TITLE>\n'
            '${public_types}'
            '${public_methods}'
            '<SUBSECTION Private>\n'
            '${private}'
            '<SUBSECTION Standard>\n'
            '${standard}'
            '</SECTION>\n'
            '\n')
        sfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 14
0
    def emit_output_tlv_get(self, f, line_prefix):
        translations = { 'name'                 : self.name,
                         'container_underscore' : utils.build_underscore_name (self.prefix),
                         'underscore'           : utils.build_underscore_name (self.fullname),
                         'tlv_id'               : self.id_enum_name,
                         'variable_name'        : self.variable_name,
                         'lp'                   : line_prefix,
                         'error'                : 'error' if self.mandatory == 'yes' else 'NULL'}

        template = (
            '${lp}const guint8 *buffer;\n'
            '${lp}guint16 buffer_len;\n'
            '\n'
            '${lp}buffer = qmi_message_get_raw_tlv (message,\n'
            '${lp}                                  ${tlv_id},\n'
            '${lp}                                  &buffer_len);\n'
            '${lp}if (buffer && ${underscore}_validate (buffer, buffer_len)) {\n'
            '${lp}    self->${variable_name}_set = TRUE;\n'
            '\n')
        f.write(string.Template(template).substitute(translations))

        # Now, read the contents of the buffer into the variable
        self.variable.emit_buffer_read(f, line_prefix + '    ', 'self->' + self.variable_name, 'buffer', 'buffer_len')

        template = (
            '\n'
            '${lp}    /* The remaining size of the buffer needs to be 0 if we successfully read the TLV */\n'
            '${lp}    if (buffer_len > 0) {\n'
            '${lp}        g_warning ("Left \'%u\' bytes unread when getting the \'${name}\' TLV", buffer_len);\n'
            '${lp}    }\n')

        if self.mandatory == 'yes':
            template += (
                '${lp}} else {\n'
                '${lp}    g_set_error (error,\n'
                '${lp}                 QMI_CORE_ERROR,\n'
                '${lp}                 QMI_CORE_ERROR_TLV_NOT_FOUND,\n'
                '${lp}                 \"Couldn\'t get the ${name} TLV: Not found\");\n'
                '${lp}    ${container_underscore}_unref (self);\n'
                '${lp}    return NULL;\n'
                '${lp}}\n')
        else:
            template += (
                '${lp}}\n')
        f.write(string.Template(template).substitute(translations))
Ejemplo n.º 15
0
    def __emit_response_or_indication_parser(self, hfile, cfile):
        # If no output fields to parse, don't emit anything
        if self.output is None or self.output.fields is None:
            return

        translations = { 'name'                 : self.name,
                         'type'                 : 'response' if self.type == 'Message' else 'indication',
                         'container'            : utils.build_camelcase_name (self.output.fullname),
                         'container_underscore' : utils.build_underscore_name (self.output.fullname),
                         'underscore'           : utils.build_underscore_name (self.fullname),
                         'message_id'           : self.id_enum_name }

        template = (
            '\n'
            'static ${container} *\n'
            '__${underscore}_${type}_parse (\n'
            '    QmiMessage *message,\n'
            '    GError **error)\n'
            '{\n'
            '    ${container} *self;\n'
            '\n'
            '    g_return_val_if_fail (qmi_message_get_message_id (message) == ${message_id}, NULL);\n'
            '\n'
            '    self = g_slice_new0 (${container});\n'
            '    self->ref_count = 1;\n')
        cfile.write(string.Template(template).substitute(translations))

        for field in self.output.fields:
            cfile.write(
                '\n'
                '    do {\n')
            field.emit_output_prerequisite_check(cfile, '        ')
            cfile.write(
                '\n'
                '        {\n')
            field.emit_output_tlv_get(cfile, '            ')
            cfile.write(
                '\n'
                '        }\n')
            cfile.write(
                '    } while (0);\n')
        cfile.write(
            '\n'
            '    return self;\n'
            '}\n')
Ejemplo n.º 16
0
    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']

        # 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
        if self.service == 'Basic Connect':
            self.fullname = 'MBIM Message ' + self.name
        elif self.name == "":
            self.fullname = 'MBIM Message ' + self.service
        else:
            self.fullname = 'MBIM Message ' + self.service + ' ' + self.name

        # Build CID enum
        self.cid_enum_name = 'MBIM CID ' + self.service
        if self.name != "":
            self.cid_enum_name += (' ' + self.name)
        self.cid_enum_name = utils.build_underscore_name(self.cid_enum_name).upper()
Ejemplo n.º 17
0
    def emit_getter(self, hfile, cfile):
        translations = { 'variable_name'     : self.variable_name,
                         'prefix_camelcase'  : utils.build_camelcase_name(self.prefix),
                         'prefix_underscore' : utils.build_underscore_name(self.prefix) }

        # Emit the getter header
        template = (
            '\n'
            'gboolean ${prefix_underscore}_get_result (\n'
            '    ${prefix_camelcase} *self,\n'
            '    GError **error);\n')
        hfile.write(string.Template(template).substitute(translations))

        # Emit the getter source
        template = (
            '\n'
            '/**\n'
            ' * ${prefix_underscore}_get_result:\n'
            ' * @self: a ${prefix_camelcase}.\n'
            ' * @error: Return location for error or %NULL.\n'
            ' *\n'
            ' * Get the result of the QMI operation.\n'
            ' *\n'
            ' * Returns: %TRUE if the QMI operation succeeded, %FALSE if @error is set.\n'
            ' */\n'
            'gboolean\n'
            '${prefix_underscore}_get_result (\n'
            '    ${prefix_camelcase} *self,\n'
            '    GError **error)\n'
            '{\n'
            '    g_return_val_if_fail (self != NULL, FALSE);\n'
            '\n'
            '    /* We should always have a result set in the response message */\n'
            '    if (!self->${variable_name}_set) {\n'
            '        g_set_error (error,\n'
            '                     QMI_CORE_ERROR,\n'
            '                     QMI_CORE_ERROR_INVALID_MESSAGE,\n'
            '                     "No \'Result\' field given in the message");\n'
            '        return FALSE;\n'
            '    }\n'
            '\n'
            '    if (self->${variable_name}.error_status == QMI_STATUS_SUCCESS) {\n'
            '        /* Operation succeeded */\n'
            '        return TRUE;\n'
            '    }\n'
            '\n'
            '    /* Report a QMI protocol error */\n'
            '    g_set_error (error,\n'
            '                 QMI_PROTOCOL_ERROR,\n'
            '                 (QmiProtocolError) self->${variable_name}.error_code,\n'
            '                 "QMI protocol error (%u): \'%s\'",\n'
            '                 self->${variable_name}.error_code,\n'
            '                 qmi_protocol_error_get_string ((QmiProtocolError) self->${variable_name}.error_code));\n'
            '    return FALSE;\n'
            '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 18
0
    def emit_size_read(self, f, line_prefix, variable_name, buffer_name, buffer_len):
        common_var_prefix = utils.build_underscore_name(self.name)
        translations = { 'lp'             : line_prefix,
                         'variable_name'  : variable_name,
                         'buffer_name'    : buffer_name,
                         'buffer_len'     : buffer_len,
                         'common_var_prefix' : common_var_prefix }

        template = (
            '${lp}{\n'
            '${lp}    guint ${common_var_prefix}_i;\n')
        f.write(string.Template(template).substitute(translations))

        if self.fixed_size:
            translations['fixed_size'] = self.fixed_size

            template = (
                '${lp}    guint16 ${common_var_prefix}_n_items = ${fixed_size};\n'
                '\n')
            f.write(string.Template(template).substitute(translations))
        else:
            translations['array_size_element_format'] = self.array_size_element.public_format
            if self.array_size_element.public_format == 'guint8':
                translations['array_size_element_size'] = '1'
            elif self.array_size_element.public_format == 'guint16':
                translations['array_size_element_size'] = '2'
            elif self.array_size_element.public_format == 'guint32':
                translations['array_size_element_size'] = '4'
            else:
                translations['array_size_element_size'] = '0'

            template = (
                '${lp}    ${array_size_element_format} ${common_var_prefix}_n_items;\n'
                '${lp}    const guint8 *${common_var_prefix}_aux_buffer = &${buffer_name}[${variable_name}];\n'
                '${lp}    guint16 ${common_var_prefix}_aux_buffer_len = ${buffer_len} - ${variable_name};\n'
                '\n'
                '${lp}    ${variable_name} += ${array_size_element_size};\n'
                '\n')
            f.write(string.Template(template).substitute(translations))

            self.array_size_element.emit_buffer_read(f, line_prefix + '    ', common_var_prefix + '_n_items', common_var_prefix + '_aux_buffer', common_var_prefix + '_aux_buffer_len')

        template = (
            '${lp}    for (${common_var_prefix}_i = 0; ${common_var_prefix}_i < ${common_var_prefix}_n_items; ${common_var_prefix}_i++) {\n'
            '\n')
        f.write(string.Template(template).substitute(translations))

        self.array_element.emit_size_read(f, line_prefix + '        ', variable_name, buffer_name, buffer_len)

        template = (
            '${lp}    }\n'
            '${lp}}\n')
        f.write(string.Template(template).substitute(translations))
Ejemplo n.º 19
0
    def emit_sections(self, sfile):
        translations = { 'underscore'                 : utils.build_underscore_name(self.name),
                         'no_prefix_underscore_upper' : utils.build_underscore_name(self.name[4:]).upper(),
                         'camelcase'                  : utils.build_camelcase_name (self.name),
                         'hyphened'                   : utils.build_dashed_name (self.name) }

        template = (
            '<SECTION>\n'
            '<FILE>${hyphened}</FILE>\n'
            '<TITLE>${camelcase}</TITLE>\n'
            '${camelcase}\n'
            '<SUBSECTION Standard>\n'
            '${camelcase}Class\n'
            'QMI_TYPE_${no_prefix_underscore_upper}\n'
            'QMI_${no_prefix_underscore_upper}\n'
            'QMI_${no_prefix_underscore_upper}_CLASS\n'
            'QMI_IS_${no_prefix_underscore_upper}\n'
            'QMI_IS_${no_prefix_underscore_upper}_CLASS\n'
            'QMI_${no_prefix_underscore_upper}_GET_CLASS\n'
            '${underscore}_get_type\n'
            '</SECTION>\n'
            '\n')
        sfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 20
0
    def emit_output_prerequisite_check(self, f, line_prefix):
        if self.prerequisites == []:
            f.write('%s/* No Prerequisites for field */\n' % line_prefix)
            return

        for prerequisite in self.prerequisites:
            translations = { 'lp'                     : line_prefix,
                             'prerequisite_field'     : utils.build_underscore_name(prerequisite['field']),
                             'prerequisite_operation' : prerequisite['operation'],
                             'prerequisite_value'     : prerequisite['value'] }
            template = (
                '${lp}/* Prerequisite.... */\n'
                '${lp}if (!(self->arg_${prerequisite_field} ${prerequisite_operation} ${prerequisite_value}))\n'
                '${lp}    break;\n')
            f.write(string.Template(template).substitute(translations))
Ejemplo n.º 21
0
    def emit_get_printable(self, f, line_prefix, printable, buffer_name, buffer_len):
        common_var_prefix = utils.build_underscore_name(self.name)
        translations = { 'lp'          : line_prefix,
                         'printable'   : printable,
                         'buffer_name' : buffer_name,
                         'buffer_len'  : buffer_len,
                         'common_var_prefix' : common_var_prefix }

        template = (
            '${lp}{\n'
            '${lp}    guint ${common_var_prefix}_i;\n')
        f.write(string.Template(template).substitute(translations))

        if self.fixed_size:
            translations['fixed_size'] = self.fixed_size

            template = (
                '${lp}    guint16 ${common_var_prefix}_n_items = ${fixed_size};\n'
                '\n')
            f.write(string.Template(template).substitute(translations))
        else:
            translations['array_size_element_format'] = self.array_size_element.public_format

            template = (
                '${lp}    ${array_size_element_format} ${common_var_prefix}_n_items;\n'
                '\n'
                '${lp}    /* Read number of items in the array */\n')
            f.write(string.Template(template).substitute(translations))

            self.array_size_element.emit_buffer_read(f, line_prefix + '    ', common_var_prefix + '_n_items', buffer_name, buffer_len)

        template = (
            '\n'
            '${lp}    g_string_append (${printable}, "{");\n'
            '\n'
            '${lp}    for (${common_var_prefix}_i = 0; ${common_var_prefix}_i < ${common_var_prefix}_n_items; ${common_var_prefix}_i++) {\n'
            '${lp}        g_string_append_printf (${printable}, " [%u] = \'", ${common_var_prefix}_i);\n')
        f.write(string.Template(template).substitute(translations))

        self.array_element.emit_get_printable(f, line_prefix + '        ', printable, buffer_name, buffer_len);

        template = (
            '${lp}        g_string_append (${printable}, " \'");\n'
            '${lp}    }\n'
            '\n'
            '${lp}    g_string_append (${printable}, "}");\n'
            '${lp}}')
        f.write(string.Template(template).substitute(translations))
Ejemplo n.º 22
0
    def __init__(self, dictionary, common_objects_dictionary):
        # The message service, e.g. "Ctl"
        self.service = dictionary['service']
        # The name of the specific message, e.g. "Something"
        self.name = dictionary['name']
        # The specific message ID
        self.id = dictionary['id']
        # The type, which must always be 'Message' or 'Indication'
        self.type = dictionary['type']
        # The version info, optional
        self.version_info = dictionary['version'].split(
            '.') if 'version' in dictionary else []
        self.static = True if 'scope' in dictionary and dictionary[
            'scope'] == 'library-only' else False
        self.abort = True if 'abort' in dictionary and dictionary[
            'abort'] == 'yes' else False

        # The message prefix
        self.prefix = 'Qmi ' + self.type

        # Create the composed full name (prefix + service + name),
        #  e.g. "Qmi Message Ctl Something"
        self.fullname = self.prefix + ' ' + self.service + ' ' + self.name

        # Create the ID enumeration name
        self.id_enum_name = utils.build_underscore_name(self.fullname).upper()

        # Build output container.
        # Every defined message will have its own output container, which
        # will generate a new Output type and public getters for each output
        # field. This applies to both Request/Response and Indications.
        # Output containers are actually optional in Indications
        self.output = Container(
            self.fullname, 'Output',
            dictionary['output'] if 'output' in dictionary else None,
            common_objects_dictionary, self.static)

        self.input = None
        if self.type == 'Message':
            # Build input container (Request/Response only).
            # Every defined message will have its own input container, which
            # will generate a new Input type and public getters for each input
            # field
            self.input = Container(
                self.fullname, 'Input',
                dictionary['input'] if 'input' in dictionary else None,
                common_objects_dictionary, self.static)
Ejemplo n.º 23
0
    def emit_tlv_helpers(self, f):
        if TypeFactory.helpers_emitted(self.fullname):
            return

        TypeFactory.set_helpers_emitted(self.fullname)

        translations = {
            'name': self.name,
            'tlv_id': self.id_enum_name,
            'underscore': utils.build_underscore_name(self.fullname)
        }

        template = (
            '\n'
            'static gchar *\n'
            '${underscore}_get_printable (\n'
            '    QmiMessage *message,\n'
            '    const gchar *line_prefix)\n'
            '{\n'
            '    gsize offset = 0;\n'
            '    gsize init_offset;\n'
            '    GString *printable;\n'
            '    GError *error = NULL;\n'
            '\n'
            '    if ((init_offset = qmi_message_tlv_read_init (message, ${tlv_id}, NULL, NULL)) == 0)\n'
            '        return NULL;\n'
            '\n'
            '    printable = g_string_new ("");\n')
        f.write(string.Template(template).substitute(translations))

        # Now, read the contents of the buffer into the printable representation
        self.variable.emit_get_printable(f, '    ')

        template = (
            '\n'
            '    if ((offset = qmi_message_tlv_read_remaining_size (message, init_offset, offset)) > 0)\n'
            '        g_string_append_printf (printable, "Additional unexpected \'%" G_GSIZE_FORMAT "\' bytes", offset);\n'
            '\n'
            'out:\n'
            '    if (error) {\n'
            '        g_string_append_printf (printable, " ERROR: %s", error->message);\n'
            '        g_error_free (error);\n'
            '    }\n'
            '    return g_string_free (printable, FALSE);\n'
            '}\n')
        f.write(string.Template(template).substitute(translations))
Ejemplo n.º 24
0
    def __init__(self, dictionary, common_objects_dictionary):
        # The message service, e.g. "Ctl"
        self.service = dictionary['service']
        # The name of the specific message, e.g. "Something"
        self.name = dictionary['name']
        # The specific message ID
        self.id = dictionary['id']
        # The type, which must always be 'Message' or 'Indication'
        self.type = dictionary['type']
        # The version info, optional
        self.version_info = dictionary['version'].split('.') if 'version' in dictionary else []
        self.static = True if 'scope' in dictionary and dictionary['scope'] == 'library-only' else False
        self.abort = True if 'abort' in dictionary and dictionary['abort'] == 'yes' else False

        # The message prefix
        self.prefix = 'Qmi ' + self.type

        # Create the composed full name (prefix + service + name),
        #  e.g. "Qmi Message Ctl Something"
        self.fullname = self.prefix + ' ' + self.service + ' ' + self.name

        # Create the ID enumeration name
        self.id_enum_name = utils.build_underscore_name(self.fullname).upper()

        # Build output container.
        # Every defined message will have its own output container, which
        # will generate a new Output type and public getters for each output
        # field. This applies to both Request/Response and Indications.
        # Output containers are actually optional in Indications
        self.output = Container(self.fullname,
                                'Output',
                                dictionary['output'] if 'output' in dictionary else None,
                                common_objects_dictionary,
                                self.static)

        self.input = None
        if self.type == 'Message':
            # Build input container (Request/Response only).
            # Every defined message will have its own input container, which
            # will generate a new Input type and public getters for each input
            # field
            self.input = Container(self.fullname,
                                   'Input',
                                   dictionary['input'] if 'input' in dictionary else None,
                                   common_objects_dictionary,
                                   self.static)
Ejemplo n.º 25
0
    def emit_buffer_write(self, f, line_prefix, tlv_name, variable_name):
        common_var_prefix = utils.build_underscore_name(self.name)
        translations = {
            'lp': line_prefix,
            'variable_name': variable_name,
            'common_var_prefix': common_var_prefix
        }

        template = ('${lp}{\n' '${lp}    guint ${common_var_prefix}_i;\n')
        f.write(string.Template(template).substitute(translations))

        if self.fixed_size == 0:
            translations[
                'array_size_element_format'] = self.array_size_element.private_format

            template = (
                '${lp}    ${array_size_element_format} ${common_var_prefix}_n_items;\n'
                '\n'
                '${lp}    /* Write the number of items in the array first */\n'
                '${lp}    ${common_var_prefix}_n_items = (${array_size_element_format}) ${variable_name}->len;\n'
            )
            f.write(string.Template(template).substitute(translations))

            self.array_size_element.emit_buffer_write(
                f, line_prefix + '    ', tlv_name,
                common_var_prefix + '_n_items')

        if self.array_sequence_element != '':
            self.array_sequence_element.emit_buffer_write(
                f, line_prefix + '    ', tlv_name, variable_name + '_sequence')

        template = (
            '\n'
            '${lp}    for (${common_var_prefix}_i = 0; ${common_var_prefix}_i < ${variable_name}->len; ${common_var_prefix}_i++) {\n'
        )
        f.write(string.Template(template).substitute(translations))

        self.array_element.emit_buffer_write(
            f, line_prefix + '        ', tlv_name,
            'g_array_index (' + variable_name + ', ' +
            self.array_element.public_format + ',' + common_var_prefix + '_i)')

        template = ('${lp}    }\n' '${lp}}\n')
        f.write(string.Template(template).substitute(translations))
Ejemplo n.º 26
0
    def emit_tlv_helpers(self, f):
        if TypeFactory.helpers_emitted(self.fullname):
            return

        TypeFactory.set_helpers_emitted(self.fullname)

        translations = { 'name'       : self.name,
                         'tlv_id'     : self.id_enum_name,
                         'underscore' : utils.build_underscore_name (self.fullname) }

        template = (
            '\n'
            'static gchar *\n'
            '${underscore}_get_printable (\n'
            '    QmiMessage *message,\n'
            '    const gchar *line_prefix)\n'
            '{\n'
            '    gsize offset = 0;\n'
            '    gsize init_offset;\n'
            '    GString *printable;\n'
            '    GError *error = NULL;\n'
            '\n'
            '    if ((init_offset = qmi_message_tlv_read_init (message, ${tlv_id}, NULL, NULL)) == 0)\n'
            '        return NULL;\n'
            '\n'
            '    printable = g_string_new ("");\n')
        f.write(string.Template(template).substitute(translations))

        # Now, read the contents of the buffer into the printable representation
        self.variable.emit_get_printable(f, '    ')

        template = (
            '\n'
            '    if ((offset = __qmi_message_tlv_read_remaining_size (message, init_offset, offset)) > 0)\n'
            '        g_string_append_printf (printable, "Additional unexpected \'%" G_GSIZE_FORMAT "\' bytes", offset);\n'
            '\n'
            'out:\n'
            '    if (error)\n'
            '        g_string_append_printf (printable, " ERROR: %s", error->message);\n'
            '    return g_string_free (printable, FALSE);\n'
            '}\n')
        f.write(string.Template(template).substitute(translations))
Ejemplo n.º 27
0
    def __init__(self, dictionary, sequence_type_name, container_type):

        # Call the parent constructor
        Variable.__init__(self, dictionary)

        self.container_type = container_type

        # Load members of this sequence
        self.members = []
        for member_dictionary in dictionary['contents']:
            member = {}
            member['name'] = utils.build_underscore_name(member_dictionary['name'])
            member['object'] = VariableFactory.create_variable(member_dictionary, sequence_type_name + ' ' + member['name'], self.container_type)
            self.members.append(member)

        # TODO: do we need this?
        # We'll need to dispose if at least one of the members needs it
        for member in self.members:
            if member['object'].needs_dispose == True:
                self.needs_dispose = True
Ejemplo n.º 28
0
    def __init__(self, dictionary, sequence_type_name, container_type):

        # Call the parent constructor
        Variable.__init__(self, dictionary)

        self.container_type = container_type

        # Load members of this sequence
        self.members = []
        for member_dictionary in dictionary['contents']:
            member = {}
            member['name'] = utils.build_underscore_name(member_dictionary['name'])
            member['object'] = VariableFactory.create_variable(member_dictionary, sequence_type_name + ' ' + member_dictionary['name'], self.container_type)
            self.members.append(member)

        # TODO: do we need this?
        # We'll need to dispose if at least one of the members needs it
        for member in self.members:
            if member['object'].needs_dispose == True:
                self.needs_dispose = True
Ejemplo n.º 29
0
    def emit_output_prerequisite_check(self, f, line_prefix):
        if self.prerequisites == []:
            f.write('%s/* No Prerequisites for field */\n' % line_prefix)
            return

        for prerequisite in self.prerequisites:
            translations = {
                'lp':
                line_prefix,
                'prerequisite_field':
                utils.build_underscore_name(prerequisite['field']),
                'prerequisite_operation':
                prerequisite['operation'],
                'prerequisite_value':
                prerequisite['value']
            }
            template = (
                '${lp}/* Prerequisite.... */\n'
                '${lp}if (!(self->arg_${prerequisite_field} ${prerequisite_operation} ${prerequisite_value}))\n'
                '${lp}    break;\n')
            f.write(string.Template(template).substitute(translations))
Ejemplo n.º 30
0
    def emit_buffer_write(self, f, line_prefix, variable_name, buffer_name, buffer_len):
        common_var_prefix = utils.build_underscore_name(self.name)
        translations = { 'lp'             : line_prefix,
                         'variable_name'  : variable_name,
                         'buffer_name'    : buffer_name,
                         'buffer_len'     : buffer_len,
                         'common_var_prefix' : common_var_prefix }

        template = (
            '${lp}{\n'
            '${lp}    guint ${common_var_prefix}_i;\n')
        f.write(string.Template(template).substitute(translations))

        if self.fixed_size == 0:
            translations['array_size_element_format'] = self.array_size_element.private_format

            template = (
                '${lp}    ${array_size_element_format} ${common_var_prefix}_n_items;\n'
                '\n'
                '${lp}    /* Write the number of items in the array first */\n'
                '${lp}    ${common_var_prefix}_n_items = (${array_size_element_format}) ${variable_name}->len;\n')
            f.write(string.Template(template).substitute(translations))

            self.array_size_element.emit_buffer_write(f, line_prefix + '    ', common_var_prefix + '_n_items', buffer_name, buffer_len)

        if self.array_sequence_element != '':
            self.array_sequence_element.emit_buffer_write(f, line_prefix + '    ', variable_name + '_sequence', buffer_name, buffer_len)


        template = (
            '\n'
            '${lp}    for (${common_var_prefix}_i = 0; ${common_var_prefix}_i < ${variable_name}->len; ${common_var_prefix}_i++) {\n')
        f.write(string.Template(template).substitute(translations))

        self.array_element.emit_buffer_write(f, line_prefix + '        ', 'g_array_index (' + variable_name + ', ' + self.array_element.public_format + ',' + common_var_prefix + '_i)', buffer_name, buffer_len)

        template = (
            '${lp}    }\n'
            '${lp}}\n')
        f.write(string.Template(template).substitute(translations))
Ejemplo n.º 31
0
    def emit(self, hfile, cfile):
        translations = {
            'name': self.name,
            'camelcase': utils.build_camelcase_name(self.fullname),
            'underscore': utils.build_underscore_name(self.fullname),
            'since': self.since,
            'static': 'static ' if self.static else ''
        }

        auxfile = cfile if self.static else hfile

        if self.fields is None:
            template = ('\n'
                        '/* Note: no fields in the ${name} container */\n')
            auxfile.write(string.Template(template).substitute(translations))
            cfile.write(string.Template(template).substitute(translations))
            return

        # Emit the container and field  types
        # Emit field getter/setter
        if self.fields is not None:
            for field in self.fields:
                field.emit_types(auxfile, cfile)
        self.__emit_types(auxfile, cfile, translations)

        # Emit TLV enums
        self.__emit_tlv_ids_enum(cfile)

        # Emit fields
        if self.fields is not None:
            for field in self.fields:
                field.emit_getter(auxfile, cfile)
                if self.readonly == False:
                    field.emit_setter(auxfile, cfile)

        # Emit the container core
        self.__emit_core(auxfile, cfile, translations)
Ejemplo n.º 32
0
    def emit_section_content(self, sfile):
        translations = {
            'name_dashed': utils.build_dashed_name(self.name),
            'underscore': utils.build_underscore_name(self.fullname)
        }

        template = ('\n' '<SUBSECTION ${name_dashed}>\n')
        sfile.write(string.Template(template).substitute(translations))

        if self.has_query:
            template = ('${underscore}_query_new\n')
            sfile.write(string.Template(template).substitute(translations))

        if self.has_set:
            template = ('${underscore}_set_new\n')
            sfile.write(string.Template(template).substitute(translations))

        if self.has_response:
            template = ('${underscore}_response_parse\n')
            sfile.write(string.Template(template).substitute(translations))

        if self.has_notification:
            template = ('${underscore}_notification_parse\n')
            sfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 33
0
    def add_sections(self, sections):
        if self.fields is None:
            return

        translations = {
            'name':
            self.name,
            'camelcase':
            utils.build_camelcase_name(self.fullname),
            'underscore':
            utils.build_underscore_name(self.fullname),
            'type_macro':
            'QMI_TYPE_' + utils.remove_prefix(
                utils.build_underscore_uppercase_name(self.fullname), 'QMI_')
        }

        # Standard
        template = ('${underscore}_get_type\n' '${type_macro}\n')
        sections['standard'] += string.Template(template).substitute(
            translations)

        # Public types
        template = ('${camelcase}\n')
        sections['public-types'] += string.Template(template).substitute(
            translations)

        # Public methods
        template = '<SUBSECTION ${camelcase}Methods>\n'
        if self.readonly == False:
            template += ('${underscore}_new\n')
        template += ('${underscore}_ref\n' '${underscore}_unref\n')
        sections['public-methods'] += string.Template(template).substitute(
            translations)

        for field in self.fields:
            field.add_sections(sections)
Ejemplo n.º 34
0
    def __init__(self, prefix, dictionary, common_objects_dictionary,
                 container_type, static):
        # The field prefix, usually the name of the Container,
        #  e.g. "Qmi Message Ctl Something Output"
        self.prefix = prefix
        # The name of the specific field, e.g. "Result"
        self.name = dictionary['name']
        # The specific TLV ID
        self.id = dictionary['id']
        # Overridden mandatory field, the default is calculated from id
        self._mandatory = dictionary.get('mandatory')
        # The type, which must always be "TLV"
        self.type = dictionary['type']
        # The container type, which must be either "Input" or "Output"
        self.container_type = container_type
        # Whether the whole field is internally used only
        self.static = static

        # Create the composed full name (prefix + name),
        #  e.g. "Qmi Message Ctl Something Output Result"
        self.fullname = dictionary[
            'fullname'] if 'fullname' in dictionary else self.prefix + ' ' + self.name

        # libqmi version where the message was introduced
        self.since = dictionary['since'] if 'since' in dictionary else None
        if self.since is None:
            raise ValueError(
                'TLV ' + self.fullname +
                ' requires a "since" tag specifying the major version where it was introduced'
            )

        # Create our variable object
        self.variable = VariableFactory.create_variable(
            dictionary, self.fullname, self.container_type)

        # Create the variable name within the Container
        self.variable_name = 'arg_' + utils.build_underscore_name(
            self.name).lower()

        # Create the ID enumeration name
        self.id_enum_name = utils.build_underscore_name(self.prefix + ' TLV ' +
                                                        self.name).upper()

        # Output Fields may have prerequisites
        self.prerequisites = []
        if 'prerequisites' in dictionary:
            self.prerequisites = dictionary['prerequisites']
            # First, look for references to common types
            for prerequisite_dictionary in self.prerequisites:
                if 'common-ref' in prerequisite_dictionary:
                    for common in common_objects_dictionary:
                        if common['type'] == 'prerequisite' and \
                           common['common-ref'] == prerequisite_dictionary['common-ref']:
                            # Replace the reference with a copy of the common dictionary
                            copy = dict(common)
                            self.prerequisites.remove(prerequisite_dictionary)
                            self.prerequisites.append(copy)
                            break
                    else:
                        raise RuntimeError('Common type \'%s\' not found' %
                                           prerequisite_dictionary['name'])
Ejemplo n.º 35
0
    def __emit_helpers(self, hfile, cfile):
        need_tlv_printable = False
        if self.input is not None and self.input.fields is not None:
            need_tlv_printable = True
            for field in self.input.fields:
                field.emit_tlv_helpers(cfile)

        if self.output is not None and self.output.fields is not None:
            need_tlv_printable = True
            for field in self.output.fields:
                field.emit_tlv_helpers(cfile)

        translations = {
            'name': self.name,
            'service': self.service,
            'id': self.id,
            'type': utils.build_underscore_name(self.type),
            'underscore': utils.build_underscore_name(self.name)
        }

        template = ''
        if need_tlv_printable:
            template += ('\n'
                         'struct ${type}_${underscore}_context {\n'
                         '    QmiMessage *self;\n'
                         '    const gchar *line_prefix;\n'
                         '    GString *printable;\n'
                         '};\n'
                         '\n'
                         'static void\n'
                         '${type}_${underscore}_get_tlv_printable (\n'
                         '    guint8 type,\n'
                         '    const guint8 *value,\n'
                         '    gsize length,\n'
                         '    struct ${type}_${underscore}_context *ctx)\n'
                         '{\n'
                         '    const gchar *tlv_type_str = NULL;\n'
                         '    gchar *translated_value;\n'
                         '\n')

            if self.type == 'Message':
                template += (
                    '    if (!qmi_message_is_response (ctx->self)) {\n'
                    '        switch (type) {\n')

                if self.input is not None and self.input.fields is not None:
                    for field in self.input.fields:
                        translations[
                            'underscore_field'] = utils.build_underscore_name(
                                field.fullname)
                        translations['field_enum'] = field.id_enum_name
                        translations['field_name'] = field.name
                        field_template = (
                            '        case ${field_enum}:\n'
                            '            tlv_type_str = "${field_name}";\n'
                            '            translated_value = ${underscore_field}_get_printable (\n'
                            '                                   ctx->self,\n'
                            '                                   ctx->line_prefix);\n'
                            '            break;\n')
                        template += string.Template(field_template).substitute(
                            translations)

                template += ('        default:\n'
                             '            break;\n'
                             '        }\n'
                             '    } else {\n')
            else:
                template += ('    {\n')

            template += ('        switch (type) {\n')
            if self.output is not None and self.output.fields is not None:
                for field in self.output.fields:
                    translations[
                        'underscore_field'] = utils.build_underscore_name(
                            field.fullname)
                    translations['field_enum'] = field.id_enum_name
                    translations['field_name'] = field.name
                    field_template = (
                        '        case ${field_enum}:\n'
                        '            tlv_type_str = "${field_name}";\n'
                        '            translated_value = ${underscore_field}_get_printable (\n'
                        '                                   ctx->self,\n'
                        '                                   ctx->line_prefix);\n'
                        '            break;\n')
                    template += string.Template(field_template).substitute(
                        translations)

            template += (
                '        default:\n'
                '            break;\n'
                '        }\n'
                '    }\n'
                '\n'
                '    if (!tlv_type_str) {\n'
                '        gchar *value_str = NULL;\n'
                '\n'
                '        value_str = qmi_message_get_tlv_printable (ctx->self,\n'
                '                                                   ctx->line_prefix,\n'
                '                                                   type,\n'
                '                                                   value,\n'
                '                                                   length);\n'
                '        g_string_append (ctx->printable, value_str);\n'
                '        g_free (value_str);\n'
                '    } else {\n'
                '        gchar *value_hex;\n'
                '\n'
                '        value_hex = __qmi_utils_str_hex (value, length, \':\');\n'
                '        g_string_append_printf (ctx->printable,\n'
                '                                "%sTLV:\\n"\n'
                '                                "%s  type       = \\"%s\\" (0x%02x)\\n"\n'
                '                                "%s  length     = %" G_GSIZE_FORMAT "\\n"\n'
                '                                "%s  value      = %s\\n"\n'
                '                                "%s  translated = %s\\n",\n'
                '                                ctx->line_prefix,\n'
                '                                ctx->line_prefix, tlv_type_str, type,\n'
                '                                ctx->line_prefix, length,\n'
                '                                ctx->line_prefix, value_hex,\n'
                '                                ctx->line_prefix, translated_value ? translated_value : "");\n'
                '        g_free (value_hex);\n'
                '        g_free (translated_value);\n'
                '    }\n'
                '}\n')

        template += (
            '\n'
            'static gchar *\n'
            '${type}_${underscore}_get_printable (\n'
            '    QmiMessage *self,\n'
            '    const gchar *line_prefix)\n'
            '{\n'
            '    GString *printable;\n'
            '\n'
            '    printable = g_string_new ("");\n'
            '    g_string_append_printf (printable,\n'
            '                            "%s  message     = \\\"${name}\\\" (${id})\\n",\n'
            '                            line_prefix);\n')

        if need_tlv_printable:
            template += (
                '\n'
                '    {\n'
                '        struct ${type}_${underscore}_context ctx;\n'
                '        ctx.self = self;\n'
                '        ctx.line_prefix = line_prefix;\n'
                '        ctx.printable = printable;\n'
                '        qmi_message_foreach_raw_tlv (self,\n'
                '                                     (QmiMessageForeachRawTlvFn)${type}_${underscore}_get_tlv_printable,\n'
                '                                     &ctx);\n'
                '    }\n')
        template += ('\n'
                     '    return g_string_free (printable, FALSE);\n'
                     '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 36
0
    def __init__(self, dictionary, common_objects_dictionary):
        # The message service, e.g. "Ctl"
        self.service = dictionary['service']
        # The name of the specific message, e.g. "Something"
        self.name = dictionary['name']
        # The specific message ID
        self.id = dictionary['id']
        # The type, which must always be 'Message' or 'Indication'
        self.type = dictionary['type']

        # The message version info is no longer supported
        if 'version' in dictionary:
            raise ValueError('The "version" tag is no longer supported')

        self.static = True if 'scope' in dictionary and dictionary['scope'] == 'library-only' else False
        self.abort = True if 'abort' in dictionary and dictionary['abort'] == 'yes' else False

        # libqmi version where the message was introduced
        self.since = dictionary['since'] if 'since' in dictionary else None
        if self.since is None:
            raise ValueError('Message ' + self.name + ' requires a "since" tag specifying the major version where it was introduced')

        # The vendor id if this command is vendor specific
        self.vendor = dictionary['vendor'] if 'vendor' in dictionary else None
        if self.type == 'Indication' and self.vendor is not None:
            raise ValueError('Vendor-specific indications unsupported')

        # The message prefix
        self.prefix = 'Qmi ' + self.type

        # Create the composed full name (prefix + service + name),
        #  e.g. "Qmi Message Ctl Something"
        self.fullname = self.prefix + ' ' + self.service + ' ' + self.name

        # Create the ID enumeration name
        self.id_enum_name = utils.build_underscore_name(self.fullname).upper()

        # Create the build symbol name
        self.build_symbol = 'HAVE_' + self.id_enum_name

        # Build output container.
        # Every defined message will have its own output container, which
        # will generate a new Output type and public getters for each output
        # field. This applies to both Request/Response and Indications.
        # Output containers are actually optional in Indications
        self.output = Container(self.fullname,
                                'Output',
                                dictionary['output'] if 'output' in dictionary else None,
                                common_objects_dictionary,
                                self.static,
                                self.since)

        self.input = None
        if self.type == 'Message':
            # Build input container (Request/Response only).
            # Every defined message will have its own input container, which
            # will generate a new Input type and public getters for each input
            # field
            self.input = Container(self.fullname,
                                   'Input',
                                   dictionary['input'] if 'input' in dictionary else None,
                                   common_objects_dictionary,
                                   self.static,
                                   self.since)
Ejemplo n.º 37
0
    def emit_getter(self, hfile, cfile):
        translations = {
            'variable_name': self.variable_name,
            'prefix_camelcase': utils.build_camelcase_name(self.prefix),
            'prefix_underscore': utils.build_underscore_name(self.prefix),
            'since': self.since
        }

        # Emit the getter header
        template = '\n'
        if self.static == False:
            template += (
                '\n'
                '/**\n'
                ' * ${prefix_underscore}_get_result:\n'
                ' * @self: a ${prefix_camelcase}.\n'
                ' * @error: Return location for error or %NULL.\n'
                ' *\n'
                ' * Get the result of the QMI operation.\n'
                ' *\n'
                ' * Returns: (skip): %TRUE if the QMI operation succeeded, %FALSE if @error is set.\n'
                ' *\n'
                ' * Since: ${since}\n'
                ' */\n')
        template += ('gboolean ${prefix_underscore}_get_result (\n'
                     '    ${prefix_camelcase} *self,\n'
                     '    GError **error);\n')
        hfile.write(string.Template(template).substitute(translations))

        # Emit the getter source
        template = (
            '\n'
            'gboolean\n'
            '${prefix_underscore}_get_result (\n'
            '    ${prefix_camelcase} *self,\n'
            '    GError **error)\n'
            '{\n'
            '    g_return_val_if_fail (self != NULL, FALSE);\n'
            '\n'
            '    /* We should always have a result set in the response message */\n'
            '    if (!self->${variable_name}_set) {\n'
            '        g_set_error (error,\n'
            '                     QMI_CORE_ERROR,\n'
            '                     QMI_CORE_ERROR_INVALID_MESSAGE,\n'
            '                     "No \'Result\' field given in the message");\n'
            '        return FALSE;\n'
            '    }\n'
            '\n'
            '    if (self->${variable_name}.error_status == QMI_STATUS_SUCCESS) {\n'
            '        /* Operation succeeded */\n'
            '        return TRUE;\n'
            '    }\n'
            '\n'
            '    /* Report a QMI protocol error */\n'
            '    g_set_error (error,\n'
            '                 QMI_PROTOCOL_ERROR,\n'
            '                 (QmiProtocolError) self->${variable_name}.error_code,\n'
            '                 "QMI protocol error (%u): \'%s\'",\n'
            '                 self->${variable_name}.error_code,\n'
            '                 qmi_protocol_error_get_string ((QmiProtocolError) self->${variable_name}.error_code));\n'
            '    return FALSE;\n'
            '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 38
0
    def __emit_class(self, hfile, cfile, message_list):

        # Check if we'll have indications
        has_indications = False
        for message in message_list.list:
            if message.type == 'Indication':
                has_indications = True
                break

        translations = {
            'underscore':
            utils.build_underscore_name(self.name),
            'no_prefix_underscore_upper':
            utils.build_underscore_name(self.name[4:]).upper(),
            'camelcase':
            utils.build_camelcase_name(self.name),
            'hyphened':
            utils.build_dashed_name(self.name),
            'service':
            self.service.upper()
        }

        # Emit class header
        template = (
            '#define QMI_TYPE_${no_prefix_underscore_upper}            (${underscore}_get_type ())\n'
            '#define QMI_${no_prefix_underscore_upper}(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), QMI_TYPE_${no_prefix_underscore_upper}, ${camelcase}))\n'
            '#define QMI_${no_prefix_underscore_upper}_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  QMI_TYPE_${no_prefix_underscore_upper}, ${camelcase}Class))\n'
            '#define QMI_IS_${no_prefix_underscore_upper}(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), QMI_TYPE_${no_prefix_underscore_upper}))\n'
            '#define QMI_IS_${no_prefix_underscore_upper}_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  QMI_TYPE_${no_prefix_underscore_upper}))\n'
            '#define QMI_${no_prefix_underscore_upper}_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  QMI_TYPE_${no_prefix_underscore_upper}, ${camelcase}Class))\n'
            '\n'
            'typedef struct _${camelcase} ${camelcase};\n'
            'typedef struct _${camelcase}Class ${camelcase}Class;\n'
            '\n'
            '/**\n'
            ' * ${camelcase}:\n'
            ' *\n'
            ' * The #${camelcase} structure contains private data and should only be accessed\n'
            ' * using the provided API.\n'
            ' */\n'
            'struct _${camelcase} {\n'
            '    /*< private >*/\n'
            '    QmiClient parent;\n'
            '    gpointer priv_unused;\n'
            '};\n'
            '\n'
            'struct _${camelcase}Class {\n'
            '    /*< private >*/\n'
            '    QmiClientClass parent;\n'
            '};\n'
            '\n'
            'GType ${underscore}_get_type (void);\n'
            '\n')
        hfile.write(string.Template(template).substitute(translations))

        # Emit class source. Documentation skipped for the CTL service.
        template = ''
        if self.service != 'CTL':
            template += (
                '\n'
                '/**\n'
                ' * SECTION: ${hyphened}\n'
                ' * @title: ${camelcase}\n'
                ' * @short_description: #QmiClient for the ${service} service.\n'
                ' *\n'
                ' * #QmiClient which handles operations in the ${service} service.\n'
                ' */\n'
                '\n')
        template += (
            'G_DEFINE_TYPE (${camelcase}, ${underscore}, QMI_TYPE_CLIENT);\n')

        if has_indications:
            template += ('\n' 'enum {\n')
            for message in message_list.list:
                if message.type == 'Indication':
                    translations[
                        'signal_id'] = utils.build_underscore_uppercase_name(
                            message.name)
                    inner_template = ('    SIGNAL_${signal_id},\n')
                    template += string.Template(inner_template).substitute(
                        translations)
            template += ('    SIGNAL_LAST\n'
                         '};\n'
                         '\n'
                         'static guint signals[SIGNAL_LAST] = { 0 };\n')

        template += ('\n'
                     'static void\n'
                     'process_indication (QmiClient *self,\n'
                     '                    QmiMessage *message)\n'
                     '{\n'
                     '    switch (qmi_message_get_message_id (message)) {\n')

        for message in message_list.list:
            if message.type == 'Indication':
                translations['enum_name'] = message.id_enum_name
                translations[
                    'message_fullname_underscore'] = utils.build_underscore_name(
                        message.fullname)
                translations['message_name'] = message.name
                translations[
                    'signal_id'] = utils.build_underscore_uppercase_name(
                        message.name)
                inner_template = ''
                if message.output is not None and message.output.fields is not None:
                    # At least one field in the indication
                    translations[
                        'output_camelcase'] = utils.build_camelcase_name(
                            message.output.fullname)
                    translations[
                        'output_underscore'] = utils.build_underscore_name(
                            message.output.fullname)
                    translations[
                        'output_underscore'] = utils.build_underscore_name(
                            message.output.fullname)
                    inner_template += (
                        '        case ${enum_name}: {\n'
                        '            ${output_camelcase} *output;\n'
                        '            GError *error = NULL;\n'
                        '\n'
                        '            /* Parse indication */\n'
                        '            output = __${message_fullname_underscore}_indication_parse (message, &error);\n'
                        '            if (!output) {\n'
                        '                g_warning ("Couldn\'t parse \'${message_name}\' indication: %s",\n'
                        '                           error ? error->message : "Unknown error");\n'
                        '                if (error)\n'
                        '                    g_error_free (error);\n'
                        '            } else {\n'
                        '                g_signal_emit (self, signals[SIGNAL_${signal_id}], 0, output);\n'
                        '                ${output_underscore}_unref (output);\n'
                        '            }\n'
                        '            break;\n'
                        '        }\n')
                else:
                    # No output field in the indication
                    inner_template += (
                        '        case ${enum_name}: {\n'
                        '            g_signal_emit (self, signals[SIGNAL_${signal_id}], 0, NULL);\n'
                        '            break;\n'
                        '        }\n')

                template += string.Template(inner_template).substitute(
                    translations)

        template += (
            '        default:\n'
            '            break;\n'
            '    }\n'
            '}\n'
            '\n'
            'static void\n'
            '${underscore}_init (${camelcase} *self)\n'
            '{\n'
            '}\n'
            '\n'
            'static void\n'
            '${underscore}_class_init (${camelcase}Class *klass)\n'
            '{\n'
            '    QmiClientClass *client_class = QMI_CLIENT_CLASS (klass);\n'
            '\n'
            '    client_class->process_indication = process_indication;\n')

        for message in message_list.list:
            if message.type == 'Indication':
                translations['signal_name'] = utils.build_dashed_name(
                    message.name)
                translations[
                    'signal_id'] = utils.build_underscore_uppercase_name(
                        message.name)
                translations['message_name'] = message.name
                inner_template = ''
                if message.output is not None and message.output.fields is not None:
                    # At least one field in the indication
                    translations[
                        'output_camelcase'] = utils.build_camelcase_name(
                            message.output.fullname)
                    translations[
                        'bundle_type'] = 'QMI_TYPE_' + utils.remove_prefix(
                            utils.build_underscore_uppercase_name(
                                message.output.fullname), 'QMI_')
                    translations['service'] = self.service.upper()
                    translations['message_name_dashed'] = message.name.replace(
                        ' ', '-')
                    inner_template += (
                        '\n'
                        '    /**\n'
                        '     * ${camelcase}::${signal_name}:\n'
                        '     * @object: A #${camelcase}.\n'
                        '     * @output: A #${output_camelcase}.\n'
                        '     *\n'
                        '     * The ::${signal_name} signal gets emitted when a \'<link linkend=\"libqmi-glib-${service}-${message_name_dashed}.top_of_page\">${message_name}</link>\' indication is received.\n'
                        '     */\n'
                        '    signals[SIGNAL_${signal_id}] =\n'
                        '        g_signal_new ("${signal_name}",\n'
                        '                      G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),\n'
                        '                      G_SIGNAL_RUN_LAST,\n'
                        '                      0,\n'
                        '                      NULL,\n'
                        '                      NULL,\n'
                        '                      NULL,\n'
                        '                      G_TYPE_NONE,\n'
                        '                      1,\n'
                        '                      ${bundle_type});\n')
                else:
                    # No output field in the indication
                    inner_template += (
                        '\n'
                        '    /**\n'
                        '     * ${camelcase}::${signal_name}:\n'
                        '     * @object: A #${camelcase}.\n'
                        '     *\n'
                        '     * The ::${signal_name} signal gets emitted when a \'${message_name}\' indication is received.\n'
                        '     */\n'
                        '    signals[SIGNAL_${signal_id}] =\n'
                        '        g_signal_new ("${signal_name}",\n'
                        '                      G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),\n'
                        '                      G_SIGNAL_RUN_LAST,\n'
                        '                      0,\n'
                        '                      NULL,\n'
                        '                      NULL,\n'
                        '                      NULL,\n'
                        '                      G_TYPE_NONE,\n'
                        '                      0);\n')
                template += string.Template(inner_template).substitute(
                    translations)

        template += ('}\n' '\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 39
0
    def _emit_message_parser(self, hfile, cfile, message_type, fields):
        translations = { 'message'                  : self.name,
                         'service'                  : self.service,
                         'underscore'               : utils.build_underscore_name (self.fullname),
                         'message_type'             : message_type,
                         'message_type_upper'       : message_type.upper(),
                         'service_underscore_upper' : utils.build_underscore_name (self.service).upper() }
        template = (
            '\n'
            'gboolean ${underscore}_${message_type}_parse (\n'
            '    const MbimMessage *message,\n')

        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'] == 'byte-array':
                inner_template = ('    const guint8 **${field},\n')
            elif field['format'] == 'unsized-byte-array' or field['format'] == 'ref-byte-array':
                inner_template = ('    guint32 *${field}_size,\n'
                                  '    const guint8 **${field},\n')
            elif 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')
            else:
                raise ValueError('Cannot handle field type \'%s\'' % field['format'])

            template += (string.Template(inner_template).substitute(translations))

        template += (
            '    GError **error);\n')
        hfile.write(string.Template(template).substitute(translations))

        template = (
            '\n'
            '/**\n'
            ' * ${underscore}_${message_type}_parse:\n'
            ' * @message: the #MbimMessage.\n')

        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'])
            translations['array_size'] = field['array-size'] if 'array-size' in field else ''

            if field['format'] == 'byte-array':
                inner_template = (' * @${field}: return location for an array of ${array_size} #guint8 values. Do not free the returned value, it is owned by @message.\n')
            elif field['format'] == 'unsized-byte-array' or field['format'] == 'ref-byte-array':
                inner_template = (' * @${field}_size: return location for the size of the ${field} array.\n'
                                  ' * @${field}: return location for an array of #guint8 values. Do not free the returned value, it is owned by @message.\n')
            elif 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'
            ' *\n'
            ' * Parses and returns parameters of the \'${message}\' ${message_type} command in the \'${service}\' service.\n'
            ' *\n'
            ' * Returns: %TRUE if the message was correctly parsed, %FALSE if @error is set.\n'
            ' */\n'
            'gboolean\n'
            '${underscore}_${message_type}_parse (\n'
            '    const MbimMessage *message,\n')

        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'] == 'byte-array':
                inner_template = ('    const guint8 **${field},\n')
            elif field['format'] == 'unsized-byte-array' or field['format'] == 'ref-byte-array':
                inner_template = ('    guint32 *${field}_size,\n'
                                  '    const guint8 **${field},\n')
            elif 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')

        if fields != []:
            template += (
                '    guint32 offset = 0;\n')

        for field in fields:
            if 'always-read' in field:
                translations['field'] = utils.build_underscore_name_from_camelcase(field['name'])
                inner_template = ('    guint32 _${field};\n')
                template += (string.Template(inner_template).substitute(translations))

        if message_type == 'response':
            template += (
                '\n'
                '    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_COMMAND_DONE) {\n'
                '        g_set_error (error,\n'
                '                     MBIM_CORE_ERROR,\n'
                '                     MBIM_CORE_ERROR_INVALID_MESSAGE,\n'
                '                     \"Message is not a response\");\n'
                '        return FALSE;\n'
                '    }\n')
        elif message_type == 'notification':
            template += (
                '\n'
                '    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_INDICATE_STATUS) {\n'
                '        g_set_error (error,\n'
                '                     MBIM_CORE_ERROR,\n'
                '                     MBIM_CORE_ERROR_INVALID_MESSAGE,\n'
                '                     \"Message is not a notification\");\n'
                '        return FALSE;\n'
                '    }\n')
        else:
            raise ValueError('Unexpected message type \'%s\'' % message_type)

        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 ''
            translations['array_size'] = field['array-size'] if 'array-size' in field else ''

            inner_template = (
                '\n'
                '    /* Read the \'${field_name}\' variable */\n')
            if 'available-if' in field:
                condition = field['available-if']
                translations['condition_field'] = utils.build_underscore_name_from_camelcase(condition['field'])
                translations['condition_operation'] = condition['operation']
                translations['condition_value'] = condition['value']
                inner_template += (
                    '    if (!(_${condition_field} ${condition_operation} ${condition_value})) {\n')
                if field['format'] == 'byte-array':
                    inner_template += (
                        '        if (${field})\n'
                        '            *${field} = NULL;\n')
                elif field['format'] == 'unsized-byte-array' or \
                   field['format'] == 'ref-byte-array':
                    inner_template += (
                        '        if (${field}_size)\n'
                        '            *${field}_size = 0;\n'
                        '        if (${field})\n'
                        '            *${field} = NULL;\n')
                elif field['format'] == 'guint32-array' or \
                     field['format'] == 'string' or \
                     field['format'] == 'string-array' or \
                     field['format'] == 'struct' or \
                     field['format'] == 'struct-array' or \
                     field['format'] == 'ref-struct-array' or \
                     field['format'] == 'ipv4' or \
                     field['format'] == 'ref-ipv4' or \
                     field['format'] == 'ipv4-array' or \
                     field['format'] == 'ipv6' or \
                     field['format'] == 'ref-ipv6' or \
                     field['format'] == 'ipv6-array':
                    inner_template += (
                        '        if (${field} != NULL)\n'
                        '            *${field} = NULL;\n')
                else:
                    raise ValueError('Field format \'%s\' unsupported as optional field' % field['format'])

                inner_template += (
                    '    } else {\n')
            else:
                inner_template += (
                    '    {\n')

            if 'always-read' 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'] == 'byte-array':
                inner_template += (
                    '        const guint8 *tmp;\n'
                    '\n'
                    '        tmp = _mbim_message_read_byte_array (message, 0, offset, FALSE, FALSE, NULL);\n'
                    '        if (${field} != NULL)\n'
                    '            *${field} = tmp;\n'
                    '        offset += ${array_size};\n')
            elif field['format'] == 'unsized-byte-array':
                inner_template += (
                    '        const guint8 *tmp;\n'
                    '        guint32 tmpsize;\n'
                    '\n'
                    '        tmp = _mbim_message_read_byte_array (message, 0, offset, FALSE, FALSE, &tmpsize);\n'
                    '        if (${field} != NULL)\n'
                    '            *${field} = tmp;\n'
                    '        if (${field}_size != NULL)\n'
                    '            *${field}_size = tmpsize;\n'
                    '        offset += tmpsize;\n')
            elif field['format'] == 'ref-byte-array':
                inner_template += (
                    '        const guint8 *tmp;\n'
                    '        guint32 tmpsize;\n'
                    '\n'
                    '        tmp = _mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, &tmpsize);\n'
                    '        if (${field} != NULL)\n'
                    '            *${field} = tmp;\n'
                    '        if (${field}_size != NULL)\n'
                    '            *${field}_size = tmpsize;\n'
                    '        offset += 8;\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 += (
                    '        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, 0, 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}, 0, 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')

            inner_template += (
                '    }\n')

            template += (string.Template(inner_template).substitute(translations))

        template += (
            '\n'
            '    return TRUE;\n'
            '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 40
0
    def __emit_get_printable(self, hfile, cfile):
        translations = {'service': self.service.lower()}

        template = ('\n'
                    '#if defined (LIBQMI_GLIB_COMPILATION)\n'
                    '\n'
                    'G_GNUC_INTERNAL\n'
                    'gchar *__qmi_message_${service}_get_printable (\n'
                    '    QmiMessage *self,\n'
                    '    const gchar *line_prefix);\n'
                    '\n'
                    '#endif\n'
                    '\n')
        hfile.write(string.Template(template).substitute(translations))

        template = ('\n'
                    'gchar *\n'
                    '__qmi_message_${service}_get_printable (\n'
                    '    QmiMessage *self,\n'
                    '    const gchar *line_prefix)\n'
                    '{\n'
                    '    if (qmi_message_is_indication (self)) {\n'
                    '        switch (qmi_message_get_message_id (self)) {\n')

        for message in self.list:
            if message.type == 'Indication':
                translations['enum_name'] = message.id_enum_name
                translations[
                    'message_underscore'] = utils.build_underscore_name(
                        message.name)
                translations['enum_value'] = message.id
                inner_template = (
                    '        case ${enum_name}:\n'
                    '            return indication_${message_underscore}_get_printable (self, line_prefix);\n'
                )
                template += string.Template(inner_template).substitute(
                    translations)

        template += ('         default:\n'
                     '             return NULL;\n'
                     '        }\n'
                     '    } else {\n'
                     '        switch (qmi_message_get_message_id (self)) {\n')

        for message in self.list:
            if message.type == 'Message':
                translations['enum_name'] = message.id_enum_name
                translations[
                    'message_underscore'] = utils.build_underscore_name(
                        message.name)
                translations['enum_value'] = message.id
                inner_template = (
                    '        case ${enum_name}:\n'
                    '            return message_${message_underscore}_get_printable (self, line_prefix);\n'
                )
                template += string.Template(inner_template).substitute(
                    translations)

        template += ('         default:\n'
                     '             return NULL;\n'
                     '        }\n'
                     '    }\n'
                     '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 41
0
    def __emit_request_creator(self, hfile, cfile):
        translations = { 'name'       : self.name,
                         'service'    : self.service,
                         'container'  : utils.build_camelcase_name (self.input.fullname),
                         'underscore' : utils.build_underscore_name (self.fullname),
                         'message_id' : self.id_enum_name }

        input_arg_template = 'gpointer unused' if self.input.fields is None else '${container} *input'
        template = (
            '\n'
            'static QmiMessage *\n'
            '__${underscore}_request_create (\n'
            '    guint16 transaction_id,\n'
            '    guint8 cid,\n'
            '    %s,\n'
            '    GError **error)\n'
            '{\n'
            '    QmiMessage *self;\n'
            '\n'
            '    self = qmi_message_new (QMI_SERVICE_${service},\n'
            '                            cid,\n'
            '                            transaction_id,\n'
            '                            ${message_id});\n' % input_arg_template)
        cfile.write(string.Template(template).substitute(translations))

        if self.input.fields is not None:
            # Count how many mandatory fields we have
            n_mandatory = 0
            for field in self.input.fields:
                if field.mandatory == 'yes':
                    n_mandatory += 1

            if n_mandatory == 0:
                # If we don't have mandatory fields, we do allow to have
                # a NULL input
                cfile.write(
                    '\n'
                    '    /* All TLVs are optional, we allow NULL input */\n'
                    '    if (!input)\n'
                    '        return self;\n')
            else:
                # If we do have mandatory fields, issue error if no input
                # given.
                template = (
                    '\n'
                    '    /* There is at least one mandatory TLV, don\'t allow NULL input */\n'
                    '    if (!input) {\n'
                    '        g_set_error (error,\n'
                    '                     QMI_CORE_ERROR,\n'
                    '                     QMI_CORE_ERROR_INVALID_ARGS,\n'
                    '                     "Message \'${name}\' has mandatory TLVs");\n'
                    '        goto error_out;\n'
                    '    }\n')
                cfile.write(string.Template(template).substitute(translations))

            # Now iterate fields
            for field in self.input.fields:
                translations['tlv_name'] = field.name
                translations['variable_name'] = field.variable_name
                template = (
                    '\n'
                    '    /* Try to add the \'${tlv_name}\' TLV */\n'
                    '    if (input->${variable_name}_set) {\n')
                cfile.write(string.Template(template).substitute(translations))

                # Emit the TLV getter
                field.emit_input_tlv_add(cfile, '        ')

                if field.mandatory == 'yes':
                    template = (
                        '    } else {\n'
                        '        g_set_error (error,\n'
                        '                     QMI_CORE_ERROR,\n'
                        '                     QMI_CORE_ERROR_INVALID_ARGS,\n'
                        '                     "Missing mandatory TLV \'${tlv_name}\' in message \'${name}\'");\n'
                        '        goto error_out;\n')
                    cfile.write(string.Template(template).substitute(translations))

                cfile.write(
                    '    }\n')
        cfile.write(
            '\n'
            '    return self;\n')
        if self.input.fields is not None:
            cfile.write(
                '\n'
                'error_out:\n'
                '    qmi_message_unref (self);\n'
                '    return NULL;\n')
        cfile.write(
            '}\n')
Ejemplo n.º 42
0
    def __emit_methods(self, hfile, cfile, message_list):
        translations = { 'underscore'        : utils.build_underscore_name(self.name),
                         'camelcase'         : utils.build_camelcase_name (self.name),
                         'service_lowercase' : self.service.lower(),
                         'service_uppercase' : self.service.upper(),
                         'service_camelcase' : string.capwords(self.service) }

        for message in message_list.list:

            if message.type == 'Indication':
                continue

            if message.static:
                continue

            translations['message_name'] = message.name
            translations['message_underscore'] = utils.build_underscore_name(message.name)
            translations['message_fullname_underscore'] = utils.build_underscore_name(message.fullname)
            translations['input_camelcase'] = utils.build_camelcase_name(message.input.fullname)
            translations['output_camelcase'] = utils.build_camelcase_name(message.output.fullname)
            translations['input_underscore'] = utils.build_underscore_name(message.input.fullname)
            translations['output_underscore'] = utils.build_underscore_name(message.output.fullname)

            if message.input.fields is None:
                input_arg_template = 'gpointer unused'
                translations['input_var'] = 'NULL'
                translations['input_doc'] = 'unused: %NULL. This message doesn\'t have any input bundle.'
            else:
                input_arg_template = '${input_camelcase} *input'
                translations['input_var'] = 'input'
                translations['input_doc'] = 'input: a #' + translations['input_camelcase'] + '.'
            template = (
                '\n'
                'void ${underscore}_${message_underscore} (\n'
                '    ${camelcase} *self,\n'
                '    %s,\n'
                '    guint timeout,\n'
                '    GCancellable *cancellable,\n'
                '    GAsyncReadyCallback callback,\n'
                '    gpointer user_data);\n'
                '${output_camelcase} *${underscore}_${message_underscore}_finish (\n'
                '    ${camelcase} *self,\n'
                '    GAsyncResult *res,\n'
                '    GError **error);\n' % input_arg_template)
            hfile.write(string.Template(template).substitute(translations))

            template = (
                '\n'
                '/**\n'
                ' * ${underscore}_${message_underscore}_finish:\n'
                ' * @self: a #${camelcase}.\n'
                ' * @res: the #GAsyncResult obtained from the #GAsyncReadyCallback passed to ${underscore}_${message_underscore}().\n'
                ' * @error: Return location for error or %NULL.\n'
                ' *\n'
                ' * Finishes an async operation started with ${underscore}_${message_underscore}().\n'
                ' *\n'
                ' * Returns: a #${output_camelcase}, or %NULL if @error is set. The returned value should be freed with ${output_underscore}_unref().\n'
                ' */\n'
                '${output_camelcase} *\n'
                '${underscore}_${message_underscore}_finish (\n'
                '    ${camelcase} *self,\n'
                '    GAsyncResult *res,\n'
                '    GError **error)\n'
                '{\n'
                '   if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))\n'
                '       return NULL;\n'
                '\n'
                '   return ${output_underscore}_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));\n'
                '}\n')

            if message.abort:
                template += (
                '\n'
                'static void\n'
                '${message_underscore}_abort_ready (\n'
                '    QmiDevice *device,\n'
                '    GAsyncResult *res)\n'
                '{\n'
                '    GError *error = NULL;\n'
                '    QmiMessage *reply;\n'
                '    QmiMessage${service_camelcase}AbortOutput *output;\n'
                '\n'
                '    reply = qmi_device_command_finish (device, res, &error);\n'
                '    if (reply) {\n'
                '        output = __qmi_message_${service_lowercase}_abort_response_parse (reply, &error);\n'
                '        if (output)\n'
                '            qmi_message_${service_lowercase}_abort_output_unref (output);\n'
                '        qmi_message_unref (reply);\n'
                '    }\n'
                '\n'
                '    if (error) {\n'
                '        g_debug ("Operation to abort \'${message_name}\' failed: %s", error->message);\n'
                '        g_error_free (error);\n'
                '    }\n'
                '}\n')

            template += (
                '\n'
                'static void\n'
                '${message_underscore}_ready (\n'
                '    QmiDevice *device,\n'
                '    GAsyncResult *res,\n'
                '    GSimpleAsyncResult *simple)\n'
                '{\n'
                '    GError *error = NULL;\n'
                '    QmiMessage *reply;\n'
                '    ${output_camelcase} *output;\n'
                '\n'
                '    reply = qmi_device_command_finish (device, res, &error);\n'
                '    if (!reply) {\n')

            if message.abort:
                template += (
                    '        if (g_error_matches (error, QMI_CORE_ERROR, QMI_CORE_ERROR_TIMEOUT) ||\n'
                    '            g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_ABORTED)) {\n'
                    '                QmiMessage *abort;\n'
                    '                GObject *self;\n'
                    '                guint16 transaction_id;\n'
                    '                QmiMessage${service_camelcase}AbortInput *input;\n'
                    '\n'
                    '                self = g_async_result_get_source_object (G_ASYNC_RESULT (simple));\n'
                    '                g_assert (self != NULL);\n'
                    '\n'
                    '                transaction_id = (guint16) GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (simple),\n'
                    '                                                                                "transaction-id"));\n'
                    '                g_assert (transaction_id != 0);\n'
                    '\n'
                    '                input = qmi_message_${service_lowercase}_abort_input_new ();\n'
                    '                qmi_message_${service_lowercase}_abort_input_set_transaction_id (\n'
                    '                    input,\n'
                    '                    transaction_id,\n'
                    '                    NULL);\n'
                    '                abort = __qmi_message_${service_lowercase}_abort_request_create (\n'
                    '                            qmi_client_get_next_transaction_id (QMI_CLIENT (self)),\n'
                    '                            qmi_client_get_cid (QMI_CLIENT (self)),\n'
                    '                            input,\n'
                    '                            NULL);\n'
                    '                g_assert (abort != NULL);\n'
                    '                qmi_device_command (device,\n'
                    '                                    abort,\n'
                    '                                    30,\n'
                    '                                    NULL,\n'
                    '                                    (GAsyncReadyCallback)${message_underscore}_abort_ready,\n'
                    '                                    NULL);\n'
                    '                qmi_message_${service_lowercase}_abort_input_unref (input);\n'
                    '                qmi_message_unref (abort);\n'
                    '                g_object_unref (self);\n'
                    '            }\n'
                    '\n')

            template += (
                '        g_simple_async_result_take_error (simple, error);\n'
                '        g_simple_async_result_complete (simple);\n'
                '        g_object_unref (simple);\n'
                '        return;\n'
                '    }\n'
                '\n'
                '    /* Parse reply */\n'
                '    output = __${message_fullname_underscore}_response_parse (reply, &error);\n'
                '    if (!output)\n'
                '        g_simple_async_result_take_error (simple, error);\n'
                '    else\n'
                '        g_simple_async_result_set_op_res_gpointer (simple,\n'
                '                                                   output,\n'
                '                                                   (GDestroyNotify)${output_underscore}_unref);\n'
                '    g_simple_async_result_complete (simple);\n'
                '    g_object_unref (simple);\n'
                '    qmi_message_unref (reply);\n'
                '}\n'
                '\n'
                '/**\n'
                ' * ${underscore}_${message_underscore}:\n'
                ' * @self: a #${camelcase}.\n'
                ' * @${input_doc}\n'
                ' * @timeout: maximum time to wait for the method to complete, in seconds.\n'
                ' * @cancellable: a #GCancellable or %NULL.\n'
                ' * @callback: a #GAsyncReadyCallback to call when the request is satisfied.\n'
                ' * @user_data: user data to pass to @callback.\n'
                ' *\n'
                ' * Asynchronously sends a ${message_name} request to the device.\n'
                ' *\n'
                ' * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from.\n'
                ' *\n'
                ' * You can then call ${underscore}_${message_underscore}_finish() to get the result of the operation.\n'
                ' */\n'
                'void\n'
                '${underscore}_${message_underscore} (\n'
                '    ${camelcase} *self,\n')
            template += (
                '    %s,\n'  % input_arg_template)
            template += (
                '    guint timeout,\n'
                '    GCancellable *cancellable,\n'
                '    GAsyncReadyCallback callback,\n'
                '    gpointer user_data)\n'
                '{\n'
                '    GSimpleAsyncResult *result;\n'
                '    QmiMessage *request;\n'
                '    GError *error = NULL;\n'
                '    guint16 transaction_id;\n'
                '\n'
                '    result = g_simple_async_result_new (G_OBJECT (self),\n'
                '                                        callback,\n'
                '                                        user_data,\n'
                '                                        ${underscore}_${message_underscore});\n'
                '\n'
                '    transaction_id = qmi_client_get_next_transaction_id (QMI_CLIENT (self));\n'
                '\n'
                '    request = __${message_fullname_underscore}_request_create (\n'
                '                  transaction_id,\n'
                '                  qmi_client_get_cid (QMI_CLIENT (self)),\n'
                '                  ${input_var},\n'
                '                  &error);\n'
                '    if (!request) {\n'
                '        g_prefix_error (&error, "Couldn\'t create request message: ");\n'
                '        g_simple_async_result_take_error (result, error);\n'
                '        g_simple_async_result_complete_in_idle (result);\n'
                '        g_object_unref (result);\n'
                '        return;\n'
                '    }\n')

            if message.abort:
                template += (
                    '\n'
                    '    g_object_set_data (G_OBJECT (result),\n'
                    '                       "transaction-id",\n'
                    '                       GUINT_TO_POINTER (transaction_id));\n')

            template += (
                '\n'
                '    qmi_device_command (QMI_DEVICE (qmi_client_peek_device (QMI_CLIENT (self))),\n'
                '                        request,\n'
                '                        timeout,\n'
                '                        cancellable,\n'
                '                        (GAsyncReadyCallback)${message_underscore}_ready,\n'
                '                        result);\n'
                '    qmi_message_unref (request);\n'
                '}\n'
                '\n')
            cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 43
0
    def __emit_class(self, hfile, cfile, message_list):

        # Check if we'll have indications
        has_indications = False
        for message in message_list.list:
            if message.type == 'Indication':
                has_indications = True
                break

        translations = { 'underscore'                 : utils.build_underscore_name(self.name),
                         'no_prefix_underscore_upper' : utils.build_underscore_name(self.name[4:]).upper(),
                         'camelcase'                  : utils.build_camelcase_name(self.name),
                         'hyphened'                   : utils.build_dashed_name(self.name),
                         'service'                    : self.service.upper() }

        # Emit class header
        template = (
            '#define QMI_TYPE_${no_prefix_underscore_upper}            (${underscore}_get_type ())\n'
            '#define QMI_${no_prefix_underscore_upper}(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), QMI_TYPE_${no_prefix_underscore_upper}, ${camelcase}))\n'
            '#define QMI_${no_prefix_underscore_upper}_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  QMI_TYPE_${no_prefix_underscore_upper}, ${camelcase}Class))\n'
            '#define QMI_IS_${no_prefix_underscore_upper}(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), QMI_TYPE_${no_prefix_underscore_upper}))\n'
            '#define QMI_IS_${no_prefix_underscore_upper}_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  QMI_TYPE_${no_prefix_underscore_upper}))\n'
            '#define QMI_${no_prefix_underscore_upper}_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  QMI_TYPE_${no_prefix_underscore_upper}, ${camelcase}Class))\n'
            '\n'
            'typedef struct _${camelcase} ${camelcase};\n'
            'typedef struct _${camelcase}Class ${camelcase}Class;\n'
            '\n'
            '/**\n'
            ' * ${camelcase}:\n'
            ' *\n'
            ' * The #${camelcase} structure contains private data and should only be accessed\n'
            ' * using the provided API.\n'
            ' */\n'
            'struct _${camelcase} {\n'
            '    /*< private >*/\n'
            '    QmiClient parent;\n'
            '    gpointer priv_unused;\n'
            '};\n'
            '\n'
            'struct _${camelcase}Class {\n'
            '    /*< private >*/\n'
            '    QmiClientClass parent;\n'
            '};\n'
            '\n'
            'GType ${underscore}_get_type (void);\n'
            '\n')
        hfile.write(string.Template(template).substitute(translations))

        # Emit class source. Documentation skipped for the CTL service.
        template = ''
        if self.service != 'CTL':
            template += (
                '\n'
                '/**\n'
                ' * SECTION: ${hyphened}\n'
                ' * @title: ${camelcase}\n'
                ' * @short_description: #QmiClient for the ${service} service.\n'
                ' *\n'
                ' * #QmiClient which handles operations in the ${service} service.\n'
                ' */\n'
                '\n')
        template += (
            'G_DEFINE_TYPE (${camelcase}, ${underscore}, QMI_TYPE_CLIENT);\n')

        if has_indications:
            template += (
                '\n'
                'enum {\n')
            for message in message_list.list:
                if message.type == 'Indication':
                    translations['signal_id'] = utils.build_underscore_uppercase_name(message.name)
                    inner_template = (
                        '    SIGNAL_${signal_id},\n')
                    template += string.Template(inner_template).substitute(translations)
            template += (
                '    SIGNAL_LAST\n'
                '};\n'
                '\n'
                'static guint signals[SIGNAL_LAST] = { 0 };\n')

        template += (
            '\n'
            'static void\n'
            'process_indication (QmiClient *self,\n'
            '                    QmiMessage *message)\n'
            '{\n'
            '    switch (qmi_message_get_message_id (message)) {\n')

        for message in message_list.list:
            if message.type == 'Indication':
                translations['enum_name'] = message.id_enum_name
                translations['message_fullname_underscore'] = utils.build_underscore_name(message.fullname)
                translations['message_name'] = message.name
                translations['signal_id'] = utils.build_underscore_uppercase_name(message.name)
                inner_template = ''
                if message.output is not None and message.output.fields is not None:
                    # At least one field in the indication
                    translations['output_camelcase'] = utils.build_camelcase_name(message.output.fullname)
                    translations['output_underscore'] = utils.build_underscore_name(message.output.fullname)
                    translations['output_underscore'] = utils.build_underscore_name(message.output.fullname)
                    inner_template += (
                        '        case ${enum_name}: {\n'
                        '            ${output_camelcase} *output;\n'
                        '            GError *error = NULL;\n'
                        '\n'
                        '            /* Parse indication */\n'
                        '            output = __${message_fullname_underscore}_indication_parse (message, &error);\n'
                        '            if (!output) {\n'
                        '                g_warning ("Couldn\'t parse \'${message_name}\' indication: %s",\n'
                        '                           error ? error->message : "Unknown error");\n'
                        '                if (error)\n'
                        '                    g_error_free (error);\n'
                        '            } else {\n'
                        '                g_signal_emit (self, signals[SIGNAL_${signal_id}], 0, output);\n'
                        '                ${output_underscore}_unref (output);\n'
                        '            }\n'
                        '            break;\n'
                        '        }\n')
                else:
                    # No output field in the indication
                    inner_template += (
                        '        case ${enum_name}: {\n'
                        '            g_signal_emit (self, signals[SIGNAL_${signal_id}], 0, NULL);\n'
                        '            break;\n'
                        '        }\n')

                template += string.Template(inner_template).substitute(translations)

        template += (
            '        default:\n'
            '            break;\n'
            '    }\n'
            '}\n'
            '\n'
            'static void\n'
            '${underscore}_init (${camelcase} *self)\n'
            '{\n'
            '}\n'
            '\n'
            'static void\n'
            '${underscore}_class_init (${camelcase}Class *klass)\n'
            '{\n'
            '    QmiClientClass *client_class = QMI_CLIENT_CLASS (klass);\n'
            '\n'
            '    client_class->process_indication = process_indication;\n')

        for message in message_list.list:
            if message.type == 'Indication':
                translations['signal_name'] = utils.build_dashed_name(message.name)
                translations['signal_id'] = utils.build_underscore_uppercase_name(message.name)
                translations['message_name'] = message.name
                inner_template = ''
                if message.output is not None and message.output.fields is not None:
                    # At least one field in the indication
                    translations['output_camelcase'] = utils.build_camelcase_name(message.output.fullname)
                    translations['bundle_type'] = 'QMI_TYPE_' + utils.remove_prefix(utils.build_underscore_uppercase_name(message.output.fullname), 'QMI_')
                    translations['service'] = self.service.upper()
                    translations['message_name_dashed'] = message.name.replace(' ', '-')
                    inner_template += (
                        '\n'
                        '    /**\n'
                        '     * ${camelcase}::${signal_name}:\n'
                        '     * @object: A #${camelcase}.\n'
                        '     * @output: A #${output_camelcase}.\n'
                        '     *\n'
                        '     * The ::${signal_name} signal gets emitted when a \'<link linkend=\"libqmi-glib-${service}-${message_name_dashed}.top_of_page\">${message_name}</link>\' indication is received.\n'
                        '     */\n'
                        '    signals[SIGNAL_${signal_id}] =\n'
                        '        g_signal_new ("${signal_name}",\n'
                        '                      G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),\n'
                        '                      G_SIGNAL_RUN_LAST,\n'
                        '                      0,\n'
                        '                      NULL,\n'
                        '                      NULL,\n'
                        '                      NULL,\n'
                        '                      G_TYPE_NONE,\n'
                        '                      1,\n'
                        '                      ${bundle_type});\n')
                else:
                    # No output field in the indication
                    inner_template += (
                        '\n'
                        '    /**\n'
                        '     * ${camelcase}::${signal_name}:\n'
                        '     * @object: A #${camelcase}.\n'
                        '     *\n'
                        '     * The ::${signal_name} signal gets emitted when a \'${message_name}\' indication is received.\n'
                        '     */\n'
                        '    signals[SIGNAL_${signal_id}] =\n'
                        '        g_signal_new ("${signal_name}",\n'
                        '                      G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),\n'
                        '                      G_SIGNAL_RUN_LAST,\n'
                        '                      0,\n'
                        '                      NULL,\n'
                        '                      NULL,\n'
                        '                      NULL,\n'
                        '                      G_TYPE_NONE,\n'
                        '                      0);\n')
                template += string.Template(inner_template).substitute(translations)

        template += (
            '}\n'
            '\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 44
0
    def emit_setter(self, hfile, cfile):
        input_variable_name = 'value_' + utils.build_underscore_name(self.name)
        variable_setter_dec = self.variable.build_setter_declaration(
            '    ', input_variable_name)
        variable_setter_doc = self.variable.build_setter_documentation(
            ' * ', input_variable_name)
        variable_setter_imp = self.variable.build_setter_implementation(
            '    ', input_variable_name, 'self->' + self.variable_name)
        translations = {
            'name': self.name,
            'variable_name': self.variable_name,
            'variable_setter_dec': variable_setter_dec,
            'variable_setter_doc': variable_setter_doc,
            'variable_setter_imp': variable_setter_imp,
            'underscore': utils.build_underscore_name(self.name),
            'prefix_camelcase': utils.build_camelcase_name(self.prefix),
            'prefix_underscore': utils.build_underscore_name(self.prefix),
            'since': self.since,
            'static': 'static ' if self.static else ''
        }

        # Emit the setter header
        template = '\n'
        if self.static == False:
            template += (
                '\n'
                '/**\n'
                ' * ${prefix_underscore}_set_${underscore}:\n'
                ' * @self: a #${prefix_camelcase}.\n'
                '${variable_setter_doc}'
                ' * @error: Return location for error or %NULL.\n'
                ' *\n'
                ' * Set the \'${name}\' field in the message.\n'
                ' *\n'
                ' * Returns: (skip): %TRUE if @value was successfully set, %FALSE otherwise.\n'
                ' *\n'
                ' * Since: ${since}\n'
                ' */\n')
        template += (
            '${static}gboolean ${prefix_underscore}_set_${underscore} (\n'
            '    ${prefix_camelcase} *self,\n'
            '${variable_setter_dec}'
            '    GError **error);\n')
        hfile.write(string.Template(template).substitute(translations))

        # Emit the setter source
        template = ('\n'
                    '${static}gboolean\n'
                    '${prefix_underscore}_set_${underscore} (\n'
                    '    ${prefix_camelcase} *self,\n'
                    '${variable_setter_dec}'
                    '    GError **error)\n'
                    '{\n'
                    '    g_return_val_if_fail (self != NULL, FALSE);\n'
                    '\n'
                    '${variable_setter_imp}'
                    '    self->${variable_name}_set = TRUE;\n'
                    '\n'
                    '    return TRUE;\n'
                    '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 45
0
    def __emit_methods(self, hfile, cfile, message_list):
        translations = {
            'underscore': utils.build_underscore_name(self.name),
            'camelcase': utils.build_camelcase_name(self.name),
            'service_lowercase': self.service.lower(),
            'service_uppercase': self.service.upper(),
            'service_camelcase': string.capwords(self.service)
        }

        for message in message_list.list:

            if message.type == 'Indication':
                continue

            if message.static:
                continue

            translations['message_name'] = message.name
            translations['message_underscore'] = utils.build_underscore_name(
                message.name)
            translations[
                'message_fullname_underscore'] = utils.build_underscore_name(
                    message.fullname)
            translations['input_camelcase'] = utils.build_camelcase_name(
                message.input.fullname)
            translations['output_camelcase'] = utils.build_camelcase_name(
                message.output.fullname)
            translations['input_underscore'] = utils.build_underscore_name(
                message.input.fullname)
            translations['output_underscore'] = utils.build_underscore_name(
                message.output.fullname)

            if message.input.fields is None:
                input_arg_template = 'gpointer unused'
                translations['input_var'] = 'NULL'
                translations[
                    'input_doc'] = 'unused: %NULL. This message doesn\'t have any input bundle.'
            else:
                input_arg_template = '${input_camelcase} *input'
                translations['input_var'] = 'input'
                translations['input_doc'] = 'input: a #' + translations[
                    'input_camelcase'] + '.'
            template = (
                '\n'
                'void ${underscore}_${message_underscore} (\n'
                '    ${camelcase} *self,\n'
                '    %s,\n'
                '    guint timeout,\n'
                '    GCancellable *cancellable,\n'
                '    GAsyncReadyCallback callback,\n'
                '    gpointer user_data);\n'
                '${output_camelcase} *${underscore}_${message_underscore}_finish (\n'
                '    ${camelcase} *self,\n'
                '    GAsyncResult *res,\n'
                '    GError **error);\n' % input_arg_template)
            hfile.write(string.Template(template).substitute(translations))

            template = (
                '\n'
                '/**\n'
                ' * ${underscore}_${message_underscore}_finish:\n'
                ' * @self: a #${camelcase}.\n'
                ' * @res: the #GAsyncResult obtained from the #GAsyncReadyCallback passed to ${underscore}_${message_underscore}().\n'
                ' * @error: Return location for error or %NULL.\n'
                ' *\n'
                ' * Finishes an async operation started with ${underscore}_${message_underscore}().\n'
                ' *\n'
                ' * Returns: a #${output_camelcase}, or %NULL if @error is set. The returned value should be freed with ${output_underscore}_unref().\n'
                ' */\n'
                '${output_camelcase} *\n'
                '${underscore}_${message_underscore}_finish (\n'
                '    ${camelcase} *self,\n'
                '    GAsyncResult *res,\n'
                '    GError **error)\n'
                '{\n'
                '   if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))\n'
                '       return NULL;\n'
                '\n'
                '   return ${output_underscore}_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));\n'
                '}\n')

            if message.abort:
                template += (
                    '\n'
                    'static void\n'
                    '${message_underscore}_abort_ready (\n'
                    '    QmiDevice *device,\n'
                    '    GAsyncResult *res)\n'
                    '{\n'
                    '    GError *error = NULL;\n'
                    '    QmiMessage *reply;\n'
                    '    QmiMessage${service_camelcase}AbortOutput *output;\n'
                    '\n'
                    '    reply = qmi_device_command_finish (device, res, &error);\n'
                    '    if (reply) {\n'
                    '        output = __qmi_message_${service_lowercase}_abort_response_parse (reply, &error);\n'
                    '        if (output)\n'
                    '            qmi_message_${service_lowercase}_abort_output_unref (output);\n'
                    '        qmi_message_unref (reply);\n'
                    '    }\n'
                    '\n'
                    '    if (error) {\n'
                    '        g_debug ("Operation to abort \'${message_name}\' failed: %s", error->message);\n'
                    '        g_error_free (error);\n'
                    '    }\n'
                    '}\n')

            template += (
                '\n'
                'static void\n'
                '${message_underscore}_ready (\n'
                '    QmiDevice *device,\n'
                '    GAsyncResult *res,\n'
                '    GSimpleAsyncResult *simple)\n'
                '{\n'
                '    GError *error = NULL;\n'
                '    QmiMessage *reply;\n'
                '    ${output_camelcase} *output;\n'
                '\n'
                '    reply = qmi_device_command_finish (device, res, &error);\n'
                '    if (!reply) {\n')

            if message.abort:
                template += (
                    '        if (g_error_matches (error, QMI_CORE_ERROR, QMI_CORE_ERROR_TIMEOUT) ||\n'
                    '            g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_ABORTED)) {\n'
                    '                QmiMessage *abort;\n'
                    '                GObject *self;\n'
                    '                guint16 transaction_id;\n'
                    '                QmiMessage${service_camelcase}AbortInput *input;\n'
                    '\n'
                    '                self = g_async_result_get_source_object (G_ASYNC_RESULT (simple));\n'
                    '                g_assert (self != NULL);\n'
                    '\n'
                    '                transaction_id = (guint16) GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (simple),\n'
                    '                                                                                "transaction-id"));\n'
                    '                g_assert (transaction_id != 0);\n'
                    '\n'
                    '                input = qmi_message_${service_lowercase}_abort_input_new ();\n'
                    '                qmi_message_${service_lowercase}_abort_input_set_transaction_id (\n'
                    '                    input,\n'
                    '                    transaction_id,\n'
                    '                    NULL);\n'
                    '                abort = __qmi_message_${service_lowercase}_abort_request_create (\n'
                    '                            qmi_client_get_next_transaction_id (QMI_CLIENT (self)),\n'
                    '                            qmi_client_get_cid (QMI_CLIENT (self)),\n'
                    '                            input,\n'
                    '                            NULL);\n'
                    '                g_assert (abort != NULL);\n'
                    '                qmi_device_command (device,\n'
                    '                                    abort,\n'
                    '                                    30,\n'
                    '                                    NULL,\n'
                    '                                    (GAsyncReadyCallback)${message_underscore}_abort_ready,\n'
                    '                                    NULL);\n'
                    '                qmi_message_${service_lowercase}_abort_input_unref (input);\n'
                    '                qmi_message_unref (abort);\n'
                    '                g_object_unref (self);\n'
                    '            }\n'
                    '\n')

            template += (
                '        g_simple_async_result_take_error (simple, error);\n'
                '        g_simple_async_result_complete (simple);\n'
                '        g_object_unref (simple);\n'
                '        return;\n'
                '    }\n'
                '\n'
                '    /* Parse reply */\n'
                '    output = __${message_fullname_underscore}_response_parse (reply, &error);\n'
                '    if (!output)\n'
                '        g_simple_async_result_take_error (simple, error);\n'
                '    else\n'
                '        g_simple_async_result_set_op_res_gpointer (simple,\n'
                '                                                   output,\n'
                '                                                   (GDestroyNotify)${output_underscore}_unref);\n'
                '    g_simple_async_result_complete (simple);\n'
                '    g_object_unref (simple);\n'
                '    qmi_message_unref (reply);\n'
                '}\n'
                '\n'
                '/**\n'
                ' * ${underscore}_${message_underscore}:\n'
                ' * @self: a #${camelcase}.\n'
                ' * @${input_doc}\n'
                ' * @timeout: maximum time to wait for the method to complete, in seconds.\n'
                ' * @cancellable: a #GCancellable or %NULL.\n'
                ' * @callback: a #GAsyncReadyCallback to call when the request is satisfied.\n'
                ' * @user_data: user data to pass to @callback.\n'
                ' *\n'
                ' * Asynchronously sends a ${message_name} request to the device.\n'
                ' *\n'
                ' * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from.\n'
                ' *\n'
                ' * You can then call ${underscore}_${message_underscore}_finish() to get the result of the operation.\n'
                ' */\n'
                'void\n'
                '${underscore}_${message_underscore} (\n'
                '    ${camelcase} *self,\n')
            template += ('    %s,\n' % input_arg_template)
            template += (
                '    guint timeout,\n'
                '    GCancellable *cancellable,\n'
                '    GAsyncReadyCallback callback,\n'
                '    gpointer user_data)\n'
                '{\n'
                '    GSimpleAsyncResult *result;\n'
                '    QmiMessage *request;\n'
                '    GError *error = NULL;\n'
                '    guint16 transaction_id;\n'
                '\n'
                '    result = g_simple_async_result_new (G_OBJECT (self),\n'
                '                                        callback,\n'
                '                                        user_data,\n'
                '                                        ${underscore}_${message_underscore});\n'
                '\n'
                '    transaction_id = qmi_client_get_next_transaction_id (QMI_CLIENT (self));\n'
                '\n'
                '    request = __${message_fullname_underscore}_request_create (\n'
                '                  transaction_id,\n'
                '                  qmi_client_get_cid (QMI_CLIENT (self)),\n'
                '                  ${input_var},\n'
                '                  &error);\n'
                '    if (!request) {\n'
                '        g_prefix_error (&error, "Couldn\'t create request message: ");\n'
                '        g_simple_async_result_take_error (result, error);\n'
                '        g_simple_async_result_complete_in_idle (result);\n'
                '        g_object_unref (result);\n'
                '        return;\n'
                '    }\n')

            if message.abort:
                template += (
                    '\n'
                    '    g_object_set_data (G_OBJECT (result),\n'
                    '                       "transaction-id",\n'
                    '                       GUINT_TO_POINTER (transaction_id));\n'
                )

            template += (
                '\n'
                '    qmi_device_command (QMI_DEVICE (qmi_client_peek_device (QMI_CLIENT (self))),\n'
                '                        request,\n'
                '                        timeout,\n'
                '                        cancellable,\n'
                '                        (GAsyncReadyCallback)${message_underscore}_ready,\n'
                '                        result);\n'
                '    qmi_message_unref (request);\n'
                '}\n'
                '\n')
            cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 46
0
    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,
                         'message_type_upper'       : message_type.upper(),
                         'service_underscore_upper' : utils.build_underscore_name (self.service).upper(),
                         'cid_enum_name'            : self.cid_enum_name }
        template = (
            '\n'
            'MbimMessage *${underscore}_${message_type}_new (\n')

        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'] == 'byte-array':
                inner_template = ('    const guint8 *${field},\n')
            elif field['format'] == 'unsized-byte-array' or \
                 field['format'] == 'ref-byte-array' or \
                 field['format'] == 'ref-byte-array-no-offset':
                inner_template = ('    const guint32 ${field}_size,\n'
                                  '    const guint8 *${field},\n')
            elif 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')
        hfile.write(string.Template(template).substitute(translations))

        template = (
            '\n'
            '/**\n'
            ' * ${underscore}_${message_type}_new:\n')

        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']
            translations['array_size'] = field['array-size'] if 'array-size' in field else ''

            if field['format'] == 'byte-array':
                inner_template = (' * @${field}: the \'${name}\' field, given as an array of ${array_size} #guint8 values.\n')
            elif field['format'] == 'unsized-byte-array' or \
                 field['format'] == 'ref-byte-array' or \
                 field['format'] == 'ref-byte-array-no-offset':
                inner_template = (' * @${field}_size: size of the ${field} array.\n'
                                  ' * @${field}: the \'${name}\' field, given as an array of #guint8 values.\n')
            elif 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 \'${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')

        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']
            translations['array_size'] = field['array-size'] if 'array-size' in field else ''

            if field['format'] == 'byte-array':
                inner_template = ('    const guint8 *${field},\n')
            elif field['format'] == 'unsized-byte-array' or \
                 field['format'] == 'ref-byte-array' or \
                 field['format'] == 'ref-byte-array-no-offset':
                inner_template = ('    const guint32 ${field}_size,\n'
                                  '    const guint8 *${field},\n')
            elif 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'
            '{\n'
            '    MbimMessageCommandBuilder *builder;\n'
            '\n'
            '    builder = _mbim_message_command_builder_new (0,\n'
            '                                                 MBIM_SERVICE_${service_underscore_upper},\n'
            '                                                 ${cid_enum_name},\n'
            '                                                 MBIM_MESSAGE_COMMAND_TYPE_${message_type_upper});\n')

        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'])
            translations['array_size'] = field['array-size'] if 'array-size' in field else ''
            translations['pad_array'] = field['pad-array'] if 'pad-array' in field else 'TRUE'

            inner_template = ''
            if 'available-if' in field:
                condition = field['available-if']
                translations['condition_field'] = utils.build_underscore_name_from_camelcase(condition['field'])
                translations['condition_operation'] = condition['operation']
                translations['condition_value'] = condition['value']
                inner_template += (
                    '    if (${condition_field} ${condition_operation} ${condition_value}) {\n')
            else:
                inner_template += ('    {\n')

            if field['format'] == 'byte-array':
                inner_template += ('        _mbim_message_command_builder_append_byte_array (builder, FALSE, FALSE, ${pad_array}, ${field}, ${array_size});\n')
            elif field['format'] == 'unsized-byte-array':
                inner_template += ('        _mbim_message_command_builder_append_byte_array (builder, FALSE, FALSE, ${pad_array}, ${field}, ${field}_size);\n')
            elif field['format'] == 'ref-byte-array':
                inner_template += ('        _mbim_message_command_builder_append_byte_array (builder, TRUE, TRUE, ${pad_array}, ${field}, ${field}_size);\n')
            elif field['format'] == 'ref-byte-array-no-offset':
                inner_template += ('        _mbim_message_command_builder_append_byte_array (builder, FALSE, TRUE, ${pad_array}, ${field}, ${field}_size);\n')
            elif 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')
            else:
                raise ValueError('Cannot handle field type \'%s\'' % field['format'])

            inner_template += ('    }\n')

            template += (string.Template(inner_template).substitute(translations))

        template += (
            '\n'
            '    return _mbim_message_command_builder_complete (builder);\n'
            '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 47
0
    def emit_printable(self, hfile, cfile):
        translations = {
            'service_underscore': utils.build_underscore_name(self.service),
            'service': self.service
        }

        template = (
            '\n'
            '/*****************************************************************************/\n'
            '/* Service helper for printable fields */\n'
            '\n'
            '#if defined (LIBMBIM_GLIB_COMPILATION)\n'
            '\n'
            'G_GNUC_INTERNAL\n'
            'gchar *\n'
            '__mbim_message_${service_underscore}_get_printable_fields (\n'
            '    const MbimMessage *message,\n'
            '    const gchar *line_prefix,\n'
            '    GError **error);\n'
            '\n'
            '#endif\n')
        hfile.write(string.Template(template).substitute(translations))

        template = (
            '\n'
            'typedef struct {\n'
            '  gchar * (* query_cb)        (const MbimMessage *message, const gchar *line_prefix, GError **error);\n'
            '  gchar * (* set_cb)          (const MbimMessage *message, const gchar *line_prefix, GError **error);\n'
            '  gchar * (* response_cb)     (const MbimMessage *message, const gchar *line_prefix, GError **error);\n'
            '  gchar * (* notification_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n'
            '} GetPrintableCallbacks;\n'
            '\n'
            'static const GetPrintableCallbacks get_printable_callbacks[] = {\n'
        )

        for item in self.command_list:
            translations['message'] = utils.build_underscore_name(
                item.fullname)
            translations['cid'] = item.cid_enum_name
            inner_template = ('    [${cid}] = {\n')
            if item.has_query:
                inner_template += (
                    '        .query_cb = ${message}_query_get_printable,\n')
            if item.has_set:
                inner_template += (
                    '        .set_cb = ${message}_set_get_printable,\n')
            if item.has_response:
                inner_template += (
                    '        .response_cb = ${message}_response_get_printable,\n'
                )
            if item.has_notification:
                inner_template += (
                    '        .notification_cb = ${message}_notification_get_printable,\n'
                )
            inner_template += ('    },\n')
            template += (
                string.Template(inner_template).substitute(translations))

        template += (
            '};\n'
            '\n'
            'gchar *\n'
            '__mbim_message_${service_underscore}_get_printable_fields (\n'
            '    const MbimMessage *message,\n'
            '    const gchar *line_prefix,\n'
            '    GError **error)\n'
            '{\n'
            '    guint32 cid;\n'
            '\n'
            '    switch (mbim_message_get_message_type (message)) {\n'
            '        case MBIM_MESSAGE_TYPE_COMMAND: {\n'
            '            cid = mbim_message_command_get_cid (message);\n'
            '            if (cid < G_N_ELEMENTS (get_printable_callbacks)) {\n'
            '                switch (mbim_message_command_get_command_type (message)) {\n'
            '                    case MBIM_MESSAGE_COMMAND_TYPE_QUERY:\n'
            '                        if (get_printable_callbacks[cid].query_cb)\n'
            '                            return get_printable_callbacks[cid].query_cb (message, line_prefix, error);\n'
            '                        break;\n'
            '                    case MBIM_MESSAGE_COMMAND_TYPE_SET:\n'
            '                        if (get_printable_callbacks[cid].set_cb)\n'
            '                            return get_printable_callbacks[cid].set_cb (message, line_prefix, error);\n'
            '                        break;\n'
            '                    default:\n'
            '                        g_set_error (error,\n'
            '                                     MBIM_CORE_ERROR,\n'
            '                                     MBIM_CORE_ERROR_INVALID_MESSAGE,\n'
            '                                     \"Invalid command type\");\n'
            '                        return NULL;\n'
            '                }\n'
            '            }\n'
            '            break;\n'
            '        }\n'
            '\n'
            '        case MBIM_MESSAGE_TYPE_COMMAND_DONE:\n'
            '            cid = mbim_message_command_done_get_cid (message);\n'
            '            if (cid < G_N_ELEMENTS (get_printable_callbacks)) {\n'
            '                if (get_printable_callbacks[cid].response_cb)\n'
            '                    return get_printable_callbacks[cid].response_cb (message, line_prefix, error);\n'
            '            }\n'
            '            break;\n'
            '\n'
            '        case MBIM_MESSAGE_TYPE_INDICATE_STATUS:\n'
            '            cid = mbim_message_indicate_status_get_cid (message);\n'
            '            if (cid < G_N_ELEMENTS (get_printable_callbacks)) {\n'
            '                if (get_printable_callbacks[cid].notification_cb)\n'
            '                    return get_printable_callbacks[cid].notification_cb (message, line_prefix, error);\n'
            '            }\n'
            '            break;\n'
            '\n'
            '        default:\n'
            '            g_set_error (error,\n'
            '                         MBIM_CORE_ERROR,\n'
            '                         MBIM_CORE_ERROR_INVALID_MESSAGE,\n'
            '                         \"No contents expected in this message type\");\n'
            '            return NULL;\n'
            '    }\n'
            '\n'
            '    g_set_error (error,\n'
            '                 MBIM_CORE_ERROR,\n'
            '                 MBIM_CORE_ERROR_INVALID_MESSAGE,\n'
            '                 \"Unknown contents\");\n'
            '    return NULL;\n'
            '}\n')

        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 48
0
    def __emit_methods(self, hfile, cfile, message_list):
        translations = {
            'underscore': utils.build_underscore_name(self.name),
            'camelcase': utils.build_camelcase_name(self.name),
            'service_lowercase': self.service.lower(),
            'service_uppercase': self.service.upper(),
            'service_camelcase': string.capwords(self.service)
        }

        for message in message_list.request_list:
            if message.static:
                continue

            translations['message_name'] = message.name
            translations['message_vendor_id'] = message.vendor
            translations['message_underscore'] = utils.build_underscore_name(
                message.name)
            translations[
                'message_fullname_underscore'] = utils.build_underscore_name(
                    message.fullname)
            translations['input_camelcase'] = utils.build_camelcase_name(
                message.input.fullname)
            translations['output_camelcase'] = utils.build_camelcase_name(
                message.output.fullname)
            translations['input_underscore'] = utils.build_underscore_name(
                message.input.fullname)
            translations['output_underscore'] = utils.build_underscore_name(
                message.output.fullname)
            translations['message_since'] = message.since

            if message.input.fields is None:
                translations['input_arg'] = 'gpointer unused'
                translations['input_var'] = 'NULL'
                translations[
                    'input_doc'] = 'unused: %NULL. This message doesn\'t have any input bundle.'
            else:
                translations[
                    'input_arg'] = translations['input_camelcase'] + ' *input'
                translations['input_var'] = 'input'
                translations['input_doc'] = 'input: a #' + translations[
                    'input_camelcase'] + '.'
            template = (
                '\n'
                '/**\n'
                ' * ${underscore}_${message_underscore}:\n'
                ' * @self: a #${camelcase}.\n'
                ' * @${input_doc}\n'
                ' * @timeout: maximum time to wait for the method to complete, in seconds.\n'
                ' * @cancellable: a #GCancellable or %NULL.\n'
                ' * @callback: a #GAsyncReadyCallback to call when the request is satisfied.\n'
                ' * @user_data: user data to pass to @callback.\n'
                ' *\n'
                ' * Asynchronously sends a ${message_name} request to the device.\n'
            )

            if message.abort:
                template += (
                    ' *\n'
                    ' * This message is abortable. If @cancellable is cancelled or if @timeout expires,\n'
                    ' * an abort request will be sent to the device, and the asynchronous operation will\n'
                    ' * not return until the abort response is received. It is not an error if a successful\n'
                    ' * response is returned for the asynchronous operation even after the user has cancelled\n'
                    ' * the cancellable, because it may happen that the response is received before the\n'
                    ' * modem had a chance to run the abort.\n')

            template += (
                ' *\n'
                ' * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from.\n'
                ' *\n'
                ' * You can then call ${underscore}_${message_underscore}_finish() to get the result of the operation.\n'
                ' *\n'
                ' * Since: ${message_since}\n'
                ' */\n'
                'void ${underscore}_${message_underscore} (\n'
                '    ${camelcase} *self,\n'
                '    ${input_arg},\n'
                '    guint timeout,\n'
                '    GCancellable *cancellable,\n'
                '    GAsyncReadyCallback callback,\n'
                '    gpointer user_data);\n'
                '\n'
                '/**\n'
                ' * ${underscore}_${message_underscore}_finish:\n'
                ' * @self: a #${camelcase}.\n'
                ' * @res: the #GAsyncResult obtained from the #GAsyncReadyCallback passed to ${underscore}_${message_underscore}().\n'
                ' * @error: Return location for error or %NULL.\n'
                ' *\n'
                ' * Finishes an async operation started with ${underscore}_${message_underscore}().\n'
                ' *\n'
                ' * Returns: a #${output_camelcase}, or %NULL if @error is set. The returned value should be freed with ${output_underscore}_unref().\n'
                ' *\n'
                ' * Since: ${message_since}\n'
                ' */\n'
                '${output_camelcase} *${underscore}_${message_underscore}_finish (\n'
                '    ${camelcase} *self,\n'
                '    GAsyncResult *res,\n'
                '    GError **error);\n')
            hfile.write(string.Template(template).substitute(translations))

            template = (
                '\n'
                '${output_camelcase} *\n'
                '${underscore}_${message_underscore}_finish (\n'
                '    ${camelcase} *self,\n'
                '    GAsyncResult *res,\n'
                '    GError **error)\n'
                '{\n'
                '   return g_task_propagate_pointer (G_TASK (res), error);\n'
                '}\n')

            if message.abort:
                template += (
                    '\n'
                    '#if defined HAVE_QMI_MESSAGE_${service_uppercase}_ABORT\n'
                    '\n'
                    'static QmiMessage *\n'
                    '__${message_fullname_underscore}_abortable_build_request (\n'
                    '    QmiDevice   *self,\n'
                    '    QmiMessage  *message,\n'
                    '    QmiClient   *client,\n'
                    '    GError     **error)\n'
                    '{\n'
                    '    QmiMessage *abort_request;\n'
                    '    guint16 transaction_id;\n'
                    '    g_autoptr(QmiMessage${service_camelcase}AbortInput) input = NULL;\n'
                    '\n'
                    '    transaction_id = qmi_message_get_transaction_id (message);\n'
                    '    g_assert (transaction_id != 0);\n'
                    '\n'
                    '    input = qmi_message_${service_lowercase}_abort_input_new ();\n'
                    '    qmi_message_${service_lowercase}_abort_input_set_transaction_id (\n'
                    '        input,\n'
                    '        transaction_id,\n'
                    '        NULL);\n'
                    '    abort_request = __qmi_message_${service_lowercase}_abort_request_create (\n'
                    '                        qmi_client_get_next_transaction_id (client),\n'
                    '                        qmi_client_get_cid (client),\n'
                    '                        input,\n'
                    '                        NULL);\n'
                    '    return abort_request;\n'
                    '}\n'
                    '\n'
                    'static gboolean\n'
                    '__${message_fullname_underscore}_abortable_parse_response (\n'
                    '    QmiDevice   *self,\n'
                    '    QmiMessage  *abort_response,\n'
                    '    QmiClient   *client,\n'
                    '    GError     **error)\n'
                    '{\n'
                    '    g_autoptr(QmiMessage${service_camelcase}AbortOutput) output = NULL;\n'
                    '\n'
                    '    output = __qmi_message_${service_lowercase}_abort_response_parse (\n'
                    '               abort_response,\n'
                    '               error);\n'
                    '    return !!output;\n'
                    '}\n'
                    '\n'
                    '#endif /* HAVE_QMI_MESSAGE_${service_uppercase}_ABORT */\n'
                    '\n')

            template += ('\n'
                         'static void\n'
                         '${message_underscore}_ready (\n'
                         '    QmiDevice *device,\n'
                         '    GAsyncResult *res,\n'
                         '    GTask *task)\n'
                         '{\n'
                         '    GError *error = NULL;\n'
                         '    QmiMessage *reply;\n'
                         '    ${output_camelcase} *output;\n'
                         '\n')

            if message.abort:
                template += (
                    '    reply = qmi_device_command_abortable_finish (device, res, &error);\n'
                )
            else:
                template += (
                    '    reply = qmi_device_command_full_finish (device, res, &error);\n'
                )

            template += ('    if (!reply) {\n')

            template += (
                '        g_task_return_error (task, error);\n'
                '        g_object_unref (task);\n'
                '        return;\n'
                '    }\n'
                '\n'
                '    /* Parse reply */\n'
                '    output = __${message_fullname_underscore}_response_parse (reply, &error);\n'
                '    if (!output)\n'
                '        g_task_return_error (task, error);\n'
                '    else\n'
                '        g_task_return_pointer (task,\n'
                '                               output,\n'
                '                               (GDestroyNotify)${output_underscore}_unref);\n'
                '    g_object_unref (task);\n'
                '    qmi_message_unref (reply);\n'
                '}\n'
                '\n'
                'void\n'
                '${underscore}_${message_underscore} (\n'
                '    ${camelcase} *self,\n'
                '    ${input_arg},\n'
                '    guint timeout,\n'
                '    GCancellable *cancellable,\n'
                '    GAsyncReadyCallback callback,\n'
                '    gpointer user_data)\n'
                '{\n'
                '    GTask *task;\n'
                '    GError *error = NULL;\n'
                '    guint16 transaction_id;\n'
                '    g_autoptr(QmiMessage) request = NULL;\n')

            if message.vendor is not None:
                template += (
                    '    g_autoptr(QmiMessageContext) context = NULL;\n')

            template += (
                '\n'
                '    task = g_task_new (self, cancellable, callback, user_data);\n'
                '    if (!qmi_client_is_valid (QMI_CLIENT (self))) {\n'
                '        g_task_return_new_error (task, QMI_CORE_ERROR, QMI_CORE_ERROR_WRONG_STATE, "client invalid");\n'
                '        g_object_unref (task);\n'
                '        return;\n'
                '    }\n'
                '\n'
                '    transaction_id = qmi_client_get_next_transaction_id (QMI_CLIENT (self));\n'
                '\n'
                '    request = __${message_fullname_underscore}_request_create (\n'
                '                  transaction_id,\n'
                '                  qmi_client_get_cid (QMI_CLIENT (self)),\n'
                '                  ${input_var},\n'
                '                  &error);\n'
                '    if (!request) {\n'
                '        g_prefix_error (&error, "Couldn\'t create request message: ");\n'
                '        g_task_return_error (task, error);\n'
                '        g_object_unref (task);\n'
                '        return;\n'
                '    }\n')

            if message.vendor is not None:
                template += (
                    '\n'
                    '    context = qmi_message_context_new ();\n'
                    '    qmi_message_context_set_vendor_id (context, ${message_vendor_id});\n'
                )

            if message.abort:
                template += (
                    '\n'
                    '    qmi_device_command_abortable (QMI_DEVICE (qmi_client_peek_device (QMI_CLIENT (self))),\n'
                )
            else:
                template += (
                    '\n'
                    '    qmi_device_command_full (QMI_DEVICE (qmi_client_peek_device (QMI_CLIENT (self))),\n'
                )

            template += ('                             request,\n')

            if message.vendor is not None:
                template += ('                             context,\n')
            else:
                template += ('                             NULL,\n')

            template += ('                             timeout,\n')

            if message.abort:
                template += (
                    '#if defined HAVE_QMI_MESSAGE_${service_uppercase}_ABORT\n'
                    '                             (QmiDeviceCommandAbortableBuildRequestFn)  __${message_fullname_underscore}_abortable_build_request,\n'
                    '                             (QmiDeviceCommandAbortableParseResponseFn) __${message_fullname_underscore}_abortable_parse_response,\n'
                    '                             g_object_ref (self),\n'
                    '                             g_object_unref,\n'
                    '#else\n'
                    '                             NULL,\n'
                    '                             NULL,\n'
                    '                             NULL,\n'
                    '                             NULL,\n'
                    '#endif\n')

            template += (
                '                             cancellable,\n'
                '                             (GAsyncReadyCallback)${message_underscore}_ready,\n'
                '                             task);\n')

            template += ('}\n' '\n')
            cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 49
0
    def __emit_get_printable(self, hfile, cfile):
        translations = { 'service'    : self.service.lower() }

        template = (
            '\n'
            '#if defined (LIBQMI_GLIB_COMPILATION)\n'
            '\n'
            'G_GNUC_INTERNAL\n'
            'gchar *__qmi_message_${service}_get_printable (\n'
            '    QmiMessage *self,\n'
            '    QmiMessageContext *context,\n'
            '    const gchar *line_prefix);\n'
            '\n'
            '#endif\n'
            '\n')
        hfile.write(string.Template(template).substitute(translations))

        template = (
            '\n'
            'gchar *\n'
            '__qmi_message_${service}_get_printable (\n'
            '    QmiMessage *self,\n'
            '    QmiMessageContext *context,\n'
            '    const gchar *line_prefix)\n'
            '{\n'
            '    if (qmi_message_is_indication (self)) {\n'
            '        switch (qmi_message_get_message_id (self)) {\n')

        for message in self.list:
            if message.type == 'Indication':
                translations['enum_name'] = message.id_enum_name
                translations['message_underscore'] = utils.build_underscore_name (message.name)
                inner_template = (
                    '        case ${enum_name}:\n'
                    '            return indication_${message_underscore}_get_printable (self, line_prefix);\n')
                template += string.Template(inner_template).substitute(translations)

        template += (
            '        default:\n'
            '             return NULL;\n'
            '        }\n'
            '    } else {\n'
            '        guint16 vendor_id;\n'
            '\n'
            '        vendor_id = (context ? qmi_message_context_get_vendor_id (context) : QMI_MESSAGE_VENDOR_GENERIC);\n'
            '        if (vendor_id == QMI_MESSAGE_VENDOR_GENERIC) {\n'
            '            switch (qmi_message_get_message_id (self)) {\n')

        for message in self.list:
            if message.type == 'Message' and message.vendor is None:
                translations['enum_name'] = message.id_enum_name
                translations['message_underscore'] = utils.build_underscore_name (message.name)
                inner_template = (
                    '            case ${enum_name}:\n'
                    '                return message_${message_underscore}_get_printable (self, line_prefix);\n')
                template += string.Template(inner_template).substitute(translations)

        template += (
            '             default:\n'
            '                 return NULL;\n'
            '            }\n'
            '        } else {\n')

        for message in self.list:
            if message.type == 'Message' and message.vendor is not None:
                translations['enum_name'] = message.id_enum_name
                translations['message_underscore'] = utils.build_underscore_name (message.name)
                translations['message_vendor'] = message.vendor
                inner_template = (
                    '            if (vendor_id == ${message_vendor} && (qmi_message_get_message_id (self) == ${enum_name}))\n'
                    '                return message_${message_underscore}_get_printable (self, line_prefix);\n')
                template += string.Template(inner_template).substitute(translations)

        template += (
            '            return NULL;\n'
            '        }\n'
            '    }\n'
            '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 50
0
    def emit_getter(self, hfile, cfile):
        input_variable_name = 'value_' + utils.build_underscore_name(self.name)
        variable_getter_dec = self.variable.build_getter_declaration('    ', input_variable_name)
        variable_getter_doc = self.variable.build_getter_documentation(' * ', input_variable_name)
        variable_getter_imp = self.variable.build_getter_implementation('    ', 'self->' + self.variable_name, input_variable_name, True)
        translations = { 'name'                : self.name,
                         'variable_name'       : self.variable_name,
                         'variable_getter_dec' : variable_getter_dec,
                         'variable_getter_doc' : variable_getter_doc,
                         'variable_getter_imp' : variable_getter_imp,
                         'underscore'          : utils.build_underscore_name(self.name),
                         'prefix_camelcase'    : utils.build_camelcase_name(self.prefix),
                         'prefix_underscore'   : utils.build_underscore_name(self.prefix),
                         'since'               : self.since,
                         'static'              : 'static ' if self.static else '' }

        # Emit the getter header
        template = (
            '\n'
            '/**\n'
            ' * ${prefix_underscore}_get_${underscore}:\n'
            ' * @self: a #${prefix_camelcase}.\n'
            '${variable_getter_doc}'
            ' * @error: Return location for error or %NULL.\n'
            ' *\n'
            ' * Get the \'${name}\' field from @self.\n'
            ' *\n'
            ' * Returns: %TRUE if the field is found, %FALSE otherwise.\n'
            ' *\n'
            ' * Since: ${since}\n'
            ' */\n'
            '${static}gboolean ${prefix_underscore}_get_${underscore} (\n'
            '    ${prefix_camelcase} *self,\n'
            '${variable_getter_dec}'
            '    GError **error);\n')
        hfile.write(string.Template(template).substitute(translations))

        # Emit the getter source
        template = (
            '\n'
            '${static}gboolean\n'
            '${prefix_underscore}_get_${underscore} (\n'
            '    ${prefix_camelcase} *self,\n'
            '${variable_getter_dec}'
            '    GError **error)\n'
            '{\n'
            '    g_return_val_if_fail (self != NULL, FALSE);\n'
            '\n'
            '    if (!self->${variable_name}_set) {\n'
            '        g_set_error (error,\n'
            '                     QMI_CORE_ERROR,\n'
            '                     QMI_CORE_ERROR_TLV_NOT_FOUND,\n'
            '                     "Field \'${name}\' was not found in the message");\n'
            '        return FALSE;\n'
            '    }\n'
            '\n'
            '${variable_getter_imp}'
            '\n'
            '    return TRUE;\n'
            '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 51
0
    def emit_tlv_helpers(self, f):
        if TypeFactory.helpers_emitted(self.fullname):
            return

        TypeFactory.set_helpers_emitted(self.fullname)

        translations = {
            'name': self.name,
            'tlv_id': self.id_enum_name,
            'underscore': utils.build_underscore_name(self.fullname)
        }

        template = (
            '\n'
            'static gboolean\n'
            '${underscore}_validate (\n'
            '    const guint8 *buffer,\n'
            '    guint16 buffer_len)\n'
            '{\n'
            '    static const guint expected_len = 4;\n'
            '\n'
            '    if (buffer_len < expected_len) {\n'
            '        g_warning ("Cannot read the \'${name}\' TLV: expected \'%u\' bytes, but only got \'%u\' bytes",\n'
            '                   expected_len, buffer_len);\n'
            '        return FALSE;\n'
            '    }\n'
            '\n'
            '    return TRUE;\n'
            '}\n')
        f.write(string.Template(template).substitute(translations))

        template = (
            '\n'
            'static gchar *\n'
            '${underscore}_get_printable (\n'
            '    QmiMessage *self,\n'
            '    const gchar *line_prefix)\n'
            '{\n'
            '    const guint8 *buffer;\n'
            '    guint16 buffer_len;\n'
            '\n'
            '    buffer = qmi_message_get_raw_tlv (self,\n'
            '                                      ${tlv_id},\n'
            '                                      &buffer_len);\n'
            '    if (buffer) {\n'
            '        GString *printable;\n'
            '        guint16 error_status;\n'
            '        guint16 error_code;\n'
            '\n'
            '        printable = g_string_new ("");\n'
            '        qmi_utils_read_guint16_from_buffer (\n'
            '            &buffer,\n'
            '            &buffer_len,\n'
            '            QMI_ENDIAN_LITTLE,\n'
            '            &error_status);\n'
            '        qmi_utils_read_guint16_from_buffer (\n'
            '            &buffer,\n'
            '            &buffer_len,\n'
            '            QMI_ENDIAN_LITTLE,\n'
            '            &error_code);\n'
            '\n'
            '        g_warn_if_fail (buffer_len == 0);\n'
            '\n'
            '        if (error_status == QMI_STATUS_SUCCESS)\n'
            '            g_string_append (printable, "SUCCESS");\n'
            '        else\n'
            '            g_string_append_printf (printable,\n'
            '                                    "FAILURE: %s",\n'
            '                                    qmi_protocol_error_get_string ((QmiProtocolError) error_code));\n'
            '\n'
            '        return g_string_free (printable, FALSE);\n'
            '    }\n'
            '\n'
            '    return NULL;\n'
            '}\n')
        f.write(string.Template(template).substitute(translations))
Ejemplo n.º 52
0
    def emit_printable_service(self, hfile, cfile, service):
        translations = { 'service_underscore' : utils.build_underscore_name(service),
                         'service'            : service }

        template = (
            '\n'
            'G_GNUC_INTERNAL\n'
            'gchar *\n'
            '__mbim_message_${service_underscore}_get_printable_fields (\n'
            '    const MbimMessage *message,\n'
            '    const gchar *line_prefix,\n'
            '    GError **error);\n')
        hfile.write(string.Template(template).substitute(translations))

        template = (
            '\n'
            'static const GetPrintableCallbacks ${service_underscore}_get_printable_callbacks[] = {\n')

        for item in self.command_list:
            if item.service == service:
                translations['message'] = utils.build_underscore_name (item.fullname)
                translations['cid']     = item.cid_enum_name
                inner_template = (
                    '    [${cid}] = {\n')
                if item.has_query:
                    inner_template += (
                        '        .query_cb = ${message}_query_get_printable,\n')
                if item.has_set:
                    inner_template += (
                        '        .set_cb = ${message}_set_get_printable,\n')
                if item.has_response:
                    inner_template += (
                        '        .response_cb = ${message}_response_get_printable,\n')
                if item.has_notification:
                    inner_template += (
                        '        .notification_cb = ${message}_notification_get_printable,\n')
                inner_template += (
                    '    },\n')
                template += (string.Template(inner_template).substitute(translations))

        template += (
            '};\n'
            '\n'
            'gchar *\n'
            '__mbim_message_${service_underscore}_get_printable_fields (\n'
            '    const MbimMessage *message,\n'
            '    const gchar *line_prefix,\n'
            '    GError **error)\n'
            '{\n'
            '    guint32 cid;\n'
            '\n'
            '    switch (mbim_message_get_message_type (message)) {\n'
            '        case MBIM_MESSAGE_TYPE_COMMAND: {\n'
            '            cid = mbim_message_command_get_cid (message);\n'
            '            if (cid < G_N_ELEMENTS (${service_underscore}_get_printable_callbacks)) {\n'
            '                switch (mbim_message_command_get_command_type (message)) {\n'
            '                    case MBIM_MESSAGE_COMMAND_TYPE_QUERY:\n'
            '                        if (${service_underscore}_get_printable_callbacks[cid].query_cb)\n'
            '                            return ${service_underscore}_get_printable_callbacks[cid].query_cb (message, line_prefix, error);\n'
            '                        break;\n'
            '                    case MBIM_MESSAGE_COMMAND_TYPE_SET:\n'
            '                        if (${service_underscore}_get_printable_callbacks[cid].set_cb)\n'
            '                            return ${service_underscore}_get_printable_callbacks[cid].set_cb (message, line_prefix, error);\n'
            '                        break;\n'
            '                    case MBIM_MESSAGE_COMMAND_TYPE_UNKNOWN:\n'
            '                    default:\n'
            '                        g_set_error (error,\n'
            '                                     MBIM_CORE_ERROR,\n'
            '                                     MBIM_CORE_ERROR_INVALID_MESSAGE,\n'
            '                                     \"Invalid command type\");\n'
            '                        return NULL;\n'
            '                }\n'
            '            }\n'
            '            break;\n'
            '        }\n'
            '\n'
            '        case MBIM_MESSAGE_TYPE_COMMAND_DONE:\n'
            '            cid = mbim_message_command_done_get_cid (message);\n'
            '            if (cid < G_N_ELEMENTS (${service_underscore}_get_printable_callbacks)) {\n'
            '                if (${service_underscore}_get_printable_callbacks[cid].response_cb)\n'
            '                    return ${service_underscore}_get_printable_callbacks[cid].response_cb (message, line_prefix, error);\n'
            '            }\n'
            '            break;\n'
            '\n'
            '        case MBIM_MESSAGE_TYPE_INDICATE_STATUS:\n'
            '            cid = mbim_message_indicate_status_get_cid (message);\n'
            '            if (cid < G_N_ELEMENTS (${service_underscore}_get_printable_callbacks)) {\n'
            '                if (${service_underscore}_get_printable_callbacks[cid].notification_cb)\n'
            '                    return ${service_underscore}_get_printable_callbacks[cid].notification_cb (message, line_prefix, error);\n'
            '            }\n'
            '            break;\n'
            '\n'
            '        case MBIM_MESSAGE_TYPE_OPEN: \n'
            '        case MBIM_MESSAGE_TYPE_CLOSE: \n'
            '        case MBIM_MESSAGE_TYPE_INVALID: \n'
            '        case MBIM_MESSAGE_TYPE_HOST_ERROR: \n'
            '        case MBIM_MESSAGE_TYPE_OPEN_DONE: \n'
            '        case MBIM_MESSAGE_TYPE_CLOSE_DONE: \n'
            '        case MBIM_MESSAGE_TYPE_FUNCTION_ERROR: \n'
            '        default:\n'
            '            g_set_error (error,\n'
            '                         MBIM_CORE_ERROR,\n'
            '                         MBIM_CORE_ERROR_INVALID_MESSAGE,\n'
            '                         \"No contents expected in this message type\");\n'
            '            return NULL;\n'
            '    }\n'
            '\n'
            '    g_set_error (error,\n'
            '                 MBIM_CORE_ERROR,\n'
            '                 MBIM_CORE_ERROR_UNSUPPORTED,\n'
            '                 \"Unsupported message\");\n'
            '    return NULL;\n'
            '}\n')

        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 53
0
    def emit_buffer_read(self, f, line_prefix, tlv_out, error, variable_name):
        common_var_prefix = utils.build_underscore_name(self.name)
        translations = {
            'lp': line_prefix,
            'variable_name': variable_name,
            'private_format': self.private_format,
            'public_array_element_format': self.array_element.public_format,
            'underscore': self.clear_func_name(),
            'common_var_prefix': common_var_prefix
        }

        template = ('${lp}{\n' '${lp}    guint ${common_var_prefix}_i;\n')
        f.write(string.Template(template).substitute(translations))

        if self.fixed_size:
            translations['fixed_size'] = self.fixed_size

            template = (
                '${lp}    guint16 ${common_var_prefix}_n_items = ${fixed_size};\n'
                '\n')
            f.write(string.Template(template).substitute(translations))
        else:
            translations[
                'array_size_element_format'] = self.array_size_element.public_format
            template = (
                '${lp}    ${array_size_element_format} ${common_var_prefix}_n_items;\n'
            )

            if self.array_sequence_element != '':
                translations[
                    'array_sequence_element_format'] = self.array_sequence_element.public_format
                template += (
                    '${lp}    ${array_sequence_element_format} ${common_var_prefix}_sequence;\n'
                )

            template += ('\n'
                         '${lp}    /* Read number of items in the array */\n')
            f.write(string.Template(template).substitute(translations))
            self.array_size_element.emit_buffer_read(
                f, line_prefix + '    ', tlv_out, error,
                common_var_prefix + '_n_items')

            if self.array_sequence_element != '':
                template = ('\n' '${lp}    /* Read sequence in the array */\n')
                f.write(string.Template(template).substitute(translations))
                self.array_size_element.emit_buffer_read(
                    f, line_prefix + '    ', tlv_out, error,
                    common_var_prefix + '_sequence')

                template = (
                    '\n'
                    '${lp}    ${variable_name}_sequence = ${common_var_prefix}_sequence;\n'
                )
                f.write(string.Template(template).substitute(translations))

        template = ('\n'
                    '${lp}    ${variable_name} = g_array_sized_new (\n'
                    '${lp}        FALSE,\n'
                    '${lp}        FALSE,\n'
                    '${lp}        sizeof (${public_array_element_format}),\n'
                    '${lp}        (guint)${common_var_prefix}_n_items);\n'
                    '\n')

        if self.array_element.needs_dispose == True:
            template += (
                '${lp}    g_array_set_clear_func (${variable_name},\n'
                '${lp}                            (GDestroyNotify)${underscore}_clear);\n'
                '\n')

        template += (
            '${lp}    for (${common_var_prefix}_i = 0; ${common_var_prefix}_i < ${common_var_prefix}_n_items; ${common_var_prefix}_i++) {\n'
            '${lp}        ${public_array_element_format} ${common_var_prefix}_aux;\n'
            '\n')
        f.write(string.Template(template).substitute(translations))

        self.array_element.emit_buffer_read(f, line_prefix + '        ',
                                            tlv_out, error,
                                            common_var_prefix + '_aux')

        template = (
            '${lp}        g_array_insert_val (${variable_name}, ${common_var_prefix}_i, ${common_var_prefix}_aux);\n'
            '${lp}    }\n'
            '${lp}}\n')
        f.write(string.Template(template).substitute(translations))
Ejemplo n.º 54
0
    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,
                         'message_type_upper'       : message_type.upper(),
                         'service_underscore_upper' : utils.build_underscore_name (self.service).upper(),
                         'cid_enum_name'            : self.cid_enum_name }
        template = (
            '\n'
            'MbimMessage *${underscore}_${message_type}_new (\n')

        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'] == 'byte-array':
                inner_template = ('    const guint8 *${field},\n')
            elif field['format'] == 'unsized-byte-array' or \
                 field['format'] == 'ref-byte-array' or \
                 field['format'] == 'ref-byte-array-no-offset':
                inner_template = ('    const guint32 ${field}_size,\n'
                                  '    const guint8 *${field},\n')
            elif 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')
        hfile.write(string.Template(template).substitute(translations))

        template = (
            '\n'
            '/**\n'
            ' * ${underscore}_${message_type}_new:\n')

        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']
            translations['array_size'] = field['array-size'] if 'array-size' in field else ''

            if field['format'] == 'byte-array':
                inner_template = (' * @${field}: the \'${name}\' field, given as an array of ${array_size} #guint8 values.\n')
            elif field['format'] == 'unsized-byte-array' or \
                 field['format'] == 'ref-byte-array' or \
                 field['format'] == 'ref-byte-array-no-offset':
                inner_template = (' * @${field}_size: size of the ${field} array.\n'
                                  ' * @${field}: the \'${name}\' field, given as an array of #guint8 values.\n')
            elif 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 \'${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')

        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']
            translations['array_size'] = field['array-size'] if 'array-size' in field else ''

            if field['format'] == 'byte-array':
                inner_template = ('    const guint8 *${field},\n')
            elif field['format'] == 'unsized-byte-array' or \
                 field['format'] == 'ref-byte-array' or \
                 field['format'] == 'ref-byte-array-no-offset':
                inner_template = ('    const guint32 ${field}_size,\n'
                                  '    const guint8 *${field},\n')
            elif 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'
            '{\n'
            '    MbimMessageCommandBuilder *builder;\n'
            '\n'
            '    builder = _mbim_message_command_builder_new (0,\n'
            '                                                 MBIM_SERVICE_${service_underscore_upper},\n'
            '                                                 ${cid_enum_name},\n'
            '                                                 MBIM_MESSAGE_COMMAND_TYPE_${message_type_upper});\n')

        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'])
            translations['array_size'] = field['array-size'] if 'array-size' in field else ''
            translations['pad_array'] = field['pad-array'] if 'pad-array' in field else 'TRUE'

            inner_template = ''
            if 'available-if' in field:
                condition = field['available-if']
                translations['condition_field'] = utils.build_underscore_name_from_camelcase(condition['field'])
                translations['condition_operation'] = condition['operation']
                translations['condition_value'] = condition['value']
                inner_template += (
                    '    if (${condition_field} ${condition_operation} ${condition_value}) {\n')
            else:
                inner_template += ('    {\n')

            if field['format'] == 'byte-array':
                inner_template += ('        _mbim_message_command_builder_append_byte_array (builder, FALSE, FALSE, ${pad_array}, ${field}, ${array_size});\n')
            elif field['format'] == 'unsized-byte-array':
                inner_template += ('        _mbim_message_command_builder_append_byte_array (builder, FALSE, FALSE, ${pad_array}, ${field}, ${field}_size);\n')
            elif field['format'] == 'ref-byte-array':
                inner_template += ('        _mbim_message_command_builder_append_byte_array (builder, TRUE, TRUE, ${pad_array}, ${field}, ${field}_size);\n')
            elif field['format'] == 'ref-byte-array-no-offset':
                inner_template += ('        _mbim_message_command_builder_append_byte_array (builder, FALSE, TRUE, ${pad_array}, ${field}, ${field}_size);\n')
            elif 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')
            else:
                raise ValueError('Cannot handle field type \'%s\'' % field['format'])

            inner_template += ('    }\n')

            template += (string.Template(inner_template).substitute(translations))

        template += (
            '\n'
            '    return _mbim_message_command_builder_complete (builder);\n'
            '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 55
0
    def emit_get_printable(self, f, line_prefix):
        common_var_prefix = utils.build_underscore_name(self.name)
        translations = {
            'lp': line_prefix,
            'common_var_prefix': common_var_prefix
        }

        template = ('${lp}{\n' '${lp}    guint ${common_var_prefix}_i;\n')
        f.write(string.Template(template).substitute(translations))

        if self.fixed_size:
            translations['fixed_size'] = self.fixed_size

            template = (
                '${lp}    guint16 ${common_var_prefix}_n_items = ${fixed_size};\n'
                '\n')
            f.write(string.Template(template).substitute(translations))
        else:
            translations[
                'array_size_element_format'] = self.array_size_element.public_format
            template = (
                '${lp}    ${array_size_element_format} ${common_var_prefix}_n_items;\n'
            )

            if self.array_sequence_element != '':
                translations[
                    'array_sequence_element_format'] = self.array_sequence_element.public_format
                template += (
                    '${lp}    ${array_sequence_element_format} ${common_var_prefix}_sequence;\n'
                )

            template += ('\n'
                         '${lp}    /* Read number of items in the array */\n')
            f.write(string.Template(template).substitute(translations))
            self.array_size_element.emit_buffer_read(
                f, line_prefix + '    ', 'out', '&error',
                common_var_prefix + '_n_items')

            if self.array_sequence_element != '':
                template = ('\n' '${lp}    /* Read sequence */\n')
                f.write(string.Template(template).substitute(translations))
                self.array_sequence_element.emit_buffer_read(
                    f, line_prefix + '    ', 'out', '&error',
                    common_var_prefix + '_sequence')
                template = (
                    '\n'
                    '${lp}    g_string_append_printf (printable, "[[Seq:%u]] ", ${common_var_prefix}_sequence);\n'
                )
                f.write(string.Template(template).substitute(translations))

        template = (
            '\n'
            '${lp}    g_string_append (printable, "{");\n'
            '\n'
            '${lp}    for (${common_var_prefix}_i = 0; ${common_var_prefix}_i < ${common_var_prefix}_n_items; ${common_var_prefix}_i++) {\n'
            '${lp}        g_string_append_printf (printable, " [%u] = \'", ${common_var_prefix}_i);\n'
        )
        f.write(string.Template(template).substitute(translations))

        self.array_element.emit_get_printable(f, line_prefix + '        ')

        template = ('${lp}        g_string_append (printable, " \'");\n'
                    '${lp}    }\n'
                    '\n'
                    '${lp}    g_string_append (printable, "}");\n'
                    '${lp}}')
        f.write(string.Template(template).substitute(translations))
Ejemplo n.º 56
0
    def _emit_message_parser(self, hfile, cfile, message_type, fields):
        translations = { 'name'                     : self.name,
                         'service'                  : self.service,
                         'underscore'               : utils.build_underscore_name (self.fullname),
                         'message_type'             : message_type,
                         'message_type_upper'       : message_type.upper(),
                         'service_underscore_upper' : utils.build_underscore_name (self.service).upper() }
        template = (
            '\n'
            'gboolean ${underscore}_${message_type}_parse (\n'
            '    const MbimMessage *message,\n')

        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'] == 'byte-array':
                inner_template = ('    const guint8 **${field},\n')
            elif field['format'] == 'unsized-byte-array' or field['format'] == 'ref-byte-array':
                inner_template = ('    guint32 *${field}_size,\n'
                                  '    const guint8 **${field},\n')
            elif 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')
            else:
                raise ValueError('Cannot handle field type \'%s\'' % field['format'])

            template += (string.Template(inner_template).substitute(translations))

        template += (
            '    GError **error);\n')
        hfile.write(string.Template(template).substitute(translations))

        template = (
            '\n'
            '/**\n'
            ' * ${underscore}_${message_type}_parse:\n'
            ' * @message: the #MbimMessage.\n')

        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'])
            translations['array_size'] = field['array-size'] if 'array-size' in field else ''

            if field['format'] == 'byte-array':
                inner_template = (' * @${field}: return location for an array of ${array_size} #guint8 values. Do not free the returned value, it is owned by @message.\n')
            elif field['format'] == 'unsized-byte-array' or field['format'] == 'ref-byte-array':
                inner_template = (' * @${field}_size: return location for the size of the ${field} array.\n'
                                  ' * @${field}: return location for an array of #guint8 values. Do not free the returned value, it is owned by @message.\n')
            elif 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'
            ' *\n'
            ' * Create a new request for the \'${name}\' ${message_type} command in the \'${service}\' service.\n'
            ' *\n'
            ' * Returns: %TRUE if the message was correctly parsed, %FALSE if @error is set.\n'
            ' */\n'
            'gboolean\n'
            '${underscore}_${message_type}_parse (\n'
            '    const MbimMessage *message,\n')

        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'] == 'byte-array':
                inner_template = ('    const guint8 **${field},\n')
            elif field['format'] == 'unsized-byte-array' or field['format'] == 'ref-byte-array':
                inner_template = ('    guint32 *${field}_size,\n'
                                  '    const guint8 **${field},\n')
            elif 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')

        if fields != []:
            template += (
                '    guint32 offset = 0;\n')

        for field in fields:
            if 'always-read' in field:
                translations['field'] = utils.build_underscore_name_from_camelcase(field['name'])
                inner_template = ('    guint32 _${field};\n')
                template += (string.Template(inner_template).substitute(translations))

        if message_type == 'response':
            template += (
                '\n'
                '    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_COMMAND_DONE) {\n'
                '        g_set_error (error,\n'
                '                     MBIM_CORE_ERROR,\n'
                '                     MBIM_CORE_ERROR_INVALID_MESSAGE,\n'
                '                     \"Message is not a response\");\n'
                '        return FALSE;\n'
                '    }\n')
        elif message_type == 'notification':
            template += (
                '\n'
                '    if (mbim_message_get_message_type (message) != MBIM_MESSAGE_TYPE_INDICATE_STATUS) {\n'
                '        g_set_error (error,\n'
                '                     MBIM_CORE_ERROR,\n'
                '                     MBIM_CORE_ERROR_INVALID_MESSAGE,\n'
                '                     \"Message is not a notification\");\n'
                '        return FALSE;\n'
                '    }\n')
        else:
            raise ValueError('Unexpected message type \'%s\'' % message_type)

        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 ''
            translations['array_size'] = field['array-size'] if 'array-size' in field else ''

            inner_template = (
                '\n'
                '    /* Read the \'${field_name}\' variable */\n')
            if 'available-if' in field:
                condition = field['available-if']
                translations['condition_field'] = utils.build_underscore_name_from_camelcase(condition['field'])
                translations['condition_operation'] = condition['operation']
                translations['condition_value'] = condition['value']
                inner_template += (
                    '    if (!(_${condition_field} ${condition_operation} ${condition_value})) {\n')
                if field['format'] == 'byte-array':
                    inner_template += (
                        '        if (${field})\n'
                        '            *${field} = NULL;\n')
                elif field['format'] == 'unsized-byte-array' or \
                   field['format'] == 'ref-byte-array':
                    inner_template += (
                        '        if (${field}_size)\n'
                        '            *${field}_size = 0;\n'
                        '        if (${field})\n'
                        '            *${field} = NULL;\n')
                elif field['format'] == 'guint32-array' or \
                     field['format'] == 'string' or \
                     field['format'] == 'string-array' or \
                     field['format'] == 'struct' or \
                     field['format'] == 'struct-array' or \
                     field['format'] == 'ref-struct-array' or \
                     field['format'] == 'ipv4' or \
                     field['format'] == 'ref-ipv4' or \
                     field['format'] == 'ipv4-array' or \
                     field['format'] == 'ipv6' or \
                     field['format'] == 'ref-ipv6' or \
                     field['format'] == 'ipv6-array':
                    inner_template += (
                        '        if (${field} != NULL)\n'
                        '            *${field} = NULL;\n')
                else:
                    raise ValueError('Field format \'%s\' unsupported as optional field' % field['format'])

                inner_template += (
                    '    } else {\n')
            else:
                inner_template += (
                    '    {\n')

            if 'always-read' 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'] == 'byte-array':
                inner_template += (
                    '        const guint8 *tmp;\n'
                    '\n'
                    '        tmp = _mbim_message_read_byte_array (message, 0, offset, FALSE, FALSE, NULL);\n'
                    '        if (${field} != NULL)\n'
                    '            *${field} = tmp;\n'
                    '        offset += ${array_size};\n')
            elif field['format'] == 'unsized-byte-array':
                inner_template += (
                    '        const guint8 *tmp;\n'
                    '        guint32 tmpsize;\n'
                    '\n'
                    '        tmp = _mbim_message_read_byte_array (message, 0, offset, FALSE, FALSE, &tmpsize);\n'
                    '        if (${field} != NULL)\n'
                    '            *${field} = tmp;\n'
                    '        if (${field}_size != NULL)\n'
                    '            *${field}_size = tmpsize;\n'
                    '        offset += tmpsize;\n')
            elif field['format'] == 'ref-byte-array':
                inner_template += (
                    '        const guint8 *tmp;\n'
                    '        guint32 tmpsize;\n'
                    '\n'
                    '        tmp = _mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, &tmpsize);\n'
                    '        if (${field} != NULL)\n'
                    '            *${field} = tmp;\n'
                    '        if (${field}_size != NULL)\n'
                    '            *${field}_size = tmpsize;\n'
                    '        offset += 8;\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 += (
                    '        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, 0, 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}, 0, 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')

            inner_template += (
                '    }\n')

            template += (string.Template(inner_template).substitute(translations))

        template += (
            '\n'
            '    return TRUE;\n'
            '}\n')
        cfile.write(string.Template(template).substitute(translations))
Ejemplo n.º 57
0
    def __emit_request_creator(self, hfile, cfile):
        translations = {
            'name': self.name,
            'service': self.service,
            'container': utils.build_camelcase_name(self.input.fullname),
            'underscore': utils.build_underscore_name(self.fullname),
            'message_id': self.id_enum_name
        }

        input_arg_template = 'gpointer unused' if self.input.fields is None else '${container} *input'
        template = ('\n'
                    'static QmiMessage *\n'
                    '__${underscore}_request_create (\n'
                    '    guint16 transaction_id,\n'
                    '    guint8 cid,\n'
                    '    %s,\n'
                    '    GError **error)\n'
                    '{\n'
                    '    QmiMessage *self;\n'
                    '\n'
                    '    self = qmi_message_new (QMI_SERVICE_${service},\n'
                    '                            cid,\n'
                    '                            transaction_id,\n'
                    '                            ${message_id});\n' %
                    input_arg_template)
        cfile.write(string.Template(template).substitute(translations))

        if self.input.fields:
            # Count how many mandatory fields we have
            n_mandatory = 0
            for field in self.input.fields:
                if field.mandatory:
                    n_mandatory += 1

            if n_mandatory == 0:
                # If we don't have mandatory fields, we do allow to have
                # a NULL input
                cfile.write(
                    '\n'
                    '    /* All TLVs are optional, we allow NULL input */\n'
                    '    if (!input)\n'
                    '        return self;\n')
            else:
                # If we do have mandatory fields, issue error if no input
                # given.
                template = (
                    '\n'
                    '    /* There is at least one mandatory TLV, don\'t allow NULL input */\n'
                    '    if (!input) {\n'
                    '        g_set_error (error,\n'
                    '                     QMI_CORE_ERROR,\n'
                    '                     QMI_CORE_ERROR_INVALID_ARGS,\n'
                    '                     "Message \'${name}\' has mandatory TLVs");\n'
                    '        goto error_out;\n'
                    '    }\n')
                cfile.write(string.Template(template).substitute(translations))

            # Now iterate fields
            for field in self.input.fields:
                translations['tlv_name'] = field.name
                translations['variable_name'] = field.variable_name
                template = ('\n'
                            '    /* Try to add the \'${tlv_name}\' TLV */\n'
                            '    if (input->${variable_name}_set) {\n')
                cfile.write(string.Template(template).substitute(translations))

                # Emit the TLV getter
                field.emit_input_tlv_add(cfile, '        ')

                if field.mandatory:
                    template = (
                        '    } else {\n'
                        '        g_set_error (error,\n'
                        '                     QMI_CORE_ERROR,\n'
                        '                     QMI_CORE_ERROR_INVALID_ARGS,\n'
                        '                     "Missing mandatory TLV \'${tlv_name}\' in message \'${name}\'");\n'
                        '        goto error_out;\n')
                    cfile.write(
                        string.Template(template).substitute(translations))

                cfile.write('    }\n')
        cfile.write('\n' '    return self;\n')
        if self.input.fields:
            cfile.write('\n'
                        'error_out:\n'
                        '    qmi_message_unref (self);\n'
                        '    return NULL;\n')
        cfile.write('}\n')
Ejemplo n.º 58
0
    def emit_tlv_helpers(self, f):
        if TypeFactory.helpers_emitted(self.fullname):
            return

        TypeFactory.set_helpers_emitted(self.fullname)

        translations = {
            'name': self.name,
            'tlv_id': self.id_enum_name,
            'underscore': utils.build_underscore_name(self.fullname)
        }

        template = ('\n'
                    'static gboolean\n'
                    '${underscore}_validate (\n'
                    '    const guint8 *buffer,\n'
                    '    guint16 buffer_len)\n'
                    '{\n'
                    '    guint expected_len = 0;\n'
                    '\n')
        f.write(string.Template(template).substitute(translations))

        # Now, read the size of the expected TLV
        self.variable.emit_size_read(f, '    ', 'expected_len', 'buffer',
                                     'buffer_len')

        template = (
            '\n'
            '    if (buffer_len < expected_len) {\n'
            '        g_warning ("Cannot read the \'${name}\' TLV: expected \'%u\' bytes, but only got \'%u\' bytes",\n'
            '                   expected_len, buffer_len);\n'
            '        return FALSE;\n'
            '    }\n'
            '\n'
            '    if (buffer_len > expected_len) {\n'
            '        g_debug ("Reading the \'${name}\' TLV: expected \'%u\' bytes, but got \'%u\' bytes",\n'
            '                 expected_len, buffer_len);\n'
            '        return TRUE;\n'
            '    }\n'
            '\n'
            '    return TRUE;\n'
            '}\n'
            '\n')
        f.write(string.Template(template).substitute(translations))

        template = (
            '\n'
            'static gchar *\n'
            '${underscore}_get_printable (\n'
            '    QmiMessage *message,\n'
            '    const gchar *line_prefix)\n'
            '{\n'
            '    const guint8 *buffer;\n'
            '    guint16 buffer_len;\n'
            '\n'
            '    buffer = qmi_message_get_raw_tlv (message,\n'
            '                                      ${tlv_id},\n'
            '                                      &buffer_len);\n'
            '    if (buffer && ${underscore}_validate (buffer, buffer_len)) {\n'
            '        GString *printable;\n'
            '\n'
            '        printable = g_string_new ("");\n')
        f.write(string.Template(template).substitute(translations))

        # Now, read the contents of the buffer into the printable representation
        self.variable.emit_get_printable(f, '        ', 'printable', 'buffer',
                                         'buffer_len')

        template = (
            '\n'
            '        /* The remaining size of the buffer needs to be 0 if we successfully read the TLV */\n'
            '        if (buffer_len > 0) {\n'
            '            g_warning ("Left \'%u\' bytes unread when getting the \'${name}\' TLV as printable", buffer_len);\n'
            '        }\n'
            '\n'
            '        return g_string_free (printable, FALSE);\n'
            '    }\n'
            '\n'
            '    return NULL;\n'
            '}\n')
        f.write(string.Template(template).substitute(translations))