summaryrefslogtreecommitdiffstats
path: root/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'route.c')
-rw-r--r--route.c152
1 files changed, 138 insertions, 14 deletions
diff --git a/route.c b/route.c
index 126424f..aaa5606 100644
--- a/route.c
+++ b/route.c
@@ -68,8 +68,8 @@ struct cond_defs cond_defs[] = {
"capability=speech|audio|video|digital-restricted|digital-unrestricted|digital-unrestricted-tones[,...]", "Matches the given bearer capability(s)."},
{ "infolayer1", MATCH_INFOLAYER1, COND_TYPE_INTEGER,
"infolayer1=<value>[,...]", "Matches the given information layer 1. (2=u-Law, 3=a-law, see info layer 1 in bearer capability.)"},
- { "hlc", MATCH_HLC, COND_TYPE_INTEGER,
- "hlc=<value>[,...]", "Matches the high layer capability(s)."},
+ { "hlc", MATCH_HLC, COND_TYPE_HLC,
+ "hlc=telephony|faxg2g3|faxg4|teletex1|teletex2|teletex3|videotex1|videotex2|telex|mhs|osi|maintenance|management|audiovisual[,...]", "Matches the high layer capability(s)."},
{ "file", MATCH_FILE, COND_TYPE_STRING,
"file=<path>[,...]", "Mathes is the given file exists and if the first character is '1'."},
{ "execute", MATCH_EXECUTE, COND_TYPE_STRING,
@@ -126,11 +126,11 @@ struct param_defs param_defs[] = {
"infolayer1", PARAM_TYPE_INTEGER,
"infolayer1=<value>", "Alter the layer 1 information of a call. Use 3 for ALAW or 2 for uLAW."},
{ PARAM_HLC,
- "hlc", PARAM_TYPE_INTEGER,
- "hlc=<value>", "Alter the HLC identification. Use 1 for telephony or omit."},
+ "hlc", PARAM_TYPE_HLC,
+ "hlc=telephony|faxg2g3|faxg4|teletex1|teletex2|teletex3|videotex1|videotex2|telex|mhs|osi|maintenance|management|audiovisual", "Alter the HLC identification."},
{ PARAM_EXTHLC,
- "exthlc", PARAM_TYPE_INTEGER,
- "exthlc=<value>", "Alter extended HLC value. (Mainenance only, don't use it.)"},
+ "exthlc", PARAM_TYPE_HLC,
+ "exthlc=<value>", "Alter extended HLC value, see hlc. (Mainenance only, don't use it.)"},
{ PARAM_PRESENT,
"present", PARAM_TYPE_YESNO,
"present=yes|no", "Allow or restrict caller ID regardless what the caller wants."},
@@ -342,6 +342,10 @@ struct action_defs action_defs[] = {
"disconnect", NULL, &EndpointAppPBX::action_dialing_disconnect, NULL,
PARAM_CONNECT | PARAM_CAUSE | PARAM_LOCATION | PARAM_SAMPLE | PARAM_DISPLAY,
"Caller gets disconnected optionally with given cause and given sample and given display text."},
+ { ACTION_RELEASE,
+ "release", NULL, &EndpointAppPBX::action_dialing_release, NULL,
+ PARAM_CONNECT | PARAM_CAUSE | PARAM_LOCATION | PARAM_DISPLAY,
+ "Same as 'disconnect', but using RELEASE message on ISDN."},
{ ACTION_DEFLECT,
"deflect", NULL, &EndpointAppPBX::action_dialing_deflect, NULL,
PARAM_DEST,
@@ -354,7 +358,7 @@ struct action_defs action_defs[] = {
// "The call forward is set within the telephone network of the external line."},
{ ACTION_EXECUTE,
"execute", &EndpointAppPBX::action_init_execute, NULL, &EndpointAppPBX::action_hangup_execute,
- PARAM_CONNECT | PARAM_EXECUTE | PARAM_PARAM | PARAM_ON,
+ PARAM_CONNECT | PARAM_EXECUTE | PARAM_PARAM | PARAM_ON | PARAM_TIMEOUT,
"Executes the given script file. The file must terminate quickly, because it will halt the PBX."},
{ ACTION_FILE,
"file", NULL, NULL, &EndpointAppPBX::action_hangup_file,
@@ -1248,6 +1252,43 @@ struct route_ruleset *ruleset_parse(void)
cond->value_type = VALUE_TYPE_INTEGER;
break;
+ /* parse service value */
+ case COND_TYPE_HLC:
+ if (!strncasecmp("telephony", p, 9))
+ cond->integer_value = INFO_HLC_TELEPHONY;
+ else if (!strncasecmp("faxg2g3", p, 7))
+ cond->integer_value = INFO_HLC_FAXG2G3;
+ else if (!strncasecmp("faxg4", p, 5))
+ cond->integer_value = INFO_HLC_FAXG4;
+ else if (!strncasecmp("teletex1", p, 8))
+ cond->integer_value = INFO_HLC_TELETEX1;
+ else if (!strncasecmp("teletex2", p, 8))
+ cond->integer_value = INFO_HLC_TELETEX2;
+ else if (!strncasecmp("teletex3", p, 8))
+ cond->integer_value = INFO_HLC_TELETEX3;
+ else if (!strncasecmp("videotex1", p, 9))
+ cond->integer_value = INFO_HLC_VIDEOTEX1;
+ else if (!strncasecmp("videotex2", p, 9))
+ cond->integer_value = INFO_HLC_VIDEOTEX2;
+ else if (!strncasecmp("telex", p, 5))
+ cond->integer_value = INFO_HLC_TELEX;
+ else if (!strncasecmp("mhs", p, 3))
+ cond->integer_value = INFO_HLC_MHS;
+ else if (!strncasecmp("osi", p, 3))
+ cond->integer_value = INFO_HLC_OSI;
+ else if (!strncasecmp("maintenance", p, 11))
+ cond->integer_value = INFO_HLC_MAINTENANCE;
+ else if (!strncasecmp("management", p, 10))
+ cond->integer_value = INFO_HLC_MANAGEMENT;
+ else if (!strncasecmp("audiovisual", p, 11))
+ cond->integer_value = INFO_HLC_AUDIOVISUAL;
+ else {
+ SPRINT(failure, "Given HLC type is invalid or misspelled.");
+ goto parse_error;
+ }
+ cond->value_type = VALUE_TYPE_INTEGER;
+ break;
+
/* parse interface attribute <if>:<value> */
case COND_TYPE_IFATTR:
key[0] = key_to[0] = '\0';
@@ -1532,6 +1573,7 @@ struct route_ruleset *ruleset_parse(void)
case PARAM_TYPE_CALLERIDTYPE:
case PARAM_TYPE_CAPABILITY:
case PARAM_TYPE_BMODE:
+ case PARAM_TYPE_HLC:
case PARAM_TYPE_DIVERSION:
case PARAM_TYPE_DESTIN:
case PARAM_TYPE_TYPE:
@@ -1623,6 +1665,67 @@ struct route_ruleset *ruleset_parse(void)
SPRINT(failure, "Bchannel mode '%s' unknown.", key);
goto parse_error;
}
+ if (param_defs[index].type == PARAM_TYPE_HLC) {
+ param->value_type = VALUE_TYPE_INTEGER;
+ if (!strcasecmp(key, "telephony")) {
+ param->integer_value = INFO_HLC_TELEPHONY;
+ break;
+ }
+ if (!strcasecmp(key, "faxg2g3")) {
+ param->integer_value = INFO_HLC_FAXG2G3;
+ break;
+ }
+ if (!strcasecmp(key, "faxg4")) {
+ param->integer_value = INFO_HLC_FAXG4;
+ break;
+ }
+ if (!strcasecmp(key, "teletex1")) {
+ param->integer_value = INFO_HLC_TELETEX1;
+ break;
+ }
+ if (!strcasecmp(key, "teletex2")) {
+ param->integer_value = INFO_HLC_TELETEX2;
+ break;
+ }
+ if (!strcasecmp(key, "teletex3")) {
+ param->integer_value = INFO_HLC_TELETEX3;
+ break;
+ }
+ if (!strcasecmp(key, "videotex1")) {
+ param->integer_value = INFO_HLC_VIDEOTEX1;
+ break;
+ }
+ if (!strcasecmp(key, "videotex2")) {
+ param->integer_value = INFO_HLC_VIDEOTEX2;
+ break;
+ }
+ if (!strcasecmp(key, "telex")) {
+ param->integer_value = INFO_HLC_TELEX;
+ break;
+ }
+ if (!strcasecmp(key, "mhs")) {
+ param->integer_value = INFO_HLC_MHS;
+ break;
+ }
+ if (!strcasecmp(key, "osi")) {
+ param->integer_value = INFO_HLC_OSI;
+ break;
+ }
+ if (!strcasecmp(key, "maintenance")) {
+ param->integer_value = INFO_HLC_MAINTENANCE;
+ break;
+ }
+ if (!strcasecmp(key, "management")) {
+ param->integer_value = INFO_HLC_MANAGEMENT;
+ break;
+ }
+ if (!strcasecmp(key, "audiovisual")) {
+ param->integer_value = INFO_HLC_AUDIOVISUAL;
+ break;
+ }
+ SPRINT(failure, "HLC type '%s' unknown.", key);
+ goto parse_error;
+ }
if (param_defs[index].type == PARAM_TYPE_DIVERSION) {
param->value_type = VALUE_TYPE_INTEGER;
if (!strcasecmp(key, "cfu")) {
@@ -1791,12 +1894,14 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
int integer;
char *string;
FILE *tfp;
- double timeout;
+ long long timeout, now_ll = 0, match_timeout = 0;
+ struct timeval current_time;
struct mISDNport *mISDNport;
struct admin_list *admin;
+ time_t now;
+ struct tm *now_tm;
/* reset timeout action */
- e_match_timeout = 0; /* no timeout */
e_match_to_action = NULL;
SCPY(callerid, numberrize_callerinfo(e_callerinfo.id, e_callerinfo.ntype, options.national, options.international));
@@ -1910,22 +2015,32 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
goto match_string_prefix;
case MATCH_TIME:
+ time(&now);
+ now_tm = localtime(&now);
integer = now_tm->tm_hour*100 + now_tm->tm_min;
goto match_integer;
case MATCH_MDAY:
+ time(&now);
+ now_tm = localtime(&now);
integer = now_tm->tm_mday;
goto match_integer;
case MATCH_MONTH:
+ time(&now);
+ now_tm = localtime(&now);
integer = now_tm->tm_mon+1;
goto match_integer;
case MATCH_YEAR:
+ time(&now);
+ now_tm = localtime(&now);
integer = now_tm->tm_year + 1900;
goto match_integer;
case MATCH_WDAY:
+ time(&now);
+ now_tm = localtime(&now);
integer = now_tm->tm_wday;
integer = integer?integer:7; /* correct sunday */
goto match_integer;
@@ -1963,7 +2078,11 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
break;
case MATCH_TIMEOUT:
- timeout = now_d + cond->integer_value;
+ if (!now_ll) {
+ gettimeofday(&current_time, NULL);
+ now_ll = current_time.tv_sec * MICRO_SECONDS + current_time.tv_usec;
+ }
+ timeout = now_ll + (cond->integer_value * MICRO_SECONDS);
istrue = 1;
break;
@@ -2166,10 +2285,10 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
cond = cond->next;
}
- if (timeout>now_d && match==1) /* the matching rule with timeout in the future */
- if (e_match_timeout<1 || timeout<e_match_timeout) { /* first timeout or lower */
+ if (timeout>now_ll && match==1) /* the matching rule with timeout in the future */
+ if (match_timeout == 0 || timeout < match_timeout) { /* first timeout or lower */
/* set timeout in the furture */
- e_match_timeout = timeout;
+ match_timeout = timeout;
e_match_to_action = rule->action_first;
e_match_to_extdialing = e_dialinginfo.id + dialing_required;
match = 0; /* matches in the future */
@@ -2177,7 +2296,7 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
if (match == 1) {
/* matching, we return first action */
action = rule->action_first;
- e_match_timeout = 0; /* no timeout */
+ match_timeout = 0; /* no timeout */
e_match_to_action = NULL;
e_extdialing = e_dialinginfo.id + dialing_required;
break;
@@ -2188,6 +2307,11 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
}
rule = rule->next;
}
+ if (match_timeout == 0)
+ unsched_timer(&e_match_timeout); /* no timeout */
+ else {
+ schedule_timer(&e_match_timeout, match_timeout / 1000000, match_timeout % 1000000);
+ }
return(action);
}