UniSet  2.0.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 ModbusRTU
00022 {
00023     // Базовые типы 
00024     typedef unsigned char ModbusByte;    
00025     const int BitsPerByte = 8;
00026     typedef unsigned char ModbusAddr;    
00027     typedef unsigned short ModbusData;    
00028     const int BitsPerData = 16;
00029     typedef unsigned short ModbusCRC;    
00031     // ---------------------------------------------------------------------
00033     enum SlaveFunctionCode
00034     {
00035         fnUnknown                = 0x00,
00036         fnReadCoilStatus        = 0x01, 
00037         fnReadInputStatus        = 0x02, 
00038         fnReadOutputRegisters    = 0x03, 
00039         fnReadInputRegisters    = 0x04, 
00040         fnForceSingleCoil        = 0x05, 
00041         fnWriteOutputSingleRegister = 0x06,    
00042         fnDiagnostics            = 0x08, 
00043         fnForceMultipleCoils    = 0x0F,    
00044         fnWriteOutputRegisters    = 0x10,    
00045         fnReadFileRecord        = 0x14,    
00046         fnWriteFileRecord        = 0x15,    
00047         fnMEI                    = 0x2B, 
00048         fnSetDateTime            = 0x50, 
00049         fnRemoteService            = 0x53,    
00050         fnJournalCommand        = 0x65,    
00051         fnFileTransfer            = 0x66    
00052     };
00053 
00055     enum DiagnosticsSubFunction
00056     {
00057         subEcho = 0x00,         
00058         dgRestartComm = 0x01,     
00059         dgDiagReg = 0x02,         
00060         dgChangeASCII = 0x03,    
00061         dgForceListen = 0x04,    
00062         // 05.. 09 RESERVED
00063         dgClearCounters = 0x0A,     
00064         dgBusMsgCount = 0x0B,        
00065         dgBusErrCount = 0x0C,        
00066         dgBusExceptCount = 0x0D,    
00067         dgMsgSlaveCount = 0x0E,        
00068         dgNoNoResponseCount = 0x0F,    
00069         dgSlaveNAKCount = 0x10,        
00070         dgSlaveBusyCount = 0x11,        
00071         dgBusCharOverrunCount = 0x12,    
00072          // = 0x13,    /*!<  RESERVED */
00073         dgClearOverrunCounter = 0x14    
00074          // 21 ...65535 RESERVED
00075     };
00076 
00077     // определение размера данных в зависимости от типа сообщения
00078     // возвращает -1 - если динамический размер сообщения или размер неизвестен
00079     int szRequestDiagnosticData( DiagnosticsSubFunction f );
00080 
00082     enum RDIObjectID 
00083     {
00084         rdiVendorName = 0x0,
00085         rdiProductCode = 0x1,
00086         rdiMajorMinorRevision = 0x2,
00087         rdiVendorURL = 0x3,
00088         rdiProductName = 0x4,
00089         rdiModelName = 0x5,
00090         rdiUserApplicationName = 0x6
00091         // 0x07 .. 0x7F - reserved
00092         // 0x80 .. 0xFF - optionaly defined (product dependant)
00093     };
00094 
00096     enum RDIRequestDeviceID 
00097     {
00098         rdevMinNum = 0,
00099         rdevBasicDevice = 0x1,   // request to get the basic device identification (stream access)
00100         rdevRegularDevice = 0x2, // request to get the regular device identification (stream access)
00101         rdevExtentedDevice = 0x3, // request to get the extended device identification (stream access)
00102         rdevSpecificDevice = 0x4, // request to get the extended device identification (stream access)
00103         rdevMaxNum = 0x5
00104     };
00105 
00106     std::string rdi2str( int id );
00107     // -----------------------------------------------------------------------
00108 
00110     enum
00111     {
00113         MAXLENPACKET     = 508,    
00114         BroadcastAddr    = 255,    
00115         MAXDATALEN        = 127    
00119     };
00120 
00121     const unsigned char MBErrMask = 0x80;
00122     // ---------------------------------------------------------------------
00123     unsigned short SWAPSHORT(unsigned short x);
00124     // ---------------------------------------------------------------------
00126     ModbusCRC checkCRC( ModbusByte* start, int len );
00127     const int szCRC = sizeof(ModbusCRC); 
00128     // ---------------------------------------------------------------------
00130     std::ostream& mbPrintMessage( std::ostream& os, ModbusByte* b, int len );
00131     // -------------------------------------------------------------------------
00132     ModbusAddr str2mbAddr( const std::string& val );
00133     ModbusData str2mbData( const std::string& val );
00134     std::string dat2str( const ModbusData dat );
00135     std::string addr2str( const ModbusAddr addr );
00136     std::string b2str( const ModbusByte b );
00137     // -------------------------------------------------------------------------
00138     float dat2f( const ModbusData dat1, const ModbusData dat2 );
00139     // -------------------------------------------------------------------------
00140     bool isWriteFunction( SlaveFunctionCode c );
00141     // -------------------------------------------------------------------------
00143     struct ModbusHeader
00144     {
00145         ModbusAddr addr;        
00146         ModbusByte func;        
00148         ModbusHeader():addr(0),func(0){}
00149     }__attribute__((packed));
00150 
00151     const int szModbusHeader = sizeof(ModbusHeader);
00152     std::ostream& operator<<(std::ostream& os, ModbusHeader& m );
00153     std::ostream& operator<<(std::ostream& os, ModbusHeader* m );
00154     // -----------------------------------------------------------------------
00155 
00159     struct ModbusMessage:
00160         public ModbusHeader
00161     {
00162         ModbusMessage();
00163         ModbusByte data[MAXLENPACKET+szCRC];     
00165         // Это поле вспомогательное и игнорируется при пересылке
00166         int len;    
00167     }__attribute__((packed));
00168 
00169     std::ostream& operator<<(std::ostream& os, ModbusMessage& m );
00170     std::ostream& operator<<(std::ostream& os, ModbusMessage* m );
00171     // -----------------------------------------------------------------------
00173     struct ErrorRetMessage:
00174         public ModbusHeader
00175     {
00176         ModbusByte ecode;
00177         ModbusCRC crc;
00178 
00179         // ------- from slave -------
00180         ErrorRetMessage( ModbusMessage& m );
00181         ErrorRetMessage& operator=( ModbusMessage& m );
00182         void init( ModbusMessage& m );
00183 
00184         // ------- to master -------
00185         ErrorRetMessage( ModbusAddr _from, ModbusByte _func, ModbusByte ecode );
00186 
00188         ModbusMessage transport_msg();
00189 
00193         inline static int szData(){ return sizeof(ModbusByte)+szCRC; }
00194     };
00195 
00196     std::ostream& operator<<(std::ostream& os, ErrorRetMessage& m ); 
00197     std::ostream& operator<<(std::ostream& os, ErrorRetMessage* m ); 
00198     // -----------------------------------------------------------------------
00199     struct DataBits
00200     {
00201         DataBits( ModbusByte b );
00202         DataBits( std::string s ); // example "10001111"
00203         DataBits();
00204 
00205         const DataBits& operator=(const ModbusByte& r);
00206 
00207         operator ModbusByte();
00208         ModbusByte mbyte();
00209 
00210         bool operator[]( const size_t i ){ return b[i]; }
00211         void set( int n, bool s ){ b.set(n,s); }
00212 
00213         std::bitset<BitsPerByte> b;
00214     };
00215 
00216     std::ostream& operator<<(std::ostream& os, DataBits& m );
00217     std::ostream& operator<<(std::ostream& os, DataBits* m ); 
00218     // -----------------------------------------------------------------------
00219     struct DataBits16
00220     {
00221         DataBits16( ModbusData d );
00222         DataBits16( const std::string& s ); // example "1000111110001111"
00223         DataBits16();
00224 
00225         const DataBits16& operator=(const ModbusData& r);
00226 
00227         operator ModbusData();
00228         ModbusData mdata();
00229 
00230         bool operator[]( const size_t i ){ return b[i]; }
00231         void set( int n, bool s ){ b.set(n,s); }
00232 
00233         std::bitset<BitsPerData> b;
00234     };
00235 
00236     std::ostream& operator<<(std::ostream& os, DataBits16& m );
00237     std::ostream& operator<<(std::ostream& os, DataBits16* m ); 
00238     // -----------------------------------------------------------------------
00240     struct ReadCoilMessage:
00241         public ModbusHeader
00242     {
00243         ModbusData start;
00244         ModbusData count;
00245         ModbusCRC crc;
00246 
00247         // ------- to slave -------
00248         ReadCoilMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00250         ModbusMessage transport_msg();
00251 
00252         // ------- from master -------
00253         ReadCoilMessage( ModbusMessage& m );
00254         ReadCoilMessage& operator=( ModbusMessage& m );
00255         void init( ModbusMessage& m );
00256 
00258         inline static int szData(){ return sizeof(ModbusData)*2 + szCRC; }
00259 
00260     }__attribute__((packed));
00261 
00262     std::ostream& operator<<(std::ostream& os, ReadCoilMessage& m ); 
00263     std::ostream& operator<<(std::ostream& os, ReadCoilMessage* m ); 
00264 
00265     // -----------------------------------------------------------------------
00266 
00268     struct ReadCoilRetMessage:
00269         public ModbusHeader
00270     {
00271         ModbusByte bcnt;                
00272         ModbusByte data[MAXLENPACKET];    
00274         // ------- from slave -------
00275         ReadCoilRetMessage( ModbusMessage& m );
00276         ReadCoilRetMessage& operator=( ModbusMessage& m );
00277         void init( ModbusMessage& m );
00281         static inline int szHead()
00282         {
00283             return sizeof(ModbusByte); // bcnt
00284         }
00285 
00287         static int getDataLen( ModbusMessage& m );
00288         ModbusCRC crc;
00289 
00290         // ------- to master -------
00291         ReadCoilRetMessage( ModbusAddr _from );
00292 
00297         bool addData( DataBits d );
00298 
00306         bool setBit( unsigned char dnum, unsigned char bnum, bool state );
00307 
00314         bool getData( unsigned char bnum, DataBits& d );
00315 
00317         void clear();
00318 
00320         inline bool isFull()
00321         {
00322             return ( (int)bcnt >= MAXLENPACKET );
00323         }
00324 
00326         size_t szData();
00327 
00329         ModbusMessage transport_msg();
00330     };
00331 
00332     std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage& m );
00333     std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage* m );
00334     // -----------------------------------------------------------------------
00336     struct ReadInputStatusMessage:
00337         public ModbusHeader
00338     {
00339         ModbusData start;
00340         ModbusData count;
00341         ModbusCRC crc;
00342 
00343         // ------- to slave -------
00344         ReadInputStatusMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00346         ModbusMessage transport_msg();
00347 
00348         // ------- from master -------
00349         ReadInputStatusMessage( ModbusMessage& m );
00350         ReadInputStatusMessage& operator=( ModbusMessage& m );
00351         void init( ModbusMessage& m );
00352 
00354         inline static int szData(){ return sizeof(ModbusData)*2 + szCRC; }
00355 
00356     }__attribute__((packed));
00357 
00358     std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage& m ); 
00359     std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage* m ); 
00360     // -----------------------------------------------------------------------
00362     struct ReadInputStatusRetMessage:
00363         public ModbusHeader
00364     {
00365         ModbusByte bcnt;                
00366         ModbusByte data[MAXLENPACKET];    
00368         // ------- from slave -------
00369         ReadInputStatusRetMessage( ModbusMessage& m );
00370         ReadInputStatusRetMessage& operator=( ModbusMessage& m );
00371         void init( ModbusMessage& m );
00375         static inline int szHead()
00376         {
00377             return sizeof(ModbusByte); // bcnt
00378         }
00379 
00381         static int getDataLen( ModbusMessage& m );
00382         ModbusCRC crc;
00383 
00384         // ------- to master -------
00385         ReadInputStatusRetMessage( ModbusAddr _from );
00386 
00391         bool addData( DataBits d );
00392 
00400         bool setBit( unsigned char dnum, unsigned char bnum, bool state );
00401 
00408         bool getData( unsigned char dnum, DataBits& d );
00409 
00411         void clear();
00412 
00414         inline bool isFull()
00415         {
00416             return ( (int)bcnt >= MAXLENPACKET );
00417         }
00418 
00420         size_t szData();
00421 
00423         ModbusMessage transport_msg();
00424     };
00425 
00426     std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage& m );
00427     std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage* m );
00428     // -----------------------------------------------------------------------
00429 
00431     struct ReadOutputMessage:
00432         public ModbusHeader
00433     {
00434         ModbusData start;
00435         ModbusData count;
00436         ModbusCRC crc;
00437 
00438         // ------- to slave -------
00439         ReadOutputMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00441         ModbusMessage transport_msg();
00442 
00443         // ------- from master -------
00444         ReadOutputMessage( ModbusMessage& m );
00445         ReadOutputMessage& operator=( ModbusMessage& m );
00446         void init( ModbusMessage& m );
00447 
00449         inline static int szData(){ return sizeof(ModbusData)*2 + szCRC; }
00450 
00451     }__attribute__((packed));
00452 
00453     std::ostream& operator<<(std::ostream& os, ReadOutputMessage& m ); 
00454     std::ostream& operator<<(std::ostream& os, ReadOutputMessage* m ); 
00455     // -----------------------------------------------------------------------
00457     struct ReadOutputRetMessage:
00458         public ModbusHeader
00459     {
00460         ModbusByte bcnt;                                    
00461         ModbusData data[MAXLENPACKET/sizeof(ModbusData)];    
00463         // ------- from slave -------
00464         ReadOutputRetMessage( ModbusMessage& m );
00465         ReadOutputRetMessage& operator=( ModbusMessage& m );
00466         void init( ModbusMessage& m );
00470         static inline int szHead()
00471         {
00472             // bcnt
00473             return sizeof(ModbusByte);
00474         }
00475 
00477         static int getDataLen( ModbusMessage& m );
00478         ModbusCRC crc;
00479 
00480         // ------- to master -------
00481         ReadOutputRetMessage( ModbusAddr _from );
00482 
00487         bool addData( ModbusData d );
00488 
00490         void clear();
00491 
00493         inline bool isFull()
00494         {
00495             return ( count*sizeof(ModbusData) >= MAXLENPACKET );
00496         }
00497 
00499         size_t szData();
00500 
00502         ModbusMessage transport_msg();
00503 
00504         // Это поле не входит в стандарт modbus
00505         // оно вспомогательное и игнорируется при 
00506         // преобразовании в ModbusMessage.
00507         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 
00508         // Используйте специальную функцию transport_msg()
00509         int    count;    
00510     };
00511 
00512     std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage& m );
00513     std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage* m );
00514     // -----------------------------------------------------------------------
00516     struct ReadInputMessage:
00517         public ModbusHeader
00518     {
00519         ModbusData start;
00520         ModbusData count;
00521         ModbusCRC crc;
00522 
00523         // ------- to slave -------
00524         ReadInputMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00526         ModbusMessage transport_msg();
00527 
00528         // ------- from master -------
00529         ReadInputMessage( ModbusMessage& m );
00530         ReadInputMessage& operator=( ModbusMessage& m );
00531         void init( ModbusMessage& m );
00532 
00534         inline static int szData(){ return sizeof(ModbusData)*2 + szCRC; }
00535 
00536     }__attribute__((packed));
00537 
00538     std::ostream& operator<<(std::ostream& os, ReadInputMessage& m ); 
00539     std::ostream& operator<<(std::ostream& os, ReadInputMessage* m ); 
00540     // -----------------------------------------------------------------------
00541 
00543     struct ReadInputRetMessage:
00544         public ModbusHeader
00545     {
00546         ModbusByte bcnt;                                    
00547         ModbusData data[MAXLENPACKET/sizeof(ModbusData)];    
00549         // ------- from slave -------
00550         ReadInputRetMessage( ModbusMessage& m );
00551         ReadInputRetMessage& operator=( ModbusMessage& m );
00552         void init( ModbusMessage& m );
00556         static inline int szHead()
00557         {
00558             // bcnt
00559             return sizeof(ModbusByte);
00560         }
00561 
00563         static int getDataLen( ModbusMessage& m );
00564         ModbusCRC crc;
00565 
00566         // ------- to master -------
00567         ReadInputRetMessage( ModbusAddr _from );
00568 
00573         bool addData( ModbusData d );
00574 
00576         void clear();
00577 
00579         inline bool isFull()
00580         {
00581             return ( count*sizeof(ModbusData) >= MAXLENPACKET );
00582         }
00583 
00584         void swapData();
00585 
00587         size_t szData();
00588 
00590         ModbusMessage transport_msg();
00591 
00592         // Это поле не входит в стандарт modbus
00593         // оно вспомогательное и игнорируется при 
00594         // преобразовании в ModbusMessage.
00595         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 
00596         // Используйте специальную функцию transport_msg()
00597         int    count;    
00598     };
00599 
00600     std::ostream& operator<<(std::ostream& os, ReadInputRetMessage& m );
00601     std::ostream& operator<<(std::ostream& os, ReadInputRetMessage* m );
00602     // -----------------------------------------------------------------------
00604     struct ForceCoilsMessage:
00605         public ModbusHeader
00606     {
00607         ModbusData start;    
00608         ModbusData quant;    
00609         ModbusByte bcnt;    
00611         ModbusByte data[MAXLENPACKET-sizeof(ModbusData)*2-sizeof(ModbusByte)];
00612         ModbusCRC crc;        
00614         // ------- to slave -------
00615         ForceCoilsMessage( ModbusAddr addr, ModbusData start );
00617         ModbusMessage transport_msg();
00618 
00623         bool addData( DataBits d );
00624 
00625         // return number of bit
00626         // -1 - error
00627         int addBit( bool state );
00628 
00629         bool setBit( int nbit, bool state );
00630 
00631         inline int last(){ return quant; }
00632 
00639         bool getData( unsigned char dnum, DataBits& d );
00640 
00641         bool getBit( unsigned char bnum );
00642 
00643         void clear();
00644         inline bool isFull()
00645         {
00646             return ( (int)bcnt >= MAXLENPACKET );
00647         }
00648 
00649         // ------- from master -------    
00650         ForceCoilsMessage( ModbusMessage& m );
00651         ForceCoilsMessage& operator=( ModbusMessage& m );
00652         void init( ModbusMessage& m );
00653 
00655         size_t szData();
00656 
00660         static inline int szHead()
00661         {
00662             // start + quant + count
00663             return sizeof(ModbusData)*2+sizeof(ModbusByte);
00664         }
00665         
00667         static int getDataLen( ModbusMessage& m );
00668 
00672         bool checkFormat();
00673         
00674     }__attribute__((packed));
00675 
00676     std::ostream& operator<<(std::ostream& os, ForceCoilsMessage& m );
00677     std::ostream& operator<<(std::ostream& os, ForceCoilsMessage* m );
00678     // -----------------------------------------------------------------------
00680     struct ForceCoilsRetMessage:
00681         public ModbusHeader
00682     {
00683         ModbusData start;     
00684         ModbusData quant;    
00685         ModbusCRC crc;
00686 
00687         // ------- from slave -------
00688         ForceCoilsRetMessage( ModbusMessage& m );
00689         ForceCoilsRetMessage& operator=( ModbusMessage& m );
00690         void init( ModbusMessage& m );
00691         
00692         // ------- to master -------
00698         ForceCoilsRetMessage( ModbusAddr _from, ModbusData start=0, ModbusData quant=0 );
00699 
00701         void set( ModbusData start, ModbusData quant );
00702 
00704         ModbusMessage transport_msg();
00705         
00709         inline static int szData(){ return sizeof(ModbusData)*2+sizeof(ModbusCRC); }
00710     };
00711     
00712     std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage& m );
00713     std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage* m );
00714     // -----------------------------------------------------------------------
00715 
00717     struct WriteOutputMessage:
00718         public ModbusHeader
00719     {
00720         ModbusData start;    
00721         ModbusData quant;    
00722         ModbusByte bcnt;    
00724         ModbusData data[MAXLENPACKET/sizeof(ModbusData)-sizeof(ModbusData)*2-sizeof(ModbusByte)];
00725         ModbusCRC crc;        
00727         // ------- to slave -------
00728         WriteOutputMessage( ModbusAddr addr, ModbusData start );
00730         ModbusMessage transport_msg();
00731 
00732         bool addData( ModbusData d );
00733         void clear();
00734         inline bool isFull()
00735         {
00736             return ( quant >= MAXDATALEN );
00737         }
00738 
00739         // ------- from master -------    
00740         WriteOutputMessage( ModbusMessage& m );
00741         WriteOutputMessage& operator=( ModbusMessage& m );
00742         void init( ModbusMessage& m );
00743 
00745         size_t szData();
00746 
00750         static inline int szHead()
00751         {
00752             // start + quant + count
00753             return sizeof(ModbusData)*2+sizeof(ModbusByte);
00754         }
00755         
00757         static int getDataLen( ModbusMessage& m );
00758 
00762         bool checkFormat();
00763         
00764     }__attribute__((packed));
00765 
00766 
00767     std::ostream& operator<<(std::ostream& os, WriteOutputMessage& m );
00768     std::ostream& operator<<(std::ostream& os, WriteOutputMessage* m );
00769 
00771     struct WriteOutputRetMessage:
00772         public ModbusHeader
00773     {
00774         ModbusData start;     
00775         ModbusData quant;    
00777         // ------- from slave -------
00778         WriteOutputRetMessage( ModbusMessage& m );
00779         WriteOutputRetMessage& operator=( ModbusMessage& m );
00780         void init( ModbusMessage& m );
00781         ModbusCRC crc;
00782 
00783         // ------- to master -------
00789         WriteOutputRetMessage( ModbusAddr _from, ModbusData start=0, ModbusData quant=0 );
00790 
00792         void set( ModbusData start, ModbusData quant );
00793 
00795         ModbusMessage transport_msg();
00796         
00800         inline static int szData(){ return sizeof(ModbusData)*2+sizeof(ModbusCRC); }
00801     };
00802     
00803     std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage& m );
00804     std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage* m );
00805     // -----------------------------------------------------------------------
00807     struct ForceSingleCoilMessage:
00808         public ModbusHeader
00809     {
00810         ModbusData start;    
00811         ModbusData data;    
00812         ModbusCRC crc;        
00815         inline bool cmd()
00816         {
00817             return (data & 0xFF00);
00818         }
00819 
00820 
00821         // ------- to slave -------
00822         ForceSingleCoilMessage( ModbusAddr addr, ModbusData reg, bool state );
00824         ModbusMessage transport_msg();
00825     
00826         // ------- from master -------
00827         ForceSingleCoilMessage( ModbusMessage& m );
00828         ForceSingleCoilMessage& operator=( ModbusMessage& m );
00829         void init( ModbusMessage& m );
00830 
00832         size_t szData();
00833 
00837         static inline int szHead()
00838         {
00839             return sizeof(ModbusData);
00840         }
00841         
00845         static int getDataLen( ModbusMessage& m );
00846 
00850         bool checkFormat();
00851     }__attribute__((packed));
00852 
00853 
00854     std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage& m );
00855     std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage* m );
00856     // -----------------------------------------------------------------------
00857 
00859     struct ForceSingleCoilRetMessage:
00860         public ModbusHeader
00861     {
00862         ModbusData start;     
00863         ModbusData data;     
00864         ModbusCRC crc;
00865 
00867         inline bool cmd()
00868         {
00869             return (data & 0xFF00);
00870         }
00871 
00872         // ------- from slave -------
00873         ForceSingleCoilRetMessage( ModbusMessage& m );
00874         ForceSingleCoilRetMessage& operator=( ModbusMessage& m );
00875         void init( ModbusMessage& m );
00876 
00877         // ------- to master -------
00882         ForceSingleCoilRetMessage( ModbusAddr _from );
00883 
00885         void set( ModbusData start, bool cmd );
00886 
00888         ModbusMessage transport_msg();
00889         
00893         inline static int szData(){ return 2*sizeof(ModbusData)+sizeof(ModbusCRC); }
00894     };
00895     
00896     std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage& m );
00897     std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage* m );
00898     // -----------------------------------------------------------------------
00899 
00901     struct WriteSingleOutputMessage:
00902         public ModbusHeader
00903     {
00904         ModbusData start;    
00905         ModbusData data;    
00906         ModbusCRC crc;        
00909         // ------- to slave -------
00910         WriteSingleOutputMessage( ModbusAddr addr, ModbusData reg=0, ModbusData data=0 );
00912         ModbusMessage transport_msg();
00913     
00914         // ------- from master -------
00915         WriteSingleOutputMessage( ModbusMessage& m );
00916         WriteSingleOutputMessage& operator=( ModbusMessage& m );
00917         void init( ModbusMessage& m );
00918 
00920         size_t szData();
00921 
00925         static inline int szHead()
00926         {
00927             return sizeof(ModbusData);
00928         }
00929         
00933         static int getDataLen( ModbusMessage& m );
00934 
00938         bool checkFormat();
00939     }__attribute__((packed));
00940 
00941 
00942     std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage& m );
00943     std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage* m );
00944     // -----------------------------------------------------------------------
00945 
00947     struct WriteSingleOutputRetMessage:
00948         public ModbusHeader
00949     {
00950         ModbusData start;     
00951         ModbusData data;     
00952         ModbusCRC crc;
00953 
00954 
00955         // ------- from slave -------
00956         WriteSingleOutputRetMessage( ModbusMessage& m );
00957         WriteSingleOutputRetMessage& operator=( ModbusMessage& m );
00958         void init( ModbusMessage& m );
00959 
00960         // ------- to master -------
00965         WriteSingleOutputRetMessage( ModbusAddr _from, ModbusData start=0 );
00966 
00968         void set( ModbusData start, ModbusData data );
00969 
00971         ModbusMessage transport_msg();
00972         
00976         inline static int szData(){ return 2*sizeof(ModbusData)+sizeof(ModbusCRC); }
00977     };
00978     
00979     std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage& m );
00980     std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage* m );
00981     // -----------------------------------------------------------------------
00983     struct DiagnosticMessage:
00984         public ModbusHeader
00985     {
00986         ModbusData subf;
00987         ModbusData data[MAXLENPACKET/sizeof(ModbusData)];    
00989         // ------- from slave -------
00990         DiagnosticMessage( ModbusMessage& m );
00991         DiagnosticMessage& operator=( ModbusMessage& m );
00992         void init( ModbusMessage& m );
00996         static inline int szHead()
00997         {
00998             return sizeof(ModbusData); // subf
00999         }
01000 
01002         static int getDataLen( ModbusMessage& m );
01003         ModbusCRC crc;
01004         
01005         // ------- to master -------
01006         DiagnosticMessage( ModbusAddr _from, DiagnosticsSubFunction subf, ModbusData d=0 );
01007 
01012         bool addData( ModbusData d );
01013 
01015         void clear();
01016         
01018         inline bool isFull()
01019         {
01020             // (1)subf + data count 
01021             return ( 1+count >= MAXDATALEN );
01022         }
01023 
01025         size_t szData();
01026 
01028         ModbusMessage transport_msg();
01029 
01030         // Это поле не входит в стандарт modbus
01031         // оно вспомогательное и игнорируется при 
01032         // преобразовании в ModbusMessage.
01033         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 
01034         // Используйте специальную функцию transport_msg()
01035         int    count;    
01036     };
01037     std::ostream& operator<<(std::ostream& os, DiagnosticMessage& m );
01038     std::ostream& operator<<(std::ostream& os, DiagnosticMessage* m );
01039     // -----------------------------------------------------------------------
01041     struct DiagnosticRetMessage:
01042         public DiagnosticMessage
01043     {
01044         DiagnosticRetMessage( ModbusMessage& m );
01045         DiagnosticRetMessage( DiagnosticMessage& m );
01046         DiagnosticRetMessage( ModbusAddr a, DiagnosticsSubFunction subf, ModbusData d=0 );
01047     };
01048 
01049     std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage& m );
01050     std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage* m );
01051     // -----------------------------------------------------------------------
01053     struct MEIMessageRDI:
01054         public ModbusHeader
01055     {
01056         ModbusByte type;     
01057         ModbusByte devID;     
01058         ModbusByte objID;     
01060         ModbusCRC crc;        
01062         // ------- to slave -------
01063         MEIMessageRDI( ModbusAddr addr, ModbusByte devID, ModbusByte objID );
01065         ModbusMessage transport_msg();
01066 
01067         // ------- from master -------    
01068         MEIMessageRDI( ModbusMessage& m );
01069         MEIMessageRDI& operator=( ModbusMessage& m );
01070         void init( ModbusMessage& m );
01071 
01075         static inline int szHead(){ return sizeof(ModbusByte)*3; }
01076 
01078         static inline int szData(){ return sizeof(ModbusByte)*3 + szCRC; }
01079 
01080         // вспомогательные функции
01081         bool checkFormat();
01082 
01083     }__attribute__((packed));
01084     // -----------------------------------------------------------------------
01085     std::ostream& operator<<(std::ostream& os, MEIMessageRDI& m );
01086     std::ostream& operator<<(std::ostream& os, MEIMessageRDI* m );
01087     // -----------------------------------------------------------------------
01088 
01089     struct RDIObjectInfo
01090     {
01091         RDIObjectInfo():id(0),val(""){}
01092         RDIObjectInfo( ModbusByte id, const std::string& v ):id(id),val(v){}
01093         RDIObjectInfo( ModbusByte id, ModbusByte* dat, ModbusByte len );
01094 
01095         ModbusByte id;
01096         std::string val;
01097     };
01098 
01099     typedef std::list<RDIObjectInfo> RDIObjectList;
01100 
01102     struct MEIMessageRetRDI:
01103         public ModbusHeader
01104     {
01105         ModbusByte type;     
01106         ModbusByte devID;     
01107         ModbusByte conformity; 
01108         ModbusByte mf;         
01109         ModbusByte objID;     
01110         ModbusByte objNum;     
01112         RDIObjectList dlist;
01113         ModbusCRC crc;
01114 
01115         // ------- from slave -------
01116         MEIMessageRetRDI();
01117         MEIMessageRetRDI( ModbusMessage& m );
01118         MEIMessageRetRDI& operator=( ModbusMessage& m );
01119         void init( ModbusMessage& m );
01120 
01121         // предварительная инициализации, только заголовочной части, без данных
01122         void pre_init( ModbusMessage& m );
01123 
01125         static inline int szHead()
01126         {
01127             return sizeof(ModbusByte)*6;
01128         }
01129 
01130 //        /*! узнать длину данных следующих за предварительным заголовком ( в байтах ) */
01131 //        static int getDataLen( ModbusMessage& m );
01132         
01133         // ------- to master -------
01134         MEIMessageRetRDI( ModbusAddr _from, ModbusByte devID, ModbusByte conformity, ModbusByte mf, ModbusByte objID );
01135 
01140         bool addData( ModbusByte id, const std::string& value );
01141         bool addData( RDIObjectInfo& dat );
01142 
01144         void clear();
01145         
01147         inline bool isFull()
01148         {
01149             return ( bcnt >= MAXLENPACKET );
01150         }
01151         
01153         size_t szData();
01154         
01156         ModbusMessage transport_msg();
01157 
01158         int bcnt; 
01159     };
01160 
01161     std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI& m );
01162     std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI* m );
01163     std::ostream& operator<<(std::ostream& os, RDIObjectList& dl );
01164     std::ostream& operator<<(std::ostream& os, RDIObjectList* dl );
01165     // -----------------------------------------------------------------------
01166     // -----------------------------------------------------------------------
01167 
01169     struct JournalCommandMessage:
01170         public ModbusHeader
01171     {
01172         ModbusData cmd;            
01173         ModbusData num;            
01174         ModbusCRC crc;
01175         
01176         // -------------
01177         JournalCommandMessage( ModbusMessage& m );
01178         JournalCommandMessage& operator=( ModbusMessage& m );
01179 
01181         inline static int szData(){ return sizeof(ModbusByte)*4 + szCRC; }
01182 
01183     }__attribute__((packed));
01184 
01185     std::ostream& operator<<(std::ostream& os, JournalCommandMessage& m ); 
01186     std::ostream& operator<<(std::ostream& os, JournalCommandMessage* m ); 
01187     // -----------------------------------------------------------------------
01189     struct JournalCommandRetMessage:
01190         public ModbusHeader
01191     {
01192         ModbusByte bcnt;                    
01193 //        ModbusByte data[MAXLENPACKET-1];    /*!< данные */
01194 
01195         // В связи со спецификой реализации ответной части (т.е. modbus master)
01196         // данные приходится делать не байтовым потоком, а "словами"
01197         // которые в свою очередь будут перевёрнуты при посылке...
01198         ModbusData data[MAXLENPACKET/sizeof(ModbusData)];    
01200         // -------------
01201         JournalCommandRetMessage( ModbusAddr _from );
01202 
01209         bool setData( ModbusByte* b, int len );
01210 
01212         void clear();
01213 
01215         inline bool isFull()
01216         {
01217             return ( count >= MAXDATALEN );
01218         }
01219 
01221         size_t szData();
01222         
01224         ModbusMessage transport_msg();
01225         
01226         // Это поле не входит в стандарт modbus
01227         // оно вспомогательное и игнорируется при 
01228         // преобразовании в ModbusMessage.
01229         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 
01230         // Используйте специальную функцию transport_msg()
01231         int    count;    
01232     };
01233 
01234     std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage& m );
01235     std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage* m );
01236     // -----------------------------------------------------------------------
01240     struct JournalCommandRetOK:
01241         public JournalCommandRetMessage
01242     {
01243         // -------------
01244         JournalCommandRetOK( ModbusAddr _from );
01245         void set( ModbusData cmd, ModbusData ecode );
01246         static void set( JournalCommandRetMessage& m, ModbusData cmd, ModbusData ecode );
01247     };
01248 
01249     std::ostream& operator<<(std::ostream& os, JournalCommandRetOK& m ); 
01250     std::ostream& operator<<(std::ostream& os, JournalCommandRetOK* m ); 
01251     // -----------------------------------------------------------------------
01252 
01254     struct SetDateTimeMessage:
01255         public ModbusHeader
01256     {
01257         ModbusByte hour;    
01258         ModbusByte min;        
01259         ModbusByte sec;        
01260         ModbusByte day;        
01261         ModbusByte mon;        
01262         ModbusByte year;    
01263         ModbusByte century;    
01265         ModbusCRC crc;
01266         
01267         // ------- to slave -------
01268         SetDateTimeMessage( ModbusAddr addr );
01270         ModbusMessage transport_msg();
01271         
01272         // ------- from master -------
01273         SetDateTimeMessage( ModbusMessage& m );
01274         SetDateTimeMessage& operator=( ModbusMessage& m );
01275         SetDateTimeMessage();
01276 
01277         bool checkFormat();
01278 
01280         inline static int szData(){ return sizeof(ModbusByte)*7 + szCRC; }
01281 
01282     }__attribute__((packed));
01283 
01284     std::ostream& operator<<(std::ostream& os, SetDateTimeMessage& m ); 
01285     std::ostream& operator<<(std::ostream& os, SetDateTimeMessage* m ); 
01286     // -----------------------------------------------------------------------
01287 
01289     struct SetDateTimeRetMessage:
01290         public SetDateTimeMessage
01291     {
01292 
01293         // ------- from slave -------
01294         SetDateTimeRetMessage( ModbusMessage& m );
01295         SetDateTimeRetMessage& operator=( ModbusMessage& m );
01296         void init( ModbusMessage& m );
01297 
01298         // ------- to master -------
01299         SetDateTimeRetMessage( ModbusAddr _from );
01300         SetDateTimeRetMessage( const SetDateTimeMessage& query );
01301         static void cpy( SetDateTimeRetMessage& reply, SetDateTimeMessage& query );
01302 
01304         ModbusMessage transport_msg();
01305     };
01306     // -----------------------------------------------------------------------
01307 
01309     struct RemoteServiceMessage:
01310         public ModbusHeader
01311     {
01312         ModbusByte bcnt;    
01315         ModbusByte data[MAXLENPACKET-sizeof(ModbusByte)];
01316         ModbusCRC crc;        
01318         // -----------
01319         RemoteServiceMessage( ModbusMessage& m );
01320         RemoteServiceMessage& operator=( ModbusMessage& m );
01321         void init( ModbusMessage& m );
01322 
01324         size_t szData();
01325 
01329         static inline int szHead()
01330         { return sizeof(ModbusByte); } // bcnt
01331         
01333         static int getDataLen( ModbusMessage& m );
01334 
01335     }__attribute__((packed));
01336 
01337     std::ostream& operator<<(std::ostream& os, RemoteServiceMessage& m ); 
01338     std::ostream& operator<<(std::ostream& os, RemoteServiceMessage* m ); 
01339     // -----------------------------------------------------------------------
01340     struct RemoteServiceRetMessage:
01341         public ModbusHeader
01342     {
01343         ModbusByte bcnt;    
01345         ModbusByte data[MAXLENPACKET-sizeof(ModbusByte)];
01346 
01347         RemoteServiceRetMessage( ModbusAddr _from );
01348 
01355         bool setData( ModbusByte* b, int len );
01356 
01358         void clear();
01359         
01361         inline bool isFull()
01362             { return ( count >= sizeof(data) ); }
01363 
01365         size_t szData();
01366         
01368         ModbusMessage transport_msg();
01369         
01370         // Это поле не входит в стандарт modbus
01371         // оно вспомогательное и игнорируется при 
01372         // преобразовании в ModbusMessage.
01373         unsigned int    count;    
01374     };
01375     // -----------------------------------------------------------------------
01376 
01377     struct ReadFileRecordMessage:
01378         public ModbusHeader
01379     {
01380         struct SubRequest
01381         {
01382             ModbusByte reftype; 
01383             ModbusData numfile; 
01384             ModbusData numrec;  
01385             ModbusData reglen;  
01386         }__attribute__((packed));    
01387 
01388         ModbusByte bcnt;    
01391         SubRequest data[MAXLENPACKET/sizeof(SubRequest)-sizeof(ModbusByte)];
01392         ModbusCRC crc;        
01394         // -----------
01395         ReadFileRecordMessage( ModbusMessage& m );
01396         ReadFileRecordMessage& operator=( ModbusMessage& m );
01397         void init( ModbusMessage& m );
01398 
01400         size_t szData();
01401 
01405         static inline int szHead()
01406         { return sizeof(ModbusByte); } // bcnt
01407         
01409         static int getDataLen( ModbusMessage& m );
01410 
01412         bool checkFormat();
01413         
01414         // это поле служебное и не используется в релальном обмене
01415         int count; 
01416     };
01417 
01418     std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage& m ); 
01419     std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage* m ); 
01420     // -----------------------------------------------------------------------
01421 
01422     struct FileTransferMessage:
01423         public ModbusHeader
01424     {
01425         ModbusData numfile;     
01426         ModbusData numpacket;      
01427         ModbusCRC crc;            
01429         // ------- to slave -------
01430         FileTransferMessage( ModbusAddr addr, ModbusData numfile, ModbusData numpacket );
01431         ModbusMessage transport_msg();     
01433         // ------- from master -------
01434         FileTransferMessage( ModbusMessage& m );
01435         FileTransferMessage& operator=( ModbusMessage& m );
01436         void init( ModbusMessage& m );
01437 
01439         static inline int szData()
01440         {    return sizeof(ModbusData)*2 + szCRC; }
01441 
01442     }__attribute__((packed));
01443 
01444     std::ostream& operator<<(std::ostream& os, FileTransferMessage& m ); 
01445     std::ostream& operator<<(std::ostream& os, FileTransferMessage* m ); 
01446     // -----------------------------------------------------------------------
01447 
01448     struct FileTransferRetMessage:
01449         public ModbusHeader
01450     {
01451         // 255 - max of bcnt...(1 byte)        
01452 //        static const int MaxDataLen = 255 - szCRC - szModbusHeader - sizeof(ModbusData)*3 - sizeof(ModbusByte)*2;
01453         static const int MaxDataLen = MAXLENPACKET - sizeof(ModbusData)*3 - sizeof(ModbusByte)*2;
01454 
01455         ModbusByte bcnt;        
01456         ModbusData numfile;     
01457         ModbusData numpacks;     
01458         ModbusData packet;      
01459         ModbusByte dlen;        
01460         ModbusByte data[MaxDataLen];
01461 
01462     
01463         // ------- from slave -------
01464         FileTransferRetMessage( ModbusMessage& m );
01465         FileTransferRetMessage& operator=( ModbusMessage& m );
01466         void init( ModbusMessage& m );
01467         ModbusCRC crc;
01468         static int szHead(){ return sizeof(ModbusByte); }
01469         static int getDataLen( ModbusMessage& m );
01470         
01471         // ------- to master -------
01472         FileTransferRetMessage( ModbusAddr _from );
01473 
01477         bool set( ModbusData numfile, ModbusData file_num_packets, ModbusData packet, ModbusByte* b, ModbusByte len );
01478 
01480         void clear();
01481         
01483         size_t szData();
01484         
01486         ModbusMessage transport_msg();
01487     };
01488 
01489     std::ostream& operator<<(std::ostream& os, FileTransferRetMessage& m ); 
01490     std::ostream& operator<<(std::ostream& os, FileTransferRetMessage* m );
01491     // -----------------------------------------------------------------------
01492 } // end of ModbusRTU namespace
01493 // ---------------------------------------------------------------------------
01494 namespace ModbusTCP
01495 {
01496     struct MBAPHeader
01497     {
01498         ModbusRTU::ModbusData    tID; 
01499         ModbusRTU::ModbusData    pID; 
01500         ModbusRTU::ModbusData    len; 
01501 /*        ModbusRTU::ModbusByte    uID; */  /* <------- see ModbusHeader */
01502 
01503         MBAPHeader():tID(0),pID(0) /*,uID(0) */{}
01504         
01505         void swapdata();
01506 
01507     }__attribute__((packed));
01508 
01509     std::ostream& operator<<(std::ostream& os, MBAPHeader& m ); 
01510 
01511   // -----------------------------------------------------------------------
01512 } // end of namespace ModbusTCP
01513 // ---------------------------------------------------------------------------
01514 #endif // ModbusTypes_H_
01515 // ---------------------------------------------------------------------------