gsm improvements
[lcr.git] / route.c
diff --git a/route.c b/route.c
index 97c61a6..da59e98 100644 (file)
--- a/route.c
+++ b/route.c
@@ -9,10 +9,6 @@
 **                                                                           **
 \*****************************************************************************/ 
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
 #include "main.h"
 
 
@@ -30,6 +26,8 @@ struct cond_defs cond_defs[] = {
          "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,
@@ -91,7 +89,11 @@ struct cond_defs cond_defs[] = {
        { "busy",       MATCH_BUSY,     COND_TYPE_STRING,
          "busy=<extension>[,...]","Matches if any of the given extension is busy."},
        { "notbusy",    MATCH_IDLE,     COND_TYPE_STRING,
-         "notbusy<extension>[,...]","Matches if any of the given extension is not busy."},
+         "notbusy=<extension>[,...]","Matches if any of the given extension is not busy."},
+       { "remote",     MATCH_REMOTE,   COND_TYPE_STRING,
+         "remote=<application name>","Matches if remote application is running."},
+       { "notremote",  MATCH_NOTREMOTE,COND_TYPE_STRING,
+         "notremote=<application name>","Matches if remote application is not running."},
        { NULL, 0, 0, NULL}
 };
 
@@ -119,7 +121,7 @@ struct param_defs param_defs[] = {
          "capability=speech|audio|video|digital-restricted|digital-unrestricted|digital-unrestricted-tones", "Alter the service type of the call."},
        { PARAM_BMODE,
          "bmode",      PARAM_TYPE_BMODE,
-         "capability=transparent|hdlc", "Alter the bchannel mode of the call. Use hdlc for data calls."},
+         "bmode=transparent|hdlc", "Alter the bchannel mode of the call. Use hdlc for data calls."},
        { PARAM_INFO1,
          "infolayer1", PARAM_TYPE_INTEGER,
          "infolayer1=<value>", "Alter the layer 1 information of a call. Use 3 for ALAW or 2 for uLAW."},
@@ -216,6 +218,9 @@ struct param_defs param_defs[] = {
        { PARAM_ROOM,
          "room",       PARAM_TYPE_INTEGER,
          "room=<digits>", "Conference room number, must be greater 0, as in real life."},
+       { PARAM_JINGLE,
+         "jingle",     PARAM_TYPE_NULL,
+         "jingle", "Conference members will hear a jingle if a member joins."},
        { PARAM_TIMEOUT,
          "timeout",    PARAM_TYPE_INTEGER,
          "timeout=<seconds>", "Timeout before continue with next action."},
@@ -225,6 +230,18 @@ struct param_defs param_defs[] = {
        { PARAM_STRIP,
          "strip",      PARAM_TYPE_NULL,
          "strip", "Remove digits that were required to match this rule."},
+       { PARAM_APPLICATION,
+         "application",PARAM_TYPE_STRING,
+         "application=<name>", "Name of remote application to make call to."},
+       { PARAM_CONTEXT,
+         "context",    PARAM_TYPE_STRING,
+         "context=<context>", "Give context parameter to the remote application."},
+       { 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."},
        { 0, NULL, 0, NULL, NULL}
 };
 
@@ -241,17 +258,17 @@ struct action_defs action_defs[] = {
          "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,
          "Same as 'extern'"},
-       { ACTION_CHAN,
-         "asterisk",   &EndpointAppPBX::action_init_chan, &EndpointAppPBX::action_dialing_chan, &EndpointAppPBX::action_hangup_call,
-         PARAM_CONNECT | PARAM_TIMEOUT,
-         "Call is routed to Asterisk via channel driver."},
+       { ACTION_REMOTE,
+         "remote",     &EndpointAppPBX::action_init_remote, &EndpointAppPBX::action_dialing_remote, &EndpointAppPBX::action_hangup_call,
+         PARAM_CONNECT | PARAM_APPLICATION | PARAM_CONTEXT | PARAM_EXTEN | PARAM_TIMEOUT,
+         "Call is routed to Remote application, like Asterisk."},
        { ACTION_VBOX_RECORD,
          "vbox-record",&EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_vbox_record, &EndpointAppPBX::action_hangup_call,
          PARAM_CONNECT | PARAM_EXTENSION | PARAM_ANNOUNCEMENT | PARAM_TIMEOUT,
          "Caller is routed to the voice box of given extension."},
        { ACTION_PARTYLINE,
          "partyline",&EndpointAppPBX::action_init_partyline, NULL, &EndpointAppPBX::action_hangup_call,
-         PARAM_ROOM,
+         PARAM_ROOM | PARAM_JINGLE,
          "Caller is participating the conference with the given room number."},
        { ACTION_LOGIN,
          "login",      NULL, &EndpointAppPBX::action_dialing_login, NULL,
@@ -276,7 +293,7 @@ struct action_defs action_defs[] = {
        { ACTION_REPLY,
          "reply",      &EndpointAppPBX::action_init_redial_reply, &EndpointAppPBX::action_dialing_reply, NULL,
          PARAM_CONNECT | PARAM_SELECT,
-         "Caller replies. (last incomming call(s))"},
+         "Caller replies. (last incoming call(s))"},
        { ACTION_POWERDIAL,
          "powerdial",  NULL, &EndpointAppPBX::action_dialing_powerdial, NULL,
          PARAM_CONNECT | PARAM_DELAY | PARAM_LIMIT | PARAM_TIMEOUT,
@@ -312,7 +329,7 @@ struct action_defs action_defs[] = {
 //       "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,
@@ -322,11 +339,6 @@ 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_HELP,
-         "help",       NULL, &EndpointAppPBX::action_dialing_help, NULL,
-         PARAM_CONNECT | PARAM_TIMEOUT,
-         NULL},
-//       "Caller will be able to select from current rules that would match. (using * and #)"},
        { ACTION_DEFLECT,
          "deflect",    NULL, &EndpointAppPBX::action_dialing_deflect, NULL,
          PARAM_DEST,
@@ -338,8 +350,8 @@ struct action_defs action_defs[] = {
          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,
          "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,
@@ -477,16 +489,16 @@ void ruleset_free(struct route_ruleset *ruleset_start)
                                cond = rule->cond_first;
                                if (cond->string_value)
                                {
-                                       free(cond->string_value);
+                                       FREE(cond->string_value, 0);
                                        rmemuse--;
                                }
                                if (cond->string_value_to)
                                {
-                                       free(cond->string_value_to);
+                                       FREE(cond->string_value_to, 0);
                                        rmemuse--;
                                }
                                rule->cond_first = cond->next;
-                               free(cond);
+                               FREE(cond, sizeof(struct route_cond));
                                rmemuse--;
                        }
                        while(rule->action_first)
@@ -499,19 +511,19 @@ void ruleset_free(struct route_ruleset *ruleset_start)
                                        action->param_first = param->next;
                                        if (param->string_value)
                                        {
-                                               free(param->string_value);
+                                               FREE(param->string_value, 0);
                                                rmemuse--;
                                        }
-                                       free(param);
+                                       FREE(param, sizeof(struct route_param));
                                        rmemuse--;
                                }
-                               free(action);
+                               FREE(action, sizeof(struct route_action));
                                rmemuse--;
                        }
-                       free(rule);
+                       FREE(rule, sizeof(struct route_rule));
                        rmemuse--;
                }
-               free(ruleset);
+               FREE(ruleset, sizeof(struct route_ruleset));
                rmemuse--;
        }
 }
@@ -744,7 +756,7 @@ void ruleset_debug(struct route_ruleset *ruleset_start)
 /*
  * 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;
 
@@ -841,6 +853,7 @@ struct route_ruleset *ruleset_parse(void)
        struct route_param      *param;
        struct route_param      **param_pointer = NULL;
        char                    failure[256];
+       unsigned long long      allowed_params;
 
        /* check the integrity of IDs for ACTION_* and PARAM_* */
        i = 0;
@@ -867,7 +880,7 @@ struct route_ruleset *ruleset_parse(void)
                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")))
         {
@@ -935,7 +948,7 @@ struct route_ruleset *ruleset_parse(void)
                        if (key[0] == '/')
                                SCPY(filename[nesting+1], key);
                        else
-                               SPRINT(filename[nesting+1], "%s/%s", INSTALL_DATA, key);
+                               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]);
@@ -966,7 +979,7 @@ struct route_ruleset *ruleset_parse(void)
 
                        /* reading ruleset name text */
                        i = 0;
-                       while((*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9'))
+                       while(*p>' ' && *p<127 && *p!=']')
                        {
                                if (*p>='A' && *p<='Z') *p = *p-'A'+'a'; /* lower case */
                                key[i++] = *p++;
@@ -1002,14 +1015,8 @@ struct route_ruleset *ruleset_parse(void)
                        }
 
                        /* create ruleset */
-                       ruleset = (struct route_ruleset *)malloc(sizeof(struct route_ruleset));
-                       if (ruleset == NULL)
-                       {
-                               SPRINT(failure, "Out of memory.");
-                               goto parse_error;
-                       }
+                       ruleset = (struct route_ruleset *)MALLOC(sizeof(struct route_ruleset));
                        rmemuse++;
-                       memset(ruleset, 0, sizeof(struct route_ruleset));
                        *ruleset_pointer = ruleset;
                        ruleset_pointer = &(ruleset->next);
                        SCPY(ruleset->name, key);
@@ -1026,15 +1033,9 @@ struct route_ruleset *ruleset_parse(void)
                        goto new_ruleset;
                }
 
-               /* alloc memory for rule */
-               rule = (struct route_rule *)malloc(sizeof(struct route_rule));
-               if (rule == NULL)
-               {
-                       SPRINT(failure, "Out of memory.");
-                       goto parse_error;
-               }
+               /* Alloc memory for rule */
+               rule = (struct route_rule *)MALLOC(sizeof(struct route_rule));
                rmemuse++;
-               memset(rule, 0, sizeof(struct route_rule));
                *rule_pointer = rule;
                rule_pointer = &(rule->next);
                cond_pointer = &(rule->cond_first);
@@ -1121,15 +1122,9 @@ struct route_ruleset *ruleset_parse(void)
                        }
 
                        nextcondvalue:
-                       /* alloc memory for item */
-                       cond = (struct route_cond *)malloc(sizeof(struct route_cond));
-                       if (cond == NULL)
-                       {
-                               SPRINT(failure, "Out of memory.");
-                               goto parse_error;
-                       }
+                       /* Alloc memory for item */
+                       cond = (struct route_cond *)MALLOC(sizeof(struct route_cond));
                        rmemuse++;
-                       memset(cond, 0, sizeof(struct route_cond));
                        *cond_pointer = cond;
                        cond_pointer = &(cond->next);
                        cond->index = index;
@@ -1314,22 +1309,12 @@ struct route_ruleset *ruleset_parse(void)
                                        }
                                }
                                alloc_string:
-                               cond->string_value = (char *)malloc(strlen(key)+1);
-                               if (cond->string_value == NULL)
-                               {
-                                       SPRINT(failure, "Out of memory.");
-                                       goto parse_error;
-                               }
+                               cond->string_value = (char *)MALLOC(strlen(key)+1);
                                rmemuse++;
                                UCPY(cond->string_value, key);
                                if (value_type == VALUE_TYPE_STRING_RANGE)
                                {
-                                       cond->string_value_to = (char *)malloc(strlen(key_to)+1);
-                                       if (cond->string_value_to == NULL)
-                                       {
-                                               SPRINT(failure, "Out of memory.");
-                                               goto parse_error;
-                                       }
+                                       cond->string_value_to = (char *)MALLOC(strlen(key_to)+1);
                                        rmemuse++;
                                        UCPY(cond->string_value_to, key_to);
                                        cond->comp_string = strcmp(key, key_to);
@@ -1482,16 +1467,11 @@ struct route_ruleset *ruleset_parse(void)
                        SPRINT(failure, "Unknown action name '%s'.", key);
                        goto parse_error;
                }
+               allowed_params = action_defs[index].params;
 
                /* alloc memory for action */
-               action = (struct route_action *)malloc(sizeof(struct route_action));
-               if (action == NULL)
-               {
-                       SPRINT(failure, "Out of memory.");
-                       goto parse_error;
-               }
+               action = (struct route_action *)MALLOC(sizeof(struct route_action));
                rmemuse++;
-               memset(action, 0, sizeof(struct route_action));
                *action_pointer = action;
                action_pointer = &(action->next);
                param_pointer = &(action->param_first);
@@ -1537,6 +1517,13 @@ struct route_ruleset *ruleset_parse(void)
                                goto parse_error;
                        }
 
+                       /* check if item is allowed for the action */
+                       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)
                        {
@@ -1619,15 +1606,9 @@ struct route_ruleset *ruleset_parse(void)
                        }
 
                        nextparamvalue:
-                       /* alloc memory for param */
-                       param = (struct route_param *)malloc(sizeof(struct route_param));
-                       if (param == NULL)
-                       {
-                               SPRINT(failure, "Out of memory.");
-                               goto parse_error;
-                       }
+                       /* Alloc memory for param */
+                       param = (struct route_param *)MALLOC(sizeof(struct route_param));
                        rmemuse++;
-                       memset(param, 0, sizeof(struct route_param));
                        *param_pointer = param;
                        param_pointer = &(param->next);
                        param->index = index;
@@ -1706,6 +1687,7 @@ struct route_ruleset *ruleset_parse(void)
                                case PARAM_TYPE_DESTIN:
                                case PARAM_TYPE_TYPE:
                                case PARAM_TYPE_YESNO:
+                               case PARAM_TYPE_ON:
                                key[0] = '\0';
                                if (*p==',' || *p==' ' || *p=='\0')
                                {
@@ -1744,6 +1726,22 @@ struct route_ruleset *ruleset_parse(void)
                                        SPRINT(failure, "Caller ID type '%s' unknown.", key);
                                        goto parse_error;
                                }
+                               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;
@@ -1864,12 +1862,7 @@ struct route_ruleset *ruleset_parse(void)
                                        SPRINT(failure, "Value '%s' unknown. ('yes' or 'no')", key);
                                        goto parse_error;
                                }
-                               param->string_value = (char *)malloc(strlen(key)+1);
-                               if (param->string_value == NULL)
-                               {
-                                       SPRINT(failure, "Out of memory.");
-                                       goto parse_error;
-                               }
+                               param->string_value = (char *)MALLOC(strlen(key)+1);
                                rmemuse++;
                                UCPY(param->string_value, key);
                                param->value_type = VALUE_TYPE_STRING;
@@ -1951,7 +1944,7 @@ struct route_ruleset *ruleset_parse(void)
 /*
  * return ruleset by name
  */
-struct route_ruleset *getrulesetbyname(char *name)
+struct route_ruleset *getrulesetbyname(const char *name)
 {
        struct route_ruleset *ruleset = ruleset_first;
 
@@ -1985,19 +1978,21 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
        struct route_action     *action = NULL;
        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;
        struct mISDNport        *mISDNport;
+       struct admin_list       *admin;
 
        /* reset timeout action */
        e_match_timeout = 0; /* no timeout */
        e_match_to_action = NULL;
 
-       SCPY(callerid, numberrize_callerinfo(e_callerinfo.id, e_callerinfo.ntype));
-       SCPY(redirid, numberrize_callerinfo(e_redirinfo.id, e_redirinfo.ntype));
+       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)
@@ -2027,7 +2022,7 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
 
                                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;
@@ -2042,6 +2037,10 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
                                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;
@@ -2091,12 +2090,12 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
                                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;
 
@@ -2175,7 +2174,7 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
                                        if (mISDNport->ifport)
                                        if (strlen(mISDNport->ifport->interface->name) == comp_len)
                                        if (!strncasecmp(mISDNport->ifport->interface->name, cond->string_value, comp_len)) 
-                                       if (!mISDNport->ptp || mISDNport->l2link)
+                                       if (!mISDNport->l2hold || mISDNport->l2link>0)
                                        {
                                                j = 0;
                                                jj = mISDNport->b_num;
@@ -2207,7 +2206,7 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
                                {
                                        if (mISDNport->ifport)
                                        if (!strcasecmp(mISDNport->ifport->interface->name, cond->string_value)) 
-                                       if (!mISDNport->ptp || mISDNport->l2link) /* break if one is up */
+                                       if (!mISDNport->l2hold || mISDNport->l2link>0)
                                                break;
                                        mISDNport = mISDNport->next;
                                }
@@ -2221,7 +2220,7 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
                                {
                                        if (mISDNport->ifport)
                                        if (!strcasecmp(mISDNport->ifport->interface->name, cond->string_value)) 
-                                       if (!mISDNport->ptp || mISDNport->l2link) /* break if one is up */
+                                       if (!mISDNport->l2hold || mISDNport->l2link>0)
                                                break;
                                        
                                        mISDNport = mISDNport->next;
@@ -2231,6 +2230,7 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
                                break;
 
                                case MATCH_BUSY:
+                               case MATCH_IDLE:
                                any = 0;
                                mISDNport = mISDNport_first;
                                while(mISDNport)
@@ -2241,21 +2241,24 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
                                                break;
                                        mISDNport = mISDNport->next;
                                }
-                               if (mISDNport)
+                               if (mISDNport && cond->match==MATCH_BUSY)
+                                       istrue = 1;
+                               if (!mISDNport && cond->match==MATCH_IDLE)
                                        istrue = 1;
                                break;
 
-                               case MATCH_IDLE:
-                               mISDNport = mISDNport_first;
-                               while(mISDNport)
+                               case MATCH_REMOTE:
+                               case MATCH_NOTREMOTE:
+                               admin = admin_first;
+                               while(admin)
                                {
-                                       if (mISDNport->ifport)
-                                       if (!strcasecmp(mISDNport->ifport->interface->name, cond->string_value)) 
-                                       if (mISDNport->use) /* break if in use */
+                                       if (admin->remote_name[0] && !strcmp(cond->string_value, admin->remote_name))
                                                break;
-                                       mISDNport = mISDNport->next;
+                                       admin = admin->next;
                                }
-                               if (!mISDNport)
+                               if (admin && cond->match==MATCH_REMOTE)
+                                       istrue = 1;
+                               if (!admin && cond->match==MATCH_NOTREMOTE)
                                        istrue = 1;
                                break;
 
@@ -2461,10 +2464,10 @@ struct route_action action_internal = {
        0,
 };
 
-struct route_action action_chan = {
+struct route_action action_remote = {
        NULL,
        NULL,
-       ACTION_CHAN,
+       ACTION_REMOTE,
        0,
        0,
 };