summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorKinsey Moore <kmoore@digium.com>2013-08-17 14:46:44 +0000
committerKinsey Moore <kmoore@digium.com>2013-08-17 14:46:44 +0000
commitd7f1f3127084e4b7b204141c0b40c28c327f74b0 (patch)
treedf54e4afb05375633f67c2cefe694eddbf2f146e /main
parent59753b1ea10a83ea770c35b24cd443620913349c (diff)
Refactor CEL to avoid using the event system core
This removes usage of the event system for CEL backend data distribution and strips unused pieces out of the event system. Review: https://reviewboard.asterisk.org/r/2732/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@396888 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/asterisk.c5
-rw-r--r--main/cel.c132
-rw-r--r--main/event.c658
3 files changed, 115 insertions, 680 deletions
diff --git a/main/asterisk.c b/main/asterisk.c
index 07186f655..d6a454e8b 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -4149,11 +4149,6 @@ int main(int argc, char *argv[])
exit(1);
}
- if (ast_event_init()) {
- printf("%s", term_quit());
- exit(1);
- }
-
#ifdef TEST_FRAMEWORK
if (ast_test_init()) {
printf("%s", term_quit());
diff --git a/main/cel.c b/main/cel.c
index d9e1d81df..a613b7c2e 100644
--- a/main/cel.c
+++ b/main/cel.c
@@ -147,11 +147,17 @@ static struct stasis_subscription *cel_cel_forwarder;
/*! Container for primary channel/bridge ID listing for 2 party bridges */
static struct ao2_container *bridge_primaries;
+/*! The number of buckets into which bridge primary structs will be hashed */
+#define BRIDGE_PRIMARY_BUCKETS 251
+
struct stasis_message_type *cel_generic_type(void);
STASIS_MESSAGE_TYPE_DEFN(cel_generic_type);
-/*! The number of buckets into which primary channel uniqueids will be hashed */
-#define BRIDGE_PRIMARY_BUCKETS 251
+/*! Container for CEL backend information */
+static struct ao2_container *cel_backends;
+
+/*! The number of buckets into which backend names will be hashed */
+#define BACKEND_BUCKETS 13
/*! Container for dial end multichannel blobs for holding on to dial statuses */
static struct ao2_container *cel_dialstatus_store;
@@ -323,6 +329,57 @@ static const char * const cel_event_types[CEL_MAX_EVENT_IDS] = {
[AST_CEL_LOCAL_OPTIMIZE] = "LOCAL_OPTIMIZE",
};
+struct cel_backend {
+ ast_cel_backend_cb callback; /*!< Callback for this backend */
+ char name[0]; /*!< Name of this backend */
+};
+
+/*! \brief Hashing function for cel_backend */
+static int cel_backend_hash(const void *obj, int flags)
+{
+ const struct cel_backend *backend;
+ const char *name;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ case OBJ_POINTER:
+ backend = obj;
+ name = backend->name;
+ break;
+ case OBJ_KEY:
+ name = obj;
+ break;
+ default:
+ /* Hash can only work on something with a full key. */
+ ast_assert(0);
+ return 0;
+ }
+
+ return ast_str_hash(name);
+}
+
+/*! \brief Comparator function for cel_backend */
+static int cel_backend_cmp(void *obj, void *arg, int flags)
+{
+ struct cel_backend *backend2, *backend1 = obj;
+ const char *backend2_id, *backend1_id = backend1->name;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ case OBJ_POINTER:
+ backend2 = arg;
+ backend2_id = backend2->name;
+ break;
+ case OBJ_KEY:
+ backend2_id = arg;
+ break;
+ default:
+ /* Hash can only work on something with a full key. */
+ ast_assert(0);
+ return 0;
+ }
+
+ return !strcmp(backend1_id, backend2_id) ? CMP_MATCH | CMP_STOP : 0;
+}
+
struct bridge_assoc {
AST_DECLARE_STRING_FIELDS(
AST_STRING_FIELD(bridge_id); /*!< UniqueID of the bridge */
@@ -451,18 +508,18 @@ static int print_app(void *obj, void *arg, int flags)
return 0;
}
-static void print_cel_sub(const struct ast_event *event, void *data)
+static int event_desc_cb(void *obj, void *arg, int flags)
{
- struct ast_cli_args *a = data;
+ struct ast_cli_args *a = arg;
+ struct cel_backend *backend = obj;
- ast_cli(a->fd, "CEL Event Subscriber: %s\n",
- ast_event_get_ie_str(event, AST_EVENT_IE_DESCRIPTION));
+ ast_cli(a->fd, "CEL Event Subscriber: %s\n", backend->name);
+ return 0;
}
static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
unsigned int i;
- struct ast_event_sub *sub;
RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
switch (cmd) {
@@ -506,14 +563,7 @@ static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_
}
ao2_callback(cfg->general->apps, OBJ_NODATA, print_app, a);
-
- if (!(sub = ast_event_subscribe_new(AST_EVENT_SUB, print_cel_sub, a))) {
- return CLI_FAILURE;
- }
- ast_event_sub_append_ie_uint(sub, AST_EVENT_IE_EVENTTYPE, AST_EVENT_CEL);
- ast_event_report_subs(sub);
- ast_event_sub_destroy(sub);
- sub = NULL;
+ ao2_callback(cel_backends, OBJ_MULTIPLE | OBJ_NODATA, event_desc_cb, a);
return CLI_SUCCESS;
}
@@ -668,6 +718,14 @@ struct ast_event *ast_cel_create_event(struct ast_channel_snapshot *snapshot,
AST_EVENT_IE_END);
}
+static int cel_backend_send_cb(void *obj, void *arg, int flags)
+{
+ struct cel_backend *backend = obj;
+
+ backend->callback(arg);
+ return 0;
+}
+
static int cel_report_event(struct ast_channel_snapshot *snapshot,
enum ast_cel_event_type event_type, const char *userdefevname,
struct ast_json *extra, const char *peer2_name)
@@ -711,11 +769,14 @@ static int cel_report_event(struct ast_channel_snapshot *snapshot,
}
ev = ast_cel_create_event(snapshot, event_type, userdefevname, extra, peer_name);
- if (ev && ast_event_queue(ev)) {
- ast_event_destroy(ev);
+ if (!ev) {
return -1;
}
+ /* Distribute event to backends */
+ ao2_callback(cel_backends, OBJ_MULTIPLE | OBJ_NODATA, cel_backend_send_cb, ev);
+ ast_event_destroy(ev);
+
return 0;
}
@@ -1543,6 +1604,11 @@ int ast_cel_engine_init(void)
return -1;
}
+ cel_backends = ao2_container_alloc(BACKEND_BUCKETS, cel_backend_hash, cel_backend_cmp);
+ if (!cel_backends) {
+ return -1;
+ }
+
cel_aggregation_topic = stasis_topic_create("cel_aggregation_topic");
if (!cel_aggregation_topic) {
return -1;
@@ -1702,3 +1768,35 @@ void ast_cel_set_config(struct ast_cel_general_config *config)
ao2_ref(mod_cfg->general, +1);
}
+int ast_cel_backend_unregister(const char *name)
+{
+ RAII_VAR(struct cel_backend *, backend, NULL, ao2_cleanup);
+
+ backend = ao2_find(cel_backends, name, OBJ_KEY | OBJ_UNLINK);
+ if (!backend) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int ast_cel_backend_register(const char *name, ast_cel_backend_cb backend_callback)
+{
+ RAII_VAR(struct cel_backend *, backend, NULL, ao2_cleanup);
+
+ if (ast_strlen_zero(name)) {
+ return -1;
+ }
+
+ backend = ao2_alloc(sizeof(*backend) + 1 + strlen(name), NULL);
+ if (!backend) {
+ return -1;
+ }
+
+ /* safe strcpy */
+ strcpy(backend->name, name);
+ backend->callback = backend_callback;
+ ao2_link(cel_backends, backend);
+
+ return 0;
+}
diff --git a/main/event.c b/main/event.c
index 787f3bc51..0f0406f55 100644
--- a/main/event.c
+++ b/main/event.c
@@ -44,12 +44,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/astobj2.h"
#include "asterisk/cli.h"
-static struct ast_taskprocessor *event_dispatcher;
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);
-static uint16_t event_get_ie_raw_payload_len(const struct ast_event *event, enum ast_event_ie_type ie_type);
-static uint32_t event_get_ie_str_hash(const struct ast_event *event, enum ast_event_ie_type ie_type);
/*!
* \brief An event information element
@@ -112,23 +109,6 @@ struct ast_event_ie_val {
size_t raw_datalen;
};
-/*! \brief Event subscription */
-struct ast_event_sub {
- enum ast_event_type type;
- ast_event_cb_t cb;
- char description[64];
- void *userdata;
- uint32_t uniqueid;
- AST_LIST_HEAD_NOLOCK(, ast_event_ie_val) ie_vals;
- AST_RWDLLIST_ENTRY(ast_event_sub) entry;
-};
-
-static uint32_t sub_uniqueid;
-
-/*! \brief Event subscriptions
- * The event subscribers are indexed by which event they are subscribed to */
-static AST_RWDLLIST_HEAD(ast_event_sub_list, ast_event_sub) ast_event_subs[AST_EVENT_TOTAL];
-
struct ie_map {
enum ast_event_ie_pltype ie_pltype;
const char *name;
@@ -217,513 +197,11 @@ size_t ast_event_get_size(const struct ast_event *event)
return res;
}
-static void ast_event_ie_val_destroy(struct ast_event_ie_val *ie_val)
-{
- switch (ie_val->ie_pltype) {
- case AST_EVENT_IE_PLTYPE_STR:
- ast_free((char *) ie_val->payload.str);
- break;
- case AST_EVENT_IE_PLTYPE_RAW:
- ast_free(ie_val->payload.raw);
- break;
- case AST_EVENT_IE_PLTYPE_UINT:
- case AST_EVENT_IE_PLTYPE_UNKNOWN:
- break;
- }
-
- ast_free(ie_val);
-}
-
/*! \brief Subscription event check list. */
struct ast_ev_check_list {
AST_LIST_HEAD_NOLOCK(, ast_event_ie_val) ie_vals;
};
-/*!
- * \internal
- * \brief Check if a subscription ie_val matches an event.
- *
- * \param sub_ie_val Subscripton IE value to check
- * \param check_ie_vals event list to check against
- *
- * \retval 0 not matched
- * \retval non-zero matched
- */
-static int match_sub_ie_val_to_event(const struct ast_event_ie_val *sub_ie_val, const struct ast_ev_check_list *check_ie_vals)
-{
- const struct ast_event_ie_val *event_ie_val;
- int res = 0;
-
- AST_LIST_TRAVERSE(&check_ie_vals->ie_vals, event_ie_val, entry) {
- if (sub_ie_val->ie_type == event_ie_val->ie_type) {
- break;
- }
- }
- if (!event_ie_val) {
- /* We did not find the event ie the subscriber cares about. */
- return 0;
- }
-
- if (sub_ie_val->ie_pltype != event_ie_val->ie_pltype) {
- /* Payload types do not match. */
- return 0;
- }
-
- switch (sub_ie_val->ie_pltype) {
- case AST_EVENT_IE_PLTYPE_UINT:
- res = (sub_ie_val->payload.uint == event_ie_val->payload.uint);
- break;
- case AST_EVENT_IE_PLTYPE_STR:
- {
- const char *substr = sub_ie_val->payload.str;
- const char *estr = event_ie_val->payload.str;
- res = !strcmp(substr, estr);
- break;
- }
- case AST_EVENT_IE_PLTYPE_RAW:
- res = (sub_ie_val->raw_datalen == event_ie_val->raw_datalen
- && !memcmp(sub_ie_val->payload.raw, event_ie_val->payload.raw,
- sub_ie_val->raw_datalen));
- break;
- case AST_EVENT_IE_PLTYPE_UNKNOWN:
- /*
- * Should never be in a subscription event ie val list and
- * check_ie_vals cannot have this type either.
- */
- break;
- }
-
- return res;
-}
-
-enum ast_event_subscriber_res ast_event_check_subscriber(enum ast_event_type type, ...)
-{
- va_list ap;
- enum ast_event_ie_type ie_type;
- enum ast_event_subscriber_res res = AST_EVENT_SUB_NONE;
- struct ast_event_ie_val *ie_val;
- struct ast_event_sub *sub;
- struct ast_ev_check_list check_ie_vals = {
- .ie_vals = AST_LIST_HEAD_NOLOCK_INIT_VALUE
- };
- const enum ast_event_type event_types[] = { type, AST_EVENT_ALL };
- int i;
- int want_specific_event;/* TRUE if looking for subscribers wanting specific parameters. */
-
- if (type >= AST_EVENT_TOTAL) {
- ast_log(LOG_ERROR, "%u is an invalid type!\n", type);
- return res;
- }
-
- want_specific_event = 0;
- va_start(ap, type);
- for (ie_type = va_arg(ap, enum ast_event_ie_type);
- ie_type != AST_EVENT_IE_END;
- ie_type = va_arg(ap, enum ast_event_ie_type))
- {
- struct ast_event_ie_val *ie_value = ast_alloca(sizeof(*ie_value));
- int insert = 0;
-
- 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_STR:
- ie_value->payload.str = va_arg(ap, const char *);
- insert = 1;
- break;
- case AST_EVENT_IE_PLTYPE_RAW:
- {
- void *data = va_arg(ap, void *);
- size_t datalen = va_arg(ap, size_t);
-
- ie_value->payload.raw = ast_alloca(datalen);
- memcpy(ie_value->payload.raw, data, datalen);
- ie_value->raw_datalen = datalen;
- insert = 1;
- break;
- }
- case AST_EVENT_IE_PLTYPE_UNKNOWN:
- /* Unsupported payload type. */
- break;
- }
-
- if (insert) {
- want_specific_event = 1;
- AST_LIST_INSERT_TAIL(&check_ie_vals.ie_vals, ie_value, entry);
- } else {
- ast_log(LOG_WARNING, "Unsupported PLTYPE(%d)\n", ie_value->ie_pltype);
- }
- }
- va_end(ap);
-
- for (i = 0; i < ARRAY_LEN(event_types); i++) {
- AST_RWDLLIST_RDLOCK(&ast_event_subs[event_types[i]]);
- if (want_specific_event) {
- AST_RWDLLIST_TRAVERSE(&ast_event_subs[event_types[i]], sub, entry) {
- AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
- if (!match_sub_ie_val_to_event(ie_val, &check_ie_vals)) {
- /* The current subscription ie did not match an event ie. */
- break;
- }
- }
- if (!ie_val) {
- /* Everything matched. A subscriber is looking for this event. */
- break;
- }
- }
- } else {
- /* Just looking to see if there are ANY subscribers to the event type. */
- sub = AST_RWLIST_FIRST(&ast_event_subs[event_types[i]]);
- }
- AST_RWDLLIST_UNLOCK(&ast_event_subs[event_types[i]]);
- if (sub) {
- break;
- }
- }
-
- return sub ? AST_EVENT_SUB_EXISTS : AST_EVENT_SUB_NONE;
-}
-
-/*!
- * \internal
- * \brief Check if an ie_val matches an event
- *
- * \param event event to check against
- * \param ie_val IE value to check
- * \param event2 optional event, if specified, the value to compare against will be pulled
- * from this event instead of from the ie_val structure. In this case, only the IE
- * type and payload type will be pulled from ie_val.
- *
- * \retval 0 not matched
- * \retval non-zero matched
- */
-static int match_ie_val(const struct ast_event *event,
- const struct ast_event_ie_val *ie_val, const struct ast_event *event2)
-{
- switch (ie_val->ie_pltype) {
- case AST_EVENT_IE_PLTYPE_UINT:
- {
- uint32_t val = event2 ? ast_event_get_ie_uint(event2, ie_val->ie_type) : ie_val->payload.uint;
-
- return (val == ast_event_get_ie_uint(event, ie_val->ie_type)) ? 1 : 0;
- }
-
- case AST_EVENT_IE_PLTYPE_STR:
- {
- const char *str;
- uint32_t hash;
-
- hash = event2 ? event_get_ie_str_hash(event2, ie_val->ie_type) : ie_val->payload.hash;
- if (hash != event_get_ie_str_hash(event, ie_val->ie_type)) {
- return 0;
- }
-
- str = event2 ? ast_event_get_ie_str(event2, ie_val->ie_type) : ie_val->payload.str;
- if (str) {
- const char *e1str, *e2str;
- e1str = ast_event_get_ie_str(event, ie_val->ie_type);
- e2str = str;
-
- if (!strcmp(e1str, e2str)) {
- return 1;
- }
- }
-
- return 0;
- }
-
- case AST_EVENT_IE_PLTYPE_RAW:
- {
- const void *buf = event2 ? event_get_ie_raw(event2, ie_val->ie_type) : ie_val->payload.raw;
- uint16_t ie_payload_len = event2 ? event_get_ie_raw_payload_len(event2, ie_val->ie_type) : ie_val->raw_datalen;
-
- return (buf
- && ie_payload_len == event_get_ie_raw_payload_len(event, ie_val->ie_type)
- && !memcmp(buf, event_get_ie_raw(event, ie_val->ie_type), ie_payload_len)) ? 1 : 0;
- }
-
- case AST_EVENT_IE_PLTYPE_UNKNOWN:
- return 0;
- }
-
- return 0;
-}
-
-static struct ast_event *gen_sub_event(struct ast_event_sub *sub)
-{
- struct ast_event_ie_val *ie_val;
- struct ast_event *event;
-
- event = ast_event_new(AST_EVENT_SUB,
- AST_EVENT_IE_UNIQUEID, AST_EVENT_IE_PLTYPE_UINT, sub->uniqueid,
- AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, sub->type,
- AST_EVENT_IE_DESCRIPTION, AST_EVENT_IE_PLTYPE_STR, sub->description,
- AST_EVENT_IE_END);
- if (!event)
- return NULL;
-
- AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
- switch (ie_val->ie_pltype) {
- case AST_EVENT_IE_PLTYPE_UNKNOWN:
- break;
- 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_STR:
- ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str);
- break;
- case AST_EVENT_IE_PLTYPE_RAW:
- event_append_ie_raw(&event, ie_val->ie_type, ie_val->payload.raw, ie_val->raw_datalen);
- break;
- }
- if (!event)
- break;
- }
-
- return event;
-}
-
-/*! \brief Send AST_EVENT_SUB events to this subscriber of ... subscriber events */
-void ast_event_report_subs(const struct ast_event_sub *event_sub)
-{
- struct ast_event *event;
- struct ast_event_sub *sub;
- enum ast_event_type event_type = -1;
- struct ast_event_ie_val *ie_val;
-
- if (event_sub->type != AST_EVENT_SUB)
- return;
-
- AST_LIST_TRAVERSE(&event_sub->ie_vals, ie_val, entry) {
- if (ie_val->ie_type == AST_EVENT_IE_EVENTTYPE) {
- event_type = ie_val->payload.uint;
- break;
- }
- }
-
- if (event_type == -1)
- return;
-
- AST_RWDLLIST_RDLOCK(&ast_event_subs[event_type]);
- AST_RWDLLIST_TRAVERSE(&ast_event_subs[event_type], sub, entry) {
- if (event_sub == sub) {
- continue;
- }
-
- event = gen_sub_event(sub);
- if (!event) {
- continue;
- }
-
- event_sub->cb(event, event_sub->userdata);
-
- ast_event_destroy(event);
- }
- AST_RWDLLIST_UNLOCK(&ast_event_subs[event_type]);
-}
-
-struct ast_event_sub *ast_event_subscribe_new(enum ast_event_type type,
- ast_event_cb_t cb, void *userdata)
-{
- struct ast_event_sub *sub;
-
- if (type < 0 || type >= AST_EVENT_TOTAL) {
- ast_log(LOG_ERROR, "%u is an invalid type!\n", type);
- return NULL;
- }
-
- if (!(sub = ast_calloc(1, sizeof(*sub)))) {
- return NULL;
- }
-
- sub->type = type;
- sub->cb = cb;
- sub->userdata = userdata;
- sub->uniqueid = ast_atomic_fetchadd_int((int *) &sub_uniqueid, 1);
-
- return sub;
-}
-
-int ast_event_sub_append_ie_uint(struct ast_event_sub *sub,
- enum ast_event_ie_type ie_type, uint32_t unsigned_int)
-{
- struct ast_event_ie_val *ie_val;
-
- if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
- return -1;
- }
-
- if (!(ie_val = ast_calloc(1, sizeof(*ie_val)))) {
- return -1;
- }
-
- ie_val->ie_type = ie_type;
- ie_val->payload.uint = unsigned_int;
- ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_UINT;
-
- AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);
-
- return 0;
-}
-
-int ast_event_sub_append_ie_str(struct ast_event_sub *sub,
- enum ast_event_ie_type ie_type, const char *str)
-{
- struct ast_event_ie_val *ie_val;
-
- if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
- return -1;
- }
-
- if (!(ie_val = ast_calloc(1, sizeof(*ie_val)))) {
- return -1;
- }
-
- ie_val->ie_type = ie_type;
- ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_STR;
-
- if (!(ie_val->payload.str = ast_strdup(str))) {
- ast_free(ie_val);
- return -1;
- }
-
- ie_val->payload.hash = ast_str_hash(str);
-
- AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);
-
- return 0;
-}
-
-int ast_event_sub_append_ie_raw(struct ast_event_sub *sub,
- enum ast_event_ie_type ie_type, void *data, size_t raw_datalen)
-{
- struct ast_event_ie_val *ie_val;
-
- if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
- return -1;
- }
-
- if (!(ie_val = ast_calloc(1, sizeof(*ie_val)))) {
- return -1;
- }
-
- ie_val->ie_type = ie_type;
- ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_RAW;
- ie_val->raw_datalen = raw_datalen;
-
- if (!(ie_val->payload.raw = ast_malloc(raw_datalen))) {
- ast_free(ie_val);
- return -1;
- }
-
- memcpy(ie_val->payload.raw, data, raw_datalen);
-
- AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);
-
- return 0;
-}
-
-int ast_event_sub_activate(struct ast_event_sub *sub)
-{
- if (ast_event_check_subscriber(AST_EVENT_SUB,
- AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, sub->type,
- AST_EVENT_IE_END) != AST_EVENT_SUB_NONE) {
- struct ast_event *event;
-
- event = gen_sub_event(sub);
- if (event && ast_event_queue(event)) {
- ast_event_destroy(event);
- }
- }
-
- AST_RWDLLIST_WRLOCK(&ast_event_subs[sub->type]);
- AST_RWDLLIST_INSERT_TAIL(&ast_event_subs[sub->type], sub, entry);
- AST_RWDLLIST_UNLOCK(&ast_event_subs[sub->type]);
-
- return 0;
-}
-
-struct ast_event_sub *ast_event_subscribe(enum ast_event_type type, ast_event_cb_t cb,
- const char *description, void *userdata, ...)
-{
- va_list ap;
- enum ast_event_ie_type ie_type;
- struct ast_event_sub *sub;
-
- if (!(sub = ast_event_subscribe_new(type, cb, userdata))) {
- return NULL;
- }
-
- ast_copy_string(sub->description, description, sizeof(sub->description));
-
- va_start(ap, userdata);
- for (ie_type = va_arg(ap, enum ast_event_ie_type);
- ie_type != AST_EVENT_IE_END;
- ie_type = va_arg(ap, enum ast_event_ie_type))
- {
- enum ast_event_ie_pltype ie_pltype;
-
- ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
-
- switch (ie_pltype) {
- case AST_EVENT_IE_PLTYPE_UNKNOWN:
- break;
- case AST_EVENT_IE_PLTYPE_UINT:
- {
- uint32_t unsigned_int = va_arg(ap, uint32_t);
- ast_event_sub_append_ie_uint(sub, ie_type, unsigned_int);
- break;
- }
- case AST_EVENT_IE_PLTYPE_STR:
- {
- const char *str = va_arg(ap, const char *);
- ast_event_sub_append_ie_str(sub, ie_type, str);
- break;
- }
- case AST_EVENT_IE_PLTYPE_RAW:
- {
- void *data = va_arg(ap, void *);
- size_t data_len = va_arg(ap, size_t);
- ast_event_sub_append_ie_raw(sub, ie_type, data, data_len);
- break;
- }
- }
- }
- va_end(ap);
-
- ast_event_sub_activate(sub);
-
- return sub;
-}
-
-void ast_event_sub_destroy(struct ast_event_sub *sub)
-{
- struct ast_event_ie_val *ie_val;
-
- while ((ie_val = AST_LIST_REMOVE_HEAD(&sub->ie_vals, entry))) {
- ast_event_ie_val_destroy(ie_val);
- }
-
- ast_free(sub);
-}
-
-struct ast_event_sub *ast_event_unsubscribe(struct ast_event_sub *sub)
-{
-
- AST_RWDLLIST_WRLOCK(&ast_event_subs[sub->type]);
- AST_DLLIST_REMOVE(&ast_event_subs[sub->type], sub, entry);
- AST_RWDLLIST_UNLOCK(&ast_event_subs[sub->type]);
-
- ast_event_sub_destroy(sub);
-
- return NULL;
-}
-
int ast_event_iterator_init(struct ast_event_iterator *iterator, const struct ast_event *event)
{
int res = 0;
@@ -770,11 +248,6 @@ static void *event_iterator_get_ie_raw(struct ast_event_iterator *iterator)
return iterator->ie->ie_payload;
}
-static uint16_t event_iterator_get_ie_raw_payload_len(struct ast_event_iterator *iterator)
-{
- return ntohs(iterator->ie->ie_payload_len);
-}
-
enum ast_event_type ast_event_get_type(const struct ast_event *event)
{
return ntohs(event->type);
@@ -789,15 +262,6 @@ uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_
return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0;
}
-static uint32_t event_get_ie_str_hash(const struct ast_event *event, enum ast_event_ie_type ie_type)
-{
- const struct ast_event_ie_str_payload *str_payload;
-
- str_payload = event_get_ie_raw(event, ie_type);
-
- return str_payload ? str_payload->hash : 0;
-}
-
const char *ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type)
{
const struct ast_event_ie_str_payload *str_payload;
@@ -821,20 +285,6 @@ static const void *event_get_ie_raw(const struct ast_event *event, enum ast_even
return NULL;
}
-static uint16_t 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)
{
@@ -974,111 +424,3 @@ void ast_event_destroy(struct ast_event *event)
{
ast_free(event);
}
-
-static int handle_event(void *data)
-{
- struct ast_event *event = data;
- struct ast_event_sub *sub;
- const enum ast_event_type event_types[] = {
- ntohs(event->type),
- AST_EVENT_ALL
- };
- int i;
-
- for (i = 0; i < ARRAY_LEN(event_types); i++) {
- AST_RWDLLIST_RDLOCK(&ast_event_subs[event_types[i]]);
- AST_RWDLLIST_TRAVERSE(&ast_event_subs[event_types[i]], sub, entry) {
- struct ast_event_ie_val *ie_val;
-
- AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
- if (!match_ie_val(event, ie_val, NULL)) {
- /* The current subscription ie did not match an event ie. */
- break;
- }
- }
- if (ie_val) {
- /* The event did not match this subscription. */
- continue;
- }
- sub->cb(event, sub->userdata);
- }
- AST_RWDLLIST_UNLOCK(&ast_event_subs[event_types[i]]);
- }
-
- ast_event_destroy(event);
-
- return 0;
-}
-
-int ast_event_queue(struct ast_event *event)
-{
- uint16_t host_event_type;
- int res;
-
- host_event_type = ntohs(event->type);
-
- /* Invalid type */
- if (host_event_type >= AST_EVENT_TOTAL) {
- ast_log(LOG_WARNING, "Someone tried to queue an event of invalid "
- "type '%d'!\n", host_event_type);
- return -1;
- }
-
- /* If nobody has subscribed to this event type, throw it away now */
- if (ast_event_check_subscriber(host_event_type, AST_EVENT_IE_END)
- == AST_EVENT_SUB_NONE) {
- ast_event_destroy(event);
- return 0;
- }
-
- res = ast_taskprocessor_push(event_dispatcher, handle_event, event);
- if (res) {
- ast_event_destroy(event);
- }
- return res;
-}
-
-/*! \internal \brief Clean up resources on Asterisk shutdown */
-static void event_shutdown(void)
-{
- struct ast_event_sub *sub;
- int i;
-
- if (event_dispatcher) {
- event_dispatcher = ast_taskprocessor_unreference(event_dispatcher);
- }
-
- /* Remove any remaining subscriptions. Note that we can't just call
- * unsubscribe, as it will attempt to lock the subscription list
- * as well */
- for (i = 0; i < AST_EVENT_TOTAL; i++) {
- AST_RWDLLIST_WRLOCK(&ast_event_subs[i]);
- while ((sub = AST_RWDLLIST_REMOVE_HEAD(&ast_event_subs[i], entry))) {
- ast_event_sub_destroy(sub);
- }
- AST_RWDLLIST_UNLOCK(&ast_event_subs[i]);
- AST_RWDLLIST_HEAD_DESTROY(&ast_event_subs[i]);
- }
-}
-
-int ast_event_init(void)
-{
- int i;
-
- for (i = 0; i < AST_EVENT_TOTAL; i++) {
- AST_RWDLLIST_HEAD_INIT(&ast_event_subs[i]);
- }
-
- if (!(event_dispatcher = ast_taskprocessor_get("core_event_dispatcher", 0))) {
- goto event_init_cleanup;
- }
-
- ast_register_atexit(event_shutdown);
-
- return 0;
-
-event_init_cleanup:
- event_shutdown();
- return -1;
-}
-