unified socket application interface (for asterisk and maybe other apps)
[lcr.git] / interface.c
index 520ecbd..fa7270d 100644 (file)
@@ -18,62 +18,44 @@ struct interface *interface_first = NULL; /* first interface is current list */
 struct interface *interface_newlist = NULL; /* first interface in new list */
 
 
 struct interface *interface_newlist = NULL; /* first interface in new list */
 
 
-/* set default selchannel */
-void default_selchannel(struct interface_port *ifport)
+/* set default out_channel */
+void default_out_channel(struct interface_port *ifport)
 {
        struct select_channel *selchannel, **selchannelp;
 
 {
        struct select_channel *selchannel, **selchannelp;
 
-       /* channel selection for TE-ports */
-       if (!ifport->mISDNport->ntmode)
+       selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel));
+       memuse++;
+       
+       if (ifport->mISDNport->ntmode)
+               selchannel->channel = CHANNEL_FREE;
+       else
+               selchannel->channel = CHANNEL_ANY;
+       
+       ifport->out_channel = selchannel;
+
+       /* additional channel selection for multipoint NT ports */
+       if (!ifport->mISDNport->ptp && ifport->mISDNport->ntmode)
        {
        {
-               selchannel = (struct select_channel *)malloc(sizeof(struct select_channel));
-               if (!selchannel)
-               {
-                       PERROR("No memory!");
-                       return;
-               }
+               selchannelp = &(selchannel->next);
+               selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel));
                memuse++;
                memuse++;
-               memset(*selchannelp, 0, sizeof(struct select_channel));
-               *selchannelp->channel = SEL_CHANNEL_ANY;
-               selchannelp = &ifport->selchannel;
-               while(*selchannelp)
-                       selchannelp = &((*selchannelp)->next);
+               selchannel->channel = CHANNEL_NO; // call waiting
                *selchannelp = selchannel;
                *selchannelp = selchannel;
-               return(0);
        }
        }
+}
 
 
-       /* channel selection for NT-ports */
-       selchannel = (struct select_channel *)malloc(sizeof(struct select_channel));
-       if (!selchannel)
-       {
-               PERROR("No memory!");
-               return;
-       }
+
+/* set default in_channel */
+void default_in_channel(struct interface_port *ifport)
+{
+       struct select_channel *selchannel;
+
+       selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel));
        memuse++;
        memuse++;
-       memset(*selchannelp, 0, sizeof(struct select_channel));
-       *selchannelp->channel = SEL_CHANNEL_FREE;
-       selchannelp = &ifport->selchannel;
-       while(*selchannelp)
-               selchannelp = &((*selchannelp)->next);
-       *selchannelp = selchannel;
-
-       /* additional channel selection for multipoint ports */
-       if (!ifport->mISDNport->ptp)
-       {
-               selchannel = (struct select_channel *)malloc(sizeof(struct select_channel));
-               if (!selchannel)
-               {
-                       PERROR("No memory!");
-                       return;
-               }
-               memuse++;
-               memset(*selchannelp, 0, sizeof(struct select_channel));
-               *selchannelp->channel = SEL_CHANNEL_NO; // call waiting
-               selchannelp = &ifport->selchannel;
-               while(*selchannelp)
-                       selchannelp = &((*selchannelp)->next);
-               *selchannelp = selchannel;
-       }
+       
+       selchannel->channel = CHANNEL_FREE;
+       
+       ifport->in_channel = selchannel;
 }
 
 
 }
 
 
@@ -256,7 +238,6 @@ static int inter_port(struct interface *interface, char *filename, int line, cha
 {
        struct interface_port *ifport, **ifportp;
        struct interface *searchif;
 {
        struct interface_port *ifport, **ifportp;
        struct interface *searchif;
-       struct interface_port *searchport;
        int val;
 
        val = get_number(value);
        int val;
 
        val = get_number(value);
@@ -269,7 +250,7 @@ static int inter_port(struct interface *interface, char *filename, int line, cha
        searchif = interface_newlist;
        while(searchif)
        {
        searchif = interface_newlist;
        while(searchif)
        {
-               searchport = searchif->ifport;
+               ifport = searchif->ifport;
                while(ifport)
                {
                        if (ifport->portnum == val)
                while(ifport)
                {
                        if (ifport->portnum == val)
@@ -282,14 +263,8 @@ static int inter_port(struct interface *interface, char *filename, int line, cha
                searchif = searchif->next;
        }
        /* alloc port substructure */
                searchif = searchif->next;
        }
        /* alloc port substructure */
-       ifport = (struct interface_port *)malloc(sizeof(struct interface_port));
-       if (!ifport)
-       {
-               SPRINT(interface_error, "No memory!");
-               return(-1);
-       }
+       ifport = (struct interface_port *)MALLOC(sizeof(struct interface_port));
        memuse++;
        memuse++;
-       memset(ifport, 0, sizeof(struct interface_port));
        ifport->interface = interface;
        /* set value */
        ifport->portnum = val;
        ifport->interface = interface;
        /* set value */
        ifport->portnum = val;
@@ -325,7 +300,7 @@ static int inter_channel_out(struct interface *interface, char *filename, int li
                if (!strcasecmp(el, "force"))
                {
                        ifport->channel_force = 1;
                if (!strcasecmp(el, "force"))
                {
                        ifport->channel_force = 1;
-                       if (ifport->selchannel)
+                       if (ifport->out_channel)
                        {
                                SPRINT(interface_error, "Error in %s (line %d): value 'force' may only appear as first element in list.\n", filename, line);
                                return(-1);
                        {
                                SPRINT(interface_error, "Error in %s (line %d): value 'force' may only appear as first element in list.\n", filename, line);
                                return(-1);
@@ -333,17 +308,17 @@ static int inter_channel_out(struct interface *interface, char *filename, int li
                } else
                if (!strcasecmp(el, "any"))
                {
                } else
                if (!strcasecmp(el, "any"))
                {
-                       val = SEL_CHANNEL_ANY;
+                       val = CHANNEL_ANY;
                        goto selchannel;
                } else
                if (!strcasecmp(el, "free"))
                {
                        goto selchannel;
                } else
                if (!strcasecmp(el, "free"))
                {
-                       val = SEL_CHANNEL_FREE;
+                       val = CHANNEL_FREE;
                        goto selchannel;
                } else
                if (!strcasecmp(el, "no"))
                {
                        goto selchannel;
                } else
                if (!strcasecmp(el, "no"))
                {
-                       val = SEL_CHANNEL_NO;
+                       val = CHANNEL_NO;
                        goto selchannel;
                } else
                {
                        goto selchannel;
                } else
                {
@@ -361,18 +336,12 @@ static int inter_channel_out(struct interface *interface, char *filename, int li
                        }
                        selchannel:
                        /* add to select-channel list */
                        }
                        selchannel:
                        /* add to select-channel list */
-                       selchannel = (struct select_channel *)malloc(sizeof(struct select_channel));
-                       if (!selchannel)
-                       {
-                               SPRINT(interface_error, "No memory!");
-                               return(-1);
-                       }
+                       selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel));
                        memuse++;
                        memuse++;
-                       memset(selchannel, 0, sizeof(struct select_channel));
                        /* set value */
                        selchannel->channel = val;
                        /* tail port */
                        /* set value */
                        selchannel->channel = val;
                        /* tail port */
-                       selchannelp = &ifport->selchannel;
+                       selchannelp = &ifport->out_channel;
                        while(*selchannelp)
                                selchannelp = &((*selchannelp)->next);
                        *selchannelp = selchannel;
                        while(*selchannelp)
                                selchannelp = &((*selchannelp)->next);
                        *selchannelp = selchannel;
@@ -402,14 +371,14 @@ static int inter_channel_in(struct interface *interface, char *filename, int lin
        {
                el = p;
                p = get_seperated(p);
        {
                el = p;
                p = get_seperated(p);
-               if (ifport->in_select) if (ifport->in_select->channel == SEL_CHANNEL_FREE)
+               if (ifport->in_channel) if (ifport->in_channel->channel == CHANNEL_FREE)
                {
                        SPRINT(interface_error, "Error in %s (line %d): parameter '%s' has values behind 'free' keyword. They has no effect.\n", filename, line, parameter);
                                return(-1);
                }
                if (!strcasecmp(el, "free"))
                {
                {
                        SPRINT(interface_error, "Error in %s (line %d): parameter '%s' has values behind 'free' keyword. They has no effect.\n", filename, line, parameter);
                                return(-1);
                }
                if (!strcasecmp(el, "free"))
                {
-                       val = SEL_CHANNEL_FREE;
+                       val = CHANNEL_FREE;
                        goto selchannel;
                } else
                {
                        goto selchannel;
                } else
                {
@@ -427,18 +396,12 @@ static int inter_channel_in(struct interface *interface, char *filename, int lin
                        }
                        selchannel:
                        /* add to select-channel list */
                        }
                        selchannel:
                        /* add to select-channel list */
-                       selchannel = (struct select_channel *)malloc(sizeof(struct select_channel));
-                       if (!selchannel)
-                       {
-                               SPRINT(interface_error, "No memory!");
-                               return(-1);
-                       }
+                       selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel));
                        memuse++;
                        memuse++;
-                       memset(selchannel, 0, sizeof(struct select_channel));
                        /* set value */
                        selchannel->channel = val;
                        /* tail port */
                        /* set value */
                        selchannel->channel = val;
                        /* tail port */
-                       selchannelp = &ifport->in_select;
+                       selchannelp = &ifport->in_channel;
                        while(*selchannelp)
                                selchannelp = &((*selchannelp)->next);
                        *selchannelp = selchannel;
                        while(*selchannelp)
                                selchannelp = &((*selchannelp)->next);
                        *selchannelp = selchannel;
@@ -469,14 +432,8 @@ static int inter_msn(struct interface *interface, char *filename, int line, char
                el = p;
                p = get_seperated(p);
                /* add MSN to list */
                el = p;
                p = get_seperated(p);
                /* add MSN to list */
-               ifmsn = (struct interface_msn *)malloc(sizeof(struct interface_msn));
-               if (!ifmsn)
-               {
-                       SPRINT(interface_error, "No memory!");
-                       return(-1);
-               }
+               ifmsn = (struct interface_msn *)MALLOC(sizeof(struct interface_msn));
                memuse++;
                memuse++;
-               memset(ifmsn, 0, sizeof(struct interface_msn));
                /* set value */
                SCPY(ifmsn->msn, el);
                /* tail port */
                /* set value */
                SCPY(ifmsn->msn, el);
                /* tail port */
@@ -501,15 +458,10 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
        el = p;
        p = get_seperated(p);
        /* add screen entry to list*/
        el = p;
        p = get_seperated(p);
        /* add screen entry to list*/
-       ifscreen = (struct interface_screen *)malloc(sizeof(struct interface_screen));
-       if (!ifscreen)
-       {
-               SPRINT(interface_error, "No memory!");
-               return(-1);
-       }
+       ifscreen = (struct interface_screen *)MALLOC(sizeof(struct interface_screen));
        memuse++;
        memuse++;
-       memset(ifscreen, 0, sizeof(struct interface_screen));
-#warning handle unchanged as unchanged!!
+       ifscreen->match_type = -1; /* unchecked */
+       ifscreen->match_present = -1; /* unchecked */
        ifscreen->result_type = -1; /* unchanged */
        ifscreen->result_present = -1; /* unchanged */
        /* tail port */
        ifscreen->result_type = -1; /* unchanged */
        ifscreen->result_present = -1; /* unchanged */
        /* tail port */
@@ -554,7 +506,7 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
                        if (ifscreen->match_present != -1)
                        {
                                presenterror:
                        if (ifscreen->match_present != -1)
                        {
                                presenterror:
-                               SPRINT(interface_error, "Error in %s (line %d): presentation type already set earlier.\n", filename, line, parameter);
+                               SPRINT(interface_error, "Error in %s (line %d): presentation type already set earlier.\n", filename, line);
                                return(-1);
                        }
                        ifscreen->match_present = INFO_PRESENT_ALLOWED;
                                return(-1);
                        }
                        ifscreen->match_present = INFO_PRESENT_ALLOWED;
@@ -566,6 +518,15 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
                        ifscreen->match_present = INFO_PRESENT_RESTRICTED;
                } else {
                        SCPY(ifscreen->match, el);
                        ifscreen->match_present = INFO_PRESENT_RESTRICTED;
                } else {
                        SCPY(ifscreen->match, el);
+                       /* check for % at the end */
+                       if (strchr(el, '%'))
+                       {
+                               if (strchr(el, '%') != el+strlen(el)-1)
+                               {
+                                       SPRINT(interface_error, "Error in %s (line %d): %% joker found, but must at the end.\n", filename, line, parameter);
+                                       return(-1);
+                               }
+                       }
                        break;
                }
        }
                        break;
                }
        }
@@ -616,6 +577,15 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
                        ifscreen->result_present = INFO_PRESENT_RESTRICTED;
                } else {
                        SCPY(ifscreen->result, el);
                        ifscreen->result_present = INFO_PRESENT_RESTRICTED;
                } else {
                        SCPY(ifscreen->result, el);
+                       /* check for % at the end */
+                       if (strchr(el, '%'))
+                       {
+                               if (strchr(el, '%') != el+strlen(el)-1)
+                               {
+                                       SPRINT(interface_error, "Error in %s (line %d): %% joker found, but must at the end.\n", filename, line, parameter);
+                                       return(-1);
+                               }
+                       }
                        break;
                }
        }
                        break;
                }
        }
@@ -640,11 +610,30 @@ static int inter_screen_out(struct interface *interface, char *filename, int lin
 {
        return(inter_screen(&interface->ifscreen_out, interface, filename, line, parameter, value));
 }
 {
        return(inter_screen(&interface->ifscreen_out, interface, filename, line, parameter, value));
 }
-static int inter_filter(struct interface *interface, char *filename, int line, char *parameter, char *value)
+static int inter_nodtmf(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;
+       ifport->nodtmf = 1;
+       return(0);
+}
 #warning filter to be done
 #warning filter to be done
+#if 0
+static int inter_filter(struct interface *interface, char *filename, int line, char *parameter, char *value)
+{
        return(0);
 }
        return(0);
 }
+#endif
 
 
 /*
 
 
 /*
@@ -679,7 +668,7 @@ struct interface_param interface_param[] = {
        "This is required on PRI NT-mode ports that are point-to-point by default.\n"
        "This parameter must follow a 'port' parameter."},
 
        "This is required on PRI NT-mode ports that are point-to-point by default.\n"
        "This parameter must follow a 'port' parameter."},
 
-       {"channel_out", &inter_channel_out, "[force,][<number>][,...][,free][,any][,no]",
+       {"channel-out", &inter_channel_out, "[force,][<number>][,...][,free][,any][,no]",
        "Channel selection list for all outgoing calls to the interface.\n"
        "A free channels is searched in order of appearance.\n"
        "This parameter must follow a 'port' parameter.\n"
        "Channel selection list for all outgoing calls to the interface.\n"
        "A free channels is searched in order of appearance.\n"
        "This parameter must follow a 'port' parameter.\n"
@@ -689,13 +678,13 @@ struct interface_param interface_param[] = {
        " any - On outgoing calls, signal 'any channel acceptable'. (see DSS1)\n"
        " no - Signal 'no channel available' aka 'call waiting'. (see DSS1)"},
 
        " any - On outgoing calls, signal 'any channel acceptable'. (see DSS1)\n"
        " no - Signal 'no channel available' aka 'call waiting'. (see DSS1)"},
 
-       {"channel_in", &inter_channel_in, "[force,][<number>][,...][,free][,any][,no]",
+       {"channel-in", &inter_channel_in, "[force,][<number>][,...][,free][,any][,no]",
        "Channel selection list for all incomming calls from the interface.\n"
        "A free channels is accepted if in the list.\n"
        "Channel selection list for all incomming calls from the interface.\n"
        "A free channels is accepted if in the list.\n"
-       "If no channel was requested, the first free channel found is selected.\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"
        "This parameter must follow a 'port' parameter.\n"
        " <number>[,...] - List of channels to accept.\n"
-       " free - Accept any free channel\n"
+       " free - Accept any free channel"},
 
        {"msn", &inter_msn, "<default MSN>,[<additional MSN>[,...]]",
        "Incomming caller ID is checked against given MSN numbers.\n"
 
        {"msn", &inter_msn, "<default MSN>,[<additional MSN>[,...]]",
        "Incomming caller ID is checked against given MSN numbers.\n"
@@ -716,10 +705,17 @@ struct interface_param interface_param[] = {
        "Adds an entry for outgoing calls to the caller ID screen list.\n"
        "See 'screen-in' for help."},
 
        "Adds an entry for outgoing calls to the caller ID screen list.\n"
        "See 'screen-in' for help."},
 
+       {"nodtmf", &inter_nodtmf, "",
+       "Disables DTMF detection for this interface.\n"
+       "This parameter must follow a 'port' parameter."},
+
+#if 0
+#warning todo: filter, also in the PmISDN object
        {"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"
        "blowfish <key> - Adds encryption. Key must be 4-56 bytes (8-112 hex characters."},
        {"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"
        "blowfish <key> - Adds encryption. Key must be 4-56 bytes (8-112 hex characters."},
+#endif
 
        {NULL, NULL, NULL, NULL}
 };
 
        {NULL, NULL, NULL, NULL}
 };
@@ -744,10 +740,7 @@ struct interface *read_interfaces(void)
        struct interface_param  *ifparam;
 
        if (interface_newlist != NULL)
        struct interface_param  *ifparam;
 
        if (interface_newlist != NULL)
-       {
-               PERROR("software error, list is not empty.\n");
-               exit(-1);
-       }
+               FATAL("list is not empty.\n");
        interface_error[0] = '\0';
        SPRINT(filename, "%s/interface.conf", INSTALL_DATA);
 
        interface_error[0] = '\0';
        SPRINT(filename, "%s/interface.conf", INSTALL_DATA);
 
@@ -838,7 +831,7 @@ struct interface *read_interfaces(void)
                        parameter[strlen(parameter)-1] = '\0';
 
                        /* check if interface name already exists */
                        parameter[strlen(parameter)-1] = '\0';
 
                        /* check if interface name already exists */
-                       interface = interface_first;
+                       interface = interface_newlist;
                        while(interface)
                        {
                                if (!strcasecmp(interface->name, parameter+1))
                        while(interface)
                        {
                                if (!strcasecmp(interface->name, parameter+1))
@@ -850,14 +843,8 @@ struct interface *read_interfaces(void)
                        }
 
                        /* append interface to new list */
                        }
 
                        /* append interface to new list */
-                       interface = (struct interface *)malloc(sizeof(struct interface));
-                       if (!interface)
-                       {
-                               SPRINT(interface_error, "No memory!");
-                               goto error;
-                       }
+                       interface = (struct interface *)MALLOC(sizeof(struct interface));
                        memuse++;
                        memuse++;
-                       memset(interface, 0, sizeof(struct interface));
 
                        /* name interface */
                        SCPY(interface->name, parameter+1);
 
                        /* name interface */
                        SCPY(interface->name, parameter+1);
@@ -876,10 +863,12 @@ struct interface *read_interfaces(void)
                        {
                                if (ifparam->func(interface, filename, line, parameter, value))
                                        goto error;
                        {
                                if (ifparam->func(interface, filename, line, parameter, value))
                                        goto error;
-                               continue;
+                               break;
                        }
                        ifparam++;
                }
                        }
                        ifparam++;
                }
+               if (ifparam->name)
+                       continue;
 
                SPRINT(interface_error, "Error in %s (line %d): unknown parameter: '%s'.\n", filename, line, parameter);
                goto error;
 
                SPRINT(interface_error, "Error in %s (line %d): unknown parameter: '%s'.\n", filename, line, parameter);
                goto error;
@@ -918,8 +907,7 @@ void free_interfaces(struct interface *interface)
                        {
                                temp = selchannel;
                                selchannel = selchannel->next;
                        {
                                temp = selchannel;
                                selchannel = selchannel->next;
-                               memset(temp, 0, sizeof(struct select_channel));
-                               free(temp);
+                               FREE(temp, sizeof(struct select_channel));
                                memuse--;
                        }
                        selchannel = ifport->out_channel;
                                memuse--;
                        }
                        selchannel = ifport->out_channel;
@@ -927,14 +915,12 @@ void free_interfaces(struct interface *interface)
                        {
                                temp = selchannel;
                                selchannel = selchannel->next;
                        {
                                temp = selchannel;
                                selchannel = selchannel->next;
-                               memset(temp, 0, sizeof(struct select_channel));
-                               free(temp);
+                               FREE(temp, sizeof(struct select_channel));
                                memuse--;
                        }
                        temp = ifport;
                        ifport = ifport->next;
                                memuse--;
                        }
                        temp = ifport;
                        ifport = ifport->next;
-                       memset(temp, 0, sizeof(struct interface_port));
-                       free(temp);
+                       FREE(temp, sizeof(struct interface_port));
                        memuse--;
                }
                ifmsn = interface->ifmsn;
                        memuse--;
                }
                ifmsn = interface->ifmsn;
@@ -942,8 +928,7 @@ void free_interfaces(struct interface *interface)
                {
                        temp = ifmsn;
                        ifmsn = ifmsn->next;
                {
                        temp = ifmsn;
                        ifmsn = ifmsn->next;
-                       memset(temp, 0, sizeof(struct interface_msn));
-                       free(temp);
+                       FREE(temp, sizeof(struct interface_msn));
                        memuse--;
                }
                ifscreen = interface->ifscreen_in;
                        memuse--;
                }
                ifscreen = interface->ifscreen_in;
@@ -951,8 +936,7 @@ void free_interfaces(struct interface *interface)
                {
                        temp = ifscreen;
                        ifscreen = ifscreen->next;
                {
                        temp = ifscreen;
                        ifscreen = ifscreen->next;
-                       memset(temp, 0, sizeof(struct interface_screen));
-                       free(temp);
+                       FREE(temp, sizeof(struct interface_screen));
                        memuse--;
                }
                ifscreen = interface->ifscreen_out;
                        memuse--;
                }
                ifscreen = interface->ifscreen_out;
@@ -960,8 +944,7 @@ void free_interfaces(struct interface *interface)
                {
                        temp = ifscreen;
                        ifscreen = ifscreen->next;
                {
                        temp = ifscreen;
                        ifscreen = ifscreen->next;
-                       memset(temp, 0, sizeof(struct interface_screen));
-                       free(temp);
+                       FREE(temp, sizeof(struct interface_screen));
                        memuse--;
                }
                iffilter = interface->iffilter;
                        memuse--;
                }
                iffilter = interface->iffilter;
@@ -969,18 +952,43 @@ void free_interfaces(struct interface *interface)
                {
                        temp = iffilter;
                        iffilter = iffilter->next;
                {
                        temp = iffilter;
                        iffilter = iffilter->next;
-                       memset(temp, 0, sizeof(struct interface_filter));
-                       free(temp);
+                       FREE(temp, sizeof(struct interface_filter));
                        memuse--;
                }
                temp = interface;
                interface = interface->next;
                        memuse--;
                }
                temp = interface;
                interface = interface->next;
-               memset(temp, 0, sizeof(struct interface));
-               free(temp);
+               FREE(temp, sizeof(struct interface));
                memuse--;
        }
 }
 
                memuse--;
        }
 }
 
+/*
+ * defaults of ports if not specified by config
+ */
+static void set_defaults(struct interface_port *ifport)
+{
+       /* default channel selection list */
+       if (!ifport->out_channel)
+               default_out_channel(ifport);
+       if (!ifport->in_channel)
+               default_in_channel(ifport);
+       /* default is_tones */
+       if (ifport->interface->is_tones)
+               ifport->mISDNport->tones = (ifport->interface->is_tones==IS_YES);
+       else
+               ifport->mISDNport->tones = (ifport->mISDNport->ntmode)?1:0;
+       /* default is_earlyb */
+       if (ifport->interface->is_earlyb)
+               ifport->mISDNport->earlyb = (ifport->interface->is_earlyb==IS_YES);
+       else
+               ifport->mISDNport->earlyb = (ifport->mISDNport->ntmode)?0:1;
+       /* set locally flag */
+       if (ifport->interface->extension)
+               ifport->mISDNport->locally = 1;
+       else
+               ifport->mISDNport->locally = 0;
+}
+
 
 /*
  * all links between mISDNport and interface are made
 
 /*
  * all links between mISDNport and interface are made
@@ -1015,6 +1023,7 @@ void relink_interfaces(void)
                                {
                                        ifport->mISDNport = mISDNport;
                                        mISDNport->ifport = ifport;
                                {
                                        ifport->mISDNport = mISDNport;
                                        mISDNport->ifport = ifport;
+                                       set_defaults(ifport);
                                }
                                mISDNport = mISDNport->next;
                        }
                                }
                                mISDNport = mISDNport->next;
                        }
@@ -1047,36 +1056,37 @@ void relink_interfaces(void)
                {
                        if (!ifport->mISDNport)
                        {
                {
                        if (!ifport->mISDNport)
                        {
-                               /* open new port */
-                               mISDNport = mISDNport_open(ifport->portnum, ifport->ptp, ifport->ptmp);
-                               if (mISDNport)
-                               {
-                                       ifport->mISDNport = mISDNport;
-                                       mISDNport->ifport = ifport;
-                               }
-                       }
-                       if (ifport->mISDNport)
-                       {
-                               /* default channel selection list */
-                               if (!ifport->selchannel)
-                                       default_selchannel(ifport);
-                               /* default is_tones */
-                               if (ifport->interface->is_tones)
-                                       ifport->mISDNport->is_tones = (ifport->interface->is_tones==IS_YES);
-                               else
-                                       ifport->mISDNport->is_tones = (ifport->mISDNport->ntmode)?1:0;
-                               /* default is_earlyb */
-                               if (ifport->interface->is_earlyb)
-                                       ifport->mISDNport->is_earlyb = (ifport->interface->is_earlyb==IS_YES);
-                               else
-                                       ifport->mISDNport->is_earlyb = (ifport->mISDNport->ntmode)?0:1;
+                               load_port(ifport);
                        }
                        }
+                       ifport = ifport->next;
                }
                interface = interface->next;
        }
 
 }
 
                }
                interface = interface->next;
        }
 
 }
 
+
+/*
+ * load port
+ */
+void load_port(struct interface_port *ifport)
+{
+       struct mISDNport *mISDNport;
+
+       /* open new port */
+       mISDNport = mISDNport_open(ifport->portnum, ifport->ptp, ifport->ptmp, ifport->interface);
+       if (mISDNport)
+       {
+               /* link port */
+               ifport->mISDNport = mISDNport;
+               mISDNport->ifport = ifport;
+               set_defaults(ifport);
+       } else
+       {
+               ifport->block = 2; /* not available */
+       }
+}
+
 /*
  * give summary of interface syntax
  */
 /*
  * give summary of interface syntax
  */
@@ -1104,4 +1114,3 @@ void doc_interface(void)
        }
 }
 
        }
 }
 
-