unified socket application interface (for asterisk and maybe other apps)
[lcr.git] / route.c
diff --git a/route.c b/route.c
index b39d2e0..3381251 100644 (file)
--- a/route.c
+++ b/route.c
@@ -91,7 +91,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_NULL,
+         "notremote=<application name>","Matches if remote application is not running."},
        { NULL, 0, 0, NULL}
 };
 
@@ -222,6 +226,12 @@ struct param_defs param_defs[] = {
        { PARAM_NOPASSWORD,
          "nopassword", PARAM_TYPE_NULL,
          "nopassword", "Don't ask for password. Be sure to authenticate right via real caller ID."},
+       { PARAM_STRIP,
+         "strip",      PARAM_TYPE_NULL,
+         "strip", "Remove digits that were required to match this rule."},
+       { PARAM_APPLICATION,
+         "application",PARAM_TYPE_STRING,
+         "application", "Name of remote application to make call to."},
        { 0, NULL, 0, NULL, NULL}
 };
 
@@ -238,10 +248,10 @@ 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_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,
@@ -309,7 +319,7 @@ struct action_defs action_defs[] = {
 //       "Caller calls the timer."},
        { ACTION_GOTO,
          "goto",       NULL, &EndpointAppPBX::action_dialing_goto, NULL,
-         PARAM_CONNECT | PARAM_RULESET | PARAM_SAMPLE,
+         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,
@@ -361,7 +371,7 @@ struct action_defs action_defs[] = {
        { ACTION_EFI,
          "efi",        &EndpointAppPBX::action_init_efi, NULL, NULL,
          PARAM_PROCEEDING | PARAM_ALERTING | PARAM_CONNECT,
-         "Elektronische Fernsprecher Identifikation."},
+         "Elektronische Fernsprecher Identifikation - announces caller ID."},
        { -1,
          NULL, NULL, NULL, NULL, 0, NULL}
 };
@@ -474,16 +484,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)
@@ -496,19 +506,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--;
        }
 }
@@ -999,14 +1009,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);
@@ -1023,15 +1027,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);
@@ -1118,15 +1116,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;
@@ -1311,22 +1303,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);
@@ -1481,14 +1463,8 @@ struct route_ruleset *ruleset_parse(void)
                }
 
                /* 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);
@@ -1616,15 +1592,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;
@@ -1861,12 +1831,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;
@@ -1988,6 +1953,7 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
        FILE                    *tfp;
        double                  timeout;
        struct mISDNport        *mISDNport;
+       struct admin_list       *admin;
 
        /* reset timeout action */
        e_match_timeout = 0; /* no timeout */
@@ -2013,12 +1979,12 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
                        switch(cond->match)
                        {
                                case MATCH_EXTERN:
-                               if (!e_terminal[0])
+                               if (!e_ext.number[0])
                                        istrue = 1;      
                                break;
 
                                case MATCH_INTERN:
-                               if (e_terminal[0])
+                               if (e_ext.number[0])
                                        istrue = 1;      
                                break;
 
@@ -2044,7 +2010,7 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
                                goto match_string;
 
                                case MATCH_DIALING:
-                               string = e_dialinginfo.number;
+                               string = e_dialinginfo.id;
                                goto match_string_prefix;
 
                                case MATCH_ENBLOCK:
@@ -2228,6 +2194,7 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
                                break;
 
                                case MATCH_BUSY:
+                               case MATCH_IDLE:
                                any = 0;
                                mISDNport = mISDNport_first;
                                while(mISDNport)
@@ -2238,21 +2205,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[0] && !strcmp(cond->string_value, admin->remote))
                                                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;
 
@@ -2384,7 +2354,7 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
                        /* set timeout in the furture */
                        e_match_timeout = timeout;
                        e_match_to_action = rule->action_first;
-                       e_match_to_extdialing = e_dialinginfo.number + dialing_required;
+                       e_match_to_extdialing = e_dialinginfo.id + dialing_required;
                        match = 0; /* matches in the future */
                }
                if (match == 1)
@@ -2393,7 +2363,7 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
                        action = rule->action_first;
                        e_match_timeout = 0; /* no timeout */
                        e_match_to_action = NULL;
-                       e_extdialing = e_dialinginfo.number + dialing_required;
+                       e_extdialing = e_dialinginfo.id + dialing_required;
                        break;
                }
                if (match == 2)
@@ -2458,10 +2428,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,
 };