Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions src/modbus-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,6 @@ typedef enum {
_MODBUS_BACKEND_TYPE_TCP
} modbus_backend_type_t;

/*
* ---------- Request Indication ----------
* | Client | ---------------------->| Server |
* ---------- Confirmation Response ----------
*/
typedef enum {
/* Request message on the server side */
MSG_INDICATION,
/* Request message on the client side */
MSG_CONFIRMATION
} msg_type_t;

/* This structure reduces the number of params in functions and so
* optimizes the speed of execution (~ 37%). */
typedef struct _sft {
Expand Down Expand Up @@ -98,13 +86,14 @@ struct _modbus {
int error_recovery;
struct timeval response_timeout;
struct timeval byte_timeout;
modbus_callback_t callback[MODBUS_CALLBACK_MAX];
const modbus_backend_t *backend;
void *backend_data;
};

void _modbus_init_common(modbus_t *ctx);
void _error_print(modbus_t *ctx, const char *context);
int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type);
int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, modbus_msg_type_t msg_type);

#ifndef HAVE_STRLCPY
size_t strlcpy(char *dest, const char *src, size_t dest_size);
Expand Down
4 changes: 2 additions & 2 deletions src/modbus-rtu.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,15 +306,15 @@ static int _modbus_rtu_receive(modbus_t *ctx, uint8_t *req)
modbus_rtu_t *ctx_rtu = ctx->backend_data;

if (ctx_rtu->confirmation_to_ignore) {
_modbus_receive_msg(ctx, req, MSG_CONFIRMATION);
_modbus_receive_msg(ctx, req, MODBUS_MSG_CONFIRMATION);
/* Ignore errors and reset the flag */
ctx_rtu->confirmation_to_ignore = FALSE;
rc = 0;
if (ctx->debug) {
printf("Confirmation to ignore\n");
}
} else {
rc = _modbus_receive_msg(ctx, req, MSG_INDICATION);
rc = _modbus_receive_msg(ctx, req, MODBUS_MSG_INDICATION);
if (rc == 0) {
/* The next expected message is a confirmation to ignore */
ctx_rtu->confirmation_to_ignore = TRUE;
Expand Down
2 changes: 1 addition & 1 deletion src/modbus-tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ static ssize_t _modbus_tcp_send(modbus_t *ctx, const uint8_t *req, int req_lengt
}

static int _modbus_tcp_receive(modbus_t *ctx, uint8_t *req) {
return _modbus_receive_msg(ctx, req, MSG_INDICATION);
return _modbus_receive_msg(ctx, req, MODBUS_MSG_INDICATION);
}

static ssize_t _modbus_tcp_recv(modbus_t *ctx, uint8_t *rsp, int rsp_length) {
Expand Down
63 changes: 45 additions & 18 deletions src/modbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,24 @@ static void _sleep_response_timeout(modbus_t *ctx)
#endif
}

/* Assign a callback function pointer to context */
int modbus_register_callback(modbus_t *ctx, modbus_callback_type_t cb_type, modbus_callback_t cb)
{
if (ctx == NULL) {
errno = EINVAL;
return -1;
}

/* prevent abuse */
if (cb_type >= MODBUS_CALLBACK_MAX) {
errno = EINVAL;
return -1;
}

ctx->callback[cb_type] = cb;
return 0;
}

int modbus_flush(modbus_t *ctx)
{
int rc;
Expand Down Expand Up @@ -246,12 +264,12 @@ int modbus_send_raw_request(modbus_t *ctx, uint8_t *raw_req, int raw_req_length)
*/

/* Computes the length to read after the function received */
static uint8_t compute_meta_length_after_function(int function,
msg_type_t msg_type)
static uint8_t compute_meta_length_after_function(modbus_t *ctx, int function,
modbus_msg_type_t msg_type)
{
int length;

if (msg_type == MSG_INDICATION) {
if (msg_type == MODBUS_MSG_INDICATION) {
if (function <= MODBUS_FC_WRITE_SINGLE_REGISTER) {
length = 4;
} else if (function == MODBUS_FC_WRITE_MULTIPLE_COILS ||
Expand All @@ -266,7 +284,7 @@ static uint8_t compute_meta_length_after_function(int function,
length = 0;
}
} else {
/* MSG_CONFIRMATION */
/* MODBUS_MSG_CONFIRMATION */
switch (function) {
case MODBUS_FC_WRITE_SINGLE_COIL:
case MODBUS_FC_WRITE_SINGLE_REGISTER:
Expand All @@ -282,17 +300,21 @@ static uint8_t compute_meta_length_after_function(int function,
}
}

if (ctx->callback[MODBUS_CALLBACK_COMPUTE_META_LENGTH]) {
ctx->callback[MODBUS_CALLBACK_COMPUTE_META_LENGTH](ctx, function, msg_type, &length);
}

return length;
}

/* Computes the length to read after the meta information (address, count, etc) */
static int compute_data_length_after_meta(modbus_t *ctx, uint8_t *msg,
msg_type_t msg_type)
modbus_msg_type_t msg_type)
{
int function = msg[ctx->backend->header_length];
int length;

if (msg_type == MSG_INDICATION) {
if (msg_type == MODBUS_MSG_INDICATION) {
switch (function) {
case MODBUS_FC_WRITE_MULTIPLE_COILS:
case MODBUS_FC_WRITE_MULTIPLE_REGISTERS:
Expand All @@ -315,6 +337,10 @@ static int compute_data_length_after_meta(modbus_t *ctx, uint8_t *msg,
}
}

if (ctx->callback[MODBUS_CALLBACK_COMPUTE_DATA_LENGTH]) {
ctx->callback[MODBUS_CALLBACK_COMPUTE_DATA_LENGTH](ctx, msg, msg_type, &length);
}

length += ctx->backend->checksum_length;

return length;
Expand All @@ -334,7 +360,7 @@ static int compute_data_length_after_meta(modbus_t *ctx, uint8_t *msg,
- read() or recv() error codes
*/

int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, modbus_msg_type_t msg_type)
{
int rc;
fd_set rset;
Expand All @@ -345,7 +371,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
_step_t step;

if (ctx->debug) {
if (msg_type == MSG_INDICATION) {
if (msg_type == MODBUS_MSG_INDICATION) {
printf("Waiting for a indication...\n");
} else {
printf("Waiting for a confirmation...\n");
Expand All @@ -362,7 +388,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
step = _STEP_FUNCTION;
length_to_read = ctx->backend->header_length + 1;

if (msg_type == MSG_INDICATION) {
if (msg_type == MODBUS_MSG_INDICATION) {
/* Wait for a message, we don't know when the message will be
* received */
p_tv = NULL;
Expand Down Expand Up @@ -428,6 +454,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
case _STEP_FUNCTION:
/* Function code position */
length_to_read = compute_meta_length_after_function(
ctx,
msg[ctx->backend->header_length],
msg_type);
if (length_to_read != 0) {
Expand Down Expand Up @@ -494,7 +521,7 @@ int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp)
return -1;
}

return _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
return _modbus_receive_msg(ctx, rsp, MODBUS_MSG_CONFIRMATION);
}

static int check_confirmation(modbus_t *ctx, uint8_t *req,
Expand Down Expand Up @@ -1106,7 +1133,7 @@ static int read_io_status(modbus_t *ctx, int function,
int offset;
int offset_end;

rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
rc = _modbus_receive_msg(ctx, rsp, MODBUS_MSG_CONFIRMATION);
if (rc == -1)
return -1;

Expand Down Expand Up @@ -1215,7 +1242,7 @@ static int read_registers(modbus_t *ctx, int function, int addr, int nb,
int offset;
int i;

rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
rc = _modbus_receive_msg(ctx, rsp, MODBUS_MSG_CONFIRMATION);
if (rc == -1)
return -1;

Expand Down Expand Up @@ -1306,7 +1333,7 @@ static int write_single(modbus_t *ctx, int function, int addr, int value)
/* Used by write_bit and write_register */
uint8_t rsp[MAX_MESSAGE_LENGTH];

rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
rc = _modbus_receive_msg(ctx, rsp, MODBUS_MSG_CONFIRMATION);
if (rc == -1)
return -1;

Expand Down Expand Up @@ -1391,7 +1418,7 @@ int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src)
if (rc > 0) {
uint8_t rsp[MAX_MESSAGE_LENGTH];

rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
rc = _modbus_receive_msg(ctx, rsp, MODBUS_MSG_CONFIRMATION);
if (rc == -1)
return -1;

Expand Down Expand Up @@ -1441,7 +1468,7 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src)
if (rc > 0) {
uint8_t rsp[MAX_MESSAGE_LENGTH];

rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
rc = _modbus_receive_msg(ctx, rsp, MODBUS_MSG_CONFIRMATION);
if (rc == -1)
return -1;

Expand Down Expand Up @@ -1474,7 +1501,7 @@ int modbus_mask_write_register(modbus_t *ctx, int addr, uint16_t and_mask, uint1
/* Used by write_bit and write_register */
uint8_t rsp[MAX_MESSAGE_LENGTH];

rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
rc = _modbus_receive_msg(ctx, rsp, MODBUS_MSG_CONFIRMATION);
if (rc == -1)
return -1;

Expand Down Expand Up @@ -1544,7 +1571,7 @@ int modbus_write_and_read_registers(modbus_t *ctx,
if (rc > 0) {
int offset;

rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
rc = _modbus_receive_msg(ctx, rsp, MODBUS_MSG_CONFIRMATION);
if (rc == -1)
return -1;

Expand Down Expand Up @@ -1588,7 +1615,7 @@ int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest)
int offset;
uint8_t rsp[MAX_MESSAGE_LENGTH];

rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
rc = _modbus_receive_msg(ctx, rsp, MODBUS_MSG_CONFIRMATION);
if (rc == -1)
return -1;

Expand Down
23 changes: 23 additions & 0 deletions src/modbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,29 @@ MODBUS_API int modbus_reply(modbus_t *ctx, const uint8_t *req,
MODBUS_API int modbus_reply_exception(modbus_t *ctx, const uint8_t *req,
unsigned int exception_code);

/*
* ---------- Request Indication ----------
* | Client | ---------------------->| Server |
* ---------- Confirmation Response ----------
*/
typedef enum {
/* Request message on the server side */
MODBUS_MSG_INDICATION,
/* Request message on the client side */
MODBUS_MSG_CONFIRMATION
} modbus_msg_type_t;

typedef enum
{
MODBUS_CALLBACK_COMPUTE_META_LENGTH,
MODBUS_CALLBACK_COMPUTE_DATA_LENGTH,
MODBUS_CALLBACK_MAX
} modbus_callback_type_t;

typedef int (*modbus_callback_t)(modbus_t *ctx, ...);

MODBUS_API int modbus_register_callback(modbus_t *ctx, modbus_callback_type_t cb_type, modbus_callback_t cb);

/**
* UTILS FUNCTIONS
**/
Expand Down