buildcommands: Use dictionaries to describe commands, responses, and output

Avoid transmitting lists of message ids for commands and responses -
gzip doesn't do a good job of compressing them.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2019-03-04 19:50:35 -05:00 committed by KevinOConnor
parent b9b03dd082
commit 7eda55e2b0
2 changed files with 28 additions and 21 deletions

View File

@ -6,8 +6,8 @@
import json, zlib, logging import json, zlib, logging
DefaultMessages = { DefaultMessages = {
0: "identify_response offset=%u data=%.*s", "identify_response offset=%u data=%.*s": 0,
1: "identify offset=%u count=%c", "identify offset=%u count=%c": 1,
} }
MESSAGE_MIN = 5 MESSAGE_MIN = 5
@ -190,7 +190,7 @@ class MessageParser:
self.config = {} self.config = {}
self.version = self.build_versions = "" self.version = self.build_versions = ""
self.raw_identify_data = "" self.raw_identify_data = ""
self._init_messages(DefaultMessages, DefaultMessages.keys()) self._init_messages(DefaultMessages)
def check_packet(self, s): def check_packet(self, s):
if len(s) < MESSAGE_MIN: if len(s) < MESSAGE_MIN:
return 0 return 0
@ -296,10 +296,10 @@ class MessageParser:
#traceback.print_exc() #traceback.print_exc()
raise error("Unable to encode: %s" % (msgname,)) raise error("Unable to encode: %s" % (msgname,))
return cmd return cmd
def _init_messages(self, messages, parsers): def _init_messages(self, messages, output_ids=[]):
for msgid, msgformat in messages.items(): for msgformat, msgid in messages.items():
msgid = int(msgid) msgid = int(msgid)
if msgid not in parsers: if msgid in output_ids:
self.messages_by_id[msgid] = OutputFormat(msgid, msgformat) self.messages_by_id[msgid] = OutputFormat(msgid, msgformat)
continue continue
msg = MessageFormat(msgid, msgformat) msg = MessageFormat(msgid, msgformat)
@ -311,11 +311,14 @@ class MessageParser:
data = zlib.decompress(data) data = zlib.decompress(data)
self.raw_identify_data = data self.raw_identify_data = data
data = json.loads(data) data = json.loads(data)
messages = data.get('messages')
commands = data.get('commands') commands = data.get('commands')
self.command_ids = commands
responses = data.get('responses') responses = data.get('responses')
self._init_messages(messages, commands+responses) output = data.get('output', {})
all_messages = dict(commands)
all_messages.update(responses)
all_messages.update(output)
self.command_ids = sorted(commands.values())
self._init_messages(all_messages, output.values())
static_strings = data.get('static_strings', {}) static_strings = data.get('static_strings', {})
self.static_strings = {int(k): v for k, v in static_strings.items()} self.static_strings = {int(k): v for k, v in static_strings.items()}
self.config.update(data.get('config', {})) self.config.update(data.get('config', {}))

View File

@ -131,7 +131,7 @@ class HandleCommandGeneration:
def __init__(self): def __init__(self):
self.commands = {} self.commands = {}
self.encoders = [] self.encoders = []
self.msg_to_id = { m: i for i, m in msgproto.DefaultMessages.items() } self.msg_to_id = dict(msgproto.DefaultMessages)
self.messages_by_name = { m.split()[0]: m for m in self.msg_to_id } self.messages_by_name = { m.split()[0]: m for m in self.msg_to_id }
self.all_param_types = {} self.all_param_types = {}
self.ctr_dispatch = { self.ctr_dispatch = {
@ -172,16 +172,20 @@ class HandleCommandGeneration:
# The mcu currently assumes all message ids encode to one byte # The mcu currently assumes all message ids encode to one byte
error("Too many message ids") error("Too many message ids")
def update_data_dictionary(self, data): def update_data_dictionary(self, data):
messages = { msgid: msg for msg, msgid in self.msg_to_id.items() } command_ids = [self.msg_to_id[msg]
data['messages'] = messages
commands = [self.msg_to_id[msg]
for msgname, msg in self.messages_by_name.items() for msgname, msg in self.messages_by_name.items()
if msgname in self.commands] if msgname in self.commands]
data['commands'] = sorted(commands) response_ids = [self.msg_to_id[msg]
responses = [self.msg_to_id[msg]
for msgname, msg in self.messages_by_name.items() for msgname, msg in self.messages_by_name.items()
if msgname not in self.commands] if msgname not in self.commands]
data['responses'] = sorted(responses) data['commands'] = { msg: msgid for msg, msgid in self.msg_to_id.items()
if msgid in command_ids }
data['responses'] = {msg: msgid for msg, msgid in self.msg_to_id.items()
if msgid in response_ids }
output = { msg: msgid for msg, msgid in self.msg_to_id.items()
if msgid not in command_ids and msgid not in response_ids }
if output:
data['output'] = output
def build_parser(self, parser, iscmd): def build_parser(self, parser, iscmd):
if parser.name == "#output": if parser.name == "#output":
comment = "Output: " + parser.msgformat comment = "Output: " + parser.msgformat
@ -412,7 +416,7 @@ class HandleIdentify:
data = {} data = {}
for h in Handlers: for h in Handlers:
h.update_data_dictionary(data) h.update_data_dictionary(data)
datadict = json.dumps(data, separators=(',', ':')) datadict = json.dumps(data, separators=(',', ':'), sort_keys=True)
# Write data dictionary # Write data dictionary
if options.write_dictionary: if options.write_dictionary: