19
19
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
21
* $Log: processor.c,v $
22
* Revision 1.127 2003/10/29 17:41:34 tobiasb
24
* - Enhancements for isdnrep:
25
* - New option -r for recomputing the connection fees with the rates
26
* from the current (and for a different or the cheapest provider).
27
* - Revised output format of summaries at end of report.
28
* - New format parameters %j, %v, and %V.
29
* - 2 new input formats for -t option.
30
* - Fix for dualmode workaround 0x100 to ensure that incoming calls
31
* will not become outgoing calls if a CALL_PROCEEDING message with
32
* an B channel confirmation is sent by a terminal prior to CONNECT.
33
* - Fixed and enhanced t: Tag handling in pp_rate.
34
* - Fixed typo in interface description of tools/rate.c
35
* - Fixed typo in tools/isdnrate.man, found by Paul Slootman.
36
* - Minor update to sample isdn.conf files:
37
* - Default isdnrep format shows numbers with 16 chars (+ & 15 digits).
38
* - New isdnrep format (-FNIO) without display of transfered bytes.
39
* - EUR as currency in Austria, may clash with outdated rate-at.dat.
40
* The number left of the currency symbol is nowadays insignificant.
41
* - Changes checked in earlier but after step to isdnlog-4.66:
42
* - New option for isdnrate: `-rvNN' requires a vbn starting with NN.
43
* - Do not compute the zone with empty strings (areacodes) as input.
44
* - New ratefile tags r: und t: which need an enhanced pp_rate.
45
* For a tag description see rate-files(5).
46
* - Some new and a few updated international cellphone destinations.
48
* NOTE: If there any questions, problems, or problems regarding isdnlog,
49
* feel free to join the isdn4linux mailinglist, see
50
* https://www.isdn4linux.de/mailman/listinfo/isdn4linux for details,
51
* or send a mail in English or German to <tobiasb@isdn4linux.de>.
53
* Revision 1.126 2003/08/26 19:46:12 tobiasb
55
* - Added support for AVM B1 (with layer 2 d-channel trace) in point-to-
56
* point mode, where only TEI 0 is used ("Anlagenanschluss" in German).
57
* Many thanks to Klaus Heske for his testing efforts.
58
* - The source number "0" in outgoing calls is now expanded to
59
* +<country><area>0. This may be useful for point-to-point setups,
60
* when <area> contains area code and local number without extension.
61
* - Basic support for different codesets in (E)DSS1 messages. Except
62
* for codeset 0, unknown information elements are now silently
63
* ignored (controlled by ignore_unknown_IE in isdnlog/isdnlog.h).
64
* - Added some information elements to isdnlog/messages.c.
65
* - Increased the length of msn (local number) in struct telnum.
66
* - Fixed seperation of country and area code for long numbers
67
* in getDest, tools/dest.c.
68
* - Changed broken (with gcc 2.95.2) generation of .depend. The old
69
* output did not consider the location of objectfiles in subdirs.
70
* Remove this file before compiling this upgraded isdnlog.
71
* - Moved DUALFIX... defines from tools/tools.h to isdnlog/isdnlog.h.
72
* - Added missing R:-Links for cellphone entries in country-de.dat.
73
* - Different entry for each city "Neustadt" in tools/zone/de/code.
74
* - Earlier changes since isdnlog-4.65:
75
* - Allow dualmode workaround 0x100 (DUALFIX_DESTNUM) to work also with
76
* CALL_PROCEEDING messages for cleaning up unanswered incoming calls.
78
* Revision 1.125 2003/08/14 12:18:57 tobiasb
79
* Allow dualmode workaround 0x100 aka DUALFIX_DESTNUM to work also with
80
* CALL_PROCEEDING messages for cleaning up unanswered incoming calls.
81
* (http://lists.suse.com/archive/suse-isdn/2003-Aug/0026.html in German)
82
* Update for `Denmark cellphone' entry in destination database.
84
* Revision 1.124 2003/07/25 22:18:03 tobiasb
86
* - New values for isdnlog option -2x / dual=x with enable certain
87
* workarounds for correct logging in dualmode in case of prior
88
* errors. See `man isdnlog' and isdnlog/processor.c for details.
89
* - New isdnlog option -U2 / ignoreCOLP=2 for displaying ignored
91
* - Improved handling of incomplete D-channel frames.
92
* - Increased length of number aliases shown immediately by isdnlog.
93
* Now 127 instead of 32 chars are possible. (Patch by Jochen Erwied.)
94
* - The zone number for an outgoing call as defined in the rate-file
95
* is written to the logfile again and used by isdnrep
96
* - Improved zone summary of isdnrep. Now the real zone numbers as
97
* defined in the rate-file are shown. The zone number is taken
98
* from the logfile as mentioned before or computed from the current
99
* rate-file. Missmatches are indicated with the chars ~,+ and *,
100
* isdnrep -v ... explains the meanings.
101
* - Fixed provider summary of isdnrep. Calls should no longer be
102
* treated wrongly as done via the default (preselected) provider.
103
* - Fixed the -pmx command line option of isdnrep, where x is the xth
105
* - `make install' restarts isdnlog after installing the data files.
106
* - A new version number generates new binaries.
107
* - `make clean' removes isdnlog/isdnlog/ilp.o when called with ILP=1.
22
109
* Revision 1.123 2002/03/11 16:18:43 paul
23
110
* DM -> EUR; and only test for IIOCNETGPN on i386 systems
1908
2019
Q931dump(TYPE_STRING, l, s, version);
1911
if ((l > 50) || (l < 0)) {
1912
sprintf(s, "Invalid length %d -- complete frame ignored!", l);
2022
/* An information element can be up to 256 octets long, that makes
2023
* 254 octets for its contents. The old limit of 50 octets turned
2024
* out to be to strict in case of the ISDN card connected to a PABX
2025
* and violated the standards ETSI ... and ITU Q.931.
2026
* |TB| 2003-08-17 */
2027
if ((l > 254) || (l < 0)) {
2028
sprintf(s, "Invalid length %d of information element %02x in codeset %d"
2029
" -- complete frame ignored!", l, element, codeset.current);
1913
2030
info(chan, PRT_SHOWNUMBERS, STATE_RING, s);
1917
pd = qmsg(TYPE_ELEMENT, version, element);
2034
/* FIXME: qmsg is not aware of codesets */
2035
pd = (codeset.current) ? NULL : qmsg(TYPE_ELEMENT, version, element);
1919
if (strncmp(pd, "UNKNOWN", 7) == 0) {
2037
if (codeset.current || strncmp(pd, "UNKNOWN", 7) == 0) {
1920
2038
register char *p1 = p, *p2;
1921
2039
register int i, c;
1922
2040
auto char s[LONG_STRING_SIZE];
2041
auto int full_l = l;
2043
if (4*l > LONG_STRING_SIZE-400) /* handle very long unknown IE */
2044
l = (LONG_STRING_SIZE-400)/4;
1926
p2 += sprintf(p2, "UNKNOWN ELEMENT %02x:", element);
2047
p2 += sprintf(p2, "UNKNOWN ELEMENT %02x in codeset %d:",
2048
element, codeset.current);
1928
2050
for (i = 0; i < l; i++)
1929
2051
p2 += sprintf(p2, " %02x", (int)strtol(p1 += 3, NIL, 16));
1931
p2 += sprintf(p2, " [");
2053
p2 += sprintf(p2, "%s [", (full_l>l)?" ...":"");
1934
2056
for (i = 0; i < l; i++) {
1935
2057
c = (int)strtol(p1 += 3, NIL, 16);
1936
2058
p2 += sprintf(p2, "%c", isgraph(c) ? c : ' ');
1939
p2 += sprintf(p2, "], length=%d -- complete frame ignored!", l);
1940
info(chan, PRT_SHOWNUMBERS, STATE_RING, s);
2062
if ( version==VERSION_EDSS1 &&
2063
(ignore_unknown_IE>>codeset.current)&1 ) {
2064
p2 += sprintf(p2, "], length=%d -- ignored", l);
2065
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s: %s\n", st+4, s);
2066
p += 3*l; /* skip the content of the unknown IE */
2067
continue; /* and next IE */
2069
else { /* do not ignore unknown IE */
2070
p2 += sprintf(p2, "], length=%d -- complete frame ignored!", l);
2071
info(chan, PRT_SHOWNUMBERS, STATE_RING, s);
2074
} /* if IE unknown */
1944
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s: ELEMENT %02x:%s (length=%d)\n", st + 4, element, pd, l);
2076
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s: ELEMENT %02x:%s "
2077
"(length=%d, codeset=%d)\n", st + 4, element, pd, l, codeset.current);
1946
2079
/* changing 0x28 to 0x2800 for special case prevents much complication */
1947
2080
/* later; 0x28 means / does different things in different countries */
3215
if (version == VERSION_1TR6) {
3216
switch ((element >> 4) & 7) {
3217
case 1 : sprintf(s, "%02x ---> Shift %d (cs=%d, cs_fest=%d)", element, element & 0xf, element & 7, element & 8);
3220
case 3 : sprintf(s, "%02x ---> Congestion level %d", element, element & 0xf);
3223
case 2 : if (element == 0xa0)
3224
sprintf(s, "%02x ---> More data", element);
3225
else if (element == 0xa1)
3226
sprintf(s, "%02x ---> Sending complete", element);
3229
default : sprintf(s, "%02x ---> Reserved %d", element, element);
3233
Q931dump(TYPE_STRING, -3, s, version);
3235
else if (version == VERSION_EDSS1) {
3236
switch ((element >> 4) & 7) {
3237
case 1 : sprintf(s, "%02x ---> Shift %d", element, element & 0xf);
3240
case 3 : sprintf(s, "%02x ---> Congestion level %d", element, element & 0xf);
3243
case 5 : sprintf(s, "%02x ---> Repeat indicator %d", element, element & 0xf);
3246
case 2 : if (element == 0x90)
3247
sprintf(s, "%02x ---> Umschaltung in eine andere Codegruppe %d\n", element, element);
3248
if (element == 0xa0)
3249
sprintf(s, "%02x ---> More data", element);
3250
else if (element == 0xa1)
3251
sprintf(s, "%02x ---> Sending complete", element);
3254
default : sprintf(s, "%02x ---> Reserved %d\n", element, element);
3258
Q931dump(TYPE_STRING, -3, s, version);
3363
} /* if (element < 128) -- variable length information elements */
3366
if (version == VERSION_EDSS1 && (element & 0x70) == 0x10) { /* shift IE */
3367
if (element & 0x08) { /* non locking shift */
3368
codeset.shift = element & 0x07;
3369
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s: non locking shift from"
3370
"codeset %d to codeset %d\n", st+4, codeset.current, codeset.shift);
3373
codeset.locked = element & 0x07;
3374
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s: locking shift from codeset"
3375
" %d to codeset %d\n", st+4, codeset.current, codeset.locked);
3380
if (version == VERSION_1TR6) {
3381
switch ((element >> 4) & 7) {
3382
case 1 : sprintf(s, "%02x ---> Shift %d (cs=%d, cs_fest=%d)", element, element & 0xf, element & 7, element & 8);
3385
case 3 : sprintf(s, "%02x ---> Congestion level %d", element, element & 0xf);
3388
case 2 : if (element == 0xa0)
3389
sprintf(s, "%02x ---> More data", element);
3390
else if (element == 0xa1)
3391
sprintf(s, "%02x ---> Sending complete", element);
3394
default : sprintf(s, "%02x ---> Reserved %d", element, element);
3398
Q931dump(TYPE_STRING, -3, s, version);
3400
else if (version == VERSION_EDSS1) {
3401
switch ((element >> 4) & 7) {
3402
case 1 : sprintf(s, "%02x ---> Shift %d", element, element & 0xf);
3405
case 3 : sprintf(s, "%02x ---> Congestion level %d", element, element & 0xf);
3408
case 5 : sprintf(s, "%02x ---> Repeat indicator %d", element, element & 0xf);
3411
case 2 : if (element == 0x90)
3412
sprintf(s, "%02x ---> Umschaltung in eine andere Codegruppe %d\n", element, element);
3413
if (element == 0xa0)
3414
sprintf(s, "%02x ---> More data", element);
3415
else if (element == 0xa1)
3416
sprintf(s, "%02x ---> Sending complete", element);
3419
default : sprintf(s, "%02x ---> Reserved %d\n", element, element);
3423
Q931dump(TYPE_STRING, -3, s, version);
3426
} /* if (element<128) ... else */
3427
} /* while (1) -- loop over all present information elements */
3264
3430
/* --------------------------------------------------------------------------
4683
4870
if (allflags & PRT_DEBUG_DIAG)
4684
4871
diag(cref, tei, sapi, dialin, net, type, version);
4875
print_msg(PRT_DEBUG_BUGS, " DEBUG> %s: AVMB1(D2): net=%d, D2_net=%d, %s\n"
4876
, st+4, net, D2_net, (net==D2_net) ? "OK" : "ERROR");
4686
4879
/* leider laesst sich kein switch nehmen, da decode
4687
4880
innerhalb von SETUP/A_ACK aufgerufen werden muss, sonst
4688
4881
aber erst nach feststellen von chan
4689
4882
Daher GOTO (urgs...) an das Ende vom if hex:.. */
4883
/* Tobias Becker, 2003-02-25:
4884
Using dualmode and a HFC card, an outgoing call from an a/b adapter
4885
(labelled `1&1', dating from 1996) produced the following messages
4886
recognized by isdnlog:
4887
(1) NET -> SETUP ACK.. with CHANNEL: BRI, B1 needed
4888
(2) USR -> SETUP with BEARER, CHANNEL: any channel, and Calling
4890
No further CHANNEL messages occur for this call. Prior to (1)
4891
there may be lost messages as isdnctrl0 states:
4892
`03:09.16 Card1 empty_fifo hfcpci paket inv. len 2 or crc 255'
4893
(1) is decoded in chan 5, sets channel=1 and triggers the move
4894
from chan 5 to chan 0.
4895
(2) is decoded in chan 5 (SETUP overrides chan 0 before) but
4896
does not set channel, so the information in call[5] is not
4898
Work-around: decode SETUP in chan 0/1 when cref match
4899
This workaround requires the value of DUALFIX_SRCNUM in dualfix,
4900
which is set with -2.. or dual=.. at command line or parameter file.
4691
4902
if (type == SETUP) { /* neuen Kanal, ev. dummy, wenn keiner da ist */
4692
4903
chan = 5; /* den nehmen wir _nur_ dafuer! */
4904
if (dualfix & DUALFIX_SRCNUM) {
4905
for (i=0; i<2; i++) /* look for already allocated chan 0 or 1 */
4906
if (cref>=0 && cref==call[i].cref && !dialin
4907
&& !call[i].dialin && call[i].tei==tei && call[i].channel==i+1) {
4909
print_msg(PRT_DEBUG_BUGS, " DEBUG> %s: Decoding SETUP in chan %d (cref=%d tei=%d)\n", st + 4, chan, cref, tei);
4913
if (chan == 5) /* do not clear other chans */
4694
4915
call[chan].dialin = dialin;
4695
4916
call[chan].tei = tei;
4696
4917
call[chan].card = card;
4774
4998
chan = call[chan].channel - 1;
4776
if (!chanused[chan]) {
5000
/* a previous unanswered incomming or outgoing call may have left
5001
* chanused[chan] != 0 so that the old if (!chanused[chan]) does
5002
* not the needed copy.
5003
* Hopefully the second line does it right:
5004
* - !call[chan].dialog && call[chan].dialin && call[chan].cause!=-1
5005
* turned out to be to restrictive,
5006
* - !call[chan].dialog turned out to be to generally.
5007
* - ... && type=SETUP_ACKNOWLEDGE is to restrictrive. In case of
5008
* SETUP with complete called party number, the exchange responds
5009
* with C_PROC instead of S_ACK and C_PROC contains the B-channel.
5010
* - ... && !dialin_cref is necessary, because C_PROC may be send
5011
* by local terminal on incoming call and dialin is 0 instead of
5012
* 1 in this case. (Wrong call direction due to depency on tei 127.)
5013
* This workaround requires the value of DUALFIX_DESTNUM in dualfix,
5014
* which is set with -2.. or dual=.. at command line or parameter file.
5017
if (!chanused[chan] || (dualfix & DUALFIX_DESTNUM &&
5018
!call[chan].dialog && !call[5].dialin && !dialin_cref)) {
4777
5019
/* nicht --channel, channel muss unveraendert bleiben! */
5020
if (chanused[chan]) { /* catch second line condition */
5021
print_msg(PRT_DEBUG_BUGS, " DEBUG> %s: %s contained channel B%d which is marked as in use -- overwriting anyway.\n", st+4, (type==SETUP_ACKNOWLEDGE)?"S_ACK":"C_PROC", call[5].channel);
4778
5024
memcpy((char *)&call[chan], (char *)&call[5], sizeof(CALL));
4779
5025
Change_Channel(5, chan);
4780
5026
addlist(chan, type, 1);
5351
/* An unanswered incoming calls can cause multiple logfile-entries,
5352
* because there is a RELEASE message for each 'ringing' terminal
5353
* and this messages are decoded independly from each other using
5354
* chan 4. With DUALFIX_MULTLOG only the first entry should be
5356
if (dualfix & DUALFIX_MULTLOG
5357
&& chan==4 && !call[4].dialog && call[4].dialin
5358
&& origchan > -1 && call[4].cref==call[origchan].cref
5359
&& call[origchan].logcount)
5360
print_msg(PRT_DEBUG_BUGS, " DEBUG> %s: No logfile-entry for cref=%d, tei=%d, origchan=%d -- unanswered incoming call already logged %d time(s).\n",
5361
st+4, call[chan].cref, call[chan].tei, origchan,
5362
call[origchan].logcount);
5365
call[origchan>-1?origchan:chan].logcount++; /* remember logentry */
5098
5369
chanused[chan] = 0;
5099
5370
addlist(chan, type, 2);
5562
5833
processinfo(p3);
5563
5834
else if (!memcmp(p3, "HEX: ", 5) ||
5564
5835
!memcmp(p3, "hex: ", 5) ||
5565
/* !memcmp(p3, "D2<: ", 5) || Layer 2 not yet evaluated */
5566
/* !memcmp(p3, "D2>: ", 5) || Layer 2 not yet evaluated */
5836
!memcmp(p3, "D2<: ", 5) || /* AVMB1 with layer 2 d-channel */
5837
!memcmp(p3, "D2>: ", 5) || /* info works in replaymode |TB|*/
5567
5838
!memcmp(p3, "D3<: ", 5) ||
5568
5839
!memcmp(p3, "D3>: ", 5))
5569
5840
processctrl(0, p3);
5570
5841
else if (!memcmp(p3 + 3, "HEX: ", 5))
5571
5842
processctrl(atoi(p3), p3 + 3);
5574
5845
#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
5575
5846
if (!memcmp(p1 + 9, "DW_ABC_LCR", 10))