UniSet  2.6.0
UDPPacket.h
1 /*
2  * Copyright (c) 2015 Pavel Vainerman.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as
6  * published by the Free Software Foundation, version 2.1.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Lesser Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 // -----------------------------------------------------------------------------
17 #ifndef UDPPacket_H_
18 #define UDPPacket_H_
19 // -----------------------------------------------------------------------------
20 #include <list>
21 #include <limits>
22 #include <ostream>
23 #include "UniSetTypes.h"
24 // --------------------------------------------------------------------------
25 namespace uniset
26 {
27  // -----------------------------------------------------------------------------
28  namespace UniSetUDP
29  {
43  const uint32_t UNETUDP_MAGICNUM = 0x1337A1D; // идентификатор протокола
44 
45  struct UDPHeader
46  {
47  UDPHeader() noexcept: magic(UNETUDP_MAGICNUM), num(0), nodeID(0), procID(0), dcount(0), acount(0) {}
48  uint32_t magic;
49  size_t num;
50  long nodeID;
51  long procID;
52 
53  size_t dcount;
54  size_t acount;
56  friend std::ostream& operator<<( std::ostream& os, UDPHeader& p );
57  friend std::ostream& operator<<( std::ostream& os, UDPHeader* p );
58  } __attribute__((packed));
59 
60  const size_t MaxPacketNum = std::numeric_limits<size_t>::max();
61 
62  struct UDPAData
63  {
64  UDPAData() noexcept: id(uniset::DefaultObjectId), val(0) {}
65  UDPAData(long id, long val) noexcept: id(id), val(val) {}
66 
67  long id;
68  long val;
69 
70  friend std::ostream& operator<<( std::ostream& os, UDPAData& p );
71  } __attribute__((packed));
72 
73 
74  // Теоретический размер данных в UDP пакете (исключая заголовки) 65507
75  // Фактически желательно не вылезать за размер MTU (обычно 1500) - заголовки = 1432 байта
76  // т.е. надо чтобы sizeof(UDPPacket) < 1432
77 
78  // При текущих настройках sizeof(UDPPacket) = 32654 (!)
79  static const size_t MaxACount = 1500;
80  static const size_t MaxDCount = 5000;
81  static const size_t MaxDDataCount = 1 + MaxDCount / 8 * sizeof(unsigned char);
82 
83  struct UDPPacket
84  {
85  UDPPacket() noexcept: len(0) {}
86 
87  size_t len;
88  uint8_t data[ sizeof(UDPHeader) + MaxDCount * sizeof(long) + MaxDDataCount + MaxACount * sizeof(UDPAData) ];
89  } __attribute__((packed));
90 
91  static const size_t MaxDataLen = sizeof(UDPPacket);
92 
93  struct UDPMessage:
94  public UDPHeader
95  {
96  UDPMessage() noexcept;
97 
98  UDPMessage(UDPMessage&& m) noexcept = default;
99  UDPMessage& operator=(UDPMessage&&) noexcept = default;
100 
101  UDPMessage( const UDPMessage& m ) noexcept = default;
102  UDPMessage& operator=(const UDPMessage&) noexcept = default;
103 
104  explicit UDPMessage( UDPPacket& p ) noexcept;
105  size_t transport_msg( UDPPacket& p ) const noexcept;
106 
107  static size_t getMessage( UDPMessage& m, UDPPacket& p ) noexcept;
108 
109  // \warning в случае переполнения возвращается MaxDCount
110  size_t addDData( long id, bool val ) noexcept;
111 
113  bool setDData( size_t index, bool val ) noexcept;
114 
116  long dID( size_t index ) const noexcept;
117 
119  bool dValue( size_t index ) const noexcept;
120 
121  // функции addAData возвращают индекс, по которому потом можно напрямую писать при помощи setAData(index)
122  // \warning в случае переполнения возвращается MaxACount
123  size_t addAData( const UDPAData& dat ) noexcept;
124  size_t addAData( long id, long val ) noexcept;
125 
127  bool setAData( size_t index, long val ) noexcept;
128 
129  long getDataID( ) const noexcept;
131  inline bool isAFull() const noexcept
132  {
133  return (acount >= MaxACount);
134  }
135  inline bool isDFull() const noexcept
136  {
137  return (dcount >= MaxDCount);
138  }
139 
140  inline bool isFull() const noexcept
141  {
142  return !((dcount < MaxDCount) && (acount < MaxACount));
143  }
144 
145  inline size_t dsize() const noexcept
146  {
147  return dcount;
148  }
149 
150  inline size_t asize() const noexcept
151  {
152  return acount;
153  }
154 
155  // размер итогового пакета в байтах
156  size_t sizeOf() const noexcept;
157 
158  uint16_t getDataCRC() const noexcept;
159 
160  // количество байт в пакете с булевыми переменными...
161  size_t d_byte() const noexcept
162  {
163  return dcount * sizeof(long) + dcount;
164  }
165 
166  UDPAData a_dat[MaxACount];
167  long d_id[MaxDCount];
168  uint8_t d_dat[MaxDDataCount];
170  friend std::ostream& operator<<( std::ostream& os, UDPMessage& p );
171  };
172 
173  uint16_t makeCRC( unsigned char* buf, size_t len ) noexcept;
174  }
175  // --------------------------------------------------------------------------
176 } // end of namespace uniset
177 // -----------------------------------------------------------------------------
178 #endif // UDPPacket_H_
179 // -----------------------------------------------------------------------------
Definition: CallbackTimer.h:29
UDPAData a_dat[MaxACount]
Definition: UDPPacket.h:166
bool setAData(size_t index, long val) noexcept
Definition: UDPPacket.cc:159
bool setDData(size_t index, bool val) noexcept
Definition: UDPPacket.cc:189
Definition: UDPPacket.h:62
uint8_t d_dat[MaxDDataCount]
Definition: UDPPacket.h:168
const ObjectId DefaultObjectId
Definition: UniSetTypes.h:56
long dID(size_t index) const noexcept
Definition: UDPPacket.cc:209
Definition: UDPPacket.h:93
Definition: UDPPacket.h:83
long d_id[MaxDCount]
Definition: UDPPacket.h:167
size_t dcount
Definition: UDPPacket.h:53
long getDataID() const noexcept
Definition: UDPPacket.cc:257
size_t acount
Definition: UDPPacket.h:54
Definition: UDPPacket.h:45
bool dValue(size_t index) const noexcept
Definition: UDPPacket.cc:217