diff options
author | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-05-03 14:28:59 +0000 |
---|---|---|
committer | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-05-03 14:28:59 +0000 |
commit | df4e87f651ff3a6e61470596b52f01a80a1e3e1b (patch) | |
tree | 08c6ed6c14fc54caf70ece336f9f0ab9cc2f272a /main/event.c | |
parent | c5236b374320c00b11a85adcca61801dfc7da743 (diff) |
Add 'bitflags'-style information elements to event framework
This patch add a new payload type for information elements, a set
of bit flags. The payload is transported as a 32-bit unsigned integer
but when matching is performed between events and subscribers,
the matching is done by using a bitwise AND instead of numeric value
comparison.
Review: http://reviewboard.asterisk.org/r/242/
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@191919 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/event.c')
-rw-r--r-- | main/event.c | 108 |
1 files changed, 96 insertions, 12 deletions
diff --git a/main/event.c b/main/event.c index bc814720d..483d47832 100644 --- a/main/event.c +++ b/main/event.c @@ -311,6 +311,7 @@ static void ast_event_ie_val_destroy(struct ast_event_ie_val *ie_val) ast_free(ie_val->payload.raw); break; case AST_EVENT_IE_PLTYPE_UINT: + case AST_EVENT_IE_PLTYPE_BITFLAGS: case AST_EVENT_IE_PLTYPE_EXISTS: case AST_EVENT_IE_PLTYPE_UNKNOWN: break; @@ -347,6 +348,9 @@ enum ast_event_subscriber_res ast_event_check_subscriber(enum ast_event_type typ case AST_EVENT_IE_PLTYPE_UINT: ie_value->payload.uint = va_arg(ap, uint32_t); break; + case AST_EVENT_IE_PLTYPE_BITFLAGS: + ie_value->payload.uint = va_arg(ap, uint32_t); + break; case AST_EVENT_IE_PLTYPE_STR: ie_value->payload.str = va_arg(ap, const char *); break; @@ -392,6 +396,12 @@ enum ast_event_subscriber_res ast_event_check_subscriber(enum ast_event_type typ case AST_EVENT_IE_PLTYPE_UINT: break_out = (ie_val->payload.uint != sub_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 + */ + break_out = (ie_val->payload.uint & sub_ie_val->payload.uint); + break; case AST_EVENT_IE_PLTYPE_STR: break_out = strcmp(ie_val->payload.str, sub_ie_val->payload.str); break; @@ -436,14 +446,26 @@ enum ast_event_subscriber_res ast_event_check_subscriber(enum ast_event_type typ static int match_ie_val(const struct ast_event *event, const struct ast_event_ie_val *ie_val, const struct ast_event *event2) { - if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_UINT) { + 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; - if (val == ast_event_get_ie_uint(event, ie_val->ie_type)) - return 1; - return 0; + + 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; } - if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR) { + case AST_EVENT_IE_PLTYPE_STR: + { const char *str; uint32_t hash; @@ -460,16 +482,19 @@ static int match_ie_val(const struct ast_event *event, return 0; } - if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_RAW) { + case AST_EVENT_IE_PLTYPE_RAW: + { const void *buf = event2 ? ast_event_get_ie_raw(event2, ie_val->ie_type) : ie_val->payload.raw; - if (buf && !memcmp(buf, ast_event_get_ie_raw(event, ie_val->ie_type), ie_val->raw_datalen)) - return 1; - return 0; + + return (buf && !memcmp(buf, ast_event_get_ie_raw(event, ie_val->ie_type), ie_val->raw_datalen)) ? 1 : 0; } - if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_EXISTS) { - if (ast_event_get_ie_raw(event, ie_val->ie_type)) - return 1; + 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; } @@ -527,6 +552,9 @@ static struct ast_event *gen_sub_event(struct ast_event_sub *sub) 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; @@ -625,6 +653,26 @@ int ast_event_sub_append_ie_uint(struct ast_event_sub *sub, 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_MAX) + 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) { @@ -753,6 +801,12 @@ struct ast_event_sub *ast_event_subscribe(enum ast_event_type type, ast_event_cb 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 *); @@ -839,6 +893,11 @@ 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; @@ -867,6 +926,15 @@ 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; } +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; @@ -921,6 +989,13 @@ int ast_event_append_ie_uint(struct ast_event **event, enum ast_event_ie_type ie 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) { @@ -974,6 +1049,9 @@ struct ast_event *ast_event_new(enum ast_event_type type, ...) case AST_EVENT_IE_PLTYPE_UINT: ie_value->payload.uint = va_arg(ap, uint32_t); break; + case AST_EVENT_IE_PLTYPE_BITFLAGS: + ie_value->payload.uint = va_arg(ap, uint32_t); + break; case AST_EVENT_IE_PLTYPE_STR: ie_value->payload.str = va_arg(ap, const char *); break; @@ -1014,6 +1092,9 @@ 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: ast_event_append_ie_raw(&event, ie_val->ie_type, ie_val->payload.raw, ie_val->raw_datalen); @@ -1108,6 +1189,9 @@ struct ast_event *ast_event_get_cached(enum ast_event_type type, ...) case AST_EVENT_IE_PLTYPE_UINT: ast_event_append_ie_uint(&cache_arg_event, ie_type, va_arg(ap, uint32_t)); break; + case AST_EVENT_IE_PLTYPE_BITFLAGS: + ast_event_append_ie_bitflags(&cache_arg_event, ie_type, va_arg(ap, uint32_t)); + break; case AST_EVENT_IE_PLTYPE_STR: ast_event_append_ie_str(&cache_arg_event, ie_type, va_arg(ap, const char *)); break; |