Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Data Structures | Macros | Functions | Variables
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/astobj2.h"
#include "asterisk/stasis.h"
Include dependency graph for devicestate.c:

Go to the source code of this file.

Data Structures

struct  chan2dev
 Mapping for channel states to device states. More...
 
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 DEVSTATE_TOPIC_BUCKETS   57
 

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...
 
struct stasis_cacheast_device_state_cache (void)
 Backend cache for ast_device_state_topic_cached() More...
 
int ast_device_state_clear_cache (const char *device)
 Clear the device from the stasis cache. More...
 
int ast_device_state_engine_init (void)
 Initialize the device state engine in separate thread. More...
 
struct stasis_topicast_device_state_topic (const char *device)
 Get the Stasis topic for device state messages for a specific device. More...
 
struct stasis_topicast_device_state_topic_all (void)
 Get the Stasis topic for device state messages. More...
 
struct stasis_topicast_device_state_topic_cached (void)
 Get the Stasis caching topic for device state messages. 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...
 
enum ast_device_state ast_parse_device_state (const char *device)
 Find out if device is active in a call or not. More...
 
int ast_publish_device_state_full (const char *device, enum ast_device_state state, enum ast_devstate_cache cachable, struct ast_eid *eid)
 Publish a device state update with EID. More...
 
enum ast_device_state ast_state_chan2dev (enum ast_channel_state chanstate)
 Convert channel state to devicestate. More...
 
static struct stasis_messagedevice_state_aggregate_calc (struct stasis_cache_entry *entry, struct stasis_message *new_snapshot)
 
static void device_state_aggregate_publish (struct stasis_topic *cache_topic, struct stasis_message *aggregate)
 
static struct ast_device_state_messagedevice_state_alloc (const char *device, enum ast_device_state state, enum ast_devstate_cache cachable, const struct ast_eid *eid)
 
static void device_state_engine_cleanup (void)
 
static const char * device_state_get_id (struct stasis_message *message)
 
static enum ast_device_state devstate_cached (const char *device)
 
static void devstate_change_cb (void *data, struct stasis_subscription *sub, struct stasis_message *msg)
 
static void devstate_cleanup (void)
 
int devstate_init (void)
 Initialize the device state core. More...
 
static struct ast_manager_event_blobdevstate_to_ami (struct stasis_message *msg)
 
static struct ast_eventdevstate_to_event (struct stasis_message *message)
 Convert a stasis_message to a ast_event. More...
 
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, enum ast_devstate_cache cachable)
 
static int getproviderstate (const char *provider, const char *address)
 Get provider device state. More...
 
 STASIS_MESSAGE_TYPE_DEFN (ast_device_state_message_type,.to_ami=devstate_to_ami,.to_event=devstate_to_event,)
 

Variables

static const 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...
 
static struct stasis_cachedevice_state_cache
 
static struct stasis_topicdevice_state_topic_all
 
static struct stasis_caching_topicdevice_state_topic_cached
 
static struct stasis_topic_pooldevice_state_topic_pool
 
struct stasis_subscriptiondevstate_message_sub
 
static struct devstate_provs devstate_provs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static const char *const devstatestring [][2]
 Device state strings for printing. More...
 
static volatile int shuttingdown
 
static struct state_changes state_changes = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 

Detailed Description

Device state management.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Russell Bryant russe.nosp@m.ll@d.nosp@m.igium.nosp@m..com

Definition in file devicestate.c.

Macro Definition Documentation

◆ DEVSTATE_TOPIC_BUCKETS

#define DEVSTATE_TOPIC_BUCKETS   57

Definition at line 161 of file devicestate.c.

Function Documentation

◆ _ast_device_state()

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 331 of file devicestate.c.

332{
333 char *number;
334 const struct ast_channel_tech *chan_tech;
335 enum ast_device_state res;
336 /*! \brief Channel driver that provides device state */
337 char *tech;
338
339 /* If the last known state is cached, just return that */
340 if (check_cache) {
341 res = devstate_cached(device);
342 if (res != AST_DEVICE_UNKNOWN) {
343 return res;
344 }
345 }
346
347 number = ast_strdupa(device);
348 tech = strsep(&number, "/");
349 if (!number) {
350 /*! \brief Another provider of device state */
351 char *provider;
352
353 provider = strsep(&tech, ":");
354 if (!tech) {
355 return AST_DEVICE_INVALID;
356 }
357 /* We have a provider */
358 number = tech;
359
360 ast_debug(3, "Checking if I can find provider for \"%s\" - number: %s\n", provider, number);
362 }
363
364 ast_debug(4, "No provider found, checking channel drivers for %s - %s\n", tech, number);
365
366 chan_tech = ast_get_channel_tech(tech);
367 if (!chan_tech) {
368 return AST_DEVICE_INVALID;
369 }
370
371 /* Does the channel driver support device state notification? */
372 if (!chan_tech->devicestate) {
373 /* No, try the generic function */
374 return ast_parse_device_state(device);
375 }
376
377 res = chan_tech->devicestate(number);
378 if (res == AST_DEVICE_UNKNOWN) {
379 res = ast_parse_device_state(device);
380 }
381
382 return res;
383}
char * strsep(char **str, const char *delims)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
static struct prometheus_metrics_provider provider
Definition: bridges.c:201
const struct ast_channel_tech * ast_get_channel_tech(const char *name)
Get a channel technology structure by name.
Definition: channel.c:591
static enum ast_device_state devstate_cached(const char *device)
Definition: devicestate.c:312
static int getproviderstate(const char *provider, const char *address)
Get provider device state.
Definition: devicestate.c:442
enum ast_device_state ast_parse_device_state(const char *device)
Find out if device is active in a call or not.
Definition: devicestate.c:290
ast_device_state
Device States.
Definition: devicestate.h:52
@ AST_DEVICE_UNKNOWN
Definition: devicestate.h:53
@ AST_DEVICE_INVALID
Definition: devicestate.h:57
#define ast_debug(level,...)
Log a DEBUG message.
Structure to describe a channel "technology", ie a channel driver See for examples:
Definition: channel.h:648
int(*const devicestate)(const char *device_number)
Definition: channel.h:695
Number structure.
Definition: app_followme.c:157

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(), provider, and strsep().

Referenced by ast_device_state(), and do_state_change().

◆ ast_device_state()

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.

Returns
an AST_DEVICE_??? state

Definition at line 385 of file devicestate.c.

386{
387 /* This function is called from elsewhere in the code to find out the
388 * current state of a device. Check the cache, first. */
389
390 return _ast_device_state(device, 1);
391}
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:331

References _ast_device_state().

◆ ast_device_state_cache()

struct stasis_cache * ast_device_state_cache ( void  )

◆ ast_device_state_clear_cache()

int ast_device_state_clear_cache ( const char *  device)

Clear the device from the stasis cache.

Parameters
deviceThe device to clear
Return values
0if successful
-1nothing to clear
Since
12

Definition at line 691 of file devicestate.c.

692{
693 struct stasis_message *cached_msg;
694 struct stasis_message *msg;
695
698 if (!cached_msg) {
699 /* nothing to clear */
700 return -1;
701 }
702
703 msg = stasis_cache_clear_create(cached_msg);
704 if (msg) {
706 }
707 ao2_cleanup(msg);
708 ao2_cleanup(cached_msg);
709 return 0;
710}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
struct stasis_cache * ast_device_state_cache(void)
Backend cache for ast_device_state_topic_cached()
Definition: devicestate.c:676
struct stasis_topic * ast_device_state_topic(const char *device)
Get the Stasis topic for device state messages for a specific device.
Definition: devicestate.c:686
struct stasis_message_type * ast_device_state_message_type(void)
Get the Stasis message type for device state messages.
struct stasis_message * stasis_cache_clear_create(struct stasis_message *message)
A message which instructs the caching topic to remove an entry from its cache.
Definition: stasis_cache.c:778
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1538
struct stasis_message * stasis_cache_get_by_eid(struct stasis_cache *cache, struct stasis_message_type *type, const char *id, const struct ast_eid *eid)
Retrieve an item from the cache for a specific entity.
Definition: stasis_cache.c:659
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:94

References ao2_cleanup, ast_device_state_cache(), ast_device_state_message_type(), ast_device_state_topic(), ast_eid_default, stasis_cache_clear_create(), stasis_cache_get_by_eid(), and stasis_publish().

Referenced by stasis_app_device_state_delete().

◆ ast_device_state_engine_init()

int ast_device_state_engine_init ( void  )

Initialize the device state engine in separate thread.

Provided by devicestate.c

Definition at line 621 of file devicestate.c.

622{
625 ast_log(LOG_ERROR, "Unable to start device state change thread.\n");
626 return -1;
627 }
629
630 return 0;
631}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_log
Definition: astobj2.c:42
static void device_state_engine_cleanup(void)
Definition: devicestate.c:608
static pthread_t change_thread
The device state change notification thread.
Definition: devicestate.c:214
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:526
static ast_cond_t change_pending
Flag for the queue.
Definition: devicestate.c:217
#define LOG_ERROR
#define ast_cond_init(cond, attr)
Definition: lock.h:208
#define NULL
Definition: resample.c:96
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:592

References ast_cond_init, ast_log, ast_pthread_create_background, ast_register_cleanup(), change_pending, change_thread, device_state_engine_cleanup(), do_devstate_changes(), LOG_ERROR, and NULL.

Referenced by asterisk_daemon().

◆ ast_device_state_topic()

struct stasis_topic * ast_device_state_topic ( const char *  device)

Get the Stasis topic for device state messages for a specific device.

Parameters
deviceThe device for which to get the topic
Returns
The topic structure for MWI messages for a given device
Return values
NULLif it failed to be found or allocated
Since
12

Definition at line 686 of file devicestate.c.

687{
689}
static struct stasis_topic_pool * device_state_topic_pool
Definition: devicestate.c:225
struct stasis_topic * stasis_topic_pool_get_topic(struct stasis_topic_pool *pool, const char *topic_name)
Find or create a topic in the pool.
Definition: stasis.c:1911

References device_state_topic_pool, and stasis_topic_pool_get_topic().

Referenced by ast_device_state_clear_cache(), ast_publish_device_state_full(), cc_generic_agent_start_monitoring(), create_new_generic_list(), device_state_aggregate_publish(), remove_device_states_cb(), and subscribe_device_state().

◆ ast_device_state_topic_all()

struct stasis_topic * ast_device_state_topic_all ( void  )

Get the Stasis topic for device state messages.

Returns
The topic for device state messages
Return values
NULLif it has not been allocated
Since
12

Definition at line 671 of file devicestate.c.

672{
674}
static struct stasis_topic * device_state_topic_all
Definition: devicestate.c:222

References device_state_topic_all.

Referenced by ast_publish_device_state_full(), AST_TEST_DEFINE(), asterisk_start_devicestate_publishing(), devstate_init(), load_module(), load_pbx(), publish_hint_change(), publish_hint_remove(), subscribe_device_state(), and xmpp_init_event_distribution().

◆ ast_device_state_topic_cached()

struct stasis_topic * ast_device_state_topic_cached ( void  )

Get the Stasis caching topic for device state messages.

Returns
The caching topic for device state messages
Return values
NULLif it has not been allocated
Since
12

Definition at line 681 of file devicestate.c.

682{
684}
static struct stasis_caching_topic * device_state_topic_cached
Definition: devicestate.c:224
struct stasis_topic * stasis_caching_get_topic(struct stasis_caching_topic *caching_topic)
Returns the topic of cached events from a caching topics.
Definition: stasis_cache.c:85

References device_state_topic_cached, and stasis_caching_get_topic().

Referenced by AST_TEST_DEFINE().

◆ ast_devstate2str()

const char * ast_devstate2str ( enum ast_device_state  devstate)

Find devicestate as text message for output.

Convert device state to text string for output.

Definition at line 240 of file devicestate.c.

241{
242 return devstatestring[devstate][0];
243}
static const char *const devstatestring[][2]
Device state strings for printing.
Definition: devicestate.c:164

References devstatestring.

Referenced by ast_sip_get_device_state(), AST_TEST_DEFINE(), ccss_notify_device_state_change(), device_state_cb(), do_state_change(), extension_state_cb(), page_exec(), parking_notify_metermaids(), and print_queue().

◆ ast_devstate_aggregate_add()

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
Since
1.6.1

Definition at line 639 of file devicestate.c.

640{
641 static enum ast_device_state state_order[] = {
642 1, /* AST_DEVICE_UNKNOWN */
643 3, /* AST_DEVICE_NOT_INUSE */
644 6, /* AST_DEVICE_INUSE */
645 7, /* AST_DEVICE_BUSY */
646 0, /* AST_DEVICE_INVALID */
647 2, /* AST_DEVICE_UNAVAILABLE */
648 5, /* AST_DEVICE_RINGING */
649 8, /* AST_DEVICE_RINGINUSE */
650 4, /* AST_DEVICE_ONHOLD */
651 };
652
653 if (state == AST_DEVICE_RINGING) {
654 agg->ringing = 1;
656 agg->inuse = 1;
657 }
658
659 if (agg->ringing && agg->inuse) {
661 } else if (state_order[state] > state_order[agg->state]) {
662 agg->state = state;
663 }
664}
enum cc_state state
Definition: ccss.c:399
@ AST_DEVICE_RINGINUSE
Definition: devicestate.h:60
@ AST_DEVICE_INUSE
Definition: devicestate.h:55
@ AST_DEVICE_ONHOLD
Definition: devicestate.h:61
@ AST_DEVICE_RINGING
Definition: devicestate.h:59
@ AST_DEVICE_BUSY
Definition: devicestate.h:56
enum ast_device_state state
Definition: devicestate.h:231
unsigned int ringing
Definition: devicestate.h:229

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(), AST_TEST_DEFINE(), chan_pjsip_devicestate(), and device_state_aggregate_calc().

◆ ast_devstate_aggregate_init()

void ast_devstate_aggregate_init ( struct ast_devstate_aggregate agg)

Initialize aggregate device state.

Parameters
[in]aggthe state object
Since
1.6.1

Definition at line 633 of file devicestate.c.

634{
635 memset(agg, 0, sizeof(*agg));
637}

References AST_DEVICE_INVALID, and ast_devstate_aggregate::state.

Referenced by ast_extension_state3(), AST_TEST_DEFINE(), chan_pjsip_devicestate(), and device_state_aggregate_calc().

◆ ast_devstate_aggregate_result()

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 666 of file devicestate.c.

667{
668 return agg->state;
669}

References ast_devstate_aggregate::state.

Referenced by ast_extension_state3(), AST_TEST_DEFINE(), chan_pjsip_devicestate(), and device_state_aggregate_calc().

◆ ast_devstate_changed()

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 513 of file devicestate.c.

514{
516 va_list ap;
517
518 va_start(ap, fmt);
519 vsnprintf(buf, sizeof(buf), fmt, ap);
520 va_end(ap);
521
522 return ast_devstate_changed_literal(state, cachable, buf);
523}
#define AST_MAX_EXTENSION
Definition: channel.h:134
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:474
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

References ast_devstate_changed_literal(), AST_MAX_EXTENSION, buf, and state_change::cachable.

Referenced by __expire_registry(), __iax2_poke_noanswer(), add_to_queue(), agent_devstate_changed(), ast_sip_persistent_endpoint_update_state(), calendar_devstate_change(), ccss_notify_device_state_change(), chan_pjsip_indicate(), conf_handle_first_join(), conf_run(), destroy_event(), device_state_cb(), devstate_write(), handle_cli_devstate_change(), init_queue(), join_queue(), leave_queue(), load_module(), member_add_to_queue(), member_remove_from_queue(), mwi_update_cb(), parking_notify_metermaids(), populate_cache(), reg_source_db(), register_verify(), remove_from_queue(), rt_handle_member_record(), set_queue_member_pause(), sla_change_trunk_state(), sla_handle_hold_event(), sla_station_exec(), socket_process_helper(), stasis_app_device_state_delete(), stasis_app_device_state_update(), transition_to_empty(), update_devstate(), update_registry(), and xmpp_pak_presence().

◆ ast_devstate_changed_literal()

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 474 of file devicestate.c.

475{
476 struct state_change *change;
477
478 /*
479 * If we know the state change (how nice of the caller of this function!)
480 * then we can just generate a device state event.
481 *
482 * Otherwise, we do the following:
483 * - Queue an event up to another thread that the state has changed
484 * - In the processing thread, it calls the callback provided by the
485 * device state provider (which may or may not be a channel driver)
486 * to determine the state.
487 * - If the device state provider does not know the state, or this is
488 * for a channel and the channel driver does not implement a device
489 * state callback, then we will look through the channel list to
490 * see if we can determine a state based on active calls.
491 * - Once a state has been determined, a device state event is generated.
492 */
493
494 if (state != AST_DEVICE_UNKNOWN) {
496 } else if (change_thread == AST_PTHREADT_NULL || !(change = ast_calloc(1, sizeof(*change) + strlen(device)))) {
497 /* we could not allocate a change struct, or */
498 /* there is no background thread, so process the change now */
500 } else {
501 /* queue the change */
502 strcpy(change->device, device);
503 change->cachable = cachable;
508 }
509
510 return 0;
511}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static void do_state_change(const char *device, enum ast_devstate_cache cachable)
Definition: devicestate.c:463
#define ast_publish_device_state(device, state, cachable)
Publish a device state update.
Definition: devicestate.h:321
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
#define AST_PTHREADT_NULL
Definition: lock.h:73
#define ast_cond_signal(cond)
Definition: lock.h:210
struct state_change::@345 list
enum ast_devstate_cache cachable
Definition: devicestate.c:205
char device[1]
Definition: devicestate.c:206
The state change queue. State changes are queued for processing by a separate thread.
Definition: devicestate.c:211

References ast_calloc, ast_cond_signal, AST_DEVICE_UNKNOWN, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, ast_publish_device_state, state_change::cachable, change_pending, change_thread, state_change::device, do_state_change(), and state_change::list.

Referenced by ast_channel_destructor(), ast_devstate_changed(), ast_setstate(), AST_TEST_DEFINE(), chan_pjsip_indicate(), and dahdi_new().

◆ ast_devstate_prov_add()

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

395{
396 struct devstate_prov *devcb;
397 struct devstate_prov *devprov;
398
399 if (!callback || !(devprov = ast_calloc(1, sizeof(*devprov))))
400 return -1;
401
402 devprov->callback = callback;
403 ast_copy_string(devprov->label, label, sizeof(devprov->label));
404
406 AST_RWLIST_TRAVERSE(&devstate_provs, devcb, list) {
407 if (!strcasecmp(devcb->label, label)) {
408 ast_log(LOG_WARNING, "Device state provider '%s' already registered\n", label);
409 ast_free(devprov);
411 return -1;
412 }
413 }
414 AST_RWLIST_INSERT_HEAD(&devstate_provs, devprov, list);
416
417 return 0;
418}
#define ast_free(a)
Definition: astmm.h:180
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
#define LOG_WARNING
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:718
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
A device state provider (not a channel)
Definition: devicestate.c:194
ast_devstate_prov_cb_type callback
Definition: devicestate.c:196
char label[40]
Definition: devicestate.c:195
A list of providers.
Definition: devicestate.c:201

References ast_calloc, ast_copy_string(), ast_free, ast_log, AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, callback(), devstate_prov::callback, devstate_prov::label, and LOG_WARNING.

Referenced by AST_TEST_DEFINE(), load_module(), and load_parking_devstate().

◆ ast_devstate_prov_del()

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 421 of file devicestate.c.

422{
423 struct devstate_prov *devcb;
424 int res = -1;
425
428 if (!strcasecmp(devcb->label, label)) {
430 ast_free(devcb);
431 res = 0;
432 break;
433 }
434 }
437
438 return res;
439}
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:570
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617

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 AST_TEST_DEFINE(), load_module(), unload_module(), and unload_parking_devstate().

◆ ast_devstate_str()

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 258 of file devicestate.c.

259{
260 return devstatestring[state][1];
261}

References devstatestring, and state.

Referenced by agent_handle_show_specific(), agent_show_requested(), AST_TEST_DEFINE(), asterisk_publisher_devstate_cb(), devstate_read(), devstate_to_ami(), stasis_app_device_state_to_json(), and xmpp_pubsub_devstate_cb().

◆ ast_devstate_val()

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 263 of file devicestate.c.

264{
265 if (!strcasecmp(val, "NOT_INUSE"))
267 else if (!strcasecmp(val, "INUSE"))
268 return AST_DEVICE_INUSE;
269 else if (!strcasecmp(val, "BUSY"))
270 return AST_DEVICE_BUSY;
271 else if (!strcasecmp(val, "INVALID"))
272 return AST_DEVICE_INVALID;
273 else if (!strcasecmp(val, "UNAVAILABLE"))
275 else if (!strcasecmp(val, "RINGING"))
276 return AST_DEVICE_RINGING;
277 else if (!strcasecmp(val, "RINGINUSE"))
279 else if (!strcasecmp(val, "ONHOLD"))
280 return AST_DEVICE_ONHOLD;
281
282 return AST_DEVICE_UNKNOWN;
283}
@ AST_DEVICE_NOT_INUSE
Definition: devicestate.h:54
@ AST_DEVICE_UNAVAILABLE
Definition: devicestate.h:58
Definition: ast_expr2.c:325

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 AST_TEST_DEFINE(), asterisk_publication_devicestate(), custom_devstate_callback(), devstate_write(), handle_cli_devstate_change(), initialize_cc_devstate_map_helper(), load_module(), populate_cache(), stasis_app_device_state_update(), stasis_device_state_cb(), and xmpp_pubsub_handle_event().

◆ ast_parse_device_state()

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 290 of file devicestate.c.

291{
292 struct ast_channel *chan;
294 enum ast_device_state res;
295
296 snprintf(match, sizeof(match), "%s-", device);
297
298 if (!(chan = ast_channel_get_by_name_prefix(match, strlen(match)))) {
299 return AST_DEVICE_UNKNOWN;
300 }
301
303 res = AST_DEVICE_ONHOLD;
304 } else {
306 }
307 ast_channel_unref(chan);
308
309 return res;
310}
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2388
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:1380
#define AST_CHANNEL_NAME
Definition: channel.h:173
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3008
int ast_channel_hold_state(const struct ast_channel *chan)
ast_channel_state
ast_channel states
Definition: channelstate.h:35
enum ast_device_state ast_state_chan2dev(enum ast_channel_state chanstate)
Convert channel state to devicestate.
Definition: devicestate.c:245
@ AST_CONTROL_HOLD
Main Channel structure associated with a channel.

References ast_channel_get_by_name_prefix(), ast_channel_hold_state(), AST_CHANNEL_NAME, ast_channel_unref, AST_CONTROL_HOLD, AST_DEVICE_ONHOLD, AST_DEVICE_UNKNOWN, ast_state_chan2dev(), and match().

Referenced by _ast_device_state(), AST_TEST_DEFINE(), and chanavail_exec().

◆ ast_publish_device_state_full()

int ast_publish_device_state_full ( const char *  device,
enum ast_device_state  state,
enum ast_devstate_cache  cachable,
struct ast_eid eid 
)

Publish a device state update with EID.

Parameters
[in]deviceThe device name
[in]stateThe state of the device
[in]cachableWhether the device state can be cached
[in]eidThe EID of the server that originally published the message
Return values
0Success
-1Failure
Since
12

Definition at line 712 of file devicestate.c.

717{
718 RAII_VAR(struct ast_device_state_message *, device_state, NULL, ao2_cleanup);
720 struct stasis_topic *topic;
721
722 ast_assert(!ast_strlen_zero(device));
723
725 return -1;
726 }
727
728 device_state = device_state_alloc(device, state, cachable, eid);
729 if (!device_state) {
730 return -1;
731 }
732
734 eid);
735 if (!message) {
736 return -1;
737 }
738
739 /* When a device state is to be cached it is likely that something
740 * external will either be monitoring it or will want to pull the
741 * information from the cache, so we always publish to the device
742 * specific topic. Cachable updates traditionally come from such things
743 * as a SIP or PJSIP device.
744 * When a device state is not to be cached we only publish to its
745 * specific topic if something has already created the topic. Publishing
746 * to its topic otherwise would create the topic, which may not be
747 * necessary as it could be an ephemeral device. Uncachable updates
748 * traditionally come from such things as Local channels.
749 */
751 topic = ast_device_state_topic(device);
752 } else {
754 }
755
756 if (!topic) {
757 return -1;
758 }
759
760 stasis_publish(topic, message);
761 return 0;
762}
struct stasis_topic * ast_device_state_topic_all(void)
Get the Stasis topic for device state messages.
Definition: devicestate.c:671
static struct ast_device_state_message * device_state_alloc(const char *device, enum ast_device_state state, enum ast_devstate_cache cachable, const struct ast_eid *eid)
Definition: devicestate.c:550
int stasis_topic_pool_topic_exists(const struct stasis_topic_pool *pool, const char *topic_name)
Check if a topic exists in a pool.
Definition: stasis.c:1954
struct stasis_message * stasis_message_create_full(struct stasis_message_type *type, void *data, const struct ast_eid *eid)
Create a new message for an entity.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
The structure that contains device state.
Definition: devicestate.h:238
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_assert(a)
Definition: utils.h:739

References ao2_cleanup, ast_assert, ast_device_state_message_type(), ast_device_state_topic(), ast_device_state_topic_all(), ast_strlen_zero(), device_state_alloc(), device_state_topic_pool, NULL, RAII_VAR, stasis_message_create_full(), stasis_publish(), and stasis_topic_pool_topic_exists().

Referenced by AST_TEST_DEFINE(), asterisk_publication_devicestate(), devstate_change_cb(), publish_device_state_to_stasis(), and xmpp_pubsub_handle_event().

◆ ast_state_chan2dev()

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 245 of file devicestate.c.

246{
247 int i;
248 chanstate &= 0xFFFF;
249 for (i = 0; i < ARRAY_LEN(chan2dev); i++) {
250 if (chan2dev[i].chan == chanstate) {
251 return chan2dev[i].dev;
252 }
253 }
254 return AST_DEVICE_UNKNOWN;
255}
Mapping for channel states to device states.
Definition: devicestate.c:177
enum ast_device_state dev
Definition: devicestate.c:179
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, AST_DEVICE_UNKNOWN, and chan2dev::dev.

Referenced by ast_parse_device_state(), AST_TEST_DEFINE(), and chan_pjsip_devicestate().

◆ device_state_aggregate_calc()

static struct stasis_message * device_state_aggregate_calc ( struct stasis_cache_entry entry,
struct stasis_message new_snapshot 
)
static

Definition at line 819 of file devicestate.c.

820{
821 struct stasis_message *aggregate_snapshot;
822 struct stasis_message *snapshot;
823 struct ast_device_state_message *device_state;
824 const char *device = NULL;
825 struct ast_devstate_aggregate aggregate;
826 int idx;
827
829 return NULL;
830 }
831
832 /* Determine the new aggregate device state. */
833 ast_devstate_aggregate_init(&aggregate);
834 snapshot = stasis_cache_entry_get_local(entry);
835 if (snapshot) {
836 device_state = stasis_message_data(snapshot);
837 device = device_state->device;
838 ast_devstate_aggregate_add(&aggregate, device_state->state);
839 }
840 for (idx = 0; ; ++idx) {
841 snapshot = stasis_cache_entry_get_remote(entry, idx);
842 if (!snapshot) {
843 break;
844 }
845
846 device_state = stasis_message_data(snapshot);
847 device = device_state->device;
848 ast_devstate_aggregate_add(&aggregate, device_state->state);
849 }
850
851 if (!device) {
852 /* There are no device states cached. Delete the aggregate. */
853 return NULL;
854 }
855
856 snapshot = stasis_cache_entry_get_aggregate(entry);
857 if (snapshot) {
858 device_state = stasis_message_data(snapshot);
859 if (device_state->state == ast_devstate_aggregate_result(&aggregate)) {
860 /* Aggregate device state did not change. */
861 return ao2_bump(snapshot);
862 }
863 }
864
865 device_state = device_state_alloc(device, ast_devstate_aggregate_result(&aggregate),
867 if (!device_state) {
868 /* Bummer. We have to keep the old aggregate snapshot. */
869 return ao2_bump(snapshot);
870 }
872 device_state, NULL);
873 ao2_cleanup(device_state);
874 if (!aggregate_snapshot) {
875 /* Bummer. We have to keep the old aggregate snapshot. */
876 return ao2_bump(snapshot);
877 }
878
879 return aggregate_snapshot;
880}
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
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:639
void ast_devstate_aggregate_init(struct ast_devstate_aggregate *agg)
Initialize aggregate device state.
Definition: devicestate.c:633
enum ast_device_state ast_devstate_aggregate_result(struct ast_devstate_aggregate *agg)
Get the aggregate device state result.
Definition: devicestate.c:666
@ AST_DEVSTATE_CACHABLE
Definition: devicestate.h:70
struct stasis_message * stasis_cache_entry_get_aggregate(struct stasis_cache_entry *entry)
Get the aggregate cache entry snapshot.
Definition: stasis_cache.c:365
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_message * stasis_cache_entry_get_local(struct stasis_cache_entry *entry)
Get the local entity's cache entry snapshot.
Definition: stasis_cache.c:370
struct stasis_message * stasis_cache_entry_get_remote(struct stasis_cache_entry *entry, int idx)
Get a remote entity's cache entry snapshot by index.
Definition: stasis_cache.c:375
enum ast_device_state state
Definition: devicestate.h:248
You shouldn't care about the contents of this struct.
Definition: devicestate.h:228

References ao2_bump, ao2_cleanup, ast_device_state_message_type(), ast_devstate_aggregate_add(), ast_devstate_aggregate_init(), ast_devstate_aggregate_result(), AST_DEVSTATE_CACHABLE, ast_device_state_message::device, device_state_alloc(), NULL, stasis_cache_entry_get_aggregate(), stasis_cache_entry_get_local(), stasis_cache_entry_get_remote(), stasis_message_create_full(), stasis_message_data(), and ast_device_state_message::state.

Referenced by devstate_init().

◆ device_state_aggregate_publish()

static void device_state_aggregate_publish ( struct stasis_topic cache_topic,
struct stasis_message aggregate 
)
static

Definition at line 788 of file devicestate.c.

789{
790 const char *device;
791 struct stasis_topic *device_specific_topic;
792
793 device = device_state_get_id(aggregate);
794 if (!device) {
795 return;
796 }
797 device_specific_topic = ast_device_state_topic(device);
798 if (!device_specific_topic) {
799 return;
800 }
801
802 stasis_publish(device_specific_topic, aggregate);
803}
static const char * device_state_get_id(struct stasis_message *message)
Definition: devicestate.c:764

References ast_device_state_topic(), ast_device_state_message::device, device_state_get_id(), and stasis_publish().

Referenced by devstate_init().

◆ device_state_alloc()

static struct ast_device_state_message * device_state_alloc ( const char *  device,
enum ast_device_state  state,
enum ast_devstate_cache  cachable,
const struct ast_eid eid 
)
static

Definition at line 550 of file devicestate.c.

551{
552 struct ast_device_state_message *new_device_state;
553 char *pos;
554 size_t stuff_len;
555
557
558 stuff_len = strlen(device) + 1;
559 if (eid) {
560 stuff_len += sizeof(*eid);
561 }
562 new_device_state = ao2_alloc_options(sizeof(*new_device_state) + stuff_len, NULL,
564 if (!new_device_state) {
565 return NULL;
566 }
567
568 if (eid) {
569 /* non-aggregate device state. */
570 new_device_state->stuff[0] = *eid;
571 new_device_state->eid = &new_device_state->stuff[0];
572 pos = (char *) &new_device_state->stuff[1];
573 } else {
574 pos = (char *) &new_device_state->stuff[0];
575 }
576
577 strcpy(pos, device);/* Safe */
578 new_device_state->device = pos;
579
580 new_device_state->state = state;
581 new_device_state->cachable = cachable;
582
583 return new_device_state;
584}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
const struct ast_eid * eid
The EID of the server where this message originated.
Definition: devicestate.h:246
struct ast_eid stuff[0]
Definition: devicestate.h:252
enum ast_devstate_cache cachable
Definition: devicestate.h:250

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ast_assert, ast_strlen_zero(), ast_device_state_message::cachable, ast_device_state_message::device, ast_device_state_message::eid, NULL, ast_device_state_message::state, state, and ast_device_state_message::stuff.

Referenced by ast_publish_device_state_full(), and device_state_aggregate_calc().

◆ device_state_engine_cleanup()

static void device_state_engine_cleanup ( void  )
static

Definition at line 608 of file devicestate.c.

609{
610 shuttingdown = 1;
614
616 pthread_join(change_thread, NULL);
617 }
618}
static volatile int shuttingdown
Definition: devicestate.c:218

References ast_cond_signal, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, change_pending, change_thread, NULL, and shuttingdown.

Referenced by ast_device_state_engine_init().

◆ device_state_get_id()

static const char * device_state_get_id ( struct stasis_message message)
static

Definition at line 764 of file devicestate.c.

765{
766 struct ast_device_state_message *device_state;
767
769 return NULL;
770 }
771
772 device_state = stasis_message_data(message);
773 if (device_state->cachable == AST_DEVSTATE_NOT_CACHABLE) {
774 return NULL;
775 }
776
777 return device_state->device;
778}
@ AST_DEVSTATE_NOT_CACHABLE
Definition: devicestate.h:69
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.

References ast_device_state_message_type(), AST_DEVSTATE_NOT_CACHABLE, ast_device_state_message::cachable, ast_device_state_message::device, NULL, stasis_message_data(), and stasis_message_type().

Referenced by device_state_aggregate_publish(), and devstate_init().

◆ devstate_cached()

static enum ast_device_state devstate_cached ( const char *  device)
static

Definition at line 312 of file devicestate.c.

313{
314 struct stasis_message *cached_msg;
315 struct ast_device_state_message *device_state;
317
320 if (!cached_msg) {
321 return AST_DEVICE_UNKNOWN;
322 }
323 device_state = stasis_message_data(cached_msg);
324 state = device_state->state;
325 ao2_cleanup(cached_msg);
326
327 return state;
328}

References ao2_cleanup, ast_device_state_cache(), ast_device_state_message_type(), AST_DEVICE_UNKNOWN, ast_device_state_message::device, NULL, stasis_cache_get_by_eid(), stasis_message_data(), ast_device_state_message::state, and state.

Referenced by _ast_device_state().

◆ devstate_change_cb()

static void devstate_change_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message msg 
)
static

Definition at line 586 of file devicestate.c.

587{
588 struct ast_device_state_message *device_state;
589
591 return;
592 }
593
594 device_state = stasis_message_data(msg);
595 if (device_state->cachable == AST_DEVSTATE_CACHABLE || !device_state->eid) {
596 /* Ignore cacheable and aggregate messages. */
597 return;
598 }
599
600 /*
601 * Non-cacheable device state aggregates are just the
602 * device state republished as the aggregate.
603 */
604 ast_publish_device_state_full(device_state->device, device_state->state,
605 device_state->cachable, NULL);
606}
int ast_publish_device_state_full(const char *device, enum ast_device_state state, enum ast_devstate_cache cachable, struct ast_eid *eid)
Publish a device state update with EID.
Definition: devicestate.c:712

References ast_device_state_message_type(), AST_DEVSTATE_CACHABLE, ast_publish_device_state_full(), ast_device_state_message::cachable, ast_device_state_message::device, ast_device_state_message::eid, NULL, stasis_message_data(), stasis_message_type(), and ast_device_state_message::state.

Referenced by devstate_init().

◆ devstate_cleanup()

static void devstate_cleanup ( void  )
static

Definition at line 882 of file devicestate.c.

883{
886
889
892
895
897}
struct stasis_subscription * devstate_message_sub
Definition: devicestate.c:220
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1161
struct stasis_caching_topic * stasis_caching_unsubscribe_and_join(struct stasis_caching_topic *caching_topic)
Unsubscribes a caching topic from its upstream topic, blocking until all messages have been forwarded...
Definition: stasis_cache.c:146

References ao2_cleanup, ast_device_state_message_type(), device_state_cache, device_state_topic_all, device_state_topic_cached, device_state_topic_pool, devstate_message_sub, NULL, stasis_caching_unsubscribe_and_join(), STASIS_MESSAGE_TYPE_CLEANUP, and stasis_unsubscribe_and_join().

Referenced by devstate_init().

◆ devstate_init()

int devstate_init ( void  )

Initialize the device state core.

Return values
0Success
-1Failure
Since
12

Definition at line 899 of file devicestate.c.

900{
902
904 return -1;
905 }
906 device_state_topic_all = stasis_topic_create("devicestate:all");
908 return -1;
909 }
912 return -1;
913 }
916 if (!device_state_cache) {
917 return -1;
918 }
922 return -1;
923 }
926
930 ast_log(LOG_ERROR, "Failed to create subscription creating uncached device state aggregate events.\n");
931 return -1;
932 }
935
936 return 0;
937}
static void devstate_change_cb(void *data, struct stasis_subscription *sub, struct stasis_message *msg)
Definition: devicestate.c:586
static void devstate_cleanup(void)
Definition: devicestate.c:882
static struct stasis_message * device_state_aggregate_calc(struct stasis_cache_entry *entry, struct stasis_message *new_snapshot)
Definition: devicestate.c:819
static void device_state_aggregate_publish(struct stasis_topic *cache_topic, struct stasis_message *aggregate)
Definition: devicestate.c:788
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
Definition: stasis.h:297
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:644
struct stasis_caching_topic * stasis_caching_topic_create(struct stasis_topic *original_topic, struct stasis_cache *cache)
Create a topic which monitors and caches messages from another topic.
Definition: stasis_cache.c:948
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1050
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1104
int stasis_caching_set_filter(struct stasis_caching_topic *caching_topic, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a cache.
Definition: stasis_cache.c:109
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493
struct stasis_cache * stasis_cache_create_full(snapshot_get_id id_fn, cache_aggregate_calc_fn aggregate_calc_fn, cache_aggregate_publish_fn aggregate_publish_fn)
Create a cache.
Definition: stasis_cache.c:334
struct stasis_topic_pool * stasis_topic_pool_create(struct stasis_topic *pooled_topic)
Create a topic pool that routes messages from dynamically generated topics to the given topic.
Definition: stasis.c:1860
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:649
int stasis_caching_accept_message_type(struct stasis_caching_topic *caching_topic, struct stasis_message_type *type)
Indicate to a caching topic that we are interested in a message type.
Definition: stasis_cache.c:90

References ast_device_state_message_type(), ast_device_state_topic_all(), ast_log, ast_register_cleanup(), device_state_aggregate_calc(), device_state_aggregate_publish(), device_state_cache, device_state_get_id(), device_state_topic_all, device_state_topic_cached, device_state_topic_pool, devstate_change_cb(), devstate_cleanup(), devstate_message_sub, LOG_ERROR, NULL, stasis_cache_create_full(), stasis_caching_accept_message_type(), stasis_caching_set_filter(), stasis_caching_topic_create(), STASIS_MESSAGE_TYPE_INIT, stasis_subscribe, stasis_subscription_accept_message_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, stasis_subscription_set_filter(), stasis_topic_create(), and stasis_topic_pool_create().

Referenced by asterisk_daemon().

◆ devstate_to_ami()

static struct ast_manager_event_blob * devstate_to_ami ( struct stasis_message msg)
static

Definition at line 939 of file devicestate.c.

940{
941 struct ast_device_state_message *dev_state;
942
943 dev_state = stasis_message_data(msg);
944
945 /* Ignore non-aggregate states */
946 if (dev_state->eid) {
947 return NULL;
948 }
949
950 return ast_manager_event_blob_create(EVENT_FLAG_CALL, "DeviceStateChange",
951 "Device: %s\r\n"
952 "State: %s\r\n",
953 dev_state->device, ast_devstate_str(dev_state->state));
954}
const char * ast_devstate_str(enum ast_device_state state)
Convert device state to text string that is easier to parse.
Definition: devicestate.c:258
struct ast_manager_event_blob * ast_manager_event_blob_create(int event_flags, const char *manager_event, const char *extra_fields_fmt,...)
Construct a ast_manager_event_blob.
Definition: manager.c:10237
#define EVENT_FLAG_CALL
Definition: manager.h:76

References ast_devstate_str(), ast_manager_event_blob_create(), ast_device_state_message::device, ast_device_state_message::eid, EVENT_FLAG_CALL, NULL, stasis_message_data(), and ast_device_state_message::state.

◆ devstate_to_event()

static struct ast_event * devstate_to_event ( struct stasis_message msg)
static

Convert a stasis_message to a ast_event.

Definition at line 957 of file devicestate.c.

958{
959 struct ast_event *event;
960 struct ast_device_state_message *device_state;
961
962 if (!message) {
963 return NULL;
964 }
965
966 device_state = stasis_message_data(message);
967
968 if (device_state->eid) {
973 AST_EVENT_IE_EID, AST_EVENT_IE_PLTYPE_RAW, device_state->eid, sizeof(*device_state->eid),
975 } else {
981 }
982
983 return event;
984}
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
Definition: event.c:403
@ AST_EVENT_IE_END
Definition: event_defs.h:70
@ AST_EVENT_IE_STATE
Generic State IE Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: UINT The actual state values dep...
Definition: event_defs.h:121
@ AST_EVENT_IE_DEVICE
Device Name Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: STR.
Definition: event_defs.h:113
@ AST_EVENT_IE_EID
Entity ID Used by All events Payload type: RAW This IE indicates which server the event originated fr...
Definition: event_defs.h:272
@ AST_EVENT_IE_CACHABLE
Event non-cacheability flag Used by: All events Payload type: UINT.
Definition: event_defs.h:306
@ AST_EVENT_DEVICE_STATE_CHANGE
Definition: event_defs.h:48
@ AST_EVENT_DEVICE_STATE
Definition: event_defs.h:45
@ AST_EVENT_IE_PLTYPE_RAW
Definition: event_defs.h:337
@ AST_EVENT_IE_PLTYPE_UINT
Definition: event_defs.h:333
@ AST_EVENT_IE_PLTYPE_STR
Definition: event_defs.h:335
An event.
Definition: event.c:81
Definition: astman.c:222

References AST_EVENT_DEVICE_STATE, AST_EVENT_DEVICE_STATE_CHANGE, AST_EVENT_IE_CACHABLE, AST_EVENT_IE_DEVICE, AST_EVENT_IE_EID, AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_STATE, ast_event_new(), ast_device_state_message::cachable, ast_device_state_message::device, ast_device_state_message::eid, NULL, stasis_message_data(), and ast_device_state_message::state.

◆ do_devstate_changes()

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 526 of file devicestate.c.

527{
528 struct state_change *next, *current;
529
530 while (!shuttingdown) {
531 /* This basically pops off any state change entries, resets the list back to NULL, unlocks, and processes each state change */
538
539 /* Process each state change */
540 while ((current = next)) {
542 do_state_change(current->device, current->cachable);
544 }
545 }
546
547 return NULL;
548}
size_t current
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
#define ast_cond_wait(cond, mutex)
Definition: lock.h:212
struct state_change * next
Definition: devicestate.c:204
ast_mutex_t lock
Definition: devicestate.c:211

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, change_pending, current, do_state_change(), state_change::list, state_changes::lock, state_change::next, NULL, and shuttingdown.

Referenced by ast_device_state_engine_init().

◆ do_state_change()

static void do_state_change ( const char *  device,
enum ast_devstate_cache  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 463 of file devicestate.c.

464{
466
467 state = _ast_device_state(device, 0);
468
469 ast_debug(3, "Changing state for %s - state %u (%s)\n", device, state, ast_devstate2str(state));
470
471 ast_publish_device_state(device, state, cachable);
472}
const char * ast_devstate2str(enum ast_device_state devstate)
Find devicestate as text message for output.
Definition: devicestate.c:240

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

Referenced by ast_devstate_changed_literal(), and do_devstate_changes().

◆ getproviderstate()

static int getproviderstate ( const char *  provider,
const char *  address 
)
static

Get provider device state.

Definition at line 442 of file devicestate.c.

443{
444 struct devstate_prov *devprov;
445 int res = AST_DEVICE_INVALID;
446
448 AST_RWLIST_TRAVERSE(&devstate_provs, devprov, list) {
449 ast_debug(5, "Checking provider %s with %s\n", devprov->label, provider);
450
451 if (!strcasecmp(devprov->label, provider)) {
452 res = devprov->callback(address);
453 break;
454 }
455 }
457
458 return res;
459}
char * address
Definition: f2c.h:59
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78

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

Referenced by _ast_device_state().

◆ STASIS_MESSAGE_TYPE_DEFN()

STASIS_MESSAGE_TYPE_DEFN ( ast_device_state_message_type  ,
to_ami = devstate_to_ami,
to_event = devstate_to_event 
)

Variable Documentation

◆ chan2dev

const struct chan2dev chan2dev[]
static

◆ change_pending

ast_cond_t change_pending
static

◆ change_thread

pthread_t change_thread = AST_PTHREADT_NULL
static

The device state change notification thread.

Definition at line 214 of file devicestate.c.

Referenced by ast_device_state_engine_init(), ast_devstate_changed_literal(), and device_state_engine_cleanup().

◆ device_state_cache

struct stasis_cache* device_state_cache
static

Definition at line 223 of file devicestate.c.

Referenced by ast_device_state_cache(), devstate_cleanup(), and devstate_init().

◆ device_state_topic_all

struct stasis_topic* device_state_topic_all
static

Definition at line 222 of file devicestate.c.

Referenced by ast_device_state_topic_all(), devstate_cleanup(), and devstate_init().

◆ device_state_topic_cached

struct stasis_caching_topic* device_state_topic_cached
static

Definition at line 224 of file devicestate.c.

Referenced by ast_device_state_topic_cached(), devstate_cleanup(), and devstate_init().

◆ device_state_topic_pool

struct stasis_topic_pool* device_state_topic_pool
static

◆ devstate_message_sub

struct stasis_subscription* devstate_message_sub

Definition at line 220 of file devicestate.c.

Referenced by devstate_cleanup(), and devstate_init().

◆ devstate_provs

struct devstate_provs devstate_provs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

◆ devstatestring

const char* const devstatestring[][2]
static

Device state strings for printing.

Definition at line 164 of file devicestate.c.

Referenced by ast_devstate2str(), and ast_devstate_str().

◆ shuttingdown

volatile int shuttingdown
static

Definition at line 218 of file devicestate.c.

Referenced by device_state_engine_cleanup(), and do_devstate_changes().

◆ state_changes

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