| Directory: | ./ |
|---|---|
| File: | pdserv/src/msrproto/Server.h |
| Date: | 2025-11-02 04:09:49 |
| 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 | 10104 | 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 |