UniSet  2.2.1
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 unsigned short BitsPerByte = 8;
00026     typedef unsigned char ModbusAddr;    
00027     typedef unsigned short ModbusData;    
00028     const unsigned short 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     typedef unsigned long RegID;
00079 
00086     RegID genRegID( const ModbusRTU::ModbusData r, const int fn );
00087 
00088     // определение размера данных в зависимости от типа сообщения
00089     // возвращает -1 - если динамический размер сообщения или размер неизвестен
00090     int szRequestDiagnosticData( DiagnosticsSubFunction f );
00091 
00093     enum RDIObjectID
00094     {
00095         rdiVendorName = 0x0,
00096         rdiProductCode = 0x1,
00097         rdiMajorMinorRevision = 0x2,
00098         rdiVendorURL = 0x3,
00099         rdiProductName = 0x4,
00100         rdiModelName = 0x5,
00101         rdiUserApplicationName = 0x6
00102                                  // 0x07 .. 0x7F - reserved
00103                                  // 0x80 .. 0xFF - optionaly defined (product dependant)
00104     };
00105 
00107     enum RDIRequestDeviceID
00108     {
00109         rdevMinNum = 0,
00110         rdevBasicDevice = 0x1,   // request to get the basic device identification (stream access)
00111         rdevRegularDevice = 0x2, // request to get the regular device identification (stream access)
00112         rdevExtentedDevice = 0x3, // request to get the extended device identification (stream access)
00113         rdevSpecificDevice = 0x4, // request to get the extended device identification (stream access)
00114         rdevMaxNum = 0x5
00115     };
00116 
00117     std::string rdi2str( int id );
00118     // -----------------------------------------------------------------------
00119 
00121     enum
00122     {
00124         MAXLENPACKET     = 508, 
00125         BroadcastAddr    = 255, 
00126         MAXPDULEN       = 253, // 255 - 2(CRC)
00127         MAXDATALEN       = 125  
00131     };
00132 
00133     const unsigned char MBErrMask = 0x80;
00134     // ---------------------------------------------------------------------
00135     unsigned short SWAPSHORT(unsigned short x);
00136     // ---------------------------------------------------------------------
00138     ModbusCRC checkCRC( ModbusByte* start, int len );
00139     const int szCRC = sizeof(ModbusCRC); 
00140     // ---------------------------------------------------------------------
00142     std::ostream& mbPrintMessage( std::ostream& os, ModbusByte* b, int len );
00143     // -------------------------------------------------------------------------
00144     ModbusAddr str2mbAddr( const std::string& val );
00145     ModbusData str2mbData( const std::string& val );
00146     std::string dat2str( const ModbusData dat );
00147     std::string addr2str( const ModbusAddr addr );
00148     std::string b2str( const ModbusByte b );
00149     // -------------------------------------------------------------------------
00150     float dat2f( const ModbusData dat1, const ModbusData dat2 );
00151     // -------------------------------------------------------------------------
00152     bool isWriteFunction( SlaveFunctionCode c );
00153     // -------------------------------------------------------------------------
00155     struct ModbusHeader
00156     {
00157         ModbusAddr addr;        
00158         ModbusByte func;        
00160         ModbusHeader(): addr(0), func(0) {}
00161     } __attribute__((packed));
00162 
00163     const int szModbusHeader = sizeof(ModbusHeader);
00164     std::ostream& operator<<(std::ostream& os, ModbusHeader& m );
00165     std::ostream& operator<<(std::ostream& os, ModbusHeader* m );
00166     // -----------------------------------------------------------------------
00167 
00171     struct ModbusMessage:
00172         public ModbusHeader
00173     {
00174         ModbusMessage();
00175         ModbusByte data[MAXLENPACKET + szCRC];   
00177         // Это поле вспомогательное и игнорируется при пересылке
00178         size_t len;    
00179     } __attribute__((packed));
00180 
00181     std::ostream& operator<<(std::ostream& os, ModbusMessage& m );
00182     std::ostream& operator<<(std::ostream& os, ModbusMessage* m );
00183     // -----------------------------------------------------------------------
00185     struct ErrorRetMessage:
00186         public ModbusHeader
00187     {
00188         ModbusByte ecode = { erNoError };
00189         ModbusCRC crc = { 0 };
00190 
00191         // ------- from slave -------
00192         ErrorRetMessage( ModbusMessage& m );
00193         ErrorRetMessage& operator=( ModbusMessage& m );
00194         void init( ModbusMessage& m );
00195 
00196         // ------- to master -------
00197         ErrorRetMessage( ModbusAddr _from, ModbusByte _func, ModbusByte ecode );
00198 
00200         ModbusMessage transport_msg();
00201 
00205         inline static int szData()
00206         {
00207             return sizeof(ModbusByte) + szCRC;
00208         }
00209     };
00210 
00211     std::ostream& operator<<(std::ostream& os, ErrorRetMessage& m );
00212     std::ostream& operator<<(std::ostream& os, ErrorRetMessage* m );
00213     // -----------------------------------------------------------------------
00214     struct DataBits
00215     {
00216         DataBits( ModbusByte b );
00217         DataBits( std::string s ); // example "10001111"
00218         DataBits();
00219 
00220         const DataBits& operator=(const ModbusByte& r);
00221 
00222         operator ModbusByte();
00223         ModbusByte mbyte();
00224 
00225         bool operator[]( const size_t i )
00226         {
00227             return b[i];
00228         }
00229         void set( int n, bool s )
00230         {
00231             b.set(n, s);
00232         }
00233 
00234         std::bitset<BitsPerByte> b;
00235     };
00236 
00237     std::ostream& operator<<(std::ostream& os, DataBits& m );
00238     std::ostream& operator<<(std::ostream& os, DataBits* m );
00239     // -----------------------------------------------------------------------
00240     struct DataBits16
00241     {
00242         DataBits16( ModbusData d );
00243         DataBits16( const std::string& s ); // example "1000111110001111"
00244         DataBits16();
00245 
00246         const DataBits16& operator=(const ModbusData& r);
00247 
00248         operator ModbusData();
00249         ModbusData mdata();
00250 
00251         bool operator[]( const size_t i )
00252         {
00253             return b[i];
00254         }
00255         void set( int n, bool s )
00256         {
00257             b.set(n, s);
00258         }
00259 
00260         std::bitset<BitsPerData> b;
00261     };
00262 
00263     std::ostream& operator<<(std::ostream& os, DataBits16& m );
00264     std::ostream& operator<<(std::ostream& os, DataBits16* m );
00265     // -----------------------------------------------------------------------
00267     struct ReadCoilMessage:
00268         public ModbusHeader
00269     {
00270         ModbusData start = { 0 };
00271         ModbusData count = { 0 };
00272         ModbusCRC crc = { 0 };
00273 
00274         // ------- to slave -------
00275         ReadCoilMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00277         ModbusMessage transport_msg();
00278 
00279         // ------- from master -------
00280         ReadCoilMessage( ModbusMessage& m );
00281         ReadCoilMessage& operator=( ModbusMessage& m );
00282         void init( ModbusMessage& m );
00283 
00285         inline static int szData()
00286         {
00287             return sizeof(ModbusData) * 2 + szCRC;
00288         }
00289 
00290     } __attribute__((packed));
00291 
00292     std::ostream& operator<<(std::ostream& os, ReadCoilMessage& m );
00293     std::ostream& operator<<(std::ostream& os, ReadCoilMessage* m );
00294 
00295     // -----------------------------------------------------------------------
00296 
00298     struct ReadCoilRetMessage:
00299         public ModbusHeader
00300     {
00301         ModbusByte bcnt = { 0 };          
00302         ModbusByte data[MAXLENPACKET];    
00304         // ------- from slave -------
00305         ReadCoilRetMessage( ModbusMessage& m );
00306         ReadCoilRetMessage& operator=( ModbusMessage& m );
00307         void init( ModbusMessage& m );
00311         static inline int szHead()
00312         {
00313             return sizeof(ModbusByte); // bcnt
00314         }
00315 
00317         static int getDataLen( ModbusMessage& m );
00318         ModbusCRC crc = { 0 };
00319 
00320         // ------- to master -------
00321         ReadCoilRetMessage( ModbusAddr _from );
00322 
00327         bool addData( DataBits d );
00328 
00336         bool setBit( unsigned char dnum, unsigned char bnum, bool state );
00337 
00344         bool getData( unsigned char bnum, DataBits& d );
00345 
00347         void clear();
00348 
00350         inline bool isFull()
00351         {
00352             return ( (int)bcnt >= MAXPDULEN );
00353         }
00354 
00356         size_t szData();
00357 
00359         ModbusMessage transport_msg();
00360     };
00361 
00362     std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage& m );
00363     std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage* m );
00364     // -----------------------------------------------------------------------
00366     struct ReadInputStatusMessage:
00367         public ModbusHeader
00368     {
00369         ModbusData start = { 0 };
00370         ModbusData count = { 0 };
00371         ModbusCRC crc = { 0 };
00372 
00373         // ------- to slave -------
00374         ReadInputStatusMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00376         ModbusMessage transport_msg();
00377 
00378         // ------- from master -------
00379         ReadInputStatusMessage( ModbusMessage& m );
00380         ReadInputStatusMessage& operator=( ModbusMessage& m );
00381         void init( ModbusMessage& m );
00382 
00384         inline static int szData()
00385         {
00386             return sizeof(ModbusData) * 2 + szCRC;
00387         }
00388 
00389     } __attribute__((packed));
00390 
00391     std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage& m );
00392     std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage* m );
00393     // -----------------------------------------------------------------------
00395     struct ReadInputStatusRetMessage:
00396         public ModbusHeader
00397     {
00398         ModbusByte bcnt = { 0 };          
00399         ModbusByte data[MAXLENPACKET];    
00401         // ------- from slave -------
00402         ReadInputStatusRetMessage( ModbusMessage& m );
00403         ReadInputStatusRetMessage& operator=( ModbusMessage& m );
00404         void init( ModbusMessage& m );
00408         static inline int szHead()
00409         {
00410             return sizeof(ModbusByte); // bcnt
00411         }
00412 
00414         static int getDataLen( ModbusMessage& m );
00415         ModbusCRC crc = { 0 };
00416 
00417         // ------- to master -------
00418         ReadInputStatusRetMessage( ModbusAddr _from );
00419 
00424         bool addData( DataBits d );
00425 
00433         bool setBit( unsigned char dnum, unsigned char bnum, bool state );
00434 
00441         bool getData( unsigned char dnum, DataBits& d );
00442 
00444         void clear();
00445 
00447         inline bool isFull()
00448         {
00449             return ( (int)bcnt >= MAXPDULEN );
00450         }
00451 
00453         size_t szData();
00454 
00456         ModbusMessage transport_msg();
00457     };
00458 
00459     std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage& m );
00460     std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage* m );
00461     // -----------------------------------------------------------------------
00462 
00464     struct ReadOutputMessage:
00465         public ModbusHeader
00466     {
00467         ModbusData start = { 0 };
00468         ModbusData count = { 0 };
00469         ModbusCRC crc = { 0 };
00470 
00471         // ------- to slave -------
00472         ReadOutputMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00474         ModbusMessage transport_msg();
00475 
00476         // ------- from master -------
00477         ReadOutputMessage( ModbusMessage& m );
00478         ReadOutputMessage& operator=( ModbusMessage& m );
00479         void init( ModbusMessage& m );
00480 
00482         inline static int szData()
00483         {
00484             return sizeof(ModbusData) * 2 + szCRC;
00485         }
00486 
00487     } __attribute__((packed));
00488 
00489     std::ostream& operator<<(std::ostream& os, ReadOutputMessage& m );
00490     std::ostream& operator<<(std::ostream& os, ReadOutputMessage* m );
00491     // -----------------------------------------------------------------------
00493     struct ReadOutputRetMessage:
00494         public ModbusHeader
00495     {
00496         ModbusByte bcnt = { 0 };                             
00497         ModbusData data[MAXLENPACKET / sizeof(ModbusData)];  
00499         // ------- from slave -------
00500         ReadOutputRetMessage( ModbusMessage& m );
00501         ReadOutputRetMessage& operator=( ModbusMessage& m );
00502         void init( ModbusMessage& m );
00506         static inline int szHead()
00507         {
00508             // bcnt
00509             return sizeof(ModbusByte);
00510         }
00511 
00513         static int getDataLen( ModbusMessage& m );
00514         ModbusCRC crc = { 0 };
00515 
00516         // ------- to master -------
00517         ReadOutputRetMessage( ModbusAddr _from );
00518 
00523         bool addData( ModbusData d );
00524 
00526         void clear();
00527 
00529         inline bool isFull()
00530         {
00531             return ( count * sizeof(ModbusData) >= MAXLENPACKET );
00532         }
00533 
00535         size_t szData();
00536 
00538         ModbusMessage transport_msg();
00539 
00540         // Это поле не входит в стандарт modbus
00541         // оно вспомогательное и игнорируется при
00542         // преобразовании в ModbusMessage.
00543         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
00544         // Используйте специальную функцию transport_msg()
00545         size_t count = { 0 };    
00546     };
00547 
00548     std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage& m );
00549     std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage* m );
00550     // -----------------------------------------------------------------------
00552     struct ReadInputMessage:
00553         public ModbusHeader
00554     {
00555         ModbusData start = { 0 };
00556         ModbusData count = { 0 };
00557         ModbusCRC crc = { 0 };
00558 
00559         // ------- to slave -------
00560         ReadInputMessage( ModbusAddr addr, ModbusData start, ModbusData count );
00562         ModbusMessage transport_msg();
00563 
00564         // ------- from master -------
00565         ReadInputMessage( ModbusMessage& m );
00566         ReadInputMessage& operator=( ModbusMessage& m );
00567         void init( ModbusMessage& m );
00568 
00570         inline static int szData()
00571         {
00572             return sizeof(ModbusData) * 2 + szCRC;
00573         }
00574 
00575     } __attribute__((packed));
00576 
00577     std::ostream& operator<<(std::ostream& os, ReadInputMessage& m );
00578     std::ostream& operator<<(std::ostream& os, ReadInputMessage* m );
00579     // -----------------------------------------------------------------------
00580 
00582     struct ReadInputRetMessage:
00583         public ModbusHeader
00584     {
00585         ModbusByte bcnt = { 0 };                                    
00586         ModbusData data[MAXLENPACKET / sizeof(ModbusData)];  
00588         // ------- from slave -------
00589         ReadInputRetMessage( ModbusMessage& m );
00590         ReadInputRetMessage& operator=( ModbusMessage& m );
00591         void init( ModbusMessage& m );
00595         static inline int szHead()
00596         {
00597             // bcnt
00598             return sizeof(ModbusByte);
00599         }
00600 
00602         static int getDataLen( ModbusMessage& m );
00603         ModbusCRC crc = { 0 };
00604 
00605         // ------- to master -------
00606         ReadInputRetMessage( ModbusAddr _from );
00607 
00612         bool addData( ModbusData d );
00613 
00615         void clear();
00616 
00618         inline bool isFull()
00619         {
00620             return ( count * sizeof(ModbusData) >= MAXLENPACKET );
00621         }
00622 
00623         void swapData();
00624 
00626         size_t szData();
00627 
00629         ModbusMessage transport_msg();
00630 
00631         // Это поле не входит в стандарт modbus
00632         // оно вспомогательное и игнорируется при
00633         // преобразовании в ModbusMessage.
00634         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
00635         // Используйте специальную функцию transport_msg()
00636         size_t count = { 0 };    
00637     };
00638 
00639     std::ostream& operator<<(std::ostream& os, ReadInputRetMessage& m );
00640     std::ostream& operator<<(std::ostream& os, ReadInputRetMessage* m );
00641     // -----------------------------------------------------------------------
00643     struct ForceCoilsMessage:
00644         public ModbusHeader
00645     {
00646         ModbusData start = { 0 };    
00647         ModbusData quant = { 0 };    
00648         ModbusByte bcnt = { 0 };    
00650         ModbusByte data[MAXLENPACKET - sizeof(ModbusData) * 2 - sizeof(ModbusByte)];
00651         ModbusCRC crc = { 0 };        
00653         // ------- to slave -------
00654         ForceCoilsMessage( ModbusAddr addr, ModbusData start );
00656         ModbusMessage transport_msg();
00657 
00662         bool addData( DataBits d );
00663 
00664         // return number of bit
00665         // -1 - error
00666         int addBit( bool state );
00667 
00668         bool setBit( int nbit, bool state );
00669 
00670         inline int last()
00671         {
00672             return quant;
00673         }
00674 
00681         bool getData( unsigned char dnum, DataBits& d );
00682 
00683         bool getBit( unsigned char bnum );
00684 
00685         void clear();
00686         inline bool isFull()
00687         {
00688             return ( (int)bcnt >= MAXPDULEN );
00689         }
00690 
00691         // ------- from master -------
00692         ForceCoilsMessage( ModbusMessage& m );
00693         ForceCoilsMessage& operator=( ModbusMessage& m );
00694         void init( ModbusMessage& m );
00695 
00697         size_t szData();
00698 
00702         static inline int szHead()
00703         {
00704             // start + quant + count
00705             return sizeof(ModbusData) * 2 + sizeof(ModbusByte);
00706         }
00707 
00709         static int getDataLen( ModbusMessage& m );
00710 
00714         bool checkFormat();
00715 
00716     } __attribute__((packed));
00717 
00718     std::ostream& operator<<(std::ostream& os, ForceCoilsMessage& m );
00719     std::ostream& operator<<(std::ostream& os, ForceCoilsMessage* m );
00720     // -----------------------------------------------------------------------
00722     struct ForceCoilsRetMessage:
00723         public ModbusHeader
00724     {
00725         ModbusData start = { 0 };    
00726         ModbusData quant = { 0 };    
00727         ModbusCRC crc = { 0 };
00728 
00729         // ------- from slave -------
00730         ForceCoilsRetMessage( ModbusMessage& m );
00731         ForceCoilsRetMessage& operator=( ModbusMessage& m );
00732         void init( ModbusMessage& m );
00733 
00734         // ------- to master -------
00740         ForceCoilsRetMessage( ModbusAddr _from, ModbusData start = 0, ModbusData quant = 0 );
00741 
00743         void set( ModbusData start, ModbusData quant );
00744 
00746         ModbusMessage transport_msg();
00747 
00751         inline static int szData()
00752         {
00753             return sizeof(ModbusData) * 2 + sizeof(ModbusCRC);
00754         }
00755     };
00756 
00757     std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage& m );
00758     std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage* m );
00759     // -----------------------------------------------------------------------
00760 
00762     struct WriteOutputMessage:
00763         public ModbusHeader
00764     {
00765         ModbusData start = { 0 };    
00766         ModbusData quant = { 0 };    
00767         ModbusByte bcnt = { 0 };    
00769         ModbusData data[MAXLENPACKET / sizeof(ModbusData) - sizeof(ModbusData) * 2 - sizeof(ModbusByte)];
00770         ModbusCRC crc = { 0 };        
00772         // ------- to slave -------
00773         WriteOutputMessage( ModbusAddr addr, ModbusData start );
00775         ModbusMessage transport_msg();
00776 
00777         bool addData( ModbusData d );
00778         void clear();
00779         inline bool isFull()
00780         {
00781             return ( quant >= MAXDATALEN );
00782         }
00783 
00784         // ------- from master -------
00785         WriteOutputMessage( ModbusMessage& m );
00786         WriteOutputMessage& operator=( ModbusMessage& m );
00787         void init( ModbusMessage& m );
00788 
00790         size_t szData();
00791 
00795         static inline int szHead()
00796         {
00797             // start + quant + count
00798             return sizeof(ModbusData) * 2 + sizeof(ModbusByte);
00799         }
00800 
00802         static int getDataLen( ModbusMessage& m );
00803 
00807         bool checkFormat();
00808 
00809     } __attribute__((packed));
00810 
00811 
00812     std::ostream& operator<<(std::ostream& os, WriteOutputMessage& m );
00813     std::ostream& operator<<(std::ostream& os, WriteOutputMessage* m );
00814 
00816     struct WriteOutputRetMessage:
00817         public ModbusHeader
00818     {
00819         ModbusData start = { 0 };     
00820         ModbusData quant = { 0 };    
00822         // ------- from slave -------
00823         WriteOutputRetMessage( ModbusMessage& m );
00824         WriteOutputRetMessage& operator=( ModbusMessage& m );
00825         void init( ModbusMessage& m );
00826         ModbusCRC crc = { 0 };
00827 
00828         // ------- to master -------
00834         WriteOutputRetMessage( ModbusAddr _from, ModbusData start = 0, ModbusData quant = 0 );
00835 
00837         void set( ModbusData start, ModbusData quant );
00838 
00840         ModbusMessage transport_msg();
00841 
00845         inline static int szData()
00846         {
00847             return sizeof(ModbusData) * 2 + sizeof(ModbusCRC);
00848         }
00849     };
00850 
00851     std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage& m );
00852     std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage* m );
00853     // -----------------------------------------------------------------------
00855     struct ForceSingleCoilMessage:
00856         public ModbusHeader
00857     {
00858         ModbusData start = { 0 };   
00859         ModbusData data = { 0 };    
00860         ModbusCRC crc = { 0 };      
00863         inline bool cmd()
00864         {
00865             return (data & 0xFF00);
00866         }
00867 
00868 
00869         // ------- to slave -------
00870         ForceSingleCoilMessage( ModbusAddr addr, ModbusData reg, bool state );
00872         ModbusMessage transport_msg();
00873 
00874         // ------- from master -------
00875         ForceSingleCoilMessage( ModbusMessage& m );
00876         ForceSingleCoilMessage& operator=( ModbusMessage& m );
00877         void init( ModbusMessage& m );
00878 
00880         size_t szData();
00881 
00885         static inline int szHead()
00886         {
00887             return sizeof(ModbusData);
00888         }
00889 
00893         static int getDataLen( ModbusMessage& m );
00894 
00898         bool checkFormat();
00899     } __attribute__((packed));
00900 
00901 
00902     std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage& m );
00903     std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage* m );
00904     // -----------------------------------------------------------------------
00905 
00907     struct ForceSingleCoilRetMessage:
00908         public ModbusHeader
00909     {
00910         ModbusData start = { 0 };     
00911         ModbusData data = { 0 };     
00912         ModbusCRC crc = { 0 };
00913 
00915         inline bool cmd()
00916         {
00917             return (data & 0xFF00);
00918         }
00919 
00920         // ------- from slave -------
00921         ForceSingleCoilRetMessage( ModbusMessage& m );
00922         ForceSingleCoilRetMessage& operator=( ModbusMessage& m );
00923         void init( ModbusMessage& m );
00924 
00925         // ------- to master -------
00930         ForceSingleCoilRetMessage( ModbusAddr _from );
00931 
00933         void set( ModbusData start, bool cmd );
00934 
00936         ModbusMessage transport_msg();
00937 
00941         inline static int szData()
00942         {
00943             return 2 * sizeof(ModbusData) + sizeof(ModbusCRC);
00944         }
00945     };
00946 
00947     std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage& m );
00948     std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage* m );
00949     // -----------------------------------------------------------------------
00950 
00952     struct WriteSingleOutputMessage:
00953         public ModbusHeader
00954     {
00955         ModbusData start = { 0 };    
00956         ModbusData data = { 0 };    
00957         ModbusCRC crc = { 0 };        
00960         // ------- to slave -------
00961         WriteSingleOutputMessage( ModbusAddr addr, ModbusData reg = 0, ModbusData data = 0 );
00963         ModbusMessage transport_msg();
00964 
00965         // ------- from master -------
00966         WriteSingleOutputMessage( ModbusMessage& m );
00967         WriteSingleOutputMessage& operator=( ModbusMessage& m );
00968         void init( ModbusMessage& m );
00969 
00971         size_t szData();
00972 
00976         static inline int szHead()
00977         {
00978             return sizeof(ModbusData);
00979         }
00980 
00984         static int getDataLen( ModbusMessage& m );
00985 
00989         bool checkFormat();
00990     } __attribute__((packed));
00991 
00992 
00993     std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage& m );
00994     std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage* m );
00995     // -----------------------------------------------------------------------
00996 
00998     struct WriteSingleOutputRetMessage:
00999         public ModbusHeader
01000     {
01001         ModbusData start = { 0 };     
01002         ModbusData data = { 0 };     
01003         ModbusCRC crc = { 0 };
01004 
01005 
01006         // ------- from slave -------
01007         WriteSingleOutputRetMessage( ModbusMessage& m );
01008         WriteSingleOutputRetMessage& operator=( ModbusMessage& m );
01009         void init( ModbusMessage& m );
01010 
01011         // ------- to master -------
01016         WriteSingleOutputRetMessage( ModbusAddr _from, ModbusData start = 0 );
01017 
01019         void set( ModbusData start, ModbusData data );
01020 
01022         ModbusMessage transport_msg();
01023 
01027         inline static int szData()
01028         {
01029             return 2 * sizeof(ModbusData) + sizeof(ModbusCRC);
01030         }
01031     };
01032 
01033     std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage& m );
01034     std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage* m );
01035     // -----------------------------------------------------------------------
01037     struct DiagnosticMessage:
01038         public ModbusHeader
01039     {
01040         ModbusData subf = { 0 };
01041         ModbusData data[MAXLENPACKET / sizeof(ModbusData)];  
01043         // ------- from slave -------
01044         DiagnosticMessage( ModbusMessage& m );
01045         DiagnosticMessage& operator=( ModbusMessage& m );
01046         void init( ModbusMessage& m );
01050         static inline int szHead()
01051         {
01052             return sizeof(ModbusData); // subf
01053         }
01054 
01056         static int getDataLen( ModbusMessage& m );
01057         ModbusCRC crc = { 0 };
01058 
01059         // ------- to master -------
01060         DiagnosticMessage( ModbusAddr _from, DiagnosticsSubFunction subf, ModbusData d = 0 );
01061 
01066         bool addData( ModbusData d );
01067 
01069         void clear();
01070 
01072         inline bool isFull()
01073         {
01074             // (1)subf + data count
01075             return ( 1 + count >= MAXDATALEN );
01076         }
01077 
01079         size_t szData();
01080 
01082         ModbusMessage transport_msg();
01083 
01084         // Это поле не входит в стандарт modbus
01085         // оно вспомогательное и игнорируется при
01086         // преобразовании в ModbusMessage.
01087         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
01088         // Используйте специальную функцию transport_msg()
01089         int    count = { 0 };    
01090     };
01091     std::ostream& operator<<(std::ostream& os, DiagnosticMessage& m );
01092     std::ostream& operator<<(std::ostream& os, DiagnosticMessage* m );
01093     // -----------------------------------------------------------------------
01095     struct DiagnosticRetMessage:
01096         public DiagnosticMessage
01097     {
01098         DiagnosticRetMessage( ModbusMessage& m );
01099         DiagnosticRetMessage( DiagnosticMessage& m );
01100         DiagnosticRetMessage( ModbusAddr a, DiagnosticsSubFunction subf, ModbusData d = 0 );
01101     };
01102 
01103     std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage& m );
01104     std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage* m );
01105     // -----------------------------------------------------------------------
01107     struct MEIMessageRDI:
01108         public ModbusHeader
01109     {
01110         ModbusByte type;     
01111         ModbusByte devID;     
01112         ModbusByte objID;     
01114         ModbusCRC crc = { 0 };        
01116         // ------- to slave -------
01117         MEIMessageRDI( ModbusAddr addr, ModbusByte devID, ModbusByte objID );
01119         ModbusMessage transport_msg();
01120 
01121         // ------- from master -------
01122         MEIMessageRDI( ModbusMessage& m );
01123         MEIMessageRDI& operator=( ModbusMessage& m );
01124         void init( ModbusMessage& m );
01125 
01129         static inline int szHead()
01130         {
01131             return sizeof(ModbusByte) * 3;
01132         }
01133 
01135         static inline int szData()
01136         {
01137             return sizeof(ModbusByte) * 3 + szCRC;
01138         }
01139 
01140         // вспомогательные функции
01141         bool checkFormat();
01142 
01143     } __attribute__((packed));
01144     // -----------------------------------------------------------------------
01145     std::ostream& operator<<(std::ostream& os, MEIMessageRDI& m );
01146     std::ostream& operator<<(std::ostream& os, MEIMessageRDI* m );
01147     // -----------------------------------------------------------------------
01148 
01149     struct RDIObjectInfo
01150     {
01151         RDIObjectInfo(): id(0), val("") {}
01152         RDIObjectInfo( ModbusByte id, const std::string& v ): id(id), val(v) {}
01153         RDIObjectInfo( ModbusByte id, ModbusByte* dat, ModbusByte len );
01154 
01155         ModbusByte id;
01156         std::string val;
01157     };
01158 
01159     typedef std::list<RDIObjectInfo> RDIObjectList;
01160 
01162     struct MEIMessageRetRDI:
01163         public ModbusHeader
01164     {
01165         ModbusByte type;     
01166         ModbusByte devID;     
01167         ModbusByte conformity; 
01168         ModbusByte mf;         
01169         ModbusByte objID;     
01170         ModbusByte objNum;     
01172         RDIObjectList dlist;
01173         ModbusCRC crc = { 0 };
01174 
01175         // ------- from slave -------
01176         MEIMessageRetRDI();
01177         MEIMessageRetRDI( ModbusMessage& m );
01178         MEIMessageRetRDI& operator=( ModbusMessage& m );
01179         void init( ModbusMessage& m );
01180 
01181         // предварительная инициализации, только заголовочной части, без данных
01182         void pre_init( ModbusMessage& m );
01183 
01185         static inline int szHead()
01186         {
01187             return sizeof(ModbusByte) * 6;
01188         }
01189 
01190         //        /*! узнать длину данных следующих за предварительным заголовком ( в байтах ) */
01191         //        static int getDataLen( ModbusMessage& m );
01192 
01193         // ------- to master -------
01194         MEIMessageRetRDI( ModbusAddr _from, ModbusByte devID, ModbusByte conformity, ModbusByte mf, ModbusByte objID );
01195 
01200         bool addData( ModbusByte id, const std::string& value );
01201         bool addData( RDIObjectInfo& dat );
01202 
01204         void clear();
01205 
01207         inline bool isFull()
01208         {
01209             return ( bcnt >= MAXPDULEN );
01210         }
01211 
01213         size_t szData();
01214 
01216         ModbusMessage transport_msg();
01217 
01218         int bcnt = { 0 }; 
01219     };
01220 
01221     std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI& m );
01222     std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI* m );
01223     std::ostream& operator<<(std::ostream& os, RDIObjectList& dl );
01224     std::ostream& operator<<(std::ostream& os, RDIObjectList* dl );
01225     // -----------------------------------------------------------------------
01226     // -----------------------------------------------------------------------
01227 
01229     struct JournalCommandMessage:
01230         public ModbusHeader
01231     {
01232         ModbusData cmd = { 0 };            
01233         ModbusData num = { 0 };            
01234         ModbusCRC crc = { 0 };
01235 
01236         // -------------
01237         JournalCommandMessage( ModbusMessage& m );
01238         JournalCommandMessage& operator=( ModbusMessage& m );
01239 
01241         inline static int szData()
01242         {
01243             return sizeof(ModbusByte) * 4 + szCRC;
01244         }
01245 
01246     } __attribute__((packed));
01247 
01248     std::ostream& operator<<(std::ostream& os, JournalCommandMessage& m );
01249     std::ostream& operator<<(std::ostream& os, JournalCommandMessage* m );
01250     // -----------------------------------------------------------------------
01252     struct JournalCommandRetMessage:
01253         public ModbusHeader
01254     {
01255         ModbusByte bcnt = { 0 };                    
01256         //        ModbusByte data[MAXLENPACKET-1];    /*!< данные */
01257 
01258         // В связи со спецификой реализации ответной части (т.е. modbus master)
01259         // данные приходится делать не байтовым потоком, а "словами"
01260         // которые в свою очередь будут перевёрнуты при посылке...
01261         ModbusData data[MAXLENPACKET / sizeof(ModbusData)];  
01263         // -------------
01264         JournalCommandRetMessage( ModbusAddr _from );
01265 
01272         bool setData( ModbusByte* b, int len );
01273 
01275         void clear();
01276 
01278         inline bool isFull()
01279         {
01280             return ( count >= MAXDATALEN );
01281         }
01282 
01284         size_t szData();
01285 
01287         ModbusMessage transport_msg();
01288 
01289         // Это поле не входит в стандарт modbus
01290         // оно вспомогательное и игнорируется при
01291         // преобразовании в ModbusMessage.
01292         // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
01293         // Используйте специальную функцию transport_msg()
01294         size_t count = { 0 };    
01295     };
01296 
01297     std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage& m );
01298     std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage* m );
01299     // -----------------------------------------------------------------------
01303     struct JournalCommandRetOK:
01304         public JournalCommandRetMessage
01305     {
01306         // -------------
01307         JournalCommandRetOK( ModbusAddr _from );
01308         void set( ModbusData cmd, ModbusData ecode );
01309         static void set( JournalCommandRetMessage& m, ModbusData cmd, ModbusData ecode );
01310     };
01311 
01312     std::ostream& operator<<(std::ostream& os, JournalCommandRetOK& m );
01313     std::ostream& operator<<(std::ostream& os, JournalCommandRetOK* m );
01314     // -----------------------------------------------------------------------
01315 
01317     struct SetDateTimeMessage:
01318         public ModbusHeader
01319     {
01320         ModbusByte hour = { 0 };    
01321         ModbusByte min = { 0 };        
01322         ModbusByte sec = { 0 };        
01323         ModbusByte day = { 1 };        
01324         ModbusByte mon = { 1 };        
01325         ModbusByte year = { 0 };    
01326         ModbusByte century = { 20 };    
01328         ModbusCRC crc = { 0 };
01329 
01330         // ------- to slave -------
01331         SetDateTimeMessage( ModbusAddr addr );
01333         ModbusMessage transport_msg();
01334 
01335         // ------- from master -------
01336         SetDateTimeMessage( ModbusMessage& m );
01337         SetDateTimeMessage& operator=( ModbusMessage& m );
01338         SetDateTimeMessage();
01339 
01340         bool checkFormat();
01341 
01343         inline static int szData()
01344         {
01345             return sizeof(ModbusByte) * 7 + szCRC;
01346         }
01347 
01348     } __attribute__((packed));
01349 
01350     std::ostream& operator<<(std::ostream& os, SetDateTimeMessage& m );
01351     std::ostream& operator<<(std::ostream& os, SetDateTimeMessage* m );
01352     // -----------------------------------------------------------------------
01353 
01355     struct SetDateTimeRetMessage:
01356         public SetDateTimeMessage
01357     {
01358 
01359         // ------- from slave -------
01360         SetDateTimeRetMessage( ModbusMessage& m );
01361         SetDateTimeRetMessage& operator=( ModbusMessage& m );
01362         void init( ModbusMessage& m );
01363 
01364         // ------- to master -------
01365         SetDateTimeRetMessage( ModbusAddr _from );
01366         SetDateTimeRetMessage( const SetDateTimeMessage& query );
01367         static void cpy( SetDateTimeRetMessage& reply, SetDateTimeMessage& query );
01368 
01370         ModbusMessage transport_msg();
01371     };
01372     // -----------------------------------------------------------------------
01373 
01375     struct RemoteServiceMessage:
01376         public ModbusHeader
01377     {
01378         ModbusByte bcnt = { 0 };    
01381         ModbusByte data[MAXLENPACKET - sizeof(ModbusByte)];
01382         ModbusCRC crc = { 0 };        
01384         // -----------
01385         RemoteServiceMessage( ModbusMessage& m );
01386         RemoteServiceMessage& operator=( ModbusMessage& m );
01387         void init( ModbusMessage& m );
01388 
01390         size_t szData();
01391 
01395         static inline int szHead()
01396         {
01397             return sizeof(ModbusByte);    // bcnt
01398         }
01399 
01401         static int getDataLen( ModbusMessage& m );
01402 
01403     } __attribute__((packed));
01404 
01405     std::ostream& operator<<(std::ostream& os, RemoteServiceMessage& m );
01406     std::ostream& operator<<(std::ostream& os, RemoteServiceMessage* m );
01407     // -----------------------------------------------------------------------
01408     struct RemoteServiceRetMessage:
01409         public ModbusHeader
01410     {
01411         ModbusByte bcnt = { 0 };    
01413         ModbusByte data[MAXLENPACKET - sizeof(ModbusByte)];
01414 
01415         RemoteServiceRetMessage( ModbusAddr _from );
01416 
01423         bool setData( ModbusByte* b, int len );
01424 
01426         void clear();
01427 
01429         inline bool isFull()
01430         {
01431             return ( count >= sizeof(data) );
01432         }
01433 
01435         size_t szData();
01436 
01438         ModbusMessage transport_msg();
01439 
01440         // Это поле не входит в стандарт modbus
01441         // оно вспомогательное и игнорируется при
01442         // преобразовании в ModbusMessage.
01443         size_t count = { 0 };    
01444     };
01445     // -----------------------------------------------------------------------
01446 
01447     struct ReadFileRecordMessage:
01448         public ModbusHeader
01449     {
01450         struct SubRequest
01451         {
01452             ModbusByte reftype; 
01453             ModbusData numfile; 
01454             ModbusData numrec;  
01455             ModbusData reglen;  
01456         } __attribute__((packed));
01457 
01458         ModbusByte bcnt = { 0 };    
01461         SubRequest data[MAXLENPACKET / sizeof(SubRequest) - sizeof(ModbusByte)];
01462         ModbusCRC crc = { 0 };        
01464         // -----------
01465         ReadFileRecordMessage( ModbusMessage& m );
01466         ReadFileRecordMessage& operator=( ModbusMessage& m );
01467         void init( ModbusMessage& m );
01468 
01470         size_t szData();
01471 
01475         static inline int szHead()
01476         {
01477             return sizeof(ModbusByte);    // bcnt
01478         }
01479 
01481         static int getDataLen( ModbusMessage& m );
01482 
01484         bool checkFormat();
01485 
01486         // это поле служебное и не используется в релальном обмене
01487         size_t count = { 0 }; 
01488     };
01489 
01490     std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage& m );
01491     std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage* m );
01492     // -----------------------------------------------------------------------
01493 
01494     struct FileTransferMessage:
01495         public ModbusHeader
01496     {
01497         ModbusData numfile = { 0 };     
01498         ModbusData numpacket = { 0 };   
01499         ModbusCRC crc = { 0 };          
01501         // ------- to slave -------
01502         FileTransferMessage( ModbusAddr addr, ModbusData numfile, ModbusData numpacket );
01503         ModbusMessage transport_msg();     
01505         // ------- from master -------
01506         FileTransferMessage( ModbusMessage& m );
01507         FileTransferMessage& operator=( ModbusMessage& m );
01508         void init( ModbusMessage& m );
01509 
01511         static inline int szData()
01512         {
01513             return sizeof(ModbusData) * 2 + szCRC;
01514         }
01515 
01516     } __attribute__((packed));
01517 
01518     std::ostream& operator<<(std::ostream& os, FileTransferMessage& m );
01519     std::ostream& operator<<(std::ostream& os, FileTransferMessage* m );
01520     // -----------------------------------------------------------------------
01521 
01522     struct FileTransferRetMessage:
01523         public ModbusHeader
01524     {
01525         // 255 - max of bcnt...(1 byte)
01526         //        static const int MaxDataLen = 255 - szCRC - szModbusHeader - sizeof(ModbusData)*3 - sizeof(ModbusByte)*2;
01527         static const int MaxDataLen = MAXLENPACKET - sizeof(ModbusData) * 3 - sizeof(ModbusByte) * 2;
01528 
01529         ModbusByte bcnt;        
01530         ModbusData numfile;     
01531         ModbusData numpacks;     
01532         ModbusData packet;      
01533         ModbusByte dlen;        
01534         ModbusByte data[MaxDataLen];
01535 
01536 
01537         // ------- from slave -------
01538         FileTransferRetMessage( ModbusMessage& m );
01539         FileTransferRetMessage& operator=( ModbusMessage& m );
01540         void init( ModbusMessage& m );
01541         ModbusCRC crc = { 0 };
01542         static int szHead()
01543         {
01544             return sizeof(ModbusByte);
01545         }
01546         static int getDataLen( ModbusMessage& m );
01547 
01548         // ------- to master -------
01549         FileTransferRetMessage( ModbusAddr _from );
01550 
01554         bool set( ModbusData numfile, ModbusData file_num_packets, ModbusData packet, ModbusByte* b, ModbusByte len );
01555 
01557         void clear();
01558 
01560         size_t szData();
01561 
01563         ModbusMessage transport_msg();
01564     };
01565 
01566     std::ostream& operator<<(std::ostream& os, FileTransferRetMessage& m );
01567     std::ostream& operator<<(std::ostream& os, FileTransferRetMessage* m );
01568     // -----------------------------------------------------------------------
01569 } // end of ModbusRTU namespace
01570 // ---------------------------------------------------------------------------
01571 namespace ModbusTCP
01572 {
01573     struct MBAPHeader
01574     {
01575         ModbusRTU::ModbusData    tID; 
01576         ModbusRTU::ModbusData    pID; 
01577         ModbusRTU::ModbusData    len; 
01578         /*        ModbusRTU::ModbusByte    uID; */  /* <------- see ModbusHeader */
01579 
01580         MBAPHeader(): tID(0), pID(0), len(0) /*,uID(0) */ {}
01581 
01582         void swapdata();
01583 
01584     } __attribute__((packed));
01585 
01586     std::ostream& operator<<(std::ostream& os, MBAPHeader& m );
01587 
01588     // -----------------------------------------------------------------------
01589 } // end of namespace ModbusTCP
01590 // ---------------------------------------------------------------------------
01591 #endif // ModbusTypes_H_
01592 // ---------------------------------------------------------------------------