@ -339,60 +339,95 @@ enum ast_event_subscriber_res ast_event_check_subscriber(enum ast_event_type typ
ie_type = va_arg ( ap , enum ast_event_type ) )
{
struct ast_event_ie_val * ie_value = alloca ( sizeof ( * ie_value ) ) ;
int insert = 1 ;
memset ( ie_value , 0 , sizeof ( * ie_value ) ) ;
ie_value - > ie_type = ie_type ;
ie_value - > ie_pltype = va_arg ( ap , enum ast_event_ie_pltype ) ;
if ( ie_value - > ie_pltype = = AST_EVENT_IE_PLTYPE_UINT )
switch ( ie_value - > ie_pltype ) {
case AST_EVENT_IE_PLTYPE_UINT :
ie_value - > payload . uint = va_arg ( ap , uint32_t ) ;
else if ( ie_value - > ie_pltype = = AST_EVENT_IE_PLTYPE_STR )
ie_value - > payload . str = ast_strdupa ( va_arg ( ap , const char * ) ) ;
else if ( ie_value - > ie_pltype = = AST_EVENT_IE_PLTYPE_RAW ) {
break ;
case AST_EVENT_IE_PLTYPE_STR :
ie_value - > payload . str = va_arg ( ap , const char * ) ;
break ;
case AST_EVENT_IE_PLTYPE_RAW :
{
void * data = va_arg ( ap , void * ) ;
size_t datalen = va_arg ( ap , size_t ) ;
ie_value - > payload . raw = alloca ( datalen ) ;
memcpy ( ie_value - > payload . raw , data , datalen ) ;
ie_value - > raw_datalen = datalen ;
break ;
}
case AST_EVENT_IE_PLTYPE_UNKNOWN :
insert = 0 ;
case AST_EVENT_IE_PLTYPE_EXISTS :
break ;
}
if ( insert ) {
AST_LIST_INSERT_TAIL ( & ie_vals , ie_value , entry ) ;
}
AST_LIST_INSERT_TAIL ( & ie_vals , ie_value , entry ) ;
}
va_end ( ap ) ;
AST_RWDLLIST_RDLOCK ( & ast_event_subs [ type ] ) ;
AST_RWDLLIST_TRAVERSE ( & ast_event_subs [ type ] , sub , entry ) {
AST_LIST_TRAVERSE ( & ie_vals , ie_val , entry ) {
int break_out = 0 ;
AST_LIST_TRAVERSE ( & sub - > ie_vals , sub_ie_val , entry ) {
if ( sub_ie_val - > ie_type = = ie_val - > ie_type )
if ( sub_ie_val - > ie_type = = ie_val - > ie_type ) {
break ;
}
}
if ( ! sub_ie_val ) {
if ( ie_val - > ie_pltype = = AST_EVENT_IE_PLTYPE_EXISTS )
break ;
/* This subscriber doesn't care about this IE, so consider
* it matched . */
continue ;
}
/* The subscriber doesn't actually care what the value is */
if ( sub_ie_val - > ie_pltype = = AST_EVENT_IE_PLTYPE_EXISTS )
continue ;
if ( ie_val - > ie_pltype = = AST_EVENT_IE_PLTYPE_UINT & &
ie_val - > payload . uint ! = sub_ie_val - > payload . uint )
switch ( ie_val - > ie_pltype ) {
case AST_EVENT_IE_PLTYPE_UINT :
break_out = ( ie_val - > payload . uint ! = sub_ie_val - > payload . uint ) ;
break ;
case AST_EVENT_IE_PLTYPE_STR :
break_out = strcmp ( ie_val - > payload . str , sub_ie_val - > payload . str ) ;
break ;
case AST_EVENT_IE_PLTYPE_RAW :
break_out = memcmp ( ie_val - > payload . raw ,
sub_ie_val - > payload . raw , ie_val - > raw_datalen ) ;
break ;
if ( ie_val - > ie_pltype = = AST_EVENT_IE_PLTYPE_STR & &
strcmp ( ie_val - > payload . str , sub_ie_val - > payload . str ) )
case AST_EVENT_IE_PLTYPE_EXISTS :
/* The subscriber doesn't actually care what the value is */
break_out = 1 ;
break ;
if ( ie_val - > ie_pltype = = AST_EVENT_IE_PLTYPE_RAW & &
memcmp ( ie_val - > payload . raw , sub_ie_val - > payload . raw , ie_val - > raw_datalen ) )
case AST_EVENT_IE_PLTYPE_UNKNOWN :
break ;
}
if ( break_out ) {
break ;
}
}
if ( ! ie_val )
if ( ! ie_val ) {
/* Everything matched */
break ;
}
}
AST_RWDLLIST_UNLOCK ( & ast_event_subs [ type ] ) ;
if ( sub ) /* All parameters were matched */
if ( sub ) {
/* All parameters were matched */
return AST_EVENT_SUB_EXISTS ;
}
AST_RWDLLIST_RDLOCK ( & ast_event_subs [ AST_EVENT_ALL ] ) ;
if ( ! AST_DLLIST_EMPTY ( & ast_event_subs [ AST_EVENT_ALL ] ) )
if ( ! AST_DLLIST_EMPTY ( & ast_event_subs [ AST_EVENT_ALL ] ) ) {
res = AST_EVENT_SUB_EXISTS ;
}
AST_RWDLLIST_UNLOCK ( & ast_event_subs [ AST_EVENT_ALL ] ) ;
return res ;
@ -529,13 +564,15 @@ void ast_event_report_subs(const struct ast_event_sub *event_sub)
AST_RWDLLIST_RDLOCK ( & ast_event_subs [ event_type ] ) ;
AST_RWDLLIST_TRAVERSE ( & ast_event_subs [ event_type ] , sub , entry ) {
if ( event_sub = = sub )
if ( event_sub = = sub ) {
continue ;
}
event = gen_sub_event ( sub ) ;
if ( ! event )
if ( ! event ) {
continue ;
}
event_sub - > cb ( event , event_sub - > userdata ) ;
@ -544,7 +581,7 @@ void ast_event_report_subs(const struct ast_event_sub *event_sub)
AST_RWDLLIST_UNLOCK ( & ast_event_subs [ event_type ] ) ;
}
struct ast_event_sub * ast_event_subscribe_new ( enum ast_event_type type ,
struct ast_event_sub * ast_event_subscribe_new ( enum ast_event_type type ,
ast_event_cb_t cb , void * userdata )
{
struct ast_event_sub * sub ;
@ -554,8 +591,9 @@ struct ast_event_sub *ast_event_subscribe_new(enum ast_event_type type,
return NULL ;
}
if ( ! ( sub = ast_calloc ( 1 , sizeof ( * sub ) ) ) )
if ( ! ( sub = ast_calloc ( 1 , sizeof ( * sub ) ) ) ) {
return NULL ;
}
sub - > type = type ;
sub - > cb = cb ;
@ -570,11 +608,13 @@ int ast_event_sub_append_ie_uint(struct ast_event_sub *sub,
{
struct ast_event_ie_val * ie_val ;
if ( ie_type < 0 | | ie_type > AST_EVENT_IE_MAX )
if ( ie_type < 0 | | ie_type > AST_EVENT_IE_MAX ) {
return - 1 ;
}
if ( ! ( ie_val = ast_calloc ( 1 , sizeof ( * ie_val ) ) ) )
if ( ! ( ie_val = ast_calloc ( 1 , sizeof ( * ie_val ) ) ) ) {
return - 1 ;
}
ie_val - > ie_type = ie_type ;
ie_val - > payload . uint = unsigned_int ;
@ -590,11 +630,13 @@ int ast_event_sub_append_ie_exists(struct ast_event_sub *sub,
{
struct ast_event_ie_val * ie_val ;
if ( ie_type < 0 | | ie_type > AST_EVENT_IE_MAX )
if ( ie_type < 0 | | ie_type > AST_EVENT_IE_MAX ) {
return - 1 ;
}
if ( ! ( ie_val = ast_calloc ( 1 , sizeof ( * ie_val ) ) ) )
if ( ! ( ie_val = ast_calloc ( 1 , sizeof ( * ie_val ) ) ) ) {
return - 1 ;
}
ie_val - > ie_type = ie_type ;
ie_val - > ie_pltype = AST_EVENT_IE_PLTYPE_EXISTS ;
@ -604,16 +646,18 @@ int ast_event_sub_append_ie_exists(struct ast_event_sub *sub,
return 0 ;
}
int ast_event_sub_append_ie_str ( struct ast_event_sub * sub ,
int ast_event_sub_append_ie_str ( struct ast_event_sub * sub ,
enum ast_event_ie_type ie_type , const char * str )
{
struct ast_event_ie_val * ie_val ;
if ( ie_type < 0 | | ie_type > AST_EVENT_IE_MAX )
if ( ie_type < 0 | | ie_type > AST_EVENT_IE_MAX ) {
return - 1 ;
}
if ( ! ( ie_val = ast_calloc ( 1 , sizeof ( * ie_val ) ) ) )
if ( ! ( ie_val = ast_calloc ( 1 , sizeof ( * ie_val ) ) ) ) {
return - 1 ;
}
ie_val - > ie_type = ie_type ;
ie_val - > ie_pltype = AST_EVENT_IE_PLTYPE_STR ;
@ -630,16 +674,18 @@ int ast_event_sub_append_ie_str(struct ast_event_sub *sub,
return 0 ;
}
int ast_event_sub_append_ie_raw ( struct ast_event_sub * sub ,
int ast_event_sub_append_ie_raw ( struct ast_event_sub * sub ,
enum ast_event_ie_type ie_type , void * data , size_t raw_datalen )
{
struct ast_event_ie_val * ie_val ;
if ( ie_type < 0 | | ie_type > AST_EVENT_IE_MAX )
if ( ie_type < 0 | | ie_type > AST_EVENT_IE_MAX ) {
return - 1 ;
}
if ( ! ( ie_val = ast_calloc ( 1 , sizeof ( * ie_val ) ) ) )
if ( ! ( ie_val = ast_calloc ( 1 , sizeof ( * ie_val ) ) ) ) {
return - 1 ;
}
ie_val - > ie_type = ie_type ;
ie_val - > ie_pltype = AST_EVENT_IE_PLTYPE_RAW ;
@ -666,8 +712,9 @@ int ast_event_sub_activate(struct ast_event_sub *sub)
event = gen_sub_event ( sub ) ;
if ( event )
if ( event ) {
ast_event_queue ( event ) ;
}
}
AST_RWDLLIST_WRLOCK ( & ast_event_subs [ sub - > type ] ) ;
@ -677,15 +724,16 @@ int ast_event_sub_activate(struct ast_event_sub *sub)
return 0 ;
}
struct ast_event_sub * ast_event_subscribe ( enum ast_event_type type , ast_event_cb_t cb ,
struct ast_event_sub * ast_event_subscribe ( enum ast_event_type type , ast_event_cb_t cb ,
void * userdata , . . . )
{
va_list ap ;
enum ast_event_ie_type ie_type ;
struct ast_event_sub * sub ;
if ( ! ( sub = ast_event_subscribe_new ( type , cb , userdata ) ) )
if ( ! ( sub = ast_event_subscribe_new ( type , cb , userdata ) ) ) {
return NULL ;
}
va_start ( ap , userdata ) ;
for ( ie_type = va_arg ( ap , enum ast_event_type ) ;
@ -734,8 +782,9 @@ void ast_event_sub_destroy(struct ast_event_sub *sub)
{
struct ast_event_ie_val * ie_val ;
while ( ( ie_val = AST_LIST_REMOVE_HEAD ( & sub - > ie_vals , entry ) ) )
while ( ( ie_val = AST_LIST_REMOVE_HEAD ( & sub - > ie_vals , entry ) ) ) {
ast_event_ie_val_destroy ( ie_val ) ;
}
ast_free ( sub ) ;
}
@ -751,14 +800,15 @@ struct ast_event_sub *ast_event_unsubscribe(struct ast_event_sub *sub)
if ( ast_event_check_subscriber ( AST_EVENT_UNSUB ,
AST_EVENT_IE_EVENTTYPE , AST_EVENT_IE_PLTYPE_UINT , sub - > type ,
AST_EVENT_IE_END ) ! = AST_EVENT_SUB_NONE ) {
event = ast_event_new ( AST_EVENT_UNSUB ,
AST_EVENT_IE_UNIQUEID , AST_EVENT_IE_PLTYPE_UINT , sub - > uniqueid ,
AST_EVENT_IE_EVENTTYPE , AST_EVENT_IE_PLTYPE_UINT , sub - > type ,
AST_EVENT_IE_END ) ;
if ( event )
if ( event ) {
ast_event_queue ( event ) ;
}
}
ast_event_sub_destroy ( sub ) ;
@ -771,7 +821,6 @@ void ast_event_iterator_init(struct ast_event_iterator *iterator, const struct a
iterator - > event_len = ntohs ( event - > event_len ) ;
iterator - > event = event ;
iterator - > ie = ( struct ast_event_ie * ) ( ( ( char * ) event ) + sizeof ( * event ) ) ;
return ;
}
int ast_event_iterator_next ( struct ast_event_iterator * iterator )
@ -842,8 +891,9 @@ const void *ast_event_get_ie_raw(const struct ast_event *event, enum ast_event_i
int res = 0 ;
for ( ast_event_iterator_init ( & iterator , event ) ; ! res ; res = ast_event_iterator_next ( & iterator ) ) {
if ( ast_event_iterator_get_ie_type ( & iterator ) = = ie_type )
if ( ast_event_iterator_get_ie_type ( & iterator ) = = ie_type ) {
return ast_event_iterator_get_ie_raw ( & iterator ) ;
}
}
return NULL ;
@ -881,8 +931,9 @@ int ast_event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_
event_len = ntohs ( ( * event ) - > event_len ) ;
extra_len = sizeof ( * ie ) + data_len ;
if ( ! ( * event = ast_realloc ( * event , event_len + extra_len ) ) )
if ( ! ( * event = ast_realloc ( * event , event_len + extra_len ) ) ) {
return - 1 ;
}
ie = ( struct ast_event_ie * ) ( ( ( char * ) * event ) + event_len ) ;
ie - > ie_type = htons ( ie_type ) ;
@ -915,40 +966,70 @@ struct ast_event *ast_event_new(enum ast_event_type type, ...)
ie_type = va_arg ( ap , enum ast_event_type ) )
{
struct ast_event_ie_val * ie_value = alloca ( sizeof ( * ie_value ) ) ;
int insert = 1 ;
memset ( ie_value , 0 , sizeof ( * ie_value ) ) ;
ie_value - > ie_type = ie_type ;
ie_value - > ie_pltype = va_arg ( ap , enum ast_event_ie_pltype ) ;
if ( ie_value - > ie_pltype = = AST_EVENT_IE_PLTYPE_UINT )
switch ( ie_value - > ie_pltype ) {
case AST_EVENT_IE_PLTYPE_UINT :
ie_value - > payload . uint = va_arg ( ap , uint32_t ) ;
else if ( ie_value - > ie_pltype = = AST_EVENT_IE_PLTYPE_STR )
ie_value - > payload . str = ast_strdupa ( va_arg ( ap , const char * ) ) ;
else if ( ie_value - > ie_pltype = = AST_EVENT_IE_PLTYPE_RAW ) {
break ;
case AST_EVENT_IE_PLTYPE_STR :
ie_value - > payload . str = va_arg ( ap , const char * ) ;
break ;
case AST_EVENT_IE_PLTYPE_RAW :
{
void * data = va_arg ( ap , void * ) ;
size_t datalen = va_arg ( ap , size_t ) ;
ie_value - > payload . raw = alloca ( datalen ) ;
memcpy ( ie_value - > payload . raw , data , datalen ) ;
ie_value - > raw_datalen = datalen ;
break ;
}
case AST_EVENT_IE_PLTYPE_UNKNOWN :
insert = 0 ;
break ;
case AST_EVENT_IE_PLTYPE_EXISTS :
break ;
}
if ( insert ) {
AST_LIST_INSERT_TAIL ( & ie_vals , ie_value , entry ) ;
}
AST_LIST_INSERT_TAIL ( & ie_vals , ie_value , entry ) ;
}
va_end ( ap ) ;
if ( ! ( event = ast_calloc ( 1 , sizeof ( * event ) ) ) )
if ( ! ( event = ast_calloc ( 1 , sizeof ( * event ) ) ) ) {
return NULL ;
}
event - > type = htons ( type ) ;
event - > event_len = htons ( sizeof ( * event ) ) ;
AST_LIST_TRAVERSE ( & ie_vals , ie_val , entry ) {
if ( ie_val - > ie_pltype = = AST_EVENT_IE_PLTYPE_STR )
switch ( ie_val - > ie_pltype ) {
case AST_EVENT_IE_PLTYPE_STR :
ast_event_append_ie_str ( & event , ie_val - > ie_type , ie_val - > payload . str ) ;
else if ( ie_val - > ie_pltype = = AST_EVENT_IE_PLTYPE_UINT )
break ;
case AST_EVENT_IE_PLTYPE_UINT :
ast_event_append_ie_uint ( & event , ie_val - > ie_type , ie_val - > payload . uint ) ;
else if ( ie_val - > ie_pltype = = AST_EVENT_IE_PLTYPE_RAW )
ast_event_append_ie_raw ( & event , ie_val - > ie_type , ie_val - > payload . raw , ie_val - > raw_datalen ) ;
break ;
case AST_EVENT_IE_PLTYPE_RAW :
ast_event_append_ie_raw ( & event , ie_val - > ie_type ,
ie_val - > payload . raw , ie_val - > raw_datalen ) ;
break ;
case AST_EVENT_IE_PLTYPE_EXISTS :
ast_log ( LOG_WARNING , " PLTYPE_EXISTS unsupported in event_new \n " ) ;
break ;
case AST_EVENT_IE_PLTYPE_UNKNOWN :
ast_log ( LOG_WARNING , " PLTYPE_UNKNOWN passed as an IE type "
" for a new event \n " ) ;
break ;
}
if ( ! event )
if ( ! event ) {
break ;
}
}
if ( ! ast_event_get_ie_raw ( event , AST_EVENT_IE_EID ) ) {