1 /***
2     This file is part of snapcast
3     Copyright (C) 2014-2020  Johannes Pohl
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 ***/
18 
19 #ifndef CONTROL_SERVER_H
20 #define CONTROL_SERVER_H
21 
22 #include <boost/asio.hpp>
23 #include <memory>
24 #include <mutex>
25 #include <set>
26 #include <vector>
27 
28 #include "common/queue.h"
29 #include "common/sample_format.hpp"
30 #include "control_session.hpp"
31 #include "message/codec_header.hpp"
32 #include "message/message.hpp"
33 #include "message/server_settings.hpp"
34 #include "server_settings.hpp"
35 
36 using boost::asio::ip::tcp;
37 using acceptor_ptr = std::unique_ptr<tcp::acceptor>;
38 
39 /// Telnet like remote control
40 /**
41  * Telnet like remote control
42  */
43 class ControlServer : public ControlMessageReceiver
44 {
45 public:
46     ControlServer(boost::asio::io_context& io_context, const ServerSettings::Tcp& tcp_settings, const ServerSettings::Http& http_settings,
47                   ControlMessageReceiver* controlMessageReceiver = nullptr);
48     virtual ~ControlServer();
49 
50     void start();
51     void stop();
52 
53     /// Send a message to all connected clients
54     void send(const std::string& message, const ControlSession* excludeSession = nullptr);
55 
56 private:
57     void startAccept();
58 
59     template <typename SessionType, typename... Args>
60     void handleAccept(tcp::socket socket, Args&&... args);
61     void cleanup();
62 
63     /// Implementation of ControlMessageReceiver
64     std::string onMessageReceived(ControlSession* session, const std::string& message) override;
65     void onNewSession(const std::shared_ptr<ControlSession>& session) override;
66     void onNewSession(const std::shared_ptr<StreamSession>& session) override;
67 
68     mutable std::recursive_mutex session_mutex_;
69     std::vector<std::weak_ptr<ControlSession>> sessions_;
70 
71     std::vector<acceptor_ptr> acceptor_tcp_;
72     std::vector<acceptor_ptr> acceptor_http_;
73 
74     boost::asio::io_context& io_context_;
75     ServerSettings::Tcp tcp_settings_;
76     ServerSettings::Http http_settings_;
77     ControlMessageReceiver* controlMessageReceiver_;
78 };
79 
80 
81 
82 #endif
83