Thu Jul 9 13:41:17 2009

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/lock.h"
#include "asterisk/utils.h"
#include "asterisk/unaligned.h"

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_val
struct  ast_event_iterator
struct  ast_event_ref
struct  ast_event_ref_list
 Cached events The event cache is indexed on the event type. The purpose of this is for events that express some sort of state. So, when someone first needs to know this state, it can get the last known state from the cache. 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...

Defines

#define NUM_EVENT_THREADS   1

Functions

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.
void ast_event_destroy (struct ast_event *event)
 Destroy an event.
static void * ast_event_dispatcher (void *unused)
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.
ast_eventast_event_get_cached (enum ast_event_type type,...)
 Retrieve an event from the cache.
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_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.
enum ast_event_type ast_event_get_type (const struct ast_event *event)
 Get the type for an event.
static void ast_event_ie_val_destroy (struct ast_event_ie_val *ie_val)
void 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.
void 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.
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 (struct ast_event_ref *event_ref)
void ast_event_report_subs (const struct ast_event_sub *event_sub)
 Report current subscriptions to a subscription subscriber.
static void ast_event_sub_destroy (struct ast_event_sub *sub)
ast_event_subast_event_subscribe (enum ast_event_type type, ast_event_cb_t cb, void *userdata,...)
 Subscribe to events.
void ast_event_unsubscribe (struct ast_event_sub *sub)
 Un-subscribe from events.

Variables

static struct ast_event_ref_list ast_event_cache [AST_EVENT_TOTAL]
 Cached events The event cache is indexed on the event type. The purpose of this is for events that express some sort of state. So, when someone first needs to know this state, it can get the last known state from 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_cond_t   cond
   struct {
      ast_event_ref *   first
      ast_event_ref *   last
   }   event_q
   ast_mutex_t   lock
event_thread
 data shared between event dispatching threads
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 NUM_EVENT_THREADS   1

Definition at line 38 of file event.c.

Referenced by ast_event_init().


Function Documentation

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

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

Referenced by ast_event_append_ie_str(), and ast_event_append_ie_uint().

00456 {
00457    struct ast_event_ie *ie;
00458    unsigned int extra_len;
00459    uint16_t event_len;
00460 
00461    event_len = ntohs((*event)->event_len);
00462    extra_len = sizeof(*ie) + data_len;
00463 
00464    if (!(*event = ast_realloc(*event, event_len + extra_len)))
00465       return -1;
00466 
00467    ie = (struct ast_event_ie *) ( ((char *) *event) + event_len );
00468    ie->ie_type = htons(ie_type);
00469    ie->ie_payload_len = htons(data_len);
00470    memcpy(ie->ie_payload, data, data_len);
00471 
00472    (*event)->event_len = htons(event_len + extra_len);
00473 
00474    return 0;
00475 }

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

References ast_event_append_ie_raw(), and ast_event_ref::event.

Referenced by ast_event_new(), ast_event_report_subs(), and ast_event_subscribe().

00443 {
00444    return ast_event_append_ie_raw(event, ie_type, str, strlen(str) + 1);
00445 }

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

References ast_event_append_ie_raw(), and ast_event_ref::event.

Referenced by ast_event_new(), ast_event_report_subs(), and ast_event_subscribe().

00449 {
00450    data = htonl(data);
00451    return ast_event_append_ie_raw(event, ie_type, &data, sizeof(data));
00452 }

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

References AST_EVENT_ALL, AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_SUB_EXISTS, AST_EVENT_SUB_NONE, ast_event_subs, AST_EVENT_TOTAL, AST_LIST_EMPTY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, ast_event_ref::entry, ast_event_ie_val::ie_pltype, ast_event_ie_val::ie_type, ast_event_sub::ie_vals, LOG_ERROR, ast_event_ie_val::payload, ast_event_ie_val::str, and ast_event_ie_val::uint.

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

00136 {
00137    va_list ap;
00138    enum ast_event_ie_type ie_type;
00139    enum ast_event_subscriber_res res = AST_EVENT_SUB_NONE;
00140    struct ast_event_ie_val *ie_val, *sub_ie_val;
00141    struct ast_event_sub *sub;
00142    AST_LIST_HEAD_NOLOCK_STATIC(ie_vals, ast_event_ie_val);
00143 
00144    if (type >= AST_EVENT_TOTAL) {
00145       ast_log(LOG_ERROR, "%u is an invalid type!\n", type);
00146       return res;
00147    }
00148 
00149    va_start(ap, type);
00150    for (ie_type = va_arg(ap, enum ast_event_type);
00151       ie_type != AST_EVENT_IE_END;
00152       ie_type = va_arg(ap, enum ast_event_type))
00153    {
00154       struct ast_event_ie_val *ie_val = alloca(sizeof(*ie_val));
00155       memset(ie_val, 0, sizeof(*ie_val));
00156       ie_val->ie_type = ie_type;
00157       ie_val->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
00158       if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_UINT)
00159          ie_val->payload.uint = va_arg(ap, uint32_t);
00160       else if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR)
00161          ie_val->payload.str = ast_strdupa(va_arg(ap, const char *));
00162       AST_LIST_INSERT_TAIL(&ie_vals, ie_val, entry);
00163    }
00164    va_end(ap);
00165 
00166    AST_RWLIST_RDLOCK(&ast_event_subs[type]);
00167    AST_RWLIST_TRAVERSE(&ast_event_subs[type], sub, entry) {
00168       AST_LIST_TRAVERSE(&ie_vals, ie_val, entry) {
00169          AST_LIST_TRAVERSE(&sub->ie_vals, sub_ie_val, entry) {
00170             if (sub_ie_val->ie_type == ie_val->ie_type)
00171                break;
00172          }
00173          if (!sub_ie_val) {
00174             if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_EXISTS)
00175                break;
00176             continue;
00177          }
00178          /* The subscriber doesn't actually care what the value is */
00179          if (sub_ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_EXISTS)
00180             continue;
00181          if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_UINT &&
00182             ie_val->payload.uint != sub_ie_val->payload.uint)
00183             break;
00184          if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR &&
00185             strcmp(ie_val->payload.str, sub_ie_val->payload.str))
00186             break;
00187       }
00188       if (!ie_val)
00189          break;
00190    }
00191    AST_RWLIST_UNLOCK(&ast_event_subs[type]);
00192 
00193    if (sub) /* All parameters were matched */
00194       return AST_EVENT_SUB_EXISTS;
00195 
00196    AST_RWLIST_RDLOCK(&ast_event_subs[AST_EVENT_ALL]);
00197    if (!AST_LIST_EMPTY(&ast_event_subs[AST_EVENT_ALL]))
00198       res = AST_EVENT_SUB_EXISTS;
00199    AST_RWLIST_UNLOCK(&ast_event_subs[AST_EVENT_ALL]);
00200 
00201    return res;
00202 }

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

References ast_free, and ast_event_ref::event.

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

00529 {
00530    ast_free(event);
00531 }

static void* ast_event_dispatcher ( void *  unused  )  [static]

Definition at line 753 of file event.c.

References ast_cond_wait(), AST_EVENT_ALL, ast_event_get_ie_raw(), ast_event_get_ie_str(), ast_event_get_ie_uint(), AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, ast_event_ref_destroy(), ast_event_subs, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_event_sub::cb, ast_event_ref::entry, event_thread, 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::str, ast_event_ie_val::uint, and ast_event_sub::userdata.

Referenced by ast_event_init().

00754 {
00755    for (;;) {
00756       struct ast_event_ref *event_ref;
00757       struct ast_event_sub *sub;
00758       uint16_t host_event_type;
00759 
00760       ast_mutex_lock(&event_thread.lock);
00761       while (!(event_ref = AST_LIST_REMOVE_HEAD(&event_thread.event_q, entry)))
00762          ast_cond_wait(&event_thread.cond, &event_thread.lock);
00763       ast_mutex_unlock(&event_thread.lock);
00764 
00765       host_event_type = ntohs(event_ref->event->type);
00766 
00767       /* Subscribers to this specific event first */
00768       AST_RWLIST_RDLOCK(&ast_event_subs[host_event_type]);
00769       AST_RWLIST_TRAVERSE(&ast_event_subs[host_event_type], sub, entry) {
00770          struct ast_event_ie_val *ie_val;
00771          AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
00772             if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_EXISTS &&
00773                ast_event_get_ie_raw(event_ref->event, ie_val->ie_type)) {
00774                continue;
00775             } else if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_UINT &&
00776                ast_event_get_ie_uint(event_ref->event, ie_val->ie_type) 
00777                == ie_val->payload.uint) {
00778                continue;
00779             } else if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR &&
00780                !strcmp(ast_event_get_ie_str(event_ref->event, ie_val->ie_type),
00781                   ie_val->payload.str)) {
00782                continue;
00783             }
00784             break;
00785          }
00786          if (ie_val)
00787             continue;
00788          sub->cb(event_ref->event, sub->userdata);
00789       }
00790       AST_RWLIST_UNLOCK(&ast_event_subs[host_event_type]);
00791 
00792       /* Now to subscribers to all event types */
00793       AST_RWLIST_RDLOCK(&ast_event_subs[AST_EVENT_ALL]);
00794       AST_RWLIST_TRAVERSE(&ast_event_subs[AST_EVENT_ALL], sub, entry)
00795          sub->cb(event_ref->event, sub->userdata);
00796       AST_RWLIST_UNLOCK(&ast_event_subs[AST_EVENT_ALL]);
00797 
00798       ast_event_ref_destroy(event_ref);
00799    }
00800 
00801    return NULL;
00802 }

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

Definition at line 539 of file event.c.

References ast_calloc, ast_event_ref::event, and ast_event::event_len.

Referenced by ast_event_dup_and_cache(), and ast_event_get_cached().

00540 {
00541    struct ast_event *dup_event;
00542    uint16_t event_len;
00543 
00544    event_len = ntohs(event->event_len);
00545 
00546    if (!(dup_event = ast_calloc(1, event_len)))
00547       return NULL;
00548    
00549    memcpy(dup_event, event, event_len);
00550 
00551    return dup_event;
00552 }

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

References ast_calloc, ast_event_cache, ast_event_dup(), AST_LIST_INSERT_TAIL, ast_event_ref::entry, and ast_event_ref::event.

Referenced by ast_event_queue_and_cache().

00631 {
00632    struct ast_event *dup_event;
00633    struct ast_event_ref *event_ref;
00634 
00635    if (!(dup_event = ast_event_dup(event)))
00636       return -1;
00637    if (!(event_ref = ast_calloc(1, sizeof(*event_ref))))
00638       return -1;
00639    
00640    event_ref->event = dup_event;
00641 
00642    AST_LIST_INSERT_TAIL(&ast_event_cache[ntohs(event->type)], event_ref, entry);
00643 
00644    return 0;
00645 }

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

References ast_event_cache, ast_event_dup(), ast_event_get_ie_raw(), ast_event_get_ie_str(), ast_event_get_ie_uint(), AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_TOTAL, AST_LIST_EMPTY, AST_LIST_ENTRY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, ast_strdupa, ast_event_ref::entry, ast_event_ref::event, LOG_ERROR, and str.

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

00555 {
00556    va_list ap;
00557    enum ast_event_ie_type ie_type;
00558    struct ast_event *dup_event = NULL;
00559    struct ast_event_ref *event_ref;
00560    struct cache_arg {
00561       AST_LIST_ENTRY(cache_arg) entry;
00562       enum ast_event_ie_type ie_type;
00563       enum ast_event_ie_pltype ie_pltype;
00564       union {
00565          uint32_t uint;
00566          const char *str;
00567       } payload;
00568    } *cache_arg;
00569    AST_LIST_HEAD_NOLOCK_STATIC(cache_args, cache_arg);
00570 
00571    if (type >= AST_EVENT_TOTAL) {
00572       ast_log(LOG_ERROR, "%u is an invalid type!\n", type);
00573       return NULL;
00574    }
00575 
00576    va_start(ap, type);
00577    for (ie_type = va_arg(ap, enum ast_event_type);
00578       ie_type != AST_EVENT_IE_END;
00579       ie_type = va_arg(ap, enum ast_event_type))
00580    {
00581       cache_arg = alloca(sizeof(*cache_arg));
00582       memset(cache_arg, 0, sizeof(*cache_arg));
00583       cache_arg->ie_type = ie_type;
00584       cache_arg->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
00585       if (cache_arg->ie_pltype == AST_EVENT_IE_PLTYPE_UINT)
00586          cache_arg->payload.uint = va_arg(ap, uint32_t);
00587       else if (cache_arg->ie_pltype == AST_EVENT_IE_PLTYPE_STR)
00588          cache_arg->payload.str = ast_strdupa(va_arg(ap, const char *));
00589       AST_LIST_INSERT_TAIL(&cache_args, cache_arg, entry);
00590    }
00591    va_end(ap);
00592 
00593    if (AST_LIST_EMPTY(&cache_args)) {
00594       ast_log(LOG_ERROR, "Events can not be retrieved from the cache without "
00595          "specifying at least one IE type!\n");
00596       return NULL;
00597    }
00598 
00599    AST_RWLIST_RDLOCK(&ast_event_cache[type]);
00600    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&ast_event_cache[type], event_ref, entry) {
00601       AST_LIST_TRAVERSE(&cache_args, cache_arg, entry) {
00602          if ( ! ( (cache_arg->ie_pltype == AST_EVENT_IE_PLTYPE_UINT &&
00603             (cache_arg->payload.uint ==
00604              ast_event_get_ie_uint(event_ref->event, cache_arg->ie_type))) ||
00605 
00606             (cache_arg->ie_pltype == AST_EVENT_IE_PLTYPE_STR &&
00607             (!strcmp(cache_arg->payload.str,
00608               ast_event_get_ie_str(event_ref->event, cache_arg->ie_type)))) ||
00609 
00610             (cache_arg->ie_pltype == AST_EVENT_IE_PLTYPE_EXISTS &&
00611              ast_event_get_ie_raw(event_ref->event, cache_arg->ie_type)) ) ) 
00612          {
00613             break;   
00614          }
00615       }
00616       if (!cache_arg) {
00617          /* All parameters were matched on this cache entry, so return it */
00618          dup_event = ast_event_dup(event_ref->event);
00619          break;
00620       }
00621    }
00622    AST_RWLIST_TRAVERSE_SAFE_END
00623    AST_RWLIST_UNLOCK(&ast_event_cache[type]);
00624 
00625    return dup_event;
00626 }

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 428 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_ref::event.

Referenced by ast_event_dispatcher(), ast_event_get_cached(), ast_event_get_ie_str(), ast_event_get_ie_uint(), and ast_event_queue_and_cache().

00429 {
00430    struct ast_event_iterator iterator;
00431    int res = 0;
00432 
00433    for (ast_event_iterator_init(&iterator, event); !res; res = ast_event_iterator_next(&iterator)) {
00434       if (ast_event_iterator_get_ie_type(&iterator) == ie_type)
00435          return ast_event_iterator_get_ie_raw(&iterator);
00436    }
00437 
00438    return NULL;
00439 }

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

References ast_event_get_ie_raw(), and ast_event_ref::event.

Referenced by ast_event_dispatcher(), ast_event_get_cached(), ast_event_queue_and_cache(), device_state_cb(), and mwi_sub_event_cb().

00424 {
00425    return ast_event_get_ie_raw(event, ie_type);
00426 }

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

References ast_event_get_ie_raw(), ast_event_ref::event, and get_unaligned_uint32().

Referenced by ast_event_dispatcher(), ast_event_get_cached(), ast_event_queue_and_cache(), device_state_cb(), devstate_cached(), get_cached_mwi(), has_voicemail(), mwi_sub_event_cb(), mwi_unsub_event_cb(), sip_send_mwi_to_peer(), unistim_send_mwi_to_peer(), and update_registry().

00415 {
00416    const uint32_t *ie_val;
00417 
00418    ie_val = ast_event_get_ie_raw(event, ie_type);
00419 
00420    return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0;
00421 }

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

References ast_event_ref::event.

Referenced by mwi_sub_event_cb(), and mwi_unsub_event_cb().

00410 {
00411    return ntohs(event->type);
00412 }

static void ast_event_ie_val_destroy ( struct ast_event_ie_val ie_val  )  [static]

Definition at line 127 of file event.c.

References AST_EVENT_IE_PLTYPE_STR, and ast_free.

Referenced by ast_event_sub_destroy().

00128 {
00129    if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR)
00130       ast_free((void *) ie_val->payload.str);
00131 
00132    ast_free(ie_val);
00133 }

void ast_event_init ( void   ) 

Provided by event.c

Definition at line 804 of file event.c.

References ast_cond_init(), ast_event_cache, ast_event_dispatcher(), ast_event_subs, AST_EVENT_TOTAL, ast_pthread_create_background, AST_RWLIST_HEAD_INIT, event_thread, and NUM_EVENT_THREADS.

Referenced by main().

00805 {
00806    int i;
00807 
00808    for (i = 0; i < AST_EVENT_TOTAL; i++)
00809       AST_RWLIST_HEAD_INIT(&ast_event_subs[i]);
00810 
00811    for (i = 0; i < AST_EVENT_TOTAL; i++)
00812       AST_RWLIST_HEAD_INIT(&ast_event_cache[i]);
00813 
00814    ast_cond_init(&event_thread.cond, NULL);
00815 
00816    for (i = 0; i < NUM_EVENT_THREADS; i++) {
00817       pthread_t dont_care;
00818       ast_pthread_create_background(&dont_care, NULL, ast_event_dispatcher, NULL);
00819    }
00820 }

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

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

Referenced by ast_event_get_ie_raw().

00405 {
00406    return iterator->ie->ie_payload;
00407 }

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

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

00400 {
00401    return (const char*)iterator->ie->ie_payload;
00402 }

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

References ast_event_iterator::ie.

Referenced by ast_event_get_ie_raw().

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

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

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

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

void 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
Returns:
Nothing

Definition at line 375 of file event.c.

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

Referenced by ast_event_get_ie_raw().

00376 {
00377    iterator->event_len = ntohs(event->event_len);
00378    iterator->event = event;
00379    iterator->ie = (struct ast_event_ie *) ( ((char *) event) + sizeof(*event) );
00380    return;
00381 }

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 383 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().

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

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

References ast_calloc, ast_event_append_ie_str(), ast_event_append_ie_uint(), AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_TOTAL, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_strdupa, ast_event_ref::entry, ast_event_ref::event, ast_event_ie_val::ie_pltype, ast_event_ie_val::ie_type, LOG_WARNING, ast_event_ie_val::payload, ast_event_ie_val::str, and ast_event_ie_val::uint.

Referenced by ast_event_report_subs(), ast_event_subscribe(), ast_event_unsubscribe(), devstate_event(), notify_message(), and queue_mwi_event().

00478 {
00479    va_list ap;
00480    struct ast_event *event;
00481    enum ast_event_type ie_type;
00482    struct ast_event_ie_val *ie_val;
00483    AST_LIST_HEAD_NOLOCK_STATIC(ie_vals, ast_event_ie_val);
00484 
00485    /* Invalid type */
00486    if (type >= AST_EVENT_TOTAL) {
00487       ast_log(LOG_WARNING, "Someone tried to create an event of invalid "
00488          "type '%d'!\n", type);
00489       return NULL;
00490    }
00491 
00492    va_start(ap, type);
00493    for (ie_type = va_arg(ap, enum ast_event_type);
00494       ie_type != AST_EVENT_IE_END;
00495       ie_type = va_arg(ap, enum ast_event_type))
00496    {
00497       struct ast_event_ie_val *ie_val = alloca(sizeof(*ie_val));
00498       memset(ie_val, 0, sizeof(*ie_val));
00499       ie_val->ie_type = ie_type;
00500       ie_val->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
00501       if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_UINT)
00502          ie_val->payload.uint = va_arg(ap, uint32_t);
00503       else if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR)
00504          ie_val->payload.str = ast_strdupa(va_arg(ap, const char *));
00505       AST_LIST_INSERT_TAIL(&ie_vals, ie_val, entry);
00506    }
00507    va_end(ap);
00508 
00509    if (!(event = ast_calloc(1, sizeof(*event))))
00510       return NULL;
00511 
00512    event->type = htons(type);
00513    event->event_len = htons(sizeof(*event));
00514 
00515    AST_LIST_TRAVERSE(&ie_vals, ie_val, entry) {
00516       if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR)
00517          ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str);
00518       else if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_UINT)
00519          ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
00520 
00521       if (!event)
00522          break;
00523    }
00524 
00525    return event;
00526 }

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
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 a pool of event dispatching threads handle the event queue.

Definition at line 719 of file event.c.

References ast_calloc, ast_cond_signal(), ast_event_check_subscriber(), ast_event_destroy(), AST_EVENT_IE_END, AST_EVENT_SUB_NONE, AST_EVENT_TOTAL, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_event_ref::entry, ast_event_ref::event, event_thread, and LOG_WARNING.

Referenced by ast_event_queue_and_cache(), ast_event_subscribe(), ast_event_unsubscribe(), and devstate_event().

00720 {
00721    struct ast_event_ref *event_ref;
00722    uint16_t host_event_type;
00723 
00724    host_event_type = ntohs(event->type);
00725 
00726    /* Invalid type */
00727    if (host_event_type >= AST_EVENT_TOTAL) {
00728       ast_log(LOG_WARNING, "Someone tried to queue an event of invalid "
00729          "type '%d'!\n", host_event_type);
00730       return -1;
00731    }
00732 
00733    /* If nobody has subscribed to this event type, throw it away now */
00734    if (ast_event_check_subscriber(host_event_type, AST_EVENT_IE_END) 
00735       == AST_EVENT_SUB_NONE) {
00736       ast_event_destroy(event);
00737       return 0;
00738    }
00739 
00740    if (!(event_ref = ast_calloc(1, sizeof(*event_ref))))
00741       return -1;
00742 
00743    event_ref->event = event;
00744 
00745    ast_mutex_lock(&event_thread.lock);
00746    AST_LIST_INSERT_TAIL(&event_thread.event_q, event_ref, entry);
00747    ast_cond_signal(&event_thread.cond);
00748    ast_mutex_unlock(&event_thread.lock);
00749 
00750    return 0;
00751 }

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 rest of the arguments to this function specify information elements to use for determining which events in the cache that this event should replace. All events in the cache that match the specified criteria will be removed from the cache and then this one will be added. The arguments 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 given is EXISTS, then all events that contain that information element will be removed from the cache. Otherwise, all events in the cache that contain an information element with the same value as the new event will be removed.

Note:
If more than one IE parameter is specified, they *all* must match for the event to be removed from the cache.
Example usage:

This example queues and caches an event. Any events in the cache that have the same MAILBOX information element as this event will be removed.

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.

Definition at line 647 of file event.c.

References ast_event_cache, ast_event_dup_and_cache(), ast_event_get_ie_raw(), ast_event_get_ie_str(), ast_event_get_ie_uint(), AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, ast_event_queue(), ast_event_ref_destroy(), AST_EVENT_TOTAL, AST_LIST_EMPTY, AST_LIST_ENTRY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, ast_log(), AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_event_ref::entry, ast_event_ref::event, LOG_ERROR, and LOG_WARNING.

Referenced by devstate_event(), notify_message(), and queue_mwi_event().

00648 {
00649    va_list ap;
00650    enum ast_event_type ie_type;
00651    uint16_t host_event_type;
00652    struct ast_event_ref *event_ref;
00653    int res;
00654    struct cache_arg {
00655       AST_LIST_ENTRY(cache_arg) entry;
00656       enum ast_event_ie_type ie_type;
00657       enum ast_event_ie_pltype ie_pltype;
00658    } *cache_arg;
00659    AST_LIST_HEAD_NOLOCK_STATIC(cache_args, cache_arg);
00660 
00661    host_event_type = ntohs(event->type);
00662 
00663    /* Invalid type */
00664    if (host_event_type >= AST_EVENT_TOTAL) {
00665       ast_log(LOG_WARNING, "Someone tried to queue an event of invalid "
00666          "type '%d'!\n", host_event_type);
00667       return -1;
00668    }
00669 
00670    va_start(ap, event);
00671    for (ie_type = va_arg(ap, enum ast_event_type);
00672       ie_type != AST_EVENT_IE_END;
00673       ie_type = va_arg(ap, enum ast_event_type))
00674    {
00675       cache_arg = alloca(sizeof(*cache_arg));
00676       memset(cache_arg, 0, sizeof(*cache_arg));
00677       cache_arg->ie_type = ie_type;
00678       cache_arg->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
00679       AST_LIST_INSERT_TAIL(&cache_args, cache_arg, entry);
00680    }
00681    va_end(ap);
00682 
00683    if (AST_LIST_EMPTY(&cache_args)) {
00684       ast_log(LOG_ERROR, "Events can not be cached without specifying at "
00685          "least one IE type!\n");
00686       return ast_event_queue(event);
00687    }
00688  
00689    AST_RWLIST_WRLOCK(&ast_event_cache[host_event_type]);
00690    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&ast_event_cache[host_event_type], event_ref, entry) {
00691       AST_LIST_TRAVERSE(&cache_args, cache_arg, entry) {
00692          if ( ! ( (cache_arg->ie_pltype == AST_EVENT_IE_PLTYPE_UINT &&
00693             (ast_event_get_ie_uint(event, cache_arg->ie_type) ==
00694              ast_event_get_ie_uint(event_ref->event, cache_arg->ie_type))) ||
00695 
00696             (cache_arg->ie_pltype == AST_EVENT_IE_PLTYPE_STR &&
00697             (!strcmp(ast_event_get_ie_str(event, cache_arg->ie_type),
00698               ast_event_get_ie_str(event_ref->event, cache_arg->ie_type)))) ||
00699 
00700             (cache_arg->ie_pltype == AST_EVENT_IE_PLTYPE_EXISTS &&
00701              ast_event_get_ie_raw(event_ref->event, cache_arg->ie_type)) ) )
00702          {
00703             break;   
00704          }
00705       }
00706       if (!cache_arg) {
00707          /* All parameters were matched on this cache entry, so remove it */
00708          AST_LIST_REMOVE_CURRENT(entry);
00709          ast_event_ref_destroy(event_ref);
00710       }
00711    }
00712    AST_RWLIST_TRAVERSE_SAFE_END;
00713    res = ast_event_dup_and_cache(event);
00714    AST_RWLIST_UNLOCK(&ast_event_cache[host_event_type]);
00715 
00716    return (ast_event_queue(event) || res) ? -1 : 0;
00717 }

static void ast_event_ref_destroy ( struct ast_event_ref event_ref  )  [static]

Definition at line 533 of file event.c.

References ast_event_destroy(), ast_free, and ast_event_ref::event.

Referenced by ast_event_dispatcher(), and ast_event_queue_and_cache().

00534 {
00535    ast_event_destroy(event_ref->event);
00536    ast_free(event_ref);
00537 }

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

References ast_event_append_ie_str(), ast_event_append_ie_uint(), ast_event_destroy(), AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_EXISTS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_UNIQUEID, ast_event_new(), AST_EVENT_SUB, ast_event_subs, AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_event_sub::cb, ast_event_ref::entry, ast_event_ref::event, 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::str, ast_event_sub::type, ast_event_ie_val::uint, ast_event_sub::uniqueid, and ast_event_sub::userdata.

Referenced by start_poll_thread().

00206 {
00207    struct ast_event *event;
00208    struct ast_event_sub *sub;
00209    enum ast_event_type event_type = -1;
00210    struct ast_event_ie_val *ie_val;
00211 
00212    if (event_sub->type != AST_EVENT_SUB)
00213       return;
00214 
00215    AST_LIST_TRAVERSE(&event_sub->ie_vals, ie_val, entry) {
00216       if (ie_val->ie_type == AST_EVENT_IE_EVENTTYPE) {
00217          event_type = ie_val->payload.uint;
00218          break;
00219       }
00220    }
00221 
00222    if (event_type == -1)
00223       return;
00224 
00225    AST_RWLIST_RDLOCK(&ast_event_subs[event_type]);
00226    AST_RWLIST_TRAVERSE(&ast_event_subs[event_type], sub, entry) {
00227       if (event_sub == sub)
00228          continue;
00229 
00230       event = ast_event_new(AST_EVENT_SUB,
00231          AST_EVENT_IE_UNIQUEID,  AST_EVENT_IE_PLTYPE_UINT, sub->uniqueid,
00232          AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, sub->type,
00233          AST_EVENT_IE_END);
00234 
00235       AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
00236          switch (ie_val->ie_pltype) {
00237          case AST_EVENT_IE_PLTYPE_EXISTS:
00238             ast_event_append_ie_uint(&event, AST_EVENT_IE_EXISTS, ie_val->ie_type);
00239             break;
00240          case AST_EVENT_IE_PLTYPE_UINT:
00241             ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
00242             break;
00243          case AST_EVENT_IE_PLTYPE_STR:
00244             ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str);
00245             break;
00246          }
00247          if (!event)
00248             break;
00249       }
00250 
00251       if (!event)
00252          continue;
00253 
00254       event_sub->cb(event, event_sub->userdata);
00255 
00256       ast_event_destroy(event);
00257    }
00258    AST_RWLIST_UNLOCK(&ast_event_subs[event_type]);
00259 }

static void ast_event_sub_destroy ( struct ast_event_sub sub  )  [static]

Definition at line 341 of file event.c.

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

Referenced by ast_event_unsubscribe().

00342 {
00343    struct ast_event_ie_val *ie_val;
00344 
00345    while ((ie_val = AST_LIST_REMOVE_HEAD(&sub->ie_vals, entry)))
00346       ast_event_ie_val_destroy(ie_val);
00347 
00348    ast_free(sub);
00349 }

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

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

References ast_atomic_fetchadd_int(), ast_calloc, ast_event_append_ie_str(), ast_event_append_ie_uint(), ast_event_check_subscriber(), AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_EXISTS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_UNIQUEID, ast_event_new(), ast_event_queue(), AST_EVENT_SUB, AST_EVENT_SUB_NONE, ast_event_subs, AST_EVENT_TOTAL, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_event_ref::entry, ast_event_ref::event, ast_event_ie_val::ie_pltype, ast_event_ie_val::ie_type, LOG_ERROR, ast_event_ie_val::payload, ast_event_ie_val::str, sub_uniqueid, and ast_event_ie_val::uint.

Referenced by add_peer_mwi_subs(), build_device(), build_gateway(), build_peer(), load_module(), load_pbx(), and start_poll_thread().

00263 {
00264    va_list ap;
00265    enum ast_event_ie_type ie_type;
00266    struct ast_event_sub *sub;
00267    struct ast_event *event;
00268 
00269    if (type >= AST_EVENT_TOTAL) {
00270       ast_log(LOG_ERROR, "%u is an invalid type!\n", type);
00271       return NULL;
00272    }
00273 
00274    if (!(sub = ast_calloc(1, sizeof(*sub))))
00275       return NULL;
00276 
00277    va_start(ap, userdata);
00278    for (ie_type = va_arg(ap, enum ast_event_type);
00279       ie_type != AST_EVENT_IE_END;
00280       ie_type = va_arg(ap, enum ast_event_type))
00281    {
00282       struct ast_event_ie_val *ie_val;
00283       if (!(ie_val = ast_calloc(1, sizeof(*ie_val))))
00284          continue;
00285       ie_val->ie_type = ie_type;
00286       ie_val->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
00287       if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_UINT)
00288          ie_val->payload.uint = va_arg(ap, uint32_t);
00289       else if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR) {
00290          if (!(ie_val->payload.str = ast_strdup(va_arg(ap, const char *)))) {
00291             ast_free(ie_val);
00292             continue;
00293          }
00294       }
00295       AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);
00296    }
00297    va_end(ap);
00298 
00299    sub->type = type;
00300    sub->cb = cb;
00301    sub->userdata = userdata;
00302    sub->uniqueid = ast_atomic_fetchadd_int((int *) &sub_uniqueid, 1);
00303 
00304    if (ast_event_check_subscriber(AST_EVENT_SUB,
00305       AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, type,
00306       AST_EVENT_IE_END) != AST_EVENT_SUB_NONE) {
00307       struct ast_event_ie_val *ie_val;
00308 
00309       event = ast_event_new(AST_EVENT_SUB,
00310          AST_EVENT_IE_UNIQUEID,  AST_EVENT_IE_PLTYPE_UINT, sub->uniqueid,
00311          AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, sub->type,
00312          AST_EVENT_IE_END);
00313 
00314       AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
00315          switch (ie_val->ie_pltype) {
00316          case AST_EVENT_IE_PLTYPE_EXISTS:
00317             ast_event_append_ie_uint(&event, AST_EVENT_IE_EXISTS, ie_val->ie_type);
00318             break;
00319          case AST_EVENT_IE_PLTYPE_UINT:
00320             ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
00321             break;
00322          case AST_EVENT_IE_PLTYPE_STR:
00323             ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str);
00324             break;
00325          }
00326          if (!event)
00327             break;
00328       }
00329 
00330       if (event)
00331          ast_event_queue(event);
00332    }
00333 
00334    AST_RWLIST_WRLOCK(&ast_event_subs[type]);
00335    AST_RWLIST_INSERT_TAIL(&ast_event_subs[type], sub, entry);
00336    AST_RWLIST_UNLOCK(&ast_event_subs[type]);
00337 
00338    return sub;
00339 }

void 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.
Returns:
Nothing

Definition at line 351 of file event.c.

References ast_event_check_subscriber(), AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, 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_LIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_event_ref::entry, ast_event_ref::event, ast_event_sub::type, and ast_event_sub::uniqueid.

Referenced by destroy_dahdi_pvt(), destroy_mailbox(), peer_destructor(), stop_poll_thread(), and unload_module().

00352 {
00353    struct ast_event *event;
00354 
00355    AST_RWLIST_WRLOCK(&ast_event_subs[sub->type]);
00356    AST_LIST_REMOVE(&ast_event_subs[sub->type], sub, entry);
00357    AST_RWLIST_UNLOCK(&ast_event_subs[sub->type]);
00358 
00359    if (ast_event_check_subscriber(AST_EVENT_UNSUB,
00360       AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, sub->type,
00361       AST_EVENT_IE_END) != AST_EVENT_SUB_NONE) {
00362       
00363       event = ast_event_new(AST_EVENT_UNSUB,
00364          AST_EVENT_IE_UNIQUEID,  AST_EVENT_IE_PLTYPE_UINT, sub->uniqueid,
00365          AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, sub->type,
00366          AST_EVENT_IE_END);
00367 
00368       if (event)
00369          ast_event_queue(event);
00370    }
00371 
00372    ast_event_sub_destroy(sub);
00373 }


Variable Documentation

struct ast_event_ref_list ast_event_cache[AST_EVENT_TOTAL] [static]

Cached events The event cache is indexed on the event type. The purpose of this is for events that express some sort of state. So, when someone first needs to know this state, it can get the last known state from the cache.

Referenced by ast_event_dup_and_cache(), ast_event_get_cached(), ast_event_init(), and ast_event_queue_and_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_dispatcher(), ast_event_init(), ast_event_report_subs(), ast_event_subscribe(), and ast_event_unsubscribe().

ast_cond_t cond

Definition at line 88 of file event.c.

Referenced by _macro_exec(), gosubif_exec(), and smdi_message_wait().

struct { ... } event_q

struct { ... } event_thread [static]

data shared between event dispatching threads

Referenced by ast_event_dispatcher(), ast_event_init(), and ast_event_queue().

struct ast_event_ref* first

Definition at line 90 of file event.c.

Referenced by ast_print_group(), context_merge(), h261_encap(), h263_encap(), h263p_encap(), h264_encap(), log_jack_status(), misdn_lib_init(), and mpeg4_encap().

struct ast_event_ref* last

Definition at line 90 of file event.c.

Referenced by aji_handle_presence(), ao2_callback(), apply_outgoing(), ast_config_engine_deregister(), ast_db_freetree(), ast_db_gettree(), config_odbc(), config_pgsql(), do_monitor(), gtalk_free_candidates(), jingle_free_candidates(), load_password(), next_channel(), scan_thread(), and try_firmware().

ast_mutex_t lock

Definition at line 89 of file event.c.

Referenced by dahdi_request(), dahdi_restart(), dahdi_set_swgain(), dahdi_show_channel(), dahdi_show_channels(), load_config(), load_module(), load_rpt_vars(), reload(), rpt_master(), smdi_message_wait(), sqlite3_log(), and unload_module().

uint32_t sub_uniqueid [static]

Definition at line 115 of file event.c.

Referenced by ast_event_subscribe().


Generated on Thu Jul 9 13:41:17 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7