Directory: | ./ |
---|---|
File: | pdserv/src/msrproto/Server.h |
Date: | 2023-11-12 04:06:57 |
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 | 6755 | bool active() const { return state_ == Running; } | |
92 | |||
93 | typedef std::vector<const Channel*> Channels; | ||
94 | typedef std::vector<const Parameter*> Parameters; | ||
95 | |||
96 | const Channels& getChannels() const; | ||
97 | const Channel * getChannel(size_t) const; | ||
98 | void listDir(PdServ::Session *, XmlElement& xml, | ||
99 | const std::string& path, bool hex, bool noderived) const; | ||
100 | |||
101 | const Parameters& getParameters() const; | ||
102 | const Parameter * getParameter(size_t) const; | ||
103 | const Parameter * find(const PdServ::Parameter *p) const; | ||
104 | size_t getMaxInputBufferSize() const; | ||
105 | |||
106 | template <typename T> | ||
107 | const T * find(const std::string& path) const; | ||
108 | |||
109 | private: | ||
110 | std::set<Session*> sessions, pending_sessions; | ||
111 | |||
112 | std::string bindaddr; | ||
113 | |||
114 | bool itemize; // Split multidimensional variables to scalars | ||
115 | std::atomic_int state_; | ||
116 | bool m_broadcast; | ||
117 | |||
118 | DirectoryNode variableDirectory; | ||
119 | DirectoryNode* insertRoot; | ||
120 | |||
121 | size_t maxConnections; | ||
122 | size_t maxInputBufferSize; | ||
123 | |||
124 | Channels channels; | ||
125 | Parameters parameters; | ||
126 | |||
127 | typedef std::map<const PdServ::Parameter *, const Parameter*> | ||
128 | ParameterMap; | ||
129 | ParameterMap parameterMap; | ||
130 | |||
131 | mutable std::mutex mutex; | ||
132 | std::condition_variable startup_cv; | ||
133 | |||
134 | std::unique_ptr<net::TCPServer> server; | ||
135 | #ifdef GNUTLS_FOUND | ||
136 | std::unique_ptr<net::TCPServer> secure_server; | ||
137 | std::string tlsbindaddr; | ||
138 | #endif | ||
139 | |||
140 | // Reimplemented from pthread::Thread | ||
141 | void initial(); | ||
142 | void run(); | ||
143 | void final(); | ||
144 | |||
145 | int listenTo(const std::string& interface, const std::string& port, 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 | 4680 | 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 | 2600 | 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 | 5460 | 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 | 118 | const T *Server::find(const std::string &p) const | |
209 | { | ||
210 |
6/12✓ Branch 2 taken 59 times.
✗ Branch 3 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 59 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 59 times.
✓ Branch 13 taken 59 times.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 59 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 59 times.
|
118 | if (p.empty() or p[0] != '/') |
211 | ✗ | return 0; | |
212 | |||
213 | 118 | const DirectoryNode *node = variableDirectory.find(p, 1); | |
214 |
6/8✓ Branch 0 taken 51 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 51 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 51 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 51 times.
✗ Branch 7 not taken.
|
118 | return node ? dynamic_cast<const T*>(node) : 0; |
215 | } | ||
216 | |||
217 | } | ||
218 | #endif //MSRSERVER_H | ||
219 |