[asterisk-commits] irroot: branch irroot/t38gateway-1.8 r321992 - in /team/irroot/t38gateway-1.8...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Jun 4 06:58:01 CDT 2011
Author: irroot
Date: Sat Jun 4 06:54:05 2011
New Revision: 321992
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=321992
Log:
Fixup Merge
Modified:
team/irroot/t38gateway-1.8/ (props changed)
team/irroot/t38gateway-1.8/cdr/cdr_radius.c
team/irroot/t38gateway-1.8/cel/cel_odbc.c (props changed)
team/irroot/t38gateway-1.8/cel/cel_radius.c
team/irroot/t38gateway-1.8/channels/chan_iax2.c
team/irroot/t38gateway-1.8/configs/cel_odbc.conf.sample (props changed)
team/irroot/t38gateway-1.8/configure
team/irroot/t38gateway-1.8/contrib/realtime/mysql/iaxfriends.sql (props changed)
team/irroot/t38gateway-1.8/contrib/realtime/mysql/meetme.sql (props changed)
team/irroot/t38gateway-1.8/contrib/realtime/mysql/sipfriends.sql (props changed)
team/irroot/t38gateway-1.8/contrib/realtime/mysql/voicemail.sql (props changed)
team/irroot/t38gateway-1.8/contrib/realtime/postgresql/realtime.sql (props changed)
team/irroot/t38gateway-1.8/include/asterisk/event.h
team/irroot/t38gateway-1.8/main/ccss.c
team/irroot/t38gateway-1.8/main/event.c
team/irroot/t38gateway-1.8/sounds/Makefile (props changed)
team/irroot/t38gateway-1.8/tests/test_event.c
Propchange: team/irroot/t38gateway-1.8/
------------------------------------------------------------------------------
automerge = *
Propchange: team/irroot/t38gateway-1.8/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Jun 4 06:54:05 2011
@@ -1,4 +1,1 @@
-/be/branches/C.3:256426
-/branches/1.8:318979-321755
-/team/irroot/distrotech-customers-1.8:319062-319063
-/team/irroot/t38gateway-trunk:318977-319016,319067,319070-319071,320879
+/branches/1.8:318979-321991
Modified: team/irroot/t38gateway-1.8/cdr/cdr_radius.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/t38gateway-1.8/cdr/cdr_radius.c?view=diff&rev=321992&r1=321991&r2=321992
==============================================================================
--- team/irroot/t38gateway-1.8/cdr/cdr_radius.c (original)
+++ team/irroot/t38gateway-1.8/cdr/cdr_radius.c Sat Jun 4 06:54:05 2011
@@ -224,6 +224,10 @@
static int unload_module(void)
{
ast_cdr_unregister(name);
+ if (rh) {
+ rc_destroy(rh);
+ rh = NULL;
+ }
return 0;
}
@@ -243,8 +247,17 @@
} else
return AST_MODULE_LOAD_DECLINE;
- /* start logging */
- rc_openlog("asterisk");
+ /*
+ * start logging
+ *
+ * NOTE: Yes this causes a slight memory leak if the module is
+ * unloaded. However, it is better than a crash if cdr_radius
+ * and cel_radius are both loaded.
+ */
+ tmp = ast_strdup("asterisk");
+ if (tmp) {
+ rc_openlog((char *) tmp);
+ }
/* read radiusclient-ng config file */
if (!(rh = rc_read_config(radiuscfg))) {
@@ -255,11 +268,18 @@
/* read radiusclient-ng dictionaries */
if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary"))) {
ast_log(LOG_NOTICE, "Cannot load radiusclient-ng dictionary file.\n");
- return AST_MODULE_LOAD_DECLINE;
- }
-
- ast_cdr_register(name, desc, radius_log);
- return AST_MODULE_LOAD_SUCCESS;
+ rc_destroy(rh);
+ rh = NULL;
+ return AST_MODULE_LOAD_DECLINE;
+ }
+
+ if (ast_cdr_register(name, desc, radius_log)) {
+ rc_destroy(rh);
+ rh = NULL;
+ return AST_MODULE_LOAD_DECLINE;
+ } else {
+ return AST_MODULE_LOAD_SUCCESS;
+ }
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "RADIUS CDR Backend",
Propchange: team/irroot/t38gateway-1.8/cel/cel_odbc.c
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Jun 4 06:54:05 2011
@@ -1,5 +1,5 @@
/be/branches/C.3/cel/cel_adaptive_odbc.c:256426
-/branches/1.8/cel/cel_odbc.c:318979-321755
+/branches/1.8/cel/cel_odbc.c:318979-321991
/team/irroot/distrotech-customers-1.8/cel/cel_odbc.c:319062-319063,321553
/team/irroot/distrotech-customers-trunk/cel/cel_odbc.c:321552
/team/irroot/t38gateway-trunk/cel/cel_odbc.c:318977-319016,319067,319070-319071,320879-321512,321514-321541
Modified: team/irroot/t38gateway-1.8/cel/cel_radius.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/t38gateway-1.8/cel/cel_radius.c?view=diff&rev=321992&r1=321991&r2=321992
==============================================================================
--- team/irroot/t38gateway-1.8/cel/cel_radius.c (original)
+++ team/irroot/t38gateway-1.8/cel/cel_radius.c Sat Jun 4 06:54:05 2011
@@ -208,6 +208,10 @@
if (event_sub) {
event_sub = ast_event_unsubscribe(event_sub);
}
+ if (rh) {
+ rc_destroy(rh);
+ rh = NULL;
+ }
return AST_MODULE_LOAD_SUCCESS;
}
@@ -227,8 +231,17 @@
return AST_MODULE_LOAD_DECLINE;
}
- /* start logging */
- rc_openlog("asterisk");
+ /*
+ * start logging
+ *
+ * NOTE: Yes this causes a slight memory leak if the module is
+ * unloaded. However, it is better than a crash if cdr_radius
+ * and cel_radius are both loaded.
+ */
+ tmp = ast_strdup("asterisk");
+ if (tmp) {
+ rc_openlog((char *) tmp);
+ }
/* read radiusclient-ng config file */
if (!(rh = rc_read_config(radiuscfg))) {
@@ -239,12 +252,15 @@
/* read radiusclient-ng dictionaries */
if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary"))) {
ast_log(LOG_NOTICE, "Cannot load radiusclient-ng dictionary file.\n");
+ rc_destroy(rh);
+ rh = NULL;
return AST_MODULE_LOAD_DECLINE;
}
event_sub = ast_event_subscribe(AST_EVENT_CEL, radius_log, "CEL Radius Logging", NULL, AST_EVENT_IE_END);
-
if (!event_sub) {
+ rc_destroy(rh);
+ rh = NULL;
return AST_MODULE_LOAD_DECLINE;
} else {
return AST_MODULE_LOAD_SUCCESS;
Modified: team/irroot/t38gateway-1.8/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/t38gateway-1.8/channels/chan_iax2.c?view=diff&rev=321992&r1=321991&r2=321992
==============================================================================
--- team/irroot/t38gateway-1.8/channels/chan_iax2.c (original)
+++ team/irroot/t38gateway-1.8/channels/chan_iax2.c Sat Jun 4 06:54:05 2011
@@ -1282,10 +1282,7 @@
{
if (!network_change_event_subscription) {
network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE,
- network_change_event_cb,
- "SIP Network Change ",
- NULL,
- AST_EVENT_IE_END);
+ network_change_event_cb, "IAX2 Network Change", NULL, AST_EVENT_IE_END);
}
}
Propchange: team/irroot/t38gateway-1.8/configs/cel_odbc.conf.sample
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Jun 4 06:54:05 2011
@@ -1,5 +1,5 @@
/be/branches/C.3/configs/cel_adaptive_odbc.conf.sample:256426
-/branches/1.8/configs/cel_odbc.conf.sample:318979-321755
+/branches/1.8/configs/cel_odbc.conf.sample:318979-321991
/team/irroot/distrotech-customers-1.8/configs/cel_odbc.conf.sample:319062-319063,321553
/team/irroot/distrotech-customers-trunk/configs/cel_odbc.conf.sample:321552
/team/irroot/t38gateway-trunk/configs/cel_odbc.conf.sample:318977-319016,319067,319070-319071,320879-321512,321514-321541
Propchange: team/irroot/t38gateway-1.8/contrib/realtime/mysql/iaxfriends.sql
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Jun 4 06:54:05 2011
@@ -1,4 +1,4 @@
-/branches/1.8/contrib/realtime/mysql/iaxfriends.sql:318979-321755
+/branches/1.8/contrib/realtime/mysql/iaxfriends.sql:318979-321991
/team/irroot/distrotech-customers-1.8/contrib/realtime/mysql/iaxfriends.sql:319062-319063,321553
/team/irroot/distrotech-customers-trunk/contrib/realtime/mysql/iaxfriends.sql:321552
/team/irroot/t38gateway-trunk/contrib/realtime/mysql/iaxfriends.sql:318977-319016,319067,319070-319071,320879
Propchange: team/irroot/t38gateway-1.8/contrib/realtime/mysql/meetme.sql
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Jun 4 06:54:05 2011
@@ -1,4 +1,4 @@
-/branches/1.8/contrib/realtime/mysql/meetme.sql:318979-321755
+/branches/1.8/contrib/realtime/mysql/meetme.sql:318979-321991
/team/irroot/distrotech-customers-1.8/contrib/realtime/mysql/meetme.sql:319062-319063,321553
/team/irroot/distrotech-customers-trunk/contrib/realtime/mysql/meetme.sql:321552
/team/irroot/t38gateway-trunk/contrib/realtime/mysql/meetme.sql:318977-319016,319067,319070-319071,320879
Propchange: team/irroot/t38gateway-1.8/contrib/realtime/mysql/sipfriends.sql
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Jun 4 06:54:05 2011
@@ -1,4 +1,4 @@
-/branches/1.8/contrib/realtime/mysql/sipfriends.sql:318979-321755
+/branches/1.8/contrib/realtime/mysql/sipfriends.sql:318979-321991
/team/irroot/distrotech-customers-1.8/contrib/realtime/mysql/sipfriends.sql:319062-319063,321553
/team/irroot/distrotech-customers-trunk/contrib/realtime/mysql/sipfriends.sql:321552
/team/irroot/t38gateway-trunk/contrib/realtime/mysql/sipfriends.sql:318977-319016,319067,319070-319071,320879
Propchange: team/irroot/t38gateway-1.8/contrib/realtime/mysql/voicemail.sql
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Jun 4 06:54:05 2011
@@ -1,4 +1,4 @@
-/branches/1.8/contrib/realtime/mysql/voicemail.sql:318979-321755
+/branches/1.8/contrib/realtime/mysql/voicemail.sql:318979-321991
/team/irroot/distrotech-customers-1.8/contrib/realtime/mysql/voicemail.sql:319062-319063,321553
/team/irroot/distrotech-customers-trunk/contrib/realtime/mysql/voicemail.sql:321552
/team/irroot/t38gateway-trunk/contrib/realtime/mysql/voicemail.sql:318977-319016,319067,319070-319071,320879
Propchange: team/irroot/t38gateway-1.8/contrib/realtime/postgresql/realtime.sql
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Jun 4 06:54:05 2011
@@ -1,4 +1,4 @@
-/branches/1.8/contrib/realtime/postgresql/realtime.sql:318979-321755
+/branches/1.8/contrib/realtime/postgresql/realtime.sql:318979-321991
/team/irroot/distrotech-customers-1.8/contrib/realtime/postgresql/realtime.sql:319062-319063,321553
/team/irroot/distrotech-customers-trunk/contrib/realtime/postgresql/realtime.sql:321552
/team/irroot/t38gateway-trunk/contrib/realtime/postgresql/realtime.sql:318977-319016,319067,319070-319071,320879
Modified: team/irroot/t38gateway-1.8/include/asterisk/event.h
URL: http://svnview.digium.com/svn/asterisk/team/irroot/t38gateway-1.8/include/asterisk/event.h?view=diff&rev=321992&r1=321991&r2=321992
==============================================================================
--- team/irroot/t38gateway-1.8/include/asterisk/event.h (original)
+++ team/irroot/t38gateway-1.8/include/asterisk/event.h Sat Jun 4 06:54:05 2011
@@ -114,7 +114,7 @@
* \note A NULL description will cause this function to crash, so watch out!
*/
struct ast_event_sub *ast_event_subscribe(enum ast_event_type event_type,
- ast_event_cb_t cb, char *description, void *userdata, ...);
+ ast_event_cb_t cb, const char *description, void *userdata, ...);
/*!
* \brief Allocate a subscription, but do not activate it
@@ -397,8 +397,7 @@
* The event API already knows which events can be cached and how to cache them.
*
* \retval 0 success
- * \retval non-zero failure. If failure is returned, the event must be destroyed
- * by the caller of this function.
+ * \retval non-zero failure.
*/
int ast_event_queue_and_cache(struct ast_event *event);
Modified: team/irroot/t38gateway-1.8/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/t38gateway-1.8/main/ccss.c?view=diff&rev=321992&r1=321991&r2=321992
==============================================================================
--- team/irroot/t38gateway-1.8/main/ccss.c (original)
+++ team/irroot/t38gateway-1.8/main/ccss.c Sat Jun 4 06:54:05 2011
@@ -1135,9 +1135,11 @@
return NULL;
}
- if (!(generic_list->sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE, generic_monitor_devstate_cb,
- "Requesting CC", NULL, AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR,
- monitor->interface->device_name, AST_EVENT_IE_END))) {
+ if (!(generic_list->sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE,
+ generic_monitor_devstate_cb, "Requesting CC", NULL,
+ AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, monitor->interface->device_name,
+ AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_EXISTS,
+ AST_EVENT_IE_END))) {
cc_unref(generic_list, "Failed to subscribe to device state");
return NULL;
}
@@ -2523,10 +2525,11 @@
ast_str_set(&str, 0, "Agent monitoring %s device state since it is busy\n",
agent->device_name);
- if (!(generic_pvt->sub = ast_event_subscribe(
- AST_EVENT_DEVICE_STATE, generic_agent_devstate_cb, ast_str_buffer(str), agent,
- AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, agent->device_name,
- AST_EVENT_IE_END))) {
+ if (!(generic_pvt->sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE,
+ generic_agent_devstate_cb, ast_str_buffer(str), agent,
+ AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, agent->device_name,
+ AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_EXISTS,
+ AST_EVENT_IE_END))) {
return -1;
}
return 0;
Modified: team/irroot/t38gateway-1.8/main/event.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/t38gateway-1.8/main/event.c?view=diff&rev=321992&r1=321991&r2=321992
==============================================================================
--- team/irroot/t38gateway-1.8/main/event.c (original)
+++ team/irroot/t38gateway-1.8/main/event.c Sat Jun 4 06:54:05 2011
@@ -194,6 +194,7 @@
* \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",
@@ -359,53 +360,72 @@
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 an ie_val matches a subscription
- *
- * \param sub subscription to check against
- * \param ie_val IE value to check
+ * \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_ie_val_to_sub(const struct ast_event_sub *sub, const struct ast_event_ie_val *ie_val)
-{
- const struct ast_event_ie_val *sub_ie_val;
- int res = 1;
-
- AST_LIST_TRAVERSE(&sub->ie_vals, sub_ie_val, entry) {
- if (sub_ie_val->ie_type == ie_val->ie_type) {
- break;
- }
- }
-
- if (!sub_ie_val) {
- /* This subscriber doesn't care about this IE, so consider
- * it matched. */
- return 1;
- }
-
- switch (ie_val->ie_pltype) {
+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 (event_ie_val->ie_type == sub_ie_val->ie_type) {
+ break;
+ }
+ }
+ if (!event_ie_val) {
+ /* The did not find the event ie the subscriber cares about. */
+ return 0;
+ }
+
+ if (sub_ie_val->ie_pltype != event_ie_val->ie_pltype) {
+ if (sub_ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_EXISTS) {
+ /* The subscription only cares that this ie exists. */
+ return 1;
+ }
+ /* Payload types do not match. */
+ return 0;
+ }
+
+ switch (sub_ie_val->ie_pltype) {
case AST_EVENT_IE_PLTYPE_UINT:
- res = (ie_val->payload.uint != sub_ie_val->payload.uint);
+ res = (sub_ie_val->payload.uint == event_ie_val->payload.uint);
break;
case AST_EVENT_IE_PLTYPE_BITFLAGS:
/*
* If the subscriber has requested *any* of the bitflags we are providing,
* then it's a match.
*/
- res = !(ie_val->payload.uint & sub_ie_val->payload.uint);
+ res = (sub_ie_val->payload.uint & event_ie_val->payload.uint);
break;
case AST_EVENT_IE_PLTYPE_STR:
- res = strcmp(ie_val->payload.str, sub_ie_val->payload.str);
+ res = !strcmp(sub_ie_val->payload.str, event_ie_val->payload.str);
break;
case AST_EVENT_IE_PLTYPE_RAW:
- res = memcmp(ie_val->payload.raw,
- sub_ie_val->payload.raw, ie_val->raw_datalen);
+ 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_EXISTS:
+ /* Should never get here since check_ie_vals cannot have this type. */
+ 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;
}
@@ -419,7 +439,9 @@
enum ast_event_subscriber_res res = AST_EVENT_SUB_NONE;
struct ast_event_ie_val *ie_val;
struct ast_event_sub *sub;
- AST_LIST_HEAD_NOLOCK_STATIC(ie_vals, ast_event_ie_val);
+ 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;
@@ -434,19 +456,740 @@
ie_type = va_arg(ap, enum ast_event_ie_type))
{
struct ast_event_ie_val *ie_value = alloca(sizeof(*ie_value));
- int insert = 1;
+ 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_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;
+ 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 = alloca(datalen);
+ memcpy(ie_value->payload.raw, data, datalen);
+ ie_value->raw_datalen = datalen;
+ insert = 1;
+ break;
+ }
+ case AST_EVENT_IE_PLTYPE_UNKNOWN:
+ case AST_EVENT_IE_PLTYPE_EXISTS:
+ /* Unsupported payload type. */
+ break;
+ }
+
+ if (insert) {
+ 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]]);
+ 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;
+ }
+ }
+ 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_BITFLAGS:
+ {
+ uint32_t flags = event2 ? ast_event_get_ie_uint(event2, ie_val->ie_type) : ie_val->payload.uint;
+
+ /*
+ * If the subscriber has requested *any* of the bitflags that this event provides,
+ * then it's a match.
+ */
+ return (flags & ast_event_get_ie_bitflags(event, ie_val->ie_type)) ? 1 : 0;
+ }
+
+ case AST_EVENT_IE_PLTYPE_STR:
+ {
+ const char *str;
+ uint32_t hash;
+
+ hash = event2 ? ast_event_get_ie_str_hash(event2, ie_val->ie_type) : ie_val->payload.hash;
+ if (hash != ast_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 && !strcmp(str, ast_event_get_ie_str(event, ie_val->ie_type))) {
+ return 1;
+ }
+
+ return 0;
+ }
+
+ case AST_EVENT_IE_PLTYPE_RAW:
+ {
+ const void *buf = event2 ? ast_event_get_ie_raw(event2, ie_val->ie_type) : ie_val->payload.raw;
+ uint16_t ie_payload_len = event2 ? ast_event_get_ie_raw_payload_len(event2, ie_val->ie_type) : ie_val->raw_datalen;
+
+ return (buf
+ && ie_payload_len == ast_event_get_ie_raw_payload_len(event, ie_val->ie_type)
+ && !memcmp(buf, ast_event_get_ie_raw(event, ie_val->ie_type), ie_payload_len)) ? 1 : 0;
+ }
+
+ case AST_EVENT_IE_PLTYPE_EXISTS:
+ {
+ return ast_event_get_ie_raw(event, ie_val->ie_type) ? 1 : 0;
+ }
+
+ case AST_EVENT_IE_PLTYPE_UNKNOWN:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int dump_cache_cb(void *obj, void *arg, int flags)
+{
+ const struct ast_event_ref *event_ref = obj;
+ const struct ast_event *event = event_ref->event;
+ const struct ast_event_sub *event_sub = arg;
+ struct ast_event_ie_val *ie_val = NULL;
+
+ AST_LIST_TRAVERSE(&event_sub->ie_vals, ie_val, entry) {
+ if (!match_ie_val(event, ie_val, NULL)) {
+ break;
+ }
+ }
+
+ if (!ie_val) {
+ /* All parameters were matched on this cache entry, so dump it */
+ event_sub->cb(event, event_sub->userdata);
+ }
+
+ return 0;
+}
+
+/*! \brief Dump the event cache for the subscribed event type */
+void ast_event_dump_cache(const struct ast_event_sub *event_sub)
+{
+ ao2_callback(ast_event_cache[event_sub->type].container, OBJ_NODATA,
+ dump_cache_cb, (void *) event_sub);
+}
+
+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_EXISTS:
+ ast_event_append_ie_uint(&event, AST_EVENT_IE_EXISTS, ie_val->ie_type);
+ 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_BITFLAGS:
+ ast_event_append_ie_bitflags(&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:
+ ast_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_bitflags(struct ast_event_sub *sub,
+ enum ast_event_ie_type ie_type, uint32_t flags)
+{
+ 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 = flags;
+ ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_BITFLAGS;
+
+ AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);
+
+ return 0;
+}
+
+int ast_event_sub_append_ie_exists(struct ast_event_sub *sub,
+ enum ast_event_ie_type ie_type)
+{
+ 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_EXISTS;
+
+ 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_BITFLAGS:
+ {
+ uint32_t unsigned_int = va_arg(ap, uint32_t);
+ ast_event_sub_append_ie_bitflags(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;
+ }
+ case AST_EVENT_IE_PLTYPE_EXISTS:
+ ast_event_sub_append_ie_exists(sub, ie_type);
+ 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);
+}
+
+const char *ast_event_subscriber_get_description(struct ast_event_sub *sub)
+{
+ return sub ? sub->description : NULL;
+}
+
+struct ast_event_sub *ast_event_unsubscribe(struct ast_event_sub *sub)
+{
+ struct ast_event *event;
+
+ 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]);
+
+ if (ast_event_check_subscriber(AST_EVENT_UNSUB,
+ AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, sub->type,
+ AST_EVENT_IE_END) != AST_EVENT_SUB_NONE) {
+
+ event = ast_event_new(AST_EVENT_UNSUB,
+ 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 && ast_event_queue(event)) {
+ ast_event_destroy(event);
+ }
+ }
+
+ 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;
+
+ iterator->event_len = ast_event_get_size(event);
+ iterator->event = event;
+ if (iterator->event_len >= sizeof(*event) + sizeof(struct ast_event_ie)) {
+ iterator->ie = (struct ast_event_ie *) ( ((char *) event) + sizeof(*event) );
+ } else {
+ iterator->ie = NULL;
+ res = -1;
+ }
+
+ return res;
+}
+
+int ast_event_iterator_next(struct ast_event_iterator *iterator)
+{
+ iterator->ie = (struct ast_event_ie *) ( ((char *) iterator->ie) + sizeof(*iterator->ie) + ntohs(iterator->ie->ie_payload_len));
+ return ((iterator->event_len <= (((char *) iterator->ie) - ((char *) iterator->event))) ? -1 : 0);
+}
+
+enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator *iterator)
+{
+ return ntohs(iterator->ie->ie_type);
+}
+
+uint32_t ast_event_iterator_get_ie_uint(struct ast_event_iterator *iterator)
+{
+ return ntohl(get_unaligned_uint32(iterator->ie->ie_payload));
+}
+
+uint32_t ast_event_iterator_get_ie_bitflags(struct ast_event_iterator *iterator)
+{
+ return ntohl(get_unaligned_uint32(iterator->ie->ie_payload));
+}
+
+const char *ast_event_iterator_get_ie_str(struct ast_event_iterator *iterator)
+{
+ const struct ast_event_ie_str_payload *str_payload;
+
+ str_payload = (struct ast_event_ie_str_payload *) iterator->ie->ie_payload;
+
+ return str_payload ? str_payload->str : NULL;
+}
+
+void *ast_event_iterator_get_ie_raw(struct ast_event_iterator *iterator)
+{
+ return iterator->ie->ie_payload;
+}
+
+uint16_t ast_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);
+}
+
+uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
+{
+ const uint32_t *ie_val;
+
+ ie_val = ast_event_get_ie_raw(event, ie_type);
+
+ return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0;
+}
+
+uint32_t ast_event_get_ie_bitflags(const struct ast_event *event, enum ast_event_ie_type ie_type)
+{
+ const uint32_t *ie_val;
+
+ ie_val = ast_event_get_ie_raw(event, ie_type);
+
+ return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0;
+}
+
+uint32_t ast_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 = ast_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;
+
+ str_payload = ast_event_get_ie_raw(event, ie_type);
+
+ return str_payload ? str_payload->str : NULL;
+}
+
+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;
+
+ 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 ast_event_iterator_get_ie_raw(&iterator);
+ }
+ }
+
+ return NULL;
+}
+
+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 ast_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)
+{
+ struct ast_event_ie_str_payload *str_payload;
+ size_t payload_len;
+
+ payload_len = sizeof(*str_payload) + strlen(str);
+ str_payload = alloca(payload_len);
+
+ strcpy(str_payload->str, str);
+ str_payload->hash = ast_str_hash(str);
+
+ 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 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));
+}
+
+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;
+ unsigned int extra_len;
+ uint16_t event_len;
+
+ event_len = ntohs((*event)->event_len);
+ extra_len = sizeof(*ie) + data_len;
+
+ if (!(*event = ast_realloc(*event, event_len + extra_len))) {
+ return -1;
+ }
+
+ ie = (struct ast_event_ie *) ( ((char *) *event) + event_len );
+ ie->ie_type = htons(ie_type);
+ ie->ie_payload_len = htons(data_len);
+ memcpy(ie->ie_payload, data, data_len);
+
+ (*event)->event_len = htons(event_len + extra_len);
+
+ return 0;
+}
+
+struct ast_event *ast_event_new(enum ast_event_type type, ...)
+{
+ va_list ap;
+ struct ast_event *event;
+ enum ast_event_ie_type ie_type;
+ struct ast_event_ie_val *ie_val;
+ int has_ie = 0;
+ AST_LIST_HEAD_NOLOCK_STATIC(ie_vals, ast_event_ie_val);
+
+ /* Invalid type */
+ if (type >= AST_EVENT_TOTAL) {
+ ast_log(LOG_WARNING, "Someone tried to create an event of invalid "
+ "type '%d'!\n", type);
+ return NULL;
+ }
+
+ 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 = 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_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;
break;
case AST_EVENT_IE_PLTYPE_RAW:
{
@@ -455,722 +1198,10 @@
ie_value->payload.raw = alloca(datalen);
memcpy(ie_value->payload.raw, data, datalen);
ie_value->raw_datalen = datalen;
+ insert = 1;
break;
}
case AST_EVENT_IE_PLTYPE_UNKNOWN:
- insert = 0;
- case AST_EVENT_IE_PLTYPE_EXISTS:
- break;
- }
-
- if (insert) {
- AST_LIST_INSERT_TAIL(&ie_vals, ie_value, entry);
- }
- }
- va_end(ap);
-
- 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) {
- AST_LIST_TRAVERSE(&ie_vals, ie_val, entry) {
- if (match_ie_val_to_sub(sub, ie_val)) {
- break;
- }
- }
-
- if (!ie_val) {
- /* Everything matched. */
- break;
- }
- }
- 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_BITFLAGS:
- {
- uint32_t flags = event2 ? ast_event_get_ie_uint(event2, ie_val->ie_type) : ie_val->payload.uint;
-
- /*
- * If the subscriber has requested *any* of the bitflags that this event provides,
- * then it's a match.
- */
- return (flags & ast_event_get_ie_bitflags(event, ie_val->ie_type)) ? 1 : 0;
- }
-
- case AST_EVENT_IE_PLTYPE_STR:
- {
- const char *str;
- uint32_t hash;
-
- hash = event2 ? ast_event_get_ie_str_hash(event2, ie_val->ie_type) : ie_val->payload.hash;
- if (hash != ast_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 && !strcmp(str, ast_event_get_ie_str(event, ie_val->ie_type))) {
- return 1;
- }
-
- return 0;
- }
-
- case AST_EVENT_IE_PLTYPE_RAW:
- {
[... 1589 lines stripped ...]
More information about the asterisk-commits
mailing list