I am not sure that I understand your question correctly. The problem you are facing is that all your messages have a common header and then some type-specific part. And to send them you want both of these parts in a contiguous buffer. I guess you have two options here:
(1) Include the header in every message type, i.e.
typedef struct ThermocontactMessage_t
{
MessageHeader_t hdr;
uint32_t count;
uint8_t value:1;
}ThermocontactMessage_t;
(2) Just leave your type-specific structures as they are and construct a buffer with header + message in your transmit function:
typedef struct Message_t
{
MessageHeader_t hdr;
BYTE data[MAX_CARGO_SIZE];
}Message_t;
void SomeFunction(bool thermocontactState)
{
Message_t msg;
ThermocontactMessage_t* pData = (ThermocontactMessage_t*) msg.data;
msg.hdr.id = MessageType_Thermocontact,
msg.hdr.length = sizeof(ThermocontactMessage_t)
pData->value = thermocontactState;
pData->count = ++messageCount;
...
}
With many message types you are going to end-up with a lot of repetitive code, which can be mitigated by use of a macro that fills the header and casts a pointer to the data part. Then this function would look like:
void SomeFunction(bool thermocontactState)
{
Message_t msg;
ThermocontactMessage_t* pData = FILLHEADER (Thermocontact);
pData->value = thermocontactState;
pData->count = ++messageCount;
...
}
That looks a lot nicer, avoids copy-paste errors and keeps your code clean. The macro is smart enough to derive from its argument Thermocontact that the message type-id is MessageType_Thermocontact by prepending MessageType_ and that the message structure is ThermocontactMessage_t by appending Message_t. Thus with a bit of macro-magic you can accomplish quite a bit. Of course, all of this would not be necessary if you could use C++ instead of C.