#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_event * | ast_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_event * | ast_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_event * | ast_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_sub * | ast_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 |
Definition in file event.c.
#define NUM_EVENT_THREADS 1 |
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.
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 |
0 | success | |
-1 | failure |
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.
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 |
0 | success | |
-1 | failure |
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.
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 |
0 | success | |
-1 | failure |
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.
event_type | This is the type of event that the caller would like to check for subscribers to. |
<enum ast_event_ie_type>, [enum ast_event_ie_pltype, [payload] ]
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.
if (ast_event_check_subscriber(AST_EVENT_MWI, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, AST_EVENT_IE_END) == AST_EVENT_SUB_NONE) { return; }
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.
event | the event to destroy |
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 }
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.
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.
ast_event_type | The type of event to retrieve from the cache |
<enum ast_event_ie_type>, [enum ast_event_ie_pltype, [payload] ]
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.
The caller of this function *must* call ast_event_destroy() on the returned event after it is done using it.
event = ast_event_get_cached(AST_EVENT_MWI, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, AST_EVENT_IE_END);
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.
event | The event to get the IE from | |
ie_type | the type of information element to retrieve |
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.
event | The event to get the IE from | |
ie_type | the type of information element to retrieve |
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.
event | The event to get the IE from | |
ie_type | the type of information element to retrieve |
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.
event | the event to get the type for |
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.
iterator | The iterator instance |
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.
iterator | The iterator instance |
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.
iterator | The iterator instance |
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.
iterator | The iterator instance |
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.
iterator | The iterator instance to initialize | |
event | The event that will be iterated through |
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.
iterator | The iterator instance |
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.
event_type | The type of event to create |
<enum ast_event_ie_type>, [enum ast_event_ie_pltype, [payload] ]
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.
if (!(event = ast_event_new(AST_EVENT_MWI, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, new, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, AST_EVENT_IE_END))) { return; }
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.
event | the event to be queued |
zero | success | |
non-zero | failure |
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.
event | the event to be queued and cached |
<enum ast_event_ie_type>, [enum ast_event_ie_pltype]
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.
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.
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.
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 |
<enum ast_event_ie_type>, [enum ast_event_ie_pltype, [payload] ]
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.
peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, peer, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, peer->mailbox, AST_EVENT_IE_END);
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.
event_sub | This is the reference to the subscription returned by ast_event_subscribe. |
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 }
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().
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().
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] |