diff --git a/server/controlServer.cpp b/server/controlServer.cpp index 091f9f4e..dfcca392 100644 --- a/server/controlServer.cpp +++ b/server/controlServer.cpp @@ -34,7 +34,7 @@ using namespace std; using json = nlohmann::json; -ControlServer::ControlServer(size_t port) : port_(port) +ControlServer::ControlServer(size_t port, ControlMessageReceiver* controlMessageReceiver) : port_(port), controlMessageReceiver_(controlMessageReceiver) { } @@ -84,82 +84,8 @@ void ControlServer::onMessageReceived(ControlSession* connection, const std::str } else { - try - { - JsonRequest request; - request.parse(message); - - //{"jsonrpc": "2.0", "method": "System.GetStatus", "id": 2} - //{"jsonrpc": "2.0", "method": "System.GetStatus", "params": {"client": "00:21:6a:7d:74:fc"}, "id": 2} - - //{"jsonrpc": "2.0", "method": "Client.SetVolume", "params": {"client": "00:21:6a:7d:74:fc", "volume": 83}, "id": 2} - //{"jsonrpc": "2.0", "method": "Client.SetLatency", "params": {"client": "00:21:6a:7d:74:fc", "latency": 10}, "id": 2} - //{"jsonrpc": "2.0", "method": "Client.SetName", "params": {"client": "00:21:6a:7d:74:fc", "name": "living room"}, "id": 2} - //{"jsonrpc": "2.0", "method": "Client.SetMute", "params": {"client": "00:21:6a:7d:74:fc", "mute": false}, "id": 2} - -//curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "Application.SetVolume", "params": {"volume":100}, "id": 1}' http://i3c.pla.lcl:8080/jsonrpc -//https://github.com/pla1/utils/blob/master/kodi_remote.desktop -//http://forum.fhem.de/index.php?topic=10075.130;wap2 -//http://kodi.wiki/view/JSON-RPC_API/v6#Application.SetVolume - - - logO << "method: " << request.method << ", " << "id: " << request.id << "\n"; - - json response; - - if (request.method == "System.GetStatus") - { - json jClient = json::array(); - if (request.hasParam("client")) - { - ClientInfoPtr client = Config::instance().getClientInfo(request.getParam("client").get(), false); - if (client) - jClient += client->toJson(); - } - else - jClient = Config::instance().getClientInfos(); - - response = { - {"server", { - {"host", getHostName()}, - {"version", VERSION} - }}, - {"clients", jClient} - }; - } - else if (request.method == "Client.SetVolume") - { - int volume = request.getParam("volume").get(); - logO << "client: " << request.getParam("client").get() << ", volume: " << volume << "\n"; - response = volume; - } - else if (request.method == "Client.SetLatency") - { - int latency = request.getParam("latency").get(); - logO << "client: " << request.getParam("client").get() << ", latency: " << latency << "\n"; - response = latency; - } - else if (request.method == "Client.SetName") - { - string name = request.getParam("name").get(); - logO << "client: " << request.getParam("client").get() << ", name: " << name << "\n"; - response = name; - } - else if (request.method == "Client.SetMute") - { - bool mute = request.getParam("mute").get(); - logO << "client: " << request.getParam("client").get() << ", mute: " << mute << "\n"; - response = mute; - } - else - throw JsonMethodNotFoundException(request); - - connection->send(request.getResponse(response).dump()); - } - catch (const JsonRequestException& e) - { - connection->send(e.getResponse().dump()); - } + if (controlMessageReceiver_ != NULL) + controlMessageReceiver_->onMessageReceived(connection, message); } } diff --git a/server/controlServer.h b/server/controlServer.h index 47ed0053..9d8b5fc3 100644 --- a/server/controlServer.h +++ b/server/controlServer.h @@ -47,7 +47,7 @@ typedef std::shared_ptr socket_ptr; class ControlServer : public ControlMessageReceiver { public: - ControlServer(size_t port); + ControlServer(size_t port, ControlMessageReceiver* controlMessageReceiver = NULL); virtual ~ControlServer(); void start(); @@ -71,6 +71,8 @@ private: std::thread acceptThread_; Queue> messages_; + + ControlMessageReceiver* controlMessageReceiver_; }; diff --git a/server/streamServer.cpp b/server/streamServer.cpp index 827eb2bb..9e620051 100644 --- a/server/streamServer.cpp +++ b/server/streamServer.cpp @@ -91,6 +91,91 @@ void StreamServer::onDisconnect(ServerSession* connection) } +void StreamServer::onMessageReceived(ControlSession* connection, const std::string& message) +{ + try + { + JsonRequest request; + request.parse(message); + + //{"jsonrpc": "2.0", "method": "System.GetStatus", "id": 2} + //{"jsonrpc": "2.0", "method": "System.GetStatus", "params": {"client": "00:21:6a:7d:74:fc"}, "id": 2} + + //{"jsonrpc": "2.0", "method": "Client.SetVolume", "params": {"client": "00:21:6a:7d:74:fc", "volume": 83}, "id": 2} + //{"jsonrpc": "2.0", "method": "Client.SetLatency", "params": {"client": "00:21:6a:7d:74:fc", "latency": 10}, "id": 2} + //{"jsonrpc": "2.0", "method": "Client.SetName", "params": {"client": "00:21:6a:7d:74:fc", "name": "living room"}, "id": 2} + //{"jsonrpc": "2.0", "method": "Client.SetMute", "params": {"client": "00:21:6a:7d:74:fc", "mute": false}, "id": 2} + +//curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "Application.SetVolume", "params": {"volume":100}, "id": 1}' http://i3c.pla.lcl:8080/jsonrpc +//https://en.wikipedia.org/wiki/JSON-RPC +//https://github.com/pla1/utils/blob/master/kodi_remote.desktop +//http://forum.fhem.de/index.php?topic=10075.130;wap2 +//http://kodi.wiki/view/JSON-RPC_API/v6#Application.SetVolume + + + logO << "method: " << request.method << ", " << "id: " << request.id << "\n"; + + json response; + + if (request.method == "System.GetStatus") + { + json jClient = json::array(); + if (request.hasParam("client")) + { + ClientInfoPtr client = Config::instance().getClientInfo(request.getParam("client").get(), false); + if (client) + jClient += client->toJson(); + } + else + jClient = Config::instance().getClientInfos(); + + response = { + {"server", { + {"host", getHostName()}, + {"version", VERSION} + }}, + {"clients", jClient} + }; + } + else if (request.method == "Client.SetVolume") + { + int volume = request.getParam("volume").get(); + logO << "client: " << request.getParam("client").get() << ", volume: " << volume << "\n"; + ServerSession* session = getClientSession(request.getParam("client").get()); +// if (session != NULL) + + response = volume; + } + else if (request.method == "Client.SetLatency") + { + int latency = request.getParam("latency").get(); + logO << "client: " << request.getParam("client").get() << ", latency: " << latency << "\n"; + response = latency; + } + else if (request.method == "Client.SetName") + { + string name = request.getParam("name").get(); + logO << "client: " << request.getParam("client").get() << ", name: " << name << "\n"; + response = name; + } + else if (request.method == "Client.SetMute") + { + bool mute = request.getParam("mute").get(); + logO << "client: " << request.getParam("client").get() << ", mute: " << mute << "\n"; + response = mute; + } + else + throw JsonMethodNotFoundException(request); + + connection->send(request.getResponse(response).dump()); + } + catch (const JsonRequestException& e) + { + connection->send(e.getResponse().dump()); + } +} + + void StreamServer::onMessageReceived(ServerSession* connection, const msg::BaseMessage& baseMessage, char* buffer) { // logO << "getNextMessage: " << baseMessage.type << ", size: " << baseMessage.size << ", id: " << baseMessage.id << ", refers: " << baseMessage.refersTo << ", sent: " << baseMessage.sent.sec << "," << baseMessage.sent.usec << ", recv: " << baseMessage.received.sec << "," << baseMessage.received.usec << "\n"; @@ -160,6 +245,16 @@ void StreamServer::onMessageReceived(ServerSession* connection, const msg::BaseM } +ServerSession* StreamServer::getClientSession(const std::string& mac) +{ + for (auto session: sessions_) + { + if (session->macAddress == mac) + return session.get(); + } + return NULL; +} + void StreamServer::startAccept() { @@ -189,7 +284,7 @@ void StreamServer::handleAccept(socket_ptr socket) void StreamServer::start() { - controlServer.reset(new ControlServer(settings_.port + 1)); + controlServer.reset(new ControlServer(settings_.port + 1, this)); controlServer->start(); pipeReader_ = new PipeReader(this, settings_.sampleFormat, settings_.codec, settings_.fifoName, settings_.pipeReadMs); diff --git a/server/streamServer.h b/server/streamServer.h index 4e3b0eb5..4c86c51d 100644 --- a/server/streamServer.h +++ b/server/streamServer.h @@ -68,7 +68,7 @@ struct StreamServerSettings * Receives (via the MessageReceiver interface) and answers messages from the clients * Forwards PCM data to the clients */ -class StreamServer : public MessageReceiver, PipeListener +class StreamServer : public MessageReceiver, ControlMessageReceiver, PipeListener { public: StreamServer(const StreamServerSettings& streamServerSettings); @@ -84,6 +84,8 @@ public: virtual void onMessageReceived(ServerSession* connection, const msg::BaseMessage& baseMessage, char* buffer); virtual void onDisconnect(ServerSession* connection); + virtual void onMessageReceived(ControlSession* connection, const std::string& message); + /// Implementation of PipeListener virtual void onChunkRead(const PipeReader* pipeReader, const msg::PcmChunk* chunk, double duration); virtual void onResync(const PipeReader* pipeReader, double ms); @@ -92,6 +94,7 @@ private: void startAccept(); void handleAccept(socket_ptr socket); void acceptor(); + ServerSession* getClientSession(const std::string& mac); mutable std::mutex mutex_; PipeReader* pipeReader_; std::set> sessions_;