Directory: | ./ |
---|---|
File: | pdserv/src/msrproto/Server.h |
Date: | 2025-08-17 04:10:43 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 8 | 9 | 88.9% |
Branches: | 12 | 20 | 60.0% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /***************************************************************************** | ||
2 | * | ||
3 | * Copyright 2010 Richard Hacker (lerichi at gmx dot net) | ||
4 | * | ||
5 | * This file is part of the pdserv library. | ||
6 | * | ||
7 | * The pdserv library is free software: you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Lesser General Public License as published | ||
9 | * by the Free Software Foundation, either version 3 of the License, or (at | ||
10 | * your option) any later version. | ||
11 | * | ||
12 | * The pdserv library is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | ||
15 | * License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public License | ||
18 | * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef MSRSERVER_H | ||
23 | #define MSRSERVER_H | ||
24 | |||
25 | #include <atomic> | ||
26 | #include <condition_variable> | ||
27 | #include <set> | ||
28 | #include <list> | ||
29 | #include <mutex> | ||
30 | #include <memory> | ||
31 | #include <string> | ||
32 | #include <log4cplus/logger.h> | ||
33 | |||
34 | #include "../PThread.h" | ||
35 | #include "../SessionStatistics.h" | ||
36 | #include "../Config.h" | ||
37 | #include "../DataType.h" | ||
38 | #include "DirectoryNode.h" | ||
39 | |||
40 | namespace PdServ { | ||
41 | class Main; | ||
42 | class Task; | ||
43 | class Parameter; | ||
44 | class Signal; | ||
45 | class Variable; | ||
46 | } | ||
47 | |||
48 | namespace net { | ||
49 | class TCPServer; | ||
50 | } | ||
51 | |||
52 | namespace MsrProto { | ||
53 | |||
54 | class Session; | ||
55 | class Parameter; | ||
56 | class Channel; | ||
57 | |||
58 | class Server: public pthread::Thread { | ||
59 | public: | ||
60 | enum State | ||
61 | { | ||
62 | Init, | ||
63 | Running, | ||
64 | Stopped, | ||
65 | }; | ||
66 | |||
67 | Server(const PdServ::Main *main, const PdServ::Config &config); | ||
68 | ~Server(); | ||
69 | |||
70 | // return: string <IP><sep><port> of connection | ||
71 | std::string getAddr(char sep = ':') const; | ||
72 | |||
73 | void broadcast(Session *s, const struct timespec& ts, | ||
74 | const std::string& action, const std::string& text); | ||
75 | |||
76 | void setAic(const Parameter*); | ||
77 | void parameterChanged(const PdServ::Parameter*, | ||
78 | size_t startIndex, size_t n, | ||
79 | const char* data, const struct timespec* time); | ||
80 | |||
81 | void sessionClosed(Session *s); | ||
82 | void sessionReady(Session *s); | ||
83 | |||
84 | void getSessionStatistics( | ||
85 | std::list<PdServ::SessionStatistics>& stats) const; | ||
86 | |||
87 | const PdServ::Main * const main; | ||
88 | log4cplus::Logger log; | ||
89 | const log4cplus::Logger broadcastLog; | ||
90 | 10021 | bool active() const { return state_ == Running; } | |
91 | |||
92 | typedef std::vector<const Channel*> Channels; | ||
93 | typedef std::vector<const Parameter*> Parameters; | ||
94 | |||
95 | const Channels& getChannels() const; | ||
96 | const Channel * getChannel(size_t) const; | ||
97 | void listDir(PdServ::Session *, XmlElement& xml, | ||
98 | const std::string& path, bool hex, bool noderived) const; | ||
99 | |||
100 | const Parameters& getParameters() const; | ||
101 | const Parameter * getParameter(size_t) const; | ||
102 | const Parameter * find(const PdServ::Parameter *p) const; | ||
103 | size_t getMaxInputBufferSize() const; | ||
104 | |||
105 | template <typename T> | ||
106 | const T * find(const std::string& path) const; | ||
107 | |||
108 | private: | ||
109 | std::set<Session*> sessions, pending_sessions; | ||
110 | |||
111 | std::string bindaddr; | ||
112 | |||
113 | bool itemize; // Split multidimensional variables to scalars | ||
114 | std::atomic_int state_; | ||
115 | bool m_broadcast; | ||
116 | |||
117 | DirectoryNode variableDirectory; | ||
118 | DirectoryNode* insertRoot; | ||
119 | |||
120 | size_t maxConnections; | ||
121 | size_t maxInputBufferSize; | ||
122 | |||
123 | Channels channels; | ||
124 | Parameters parameters; | ||
125 | |||
126 | typedef std::map<const PdServ::Parameter *, const Parameter*> | ||
127 | ParameterMap; | ||
128 | ParameterMap parameterMap; | ||
129 | |||
130 | mutable std::mutex mutex; | ||
131 | std::condition_variable startup_cv; | ||
132 | |||
133 | std::unique_ptr<net::TCPServer> server; | ||
134 | #ifdef GNUTLS_FOUND | ||
135 | std::unique_ptr<net::TCPServer> secure_server; | ||
136 | std::string tlsbindaddr; | ||
137 | #endif | ||
138 | |||
139 | // Reimplemented from pthread::Thread | ||
140 | void initial(); | ||
141 | void run(); | ||
142 | void final(); | ||
143 | |||
144 | int listenTo(const std::string& interface, const std::string& port, | ||
145 | net::TCPServer &server); | ||
146 | |||
147 | void createChannels(DirectoryNode* baseDir, | ||
148 | const PdServ::Task* task); | ||
149 | void createParameters(DirectoryNode* baseDir); | ||
150 | |||
151 | struct CreateVariable { | ||
152 | CreateVariable(Server* server, DirectoryNode* baseDir, | ||
153 | const PdServ::Variable* var); | ||
154 | CreateVariable(const CreateVariable& other); | ||
155 | 6160 | virtual ~CreateVariable() {} | |
156 | |||
157 | void newDimension( | ||
158 | const PdServ::DataType& dtype, | ||
159 | const PdServ::DataType::DimType& dim, | ||
160 | size_t dimIdx, size_t elemIdx, | ||
161 | CreateVariable& c, size_t offset); | ||
162 | void newField(const PdServ::DataType::Field *field, | ||
163 | CreateVariable& c, size_t offset); | ||
164 | bool newVariable( | ||
165 | const PdServ::DataType& dtype, | ||
166 | const PdServ::DataType::DimType& dim, | ||
167 | size_t dimIdx, size_t elemIdx, size_t offset) const; | ||
168 | virtual bool createVariable( | ||
169 | const PdServ::DataType& dtype, | ||
170 | const PdServ::DataType::DimType& dim, | ||
171 | size_t offset) const = 0; | ||
172 | |||
173 | std::string path() const; | ||
174 | |||
175 | std::string name; | ||
176 | |||
177 | const CreateVariable* const parent; | ||
178 | Server* const server; | ||
179 | DirectoryNode* const baseDir; | ||
180 | const PdServ::Variable* const var; | ||
181 | }; | ||
182 | |||
183 | 4004 | struct CreateChannel: CreateVariable { | |
184 | CreateChannel(Server* server, DirectoryNode* baseDir, | ||
185 | const PdServ::Signal* s); | ||
186 | |||
187 | bool createVariable( | ||
188 | const PdServ::DataType& dtype, | ||
189 | const PdServ::DataType::DimType& dim, | ||
190 | size_t offset) const; | ||
191 | }; | ||
192 | |||
193 | 6468 | struct CreateParameter: CreateVariable { | |
194 | CreateParameter(Server* server, DirectoryNode* baseDir, | ||
195 | const PdServ::Parameter* p); | ||
196 | |||
197 | bool createVariable( | ||
198 | const PdServ::DataType& dtype, | ||
199 | const PdServ::DataType::DimType& dim, | ||
200 | size_t offset) const; | ||
201 | |||
202 | mutable Parameter* parentParameter; | ||
203 | }; | ||
204 | }; | ||
205 | |||
206 | ///////////////////////////////////////////////////////////////////////////// | ||
207 | template <typename T> | ||
208 | 182 | const T *Server::find(const std::string &p) const | |
209 | { | ||
210 |
6/12✓ Branch 2 taken 91 times.
✗ Branch 3 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 91 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 91 times.
✓ Branch 13 taken 91 times.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 91 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 91 times.
|
182 | if (p.empty() or p[0] != '/') |
211 | ✗ | return 0; | |
212 | |||
213 | 182 | const DirectoryNode *node = variableDirectory.find(p, 1); | |
214 |
6/8✓ Branch 0 taken 83 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 83 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 83 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 83 times.
✗ Branch 7 not taken.
|
182 | return node ? dynamic_cast<const T*>(node) : 0; |
215 | } | ||
216 | |||
217 | } | ||
218 | #endif //MSRSERVER_H | ||
219 |