work on socket. (don't try yet)
[lcr.git] / interface.c
index e95d613..aa55f36 100644 (file)
@@ -9,9 +9,6 @@
 **                                                                           **
 \*****************************************************************************/ 
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include "main.h"
 
 struct interface *interface_first = NULL; /* first interface is current list */
@@ -434,6 +431,55 @@ static int inter_channel_in(struct interface *interface, char *filename, int lin
        }
        return(0);
 }
+static int inter_timeouts(struct interface *interface, char *filename, int line, char *parameter, char *value)
+{
+       struct interface_port *ifport;
+//     struct select_channel *selchannel, **selchannelp;
+//     int val;
+       char *p, *el;
+
+       /* port in chain ? */
+       if (!interface->ifport)
+       {
+               SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
+               return(-1);
+       }
+       /* goto end of chain */
+       ifport = interface->ifport;
+       while(ifport->next)
+               ifport = ifport->next;
+       p = value;
+       if (!*p)
+       {
+               nofive:
+               SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects five timeout values.\n", filename, line, parameter);
+               return(-1);
+       }
+       el = p;
+       p = get_seperated(p);
+       ifport->tout_setup = atoi(el);
+       if (!*p)
+               goto nofive;
+       el = p;
+       p = get_seperated(p);
+       ifport->tout_dialing = atoi(el);
+       if (!*p)
+               goto nofive;
+       el = p;
+       p = get_seperated(p);
+       ifport->tout_proceeding = atoi(el);
+       if (!*p)
+               goto nofive;
+       el = p;
+       p = get_seperated(p);
+       ifport->tout_alerting = atoi(el);
+       if (!*p)
+               goto nofive;
+       el = p;
+       p = get_seperated(p);
+       ifport->tout_disconnect = atoi(el);
+       return(0);
+}
 static int inter_msn(struct interface *interface, char *filename, int line, char *parameter, char *value)
 {
        struct interface_msn *ifmsn, **ifmsnp;
@@ -588,13 +634,13 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
                                goto typeerror;
                        ifscreen->result_type = INFO_NTYPE_INTERNATIONAL;
                } else
-               if (!strcasecmp(el, "allowed"))
+               if (!strcasecmp(el, "present") || !strcasecmp(el, "presented") || !strcasecmp(el, "allowed") || !strcasecmp(el, "allow"))
                {
                        if (ifscreen->result_present != -1)
                                goto presenterror;
                        ifscreen->result_present = INFO_PRESENT_ALLOWED;
                } else
-               if (!strcasecmp(el, "restrict") || !strcasecmp(el, "restricted"))
+               if (!strcasecmp(el, "restrict") || !strcasecmp(el, "restricted") || !strcasecmp(el, "deny") || !strcasecmp(el, "denied"))
                {
                        if (ifscreen->result_present != -1)
                                goto presenterror;
@@ -651,13 +697,116 @@ static int inter_nodtmf(struct interface *interface, char *filename, int line, c
        ifport->nodtmf = 1;
        return(0);
 }
-#warning filter to be done
-#if 0
 static int inter_filter(struct interface *interface, char *filename, int line, char *parameter, char *value)
 {
+       char *p, *q;
+
+       /* seperate parameter from filter */
+       p = value;
+       while(*p > 32)
+               p++;
+       if (*p)
+       {
+               *p++ = 0;
+               while(*p > 0 && *p <= 32)
+                       p++;
+       }
+
+       if (!strcasecmp(value, "gain"))
+       {
+               q = p;
+               while(*q > 32)
+                       q++;
+               if (*q)
+               {
+                       *q++ = 0;
+                       while(*q > 0 && *q <= 32)
+                               q++;
+               }
+               if (*p == 0 || *q == 0)
+               {
+                       SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' expects two gain values.\n", filename, line, parameter, value);
+                       return(-1);
+               }
+               if (atoi(p)<-8 || atoi(p)>8 || atoi(q)<-8 || atoi(q)>8)
+               {
+                       SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' gain values not in range. (-8...8)\n", filename, line, parameter, value);
+                       return(-1);
+               }
+               interface->tx_gain = atoi(p);
+               interface->rx_gain = atoi(q);
+       } else
+       if (!strcasecmp(value, "pipeline"))
+       {
+               if (*p == 0)
+               {
+                       SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' expects pipeline string.\n", filename, line, parameter, value);
+                       return(-1);
+               }
+               SCPY(interface->pipeline, p);
+       } else
+       if (!strcasecmp(value, "blowfish"))
+       {
+               unsigned char key[56];
+               int l;
+               
+               if (!!strncmp(p, "0x", 2))
+               {
+                       SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' expects blowfish key starting with '0x'.\n", filename, line, parameter, value);
+                       return(-1);
+               }
+               p += 2;
+               l = 0; 
+               while(*p)
+               {
+                       if (l == 56)
+                       {
+                               SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' key too long.\n", filename, line, parameter, value);
+                               return(-1);
+                       }
+                       if (*p >= '0' && *p <= '9')
+                               key[l] = (*p-'0')<<4;
+                       else if (*p >= 'a' && *p <= 'f')
+                               key[l] = (*p-'a'+10)<<4;
+                       else if (*p >= 'A' && *p <= 'F')
+                               key[l] = (*p-'A'+10)<<4;
+                       else
+                       {
+                               digout:
+                               SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' key has digits out of range. (0...9, a...f)\n", filename, line, parameter, value);
+                               return(-1);
+                       }
+                       p++;
+                       if (*p == 0)
+                       {
+                               SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' key must end on an 8 bit boundary (two character boundary).\n", filename, line, parameter, value);
+                               return(-1);
+                       }
+                       if (*p >= '0' && *p <= '9')
+                               key[l] = (*p-'0')<<4;
+                       else if (*p >= 'a' && *p <= 'f')
+                               key[l] = (*p-'a'+10)<<4;
+                       else if (*p >= 'A' && *p <= 'F')
+                               key[l] = (*p-'A'+10)<<4;
+                       else
+                               goto digout;
+                       p++;
+                       l++;
+               }
+               if (l < 4)
+               {
+                       SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' key must be at least 4 bytes (8 characters).\n", filename, line, parameter, value);
+                       return(-1);
+               }
+               memcpy(interface->bf_key, key, l);
+               interface->bf_len = l;
+       } else
+       {
+               SPRINT(interface_error, "Error in %s (line %d): parameter '%s' has unknown filter '%s'.\n", filename, line, parameter, value);
+               return(-1);
+       }
        return(0);
 }
-#endif
 
 
 /*
@@ -711,19 +860,24 @@ struct interface_param interface_param[] = {
        " no - Signal 'no channel available' aka 'call waiting'. (see DSS1)"},
 
        {"channel-in", &inter_channel_in, "[<number>][,...][,free]",
-       "Channel selection list for all incomming calls from the interface.\n"
+       "Channel selection list for all incoming calls from the interface.\n"
        "A free channels is accepted if in the list.\n"
        "If any channel was requested, the first free channel found is selected.\n"
        "This parameter must follow a 'port' parameter.\n"
        " <number>[,...] - List of channels to accept.\n"
        " free - Accept any free channel"},
 
+       {"timeouts", &inter_timeouts, "<setup> <dialing> <proceeding> <alerting> <disconnect>",
+       "Timeout values for call states. They are both for incoming and outgoing states.\n"
+       "The default is 120 seconds for all states. Use 0 to disable.\n"
+       "This parameter must follow a 'port' parameter.\n"},
+
        {"msn", &inter_msn, "<default MSN>,[<additional MSN>[,...]]",
-       "Incomming caller ID is checked against given MSN numbers.\n"
+       "Incoming caller ID is checked against given MSN numbers.\n"
        "If the caller ID is not found in this list, it is overwritten by the first MSN"},
 
        {"screen-in", &inter_screen_in, "[options] <old caller ID>[%] [options] <new caller ID>[%]",
-       "Adds an entry for incomming calls to the caller ID screen list.\n"
+       "Adds an entry for incoming calls to the caller ID screen list.\n"
        "If the given 'old caller ID' matches, it is replaced by the 'new caller ID'\n"
        "If '%' is given after old caller ID, it matches even if caller ID has\n"
        "additional digits.\n"
@@ -748,13 +902,11 @@ struct interface_param interface_param[] = {
        "This parameter must follow a 'port' parameter."},
 #endif
 
-#if 0
-#warning todo: filter, also in the PmISDN object
-       {"filter", &inter_filter, "<filter> [parameters]",
+       {"filter", &inter_filter, "<filter> <parameters>",
        "Adds/appends a filter. Filters are ordered in transmit direction.\n"
        "gain <tx-volume> <rx-volume> - Changes volume (-8 .. 8)\n"
+       "pipeline <string> - Sets echo cancelation pipeline.\n"
        "blowfish <key> - Adds encryption. Key must be 4-56 bytes (8-112 hex characters."},
-#endif
 
        {NULL, NULL, NULL, NULL}
 };
@@ -934,7 +1086,6 @@ void free_interfaces(struct interface *interface)
        struct select_channel *selchannel;
        struct interface_msn *ifmsn;
        struct interface_screen *ifscreen;
-       struct interface_filter *iffilter;
 
        while(interface)
        {
@@ -986,14 +1137,6 @@ void free_interfaces(struct interface *interface)
                        FREE(temp, sizeof(struct interface_screen));
                        memuse--;
                }
-               iffilter = interface->iffilter;
-               while(iffilter)
-               {
-                       temp = iffilter;
-                       iffilter = iffilter->next;
-                       FREE(temp, sizeof(struct interface_filter));
-                       memuse--;
-               }
                temp = interface;
                interface = interface->next;
                FREE(temp, sizeof(struct interface));
@@ -1155,7 +1298,7 @@ void doc_interface(void)
 
 
 /* screen caller id
- * out==0: incomming caller id, out==1: outgoing caller id
+ * out==0: incoming caller id, out==1: outgoing caller id
  */
 void do_screen(int out, char *id, int idsize, int *type, int *present, struct interface *interface)
 {
@@ -1182,13 +1325,13 @@ void do_screen(int out, char *id, int idsize, int *type, int *present, struct in
                }
                if (ifmsn)
                {
-                       start_trace(0, interface, numberrize_callerinfo(id, *type), NULL, DIRECTION_IN, 0, 0, "SCREEN (fount in MSN list)");
+                       start_trace(0, interface, numberrize_callerinfo(id, *type), NULL, DIRECTION_IN, 0, 0, "SCREEN (found in MSN list)");
                        add_trace("msn", NULL, "%s", id);
                        end_trace();
                }
                if (!ifmsn && msn1) // not in list, first msn given
                {
-                       start_trace(0, interface, numberrize_callerinfo(id, *type), NULL, DIRECTION_IN, 0, 0, "SCREEN (not fount in MSN list)");
+                       start_trace(0, interface, numberrize_callerinfo(id, *type), NULL, DIRECTION_IN, 0, 0, "SCREEN (not found in MSN list)");
                        add_trace("msn", "given", "%s", id);
                        add_trace("msn", "used", "%s", msn1);
                        end_trace();
@@ -1221,7 +1364,7 @@ void do_screen(int out, char *id, int idsize, int *type, int *present, struct in
        }
        if (ifscreen) // match
        {
-               start_trace(0, interface, numberrize_callerinfo(id, *type), NULL, out?DIRECTION_OUT:DIRECTION_IN, 0, 0, "SCREEN (fount in screen list)");
+               start_trace(0, interface, numberrize_callerinfo(id, *type), NULL, out?DIRECTION_OUT:DIRECTION_IN, 0, 0, "SCREEN (found in screen list)");
                switch(*type)
                {
                        case INFO_NTYPE_UNKNOWN: