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: https://origsvn.digium.com/svn/asterisk/trunk@191919 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
parent
7b24f99808
commit
73743b77b0
|
@ -156,6 +156,20 @@ void ast_event_sub_destroy(struct ast_event_sub *sub);
|
||||||
int ast_event_sub_append_ie_uint(struct ast_event_sub *sub,
|
int ast_event_sub_append_ie_uint(struct ast_event_sub *sub,
|
||||||
enum ast_event_ie_type ie_type, uint32_t uint);
|
enum ast_event_ie_type ie_type, uint32_t uint);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Append a bitflags parameter to a subscription
|
||||||
|
*
|
||||||
|
* \param sub the dynamic subscription allocated with ast_event_subscribe_new()
|
||||||
|
* \param ie_type the information element type for the parameter
|
||||||
|
* \param flags the flags that must be present in the event to match this subscription
|
||||||
|
*
|
||||||
|
* \retval 0 success
|
||||||
|
* \retval non-zero failure
|
||||||
|
* \since 1.6.3
|
||||||
|
*/
|
||||||
|
int ast_event_sub_append_ie_bitflags(struct ast_event_sub *sub,
|
||||||
|
enum ast_event_ie_type ie_type, uint32_t flags);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Append a string parameter to a subscription
|
* \brief Append a string parameter to a subscription
|
||||||
*
|
*
|
||||||
|
@ -445,6 +459,24 @@ int ast_event_append_ie_str(struct ast_event **event, enum ast_event_ie_type ie_
|
||||||
int ast_event_append_ie_uint(struct ast_event **event, enum ast_event_ie_type ie_type,
|
int ast_event_append_ie_uint(struct ast_event **event, enum ast_event_ie_type ie_type,
|
||||||
uint32_t data);
|
uint32_t data);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Append an information element that has a bitflags payload
|
||||||
|
*
|
||||||
|
* \param event the event that the IE will be appended to
|
||||||
|
* \param ie_type the type of IE to append
|
||||||
|
* \param flags the flags that are the payload of the IE
|
||||||
|
*
|
||||||
|
* \retval 0 success
|
||||||
|
* \retval -1 failure
|
||||||
|
* \since 1.6.3
|
||||||
|
*
|
||||||
|
* The pointer to the event will get updated with the new location for the event
|
||||||
|
* that now contains the appended information element. If the re-allocation of
|
||||||
|
* the memory for this event fails, it will be set to NULL.
|
||||||
|
*/
|
||||||
|
int ast_event_append_ie_bitflags(struct ast_event **event, enum ast_event_ie_type ie_type,
|
||||||
|
uint32_t bitflags);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Append an information element that has a raw payload
|
* \brief Append an information element that has a raw payload
|
||||||
*
|
*
|
||||||
|
@ -475,6 +507,18 @@ int ast_event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_
|
||||||
*/
|
*/
|
||||||
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type);
|
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get the value of an information element that has a bitflags payload
|
||||||
|
*
|
||||||
|
* \param event The event to get the IE from
|
||||||
|
* \param ie_type the type of information element to retrieve
|
||||||
|
*
|
||||||
|
* \return This returns the payload of the information element with the given type.
|
||||||
|
* However, an IE with a payload of 0, and the case where no IE is found
|
||||||
|
* yield the same return value.
|
||||||
|
*/
|
||||||
|
uint32_t ast_event_get_ie_bitflags(const struct ast_event *event, enum ast_event_ie_type ie_type);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Get the value of an information element that has a string payload
|
* \brief Get the value of an information element that has a string payload
|
||||||
*
|
*
|
||||||
|
@ -614,7 +658,7 @@ int ast_event_iterator_next(struct ast_event_iterator *iterator);
|
||||||
enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator *iterator);
|
enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator *iterator);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Get the value of the current IE in the ierator as an integer payload
|
* \brief Get the value of the current IE in the iterator as an integer payload
|
||||||
*
|
*
|
||||||
* \param iterator The iterator instance
|
* \param iterator The iterator instance
|
||||||
*
|
*
|
||||||
|
@ -622,6 +666,15 @@ enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator
|
||||||
*/
|
*/
|
||||||
uint32_t ast_event_iterator_get_ie_uint(struct ast_event_iterator *iterator);
|
uint32_t ast_event_iterator_get_ie_uint(struct ast_event_iterator *iterator);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get the value of the current IE in the iterator as a bitflags payload
|
||||||
|
*
|
||||||
|
* \param iterator The iterator instance
|
||||||
|
*
|
||||||
|
* \return This returns the payload of the information element as bitflags.
|
||||||
|
*/
|
||||||
|
uint32_t ast_event_iterator_get_ie_bitflags(struct ast_event_iterator *iterator);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Get the value of the current IE in the iterator as a string payload
|
* \brief Get the value of the current IE in the iterator as a string payload
|
||||||
*
|
*
|
||||||
|
|
|
@ -137,6 +137,8 @@ enum ast_event_ie_pltype {
|
||||||
AST_EVENT_IE_PLTYPE_STR,
|
AST_EVENT_IE_PLTYPE_STR,
|
||||||
/*! Raw data, compared with memcmp */
|
/*! Raw data, compared with memcmp */
|
||||||
AST_EVENT_IE_PLTYPE_RAW,
|
AST_EVENT_IE_PLTYPE_RAW,
|
||||||
|
/*! Bit flags (unsigned integer, compared using boolean logic) */
|
||||||
|
AST_EVENT_IE_PLTYPE_BITFLAGS,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
108
main/event.c
108
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);
|
ast_free(ie_val->payload.raw);
|
||||||
break;
|
break;
|
||||||
case AST_EVENT_IE_PLTYPE_UINT:
|
case AST_EVENT_IE_PLTYPE_UINT:
|
||||||
|
case AST_EVENT_IE_PLTYPE_BITFLAGS:
|
||||||
case AST_EVENT_IE_PLTYPE_EXISTS:
|
case AST_EVENT_IE_PLTYPE_EXISTS:
|
||||||
case AST_EVENT_IE_PLTYPE_UNKNOWN:
|
case AST_EVENT_IE_PLTYPE_UNKNOWN:
|
||||||
break;
|
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:
|
case AST_EVENT_IE_PLTYPE_UINT:
|
||||||
ie_value->payload.uint = va_arg(ap, uint32_t);
|
ie_value->payload.uint = va_arg(ap, uint32_t);
|
||||||
break;
|
break;
|
||||||
|
case AST_EVENT_IE_PLTYPE_BITFLAGS:
|
||||||
|
ie_value->payload.uint = va_arg(ap, uint32_t);
|
||||||
|
break;
|
||||||
case AST_EVENT_IE_PLTYPE_STR:
|
case AST_EVENT_IE_PLTYPE_STR:
|
||||||
ie_value->payload.str = va_arg(ap, const char *);
|
ie_value->payload.str = va_arg(ap, const char *);
|
||||||
break;
|
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:
|
case AST_EVENT_IE_PLTYPE_UINT:
|
||||||
break_out = (ie_val->payload.uint != sub_ie_val->payload.uint);
|
break_out = (ie_val->payload.uint != sub_ie_val->payload.uint);
|
||||||
break;
|
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:
|
case AST_EVENT_IE_PLTYPE_STR:
|
||||||
break_out = strcmp(ie_val->payload.str, sub_ie_val->payload.str);
|
break_out = strcmp(ie_val->payload.str, sub_ie_val->payload.str);
|
||||||
break;
|
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,
|
static int match_ie_val(const struct ast_event *event,
|
||||||
const struct ast_event_ie_val *ie_val, const struct ast_event *event2)
|
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;
|
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 (val == ast_event_get_ie_uint(event, ie_val->ie_type)) ? 1 : 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR) {
|
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;
|
const char *str;
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
|
|
||||||
|
@ -460,16 +482,19 @@ static int match_ie_val(const struct ast_event *event,
|
||||||
return 0;
|
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;
|
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 (buf && !memcmp(buf, ast_event_get_ie_raw(event, ie_val->ie_type), ie_val->raw_datalen)) ? 1 : 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_EXISTS) {
|
case AST_EVENT_IE_PLTYPE_EXISTS:
|
||||||
if (ast_event_get_ie_raw(event, ie_val->ie_type))
|
{
|
||||||
return 1;
|
return ast_event_get_ie_raw(event, ie_val->ie_type) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case AST_EVENT_IE_PLTYPE_UNKNOWN:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,6 +552,9 @@ static struct ast_event *gen_sub_event(struct ast_event_sub *sub)
|
||||||
case AST_EVENT_IE_PLTYPE_UINT:
|
case AST_EVENT_IE_PLTYPE_UINT:
|
||||||
ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
|
ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
|
||||||
break;
|
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:
|
case AST_EVENT_IE_PLTYPE_STR:
|
||||||
ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str);
|
ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str);
|
||||||
break;
|
break;
|
||||||
|
@ -625,6 +653,26 @@ int ast_event_sub_append_ie_uint(struct ast_event_sub *sub,
|
||||||
return 0;
|
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,
|
int ast_event_sub_append_ie_exists(struct ast_event_sub *sub,
|
||||||
enum ast_event_ie_type ie_type)
|
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);
|
ast_event_sub_append_ie_uint(sub, ie_type, unsigned_int);
|
||||||
break;
|
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:
|
case AST_EVENT_IE_PLTYPE_STR:
|
||||||
{
|
{
|
||||||
const char *str = va_arg(ap, const char *);
|
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));
|
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 char *ast_event_iterator_get_ie_str(struct ast_event_iterator *iterator)
|
||||||
{
|
{
|
||||||
const struct ast_event_ie_str_payload *str_payload;
|
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;
|
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)
|
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;
|
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));
|
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,
|
int ast_event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_type,
|
||||||
const void *data, size_t data_len)
|
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:
|
case AST_EVENT_IE_PLTYPE_UINT:
|
||||||
ie_value->payload.uint = va_arg(ap, uint32_t);
|
ie_value->payload.uint = va_arg(ap, uint32_t);
|
||||||
break;
|
break;
|
||||||
|
case AST_EVENT_IE_PLTYPE_BITFLAGS:
|
||||||
|
ie_value->payload.uint = va_arg(ap, uint32_t);
|
||||||
|
break;
|
||||||
case AST_EVENT_IE_PLTYPE_STR:
|
case AST_EVENT_IE_PLTYPE_STR:
|
||||||
ie_value->payload.str = va_arg(ap, const char *);
|
ie_value->payload.str = va_arg(ap, const char *);
|
||||||
break;
|
break;
|
||||||
|
@ -1014,6 +1092,9 @@ struct ast_event *ast_event_new(enum ast_event_type type, ...)
|
||||||
case AST_EVENT_IE_PLTYPE_UINT:
|
case AST_EVENT_IE_PLTYPE_UINT:
|
||||||
ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
|
ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
|
||||||
break;
|
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:
|
case AST_EVENT_IE_PLTYPE_RAW:
|
||||||
ast_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);
|
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:
|
case AST_EVENT_IE_PLTYPE_UINT:
|
||||||
ast_event_append_ie_uint(&cache_arg_event, ie_type, va_arg(ap, uint32_t));
|
ast_event_append_ie_uint(&cache_arg_event, ie_type, va_arg(ap, uint32_t));
|
||||||
break;
|
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:
|
case AST_EVENT_IE_PLTYPE_STR:
|
||||||
ast_event_append_ie_str(&cache_arg_event, ie_type, va_arg(ap, const char *));
|
ast_event_append_ie_str(&cache_arg_event, ie_type, va_arg(ap, const char *));
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue