Tue Aug 24 2010 19:41:52

Asterisk developer's documentation


Data Structures | Defines | Functions | Variables

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 dependency graph for event.c:

Go to the source code of this file.

Data Structures

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  event_name
struct  ie_map

Defines

#define MAX_CACHE_ARGS   8
#define NUM_CACHE_BUCKETS   563

Functions

static struct ast_event_refalloc_event_ref (void)
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 subscribed event type.
static struct ast_eventast_event_dup (const struct ast_event *event)
static int ast_event_dup_and_cache (const struct ast_event *event)
 Duplicate an event and add it to the cache.
struct ast_eventast_event_get_cached (enum ast_event_type type,...)
 Retrieve an event from the cache.
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.
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)
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.
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 ierator 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.
struct 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)
 Send AST_EVENT_SUB events to this subscriber of ... subscriber events.
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_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.
struct ast_event_subast_event_subscribe (enum ast_event_type type, ast_event_cb_t cb, void *userdata,...)
 Subscribe to events.
struct 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.
struct 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 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_ie_val_to_sub (const struct ast_event_sub *sub, const struct ast_event_ie_val *ie_val)

Variables

struct {
   enum ast_event_ie_type   cache_args [MAX_CACHE_ARGS]
 Information Elements used for caching.
   struct 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.
struct ast_taskprocessorevent_dispatcher
static struct event_name event_names []
static struct ie_map ie_maps []
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 145 of file event.c.

#define NUM_CACHE_BUCKETS   563

Definition at line 142 of file event.c.

Referenced by ast_event_init().


Function Documentation

static struct ast_event_ref* alloc_event_ref ( void   )  [static, read]

Definition at line 1116 of file event.c.

References ao2_alloc, and ast_event_ref_destroy().

Referenced by ast_event_dup_and_cache(), and ast_event_queue().

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

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 926 of file event.c.

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

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

{
   struct ast_event_ie *ie;
   unsigned int extra_len;
   uint16_t event_len;

   event_len = ntohs((*event)->event_len);
   extra_len = sizeof(*ie) + data_len;

   if (!(*event = ast_realloc(*event, event_len + extra_len)))
      return -1;

   ie = (struct ast_event_ie *) ( ((char *) *event) + event_len );
   ie->ie_type = htons(ie_type);
   ie->ie_payload_len = htons(data_len);
   memcpy(ie->ie_payload, data, data_len);

   (*event)->event_len = htons(event_len + extra_len);

   return 0;
}

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 904 of file event.c.

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

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

{
   struct ast_event_ie_str_payload *str_payload;
   size_t payload_len;

   payload_len = sizeof(*str_payload) + strlen(str);
   str_payload = alloca(payload_len);

   strcpy(str_payload->str, str);
   str_payload->hash = ast_str_hash(str);

   return ast_event_append_ie_raw(event, ie_type, str_payload, payload_len);
}

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

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 919 of file event.c.

References ast_event_append_ie_raw().

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

{
   data = htonl(data);
   return ast_event_append_ie_raw(event, ie_type, &data, sizeof(data));
}

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 368 of file event.c.

References ARRAY_LEN, AST_EVENT_ALL, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_SUB_EXISTS, ast_event_subs, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), AST_RWDLLIST_RDLOCK, AST_RWDLLIST_TRAVERSE, AST_RWDLLIST_UNLOCK, ast_strdupa, ast_event_ie_val::ie_pltype, ast_event_ie_val::ie_type, LOG_ERROR, match_ie_val_to_sub(), 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_queue(), ast_event_sub_activate(), and ast_event_unsubscribe().

{
   va_list ap;
   enum ast_event_ie_type ie_type;
   enum ast_event_subscriber_res res = AST_EVENT_SUB_NONE;
   struct ast_event_ie_val *ie_val;
   struct ast_event_sub *sub;
   AST_LIST_HEAD_NOLOCK_STATIC(ie_vals, ast_event_ie_val);
   const enum ast_event_type event_types[] = { type, AST_EVENT_ALL };
   int i;

   if (type >= AST_EVENT_TOTAL) {
      ast_log(LOG_ERROR, "%u is an invalid type!\n", type);
      return res;
   }

   va_start(ap, type);
   for (ie_type = va_arg(ap, enum ast_event_ie_type);
      ie_type != AST_EVENT_IE_END;
      ie_type = va_arg(ap, enum ast_event_ie_type))
   {
      struct ast_event_ie_val *ie_value = alloca(sizeof(*ie_value));
      memset(ie_value, 0, sizeof(*ie_value));
      ie_value->ie_type = ie_type;
      ie_value->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
      if (ie_value->ie_pltype == AST_EVENT_IE_PLTYPE_UINT)
         ie_value->payload.uint = va_arg(ap, uint32_t);
      else if (ie_value->ie_pltype == AST_EVENT_IE_PLTYPE_STR)
         ie_value->payload.str = ast_strdupa(va_arg(ap, const char *));
      else if (ie_value->ie_pltype == AST_EVENT_IE_PLTYPE_RAW) {
         void *data = va_arg(ap, void *);
         size_t datalen = va_arg(ap, size_t);
         ie_value->payload.raw = alloca(datalen);
         memcpy(ie_value->payload.raw, data, datalen);
         ie_value->raw_datalen = datalen;
      }
      AST_LIST_INSERT_TAIL(&ie_vals, ie_value, entry);
   }
   va_end(ap);

   for (i = 0; i < ARRAY_LEN(event_types); i++) {
      AST_RWDLLIST_RDLOCK(&ast_event_subs[event_types[i]]);
      AST_RWDLLIST_TRAVERSE(&ast_event_subs[event_types[i]], sub, entry) {
         AST_LIST_TRAVERSE(&ie_vals, ie_val, entry) {
            if (match_ie_val_to_sub(sub, ie_val)) {
               break;
            }
         }

         if (!ie_val) {
            /* Everything matched. */
            break;
         }
      }
      AST_RWDLLIST_UNLOCK(&ast_event_subs[event_types[i]]);
      if (sub) {
         break;
      }
   }

   return sub ? AST_EVENT_SUB_EXISTS : AST_EVENT_SUB_NONE;
}

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

Definition at line 1306 of file event.c.

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

Referenced by ast_event_init(), and ast_event_queue_and_cache().

{
   struct ast_event_ref *event_ref, *event_ref2;
   struct ast_event *event, *event2;
   int res = CMP_MATCH;
   int i;
   enum ast_event_ie_type *cache_args;

   event_ref = obj;
   event = event_ref->event;

   event_ref2 = arg;
   event2 = event_ref2->event;

   cache_args = ast_event_cache[ast_event_get_type(event)].cache_args;

   for (i = 0; i < ARRAY_LEN(ast_event_cache[0].cache_args) && cache_args[i]; i++) {
      struct ast_event_ie_val ie_val = {
         .ie_pltype = ast_event_get_ie_pltype(cache_args[i]),
         .ie_type = cache_args[i],
      };

      if (!match_ie_val(event, &ie_val, event2)) {
         res = 0;
         break;
      }
   }

   return res;
}

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 1015 of file event.c.

References ast_free.

Referenced by ast_event_dup_and_cache(), ast_event_get_cached(), ast_event_queue(), ast_event_ref_destroy(), ast_event_report_subs(), devstate_cached(), get_cached_mwi(), has_voicemail(), process_collection(), unistim_send_mwi_to_peer(), and update_registry().

{
   ast_free(event);
}

void ast_event_dump_cache ( const struct ast_event_sub event_sub  ) 

Dump the event cache for the subscribed event type.

Dump the event cache for the subscriber.

Definition at line 509 of file event.c.

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

Referenced by add_publish_event(), and handle_devstate_change().

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

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

Definition at line 1027 of file event.c.

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

Referenced by ast_event_dup_and_cache(), and ast_event_get_cached().

{
   struct ast_event *dup_event;
   uint16_t event_len;

   event_len = ast_event_get_size(event);

   if (!(dup_event = ast_calloc(1, event_len))) {
      return NULL;
   }

   memcpy(dup_event, event, event_len);

   return dup_event;
}

static int ast_event_dup_and_cache ( const struct ast_event event  )  [static]

Duplicate an event and add it to the cache.

Note:
This assumes this index in to the cache is locked

Definition at line 1123 of file event.c.

References alloc_event_ref(), ao2_link, ao2_ref, ast_event_cache, ast_event_destroy(), ast_event_dup(), ast_event_get_type(), container, and ast_event_ref::event.

Referenced by ast_event_queue_and_cache().

{
   struct ast_event *dup_event;
   struct ast_event_ref *event_ref;

   if (!(dup_event = ast_event_dup(event))) {
      return -1;
   }

   if (!(event_ref = alloc_event_ref())) {
      ast_event_destroy(dup_event);
      return -1;
   }

   event_ref->event = dup_event;

   ao2_link(ast_event_cache[ast_event_get_type(event)].container, event_ref);

   ao2_ref(event_ref, -1);

   return 0;
}

struct ast_event* ast_event_get_cached ( enum  ast_event_type,
  ... 
) [read]

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:

    <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:
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 1043 of file event.c.

References ao2_find, ao2_ref, 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_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(), unistim_send_mwi_to_peer(), and update_registry().

{
   va_list ap;
   enum ast_event_ie_type ie_type;
   struct ast_event *dup_event = NULL;
   struct ast_event_ref *cached_event_ref;
   struct ast_event *cache_arg_event;
   struct ast_event_ref tmp_event_ref = {
      .event = NULL,
   };
   struct ao2_container *container = NULL;

   if (type >= AST_EVENT_TOTAL) {
      ast_log(LOG_ERROR, "%u is an invalid type!\n", type);
      return NULL;
   }

   if (!(container = ast_event_cache[type].container)) {
      ast_log(LOG_ERROR, "%u is not a cached event type\n", type);
      return NULL;
   }

   if (!(cache_arg_event = ast_event_new(type, AST_EVENT_IE_END))) {
      return NULL;
   }

   va_start(ap, type);
   for (ie_type = va_arg(ap, enum ast_event_ie_type);
      ie_type != AST_EVENT_IE_END;
      ie_type = va_arg(ap, enum ast_event_ie_type))
   {
      enum ast_event_ie_pltype ie_pltype;

      ie_pltype = va_arg(ap, enum ast_event_ie_pltype);

      switch (ie_pltype) {
      case AST_EVENT_IE_PLTYPE_UINT:
         ast_event_append_ie_uint(&cache_arg_event, ie_type, va_arg(ap, uint32_t));
         break;
      case AST_EVENT_IE_PLTYPE_STR:
         ast_event_append_ie_str(&cache_arg_event, ie_type, va_arg(ap, const char *));
         break;
      case AST_EVENT_IE_PLTYPE_RAW:
      {
         void *data = va_arg(ap, void *);
         size_t datalen = va_arg(ap, size_t);
         ast_event_append_ie_raw(&cache_arg_event, ie_type, data, datalen);
      }
      case AST_EVENT_IE_PLTYPE_EXISTS:
         ast_log(LOG_WARNING, "PLTYPE_EXISTS not supported by this function\n");
         break;
      case AST_EVENT_IE_PLTYPE_UNKNOWN:
         break;
      }
   }
   va_end(ap);

   tmp_event_ref.event = cache_arg_event;

   cached_event_ref = ao2_find(container, &tmp_event_ref, OBJ_POINTER);

   ast_event_destroy(cache_arg_event);
   cache_arg_event = NULL;

   if (cached_event_ref) {
      dup_event = ast_event_dup(cached_event_ref->event);
      ao2_ref(cached_event_ref, -1);
      cached_event_ref = NULL;
   }

   return dup_event;
}

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 265 of file event.c.

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

Referenced by ast_event_cmp().

{
   if (ie_type <= 0 || ie_type > AST_EVENT_IE_MAX) {
      ast_log(LOG_ERROR, "Invalid IE type - '%d'\n", ie_type);
      return AST_EVENT_IE_PLTYPE_UNKNOWN;
   }

   if (ie_maps[ie_type].ie_type != ie_type) {
      ast_log(LOG_ERROR, "The ie type passed in does not match the ie type defined in the ie table.\n");
      return AST_EVENT_IE_PLTYPE_UNKNOWN;
   }

   return ie_maps[ie_type].ie_pltype;
}

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 890 of file event.c.

References ast_event_iterator_get_ie_raw(), ast_event_iterator_get_ie_type(), ast_event_iterator_init(), and ast_event_iterator_next().

Referenced by ast_event_cb(), 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(), and match_ie_val().

{
   struct ast_event_iterator iterator;
   int res = 0;

   for (res = ast_event_iterator_init(&iterator, event); !res; res = ast_event_iterator_next(&iterator)) {
      if (ast_event_iterator_get_ie_type(&iterator) == ie_type) {
         return ast_event_iterator_get_ie_raw(&iterator);
      }
   }

   return NULL;
}

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 881 of file event.c.

References ast_event_get_ie_raw(), and ast_event_ie_str_payload::str.

Referenced by ast_event_hash_devstate(), ast_event_hash_devstate_change(), ast_event_hash_mwi(), device_state_cb(), devstate_change_collector_cb(), match_ie_val(), and mwi_sub_event_cb().

{
   const struct ast_event_ie_str_payload *str_payload;

   str_payload = ast_event_get_ie_raw(event, ie_type);

   return str_payload ? str_payload->str : NULL;
}

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 872 of file event.c.

References ast_event_get_ie_raw(), and ast_event_ie_str_payload::hash.

Referenced by match_ie_val().

{
   const struct ast_event_ie_str_payload *str_payload;

   str_payload = ast_event_get_ie_raw(event, ie_type);

   return str_payload ? str_payload->hash : 0;
}

const char* ast_event_get_ie_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 250 of file event.c.

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

{
   if (ie_type <= 0 || ie_type > AST_EVENT_IE_MAX) {
      ast_log(LOG_ERROR, "Invalid IE type - '%d'\n", ie_type);
      return "";
   }

   if (ie_maps[ie_type].ie_type != ie_type) {
      ast_log(LOG_ERROR, "The ie type passed in does not match the ie type defined in the ie table.\n");
      return "";
   }

   return ie_maps[ie_type].name;
}

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 863 of file event.c.

References ast_event_get_ie_raw(), and get_unaligned_uint32().

Referenced by device_state_cb(), devstate_cache_cb(), devstate_cached(), devstate_change_collector_cb(), get_cached_mwi(), has_voicemail(), match_ie_val(), mwi_event_cb(), mwi_sub_event_cb(), mwi_unsub_event_cb(), process_collection(), sip_send_mwi_to_peer(), unistim_send_mwi_to_peer(), and update_registry().

{
   const uint32_t *ie_val;

   ie_val = ast_event_get_ie_raw(event, ie_type);

   return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0;
}

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 295 of file event.c.

References ast_event::event_len.

Referenced by ast_event_cb(), and ast_event_dup().

{
   size_t res;

   res = ntohs(event->event_len);

   return res;
}

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 858 of file event.c.

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

{
   return ntohs(event->type);
}

const char* ast_event_get_type_name ( const struct ast_event event  ) 

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

  • event the event to get the type of
Returns:
the string representation of the event type of the provided event
Since:
1.6.1

Definition at line 221 of file event.c.

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

{
   enum ast_event_type type;

   type = ast_event_get_type(event);

   if (type >= AST_EVENT_TOTAL || type < 0) {
      ast_log(LOG_ERROR, "Invalid event type - '%d'\n", type);
      return "";
   }

   return event_names[type].name;
}

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

Definition at line 1272 of file event.c.

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

Referenced by ast_event_init().

{
   const struct ast_event_ref *event_ref;
   const struct ast_event *event;
   ao2_hash_fn *hash_fn;

   event_ref = obj;
   event = event_ref->event;

   if (!(hash_fn = ast_event_cache[ast_event_get_type(event)].hash_fn)) {
      return 0;
   }

   return hash_fn(event, flags);
}

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

Definition at line 1249 of file event.c.

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

{
   const struct ast_event *event = obj;

   return ast_str_hash(ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE));
}

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

Definition at line 1265 of file event.c.

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

{
   const struct ast_event *event = obj;

   return ast_str_hash(ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE));
}

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

Definition at line 1231 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.

{
   const struct ast_event *event = obj;
   const char *mailbox = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX);
   const char *context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT);

   return ast_str_hash_add(context, ast_str_hash(mailbox));
}

static void ast_event_ie_val_destroy ( struct ast_event_ie_val ie_val  )  [static]
int ast_event_init ( void   ) 

Provided by event.c

Definition at line 1337 of file event.c.

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

Referenced by main().

{
   int i;

   for (i = 0; i < AST_EVENT_TOTAL; i++) {
      AST_RWDLLIST_HEAD_INIT(&ast_event_subs[i]);
   }

   for (i = 0; i < AST_EVENT_TOTAL; i++) {
      if (!ast_event_cache[i].hash_fn) {
         /* This event type is not cached. */
         continue;
      }

      if (!(ast_event_cache[i].container = ao2_container_alloc(NUM_CACHE_BUCKETS,
            ast_event_hash, ast_event_cmp))) {
         return -1;
      }
   }

   if (!(event_dispatcher = ast_taskprocessor_get("core_event_dispatcher", 0))) {
      return -1;
   }

   return 0;
}

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 853 of file event.c.

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

Referenced by ast_event_get_ie_raw().

{
   return iterator->ie->ie_payload;
}

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 844 of file event.c.

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

{
   const struct ast_event_ie_str_payload *str_payload;

   str_payload = (struct ast_event_ie_str_payload *) iterator->ie->ie_payload;

   return str_payload ? str_payload->str : NULL;
}

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 834 of file event.c.

References ast_event_iterator::ie.

Referenced by ast_event_get_ie_raw().

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

uint32_t ast_event_iterator_get_ie_uint ( struct ast_event_iterator iterator  ) 

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

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

Definition at line 839 of file event.c.

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

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

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 812 of file event.c.

References ast_event_iterator::event, ast_event::event_len, ast_event_iterator::event_len, and ast_event_iterator::ie.

Referenced by ast_event_get_ie_raw().

{
   int res = 0;

   iterator->event_len = ntohs(event->event_len);
   iterator->event = event;
   if (iterator->event_len >= sizeof(*event) + sizeof(struct ast_event_ie)) {
      iterator->ie = (struct ast_event_ie *) ( ((char *) event) + sizeof(*event) );
   } else {
      iterator->ie = NULL;
      res = -1;
   }

   return res;
}

int ast_event_iterator_next ( struct ast_event_iterator iterator  ) 

Move iterator instance to next IE.

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

Definition at line 828 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().

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

struct ast_event* ast_event_new ( enum ast_event_type  event_type,
  ... 
) [read]

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:

    <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. 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.

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 949 of file event.c.

References ast_calloc, ast_eid_default, 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_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_strdupa, ast_event_ie_val::ie_pltype, ast_event_ie_val::ie_type, 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 ast_event_get_cached(), ast_event_unsubscribe(), devstate_event(), gen_sub_event(), handle_request_notify(), notify_message(), process_collection(), and queue_mwi_event().

{
   va_list ap;
   struct ast_event *event;
   enum ast_event_ie_type ie_type;
   struct ast_event_ie_val *ie_val;
   AST_LIST_HEAD_NOLOCK_STATIC(ie_vals, ast_event_ie_val);

   /* Invalid type */
   if (type >= AST_EVENT_TOTAL) {
      ast_log(LOG_WARNING, "Someone tried to create an event of invalid "
         "type '%d'!\n", type);
      return NULL;
   }

   va_start(ap, type);
   for (ie_type = va_arg(ap, enum ast_event_ie_type);
      ie_type != AST_EVENT_IE_END;
      ie_type = va_arg(ap, enum ast_event_ie_type))
   {
      struct ast_event_ie_val *ie_value = alloca(sizeof(*ie_value));
      memset(ie_value, 0, sizeof(*ie_value));
      ie_value->ie_type = ie_type;
      ie_value->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
      if (ie_value->ie_pltype == AST_EVENT_IE_PLTYPE_UINT)
         ie_value->payload.uint = va_arg(ap, uint32_t);
      else if (ie_value->ie_pltype == AST_EVENT_IE_PLTYPE_STR)
         ie_value->payload.str = ast_strdupa(va_arg(ap, const char *));
      else if (ie_value->ie_pltype == AST_EVENT_IE_PLTYPE_RAW) {
         void *data = va_arg(ap, void *);
         size_t datalen = va_arg(ap, size_t);
         ie_value->payload.raw = alloca(datalen);
         memcpy(ie_value->payload.raw, data, datalen);
         ie_value->raw_datalen = datalen;
      }
      AST_LIST_INSERT_TAIL(&ie_vals, ie_value, entry);
   }
   va_end(ap);

   if (!(event = ast_calloc(1, sizeof(*event))))
      return NULL;

   event->type = htons(type);
   event->event_len = htons(sizeof(*event));

   AST_LIST_TRAVERSE(&ie_vals, ie_val, entry) {
      if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR)
         ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str);
      else if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_UINT)
         ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
      else if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_RAW)
         ast_event_append_ie_raw(&event, ie_val->ie_type, ie_val->payload.raw, ie_val->raw_datalen);

      if (!event)
         break;
   }

   if (!ast_event_get_ie_raw(event, AST_EVENT_IE_EID)) {
      /* If the event is originating on this server, add the server's
       * entity ID to the event. */
      ast_event_append_ie_raw(&event, AST_EVENT_IE_EID, &ast_eid_default, sizeof(ast_eid_default));
   }

   return event;
}

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 1201 of file event.c.

References alloc_event_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, handle_event(), and LOG_WARNING.

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

{
   struct ast_event_ref *event_ref;
   uint16_t host_event_type;

   host_event_type = ntohs(event->type);

   /* Invalid type */
   if (host_event_type >= AST_EVENT_TOTAL) {
      ast_log(LOG_WARNING, "Someone tried to queue an event of invalid "
         "type '%d'!\n", host_event_type);
      return -1;
   }

   /* If nobody has subscribed to this event type, throw it away now */
   if (ast_event_check_subscriber(host_event_type, AST_EVENT_IE_END)
         == AST_EVENT_SUB_NONE) {
      ast_event_destroy(event);
      return 0;
   }

   if (!(event_ref = alloc_event_ref())) {
      return -1;
   }

   event_ref->event = event;

   return ast_taskprocessor_push(event_dispatcher, handle_event, event_ref);
}

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. If failure is returned, the event must be destroyed by the caller of this function.

Definition at line 1146 of file event.c.

References ao2_callback, ast_event_cache, ast_event_cmp(), ast_event_dup_and_cache(), ast_event_get_type(), ast_event_queue(), ast_log(), container, ast_event_ref::event, LOG_WARNING, OBJ_MULTIPLE, OBJ_NODATA, OBJ_POINTER, OBJ_UNLINK, and queue_event().

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

{
   struct ao2_container *container;
   struct ast_event_ref tmp_event_ref = {
      .event = event,
   };
   int res = -1;

   if (!(container = ast_event_cache[ast_event_get_type(event)].container)) {
      ast_log(LOG_WARNING, "cache requested for non-cached event type\n");
      goto queue_event;
   }

   /* Remove matches from the cache */
   ao2_callback(container, OBJ_POINTER | OBJ_UNLINK | OBJ_MULTIPLE | OBJ_NODATA,
         ast_event_cmp, &tmp_event_ref);

   res = ast_event_dup_and_cache(event);

queue_event:
   return ast_event_queue(event) ? -1 : res;
}

static void ast_event_ref_destroy ( void *  obj  )  [static]

Definition at line 1020 of file event.c.

References ast_event_destroy(), and ast_event_ref::event.

Referenced by alloc_event_ref().

{
   struct ast_event_ref *event_ref = obj;

   ast_event_destroy(event_ref->event);
}

void ast_event_report_subs ( const struct ast_event_sub event_sub  ) 

Send AST_EVENT_SUB events to this subscriber of ... subscriber events.

Report current subscriptions to a subscription subscriber.

Definition at line 553 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, 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 start_poll_thread().

{
   struct ast_event *event;
   struct ast_event_sub *sub;
   enum ast_event_type event_type = -1;
   struct ast_event_ie_val *ie_val;

   if (event_sub->type != AST_EVENT_SUB)
      return;

   AST_LIST_TRAVERSE(&event_sub->ie_vals, ie_val, entry) {
      if (ie_val->ie_type == AST_EVENT_IE_EVENTTYPE) {
         event_type = ie_val->payload.uint;
         break;
      }
   }

   if (event_type == -1)
      return;

   AST_RWDLLIST_RDLOCK(&ast_event_subs[event_type]);
   AST_RWDLLIST_TRAVERSE(&ast_event_subs[event_type], sub, entry) {
      if (event_sub == sub)
         continue;

      event = gen_sub_event(sub);

      if (!event)
         continue;

      event_sub->cb(event, event_sub->userdata);

      ast_event_destroy(event);
   }
   AST_RWDLLIST_UNLOCK(&ast_event_subs[event_type]);
}

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 235 of file event.c.

References ARRAY_LEN, event_names, name, and event_name::type.

{
   int i;

   for (i = 0; i < ARRAY_LEN(event_names); i++) {
      if (strcasecmp(event_names[i].name, str))
         continue;

      *event_type = event_names[i].type;
      return 0;
   }

   return -1;
}

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 280 of file event.c.

References ARRAY_LEN, ie_maps, ie_map::ie_type, and name.

{
   int i;

   for (i = 0; i < ARRAY_LEN(ie_maps); i++) {
      if (strcasecmp(ie_maps[i].name, str))
         continue;

      *ie_type = ie_maps[i].ie_type;
      return 0;
   }

   return -1;
}

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 703 of file event.c.

References ast_event_check_subscriber(), 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().

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 631 of file event.c.

References ast_calloc, AST_EVENT_IE_MAX, AST_LIST_INSERT_TAIL, ast_event_ie_val::ie_pltype, ast_event_ie_val::ie_type, and ast_event_sub::ie_vals.

Referenced by ast_event_subscribe().

{
   struct ast_event_ie_val *ie_val;

   if (ie_type < 0 || ie_type > AST_EVENT_IE_MAX)
      return -1;

   if (!(ie_val = ast_calloc(1, sizeof(*ie_val))))
      return -1;

   ie_val->ie_type = ie_type;
   ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_EXISTS;

   AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);

   return 0;
}

int ast_event_sub_append_ie_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
raw the data 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 676 of file event.c.

References ast_calloc, AST_EVENT_IE_MAX, ast_free, AST_LIST_INSERT_TAIL, ast_malloc, 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, and ast_event_ie_val::raw_datalen.

Referenced by ast_event_subscribe().

{
   struct ast_event_ie_val *ie_val;

   if (ie_type < 0 || ie_type > AST_EVENT_IE_MAX)
      return -1;

   if (!(ie_val = ast_calloc(1, sizeof(*ie_val))))
      return -1;

   ie_val->ie_type = ie_type;
   ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_RAW;
   ie_val->raw_datalen = raw_datalen;

   if (!(ie_val->payload.raw = ast_malloc(raw_datalen))) {
      ast_free(ie_val);
      return -1;
   }

   memcpy(ie_val->payload.raw, data, raw_datalen);

   AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);

   return 0;
}

int ast_event_sub_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 650 of file event.c.

References ast_calloc, AST_EVENT_IE_MAX, ast_free, AST_LIST_INSERT_TAIL, ast_str_hash(), ast_strdup, ast_event_ie_val::hash, ast_event_ie_val::ie_pltype, ast_event_ie_val::ie_type, ast_event_sub::ie_vals, ast_event_ie_val::payload, and ast_event_ie_val::str.

Referenced by ast_event_subscribe(), and handle_devstate_change().

{
   struct ast_event_ie_val *ie_val;

   if (ie_type < 0 || ie_type > AST_EVENT_IE_MAX)
      return -1;

   if (!(ie_val = ast_calloc(1, sizeof(*ie_val))))
      return -1;

   ie_val->ie_type = ie_type;
   ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_STR;

   if (!(ie_val->payload.str = ast_strdup(str))) {
      ast_free(ie_val);
      return -1;
   }

   ie_val->payload.hash = ast_str_hash(str);

   AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);

   return 0;
}

int ast_event_sub_append_ie_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 611 of file event.c.

References ast_calloc, AST_EVENT_IE_MAX, AST_LIST_INSERT_TAIL, ast_event_ie_val::ie_pltype, ast_event_ie_val::ie_type, ast_event_sub::ie_vals, ast_event_ie_val::payload, and ast_event_ie_val::uint.

Referenced by ast_event_subscribe().

{
   struct ast_event_ie_val *ie_val;

   if (ie_type < 0 || ie_type > AST_EVENT_IE_MAX)
      return -1;

   if (!(ie_val = ast_calloc(1, sizeof(*ie_val))))
      return -1;

   ie_val->ie_type = ie_type;
   ie_val->payload.uint = unsigned_int;
   ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_UINT;

   AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);

   return 0;
}

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 776 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(), and handle_devstate_change().

{
   struct ast_event_ie_val *ie_val;

   while ((ie_val = AST_LIST_REMOVE_HEAD(&sub->ie_vals, entry)))
      ast_event_ie_val_destroy(ie_val);

   ast_free(sub);
}

struct ast_event_sub* ast_event_subscribe ( enum ast_event_type  event_type,
ast_event_cb_t  cb,
void *  userdata,
  ... 
) [read]

Subscribe to events.

Parameters:
event_type The type of events to subscribe to
cb The function to be called with events
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:

    <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 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.

Definition at line 723 of file event.c.

References 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_exists(), ast_event_sub_append_ie_raw(), ast_event_sub_append_ie_str(), ast_event_sub_append_ie_uint(), ast_event_subscribe_new(), and str.

Referenced by add_peer_mwi_subs(), add_publish_event(), ast_enable_distributed_devstate(), build_gateway(), build_peer(), config_line(), load_module(), load_pbx(), mkintf(), and start_poll_thread().

{
   va_list ap;
   enum ast_event_ie_type ie_type;
   struct ast_event_sub *sub;

   if (!(sub = ast_event_subscribe_new(type, cb, userdata)))
      return NULL;

   va_start(ap, userdata);
   for (ie_type = va_arg(ap, enum ast_event_ie_type);
      ie_type != AST_EVENT_IE_END;
      ie_type = va_arg(ap, enum ast_event_ie_type))
   {
      enum ast_event_ie_pltype ie_pltype;

      ie_pltype = va_arg(ap, enum ast_event_ie_pltype);

      switch (ie_pltype) {
      case AST_EVENT_IE_PLTYPE_UNKNOWN:
         break;
      case AST_EVENT_IE_PLTYPE_UINT:
      {
         uint32_t unsigned_int = va_arg(ap, uint32_t);
         ast_event_sub_append_ie_uint(sub, ie_type, unsigned_int);
         break;
      }
      case AST_EVENT_IE_PLTYPE_STR:
      {
         const char *str = va_arg(ap, const char *);
         ast_event_sub_append_ie_str(sub, ie_type, str);
         break;
      }
      case AST_EVENT_IE_PLTYPE_RAW:
      {
         void *data = va_arg(ap, void *);
         size_t data_len = va_arg(ap, size_t);
         ast_event_sub_append_ie_raw(sub, ie_type, data, data_len);
         break;
      }
      case AST_EVENT_IE_PLTYPE_EXISTS:
         ast_event_sub_append_ie_exists(sub, ie_type);
         break;
      }
   }
   va_end(ap);

   ast_event_sub_activate(sub);

   return sub;
}

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

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 590 of file event.c.

References ast_atomic_fetchadd_int(), ast_calloc, ast_log(), ast_event_sub::cb, LOG_ERROR, ast_event_sub::type, ast_event_sub::uniqueid, and ast_event_sub::userdata.

Referenced by ast_event_subscribe(), and handle_devstate_change().

{
   struct ast_event_sub *sub;

   if (type < 0 || type >= AST_EVENT_TOTAL) {
      ast_log(LOG_ERROR, "%u is an invalid type!\n", type);
      return NULL;
   }

   if (!(sub = ast_calloc(1, sizeof(*sub))))
      return NULL;

   sub->type = type;
   sub->cb = cb;
   sub->userdata = userdata;
   sub->uniqueid = ast_atomic_fetchadd_int((int *) &sub_uniqueid, 1);

   return sub;
}

struct ast_event_sub* ast_event_unsubscribe ( struct ast_event_sub event_sub  )  [read]
static int dump_cache_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 487 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().

{
   const struct ast_event_ref *event_ref = obj;
   const struct ast_event *event = event_ref->event;
   const struct ast_event_sub *event_sub = arg;
   struct ast_event_ie_val *ie_val = NULL;

   AST_LIST_TRAVERSE(&event_sub->ie_vals, ie_val, entry) {
      if (!match_ie_val(event, ie_val, NULL)) {
         break;
      }
   }

   if (!ie_val) {
      /* All parameters were matched on this cache entry, so dump it */
      event_sub->cb(event, event_sub->userdata);
   }

   return 0;
}

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

Definition at line 515 of file event.c.

References ast_event_append_ie_raw(), ast_event_append_ie_str(), ast_event_append_ie_uint(), AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_EXISTS, 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_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().

{
   struct ast_event_ie_val *ie_val;
   struct ast_event *event;

   event = ast_event_new(AST_EVENT_SUB,
      AST_EVENT_IE_UNIQUEID,  AST_EVENT_IE_PLTYPE_UINT, sub->uniqueid,
      AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, sub->type,
      AST_EVENT_IE_END);

   if (!event)
      return NULL;

   AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
      switch (ie_val->ie_pltype) {
      case AST_EVENT_IE_PLTYPE_UNKNOWN:
         break;
      case AST_EVENT_IE_PLTYPE_EXISTS:
         ast_event_append_ie_uint(&event, AST_EVENT_IE_EXISTS, ie_val->ie_type);
         break;
      case AST_EVENT_IE_PLTYPE_UINT:
         ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
         break;
      case AST_EVENT_IE_PLTYPE_STR:
         ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str);
         break;
      case AST_EVENT_IE_PLTYPE_RAW:
         ast_event_append_ie_raw(&event, ie_val->ie_type, ie_val->payload.raw, ie_val->raw_datalen);
         break;
      }
      if (!event)
         break;
   }

   return event;
}

static int handle_event ( void *  data  )  [static]

Definition at line 1169 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.

Referenced by ast_event_queue().

{
   struct ast_event_ref *event_ref = data;
   struct ast_event_sub *sub;
   const enum ast_event_type event_types[] = {
      ntohs(event_ref->event->type),
      AST_EVENT_ALL
   };
   int i;

   for (i = 0; i < ARRAY_LEN(event_types); i++) {
      AST_RWDLLIST_RDLOCK(&ast_event_subs[event_types[i]]);
      AST_RWDLLIST_TRAVERSE(&ast_event_subs[event_types[i]], sub, entry) {
         struct ast_event_ie_val *ie_val;
         AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
            if (!match_ie_val(event_ref->event, ie_val, NULL)) {
               break;
            }
         }
         if (ie_val) {
            continue;
         }
         sub->cb(event_ref->event, sub->userdata);
      }
      AST_RWDLLIST_UNLOCK(&ast_event_subs[event_types[i]]);
   }

   ao2_ref(event_ref, -1);

   return 0;
}

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 444 of file event.c.

References ast_event_get_ie_raw(), ast_event_get_ie_str(), ast_event_get_ie_str_hash(), ast_event_get_ie_uint(), AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, buf, 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().

{
   if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_UINT) {
      uint32_t val = event2 ? ast_event_get_ie_uint(event2, ie_val->ie_type) : ie_val->payload.uint;
      if (val == ast_event_get_ie_uint(event, ie_val->ie_type))
         return 1;
      return 0;
   }

   if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR) {
      const char *str;
      uint32_t hash;

      hash = event2 ? ast_event_get_ie_str_hash(event2, ie_val->ie_type) : ie_val->payload.hash;
      if (hash != ast_event_get_ie_str_hash(event, ie_val->ie_type)) {
         return 0;
      }

      str = event2 ? ast_event_get_ie_str(event2, ie_val->ie_type) : ie_val->payload.str;
      if (str && !strcmp(str, ast_event_get_ie_str(event, ie_val->ie_type))) {
         return 1;
      }

      return 0;
   }

   if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_RAW) {
      const void *buf = event2 ? ast_event_get_ie_raw(event2, ie_val->ie_type) : ie_val->payload.raw;
      if (buf && !memcmp(buf, ast_event_get_ie_raw(event, ie_val->ie_type), ie_val->raw_datalen))
         return 1;
      return 0;
   }

   if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_EXISTS) {
      if (ast_event_get_ie_raw(event, ie_val->ie_type))
         return 1;
      return 0;
   }

   return 0;
}

static int match_ie_val_to_sub ( const struct ast_event_sub sub,
const struct ast_event_ie_val ie_val 
) [static]

Definition at line 332 of file event.c.

References 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_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, and ast_event_ie_val::uint.

Referenced by ast_event_check_subscriber().

{
   const struct ast_event_ie_val *sub_ie_val;
   int res = 1;

   AST_LIST_TRAVERSE(&sub->ie_vals, sub_ie_val, entry) {
      if (sub_ie_val->ie_type == ie_val->ie_type) {
         break;
      }
   }

   if (!sub_ie_val) {
      /* This subscriber doesn't care about this IE, so consider
       * it matched. */
      return 1;
   }

   switch (ie_val->ie_pltype) {
   case AST_EVENT_IE_PLTYPE_UINT:
      res = (ie_val->payload.uint != sub_ie_val->payload.uint);
      break;
   case AST_EVENT_IE_PLTYPE_STR:
      res = strcmp(ie_val->payload.str, sub_ie_val->payload.str);
      break;
   case AST_EVENT_IE_PLTYPE_RAW:
      res = memcmp(ie_val->payload.raw,
            sub_ie_val->payload.raw, ie_val->raw_datalen);
      break;
   case AST_EVENT_IE_PLTYPE_EXISTS:
   case AST_EVENT_IE_PLTYPE_UNKNOWN:
      break;
   }

   return res;
}


Variable Documentation

struct { ... } ast_event_cache[AST_EVENT_TOTAL] [static]
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 168 of file event.c.

Referenced by ast_event_cmp().

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 157 of file event.c.

Referenced by ast_event_dup_and_cache(), ast_event_get_cached(), ast_event_init(), and ast_event_queue_and_cache().

Definition at line 42 of file event.c.

struct event_name event_names[] [static]

The index of each entry _must_ match the event type number!

Referenced by ast_event_get_type_name(), and ast_event_str_to_event_type().

Event type specific hash function.

Definition at line 159 of file event.c.

Referenced by ast_event_hash(), and ast_event_init().

struct ie_map ie_maps[] [static]

The index of each entry _must_ match the event ie number!

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 128 of file event.c.