Device state management. More...
#include "asterisk/channelstate.h"
Go to the source code of this file.
Data Structures | |
struct | ast_devstate_aggregate |
You shouldn't care about the contents of this struct. More... | |
Enumerations | |
enum | ast_device_state { AST_DEVICE_UNKNOWN, AST_DEVICE_NOT_INUSE, AST_DEVICE_INUSE, AST_DEVICE_BUSY, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_ONHOLD, AST_DEVICE_TOTAL } |
Device States. More... | |
enum | ast_devstate_cache { AST_DEVSTATE_NOT_CACHABLE, AST_DEVSTATE_CACHABLE } |
Device State Cachability. More... | |
Functions | |
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 *device) |
Tells Asterisk the State for Device is changed. | |
const char * | ast_devstate2str (enum ast_device_state devstate) attribute_pure |
Find devicestate as text message for output. | |
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, enum ast_devstate_cache cachable, const char *fmt,...) |
Tells Asterisk the State for Device is changed. | |
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. | |
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 devstate) attribute_pure |
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. | |
const char * | devstate2str (enum ast_device_state devstate) attribute_pure |
Convert device state to text string for output. | |
Variables | |
enum ast_device_state(* | ast_devstate_prov_cb_type )(const char *data) |
Devicestate provider call back. |
Device state management.
To subscribe to device state changes, use the generic ast_event_subscribe method. For an example, see apps/app_queue.c.
Definition in file devicestate.h.
enum ast_device_state |
Device States.
AST_DEVICE_UNKNOWN |
Device is valid but channel didn't know state |
AST_DEVICE_NOT_INUSE |
Device is not used |
AST_DEVICE_INUSE |
Device is in use |
AST_DEVICE_BUSY |
Device is busy |
AST_DEVICE_INVALID |
Device is invalid |
AST_DEVICE_UNAVAILABLE |
Device is unavailable |
AST_DEVICE_RINGING |
Device is ringing |
AST_DEVICE_RINGINUSE |
Device is ringing *and* in use |
AST_DEVICE_ONHOLD |
Device is on hold |
AST_DEVICE_TOTAL |
Definition at line 51 of file devicestate.h.
00051 { 00052 AST_DEVICE_UNKNOWN, /*!< Device is valid but channel didn't know state */ 00053 AST_DEVICE_NOT_INUSE, /*!< Device is not used */ 00054 AST_DEVICE_INUSE, /*!< Device is in use */ 00055 AST_DEVICE_BUSY, /*!< Device is busy */ 00056 AST_DEVICE_INVALID, /*!< Device is invalid */ 00057 AST_DEVICE_UNAVAILABLE, /*!< Device is unavailable */ 00058 AST_DEVICE_RINGING, /*!< Device is ringing */ 00059 AST_DEVICE_RINGINUSE, /*!< Device is ringing *and* in use */ 00060 AST_DEVICE_ONHOLD, /*!< Device is on hold */ 00061 AST_DEVICE_TOTAL, /*/ Total num of device states, used for testing */ 00062 };
enum ast_devstate_cache |
Device State Cachability.
AST_DEVSTATE_NOT_CACHABLE |
This device state is not cachable |
AST_DEVSTATE_CACHABLE |
This device state is cachable |
Definition at line 67 of file devicestate.h.
00067 { 00068 AST_DEVSTATE_NOT_CACHABLE, /*!< This device state is not cachable */ 00069 AST_DEVSTATE_CACHABLE, /*!< This device state is cachable */ 00070 };
enum ast_device_state ast_device_state | ( | const char * | device | ) |
Asks a channel for device state.
device | like 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.
an | AST_DEVICE_??? state | |
-1 | on failure |
Definition at line 362 of file devicestate.c.
References _ast_device_state().
00363 { 00364 /* This function is called from elsewhere in the code to find out the 00365 * current state of a device. Check the cache, first. */ 00366 00367 return _ast_device_state(device, 1); 00368 }
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 |
Asterisk polls the new extension states and calls the registered callbacks for the changed extensions
0 | on success | |
-1 | on failure |
Definition at line 528 of file devicestate.c.
References AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed_literal(), and AST_MAX_EXTENSION.
00529 { 00530 char buf[AST_MAX_EXTENSION]; 00531 va_list ap; 00532 00533 va_start(ap, fmt); 00534 vsnprintf(buf, sizeof(buf), fmt, ap); 00535 va_end(ap); 00536 00537 return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, buf); 00538 }
int ast_device_state_changed_literal | ( | const char * | device | ) |
Tells Asterisk the State for Device is changed.
device | device name like a dial string |
Asterisk polls the new extension states and calls the registered callbacks for the changed extensions
0 | on success | |
-1 | on failure |
Definition at line 511 of file devicestate.c.
References AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, and ast_devstate_changed_literal().
00512 { 00513 return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, dev); 00514 }
const char* ast_devstate2str | ( | enum ast_device_state | devstate | ) |
Find devicestate as text message for output.
Definition at line 215 of file devicestate.c.
Referenced by __queues_show(), do_state_change(), extension_state_cb(), handle_statechange(), notify_metermaids(), page_exec(), and process_collection().
00216 { 00217 return devstatestring[devstate][0]; 00218 }
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 at line 764 of file devicestate.c.
References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, ast_devstate_aggregate::inuse, ast_devstate_aggregate::ringing, and ast_devstate_aggregate::state.
Referenced by ast_extension_state3(), and process_collection().
00765 { 00766 static enum ast_device_state state_order[] = { 00767 1, /* AST_DEVICE_UNKNOWN */ 00768 3, /* AST_DEVICE_NOT_INUSE */ 00769 6, /* AST_DEVICE_INUSE */ 00770 7, /* AST_DEVICE_BUSY */ 00771 0, /* AST_DEVICE_INVALID */ 00772 2, /* AST_DEVICE_UNAVAILABLE */ 00773 5, /* AST_DEVICE_RINGING */ 00774 8, /* AST_DEVICE_RINGINUSE */ 00775 4, /* AST_DEVICE_ONHOLD */ 00776 }; 00777 00778 if (state == AST_DEVICE_RINGING) { 00779 agg->ringing = 1; 00780 } else if (state == AST_DEVICE_INUSE || state == AST_DEVICE_ONHOLD || state == AST_DEVICE_BUSY) { 00781 agg->inuse = 1; 00782 } 00783 00784 if (agg->ringing && agg->inuse) { 00785 agg->state = AST_DEVICE_RINGINUSE; 00786 } else if (state_order[state] > state_order[agg->state]) { 00787 agg->state = state; 00788 } 00789 }
void ast_devstate_aggregate_init | ( | struct ast_devstate_aggregate * | agg | ) |
Initialize aggregate device state.
[in] | agg | the state object |
Definition at line 758 of file devicestate.c.
References AST_DEVICE_INVALID, and ast_devstate_aggregate::state.
Referenced by ast_extension_state3(), and process_collection().
00759 { 00760 memset(agg, 0, sizeof(*agg)); 00761 agg->state = AST_DEVICE_INVALID; 00762 }
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 791 of file devicestate.c.
References ast_devstate_aggregate::state.
Referenced by ast_extension_state3(), and process_collection().
00792 { 00793 return agg->state; 00794 }
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.
state | the new state of the device | |
cachable | whether this device state is cachable | |
fmt | device 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.
0 | on success | |
-1 | on failure |
Definition at line 516 of file devicestate.c.
References ast_devstate_changed_literal(), and AST_MAX_EXTENSION.
Referenced by __expire_registry(), __iax2_poke_noanswer(), calendar_devstate_change(), conf_run(), destroy_event(), devstate_write(), expire_register(), handle_cli_devstate_change(), handle_offhook_message(), handle_onhook_message(), handle_response_peerpoke(), handle_soft_key_event_message(), handle_stimulus_message(), join_conference_bridge(), leave_conference_bridge(), load_module(), login_exec(), notify_metermaids(), reg_source_db(), register_verify(), sip_peer_hold(), sip_poke_noanswer(), skinny_register(), skinny_unregister(), sla_change_trunk_state(), sla_handle_hold_event(), sla_station_exec(), socket_process(), update_call_counter(), and update_registry().
00517 { 00518 char buf[AST_MAX_EXTENSION]; 00519 va_list ap; 00520 00521 va_start(ap, fmt); 00522 vsnprintf(buf, sizeof(buf), fmt, ap); 00523 va_end(ap); 00524 00525 return ast_devstate_changed_literal(state, cachable, buf); 00526 }
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.
state | the new state of the device | |
cachable | whether this device state is cachable | |
device | device 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.
0 | on success | |
-1 | on failure |
Definition at line 472 of file devicestate.c.
References ast_calloc, ast_cond_signal, AST_DEVICE_UNKNOWN, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, state_change::cachable, change_thread, state_change::device, devstate_event(), and do_state_change().
Referenced by ast_channel_destructor(), ast_device_state_changed(), ast_device_state_changed_literal(), ast_devstate_changed(), ast_setstate(), and dahdi_new().
00473 { 00474 struct state_change *change; 00475 00476 /* 00477 * If we know the state change (how nice of the caller of this function!) 00478 * then we can just generate a device state event. 00479 * 00480 * Otherwise, we do the following: 00481 * - Queue an event up to another thread that the state has changed 00482 * - In the processing thread, it calls the callback provided by the 00483 * device state provider (which may or may not be a channel driver) 00484 * to determine the state. 00485 * - If the device state provider does not know the state, or this is 00486 * for a channel and the channel driver does not implement a device 00487 * state callback, then we will look through the channel list to 00488 * see if we can determine a state based on active calls. 00489 * - Once a state has been determined, a device state event is generated. 00490 */ 00491 00492 if (state != AST_DEVICE_UNKNOWN) { 00493 devstate_event(device, state, cachable); 00494 } else if (change_thread == AST_PTHREADT_NULL || !(change = ast_calloc(1, sizeof(*change) + strlen(device)))) { 00495 /* we could not allocate a change struct, or */ 00496 /* there is no background thread, so process the change now */ 00497 do_state_change(device, cachable); 00498 } else { 00499 /* queue the change */ 00500 strcpy(change->device, device); 00501 change->cachable = cachable; 00502 AST_LIST_LOCK(&state_changes); 00503 AST_LIST_INSERT_TAIL(&state_changes, change, list); 00504 ast_cond_signal(&change_pending); 00505 AST_LIST_UNLOCK(&state_changes); 00506 } 00507 00508 return 1; 00509 }
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 371 of file devicestate.c.
References ast_calloc, ast_copy_string(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, devstate_prov::callback, and devstate_prov::label.
Referenced by ast_features_init(), and load_module().
00372 { 00373 struct devstate_prov *devprov; 00374 00375 if (!callback || !(devprov = ast_calloc(1, sizeof(*devprov)))) 00376 return -1; 00377 00378 devprov->callback = callback; 00379 ast_copy_string(devprov->label, label, sizeof(devprov->label)); 00380 00381 AST_RWLIST_WRLOCK(&devstate_provs); 00382 AST_RWLIST_INSERT_HEAD(&devstate_provs, devprov, list); 00383 AST_RWLIST_UNLOCK(&devstate_provs); 00384 00385 return 0; 00386 }
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 389 of file devicestate.c.
References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and devstate_prov::label.
Referenced by cc_shutdown(), features_shutdown(), and unload_module().
00390 { 00391 struct devstate_prov *devcb; 00392 int res = -1; 00393 00394 AST_RWLIST_WRLOCK(&devstate_provs); 00395 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&devstate_provs, devcb, list) { 00396 if (!strcasecmp(devcb->label, label)) { 00397 AST_RWLIST_REMOVE_CURRENT(list); 00398 ast_free(devcb); 00399 res = 0; 00400 break; 00401 } 00402 } 00403 AST_RWLIST_TRAVERSE_SAFE_END; 00404 AST_RWLIST_UNLOCK(&devstate_provs); 00405 00406 return res; 00407 }
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 239 of file devicestate.c.
Referenced by aji_devstate_cb(), and devstate_read().
00240 { 00241 return devstatestring[state][1]; 00242 }
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 244 of file devicestate.c.
References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, and AST_DEVICE_UNKNOWN.
Referenced by aji_handle_pubsub_event(), custom_devstate_callback(), devstate_write(), handle_cli_devstate_change(), and load_module().
00245 { 00246 if (!strcasecmp(val, "NOT_INUSE")) 00247 return AST_DEVICE_NOT_INUSE; 00248 else if (!strcasecmp(val, "INUSE")) 00249 return AST_DEVICE_INUSE; 00250 else if (!strcasecmp(val, "BUSY")) 00251 return AST_DEVICE_BUSY; 00252 else if (!strcasecmp(val, "INVALID")) 00253 return AST_DEVICE_INVALID; 00254 else if (!strcasecmp(val, "UNAVAILABLE")) 00255 return AST_DEVICE_UNAVAILABLE; 00256 else if (!strcasecmp(val, "RINGING")) 00257 return AST_DEVICE_RINGING; 00258 else if (!strcasecmp(val, "RINGINUSE")) 00259 return AST_DEVICE_RINGINUSE; 00260 else if (!strcasecmp(val, "ONHOLD")) 00261 return AST_DEVICE_ONHOLD; 00262 00263 return AST_DEVICE_UNKNOWN; 00264 }
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 796 of file devicestate.c.
References ast_cond_init, AST_EVENT_DEVICE_STATE_CHANGE, AST_EVENT_IE_END, ast_event_subscribe(), ast_log(), ast_mutex_init, ast_pthread_create_background, devstate_change_collector_cb(), devstate_collector, LOG_ERROR, and run_devstate_collector().
Referenced by add_publish_event(), add_subscribe_event(), and aji_init_event_distribution().
00797 { 00798 if (devstate_collector.enabled) { 00799 return 0; 00800 } 00801 00802 devstate_collector.event_sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE_CHANGE, 00803 devstate_change_collector_cb, "devicestate_engine_enable_distributed", NULL, AST_EVENT_IE_END); 00804 00805 if (!devstate_collector.event_sub) { 00806 ast_log(LOG_ERROR, "Failed to create subscription for the device state change collector\n"); 00807 return -1; 00808 } 00809 00810 ast_mutex_init(&devstate_collector.lock); 00811 ast_cond_init(&devstate_collector.cond, NULL); 00812 if (ast_pthread_create_background(&devstate_collector.thread, NULL, run_devstate_collector, NULL) < 0) { 00813 ast_log(LOG_ERROR, "Unable to start device state collector thread.\n"); 00814 return -1; 00815 } 00816 00817 devstate_collector.enabled = 1; 00818 00819 return 0; 00820 }
enum ast_device_state ast_parse_device_state | ( | const char * | device | ) |
Search the Channels by Name.
device | like a dial string |
Search the Device in active channels by compare the channel name against the device name. Compared are only the first chars to the first '-' char.
AST_DEVICE_UNKNOWN | if no channel found | |
AST_DEVICE_INUSE | if a channel is found |
Search the Channels by Name.
Definition at line 271 of file devicestate.c.
References ast_channel::_state, ast_channel_get_by_name_prefix(), AST_CHANNEL_NAME, ast_channel_unref, AST_DEVICE_INUSE, AST_DEVICE_RINGING, AST_DEVICE_UNKNOWN, AST_STATE_RINGING, and match().
Referenced by _ast_device_state(), and chanavail_exec().
00272 { 00273 struct ast_channel *chan; 00274 char match[AST_CHANNEL_NAME]; 00275 enum ast_device_state res; 00276 00277 snprintf(match, sizeof(match), "%s-", device); 00278 00279 if (!(chan = ast_channel_get_by_name_prefix(match, strlen(match)))) { 00280 return AST_DEVICE_UNKNOWN; 00281 } 00282 00283 res = (chan->_state == AST_STATE_RINGING) ? AST_DEVICE_RINGING : AST_DEVICE_INUSE; 00284 00285 chan = ast_channel_unref(chan); 00286 00287 return res; 00288 }
enum ast_device_state ast_state_chan2dev | ( | enum ast_channel_state | chanstate | ) |
Convert channel state to devicestate.
chanstate | Current channel state |
Definition at line 226 of file devicestate.c.
References AST_DEVICE_UNKNOWN.
00227 { 00228 int i; 00229 chanstate &= 0xFFFF; 00230 for (i = 0; chan2dev[i].chan != -100; i++) { 00231 if (chan2dev[i].chan == chanstate) { 00232 return chan2dev[i].dev; 00233 } 00234 } 00235 return AST_DEVICE_UNKNOWN; 00236 }
const char* devstate2str | ( | enum ast_device_state | devstate | ) |
Convert device state to text string for output.
devstate | Current device state |
Definition at line 221 of file devicestate.c.
00222 { 00223 return devstatestring[devstate][0]; 00224 }
enum ast_device_state(* ast_devstate_prov_cb_type)(const char *data) |
Devicestate provider call back.