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