Commit f98f5e49 authored by Pavel Vainerman's avatar Pavel Vainerman

(Modbus):

- добавил проверку корректности ответов (сколько регистров запрашивали, столько и пришло) - (MBSlave): добавил проверку корректности параметров запроса - небольшой рефакторинг внутренних названий - добавил два новых кода ошибки (10,11 - ошибка в работе шлюза) - сделал в соответсвии со стандартом, broadcast адрес = 0 (а не 255).
parent 28f38ae3
...@@ -26,7 +26,7 @@ static void print_help() ...@@ -26,7 +26,7 @@ static void print_help()
printf("[-v|--verbose] - Print all messages to stdout\n"); printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n"); printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-a|--myaddr] addr1,addr2,... - Modbus address for this slave. Default: 0x01.\n"); printf("[-a|--myaddr] addr1,addr2,... - Modbus address for this slave. Default: 0x01.\n");
printf(" myaddr=255 - Reply to all RTU-addresses.\n"); printf(" myaddr=0 - Reply to all RTU-addresses (broadcast).\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n"); printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-v|--verbose] - Print all messages to stdout\n"); printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-g|--f485] - Use 485 Fastwel\n"); printf("[-g|--f485] - Use 485 Fastwel\n");
......
...@@ -27,7 +27,7 @@ static void print_help() ...@@ -27,7 +27,7 @@ static void print_help()
printf("[-v|--verbose] - Print all messages to stdout\n"); printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-i|--iaddr] ip - Server listen ip. Default 127.0.0.1\n"); printf("[-i|--iaddr] ip - Server listen ip. Default 127.0.0.1\n");
printf("[-a|--myaddr] addr1,addr2,... - Modbus address for master. Default: 0x01.\n"); printf("[-a|--myaddr] addr1,addr2,... - Modbus address for master. Default: 0x01.\n");
printf(" myaddr=255 - Reply to all RTU-addresses.\n"); printf(" myaddr=0 - Reply to all RTU-addresses (broadcast).\n");
printf("[-p|--port] port - Server port. Default: 502.\n"); printf("[-p|--port] port - Server port. Default: 502.\n");
printf("[-c|--const-reply] val - Reply 'val' for all queries\n"); printf("[-c|--const-reply] val - Reply 'val' for all queries\n");
printf("[-s|--after-send-pause] msec - Pause after send request. Default: 0\n"); printf("[-s|--after-send-pause] msec - Pause after send request. Default: 0\n");
......
...@@ -2152,8 +2152,8 @@ namespace uniset ...@@ -2152,8 +2152,8 @@ namespace uniset
( p.stype == UniversalIO::AI || ( p.stype == UniversalIO::AI ||
p.stype == UniversalIO::AO ) ) p.stype == UniversalIO::AO ) )
{ {
mbwarn << "(initRSProperty): (ignore) uncorrect param`s nbit>1 (" << p.nbit << ")" mbwarn << "(initRSProperty): (ignore) uncorrect param`s nbit!=0(" << p.nbit << ")"
<< " but iotype=" << p.stype << " for " << it.getProp("name") << endl; << " for iotype=" << p.stype << " for " << it.getProp("name") << endl;
} }
string sbyte(IOBase::initProp(it, "nbyte", prop_prefix, false) ); string sbyte(IOBase::initProp(it, "nbyte", prop_prefix, false) );
......
...@@ -1638,7 +1638,13 @@ namespace uniset ...@@ -1638,7 +1638,13 @@ namespace uniset
return ModbusRTU::erTimeOut; return ModbusRTU::erTimeOut;
} }
if( query.count <= 1 ) if( query.count <= 0 )
{
mbinfo << myname << "(readOutputRegisters): BAD QUERY: count=0!" << endl;
return ModbusRTU::erBadDataValue;
}
if( query.count == 1 )
{ {
ModbusRTU::ModbusData d = 0; ModbusRTU::ModbusData d = 0;
ModbusRTU::mbErrCode ret = real_read(regmap->second, query.start, d, query.func); ModbusRTU::mbErrCode ret = real_read(regmap->second, query.start, d, query.func);
...@@ -2435,7 +2441,13 @@ namespace uniset ...@@ -2435,7 +2441,13 @@ namespace uniset
return ModbusRTU::erTimeOut; return ModbusRTU::erTimeOut;
} }
if( query.count <= 1 ) if( query.count <= 0 )
{
mbinfo << myname << "(readInputRegisters): BAD QUERY: count=0!" << endl;
return ModbusRTU::erBadDataValue;
}
if( query.count == 1 )
{ {
ModbusRTU::ModbusData d = 0; ModbusRTU::ModbusData d = 0;
ModbusRTU::mbErrCode ret = real_read(regmap->second, query.start, d, query.func); ModbusRTU::mbErrCode ret = real_read(regmap->second, query.start, d, query.func);
...@@ -2500,9 +2512,15 @@ namespace uniset ...@@ -2500,9 +2512,15 @@ namespace uniset
return ModbusRTU::erTimeOut; return ModbusRTU::erTimeOut;
} }
if( query.count <= 0 )
{
mbinfo << myname << "(readCoilStatus): BAD QUERY: count=0!" << endl;
return ModbusRTU::erBadDataValue;
}
try try
{ {
if( query.count <= 1 ) if( query.count == 1 )
{ {
ModbusRTU::ModbusData d = 0; ModbusRTU::ModbusData d = 0;
ModbusRTU::mbErrCode ret = real_read(regmap->second, query.start, d, query.func); ModbusRTU::mbErrCode ret = real_read(regmap->second, query.start, d, query.func);
...@@ -2573,9 +2591,15 @@ namespace uniset ...@@ -2573,9 +2591,15 @@ namespace uniset
return ModbusRTU::erTimeOut; return ModbusRTU::erTimeOut;
} }
if( query.count <= 0 )
{
mbinfo << myname << "(readInputStatus): BAD QUERY: count=0!" << endl;
return ModbusRTU::erBadDataValue;
}
try try
{ {
if( query.count <= 1 ) if( query.count == 1 )
{ {
ModbusRTU::ModbusData d = 0; ModbusRTU::ModbusData d = 0;
ModbusRTU::mbErrCode ret = real_read(regmap->second, query.start, d, query.func); ModbusRTU::mbErrCode ret = real_read(regmap->second, query.start, d, query.func);
......
...@@ -110,7 +110,7 @@ TEST_CASE("Function (0x03): 'read register outputs or memories or read word outp ...@@ -110,7 +110,7 @@ TEST_CASE("Function (0x03): 'read register outputs or memories or read word outp
{ {
try try
{ {
mb->read03(slaveaddr, -23, 1200); mb->read03(slaveaddr, 23, 1200);
} }
catch( ModbusRTU::mbException& ex ) catch( ModbusRTU::mbException& ex )
{ {
...@@ -128,17 +128,7 @@ TEST_CASE("Function (0x03): 'read register outputs or memories or read word outp ...@@ -128,17 +128,7 @@ TEST_CASE("Function (0x03): 'read register outputs or memories or read word outp
REQUIRE( ex.err == ModbusRTU::erBadDataAddress ); REQUIRE( ex.err == ModbusRTU::erBadDataAddress );
} }
} }
SECTION("Test: incorrect number")
{
try
{
mb->read03(slaveaddr, tREG, -3);
}
catch( ModbusRTU::mbException& ex )
{
REQUIRE( ex.err == ModbusRTU::erTimeOut );
}
}
SECTION("Test: zero number") SECTION("Test: zero number")
{ {
try try
...@@ -147,7 +137,7 @@ TEST_CASE("Function (0x03): 'read register outputs or memories or read word outp ...@@ -147,7 +137,7 @@ TEST_CASE("Function (0x03): 'read register outputs or memories or read word outp
} }
catch( ModbusRTU::mbException& ex ) catch( ModbusRTU::mbException& ex )
{ {
REQUIRE( ex.err == ModbusRTU::erTimeOut ); REQUIRE( ex.err == ModbusRTU::erBadDataValue );
} }
} }
} }
...@@ -178,7 +168,7 @@ TEST_CASE("Function (0x04): 'read input registers or memories or read word outpu ...@@ -178,7 +168,7 @@ TEST_CASE("Function (0x04): 'read input registers or memories or read word outpu
{ {
try try
{ {
mb->read04(slaveaddr, -23, 1200); mb->read04(slaveaddr, 23, 1200);
} }
catch( ModbusRTU::mbException& ex ) catch( ModbusRTU::mbException& ex )
{ {
...@@ -196,17 +186,7 @@ TEST_CASE("Function (0x04): 'read input registers or memories or read word outpu ...@@ -196,17 +186,7 @@ TEST_CASE("Function (0x04): 'read input registers or memories or read word outpu
REQUIRE( ex.err == ModbusRTU::erBadDataAddress ); REQUIRE( ex.err == ModbusRTU::erBadDataAddress );
} }
} }
SECTION("Test: incorrect number")
{
try
{
mb->read04(slaveaddr, tREG, -3);
}
catch( ModbusRTU::mbException& ex )
{
REQUIRE( ex.err == ModbusRTU::erTimeOut );
}
}
SECTION("Test: zero number") SECTION("Test: zero number")
{ {
try try
...@@ -215,7 +195,7 @@ TEST_CASE("Function (0x04): 'read input registers or memories or read word outpu ...@@ -215,7 +195,7 @@ TEST_CASE("Function (0x04): 'read input registers or memories or read word outpu
} }
catch( ModbusRTU::mbException& ex ) catch( ModbusRTU::mbException& ex )
{ {
REQUIRE( ex.err == ModbusRTU::erTimeOut ); REQUIRE( ex.err == ModbusRTU::erBadDataValue );
} }
} }
} }
......
...@@ -24,14 +24,18 @@ namespace uniset ...@@ -24,14 +24,18 @@ namespace uniset
erSlaveBusy = 6, /*!< контроллер занят длительной операцией (повторить запрос позже) */ erSlaveBusy = 6, /*!< контроллер занят длительной операцией (повторить запрос позже) */
erOperationFailed = 7, /*!< запрашиваемая функция запрещена конфигурацией контроллера */ erOperationFailed = 7, /*!< запрашиваемая функция запрещена конфигурацией контроллера */
erMemoryParityError = 8, /*!< ошибка паритета при чтении памяти */ erMemoryParityError = 8, /*!< ошибка паритета при чтении памяти */
erGatewayUnavailable = 10, /*!< шлюз не смог обработать запрос */
erGatewayTargetUnavailable = 11, /*!< устройство за шлюзом недоступно */
erInternalErrorCode = 10, /*!< коды ошибок используемые для внутренней работы */ // коды ошибок >= erInternalErrorCode не посылаются в ответах,
erInvalidFormat = 11, /*!< неправильный формат */ // а используются только для внутренней диагностики
erBadCheckSum = 12, /*!< У пакета не сошлась контрольная сумма */ erInternalErrorCode = 100, /*!< коды ошибок используемые для внутренней работы */
erBadReplyNodeAddress = 13, /*!< Ответ на запрос адресован не мне или от станции,которую не спрашивали */ erInvalidFormat = 111, /*!< неправильный формат */
erTimeOut = 14, /*!< Тайм-аут при приеме ответа */ erBadCheckSum = 112, /*!< У пакета не сошлась контрольная сумма */
erPacketTooLong = 15, /*!< пакет длинее буфера приема */ erBadReplyNodeAddress = 113, /*!< Ответ на запрос адресован не мне или от станции, которую не спрашивали */
erSessionClosed = 16 /*!< соединение закрыто */ erTimeOut = 114, /*!< Тайм-аут при приеме ответа */
erPacketTooLong = 115, /*!< пакет длинее буфера приема */
erSessionClosed = 116 /*!< соединение закрыто */
}; };
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
......
...@@ -146,7 +146,7 @@ namespace uniset ...@@ -146,7 +146,7 @@ namespace uniset
std::string iaddr; std::string iaddr;
std::string myname; std::string myname;
std::queue<unsigned char> qrecv; std::queue<unsigned char> qrecv;
ModbusRTU::ADUHeader curQueryHeader; ModbusRTU::MBAPHeader curQueryHeader;
std::mutex sMutex; std::mutex sMutex;
typedef std::list<std::shared_ptr<ModbusTCPSession>> SessionList; typedef std::list<std::shared_ptr<ModbusTCPSession>> SessionList;
......
...@@ -75,7 +75,7 @@ namespace uniset ...@@ -75,7 +75,7 @@ namespace uniset
virtual size_t getNextData( unsigned char* buf, int len ) override; virtual size_t getNextData( unsigned char* buf, int len ) override;
virtual void setChannelTimeout( timeout_t msec ); virtual void setChannelTimeout( timeout_t msec );
virtual ModbusRTU::mbErrCode sendData( unsigned char* buf, int len ) override; virtual ModbusRTU::mbErrCode sendData( unsigned char* buf, int len ) override;
virtual ModbusRTU::mbErrCode tcp_processing( ModbusRTU::ADUHeader& mhead ); virtual ModbusRTU::mbErrCode tcp_processing( ModbusRTU::MBAPHeader& mhead );
virtual ModbusRTU::mbErrCode make_adu_header( ModbusRTU::ModbusMessage& request ) override; virtual ModbusRTU::mbErrCode make_adu_header( ModbusRTU::ModbusMessage& request ) override;
virtual ModbusRTU::mbErrCode post_send_request(ModbusRTU::ModbusMessage& request ) override; virtual ModbusRTU::mbErrCode post_send_request(ModbusRTU::ModbusMessage& request ) override;
...@@ -124,7 +124,7 @@ namespace uniset ...@@ -124,7 +124,7 @@ namespace uniset
private: private:
std::queue<unsigned char> qrecv; std::queue<unsigned char> qrecv;
std::unordered_set<ModbusRTU::ModbusAddr> vaddr; std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
ModbusRTU::ADUHeader curQueryHeader; ModbusRTU::MBAPHeader curQueryHeader;
PassiveTimer ptTimeout; PassiveTimer ptTimeout;
timeout_t timeout = { 0 }; timeout_t timeout = { 0 };
ModbusRTU::ModbusMessage buf; ModbusRTU::ModbusMessage buf;
......
...@@ -125,7 +125,7 @@ namespace uniset ...@@ -125,7 +125,7 @@ namespace uniset
{ {
/*! максимальное количество данных в пакете (c учётом контрольной суммы) */ /*! максимальное количество данных в пакете (c учётом контрольной суммы) */
MAXLENPACKET = 508, /*!< максимальная длина пакета 512 - header(2) - CRC(2) */ MAXLENPACKET = 508, /*!< максимальная длина пакета 512 - header(2) - CRC(2) */
BroadcastAddr = 255, /*!< адрес для широковещательных сообщений */ BroadcastAddr = 0, /*!< адрес для широковещательных сообщений */
MAXPDULEN = 253, // 255 - 2(CRC) MAXPDULEN = 253, // 255 - 2(CRC)
MAXDATALEN = 125 /*!< максимальное число слов, которое можно запросить. MAXDATALEN = 125 /*!< максимальное число слов, которое можно запросить.
Связано с тем, что в ответе есть поле bcnt - количество байт Связано с тем, что в ответе есть поле bcnt - количество байт
...@@ -169,19 +169,19 @@ namespace uniset ...@@ -169,19 +169,19 @@ namespace uniset
std::ostream& operator<<(std::ostream& os, const ModbusHeader& m ); std::ostream& operator<<(std::ostream& os, const ModbusHeader& m );
std::ostream& operator<<(std::ostream& os, const ModbusHeader* m ); std::ostream& operator<<(std::ostream& os, const ModbusHeader* m );
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
struct ADUHeader struct MBAPHeader
{ {
ModbusRTU::ModbusData tID; /*!< transaction ID */ ModbusRTU::ModbusData tID; /*!< transaction ID */
ModbusRTU::ModbusData pID; /*!< protocol ID */ ModbusRTU::ModbusData pID; /*!< protocol ID */
ModbusRTU::ModbusData len; /*!< lenght */ ModbusRTU::ModbusData len; /*!< lenght */
ADUHeader(): tID(0), pID(0), len(0) {} MBAPHeader(): tID(0), pID(0), len(0) {}
void swapdata(); void swapdata();
} __attribute__((packed)); } __attribute__((packed));
std::ostream& operator<<(std::ostream& os, const ADUHeader& m ); std::ostream& operator<<(std::ostream& os, const MBAPHeader& m );
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
/*! Базовое (сырое) сообщение /*! Базовое (сырое) сообщение
...@@ -206,21 +206,21 @@ namespace uniset ...@@ -206,21 +206,21 @@ namespace uniset
} }
inline ModbusRTU::ModbusData tID() const inline ModbusRTU::ModbusData tID() const
{ {
return aduhead.tID; return mbaphead.tID;
} }
inline ModbusRTU::ModbusData pID() const inline ModbusRTU::ModbusData pID() const
{ {
return aduhead.pID; return mbaphead.pID;
} }
inline ModbusRTU::ModbusData aduLen() const inline ModbusRTU::ModbusData aduLen() const
{ {
return aduhead.len; return mbaphead.len;
} }
unsigned char* buf(); unsigned char* buf();
ModbusRTU::ModbusData len() const; ModbusRTU::ModbusData len() const;
void swapHead(); void swapHead();
void makeHead( ModbusRTU::ModbusData tID, bool noCRC = true, ModbusRTU::ModbusData pID = 0 ); void makeMBAPHeader( ModbusRTU::ModbusData tID, bool noCRC = true, ModbusRTU::ModbusData pID = 0 );
ModbusRTU::ModbusData pduLen() const; ModbusRTU::ModbusData pduLen() const;
ModbusCRC pduCRC( size_t len ) const; ModbusCRC pduCRC( size_t len ) const;
...@@ -228,7 +228,7 @@ namespace uniset ...@@ -228,7 +228,7 @@ namespace uniset
void clear(); void clear();
ADUHeader aduhead; MBAPHeader mbaphead;
ModbusHeader pduhead; ModbusHeader pduhead;
ModbusByte data[MAXLENPACKET + szCRC]; /*!< данные */ ModbusByte data[MAXLENPACKET + szCRC]; /*!< данные */
......
...@@ -66,7 +66,14 @@ namespace uniset ...@@ -66,7 +66,14 @@ namespace uniset
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms); mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError ) if( res == erNoError )
return ReadCoilRetMessage(qreply); {
ReadCoilRetMessage ret(qreply);
if( ret.bcnt != (count*2) )
throw mbException(erBadDataValue);
return ret;
}
throw mbException(res); throw mbException(res);
} }
...@@ -80,7 +87,14 @@ namespace uniset ...@@ -80,7 +87,14 @@ namespace uniset
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms); mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError ) if( res == erNoError )
return ReadInputStatusRetMessage(qreply); {
ReadInputStatusRetMessage ret(qreply);
if( ret.bcnt != (count*2) )
throw mbException(erBadDataValue);
return ret;
}
throw mbException(res); throw mbException(res);
} }
...@@ -96,7 +110,14 @@ namespace uniset ...@@ -96,7 +110,14 @@ namespace uniset
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms); mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError ) if( res == erNoError )
return ReadOutputRetMessage(qreply); {
ReadOutputRetMessage ret(qreply);
if( ret.count != count )
throw mbException(erBadDataValue);
return ret;
}
throw mbException(res); throw mbException(res);
} }
...@@ -110,7 +131,14 @@ namespace uniset ...@@ -110,7 +131,14 @@ namespace uniset
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms); mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError ) if( res == erNoError )
return ReadInputRetMessage(qreply); {
ReadInputRetMessage ret(qreply);
if( ret.count != count )
throw mbException(erBadDataValue);
return ret;
}
throw mbException(res); throw mbException(res);
} }
...@@ -125,7 +153,17 @@ namespace uniset ...@@ -125,7 +153,17 @@ namespace uniset
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms); mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError ) if( res == erNoError )
return ForceSingleCoilRetMessage(qreply); {
ForceSingleCoilRetMessage ret(qreply);
if( ret.start != start )
throw mbException(erBadDataValue);
if( ret.cmd() != cmd )
throw mbException(erBadDataValue);
return ret;
}
throw mbException(res); throw mbException(res);
} }
...@@ -141,7 +179,17 @@ namespace uniset ...@@ -141,7 +179,17 @@ namespace uniset
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms); mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError ) if( res == erNoError )
return WriteSingleOutputRetMessage(qreply); {
WriteSingleOutputRetMessage ret(qreply);
if( ret.start != start )
throw mbException(erBadDataValue);
if( ret.data != data )
throw mbException(erBadDataValue);
return ret;
}
throw mbException(res); throw mbException(res);
} }
...@@ -153,7 +201,17 @@ namespace uniset ...@@ -153,7 +201,17 @@ namespace uniset
mbErrCode res = query(msg.addr, qbuf, qreply, replyTimeOut_ms); mbErrCode res = query(msg.addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError ) if( res == erNoError )
return ForceCoilsRetMessage(qreply); {
ForceCoilsRetMessage ret(qreply);
if( ret.start != msg.start )
throw mbException(erBadDataValue);
if( ret.quant != msg.quant )
throw mbException(erBadDataValue);
return ret;
}
throw mbException(res); throw mbException(res);
} }
...@@ -166,7 +224,17 @@ namespace uniset ...@@ -166,7 +224,17 @@ namespace uniset
mbErrCode res = query(msg.addr, qbuf, qreply, replyTimeOut_ms); mbErrCode res = query(msg.addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError ) if( res == erNoError )
return WriteOutputRetMessage(qreply); {
WriteOutputRetMessage ret(qreply);
if( ret.start != msg.start )
throw mbException(erBadDataValue);
if( ret.quant != msg.quant )
throw mbException(erBadDataValue);
return ret;
}
throw mbException(res); throw mbException(res);
} }
...@@ -181,7 +249,14 @@ namespace uniset ...@@ -181,7 +249,14 @@ namespace uniset
mbErrCode res = query(msg.addr, qbuf, qreply, replyTimeOut_ms); mbErrCode res = query(msg.addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError ) if( res == erNoError )
return DiagnosticRetMessage(qreply); {
DiagnosticRetMessage ret(qreply);
if( ret.subf != subfunc )
throw mbException(erBadDataValue);
return ret;
}
throw mbException(res); throw mbException(res);
} }
...@@ -196,7 +271,17 @@ namespace uniset ...@@ -196,7 +271,17 @@ namespace uniset
mbErrCode res = query(msg.addr, qbuf, qreply, replyTimeOut_ms); mbErrCode res = query(msg.addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError ) if( res == erNoError )
return MEIMessageRetRDI(qreply); {
MEIMessageRetRDI ret(qreply);
if( ret.devID != devID )
throw mbException(erBadDataValue);
if( ret.objID != objID )
throw mbException(erBadDataValue);
return ret;
}
throw mbException(res); throw mbException(res);
} }
......
...@@ -122,7 +122,8 @@ namespace uniset ...@@ -122,7 +122,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && mRead.addr != BroadcastAddr )
{ {
ErrorRetMessage em( mRead.addr, mRead.func, res ); ErrorRetMessage em( mRead.addr, mRead.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -155,7 +156,8 @@ namespace uniset ...@@ -155,7 +156,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && mRead.addr != BroadcastAddr )
{ {
ErrorRetMessage em( mRead.addr, mRead.func, res ); ErrorRetMessage em( mRead.addr, mRead.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -188,7 +190,8 @@ namespace uniset ...@@ -188,7 +190,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && mRead.addr != BroadcastAddr )
{ {
ErrorRetMessage em( mRead.addr, mRead.func, res ); ErrorRetMessage em( mRead.addr, mRead.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -221,7 +224,8 @@ namespace uniset ...@@ -221,7 +224,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && mRead.addr != BroadcastAddr )
{ {
ErrorRetMessage em( mRead.addr, mRead.func, res ); ErrorRetMessage em( mRead.addr, mRead.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -255,7 +259,8 @@ namespace uniset ...@@ -255,7 +259,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && mWrite.addr != BroadcastAddr )
{ {
ErrorRetMessage em( mWrite.addr, mWrite.func, res ); ErrorRetMessage em( mWrite.addr, mWrite.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -289,7 +294,8 @@ namespace uniset ...@@ -289,7 +294,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && mWrite.addr != BroadcastAddr )
{ {
ErrorRetMessage em( mWrite.addr, mWrite.func, res ); ErrorRetMessage em( mWrite.addr, mWrite.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -321,7 +327,8 @@ namespace uniset ...@@ -321,7 +327,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && mDiag.addr != BroadcastAddr )
{ {
ErrorRetMessage em( mDiag.addr, mDiag.func, res ); ErrorRetMessage em( mDiag.addr, mDiag.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -353,7 +360,8 @@ namespace uniset ...@@ -353,7 +360,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && mRDI.addr != BroadcastAddr )
{ {
ErrorRetMessage em( mRDI.addr, mRDI.func, res ); ErrorRetMessage em( mRDI.addr, mRDI.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -386,7 +394,8 @@ namespace uniset ...@@ -386,7 +394,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && mWrite.addr != BroadcastAddr )
{ {
ErrorRetMessage em( mWrite.addr, mWrite.func, res ); ErrorRetMessage em( mWrite.addr, mWrite.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -420,7 +429,8 @@ namespace uniset ...@@ -420,7 +429,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && mWrite.addr != BroadcastAddr )
{ {
ErrorRetMessage em( mWrite.addr, mWrite.func, res ); ErrorRetMessage em( mWrite.addr, mWrite.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -453,7 +463,8 @@ namespace uniset ...@@ -453,7 +463,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && mJournal.addr != BroadcastAddr )
{ {
ErrorRetMessage em( mJournal.addr, mJournal.func, res ); ErrorRetMessage em( mJournal.addr, mJournal.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -486,7 +497,8 @@ namespace uniset ...@@ -486,7 +497,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && mSet.addr != BroadcastAddr )
{ {
ErrorRetMessage em( mSet.addr, mSet.func, res ); ErrorRetMessage em( mSet.addr, mSet.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -519,7 +531,8 @@ namespace uniset ...@@ -519,7 +531,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && query.addr != BroadcastAddr )
{ {
ErrorRetMessage em( query.addr, query.func, res ); ErrorRetMessage em( query.addr, query.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
...@@ -552,7 +565,8 @@ namespace uniset ...@@ -552,7 +565,8 @@ namespace uniset
// Если ошибка подразумевает посылку ответа с сообщением об ошибке // Если ошибка подразумевает посылку ответа с сообщением об ошибке
// то посылаем // то посылаем
if( res < erInternalErrorCode ) // если адрес запроса является broadcast-овым, то ответ тоже не посылается
if( res < erInternalErrorCode && query.addr != BroadcastAddr )
{ {
ErrorRetMessage em( query.addr, query.func, res ); ErrorRetMessage em( query.addr, query.func, res );
buf = em.transport_msg(); buf = em.transport_msg();
......
...@@ -114,7 +114,7 @@ namespace uniset ...@@ -114,7 +114,7 @@ namespace uniset
ptTimeout.setTiming(timeout_msec); ptTimeout.setTiming(timeout_msec);
tcp->setReceiveTimeout( UniSetTimer::millisecToPoco(timeout_msec) ); tcp->setReceiveTimeout( UniSetTimer::millisecToPoco(timeout_msec) );
msg.makeHead(++nTransaction, crcNoCheckit); msg.makeMBAPHeader(++nTransaction, crcNoCheckit);
for( size_t i = 0; i < 2; i++ ) for( size_t i = 0; i < 2; i++ )
{ {
...@@ -170,20 +170,20 @@ namespace uniset ...@@ -170,20 +170,20 @@ namespace uniset
while( !ptTimeout.checkTime() ) while( !ptTimeout.checkTime() )
{ {
ret = getNextData((unsigned char*)(&reply.aduhead), sizeof(reply.aduhead)); ret = getNextData((unsigned char*)(&reply.mbaphead), sizeof(reply.mbaphead));
if( ret == sizeof(reply.aduhead) ) if( ret == sizeof(reply.mbaphead) )
break; break;
} }
if( ret > 0 && dlog->is_info() ) if( ret > 0 && dlog->is_info() )
{ {
dlog->info() << "(ModbusTCPMaster::query): recv tcp header(" << ret << "): "; dlog->info() << "(ModbusTCPMaster::query): recv tcp header(" << ret << "): ";
mbPrintMessage( dlog->info(false), (ModbusByte*)(&reply.aduhead), sizeof(reply.aduhead)); mbPrintMessage( dlog->info(false), (ModbusByte*)(&reply.mbaphead), sizeof(reply.mbaphead));
dlog->info(false) << endl; dlog->info(false) << endl;
} }
if( ret < sizeof(reply.aduhead) ) if( ret < sizeof(reply.mbaphead) )
{ {
if( dlog->is_warn() ) if( dlog->is_warn() )
{ {
...@@ -192,7 +192,7 @@ namespace uniset ...@@ -192,7 +192,7 @@ namespace uniset
Poco::Net::SocketAddress ia = tcp->peerAddress(); Poco::Net::SocketAddress ia = tcp->peerAddress();
dlog->warn() << "(ModbusTCPMaster::query): ret=" << ret dlog->warn() << "(ModbusTCPMaster::query): ret=" << ret
<< " < rmh=" << sizeof(reply.aduhead) << " < rmh=" << sizeof(reply.mbaphead)
<< " perr: " << ia.host().toString() << ":" << ia.port() << " perr: " << ia.host().toString() << ":" << ia.port()
<< endl; << endl;
} }
......
...@@ -216,7 +216,7 @@ namespace uniset ...@@ -216,7 +216,7 @@ namespace uniset
try try
{ {
buf.clear(); buf.clear();
res = tcp_processing(buf.aduhead); res = tcp_processing(buf.mbaphead);
if( res != erNoError ) if( res != erNoError )
return res; return res;
...@@ -237,7 +237,7 @@ namespace uniset ...@@ -237,7 +237,7 @@ namespace uniset
// запоминаем принятый заголовок, // запоминаем принятый заголовок,
// для формирования ответа (см. make_adu_header) // для формирования ответа (см. make_adu_header)
curQueryHeader = buf.aduhead; curQueryHeader = buf.mbaphead;
if( dlog->is_level9() ) if( dlog->is_level9() )
dlog->level9() << "(ModbusTCPSession::recv): ADU len=" << curQueryHeader.len << endl; dlog->level9() << "(ModbusTCPSession::recv): ADU len=" << curQueryHeader.len << endl;
...@@ -325,7 +325,7 @@ namespace uniset ...@@ -325,7 +325,7 @@ namespace uniset
return 0; return 0;
} }
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
mbErrCode ModbusTCPSession::tcp_processing( ModbusRTU::ADUHeader& mhead ) mbErrCode ModbusTCPSession::tcp_processing( ModbusRTU::MBAPHeader& mhead )
{ {
// чистим очередь // чистим очередь
while( !qrecv.empty() ) while( !qrecv.empty() )
...@@ -409,7 +409,7 @@ namespace uniset ...@@ -409,7 +409,7 @@ namespace uniset
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
mbErrCode ModbusTCPSession::make_adu_header( ModbusMessage& req ) mbErrCode ModbusTCPSession::make_adu_header( ModbusMessage& req )
{ {
req.makeHead(curQueryHeader.tID, isCRCNoCheckit(), curQueryHeader.pID); req.makeMBAPHeader(curQueryHeader.tID, isCRCNoCheckit(), curQueryHeader.pID);
return erNoError; return erNoError;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
......
...@@ -246,33 +246,33 @@ namespace uniset ...@@ -246,33 +246,33 @@ namespace uniset
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
unsigned char* ModbusMessage::buf() unsigned char* ModbusMessage::buf()
{ {
if( aduhead.len == 0 ) if( mbaphead.len == 0 )
return (unsigned char*)&pduhead; return (unsigned char*)&pduhead;
return (unsigned char*)&aduhead; return (unsigned char*)&mbaphead;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
ModbusData ModbusMessage::len() const ModbusData ModbusMessage::len() const
{ {
if( aduhead.len == 0 ) if( mbaphead.len == 0 )
return pduLen(); return pduLen();
return (sizeof(aduhead) + aduhead.len); return (sizeof(mbaphead) + mbaphead.len);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void ModbusMessage::swapHead() void ModbusMessage::swapHead()
{ {
aduhead.swapdata(); mbaphead.swapdata();
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void ModbusMessage::makeHead( ModbusData tID, bool noCRC, ModbusData pID ) void ModbusMessage::makeMBAPHeader( ModbusData tID, bool noCRC, ModbusData pID )
{ {
aduhead.tID = tID; mbaphead.tID = tID;
aduhead.pID = pID; mbaphead.pID = pID;
aduhead.len = pduLen(); mbaphead.len = pduLen();
if( noCRC ) if( noCRC )
aduhead.len -= szCRC; mbaphead.len -= szCRC;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
ModbusData ModbusMessage::pduLen() const ModbusData ModbusMessage::pduLen() const
...@@ -287,7 +287,7 @@ namespace uniset ...@@ -287,7 +287,7 @@ namespace uniset
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
size_t ModbusMessage::maxSizeOfMessage() size_t ModbusMessage::maxSizeOfMessage()
{ {
return (MAXLENPACKET + szModbusHeader + sizeof(ModbusRTU::ADUHeader)); return (MAXLENPACKET + szModbusHeader + sizeof(ModbusRTU::MBAPHeader));
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void ModbusMessage::clear() void ModbusMessage::clear()
...@@ -297,7 +297,7 @@ namespace uniset ...@@ -297,7 +297,7 @@ namespace uniset
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
std::ostream& ModbusRTU::operator<<(std::ostream& os, const ModbusMessage& m ) std::ostream& ModbusRTU::operator<<(std::ostream& os, const ModbusMessage& m )
{ {
os << m.aduhead << "| "; os << m.mbaphead << "| ";
if( m.aduLen() == 0 ) if( m.aduLen() == 0 )
mbPrintMessage(os, (ModbusByte*)(&m.pduhead), sizeof(m.pduhead) + m.dlen); mbPrintMessage(os, (ModbusByte*)(&m.pduhead), sizeof(m.pduhead) + m.dlen);
...@@ -2987,7 +2987,7 @@ namespace uniset ...@@ -2987,7 +2987,7 @@ namespace uniset
return "У пакета не сошлась контрольная сумма"; return "У пакета не сошлась контрольная сумма";
case erBadReplyNodeAddress: case erBadReplyNodeAddress:
return "Ответ на запрос адресован не мне или от станции,которую не спрашивали"; return "Ответ на запрос адресован не мне или от станции, которую не спрашивали";
case erTimeOut: case erTimeOut:
return "Тайм-аут при приеме"; return "Тайм-аут при приеме";
...@@ -3005,7 +3005,7 @@ namespace uniset ...@@ -3005,7 +3005,7 @@ namespace uniset
return "регистр не существует или запрещён к опросу"; return "регистр не существует или запрещён к опросу";
case erBadDataValue: case erBadDataValue:
return "значение не входит в разрешённый диапазон"; return "недопустимое значение";
case erAnknowledge: case erAnknowledge:
return "запрос принят в исполнению, но ещё не выполнен"; return "запрос принят в исполнению, но ещё не выполнен";
...@@ -3019,6 +3019,12 @@ namespace uniset ...@@ -3019,6 +3019,12 @@ namespace uniset
case erMemoryParityError: case erMemoryParityError:
return "ошибка паритета при чтении памяти"; return "ошибка паритета при чтении памяти";
case erGatewayUnavailable:
return "шлюз не смог обработать запрос";
case erGatewayTargetUnavailable:
return "устройство за шлюзом не отвечает";
default: default:
return "Неизвестный код ошибки"; return "Неизвестный код ошибки";
} }
...@@ -3589,12 +3595,12 @@ namespace uniset ...@@ -3589,12 +3595,12 @@ namespace uniset
return mbPrintMessage(os, (ModbusByte*)m, szModbusHeader + m->szData() ); return mbPrintMessage(os, (ModbusByte*)m, szModbusHeader + m->szData() );
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
std::ostream& ModbusRTU::operator<<(std::ostream& os, const ModbusRTU::ADUHeader& m ) std::ostream& ModbusRTU::operator<<(std::ostream& os, const ModbusRTU::MBAPHeader& m )
{ {
return mbPrintMessage(os, (ModbusByte*)(&m), sizeof(m)); return mbPrintMessage(os, (ModbusByte*)(&m), sizeof(m));
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
void ModbusRTU::ADUHeader::swapdata() void ModbusRTU::MBAPHeader::swapdata()
{ {
tID = SWAPSHORT(tID); tID = SWAPSHORT(tID);
pID = SWAPSHORT(pID); pID = SWAPSHORT(pID);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment