Commit eb6f42a3 authored by Pavel Vainerman's avatar Pavel Vainerman

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

Чтобы посылать в соответсвии со стандартом, посылать сообщение одним "пакетом" (по крайней мере одним write(buf,len), изменён формат ModbusMessage. А также проведён небольшой рефакторинг классов ModbusXXX.
parent bb43c2e0
......@@ -170,12 +170,12 @@ class ModbusClient
\param len - size of buf
\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 */
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,
......
......@@ -46,12 +46,12 @@ class ModbusRTUMaster:
\param len - size of buf
\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 */
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,
......
......@@ -299,11 +299,11 @@ class ModbusServer
virtual ModbusRTU::mbErrCode send( ModbusRTU::ModbusMessage& buf );
// Если заголовок не должен использоваться оставляйте 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;
}
virtual ModbusRTU::mbErrCode post_send_request( ModbusTCP::ADU& request )
virtual ModbusRTU::mbErrCode post_send_request( ModbusRTU::ModbusMessage& request )
{
return ModbusRTU::erNoError;
}
......
......@@ -50,9 +50,9 @@ class ModbusTCPMaster:
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 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,
ModbusRTU::ModbusMessage& reply, timeout_t timeout ) override;
......
......@@ -137,7 +137,7 @@ class ModbusTCPServer:
ost::InetAddress iaddr;
std::string myname;
std::queue<unsigned char> qrecv;
ModbusTCP::MBAPHeader curQueryHeader;
ModbusRTU::ADUHeader curQueryHeader;
std::mutex sMutex;
typedef std::list<std::shared_ptr<ModbusTCPSession>> SessionList;
......
......@@ -72,9 +72,9 @@ class ModbusTCPSession:
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(ModbusTCP::MBAPHeader& mhead );
virtual ModbusRTU::mbErrCode make_adu_header( ModbusTCP::ADU& request ) override;
virtual ModbusRTU::mbErrCode post_send_request( ModbusTCP::ADU& request ) override;
virtual ModbusRTU::mbErrCode tcp_processing( ModbusRTU::ADUHeader& mhead );
virtual ModbusRTU::mbErrCode make_adu_header( ModbusRTU::ModbusMessage& request ) override;
virtual ModbusRTU::mbErrCode post_send_request(ModbusRTU::ModbusMessage& request ) override;
virtual ModbusRTU::mbErrCode readCoilStatus( ModbusRTU::ReadCoilMessage& query,
ModbusRTU::ReadCoilRetMessage& reply );
......@@ -120,8 +120,8 @@ class ModbusTCPSession:
private:
std::queue<unsigned char> qrecv;
ModbusTCP::MBAPHeader curQueryHeader;
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
ModbusRTU::ADUHeader curQueryHeader;
PassiveTimer ptTimeout;
timeout_t timeout = { 0 };
ModbusRTU::ModbusMessage buf;
......
......@@ -21,12 +21,12 @@
namespace ModbusRTU
{
// Базовые типы
typedef unsigned char ModbusByte; /*!< modbus-байт */
typedef uint8_t ModbusByte; /*!< modbus-байт */
const size_t BitsPerByte = 8;
typedef unsigned char ModbusAddr; /*!< адрес узла в modbus-сети */
typedef unsigned short ModbusData; /*!< размер данных в modbus-сообщениях */
typedef uint8_t ModbusAddr; /*!< адрес узла в modbus-сети */
typedef uint16_t ModbusData; /*!< размер данных в modbus-сообщениях */
const size_t BitsPerData = 16;
typedef unsigned short ModbusCRC; /*!< размер CRC16 в modbus-сообщениях */
typedef uint16_t ModbusCRC; /*!< размер CRC16 в modbus-сообщениях */
// ---------------------------------------------------------------------
/*! Коды используемых функций (согласно описанию modbus) */
......@@ -132,10 +132,10 @@ namespace ModbusRTU
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); /*!< размер данных для контрольной суммы */
// ---------------------------------------------------------------------
/*! вывод сообщения */
......@@ -161,15 +161,29 @@ namespace ModbusRTU
} __attribute__((packed));
const size_t szModbusHeader = sizeof(ModbusHeader);
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?
*/
struct ModbusMessage:
public ModbusHeader
struct ModbusMessage
{
ModbusMessage();
......@@ -178,10 +192,29 @@ namespace ModbusRTU
ModbusMessage( 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]; /*!< данные */
// Это поле вспомогательное и игнорируется при пересылке
size_t len = { 0 }; /*!< фактическая длина */
size_t dlen = { 0 }; /*!< фактическая длина сообщения */
} __attribute__((packed));
std::ostream& operator<<(std::ostream& os, const ModbusMessage& m );
......@@ -1573,39 +1606,5 @@ namespace ModbusRTU
// -----------------------------------------------------------------------
} // 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_
// ---------------------------------------------------------------------------
......@@ -90,6 +90,7 @@ throw(ModbusRTU::mbException)
{
ReadOutputMessage msg(addr, start, count);
qbuf = msg.transport_msg();
mbErrCode res = query(addr, qbuf, reply, replyTimeOut_ms);
if( res == erNoError )
......@@ -338,9 +339,7 @@ mbErrCode ModbusClient::recv( ModbusAddr addr, ModbusByte qfunc,
setChannelTimeout(timeout);
PassiveTimer tmAbort(timeout);
// предварительно чистим буфер
memset(&rbuf, 0, sizeof(rbuf));
int bcnt = 0; // receive bytes count
size_t bcnt = 0; // receive bytes count
try
{
......@@ -348,9 +347,9 @@ mbErrCode ModbusClient::recv( ModbusAddr addr, ModbusByte qfunc,
while( !tmAbort.checkTime() )
{
bcnt = getNextData((unsigned char*)(&rbuf), sizeof(ModbusAddr));
bcnt = getNextData((unsigned char*)(&rbuf.pduhead.addr), sizeof(rbuf.pduhead.addr));
if( bcnt > 0 && ( rbuf.addr == addr ) ) // || (onBroadcast && rbuf.addr==BroadcastAddr) ) )
if( bcnt > 0 && ( rbuf.addr() == addr ) ) // || (onBroadcast && rbuf.addr==BroadcastAddr) ) )
{
begin = true;
break;
......@@ -366,11 +365,11 @@ mbErrCode ModbusClient::recv( ModbusAddr addr, ModbusByte qfunc,
// Lav: конечно стоит, нам же надо буфер чистить
*/
// Проверка кому адресован пакет...
if( rbuf.addr != addr && rbuf.addr != BroadcastAddr )
if( rbuf.addr() != addr && rbuf.addr() != BroadcastAddr )
{
ostringstream err;
err << "(recv): BadNodeAddress. my= " << addr2str(addr)
<< " msg.addr=" << addr2str(rbuf.addr);
<< " msg.addr=" << addr2str(rbuf.addr());
if( dlog->is_warn() )
dlog->warn() << err.str() << endl;
......@@ -401,21 +400,20 @@ mbErrCode ModbusClient::recv( ModbusAddr addr, ModbusByte qfunc,
// --------------------------------------------------------------------------------
mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout_t timeout )
{
int bcnt = 1; // receive bytes count (1 - addr)
size_t bcnt = 1; // receive bytes count (1 - addr)
try
{
// -----------------------------------
tmProcessing.setTiming(replyTimeOut_ms);
// recv func number
size_t k = getNextData((unsigned char*)(&rbuf.func), sizeof(ModbusByte));
size_t k = getNextData((unsigned char*)(&rbuf.pduhead.func), sizeof(rbuf.pduhead.func));
if( k < sizeof(ModbusByte) )
if( k < sizeof(rbuf.pduhead.func) )
{
if( dlog->is_warn() )
{
dlog->warn() << "(recv): " << (ModbusHeader*)(&rbuf) << endl;
dlog->warn() << "(recv): заголовок меньше положенного..." << endl;
dlog->warn() << "(recv): receive " << k << " bytes < " << sizeof(rbuf.pduhead.func) << endl;
}
cleanupChannel();
......@@ -423,29 +421,29 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
}
bcnt += k;
rbuf.len = 0;
rbuf.dlen = 0;
if( dlog->is_info() )
dlog->info() << "(recv): header: " << rbuf << endl;
dlog->info() << "(recv): PDU: " << rbuf.pduhead << endl;
// обработка сообщения об ошибке...
if( rbuf.func == (qfunc | MBErrMask) )
if( rbuf.func() == (qfunc | MBErrMask) )
{
rbuf.len = ErrorRetMessage::szData();
rbuf.dlen = ErrorRetMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
size_t rlen = getNextData((unsigned char*)(&(rbuf.data)), rbuf.len);
size_t rlen = getNextData((unsigned char*)(&(rbuf.data)), rbuf.dlen);
if( rlen < rbuf.len )
if( rlen < rbuf.dlen )
{
if( dlog->is_warn() )
{
dlog->warn() << "(recv:Error): buf: " << rbuf << endl;
dlog->warn() << "(recv:Error)(" << rbuf.func
dlog->warn() << "(recv:Error)(" << rbuf.func()
<< "): Получили данных меньше чем ждали...(recv="
<< rlen << " < wait=" << rbuf.len << ")" << endl;
<< rlen << " < wait=" << rbuf.dlen << ")" << endl;
}
cleanupChannel();
......@@ -458,7 +456,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
if( !crcNoCheckit )
{
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != em.crc )
{
......@@ -476,81 +474,81 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return (mbErrCode)em.ecode;
}
if( qfunc != rbuf.func )
if( qfunc != rbuf.func() )
{
cleanupChannel();
return erUnExpectedPacketType;
}
// Определяем тип сообщения
switch( rbuf.func )
switch( rbuf.func() )
{
case fnReadCoilStatus:
rbuf.len = ReadCoilRetMessage::szHead();
rbuf.dlen = ReadCoilRetMessage::szHead();
break;
case fnReadInputStatus:
rbuf.len = ReadInputStatusRetMessage::szHead();
rbuf.dlen = ReadInputStatusRetMessage::szHead();
break;
case fnReadOutputRegisters:
rbuf.len = ReadOutputRetMessage::szHead();
rbuf.dlen = ReadOutputRetMessage::szHead();
break;
case fnReadInputRegisters:
rbuf.len = ReadInputRetMessage::szHead();
rbuf.dlen = ReadInputRetMessage::szHead();
break;
case fnForceMultipleCoils:
rbuf.len = ForceCoilsRetMessage::szData();
rbuf.dlen = ForceCoilsRetMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
break;
case fnWriteOutputRegisters:
rbuf.len = WriteOutputRetMessage::szData();
rbuf.dlen = WriteOutputRetMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
break;
case fnWriteOutputSingleRegister:
rbuf.len = WriteSingleOutputRetMessage::szData();
rbuf.dlen = WriteSingleOutputRetMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
break;
case fnForceSingleCoil:
rbuf.len = ForceSingleCoilRetMessage::szData();
rbuf.dlen = ForceSingleCoilRetMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
break;
case fnDiagnostics:
rbuf.len = DiagnosticRetMessage::szHead();
rbuf.dlen = DiagnosticRetMessage::szHead();
break;
case fnMEI:
rbuf.len = MEIMessageRetRDI::szHead();
rbuf.dlen = MEIMessageRetRDI::szHead();
break;
case fnSetDateTime:
rbuf.len = SetDateTimeRetMessage::szData();
rbuf.dlen = SetDateTimeRetMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
break;
case fnFileTransfer:
rbuf.len = FileTransferRetMessage::szHead();
rbuf.dlen = FileTransferRetMessage::szHead();
break;
/*
......@@ -572,17 +570,17 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
setChannelTimeout(10); // 10 msec
// Получаем остальную часть сообщения
size_t rlen = getNextData((unsigned char*)(rbuf.data), rbuf.len);
size_t rlen = getNextData((unsigned char*)(rbuf.data), rbuf.dlen);
if( rlen < rbuf.len )
if( rlen < rbuf.dlen )
{
// rbuf.len = bcnt + rlen - szModbusHeader;
if( dlog->is_warn() )
{
dlog->warn() << "(recv): buf: " << rbuf << endl;
dlog->warn() << "(recv)(" << rbuf.func
dlog->warn() << "(recv)(" << rbuf.func()
<< "): Получили данных меньше чем ждали...(recv="
<< rlen << " < wait=" << rbuf.len << ")" << endl;
<< rlen << " < wait=" << rbuf.dlen << ")" << endl;
}
cleanupChannel();
......@@ -592,7 +590,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
bcnt += rlen;
// получаем остальное...
if( rbuf.func == fnReadCoilStatus )
if( rbuf.func() == fnReadCoilStatus )
{
int szDataLen = ReadCoilRetMessage::getDataLen(rbuf) + szCRC;
......@@ -606,13 +604,13 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
if( rlen1 < szDataLen )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
if( dlog->is_warn() )
{
dlog->warn() << "(0x01): buf: " << rbuf << endl;
dlog->warn() << "(0x01)("
<< (int)rbuf.func << "):(fnReadCoilStatus) "
<< (int)rbuf.func() << "):(fnReadCoilStatus) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -622,7 +620,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
ReadCoilRetMessage mRead(rbuf);
......@@ -636,7 +634,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mRead.crc )
{
......@@ -652,7 +650,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return erNoError;
}
else if( rbuf.func == fnReadInputStatus )
else if( rbuf.func() == fnReadInputStatus )
{
int szDataLen = ReadInputStatusRetMessage::getDataLen(rbuf) + szCRC;
......@@ -666,13 +664,13 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
if( rlen1 < szDataLen )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
if( dlog->is_warn() )
{
dlog->warn() << "(0x02): buf: " << rbuf << endl;
dlog->warn() << "(0x02)("
<< (int)rbuf.func << "):(fnReadInputStatus) "
<< (int)rbuf.func() << "):(fnReadInputStatus) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -682,7 +680,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
ReadInputStatusRetMessage mRead(rbuf);
......@@ -696,7 +694,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mRead.crc )
{
......@@ -712,7 +710,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return erNoError;
}
else if( rbuf.func == fnReadInputRegisters )
else if( rbuf.func() == fnReadInputRegisters )
{
int szDataLen = ReadInputRetMessage::getDataLen(rbuf) + szCRC;
......@@ -726,13 +724,13 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
if( rlen1 < szDataLen )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
if( dlog->is_warn() )
{
dlog->warn() << "(0x04): buf: " << rbuf << endl;
dlog->warn() << "(0x04)("
<< (int)rbuf.func << "):(fnReadInputRegisters) "
<< (int)rbuf.func() << "):(fnReadInputRegisters) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -742,7 +740,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
ReadInputRetMessage mRead(rbuf);
......@@ -756,7 +754,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mRead.crc )
{
......@@ -772,7 +770,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return erNoError;
}
else if( rbuf.func == fnReadOutputRegisters )
else if( rbuf.func() == fnReadOutputRegisters )
{
int szDataLen = ReadOutputRetMessage::getDataLen(rbuf) + szCRC;
......@@ -786,13 +784,13 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
if( rlen1 < szDataLen )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
if( dlog->is_warn() )
{
dlog->warn() << "(0x03): buf: " << rbuf << endl;
dlog->warn() << "(0x03)("
<< (int)rbuf.func << "):(fnReadInputRegisters) "
<< (int)rbuf.func() << "):(fnReadInputRegisters) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -802,7 +800,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
ReadOutputRetMessage mRead(rbuf);
......@@ -816,7 +814,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mRead.crc )
{
......@@ -832,9 +830,9 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return erNoError;
}
else if( rbuf.func == fnForceMultipleCoils )
else if( rbuf.func() == fnForceMultipleCoils )
{
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
ForceCoilsRetMessage mWrite(rbuf);
if( dlog->is_info() )
......@@ -847,7 +845,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc =rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mWrite.crc )
{
......@@ -860,9 +858,9 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return erNoError;
}
else if( rbuf.func == fnWriteOutputRegisters )
else if( rbuf.func() == fnWriteOutputRegisters )
{
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
WriteOutputRetMessage mWrite(rbuf);
if( dlog->is_info() )
......@@ -875,7 +873,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mWrite.crc )
{
......@@ -888,7 +886,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return erNoError;
}
else if( rbuf.func == fnWriteOutputSingleRegister )
else if( rbuf.func() == fnWriteOutputSingleRegister )
{
WriteSingleOutputRetMessage mWrite(rbuf);
......@@ -902,7 +900,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead() + mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mWrite.crc )
{
......@@ -915,7 +913,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return erNoError;
}
else if( rbuf.func == fnForceSingleCoil )
else if( rbuf.func() == fnForceSingleCoil )
{
ForceSingleCoilRetMessage mWrite(rbuf);
......@@ -929,7 +927,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead() + mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mWrite.crc )
{
......@@ -942,7 +940,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return erNoError;
}
else if( rbuf.func == fnDiagnostics )
else if( rbuf.func() == fnDiagnostics )
{
int szDataLen = DiagnosticRetMessage::getDataLen(rbuf) + szCRC;
......@@ -956,13 +954,13 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
if( rlen1 < szDataLen )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
if( dlog->is_warn() )
{
dlog->warn() << "(0x08): buf: " << rbuf << endl;
dlog->warn() << "(0x08)("
<< (int)rbuf.func << "):(fnDiagnostics) "
<< (int)rbuf.func() << "):(fnDiagnostics) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -972,7 +970,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
DiagnosticRetMessage mDiag(rbuf);
......@@ -986,7 +984,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mDiag.crc )
{
......@@ -1002,7 +1000,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return erNoError;
}
else if( rbuf.func == fnMEI )
else if( rbuf.func() == fnMEI )
{
MEIMessageRetRDI mPreRDI;
mPreRDI.pre_init(rbuf);
......@@ -1019,13 +1017,13 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
if( rlen1 < szDataLen )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
if( dlog->is_warn() )
{
dlog->warn() << "(0x2B/0x0E): buf: " << rbuf << endl;
dlog->warn() << "(0x2B/0x0E)("
<< (int)rbuf.func << "):(fnMEI) "
<< (int)rbuf.func() << "):(fnMEI) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -1043,13 +1041,13 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
if( rlen1 < szDataLen )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
if( dlog->is_warn() )
{
dlog->warn() << "(0x2B/0x0E): buf: " << rbuf << endl;
dlog->warn() << "(0x2B/0x0E)("
<< (int)rbuf.func << "):(fnMEI) "
<< (int)rbuf.func() << "):(fnMEI) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -1064,7 +1062,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
}
}
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
if( crcNoCheckit )
{
......@@ -1079,13 +1077,13 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
if( rlen1 < szCRC )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
if( dlog->is_warn() )
{
dlog->warn() << "(0x2B/0x0E): buf: " << rbuf << endl;
dlog->warn() << "(0x2B/0x0E)("
<< (int)rbuf.func << "):(fnMEI) "
<< (int)rbuf.func() << "):(fnMEI) "
<< "(CRC): Получили данных меньше чем ждали...("
<< rlen1 << " < " << szCRC << ")" << endl;
}
......@@ -1095,7 +1093,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
if( dlog->is_info() )
dlog->info() << "(recv)(fnMEI): recv buf: " << rbuf << endl;
......@@ -1106,7 +1104,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mRDI.crc )
{
......@@ -1122,7 +1120,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return erNoError;
}
else if( rbuf.func == fnSetDateTime )
else if( rbuf.func() == fnSetDateTime )
{
SetDateTimeRetMessage mSet(rbuf);
......@@ -1133,7 +1131,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
{
// Проверяем контрольную сумму
// от начала(включая заголовок) и до конца (исключив последний элемент содержащий CRC)
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mSet.crc )
{
......@@ -1158,7 +1156,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return erNoError;
}
else if( rbuf.func == fnFileTransfer )
else if( rbuf.func() == fnFileTransfer )
{
int szDataLen = FileTransferRetMessage::getDataLen(rbuf) + szCRC;
......@@ -1172,13 +1170,13 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
if( rlen1 < szDataLen )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
if( dlog->is_warn() )
{
dlog->warn() << "(0x66): buf: " << rbuf << endl;
dlog->warn() << "(0x66)("
<< rbuf.func << "):(fnFileTransfer) "
<< rbuf.func() << "):(fnFileTransfer) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -1188,7 +1186,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
FileTransferRetMessage mFT(rbuf);
......@@ -1202,7 +1200,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mFT.crc )
{
......@@ -1220,7 +1218,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
}
#if 0
else if( rbuf.func == fnJournalCommand )
else if( rbuf.func() == fnJournalCommand )
{
JournalCommandMessage mRead(rbuf);
......@@ -1232,8 +1230,8 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// Проверяем контрольную сумму
// от начала(включая заголовок) и до конца (исключив последний элемент содержащий CRC)
// ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf),sizeof(ReadOutputMessage)-szCRC);
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
// ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf.pduhead),sizeof(ReadOutputMessage)-szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mRead.crc )
{
......@@ -1246,7 +1244,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
return erNoError;
}
else if( rbuf.func == fnRemoteService )
else if( rbuf.func() == fnRemoteService )
{
int szDataLen = RemoteServiceMessage::getDataLen(rbuf) + szCRC;
......@@ -1263,7 +1261,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
rbuf.len = bcnt + rlen1 - szModbusHeader;
dlog->warn() << "(0x53): buf: " << rbuf << endl;
dlog->warn() << "(0x53)("
<< rbuf.func << "):(fnWriteOutputRegisters) "
<< rbuf.func() << "):(fnWriteOutputRegisters) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
......@@ -1286,7 +1284,7 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mRServ.crc )
{
......@@ -1334,29 +1332,30 @@ mbErrCode ModbusClient::recv_pdu( ModbusByte qfunc, ModbusMessage& rbuf, timeout
// -------------------------------------------------------------------------
mbErrCode ModbusClient::send( ModbusMessage& msg )
{
if( msg.len > MAXLENPACKET + szModbusHeader )
if( msg.len() > msg.maxSizeOfMessage() )
{
dlog->warn() << "(send): длина пакета больше разрешённой..." << endl;
if( dlog->is_warn() )
dlog->warn() << "(ModbusClient::send): message len=" << msg.len()
<< " > MAXLEN=" << msg.maxSizeOfMessage() << endl;
return erPacketTooLong;
}
int len = szModbusHeader + msg.len;
if( crcNoCheckit )
len -= szCRC;
if( dlog->is_info() )
dlog->info() << "(send)(" << len << " bytes): " << msg << endl;
dlog->info() << "(ModbusClient::send): [" << msg.len() << " bytes]: " << msg << endl;
try
{
sendData((unsigned char*)(&msg), len);
size_t len = msg.len(); // т.к. swapHead() поменяет
msg.swapHead();
sendData(msg.buf(),len);
msg.swapHead();
}
catch( mbException& ex )
{
if( dlog->is_crit() )
dlog->crit() << "(send): " << ex << endl;
msg.swapHead();
return ex.err;
}
catch( const Exception& ex ) // SystemError
......@@ -1364,6 +1363,7 @@ mbErrCode ModbusClient::send( ModbusMessage& msg )
if( dlog->is_crit() )
dlog->crit() << "(send): " << ex << endl;
msg.swapHead();
return erHardwareError;
}
......@@ -1371,9 +1371,6 @@ mbErrCode ModbusClient::send( ModbusMessage& msg )
if( aftersend_msec > 0 )
msleep(aftersend_msec);
//#warning Разобраться с паузой после посылки...
// msleep(10);
return erNoError;
}
......
......@@ -124,7 +124,7 @@ int ModbusRTUMaster::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;
return port->receiveBlock(buf, len);
......@@ -136,7 +136,7 @@ void ModbusRTUMaster::setChannelTimeout( timeout_t msec )
port->setTimeout(msec);
}
// --------------------------------------------------------------------------------
mbErrCode ModbusRTUMaster::sendData( unsigned char* buf, int len )
mbErrCode ModbusRTUMaster::sendData(unsigned char* buf, size_t len )
{
try
{
......@@ -159,6 +159,6 @@ mbErrCode ModbusRTUMaster::query( ModbusAddr addr, ModbusMessage& msg,
if( res != erNoError )
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
// то посылаем
if( res < erInternalErrorCode )
{
ErrorRetMessage em( buf.addr, buf.func, res );
ErrorRetMessage em( buf.addr(), buf.func(), res );
buf = em.transport_msg();
send(buf);
printProcessingTime();
......
......@@ -105,10 +105,10 @@ std::string ModbusServer::vaddr2str( const std::unordered_set<ModbusAddr>& vaddr
// --------------------------------------------------------------------------------
mbErrCode ModbusServer::processing( ModbusMessage& buf )
{
if( buf.func == fnReadCoilStatus )
if( buf.func() == fnReadCoilStatus )
{
ReadCoilMessage mRead(buf);
ReadCoilRetMessage reply(buf.addr); // addr?
ReadCoilRetMessage reply(buf.pduhead.addr); // addr?
// вызываем обработчик..
mbErrCode res = readCoilStatus( mRead, reply );
......@@ -138,10 +138,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnReadInputStatus )
else if( buf.func() == fnReadInputStatus )
{
ReadInputStatusMessage mRead(buf);
ReadInputStatusRetMessage reply(buf.addr); // addr?
ReadInputStatusRetMessage reply(buf.pduhead.addr); // addr?
// вызываем обработчик..
mbErrCode res = readInputStatus( mRead, reply );
......@@ -171,10 +171,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnReadOutputRegisters )
else if( buf.func() == fnReadOutputRegisters )
{
ReadOutputMessage mRead(buf);
ReadOutputRetMessage reply(buf.addr); // addr?
ReadOutputRetMessage reply(buf.pduhead.addr); // addr?
// вызываем обработчик..
mbErrCode res = readOutputRegisters( mRead, reply );
......@@ -204,10 +204,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnReadInputRegisters )
else if( buf.func() == fnReadInputRegisters )
{
ReadInputMessage mRead(buf);
ReadInputRetMessage reply(buf.addr); // addr?
ReadInputRetMessage reply(buf.pduhead.addr); // addr?
// вызываем обработчик..
mbErrCode res = readInputRegisters( mRead, reply );
......@@ -237,10 +237,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnForceMultipleCoils )
else if( buf.func() == fnForceMultipleCoils )
{
ForceCoilsMessage mWrite(buf);
ForceCoilsRetMessage reply(buf.addr); // addr?
ForceCoilsRetMessage reply(buf.pduhead.addr); // addr?
// вызываем обработчик..
mbErrCode res = forceMultipleCoils( mWrite, reply );
......@@ -271,10 +271,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnWriteOutputRegisters )
else if( buf.func() == fnWriteOutputRegisters )
{
WriteOutputMessage mWrite(buf);
WriteOutputRetMessage reply(buf.addr); // addr?
WriteOutputRetMessage reply(buf.pduhead.addr); // addr?
// вызываем обработчик..
mbErrCode res = writeOutputRegisters( mWrite, reply );
......@@ -305,10 +305,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnDiagnostics )
else if( buf.func() == fnDiagnostics )
{
DiagnosticMessage mDiag(buf);
DiagnosticRetMessage reply(buf.addr, (DiagnosticsSubFunction)mDiag.subf );
DiagnosticRetMessage reply(buf.pduhead.addr, (DiagnosticsSubFunction)mDiag.subf );
mbErrCode res = diagnostics( mDiag, reply );
// в случае ошибок ответа не посылаем
......@@ -336,10 +336,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnMEI )
else if( buf.func() == fnMEI )
{
MEIMessageRDI mRDI(buf);
MEIMessageRetRDI reply( buf.addr, mRDI.devID, 0, 0, mRDI.objID );
MEIMessageRetRDI reply( buf.pduhead.addr, mRDI.devID, 0, 0, mRDI.objID );
mbErrCode res = read4314( mRDI, reply );
......@@ -368,10 +368,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnForceSingleCoil )
else if( buf.func() == fnForceSingleCoil )
{
ForceSingleCoilMessage mWrite(buf);
ForceSingleCoilRetMessage reply(buf.addr); // addr?
ForceSingleCoilRetMessage reply(buf.pduhead.addr); // addr?
// вызываем обработчик..
mbErrCode res = forceSingleCoil( mWrite, reply );
......@@ -402,10 +402,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnWriteOutputSingleRegister )
else if( buf.func() == fnWriteOutputSingleRegister )
{
WriteSingleOutputMessage mWrite(buf);
WriteSingleOutputRetMessage reply(buf.addr); // addr?
WriteSingleOutputRetMessage reply(buf.pduhead.addr); // addr?
// вызываем обработчик..
mbErrCode res = writeOutputSingleRegister( mWrite, reply );
......@@ -436,10 +436,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnJournalCommand )
else if( buf.func() == fnJournalCommand )
{
JournalCommandMessage mJournal(buf);
JournalCommandRetMessage reply(buf.addr); // addr?
JournalCommandRetMessage reply(buf.pduhead.addr); // addr?
// вызываем обработчик..
mbErrCode res = journalCommand( mJournal, reply );
......@@ -469,10 +469,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnSetDateTime )
else if( buf.func() == fnSetDateTime )
{
SetDateTimeMessage mSet(buf);
SetDateTimeRetMessage reply(buf.addr); // addr?
SetDateTimeRetMessage reply(buf.pduhead.addr); // addr?
// вызываем обработчик..
mbErrCode res = setDateTime( mSet, reply );
......@@ -502,10 +502,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnRemoteService )
else if( buf.func() == fnRemoteService )
{
RemoteServiceMessage query(buf);
RemoteServiceRetMessage reply(buf.addr);
RemoteServiceRetMessage reply(buf.pduhead.addr);
// вызываем обработчик..
mbErrCode res = remoteService( query, reply );
......@@ -535,10 +535,10 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
// --------------------------------
return res;
}
else if( buf.func == fnFileTransfer )
else if( buf.func() == fnFileTransfer )
{
FileTransferMessage query(buf);
FileTransferRetMessage reply(buf.addr);
FileTransferRetMessage reply(buf.pduhead.addr);
// вызываем обработчик..
mbErrCode res = fileTransfer( query, reply );
......@@ -569,7 +569,7 @@ mbErrCode ModbusServer::processing( ModbusMessage& buf )
return res;
}
ErrorRetMessage em( buf.addr, buf.func, erUnExpectedPacketType );
ErrorRetMessage em( buf.addr(), buf.func(), erUnExpectedPacketType );
buf = em.transport_msg();
send(buf);
printProcessingTime();
......@@ -586,9 +586,7 @@ mbErrCode ModbusServer::recv( const std::unordered_set<ModbusRTU::ModbusAddr>& v
setChannelTimeout(timeout);
PassiveTimer tmAbort(timeout);
// предварительно чистим буфер
memset(&rbuf, 0, sizeof(rbuf));
int bcnt = 0; // receive bytes count
size_t bcnt = 0; // receive bytes count
try
{
......@@ -597,9 +595,9 @@ mbErrCode ModbusServer::recv( const std::unordered_set<ModbusRTU::ModbusAddr>& v
while( !tmAbort.checkTime() )
{
bcnt = getNextData((unsigned char*)(&rbuf), sizeof(ModbusAddr));
bcnt = getNextData((unsigned char*)(&rbuf.pduhead.addr), sizeof(rbuf.pduhead.addr));
if( bcnt > 0 && checkAddr(vaddr, rbuf.addr) )
if( bcnt > 0 && checkAddr(vaddr, rbuf.addr()) )
{
begin = true;
break;
......@@ -615,13 +613,13 @@ mbErrCode ModbusServer::recv( const std::unordered_set<ModbusRTU::ModbusAddr>& v
// Lav: конечно стоит, нам же надо буфер чистить
*/
// Проверка кому адресован пакет... (только если не включён режим отвечать на любые адреса)
if( !(onBroadcast && rbuf.addr == BroadcastAddr) && !checkAddr(vaddr, rbuf.addr) )
if( !(onBroadcast && rbuf.addr() == BroadcastAddr) && !checkAddr(vaddr, rbuf.addr()) )
{
if( dlog->is_warn() )
{
ostringstream err;
err << "(recv): BadNodeAddress. my= " << vaddr2str(vaddr)
<< " msg.addr=" << addr2str(rbuf.addr);
<< " msg.addr=" << addr2str(rbuf.addr());
dlog->warn() << err.str() << endl;
}
......@@ -648,113 +646,113 @@ mbErrCode ModbusServer::recv( const std::unordered_set<ModbusRTU::ModbusAddr>& v
// -------------------------------------------------------------------------
mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
{
int bcnt = 1; // 1 - addr
size_t bcnt = 1; // 1 - addr
try
{
// -----------------------------------
tmProcessing.setTiming(replyTimeout_ms);
// recv func number
size_t k = getNextData((unsigned char*)(&rbuf.func), sizeof(ModbusByte));
size_t k = getNextData((unsigned char*)(&rbuf.pduhead.func), sizeof(rbuf.pduhead.func));
if( k < sizeof(ModbusByte) )
{
dlog->warn() << "(recv): " << (ModbusHeader*)(&rbuf) << endl;
dlog->warn() << "(recv): " << (ModbusHeader*)(&rbuf.pduhead) << endl;
dlog->warn() << "(recv): заголовок меньше положенного..." << endl;
cleanupChannel();
return erInvalidFormat;
}
bcnt += k;
rbuf.len = 0;
rbuf.dlen = 0;
if( dlog->is_info() )
dlog->info() << "(recv): header: " << rbuf << endl;
dlog->info() << "(recv): header: " << rbuf.pduhead << endl;
// Определяем тип сообщения
switch( rbuf.func )
switch( rbuf.func() )
{
case fnReadCoilStatus:
rbuf.len = ReadCoilMessage::szData();
rbuf.dlen = ReadCoilMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
break;
case fnReadInputStatus:
rbuf.len = ReadInputStatusMessage::szData();
rbuf.dlen = ReadInputStatusMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
break;
case fnReadOutputRegisters:
rbuf.len = ReadOutputMessage::szData();
rbuf.dlen = ReadOutputMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
break;
case fnReadInputRegisters:
rbuf.len = ReadInputMessage::szData();
rbuf.dlen = ReadInputMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
break;
case fnForceMultipleCoils:
rbuf.len = ForceCoilsMessage::szHead();
rbuf.dlen = ForceCoilsMessage::szHead();
break;
case fnWriteOutputRegisters:
rbuf.len = WriteOutputMessage::szHead();
rbuf.dlen = WriteOutputMessage::szHead();
break;
case fnForceSingleCoil:
rbuf.len = ForceSingleCoilMessage::szHead();
rbuf.dlen = ForceSingleCoilMessage::szHead();
break;
case fnWriteOutputSingleRegister:
rbuf.len = WriteSingleOutputMessage::szHead();
rbuf.dlen = WriteSingleOutputMessage::szHead();
break;
case fnDiagnostics:
rbuf.len = DiagnosticMessage::szHead();
rbuf.dlen = DiagnosticMessage::szHead();
break;
case fnMEI:
rbuf.len = MEIMessageRDI::szHead();
rbuf.dlen = MEIMessageRDI::szHead();
break;
case fnJournalCommand:
rbuf.len = JournalCommandMessage::szData();
rbuf.dlen = JournalCommandMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
break;
case fnSetDateTime:
rbuf.len = SetDateTimeMessage::szData();
rbuf.dlen = SetDateTimeMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
break;
case fnRemoteService:
rbuf.len = RemoteServiceMessage::szHead();
rbuf.dlen = RemoteServiceMessage::szHead();
break;
case fnFileTransfer:
rbuf.len = FileTransferMessage::szData();
rbuf.dlen = FileTransferMessage::szData();
if( crcNoCheckit )
rbuf.len -= szCRC;
rbuf.dlen -= szCRC;
break;
......@@ -767,17 +765,17 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
setChannelTimeout(10); // 10 msec
// Получаем остальную часть сообщения
size_t rlen = getNextData((unsigned char*)(rbuf.data), rbuf.len);
size_t rlen = getNextData((unsigned char*)(rbuf.data), rbuf.dlen);
if( rlen < rbuf.len )
if( rlen < rbuf.dlen )
{
if( dlog->is_warn() )
{
// rbuf.len = bcnt + rlen - szModbusHeader;
dlog->warn() << "(recv): buf: " << rbuf << endl;
dlog->warn() << "(recv)(" << rbuf.func
dlog->warn() << "(recv)(" << rbuf.func()
<< "): Получили данных меньше чем ждали...(recv="
<< rlen << " < wait=" << (int)rbuf.len << ")" << endl;
<< rlen << " < wait=" << (int)rbuf.dlen << ")" << endl;
}
cleanupChannel();
......@@ -787,7 +785,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
bcnt += rlen;
// получаем остальное...
if( rbuf.func == fnReadCoilStatus )
if( rbuf.func() == fnReadCoilStatus )
{
ReadCoilMessage mRead(rbuf);
......@@ -799,7 +797,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
if( crcNoCheckit )
return erNoError;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mRead.crc )
{
......@@ -817,7 +815,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
return erNoError;
}
else if( rbuf.func == fnReadInputStatus )
else if( rbuf.func() == fnReadInputStatus )
{
ReadInputStatusMessage mRead(rbuf);
......@@ -829,7 +827,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
if( crcNoCheckit )
return erNoError;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mRead.crc )
{
......@@ -847,7 +845,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
return erNoError;
}
else if( rbuf.func == fnReadOutputRegisters )
else if( rbuf.func() == fnReadOutputRegisters )
{
ReadOutputMessage mRead(rbuf);
......@@ -859,7 +857,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
// Проверяем контрольную сумму
// от начала(включая заголовок) и до конца (исключив последний элемент содержащий CRC)
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mRead.crc )
{
......@@ -877,7 +875,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
return erNoError;
}
else if( rbuf.func == fnReadInputRegisters )
else if( rbuf.func() == fnReadInputRegisters )
{
ReadInputMessage mRead(rbuf);
......@@ -889,7 +887,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
// Проверяем контрольную сумму
// от начала(включая заголовок) и до конца (исключив последний элемент содержащий CRC)
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC(bcnt - szCRC);
if( tcrc != mRead.crc )
{
......@@ -907,7 +905,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
return erNoError;
}
else if( rbuf.func == fnForceMultipleCoils )
else if( rbuf.func() == fnForceMultipleCoils )
{
int szDataLen = ForceCoilsMessage::getDataLen(rbuf) + szCRC;
......@@ -923,10 +921,10 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
{
if( dlog->is_warn() )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
dlog->warn() << "(0x0F): buf: " << rbuf << endl;
dlog->warn() << "(0x0F)("
<< rbuf.func << "):(fnForceMultipleCoils) "
<< rbuf.func() << "):(fnForceMultipleCoils) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -936,7 +934,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
ForceCoilsMessage mWrite(rbuf);
......@@ -949,7 +947,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mWrite.crc )
{
......@@ -966,7 +964,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
{
if( dlog->is_warn() )
{
dlog->warn() << "(0x0F): (" << rbuf.func
dlog->warn() << "(0x0F): (" << rbuf.func()
<< ")(fnForceMultipleCoils): "
<< ": некорректный формат сообщения..." << endl;
}
......@@ -977,7 +975,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
return erNoError;
}
else if( rbuf.func == fnWriteOutputRegisters )
else if( rbuf.func() == fnWriteOutputRegisters )
{
int szDataLen = WriteOutputMessage::getDataLen(rbuf) + szCRC;
......@@ -993,10 +991,10 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
{
if( dlog->is_warn() )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
dlog->warn() << "(0x10): buf: " << rbuf << endl;
dlog->warn() << "(0x10)("
<< rbuf.func << "):(fnWriteOutputRegisters) "
<< rbuf.func() << "):(fnWriteOutputRegisters) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -1006,7 +1004,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
WriteOutputMessage mWrite(rbuf);
......@@ -1019,7 +1017,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mWrite.crc )
{
......@@ -1038,7 +1036,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
if( !mWrite.checkFormat() )
{
dlog->warn() << "(0x10): (" << rbuf.func
dlog->warn() << "(0x10): (" << rbuf.func()
<< ")(fnWriteOutputRegisters): "
<< ": некорректный формат сообщения..." << endl;
cleanupChannel();
......@@ -1047,7 +1045,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
return erNoError;
}
else if( rbuf.func == fnForceSingleCoil )
else if( rbuf.func() == fnForceSingleCoil )
{
int szDataLen = ForceSingleCoilMessage::getDataLen(rbuf) + szCRC;
......@@ -1063,10 +1061,10 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
{
if( dlog->is_warn() )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
dlog->warn() << "(0x05): buf: " << rbuf << endl;
dlog->warn() << "(0x05)("
<< rbuf.func << "):(fnForceSingleCoil) "
<< rbuf.func() << "):(fnForceSingleCoil) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -1076,7 +1074,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
ForceSingleCoilMessage mWrite(rbuf);
......@@ -1089,7 +1087,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead() + mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mWrite.crc )
{
......@@ -1108,7 +1106,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
if( !mWrite.checkFormat() )
{
dlog->warn() << "(0x05): (" << rbuf.func
dlog->warn() << "(0x05): (" << rbuf.func()
<< ")(fnForceSingleCoil): "
<< ": некорректный формат сообщения..." << endl;
cleanupChannel();
......@@ -1117,7 +1115,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
return erNoError;
}
else if( rbuf.func == fnWriteOutputSingleRegister )
else if( rbuf.func() == fnWriteOutputSingleRegister )
{
int szDataLen = WriteSingleOutputMessage::getDataLen(rbuf) + szCRC;
......@@ -1133,10 +1131,10 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
{
if( dlog->is_warn() )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
dlog->warn() << "(0x06): buf: " << rbuf << endl;
dlog->warn() << "(0x06)("
<< rbuf.func << "):(fnWriteOutputSingleRegisters) "
<< rbuf.func() << "):(fnWriteOutputSingleRegisters) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -1146,7 +1144,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
WriteSingleOutputMessage mWrite(rbuf);
......@@ -1159,7 +1157,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead() + mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mWrite.crc )
{
......@@ -1178,7 +1176,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
if( !mWrite.checkFormat() )
{
dlog->warn() << "(0x06): (" << rbuf.func
dlog->warn() << "(0x06): (" << rbuf.func()
<< ")(fnWriteOutputSingleRegisters): "
<< ": некорректный формат сообщения..." << endl;
cleanupChannel();
......@@ -1187,7 +1185,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
return erNoError;
}
else if( rbuf.func == fnDiagnostics )
else if( rbuf.func() == fnDiagnostics )
{
int szDataLen = DiagnosticMessage::getDataLen(rbuf) + szCRC;
......@@ -1203,10 +1201,10 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
{
if( dlog->is_warn() )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
dlog->warn() << "(0x08): buf: " << rbuf << endl;
dlog->warn() << "(0x08)("
<< rbuf.func << "):(fnDiagnostics) "
<< rbuf.func() << "):(fnDiagnostics) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -1216,7 +1214,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
DiagnosticMessage mDiag(rbuf);
......@@ -1229,7 +1227,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead() + mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mDiag.crc )
{
......@@ -1258,7 +1256,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
*/
return erNoError;
}
else if( rbuf.func == fnMEI )
else if( rbuf.func() == fnMEI )
{
if( !crcNoCheckit )
{
......@@ -1268,10 +1266,10 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
{
if( dlog->is_warn() )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
dlog->warn() << "(0x2B/0x0E): buf: " << rbuf << endl;
dlog->warn() << "(0x2B/0x0E)("
<< rbuf.func << "):(fnMEI) "
<< rbuf.func() << "):(fnMEI) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szCRC << ")" << endl;
}
......@@ -1281,7 +1279,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
}
MEIMessageRDI mRDI(rbuf);
......@@ -1296,7 +1294,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead() + mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mRDI.crc )
{
......@@ -1314,7 +1312,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
return erNoError;
}
else if( rbuf.func == fnJournalCommand )
else if( rbuf.func() == fnJournalCommand )
{
JournalCommandMessage mRead(rbuf);
......@@ -1326,8 +1324,8 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
// Проверяем контрольную сумму
// от начала(включая заголовок) и до конца (исключив последний элемент содержащий CRC)
// ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf),sizeof(ReadOutputMessage)-szCRC);
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
// ModbusData tcrc = rbuf.pduCRC(sizeof(ReadOutputMessage)-szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mRead.crc )
{
......@@ -1345,7 +1343,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
return erNoError;
}
else if( rbuf.func == fnSetDateTime )
else if( rbuf.func() == fnSetDateTime )
{
SetDateTimeMessage mSet(rbuf);
......@@ -1356,8 +1354,8 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
{
// Проверяем контрольную сумму
// от начала(включая заголовок) и до конца (исключив последний элемент содержащий CRC)
// ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf),sizeof(ReadOutputMessage)-szCRC);
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
// ModbusData tcrc = rbuf.pduCRC(sizeof(ReadOutputMessage)-szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mSet.crc )
{
......@@ -1383,7 +1381,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
return erNoError;
}
else if( rbuf.func == fnRemoteService )
else if( rbuf.func() == fnRemoteService )
{
int szDataLen = RemoteServiceMessage::getDataLen(rbuf) + szCRC;
......@@ -1399,10 +1397,10 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
{
if( dlog->is_warn() )
{
rbuf.len = bcnt + rlen1 - szModbusHeader;
rbuf.dlen = bcnt + rlen1 - szModbusHeader;
dlog->warn() << "(0x53): buf: " << rbuf << endl;
dlog->warn() << "(0x53)("
<< rbuf.func << "):(fnWriteOutputRegisters) "
<< rbuf.func() << "):(fnWriteOutputRegisters) "
<< "Получили данных меньше чем ждали...("
<< rlen1 << " < " << szDataLen << ")" << endl;
}
......@@ -1412,7 +1410,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
}
bcnt += rlen1;
rbuf.len = bcnt - szModbusHeader;
rbuf.dlen = bcnt - szModbusHeader;
RemoteServiceMessage mRServ(rbuf);
......@@ -1426,7 +1424,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mRServ.crc )
{
......@@ -1444,7 +1442,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
return erNoError;
}
else if( rbuf.func == fnFileTransfer )
else if( rbuf.func() == fnFileTransfer )
{
FileTransferMessage mFT(rbuf);
......@@ -1458,7 +1456,7 @@ mbErrCode ModbusServer::recv_pdu( ModbusMessage& rbuf, timeout_t timeout )
// от начала(включая заголовок)
// и до конца (исключив последний элемент содержащий CRC)
// int mlen = szModbusHeader + mWrite.szHead()+ mWrite.bcnt;
ModbusData tcrc = checkCRC((ModbusByte*)(&rbuf), bcnt - szCRC);
ModbusData tcrc = rbuf.pduCRC( bcnt - szCRC);
if( tcrc != mFT.crc )
{
......@@ -1739,25 +1737,21 @@ ModbusRTU::mbErrCode ModbusServer::replySetDateTime( ModbusRTU::SetDateTimeMessa
// -------------------------------------------------------------------------
mbErrCode ModbusServer::send( ModbusMessage& msg )
{
if( msg.len > MAXLENPACKET + szModbusHeader )
if( msg.len() > msg.maxSizeOfMessage() )
{
if( dlog->is_warn() )
dlog->warn() << "(ModbusServer::send): длина пакета больше разрешённой..." << endl;
dlog->warn() << "(ModbusServer::send): message len=" << msg.len()
<< " > MAXLEN=" << msg.maxSizeOfMessage() << endl;
return erPacketTooLong;
}
// в стандарте Modbus подразумевается, что данные должны посылаться одним пакетом
// поэтому как минимум надо делать sendData одним буфером.
// Для этого используем класс ADU
ModbusTCP::ADU adu(msg);
mbErrCode ret = make_adu_header(adu);
mbErrCode ret = make_adu_header(msg);
if( ret != erNoError )
return ret;
if( adu.len > (MAXLENPACKET + szModbusHeader + sizeof(ModbusTCP::MBAPHeader)) )
if( msg.len() > msg.maxSizeOfMessage() )
{
if( dlog->is_warn() )
dlog->warn() << "(ModbusServer::send): длина ADU-пакета больше разрешённой..." << endl;
......@@ -1777,36 +1771,28 @@ mbErrCode ModbusServer::send( ModbusMessage& msg )
}
if( dlog->is_info() )
{
if( adu.header.len == 0 )
dlog->info() << "(ModbusServer::send): PDU data[" << adu.pdu.len << " bytes]: " << adu.pdu << endl;
else
dlog->info() << "(ModbusServer::send): ADU data[" << adu.len << " bytes]: " << adu << endl;
}
dlog->info() << "(ModbusServer::send): ADU len=" << msg.aduLen() << " data[" << msg.len() << " bytes]: " << msg << endl;
try
{
if( adu.header.len == 0 )
sendData((unsigned char*)(&adu.pdu), adu.pdu.len);
else
{
adu.header.swapdata();
sendData((unsigned char*)(&adu), adu.len);
adu.header.swapdata(); // обратно, т.к. потом ещё будет post_send_request
}
size_t len = msg.len(); // т.к. swapHead() поменяет
msg.swapHead();
sendData(msg.buf(),len);
msg.swapHead(); // обратно, т.к. потом ещё будет post_send_request
}
catch( const Exception& ex ) // SystemError
{
if( dlog->is_crit() )
dlog->crit() << "(ModbusServer::send): " << ex << endl;
msg.swapHead();
return erHardwareError;
}
if( aftersend_msec > 0 )
iowait(aftersend_msec);
return post_send_request(adu);
return post_send_request(msg);
}
// -------------------------------------------------------------------------
......@@ -80,11 +80,11 @@ size_t ModbusTCPCore::getNextData(UTCPStream* tcp,
std::queue<unsigned char>& qrecv,
unsigned char* buf, size_t len, timeout_t t )
{
if( !tcp || !tcp->isConnected() )
return 0;
if( qrecv.empty() )
if( qrecv.empty() || qrecv.size() < len )
{
if( !tcp || !tcp->isConnected() )
return 0;
if( len <= 0 )
len = 7;
......@@ -159,7 +159,7 @@ size_t ModbusTCPCore::readDataFD( int fd, std::queue<unsigned char>& qrecv, size
size_t ModbusTCPCore::getDataFD( int fd, std::queue<unsigned char>& qrecv,
unsigned char* buf, size_t len, size_t attempts )
{
if( qrecv.empty() || qrecv.size() < len )
if( qrecv.empty() || qrecv.size() < len )
{
if( len == 0 )
len = 7;
......
......@@ -49,7 +49,7 @@ ModbusTCPMaster::~ModbusTCPMaster()
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);
}
......@@ -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);
}
......@@ -102,39 +102,12 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
tcp->setTimeout(timeout);
// ost::Thread::setException(ost::Thread::throwException);
// 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;
}
msg.makeHead(++nTransaction,crcNoCheckit);
for( unsigned int i = 0; i < 2; i++ )
{
if( tcp->isPending(ost::Socket::pendingOutput, timeout) )
{
tcp->writeData(&mh, sizeof(mh));
// send PDU
mbErrCode res = send(msg);
if( res != erNoError )
......@@ -163,8 +136,6 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
dlog->info() << "(ModbusTCPMaster::query): no write pending.. reconnnect OK" << endl;
}
mh.swapdata();
if( timeout != UniSetTimer::WaitUpTime )
{
timeout = ptTimeout.getLeft(timeout);
......@@ -182,19 +153,29 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
tcp->sync();
//reply.clear();
if( tcp->isPending(ost::Socket::pendingInput, timeout) )
{
ModbusTCP::MBAPHeader rmh;
int ret = getNextData((unsigned char*)(&rmh), sizeof(rmh));
size_t ret = 0;
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 << "): ";
mbPrintMessage( dlog->info(false), (ModbusByte*)(&rmh), sizeof(rmh));
mbPrintMessage( dlog->info(false), (ModbusByte*)(&reply.aduhead), sizeof(reply.aduhead));
dlog->info(false) << endl;
}
if( ret < (int)sizeof(rmh) )
if( ret < sizeof(reply.aduhead) )
{
ost::tpport_t port;
......@@ -204,8 +185,8 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
try
{
dlog->warn() << "(ModbusTCPMaster::query): ret=" << (int)ret
<< " < rmh=" << (int)sizeof(rmh)
dlog->warn() << "(ModbusTCPMaster::query): ret=" << ret
<< " < rmh=" << sizeof(reply.aduhead)
<< " errnum: " << tcp->getErrorNumber()
<< " perr: " << tcp->getPeer(&port)
<< " err: " << (err ? string(err) : "")
......@@ -218,19 +199,30 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
}
}
cleanInputStream();
tcp->forceDisconnect();
return erTimeOut; // return erHardwareError;
}
rmh.swapdata();
reply.swapHead();
if( dlog->is_info() )
dlog->info() << "(ModbusTCPMaster::query): ADU len=" << reply.aduLen()
<< endl;
if( rmh.tID != mh.tID )
if( reply.tID() != msg.tID() )
{
if( dlog->is_warn() )
dlog->warn() << "(ModbusTCPMaster::query): tID=" << reply.tID()
<< " != " << msg.tID()
<< " (len=" << reply.len() << ")"
<< endl;
cleanInputStream();
return erBadReplyNodeAddress;
}
if( rmh.pID != 0 )
if( reply.pID() != 0 )
{
cleanInputStream();
return erBadReplyNodeAddress;
......@@ -249,7 +241,8 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
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 )
{
......
......@@ -206,8 +206,8 @@ ModbusRTU::mbErrCode ModbusTCPSession::realReceive( const std::unordered_set<Mod
ptTimeout.setTiming(msec);
{
memset(&curQueryHeader, 0, sizeof(curQueryHeader));
res = tcp_processing(curQueryHeader);
buf.clear();
res = tcp_processing(buf.aduhead);
if( res != erNoError )
return res;
......@@ -223,12 +223,16 @@ ModbusRTU::mbErrCode ModbusTCPSession::realReceive( const std::unordered_set<Mod
if( qrecv.empty() )
return erTimeOut;
unsigned char q_addr = qrecv.front();
if( cancelled )
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 );
if( cancelled )
......@@ -238,7 +242,7 @@ ModbusRTU::mbErrCode ModbusTCPSession::realReceive( const std::unordered_set<Mod
{
if( res < erInternalErrorCode )
{
ErrorRetMessage em( q_addr, buf.func, res );
ErrorRetMessage em( buf.addr(), buf.func(), res );
buf = em.transport_msg();
send(buf);
printProcessingTime();
......@@ -300,7 +304,7 @@ size_t ModbusTCPSession::getNextData( unsigned char* buf, int len )
return 0;
}
// --------------------------------------------------------------------------------
mbErrCode ModbusTCPSession::tcp_processing( ModbusTCP::MBAPHeader& mhead )
mbErrCode ModbusTCPSession::tcp_processing( ModbusRTU::ADUHeader& mhead )
{
// чистим очередь
while( !qrecv.empty() )
......@@ -321,7 +325,6 @@ mbErrCode ModbusTCPSession::tcp_processing( ModbusTCP::MBAPHeader& mhead )
if( dlog->is_info() )
{
//dlog->info() << peername << "(tcp_processing): recv tcp header(" << len << "): " << mhead << endl;
dlog->info() << peername << "(tcp_processing): recv tcp header(" << len << "): ";
mbPrintMessage( dlog->info(false), (ModbusByte*)(&mhead), sizeof(mhead));
dlog->info(false) << endl;
......@@ -331,6 +334,14 @@ mbErrCode ModbusTCPSession::tcp_processing( ModbusTCP::MBAPHeader& mhead )
if( mhead.pID != 0 )
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( dlog->is_info() )
......@@ -363,33 +374,25 @@ mbErrCode ModbusTCPSession::tcp_processing( ModbusTCP::MBAPHeader& mhead )
return erNoError;
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode ModbusTCPSession::post_send_request( ModbusTCP::ADU& request )
ModbusRTU::mbErrCode ModbusTCPSession::post_send_request( ModbusRTU::ModbusMessage& request )
{
return erNoError;
}
// -------------------------------------------------------------------------
mbErrCode ModbusTCPSession::make_adu_header( ModbusTCP::ADU& req )
mbErrCode ModbusTCPSession::make_adu_header( ModbusMessage& req )
{
req.header = curQueryHeader;
req.header.len = req.pdu.len + szModbusHeader;
if( crcNoCheckit )
req.header.len -= szCRC;
req.len = sizeof(req.header) + req.header.len;
//req.header.swapdata();
req.makeHead(curQueryHeader.tID,isCRCNoCheckit(),curQueryHeader.pID);
return erNoError;
}
// -------------------------------------------------------------------------
void ModbusTCPSession::cleanInputStream()
{
unsigned char buf[100];
int ret = 0;
unsigned char tmpbuf[100];
size_t ret = 0;
do
{
ret = getNextData(buf, sizeof(buf));
ret = getNextData(tmpbuf, sizeof(tmpbuf));
}
while( ret > 0);
}
......
......@@ -29,7 +29,7 @@ using namespace std;
#define USE_CRC_TAB 1 // при расчёте использовать таблицы
// -------------------------------------------------------------------------
unsigned short ModbusRTU::SWAPSHORT( unsigned short x )
uint16_t ModbusRTU::SWAPSHORT( uint16_t x )
{
return ((((x) >> 8) & 0xff) | (((x) << 8) & 0xff00));
}
......@@ -39,7 +39,7 @@ unsigned short ModbusRTU::SWAPSHORT( unsigned short x )
#ifdef USE_CRC_TAB
#if 0
static unsigned short crc_ccitt_tab[] =
static uint16_t crc_ccitt_tab[] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
......@@ -76,7 +76,7 @@ static unsigned short crc_ccitt_tab[] =
};
#endif
static unsigned short crc_16_tab[] =
static uint16_t crc_16_tab[] =
{
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
......@@ -115,7 +115,7 @@ static unsigned short crc_16_tab[] =
// Lav: отключил, раз не используем
#if 0
// -------------------------------------------------------------------------
static int get_crc_ccitt( unsigned short crc, unsigned char* buf, int size )
static int get_crc_ccitt( uint16_t crc, uint8_t* buf, size_t size )
{
while( size-- )
{
......@@ -142,7 +142,7 @@ static int get_crc_ccitt( unsigned short crc, unsigned char* buf, int size )
// -------------------------------------------------------------------------
/* CRC-16 is based on the polynomial x^16 + x^15 + x^2 + 1. Bits are */
/* sent LSB to MSB. */
static int get_crc_16( unsigned short crc, unsigned char* buf, int size )
static int get_crc_16( uint16_t crc, uint8_t* buf, size_t size )
{
while( size-- )
......@@ -174,10 +174,10 @@ static int get_crc_16( unsigned short crc, unsigned char* buf, int size )
/*! \todo Необходимо разобраться с разными версиями и функциями расчёта CRC
и по возможности вынести их в отдельный модуль или класс
*/
ModbusCRC ModbusRTU::checkCRC( ModbusByte* buf, int len )
ModbusCRC ModbusRTU::checkCRC( ModbusByte* buf, size_t len )
{
unsigned short crc = 0xffff;
crc = get_crc_16(crc, (unsigned char*)(buf), len);
crc = get_crc_16(crc, (uint8_t*)(buf), len);
// crc = SWAPSHORT(crc);
return crc;
......@@ -223,16 +223,72 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, const ModbusHeader* m )
// -------------------------------------------------------------------------
ModbusMessage::ModbusMessage():
len(0)
dlen(0)
{
addr = 0;
func = 0;
pduhead.addr = 0;
pduhead.func = 0;
memset(data, 0, sizeof(data));
}
// -------------------------------------------------------------------------
unsigned char* ModbusMessage::buf()
{
if( aduhead.len == 0 )
return (unsigned char*)&pduhead;
return (unsigned char*)&aduhead;
}
// -------------------------------------------------------------------------
ModbusData ModbusMessage::len() const
{
if( aduhead.len == 0 )
return pduLen();
return (sizeof(aduhead) + aduhead.len);
}
// -------------------------------------------------------------------------
void ModbusMessage::swapHead()
{
aduhead.swapdata();
}
// -------------------------------------------------------------------------
void ModbusMessage::makeHead( ModbusData tID, bool noCRC, ModbusData pID )
{
aduhead.tID = tID;
aduhead.pID = pID;
aduhead.len = pduLen();
if( noCRC )
aduhead.len -= szCRC;
}
// -------------------------------------------------------------------------
ModbusData ModbusMessage::pduLen() const
{
return (szModbusHeader + dlen);
}
// -------------------------------------------------------------------------
ModbusCRC ModbusMessage::pduCRC( size_t clen ) const
{
return checkCRC( (ModbusByte*)(&pduhead), clen /* sizeof(pduhead)+dlen */ );
}
// -------------------------------------------------------------------------
size_t ModbusMessage::maxSizeOfMessage()
{
return (MAXLENPACKET + szModbusHeader + sizeof(ModbusRTU::ADUHeader));
}
// -------------------------------------------------------------------------
void ModbusMessage::clear()
{
memset(this, 0, sizeof(*this));
}
// -------------------------------------------------------------------------
std::ostream& ModbusRTU::operator<<(std::ostream& os, const ModbusMessage& m )
{
return mbPrintMessage(os, (ModbusByte*)(&m), szModbusHeader + m.len);
os << m.aduhead << "| ";
if( m.aduLen() == 0 )
mbPrintMessage(os, (ModbusByte*)(&m.pduhead), sizeof(m.pduhead) + m.dlen);
else
mbPrintMessage(os, (ModbusByte*)(&m.pduhead), m.aduLen());
return os;
// return mbPrintMessage(os, (ModbusByte*)(&m), sizeof(m.aduhead) + sizeof(m.pduhead) + m.dlen);
}
std::ostream& ModbusRTU::operator<<(std::ostream& os, const ModbusMessage* m )
......@@ -254,7 +310,7 @@ ErrorRetMessage& ErrorRetMessage::operator=( const ModbusMessage& m )
void ErrorRetMessage::init( const ModbusMessage& m )
{
memset(this, 0, sizeof(*this));
memcpy(this, &m, szModbusHeader);
memcpy(this, &m.pduhead, szModbusHeader);
ecode = m.data[0];
memcpy( &crc, &(m.data[1]), szCRC);
}
......@@ -272,21 +328,21 @@ ModbusMessage ErrorRetMessage::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
memcpy(&mm.data, &ecode, sizeof(ecode));
size_t ind = sizeof(ecode);
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + ind );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + ind );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = ind; // szData();
mm.dlen = ind; // szData();
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -319,7 +375,7 @@ ModbusMessage ReadCoilMessage::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
// копируем данные (переворачиваем байты)
ModbusData d[2] = { SWAPSHORT(start), SWAPSHORT(count) };
......@@ -330,12 +386,12 @@ ModbusMessage ReadCoilMessage::transport_msg()
memcpy(mm.data, &d, last);
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + sizeof(d) );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + sizeof(d) );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[last]), &crc, szCRC);
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -353,9 +409,10 @@ ReadCoilMessage& ReadCoilMessage::operator=( const ModbusMessage& m )
// -------------------------------------------------------------------------
void ReadCoilMessage::init( const ModbusMessage& m )
{
assert( m.func == fnReadCoilStatus );
memset(this, 0, sizeof(*this));
memcpy(this, &m, sizeof(*this)); // m.len
assert( m.pduhead.func == fnReadCoilStatus );
// memset(this, 0, sizeof(*this));
memcpy(this, &m.pduhead, sizeof(m.pduhead));
memcpy(&start, m.data, szData());
// переворачиваем слова
start = SWAPSHORT(start);
......@@ -508,11 +565,11 @@ ReadCoilRetMessage& ReadCoilRetMessage::operator=( const ModbusMessage& m )
// -------------------------------------------------------------------------
void ReadCoilRetMessage::init( const ModbusMessage& m )
{
assert( m.func == fnReadCoilStatus );
assert( m.pduhead.func == fnReadCoilStatus );
memset(this, 0, sizeof(*this));
addr = m.addr;
func = m.func;
addr = m.pduhead.addr;
func = m.pduhead.func;
bcnt = m.data[0];
......@@ -525,7 +582,7 @@ void ReadCoilRetMessage::init( const ModbusMessage& m )
// -------------------------------------------------------------------------
size_t ReadCoilRetMessage::getDataLen( const ModbusMessage& m )
{
if( m.len == 0 )
if( m.dlen == 0 )
return 0;
return m.data[0];
......@@ -585,7 +642,7 @@ ModbusMessage ReadCoilRetMessage::transport_msg()
assert( sizeof(ModbusMessage) >= (unsigned int)szModbusHeader + szData() );
// копируем заголовок и данные
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
memcpy(&mm.data, &bcnt, sizeof(bcnt));
size_t ind = sizeof(bcnt);
......@@ -595,14 +652,14 @@ ModbusMessage ReadCoilRetMessage::transport_msg()
ind += bcnt;
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + sizeof(bcnt) + bcnt );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + sizeof(bcnt) + bcnt );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = ind;
mm.dlen = ind;
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -638,7 +695,7 @@ ModbusMessage ReadInputStatusMessage::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
// копируем данные (переворачиваем байты)
ModbusData d[2] = { SWAPSHORT(start), SWAPSHORT(count) };
......@@ -649,12 +706,12 @@ ModbusMessage ReadInputStatusMessage::transport_msg()
memcpy(mm.data, &d, last);
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + sizeof(d) );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + sizeof(d) );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[last]), &crc, szCRC);
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -672,9 +729,8 @@ ReadInputStatusMessage& ReadInputStatusMessage::operator=( const ModbusMessage&
// -------------------------------------------------------------------------
void ReadInputStatusMessage::init( const ModbusMessage& m )
{
assert( m.func == fnReadInputStatus );
memset(this, 0, sizeof(*this));
memcpy(this, &m, sizeof(*this)); // m.len
assert( m.pduhead.func == fnReadInputStatus );
memcpy(this, &m.pduhead, sizeof(m.pduhead)+szData());
// переворачиваем слова
start = SWAPSHORT(start);
......@@ -710,11 +766,11 @@ ReadInputStatusRetMessage& ReadInputStatusRetMessage::operator=( const ModbusMes
// -------------------------------------------------------------------------
void ReadInputStatusRetMessage::init( const ModbusMessage& m )
{
assert( m.func == fnReadInputStatus );
assert( m.pduhead.func == fnReadInputStatus );
memset(this, 0, sizeof(*this));
addr = m.addr;
func = m.func;
//memset(this, 0, sizeof(*this));
addr = m.pduhead.addr;
func = m.pduhead.func;
bcnt = m.data[0];
......@@ -727,7 +783,7 @@ void ReadInputStatusRetMessage::init( const ModbusMessage& m )
// -------------------------------------------------------------------------
size_t ReadInputStatusRetMessage::getDataLen( const ModbusMessage& m )
{
if( m.len == 0 )
if( m.dlen == 0 )
return 0;
return m.data[0];
......@@ -787,7 +843,7 @@ ModbusMessage ReadInputStatusRetMessage::transport_msg()
assert( sizeof(ModbusMessage) >= (unsigned int)szModbusHeader + szData() );
// копируем заголовок и данные
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
memcpy(&mm.data, &bcnt, sizeof(bcnt));
size_t ind = sizeof(bcnt);
......@@ -797,14 +853,14 @@ ModbusMessage ReadInputStatusRetMessage::transport_msg()
ind += bcnt;
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + sizeof(bcnt) + bcnt );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + sizeof(bcnt) + bcnt );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = ind;
mm.dlen = ind;
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -841,7 +897,7 @@ ModbusMessage ReadOutputMessage::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
// копируем данные (переворачиваем байты)
ModbusData d[2] = { SWAPSHORT(start), SWAPSHORT(count) };
......@@ -852,13 +908,13 @@ ModbusMessage ReadOutputMessage::transport_msg()
memcpy(mm.data, &d, last);
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + sizeof(d) );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + sizeof(d) );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[last]), &crc, szCRC);
// длина сообщения...
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
......@@ -877,9 +933,9 @@ ReadOutputMessage& ReadOutputMessage::operator=( const ModbusMessage& m )
// -------------------------------------------------------------------------
void ReadOutputMessage::init( const ModbusMessage& m )
{
assert( m.func == fnReadOutputRegisters );
memset(this, 0, sizeof(*this));
memcpy(this, &m, sizeof(*this)); // m.len
assert( m.pduhead.func == fnReadOutputRegisters );
//memset(this, 0, sizeof(*this));
memcpy(this, &m.pduhead, sizeof(m.pduhead)+szData());
// переворачиваем слова
start = SWAPSHORT(start);
......@@ -916,21 +972,16 @@ ReadOutputRetMessage& ReadOutputRetMessage::operator=( const ModbusMessage& m )
// -------------------------------------------------------------------------
void ReadOutputRetMessage::init( const ModbusMessage& m )
{
assert( m.func == fnReadOutputRegisters );
assert( m.pduhead.func == fnReadOutputRegisters );
memset(this, 0, sizeof(*this));
addr = m.addr;
func = m.func;
addr = m.pduhead.addr;
func = m.pduhead.func;
// bcnt = m.data[0];
unsigned int cnt = m.data[0] / sizeof(ModbusData);
size_t cnt = m.data[0] / sizeof(ModbusData);
if( cnt > MAXLENPACKET / sizeof(ModbusData) )
{
// cerr << "(ReadOutputRetMessage): BAD bcnt="
// << (int)bcnt << " count=" << cnt << endl;
throw mbException(erPacketTooLong);
}
count = cnt;
bcnt = m.data[0];
......@@ -945,7 +996,7 @@ void ReadOutputRetMessage::init( const ModbusMessage& m )
// -------------------------------------------------------------------------
size_t ReadOutputRetMessage::getDataLen( const ModbusMessage& m )
{
if( m.len == 0 )
if( m.dlen == 0 )
return 0;
return m.data[0];
......@@ -984,7 +1035,7 @@ ModbusMessage ReadOutputRetMessage::transport_msg()
assert( sizeof(ModbusMessage) >= (unsigned int)szModbusHeader + szData() );
// копируем заголовок и данные
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
size_t ind = 0;
bcnt = count * sizeof(ModbusData);
......@@ -1011,14 +1062,14 @@ ModbusMessage ReadOutputRetMessage::transport_msg()
}
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + sizeof(bcnt) + bcnt );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + sizeof(bcnt) + bcnt );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = ind;
mm.dlen = ind;
return std::move(mm);
}
......@@ -1055,7 +1106,7 @@ ModbusMessage ReadInputMessage::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
// копируем данные (переворачиваем байты)
ModbusData d[2] = { SWAPSHORT(start), SWAPSHORT(count) };
......@@ -1066,13 +1117,13 @@ ModbusMessage ReadInputMessage::transport_msg()
memcpy(mm.data, &d, last);
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + sizeof(d) );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + sizeof(d) );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[last]), &crc, szCRC);
// длина сообщения...
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -1090,9 +1141,10 @@ ReadInputMessage& ReadInputMessage::operator=( const ModbusMessage& m )
// -------------------------------------------------------------------------
void ReadInputMessage::init( const ModbusMessage& m )
{
assert( m.func == fnReadInputRegisters );
memset(this, 0, sizeof(*this));
memcpy(this, &m, sizeof(*this)); // m.len
assert( m.pduhead.func == fnReadInputRegisters );
// memset(this, 0, sizeof(*this));
memcpy(this, &m.pduhead, sizeof(m.pduhead));
memcpy(&start,m.data,szData());
// переворачиваем слова
start = SWAPSHORT(start);
......@@ -1129,14 +1181,14 @@ ReadInputRetMessage& ReadInputRetMessage::operator=( const ModbusMessage& m )
// -------------------------------------------------------------------------
void ReadInputRetMessage::init( const ModbusMessage& m )
{
assert( m.func == fnReadInputRegisters );
assert( m.pduhead.func == fnReadInputRegisters );
memset(this, 0, sizeof(*this));
addr = m.addr;
func = m.func;
addr = m.pduhead.addr;
func = m.pduhead.func;
// bcnt = m.data[0];
unsigned int cnt = m.data[0] / sizeof(ModbusData);
size_t cnt = m.data[0] / sizeof(ModbusData);
if( cnt > MAXLENPACKET / sizeof(ModbusData) )
throw mbException(erPacketTooLong);
......@@ -1160,7 +1212,7 @@ void ReadInputRetMessage::swapData()
// -------------------------------------------------------------------------
size_t ReadInputRetMessage::getDataLen( const ModbusMessage& m )
{
if( m.len == 0 )
if( m.dlen == 0 )
return 0;
return m.data[0];
......@@ -1198,7 +1250,7 @@ ModbusMessage ReadInputRetMessage::transport_msg()
assert( sizeof(ModbusMessage) >= (unsigned int)szModbusHeader + szData() );
// копируем заголовок и данные
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
size_t ind = 0;
bcnt = count * sizeof(ModbusData);
......@@ -1224,14 +1276,14 @@ ModbusMessage ReadInputRetMessage::transport_msg()
}
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + sizeof(bcnt) + bcnt );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + sizeof(bcnt) + bcnt );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = ind;
mm.dlen = ind;
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -1325,7 +1377,7 @@ ModbusMessage ForceCoilsMessage::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
size_t ind = 0;
......@@ -1346,14 +1398,14 @@ ModbusMessage ForceCoilsMessage::transport_msg()
ind += bcnt;
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + ind );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + ind );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = ind;
mm.dlen = ind;
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -1371,12 +1423,12 @@ ForceCoilsMessage& ForceCoilsMessage::operator=( const ModbusMessage& m )
// -------------------------------------------------------------------------
void ForceCoilsMessage::init( const ModbusMessage& m )
{
assert( m.func == fnForceMultipleCoils );
assert( m.pduhead.func == fnForceMultipleCoils );
memset(this, 0, sizeof(*this));
// copy not include CRC
memcpy(this, &m, szModbusHeader + m.len);
memcpy(this, &m.pduhead, szModbusHeader + m.dlen);
// Сперва переворачиваем обратно слова
start = SWAPSHORT(start);
......@@ -1400,7 +1452,7 @@ void ForceCoilsMessage::init( const ModbusMessage& m )
}
// последний элемент это CRC
memcpy(&crc, &(m.data[m.len - szCRC]), szCRC);
memcpy(&crc, &(m.data[m.dlen - szCRC]), szCRC);
}
// -------------------------------------------------------------------------
bool ForceCoilsMessage::checkFormat()
......@@ -1415,7 +1467,7 @@ size_t ForceCoilsMessage::szData()
// -------------------------------------------------------------------------
size_t ForceCoilsMessage::getDataLen( const ModbusMessage& m )
{
if( m.len == 0 )
if( m.dlen == 0 )
return 0;
ForceCoilsMessage wm(m);
......@@ -1457,12 +1509,12 @@ ForceCoilsRetMessage& ForceCoilsRetMessage::operator=( const ModbusMessage& m )
// -------------------------------------------------------------------------
void ForceCoilsRetMessage::init( const ModbusMessage& m )
{
assert( m.func == fnForceMultipleCoils );
assert( m.pduhead.func == fnForceMultipleCoils );
memset(this, 0, sizeof(*this));
// memset(this, 0, sizeof(*this));
// copy not include CRC
memcpy(this, &m, szModbusHeader + m.len);
memcpy(this, &m.pduhead, szModbusHeader + m.dlen);
/*! \todo (WriteOutputRetMessage): необходимо встроить проверку на корректность данных */
......@@ -1470,7 +1522,7 @@ void ForceCoilsRetMessage::init( const ModbusMessage& m )
start = SWAPSHORT(start);
quant = SWAPSHORT(quant);
int ind = sizeof(quant) + sizeof(start);
size_t ind = sizeof(quant) + sizeof(start);
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&crc, &(m.data[ind]), szCRC);
......@@ -1498,7 +1550,7 @@ ModbusMessage ForceCoilsRetMessage::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
// данные (переворачиваем байты)
ModbusData d[2] = { SWAPSHORT(start), SWAPSHORT(quant) };
......@@ -1507,12 +1559,12 @@ ModbusMessage ForceCoilsRetMessage::transport_msg()
memcpy(mm.data, &d, last);
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + last );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + last );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[last]), &crc, szCRC);
// длина сообщения...
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
......@@ -1560,7 +1612,7 @@ ModbusMessage WriteOutputMessage::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
size_t ind = 0;
......@@ -1589,14 +1641,14 @@ ModbusMessage WriteOutputMessage::transport_msg()
ind += bcnt;
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + ind );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + ind );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = ind;
mm.dlen = ind;
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -1614,12 +1666,12 @@ WriteOutputMessage& WriteOutputMessage::operator=( const ModbusMessage& m )
// -------------------------------------------------------------------------
void WriteOutputMessage::init( const ModbusMessage& m )
{
assert( m.func == fnWriteOutputRegisters );
assert( m.pduhead.func == fnWriteOutputRegisters );
memset(this, 0, sizeof(*this));
// copy not include CRC
memcpy(this, &m, szModbusHeader + m.len);
memcpy(this, &m.pduhead, szModbusHeader + m.dlen);
// Сперва переворачиваем обратно слова
start = SWAPSHORT(start);
......@@ -1643,7 +1695,7 @@ void WriteOutputMessage::init( const ModbusMessage& m )
}
// последний элемент это CRC
memcpy(&crc, &(m.data[m.len - szCRC]), szCRC);
memcpy(&crc, &(m.data[m.dlen - szCRC]), szCRC);
int count( bcnt / sizeof(ModbusData) );
......@@ -1664,7 +1716,7 @@ size_t WriteOutputMessage::szData()
// -------------------------------------------------------------------------
size_t WriteOutputMessage::getDataLen( const ModbusMessage& m )
{
if( m.len == 0 )
if( m.dlen == 0 )
return 0;
// копируем только часть заголовка возвращаем count
......@@ -1716,12 +1768,12 @@ WriteOutputRetMessage& WriteOutputRetMessage::operator=( const ModbusMessage& m
// -------------------------------------------------------------------------
void WriteOutputRetMessage::init( const ModbusMessage& m )
{
assert( m.func == fnWriteOutputRegisters );
assert( m.pduhead.func == fnWriteOutputRegisters );
memset(this, 0, sizeof(*this));
//memset(this, 0, sizeof(*this));
// copy not include CRC
memcpy(this, &m, szModbusHeader + m.len);
memcpy(this, &m.pduhead, szModbusHeader + m.dlen);
/*! \todo (WriteOutputRetMessage): необходимо встроить проверку на корректность данных */
......@@ -1729,7 +1781,7 @@ void WriteOutputRetMessage::init( const ModbusMessage& m )
start = SWAPSHORT(start);
quant = SWAPSHORT(quant);
int ind = sizeof(quant) + sizeof(start);
size_t ind = sizeof(quant) + sizeof(start);
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&crc, &(m.data[ind]), szCRC);
......@@ -1757,7 +1809,7 @@ ModbusMessage WriteOutputRetMessage::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
// данные (переворачиваем байты)
ModbusData d[2] = { SWAPSHORT(start), SWAPSHORT(quant) };
......@@ -1766,12 +1818,12 @@ ModbusMessage WriteOutputRetMessage::transport_msg()
memcpy(mm.data, &d, last);
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + last );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + last );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[last]), &crc, szCRC);
// длина сообщения...
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
......@@ -1798,15 +1850,15 @@ ModbusMessage ForceSingleCoilMessage::transport_msg()
assert(sizeof(ModbusMessage) >= sizeof(ForceSingleCoilMessage));
ModbusMessage mm;
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
ModbusData d[2] = { SWAPSHORT(start), SWAPSHORT(data) };
size_t last = sizeof(d); // индекс в массиве данных ( байтовый массив!!! )
memcpy(mm.data, &d, last);
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + last );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + last );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[last]), &crc, szCRC);
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
// --------------------------------------------------------------------------------
......@@ -1824,11 +1876,11 @@ ForceSingleCoilMessage& ForceSingleCoilMessage::operator=( const ModbusMessage&
// -------------------------------------------------------------------------
void ForceSingleCoilMessage::init( const ModbusMessage& m )
{
assert( m.func == fnForceSingleCoil );
memset(this, 0, sizeof(*this));
assert( m.pduhead.func == fnForceSingleCoil );
// memset(this, 0, sizeof(*this));
// копируем данные вместе с CRC
memcpy(this, &m, szModbusHeader + m.len + szCRC);
memcpy(this, &m.pduhead, szModbusHeader + m.dlen + szCRC);
// Сперва переворачиваем обратно слова
start = SWAPSHORT(start);
......@@ -1859,7 +1911,7 @@ size_t ForceSingleCoilMessage::szData()
// -------------------------------------------------------------------------
size_t ForceSingleCoilMessage::getDataLen( const ModbusMessage& m )
{
if( m.len == 0 )
if( m.dlen == 0 )
return 0;
return sizeof(ModbusData); // data;
......@@ -1894,13 +1946,13 @@ void ForceSingleCoilRetMessage::init( const ModbusMessage& m )
memset(this, 0, sizeof(*this));
// copy not include CRC
memcpy(this, &m, szModbusHeader + m.len);
memcpy(this, &m.pduhead, szModbusHeader + m.dlen);
/*! \todo (ForceSingleCoilRetMessage): необходимо встроить проверку на корректность данных */
// переворачиваем обратно слова
start = SWAPSHORT(start);
data = SWAPSHORT(data);
start = SWAPSHORT(start);
data = SWAPSHORT(data);
}
// -------------------------------------------------------------------------
ForceSingleCoilRetMessage::ForceSingleCoilRetMessage( ModbusAddr _from )
......@@ -1924,7 +1976,7 @@ ModbusMessage ForceSingleCoilRetMessage::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
// копируем данные (переворачиваем байты)
ModbusData d[2] = { SWAPSHORT(start), SWAPSHORT(data) };
......@@ -1935,13 +1987,13 @@ ModbusMessage ForceSingleCoilRetMessage::transport_msg()
memcpy(mm.data, &d, last);
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + sizeof(d) );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + sizeof(d) );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[last]), &crc, szCRC);
// длина сообщения...
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
......@@ -1969,15 +2021,15 @@ ModbusMessage WriteSingleOutputMessage::transport_msg()
assert(sizeof(ModbusMessage) >= sizeof(WriteSingleOutputMessage));
ModbusMessage mm;
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
ModbusData d[2] = { SWAPSHORT(start), SWAPSHORT(data) };
size_t last = sizeof(d); // индекс в массиве данных ( байтовый массив!!! )
memcpy(mm.data, &d, last);
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + last );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + last );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[last]), &crc, szCRC);
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
// --------------------------------------------------------------------------------
......@@ -1995,11 +2047,11 @@ WriteSingleOutputMessage& WriteSingleOutputMessage::operator=( const ModbusMessa
// -------------------------------------------------------------------------
void WriteSingleOutputMessage::init( const ModbusMessage& m )
{
assert( m.func == fnWriteOutputSingleRegister );
memset(this, 0, sizeof(*this));
assert( m.pduhead.func == fnWriteOutputSingleRegister );
// memset(this, 0, sizeof(*this));
// копируем данные вместе с CRC
memcpy(this, &m, szModbusHeader + m.len + szCRC);
memcpy(this, &m.pduhead, szModbusHeader + m.dlen + szCRC);
// Сперва переворачиваем обратно слова
start = SWAPSHORT(start);
......@@ -2031,7 +2083,7 @@ size_t WriteSingleOutputMessage::szData()
// -------------------------------------------------------------------------
size_t WriteSingleOutputMessage::getDataLen( const ModbusMessage& m )
{
if( m.len == 0 )
if( m.dlen == 0 )
return 0;
return sizeof(ModbusData); // data;
......@@ -2068,10 +2120,10 @@ WriteSingleOutputRetMessage& WriteSingleOutputRetMessage::operator=( const Modbu
// -------------------------------------------------------------------------
void WriteSingleOutputRetMessage::init( const ModbusMessage& m )
{
memset(this, 0, sizeof(*this));
// memset(this, 0, sizeof(*this));
// copy not include CRC
memcpy(this, &m, szModbusHeader + m.len);
memcpy(this, &m.pduhead, szModbusHeader + m.dlen);
/*! \todo (WriteSingleOutputRetMessage): необходимо встроить проверку на корректность данных */
......@@ -2102,7 +2154,7 @@ ModbusMessage WriteSingleOutputRetMessage::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
// копируем данные (переворачиваем байты)
ModbusData d[2] = { SWAPSHORT(start), SWAPSHORT(data) };
......@@ -2113,13 +2165,13 @@ ModbusMessage WriteSingleOutputRetMessage::transport_msg()
memcpy(mm.data, &d, last);
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + sizeof(d) );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + sizeof(d) );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[last]), &crc, szCRC);
// длина сообщения...
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
......@@ -2199,11 +2251,11 @@ DiagnosticMessage& DiagnosticMessage::operator=( const ModbusMessage& m )
// -------------------------------------------------------------------------
void DiagnosticMessage::init( const ModbusMessage& m )
{
assert( m.func == fnDiagnostics );
assert( m.pduhead.func == fnDiagnostics );
memset(this, 0, sizeof(*this));
addr = m.addr;
func = m.func;
addr = m.pduhead.addr;
func = m.pduhead.func;
memcpy( &subf, &(m.data[0]), sizeof(subf) );
int last = sizeof(subf);
......@@ -2229,7 +2281,7 @@ void DiagnosticMessage::init( const ModbusMessage& m )
// -------------------------------------------------------------------------
size_t DiagnosticMessage::getDataLen( const ModbusMessage& m )
{
if( m.len == 0 )
if( m.dlen == 0 )
return 0;
// data[0] = subfunction
......@@ -2277,7 +2329,7 @@ ModbusMessage DiagnosticMessage::transport_msg()
assert( sizeof(ModbusMessage) >= (unsigned int)szModbusHeader + szData() );
// копируем заголовок и данные
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
size_t ind = 0;
// copy bcnt
......@@ -2302,14 +2354,14 @@ ModbusMessage DiagnosticMessage::transport_msg()
}
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + sizeof(subf) + sizeof(ModbusData) * count );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + sizeof(subf) + sizeof(ModbusData) * count );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -2391,21 +2443,21 @@ ModbusMessage MEIMessageRDI::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
mm.data[0] = type;
mm.data[1] = devID;
mm.data[2] = objID;
size_t ind = 3;
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + ind );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + ind );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -2423,12 +2475,12 @@ MEIMessageRDI& MEIMessageRDI::operator=( const ModbusMessage& m )
// -------------------------------------------------------------------------
void MEIMessageRDI::init( const ModbusMessage& m )
{
assert( m.func == fnMEI );
assert( m.pduhead.func == fnMEI );
memset(this, 0, sizeof(*this));
// copy not include CRC
memcpy(this, &m, szModbusHeader + m.len);
memcpy(this, &m.pduhead, szModbusHeader + m.dlen);
// потом проверяем
if( !checkFormat() )
......@@ -2441,7 +2493,7 @@ void MEIMessageRDI::init( const ModbusMessage& m )
}
// последний элемент это CRC
memcpy(&crc, &(m.data[m.len - szCRC]), szCRC);
memcpy(&crc, &(m.data[m.dlen - szCRC]), szCRC);
}
// -------------------------------------------------------------------------
bool MEIMessageRDI::checkFormat()
......@@ -2494,17 +2546,17 @@ RDIObjectInfo::RDIObjectInfo( ModbusByte id, const ModbusByte* dat, ModbusByte l
// -------------------------------------------------------------------------
void MEIMessageRetRDI::pre_init( const ModbusMessage& m )
{
assert( m.func == fnMEI );
assert( m.pduhead.func == fnMEI );
addr = m.addr;
func = m.func;
addr = m.pduhead.addr;
func = m.pduhead.func;
type = m.data[0];
if( type != 0x0E )
throw mbException(erInvalidFormat);
if( m.len < 6 )
if( m.dlen < 6 )
throw mbException(erInvalidFormat);
devID = m.data[1];
......@@ -2516,16 +2568,16 @@ void MEIMessageRetRDI::pre_init( const ModbusMessage& m )
// -------------------------------------------------------------------------
void MEIMessageRetRDI::init( const ModbusMessage& m )
{
assert( m.func == fnMEI );
assert( m.pduhead.func == fnMEI );
addr = m.addr;
func = m.func;
addr = m.pduhead.addr;
func = m.pduhead.func;
type = m.data[0];
if( type != 0x0E )
throw mbException(erInvalidFormat);
if( m.len < 6 )
if( m.dlen < 6 )
throw mbException(erInvalidFormat);
devID = m.data[1];
......@@ -2540,15 +2592,15 @@ void MEIMessageRetRDI::init( const ModbusMessage& m )
if( objNum > 0 )
{
if( m.len < 7 )
if( m.dlen < 7 )
throw mbException(erInvalidFormat);
while( i < m.len && dlist.size() < objNum )
while( i < m.dlen && dlist.size() < objNum )
{
ModbusByte id = m.data[i];
size_t dlen = (int)(m.data[i + 1]);
if( m.len < (i + 1 + dlen) )
if( m.dlen < (i + 1 + dlen) )
throw mbException(erInvalidFormat);
RDIObjectInfo rdi(id, &(m.data[i + 2]), dlen );
......@@ -2613,7 +2665,7 @@ ModbusMessage MEIMessageRetRDI::transport_msg()
assert( sizeof(ModbusMessage) >= (unsigned int)szModbusHeader + szData() );
// копируем заголовок и данные
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
mm.data[0] = type;
mm.data[1] = devID;
......@@ -2633,14 +2685,14 @@ ModbusMessage MEIMessageRetRDI::transport_msg()
}
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + ind );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + ind );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = ind;
mm.dlen = ind;
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -2697,9 +2749,9 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, RDIObjectList* l )
JournalCommandMessage::JournalCommandMessage( const ModbusMessage& m )
{
assert( m.func == fnJournalCommand );
memset(this, 0, sizeof(*this));
memcpy(this, &m, sizeof(*this)); // m.len
assert( m.pduhead.func == fnJournalCommand );
//memset(this, 0, sizeof(*this));
memcpy(this, &m.pduhead, sizeof(*this)); // m.len
// переворачиваем слова
cmd = SWAPSHORT(cmd);
......@@ -2708,9 +2760,9 @@ JournalCommandMessage::JournalCommandMessage( const ModbusMessage& m )
// -------------------------------------------------------------------------
JournalCommandMessage& JournalCommandMessage::operator=( const ModbusMessage& m )
{
assert( m.func == fnJournalCommand );
memset(this, 0, sizeof(*this));
memcpy(this, &m, sizeof(*this)); // m.len
assert( m.pduhead.func == fnJournalCommand );
// memset(this, 0, sizeof(*this));
memcpy(this, &m.pduhead, sizeof(*this)); // m.len
// переворачиваем слова
cmd = SWAPSHORT(cmd);
......@@ -2775,7 +2827,7 @@ ModbusMessage JournalCommandRetMessage::transport_msg()
assert( sizeof(ModbusMessage) >= (unsigned int)szModbusHeader + szData() );
// копируем заголовок и данные
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
size_t ind = 0;
bcnt = count * sizeof(ModbusData);
......@@ -2804,14 +2856,14 @@ ModbusMessage JournalCommandRetMessage::transport_msg()
}
// пересчитываем CRC по данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + ind );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + ind );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = ind;
mm.dlen = ind;
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -2961,16 +3013,16 @@ std::string ModbusRTU::mbErr2Str( ModbusRTU::mbErrCode e )
// -------------------------------------------------------------------------
SetDateTimeMessage::SetDateTimeMessage( const ModbusMessage& m )
{
assert( m.func == fnSetDateTime );
assert( m.pduhead.func == fnSetDateTime );
memset(this, 0, sizeof(*this));
memcpy(this, &m, sizeof(*this)); // m.len
memcpy(this, &m.pduhead, sizeof(*this)); // m.len
}
// -------------------------------------------------------------------------
SetDateTimeMessage& SetDateTimeMessage::operator=( const ModbusMessage& m )
{
assert( m.func == fnSetDateTime );
assert( m.pduhead.func == fnSetDateTime );
memset(this, 0, sizeof(*this));
memcpy(this, &m, sizeof(*this)); // m.len
memcpy(this, &m.pduhead, sizeof(*this)); // m.len
return *this;
}
// -------------------------------------------------------------------------
......@@ -3033,7 +3085,7 @@ ModbusMessage SetDateTimeMessage::transport_msg()
assert( sizeof(ModbusMessage) >= (unsigned int)szModbusHeader + szData() );
// копируем заголовок и данные
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
/*
mm.data[0] = hour;
mm.data[1] = min;
......@@ -3047,11 +3099,11 @@ ModbusMessage SetDateTimeMessage::transport_msg()
memcpy( mm.data, &hour, bcnt );
// пересчитываем CRC
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + bcnt );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + bcnt );
memcpy(&(mm.data[bcnt]), &crc, szCRC);
// длина сообщения...
mm.len = szData(); // bcnt + szCRC
mm.dlen = szData(); // bcnt + szCRC
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -3068,9 +3120,9 @@ SetDateTimeRetMessage& SetDateTimeRetMessage::operator=( const ModbusMessage& m
// -------------------------------------------------------------------------
void SetDateTimeRetMessage::init( const ModbusMessage& m )
{
assert( m.func == fnSetDateTime );
assert( m.pduhead.func == fnSetDateTime );
memset(this, 0, sizeof(*this));
memcpy(this, &m, sizeof(*this)); // m.len
memcpy(this, &m.pduhead, sizeof(*this)); // m.len
}
// -------------------------------------------------------------------------
SetDateTimeRetMessage::SetDateTimeRetMessage( ModbusAddr _from )
......@@ -3106,7 +3158,7 @@ ModbusMessage SetDateTimeRetMessage::transport_msg()
assert( sizeof(ModbusMessage) >= (unsigned int)szModbusHeader + szData() );
// копируем заголовок и данные
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
/*
mm.data[0] = hour;
......@@ -3121,13 +3173,13 @@ ModbusMessage SetDateTimeRetMessage::transport_msg()
memcpy( mm.data, &hour, bcnt );
// пересчитываем CRC
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + bcnt );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + bcnt );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[bcnt]), &crc, szCRC);
// длина сообщения...
mm.len = szData(); // bcnt + szCRC
mm.dlen = szData(); // bcnt + szCRC
return std::move(mm);
}
......@@ -3145,14 +3197,14 @@ RemoteServiceMessage& RemoteServiceMessage::operator=( const ModbusMessage& m )
// -------------------------------------------------------------------------
void RemoteServiceMessage::init( const ModbusMessage& m )
{
assert( m.func == fnRemoteService );
assert( m.pduhead.func == fnRemoteService );
memset(this, 0, sizeof(*this));
// copy not include CRC
memcpy(this, &m, szModbusHeader + m.len);
memcpy(this, &m.pduhead, szModbusHeader + m.dlen);
// последний элемент это CRC
memcpy(&crc, &(m.data[m.len - szCRC]), szCRC);
memcpy(&crc, &(m.data[m.dlen - szCRC]), szCRC);
}
// -------------------------------------------------------------------------
size_t RemoteServiceMessage::szData()
......@@ -3162,7 +3214,7 @@ size_t RemoteServiceMessage::szData()
// -------------------------------------------------------------------------
size_t RemoteServiceMessage::getDataLen( const ModbusMessage& m )
{
if( m.len == 0 )
if( m.dlen == 0 )
return 0;
return (size_t)(m.data[0]);
......@@ -3224,7 +3276,7 @@ ModbusMessage RemoteServiceRetMessage::transport_msg()
assert( sizeof(ModbusMessage) >= (unsigned int)szModbusHeader + szData() );
// копируем заголовок и данные
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
size_t ind = 0;
bcnt = count * sizeof(ModbusByte);
......@@ -3240,14 +3292,14 @@ ModbusMessage RemoteServiceRetMessage::transport_msg()
ind += bcnt;
// пересчитываем CRC по данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + ind );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + ind );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = ind;
mm.dlen = ind;
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -3269,12 +3321,12 @@ bool ReadFileRecordMessage::checkFormat()
// -------------------------------------------------------------------------
void ReadFileRecordMessage::init( const ModbusMessage& m )
{
assert( m.func == fnReadFileRecord );
assert( m.pduhead.func == fnReadFileRecord );
memset(this, 0, sizeof(*this));
// copy not include CRC
memcpy(this, &m, szModbusHeader + m.len);
memcpy(this, &m.pduhead, szModbusHeader + m.dlen);
// потом проверяем
if( !checkFormat() )
......@@ -3288,7 +3340,7 @@ void ReadFileRecordMessage::init( const ModbusMessage& m )
}
// последний элемент это CRC
memcpy(&crc, &(m.data[m.len - szCRC]), szCRC);
memcpy(&crc, &(m.data[m.dlen - szCRC]), szCRC);
count = bcnt / sizeof(SubRequest);
......@@ -3308,7 +3360,7 @@ size_t ReadFileRecordMessage::szData()
// -------------------------------------------------------------------------
size_t ReadFileRecordMessage::getDataLen( const ModbusMessage& m )
{
if( m.len == 0 )
if( m.dlen == 0 )
return 0;
return (size_t)(m.data[0]);
......@@ -3337,7 +3389,7 @@ ModbusMessage FileTransferMessage::transport_msg()
ModbusMessage mm;
// копируем заголовок
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
// копируем данные (переворачиваем байты)
ModbusData d[2] = { SWAPSHORT(numfile), SWAPSHORT(numpacket) };
......@@ -3345,13 +3397,13 @@ ModbusMessage FileTransferMessage::transport_msg()
memcpy(mm.data, &d, last);
// пересчитываем CRC по перевёрнутым данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + sizeof(d) );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + sizeof(d) );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[last]), &crc, szCRC);
// длина сообщения...
mm.len = szData();
mm.dlen = szData();
return std::move(mm);
}
// -------------------------------------------------------------------------
......@@ -3368,15 +3420,15 @@ FileTransferMessage& FileTransferMessage::operator=( const ModbusMessage& m )
// -----------------------------------------------------------------------
void FileTransferMessage::init( const ModbusMessage& m )
{
assert( m.func == fnFileTransfer );
assert( m.pduhead.func == fnFileTransfer );
memset(this, 0, sizeof(*this));
// copy not include CRC
memcpy(this, &m, szModbusHeader + m.len);
memcpy(this, &m.pduhead, szModbusHeader + m.dlen);
// последний элемент это CRC
memcpy(&crc, &(m.data[m.len - szCRC]), szCRC);
memcpy(&crc, &(m.data[m.dlen - szCRC]), szCRC);
numfile = SWAPSHORT(numfile);
numpacket = SWAPSHORT(numpacket);
......@@ -3407,11 +3459,11 @@ FileTransferRetMessage& FileTransferRetMessage::operator=( const ModbusMessage&
// -----------------------------------------------------------------------
void FileTransferRetMessage::init( const ModbusMessage& m )
{
assert( m.func == fnFileTransfer );
assert( m.pduhead.func == fnFileTransfer );
memset(this, 0, sizeof(*this));
// copy header
memcpy(this, &m, szModbusHeader);
memcpy(this, &m.pduhead, szModbusHeader);
bcnt = m.data[0];
memcpy(&numfile, &(m.data[1]), sizeof(ModbusData));
......@@ -3480,7 +3532,7 @@ ModbusMessage FileTransferRetMessage::transport_msg()
assert( sizeof(ModbusMessage) >= (unsigned int)(szModbusHeader + szData()) );
// копируем заголовок и данные
memcpy(&mm, this, szModbusHeader);
memcpy(&mm.pduhead, this, szModbusHeader);
size_t ind = 0;
bcnt = szData() - szCRC - 1; // -1 - это сам байт содержащий количество байт (bcnt)...
......@@ -3506,14 +3558,14 @@ ModbusMessage FileTransferRetMessage::transport_msg()
ind += dlen;
// пересчитываем CRC по данным
ModbusData crc = checkCRC( (ModbusByte*)(&mm), szModbusHeader + ind );
ModbusData crc = checkCRC( (ModbusByte*)(&mm.pduhead), szModbusHeader + ind );
// копируем CRC (последний элемент). Без переворачивания...
memcpy(&(mm.data[ind]), &crc, szCRC);
ind += szCRC;
// длина сообщения...
mm.len = ind;
mm.dlen = ind;
return std::move(mm);
}
// -----------------------------------------------------------------------
......@@ -3527,12 +3579,12 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, FileTransferRetMessage* m
return mbPrintMessage(os, (ModbusByte*)m, szModbusHeader + m->szData() );
}
// -----------------------------------------------------------------------
std::ostream& ModbusTCP::operator<<(std::ostream& os, const MBAPHeader& m )
std::ostream& ModbusRTU::operator<<(std::ostream& os, const ModbusRTU::ADUHeader& m )
{
return mbPrintMessage(os, (ModbusByte*)(&m), sizeof(m));
}
// -----------------------------------------------------------------------
void ModbusTCP::MBAPHeader::swapdata()
void ModbusRTU::ADUHeader::swapdata()
{
tID = SWAPSHORT(tID);
pID = SWAPSHORT(pID);
......@@ -3579,11 +3631,3 @@ ModbusRTU::RegID ModbusRTU::genRegID( const ModbusRTU::ModbusData mbreg, const i
return max + mbreg + max + UniSetTypes::lcalibrate(fn, 0, fn_max, 0, max, false);
}
// -----------------------------------------------------------------------
ostream& ModbusTCP::operator<<( ostream& os, const ModbusTCP::ADU& m )
{
os << m.header << "| ";
mbPrintMessage(os, (ModbusByte*)&(m.pdu), szModbusHeader+m.pdu.len);
//return os << m.header << "| " << m.pdu;
return os;
}
// -----------------------------------------------------------------------
......@@ -438,6 +438,7 @@ tests/UniXmlTest/XmlTest.cc
tests/int_unsigned.cc
tests/Makefile.am
tests/test.xml
tests/develop.cc
tests/test_callbacktimer.cc
tests/test_conftest.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