output/Interface: add "attributes" map

These attributes are printed in the "outputs" response, and the new
command "outputset" allows setting new values.

No attributes are currently implemented.
This commit is contained in:
Max Kellermann
2017-12-19 08:45:34 +01:00
parent d05c3f4e4d
commit 86a06a7acc
13 changed files with 161 additions and 1 deletions

View File

@@ -138,6 +138,7 @@ static constexpr struct command commands[] = {
{ "next", PERMISSION_CONTROL, 0, 0, handle_next },
{ "notcommands", PERMISSION_NONE, 0, 0, handle_not_commands },
{ "outputs", PERMISSION_READ, 0, 0, handle_devices },
{ "outputset", PERMISSION_ADMIN, 3, 3, handle_outputset },
{ "partition", PERMISSION_READ, 1, 1, handle_partition },
{ "password", PERMISSION_NONE, 1, 1, handle_password },
{ "pause", PERMISSION_CONTROL, 0, 1, handle_pause },

View File

@@ -25,6 +25,8 @@
#include "client/Client.hxx"
#include "client/Response.hxx"
#include "Partition.hxx"
#include "IdleFlags.hxx"
#include "util/CharUtil.hxx"
CommandResult
handle_enableoutput(Client &client, Request args, Response &r)
@@ -68,6 +70,54 @@ handle_toggleoutput(Client &client, Request args, Response &r)
return CommandResult::OK;
}
static bool
IsValidAttributeNameChar(char ch) noexcept
{
return IsAlphaNumericASCII(ch) || ch == '_';
}
gcc_pure
static bool
IsValidAttributeName(const char *s) noexcept
{
do {
if (!IsValidAttributeNameChar(*s))
return false;
} while (*++s);
return true;
}
CommandResult
handle_outputset(Client &client, Request request, Response &response)
{
assert(request.size == 3);
const unsigned i = request.ParseUnsigned(0);
auto &partition = client.GetPartition();
auto &outputs = partition.outputs;
if (i >= outputs.Size()) {
response.Error(ACK_ERROR_NO_EXIST, "No such audio output");
return CommandResult::ERROR;
}
auto &ao = outputs.Get(i);
const char *const name = request[1];
if (!IsValidAttributeName(name)) {
response.Error(ACK_ERROR_ARG, "Illegal attribute name");
return CommandResult::ERROR;
}
const char *const value = request[2];
ao.SetAttribute(name, value);
partition.EmitIdle(IDLE_OUTPUT);
return CommandResult::OK;
}
CommandResult
handle_devices(Client &client, gcc_unused Request args, Response &r)
{

View File

@@ -35,6 +35,9 @@ handle_disableoutput(Client &client, Request request, Response &response);
CommandResult
handle_toggleoutput(Client &client, Request request, Response &response);
CommandResult
handle_outputset(Client &client, Request request, Response &response);
CommandResult
handle_devices(Client &client, Request request, Response &response);