summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/app.c35
-rw-r--r--main/devicestate.c33
-rw-r--r--main/event.c123
-rw-r--r--main/stasis.c21
-rw-r--r--main/stasis_message.c5
5 files changed, 194 insertions, 23 deletions
diff --git a/main/app.c b/main/app.c
index a5c4c7af5..3c2f33c51 100644
--- a/main/app.c
+++ b/main/app.c
@@ -96,10 +96,43 @@ static struct stasis_topic *queue_topic_all;
static struct stasis_topic_pool *queue_topic_pool;
/* @} */
+/*! \brief Convert a MWI \ref stasis_message to a \ref ast_event */
+static struct ast_event *mwi_to_event(struct stasis_message *message)
+{
+ struct ast_event *event;
+ struct ast_mwi_state *mwi_state;
+ char *mailbox;
+ char *context;
+
+ if (!message) {
+ return NULL;
+ }
+
+ mwi_state = stasis_message_data(message);
+
+ /* Strip off @context */
+ context = mailbox = ast_strdupa(mwi_state->uniqueid);
+ strsep(&context, "@");
+ if (ast_strlen_zero(context)) {
+ context = "default";
+ }
+
+ event = ast_event_new(AST_EVENT_MWI,
+ AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
+ AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
+ AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, mwi_state->new_msgs,
+ AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, mwi_state->old_msgs,
+ AST_EVENT_IE_EID, AST_EVENT_IE_PLTYPE_RAW, &mwi_state->eid, sizeof(mwi_state->eid),
+ AST_EVENT_IE_END);
+
+ return event;
+}
+
/*
* @{ \brief Define \ref stasis message types for MWI
*/
-STASIS_MESSAGE_TYPE_DEFN(ast_mwi_state_type);
+STASIS_MESSAGE_TYPE_DEFN(ast_mwi_state_type,
+ .to_event = mwi_to_event, );
STASIS_MESSAGE_TYPE_DEFN(ast_mwi_vm_app_type);
/* @} */
diff --git a/main/devicestate.c b/main/devicestate.c
index 1199e68ab..3580b1af7 100644
--- a/main/devicestate.c
+++ b/main/devicestate.c
@@ -224,9 +224,12 @@ static struct stasis_caching_topic *device_state_topic_cached;
static struct stasis_topic_pool *device_state_topic_pool;
static struct ast_manager_event_blob *devstate_to_ami(struct stasis_message *msg);
+static struct ast_event *devstate_to_event(struct stasis_message *msg);
+
STASIS_MESSAGE_TYPE_DEFN(ast_device_state_message_type,
.to_ami = devstate_to_ami,
+ .to_event = devstate_to_event,
);
/* Forward declarations */
@@ -925,3 +928,33 @@ static struct ast_manager_event_blob *devstate_to_ami(struct stasis_message *msg
"State: %s\r\n",
dev_state->device, ast_devstate_str(dev_state->state));
}
+
+/*! \brief Convert a \ref stasis_message to a \ref ast_event */
+static struct ast_event *devstate_to_event(struct stasis_message *message)
+{
+ struct ast_event *event;
+ struct ast_device_state_message *device_state;
+
+ if (!message) {
+ return NULL;
+ }
+
+ device_state = stasis_message_data(message);
+
+ if (device_state->eid) {
+ event = ast_event_new(AST_EVENT_DEVICE_STATE_CHANGE,
+ AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device_state->device,
+ AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, device_state->state,
+ AST_EVENT_IE_CACHABLE, AST_EVENT_IE_PLTYPE_UINT, device_state->cachable,
+ AST_EVENT_IE_EID, AST_EVENT_IE_PLTYPE_RAW, device_state->eid, sizeof(*device_state->eid),
+ AST_EVENT_IE_END);
+ } else {
+ event = ast_event_new(AST_EVENT_DEVICE_STATE,
+ AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device_state->device,
+ AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, device_state->state,
+ AST_EVENT_IE_CACHABLE, AST_EVENT_IE_PLTYPE_UINT, device_state->cachable,
+ AST_EVENT_IE_END);
+ }
+
+ return event;
+}
diff --git a/main/event.c b/main/event.c
index 990f62161..876e53b88 100644
--- a/main/event.c
+++ b/main/event.c
@@ -44,10 +44,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/astobj2.h"
#include "asterisk/cli.h"
-static int event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_type,
- const void *data, size_t data_len);
-static const void *event_get_ie_raw(const struct ast_event *event, enum ast_event_ie_type ie_type);
-
/*!
* \brief An event information element
*
@@ -109,19 +105,42 @@ struct ast_event_ie_val {
size_t raw_datalen;
};
-struct ie_map {
- enum ast_event_ie_pltype ie_pltype;
- const char *name;
+/*!
+ * \brief Event Names
+ */
+static const char * const event_names[AST_EVENT_TOTAL] = {
+ [AST_EVENT_ALL] = "All",
+ [AST_EVENT_CUSTOM] = "Custom",
+ [AST_EVENT_MWI] = "MWI",
+ [AST_EVENT_SUB] = "Subscription",
+ [AST_EVENT_UNSUB] = "Unsubscription",
+ [AST_EVENT_DEVICE_STATE] = "DeviceState",
+ [AST_EVENT_DEVICE_STATE_CHANGE] = "DeviceStateChange",
+ [AST_EVENT_CEL] = "CEL",
+ [AST_EVENT_SECURITY] = "Security",
+ [AST_EVENT_NETWORK_CHANGE] = "NetworkChange",
+ [AST_EVENT_PRESENCE_STATE] = "PresenceState",
+ [AST_EVENT_ACL_CHANGE] = "ACLChange",
+ [AST_EVENT_PING] = "Ping",
};
/*!
* \brief IE payload types and names
*/
-static const struct ie_map ie_maps[AST_EVENT_IE_TOTAL] = {
+static const struct ie_map {
+ enum ast_event_ie_pltype ie_pltype;
+ const char *name;
+} ie_maps[AST_EVENT_IE_TOTAL] = {
+ [AST_EVENT_IE_NEWMSGS] = { AST_EVENT_IE_PLTYPE_UINT, "NewMessages" },
+ [AST_EVENT_IE_OLDMSGS] = { AST_EVENT_IE_PLTYPE_UINT, "OldMessages" },
+ [AST_EVENT_IE_MAILBOX] = { AST_EVENT_IE_PLTYPE_STR, "Mailbox" },
[AST_EVENT_IE_UNIQUEID] = { AST_EVENT_IE_PLTYPE_UINT, "UniqueID" },
[AST_EVENT_IE_EVENTTYPE] = { AST_EVENT_IE_PLTYPE_UINT, "EventType" },
[AST_EVENT_IE_EXISTS] = { AST_EVENT_IE_PLTYPE_UINT, "Exists" },
+ [AST_EVENT_IE_DEVICE] = { AST_EVENT_IE_PLTYPE_STR, "Device" },
+ [AST_EVENT_IE_STATE] = { AST_EVENT_IE_PLTYPE_UINT, "State" },
[AST_EVENT_IE_CONTEXT] = { AST_EVENT_IE_PLTYPE_STR, "Context" },
+ [AST_EVENT_IE_EID] = { AST_EVENT_IE_PLTYPE_RAW, "EntityID" },
[AST_EVENT_IE_CEL_EVENT_TYPE] = { AST_EVENT_IE_PLTYPE_UINT, "CELEventType" },
[AST_EVENT_IE_CEL_EVENT_TIME] = { AST_EVENT_IE_PLTYPE_UINT, "CELEventTime" },
[AST_EVENT_IE_CEL_EVENT_TIME_USEC] = { AST_EVENT_IE_PLTYPE_UINT, "CELEventTimeUSec" },
@@ -144,6 +163,7 @@ static const struct ie_map ie_maps[AST_EVENT_IE_TOTAL] = {
[AST_EVENT_IE_CEL_LINKEDID] = { AST_EVENT_IE_PLTYPE_STR, "CELLinkedID" },
[AST_EVENT_IE_CEL_PEERACCT] = { AST_EVENT_IE_PLTYPE_STR, "CELPeerAcct" },
[AST_EVENT_IE_CEL_EXTRA] = { AST_EVENT_IE_PLTYPE_STR, "CELExtra" },
+ [AST_EVENT_IE_SECURITY_EVENT] = { AST_EVENT_IE_PLTYPE_STR, "SecurityEvent" },
[AST_EVENT_IE_EVENT_VERSION] = { AST_EVENT_IE_PLTYPE_UINT, "EventVersion" },
[AST_EVENT_IE_SERVICE] = { AST_EVENT_IE_PLTYPE_STR, "Service" },
[AST_EVENT_IE_MODULE] = { AST_EVENT_IE_PLTYPE_STR, "Module" },
@@ -166,8 +186,27 @@ static const struct ie_map ie_maps[AST_EVENT_IE_TOTAL] = {
[AST_EVENT_IE_RECEIVED_HASH] = { AST_EVENT_IE_PLTYPE_STR, "ReceivedHash" },
[AST_EVENT_IE_USING_PASSWORD] = { AST_EVENT_IE_PLTYPE_UINT, "UsingPassword" },
[AST_EVENT_IE_ATTEMPTED_TRANSPORT] = { AST_EVENT_IE_PLTYPE_STR, "AttemptedTransport" },
+ [AST_EVENT_IE_CACHABLE] = { AST_EVENT_IE_PLTYPE_UINT, "Cachable" },
+ [AST_EVENT_IE_PRESENCE_PROVIDER] = { AST_EVENT_IE_PLTYPE_STR, "PresenceProvider" },
+ [AST_EVENT_IE_PRESENCE_STATE] = { AST_EVENT_IE_PLTYPE_UINT, "PresenceState" },
+ [AST_EVENT_IE_PRESENCE_SUBTYPE] = { AST_EVENT_IE_PLTYPE_STR, "PresenceSubtype" },
+ [AST_EVENT_IE_PRESENCE_MESSAGE] = { AST_EVENT_IE_PLTYPE_STR, "PresenceMessage" },
};
+const char *ast_event_get_type_name(const struct ast_event *event)
+{
+ enum ast_event_type type;
+
+ type = ast_event_get_type(event);
+
+ if (type < 0 || type >= ARRAY_LEN(event_names)) {
+ ast_log(LOG_ERROR, "Invalid event type - '%d'\n", type);
+ return "";
+ }
+
+ return event_names[type];
+}
+
const char *ast_event_get_ie_type_name(enum ast_event_ie_type ie_type)
{
if (ie_type <= 0 || ie_type >= ARRAY_LEN(ie_maps)) {
@@ -257,7 +296,7 @@ uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_
{
const uint32_t *ie_val;
- ie_val = event_get_ie_raw(event, ie_type);
+ ie_val = ast_event_get_ie_raw(event, ie_type);
return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0;
}
@@ -266,12 +305,12 @@ const char *ast_event_get_ie_str(const struct ast_event *event, enum ast_event_i
{
const struct ast_event_ie_str_payload *str_payload;
- str_payload = event_get_ie_raw(event, ie_type);
+ str_payload = ast_event_get_ie_raw(event, ie_type);
return str_payload ? str_payload->str : NULL;
}
-static const void *event_get_ie_raw(const struct ast_event *event, enum ast_event_ie_type ie_type)
+const void *ast_event_get_ie_raw(const struct ast_event *event, enum ast_event_ie_type ie_type)
{
struct ast_event_iterator iterator;
int res;
@@ -285,6 +324,26 @@ static const void *event_get_ie_raw(const struct ast_event *event, enum ast_even
return NULL;
}
+static uint16_t event_iterator_get_ie_raw_payload_len(struct ast_event_iterator *iterator)
+{
+ return ntohs(iterator->ie->ie_payload_len);
+}
+
+uint16_t ast_event_get_ie_raw_payload_len(const struct ast_event *event, enum ast_event_ie_type ie_type)
+{
+ struct ast_event_iterator iterator;
+ int res;
+
+ for (res = ast_event_iterator_init(&iterator, event); !res; res = ast_event_iterator_next(&iterator)) {
+ if (ast_event_iterator_get_ie_type(&iterator) == ie_type) {
+ return event_iterator_get_ie_raw_payload_len(&iterator);
+ }
+ }
+
+ return 0;
+}
+
+
int ast_event_append_ie_str(struct ast_event **event, enum ast_event_ie_type ie_type,
const char *str)
{
@@ -297,17 +356,24 @@ int ast_event_append_ie_str(struct ast_event **event, enum ast_event_ie_type ie_
strcpy(str_payload->str, str);
str_payload->hash = ast_str_hash(str);
- return event_append_ie_raw(event, ie_type, str_payload, payload_len);
+ return ast_event_append_ie_raw(event, ie_type, str_payload, payload_len);
}
int ast_event_append_ie_uint(struct ast_event **event, enum ast_event_ie_type ie_type,
uint32_t data)
{
data = htonl(data);
- return event_append_ie_raw(event, ie_type, &data, sizeof(data));
+ return ast_event_append_ie_raw(event, ie_type, &data, sizeof(data));
+}
+
+int ast_event_append_ie_bitflags(struct ast_event **event, enum ast_event_ie_type ie_type,
+ uint32_t flags)
+{
+ flags = htonl(flags);
+ return ast_event_append_ie_raw(event, ie_type, &flags, sizeof(flags));
}
-static int event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_type,
+int ast_event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_type,
const void *data, size_t data_len)
{
struct ast_event_ie *ie;
@@ -361,11 +427,16 @@ struct ast_event *ast_event_new(enum ast_event_type type, ...)
memset(ie_value, 0, sizeof(*ie_value));
ie_value->ie_type = ie_type;
ie_value->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
+
switch (ie_value->ie_pltype) {
case AST_EVENT_IE_PLTYPE_UINT:
ie_value->payload.uint = va_arg(ap, uint32_t);
insert = 1;
break;
+ case AST_EVENT_IE_PLTYPE_BITFLAGS:
+ ie_value->payload.uint = va_arg(ap, uint32_t);
+ insert = 1;
+ break;
case AST_EVENT_IE_PLTYPE_STR:
ie_value->payload.str = va_arg(ap, const char *);
insert = 1;
@@ -381,6 +452,7 @@ struct ast_event *ast_event_new(enum ast_event_type type, ...)
break;
}
case AST_EVENT_IE_PLTYPE_UNKNOWN:
+ case AST_EVENT_IE_PLTYPE_EXISTS:
break;
}
@@ -407,10 +479,14 @@ struct ast_event *ast_event_new(enum ast_event_type type, ...)
case AST_EVENT_IE_PLTYPE_UINT:
ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
break;
+ case AST_EVENT_IE_PLTYPE_BITFLAGS:
+ ast_event_append_ie_bitflags(&event, ie_val->ie_type, ie_val->payload.uint);
+ break;
case AST_EVENT_IE_PLTYPE_RAW:
- event_append_ie_raw(&event, ie_val->ie_type,
+ ast_event_append_ie_raw(&event, ie_val->ie_type,
ie_val->payload.raw, ie_val->raw_datalen);
break;
+ case AST_EVENT_IE_PLTYPE_EXISTS:
case AST_EVENT_IE_PLTYPE_UNKNOWN:
break;
}
@@ -421,10 +497,27 @@ struct ast_event *ast_event_new(enum ast_event_type type, ...)
}
}
+ if (!ast_event_get_ie_raw(event, AST_EVENT_IE_EID)) {
+ /* If the event is originating on this server, add the server's
+ * entity ID to the event. */
+ ast_event_append_eid(&event);
+ }
+
return event;
}
+int ast_event_append_eid(struct ast_event **event)
+{
+ return ast_event_append_ie_raw(event, AST_EVENT_IE_EID,
+ &ast_eid_default, sizeof(ast_eid_default));
+}
+
void ast_event_destroy(struct ast_event *event)
{
ast_free(event);
}
+
+size_t ast_event_minimum_length(void)
+{
+ return sizeof(struct ast_event);
+}
diff --git a/main/stasis.c b/main/stasis.c
index 4d05f18e8..5eca791ef 100644
--- a/main/stasis.c
+++ b/main/stasis.c
@@ -686,15 +686,17 @@ struct stasis_forward *stasis_forward_cancel(struct stasis_forward *forward)
from = forward->from_topic;
to = forward->to_topic;
- topic_lock_both(to, from);
- AST_VECTOR_REMOVE_ELEM_UNORDERED(&to->upstream_topics, from,
- AST_VECTOR_ELEM_CLEANUP_NOOP);
+ if (from && to) {
+ topic_lock_both(to, from);
+ AST_VECTOR_REMOVE_ELEM_UNORDERED(&to->upstream_topics, from,
+ AST_VECTOR_ELEM_CLEANUP_NOOP);
- for (idx = 0; idx < AST_VECTOR_SIZE(&to->subscribers); ++idx) {
- topic_remove_subscription(from, AST_VECTOR_GET(&to->subscribers, idx));
+ for (idx = 0; idx < AST_VECTOR_SIZE(&to->subscribers); ++idx) {
+ topic_remove_subscription(from, AST_VECTOR_GET(&to->subscribers, idx));
+ }
+ ao2_unlock(from);
+ ao2_unlock(to);
}
- ao2_unlock(from);
- ao2_unlock(to);
ao2_cleanup(forward);
@@ -717,6 +719,11 @@ struct stasis_forward *stasis_forward_all(struct stasis_topic *from_topic,
return NULL;
}
+ /* Forwards to ourselves are implicit. */
+ if (to_topic == from_topic) {
+ return ao2_bump(forward);
+ }
+
forward->from_topic = ao2_bump(from_topic);
forward->to_topic = ao2_bump(to_topic);
diff --git a/main/stasis_message.c b/main/stasis_message.c
index 1db2ae97a..6132efc20 100644
--- a/main/stasis_message.c
+++ b/main/stasis_message.c
@@ -187,3 +187,8 @@ struct ast_json *stasis_message_to_json(
{
return INVOKE_VIRTUAL(to_json, msg, sanitize);
}
+
+struct ast_event *stasis_message_to_event(struct stasis_message *msg)
+{
+ return INVOKE_VIRTUAL(to_event, msg);
+} \ No newline at end of file