Merge "res_calendar: Specialized calendars depend on symbols of general calendar."
[asterisk/asterisk.git] / main / stasis_message.c
index b25d1f2..88db49f 100644 (file)
@@ -29,8 +29,6 @@
 
 #include "asterisk.h"
 
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
 #include "asterisk/astobj2.h"
 #include "asterisk/stasis.h"
 #include "asterisk/utils.h"
@@ -50,14 +48,20 @@ static void message_type_dtor(void *obj)
        type->name = NULL;
 }
 
-struct stasis_message_type *stasis_message_type_create(const char *name,
-       struct stasis_message_vtable *vtable)
+int stasis_message_type_create(const char *name,
+       struct stasis_message_vtable *vtable,
+       struct stasis_message_type **result)
 {
-       RAII_VAR(struct stasis_message_type *, type, NULL, ao2_cleanup);
+       struct stasis_message_type *type;
+
+       /* Check for declination */
+       if (name && stasis_message_type_declined(name)) {
+               return STASIS_MESSAGE_TYPE_DECLINED;
+       }
 
-       type = ao2_alloc(sizeof(*type), message_type_dtor);
+       type = ao2_t_alloc(sizeof(*type), message_type_dtor, name);
        if (!type) {
-               return NULL;
+               return STASIS_MESSAGE_TYPE_ERROR;
        }
        if (!vtable) {
                /* Null object pattern, FTW! */
@@ -66,12 +70,13 @@ struct stasis_message_type *stasis_message_type_create(const char *name,
 
        type->name = ast_strdup(name);
        if (!type->name) {
-               return NULL;
+               ao2_cleanup(type);
+               return STASIS_MESSAGE_TYPE_ERROR;
        }
        type->vtable = vtable;
+       *result = type;
 
-       ao2_ref(type, +1);
-       return type;
+       return STASIS_MESSAGE_TYPE_SUCCESS;
 }
 
 const char *stasis_message_type_name(const struct stasis_message_type *type)
@@ -85,8 +90,12 @@ struct stasis_message {
        struct timeval timestamp;
        /*! Type of the message */
        struct stasis_message_type *type;
+       /*! Where this message originated.  NULL if aggregate message. */
+       const struct ast_eid *eid_ptr;
        /*! Message content */
        void *data;
+       /*! Where this message originated. */
+       struct ast_eid eid;
 };
 
 static void stasis_message_dtor(void *obj)
@@ -96,15 +105,15 @@ static void stasis_message_dtor(void *obj)
        ao2_cleanup(message->data);
 }
 
-struct stasis_message *stasis_message_create(struct stasis_message_type *type, void *data)
+struct stasis_message *stasis_message_create_full(struct stasis_message_type *type, void *data, const struct ast_eid *eid)
 {
-       RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+       struct stasis_message *message;
 
        if (type == NULL || data == NULL) {
                return NULL;
        }
 
-       message = ao2_alloc(sizeof(*message), stasis_message_dtor);
+       message = ao2_t_alloc(sizeof(*message), stasis_message_dtor, type->name);
        if (message == NULL) {
                return NULL;
        }
@@ -114,11 +123,27 @@ struct stasis_message *stasis_message_create(struct stasis_message_type *type, v
        message->type = type;
        ao2_ref(data, +1);
        message->data = data;
+       if (eid) {
+               message->eid_ptr = &message->eid;
+               message->eid = *eid;
+       }
 
-       ao2_ref(message, +1);
        return message;
 }
 
+struct stasis_message *stasis_message_create(struct stasis_message_type *type, void *data)
+{
+       return stasis_message_create_full(type, data, &ast_eid_default);
+}
+
+const struct ast_eid *stasis_message_eid(const struct stasis_message *msg)
+{
+       if (msg == NULL) {
+               return NULL;
+       }
+       return msg->eid_ptr;
+}
+
 struct stasis_message_type *stasis_message_type(const struct stasis_message *msg)
 {
        if (msg == NULL) {
@@ -143,17 +168,17 @@ 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);          \
+#define INVOKE_VIRTUAL(fn, ...)                                        \
+       ({                                                                                      \
+               if (!msg) {                                                             \
+                       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__);     \
+               if (!msg->type->vtable->fn) {                   \
+                       return NULL;                                            \
+               }                                                                               \
+               msg->type->vtable->fn(__VA_ARGS__);             \
        })
 
 struct ast_manager_event_blob *stasis_message_to_ami(struct stasis_message *msg)
@@ -161,7 +186,29 @@ 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)
+struct ast_json *stasis_message_to_json(
+       struct stasis_message *msg,
+       struct stasis_message_sanitizer *sanitize)
+{
+       return INVOKE_VIRTUAL(to_json, msg, sanitize);
+}
+
+struct ast_event *stasis_message_to_event(struct stasis_message *msg)
+{
+       return INVOKE_VIRTUAL(to_event, msg);
+}
+
+#define HAS_VIRTUAL(fn, msg)                                   \
+       ({                                                                                      \
+               if (!msg) {                                                             \
+                       return 0;                                                       \
+               }                                                                               \
+               ast_assert(msg->type != NULL);                  \
+               ast_assert(msg->type->vtable != NULL);  \
+               !!msg->type->vtable->fn;                                \
+       })
+
+int stasis_message_can_be_ami(struct stasis_message *msg)
 {
-       return INVOKE_VIRTUAL(to_json, msg);
+       return HAS_VIRTUAL(to_ami, msg);
 }