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