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