UniSet  1.4.0
ModbusTypes.h
00001 // -------------------------------------------------------------------------
00002 #ifndef ModbusTypes_H_
00003 #define ModbusTypes_H_
00004 // -------------------------------------------------------------------------
00005 #include <ostream>
00006 #include <bitset>
00007 #include "ModbusRTUErrors.h"
00008 // -------------------------------------------------------------------------
00009 /* Основные предположения: 
00010  * - младший и старший байт переворачиваются только в CRC
00011  * - В случае неправильного формата пакета(запроса), логической ошибки и т.п
00012  *      ОТВЕТ просто не посылается, а пакет отбрасывается...
00013  * - CRC считается по всей посылке (с начальным адресом)
00014  * - CRC инициализируется значением 0xffff
00015  * - CRC не переворачивается
00016  * - Все двухбайтовые слова переворачиваются. Порядок байт: старший младший
00017 */
00018 // -------------------------------------------------------------------------
00019 namespace ModbusRTU
00020 {
00021     // Базовые типы 
00022     typedef unsigned char ModbusByte;   
00023     const int BitsPerByte = 8;
00024     typedef unsigned char ModbusAddr;   
00025     typedef unsigned short ModbusData;  
00026     const int BitsPerData = 16;
00027     typedef unsigned short ModbusCRC;   
00029     // ---------------------------------------------------------------------
00031     enum SlaveFunctionCode
00032     {
00033         fnUnknown               = 0x00,
00034         fnReadCoilStatus        = 0x01, 
00035         fnReadInputStatus       = 0x02, 
00036         fnReadOutputRegisters   = 0x03, 
00037         fnReadInputRegisters    = 0x04, 
00038         fnForceSingleCoil       = 0x05, 
00039         fnWriteOutputSingleRegister = 0x06, 
00040         fnDiagnostics           = 0x08, 
00041         fnForceMultipleCoils    = 0x0F, 
00042         fnWriteOutputRegisters  = 0x10, 
00043         fnReadFileRecord        = 0x14, 
00044         fnWriteFileRecord       = 0x15, 
00045         fnSetDateTime           = 0x50, 
00046         fnRemoteService         = 0x53, 
00047         fnJournalCommand        = 0x65, 
00048         fnFileTransfer          = 0x66  
00049     };
00050 
00052     enum DiagnosticsSubFunction
00053     {
00054         subEcho = 0x00,         
00055         dgRestartComm = 0x01,   
00056         dgDiagReg = 0x02,       
00057         dgChangeASCII = 0x03,   
00058         dgForceListen = 0x04,   
00059         // 05.. 09 RESERVED
00060         dgClearCounters = 0x0A,     
00061         dgBusMsgCount = 0x0B,       
00062         dgBusErrCount = 0x0C,       
00063         dgBusExceptCount = 0x0D,    
00064         dgMsgSlaveCount = 0x0E,     
00065         dgNoNoResponseCount = 0x0F, 
00066         dgSlaveNAKCount = 0x10,     
00067         dgSlaveBusyCount = 0x11,        
00068         dgBusCharOverrunCount = 0x12,   
00069          // = 0x13, /*!<  RESERVED */
00070         dgClearOverrunCounter = 0x14    
00071          // 21 ...65535 RESERVED
00072     };
00073     
00074     // определение размера данных в зависимости от типа сообщения
00075     // возвращает -1 - если динамический размер сообщения или размер неизвестен
00076     int szRequestDiagnosticData( DiagnosticsSubFunction f );
00077 
00079     enum
00080     {
00082         MAXLENPACKET    = 508,  
00083         BroadcastAddr   = 255,  
00084         MAXDATALEN      = 127   
00088     };
00089 
00090     const unsigned char MBErrMask = 0x80;
00091     // ---------------------------------------------------------------------
00092     unsigned short SWAPSHORT(unsigned short x);
00093     // ---------------------------------------------------------------------
00095     ModbusCRC checkCRC( ModbusByte* start, int len );
00096     const int szCRC = sizeof(ModbusCRC); 
00097     // ---------------------------------------------------------------------
00099     std::ostream& mbPrintMessage( std::ostream& os, ModbusByte* b, int len );
00100     // -------------------------------------------------------------------------
00101     ModbusAddr str2mbAddr( const std::string val );
00102     ModbusData str2mbData( const std::string val );
00103     std::string dat2str( const ModbusData dat );
00104     std::string addr2str( const ModbusAddr addr );
00105     std::string b2str( const ModbusByte b );
00106     // -------------------------------------------------------------------------
00107     float dat2f( const ModbusData dat1, const ModbusData dat2 );
00108     // -------------------------------------------------------------------------
00109     bool isWriteFunction( SlaveFunctionCode c );
00110     // -------------------------------------------------------------------------
00112     struct ModbusHeader
00113     {
00114         ModbusAddr addr;        
00115         ModbusByte func;        
00117         ModbusHeader():addr(0),func(0){}
00118     }__attribute__((packed));
00119 
00120     const int szModbusHeader = sizeof(ModbusHeader);
00121     std::ostream& operator<<(std::ostream& os, ModbusHeader& m );
00122     std::ostream& operator<<(std::ostream& os, ModbusHeader* m );
00123     // -----------------------------------------------------------------------
00124 
00128     struct ModbusMessage:
00129         public ModbusHeader
00130     {
00131         ModbusMessage();
00132         ModbusByte data[MAXLENPACKET+szCRC];    
00134         // Это поле вспомогательное и игнорируется при пересылке
00135         int len;    
00136     }__attribute__((packed));
00137 
00138     std::ostream& operator<<(std::ostream& os, ModbusMessage& m );
00139     std::ostream& operator<<(std::ostream& os, ModbusMessage* m );
00140     // -----------------------------------------------------------------------
00142     struct ErrorRetMessage:
00143         public ModbusHeader
00144     {
00145         ModbusByte ecode;
00146         ModbusCRC crc;
00147         
00148         // ------- from slave -------
00149         ErrorRetMessage( ModbusMessage& m );
00150         ErrorRetMessage& operator=( ModbusMessage& m );
00151         void init( ModbusMessage& m );
00152         
00153         // ------- to master -------
00154         ErrorRetMessage( ModbusAddr _from, ModbusByte _func, ModbusByte ecode );
00155 
00157         ModbusMessage transport_msg();
00158 
00162         inline static int szData(){ return sizeof(ModbusByte)+szCRC; }
00163     };
00164 
00165     std::ostream& operator<<(std::ostream& os, ErrorRetMessage& m ); 
00166     std::ostream& operator<<(std::ostream& os, ErrorRetMessage* m ); 
00167     // -----------------------------------------------------------------------
00168     struct DataBits
00169     {   
00170         DataBits( ModbusByte b );
00171         DataBits( std::string s ); // example "10001111"
00172         DataBits();
00173         
00174         const DataBits& operator=(const ModbusByte& r);
00175 
00176         operator ModbusByte();
00177         ModbusByte mbyte();
00178         
00179         bool operator[]( const int i ){ return b[i]; }
00180         
00181         std::bitset<BitsPerByte> b;
00182     };
00183 
00184     std::ostream& operator<<(std::ostream& os, DataBits& m );
00185     std::ostream& operator<<(std::ostream& os, DataBits* m ); 
00186     // -----------------------------------------------------------------------
00187     struct DataBits16
00188     {   
00189         DataBits16( ModbusData d );
00190         DataBits16( std::string s ); // example "1000111110001111"
00191         DataBits16();
00192         
00193         const DataBits16& operator=(const ModbusData& r);
00194 
00195         operator ModbusData();
00196         ModbusData mdata();
00197         
00198         bool operator[]( const int i ){ return b[i]; }
00199         void set( int n, bool s ){ b.set(n,s); }
00200         
00201         std::bitset<BitsPerData> b;
00202     };
00203 
00204     std::ostream& operator<<(std::ostream& os, DataBits16& m );
00205     std::ostream& operator<<(std::ostream& os, DataBits16* m ); 
00206     // -----------------------------------------------------------------------
00208     struct ReadCoilMessage:
00209         public ModbusHeader
00210     {
00211         ModbusData start;
00212         ModbusData count;
00213         ModbusCRC crc;
00214         
00215         // ------- to slave -------
00216         ReadCoilMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00218         ModbusMessage transport_msg();
00219 
00220         // ------- from master -------
00221         ReadCoilMessage( ModbusMessage& m );
00222         ReadCoilMessage& operator=( ModbusMessage& m );
00223         void init( ModbusMessage& m );
00224 
00226         inline static int szData(){ return sizeof(ModbusData)*2 + szCRC; }
00227 
00228     }__attribute__((packed));
00229 
00230     std::ostream& operator<<(std::ostream& os, ReadCoilMessage& m ); 
00231     std::ostream& operator<<(std::ostream& os, ReadCoilMessage* m ); 
00232 
00233     // -----------------------------------------------------------------------
00234     
00236     struct ReadCoilRetMessage:
00237         public ModbusHeader
00238     {
00239         ModbusByte bcnt;                
00240         ModbusByte data[MAXLENPACKET];  
00242         // ------- from slave -------
00243         ReadCoilRetMessage( ModbusMessage& m );
00244         ReadCoilRetMessage& operator=( ModbusMessage& m );
00245         void init( ModbusMessage& m );
00249         static inline int szHead()
00250         {
00251             return sizeof(ModbusByte); // bcnt
00252         }
00253 
00255         static int getDataLen( ModbusMessage& m );
00256         ModbusCRC crc;
00257         
00258         // ------- to master -------
00259         ReadCoilRetMessage( ModbusAddr _from );
00260 
00265         bool addData( DataBits d );
00266 
00274         bool setBit( unsigned char dnum, unsigned char bnum, bool state );
00275 
00282         bool getData( unsigned char bnum, DataBits& d );
00283 
00285         void clear();
00286         
00288         inline bool isFull()
00289         {
00290             return ( bcnt >= MAXLENPACKET );
00291         }
00292 
00294         int szData();
00295         
00297         ModbusMessage transport_msg();
00298     };
00299 
00300     std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage& m );
00301     std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage* m );
00302     // -----------------------------------------------------------------------
00304     struct ReadInputStatusMessage:
00305         public ModbusHeader
00306     {
00307         ModbusData start;
00308         ModbusData count;
00309         ModbusCRC crc;
00310         
00311         // ------- to slave -------
00312         ReadInputStatusMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00314         ModbusMessage transport_msg();
00315 
00316         // ------- from master -------
00317         ReadInputStatusMessage( ModbusMessage& m );
00318         ReadInputStatusMessage& operator=( ModbusMessage& m );
00319         void init( ModbusMessage& m );
00320 
00322         inline static int szData(){ return sizeof(ModbusData)*2 + szCRC; }
00323 
00324     }__attribute__((packed));
00325 
00326     std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage& m ); 
00327     std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage* m ); 
00328     // -----------------------------------------------------------------------
00330     struct ReadInputStatusRetMessage:
00331         public ModbusHeader
00332     {
00333         ModbusByte bcnt;                
00334         ModbusByte data[MAXLENPACKET];  
00336         // ------- from slave -------
00337         ReadInputStatusRetMessage( ModbusMessage& m );
00338         ReadInputStatusRetMessage& operator=( ModbusMessage& m );
00339         void init( ModbusMessage& m );
00343         static inline int szHead()
00344         {
00345             return sizeof(ModbusByte); // bcnt
00346         }
00347 
00349         static int getDataLen( ModbusMessage& m );
00350         ModbusCRC crc;
00351         
00352         // ------- to master -------
00353         ReadInputStatusRetMessage( ModbusAddr _from );
00354 
00359         bool addData( DataBits d );
00360 
00368         bool setBit( unsigned char dnum, unsigned char bnum, bool state );
00369 
00376         bool getData( unsigned char dnum, DataBits& d );
00377 
00379         void clear();
00380         
00382         inline bool isFull()        
00383         {
00384             return ( bcnt >= MAXLENPACKET );
00385         }
00386 
00388         int szData();
00389         
00391         ModbusMessage transport_msg();
00392     };
00393 
00394     std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage& m );
00395     std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage* m );
00396     // -----------------------------------------------------------------------
00397 
00399     struct ReadOutputMessage:
00400         public ModbusHeader
00401     {
00402         ModbusData start;
00403         ModbusData count;
00404         ModbusCRC crc;
00405         
00406         // ------- to slave -------
00407         ReadOutputMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00409         ModbusMessage transport_msg();
00410 
00411         // ------- from master -------
00412         ReadOutputMessage( ModbusMessage& m );
00413         ReadOutputMessage& operator=( ModbusMessage& m );
00414         void init( ModbusMessage& m );
00415 
00417         inline static int szData(){ return sizeof(ModbusData)*2 + szCRC; }
00418 
00419     }__attribute__((packed));
00420 
00421     std::ostream& operator<<(std::ostream& os, ReadOutputMessage& m ); 
00422     std::ostream& operator<<(std::ostream& os, ReadOutputMessage* m ); 
00423     // -----------------------------------------------------------------------
00425     struct ReadOutputRetMessage:
00426         public ModbusHeader
00427     {
00428         ModbusByte bcnt;                                    
00429         ModbusData data[MAXLENPACKET/sizeof(ModbusData)];   
00431         // ------- from slave -------
00432         ReadOutputRetMessage( ModbusMessage& m );
00433         ReadOutputRetMessage& operator=( ModbusMessage& m );
00434         void init( ModbusMessage& m );
00438         static inline int szHead()
00439         {
00440             // bcnt
00441             return sizeof(ModbusByte);
00442         }
00443 
00445         static int getDataLen( ModbusMessage& m );
00446         ModbusCRC crc;
00447         
00448         // ------- to master -------
00449         ReadOutputRetMessage( ModbusAddr _from );
00450 
00455         bool addData( ModbusData d );
00456 
00458         void clear();
00459         
00461         inline bool isFull()        
00462         {
00463             return ( count*sizeof(ModbusData) >= MAXLENPACKET );
00464         }
00465 
00467         int szData();
00468         
00470         ModbusMessage transport_msg();
00471         
00472         // Это поле не входит в стандарт modbus
00473         // оно вспомогательное и игнорируется при 
00474         // преобразовании в ModbusMessage.
00475         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 
00476         // Используйте специальную функцию transport_msg()
00477         int count;  
00478     };
00479 
00480     std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage& m );
00481     std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage* m );
00482     // -----------------------------------------------------------------------
00484     struct ReadInputMessage:
00485         public ModbusHeader
00486     {
00487         ModbusData start;
00488         ModbusData count;
00489         ModbusCRC crc;
00490         
00491         // ------- to slave -------
00492         ReadInputMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00494         ModbusMessage transport_msg();
00495 
00496         // ------- from master -------
00497         ReadInputMessage( ModbusMessage& m );
00498         ReadInputMessage& operator=( ModbusMessage& m );
00499         void init( ModbusMessage& m );
00500 
00502         inline static int szData(){ return sizeof(ModbusData)*2 + szCRC; }
00503 
00504     }__attribute__((packed));
00505 
00506     std::ostream& operator<<(std::ostream& os, ReadInputMessage& m ); 
00507     std::ostream& operator<<(std::ostream& os, ReadInputMessage* m ); 
00508     // -----------------------------------------------------------------------
00509 
00511     struct ReadInputRetMessage:
00512         public ModbusHeader
00513     {
00514         ModbusByte bcnt;                                    
00515         ModbusData data[MAXLENPACKET/sizeof(ModbusData)];   
00517         // ------- from slave -------
00518         ReadInputRetMessage( ModbusMessage& m );
00519         ReadInputRetMessage& operator=( ModbusMessage& m );
00520         void init( ModbusMessage& m );
00524         static inline int szHead()
00525         {
00526             // bcnt
00527             return sizeof(ModbusByte);
00528         }
00529 
00531         static int getDataLen( ModbusMessage& m );
00532         ModbusCRC crc;
00533         
00534         // ------- to master -------
00535         ReadInputRetMessage( ModbusAddr _from );
00536 
00541         bool addData( ModbusData d );
00542 
00544         void clear();
00545         
00547         inline bool isFull()
00548         {
00549             return ( count*sizeof(ModbusData) >= MAXLENPACKET );
00550         }
00551         
00552         void swapData();
00553 
00555         int szData();
00556         
00558         ModbusMessage transport_msg();
00559         
00560         // Это поле не входит в стандарт modbus
00561         // оно вспомогательное и игнорируется при 
00562         // преобразовании в ModbusMessage.
00563         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 
00564         // Используйте специальную функцию transport_msg()
00565         int count;  
00566     };
00567 
00568     std::ostream& operator<<(std::ostream& os, ReadInputRetMessage& m );
00569     std::ostream& operator<<(std::ostream& os, ReadInputRetMessage* m );
00570     // -----------------------------------------------------------------------
00572     struct ForceCoilsMessage:
00573         public ModbusHeader
00574     {
00575         ModbusData start;   
00576         ModbusData quant;   
00577         ModbusByte bcnt;    
00579         ModbusByte data[MAXLENPACKET-sizeof(ModbusData)*2-sizeof(ModbusByte)];
00580         ModbusCRC crc;      
00582         // ------- to slave -------
00583         ForceCoilsMessage( ModbusAddr addr, ModbusData start );
00585         ModbusMessage transport_msg();
00586 
00591         bool addData( DataBits d );
00592         
00593         // return number of bit
00594         // -1 - error
00595         int addBit( bool state );
00596         
00597         bool setBit( int nbit, bool state );
00598         
00599         inline int last(){ return quant; }
00600 
00607         bool getData( unsigned char dnum, DataBits& d );
00608         
00609         bool getBit( unsigned char bnum );
00610 
00611         void clear();
00612         inline bool isFull()
00613         {
00614             return ( bcnt >= MAXLENPACKET );
00615         }
00616 
00617         // ------- from master -------  
00618         ForceCoilsMessage( ModbusMessage& m );
00619         ForceCoilsMessage& operator=( ModbusMessage& m );
00620         void init( ModbusMessage& m );
00621 
00623         int szData();
00624 
00628         static inline int szHead()
00629         {
00630             // start + quant + count
00631             return sizeof(ModbusData)*2+sizeof(ModbusByte);
00632         }
00633         
00635         static int getDataLen( ModbusMessage& m );
00636 
00640         bool checkFormat();
00641         
00642     }__attribute__((packed));
00643 
00644     std::ostream& operator<<(std::ostream& os, ForceCoilsMessage& m );
00645     std::ostream& operator<<(std::ostream& os, ForceCoilsMessage* m );
00646     // -----------------------------------------------------------------------
00648     struct ForceCoilsRetMessage:
00649         public ModbusHeader
00650     {
00651         ModbusData start;   
00652         ModbusData quant;   
00653         ModbusCRC crc;
00654 
00655         // ------- from slave -------
00656         ForceCoilsRetMessage( ModbusMessage& m );
00657         ForceCoilsRetMessage& operator=( ModbusMessage& m );
00658         void init( ModbusMessage& m );
00659         
00660         // ------- to master -------
00666         ForceCoilsRetMessage( ModbusAddr _from, ModbusData start=0, ModbusData quant=0 );
00667 
00669         void set( ModbusData start, ModbusData quant );
00670 
00672         ModbusMessage transport_msg();
00673         
00677         inline static int szData(){ return sizeof(ModbusData)*2+sizeof(ModbusCRC); }
00678     };
00679     
00680     std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage& m );
00681     std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage* m );
00682     // -----------------------------------------------------------------------
00683 
00685     struct WriteOutputMessage:
00686         public ModbusHeader
00687     {
00688         ModbusData start;   
00689         ModbusData quant;   
00690         ModbusByte bcnt;    
00692         ModbusData data[MAXLENPACKET/sizeof(ModbusData)-sizeof(ModbusData)*2-sizeof(ModbusByte)];
00693         ModbusCRC crc;      
00695         // ------- to slave -------
00696         WriteOutputMessage( ModbusAddr addr, ModbusData start );
00698         ModbusMessage transport_msg();
00699 
00700         bool addData( ModbusData d );
00701         void clear();
00702         inline bool isFull()        
00703         {
00704             return ( quant*sizeof(ModbusData) >= MAXLENPACKET );
00705         }
00706 
00707         // ------- from master -------  
00708         WriteOutputMessage( ModbusMessage& m );
00709         WriteOutputMessage& operator=( ModbusMessage& m );
00710         void init( ModbusMessage& m );
00711 
00713         int szData();
00714 
00718         static inline int szHead()
00719         {
00720             // start + quant + count
00721             return sizeof(ModbusData)*2+sizeof(ModbusByte);
00722         }
00723         
00725         static int getDataLen( ModbusMessage& m );
00726 
00730         bool checkFormat();
00731         
00732     }__attribute__((packed));
00733 
00734 
00735     std::ostream& operator<<(std::ostream& os, WriteOutputMessage& m );
00736     std::ostream& operator<<(std::ostream& os, WriteOutputMessage* m );
00737 
00739     struct WriteOutputRetMessage:
00740         public ModbusHeader
00741     {
00742         ModbusData start;   
00743         ModbusData quant;   
00745         // ------- from slave -------
00746         WriteOutputRetMessage( ModbusMessage& m );
00747         WriteOutputRetMessage& operator=( ModbusMessage& m );
00748         void init( ModbusMessage& m );
00749         ModbusCRC crc;
00750 
00751         // ------- to master -------
00757         WriteOutputRetMessage( ModbusAddr _from, ModbusData start=0, ModbusData quant=0 );
00758 
00760         void set( ModbusData start, ModbusData quant );
00761 
00763         ModbusMessage transport_msg();
00764         
00768         inline static int szData(){ return sizeof(ModbusData)*2+sizeof(ModbusCRC); }
00769     };
00770     
00771     std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage& m );
00772     std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage* m );
00773     // -----------------------------------------------------------------------
00775     struct ForceSingleCoilMessage:
00776         public ModbusHeader
00777     {
00778         ModbusData start;   
00779         ModbusData data;    
00780         ModbusCRC crc;      
00783         inline bool cmd()
00784         {
00785             return (data & 0xFF00);
00786         }
00787 
00788 
00789         // ------- to slave -------
00790         ForceSingleCoilMessage( ModbusAddr addr, ModbusData reg, bool state );
00792         ModbusMessage transport_msg();
00793     
00794         // ------- from master -------
00795         ForceSingleCoilMessage( ModbusMessage& m );
00796         ForceSingleCoilMessage& operator=( ModbusMessage& m );
00797         void init( ModbusMessage& m );
00798 
00800         int szData();
00801 
00805         static inline int szHead()
00806         {
00807             return sizeof(ModbusData);
00808         }
00809         
00813         static int getDataLen( ModbusMessage& m );
00814 
00818         bool checkFormat();
00819     }__attribute__((packed));
00820 
00821 
00822     std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage& m );
00823     std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage* m );
00824     // -----------------------------------------------------------------------
00825 
00827     struct ForceSingleCoilRetMessage:
00828         public ModbusHeader
00829     {
00830         ModbusData start;   
00831         ModbusData data;    
00832         ModbusCRC crc;
00833 
00834 
00835         // ------- from slave -------
00836         ForceSingleCoilRetMessage( ModbusMessage& m );
00837         ForceSingleCoilRetMessage& operator=( ModbusMessage& m );
00838         void init( ModbusMessage& m );
00839 
00840         // ------- to master -------
00845         ForceSingleCoilRetMessage( ModbusAddr _from );
00846 
00848         void set( ModbusData start, bool cmd );
00849 
00851         ModbusMessage transport_msg();
00852         
00856         inline static int szData(){ return 2*sizeof(ModbusData)+sizeof(ModbusCRC); }
00857     };
00858     
00859     std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage& m );
00860     std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage* m );
00861     // -----------------------------------------------------------------------
00862 
00864     struct WriteSingleOutputMessage:
00865         public ModbusHeader
00866     {
00867         ModbusData start;   
00868         ModbusData data;    
00869         ModbusCRC crc;      
00872         // ------- to slave -------
00873         WriteSingleOutputMessage( ModbusAddr addr, ModbusData reg=0, ModbusData data=0 );
00875         ModbusMessage transport_msg();
00876     
00877         // ------- from master -------
00878         WriteSingleOutputMessage( ModbusMessage& m );
00879         WriteSingleOutputMessage& operator=( ModbusMessage& m );
00880         void init( ModbusMessage& m );
00881 
00883         int szData();
00884 
00888         static inline int szHead()
00889         {
00890             return sizeof(ModbusData);
00891         }
00892         
00896         static int getDataLen( ModbusMessage& m );
00897 
00901         bool checkFormat();
00902     }__attribute__((packed));
00903 
00904 
00905     std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage& m );
00906     std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage* m );
00907     // -----------------------------------------------------------------------
00908 
00910     struct WriteSingleOutputRetMessage:
00911         public ModbusHeader
00912     {
00913         ModbusData start;   
00914         ModbusData data;    
00915         ModbusCRC crc;
00916 
00917 
00918         // ------- from slave -------
00919         WriteSingleOutputRetMessage( ModbusMessage& m );
00920         WriteSingleOutputRetMessage& operator=( ModbusMessage& m );
00921         void init( ModbusMessage& m );
00922 
00923         // ------- to master -------
00928         WriteSingleOutputRetMessage( ModbusAddr _from, ModbusData start=0 );
00929 
00931         void set( ModbusData start, ModbusData data );
00932 
00934         ModbusMessage transport_msg();
00935         
00939         inline static int szData(){ return 2*sizeof(ModbusData)+sizeof(ModbusCRC); }
00940     };
00941     
00942     std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage& m );
00943     std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage* m );
00944     // -----------------------------------------------------------------------
00946     struct DiagnosticMessage:
00947         public ModbusHeader
00948     {
00949         ModbusData subf;
00950         ModbusData data[MAXLENPACKET/sizeof(ModbusData)];   
00952         // ------- from slave -------
00953         DiagnosticMessage( ModbusMessage& m );
00954         DiagnosticMessage& operator=( ModbusMessage& m );
00955         void init( ModbusMessage& m );
00959         static inline int szHead()
00960         {
00961             return sizeof(ModbusData); // subf
00962         }
00963 
00965         static int getDataLen( ModbusMessage& m );
00966         ModbusCRC crc;
00967         
00968         // ------- to master -------
00969         DiagnosticMessage( ModbusAddr _from, DiagnosticsSubFunction subf, ModbusData d=0 );
00970 
00975         bool addData( ModbusData d );
00976 
00978         void clear();
00979         
00981         inline bool isFull()        
00982         {
00983             return ( sizeof(subf)+count*sizeof(ModbusData) >= MAXLENPACKET );
00984         }
00985 
00987         int szData();
00988         
00990         ModbusMessage transport_msg();
00991         
00992         // Это поле не входит в стандарт modbus
00993         // оно вспомогательное и игнорируется при 
00994         // преобразовании в ModbusMessage.
00995         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 
00996         // Используйте специальную функцию transport_msg()
00997         int count;  
00998     };
00999     std::ostream& operator<<(std::ostream& os, DiagnosticMessage& m );
01000     std::ostream& operator<<(std::ostream& os, DiagnosticMessage* m );
01001     // -----------------------------------------------------------------------
01003     struct DiagnosticRetMessage:
01004         public DiagnosticMessage
01005     {
01006         DiagnosticRetMessage( ModbusMessage& m );
01007         DiagnosticRetMessage( DiagnosticMessage& m );
01008         DiagnosticRetMessage( ModbusAddr a, DiagnosticsSubFunction subf, ModbusData d=0 );
01009     };
01010 
01011     std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage& m );
01012     std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage* m );
01013     // -----------------------------------------------------------------------
01014 
01016     struct JournalCommandMessage:
01017         public ModbusHeader
01018     {
01019         ModbusData cmd;         
01020         ModbusData num;         
01021         ModbusCRC crc;
01022         
01023         // -------------
01024         JournalCommandMessage( ModbusMessage& m );
01025         JournalCommandMessage& operator=( ModbusMessage& m );
01026 
01028         inline static int szData(){ return sizeof(ModbusByte)*4 + szCRC; }
01029 
01030     }__attribute__((packed));
01031 
01032     std::ostream& operator<<(std::ostream& os, JournalCommandMessage& m ); 
01033     std::ostream& operator<<(std::ostream& os, JournalCommandMessage* m ); 
01034     // -----------------------------------------------------------------------
01036     struct JournalCommandRetMessage:
01037         public ModbusHeader
01038     {
01039         ModbusByte bcnt;                    
01040 //      ModbusByte data[MAXLENPACKET-1];    /*!< данные */
01041 
01042         // В связи со спецификой реализации ответной части (т.е. modbus master)
01043         // данные приходится делать не байтовым потоком, а "словами"
01044         // которые в свою очередь будут перевёрнуты при посылке...
01045         ModbusData data[MAXLENPACKET/sizeof(ModbusData)];   
01047         // -------------
01048         JournalCommandRetMessage( ModbusAddr _from );
01049 
01056         bool setData( ModbusByte* b, int len );
01057 
01059         void clear();
01060         
01062         inline bool isFull()        
01063         {
01064             return ( count*sizeof(ModbusData) >= MAXLENPACKET );
01065         }
01066 
01068         int szData();
01069         
01071         ModbusMessage transport_msg();
01072         
01073         // Это поле не входит в стандарт modbus
01074         // оно вспомогательное и игнорируется при 
01075         // преобразовании в ModbusMessage.
01076         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 
01077         // Используйте специальную функцию transport_msg()
01078         int count;  
01079     };
01080 
01081     std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage& m );
01082     std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage* m );
01083     // -----------------------------------------------------------------------
01087     struct JournalCommandRetOK:
01088         public JournalCommandRetMessage
01089     {
01090         // -------------
01091         JournalCommandRetOK( ModbusAddr _from );
01092         void set( ModbusData cmd, ModbusData ecode );
01093         static void set( JournalCommandRetMessage& m, ModbusData cmd, ModbusData ecode );
01094     };
01095 
01096     std::ostream& operator<<(std::ostream& os, JournalCommandRetOK& m ); 
01097     std::ostream& operator<<(std::ostream& os, JournalCommandRetOK* m ); 
01098     // -----------------------------------------------------------------------
01099 
01101     struct SetDateTimeMessage:
01102         public ModbusHeader
01103     {
01104         ModbusByte hour;    
01105         ModbusByte min;     
01106         ModbusByte sec;     
01107         ModbusByte day;     
01108         ModbusByte mon;     
01109         ModbusByte year;    
01110         ModbusByte century; 
01112         ModbusCRC crc;
01113         
01114         // ------- to slave -------
01115         SetDateTimeMessage( ModbusAddr addr );
01117         ModbusMessage transport_msg();
01118         
01119         // ------- from master -------
01120         SetDateTimeMessage( ModbusMessage& m );
01121         SetDateTimeMessage& operator=( ModbusMessage& m );
01122         SetDateTimeMessage();
01123 
01124         bool checkFormat();
01125 
01127         inline static int szData(){ return sizeof(ModbusByte)*7 + szCRC; }
01128 
01129     }__attribute__((packed));
01130 
01131     std::ostream& operator<<(std::ostream& os, SetDateTimeMessage& m ); 
01132     std::ostream& operator<<(std::ostream& os, SetDateTimeMessage* m ); 
01133     // -----------------------------------------------------------------------
01134 
01136     struct SetDateTimeRetMessage:
01137         public SetDateTimeMessage
01138     {
01139 
01140         // ------- from slave -------
01141         SetDateTimeRetMessage( ModbusMessage& m );
01142         SetDateTimeRetMessage& operator=( ModbusMessage& m );
01143         void init( ModbusMessage& m );
01144 
01145         // ------- to master -------
01146         SetDateTimeRetMessage( ModbusAddr _from );
01147         SetDateTimeRetMessage( const SetDateTimeMessage& query );
01148         static void cpy( SetDateTimeRetMessage& reply, SetDateTimeMessage& query );
01149 
01151         ModbusMessage transport_msg();
01152     };
01153     // -----------------------------------------------------------------------
01154 
01156     struct RemoteServiceMessage:
01157         public ModbusHeader
01158     {
01159         ModbusByte bcnt;    
01162         ModbusByte data[MAXLENPACKET-sizeof(ModbusByte)];
01163         ModbusCRC crc;      
01165         // -----------
01166         RemoteServiceMessage( ModbusMessage& m );
01167         RemoteServiceMessage& operator=( ModbusMessage& m );
01168         void init( ModbusMessage& m );
01169 
01171         int szData();
01172 
01176         static inline int szHead()
01177         { return sizeof(ModbusByte); } // bcnt
01178         
01180         static int getDataLen( ModbusMessage& m );
01181 
01182     }__attribute__((packed));
01183 
01184     std::ostream& operator<<(std::ostream& os, RemoteServiceMessage& m ); 
01185     std::ostream& operator<<(std::ostream& os, RemoteServiceMessage* m ); 
01186     // -----------------------------------------------------------------------
01187     struct RemoteServiceRetMessage:
01188         public ModbusHeader
01189     {
01190         ModbusByte bcnt;    
01192         ModbusByte data[MAXLENPACKET-sizeof(ModbusByte)];
01193 
01194         RemoteServiceRetMessage( ModbusAddr _from );
01195 
01202         bool setData( ModbusByte* b, int len );
01203 
01205         void clear();
01206         
01208         inline bool isFull()        
01209             { return ( count >= sizeof(data) ); }
01210 
01212         int szData();
01213         
01215         ModbusMessage transport_msg();
01216         
01217         // Это поле не входит в стандарт modbus
01218         // оно вспомогательное и игнорируется при 
01219         // преобразовании в ModbusMessage.
01220         unsigned int    count;  
01221     };
01222     // -----------------------------------------------------------------------
01223 
01224     struct ReadFileRecordMessage:
01225         public ModbusHeader
01226     {
01227         struct SubRequest
01228         {
01229             ModbusByte reftype; 
01230             ModbusData numfile; 
01231             ModbusData numrec;  
01232             ModbusData reglen;  
01233         }__attribute__((packed));   
01234 
01235         ModbusByte bcnt;    
01238         SubRequest data[MAXLENPACKET/sizeof(SubRequest)-sizeof(ModbusByte)];
01239         ModbusCRC crc;      
01241         // -----------
01242         ReadFileRecordMessage( ModbusMessage& m );
01243         ReadFileRecordMessage& operator=( ModbusMessage& m );
01244         void init( ModbusMessage& m );
01245 
01247         int szData();
01248 
01252         static inline int szHead()
01253         { return sizeof(ModbusByte); } // bcnt
01254         
01256         static int getDataLen( ModbusMessage& m );
01257 
01259         bool checkFormat();
01260         
01261         // это поле служебное и не используется в релальном обмене
01262         int count; 
01263     };
01264 
01265     std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage& m ); 
01266     std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage* m ); 
01267     // -----------------------------------------------------------------------
01268 
01269     struct FileTransferMessage:
01270         public ModbusHeader
01271     {
01272         ModbusData numfile;     
01273         ModbusData numpacket;   
01274         ModbusCRC crc;          
01276         // ------- to slave -------
01277         FileTransferMessage( ModbusAddr addr, ModbusData numfile, ModbusData numpacket );
01278         ModbusMessage transport_msg();  
01280         // ------- from master -------
01281         FileTransferMessage( ModbusMessage& m );
01282         FileTransferMessage& operator=( ModbusMessage& m );
01283         void init( ModbusMessage& m );
01284 
01286         static inline int szData()
01287         {   return sizeof(ModbusData)*2 + szCRC; }
01288 
01289     }__attribute__((packed));
01290 
01291     std::ostream& operator<<(std::ostream& os, FileTransferMessage& m ); 
01292     std::ostream& operator<<(std::ostream& os, FileTransferMessage* m ); 
01293     // -----------------------------------------------------------------------
01294 
01295     struct FileTransferRetMessage:
01296         public ModbusHeader
01297     {
01298         // 255 - max of bcnt...(1 byte)     
01299 //      static const int MaxDataLen = 255 - szCRC - szModbusHeader - sizeof(ModbusData)*3 - sizeof(ModbusByte)*2;
01300         static const int MaxDataLen = MAXLENPACKET - sizeof(ModbusData)*3 - sizeof(ModbusByte)*2;
01301 
01302         ModbusByte bcnt;        
01303         ModbusData numfile;     
01304         ModbusData numpacks;    
01305         ModbusData packet;      
01306         ModbusByte dlen;        
01307         ModbusByte data[MaxDataLen];
01308 
01309     
01310         // ------- from slave -------
01311         FileTransferRetMessage( ModbusMessage& m );
01312         FileTransferRetMessage& operator=( ModbusMessage& m );
01313         void init( ModbusMessage& m );
01314         ModbusCRC crc;
01315         static int szHead(){ return sizeof(ModbusByte); }
01316         static int getDataLen( ModbusMessage& m );
01317         
01318         // ------- to master -------
01319         FileTransferRetMessage( ModbusAddr _from );
01320 
01324         bool set( ModbusData numfile, ModbusData file_num_packets, ModbusData packet, ModbusByte* b, ModbusByte len );
01325 
01327         void clear();
01328         
01330         int szData();
01331         
01333         ModbusMessage transport_msg();
01334     };
01335 
01336     std::ostream& operator<<(std::ostream& os, FileTransferRetMessage& m ); 
01337     std::ostream& operator<<(std::ostream& os, FileTransferRetMessage* m );
01338     // -----------------------------------------------------------------------
01339 } // end of ModbusRTU namespace
01340 // ---------------------------------------------------------------------------
01341 namespace ModbusTCP
01342 {
01343     struct MBAPHeader
01344     {
01345         ModbusRTU::ModbusData   tID; 
01346         ModbusRTU::ModbusData   pID; 
01347         ModbusRTU::ModbusData   len; 
01348 /*      ModbusRTU::ModbusByte   uID; */  /* <------- see ModbusHeader */
01349 
01350         MBAPHeader():tID(0),pID(0) /*,uID(0) */{}
01351         
01352         void swapdata();
01353 
01354     }__attribute__((packed));
01355 
01356     std::ostream& operator<<(std::ostream& os, MBAPHeader& m ); 
01357 
01358   // -----------------------------------------------------------------------
01359 } // end of namespace ModbusTCP
01360 // ---------------------------------------------------------------------------
01361 #endif // ModbusTypes_H_
01362 // ---------------------------------------------------------------------------