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