#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... | |
Defines | |
#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. | |
enum ast_device_state | ast_device_state (const char *device) |
Asks a channel for device state. | |
int | ast_device_state_changed (const char *fmt,...) |
Tells Asterisk the State for Device is changed. (Accept change notification, add it to change queue.). | |
int | ast_device_state_changed_literal (const char *dev) |
Tells Asterisk the State for Device is changed. | |
int | ast_device_state_engine_init (void) |
Initialize the device state engine in separate thread. | |
void | ast_devstate_aggregate_add (struct ast_devstate_aggregate *agg, enum ast_device_state state) |
Add a device state to the aggregate device state. | |
void | ast_devstate_aggregate_init (struct ast_devstate_aggregate *agg) |
Initialize aggregate device state. | |
enum ast_device_state | ast_devstate_aggregate_result (struct ast_devstate_aggregate *agg) |
Get the aggregate device state result. | |
int | ast_devstate_changed (enum ast_device_state state, const char *fmt,...) |
Tells Asterisk the State for Device is changed. | |
int | ast_devstate_changed_literal (enum ast_device_state state, const char *device) |
Tells Asterisk the State for Device is changed. | |
int | ast_devstate_prov_add (const char *label, ast_devstate_prov_cb_type callback) |
Add device state provider. | |
int | ast_devstate_prov_del (const char *label) |
Remove device state provider. | |
const char * | ast_devstate_str (enum ast_device_state state) |
Convert device state to text string that is easier to parse. | |
enum ast_device_state | ast_devstate_val (const char *val) |
Convert device state from text to integer value. | |
int | ast_enable_distributed_devstate (void) |
Enable distributed device state processing. | |
enum ast_device_state | ast_parse_device_state (const char *device) |
Search the Channels by Name. | |
enum ast_device_state | ast_state_chan2dev (enum ast_channel_state chanstate) |
Convert channel state to devicestate. | |
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. | |
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) |
static void * | do_devstate_changes (void *data) |
Go through the dev state change queue and update changes in the dev state thread. | |
static void | do_state_change (const char *device) |
static int | getproviderstate (const char *provider, const char *address) |
Get provider device state. | |
static void | handle_devstate_change (struct devstate_change *sc) |
static void | process_collection (const char *device, struct change_collection *collection) |
static void * | run_devstate_collector (void *data) |
Variables | |
static ast_cond_t | change_pending |
Flag for the queue. | |
static pthread_t | change_thread = AST_PTHREADT_NULL |
The device state change notification thread. | |
struct { | |
ast_cond_t cond | |
struct { | |
devstate_change * first | |
devstate_change * last | |
} devstate_change_q | |
unsigned int enabled:1 | |
ast_event_sub * event_sub | |
ast_mutex_t lock | |
pthread_t thread | |
} | devstate_collector |
static const char * | devstatestring [] |
Device state strings for printing. |
Russell Bryant <russell@digium.com>
Definition in file devicestate.c.
#define MAX_SERVERS 64 |
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 332 of file devicestate.c.
References ast_debug, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, ast_device_state(), AST_DEVICE_UNKNOWN, ast_get_channel_tech(), ast_parse_device_state(), ast_strdupa, buf, ast_channel_tech::devicestate, devstate_cached(), getproviderstate(), and strsep().
Referenced by ast_device_state(), and do_state_change().
00333 { 00334 char *buf; 00335 char *number; 00336 const struct ast_channel_tech *chan_tech; 00337 enum ast_device_state res; 00338 /*! \brief Channel driver that provides device state */ 00339 char *tech; 00340 /*! \brief Another provider of device state */ 00341 char *provider = NULL; 00342 00343 /* If the last known state is cached, just return that */ 00344 if (check_cache) { 00345 res = devstate_cached(device); 00346 if (res != AST_DEVICE_UNKNOWN) { 00347 return res; 00348 } 00349 } 00350 00351 buf = ast_strdupa(device); 00352 tech = strsep(&buf, "/"); 00353 if (!(number = buf)) { 00354 if (!(provider = strsep(&tech, ":"))) 00355 return AST_DEVICE_INVALID; 00356 /* We have a provider */ 00357 number = tech; 00358 tech = NULL; 00359 } 00360 00361 if (provider) { 00362 ast_debug(3, "Checking if I can find provider for \"%s\" - number: %s\n", provider, number); 00363 return getproviderstate(provider, number); 00364 } 00365 00366 ast_debug(4, "No provider found, checking channel drivers for %s - %s\n", tech, number); 00367 00368 if (!(chan_tech = ast_get_channel_tech(tech))) 00369 return AST_DEVICE_INVALID; 00370 00371 if (!(chan_tech->devicestate)) /* Does the channel driver support device state notification? */ 00372 return ast_parse_device_state(device); /* No, try the generic function */ 00373 00374 res = chan_tech->devicestate(number); 00375 00376 if (res != AST_DEVICE_UNKNOWN) 00377 return res; 00378 00379 res = ast_parse_device_state(device); 00380 00381 if (res == AST_DEVICE_UNKNOWN) 00382 return AST_DEVICE_NOT_INUSE; 00383 00384 return res; 00385 }
enum ast_device_state ast_device_state | ( | const char * | device | ) |
Asks a channel for device state.
device | like a dial string |
an | AST_DEVICE_??? state | |
-1 | on failure |
Definition at line 387 of file devicestate.c.
References _ast_device_state().
Referenced by _ast_device_state(), ast_extension_state2(), ast_parse_device_state(), chanavail_exec(), create_queue_member(), device_state_cb(), devstate_cached(), devstate_read(), devstate_write(), do_state_change(), handle_cli_devstate_change(), page_exec(), process_collection(), ring_entry(), skinny_extensionstate_cb(), sla_state(), and transmit_state_notify().
00388 { 00389 /* This function is called from elsewhere in the code to find out the 00390 * current state of a device. Check the cache, first. */ 00391 00392 return _ast_device_state(device, 1); 00393 }
int ast_device_state_changed | ( | const char * | fmt, | |
... | ||||
) |
Tells Asterisk the State for Device is changed. (Accept change notification, add it to change queue.).
fmt | device name like a dial string with format parameters |
0 | on success | |
-1 | on failure |
Definition at line 547 of file devicestate.c.
References AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), AST_MAX_EXTENSION, and buf.
00548 { 00549 char buf[AST_MAX_EXTENSION]; 00550 va_list ap; 00551 00552 va_start(ap, fmt); 00553 vsnprintf(buf, sizeof(buf), fmt, ap); 00554 va_end(ap); 00555 00556 return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, buf); 00557 }
int ast_device_state_changed_literal | ( | const char * | device | ) |
Tells Asterisk the State for Device is changed.
device | device name like a dial string |
0 | on success | |
-1 | on failure |
Definition at line 530 of file devicestate.c.
References AST_DEVICE_UNKNOWN, and ast_devstate_changed_literal().
00531 { 00532 return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, dev); 00533 }
int ast_device_state_engine_init | ( | void | ) |
Initialize the device state engine in separate thread.
Provided by devicestate.c
Definition at line 749 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().
00750 { 00751 ast_cond_init(&change_pending, NULL); 00752 if (ast_pthread_create_background(&change_thread, NULL, do_devstate_changes, NULL) < 0) { 00753 ast_log(LOG_ERROR, "Unable to start device state change thread.\n"); 00754 return -1; 00755 } 00756 00757 return 0; 00758 }
void ast_devstate_aggregate_add | ( | struct ast_devstate_aggregate * | agg, | |
enum ast_device_state | state | |||
) |
Add a device state to the aggregate device state.
[in] | agg | the state object |
[in] | state | the state to add |
Definition at line 770 of file devicestate.c.
References ast_devstate_aggregate::all_busy, ast_devstate_aggregate::all_free, ast_devstate_aggregate::all_on_hold, ast_devstate_aggregate::all_unavail, 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, AST_DEVICE_UNKNOWN, ast_devstate_aggregate::busy, ast_devstate_aggregate::in_use, and ast_devstate_aggregate::ring.
Referenced by ast_extension_state2(), and process_collection().
00771 { 00772 switch (state) { 00773 case AST_DEVICE_NOT_INUSE: 00774 agg->all_unavail = 0; 00775 agg->all_busy = 0; 00776 agg->all_on_hold = 0; 00777 break; 00778 case AST_DEVICE_INUSE: 00779 agg->in_use = 1; 00780 agg->all_busy = 0; 00781 agg->all_unavail = 0; 00782 agg->all_free = 0; 00783 agg->all_on_hold = 0; 00784 break; 00785 case AST_DEVICE_RINGING: 00786 agg->ring = 1; 00787 agg->all_busy = 0; 00788 agg->all_unavail = 0; 00789 agg->all_free = 0; 00790 agg->all_on_hold = 0; 00791 break; 00792 case AST_DEVICE_RINGINUSE: 00793 agg->in_use = 1; 00794 agg->ring = 1; 00795 agg->all_busy = 0; 00796 agg->all_unavail = 0; 00797 agg->all_free = 0; 00798 agg->all_on_hold = 0; 00799 break; 00800 case AST_DEVICE_ONHOLD: 00801 agg->all_unavail = 0; 00802 agg->all_free = 0; 00803 break; 00804 case AST_DEVICE_BUSY: 00805 agg->all_unavail = 0; 00806 agg->all_free = 0; 00807 agg->all_on_hold = 0; 00808 agg->busy = 1; 00809 break; 00810 case AST_DEVICE_UNAVAILABLE: 00811 case AST_DEVICE_INVALID: 00812 agg->all_busy = 0; 00813 agg->all_free = 0; 00814 agg->all_on_hold = 0; 00815 break; 00816 case AST_DEVICE_UNKNOWN: 00817 break; 00818 } 00819 }
void ast_devstate_aggregate_init | ( | struct ast_devstate_aggregate * | agg | ) |
Initialize aggregate device state.
[in] | agg | the state object |
Definition at line 760 of file devicestate.c.
Referenced by ast_extension_state2(), and process_collection().
00761 { 00762 memset(agg, 0, sizeof(*agg)); 00763 00764 agg->all_unavail = 1; 00765 agg->all_busy = 1; 00766 agg->all_free = 1; 00767 agg->all_on_hold = 1; 00768 }
enum ast_device_state ast_devstate_aggregate_result | ( | struct ast_devstate_aggregate * | agg | ) |
Get the aggregate device state result.
[in] | agg | the state object |
Definition at line 821 of file devicestate.c.
References ast_devstate_aggregate::all_busy, ast_devstate_aggregate::all_free, ast_devstate_aggregate::all_on_hold, ast_devstate_aggregate::all_unavail, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, ast_devstate_aggregate::busy, ast_devstate_aggregate::in_use, and ast_devstate_aggregate::ring.
Referenced by ast_extension_state2(), and process_collection().
00822 { 00823 if (agg->all_free) 00824 return AST_DEVICE_NOT_INUSE; 00825 00826 if (agg->all_on_hold) 00827 return AST_DEVICE_ONHOLD; 00828 00829 if (agg->all_busy) 00830 return AST_DEVICE_BUSY; 00831 00832 if (agg->all_unavail) 00833 return AST_DEVICE_UNAVAILABLE; 00834 00835 if (agg->ring) 00836 return agg->in_use ? AST_DEVICE_RINGINUSE : AST_DEVICE_RINGING; 00837 00838 if (agg->in_use) 00839 return AST_DEVICE_INUSE; 00840 00841 if (agg->busy) 00842 return AST_DEVICE_BUSY; 00843 00844 return AST_DEVICE_NOT_INUSE; 00845 }
int ast_devstate_changed | ( | enum ast_device_state | state, | |
const char * | fmt, | |||
... | ||||
) |
Tells Asterisk the State for Device is changed.
state | the new state of the device | |
fmt | device name like a dial string with format parameters |
0 | on success | |
-1 | on failure |
Definition at line 535 of file devicestate.c.
References ast_devstate_changed_literal(), AST_MAX_EXTENSION, and buf.
Referenced by __expire_registry(), __iax2_poke_noanswer(), agent_call(), agent_hangup(), agent_logoff_maintenance(), agent_read(), conf_run(), 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(), load_module(), login_exec(), notify_metermaids(), reg_source_db(), register_verify(), reload_agents(), 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().
00536 { 00537 char buf[AST_MAX_EXTENSION]; 00538 va_list ap; 00539 00540 va_start(ap, fmt); 00541 vsnprintf(buf, sizeof(buf), fmt, ap); 00542 va_end(ap); 00543 00544 return ast_devstate_changed_literal(state, buf); 00545 }
int ast_devstate_changed_literal | ( | enum ast_device_state | state, | |
const char * | device | |||
) |
Tells Asterisk the State for Device is changed.
state | the new state of the device | |
device | device name like a dial string with format parameters |
0 | on success | |
-1 | on failure |
Definition at line 492 of file devicestate.c.
References ast_calloc, ast_cond_signal(), AST_DEVICE_UNKNOWN, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, change_thread, devstate_event(), do_state_change(), and devstate_prov::list.
Referenced by ast_channel_free(), ast_device_state_changed(), ast_device_state_changed_literal(), ast_devstate_changed(), ast_setstate(), and dahdi_new().
00493 { 00494 struct state_change *change; 00495 00496 /* 00497 * If we know the state change (how nice of the caller of this function!) 00498 * then we can just generate a device state event. 00499 * 00500 * Otherwise, we do the following: 00501 * - Queue an event up to another thread that the state has changed 00502 * - In the processing thread, it calls the callback provided by the 00503 * device state provider (which may or may not be a channel driver) 00504 * to determine the state. 00505 * - If the device state provider does not know the state, or this is 00506 * for a channel and the channel driver does not implement a device 00507 * state callback, then we will look through the channel list to 00508 * see if we can determine a state based on active calls. 00509 * - Once a state has been determined, a device state event is generated. 00510 */ 00511 00512 if (state != AST_DEVICE_UNKNOWN) { 00513 devstate_event(device, state); 00514 } else if (change_thread == AST_PTHREADT_NULL || !(change = ast_calloc(1, sizeof(*change) + strlen(device)))) { 00515 /* we could not allocate a change struct, or */ 00516 /* there is no background thread, so process the change now */ 00517 do_state_change(device); 00518 } else { 00519 /* queue the change */ 00520 strcpy(change->device, device); 00521 AST_LIST_LOCK(&state_changes); 00522 AST_LIST_INSERT_TAIL(&state_changes, change, list); 00523 ast_cond_signal(&change_pending); 00524 AST_LIST_UNLOCK(&state_changes); 00525 } 00526 00527 return 1; 00528 }
int ast_devstate_prov_add | ( | const char * | label, | |
ast_devstate_prov_cb_type | callback | |||
) |
Add device state provider.
label | to use in hint, like label:object | |
callback | Callback |
0 | success | |
-1 | failure |
Definition at line 396 of file devicestate.c.
References ast_calloc, ast_copy_string(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and devstate_prov::list.
Referenced by ast_features_init(), and load_module().
00397 { 00398 struct devstate_prov *devprov; 00399 00400 if (!callback || !(devprov = ast_calloc(1, sizeof(*devprov)))) 00401 return -1; 00402 00403 devprov->callback = callback; 00404 ast_copy_string(devprov->label, label, sizeof(devprov->label)); 00405 00406 AST_RWLIST_WRLOCK(&devstate_provs); 00407 AST_RWLIST_INSERT_HEAD(&devstate_provs, devprov, list); 00408 AST_RWLIST_UNLOCK(&devstate_provs); 00409 00410 return 0; 00411 }
int ast_devstate_prov_del | ( | const char * | label | ) |
Remove device state provider.
label | to use in hint, like label:object |
-1 | on failure | |
0 | on success |
Definition at line 414 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, devstate_prov::label, and devstate_prov::list.
Referenced by unload_module().
00415 { 00416 struct devstate_prov *devcb; 00417 int res = -1; 00418 00419 AST_RWLIST_WRLOCK(&devstate_provs); 00420 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&devstate_provs, devcb, list) { 00421 if (!strcasecmp(devcb->label, label)) { 00422 AST_RWLIST_REMOVE_CURRENT(list); 00423 ast_free(devcb); 00424 res = 0; 00425 break; 00426 } 00427 } 00428 AST_RWLIST_TRAVERSE_SAFE_END; 00429 AST_RWLIST_UNLOCK(&devstate_provs); 00430 00431 return res; 00432 }
const char* ast_devstate_str | ( | enum ast_device_state | devstate | ) |
Convert device state to text string that is easier to parse.
devstate | Current device state |
Definition at line 226 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 devstate_read().
00227 { 00228 const char *res = "UNKNOWN"; 00229 00230 switch (state) { 00231 case AST_DEVICE_UNKNOWN: 00232 break; 00233 case AST_DEVICE_NOT_INUSE: 00234 res = "NOT_INUSE"; 00235 break; 00236 case AST_DEVICE_INUSE: 00237 res = "INUSE"; 00238 break; 00239 case AST_DEVICE_BUSY: 00240 res = "BUSY"; 00241 break; 00242 case AST_DEVICE_INVALID: 00243 res = "INVALID"; 00244 break; 00245 case AST_DEVICE_UNAVAILABLE: 00246 res = "UNAVAILABLE"; 00247 break; 00248 case AST_DEVICE_RINGING: 00249 res = "RINGING"; 00250 break; 00251 case AST_DEVICE_RINGINUSE: 00252 res = "RINGINUSE"; 00253 break; 00254 case AST_DEVICE_ONHOLD: 00255 res = "ONHOLD"; 00256 break; 00257 } 00258 00259 return res; 00260 }
enum ast_device_state ast_devstate_val | ( | const char * | val | ) |
Convert device state from text to integer value.
val | The text representing the device state. Valid values are anything that comes after AST_DEVICE_ in one of the defined values. |
Definition at line 262 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 custom_devstate_callback(), devstate_write(), handle_cli_devstate_change(), and load_module().
00263 { 00264 if (!strcasecmp(val, "NOT_INUSE")) 00265 return AST_DEVICE_NOT_INUSE; 00266 else if (!strcasecmp(val, "INUSE")) 00267 return AST_DEVICE_INUSE; 00268 else if (!strcasecmp(val, "BUSY")) 00269 return AST_DEVICE_BUSY; 00270 else if (!strcasecmp(val, "INVALID")) 00271 return AST_DEVICE_INVALID; 00272 else if (!strcasecmp(val, "UNAVAILABLE")) 00273 return AST_DEVICE_UNAVAILABLE; 00274 else if (!strcasecmp(val, "RINGING")) 00275 return AST_DEVICE_RINGING; 00276 else if (!strcasecmp(val, "RINGINUSE")) 00277 return AST_DEVICE_RINGINUSE; 00278 else if (!strcasecmp(val, "ONHOLD")) 00279 return AST_DEVICE_ONHOLD; 00280 00281 return AST_DEVICE_UNKNOWN; 00282 }
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.
0 | success | |
-1 | failure |
Definition at line 847 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().
00848 { 00849 if (devstate_collector.enabled) { 00850 return 0; 00851 } 00852 00853 devstate_collector.event_sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE_CHANGE, 00854 devstate_change_collector_cb, NULL, AST_EVENT_IE_END); 00855 00856 if (!devstate_collector.event_sub) { 00857 ast_log(LOG_ERROR, "Failed to create subscription for the device state change collector\n"); 00858 return -1; 00859 } 00860 00861 ast_mutex_init(&devstate_collector.lock); 00862 ast_cond_init(&devstate_collector.cond, NULL); 00863 if (ast_pthread_create_background(&devstate_collector.thread, NULL, run_devstate_collector, NULL) < 0) { 00864 ast_log(LOG_ERROR, "Unable to start device state collector thread.\n"); 00865 return -1; 00866 } 00867 00868 devstate_collector.enabled = 1; 00869 00870 return 0; 00871 }
enum ast_device_state ast_parse_device_state | ( | const char * | device | ) |
Search the Channels by Name.
Definition at line 289 of file devicestate.c.
References ast_channel::_state, AST_CHANNEL_NAME, ast_channel_unlock, ast_copy_string(), AST_DEVICE_INUSE, AST_DEVICE_RINGING, ast_device_state(), AST_DEVICE_UNKNOWN, ast_get_channel_by_name_prefix_locked(), AST_STATE_RINGING, chan, and match().
Referenced by _ast_device_state(), and chanavail_exec().
00290 { 00291 struct ast_channel *chan; 00292 char match[AST_CHANNEL_NAME]; 00293 enum ast_device_state res; 00294 00295 ast_copy_string(match, device, sizeof(match)-1); 00296 strcat(match, "-"); 00297 chan = ast_get_channel_by_name_prefix_locked(match, strlen(match)); 00298 00299 if (!chan) 00300 return AST_DEVICE_UNKNOWN; 00301 00302 if (chan->_state == AST_STATE_RINGING) 00303 res = AST_DEVICE_RINGING; 00304 else 00305 res = AST_DEVICE_INUSE; 00306 00307 ast_channel_unlock(chan); 00308 00309 return res; 00310 }
enum ast_device_state ast_state_chan2dev | ( | enum ast_channel_state | chanstate | ) |
Convert channel state to devicestate.
chanstate | Current channel state |
Definition at line 214 of file devicestate.c.
References AST_DEVICE_UNKNOWN, and chan.
Referenced by dahdi_new().
00215 { 00216 int i; 00217 chanstate &= 0xFFFF; 00218 for (i = 0; chan2dev[i].chan != -100; i++) { 00219 if (chan2dev[i].chan == chanstate) { 00220 return chan2dev[i].dev; 00221 } 00222 } 00223 return AST_DEVICE_UNKNOWN; 00224 }
static void destroy_devstate_change | ( | struct devstate_change * | sc | ) | [static] |
Definition at line 584 of file devicestate.c.
References ast_free.
Referenced by run_devstate_collector().
00585 { 00586 ast_free(sc); 00587 }
const char* devstate2str | ( | enum ast_device_state | devstate | ) |
Convert device state to text string for output.
devstate | Current device state |
Definition at line 209 of file devicestate.c.
Referenced by __queues_show(), do_state_change(), handle_statechange(), notify_metermaids(), page_exec(), and process_collection().
00210 { 00211 return devstatestring[devstate]; 00212 }
static void devstate_cache_cb | ( | const struct ast_event * | event, | |
void * | data | |||
) | [static] |
Definition at line 595 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().
00596 { 00597 struct change_collection *collection = data; 00598 int i; 00599 const struct ast_eid *eid; 00600 00601 if (collection->num_states == ARRAY_LEN(collection->states)) { 00602 ast_log(LOG_ERROR, "More per-server state values than we have room for (MAX_SERVERS is %d)\n", 00603 MAX_SERVERS); 00604 return; 00605 } 00606 00607 if (!(eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID))) { 00608 ast_log(LOG_ERROR, "Device state change event with no EID\n"); 00609 return; 00610 } 00611 00612 i = collection->num_states; 00613 00614 collection->states[i].state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE); 00615 collection->states[i].eid = *eid; 00616 00617 collection->num_states++; 00618 }
static enum ast_device_state devstate_cached | ( | const char * | device | ) | [static] |
Definition at line 312 of file devicestate.c.
References ast_device_state(), 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().
00313 { 00314 enum ast_device_state res = AST_DEVICE_UNKNOWN; 00315 struct ast_event *event; 00316 00317 event = ast_event_get_cached(AST_EVENT_DEVICE_STATE, 00318 AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device, 00319 AST_EVENT_IE_END); 00320 00321 if (!event) 00322 return res; 00323 00324 res = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE); 00325 00326 ast_event_destroy(event); 00327 00328 return res; 00329 }
static void devstate_change_collector_cb | ( | const struct ast_event * | event, | |
void * | data | |||
) | [static] |
Definition at line 719 of file devicestate.c.
References ast_calloc, ast_cond_signal(), ast_event_get_ie_raw(), ast_event_get_ie_str(), ast_event_get_ie_uint(), 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_collector, ast_eid::eid, and LOG_ERROR.
Referenced by ast_enable_distributed_devstate().
00720 { 00721 struct devstate_change *sc; 00722 const char *device; 00723 const struct ast_eid *eid; 00724 uint32_t state; 00725 00726 device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE); 00727 eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID); 00728 state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE); 00729 00730 if (ast_strlen_zero(device) || !eid) { 00731 ast_log(LOG_ERROR, "Invalid device state change event received\n"); 00732 return; 00733 } 00734 00735 if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(device)))) 00736 return; 00737 00738 strcpy(sc->device, device); 00739 sc->eid = *eid; 00740 sc->state = state; 00741 00742 ast_mutex_lock(&devstate_collector.lock); 00743 AST_LIST_INSERT_TAIL(&devstate_collector.devstate_change_q, sc, entry); 00744 ast_cond_signal(&devstate_collector.cond); 00745 ast_mutex_unlock(&devstate_collector.lock); 00746 }
static void devstate_event | ( | const char * | device, | |
enum ast_device_state | state | |||
) | [static] |
Definition at line 454 of file devicestate.c.
References ast_debug, AST_EVENT_DEVICE_STATE, AST_EVENT_DEVICE_STATE_CHANGE, 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_and_cache(), and devstate_collector.
Referenced by ast_devstate_changed_literal(), and do_state_change().
00455 { 00456 struct ast_event *event; 00457 enum ast_event_type event_type; 00458 00459 if (devstate_collector.enabled) { 00460 /* Distributed device state is enabled, so this state change is a change 00461 * for a single server, not the real state. */ 00462 event_type = AST_EVENT_DEVICE_STATE_CHANGE; 00463 } else { 00464 event_type = AST_EVENT_DEVICE_STATE; 00465 } 00466 00467 ast_debug(3, "device '%s' state '%d'\n", device, state); 00468 00469 if (!(event = ast_event_new(event_type, 00470 AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device, 00471 AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state, 00472 AST_EVENT_IE_END))) { 00473 return; 00474 } 00475 00476 ast_event_queue_and_cache(event); 00477 }
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 560 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::device, do_state_change(), devstate_prov::list, state_changes::lock, and devstate_prov::next.
Referenced by ast_device_state_engine_init().
00561 { 00562 struct state_change *next, *current; 00563 00564 for (;;) { 00565 /* This basically pops off any state change entries, resets the list back to NULL, unlocks, and processes each state change */ 00566 AST_LIST_LOCK(&state_changes); 00567 if (AST_LIST_EMPTY(&state_changes)) 00568 ast_cond_wait(&change_pending, &state_changes.lock); 00569 next = AST_LIST_FIRST(&state_changes); 00570 AST_LIST_HEAD_INIT_NOLOCK(&state_changes); 00571 AST_LIST_UNLOCK(&state_changes); 00572 00573 /* Process each state change */ 00574 while ((current = next)) { 00575 next = AST_LIST_NEXT(current, list); 00576 do_state_change(current->device); 00577 ast_free(current); 00578 } 00579 } 00580 00581 return NULL; 00582 }
static void do_state_change | ( | const char * | device | ) | [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 481 of file devicestate.c.
References _ast_device_state(), ast_debug, ast_device_state(), devstate2str(), and devstate_event().
Referenced by ast_devstate_changed_literal(), and do_devstate_changes().
00482 { 00483 enum ast_device_state state; 00484 00485 state = _ast_device_state(device, 0); 00486 00487 ast_debug(3, "Changing state for %s - state %d (%s)\n", device, state, devstate2str(state)); 00488 00489 devstate_event(device, state); 00490 }
static int getproviderstate | ( | const char * | provider, | |
const char * | address | |||
) | [static] |
Get provider device state.
Definition at line 435 of file devicestate.c.
References ast_debug, AST_DEVICE_INVALID, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, devstate_prov::callback, devstate_prov::label, and devstate_prov::list.
Referenced by _ast_device_state().
00436 { 00437 struct devstate_prov *devprov; 00438 int res = AST_DEVICE_INVALID; 00439 00440 AST_RWLIST_RDLOCK(&devstate_provs); 00441 AST_RWLIST_TRAVERSE(&devstate_provs, devprov, list) { 00442 ast_debug(5, "Checking provider %s with %s\n", devprov->label, provider); 00443 00444 if (!strcasecmp(devprov->label, provider)) { 00445 res = devprov->callback(address); 00446 break; 00447 } 00448 } 00449 AST_RWLIST_UNLOCK(&devstate_provs); 00450 00451 return res; 00452 }
static void handle_devstate_change | ( | struct devstate_change * | sc | ) | [static] |
Definition at line 673 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::device, devstate_cache_cb(), LOG_ERROR, change_collection::num_states, and process_collection().
Referenced by run_devstate_collector().
00674 { 00675 struct ast_event_sub *tmp_sub; 00676 struct change_collection collection = { 00677 .num_states = 0, 00678 }; 00679 00680 ast_debug(1, "Processing device state change for '%s'\n", sc->device); 00681 00682 if (!(tmp_sub = ast_event_subscribe_new(AST_EVENT_DEVICE_STATE_CHANGE, devstate_cache_cb, &collection))) { 00683 ast_log(LOG_ERROR, "Failed to create subscription\n"); 00684 return; 00685 } 00686 00687 if (ast_event_sub_append_ie_str(tmp_sub, AST_EVENT_IE_DEVICE, sc->device)) { 00688 ast_log(LOG_ERROR, "Failed to append device IE\n"); 00689 ast_event_sub_destroy(tmp_sub); 00690 return; 00691 } 00692 00693 /* Populate the collection of device states from the cache */ 00694 ast_event_dump_cache(tmp_sub); 00695 00696 process_collection(sc->device, &collection); 00697 00698 ast_event_sub_destroy(tmp_sub); 00699 }
static void process_collection | ( | const char * | device, | |
struct change_collection * | collection | |||
) | [static] |
Definition at line 620 of file devicestate.c.
References ast_debug, ast_device_state(), 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_and_cache(), devstate2str(), change_collection::num_states, devstate_change::state, and change_collection::states.
Referenced by handle_devstate_change().
00621 { 00622 int i; 00623 struct ast_devstate_aggregate agg; 00624 enum ast_device_state state; 00625 struct ast_event *event; 00626 00627 ast_devstate_aggregate_init(&agg); 00628 00629 for (i = 0; i < collection->num_states; i++) { 00630 ast_debug(1, "Adding per-server state of '%s' for '%s'\n", 00631 devstate2str(collection->states[i].state), device); 00632 ast_devstate_aggregate_add(&agg, collection->states[i].state); 00633 } 00634 00635 state = ast_devstate_aggregate_result(&agg); 00636 00637 ast_debug(1, "Aggregate devstate result is %d\n", state); 00638 00639 event = ast_event_get_cached(AST_EVENT_DEVICE_STATE, 00640 AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device, 00641 AST_EVENT_IE_END); 00642 00643 if (event) { 00644 enum ast_device_state old_state; 00645 00646 old_state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE); 00647 00648 ast_event_destroy(event); 00649 00650 if (state == old_state) { 00651 /* No change since last reported device state */ 00652 ast_debug(1, "Aggregate state for device '%s' has not changed from '%s'\n", 00653 device, devstate2str(state)); 00654 return; 00655 } 00656 } 00657 00658 ast_debug(1, "Aggregate state for device '%s' has changed to '%s'\n", 00659 device, devstate2str(state)); 00660 00661 event = ast_event_new(AST_EVENT_DEVICE_STATE, 00662 AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device, 00663 AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state, 00664 AST_EVENT_IE_END); 00665 00666 if (!event) { 00667 return; 00668 } 00669 00670 ast_event_queue_and_cache(event); 00671 }
static void* run_devstate_collector | ( | void * | data | ) | [static] |
Definition at line 701 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().
00702 { 00703 for (;;) { 00704 struct devstate_change *sc; 00705 00706 ast_mutex_lock(&devstate_collector.lock); 00707 while (!(sc = AST_LIST_REMOVE_HEAD(&devstate_collector.devstate_change_q, entry))) 00708 ast_cond_wait(&devstate_collector.cond, &devstate_collector.lock); 00709 ast_mutex_unlock(&devstate_collector.lock); 00710 00711 handle_devstate_change(sc); 00712 00713 destroy_devstate_change(sc); 00714 } 00715 00716 return NULL; 00717 }
ast_cond_t change_pending [static] |
pthread_t change_thread = AST_PTHREADT_NULL [static] |
The device state change notification thread.
Definition at line 181 of file devicestate.c.
Referenced by ast_device_state_engine_init(), and ast_devstate_changed_literal().
Definition at line 196 of file devicestate.c.
Referenced by _macro_exec(), gosubif_exec(), and smdi_message_wait().
struct { ... } devstate_change_q |
struct { ... } devstate_collector |
const char* devstatestring[] [static] |
unsigned int enabled |
Definition at line 199 of file devicestate.c.
struct ast_event_sub* event_sub |
Definition at line 195 of file devicestate.c.
Referenced by ast_event_dump_cache(), ast_event_report_subs(), and dump_cache_cb().
struct devstate_change* first |
Definition at line 198 of file devicestate.c.
Referenced by ast_print_group(), h261_encap(), h263_encap(), h263p_encap(), h264_encap(), log_jack_status(), misdn_lib_init(), mpeg4_encap(), and schedule().
struct devstate_change* last |
Definition at line 198 of file devicestate.c.
Referenced by __ao2_callback(), aji_handle_presence(), apply_outgoing(), ast_config_engine_deregister(), ast_db_freetree(), ast_db_gettree(), config_odbc(), config_pgsql(), do_monitor(), gtalk_free_candidates(), jingle_free_candidates(), load_password(), next_channel(), node_lookup(), scan_thread(), schedule(), and try_firmware().
Definition at line 197 of file devicestate.c.
Referenced by dahdi_request(), dahdi_restart(), dahdi_set_swgain(), dahdi_show_channel(), dahdi_show_channels(), free_config(), load_config(), load_module(), load_rpt_vars(), rpt_master(), smdi_message_wait(), sqlite3_log(), and unload_module().
pthread_t thread |
Definition at line 194 of file devicestate.c.
Referenced by __schedule_action(), __unload_module(), ast_bridge_call_thread_launch(), find_idle_thread(), handle_cli_iax2_show_threads(), handle_deferred_full_frames(), iax2_process_thread(), iax2_process_thread_cleanup(), insert_idle_thread(), launch_monitor_thread(), load_module(), socket_process(), socket_read(), start_network_thread(), and unload_module().