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