Wed Jan 8 2020 09:50:11

Asterisk developer's documentation


evt.c File Reference

Usage of the SAForum AIS (Application Interface Specification) More...

#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "ais.h"
#include "asterisk/module.h"
#include "asterisk/utils.h"
#include "asterisk/cli.h"
#include "asterisk/logger.h"
#include "asterisk/event.h"
#include "asterisk/config.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h"

Go to the source code of this file.

Data Structures

struct  event_channel
 
struct  event_channels
 
struct  publish_event
 
struct  subscribe_event
 

Macros

#define AST_MODULE   "res_ais"
 

Functions

static void add_publish_event (struct event_channel *event_channel, const char *event_type)
 
static void add_subscribe_event (struct event_channel *event_channel, const char *event_type)
 
static char * ais_evt_show_event_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
int ast_ais_evt_load_module (void)
 
void ast_ais_evt_membership_changed (void)
 
int ast_ais_evt_unload_module (void)
 
static void ast_event_cb (const struct ast_event *ast_event, void *data)
 
 ASTERISK_FILE_VERSION (__FILE__,"$Revision: 369001 $")
 
static void build_event_channel (struct ast_config *cfg, const char *cat)
 
static void destroy_event_channels (void)
 
static void event_channel_destroy (struct event_channel *event_channel)
 
void evt_channel_open_cb (SaInvocationT invocation, SaEvtChannelHandleT channel_handle, SaAisErrorT error)
 
void evt_event_deliver_cb (SaEvtSubscriptionIdT subscription_id, const SaEvtEventHandleT event_handle, const SaSizeT event_datalen)
 
static void load_config (void)
 
static void publish_event_destroy (struct publish_event *publish_event)
 
static void queue_event (struct ast_event *ast_event)
 
static SaAisErrorT set_egress_subscription (struct event_channel *event_channel, struct subscribe_event *subscribe_event)
 
static void subscribe_event_destroy (const struct event_channel *event_channel, struct subscribe_event *subscribe_event)
 
static const char * type_to_filter_str (enum ast_event_type type)
 

Variables

static struct ast_cli_entry ais_cli []
 
static struct event_channels event_channels = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static const SaEvtCallbacksT evt_callbacks
 
SaEvtHandleT evt_handle
 
static SaAisErrorT evt_init_res
 
struct {
   const char *   str
 
   enum ast_event_type   type
 
supported_event_types []
 
static int unique_id
 

Detailed Description

Usage of the SAForum AIS (Application Interface Specification)

Author
Russell Bryant russe.nosp@m.ll@d.nosp@m.igium.nosp@m..com

This file contains the code specific to the use of the EVT (Event) Service.

Definition in file evt.c.

Macro Definition Documentation

#define AST_MODULE   "res_ais"

Definition at line 58 of file evt.c.

Function Documentation

static void add_publish_event ( struct event_channel event_channel,
const char *  event_type 
)
static

Definition at line 335 of file evt.c.

References ARRAY_LEN, ast_calloc, ast_enable_distributed_devstate(), ast_event_cb(), AST_EVENT_DEVICE_STATE_CHANGE, ast_event_dump_cache(), AST_EVENT_IE_END, ast_event_subscribe(), AST_LIST_INSERT_TAIL, ast_log(), LOG_DEBUG, LOG_WARNING, event_channel::publish_events, str, publish_event::sub, supported_event_types, subscribe_event::type, and publish_event::type.

Referenced by build_event_channel().

336 {
337  int i;
338  enum ast_event_type type = -1;
340 
341  for (i = 0; i < ARRAY_LEN(supported_event_types); i++) {
342  if (!strcasecmp(event_type, supported_event_types[i].str)) {
343  type = supported_event_types[i].type;
344  break;
345  }
346  }
347 
348  if (type == -1) {
349  ast_log(LOG_WARNING, "publish_event option given with invalid value '%s'\n", event_type);
350  return;
351  }
352 
354  return;
355  }
356 
357  if (!(publish_event = ast_calloc(1, sizeof(*publish_event)))) {
358  return;
359  }
360 
361  publish_event->type = type;
362  ast_log(LOG_DEBUG, "Subscribing to event type %d\n", type);
363  publish_event->sub = ast_event_subscribe(type, ast_event_cb, "AIS", event_channel,
365  ast_event_dump_cache(publish_event->sub);
366 
367  AST_LIST_INSERT_TAIL(&event_channel->publish_events, publish_event, entry);
368 }
struct event_channel::@356 publish_events
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_WARNING
Definition: logger.h:144
int ast_enable_distributed_devstate(void)
Enable distributed device state processing.
Definition: devicestate.c:796
const char * str
Definition: app_jack.c:144
#define LOG_DEBUG
Definition: logger.h:122
static struct @353 supported_event_types[]
ast_event_type
Event types.
Definition: event_defs.h:30
enum ast_event_type type
Definition: evt.c:99
void ast_event_dump_cache(const struct ast_event_sub *event_sub)
Dump the event cache for the subscriber.
Definition: event.c:654
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
struct publish_event::@355 entry
static void ast_event_cb(const struct ast_event *ast_event, void *data)
Definition: evt.c:184
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_event_sub * sub
Definition: evt.c:98
static const char type[]
Definition: chan_nbs.c:57
#define ast_calloc(a, b)
Definition: astmm.h:82
struct ast_event_sub * ast_event_subscribe(enum ast_event_type event_type, ast_event_cb_t cb, const char *description, void *userdata,...)
Subscribe to events.
Definition: event.c:909
static void add_subscribe_event ( struct event_channel event_channel,
const char *  event_type 
)
static

Definition at line 397 of file evt.c.

References ais_err2str(), ARRAY_LEN, ast_atomic_fetchadd_int(), ast_calloc, ast_enable_distributed_devstate(), AST_EVENT_DEVICE_STATE_CHANGE, AST_LIST_INSERT_TAIL, ast_log(), free, subscribe_event::id, LOG_ERROR, LOG_WARNING, set_egress_subscription(), str, event_channel::subscribe_events, supported_event_types, subscribe_event::type, and unique_id.

Referenced by build_event_channel().

398 {
399  int i;
400  enum ast_event_type type = -1;
402  SaAisErrorT ais_res;
403 
404  for (i = 0; i < ARRAY_LEN(supported_event_types); i++) {
405  if (!strcasecmp(event_type, supported_event_types[i].str)) {
406  type = supported_event_types[i].type;
407  break;
408  }
409  }
410 
411  if (type == -1) {
412  ast_log(LOG_WARNING, "subscribe_event option given with invalid value '%s'\n", event_type);
413  return;
414  }
415 
417  return;
418  }
419 
420  if (!(subscribe_event = ast_calloc(1, sizeof(*subscribe_event)))) {
421  return;
422  }
423 
424  subscribe_event->type = type;
425  subscribe_event->id = ast_atomic_fetchadd_int(&unique_id, +1);
426 
427  ais_res = set_egress_subscription(event_channel, subscribe_event);
428  if (ais_res != SA_AIS_OK) {
429  ast_log(LOG_ERROR, "Error setting up egress subscription: %s\n",
430  ais_err2str(ais_res));
431  free(subscribe_event);
432  return;
433  }
434 
435  AST_LIST_INSERT_TAIL(&event_channel->subscribe_events, subscribe_event, entry);
436 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_WARNING
Definition: logger.h:144
int ast_enable_distributed_devstate(void)
Enable distributed device state processing.
Definition: devicestate.c:796
struct subscribe_event::@354 entry
const char * str
Definition: app_jack.c:144
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
enum ast_event_type type
Definition: evt.c:91
static struct @353 supported_event_types[]
ast_event_type
Event types.
Definition: event_defs.h:30
static int unique_id
Definition: evt.c:83
#define LOG_ERROR
Definition: logger.h:155
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
#define free(a)
Definition: astmm.h:94
subscribe_events
Definition: evt.c:104
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char type[]
Definition: chan_nbs.c:57
#define ast_calloc(a, b)
Definition: astmm.h:82
const char * ais_err2str(SaAisErrorT error)
Definition: res_ais.c:105
static SaAisErrorT set_egress_subscription(struct event_channel *event_channel, struct subscribe_event *subscribe_event)
Definition: evt.c:370
SaEvtSubscriptionIdT id
Definition: evt.c:90
static char* ais_evt_show_event_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 261 of file evt.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, event_channel::name, event_channel::publish_events, event_channel::subscribe_events, subscribe_event::type, publish_event::type, type_to_filter_str(), and ast_cli_entry::usage.

262 {
264 
265  switch (cmd) {
266  case CLI_INIT:
267  e->command = "ais evt show event channels";
268  e->usage =
269  "Usage: ais evt show event channels\n"
270  " List configured event channels for the (EVT) Eventing service.\n";
271  return NULL;
272 
273  case CLI_GENERATE:
274  return NULL; /* no completion */
275  }
276 
277  if (a->argc != e->args)
278  return CLI_SHOWUSAGE;
279 
280  ast_cli(a->fd, "\n"
281  "=============================================================\n"
282  "=== Event Channels ==========================================\n"
283  "=============================================================\n"
284  "===\n");
285 
287  AST_RWLIST_TRAVERSE(&event_channels, event_channel, entry) {
290 
291  ast_cli(a->fd, "=== ---------------------------------------------------------\n"
292  "=== Event Channel Name: %s\n", event_channel->name);
293 
294  AST_LIST_TRAVERSE(&event_channel->publish_events, publish_event, entry) {
295  ast_cli(a->fd, "=== ==> Publishing Event Type: %s\n",
296  type_to_filter_str(publish_event->type));
297  }
298 
299  AST_LIST_TRAVERSE(&event_channel->subscribe_events, subscribe_event, entry) {
300  ast_cli(a->fd, "=== ==> Subscribing to Event Type: %s\n",
301  type_to_filter_str(subscribe_event->type));
302  }
303 
304  ast_cli(a->fd, "=== ---------------------------------------------------------\n"
305  "===\n");
306  }
308 
309  ast_cli(a->fd, "=============================================================\n"
310  "\n");
311 
312  return CLI_SUCCESS;
313 }
struct event_channel::@356 publish_events
const int argc
Definition: cli.h:154
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
struct subscribe_event::@354 entry
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
enum ast_event_type type
Definition: evt.c:91
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
enum ast_event_type type
Definition: evt.c:99
#define CLI_SHOWUSAGE
Definition: cli.h:44
subscribe_events
Definition: evt.c:104
static const char * type_to_filter_str(enum ast_event_type type)
Definition: evt.c:169
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
char name[1]
Definition: evt.c:107
int ast_ais_evt_load_module ( void  )

Definition at line 576 of file evt.c.

References ais_err2str(), ais_version, ARRAY_LEN, ast_cli_register_multiple(), ast_log(), evt_callbacks, evt_handle, evt_init_res, load_config(), and LOG_ERROR.

Referenced by load_module().

577 {
578  evt_init_res = saEvtInitialize(&evt_handle, &evt_callbacks, &ais_version);
579  if (evt_init_res != SA_AIS_OK) {
580  ast_log(LOG_ERROR, "Could not initialize eventing service: %s\n",
582  return -1;
583  }
584 
585  load_config();
586 
588 
589  return 0;
590 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_cli_entry ais_cli[]
Definition: evt.c:315
SaEvtHandleT evt_handle
Definition: evt.c:61
static void load_config(void)
Definition: evt.c:490
static const SaEvtCallbacksT evt_callbacks
Definition: evt.c:69
SaVersionT ais_version
Definition: res_ais.c:70
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
const char * ais_err2str(SaAisErrorT error)
Definition: res_ais.c:105
static SaAisErrorT evt_init_res
Definition: evt.c:62
void ast_ais_evt_membership_changed ( void  )

Definition at line 319 of file evt.c.

References ast_debug, ast_event_dump_cache(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, event_channel::name, event_channel::publish_events, and publish_event::sub.

Referenced by dispatch_thread_handler().

320 {
321  struct event_channel *ec;
322 
324  AST_RWLIST_TRAVERSE(&event_channels, ec, entry) {
325  struct publish_event *pe;
326 
328  ast_debug(1, "Dumping cache for event channel '%s'\n", ec->name);
330  }
331  }
333 }
struct event_channel::@356 publish_events
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
void ast_event_dump_cache(const struct ast_event_sub *event_sub)
Dump the event cache for the subscriber.
Definition: event.c:654
struct publish_event::@355 entry
struct ast_event_sub * sub
Definition: evt.c:98
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char name[1]
Definition: evt.c:107
int ast_ais_evt_unload_module ( void  )

Definition at line 592 of file evt.c.

References ais_err2str(), ast_log(), destroy_event_channels(), evt_handle, evt_init_res, and LOG_ERROR.

Referenced by load_module(), and unload_module().

593 {
594  SaAisErrorT ais_res;
595 
596  if (evt_init_res != SA_AIS_OK) {
597  return 0;
598  }
599 
601 
602  ais_res = saEvtFinalize(evt_handle);
603  if (ais_res != SA_AIS_OK) {
604  ast_log(LOG_ERROR, "Problem stopping eventing service: %s\n",
605  ais_err2str(ais_res));
606  return -1;
607  }
608 
609  return 0;
610 }
SaEvtHandleT evt_handle
Definition: evt.c:61
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void destroy_event_channels(void)
Definition: evt.c:565
const char * ais_err2str(SaAisErrorT error)
Definition: res_ais.c:105
static SaAisErrorT evt_init_res
Definition: evt.c:62
static void ast_event_cb ( const struct ast_event ast_event,
void *  data 
)
static

/todo Make retention time configurable /todo Make event priorities configurable

Definition at line 184 of file evt.c.

References ais_err2str(), ast_eid_cmp(), ast_eid_default, ast_event_get_ie_raw(), ast_event_get_size(), ast_event_get_type(), AST_EVENT_IE_EID, ast_log(), clm_handle, event_channel::handle, len(), LOG_DEBUG, LOG_ERROR, and type_to_filter_str().

Referenced by add_publish_event().

185 {
186  SaEvtEventHandleT event_handle;
187  SaAisErrorT ais_res;
188  struct event_channel *event_channel = data;
189  SaClmClusterNodeT local_node;
190  SaEvtEventPatternArrayT pattern_array;
191  SaEvtEventPatternT pattern;
192  SaSizeT len;
193  const char *filter_str;
194  SaEvtEventIdT event_id;
195 
196  ast_log(LOG_DEBUG, "Got an event to forward\n");
197 
199  /* If the event didn't originate from this server, don't send it back out. */
200  ast_log(LOG_DEBUG, "Returning here\n");
201  return;
202  }
203 
204  ais_res = saEvtEventAllocate(event_channel->handle, &event_handle);
205  if (ais_res != SA_AIS_OK) {
206  ast_log(LOG_ERROR, "Error allocating event: %s\n", ais_err2str(ais_res));
207  ast_log(LOG_DEBUG, "Returning here\n");
208  return;
209  }
210 
211  ais_res = saClmClusterNodeGet(clm_handle, SA_CLM_LOCAL_NODE_ID,
212  SA_TIME_ONE_SECOND, &local_node);
213  if (ais_res != SA_AIS_OK) {
214  ast_log(LOG_ERROR, "Error getting local node name: %s\n", ais_err2str(ais_res));
215  goto return_event_free;
216  }
217 
218  filter_str = type_to_filter_str(ast_event_get_type(ast_event));
219  len = strlen(filter_str) + 1;
220  pattern.pattern = (SaUint8T *) filter_str;
221  pattern.patternSize = len;
222  pattern.allocatedSize = len;
223 
224  pattern_array.allocatedNumber = 1;
225  pattern_array.patternsNumber = 1;
226  pattern_array.patterns = &pattern;
227 
228  /*!
229  * /todo Make retention time configurable
230  * /todo Make event priorities configurable
231  */
232  ais_res = saEvtEventAttributesSet(event_handle, &pattern_array,
233  SA_EVT_LOWEST_PRIORITY, SA_TIME_ONE_MINUTE, &local_node.nodeName);
234  if (ais_res != SA_AIS_OK) {
235  ast_log(LOG_ERROR, "Error setting event attributes: %s\n", ais_err2str(ais_res));
236  goto return_event_free;
237  }
238 
239  for (;;) {
240  ais_res = saEvtEventPublish(event_handle,
241  ast_event, ast_event_get_size(ast_event), &event_id);
242  if (ais_res != SA_AIS_ERR_TRY_AGAIN) {
243  break;
244  }
245  sched_yield();
246  }
247 
248  if (ais_res != SA_AIS_OK) {
249  ast_log(LOG_ERROR, "Error publishing event: %s\n", ais_err2str(ais_res));
250  goto return_event_free;
251  }
252 
253 return_event_free:
254  ais_res = saEvtEventFree(event_handle);
255  if (ais_res != SA_AIS_OK) {
256  ast_log(LOG_ERROR, "Error freeing allocated event: %s\n", ais_err2str(ais_res));
257  }
258  ast_log(LOG_DEBUG, "Returning here (event_free)\n");
259 }
enum ast_event_type ast_event_get_type(const struct ast_event *event)
Get the type for an event.
Definition: event.c:1070
#define LOG_DEBUG
Definition: logger.h:122
Entity ID Used by All events Payload type: RAW This IE indicates which server the event originated fr...
Definition: event_defs.h:266
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
Definition: netsock.c:320
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.
Definition: event.c:1111
#define LOG_ERROR
Definition: logger.h:155
static const char * type_to_filter_str(enum ast_event_type type)
Definition: evt.c:169
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
SaClmHandleT clm_handle
Definition: clm.c:52
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_eid ast_eid_default
Global EID.
Definition: asterisk.c:192
SaEvtChannelHandleT handle
Definition: evt.c:106
const char * ais_err2str(SaAisErrorT error)
Definition: res_ais.c:105
size_t ast_event_get_size(const struct ast_event *event)
Get the size of an event.
Definition: event.c:340
ASTERISK_FILE_VERSION ( __FILE__  ,
"$Revision: 369001 $"   
)
static void build_event_channel ( struct ast_config cfg,
const char *  cat 
)
static

Definition at line 438 of file evt.c.

References add_publish_event(), add_subscribe_event(), ais_err2str(), ast_calloc, ast_copy_string(), ast_log(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_variable_browse(), evt_handle, free, event_channel::handle, LOG_ERROR, LOG_WARNING, ast_variable::name, event_channel::name, ast_variable::next, ast_variable::value, and var.

Referenced by load_config().

439 {
440  struct ast_variable *var;
442  SaAisErrorT ais_res;
443  SaNameT sa_name = { 0, };
444 
446  AST_RWLIST_TRAVERSE(&event_channels, event_channel, entry) {
447  if (!strcasecmp(event_channel->name, cat))
448  break;
449  }
451  if (event_channel) {
452  ast_log(LOG_WARNING, "Event channel '%s' was specified twice in "
453  "configuration. Second instance ignored.\n", cat);
454  return;
455  }
456 
457  if (!(event_channel = ast_calloc(1, sizeof(*event_channel) + strlen(cat))))
458  return;
459 
460  strcpy(event_channel->name, cat);
461  ast_copy_string((char *) sa_name.value, cat, sizeof(sa_name.value));
462  sa_name.length = strlen((char *) sa_name.value);
463  ais_res = saEvtChannelOpen(evt_handle, &sa_name,
464  SA_EVT_CHANNEL_PUBLISHER | SA_EVT_CHANNEL_SUBSCRIBER | SA_EVT_CHANNEL_CREATE,
465  SA_TIME_MAX, &event_channel->handle);
466  if (ais_res != SA_AIS_OK) {
467  ast_log(LOG_ERROR, "Error opening event channel: %s\n", ais_err2str(ais_res));
468  free(event_channel);
469  return;
470  }
471 
472  for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
473  if (!strcasecmp(var->name, "type")) {
474  continue;
475  } else if (!strcasecmp(var->name, "publish_event")) {
476  add_publish_event(event_channel, var->value);
477  } else if (!strcasecmp(var->name, "subscribe_event")) {
478  add_subscribe_event(event_channel, var->value);
479  } else {
480  ast_log(LOG_WARNING, "Event channel '%s' contains invalid option '%s'\n",
481  event_channel->name, var->name);
482  }
483  }
484 
486  AST_RWLIST_INSERT_TAIL(&event_channels, event_channel, entry);
488 }
SaEvtHandleT evt_handle
Definition: evt.c:61
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
static void add_publish_event(struct event_channel *event_channel, const char *event_type)
Definition: evt.c:335
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
static void add_subscribe_event(struct event_channel *event_channel, const char *event_type)
Definition: evt.c:397
const char * value
Definition: config.h:79
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
const char * name
Definition: config.h:77
#define LOG_ERROR
Definition: logger.h:155
#define free(a)
Definition: astmm.h:94
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
SaEvtChannelHandleT handle
Definition: evt.c:106
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
const char * ais_err2str(SaAisErrorT error)
Definition: res_ais.c:105
struct ast_variable * next
Definition: config.h:82
char name[1]
Definition: evt.c:107
static void destroy_event_channels ( void  )
static

Definition at line 565 of file evt.c.

References AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and event_channel_destroy().

Referenced by ast_ais_evt_unload_module().

566 {
568 
570  while ((event_channel = AST_RWLIST_REMOVE_HEAD(&event_channels, entry))) {
571  event_channel_destroy(event_channel);
572  }
574 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
static void event_channel_destroy(struct event_channel *event_channel)
Definition: evt.c:545
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:829
static void event_channel_destroy ( struct event_channel event_channel)
static

Definition at line 545 of file evt.c.

References ais_err2str(), AST_LIST_REMOVE_HEAD, ast_log(), free, event_channel::handle, LOG_ERROR, event_channel::name, publish_event_destroy(), event_channel::publish_events, subscribe_event_destroy(), and event_channel::subscribe_events.

Referenced by destroy_event_channels().

546 {
549  SaAisErrorT ais_res;
550 
551  while ((publish_event = AST_LIST_REMOVE_HEAD(&event_channel->publish_events, entry)))
552  publish_event_destroy(publish_event);
553  while ((subscribe_event = AST_LIST_REMOVE_HEAD(&event_channel->subscribe_events, entry)))
554  subscribe_event_destroy(event_channel, subscribe_event);
555 
556  ais_res = saEvtChannelClose(event_channel->handle);
557  if (ais_res != SA_AIS_OK) {
558  ast_log(LOG_ERROR, "Error closing event channel '%s': %s\n",
559  event_channel->name, ais_err2str(ais_res));
560  }
561 
562  free(event_channel);
563 }
struct event_channel::@356 publish_events
struct subscribe_event::@354 entry
static void publish_event_destroy(struct publish_event *publish_event)
Definition: evt.c:523
static void subscribe_event_destroy(const struct event_channel *event_channel, struct subscribe_event *subscribe_event)
Definition: evt.c:530
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
#define LOG_ERROR
Definition: logger.h:155
#define free(a)
Definition: astmm.h:94
subscribe_events
Definition: evt.c:104
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
SaEvtChannelHandleT handle
Definition: evt.c:106
const char * ais_err2str(SaAisErrorT error)
Definition: res_ais.c:105
char name[1]
Definition: evt.c:107
void evt_channel_open_cb ( SaInvocationT  invocation,
SaEvtChannelHandleT  channel_handle,
SaAisErrorT  error 
)

Definition at line 112 of file evt.c.

114 {
115 
116 }
void evt_event_deliver_cb ( SaEvtSubscriptionIdT  subscription_id,
const SaEvtEventHandleT  event_handle,
const SaSizeT  event_datalen 
)

Definition at line 123 of file evt.c.

References ais_err2str(), ast_debug, ast_eid_cmp(), ast_eid_default, ast_event_get_ie_raw(), AST_EVENT_IE_EID, ast_event_minimum_length(), ast_log(), ast_malloc, len(), LOG_ERROR, and queue_event().

125 {
126  /* It is important to note that this works because we *know* that this
127  * function will only be called by a single thread, the dispatch_thread.
128  * If this module gets changed such that this is no longer the case, this
129  * should get changed to a thread-local buffer, instead. */
130  static unsigned char buf[4096];
131  struct ast_event *event_dup, *event = (void *) buf;
132  SaAisErrorT ais_res;
133  SaSizeT len = sizeof(buf);
134 
135  if (event_datalen > len) {
136  ast_log(LOG_ERROR, "Event received with size %u, which is too big\n"
137  "for the allocated size %u. Change the code to increase the size.\n",
138  (unsigned int) event_datalen, (unsigned int) len);
139  return;
140  }
141 
142  if (event_datalen < ast_event_minimum_length()) {
143  ast_debug(1, "Ignoring event that's too small. %u < %u\n",
144  (unsigned int) event_datalen,
145  (unsigned int) ast_event_minimum_length());
146  return;
147  }
148 
149  ais_res = saEvtEventDataGet(event_handle, event, &len);
150  if (ais_res != SA_AIS_OK) {
151  ast_log(LOG_ERROR, "Error retrieving event payload: %s\n",
152  ais_err2str(ais_res));
153  return;
154  }
155 
157  /* Don't feed events back in that originated locally. */
158  return;
159  }
160 
161  if (!(event_dup = ast_malloc(len)))
162  return;
163 
164  memcpy(event_dup, event, len);
165 
166  queue_event(event_dup);
167 }
An event.
Definition: event.c:85
static void queue_event(struct ast_event *ast_event)
Definition: evt.c:118
Entity ID Used by All events Payload type: RAW This IE indicates which server the event originated fr...
Definition: event_defs.h:266
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
Definition: netsock.c:320
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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.
Definition: event.c:1111
#define LOG_ERROR
Definition: logger.h:155
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
size_t ast_event_minimum_length(void)
Get the minimum length of an ast_event.
Definition: event.c:1854
struct ast_eid ast_eid_default
Global EID.
Definition: asterisk.c:192
const char * ais_err2str(SaAisErrorT error)
Definition: res_ais.c:105
#define ast_malloc(a)
Definition: astmm.h:91
static void load_config ( void  )
static

Definition at line 490 of file evt.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load, ast_log(), ast_variable_retrieve(), build_event_channel(), CONFIG_STATUS_FILEINVALID, LOG_WARNING, and subscribe_event::type.

Referenced by ast_ais_evt_load_module().

491 {
492  static const char filename[] = "ais.conf";
493  struct ast_config *cfg;
494  const char *cat = NULL;
495  struct ast_flags config_flags = { 0 };
496 
497  if (!(cfg = ast_config_load(filename, config_flags)) || cfg == CONFIG_STATUS_FILEINVALID)
498  return;
499 
500  while ((cat = ast_category_browse(cfg, cat))) {
501  const char *type;
502 
503  if (!strcasecmp(cat, "general"))
504  continue;
505 
506  if (!(type = ast_variable_retrieve(cfg, cat, "type"))) {
507  ast_log(LOG_WARNING, "Invalid entry in %s defined with no type!\n",
508  filename);
509  continue;
510  }
511 
512  if (!strcasecmp(type, "event_channel")) {
513  build_event_channel(cfg, cat);
514  } else {
515  ast_log(LOG_WARNING, "Entry in %s defined with invalid type '%s'\n",
516  filename, type);
517  }
518  }
519 
520  ast_config_destroy(cfg);
521 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define LOG_WARNING
Definition: logger.h:144
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static void build_event_channel(struct ast_config *cfg, const char *cat)
Definition: evt.c:438
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char type[]
Definition: chan_nbs.c:57
Structure used to handle boolean flags.
Definition: utils.h:200
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static void publish_event_destroy ( struct publish_event publish_event)
static

Definition at line 523 of file evt.c.

References ast_event_unsubscribe(), free, and publish_event::sub.

Referenced by event_channel_destroy().

524 {
525  ast_event_unsubscribe(publish_event->sub);
526 
527  free(publish_event);
528 }
#define free(a)
Definition: astmm.h:94
struct ast_event_sub * sub
Definition: evt.c:98
struct ast_event_sub * ast_event_unsubscribe(struct ast_event_sub *event_sub)
Un-subscribe from events.
Definition: event.c:987
static void queue_event ( struct ast_event ast_event)
static

Definition at line 118 of file evt.c.

References ast_event_queue_and_cache().

Referenced by evt_event_deliver_cb().

119 {
120  ast_event_queue_and_cache(ast_event);
121 }
int ast_event_queue_and_cache(struct ast_event *event)
Queue and cache an event.
Definition: event.c:1465
static SaAisErrorT set_egress_subscription ( struct event_channel event_channel,
struct subscribe_event subscribe_event 
)
static

Definition at line 370 of file evt.c.

References filter(), event_channel::handle, subscribe_event::id, len(), subscribe_event::type, and type_to_filter_str().

Referenced by add_subscribe_event().

372 {
373  SaAisErrorT ais_res;
374  SaEvtEventFilterArrayT filter_array;
375  SaEvtEventFilterT filter;
376  const char *filter_str = NULL;
377  SaSizeT len;
378 
379  /* We know it's going to be valid. It was checked earlier. */
380  filter_str = type_to_filter_str(subscribe_event->type);
381 
382  filter.filterType = SA_EVT_EXACT_FILTER;
383  len = strlen(filter_str) + 1;
384  filter.filter.allocatedSize = len;
385  filter.filter.patternSize = len;
386  filter.filter.pattern = (SaUint8T *) filter_str;
387 
388  filter_array.filtersNumber = 1;
389  filter_array.filters = &filter;
390 
391  ais_res = saEvtEventSubscribe(event_channel->handle, &filter_array,
392  subscribe_event->id);
393 
394  return ais_res;
395 }
enum ast_event_type type
Definition: evt.c:91
static const char * type_to_filter_str(enum ast_event_type type)
Definition: evt.c:169
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
SaEvtChannelHandleT handle
Definition: evt.c:106
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:694
SaEvtSubscriptionIdT id
Definition: evt.c:90
static void subscribe_event_destroy ( const struct event_channel event_channel,
struct subscribe_event subscribe_event 
)
static

Definition at line 530 of file evt.c.

References ais_err2str(), ast_log(), free, event_channel::handle, subscribe_event::id, and LOG_ERROR.

Referenced by event_channel_destroy().

532 {
533  SaAisErrorT ais_res;
534 
535  /* saEvtChannelClose() will actually do this automatically, but it just
536  * feels cleaner to go ahead and do it manually ... */
537  ais_res = saEvtEventUnsubscribe(event_channel->handle, subscribe_event->id);
538  if (ais_res != SA_AIS_OK) {
539  ast_log(LOG_ERROR, "Error unsubscribing: %s\n", ais_err2str(ais_res));
540  }
541 
542  free(subscribe_event);
543 }
#define LOG_ERROR
Definition: logger.h:155
#define free(a)
Definition: astmm.h:94
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
SaEvtChannelHandleT handle
Definition: evt.c:106
const char * ais_err2str(SaAisErrorT error)
Definition: res_ais.c:105
SaEvtSubscriptionIdT id
Definition: evt.c:90
static const char* type_to_filter_str ( enum ast_event_type  type)
static

Definition at line 169 of file evt.c.

References ARRAY_LEN, and supported_event_types.

Referenced by ais_evt_show_event_channels(), ast_event_cb(), and set_egress_subscription().

170 {
171  const char *filter_str = NULL;
172  int i;
173 
174  for (i = 0; i < ARRAY_LEN(supported_event_types); i++) {
175  if (supported_event_types[i].type == type) {
176  filter_str = supported_event_types[i].str;
177  break;
178  }
179  }
180 
181  return filter_str;
182 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct @353 supported_event_types[]
static const char type[]
Definition: chan_nbs.c:57

Variable Documentation

struct ast_cli_entry ais_cli[]
static
Initial value:
= {
AST_CLI_DEFINE(ais_evt_show_event_channels, "Show configured event channels"),
}
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
static char * ais_evt_show_event_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: evt.c:261

Definition at line 315 of file evt.c.

struct event_channels event_channels = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
const SaEvtCallbacksT evt_callbacks
static
Initial value:
= {
.saEvtChannelOpenCallback = evt_channel_open_cb,
.saEvtEventDeliverCallback = evt_event_deliver_cb,
}
void evt_event_deliver_cb(SaEvtSubscriptionIdT subscription_id, const SaEvtEventHandleT event_handle, const SaSizeT event_datalen)
Definition: evt.c:123
void evt_channel_open_cb(SaInvocationT invocation, SaEvtChannelHandleT channel_handle, SaAisErrorT error)
Definition: evt.c:112

Definition at line 69 of file evt.c.

Referenced by ast_ais_evt_load_module().

SaEvtHandleT evt_handle
SaAisErrorT evt_init_res
static

Definition at line 62 of file evt.c.

Referenced by ast_ais_evt_load_module(), and ast_ais_evt_unload_module().

const char* str

Definition at line 75 of file evt.c.

struct { ... } supported_event_types[]
enum ast_event_type type

Definition at line 76 of file evt.c.

int unique_id
static

Used to provide unique id's to egress subscriptions

Definition at line 83 of file evt.c.

Referenced by add_subscribe_event().