summaryrefslogtreecommitdiff
path: root/main/stasis_message.c
diff options
context:
space:
mode:
authorDavid M. Lee <dlee@digium.com>2013-06-11 15:46:35 +0000
committerDavid M. Lee <dlee@digium.com>2013-06-11 15:46:35 +0000
commitdbdb2b1b3a618a79b3e42c77c05cb2688b4da08d (patch)
tree6d7174c03a0388cf81bee13403cf4c118184d1d9 /main/stasis_message.c
parent2053fc31594d4069cb178e591ab2b4e0df08b268 (diff)
Add vtable and methods for to_json and to_ami for Stasis messages
When a Stasis message type is defined in a loadable module, handling those messages for AMI and res_stasis events can be cumbersome. This patch adds a vtable to stasis_message_type, with to_ami and to_json virtual functions. These allow messages to be handled abstractly without putting module-specific code in core. As an example, the VarSet AMI event was refactored to use the to_ami virtual function. (closes issue ASTERISK-21817) Review: https://reviewboard.asterisk.org/r/2579/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@391403 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/stasis_message.c')
-rw-r--r--main/stasis_message.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/main/stasis_message.c b/main/stasis_message.c
index 8d2373f4d..b25d1f25a 100644
--- a/main/stasis_message.c
+++ b/main/stasis_message.c
@@ -37,9 +37,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
/*! \internal */
struct stasis_message_type {
+ struct stasis_message_vtable *vtable;
char *name;
};
+static struct stasis_message_vtable null_vtable = {};
+
static void message_type_dtor(void *obj)
{
struct stasis_message_type *type = obj;
@@ -47,7 +50,8 @@ static void message_type_dtor(void *obj)
type->name = NULL;
}
-struct stasis_message_type *stasis_message_type_create(const char *name)
+struct stasis_message_type *stasis_message_type_create(const char *name,
+ struct stasis_message_vtable *vtable)
{
RAII_VAR(struct stasis_message_type *, type, NULL, ao2_cleanup);
@@ -55,11 +59,16 @@ struct stasis_message_type *stasis_message_type_create(const char *name)
if (!type) {
return NULL;
}
+ if (!vtable) {
+ /* Null object pattern, FTW! */
+ vtable = &null_vtable;
+ }
type->name = ast_strdup(name);
if (!type->name) {
return NULL;
}
+ type->vtable = vtable;
ao2_ref(type, +1);
return type;
@@ -133,3 +142,26 @@ const struct timeval *stasis_message_timestamp(const struct stasis_message *msg)
}
return &msg->timestamp;
}
+
+#define INVOKE_VIRTUAL(fn, ...) \
+ ({ \
+ if (msg == NULL) { \
+ return NULL; \
+ } \
+ ast_assert(msg->type != NULL); \
+ ast_assert(msg->type->vtable != NULL); \
+ if (msg->type->vtable->fn == NULL) { \
+ return NULL; \
+ } \
+ msg->type->vtable->fn(__VA_ARGS__); \
+ })
+
+struct ast_manager_event_blob *stasis_message_to_ami(struct stasis_message *msg)
+{
+ return INVOKE_VIRTUAL(to_ami, msg);
+}
+
+struct ast_json *stasis_message_to_json(struct stasis_message *msg)
+{
+ return INVOKE_VIRTUAL(to_json, msg);
+}