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