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