UniSet 2.32.1
UNetSender.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 UNetSender_H_
18#define UNetSender_H_
19// -----------------------------------------------------------------------------
20#include <ostream>
21#include <string>
22#include <vector>
23#include <limits>
24#include <unordered_map>
25#include "UniSetObject.h"
26#include "Trigger.h"
27#include "Mutex.h"
28#include "SMInterface.h"
29#include "SharedMemory.h"
30#include "ThreadCreator.h"
31#include "UDPPacket.h"
32#include "UNetTransport.h"
33// --------------------------------------------------------------------------
34namespace uniset
35{
36 // -----------------------------------------------------------------------------
37 /*
38 * Распределение датчиков по пакетам
39 * =========================================================================
40 * Все пересылаемые данные разбиваются на группы по частоте посылки("sendfactor").
41 * Частота посылки кратна sendpause, задаётся для каждого датчика, при помощи свойства prefix_sendfactor.
42 * Внутри каждой группы пакеты набираются по мере "заполнения".
43 *
44 * Добавление датчика в пакет и создание нового пакета при переполнении происходит в функции initItem().
45 * Причем так как дискретные и аналоговые датчики обрабатываются отдельно (но пересылаются в одном пакете),
46 * то датчики, которые первые переполнятся приводят к тому, что создаётся новый пакет и они добавляются в него,
47 * в свою очередь остальные продолжают "добивать" предыдущий пакет.
48 * В initItem() каждому UItem в dlist кроме pack_ind присваивается еще и номер пакета pack_num, который гарантировано соответствует
49 * существующему пакету, поэтому в дальнейшем при использовании pack_num в качестве ключа в mypacks мы не проверяем пакет на существование.
50 *
51 * Создание соединения
52 * ======================================
53 * Попытка создать соединение производиться сразу в конструкторе, если это не получается,
54 * то в потоке "посылки", с заданным периодом (checkConnectionTime) идёт попытка создать соединение..
55 * и так бесконечно, пока не получиться. Это важно для систем, где в момент загрузки программы
56 * (в момент создания объекта UNetSender) ещё может быть не поднята сеть или какой-то сбой с сетью и требуется
57 * ожидание (без вылета программы) пока "внешняя система мониторинга" не поднимет сеть).
58 * Если такая логика не требуется, то можно задать в конструкторе флаг nocheckconnection=true,
59 * тогда при создании объекта UNetSender, в конструкторе будет
60 * выкинуто исключение при неудачной попытке создания соединения.
61 * \warning setCheckConnectionPause(msec) должно быть кратно sendpause!
62 */
63 class UNetSender final
64 {
65 public:
66 UNetSender( std::unique_ptr<UNetSendTransport>&& transport, const std::shared_ptr<SMInterface>& smi
67 , bool nocheckConnection = false
68 , const std::string& s_field = ""
69 , const std::string& s_fvalue = ""
70 , const std::string& prop_prefix = "unet"
71 , const std::string& prefix = "unet"
72 , size_t maxDCount = UniSetUDP::MaxDCount
73 , size_t maxACount = UniSetUDP::MaxACount );
74
76
77 typedef size_t sendfactor_t;
78
79 static const long not_specified_value = { std::numeric_limits<long>::max() };
80
81 enum class Mode : int
82 {
83 mEnabled = 0,
84 mDisabled = 1
85 };
86
87 struct UItem
88 {
89 UItem():
90 iotype(UniversalIO::UnknownIOType),
92 pack_num(0),
93 pack_ind(0),
94 pack_sendfactor(0) {}
95
96 UniversalIO::IOType iotype;
98 IOController::IOStateList::iterator ioit;
99 size_t pack_num;
100 size_t pack_ind;
101 sendfactor_t pack_sendfactor = { 0 };
102 long undefined_value = { not_specified_value };
103 friend std::ostream& operator<<( std::ostream& os, UItem& p );
104 };
105
106 typedef std::unordered_map<uniset::ObjectId, UItem> UItemMap;
107
108 size_t getDataPackCount() const noexcept;
109
110 void start();
111 void stop();
112
113 void send() noexcept;
114
116 {
117 PackMessage( uniset::UniSetUDP::UDPMessage&& m ) noexcept: msg(std::move(m)) {}
118 PackMessage( const uniset::UniSetUDP::UDPMessage& m ) = delete;
119
120 PackMessage() noexcept {}
121
124 };
125
126 void real_send( PackMessage& mypack ) noexcept;
127
129 void updateFromSM();
130
132 void updateSensor( uniset::ObjectId id, long value );
133
135 void updateItem( const UItem& it, long value );
136
137 inline void setSendPause( int msec ) noexcept
138 {
139 sendpause = msec;
140 }
141 inline void setPackSendPause( int msec ) noexcept
142 {
143 packsendpause = msec;
144 }
145 inline void setPackSendPauseFactor( int factor ) noexcept
146 {
147 packsendpauseFactor = factor;
148 }
149
150 void setModeID( uniset::ObjectId id ) noexcept;
151
152 void setCheckConnectionPause( int msec ) noexcept;
153
155 void askSensors( UniversalIO::UIOCommand cmd );
156
158 void initIterators() noexcept;
159
160 inline std::shared_ptr<DebugStream> getLog() noexcept
161 {
162 return unetlog;
163 }
164
165 std::string getShortInfo() const noexcept;
166
167 inline size_t getADataSize() const noexcept
168 {
169 return maxAData;
170 }
171 inline size_t getDDataSize() const noexcept
172 {
173 return maxDData;
174 }
175
176 protected:
177
178 std::string s_field = { "" };
179 std::string s_fvalue = { "" };
180 std::string prop_prefix = { "" };
181
182 const std::shared_ptr<SMInterface> shm;
183 std::shared_ptr<DebugStream> unetlog;
184
185 bool initItem( UniXML::iterator& it );
186 bool readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec );
187
188 void readConfiguration();
189
190 bool createConnection( bool throwEx );
191
192 private:
193 UNetSender();
194
195 std::unique_ptr<UNetSendTransport> transport;
196
197 std::string myname = { "" };
198 timeout_t sendpause = { 150 };
199 timeout_t packsendpause = { 5 };
200 int packsendpauseFactor = { 1 };
201 timeout_t writeTimeout = { 1000 }; // msec
202 std::atomic_bool activated = { false };
203 PassiveTimer ptCheckConnection;
204
205 // режим работы
207 IOController::IOStateList::iterator itMode;
208 Mode mode = { Mode::mEnabled };
209
210 typedef std::unordered_map<sendfactor_t, std::vector<PackMessage>> Packs;
211
212 // mypacks заполняется в начале и дальше с ним происходит только чтение
213 // (меняются данные внутри пакетов, но не меняется само количество пакетов)
214 // поэтому mutex-ом его не защищаем
215 Packs mypacks;
216 std::unordered_map<sendfactor_t, size_t> packs_anum;
217 std::unordered_map<sendfactor_t, size_t> packs_dnum;
218 UItemMap items;
219 size_t packetnum = { 1 };
221 size_t maxAData = { UniSetUDP::MaxACount };
222 size_t maxDData = { UniSetUDP::MaxDCount };
223
224 std::unique_ptr< ThreadCreator<UNetSender> > s_thr; // send thread
225
226 size_t ncycle = { 0 };
228 };
229 // --------------------------------------------------------------------------
230} // end of namespace uniset
231// -----------------------------------------------------------------------------
232namespace std
233{
234 std::string to_string( const uniset::UNetSender::Mode& p );
235}
236// -----------------------------------------------------------------------------
237#endif // UNetSender_H_
238// -----------------------------------------------------------------------------
Definition DebugStream.h:62
Definition UNetSender.h:64
void initIterators() noexcept
Definition UNetSender.cc:553
void updateSensor(uniset::ObjectId id, long value)
Definition UNetSender.cc:170
void updateFromSM()
Definition UNetSender.cc:133
Mode
Definition UNetSender.h:82
void updateItem(const UItem &it, long value)
Definition UNetSender.cc:184
void askSensors(UniversalIO::UIOCommand cmd)
Definition UNetSender.cc:561
Definition Mutex.h:32
STL namespace.
Definition Calibration.h:27
const ObjectId DefaultObjectId
Definition UniSetTypes.h:71
long ObjectId
Definition UniSetTypes_i.idl:30
Definition UNetSender.h:116
Definition UNetSender.h:88
Definition UDPPacket.h:88