UniSet  2.24.2
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  {
46  const uint32_t UNETUDP_MAGICNUM = 0x1348A5F; // идентификатор протокола
47 
48  struct UDPHeader
49  {
50  UDPHeader() noexcept;
51  uint32_t magic;
52  uint8_t _be_order; // 1 - BE byte order, 0 - LE byte order
53  size_t num; // порядковый номер сообщения
54  int64_t nodeID;
55  int64_t procID;
56  size_t dcount;
57  size_t acount;
58  uint16_t dcrc;
59  uint16_t acrc;
60  } __attribute__((packed));
61 
62  std::ostream& operator<<( std::ostream& os, UDPHeader& p );
63  std::ostream& operator<<( std::ostream& os, UDPHeader* p );
64 
65  const size_t MaxPacketNum = std::numeric_limits<size_t>::max();
66 
67  struct UDPAData
68  {
69  UDPAData() noexcept: id(uniset::DefaultObjectId), val(0) {}
70  UDPAData(int32_t id, int64_t val) noexcept: id(id), val(val) {}
71 
72  int32_t id;
73  int64_t val;
74 
75  } __attribute__((packed));
76 
77  std::ostream& operator<<( std::ostream& os, UDPAData& p );
78 
79  // Теоретический размер данных в UDP пакете (исключая заголовки) 65507
80  // Фактически желательно не вылезать за размер MTU (обычно 1500) - заголовки = 1432 байта
81  // т.е. надо чтобы sizeof(UDPPacket) < 1432
82  //
83  static const size_t MaxACount = 2000;
84  static const size_t MaxDCount = 4000;
85  static const size_t MaxDDataCount = 1 + MaxDCount / (8 * sizeof(uint8_t));
86 
87  struct UDPMessage
88  {
89  // net to host
90  void ntoh() noexcept;
91  bool isOk() noexcept;
92 
93  // \warning в случае переполнения возвращается MaxDCount
94  size_t addDData( int32_t id, bool val ) noexcept;
95 
97  bool setDData( size_t index, bool val ) noexcept;
98 
100  long dID( size_t index ) const noexcept;
101 
103  bool dValue( size_t index ) const noexcept;
104 
105  // функции addAData возвращают индекс, по которому потом можно напрямую писать при помощи setAData(index)
106  // \warning в случае переполнения возвращается MaxACount
107  size_t addAData( const UDPAData& dat ) noexcept;
108  size_t addAData( int32_t id, int64_t val ) noexcept;
109 
111  bool setAData( size_t index, int64_t val ) noexcept;
112 
113  long getDataID( ) const noexcept;
115  inline bool isAFull() const noexcept
116  {
117  return (header.acount >= MaxACount);
118  }
119  inline bool isDFull() const noexcept
120  {
121  return (header.dcount >= MaxDCount);
122  }
123 
124  inline bool isFull() const noexcept
125  {
126  return !((header.dcount < MaxDCount) && (header.acount < MaxACount));
127  }
128 
129  inline size_t dsize() const noexcept
130  {
131  return header.dcount;
132  }
133 
134  inline size_t asize() const noexcept
135  {
136  return header.acount;
137  }
138 
139  uint16_t calcDcrc() const noexcept;
140  uint16_t calcAcrc() const noexcept;
141  void updatePacketCrc() noexcept;
142 
143  UDPHeader header;
144  UDPAData a_dat[MaxACount];
145  int32_t d_id[MaxDCount];
146  uint8_t d_dat[MaxDDataCount];
147  } __attribute__((packed));
148 
149  std::ostream& operator<<( std::ostream& os, UDPMessage& p );
150 
151  uint16_t makeCRC( unsigned char* buf, size_t len ) noexcept;
152  }
153  // --------------------------------------------------------------------------
154 } // end of namespace uniset
155 // -----------------------------------------------------------------------------
156 #endif // UDPPacket_H_
157 // -----------------------------------------------------------------------------
Definition: CommonEventLoop.h:15
const ObjectId DefaultObjectId
Definition: UniSetTypes.h:70
Definition: UDPPacket.h:68
Definition: UDPPacket.h:49
size_t acount
Definition: UDPPacket.h:57
size_t dcount
Definition: UDPPacket.h:56
uint16_t acrc
Definition: UDPPacket.h:59
uint16_t dcrc
Definition: UDPPacket.h:58
Definition: UDPPacket.h:88
long dID(size_t index) const noexcept
Definition: UDPPacket.cc:246
int32_t d_id[MaxDCount]
Definition: UDPPacket.h:145
uint8_t d_dat[MaxDDataCount]
Definition: UDPPacket.h:146
long getDataID() const noexcept
Definition: UDPPacket.cc:265
bool setDData(size_t index, bool val) noexcept
Definition: UDPPacket.cc:226
UDPAData a_dat[MaxACount]
Definition: UDPPacket.h:144
bool setAData(size_t index, int64_t val) noexcept
Definition: UDPPacket.cc:196
bool dValue(size_t index) const noexcept
Definition: UDPPacket.cc:254