From: Andreas Eversberg Date: Fri, 20 Mar 2009 19:46:25 +0000 (+0100) Subject: Added layer1 hold feature. Requires new mISDN and mISDNuser package from git. X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=commitdiff_plain;h=57549529c86785b7ecf5f56d2a3ff42b5e519755 Added layer1 hold feature. Requires new mISDN and mISDNuser package from git. modified: README modified: interface.c modified: interface.h modified: lcradmin.c modified: lcrsocket.h modified: mISDN.cpp modified: mISDN.h modified: socket_server.c --- diff --git a/README b/README index 0013a14..b0772c4 100644 --- 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). + diff --git a/interface.c b/interface.c index 8a367d6..28ad88c 100644 --- a/interface.c +++ b/interface.c @@ -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 */ diff --git a/interface.h b/interface.h index 46671a4..a467a71 100644 --- a/interface.h +++ b/interface.h @@ -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 */ diff --git a/lcradmin.c b/lcradmin.c index dc80d43..306a0da 100644 --- a/lcradmin.c +++ b/lcradmin.c @@ -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 diff --git a/lcrsocket.h b/lcrsocket.h index e7d51c5..69b8c7d 100644 --- a/lcrsocket.h +++ b/lcrsocket.h @@ -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 */ diff --git a/mISDN.cpp b/mISDN.cpp index 2f8dd5f..1bb9362 100644 --- 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 --- 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); diff --git a/socket_server.c b/socket_server.c index 7f6e7ec..a527114 100644 --- a/socket_server.c +++ b/socket_server.c @@ -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 */