UniSet  2.6.0
ModbusTypes.h
00001 // -------------------------------------------------------------------------
00002 #ifndef ModbusTypes_H_
00003 #define ModbusTypes_H_
00004 // -------------------------------------------------------------------------
00005 #include <ostream>
00006 #include <bitset>
00007 #include <string>
00008 #include <list>
00009 #include "ModbusRTUErrors.h"
00010 // -------------------------------------------------------------------------
00011 /* Основные предположения:
00012  * - младший и старший байт переворачиваются только в CRC
00013  * - В случае неправильного формата пакета(запроса), логической ошибки и т.п
00014  *         ОТВЕТ просто не посылается, а пакет отбрасывается...
00015  * - CRC считается по всей посылке (с начальным адресом)
00016  * - CRC инициализируется значением 0xffff
00017  * - CRC не переворачивается
00018  * - Все двухбайтовые слова переворачиваются. Порядок байт: старший младший
00019 */
00020 // -------------------------------------------------------------------------
00021 namespace uniset
00022 {
00023 // -------------------------------------------------------------------------
00024 namespace ModbusRTU
00025 {
00026 // Базовые типы
00027 typedef uint8_t ModbusByte;    
00028 const size_t BitsPerByte = 8;
00029 typedef uint8_t ModbusAddr;    
00030 typedef uint16_t ModbusData;    
00031 const size_t BitsPerData = 16;
00032 typedef uint16_t ModbusCRC;    
00034 // ---------------------------------------------------------------------
00036 enum SlaveFunctionCode
00037 {
00038     fnUnknown                = 0x00,
00039     fnReadCoilStatus         = 0x01, 
00040     fnReadInputStatus        = 0x02, 
00041     fnReadOutputRegisters    = 0x03, 
00042     fnReadInputRegisters     = 0x04, 
00043     fnForceSingleCoil        = 0x05, 
00044     fnWriteOutputSingleRegister = 0x06,    
00045     fnDiagnostics            = 0x08, 
00046     fnForceMultipleCoils     = 0x0F,    
00047     fnWriteOutputRegisters   = 0x10,    
00048     fnReadFileRecord         = 0x14,    
00049     fnWriteFileRecord        = 0x15,    
00050     fnMEI                    = 0x2B, 
00051     fnSetDateTime            = 0x50, 
00052     fnRemoteService          = 0x53,    
00053     fnJournalCommand         = 0x65,    
00054     fnFileTransfer           = 0x66    
00055 };
00056 
00058 enum DiagnosticsSubFunction
00059 {
00060     subEcho = 0x00,          
00061     dgRestartComm = 0x01,    
00062     dgDiagReg = 0x02,        
00063     dgChangeASCII = 0x03,    
00064     dgForceListen = 0x04,    
00065     // 05.. 09 RESERVED
00066     dgClearCounters = 0x0A,  
00067     dgBusMsgCount = 0x0B,    
00068     dgBusErrCount = 0x0C,    
00069     dgBusExceptCount = 0x0D, 
00070     dgMsgSlaveCount = 0x0E,        
00071     dgNoNoResponseCount = 0x0F,    
00072     dgSlaveNAKCount = 0x10,        
00073     dgSlaveBusyCount = 0x11,       
00074     dgBusCharOverrunCount = 0x12,  
00075     // = 0x13,    /*!<  RESERVED */
00076     dgClearOverrunCounter = 0x14   
00077                             // 21 ...65535 RESERVED
00078 };
00079 
00080 
00081 typedef unsigned long RegID;
00082 
00089 RegID genRegID( const ModbusRTU::ModbusData r, const int fn );
00090 
00091 // определение размера данных в зависимости от типа сообщения
00092 // возвращает -1 - если динамический размер сообщения или размер неизвестен
00093 ssize_t szRequestDiagnosticData( DiagnosticsSubFunction f );
00094 
00096 enum RDIObjectID
00097 {
00098     rdiVendorName = 0x0,
00099     rdiProductCode = 0x1,
00100     rdiMajorMinorRevision = 0x2,
00101     rdiVendorURL = 0x3,
00102     rdiProductName = 0x4,
00103     rdiModelName = 0x5,
00104     rdiUserApplicationName = 0x6
00105                              // 0x07 .. 0x7F - reserved
00106                              // 0x80 .. 0xFF - optionaly defined (product dependant)
00107 };
00108 
00110 enum RDIRequestDeviceID
00111 {
00112     rdevMinNum = 0,
00113     rdevBasicDevice = 0x1,   // request to get the basic device identification (stream access)
00114     rdevRegularDevice = 0x2, // request to get the regular device identification (stream access)
00115     rdevExtentedDevice = 0x3, // request to get the extended device identification (stream access)
00116     rdevSpecificDevice = 0x4, // request to get the extended device identification (stream access)
00117     rdevMaxNum = 0x5
00118 };
00119 
00120 std::string rdi2str( int id );
00121 // -----------------------------------------------------------------------
00122 
00124 enum
00125 {
00127     MAXLENPACKET     = 508, 
00128     BroadcastAddr    = 255, 
00129     MAXPDULEN       = 253, // 255 - 2(CRC)
00130     MAXDATALEN       = 125  
00134 };
00135 
00136 const unsigned char MBErrMask = 0x80;
00137 // ---------------------------------------------------------------------
00138 uint16_t SWAPSHORT( uint16_t x );
00139 // ---------------------------------------------------------------------
00141 ModbusCRC checkCRC( ModbusByte* start, size_t len );
00142 const size_t szCRC = sizeof(ModbusCRC); 
00143 // ---------------------------------------------------------------------
00145 std::ostream& mbPrintMessage(std::ostream& os, ModbusByte* b, size_t len );
00146 // -------------------------------------------------------------------------
00147 ModbusAddr str2mbAddr( const std::string& val );
00148 ModbusData str2mbData( const std::string& val );
00149 std::string dat2str( const ModbusData dat );
00150 std::string addr2str( const ModbusAddr addr );
00151 std::string b2str( const ModbusByte b );
00152 // -------------------------------------------------------------------------
00153 float dat2f( const ModbusData dat1, const ModbusData dat2 );
00154 // -------------------------------------------------------------------------
00155 bool isWriteFunction( SlaveFunctionCode c );
00156 bool isReadFunction( SlaveFunctionCode c );
00157 // -------------------------------------------------------------------------
00159 struct ModbusHeader
00160 {
00161     ModbusAddr addr;        
00162     ModbusByte func;        
00164     ModbusHeader(): addr(0), func(0) {}
00165 } __attribute__((packed));
00166 
00167 const size_t szModbusHeader = sizeof(ModbusHeader);
00168 
00169 std::ostream& operator<<(std::ostream& os, const ModbusHeader& m );
00170 std::ostream& operator<<(std::ostream& os, const ModbusHeader* m );
00171 // -----------------------------------------------------------------------
00172 struct ADUHeader
00173 {
00174     ModbusRTU::ModbusData tID; 
00175     ModbusRTU::ModbusData pID; 
00176     ModbusRTU::ModbusData len; 
00178     ADUHeader(): tID(0), pID(0), len(0) {}
00179 
00180     void swapdata();
00181 
00182 } __attribute__((packed));
00183 
00184 std::ostream& operator<<(std::ostream& os, const ADUHeader& m );
00185 // -----------------------------------------------------------------------
00186 
00190 struct ModbusMessage
00191 {
00192     ModbusMessage();
00193 
00194     ModbusMessage( ModbusMessage&& ) = default;
00195     ModbusMessage& operator=(ModbusMessage&& ) = default;
00196     ModbusMessage( const ModbusMessage& ) = default;
00197     ModbusMessage& operator=(const ModbusMessage& ) = default;
00198 
00199     inline ModbusByte func() const
00200     {
00201         return pduhead.func;
00202     }
00203     inline ModbusAddr addr() const
00204     {
00205         return pduhead.addr;
00206     }
00207     inline ModbusRTU::ModbusData tID() const
00208     {
00209         return aduhead.tID;
00210     }
00211     inline ModbusRTU::ModbusData pID() const
00212     {
00213         return aduhead.pID;
00214     }
00215     inline ModbusRTU::ModbusData aduLen() const
00216     {
00217         return aduhead.len;
00218     }
00219 
00220     unsigned char* buf();
00221     ModbusRTU::ModbusData len() const;
00222     void swapHead();
00223     void makeHead( ModbusRTU::ModbusData tID, bool noCRC = true, ModbusRTU::ModbusData pID = 0 );
00224 
00225     ModbusRTU::ModbusData pduLen() const;
00226     ModbusCRC pduCRC( size_t len ) const;
00227     static size_t maxSizeOfMessage();
00228 
00229     void clear();
00230 
00231     ADUHeader aduhead;
00232     ModbusHeader pduhead;
00233     ModbusByte data[MAXLENPACKET + szCRC];   
00235     // Это поле вспомогательное и игнорируется при пересылке
00236     size_t dlen = { 0 };  
00237 } __attribute__((packed));
00238 
00239 std::ostream& operator<<(std::ostream& os, const ModbusMessage& m );
00240 std::ostream& operator<<(std::ostream& os, const ModbusMessage* m );
00241 // -----------------------------------------------------------------------
00243 struct ErrorRetMessage:
00244     public ModbusHeader
00245 {
00246     ModbusByte ecode = { erNoError };
00247     ModbusCRC crc = { 0 };
00248 
00249     // ------- from slave -------
00250     ErrorRetMessage( const ModbusMessage& m );
00251     ErrorRetMessage& operator=( const ModbusMessage& m );
00252     void init( const ModbusMessage& m );
00253 
00254     // ------- to master -------
00255     ErrorRetMessage( ModbusAddr _from, ModbusByte _func, ModbusByte ecode );
00256 
00258     ModbusMessage transport_msg();
00259 
00263     inline static size_t szData()
00264     {
00265         return sizeof(ModbusByte) + szCRC;
00266     }
00267 };
00268 
00269 std::ostream& operator<<(std::ostream& os, ErrorRetMessage& m );
00270 std::ostream& operator<<(std::ostream& os, ErrorRetMessage* m );
00271 // -----------------------------------------------------------------------
00272 struct DataBits
00273 {
00274     DataBits( ModbusByte b );
00275     DataBits( std::string s ); // example "10001111"
00276     DataBits();
00277 
00278     const DataBits& operator=(const ModbusByte& r);
00279 
00280     operator ModbusByte();
00281     ModbusByte mbyte();
00282 
00283     bool operator[]( const size_t i )
00284     {
00285         return b[i];
00286     }
00287     void set( int n, bool s )
00288     {
00289         b.set(n, s);
00290     }
00291 
00292     std::bitset<BitsPerByte> b;
00293 };
00294 
00295 std::ostream& operator<<(std::ostream& os, DataBits& m );
00296 std::ostream& operator<<(std::ostream& os, DataBits* m );
00297 // -----------------------------------------------------------------------
00298 struct DataBits16
00299 {
00300     DataBits16( ModbusData d );
00301     DataBits16( const std::string& s ); // example "1000111110001111"
00302     DataBits16();
00303 
00304     const DataBits16& operator=(const ModbusData& r);
00305 
00306     operator ModbusData();
00307     ModbusData mdata() const;
00308 
00309     bool operator[]( const size_t i )
00310     {
00311         return b[i];
00312     }
00313     void set( int n, bool s )
00314     {
00315         b.set(n, s);
00316     }
00317 
00318     std::bitset<BitsPerData> b;
00319 };
00320 
00321 std::ostream& operator<<(std::ostream& os, DataBits16& m );
00322 std::ostream& operator<<(std::ostream& os, DataBits16* m );
00323 // -----------------------------------------------------------------------
00325 struct ReadCoilMessage:
00326     public ModbusHeader
00327 {
00328     ModbusData start = { 0 };
00329     ModbusData count = { 0 };
00330     ModbusCRC crc = { 0 };
00331 
00332     // ------- to slave -------
00333     ReadCoilMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00335     ModbusMessage transport_msg();
00336 
00337     // ------- from master -------
00338     ReadCoilMessage( const ModbusMessage& m );
00339     ReadCoilMessage& operator=( const ModbusMessage& m );
00340     void init( const ModbusMessage& m );
00341 
00343     inline static size_t szData()
00344     {
00345         return sizeof(ModbusData) * 2 + szCRC;
00346     }
00347 
00348 } __attribute__((packed));
00349 
00350 std::ostream& operator<<(std::ostream& os, ReadCoilMessage& m );
00351 std::ostream& operator<<(std::ostream& os, ReadCoilMessage* m );
00352 
00353 // -----------------------------------------------------------------------
00354 
00356 struct ReadCoilRetMessage:
00357     public ModbusHeader
00358 {
00359     ModbusByte bcnt = { 0 };          
00360     ModbusByte data[MAXLENPACKET];    
00362     // ------- from slave -------
00363     ReadCoilRetMessage( const ModbusMessage& m );
00364     ReadCoilRetMessage& operator=( const ModbusMessage& m );
00365     void init( const ModbusMessage& m );
00366 
00370     static inline int szHead()
00371     {
00372         return sizeof(ModbusByte); // bcnt
00373     }
00374 
00376     static size_t getDataLen( const ModbusMessage& m );
00377     ModbusCRC crc = { 0 };
00378 
00379     // ------- to master -------
00380     ReadCoilRetMessage( ModbusAddr _from );
00381 
00386     bool addData( DataBits d );
00387 
00395     bool setBit( unsigned char dnum, unsigned char bnum, bool state );
00396 
00403     bool getData( unsigned char bnum, DataBits& d ) const;
00404 
00406     void clear();
00407 
00409     inline bool isFull() const
00410     {
00411         return ( (int)bcnt >= MAXPDULEN );
00412     }
00413 
00415     size_t szData() const;
00416 
00418     ModbusMessage transport_msg();
00419 };
00420 
00421 std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage& m );
00422 std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage* m );
00423 // -----------------------------------------------------------------------
00425 struct ReadInputStatusMessage:
00426     public ModbusHeader
00427 {
00428     ModbusData start = { 0 };
00429     ModbusData count = { 0 };
00430     ModbusCRC crc = { 0 };
00431 
00432     // ------- to slave -------
00433     ReadInputStatusMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00434 
00436     ModbusMessage transport_msg();
00437 
00438     // ------- from master -------
00439     ReadInputStatusMessage( const ModbusMessage& m );
00440     ReadInputStatusMessage& operator=( const ModbusMessage& m );
00441 
00442     void init( const ModbusMessage& m );
00443 
00445     inline static size_t szData()
00446     {
00447         return sizeof(ModbusData) * 2 + szCRC;
00448     }
00449 
00450 } __attribute__((packed));
00451 
00452 std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage& m );
00453 std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage* m );
00454 // -----------------------------------------------------------------------
00456 struct ReadInputStatusRetMessage:
00457     public ModbusHeader
00458 {
00459     ModbusByte bcnt = { 0 };          
00460     ModbusByte data[MAXLENPACKET];    
00462     // ------- from slave -------
00463     ReadInputStatusRetMessage( const ModbusMessage& m );
00464     ReadInputStatusRetMessage& operator=( const ModbusMessage& m );
00465     void init( const ModbusMessage& m );
00466 
00470     static inline size_t szHead()
00471     {
00472         return sizeof(ModbusByte); // bcnt
00473     }
00474 
00476     static size_t getDataLen( const ModbusMessage& m );
00477     ModbusCRC crc = { 0 };
00478 
00479     // ------- to master -------
00480     ReadInputStatusRetMessage( ModbusAddr _from );
00481 
00486     bool addData( DataBits d );
00487 
00495     bool setBit( unsigned char dnum, unsigned char bnum, bool state );
00496 
00503     bool getData( unsigned char dnum, DataBits& d ) const;
00504 
00506     void clear();
00507 
00509     inline bool isFull() const
00510     {
00511         return ( (int)bcnt >= MAXPDULEN );
00512     }
00513 
00515     size_t szData() const;
00516 
00518     ModbusMessage transport_msg();
00519 };
00520 
00521 std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage& m );
00522 std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage* m );
00523 // -----------------------------------------------------------------------
00524 
00526 struct ReadOutputMessage:
00527     public ModbusHeader
00528 {
00529     ModbusData start = { 0 };
00530     ModbusData count = { 0 };
00531     ModbusCRC crc = { 0 };
00532 
00533     // ------- to slave -------
00534     ReadOutputMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00536     ModbusMessage transport_msg();
00537 
00538     // ------- from master -------
00539     ReadOutputMessage( const ModbusMessage& m );
00540     ReadOutputMessage& operator=( const ModbusMessage& m );
00541     void init( const ModbusMessage& m );
00542 
00544     inline static size_t szData()
00545     {
00546         return sizeof(ModbusData) * 2 + szCRC;
00547     }
00548 
00549 } __attribute__((packed));
00550 
00551 std::ostream& operator<<(std::ostream& os, ReadOutputMessage& m );
00552 std::ostream& operator<<(std::ostream& os, ReadOutputMessage* m );
00553 // -----------------------------------------------------------------------
00555 struct ReadOutputRetMessage:
00556     public ModbusHeader
00557 {
00558     ModbusByte bcnt = { 0 };                             
00559     ModbusData data[MAXLENPACKET / sizeof(ModbusData)];  
00561     // ------- from slave -------
00562     ReadOutputRetMessage( const ModbusMessage& m );
00563     ReadOutputRetMessage& operator=( const ModbusMessage& m );
00564     void init( const ModbusMessage& m );
00568     static inline size_t szHead()
00569     {
00570         // bcnt
00571         return sizeof(ModbusByte);
00572     }
00573 
00575     static size_t getDataLen( const ModbusMessage& m );
00576     ModbusCRC crc = { 0 };
00577 
00578     // ------- to master -------
00579     ReadOutputRetMessage( ModbusAddr _from );
00580 
00585     bool addData( ModbusData d );
00586 
00588     void clear();
00589 
00591     inline bool isFull() const
00592     {
00593         return ( count * sizeof(ModbusData) >= MAXLENPACKET );
00594     }
00595 
00597     size_t szData() const;
00598 
00600     ModbusMessage transport_msg();
00601 
00602     // Это поле не входит в стандарт modbus
00603     // оно вспомогательное и игнорируется при
00604     // преобразовании в ModbusMessage.
00605     // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
00606     // Используйте специальную функцию transport_msg()
00607     size_t count = { 0 };    
00608 };
00609 
00610 std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage& m );
00611 std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage* m );
00612 // -----------------------------------------------------------------------
00614 struct ReadInputMessage:
00615     public ModbusHeader
00616 {
00617     ModbusData start = { 0 };
00618     ModbusData count = { 0 };
00619     ModbusCRC crc = { 0 };
00620 
00621     // ------- to slave -------
00622     ReadInputMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00624     ModbusMessage transport_msg();
00625 
00626     // ------- from master -------
00627     ReadInputMessage( const ModbusMessage& m );
00628     ReadInputMessage& operator=( const ModbusMessage& m );
00629     void init( const ModbusMessage& m );
00630 
00632     inline static size_t szData()
00633     {
00634         return sizeof(ModbusData) * 2 + szCRC;
00635     }
00636 
00637 } __attribute__((packed));
00638 
00639 std::ostream& operator<<(std::ostream& os, ReadInputMessage& m );
00640 std::ostream& operator<<(std::ostream& os, ReadInputMessage* m );
00641 // -----------------------------------------------------------------------
00642 
00644 struct ReadInputRetMessage:
00645     public ModbusHeader
00646 {
00647     ModbusByte bcnt = { 0 };                                    
00648     ModbusData data[MAXLENPACKET / sizeof(ModbusData)];  
00650     // ------- from slave -------
00651     ReadInputRetMessage( const ModbusMessage& m );
00652     ReadInputRetMessage& operator=( const ModbusMessage& m );
00653     void init( const ModbusMessage& m );
00657     static inline size_t szHead()
00658     {
00659         // bcnt
00660         return sizeof(ModbusByte);
00661     }
00662 
00664     static size_t getDataLen( const ModbusMessage& m );
00665     ModbusCRC crc = { 0 };
00666 
00667     // ------- to master -------
00668     ReadInputRetMessage( ModbusAddr _from );
00669 
00674     bool addData( ModbusData d );
00675 
00677     void clear();
00678 
00680     inline bool isFull() const
00681     {
00682         return ( count * sizeof(ModbusData) >= MAXLENPACKET );
00683     }
00684 
00685     void swapData();
00686 
00688     size_t szData();
00689 
00691     ModbusMessage transport_msg();
00692 
00693     // Это поле не входит в стандарт modbus
00694     // оно вспомогательное и игнорируется при
00695     // преобразовании в ModbusMessage.
00696     // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
00697     // Используйте специальную функцию transport_msg()
00698     size_t count = { 0 };    
00699 };
00700 
00701 std::ostream& operator<<(std::ostream& os, ReadInputRetMessage& m );
00702 std::ostream& operator<<(std::ostream& os, ReadInputRetMessage* m );
00703 // -----------------------------------------------------------------------
00705 struct ForceCoilsMessage:
00706     public ModbusHeader
00707 {
00708     ModbusData start = { 0 };    
00709     ModbusData quant = { 0 };    
00710     ModbusByte bcnt = { 0 };    
00712     ModbusByte data[MAXLENPACKET - sizeof(ModbusData) * 2 - sizeof(ModbusByte)];
00713     ModbusCRC crc = { 0 };        
00715     // ------- to slave -------
00716     ForceCoilsMessage( ModbusAddr addr, ModbusData start );
00718     ModbusMessage transport_msg();
00719 
00724     bool addData( DataBits d );
00725 
00726     // return number of bit
00727     // -1 - error
00728     int addBit( bool state );
00729 
00730     bool setBit( int nbit, bool state );
00731 
00732     inline size_t last() const
00733     {
00734         return quant;
00735     }
00736 
00743     bool getData( unsigned char dnum, DataBits& d );
00744 
00745     bool getBit( unsigned char bnum );
00746 
00747     void clear();
00748     inline bool isFull() const
00749     {
00750         return ( (int)bcnt >= MAXPDULEN );
00751     }
00752 
00753     // ------- from master -------
00754     ForceCoilsMessage( const ModbusMessage& m );
00755     ForceCoilsMessage& operator=( const ModbusMessage& m );
00756     void init( const ModbusMessage& m );
00757 
00759     size_t szData() const;
00760 
00764     static inline size_t szHead()
00765     {
00766         // start + quant + count
00767         return sizeof(ModbusData) * 2 + sizeof(ModbusByte);
00768     }
00769 
00771     static size_t getDataLen( const ModbusMessage& m );
00772 
00776     bool checkFormat() const;
00777 
00778 } __attribute__((packed));
00779 
00780 std::ostream& operator<<(std::ostream& os, ForceCoilsMessage& m );
00781 std::ostream& operator<<(std::ostream& os, ForceCoilsMessage* m );
00782 // -----------------------------------------------------------------------
00784 struct ForceCoilsRetMessage:
00785     public ModbusHeader
00786 {
00787     ModbusData start = { 0 };    
00788     ModbusData quant = { 0 };    
00789     ModbusCRC crc = { 0 };
00790 
00791     // ------- from slave -------
00792     ForceCoilsRetMessage( const ModbusMessage& m );
00793     ForceCoilsRetMessage& operator=( const ModbusMessage& m );
00794     void init( const ModbusMessage& m );
00795 
00796     // ------- to master -------
00802     ForceCoilsRetMessage( ModbusAddr _from, ModbusData start = 0, ModbusData quant = 0 );
00803 
00805     void set( ModbusData start, ModbusData quant );
00806 
00808     ModbusMessage transport_msg();
00809 
00813     inline static size_t szData()
00814     {
00815         return sizeof(ModbusData) * 2 + sizeof(ModbusCRC);
00816     }
00817 };
00818 
00819 std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage& m );
00820 std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage* m );
00821 // -----------------------------------------------------------------------
00822 
00824 struct WriteOutputMessage:
00825     public ModbusHeader
00826 {
00827     ModbusData start = { 0 };    
00828     ModbusData quant = { 0 };    
00829     ModbusByte bcnt = { 0 };    
00831     ModbusData data[MAXLENPACKET / sizeof(ModbusData) - sizeof(ModbusData) * 2 - sizeof(ModbusByte)];
00832     ModbusCRC crc = { 0 };        
00834     // ------- to slave -------
00835     WriteOutputMessage( ModbusAddr addr, ModbusData start );
00837     ModbusMessage transport_msg();
00838 
00839     bool addData( ModbusData d );
00840     void clear();
00841     inline bool isFull() const
00842     {
00843         return ( quant >= MAXDATALEN );
00844     }
00845 
00846     // ------- from master -------
00847     WriteOutputMessage( const ModbusMessage& m );
00848     WriteOutputMessage& operator=( const ModbusMessage& m );
00849     void init( const ModbusMessage& m );
00850 
00852     size_t szData() const;
00853 
00857     static inline size_t szHead()
00858     {
00859         // start + quant + count
00860         return sizeof(ModbusData) * 2 + sizeof(ModbusByte);
00861     }
00862 
00864     static size_t getDataLen( const ModbusMessage& m );
00865 
00869     bool checkFormat() const;
00870 
00871 } __attribute__((packed));
00872 
00873 
00874 std::ostream& operator<<(std::ostream& os, WriteOutputMessage& m );
00875 std::ostream& operator<<(std::ostream& os, WriteOutputMessage* m );
00876 
00878 struct WriteOutputRetMessage:
00879     public ModbusHeader
00880 {
00881     ModbusData start = { 0 };     
00882     ModbusData quant = { 0 };    
00884     // ------- from slave -------
00885     WriteOutputRetMessage( const ModbusMessage& m );
00886     WriteOutputRetMessage& operator=( const ModbusMessage& m );
00887     void init( const ModbusMessage& m );
00888     ModbusCRC crc = { 0 };
00889 
00890     // ------- to master -------
00896     WriteOutputRetMessage( ModbusAddr _from, ModbusData start = 0, ModbusData quant = 0 );
00897 
00899     void set( ModbusData start, ModbusData quant );
00900 
00902     ModbusMessage transport_msg();
00903 
00907     inline static size_t szData()
00908     {
00909         return sizeof(ModbusData) * 2 + sizeof(ModbusCRC);
00910     }
00911 };
00912 
00913 std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage& m );
00914 std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage* m );
00915 // -----------------------------------------------------------------------
00917 struct ForceSingleCoilMessage:
00918     public ModbusHeader
00919 {
00920     ModbusData start = { 0 };   
00921     ModbusData data = { 0 };    
00922     ModbusCRC crc = { 0 };      
00925     inline bool cmd()
00926     {
00927         return (data & 0xFF00);
00928     }
00929 
00930     // ------- to slave -------
00931     ForceSingleCoilMessage( ModbusAddr addr, ModbusData reg, bool state );
00933     ModbusMessage transport_msg();
00934 
00935     // ------- from master -------
00936     ForceSingleCoilMessage( const ModbusMessage& m );
00937     ForceSingleCoilMessage& operator=( const ModbusMessage& m );
00938     void init( const ModbusMessage& m );
00939 
00941     size_t szData() const;
00942 
00946     static inline size_t szHead()
00947     {
00948         return sizeof(ModbusData);
00949     }
00950 
00954     static size_t getDataLen( const ModbusMessage& m );
00955 
00959     bool checkFormat() const;
00960 } __attribute__((packed));
00961 
00962 
00963 std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage& m );
00964 std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage* m );
00965 // -----------------------------------------------------------------------
00966 
00968 struct ForceSingleCoilRetMessage:
00969     public ModbusHeader
00970 {
00971     ModbusData start = { 0 };     
00972     ModbusData data = { 0 };     
00973     ModbusCRC crc = { 0 };
00974 
00976     inline bool cmd() const
00977     {
00978         return (data & 0xFF00);
00979     }
00980 
00981     // ------- from slave -------
00982     ForceSingleCoilRetMessage( const ModbusMessage& m );
00983     ForceSingleCoilRetMessage& operator=( const ModbusMessage& m );
00984     void init( const ModbusMessage& m );
00985 
00986     // ------- to master -------
00991     ForceSingleCoilRetMessage( ModbusAddr _from );
00992 
00994     void set( ModbusData start, bool cmd );
00995 
00997     ModbusMessage transport_msg();
00998 
01002     inline static size_t szData()
01003     {
01004         return 2 * sizeof(ModbusData) + sizeof(ModbusCRC);
01005     }
01006 };
01007 
01008 std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage& m );
01009 std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage* m );
01010 // -----------------------------------------------------------------------
01011 
01013 struct WriteSingleOutputMessage:
01014     public ModbusHeader
01015 {
01016     ModbusData start = { 0 };    
01017     ModbusData data = { 0 };    
01018     ModbusCRC crc = { 0 };        
01021     // ------- to slave -------
01022     WriteSingleOutputMessage( ModbusAddr addr, ModbusData reg = 0, ModbusData data = 0 );
01024     ModbusMessage transport_msg();
01025 
01026     // ------- from master -------
01027     WriteSingleOutputMessage( const ModbusMessage& m );
01028     WriteSingleOutputMessage& operator=( const ModbusMessage& m );
01029     void init( const ModbusMessage& m );
01030 
01032     size_t szData() const;
01033 
01037     static inline size_t szHead()
01038     {
01039         return sizeof(ModbusData);
01040     }
01041 
01045     static size_t getDataLen( const ModbusMessage& m );
01046 
01050     bool checkFormat();
01051 } __attribute__((packed));
01052 
01053 
01054 std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage& m );
01055 std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage* m );
01056 // -----------------------------------------------------------------------
01057 
01059 struct WriteSingleOutputRetMessage:
01060     public ModbusHeader
01061 {
01062     ModbusData start = { 0 };     
01063     ModbusData data = { 0 };     
01064     ModbusCRC crc = { 0 };
01065 
01066 
01067     // ------- from slave -------
01068     WriteSingleOutputRetMessage( const ModbusMessage& m );
01069     WriteSingleOutputRetMessage& operator=( const ModbusMessage& m );
01070     void init( const ModbusMessage& m );
01071 
01072     // ------- to master -------
01077     WriteSingleOutputRetMessage( ModbusAddr _from, ModbusData start = 0 );
01078 
01080     void set( ModbusData start, ModbusData data );
01081 
01083     ModbusMessage transport_msg();
01084 
01088     inline static size_t szData()
01089     {
01090         return 2 * sizeof(ModbusData) + sizeof(ModbusCRC);
01091     }
01092 };
01093 
01094 std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage& m );
01095 std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage* m );
01096 // -----------------------------------------------------------------------
01098 struct DiagnosticMessage:
01099     public ModbusHeader
01100 {
01101     ModbusData subf = { 0 };
01102     ModbusData data[MAXLENPACKET / sizeof(ModbusData)];  
01104     // ------- from slave -------
01105     DiagnosticMessage( const ModbusMessage& m );
01106     DiagnosticMessage& operator=( const ModbusMessage& m );
01107     void init( const ModbusMessage& m );
01111     static inline size_t szHead()
01112     {
01113         return sizeof(ModbusData); // subf
01114     }
01115 
01117     static size_t getDataLen( const ModbusMessage& m );
01118     ModbusCRC crc = { 0 };
01119 
01120     // ------- to master -------
01121     DiagnosticMessage( ModbusAddr _from, DiagnosticsSubFunction subf, ModbusData d = 0 );
01122 
01127     bool addData( ModbusData d );
01128 
01130     void clear();
01131 
01133     inline bool isFull() const
01134     {
01135         // (1)subf + data count
01136         return ( 1 + count >= MAXDATALEN );
01137     }
01138 
01140     size_t szData() const;
01141 
01143     ModbusMessage transport_msg();
01144 
01145     // Это поле не входит в стандарт modbus
01146     // оно вспомогательное и игнорируется при
01147     // преобразовании в ModbusMessage.
01148     // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
01149     // Используйте специальную функцию transport_msg()
01150     size_t count = { 0 };    
01151 };
01152 std::ostream& operator<<(std::ostream& os, DiagnosticMessage& m );
01153 std::ostream& operator<<(std::ostream& os, DiagnosticMessage* m );
01154 // -----------------------------------------------------------------------
01156 struct DiagnosticRetMessage:
01157     public DiagnosticMessage
01158 {
01159     DiagnosticRetMessage( const ModbusMessage& m );
01160     DiagnosticRetMessage( const DiagnosticMessage& m );
01161     DiagnosticRetMessage( ModbusAddr a, DiagnosticsSubFunction subf, ModbusData d = 0 );
01162 };
01163 
01164 std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage& m );
01165 std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage* m );
01166 // -----------------------------------------------------------------------
01168 struct MEIMessageRDI:
01169     public ModbusHeader
01170 {
01171     ModbusByte type;     
01172     ModbusByte devID;     
01173     ModbusByte objID;     
01175     ModbusCRC crc = { 0 };        
01177     // ------- to slave -------
01178     MEIMessageRDI( ModbusAddr addr, ModbusByte devID, ModbusByte objID );
01180     ModbusMessage transport_msg();
01181 
01182     // ------- from master -------
01183     MEIMessageRDI( const ModbusMessage& m );
01184     MEIMessageRDI& operator=( const ModbusMessage& m );
01185     void init( const ModbusMessage& m );
01186 
01190     static inline size_t szHead()
01191     {
01192         return sizeof(ModbusByte) * 3;
01193     }
01194 
01196     static inline size_t szData()
01197     {
01198         return sizeof(ModbusByte) * 3 + szCRC;
01199     }
01200 
01201     // вспомогательные функции
01202     bool checkFormat() const;
01203 
01204 } __attribute__((packed));
01205 // -----------------------------------------------------------------------
01206 std::ostream& operator<<(std::ostream& os, MEIMessageRDI& m );
01207 std::ostream& operator<<(std::ostream& os, MEIMessageRDI* m );
01208 // -----------------------------------------------------------------------
01209 
01210 struct RDIObjectInfo
01211 {
01212     RDIObjectInfo(): id(0), val("") {}
01213     RDIObjectInfo( ModbusByte id, const std::string& v ): id(id), val(v) {}
01214     RDIObjectInfo( ModbusByte id, const ModbusByte* dat, ModbusByte len );
01215 
01216     ModbusByte id;
01217     std::string val;
01218 };
01219 
01220 typedef std::list<RDIObjectInfo> RDIObjectList;
01221 
01223 struct MEIMessageRetRDI:
01224     public ModbusHeader
01225 {
01226     ModbusByte type;     
01227     ModbusByte devID;     
01228     ModbusByte conformity; 
01229     ModbusByte mf;         
01230     ModbusByte objID;     
01231     ModbusByte objNum;     
01233     RDIObjectList dlist;
01234     ModbusCRC crc = { 0 };
01235 
01236     // ------- from slave -------
01237     MEIMessageRetRDI();
01238     MEIMessageRetRDI( const ModbusMessage& m );
01239     MEIMessageRetRDI& operator=( const ModbusMessage& m );
01240     void init( const ModbusMessage& m );
01241 
01242     // предварительная инициализации, только заголовочной части, без данных
01243     void pre_init( const ModbusMessage& m );
01244 
01246     static inline size_t szHead()
01247     {
01248         return sizeof(ModbusByte) * 6;
01249     }
01250 
01251     //        /*! узнать длину данных следующих за предварительным заголовком ( в байтах ) */
01252     //        static int getDataLen( ModbusMessage& m );
01253 
01254     // ------- to master -------
01255     MEIMessageRetRDI( ModbusAddr _from, ModbusByte devID, ModbusByte conformity, ModbusByte mf, ModbusByte objID );
01256 
01261     bool addData( ModbusByte id, const std::string& value );
01262     bool addData( RDIObjectInfo& dat );
01263 
01265     void clear();
01266 
01268     inline bool isFull() const
01269     {
01270         return ( bcnt >= MAXPDULEN );
01271     }
01272 
01274     size_t szData() const;
01275 
01277     ModbusMessage transport_msg();
01278 
01279     size_t bcnt = { 0 }; 
01280 };
01281 
01282 std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI& m );
01283 std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI* m );
01284 std::ostream& operator<<(std::ostream& os, RDIObjectList& dl );
01285 std::ostream& operator<<(std::ostream& os, RDIObjectList* dl );
01286 // -----------------------------------------------------------------------
01287 // -----------------------------------------------------------------------
01288 
01290 struct JournalCommandMessage:
01291     public ModbusHeader
01292 {
01293     ModbusData cmd = { 0 };            
01294     ModbusData num = { 0 };            
01295     ModbusCRC crc = { 0 };
01296 
01297     // -------------
01298     JournalCommandMessage( const ModbusMessage& m );
01299     JournalCommandMessage& operator=( const ModbusMessage& m );
01300 
01302     inline static size_t szData()
01303     {
01304         return sizeof(ModbusByte) * 4 + szCRC;
01305     }
01306 
01307 } __attribute__((packed));
01308 
01309 std::ostream& operator<<(std::ostream& os, JournalCommandMessage& m );
01310 std::ostream& operator<<(std::ostream& os, JournalCommandMessage* m );
01311 // -----------------------------------------------------------------------
01313 struct JournalCommandRetMessage:
01314     public ModbusHeader
01315 {
01316     ModbusByte bcnt = { 0 };                    
01317     //        ModbusByte data[MAXLENPACKET-1];    /*!< данные */
01318 
01319     // В связи со спецификой реализации ответной части (т.е. modbus master)
01320     // данные приходится делать не байтовым потоком, а "словами"
01321     // которые в свою очередь будут перевёрнуты при посылке...
01322     ModbusData data[MAXLENPACKET / sizeof(ModbusData)];  
01324     // -------------
01325     JournalCommandRetMessage( ModbusAddr _from );
01326 
01333     bool setData( ModbusByte* b, int len );
01334 
01336     void clear();
01337 
01339     inline bool isFull() const
01340     {
01341         return ( count >= MAXDATALEN );
01342     }
01343 
01345     size_t szData() const;
01346 
01348     ModbusMessage transport_msg();
01349 
01350     // Это поле не входит в стандарт modbus
01351     // оно вспомогательное и игнорируется при
01352     // преобразовании в ModbusMessage.
01353     // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
01354     // Используйте специальную функцию transport_msg()
01355     size_t count = { 0 };    
01356 };
01357 
01358 std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage& m );
01359 std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage* m );
01360 // -----------------------------------------------------------------------
01364 struct JournalCommandRetOK:
01365     public JournalCommandRetMessage
01366 {
01367     // -------------
01368     JournalCommandRetOK( ModbusAddr _from );
01369     void set( ModbusData cmd, ModbusData ecode );
01370     static void set( JournalCommandRetMessage& m, ModbusData cmd, ModbusData ecode );
01371 };
01372 
01373 std::ostream& operator<<(std::ostream& os, JournalCommandRetOK& m );
01374 std::ostream& operator<<(std::ostream& os, JournalCommandRetOK* m );
01375 // -----------------------------------------------------------------------
01376 
01378 struct SetDateTimeMessage:
01379     public ModbusHeader
01380 {
01381     ModbusByte hour = { 0 };    
01382     ModbusByte min = { 0 };        
01383     ModbusByte sec = { 0 };        
01384     ModbusByte day = { 1 };        
01385     ModbusByte mon = { 1 };        
01386     ModbusByte year = { 0 };    
01387     ModbusByte century = { 20 };    
01389     ModbusCRC crc = { 0 };
01390 
01391     // ------- to slave -------
01392     SetDateTimeMessage( ModbusAddr addr );
01394     ModbusMessage transport_msg();
01395 
01396     // ------- from master -------
01397     SetDateTimeMessage( const ModbusMessage& m );
01398     SetDateTimeMessage& operator=( const ModbusMessage& m );
01399     SetDateTimeMessage();
01400 
01401     bool checkFormat() const;
01402 
01404     inline static size_t szData()
01405     {
01406         return sizeof(ModbusByte) * 7 + szCRC;
01407     }
01408 
01409 } __attribute__((packed));
01410 
01411 std::ostream& operator<<(std::ostream& os, SetDateTimeMessage& m );
01412 std::ostream& operator<<(std::ostream& os, SetDateTimeMessage* m );
01413 // -----------------------------------------------------------------------
01414 
01416 struct SetDateTimeRetMessage:
01417     public SetDateTimeMessage
01418 {
01419 
01420     // ------- from slave -------
01421     SetDateTimeRetMessage( const ModbusMessage& m );
01422     SetDateTimeRetMessage& operator=( const ModbusMessage& m );
01423     void init( const ModbusMessage& m );
01424 
01425     // ------- to master -------
01426     SetDateTimeRetMessage( ModbusAddr _from );
01427     SetDateTimeRetMessage( const SetDateTimeMessage& query );
01428     static void cpy( SetDateTimeRetMessage& reply, const SetDateTimeMessage& query );
01429 
01431     ModbusMessage transport_msg();
01432 };
01433 // -----------------------------------------------------------------------
01434 
01436 struct RemoteServiceMessage:
01437     public ModbusHeader
01438 {
01439     ModbusByte bcnt = { 0 };    
01442     ModbusByte data[MAXLENPACKET - sizeof(ModbusByte)];
01443     ModbusCRC crc = { 0 };        
01445     // -----------
01446     RemoteServiceMessage( const ModbusMessage& m );
01447     RemoteServiceMessage& operator=( const ModbusMessage& m );
01448     void init( const ModbusMessage& m );
01449 
01451     size_t szData() const;
01452 
01456     static inline size_t szHead()
01457     {
01458         return sizeof(ModbusByte);    // bcnt
01459     }
01460 
01462     static size_t getDataLen( const ModbusMessage& m );
01463 
01464 } __attribute__((packed));
01465 
01466 std::ostream& operator<<(std::ostream& os, RemoteServiceMessage& m );
01467 std::ostream& operator<<(std::ostream& os, RemoteServiceMessage* m );
01468 // -----------------------------------------------------------------------
01469 struct RemoteServiceRetMessage:
01470     public ModbusHeader
01471 {
01472     ModbusByte bcnt = { 0 };    
01474     ModbusByte data[MAXLENPACKET - sizeof(ModbusByte)];
01475 
01476     RemoteServiceRetMessage( ModbusAddr _from );
01477 
01484     bool setData( ModbusByte* b, int len );
01485 
01487     void clear();
01488 
01490     inline bool isFull() const
01491     {
01492         return ( count >= sizeof(data) );
01493     }
01494 
01496     size_t szData() const;
01497 
01499     ModbusMessage transport_msg();
01500 
01501     // Это поле не входит в стандарт modbus
01502     // оно вспомогательное и игнорируется при
01503     // преобразовании в ModbusMessage.
01504     size_t count = { 0 };    
01505 };
01506 // -----------------------------------------------------------------------
01507 
01508 struct ReadFileRecordMessage:
01509     public ModbusHeader
01510 {
01511     struct SubRequest
01512     {
01513         ModbusByte reftype; 
01514         ModbusData numfile; 
01515         ModbusData numrec;  
01516         ModbusData reglen;  
01517     } __attribute__((packed));
01518 
01519     ModbusByte bcnt = { 0 };    
01522     SubRequest data[MAXLENPACKET / sizeof(SubRequest) - sizeof(ModbusByte)];
01523     ModbusCRC crc = { 0 };        
01525     // -----------
01526     ReadFileRecordMessage( const ModbusMessage& m );
01527     ReadFileRecordMessage& operator=( const ModbusMessage& m );
01528     void init( const ModbusMessage& m );
01529 
01531     size_t szData() const;
01532 
01536     static inline size_t szHead()
01537     {
01538         return sizeof(ModbusByte);    // bcnt
01539     }
01540 
01542     static size_t getDataLen( const ModbusMessage& m );
01543 
01545     bool checkFormat() const;
01546 
01547     // это поле служебное и не используется в релальном обмене
01548     size_t count = { 0 }; 
01549 };
01550 
01551 std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage& m );
01552 std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage* m );
01553 // -----------------------------------------------------------------------
01554 
01555 struct FileTransferMessage:
01556     public ModbusHeader
01557 {
01558     ModbusData numfile = { 0 };     
01559     ModbusData numpacket = { 0 };   
01560     ModbusCRC crc = { 0 };          
01562     // ------- to slave -------
01563     FileTransferMessage( ModbusAddr addr, ModbusData numfile, ModbusData numpacket );
01564     ModbusMessage transport_msg();     
01566     // ------- from master -------
01567     FileTransferMessage( const ModbusMessage& m );
01568     FileTransferMessage& operator=( const ModbusMessage& m );
01569     void init( const ModbusMessage& m );
01570 
01572     static inline size_t szData()
01573     {
01574         return sizeof(ModbusData) * 2 + szCRC;
01575     }
01576 
01577 } __attribute__((packed));
01578 
01579 std::ostream& operator<<(std::ostream& os, FileTransferMessage& m );
01580 std::ostream& operator<<(std::ostream& os, FileTransferMessage* m );
01581 // -----------------------------------------------------------------------
01582 
01583 struct FileTransferRetMessage:
01584     public ModbusHeader
01585 {
01586     // 255 - max of bcnt...(1 byte)
01587     //        static const int MaxDataLen = 255 - szCRC - szModbusHeader - sizeof(ModbusData)*3 - sizeof(ModbusByte)*2;
01588     static const size_t MaxDataLen = MAXLENPACKET - sizeof(ModbusData) * 3 - sizeof(ModbusByte) * 2;
01589 
01590     ModbusByte bcnt;        
01591     ModbusData numfile;     
01592     ModbusData numpacks;     
01593     ModbusData packet;      
01594     ModbusByte dlen;        
01595     ModbusByte data[MaxDataLen];
01596 
01597 
01598     // ------- from slave -------
01599     FileTransferRetMessage( const ModbusMessage& m );
01600     FileTransferRetMessage& operator=( const ModbusMessage& m );
01601     void init( const ModbusMessage& m );
01602     ModbusCRC crc = { 0 };
01603     static size_t szHead()
01604     {
01605         return sizeof(ModbusByte);
01606     }
01607     static size_t getDataLen( const ModbusMessage& m );
01608 
01609     // ------- to master -------
01610     FileTransferRetMessage( ModbusAddr _from );
01611 
01615     bool set( ModbusData numfile, ModbusData file_num_packets, ModbusData packet, ModbusByte* b, ModbusByte len );
01616 
01618     void clear();
01619 
01621     size_t szData() const;
01622 
01624     ModbusMessage transport_msg();
01625 };
01626 
01627 std::ostream& operator<<(std::ostream& os, FileTransferRetMessage& m );
01628 std::ostream& operator<<(std::ostream& os, FileTransferRetMessage* m );
01629 // -----------------------------------------------------------------------
01630 } // end of ModbusRTU namespace
01631 // -------------------------------------------------------------------------
01632 } // end of namespace uniset
01633 // ---------------------------------------------------------------------------
01634 #endif // ModbusTypes_H_
01635 // ---------------------------------------------------------------------------