#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 334 of file devicestate.c.
References ast_debug, AST_DEVICE_INVALID, 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().
00335 { 00336 char *buf; 00337 char *number; 00338 const struct ast_channel_tech *chan_tech; 00339 enum ast_device_state res; 00340 /*! \brief Channel driver that provides device state */ 00341 char *tech; 00342 /*! \brief Another provider of device state */ 00343 char *provider = NULL; 00344 00345 /* If the last known state is cached, just return that */ 00346 if (check_cache) { 00347 res = devstate_cached(device); 00348 if (res != AST_DEVICE_UNKNOWN) { 00349 return res; 00350 } 00351 } 00352 00353 buf = ast_strdupa(device); 00354 tech = strsep(&buf, "/"); 00355 if (!(number = buf)) { 00356 if (!(provider = strsep(&tech, ":"))) 00357 return AST_DEVICE_INVALID; 00358 /* We have a provider */ 00359 number = tech; 00360 tech = NULL; 00361 } 00362 00363 if (provider) { 00364 ast_debug(3, "Checking if I can find provider for \"%s\" - number: %s\n", provider, number); 00365 return getproviderstate(provider, number); 00366 } 00367 00368 ast_debug(4, "No provider found, checking channel drivers for %s - %s\n", tech, number); 00369 00370 if (!(chan_tech = ast_get_channel_tech(tech))) 00371 return AST_DEVICE_INVALID; 00372 00373 if (!(chan_tech->devicestate)) /* Does the channel driver support device state notification? */ 00374 return ast_parse_device_state(device); /* No, try the generic function */ 00375 00376 res = chan_tech->devicestate(number); 00377 00378 if (res != AST_DEVICE_UNKNOWN) 00379 return res; 00380 00381 res = ast_parse_device_state(device); 00382 00383 return res; 00384 }
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 386 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().
00387 { 00388 /* This function is called from elsewhere in the code to find out the 00389 * current state of a device. Check the cache, first. */ 00390 00391 return _ast_device_state(device, 1); 00392 }
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 546 of file devicestate.c.
References AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), AST_MAX_EXTENSION, and buf.
00547 { 00548 char buf[AST_MAX_EXTENSION]; 00549 va_list ap; 00550 00551 va_start(ap, fmt); 00552 vsnprintf(buf, sizeof(buf), fmt, ap); 00553 va_end(ap); 00554 00555 return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, buf); 00556 }
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 529 of file devicestate.c.
References AST_DEVICE_UNKNOWN, and ast_devstate_changed_literal().
00530 { 00531 return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, dev); 00532 }
int ast_device_state_engine_init | ( | void | ) |
Initialize the device state engine in separate thread.
Provided by devicestate.c
Definition at line 748 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().
00749 { 00750 ast_cond_init(&change_pending, NULL); 00751 if (ast_pthread_create_background(&change_thread, NULL, do_devstate_changes, NULL) < 0) { 00752 ast_log(LOG_ERROR, "Unable to start device state change thread.\n"); 00753 return -1; 00754 } 00755 00756 return 0; 00757 }
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 769 of file devicestate.c.
References ast_devstate_aggregate::all_busy, ast_devstate_aggregate::all_free, ast_devstate_aggregate::all_unavail, ast_devstate_aggregate::all_unknown, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_TOTAL, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_aggregate::busy, ast_devstate_aggregate::in_use, ast_devstate_aggregate::on_hold, and ast_devstate_aggregate::ring.
Referenced by ast_extension_state2(), and process_collection().
00770 { 00771 switch (state) { 00772 case AST_DEVICE_NOT_INUSE: 00773 agg->all_unknown = 0; 00774 agg->all_unavail = 0; 00775 agg->all_busy = 0; 00776 break; 00777 case AST_DEVICE_INUSE: 00778 agg->in_use = 1; 00779 agg->all_unavail = 0; 00780 agg->all_free = 0; 00781 agg->all_unknown = 0; 00782 break; 00783 case AST_DEVICE_RINGING: 00784 agg->ring = 1; 00785 agg->all_unavail = 0; 00786 agg->all_free = 0; 00787 agg->all_unknown = 0; 00788 break; 00789 case AST_DEVICE_RINGINUSE: 00790 agg->in_use = 1; 00791 agg->ring = 1; 00792 agg->all_unavail = 0; 00793 agg->all_free = 0; 00794 agg->all_unknown = 0; 00795 break; 00796 case AST_DEVICE_ONHOLD: 00797 agg->all_unknown = 0; 00798 agg->all_unavail = 0; 00799 agg->all_free = 0; 00800 agg->on_hold = 1; 00801 break; 00802 case AST_DEVICE_BUSY: 00803 agg->all_unknown = 0; 00804 agg->all_unavail = 0; 00805 agg->all_free = 0; 00806 agg->busy = 1; 00807 agg->in_use = 1; 00808 break; 00809 case AST_DEVICE_UNAVAILABLE: 00810 agg->all_unknown = 0; 00811 case AST_DEVICE_INVALID: 00812 agg->all_busy = 0; 00813 agg->all_free = 0; 00814 break; 00815 case AST_DEVICE_UNKNOWN: 00816 agg->all_busy = 0; 00817 agg->all_free = 0; 00818 break; 00819 case AST_DEVICE_TOTAL: /* not a device state, included for completeness. */ 00820 break; 00821 } 00822 }
void ast_devstate_aggregate_init | ( | struct ast_devstate_aggregate * | agg | ) |
Initialize aggregate device state.
[in] | agg | the state object |
Definition at line 759 of file devicestate.c.
Referenced by ast_extension_state2(), and process_collection().
00760 { 00761 memset(agg, 0, sizeof(*agg)); 00762 00763 agg->all_unknown = 1; 00764 agg->all_unavail = 1; 00765 agg->all_busy = 1; 00766 agg->all_free = 1; 00767 }
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 825 of file devicestate.c.
References ast_devstate_aggregate::all_busy, ast_devstate_aggregate::all_free, ast_devstate_aggregate::all_unavail, ast_devstate_aggregate::all_unknown, AST_DEVICE_BUSY, AST_DEVICE_INUSE, 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, ast_devstate_aggregate::on_hold, and ast_devstate_aggregate::ring.
Referenced by ast_extension_state2(), and process_collection().
00826 { 00827 if (agg->all_free) 00828 return AST_DEVICE_NOT_INUSE; 00829 if ((agg->in_use || agg->on_hold) && agg->ring) 00830 return AST_DEVICE_RINGINUSE; 00831 if (agg->ring) 00832 return AST_DEVICE_RINGING; 00833 if (agg->busy) 00834 return AST_DEVICE_BUSY; 00835 if (agg->in_use) 00836 return AST_DEVICE_INUSE; 00837 if (agg->on_hold) 00838 return AST_DEVICE_ONHOLD; 00839 if (agg->all_busy) 00840 return AST_DEVICE_BUSY; 00841 if (agg->all_unknown) 00842 return AST_DEVICE_UNKNOWN; 00843 if (agg->all_unavail) 00844 return AST_DEVICE_UNAVAILABLE; 00845 00846 return AST_DEVICE_NOT_INUSE; 00847 }
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 534 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().
00535 { 00536 char buf[AST_MAX_EXTENSION]; 00537 va_list ap; 00538 00539 va_start(ap, fmt); 00540 vsnprintf(buf, sizeof(buf), fmt, ap); 00541 va_end(ap); 00542 00543 return ast_devstate_changed_literal(state, buf); 00544 }
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 491 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().
00492 { 00493 struct state_change *change; 00494 00495 /* 00496 * If we know the state change (how nice of the caller of this function!) 00497 * then we can just generate a device state event. 00498 * 00499 * Otherwise, we do the following: 00500 * - Queue an event up to another thread that the state has changed 00501 * - In the processing thread, it calls the callback provided by the 00502 * device state provider (which may or may not be a channel driver) 00503 * to determine the state. 00504 * - If the device state provider does not know the state, or this is 00505 * for a channel and the channel driver does not implement a device 00506 * state callback, then we will look through the channel list to 00507 * see if we can determine a state based on active calls. 00508 * - Once a state has been determined, a device state event is generated. 00509 */ 00510 00511 if (state != AST_DEVICE_UNKNOWN) { 00512 devstate_event(device, state); 00513 } else if (change_thread == AST_PTHREADT_NULL || !(change = ast_calloc(1, sizeof(*change) + strlen(device)))) { 00514 /* we could not allocate a change struct, or */ 00515 /* there is no background thread, so process the change now */ 00516 do_state_change(device); 00517 } else { 00518 /* queue the change */ 00519 strcpy(change->device, device); 00520 AST_LIST_LOCK(&state_changes); 00521 AST_LIST_INSERT_TAIL(&state_changes, change, list); 00522 ast_cond_signal(&change_pending); 00523 AST_LIST_UNLOCK(&state_changes); 00524 } 00525 00526 return 1; 00527 }
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 395 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().
00396 { 00397 struct devstate_prov *devprov; 00398 00399 if (!callback || !(devprov = ast_calloc(1, sizeof(*devprov)))) 00400 return -1; 00401 00402 devprov->callback = callback; 00403 ast_copy_string(devprov->label, label, sizeof(devprov->label)); 00404 00405 AST_RWLIST_WRLOCK(&devstate_provs); 00406 AST_RWLIST_INSERT_HEAD(&devstate_provs, devprov, list); 00407 AST_RWLIST_UNLOCK(&devstate_provs); 00408 00409 return 0; 00410 }
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 413 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().
00414 { 00415 struct devstate_prov *devcb; 00416 int res = -1; 00417 00418 AST_RWLIST_WRLOCK(&devstate_provs); 00419 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&devstate_provs, devcb, list) { 00420 if (!strcasecmp(devcb->label, label)) { 00421 AST_RWLIST_REMOVE_CURRENT(list); 00422 ast_free(devcb); 00423 res = 0; 00424 break; 00425 } 00426 } 00427 AST_RWLIST_TRAVERSE_SAFE_END; 00428 AST_RWLIST_UNLOCK(&devstate_provs); 00429 00430 return res; 00431 }
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_TOTAL, 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 case AST_DEVICE_TOTAL: 00258 break; 00259 } 00260 00261 return res; 00262 }
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 264 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().
00265 { 00266 if (!strcasecmp(val, "NOT_INUSE")) 00267 return AST_DEVICE_NOT_INUSE; 00268 else if (!strcasecmp(val, "INUSE")) 00269 return AST_DEVICE_INUSE; 00270 else if (!strcasecmp(val, "BUSY")) 00271 return AST_DEVICE_BUSY; 00272 else if (!strcasecmp(val, "INVALID")) 00273 return AST_DEVICE_INVALID; 00274 else if (!strcasecmp(val, "UNAVAILABLE")) 00275 return AST_DEVICE_UNAVAILABLE; 00276 else if (!strcasecmp(val, "RINGING")) 00277 return AST_DEVICE_RINGING; 00278 else if (!strcasecmp(val, "RINGINUSE")) 00279 return AST_DEVICE_RINGINUSE; 00280 else if (!strcasecmp(val, "ONHOLD")) 00281 return AST_DEVICE_ONHOLD; 00282 00283 return AST_DEVICE_UNKNOWN; 00284 }
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 849 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().
00850 { 00851 if (devstate_collector.enabled) { 00852 return 0; 00853 } 00854 00855 devstate_collector.event_sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE_CHANGE, 00856 devstate_change_collector_cb, NULL, AST_EVENT_IE_END); 00857 00858 if (!devstate_collector.event_sub) { 00859 ast_log(LOG_ERROR, "Failed to create subscription for the device state change collector\n"); 00860 return -1; 00861 } 00862 00863 ast_mutex_init(&devstate_collector.lock); 00864 ast_cond_init(&devstate_collector.cond, NULL); 00865 if (ast_pthread_create_background(&devstate_collector.thread, NULL, run_devstate_collector, NULL) < 0) { 00866 ast_log(LOG_ERROR, "Unable to start device state collector thread.\n"); 00867 return -1; 00868 } 00869 00870 devstate_collector.enabled = 1; 00871 00872 return 0; 00873 }
enum ast_device_state ast_parse_device_state | ( | const char * | device | ) |
Search the Channels by Name.
Definition at line 291 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().
00292 { 00293 struct ast_channel *chan; 00294 char match[AST_CHANNEL_NAME]; 00295 enum ast_device_state res; 00296 00297 ast_copy_string(match, device, sizeof(match)-1); 00298 strcat(match, "-"); 00299 chan = ast_get_channel_by_name_prefix_locked(match, strlen(match)); 00300 00301 if (!chan) 00302 return AST_DEVICE_UNKNOWN; 00303 00304 if (chan->_state == AST_STATE_RINGING) 00305 res = AST_DEVICE_RINGING; 00306 else 00307 res = AST_DEVICE_INUSE; 00308 00309 ast_channel_unlock(chan); 00310 00311 return res; 00312 }
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 583 of file devicestate.c.
References ast_free.
Referenced by run_devstate_collector().
00584 { 00585 ast_free(sc); 00586 }
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 594 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().
00595 { 00596 struct change_collection *collection = data; 00597 int i; 00598 const struct ast_eid *eid; 00599 00600 if (collection->num_states == ARRAY_LEN(collection->states)) { 00601 ast_log(LOG_ERROR, "More per-server state values than we have room for (MAX_SERVERS is %d)\n", 00602 MAX_SERVERS); 00603 return; 00604 } 00605 00606 if (!(eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID))) { 00607 ast_log(LOG_ERROR, "Device state change event with no EID\n"); 00608 return; 00609 } 00610 00611 i = collection->num_states; 00612 00613 collection->states[i].state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE); 00614 collection->states[i].eid = *eid; 00615 00616 collection->num_states++; 00617 }
static enum ast_device_state devstate_cached | ( | const char * | device | ) | [static] |
Definition at line 314 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().
00315 { 00316 enum ast_device_state res = AST_DEVICE_UNKNOWN; 00317 struct ast_event *event; 00318 00319 event = ast_event_get_cached(AST_EVENT_DEVICE_STATE, 00320 AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device, 00321 AST_EVENT_IE_END); 00322 00323 if (!event) 00324 return res; 00325 00326 res = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE); 00327 00328 ast_event_destroy(event); 00329 00330 return res; 00331 }
static void devstate_change_collector_cb | ( | const struct ast_event * | event, | |
void * | data | |||
) | [static] |
Definition at line 718 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().
00719 { 00720 struct devstate_change *sc; 00721 const char *device; 00722 const struct ast_eid *eid; 00723 uint32_t state; 00724 00725 device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE); 00726 eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID); 00727 state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE); 00728 00729 if (ast_strlen_zero(device) || !eid) { 00730 ast_log(LOG_ERROR, "Invalid device state change event received\n"); 00731 return; 00732 } 00733 00734 if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(device)))) 00735 return; 00736 00737 strcpy(sc->device, device); 00738 sc->eid = *eid; 00739 sc->state = state; 00740 00741 ast_mutex_lock(&devstate_collector.lock); 00742 AST_LIST_INSERT_TAIL(&devstate_collector.devstate_change_q, sc, entry); 00743 ast_cond_signal(&devstate_collector.cond); 00744 ast_mutex_unlock(&devstate_collector.lock); 00745 }
static void devstate_event | ( | const char * | device, | |
enum ast_device_state | state | |||
) | [static] |
Definition at line 453 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().
00454 { 00455 struct ast_event *event; 00456 enum ast_event_type event_type; 00457 00458 if (devstate_collector.enabled) { 00459 /* Distributed device state is enabled, so this state change is a change 00460 * for a single server, not the real state. */ 00461 event_type = AST_EVENT_DEVICE_STATE_CHANGE; 00462 } else { 00463 event_type = AST_EVENT_DEVICE_STATE; 00464 } 00465 00466 ast_debug(3, "device '%s' state '%d'\n", device, state); 00467 00468 if (!(event = ast_event_new(event_type, 00469 AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device, 00470 AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state, 00471 AST_EVENT_IE_END))) { 00472 return; 00473 } 00474 00475 ast_event_queue_and_cache(event); 00476 }
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 559 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().
00560 { 00561 struct state_change *next, *current; 00562 00563 for (;;) { 00564 /* This basically pops off any state change entries, resets the list back to NULL, unlocks, and processes each state change */ 00565 AST_LIST_LOCK(&state_changes); 00566 if (AST_LIST_EMPTY(&state_changes)) 00567 ast_cond_wait(&change_pending, &state_changes.lock); 00568 next = AST_LIST_FIRST(&state_changes); 00569 AST_LIST_HEAD_INIT_NOLOCK(&state_changes); 00570 AST_LIST_UNLOCK(&state_changes); 00571 00572 /* Process each state change */ 00573 while ((current = next)) { 00574 next = AST_LIST_NEXT(current, list); 00575 do_state_change(current->device); 00576 ast_free(current); 00577 } 00578 } 00579 00580 return NULL; 00581 }
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 480 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().
00481 { 00482 enum ast_device_state state; 00483 00484 state = _ast_device_state(device, 0); 00485 00486 ast_debug(3, "Changing state for %s - state %d (%s)\n", device, state, devstate2str(state)); 00487 00488 devstate_event(device, state); 00489 }
static int getproviderstate | ( | const char * | provider, | |
const char * | address | |||
) | [static] |
Get provider device state.
Definition at line 434 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().
00435 { 00436 struct devstate_prov *devprov; 00437 int res = AST_DEVICE_INVALID; 00438 00439 AST_RWLIST_RDLOCK(&devstate_provs); 00440 AST_RWLIST_TRAVERSE(&devstate_provs, devprov, list) { 00441 ast_debug(5, "Checking provider %s with %s\n", devprov->label, provider); 00442 00443 if (!strcasecmp(devprov->label, provider)) { 00444 res = devprov->callback(address); 00445 break; 00446 } 00447 } 00448 AST_RWLIST_UNLOCK(&devstate_provs); 00449 00450 return res; 00451 }
static void handle_devstate_change | ( | struct devstate_change * | sc | ) | [static] |
Definition at line 672 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().
00673 { 00674 struct ast_event_sub *tmp_sub; 00675 struct change_collection collection = { 00676 .num_states = 0, 00677 }; 00678 00679 ast_debug(1, "Processing device state change for '%s'\n", sc->device); 00680 00681 if (!(tmp_sub = ast_event_subscribe_new(AST_EVENT_DEVICE_STATE_CHANGE, devstate_cache_cb, &collection))) { 00682 ast_log(LOG_ERROR, "Failed to create subscription\n"); 00683 return; 00684 } 00685 00686 if (ast_event_sub_append_ie_str(tmp_sub, AST_EVENT_IE_DEVICE, sc->device)) { 00687 ast_log(LOG_ERROR, "Failed to append device IE\n"); 00688 ast_event_sub_destroy(tmp_sub); 00689 return; 00690 } 00691 00692 /* Populate the collection of device states from the cache */ 00693 ast_event_dump_cache(tmp_sub); 00694 00695 process_collection(sc->device, &collection); 00696 00697 ast_event_sub_destroy(tmp_sub); 00698 }
static void process_collection | ( | const char * | device, | |
struct change_collection * | collection | |||
) | [static] |
Definition at line 619 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().
00620 { 00621 int i; 00622 struct ast_devstate_aggregate agg; 00623 enum ast_device_state state; 00624 struct ast_event *event; 00625 00626 ast_devstate_aggregate_init(&agg); 00627 00628 for (i = 0; i < collection->num_states; i++) { 00629 ast_debug(1, "Adding per-server state of '%s' for '%s'\n", 00630 devstate2str(collection->states[i].state), device); 00631 ast_devstate_aggregate_add(&agg, collection->states[i].state); 00632 } 00633 00634 state = ast_devstate_aggregate_result(&agg); 00635 00636 ast_debug(1, "Aggregate devstate result is %d\n", state); 00637 00638 event = ast_event_get_cached(AST_EVENT_DEVICE_STATE, 00639 AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device, 00640 AST_EVENT_IE_END); 00641 00642 if (event) { 00643 enum ast_device_state old_state; 00644 00645 old_state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE); 00646 00647 ast_event_destroy(event); 00648 00649 if (state == old_state) { 00650 /* No change since last reported device state */ 00651 ast_debug(1, "Aggregate state for device '%s' has not changed from '%s'\n", 00652 device, devstate2str(state)); 00653 return; 00654 } 00655 } 00656 00657 ast_debug(1, "Aggregate state for device '%s' has changed to '%s'\n", 00658 device, devstate2str(state)); 00659 00660 event = ast_event_new(AST_EVENT_DEVICE_STATE, 00661 AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device, 00662 AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state, 00663 AST_EVENT_IE_END); 00664 00665 if (!event) { 00666 return; 00667 } 00668 00669 ast_event_queue_and_cache(event); 00670 }
static void* run_devstate_collector | ( | void * | data | ) | [static] |
Definition at line 700 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().
00701 { 00702 for (;;) { 00703 struct devstate_change *sc; 00704 00705 ast_mutex_lock(&devstate_collector.lock); 00706 while (!(sc = AST_LIST_REMOVE_HEAD(&devstate_collector.devstate_change_q, entry))) 00707 ast_cond_wait(&devstate_collector.cond, &devstate_collector.lock); 00708 ast_mutex_unlock(&devstate_collector.lock); 00709 00710 handle_devstate_change(sc); 00711 00712 destroy_devstate_change(sc); 00713 } 00714 00715 return NULL; 00716 }
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_format_str_reduce(), 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(), load_config(), load_module(), load_rpt_vars(), reload(), rpt_master(), smdi_message_wait(), unload_module(), and write_cdr().
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().