core: add message handler

This patch adds a small message handler to the core which enables
clients to list available handlers via the list-handlers message.
Command: pacmd send-message /core list-handlers
pactl can be used with the same parameters.

The patch also introduces a convention for the return string.
It consists of a list of elements where curly braces are used
to separate elements. Each element can itself contain further
elements. For example consider a message that returns multiple
elements which each contain an integer and an array of float.
A response string would look like that:
{{Integer} {{1st float} {2nd float} ...}}{...}

Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/51>
This commit is contained in:
Georg Chini 2020-01-14 11:00:20 +01:00 committed by Tanu Kaskinen
parent 68f2f1395d
commit 5c0ab52145
3 changed files with 84 additions and 6 deletions

View file

@ -31,6 +31,20 @@
#include "message-handler.h"
/* Check if a string does not contain control characters. Currently these are
* only "{" and "}". */
static bool string_is_valid(const char *test_string) {
uint32_t i;
for (i = 0; test_string[i]; i++) {
if (test_string[i] == '{' ||
test_string[i] == '}')
return false;
}
return true;
}
/* Message handler functions */
/* Register message handler for the specified object. object_path must be a unique name starting with "/". */
@ -45,6 +59,11 @@ void pa_message_handler_register(pa_core *c, const char *object_path, const char
/* Ensure that the object path is not empty and starts with "/". */
pa_assert(object_path[0] == '/');
/* Ensure that object path and description are valid strings */
pa_assert(string_is_valid(object_path));
if (description)
pa_assert(string_is_valid(description));
handler = pa_xnew0(struct pa_message_handler, 1);
handler->userdata = userdata;
handler->callback = cb;
@ -97,6 +116,11 @@ int pa_message_handler_set_description(pa_core *c, const char *object_path, cons
if (!(handler = pa_hashmap_get(c->message_handlers, object_path)))
return -PA_ERR_NOENTITY;
if (description) {
if (!string_is_valid(description))
return -PA_ERR_INVALID;
}
pa_xfree(handler->description);
handler->description = pa_xstrdup(description);