libipc-old/src/message.c

148 lines
4.1 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <arpa/inet.h>
#include "message.h"
#include "usocket.h"
// #define IPC_WITH_ERRORS 3
uint32_t ipc_message_raw_serialize (char *buffer, char type, char user_type, char *message, uint32_t message_size)
{
uint32_t msize = 6 + message_size;
buffer[0] = type;
uint32_t msize_n = htonl (message_size);
uint32_t index = 1;
memcpy (buffer + index, &msize_n, sizeof (uint32_t));
index += sizeof (uint32_t);
buffer[index] = user_type;
index += 1;
memcpy (buffer + index, message, message_size);
return msize;
}
struct ipc_error ipc_message_format_read (struct ipc_message *m, const char *buf, size_t msize)
{
T_R ((m == NULL), IPC_ERROR_MESSAGE_FORMAT_READ__EMPTY_MESSAGE);
T_R ((buf == NULL), IPC_ERROR_MESSAGE_FORMAT_READ__EMPTY_BUFFER);
T_R ((msize > IPC_MAX_MESSAGE_SIZE), IPC_ERROR_MESSAGE_FORMAT_READ__PARAM_MESSAGE_SIZE);
// message format:
// Type (1 B) | Length (4 B) | UserType (1 B) | Payload (Length B)
m->type = buf[0];
uint32_t unformated_size = 0;
memcpy (&unformated_size, buf + 1, sizeof (uint32_t));
m->length = ntohl (unformated_size);
m->user_type = buf[1 + sizeof m->length];
T_R ((m->length > IPC_MAX_MESSAGE_SIZE), IPC_ERROR_MESSAGE_FORMAT_READ__MESSAGE_TOO_LONG);
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
LOG_INFO ("receiving msg: type %d, paylen %u, total %lu", m->type, m->length, msize);
#endif
T_R ((m->length != msize - IPC_HEADER_SIZE && m->length != 0)
, IPC_ERROR_MESSAGE_FORMAT_READ__READ_MESSAGE_SIZE);
if (m->payload != NULL) {
free (m->payload);
m->payload = NULL;
}
if (m->length > 0) {
m->payload = malloc (m->length);
memcpy (m->payload, buf + IPC_HEADER_SIZE, m->length);
} else {
m->payload = malloc (1);
}
IPC_RETURN_NO_ERROR;
}
struct ipc_error ipc_message_format_write (const struct ipc_message *m, char **buf, size_t * msize)
{
T_R ((m == NULL), IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_MESSAGE);
T_R ((buf == NULL), IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_BUFFER);
T_R ((msize == NULL), IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_MSIZE);
T_R ((m->length > IPC_MAX_MESSAGE_SIZE), IPC_ERROR_MESSAGE_FORMAT_WRITE__MESSAGE_LENGTH);
if (*buf == NULL) {
*buf = malloc (IPC_HEADER_SIZE + m->length);
memset (*buf, 0, IPC_HEADER_SIZE + m->length);
}
char *buffer = *buf;
uint32_t net_paylen = htonl (m->length);
buffer[0] = m->type;
memcpy (buffer + 1, &net_paylen, sizeof (uint32_t));
buffer[1 + sizeof m->length] = m->user_type;
if (m->payload != NULL && m->length > 0) {
memcpy (buffer + IPC_HEADER_SIZE, m->payload, m->length);
}
*msize = IPC_HEADER_SIZE + m->length;
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
LOG_INFO ("sending msg: type %u, paylen %u, msize %lu", m->type, m->length, *msize);
#endif
IPC_RETURN_NO_ERROR;
}
// MSG FORMAT
struct ipc_error ipc_message_format (struct ipc_message *m, char type, char utype, const char *payload, size_t length)
{
T_R ((m == NULL), IPC_ERROR_MESSAGE_FORMAT__NO_MESSAGE_PARAM);
T_R ((length > IPC_MAX_MESSAGE_SIZE), IPC_ERROR_MESSAGE_FORMAT__MESSAGE_SIZE);
T_R (((length == 0 && payload != NULL) || (length > 0 && payload == NULL))
, IPC_ERROR_MESSAGE_FORMAT__INCONSISTENT_PARAMS);
m->type = type;
m->user_type = utype;
m->length = (uint32_t) length;
if (payload != NULL) {
if (m->payload != NULL) {
free (m->payload);
}
SECURE_BUFFER_HEAP_ALLOCATION_R (m->payload, length,, IPC_ERROR_MESSAGE_FORMAT__HEAP_ALLOCATION);
}
if (payload != NULL) {
memcpy (m->payload, payload, length);
}
IPC_RETURN_NO_ERROR;
}
struct ipc_error ipc_message_format_data (struct ipc_message *m, char utype, const char *payload, size_t length)
{
return ipc_message_format (m, MSG_TYPE_DATA, utype, payload, length);
}
struct ipc_error ipc_message_format_server_close (struct ipc_message *m)
{
return ipc_message_format (m, MSG_TYPE_SERVER_CLOSE, 0, NULL, 0);
}
struct ipc_error ipc_message_empty (struct ipc_message *m)
{
T_R ((m == NULL), IPC_ERROR_MESSAGE_EMPTY__EMPTY_MESSAGE_LIST);
if (m->payload != NULL) {
free (m->payload);
m->payload = NULL;
}
m->length = 0;
IPC_RETURN_NO_ERROR;
}