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
2 changes: 2 additions & 0 deletions src/modbus-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ typedef struct _modbus_backend {
struct _modbus {
/* Slave address */
int slave;
/* used only in user-defined functions */
int wanted_resp_data_length;
/* Socket or file descriptor */
int s;
int debug;
Expand Down
4 changes: 2 additions & 2 deletions src/modbus-rtu.c
Original file line number Diff line number Diff line change
Expand Up @@ -911,11 +911,11 @@ int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode)
struct serial_rs485 rs485conf;

if (mode == MODBUS_RTU_RS485) {
// Get
/* Get */
if (ioctl(ctx->s, TIOCGRS485, &rs485conf) < 0) {
return -1;
}
// Set
/* Set */
rs485conf.flags |= SER_RS485_ENABLED;
if (ioctl(ctx->s, TIOCSRS485, &rs485conf) < 0) {
return -1;
Expand Down
54 changes: 33 additions & 21 deletions src/modbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ static int send_msg(modbus_t *ctx, uint8_t *msg, int msg_length)
return rc;
}

int modbus_send_raw_request(modbus_t *ctx, const uint8_t *raw_req, int raw_req_length)
int modbus_send_generic_request(modbus_t *ctx,
const uint8_t *raw_req, int raw_req_length, int wanted_resp_data_length)
{
sft_t sft;
uint8_t req[MAX_MESSAGE_LENGTH];
Expand All @@ -226,10 +227,14 @@ int modbus_send_raw_request(modbus_t *ctx, const uint8_t *raw_req, int raw_req_l
return -1;
}

sft.slave = raw_req[0];
ctx->wanted_resp_data_length = wanted_resp_data_length;

sft.slave = raw_req[0];
sft.function = raw_req[1];

/* The t_id is left to zero */
sft.t_id = 0;

/* This response function only set the header so it's convenient here */
req_length = ctx->backend->build_response_basis(&sft, req);

Expand All @@ -242,6 +247,18 @@ int modbus_send_raw_request(modbus_t *ctx, const uint8_t *raw_req, int raw_req_l
return send_msg(ctx, req, req_length);
}

int modbus_send_raw_request(modbus_t *ctx, const uint8_t *raw_req, int raw_req_length)
{
/* The wanted_resp_data_length is set to zero (cause used only in user-defined functions) */
return modbus_send_generic_request(ctx, raw_req, raw_req_length, 0);
}

static uint_fast8_t is_users_function(int function)
{
return ((function >= MODBUS_FC_USERS_RANGE1_LO && function <= MODBUS_FC_USERS_RANGE1_HI) ||
(function >= MODBUS_FC_USERS_RANGE2_LO && function <= MODBUS_FC_USERS_RANGE2_HI));
}

/*
* ---------- Request Indication ----------
* | Client | ---------------------->| Server |
Expand Down Expand Up @@ -270,19 +287,17 @@ static uint8_t compute_meta_length_after_function(int function,
}
} else {
/* MSG_CONFIRMATION */
switch (function) {
case MODBUS_FC_WRITE_SINGLE_COIL:
case MODBUS_FC_WRITE_SINGLE_REGISTER:
case MODBUS_FC_WRITE_MULTIPLE_COILS:
case MODBUS_FC_WRITE_MULTIPLE_REGISTERS:
if ((function == MODBUS_FC_WRITE_SINGLE_COIL) ||
(function == MODBUS_FC_WRITE_SINGLE_REGISTER) ||
(function == MODBUS_FC_WRITE_MULTIPLE_COILS) ||
(function == MODBUS_FC_WRITE_MULTIPLE_REGISTERS))
length = 4;
break;
case MODBUS_FC_MASK_WRITE_REGISTER:
else if (function == MODBUS_FC_MASK_WRITE_REGISTER)
length = 6;
break;
default:
else if (is_users_function(function))
length = 0;
else
length = 1;
}
}

return length;
Expand All @@ -293,7 +308,7 @@ static int compute_data_length_after_meta(modbus_t *ctx, uint8_t *msg,
msg_type_t msg_type)
{
int function = msg[ctx->backend->header_length];
int length;
int length = 0;

if (msg_type == MSG_INDICATION) {
switch (function) {
Expand All @@ -304,18 +319,15 @@ static int compute_data_length_after_meta(modbus_t *ctx, uint8_t *msg,
case MODBUS_FC_WRITE_AND_READ_REGISTERS:
length = msg[ctx->backend->header_length + 9];
break;
default:
length = 0;
}
} else {
/* MSG_CONFIRMATION */
if (function <= MODBUS_FC_READ_INPUT_REGISTERS ||
function == MODBUS_FC_REPORT_SLAVE_ID ||
function == MODBUS_FC_WRITE_AND_READ_REGISTERS) {
if ( function <= MODBUS_FC_READ_INPUT_REGISTERS ||
function == MODBUS_FC_REPORT_SLAVE_ID ||
function == MODBUS_FC_WRITE_AND_READ_REGISTERS )
length = msg[ctx->backend->header_length + 1];
} else {
length = 0;
}
else if (is_users_function(function))
length = ctx->wanted_resp_data_length;
}

length += ctx->backend->checksum_length;
Expand Down
8 changes: 8 additions & 0 deletions src/modbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ MODBUS_BEGIN_DECLS
#define MODBUS_FC_MASK_WRITE_REGISTER 0x16
#define MODBUS_FC_WRITE_AND_READ_REGISTERS 0x17

#define MODBUS_FC_USERS_RANGE1_LO 0x41 /* 65-72 */
#define MODBUS_FC_USERS_RANGE1_HI 0x48
#define MODBUS_FC_USERS_RANGE2_LO 0x64 /* 100-110 */
#define MODBUS_FC_USERS_RANGE2_HI 0x6E

#define MODBUS_BROADCAST_ADDRESS 0

/* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 1 page 12)
Expand Down Expand Up @@ -227,6 +232,9 @@ MODBUS_API modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
int nb_registers, int nb_input_registers);
MODBUS_API void modbus_mapping_free(modbus_mapping_t *mb_mapping);

MODBUS_API int modbus_send_generic_request(modbus_t *ctx,
const uint8_t *raw_req, int raw_req_length, int wanted_resp_data_length);

MODBUS_API int modbus_send_raw_request(modbus_t *ctx, const uint8_t *raw_req, int raw_req_length);

MODBUS_API int modbus_receive(modbus_t *ctx, uint8_t *req);
Expand Down