21 #include "asterisk/features_config.h"
29 #include "features_config.h"
360 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 1000
361 #define DEFAULT_COURTESY_TONE ""
362 #define DEFAULT_RECORDING_FAIL_SOUND ""
365 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3
366 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15
367 #define DEFAULT_ATXFER_DROP_CALL 0
368 #define DEFAULT_ATXFER_LOOP_DELAY 10
369 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
370 #define DEFAULT_XFERSOUND "beep"
371 #define DEFAULT_XFERFAILSOUND "beeperr"
372 #define DEFAULT_ATXFER_ABORT "*1"
373 #define DEFAULT_ATXFER_COMPLETE "*2"
374 #define DEFAULT_ATXFER_THREEWAY "*3"
375 #define DEFAULT_ATXFER_SWAP "*4"
376 #define DEFAULT_TRANSFER_DIAL_ATTEMPTS 3
377 #define DEFAULT_TRANSFER_RETRY_SOUND "pbx-invalid"
378 #define DEFAULT_TRANSFER_INVALID_SOUND "privacy-incorrect"
379 #define DEFAULT_TRANSFER_ANNOUNCE_SOUND "pbx-transfer"
382 #define DEFAULT_PICKUPEXTEN "*8"
383 #define DEFAULT_PICKUPSOUND ""
384 #define DEFAULT_PICKUPFAILSOUND ""
387 #define DEFAULT_FEATUREMAP_BLINDXFER "#"
388 #define DEFAULT_FEATUREMAP_DISCONNECT "*"
389 #define DEFAULT_FEATUREMAP_AUTOMON ""
390 #define DEFAULT_FEATUREMAP_ATXFER ""
391 #define DEFAULT_FEATUREMAP_PARKCALL ""
392 #define DEFAULT_FEATUREMAP_AUTOMIXMON ""
403 static void ast_applicationmap_item_destructor(
void *obj)
410 static int applicationmap_sort(
const void *obj,
const void *arg,
int flags)
419 return strcasecmp(item1->name, key2);
422 return strncasecmp(item1->name, key2, strlen(key2));
426 return strcasecmp(item1->name, item2->name);
444 static void featuregroup_item_destructor(
void *obj)
452 static int group_item_sort(
const void *obj,
const void *arg,
int flags)
483 static int featuregroup_hash(
const void *obj,
int flags)
502 static int featuregroup_cmp(
void *obj,
void *arg,
int flags)
514 return strncasecmp(group1->
name, key2, strlen(key2)) ? 0 :
CMP_MATCH;
523 static void *featuregroup_find(
struct ao2_container *group_container,
const char *category)
525 return ao2_find(group_container, category,
OBJ_KEY);
528 static void featuregroup_destructor(
void *obj)
532 ast_free((
char *) group->
name);
533 ao2_cleanup(group->
items);
536 static void *featuregroup_alloc(
const char *cat)
540 group = ao2_alloc(
sizeof(*group), featuregroup_destructor);
578 .category =
"general",
582 static struct aco_type featuremap_option = {
584 .name =
"featuremap",
586 .category =
"featuremap",
590 static struct aco_type applicationmap_option = {
592 .name =
"applicationmap",
594 .category =
"applicationmap",
598 static struct aco_type featuregroup_option = {
600 .name =
"featuregroup",
602 .category =
"^(general|featuremap|applicationmap|parkinglot_.*)$",
604 .item_alloc = featuregroup_alloc,
605 .item_find = featuregroup_find,
608 static struct aco_type parkinglot_option = {
610 .name =
"parkinglot",
612 .category =
"^parkinglot_.*$",
619 static struct aco_type *applicationmap_options[] =
ACO_TYPES(&applicationmap_option);
620 static struct aco_type *featuregroup_options[] =
ACO_TYPES(&featuregroup_option);
623 static struct aco_file features_conf = {
625 .types =
ACO_TYPES(&global_option, &featuremap_option, &applicationmap_option, &featuregroup_option, &parkinglot_option),
630 static void features_config_destructor(
void *obj)
634 ao2_cleanup(cfg->global);
635 ao2_cleanup(cfg->featuremap);
636 ao2_cleanup(cfg->parkinglots);
637 ao2_cleanup(cfg->applicationmap);
638 ao2_cleanup(cfg->featuregroups);
641 static void featuremap_config_destructor(
void *obj)
648 static void global_config_destructor(
void *obj)
652 ao2_cleanup(cfg->general);
653 ao2_cleanup(cfg->xfer);
654 ao2_cleanup(cfg->pickup);
657 static void general_destructor(
void *obj)
664 static void xfer_destructor(
void *obj)
671 static void pickup_destructor(
void *obj)
682 cfg = ao2_alloc(
sizeof(*cfg), global_config_destructor);
687 cfg->general = ao2_alloc(
sizeof(*cfg->general), general_destructor);
692 cfg->xfer = ao2_alloc(
sizeof(*cfg->xfer), xfer_destructor);
697 cfg->pickup = ao2_alloc(
sizeof(*cfg->pickup), pickup_destructor);
706 static struct ao2_container *applicationmap_alloc(
int replace_duplicates)
710 applicationmap_sort, NULL);
726 static struct features_config *__features_config_alloc(
int allocate_applicationmap)
730 cfg = ao2_alloc(
sizeof(*cfg), features_config_destructor);
735 cfg->global = global_config_alloc();
740 cfg->featuremap = ao2_alloc(
sizeof(*cfg->featuremap), featuremap_config_destructor);
745 cfg->parkinglots = ao2_alloc(
sizeof(*cfg->parkinglots), NULL);
746 if (!cfg->parkinglots) {
750 if (allocate_applicationmap) {
751 cfg->applicationmap = applicationmap_alloc(1);
752 if (!cfg->applicationmap) {
757 featuregroup_hash, NULL, featuregroup_cmp);
758 if (!cfg->featuregroups) {
768 static void *features_config_alloc(
void)
770 return __features_config_alloc(1);
797 general_copy(dest->general, src->general);
798 xfer_copy(dest->xfer, src->xfer);
799 pickup_copy(dest->pickup, src->pickup);
809 global_copy(dest->global, src->global);
810 featuremap_copy(dest->featuremap, src->featuremap);
822 dup = __features_config_alloc(0);
827 features_copy(dup, orig);
837 if (!strcasecmp(name,
"featuredigittimeout")) {
839 }
else if (!strcasecmp(name,
"courtesytone")) {
841 }
else if (!strcasecmp(name,
"recordingfailsound")) {
852 char *buf,
size_t len)
856 if (!strcasecmp(field,
"featuredigittimeout")) {
858 }
else if (!strcasecmp(field,
"courtesytone")) {
860 }
else if (!strcasecmp(field,
"recordingfailsound")) {
875 if (!strcasecmp(name,
"transferdigittimeout")) {
877 }
else if (!strcasecmp(name,
"atxfernoanswertimeout")) {
879 }
else if (!strcasecmp(name,
"atxferloopdelay")) {
881 }
else if (!strcasecmp(name,
"atxfercallbackretries")) {
883 }
else if (!strcasecmp(name,
"atxferdropcall")) {
885 }
else if (!strcasecmp(name,
"xfersound")) {
887 }
else if (!strcasecmp(name,
"xferfailsound")) {
889 }
else if (!strcasecmp(name,
"atxferabort")) {
891 }
else if (!strcasecmp(name,
"atxfercomplete")) {
893 }
else if (!strcasecmp(name,
"atxferthreeway")) {
895 }
else if (!strcasecmp(name,
"atxferswap")) {
897 }
else if (!strcasecmp(name,
"transferdialattempts")) {
899 }
else if (!strcasecmp(name,
"transferretrysound")) {
901 }
else if (!strcasecmp(name,
"transferinvalidsound")) {
903 }
else if (!strcasecmp(name,
"transferannouncesound")) {
914 char *buf,
size_t len)
918 if (!strcasecmp(field,
"transferdigittimeout")) {
920 }
else if (!strcasecmp(field,
"atxfernoanswertimeout")) {
922 }
else if (!strcasecmp(field,
"atxferloopdelay")) {
924 }
else if (!strcasecmp(field,
"atxfercallbackretries")) {
926 }
else if (!strcasecmp(field,
"atxferdropcall")) {
928 }
else if (!strcasecmp(field,
"xfersound")) {
930 }
else if (!strcasecmp(field,
"xferfailsound")) {
932 }
else if (!strcasecmp(field,
"atxferabort")) {
934 }
else if (!strcasecmp(field,
"atxfercomplete")) {
936 }
else if (!strcasecmp(field,
"atxferthreeway")) {
938 }
else if (!strcasecmp(field,
"atxferswap")) {
940 }
else if (!strcasecmp(field,
"transferdialattempts")) {
942 }
else if (!strcasecmp(field,
"transferretrysound")) {
944 }
else if (!strcasecmp(field,
"transferinvalidsound")) {
959 if (!strcasecmp(name,
"pickupsound")) {
961 }
else if (!strcasecmp(name,
"pickupfailsound")) {
963 }
else if (!strcasecmp(name,
"pickupexten")) {
974 char *buf,
size_t len)
978 if (!strcasecmp(field,
"pickupsound")) {
980 }
else if (!strcasecmp(field,
"pickupfailsound")) {
982 }
else if (!strcasecmp(field,
"pickupexten")) {
997 if (!strcasecmp(name,
"blindxfer")) {
999 }
else if (!strcasecmp(name,
"disconnect")) {
1001 }
else if (!strcasecmp(name,
"atxfer")) {
1003 }
else if (!strcasecmp(name,
"automixmon")) {
1005 }
else if (!strcasecmp(name,
"parkcall")) {
1016 char *buf,
size_t len)
1020 if (!strcasecmp(field,
"blindxfer")) {
1022 }
else if (!strcasecmp(field,
"disconnect")) {
1024 }
else if (!strcasecmp(field,
"atxfer")) {
1026 }
else if (!strcasecmp(field,
"automixmon")) {
1028 }
else if (!strcasecmp(field,
"parkcall")) {
1038 static void feature_ds_destroy(
void *data)
1044 static void *feature_ds_duplicate(
void *data)
1048 return features_config_dup(old_cfg);
1053 .destroy = feature_ds_destroy,
1054 .duplicate = feature_ds_duplicate,
1082 cfg = features_config_dup(orig);
1087 if (!(ds = ast_datastore_alloc(&feature_ds_info, NULL))) {
1107 ao2_cleanup(get_feature_ds(chan));
1120 cfg = get_feature_ds(chan);
1129 ast_assert(cfg->global && cfg->global->general);
1131 ao2_ref(cfg->global->general, +1);
1132 return cfg->global->general;
1140 cfg = get_feature_ds(chan);
1149 ast_assert(cfg->global && cfg->global->xfer);
1151 ao2_ref(cfg->global->xfer, +1);
1152 return cfg->global->xfer;
1155 char *ast_get_chan_features_xferfailsound(
struct ast_channel *chan)
1170 char *ast_get_chan_features_atxferabort(
struct ast_channel *chan)
1190 cfg = get_feature_ds(chan);
1199 ast_assert(cfg->global && cfg->global->pickup);
1201 ao2_ref(cfg->global->pickup, +1);
1202 return cfg->global->pickup;
1210 cfg = get_feature_ds(chan);
1219 ast_assert(cfg->featuremap != NULL);
1222 return cfg->featuremap;
1225 int ast_get_builtin_feature(
struct ast_channel *chan,
const char *feature,
char *buf,
size_t len)
1230 cfg = get_feature_ds(chan);
1239 return featuremap_get(cfg->featuremap, feature, buf, len);
1242 int ast_get_feature(
struct ast_channel *chan,
const char *feature,
char *buf,
size_t len)
1247 if (!ast_get_builtin_feature(chan, feature, buf, len)) {
1252 applicationmap = ast_get_chan_applicationmap(chan);
1253 if (!applicationmap) {
1257 item = ao2_find(applicationmap, feature,
OBJ_KEY);
1267 const char *app,
const char *
app_data,
const char *moh_class,
const char *dtmf,
1268 unsigned int activate_on_self)
1272 item = ao2_alloc(
sizeof(*item), ast_applicationmap_item_destructor);
1283 item->activate_on_self = activate_on_self;
1288 static int add_item(
void *obj,
void *arg,
int flags)
1313 ao2_link(applicationmap, appmap_item);
1332 ao2_ref(cfg->applicationmap, +1);
1333 return cfg->applicationmap;
1337 if (ast_strlen_zero(group_names)) {
1341 applicationmap = applicationmap_alloc(0);
1342 if (!applicationmap) {
1347 ast_assert(cfg->featuregroups != NULL);
1348 ast_assert(cfg->applicationmap != NULL);
1349 while ((name = strsep(&group_names,
"#"))) {
1358 ast_log(LOG_WARNING,
"Unknown DYNAMIC_FEATURES item '%s' on channel %s.\n",
1359 name, ast_channel_name(chan));
1367 ao2_cleanup(applicationmap);
1371 return applicationmap;
1374 static int applicationmap_handler(
const struct aco_option *opt,
1389 unsigned int activate_on_self;
1393 if (ast_strlen_zero(args.dtmf) ||
1394 ast_strlen_zero(args.activate_on) ||
1395 ast_strlen_zero(args.app)) {
1396 ast_log(LOG_WARNING,
"Invalid applicationmap syntax for '%s'. Missing required argument\n", var->
name);
1404 slash = strchr(args.activate_on,
'/');
1410 if (!args.app_data) {
1420 paren = strchr(args.app,
'(');
1425 args.moh_class = args.app_data;
1427 close_paren = strrchr(paren,
')');
1429 *close_paren =
'\0';
1431 args.app_data = paren;
1434 if (ast_strlen_zero(args.app)) {
1435 ast_log(LOG_WARNING,
"Applicationmap item '%s' does not contain an application name.\n", var->
name);
1438 }
else if (strchr(args.app_data,
'"')) {
1443 if (!strcasecmp(args.activate_on,
"self") || !strcasecmp(args.activate_on,
"caller")) {
1444 activate_on_self = 1;
1445 }
else if (!strcasecmp(args.activate_on,
"peer") || !strcasecmp(args.activate_on,
"callee")) {
1446 activate_on_self = 0;
1448 ast_log(LOG_WARNING,
"Invalid 'activate_on' value %s for applicationmap item %s\n",
1449 args.activate_on, var->
name);
1453 ast_debug(1,
"Allocating applicationmap item: dtmf = %s, app = %s, app_data = %s, moh_class = %s\n",
1454 args.dtmf, args.app, args.app_data, args.moh_class);
1456 item = applicationmap_item_alloc(var->
name, args.app, args.app_data,
1457 args.moh_class, args.dtmf, activate_on_self);
1463 if (!
ao2_link(applicationmap, item)) {
1470 static int featuregroup_handler(
const struct aco_option *opt,
1476 item = ao2_alloc(
sizeof(*item), featuregroup_item_destructor);
1493 static int general_handler(
const struct aco_option *opt,
1499 return general_set(general, var->
name, var->
value);
1502 static int xfer_handler(
const struct aco_option *opt,
1508 return xfer_set(xfer, var->
name, var->
value);
1511 static int pickup_handler(
const struct aco_option *opt,
1517 return pickup_set(pickup, var->
name, var->
value);
1520 static int parking_warning = 0;
1521 static int unsupported_handler(
const struct aco_option *opt,
1524 if (!parking_warning) {
1525 ast_log(LOG_WARNING,
"Parkinglots are no longer configurable in features.conf; "
1526 "parking is now handled by res_parking.conf\n");
1527 parking_warning = 1;
1529 ast_log(LOG_WARNING,
"The option '%s' is no longer configurable in features.conf.\n", var->
name);
1533 static int featuremap_handler(
const struct aco_option *opt,
1538 return featuremap_set(featuremap, var->
name, var->
value);
1541 static int check_featuregroup_item(
void *obj,
void *arg,
void *data,
int flags)
1559 static int check_featuregroup(
void *obj,
void *arg,
void *data,
int flags)
1564 ao2_callback_data(group->
items, 0, check_featuregroup_item, arg, data);
1567 ast_log(LOG_WARNING,
"Featuregroup %s refers to non-existent applicationmap item\n",
1574 static int features_pre_apply_config(
void);
1577 .files = ACO_FILES(&features_conf),
1578 .pre_apply_config = features_pre_apply_config,
1581 static int features_pre_apply_config(
void)
1591 ast_assert(cfg->featuregroups != NULL);
1592 ast_assert(cfg->applicationmap != NULL);
1593 ao2_callback_data(cfg->featuregroups, 0, check_featuregroup, &err, cfg->applicationmap);
1598 static int internal_feature_read(
struct ast_channel *chan,
const char *cmd,
char *data,
1599 char *buf,
size_t len)
1605 if (!strcasecmp(data,
"inherit")) {
1609 snprintf(buf, len,
"%s", inherit ?
"yes" :
"no");
1613 cfg = get_feature_ds(chan);
1618 res = general_get(cfg->global->general, data, buf, len) &&
1619 xfer_get(cfg->global->xfer, data, buf, len) &&
1620 pickup_get(cfg->global->pickup, data, buf, len);
1623 ast_log(LOG_WARNING,
"Invalid argument '%s' to FEATURE()\n", data);
1629 static int internal_feature_write(
struct ast_channel *chan,
const char *cmd,
char *data,
1636 if (!strcasecmp(data,
"inherit")) {
1644 if (!(cfg = get_feature_ds(chan))) {
1648 res = general_set(cfg->global->general, data, value) &&
1649 xfer_set(cfg->global->xfer, data, value) &&
1650 pickup_set(cfg->global->pickup, data, value);
1653 ast_log(LOG_WARNING,
"Invalid argument '%s' to FEATURE()\n", data);
1659 static int internal_featuremap_read(
struct ast_channel *chan,
const char *cmd,
char *data,
1660 char *buf,
size_t len)
1665 res = ast_get_builtin_feature(chan, data, buf, len);
1668 ast_log(LOG_WARNING,
"Invalid argument '%s' to FEATUREMAP()\n", data);
1674 static int internal_featuremap_write(
struct ast_channel *chan,
const char *cmd,
char *data,
1681 if (!(cfg = get_feature_ds(chan))) {
1685 res = featuremap_set(cfg->featuremap, data, value);
1687 ast_log(LOG_WARNING,
"Invalid argument '%s' to FEATUREMAP()\n", data);
1694 static int feature_read(
struct ast_channel *chan,
const char *cmd,
char *data,
1695 char *buf,
size_t len)
1698 ast_log(LOG_WARNING,
"No channel was provided to %s function.\n", cmd);
1702 return internal_feature_read(chan, cmd, data, buf, len);
1705 static int feature_write(
struct ast_channel *chan,
const char *cmd,
char *data,
1709 ast_log(LOG_WARNING,
"No channel was provided to %s function.\n", cmd);
1713 return internal_feature_write(chan, cmd, data, value);
1716 static int featuremap_read(
struct ast_channel *chan,
const char *cmd,
char *data,
1717 char *buf,
size_t len)
1720 ast_log(LOG_WARNING,
"No channel was provided to %s function.\n", cmd);
1724 return internal_featuremap_read(chan, cmd, data, buf, len);
1727 static int featuremap_write(
struct ast_channel *chan,
const char *cmd,
char *data,
1731 ast_log(LOG_WARNING,
"No channel was provided to %s function.\n", cmd);
1735 return internal_featuremap_write(chan, cmd, data, value);
1740 .read = feature_read,
1741 .write = feature_write
1745 .
name =
"FEATUREMAP",
1746 .read = featuremap_read,
1747 .write = featuremap_write
1750 static int load_config(
void)
1753 ast_log(LOG_ERROR,
"Unable to initialize configuration info for features\n");
1758 __stringify(DEFAULT_FEATURE_DIGIT_TIMEOUT), general_handler, 0);
1760 DEFAULT_RECORDING_FAIL_SOUND, general_handler, 0);
1762 DEFAULT_COURTESY_TONE, general_handler, 0);
1765 __stringify(DEFAULT_TRANSFER_DIGIT_TIMEOUT), xfer_handler, 0)
1767 __stringify(DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER), xfer_handler, 0);
1769 __stringify(DEFAULT_ATXFER_DROP_CALL), xfer_handler, 0);
1771 __stringify(DEFAULT_ATXFER_LOOP_DELAY), xfer_handler, 0);
1773 __stringify(DEFAULT_ATXFER_CALLBACK_RETRIES), xfer_handler, 0);
1775 DEFAULT_XFERSOUND, xfer_handler, 0);
1777 DEFAULT_XFERFAILSOUND, xfer_handler, 0);
1779 DEFAULT_ATXFER_ABORT, xfer_handler, 0);
1781 DEFAULT_ATXFER_COMPLETE, xfer_handler, 0);
1783 DEFAULT_ATXFER_THREEWAY, xfer_handler, 0);
1785 DEFAULT_ATXFER_SWAP, xfer_handler, 0);
1787 __stringify(DEFAULT_TRANSFER_DIAL_ATTEMPTS), xfer_handler, 0);
1789 DEFAULT_TRANSFER_RETRY_SOUND, xfer_handler, 0);
1791 DEFAULT_TRANSFER_INVALID_SOUND, xfer_handler, 0);
1793 DEFAULT_TRANSFER_ANNOUNCE_SOUND, xfer_handler, 0);
1796 DEFAULT_PICKUPEXTEN, pickup_handler, 0);
1798 DEFAULT_PICKUPSOUND, pickup_handler, 0);
1800 DEFAULT_PICKUPFAILSOUND, pickup_handler, 0);
1803 "", unsupported_handler, 0);
1805 "", unsupported_handler, 0);
1807 "", unsupported_handler, 0);
1809 "", unsupported_handler, 0);
1811 "", unsupported_handler, 0);
1813 "", unsupported_handler, 0);
1815 "", unsupported_handler, 0);
1817 "", unsupported_handler, 0);
1819 "", unsupported_handler, 0);
1821 "", unsupported_handler, 0);
1823 "", unsupported_handler, 0);
1825 "", unsupported_handler, 0);
1827 "", unsupported_handler, 0);
1829 "", unsupported_handler, 0);
1831 "", unsupported_handler, 0);
1833 "", unsupported_handler, 0);
1835 "", unsupported_handler, 0);
1838 DEFAULT_FEATUREMAP_BLINDXFER, featuremap_handler, 0);
1840 DEFAULT_FEATUREMAP_DISCONNECT, featuremap_handler, 0);
1842 DEFAULT_FEATUREMAP_ATXFER, featuremap_handler, 0);
1844 DEFAULT_FEATUREMAP_PARKCALL, featuremap_handler, 0);
1846 DEFAULT_FEATUREMAP_AUTOMIXMON, featuremap_handler, 0);
1849 "", applicationmap_handler, 0);
1852 "", featuregroup_handler, 0);
1855 "", unsupported_handler, 0);
1861 aco_set_defaults(&featuremap_option,
"featuremap", features_cfg->featuremap)) {
1862 ast_log(LOG_ERROR,
"Failed to load features.conf and failed to initialize defaults.\n");
1866 ast_log(LOG_NOTICE,
"Could not load features config; using defaults\n");
1873 static int print_featuregroup(
void *obj,
void *arg,
int flags)
1884 static int print_featuregroups(
void *obj,
void *arg,
int flags)
1889 ast_cli(a->fd,
"===> Group: %s\n", group->
name);
1895 #define HFS_FORMAT "%-25s %-7s %-7s\n"
1897 static int print_applicationmap(
void *obj,
void *arg,
int flags)
1902 ast_cli(a->fd, HFS_FORMAT, item->name,
"no def", item->dtmf);
1924 "Usage: features show\n"
1925 " Lists configured features\n";
1933 ast_cli(a->fd, HFS_FORMAT,
"Builtin Feature",
"Default",
"Current");
1934 ast_cli(a->fd, HFS_FORMAT,
"---------------",
"-------",
"-------");
1936 ast_cli(a->fd, HFS_FORMAT,
"Pickup", DEFAULT_PICKUPEXTEN, cfg->global->pickup->pickupexten);
1937 ast_cli(a->fd, HFS_FORMAT,
"Blind Transfer", DEFAULT_FEATUREMAP_BLINDXFER, cfg->featuremap->blindxfer);
1938 ast_cli(a->fd, HFS_FORMAT,
"Attended Transfer", DEFAULT_FEATUREMAP_ATXFER, cfg->featuremap->atxfer);
1939 ast_cli(a->fd, HFS_FORMAT,
"Disconnect Call", DEFAULT_FEATUREMAP_DISCONNECT, cfg->featuremap->disconnect);
1940 ast_cli(a->fd, HFS_FORMAT,
"Park Call", DEFAULT_FEATUREMAP_PARKCALL, cfg->featuremap->parkcall);
1941 ast_cli(a->fd, HFS_FORMAT,
"One Touch MixMonitor", DEFAULT_FEATUREMAP_AUTOMIXMON, cfg->featuremap->automixmon);
1943 ast_cli(a->fd,
"\n");
1944 ast_cli(a->fd, HFS_FORMAT,
"Dynamic Feature",
"Default",
"Current");
1945 ast_cli(a->fd, HFS_FORMAT,
"---------------",
"-------",
"-------");
1947 ast_cli(a->fd,
"(none)\n");
1949 ao2_callback(cfg->applicationmap, 0, print_applicationmap, a);
1952 ast_cli(a->fd,
"\nFeature Groups:\n");
1953 ast_cli(a->fd,
"---------------\n");
1955 ast_cli(a->fd,
"(none)\n");
1957 ao2_callback(cfg->featuregroups, 0, print_featuregroups, a);
1964 AST_CLI_DEFINE(handle_feature_show,
"Lists configured features"),
1967 void unload_features_config(
void)
1976 int reload_features_config(
void)
1979 parking_warning = 0;
1987 int load_features_config(
void)
1991 res = load_config();
Main Channel structure associated with a channel.
Feature configuration relating to transfers.
Asterisk main include file. File version handling, generic pbx functions.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
The argument parsing routine.
Featuregroup representation.
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
const ast_string_field atxferabort
const ast_string_field atxferthreeway
Configuration for the builtin features.
An applicationmap configuration item.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
descriptor for a cli entry.
const ast_string_field atxfercomplete
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Allow objects with duplicate keys in container.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Structure for variables, used for configurations and for channel variables.
unsigned int atxferdropcall
const ast_string_field appmap_item_name
const ast_string_field pickupsound
Structure for a data store type.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
General features configuration items.
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
CONFIG_INFO_CORE("stasis", cfg_info, globals, stasis_config_alloc,.files=ACO_FILES(&stasis_conf),)
Register information about the configs being processed by this module.
unsigned int featuredigittimeout
#define ast_strdup(str)
A wrapper for strdup()
Structure for a data store object.
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.
unsigned int transferdigittimeout
The representation of a single configuration file to be processed.
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
struct ast_applicationmap_item * appmap_item
struct ao2_container * items
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
unsigned int transferdialattempts
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 ast_string_field courtesytone
const ast_string_field atxfer
Asterisk datastore objects.
Configuration from the "general" section of features.conf.
const ast_string_field xferfailsound
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
const ast_string_field transferretrysound
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
General Asterisk PBX channel definitions.
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Data structure associated with a custom dialplan function.
unsigned int atxferloopdelay
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define AST_STRING_FIELD(name)
Declare a string field.
#define ast_debug(level,...)
Log a DEBUG message.
Core PBX routines and definitions.
Their was an error and no changes were applied.
Configuration option-handling.
#define ast_string_fields_copy(copy, orig)
Copy all string fields from one instance to another of the same structure.
#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.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
const ast_string_field pickupfailsound
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
unsigned int atxfernoanswertimeout
const ast_string_field atxferswap
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
const ast_string_field dtmf_override
static struct aco_type global_option
An aco_type structure to link the "general" category to the skel_global_config type.
Entry in the container of featuregroups.
const ast_string_field recordingfailsound
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Replace objects with duplicate keys in container.
const ast_string_field blindxfer
Standard Command Line Interface.
Type information about a category-level configurable object.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
Register a custom function.
const ast_string_field xfersound
#define AO2_GLOBAL_OBJ_STATIC(name)
Define a global object holder to be used to hold an ao2 object, statically initialized.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
const ast_string_field parkcall
const ast_string_field automixmon
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
unsigned int atxfercallbackretries
const ast_string_field disconnect
const ast_string_field transferinvalidsound
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
const ast_string_field pickupexten
Configuration relating to call pickup.
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define aco_option_register_custom_nodoc(info, name, matchtype, types, default_val, handler, flags)
Register a config option with no expected documentation.
#define ao2_link(container, obj)
Add an object to a container.