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