aboutsummaryrefslogtreecommitdiff
path: root/build-aux
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2017-01-22 18:17:09 +0100
committerAleksander Morgado <aleksander@aleksander.es>2017-01-29 10:37:53 +0100
commit9bd604224f56fcf6fb0be577a646e62f59200594 (patch)
treee0eb725cd2f094502f8c613866ce027536a4aa42 /build-aux
parent132bd1b0ef5c3b8b9f2544261a9e57e0fd589c14 (diff)
libqmi-glib: support vendor-specific request/responses
We want to support non-standard messages that may be encoded with different TLVs depending on how the vendor implemented them. Anyway, right now this is really just to support the correct translation of TLVs and message contents in the get_printable() methods. The support is only included for QMI request/responses, and not for QMI indications. This is because the library knows in which moment the requests are created (and can apply the same rules to the matched response when it is received). For the indications, though, there is no such context configurable yet.
Diffstat (limited to 'build-aux')
-rw-r--r--build-aux/qmi-codegen/Client.py46
-rw-r--r--build-aux/qmi-codegen/Message.py5
-rw-r--r--build-aux/qmi-codegen/MessageList.py85
3 files changed, 110 insertions, 26 deletions
diff --git a/build-aux/qmi-codegen/Client.py b/build-aux/qmi-codegen/Client.py
index 1e342ae..32e1e0d 100644
--- a/build-aux/qmi-codegen/Client.py
+++ b/build-aux/qmi-codegen/Client.py
@@ -278,6 +278,7 @@ class Client:
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)
@@ -370,7 +371,7 @@ class Client:
' QmiMessage *reply;\n'
' ${output_camelcase} *output;\n'
'\n'
- ' reply = qmi_device_command_finish (device, res, &error);\n'
+ ' reply = qmi_device_command_full_finish (device, res, &error);\n'
' if (!reply) {\n')
if message.abort:
@@ -461,7 +462,13 @@ class Client:
' GSimpleAsyncResult *result;\n'
' QmiMessage *request;\n'
' GError *error = NULL;\n'
- ' guint16 transaction_id;\n'
+ ' guint16 transaction_id;\n')
+
+ if message.vendor is not None:
+ template += (
+ ' QmiMessageContext *context;\n')
+
+ template += (
'\n'
' result = g_simple_async_result_new (G_OBJECT (self),\n'
' callback,\n'
@@ -490,15 +497,36 @@ class Client:
' "transaction-id",\n'
' GUINT_TO_POINTER (transaction_id));\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')
+
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'
+ ' qmi_device_command_full (QMI_DEVICE (qmi_client_peek_device (QMI_CLIENT (self))),\n'
+ ' request,\n')
+
+ if message.vendor is not None:
+ template += (
+ ' context,\n')
+ else:
+ template += (
+ ' NULL,\n')
+
+ template += (
+ ' timeout,\n'
+ ' cancellable,\n'
+ ' (GAsyncReadyCallback)${message_underscore}_ready,\n'
+ ' result);\n'
+ ' qmi_message_unref (request);\n')
+
+ if message.vendor is not None:
+ template += (
+ ' qmi_message_context_unref (context);\n')
+
+ template += (
'}\n'
'\n')
cfile.write(string.Template(template).substitute(translations))
diff --git a/build-aux/qmi-codegen/Message.py b/build-aux/qmi-codegen/Message.py
index aae9561..9c78cf5 100644
--- a/build-aux/qmi-codegen/Message.py
+++ b/build-aux/qmi-codegen/Message.py
@@ -45,6 +45,11 @@ class Message:
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 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
diff --git a/build-aux/qmi-codegen/MessageList.py b/build-aux/qmi-codegen/MessageList.py
index bbd020f..4331b90 100644
--- a/build-aux/qmi-codegen/MessageList.py
+++ b/build-aux/qmi-codegen/MessageList.py
@@ -73,8 +73,13 @@ class MessageList:
if message.type == 'Message':
translations['enum_name'] = message.id_enum_name
translations['enum_value'] = message.id
- enum_template = (
- ' ${enum_name} = ${enum_value},\n')
+ if message.vendor is None:
+ enum_template = (
+ ' ${enum_name} = ${enum_value},\n')
+ else:
+ translations['vendor'] = message.vendor
+ enum_template = (
+ ' ${enum_name} = ${enum_value}, /* vendor ${vendor} */\n')
template += string.Template(enum_template).substitute(translations)
template += (
@@ -118,6 +123,7 @@ class MessageList:
'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'
@@ -129,6 +135,7 @@ class MessageList:
'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'
@@ -138,7 +145,6 @@ class MessageList:
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')
@@ -149,21 +155,39 @@ class MessageList:
' return NULL;\n'
' }\n'
' } else {\n'
- ' switch (qmi_message_get_message_id (self)) {\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':
+ 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)
- translations['enum_value'] = message.id
inner_template = (
- ' case ${enum_name}:\n'
- ' return message_${message_underscore}_get_printable (self, line_prefix);\n')
+ ' 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'
+ ' 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')
@@ -184,6 +208,7 @@ class MessageList:
'G_GNUC_INTERNAL\n'
'gboolean __qmi_message_${service}_get_version_introduced (\n'
' QmiMessage *self,\n'
+ ' QmiMessageContext *context,\n'
' guint *major,\n'
' guint *minor);\n'
'\n'
@@ -196,27 +221,53 @@ class MessageList:
'gboolean\n'
'__qmi_message_${service}_get_version_introduced (\n'
' QmiMessage *self,\n'
+ ' QmiMessageContext *context,\n'
' guint *major,\n'
' guint *minor)\n'
'{\n'
- ' switch (qmi_message_get_message_id (self)) {\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':
+ if message.type == 'Message' and message.vendor is None:
+ # Only add if we know the version info
+ if message.version_info != []:
+ translations['enum_name'] = message.id_enum_name
+ translations['message_major'] = message.version_info[0]
+ translations['message_minor'] = message.version_info[1]
+ inner_template = (
+ ' case ${enum_name}:\n'
+ ' *major = ${message_major};\n'
+ ' *minor = ${message_minor};\n'
+ ' return TRUE;\n')
+ template += string.Template(inner_template).substitute(translations)
+
+ template += (
+ ' default:\n'
+ ' return FALSE;\n'
+ ' }\n'
+ ' } else {\n')
+
+ for message in self.list:
+ if message.type == 'Message' and message.vendor is not None:
# Only add if we know the version info
if message.version_info != []:
translations['enum_name'] = message.id_enum_name
translations['message_major'] = message.version_info[0]
translations['message_minor'] = message.version_info[1]
+ translations['message_vendor'] = message.vendor
inner_template = (
- ' case ${enum_name}:\n'
- ' *major = ${message_major};\n'
- ' *minor = ${message_minor};\n'
- ' return TRUE;\n')
+ ' if (vendor_id == ${message_vendor} && (qmi_message_get_message_id (self) == ${enum_name})) {\n'
+ ' *major = ${message_major};\n'
+ ' *minor = ${message_minor};\n'
+ ' return TRUE;\n'
+ ' }\n')
template += string.Template(inner_template).substitute(translations)
template += (
- ' default:\n'
' return FALSE;\n'
' }\n'
'}\n')