linux/drivers/isdn/hardware/eicon/maintidi.c
<<
>>
Prefs
   1/*
   2 *
   3  Copyright (c) Eicon Networks, 2000.
   4 *
   5  This source file is supplied for the use with
   6  Eicon Networks range of DIVA Server Adapters.
   7 *
   8  Eicon File Revision :    1.9
   9 *
  10  This program is free software; you can redistribute it and/or modify
  11  it under the terms of the GNU General Public License as published by
  12  the Free Software Foundation; either version 2, or (at your option)
  13  any later version.
  14 *
  15  This program is distributed in the hope that it will be useful,
  16  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
  17  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  18  See the GNU General Public License for more details.
  19 *
  20  You should have received a copy of the GNU General Public License
  21  along with this program; if not, write to the Free Software
  22  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23 *
  24 */
  25#include "platform.h"
  26#include "kst_ifc.h"
  27#include "di_defs.h"
  28#include "maintidi.h"
  29#include "pc.h"
  30#include "man_defs.h"
  31
  32
  33extern void diva_mnt_internal_dprintf (dword drv_id, dword type, char* p, ...);
  34
  35#define MODEM_PARSE_ENTRIES  16 /* amount of variables of interest */
  36#define FAX_PARSE_ENTRIES    12 /* amount of variables of interest */
  37#define LINE_PARSE_ENTRIES   15 /* amount of variables of interest */
  38#define STAT_PARSE_ENTRIES   70 /* amount of variables of interest */
  39
  40/*
  41        LOCAL FUNCTIONS
  42        */
  43static int DivaSTraceLibraryStart (void* hLib);
  44static int DivaSTraceLibraryStop  (void* hLib);
  45static int SuperTraceLibraryFinit (void* hLib);
  46static void*    SuperTraceGetHandle (void* hLib);
  47static int SuperTraceMessageInput (void* hLib);
  48static int SuperTraceSetAudioTap  (void* hLib, int Channel, int on);
  49static int SuperTraceSetBChannel  (void* hLib, int Channel, int on);
  50static int SuperTraceSetDChannel  (void* hLib, int on);
  51static int SuperTraceSetInfo      (void* hLib, int on);
  52static int SuperTraceClearCall (void* hLib, int Channel);
  53static int SuperTraceGetOutgoingCallStatistics (void* hLib);
  54static int SuperTraceGetIncomingCallStatistics (void* hLib);
  55static int SuperTraceGetModemStatistics (void* hLib);
  56static int SuperTraceGetFaxStatistics (void* hLib);
  57static int SuperTraceGetBLayer1Statistics (void* hLib);
  58static int SuperTraceGetBLayer2Statistics (void* hLib);
  59static int SuperTraceGetDLayer1Statistics (void* hLib);
  60static int SuperTraceGetDLayer2Statistics (void* hLib);
  61
  62/*
  63        LOCAL FUNCTIONS
  64        */
  65static int ScheduleNextTraceRequest (diva_strace_context_t* pLib);
  66static int process_idi_event (diva_strace_context_t* pLib,
  67                                                                                                                        diva_man_var_header_t* pVar);
  68static int process_idi_info  (diva_strace_context_t* pLib,
  69                                                                                                                        diva_man_var_header_t* pVar);
  70static int diva_modem_event (diva_strace_context_t* pLib, int Channel);
  71static int diva_fax_event   (diva_strace_context_t* pLib, int Channel);
  72static int diva_line_event (diva_strace_context_t* pLib, int Channel);
  73static int diva_modem_info (diva_strace_context_t* pLib,
  74                                                                                                                int Channel,
  75                                                                                                                diva_man_var_header_t* pVar);
  76static int diva_fax_info   (diva_strace_context_t* pLib,
  77                                                                                                                int Channel,
  78                                                                                                                diva_man_var_header_t* pVar);
  79static int diva_line_info  (diva_strace_context_t* pLib,
  80                                                                                                                int Channel,
  81                                                                                                                diva_man_var_header_t* pVar);
  82static int diva_ifc_statistics (diva_strace_context_t* pLib,
  83                                                                                                                                diva_man_var_header_t* pVar);
  84static diva_man_var_header_t* get_next_var (diva_man_var_header_t* pVar);
  85static diva_man_var_header_t* find_var (diva_man_var_header_t* pVar,
  86                                                                                                                                                                const char* name);
  87static int diva_strace_read_int  (diva_man_var_header_t* pVar, int* var);
  88static int diva_strace_read_uint (diva_man_var_header_t* pVar, dword* var);
  89static int diva_strace_read_asz  (diva_man_var_header_t* pVar, char* var);
  90static int diva_strace_read_asc  (diva_man_var_header_t* pVar, char* var);
  91static int  diva_strace_read_ie  (diva_man_var_header_t* pVar,
  92                                                                                                                                        diva_trace_ie_t* var);
  93static void diva_create_parse_table (diva_strace_context_t* pLib);
  94static void diva_trace_error (diva_strace_context_t* pLib,
  95                                                                                                                        int error, const char* file, int line);
  96static void diva_trace_notify_user (diva_strace_context_t* pLib,
  97                                                                                                                 int Channel,
  98                                                                                                                 int notify_subject);
  99static int diva_trace_read_variable (diva_man_var_header_t* pVar,
 100                                                                                                                                                 void* variable);
 101
 102/*
 103        Initialize the library and return context
 104        of the created trace object that will represent
 105        the IDI adapter.
 106        Return 0 on error.
 107        */
 108diva_strace_library_interface_t* DivaSTraceLibraryCreateInstance (int Adapter,
 109                                                                                        const diva_trace_library_user_interface_t* user_proc,
 110                      byte* pmem) {
 111        diva_strace_context_t* pLib = (diva_strace_context_t*)pmem;
 112        int i;
 113
 114        if (!pLib) {
 115                return NULL;
 116        }
 117
 118        pmem += sizeof(*pLib);
 119        memset(pLib, 0x00, sizeof(*pLib));
 120
 121        pLib->Adapter  = Adapter;
 122
 123        /*
 124                Set up Library Interface
 125                */
 126        pLib->instance.hLib                                = pLib;
 127  pLib->instance.DivaSTraceLibraryStart              = DivaSTraceLibraryStart;
 128  pLib->instance.DivaSTraceLibraryStop               = DivaSTraceLibraryStop;
 129        pLib->instance.DivaSTraceLibraryFinit              = SuperTraceLibraryFinit;
 130        pLib->instance.DivaSTraceMessageInput              = SuperTraceMessageInput;
 131        pLib->instance.DivaSTraceGetHandle                 = SuperTraceGetHandle;
 132        pLib->instance.DivaSTraceSetAudioTap               = SuperTraceSetAudioTap;
 133        pLib->instance.DivaSTraceSetBChannel               = SuperTraceSetBChannel;
 134        pLib->instance.DivaSTraceSetDChannel               = SuperTraceSetDChannel;
 135        pLib->instance.DivaSTraceSetInfo                   = SuperTraceSetInfo;
 136        pLib->instance.DivaSTraceGetOutgoingCallStatistics = \
 137                                                                                                                                                        SuperTraceGetOutgoingCallStatistics;
 138        pLib->instance.DivaSTraceGetIncomingCallStatistics = \
 139                                                                                                                                                        SuperTraceGetIncomingCallStatistics;
 140        pLib->instance.DivaSTraceGetModemStatistics        = \
 141                                                                                                                                                        SuperTraceGetModemStatistics;
 142        pLib->instance.DivaSTraceGetFaxStatistics          = \
 143                                                                                                                                                        SuperTraceGetFaxStatistics;
 144        pLib->instance.DivaSTraceGetBLayer1Statistics      = \
 145                                                                                                                                                        SuperTraceGetBLayer1Statistics;
 146        pLib->instance.DivaSTraceGetBLayer2Statistics      = \
 147                                                                                                                                                        SuperTraceGetBLayer2Statistics;
 148        pLib->instance.DivaSTraceGetDLayer1Statistics      = \
 149                                                                                                                                                        SuperTraceGetDLayer1Statistics;
 150        pLib->instance.DivaSTraceGetDLayer2Statistics      = \
 151                                                                                                                                                        SuperTraceGetDLayer2Statistics;
 152        pLib->instance.DivaSTraceClearCall                 = SuperTraceClearCall;
 153
 154
 155        if (user_proc) {
 156                pLib->user_proc_table.user_context      = user_proc->user_context;
 157                pLib->user_proc_table.notify_proc       = user_proc->notify_proc;
 158                pLib->user_proc_table.trace_proc        = user_proc->trace_proc;
 159                pLib->user_proc_table.error_notify_proc = user_proc->error_notify_proc;
 160        }
 161
 162        if (!(pLib->hAdapter = SuperTraceOpenAdapter (Adapter))) {
 163    diva_mnt_internal_dprintf (0, DLI_ERR, "Can not open XDI adapter");
 164                return NULL;
 165        }
 166        pLib->Channels = SuperTraceGetNumberOfChannels (pLib->hAdapter);
 167
 168        /*
 169                Calculate amount of parte table entites necessary to translate
 170                information from all events of onterest
 171                */
 172        pLib->parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \
 173                                                                                                 STAT_PARSE_ENTRIES + \
 174                                                                                                 LINE_PARSE_ENTRIES + 1) * pLib->Channels;
 175        pLib->parse_table = (diva_strace_path2action_t*)pmem;
 176
 177        for (i = 0; i < 30; i++) {
 178                pLib->lines[i].pInterface     = &pLib->Interface;
 179                pLib->lines[i].pInterfaceStat = &pLib->InterfaceStat;
 180        }
 181
 182  pLib->e.R = &pLib->RData;
 183
 184        pLib->req_busy = 1;
 185        pLib->rc_ok    = ASSIGN_OK;
 186
 187        diva_create_parse_table (pLib);
 188
 189        return ((diva_strace_library_interface_t*)pLib);
 190}
 191
 192static int DivaSTraceLibraryStart (void* hLib) {
 193  diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
 194
 195  return (SuperTraceASSIGN (pLib->hAdapter, pLib->buffer));
 196}
 197
 198/*
 199  Return (-1) on error
 200  Return (0) if was initiated or pending
 201  Return (1) if removal is complete
 202  */
 203static int DivaSTraceLibraryStop  (void* hLib) {
 204  diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
 205
 206  if (!pLib->e.Id) { /* Was never started/assigned */
 207    return (1);
 208  }
 209
 210  switch (pLib->removal_state) {
 211    case 0:
 212      pLib->removal_state = 1;
 213      ScheduleNextTraceRequest(pLib);
 214      break;
 215
 216    case 3:
 217      return (1);
 218  }
 219
 220  return (0);
 221}
 222
 223static int SuperTraceLibraryFinit (void* hLib) {
 224        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
 225        if (pLib) {
 226                if (pLib->hAdapter) {
 227                        SuperTraceCloseAdapter  (pLib->hAdapter);
 228                }
 229                return (0);
 230        }
 231        return (-1);
 232}
 233
 234static void*    SuperTraceGetHandle (void* hLib) {
 235        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
 236
 237  return (&pLib->e);
 238}
 239
 240/*
 241        After library handle object is gone in signaled state
 242        this function should be called and will pick up incoming
 243        IDI messages (return codes and indications).
 244        */
 245static int SuperTraceMessageInput (void* hLib) {
 246        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
 247        int ret = 0;
 248  byte Rc, Ind;
 249
 250  if (pLib->e.complete == 255) {
 251    /*
 252      Process return code
 253      */
 254    pLib->req_busy = 0;
 255    Rc             = pLib->e.Rc;
 256    pLib->e.Rc     = 0;
 257
 258    if (pLib->removal_state == 2) {
 259      pLib->removal_state = 3;
 260      return (0);
 261    }
 262
 263                if (Rc != pLib->rc_ok) {
 264      int ignore = 0;
 265      /*
 266        Auto-detect amount of events/channels and features
 267        */
 268      if (pLib->general_b_ch_event == 1) {
 269        pLib->general_b_ch_event = 2;
 270        ignore = 1;
 271      } else if (pLib->general_fax_event == 1) {
 272        pLib->general_fax_event = 2;
 273        ignore = 1;
 274      } else if (pLib->general_mdm_event == 1) {
 275        pLib->general_mdm_event = 2;
 276        ignore = 1;
 277      } else if ((pLib->ChannelsTraceActive < pLib->Channels) && pLib->ChannelsTraceActive) {
 278        pLib->ChannelsTraceActive = pLib->Channels;
 279        ignore = 1;
 280      } else if (pLib->ModemTraceActive < pLib->Channels) {
 281        pLib->ModemTraceActive = pLib->Channels;
 282        ignore = 1;
 283      } else if (pLib->FaxTraceActive < pLib->Channels) {
 284        pLib->FaxTraceActive = pLib->Channels;
 285        ignore = 1;
 286      } else if (pLib->audio_trace_init == 2) {
 287        ignore = 1;
 288        pLib->audio_trace_init = 1;
 289      } else if (pLib->eye_pattern_pending) {
 290                                pLib->eye_pattern_pending =  0;
 291                                ignore = 1;
 292                        } else if (pLib->audio_tap_pending) {
 293                                pLib->audio_tap_pending = 0;
 294                                ignore = 1;
 295      }
 296
 297      if (!ignore) {
 298        return (-1); /* request failed */
 299      }
 300    } else {
 301      if (pLib->general_b_ch_event == 1) {
 302        pLib->ChannelsTraceActive = pLib->Channels;
 303        pLib->general_b_ch_event = 2;
 304      } else if (pLib->general_fax_event == 1) {
 305        pLib->general_fax_event = 2;
 306        pLib->FaxTraceActive = pLib->Channels;
 307      } else if (pLib->general_mdm_event == 1) {
 308        pLib->general_mdm_event = 2;
 309        pLib->ModemTraceActive = pLib->Channels;
 310      }
 311    }
 312    if (pLib->audio_trace_init == 2) {
 313      pLib->audio_trace_init = 1;
 314    }
 315    pLib->rc_ok = 0xff; /* default OK after assign was done */
 316    if ((ret = ScheduleNextTraceRequest(pLib))) {
 317      return (-1);
 318    }
 319  } else {
 320    /*
 321      Process indication
 322      Always 'RNR' indication if return code is pending
 323      */
 324    Ind         = pLib->e.Ind;
 325    pLib->e.Ind = 0;
 326    if (pLib->removal_state) {
 327      pLib->e.RNum      = 0;
 328      pLib->e.RNR       = 2;
 329    } else if (pLib->req_busy) {
 330      pLib->e.RNum      = 0;
 331      pLib->e.RNR       = 1;
 332    } else {
 333      if (pLib->e.complete != 0x02) {
 334        /*
 335          Look-ahead call, set up buffers
 336          */
 337        pLib->e.RNum       = 1;
 338        pLib->e.R->P       = (byte*)&pLib->buffer[0];
 339        pLib->e.R->PLength = (word)(sizeof(pLib->buffer) - 1);
 340
 341      } else {
 342        /*
 343          Indication reception complete, process it now
 344          */
 345        byte* p = (byte*)&pLib->buffer[0];
 346        pLib->buffer[pLib->e.R->PLength] = 0; /* terminate I.E. with zero */
 347
 348        switch (Ind) {
 349          case MAN_COMBI_IND: {
 350            int total_length    = pLib->e.R->PLength;
 351            word  this_ind_length;
 352
 353            while (total_length > 3 && *p) {
 354              Ind = *p++;
 355              this_ind_length = (word)p[0] | ((word)p[1] << 8);
 356              p += 2;
 357
 358              switch (Ind) {
 359                case MAN_INFO_IND:
 360                  if (process_idi_info (pLib, (diva_man_var_header_t*)p)) {
 361                    return (-1);
 362                  }
 363                  break;
 364                                        case MAN_EVENT_IND:
 365                  if (process_idi_event (pLib, (diva_man_var_header_t*)p)) {
 366                    return (-1);
 367                  }
 368                  break;
 369                case MAN_TRACE_IND:
 370                  if (pLib->trace_on == 1) {
 371                    /*
 372                      Ignore first trace event that is result of
 373                      EVENT_ON operation
 374                    */
 375                    pLib->trace_on++;
 376                  } else {
 377                    /*
 378                      Delivery XLOG buffer to application
 379                      */
 380                    if (pLib->user_proc_table.trace_proc) {
 381                      (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
 382                                                            &pLib->instance, pLib->Adapter,
 383                                                            p, this_ind_length);
 384                    }
 385                  }
 386                  break;
 387                default:
 388                  diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind (DMA mode): %02x", Ind);
 389              }
 390              p += (this_ind_length+1);
 391              total_length -= (4 + this_ind_length);
 392            }
 393          } break;
 394          case MAN_INFO_IND:
 395            if (process_idi_info (pLib, (diva_man_var_header_t*)p)) {
 396              return (-1);
 397            }
 398            break;
 399                                        case MAN_EVENT_IND:
 400            if (process_idi_event (pLib, (diva_man_var_header_t*)p)) {
 401              return (-1);
 402            }
 403            break;
 404          case MAN_TRACE_IND:
 405            if (pLib->trace_on == 1) {
 406              /*
 407                Ignore first trace event that is result of
 408                EVENT_ON operation
 409              */
 410              pLib->trace_on++;
 411            } else {
 412              /*
 413                Delivery XLOG buffer to application
 414                */
 415              if (pLib->user_proc_table.trace_proc) {
 416                (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
 417                                                      &pLib->instance, pLib->Adapter,
 418                                                      p, pLib->e.R->PLength);
 419              }
 420            }
 421            break;
 422          default:
 423            diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind: %02x", Ind);
 424        }
 425      }
 426    }
 427  }
 428
 429        if ((ret = ScheduleNextTraceRequest(pLib))) {
 430                return (-1);
 431        }
 432
 433        return (ret);
 434}
 435
 436/*
 437        Internal state machine responsible for scheduling of requests
 438        */
 439static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 440        char name[64];
 441        int ret = 0;
 442        int i;
 443
 444        if (pLib->req_busy) {
 445                return (0);
 446        }
 447
 448  if (pLib->removal_state == 1) {
 449                if (SuperTraceREMOVE (pLib->hAdapter)) {
 450      pLib->removal_state = 3;
 451    } else {
 452      pLib->req_busy = 1;
 453      pLib->removal_state = 2;
 454    }
 455    return (0);
 456  }
 457
 458  if (pLib->removal_state) {
 459    return (0);
 460  }
 461
 462  if (!pLib->general_b_ch_event) {
 463                if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\B Event", pLib->buffer))) {
 464      return (-1);
 465    }
 466    pLib->general_b_ch_event = 1;
 467                pLib->req_busy = 1;
 468                return (0);
 469  }
 470
 471  if (!pLib->general_fax_event) {
 472                if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\FAX Event", pLib->buffer))) {
 473      return (-1);
 474    }
 475    pLib->general_fax_event = 1;
 476                pLib->req_busy = 1;
 477                return (0);
 478  }
 479
 480  if (!pLib->general_mdm_event) {
 481                if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\Modem Event", pLib->buffer))) {
 482      return (-1);
 483    }
 484    pLib->general_mdm_event = 1;
 485                pLib->req_busy = 1;
 486                return (0);
 487  }
 488
 489        if (pLib->ChannelsTraceActive < pLib->Channels) {
 490                pLib->ChannelsTraceActive++;
 491                sprintf (name, "State\\B%d\\Line", pLib->ChannelsTraceActive);
 492                if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 493                        pLib->ChannelsTraceActive--;
 494                        return (-1);
 495                }
 496                pLib->req_busy = 1;
 497                return (0);
 498        }
 499
 500        if (pLib->ModemTraceActive < pLib->Channels) {
 501                pLib->ModemTraceActive++;
 502                sprintf (name, "State\\B%d\\Modem\\Event", pLib->ModemTraceActive);
 503                if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 504                        pLib->ModemTraceActive--;
 505                        return (-1);
 506                }
 507                pLib->req_busy = 1;
 508                return (0);
 509        }
 510
 511        if (pLib->FaxTraceActive < pLib->Channels) {
 512                pLib->FaxTraceActive++;
 513                sprintf (name, "State\\B%d\\FAX\\Event", pLib->FaxTraceActive);
 514                if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 515                        pLib->FaxTraceActive--;
 516                        return (-1);
 517                }
 518                pLib->req_busy = 1;
 519                return (0);
 520        }
 521
 522        if (!pLib->trace_mask_init) {
 523                word tmp = 0x0000;
 524                if (SuperTraceWriteVar (pLib->hAdapter,
 525                                                                                                                pLib->buffer,
 526                                                                                                                "Trace\\Event Enable",
 527                                                                                                                &tmp,
 528                                                                                                                0x87, /* MI_BITFLD */
 529                                                                                                                sizeof(tmp))) {
 530                        return (-1);
 531                }
 532                pLib->trace_mask_init = 1;
 533                pLib->req_busy = 1;
 534                return (0);
 535        }
 536
 537        if (!pLib->audio_trace_init) {
 538                dword tmp = 0x00000000;
 539                if (SuperTraceWriteVar (pLib->hAdapter,
 540                                                                                                                pLib->buffer,
 541                                                                                                                "Trace\\AudioCh# Enable",
 542                                                                                                                &tmp,
 543                                                                                                                0x87, /* MI_BITFLD */
 544                                                                                                                sizeof(tmp))) {
 545                        return (-1);
 546                }
 547                pLib->audio_trace_init = 2;
 548                pLib->req_busy = 1;
 549                return (0);
 550        }
 551
 552        if (!pLib->bchannel_init) {
 553                dword tmp = 0x00000000;
 554                if (SuperTraceWriteVar (pLib->hAdapter,
 555                                                                                                                pLib->buffer,
 556                                                                                                                "Trace\\B-Ch# Enable",
 557                                                                                                                &tmp,
 558                                                                                                                0x87, /* MI_BITFLD */
 559                                                                                                                sizeof(tmp))) {
 560                        return (-1);
 561                }
 562                pLib->bchannel_init = 1;
 563                pLib->req_busy = 1;
 564                return (0);
 565        }
 566
 567        if (!pLib->trace_length_init) {
 568                word tmp = 30;
 569                if (SuperTraceWriteVar (pLib->hAdapter,
 570                                                                                                                pLib->buffer,
 571                                                                                                                "Trace\\Max Log Length",
 572                                                                                                                &tmp,
 573                                                                                                                0x82, /* MI_UINT */
 574                                                                                                                sizeof(tmp))) {
 575                        return (-1);
 576                }
 577                pLib->trace_length_init = 1;
 578                pLib->req_busy = 1;
 579                return (0);
 580        }
 581
 582        if (!pLib->trace_on) {
 583                if (SuperTraceTraceOnRequest (pLib->hAdapter,
 584                                                                                                                                        "Trace\\Log Buffer",
 585                                                                                                                                        pLib->buffer)) {
 586                        return (-1);
 587                }
 588                pLib->trace_on = 1;
 589                pLib->req_busy = 1;
 590                return (0);
 591        }
 592
 593        if (pLib->trace_event_mask != pLib->current_trace_event_mask) {
 594                if (SuperTraceWriteVar (pLib->hAdapter,
 595                                                                                                                pLib->buffer,
 596                                                                                                                "Trace\\Event Enable",
 597                                                                                                                &pLib->trace_event_mask,
 598                                                                                                                0x87, /* MI_BITFLD */
 599                                                                                                                sizeof(pLib->trace_event_mask))) {
 600                        return (-1);
 601                }
 602                pLib->current_trace_event_mask = pLib->trace_event_mask;
 603                pLib->req_busy = 1;
 604                return (0);
 605        }
 606
 607        if ((pLib->audio_tap_pending >= 0) && (pLib->audio_tap_mask != pLib->current_audio_tap_mask)) {
 608                if (SuperTraceWriteVar (pLib->hAdapter,
 609                                                                                                                pLib->buffer,
 610                                                                                                                "Trace\\AudioCh# Enable",
 611                                                                                                                &pLib->audio_tap_mask,
 612                                                                                                                0x87, /* MI_BITFLD */
 613                                                                                                                sizeof(pLib->audio_tap_mask))) {
 614                        return (-1);
 615                }
 616                pLib->current_audio_tap_mask = pLib->audio_tap_mask;
 617                pLib->audio_tap_pending = 1;
 618                pLib->req_busy = 1;
 619                return (0);
 620        }
 621
 622        if ((pLib->eye_pattern_pending >= 0) && (pLib->audio_tap_mask != pLib->current_eye_pattern_mask)) {
 623                if (SuperTraceWriteVar (pLib->hAdapter,
 624                                                                                                                pLib->buffer,
 625                                                                                                                "Trace\\EyeCh# Enable",
 626                                                                                                                &pLib->audio_tap_mask,
 627                                                                                                                0x87, /* MI_BITFLD */
 628                                                                                                                sizeof(pLib->audio_tap_mask))) {
 629                        return (-1);
 630                }
 631                pLib->current_eye_pattern_mask = pLib->audio_tap_mask;
 632                pLib->eye_pattern_pending = 1;
 633                pLib->req_busy = 1;
 634                return (0);
 635        }
 636
 637        if (pLib->bchannel_trace_mask != pLib->current_bchannel_trace_mask) {
 638                if (SuperTraceWriteVar (pLib->hAdapter,
 639                                                                                                                pLib->buffer,
 640                                                                                                                "Trace\\B-Ch# Enable",
 641                                                                                                                &pLib->bchannel_trace_mask,
 642                                                                                                                0x87, /* MI_BITFLD */
 643                                                                                                                sizeof(pLib->bchannel_trace_mask))) {
 644                        return (-1);
 645                }
 646                pLib->current_bchannel_trace_mask = pLib->bchannel_trace_mask;
 647                pLib->req_busy = 1;
 648                return (0);
 649        }
 650
 651        if (!pLib->trace_events_down) {
 652                if (SuperTraceTraceOnRequest (pLib->hAdapter,
 653                                                                                                                                        "Events Down",
 654                                                                                                                                        pLib->buffer)) {
 655                        return (-1);
 656                }
 657                pLib->trace_events_down = 1;
 658                pLib->req_busy = 1;
 659                return (0);
 660        }
 661
 662        if (!pLib->l1_trace) {
 663                if (SuperTraceTraceOnRequest (pLib->hAdapter,
 664                                                                                                                                        "State\\Layer1",
 665                                                                                                                                        pLib->buffer)) {
 666                        return (-1);
 667                }
 668                pLib->l1_trace = 1;
 669                pLib->req_busy = 1;
 670                return (0);
 671        }
 672
 673        if (!pLib->l2_trace) {
 674                if (SuperTraceTraceOnRequest (pLib->hAdapter,
 675                                                                                                                                        "State\\Layer2 No1",
 676                                                                                                                                        pLib->buffer)) {
 677                        return (-1);
 678                }
 679                pLib->l2_trace = 1;
 680                pLib->req_busy = 1;
 681                return (0);
 682        }
 683
 684        for (i = 0; i < 30; i++) {
 685                if (pLib->pending_line_status & (1L << i)) {
 686                        sprintf (name, "State\\B%d", i+1);
 687                        if (SuperTraceReadRequest (pLib->hAdapter, name, pLib->buffer)) {
 688                                return (-1);
 689                        }
 690                        pLib->pending_line_status &= ~(1L << i);
 691                        pLib->req_busy = 1;
 692                        return (0);
 693                }
 694                if (pLib->pending_modem_status & (1L << i)) {
 695                        sprintf (name, "State\\B%d\\Modem", i+1);
 696                        if (SuperTraceReadRequest (pLib->hAdapter, name, pLib->buffer)) {
 697                                return (-1);
 698                        }
 699                        pLib->pending_modem_status &= ~(1L << i);
 700                        pLib->req_busy = 1;
 701                        return (0);
 702                }
 703                if (pLib->pending_fax_status & (1L << i)) {
 704                        sprintf (name, "State\\B%d\\FAX", i+1);
 705                        if (SuperTraceReadRequest (pLib->hAdapter, name, pLib->buffer)) {
 706                                return (-1);
 707                        }
 708                        pLib->pending_fax_status &= ~(1L << i);
 709                        pLib->req_busy = 1;
 710                        return (0);
 711                }
 712                if (pLib->clear_call_command & (1L << i)) {
 713                        sprintf (name, "State\\B%d\\Clear Call", i+1);
 714                        if (SuperTraceExecuteRequest (pLib->hAdapter, name, pLib->buffer)) {
 715                                return (-1);
 716                        }
 717                        pLib->clear_call_command &= ~(1L << i);
 718                        pLib->req_busy = 1;
 719                        return (0);
 720                }
 721        }
 722
 723        if (pLib->outgoing_ifc_stats) {
 724                if (SuperTraceReadRequest (pLib->hAdapter,
 725                                                                                                                         "Statistics\\Outgoing Calls",
 726                                                                                                                         pLib->buffer)) {
 727                        return (-1);
 728                }
 729                pLib->outgoing_ifc_stats = 0;
 730                pLib->req_busy = 1;
 731                return (0);
 732        }
 733
 734        if (pLib->incoming_ifc_stats) {
 735                if (SuperTraceReadRequest (pLib->hAdapter,
 736                                                                                                                         "Statistics\\Incoming Calls",
 737                                                                                                                         pLib->buffer)) {
 738                        return (-1);
 739                }
 740                pLib->incoming_ifc_stats = 0;
 741                pLib->req_busy = 1;
 742                return (0);
 743        }
 744
 745        if (pLib->modem_ifc_stats) {
 746                if (SuperTraceReadRequest (pLib->hAdapter,
 747                                                                                                                         "Statistics\\Modem",
 748                                                                                                                         pLib->buffer)) {
 749                        return (-1);
 750                }
 751                pLib->modem_ifc_stats = 0;
 752                pLib->req_busy = 1;
 753                return (0);
 754        }
 755
 756        if (pLib->fax_ifc_stats) {
 757                if (SuperTraceReadRequest (pLib->hAdapter,
 758                                                                                                                         "Statistics\\FAX",
 759                                                                                                                         pLib->buffer)) {
 760                        return (-1);
 761                }
 762                pLib->fax_ifc_stats = 0;
 763                pLib->req_busy = 1;
 764                return (0);
 765        }
 766
 767        if (pLib->b1_ifc_stats) {
 768                if (SuperTraceReadRequest (pLib->hAdapter,
 769                                                                                                                         "Statistics\\B-Layer1",
 770                                                                                                                         pLib->buffer)) {
 771                        return (-1);
 772                }
 773                pLib->b1_ifc_stats = 0;
 774                pLib->req_busy = 1;
 775                return (0);
 776        }
 777
 778        if (pLib->b2_ifc_stats) {
 779                if (SuperTraceReadRequest (pLib->hAdapter,
 780                                                                                                                         "Statistics\\B-Layer2",
 781                                                                                                                         pLib->buffer)) {
 782                        return (-1);
 783                }
 784                pLib->b2_ifc_stats = 0;
 785                pLib->req_busy = 1;
 786                return (0);
 787        }
 788
 789        if (pLib->d1_ifc_stats) {
 790                if (SuperTraceReadRequest (pLib->hAdapter,
 791                                                                                                                         "Statistics\\D-Layer1",
 792                                                                                                                         pLib->buffer)) {
 793                        return (-1);
 794                }
 795                pLib->d1_ifc_stats = 0;
 796                pLib->req_busy = 1;
 797                return (0);
 798        }
 799
 800        if (pLib->d2_ifc_stats) {
 801                if (SuperTraceReadRequest (pLib->hAdapter,
 802                                                                                                                         "Statistics\\D-Layer2",
 803                                                                                                                         pLib->buffer)) {
 804                        return (-1);
 805                }
 806                pLib->d2_ifc_stats = 0;
 807                pLib->req_busy = 1;
 808                return (0);
 809        }
 810
 811        if (!pLib->IncomingCallsCallsActive) {
 812                pLib->IncomingCallsCallsActive = 1;
 813                sprintf (name, "%s", "Statistics\\Incoming Calls\\Calls");
 814                if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 815                        pLib->IncomingCallsCallsActive = 0;
 816                        return (-1);
 817                }
 818                pLib->req_busy = 1;
 819                return (0);
 820        }
 821        if (!pLib->IncomingCallsConnectedActive) {
 822                pLib->IncomingCallsConnectedActive = 1;
 823                sprintf (name, "%s", "Statistics\\Incoming Calls\\Connected");
 824                if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 825                        pLib->IncomingCallsConnectedActive = 0;
 826                        return (-1);
 827                }
 828                pLib->req_busy = 1;
 829                return (0);
 830        }
 831        if (!pLib->OutgoingCallsCallsActive) {
 832                pLib->OutgoingCallsCallsActive = 1;
 833                sprintf (name, "%s", "Statistics\\Outgoing Calls\\Calls");
 834                if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 835                        pLib->OutgoingCallsCallsActive = 0;
 836                        return (-1);
 837                }
 838                pLib->req_busy = 1;
 839                return (0);
 840        }
 841        if (!pLib->OutgoingCallsConnectedActive) {
 842                pLib->OutgoingCallsConnectedActive = 1;
 843                sprintf (name, "%s", "Statistics\\Outgoing Calls\\Connected");
 844                if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 845                        pLib->OutgoingCallsConnectedActive = 0;
 846                        return (-1);
 847                }
 848                pLib->req_busy = 1;
 849                return (0);
 850        }
 851
 852        return (0);
 853}
 854
 855static int process_idi_event (diva_strace_context_t* pLib,
 856                                diva_man_var_header_t* pVar) {
 857        const char* path = (char*)&pVar->path_length+1;
 858        char name[64];
 859        int i;
 860
 861        if (!strncmp("State\\B Event", path, pVar->path_length)) {
 862    dword ch_id;
 863    if (!diva_trace_read_variable (pVar, &ch_id)) {
 864      if (!pLib->line_init_event && !pLib->pending_line_status) {
 865        for (i = 1; i <= pLib->Channels; i++) {
 866          diva_line_event(pLib, i);
 867        }
 868        return (0);
 869      } else if (ch_id && ch_id <= pLib->Channels) {
 870        return (diva_line_event(pLib, (int)ch_id));
 871      }
 872      return (0);
 873    }
 874    return (-1);
 875  }
 876
 877        if (!strncmp("State\\FAX Event", path, pVar->path_length)) {
 878    dword ch_id;
 879    if (!diva_trace_read_variable (pVar, &ch_id)) {
 880      if (!pLib->pending_fax_status && !pLib->fax_init_event) {
 881        for (i = 1; i <= pLib->Channels; i++) {
 882          diva_fax_event(pLib, i);
 883        }
 884        return (0);
 885      } else if (ch_id && ch_id <= pLib->Channels) {
 886        return (diva_fax_event(pLib, (int)ch_id));
 887      }
 888      return (0);
 889    }
 890    return (-1);
 891  }
 892
 893        if (!strncmp("State\\Modem Event", path, pVar->path_length)) {
 894    dword ch_id;
 895    if (!diva_trace_read_variable (pVar, &ch_id)) {
 896      if (!pLib->pending_modem_status && !pLib->modem_init_event) {
 897        for (i = 1; i <= pLib->Channels; i++) {
 898          diva_modem_event(pLib, i);
 899        }
 900        return (0);
 901      } else if (ch_id && ch_id <= pLib->Channels) {
 902        return (diva_modem_event(pLib, (int)ch_id));
 903      }
 904      return (0);
 905    }
 906    return (-1);
 907  }
 908
 909        /*
 910                First look for Line Event
 911                */
 912        for (i = 1; i <= pLib->Channels; i++) {
 913                sprintf (name, "State\\B%d\\Line", i);
 914                if (find_var (pVar, name)) {
 915                        return (diva_line_event(pLib, i));
 916                }
 917        }
 918
 919        /*
 920                Look for Moden Progress Event
 921                */
 922        for (i = 1; i <= pLib->Channels; i++) {
 923                sprintf (name, "State\\B%d\\Modem\\Event", i);
 924                if (find_var (pVar, name)) {
 925                        return (diva_modem_event (pLib, i));
 926                }
 927        }
 928
 929        /*
 930                Look for Fax Event
 931                */
 932        for (i = 1; i <= pLib->Channels; i++) {
 933                sprintf (name, "State\\B%d\\FAX\\Event", i);
 934                if (find_var (pVar, name)) {
 935                        return (diva_fax_event (pLib, i));
 936                }
 937        }
 938
 939        /*
 940                Notification about loss of events
 941                */
 942        if (!strncmp("Events Down", path, pVar->path_length)) {
 943                if (pLib->trace_events_down == 1) {
 944                        pLib->trace_events_down = 2;
 945                } else {
 946                        diva_trace_error (pLib, 1, "Events Down", 0);
 947                }
 948                return (0);
 949        }
 950
 951        if (!strncmp("State\\Layer1", path, pVar->path_length)) {
 952                diva_strace_read_asz  (pVar, &pLib->lines[0].pInterface->Layer1[0]);
 953                if (pLib->l1_trace == 1) {
 954                        pLib->l1_trace = 2;
 955                } else {
 956                        diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
 957                }
 958                return (0);
 959        }
 960        if (!strncmp("State\\Layer2 No1", path, pVar->path_length)) {
 961                char* tmp = &pLib->lines[0].pInterface->Layer2[0];
 962    dword l2_state;
 963    diva_strace_read_uint (pVar, &l2_state);
 964
 965                switch (l2_state) {
 966                        case 0:
 967                                strcpy (tmp, "Idle");
 968                                break;
 969                        case 1:
 970                                strcpy (tmp, "Layer2 UP");
 971                                break;
 972                        case 2:
 973                                strcpy (tmp, "Layer2 Disconnecting");
 974                                break;
 975                        case 3:
 976                                strcpy (tmp, "Layer2 Connecting");
 977                                break;
 978                        case 4:
 979                                strcpy (tmp, "SPID Initializing");
 980                                break;
 981                        case 5:
 982                                strcpy (tmp, "SPID Initialised");
 983                                break;
 984                        case 6:
 985                                strcpy (tmp, "Layer2 Connecting");
 986                                break;
 987
 988                        case  7:
 989                                strcpy (tmp, "Auto SPID Stopped");
 990                                break;
 991
 992                        case  8:
 993                                strcpy (tmp, "Auto SPID Idle");
 994                                break;
 995
 996                        case  9:
 997                                strcpy (tmp, "Auto SPID Requested");
 998                                break;
 999
1000                        case  10:
1001                                strcpy (tmp, "Auto SPID Delivery");
1002                                break;
1003
1004                        case 11:
1005                                strcpy (tmp, "Auto SPID Complete");
1006                                break;
1007
1008                        default:
1009                                sprintf (tmp, "U:%d", (int)l2_state);
1010                }
1011                if (pLib->l2_trace == 1) {
1012                        pLib->l2_trace = 2;
1013                } else {
1014                        diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
1015                }
1016                return (0);
1017        }
1018
1019        if (!strncmp("Statistics\\Incoming Calls\\Calls", path, pVar->path_length) ||
1020                        !strncmp("Statistics\\Incoming Calls\\Connected", path, pVar->path_length)) {
1021                return (SuperTraceGetIncomingCallStatistics (pLib));
1022        }
1023
1024        if (!strncmp("Statistics\\Outgoing Calls\\Calls", path, pVar->path_length) ||
1025                        !strncmp("Statistics\\Outgoing Calls\\Connected", path, pVar->path_length)) {
1026                return (SuperTraceGetOutgoingCallStatistics (pLib));
1027        }
1028
1029        return (-1);
1030}
1031
1032static int diva_line_event (diva_strace_context_t* pLib, int Channel) {
1033        pLib->pending_line_status |= (1L << (Channel-1));
1034        return (0);
1035}
1036
1037static int diva_modem_event (diva_strace_context_t* pLib, int Channel) {
1038        pLib->pending_modem_status |= (1L << (Channel-1));
1039        return (0);
1040}
1041
1042static int diva_fax_event (diva_strace_context_t* pLib, int Channel) {
1043        pLib->pending_fax_status |= (1L << (Channel-1));
1044        return (0);
1045}
1046
1047/*
1048        Process INFO indications that arrive from the card
1049        Uses path of first I.E. to detect the source of the
1050        infication
1051        */
1052static int process_idi_info  (diva_strace_context_t* pLib,
1053                                                                                                                        diva_man_var_header_t* pVar) {
1054        const char* path = (char*)&pVar->path_length+1;
1055        char name[64];
1056        int i, len;
1057
1058        /*
1059                First look for Modem Status Info
1060                */
1061        for (i = pLib->Channels; i > 0; i--) {
1062                len = sprintf (name, "State\\B%d\\Modem", i);
1063                if (!strncmp(name, path, len)) {
1064                        return (diva_modem_info (pLib, i, pVar));
1065                }
1066        }
1067
1068        /*
1069                Look for Fax Status Info
1070                */
1071        for (i = pLib->Channels; i > 0; i--) {
1072                len = sprintf (name, "State\\B%d\\FAX", i);
1073                if (!strncmp(name, path, len)) {
1074                        return (diva_fax_info (pLib, i, pVar));
1075                }
1076        }
1077
1078        /*
1079                Look for Line Status Info
1080                */
1081        for (i = pLib->Channels; i > 0; i--) {
1082                len = sprintf (name, "State\\B%d", i);
1083                if (!strncmp(name, path, len)) {
1084                        return (diva_line_info (pLib, i, pVar));
1085                }
1086        }
1087
1088        if (!diva_ifc_statistics (pLib, pVar)) {
1089                return (0);
1090        }
1091
1092        return (-1);
1093}
1094
1095/*
1096        MODEM INSTANCE STATE UPDATE
1097
1098        Update Modem Status Information and issue notification to user,
1099        that will inform about change in the state of modem instance, that is
1100        associuated with this channel
1101        */
1102static int diva_modem_info (diva_strace_context_t* pLib,
1103                                                                                                                int Channel,
1104                                                                                                                diva_man_var_header_t* pVar) {
1105        diva_man_var_header_t* cur;
1106        int i, nr = Channel - 1;
1107
1108        for (i  = pLib->modem_parse_entry_first[nr];
1109                         i <= pLib->modem_parse_entry_last[nr]; i++) {
1110                if ((cur = find_var (pVar, pLib->parse_table[i].path))) {
1111                        if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) {
1112                                diva_trace_error (pLib, -3 , __FILE__, __LINE__);
1113                                return (-1);
1114                        }
1115                } else {
1116                        diva_trace_error (pLib, -2 , __FILE__, __LINE__);
1117                        return (-1);
1118                }
1119        }
1120
1121        /*
1122                We do not use first event to notify user - this is the event that is
1123                generated as result of EVENT ON operation and is used only to initialize
1124                internal variables of application
1125                */
1126        if (pLib->modem_init_event & (1L << nr)) {
1127                diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE);
1128        } else {
1129                pLib->modem_init_event |= (1L << nr);
1130        }
1131
1132        return (0);
1133}
1134
1135static int diva_fax_info (diva_strace_context_t* pLib,
1136                                                                                                        int Channel,
1137                                                                                                        diva_man_var_header_t* pVar) {
1138        diva_man_var_header_t* cur;
1139        int i, nr = Channel - 1;
1140
1141        for (i  = pLib->fax_parse_entry_first[nr];
1142                         i <= pLib->fax_parse_entry_last[nr]; i++) {
1143                if ((cur = find_var (pVar, pLib->parse_table[i].path))) {
1144                        if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) {
1145                                diva_trace_error (pLib, -3 , __FILE__, __LINE__);
1146                                return (-1);
1147                        }
1148                } else {
1149                        diva_trace_error (pLib, -2 , __FILE__, __LINE__);
1150                        return (-1);
1151                }
1152        }
1153
1154        /*
1155                We do not use first event to notify user - this is the event that is
1156                generated as result of EVENT ON operation and is used only to initialize
1157                internal variables of application
1158                */
1159        if (pLib->fax_init_event & (1L << nr)) {
1160                diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE);
1161        } else {
1162                pLib->fax_init_event |= (1L << nr);
1163        }
1164
1165        return (0);
1166}
1167
1168/*
1169        LINE STATE UPDATE
1170        Update Line Status Information and issue notification to user,
1171        that will inform about change in the line state.
1172        */
1173static int diva_line_info  (diva_strace_context_t* pLib,
1174                                                                                                                int Channel,
1175                                                                                                                diva_man_var_header_t* pVar) {
1176        diva_man_var_header_t* cur;
1177        int i, nr = Channel - 1;
1178
1179        for (i  = pLib->line_parse_entry_first[nr];
1180                         i <= pLib->line_parse_entry_last[nr]; i++) {
1181                if ((cur = find_var (pVar, pLib->parse_table[i].path))) {
1182                        if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) {
1183                                diva_trace_error (pLib, -3 , __FILE__, __LINE__);
1184                                return (-1);
1185                        }
1186                } else {
1187                        diva_trace_error (pLib, -2 , __FILE__, __LINE__);
1188                        return (-1);
1189                }
1190        }
1191
1192        /*
1193                We do not use first event to notify user - this is the event that is
1194                generated as result of EVENT ON operation and is used only to initialize
1195                internal variables of application
1196
1197                Exception is is if the line is "online". In this case we have to notify
1198                user about this confition.
1199                */
1200        if (pLib->line_init_event & (1L << nr)) {
1201                diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
1202        } else {
1203                pLib->line_init_event |= (1L << nr);
1204                if (strcmp (&pLib->lines[nr].Line[0], "Idle")) {
1205                        diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
1206                }
1207        }
1208
1209        return (0);
1210}
1211
1212/*
1213        Move position to next vatianle in the chain
1214        */
1215static diva_man_var_header_t* get_next_var (diva_man_var_header_t* pVar) {
1216        byte* msg   = (byte*)pVar;
1217        byte* start;
1218        int msg_length;
1219
1220        if (*msg != ESC) return NULL;
1221
1222        start = msg + 2;
1223        msg_length = *(msg+1);
1224        msg = (start+msg_length);
1225
1226        if (*msg != ESC) return NULL;
1227
1228        return ((diva_man_var_header_t*)msg);
1229}
1230
1231/*
1232        Move position to variable with given name
1233        */
1234static diva_man_var_header_t* find_var (diva_man_var_header_t* pVar,
1235                                                                                                                                                                const char* name) {
1236        const char* path;
1237
1238        do {
1239                path = (char*)&pVar->path_length+1;
1240
1241                if (!strncmp (name, path, pVar->path_length)) {
1242                        break;
1243                }
1244        } while ((pVar = get_next_var (pVar)));
1245
1246        return (pVar);
1247}
1248
1249static void diva_create_line_parse_table  (diva_strace_context_t* pLib,
1250                                                                                                                                                                         int Channel) {
1251        diva_trace_line_state_t* pLine = &pLib->lines[Channel];
1252        int nr = Channel+1;
1253
1254        if ((pLib->cur_parse_entry + LINE_PARSE_ENTRIES) >= pLib->parse_entries) {
1255                diva_trace_error (pLib, -1, __FILE__, __LINE__);
1256                return;
1257        }
1258
1259        pLine->ChannelNumber = nr;
1260
1261        pLib->line_parse_entry_first[Channel] = pLib->cur_parse_entry;
1262
1263        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1264                                         "State\\B%d\\Framing", nr);
1265        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Framing[0];
1266
1267        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1268                                         "State\\B%d\\Line", nr);
1269        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Line[0];
1270
1271        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1272                                         "State\\B%d\\Layer2", nr);
1273        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer2[0];
1274
1275        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1276                                         "State\\B%d\\Layer3", nr);
1277        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer3[0];
1278
1279        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1280                                         "State\\B%d\\Remote Address", nr);
1281        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1282                                                                                                                                                                                                &pLine->RemoteAddress[0];
1283
1284        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1285                                         "State\\B%d\\Remote SubAddr", nr);
1286        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1287                                                                                                                                                                                                &pLine->RemoteSubAddress[0];
1288
1289        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1290                                         "State\\B%d\\Local Address", nr);
1291        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1292                                                                                                                                                                                                &pLine->LocalAddress[0];
1293
1294        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1295                                         "State\\B%d\\Local SubAddr", nr);
1296        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1297                                                                                                                                                                                                &pLine->LocalSubAddress[0];
1298
1299        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1300                                         "State\\B%d\\BC", nr);
1301        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_BC;
1302
1303        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1304                                         "State\\B%d\\HLC", nr);
1305        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_HLC;
1306
1307        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1308                                         "State\\B%d\\LLC", nr);
1309        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_LLC;
1310
1311        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1312                                         "State\\B%d\\Charges", nr);
1313        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Charges;
1314
1315        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1316                                         "State\\B%d\\Call Reference", nr);
1317        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->CallReference;
1318
1319        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1320                                         "State\\B%d\\Last Disc Cause", nr);
1321        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1322                                                                                                                                                                                                                &pLine->LastDisconnecCause;
1323
1324        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1325                                         "State\\B%d\\User ID", nr);
1326        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->UserID[0];
1327
1328        pLib->line_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1329}
1330
1331static void diva_create_fax_parse_table (diva_strace_context_t* pLib,
1332                                                                                                                                                                 int Channel) {
1333        diva_trace_fax_state_t* pFax = &pLib->lines[Channel].fax;
1334        int nr = Channel+1;
1335
1336        if ((pLib->cur_parse_entry + FAX_PARSE_ENTRIES) >= pLib->parse_entries) {
1337                diva_trace_error (pLib, -1, __FILE__, __LINE__);
1338                return;
1339        }
1340        pFax->ChannelNumber = nr;
1341
1342        pLib->fax_parse_entry_first[Channel] = pLib->cur_parse_entry;
1343
1344        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1345                                         "State\\B%d\\FAX\\Event", nr);
1346        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Event;
1347
1348        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1349                                         "State\\B%d\\FAX\\Page Counter", nr);
1350        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Page_Counter;
1351
1352        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1353                                         "State\\B%d\\FAX\\Features", nr);
1354        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Features;
1355
1356        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1357                                         "State\\B%d\\FAX\\Station ID", nr);
1358        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Station_ID[0];
1359
1360        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1361                                         "State\\B%d\\FAX\\Subaddress", nr);
1362        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Subaddress[0];
1363
1364        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1365                                         "State\\B%d\\FAX\\Password", nr);
1366        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Password[0];
1367
1368        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1369                                         "State\\B%d\\FAX\\Speed", nr);
1370        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Speed;
1371
1372        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1373                                         "State\\B%d\\FAX\\Resolution", nr);
1374        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Resolution;
1375
1376        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1377                                         "State\\B%d\\FAX\\Paper Width", nr);
1378        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Width;
1379
1380        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1381                                         "State\\B%d\\FAX\\Paper Length", nr);
1382        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Length;
1383
1384        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1385                                         "State\\B%d\\FAX\\Scanline Time", nr);
1386        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Scanline_Time;
1387
1388        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1389                                         "State\\B%d\\FAX\\Disc Reason", nr);
1390        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Disc_Reason;
1391
1392        pLib->fax_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1393}
1394
1395static void diva_create_modem_parse_table (diva_strace_context_t* pLib,
1396                                                                                                                                                                         int Channel) {
1397        diva_trace_modem_state_t* pModem = &pLib->lines[Channel].modem;
1398        int nr = Channel+1;
1399
1400        if ((pLib->cur_parse_entry + MODEM_PARSE_ENTRIES) >= pLib->parse_entries) {
1401                diva_trace_error (pLib, -1, __FILE__, __LINE__);
1402                return;
1403        }
1404        pModem->ChannelNumber = nr;
1405
1406        pLib->modem_parse_entry_first[Channel] = pLib->cur_parse_entry;
1407
1408        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1409                                         "State\\B%d\\Modem\\Event", nr);
1410        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Event;
1411
1412        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1413                                         "State\\B%d\\Modem\\Norm", nr);
1414        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Norm;
1415
1416        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1417                                         "State\\B%d\\Modem\\Options", nr);
1418        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Options;
1419
1420        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1421                                         "State\\B%d\\Modem\\TX Speed", nr);
1422        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->TxSpeed;
1423
1424        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1425                                         "State\\B%d\\Modem\\RX Speed", nr);
1426        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxSpeed;
1427
1428        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1429                                         "State\\B%d\\Modem\\Roundtrip ms", nr);
1430        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RoundtripMsec;
1431
1432        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1433                                         "State\\B%d\\Modem\\Symbol Rate", nr);
1434        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SymbolRate;
1435
1436        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1437                                         "State\\B%d\\Modem\\RX Level dBm", nr);
1438        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxLeveldBm;
1439
1440        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1441                                         "State\\B%d\\Modem\\Echo Level dBm", nr);
1442        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->EchoLeveldBm;
1443
1444        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1445                                         "State\\B%d\\Modem\\SNR dB", nr);
1446        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SNRdb;
1447
1448        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1449                                         "State\\B%d\\Modem\\MAE", nr);
1450        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->MAE;
1451
1452        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1453                                         "State\\B%d\\Modem\\Local Retrains", nr);
1454        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalRetrains;
1455
1456        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1457                                         "State\\B%d\\Modem\\Remote Retrains", nr);
1458        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteRetrains;
1459
1460        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1461                                         "State\\B%d\\Modem\\Local Resyncs", nr);
1462        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalResyncs;
1463
1464        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1465                                         "State\\B%d\\Modem\\Remote Resyncs", nr);
1466        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteResyncs;
1467
1468        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1469                                         "State\\B%d\\Modem\\Disc Reason", nr);
1470        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->DiscReason;
1471
1472        pLib->modem_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1473}
1474
1475static void diva_create_parse_table (diva_strace_context_t* pLib) {
1476        int i;
1477
1478        for (i = 0; i < pLib->Channels; i++) {
1479                diva_create_line_parse_table  (pLib, i);
1480                diva_create_modem_parse_table (pLib, i);
1481                diva_create_fax_parse_table   (pLib, i);
1482        }
1483
1484        pLib->statistic_parse_first = pLib->cur_parse_entry;
1485
1486        /*
1487                Outgoing Calls
1488                */
1489        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1490                                        "Statistics\\Outgoing Calls\\Calls");
1491        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1492                                                                                                                                                &pLib->InterfaceStat.outg.Calls;
1493
1494        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1495                                        "Statistics\\Outgoing Calls\\Connected");
1496        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1497                                                                                                                                                &pLib->InterfaceStat.outg.Connected;
1498
1499        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1500                                        "Statistics\\Outgoing Calls\\User Busy");
1501        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1502                                                                                                                                                &pLib->InterfaceStat.outg.User_Busy;
1503
1504        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1505                                        "Statistics\\Outgoing Calls\\No Answer");
1506        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1507                                                                                                                                                &pLib->InterfaceStat.outg.No_Answer;
1508
1509        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1510                                        "Statistics\\Outgoing Calls\\Wrong Number");
1511        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1512                                                                                                                                                &pLib->InterfaceStat.outg.Wrong_Number;
1513
1514        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1515                                        "Statistics\\Outgoing Calls\\Call Rejected");
1516        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1517                                                                                                                                                &pLib->InterfaceStat.outg.Call_Rejected;
1518
1519        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1520                                        "Statistics\\Outgoing Calls\\Other Failures");
1521        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1522                                                                                                                                                &pLib->InterfaceStat.outg.Other_Failures;
1523
1524        /*
1525                Incoming Calls
1526                */
1527        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1528                                        "Statistics\\Incoming Calls\\Calls");
1529        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1530                                                                                                                                                &pLib->InterfaceStat.inc.Calls;
1531
1532        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1533                                        "Statistics\\Incoming Calls\\Connected");
1534        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1535                                                                                                                                                &pLib->InterfaceStat.inc.Connected;
1536
1537        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1538                                        "Statistics\\Incoming Calls\\User Busy");
1539        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1540                                                                                                                                                &pLib->InterfaceStat.inc.User_Busy;
1541
1542        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1543                                        "Statistics\\Incoming Calls\\Call Rejected");
1544        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1545                                                                                                                                                &pLib->InterfaceStat.inc.Call_Rejected;
1546
1547        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1548                                        "Statistics\\Incoming Calls\\Wrong Number");
1549        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1550                                                                                                                                                &pLib->InterfaceStat.inc.Wrong_Number;
1551
1552        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1553                                        "Statistics\\Incoming Calls\\Incompatible Dst");
1554        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1555                                                                                                                                                &pLib->InterfaceStat.inc.Incompatible_Dst;
1556
1557        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1558                                        "Statistics\\Incoming Calls\\Out of Order");
1559        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1560                                                                                                                                                &pLib->InterfaceStat.inc.Out_of_Order;
1561
1562        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1563                                        "Statistics\\Incoming Calls\\Ignored");
1564        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1565                                                                                                                                                &pLib->InterfaceStat.inc.Ignored;
1566
1567        /*
1568                Modem Statistics
1569                */
1570        pLib->mdm_statistic_parse_first = pLib->cur_parse_entry;
1571
1572        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1573                                        "Statistics\\Modem\\Disc Normal");
1574        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1575                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Normal;
1576
1577        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1578                                        "Statistics\\Modem\\Disc Unspecified");
1579        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1580                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Unspecified;
1581
1582        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1583                                        "Statistics\\Modem\\Disc Busy Tone");
1584        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1585                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Busy_Tone;
1586
1587        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1588                                        "Statistics\\Modem\\Disc Congestion");
1589        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1590                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Congestion;
1591
1592        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1593                                        "Statistics\\Modem\\Disc Carr. Wait");
1594        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1595                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Carr_Wait;
1596
1597        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1598                                        "Statistics\\Modem\\Disc Trn Timeout");
1599        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1600                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Trn_Timeout;
1601
1602        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1603                                        "Statistics\\Modem\\Disc Incompat.");
1604        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1605                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Incompat;
1606
1607        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1608                                        "Statistics\\Modem\\Disc Frame Rej.");
1609        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1610                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Frame_Rej;
1611
1612        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1613                                        "Statistics\\Modem\\Disc V42bis");
1614        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1615                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_V42bis;
1616
1617        pLib->mdm_statistic_parse_last  = pLib->cur_parse_entry - 1;
1618
1619        /*
1620                Fax Statistics
1621                */
1622        pLib->fax_statistic_parse_first = pLib->cur_parse_entry;
1623
1624        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1625                                        "Statistics\\FAX\\Disc Normal");
1626        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1627                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Normal;
1628
1629        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1630                                        "Statistics\\FAX\\Disc Not Ident.");
1631        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1632                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Not_Ident;
1633
1634        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1635                                        "Statistics\\FAX\\Disc No Response");
1636        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1637                                                                                                                                                &pLib->InterfaceStat.fax.Disc_No_Response;
1638
1639        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1640                                        "Statistics\\FAX\\Disc Retries");
1641        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1642                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Retries;
1643
1644        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1645                                        "Statistics\\FAX\\Disc Unexp. Msg.");
1646        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1647                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Unexp_Msg;
1648
1649        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1650                                        "Statistics\\FAX\\Disc No Polling.");
1651        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1652                                                                                                                                                &pLib->InterfaceStat.fax.Disc_No_Polling;
1653
1654        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1655                                        "Statistics\\FAX\\Disc Training");
1656        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1657                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Training;
1658
1659        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1660                                        "Statistics\\FAX\\Disc Unexpected");
1661        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1662                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Unexpected;
1663
1664        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1665                                        "Statistics\\FAX\\Disc Application");
1666        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1667                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Application;
1668
1669        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1670                                        "Statistics\\FAX\\Disc Incompat.");
1671        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1672                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Incompat;
1673
1674        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1675                                        "Statistics\\FAX\\Disc No Command");
1676        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1677                                                                                                                                                &pLib->InterfaceStat.fax.Disc_No_Command;
1678
1679        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1680                                        "Statistics\\FAX\\Disc Long Msg");
1681        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1682                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Long_Msg;
1683
1684        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1685                                        "Statistics\\FAX\\Disc Supervisor");
1686        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1687                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Supervisor;
1688
1689        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1690                                        "Statistics\\FAX\\Disc SUB SEP PWD");
1691        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1692                                                                                                                                                &pLib->InterfaceStat.fax.Disc_SUB_SEP_PWD;
1693
1694        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1695                                        "Statistics\\FAX\\Disc Invalid Msg");
1696        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1697                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Invalid_Msg;
1698
1699        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1700                                        "Statistics\\FAX\\Disc Page Coding");
1701        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1702                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Page_Coding;
1703
1704        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1705                                        "Statistics\\FAX\\Disc App Timeout");
1706        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1707                                                                                                                                                &pLib->InterfaceStat.fax.Disc_App_Timeout;
1708
1709        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1710                                        "Statistics\\FAX\\Disc Unspecified");
1711        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1712                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Unspecified;
1713
1714        pLib->fax_statistic_parse_last  = pLib->cur_parse_entry - 1;
1715
1716        /*
1717                B-Layer1"
1718                */
1719        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1720                                        "Statistics\\B-Layer1\\X-Frames");
1721        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1722                                                                                                                                                &pLib->InterfaceStat.b1.X_Frames;
1723
1724        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1725                                        "Statistics\\B-Layer1\\X-Bytes");
1726        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1727                                                                                                                                                &pLib->InterfaceStat.b1.X_Bytes;
1728
1729        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1730                                        "Statistics\\B-Layer1\\X-Errors");
1731        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1732                                                                                                                                                &pLib->InterfaceStat.b1.X_Errors;
1733
1734        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1735                                        "Statistics\\B-Layer1\\R-Frames");
1736        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1737                                                                                                                                                &pLib->InterfaceStat.b1.R_Frames;
1738
1739        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1740                                        "Statistics\\B-Layer1\\R-Bytes");
1741        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1742                                                                                                                                                &pLib->InterfaceStat.b1.R_Bytes;
1743
1744        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1745                                        "Statistics\\B-Layer1\\R-Errors");
1746        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1747                                                                                                                                                &pLib->InterfaceStat.b1.R_Errors;
1748
1749        /*
1750                B-Layer2
1751                */
1752        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1753                                        "Statistics\\B-Layer2\\X-Frames");
1754        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1755                                                                                                                                                &pLib->InterfaceStat.b2.X_Frames;
1756
1757        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1758                                        "Statistics\\B-Layer2\\X-Bytes");
1759        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1760                                                                                                                                                &pLib->InterfaceStat.b2.X_Bytes;
1761
1762        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1763                                        "Statistics\\B-Layer2\\X-Errors");
1764        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1765                                                                                                                                                &pLib->InterfaceStat.b2.X_Errors;
1766
1767        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1768                                        "Statistics\\B-Layer2\\R-Frames");
1769        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1770                                                                                                                                                &pLib->InterfaceStat.b2.R_Frames;
1771
1772        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1773                                        "Statistics\\B-Layer2\\R-Bytes");
1774        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1775                                                                                                                                                &pLib->InterfaceStat.b2.R_Bytes;
1776
1777        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1778                                        "Statistics\\B-Layer2\\R-Errors");
1779        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1780                                                                                                                                                &pLib->InterfaceStat.b2.R_Errors;
1781
1782        /*
1783                D-Layer1
1784                */
1785        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1786                                        "Statistics\\D-Layer1\\X-Frames");
1787        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1788                                                                                                                                                &pLib->InterfaceStat.d1.X_Frames;
1789
1790        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1791                                        "Statistics\\D-Layer1\\X-Bytes");
1792        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1793                                                                                                                                                &pLib->InterfaceStat.d1.X_Bytes;
1794
1795        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1796                                        "Statistics\\D-Layer1\\X-Errors");
1797        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1798                                                                                                                                                &pLib->InterfaceStat.d1.X_Errors;
1799
1800        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1801                                        "Statistics\\D-Layer1\\R-Frames");
1802        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1803                                                                                                                                                &pLib->InterfaceStat.d1.R_Frames;
1804
1805        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1806                                        "Statistics\\D-Layer1\\R-Bytes");
1807        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1808                                                                                                                                                &pLib->InterfaceStat.d1.R_Bytes;
1809
1810        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1811                                        "Statistics\\D-Layer1\\R-Errors");
1812        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1813                                                                                                                                                &pLib->InterfaceStat.d1.R_Errors;
1814
1815        /*
1816                D-Layer2
1817                */
1818        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1819                                        "Statistics\\D-Layer2\\X-Frames");
1820        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1821                                                                                                                                                &pLib->InterfaceStat.d2.X_Frames;
1822
1823        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1824                                        "Statistics\\D-Layer2\\X-Bytes");
1825        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1826                                                                                                                                                &pLib->InterfaceStat.d2.X_Bytes;
1827
1828        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1829                                        "Statistics\\D-Layer2\\X-Errors");
1830        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1831                                                                                                                                                &pLib->InterfaceStat.d2.X_Errors;
1832
1833        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1834                                        "Statistics\\D-Layer2\\R-Frames");
1835        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1836                                                                                                                                                &pLib->InterfaceStat.d2.R_Frames;
1837
1838        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1839                                        "Statistics\\D-Layer2\\R-Bytes");
1840        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1841                                                                                                                                                &pLib->InterfaceStat.d2.R_Bytes;
1842
1843        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1844                                        "Statistics\\D-Layer2\\R-Errors");
1845        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1846                                                                                                                                                &pLib->InterfaceStat.d2.R_Errors;
1847
1848
1849        pLib->statistic_parse_last  = pLib->cur_parse_entry - 1;
1850}
1851
1852static void diva_trace_error (diva_strace_context_t* pLib,
1853                                                                                                                        int error, const char* file, int line) {
1854        if (pLib->user_proc_table.error_notify_proc) {
1855                (*(pLib->user_proc_table.error_notify_proc))(\
1856                                                                                                                                                                                pLib->user_proc_table.user_context,
1857                                                                                                                                                                                &pLib->instance, pLib->Adapter,
1858                                                                                                                                                                                error, file, line);
1859        }
1860}
1861
1862/*
1863        Delivery notification to user
1864        */
1865static void diva_trace_notify_user (diva_strace_context_t* pLib,
1866                                                                                                                 int Channel,
1867                                                                                                                 int notify_subject) {
1868        if (pLib->user_proc_table.notify_proc) {
1869                (*(pLib->user_proc_table.notify_proc))(pLib->user_proc_table.user_context,
1870                                                                                                                                                                         &pLib->instance,
1871                                                                                                                                                                         pLib->Adapter,
1872                                                                                                                                                                         &pLib->lines[Channel],
1873                                                                                                                                                                         notify_subject);
1874        }
1875}
1876
1877/*
1878        Read variable value to they destination based on the variable type
1879        */
1880static int diva_trace_read_variable (diva_man_var_header_t* pVar,
1881                                                                                                                                                 void* variable) {
1882        switch (pVar->type) {
1883                case 0x03: /* MI_ASCIIZ - syting                               */
1884                        return (diva_strace_read_asz  (pVar, (char*)variable));
1885                case 0x04: /* MI_ASCII  - string                               */
1886                        return (diva_strace_read_asc  (pVar, (char*)variable));
1887                case 0x05: /* MI_NUMBER - counted sequence of bytes            */
1888                        return (diva_strace_read_ie  (pVar, (diva_trace_ie_t*)variable));
1889                case 0x81: /* MI_INT    - signed integer                       */
1890                        return (diva_strace_read_int (pVar, (int*)variable));
1891                case 0x82: /* MI_UINT   - unsigned integer                     */
1892                        return (diva_strace_read_uint (pVar, (dword*)variable));
1893                case 0x83: /* MI_HINT   - unsigned integer, hex representetion */
1894                        return (diva_strace_read_uint (pVar, (dword*)variable));
1895                case 0x87: /* MI_BITFLD - unsigned integer, bit representation */
1896                        return (diva_strace_read_uint (pVar, (dword*)variable));
1897        }
1898
1899        /*
1900                This type of variable is not handled, indicate error
1901                Or one problem in management interface, or in application recodeing
1902                table, or this application should handle it.
1903                */
1904        return (-1);
1905}
1906
1907/*
1908        Read signed integer to destination
1909        */
1910static int diva_strace_read_int  (diva_man_var_header_t* pVar, int* var) {
1911        byte* ptr = (char*)&pVar->path_length;
1912        int value;
1913
1914        ptr += (pVar->path_length + 1);
1915
1916        switch (pVar->value_length) {
1917                case 1:
1918                        value = *(char*)ptr;
1919                        break;
1920
1921                case 2:
1922                        value = (short)GET_WORD(ptr);
1923                        break;
1924
1925                case 4:
1926                        value = (int)GET_DWORD(ptr);
1927                        break;
1928
1929                default:
1930                        return (-1);
1931        }
1932
1933        *var = value;
1934
1935        return (0);
1936}
1937
1938static int diva_strace_read_uint (diva_man_var_header_t* pVar, dword* var) {
1939        byte* ptr = (char*)&pVar->path_length;
1940        dword value;
1941
1942        ptr += (pVar->path_length + 1);
1943
1944        switch (pVar->value_length) {
1945                case 1:
1946                        value = (byte)(*ptr);
1947                        break;
1948
1949                case 2:
1950                        value = (word)GET_WORD(ptr);
1951                        break;
1952
1953                case 3:
1954                        value  = (dword)GET_DWORD(ptr);
1955                        value &= 0x00ffffff;
1956                        break;
1957
1958                case 4:
1959                        value = (dword)GET_DWORD(ptr);
1960                        break;
1961
1962                default:
1963                        return (-1);
1964        }
1965
1966        *var = value;
1967
1968        return (0);
1969}
1970
1971/*
1972        Read zero terminated ASCII string
1973        */
1974static int diva_strace_read_asz  (diva_man_var_header_t* pVar, char* var) {
1975        char* ptr = (char*)&pVar->path_length;
1976        int length;
1977
1978        ptr += (pVar->path_length + 1);
1979
1980        if (!(length = pVar->value_length)) {
1981                length = strlen (ptr);
1982        }
1983        memcpy (var, ptr, length);
1984        var[length] = 0;
1985
1986        return (0);
1987}
1988
1989/*
1990        Read counted (with leading length byte) ASCII string
1991        */
1992static int diva_strace_read_asc  (diva_man_var_header_t* pVar, char* var) {
1993        char* ptr = (char*)&pVar->path_length;
1994
1995        ptr += (pVar->path_length + 1);
1996        memcpy (var, ptr+1, *ptr);
1997        var[(int)*ptr] = 0;
1998
1999        return (0);
2000}
2001
2002/*
2003                Read one information element - i.e. one string of byte values with
2004                one length byte in front
2005        */
2006static int  diva_strace_read_ie  (diva_man_var_header_t* pVar,
2007                                                                                                                                        diva_trace_ie_t* var) {
2008        char* ptr = (char*)&pVar->path_length;
2009
2010        ptr += (pVar->path_length + 1);
2011
2012        var->length = *ptr;
2013        memcpy (&var->data[0], ptr+1, *ptr);
2014
2015        return (0);
2016}
2017
2018static int SuperTraceSetAudioTap  (void* hLib, int Channel, int on) {
2019        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2020
2021        if ((Channel < 1) || (Channel > pLib->Channels)) {
2022                return (-1);
2023        }
2024        Channel--;
2025
2026        if (on) {
2027                pLib->audio_tap_mask |=  (1L << Channel);
2028        } else {
2029                pLib->audio_tap_mask &= ~(1L << Channel);
2030        }
2031
2032  /*
2033    EYE patterns have TM_M_DATA set as additional
2034    condition
2035    */
2036  if (pLib->audio_tap_mask) {
2037    pLib->trace_event_mask |= TM_M_DATA;
2038  } else {
2039    pLib->trace_event_mask &= ~TM_M_DATA;
2040  }
2041
2042        return (ScheduleNextTraceRequest (pLib));
2043}
2044
2045static int SuperTraceSetBChannel  (void* hLib, int Channel, int on) {
2046        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2047
2048        if ((Channel < 1) || (Channel > pLib->Channels)) {
2049                return (-1);
2050        }
2051        Channel--;
2052
2053        if (on) {
2054                pLib->bchannel_trace_mask |=  (1L << Channel);
2055        } else {
2056                pLib->bchannel_trace_mask &= ~(1L << Channel);
2057        }
2058
2059        return (ScheduleNextTraceRequest (pLib));
2060}
2061
2062static int SuperTraceSetDChannel  (void* hLib, int on) {
2063        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2064
2065        if (on) {
2066                pLib->trace_event_mask |= (TM_D_CHAN | TM_C_COMM | TM_DL_ERR | TM_LAYER1);
2067        } else {
2068                pLib->trace_event_mask &= ~(TM_D_CHAN | TM_C_COMM | TM_DL_ERR | TM_LAYER1);
2069        }
2070
2071        return (ScheduleNextTraceRequest (pLib));
2072}
2073
2074static int SuperTraceSetInfo (void* hLib, int on) {
2075        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2076
2077        if (on) {
2078                pLib->trace_event_mask |= TM_STRING;
2079        } else {
2080                pLib->trace_event_mask &= ~TM_STRING;
2081        }
2082
2083        return (ScheduleNextTraceRequest (pLib));
2084}
2085
2086static int SuperTraceClearCall (void* hLib, int Channel) {
2087        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2088
2089        if ((Channel < 1) || (Channel > pLib->Channels)) {
2090                return (-1);
2091        }
2092        Channel--;
2093
2094        pLib->clear_call_command |= (1L << Channel);
2095
2096        return (ScheduleNextTraceRequest (pLib));
2097}
2098
2099/*
2100        Parse and update cumulative statistice
2101        */
2102static int diva_ifc_statistics (diva_strace_context_t* pLib,
2103                                                                                                                                diva_man_var_header_t* pVar) {
2104        diva_man_var_header_t* cur;
2105        int i, one_updated = 0, mdm_updated = 0, fax_updated = 0;
2106
2107        for (i  = pLib->statistic_parse_first; i <= pLib->statistic_parse_last; i++) {
2108                if ((cur = find_var (pVar, pLib->parse_table[i].path))) {
2109                        if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) {
2110                                diva_trace_error (pLib, -3 , __FILE__, __LINE__);
2111                                return (-1);
2112                        }
2113                        one_updated = 1;
2114      if ((i >= pLib->mdm_statistic_parse_first) && (i <= pLib->mdm_statistic_parse_last)) {
2115        mdm_updated = 1;
2116      }
2117      if ((i >= pLib->fax_statistic_parse_first) && (i <= pLib->fax_statistic_parse_last)) {
2118        fax_updated = 1;
2119      }
2120                }
2121        }
2122
2123        /*
2124                We do not use first event to notify user - this is the event that is
2125                generated as result of EVENT ON operation and is used only to initialize
2126                internal variables of application
2127                */
2128  if (mdm_updated) {
2129                diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE);
2130  } else if (fax_updated) {
2131                diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE);
2132  } else if (one_updated) {
2133                diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE);
2134        }
2135
2136        return (one_updated ? 0 : -1);
2137}
2138
2139static int SuperTraceGetOutgoingCallStatistics (void* hLib) {
2140        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2141        pLib->outgoing_ifc_stats = 1;
2142        return (ScheduleNextTraceRequest (pLib));
2143}
2144
2145static int SuperTraceGetIncomingCallStatistics (void* hLib) {
2146        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2147        pLib->incoming_ifc_stats = 1;
2148        return (ScheduleNextTraceRequest (pLib));
2149}
2150
2151static int SuperTraceGetModemStatistics (void* hLib) {
2152        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2153        pLib->modem_ifc_stats = 1;
2154        return (ScheduleNextTraceRequest (pLib));
2155}
2156
2157static int SuperTraceGetFaxStatistics (void* hLib) {
2158        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2159        pLib->fax_ifc_stats = 1;
2160        return (ScheduleNextTraceRequest (pLib));
2161}
2162
2163static int SuperTraceGetBLayer1Statistics (void* hLib) {
2164        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2165        pLib->b1_ifc_stats = 1;
2166        return (ScheduleNextTraceRequest (pLib));
2167}
2168
2169static int SuperTraceGetBLayer2Statistics (void* hLib) {
2170        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2171        pLib->b2_ifc_stats = 1;
2172        return (ScheduleNextTraceRequest (pLib));
2173}
2174
2175static int SuperTraceGetDLayer1Statistics (void* hLib) {
2176        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2177        pLib->d1_ifc_stats = 1;
2178        return (ScheduleNextTraceRequest (pLib));
2179}
2180
2181static int SuperTraceGetDLayer2Statistics (void* hLib) {
2182        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2183        pLib->d2_ifc_stats = 1;
2184        return (ScheduleNextTraceRequest (pLib));
2185}
2186
2187dword DivaSTraceGetMemotyRequirement (int channels) {
2188  dword parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \
2189                                                                                                 STAT_PARSE_ENTRIES + \
2190                                                                                                 LINE_PARSE_ENTRIES + 1) * channels;
2191  return (sizeof(diva_strace_context_t) + \
2192          (parse_entries * sizeof(diva_strace_path2action_t)));
2193}
2194
2195
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.