Commit eb6f42a3 authored by Pavel Vainerman's avatar Pavel Vainerman

(ModbusSlave): ГЛОБАЛЬНОЕ ПЕРЕПИСЫВАНИЕ ФОРМАТОВ.

Чтобы посылать в соответсвии со стандартом, посылать сообщение одним "пакетом" (по крайней мере одним write(buf,len), изменён формат ModbusMessage. А также проведён небольшой рефакторинг классов ModbusXXX.
parent bb43c2e0
...@@ -170,12 +170,12 @@ class ModbusClient ...@@ -170,12 +170,12 @@ class ModbusClient
\param len - size of buf \param len - size of buf
\return real data lenght ( must be <= len ) \return real data lenght ( must be <= len )
*/ */
virtual size_t getNextData( unsigned char* buf, int len ) = 0; virtual size_t getNextData( unsigned char* buf, size_t len ) = 0;
/*! set timeout for send/receive data */ /*! set timeout for send/receive data */
virtual void setChannelTimeout( timeout_t msec ) = 0; virtual void setChannelTimeout( timeout_t msec ) = 0;
virtual ModbusRTU::mbErrCode sendData( unsigned char* buf, int len ) = 0; virtual ModbusRTU::mbErrCode sendData( unsigned char* buf, size_t len ) = 0;
/*! функция запрос-ответ */ /*! функция запрос-ответ */
virtual ModbusRTU::mbErrCode query( ModbusRTU::ModbusAddr addr, ModbusRTU::ModbusMessage& msg, virtual ModbusRTU::mbErrCode query( ModbusRTU::ModbusAddr addr, ModbusRTU::ModbusMessage& msg,
......
...@@ -46,12 +46,12 @@ class ModbusRTUMaster: ...@@ -46,12 +46,12 @@ class ModbusRTUMaster:
\param len - size of buf \param len - size of buf
\return real data lenght ( must be <= len ) \return real data lenght ( must be <= len )
*/ */
virtual size_t getNextData( unsigned char* buf, int len ) override; virtual size_t getNextData( unsigned char* buf, size_t len ) override;
/*! set timeout for send/receive data */ /*! set timeout for send/receive data */
virtual void setChannelTimeout( timeout_t msec ) override; virtual void setChannelTimeout( timeout_t msec ) override;
virtual ModbusRTU::mbErrCode sendData( unsigned char* buf, int len ) override; virtual ModbusRTU::mbErrCode sendData( unsigned char* buf, size_t len ) override;
/*! функция запрос-ответ */ /*! функция запрос-ответ */
virtual ModbusRTU::mbErrCode query( ModbusRTU::ModbusAddr addr, ModbusRTU::ModbusMessage& msg, virtual ModbusRTU::mbErrCode query( ModbusRTU::ModbusAddr addr, ModbusRTU::ModbusMessage& msg,
......
...@@ -299,11 +299,11 @@ class ModbusServer ...@@ -299,11 +299,11 @@ class ModbusServer
virtual ModbusRTU::mbErrCode send( ModbusRTU::ModbusMessage& buf ); virtual ModbusRTU::mbErrCode send( ModbusRTU::ModbusMessage& buf );
// Если заголовок не должен использоваться оставляйте request.header.len = 0 // Если заголовок не должен использоваться оставляйте request.header.len = 0
virtual ModbusRTU::mbErrCode make_adu_header( ModbusTCP::ADU& request ) virtual ModbusRTU::mbErrCode make_adu_header( ModbusRTU::ModbusMessage& request )
{ {
return ModbusRTU::erNoError; return ModbusRTU::erNoError;
} }
virtual ModbusRTU::mbErrCode post_send_request( ModbusTCP::ADU& request ) virtual ModbusRTU::mbErrCode post_send_request( ModbusRTU::ModbusMessage& request )
{ {
return ModbusRTU::erNoError; return ModbusRTU::erNoError;
} }
......
...@@ -50,9 +50,9 @@ class ModbusTCPMaster: ...@@ -50,9 +50,9 @@ class ModbusTCPMaster:
protected: protected:
virtual size_t getNextData( unsigned char* buf, int len ) override; virtual size_t getNextData(unsigned char* buf, size_t len ) override;
virtual void setChannelTimeout( timeout_t msec ) override; virtual void setChannelTimeout( timeout_t msec ) override;
virtual ModbusRTU::mbErrCode sendData( unsigned char* buf, int len ) override; virtual ModbusRTU::mbErrCode sendData( unsigned char* buf, size_t len ) override;
virtual ModbusRTU::mbErrCode query( ModbusRTU::ModbusAddr addr, ModbusRTU::ModbusMessage& msg, virtual ModbusRTU::mbErrCode query( ModbusRTU::ModbusAddr addr, ModbusRTU::ModbusMessage& msg,
ModbusRTU::ModbusMessage& reply, timeout_t timeout ) override; ModbusRTU::ModbusMessage& reply, timeout_t timeout ) override;
......
...@@ -137,7 +137,7 @@ class ModbusTCPServer: ...@@ -137,7 +137,7 @@ class ModbusTCPServer:
ost::InetAddress iaddr; ost::InetAddress iaddr;
std::string myname; std::string myname;
std::queue<unsigned char> qrecv; std::queue<unsigned char> qrecv;
ModbusTCP::MBAPHeader curQueryHeader; ModbusRTU::ADUHeader curQueryHeader;
std::mutex sMutex; std::mutex sMutex;
typedef std::list<std::shared_ptr<ModbusTCPSession>> SessionList; typedef std::list<std::shared_ptr<ModbusTCPSession>> SessionList;
......
...@@ -72,9 +72,9 @@ class ModbusTCPSession: ...@@ -72,9 +72,9 @@ class ModbusTCPSession:
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(ModbusTCP::MBAPHeader& mhead ); virtual ModbusRTU::mbErrCode tcp_processing( ModbusRTU::ADUHeader& mhead );
virtual ModbusRTU::mbErrCode make_adu_header( ModbusTCP::ADU& request ) override; virtual ModbusRTU::mbErrCode make_adu_header( ModbusRTU::ModbusMessage& request ) override;
virtual ModbusRTU::mbErrCode post_send_request( ModbusTCP::ADU& request ) override; virtual ModbusRTU::mbErrCode post_send_request(ModbusRTU::ModbusMessage& request ) override;
virtual ModbusRTU::mbErrCode readCoilStatus( ModbusRTU::ReadCoilMessage& query, virtual ModbusRTU::mbErrCode readCoilStatus( ModbusRTU::ReadCoilMessage& query,
ModbusRTU::ReadCoilRetMessage& reply ); ModbusRTU::ReadCoilRetMessage& reply );
...@@ -120,8 +120,8 @@ class ModbusTCPSession: ...@@ -120,8 +120,8 @@ class ModbusTCPSession:
private: private:
std::queue<unsigned char> qrecv; std::queue<unsigned char> qrecv;
ModbusTCP::MBAPHeader curQueryHeader;
std::unordered_set<ModbusRTU::ModbusAddr> vaddr; std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
ModbusRTU::ADUHeader curQueryHeader;
PassiveTimer ptTimeout; PassiveTimer ptTimeout;
timeout_t timeout = { 0 }; timeout_t timeout = { 0 };
ModbusRTU::ModbusMessage buf; ModbusRTU::ModbusMessage buf;
......
...@@ -21,12 +21,12 @@ ...@@ -21,12 +21,12 @@
namespace ModbusRTU namespace ModbusRTU
{ {
// Базовые типы // Базовые типы
typedef unsigned char ModbusByte; /*!< modbus-байт */ typedef uint8_t ModbusByte; /*!< modbus-байт */
const size_t BitsPerByte = 8; const size_t BitsPerByte = 8;
typedef unsigned char ModbusAddr; /*!< адрес узла в modbus-сети */ typedef uint8_t ModbusAddr; /*!< адрес узла в modbus-сети */
typedef unsigned short ModbusData; /*!< размер данных в modbus-сообщениях */ typedef uint16_t ModbusData; /*!< размер данных в modbus-сообщениях */
const size_t BitsPerData = 16; const size_t BitsPerData = 16;
typedef unsigned short ModbusCRC; /*!< размер CRC16 в modbus-сообщениях */ typedef uint16_t ModbusCRC; /*!< размер CRC16 в modbus-сообщениях */
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
/*! Коды используемых функций (согласно описанию modbus) */ /*! Коды используемых функций (согласно описанию modbus) */
...@@ -132,10 +132,10 @@ namespace ModbusRTU ...@@ -132,10 +132,10 @@ namespace ModbusRTU
const unsigned char MBErrMask = 0x80; const unsigned char MBErrMask = 0x80;
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
unsigned short SWAPSHORT(unsigned short x); uint16_t SWAPSHORT( uint16_t x );
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
/*! Расчёт контрольной суммы */ /*! Расчёт контрольной суммы */
ModbusCRC checkCRC( ModbusByte* start, int len ); ModbusCRC checkCRC( ModbusByte* start, size_t len );
const size_t szCRC = sizeof(ModbusCRC); /*!< размер данных для контрольной суммы */ const size_t szCRC = sizeof(ModbusCRC); /*!< размер данных для контрольной суммы */
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
/*! вывод сообщения */ /*! вывод сообщения */
...@@ -161,15 +161,29 @@ namespace ModbusRTU ...@@ -161,15 +161,29 @@ namespace ModbusRTU
} __attribute__((packed)); } __attribute__((packed));
const size_t szModbusHeader = sizeof(ModbusHeader); const size_t szModbusHeader = sizeof(ModbusHeader);
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
{
ModbusRTU::ModbusData tID; /*!< transaction ID */
ModbusRTU::ModbusData pID; /*!< protocol ID */
ModbusRTU::ModbusData len; /*!< lenght */
ADUHeader(): tID(0), pID(0), len(0) {}
void swapdata();
} __attribute__((packed));
std::ostream& operator<<(std::ostream& os, const ADUHeader& m );
// -----------------------------------------------------------------------
/*! Базовое (сырое) сообщение /*! Базовое (сырое) сообщение
\todo Может переименовать ModbusMessage в TransportMessage? \todo Может переименовать ModbusMessage в TransportMessage?
*/ */
struct ModbusMessage: struct ModbusMessage
public ModbusHeader
{ {
ModbusMessage(); ModbusMessage();
...@@ -178,10 +192,29 @@ namespace ModbusRTU ...@@ -178,10 +192,29 @@ namespace ModbusRTU
ModbusMessage( const ModbusMessage& ) = default; ModbusMessage( const ModbusMessage& ) = default;
ModbusMessage& operator=(const ModbusMessage& ) = default; ModbusMessage& operator=(const ModbusMessage& ) = default;
inline ModbusByte func() const { return pduhead.func; }
inline ModbusAddr addr() const { return pduhead.addr; }
inline ModbusRTU::ModbusData tID() const { return aduhead.tID; }
inline ModbusRTU::ModbusData pID() const { return aduhead.pID; }
inline ModbusRTU::ModbusData aduLen() const { return aduhead.len; }
unsigned char* buf();
ModbusRTU::ModbusData len() const;
void swapHead();
void makeHead( ModbusRTU::ModbusData tID, bool noCRC = true, ModbusRTU::ModbusData pID=0 );
ModbusRTU::ModbusData pduLen() const;
ModbusCRC pduCRC( size_t len ) const;
static size_t maxSizeOfMessage();
void clear();
ADUHeader aduhead;
ModbusHeader pduhead;
ModbusByte data[MAXLENPACKET + szCRC]; /*!< данные */ ModbusByte data[MAXLENPACKET + szCRC]; /*!< данные */
// Это поле вспомогательное и игнорируется при пересылке // Это поле вспомогательное и игнорируется при пересылке
size_t len = { 0 }; /*!< фактическая длина */ size_t dlen = { 0 }; /*!< фактическая длина сообщения */
} __attribute__((packed)); } __attribute__((packed));
std::ostream& operator<<(std::ostream& os, const ModbusMessage& m ); std::ostream& operator<<(std::ostream& os, const ModbusMessage& m );
...@@ -1573,39 +1606,5 @@ namespace ModbusRTU ...@@ -1573,39 +1606,5 @@ namespace ModbusRTU
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
} // end of ModbusRTU namespace } // end of ModbusRTU namespace
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
namespace ModbusTCP
{
struct MBAPHeader
{
ModbusRTU::ModbusData tID; /*!< transaction ID */
ModbusRTU::ModbusData pID; /*!< protocol ID */
ModbusRTU::ModbusData len; /*!< lenght */
/* ModbusRTU::ModbusByte uID; */ /*!< unit ID */ /* <------- see ModbusHeader */
MBAPHeader(): tID(0), pID(0), len(0) /*,uID(0) */ {}
void swapdata();
} __attribute__((packed));
std::ostream& operator<<(std::ostream& os, const MBAPHeader& m );
// просто агрегированное сообщение
struct ADU
{
MBAPHeader header;
ModbusRTU::ModbusMessage pdu; // здесь ссылка!! (т.к. ADU это просто обёртка для удобной посылки данных)
size_t len = { 0 };
ADU( const ModbusRTU::ModbusMessage& m ):pdu(m),len(sizeof(header) + m.len){}
} __attribute__((packed));
std::ostream& operator<<(std::ostream& os, const ADU& m );
// -----------------------------------------------------------------------
} // end of namespace ModbusTCP
// ---------------------------------------------------------------------------
#endif // ModbusTypes_H_ #endif // ModbusTypes_H_
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
...@@ -124,7 +124,7 @@ int ModbusRTUMaster::getTimeout() ...@@ -124,7 +124,7 @@ int ModbusRTUMaster::getTimeout()
return port->getTimeout(); return port->getTimeout();
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
size_t ModbusRTUMaster::getNextData( unsigned char* buf, int len ) size_t ModbusRTUMaster::getNextData( unsigned char* buf, size_t len )
{ {
// if( !port ) return 0; // if( !port ) return 0;
return port->receiveBlock(buf, len); return port->receiveBlock(buf, len);
...@@ -136,7 +136,7 @@ void ModbusRTUMaster::setChannelTimeout( timeout_t msec ) ...@@ -136,7 +136,7 @@ void ModbusRTUMaster::setChannelTimeout( timeout_t msec )
port->setTimeout(msec); port->setTimeout(msec);
} }
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
mbErrCode ModbusRTUMaster::sendData( unsigned char* buf, int len ) mbErrCode ModbusRTUMaster::sendData(unsigned char* buf, size_t len )
{ {
try try
{ {
...@@ -159,6 +159,6 @@ mbErrCode ModbusRTUMaster::query( ModbusAddr addr, ModbusMessage& msg, ...@@ -159,6 +159,6 @@ mbErrCode ModbusRTUMaster::query( ModbusAddr addr, ModbusMessage& msg,
if( res != erNoError ) if( res != erNoError )
return res; return res;
return recv(addr, msg.func, reply, timeout); return recv(addr, msg.pduhead.func, reply, timeout);
} }
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
...@@ -169,7 +169,7 @@ mbErrCode ModbusRTUSlave::realReceive(const std::unordered_set<ModbusAddr>& vmba ...@@ -169,7 +169,7 @@ mbErrCode ModbusRTUSlave::realReceive(const std::unordered_set<ModbusAddr>& vmba
// то посылаем // то посылаем
if( res < erInternalErrorCode ) if( res < erInternalErrorCode )
{ {
ErrorRetMessage em( buf.addr, buf.func, res ); ErrorRetMessage em( buf.addr(), buf.func(), res );
buf = em.transport_msg(); buf = em.transport_msg();
send(buf); send(buf);
printProcessingTime(); printProcessingTime();
......
...@@ -80,11 +80,11 @@ size_t ModbusTCPCore::getNextData(UTCPStream* tcp, ...@@ -80,11 +80,11 @@ size_t ModbusTCPCore::getNextData(UTCPStream* tcp,
std::queue<unsigned char>& qrecv, std::queue<unsigned char>& qrecv,
unsigned char* buf, size_t len, timeout_t t ) unsigned char* buf, size_t len, timeout_t t )
{ {
if( qrecv.empty() || qrecv.size() < len )
{
if( !tcp || !tcp->isConnected() ) if( !tcp || !tcp->isConnected() )
return 0; return 0;
if( qrecv.empty() )
{
if( len <= 0 ) if( len <= 0 )
len = 7; len = 7;
......
...@@ -49,7 +49,7 @@ ModbusTCPMaster::~ModbusTCPMaster() ...@@ -49,7 +49,7 @@ ModbusTCPMaster::~ModbusTCPMaster()
tcp.reset(); tcp.reset();
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
size_t ModbusTCPMaster::getNextData( unsigned char* buf, int len ) size_t ModbusTCPMaster::getNextData( unsigned char* buf, size_t len )
{ {
return ModbusTCPCore::getNextData(tcp.get(), qrecv, buf, len); return ModbusTCPCore::getNextData(tcp.get(), qrecv, buf, len);
} }
...@@ -63,7 +63,7 @@ void ModbusTCPMaster::setChannelTimeout( timeout_t msec ) ...@@ -63,7 +63,7 @@ void ModbusTCPMaster::setChannelTimeout( timeout_t msec )
} }
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
mbErrCode ModbusTCPMaster::sendData( unsigned char* buf, int len ) mbErrCode ModbusTCPMaster::sendData( unsigned char* buf, size_t len )
{ {
return ModbusTCPCore::sendData(tcp.get(), buf, len); return ModbusTCPCore::sendData(tcp.get(), buf, len);
} }
...@@ -102,39 +102,12 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg, ...@@ -102,39 +102,12 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
tcp->setTimeout(timeout); tcp->setTimeout(timeout);
// ost::Thread::setException(ost::Thread::throwException); msg.makeHead(++nTransaction,crcNoCheckit);
// ost::tpport_t port;
// cerr << "****** peer: " << tcp->getPeer(&port) << " err: " << tcp->getErrorNumber() << endl;
if( nTransaction >= numeric_limits<ModbusRTU::ModbusData>::max() )
nTransaction = 0;
ModbusTCP::MBAPHeader mh;
mh.tID = ++nTransaction;
mh.pID = 0;
mh.len = msg.len + szModbusHeader;
// mh.uID = addr;
if( crcNoCheckit )
mh.len -= szCRC;
mh.swapdata();
// send TCP header
if( dlog->is_info() )
{
dlog->info() << iaddr << "(ModbusTCPMaster::query): send tcp header(" << sizeof(mh) << "): ";
mbPrintMessage( dlog->info(false), (ModbusByte*)(&mh), sizeof(mh));
dlog->info(false) << endl;
}
for( unsigned int i = 0; i < 2; i++ ) for( unsigned int i = 0; i < 2; i++ )
{ {
if( tcp->isPending(ost::Socket::pendingOutput, timeout) ) if( tcp->isPending(ost::Socket::pendingOutput, timeout) )
{ {
tcp->writeData(&mh, sizeof(mh));
// send PDU
mbErrCode res = send(msg); mbErrCode res = send(msg);
if( res != erNoError ) if( res != erNoError )
...@@ -163,8 +136,6 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg, ...@@ -163,8 +136,6 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
dlog->info() << "(ModbusTCPMaster::query): no write pending.. reconnnect OK" << endl; dlog->info() << "(ModbusTCPMaster::query): no write pending.. reconnnect OK" << endl;
} }
mh.swapdata();
if( timeout != UniSetTimer::WaitUpTime ) if( timeout != UniSetTimer::WaitUpTime )
{ {
timeout = ptTimeout.getLeft(timeout); timeout = ptTimeout.getLeft(timeout);
...@@ -182,19 +153,29 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg, ...@@ -182,19 +153,29 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
tcp->sync(); tcp->sync();
//reply.clear();
if( tcp->isPending(ost::Socket::pendingInput, timeout) ) if( tcp->isPending(ost::Socket::pendingInput, timeout) )
{ {
ModbusTCP::MBAPHeader rmh; size_t ret = 0;
int ret = getNextData((unsigned char*)(&rmh), sizeof(rmh)); while( !ptTimeout.checkTime() )
{
ret = getNextData((unsigned char*)(&reply.aduhead), sizeof(reply.aduhead));
if( dlog->is_info() ) if( ret == sizeof(reply.aduhead) )
break;
if( !tcp->isPending(ost::Socket::pendingInput, timeout) )
break;
}
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*)(&rmh), sizeof(rmh)); mbPrintMessage( dlog->info(false), (ModbusByte*)(&reply.aduhead), sizeof(reply.aduhead));
dlog->info(false) << endl; dlog->info(false) << endl;
} }
if( ret < (int)sizeof(rmh) ) if( ret < sizeof(reply.aduhead) )
{ {
ost::tpport_t port; ost::tpport_t port;
...@@ -204,8 +185,8 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg, ...@@ -204,8 +185,8 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
try try
{ {
dlog->warn() << "(ModbusTCPMaster::query): ret=" << (int)ret dlog->warn() << "(ModbusTCPMaster::query): ret=" << ret
<< " < rmh=" << (int)sizeof(rmh) << " < rmh=" << sizeof(reply.aduhead)
<< " errnum: " << tcp->getErrorNumber() << " errnum: " << tcp->getErrorNumber()
<< " perr: " << tcp->getPeer(&port) << " perr: " << tcp->getPeer(&port)
<< " err: " << (err ? string(err) : "") << " err: " << (err ? string(err) : "")
...@@ -218,19 +199,30 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg, ...@@ -218,19 +199,30 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
} }
} }
cleanInputStream();
tcp->forceDisconnect(); tcp->forceDisconnect();
return erTimeOut; // return erHardwareError; return erTimeOut; // return erHardwareError;
} }
rmh.swapdata(); reply.swapHead();
if( rmh.tID != mh.tID ) if( dlog->is_info() )
dlog->info() << "(ModbusTCPMaster::query): ADU len=" << reply.aduLen()
<< endl;
if( reply.tID() != msg.tID() )
{ {
if( dlog->is_warn() )
dlog->warn() << "(ModbusTCPMaster::query): tID=" << reply.tID()
<< " != " << msg.tID()
<< " (len=" << reply.len() << ")"
<< endl;
cleanInputStream(); cleanInputStream();
return erBadReplyNodeAddress; return erBadReplyNodeAddress;
} }
if( rmh.pID != 0 ) if( reply.pID() != 0 )
{ {
cleanInputStream(); cleanInputStream();
return erBadReplyNodeAddress; return erBadReplyNodeAddress;
...@@ -249,7 +241,8 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg, ...@@ -249,7 +241,8 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
return erTimeOut; // return erHardwareError; return erTimeOut; // return erHardwareError;
} }
mbErrCode res = recv(addr, msg.func, reply, timeout); //msg.aduhead = reply.aduhead;
mbErrCode res = recv(addr, msg.func(), reply, timeout);
if( force_disconnect ) if( force_disconnect )
{ {
......
...@@ -206,8 +206,8 @@ ModbusRTU::mbErrCode ModbusTCPSession::realReceive( const std::unordered_set<Mod ...@@ -206,8 +206,8 @@ ModbusRTU::mbErrCode ModbusTCPSession::realReceive( const std::unordered_set<Mod
ptTimeout.setTiming(msec); ptTimeout.setTiming(msec);
{ {
memset(&curQueryHeader, 0, sizeof(curQueryHeader)); buf.clear();
res = tcp_processing(curQueryHeader); res = tcp_processing(buf.aduhead);
if( res != erNoError ) if( res != erNoError )
return res; return res;
...@@ -223,12 +223,16 @@ ModbusRTU::mbErrCode ModbusTCPSession::realReceive( const std::unordered_set<Mod ...@@ -223,12 +223,16 @@ ModbusRTU::mbErrCode ModbusTCPSession::realReceive( const std::unordered_set<Mod
if( qrecv.empty() ) if( qrecv.empty() )
return erTimeOut; return erTimeOut;
unsigned char q_addr = qrecv.front();
if( cancelled ) if( cancelled )
return erSessionClosed; return erSessionClosed;
memset(&buf, 0, sizeof(buf)); // запоминаем принятый заголовок,
// для формирования ответа (см. make_adu_header)
curQueryHeader = buf.aduhead;
if( dlog->is_info() )
dlog->info() << "(ModbusTCPSession::recv): ADU len=" << curQueryHeader.len << endl;
res = recv( vmbaddr, buf, msec ); res = recv( vmbaddr, buf, msec );
if( cancelled ) if( cancelled )
...@@ -238,7 +242,7 @@ ModbusRTU::mbErrCode ModbusTCPSession::realReceive( const std::unordered_set<Mod ...@@ -238,7 +242,7 @@ ModbusRTU::mbErrCode ModbusTCPSession::realReceive( const std::unordered_set<Mod
{ {
if( res < erInternalErrorCode ) if( res < erInternalErrorCode )
{ {
ErrorRetMessage em( q_addr, buf.func, res ); ErrorRetMessage em( buf.addr(), buf.func(), res );
buf = em.transport_msg(); buf = em.transport_msg();
send(buf); send(buf);
printProcessingTime(); printProcessingTime();
...@@ -300,7 +304,7 @@ size_t ModbusTCPSession::getNextData( unsigned char* buf, int len ) ...@@ -300,7 +304,7 @@ size_t ModbusTCPSession::getNextData( unsigned char* buf, int len )
return 0; return 0;
} }
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
mbErrCode ModbusTCPSession::tcp_processing( ModbusTCP::MBAPHeader& mhead ) mbErrCode ModbusTCPSession::tcp_processing( ModbusRTU::ADUHeader& mhead )
{ {
// чистим очередь // чистим очередь
while( !qrecv.empty() ) while( !qrecv.empty() )
...@@ -321,7 +325,6 @@ mbErrCode ModbusTCPSession::tcp_processing( ModbusTCP::MBAPHeader& mhead ) ...@@ -321,7 +325,6 @@ mbErrCode ModbusTCPSession::tcp_processing( ModbusTCP::MBAPHeader& mhead )
if( dlog->is_info() ) if( dlog->is_info() )
{ {
//dlog->info() << peername << "(tcp_processing): recv tcp header(" << len << "): " << mhead << endl;
dlog->info() << peername << "(tcp_processing): recv tcp header(" << len << "): "; dlog->info() << peername << "(tcp_processing): recv tcp header(" << len << "): ";
mbPrintMessage( dlog->info(false), (ModbusByte*)(&mhead), sizeof(mhead)); mbPrintMessage( dlog->info(false), (ModbusByte*)(&mhead), sizeof(mhead));
dlog->info(false) << endl; dlog->info(false) << endl;
...@@ -331,6 +334,14 @@ mbErrCode ModbusTCPSession::tcp_processing( ModbusTCP::MBAPHeader& mhead ) ...@@ -331,6 +334,14 @@ mbErrCode ModbusTCPSession::tcp_processing( ModbusTCP::MBAPHeader& mhead )
if( mhead.pID != 0 ) if( mhead.pID != 0 )
return erUnExpectedPacketType; // erTimeOut; return erUnExpectedPacketType; // erTimeOut;
if( mhead.len == 0 )
{
if( dlog->is_info() )
dlog->info() << "(ModbusTCPServer::tcp_processing): BAD FORMAT: len=0!" << endl;
return erInvalidFormat;
}
if( mhead.len > ModbusRTU::MAXLENPACKET ) if( mhead.len > ModbusRTU::MAXLENPACKET )
{ {
if( dlog->is_info() ) if( dlog->is_info() )
...@@ -363,33 +374,25 @@ mbErrCode ModbusTCPSession::tcp_processing( ModbusTCP::MBAPHeader& mhead ) ...@@ -363,33 +374,25 @@ mbErrCode ModbusTCPSession::tcp_processing( ModbusTCP::MBAPHeader& mhead )
return erNoError; return erNoError;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
ModbusRTU::mbErrCode ModbusTCPSession::post_send_request( ModbusTCP::ADU& request ) ModbusRTU::mbErrCode ModbusTCPSession::post_send_request( ModbusRTU::ModbusMessage& request )
{ {
return erNoError; return erNoError;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
mbErrCode ModbusTCPSession::make_adu_header( ModbusTCP::ADU& req ) mbErrCode ModbusTCPSession::make_adu_header( ModbusMessage& req )
{ {
req.header = curQueryHeader; req.makeHead(curQueryHeader.tID,isCRCNoCheckit(),curQueryHeader.pID);
req.header.len = req.pdu.len + szModbusHeader;
if( crcNoCheckit )
req.header.len -= szCRC;
req.len = sizeof(req.header) + req.header.len;
//req.header.swapdata();
return erNoError; return erNoError;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void ModbusTCPSession::cleanInputStream() void ModbusTCPSession::cleanInputStream()
{ {
unsigned char buf[100]; unsigned char tmpbuf[100];
int ret = 0; size_t ret = 0;
do do
{ {
ret = getNextData(buf, sizeof(buf)); ret = getNextData(tmpbuf, sizeof(tmpbuf));
} }
while( ret > 0); while( ret > 0);
} }
......
...@@ -438,6 +438,7 @@ tests/UniXmlTest/XmlTest.cc ...@@ -438,6 +438,7 @@ tests/UniXmlTest/XmlTest.cc
tests/int_unsigned.cc tests/int_unsigned.cc
tests/Makefile.am tests/Makefile.am
tests/test.xml tests/test.xml
tests/develop.cc
tests/test_callbacktimer.cc tests/test_callbacktimer.cc
tests/test_conftest.cc tests/test_conftest.cc
tests/test_delaytimer.cc tests/test_delaytimer.cc
......
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