This commit is contained in:
Matthias Urlichs 1995-11-02 10:15:35 +01:00 committed by Harald Welte
parent 0bada575c3
commit 31dd84ea4c
21 changed files with 672 additions and 365 deletions

73
DOKU
View File

@ -801,11 +801,14 @@ Protokolle und Flags in der DL-Zeile:
Die Reihenfolge ist wichtig.
:pp Punkt-zu-Punkt-Verbindung, feste TEI (0x00). :kl ebenfalls
angeben!
:pp Punkt-zu-Punkt-Verbindung, feste TEI (0x00).
Vorsicht: Anlagenanschluß wird vom 1TR6-Treiber nicht und vom
Euro-Treiber nur unvollständig unterstützt.
:mp Verbindung am Bus, variabler TEI-Identifier. Bei manchen 1TR6-
Vermittlungen und Nebenstellenanlagen sinnvoll.
:mf Verbindung am Bus, fester TEI-Identifier. Default.
Vermittlungen und Nebenstellenanlagen notwendig, in der DSS1-
Norm vorgeschrieben.
:mq Verbindung am Bus, fester TEI-Identifier. Default, weil es an
vielen Anlagen besser funktioniert als :mp.
:mt Verbindung am Bus, feste TEI(0x12). In Spezialfällen notwendig.
:de Debugging, macht D-Kanal-Datenaustausch beobachtbar (mit AT/W).
Vorsicht: Diese Option verlangsamt das gesamte ISDN-System, auch
@ -825,14 +828,17 @@ Die Reihenfolge ist wichtig.
verwendet werden. <phone>
:kl Level-2-Verbindung zur Vermittlung nicht trennen. Bei Punkt-
zu-Punkt-Verbindungen und bei entsprechend konfigurierten
ISDN-Anschlüssen ("Dauerüberwachung oder sowas ähnliches")
ISDN-Anschlüssen ("Dauerüberwachung" oder sowas ähnliches)
notwendig.
:cl Level-2-Verbindung zur Vermittlung trennen, wenn keine
Verbindung besteht. Default.
:sp 8 DSS1, Euro-ISDN. [euro]
:sp 65 1TR6, deutscher Standard. [german]
Entweder :sp 8 oder :sp 65 muß angegeben werden, NICHT beides!
:sp 8 DSS1, Euro-ISDN. [euro]
:b1 an manchen Nebenstellen zur korekten Nummernerkennung notwendig.
Einschalten, wenn die Nebenstellennummer nicht mit . oder /
eingeleitet wird.
:sp 65 1TR6, deutscher Standard. [german]
:ai Ankommenden Anruf mit dem ISDN-Äquivalent von "RINGING"
beantworten, dann prüfen ob der Anruf angenommen werden kann.
@ -844,26 +850,27 @@ Die Reihenfolge ist wichtig.
beschäftigten Rechnern und bei manchen Telefonanlagen.
:td TEI beim ersten Verbindungsaufbau zuordnen lassen. Default.
:pr 64 Festverbindung: kein D-Kanal. <fixed>
:pr 65 Intelligente Karte mit CAPI-1.x-Schnittstelle. (Noch nicht!)
:pr 65 Intelligente Karte mit CAPI-1.x-Schnittstelle.
In der Konfiguration verhält sich eine CAPI-Karte ansonsten wie
der 1TR6-Treiber, und zwar AUCH DANN WENN DAS TEIl AM EURO-ISDN
der 1TR6-Treiber, und zwar AUCH DANN WENN DAS TEIL AM EURO-ISDN
HÄNGT. <capi>
:pb Verwendet die CAPI wie eine Nebenstellenanlage, d.h. ankommend
Akkumulation ankommender Ziffern, abgehend dynamisches Mapping
EAZ->Nebenstellennummer. (Teilweise implementiert: ankommend
funktioniert nur Blockwahl.)
:pb Die Karte hängt an einem Anlagenanschluß / S2M und verhält sich
wie eine Nebenstellenanlage.
:sp 0 Bintec-Karte. [bintec]
Auf diese Karte muß zunächst boot.68k und dann entweder bri.68k,
bri_4.68k oder pmx.68k geladen werden (LF-Zeile).
Auf diese Karte muß zunächst boot.68k und dann entweder bri.68k
oder pmx.68k geladen werden (LF-Zeile).
:sc X Die folgenden Optionen betreffen nur das Xte Interface
auf der Karte. X in 1..4.
:lp X X X CAPI-Bitmasken für EAZ, Service, Infos. Hexadezimal.
Default: 03FF E7BF 003F.
:st XXXXX Protokollstack XXXXX laden. Siehe Handbuch zur Karte.
Default ist u_dss1_pmp.
:ea N NNN EAZ N auf (lokale) Endnummer NNN mappen.
Default ist u_1tr6_pmp (wenn "german" und nicht "euro" inn
config/config-data angegeben wurde) oder u_dss1_pmp (sonst).
:ea N NNN EAZ N auf lokale Nummer (MSN) NNN mappen.
Default ist die letzte Ziffer der Nummer.
Nicht bei :pb verwenden.
:lw X Warte bis zu X Sekunden auf nachgewählte Ziffern.
Nur bei :pb verwenden.
DP-Zeile ("Dial Prefix")
@ -896,6 +903,8 @@ DP... -
MP... :nr /5
würde die Nummer 12345 wählen.
Siehe auch unten unter "Bugs anderer Leute".
R-Zeile ("Run")
-------
@ -1014,11 +1023,13 @@ Parameter.
LF-Zeile ("Load File")
--------
Form: LF <Karte> <Segmentgröße> <Dateiname>
Form: LF <Karte> <Segmentgröße> <Delay> <Dateiname>
Lädt die Datei auf die (aktive) Karte. Mehrere LF-Zeilen können angegeben
werden (in der richtigen Reihenfolge!). Die maximal mögliche Segmentgröße
ist 4096.
werden (in der richtigen Reihenfolge! Doku beachten!). Die maximal mögliche
Segmentgröße ist 4096. Der Delay gibt an, wie lange das Programm nach dem
Laden dieser Datei mit dem nächsten Schritt warten soll (Karte macht
Speichertest über 8 MB, und ähnliche Feinheiten).
RP-Zeile ("Run Program")
@ -1538,8 +1549,11 @@ Wie dem auch sei, die Infobits haben folgende Bedeutung:
00000008 User-User Info
00000010 Cause
00000020 Status des gerufenen Teilnehmers
00000040...
80000000 reserviert
00000040 Rufnummernübergabe (Anlagenanschluß)
00000080...
20000000 reserviert
40000000 SPVs
80000000 Festverbindungen
Die EAZ-Bits:
0001 Null ("Global Call", wird aber nicht besonders behandelt)
@ -1570,3 +1584,18 @@ Ankommende Rufe, die zu diesen EAZs und Diensten passen, werden
durchgereicht (und die angeforderten Informationen werden gemeldet, wenn
die Vermittlung sie sendet(!)); andere Rufe werden ignoriert.
Bugs anderer Leute
==================
(1)
An manchen Nebenstellenanlagen werden ankommende Rufe teilweise mit,
teilweise ohne der zum Rauswählen notwendigen Null ausgeliefert.
Das liegt an der Quelle der Anrufe; die Telekom signalisiert 1TR6-Anrufe
etwas anders als Euro-ISDN (ist aber beides legal), die Telefonanlage setzt
aber nur eine Version korrekt um.
Workaround: Keiner.
Bugfix: Hersteller kräftig treten.

View File

@ -977,11 +977,17 @@ sendone(struct _bintec *bp, int thechan)
freemsg(mb);
if(thechan != 0)
chan->waitflow++;
if(BOARD_TYPE(bp) != BOARD_ID_PMX) {
*bp->ctrl = bp->cflag | 0x10;
*bp->ctrl = bp->cflag;
} else
CTRL_SET(bp,1);
}
} else if(err == -EAGAIN) {
S_requeue(&chan->q_out,mb);
} else {
freemsg(mb);
/* TODO: Kill the board? */
}
return err;
}
@ -1349,8 +1355,16 @@ DoIRQ(struct _bintec *bp)
if (err < 0)
freemsg(mb);
} else {
printf("BINTEC error: msg type %04x\n",ntohs(err));
getflush(bp,len);
mblk_t *mb = allocb(len+2,BPRI_LO);
if(mb != NULL) {
*((ushort_t *)mb->b_wptr)++ = ntohs(err);
getmb(bp,mb,len);
log_printmsg(NULL,"BINTEC error: msgtype",mb,KERN_WARNING);
freemsg(mb);
} else {
printf("BINTEC error: msg type %04x\n",ntohs(err));
getflush(bp,len);
}
err = getend(bp);
}
}
@ -1436,7 +1450,7 @@ bintectimer(struct _bintec *bp)
#ifdef NEW_TIMEOUT
bp->timer =
#endif
timeout((void *)bintectimer,bp,(bp->info.irq == 0) ? ((bp->type == BOARD_ID_PMX) ? HZ/100+1 : HZ/20+1) : HZ/2);
timeout((void *)bintectimer,bp, (bp->info.irq == 0) ? (HZ/100+1) : (HZ/2));
}
#endif

View File

@ -405,6 +405,9 @@ long isdn3_flags(mblk_t *info, uchar_t protocol, uchar_t subprot);
#define FL_POINTMASK 0300
#define FL_ANS_IMMED 0400 /* default is to delay */
#define FL_BUG1 01000
#define FL_BUG2 02000
#define FL_BUG3 04000
/**
* Convenience macros for handling connection timeouts.
@ -423,10 +426,13 @@ long isdn3_flags(mblk_t *info, uchar_t protocol, uchar_t subprot);
#define UNTIMER(T,c,w,f) do { if((c)->timerflags & f) { untimeout(w,(c)); (c)->timerflags &=~ f; } } while(0)
#define untimer(T,c) UNTIMER(T,c,T,RUN_##T)
#define TIMER(T,c,w,v,f) do { if(!((c)->timerflags & f)) { if((c)->talk->state & IS_UP) timeout(w,(c),v); (c)->timerflags |= f; } } while(0)
#define timer(T,c) TIMER(T,c,T,VAL_##T,RUN_##T)
#define timer(T,c) TIMER(T,(c),T,VAL_##T,RUN_##T)
#define ntimer(T,c,n) TIMER(T,(c),T,(n),RUN_##T)
#define FTIMER(T,c,w,v,f) do { if(!((c)->timerflags & f)) { timeout(w,(c),v); (c)->timerflags |= f; } } while(0)
#define ftimer(T,c) FTIMER(T,c,T,VAL_##T,RUN_##T)
#define ftimer(T,c) FTIMER(T,(c),T,VAL_##T,RUN_##T)
#define fntimer(T,c) FTIMER(T,(c),T,(n),RUN_##T)
#define RTIMER(T,c,w,v,f) do { if((c)->timerflags & f) { untimeout(w,(c)); timeout(w,(c),v); } } while(0)
#define rtimer(T,c) RTIMER(T,c,T,VAL_##T,RUN_##T)
#define rtimer(T,c) RTIMER(T,(c),T,VAL_##T,RUN_##T)
#define rntimer(T,c,n) RTIMER(T,(c),T,(n),RUN_##T)
#endif /* _ISDN_3 */

View File

@ -138,6 +138,7 @@
#define ARG_CALLREF CHAR2 ('c','r') /* long call reference number */
#define ARG_PBX CHAR2 ('p','b') /* behave like a PBX */
#define ARG_EAZ CHAR2 ('e','a') /* map EAZ to local phone nr */
#define ARG_LWAIT CHAR2 ('l','w') /* how long to wait for additional digits */
#define ARG_LNUMBER CHAR2 ('l','r') /* local phone nr */
#define ARG_NUMBER CHAR2 ('n','r') /* remote phone nr */
#define ARG_OUTNUMS CHAR2 ('o','m') /* outgoing, for build */
@ -158,6 +159,7 @@
#define ARG_ERRHDR CHAR2 ('e','H') /* reported error type */
#define ARG_SPV CHAR2 ('p','v') /* semipermanent */
#define ARG_FORCETALK CHAR2 ('F','t') /* force talker */
#define ARG_INCOMPLETE CHAR2('i','C') /* Number may be incomplete */
#define ARG_SUBPROT CHAR2 ('s','p') /* long Subprotocol to use. For SAPI 0:
* "65" for calls according to 1TR6,
* "0" for Q.931. */
@ -177,7 +179,7 @@
#define ARG_POINTOPOINT CHAR2('p','p') /* point-to-point link */
#define ARG_MULTIPOINT1 CHAR2('m','p') /* multipoint link, variable ID */
#define ARG_MULTIPOINT2 CHAR2('m','f') /* multipoint link, fixed ID */
#define ARG_MULTIPOINT2 CHAR2('m','q') /* multipoint link, fixed ID */
#define ARG_MULTIPOINT3 CHAR2('m','t') /* multipoint link, fixed TEI */
#define ARG_ANSWER_IMMED CHAR2('a','i') /* grab the TEI on startup */
@ -191,6 +193,9 @@
#define ARG_DEBUG CHAR2('d','e')
#define ARG_EVENT CHAR2('e','v')
#define ARG_SUBEVENT CHAR2('e','s')
#define ARG_BUG1 CHAR2('b','1')
#define ARG_BUG2 CHAR2('b','2')
#define ARG_BUG3 CHAR2('b','3')
/* Other arguments are protocol dependent. See the appropriate include files. */

View File

@ -2390,7 +2390,6 @@ isdn2_wsrv (queue_t *q)
}
#endif
{
printf("m");
if (chan->card != NULL) {
if((err = do_chprot(chan->card,chan->channel,mp,CHP_FROMSTACK)|CHP_TOCARD) < 0) {
printf("%sChProtErr isdn_2.c %d %d\n",KERN_DEBUG,__LINE__,err);
@ -2399,14 +2398,12 @@ printf("m");
}
} else {
mblk_t *mb = allocb (sizeof (struct _isdn23_hdr), BPRI_MED);
printf("j");
if (mb == NULL) {
printf("%sNoMemHdr isdn_2.c %d\n",KERN_DEBUG,__LINE__);
putbqf (q, mp);
return;
}
printf("i");
hdr2 = ((isdn23_hdr) mb->b_wptr)++;
hdr2->key = HDR_PROTOCMD;
hdr2->seqnum = hdrseq; hdrseq += 2;
@ -2415,20 +2412,15 @@ printf("i");
hdr2->hdr_protocmd.channel = 0;
hdr2->hdr_protocmd.len = dsize (mp);
linkb (mb, mp);
printf("h");
do {
DATA_TYPE(mp) = M_DATA;
mp = mp->b_cont;
} while(mp != NULL);
printf("g");
if (isdn_chan.qptr != NULL) {
printf("f");
if(isdn2_debug & 0x2000) logh_printmsg (NULL, "Up", mb);
if(canput(isdn_chan.qptr->q_next)) {
printf("e");
putnext (isdn_chan.qptr, mb);
} else {
printf("d");
freemsg(mb);
}
} else {
@ -2436,11 +2428,8 @@ printf("d");
printf ("%sHang 4\n",KERN_DEBUG);
putctlx (RD (q), M_HANGUP);
}
printf("c");
}
printf("b");
}
printf("a");
}
break;
case CASE_DATA:

View File

@ -71,15 +71,18 @@
#define STATE_DEAD 255
#define RUN_CAPI_TCONN 01
#define RUN_CAPI_TWAITEAZ 02
#define RUN_CAPI_TWAITLOCAL 02
#define RUN_CAPI_TFOO 04
#define RUN_CAPI_TWAITFIRSTLOCAL 010
#define VAL_CAPI_TCONN ( 40 *HZ) /* timer for delaying an ALERT response */
#define VAL_CAPI_TWAITEAZ ( HZ/2) /* timer for waiting for the EAZ */
#define VAL_CAPI_TWAITLOCAL ( 5 *HZ) /* wait for additional digits */
#define VAL_CAPI_TWAITFIRSTLOCAL ( HZ/2) /* wait for the first digit */
#define VAL_CAPI_TFOO ( 10 * HZ) /* timer for waiting for teardown */
static void CAPI_TCONN (isdn3_conn conn);
static void CAPI_TWAITEAZ (isdn3_conn conn);
static void CAPI_TWAITLOCAL (isdn3_conn conn);
static void CAPI_TWAITFIRSTLOCAL (isdn3_conn conn);
static void CAPI_TFOO (isdn3_conn conn);
/* Connection states:
@ -118,6 +121,7 @@ struct capi_info {
#define INF_SPV 01
unsigned char lnr[MAXNR];
unsigned char nr[MAXNR];
unsigned short waitlocal;
};
struct trace_timer {
@ -139,8 +143,14 @@ static void checkterm (isdn3_conn conn);
static void
capi_timerup (isdn3_conn conn)
{
struct capi_info *info = conn->p_data;
rtimer (CAPI_TCONN, conn);
rtimer (CAPI_TWAITEAZ, conn);
rtimer (CAPI_TWAITFIRSTLOCAL, conn);
if(info == NULL)
rtimer (CAPI_TWAITLOCAL, conn);
else
rntimer(CAPI_TWAITLOCAL, conn, info->waitlocal);
rtimer (CAPI_TFOO, conn);
}
@ -148,6 +158,8 @@ capi_timerup (isdn3_conn conn)
static void
Xsetstate(unsigned int deb_line, isdn3_conn conn, uchar_t state)
{
struct capi_info *info = conn->p_data;
printf ("Conn CAPI:%d %05lx: State %d --> %d\n", deb_line, conn->call_ref, conn->state, state);
if(conn->state == state)
@ -156,7 +168,8 @@ printf ("Conn CAPI:%d %05lx: State %d --> %d\n", deb_line, conn->call_ref, conn-
untimer(CAPI_TCONN, conn);
switch(conn->state) {
case 6:
untimer(CAPI_TWAITEAZ, conn);
untimer(CAPI_TWAITLOCAL, conn);
untimer(CAPI_TWAITFIRSTLOCAL, conn);
break;
case 99:
untimer(CAPI_TFOO, conn);
@ -169,7 +182,12 @@ printf ("Conn CAPI:%d %05lx: State %d --> %d\n", deb_line, conn->call_ref, conn-
switch(state) {
case 6:
timer(CAPI_TWAITEAZ,conn);
if(info != NULL) {
ntimer(CAPI_TWAITLOCAL,conn,info->waitlocal);
if(info->lnr == '\0')
timer(CAPI_TWAITFIRSTLOCAL,conn);
} else
timer(CAPI_TWAITLOCAL,conn);
break;
case 99:
timer(CAPI_TFOO,conn);
@ -196,13 +214,84 @@ printf ("Conn CAPI:%d %05lx: State %d --> %d\n", deb_line, conn->call_ref, conn-
}
}
static ushort_t newmsgid(isdn3_talk talk)
static ushort_t
newmsgid(isdn3_talk talk)
{
talk->message_id = ((talk->message_id + 1) & 0x3FFF) | 0x4000;
return talk->message_id;
}
static int
putnr(uchar_t *nrto, uchar_t *nrfrom)
{
uchar_t *nrorig = nrto;
switch(*nrfrom) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
*nrto++ = 0x80; break;
case '+': /* international */
*nrto++ = 0x91; nrfrom++; break;
case '=': /* national */
*nrto++ = 0xA1; nrfrom++; break;
case '-': /* subscriber */
*nrto++ = 0xC1; nrfrom++; break;
case '.': /* abbreviated */
case '/': /* abbreviated */
*nrto++ = 0xE1; nrfrom++; break;
default:
*nrto++ = 0x80; nrfrom++;
break;
}
while(*nrfrom)
*nrto++ = *nrfrom++;
return (nrto - nrorig);
}
static int
getnr(uchar_t *nrto, uchar_t *nrfrom)
{
uchar_t *nrorig = nrfrom;
int len = *nrfrom++;
if(*nrto == '\0') {
switch(*nrfrom & 0x70) {
case 0x00: /* unknown */
if(nrfrom[0] == 0x00 && nrfrom[1] == 0x83)
*nrto++ = '='; /* at least one PBX is stupid */
else if(nrfrom[0] == 0x81)
*nrto++='.'; /* the very same PBX */
break;
case 0x10: /* international */
*nrto++='+';
break;
case 0x20: /* national */
*nrto++='=';
break;
case 0x30: /* network specific */
break;
case 0x40: /* subscriber */
*nrto++='-';
break;
case 0x60: /* abbreviated */
*nrto++='.';
break;
case 0x70: /* extension */
*nrto++='.';
break;
}
} else {
while(*nrto) nrto++; /* number becomes longer */
}
while (len-- > 0 && (*nrfrom++ & 0x80) == 0) ;
while (len-- > 0)
*nrto++ = *nrfrom++;
*nrto = '\0';
return nrfrom - nrorig;
}
static int
capi_send(isdn3_talk talk, ushort_t appl, ushort_t msgtype, mblk_t *data, ushort_t msgid)
{
@ -265,16 +354,26 @@ talk_timer(struct trace_timer *tt)
}
static void
CAPI_TWAITEAZ(isdn3_conn conn)
CAPI_TWAITLOCAL(isdn3_conn conn)
{
printf("CAPI_TWAITEAZ %05lx\n",conn->call_ref);
conn->timerflags &= ~RUN_CAPI_TWAITEAZ;
printf("CAPI_TWAITLOCAL %05lx\n",conn->call_ref);
conn->timerflags &= ~RUN_CAPI_TWAITLOCAL;
if(conn->state != 6)
return;
setstate(conn,7);
report_incoming(conn);
}
static void
CAPI_TWAITFIRSTLOCAL(isdn3_conn conn)
{
printf("CAPI_TWAITFIRSTLOCAL %05lx\n",conn->call_ref);
conn->timerflags &= ~RUN_CAPI_TWAITFIRSTLOCAL;
if(conn->state != 6)
return;
report_incoming(conn);
}
static void
CAPI_TFOO(isdn3_conn conn)
{
@ -294,6 +393,22 @@ CAPI_TCONN(isdn3_conn conn)
send_disconnect(conn,0,0);
}
static int
checknrlen(isdn3_conn conn)
{
struct capi_info *info = conn->p_data;
if(info == NULL)
return -ENXIO;
if(!(conn->talk->state & (1<<(info->subcard+ST_pbx))))
return -EINVAL;
if(conn->state != 6)
return -EINVAL;
setstate(conn,6); /* this kicks the timers */
return report_incoming(conn);
}
static int
send_setup(isdn3_conn conn)
{
@ -358,51 +473,50 @@ send_open(isdn3_talk talk)
#endif
char profile[32] = DEFPROFILE;
{ /* Find correct driver name */
int err; char skip = 0;
mblk_t *info = talk->card->info;
if(info != NULL) {
streamchar *sta = info->b_rptr;
int err; char skip = 0, subskip = 0;
mblk_t *inf = talk->card->info;
if(inf != NULL) {
streamchar *sta = inf->b_rptr;
ushort_t idx;
while(m_getid(info,&idx) == 0) {
while(m_getid(inf,&idx) == 0) {
long sap;
switch(idx) {
case ARG_PROTOCOL:
if (m_geti(info,&sap) == 0) {
skip = (sap != SAPI_CAPI);
}
if (m_geti(inf,&sap) == 0)
skip = (sap != SAPI_CAPI);
break;
case ARG_SUBPROT:
if (m_geti(info,&sap) == 0 && !skip) {
if (m_geti(inf,&sap) == 0 && !skip) {
switch(sap) {
case SAPI_CAPI_BINTEC:
skip=0;
break;
default:
/* Wrong card. TODO: Do something! */
info->b_rptr = sta;
inf->b_rptr = sta;
return -ENXIO;
}
}
break;
case ARG_SUBCARD:
if (m_geti(info,&sap) == 0 && !skip)
skip = (sap != talk->regnum+1);
if (m_geti(inf,&sap) == 0 && !skip)
subskip = (sap != talk->regnum+1);
break;
case ARG_STACK:
if(skip)
if(skip || subskip)
break;
if((err = m_getstr(info,profile,sizeof(profile)-1)) < 0)
if((err = m_getstr(inf,profile,sizeof(profile)-1)) < 0)
strcpy(profile,DEFPROFILE);
break;
case ARG_PBX:
if(skip)
if(skip || subskip)
break;
talk->state |= 1<<(talk->regnum+ST_pbx);
break;
}
}
info->b_rptr = sta;
inf->b_rptr = sta;
}
}
@ -538,14 +652,21 @@ static int
report_incoming (isdn3_conn conn)
{
int err = 0;
struct capi_info *info = conn->p_data;
mblk_t *mb;
mblk_t *mb = allocb (256, BPRI_MED);
if(info == NULL)
return -ENXIO;
mb = allocb (256, BPRI_MED);
if (mb == NULL) {
setstate (conn, 0);
return -ENOMEM;
}
m_putid (mb, IND_INCOMING);
if((conn->state == 6) && !(conn->talk->state & (1<<(info->subcard+ST_pbx))))
m_putsx(mb,ARG_INCOMPLETE);
conn_info (conn, mb);
if ((err = isdn3_at_send (conn, mb, 0)) != 0) {
@ -574,7 +695,7 @@ report_nocard (isdn3_talk talk, ushort_t info)
{
mblk_t *mb = allocb (64, BPRI_MED);
talk->state = STATE_DEAD;
talk->tstate = STATE_DEAD;
m_putid (mb, IND_NOCARD);
m_putlx (mb, talk->card->id);
@ -649,8 +770,10 @@ send_disconnect(isdn3_conn conn, char do_L3, ushort_t cause)
conn->msgid0)) < 0) {
setstate(conn,0);
freemsg(m3);
} else
} else {
setstate(conn,99);
report_terminate (conn,0,cause);
}
}
break;
case 15:
@ -709,11 +832,10 @@ send_dialout(isdn3_conn conn)
struct CAPI_connect_req *c2;
struct capi_info *info = conn->p_data;
mblk_t *m2;
int llen = strlen(info->lnr);
if(info == NULL)
return -ENXIO;
m2 = allocb(sizeof(*c2)+strlen(info->nr)+1+(llen ? llen+1 : 0)+((info->flags & INF_SPV) != 0),BPRI_MED);
m2 = allocb(sizeof(*c2)+strlen(info->nr)+strlen(info->lnr)+3,BPRI_MED);
if(m2 == NULL)
return -ENOMEM;
@ -721,7 +843,7 @@ send_dialout(isdn3_conn conn)
bzero(c2,sizeof(*c2));
c2->infomask = 0xC00000FF;
{ /* Find correct info mask */
int err; char skip = 0;
int err; char skip = 0, subskip = 0;
mblk_t *inf = conn->talk->card->info;
if(inf != NULL) {
streamchar *sta = inf->b_rptr;
@ -731,9 +853,8 @@ send_dialout(isdn3_conn conn)
long sap;
switch(idx) {
case ARG_PROTOCOL:
if (m_geti(inf,&sap) == 0) {
skip = (sap != SAPI_CAPI);
}
if (m_geti(inf,&sap) == 0)
skip = (sap != SAPI_CAPI);
break;
case ARG_SUBPROT:
if (m_geti(inf,&sap) == 0 && !skip) {
@ -750,13 +871,13 @@ send_dialout(isdn3_conn conn)
break;
case ARG_SUBCARD:
if (m_geti(inf,&sap) == 0 && !skip)
skip = (sap != info->subcard);
subskip = (sap != info->subcard+1);
break;
case ARG_LISTEN:
if(skip || subskip)
break;
{
long x;
if(skip)
break;
if((err = m_getx(inf,&x)) >= 0) {
if((err = m_getx(inf,&x)) >= 0) {
if((err = m_getx(inf,&x)) >= 0) {
@ -774,26 +895,24 @@ send_dialout(isdn3_conn conn)
c2->channel = (info->bchan ? info->bchan : CAPI_ANYBCHANNEL);
c2->DST_service = info->service >> 8;
c2->DST_addinfo = info->service;
c2->telnolen = strlen(info->nr)+1;
*m2->b_wptr++ = 0x81;
strncpy(m2->b_wptr,info->nr,c2->telnolen);
m2->b_wptr += strlen(info->nr);
m2->b_wptr += (c2->telnolen = putnr(m2->b_wptr,info->nr));
if(info->flags & INF_SPV) {
c2->telnolen++;
*m2->b_wptr++ = 'S';
}
if((llen > 0) && (conn->talk->state & (1<<(info->subcard+ST_pbx)))) {
if((*info->lnr != '\0') && (conn->talk->state & (1<<(info->subcard+ST_pbx)))) {
uchar_t *lp = m2->b_wptr++;
m2->b_wptr += (*lp = putnr(m2->b_wptr,info->lnr));
c2->SRC_eaz = 0;
if(info->lnr[0] >= '0' && info->lnr[0] <= '9') {
memcpy(m2->b_wptr+1,info->lnr,llen);
} else {
llen--;
memcpy(m2->b_wptr+1,info->lnr+1,llen);
}
*m2->b_wptr = llen;
m2->b_wptr += llen+1;
} else if(llen > 0)
c2->SRC_eaz = info->lnr[llen-1];
c2->infomask |= 0x40;
} else {
c2->infomask &=~ 0x40;
if(*info->lnr != '\0')
c2->SRC_eaz = info->lnr[strlen(info->lnr)-1];
else
c2->SRC_eaz = '0';
}
conn->call_ref = conn->talk->tappl[info->subcard]<<16;
printf(">CONNECT_REQ ");
if((err = capi_send(conn->talk,conn->talk->tappl[info->subcard],CAPI_CONNECT_REQ,m2,conn->conni[WF_CONNECT_CONF]=newmsgid(conn->talk))) < 0)
@ -931,7 +1050,7 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
int err = 0;
isdn3_conn conn = 0;
if(talk->state == STATE_DEAD)
if(talk->tstate == STATE_DEAD)
return -ENXIO;
printf("CAPI: recv %d, in state %ld: ",isUI,talk->tstate);
@ -1050,6 +1169,7 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
isdn3_setup_conn (conn, EST_DISCONNECT);
report_terminate(conn,c2->info,0);
}
setstate(conn,99);
{
int err3 = 0;
struct CAPI_disconnect_resp *c3;
@ -1064,8 +1184,6 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
if((err3 = capi_send(talk,capi->appl,CAPI_DISCONNECT_RESP,m3,capi->messid)) < 0)
freemsg(m3);
}
if(err == 0)
err = send_disconnect(conn,0,0);
if(err == 0)
err = err3;
}
@ -1391,6 +1509,52 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
}
}
}
info->waitlocal = VAL_CAPI_TWAITLOCAL/HZ;
{ /* get real wait value */
int err; char skip = 0, subskip = 0;
mblk_t *inf = talk->card->info;
if(inf != NULL) {
streamchar *sta = inf->b_rptr;
ushort_t idx;
while(m_getid(inf,&idx) == 0) {
long sap;
switch(idx) {
case ARG_PROTOCOL:
if (m_geti(inf,&sap) == 0)
skip = (sap != SAPI_CAPI);
break;
case ARG_SUBPROT:
if (m_geti(inf,&sap) == 0 && !skip) {
switch(sap) {
case SAPI_CAPI_BINTEC:
skip=0;
break;
default:
/* Wrong card. TODO: Do something! */
inf->b_rptr = sta;
return -ENXIO;
}
}
break;
case ARG_SUBCARD:
if (m_geti(inf,&sap) == 0 && !skip)
subskip = (sap != info->subcard+1);
break;
case ARG_LWAIT:
if(skip || subskip)
break;
{
long x;
if((err = m_geti(inf,&x)) >= 0)
info->waitlocal = x;
}
break;
}
}
inf->b_rptr = sta;
}
}
if(c2->DST_eaz) {
info->lnr[0] = '/';
info->lnr[1] = c2->DST_eaz;
@ -1399,21 +1563,12 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
info->lnr[0] = '\0';
info->service = (c2->DST_service << 8) | c2->DST_addinfo;
if(c2->telnolen > 1) {
int nrlen = c2->telnolen;
switch(*data->b_rptr) {
case 0x91: /* international number */
case 0xA1: /* national number */
data->b_rptr++; nrlen--;
if(data->b_rptr[nrlen-1] == 'S') /* SPV */
nrlen--;
if(nrlen >= MAXNR)
nrlen = MAXNR-1;
bcopy(data->b_rptr,info->nr,nrlen);
break;
default:
err = -EINVAL;
break;
}
int nrlen;
--data->b_rptr;
data->b_rptr += getnr(info->nr,data->b_rptr);
nrlen = strlen(info->nr);
if(nrlen > 0 && (info->nr[nrlen-1] == 'S' || info->nr[nrlen-1] == 's'))
info->nr[nrlen-1] = '\0';
}
conn->call_ref = (capi->appl << 16) | c2->plci;
@ -1421,7 +1576,15 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
conn->minorstate |= MS_INCOMING;
if(err >= 0) {
setstate(conn,6);
if(c2->DST_eaz) {
setstate(conn,7);
report_incoming(conn);
} else if(conn->talk->state & (1<<(info->subcard+ST_pbx))) {
setstate(conn,6); /* no report yet */
} else {
setstate(conn,6);
report_incoming(conn);
}
break;
}
}
@ -1500,27 +1663,11 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
break;
case AI_DAD:
printf("DAD ");
switch(*data->b_rptr) {
case 0x81:
{
int nrlen = c2->infolen;
int haslen = strlen(info->lnr);
if(haslen == 0) {
haslen = 1;
info->lnr[0] = '/';
}
data->b_rptr++; nrlen--;
if(nrlen >= MAXNR-haslen)
nrlen = MAXNR-haslen-1;
bcopy(data->b_rptr,info->lnr+haslen,nrlen);
info->lnr[nrlen+1]='\0';
setstate(conn,6);
}
break;
default:
err = -EINVAL;
break;
}
--data->b_rptr;
data->b_rptr += getnr(info->lnr,data->b_rptr);
if(conn->state == 6)
checknrlen(conn);
goto empt;
break;
case AI_UUINFO:
printf("UUINFO ");
@ -1603,44 +1750,43 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
{
int dodebug = 0;
{
mblk_t *info = talk->card->info;
if(info != NULL) {
streamchar *sta = info->b_rptr;
mblk_t *inf = talk->card->info;
if(inf != NULL) {
streamchar *sta = inf->b_rptr;
ushort_t idx;
char skip = 0;
char skip = 0, subskip = 0;
while(m_getid(info,&idx) == 0) {
while(m_getid(inf,&idx) == 0) {
long sap;
switch(idx) {
case ARG_PROTOCOL:
if (m_geti(info,&sap) == 0) {
skip = (sap != SAPI_CAPI);
}
if (m_geti(inf,&sap) == 0)
skip = (sap != SAPI_CAPI);
break;
case ARG_SUBPROT:
if (m_geti(info,&sap) == 0 && !skip) {
if (m_geti(inf,&sap) == 0 && !skip) {
switch(sap) {
case SAPI_CAPI_BINTEC:
skip=0;
break;
default:
/* Wrong card. Do something! */
info->b_rptr = sta;
inf->b_rptr = sta;
return -ENXIO;
}
}
break;
case ARG_SUBCARD:
if (m_geti(info,&sap) == 0 && !skip)
skip = (sap != talk->regnum+1);
if (m_geti(inf,&sap) == 0 && !skip)
subskip = (sap != talk->regnum+1);
break;
case ARG_DEBUG:
if(skip)
if(skip || subskip)
break;
dodebug = 1;
break;
case ARG_EAZ:
if(skip)
if(skip || subskip)
break;
if(talk->state & 1<<(talk->regnum+ST_pbx))
break;
@ -1650,9 +1796,9 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
mblk_t *mp;
int len;
if((err = m_getc(info,&eaz)) < 0)
if((err = m_getc(inf,&eaz)) < 0)
break;
if((len = m_getstrlen(info)) < 0)
if((len = m_getstrlen(inf)) < 0)
break;
mp = allocb(sizeof(*ce)+len, BPRI_MED);
if(mp == NULL)
@ -1661,7 +1807,7 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
bzero(ce,sizeof(*ce));
ce->eaz = eaz;
ce->telnolen = len;
if((err = m_getstr(info,mp->b_wptr,len)) < 0) {
if((err = m_getstr(inf,mp->b_wptr,len)) < 0) {
freemsg(mp);
break;
}
@ -1675,7 +1821,7 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
break; /* ARG_EAZ */
}
}
info->b_rptr = sta;
inf->b_rptr = sta;
}
}
if((talk->tstate == STATE_REGISTER) && dodebug) {
@ -1709,47 +1855,46 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
c2->eaz_mask = 0x03FF;
c2->service_mask = 0xE7BF;
{ /* Find correct masks */
int err; char skip = 0;
mblk_t *info = talk->card->info;
if(info != NULL) {
streamchar *sta = info->b_rptr;
int err; char skip = 0, subskip = 0;
mblk_t *inf = talk->card->info;
if(inf != NULL) {
streamchar *sta = inf->b_rptr;
ushort_t idx;
while(m_getid(info,&idx) == 0) {
while(m_getid(inf,&idx) == 0) {
long sap;
switch(idx) {
case ARG_PROTOCOL:
if (m_geti(info,&sap) == 0) {
skip = (sap != SAPI_CAPI);
}
if (m_geti(inf,&sap) == 0)
skip = (sap != SAPI_CAPI);
break;
case ARG_SUBPROT:
if (m_geti(info,&sap) == 0 && !skip) {
if (m_geti(inf,&sap) == 0 && !skip) {
switch(sap) {
case SAPI_CAPI_BINTEC:
skip=0;
break;
default:
/* Wrong card. TODO: Do something! */
info->b_rptr = sta;
inf->b_rptr = sta;
return -ENXIO;
}
}
break;
case ARG_SUBCARD:
if (m_geti(info,&sap) == 0 && !skip)
skip = (sap != talk->regnum+1);
if (m_geti(inf,&sap) == 0 && !skip)
subskip = (sap != talk->regnum+1);
break;
case ARG_LISTEN:
if(skip || subskip)
break;
{
long x;
if(skip)
break;
if((err = m_getx(info,&x)) >= 0) {
if((err = m_getx(inf,&x)) >= 0) {
c2->eaz_mask = x;
if((err = m_getx(info,&x)) >= 0) {
if((err = m_getx(inf,&x)) >= 0) {
c2->service_mask = x;
if((err = m_getx(info,&x)) >= 0) {
if((err = m_getx(inf,&x)) >= 0) {
c2->info_mask = x;
}
}
@ -1758,10 +1903,15 @@ recv (isdn3_talk talk, char isUI, mblk_t * data)
break;
}
}
info->b_rptr = sta;
inf->b_rptr = sta;
}
}
printf(">LISTEN_RESP ");
if(talk->state & 1<<(talk->regnum+ST_pbx))
c2->info_mask |= 0x40;
else
c2->info_mask &=~ 0x40;
printf(">LISTEN_REQ ");
if((err =
capi_send(talk,talk->tappl[talk->regnum],CAPI_LISTEN_REQ,mp,capi->messid)) < 0) {
freemsg(mp);
@ -2044,7 +2194,7 @@ sendcmd (isdn3_conn conn, ushort_t id, mblk_t * data)
int force = 0;
uchar_t cause = 0;
if(conn->talk->state == STATE_DEAD)
if(conn->talk->tstate == STATE_DEAD)
return -ENXIO;
printf("CAPI: sendcmd %05lx %04x: ",conn->call_ref,id);
@ -2122,14 +2272,14 @@ sendcmd (isdn3_conn conn, ushort_t id, mblk_t * data)
break;
case ARG_LNUMBER:
m_getskip (data);
if ((err = m_getstr (data, (char *) info->lnr, MAXNR)) != 0) {
if ((err = m_getstr (data, (uchar_t *) info->lnr, MAXNR)) != 0) {
printf("GetStr LNumber: ");
goto RetErr;
}
break;
case ARG_NUMBER:
m_getskip (data);
if ((err = m_getstr (data, (char *) info->nr, MAXNR)) != 0) {
if ((err = m_getstr (data, (uchar_t *) info->nr, MAXNR)) != 0) {
printf("GetStr Number: ");
goto RetErr;
}
@ -2146,12 +2296,14 @@ sendcmd (isdn3_conn conn, ushort_t id, mblk_t * data)
switch (id) {
case CMD_ANSWER:
{
if(conn->talk->tstate != STATE_RUNNING)
return -ENXIO;
if (data == NULL) {
printf("DataNull: ");
conn->lockit--;
return -EINVAL;
}
if(conn->state != 7) {
if(conn->state != 6 && conn->state != 7) {
printf("CAPI error: ANSWER in bad state!\n");
conn->lockit--;
return -EINVAL;
@ -2169,6 +2321,8 @@ sendcmd (isdn3_conn conn, ushort_t id, mblk_t * data)
break;
case CMD_DIAL:
{
if(conn->talk->tstate != STATE_RUNNING)
return -ENXIO;
conn->minorstate |= MS_OUTGOING | MS_WANTCONN;
isdn3_setup_conn (conn, EST_NO_CHANGE);
@ -2210,8 +2364,8 @@ sendcmd (isdn3_conn conn, ushort_t id, mblk_t * data)
break;
}
checkterm(conn);
conn->lockit--;
checkterm(conn);
return err;
}
@ -2219,16 +2373,6 @@ static void
report (isdn3_conn conn, mblk_t * data)
{
struct capi_info *info;
printf("CAPI: report %05lx: ",conn->call_ref);
{
mblk_t *mb = data;
if(mb == NULL) printf("NULL"); else
while(mb != NULL) {
dumpascii(mb->b_rptr,mb->b_wptr-mb->b_rptr);
mb = mb->b_cont;
}
}
printf("\n");
info = conn->p_data;
if (info == NULL)
return;
@ -2244,7 +2388,7 @@ report (isdn3_conn conn, mblk_t * data)
m_putsx (data, ARG_SERVICE);
m_putx (data, info->service);
}
if(info->subcard != (unsigned char) ~0) {
if(info->subcard != (uchar_t) ~0) {
m_putsx (data, ARG_SUBCARD);
m_puti (data,info->subcard+1);
}
@ -2274,7 +2418,8 @@ killconn (isdn3_conn conn, char force)
conn->lockit++;
if (force) {
untimer (CAPI_TCONN, conn);
untimer (CAPI_TWAITEAZ, conn);
untimer (CAPI_TWAITLOCAL, conn);
untimer (CAPI_TWAITFIRSTLOCAL, conn);
untimer (CAPI_TFOO, conn);
}
if(conn->state == 0) {
@ -2309,7 +2454,6 @@ newcard (isdn3_card card)
if(card->is_up)
chstate (talk, DL_ESTABLISH_CONF,0);
}
static ulong_t

View File

@ -2049,9 +2049,8 @@ printf("ErX k\n");
conn->lockit++;
isdn3_setup_conn (conn, EST_NO_CHANGE);
conn->lockit--;
if(conn->state == 0) {
if(conn->state == 0 && conn->id_msg == 0)
isdn3_killconn(conn,0);
}
}
} else {
if (minor == 0) {
@ -2150,9 +2149,8 @@ printf("ErX k\n");
conn->lockit++;
isdn3_setup_conn (conn, EST_NO_CHANGE);
conn->lockit--;
if(conn->state == 0) {
/* XXX */
}
if(conn->state == 0 && conn->id_msg == 0)
isdn3_killconn(conn,0);
} else {
#if 1
printf("ErrOut 2c");
@ -2363,7 +2361,7 @@ if(theID == CMD_OFF) printf(" D9 ");
if (mb != NULL) {
m_putid (mb, IND_ERR);
m_putsx (mb, ARG_ERRNO);
m_puti (mb, err);
m_puti (mb, (err>0) ? err : -err);
if(conn_id == 0 && conn != NULL)
conn_id = conn->conn_id;
if(conn_id != 0) {
@ -2634,6 +2632,15 @@ isdn3_flags(mblk_t *info, uchar_t protocol, uchar_t subprot)
case ARG_L2CLOSE:
flags &=~ FL_L2KEEP;
break;
case ARG_BUG1:
flags |= FL_BUG1;
break;
case ARG_BUG2:
flags |= FL_BUG2;
break;
case ARG_BUG3:
flags |= FL_BUG3;
break;
default:
break;
}

View File

@ -40,9 +40,6 @@ phone_sendback (isdn3_conn conn, uchar_t msgtype, mblk_t * data)
if (data != NULL)
linkb (mb, data);
*mb->b_wptr++ = conn->subprotocol;
*mb->b_wptr++ = creflen;
if (conn->subprotocol == SAPI_PHONE_DSS1) {
if(conn->card == NULL || conn->card->bchans <= 2) {
if (creflen < 1)
@ -53,6 +50,9 @@ phone_sendback (isdn3_conn conn, uchar_t msgtype, mblk_t * data)
}
}
*mb->b_wptr++ = conn->subprotocol;
*mb->b_wptr++ = creflen;
if (creflen > 0) {
int clen = creflen;

View File

@ -675,10 +675,15 @@ get_ET_nr (isdn3_conn conn, uchar_t * data, int len, uchar_t *nrpos, uchar_t wha
return 0;
switch(*qd_data & 0x70) {
case 0x00: /* unknown */
if(qd_data[0] == 0x00 && qd_data[1] == 0x83)
*nrpos++ = '='; /* at least one PBX is stupid */
else if(qd_data[0] == 0x81)
*nrpos++='.'; /* the very same PBX */
{
long flags = isdn3_flags(conn->card->info,-1,-1);
if(flags & FL_BUG1) {
if(qd_data[0] == 0x00 && qd_data[1] == 0x83)
*nrpos++ = '='; /* at least one PBX is stupid */
else if(qd_data[0] == 0x81)
*nrpos++='.'; /* the very same PBX */
}
}
break;
case 0x10: /* international */
*nrpos++='+';

View File

@ -326,13 +326,15 @@ read_file (FILE * ffile, char *errf)
if (skipsp (&li)) break;
if ((c->num = atoi (li)) == 0 && li[0] != '0')
break;
if (skipsp (&li)) break;
if ((c->num2 = atoi (li)) == 0 && li[0] != '0')
break;
if (skipsp (&li)) break; c->arg = li;
if(!skipsp (&li)) break;
chkone(c);
do_subclass(c);
c->card = str_enter(c->card);
c->arg = str_enter(c->arg);
c->num2 = ++seqnum;
app (&cf_LF, c);
continue;
case CHAR2 ('C', 'M'):

View File

@ -248,7 +248,8 @@ Xsetconnstate(const char *deb_file, unsigned int deb_line,conninfo conn, CState
}
if(state >= c_going_up) {
conn->got_id = 0;
conn->got_hd = 0;
if(state > c_going_up)
conn->got_hd = 0;
}
if((state == c_off) && !conn->retime && (conn->flags & F_PERMANENT)) {
conn->retime = 1;
@ -421,7 +422,7 @@ try_reconn(struct conninfo *conn)
/* anything else is added by startconn */
if((xconn = startconn(cg,0,0, &ret)) == conn) {
if((xconn = startconn(cg,0,0, &ret, NULL)) == conn) {
dropgrab(cg);
freeb(md);
return;

View File

@ -83,7 +83,7 @@ checkdev(int dev)
else
sbuf[len]='\0';
pid = atoi(sbuf);
if(pid <= 0 || (kill(pid,0) == -1 && errno == -ESRCH)) {
if(pid <= 0 || (kill(pid,0) == -1 && errno == ESRCH)) {
if(0)syslog(LOG_WARNING,"Checking %s: unkillable, pid %d, deleted, %m",permtt1, pid);
unlink(permtt1);
}
@ -104,7 +104,7 @@ checkdev(int dev)
else
sbuf[len]='\0';
pid = atoi(sbuf);
if(pid <= 0 || (kill(pid,0) == -1 && errno == -ESRCH)) {
if(pid <= 0 || (kill(pid,0) == -1 && errno == ESRCH)) {
if(0)syslog(LOG_WARNING,"Checking %s: unkillable, pid %d, deleted, %m",permtt2, pid);
unlink(permtt2);
}

View File

@ -50,6 +50,7 @@ long hdrval;
char no_error;
struct loader *loader;
long errnum;
char incomplete;
/* Take the incoming arguments and put them into their variables. */
@ -60,6 +61,9 @@ parse_arg(void)
case ARG_CAUSE:
(void)m_getid(&xx,&cause);
break;
case ARG_INCOMPLETE:
incomplete = 1;
break;
case ARG_CHARGE:
(void)m_geti(&xx,&charge);
break;
@ -292,6 +296,7 @@ init_vars (void)
lnr[0] = '\0';
uid = -1;
connref = 0;
incomplete = 0;
dialin = -1;
charge = 0;
cause = 0;
@ -534,7 +539,7 @@ do_cardproto(void)
return 2;
}
if (pushcardprot (cg, minor) == 0) {
if (pushcardprot (cg, minor, connref) == 0) {
dropgrab(cg);
/* Success */
return 0;
@ -611,7 +616,7 @@ do_proto(void)
m_putid (&xx, CMD_CLOSE);
m_putsx (&xx, ARG_MINOR);
m_puti (&xx, minor);
if(conn->minor == minor) {
if(conn != NULL && conn->minor == minor) {
conn->minor = 0;
if(conn->pid == 0)
dropconn(conn);
@ -624,7 +629,7 @@ do_proto(void)
(void) strwrite (xs_mon, ans, xlen, 1);
return 2;
}
if (pushprot (cg, minor, ind == IND_PROTO_AGAIN) == 0) {
if (pushprot (cg, minor, conn ? conn->connref : 0, ind == IND_PROTO_AGAIN) == 0) {
/* Success */
dropgrab(cg);
return 0;
@ -659,12 +664,14 @@ do_incoming(void)
conngrab cg = newgrab(NULL);
if(cg == NULL) {
resp = "OutOfMemFoo";
incomplete = 0;
goto inc_err;
}
cg->flags = F_INCOMING|F_DIALUP|F_PERMANENT|F_NRCOMPLETE|F_LNRCOMPLETE;
cinf = allocb(len,BPRI_LO);
if(cinf == NULL) {
resp = "OutOfMemFoo";
incomplete = 0;
goto inc_err;
}
@ -673,8 +680,12 @@ do_incoming(void)
cinf->b_wptr += len;
cg->par_in = cinf;
cg->card = str_enter(crd);
if ((resp = findit (&cg,0)) != NULL)
if ((resp = findit (&cg,0)) != NULL) {
if(incomplete && !strncmp(resp+1,"LNrIncomp",8))
resp = "waiting for number";
goto inc_err;
}
incomplete = 0;
if (quitnow) {
resp = "SHUTTING DOWN";
goto inc_err;
@ -709,7 +720,7 @@ do_incoming(void)
resp = "0BUSY other";
goto inc_err;
}
if(((conn = startconn(cg,fminor,connref,&resp)) != NULL) && (resp != NULL)) {
if(((conn = startconn(cg,fminor,connref,&resp, NULL)) != NULL) && (resp != NULL)) {
/* An existing connection feels responsible for this. */
mblk_t *mz;
if(conn->state == c_forceoff) {
@ -803,7 +814,7 @@ do_incoming(void)
#if 1
/* cg->flags &=~ F_INCOMING; */
/* cg->flags |= F_OUTGOING; */
if(startconn(cg,fminor,connref,NULL) != conn)
if(startconn(cg,fminor,connref,NULL, NULL) != conn)
resp = "ClashRestart Failed";
#endif
conn = malloc(sizeof(*conn));
@ -852,60 +863,61 @@ do_incoming(void)
cont:
if (resp != NULL) {
inc_err:
xx.b_wptr = xx.b_rptr = ans;
xx.b_datap = &db;
db.db_base = ans;
db.db_lim = ans + sizeof (ans);
if(!incomplete) {
xx.b_wptr = xx.b_rptr = ans;
xx.b_datap = &db;
db.db_base = ans;
db.db_lim = ans + sizeof (ans);
if(1)printf("Dis3 ");
m_putid (&xx, CMD_OFF);
if(connref != 0) {
m_putsx (&xx, ARG_CONNREF);
m_puti (&xx, connref);
}
/* BUSY-if-no-channel is very ugly but unavoidable when
sharing the bus with brain-damaged devices (there are
many out there) which don't answer at all when they're busy.
Grr. The PBX should catch this case. */
/* We send the BUSY fast if _we_re busy, else we have to send it slow
because somebody else might in fact answer... */
m_putsx (&xx, ARG_CAUSE);
if((bchan < 0) || !strncmp(resp+1,"BUSY",4)) {
m_putsx2 (&xx, ID_N1_UserBusy);
if(!strcmp(resp+1,"BUSY") || (cg->flags & F_FASTDROP))
m_putsx(&xx,ARG_FASTDROP);
if(conn != NULL && (conn->flags & F_BACKCALL)) {
if(conn->want_reconn == 0)
conn->want_reconn = MAX_RECONN - (MAX_RECONN >> 1);
setconnstate(conn,conn->state);
if(1)printf("Dis3 ");
m_putid (&xx, CMD_OFF);
if(connref != 0) {
m_putsx (&xx, ARG_CONNREF);
m_puti (&xx, connref);
}
} else {
if(cg->flags & F_NOREJECT)
m_putsx2 (&xx, ID_N1_NoChans);
else
m_putsx2 (&xx, ID_N1_CallRejected);
if(cg->flags & F_FASTDROP)
m_putsx(&xx,ARG_FASTDROP);
}
if(crd[0] != '\0') {
m_putsx(&xx,ARG_CARD);
m_putsz(&xx,crd);
}
if(callref != 0) {
m_putsx (&xx, ARG_CALLREF);
m_puti (&xx, callref);
}
if(cg != NULL) {
syslog (LOG_WARNING, "Got '%s' for %s/%s/%s/%s,%s", resp, cg->site, cg->protocol, cg->card, cg->cclass, nr);
} else
syslog (LOG_WARNING, "Got '%s' for ???,%s", resp, nr);
xlen = xx.b_wptr - xx.b_rptr;
DUMPW (ans, xlen);
(void) strwrite (xs_mon, ans, xlen, 1);
/* BUSY-if-no-channel is very ugly but unavoidable when
sharing the bus with brain-damaged devices (there are
many out there) which don't answer at all when they're busy.
Grr. The PBX should catch this case. */
/* We send the BUSY fast if _we_re busy, else we have to send it slow
because somebody else might in fact answer... */
m_putsx (&xx, ARG_CAUSE);
if((bchan < 0) || !strncmp(resp+1,"BUSY",4)) {
m_putsx2 (&xx, ID_N1_UserBusy);
if(!strcmp(resp+1,"BUSY") || (cg->flags & F_FASTDROP))
m_putsx(&xx,ARG_FASTDROP);
if(conn != NULL && (conn->flags & F_BACKCALL)) {
if(conn->want_reconn == 0)
conn->want_reconn = MAX_RECONN - (MAX_RECONN >> 1);
setconnstate(conn,conn->state);
}
} else {
if(cg->flags & F_NOREJECT)
m_putsx2 (&xx, ID_N1_NoChans);
else
m_putsx2 (&xx, ID_N1_CallRejected);
if(cg->flags & F_FASTDROP)
m_putsx(&xx,ARG_FASTDROP);
}
if(crd[0] != '\0') {
m_putsx(&xx,ARG_CARD);
m_putsz(&xx,crd);
}
if(callref != 0) {
m_putsx (&xx, ARG_CALLREF);
m_puti (&xx, callref);
}
if(cg != NULL) {
syslog (LOG_WARNING, "Got '%s' for %s/%s/%s/%s,%s", resp, cg->site, cg->protocol, cg->card, cg->cclass, nr);
} else
syslog (LOG_WARNING, "Got '%s' for ???,%s", resp, nr);
xlen = xx.b_wptr - xx.b_rptr;
DUMPW (ans, xlen);
(void) strwrite (xs_mon, ans, xlen, 1);
}
conn = malloc(sizeof(*conn));
if(conn != NULL) {
bzero(conn,sizeof(*conn));
@ -1094,6 +1106,9 @@ do_disc(void)
}
}
break;
case c_down:
setconnstate(conn,c_down);
break;
default:;
}
} else { /* protocol stack isn't yet down */
@ -1531,6 +1546,7 @@ do_wantconnect(void)
}
}
if(conn->state < c_going_up) {
conn->got_hd = 0;
setconnref(conn,0);
try_reconn(conn);
}
@ -1738,7 +1754,6 @@ do_atcmd(void)
case 'l': /* AT/L */
case 'L': /* List connections and state changes. */
{
char buf[30];
struct conninfo *fconn;
char *sp;
msgbuf = malloc(10240);
@ -1798,8 +1813,7 @@ do_atcmd(void)
conn->ignore = 3;
conn->minor = minor;
conn->next = isdn4_conn; isdn4_conn = conn;
sprintf(buf,"# Waiting %s...",conn->cardname);
resp = str_enter(buf);
sp += sprintf(sp,"# Waiting %s...",conn->cardname);
return 1;
}
@ -1842,7 +1856,7 @@ do_atcmd(void)
} else
conn->cardname = "*";
}
sprintf(buf,"# Monitoring %s...",conn->cardname);;
sprintf(buf,"# Monitoring %s...",conn->cardname);
resp = str_enter(buf);
return 1;
}
@ -2110,11 +2124,17 @@ do_atcmd(void)
dropgrab(cg);
return 1;
}
if(!(cg->flags & F_NRCOMPLETE)) {
freeb(md);
dropgrab(cg);
resp = "RemoteNr incomplete";
return 1;
}
cg->refs++;
dropgrab(conn->cg);
conn->cg = cg;
setconnstate(conn,c_down);
if((conn = startconn(cg,fminor,0,NULL)) != NULL) {
if((conn = startconn(cg,fminor,0,NULL, NULL)) != NULL) {
freeb(md);
dropgrab(cg);
break;

View File

@ -15,7 +15,7 @@ struct loader {
int nrfile; /* number loaded to card */
};
/* cf_LF: num2: sequence number; num: block size */
/* cf_LF: num2: wait after load; num: block size */
#endif
static void
@ -121,17 +121,21 @@ void
card_load(struct loader *ld)
{
cf dl,lf;
int do_again;
int do_again, thisseq;
ld->timer = 0;
again:
do_again = 0;
thisseq = 0;
/* Now find the next applicable entry. ld->seqnum is the cf number of the
next file to load. */
for(lf = cf_LF; lf != NULL; lf = lf->next) {
thisseq++;
if(!wildmatch(ld->name,lf->card))
continue;
if(ld->seqnum != 0 && ld->seqnum != lf->num2) {
if(ld->seqnum < lf->num2 && (do_again == 0 || do_again > lf->num2))
do_again = ld->seqnum;
if(ld->seqnum != 0 && ld->seqnum != thisseq) {
if(ld->seqnum < thisseq && (do_again == 0 || do_again < thisseq))
do_again = thisseq;
continue;
}
break;
@ -216,11 +220,11 @@ card_load(struct loader *ld)
free(buf);
if(do_again) {
ld->timer = 1;
timeout(card_load,ld,ld->file ? HZ : HZ*(ld->nrfile+2));
timeout(card_load,ld,(ld->file || !lf) ? HZ : (HZ*lf->num2+HZ/3));
return;
}
} else {
ld->seqnum = lf->num2;
ld->seqnum = thisseq;
ld->nrfile++;
ld->file = fopen(lf->arg,"r");
ld->foffset = 0;
@ -229,7 +233,7 @@ card_load(struct loader *ld)
goto ex_load;
}
ld->timer = 1;
timeout(card_load,ld,HZ*2);
timeout(card_load,ld,HZ/3);
return;
}

View File

@ -403,9 +403,10 @@ void putenv2 (const char *key, const char *val);
char *match_nr (char *extnr, char *locnr, char *locpref);
int match_suffix(char *extsuf, char *extnr);
int match_incom(char *extsuf, char *extnr);
char *build_nr (char *extnr, char *locnr, char *locpref, int islocal);
char *append_nr(char *extnr, char *extext);
char *strip_nr(char *extnr);
char *strip_nr(char *extnr, int keepfirst);
/**
@ -474,8 +475,8 @@ char * findit (conngrab *foo, int nobusy);
mblk_t * getprot (char *protocol, char *site, char *cclass, char *suffix);
#endif
int pushprot (conngrab cg, int minor, char update);
int pushcardprot (conngrab cg, int minor);
int pushprot (conngrab cg, int minor, int connref, char update);
int pushcardprot (conngrab cg, int minor, int connref);
void xquit (const char *s, const char *t);
@ -483,7 +484,7 @@ EXTERN int quitnow INIT(0);
void panic(const char *x, ...);
struct conninfo * startconn(conngrab cg, int fminor, int connref, char **ret);
struct conninfo * startconn(conngrab cg, int fminor, int connref, char **ret, conngrab *retcg);
EXTERN struct conninfo *zzconn INIT(NULL);
void dropdead(void);
char * runprog (cf cfr, struct conninfo **rconn, conngrab *foo);

View File

@ -49,7 +49,7 @@ pmatch1 (cf prot, conngrab *cgm)
chkone(prot); chkone(cg);
/* Basic preprocessing */
sit = wildmatch(cg->site, prot->site); if(sit == NULL) return "7ERR Match SITE";
pro = wildmatch(cg->protocol,prot->protocol);if(pro == NULL) return "6ERR Match PROTOCOL";
pro = wildmatch(cg->protocol,prot->protocol);if(pro == NULL) return "7ERR Match PROTOCOL";
car = wildmatch(cg->card, prot->card); if(car == NULL) return "6ERR Match CARD";
cla =classmatch(cg->cclass, prot->cclass); if(cla == NULL) return "6ERR Match CLASS";
sub = maskmatch(cg->mask, prot->mask); if(sub == 0) return "6ERR Match SUBCARD";
@ -104,7 +104,7 @@ pmatch1 (cf prot, conngrab *cgm)
return "0OUT of MEMORY";
}
}
#define DG(str) { if(first) { Xbreak(); dropgrab(cgc); dropgrab(cg); return str; } goto Ex; }
#define DG(str) do { if(first) { dropgrab(cgc); dropgrab(cg); return str; } goto Ex; } while(0)
/* Remember pointers into the parameter strings. */
mbs_in = ((cgc->par_in !=NULL)? cgc->par_in->b_rptr : NULL);
@ -162,8 +162,8 @@ pmatch1 (cf prot, conngrab *cgm)
/* Put it all together. */
#define CHK(_what,_t) { \
if((nrt & ARG_OUT)&& (cgc->par_out!= NULL)) CHKO(_what,_t); \
if((nrt & ARG_IN) && (cgc->par_in != NULL)) CHKI(_what,_t); } break
if((nrt & ARG_OUT)&& (cgc->flags & F_OUTGOING) && (cgc->par_out!= NULL)) CHKO(_what,_t); \
if((nrt & ARG_IN) && (cgc->flags & F_INCOMING) && (cgc->par_in != NULL)) CHKI(_what,_t); } break
/* Same as above, but for vectorized parameters with optional bitmasks. */
/* You are not supposed to understand this code. */
@ -235,8 +235,8 @@ pmatch1 (cf prot, conngrab *cgm)
ex:; }) /**/
#define CHKV() { \
if((nrt & ARG_OUT)&& (cgc->par_out!= NULL)) CHKVO(); \
if((nrt & ARG_IN) && (cgc->par_in != NULL)) CHKVI(); } break
if((nrt & ARG_OUT)&& (cgc->flags & F_OUTGOING) && (cgc->par_out!= NULL)) CHKVO(); \
if((nrt & ARG_IN) && (cgc->flags & F_INCOMING) && (cgc->par_in != NULL)) CHKVI(); } break
/* Simple one-shot labels that can't be undone (and don't need to be). */
#define CHKX() \
@ -284,20 +284,28 @@ pmatch1 (cf prot, conngrab *cgm)
if (m_getstr (cand, yy, MAXNR) != 0)
break;
if ((nrt & ARG_IN) && (cgc->nrsuf != NULL)) {
if(0)printf("MatchSuffix %s and %s\n",cgc->nrsuf,yy);
if(!match_suffix(cgc->nrsuf,yy)) { if(cgc->flags & F_OUTGOING) { printf(" SuffixBadness "); Xbreak(); } else DG("2WrongNrSuffix 2") }
} else if((nrt & ARG_OUT) && (cgc->nrsuf == NULL))
cgc->nrsuf = str_enter(yy);
if((cgc->nr != NULL) && (nrt & ARG_OUT) && !(cgc->flags & F_NRCOMPLETE)) {
char *foo = append_nr(cgc->nr,yy);
if(0)printf("Append1 %s,%s -> %s\n",cgc->nr,yy,foo);
cgc->nr = foo;
if(cgc->nr != NULL) {
if(0)printf("Strip1 %s -> %s\n",cg->nr,strip_nr(cg->nr));
if(strip_nr(cgc->nr) != NULL)
cgc->flags |= F_NRCOMPLETE;
} else { if(cgc->flags & F_OUTGOING) { printf(" SuffixBadness2 "); Xbreak(); } else DG("3WrongNrSuffix 1") }
if ((nrt & ARG_IN) && (cgc->flags & F_INCOMING)) {
if (cgc->nrsuf != NULL) {
if(1)printf("MatchSuffix %s and %s\n",cgc->nrsuf,yy);
if(match_suffix(cgc->nrsuf,yy) <= 0) DG("2WrongNrSuffix 2");
} else
cgc->nrsuf = str_enter(yy);
}
if((nrt & ARG_OUT) &&(cgc->flags & F_OUTGOING)) {
if (cgc->nrsuf == NULL)
cgc->nrsuf = str_enter(yy);
else if(match_suffix(cgc->nrsuf,yy) <= 0)
DG("4NrOutMatch");
if((cgc->nr != NULL) && !(cgc->flags & F_NRCOMPLETE)) {
char *foo = append_nr(cgc->nr,yy);
if(1)printf("Append1 %s,%s -> %s\n",cgc->nr,yy,foo);
cgc->nr = foo;
if(cgc->nr != NULL) {
if(0)printf("Strip1 %s -> %s\n",cg->nr,strip_nr(cg->nr,0));
if(strip_nr(cgc->nr,0) != NULL)
cgc->flags |= F_NRCOMPLETE;
} else DG("3WrongNrSuffix 1");
}
}
}
break;
@ -306,23 +314,39 @@ pmatch1 (cf prot, conngrab *cgm)
case ARG_LNUMBER:
{
char yy[MAXNR + 2];
int suf;
if (m_getstr (cand, yy, MAXNR) != 0)
break;
if ((nrt & ARG_IN) && (cgc->lnrsuf != NULL)) {
if(0)printf("MatchLSuffix %s and %s\n",cgc->lnrsuf,yy);
if(!match_suffix(cgc->lnrsuf,yy)) { if(cgc->flags & F_OUTGOING) { printf(" SuffixBadness3 "); Xbreak(); } else DG("3WrongLNrSuffix 2") }
} else if((nrt & ARG_OUT) && (cgc->lnrsuf == NULL))
cgc->lnrsuf = str_enter(yy);
if((cgc->lnr != NULL) && (nrt & ARG_OUT) && !(cgc->flags & F_LNRCOMPLETE)) {
char *foo = append_nr(cgc->lnr,yy);
if(0)printf("Append2 %s,%s -> %s\n",cgc->lnr,yy,foo);
cgc->lnr = foo;
if(cgc->lnr != NULL) {
if(0)printf("Strip2 %s -> %s\n",cg->lnr,strip_nr(cg->lnr));
if(strip_nr(cgc->lnr) != NULL)
cgc->flags |= F_LNRCOMPLETE;
} else { if(cgc->flags & F_OUTGOING) { printf(" SuffixBadness4 "); Xbreak(); } else DG("3WrongLNrSuffix 1") }
if ((nrt & ARG_IN) && (cgc->flags & F_INCOMING)) {
if(cgc->lnrsuf != NULL) {
if(1)printf("MatchLSuffix %s and %s\n",cgc->lnrsuf,yy);
if((suf = match_suffix(cgc->lnrsuf,yy)) <= 0)
DG(suf ? "3LNrIncompSuffix 2" : "3WrongLNrSuffix 2");
} else
DG("4LNrIncompSuffix 3");
}
if((nrt & ARG_OUT) && (cgc->flags & F_OUTGOING)) {
if(cgc->lnrsuf == NULL)
cgc->lnrsuf = str_enter(yy);
else if(match_suffix(cgc->lnrsuf,yy) <= 0)
DG("4LNrOutMatch");
if((cgc->lnr != NULL) && !(cgc->flags & F_LNRCOMPLETE)) {
char *foo = append_nr(cgc->lnr,yy);
if(1)printf("Append2 %s,%s -> %s\n",cgc->lnr,yy,foo);
cgc->lnr = foo;
if(cgc->lnr != NULL) {
if(0)printf("Strip2 %s -> %s\n",cg->lnr,strip_nr(cg->lnr,1));
if(strip_nr(cgc->lnr,1) != NULL)
cgc->flags |= F_LNRCOMPLETE;
} else {
if((cgc->lnrsuf != 0) && (match_suffix(cgc->lnrsuf,yy) < 0))
DG("3LNrIncompSuffix 4");
else
DG("3WrongLNrSuffix 4");
}
}
}
}
break;
@ -411,7 +435,7 @@ findsite (conngrab *foo, int ignbusy)
cf dp = NULL;
cf dl = NULL;
cf d = NULL;
char *errstr = "8ERR FIND";
char *errstr = "8No matching ISDN card / DL entry";
char *errstrx;
int numwrap = 1;
conngrab cg = *foo;
@ -443,12 +467,12 @@ if(0)printf("%s.%s.!.",cg->site,cg->card); /* I hate debugging. */
break;
}
if (dp == NULL) {
errstr = "9CARD UNKNOWN";
errstr = "9No matching DP entry";
continue;
}
matcrd = crd;
matsub = sub;
} /* if everybody had DSS1, we could skip the prefix nonsense... */
}
/* Now find a site to call out to. */
/* The numwrap stuff makes sure that we restart where we left off last
@ -487,10 +511,8 @@ if(0)printf("%s.%s.!.",cg->site,cg->card); /* I hate debugging. */
if((matsit = wildmatch(cg->site,d->site)) == NULL) continue;
if((matpro = wildmatch(cg->protocol,d->protocol)) == NULL) continue;
if((matcar = wildmatch(matcrd,d->card)) == NULL) continue;
if((matcla = classmatch(cg->cclass,d->cclass)) == NULL) continue;
if((matcla = classmatch(matcla,matclass)) == NULL) continue;
if((matcla = classmatch(matclass,d->cclass)) == NULL) continue;
if((matsub = maskmatch(cg->mask,d->mask)) == 0) continue;
if((matsub = maskmatch(matsub,matsub)) == 0) continue;
if(!matchflag(cg->flags,d->type)) continue;
/* Preliminary match OK, remember the data so far. */
@ -501,7 +523,6 @@ if(0)printf("%s.%s.!.",cg->site,cg->card); /* I hate debugging. */
cg->site = matsit; cg->cclass = matcla;
cg->card = matcar; cg->protocol = matpro;
cg->mask = matsub;
if(0)printf("%s...",matsit);
if(!(cg->flags & F_LEASED)) {
/* Now figure out the numbers... */
@ -536,8 +557,8 @@ if(0)printf("%s.%s.!.",cg->site,cg->card); /* I hate debugging. */
}
continue;
}
} else if(0) { /* Hmmm... */
cg->lnr = build_nr(dl->arg,dl->arg,((cg->flags&F_INCOMING) && (dp->args != NULL)) ? dp->args : dp->arg, 0);
} else if(!(cg->flags & F_INCOMING)) { /* Hmmm... */
cg->lnr = build_nr(dl->arg,dl->arg,((cg->flags&F_INCOMING) && (dp->args != NULL)) ? dp->args : dp->arg, 2);
if(cg->lnr == NULL) {
if(*errstr > '4') {
dropgrab(errcg); errcg = cg; cg->refs++;
@ -550,10 +571,33 @@ if(0)printf("%s.%s.!.",cg->site,cg->card); /* I hate debugging. */
/* Do we have a matching P line? */
if ((errstrx = pmatch (&cg)) == NULL) {
/* We have what we need. Now figure out if we can use it. */
/* We should have what we need. Now figure out if we can use it... */
cf cl = NULL;
int nrbchan = 0;
if(cg->nr != NULL && (cg->flags & (F_INCOMING|F_OUTGOING)) && !(cg->flags & F_NRCOMPLETE)) {
if(strip_nr(cg->nr,0) != NULL)
cg->flags |= F_NRCOMPLETE;
else {
if(*errstr > '3') {
errstr = "3RemoteNr incomplete";
errcg = cg; cg->refs++;
}
continue;
}
}
if(cg->lnr != NULL && (cg->flags & (F_INCOMING|F_OUTGOING)) && !(cg->flags & F_LNRCOMPLETE)) {
if(strip_nr(cg->lnr,1) != NULL)
cg->flags |= F_LNRCOMPLETE;
else {
if(*errstr > '3') {
errstr = "3LocalNr incomplete";
errcg = cg; cg->refs++;
}
continue;
}
}
/* Check if we know how many B channels the card has */
{
struct isdncard *ca;
@ -660,8 +704,7 @@ findit (conngrab *foo, int ignbusy)
char *errstr = "9NO CARD";
char *errstrx;
struct isdncard *c;
char *card;
conngrab cg = newgrab(*foo);
conngrab cg = newgrab(*foo), cgc = NULL;
conngrab errcg = NULL;
int cardlim;
@ -673,12 +716,10 @@ findit (conngrab *foo, int ignbusy)
return "0Not Now";
}
p = cg->par_in;
card = cg->card;
if(p != NULL) {
streamchar *olds = p->b_rptr;
char st[MAXNR + 2];
char *card;
long x;
while (m_getsx (p, &id) == 0) {
@ -697,7 +738,7 @@ findit (conngrab *foo, int ignbusy)
break;
case ARG_CARD:
m_getstr (p, st, 4);
if((card = wildmatch(st,cg->card)) == NULL) {
if((cg->card = wildmatch(str_enter(st),cg->card)) == NULL) {
dropgrab(cg);
return "0CARD MISMATCH";
}
@ -721,39 +762,43 @@ findit (conngrab *foo, int ignbusy)
c = isdn4_card;
cardidx %= cardlim;
}
if(!wildmatch(card,c->name)) {
if(!wildmatch(cg->card,c->name)) {
cardlim += c->nrdchan;
continue;
}
cg->card = c->name;
cg->mask = 1;
redo:
dropgrab(cgc);
cgc = newgrab(cg);
if(cgc == NULL) return "0NoMemFind";
cardlim++;
if(cg->flags & F_INCOMING) /* never skip */
cgc->card = c->name;
if(cgc->flags & F_INCOMING) /* never skip */
cardidx = 1;
if(cardlim >= cardidx) {
if ((errstrx = findsite (&cg,ignbusy)) == NULL) { /* Found it */
if ((errstrx = findsite (&cgc,ignbusy)) == NULL) { /* Found it */
cf crd;
cardidx++;
cg->flags |= F_OUTCOMPLETE;
cgc->flags |= F_OUTCOMPLETE;
if(c->cap & CHM_INTELLIGENT) {
dropgrab(*foo);
*foo = cg;
dropgrab(*foo); dropgrab(cg);
*foo = cgc;
return NULL;
}
for (crd = cf_CM; crd != NULL; crd = crd->next) {
if (!wildmatch (c->name, crd->card))
continue;
dropgrab(*foo);
*foo = cg;
dropgrab(*foo); dropgrab(cg);
*foo = cgc;
return NULL;
}
errstrx = "0CM line missing";
}
if(*errstrx < *errstr) {
errstr = errstrx;
dropgrab(errcg); errcg = cg;
dropgrab(errcg); errcg = cgc;
errcg->refs++;
}
}
@ -771,7 +816,7 @@ findit (conngrab *foo, int ignbusy)
dropgrab(*foo);
*foo = errcg;
}
dropgrab(cg);
dropgrab(cg); dropgrab(cgc);
return errstr;
}

View File

@ -8,7 +8,6 @@
#include "master.h"
/**
** Number String Stuff
**/
@ -74,11 +73,11 @@ char *match_nr (char *extnr, char *locnr, char *locpref)
if(*extpos == '\0')
return "";
if(!isdigit(*extpos)) {
if(strcmp(extpos,locpos+1) && !wildmat(extpos,locpos+1))
if(strcmp(extpos,locpos+1) && wildmat(extpos,locpos+1) <= 0)
return NULL;
}
} else {
if(locpos[1] != '\0' && !wildmat(extpos,locpos+1))
if(locpos[1] != '\0' && wildmat(extpos,locpos+1) <= 0)
return NULL;
}
*destpos++=*locpos;
@ -117,7 +116,7 @@ int match_suffix(char *extsuf, char *extnr)
if(*extsuf=='\0')
return 1;
extsuf++; extnr++;
return (wildmatch(extsuf,extnr) != NULL);
return (wildmat(extsuf,extnr));
}
char *build_nr (char *extnr, char *locnr, char *locpref, int islocal)
@ -155,17 +154,20 @@ char *build_nr (char *extnr, char *locnr, char *locpref, int islocal)
}
if(lastprefpos==NULL)
return NULL;
if(*prefpos == '\0' && islocal) {
if(*prefpos == '\0' && (islocal & 1)) {
char *xextpos = strchr(extnr,'/');
char *xlocpos = strchr(locnr,'/');
if(xextpos != NULL && xlocpos != NULL &&
(!strcmp(xextpos,xlocpos) || wildmatch(xextpos+1,xlocpos+1)))
(!strcmp(xextpos,xlocpos) || wildmatch(xextpos+1,xlocpos+1) > 0))
lastprefpos="/";
}
locpos=strchr(locnr,*lastprefpos);
extpos=strchr(extnr,*lastprefpos);
lastprefpos++;
if(islocal & 2)
*destpos++ = *lastprefpos++;
else
lastprefpos++;
while(*lastprefpos != '\0' && isdigit(*lastprefpos)) {
*destpos++ = *lastprefpos;
lastprefpos++;
@ -197,7 +199,7 @@ char *append_nr(char *extnr, char *extext)
return NULL;
if((extpos = strchr(extnr,*extext)) == NULL)
return NULL;
if(extpos[1] != '\0' && !wildmatch(extpos,extext))
if(extpos[1] != '\0' && wildmatch(extpos,extext) <= 0)
return NULL;
while(extnr != extpos)
*destpos++ = *extnr++;
@ -208,7 +210,7 @@ char *append_nr(char *extnr, char *extext)
return str_enter(destnr);
}
char *strip_nr(char *extnr)
char *strip_nr(char *extnr, int keepfirst)
/* entfernt die Spezialzeichen aus einer vollständigen Nummer,
zwecks Dialout; NULL wenn die Nummer unvollständig ist */
/* 123.45 -> 12345 */
@ -219,7 +221,8 @@ char *strip_nr(char *extnr)
char *destpos = destnr;
int lastspc=1;
if(keepfirst && (*extnr != '\0'))
*destpos++ = *extnr++;
while(*extnr != '\0') {
if(isdigit(*extnr)) {
lastspc=0;

View File

@ -52,9 +52,9 @@ char *wildmatch(char *a, char *b)
return b;
else if(b == NULL)
return a;
else if(wildmat(a,b))
else if(wildmat(a,b) > 0)
return a;
else if(wildmat(b,a))
else if(wildmat(b,a) > 0)
return b;
else
return NULL;

View File

@ -72,7 +72,7 @@ deadkid (void)
/* Push protocols onto stream */
int
pushprot (conngrab cg, int minor, char update)
pushprot (conngrab cg, int minor, int connref, char update)
{
cf prot;
char *mods = NULL;
@ -108,6 +108,14 @@ pushprot (conngrab cg, int minor, char update)
m_putid (mj, PROTO_UPDATEMODLIST);
else
m_putid (mj, PROTO_MODLIST);
if(cg != NULL && cg->card != NULL && strcmp(cg->card,"*") != 0) {
m_putsx(mj,ARG_CARD);
m_putsz(mj,cg->card);
}
if(connref) {
m_putsx (mj, ARG_CONNREF);
m_puti(mj,connref);
}
m_putsx (mj, ARG_MODE); /* set card mode */
m_putsz (mj, prot->arg);
m_putdelim (mj);
@ -236,7 +244,7 @@ pushprot (conngrab cg, int minor, char update)
/* Set ISDN card mode */
int
pushcardprot (conngrab cg, int minor)
pushcardprot (conngrab cg, int minor, int connref)
{
cf prot;
cf cmod = NULL;
@ -276,7 +284,7 @@ pushcardprot (conngrab cg, int minor)
return -ENOENT;
if (minor != 0) {
mblk_t *mj = allocb (32, BPRI_LO);
mblk_t *mj = allocb (64, BPRI_LO);
int len;
if (mj == NULL)
@ -284,6 +292,14 @@ pushcardprot (conngrab cg, int minor)
m_putid (mj, CMD_CARDSETUP);
m_putsx (mj, ARG_MINOR);
m_puti (mj, minor);
if(cg != NULL && cg->card != NULL && strcmp(cg->card,"*") != 0) {
m_putsx(mj,ARG_CARD);
m_putsz(mj,cg->card);
}
if(connref != 0) {
m_putsx (mj, ARG_CONNREF);
m_puti (mj, connref);
}
m_putdelim (mj);
m_putc (mj, PROTO_MODE);
m_puti (mj, num);
@ -299,7 +315,7 @@ pushcardprot (conngrab cg, int minor)
/* Startup a connection... */
struct conninfo *
startconn(conngrab cg, int fminor, int connref, char **ret)
startconn(conngrab cg, int fminor, int connref, char **ret, conngrab *retcg)
{
struct iovec io[3];
int iovlen = 0;
@ -308,6 +324,7 @@ startconn(conngrab cg, int fminor, int connref, char **ret)
struct datab db;
struct conninfo *conn;
char *str;
conngrab rcg = NULL;
yy.b_rptr = data;
yy.b_wptr = data;
@ -317,6 +334,8 @@ startconn(conngrab cg, int fminor, int connref, char **ret)
if(ret == NULL)
ret = &str;
if(retcg == NULL)
retcg = &rcg;
if(cg->mask == 0) {
*ret = "Internal error: bad mask";
return NULL;
@ -408,7 +427,8 @@ startconn(conngrab cg, int fminor, int connref, char **ret)
printf("Start: %s:%s #%s...",cg->site,cg->protocol,cg->nr);
if(((*ret) = findit (&cg,0)) != NULL) {
dropgrab(cg);
*retcg = cg;
dropgrab(rcg);
chkall();
return NULL;
}
@ -461,13 +481,20 @@ printf("Start: %s:%s #%s...",cg->site,cg->protocol,cg->nr);
m_puti (&yy, connref ? connref : conn->connref);
}
if (cg->lnrsuf != NULL) {
char *s = cg->lnrsuf;
m_putsx (&yy, ARG_LNUMBER);
m_putsz (&yy, s);
if (cg->lnr != NULL) {
char *s = strip_nr(cg->lnr,1);
printf("Strip3 %s -> %s\n",cg->lnr,s);
if(s == NULL && cg->lnrsuf != NULL) {
s = append_nr(cg->lnr,cg->lnrsuf);
printf("Append3 %s,%s -> %s\n",cg->lnr,cg->lnrsuf,s);
}
if(s != NULL) {
m_putsx (&yy, ARG_LNUMBER);
m_putsz (&yy, s);
}
}
if (cg->nr != NULL) {
char *s = strip_nr(cg->nr);
char *s = strip_nr(cg->nr,0);
printf("Strip3 %s -> %s\n",cg->nr,s);
if(s == NULL && cg->nrsuf != NULL) {
s = append_nr(cg->nr,cg->nrsuf);
@ -621,6 +648,7 @@ runprog (cf cfr, struct conninfo **rconn, conngrab *foo)
conn->seqnum = ++connseq;
conn->state = c_down;
conn->cause = 999999;
conn->got_hd = 1;
conn->next = isdn4_conn; isdn4_conn = conn;
}
cg->refs++;
@ -814,7 +842,7 @@ runprog (cf cfr, struct conninfo **rconn, conngrab *foo)
strncpy (ut.ut_id, sdevname (dev), sizeof (ut.ut_id));
strncpy (ut.ut_line, mdevname (dev), sizeof (ut.ut_line));
#ifndef M_UNIX
strncpy (ut.ut_host, cfr->protocol, sizeof (ut.ut_host));
strncpy (ut.ut_host, cfr->site, sizeof (ut.ut_host));
#endif
ut.ut_pid = getpid ();
ut.ut_type = LOGIN_PROCESS;
@ -1035,14 +1063,14 @@ runprog (cf cfr, struct conninfo **rconn, conngrab *foo)
else
cg->delay = 0;
}
if(startconn(conn->cg,0,0, &msg) != conn) {
if(startconn(conn->cg,0,0, &msg, NULL) != conn) {
syslog(LOG_CRIT,"Bug in runprog->startconn (%s) for %s:%s",msg ? msg : "(unknown reason)", cg->site,cg->protocol);
dropgrab(conn->cg);
conn->cg = NULL;
chkone(conn);
}
} else {
int err = pushprot (conn->cg, conn->minor, 0);
int err = pushprot (conn->cg, conn->minor, conn->connref, 0);
if(err != 0) {
printf("NoProtoEnable NotPushprot\n");
m_putid (&yy, CMD_CLOSE);
@ -1248,7 +1276,7 @@ printf("FAIL %s\n",err);
} else {
printf("exist %s:%s\n",conn->cg->site,conn->cg->protocol);
if(conn->cg != NULL && conn->minor != 0 && conn->pid != 0)
pushprot(conn->cg,conn->minor,1);
pushprot(conn->cg,conn->minor,conn->connref,1);
}
}
}

View File

@ -1,4 +1,6 @@
KERNEL=1
TOPDIR=..
SOURCES= streamlib.c smallq.c dump.c log.c logh.c proto.c x75lib.c qinfo.c count.c
include $(TOPDIR)/Make.rules

View File

@ -269,12 +269,14 @@ log_printmsg (void *xlog, const char *text, mblk_t * mp, const char *prefix)
int l = (uchar_t *) mp1->b_wptr - dp;
printf ("%s%03x ",pprefix,i);
#if 0
if(i >= 2*BLOCKSIZE && l > 3*BLOCKSIZE) { /* Skip the stuff in the middle */
l -= 2*BLOCKSIZE + (l % BLOCKSIZE);
printf("[... %d bytes (0x%x) skipped ...]\n",l,l);
dp += l; i += l;
continue;
}
#endif
for (k = 0; k < BLOCKSIZE && k < l; k++)
printf ("%c%c ", ctab[dp[k] >> 4], ctab[dp[k] & 0x0F]);
i += k;