]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/isdn/hardware/eicon/maintidi.c
isdn: eicon: Return on error
[net-next-2.6.git] / drivers / isdn / hardware / eicon / maintidi.c
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
33 extern 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         */
43 static int DivaSTraceLibraryStart (void* hLib);
44 static int DivaSTraceLibraryStop  (void* hLib);
45 static int SuperTraceLibraryFinit (void* hLib);
46 static void*    SuperTraceGetHandle (void* hLib);
47 static int SuperTraceMessageInput (void* hLib);
48 static int SuperTraceSetAudioTap  (void* hLib, int Channel, int on);
49 static int SuperTraceSetBChannel  (void* hLib, int Channel, int on);
50 static int SuperTraceSetDChannel  (void* hLib, int on);
51 static int SuperTraceSetInfo      (void* hLib, int on);
52 static int SuperTraceClearCall (void* hLib, int Channel);
53 static int SuperTraceGetOutgoingCallStatistics (void* hLib);
54 static int SuperTraceGetIncomingCallStatistics (void* hLib);
55 static int SuperTraceGetModemStatistics (void* hLib);
56 static int SuperTraceGetFaxStatistics (void* hLib);
57 static int SuperTraceGetBLayer1Statistics (void* hLib);
58 static int SuperTraceGetBLayer2Statistics (void* hLib);
59 static int SuperTraceGetDLayer1Statistics (void* hLib);
60 static int SuperTraceGetDLayer2Statistics (void* hLib);
61
62 /*
63         LOCAL FUNCTIONS
64         */
65 static int ScheduleNextTraceRequest (diva_strace_context_t* pLib);
66 static int process_idi_event (diva_strace_context_t* pLib,
67                                                                                                                         diva_man_var_header_t* pVar);
68 static int process_idi_info  (diva_strace_context_t* pLib,
69                                                                                                                         diva_man_var_header_t* pVar);
70 static int diva_modem_event (diva_strace_context_t* pLib, int Channel);
71 static int diva_fax_event   (diva_strace_context_t* pLib, int Channel);
72 static int diva_line_event (diva_strace_context_t* pLib, int Channel);
73 static int diva_modem_info (diva_strace_context_t* pLib,
74                                                                                                                 int Channel,
75                                                                                                                 diva_man_var_header_t* pVar);
76 static int diva_fax_info   (diva_strace_context_t* pLib,
77                                                                                                                 int Channel,
78                                                                                                                 diva_man_var_header_t* pVar);
79 static int diva_line_info  (diva_strace_context_t* pLib,
80                                                                                                                 int Channel,
81                                                                                                                 diva_man_var_header_t* pVar);
82 static int diva_ifc_statistics (diva_strace_context_t* pLib,
83                                                                                                                                 diva_man_var_header_t* pVar);
84 static diva_man_var_header_t* get_next_var (diva_man_var_header_t* pVar);
85 static diva_man_var_header_t* find_var (diva_man_var_header_t* pVar,
86                                                                                                                                                                 const char* name);
87 static int diva_strace_read_int  (diva_man_var_header_t* pVar, int* var);
88 static int diva_strace_read_uint (diva_man_var_header_t* pVar, dword* var);
89 static int diva_strace_read_asz  (diva_man_var_header_t* pVar, char* var);
90 static int diva_strace_read_asc  (diva_man_var_header_t* pVar, char* var);
91 static int  diva_strace_read_ie  (diva_man_var_header_t* pVar,
92                                                                                                                                         diva_trace_ie_t* var);
93 static void diva_create_parse_table (diva_strace_context_t* pLib);
94 static void diva_trace_error (diva_strace_context_t* pLib,
95                                                                                                                         int error, const char* file, int line);
96 static void diva_trace_notify_user (diva_strace_context_t* pLib,
97                                                                                                                  int Channel,
98                                                                                                                  int notify_subject);
99 static 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         */
108 diva_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
192 static 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   */
203 static 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
223 static 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
234 static 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         */
245 static int SuperTraceMessageInput (void* hLib) {
246         diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
247         int ret = 0;
248   byte Rc, Ind;
249
250   if (pLib->e.complete == 255) {
251     /*
252       Process return code
253       */
254     pLib->req_busy = 0;
255     Rc             = pLib->e.Rc;
256     pLib->e.Rc     = 0;
257
258     if (pLib->removal_state == 2) {
259       pLib->removal_state = 3;
260       return (0);
261     }
262
263                 if (Rc != pLib->rc_ok) {
264       int ignore = 0;
265       /*
266         Auto-detect amount of events/channels and features
267         */
268       if (pLib->general_b_ch_event == 1) {
269         pLib->general_b_ch_event = 2;
270         ignore = 1;
271       } else if (pLib->general_fax_event == 1) {
272         pLib->general_fax_event = 2;
273         ignore = 1;
274       } else if (pLib->general_mdm_event == 1) {
275         pLib->general_mdm_event = 2;
276         ignore = 1;
277       } else if ((pLib->ChannelsTraceActive < pLib->Channels) && pLib->ChannelsTraceActive) {
278         pLib->ChannelsTraceActive = pLib->Channels;
279         ignore = 1;
280       } else if (pLib->ModemTraceActive < pLib->Channels) {
281         pLib->ModemTraceActive = pLib->Channels;
282         ignore = 1;
283       } else if (pLib->FaxTraceActive < pLib->Channels) {
284         pLib->FaxTraceActive = pLib->Channels;
285         ignore = 1;
286       } else if (pLib->audio_trace_init == 2) {
287         ignore = 1;
288         pLib->audio_trace_init = 1;
289       } else if (pLib->eye_pattern_pending) {
290                                 pLib->eye_pattern_pending =  0;
291                                 ignore = 1;
292                         } else if (pLib->audio_tap_pending) {
293                                 pLib->audio_tap_pending = 0;
294                                 ignore = 1;
295       }
296
297       if (!ignore) {
298         return (-1); /* request failed */
299       }
300     } else {
301       if (pLib->general_b_ch_event == 1) {
302         pLib->ChannelsTraceActive = pLib->Channels;
303         pLib->general_b_ch_event = 2;
304       } else if (pLib->general_fax_event == 1) {
305         pLib->general_fax_event = 2;
306         pLib->FaxTraceActive = pLib->Channels;
307       } else if (pLib->general_mdm_event == 1) {
308         pLib->general_mdm_event = 2;
309         pLib->ModemTraceActive = pLib->Channels;
310       }
311     }
312     if (pLib->audio_trace_init == 2) {
313       pLib->audio_trace_init = 1;
314     }
315     pLib->rc_ok = 0xff; /* default OK after assign was done */
316     if ((ret = ScheduleNextTraceRequest(pLib))) {
317       return (-1);
318     }
319   } else {
320     /*
321       Process indication
322       Always 'RNR' indication if return code is pending
323       */
324     Ind         = pLib->e.Ind;
325     pLib->e.Ind = 0;
326     if (pLib->removal_state) {
327       pLib->e.RNum      = 0;
328       pLib->e.RNR       = 2;
329     } else if (pLib->req_busy) {
330       pLib->e.RNum      = 0;
331       pLib->e.RNR       = 1;
332     } else {
333       if (pLib->e.complete != 0x02) {
334         /*
335           Look-ahead call, set up buffers
336           */
337         pLib->e.RNum       = 1;
338         pLib->e.R->P       = (byte*)&pLib->buffer[0];
339         pLib->e.R->PLength = (word)(sizeof(pLib->buffer) - 1);
340
341       } else {
342         /*
343           Indication reception complete, process it now
344           */
345         byte* p = (byte*)&pLib->buffer[0];
346         pLib->buffer[pLib->e.R->PLength] = 0; /* terminate I.E. with zero */
347
348         switch (Ind) {
349           case MAN_COMBI_IND: {
350             int total_length    = pLib->e.R->PLength;
351             word  this_ind_length;
352
353             while (total_length > 3 && *p) {
354               Ind = *p++;
355               this_ind_length = (word)p[0] | ((word)p[1] << 8);
356               p += 2;
357
358               switch (Ind) {
359                 case MAN_INFO_IND:
360                   if (process_idi_info (pLib, (diva_man_var_header_t*)p)) {
361                     return (-1);
362                   }
363                   break;
364                                         case MAN_EVENT_IND:
365                   if (process_idi_event (pLib, (diva_man_var_header_t*)p)) {
366                     return (-1);
367                   }
368                   break;
369                 case MAN_TRACE_IND:
370                   if (pLib->trace_on == 1) {
371                     /*
372                       Ignore first trace event that is result of
373                       EVENT_ON operation
374                     */
375                     pLib->trace_on++;
376                   } else {
377                     /*
378                       Delivery XLOG buffer to application
379                       */
380                     if (pLib->user_proc_table.trace_proc) {
381                       (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
382                                                             &pLib->instance, pLib->Adapter,
383                                                             p, this_ind_length);
384                     }
385                   }
386                   break;
387                 default:
388                   diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind (DMA mode): %02x", Ind);
389               }
390               p += (this_ind_length+1);
391               total_length -= (4 + this_ind_length);
392             }
393           } break;
394           case MAN_INFO_IND:
395             if (process_idi_info (pLib, (diva_man_var_header_t*)p)) {
396               return (-1);
397             }
398             break;
399                                         case MAN_EVENT_IND:
400             if (process_idi_event (pLib, (diva_man_var_header_t*)p)) {
401               return (-1);
402             }
403             break;
404           case MAN_TRACE_IND:
405             if (pLib->trace_on == 1) {
406               /*
407                 Ignore first trace event that is result of
408                 EVENT_ON operation
409               */
410               pLib->trace_on++;
411             } else {
412               /*
413                 Delivery XLOG buffer to application
414                 */
415               if (pLib->user_proc_table.trace_proc) {
416                 (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
417                                                       &pLib->instance, pLib->Adapter,
418                                                       p, pLib->e.R->PLength);
419               }
420             }
421             break;
422           default:
423             diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind: %02x", Ind);
424         }
425       }
426     }
427   }
428
429         if ((ret = ScheduleNextTraceRequest(pLib))) {
430                 return (-1);
431         }
432
433         return (ret);
434 }
435
436 /*
437         Internal state machine responsible for scheduling of requests
438         */
439 static 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
855 static 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
1033 static int diva_line_event (diva_strace_context_t* pLib, int Channel) {
1034         pLib->pending_line_status |= (1L << (Channel-1));
1035         return (0);
1036 }
1037
1038 static int diva_modem_event (diva_strace_context_t* pLib, int Channel) {
1039         pLib->pending_modem_status |= (1L << (Channel-1));
1040         return (0);
1041 }
1042
1043 static 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         */
1053 static 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         */
1103 static 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
1136 static 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         */
1174 static 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         */
1216 static 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         */
1235 static 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
1250 static 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
1332 static 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
1396 static 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
1476 static 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
1853 static 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         */
1866 static 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         */
1881 static 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         */
1911 static 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
1939 static 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         */
1975 static 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         */
1993 static 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         */
2007 static 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
2019 static 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
2046 static 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
2063 static 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
2075 static 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
2087 static 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         */
2103 static 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
2140 static 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
2146 static 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
2152 static 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
2158 static 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
2164 static 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
2170 static 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
2176 static 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
2182 static 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
2188 dword 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