Ports can now be specified by number or by name.
[lcr.git] / interface.c
index 4acc514..c70222c 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 */
@@ -158,6 +155,7 @@ static int inter_ptp(struct interface *interface, char *filename, int line, char
        ifport->ptp = 1;
        return(0);
 }
+#if 0
 static int inter_ptmp(struct interface *interface, char *filename, int line, char *parameter, char *value)
 {
        struct interface_port *ifport;
@@ -186,9 +184,9 @@ static int inter_ptmp(struct interface *interface, char *filename, int line, cha
        ifport->ptmp = 1;
        return(0);
 }
+#endif
 static int inter_nt(struct interface *interface, char *filename, int line, char *parameter, char *value)
 {
-#ifdef SOCKET_MISDN
        struct interface_port *ifport;
 
        /* port in chain ? */
@@ -208,7 +206,6 @@ static int inter_nt(struct interface *interface, char *filename, int line, char
                return(-1);
        }
        ifport->nt = 1;
-#endif
        return(0);
 }
 static int inter_tones(struct interface *interface, char *filename, int line, char *parameter, char *value)
@@ -261,6 +258,11 @@ static int inter_hunt(struct interface *interface, char *filename, int line, cha
 }
 static int inter_port(struct interface *interface, char *filename, int line, char *parameter, char *value)
 {
+       SPRINT(interface_error, "Error in %s (line %d): parameter '%s' is outdated.\nPlease use 'portnum' and decrease port number by 1! Ports are counted from 0 now.\n", filename, line, parameter);
+       return(-1);
+}
+static int inter_portnum(struct interface *interface, char *filename, int line, char *parameter, char *value)
+{
        struct interface_port *ifport, **ifportp;
        struct interface *searchif;
        int val;
@@ -300,6 +302,69 @@ static int inter_port(struct interface *interface, char *filename, int line, cha
        *ifportp = ifport;
        return(0);
 }
+static int inter_portname(struct interface *interface, char *filename, int line, char *parameter, char *value)
+{
+       struct interface_port *ifport, **ifportp;
+       struct interface *searchif;
+
+       /* check for port already assigned */
+       searchif = interface_newlist;
+       while(searchif)
+       {
+               ifport = searchif->ifport;
+               while(ifport)
+               {
+                       if (!strcasecmp(ifport->portname, value))
+                       {
+                               SPRINT(interface_error, "Error in %s (line %d): port '%s' already used above.\n", filename, line, value);
+                               return(-1);
+                       }
+                       ifport = ifport->next;
+               }
+               searchif = searchif->next;
+       }
+       /* alloc port substructure */
+       ifport = (struct interface_port *)MALLOC(sizeof(struct interface_port));
+       memuse++;
+       ifport->interface = interface;
+       /* set value */
+       ifport->portnum = -1; // disable until resolved
+       SCPY(ifport->portname, value);
+       /* tail port */
+       ifportp = &interface->ifport;
+       while(*ifportp)
+               ifportp = &((*ifportp)->next);
+       *ifportp = ifport;
+       return(0);
+}
+static int inter_l2hold(struct interface *interface, char *filename, int line, char *parameter, char *value)
+{
+       struct interface_port *ifport;
+
+       /* 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;
+       if (!strcmp(value, "yes"))
+       {
+               ifport->l2hold = 1;
+       } else
+       if (!strcmp(value, "no"))
+       {
+               ifport->l2hold = -1;
+       } else
+       {
+               SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expecting parameter 'yes' or 'no'.\n", filename, line, parameter);
+               return(-1);
+       }
+       return(0);
+}
 static int inter_channel_out(struct interface *interface, char *filename, int line, char *parameter, char *value)
 {
        struct interface_port *ifport;
@@ -437,8 +502,8 @@ static int inter_channel_in(struct interface *interface, char *filename, int lin
 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;
+//     struct select_channel *selchannel, **selchannelp;
+//     int val;
        char *p, *el;
 
        /* port in chain ? */
@@ -637,13 +702,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;
@@ -736,8 +801,8 @@ static int inter_filter(struct interface *interface, char *filename, int line, c
                        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->gain_tx = atoi(p);
-               interface->gain_rx = atoi(q);
+               interface->tx_gain = atoi(p);
+               interface->rx_gain = atoi(q);
        } else
        if (!strcasecmp(value, "pipeline"))
        {
@@ -828,7 +893,11 @@ struct interface_param interface_param[] = {
        "Select the algorithm for selecting port with free channel."},
 
        {"port", &inter_port, "<number>",
+       ""},
+       {"portnum", &inter_portnum, "<number>",
        "Give exactly one port for this interface.\nTo give multiple ports, add more lines with port parameters."},
+       {"portname", &inter_portname, "<name>",
+       "Same as 'portnum', but the name is given instead.\nUse 'isdninfo' to list all available ports and names."},
 
        {"block", &inter_block, "",
        "If keyword is given, calls on this interface are blocked.\n"
@@ -839,17 +908,21 @@ struct interface_param interface_param[] = {
        "This is required on NT-mode ports that are multipoint by default.\n"
        "This parameter must follow a 'port' parameter."},
 
+#if 0
        {"ptmp", &inter_ptmp, "",
        "The given port above is opened as point-to-multipoint.\n"
        "This is required on PRI NT-mode ports that are point-to-point by default.\n"
        "This parameter must follow a 'port' parameter."},
+#endif
+
        {"nt", &inter_nt, "",
        "The given port above is opened in NT-mode.\n"
-#ifdef SOCKET_MISDN
        "This is required on interfaces that support both NT-mode and TE-mode.\n"
-#else
-       "This parameter is only required for socket based mISDN driver.\n"
-#endif
+       "This parameter must follow a 'port' parameter."},
+
+       {"layer2hold", &inter_l2hold, "yes | no",
+       "The given port will continuously try to establish layer 2 link and hold it.\n"
+       "It is required for PTP links in most cases, therefore it is default.\n"
        "This parameter must follow a 'port' parameter."},
 
        {"channel-out", &inter_channel_out, "[force,][<number>][,...][,free][,any][,no]",
@@ -863,7 +936,7 @@ 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"
@@ -871,16 +944,16 @@ struct interface_param interface_param[] = {
        " free - Accept any free channel"},
 
        {"timeouts", &inter_timeouts, "<setup> <dialing> <proceeding> <alerting> <disconnect>",
-       "Timeout values for call states. They are both for incomming and outgoing states.\n"
+       "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"
@@ -898,13 +971,6 @@ struct interface_param interface_param[] = {
        "Disables DTMF detection for this interface.\n"
        "This parameter must follow a 'port' parameter."},
 
-#if 0
-       {"layer2keep", &inter_layer2keep, "yes | no",
-       "By default, layer 2 is establised and kept up on PTP interfaces.\n"
-       ".\n"
-       "This parameter must follow a 'port' parameter."},
-#endif
-
        {"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"
@@ -1259,12 +1325,16 @@ void load_port(struct interface_port *ifport)
        struct mISDNport *mISDNport;
 
        /* open new port */
-       mISDNport = mISDNport_open(ifport->portnum, ifport->ptp, ifport->ptmp, ifport->nt, ifport->interface);
+       mISDNport = mISDNport_open(ifport->portnum, ifport->portname, ifport->ptp, ifport->nt, ifport->l2hold, ifport->interface);
        if (mISDNport)
        {
                /* link port */
                ifport->mISDNport = mISDNport;
                mISDNport->ifport = ifport;
+               /* set number and name */
+               ifport->portnum = mISDNport->portnum;
+               SCPY(ifport->portname, mISDNport->name);
+               /* set defaults */
                set_defaults(ifport);
        } else
        {
@@ -1286,22 +1356,26 @@ void doc_interface(void)
        ifparam = interface_param;
        while(ifparam->name)
        {
-               printf("%s %s\n", ifparam->name, ifparam->usage);
+               if (ifparam->name[0])
+                       printf("%s %s\n", ifparam->name, ifparam->usage);
                ifparam++;
        }
 
        ifparam = interface_param;
        while(ifparam->name)
        {
-               printf("\nParameter: %s %s\n", ifparam->name, ifparam->usage);
-               printf("%s\n", ifparam->help);
+               if (ifparam->name[0])
+               {
+                       printf("\nParameter: %s %s\n", ifparam->name, ifparam->usage);
+                       printf("%s\n", ifparam->help);
+               }
                ifparam++;
        }
 }
 
 
 /* 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)
 {
@@ -1328,13 +1402,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, options.national, options.international), 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, options.national, options.international), 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();
@@ -1367,7 +1441,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, options.national, options.international), NULL, out?DIRECTION_OUT:DIRECTION_IN, 0, 0, "SCREEN (found in screen list)");
                switch(*type)
                {
                        case INFO_NTYPE_UNKNOWN: