****************** BEFORE ***************************
v = ast_variable_browse(cfg, "general");
while(v) {
if (handle_common_options(&global_flags, &dummy, v)) {
v = v->next;
continue;
}
/* Create the interface list */
if (!strcasecmp(v->name, "context")) {
ast_copy_string(default_context, v->value, sizeof(default_context));
} else if (!strcasecmp(v->name, "realm")) {
ast_copy_string(global_realm, v->value, sizeof(global_realm));
} else if (!strcasecmp(v->name, "useragent")) {
ast_copy_string(default_useragent, v->value, sizeof(default_useragent));
ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n",
default_useragent);
} else if (!strcasecmp(v->name, "rtcachefriends")) {
ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS);
} else if (!strcasecmp(v->name, "rtupdate")) {
ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTUPDATE);
} else if (!strcasecmp(v->name, "ignoreregexpire")) {
ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE);
} else if (!strcasecmp(v->name, "rtautoclear")) {
int i = atoi(v->value);
if (i > 0)
global_rtautoclear = i;
else
i = 0;
ast_set2_flag((&global_flags_page2), i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
} else if (!strcasecmp(v->name, "usereqphone")) {
ast_set2_flag((&global_flags), ast_true(v->value), SIP_USEREQPHONE);
} else if (!strcasecmp(v->name, "relaxdtmf")) {
relaxdtmf = ast_true(v->value);
} else if (!strcasecmp(v->name, "checkmwi")) {
if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) {
ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno);
global_mwitime = DEFAULT_MWITIME;
}
} else if (!strcasecmp(v->name, "vmexten")) {
ast_copy_string(global_vmexten, v->value, sizeof(global_vmexten));
} else if (!strcasecmp(v->name, "rtptimeout")) {
if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno);
global_rtptimeout = 0;
}
} else if (!strcasecmp(v->name, "rtpholdtimeout")) {
if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno);
global_rtpholdtimeout = 0;
}
} else if (!strcasecmp(v->name, "rtpkeepalive")) {
if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno);
global_rtpkeepalive = 0;
}
} else if (!strcasecmp(v->name, "videosupport")) {
videosupport = ast_true(v->value);
} else if (!strcasecmp(v->name, "compactheaders")) {
compactheaders = ast_true(v->value);
} else if (!strcasecmp(v->name, "notifymimetype")) {
ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
} else if (!strcasecmp(v->name, "notifyringing")) {
global_notifyringing = ast_true(v->value);
} else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
ast_copy_string(global_musicclass, v->value, sizeof(global_musicclass));
} else if (!strcasecmp(v->name, "language")) {
ast_copy_string(default_language, v->value, sizeof(default_language));
} else if (!strcasecmp(v->name, "regcontext")) {
ast_copy_string(regcontext, v->value, sizeof(regcontext));
/* Create context if it doesn't exist already */
if (!ast_context_find(regcontext))
ast_context_create(NULL, regcontext, channeltype);
} else if (!strcasecmp(v->name, "callerid")) {
ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
} else if (!strcasecmp(v->name, "fromdomain")) {
ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
} else if (!strcasecmp(v->name, "outboundproxy")) {
if (ast_get_ip_or_srv(&outboundproxyip, v->value, "_sip._udp") < 0)
ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
} else if (!strcasecmp(v->name, "outboundproxyport")) {
/* Port needs to be after IP */
sscanf(v->value, "%d", &format);
outboundproxyip.sin_port = htons(format);
} else if (!strcasecmp(v->name, "autocreatepeer")) {
autocreatepeer = ast_true(v->value);
} else if (!strcasecmp(v->name, "srvlookup")) {
srvlookup = ast_true(v->value);
} else if (!strcasecmp(v->name, "pedantic")) {
pedanticsipchecking = ast_true(v->value);
} else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
max_expiry = atoi(v->value);
if (max_expiry < 1)
max_expiry = DEFAULT_MAX_EXPIRY;
} else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
default_expiry = atoi(v->value);
if (default_expiry < 1)
default_expiry = DEFAULT_DEFAULT_EXPIRY;
} else if (!strcasecmp(v->name, "sipdebug")) {
if (ast_true(v->value))
sipdebug |= SIP_DEBUG_CONFIG;
} else if (!strcasecmp(v->name, "dumphistory")) {
dumphistory = ast_true(v->value);
} else if (!strcasecmp(v->name, "recordhistory")) {
recordhistory = ast_true(v->value);
} else if (!strcasecmp(v->name, "registertimeout")) {
global_reg_timeout = atoi(v->value);
if (global_reg_timeout < 1)
global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
} else if (!strcasecmp(v->name, "registerattempts")) {
global_regattempts_max = atoi(v->value);
***************** AFTER *****************************
AST_CONFIG_PARSE_BEGIN(cfg, "general")
SIP_COMMON_OPTIONS(&global_flags)
AST_CONFIG_STR("context", default_context)
AST_CONFIG_STR("realm", global_realm)
AST_CONFIG_STR("useragent", default_useragent)
AST_CONFIG_FLAG("rtcachefriends", &global_flags_page2, SIP_PAGE2_RTCACHEFRIENDS)
AST_CONFIG_FLAG("rtupdate", &global_flags_page2, SIP_PAGE2_RTUPDATE)
AST_CONFIG_FLAG("ignoreexpire", &global_flags_page2, SIP_PAGE2_IGNOEEXPIRE)
AST_CONFIG_CUSTOM("rtautoclear", parse_rtautoclear(val))
AST_CONFIG_FLAG("usereqphone", &global_flags, SIP_USEREQPHONE)
AST_CONFIG_BOOL("relaxdtmf", relaxdtmf)
AST_CONFIG_UINT("checkmwi", global_mwitime)
AST_CONFIG_STR("vmexten", global_vmexten)
AST_CONFIG_UINT("rtptimeout", global_rtptimeout)
AST_CONFIG_UINT("rtpholdtimeout", global_rtpholdtimeout)
AST_CONFIG_UINT("rtpkeepalive", global_rtpkeepalive)
AST_CONFIG_BOOL("videosupport", videosupport)
AST_CONFIG_BOOL("compactheaders", compactheaders)
AST_CONFIG_STR("notifymimetype", default_notifymime)
AST_CONFIG_BOOL("notifyringing", global_notifyringing)
AST_CONFIG_STR("musicclass", global_musicclass)
AST_CONFIG_STR("musiconhold", global_musicclass)
AST_CONFIG_STR("language", default_language)
AST_CONFIG_CUSTOM("regcontext", parse_regcontext(val))
AST_CONFIG_STR("callerid", default_callerid)
AST_CONFIG_STR("fromdomain", default_fromdomain)
AST_CONFIG_CUSTOM("outboundproxy", parse_outboundproxy(val))
AST_CONFIG_CUSTOM("outboundproxyport", parse_outboundproxyport(val))
AST_CONFIG_BOOL("autocreatepeer", autocreatepeer)
AST_CONFIG_BOOL("srvlookup", srvlookup)
AST_CONFIG_BOOL("pedantic", pendanticsipchecking)
AST_CONFIG_UINT("maxexpirey", max_expiry)
AST_CONFIG_UINT("maxexpiry", max_expiry)
AST_CONFIG_UINT("defaultexpirey", default_expiry)
AST_CONFIG_UINT("defaultexpiry", default_expiry)
AST_CONFIG_CUSTOM("sipdebug", if (ast_true(val)) sipdebug |= SIP_DEBUGCONFIG)
AST_CONFIG_BOOL("dumphistory", dumphistory)
AST_CONFIG_BOOL("recordhistory", recordhistory)
/* XXX a lot of these UINT opts want something > 1, and a default val otherwise ... XXX */
AST_CONFIG_UINT("registertimeout", global_reg_timeout)
AST_CONFIG_BOOL("registerattempts", global_regattempts_max)
AST_CONFIG_CUSTOM("bindaddr", parse_bindaddr(val))
AST_CONFIG_PARSE_END
************************************************
/*!
The following are a set of macros to help with the parsing of an Asterisk
configuration file. This how to use them...
All of the option parsing is done inside of these two macros:
AST_CONFIG_PARSE_BEGIN(cfg, context)
-- option parsing happens in here --
AST_CONFIG_PARSE_END
'cfg' is a pointer to a 'struct ast_config' that has already been initialized
prior to this point. 'context' is a string that indicates which context to
read from the config, 'cfg'.
Inside of these macros, all of the options to look for will be listed. There
are seperate macros to indicate different interpretations of the value that
has been specified in the configuration file.
For example, if the option's value string should be copied directly into a
character array, the following macro would be used:
AST_CONFIG_STR("context", peer->context)
There are also cases where another function should be called should an option
be found in a configuration file. It would also be common in this case to
need to be able to access to option's value directly. This can be done with
the variable 'val', which is defined in AST_CONFIG_PARSE_BEGIN.
For example:
AST_CONFIG_CUSTOM("mixer", store_mixer(o, val))
NOTE: It is very important that semicolons *ARE NOT* specified after the use
of any of these macros.
*/
/*!
\brief Begin parsing options from the given context in the configuration file
that has already been loaded.
If at any point during the parsing of configuration options, the value of of
the option needs to be directly accessed, it can be done with the variable,
'val'.
*/
#define AST_CONFIG_PARSE_BEGIN(cfg, context) \
do { \
struct ast_variable *__v; \
const char *val; \
for (__v = ast_variable_browse(cfg, context); __v; __v = __v->next) { \
val = __v->value;
/*!
\brief End Config parsing.
This is used after a call to AST_CONFIG_PARSE_BEGIN.
*/
#define AST_CONFIG_PARSE_END ; } } while (0);
#define AST_CONFIG_CHECK(name, tag, f) if (!strcasecmp(name, tag)) { f; } else
/*!
\brief If 'tag' matches the current option, execute the function 'f'.
*/
#define AST_CONFIG_CUSTOM(tag, f) AST_CONFIG_CHECK(__v->name, tag, f)
/*!
\brief If 'tag' matches the current option, set 'dst' to the result of ast_true()
*/
#define AST_CONFIG_BOOL(tag, dst) AST_CONFIG_CUSTOM(tag, (dst) = ast_true(val))
/*!
\brief If 'tag' matches the current option, set the 'flag' in the 'flags'
member of the structure pointed to by 'dst'.
*/
#define AST_CONFIG_FLAG(tag, dst, flag) AST_CONFIG_CUSTOM(tag, ast_set2_flag(dst, ast_true(val), flag))
/*!
\brief If 'tag' matches the current option, interpret the value as an unsigned
integer and store it in 'dst'.
*/
#define AST_CONFIG_UINT(tag, dst) AST_CONFIG_CUSTOM(tag, (dst) = strtoul(val, NULL, 0))
/*!
\brief If 'tag' matches the current option, copy the value directly to 'dst'.
*/
#define AST_CONFIG_STR(tag, dst) AST_CONFIG_CUSTOM(tag, ast_copy_string(dst, val, sizeof(dst)))
#define AST_CONFIG_CHECK_VAL_BEGIN(tag) if (!strcasecmp(__v->name, tag)) {
#define AST_CONFIG_CHECK_VAL_END ; } else
#define AST_CONFIG_VAL_FLAG_DIRECT(tag, dst, flag) \
AST_CONFIG_CHECK(val, tag, ast_set_flag(dst, flag))
#define AST_CONFIG_VAL_FLAG(dst, flag) if (ast_true(val)) { ast_set_flag(dst, flag); } else
#define AST_CONFIG_VAL_CUSTOM(tag, f) AST_CONFIG_CHECK(val, tag, f)
#define AST_CONFIG_VAL_DEFAULT(dst, flag, f) \
f; ast_set_flag(dst, flag)
#define AST_CONFIG_VAL_UNKNOWN(f) f