Wed Jan 8 2020 09:50:11

Asterisk developer's documentation


devicestate.c File Reference

Device state management. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h"
#include "asterisk/pbx.h"
#include "asterisk/app.h"
#include "asterisk/event.h"

Go to the source code of this file.

Data Structures

struct  chan2dev
 Mapping for channel states to device states. More...
 
struct  change_collection
 
struct  devstate_change
 
struct  devstate_prov
 A device state provider (not a channel) More...
 
struct  devstate_provs
 A list of providers. More...
 
struct  state_change
 
struct  state_changes
 The state change queue. State changes are queued for processing by a separate thread. More...
 

Macros

#define MAX_SERVERS   64
 

Functions

static enum ast_device_state _ast_device_state (const char *device, int check_cache)
 Check device state through channel specific function or generic function. More...
 
enum ast_device_state ast_device_state (const char *device)
 Asks a channel for device state. More...
 
int ast_device_state_changed (const char *fmt,...)
 Tells Asterisk the State for Device is changed. (Accept change notification, add it to change queue.) More...
 
int ast_device_state_changed_literal (const char *dev)
 Tells Asterisk the State for Device is changed. More...
 
int ast_device_state_engine_init (void)
 Initialize the device state engine in separate thread. More...
 
const char * ast_devstate2str (enum ast_device_state devstate)
 Find devicestate as text message for output. More...
 
void ast_devstate_aggregate_add (struct ast_devstate_aggregate *agg, enum ast_device_state state)
 Add a device state to the aggregate device state. More...
 
void ast_devstate_aggregate_init (struct ast_devstate_aggregate *agg)
 Initialize aggregate device state. More...
 
enum ast_device_state ast_devstate_aggregate_result (struct ast_devstate_aggregate *agg)
 Get the aggregate device state result. More...
 
int ast_devstate_changed (enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
 Tells Asterisk the State for Device is changed. More...
 
int ast_devstate_changed_literal (enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
 Tells Asterisk the State for Device is changed. More...
 
int ast_devstate_prov_add (const char *label, ast_devstate_prov_cb_type callback)
 Add device state provider. More...
 
int ast_devstate_prov_del (const char *label)
 Remove device state provider. More...
 
const char * ast_devstate_str (enum ast_device_state state)
 Convert device state to text string that is easier to parse. More...
 
enum ast_device_state ast_devstate_val (const char *val)
 Convert device state from text to integer value. More...
 
int ast_enable_distributed_devstate (void)
 Enable distributed device state processing. More...
 
enum ast_device_state ast_parse_device_state (const char *device)
 Find out if device is active in a call or not. More...
 
enum ast_device_state ast_state_chan2dev (enum ast_channel_state chanstate)
 Convert channel state to devicestate. More...
 
static void destroy_devstate_change (struct devstate_change *sc)
 
const char * devstate2str (enum ast_device_state devstate)
 Convert device state to text string for output. More...
 
static void devstate_cache_cb (const struct ast_event *event, void *data)
 
static enum ast_device_state devstate_cached (const char *device)
 
static void devstate_change_collector_cb (const struct ast_event *event, void *data)
 
static void devstate_event (const char *device, enum ast_device_state state, int cachable)
 
static void * do_devstate_changes (void *data)
 Go through the dev state change queue and update changes in the dev state thread. More...
 
static void do_state_change (const char *device, int cachable)
 
static int getproviderstate (const char *provider, const char *address)
 Get provider device state. More...
 
static void handle_devstate_change (struct devstate_change *sc)
 
static void process_collection (const char *device, enum ast_devstate_cache cachable, struct change_collection *collection)
 
static void * run_devstate_collector (void *data)
 

Variables

static struct chan2dev chan2dev []
 
static ast_cond_t change_pending
 Flag for the queue. More...
 
static pthread_t change_thread = AST_PTHREADT_NULL
 The device state change notification thread. More...
 
struct {
   ast_cond_t   cond
 
   struct {
      struct devstate_change *   first
 
      struct devstate_change *   last
 
   }   devstate_change_q
 
   unsigned int   enabled:1
 
   struct ast_event_sub *   event_sub
 
   ast_mutex_t   lock
 
   pthread_t   thread
 
devstate_collector
 
static struct devstate_provs devstate_provs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static const char *const devstatestring [][2]
 Device state strings for printing. More...
 
static struct state_changes state_changes = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
 

Detailed Description

Macro Definition Documentation

#define MAX_SERVERS   64

Definition at line 570 of file devicestate.c.

Referenced by devstate_cache_cb().

Function Documentation

static enum ast_device_state _ast_device_state ( const char *  device,
int  check_cache 
)
static

Check device state through channel specific function or generic function.

Channel driver that provides device state

Another provider of device state

Definition at line 310 of file devicestate.c.

References ast_debug, AST_DEVICE_INVALID, AST_DEVICE_UNKNOWN, ast_get_channel_tech(), ast_parse_device_state(), ast_strdupa, ast_channel_tech::devicestate, devstate_cached(), getproviderstate(), and strsep().

Referenced by ast_device_state(), and do_state_change().

311 {
312  char *buf;
313  char *number;
314  const struct ast_channel_tech *chan_tech;
315  enum ast_device_state res;
316  /*! \brief Channel driver that provides device state */
317  char *tech;
318  /*! \brief Another provider of device state */
319  char *provider = NULL;
320 
321  /* If the last known state is cached, just return that */
322  if (check_cache) {
323  res = devstate_cached(device);
324  if (res != AST_DEVICE_UNKNOWN) {
325  return res;
326  }
327  }
328 
329  buf = ast_strdupa(device);
330  tech = strsep(&buf, "/");
331  if (!(number = buf)) {
332  provider = strsep(&tech, ":");
333  if (!tech) {
334  return AST_DEVICE_INVALID;
335  }
336  /* We have a provider */
337  number = tech;
338  tech = NULL;
339 
340  ast_debug(3, "Checking if I can find provider for \"%s\" - number: %s\n", provider, number);
341  return getproviderstate(provider, number);
342  }
343 
344  ast_debug(4, "No provider found, checking channel drivers for %s - %s\n", tech, number);
345 
346  if (!(chan_tech = ast_get_channel_tech(tech)))
347  return AST_DEVICE_INVALID;
348 
349  if (!(chan_tech->devicestate)) /* Does the channel driver support device state notification? */
350  return ast_parse_device_state(device); /* No, try the generic function */
351 
352  res = chan_tech->devicestate(number);
353 
354  if (res != AST_DEVICE_UNKNOWN)
355  return res;
356 
357  res = ast_parse_device_state(device);
358 
359  return res;
360 }
ast_device_state
Device States.
Definition: devicestate.h:51
char * strsep(char **str, const char *delims)
static int getproviderstate(const char *provider, const char *address)
Get provider device state.
Definition: devicestate.c:410
struct ast_channel_tech * ast_get_channel_tech(const char *name)
Get a channel technology structure by name.
Definition: channel.c:960
static enum ast_device_state devstate_cached(const char *device)
Definition: devicestate.c:290
enum ast_device_state ast_parse_device_state(const char *device)
Search the Channels by Name.
Definition: devicestate.c:271
Number structure.
Definition: app_followme.c:109
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:507
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int(*const devicestate)(void *data)
Definition: channel.h:521
enum ast_device_state ast_device_state ( const char *  device)

Asks a channel for device state.

Parameters
devicelike a dial string

Asks a channel for device state, data is normally a number from a dial string used by the low level module Tries the channel device state callback if not supported search in the active channels list for the device.

Return values
anAST_DEVICE_??? state

Definition at line 362 of file devicestate.c.

References _ast_device_state().

363 {
364  /* This function is called from elsewhere in the code to find out the
365  * current state of a device. Check the cache, first. */
366 
367  return _ast_device_state(device, 1);
368 }
static enum ast_device_state _ast_device_state(const char *device, int check_cache)
Check device state through channel specific function or generic function.
Definition: devicestate.c:310
int ast_device_state_changed ( const char *  fmt,
  ... 
)

Tells Asterisk the State for Device is changed. (Accept change notification, add it to change queue.)

Parameters
fmtdevice name like a dial string with format parameters

Asterisk polls the new extension states and calls the registered callbacks for the changed extensions

Return values
0on success
-1on failure
Note
This is deprecated in favor of ast_devstate_changed()
Version
1.6.1 deprecated

Definition at line 528 of file devicestate.c.

References AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed_literal(), and AST_MAX_EXTENSION.

529 {
530  char buf[AST_MAX_EXTENSION];
531  va_list ap;
532 
533  va_start(ap, fmt);
534  vsnprintf(buf, sizeof(buf), fmt, ap);
535  va_end(ap);
536 
538 }
#define AST_MAX_EXTENSION
Definition: channel.h:135
int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:472
int ast_device_state_changed_literal ( const char *  device)

Tells Asterisk the State for Device is changed.

Parameters
devicedevice name like a dial string

Asterisk polls the new extension states and calls the registered callbacks for the changed extensions

Return values
0on success
-1on failure
Note
This is deprecated in favor of ast_devstate_changed_literal()
Version
1.6.1 deprecated

Definition at line 511 of file devicestate.c.

References AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, and ast_devstate_changed_literal().

512 {
514 }
int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:472
int ast_device_state_engine_init ( void  )

Initialize the device state engine in separate thread.

Provided by devicestate.c

Definition at line 747 of file devicestate.c.

References ast_cond_init, ast_log(), ast_pthread_create_background, change_thread, do_devstate_changes(), and LOG_ERROR.

Referenced by main().

748 {
751  ast_log(LOG_ERROR, "Unable to start device state change thread.\n");
752  return -1;
753  }
754 
755  return 0;
756 }
#define ast_cond_init(cond, attr)
Definition: lock.h:167
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
#define LOG_ERROR
Definition: logger.h:155
static pthread_t change_thread
The device state change notification thread.
Definition: devicestate.c:186
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 * do_devstate_changes(void *data)
Go through the dev state change queue and update changes in the dev state thread. ...
Definition: devicestate.c:541
static ast_cond_t change_pending
Flag for the queue.
Definition: devicestate.c:189
const char* ast_devstate2str ( enum ast_device_state  devstate)

Find devicestate as text message for output.

Definition at line 215 of file devicestate.c.

Referenced by __queues_show(), do_state_change(), extension_state_cb(), handle_statechange(), notify_metermaids(), page_exec(), process_collection(), and queue_function_queuememberstatus().

216 {
217  return devstatestring[devstate][0];
218 }
static const char *const devstatestring[][2]
Device state strings for printing.
Definition: devicestate.c:135
void ast_devstate_aggregate_add ( struct ast_devstate_aggregate agg,
enum ast_device_state  state 
)

Add a device state to the aggregate device state.

Parameters
[in]aggthe state object
[in]statethe state to add
Returns
nothing
Since
1.6.1

Definition at line 764 of file devicestate.c.

References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, ast_devstate_aggregate::inuse, ast_devstate_aggregate::ringing, ast_devstate_aggregate::state, and state.

Referenced by ast_extension_state3(), and process_collection().

765 {
766  static enum ast_device_state state_order[] = {
767  1, /* AST_DEVICE_UNKNOWN */
768  3, /* AST_DEVICE_NOT_INUSE */
769  6, /* AST_DEVICE_INUSE */
770  7, /* AST_DEVICE_BUSY */
771  0, /* AST_DEVICE_INVALID */
772  2, /* AST_DEVICE_UNAVAILABLE */
773  5, /* AST_DEVICE_RINGING */
774  8, /* AST_DEVICE_RINGINUSE */
775  4, /* AST_DEVICE_ONHOLD */
776  };
777 
778  if (state == AST_DEVICE_RINGING) {
779  agg->ringing = 1;
781  agg->inuse = 1;
782  }
783 
784  if (agg->ringing && agg->inuse) {
786  } else if (state_order[state] > state_order[agg->state]) {
787  agg->state = state;
788  }
789 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
ast_device_state
Device States.
Definition: devicestate.h:51
unsigned int ringing
Definition: devicestate.h:266
enum ast_device_state state
Definition: devicestate.h:268
void ast_devstate_aggregate_init ( struct ast_devstate_aggregate agg)

Initialize aggregate device state.

Parameters
[in]aggthe state object
Returns
nothing
Since
1.6.1

Definition at line 758 of file devicestate.c.

References AST_DEVICE_INVALID, and ast_devstate_aggregate::state.

Referenced by ast_extension_state3(), and process_collection().

759 {
760  memset(agg, 0, sizeof(*agg));
761  agg->state = AST_DEVICE_INVALID;
762 }
enum ast_device_state state
Definition: devicestate.h:268
enum ast_device_state ast_devstate_aggregate_result ( struct ast_devstate_aggregate agg)

Get the aggregate device state result.

Parameters
[in]aggthe state object
Returns
the aggregate device state after adding some number of device states.
Since
1.6.1

Definition at line 791 of file devicestate.c.

References ast_devstate_aggregate::state.

Referenced by ast_extension_state3(), and process_collection().

792 {
793  return agg->state;
794 }
enum ast_device_state state
Definition: devicestate.h:268
int ast_devstate_changed ( enum ast_device_state  state,
enum ast_devstate_cache  cachable,
const char *  fmt,
  ... 
)

Tells Asterisk the State for Device is changed.

Parameters
statethe new state of the device
cachablewhether this device state is cachable
fmtdevice name like a dial string with format parameters

The new state of the device will be sent off to any subscribers of device states. It will also be stored in the internal event cache.

Return values
0on success
-1on failure

Definition at line 516 of file devicestate.c.

References ast_devstate_changed_literal(), and AST_MAX_EXTENSION.

Referenced by __expire_registry(), __iax2_poke_noanswer(), calendar_devstate_change(), conf_run(), dahdi_pri_update_span_devstate(), destroy_event(), devstate_write(), expire_register(), handle_cli_devstate_change(), handle_offhook_message(), handle_onhook_message(), handle_response_peerpoke(), handle_soft_key_event_message(), handle_stimulus_message(), join_conference_bridge(), leave_conference_bridge(), load_module(), login_exec(), notify_metermaids(), reg_source_db(), register_verify(), sip_peer_hold(), sip_poke_noanswer(), skinny_register(), skinny_unregister(), sla_change_trunk_state(), sla_handle_hold_event(), sla_station_exec(), socket_process(), update_call_counter(), and update_registry().

517 {
518  char buf[AST_MAX_EXTENSION];
519  va_list ap;
520 
521  va_start(ap, fmt);
522  vsnprintf(buf, sizeof(buf), fmt, ap);
523  va_end(ap);
524 
525  return ast_devstate_changed_literal(state, cachable, buf);
526 }
#define AST_MAX_EXTENSION
Definition: channel.h:135
int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:472
int ast_devstate_changed_literal ( enum ast_device_state  state,
enum ast_devstate_cache  cachable,
const char *  device 
)

Tells Asterisk the State for Device is changed.

Parameters
statethe new state of the device
cachablewhether this device state is cachable
devicedevice name like a dial string with format parameters

The new state of the device will be sent off to any subscribers of device states. It will also be stored in the internal event cache.

Return values
0on success
-1on failure

Definition at line 472 of file devicestate.c.

References ast_calloc, ast_cond_signal, AST_DEVICE_UNKNOWN, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, state_change::cachable, change_thread, state_change::device, devstate_event(), and do_state_change().

Referenced by ast_channel_destructor(), ast_device_state_changed(), ast_device_state_changed_literal(), ast_devstate_changed(), ast_setstate(), and dahdi_new().

473 {
474  struct state_change *change;
475 
476  /*
477  * If we know the state change (how nice of the caller of this function!)
478  * then we can just generate a device state event.
479  *
480  * Otherwise, we do the following:
481  * - Queue an event up to another thread that the state has changed
482  * - In the processing thread, it calls the callback provided by the
483  * device state provider (which may or may not be a channel driver)
484  * to determine the state.
485  * - If the device state provider does not know the state, or this is
486  * for a channel and the channel driver does not implement a device
487  * state callback, then we will look through the channel list to
488  * see if we can determine a state based on active calls.
489  * - Once a state has been determined, a device state event is generated.
490  */
491 
492  if (state != AST_DEVICE_UNKNOWN) {
494  } else if (change_thread == AST_PTHREADT_NULL || !(change = ast_calloc(1, sizeof(*change) + strlen(device)))) {
495  /* we could not allocate a change struct, or */
496  /* there is no background thread, so process the change now */
498  } else {
499  /* queue the change */
500  strcpy(change->device, device);
501  change->cachable = cachable;
506  }
507 
508  return 0;
509 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static void devstate_event(const char *device, enum ast_device_state state, int cachable)
Definition: devicestate.c:429
struct state_change::@249 list
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
enum ast_devstate_cache cachable
Definition: devicestate.c:177
#define ast_cond_signal(cond)
Definition: lock.h:169
static void do_state_change(const char *device, int cachable)
Definition: devicestate.c:461
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
static pthread_t change_thread
The device state change notification thread.
Definition: devicestate.c:186
char device[1]
Definition: devicestate.c:178
static ast_cond_t change_pending
Flag for the queue.
Definition: devicestate.c:189
#define ast_calloc(a, b)
Definition: astmm.h:82
The state change queue. State changes are queued for processing by a separate thread.
Definition: devicestate.c:183
int ast_devstate_prov_add ( const char *  label,
ast_devstate_prov_cb_type  callback 
)

Add device state provider.

Parameters
labelto use in hint, like label:object
callbackCallback
Return values
0success
-1failure

Definition at line 371 of file devicestate.c.

References ast_calloc, ast_copy_string(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, devstate_prov::callback, and devstate_prov::label.

Referenced by ast_features_init(), and load_module().

372 {
373  struct devstate_prov *devprov;
374 
375  if (!callback || !(devprov = ast_calloc(1, sizeof(*devprov))))
376  return -1;
377 
378  devprov->callback = callback;
379  ast_copy_string(devprov->label, label, sizeof(devprov->label));
380 
382  AST_RWLIST_INSERT_HEAD(&devstate_provs, devprov, list);
384 
385  return 0;
386 }
A list of providers.
Definition: devicestate.c:173
A device state provider (not a channel)
Definition: devicestate.c:166
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
ast_devstate_prov_cb_type callback
Definition: devicestate.c:168
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:703
char label[40]
Definition: devicestate.c:167
#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
int ast_devstate_prov_del ( const char *  label)

Remove device state provider.

Parameters
labelto use in hint, like label:object
Return values
-1on failure
0on success

Definition at line 389 of file devicestate.c.

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and devstate_prov::label.

Referenced by cc_shutdown(), features_shutdown(), and unload_module().

390 {
391  struct devstate_prov *devcb;
392  int res = -1;
393 
396  if (!strcasecmp(devcb->label, label)) {
398  ast_free(devcb);
399  res = 0;
400  break;
401  }
402  }
405 
406  return res;
407 }
A list of providers.
Definition: devicestate.c:173
A device state provider (not a channel)
Definition: devicestate.c:166
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:565
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
#define ast_free(a)
Definition: astmm.h:97
char label[40]
Definition: devicestate.c:167
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
const char* ast_devstate_str ( enum ast_device_state  devstate)

Convert device state to text string that is easier to parse.

Parameters
devstateCurrent device state

Definition at line 239 of file devicestate.c.

References state.

Referenced by aji_devstate_cb(), and devstate_read().

240 {
241  return devstatestring[state][1];
242 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
static const char *const devstatestring[][2]
Device state strings for printing.
Definition: devicestate.c:135
enum ast_device_state ast_devstate_val ( const char *  val)

Convert device state from text to integer value.

Parameters
valThe text representing the device state. Valid values are anything that comes after AST_DEVICE_ in one of the defined values.
Returns
The AST_DEVICE_ integer value

Definition at line 244 of file devicestate.c.

References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, and AST_DEVICE_UNKNOWN.

Referenced by aji_handle_pubsub_event(), custom_devstate_callback(), devstate_write(), handle_cli_devstate_change(), and load_module().

245 {
246  if (!strcasecmp(val, "NOT_INUSE"))
247  return AST_DEVICE_NOT_INUSE;
248  else if (!strcasecmp(val, "INUSE"))
249  return AST_DEVICE_INUSE;
250  else if (!strcasecmp(val, "BUSY"))
251  return AST_DEVICE_BUSY;
252  else if (!strcasecmp(val, "INVALID"))
253  return AST_DEVICE_INVALID;
254  else if (!strcasecmp(val, "UNAVAILABLE"))
255  return AST_DEVICE_UNAVAILABLE;
256  else if (!strcasecmp(val, "RINGING"))
257  return AST_DEVICE_RINGING;
258  else if (!strcasecmp(val, "RINGINUSE"))
259  return AST_DEVICE_RINGINUSE;
260  else if (!strcasecmp(val, "ONHOLD"))
261  return AST_DEVICE_ONHOLD;
262 
263  return AST_DEVICE_UNKNOWN;
264 }
Definition: ast_expr2.c:325
int ast_enable_distributed_devstate ( void  )

Enable distributed device state processing.

By default, Asterisk assumes that device state change events will only be originating from one instance. If a module gets loaded and configured such that multiple instances of Asterisk will be sharing device state, this function should be called to enable distributed device state processing. It is off by default to save on unnecessary processing.

Return values
0success
-1failure

Definition at line 796 of file devicestate.c.

References ast_cond_init, AST_EVENT_DEVICE_STATE_CHANGE, AST_EVENT_IE_END, ast_event_subscribe(), ast_log(), ast_mutex_init, ast_pthread_create_background, devstate_change_collector_cb(), devstate_collector, LOG_ERROR, and run_devstate_collector().

Referenced by add_publish_event(), add_subscribe_event(), and aji_init_event_distribution().

797 {
798  if (devstate_collector.enabled) {
799  return 0;
800  }
801 
803  devstate_change_collector_cb, "devicestate_engine_enable_distributed", NULL, AST_EVENT_IE_END);
804 
805  if (!devstate_collector.event_sub) {
806  ast_log(LOG_ERROR, "Failed to create subscription for the device state change collector\n");
807  return -1;
808  }
809 
811  ast_cond_init(&devstate_collector.cond, NULL);
813  ast_log(LOG_ERROR, "Unable to start device state collector thread.\n");
814  return -1;
815  }
816 
817  devstate_collector.enabled = 1;
818 
819  return 0;
820 }
static struct @248 devstate_collector
#define ast_cond_init(cond, attr)
Definition: lock.h:167
static void * run_devstate_collector(void *data)
Definition: devicestate.c:687
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
static void devstate_change_collector_cb(const struct ast_event *event, void *data)
Definition: devicestate.c:705
#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
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
#define ast_mutex_init(pmutex)
Definition: lock.h:152
enum ast_device_state ast_parse_device_state ( const char *  device)

Find out if device is active in a call or not.

Search the Channels by Name.

Note
find channels with the device's name in it This function is only used for channels that does not implement devicestate natively

Definition at line 271 of file devicestate.c.

References ast_channel::_state, ast_channel_get_by_name_prefix(), AST_CHANNEL_NAME, ast_channel_unref, AST_DEVICE_INUSE, AST_DEVICE_RINGING, AST_DEVICE_UNKNOWN, AST_STATE_RINGING, and match().

Referenced by _ast_device_state(), and chanavail_exec().

272 {
273  struct ast_channel *chan;
274  char match[AST_CHANNEL_NAME];
275  enum ast_device_state res;
276 
277  snprintf(match, sizeof(match), "%s-", device);
278 
279  if (!(chan = ast_channel_get_by_name_prefix(match, strlen(match)))) {
280  return AST_DEVICE_UNKNOWN;
281  }
282 
284 
285  chan = ast_channel_unref(chan);
286 
287  return res;
288 }
Main Channel structure associated with a channel.
Definition: channel.h:742
ast_device_state
Device States.
Definition: devicestate.h:51
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
Definition: channel.c:1808
enum ast_channel_state _state
Definition: channel.h:839
#define AST_CHANNEL_NAME
Definition: channel.h:137
static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2069
enum ast_device_state ast_state_chan2dev ( enum ast_channel_state  chanstate)

Convert channel state to devicestate.

Parameters
chanstateCurrent channel state
Since
1.6.1

Definition at line 226 of file devicestate.c.

References AST_DEVICE_UNKNOWN, chan2dev::chan, and chan2dev::dev.

227 {
228  int i;
229  chanstate &= 0xFFFF;
230  for (i = 0; chan2dev[i].chan != -100; i++) {
231  if (chan2dev[i].chan == chanstate) {
232  return chan2dev[i].dev;
233  }
234  }
235  return AST_DEVICE_UNKNOWN;
236 }
enum ast_device_state dev
Definition: devicestate.c:150
enum ast_channel_state chan
Definition: devicestate.c:149
Mapping for channel states to device states.
Definition: devicestate.c:148
static void destroy_devstate_change ( struct devstate_change sc)
static

Definition at line 565 of file devicestate.c.

References ast_free.

Referenced by run_devstate_collector().

566 {
567  ast_free(sc);
568 }
#define ast_free(a)
Definition: astmm.h:97
const char* devstate2str ( enum ast_device_state  devstate)

Convert device state to text string for output.

Parameters
devstateCurrent device state

Definition at line 221 of file devicestate.c.

222 {
223  return devstatestring[devstate][0];
224 }
static const char *const devstatestring[][2]
Device state strings for printing.
Definition: devicestate.c:135
static void devstate_cache_cb ( const struct ast_event event,
void *  data 
)
static

Definition at line 576 of file devicestate.c.

References ARRAY_LEN, ast_event_get_ie_raw(), ast_event_get_ie_uint(), AST_EVENT_IE_EID, AST_EVENT_IE_STATE, ast_log(), devstate_change::eid, ast_eid::eid, LOG_ERROR, MAX_SERVERS, change_collection::num_states, devstate_change::state, and change_collection::states.

Referenced by handle_devstate_change().

577 {
578  struct change_collection *collection = data;
579  int i;
580  const struct ast_eid *eid;
581 
582  if (collection->num_states == ARRAY_LEN(collection->states)) {
583  ast_log(LOG_ERROR, "More per-server state values than we have room for (MAX_SERVERS is %d)\n",
584  MAX_SERVERS);
585  return;
586  }
587 
588  if (!(eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID))) {
589  ast_log(LOG_ERROR, "Device state change event with no EID\n");
590  return;
591  }
592 
593  i = collection->num_states;
594 
595  collection->states[i].state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
596  collection->states[i].eid = *eid;
597 
598  collection->num_states++;
599 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_eid eid
Definition: devicestate.c:194
struct devstate_change states[MAX_SERVERS]
Definition: devicestate.c:572
An Entity ID is essentially a MAC address, brief and unique.
Definition: utils.h:808
Entity ID Used by All events Payload type: RAW This IE indicates which server the event originated fr...
Definition: event_defs.h:266
uint32_t state
Definition: devicestate.c:193
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
unsigned char eid[6]
Definition: utils.h:809
#define MAX_SERVERS
Definition: devicestate.c:570
#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
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.
Definition: event.c:1075
Generic State IE Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: UINT The actual state values dep...
Definition: event_defs.h:115
static enum ast_device_state devstate_cached ( const char *  device)
static

Definition at line 290 of file devicestate.c.

References AST_DEVICE_UNKNOWN, ast_event_destroy(), AST_EVENT_DEVICE_STATE, ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_DEVICE, AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_STR, and AST_EVENT_IE_STATE.

Referenced by _ast_device_state().

291 {
293  struct ast_event *event;
294 
298 
299  if (!event)
300  return res;
301 
303 
304  ast_event_destroy(event);
305 
306  return res;
307 }
ast_device_state
Device States.
Definition: devicestate.h:51
An event.
Definition: event.c:85
struct ast_event * ast_event_get_cached(enum ast_event_type,...)
Retrieve an event from the cache.
Definition: event.c:1342
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.
Definition: event.c:1075
void ast_event_destroy(struct ast_event *event)
Destroy an event.
Definition: event.c:1314
Generic State IE Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: UINT The actual state values dep...
Definition: event_defs.h:115
Device Name Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: STR.
Definition: event_defs.h:107
static void devstate_change_collector_cb ( const struct ast_event event,
void *  data 
)
static

Definition at line 705 of file devicestate.c.

References ast_calloc, ast_cond_signal, AST_DEVSTATE_CACHABLE, ast_event_get_ie_raw(), ast_event_get_ie_str(), ast_event_get_ie_uint(), AST_EVENT_IE_CACHABLE, AST_EVENT_IE_DEVICE, AST_EVENT_IE_EID, AST_EVENT_IE_STATE, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), devstate_change::cachable, devstate_change::device, devstate_collector, devstate_change::eid, ast_eid::eid, LOG_ERROR, devstate_change::state, and state.

Referenced by ast_enable_distributed_devstate().

706 {
707  struct devstate_change *sc;
708  const char *device, *cachable_str;
709  const struct ast_eid *eid;
710  uint32_t state;
712 
713  device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
716 
717  if (ast_strlen_zero(device) || !eid) {
718  ast_log(LOG_ERROR, "Invalid device state change event received\n");
719  return;
720  }
721 
722  if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(device))))
723  return;
724 
725  strcpy(sc->device, device);
726  sc->eid = *eid;
727  sc->state = state;
728 
729  /* For 'cachable' we cannot use ast_event_get_ie_uint(), it overwrites the default of AST_DEVSTATE_CACHABLE we
730  * have already setup for 'cachable', if for whatever reason the AST_EVENT_IE_CACHABLE wasn't
731  * posted in the event ast_event_get_ie_uint() is going will return 0,
732  * which equates to AST_DEVSTATE_NOT_CACHABLE the first enumeration in 'ast_devstate_cache'.
733  */
734 
735  if ((cachable_str = ast_event_get_ie_str(event, AST_EVENT_IE_CACHABLE))) {
736  sscanf(cachable_str, "%30u", &cachable);
737  }
738  sc->cachable = cachable;
739 
741  AST_LIST_INSERT_TAIL(&devstate_collector.devstate_change_q, sc, entry);
744 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
static struct @248 devstate_collector
struct ast_eid eid
Definition: devicestate.c:194
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_cond_signal(cond)
Definition: lock.h:169
An Entity ID is essentially a MAC address, brief and unique.
Definition: utils.h:808
Entity ID Used by All events Payload type: RAW This IE indicates which server the event originated fr...
Definition: event_defs.h:266
uint32_t state
Definition: devicestate.c:193
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
Event non-cachability flag Used by: All events Payload type: UINT.
Definition: event_defs.h:291
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
unsigned char eid[6]
Definition: utils.h:809
#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
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
enum ast_devstate_cache cachable
Definition: devicestate.c:195
ast_devstate_cache
Device State Cachability.
Definition: devicestate.h:67
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.
Definition: event.c:1075
#define ast_calloc(a, b)
Definition: astmm.h:82
Generic State IE Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: UINT The actual state values dep...
Definition: event_defs.h:115
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.
Definition: event.c:1102
Device Name Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: STR.
Definition: event_defs.h:107
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void devstate_event ( const char *  device,
enum ast_device_state  state,
int  cachable 
)
static

Definition at line 429 of file devicestate.c.

References ast_debug, AST_EVENT_DEVICE_STATE, AST_EVENT_DEVICE_STATE_CHANGE, AST_EVENT_IE_CACHABLE, AST_EVENT_IE_DEVICE, AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_STATE, ast_event_new(), ast_event_queue(), ast_event_queue_and_cache(), and devstate_collector.

Referenced by ast_devstate_changed_literal(), and do_state_change().

430 {
431  struct ast_event *event;
432  enum ast_event_type event_type;
433 
434  if (devstate_collector.enabled) {
435  /* Distributed device state is enabled, so this state change is a change
436  * for a single server, not the real state. */
437  event_type = AST_EVENT_DEVICE_STATE_CHANGE;
438  } else {
439  event_type = AST_EVENT_DEVICE_STATE;
440  }
441 
442  ast_debug(3, "device '%s' state '%u'\n", device, state);
443 
444  if (!(event = ast_event_new(event_type,
448  AST_EVENT_IE_END))) {
449  return;
450  }
451 
452  if (cachable) {
454  } else {
455  ast_event_queue(event);
456  }
457 }
An event.
Definition: event.c:85
static struct @248 devstate_collector
int ast_event_queue_and_cache(struct ast_event *event)
Queue and cache an event.
Definition: event.c:1465
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_event_queue(struct ast_event *event)
Queue an event.
Definition: event.c:1517
ast_event_type
Event types.
Definition: event_defs.h:30
Event non-cachability flag Used by: All events Payload type: UINT.
Definition: event_defs.h:291
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
Definition: event.c:1202
Generic State IE Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: UINT The actual state values dep...
Definition: event_defs.h:115
Device Name Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: STR.
Definition: event_defs.h:107
static void* do_devstate_changes ( void *  data)
static

Go through the dev state change queue and update changes in the dev state thread.

Definition at line 541 of file devicestate.c.

References ast_cond_wait, ast_free, AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_UNLOCK, state_change::cachable, state_change::device, do_state_change(), and state_change::next.

Referenced by ast_device_state_engine_init().

542 {
543  struct state_change *next, *current;
544 
545  for (;;) {
546  /* This basically pops off any state change entries, resets the list back to NULL, unlocks, and processes each state change */
550  next = AST_LIST_FIRST(&state_changes);
553 
554  /* Process each state change */
555  while ((current = next)) {
556  next = AST_LIST_NEXT(current, list);
557  do_state_change(current->device, current->cachable);
558  ast_free(current);
559  }
560  }
561 
562  return NULL;
563 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct state_change * next
Definition: devicestate.c:176
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
struct state_change::@249 list
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
#define ast_cond_wait(cond, mutex)
Definition: lock.h:171
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
enum ast_devstate_cache cachable
Definition: devicestate.c:177
ast_mutex_t lock
Definition: devicestate.c:183
static void do_state_change(const char *device, int cachable)
Definition: devicestate.c:461
char device[1]
Definition: devicestate.c:178
#define ast_free(a)
Definition: astmm.h:97
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:666
static ast_cond_t change_pending
Flag for the queue.
Definition: devicestate.c:189
The state change queue. State changes are queued for processing by a separate thread.
Definition: devicestate.c:183
static void do_state_change ( const char *  device,
int  cachable 
)
static

Called by the state change thread to find out what the state is, and then to queue up the state change event

Definition at line 461 of file devicestate.c.

References _ast_device_state(), ast_debug, ast_devstate2str(), devstate_event(), and state.

Referenced by ast_devstate_changed_literal(), and do_devstate_changes().

462 {
463  enum ast_device_state state;
464 
465  state = _ast_device_state(device, 0);
466 
467  ast_debug(3, "Changing state for %s - state %u (%s)\n", device, state, ast_devstate2str(state));
468 
469  devstate_event(device, state, cachable);
470 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
const char * ast_devstate2str(enum ast_device_state devstate) attribute_pure
Find devicestate as text message for output.
Definition: devicestate.c:215
ast_device_state
Device States.
Definition: devicestate.h:51
static void devstate_event(const char *device, enum ast_device_state state, int cachable)
Definition: devicestate.c:429
enum ast_devstate_cache cachable
Definition: devicestate.c:177
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char device[1]
Definition: devicestate.c:178
static enum ast_device_state _ast_device_state(const char *device, int check_cache)
Check device state through channel specific function or generic function.
Definition: devicestate.c:310
static int getproviderstate ( const char *  provider,
const char *  address 
)
static

Get provider device state.

Definition at line 410 of file devicestate.c.

References ast_debug, AST_DEVICE_INVALID, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, devstate_prov::callback, and devstate_prov::label.

Referenced by _ast_device_state().

411 {
412  struct devstate_prov *devprov;
413  int res = AST_DEVICE_INVALID;
414 
416  AST_RWLIST_TRAVERSE(&devstate_provs, devprov, list) {
417  ast_debug(5, "Checking provider %s with %s\n", devprov->label, provider);
418 
419  if (!strcasecmp(devprov->label, provider)) {
420  res = devprov->callback(address);
421  break;
422  }
423  }
425 
426  return res;
427 }
A list of providers.
Definition: devicestate.c:173
A device state provider (not a channel)
Definition: devicestate.c:166
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
ast_devstate_prov_cb_type callback
Definition: devicestate.c:168
#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
char label[40]
Definition: devicestate.c:167
static void handle_devstate_change ( struct devstate_change sc)
static

Definition at line 659 of file devicestate.c.

References ast_debug, AST_EVENT_DEVICE_STATE_CHANGE, ast_event_dump_cache(), AST_EVENT_IE_DEVICE, ast_event_sub_append_ie_str(), ast_event_sub_destroy(), ast_event_subscribe_new(), ast_log(), devstate_change::cachable, devstate_change::device, devstate_cache_cb(), LOG_ERROR, change_collection::num_states, and process_collection().

Referenced by run_devstate_collector().

660 {
661  struct ast_event_sub *tmp_sub;
662  struct change_collection collection = {
663  .num_states = 0,
664  };
665 
666  ast_debug(1, "Processing device state change for '%s'\n", sc->device);
667 
669  ast_log(LOG_ERROR, "Failed to create subscription\n");
670  return;
671  }
672 
674  ast_log(LOG_ERROR, "Failed to append device IE\n");
675  ast_event_sub_destroy(tmp_sub);
676  return;
677  }
678 
679  /* Populate the collection of device states from the cache */
680  ast_event_dump_cache(tmp_sub);
681 
682  process_collection(sc->device, sc->cachable, &collection);
683 
684  ast_event_sub_destroy(tmp_sub);
685 }
int ast_event_sub_append_ie_str(struct ast_event_sub *sub, enum ast_event_ie_type ie_type, const char *str)
Append a string parameter to a subscription.
Definition: event.c:826
static void devstate_cache_cb(const struct ast_event *event, void *data)
Definition: devicestate.c:576
void ast_event_sub_destroy(struct ast_event_sub *sub)
Destroy an allocated subscription.
Definition: event.c:971
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
void ast_event_dump_cache(const struct ast_event_sub *event_sub)
Dump the event cache for the subscriber.
Definition: event.c:654
#define LOG_ERROR
Definition: logger.h:155
Event subscription.
Definition: event.c:124
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
enum ast_devstate_cache cachable
Definition: devicestate.c:195
Device Name Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: STR.
Definition: event_defs.h:107
struct ast_event_sub * ast_event_subscribe_new(enum ast_event_type type, ast_event_cb_t cb, void *userdata)
Allocate a subscription, but do not activate it.
Definition: event.c:739
static void process_collection(const char *device, enum ast_devstate_cache cachable, struct change_collection *collection)
Definition: devicestate.c:601
static void process_collection ( const char *  device,
enum ast_devstate_cache  cachable,
struct change_collection collection 
)
static

Definition at line 601 of file devicestate.c.

References ast_debug, ast_devstate2str(), ast_devstate_aggregate_add(), ast_devstate_aggregate_init(), ast_devstate_aggregate_result(), ast_event_destroy(), AST_EVENT_DEVICE_STATE, ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_DEVICE, AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_STATE, ast_event_new(), ast_event_queue(), ast_event_queue_and_cache(), change_collection::num_states, devstate_change::state, state, and change_collection::states.

Referenced by handle_devstate_change().

602 {
603  int i;
604  struct ast_devstate_aggregate agg;
605  enum ast_device_state state;
606  struct ast_event *event;
607 
609 
610  for (i = 0; i < collection->num_states; i++) {
611  ast_debug(1, "Adding per-server state of '%s' for '%s'\n",
612  ast_devstate2str(collection->states[i].state), device);
613  ast_devstate_aggregate_add(&agg, collection->states[i].state);
614  }
615 
616  state = ast_devstate_aggregate_result(&agg);
617 
618  ast_debug(1, "Aggregate devstate result is '%s' for '%s'\n",
619  ast_devstate2str(state), device);
620 
624 
625  if (event) {
626  enum ast_device_state old_state;
627 
628  old_state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
629 
630  ast_event_destroy(event);
631 
632  if (state == old_state) {
633  /* No change since last reported device state */
634  ast_debug(1, "Aggregate state for device '%s' has not changed from '%s'\n",
635  device, ast_devstate2str(state));
636  return;
637  }
638  }
639 
640  ast_debug(1, "Aggregate state for device '%s' has changed to '%s'\n",
641  device, ast_devstate2str(state));
642 
647 
648  if (!event) {
649  return;
650  }
651 
652  if (cachable) {
654  } else {
655  ast_event_queue(event);
656  }
657 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
const char * ast_devstate2str(enum ast_device_state devstate) attribute_pure
Find devicestate as text message for output.
Definition: devicestate.c:215
ast_device_state
Device States.
Definition: devicestate.h:51
An event.
Definition: event.c:85
int ast_event_queue_and_cache(struct ast_event *event)
Queue and cache an event.
Definition: event.c:1465
struct devstate_change states[MAX_SERVERS]
Definition: devicestate.c:572
struct ast_event * ast_event_get_cached(enum ast_event_type,...)
Retrieve an event from the cache.
Definition: event.c:1342
enum ast_device_state ast_devstate_aggregate_result(struct ast_devstate_aggregate *agg)
Get the aggregate device state result.
Definition: devicestate.c:791
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_event_queue(struct ast_event *event)
Queue an event.
Definition: event.c:1517
uint32_t state
Definition: devicestate.c:193
void ast_devstate_aggregate_add(struct ast_devstate_aggregate *agg, enum ast_device_state state)
Add a device state to the aggregate device state.
Definition: devicestate.c:764
void ast_devstate_aggregate_init(struct ast_devstate_aggregate *agg)
Initialize aggregate device state.
Definition: devicestate.c:758
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.
Definition: event.c:1075
void ast_event_destroy(struct ast_event *event)
Destroy an event.
Definition: event.c:1314
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
Definition: event.c:1202
You shouldn&#39;t care about the contents of this struct.
Definition: devicestate.h:265
Generic State IE Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: UINT The actual state values dep...
Definition: event_defs.h:115
Device Name Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: STR.
Definition: event_defs.h:107
static void* run_devstate_collector ( void *  data)
static

Definition at line 687 of file devicestate.c.

References ast_cond_wait, AST_LIST_REMOVE_HEAD, ast_mutex_lock, ast_mutex_unlock, destroy_devstate_change(), devstate_collector, and handle_devstate_change().

Referenced by ast_enable_distributed_devstate().

688 {
689  for (;;) {
690  struct devstate_change *sc;
691 
693  while (!(sc = AST_LIST_REMOVE_HEAD(&devstate_collector.devstate_change_q, entry)))
696 
698 
700  }
701 
702  return NULL;
703 }
static struct @248 devstate_collector
#define ast_cond_wait(cond, mutex)
Definition: lock.h:171
#define ast_mutex_lock(a)
Definition: lock.h:155
static void destroy_devstate_change(struct devstate_change *sc)
Definition: devicestate.c:565
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
static void handle_devstate_change(struct devstate_change *sc)
Definition: devicestate.c:659
struct devstate_change::@250 entry
#define ast_mutex_unlock(a)
Definition: lock.h:156

Variable Documentation

struct chan2dev chan2dev[]
static
ast_cond_t change_pending
static

Flag for the queue.

Definition at line 189 of file devicestate.c.

pthread_t change_thread = AST_PTHREADT_NULL
static

The device state change notification thread.

Definition at line 186 of file devicestate.c.

Referenced by ast_device_state_engine_init(), and ast_devstate_changed_literal().

ast_cond_t cond

Definition at line 202 of file devicestate.c.

struct { ... } devstate_change_q
struct { ... } devstate_collector
Initial value:
= {
.thread = AST_PTHREADT_NULL,
.enabled = 0,
}
#define AST_PTHREADT_NULL
Definition: lock.h:65

Referenced by ast_enable_distributed_devstate(), devstate_change_collector_cb(), devstate_event(), and run_devstate_collector().

struct devstate_provs devstate_provs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
const char* const devstatestring[][2]
static

Device state strings for printing.

Definition at line 135 of file devicestate.c.

unsigned int enabled

Definition at line 205 of file devicestate.c.

Referenced by __ast_http_load(), load_odbc_config(), and osp_check_destination().

struct ast_event_sub* event_sub

Definition at line 201 of file devicestate.c.

Referenced by dump_cache_cb().

struct devstate_change* first

Definition at line 204 of file devicestate.c.

struct devstate_change* last

Definition at line 204 of file devicestate.c.

Definition at line 203 of file devicestate.c.

struct state_changes state_changes = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
static
pthread_t thread

Definition at line 200 of file devicestate.c.