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