///////////////////////////////////////////////////////////////////////////////// // // modbus.h is part of TestModbus-Server. // ///////////////////////////////////////////////////////////////////////////////// #ifndef _MODBUS_H_ #define _MODBUS_H_ #include #include #include #include "tcp.h" #include enum { FC1 = 0, FC2, FC3, FC4, FCCOUNT }; #define TEXT_LEN 512 #define MODBUS_MAXCLIENTS 5 #define MODBUS_IOBUFFER 0x10000 struct modbus_data { char hostname[TEXT_LEN]; char buffer[0x10000]; size_t bufferlen; int transactionid; int protoolid; int length; int unitid; int direction; int fc; int regstart; int regcnt; int bytecnt; }; // return the cycletime in us std::string to_hex16 (int v); float get_cycletime(struct timeval *t); struct { uint16_t value; bool enabled; int requested; // 1 .. Read 2 .. Write bool updated; } typedef ModbusRegister; struct modbus_callback_data { int fc; int regstart; int count; ModbusRegister *r; }; class ModbusSrv { private: TCP tcpserver; int port; TCP *clients[MODBUS_MAXCLIENTS]; GThread *serverthread; GMutex servermutex; gboolean (*onchangecallback)(gpointer data); ModbusRegister mbarray[FCCOUNT][MODBUS_IOBUFFER]; // for all 4 Registertypes .. char inbuffer[MODBUS_IOBUFFER]; char outbuffer[MODBUS_IOBUFFER]; void Decode(struct modbus_data *mbdata); // return 0 on error, 1 on no error int WorkerAndEncodeRead(struct modbus_data *mbin, struct modbus_data *mbout); int WorkerAndEncodeWriteSingle(struct modbus_data *mbin, struct modbus_data *mbout); int WorkerAndEncodeWriteMulti(struct modbus_data *mbin, struct modbus_data *mbout); public: ModbusSrv(); ~ModbusSrv(); void ServerThread(); void SetCallback (gboolean (*callback_func)(gpointer data)); int Start(int serverport); void Stop(); int GetRegister(int fc, int regnum, ModbusRegister *r); int GetRegisters(int fc, int regnum, int count, ModbusRegister *r); int SetRegister(int fc, int regnum, ModbusRegister *r); int SetRegisters(int fc, int regnum, int count, ModbusRegister *r); void CloseConnection(int slot); void ReadData(gpointer pdata); void Enable(int fc, int regstart, int count, int onoff); void EnableAll(int onoff); void RequestsClear(); void SetRegValue(int fc, int regstart, int count, uint16_t *values); int isRunning(); }; class ModbusCli { private: public: ModbusCli() {}; ~ModbusCli() {}; }; #if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) #define usleep(_us_) Sleep(_us_/1000) #endif #endif