UniSet  2.6.0
ModbusTypes.h
1 // -------------------------------------------------------------------------
2 #ifndef ModbusTypes_H_
3 #define ModbusTypes_H_
4 // -------------------------------------------------------------------------
5 #include <ostream>
6 #include <bitset>
7 #include <string>
8 #include <list>
9 #include "ModbusRTUErrors.h"
10 // -------------------------------------------------------------------------
11 /* Основные предположения:
12  * - младший и старший байт переворачиваются только в CRC
13  * - В случае неправильного формата пакета(запроса), логической ошибки и т.п
14  * ОТВЕТ просто не посылается, а пакет отбрасывается...
15  * - CRC считается по всей посылке (с начальным адресом)
16  * - CRC инициализируется значением 0xffff
17  * - CRC не переворачивается
18  * - Все двухбайтовые слова переворачиваются. Порядок байт: старший младший
19 */
20 // -------------------------------------------------------------------------
21 namespace uniset
22 {
23  // -------------------------------------------------------------------------
24  namespace ModbusRTU
25  {
26  // Базовые типы
27  typedef uint8_t ModbusByte;
28  const size_t BitsPerByte = 8;
29  typedef uint8_t ModbusAddr;
30  typedef uint16_t ModbusData;
31  const size_t BitsPerData = 16;
32  typedef uint16_t ModbusCRC;
34  // ---------------------------------------------------------------------
36  enum SlaveFunctionCode
37  {
38  fnUnknown = 0x00,
39  fnReadCoilStatus = 0x01,
40  fnReadInputStatus = 0x02,
41  fnReadOutputRegisters = 0x03,
42  fnReadInputRegisters = 0x04,
43  fnForceSingleCoil = 0x05,
44  fnWriteOutputSingleRegister = 0x06,
45  fnDiagnostics = 0x08,
46  fnForceMultipleCoils = 0x0F,
47  fnWriteOutputRegisters = 0x10,
48  fnReadFileRecord = 0x14,
49  fnWriteFileRecord = 0x15,
50  fnMEI = 0x2B,
51  fnSetDateTime = 0x50,
52  fnRemoteService = 0x53,
53  fnJournalCommand = 0x65,
54  fnFileTransfer = 0x66
55  };
56 
58  enum DiagnosticsSubFunction
59  {
60  subEcho = 0x00,
61  dgRestartComm = 0x01,
62  dgDiagReg = 0x02,
63  dgChangeASCII = 0x03,
64  dgForceListen = 0x04,
65  // 05.. 09 RESERVED
66  dgClearCounters = 0x0A,
67  dgBusMsgCount = 0x0B,
68  dgBusErrCount = 0x0C,
69  dgBusExceptCount = 0x0D,
70  dgMsgSlaveCount = 0x0E,
71  dgNoNoResponseCount = 0x0F,
72  dgSlaveNAKCount = 0x10,
73  dgSlaveBusyCount = 0x11,
74  dgBusCharOverrunCount = 0x12,
75  // = 0x13, /*!< RESERVED */
76  dgClearOverrunCounter = 0x14
77  // 21 ...65535 RESERVED
78  };
79 
80 
81  typedef unsigned long RegID;
82 
89  RegID genRegID( const ModbusRTU::ModbusData r, const int fn );
90 
91  // определение размера данных в зависимости от типа сообщения
92  // возвращает -1 - если динамический размер сообщения или размер неизвестен
93  ssize_t szRequestDiagnosticData( DiagnosticsSubFunction f );
94 
96  enum RDIObjectID
97  {
98  rdiVendorName = 0x0,
99  rdiProductCode = 0x1,
100  rdiMajorMinorRevision = 0x2,
101  rdiVendorURL = 0x3,
102  rdiProductName = 0x4,
103  rdiModelName = 0x5,
104  rdiUserApplicationName = 0x6
105  // 0x07 .. 0x7F - reserved
106  // 0x80 .. 0xFF - optionaly defined (product dependant)
107  };
108 
110  enum RDIRequestDeviceID
111  {
112  rdevMinNum = 0,
113  rdevBasicDevice = 0x1, // request to get the basic device identification (stream access)
114  rdevRegularDevice = 0x2, // request to get the regular device identification (stream access)
115  rdevExtentedDevice = 0x3, // request to get the extended device identification (stream access)
116  rdevSpecificDevice = 0x4, // request to get the extended device identification (stream access)
117  rdevMaxNum = 0x5
118  };
119 
120  std::string rdi2str( int id );
121  // -----------------------------------------------------------------------
122 
124  enum
125  {
127  MAXLENPACKET = 508,
128  BroadcastAddr = 255,
129  MAXPDULEN = 253, // 255 - 2(CRC)
130  MAXDATALEN = 125
134  };
135 
136  const unsigned char MBErrMask = 0x80;
137  // ---------------------------------------------------------------------
138  uint16_t SWAPSHORT( uint16_t x );
139  // ---------------------------------------------------------------------
141  ModbusCRC checkCRC( ModbusByte* start, size_t len );
142  const size_t szCRC = sizeof(ModbusCRC);
143  // ---------------------------------------------------------------------
145  std::ostream& mbPrintMessage(std::ostream& os, ModbusByte* b, size_t len );
146  // -------------------------------------------------------------------------
147  ModbusAddr str2mbAddr( const std::string& val );
148  ModbusData str2mbData( const std::string& val );
149  std::string dat2str( const ModbusData dat );
150  std::string addr2str( const ModbusAddr addr );
151  std::string b2str( const ModbusByte b );
152  // -------------------------------------------------------------------------
153  float dat2f( const ModbusData dat1, const ModbusData dat2 );
154  // -------------------------------------------------------------------------
155  bool isWriteFunction( SlaveFunctionCode c );
156  bool isReadFunction( SlaveFunctionCode c );
157  // -------------------------------------------------------------------------
160  {
161  ModbusAddr addr;
162  ModbusByte func;
164  ModbusHeader(): addr(0), func(0) {}
165  } __attribute__((packed));
166 
167  const size_t szModbusHeader = sizeof(ModbusHeader);
168 
169  std::ostream& operator<<(std::ostream& os, const ModbusHeader& m );
170  std::ostream& operator<<(std::ostream& os, const ModbusHeader* m );
171  // -----------------------------------------------------------------------
172  struct ADUHeader
173  {
174  ModbusRTU::ModbusData tID;
175  ModbusRTU::ModbusData pID;
176  ModbusRTU::ModbusData len;
178  ADUHeader(): tID(0), pID(0), len(0) {}
179 
180  void swapdata();
181 
182  } __attribute__((packed));
183 
184  std::ostream& operator<<(std::ostream& os, const ADUHeader& m );
185  // -----------------------------------------------------------------------
186 
191  {
192  ModbusMessage();
193 
194  ModbusMessage( ModbusMessage&& ) = default;
195  ModbusMessage& operator=(ModbusMessage&& ) = default;
196  ModbusMessage( const ModbusMessage& ) = default;
197  ModbusMessage& operator=(const ModbusMessage& ) = default;
198 
199  inline ModbusByte func() const
200  {
201  return pduhead.func;
202  }
203  inline ModbusAddr addr() const
204  {
205  return pduhead.addr;
206  }
207  inline ModbusRTU::ModbusData tID() const
208  {
209  return aduhead.tID;
210  }
211  inline ModbusRTU::ModbusData pID() const
212  {
213  return aduhead.pID;
214  }
215  inline ModbusRTU::ModbusData aduLen() const
216  {
217  return aduhead.len;
218  }
219 
220  unsigned char* buf();
221  ModbusRTU::ModbusData len() const;
222  void swapHead();
223  void makeHead( ModbusRTU::ModbusData tID, bool noCRC = true, ModbusRTU::ModbusData pID = 0 );
224 
225  ModbusRTU::ModbusData pduLen() const;
226  ModbusCRC pduCRC( size_t len ) const;
227  static size_t maxSizeOfMessage();
228 
229  void clear();
230 
231  ADUHeader aduhead;
232  ModbusHeader pduhead;
233  ModbusByte data[MAXLENPACKET + szCRC];
235  // Это поле вспомогательное и игнорируется при пересылке
236  size_t dlen = { 0 };
237  } __attribute__((packed));
238 
239  std::ostream& operator<<(std::ostream& os, const ModbusMessage& m );
240  std::ostream& operator<<(std::ostream& os, const ModbusMessage* m );
241  // -----------------------------------------------------------------------
244  public ModbusHeader
245  {
246  ModbusByte ecode = { erNoError };
247  ModbusCRC crc = { 0 };
248 
249  // ------- from slave -------
250  ErrorRetMessage( const ModbusMessage& m );
251  ErrorRetMessage& operator=( const ModbusMessage& m );
252  void init( const ModbusMessage& m );
253 
254  // ------- to master -------
255  ErrorRetMessage( ModbusAddr _from, ModbusByte _func, ModbusByte ecode );
256 
259 
263  inline static size_t szData()
264  {
265  return sizeof(ModbusByte) + szCRC;
266  }
267  };
268 
269  std::ostream& operator<<(std::ostream& os, ErrorRetMessage& m );
270  std::ostream& operator<<(std::ostream& os, ErrorRetMessage* m );
271  // -----------------------------------------------------------------------
272  struct DataBits
273  {
274  DataBits( ModbusByte b );
275  DataBits( std::string s ); // example "10001111"
276  DataBits();
277 
278  const DataBits& operator=(const ModbusByte& r);
279 
280  operator ModbusByte();
281  ModbusByte mbyte();
282 
283  bool operator[]( const size_t i )
284  {
285  return b[i];
286  }
287  void set( int n, bool s )
288  {
289  b.set(n, s);
290  }
291 
292  std::bitset<BitsPerByte> b;
293  };
294 
295  std::ostream& operator<<(std::ostream& os, DataBits& m );
296  std::ostream& operator<<(std::ostream& os, DataBits* m );
297  // -----------------------------------------------------------------------
298  struct DataBits16
299  {
300  DataBits16( ModbusData d );
301  DataBits16( const std::string& s ); // example "1000111110001111"
302  DataBits16();
303 
304  const DataBits16& operator=(const ModbusData& r);
305 
306  operator ModbusData();
307  ModbusData mdata() const;
308 
309  bool operator[]( const size_t i )
310  {
311  return b[i];
312  }
313  void set( int n, bool s )
314  {
315  b.set(n, s);
316  }
317 
318  std::bitset<BitsPerData> b;
319  };
320 
321  std::ostream& operator<<(std::ostream& os, DataBits16& m );
322  std::ostream& operator<<(std::ostream& os, DataBits16* m );
323  // -----------------------------------------------------------------------
326  public ModbusHeader
327  {
328  ModbusData start = { 0 };
329  ModbusData count = { 0 };
330  ModbusCRC crc = { 0 };
331 
332  // ------- to slave -------
333  ReadCoilMessage( ModbusAddr addr, ModbusData start, ModbusData count );
336 
337  // ------- from master -------
338  ReadCoilMessage( const ModbusMessage& m );
339  ReadCoilMessage& operator=( const ModbusMessage& m );
340  void init( const ModbusMessage& m );
341 
343  inline static size_t szData()
344  {
345  return sizeof(ModbusData) * 2 + szCRC;
346  }
347 
348  } __attribute__((packed));
349 
350  std::ostream& operator<<(std::ostream& os, ReadCoilMessage& m );
351  std::ostream& operator<<(std::ostream& os, ReadCoilMessage* m );
352 
353  // -----------------------------------------------------------------------
354 
357  public ModbusHeader
358  {
359  ModbusByte bcnt = { 0 };
360  ModbusByte data[MAXLENPACKET];
362  // ------- from slave -------
363  ReadCoilRetMessage( const ModbusMessage& m );
364  ReadCoilRetMessage& operator=( const ModbusMessage& m );
365  void init( const ModbusMessage& m );
366 
370  static inline int szHead()
371  {
372  return sizeof(ModbusByte); // bcnt
373  }
374 
376  static size_t getDataLen( const ModbusMessage& m );
377  ModbusCRC crc = { 0 };
378 
379  // ------- to master -------
380  ReadCoilRetMessage( ModbusAddr _from );
381 
386  bool addData( DataBits d );
387 
395  bool setBit( unsigned char dnum, unsigned char bnum, bool state );
396 
403  bool getData( unsigned char bnum, DataBits& d ) const;
404 
406  void clear();
407 
409  inline bool isFull() const
410  {
411  return ( (int)bcnt >= MAXPDULEN );
412  }
413 
415  size_t szData() const;
416 
419  };
420 
421  std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage& m );
422  std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage* m );
423  // -----------------------------------------------------------------------
426  public ModbusHeader
427  {
428  ModbusData start = { 0 };
429  ModbusData count = { 0 };
430  ModbusCRC crc = { 0 };
431 
432  // ------- to slave -------
433  ReadInputStatusMessage( ModbusAddr addr, ModbusData start, ModbusData count );
434 
437 
438  // ------- from master -------
440  ReadInputStatusMessage& operator=( const ModbusMessage& m );
441 
442  void init( const ModbusMessage& m );
443 
445  inline static size_t szData()
446  {
447  return sizeof(ModbusData) * 2 + szCRC;
448  }
449 
450  } __attribute__((packed));
451 
452  std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage& m );
453  std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage* m );
454  // -----------------------------------------------------------------------
457  public ModbusHeader
458  {
459  ModbusByte bcnt = { 0 };
460  ModbusByte data[MAXLENPACKET];
462  // ------- from slave -------
464  ReadInputStatusRetMessage& operator=( const ModbusMessage& m );
465  void init( const ModbusMessage& m );
466 
470  static inline size_t szHead()
471  {
472  return sizeof(ModbusByte); // bcnt
473  }
474 
476  static size_t getDataLen( const ModbusMessage& m );
477  ModbusCRC crc = { 0 };
478 
479  // ------- to master -------
480  ReadInputStatusRetMessage( ModbusAddr _from );
481 
486  bool addData( DataBits d );
487 
495  bool setBit( unsigned char dnum, unsigned char bnum, bool state );
496 
503  bool getData( unsigned char dnum, DataBits& d ) const;
504 
506  void clear();
507 
509  inline bool isFull() const
510  {
511  return ( (int)bcnt >= MAXPDULEN );
512  }
513 
515  size_t szData() const;
516 
519  };
520 
521  std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage& m );
522  std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage* m );
523  // -----------------------------------------------------------------------
524 
527  public ModbusHeader
528  {
529  ModbusData start = { 0 };
530  ModbusData count = { 0 };
531  ModbusCRC crc = { 0 };
532 
533  // ------- to slave -------
534  ReadOutputMessage( ModbusAddr addr, ModbusData start, ModbusData count );
537 
538  // ------- from master -------
539  ReadOutputMessage( const ModbusMessage& m );
540  ReadOutputMessage& operator=( const ModbusMessage& m );
541  void init( const ModbusMessage& m );
542 
544  inline static size_t szData()
545  {
546  return sizeof(ModbusData) * 2 + szCRC;
547  }
548 
549  } __attribute__((packed));
550 
551  std::ostream& operator<<(std::ostream& os, ReadOutputMessage& m );
552  std::ostream& operator<<(std::ostream& os, ReadOutputMessage* m );
553  // -----------------------------------------------------------------------
556  public ModbusHeader
557  {
558  ModbusByte bcnt = { 0 };
559  ModbusData data[MAXLENPACKET / sizeof(ModbusData)];
561  // ------- from slave -------
563  ReadOutputRetMessage& operator=( const ModbusMessage& m );
564  void init( const ModbusMessage& m );
568  static inline size_t szHead()
569  {
570  // bcnt
571  return sizeof(ModbusByte);
572  }
573 
575  static size_t getDataLen( const ModbusMessage& m );
576  ModbusCRC crc = { 0 };
577 
578  // ------- to master -------
579  ReadOutputRetMessage( ModbusAddr _from );
580 
585  bool addData( ModbusData d );
586 
588  void clear();
589 
591  inline bool isFull() const
592  {
593  return ( count * sizeof(ModbusData) >= MAXLENPACKET );
594  }
595 
597  size_t szData() const;
598 
601 
602  // Это поле не входит в стандарт modbus
603  // оно вспомогательное и игнорируется при
604  // преобразовании в ModbusMessage.
605  // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
606  // Используйте специальную функцию transport_msg()
607  size_t count = { 0 };
608  };
609 
610  std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage& m );
611  std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage* m );
612  // -----------------------------------------------------------------------
615  public ModbusHeader
616  {
617  ModbusData start = { 0 };
618  ModbusData count = { 0 };
619  ModbusCRC crc = { 0 };
620 
621  // ------- to slave -------
622  ReadInputMessage( ModbusAddr addr, ModbusData start, ModbusData count );
625 
626  // ------- from master -------
627  ReadInputMessage( const ModbusMessage& m );
628  ReadInputMessage& operator=( const ModbusMessage& m );
629  void init( const ModbusMessage& m );
630 
632  inline static size_t szData()
633  {
634  return sizeof(ModbusData) * 2 + szCRC;
635  }
636 
637  } __attribute__((packed));
638 
639  std::ostream& operator<<(std::ostream& os, ReadInputMessage& m );
640  std::ostream& operator<<(std::ostream& os, ReadInputMessage* m );
641  // -----------------------------------------------------------------------
642 
645  public ModbusHeader
646  {
647  ModbusByte bcnt = { 0 };
648  ModbusData data[MAXLENPACKET / sizeof(ModbusData)];
650  // ------- from slave -------
652  ReadInputRetMessage& operator=( const ModbusMessage& m );
653  void init( const ModbusMessage& m );
657  static inline size_t szHead()
658  {
659  // bcnt
660  return sizeof(ModbusByte);
661  }
662 
664  static size_t getDataLen( const ModbusMessage& m );
665  ModbusCRC crc = { 0 };
666 
667  // ------- to master -------
668  ReadInputRetMessage( ModbusAddr _from );
669 
674  bool addData( ModbusData d );
675 
677  void clear();
678 
680  inline bool isFull() const
681  {
682  return ( count * sizeof(ModbusData) >= MAXLENPACKET );
683  }
684 
685  void swapData();
686 
688  size_t szData();
689 
692 
693  // Это поле не входит в стандарт modbus
694  // оно вспомогательное и игнорируется при
695  // преобразовании в ModbusMessage.
696  // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
697  // Используйте специальную функцию transport_msg()
698  size_t count = { 0 };
699  };
700 
701  std::ostream& operator<<(std::ostream& os, ReadInputRetMessage& m );
702  std::ostream& operator<<(std::ostream& os, ReadInputRetMessage* m );
703  // -----------------------------------------------------------------------
706  public ModbusHeader
707  {
708  ModbusData start = { 0 };
709  ModbusData quant = { 0 };
710  ModbusByte bcnt = { 0 };
712  ModbusByte data[MAXLENPACKET - sizeof(ModbusData) * 2 - sizeof(ModbusByte)];
713  ModbusCRC crc = { 0 };
715  // ------- to slave -------
716  ForceCoilsMessage( ModbusAddr addr, ModbusData start );
719 
724  bool addData( DataBits d );
725 
726  // return number of bit
727  // -1 - error
728  int addBit( bool state );
729 
730  bool setBit( int nbit, bool state );
731 
732  inline size_t last() const
733  {
734  return quant;
735  }
736 
743  bool getData( unsigned char dnum, DataBits& d );
744 
745  bool getBit( unsigned char bnum );
746 
747  void clear();
748  inline bool isFull() const
749  {
750  return ( (int)bcnt >= MAXPDULEN );
751  }
752 
753  // ------- from master -------
754  ForceCoilsMessage( const ModbusMessage& m );
755  ForceCoilsMessage& operator=( const ModbusMessage& m );
756  void init( const ModbusMessage& m );
757 
759  size_t szData() const;
760 
764  static inline size_t szHead()
765  {
766  // start + quant + count
767  return sizeof(ModbusData) * 2 + sizeof(ModbusByte);
768  }
769 
771  static size_t getDataLen( const ModbusMessage& m );
772 
776  bool checkFormat() const;
777 
778  } __attribute__((packed));
779 
780  std::ostream& operator<<(std::ostream& os, ForceCoilsMessage& m );
781  std::ostream& operator<<(std::ostream& os, ForceCoilsMessage* m );
782  // -----------------------------------------------------------------------
785  public ModbusHeader
786  {
787  ModbusData start = { 0 };
788  ModbusData quant = { 0 };
789  ModbusCRC crc = { 0 };
790 
791  // ------- from slave -------
793  ForceCoilsRetMessage& operator=( const ModbusMessage& m );
794  void init( const ModbusMessage& m );
795 
796  // ------- to master -------
802  ForceCoilsRetMessage( ModbusAddr _from, ModbusData start = 0, ModbusData quant = 0 );
803 
805  void set( ModbusData start, ModbusData quant );
806 
809 
813  inline static size_t szData()
814  {
815  return sizeof(ModbusData) * 2 + sizeof(ModbusCRC);
816  }
817  };
818 
819  std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage& m );
820  std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage* m );
821  // -----------------------------------------------------------------------
822 
825  public ModbusHeader
826  {
827  ModbusData start = { 0 };
828  ModbusData quant = { 0 };
829  ModbusByte bcnt = { 0 };
831  ModbusData data[MAXLENPACKET / sizeof(ModbusData) - sizeof(ModbusData) * 2 - sizeof(ModbusByte)];
832  ModbusCRC crc = { 0 };
834  // ------- to slave -------
835  WriteOutputMessage( ModbusAddr addr, ModbusData start );
838 
839  bool addData( ModbusData d );
840  void clear();
841  inline bool isFull() const
842  {
843  return ( quant >= MAXDATALEN );
844  }
845 
846  // ------- from master -------
847  WriteOutputMessage( const ModbusMessage& m );
848  WriteOutputMessage& operator=( const ModbusMessage& m );
849  void init( const ModbusMessage& m );
850 
852  size_t szData() const;
853 
857  static inline size_t szHead()
858  {
859  // start + quant + count
860  return sizeof(ModbusData) * 2 + sizeof(ModbusByte);
861  }
862 
864  static size_t getDataLen( const ModbusMessage& m );
865 
869  bool checkFormat() const;
870 
871  } __attribute__((packed));
872 
873 
874  std::ostream& operator<<(std::ostream& os, WriteOutputMessage& m );
875  std::ostream& operator<<(std::ostream& os, WriteOutputMessage* m );
876 
879  public ModbusHeader
880  {
881  ModbusData start = { 0 };
882  ModbusData quant = { 0 };
884  // ------- from slave -------
886  WriteOutputRetMessage& operator=( const ModbusMessage& m );
887  void init( const ModbusMessage& m );
888  ModbusCRC crc = { 0 };
889 
890  // ------- to master -------
896  WriteOutputRetMessage( ModbusAddr _from, ModbusData start = 0, ModbusData quant = 0 );
897 
899  void set( ModbusData start, ModbusData quant );
900 
903 
907  inline static size_t szData()
908  {
909  return sizeof(ModbusData) * 2 + sizeof(ModbusCRC);
910  }
911  };
912 
913  std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage& m );
914  std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage* m );
915  // -----------------------------------------------------------------------
918  public ModbusHeader
919  {
920  ModbusData start = { 0 };
921  ModbusData data = { 0 };
922  ModbusCRC crc = { 0 };
925  inline bool cmd()
926  {
927  return (data & 0xFF00);
928  }
929 
930  // ------- to slave -------
931  ForceSingleCoilMessage( ModbusAddr addr, ModbusData reg, bool state );
934 
935  // ------- from master -------
937  ForceSingleCoilMessage& operator=( const ModbusMessage& m );
938  void init( const ModbusMessage& m );
939 
941  size_t szData() const;
942 
946  static inline size_t szHead()
947  {
948  return sizeof(ModbusData);
949  }
950 
954  static size_t getDataLen( const ModbusMessage& m );
955 
959  bool checkFormat() const;
960  } __attribute__((packed));
961 
962 
963  std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage& m );
964  std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage* m );
965  // -----------------------------------------------------------------------
966 
969  public ModbusHeader
970  {
971  ModbusData start = { 0 };
972  ModbusData data = { 0 };
973  ModbusCRC crc = { 0 };
974 
976  inline bool cmd() const
977  {
978  return (data & 0xFF00);
979  }
980 
981  // ------- from slave -------
983  ForceSingleCoilRetMessage& operator=( const ModbusMessage& m );
984  void init( const ModbusMessage& m );
985 
986  // ------- to master -------
991  ForceSingleCoilRetMessage( ModbusAddr _from );
992 
994  void set( ModbusData start, bool cmd );
995 
998 
1002  inline static size_t szData()
1003  {
1004  return 2 * sizeof(ModbusData) + sizeof(ModbusCRC);
1005  }
1006  };
1007 
1008  std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage& m );
1009  std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage* m );
1010  // -----------------------------------------------------------------------
1011 
1014  public ModbusHeader
1015  {
1016  ModbusData start = { 0 };
1017  ModbusData data = { 0 };
1018  ModbusCRC crc = { 0 };
1021  // ------- to slave -------
1022  WriteSingleOutputMessage( ModbusAddr addr, ModbusData reg = 0, ModbusData data = 0 );
1025 
1026  // ------- from master -------
1028  WriteSingleOutputMessage& operator=( const ModbusMessage& m );
1029  void init( const ModbusMessage& m );
1030 
1032  size_t szData() const;
1033 
1037  static inline size_t szHead()
1038  {
1039  return sizeof(ModbusData);
1040  }
1041 
1045  static size_t getDataLen( const ModbusMessage& m );
1046 
1050  bool checkFormat();
1051  } __attribute__((packed));
1052 
1053 
1054  std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage& m );
1055  std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage* m );
1056  // -----------------------------------------------------------------------
1057 
1060  public ModbusHeader
1061  {
1062  ModbusData start = { 0 };
1063  ModbusData data = { 0 };
1064  ModbusCRC crc = { 0 };
1065 
1066 
1067  // ------- from slave -------
1069  WriteSingleOutputRetMessage& operator=( const ModbusMessage& m );
1070  void init( const ModbusMessage& m );
1071 
1072  // ------- to master -------
1077  WriteSingleOutputRetMessage( ModbusAddr _from, ModbusData start = 0 );
1078 
1080  void set( ModbusData start, ModbusData data );
1081 
1084 
1088  inline static size_t szData()
1089  {
1090  return 2 * sizeof(ModbusData) + sizeof(ModbusCRC);
1091  }
1092  };
1093 
1094  std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage& m );
1095  std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage* m );
1096  // -----------------------------------------------------------------------
1099  public ModbusHeader
1100  {
1101  ModbusData subf = { 0 };
1102  ModbusData data[MAXLENPACKET / sizeof(ModbusData)];
1104  // ------- from slave -------
1105  DiagnosticMessage( const ModbusMessage& m );
1106  DiagnosticMessage& operator=( const ModbusMessage& m );
1107  void init( const ModbusMessage& m );
1111  static inline size_t szHead()
1112  {
1113  return sizeof(ModbusData); // subf
1114  }
1115 
1117  static size_t getDataLen( const ModbusMessage& m );
1118  ModbusCRC crc = { 0 };
1119 
1120  // ------- to master -------
1121  DiagnosticMessage( ModbusAddr _from, DiagnosticsSubFunction subf, ModbusData d = 0 );
1122 
1127  bool addData( ModbusData d );
1128 
1130  void clear();
1131 
1133  inline bool isFull() const
1134  {
1135  // (1)subf + data count
1136  return ( 1 + count >= MAXDATALEN );
1137  }
1138 
1140  size_t szData() const;
1141 
1144 
1145  // Это поле не входит в стандарт modbus
1146  // оно вспомогательное и игнорируется при
1147  // преобразовании в ModbusMessage.
1148  // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
1149  // Используйте специальную функцию transport_msg()
1150  size_t count = { 0 };
1151  };
1152  std::ostream& operator<<(std::ostream& os, DiagnosticMessage& m );
1153  std::ostream& operator<<(std::ostream& os, DiagnosticMessage* m );
1154  // -----------------------------------------------------------------------
1157  public DiagnosticMessage
1158  {
1159  DiagnosticRetMessage( const ModbusMessage& m );
1161  DiagnosticRetMessage( ModbusAddr a, DiagnosticsSubFunction subf, ModbusData d = 0 );
1162  };
1163 
1164  std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage& m );
1165  std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage* m );
1166  // -----------------------------------------------------------------------
1169  public ModbusHeader
1170  {
1171  ModbusByte type;
1172  ModbusByte devID;
1173  ModbusByte objID;
1175  ModbusCRC crc = { 0 };
1177  // ------- to slave -------
1178  MEIMessageRDI( ModbusAddr addr, ModbusByte devID, ModbusByte objID );
1181 
1182  // ------- from master -------
1183  MEIMessageRDI( const ModbusMessage& m );
1184  MEIMessageRDI& operator=( const ModbusMessage& m );
1185  void init( const ModbusMessage& m );
1186 
1190  static inline size_t szHead()
1191  {
1192  return sizeof(ModbusByte) * 3;
1193  }
1194 
1196  static inline size_t szData()
1197  {
1198  return sizeof(ModbusByte) * 3 + szCRC;
1199  }
1200 
1201  // вспомогательные функции
1202  bool checkFormat() const;
1203 
1204  } __attribute__((packed));
1205  // -----------------------------------------------------------------------
1206  std::ostream& operator<<(std::ostream& os, MEIMessageRDI& m );
1207  std::ostream& operator<<(std::ostream& os, MEIMessageRDI* m );
1208  // -----------------------------------------------------------------------
1209 
1211  {
1212  RDIObjectInfo(): id(0), val("") {}
1213  RDIObjectInfo( ModbusByte id, const std::string& v ): id(id), val(v) {}
1214  RDIObjectInfo( ModbusByte id, const ModbusByte* dat, ModbusByte len );
1215 
1216  ModbusByte id;
1217  std::string val;
1218  };
1219 
1220  typedef std::list<RDIObjectInfo> RDIObjectList;
1221 
1224  public ModbusHeader
1225  {
1226  ModbusByte type;
1227  ModbusByte devID;
1228  ModbusByte conformity;
1229  ModbusByte mf;
1230  ModbusByte objID;
1231  ModbusByte objNum;
1233  RDIObjectList dlist;
1234  ModbusCRC crc = { 0 };
1235 
1236  // ------- from slave -------
1237  MEIMessageRetRDI();
1238  MEIMessageRetRDI( const ModbusMessage& m );
1239  MEIMessageRetRDI& operator=( const ModbusMessage& m );
1240  void init( const ModbusMessage& m );
1241 
1242  // предварительная инициализации, только заголовочной части, без данных
1243  void pre_init( const ModbusMessage& m );
1244 
1246  static inline size_t szHead()
1247  {
1248  return sizeof(ModbusByte) * 6;
1249  }
1250 
1251  // /*! узнать длину данных следующих за предварительным заголовком ( в байтах ) */
1252  // static int getDataLen( ModbusMessage& m );
1253 
1254  // ------- to master -------
1255  MEIMessageRetRDI( ModbusAddr _from, ModbusByte devID, ModbusByte conformity, ModbusByte mf, ModbusByte objID );
1256 
1261  bool addData( ModbusByte id, const std::string& value );
1262  bool addData( RDIObjectInfo& dat );
1263 
1265  void clear();
1266 
1268  inline bool isFull() const
1269  {
1270  return ( bcnt >= MAXPDULEN );
1271  }
1272 
1274  size_t szData() const;
1275 
1278 
1279  size_t bcnt = { 0 };
1280  };
1281 
1282  std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI& m );
1283  std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI* m );
1284  std::ostream& operator<<(std::ostream& os, RDIObjectList& dl );
1285  std::ostream& operator<<(std::ostream& os, RDIObjectList* dl );
1286  // -----------------------------------------------------------------------
1287  // -----------------------------------------------------------------------
1288 
1291  public ModbusHeader
1292  {
1293  ModbusData cmd = { 0 };
1294  ModbusData num = { 0 };
1295  ModbusCRC crc = { 0 };
1296 
1297  // -------------
1299  JournalCommandMessage& operator=( const ModbusMessage& m );
1300 
1302  inline static size_t szData()
1303  {
1304  return sizeof(ModbusByte) * 4 + szCRC;
1305  }
1306 
1307  } __attribute__((packed));
1308 
1309  std::ostream& operator<<(std::ostream& os, JournalCommandMessage& m );
1310  std::ostream& operator<<(std::ostream& os, JournalCommandMessage* m );
1311  // -----------------------------------------------------------------------
1314  public ModbusHeader
1315  {
1316  ModbusByte bcnt = { 0 };
1317  // ModbusByte data[MAXLENPACKET-1]; /*!< данные */
1318 
1319  // В связи со спецификой реализации ответной части (т.е. modbus master)
1320  // данные приходится делать не байтовым потоком, а "словами"
1321  // которые в свою очередь будут перевёрнуты при посылке...
1322  ModbusData data[MAXLENPACKET / sizeof(ModbusData)];
1324  // -------------
1325  JournalCommandRetMessage( ModbusAddr _from );
1326 
1333  bool setData( ModbusByte* b, int len );
1334 
1336  void clear();
1337 
1339  inline bool isFull() const
1340  {
1341  return ( count >= MAXDATALEN );
1342  }
1343 
1345  size_t szData() const;
1346 
1349 
1350  // Это поле не входит в стандарт modbus
1351  // оно вспомогательное и игнорируется при
1352  // преобразовании в ModbusMessage.
1353  // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
1354  // Используйте специальную функцию transport_msg()
1355  size_t count = { 0 };
1356  };
1357 
1358  std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage& m );
1359  std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage* m );
1360  // -----------------------------------------------------------------------
1366  {
1367  // -------------
1368  JournalCommandRetOK( ModbusAddr _from );
1369  void set( ModbusData cmd, ModbusData ecode );
1370  static void set( JournalCommandRetMessage& m, ModbusData cmd, ModbusData ecode );
1371  };
1372 
1373  std::ostream& operator<<(std::ostream& os, JournalCommandRetOK& m );
1374  std::ostream& operator<<(std::ostream& os, JournalCommandRetOK* m );
1375  // -----------------------------------------------------------------------
1376 
1379  public ModbusHeader
1380  {
1381  ModbusByte hour = { 0 };
1382  ModbusByte min = { 0 };
1383  ModbusByte sec = { 0 };
1384  ModbusByte day = { 1 };
1385  ModbusByte mon = { 1 };
1386  ModbusByte year = { 0 };
1387  ModbusByte century = { 20 };
1389  ModbusCRC crc = { 0 };
1390 
1391  // ------- to slave -------
1392  SetDateTimeMessage( ModbusAddr addr );
1395 
1396  // ------- from master -------
1397  SetDateTimeMessage( const ModbusMessage& m );
1398  SetDateTimeMessage& operator=( const ModbusMessage& m );
1400 
1401  bool checkFormat() const;
1402 
1404  inline static size_t szData()
1405  {
1406  return sizeof(ModbusByte) * 7 + szCRC;
1407  }
1408 
1409  } __attribute__((packed));
1410 
1411  std::ostream& operator<<(std::ostream& os, SetDateTimeMessage& m );
1412  std::ostream& operator<<(std::ostream& os, SetDateTimeMessage* m );
1413  // -----------------------------------------------------------------------
1414 
1417  public SetDateTimeMessage
1418  {
1419 
1420  // ------- from slave -------
1422  SetDateTimeRetMessage& operator=( const ModbusMessage& m );
1423  void init( const ModbusMessage& m );
1424 
1425  // ------- to master -------
1426  SetDateTimeRetMessage( ModbusAddr _from );
1427  SetDateTimeRetMessage( const SetDateTimeMessage& query );
1428  static void cpy( SetDateTimeRetMessage& reply, const SetDateTimeMessage& query );
1429 
1432  };
1433  // -----------------------------------------------------------------------
1434 
1437  public ModbusHeader
1438  {
1439  ModbusByte bcnt = { 0 };
1442  ModbusByte data[MAXLENPACKET - sizeof(ModbusByte)];
1443  ModbusCRC crc = { 0 };
1445  // -----------
1446  RemoteServiceMessage( const ModbusMessage& m );
1447  RemoteServiceMessage& operator=( const ModbusMessage& m );
1448  void init( const ModbusMessage& m );
1449 
1451  size_t szData() const;
1452 
1456  static inline size_t szHead()
1457  {
1458  return sizeof(ModbusByte); // bcnt
1459  }
1460 
1462  static size_t getDataLen( const ModbusMessage& m );
1463 
1464  } __attribute__((packed));
1465 
1466  std::ostream& operator<<(std::ostream& os, RemoteServiceMessage& m );
1467  std::ostream& operator<<(std::ostream& os, RemoteServiceMessage* m );
1468  // -----------------------------------------------------------------------
1470  public ModbusHeader
1471  {
1472  ModbusByte bcnt = { 0 };
1474  ModbusByte data[MAXLENPACKET - sizeof(ModbusByte)];
1475 
1476  RemoteServiceRetMessage( ModbusAddr _from );
1477 
1484  bool setData( ModbusByte* b, int len );
1485 
1487  void clear();
1488 
1490  inline bool isFull() const
1491  {
1492  return ( count >= sizeof(data) );
1493  }
1494 
1496  size_t szData() const;
1497 
1500 
1501  // Это поле не входит в стандарт modbus
1502  // оно вспомогательное и игнорируется при
1503  // преобразовании в ModbusMessage.
1504  size_t count = { 0 };
1505  };
1506  // -----------------------------------------------------------------------
1507 
1509  public ModbusHeader
1510  {
1511  struct SubRequest
1512  {
1513  ModbusByte reftype;
1514  ModbusData numfile;
1515  ModbusData numrec;
1516  ModbusData reglen;
1517  } __attribute__((packed));
1518 
1519  ModbusByte bcnt = { 0 };
1522  SubRequest data[MAXLENPACKET / sizeof(SubRequest) - sizeof(ModbusByte)];
1523  ModbusCRC crc = { 0 };
1525  // -----------
1527  ReadFileRecordMessage& operator=( const ModbusMessage& m );
1528  void init( const ModbusMessage& m );
1529 
1531  size_t szData() const;
1532 
1536  static inline size_t szHead()
1537  {
1538  return sizeof(ModbusByte); // bcnt
1539  }
1540 
1542  static size_t getDataLen( const ModbusMessage& m );
1543 
1545  bool checkFormat() const;
1546 
1547  // это поле служебное и не используется в релальном обмене
1548  size_t count = { 0 };
1549  };
1550 
1551  std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage& m );
1552  std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage* m );
1553  // -----------------------------------------------------------------------
1554 
1556  public ModbusHeader
1557  {
1558  ModbusData numfile = { 0 };
1559  ModbusData numpacket = { 0 };
1560  ModbusCRC crc = { 0 };
1562  // ------- to slave -------
1563  FileTransferMessage( ModbusAddr addr, ModbusData numfile, ModbusData numpacket );
1566  // ------- from master -------
1567  FileTransferMessage( const ModbusMessage& m );
1568  FileTransferMessage& operator=( const ModbusMessage& m );
1569  void init( const ModbusMessage& m );
1570 
1572  static inline size_t szData()
1573  {
1574  return sizeof(ModbusData) * 2 + szCRC;
1575  }
1576 
1577  } __attribute__((packed));
1578 
1579  std::ostream& operator<<(std::ostream& os, FileTransferMessage& m );
1580  std::ostream& operator<<(std::ostream& os, FileTransferMessage* m );
1581  // -----------------------------------------------------------------------
1582 
1584  public ModbusHeader
1585  {
1586  // 255 - max of bcnt...(1 byte)
1587  // static const int MaxDataLen = 255 - szCRC - szModbusHeader - sizeof(ModbusData)*3 - sizeof(ModbusByte)*2;
1588  static const size_t MaxDataLen = MAXLENPACKET - sizeof(ModbusData) * 3 - sizeof(ModbusByte) * 2;
1589 
1590  ModbusByte bcnt;
1591  ModbusData numfile;
1592  ModbusData numpacks;
1593  ModbusData packet;
1594  ModbusByte dlen;
1595  ModbusByte data[MaxDataLen];
1596 
1597 
1598  // ------- from slave -------
1600  FileTransferRetMessage& operator=( const ModbusMessage& m );
1601  void init( const ModbusMessage& m );
1602  ModbusCRC crc = { 0 };
1603  static size_t szHead()
1604  {
1605  return sizeof(ModbusByte);
1606  }
1607  static size_t getDataLen( const ModbusMessage& m );
1608 
1609  // ------- to master -------
1610  FileTransferRetMessage( ModbusAddr _from );
1611 
1615  bool set( ModbusData numfile, ModbusData file_num_packets, ModbusData packet, ModbusByte* b, ModbusByte len );
1616 
1618  void clear();
1619 
1621  size_t szData() const;
1622 
1625  };
1626 
1627  std::ostream& operator<<(std::ostream& os, FileTransferRetMessage& m );
1628  std::ostream& operator<<(std::ostream& os, FileTransferRetMessage* m );
1629  // -----------------------------------------------------------------------
1630  } // end of ModbusRTU namespace
1631  // -------------------------------------------------------------------------
1632 } // end of namespace uniset
1633 // ---------------------------------------------------------------------------
1634 #endif // ModbusTypes_H_
1635 // ---------------------------------------------------------------------------