~ubuntu-branches/ubuntu/jaunty/isdnutils/jaunty-proposed

« back to all changes in this revision

Viewing changes to isdnlog/isdnlog/processor.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2004-09-04 08:20:20 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040904082020-g641px056lshw203
Tags: 1:3.3.0.20040728-2
* Put libcapi20 development files into new libcapi20-dev package,
  change libcapi20 soname to libcapi20-3, conflict with existing
  versions of packages depending on libcapi20-3 (closes: #268767).
* Update debconf translation strings (closes: #268716).
* Update french debconf translation (closes: #269666).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: processor.c,v 1.123 2002/03/11 16:18:43 paul Exp $
 
1
/* $Id: processor.c,v 1.127 2003/10/29 17:41:34 tobiasb Exp $
2
2
 *
3
3
 * ISDN accounting for isdn4linux. (log-module)
4
4
 *
19
19
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
20
 *
21
21
 * $Log: processor.c,v $
 
22
 * Revision 1.127  2003/10/29 17:41:34  tobiasb
 
23
 * isdnlog-4.67:
 
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.
 
47
 *
 
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>.
 
52
 *
 
53
 * Revision 1.126  2003/08/26 19:46:12  tobiasb
 
54
 * isdnlog-4.66:
 
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.
 
77
 *
 
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.
 
83
 *
 
84
 * Revision 1.124  2003/07/25 22:18:03  tobiasb
 
85
 * isdnlog-4.65:
 
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
 
90
 *    COLP information.
 
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
 
104
 *    defined [MSN].
 
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.
 
108
 *
22
109
 * Revision 1.123  2002/03/11 16:18:43  paul
23
110
 * DM -> EUR; and only test for IIOCNETGPN on i386 systems
24
111
 *
1183
1270
 
1184
1271
static int    HiSax = 0, hexSeen = 0, uid = UNKNOWN, lfd = 0;
1185
1272
static char  *asnp, *asnm = NULL;
1186
 
static int    chanused[2] = { 0, 0 };
 
1273
static int    chanused[MAXCHAN] = { 0, 0 }; /* chan < MAXCHAN, not < 2  */
1187
1274
static int    IIOCNETGPNavailable = -1; /* -1 = unknown, 0 = no, 1 = yes */
1188
1275
 
1189
1276
#ifdef Q931
1347
1434
  *intern = ((strlen(num) < interns0) || !isdigit(*num));
1348
1435
 
1349
1436
  if (trim && !*intern) {
1350
 
    if (dir && (who == CALLING))
 
1437
    if (dir && (who == CALLING))         /* source number of incoming call */
1351
1438
      num += min(trimi, strlen(num));
1352
 
    else if (!dir && (who == CALLED))
 
1439
    else if (!dir && (who == CALLED))    /* dest. number of outgoing call */
1353
1440
      num += min(trimo, strlen(num));
1354
1441
 
1355
1442
    print_msg(PRT_DEBUG_DECODE, " TRIM> \"%s\" -> \"%s\" (trimi=%d, trimo=%d, %s, %s, %s)\n",
1462
1549
  if ((*sondernummer == UNKNOWN) && !*intern) {
1463
1550
    switch (oc3 & 0x70) { /* Calling party number Information element, Octet 3 - Table 4-11/Q.931 */
1464
1551
      case 0x00 : if (*num) {                  /* 000 Unknown */
1465
 
                    if (*num != '0') {
 
1552
                    /* Let own number 0 lead to +CC_Area_0, useful with PABX */
 
1553
                    if (*num=='0' && !*(num+1) && !partner)
 
1554
                      strcpy(result, mynum); 
 
1555
                    else if (*num != '0') {
1466
1556
                      /* in NL the MSN contains myarea w/o leading zero
1467
1557
                         so myarea get's prepended again */
1468
1558
                      if (memcmp(myarea, num, strlen(myarea)) == 0)
1480
1570
                      while (*num == '0')
1481
1571
                        num++;
1482
1572
                    } /* else */
1483
 
                  } /* if */
 
1573
                  } /* if (*num) */
1484
1574
                  break;
1485
1575
 
1486
1576
      case 0x10 : if (version != VERSION_1TR6)
1874
1964
         ((ifo[bchan].u & ISDN_USAGE_MASK) == ISDN_USAGE_MODEM)));
1875
1965
} /* expensive */
1876
1966
 
1877
 
 
 
1967
/* decode parses the information elements (IE) of a layer 3 D-channel message
 
1968
 * and stores the retrieved information in call[chan].
 
1969
 * p points to "tt ee ll .." where tt is the message type as hex number */
1878
1970
static void decode(int chan, register char *p, int type, int version, int tei)
1879
1971
{
1880
1972
  register char     *pd, *px, *py;
1886
1978
  auto     struct tm tm;
1887
1979
  auto     time_t    t;
1888
1980
  auto     double    tx, err, tack;
 
1981
  auto     CODESET   codeset;
1889
1982
 
 
1983
  codeset.current = codeset.locked = 0;  /* every message starts in codeset 0 */
 
1984
  codeset.shift = -1;
1890
1985
 
1891
1986
  while (1) {
1892
1987
 
 
1988
    /* *p should be the first digit (O) of the last already processed byte, */
 
1989
    /* like: "oo Oo nn nn" or "oo Oo" */
1893
1990
    if (!*(p - 1) || !*(p + 2))
1894
 
      break;
 
1991
      break;                             /* regular exit point of decode */
 
1992
 
 
1993
    if (codeset.shift >= 0) {            /* previous IE was non-locked shift */ 
 
1994
      codeset.current = codeset.shift;
 
1995
      codeset.shift = -1;
 
1996
    }
 
1997
    else
 
1998
      codeset.current = codeset.locked;
1895
1999
 
1896
2000
    element = strtol(p += 3, NIL, 16);
1897
2001
 
1899
2003
 
1900
2004
      l = strtol(p += 3, NIL, 16);
1901
2005
 
 
2006
      l1 = strlen(p+2); /* *(p+2) is ' ' before first digit of first contents byte */
 
2007
      if (l1 < 3*l) { /* not enouph input to for l bytes of element contents */
 
2008
        sprintf(s, "Not enough raw input from isdnctrl? for contents of element 0x%X in codeset %d: %d raw bytes (length=%d) needed but only %d raw bytes present --  ignoring this element!", element, codeset.current, 3*l, l, l1);
 
2009
        info(chan, PRT_SHOWNUMBERS, STATE_RING, s);
 
2010
        return;
 
2011
      }
 
2012
 
1902
2013
      if (Q931dmp) {
1903
2014
        auto char s[BUFSIZ];
1904
2015
 
1908
2019
        Q931dump(TYPE_STRING, l, s, version);
1909
2020
      } /* if */
1910
2021
 
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);
1914
2031
        return;
1915
2032
      } /* if */
1916
2033
 
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);
1918
2036
 
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; 
1923
2042
 
 
2043
        if (4*l > LONG_STRING_SIZE-400)   /* handle very long unknown IE */
 
2044
          l = (LONG_STRING_SIZE-400)/4;
1924
2045
 
1925
2046
        p2 = s;
1926
 
        p2 += sprintf(p2, "UNKNOWN ELEMENT %02x:", element);
 
2047
        p2 += sprintf(p2, "UNKNOWN ELEMENT %02x in codeset %d:",
 
2048
                      element, codeset.current);
1927
2049
 
1928
2050
        for (i = 0; i < l; i++)
1929
2051
          p2 += sprintf(p2, " %02x", (int)strtol(p1 += 3, NIL, 16));
1930
2052
 
1931
 
        p2 += sprintf(p2, " [");
 
2053
        p2 += sprintf(p2, "%s  [", (full_l>l)?" ...":"");
1932
2054
        p1 = p;
1933
2055
 
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 : ' ');
1937
2059
        } /* for */
 
2060
        l = full_l;
1938
2061
 
1939
 
        p2 += sprintf(p2, "], length=%d -- complete frame ignored!", l);
1940
 
        info(chan, PRT_SHOWNUMBERS, STATE_RING, s);
1941
 
        return;
1942
 
      }
 
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 */
 
2068
        }
 
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);
 
2072
          return;
 
2073
        }
 
2074
      }   /* if IE unknown */
1943
2075
      else
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);
1945
2078
 
1946
2079
      /* changing 0x28 to 0x2800 for special case prevents much complication */
1947
2080
      /* later; 0x28 means / does different things in different countries    */
2396
2529
 
2397
2530
                    *pd = 0;
2398
2531
 
2399
 
                    if (ignoreCOLP && !Q931dmp) /* FIXME */
 
2532
                    if (ignoreCOLP && !Q931dmp) { /* FIXME */
 
2533
                      if (ignoreCOLP & 0x02) { /* show ignored info */
 
2534
                        sprintf(s1, "COLP %s -- ignored", s);
 
2535
                        info(chan, PRT_SHOWNUMBERS, STATE_RING, s1);
 
2536
                      }
2400
2537
                      break;
 
2538
                    }
2401
2539
 
2402
2540
                    if (!*s) {
2403
2541
                      info(chan, PRT_SHOWNUMBERS, STATE_RING, "COLP *INVALID* -- ignored!");
2509
2647
 
2510
2648
                          /* fall thru, and overwrite ... */
2511
2649
                        } /* else */
2512
 
                      } /* else */
2513
 
                    } /* else */
 
2650
                      } /* if current calling party number different */
 
2651
                    } /* if calling party number already present */
2514
2652
 
2515
2653
                    call[chan].screening = (oc3a & 3);
2516
2654
 
3018
3156
                      if (!Q931dmp)
3019
3157
                        px += sprintf(px, "PROGRESS: ");
3020
3158
 
3021
 
                      c = strtol(p + 6, NIL, 16);
3022
 
                      sn[sxp] = c;
 
3159
                      /* save coding standard (1=ISO,0=ETSI) with description */
 
3160
                      c = ((c&0x60)<<3) + strtol(p + 6, NIL, 16);
 
3161
                      sn[sxp] = c&0xff;
3023
3162
 
3024
3163
                      switch (c) {
3025
3164
#ifdef LANG_DE
3035
3174
                        case 0x84 : px += sprintf(px, "call has returned to the ISDN");                         break;
3036
3175
                        case 0x88 : px += sprintf(px, "inband information available");                            break;
3037
3176
#endif
 
3177
                        /* EN 301 060-1 and ECMA-143 table ZB.1 define: */
 
3178
                        case 0x190: px += sprintf(px, "interworking with a public network");
 
3179
                                  break;
 
3180
                        case 0x191: px += sprintf(px, "interworking with a network unable to supply a release signal");
 
3181
                                  break;
 
3182
                        case 0x192: px += sprintf(px, "interworking with a network unable to supply a release signal before answer");
 
3183
                                  break;
 
3184
                        case 0x193: px += sprintf(px, "interworking with a network unable to supply a release signal after answer");
 
3185
                                  break;
 
3186
                        default:    px += sprintf(px, "unknown description");
 
3187
                                  break;
3038
3188
                      } /* switch */
3039
3189
                    } /* if */
3040
3190
 
3185
3335
        default   : {
3186
3336
                      register char *p1, *p2;
3187
3337
                      register int  i;
3188
 
UNKNOWN_ELEMENT:      p1 = p; p2 = s;
 
3338
UNKNOWN_ELEMENT:      p1 = p; p2 = s;   /* s has length of BUFSIZ=8192 */
3189
3339
 
3190
3340
                      for (i = 0; i < l; i++)
3191
3341
                        p2 += sprintf(p2, "%02x ", (int)strtol(p1 += 3, NIL, 16));
3210
3360
                    break;
3211
3361
      } /* switch */
3212
3362
 
3213
 
    }
3214
 
    else if (Q931dmp) {
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);
3218
 
                   break;
3219
 
 
3220
 
          case 3 : sprintf(s, "%02x ---> Congestion level %d", element, element & 0xf);
3221
 
                   break;
3222
 
 
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);
3227
 
                   break;
3228
 
 
3229
 
         default : sprintf(s, "%02x ---> Reserved %d", element, element);
3230
 
                   break;
3231
 
        } /* switch */
3232
 
 
3233
 
        Q931dump(TYPE_STRING, -3, s, version);
3234
 
      }
3235
 
      else if (version == VERSION_EDSS1) {
3236
 
        switch ((element >> 4) & 7) {
3237
 
          case 1 : sprintf(s, "%02x ---> Shift %d", element, element & 0xf);
3238
 
                   break;
3239
 
 
3240
 
          case 3 : sprintf(s, "%02x ---> Congestion level %d", element, element & 0xf);
3241
 
                   break;
3242
 
 
3243
 
          case 5 : sprintf(s, "%02x ---> Repeat indicator %d", element, element & 0xf);
3244
 
                   break;
3245
 
 
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);
3252
 
                   break;
3253
 
 
3254
 
         default : sprintf(s, "%02x ---> Reserved %d\n", element, element);
3255
 
                   break;
3256
 
        } /* switch */
3257
 
 
3258
 
        Q931dump(TYPE_STRING, -3, s, version);
3259
 
      } /* else */
3260
 
    } /* else */
3261
 
  } /* while */
 
3363
    } /* if (element < 128) -- variable length information elements */
 
3364
    else {
 
3365
 
 
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);
 
3371
        }
 
3372
        else {
 
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);
 
3376
        }
 
3377
      } 
 
3378
 
 
3379
      if (Q931dmp) {
 
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);
 
3383
                     break;
 
3384
 
 
3385
            case 3 : sprintf(s, "%02x ---> Congestion level %d", element, element & 0xf);
 
3386
                     break;
 
3387
 
 
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);
 
3392
                     break;
 
3393
 
 
3394
           default : sprintf(s, "%02x ---> Reserved %d", element, element);
 
3395
                     break;
 
3396
          } /* switch */
 
3397
 
 
3398
          Q931dump(TYPE_STRING, -3, s, version);
 
3399
        }
 
3400
        else if (version == VERSION_EDSS1) {
 
3401
          switch ((element >> 4) & 7) {
 
3402
            case 1 : sprintf(s, "%02x ---> Shift %d", element, element & 0xf);
 
3403
                     break;
 
3404
 
 
3405
            case 3 : sprintf(s, "%02x ---> Congestion level %d", element, element & 0xf);
 
3406
                     break;
 
3407
 
 
3408
            case 5 : sprintf(s, "%02x ---> Repeat indicator %d", element, element & 0xf);
 
3409
                     break;
 
3410
 
 
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);
 
3417
                     break;
 
3418
 
 
3419
           default : sprintf(s, "%02x ---> Reserved %d\n", element, element);
 
3420
                     break;
 
3421
          } /* switch */
 
3422
 
 
3423
          Q931dump(TYPE_STRING, -3, s, version);
 
3424
        } /* else */
 
3425
      } /* if Q931dmp */
 
3426
    } /* if (element<128) ... else */
 
3427
  } /* while (1) -- loop over all present information elements */
3262
3428
} /* decode */
3263
3429
 
3264
3430
/* --------------------------------------------------------------------------
4098
4264
  else {
4099
4265
    call[chan].tarifknown = 1;
4100
4266
    call[chan].pay = call[chan].Rate.Charge;
 
4267
                if (call[chan].zone == UNKNOWN) {
 
4268
                        if ( call[chan].Rate.z > 0 && call[chan].Rate.domestic
 
4269
                       && call[chan].sondernummer[CALLED] == UNKNOWN )
 
4270
                                call[chan].zone = call[chan].Rate.z; /* store exact zone DE:[1234] */
 
4271
                        else
 
4272
                                call[chan].zone = call[chan].Rate.zone; /* store for logfile entry */
 
4273
                }       
4101
4274
  } /* else */
4102
4275
} /* processRate */
4103
4276
 
4350
4523
  register int         i, c;
4351
4524
  register int         wegchan; /* fuer gemakelte */
4352
4525
  auto     int         dialin, type = 0, cref = -1, creflen, version;
 
4526
  auto     int         dialin_cref;
4353
4527
  static   int         tei = BROADCAST, sapi = 0, net = 1, firsttime = 1;
4354
4528
  auto     char        sx[BUFSIZ], s1[BUFSIZ], s2[BUFSIZ];
4355
4529
  auto     char       *why, *hint;
4356
4530
  auto     char        hints[BUFSIZ];
4357
4531
  static   char        last[BUFSIZ];
4358
 
  auto     int         isAVMB1 = 0;
 
4532
  auto     int         isAVMB1 = 0,  isAVMB1_D2 = 0;   /*,  D2_net = -1; */
4359
4533
  auto     double      tx;
 
4534
  auto     int         origchan = -1; /* sourcechan for RELEASE in chan 4 */
4360
4535
 
4361
4536
 
4362
4537
  hexSeen = 1;
4385
4560
  if (!memcmp(ps, "D2", 2)) { /* AVMB1 */
4386
4561
    if (firsttime) {
4387
4562
      firsttime = 0;
4388
 
      print_msg (PRT_NORMAL, "(AVM B1 driver detected (D2))");
 
4563
      print_msg (PRT_NORMAL, "(AVM B1 driver detected (D2))\n");
4389
4564
    } /* if */
 
4565
    isAVMB1_D2 = 1;
 
4566
    /* D2_net = ( *(ps+2) == '<' ) ? 0 : 1; */
4390
4567
    memcpy(ps, "HEX: ", 5);
4391
4568
  } /* if */
4392
4569
 
4393
4570
  if (!memcmp(ps, "DTRC:", 5)) { /* Eicon Driver */
4394
4571
    if (firsttime) {
4395
4572
      firsttime = 0;
4396
 
      print_msg (PRT_NORMAL, "(Eicon active driver detected)");
 
4573
      print_msg (PRT_NORMAL, "(Eicon active driver detected)\n");
4397
4574
    } /* if */
4398
4575
    memcpy(ps, "HEX: ", 5);
4399
4576
  } /* if */
4407
4584
      firsttime = 0;
4408
4585
 
4409
4586
      if (!Q931dmp)
4410
 
        print_msg(PRT_NORMAL, "(HiSax driver detected)");
 
4587
        print_msg(PRT_NORMAL, "(HiSax driver detected)\n");
4411
4588
 
4412
4589
      HiSax = 1;
4413
4590
      strcpy(last, s);
4668
4845
 
4669
4846
    type = strtol(ps += 3, NIL, 16);
4670
4847
 
4671
 
    if (!isAVMB1)
 
4848
    dialin_cref = (cref>>7)!=net;
 
4849
 
 
4850
    if (isAVMB1)
 
4851
      dialin = (cref & 0x80);  /* first (SETUP) tells us who initiates the connection */
 
4852
    else if (isAVMB1_D2 && tei==0) /* AVMB1 with D2 D-channel trace connected */
 
4853
      dialin = dialin_cref;        /* point to point (PtP) to NT or PABX */
 
4854
    else
4672
4855
      dialin = (tei == BROADCAST); /* dialin (Broadcast), alle anderen haben schon eine Tei! */
4673
 
    else
4674
 
      dialin = (cref & 0x80);  /* first (SETUP) tells us who initiates the connection */
 
4856
 
 
4857
    /* cref&0x80 will be 0 if current message comes from the side (NET or USR)
 
4858
     * that has initially used this cref.  It will be 0x80 if the message is
 
4859
     * from the opposite side.  Consequently just (cref&0x80) should not work.
 
4860
     * |TB| 2003-08-17 */     
4675
4861
 
4676
4862
    /* dialin = (cref & 0x7f) < 64; */
 
4863
    /* ^-- line was commented out before rev. 1.1 dating from 1997-03-16 */
4677
4864
 
4678
4865
    cref = (net) ? cref : cref ^ 0x80; /* cref immer aus Sicht des Amts */
4679
4866
 
4683
4870
    if (allflags & PRT_DEBUG_DIAG)
4684
4871
      diag(cref, tei, sapi, dialin, net, type, version);
4685
4872
 
 
4873
#if 0
 
4874
    if (isAVMB1_D2)
 
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");
 
4877
#endif
 
4878
 
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:.. */
4690
 
 
 
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
 
4889
                        party number
 
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
 
4897
       moved to call[0].
 
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. 
 
4901
    */
4691
4902
    if (type == SETUP) { /* neuen Kanal, ev. dummy, wenn keiner da ist */
4692
4903
      chan = 5; /* den nehmen wir _nur_ dafuer! */
4693
 
      clearchan(chan, 1);
 
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) {
 
4908
            chan = i;
 
4909
            print_msg(PRT_DEBUG_BUGS, " DEBUG> %s: Decoding SETUP in chan %d (cref=%d tei=%d)\n", st + 4, chan, cref, tei);
 
4910
            break;
 
4911
          }
 
4912
      }  
 
4913
      if (chan == 5) /* do not clear other chans */
 
4914
        clearchan(chan, 1);
4694
4915
      call[chan].dialin = dialin;
4695
4916
      call[chan].tei = tei;
4696
4917
      call[chan].card = card;
4702
4923
        LCR(chan, s);
4703
4924
#endif
4704
4925
 
4705
 
      if (call[chan].channel) { /* Aha, Kanal war dabei, dann nehmen wir den gleich */
 
4926
      if (chan != 5 && call[chan].channel && call[chan].channel != chan+1)
 
4927
        print_msg(PRT_WARN, "Warning: SETUP assumed for channel B%d lead to channel B%d.\n", chan+1, call[chan].channel);
 
4928
        
 
4929
      if (chan == 5 && call[chan].channel) { /* Aha, Kanal war dabei, dann nehmen wir den gleich */
4706
4930
        chan = call[chan].channel - 1;
4707
4931
 
4708
4932
        if (chanused[chan])
4773
4997
 
4774
4998
        chan = call[chan].channel - 1;
4775
4999
 
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. 
 
5015
         * |TB| 2003-09-16
 
5016
         */
 
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);
 
5022
            chanused[chan] = 0;
 
5023
          }
4778
5024
          memcpy((char *)&call[chan], (char *)&call[5], sizeof(CALL));
4779
5025
          Change_Channel(5, chan);
4780
5026
          addlist(chan, type, 1);
5030
5276
           CONNECT noch folgt, wird dafuer jetzt chan auf
5031
5277
           4 gepackt, um die schoenen Daten in 0/1/ev.4 nicht
5032
5278
           zu zerstoeren. Wir erkennen das an fehlender tei. */
5033
 
 
 
5279
        /* The above strategy leaves chan 0/1 uncleared since it seems
 
5280
         * unknown whether this is the last RELEASE with an unanswered
 
5281
         * call or not. */
5034
5282
        if (call[chan].tei == BROADCAST) {
5035
5283
          memcpy((char *)&call[4], (char *)&call[chan], sizeof(CALL));
5036
5284
          Change_Channel(chan, 4);
 
5285
          /* The following proofed to be not clever, since chan 4 is also
 
5286
           * cleared later.  For a cleared status for the next call another
 
5287
           * idea is needed.
 
5288
            clearchan(chan, 1);
 
5289
            chanused[chan] = 0;
 
5290
           */
 
5291
          origchan = chan; /* save number of persistent channel */
5037
5292
          chan = 4;
5038
5293
          addlist(chan, type, 1);
5039
5294
          call[chan].tei = tei;
5092
5347
          } /* if */
5093
5348
        } /* if */
5094
5349
 
5095
 
        if (!Q931dmp)
5096
 
          logger(chan);
 
5350
        if (!Q931dmp) {
 
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
 
5355
           * written.  |TB| */
 
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);
 
5363
          else {
 
5364
            logger(chan);
 
5365
            call[origchan>-1?origchan:chan].logcount++; /* remember logentry */
 
5366
          }
 
5367
        }
5097
5368
 
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);
5572
 
      }
 
5843
      } /* if (replay) */
5573
5844
      else {
5574
5845
#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
5575
5846
        if (!memcmp(p1 + 9, "DW_ABC_LCR", 10))
5597
5868
            } /* else */
5598
5869
          } /* else */
5599
5870
        } /* else */
5600
 
      } /* else */
 
5871
      } /* if (replay) ... else */
5601
5872
 
5602
5873
      p1 = p2 + 1;
5603
5874
    } /* while */