modbuspp  1.1.40
C++ wrapper for the libmodbus library
server/callback-server-json/main.cpp
Author
Pascal JEAN, aka epsilonrt
#include <csignal>
#include <thread>
#include <iostream>
#include <modbuspp.h>
using namespace std;
using namespace Modbus;
Server srv; // instantiates new MODBUS Server
/* -----------------------------------------------------------------------------
* Incoming message handler
* This function is called each time a MODBUS message is received by the Server
* class on the backend network (TCP-IP or OSL).
* Here the function analyzes the message, if it is a message for reading input
* registers (FC 4), a response is constructed which sends dummy values which
* are incremented with each reading. The response is sent using the
* sendRawMessage() function, which automatically completes the message with a
* header or CRC.
*/
int messageHandler (Message * req, Device * dev) {
cout << "Receive message, size : " << req->aduSize() << endl;
if (req->function() == ReadInputRegisters) {
// the dummy word will be the returned value, incremented after each reading
static uint16_t dummy = 1;
// get request parameters
uint16_t N = req->quantity();
uint16_t index = req->startingAddress();
// build response, see page 16 of MODBUS Application Protocol Specification
Response rsp (*req); // uses copy constructor to keep transaction id
rsp.setSize (1); // keep until function code
rsp.setByteCount (N * 2);
for (uint16_t i = 0; i < N; i++) {
rsp.setRegisterValue (index + i, dummy++);
}
return dev->sendRawMessage (rsp, true);
}
return 0;
}
// -----------------------------------------------------------------------------
// Signal trap, triggers during a CTRL+C or if kill is called
void
sighandler (int sig) {
srv.close();
cout << "everything was closed." << endl << "Have a nice day !" << endl;
exit (EXIT_SUCCESS);
}
// -----------------------------------------------------------------------------
int main (int argc, char **argv) {
if (argc < 2) {
cerr << "Error: the JSON filename must be provided as a parameter on the command line !" << endl;
cerr << "e.g. : " << argv[0] << " virtual-server-tcp.json" << endl;
exit (EXIT_FAILURE);
}
string jsonfile = argv[1];
cout << "Callback Server" << endl;
// CTRL+C and kill call triggers the trap sighandler()
signal (SIGINT, sighandler);
signal (SIGTERM, sighandler);
cout << "Press CTRL+C to stop... " << endl << endl;
try {
cout << "opening " << jsonfile << "..." << endl;
srv.setConfig (jsonfile, "modbuspp-server");
srv.setMessageCallback (messageHandler);
if (srv.open ()) { // open a connection
cout << "Listening server on " <<
srv.connection() << ":" << srv.settings() << "..." << endl << endl;
srv.run();
while (srv.isOpen()) {
// std::this_thread::yield();
std::this_thread::sleep_for (std::chrono::milliseconds (200));
}
}
}
catch (std::exception & e) {
cerr << "Error: " << e.what() << endl;
}
catch (...) {
cerr << "Unattended exception !" << endl;
}
return EXIT_FAILURE;
}
/* ========================================================================== */