hydrolink/gen_c/gen_messages.py

82 lines
2.8 KiB
Python

from hydroparse import HydroMessageType
import os
NS_PREFIX_LOWER = "hydrolink_"
GENERIC_MSG_NAME = f"{NS_PREFIX_LOWER}msg"
GENERIC_MSG_STRUCT = f"{GENERIC_MSG_NAME}_s"
GENERIC_MSG_TYPE = f"{GENERIC_MSG_NAME}_t"
MSG_ID_PREFIX = "HYDROLINK_MSG_ID_"
def generate_message_h(dir, m: HydroMessageType):
msg_name = f"{NS_PREFIX_LOWER}msg_{m.name_lower}"
msg_type = f"{msg_name}_t"
msg_struct = f"{msg_type}_s"
def decode_payload_str(m: HydroMessageType):
array = []
for field in m.ordered_fields:
array.append(
f" {m.name_lower}->{field.name} = {msg_name}_get_{field.name}(packet);"
)
return "\n".join(array)
struct_fields = []
for i, field in enumerate(m.ordered_fields):
if field.units:
units = f"[{field.units}]"
else:
units = ""
if field.array_length:
struct_fields.append(
f"{field.type} {field.name}[{field.array_length}]; /// {units} {field.description}"
)
else:
struct_fields.append(
f"{field.type} {field.name}; /// {units} {field.description}"
)
struct_fields_str = "\n".join(struct_fields)
encode_payload = []
wire_offset = 0
for i, field in enumerate(m.ordered_fields):
if field.array_length:
raise Exception("Arrays currently not supported!")
else:
typename = field.type
encode_payload.append(
f" hydrolink_put_{typename}(HYDROLINK_PAYLOAD_NON_CONST(packet), {field.wire_offset}, msg->{field.name});"
)
wire_offset += field.wire_length
encode_payload_str = "\n".join(encode_payload)
with open(os.path.join(dir, f"hydrolink_msg_{m.name_lower}.h"), "w") as f:
f.write(f"""#pragma once
#include "protocol.h"
#define {MSG_ID_PREFIX}{m.name} {m.id}
#define {MSG_ID_PREFIX}{m.name}_LEN {m.wire_length}
#define {MSG_ID_PREFIX}{m.id}_LEN {m.wire_length}
#define {MSG_ID_PREFIX}{m.name}_CRC_EXTRA {m.crc_extra}
typedef struct {msg_struct} {{
{struct_fields_str}
}} {msg_type};
void {NS_PREFIX_LOWER}{m.name_lower}_msg_encode(uint8_t src_id, uint8_t dst_id, const {msg_type} *msg, {GENERIC_MSG_TYPE} *packet) {{
packet->id = {MSG_ID_PREFIX}{m.name};
packet->src_id = src_id;
packet->dst_id = dst_id;
packet->length = {MSG_ID_PREFIX}{m.id}_LEN + HYDROLINK_NON_PAYLOAD_LEN;
{encode_payload_str}
}}
""")
wire_offset = 0
for field in m.ordered_fields:
f.write(f"""
static inline {field.type} {msg_name}_get_{field.name}(const {GENERIC_MSG_TYPE} *packet) {{
return HYDROLINK_RETURN_{field.type}(packet, {field.wire_offset});
}}""")
f.write(f"""
static inline void {NS_PREFIX_LOWER}msg{m.name_lower}_decode(const {GENERIC_MSG_TYPE} *packet, {msg_type} *{m.name_lower}) {{
{decode_payload_str(m)}
}}""")