Mon Oct 8 12:39:21 2012

Asterisk developer's documentation


event.c File Reference

Internal generic event system. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/event.h"
#include "asterisk/linkedlists.h"
#include "asterisk/dlinkedlists.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/unaligned.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/astobj2.h"
#include "asterisk/cli.h"

Go to the source code of this file.

Data Structures

struct  ast_ev_check_list
 Subscription event check list. More...
struct  ast_event
 An event. More...
struct  ast_event_ie
 An event information element. More...
struct  ast_event_ie_str_payload
 The payload for a string information element. More...
struct  ast_event_ie_val
struct  ast_event_ref
 A holder for an event. More...
struct  ast_event_sub
 Event subscription. More...
struct  ast_event_sub_list
 Event subscriptions The event subscribers are indexed by which event they are subscribed to. More...
struct  ie_map
 IE payload types and names. More...

Defines

#define MAX_CACHE_ARGS   8
#define NUM_CACHE_BUCKETS   563

Functions

static struct ast_event_refalloc_event_ref (void)
int ast_event_append_eid (struct ast_event **event)
 Append the global EID IE.
int ast_event_append_ie_bitflags (struct ast_event **event, enum ast_event_ie_type ie_type, uint32_t flags)
 Append an information element that has a bitflags payload.
int ast_event_append_ie_raw (struct ast_event **event, enum ast_event_ie_type ie_type, const void *data, size_t data_len)
 Append an information element that has a raw payload.
int ast_event_append_ie_str (struct ast_event **event, enum ast_event_ie_type ie_type, const char *str)
 Append an information element that has a string payload.
int ast_event_append_ie_uint (struct ast_event **event, enum ast_event_ie_type ie_type, uint32_t data)
 Append an information element that has an integer payload.
enum ast_event_subscriber_res ast_event_check_subscriber (enum ast_event_type type,...)
 Check if subscribers exist.
static int ast_event_cmp (void *obj, void *arg, int flags)
void ast_event_destroy (struct ast_event *event)
 Destroy an event.
void ast_event_dump_cache (const struct ast_event_sub *event_sub)
 Dump the event cache for the subscriber.
static struct ast_eventast_event_dup (const struct ast_event *event)
ast_eventast_event_get_cached (enum ast_event_type type,...)
 Retrieve an event from the cache.
uint32_t ast_event_get_ie_bitflags (const struct ast_event *event, enum ast_event_ie_type ie_type)
 Get the value of an information element that has a bitflags payload.
enum ast_event_ie_pltype ast_event_get_ie_pltype (enum ast_event_ie_type ie_type)
 Get the payload type for a given information element type.
const void * ast_event_get_ie_raw (const struct ast_event *event, enum ast_event_ie_type ie_type)
 Get the value of an information element that has a raw payload.
uint16_t ast_event_get_ie_raw_payload_len (const struct ast_event *event, enum ast_event_ie_type ie_type)
 Get the length of the raw payload for a particular IE.
const char * ast_event_get_ie_str (const struct ast_event *event, enum ast_event_ie_type ie_type)
 Get the value of an information element that has a string payload.
uint32_t ast_event_get_ie_str_hash (const struct ast_event *event, enum ast_event_ie_type ie_type)
 Get the hash for the string payload of an IE.
const char * ast_event_get_ie_type_name (enum ast_event_ie_type ie_type)
 Get the string representation of an information element type.
uint32_t ast_event_get_ie_uint (const struct ast_event *event, enum ast_event_ie_type ie_type)
 Get the value of an information element that has an integer payload.
size_t ast_event_get_size (const struct ast_event *event)
 Get the size of an event.
enum ast_event_type ast_event_get_type (const struct ast_event *event)
 Get the type for an event.
const char * ast_event_get_type_name (const struct ast_event *event)
 Get the string representation of the type of the given event.
static int ast_event_hash (const void *obj, const int flags)
static int ast_event_hash_devstate (const void *obj, const int flags)
static int ast_event_hash_devstate_change (const void *obj, const int flags)
static int ast_event_hash_mwi (const void *obj, const int flags)
static void ast_event_ie_val_destroy (struct ast_event_ie_val *ie_val)
int ast_event_init (void)
uint32_t ast_event_iterator_get_ie_bitflags (struct ast_event_iterator *iterator)
 Get the value of the current IE in the iterator as a bitflags payload.
void * ast_event_iterator_get_ie_raw (struct ast_event_iterator *iterator)
 Get the value of the current IE in the iterator instance that has a raw payload.
uint16_t ast_event_iterator_get_ie_raw_payload_len (struct ast_event_iterator *iterator)
 Get the length of the raw payload for the current IE for an iterator.
const char * ast_event_iterator_get_ie_str (struct ast_event_iterator *iterator)
 Get the value of the current IE in the iterator as a string payload.
enum ast_event_ie_type ast_event_iterator_get_ie_type (struct ast_event_iterator *iterator)
 Get the type of the current IE in the iterator instance.
uint32_t ast_event_iterator_get_ie_uint (struct ast_event_iterator *iterator)
 Get the value of the current IE in the iterator as an integer payload.
int ast_event_iterator_init (struct ast_event_iterator *iterator, const struct ast_event *event)
 Initialize an event iterator instance.
int ast_event_iterator_next (struct ast_event_iterator *iterator)
 Move iterator instance to next IE.
size_t ast_event_minimum_length (void)
 Get the minimum length of an ast_event.
ast_eventast_event_new (enum ast_event_type type,...)
 Create a new event.
int ast_event_queue (struct ast_event *event)
 Queue an event.
int ast_event_queue_and_cache (struct ast_event *event)
 Queue and cache an event.
static void ast_event_ref_destroy (void *obj)
void ast_event_report_subs (const struct ast_event_sub *event_sub)
 Report current subscriptions to a subscription subscriber.
int ast_event_str_to_event_type (const char *str, enum ast_event_type *event_type)
 Convert a string into an event type.
int ast_event_str_to_ie_type (const char *str, enum ast_event_ie_type *ie_type)
 Convert a string to an IE type.
int ast_event_sub_activate (struct ast_event_sub *sub)
 Activate a dynamically built subscription.
int ast_event_sub_append_ie_bitflags (struct ast_event_sub *sub, enum ast_event_ie_type ie_type, uint32_t flags)
 Append a bitflags parameter to a subscription.
int ast_event_sub_append_ie_exists (struct ast_event_sub *sub, enum ast_event_ie_type ie_type)
 Append an 'exists' parameter to a subscription.
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)
 Append a raw parameter to a subscription.
int ast_event_sub_append_ie_str (struct ast_event_sub *sub, enum ast_event_ie_type ie_type, const char *str)
 Append a string parameter to a subscription.
int ast_event_sub_append_ie_uint (struct ast_event_sub *sub, enum ast_event_ie_type ie_type, uint32_t unsigned_int)
 Append a uint parameter to a subscription.
void ast_event_sub_destroy (struct ast_event_sub *sub)
 Destroy an allocated subscription.
ast_event_subast_event_subscribe (enum ast_event_type type, ast_event_cb_t cb, const char *description, void *userdata,...)
 Subscribe to events.
ast_event_subast_event_subscribe_new (enum ast_event_type type, ast_event_cb_t cb, void *userdata)
 Allocate a subscription, but do not activate it.
const char * ast_event_subscriber_get_description (struct ast_event_sub *sub)
 Get description for a subscription.
ast_event_subast_event_unsubscribe (struct ast_event_sub *sub)
 Un-subscribe from events.
static int dump_cache_cb (void *obj, void *arg, int flags)
static void dump_raw_ie (struct ast_event_iterator *i, struct ast_cli_args *a)
static char * event_dump_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int event_dump_cli (void *obj, void *arg, int flags)
static void event_update_cache (struct ao2_container *cache, struct ast_event *event)
static struct ast_eventgen_sub_event (struct ast_event_sub *sub)
static int handle_event (void *data)
static int match_ie_val (const struct ast_event *event, const struct ast_event_ie_val *ie_val, const struct ast_event *event2)
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)

Variables

struct {
   enum ast_event_ie_type   cache_args [MAX_CACHE_ARGS]
 Information Elements used for caching.
   ao2_container *   container
 Container of cached events.
   ao2_hash_fn *   hash_fn
 Event type specific hash function.
ast_event_cache [AST_EVENT_TOTAL]
 Event types that are kept in the cache.
static struct ast_event_sub_list ast_event_subs [AST_EVENT_TOTAL]
 Event subscriptions The event subscribers are indexed by which event they are subscribed to.
static const char *const cached_event_types [] = { "MWI", "DeviceState", "DeviceStateChange", NULL }
 Names of cached event types, for CLI tab completion.
static struct ast_cli_entry event_cli []
static struct ast_taskprocessorevent_dispatcher
static const char *const event_names [AST_EVENT_TOTAL]
 Event Names.
static struct ie_map ie_maps [AST_EVENT_IE_TOTAL]
 IE payload types and names.
static uint32_t sub_uniqueid


Detailed Description

Internal generic event system.

Author:
Russell Bryant <russell@digium.com>

Definition in file event.c.


Define Documentation

#define MAX_CACHE_ARGS   8

Definition at line 151 of file event.c.

#define NUM_CACHE_BUCKETS   563

Definition at line 148 of file event.c.

Referenced by ast_event_init().


Function Documentation

static struct ast_event_ref* alloc_event_ref ( void   )  [static]

Definition at line 1414 of file event.c.

References ao2_alloc, and ast_event_ref_destroy().

Referenced by ast_event_queue(), and event_update_cache().

01415 {
01416    return ao2_alloc(sizeof(struct ast_event_ref), ast_event_ref_destroy);
01417 }

int ast_event_append_eid ( struct ast_event **  event  ) 

Append the global EID IE.

Parameters:
event the event to append IE to
Note:
For ast_event_new() that includes IEs, this is done automatically for you.
Return values:
0 success
-1 failure

Definition at line 1303 of file event.c.

References ast_eid_default, ast_event_append_ie_raw(), and AST_EVENT_IE_EID.

Referenced by ast_event_new().

01304 {
01305    return ast_event_append_ie_raw(event, AST_EVENT_IE_EID,
01306          &ast_eid_default, sizeof(ast_eid_default));
01307 }

int ast_event_append_ie_bitflags ( struct ast_event **  event,
enum ast_event_ie_type  ie_type,
uint32_t  bitflags 
)

Append an information element that has a bitflags payload.

Parameters:
event the event that the IE will be appended to
ie_type the type of IE to append
bitflags the flags that are the payload of the IE
Return values:
0 success
-1 failure
Since:
1.8
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.

Definition at line 1166 of file event.c.

References ast_event_append_ie_raw().

Referenced by ast_event_get_cached(), ast_event_new(), and gen_sub_event().

01168 {
01169    flags = htonl(flags);
01170    return ast_event_append_ie_raw(event, ie_type, &flags, sizeof(flags));
01171 }

int ast_event_append_ie_raw ( struct ast_event **  event,
enum ast_event_ie_type  ie_type,
const void *  data,
size_t  data_len 
)

Append an information element that has a raw payload.

Parameters:
event the event that the IE will be appended to
ie_type the type of IE to append
data A pointer to the raw data for the payload of the IE
data_len The amount of data to copy into the payload
Return values:
0 success
-1 failure
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.

Definition at line 1173 of file event.c.

References ast_realloc, ast_event_ie::ie_payload, and ast_event_ie::ie_payload_len.

Referenced by ast_event_append_eid(), ast_event_append_ie_bitflags(), ast_event_append_ie_str(), ast_event_append_ie_uint(), ast_event_get_cached(), ast_event_new(), and gen_sub_event().

01175 {
01176    struct ast_event_ie *ie;
01177    unsigned int extra_len;
01178    uint16_t event_len;
01179 
01180    event_len = ntohs((*event)->event_len);
01181    extra_len = sizeof(*ie) + data_len;
01182 
01183    if (!(*event = ast_realloc(*event, event_len + extra_len))) {
01184       return -1;
01185    }
01186 
01187    ie = (struct ast_event_ie *) ( ((char *) *event) + event_len );
01188    ie->ie_type = htons(ie_type);
01189    ie->ie_payload_len = htons(data_len);
01190    memcpy(ie->ie_payload, data, data_len);
01191 
01192    (*event)->event_len = htons(event_len + extra_len);
01193 
01194    return 0;
01195 }

int ast_event_append_ie_str ( struct ast_event **  event,
enum ast_event_ie_type  ie_type,
const char *  str 
)

Append an information element that has a string payload.

Parameters:
event the event that the IE will be appended to
ie_type the type of IE to append
str The string for the payload of the IE
Return values:
0 success
-1 failure
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.

Definition at line 1138 of file event.c.

References ast_event_append_ie_raw(), AST_EVENT_IE_DEVICE, ast_str_hash(), ast_strdupa, ast_tech_to_upper(), ast_event_ie_str_payload::hash, and ast_event_ie_str_payload::str.

Referenced by add_ie(), add_ipv4_ie(), add_timeval_ie(), ast_event_get_cached(), ast_event_new(), and gen_sub_event().

01140 {
01141    struct ast_event_ie_str_payload *str_payload;
01142    size_t payload_len;
01143 
01144    payload_len = sizeof(*str_payload) + strlen(str);
01145    str_payload = alloca(payload_len);
01146 
01147    strcpy(str_payload->str, str);
01148    if (ie_type == AST_EVENT_IE_DEVICE) {
01149       char *uppertech = ast_strdupa(str);
01150       ast_tech_to_upper(uppertech);
01151       str_payload->hash = ast_str_hash(uppertech);
01152    } else {
01153       str_payload->hash = ast_str_hash(str);
01154    }
01155 
01156    return ast_event_append_ie_raw(event, ie_type, str_payload, payload_len);
01157 }

int ast_event_append_ie_uint ( struct ast_event **  event,
enum ast_event_ie_type  ie_type,
uint32_t  data 
)

Append an information element that has an integer payload.

Parameters:
event the event that the IE will be appended to
ie_type the type of IE to append
data The integer for the payload of the IE
Return values:
0 success
-1 failure
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.

Definition at line 1159 of file event.c.

References ast_event_append_ie_raw().

Referenced by add_ie(), ast_event_get_cached(), ast_event_new(), and gen_sub_event().

01161 {
01162    data = htonl(data);
01163    return ast_event_append_ie_raw(event, ie_type, &data, sizeof(data));
01164 }

enum ast_event_subscriber_res ast_event_check_subscriber ( enum ast_event_type  event_type,
  ... 
)

Check if subscribers exist.

Parameters:
event_type This is the type of event that the caller would like to check for subscribers to.
The rest of the arguments to this function specify additional parameters for checking for subscriptions to subsets of an event type. The arguments must in sets of:
    <enum ast_event_ie_type>, [enum ast_event_ie_pltype, [payload] ]
and must end with AST_EVENT_IE_END.

If the ie_type specified is *not* AST_EVENT_IE_END, then it must be followed by a valid IE payload type. If the payload type specified is AST_EVENT_IE_PLTYPE_EXISTS, then the 3rd argument should not be provided. Otherwise, a payload must also be specified.

Returns:
This returns one of the values defined in the ast_event_subscriber_res enum which will indicate if subscribers exist that match the given criteria.
Example usage:

This example will check if there are any subscribers to MWI events for the mailbox defined in the "mailbox" variable.

Definition at line 447 of file event.c.

References ARRAY_LEN, AST_EVENT_ALL, AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_BITFLAGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_PLTYPE_UNKNOWN, AST_EVENT_SUB_EXISTS, AST_EVENT_SUB_NONE, ast_event_subs, AST_LIST_HEAD_NOLOCK_INIT_VALUE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), AST_RWDLLIST_RDLOCK, AST_RWDLLIST_TRAVERSE, AST_RWDLLIST_UNLOCK, AST_RWLIST_FIRST, ast_event_ie_val::ie_type, ast_event_sub::ie_vals, ast_ev_check_list::ie_vals, LOG_ERROR, LOG_WARNING, and match_sub_ie_val_to_event().

Referenced by ast_event_queue(), ast_event_sub_activate(), and ast_event_unsubscribe().

00448 {
00449    va_list ap;
00450    enum ast_event_ie_type ie_type;
00451    enum ast_event_subscriber_res res = AST_EVENT_SUB_NONE;
00452    struct ast_event_ie_val *ie_val;
00453    struct ast_event_sub *sub;
00454    struct ast_ev_check_list check_ie_vals = {
00455       .ie_vals = AST_LIST_HEAD_NOLOCK_INIT_VALUE
00456    };
00457    const enum ast_event_type event_types[] = { type, AST_EVENT_ALL };
00458    int i;
00459    int want_specific_event;/* TRUE if looking for subscribers wanting specific parameters. */
00460 
00461    if (type >= AST_EVENT_TOTAL) {
00462       ast_log(LOG_ERROR, "%u is an invalid type!\n", type);
00463       return res;
00464    }
00465 
00466    want_specific_event = 0;
00467    va_start(ap, type);
00468    for (ie_type = va_arg(ap, enum ast_event_ie_type);
00469       ie_type != AST_EVENT_IE_END;
00470       ie_type = va_arg(ap, enum ast_event_ie_type))
00471    {
00472       struct ast_event_ie_val *ie_value = alloca(sizeof(*ie_value));
00473       int insert = 0;
00474 
00475       memset(ie_value, 0, sizeof(*ie_value));
00476       ie_value->ie_type = ie_type;
00477       ie_value->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
00478       switch (ie_value->ie_pltype) {
00479       case AST_EVENT_IE_PLTYPE_UINT:
00480          ie_value->payload.uint = va_arg(ap, uint32_t);
00481          insert = 1;
00482          break;
00483       case AST_EVENT_IE_PLTYPE_BITFLAGS:
00484          ie_value->payload.uint = va_arg(ap, uint32_t);
00485          insert = 1;
00486          break;
00487       case AST_EVENT_IE_PLTYPE_STR:
00488          ie_value->payload.str = va_arg(ap, const char *);
00489          insert = 1;
00490          break;
00491       case AST_EVENT_IE_PLTYPE_RAW:
00492       {
00493          void *data = va_arg(ap, void *);
00494          size_t datalen = va_arg(ap, size_t);
00495 
00496          ie_value->payload.raw = alloca(datalen);
00497          memcpy(ie_value->payload.raw, data, datalen);
00498          ie_value->raw_datalen = datalen;
00499          insert = 1;
00500          break;
00501       }
00502       case AST_EVENT_IE_PLTYPE_UNKNOWN:
00503       case AST_EVENT_IE_PLTYPE_EXISTS:
00504          /* Unsupported payload type. */
00505          break;
00506       }
00507 
00508       if (insert) {
00509          want_specific_event = 1;
00510          AST_LIST_INSERT_TAIL(&check_ie_vals.ie_vals, ie_value, entry);
00511       } else {
00512          ast_log(LOG_WARNING, "Unsupported PLTYPE(%d)\n", ie_value->ie_pltype);
00513       }
00514    }
00515    va_end(ap);
00516 
00517    for (i = 0; i < ARRAY_LEN(event_types); i++) {
00518       AST_RWDLLIST_RDLOCK(&ast_event_subs[event_types[i]]);
00519       if (want_specific_event) {
00520          AST_RWDLLIST_TRAVERSE(&ast_event_subs[event_types[i]], sub, entry) {
00521             AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
00522                if (!match_sub_ie_val_to_event(ie_val, &check_ie_vals)) {
00523                   /* The current subscription ie did not match an event ie. */
00524                   break;
00525                }
00526             }
00527             if (!ie_val) {
00528                /* Everything matched.  A subscriber is looking for this event. */
00529                break;
00530             }
00531          }
00532       } else {
00533          /* Just looking to see if there are ANY subscribers to the event type. */
00534          sub = AST_RWLIST_FIRST(&ast_event_subs[event_types[i]]);
00535       }
00536       AST_RWDLLIST_UNLOCK(&ast_event_subs[event_types[i]]);
00537       if (sub) {
00538          break;
00539       }
00540    }
00541 
00542    return sub ? AST_EVENT_SUB_EXISTS : AST_EVENT_SUB_NONE;
00543 }

static int ast_event_cmp ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1623 of file event.c.

References ARRAY_LEN, ast_event_cache, ast_event_get_ie_pltype(), ast_event_get_type(), cache_args, CMP_MATCH, ast_event_ref::event, and match_ie_val().

Referenced by ast_event_init(), and event_update_cache().

01624 {
01625    struct ast_event_ref *event_ref, *event_ref2;
01626    struct ast_event *event, *event2;
01627    int res = CMP_MATCH;
01628    int i;
01629    enum ast_event_ie_type *cache_args;
01630 
01631    event_ref = obj;
01632    event = event_ref->event;
01633 
01634    event_ref2 = arg;
01635    event2 = event_ref2->event;
01636 
01637    cache_args = ast_event_cache[ast_event_get_type(event)].cache_args;
01638 
01639    for (i = 0; i < ARRAY_LEN(ast_event_cache[0].cache_args) && cache_args[i]; i++) {
01640       struct ast_event_ie_val ie_val = {
01641          .ie_pltype = ast_event_get_ie_pltype(cache_args[i]),
01642          .ie_type = cache_args[i],
01643       };
01644 
01645       if (!match_ie_val(event, &ie_val, event2)) {
01646          res = 0;
01647          break;
01648       }
01649    }
01650 
01651    return res;
01652 }

void ast_event_destroy ( struct ast_event event  ) 

Destroy an event.

Parameters:
event the event to destroy
Returns:
Nothing
Note:
Events that have been queued should *not* be destroyed by the code that created the event. It will be automatically destroyed after being dispatched to the appropriate subscribers.

Definition at line 1309 of file event.c.

References ast_free.

Referenced by ast_cel_report_event(), ast_event_get_cached(), ast_event_queue(), ast_event_queue_and_cache(), ast_event_ref_destroy(), ast_event_report_subs(), ast_event_sub_activate(), ast_event_unsubscribe(), devstate_cached(), event_update_cache(), get_cached_mwi(), handle_security_event(), has_voicemail(), process_collection(), sig_pri_mwi_cache_update(), stun_monitor_request(), unistim_send_mwi_to_peer(), and update_registry().

01310 {
01311    ast_free(event);
01312 }

void ast_event_dump_cache ( const struct ast_event_sub event_sub  ) 

Dump the event cache for the subscriber.

Since:
1.6.1

Definition at line 653 of file event.c.

References ao2_callback, ast_event_cache, dump_cache_cb(), event_sub, OBJ_NODATA, and ast_event_sub::type.

Referenced by add_publish_event(), aji_init_event_distribution(), ast_ais_evt_membership_changed(), and handle_devstate_change().

00654 {
00655    ao2_callback(ast_event_cache[event_sub->type].container, OBJ_NODATA,
00656          dump_cache_cb, (void *) event_sub);
00657 }

static struct ast_event* ast_event_dup ( const struct ast_event event  )  [static]

Definition at line 1321 of file event.c.

References ast_calloc, ast_event_get_size(), and ast_event::event_len.

Referenced by ast_event_get_cached(), and event_update_cache().

01322 {
01323    struct ast_event *dup_event;
01324    uint16_t event_len;
01325 
01326    event_len = ast_event_get_size(event);
01327 
01328    if (!(dup_event = ast_calloc(1, event_len))) {
01329       return NULL;
01330    }
01331 
01332    memcpy(dup_event, event, event_len);
01333 
01334    return dup_event;
01335 }

struct ast_event* ast_event_get_cached ( enum  ast_event_type,
  ... 
)

Retrieve an event from the cache.

Parameters:
ast_event_type The type of event to retrieve from the cache
The rest of the arguments to this function specify information elements to match for retrieving events from the cache. They are specified in the form: and must end with AST_EVENT_IE_END.

If the ie_type specified is *not* AST_EVENT_IE_END, then it must be followed by a valid IE payload type. If the payload type specified is AST_EVENT_IE_PLTYPE_EXISTS, then the 3rd argument should not be provided. Otherwise, a payload must also be specified.

Returns:
A reference to an event retrieved from the cache. If no event was found that matches the specified criteria, then NULL will be returned.
Note:
If more than one event in the cache matches the specified criteria, only one will be returned, and it is undefined which one it will be.

The caller of this function *must* call ast_event_destroy() on the returned event after it is done using it.

Example Usage:

This example will check for an MWI event in the cache that matches the specified mailbox. This would be the way to find out the last known state of a mailbox without having to poll the mailbox directly.

Definition at line 1337 of file event.c.

References ao2_find, ao2_ref, ast_event_append_ie_bitflags(), ast_event_append_ie_raw(), ast_event_append_ie_str(), ast_event_append_ie_uint(), ast_event_cache, ast_event_destroy(), ast_event_dup(), AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_BITFLAGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_PLTYPE_UNKNOWN, ast_event_new(), ast_log(), container, ast_event_ref::event, LOG_ERROR, LOG_WARNING, and OBJ_POINTER.

Referenced by devstate_cached(), get_cached_mwi(), has_voicemail(), process_collection(), sig_pri_mwi_cache_update(), unistim_send_mwi_to_peer(), and update_registry().

01338 {
01339    va_list ap;
01340    enum ast_event_ie_type ie_type;
01341    struct ast_event *dup_event = NULL;
01342    struct ast_event_ref *cached_event_ref;
01343    struct ast_event *cache_arg_event;
01344    struct ast_event_ref tmp_event_ref = {
01345       .event = NULL,
01346    };
01347    struct ao2_container *container = NULL;
01348 
01349    if (type >= AST_EVENT_TOTAL) {
01350       ast_log(LOG_ERROR, "%u is an invalid type!\n", type);
01351       return NULL;
01352    }
01353 
01354    if (!(container = ast_event_cache[type].container)) {
01355       ast_log(LOG_ERROR, "%u is not a cached event type\n", type);
01356       return NULL;
01357    }
01358 
01359    if (!(cache_arg_event = ast_event_new(type, AST_EVENT_IE_END))) {
01360       return NULL;
01361    }
01362 
01363    va_start(ap, type);
01364    for (ie_type = va_arg(ap, enum ast_event_ie_type);
01365       ie_type != AST_EVENT_IE_END;
01366       ie_type = va_arg(ap, enum ast_event_ie_type))
01367    {
01368       enum ast_event_ie_pltype ie_pltype;
01369 
01370       ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
01371 
01372       switch (ie_pltype) {
01373       case AST_EVENT_IE_PLTYPE_UINT:
01374          ast_event_append_ie_uint(&cache_arg_event, ie_type, va_arg(ap, uint32_t));
01375          break;
01376       case AST_EVENT_IE_PLTYPE_BITFLAGS:
01377          ast_event_append_ie_bitflags(&cache_arg_event, ie_type, va_arg(ap, uint32_t));
01378          break;
01379       case AST_EVENT_IE_PLTYPE_STR:
01380          ast_event_append_ie_str(&cache_arg_event, ie_type, va_arg(ap, const char *));
01381          break;
01382       case AST_EVENT_IE_PLTYPE_RAW:
01383       {
01384          void *data = va_arg(ap, void *);
01385          size_t datalen = va_arg(ap, size_t);
01386          ast_event_append_ie_raw(&cache_arg_event, ie_type, data, datalen);
01387          break;
01388       }
01389       case AST_EVENT_IE_PLTYPE_EXISTS:
01390          ast_log(LOG_WARNING, "PLTYPE_EXISTS not supported by this function\n");
01391          break;
01392       case AST_EVENT_IE_PLTYPE_UNKNOWN:
01393          break;
01394       }
01395    }
01396    va_end(ap);
01397 
01398    tmp_event_ref.event = cache_arg_event;
01399 
01400    cached_event_ref = ao2_find(container, &tmp_event_ref, OBJ_POINTER);
01401 
01402    ast_event_destroy(cache_arg_event);
01403    cache_arg_event = NULL;
01404 
01405    if (cached_event_ref) {
01406       dup_event = ast_event_dup(cached_event_ref->event);
01407       ao2_ref(cached_event_ref, -1);
01408       cached_event_ref = NULL;
01409    }
01410 
01411    return dup_event;
01412 }

uint32_t ast_event_get_ie_bitflags ( const struct ast_event event,
enum ast_event_ie_type  ie_type 
)

Get the value of an information element that has a bitflags payload.

Parameters:
event The event to get the IE from
ie_type the type of information element to retrieve
Returns:
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.

Definition at line 1083 of file event.c.

References ast_event_get_ie_raw(), and get_unaligned_uint32().

Referenced by append_ie(), and match_ie_val().

01084 {
01085    const uint32_t *ie_val;
01086 
01087    ie_val = ast_event_get_ie_raw(event, ie_type);
01088 
01089    return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0;
01090 }

enum ast_event_ie_pltype ast_event_get_ie_pltype ( enum ast_event_ie_type  ie_type  ) 

Get the payload type for a given information element type.

Parameters:
ie_type the information element type to get the payload type of
Returns:
the payload type for the provided IE type
Since:
1.6.1

Definition at line 313 of file event.c.

References ARRAY_LEN, AST_EVENT_IE_PLTYPE_UNKNOWN, ast_log(), ie_maps, ie_map::ie_pltype, and LOG_ERROR.

Referenced by append_ie(), ast_event_cmp(), and event_dump_cli().

00314 {
00315    if (ie_type <= 0 || ie_type >= ARRAY_LEN(ie_maps)) {
00316       ast_log(LOG_ERROR, "Invalid IE type - '%d'\n", ie_type);
00317       return AST_EVENT_IE_PLTYPE_UNKNOWN;
00318    }
00319 
00320    return ie_maps[ie_type].ie_pltype;
00321 }

const void* ast_event_get_ie_raw ( const struct ast_event event,
enum ast_event_ie_type  ie_type 
)

Get the value of an information element that has a raw payload.

Parameters:
event The event to get the IE from
ie_type the type of information element to retrieve
Returns:
This returns the payload of the information element with the given type. If the information element isn't found, NULL will be returned.

Definition at line 1110 of file event.c.

References ast_event_iterator_get_ie_raw(), ast_event_iterator_get_ie_type(), ast_event_iterator_init(), ast_event_iterator_next(), and ast_event_iterator::event.

Referenced by aji_devstate_cb(), aji_mwi_cb(), ast_event_cb(), ast_event_get_ie_bitflags(), ast_event_get_ie_str(), ast_event_get_ie_str_hash(), ast_event_get_ie_uint(), ast_event_new(), devstate_cache_cb(), devstate_change_collector_cb(), evt_event_deliver_cb(), ie_is_present(), and match_ie_val().

01111 {
01112    struct ast_event_iterator iterator;
01113    int res;
01114 
01115    for (res = ast_event_iterator_init(&iterator, event); !res; res = ast_event_iterator_next(&iterator)) {
01116       if (ast_event_iterator_get_ie_type(&iterator) == ie_type) {
01117          return ast_event_iterator_get_ie_raw(&iterator);
01118       }
01119    }
01120 
01121    return NULL;
01122 }

uint16_t ast_event_get_ie_raw_payload_len ( const struct ast_event event,
enum ast_event_ie_type  ie_type 
)

Get the length of the raw payload for a particular IE.

Parameters:
event The event to get the IE payload length from
ie_type the type of information element to get the length of
Returns:
If an IE of type ie_type is found, its payload length is returned. Otherwise, 0 is returned.

Definition at line 1124 of file event.c.

References ast_event_iterator_get_ie_raw_payload_len(), ast_event_iterator_get_ie_type(), ast_event_iterator_init(), ast_event_iterator_next(), and ast_event_iterator::event.

Referenced by match_ie_val().

01125 {
01126    struct ast_event_iterator iterator;
01127    int res;
01128 
01129    for (res = ast_event_iterator_init(&iterator, event); !res; res = ast_event_iterator_next(&iterator)) {
01130       if (ast_event_iterator_get_ie_type(&iterator) == ie_type) {
01131          return ast_event_iterator_get_ie_raw_payload_len(&iterator);
01132       }
01133    }
01134 
01135    return 0;
01136 }

const char* ast_event_get_ie_str ( const struct ast_event event,
enum ast_event_ie_type  ie_type 
)

Get the value of an information element that has a string payload.

Parameters:
event The event to get the IE from
ie_type the type of information element to retrieve
Returns:
This returns the payload of the information element with the given type. If the information element isn't found, NULL will be returned.

Definition at line 1101 of file event.c.

References ast_event_get_ie_raw(), and ast_event_ie_str_payload::str.

Referenced by aji_devstate_cb(), aji_mwi_cb(), append_ie(), ast_cel_fill_record(), ast_event_hash_devstate(), ast_event_hash_devstate_change(), ast_event_hash_mwi(), device_state_cb(), devstate_change_collector_cb(), generic_monitor_devstate_cb(), match_ie_val(), mwi_sub_event_cb(), print_cel_sub(), and sig_pri_mwi_event_cb().

01102 {
01103    const struct ast_event_ie_str_payload *str_payload;
01104 
01105    str_payload = ast_event_get_ie_raw(event, ie_type);
01106 
01107    return str_payload ? str_payload->str : NULL;
01108 }

uint32_t ast_event_get_ie_str_hash ( const struct ast_event event,
enum ast_event_ie_type  ie_type 
)

Get the hash for the string payload of an IE.

Parameters:
event The event to get the IE from
ie_type the type of information element to retrieve the hash for
Returns:
This function returns the hash value as calculated by ast_str_hash() for the string payload. This is stored in the event to avoid unnecessary string comparisons.

Definition at line 1092 of file event.c.

References ast_event_get_ie_raw(), and ast_event_ie_str_payload::hash.

Referenced by match_ie_val().

01093 {
01094    const struct ast_event_ie_str_payload *str_payload;
01095 
01096    str_payload = ast_event_get_ie_raw(event, ie_type);
01097 
01098    return str_payload ? str_payload->hash : 0;
01099 }

const char* ast_event_get_ie_type_name ( enum ast_event_ie_type  ie_type  ) 

Get the string representation of an information element type.

Parameters:
ie_type the information element type to get the string representation of
Returns:
the string representation of the information element type
Since:
1.6.1

Definition at line 303 of file event.c.

References ARRAY_LEN, ast_log(), ie_maps, LOG_ERROR, and ie_map::name.

Referenced by append_ie(), dump_raw_ie(), event_dump_cache(), event_dump_cli(), and security_event_cb().

00304 {
00305    if (ie_type <= 0 || ie_type >= ARRAY_LEN(ie_maps)) {
00306       ast_log(LOG_ERROR, "Invalid IE type - '%d'\n", ie_type);
00307       return "";
00308    }
00309 
00310    return ie_maps[ie_type].name;
00311 }

uint32_t ast_event_get_ie_uint ( const struct ast_event event,
enum ast_event_ie_type  ie_type 
)

Get the value of an information element that has an integer payload.

Parameters:
event The event to get the IE from
ie_type the type of information element to retrieve
Returns:
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.

Definition at line 1074 of file event.c.

References ast_event_get_ie_raw(), and get_unaligned_uint32().

Referenced by aji_devstate_cb(), aji_mwi_cb(), append_ie(), ast_cel_fill_record(), device_state_cb(), devstate_cache_cb(), devstate_cached(), devstate_change_collector_cb(), generic_agent_devstate_cb(), generic_monitor_devstate_cb(), get_cached_mwi(), has_voicemail(), match_ie_val(), mwi_event_cb(), mwi_sub_event_cb(), mwi_unsub_event_cb(), process_collection(), security_event_cb(), sig_pri_mwi_cache_update(), sig_pri_mwi_event_cb(), unistim_send_mwi_to_peer(), and update_registry().

01075 {
01076    const uint32_t *ie_val;
01077 
01078    ie_val = ast_event_get_ie_raw(event, ie_type);
01079 
01080    return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0;
01081 }

size_t ast_event_get_size ( const struct ast_event event  ) 

Get the size of an event.

Parameters:
event the event to get the size of
Returns:
the number of bytes contained in the event
Since:
1.6.1

Definition at line 339 of file event.c.

References ast_event::event_len.

Referenced by ast_event_cb(), ast_event_dup(), and ast_event_iterator_init().

00340 {
00341    size_t res;
00342 
00343    res = ntohs(event->event_len);
00344 
00345    return res;
00346 }

enum ast_event_type ast_event_get_type ( const struct ast_event event  ) 

Get the type for an event.

Parameters:
event the event to get the type for
Returns:
the event type as represented by one of the values in the ast_event_type enum

Definition at line 1069 of file event.c.

Referenced by ast_event_cb(), ast_event_cmp(), ast_event_get_type_name(), ast_event_hash(), ast_event_queue_and_cache(), mwi_sub_event_cb(), and mwi_unsub_event_cb().

01070 {
01071    return ntohs(event->type);
01072 }

const char* ast_event_get_type_name ( const struct ast_event event  ) 

Get the string representation of the type of the given event.

Returns:
the string representation of the event type of the provided event
Since:
1.6.1

Definition at line 273 of file event.c.

References ARRAY_LEN, ast_event_get_type(), ast_log(), event_names, LOG_ERROR, and ast_event_sub::type.

Referenced by event_dump_cli().

00274 {
00275    enum ast_event_type type;
00276 
00277    type = ast_event_get_type(event);
00278 
00279    if (type < 0 || type >= ARRAY_LEN(event_names)) {
00280       ast_log(LOG_ERROR, "Invalid event type - '%d'\n", type);
00281       return "";
00282    }
00283 
00284    return event_names[type];
00285 }

static int ast_event_hash ( const void *  obj,
const int  flags 
) [static]

Definition at line 1589 of file event.c.

References ast_event_cache, ast_event_get_type(), ast_event_ref::event, and hash_fn.

Referenced by ast_event_init().

01590 {
01591    const struct ast_event_ref *event_ref;
01592    const struct ast_event *event;
01593    ao2_hash_fn *hash_fn;
01594 
01595    event_ref = obj;
01596    event = event_ref->event;
01597 
01598    if (!(hash_fn = ast_event_cache[ast_event_get_type(event)].hash_fn)) {
01599       return 0;
01600    }
01601 
01602    return hash_fn(event, flags);
01603 }

static int ast_event_hash_devstate ( const void *  obj,
const int  flags 
) [static]

Definition at line 1566 of file event.c.

References ast_event_get_ie_str(), AST_EVENT_IE_DEVICE, and ast_str_hash().

01567 {
01568    const struct ast_event *event = obj;
01569 
01570    return ast_str_hash(ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE));
01571 }

static int ast_event_hash_devstate_change ( const void *  obj,
const int  flags 
) [static]

Definition at line 1582 of file event.c.

References ast_event_get_ie_str(), AST_EVENT_IE_DEVICE, and ast_str_hash().

01583 {
01584    const struct ast_event *event = obj;
01585 
01586    return ast_str_hash(ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE));
01587 }

static int ast_event_hash_mwi ( const void *  obj,
const int  flags 
) [static]

Definition at line 1548 of file event.c.

References ast_event_get_ie_str(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_MAILBOX, ast_str_hash(), ast_str_hash_add(), context, and mailbox.

01549 {
01550    const struct ast_event *event = obj;
01551    const char *mailbox = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX);
01552    const char *context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT);
01553 
01554    return ast_str_hash_add(context, ast_str_hash(mailbox));
01555 }

static void ast_event_ie_val_destroy ( struct ast_event_ie_val ie_val  )  [static]

Definition at line 348 of file event.c.

References AST_EVENT_IE_PLTYPE_BITFLAGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_PLTYPE_UNKNOWN, ast_free, ast_event_ie_val::ie_pltype, ast_event_ie_val::payload, ast_event_ie_val::raw, and ast_event_ie_val::str.

Referenced by ast_event_sub_destroy().

00349 {
00350    switch (ie_val->ie_pltype) {
00351    case AST_EVENT_IE_PLTYPE_STR:
00352       ast_free((char *) ie_val->payload.str);
00353       break;
00354    case AST_EVENT_IE_PLTYPE_RAW:
00355       ast_free(ie_val->payload.raw);
00356       break;
00357    case AST_EVENT_IE_PLTYPE_UINT:
00358    case AST_EVENT_IE_PLTYPE_BITFLAGS:
00359    case AST_EVENT_IE_PLTYPE_EXISTS:
00360    case AST_EVENT_IE_PLTYPE_UNKNOWN:
00361       break;
00362    }
00363 
00364    ast_free(ie_val);
00365 }

int ast_event_init ( void   ) 

Provided by event.c

Definition at line 1780 of file event.c.

References ao2_container_alloc, ARRAY_LEN, ast_cli_register_multiple(), ast_event_cache, ast_event_cmp(), ast_event_hash(), ast_event_subs, AST_RWDLLIST_HEAD_INIT, ast_taskprocessor_get(), container, event_cli, event_dispatcher, hash_fn, and NUM_CACHE_BUCKETS.

Referenced by main().

01781 {
01782    int i;
01783 
01784    for (i = 0; i < AST_EVENT_TOTAL; i++) {
01785       AST_RWDLLIST_HEAD_INIT(&ast_event_subs[i]);
01786    }
01787 
01788    for (i = 0; i < AST_EVENT_TOTAL; i++) {
01789       if (!ast_event_cache[i].hash_fn) {
01790          /* This event type is not cached. */
01791          continue;
01792       }
01793 
01794       if (!(ast_event_cache[i].container = ao2_container_alloc(NUM_CACHE_BUCKETS,
01795             ast_event_hash, ast_event_cmp))) {
01796          return -1;
01797       }
01798    }
01799 
01800    if (!(event_dispatcher = ast_taskprocessor_get("core_event_dispatcher", 0))) {
01801       return -1;
01802    }
01803 
01804    ast_cli_register_multiple(event_cli, ARRAY_LEN(event_cli));
01805 
01806    return 0;
01807 }

uint32_t ast_event_iterator_get_ie_bitflags ( struct ast_event_iterator iterator  ) 

Get the value of the current IE in the iterator as a bitflags payload.

Parameters:
iterator The iterator instance
Returns:
This returns the payload of the information element as bitflags.

Definition at line 1045 of file event.c.

References get_unaligned_uint32(), ast_event_iterator::ie, and ast_event_ie::ie_payload.

Referenced by event_dump_cli().

01046 {
01047    return ntohl(get_unaligned_uint32(iterator->ie->ie_payload));
01048 }

void* ast_event_iterator_get_ie_raw ( struct ast_event_iterator iterator  ) 

Get the value of the current IE in the iterator instance that has a raw payload.

Parameters:
iterator The iterator instance
Returns:
This returns the payload of the information element as type raw.

Definition at line 1059 of file event.c.

References ast_event_iterator::ie, and ast_event_ie::ie_payload.

Referenced by ast_event_get_ie_raw(), and dump_raw_ie().

01060 {
01061    return iterator->ie->ie_payload;
01062 }

uint16_t ast_event_iterator_get_ie_raw_payload_len ( struct ast_event_iterator iterator  ) 

Get the length of the raw payload for the current IE for an iterator.

Parameters:
iterator The IE iterator
Returns:
The payload length of the current IE

Definition at line 1064 of file event.c.

References ast_event_iterator::ie, and ast_event_ie::ie_payload_len.

Referenced by ast_event_get_ie_raw_payload_len().

01065 {
01066    return ntohs(iterator->ie->ie_payload_len);
01067 }

const char* ast_event_iterator_get_ie_str ( struct ast_event_iterator iterator  ) 

Get the value of the current IE in the iterator as a string payload.

Parameters:
iterator The iterator instance
Returns:
This returns the payload of the information element as a string.

Definition at line 1050 of file event.c.

References ast_event_iterator::ie, ast_event_ie::ie_payload, and ast_event_ie_str_payload::str.

Referenced by event_dump_cli().

01051 {
01052    const struct ast_event_ie_str_payload *str_payload;
01053 
01054    str_payload = (struct ast_event_ie_str_payload *) iterator->ie->ie_payload;
01055 
01056    return str_payload ? str_payload->str : NULL;
01057 }

enum ast_event_ie_type ast_event_iterator_get_ie_type ( struct ast_event_iterator iterator  ) 

Get the type of the current IE in the iterator instance.

Parameters:
iterator The iterator instance
Returns:
the ie type as represented by one of the value sin the ast_event_ie_type enum

Definition at line 1035 of file event.c.

References ast_event_iterator::ie.

Referenced by ast_event_get_ie_raw(), ast_event_get_ie_raw_payload_len(), dump_raw_ie(), and event_dump_cli().

01036 {
01037    return ntohs(iterator->ie->ie_type);
01038 }

uint32_t ast_event_iterator_get_ie_uint ( struct ast_event_iterator iterator  ) 

Get the value of the current IE in the iterator as an integer payload.

Parameters:
iterator The iterator instance
Returns:
This returns the payload of the information element as a uint.

Definition at line 1040 of file event.c.

References get_unaligned_uint32(), ast_event_iterator::ie, and ast_event_ie::ie_payload.

Referenced by event_dump_cli().

01041 {
01042    return ntohl(get_unaligned_uint32(iterator->ie->ie_payload));
01043 }

int ast_event_iterator_init ( struct ast_event_iterator iterator,
const struct ast_event event 
)

Initialize an event iterator instance.

Parameters:
iterator The iterator instance to initialize
event The event that will be iterated through
Return values:
0 Success, there are IEs available to iterate
-1 Failure, there are no IEs in the event to iterate

Definition at line 1013 of file event.c.

References ast_event_get_size(), ast_event_iterator::event, ast_event_iterator::event_len, and ast_event_iterator::ie.

Referenced by ast_event_get_ie_raw(), ast_event_get_ie_raw_payload_len(), and event_dump_cli().

01014 {
01015    int res = 0;
01016 
01017    iterator->event_len = ast_event_get_size(event);
01018    iterator->event = event;
01019    if (iterator->event_len >= sizeof(*event) + sizeof(struct ast_event_ie)) {
01020       iterator->ie = (struct ast_event_ie *) ( ((char *) event) + sizeof(*event) );
01021    } else {
01022       iterator->ie = NULL;
01023       res = -1;
01024    }
01025 
01026    return res;
01027 }

int ast_event_iterator_next ( struct ast_event_iterator iterator  ) 

Move iterator instance to next IE.

Parameters:
iterator The iterator instance
Return values:
0 on success
-1 if end is reached

Definition at line 1029 of file event.c.

References ast_event_iterator::event, ast_event_iterator::event_len, ast_event_iterator::ie, and ast_event_ie::ie_payload_len.

Referenced by ast_event_get_ie_raw(), ast_event_get_ie_raw_payload_len(), and event_dump_cli().

01030 {
01031    iterator->ie = (struct ast_event_ie *) ( ((char *) iterator->ie) + sizeof(*iterator->ie) + ntohs(iterator->ie->ie_payload_len));
01032    return ((iterator->event_len <= (((char *) iterator->ie) - ((char *) iterator->event))) ? -1 : 0);
01033 }

size_t ast_event_minimum_length ( void   ) 

Get the minimum length of an ast_event.

Returns:
minimum amount of memory that will be consumed by any ast_event.

Definition at line 1809 of file event.c.

Referenced by evt_event_deliver_cb().

01810 {
01811    return sizeof(struct ast_event);
01812 }

struct ast_event* ast_event_new ( enum ast_event_type  event_type,
  ... 
)

Create a new event.

Parameters:
event_type The type of event to create
The rest of the arguments to this function specify information elements to add to the event. They are specified in the form: and must end with AST_EVENT_IE_END.

If the ie_type specified is *not* AST_EVENT_IE_END, then it must be followed by a valid IE payload type. The payload type, EXISTS, should not be used here because it makes no sense to do so. So, a payload must also be specified after the IE payload type.

Note:
The EID IE will be appended automatically when this function is used with at least one IE specified.
Returns:
This returns the event that has been created. If there is an error creating the event, NULL will be returned.
Example usage:

This creates a MWI event with 3 information elements, a mailbox which is a string, and the number of new and old messages, specified as integers.

Definition at line 1197 of file event.c.

References ast_calloc, ast_event_append_eid(), ast_event_append_ie_bitflags(), ast_event_append_ie_raw(), ast_event_append_ie_str(), ast_event_append_ie_uint(), ast_event_get_ie_raw(), AST_EVENT_IE_EID, AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_BITFLAGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_PLTYPE_UNKNOWN, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_event_ie_val::ie_pltype, ast_event_ie_val::ie_type, ast_event_sub::ie_vals, LOG_WARNING, ast_event_ie_val::payload, ast_event_ie_val::raw, ast_event_ie_val::raw_datalen, ast_event_ie_val::str, and ast_event_ie_val::uint.

Referenced by aji_handle_pubsub_event(), alloc_event(), ast_cel_report_event(), ast_event_get_cached(), ast_event_unsubscribe(), devstate_event(), gen_sub_event(), handle_request_notify(), notify_message(), process_collection(), queue_mwi_event(), and stun_monitor_request().

01198 {
01199    va_list ap;
01200    struct ast_event *event;
01201    enum ast_event_ie_type ie_type;
01202    struct ast_event_ie_val *ie_val;
01203    int has_ie = 0;
01204    AST_LIST_HEAD_NOLOCK_STATIC(ie_vals, ast_event_ie_val);
01205 
01206    /* Invalid type */
01207    if (type >= AST_EVENT_TOTAL) {
01208       ast_log(LOG_WARNING, "Someone tried to create an event of invalid "
01209          "type '%d'!\n", type);
01210       return NULL;
01211    }
01212 
01213    va_start(ap, type);
01214    for (ie_type = va_arg(ap, enum ast_event_ie_type);
01215       ie_type != AST_EVENT_IE_END;
01216       ie_type = va_arg(ap, enum ast_event_ie_type))
01217    {
01218       struct ast_event_ie_val *ie_value = alloca(sizeof(*ie_value));
01219       int insert = 0;
01220 
01221       memset(ie_value, 0, sizeof(*ie_value));
01222       ie_value->ie_type = ie_type;
01223       ie_value->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
01224       switch (ie_value->ie_pltype) {
01225       case AST_EVENT_IE_PLTYPE_UINT:
01226          ie_value->payload.uint = va_arg(ap, uint32_t);
01227          insert = 1;
01228          break;
01229       case AST_EVENT_IE_PLTYPE_BITFLAGS:
01230          ie_value->payload.uint = va_arg(ap, uint32_t);
01231          insert = 1;
01232          break;
01233       case AST_EVENT_IE_PLTYPE_STR:
01234          ie_value->payload.str = va_arg(ap, const char *);
01235          insert = 1;
01236          break;
01237       case AST_EVENT_IE_PLTYPE_RAW:
01238       {
01239          void *data = va_arg(ap, void *);
01240          size_t datalen = va_arg(ap, size_t);
01241          ie_value->payload.raw = alloca(datalen);
01242          memcpy(ie_value->payload.raw, data, datalen);
01243          ie_value->raw_datalen = datalen;
01244          insert = 1;
01245          break;
01246       }
01247       case AST_EVENT_IE_PLTYPE_UNKNOWN:
01248       case AST_EVENT_IE_PLTYPE_EXISTS:
01249          break;
01250       }
01251 
01252       if (insert) {
01253          AST_LIST_INSERT_TAIL(&ie_vals, ie_value, entry);
01254          has_ie = 1;
01255       } else {
01256          ast_log(LOG_WARNING, "Unsupported PLTYPE(%d)\n", ie_value->ie_pltype);
01257       }
01258    }
01259    va_end(ap);
01260 
01261    if (!(event = ast_calloc(1, sizeof(*event)))) {
01262       return NULL;
01263    }
01264 
01265    event->type = htons(type);
01266    event->event_len = htons(sizeof(*event));
01267 
01268    AST_LIST_TRAVERSE(&ie_vals, ie_val, entry) {
01269       switch (ie_val->ie_pltype) {
01270       case AST_EVENT_IE_PLTYPE_STR:
01271          ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str);
01272          break;
01273       case AST_EVENT_IE_PLTYPE_UINT:
01274          ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
01275          break;
01276       case AST_EVENT_IE_PLTYPE_BITFLAGS:
01277          ast_event_append_ie_bitflags(&event, ie_val->ie_type, ie_val->payload.uint);
01278          break;
01279       case AST_EVENT_IE_PLTYPE_RAW:
01280          ast_event_append_ie_raw(&event, ie_val->ie_type,
01281                ie_val->payload.raw, ie_val->raw_datalen);
01282          break;
01283       case AST_EVENT_IE_PLTYPE_EXISTS:
01284       case AST_EVENT_IE_PLTYPE_UNKNOWN:
01285          break;
01286       }
01287 
01288       /* realloc inside one of the append functions failed */
01289       if (!event) {
01290          return NULL;
01291       }
01292    }
01293 
01294    if (has_ie && !ast_event_get_ie_raw(event, AST_EVENT_IE_EID)) {
01295       /* If the event is originating on this server, add the server's
01296        * entity ID to the event. */
01297       ast_event_append_eid(&event);
01298    }
01299 
01300    return event;
01301 }

int ast_event_queue ( struct ast_event event  ) 

Queue an event.

Parameters:
event the event to be queued
Return values:
zero success
non-zero failure. Note that the caller of this function is responsible for destroying the event in the case of a failure.
This function queues an event to be dispatched to all of the appropriate subscribers. This function will not block while the event is being dispatched because the event is queued up for a dispatching thread to handle.

Definition at line 1512 of file event.c.

References alloc_event_ref(), ao2_ref, ast_event_check_subscriber(), ast_event_destroy(), AST_EVENT_IE_END, AST_EVENT_SUB_NONE, ast_log(), ast_taskprocessor_push(), ast_event_ref::event, event_dispatcher, handle_event(), and LOG_WARNING.

Referenced by ast_cel_report_event(), ast_event_queue_and_cache(), ast_event_sub_activate(), ast_event_unsubscribe(), handle_security_event(), and stun_monitor_request().

01513 {
01514    struct ast_event_ref *event_ref;
01515    uint16_t host_event_type;
01516    int res;
01517 
01518    host_event_type = ntohs(event->type);
01519 
01520    /* Invalid type */
01521    if (host_event_type >= AST_EVENT_TOTAL) {
01522       ast_log(LOG_WARNING, "Someone tried to queue an event of invalid "
01523          "type '%d'!\n", host_event_type);
01524       return -1;
01525    }
01526 
01527    /* If nobody has subscribed to this event type, throw it away now */
01528    if (ast_event_check_subscriber(host_event_type, AST_EVENT_IE_END)
01529          == AST_EVENT_SUB_NONE) {
01530       ast_event_destroy(event);
01531       return 0;
01532    }
01533 
01534    if (!(event_ref = alloc_event_ref())) {
01535       return -1;
01536    }
01537 
01538    event_ref->event = event;
01539 
01540    res = ast_taskprocessor_push(event_dispatcher, handle_event, event_ref);
01541    if (res) {
01542       event_ref->event = NULL;
01543       ao2_ref(event_ref, -1);
01544    }
01545    return res;
01546 }

int ast_event_queue_and_cache ( struct ast_event event  ) 

Queue and cache an event.

Parameters:
event the event to be queued and cached
The purpose of caching events is so that the core can retain the last known information for events that represent some sort of state. That way, when code needs to find out the current state, it can query the cache.

The event API already knows which events can be cached and how to cache them.

Return values:
0 success
non-zero failure.

Definition at line 1460 of file event.c.

References ast_event_cache, ast_event_destroy(), ast_event_get_type(), ast_event_queue(), ast_log(), container, event_update_cache(), and LOG_WARNING.

Referenced by aji_handle_pubsub_event(), devstate_event(), handle_request_notify(), notify_message(), process_collection(), queue_event(), and queue_mwi_event().

01461 {
01462    struct ao2_container *container;
01463 
01464    container = ast_event_cache[ast_event_get_type(event)].container;
01465    if (!container) {
01466       ast_log(LOG_WARNING, "cache requested for non-cached event type\n");
01467    } else {
01468       event_update_cache(container, event);
01469    }
01470 
01471    if (ast_event_queue(event)) {
01472       ast_event_destroy(event);
01473    }
01474    return 0;
01475 }

static void ast_event_ref_destroy ( void *  obj  )  [static]

Definition at line 1314 of file event.c.

References ast_event_destroy(), and ast_event_ref::event.

Referenced by alloc_event_ref().

01315 {
01316    struct ast_event_ref *event_ref = obj;
01317 
01318    ast_event_destroy(event_ref->event);
01319 }

void ast_event_report_subs ( const struct ast_event_sub sub  ) 

Report current subscriptions to a subscription subscriber.

Returns:
nothing
This reports all of the current subscribers to a subscriber of subscribers to a specific event type. (Try saying that a few times fast).

The idea here is that it is sometimes very useful for a module to know when someone subscribes to events. However, when they first subscribe, this provides that module the ability to request the event core report to them all of the subscriptions to that event type that already exist.

Definition at line 700 of file event.c.

References ast_event_destroy(), AST_EVENT_IE_EVENTTYPE, AST_EVENT_SUB, ast_event_subs, AST_LIST_TRAVERSE, AST_RWDLLIST_RDLOCK, AST_RWDLLIST_TRAVERSE, AST_RWDLLIST_UNLOCK, ast_event_sub::cb, event_sub, gen_sub_event(), ast_event_ie_val::ie_type, ast_event_sub::ie_vals, ast_event_ie_val::payload, ast_event_sub::type, ast_event_ie_val::uint, and ast_event_sub::userdata.

Referenced by handle_cli_status(), and start_poll_thread().

00701 {
00702    struct ast_event *event;
00703    struct ast_event_sub *sub;
00704    enum ast_event_type event_type = -1;
00705    struct ast_event_ie_val *ie_val;
00706 
00707    if (event_sub->type != AST_EVENT_SUB)
00708       return;
00709 
00710    AST_LIST_TRAVERSE(&event_sub->ie_vals, ie_val, entry) {
00711       if (ie_val->ie_type == AST_EVENT_IE_EVENTTYPE) {
00712          event_type = ie_val->payload.uint;
00713          break;
00714       }
00715    }
00716 
00717    if (event_type == -1)
00718       return;
00719 
00720    AST_RWDLLIST_RDLOCK(&ast_event_subs[event_type]);
00721    AST_RWDLLIST_TRAVERSE(&ast_event_subs[event_type], sub, entry) {
00722       if (event_sub == sub) {
00723          continue;
00724       }
00725 
00726       event = gen_sub_event(sub);
00727       if (!event) {
00728          continue;
00729       }
00730 
00731       event_sub->cb(event, event_sub->userdata);
00732 
00733       ast_event_destroy(event);
00734    }
00735    AST_RWDLLIST_UNLOCK(&ast_event_subs[event_type]);
00736 }

int ast_event_str_to_event_type ( const char *  str,
enum ast_event_type event_type 
)

Convert a string into an event type.

Parameters:
str the string to convert
event_type an output parameter for the event type
Return values:
0 success
non-zero failure
Since:
1.6.1

Definition at line 287 of file event.c.

References ARRAY_LEN, ast_strlen_zero(), and event_names.

Referenced by event_dump_cache().

00288 {
00289    int i;
00290 
00291    for (i = 0; i < ARRAY_LEN(event_names); i++) {
00292       if (ast_strlen_zero(event_names[i]) || strcasecmp(event_names[i], str)) {
00293          continue;
00294       }
00295 
00296       *event_type = i;
00297       return 0;
00298    }
00299 
00300    return -1;
00301 }

int ast_event_str_to_ie_type ( const char *  str,
enum ast_event_ie_type ie_type 
)

Convert a string to an IE type.

Parameters:
str the string to convert
ie_type an output parameter for the IE type
Return values:
0 success
non-zero failure
Since:
1.6.1

Definition at line 323 of file event.c.

References ARRAY_LEN, ie_maps, and name.

00324 {
00325    int i;
00326 
00327    for (i = 0; i < ARRAY_LEN(ie_maps); i++) {
00328       if (strcasecmp(ie_maps[i].name, str)) {
00329          continue;
00330       }
00331 
00332       *ie_type = i;
00333       return 0;
00334    }
00335 
00336    return -1;
00337 }

int ast_event_sub_activate ( struct ast_event_sub sub  ) 

Activate a dynamically built subscription.

Parameters:
sub the subscription to activate that was allocated using ast_event_subscribe_new()
Once a dynamically built subscription has had all of the parameters added to it, it should be activated using this function.

Return values:
0 success
non-zero failure
Since:
1.6.1

Definition at line 888 of file event.c.

References ast_event_check_subscriber(), ast_event_destroy(), AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, ast_event_queue(), AST_EVENT_SUB, AST_EVENT_SUB_NONE, ast_event_subs, AST_RWDLLIST_INSERT_TAIL, AST_RWDLLIST_UNLOCK, AST_RWDLLIST_WRLOCK, gen_sub_event(), and ast_event_sub::type.

Referenced by ast_event_subscribe().

00889 {
00890    if (ast_event_check_subscriber(AST_EVENT_SUB,
00891       AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, sub->type,
00892       AST_EVENT_IE_END) != AST_EVENT_SUB_NONE) {
00893       struct ast_event *event;
00894 
00895       event = gen_sub_event(sub);
00896       if (event && ast_event_queue(event)) {
00897          ast_event_destroy(event);
00898       }
00899    }
00900 
00901    AST_RWDLLIST_WRLOCK(&ast_event_subs[sub->type]);
00902    AST_RWDLLIST_INSERT_TAIL(&ast_event_subs[sub->type], sub, entry);
00903    AST_RWDLLIST_UNLOCK(&ast_event_subs[sub->type]);
00904 
00905    return 0;
00906 }

int ast_event_sub_append_ie_bitflags ( struct ast_event_sub sub,
enum ast_event_ie_type  ie_type,
uint32_t  flags 
)

Append a bitflags parameter to a subscription.

Parameters:
sub the dynamic subscription allocated with ast_event_subscribe_new()
ie_type the information element type for the parameter
flags the flags that must be present in the event to match this subscription
Return values:
0 success
non-zero failure
Since:
1.8

Definition at line 782 of file event.c.

References ast_calloc, AST_EVENT_IE_PLTYPE_BITFLAGS, AST_EVENT_IE_TOTAL, AST_LIST_INSERT_TAIL, and ast_event_sub::ie_vals.

Referenced by ast_event_subscribe().

00784 {
00785    struct ast_event_ie_val *ie_val;
00786 
00787    if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
00788       return -1;
00789    }
00790 
00791    if (!(ie_val = ast_calloc(1, sizeof(*ie_val)))) {
00792       return -1;
00793    }
00794 
00795    ie_val->ie_type = ie_type;
00796    ie_val->payload.uint = flags;
00797    ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_BITFLAGS;
00798 
00799    AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);
00800 
00801    return 0;
00802 }

int ast_event_sub_append_ie_exists ( struct ast_event_sub sub,
enum ast_event_ie_type  ie_type 
)

Append an 'exists' parameter to a subscription.

Parameters:
sub the dynamic subscription allocated with ast_event_subscribe_new()
ie_type the information element type that must be present in the event for it to match this subscription.
Return values:
0 success
non-zero failure
Since:
1.6.1

Definition at line 804 of file event.c.

References ast_calloc, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_TOTAL, AST_LIST_INSERT_TAIL, and ast_event_sub::ie_vals.

Referenced by ast_event_subscribe().

00806 {
00807    struct ast_event_ie_val *ie_val;
00808 
00809    if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
00810       return -1;
00811    }
00812 
00813    if (!(ie_val = ast_calloc(1, sizeof(*ie_val)))) {
00814       return -1;
00815    }
00816 
00817    ie_val->ie_type = ie_type;
00818    ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_EXISTS;
00819 
00820    AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);
00821 
00822    return 0;
00823 }

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 
)

Append a raw parameter to a subscription.

Parameters:
sub the dynamic subscription allocated with ast_event_subscribe_new()
ie_type the information element type for the parameter
data the data that must be present in the event to match this subscription
raw_datalen length of data
Return values:
0 success
non-zero failure
Since:
1.6.1

Definition at line 859 of file event.c.

References ast_calloc, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_TOTAL, ast_free, AST_LIST_INSERT_TAIL, ast_malloc, and ast_event_sub::ie_vals.

Referenced by ast_event_subscribe().

00861 {
00862    struct ast_event_ie_val *ie_val;
00863 
00864    if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
00865       return -1;
00866    }
00867 
00868    if (!(ie_val = ast_calloc(1, sizeof(*ie_val)))) {
00869       return -1;
00870    }
00871 
00872    ie_val->ie_type = ie_type;
00873    ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_RAW;
00874    ie_val->raw_datalen = raw_datalen;
00875 
00876    if (!(ie_val->payload.raw = ast_malloc(raw_datalen))) {
00877       ast_free(ie_val);
00878       return -1;
00879    }
00880 
00881    memcpy(ie_val->payload.raw, data, raw_datalen);
00882 
00883    AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);
00884 
00885    return 0;
00886 }

int ast_event_sub_append_ie_str ( struct ast_event_sub sub,
enum ast_event_ie_type  ie_type,
const char *  str 
)

Append a string parameter to a subscription.

Parameters:
sub the dynamic subscription allocated with ast_event_subscribe_new()
ie_type the information element type for the parameter
str the string that must be present in the event to match this subscription
Return values:
0 success
non-zero failure
Since:
1.6.1

Definition at line 825 of file event.c.

References ast_calloc, AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_TOTAL, ast_free, AST_LIST_INSERT_TAIL, ast_str_hash(), ast_strdup, ast_strdupa, ast_tech_to_upper(), and ast_event_sub::ie_vals.

Referenced by ast_event_subscribe(), and handle_devstate_change().

00827 {
00828    struct ast_event_ie_val *ie_val;
00829 
00830    if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
00831       return -1;
00832    }
00833 
00834    if (!(ie_val = ast_calloc(1, sizeof(*ie_val)))) {
00835       return -1;
00836    }
00837 
00838    ie_val->ie_type = ie_type;
00839    ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_STR;
00840 
00841    if (!(ie_val->payload.str = ast_strdup(str))) {
00842       ast_free(ie_val);
00843       return -1;
00844    }
00845 
00846    if (ie_type == AST_EVENT_IE_DEVICE) {
00847       char *uppertech = ast_strdupa(str);
00848       ast_tech_to_upper(uppertech);
00849       ie_val->payload.hash = ast_str_hash(uppertech);
00850    } else {
00851       ie_val->payload.hash = ast_str_hash(str);
00852    }
00853 
00854    AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);
00855 
00856    return 0;
00857 }

int ast_event_sub_append_ie_uint ( struct ast_event_sub sub,
enum ast_event_ie_type  ie_type,
uint32_t  uint 
)

Append a uint parameter to a subscription.

Parameters:
sub the dynamic subscription allocated with ast_event_subscribe_new()
ie_type the information element type for the parameter
uint the value that must be present in the event to match this subscription
Return values:
0 success
non-zero failure
Since:
1.6.1

Definition at line 760 of file event.c.

References ast_calloc, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_TOTAL, AST_LIST_INSERT_TAIL, and ast_event_sub::ie_vals.

Referenced by ast_event_subscribe(), and handle_cli_status().

00762 {
00763    struct ast_event_ie_val *ie_val;
00764 
00765    if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
00766       return -1;
00767    }
00768 
00769    if (!(ie_val = ast_calloc(1, sizeof(*ie_val)))) {
00770       return -1;
00771    }
00772 
00773    ie_val->ie_type = ie_type;
00774    ie_val->payload.uint = unsigned_int;
00775    ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_UINT;
00776 
00777    AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);
00778 
00779    return 0;
00780 }

void ast_event_sub_destroy ( struct ast_event_sub sub  ) 

Destroy an allocated subscription.

Parameters:
sub the subscription to destroy
This function should be used when a subscription is allocated with ast_event_subscribe_new(), but for some reason, you want to destroy it instead of activating it. This could be because of an error when reading in the configuration for the dynamically built subscription.
Since:
1.6.1

Definition at line 970 of file event.c.

References ast_event_ie_val_destroy(), ast_free, AST_LIST_REMOVE_HEAD, and ast_event_sub::ie_vals.

Referenced by ast_event_unsubscribe(), handle_cli_status(), and handle_devstate_change().

00971 {
00972    struct ast_event_ie_val *ie_val;
00973 
00974    while ((ie_val = AST_LIST_REMOVE_HEAD(&sub->ie_vals, entry))) {
00975       ast_event_ie_val_destroy(ie_val);
00976    }
00977 
00978    ast_free(sub);
00979 }

struct ast_event_sub* ast_event_subscribe ( enum ast_event_type  event_type,
ast_event_cb_t  cb,
const char *  description,
void *  userdata,
  ... 
)

Subscribe to events.

Parameters:
event_type The type of events to subscribe to
cb The function to be called with events
description Description of the subscription.
userdata data to be passed to the event callback
The rest of the arguments to this function specify additional parameters for the subscription to filter which events are passed to this subscriber. The arguments must be in sets of: and must end with AST_EVENT_IE_END.

If the ie_type specified is *not* AST_EVENT_IE_END, then it must be followed by a valid IE payload type. If the payload type specified is AST_EVENT_IE_PLTYPE_EXISTS, then the 3rd argument should not be provided. Otherwise, a payload must also be specified.

Returns:
This returns a reference to the subscription for use with un-subscribing later. If there is a failure in creating the subscription, NULL will be returned.
Example usage:

This creates a subscription to AST_EVENT_MWI events that contain an information element, AST_EVENT_IE_MAILBOX, with the same string value contained in peer->mailbox. Also, the event callback will be passed a pointer to the peer.

Note:
A NULL description will cause this function to crash, so watch out!

Definition at line 908 of file event.c.

References ast_copy_string(), AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_BITFLAGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_PLTYPE_UNKNOWN, ast_event_sub_activate(), ast_event_sub_append_ie_bitflags(), ast_event_sub_append_ie_exists(), ast_event_sub_append_ie_raw(), ast_event_sub_append_ie_str(), ast_event_sub_append_ie_uint(), ast_event_subscribe_new(), ast_event_sub::description, and str.

Referenced by add_peer_mwi_subs(), add_publish_event(), aji_init_event_distribution(), ast_enable_distributed_devstate(), build_peer(), cc_generic_agent_start_monitoring(), config_line(), create_new_generic_list(), load_module(), load_pbx(), network_change_event_subscribe(), sig_pri_start_pri(), and start_poll_thread().

00910 {
00911    va_list ap;
00912    enum ast_event_ie_type ie_type;
00913    struct ast_event_sub *sub;
00914 
00915    if (!(sub = ast_event_subscribe_new(type, cb, userdata))) {
00916       return NULL;
00917    }
00918 
00919    ast_copy_string(sub->description, description, sizeof(sub->description));
00920 
00921    va_start(ap, userdata);
00922    for (ie_type = va_arg(ap, enum ast_event_ie_type);
00923       ie_type != AST_EVENT_IE_END;
00924       ie_type = va_arg(ap, enum ast_event_ie_type))
00925    {
00926       enum ast_event_ie_pltype ie_pltype;
00927 
00928       ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
00929 
00930       switch (ie_pltype) {
00931       case AST_EVENT_IE_PLTYPE_UNKNOWN:
00932          break;
00933       case AST_EVENT_IE_PLTYPE_UINT:
00934       {
00935          uint32_t unsigned_int = va_arg(ap, uint32_t);
00936          ast_event_sub_append_ie_uint(sub, ie_type, unsigned_int);
00937          break;
00938       }
00939       case AST_EVENT_IE_PLTYPE_BITFLAGS:
00940       {
00941          uint32_t unsigned_int = va_arg(ap, uint32_t);
00942          ast_event_sub_append_ie_bitflags(sub, ie_type, unsigned_int);
00943          break;
00944       }
00945       case AST_EVENT_IE_PLTYPE_STR:
00946       {
00947          const char *str = va_arg(ap, const char *);
00948          ast_event_sub_append_ie_str(sub, ie_type, str);
00949          break;
00950       }
00951       case AST_EVENT_IE_PLTYPE_RAW:
00952       {
00953          void *data = va_arg(ap, void *);
00954          size_t data_len = va_arg(ap, size_t);
00955          ast_event_sub_append_ie_raw(sub, ie_type, data, data_len);
00956          break;
00957       }
00958       case AST_EVENT_IE_PLTYPE_EXISTS:
00959          ast_event_sub_append_ie_exists(sub, ie_type);
00960          break;
00961       }
00962    }
00963    va_end(ap);
00964 
00965    ast_event_sub_activate(sub);
00966 
00967    return sub;
00968 }

struct ast_event_sub* ast_event_subscribe_new ( enum ast_event_type  type,
ast_event_cb_t  cb,
void *  userdata 
)

Allocate a subscription, but do not activate it.

Parameters:
type the event type to subscribe to
cb the function to call when an event matches this subscription
userdata data to pass to the provided callback
This function should be used when you want to dynamically build a subscription.

Returns:
the allocated subscription, or NULL on failure
Since:
1.6.1

Definition at line 738 of file event.c.

References ast_atomic_fetchadd_int(), ast_calloc, ast_log(), and LOG_ERROR.

Referenced by ast_event_subscribe(), handle_cli_status(), and handle_devstate_change().

00740 {
00741    struct ast_event_sub *sub;
00742 
00743    if (type < 0 || type >= AST_EVENT_TOTAL) {
00744       ast_log(LOG_ERROR, "%u is an invalid type!\n", type);
00745       return NULL;
00746    }
00747 
00748    if (!(sub = ast_calloc(1, sizeof(*sub)))) {
00749       return NULL;
00750    }
00751 
00752    sub->type = type;
00753    sub->cb = cb;
00754    sub->userdata = userdata;
00755    sub->uniqueid = ast_atomic_fetchadd_int((int *) &sub_uniqueid, 1);
00756 
00757    return sub;
00758 }

const char* ast_event_subscriber_get_description ( struct ast_event_sub sub  ) 

Get description for a subscription.

Parameters:
sub subscription
Returns:
string description of the subscription

Definition at line 981 of file event.c.

References ast_event_sub::description.

00982 {
00983    return sub ? sub->description : NULL;
00984 }

struct ast_event_sub* ast_event_unsubscribe ( struct ast_event_sub event_sub  ) 

Un-subscribe from events.

Parameters:
event_sub This is the reference to the subscription returned by ast_event_subscribe.
This function will remove a subscription and free the associated data structures.

Returns:
NULL for convenience.
Version:
1.6.1 return changed to NULL

Definition at line 986 of file event.c.

References AST_DLLIST_REMOVE, ast_event_check_subscriber(), ast_event_destroy(), AST_EVENT_IE_DESCRIPTION, AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_UNIQUEID, ast_event_new(), ast_event_queue(), ast_event_sub_destroy(), AST_EVENT_SUB_NONE, ast_event_subs, AST_EVENT_UNSUB, AST_RWDLLIST_UNLOCK, AST_RWDLLIST_WRLOCK, ast_event_sub::description, ast_event_sub::type, and ast_event_sub::uniqueid.

Referenced by add_peer_mwi_subs(), cc_generic_agent_destructor(), destroy_dahdi_pvt(), destroy_mailbox(), generic_agent_devstate_unsubscribe(), generic_monitor_instance_list_destructor(), network_change_event_unsubscribe(), peer_destructor(), publish_event_destroy(), sig_pri_start_pri(), sig_pri_stop_pri(), stop_poll_thread(), and unload_module().

00987 {
00988    struct ast_event *event;
00989 
00990    AST_RWDLLIST_WRLOCK(&ast_event_subs[sub->type]);
00991    AST_DLLIST_REMOVE(&ast_event_subs[sub->type], sub, entry);
00992    AST_RWDLLIST_UNLOCK(&ast_event_subs[sub->type]);
00993 
00994    if (ast_event_check_subscriber(AST_EVENT_UNSUB,
00995       AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, sub->type,
00996       AST_EVENT_IE_END) != AST_EVENT_SUB_NONE) {
00997 
00998       event = ast_event_new(AST_EVENT_UNSUB,
00999          AST_EVENT_IE_UNIQUEID,    AST_EVENT_IE_PLTYPE_UINT, sub->uniqueid,
01000          AST_EVENT_IE_EVENTTYPE,   AST_EVENT_IE_PLTYPE_UINT, sub->type,
01001          AST_EVENT_IE_DESCRIPTION, AST_EVENT_IE_PLTYPE_STR, sub->description,
01002          AST_EVENT_IE_END);
01003       if (event && ast_event_queue(event)) {
01004          ast_event_destroy(event);
01005       }
01006    }
01007 
01008    ast_event_sub_destroy(sub);
01009 
01010    return NULL;
01011 }

static int dump_cache_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 631 of file event.c.

References AST_LIST_TRAVERSE, ast_event_sub::cb, ast_event_ref::event, event_sub, ast_event_sub::ie_vals, match_ie_val(), and ast_event_sub::userdata.

Referenced by ast_event_dump_cache().

00632 {
00633    const struct ast_event_ref *event_ref = obj;
00634    const struct ast_event *event = event_ref->event;
00635    const struct ast_event_sub *event_sub = arg;
00636    struct ast_event_ie_val *ie_val = NULL;
00637 
00638    AST_LIST_TRAVERSE(&event_sub->ie_vals, ie_val, entry) {
00639       if (!match_ie_val(event, ie_val, NULL)) {
00640          break;
00641       }
00642    }
00643 
00644    if (!ie_val) {
00645       /* All parameters were matched on this cache entry, so dump it */
00646       event_sub->cb(event, event_sub->userdata);
00647    }
00648 
00649    return 0;
00650 }

static void dump_raw_ie ( struct ast_event_iterator i,
struct ast_cli_args a 
) [static]

Definition at line 1654 of file event.c.

References ast_cli(), ast_eid_to_str(), ast_event_get_ie_type_name(), AST_EVENT_IE_EID, ast_event_iterator_get_ie_raw(), ast_event_iterator_get_ie_type(), and ast_cli_args::fd.

Referenced by event_dump_cli().

01655 {
01656    char eid_buf[32];
01657    enum ast_event_ie_type ie_type;
01658    const char *ie_type_name;
01659 
01660    ie_type = ast_event_iterator_get_ie_type(i);
01661    ie_type_name = ast_event_get_ie_type_name(ie_type);
01662 
01663    switch (ie_type) {
01664    case AST_EVENT_IE_EID:
01665       ast_eid_to_str(eid_buf, sizeof(eid_buf), ast_event_iterator_get_ie_raw(i));
01666       ast_cli(a->fd, "%.30s: %s\n", ie_type_name, eid_buf);
01667       break;
01668    default:
01669       ast_cli(a->fd, "%s\n", ie_type_name);
01670       break;
01671    }
01672 }

static char* event_dump_cache ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1725 of file event.c.

References ao2_callback, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ARRAY_LEN, ast_cli(), ast_cli_complete(), ast_event_cache, ast_event_get_ie_type_name(), ast_event_str_to_event_type(), cache_args, cached_event_types, CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, container, event_dump_cli(), ast_cli_args::fd, ast_cli_args::n, OBJ_NODATA, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

01726 {
01727    enum ast_event_type event_type;
01728    enum ast_event_ie_type *cache_args;
01729    int i;
01730 
01731    switch (cmd) {
01732    case CLI_INIT:
01733       e->command = "event dump cache";
01734       e->usage =
01735          "Usage: event dump cache <event type>\n"
01736          "       Dump all of the cached events for the given event type.\n"
01737          "       This is primarily intended for debugging.\n";
01738       return NULL;
01739    case CLI_GENERATE:
01740       if (a->pos == 3) {
01741          return ast_cli_complete(a->word, cached_event_types, a->n);
01742       }
01743       return NULL;
01744    case CLI_HANDLER:
01745       break;
01746    }
01747 
01748    if (a->argc != e->args + 1) {
01749       return CLI_SHOWUSAGE;
01750    }
01751 
01752    if (ast_event_str_to_event_type(a->argv[e->args], &event_type)) {
01753       ast_cli(a->fd, "Invalid cached event type: '%s'\n", a->argv[e->args]);
01754       return CLI_SHOWUSAGE;
01755    }
01756 
01757    if (!ast_event_cache[event_type].container) {
01758       ast_cli(a->fd, "Event type '%s' has no cache.\n", a->argv[e->args]);
01759       return CLI_SUCCESS;
01760    }
01761 
01762    ast_cli(a->fd, "Event Type: %s\n", a->argv[e->args]);
01763    ast_cli(a->fd, "Cache Unique Keys:\n");
01764    cache_args = ast_event_cache[event_type].cache_args;
01765    for (i = 0; i < ARRAY_LEN(ast_event_cache[0].cache_args) && cache_args[i]; i++) {
01766       ast_cli(a->fd, "--> %s\n", ast_event_get_ie_type_name(cache_args[i]));
01767    }
01768 
01769    ast_cli(a->fd, "\n--- Begin Cache Dump ---\n\n");
01770    ao2_callback(ast_event_cache[event_type].container, OBJ_NODATA, event_dump_cli, a);
01771    ast_cli(a->fd, "--- End Cache Dump ---\n\n");
01772 
01773    return CLI_SUCCESS;
01774 }

static int event_dump_cli ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1674 of file event.c.

References ast_cli(), ast_event_get_ie_pltype(), ast_event_get_ie_type_name(), ast_event_get_type_name(), AST_EVENT_IE_PLTYPE_BITFLAGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_PLTYPE_UNKNOWN, ast_event_iterator_get_ie_bitflags(), ast_event_iterator_get_ie_str(), ast_event_iterator_get_ie_type(), ast_event_iterator_get_ie_uint(), ast_event_iterator_init(), ast_event_iterator_next(), dump_raw_ie(), ast_event_iterator::event, ast_event_ref::event, and ast_cli_args::fd.

Referenced by event_dump_cache().

01675 {
01676    const struct ast_event_ref *event_ref = obj;
01677    const struct ast_event *event = event_ref->event;
01678    struct ast_cli_args *a = arg;
01679    struct ast_event_iterator i;
01680 
01681    if (ast_event_iterator_init(&i, event)) {
01682       ast_cli(a->fd, "Failed to initialize event iterator.  :-(\n");
01683       return 0;
01684    }
01685 
01686    ast_cli(a->fd, "Event: %s\n", ast_event_get_type_name(event));
01687 
01688    do {
01689       enum ast_event_ie_type ie_type;
01690       enum ast_event_ie_pltype ie_pltype;
01691       const char *ie_type_name;
01692 
01693       ie_type = ast_event_iterator_get_ie_type(&i);
01694       ie_type_name = ast_event_get_ie_type_name(ie_type);
01695       ie_pltype = ast_event_get_ie_pltype(ie_type);
01696 
01697       switch (ie_pltype) {
01698       case AST_EVENT_IE_PLTYPE_UNKNOWN:
01699       case AST_EVENT_IE_PLTYPE_EXISTS:
01700          ast_cli(a->fd, "%s\n", ie_type_name);
01701          break;
01702       case AST_EVENT_IE_PLTYPE_STR:
01703          ast_cli(a->fd, "%.30s: %s\n", ie_type_name,
01704                ast_event_iterator_get_ie_str(&i));
01705          break;
01706       case AST_EVENT_IE_PLTYPE_UINT:
01707          ast_cli(a->fd, "%.30s: %u\n", ie_type_name,
01708                ast_event_iterator_get_ie_uint(&i));
01709          break;
01710       case AST_EVENT_IE_PLTYPE_BITFLAGS:
01711          ast_cli(a->fd, "%.30s: %u\n", ie_type_name,
01712                ast_event_iterator_get_ie_bitflags(&i));
01713          break;
01714       case AST_EVENT_IE_PLTYPE_RAW:
01715          dump_raw_ie(&i, a);
01716          break;
01717       }
01718    } while (!ast_event_iterator_next(&i));
01719 
01720    ast_cli(a->fd, "\n");
01721 
01722    return 0;
01723 }

static void event_update_cache ( struct ao2_container cache,
struct ast_event event 
) [static]

Definition at line 1429 of file event.c.

References alloc_event_ref(), ao2_callback, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_event_cmp(), ast_event_destroy(), ast_event_dup(), cache, ast_event_ref::event, OBJ_MULTIPLE, OBJ_NODATA, OBJ_POINTER, and OBJ_UNLINK.

Referenced by ast_event_queue_and_cache().

01430 {
01431    struct ast_event_ref tmp_event_ref = {
01432       .event = event,
01433    };
01434    struct ast_event *dup_event;
01435    struct ast_event_ref *event_ref;
01436 
01437    /* Hold the cache container lock while it is updated. */
01438    ao2_lock(cache);
01439 
01440    /* Remove matches from the cache. */
01441    ao2_callback(cache, OBJ_POINTER | OBJ_UNLINK | OBJ_MULTIPLE | OBJ_NODATA,
01442       ast_event_cmp, &tmp_event_ref);
01443 
01444    /* Save a copy of the event in the cache. */
01445    dup_event = ast_event_dup(event);
01446    if (dup_event) {
01447       event_ref = alloc_event_ref();
01448       if (event_ref) {
01449          event_ref->event = dup_event;
01450          ao2_link(cache, event_ref);
01451          ao2_ref(event_ref, -1);
01452       } else {
01453          ast_event_destroy(dup_event);
01454       }
01455    }
01456 
01457    ao2_unlock(cache);
01458 }

static struct ast_event* gen_sub_event ( struct ast_event_sub sub  )  [static]

Definition at line 659 of file event.c.

References ast_event_append_ie_bitflags(), ast_event_append_ie_raw(), ast_event_append_ie_str(), ast_event_append_ie_uint(), AST_EVENT_IE_DESCRIPTION, AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_EXISTS, AST_EVENT_IE_PLTYPE_BITFLAGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_PLTYPE_UNKNOWN, AST_EVENT_IE_UNIQUEID, ast_event_new(), AST_EVENT_SUB, AST_LIST_TRAVERSE, ast_event_sub::description, ast_event_ie_val::ie_pltype, ast_event_ie_val::ie_type, ast_event_sub::ie_vals, ast_event_ie_val::payload, ast_event_ie_val::raw, ast_event_ie_val::raw_datalen, ast_event_ie_val::str, ast_event_sub::type, ast_event_ie_val::uint, and ast_event_sub::uniqueid.

Referenced by ast_event_report_subs(), and ast_event_sub_activate().

00660 {
00661    struct ast_event_ie_val *ie_val;
00662    struct ast_event *event;
00663 
00664    event = ast_event_new(AST_EVENT_SUB,
00665       AST_EVENT_IE_UNIQUEID,    AST_EVENT_IE_PLTYPE_UINT, sub->uniqueid,
00666       AST_EVENT_IE_EVENTTYPE,   AST_EVENT_IE_PLTYPE_UINT, sub->type,
00667       AST_EVENT_IE_DESCRIPTION, AST_EVENT_IE_PLTYPE_STR, sub->description,
00668       AST_EVENT_IE_END);
00669    if (!event)
00670       return NULL;
00671 
00672    AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
00673       switch (ie_val->ie_pltype) {
00674       case AST_EVENT_IE_PLTYPE_UNKNOWN:
00675          break;
00676       case AST_EVENT_IE_PLTYPE_EXISTS:
00677          ast_event_append_ie_uint(&event, AST_EVENT_IE_EXISTS, ie_val->ie_type);
00678          break;
00679       case AST_EVENT_IE_PLTYPE_UINT:
00680          ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
00681          break;
00682       case AST_EVENT_IE_PLTYPE_BITFLAGS:
00683          ast_event_append_ie_bitflags(&event, ie_val->ie_type, ie_val->payload.uint);
00684          break;
00685       case AST_EVENT_IE_PLTYPE_STR:
00686          ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str);
00687          break;
00688       case AST_EVENT_IE_PLTYPE_RAW:
00689          ast_event_append_ie_raw(&event, ie_val->ie_type, ie_val->payload.raw, ie_val->raw_datalen);
00690          break;
00691       }
00692       if (!event)
00693          break;
00694    }
00695 
00696    return event;
00697 }

static int handle_event ( void *  data  )  [static]

Definition at line 1477 of file event.c.

References ao2_ref, ARRAY_LEN, AST_EVENT_ALL, ast_event_subs, AST_LIST_TRAVERSE, AST_RWDLLIST_RDLOCK, AST_RWDLLIST_TRAVERSE, AST_RWDLLIST_UNLOCK, ast_event_sub::cb, ast_event_ref::event, ast_event_sub::ie_vals, match_ie_val(), and ast_event_sub::userdata.

01478 {
01479    struct ast_event_ref *event_ref = data;
01480    struct ast_event_sub *sub;
01481    const enum ast_event_type event_types[] = {
01482       ntohs(event_ref->event->type),
01483       AST_EVENT_ALL
01484    };
01485    int i;
01486 
01487    for (i = 0; i < ARRAY_LEN(event_types); i++) {
01488       AST_RWDLLIST_RDLOCK(&ast_event_subs[event_types[i]]);
01489       AST_RWDLLIST_TRAVERSE(&ast_event_subs[event_types[i]], sub, entry) {
01490          struct ast_event_ie_val *ie_val;
01491 
01492          AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
01493             if (!match_ie_val(event_ref->event, ie_val, NULL)) {
01494                /* The current subscription ie did not match an event ie. */
01495                break;
01496             }
01497          }
01498          if (ie_val) {
01499             /* The event did not match this subscription. */
01500             continue;
01501          }
01502          sub->cb(event_ref->event, sub->userdata);
01503       }
01504       AST_RWDLLIST_UNLOCK(&ast_event_subs[event_types[i]]);
01505    }
01506 
01507    ao2_ref(event_ref, -1);
01508 
01509    return 0;
01510 }

static int match_ie_val ( const struct ast_event event,
const struct ast_event_ie_val ie_val,
const struct ast_event event2 
) [static]

Definition at line 558 of file event.c.

References ast_event_get_ie_bitflags(), ast_event_get_ie_raw(), ast_event_get_ie_raw_payload_len(), ast_event_get_ie_str(), ast_event_get_ie_str_hash(), ast_event_get_ie_uint(), AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_BITFLAGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_PLTYPE_UNKNOWN, ast_strdupa, ast_tech_to_upper(), ast_event_ie_val::hash, ast_event_ie_val::ie_pltype, ast_event_ie_val::ie_type, ast_event_ie_val::payload, ast_event_ie_val::raw, ast_event_ie_val::raw_datalen, ast_event_ie_val::str, str, and ast_event_ie_val::uint.

Referenced by ast_event_cmp(), dump_cache_cb(), and handle_event().

00560 {
00561    switch (ie_val->ie_pltype) {
00562    case AST_EVENT_IE_PLTYPE_UINT:
00563    {
00564       uint32_t val = event2 ? ast_event_get_ie_uint(event2, ie_val->ie_type) : ie_val->payload.uint;
00565 
00566       return (val == ast_event_get_ie_uint(event, ie_val->ie_type)) ? 1 : 0;
00567    }
00568 
00569    case AST_EVENT_IE_PLTYPE_BITFLAGS:
00570    {
00571       uint32_t flags = event2 ? ast_event_get_ie_uint(event2, ie_val->ie_type) : ie_val->payload.uint;
00572 
00573       /*
00574        * If the subscriber has requested *any* of the bitflags that this event provides,
00575        * then it's a match.
00576        */
00577       return (flags & ast_event_get_ie_bitflags(event, ie_val->ie_type)) ? 1 : 0;
00578    }
00579 
00580    case AST_EVENT_IE_PLTYPE_STR:
00581    {
00582       const char *str;
00583       uint32_t hash;
00584 
00585       hash = event2 ? ast_event_get_ie_str_hash(event2, ie_val->ie_type) : ie_val->payload.hash;
00586       if (hash != ast_event_get_ie_str_hash(event, ie_val->ie_type)) {
00587          return 0;
00588       }
00589 
00590       str = event2 ? ast_event_get_ie_str(event2, ie_val->ie_type) : ie_val->payload.str;
00591       if (str) {
00592          const char *e1str, *e2str;
00593          e1str = ast_event_get_ie_str(event, ie_val->ie_type);
00594          e2str = str;
00595 
00596          if (ie_val->ie_type == AST_EVENT_IE_DEVICE) {
00597             e1str = ast_tech_to_upper(ast_strdupa(e1str));
00598             e2str = ast_tech_to_upper(ast_strdupa(e2str));
00599          }
00600 
00601          if (!strcmp(e1str, e2str)) {
00602             return 1;
00603          }
00604       }
00605 
00606       return 0;
00607    }
00608 
00609    case AST_EVENT_IE_PLTYPE_RAW:
00610    {
00611       const void *buf = event2 ? ast_event_get_ie_raw(event2, ie_val->ie_type) : ie_val->payload.raw;
00612       uint16_t ie_payload_len = event2 ? ast_event_get_ie_raw_payload_len(event2, ie_val->ie_type) : ie_val->raw_datalen;
00613 
00614       return (buf
00615          && ie_payload_len == ast_event_get_ie_raw_payload_len(event, ie_val->ie_type)
00616          && !memcmp(buf, ast_event_get_ie_raw(event, ie_val->ie_type), ie_payload_len)) ? 1 : 0;
00617    }
00618 
00619    case AST_EVENT_IE_PLTYPE_EXISTS:
00620    {
00621       return ast_event_get_ie_raw(event, ie_val->ie_type) ? 1 : 0;
00622    }
00623 
00624    case AST_EVENT_IE_PLTYPE_UNKNOWN:
00625       return 0;
00626    }
00627 
00628    return 0;
00629 }

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 
) [static]

Definition at line 382 of file event.c.

References AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_BITFLAGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_PLTYPE_UNKNOWN, AST_LIST_TRAVERSE, ast_strdupa, ast_tech_to_upper(), ast_event_ie_val::ie_pltype, ast_event_ie_val::ie_type, ast_event_ie_val::payload, ast_event_ie_val::raw, ast_event_ie_val::raw_datalen, ast_event_ie_val::str, and ast_event_ie_val::uint.

Referenced by ast_event_check_subscriber().

00383 {
00384    const struct ast_event_ie_val *event_ie_val;
00385    int res = 0;
00386 
00387    AST_LIST_TRAVERSE(&check_ie_vals->ie_vals, event_ie_val, entry) {
00388       if (sub_ie_val->ie_type == event_ie_val->ie_type) {
00389          break;
00390       }
00391    }
00392    if (!event_ie_val) {
00393       /* We did not find the event ie the subscriber cares about. */
00394       return 0;
00395    }
00396 
00397    if (sub_ie_val->ie_pltype != event_ie_val->ie_pltype) {
00398       if (sub_ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_EXISTS) {
00399          /* The subscription only cares that this ie exists. */
00400          return 1;
00401       }
00402       /* Payload types do not match. */
00403       return 0;
00404    }
00405 
00406    switch (sub_ie_val->ie_pltype) {
00407    case AST_EVENT_IE_PLTYPE_UINT:
00408       res = (sub_ie_val->payload.uint == event_ie_val->payload.uint);
00409       break;
00410    case AST_EVENT_IE_PLTYPE_BITFLAGS:
00411       /*
00412        * If the subscriber has requested *any* of the bitflags we are providing,
00413        * then it's a match.
00414        */
00415       res = (sub_ie_val->payload.uint & event_ie_val->payload.uint);
00416       break;
00417    case AST_EVENT_IE_PLTYPE_STR:
00418    {
00419       const char *substr = sub_ie_val->payload.str;
00420       const char *estr = event_ie_val->payload.str;
00421       if (sub_ie_val->ie_type == AST_EVENT_IE_DEVICE) {
00422          substr = ast_tech_to_upper(ast_strdupa(substr));
00423          estr = ast_tech_to_upper(ast_strdupa(estr));
00424       }
00425       res = !strcmp(substr, estr);
00426       break;
00427    }
00428    case AST_EVENT_IE_PLTYPE_RAW:
00429       res = (sub_ie_val->raw_datalen == event_ie_val->raw_datalen
00430          && !memcmp(sub_ie_val->payload.raw, event_ie_val->payload.raw,
00431             sub_ie_val->raw_datalen));
00432       break;
00433    case AST_EVENT_IE_PLTYPE_EXISTS:
00434       /* Should never get here since check_ie_vals cannot have this type. */
00435       break;
00436    case AST_EVENT_IE_PLTYPE_UNKNOWN:
00437       /*
00438        * Should never be in a subscription event ie val list and
00439        * check_ie_vals cannot have this type either.
00440        */
00441       break;
00442    }
00443 
00444    return res;
00445 }


Variable Documentation

struct { ... } ast_event_cache[AST_EVENT_TOTAL] [static]

Event types that are kept in the cache.

Referenced by ast_event_cmp(), ast_event_dump_cache(), ast_event_get_cached(), ast_event_hash(), ast_event_init(), ast_event_queue_and_cache(), and event_dump_cache().

struct ast_event_sub_list ast_event_subs[AST_EVENT_TOTAL] [static]

Event subscriptions The event subscribers are indexed by which event they are subscribed to.

Referenced by ast_event_check_subscriber(), ast_event_init(), ast_event_report_subs(), ast_event_sub_activate(), ast_event_unsubscribe(), and handle_event().

enum ast_event_ie_type cache_args[MAX_CACHE_ARGS]

Information Elements used for caching.

This array is the set of information elements that will be unique among all events in the cache for this event type. When a new event gets cached, a previous event with the same values for these information elements will be replaced.

Definition at line 174 of file event.c.

Referenced by ast_event_cmp(), and event_dump_cache().

const char* const cached_event_types[] = { "MWI", "DeviceState", "DeviceStateChange", NULL } [static]

Names of cached event types, for CLI tab completion.

Note:
These names must match what is in the event_names array.

Definition at line 195 of file event.c.

Referenced by event_dump_cache().

struct ao2_container* container

Container of cached events.

This gets allocated in ast_event_init() when Asterisk starts for the event types declared as using the cache.

Definition at line 163 of file event.c.

struct ast_cli_entry event_cli[] [static]

Initial value:

 {
   { .handler =  event_dump_cache , .summary =  "Dump the internal event cache (for debugging)" ,__VA_ARGS__ },
}

Definition at line 1776 of file event.c.

Referenced by ast_event_init().

struct ast_taskprocessor* event_dispatcher [static]

Definition at line 47 of file event.c.

Referenced by ast_event_init(), and ast_event_queue().

const char* const event_names[AST_EVENT_TOTAL] [static]

Event Names.

Definition at line 200 of file event.c.

Referenced by ast_event_get_type_name(), and ast_event_str_to_event_type().

ao2_hash_fn* hash_fn

Event type specific hash function.

Definition at line 165 of file event.c.

Referenced by ast_event_hash(), and ast_event_init().

struct ie_map ie_maps[AST_EVENT_IE_TOTAL] [static]

IE payload types and names.

Referenced by ast_event_get_ie_pltype(), ast_event_get_ie_type_name(), and ast_event_str_to_ie_type().

uint32_t sub_uniqueid [static]

Definition at line 134 of file event.c.


Generated on Mon Oct 8 12:39:21 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7