make demo server interactive

master
Ondřej Hruška 2 months ago
parent ed4d54a510
commit c0fb0e8122
  1. 189
      src/main.c

@ -12,83 +12,156 @@ ModbusException_t startOfAccess(ModbusSlave_t *ms, ModbusFunction_t fcx, uint8_t
void endOfAccess(ModbusSlave_t *ms) { printf("End of access\n"); }
typedef struct {
uint16_t num;
uint16_t value;
} register_slot_t;
typedef struct {
uint16_t num;
bool value;
} coil_slot_t;
//@formatter:off
static register_slot_t holdings[] = {
{1, 10},
{2, 20},
{3, 30},
{4, 40},
{5, 50},
{7, 70},
{0xffff, 0}
};
static register_slot_t inputs[] = {
{1, 11},
{2, 21},
{3, 31},
{4, 41},
{5, 51},
{7, 71},
{0xffff, 0}
};
static coil_slot_t coils[] = {
{1, 1},
{2, 0},
{3, 1},
{4, 0},
{5, 1},
{7, 1},
{0xffff, 0}
};
static coil_slot_t discretes[] = {
{1, 0},
{2, 1},
{3, 1},
{4, 1},
{5, 1},
{7, 0},
{0xffff, 0}
};
//@formatter:on
ModbusException_t readHolding(ModbusSlave_t *ms, uint16_t i, uint16_t *out) {
printf("rh %d\n", i);
switch (i) {
case 107:
*out = 0xAE41;
break;
case 108:
*out = 0x5652;
break;
case 109:
*out = 0x4340;
break;
default:
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
const register_slot_t *p = holdings;
while (p->num != 0xffff) {
if (p->num == i) {
*out = p->value;
return 0;
}
p++;
}
return 0;
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
}
ModbusException_t readInput(ModbusSlave_t *ms, uint16_t i, uint16_t *out) {
printf("ri %d\n", i);
switch (i) {
case 8:
*out = 0xa;
break;
default:
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
const register_slot_t *p = inputs;
while (p->num != 0xffff) {
if (p->num == i) {
*out = p->value;
return 0;
}
p++;
}
return 0;
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
}
ModbusException_t readCoil(ModbusSlave_t *ms, uint16_t i, bool *out) {
uint8_t store[] = {
0b11001101, 0b01101011, 0b10110010, 0b00001110, 0b00011011,
};
if (i >= 19 && i <= 55) {
int pos = i - 19;
*out = 0 != (store[pos / 8] & (1 << (pos % 8)));
} else {
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
ModbusException_t readCoil(ModbusSlave_t *ms, uint16_t i, bool *out) {
const coil_slot_t *p = coils;
while (p->num != 0xffff) {
if (p->num == i) {
*out = p->value;
return 0;
}
p++;
}
return 0;
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
}
ModbusException_t readDiscrete(ModbusSlave_t *ms, uint16_t i, bool *out) {
uint8_t store[] = {
0b10101100,
0b11011011,
0b00110101,
};
if (i >= 196 && i <= 217) {
int pos = i - 196;
*out = 0 != (store[pos / 8] & (1 << (pos % 8)));
} else {
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
ModbusException_t readDiscrete(ModbusSlave_t *ms, uint16_t i, bool *out) {
const coil_slot_t *p = discretes;
while (p->num != 0xffff) {
if (p->num == i) {
*out = p->value;
return 0;
}
p++;
}
return 0;
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
}
ModbusException_t writeCoil(ModbusSlave_t *pSlave, uint16_t i, bool b) {
printf("Write coil %d <- %d\n", i, b);
return 0;
coil_slot_t *p = coils;
while (p->num != 0) {
if (p->num == i) {
p->value = b;
return 0;
}
p++;
}
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
}
ModbusException_t writeHolding(ModbusSlave_t *pSlave, uint16_t i, uint16_t i1) {
printf("Write reg %d <- %d\n", i, i1);
return 0;
ModbusException_t writeHolding(ModbusSlave_t *pSlave, uint16_t i, uint16_t val) {
printf("Write reg %d <- %d\n", i, val);
register_slot_t *p = holdings;
while (p->num != 0) {
if (p->num == i) {
p->value = val;
return 0;
}
p++;
}
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
}
static ModbusSlave_t ms = {
.addr = 1,
.proto = MB_PROTO_TCP,
.startOfAccess = startOfAccess,
.endOfAccess = endOfAccess,
.readHolding = readHolding,
.readInput = readInput,
.readCoil = readCoil,
.readDiscrete = readDiscrete,
.writeCoil = writeCoil,
.writeHolding = writeHolding,
.addr = 1,
.proto = MB_PROTO_TCP,
.startOfAccess = startOfAccess,
.endOfAccess = endOfAccess,
.readHolding = readHolding,
.readInput = readInput,
.readCoil = readCoil,
.readDiscrete = readDiscrete,
.writeCoil = writeCoil,
.writeHolding = writeHolding,
};
int msg_received_fce(int fd, const simple_msg_t *msg) {
@ -103,8 +176,8 @@ int msg_received_fce(int fd, const simple_msg_t *msg) {
return 1; // kick the client
simple_msg_t resp = {
.data = resp_buf,
.len = resp_size,
.data = resp_buf,
.len = resp_size,
};
simple_tcp_send(fd, &resp);

Loading…
Cancel
Save