added Host, Snapcast and Config to Client json

This commit is contained in:
badaix 2016-03-06 13:48:44 +01:00
parent d8e23fadac
commit 8ddf928b9a
3 changed files with 167 additions and 52 deletions

View file

@ -84,7 +84,7 @@ ClientInfoPtr Config::getClientInfo(const std::string& macAddress, bool add)
for (auto client: clients) for (auto client: clients)
{ {
if (client->macAddress == macAddress) if (client->host.mac == macAddress)
return client; return client;
} }

View file

@ -24,6 +24,8 @@
#include <vector> #include <vector>
#include <sys/time.h> #include <sys/time.h>
#include "json/json.hpp" #include "json/json.hpp"
#include "common/utils.h"
using json = nlohmann::json; using json = nlohmann::json;
@ -67,9 +69,106 @@ struct Volume
struct Host
{
Host(const std::string& _macAddress = "") : name(getHostName()), mac(_macAddress), os(getOS()), arch(getArch()), ip("")
{
}
void fromJson(const json& j)
{
name = trim_copy(jGet<std::string>(j, "name", ""));
mac = trim_copy(jGet<std::string>(j, "mac", ""));
os = trim_copy(jGet<std::string>(j, "os", ""));
arch = trim_copy(jGet<std::string>(j, "arch", ""));
ip = trim_copy(jGet<std::string>(j, "ip", ""));
}
json toJson()
{
json j;
j["name"] = name;
j["mac"] = mac;
j["os"] = os;
j["arch"] = arch;
j["ip"] = ip;
return j;
}
std::string name;
std::string mac;
std::string os;
std::string arch;
std::string ip;
};
struct ClientConfig
{
ClientConfig() : name(""), volume(100), latency(0), streamId("")
{
}
void fromJson(const json& j)
{
name = trim_copy(jGet<std::string>(j, "name", ""));
volume.fromJson(j["volume"]);
latency = jGet<int32_t>(j, "latency", 0);
streamId = trim_copy(jGet<std::string>(j, "stream", ""));
}
json toJson()
{
json j;
j["name"] = trim_copy(name);
j["volume"] = volume.toJson();
j["latency"] = latency;
j["stream"] = trim_copy(streamId);
return j;
}
std::string name;
Volume volume;
int32_t latency;
std::string streamId;
};
struct Snapcast
{
Snapcast(const std::string& _name = "", const std::string& _version = "") : name(_name), version(_version), streamProtocolVersion(1), controlProtocolVersion(1)
{
}
void fromJson(const json& j)
{
name = trim_copy(jGet<std::string>(j, "name", ""));
version = trim_copy(jGet<std::string>(j, "version", ""));
streamProtocolVersion = jGet<int>(j, "streamProtocolVersion", 1);
controlProtocolVersion = jGet<int>(j, "controlProtocolVersion", 1);
}
json toJson()
{
json j;
j["name"] = trim_copy(name);
j["version"] = trim_copy(version);
j["streamProtocolVersion"] = streamProtocolVersion;
j["controlProtocolVersion"] = controlProtocolVersion;
return j;
}
std::string name;
std::string version;
int streamProtocolVersion;
int controlProtocolVersion;
};
struct ClientInfo struct ClientInfo
{ {
ClientInfo(const std::string& _macAddress = "") : macAddress(_macAddress), volume(100), connected(false), latency(0), streamId("") ClientInfo(const std::string& _macAddress = "") : host(_macAddress), connected(false)
{ {
lastSeen.tv_sec = 0; lastSeen.tv_sec = 0;
lastSeen.tv_usec = 0; lastSeen.tv_usec = 0;
@ -77,47 +176,52 @@ struct ClientInfo
void fromJson(const json& j) void fromJson(const json& j)
{ {
macAddress = jGet<std::string>(j, "MAC", ""); if (j.count("host") && !j["host"].is_string())
ipAddress = jGet<std::string>(j, "IP", ""); host.fromJson(j["host"]);
hostName = jGet<std::string>(j, "host", ""); else
version = jGet<std::string>(j, "version", ""); {
name = jGet<std::string>(j, "name", ""); host.ip = jGet<std::string>(j, "IP", "");
volume.fromJson(j["volume"]); host.mac = jGet<std::string>(j, "MAC", "");
host.name = jGet<std::string>(j, "host", "");
}
if (j.count("snapclient"))
snapclient.fromJson(j["snapclient"]);
else
snapclient.version = jGet<std::string>(j, "version", "");
if (j.count("config"))
host.fromJson(j["config"]);
else
{
config.name = trim_copy(jGet<std::string>(j, "name", ""));
config.volume.fromJson(j["volume"]);
config.latency = jGet<int32_t>(j, "latency", 0);
config.streamId = trim_copy(jGet<std::string>(j, "stream", ""));
}
lastSeen.tv_sec = jGet<int32_t>(j["lastSeen"], "sec", 0); lastSeen.tv_sec = jGet<int32_t>(j["lastSeen"], "sec", 0);
lastSeen.tv_usec = jGet<int32_t>(j["lastSeen"], "usec", 0); lastSeen.tv_usec = jGet<int32_t>(j["lastSeen"], "usec", 0);
connected = jGet<bool>(j, "connected", true); connected = jGet<bool>(j, "connected", true);
latency = jGet<int32_t>(j, "latency", 0);
streamId = jGet<std::string>(j, "stream", "");
} }
json toJson() json toJson()
{ {
json j; json j;
j["MAC"] = macAddress; j["host"] = host.toJson();
j["IP"] = ipAddress; j["snapclient"] = snapclient.toJson();
j["host"] = hostName; j["config"] = config.toJson();
j["version"] = version;
j["name"] = name;
j["volume"] = volume.toJson();
j["lastSeen"]["sec"] = lastSeen.tv_sec; j["lastSeen"]["sec"] = lastSeen.tv_sec;
j["lastSeen"]["usec"] = lastSeen.tv_usec; j["lastSeen"]["usec"] = lastSeen.tv_usec;
j["connected"] = connected; j["connected"] = connected;
j["latency"] = latency;
j["stream"] = streamId;
return j; return j;
} }
std::string macAddress; Host host;
std::string ipAddress; Snapcast snapclient;
std::string hostName; ClientConfig config;
std::string version;
std::string name;
Volume volume;
bool muted;
timeval lastSeen; timeval lastSeen;
bool connected; bool connected;
int32_t latency;
std::string streamId;
}; };
typedef std::shared_ptr<ClientInfo> ClientInfoPtr; typedef std::shared_ptr<ClientInfo> ClientInfoPtr;

View file

@ -135,21 +135,25 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
else else
jClient = Config::instance().getClientInfos(); jClient = Config::instance().getClientInfos();
Host host;
//TODO: Set MAC and IP
Snapcast snapserver("Snapserver", VERSION);
response = { response = {
{"server", { {"server", {
{"host", getHostName()}, {"host", host.toJson()},//getHostName()},
{"version", VERSION} {"snapserver", snapserver.toJson()}
}}, }},
{"clients", jClient}, {"clients", jClient},
{"streams", streamManager_->toJson()} {"streams", streamManager_->toJson()}
}; };
// cout << response.dump(4);
} }
else if (request.method == "Server.DeleteClient") else if (request.method == "Server.DeleteClient")
{ {
clientInfo = Config::instance().getClientInfo(request.getParam("client").get<string>(), false); clientInfo = Config::instance().getClientInfo(request.getParam("client").get<string>(), false);
if (clientInfo == nullptr) if (clientInfo == nullptr)
throw JsonInternalErrorException("Client not found", request.id); throw JsonInternalErrorException("Client not found", request.id);
response = clientInfo->macAddress; response = clientInfo->host.mac;
Config::instance().remove(clientInfo); Config::instance().remove(clientInfo);
Config::instance().save(); Config::instance().save();
json notification = JsonNotification::getJson("Client.OnDelete", clientInfo->toJson()); json notification = JsonNotification::getJson("Client.OnDelete", clientInfo->toJson());
@ -158,13 +162,13 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
} }
else if (request.method == "Client.SetVolume") else if (request.method == "Client.SetVolume")
{ {
clientInfo->volume.percent = request.getParam<uint16_t>("volume", 0, 100); clientInfo->config.volume.percent = request.getParam<uint16_t>("volume", 0, 100);
response = clientInfo->volume.percent; response = clientInfo->config.volume.percent;
} }
else if (request.method == "Client.SetMute") else if (request.method == "Client.SetMute")
{ {
clientInfo->volume.muted = request.getParam<bool>("mute", false, true); clientInfo->config.volume.muted = request.getParam<bool>("mute", false, true);
response = clientInfo->volume.muted; response = clientInfo->config.volume.muted;
} }
else if (request.method == "Client.SetStream") else if (request.method == "Client.SetStream")
{ {
@ -173,8 +177,8 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
if (stream == nullptr) if (stream == nullptr)
throw JsonInternalErrorException("Stream not found", request.id); throw JsonInternalErrorException("Stream not found", request.id);
clientInfo->streamId = streamId; clientInfo->config.streamId = streamId;
response = clientInfo->streamId; response = clientInfo->config.streamId;
StreamSession* session = getStreamSession(request.getParam("client").get<string>()); StreamSession* session = getStreamSession(request.getParam("client").get<string>());
if (session != NULL) if (session != NULL)
@ -185,22 +189,22 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
} }
else if (request.method == "Client.SetLatency") else if (request.method == "Client.SetLatency")
{ {
clientInfo->latency = request.getParam<int>("latency", -10000, settings_.bufferMs); clientInfo->config.latency = request.getParam<int>("latency", -10000, settings_.bufferMs);
response = clientInfo->latency; response = clientInfo->config.latency;
} }
else if (request.method == "Client.SetName") else if (request.method == "Client.SetName")
{ {
clientInfo->name = request.getParam("name").get<string>(); clientInfo->config.name = request.getParam("name").get<string>();
response = clientInfo->name; response = clientInfo->config.name;
} }
else else
throw JsonMethodNotFoundException(request.id); throw JsonMethodNotFoundException(request.id);
if (clientInfo != nullptr) if (clientInfo != nullptr)
{ {
serverSettings.volume = clientInfo->volume.percent; serverSettings.volume = clientInfo->config.volume.percent;
serverSettings.muted = clientInfo->volume.muted; serverSettings.muted = clientInfo->config.volume.muted;
serverSettings.latency = clientInfo->latency; serverSettings.latency = clientInfo->config.latency;
StreamSession* session = getStreamSession(request.getParam("client").get<string>()); StreamSession* session = getStreamSession(request.getParam("client").get<string>());
if (session != NULL) if (session != NULL)
@ -247,7 +251,9 @@ void StreamServer::onMessageReceived(StreamSession* connection, const msg::BaseM
msg::Hello helloMsg; msg::Hello helloMsg;
helloMsg.deserialize(baseMessage, buffer); helloMsg.deserialize(baseMessage, buffer);
connection->macAddress = helloMsg.getMacAddress(); connection->macAddress = helloMsg.getMacAddress();
logO << "Hello from " << connection->macAddress << ", host: " << helloMsg.getHostName() << ", v" << helloMsg.getVersion() << "\n"; logO << "Hello from " << connection->macAddress << ", host: " << helloMsg.getHostName() << ", v" << helloMsg.getVersion()
<< ", ClientName: " << helloMsg.getClientName() << ", OS: " << helloMsg.getOS() << ", Arch: " << helloMsg.getArch()
<< ", control version: " << helloMsg.getControlProtocolVersion() << ", Stream version: " << helloMsg.getStreamProtocolVersion() << "\n";
logD << "request kServerSettings: " << connection->macAddress << "\n"; logD << "request kServerSettings: " << connection->macAddress << "\n";
// std::lock_guard<std::mutex> mlock(mutex_); // std::lock_guard<std::mutex> mlock(mutex_);
@ -260,27 +266,32 @@ void StreamServer::onMessageReceived(StreamSession* connection, const msg::BaseM
{ {
logD << "request kServerSettings\n"; logD << "request kServerSettings\n";
msg::ServerSettings serverSettings; msg::ServerSettings serverSettings;
serverSettings.volume = clientInfo->volume.percent; serverSettings.volume = clientInfo->config.volume.percent;
serverSettings.muted = clientInfo->volume.muted; serverSettings.muted = clientInfo->config.volume.muted;
serverSettings.latency = clientInfo->latency; serverSettings.latency = clientInfo->config.latency;
serverSettings.refersTo = helloMsg.id; serverSettings.refersTo = helloMsg.id;
serverSettings.bufferMs = settings_.bufferMs; serverSettings.bufferMs = settings_.bufferMs;
connection->send(&serverSettings); connection->send(&serverSettings);
} }
ClientInfoPtr client = Config::instance().getClientInfo(connection->macAddress); ClientInfoPtr client = Config::instance().getClientInfo(connection->macAddress);
client->ipAddress = connection->getIP(); client->host.ip = connection->getIP();
client->hostName = helloMsg.getHostName(); client->host.name = helloMsg.getHostName();
client->version = helloMsg.getVersion(); client->host.os = helloMsg.getOS();
client->host.arch = helloMsg.getArch();
client->snapclient.version = helloMsg.getVersion();
client->snapclient.name = helloMsg.getClientName();
client->snapclient.streamProtocolVersion = helloMsg.getStreamProtocolVersion();
client->snapclient.controlProtocolVersion = helloMsg.getControlProtocolVersion();
client->connected = true; client->connected = true;
gettimeofday(&client->lastSeen, NULL); gettimeofday(&client->lastSeen, NULL);
// Assign and update stream // Assign and update stream
PcmReaderPtr stream = streamManager_->getStream(client->streamId); PcmReaderPtr stream = streamManager_->getStream(client->config.streamId);
if (stream == nullptr) if (stream == nullptr)
{ {
stream = streamManager_->getDefaultStream(); stream = streamManager_->getDefaultStream();
client->streamId = stream->getUri().id(); client->config.streamId = stream->getUri().id();
} }
Config::instance().save(); Config::instance().save();