summaryrefslogtreecommitdiff
path: root/main/cel.c
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/cel.c
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/cel.c')
-rw-r--r--main/cel.c132
1 files changed, 115 insertions, 17 deletions
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;
+}