37#if defined(HAVE_SYSINFO)
38#include <sys/sysinfo.h>
41#include <sys/loadavg.h>
229#define EXT_DATA_SIZE 256
231#define EXT_DATA_SIZE 8192
234#define SWITCH_DATA_LENGTH 256
237#define VAR_SOFTTRAN 2
238#define VAR_HARDTRAN 3
373#define HINTDEVICE_DATA_LENGTH 16
378#define HASH_EXTENHINT_SIZE 17
380#define HASH_EXTENHINT_SIZE 563
428 key =
ext->hintdevice;
447 const char *right_key = arg;
455 cmp = strcasecmp(left->
hintdevice, right_key);
462 cmp = strncmp(left->
hintdevice, right_key, strlen(right_key));
500 const char *right_key = arg;
508 cmp = strcasecmp(left->
context, right_key);
515 cmp = strncmp(left->
context, right_key, strlen(right_key));
532 if (!strcasecmp(candidate->
hintdevice, device)
533 && candidate->
hint == hint) {
580 if (!
hint || !devicelist) {
591 while ((cur =
strsep(&parse,
"&,"))) {
594 devicelength = strlen(cur);
605 "allocating a hintdevice structure");
619 ao2_t_ref(device, -1,
"hintdevice is linked so we can unref");
650static int matchcid(
const char *cidpattern,
const char *callerid);
655 struct match_char *tree,
int length,
int spec,
const char *callerid,
675 const char *application,
void *
data,
void (*
datad)(
void *),
681static unsigned int ext_strncpy(
char *dst,
const char *src,
size_t dst_size,
int nofluff);
696 const unsigned char *ac =
a;
697 const unsigned char *
bc =
b;
710 return strcmp(ac->
name,
bc->name);
717 int x = strcmp(ac->
exten,
bc->exten);
839void check_contexts_trouble(
void);
841void check_contexts_trouble(
void)
847int check_contexts(
char *,
int);
849int check_contexts(
char *
file,
int line )
875 check_contexts_trouble();
883 check_contexts_trouble();
898 char dummy_name[1024];
899 ex.exten = dummy_name;
907 "the exten %s (CID match: %s) but it is not in its root_table\n",
911 "the exten %s but it is not in its root_table\n",
914 check_contexts_trouble();
935 check_contexts_trouble();
947 for(e1 = c2->
root; e1; e1 = e1->
next) {
949 for(e2=e1;e2;e2=e2->
peer) {
953 check_contexts_trouble();
958 check_contexts_trouble();
963 check_contexts_trouble();
968 check_contexts_trouble();
975 check_contexts_trouble();
987 for(e3=e1;e3;e3=e3->
peer) {
995 check_contexts_trouble();
1095#ifdef NEED_DEBUG_HERE
1109 snprintf(extenstr,
sizeof(extenstr),
"(%p)",
node->exten);
1111 if (strlen(
node->x) > 1) {
1113 node->deleted?
'D':
'-',
node->specificity,
node->exten?
"EXTEN:":
"",
1114 node->exten ?
node->exten->exten :
"", extenstr);
1117 node->deleted?
'D':
'-',
node->specificity,
node->exten?
"EXTEN:":
"",
1118 node->exten ?
node->exten->exten :
"", extenstr);
1123 if (
node->next_char)
1139 snprintf(extenstr,
sizeof(extenstr),
"(%p)",
node->exten);
1142 if (strlen(
node->x) > 1) {
1144 node->deleted ?
'D' :
'-',
node->specificity,
node->exten?
"EXTEN:" :
"",
1145 node->exten ?
node->exten->name :
"", extenstr);
1148 node->deleted ?
'D' :
'-',
node->specificity,
node->exten?
"EXTEN:" :
"",
1149 node->exten ?
node->exten->name :
"", extenstr);
1154 if (
node->next_char)
1168#ifdef NEED_DEBUG_HERE
1171 return node2->
exten;
1174#ifdef NEED_DEBUG_HERE
1198 m3 =
node->next_char;
1208 for (m4 = m3; m4; m4 = m4->
alt_char) {
1242 while (*
str ==
'-') {
1248#define MORE(s) (*candidate_exten_advance(s))
1249#define ADVANCE(s) candidate_exten_advance(s)
1257 ast_log(
LOG_NOTICE,
"new_find_extension called with %s on (sub)tree %s action=%s\n",
str, tree->
x, action2str(action));
1259 ast_log(
LOG_NOTICE,
"new_find_extension called with %s on (sub)tree NULL action=%s\n",
str, action2str(action));
1261 for (p = tree; p; p = p->
alt_char) {
1263 if (p->
x[0] ==
'N') {
1264 if (p->
x[1] == 0 && *
str >=
'2' && *
str <=
'9' ) {
1265#define NEW_MATCHER_CHK_MATCH \
1266 if (p->exten && !MORE(str)) { \
1267 if (action == E_MATCH || action == E_SPAWN || action == E_FINDLABEL) { \
1268 update_scoreboard(score, length + 1, spec + p->specificity, p->exten, 0, callerid, p->deleted, p); \
1269 if (!p->deleted) { \
1270 if (action == E_FINDLABEL) { \
1271 if (ast_hashtab_lookup(score->exten->peer_label_table, &pattern)) { \
1272 ast_debug(4, "Found label in preferred extension\n"); \
1276 ast_debug(4, "returning an exact match-- first found-- %s\n", p->exten->name); \
1283#define NEW_MATCHER_RECURSE \
1284 if (p->next_char && (MORE(str) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0) \
1285 || p->next_char->x[0] == '!')) { \
1286 if (MORE(str) || p->next_char->x[0] == '!') { \
1287 new_find_extension(ADVANCE(str), score, p->next_char, length + 1, spec + p->specificity, callerid, label, action); \
1288 if (score->exten) { \
1289 ast_debug(4 ,"returning an exact match-- %s\n", score->exten->name); \
1293 new_find_extension("/", score, p->next_char, length + 1, spec + p->specificity, callerid, label, action); \
1294 if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) { \
1295 ast_debug(4,"returning a (can/more) match--- %s\n", score->exten ? score->exten->name : \
1300 } else if ((p->next_char || action == E_CANMATCH) && !MORE(str)) { \
1301 score->canmatch = 1; \
1302 score->canmatch_exten = get_canmatch_exten(p); \
1303 if (action == E_CANMATCH || action == E_MATCHMORE) { \
1304 ast_debug(4, "returning a canmatch/matchmore--- str=%s\n", str); \
1312 }
else if (p->
x[0] ==
'Z') {
1313 if (p->
x[1] == 0 && *
str >=
'1' && *
str <=
'9' ) {
1317 }
else if (p->
x[0] ==
'X') {
1318 if (p->
x[1] == 0 && *
str >=
'0' && *
str <=
'9' ) {
1322 }
else if (p->
x[0] ==
'.' && p->
x[1] == 0) {
1325 const char *str2 =
str;
1326 while (*str2 && *str2 !=
'/') {
1330 if (p->
exten && *str2 !=
'/') {
1333 ast_debug(4,
"return because scoreboard has a match with '/'--- %s\n",
1341 ast_debug(4,
"return because scoreboard has exact match OR "
1342 "CANMATCH/MATCHMORE & canmatch set--- %s\n",
1347 }
else if (p->
x[0] ==
'!' && p->
x[1] == 0) {
1350 const char *str2 =
str;
1351 while (*str2 && *str2 !=
'/') {
1355 if (p->
exten && *str2 !=
'/') {
1358 ast_debug(4,
"return because scoreboard has a '!' match--- %s\n",
1366 ast_debug(4,
"return because scoreboard has exact match OR "
1367 "CANMATCH/MATCHMORE & canmatch set with '/' and '!'--- %s\n",
1372 }
else if (p->
x[0] ==
'/' && p->
x[1] == 0) {
1374 if (p->
next_char && callerid && *callerid) {
1377 ast_debug(4,
"return because scoreboard has exact match OR "
1378 "CANMATCH/MATCHMORE & canmatch set with '/'--- %s\n",
1383 }
else if (strchr(p->
x, *
str)) {
1384 ast_debug(4,
"Nothing strange about this match\n");
1388 }
else if (strchr(p->
x, *
str)) {
1389 ast_debug(4,
"Nothing strange about this match\n");
1394 ast_debug(4,
"return at end of func\n");
1444 if (!(*parent_ptr)) {
1449 if ((*parent_ptr)->specificity >
node->specificity) {
1451 node->alt_char = (*parent_ptr);
1456 lcurr = *parent_ptr;
1459 node->alt_char = curr;
1483 if (!(m =
ast_calloc(1,
sizeof(*m) + strlen(pattern->
buf)))) {
1490 strcpy(m->
x, pattern->
buf);
1535#define INC_DST_OVERFLOW_CHECK \
1537 if (dst - node->buf < sizeof(node->buf) - 1) { \
1545 node->buf[0] =
'\0';
1547 if (*src ==
'[' && pattern) {
1548 char *dst =
node->buf;
1549 const char *src_next;
1559 if (*src ==
'[' || *src ==
'\\' || *src ==
'-' || *src ==
']') {
1563 }
else if (*src ==
'-') {
1564 unsigned char first;
1568 first = *(src_next - 1);
1592 }
else if (*src ==
'\0') {
1594 "A matching ']' was not found for '[' in exten pattern '%s'\n",
1597 }
else if (*src ==
']') {
1610 "Expanded character set too large to deal with in exten pattern '%s'. Ignoring character set.\n",
1612 node->buf[0] =
'\0';
1617 length = strlen(
node->buf);
1621 node->buf[0] =
'\0';
1628 src_next =
node->buf;
1629 while (*src_next++) {
1630 if (*dst != *src_next) {
1635 length = strlen(
node->buf);
1637 node->specif = length | (
unsigned char)
node->buf[0];
1639 }
else if (*src ==
'-') {
1649 node->buf[0] = *++src;
1650 if (!
node->buf[0]) {
1654 node->buf[0] = *src;
1657 if (
node->buf[0] ==
'n') {
1659 }
else if (
node->buf[0] ==
'x') {
1661 }
else if (
node->buf[0] ==
'z') {
1666 node->buf[1] =
'\0';
1674#undef INC_DST_OVERFLOW_CHECK
1677#define MAX_EXTENBUF_SIZE 512
1689 volatile size_t required_space = strlen(e1->
exten) + 1;
1693 required_space += (strlen(e1->
cidmatch) + 2 );
1696 "The pattern %s/%s is too big to deal with: it will be ignored! Disaster!\n",
1704 "The pattern %s/%s is too big to deal with: it will be ignored! Disaster!\n",
1712 ast_debug(1,
"Adding exten %s to tree\n", extenbuf);
1725 for (; pat_node[idx_cur].
buf[0]; idx_cur = idx_next) {
1726 idx_next = (idx_cur + 1) %
ARRAY_LEN(pat_node);
1733 if (!pat_node[idx_next].
buf[0]) {
1767 if (!pat_node[idx_next].
buf[0]) {
1768 if (m2 && m2->
exten) {
1790 int biggest_bucket, resizes, numobjs, numbucks;
1792 ast_debug(1,
"Creating Extension Trie for context %s(%p)\n", con->
name, con);
1794 ast_debug(1,
"This tree has %d objects in %d bucket lists, longest list=%d objects, and has resized %d times\n",
1795 numobjs, numbucks, biggest_bucket, resizes);
1802 ast_log(
LOG_ERROR,
"Attempt to create extension with no extension name.\n");
1820 pattern_tree->
exten = 0;
1839 while (*
str ==
'-') {
1868 while (*left ==
'-') {
1871 while (*right ==
'-') {
1884 cmp = *left - *right;
1911 while (*left ==
'-') {
1914 while (*right ==
'-') {
1918 cmp = *left - *right;
2018 return 0x0800 |
'2';
2025 return 0x0A00 |
'0';
2032 return 0x0900 |
'1';
2052 end = strchr(*p,
']');
2061 for (; *p <
end; ++*p) {
2066 if (*p + 2 <
end && (*p)[1] ==
'-') {
2075 for (; c1 <= c2; ++c1) {
2084 if (!(bitwise[c1 /
BITS_PER] & mask)) {
2093 return count | cmin;
2114 unsigned char left_bitwise[32] = { 0, };
2115 unsigned char right_bitwise[32] = { 0, };
2119 cmp = left_pos - right_pos;
2128 cmp = memcmp(right_bitwise, left_bitwise,
ARRAY_LEN(left_bitwise));
2155static int ext_cmp(
const char *left,
const char *right)
2158 if (left[0] !=
'_') {
2159 if (right[0] ==
'_') {
2165 if (right[0] !=
'_') {
2181 if (*
exten !=
'_') {
2184 if (*
exten ==
'-') {
2195 if (*
exten ==
'-') {
2197 }
else if (*
exten ==
'[') {
2242#ifdef NEED_DEBUG_HERE
2246 if (pattern[0] !=
'_') {
2251#ifdef NEED_DEBUG_HERE
2258#ifdef NEED_DEBUG_HERE
2264#ifdef NEED_DEBUG_HERE
2265 ast_log(
LOG_NOTICE,
"return (mode(%d) == E_MATCHMORE ? lp(%d) > ld(%d) : 1)\n", mode, lp, ld);
2269#ifdef NEED_DEBUG_HERE
2285#ifdef NEED_DEBUG_HERE
2289#ifdef NEED_DEBUG_HERE
2305 while (*
data ==
'-') {
2308 while (*pattern ==
'-') {
2311 if (!*
data || !*pattern || *pattern ==
'/') {
2318 end = strchr(pattern,
']');
2323 if (pattern ==
end) {
2328 for (; pattern <
end; ++pattern) {
2329 if (pattern+2 <
end && pattern[1] ==
'-') {
2330 if (*
data >= pattern[0] && *
data <= pattern[2])
2336 }
else if (*
data == pattern[0])
2339 if (pattern >=
end) {
2340#ifdef NEED_DEBUG_HERE
2349 if (*data < '2' || *data >
'9') {
2350#ifdef NEED_DEBUG_HERE
2358 if (*data < '0' || *data >
'9') {
2359#ifdef NEED_DEBUG_HERE
2367 if (*data < '1' || *data >
'9') {
2368#ifdef NEED_DEBUG_HERE
2375#ifdef NEED_DEBUG_HERE
2380#ifdef NEED_DEBUG_HERE
2385 if (*
data != *pattern) {
2386#ifdef NEED_DEBUG_HERE
2397#ifdef NEED_DEBUG_HERE
2407 if (*pattern ==
'\0' || *pattern ==
'/') {
2408#ifdef NEED_DEBUG_HERE
2412 }
else if (*pattern ==
'!') {
2413#ifdef NEED_DEBUG_HERE
2418#ifdef NEED_DEBUG_HERE
2421 return (mode ==
E_MATCH) ? 0 : 1;
2432 static int prof_id = -2;
2433 if (prof_id == -2) {
2470 if (!strcasecmp(
name, tmp->
name)) {
2479#define STATUS_NO_CONTEXT 1
2480#define STATUS_NO_EXTENSION 2
2481#define STATUS_NO_PRIORITY 3
2482#define STATUS_NO_LABEL 4
2483#define STATUS_SUCCESS 5
2485static int matchcid(
const char *cidpattern,
const char *callerid)
2510 pattern.
label = label;
2512#ifdef NEED_DEBUG_HERE
2528 for (x = 0; x < q->
stacklen; x++) {
2579 if (osw && strchr(osw,
'$')) {
2624 eroot = score.
exten;
2630#ifdef NEED_DEBUG_HERE
2638#ifdef NEED_DEBUG_HERE
2648#ifdef NEED_DEBUG_HERE
2653#ifdef NEED_DEBUG_HERE
2658#ifdef NEED_DEBUG_HERE
2665#ifdef NEED_DEBUG_HERE
2686#ifdef NEED_DEBUG_HERE
2700 if (!
match || (eroot->matchcid && !
matchcid(eroot->cidmatch, callerid)))
2786#ifdef NEED_DEBUG_HERE
2806 .
type =
"EXCEPTION",
2834 ds->
data = exception;
2837 exception = ds->
data;
2851 if (!ds || !ds->
data)
2853 exception = ds->
data;
2854 if (!strcasecmp(data,
"REASON"))
2856 else if (!strcasecmp(data,
"CONTEXT"))
2858 else if (!strncasecmp(data,
"EXTEN", 5))
2860 else if (!strcasecmp(data,
"PRIORITY"))
2868 .
name =
"EXCEPTION",
2892 const char *label,
const char *callerid,
enum ext_match_t action,
int *found,
int combined_find_spawn)
2896 char *substitute =
NULL;
2914 if (matching_action) {
2932 if ((!(tmp = strchr(e->
data,
'$'))) || (!strstr(tmp,
"${") && !strstr(tmp,
"$["))) {
2968 if (matching_action) {
2982 if (!matching_action && !combined_find_spawn)
2986 if (!matching_action && !combined_find_spawn)
2990 if (!matching_action && !combined_find_spawn)
2994 if (
context && !combined_find_spawn)
3001 return (matching_action) ? 0 : -1;
3057 if ((tmp = strrchr(
copy,
','))) {
3076 if ((tmp = strrchr(
copy,
','))) {
3106 while ((cur =
strsep(&rest,
"&"))) {
3110 if (device_state_info) {
3132 if (!e || !hint_app) {
3165 if (e->
exten[0] ==
'_') {
3197 if (device_state_info) {
3207 if (device_state_info) {
3218 char *presence_provider;
3221 if (!e || !hint_app) {
3249 if (e->
exten[0] ==
'_') {
3287 info.presence_subtype =
"";
3292 info.presence_message =
"";
3325 struct timeval chantime = {0, };
3327 switch (
info->device_state) {
3364 info->causing_channel = chan;
3368 if (!
info->causing_channel) {
3371 info->causing_channel = chan;
3376 info->causing_channel = chan;
3392 int first_extended_cb_call = 1;
3459 if (state_cb->
extended && first_extended_cb_call) {
3461 first_extended_cb_call = 0;
3464 if (state_cb->
extended || !same_state) {
3573 char *presence_subtype =
NULL;
3574 char *presence_message =
NULL;
3578 hint->
exten, &presence_subtype, &presence_message);
3582 .subtype = presence_subtype,
3583 .message = presence_message
3608 char *virtual_device;
3645 if (dev_state->
eid) {
3670 "find devices in container");
3689 virtual_device = strchr(
type,
':');
3690 device_name = strchr(
type,
'/');
3691 if (virtual_device && (!device_name || (virtual_device < device_name))) {
3692 device_name = virtual_device;
3700 *device_name++ =
'\0';
3788 if (e->
exten[0] ==
'_') {
3795 if (!e || e->
exten[0] ==
'_') {
3817 }
while (
id == -1 ||
id == 0);
3939 if (!hint_remove_message_type()) {
3998 char *subtype =
NULL;
4022 hint_new->
exten = e;
4023 if (strstr(e->
app,
"${") && e->
exten[0] ==
'_') {
4045 ast_debug(2,
"HINTS: Not re-adding existing hint %s: %s\n",
4051 ast_debug(2,
"HINTS: Adding hint %s: %s\n",
4061 if (!(strstr(e->
app,
"${") && e->
exten[0] ==
'_')) {
4089 if (!hint_change_message_type()) {
4260 if (found && spawn_error) {
4262 ast_debug(1,
"Spawn extension (%s,%s,%d) exited non-zero on '%s'\n",
4265 ast_verb(2,
"Spawn extension (%s, %s, %d) exited non-zero on '%s'\n",
4311 if (pos < buflen - 1) {
4381 char dst_exten[256];
4388 dst_exten[pos] =
'\0';
4426 ast_debug(1,
"Extension %s, priority %d returned normally even though call was hung up\n",
4433 if (strchr(
"0123456789ABCDEF*#", res)) {
4434 ast_debug(1,
"Oooh, got something to jump out with ('%c')!\n", res);
4436 dst_exten[pos++] =
digit = res;
4437 dst_exten[pos] =
'\0';
4449 pos = strlen(dst_exten);
4513 ast_verb(3,
"Channel '%s' sent to invalid extension: context,exten,priority=%s,%s,%d\n",
4521 ast_log(
LOG_WARNING,
"Channel '%s' sent to invalid extension but no invalid handler: context,exten,priority=%s,%s,%d\n",
4540 if (!strcasecmp(
status,
"CONGESTION"))
4542 else if (!strcasecmp(
status,
"CHANUNAVAIL"))
4544 else if (!strcasecmp(
status,
"BUSY"))
4572 "Invalid extension '%s', but no rule 'i' or 'e' in context '%s'\n",
4588 "Timeout, but no rule 't' or 'e' in context '%s'\n",
4598 if (!found && !
error) {
4602 if (!
args || !
args->no_hangup_chan) {
4620 if (!
args || !
args->no_hangup_chan) {
4636#if defined(HAVE_SYSINFO)
4637 struct sysinfo sys_info;
4654#if defined(HAVE_SYSINFO)
4657 if (!sysinfo(&sys_info)) {
4660 uint64_t curfreemem = sys_info.freeram + sys_info.bufferram;
4661 curfreemem *= sys_info.mem_unit;
4662 curfreemem /= 1024 * 1024;
4664 ast_log(
LOG_WARNING,
"Available system memory (~%" PRIu64
"MB) is below the configured low watermark (%ldMB)\n",
5003 char dummy_name[1024];
5004 char dummy_cid[1024];
5009 if (!already_locked)
5016 check_contexts(__FILE__, __LINE__);
5019 ex.
exten = dummy_name;
5024 ext_strncpy(dummy_cid, callerid,
sizeof(dummy_cid), 1);
5041 ast_log(
LOG_WARNING,
"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n");
5048 if (exten2->
label) {
5052 "from the peer_label_table of context %s, extension %s!\n",
5060 "peer_table of context %s, extension %s!\n",
5073 "context root_table (%s) (priority %d)\n",
5085 ast_debug(3,
"Could not find priority %d of exten %s in context %s!\n",
5112 if (!already_locked)
5121 peer = next_peer, next_peer = next_peer ? (next_peer->
peer ? next_peer->
peer : next_peer->
next) :
NULL) {
5128 if (!previous_peer) {
5143 con->
root = next_node;
5145 prev_exten->
next = next_node;
5158 previous_peer =
peer;
5161 if (!already_locked)
5163 return found ? 0 : -1;
5181 e->
command =
"core show hints";
5183 "Usage: core show hints\n"
5184 " List registered hints.\n"
5185 " Hint details are shown in five columns. In order from left to right, they are:\n"
5186 " 1. Hint extension URI.\n"
5187 " 2. List of mapped device or presence state identifiers.\n"
5188 " 3. Current extension state. The aggregate of mapped device states.\n"
5189 " 4. Current presence state for the mapped presence state provider.\n"
5190 " 5. Watchers - number of subscriptions and other entities watching this hint.\n";
5197 ast_cli(
a->fd,
"There are no registered dialplan hints\n");
5201 ast_cli(
a->fd,
"\n -= Registered Asterisk Dial Plan Hints =-\n");
5212 snprintf(
buf,
sizeof(
buf),
"%s@%s",
5216 ast_cli(
a->fd,
"%-30.30s: %-60.60s State:%-15.15s Presence:%-15.15s Watchers %2d\n",
5228 ast_cli(
a->fd,
"----------------\n");
5229 ast_cli(
a->fd,
"- %d hints registered\n", num);
5245 wordlen = strlen(
word);
5274 int num = 0, extenlen;
5280 e->
command =
"core show hint";
5282 "Usage: core show hint <exten>\n"
5283 " List registered hint.\n"
5284 " Hint details are shown in five columns. In order from left to right, they are:\n"
5285 " 1. Hint extension URI.\n"
5286 " 2. List of mapped device or presence state identifiers.\n"
5287 " 3. Current extension state. The aggregate of mapped device states.\n"
5288 " 4. Current presence state for the mapped presence state provider.\n"
5289 " 5. Watchers - number of subscriptions and other entities watching this hint.\n";
5299 ast_cli(
a->fd,
"There are no registered dialplan hints\n");
5303 extenlen = strlen(
a->argv[3]);
5314 sprintf(
buf,
"%s@%s",
5317 ast_cli(
a->fd,
"%-30.30s: %-60.60s State:%-15.15s Presence:%-15.15s Watchers %2d\n",
5329 ast_cli(
a->fd,
"No hints matching extension %s\n",
a->argv[3]);
5331 ast_cli(
a->fd,
"%d hint%s matching extension %s\n", num, (num!=1 ?
"s":
""),
a->argv[3]);
5355 const int blocks_max = 50000;
5356 long long int allocated = 0;
5369 e->
command =
"core eat memory";
5371 "Usage: core eat memory\n"
5372 " Eats all available memory so you can test if the system survives\n";
5378 blocks =
ast_malloc(
sizeof(
void*) * blocks_max);
5384 for (i = 0; sizes[i]; ++i) {
5385 int alloc_size = sizes[i];
5386 ast_log(
LOG_WARNING,
"Allocating %d sized blocks (got %d blocks already)\n", alloc_size, blocks_pos);
5389 if (blocks_pos >= blocks_max) {
5399 blocks[blocks_pos++] = block;
5400 allocated += alloc_size;
5427 wordlen = strlen(
word);
5457 snprintf(
buf, buflen,
"hint: %s",
5460 snprintf(
buf, buflen,
"%d. %s(%s)",
5470 ast_cli(fd,
" %-17s %-45s [%s:%d]\n",
5477 ast_cli(fd,
" %-17s %-45s [%s]\n",
5498 int context_info_printed = 0;
5515 ast_cli(fd,
"[ Context '%s' created by '%s' ]\n",
5518 ast_cli(fd,
"Autohints support enabled\n");
5520 context_info_printed = 1;
5534 if (!context_info_printed) {
5537 ast_cli(fd,
"[ Included context '%s' created by '%s' ]\n",
5540 ast_cli(fd,
"[ Context '%s' created by '%s' ]\n",
5543 ast_cli(fd,
"Autohints support enabled\n");
5546 context_info_printed = 1;
5567 snprintf(
buf,
sizeof(
buf),
" [%s]",
el);
5588 for (x = 0; x < includecount; x++) {
5602 ast_cli(fd,
" Include => %-45s [%s]\n",
5613 snprintf(
buf,
sizeof(
buf),
"'%s'", ipname);
5614 snprintf(ignorepat,
sizeof(ignorepat),
"_%s.", ipname);
5616 ast_cli(fd,
" Ignore pattern => %-45s [%s]\n",
5624 snprintf(
buf,
sizeof(
buf),
"'%s/%s'",
5627 ast_cli(fd,
" Alt. Switch => %-45s [%s]\n",
5635 if (context_info_printed)
5640 return (dpc->
total_exten == old_total_exten) ? -1 : res;
5648 ast_cli(fd,
"\n In-mem exten Trie for Fast Extension Pattern Matching:\n\n");
5650 ast_cli(fd,
"\n Explanation: Node Contents Format = <char(s) to match>:<pattern?>:<specif>:[matched extension]\n");
5651 ast_cli(fd,
" Where <char(s) to match> is a set of chars, any one of which should match the current character\n");
5652 ast_cli(fd,
" <pattern?>: Y if this a pattern match (eg. _XZN[5-7]), N otherwise\n");
5653 ast_cli(fd,
" <specif>: an assigned 'exactness' number for this matching char. The lower the number, the more exact the match\n");
5654 ast_cli(fd,
" [matched exten]: If all chars matched to this point, which extension this matches. In form: EXTEN:<exten string>\n");
5655 ast_cli(fd,
" In general, you match a trie node to a string character, from left to right. All possible matching chars\n");
5656 ast_cli(fd,
" are in a string vertically, separated by an unbroken string of '+' characters.\n\n");
5661 int context_info_printed = 0;
5668 if (!
c->pattern_tree) {
5676 ast_cli(fd,
"[ Context '%s' created by '%s' ]\n",
5678 context_info_printed = 1;
5680 if (
c->pattern_tree)
5684 ast_cli(fd,
"\n No Pattern Trie present. Perhaps the context is empty...or there is trouble...\n\n");
5690 if (context_info_printed)
5695 return (dpc->
total_exten == old_total_exten) ? -1 : res;
5709 "Usage: dialplan show [[exten@]context]\n"
5716 memset(&counters, 0,
sizeof(counters));
5718 if (
a->argc != 2 &&
a->argc != 3)
5723 if (strchr(
a->argv[2],
'@')) {
5746 ast_cli(
a->fd,
"There is no existence of %s@%s extension\n",
5750 "There is no existence of '%s' extension in all contexts\n",
5755 ast_cli(
a->fd,
"-= %d %s (%d %s) in %d %s. =-\n",
5774 e->
command =
"dialplan debug";
5776 "Usage: dialplan debug [context]\n"
5777 " Show dialplan context Trie(s). Usually only useful to folks debugging the deep internals of the fast pattern matcher\n";
5783 memset(&counters, 0,
sizeof(counters));
5785 if (
a->argc != 2 &&
a->argc != 3)
5791 if (strchr(
a->argv[2],
'@')) {
5831 const char *actionidtext,
const char *
context,
5834 int includecount,
const char *includes[])
5844 ast_debug(3,
"manager_show_dialplan: Context: -%s- Extension: -%s-\n",
context, exten);
5867 ast_debug(3,
"manager_show_dialplan: Failed to lock context\n");
5895 astman_append(s,
"Event: ListDialplan\r\n%s", actionidtext);
5921 for (x = 0; x < includecount; x++) {
5937 astman_append(s,
"Event: ListDialplan\r\n%s", actionidtext);
5949 snprintf(ignorepat,
sizeof(ignorepat),
"_%s.", ipname);
5953 astman_append(s,
"Event: ListDialplan\r\n%s", actionidtext);
5964 astman_append(s,
"Event: ListDialplan\r\n%s", actionidtext);
5976 ast_debug(3,
"manager_show_dialplan: Found nothing new\n");
5996 snprintf(idtext,
sizeof(idtext),
"ActionID: %s\r\n",
id);
6000 memset(&counters, 0,
sizeof(counters));
6008 char errorbuf[BUFSIZ];
6010 snprintf(errorbuf,
sizeof(errorbuf),
"Did not find context %s",
context);
6015 char errorbuf[BUFSIZ];
6018 snprintf(errorbuf,
sizeof(errorbuf),
"Did not find extension %s@%s", exten,
context);
6020 snprintf(errorbuf,
sizeof(errorbuf),
"Did not find extension %s in any context", exten);
6031 "ListExtensions: %d\r\n"
6032 "ListPriorities: %d\r\n"
6033 "ListContexts: %d\r\n",
6045 int i, j, exten, combined;
6049 e->
command =
"core show device2extenstate";
6051 "Usage: core show device2extenstate\n"
6052 " Lists device state to extension state combinations.\n";
6077 e->
command =
"dialplan set extenpatternmatchnew true";
6079 "Usage: dialplan set extenpatternmatchnew true|false\n"
6080 " Use the NEW extension pattern matching algorithm, true or false.\n";
6092 ast_cli(
a->fd,
"\n -- Still using the NEW pattern match algorithm for extension names in the dialplan.\n");
6094 ast_cli(
a->fd,
"\n -- Switched to using the NEW pattern match algorithm for extension names in the dialplan.\n");
6105 e->
command =
"dialplan set extenpatternmatchnew false";
6107 "Usage: dialplan set extenpatternmatchnew true|false\n"
6108 " Use the NEW extension pattern matching algorithm, true or false.\n";
6120 ast_cli(
a->fd,
"\n -- Still using the OLD pattern match algorithm for extension names in the dialplan.\n");
6122 ast_cli(
a->fd,
"\n -- Switched to using the OLD pattern match algorithm for extension names in the dialplan.\n");
6137 AST_CLI_DEFINE(handle_show_device2extenstate,
"Show expected exten state from multiple device states"),
6154 if (e->cached_app ==
app)
6155 e->cached_app =
NULL;
6170 size_t name_bytes = strlen(
name);
6171 size_t registrar_bytes = strlen(
registrar);
6172 int length =
sizeof(
struct ast_context) + name_bytes + registrar_bytes + 2;
6315 size_t name_len = strlen(con->
name) + 1;
6316 size_t registrar_len = strlen(con->
registrar) + 1;
6335 ast_verb(3,
"Enabled autohints support on context '%s'\n", con->
name);
6345 struct ast_exten *exten_item, *prio_item, *new_exten_item, *new_prio_item;
6348 int insert_count = 0;
6362 new_exten_item =
NULL;
6369 if (new_exten_item) {
6372 new_prio_item =
NULL;
6381 new->autohints =
context->autohints;
6405 if (!res1 && new_exten_item && new_prio_item){
6406 ast_verb(3,
"Dropping old dialplan item %s/%s/%d [%s(%s)] (registrar=%s) due to conflict with new dialplan\n",
6424 if (!insert_count && !
new && (strcmp(
context->registrar,
registrar) != 0 ||
6431 new->autohints =
context->autohints;
6457 struct timeval begintime;
6458 struct timeval writelocktime;
6459 struct timeval endlocktime;
6460 struct timeval enddeltime;
6515 +
sizeof(*saved_hint);
6530 saved_hint->laststate = hint->
laststate;
6531 saved_hint->context = saved_hint->data;
6533 saved_hint->exten = saved_hint->data + strlen(saved_hint->context) + 1;
6570 if (exten && exten->
exten[0] ==
'_') {
6647 for (tmp = oldcontextslist; tmp; ) {
6658 ast_verb(5,
"Time to scan old dialplan and merge leftovers back into the new: %8.6f sec\n", ft);
6662 ast_verb(5,
"Time to restore hints and swap in new dialplan: %8.6f sec\n", ft);
6666 ast_verb(5,
"Time to delete the old dialplan: %8.6f sec\n", ft);
6670 ast_verb(5,
"Total time merge_contexts_delete: %8.6f sec\n", ft);
6671 ast_verb(5,
"%s successfully loaded %d contexts (enable debug for details).\n",
registrar, ctx_count);
6731 ast_debug(1,
"Including context '%s' in context '%s'\n",
6798 ast_verb(3,
"Including switch '%s/%s' in context '%s'\n",
6924 int priority,
const char *label,
const char *callerid,
6925 const char *application,
void *data,
void (*datad)(
void *),
const char *
registrar)
6944 int priority,
const char *label,
const char *callerid,
6945 const char *application,
void *
data,
void (*datad)(
void *),
const char *
registrar)
7041static unsigned int ext_strncpy(
char *dst,
const char *src,
size_t dst_size,
int nofluff)
7044 unsigned int insquares;
7045 unsigned int is_pattern;
7054 is_pattern = *src ==
'_';
7055 while (*src && count < dst_size) {
7060 }
else if (*src ==
']') {
7062 }
else if (*src ==
' ' && !insquares) {
7065 }
else if (*src ==
'-' && !insquares && nofluff) {
7087 int repeated_label = 0;
7089 for (ep =
NULL; e ; ep = e, e = e->
peer) {
7093 "Extension '%s' priority %d in '%s', label '%s' already in use at aliased extension '%s' priority %d\n",
7097 "Extension '%s' priority %d in '%s', label '%s' already in use at priority %d\n",
7107 if (repeated_label) {
7126 "Unable to register extension '%s' priority %d in '%s', already in use by aliased extension '%s'\n",
7130 "Unable to register extension '%s' priority %d in '%s', already in use\n",
7176 ast_log(
LOG_ERROR,
"Trying to delete an exten from a context, but the pattern tree node returned isn't an extension\n");
7203 ast_log(
LOG_ERROR,
"Trying to delete an exten from a context, but the pattern tree node returned isn't an extension\n");
7274 const char *application,
void *data,
void (*datad)(
void *),
7275 const char *
registrar,
const char *registrar_file,
int registrar_line)
7278 application, data, datad,
registrar, registrar_file, registrar_line, 1);
7283 const char *application,
void *data,
void (*datad)(
void *),
7284 const char *
registrar,
const char *registrar_file,
int registrar_line)
7287 application, data, datad,
registrar, registrar_file, registrar_line, 0);
7300 const char *application,
void *data,
void (*datad)(
void *),
7301 const char *
registrar,
const char *registrar_file,
int registrar_line,
int lock_context)
7315 char dummy_name[1024];
7320 ast_log(
LOG_ERROR,
"You have to be kidding-- add exten '' to context %s? Figure out a name and call me back. Action ignored.\n",
7346 if (0 < inhibited) {
7350 application = expand_buf;
7369 length += strlen(
extension) + 1 - exten_fluff;
7371 length += strlen(application) + 1;
7373 length += strlen(
label) + 1;
7376 length += strlen(callerid) + 1;
7377 if (callerid_fluff) {
7378 length += strlen(callerid) + 1 - callerid_fluff;
7405 p += strlen(
label) + 1;
7421 p +=
ext_strncpy(p, callerid, strlen(callerid) + 1, 0);
7422 if (callerid_fluff) {
7424 p +=
ext_strncpy(p, callerid, strlen(callerid) + 1 - callerid_fluff, 1);
7441 strcpy(p, application);
7455 dummy_exten.
exten = dummy_name;
7466 for (e = con->
root; e;
el = e, e = e->
next) {
7481 if (e && res == 0) {
7557 ast_log(
LOG_DEBUG,
"Added extension '%s' priority %d (CID match '%s') to %s (%p)\n",
7615 if (
outgoing->in_separate_thread) {
7682 ast_verb(4,
"Treating progress as answer on '%s' due to early media option\n",
7737 const char *
app,
const char *appdata,
int *reason,
int synchronous,
7738 const char *cid_num,
const char *cid_name,
struct ast_variable *vars,
7739 const char *account,
struct ast_channel **locked_channel,
int early_media,
7745 char tmp_cid_name[128];
7746 char tmp_cid_num[128];
7779 if (synchronous && reason) {
7797 ast_channel_accountcode_set(
dialed, account);
7798 ast_channel_peeraccount_set(
dialed, account);
7813 cid_num = tmp_cid_num;
7818 cid_name = tmp_cid_name;
7839 connected.id.number.str = (
char *) cid_num;
7844 connected.id.name.str = (
char *) cid_name;
7854 if (locked_channel) {
7887 if (locked_channel) {
7915 if (locked_channel) {
7920 if (locked_channel) {
7925 if (locked_channel) {
7926 *locked_channel = dialed;
7932 int timeout,
const char *
context,
const char *exten,
int priority,
int *reason,
7933 int synchronous,
const char *cid_num,
const char *cid_name,
struct ast_variable *vars,
7934 const char *account,
struct ast_channel **locked_channel,
int early_media,
7938 synchronous, cid_num, cid_name, vars, account, locked_channel, early_media, assignedids,
NULL);
7942 int timeout,
const char *
context,
const char *exten,
int priority,
int *reason,
7943 int synchronous,
const char *cid_num,
const char *cid_name,
struct ast_variable *vars,
7944 const char *account,
struct ast_channel **locked_channel,
int early_media,
7951 reason = &my_reason;
7954 if (locked_channel) {
7955 *locked_channel =
NULL;
7959 NULL,
NULL, reason, synchronous, cid_num, cid_name, vars, account, locked_channel,
7960 early_media, assignedids, predial_callee);
7968 ast_assert(!locked_channel || !*locked_channel);
7977 char failed_reason[12];
7980 snprintf(failed_reason,
sizeof(failed_reason),
"%d", *reason);
7996 int timeout,
const char *
app,
const char *appdata,
int *reason,
int synchronous,
7997 const char *cid_num,
const char *cid_name,
struct ast_variable *vars,
7998 const char *account,
struct ast_channel **locked_channel,
8002 cid_num, cid_name, vars, account, locked_channel, assignedids,
NULL);
8006 int timeout,
const char *
app,
const char *appdata,
int *reason,
int synchronous,
8007 const char *cid_num,
const char *cid_name,
struct ast_variable *vars,
8008 const char *account,
struct ast_channel **locked_channel,
8014 if (locked_channel) {
8015 *locked_channel =
NULL;
8022 reason, synchronous, cid_num, cid_name, vars, account, locked_channel, 0,
8023 assignedids, predial_callee);
8055 for (e = tmp->
root; e;) {
8056 for (en = e->
peer; en;) {
8074 struct ast_exten *exten_item, *prio_item;
8076 for (tmp = list; tmp; ) {
8084 for (; tmp; tmpl = tmp, tmp = tmp->
next) {
8085 ast_debug(1,
"check ctx %s %s\n", tmp->name, tmp->registrar);
8086 if ( !strcasecmp(tmp->name, con->
name) ) {
8133 int end_traversal = 1;
8151 ast_verb(5,
"Remove %s/%s/%d, registrar=%s; con=%s(%p); con->root=%p\n",
8167 if (end_traversal) {
8253 waittime = waitsec * 1000.0;
8272 char *remainder,
result[30], timezone[80];
8284 sscanf(remainder,
"%79s", timezone);
8287 snprintf(
result,
sizeof(
result),
"%ld", (
long) tv.tv_sec);
8302 }
else if (sscanf(condition,
"%30d", &res) == 1) {
8333 cmpdevice =
ast_alloca(
sizeof(*cmpdevice) + strlen(presence_state->provider));
8334 strcpy(cmpdevice->
hintdevice, presence_state->provider);
8341 "find devices in container");
8399 "StatusText: %s\r\n\r\n",
8443 ast_verb(1,
"Asterisk PBX Core Initializing\n");
8445 ast_verb(5,
"Registering builtin functions:\n");
8536 return exten ? exten->
priority : -1;
8544 return c ?
c->registrar :
NULL;
8679 if (inc == include) {
8758 for (idx = 0; idx < includecount; idx++) {
8815 }
else if (!*prip) {
8818 *extenp = *contextp;
8828 }
else if (*pri ==
'-') {
8833 if ((rest && sscanf(pri,
"%30d%1s", ipri, rest) != 1) || sscanf(pri,
"%30d", ipri) != 1) {
8856 ast_log(
LOG_WARNING,
"Goto requires an argument ([[context,]extension,]priority)\n");
8862 pri =
strsep(&stringp,
",");
8979 prnt(where,
"%s => %s@%s",
hintdevice->hintdevice,
8991 prnt(where,
"%s", autohint->
context);
9001 prnt(where,
"%d", state_cb->
id);
Prototypes for public functions only of internal interest,.
struct sla_ringing_trunk * first
struct sla_ringing_trunk * last
static int copy(char *infile, char *outfile)
Utility function to copy a file.
int getloadavg(double *list, int nelem)
char * strsep(char **str, const char *delims)
Asterisk main include file. File version handling, generic pbx functions.
int ast_add_profile(const char *, uint64_t scale)
support for event profiling
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
int64_t ast_mark(int, int start1_stop0)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
void ast_free_ptr(void *ptr)
free() wrapper
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_t_ref(o, delta, tag)
#define ao2_iterator_next(iter)
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
@ AO2_ALLOC_OPT_LOCK_MUTEX
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
void ao2_container_unregister(const char *name)
Unregister a container for CLI stats and integrity check.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_t_link(container, obj, tag)
@ AO2_ITERATOR_DONTLOCK
Assume that the ao2_container is already locked.
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc_options(data_size, destructor_fn, options)
#define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag)
ao2_callback_data() is a generic function that applies cb_fn() to all objects in a container....
int ao2_container_register(const char *name, struct ao2_container *self, ao2_prnt_obj_fn *prnt_obj)
Register a container for CLI stats and integrity check.
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
@ OBJ_SEARCH_MASK
Search option field mask.
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
#define ao2_alloc(data_size, destructor_fn)
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
void() ao2_prnt_fn(void *where, const char *fmt,...)
Print output.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
#define AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED
Internal Asterisk hangup causes.
#define AST_CAUSE_SWITCH_CONGESTION
#define AST_CAUSE_UNALLOCATED
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
#define AST_CAUSE_CALL_REJECTED
#define AST_CAUSE_NETWORK_OUT_OF_ORDER
#define AST_CAUSE_ANSWERED_ELSEWHERE
#define AST_CAUSE_NO_ANSWER
#define AST_CAUSE_USER_BUSY
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
General Asterisk PBX channel definitions.
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
const char * ast_channel_name(const struct ast_channel *chan)
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
Clear a set of softhangup flags from a channel.
struct ast_channel_iterator * ast_channel_iterator_by_name_new(const char *name, size_t name_len)
Create a new channel iterator based on name.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Set the connected line information in the Asterisk channel.
#define ast_channel_lock(chan)
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
adds a list of channel variables to a channel
struct ast_channel * ast_channel_yank(struct ast_channel *yankee)
Gain control of a channel in the system.
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_channel_priority(const struct ast_channel *chan)
#define ast_channel_ref(c)
Increase channel reference count.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
ast_callid ast_channel_callid(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
struct timeval ast_channel_creationtime(struct ast_channel *chan)
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
struct timeval * ast_channel_whentohangup(struct ast_channel *chan)
#define ast_channel_unref(c)
Decrease channel reference count.
@ AST_FLAG_BRIDGE_HANGUP_RUN
void ast_channel_context_set(struct ast_channel *chan, const char *value)
#define ast_dummy_channel_alloc()
Create a fake channel structure.
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
Initialize the given connected line structure using the given guide for a set update operation.
void ast_channel_callid_set(struct ast_channel *chan, ast_callid value)
void ast_channel_priority_set(struct ast_channel *chan, int value)
int ast_safe_sleep_without_silence(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups, and do not generate silence.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
#define AST_MAX_EXTENSION
void ast_channel_pbx_set(struct ast_channel *chan, struct ast_pbx *value)
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
@ AST_SOFTHANGUP_ASYNCGOTO
@ AST_SOFTHANGUP_HANGUP_EXEC
@ AST_SOFTHANGUP_APPUNLOAD
ast_channel_state
ast_channel states
Standard Command Line Interface.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
#define ast_datastore_alloc(info, uid)
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
struct stasis_message_type * ast_device_state_message_type(void)
Get the Stasis message type for device state messages.
const char * ast_devstate_str(enum ast_device_state devstate) attribute_pure
Convert device state to text string that is easier to parse.
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.
struct stasis_topic * ast_device_state_topic_all(void)
Get the Stasis topic for device state messages.
enum ast_device_state ast_devstate_aggregate_result(struct ast_devstate_aggregate *agg)
Get the aggregate device state result.
ast_device_state
Device States.
enum ast_dial_result ast_dial_state(struct ast_dial *dial)
Return state of dial.
ast_dial_result
List of return codes for dial run API calls.
@ AST_DIAL_RESULT_ANSWERED
@ AST_DIAL_RESULT_PROGRESS
void ast_dial_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback)
Set a callback for state changes.
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
Append a channel.
struct ast_dial * ast_dial_create(void)
New dialing structure.
int ast_dial_prerun(struct ast_dial *dial, struct ast_channel *chan, struct ast_format_cap *cap)
Request all appended channels, but do not dial.
void ast_dial_set_global_timeout(struct ast_dial *dial, int timeout)
Set the maximum time (globally) allowed for trying to ring phones.
enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
Execute dialing synchronously or asynchronously.
struct ast_channel * ast_dial_answered_steal(struct ast_dial *dial)
Steal the channel that answered.
int ast_dial_reason(struct ast_dial *dial, int num)
Get the reason an outgoing channel has failed.
@ AST_DIAL_OPTION_PREDIAL
struct ast_channel * ast_dial_get_channel(struct ast_dial *dial, int num)
Get the dialing channel, if prerun has been executed.
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
int ast_dial_option_global_enable(struct ast_dial *dial, enum ast_dial_option option, void *data)
Enables an option globally.
#define AST_PBX_MAX_STACK
Generic File Format Support. Should be included by clients of the file handling routines....
static const char exten_name[]
static const char context_name[]
static struct ast_threadstorage buf2
static struct ast_threadstorage buf1
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
void astman_append(struct mansession *s, const char *fmt,...)
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
int indicate_busy(struct ast_channel *chan, const char *data)
int indicate_congestion(struct ast_channel *chan, const char *data)
static int testtime_write(struct ast_channel *chan, const char *cmd, char *var, const char *value)
double ast_option_maxload
struct ast_flags ast_options
@ AST_OPT_FLAG_FULLY_BOOTED
Generic (perhaps overly so) hashtable implementation Hash Table support in Asterisk.
#define ast_hashtab_start_traversal(tab)
#define ast_hashtab_insert_safe(tab, obj)
unsigned int ast_hashtab_hash_int(const int num)
void * ast_hashtab_remove_this_object(struct ast_hashtab *tab, void *obj)
Hash the object and then compare ptrs in bucket list instead of calling the compare routine,...
void ast_hashtab_destroy(struct ast_hashtab *tab, void(*objdestroyfunc)(void *obj))
This func will free the hash table and all its memory.
int ast_hashtab_newsize_java(struct ast_hashtab *tab)
Create a prime number roughly 2x the current table size.
void ast_hashtab_end_traversal(struct ast_hashtab_iter *it)
end the traversal, free the iterator, unlock if necc.
#define ast_hashtab_insert_immediate(tab, obj)
Insert without checking.
int ast_hashtab_size(struct ast_hashtab *tab)
Returns the number of elements stored in the hashtab.
void * ast_hashtab_next(struct ast_hashtab_iter *it)
Gets the next object in the list, advances iter one step returns null on end of traversal.
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
Lookup this object in the hash table.
#define ast_hashtab_create(initial_buckets, compare, resize, newsize, hash, do_locking)
Create the hashtable list.
void ast_hashtab_get_stats(struct ast_hashtab *tab, int *biggest_bucket_size, int *resize_count, int *num_objects, int *num_buckets)
Returns key stats for the table.
int ast_hashtab_resize_java(struct ast_hashtab *tab)
Determines if a table resize should occur using the Java algorithm (if the table load factor is 75% o...
void * ast_hashtab_remove_object_via_lookup(struct ast_hashtab *tab, void *obj)
Looks up the object, removes the corresponding bucket.
unsigned int ast_hashtab_hash_string(const void *obj)
Hashes a string to a number.
static char prefix[MAX_PREFIX]
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
Configuration File Parser.
ast_control_frame_type
Internal control frame subtype field values.
#define DEBUG_ATLEAST(level)
#define ast_debug(level,...)
Log a DEBUG message.
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
ast_callid ast_create_callid(void)
factory function to create a new uniquely identifying callid.
#define VERBOSITY_ATLEAST(level)
#define ast_verb(level,...)
A set of macros to manage forward-linked lists.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
struct timeval ast_mktime(struct ast_tm *const tmp, const char *zone)
Timezone-independent version of mktime(3).
char * ast_strptime(const char *s, const char *format, struct ast_tm *tm)
Special version of strptime(3) which places the answer in the common structure ast_tm....
Asterisk locking-related definitions:
#define ast_rwlock_wrlock(a)
#define ast_cond_destroy(cond)
#define ast_cond_wait(cond, mutex)
#define ast_cond_init(cond, attr)
#define ast_rwlock_rdlock(a)
#define ast_mutex_unlock(a)
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
pthread_cond_t ast_cond_t
#define ast_rwlock_destroy(rwlock)
#define ast_rwlock_unlock(a)
#define ast_mutex_lock(a)
#define AST_MUTEX_DEFINE_STATIC(mutex)
#define ast_cond_signal(cond)
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define EVENT_FLAG_REPORTING
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
#define EVENT_FLAG_CONFIG
Asterisk module definitions.
Asterisk file paths, configured in asterisk.conf.
void * ast_get_extension_app_data(struct ast_exten *e)
static void pbx_outgoing_state_callback(struct ast_dial *dial)
Internal dialing state callback which causes early media to trigger an answer.
static int hashtab_compare_extens(const void *ha_a, const void *ah_b)
static struct ao2_container * statecbs
const struct ast_sw * ast_context_switches_get(const struct ast_context *con, int idx)
static void update_scoreboard(struct scoreboard *board, int length, int spec, struct ast_exten *exten, char last, const char *callerid, int deleted, struct match_char *node)
void unreference_cached_app(struct ast_app *app)
void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *contexttab, struct ast_context *con, const char *registrar)
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
int ast_context_destroy_by_name(const char *context, const char *registrar)
Destroy a context by name.
static int manager_show_dialplan(struct mansession *s, const struct message *m)
Manager listing of dial plan.
int ast_context_remove_ignorepat(const char *context, const char *ignorepat, const char *registrar)
Remove an ignorepat.
int ast_hint_presence_state(struct ast_channel *c, const char *context, const char *exten, char **subtype, char **message)
Uses hint and presence state callback to get the presence state of an extension.
static int internal_extension_state_extended(struct ast_channel *c, const char *context, const char *exten, struct ao2_container *device_state_info)
int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
Find the priority of an extension that has the specified label.
static enum ast_control_frame_type pbx_dial_reason(enum ast_dial_result dial_result, int cause)
Attempt to convert disconnect cause to old originate reason.
int ast_pbx_outgoing_exten_predial(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, int early_media, const struct ast_assigned_ids *assignedids, const char *predial_callee)
static struct ast_exten * trie_find_next_match(struct match_char *node)
int ast_extension_state_add_destroy_extended(const char *context, const char *exten, ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data)
Add watcher for extended extension states with destructor.
const char * ast_extension_state2str(int extension_state)
Return extension_state as string.
static int handle_hint_change_message_type(struct stasis_message *msg, enum ast_state_cb_update_reason reason)
static void hintdevice_destroy(void *obj)
int ast_get_extension_priority(struct ast_exten *exten)
int ast_wrlock_contexts(void)
Write locks the context list.
static void pbx_destroy(struct ast_pbx *p)
static int action_extensionstatelist(struct mansession *s, const struct message *m)
static struct stasis_subscription * presence_state_sub
Subscription for presence state change events.
void ast_context_set_autohints(struct ast_context *con, int enabled)
Enable or disable autohints support on a context.
int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b)
hashtable functions for contexts
static void print_autohint_key(void *v_obj, void *where, ao2_prnt_fn *prnt)
int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar)
This function locks given context, removes switch, unlock context and return.
static void device_state_notify_callbacks(struct ast_hint *hint, struct ast_str **hint_app)
int ast_pbx_outgoing_app_predial(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, const struct ast_assigned_ids *assignedids, const char *predial_callee)
int ast_get_extension_registrar_line(struct ast_exten *e)
Get line number of configuration file used by registrar to register this extension.
int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar, int already_locked)
This functionc locks given context, search for the right extension and fires out all peer in this ext...
static int ast_add_extension2_lockopt(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar, const char *registrar_file, int registrar_line, int lock_context)
Same as ast_add_extension2() but controls the context locking.
int ast_get_extension_matchcid(struct ast_exten *e)
const struct ast_include * ast_walk_context_includes(const struct ast_context *con, const struct ast_include *inc)
int ast_async_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
static int acf_exception_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
static void print_statecbs_key(void *v_obj, void *where, ao2_prnt_fn *prnt)
int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, const struct ast_assigned_ids *assignedids)
Synchronously or asynchronously make an outbound call and execute an application on the channel.
enum ast_pbx_result ast_pbx_run_args(struct ast_channel *c, struct ast_pbx_args *args)
Execute the PBX in the current thread.
static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid, const char *label, enum ext_match_t action)
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
void wait_for_hangup(struct ast_channel *chan, const void *data)
static char * parse_hint_presence(struct ast_str *hint_args)
static const struct cfextension_states extension_states[]
static void presence_state_cb(void *unused, struct stasis_subscription *sub, struct stasis_message *msg)
static int hashtab_compare_exten_numbers(const void *ah_a, const void *ah_b)
static int ext_cmp(const char *left, const char *right)
static int add_priority(struct ast_context *con, struct ast_exten *tmp, struct ast_exten *el, struct ast_exten *e, int replace)
add the extension in the priority chain.
int ast_context_add_ignorepat(const char *context, const char *value, const char *registrar)
Add an ignorepat.
static struct ast_threadstorage switch_data
static int ast_extension_state3(struct ast_str *hint_app, struct ao2_container *device_state_info)
static void cli_match_char_tree(struct match_char *node, char *prefix, int fd)
const char * ast_get_extension_app(struct ast_exten *e)
static void destroy_pattern_tree(struct match_char *pattern_tree)
int ast_context_add_include(const char *context, const char *include, const char *registrar)
Add a context include.
static int publish_hint_remove(struct ast_hint *hint)
Publish a hint removed event
static int extenpatternmatchnew
enum ast_extension_states ast_devstate_to_extenstate(enum ast_device_state devstate)
Map devstate to an extension state.
static char * complete_show_dialplan_context(const char *line, const char *word, int pos, int state)
int ast_add_extension2(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar, const char *registrar_file, int registrar_line)
Main interface to add extensions to the list for out context.
static void decrease_call_count(void)
int ast_context_remove_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
static void * pbx_outgoing_exec(void *data)
Internal function which dials an outgoing leg and sends it to a provided extension or application.
static const struct ast_datastore_info exception_store_info
int ast_extension_state_add_destroy(const char *context, const char *exten, ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data)
Add watcher for extension states with destructor.
STASIS_MESSAGE_TYPE_DEFN_LOCAL(hint_change_message_type)
static int ext_fluff_count(const char *exten)
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
static struct ast_hashtab * contexts_table
static unsigned int hashtab_hash_extens(const void *obj)
static char * complete_core_show_hint(const char *line, const char *word, int pos, int state)
autocomplete for CLI command 'core show hint'
static int hint_cmp(void *obj, void *arg, int flags)
static struct ao2_container * autohints
Container for autohint contexts.
static int ext_cmp_exten_strlen(const char *str)
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
static unsigned int hashtab_hash_priority(const void *obj)
static int publish_hint_change(struct ast_hint *hint, struct ast_exten *ne)
Publish a hint changed event
const char * ast_get_extension_cidmatch(struct ast_exten *e)
static unsigned int ext_strncpy(char *dst, const char *src, size_t dst_size, int nofluff)
int ast_active_calls(void)
Retrieve the number of active calls.
#define STATUS_NO_EXTENSION
static ast_mutex_t maxcalllock
unsigned int ast_hashtab_hash_contexts(const void *obj)
static int remove_hintdevice(struct ast_hint *hint)
struct ast_context * ast_context_find(const char *name)
Find a context.
static int ext_cmp_exten(const char *left, const char *right)
static void context_merge_incls_swits_igps_other_registrars(struct ast_context *new, struct ast_context *old, const char *registrar)
static int execute_state_callback(ast_state_cb_type cb, const char *context, const char *exten, void *data, enum ast_state_cb_update_reason reason, struct ast_hint *hint, struct ao2_container *device_state_info)
static int __ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, int async)
static int autofallthrough
static void exception_store_free(void *data)
static int hintdevice_hash_cb(const void *obj, const int flags)
static void context_table_create_autohints(struct ast_hashtab *table)
static char * handle_show_hints(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
handle_show_hints: CLI support for listing registered dial plan hints
static struct match_char * already_in_tree(struct match_char *current, char *pat, int is_pattern)
static int ast_add_extension_nolock(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
static char * handle_unset_extenpatternmatchnew(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * parse_hint_device(struct ast_str *hint_args)
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
static int compare_char(const void *a, const void *b)
static int hint_hash(const void *obj, const int flags)
static int statecbs_cmp(void *obj, void *arg, int flags)
int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
static void context_merge(struct ast_context **extcontexts, struct ast_hashtab *exttable, struct ast_context *context, const char *registrar)
static void show_dialplan_helper_extension_output(int fd, char *buf1, char *buf2, struct ast_exten *exten)
Writes CLI output of a single extension for show dialplan.
int pbx_parse_location(struct ast_channel *chan, char **contextp, char **extenp, char **prip, int *ipri, int *mode, char *rest)
Parses a dialplan location into context, extension, priority.
int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, int early_media, const struct ast_assigned_ids *assignedids)
Synchronously or asynchronously make an outbound call and send it to a particular extension.
int ast_processed_calls(void)
Retrieve the total number of calls processed through the PBX since last restart.
static void manager_dpsendack(struct mansession *s, const struct message *m)
Send ack once.
static void create_match_char_tree(struct ast_context *con)
static int autohint_hash_cb(const void *obj, const int flags)
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
static ast_mutex_t conlock
Lock for the ast_context list.
static struct match_char * add_pattern_node(struct ast_context *con, struct match_char *current, const struct pattern_node *pattern, int is_pattern, int already, struct match_char **nextcharptr)
int raise_exception(struct ast_channel *chan, const char *reason, int priority)
const char * ast_get_context_registrar(struct ast_context *c)
int ast_context_add_switch(const char *context, const char *sw, const char *data, int eval, const char *registrar)
Add a switch.
#define NEW_MATCHER_RECURSE
void pbx_set_overrideswitch(const char *newval)
static void print_hintdevices_key(void *v_obj, void *where, ao2_prnt_fn *prnt)
int ast_unlock_context(struct ast_context *con)
static void unload_pbx(void)
static int increase_call_count(const struct ast_channel *c)
Increase call count for channel.
int ast_extension_close(const char *pattern, const char *data, int needmore)
void ast_merge_contexts_and_delete(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *registrar)
Merge the temporary contexts into a global contexts list and delete from the global list the ones tha...
const char * ast_get_extension_label(struct ast_exten *exten)
static struct ast_context * find_context_locked(const char *context)
lookup for a context with a given name,
int pbx_set_extenpatternmatchnew(int newval)
static void destroy_hint(void *obj)
static struct ao2_container * hintdevices
Container for hint devices.
static void pbx_outgoing_destroy(void *obj)
Destructor for outgoing structure.
static char * handle_show_hint(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
handle_show_hint: CLI support for listing registered dial plan hint
static struct ast_threadstorage hintdevice_data
int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar)
Locks context, remove included contexts, unlocks context. When we call this function,...
static void print_hints_key(void *v_obj, void *where, ao2_prnt_fn *prnt)
struct ast_context * ast_walk_contexts(struct ast_context *con)
static char * overrideswitch
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
struct ast_context * ast_get_extension_context(struct ast_exten *exten)
static int ast_remove_hint(struct ast_exten *e)
Remove hint from extension.
void ast_pbx_h_exten_run(struct ast_channel *chan, const char *context)
Run the h exten from the given context.
int ast_context_add_include2(struct ast_context *con, const char *value, const char *registrar)
Add a context include.
static int ast_extension_state2(struct ast_exten *e, struct ao2_container *device_state_info)
Check state of extension by using hints.
int ast_context_remove_extension_callerid2(struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcallerid, const char *registrar, int already_locked)
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid, int *found, int combined_find_spawn)
Launch a new extension (i.e. new stack)
int ast_extension_match(const char *pattern, const char *extension)
Determine if a given extension matches a given pattern (in NXX format)
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context or ANY context if NULL)
static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, int early_media, const struct ast_assigned_ids *assignedids, const char *predial_callee)
static void print_ext(struct ast_exten *e, char *buf, int buflen)
helper function to print an extension
static char * handle_debug_dialplan(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Send ack once.
static int ext_cmp_pattern_pos(const char **p, unsigned char *bitwise)
helper functions to sort extension patterns in the desired way, so that more specific patterns appear...
int ast_context_remove_switch(const char *context, const char *sw, const char *data, const char *registrar)
Remove a switch.
#define MAX_EXTENBUF_SIZE
static void destroy_state_cb(void *doomed)
static int hintdevice_remove_cb(void *obj, void *arg, void *data, int flags)
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
static int show_debug_helper(int fd, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, const char *includes[])
static int extension_state_add_destroy(const char *context, const char *exten, ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data, int extended)
static ast_mutex_t context_merge_lock
Lock to hold off restructuring of hints by ast_merge_contexts_and_delete.
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
static int pbx_parseable_goto(struct ast_channel *chan, const char *goto_string, int async)
int ast_rdlock_contexts(void)
Read locks the context list.
int ast_async_parseable_goto(struct ast_channel *chan, const char *goto_string)
#define STATUS_NO_CONTEXT
static int matchcid(const char *cidpattern, const char *callerid)
int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
Find the priority of an extension that has the specified label.
int ast_extension_state_add_extended(const char *context, const char *exten, ast_state_cb_type change_cb, void *data)
Add watcher for extended extension states.
static struct match_char * add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1, int findonly)
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
int ast_context_ignorepats_count(const struct ast_context *con)
#define HASH_EXTENHINT_SIZE
int ast_extension_cmp(const char *a, const char *b)
Determine if one extension should match before another.
int ast_extension_state_del(int id, ast_state_cb_type change_cb)
Deletes a state change watcher by ID.
const struct ast_include * ast_context_includes_get(const struct ast_context *con, int idx)
static struct ast_custom_function testtime_function
static int hintdevice_cmp_multiple(void *obj, void *arg, int flags)
static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
static int hashtab_compare_exten_labels(const void *ah_a, const void *ah_b)
static void presence_state_notify_callbacks(struct ast_hint *hint, struct ast_str **hint_app, struct ast_presence_state_message *presence_state)
static struct ast_context * contexts
const struct ast_sw * ast_walk_context_switches(const struct ast_context *con, const struct ast_sw *sw)
int ast_extension_state_add(const char *context, const char *exten, ast_state_cb_type change_cb, void *data)
Add watcher for extension states.
static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c, struct ast_pbx_args *args)
static const char * get_pattern_node(struct pattern_node *node, const char *src, int pattern, const char *extenbuf)
#define STATUS_NO_PRIORITY
const char * ast_get_context_name(struct ast_context *con)
int ast_get_extension_data(char *buf, int bufsize, struct ast_channel *c, const char *context, const char *exten, int priority)
Fill a string buffer with the data at a dialplan extension.
static struct ao2_container * alloc_device_state_info(void)
static const char * candidate_exten_advance(const char *str)
static struct ast_exten * ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
static int find_hint_by_cb_id(void *obj, void *arg, int flags)
Find Hint by callback id.
static int extension_presence_state_helper(struct ast_exten *e, char **subtype, char **message)
static void device_state_cb(void *unused, struct stasis_subscription *sub, struct stasis_message *msg)
static void device_state_info_dt(void *obj)
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch)
static struct ast_threadstorage extensionstate_buf
int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
Get hint for channel.
static struct ast_cli_entry pbx_cli[]
int pbx_checkcondition(const char *condition)
Evaluate a condition.
int ast_context_verify_includes(struct ast_context *con)
Verifies includes in an ast_contect structure.
static int show_dialplan_helper(int fd, const char *context, const char *exten, struct dialplan_counters *dpc, const struct ast_include *rinclude, int includecount, const char *includes[])
static struct stasis_subscription * device_state_sub
Subscription for device state change events.
int ast_context_remove_include(const char *context, const char *include, const char *registrar)
Remove included contexts. This function locks contexts list by &conlist, search for the right context...
const struct ast_ignorepat * ast_walk_context_ignorepats(const struct ast_context *con, const struct ast_ignorepat *ip)
static struct ast_exten * ast_hint_extension_nolock(struct ast_channel *c, const char *context, const char *exten)
Find hint for given extension in context.
static void pbx_shutdown(void)
const struct ast_ignorepat * ast_context_ignorepats_get(const struct ast_context *con, int idx)
static struct ao2_container * hints
static int ext_cmp_pattern(const char *left, const char *right)
static char * handle_set_extenpatternmatchnew(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_exten * ast_walk_extension_priorities(struct ast_exten *exten, struct ast_exten *priority)
int ast_add_extension2_nolock(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar, const char *registrar_file, int registrar_line)
Same as ast_add_extension2, but assumes you have already locked context.
static char * handle_show_dialplan(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
Change hint for an extension.
static int autohint_cmp(void *obj, void *arg, int flags)
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
static int hint_id_cmp(void *obj, void *arg, int flags)
static void destroy_exten(struct ast_exten *e)
static int add_hintdevice(struct ast_hint *hint, const char *devicelist)
add hintdevice structure and link it into the container.
int ast_context_add_switch2(struct ast_context *con, const char *value, const char *data, int eval, const char *registrar)
Adds a switch (first param is a ast_context)
static struct ast_context * find_context(const char *context)
lookup for a context with a given name,
static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action, int *found, int combined_find_spawn)
The return value depends on the action:
static int ast_add_hint(struct ast_exten *e)
Add hint to hint list, check initial extension state.
static unsigned int hashtab_hash_labels(const void *obj)
int ast_unlock_contexts(void)
Unlocks contexts.
static struct ast_custom_function exception_function
struct ast_exten * ast_walk_context_extensions(struct ast_context *con, struct ast_exten *exten)
int ast_context_switches_count(const struct ast_context *con)
#define NEW_MATCHER_CHK_MATCH
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
int ast_str_get_hint(struct ast_str **hint, ssize_t hintsize, struct ast_str **name, ssize_t namesize, struct ast_channel *c, const char *context, const char *exten)
Get hint for channel.
int ast_context_remove_extension_callerid(const char *context, const char *extension, int priority, const char *callerid, int matchcallerid, const char *registrar)
int pbx_set_autofallthrough(int newval)
int ast_context_includes_count(const struct ast_context *con)
static int collect_digits(struct ast_channel *c, int waittime, char *buf, int buflen, int pos)
collect digits from the channel into the buffer.
int ast_extension_state(struct ast_channel *c, const char *context, const char *exten)
Check extension state for an extension by using hint.
static void * pbx_thread(void *data)
static int manager_show_dialplan_helper(struct mansession *s, const struct message *m, const char *actionidtext, const char *context, const char *exten, struct dialplan_counters *dpc, const struct ast_include *rinclude, int includecount, const char *includes[])
Show dialplan extensions XXX this function is similar but not exactly the same as the CLI's show dial...
int ast_async_goto_by_name(const char *channame, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
static struct ast_exten * get_canmatch_exten(struct match_char *node)
const char * ast_get_extension_name(struct ast_exten *exten)
static void insert_in_next_chars_alt_char_list(struct match_char **parent_ptr, struct match_char *node)
int ast_rdlock_context(struct ast_context *con)
Read locks a given context.
const char * ast_get_extension_registrar_file(struct ast_exten *e)
Get name of configuration file used by registrar to register this extension.
const char * ast_get_extension_registrar(struct ast_exten *e)
static void get_device_state_causing_channels(struct ao2_container *c)
static void __ast_internal_context_destroy(struct ast_context *con)
static int ext_cmp_exten_partial(const char *left, const char *right)
int ast_extension_state_extended(struct ast_channel *c, const char *context, const char *exten, struct ao2_container **device_state_info)
Check extended extension state for an extension by using hint.
#define INC_DST_OVERFLOW_CHECK
void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
Core PBX routines and definitions.
ast_pbx_result
The result codes when starting the PBX on a channel with ast_pbx_start.
int ast_thread_inhibit_escalations_swap(int inhibit)
Swap the current thread escalation inhibit setting.
@ AST_OUTGOING_WAIT_COMPLETE
int(* ast_state_cb_type)(const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
Typedef for devicestate and hint callbacks.
const char * ast_get_switch_name(const struct ast_sw *sw)
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
const char * ast_get_switch_data(const struct ast_sw *sw)
#define AST_PBX_INCOMPLETE
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
const char * ast_get_include_name(const struct ast_include *include)
ast_extension_states
Extension states.
@ AST_EXTENSION_NOT_INUSE
@ AST_EXTENSION_UNAVAILABLE
@ AST_EXTENSION_DEACTIVATED
const char * ast_get_ignorepat_registrar(const struct ast_ignorepat *ip)
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
int() ast_switch_f(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
All switch functions have the same interface, so define a type for them.
int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
Register a custom function.
ast_state_cb_update_reason
@ AST_HINT_UPDATE_PRESENCE
#define AST_PBX_GOTO_FAILED
void(* ast_state_cb_destroy_type)(int id, void *data)
Typedef for devicestate and hint callback removal indication callback.
struct ast_app * pbx_findapp(const char *app)
Look up an application.
int ast_pbx_hangup_handler_run(struct ast_channel *chan)
Run all hangup handlers on the channel.
int ast_get_switch_eval(const struct ast_sw *sw)
int ast_thread_inhibit_escalations(void)
Inhibit (in the current thread) the execution of dialplan functions which cause privilege escalations...
const char * ast_get_include_registrar(const struct ast_include *i)
const char * ast_get_ignorepat_name(const struct ast_ignorepat *ip)
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
const char * ast_get_switch_registrar(const struct ast_sw *sw)
const char * app_name(struct ast_app *app)
static struct ast_context * local_contexts
void ignorepat_free(struct ast_ignorepat *ip)
struct ast_ignorepat * ignorepat_alloc(const char *value, const char *registrar)
void include_free(struct ast_include *inc)
int include_valid(const struct ast_include *inc)
struct ast_include * include_alloc(const char *value, const char *registrar)
const char * include_rname(const struct ast_include *inc)
Private include file for pbx.
struct ast_switch * pbx_findswitch(const char *sw)
struct ast_sw * sw_alloc(const char *value, const char *data, int eval, const char *registrar)
void sw_free(struct ast_sw *sw)
Presence state management.
struct stasis_topic * ast_presence_state_topic_all(void)
Get presence state topic.
const char * ast_presence_state2str(enum ast_presence_state state)
Convert presence state to text string for output.
struct stasis_message_type * ast_presence_state_message_type(void)
Get presence state message type.
struct stasis_forward * sub
struct ao2_container * container
Say numbers and dates (maybe words one day too)
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
#define stasis_subscribe(topic, callback, data)
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define ast_calloc_with_stringfields(n, type, size)
Allocate a structure with embedded stringfields in a single allocation.
#define AST_STRING_FIELD(name)
Declare a string field.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_alloca(init_len)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
ast_app: A registered application
Structure to pass both assignedid values to channel drivers.
Structure for dial plan autohints.
char context[1]
Name of the context.
char * registrar
Name of the registrar.
Main Channel structure associated with a channel.
char exten[AST_MAX_EXTENSION]
struct ast_party_dialed dialed
Dialed/Called information.
descriptor for a cli entry.
ast_context: An extension context
struct match_char * pattern_tree
struct ast_ignorepats ignorepats
struct ast_includes includes
struct ast_context * next
struct ast_hashtab * root_table
Data structure associated with a custom dialplan function.
Structure for a data store type.
Structure for a data store object.
enum ast_device_state device_state
The structure that contains device state.
const struct ast_eid * eid
The EID of the server where this message originated.
You shouldn't care about the contents of this struct.
Main dialing structure. Contains global options, channels being dialed, and more!
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
const char * cidmatch_display
struct ast_hashtab * peer_label_table
struct ast_hashtab * peer_table
const char * registrar_file
struct ast_app * cached_app
struct ast_context * parent
Data structure associated with a single frame of data.
union ast_frame::@228 data
an iterator for traversing the buckets
Structure for dial plan hints.
struct ao2_container * callbacks
char exten_name[AST_MAX_EXTENSION]
struct ast_exten * exten
Hint extension.
char * last_presence_subtype
char context_name[AST_MAX_CONTEXT]
struct ast_hint::@379 devices
char * last_presence_message
Structure for dial plan hint devices.
struct ast_hint * hint
Hint this hintdevice belongs to.
ast_ignorepat: Ignore patterns in dial plan
struct ast_ignorepat * next
ast_include: include= support in extensions.conf
struct ast_include * next
Connected Line/Party information.
Options for ast_pbx_run()
Stasis message payload representing a presence state update.
enum ast_presence_state state
Structure for rwlock and tracking information.
enum ast_state_cb_update_reason reason
struct ao2_container * device_state_info
ast_state_cb: An extension state notify register item
ast_state_cb_type change_cb
struct ast_state_cb::@378 entry
ast_state_cb_destroy_type destroy_cb
Support for dynamic strings.
ast_sw: Switch statement in extensions.conf
Structure for variables, used for configurations and for channel variables.
Counters for the show dialplan manager command.
structure to hold extensions
In case you didn't read that giant block of text above the mansession_session struct,...
match_char: forms a syntax tree for quick matching of extension patterns
struct match_char * alt_char
struct match_char * next_char
const ast_string_field app
const ast_string_field context
const ast_string_field exten
const ast_string_field context
const ast_string_field exten
const ast_string_field reason
char * incstack[AST_PBX_MAX_STACK]
const char * foundcontext
Structure which contains information about an outgoing dial.
int dial_res
Result of the dial operation when dialed is set.
ast_cond_t cond
Condition for synchronous dialing.
char app[AST_MAX_APP]
Application to execute.
unsigned int in_separate_thread
Set if we've spawned a thread to do our work.
struct ast_dial * dial
Dialing structure being used.
unsigned int dialed
Set when dialing is completed.
char exten[AST_MAX_EXTENSION]
Dialplan extension.
char context[AST_MAX_CONTEXT]
Dialplan context.
int priority
Dialplan priority.
char * appdata
Application data to pass to application.
struct ast_exten * canmatch_exten
struct store_hint::@380 callbacks
struct store_hint::@381 list
char * last_presence_subtype
char * last_presence_message
An API for managing task processing threads that can be shared across modules.
Handy terminal functions for vt* terms.
#define COLORIZE(fg, bg, str)
#define COLORIZE_FMT
Shortcut macros for coloring a set of text.
static struct aco_type item
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Time-related functions and macros.
int64_t ast_tvdiff_us(struct timeval end, struct timeval start)
Computes the difference (in microseconds) between two struct timeval instances.
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compress two struct timeval instances returning -1, 0, 1 if the first arg is smaller,...
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int error(const char *format,...)
#define ast_test_flag(p, flag)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ast_set2_flag(p, value, flag)
#define ast_clear_flag(p, flag)
#define ast_pthread_create_detached(a, b, c, d)
#define ast_set_flag(p, flag)
Vector container support.
#define AST_VECTOR_REMOVE_ORDERED(vec, idx)
Remove an element from a vector by index while maintaining order.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
#define AST_VECTOR_REMOVE_UNORDERED(vec, idx)
Remove an element from an unordered vector by index.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
#define AST_VECTOR(name, type)
Define a vector structure.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Asterisk XML Documentation API.