"interface=<interface>[,...]", "Matches if call is received from given interface(s). NOT PORTS!"},
{ "callerid", MATCH_CALLERID, COND_TYPE_STRING,
"callerid=<digits>[-<digits>][,...]", "Matches if caller ID matches or begins with the given (range(s) of) prefixes(s)."},
+ { "callerid2", MATCH_CALLERID2,COND_TYPE_STRING,
+ "callerid2=<digits>[-<digits>][,...]", "Matches the second caller ID (network provided)."},
{ "extension", MATCH_EXTENSION,COND_TYPE_STRING,
"extension=<digits>[-<digits>][,...]", "Matches if caller calls from given (range(s) of) extension(s)."},
{ "dialing", MATCH_DIALING, COND_TYPE_STRING,
"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,
"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."},
{ PARAM_EXTEN,
"exten", PARAM_TYPE_STRING,
"exten=<extension>", "Give exten parameter to the remote application. (overrides dialed number)"},
+ { PARAM_ON,
+ "on", PARAM_TYPE_STRING,
+ "on=[init|hangup]", "Defines if the action is executed on call init or on hangup."},
+ { PARAM_KEYPAD,
+ "keypad", PARAM_TYPE_NULL,
+ "keypad", "Use 'keypad facility' for dialing, instead of 'called number'."},
{ 0, NULL, 0, NULL, NULL}
};
struct action_defs action_defs[] = {
{ ACTION_EXTERNAL,
"extern", &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call,
- PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_TIMEOUT,
+ PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_KEYPAD | PARAM_TIMEOUT,
"Call is routed to extern number as dialed."},
{ ACTION_INTERNAL,
"intern", &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_internal, &EndpointAppPBX::action_hangup_call,
"Call is routed to intern extension as given by the dialed number or specified by option."},
{ ACTION_OUTDIAL,
"outdial", &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call,
- PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_TIMEOUT,
+ PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_KEYPAD | PARAM_TIMEOUT,
"Same as 'extern'"},
{ ACTION_REMOTE,
"remote", &EndpointAppPBX::action_init_remote, &EndpointAppPBX::action_dialing_remote, &EndpointAppPBX::action_hangup_call,
// "Caller calls the timer."},
{ ACTION_GOTO,
"goto", NULL, &EndpointAppPBX::action_dialing_goto, NULL,
- PARAM_CONNECT | PARAM_RULESET | PARAM_STRIP | PARAM_SAMPLE,
+ PARAM_PROCEEDING | PARAM_ALERTING | PARAM_CONNECT | PARAM_RULESET | PARAM_STRIP | PARAM_SAMPLE,
"Jump to given ruleset and optionally play sample. Dialed digits are not flushed."},
{ ACTION_MENU,
"menu", NULL, &EndpointAppPBX::action_dialing_menu, NULL,
"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,
NULL},
// "The call forward is set within the telephone network of the external line."},
{ ACTION_EXECUTE,
- "execute", NULL, NULL, &EndpointAppPBX::action_hangup_execute,
- PARAM_CONNECT | PARAM_EXECUTE | PARAM_PARAM,
+ "execute", &EndpointAppPBX::action_init_execute, NULL, &EndpointAppPBX::action_hangup_execute,
+ 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,
{
int i, j;
- if (name)
- {
+ if (name) {
i = 0;
- while(action_defs[i].name)
- {
+ while(action_defs[i].name) {
if (!strcasecmp(action_defs[i].name, name))
break;
i++;
}
- if (!action_defs[i].name)
- {
+ if (!action_defs[i].name) {
fprintf(stderr, "Given action '%s' unknown.\n", name);
return;
}
printf("...\n");
printf("Please refer to the documentation for description on rule format.\n\n");
- if (!name)
- {
+ if (!name) {
printf("Available conditions to match:\n");
printf("------------------------------\n\n");
i = 0;
- while(cond_defs[i].name)
- {
+ while(cond_defs[i].name) {
printf("Usage: %s\n", cond_defs[i].doc);
printf("%s\n\n", cond_defs[i].help);
i++;
printf("Available actions with their parameters:\n");
printf("----------------------------------------\n\n");
- } else
- {
+ } else {
printf("Detailes parameter description of action:\n");
printf("-----------------------------------------\n\n");
}
i = 0;
- while(action_defs[i].name)
- {
- if (name && !!strcmp(action_defs[i].name,name)) /* not selected */
- {
+ while(action_defs[i].name) {
+ if (name && !!strcmp(action_defs[i].name,name)) { /* not selected */
i++;
continue;
}
- if (!action_defs[i].help) /* not internal actions */
- {
+ if (!action_defs[i].help) { /* not internal actions */
i++;
continue;
}
printf("Usage: %s", action_defs[i].name);
j = 0;
- while(j < 64)
- {
+ while(j < 64) {
if ((1LL<<j) & action_defs[i].params)
printf(" [%s]", param_defs[j].doc);
j++;
}
printf("\n%s\n\n", action_defs[i].help);
- if (name) /* only show parameter help for specific action */
- {
+ if (name) { /* only show parameter help for specific action */
j = 0;
- while(j < 64)
- {
+ while(j < 64) {
if ((1LL<<j) & action_defs[i].params)
printf("%s:\n\t%s\n", param_defs[j].doc, param_defs[j].help);
j++;
struct route_action *action;
struct route_param *param;
- while(ruleset_start)
- {
+ while(ruleset_start) {
ruleset = ruleset_start;
ruleset_start = ruleset->next;
- while(ruleset->rule_first)
- {
+ while(ruleset->rule_first) {
rule = ruleset->rule_first;
ruleset->rule_first = rule->next;
- while(rule->cond_first)
- {
+ while(rule->cond_first) {
cond = rule->cond_first;
- if (cond->string_value)
- {
+ if (cond->string_value) {
FREE(cond->string_value, 0);
rmemuse--;
}
- if (cond->string_value_to)
- {
+ if (cond->string_value_to) {
FREE(cond->string_value_to, 0);
rmemuse--;
}
FREE(cond, sizeof(struct route_cond));
rmemuse--;
}
- while(rule->action_first)
- {
+ while(rule->action_first) {
action = rule->action_first;
rule->action_first = action->next;
- while(action->param_first)
- {
+ while(action->param_first) {
param = action->param_first;
action->param_first = param->next;
- if (param->string_value)
- {
+ if (param->string_value) {
FREE(param->string_value, 0);
rmemuse--;
}
int first;
ruleset = ruleset_start;
- while(ruleset)
- {
+ while(ruleset) {
printf("Ruleset: '%s'\n", ruleset->name);
rule = ruleset->rule_first;
- while(rule)
- {
+ while(rule) {
/* CONDITION */
first = 1;
cond = rule->cond_first;
- while(cond)
- {
+ while(cond) {
if (first)
printf(" Condition:");
else
if (cond->value_type != VALUE_TYPE_NULL)
printf(" = ");
next_cond_value:
- switch(cond->value_type)
- {
+ switch(cond->value_type) {
case VALUE_TYPE_NULL:
break;
default:
printf("Software error: VALUE_TYPE_* %d not known in function '%s' line=%d", cond->value_type, __FUNCTION__, __LINE__);
}
- if (cond->value_extension && cond->next)
- {
+ if (cond->value_extension && cond->next) {
cond = cond->next;
printf(" or ");
goto next_cond_value;
/* ACTION */
action = rule->action_first;
- while(action)
- {
+ while(action) {
printf(" Action: %s\n", action_defs[action->index].name);
/* PARAM */
first = 1;
param = action->param_first;
- while(param)
- {
+ while(param) {
if (first)
printf(" Param:");
else
printf(" %s", param_defs[param->index].name);
if (param->value_type != VALUE_TYPE_NULL)
printf(" = ");
- switch(param->value_type)
- {
+ switch(param->value_type) {
case VALUE_TYPE_NULL:
break;
case VALUE_TYPE_INTEGER:
- if (param_defs[param->index].type == PARAM_TYPE_CALLERIDTYPE)
- {
- switch(param->integer_value)
- {
+ if (param_defs[param->index].type == PARAM_TYPE_CALLERIDTYPE) {
+ switch(param->integer_value) {
case INFO_NTYPE_UNKNOWN:
printf("unknown");
break;
}
break;
}
- if (param_defs[param->index].type == PARAM_TYPE_CAPABILITY)
- {
- switch(param->integer_value)
- {
+ if (param_defs[param->index].type == PARAM_TYPE_CAPABILITY) {
+ switch(param->integer_value) {
case INFO_BC_SPEECH:
printf("speech");
break;
}
break;
}
- if (param_defs[param->index].type == PARAM_TYPE_DIVERSION)
- {
- switch(param->integer_value)
- {
+ if (param_defs[param->index].type == PARAM_TYPE_DIVERSION) {
+ switch(param->integer_value) {
case INFO_DIVERSION_CFU:
printf("cfu");
break;
}
break;
}
- if (param_defs[param->index].type == PARAM_TYPE_TYPE)
- {
- switch(param->integer_value)
- {
+ if (param_defs[param->index].type == PARAM_TYPE_TYPE) {
+ switch(param->integer_value) {
case INFO_NTYPE_UNKNOWN:
printf("unknown");
break;
}
break;
}
- if (param_defs[param->index].type == PARAM_TYPE_YESNO)
- {
- switch(param->integer_value)
- {
+ if (param_defs[param->index].type == PARAM_TYPE_YESNO) {
+ switch(param->integer_value) {
case 1:
printf("yes");
break;
}
break;
}
- if (param_defs[param->index].type == PARAM_TYPE_NULL)
- {
+ if (param_defs[param->index].type == PARAM_TYPE_NULL) {
break;
}
printf("%d", param->integer_value);
/*
* parse ruleset
*/
-static char *read_string(char *p, char *key, int key_size, char *special)
+static char *read_string(char *p, char *key, int key_size, const char *special)
{
key[0] = 0;
- if (*p == '\"')
- {
+ if (*p == '\"') {
p++;
/* quote */
- while(*p)
- {
- if (*p == '\"')
- {
+ while(*p) {
+ if (*p == '\"') {
p++;
*key = '\0';
return(p);
}
- if (*p == '\\')
- {
+ if (*p == '\\') {
p++;
- if (*p == '\0')
- {
+ if (*p == '\0') {
break;
}
}
- if (--key_size == 0)
- {
+ if (--key_size == 0) {
UPRINT(key, "\001String too long.");
return(p);
}
}
/* no quote */
- while(*p)
- {
- if (strchr(special, *p))
- {
+ while(*p) {
+ if (strchr(special, *p)) {
*key = '\0';
return(p);
}
- if (*p == '\\')
- {
+ if (*p == '\\') {
p++;
- if (*p == '\0')
- {
+ if (*p == '\0') {
UPRINT(key, "\001Unexpected end of line.");
return(p);
}
}
- if (--key_size == 0)
- {
+ if (--key_size == 0) {
UPRINT(key, "\001String too long.");
return(p);
}
/* check the integrity of IDs for ACTION_* and PARAM_* */
i = 0;
- while(action_defs[i].name)
- {
- if (action_defs[i].id != i)
- {
+ while(action_defs[i].name) {
+ if (action_defs[i].id != i) {
PERROR("Software Error action '%s' must have id of %d, but has %d.\n",
action_defs[i].name, i, action_defs[i].id);
goto openerror;
i++;
}
i = 0; j = 1;
- while(param_defs[i].name)
- {
- if (param_defs[i].id != j)
- {
+ while(param_defs[i].name) {
+ if (param_defs[i].id != j) {
PERROR("Software Error param '%s' must have id of 0x%llx, but has 0x%llx.\n",
param_defs[i].name, j, param_defs[i].id);
goto openerror;
j<<=1;
}
- SPRINT(filename[0], "%s/routing.conf", INSTALL_DATA);
+ SPRINT(filename[0], "%s/routing.conf", CONFIG_DATA);
if (!(fp[0]=fopen(filename[0],"r")))
{
go_leaf:
line[nesting]=0;
go_root:
- while((fgets(buffer,sizeof(buffer),fp[nesting])))
+ while((GETLINE(buffer, fp[nesting])))
{
line[nesting]++;
- buffer[sizeof(buffer)-1]=0;
- if (buffer[0]) buffer[strlen(buffer)-1]=0;
p = buffer;
/* remove tabs */
}
/* skip comments */
- if (*p == '#')
- {
+ if (*p == '#') {
p++;
/* don't skip "define" */
if (!!strncmp(p, "define", 6))
if (*p != 32)
continue;
/* skip spaces */
- while(*p == 32)
- {
+ while(*p == 32) {
if (*p == 0)
break;
p++;
}
p++;
p = read_string(p, key, sizeof(key), " ");
- if (key[0] == 1) /* error */
- {
+ if (key[0] == 1) { /* error */
SPRINT(failure, "Parsing Filename failed: %s", key+1);
goto parse_error;
}
- if (nesting == MAXNESTING-1)
- {
+ if (nesting == MAXNESTING-1) {
SPRINT(failure, "'include' is nesting too deep.\n");
goto parse_error;
}
if (key[0] == '/')
SCPY(filename[nesting+1], key);
else
- SPRINT(filename[nesting+1], "%s/%s", INSTALL_DATA, key);
- if (!(fp[nesting+1]=fopen(filename[nesting+1],"r")))
- {
+ SPRINT(filename[nesting+1], "%s/%s", CONFIG_DATA, key);
+ if (!(fp[nesting+1]=fopen(filename[nesting+1],"r"))) {
PERROR("Cannot open %s\n", filename[nesting+1]);
goto parse_error;
}
continue;
/* expecting ruleset */
- if (expecting)
- {
+ if (expecting) {
new_ruleset:
/* expecting [ */
- if (*p != '[')
- {
+ if (*p != '[') {
SPRINT(failure, "Expecting ruleset name starting with '['.");
goto parse_error;
}
/* reading ruleset name text */
i = 0;
- while(*p>' ' && *p<127 && *p!=']')
- {
+ while(*p>' ' && *p<127 && *p!=']') {
if (*p>='A' && *p<='Z') *p = *p-'A'+'a'; /* lower case */
key[i++] = *p++;
if (i == sizeof(key)) i--; /* limit */
/* check for duplicate rulesets */
ruleset = ruleset_start;
- while(ruleset)
- {
- if (!strcmp(ruleset->name, key))
- {
+ while(ruleset) {
+ if (!strcmp(ruleset->name, key)) {
SPRINT(failure, "Duplicate ruleset '%s', already defined in file '%s' line %d.", key, ruleset->file, ruleset->line);
goto parse_error;
}
}
/* for new ruleset [ */
- if (*p == '[')
- {
+ if (*p == '[') {
goto new_ruleset;
}
rule->line = line[nesting];
/* loop CONDITIONS */
- while(*p!=':' && *p!='\0')
- {
+ while(*p!=':' && *p!='\0') {
/* read item text */
i = 0;
- while((*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9'))
- {
+ while((*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9')) {
if (*p>='A' && *p<='Z') *p = *p-'A'+'a'; /* lower case */
key[i++] = *p++;
if (i == sizeof(key)) i--; /* limit */
}
key[i] = 0;
- if (key[0] == '\0')
- {
+ if (key[0] == '\0') {
SPRINT(failure, "Expecting condition item name or ':' for end of condition list.");
goto parse_error;
}
- if (*p!=' ' && *p!='=')
- {
+ if (*p!=' ' && *p!='=') {
SPRINT(failure, "Illegal character '%c' after condition name '%s'. Expecting '=' for equation or ' ' to seperate condition items.", *p, key);
goto parse_error;
}
/* check if condition exists */
index = 0;
- while(cond_defs[index].name)
- {
+ while(cond_defs[index].name) {
if (!strcmp(cond_defs[index].name, key))
break;
index++;
}
- if (cond_defs[index].name == NULL)
- {
+ if (cond_defs[index].name == NULL) {
SPRINT(failure, "Unknown condition item name '%s'.", key);
goto parse_error;
}
/* items without values must not have any parameter */
- if (cond_defs[index].type == COND_TYPE_NULL)
- {
- if (*p == '=')
- {
+ if (cond_defs[index].type == COND_TYPE_NULL) {
+ if (*p == '=') {
SPRINT(failure, "Condition item '%s' must not have any value. Don't use '=' for this type of condition.", key);
goto parse_error;
}
- if (*p != ' ')
- {
+ if (*p != ' ') {
SPRINT(failure, "Condition item '%s' must not have any value. Expecting ' ' or tab after item name.", key);
goto parse_error;
}
// p++;
- } else
- {
- if (*p == ' ')
- {
+ } else {
+ if (*p == ' ') {
SPRINT(failure, "Condition item '%s' must have at least one value, '=' expected, and not a space.", key);
goto parse_error;
}
- if (*p != '=')
- {
+ if (*p != '=') {
SPRINT(failure, "Condition item '%s' must have at least one value, '=' expected.", key);
goto parse_error;
}
/* check for duplicate condition */
cond = rule->cond_first;
- while(cond)
- {
- if (cond->index == index)
- {
+ while(cond) {
+ if (cond->index == index) {
SPRINT(failure, "Duplicate condition '%s', use ',' to give multiple values.", key);
goto parse_error;
}
cond_pointer = &(cond->next);
cond->index = index;
cond->match = cond_defs[index].match;
- switch(cond_defs[index].type)
- {
+ switch(cond_defs[index].type) {
case COND_TYPE_NULL:
- if (*p=='=')
- {
+ if (*p=='=') {
SPRINT(failure, "Expecting no value.");
goto parse_error;
}
case COND_TYPE_WDAY:
case COND_TYPE_YEAR:
integer = integer_to = 0;
- if (*p==',' || *p==' ' || *p=='\0')
- {
+ if (*p==',' || *p==' ' || *p=='\0') {
SPRINT(failure, "Missing integer value.");
goto parse_error;
}
- while(*p>='0' && *p<='9')
- {
+ while(*p>='0' && *p<='9') {
integer = integer*10 + *p-'0';
p++;
}
value_type = VALUE_TYPE_INTEGER;
- if (*p == '-')
- {
+ if (*p == '-') {
p++;
- if (*p==',' || *p==' ' || *p=='\0')
- {
+ if (*p==',' || *p==' ' || *p=='\0') {
SPRINT(failure, "Missing integer value.");
goto parse_error;
}
- while(*p>='0' && *p<='9')
- {
+ while(*p>='0' && *p<='9') {
integer_to = integer_to*10 + *p-'0';
p++;
}
value_type = VALUE_TYPE_INTEGER_RANGE;
}
- if (cond_defs[index].type == COND_TYPE_TIME)
- {
+ if (cond_defs[index].type == COND_TYPE_TIME) {
// Simon: i store the time as decimal, later i compare it correctly:
// hours * 100 + minutes
if (integer == 2400)
integer = 0;
- if (integer >= 2400)
- {
+ if (integer >= 2400) {
timeoutofrange1:
SPRINT(failure, "Given time '%d' not in range 0000..2359 (or 2400 for 0000)", integer);
goto parse_error;
goto integer_done;
if (integer_to == 2400)
integer_to = 0;
- if (integer_to >= 2400)
- {
+ if (integer_to >= 2400) {
timeoutofrange2:
SPRINT(failure, "Given time '%d' not in range 0000..2359 (or 2400 for 0000)", integer_to);
goto parse_error;
if (integer_to%100 >= 60)
goto timeoutofrange2;
}
- if (cond_defs[index].type == COND_TYPE_MDAY)
- {
- if (integer<1 || integer>31)
- {
+ if (cond_defs[index].type == COND_TYPE_MDAY) {
+ if (integer<1 || integer>31) {
SPRINT(failure, "Given day-of-month '%d' not in range 1..31", integer);
goto parse_error;
}
if (value_type == VALUE_TYPE_INTEGER)
goto integer_done;
- if (integer_to<1 || integer_to>31)
- {
+ if (integer_to<1 || integer_to>31) {
SPRINT(failure, "Given day-of-month '%d' not in range 1..31", integer_to);
goto parse_error;
}
}
- if (cond_defs[index].type == COND_TYPE_WDAY)
- {
- if (integer<1 || integer>7)
- {
+ if (cond_defs[index].type == COND_TYPE_WDAY) {
+ if (integer<1 || integer>7) {
SPRINT(failure, "Given day-of-week '%d' not in range 1..7", integer);
goto parse_error;
}
if (value_type == VALUE_TYPE_INTEGER)
goto integer_done;
- if (integer_to<1 || integer_to>7)
- {
+ if (integer_to<1 || integer_to>7) {
SPRINT(failure, "Given day-of-week '%d' not in range 1..7", integer_to);
goto parse_error;
}
}
- if (cond_defs[index].type == COND_TYPE_MONTH)
- {
- if (integer<1 || integer>12)
- {
+ if (cond_defs[index].type == COND_TYPE_MONTH) {
+ if (integer<1 || integer>12) {
SPRINT(failure, "Given month '%d' not in range 1..12", integer);
goto parse_error;
}
if (value_type == VALUE_TYPE_INTEGER)
goto integer_done;
- if (integer_to<1 || integer_to>12)
- {
+ if (integer_to<1 || integer_to>12) {
SPRINT(failure, "Given month '%d' not in range 1..12", integer_to);
goto parse_error;
}
}
- if (cond_defs[index].type == COND_TYPE_YEAR)
- {
- if (integer<1970 || integer>2106)
- {
+ if (cond_defs[index].type == COND_TYPE_YEAR) {
+ if (integer<1970 || integer>2106) {
SPRINT(failure, "Given year '%d' not in range 1970..2106", integer);
goto parse_error;
}
if (value_type == VALUE_TYPE_INTEGER)
goto integer_done;
- if (integer_to<1970 || integer_to>2106)
- {
+ if (integer_to<1970 || integer_to>2106) {
SPRINT(failure, "Given year '%d' not in range 1970..2106", integer_to);
goto parse_error;
}
/* parse all string values/ranges */
case COND_TYPE_STRING:
key[0] = key_to[0] = '\0';
- if (*p==',' || *p==' ' || *p=='\0')
- {
+ if (*p==',' || *p==' ' || *p=='\0') {
SPRINT(failure, "Missing string value, use \"\" for empty string.");
goto parse_error;
}
p = read_string(p, key, sizeof(key), "-, ");
- if (key[0] == 1) /* error */
- {
+ if (key[0] == 1) { /* error */
SPRINT(failure, "Parsing String failed: %s", key+1);
goto parse_error;
}
value_type = VALUE_TYPE_STRING;
- if (*p == '-')
- {
+ if (*p == '-') {
p++;
- if (*p==',' || *p==' ' || *p=='\0')
- {
+ if (*p==',' || *p==' ' || *p=='\0') {
SPRINT(failure, "Missing string value, use \"\" for empty string.");
goto parse_error;
}
p = read_string(p, key_to, sizeof(key_to), "-, ");
- if (key_to[0] == 1) /* error */
- {
+ if (key_to[0] == 1) { /* error */
SPRINT(failure, "Parsing string failed: %s", key_to+1);
goto parse_error;
}
value_type = VALUE_TYPE_STRING_RANGE;
- if (strlen(key) != strlen(key_to))
- {
+ if (strlen(key) != strlen(key_to)) {
SPRINT(failure, "Given range of strings \"%s\"-\"%s\" have unequal length.", key, key_to);
goto parse_error;
}
- if (key[0] == '\0')
- {
+ if (key[0] == '\0') {
SPRINT(failure, "Given range has no length.");
goto parse_error;
}
cond->string_value = (char *)MALLOC(strlen(key)+1);
rmemuse++;
UCPY(cond->string_value, key);
- if (value_type == VALUE_TYPE_STRING_RANGE)
- {
+ if (value_type == VALUE_TYPE_STRING_RANGE) {
cond->string_value_to = (char *)MALLOC(strlen(key_to)+1);
rmemuse++;
UCPY(cond->string_value_to, key_to);
cond->integer_value = INFO_BC_DATAUNRESTRICTED;
else if (!strncasecmp("digital-unrestricted-tones", p, 26))
cond->integer_value = INFO_BC_DATAUNRESTRICTED_TONES;
- else
- {
+ else {
SPRINT(failure, "Given service type is invalid or misspelled.");
goto parse_error;
}
cond->integer_value = INFO_BMODE_CIRCUIT;
else if (!strncasecmp("hdlc", p, 4))
cond->integer_value = INFO_BMODE_PACKET;
- else
- {
+ else {
SPRINT(failure, "Given bchannel mode is invalid or misspelled.");
goto parse_error;
}
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';
- if (*p==':' || *p==',' || *p==' ' || *p=='\0')
- {
+ if (*p==':' || *p==',' || *p==' ' || *p=='\0') {
SPRINT(failure, "Missing interface name.");
goto parse_error;
}
p = read_string(p, key, sizeof(key), ":-, ");
- if (key[0] == 1) /* error */
- {
+ if (key[0] == 1) { /* error */
SPRINT(failure, "Parsing interface failed: %s", key+1);
goto parse_error;
}
- if (*p != ':')
- {
+ if (*p != ':') {
SPRINT(failure, "Expeciting kolon to seperate value behind interface name.");
goto parse_error;
}
SCCAT(key, *p++);
- while(*p>='0' && *p<='9')
- {
+ while(*p>='0' && *p<='9') {
SCCAT(key, *p++);
}
- if (*p!=',' && *p!=' ' && *p!='\0')
- {
+ if (*p!=',' && *p!=' ' && *p!='\0') {
SPRINT(failure, "Invalid characters behind value.");
goto parse_error;
}
goto parse_error;
}
/* if we have another value for that item, we attach it */
- if (*p == ',')
- {
+ if (*p == ',') {
p++;
/* next item */
cond->value_extension = 1;
goto nextcondvalue;
}
/* to seperate the items, a space is required */
- if (*p != ' ')
- {
+ if (*p != ' ') {
SPRINT(failure, "Character '%c' not expected here. Use ',' to seperate multiple possible values.", *p);
goto parse_error;
}
}
/* we are done with CONDITIONS, so we expect the ACTION */
- if (*p != ':')
- {
+ if (*p != ':') {
SPRINT(failure, "Expecting ':' after condition item(s).");
goto parse_error;
}
/* read action name */
i = 0;
- while((*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9') || *p == '-')
- {
+ while((*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9') || *p == '-') {
if (*p>='A' && *p<='Z') *p = *p-'A'+'a'; /* lower case */
key[i++] = *p++;
if (i == sizeof(key)) i--; /* limit */
/* check if item exists */
index = 0;
- while(action_defs[index].name)
- {
- if (!action_defs[index].help) /* not internal actions */
- {
+ while(action_defs[index].name) {
+ if (!action_defs[index].help) { /* not internal actions */
index++;
continue;
}
break;
index++;
}
- if (action_defs[index].name == NULL)
- {
+ if (action_defs[index].name == NULL) {
SPRINT(failure, "Unknown action name '%s'.", key);
goto parse_error;
}
}
/* loop PARAMS */
- while(*p != 0)
- {
+ while(*p != 0) {
/* read param text */
i = 0;
- while((*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9'))
- {
+ while((*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9')) {
if (*p>='A' && *p<='Z') *p = *p-'A'+'a'; /* lower case */
key[i++] = *p++;
if (i == sizeof(key)) i--; /* limit */
/* check if item exists */
index = 0;
- while(param_defs[index].name)
- {
+ while(param_defs[index].name) {
if (!strcmp(param_defs[index].name, key))
break;
index++;
}
- if (param_defs[index].name == NULL)
- {
+ if (param_defs[index].name == NULL) {
SPRINT(failure, "Unknown param name '%s'.", key);
goto parse_error;
}
/* check if item is allowed for the action */
- if (!(param_defs[index].id & allowed_params))
- {
+ if (!(param_defs[index].id & allowed_params)) {
SPRINT(failure, "Param name '%s' exists, but not for this action.", key);
goto parse_error;
}
/* params without values must not have any parameter */
- if (param_defs[index].type == PARAM_TYPE_NULL)
- {
- if (*p!=' ' && *p!='\0')
- {
+ if (param_defs[index].type == PARAM_TYPE_NULL) {
+ if (*p!=' ' && *p!='\0') {
SPRINT(failure, "Parameter '%s' must not have any value.", key);
goto parse_error;
}
- } else
- {
- if (*p == ' ')
- {
+ } else {
+ if (*p == ' ') {
SPRINT(failure, "Parameter '%s' must have at least one value, '=' expected and not a space.", key);
goto parse_error;
}
- if (*p != '=')
- {
+ if (*p != '=') {
SPRINT(failure, "Parameter '%s' must have at least one value, '=' expected.", key);
goto parse_error;
}
}
/* special timeout value */
- if (!strcmp("timeout", key))
- {
- if (action->timeout)
- {
+ if (!strcmp("timeout", key)) {
+ if (action->timeout) {
SPRINT(failure, "Duplicate timeout value.");
goto parse_error;
}
- if (*p==',' || *p==' ' || *p=='\0')
- {
+ if (*p==',' || *p==' ' || *p=='\0') {
SPRINT(failure, "Missing integer value.");
goto parse_error;
}
integer = 0;
- while(*p>='0' && *p<='9')
- {
+ while(*p>='0' && *p<='9') {
integer = integer*10 + *p-'0';
p++;
}
- if (integer < 1)
- {
+ if (integer < 1) {
SPRINT(failure, "Expecting timeout value greater 0.");
goto parse_error;
}
- if (*p!=' ' && *p!='\0')
- {
+ if (*p!=' ' && *p!='\0') {
SPRINT(failure, "Character '%c' not expected here. Use ' ' to seperate parameters.", *p);
goto parse_error;
}
/* skip spaces */
- while(*p == 32)
- {
+ while(*p == 32) {
if (*p == 0)
break;
p++;
}
action->timeout = integer;
/* check for next ACTION */
- if (*p == ':')
- {
+ if (*p == ':') {
p++;
goto nextaction;
}
/* check for duplicate parameters */
param = action->param_first;
- while(param)
- {
- if (param->index == index)
- {
+ while(param) {
+ if (param->index == index) {
SPRINT(failure, "Duplicate parameter '%s', use ',' to give multiple values.", key);
goto parse_error;
}
param->index = index;
param->id = param_defs[index].id;
- switch(param_defs[index].type)
- {
+ switch(param_defs[index].type) {
/* parse null value */
case PARAM_TYPE_NULL:
param->value_type = VALUE_TYPE_NULL;
/* parse integer value */
case PARAM_TYPE_INTEGER:
integer = 0;
- if (*p==',' || *p==' ' || *p=='\0')
- {
+ if (*p==',' || *p==' ' || *p=='\0') {
SPRINT(failure, "Missing integer value.");
goto parse_error;
}
- while(*p>='0' && *p<='9')
- {
+ while(*p>='0' && *p<='9') {
integer = integer*10 + *p-'0';
p++;
}
/* parse ports value */
case PARAM_TYPE_PORTS:
key[0] = '\0';
- if (*p==',' || *p==' ' || *p=='\0')
- {
+ if (*p==',' || *p==' ' || *p=='\0') {
SPRINT(failure, "Missing port number, omit parameter or give port number.");
goto parse_error;
}
i = 0;
nextport:
integer = 0;
- while(*p>='0' && *p<='9')
- {
- if (i < (int)sizeof(key)-1)
- {
+ while(*p>='0' && *p<='9') {
+ if (i < (int)sizeof(key)-1) {
key[i] = *p;
key[i++] = '\0';
}
integer = integer*10 + *p-'0';
p++;
}
- if (integer > 255)
- {
+ if (integer > 255) {
SPRINT(failure, "Port number too high.");
goto parse_error;
}
- if (*p==',')
- {
- if (i < (int)sizeof(key)-1)
- {
+ if (*p==',') {
+ if (i < (int)sizeof(key)-1) {
key[i] = *p;
key[i++] = '\0';
}
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:
case PARAM_TYPE_YESNO:
+ case PARAM_TYPE_ON:
key[0] = '\0';
- if (*p==',' || *p==' ' || *p=='\0')
- {
+ if (*p==',' || *p==' ' || *p=='\0') {
SPRINT(failure, "Missing string value, use \"\" for empty string.");
goto parse_error;
}
p = read_string(p, key, sizeof(key), " ");
- if (key[0] == 1) /* error */
- {
+ if (key[0] == 1) { /* error */
SPRINT(failure, "Parsing string failed: %s", key+1);
goto parse_error;
}
- if (param_defs[index].type == PARAM_TYPE_CALLERIDTYPE)
- {
+ if (param_defs[index].type == PARAM_TYPE_CALLERIDTYPE) {
param->value_type = VALUE_TYPE_INTEGER;
- if (!strcasecmp(key, "unknown"))
- {
+ if (!strcasecmp(key, "unknown")) {
param->integer_value = INFO_NTYPE_UNKNOWN;
break;
}
- if (!strcasecmp(key, "subscriber"))
- {
+ if (!strcasecmp(key, "subscriber")) {
param->integer_value = INFO_NTYPE_SUBSCRIBER;
break;
}
- if (!strcasecmp(key, "national"))
- {
+ if (!strcasecmp(key, "national")) {
param->integer_value = INFO_NTYPE_NATIONAL;
break;
}
- if (!strcasecmp(key, "international"))
- {
+ if (!strcasecmp(key, "international")) {
param->integer_value = INFO_NTYPE_INTERNATIONAL;
break;
}
SPRINT(failure, "Caller ID type '%s' unknown.", key);
goto parse_error;
}
- if (param_defs[index].type == PARAM_TYPE_CAPABILITY)
- {
+ if (param_defs[index].type == PARAM_TYPE_ON) {
+ param->value_type = VALUE_TYPE_INTEGER;
+ if (!strcasecmp(key, "init")) {
+ param->integer_value = INFO_ON_INIT;
+ break;
+ }
+ if (!strcasecmp(key, "hangup")) {
+ param->integer_value = INFO_ON_HANGUP;
+ break;
+ }
+ SPRINT(failure, "Execute on '%s' unknown.", key);
+ goto parse_error;
+ }
+ if (param_defs[index].type == PARAM_TYPE_CAPABILITY) {
param->value_type = VALUE_TYPE_INTEGER;
- if (!strcasecmp(key, "speech"))
- {
+ if (!strcasecmp(key, "speech")) {
param->integer_value = INFO_BC_SPEECH;
break;
}
- if (!strcasecmp(key, "audio"))
- {
+ if (!strcasecmp(key, "audio")) {
param->integer_value = INFO_BC_AUDIO;
break;
}
- if (!strcasecmp(key, "video"))
- {
+ if (!strcasecmp(key, "video")) {
param->integer_value = INFO_BC_VIDEO;
break;
}
- if (!strcasecmp(key, "digital-restricted"))
- {
+ if (!strcasecmp(key, "digital-restricted")) {
param->integer_value = INFO_BC_DATARESTRICTED;
break;
}
- if (!strcasecmp(key, "digital-unrestricted"))
- {
+ if (!strcasecmp(key, "digital-unrestricted")) {
param->integer_value = INFO_BC_DATAUNRESTRICTED;
break;
}
- if (!strcasecmp(key, "digital-unrestricted-tones"))
- {
+ if (!strcasecmp(key, "digital-unrestricted-tones")) {
param->integer_value = INFO_BC_DATAUNRESTRICTED_TONES;
break;
}
SPRINT(failure, "Service type '%s' unknown.", key);
goto parse_error;
}
- if (param_defs[index].type == PARAM_TYPE_BMODE)
- {
+ if (param_defs[index].type == PARAM_TYPE_BMODE) {
param->value_type = VALUE_TYPE_INTEGER;
- if (!strcasecmp(key, "transparent"))
- {
+ if (!strcasecmp(key, "transparent")) {
param->integer_value = INFO_BMODE_CIRCUIT;
break;
}
- if (!strcasecmp(key, "hdlc"))
- {
+ if (!strcasecmp(key, "hdlc")) {
param->integer_value = INFO_BMODE_PACKET;
break;
}
SPRINT(failure, "Bchannel mode '%s' unknown.", key);
goto parse_error;
}
- if (param_defs[index].type == PARAM_TYPE_DIVERSION)
- {
+ if (param_defs[index].type == PARAM_TYPE_HLC) {
param->value_type = VALUE_TYPE_INTEGER;
- if (!strcasecmp(key, "cfu"))
- {
+ 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")) {
param->integer_value = INFO_DIVERSION_CFU;
break;
}
- if (!strcasecmp(key, "cfb"))
- {
+ if (!strcasecmp(key, "cfb")) {
param->integer_value = INFO_DIVERSION_CFB;
break;
}
- if (!strcasecmp(key, "cfnr"))
- {
+ if (!strcasecmp(key, "cfnr")) {
param->integer_value = INFO_DIVERSION_CFNR;
break;
}
- if (!strcasecmp(key, "cfp"))
- {
+ if (!strcasecmp(key, "cfp")) {
param->integer_value = INFO_DIVERSION_CFP;
break;
}
SPRINT(failure, "Diversion type '%s' unknown.", key);
goto parse_error;
}
- if (param_defs[index].type == PARAM_TYPE_TYPE)
- {
+ if (param_defs[index].type == PARAM_TYPE_TYPE) {
param->value_type = VALUE_TYPE_INTEGER;
- if (!strcasecmp(key, "unknown"))
- {
+ if (!strcasecmp(key, "unknown")) {
param->integer_value = INFO_NTYPE_UNKNOWN;
break;
}
- if (!strcasecmp(key, "subscriber"))
- {
+ if (!strcasecmp(key, "subscriber")) {
param->integer_value = INFO_NTYPE_SUBSCRIBER;
break;
}
- if (!strcasecmp(key, "national"))
- {
+ if (!strcasecmp(key, "national")) {
param->integer_value = INFO_NTYPE_NATIONAL;
break;
}
- if (!strcasecmp(key, "international"))
- {
+ if (!strcasecmp(key, "international")) {
param->integer_value = INFO_NTYPE_INTERNATIONAL;
break;
}
SPRINT(failure, "Number type '%s' unknown.", key);
goto parse_error;
}
- if (param_defs[index].type == PARAM_TYPE_YESNO)
- {
+ if (param_defs[index].type == PARAM_TYPE_YESNO) {
param->value_type = VALUE_TYPE_INTEGER;
- if (!strcasecmp(key, "yes"))
- {
+ if (!strcasecmp(key, "yes")) {
param->integer_value = 1;
break;
}
- if (!strcasecmp(key, "no"))
- {
+ if (!strcasecmp(key, "no")) {
param->integer_value = 0;
break;
}
goto parse_error;
}
- if (*p == ',')
- {
+ if (*p == ',') {
p++;
/* next item */
param->value_extension = 1;
break;
/* to seperate the items, a space is required */
- if (*p != ' ')
- {
+ if (*p != ' ') {
SPRINT(failure, "Character '%c' not expected here. Use ' ' to seperate parameters, or ',' for multiple values.", *p);
goto parse_error;
}
}
/* check for next ACTION */
- if (*p == ':')
- {
+ if (*p == ':') {
p++;
goto nextaction;
}
if (nesting >= 0)
goto go_root;
- if (!ruleset_start)
- {
+ if (!ruleset_start) {
SPRINT(failure, "No ruleset defined.");
}
return(ruleset_start);
SPRINT(ruleset_error, "Error in file %s, line %d: %s", filename[nesting], line[nesting], failure);
openerror:
- while(nesting >= 0)
- {
+ while(nesting >= 0) {
fclose(fp[nesting--]);
fduse--;
}
/*
* return ruleset by name
*/
-struct route_ruleset *getrulesetbyname(char *name)
+struct route_ruleset *getrulesetbyname(const char *name)
{
struct route_ruleset *ruleset = ruleset_first;
- while(ruleset)
- {
- if (!strcasecmp(name, ruleset->name))
- {
+ while(ruleset) {
+ if (!strcasecmp(name, ruleset->name)) {
break;
}
ruleset = ruleset->next;
struct route_rule *rule = ruleset->rule_first;
struct route_cond *cond;
struct route_action *action = NULL;
- unsigned int comp_len;
+ unsigned long comp_len;
int j, jj;
- char callerid[64], redirid[64];
+ char callerid[64], callerid2[64], redirid[64];
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));
+ SCPY(callerid2, numberrize_callerinfo(e_callerinfo.id2, e_callerinfo.ntype2, options.national, options.international));
SCPY(redirid, numberrize_callerinfo(e_redirinfo.id, e_redirinfo.ntype, options.national, options.international));
PDEBUG(DEBUG_ROUTE, "parsing ruleset '%s'\n", ruleset->name);
- while(rule)
- {
+ while(rule) {
PDEBUG(DEBUG_ROUTE, "checking rule in line %d\n", rule->line);
match = 1; /* this rule matches */
dialing_required = 0;
timeout = 0; /* timeout time */
cond = rule->cond_first;
- while(cond)
- {
+ while(cond) {
condition = 0; /* any condition element is true (1) or could be true (2) */
checkextension:
istrue = 0; /* this condition-element is true */
couldbetrue = 0; /* this conditions-element could be true */
- switch(cond->match)
- {
+ switch(cond->match) {
case MATCH_EXTERN:
if (!e_ext.number[0])
istrue = 1;
case MATCH_PORT:
if (ea_endpoint->ep_portlist)
- if ((ea_endpoint->ep_portlist->port_type & PORT_CLASS_mISDN_MASK) != PORT_CLASS_mISDN_DSS1)
+ if ((ea_endpoint->ep_portlist->port_type & PORT_CLASS_MASK) != PORT_CLASS_mISDN)
break;
integer = e_callerinfo.isdn_port;
goto match_integer;
string = callerid;
goto match_string_prefix;
+ case MATCH_CALLERID2:
+ string = callerid2;
+ goto match_string_prefix;
+
case MATCH_EXTENSION:
string = e_ext.name;
goto match_string;
break;
case MATCH_REDIRECTED:
- if (e_redirinfo.present != INFO_PRESENT_NULL)
+ if (e_redirinfo.ntype != INFO_NTYPE_NOTPRESENT)
istrue = 1;
break;
case MATCH_DIRECT:
- if (e_redirinfo.present == INFO_PRESENT_NULL)
+ if (e_redirinfo.ntype == INFO_NTYPE_NOTPRESENT)
istrue = 1;
break;
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;
case MATCH_FILE:
tfp = fopen(cond->string_value, "r");
- if (!tfp)
- {
+ if (!tfp) {
break;
}
if (fgetc(tfp) == '1')
break;
case MATCH_TIMEOUT:
- timeout = now_d + cond->integer_value;
+ if (!now_ll) {
+ gettimeofday(¤t_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;
comp_len = comp_len-(unsigned long)cond->string_value;
avail = 0;
mISDNport = mISDNport_first;
- while(mISDNport)
- {
+ while(mISDNport) {
if (mISDNport->ifport)
if (strlen(mISDNport->ifport->interface->name) == comp_len)
if (!strncasecmp(mISDNport->ifport->interface->name, cond->string_value, comp_len))
- if (!mISDNport->l2hold || mISDNport->l2link)
- {
+ if (!mISDNport->l2hold || mISDNport->l2link>0) {
j = 0;
jj = mISDNport->b_num;
avail += jj;
- while(j < jj)
- {
+ while(j < jj) {
if (mISDNport->b_state[j])
avail--;
j++;
}
mISDNport = mISDNport->next;
}
- if (cond->match == MATCH_FREE)
- {
+ if (cond->match == MATCH_FREE) {
if (avail >= atoi(cond->string_value + comp_len + 1))
istrue = 1;
- } else
- {
+ } else {
if (avail < atoi(cond->string_value + comp_len + 1))
istrue = 1;
}
case MATCH_DOWN:
mISDNport = mISDNport_first;
- while(mISDNport)
- {
+ while(mISDNport) {
if (mISDNport->ifport)
if (!strcasecmp(mISDNport->ifport->interface->name, cond->string_value))
- if (!mISDNport->l2hold || mISDNport->l2link)
+ if (!mISDNport->l2hold || mISDNport->l2link>0)
break;
mISDNport = mISDNport->next;
}
case MATCH_UP:
mISDNport = mISDNport_first;
- while(mISDNport)
- {
+ while(mISDNport) {
if (mISDNport->ifport)
if (!strcasecmp(mISDNport->ifport->interface->name, cond->string_value))
- if (!mISDNport->l2hold || mISDNport->l2link)
+ if (!mISDNport->l2hold || mISDNport->l2link>0)
break;
mISDNport = mISDNport->next;
case MATCH_IDLE:
any = 0;
mISDNport = mISDNport_first;
- while(mISDNport)
- {
+ while(mISDNport) {
if (mISDNport->ifport)
if (!strcasecmp(mISDNport->ifport->interface->name, cond->string_value))
if (mISDNport->use) /* break if in use */
case MATCH_REMOTE:
case MATCH_NOTREMOTE:
admin = admin_first;
- while(admin)
- {
+ while(admin) {
if (admin->remote_name[0] && !strcmp(cond->string_value, admin->remote_name))
break;
admin = admin->next;
break;
match_integer:
- if (cond->value_type == VALUE_TYPE_INTEGER)
- {
+ if (cond->value_type == VALUE_TYPE_INTEGER) {
if (integer != cond->integer_value)
break;
istrue = 1;
break;
}
- if (cond->value_type == VALUE_TYPE_INTEGER_RANGE)
- {
+ if (cond->value_type == VALUE_TYPE_INTEGER_RANGE) {
/* check if negative range (2100 - 700 o'clock) */
- if (cond->integer_value > cond->integer_value_to)
- {
+ if (cond->integer_value > cond->integer_value_to) {
if (integer>=cond->integer_value && integer<=cond->integer_value_to)
istrue = 1;
break;
match_string_prefix:
comp_len = strlen(cond->string_value); /* because we must reach value's length */
/* we must have greater or equal length to values */
- if ((unsigned int)strlen(string) < comp_len)
- {
+ if ((unsigned long)strlen(string) < comp_len) {
/* special case for unfinished dialing */
- if (cond->match == MATCH_DIALING)
- {
+ if (cond->match == MATCH_DIALING) {
couldbetrue = 1; /* could match */
comp_len = strlen(string);
- } else
- {
+ } else {
break;
}
}
/* on single string match */
- if (cond->value_type == VALUE_TYPE_STRING)
- {
- if (!strncmp(string, cond->string_value, comp_len))
- {
+ if (cond->value_type == VALUE_TYPE_STRING) {
+ if (!strncmp(string, cond->string_value, comp_len)) {
istrue = 1;
/* must be set for changing 'e_extdialing' */
if (cond->match == MATCH_DIALING)
break;
}
/* on range match */
- if (cond->value_type == VALUE_TYPE_STRING_RANGE)
- {
+ if (cond->value_type == VALUE_TYPE_STRING_RANGE) {
/* check if negative range ("55"-"22") */
- if (cond->comp_string > 0)
- {
- if (strncmp(string, cond->string_value, comp_len) >= 0)
- {
+ if (cond->comp_string > 0) {
+ if (strncmp(string, cond->string_value, comp_len) >= 0) {
istrue = 1;
/* must be set for changing 'e_extdialing' */
if (cond->match == MATCH_DIALING)
dialing_required = comp_len;
break;
}
- if (strncmp(string, cond->string_value_to, comp_len) <= 0)
- {
+ if (strncmp(string, cond->string_value_to, comp_len) <= 0) {
/* must be set for changing 'e_extdialing' */
istrue = 1;
if (cond->match == MATCH_DIALING)
condition = 2; /* element could match and other elements don't match, so condition could match */
/* if not matching or could match */
- if (condition != 1)
- {
+ if (condition != 1) {
/* if we have more values to check */
- if (cond->value_extension && cond->next)
- {
+ if (cond->value_extension && cond->next) {
cond = cond->next;
goto checkextension;
}
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 */
}
- if (match == 1)
- {
+ 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;
}
- if (match == 2)
- {
+ if (match == 2) {
/* rule could match if more is dialed */
couldmatch = 1;
}
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);
}
{
struct route_param *param = action->param_first;
- while(param)
- {
+ while(param) {
if (param->id == id)
break;
param = param->next;