UniSet  1.7.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 int i ){ return b[i]; }
00211         
00212         std::bitset<BitsPerByte> b;
00213     };
00214 
00215     std::ostream& operator<<(std::ostream& os, DataBits& m );
00216     std::ostream& operator<<(std::ostream& os, DataBits* m ); 
00217     // -----------------------------------------------------------------------
00218     struct DataBits16
00219     {   
00220         DataBits16( ModbusData d );
00221         DataBits16( std::string s ); // example "1000111110001111"
00222         DataBits16();
00223         
00224         const DataBits16& operator=(const ModbusData& r);
00225 
00226         operator ModbusData();
00227         ModbusData mdata();
00228         
00229         bool operator[]( const int i ){ return b[i]; }
00230         void set( int n, bool s ){ b.set(n,s); }
00231         
00232         std::bitset<BitsPerData> b;
00233     };
00234 
00235     std::ostream& operator<<(std::ostream& os, DataBits16& m );
00236     std::ostream& operator<<(std::ostream& os, DataBits16* m ); 
00237     // -----------------------------------------------------------------------
00239     struct ReadCoilMessage:
00240         public ModbusHeader
00241     {
00242         ModbusData start;
00243         ModbusData count;
00244         ModbusCRC crc;
00245         
00246         // ------- to slave -------
00247         ReadCoilMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00249         ModbusMessage transport_msg();
00250 
00251         // ------- from master -------
00252         ReadCoilMessage( ModbusMessage& m );
00253         ReadCoilMessage& operator=( ModbusMessage& m );
00254         void init( ModbusMessage& m );
00255 
00257         inline static int szData(){ return sizeof(ModbusData)*2 + szCRC; }
00258 
00259     }__attribute__((packed));
00260 
00261     std::ostream& operator<<(std::ostream& os, ReadCoilMessage& m ); 
00262     std::ostream& operator<<(std::ostream& os, ReadCoilMessage* m ); 
00263 
00264     // -----------------------------------------------------------------------
00265     
00267     struct ReadCoilRetMessage:
00268         public ModbusHeader
00269     {
00270         ModbusByte bcnt;                
00271         ModbusByte data[MAXLENPACKET];  
00273         // ------- from slave -------
00274         ReadCoilRetMessage( ModbusMessage& m );
00275         ReadCoilRetMessage& operator=( ModbusMessage& m );
00276         void init( ModbusMessage& m );
00280         static inline int szHead()
00281         {
00282             return sizeof(ModbusByte); // bcnt
00283         }
00284 
00286         static int getDataLen( ModbusMessage& m );
00287         ModbusCRC crc;
00288         
00289         // ------- to master -------
00290         ReadCoilRetMessage( ModbusAddr _from );
00291 
00296         bool addData( DataBits d );
00297 
00305         bool setBit( unsigned char dnum, unsigned char bnum, bool state );
00306 
00313         bool getData( unsigned char bnum, DataBits& d );
00314 
00316         void clear();
00317         
00319         inline bool isFull()
00320         {
00321             return ( (int)bcnt >= MAXLENPACKET );
00322         }
00323 
00325         int szData();
00326         
00328         ModbusMessage transport_msg();
00329     };
00330 
00331     std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage& m );
00332     std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage* m );
00333     // -----------------------------------------------------------------------
00335     struct ReadInputStatusMessage:
00336         public ModbusHeader
00337     {
00338         ModbusData start;
00339         ModbusData count;
00340         ModbusCRC crc;
00341         
00342         // ------- to slave -------
00343         ReadInputStatusMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00345         ModbusMessage transport_msg();
00346 
00347         // ------- from master -------
00348         ReadInputStatusMessage( ModbusMessage& m );
00349         ReadInputStatusMessage& operator=( ModbusMessage& m );
00350         void init( ModbusMessage& m );
00351 
00353         inline static int szData(){ return sizeof(ModbusData)*2 + szCRC; }
00354 
00355     }__attribute__((packed));
00356 
00357     std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage& m ); 
00358     std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage* m ); 
00359     // -----------------------------------------------------------------------
00361     struct ReadInputStatusRetMessage:
00362         public ModbusHeader
00363     {
00364         ModbusByte bcnt;                
00365         ModbusByte data[MAXLENPACKET];  
00367         // ------- from slave -------
00368         ReadInputStatusRetMessage( ModbusMessage& m );
00369         ReadInputStatusRetMessage& operator=( ModbusMessage& m );
00370         void init( ModbusMessage& m );
00374         static inline int szHead()
00375         {
00376             return sizeof(ModbusByte); // bcnt
00377         }
00378 
00380         static int getDataLen( ModbusMessage& m );
00381         ModbusCRC crc;
00382         
00383         // ------- to master -------
00384         ReadInputStatusRetMessage( ModbusAddr _from );
00385 
00390         bool addData( DataBits d );
00391 
00399         bool setBit( unsigned char dnum, unsigned char bnum, bool state );
00400 
00407         bool getData( unsigned char dnum, DataBits& d );
00408 
00410         void clear();
00411         
00413         inline bool isFull()        
00414         {
00415             return ( (int)bcnt >= MAXLENPACKET );
00416         }
00417 
00419         int szData();
00420         
00422         ModbusMessage transport_msg();
00423     };
00424 
00425     std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage& m );
00426     std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage* m );
00427     // -----------------------------------------------------------------------
00428 
00430     struct ReadOutputMessage:
00431         public ModbusHeader
00432     {
00433         ModbusData start;
00434         ModbusData count;
00435         ModbusCRC crc;
00436         
00437         // ------- to slave -------
00438         ReadOutputMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00440         ModbusMessage transport_msg();
00441 
00442         // ------- from master -------
00443         ReadOutputMessage( ModbusMessage& m );
00444         ReadOutputMessage& operator=( ModbusMessage& m );
00445         void init( ModbusMessage& m );
00446 
00448         inline static int szData(){ return sizeof(ModbusData)*2 + szCRC; }
00449 
00450     }__attribute__((packed));
00451 
00452     std::ostream& operator<<(std::ostream& os, ReadOutputMessage& m ); 
00453     std::ostream& operator<<(std::ostream& os, ReadOutputMessage* m ); 
00454     // -----------------------------------------------------------------------
00456     struct ReadOutputRetMessage:
00457         public ModbusHeader
00458     {
00459         ModbusByte bcnt;                                    
00460         ModbusData data[MAXLENPACKET/sizeof(ModbusData)];   
00462         // ------- from slave -------
00463         ReadOutputRetMessage( ModbusMessage& m );
00464         ReadOutputRetMessage& operator=( ModbusMessage& m );
00465         void init( ModbusMessage& m );
00469         static inline int szHead()
00470         {
00471             // bcnt
00472             return sizeof(ModbusByte);
00473         }
00474 
00476         static int getDataLen( ModbusMessage& m );
00477         ModbusCRC crc;
00478         
00479         // ------- to master -------
00480         ReadOutputRetMessage( ModbusAddr _from );
00481 
00486         bool addData( ModbusData d );
00487 
00489         void clear();
00490         
00492         inline bool isFull()        
00493         {
00494             return ( count*sizeof(ModbusData) >= MAXLENPACKET );
00495         }
00496 
00498         int szData();
00499         
00501         ModbusMessage transport_msg();
00502         
00503         // Это поле не входит в стандарт modbus
00504         // оно вспомогательное и игнорируется при 
00505         // преобразовании в ModbusMessage.
00506         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 
00507         // Используйте специальную функцию transport_msg()
00508         int count;  
00509     };
00510 
00511     std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage& m );
00512     std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage* m );
00513     // -----------------------------------------------------------------------
00515     struct ReadInputMessage:
00516         public ModbusHeader
00517     {
00518         ModbusData start;
00519         ModbusData count;
00520         ModbusCRC crc;
00521         
00522         // ------- to slave -------
00523         ReadInputMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00525         ModbusMessage transport_msg();
00526 
00527         // ------- from master -------
00528         ReadInputMessage( ModbusMessage& m );
00529         ReadInputMessage& operator=( ModbusMessage& m );
00530         void init( ModbusMessage& m );
00531 
00533         inline static int szData(){ return sizeof(ModbusData)*2 + szCRC; }
00534 
00535     }__attribute__((packed));
00536 
00537     std::ostream& operator<<(std::ostream& os, ReadInputMessage& m ); 
00538     std::ostream& operator<<(std::ostream& os, ReadInputMessage* m ); 
00539     // -----------------------------------------------------------------------
00540 
00542     struct ReadInputRetMessage:
00543         public ModbusHeader
00544     {
00545         ModbusByte bcnt;                                    
00546         ModbusData data[MAXLENPACKET/sizeof(ModbusData)];   
00548         // ------- from slave -------
00549         ReadInputRetMessage( ModbusMessage& m );
00550         ReadInputRetMessage& operator=( ModbusMessage& m );
00551         void init( ModbusMessage& m );
00555         static inline int szHead()
00556         {
00557             // bcnt
00558             return sizeof(ModbusByte);
00559         }
00560 
00562         static int getDataLen( ModbusMessage& m );
00563         ModbusCRC crc;
00564         
00565         // ------- to master -------
00566         ReadInputRetMessage( ModbusAddr _from );
00567 
00572         bool addData( ModbusData d );
00573 
00575         void clear();
00576         
00578         inline bool isFull()
00579         {
00580             return ( count*sizeof(ModbusData) >= MAXLENPACKET );
00581         }
00582         
00583         void swapData();
00584 
00586         int szData();
00587         
00589         ModbusMessage transport_msg();
00590         
00591         // Это поле не входит в стандарт modbus
00592         // оно вспомогательное и игнорируется при 
00593         // преобразовании в ModbusMessage.
00594         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 
00595         // Используйте специальную функцию transport_msg()
00596         int count;  
00597     };
00598 
00599     std::ostream& operator<<(std::ostream& os, ReadInputRetMessage& m );
00600     std::ostream& operator<<(std::ostream& os, ReadInputRetMessage* m );
00601     // -----------------------------------------------------------------------
00603     struct ForceCoilsMessage:
00604         public ModbusHeader
00605     {
00606         ModbusData start;   
00607         ModbusData quant;   
00608         ModbusByte bcnt;    
00610         ModbusByte data[MAXLENPACKET-sizeof(ModbusData)*2-sizeof(ModbusByte)];
00611         ModbusCRC crc;      
00613         // ------- to slave -------
00614         ForceCoilsMessage( ModbusAddr addr, ModbusData start );
00616         ModbusMessage transport_msg();
00617 
00622         bool addData( DataBits d );
00623         
00624         // return number of bit
00625         // -1 - error
00626         int addBit( bool state );
00627         
00628         bool setBit( int nbit, bool state );
00629         
00630         inline int last(){ return quant; }
00631 
00638         bool getData( unsigned char dnum, DataBits& d );
00639         
00640         bool getBit( unsigned char bnum );
00641 
00642         void clear();
00643         inline bool isFull()
00644         {
00645             return ( (int)bcnt >= MAXLENPACKET );
00646         }
00647 
00648         // ------- from master -------  
00649         ForceCoilsMessage( ModbusMessage& m );
00650         ForceCoilsMessage& operator=( ModbusMessage& m );
00651         void init( ModbusMessage& m );
00652 
00654         int szData();
00655 
00659         static inline int szHead()
00660         {
00661             // start + quant + count
00662             return sizeof(ModbusData)*2+sizeof(ModbusByte);
00663         }
00664         
00666         static int getDataLen( ModbusMessage& m );
00667 
00671         bool checkFormat();
00672         
00673     }__attribute__((packed));
00674 
00675     std::ostream& operator<<(std::ostream& os, ForceCoilsMessage& m );
00676     std::ostream& operator<<(std::ostream& os, ForceCoilsMessage* m );
00677     // -----------------------------------------------------------------------
00679     struct ForceCoilsRetMessage:
00680         public ModbusHeader
00681     {
00682         ModbusData start;   
00683         ModbusData quant;   
00684         ModbusCRC crc;
00685 
00686         // ------- from slave -------
00687         ForceCoilsRetMessage( ModbusMessage& m );
00688         ForceCoilsRetMessage& operator=( ModbusMessage& m );
00689         void init( ModbusMessage& m );
00690         
00691         // ------- to master -------
00697         ForceCoilsRetMessage( ModbusAddr _from, ModbusData start=0, ModbusData quant=0 );
00698 
00700         void set( ModbusData start, ModbusData quant );
00701 
00703         ModbusMessage transport_msg();
00704         
00708         inline static int szData(){ return sizeof(ModbusData)*2+sizeof(ModbusCRC); }
00709     };
00710     
00711     std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage& m );
00712     std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage* m );
00713     // -----------------------------------------------------------------------
00714 
00716     struct WriteOutputMessage:
00717         public ModbusHeader
00718     {
00719         ModbusData start;   
00720         ModbusData quant;   
00721         ModbusByte bcnt;    
00723         ModbusData data[MAXLENPACKET/sizeof(ModbusData)-sizeof(ModbusData)*2-sizeof(ModbusByte)];
00724         ModbusCRC crc;      
00726         // ------- to slave -------
00727         WriteOutputMessage( ModbusAddr addr, ModbusData start );
00729         ModbusMessage transport_msg();
00730 
00731         bool addData( ModbusData d );
00732         void clear();
00733         inline bool isFull()        
00734         {
00735             return ( quant*sizeof(ModbusData) >= MAXLENPACKET );
00736         }
00737 
00738         // ------- from master -------  
00739         WriteOutputMessage( ModbusMessage& m );
00740         WriteOutputMessage& operator=( ModbusMessage& m );
00741         void init( ModbusMessage& m );
00742 
00744         int szData();
00745 
00749         static inline int szHead()
00750         {
00751             // start + quant + count
00752             return sizeof(ModbusData)*2+sizeof(ModbusByte);
00753         }
00754         
00756         static int getDataLen( ModbusMessage& m );
00757 
00761         bool checkFormat();
00762         
00763     }__attribute__((packed));
00764 
00765 
00766     std::ostream& operator<<(std::ostream& os, WriteOutputMessage& m );
00767     std::ostream& operator<<(std::ostream& os, WriteOutputMessage* m );
00768 
00770     struct WriteOutputRetMessage:
00771         public ModbusHeader
00772     {
00773         ModbusData start;   
00774         ModbusData quant;   
00776         // ------- from slave -------
00777         WriteOutputRetMessage( ModbusMessage& m );
00778         WriteOutputRetMessage& operator=( ModbusMessage& m );
00779         void init( ModbusMessage& m );
00780         ModbusCRC crc;
00781 
00782         // ------- to master -------
00788         WriteOutputRetMessage( ModbusAddr _from, ModbusData start=0, ModbusData quant=0 );
00789 
00791         void set( ModbusData start, ModbusData quant );
00792 
00794         ModbusMessage transport_msg();
00795         
00799         inline static int szData(){ return sizeof(ModbusData)*2+sizeof(ModbusCRC); }
00800     };
00801     
00802     std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage& m );
00803     std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage* m );
00804     // -----------------------------------------------------------------------
00806     struct ForceSingleCoilMessage:
00807         public ModbusHeader
00808     {
00809         ModbusData start;   
00810         ModbusData data;    
00811         ModbusCRC crc;      
00814         inline bool cmd()
00815         {
00816             return (data & 0xFF00);
00817         }
00818 
00819 
00820         // ------- to slave -------
00821         ForceSingleCoilMessage( ModbusAddr addr, ModbusData reg, bool state );
00823         ModbusMessage transport_msg();
00824     
00825         // ------- from master -------
00826         ForceSingleCoilMessage( ModbusMessage& m );
00827         ForceSingleCoilMessage& operator=( ModbusMessage& m );
00828         void init( ModbusMessage& m );
00829 
00831         int szData();
00832 
00836         static inline int szHead()
00837         {
00838             return sizeof(ModbusData);
00839         }
00840         
00844         static int getDataLen( ModbusMessage& m );
00845 
00849         bool checkFormat();
00850     }__attribute__((packed));
00851 
00852 
00853     std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage& m );
00854     std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage* m );
00855     // -----------------------------------------------------------------------
00856 
00858     struct ForceSingleCoilRetMessage:
00859         public ModbusHeader
00860     {
00861         ModbusData start;   
00862         ModbusData data;    
00863         ModbusCRC crc;
00864 
00865 
00866         // ------- from slave -------
00867         ForceSingleCoilRetMessage( ModbusMessage& m );
00868         ForceSingleCoilRetMessage& operator=( ModbusMessage& m );
00869         void init( ModbusMessage& m );
00870 
00871         // ------- to master -------
00876         ForceSingleCoilRetMessage( ModbusAddr _from );
00877 
00879         void set( ModbusData start, bool cmd );
00880 
00882         ModbusMessage transport_msg();
00883         
00887         inline static int szData(){ return 2*sizeof(ModbusData)+sizeof(ModbusCRC); }
00888     };
00889     
00890     std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage& m );
00891     std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage* m );
00892     // -----------------------------------------------------------------------
00893 
00895     struct WriteSingleOutputMessage:
00896         public ModbusHeader
00897     {
00898         ModbusData start;   
00899         ModbusData data;    
00900         ModbusCRC crc;      
00903         // ------- to slave -------
00904         WriteSingleOutputMessage( ModbusAddr addr, ModbusData reg=0, ModbusData data=0 );
00906         ModbusMessage transport_msg();
00907     
00908         // ------- from master -------
00909         WriteSingleOutputMessage( ModbusMessage& m );
00910         WriteSingleOutputMessage& operator=( ModbusMessage& m );
00911         void init( ModbusMessage& m );
00912 
00914         int szData();
00915 
00919         static inline int szHead()
00920         {
00921             return sizeof(ModbusData);
00922         }
00923         
00927         static int getDataLen( ModbusMessage& m );
00928 
00932         bool checkFormat();
00933     }__attribute__((packed));
00934 
00935 
00936     std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage& m );
00937     std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage* m );
00938     // -----------------------------------------------------------------------
00939 
00941     struct WriteSingleOutputRetMessage:
00942         public ModbusHeader
00943     {
00944         ModbusData start;   
00945         ModbusData data;    
00946         ModbusCRC crc;
00947 
00948 
00949         // ------- from slave -------
00950         WriteSingleOutputRetMessage( ModbusMessage& m );
00951         WriteSingleOutputRetMessage& operator=( ModbusMessage& m );
00952         void init( ModbusMessage& m );
00953 
00954         // ------- to master -------
00959         WriteSingleOutputRetMessage( ModbusAddr _from, ModbusData start=0 );
00960 
00962         void set( ModbusData start, ModbusData data );
00963 
00965         ModbusMessage transport_msg();
00966         
00970         inline static int szData(){ return 2*sizeof(ModbusData)+sizeof(ModbusCRC); }
00971     };
00972     
00973     std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage& m );
00974     std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage* m );
00975     // -----------------------------------------------------------------------
00977     struct DiagnosticMessage:
00978         public ModbusHeader
00979     {
00980         ModbusData subf;
00981         ModbusData data[MAXLENPACKET/sizeof(ModbusData)];   
00983         // ------- from slave -------
00984         DiagnosticMessage( ModbusMessage& m );
00985         DiagnosticMessage& operator=( ModbusMessage& m );
00986         void init( ModbusMessage& m );
00990         static inline int szHead()
00991         {
00992             return sizeof(ModbusData); // subf
00993         }
00994 
00996         static int getDataLen( ModbusMessage& m );
00997         ModbusCRC crc;
00998         
00999         // ------- to master -------
01000         DiagnosticMessage( ModbusAddr _from, DiagnosticsSubFunction subf, ModbusData d=0 );
01001 
01006         bool addData( ModbusData d );
01007 
01009         void clear();
01010         
01012         inline bool isFull()        
01013         {
01014             return ( sizeof(subf)+count*sizeof(ModbusData) >= MAXLENPACKET );
01015         }
01016 
01018         int szData();
01019         
01021         ModbusMessage transport_msg();
01022         
01023         // Это поле не входит в стандарт modbus
01024         // оно вспомогательное и игнорируется при 
01025         // преобразовании в ModbusMessage.
01026         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 
01027         // Используйте специальную функцию transport_msg()
01028         int count;  
01029     };
01030     std::ostream& operator<<(std::ostream& os, DiagnosticMessage& m );
01031     std::ostream& operator<<(std::ostream& os, DiagnosticMessage* m );
01032     // -----------------------------------------------------------------------
01034     struct DiagnosticRetMessage:
01035         public DiagnosticMessage
01036     {
01037         DiagnosticRetMessage( ModbusMessage& m );
01038         DiagnosticRetMessage( DiagnosticMessage& m );
01039         DiagnosticRetMessage( ModbusAddr a, DiagnosticsSubFunction subf, ModbusData d=0 );
01040     };
01041 
01042     std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage& m );
01043     std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage* m );
01044     // -----------------------------------------------------------------------
01046     struct MEIMessageRDI:
01047         public ModbusHeader
01048     {
01049         ModbusByte type;    
01050         ModbusByte devID;   
01051         ModbusByte objID;   
01053         ModbusCRC crc;      
01055         // ------- to slave -------
01056         MEIMessageRDI( ModbusAddr addr, ModbusByte devID, ModbusByte objID );
01058         ModbusMessage transport_msg();
01059 
01060         // ------- from master -------  
01061         MEIMessageRDI( ModbusMessage& m );
01062         MEIMessageRDI& operator=( ModbusMessage& m );
01063         void init( ModbusMessage& m );
01064 
01068         static inline int szHead(){ return sizeof(ModbusByte)*3; }
01069 
01071         static inline int szData(){ return sizeof(ModbusByte)*3 + szCRC; }
01072 
01073         // вспомогательные функции
01074         bool checkFormat();
01075 
01076     }__attribute__((packed));
01077     // -----------------------------------------------------------------------
01078     std::ostream& operator<<(std::ostream& os, MEIMessageRDI& m );
01079     std::ostream& operator<<(std::ostream& os, MEIMessageRDI* m );
01080     // -----------------------------------------------------------------------
01081 
01082     struct RDIObjectInfo
01083     {
01084         RDIObjectInfo():id(0),val(""){}
01085         RDIObjectInfo( ModbusByte id, const std::string v ):id(id),val(v){}
01086         RDIObjectInfo( ModbusByte id, ModbusByte* dat, ModbusByte len );
01087 
01088         ModbusByte id;
01089         std::string val;
01090     };
01091 
01092     typedef std::list<RDIObjectInfo> RDIObjectList;
01093 
01095     struct MEIMessageRetRDI:
01096         public ModbusHeader
01097     {
01098         ModbusByte type;    
01099         ModbusByte devID;   
01100         ModbusByte conformity; 
01101         ModbusByte mf;      
01102         ModbusByte objID;   
01103         ModbusByte objNum;  
01105         RDIObjectList dlist;
01106         ModbusCRC crc;
01107 
01108         // ------- from slave -------
01109         MEIMessageRetRDI();
01110         MEIMessageRetRDI( ModbusMessage& m );
01111         MEIMessageRetRDI& operator=( ModbusMessage& m );
01112         void init( ModbusMessage& m );
01113 
01114         // предварительная инициализации, только заголовочной части, без данных
01115         void pre_init( ModbusMessage& m );
01116 
01118         static inline int szHead()
01119         {
01120             return sizeof(ModbusByte)*6;
01121         }
01122 
01123 //      /*! узнать длину данных следующих за предварительным заголовком ( в байтах ) */
01124 //      static int getDataLen( ModbusMessage& m );
01125         
01126         // ------- to master -------
01127         MEIMessageRetRDI( ModbusAddr _from, ModbusByte devID, ModbusByte conformity, ModbusByte mf, ModbusByte objID );
01128 
01133         bool addData( ModbusByte id, const std::string value );
01134         bool addData( RDIObjectInfo& dat );
01135 
01137         void clear();
01138         
01140         inline bool isFull()
01141         {
01142             return ( bcnt >= MAXLENPACKET );
01143         }
01144         
01146         int szData();
01147         
01149         ModbusMessage transport_msg();
01150 
01151         int bcnt; 
01152     };
01153 
01154     std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI& m );
01155     std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI* m );
01156     std::ostream& operator<<(std::ostream& os, RDIObjectList& dl );
01157     std::ostream& operator<<(std::ostream& os, RDIObjectList* dl );
01158     // -----------------------------------------------------------------------
01159     // -----------------------------------------------------------------------
01160 
01162     struct JournalCommandMessage:
01163         public ModbusHeader
01164     {
01165         ModbusData cmd;         
01166         ModbusData num;         
01167         ModbusCRC crc;
01168         
01169         // -------------
01170         JournalCommandMessage( ModbusMessage& m );
01171         JournalCommandMessage& operator=( ModbusMessage& m );
01172 
01174         inline static int szData(){ return sizeof(ModbusByte)*4 + szCRC; }
01175 
01176     }__attribute__((packed));
01177 
01178     std::ostream& operator<<(std::ostream& os, JournalCommandMessage& m ); 
01179     std::ostream& operator<<(std::ostream& os, JournalCommandMessage* m ); 
01180     // -----------------------------------------------------------------------
01182     struct JournalCommandRetMessage:
01183         public ModbusHeader
01184     {
01185         ModbusByte bcnt;                    
01186 //      ModbusByte data[MAXLENPACKET-1];    /*!< данные */
01187 
01188         // В связи со спецификой реализации ответной части (т.е. modbus master)
01189         // данные приходится делать не байтовым потоком, а "словами"
01190         // которые в свою очередь будут перевёрнуты при посылке...
01191         ModbusData data[MAXLENPACKET/sizeof(ModbusData)];   
01193         // -------------
01194         JournalCommandRetMessage( ModbusAddr _from );
01195 
01202         bool setData( ModbusByte* b, int len );
01203 
01205         void clear();
01206         
01208         inline bool isFull()        
01209         {
01210             return ( count*sizeof(ModbusData) >= MAXLENPACKET );
01211         }
01212 
01214         int szData();
01215         
01217         ModbusMessage transport_msg();
01218         
01219         // Это поле не входит в стандарт modbus
01220         // оно вспомогательное и игнорируется при 
01221         // преобразовании в ModbusMessage.
01222         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 
01223         // Используйте специальную функцию transport_msg()
01224         int count;  
01225     };
01226 
01227     std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage& m );
01228     std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage* m );
01229     // -----------------------------------------------------------------------
01233     struct JournalCommandRetOK:
01234         public JournalCommandRetMessage
01235     {
01236         // -------------
01237         JournalCommandRetOK( ModbusAddr _from );
01238         void set( ModbusData cmd, ModbusData ecode );
01239         static void set( JournalCommandRetMessage& m, ModbusData cmd, ModbusData ecode );
01240     };
01241 
01242     std::ostream& operator<<(std::ostream& os, JournalCommandRetOK& m ); 
01243     std::ostream& operator<<(std::ostream& os, JournalCommandRetOK* m ); 
01244     // -----------------------------------------------------------------------
01245 
01247     struct SetDateTimeMessage:
01248         public ModbusHeader
01249     {
01250         ModbusByte hour;    
01251         ModbusByte min;     
01252         ModbusByte sec;     
01253         ModbusByte day;     
01254         ModbusByte mon;     
01255         ModbusByte year;    
01256         ModbusByte century; 
01258         ModbusCRC crc;
01259         
01260         // ------- to slave -------
01261         SetDateTimeMessage( ModbusAddr addr );
01263         ModbusMessage transport_msg();
01264         
01265         // ------- from master -------
01266         SetDateTimeMessage( ModbusMessage& m );
01267         SetDateTimeMessage& operator=( ModbusMessage& m );
01268         SetDateTimeMessage();
01269 
01270         bool checkFormat();
01271 
01273         inline static int szData(){ return sizeof(ModbusByte)*7 + szCRC; }
01274 
01275     }__attribute__((packed));
01276 
01277     std::ostream& operator<<(std::ostream& os, SetDateTimeMessage& m ); 
01278     std::ostream& operator<<(std::ostream& os, SetDateTimeMessage* m ); 
01279     // -----------------------------------------------------------------------
01280 
01282     struct SetDateTimeRetMessage:
01283         public SetDateTimeMessage
01284     {
01285 
01286         // ------- from slave -------
01287         SetDateTimeRetMessage( ModbusMessage& m );
01288         SetDateTimeRetMessage& operator=( ModbusMessage& m );
01289         void init( ModbusMessage& m );
01290 
01291         // ------- to master -------
01292         SetDateTimeRetMessage( ModbusAddr _from );
01293         SetDateTimeRetMessage( const SetDateTimeMessage& query );
01294         static void cpy( SetDateTimeRetMessage& reply, SetDateTimeMessage& query );
01295 
01297         ModbusMessage transport_msg();
01298     };
01299     // -----------------------------------------------------------------------
01300 
01302     struct RemoteServiceMessage:
01303         public ModbusHeader
01304     {
01305         ModbusByte bcnt;    
01308         ModbusByte data[MAXLENPACKET-sizeof(ModbusByte)];
01309         ModbusCRC crc;      
01311         // -----------
01312         RemoteServiceMessage( ModbusMessage& m );
01313         RemoteServiceMessage& operator=( ModbusMessage& m );
01314         void init( ModbusMessage& m );
01315 
01317         int szData();
01318 
01322         static inline int szHead()
01323         { return sizeof(ModbusByte); } // bcnt
01324         
01326         static int getDataLen( ModbusMessage& m );
01327 
01328     }__attribute__((packed));
01329 
01330     std::ostream& operator<<(std::ostream& os, RemoteServiceMessage& m ); 
01331     std::ostream& operator<<(std::ostream& os, RemoteServiceMessage* m ); 
01332     // -----------------------------------------------------------------------
01333     struct RemoteServiceRetMessage:
01334         public ModbusHeader
01335     {
01336         ModbusByte bcnt;    
01338         ModbusByte data[MAXLENPACKET-sizeof(ModbusByte)];
01339 
01340         RemoteServiceRetMessage( ModbusAddr _from );
01341 
01348         bool setData( ModbusByte* b, int len );
01349 
01351         void clear();
01352         
01354         inline bool isFull()        
01355             { return ( count >= sizeof(data) ); }
01356 
01358         int szData();
01359         
01361         ModbusMessage transport_msg();
01362         
01363         // Это поле не входит в стандарт modbus
01364         // оно вспомогательное и игнорируется при 
01365         // преобразовании в ModbusMessage.
01366         unsigned int    count;  
01367     };
01368     // -----------------------------------------------------------------------
01369 
01370     struct ReadFileRecordMessage:
01371         public ModbusHeader
01372     {
01373         struct SubRequest
01374         {
01375             ModbusByte reftype; 
01376             ModbusData numfile; 
01377             ModbusData numrec;  
01378             ModbusData reglen;  
01379         }__attribute__((packed));   
01380 
01381         ModbusByte bcnt;    
01384         SubRequest data[MAXLENPACKET/sizeof(SubRequest)-sizeof(ModbusByte)];
01385         ModbusCRC crc;      
01387         // -----------
01388         ReadFileRecordMessage( ModbusMessage& m );
01389         ReadFileRecordMessage& operator=( ModbusMessage& m );
01390         void init( ModbusMessage& m );
01391 
01393         int szData();
01394 
01398         static inline int szHead()
01399         { return sizeof(ModbusByte); } // bcnt
01400         
01402         static int getDataLen( ModbusMessage& m );
01403 
01405         bool checkFormat();
01406         
01407         // это поле служебное и не используется в релальном обмене
01408         int count; 
01409     };
01410 
01411     std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage& m ); 
01412     std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage* m ); 
01413     // -----------------------------------------------------------------------
01414 
01415     struct FileTransferMessage:
01416         public ModbusHeader
01417     {
01418         ModbusData numfile;     
01419         ModbusData numpacket;   
01420         ModbusCRC crc;          
01422         // ------- to slave -------
01423         FileTransferMessage( ModbusAddr addr, ModbusData numfile, ModbusData numpacket );
01424         ModbusMessage transport_msg();  
01426         // ------- from master -------
01427         FileTransferMessage( ModbusMessage& m );
01428         FileTransferMessage& operator=( ModbusMessage& m );
01429         void init( ModbusMessage& m );
01430 
01432         static inline int szData()
01433         {   return sizeof(ModbusData)*2 + szCRC; }
01434 
01435     }__attribute__((packed));
01436 
01437     std::ostream& operator<<(std::ostream& os, FileTransferMessage& m ); 
01438     std::ostream& operator<<(std::ostream& os, FileTransferMessage* m ); 
01439     // -----------------------------------------------------------------------
01440 
01441     struct FileTransferRetMessage:
01442         public ModbusHeader
01443     {
01444         // 255 - max of bcnt...(1 byte)     
01445 //      static const int MaxDataLen = 255 - szCRC - szModbusHeader - sizeof(ModbusData)*3 - sizeof(ModbusByte)*2;
01446         static const int MaxDataLen = MAXLENPACKET - sizeof(ModbusData)*3 - sizeof(ModbusByte)*2;
01447 
01448         ModbusByte bcnt;        
01449         ModbusData numfile;     
01450         ModbusData numpacks;    
01451         ModbusData packet;      
01452         ModbusByte dlen;        
01453         ModbusByte data[MaxDataLen];
01454 
01455     
01456         // ------- from slave -------
01457         FileTransferRetMessage( ModbusMessage& m );
01458         FileTransferRetMessage& operator=( ModbusMessage& m );
01459         void init( ModbusMessage& m );
01460         ModbusCRC crc;
01461         static int szHead(){ return sizeof(ModbusByte); }
01462         static int getDataLen( ModbusMessage& m );
01463         
01464         // ------- to master -------
01465         FileTransferRetMessage( ModbusAddr _from );
01466 
01470         bool set( ModbusData numfile, ModbusData file_num_packets, ModbusData packet, ModbusByte* b, ModbusByte len );
01471 
01473         void clear();
01474         
01476         int szData();
01477         
01479         ModbusMessage transport_msg();
01480     };
01481 
01482     std::ostream& operator<<(std::ostream& os, FileTransferRetMessage& m ); 
01483     std::ostream& operator<<(std::ostream& os, FileTransferRetMessage* m );
01484     // -----------------------------------------------------------------------
01485 } // end of ModbusRTU namespace
01486 // ---------------------------------------------------------------------------
01487 namespace ModbusTCP
01488 {
01489     struct MBAPHeader
01490     {
01491         ModbusRTU::ModbusData   tID; 
01492         ModbusRTU::ModbusData   pID; 
01493         ModbusRTU::ModbusData   len; 
01494 /*      ModbusRTU::ModbusByte   uID; */  /* <------- see ModbusHeader */
01495 
01496         MBAPHeader():tID(0),pID(0) /*,uID(0) */{}
01497         
01498         void swapdata();
01499 
01500     }__attribute__((packed));
01501 
01502     std::ostream& operator<<(std::ostream& os, MBAPHeader& m ); 
01503 
01504   // -----------------------------------------------------------------------
01505 } // end of namespace ModbusTCP
01506 // ---------------------------------------------------------------------------
01507 #endif // ModbusTypes_H_
01508 // ---------------------------------------------------------------------------