Added layer1 hold feature. Requires new mISDN and mISDNuser package from git.
authorAndreas Eversberg <andreas@eversberg.eu>
Fri, 20 Mar 2009 19:46:25 +0000 (20:46 +0100)
committerAndreas Eversberg <andreas@eversberg.eu>
Fri, 20 Mar 2009 19:46:25 +0000 (20:46 +0100)
modified:   README
modified:   interface.c
modified:   interface.h
modified:   lcradmin.c
modified:   lcrsocket.h
modified:   mISDN.cpp
modified:   mISDN.h
modified:   socket_server.c

README
interface.c
interface.h
lcradmin.c
lcrsocket.h
mISDN.cpp
mISDN.h
socket_server.c

diff --git a/README b/README
index 0013a14..b0772c4 100644 (file)
--- a/README
+++ b/README
@@ -478,3 +478,5 @@ Changes after Version 1.4 release
 - Fixed dtmf detection of A-D. (thanx to Ralf)
 - Fixed Notification messages in NT-mode
   -> Notifications like diversions are now sent to terminal.
+- Added l1hold feature (requires new mISDN and mISDNuser).
+
index 8a367d6..28ad88c 100644 (file)
@@ -360,6 +360,34 @@ static int inter_portname(struct interface *interface, char *filename, int line,
        *ifportp = ifport;
        return(0);
 }
+static int inter_l1hold(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->l1hold = 1;
+       } else
+       if (!strcmp(value, "no"))
+       {
+               ifport->l1hold = 0;
+       } 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_l2hold(struct interface *interface, char *filename, int line, char *parameter, char *value)
 {
        struct interface_port *ifport;
@@ -968,6 +996,11 @@ struct interface_param interface_param[] = {
        "Note that this is not compliant with ISDN protocol.\n"
        "This parameter must follow a 'port' parameter."},
 
+       {"layer1hold", &inter_l1hold, "yes | no",
+       "The given port will not release layer 1 after layer 2 is down.\n"
+       "It is required to keep layer 1 of telephones up, to solve activation problems.\n"
+       "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"
@@ -1379,7 +1412,7 @@ void load_port(struct interface_port *ifport)
        struct mISDNport *mISDNport;
 
        /* open new port */
-       mISDNport = mISDNport_open(ifport->portnum, ifport->portname, ifport->ptp, ifport->nt, ifport->tespecial, ifport->l2hold, ifport->interface);
+       mISDNport = mISDNport_open(ifport->portnum, ifport->portname, ifport->ptp, ifport->nt, ifport->tespecial, ifport->l1hold, ifport->l2hold, ifport->interface);
        if (mISDNport)
        {
                /* link port */
index 46671a4..a467a71 100644 (file)
@@ -49,7 +49,8 @@ struct interface_port {
        int                     ptmp; /* force load stack in PTP mode */
        int                     nt; /* load stack in NT-mode */
        int                     tespecial; /* special TE-mode behavior */
-       int                     l2hold; /* hold layer 2 (1=force, -1=disable */
+       int                     l1hold; /* hold layer 1 (1=on, 0=off) */
+       int                     l2hold; /* hold layer 2 (1=force, -1=disable, 0=default) */
        int                     channel_force; /* forces channel by protocol */
        int                     nodtmf; /* disables DTMF */
        struct select_channel   *out_channel; /* list of channels to select */
index dc80d43..306a0da 100644 (file)
@@ -678,7 +678,19 @@ const char *admin_state(int sock, char *argv[])
                                addstr("  not loaded");
                        } else
                        {
-                               SPRINT(buffer, "%s (port %d: %s) %s %s%s use:%d", m[i].u.i.interface_name, m[i].u.i.portnum, m[i].u.i.portname, (m[i].u.i.ntmode)?"NT-mode":"TE-mode", (m[i].u.i.ptp)?"ptp ":"ptmp", (m[i].u.i.extension)?" extension":"", m[i].u.i.use);
+                               SPRINT(buffer, "%s", m[i].u.i.interface_name);
+                               addstr(buffer);
+                               color(yellow);
+                               SPRINT(buffer, "(port %d: %s)", m[i].u.i.portnum, m[i].u.i.portname);
+                               addstr(buffer);
+                               color(cyan);
+                               SPRINT(buffer, " %s %s%s%s%s", (m[i].u.i.ntmode)?"NT-mode":"TE-mode", (m[i].u.i.ptp)?"ptp":"ptmp", (m[i].u.i.l1hold)?" l1hold":"", (m[i].u.i.l2hold)?" l2hold":"", (m[i].u.i.extension)?" extension":"");
+                               addstr(buffer);
+                               if (m[i].u.i.use)
+                                       color(green);
+                               else
+                                       color(blue);
+                               SPRINT(buffer, " use:%d", m[i].u.i.use);
                                addstr(buffer);
                                if (m[i].u.i.ptp || !m[i].u.i.ntmode)
                                {
@@ -1403,7 +1415,7 @@ const char *admin_portinfo(int sock, int argc, char *argv[])
                                printf("\t status = blocked\n");
                        else
                                printf("\t status = unblocked\n");
-                       printf("\t mode = %s %s\n", (m[i].u.i.ntmode)?"NT-mode":"TE-mode", (m[i].u.i.ptp)?"ptp ":"ptmp");
+                       printf("\t mode = %s %s%s%s\n", (m[i].u.i.ntmode)?"NT-mode":"TE-mode", (m[i].u.i.ptp)?"ptp":"ptmp", (m[i].u.i.l1hold)?" l1hold":"", (m[i].u.i.l2hold)?" l2hold":"");
                        if (m[i].u.i.l1link < 0)
                                printf("\t l1 link = unknown\n");
                        else
index e7d51c5..69b8c7d 100644 (file)
@@ -69,6 +69,8 @@ struct admin_response_interface {
        int             block;
        int             ntmode;
        int             ptp;
+       int             l1hold;
+       int             l2hold;
        int             pri;
        int             extension;
        int             use; /* number of ports that use this interface */
index 2f8dd5f..1bb9362 100644 (file)
--- a/mISDN.cpp
+++ b/mISDN.cpp
@@ -2124,7 +2124,7 @@ int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3
 /*
  * global function to add a new card (port)
  */
-struct mISDNport *mISDNport_open(int port, char *portname, int ptp, int force_nt, int te_special, int l2hold, struct interface *interface)
+struct mISDNport *mISDNport_open(int port, char *portname, int ptp, int force_nt, int te_special, int l1hold, int l2hold, struct interface *interface)
 {
        int ret;
        struct mISDNport *mISDNport, **mISDNportp;
@@ -2310,6 +2310,8 @@ struct mISDNport *mISDNport_open(int port, char *portname, int ptp, int force_nt
               prop |= (1 << MISDN_FLG_PTP);
        if (nt) // supports hold/retrieve on nt-mode
               prop |= (1 << MISDN_FLG_NET_HOLD);
+       if (l1hold) // supports layer 1 hold
+              prop |= (1 << MISDN_FLG_L1_HOLD);
        if (l2hold) // supports layer 2 hold
               prop |= (1 << MISDN_FLG_L2_HOLD);
        /* queue must be initializes, because l3-thread may send messages during open_layer3() */
@@ -2355,6 +2357,7 @@ struct mISDNport *mISDNport_open(int port, char *portname, int ptp, int force_nt
        mISDNport->tespecial = te_special;
        mISDNport->pri = pri;
        mISDNport->ptp = ptp;
+       mISDNport->l1hold = l1hold;
        mISDNport->l2hold = l2hold;
        PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
        i = 0;
diff --git a/mISDN.h b/mISDN.h
index b93ebb2..9907b9a 100644 (file)
--- a/mISDN.h
+++ b/mISDN.h
@@ -39,6 +39,7 @@ struct mISDNport {
        int ptp; /* if ptp is set, we keep track of l2link */
        int l1link; /* if l1 is available (only works with nt-mode) */
        int l2link; /* if l2 is available (at PTP we take this serious) */
+       int l1hold; /* set, if layer 1 should be holt */
        int l2hold; /* set, if layer 2 must be hold/checked */
        time_t l2establish; /* time until establishing after link failure */
        int use; /* counts the number of port that uses this port */
@@ -80,7 +81,7 @@ calls with no bchannel (call waiting, call on hold).
 /* mISDN none-object functions */
 int mISDN_initialize(void);
 void mISDN_deinitialize(void);
-struct mISDNport *mISDNport_open(int port, char *portname, int ptp, int force_nt, int te_special, int l2hold, struct interface *interface);
+struct mISDNport *mISDNport_open(int port, char *portname, int ptp, int force_nt, int te_special, int l1hold, int l2hold, struct interface *interface);
 void mISDNport_close_all(void);
 void mISDNport_close(struct mISDNport *mISDNport);
 void mISDN_port_reorder(void);
index 7f6e7ec..a527114 100644 (file)
@@ -900,6 +900,10 @@ int admin_state(struct admin_queue **responsep)
 
                                /* ptp */
                                response->am[num].u.i.ptp = mISDNport->ptp;
+                               /* l1hold */
+                               response->am[num].u.i.l1hold = mISDNport->l1hold;
+                               /* l2hold */
+                               response->am[num].u.i.l2hold = mISDNport->l2hold;
                                /* ntmode */
                                response->am[num].u.i.ntmode = mISDNport->ntmode;
                                /* pri */