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, "Unknown 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, "Unknown 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                if (diva_strace_read_uint(pVar, &l2_state))
 964                        return -1;
 965
 966                switch (l2_state) {
 967                        case 0:
 968                                strcpy (tmp, "Idle");
 969                                break;
 970                        case 1:
 971                                strcpy (tmp, "Layer2 UP");
 972                                break;
 973                        case 2:
 974                                strcpy (tmp, "Layer2 Disconnecting");
 975                                break;
 976                        case 3:
 977                                strcpy (tmp, "Layer2 Connecting");
 978                                break;
 979                        case 4:
 980                                strcpy (tmp, "SPID Initializing");
 981                                break;
 982                        case 5:
 983                                strcpy (tmp, "SPID Initialised");
 984                                break;
 985                        case 6:
 986                                strcpy (tmp, "Layer2 Connecting");
 987                                break;
 988
 989                        case  7:
 990                                strcpy (tmp, "Auto SPID Stopped");
 991                                break;
 992
 993                        case  8:
 994                                strcpy (tmp, "Auto SPID Idle");
 995                                break;
 996
 997                        case  9:
 998                                strcpy (tmp, "Auto SPID Requested");
 999                                break;
1000
1001                        case  10:
1002                                strcpy (tmp, "Auto SPID Delivery");
1003                                break;
1004
1005                        case 11:
1006                                strcpy (tmp, "Auto SPID Complete");
1007                                break;
1008
1009                        default:
1010                                sprintf (tmp, "U:%d", (int)l2_state);
1011                }
1012                if (pLib->l2_trace == 1) {
1013                        pLib->l2_trace = 2;
1014                } else {
1015                        diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
1016                }
1017                return (0);
1018        }
1019
1020        if (!strncmp("Statistics\\Incoming Calls\\Calls", path, pVar->path_length) ||
1021                        !strncmp("Statistics\\Incoming Calls\\Connected", path, pVar->path_length)) {
1022                return (SuperTraceGetIncomingCallStatistics (pLib));
1023        }
1024
1025        if (!strncmp("Statistics\\Outgoing Calls\\Calls", path, pVar->path_length) ||
1026                        !strncmp("Statistics\\Outgoing Calls\\Connected", path, pVar->path_length)) {
1027                return (SuperTraceGetOutgoingCallStatistics (pLib));
1028        }
1029
1030        return (-1);
1031}
1032
1033static int diva_line_event (diva_strace_context_t* pLib, int Channel) {
1034        pLib->pending_line_status |= (1L << (Channel-1));
1035        return (0);
1036}
1037
1038static int diva_modem_event (diva_strace_context_t* pLib, int Channel) {
1039        pLib->pending_modem_status |= (1L << (Channel-1));
1040        return (0);
1041}
1042
1043static int diva_fax_event (diva_strace_context_t* pLib, int Channel) {
1044        pLib->pending_fax_status |= (1L << (Channel-1));
1045        return (0);
1046}
1047
1048/*
1049        Process INFO indications that arrive from the card
1050        Uses path of first I.E. to detect the source of the
1051        infication
1052        */
1053static int process_idi_info  (diva_strace_context_t* pLib,
1054                                                                                                                        diva_man_var_header_t* pVar) {
1055        const char* path = (char*)&pVar->path_length+1;
1056        char name[64];
1057        int i, len;
1058
1059        /*
1060                First look for Modem Status Info
1061                */
1062        for (i = pLib->Channels; i > 0; i--) {
1063                len = sprintf (name, "State\\B%d\\Modem", i);
1064                if (!strncmp(name, path, len)) {
1065                        return (diva_modem_info (pLib, i, pVar));
1066                }
1067        }
1068
1069        /*
1070                Look for Fax Status Info
1071                */
1072        for (i = pLib->Channels; i > 0; i--) {
1073                len = sprintf (name, "State\\B%d\\FAX", i);
1074                if (!strncmp(name, path, len)) {
1075                        return (diva_fax_info (pLib, i, pVar));
1076                }
1077        }
1078
1079        /*
1080                Look for Line Status Info
1081                */
1082        for (i = pLib->Channels; i > 0; i--) {
1083                len = sprintf (name, "State\\B%d", i);
1084                if (!strncmp(name, path, len)) {
1085                        return (diva_line_info (pLib, i, pVar));
1086                }
1087        }
1088
1089        if (!diva_ifc_statistics (pLib, pVar)) {
1090                return (0);
1091        }
1092
1093        return (-1);
1094}
1095
1096/*
1097        MODEM INSTANCE STATE UPDATE
1098
1099        Update Modem Status Information and issue notification to user,
1100        that will inform about change in the state of modem instance, that is
1101        associuated with this channel
1102        */
1103static int diva_modem_info (diva_strace_context_t* pLib,
1104                                                                                                                int Channel,
1105                                                                                                                diva_man_var_header_t* pVar) {
1106        diva_man_var_header_t* cur;
1107        int i, nr = Channel - 1;
1108
1109        for (i  = pLib->modem_parse_entry_first[nr];
1110                         i <= pLib->modem_parse_entry_last[nr]; i++) {
1111                if ((cur = find_var (pVar, pLib->parse_table[i].path))) {
1112                        if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) {
1113                                diva_trace_error (pLib, -3 , __FILE__, __LINE__);
1114                                return (-1);
1115                        }
1116                } else {
1117                        diva_trace_error (pLib, -2 , __FILE__, __LINE__);
1118                        return (-1);
1119                }
1120        }
1121
1122        /*
1123                We do not use first event to notify user - this is the event that is
1124                generated as result of EVENT ON operation and is used only to initialize
1125                internal variables of application
1126                */
1127        if (pLib->modem_init_event & (1L << nr)) {
1128                diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE);
1129        } else {
1130                pLib->modem_init_event |= (1L << nr);
1131        }
1132
1133        return (0);
1134}
1135
1136static int diva_fax_info (diva_strace_context_t* pLib,
1137                                                                                                        int Channel,
1138                                                                                                        diva_man_var_header_t* pVar) {
1139        diva_man_var_header_t* cur;
1140        int i, nr = Channel - 1;
1141
1142        for (i  = pLib->fax_parse_entry_first[nr];
1143                         i <= pLib->fax_parse_entry_last[nr]; i++) {
1144                if ((cur = find_var (pVar, pLib->parse_table[i].path))) {
1145                        if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) {
1146                                diva_trace_error (pLib, -3 , __FILE__, __LINE__);
1147                                return (-1);
1148                        }
1149                } else {
1150                        diva_trace_error (pLib, -2 , __FILE__, __LINE__);
1151                        return (-1);
1152                }
1153        }
1154
1155        /*
1156                We do not use first event to notify user - this is the event that is
1157                generated as result of EVENT ON operation and is used only to initialize
1158                internal variables of application
1159                */
1160        if (pLib->fax_init_event & (1L << nr)) {
1161                diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE);
1162        } else {
1163                pLib->fax_init_event |= (1L << nr);
1164        }
1165
1166        return (0);
1167}
1168
1169/*
1170        LINE STATE UPDATE
1171        Update Line Status Information and issue notification to user,
1172        that will inform about change in the line state.
1173        */
1174static int diva_line_info  (diva_strace_context_t* pLib,
1175                                                                                                                int Channel,
1176                                                                                                                diva_man_var_header_t* pVar) {
1177        diva_man_var_header_t* cur;
1178        int i, nr = Channel - 1;
1179
1180        for (i  = pLib->line_parse_entry_first[nr];
1181                         i <= pLib->line_parse_entry_last[nr]; i++) {
1182                if ((cur = find_var (pVar, pLib->parse_table[i].path))) {
1183                        if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) {
1184                                diva_trace_error (pLib, -3 , __FILE__, __LINE__);
1185                                return (-1);
1186                        }
1187                } else {
1188                        diva_trace_error (pLib, -2 , __FILE__, __LINE__);
1189                        return (-1);
1190                }
1191        }
1192
1193        /*
1194                We do not use first event to notify user - this is the event that is
1195                generated as result of EVENT ON operation and is used only to initialize
1196                internal variables of application
1197
1198                Exception is is if the line is "online". In this case we have to notify
1199                user about this confition.
1200                */
1201        if (pLib->line_init_event & (1L << nr)) {
1202                diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
1203        } else {
1204                pLib->line_init_event |= (1L << nr);
1205                if (strcmp (&pLib->lines[nr].Line[0], "Idle")) {
1206                        diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
1207                }
1208        }
1209
1210        return (0);
1211}
1212
1213/*
1214        Move position to next vatianle in the chain
1215        */
1216static diva_man_var_header_t* get_next_var (diva_man_var_header_t* pVar) {
1217        byte* msg   = (byte*)pVar;
1218        byte* start;
1219        int msg_length;
1220
1221        if (*msg != ESC) return NULL;
1222
1223        start = msg + 2;
1224        msg_length = *(msg+1);
1225        msg = (start+msg_length);
1226
1227        if (*msg != ESC) return NULL;
1228
1229        return ((diva_man_var_header_t*)msg);
1230}
1231
1232/*
1233        Move position to variable with given name
1234        */
1235static diva_man_var_header_t* find_var (diva_man_var_header_t* pVar,
1236                                                                                                                                                                const char* name) {
1237        const char* path;
1238
1239        do {
1240                path = (char*)&pVar->path_length+1;
1241
1242                if (!strncmp (name, path, pVar->path_length)) {
1243                        break;
1244                }
1245        } while ((pVar = get_next_var (pVar)));
1246
1247        return (pVar);
1248}
1249
1250static void diva_create_line_parse_table  (diva_strace_context_t* pLib,
1251                                                                                                                                                                         int Channel) {
1252        diva_trace_line_state_t* pLine = &pLib->lines[Channel];
1253        int nr = Channel+1;
1254
1255        if ((pLib->cur_parse_entry + LINE_PARSE_ENTRIES) >= pLib->parse_entries) {
1256                diva_trace_error (pLib, -1, __FILE__, __LINE__);
1257                return;
1258        }
1259
1260        pLine->ChannelNumber = nr;
1261
1262        pLib->line_parse_entry_first[Channel] = pLib->cur_parse_entry;
1263
1264        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1265                                         "State\\B%d\\Framing", nr);
1266        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Framing[0];
1267
1268        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1269                                         "State\\B%d\\Line", nr);
1270        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Line[0];
1271
1272        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1273                                         "State\\B%d\\Layer2", nr);
1274        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer2[0];
1275
1276        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1277                                         "State\\B%d\\Layer3", nr);
1278        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer3[0];
1279
1280        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1281                                         "State\\B%d\\Remote Address", nr);
1282        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1283                                                                                                                                                                                                &pLine->RemoteAddress[0];
1284
1285        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1286                                         "State\\B%d\\Remote SubAddr", nr);
1287        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1288                                                                                                                                                                                                &pLine->RemoteSubAddress[0];
1289
1290        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1291                                         "State\\B%d\\Local Address", nr);
1292        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1293                                                                                                                                                                                                &pLine->LocalAddress[0];
1294
1295        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1296                                         "State\\B%d\\Local SubAddr", nr);
1297        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1298                                                                                                                                                                                                &pLine->LocalSubAddress[0];
1299
1300        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1301                                         "State\\B%d\\BC", nr);
1302        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_BC;
1303
1304        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1305                                         "State\\B%d\\HLC", nr);
1306        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_HLC;
1307
1308        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1309                                         "State\\B%d\\LLC", nr);
1310        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_LLC;
1311
1312        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1313                                         "State\\B%d\\Charges", nr);
1314        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Charges;
1315
1316        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1317                                         "State\\B%d\\Call Reference", nr);
1318        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->CallReference;
1319
1320        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1321                                         "State\\B%d\\Last Disc Cause", nr);
1322        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1323                                                                                                                                                                                                                &pLine->LastDisconnecCause;
1324
1325        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1326                                         "State\\B%d\\User ID", nr);
1327        pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->UserID[0];
1328
1329        pLib->line_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1330}
1331
1332static void diva_create_fax_parse_table (diva_strace_context_t* pLib,
1333                                                                                                                                                                 int Channel) {
1334        diva_trace_fax_state_t* pFax = &pLib->lines[Channel].fax;
1335        int nr = Channel+1;
1336
1337        if ((pLib->cur_parse_entry + FAX_PARSE_ENTRIES) >= pLib->parse_entries) {
1338                diva_trace_error (pLib, -1, __FILE__, __LINE__);
1339                return;
1340        }
1341        pFax->ChannelNumber = nr;
1342
1343        pLib->fax_parse_entry_first[Channel] = pLib->cur_parse_entry;
1344
1345        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1346                                         "State\\B%d\\FAX\\Event", nr);
1347        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Event;
1348
1349        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1350                                         "State\\B%d\\FAX\\Page Counter", nr);
1351        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Page_Counter;
1352
1353        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1354                                         "State\\B%d\\FAX\\Features", nr);
1355        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Features;
1356
1357        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1358                                         "State\\B%d\\FAX\\Station ID", nr);
1359        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Station_ID[0];
1360
1361        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1362                                         "State\\B%d\\FAX\\Subaddress", nr);
1363        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Subaddress[0];
1364
1365        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1366                                         "State\\B%d\\FAX\\Password", nr);
1367        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Password[0];
1368
1369        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1370                                         "State\\B%d\\FAX\\Speed", nr);
1371        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Speed;
1372
1373        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1374                                         "State\\B%d\\FAX\\Resolution", nr);
1375        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Resolution;
1376
1377        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1378                                         "State\\B%d\\FAX\\Paper Width", nr);
1379        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Width;
1380
1381        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1382                                         "State\\B%d\\FAX\\Paper Length", nr);
1383        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Length;
1384
1385        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1386                                         "State\\B%d\\FAX\\Scanline Time", nr);
1387        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Scanline_Time;
1388
1389        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1390                                         "State\\B%d\\FAX\\Disc Reason", nr);
1391        pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Disc_Reason;
1392
1393        pLib->fax_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1394}
1395
1396static void diva_create_modem_parse_table (diva_strace_context_t* pLib,
1397                                                                                                                                                                         int Channel) {
1398        diva_trace_modem_state_t* pModem = &pLib->lines[Channel].modem;
1399        int nr = Channel+1;
1400
1401        if ((pLib->cur_parse_entry + MODEM_PARSE_ENTRIES) >= pLib->parse_entries) {
1402                diva_trace_error (pLib, -1, __FILE__, __LINE__);
1403                return;
1404        }
1405        pModem->ChannelNumber = nr;
1406
1407        pLib->modem_parse_entry_first[Channel] = pLib->cur_parse_entry;
1408
1409        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1410                                         "State\\B%d\\Modem\\Event", nr);
1411        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Event;
1412
1413        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1414                                         "State\\B%d\\Modem\\Norm", nr);
1415        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Norm;
1416
1417        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1418                                         "State\\B%d\\Modem\\Options", nr);
1419        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Options;
1420
1421        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1422                                         "State\\B%d\\Modem\\TX Speed", nr);
1423        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->TxSpeed;
1424
1425        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1426                                         "State\\B%d\\Modem\\RX Speed", nr);
1427        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxSpeed;
1428
1429        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1430                                         "State\\B%d\\Modem\\Roundtrip ms", nr);
1431        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RoundtripMsec;
1432
1433        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1434                                         "State\\B%d\\Modem\\Symbol Rate", nr);
1435        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SymbolRate;
1436
1437        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1438                                         "State\\B%d\\Modem\\RX Level dBm", nr);
1439        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxLeveldBm;
1440
1441        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1442                                         "State\\B%d\\Modem\\Echo Level dBm", nr);
1443        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->EchoLeveldBm;
1444
1445        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1446                                         "State\\B%d\\Modem\\SNR dB", nr);
1447        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SNRdb;
1448
1449        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1450                                         "State\\B%d\\Modem\\MAE", nr);
1451        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->MAE;
1452
1453        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1454                                         "State\\B%d\\Modem\\Local Retrains", nr);
1455        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalRetrains;
1456
1457        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1458                                         "State\\B%d\\Modem\\Remote Retrains", nr);
1459        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteRetrains;
1460
1461        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1462                                         "State\\B%d\\Modem\\Local Resyncs", nr);
1463        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalResyncs;
1464
1465        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1466                                         "State\\B%d\\Modem\\Remote Resyncs", nr);
1467        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteResyncs;
1468
1469        sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
1470                                         "State\\B%d\\Modem\\Disc Reason", nr);
1471        pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->DiscReason;
1472
1473        pLib->modem_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1474}
1475
1476static void diva_create_parse_table (diva_strace_context_t* pLib) {
1477        int i;
1478
1479        for (i = 0; i < pLib->Channels; i++) {
1480                diva_create_line_parse_table  (pLib, i);
1481                diva_create_modem_parse_table (pLib, i);
1482                diva_create_fax_parse_table   (pLib, i);
1483        }
1484
1485        pLib->statistic_parse_first = pLib->cur_parse_entry;
1486
1487        /*
1488                Outgoing Calls
1489                */
1490        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1491                                        "Statistics\\Outgoing Calls\\Calls");
1492        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1493                                                                                                                                                &pLib->InterfaceStat.outg.Calls;
1494
1495        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1496                                        "Statistics\\Outgoing Calls\\Connected");
1497        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1498                                                                                                                                                &pLib->InterfaceStat.outg.Connected;
1499
1500        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1501                                        "Statistics\\Outgoing Calls\\User Busy");
1502        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1503                                                                                                                                                &pLib->InterfaceStat.outg.User_Busy;
1504
1505        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1506                                        "Statistics\\Outgoing Calls\\No Answer");
1507        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1508                                                                                                                                                &pLib->InterfaceStat.outg.No_Answer;
1509
1510        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1511                                        "Statistics\\Outgoing Calls\\Wrong Number");
1512        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1513                                                                                                                                                &pLib->InterfaceStat.outg.Wrong_Number;
1514
1515        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1516                                        "Statistics\\Outgoing Calls\\Call Rejected");
1517        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1518                                                                                                                                                &pLib->InterfaceStat.outg.Call_Rejected;
1519
1520        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1521                                        "Statistics\\Outgoing Calls\\Other Failures");
1522        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1523                                                                                                                                                &pLib->InterfaceStat.outg.Other_Failures;
1524
1525        /*
1526                Incoming Calls
1527                */
1528        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1529                                        "Statistics\\Incoming Calls\\Calls");
1530        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1531                                                                                                                                                &pLib->InterfaceStat.inc.Calls;
1532
1533        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1534                                        "Statistics\\Incoming Calls\\Connected");
1535        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1536                                                                                                                                                &pLib->InterfaceStat.inc.Connected;
1537
1538        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1539                                        "Statistics\\Incoming Calls\\User Busy");
1540        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1541                                                                                                                                                &pLib->InterfaceStat.inc.User_Busy;
1542
1543        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1544                                        "Statistics\\Incoming Calls\\Call Rejected");
1545        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1546                                                                                                                                                &pLib->InterfaceStat.inc.Call_Rejected;
1547
1548        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1549                                        "Statistics\\Incoming Calls\\Wrong Number");
1550        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1551                                                                                                                                                &pLib->InterfaceStat.inc.Wrong_Number;
1552
1553        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1554                                        "Statistics\\Incoming Calls\\Incompatible Dst");
1555        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1556                                                                                                                                                &pLib->InterfaceStat.inc.Incompatible_Dst;
1557
1558        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1559                                        "Statistics\\Incoming Calls\\Out of Order");
1560        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1561                                                                                                                                                &pLib->InterfaceStat.inc.Out_of_Order;
1562
1563        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1564                                        "Statistics\\Incoming Calls\\Ignored");
1565        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1566                                                                                                                                                &pLib->InterfaceStat.inc.Ignored;
1567
1568        /*
1569                Modem Statistics
1570                */
1571        pLib->mdm_statistic_parse_first = pLib->cur_parse_entry;
1572
1573        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1574                                        "Statistics\\Modem\\Disc Normal");
1575        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1576                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Normal;
1577
1578        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1579                                        "Statistics\\Modem\\Disc Unspecified");
1580        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1581                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Unspecified;
1582
1583        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1584                                        "Statistics\\Modem\\Disc Busy Tone");
1585        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1586                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Busy_Tone;
1587
1588        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1589                                        "Statistics\\Modem\\Disc Congestion");
1590        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1591                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Congestion;
1592
1593        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1594                                        "Statistics\\Modem\\Disc Carr. Wait");
1595        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1596                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Carr_Wait;
1597
1598        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1599                                        "Statistics\\Modem\\Disc Trn Timeout");
1600        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1601                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Trn_Timeout;
1602
1603        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1604                                        "Statistics\\Modem\\Disc Incompat.");
1605        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1606                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Incompat;
1607
1608        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1609                                        "Statistics\\Modem\\Disc Frame Rej.");
1610        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1611                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_Frame_Rej;
1612
1613        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1614                                        "Statistics\\Modem\\Disc V42bis");
1615        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1616                                                                                                                                                &pLib->InterfaceStat.mdm.Disc_V42bis;
1617
1618        pLib->mdm_statistic_parse_last  = pLib->cur_parse_entry - 1;
1619
1620        /*
1621                Fax Statistics
1622                */
1623        pLib->fax_statistic_parse_first = pLib->cur_parse_entry;
1624
1625        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1626                                        "Statistics\\FAX\\Disc Normal");
1627        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1628                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Normal;
1629
1630        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1631                                        "Statistics\\FAX\\Disc Not Ident.");
1632        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1633                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Not_Ident;
1634
1635        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1636                                        "Statistics\\FAX\\Disc No Response");
1637        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1638                                                                                                                                                &pLib->InterfaceStat.fax.Disc_No_Response;
1639
1640        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1641                                        "Statistics\\FAX\\Disc Retries");
1642        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1643                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Retries;
1644
1645        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1646                                        "Statistics\\FAX\\Disc Unexp. Msg.");
1647        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1648                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Unexp_Msg;
1649
1650        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1651                                        "Statistics\\FAX\\Disc No Polling.");
1652        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1653                                                                                                                                                &pLib->InterfaceStat.fax.Disc_No_Polling;
1654
1655        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1656                                        "Statistics\\FAX\\Disc Training");
1657        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1658                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Training;
1659
1660        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1661                                        "Statistics\\FAX\\Disc Unexpected");
1662        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1663                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Unexpected;
1664
1665        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1666                                        "Statistics\\FAX\\Disc Application");
1667        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1668                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Application;
1669
1670        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1671                                        "Statistics\\FAX\\Disc Incompat.");
1672        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1673                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Incompat;
1674
1675        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1676                                        "Statistics\\FAX\\Disc No Command");
1677        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1678                                                                                                                                                &pLib->InterfaceStat.fax.Disc_No_Command;
1679
1680        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1681                                        "Statistics\\FAX\\Disc Long Msg");
1682        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1683                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Long_Msg;
1684
1685        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1686                                        "Statistics\\FAX\\Disc Supervisor");
1687        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1688                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Supervisor;
1689
1690        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1691                                        "Statistics\\FAX\\Disc SUB SEP PWD");
1692        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1693                                                                                                                                                &pLib->InterfaceStat.fax.Disc_SUB_SEP_PWD;
1694
1695        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1696                                        "Statistics\\FAX\\Disc Invalid Msg");
1697        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1698                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Invalid_Msg;
1699
1700        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1701                                        "Statistics\\FAX\\Disc Page Coding");
1702        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1703                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Page_Coding;
1704
1705        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1706                                        "Statistics\\FAX\\Disc App Timeout");
1707        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1708                                                                                                                                                &pLib->InterfaceStat.fax.Disc_App_Timeout;
1709
1710        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1711                                        "Statistics\\FAX\\Disc Unspecified");
1712        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1713                                                                                                                                                &pLib->InterfaceStat.fax.Disc_Unspecified;
1714
1715        pLib->fax_statistic_parse_last  = pLib->cur_parse_entry - 1;
1716
1717        /*
1718                B-Layer1"
1719                */
1720        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1721                                        "Statistics\\B-Layer1\\X-Frames");
1722        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1723                                                                                                                                                &pLib->InterfaceStat.b1.X_Frames;
1724
1725        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1726                                        "Statistics\\B-Layer1\\X-Bytes");
1727        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1728                                                                                                                                                &pLib->InterfaceStat.b1.X_Bytes;
1729
1730        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1731                                        "Statistics\\B-Layer1\\X-Errors");
1732        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1733                                                                                                                                                &pLib->InterfaceStat.b1.X_Errors;
1734
1735        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1736                                        "Statistics\\B-Layer1\\R-Frames");
1737        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1738                                                                                                                                                &pLib->InterfaceStat.b1.R_Frames;
1739
1740        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1741                                        "Statistics\\B-Layer1\\R-Bytes");
1742        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1743                                                                                                                                                &pLib->InterfaceStat.b1.R_Bytes;
1744
1745        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1746                                        "Statistics\\B-Layer1\\R-Errors");
1747        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1748                                                                                                                                                &pLib->InterfaceStat.b1.R_Errors;
1749
1750        /*
1751                B-Layer2
1752                */
1753        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1754                                        "Statistics\\B-Layer2\\X-Frames");
1755        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1756                                                                                                                                                &pLib->InterfaceStat.b2.X_Frames;
1757
1758        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1759                                        "Statistics\\B-Layer2\\X-Bytes");
1760        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1761                                                                                                                                                &pLib->InterfaceStat.b2.X_Bytes;
1762
1763        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1764                                        "Statistics\\B-Layer2\\X-Errors");
1765        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1766                                                                                                                                                &pLib->InterfaceStat.b2.X_Errors;
1767
1768        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1769                                        "Statistics\\B-Layer2\\R-Frames");
1770        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1771                                                                                                                                                &pLib->InterfaceStat.b2.R_Frames;
1772
1773        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1774                                        "Statistics\\B-Layer2\\R-Bytes");
1775        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1776                                                                                                                                                &pLib->InterfaceStat.b2.R_Bytes;
1777
1778        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1779                                        "Statistics\\B-Layer2\\R-Errors");
1780        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1781                                                                                                                                                &pLib->InterfaceStat.b2.R_Errors;
1782
1783        /*
1784                D-Layer1
1785                */
1786        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1787                                        "Statistics\\D-Layer1\\X-Frames");
1788        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1789                                                                                                                                                &pLib->InterfaceStat.d1.X_Frames;
1790
1791        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1792                                        "Statistics\\D-Layer1\\X-Bytes");
1793        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1794                                                                                                                                                &pLib->InterfaceStat.d1.X_Bytes;
1795
1796        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1797                                        "Statistics\\D-Layer1\\X-Errors");
1798        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1799                                                                                                                                                &pLib->InterfaceStat.d1.X_Errors;
1800
1801        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1802                                        "Statistics\\D-Layer1\\R-Frames");
1803        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1804                                                                                                                                                &pLib->InterfaceStat.d1.R_Frames;
1805
1806        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1807                                        "Statistics\\D-Layer1\\R-Bytes");
1808        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1809                                                                                                                                                &pLib->InterfaceStat.d1.R_Bytes;
1810
1811        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1812                                        "Statistics\\D-Layer1\\R-Errors");
1813        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1814                                                                                                                                                &pLib->InterfaceStat.d1.R_Errors;
1815
1816        /*
1817                D-Layer2
1818                */
1819        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1820                                        "Statistics\\D-Layer2\\X-Frames");
1821        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1822                                                                                                                                                &pLib->InterfaceStat.d2.X_Frames;
1823
1824        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1825                                        "Statistics\\D-Layer2\\X-Bytes");
1826        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1827                                                                                                                                                &pLib->InterfaceStat.d2.X_Bytes;
1828
1829        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1830                                        "Statistics\\D-Layer2\\X-Errors");
1831        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1832                                                                                                                                                &pLib->InterfaceStat.d2.X_Errors;
1833
1834        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1835                                        "Statistics\\D-Layer2\\R-Frames");
1836        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1837                                                                                                                                                &pLib->InterfaceStat.d2.R_Frames;
1838
1839        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1840                                        "Statistics\\D-Layer2\\R-Bytes");
1841        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1842                                                                                                                                                &pLib->InterfaceStat.d2.R_Bytes;
1843
1844        strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
1845                                        "Statistics\\D-Layer2\\R-Errors");
1846        pLib->parse_table[pLib->cur_parse_entry++].variable = \
1847                                                                                                                                                &pLib->InterfaceStat.d2.R_Errors;
1848
1849
1850        pLib->statistic_parse_last  = pLib->cur_parse_entry - 1;
1851}
1852
1853static void diva_trace_error (diva_strace_context_t* pLib,
1854                                                                                                                        int error, const char* file, int line) {
1855        if (pLib->user_proc_table.error_notify_proc) {
1856                (*(pLib->user_proc_table.error_notify_proc))(\
1857                                                                                                                                                                                pLib->user_proc_table.user_context,
1858                                                                                                                                                                                &pLib->instance, pLib->Adapter,
1859                                                                                                                                                                                error, file, line);
1860        }
1861}
1862
1863/*
1864        Delivery notification to user
1865        */
1866static void diva_trace_notify_user (diva_strace_context_t* pLib,
1867                                                                                                                 int Channel,
1868                                                                                                                 int notify_subject) {
1869        if (pLib->user_proc_table.notify_proc) {
1870                (*(pLib->user_proc_table.notify_proc))(pLib->user_proc_table.user_context,
1871                                                                                                                                                                         &pLib->instance,
1872                                                                                                                                                                         pLib->Adapter,
1873                                                                                                                                                                         &pLib->lines[Channel],
1874                                                                                                                                                                         notify_subject);
1875        }
1876}
1877
1878/*
1879        Read variable value to they destination based on the variable type
1880        */
1881static int diva_trace_read_variable (diva_man_var_header_t* pVar,
1882                                                                                                                                                 void* variable) {
1883        switch (pVar->type) {
1884                case 0x03: /* MI_ASCIIZ - syting                               */
1885                        return (diva_strace_read_asz  (pVar, (char*)variable));
1886                case 0x04: /* MI_ASCII  - string                               */
1887                        return (diva_strace_read_asc  (pVar, (char*)variable));
1888                case 0x05: /* MI_NUMBER - counted sequence of bytes            */
1889                        return (diva_strace_read_ie  (pVar, (diva_trace_ie_t*)variable));
1890                case 0x81: /* MI_INT    - signed integer                       */
1891                        return (diva_strace_read_int (pVar, (int*)variable));
1892                case 0x82: /* MI_UINT   - unsigned integer                     */
1893                        return (diva_strace_read_uint (pVar, (dword*)variable));
1894                case 0x83: /* MI_HINT   - unsigned integer, hex representetion */
1895                        return (diva_strace_read_uint (pVar, (dword*)variable));
1896                case 0x87: /* MI_BITFLD - unsigned integer, bit representation */
1897                        return (diva_strace_read_uint (pVar, (dword*)variable));
1898        }
1899
1900        /*
1901                This type of variable is not handled, indicate error
1902                Or one problem in management interface, or in application recodeing
1903                table, or this application should handle it.
1904                */
1905        return (-1);
1906}
1907
1908/*
1909        Read signed integer to destination
1910        */
1911static int diva_strace_read_int  (diva_man_var_header_t* pVar, int* var) {
1912        byte* ptr = (char*)&pVar->path_length;
1913        int value;
1914
1915        ptr += (pVar->path_length + 1);
1916
1917        switch (pVar->value_length) {
1918                case 1:
1919                        value = *(char*)ptr;
1920                        break;
1921
1922                case 2:
1923                        value = (short)GET_WORD(ptr);
1924                        break;
1925
1926                case 4:
1927                        value = (int)GET_DWORD(ptr);
1928                        break;
1929
1930                default:
1931                        return (-1);
1932        }
1933
1934        *var = value;
1935
1936        return (0);
1937}
1938
1939static int diva_strace_read_uint (diva_man_var_header_t* pVar, dword* var) {
1940        byte* ptr = (char*)&pVar->path_length;
1941        dword value;
1942
1943        ptr += (pVar->path_length + 1);
1944
1945        switch (pVar->value_length) {
1946                case 1:
1947                        value = (byte)(*ptr);
1948                        break;
1949
1950                case 2:
1951                        value = (word)GET_WORD(ptr);
1952                        break;
1953
1954                case 3:
1955                        value  = (dword)GET_DWORD(ptr);
1956                        value &= 0x00ffffff;
1957                        break;
1958
1959                case 4:
1960                        value = (dword)GET_DWORD(ptr);
1961                        break;
1962
1963                default:
1964                        return (-1);
1965        }
1966
1967        *var = value;
1968
1969        return (0);
1970}
1971
1972/*
1973        Read zero terminated ASCII string
1974        */
1975static int diva_strace_read_asz  (diva_man_var_header_t* pVar, char* var) {
1976        char* ptr = (char*)&pVar->path_length;
1977        int length;
1978
1979        ptr += (pVar->path_length + 1);
1980
1981        if (!(length = pVar->value_length)) {
1982                length = strlen (ptr);
1983        }
1984        memcpy (var, ptr, length);
1985        var[length] = 0;
1986
1987        return (0);
1988}
1989
1990/*
1991        Read counted (with leading length byte) ASCII string
1992        */
1993static int diva_strace_read_asc  (diva_man_var_header_t* pVar, char* var) {
1994        char* ptr = (char*)&pVar->path_length;
1995
1996        ptr += (pVar->path_length + 1);
1997        memcpy (var, ptr+1, *ptr);
1998        var[(int)*ptr] = 0;
1999
2000        return (0);
2001}
2002
2003/*
2004                Read one information element - i.e. one string of byte values with
2005                one length byte in front
2006        */
2007static int  diva_strace_read_ie  (diva_man_var_header_t* pVar,
2008                                                                                                                                        diva_trace_ie_t* var) {
2009        char* ptr = (char*)&pVar->path_length;
2010
2011        ptr += (pVar->path_length + 1);
2012
2013        var->length = *ptr;
2014        memcpy (&var->data[0], ptr+1, *ptr);
2015
2016        return (0);
2017}
2018
2019static int SuperTraceSetAudioTap  (void* hLib, int Channel, int on) {
2020        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2021
2022        if ((Channel < 1) || (Channel > pLib->Channels)) {
2023                return (-1);
2024        }
2025        Channel--;
2026
2027        if (on) {
2028                pLib->audio_tap_mask |=  (1L << Channel);
2029        } else {
2030                pLib->audio_tap_mask &= ~(1L << Channel);
2031        }
2032
2033  /*
2034    EYE patterns have TM_M_DATA set as additional
2035    condition
2036    */
2037  if (pLib->audio_tap_mask) {
2038    pLib->trace_event_mask |= TM_M_DATA;
2039  } else {
2040    pLib->trace_event_mask &= ~TM_M_DATA;
2041  }
2042
2043        return (ScheduleNextTraceRequest (pLib));
2044}
2045
2046static int SuperTraceSetBChannel  (void* hLib, int Channel, int on) {
2047        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2048
2049        if ((Channel < 1) || (Channel > pLib->Channels)) {
2050                return (-1);
2051        }
2052        Channel--;
2053
2054        if (on) {
2055                pLib->bchannel_trace_mask |=  (1L << Channel);
2056        } else {
2057                pLib->bchannel_trace_mask &= ~(1L << Channel);
2058        }
2059
2060        return (ScheduleNextTraceRequest (pLib));
2061}
2062
2063static int SuperTraceSetDChannel  (void* hLib, int on) {
2064        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2065
2066        if (on) {
2067                pLib->trace_event_mask |= (TM_D_CHAN | TM_C_COMM | TM_DL_ERR | TM_LAYER1);
2068        } else {
2069                pLib->trace_event_mask &= ~(TM_D_CHAN | TM_C_COMM | TM_DL_ERR | TM_LAYER1);
2070        }
2071
2072        return (ScheduleNextTraceRequest (pLib));
2073}
2074
2075static int SuperTraceSetInfo (void* hLib, int on) {
2076        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2077
2078        if (on) {
2079                pLib->trace_event_mask |= TM_STRING;
2080        } else {
2081                pLib->trace_event_mask &= ~TM_STRING;
2082        }
2083
2084        return (ScheduleNextTraceRequest (pLib));
2085}
2086
2087static int SuperTraceClearCall (void* hLib, int Channel) {
2088        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2089
2090        if ((Channel < 1) || (Channel > pLib->Channels)) {
2091                return (-1);
2092        }
2093        Channel--;
2094
2095        pLib->clear_call_command |= (1L << Channel);
2096
2097        return (ScheduleNextTraceRequest (pLib));
2098}
2099
2100/*
2101        Parse and update cumulative statistice
2102        */
2103static int diva_ifc_statistics (diva_strace_context_t* pLib,
2104                                                                                                                                diva_man_var_header_t* pVar) {
2105        diva_man_var_header_t* cur;
2106        int i, one_updated = 0, mdm_updated = 0, fax_updated = 0;
2107
2108        for (i  = pLib->statistic_parse_first; i <= pLib->statistic_parse_last; i++) {
2109                if ((cur = find_var (pVar, pLib->parse_table[i].path))) {
2110                        if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) {
2111                                diva_trace_error (pLib, -3 , __FILE__, __LINE__);
2112                                return (-1);
2113                        }
2114                        one_updated = 1;
2115      if ((i >= pLib->mdm_statistic_parse_first) && (i <= pLib->mdm_statistic_parse_last)) {
2116        mdm_updated = 1;
2117      }
2118      if ((i >= pLib->fax_statistic_parse_first) && (i <= pLib->fax_statistic_parse_last)) {
2119        fax_updated = 1;
2120      }
2121                }
2122        }
2123
2124        /*
2125                We do not use first event to notify user - this is the event that is
2126                generated as result of EVENT ON operation and is used only to initialize
2127                internal variables of application
2128                */
2129  if (mdm_updated) {
2130                diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE);
2131  } else if (fax_updated) {
2132                diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE);
2133  } else if (one_updated) {
2134                diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE);
2135        }
2136
2137        return (one_updated ? 0 : -1);
2138}
2139
2140static int SuperTraceGetOutgoingCallStatistics (void* hLib) {
2141        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2142        pLib->outgoing_ifc_stats = 1;
2143        return (ScheduleNextTraceRequest (pLib));
2144}
2145
2146static int SuperTraceGetIncomingCallStatistics (void* hLib) {
2147        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2148        pLib->incoming_ifc_stats = 1;
2149        return (ScheduleNextTraceRequest (pLib));
2150}
2151
2152static int SuperTraceGetModemStatistics (void* hLib) {
2153        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2154        pLib->modem_ifc_stats = 1;
2155        return (ScheduleNextTraceRequest (pLib));
2156}
2157
2158static int SuperTraceGetFaxStatistics (void* hLib) {
2159        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2160        pLib->fax_ifc_stats = 1;
2161        return (ScheduleNextTraceRequest (pLib));
2162}
2163
2164static int SuperTraceGetBLayer1Statistics (void* hLib) {
2165        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2166        pLib->b1_ifc_stats = 1;
2167        return (ScheduleNextTraceRequest (pLib));
2168}
2169
2170static int SuperTraceGetBLayer2Statistics (void* hLib) {
2171        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2172        pLib->b2_ifc_stats = 1;
2173        return (ScheduleNextTraceRequest (pLib));
2174}
2175
2176static int SuperTraceGetDLayer1Statistics (void* hLib) {
2177        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2178        pLib->d1_ifc_stats = 1;
2179        return (ScheduleNextTraceRequest (pLib));
2180}
2181
2182static int SuperTraceGetDLayer2Statistics (void* hLib) {
2183        diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
2184        pLib->d2_ifc_stats = 1;
2185        return (ScheduleNextTraceRequest (pLib));
2186}
2187
2188dword DivaSTraceGetMemotyRequirement (int channels) {
2189  dword parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \
2190                                                                                                 STAT_PARSE_ENTRIES + \
2191                                                                                                 LINE_PARSE_ENTRIES + 1) * channels;
2192  return (sizeof(diva_strace_context_t) + \
2193          (parse_entries * sizeof(diva_strace_path2action_t)));
2194}
2195
2196