PageRenderTime 134ms CodeModel.GetById 2ms app.highlight 120ms RepoModel.GetById 1ms app.codeStats 1ms

/drivers/isdn/hardware/eicon/maintidi.c

http://github.com/mirrors/linux
C | 2194 lines | 1669 code | 317 blank | 208 comment | 271 complexity | e13d7a17df4538fbabd21aaecacdb040 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 *
   3 Copyright (c) Eicon Networks, 2000.
   4 *
   5 This source file is supplied for the use with
   6 Eicon Networks range of DIVA Server Adapters.
   7 *
   8 Eicon File Revision :    1.9
   9 *
  10 This program is free software; you can redistribute it and/or modify
  11 it under the terms of the GNU General Public License as published by
  12 the Free Software Foundation; either version 2, or (at your option)
  13 any later version.
  14 *
  15 This program is distributed in the hope that it will be useful,
  16 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
  17 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  18 See the GNU General Public License for more details.
  19 *
  20 You should have received a copy of the GNU General Public License
  21 along with this program; if not, write to the Free Software
  22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23 *
  24 */
  25#include "platform.h"
  26#include "kst_ifc.h"
  27#include "di_defs.h"
  28#include "maintidi.h"
  29#include "pc.h"
  30#include "man_defs.h"
  31
  32
  33extern void diva_mnt_internal_dprintf(dword drv_id, dword type, char *p, ...);
  34
  35#define MODEM_PARSE_ENTRIES  16 /* amount of variables of interest */
  36#define FAX_PARSE_ENTRIES    12 /* amount of variables of interest */
  37#define LINE_PARSE_ENTRIES   15 /* amount of variables of interest */
  38#define STAT_PARSE_ENTRIES   70 /* amount of variables of interest */
  39
  40/*
  41  LOCAL FUNCTIONS
  42*/
  43static int DivaSTraceLibraryStart(void *hLib);
  44static int DivaSTraceLibraryStop(void *hLib);
  45static int SuperTraceLibraryFinit(void *hLib);
  46static void *SuperTraceGetHandle(void *hLib);
  47static int SuperTraceMessageInput(void *hLib);
  48static int SuperTraceSetAudioTap(void *hLib, int Channel, int on);
  49static int SuperTraceSetBChannel(void *hLib, int Channel, int on);
  50static int SuperTraceSetDChannel(void *hLib, int on);
  51static int SuperTraceSetInfo(void *hLib, int on);
  52static int SuperTraceClearCall(void *hLib, int Channel);
  53static int SuperTraceGetOutgoingCallStatistics(void *hLib);
  54static int SuperTraceGetIncomingCallStatistics(void *hLib);
  55static int SuperTraceGetModemStatistics(void *hLib);
  56static int SuperTraceGetFaxStatistics(void *hLib);
  57static int SuperTraceGetBLayer1Statistics(void *hLib);
  58static int SuperTraceGetBLayer2Statistics(void *hLib);
  59static int SuperTraceGetDLayer1Statistics(void *hLib);
  60static int SuperTraceGetDLayer2Statistics(void *hLib);
  61
  62/*
  63  LOCAL FUNCTIONS
  64*/
  65static int ScheduleNextTraceRequest(diva_strace_context_t *pLib);
  66static int process_idi_event(diva_strace_context_t *pLib,
  67			     diva_man_var_header_t *pVar);
  68static int process_idi_info(diva_strace_context_t *pLib,
  69			    diva_man_var_header_t *pVar);
  70static int diva_modem_event(diva_strace_context_t *pLib, int Channel);
  71static int diva_fax_event(diva_strace_context_t *pLib, int Channel);
  72static int diva_line_event(diva_strace_context_t *pLib, int Channel);
  73static int diva_modem_info(diva_strace_context_t *pLib,
  74			   int Channel,
  75			   diva_man_var_header_t *pVar);
  76static int diva_fax_info(diva_strace_context_t *pLib,
  77			 int Channel,
  78			 diva_man_var_header_t *pVar);
  79static int diva_line_info(diva_strace_context_t *pLib,
  80			  int Channel,
  81			  diva_man_var_header_t *pVar);
  82static int diva_ifc_statistics(diva_strace_context_t *pLib,
  83			       diva_man_var_header_t *pVar);
  84static diva_man_var_header_t *get_next_var(diva_man_var_header_t *pVar);
  85static diva_man_var_header_t *find_var(diva_man_var_header_t *pVar,
  86				       const char *name);
  87static int diva_strace_read_int(diva_man_var_header_t *pVar, int *var);
  88static int diva_strace_read_uint(diva_man_var_header_t *pVar, dword *var);
  89static int diva_strace_read_asz(diva_man_var_header_t *pVar, char *var);
  90static int diva_strace_read_asc(diva_man_var_header_t *pVar, char *var);
  91static int diva_strace_read_ie(diva_man_var_header_t *pVar,
  92			       diva_trace_ie_t *var);
  93static void diva_create_parse_table(diva_strace_context_t *pLib);
  94static void diva_trace_error(diva_strace_context_t *pLib,
  95			     int error, const char *file, int line);
  96static void diva_trace_notify_user(diva_strace_context_t *pLib,
  97				   int Channel,
  98				   int notify_subject);
  99static int diva_trace_read_variable(diva_man_var_header_t *pVar,
 100				    void *variable);
 101
 102/*
 103  Initialize the library and return context
 104  of the created trace object that will represent
 105  the IDI adapter.
 106  Return 0 on error.
 107*/
 108diva_strace_library_interface_t *DivaSTraceLibraryCreateInstance(int Adapter,
 109								 const diva_trace_library_user_interface_t *user_proc,
 110								 byte *pmem) {
 111	diva_strace_context_t *pLib = (diva_strace_context_t *)pmem;
 112	int i;
 113
 114	if (!pLib) {
 115		return NULL;
 116	}
 117
 118	pmem += sizeof(*pLib);
 119	memset(pLib, 0x00, sizeof(*pLib));
 120
 121	pLib->Adapter  = Adapter;
 122
 123	/*
 124	  Set up Library Interface
 125	*/
 126	pLib->instance.hLib                                = pLib;
 127	pLib->instance.DivaSTraceLibraryStart              = DivaSTraceLibraryStart;
 128	pLib->instance.DivaSTraceLibraryStop               = DivaSTraceLibraryStop;
 129	pLib->instance.DivaSTraceLibraryFinit              = SuperTraceLibraryFinit;
 130	pLib->instance.DivaSTraceMessageInput              = SuperTraceMessageInput;
 131	pLib->instance.DivaSTraceGetHandle                 = SuperTraceGetHandle;
 132	pLib->instance.DivaSTraceSetAudioTap               = SuperTraceSetAudioTap;
 133	pLib->instance.DivaSTraceSetBChannel               = SuperTraceSetBChannel;
 134	pLib->instance.DivaSTraceSetDChannel               = SuperTraceSetDChannel;
 135	pLib->instance.DivaSTraceSetInfo                   = SuperTraceSetInfo;
 136	pLib->instance.DivaSTraceGetOutgoingCallStatistics = \
 137		SuperTraceGetOutgoingCallStatistics;
 138	pLib->instance.DivaSTraceGetIncomingCallStatistics = \
 139		SuperTraceGetIncomingCallStatistics;
 140	pLib->instance.DivaSTraceGetModemStatistics        = \
 141		SuperTraceGetModemStatistics;
 142	pLib->instance.DivaSTraceGetFaxStatistics          = \
 143		SuperTraceGetFaxStatistics;
 144	pLib->instance.DivaSTraceGetBLayer1Statistics      = \
 145		SuperTraceGetBLayer1Statistics;
 146	pLib->instance.DivaSTraceGetBLayer2Statistics      = \
 147		SuperTraceGetBLayer2Statistics;
 148	pLib->instance.DivaSTraceGetDLayer1Statistics      = \
 149		SuperTraceGetDLayer1Statistics;
 150	pLib->instance.DivaSTraceGetDLayer2Statistics      = \
 151		SuperTraceGetDLayer2Statistics;
 152	pLib->instance.DivaSTraceClearCall                 = SuperTraceClearCall;
 153
 154
 155	if (user_proc) {
 156		pLib->user_proc_table.user_context      = user_proc->user_context;
 157		pLib->user_proc_table.notify_proc       = user_proc->notify_proc;
 158		pLib->user_proc_table.trace_proc        = user_proc->trace_proc;
 159		pLib->user_proc_table.error_notify_proc = user_proc->error_notify_proc;
 160	}
 161
 162	if (!(pLib->hAdapter = SuperTraceOpenAdapter(Adapter))) {
 163		diva_mnt_internal_dprintf(0, DLI_ERR, "Can not open XDI adapter");
 164		return NULL;
 165	}
 166	pLib->Channels = SuperTraceGetNumberOfChannels(pLib->hAdapter);
 167
 168	/*
 169	  Calculate amount of parte table entites necessary to translate
 170	  information from all events of onterest
 171	*/
 172	pLib->parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \
 173			       STAT_PARSE_ENTRIES + \
 174			       LINE_PARSE_ENTRIES + 1) * pLib->Channels;
 175	pLib->parse_table = (diva_strace_path2action_t *)pmem;
 176
 177	for (i = 0; i < 30; i++) {
 178		pLib->lines[i].pInterface     = &pLib->Interface;
 179		pLib->lines[i].pInterfaceStat = &pLib->InterfaceStat;
 180	}
 181
 182	pLib->e.R = &pLib->RData;
 183
 184	pLib->req_busy = 1;
 185	pLib->rc_ok    = ASSIGN_OK;
 186
 187	diva_create_parse_table(pLib);
 188
 189	return ((diva_strace_library_interface_t *)pLib);
 190}
 191
 192static int DivaSTraceLibraryStart(void *hLib) {
 193	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 194
 195	return (SuperTraceASSIGN(pLib->hAdapter, pLib->buffer));
 196}
 197
 198/*
 199  Return (-1) on error
 200  Return (0) if was initiated or pending
 201  Return (1) if removal is complete
 202*/
 203static int DivaSTraceLibraryStop(void *hLib) {
 204	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 205
 206	if (!pLib->e.Id) { /* Was never started/assigned */
 207		return (1);
 208	}
 209
 210	switch (pLib->removal_state) {
 211	case 0:
 212		pLib->removal_state = 1;
 213		ScheduleNextTraceRequest(pLib);
 214		break;
 215
 216	case 3:
 217		return (1);
 218	}
 219
 220	return (0);
 221}
 222
 223static int SuperTraceLibraryFinit(void *hLib) {
 224	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 225	if (pLib) {
 226		if (pLib->hAdapter) {
 227			SuperTraceCloseAdapter(pLib->hAdapter);
 228		}
 229		return (0);
 230	}
 231	return (-1);
 232}
 233
 234static void *SuperTraceGetHandle(void *hLib) {
 235	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 236
 237	return (&pLib->e);
 238}
 239
 240/*
 241  After library handle object is gone in signaled state
 242  this function should be called and will pick up incoming
 243  IDI messages (return codes and indications).
 244*/
 245static int SuperTraceMessageInput(void *hLib) {
 246	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 247	int ret = 0;
 248	byte Rc, Ind;
 249
 250	if (pLib->e.complete == 255) {
 251		/*
 252		  Process return code
 253		*/
 254		pLib->req_busy = 0;
 255		Rc             = pLib->e.Rc;
 256		pLib->e.Rc     = 0;
 257
 258		if (pLib->removal_state == 2) {
 259			pLib->removal_state = 3;
 260			return (0);
 261		}
 262
 263		if (Rc != pLib->rc_ok) {
 264			int ignore = 0;
 265			/*
 266			  Auto-detect amount of events/channels and features
 267			*/
 268			if (pLib->general_b_ch_event == 1) {
 269				pLib->general_b_ch_event = 2;
 270				ignore = 1;
 271			} else if (pLib->general_fax_event == 1) {
 272				pLib->general_fax_event = 2;
 273				ignore = 1;
 274			} else if (pLib->general_mdm_event == 1) {
 275				pLib->general_mdm_event = 2;
 276				ignore = 1;
 277			} else if ((pLib->ChannelsTraceActive < pLib->Channels) && pLib->ChannelsTraceActive) {
 278				pLib->ChannelsTraceActive = pLib->Channels;
 279				ignore = 1;
 280			} else if (pLib->ModemTraceActive < pLib->Channels) {
 281				pLib->ModemTraceActive = pLib->Channels;
 282				ignore = 1;
 283			} else if (pLib->FaxTraceActive < pLib->Channels) {
 284				pLib->FaxTraceActive = pLib->Channels;
 285				ignore = 1;
 286			} else if (pLib->audio_trace_init == 2) {
 287				ignore = 1;
 288				pLib->audio_trace_init = 1;
 289			} else if (pLib->eye_pattern_pending) {
 290				pLib->eye_pattern_pending =  0;
 291				ignore = 1;
 292			} else if (pLib->audio_tap_pending) {
 293				pLib->audio_tap_pending = 0;
 294				ignore = 1;
 295			}
 296
 297			if (!ignore) {
 298				return (-1); /* request failed */
 299			}
 300		} else {
 301			if (pLib->general_b_ch_event == 1) {
 302				pLib->ChannelsTraceActive = pLib->Channels;
 303				pLib->general_b_ch_event = 2;
 304			} else if (pLib->general_fax_event == 1) {
 305				pLib->general_fax_event = 2;
 306				pLib->FaxTraceActive = pLib->Channels;
 307			} else if (pLib->general_mdm_event == 1) {
 308				pLib->general_mdm_event = 2;
 309				pLib->ModemTraceActive = pLib->Channels;
 310			}
 311		}
 312		if (pLib->audio_trace_init == 2) {
 313			pLib->audio_trace_init = 1;
 314		}
 315		pLib->rc_ok = 0xff; /* default OK after assign was done */
 316		if ((ret = ScheduleNextTraceRequest(pLib))) {
 317			return (-1);
 318		}
 319	} else {
 320		/*
 321		  Process indication
 322		  Always 'RNR' indication if return code is pending
 323		*/
 324		Ind         = pLib->e.Ind;
 325		pLib->e.Ind = 0;
 326		if (pLib->removal_state) {
 327			pLib->e.RNum	= 0;
 328			pLib->e.RNR	= 2;
 329		} else if (pLib->req_busy) {
 330			pLib->e.RNum	= 0;
 331			pLib->e.RNR	= 1;
 332		} else {
 333			if (pLib->e.complete != 0x02) {
 334				/*
 335				  Look-ahead call, set up buffers
 336				*/
 337				pLib->e.RNum       = 1;
 338				pLib->e.R->P       = (byte *)&pLib->buffer[0];
 339				pLib->e.R->PLength = (word)(sizeof(pLib->buffer) - 1);
 340
 341			} else {
 342				/*
 343				  Indication reception complete, process it now
 344				*/
 345				byte *p = (byte *)&pLib->buffer[0];
 346				pLib->buffer[pLib->e.R->PLength] = 0; /* terminate I.E. with zero */
 347
 348				switch (Ind) {
 349				case MAN_COMBI_IND: {
 350					int total_length    = pLib->e.R->PLength;
 351					word  this_ind_length;
 352
 353					while (total_length > 3 && *p) {
 354						Ind = *p++;
 355						this_ind_length = (word)p[0] | ((word)p[1] << 8);
 356						p += 2;
 357
 358						switch (Ind) {
 359						case MAN_INFO_IND:
 360							if (process_idi_info(pLib, (diva_man_var_header_t *)p)) {
 361								return (-1);
 362							}
 363							break;
 364						case MAN_EVENT_IND:
 365							if (process_idi_event(pLib, (diva_man_var_header_t *)p)) {
 366								return (-1);
 367							}
 368							break;
 369						case MAN_TRACE_IND:
 370							if (pLib->trace_on == 1) {
 371								/*
 372								  Ignore first trace event that is result of
 373								  EVENT_ON operation
 374								*/
 375								pLib->trace_on++;
 376							} else {
 377								/*
 378								  Delivery XLOG buffer to application
 379								*/
 380								if (pLib->user_proc_table.trace_proc) {
 381									(*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
 382													      &pLib->instance, pLib->Adapter,
 383													      p, this_ind_length);
 384								}
 385							}
 386							break;
 387						default:
 388							diva_mnt_internal_dprintf(0, DLI_ERR, "Unknown IDI Ind (DMA mode): %02x", Ind);
 389						}
 390						p += (this_ind_length + 1);
 391						total_length -= (4 + this_ind_length);
 392					}
 393				} break;
 394				case MAN_INFO_IND:
 395					if (process_idi_info(pLib, (diva_man_var_header_t *)p)) {
 396						return (-1);
 397					}
 398					break;
 399				case MAN_EVENT_IND:
 400					if (process_idi_event(pLib, (diva_man_var_header_t *)p)) {
 401						return (-1);
 402					}
 403					break;
 404				case MAN_TRACE_IND:
 405					if (pLib->trace_on == 1) {
 406						/*
 407						  Ignore first trace event that is result of
 408						  EVENT_ON operation
 409						*/
 410						pLib->trace_on++;
 411					} else {
 412						/*
 413						  Delivery XLOG buffer to application
 414						*/
 415						if (pLib->user_proc_table.trace_proc) {
 416							(*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
 417											      &pLib->instance, pLib->Adapter,
 418											      p, pLib->e.R->PLength);
 419						}
 420					}
 421					break;
 422				default:
 423					diva_mnt_internal_dprintf(0, DLI_ERR, "Unknown IDI Ind: %02x", Ind);
 424				}
 425			}
 426		}
 427	}
 428
 429	if ((ret = ScheduleNextTraceRequest(pLib))) {
 430		return (-1);
 431	}
 432
 433	return (ret);
 434}
 435
 436/*
 437  Internal state machine responsible for scheduling of requests
 438*/
 439static int ScheduleNextTraceRequest(diva_strace_context_t *pLib) {
 440	char name[64];
 441	int ret = 0;
 442	int i;
 443
 444	if (pLib->req_busy) {
 445		return (0);
 446	}
 447
 448	if (pLib->removal_state == 1) {
 449		if (SuperTraceREMOVE(pLib->hAdapter)) {
 450			pLib->removal_state = 3;
 451		} else {
 452			pLib->req_busy = 1;
 453			pLib->removal_state = 2;
 454		}
 455		return (0);
 456	}
 457
 458	if (pLib->removal_state) {
 459		return (0);
 460	}
 461
 462	if (!pLib->general_b_ch_event) {
 463		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\B Event", pLib->buffer))) {
 464			return (-1);
 465		}
 466		pLib->general_b_ch_event = 1;
 467		pLib->req_busy = 1;
 468		return (0);
 469	}
 470
 471	if (!pLib->general_fax_event) {
 472		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\FAX Event", pLib->buffer))) {
 473			return (-1);
 474		}
 475		pLib->general_fax_event = 1;
 476		pLib->req_busy = 1;
 477		return (0);
 478	}
 479
 480	if (!pLib->general_mdm_event) {
 481		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\Modem Event", pLib->buffer))) {
 482			return (-1);
 483		}
 484		pLib->general_mdm_event = 1;
 485		pLib->req_busy = 1;
 486		return (0);
 487	}
 488
 489	if (pLib->ChannelsTraceActive < pLib->Channels) {
 490		pLib->ChannelsTraceActive++;
 491		sprintf(name, "State\\B%d\\Line", pLib->ChannelsTraceActive);
 492		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 493			pLib->ChannelsTraceActive--;
 494			return (-1);
 495		}
 496		pLib->req_busy = 1;
 497		return (0);
 498	}
 499
 500	if (pLib->ModemTraceActive < pLib->Channels) {
 501		pLib->ModemTraceActive++;
 502		sprintf(name, "State\\B%d\\Modem\\Event", pLib->ModemTraceActive);
 503		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 504			pLib->ModemTraceActive--;
 505			return (-1);
 506		}
 507		pLib->req_busy = 1;
 508		return (0);
 509	}
 510
 511	if (pLib->FaxTraceActive < pLib->Channels) {
 512		pLib->FaxTraceActive++;
 513		sprintf(name, "State\\B%d\\FAX\\Event", pLib->FaxTraceActive);
 514		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 515			pLib->FaxTraceActive--;
 516			return (-1);
 517		}
 518		pLib->req_busy = 1;
 519		return (0);
 520	}
 521
 522	if (!pLib->trace_mask_init) {
 523		word tmp = 0x0000;
 524		if (SuperTraceWriteVar(pLib->hAdapter,
 525				       pLib->buffer,
 526				       "Trace\\Event Enable",
 527				       &tmp,
 528				       0x87, /* MI_BITFLD */
 529					sizeof(tmp))) {
 530			return (-1);
 531		}
 532		pLib->trace_mask_init = 1;
 533		pLib->req_busy = 1;
 534		return (0);
 535	}
 536
 537	if (!pLib->audio_trace_init) {
 538		dword tmp = 0x00000000;
 539		if (SuperTraceWriteVar(pLib->hAdapter,
 540				       pLib->buffer,
 541				       "Trace\\AudioCh# Enable",
 542				       &tmp,
 543				       0x87, /* MI_BITFLD */
 544					sizeof(tmp))) {
 545			return (-1);
 546		}
 547		pLib->audio_trace_init = 2;
 548		pLib->req_busy = 1;
 549		return (0);
 550	}
 551
 552	if (!pLib->bchannel_init) {
 553		dword tmp = 0x00000000;
 554		if (SuperTraceWriteVar(pLib->hAdapter,
 555				       pLib->buffer,
 556				       "Trace\\B-Ch# Enable",
 557				       &tmp,
 558				       0x87, /* MI_BITFLD */
 559					sizeof(tmp))) {
 560			return (-1);
 561		}
 562		pLib->bchannel_init = 1;
 563		pLib->req_busy = 1;
 564		return (0);
 565	}
 566
 567	if (!pLib->trace_length_init) {
 568		word tmp = 30;
 569		if (SuperTraceWriteVar(pLib->hAdapter,
 570				       pLib->buffer,
 571				       "Trace\\Max Log Length",
 572				       &tmp,
 573				       0x82, /* MI_UINT */
 574					sizeof(tmp))) {
 575			return (-1);
 576		}
 577		pLib->trace_length_init = 1;
 578		pLib->req_busy = 1;
 579		return (0);
 580	}
 581
 582	if (!pLib->trace_on) {
 583		if (SuperTraceTraceOnRequest(pLib->hAdapter,
 584					     "Trace\\Log Buffer",
 585					     pLib->buffer)) {
 586			return (-1);
 587		}
 588		pLib->trace_on = 1;
 589		pLib->req_busy = 1;
 590		return (0);
 591	}
 592
 593	if (pLib->trace_event_mask != pLib->current_trace_event_mask) {
 594		if (SuperTraceWriteVar(pLib->hAdapter,
 595				       pLib->buffer,
 596				       "Trace\\Event Enable",
 597				       &pLib->trace_event_mask,
 598				       0x87, /* MI_BITFLD */
 599					sizeof(pLib->trace_event_mask))) {
 600			return (-1);
 601		}
 602		pLib->current_trace_event_mask = pLib->trace_event_mask;
 603		pLib->req_busy = 1;
 604		return (0);
 605	}
 606
 607	if ((pLib->audio_tap_pending >= 0) && (pLib->audio_tap_mask != pLib->current_audio_tap_mask)) {
 608		if (SuperTraceWriteVar(pLib->hAdapter,
 609				       pLib->buffer,
 610				       "Trace\\AudioCh# Enable",
 611				       &pLib->audio_tap_mask,
 612				       0x87, /* MI_BITFLD */
 613					sizeof(pLib->audio_tap_mask))) {
 614			return (-1);
 615		}
 616		pLib->current_audio_tap_mask = pLib->audio_tap_mask;
 617		pLib->audio_tap_pending = 1;
 618		pLib->req_busy = 1;
 619		return (0);
 620	}
 621
 622	if ((pLib->eye_pattern_pending >= 0) && (pLib->audio_tap_mask != pLib->current_eye_pattern_mask)) {
 623		if (SuperTraceWriteVar(pLib->hAdapter,
 624				       pLib->buffer,
 625				       "Trace\\EyeCh# Enable",
 626				       &pLib->audio_tap_mask,
 627				       0x87, /* MI_BITFLD */
 628					sizeof(pLib->audio_tap_mask))) {
 629			return (-1);
 630		}
 631		pLib->current_eye_pattern_mask = pLib->audio_tap_mask;
 632		pLib->eye_pattern_pending = 1;
 633		pLib->req_busy = 1;
 634		return (0);
 635	}
 636
 637	if (pLib->bchannel_trace_mask != pLib->current_bchannel_trace_mask) {
 638		if (SuperTraceWriteVar(pLib->hAdapter,
 639				       pLib->buffer,
 640				       "Trace\\B-Ch# Enable",
 641				       &pLib->bchannel_trace_mask,
 642				       0x87, /* MI_BITFLD */
 643					sizeof(pLib->bchannel_trace_mask))) {
 644			return (-1);
 645		}
 646		pLib->current_bchannel_trace_mask = pLib->bchannel_trace_mask;
 647		pLib->req_busy = 1;
 648		return (0);
 649	}
 650
 651	if (!pLib->trace_events_down) {
 652		if (SuperTraceTraceOnRequest(pLib->hAdapter,
 653					     "Events Down",
 654					     pLib->buffer)) {
 655			return (-1);
 656		}
 657		pLib->trace_events_down = 1;
 658		pLib->req_busy = 1;
 659		return (0);
 660	}
 661
 662	if (!pLib->l1_trace) {
 663		if (SuperTraceTraceOnRequest(pLib->hAdapter,
 664					     "State\\Layer1",
 665					     pLib->buffer)) {
 666			return (-1);
 667		}
 668		pLib->l1_trace = 1;
 669		pLib->req_busy = 1;
 670		return (0);
 671	}
 672
 673	if (!pLib->l2_trace) {
 674		if (SuperTraceTraceOnRequest(pLib->hAdapter,
 675					     "State\\Layer2 No1",
 676					     pLib->buffer)) {
 677			return (-1);
 678		}
 679		pLib->l2_trace = 1;
 680		pLib->req_busy = 1;
 681		return (0);
 682	}
 683
 684	for (i = 0; i < 30; i++) {
 685		if (pLib->pending_line_status & (1L << i)) {
 686			sprintf(name, "State\\B%d", i + 1);
 687			if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
 688				return (-1);
 689			}
 690			pLib->pending_line_status &= ~(1L << i);
 691			pLib->req_busy = 1;
 692			return (0);
 693		}
 694		if (pLib->pending_modem_status & (1L << i)) {
 695			sprintf(name, "State\\B%d\\Modem", i + 1);
 696			if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
 697				return (-1);
 698			}
 699			pLib->pending_modem_status &= ~(1L << i);
 700			pLib->req_busy = 1;
 701			return (0);
 702		}
 703		if (pLib->pending_fax_status & (1L << i)) {
 704			sprintf(name, "State\\B%d\\FAX", i + 1);
 705			if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
 706				return (-1);
 707			}
 708			pLib->pending_fax_status &= ~(1L << i);
 709			pLib->req_busy = 1;
 710			return (0);
 711		}
 712		if (pLib->clear_call_command & (1L << i)) {
 713			sprintf(name, "State\\B%d\\Clear Call", i + 1);
 714			if (SuperTraceExecuteRequest(pLib->hAdapter, name, pLib->buffer)) {
 715				return (-1);
 716			}
 717			pLib->clear_call_command &= ~(1L << i);
 718			pLib->req_busy = 1;
 719			return (0);
 720		}
 721	}
 722
 723	if (pLib->outgoing_ifc_stats) {
 724		if (SuperTraceReadRequest(pLib->hAdapter,
 725					  "Statistics\\Outgoing Calls",
 726					  pLib->buffer)) {
 727			return (-1);
 728		}
 729		pLib->outgoing_ifc_stats = 0;
 730		pLib->req_busy = 1;
 731		return (0);
 732	}
 733
 734	if (pLib->incoming_ifc_stats) {
 735		if (SuperTraceReadRequest(pLib->hAdapter,
 736					  "Statistics\\Incoming Calls",
 737					  pLib->buffer)) {
 738			return (-1);
 739		}
 740		pLib->incoming_ifc_stats = 0;
 741		pLib->req_busy = 1;
 742		return (0);
 743	}
 744
 745	if (pLib->modem_ifc_stats) {
 746		if (SuperTraceReadRequest(pLib->hAdapter,
 747					  "Statistics\\Modem",
 748					  pLib->buffer)) {
 749			return (-1);
 750		}
 751		pLib->modem_ifc_stats = 0;
 752		pLib->req_busy = 1;
 753		return (0);
 754	}
 755
 756	if (pLib->fax_ifc_stats) {
 757		if (SuperTraceReadRequest(pLib->hAdapter,
 758					  "Statistics\\FAX",
 759					  pLib->buffer)) {
 760			return (-1);
 761		}
 762		pLib->fax_ifc_stats = 0;
 763		pLib->req_busy = 1;
 764		return (0);
 765	}
 766
 767	if (pLib->b1_ifc_stats) {
 768		if (SuperTraceReadRequest(pLib->hAdapter,
 769					  "Statistics\\B-Layer1",
 770					  pLib->buffer)) {
 771			return (-1);
 772		}
 773		pLib->b1_ifc_stats = 0;
 774		pLib->req_busy = 1;
 775		return (0);
 776	}
 777
 778	if (pLib->b2_ifc_stats) {
 779		if (SuperTraceReadRequest(pLib->hAdapter,
 780					  "Statistics\\B-Layer2",
 781					  pLib->buffer)) {
 782			return (-1);
 783		}
 784		pLib->b2_ifc_stats = 0;
 785		pLib->req_busy = 1;
 786		return (0);
 787	}
 788
 789	if (pLib->d1_ifc_stats) {
 790		if (SuperTraceReadRequest(pLib->hAdapter,
 791					  "Statistics\\D-Layer1",
 792					  pLib->buffer)) {
 793			return (-1);
 794		}
 795		pLib->d1_ifc_stats = 0;
 796		pLib->req_busy = 1;
 797		return (0);
 798	}
 799
 800	if (pLib->d2_ifc_stats) {
 801		if (SuperTraceReadRequest(pLib->hAdapter,
 802					  "Statistics\\D-Layer2",
 803					  pLib->buffer)) {
 804			return (-1);
 805		}
 806		pLib->d2_ifc_stats = 0;
 807		pLib->req_busy = 1;
 808		return (0);
 809	}
 810
 811	if (!pLib->IncomingCallsCallsActive) {
 812		pLib->IncomingCallsCallsActive = 1;
 813		sprintf(name, "%s", "Statistics\\Incoming Calls\\Calls");
 814		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 815			pLib->IncomingCallsCallsActive = 0;
 816			return (-1);
 817		}
 818		pLib->req_busy = 1;
 819		return (0);
 820	}
 821	if (!pLib->IncomingCallsConnectedActive) {
 822		pLib->IncomingCallsConnectedActive = 1;
 823		sprintf(name, "%s", "Statistics\\Incoming Calls\\Connected");
 824		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 825			pLib->IncomingCallsConnectedActive = 0;
 826			return (-1);
 827		}
 828		pLib->req_busy = 1;
 829		return (0);
 830	}
 831	if (!pLib->OutgoingCallsCallsActive) {
 832		pLib->OutgoingCallsCallsActive = 1;
 833		sprintf(name, "%s", "Statistics\\Outgoing Calls\\Calls");
 834		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 835			pLib->OutgoingCallsCallsActive = 0;
 836			return (-1);
 837		}
 838		pLib->req_busy = 1;
 839		return (0);
 840	}
 841	if (!pLib->OutgoingCallsConnectedActive) {
 842		pLib->OutgoingCallsConnectedActive = 1;
 843		sprintf(name, "%s", "Statistics\\Outgoing Calls\\Connected");
 844		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 845			pLib->OutgoingCallsConnectedActive = 0;
 846			return (-1);
 847		}
 848		pLib->req_busy = 1;
 849		return (0);
 850	}
 851
 852	return (0);
 853}
 854
 855static int process_idi_event(diva_strace_context_t *pLib,
 856			     diva_man_var_header_t *pVar) {
 857	const char *path = (char *)&pVar->path_length + 1;
 858	char name[64];
 859	int i;
 860
 861	if (!strncmp("State\\B Event", path, pVar->path_length)) {
 862		dword ch_id;
 863		if (!diva_trace_read_variable(pVar, &ch_id)) {
 864			if (!pLib->line_init_event && !pLib->pending_line_status) {
 865				for (i = 1; i <= pLib->Channels; i++) {
 866					diva_line_event(pLib, i);
 867				}
 868				return (0);
 869			} else if (ch_id && ch_id <= pLib->Channels) {
 870				return (diva_line_event(pLib, (int)ch_id));
 871			}
 872			return (0);
 873		}
 874		return (-1);
 875	}
 876
 877	if (!strncmp("State\\FAX Event", path, pVar->path_length)) {
 878		dword ch_id;
 879		if (!diva_trace_read_variable(pVar, &ch_id)) {
 880			if (!pLib->pending_fax_status && !pLib->fax_init_event) {
 881				for (i = 1; i <= pLib->Channels; i++) {
 882					diva_fax_event(pLib, i);
 883				}
 884				return (0);
 885			} else if (ch_id && ch_id <= pLib->Channels) {
 886				return (diva_fax_event(pLib, (int)ch_id));
 887			}
 888			return (0);
 889		}
 890		return (-1);
 891	}
 892
 893	if (!strncmp("State\\Modem Event", path, pVar->path_length)) {
 894		dword ch_id;
 895		if (!diva_trace_read_variable(pVar, &ch_id)) {
 896			if (!pLib->pending_modem_status && !pLib->modem_init_event) {
 897				for (i = 1; i <= pLib->Channels; i++) {
 898					diva_modem_event(pLib, i);
 899				}
 900				return (0);
 901			} else if (ch_id && ch_id <= pLib->Channels) {
 902				return (diva_modem_event(pLib, (int)ch_id));
 903			}
 904			return (0);
 905		}
 906		return (-1);
 907	}
 908
 909	/*
 910	  First look for Line Event
 911	*/
 912	for (i = 1; i <= pLib->Channels; i++) {
 913		sprintf(name, "State\\B%d\\Line", i);
 914		if (find_var(pVar, name)) {
 915			return (diva_line_event(pLib, i));
 916		}
 917	}
 918
 919	/*
 920	  Look for Moden Progress Event
 921	*/
 922	for (i = 1; i <= pLib->Channels; i++) {
 923		sprintf(name, "State\\B%d\\Modem\\Event", i);
 924		if (find_var(pVar, name)) {
 925			return (diva_modem_event(pLib, i));
 926		}
 927	}
 928
 929	/*
 930	  Look for Fax Event
 931	*/
 932	for (i = 1; i <= pLib->Channels; i++) {
 933		sprintf(name, "State\\B%d\\FAX\\Event", i);
 934		if (find_var(pVar, name)) {
 935			return (diva_fax_event(pLib, i));
 936		}
 937	}
 938
 939	/*
 940	  Notification about loss of events
 941	*/
 942	if (!strncmp("Events Down", path, pVar->path_length)) {
 943		if (pLib->trace_events_down == 1) {
 944			pLib->trace_events_down = 2;
 945		} else {
 946			diva_trace_error(pLib, 1, "Events Down", 0);
 947		}
 948		return (0);
 949	}
 950
 951	if (!strncmp("State\\Layer1", path, pVar->path_length)) {
 952		diva_strace_read_asz(pVar, &pLib->lines[0].pInterface->Layer1[0]);
 953		if (pLib->l1_trace == 1) {
 954			pLib->l1_trace = 2;
 955		} else {
 956			diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
 957		}
 958		return (0);
 959	}
 960	if (!strncmp("State\\Layer2 No1", path, pVar->path_length)) {
 961		char *tmp = &pLib->lines[0].pInterface->Layer2[0];
 962		dword l2_state;
 963		if (diva_strace_read_uint(pVar, &l2_state))
 964			return -1;
 965
 966		switch (l2_state) {
 967		case 0:
 968			strcpy(tmp, "Idle");
 969			break;
 970		case 1:
 971			strcpy(tmp, "Layer2 UP");
 972			break;
 973		case 2:
 974			strcpy(tmp, "Layer2 Disconnecting");
 975			break;
 976		case 3:
 977			strcpy(tmp, "Layer2 Connecting");
 978			break;
 979		case 4:
 980			strcpy(tmp, "SPID Initializing");
 981			break;
 982		case 5:
 983			strcpy(tmp, "SPID Initialised");
 984			break;
 985		case 6:
 986			strcpy(tmp, "Layer2 Connecting");
 987			break;
 988
 989		case  7:
 990			strcpy(tmp, "Auto SPID Stopped");
 991			break;
 992
 993		case  8:
 994			strcpy(tmp, "Auto SPID Idle");
 995			break;
 996
 997		case  9:
 998			strcpy(tmp, "Auto SPID Requested");
 999			break;
1000
1001		case  10:
1002			strcpy(tmp, "Auto SPID Delivery");
1003			break;
1004
1005		case 11:
1006			strcpy(tmp, "Auto SPID Complete");
1007			break;
1008
1009		default:
1010			sprintf(tmp, "U:%d", (int)l2_state);
1011		}
1012		if (pLib->l2_trace == 1) {
1013			pLib->l2_trace = 2;
1014		} else {
1015			diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
1016		}
1017		return (0);
1018	}
1019
1020	if (!strncmp("Statistics\\Incoming Calls\\Calls", path, pVar->path_length) ||
1021	    !strncmp("Statistics\\Incoming Calls\\Connected", path, pVar->path_length)) {
1022		return (SuperTraceGetIncomingCallStatistics(pLib));
1023	}
1024
1025	if (!strncmp("Statistics\\Outgoing Calls\\Calls", path, pVar->path_length) ||
1026	    !strncmp("Statistics\\Outgoing Calls\\Connected", path, pVar->path_length)) {
1027		return (SuperTraceGetOutgoingCallStatistics(pLib));
1028	}
1029
1030	return (-1);
1031}
1032
1033static int diva_line_event(diva_strace_context_t *pLib, int Channel) {
1034	pLib->pending_line_status |= (1L << (Channel - 1));
1035	return (0);
1036}
1037
1038static int diva_modem_event(diva_strace_context_t *pLib, int Channel) {
1039	pLib->pending_modem_status |= (1L << (Channel - 1));
1040	return (0);
1041}
1042
1043static int diva_fax_event(diva_strace_context_t *pLib, int Channel) {
1044	pLib->pending_fax_status |= (1L << (Channel - 1));
1045	return (0);
1046}
1047
1048/*
1049  Process INFO indications that arrive from the card
1050  Uses path of first I.E. to detect the source of the
1051  infication
1052*/
1053static int process_idi_info(diva_strace_context_t *pLib,
1054			    diva_man_var_header_t *pVar) {
1055	const char *path = (char *)&pVar->path_length + 1;
1056	char name[64];
1057	int i, len;
1058
1059	/*
1060	  First look for Modem Status Info
1061	*/
1062	for (i = pLib->Channels; i > 0; i--) {
1063		len = sprintf(name, "State\\B%d\\Modem", i);
1064		if (!strncmp(name, path, len)) {
1065			return (diva_modem_info(pLib, i, pVar));
1066		}
1067	}
1068
1069	/*
1070	  Look for Fax Status Info
1071	*/
1072	for (i = pLib->Channels; i > 0; i--) {
1073		len = sprintf(name, "State\\B%d\\FAX", i);
1074		if (!strncmp(name, path, len)) {
1075			return (diva_fax_info(pLib, i, pVar));
1076		}
1077	}
1078
1079	/*
1080	  Look for Line Status Info
1081	*/
1082	for (i = pLib->Channels; i > 0; i--) {
1083		len = sprintf(name, "State\\B%d", i);
1084		if (!strncmp(name, path, len)) {
1085			return (diva_line_info(pLib, i, pVar));
1086		}
1087	}
1088
1089	if (!diva_ifc_statistics(pLib, pVar)) {
1090		return (0);
1091	}
1092
1093	return (-1);
1094}
1095
1096/*
1097  MODEM INSTANCE STATE UPDATE
1098
1099  Update Modem Status Information and issue notification to user,
1100  that will inform about change in the state of modem instance, that is
1101  associuated with this channel
1102*/
1103static int diva_modem_info(diva_strace_context_t *pLib,
1104			   int Channel,
1105			   diva_man_var_header_t *pVar) {
1106	diva_man_var_header_t *cur;
1107	int i, nr = Channel - 1;
1108
1109	for (i  = pLib->modem_parse_entry_first[nr];
1110	     i <= pLib->modem_parse_entry_last[nr]; i++) {
1111		if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
1112			if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
1113				diva_trace_error(pLib, -3, __FILE__, __LINE__);
1114				return (-1);
1115			}
1116		} else {
1117			diva_trace_error(pLib, -2, __FILE__, __LINE__);
1118			return (-1);
1119		}
1120	}
1121
1122	/*
1123	  We do not use first event to notify user - this is the event that is
1124	  generated as result of EVENT ON operation and is used only to initialize
1125	  internal variables of application
1126	*/
1127	if (pLib->modem_init_event & (1L << nr)) {
1128		diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE);
1129	} else {
1130		pLib->modem_init_event |= (1L << nr);
1131	}
1132
1133	return (0);
1134}
1135
1136static int diva_fax_info(diva_strace_context_t *pLib,
1137			 int Channel,
1138			 diva_man_var_header_t *pVar) {
1139	diva_man_var_header_t *cur;
1140	int i, nr = Channel - 1;
1141
1142	for (i  = pLib->fax_parse_entry_first[nr];
1143	     i <= pLib->fax_parse_entry_last[nr]; i++) {
1144		if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
1145			if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
1146				diva_trace_error(pLib, -3, __FILE__, __LINE__);
1147				return (-1);
1148			}
1149		} else {
1150			diva_trace_error(pLib, -2, __FILE__, __LINE__);
1151			return (-1);
1152		}
1153	}
1154
1155	/*
1156	  We do not use first event to notify user - this is the event that is
1157	  generated as result of EVENT ON operation and is used only to initialize
1158	  internal variables of application
1159	*/
1160	if (pLib->fax_init_event & (1L << nr)) {
1161		diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE);
1162	} else {
1163		pLib->fax_init_event |= (1L << nr);
1164	}
1165
1166	return (0);
1167}
1168
1169/*
1170  LINE STATE UPDATE
1171  Update Line Status Information and issue notification to user,
1172  that will inform about change in the line state.
1173*/
1174static int diva_line_info(diva_strace_context_t *pLib,
1175			  int Channel,
1176			  diva_man_var_header_t *pVar) {
1177	diva_man_var_header_t *cur;
1178	int i, nr = Channel - 1;
1179
1180	for (i = pLib->line_parse_entry_first[nr];
1181	     i <= pLib->line_parse_entry_last[nr]; i++) {
1182		if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
1183			if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
1184				diva_trace_error(pLib, -3, __FILE__, __LINE__);
1185				return (-1);
1186			}
1187		} else {
1188			diva_trace_error(pLib, -2 , __FILE__, __LINE__);
1189			return (-1);
1190		}
1191	}
1192
1193	/*
1194	  We do not use first event to notify user - this is the event that is
1195	  generated as result of EVENT ON operation and is used only to initialize
1196	  internal variables of application
1197
1198	  Exception is is if the line is "online". In this case we have to notify
1199	  user about this confition.
1200	*/
1201	if (pLib->line_init_event & (1L << nr)) {
1202		diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
1203	} else {
1204		pLib->line_init_event |= (1L << nr);
1205		if (strcmp(&pLib->lines[nr].Line[0], "Idle")) {
1206			diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
1207		}
1208	}
1209
1210	return (0);
1211}
1212
1213/*
1214  Move position to next vatianle in the chain
1215*/
1216static diva_man_var_header_t *get_next_var(diva_man_var_header_t *pVar) {
1217	byte *msg = (byte *)pVar;
1218	byte *start;
1219	int msg_length;
1220
1221	if (*msg != ESC) return NULL;
1222
1223	start = msg + 2;
1224	msg_length = *(msg + 1);
1225	msg = (start + msg_length);
1226
1227	if (*msg != ESC) return NULL;
1228
1229	return ((diva_man_var_header_t *)msg);
1230}
1231
1232/*
1233  Move position to variable with given name
1234*/
1235static diva_man_var_header_t *find_var(diva_man_var_header_t *pVar,
1236				       const char *name) {
1237	const char *path;
1238
1239	do {
1240		path = (char *)&pVar->path_length + 1;
1241
1242		if (!strncmp(name, path, pVar->path_length)) {
1243			break;
1244		}
1245	} while ((pVar = get_next_var(pVar)));
1246
1247	return (pVar);
1248}
1249
1250static void diva_create_line_parse_table(diva_strace_context_t *pLib,
1251					 int Channel) {
1252	diva_trace_line_state_t *pLine = &pLib->lines[Channel];
1253	int nr = Channel + 1;
1254
1255	if ((pLib->cur_parse_entry + LINE_PARSE_ENTRIES) >= pLib->parse_entries) {
1256		diva_trace_error(pLib, -1, __FILE__, __LINE__);
1257		return;
1258	}
1259
1260	pLine->ChannelNumber = nr;
1261
1262	pLib->line_parse_entry_first[Channel] = pLib->cur_parse_entry;
1263
1264	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1265		"State\\B%d\\Framing", nr);
1266	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Framing[0];
1267
1268	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1269		"State\\B%d\\Line", nr);
1270	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Line[0];
1271
1272	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1273		"State\\B%d\\Layer2", nr);
1274	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer2[0];
1275
1276	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1277		"State\\B%d\\Layer3", nr);
1278	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer3[0];
1279
1280	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1281		"State\\B%d\\Remote Address", nr);
1282	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1283		&pLine->RemoteAddress[0];
1284
1285	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1286		"State\\B%d\\Remote SubAddr", nr);
1287	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1288		&pLine->RemoteSubAddress[0];
1289
1290	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1291		"State\\B%d\\Local Address", nr);
1292	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1293		&pLine->LocalAddress[0];
1294
1295	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1296		"State\\B%d\\Local SubAddr", nr);
1297	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1298		&pLine->LocalSubAddress[0];
1299
1300	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1301		"State\\B%d\\BC", nr);
1302	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_BC;
1303
1304	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1305		"State\\B%d\\HLC", nr);
1306	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_HLC;
1307
1308	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1309		"State\\B%d\\LLC", nr);
1310	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_LLC;
1311
1312	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1313		"State\\B%d\\Charges", nr);
1314	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Charges;
1315
1316	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1317		"State\\B%d\\Call Reference", nr);
1318	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->CallReference;
1319
1320	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1321		"State\\B%d\\Last Disc Cause", nr);
1322	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1323		&pLine->LastDisconnecCause;
1324
1325	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1326		"State\\B%d\\User ID", nr);
1327	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->UserID[0];
1328
1329	pLib->line_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1330}
1331
1332static void diva_create_fax_parse_table(diva_strace_context_t *pLib,
1333					int Channel) {
1334	diva_trace_fax_state_t *pFax = &pLib->lines[Channel].fax;
1335	int nr = Channel + 1;
1336
1337	if ((pLib->cur_parse_entry + FAX_PARSE_ENTRIES) >= pLib->parse_entries) {
1338		diva_trace_error(pLib, -1, __FILE__, __LINE__);
1339		return;
1340	}
1341	pFax->ChannelNumber = nr;
1342
1343	pLib->fax_parse_entry_first[Channel] = pLib->cur_parse_entry;
1344
1345	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1346		"State\\B%d\\FAX\\Event", nr);
1347	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Event;
1348
1349	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1350		"State\\B%d\\FAX\\Page Counter", nr);
1351	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Page_Counter;
1352
1353	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1354		"State\\B%d\\FAX\\Features", nr);
1355	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Features;
1356
1357	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1358		"State\\B%d\\FAX\\Station ID", nr);
1359	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Station_ID[0];
1360
1361	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1362		"State\\B%d\\FAX\\Subaddress", nr);
1363	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Subaddress[0];
1364
1365	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1366		"State\\B%d\\FAX\\Password", nr);
1367	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Password[0];
1368
1369	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1370		"State\\B%d\\FAX\\Speed", nr);
1371	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Speed;
1372
1373	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1374		"State\\B%d\\FAX\\Resolution", nr);
1375	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Resolution;
1376
1377	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1378		"State\\B%d\\FAX\\Paper Width", nr);
1379	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Width;
1380
1381	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1382		"State\\B%d\\FAX\\Paper Length", nr);
1383	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Length;
1384
1385	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1386		"State\\B%d\\FAX\\Scanline Time", nr);
1387	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Scanline_Time;
1388
1389	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1390		"State\\B%d\\FAX\\Disc Reason", nr);
1391	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Disc_Reason;
1392
1393	pLib->fax_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1394}
1395
1396static void diva_create_modem_parse_table(diva_strace_context_t *pLib,
1397					  int Channel) {
1398	diva_trace_modem_state_t *pModem = &pLib->lines[Channel].modem;
1399	int nr = Channel + 1;
1400
1401	if ((pLib->cur_parse_entry + MODEM_PARSE_ENTRIES) >= pLib->parse_entries) {
1402		diva_trace_error(pLib, -1, __FILE__, __LINE__);
1403		return;
1404	}
1405	pModem->ChannelNumber = nr;
1406
1407	pLib->modem_parse_entry_first[Channel] = pLib->cur_parse_entry;
1408
1409	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1410		"State\\B%d\\Modem\\Event", nr);
1411	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Event;
1412
1413	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1414		"State\\B%d\\Modem\\Norm", nr);
1415	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Norm;
1416
1417	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1418		"State\\B%d\\Modem\\Options", nr);
1419	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Options;
1420
1421	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1422		"State\\B%d\\Modem\\TX Speed", nr);
1423	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->TxSpeed;
1424
1425	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1426		"State\\B%d\\Modem\\RX Speed", nr);
1427	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxSpeed;
1428
1429	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1430		"State\\B%d\\Modem\\Roundtrip ms", nr);
1431	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RoundtripMsec;
1432
1433	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1434		"State\\B%d\\Modem\\Symbol Rate", nr);
1435	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SymbolRate;
1436
1437	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1438		"State\\B%d\\Modem\\RX Level dBm", nr);
1439	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxLeveldBm;
1440
1441	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1442		"State\\B%d\\Modem\\Echo Level dBm", nr);
1443	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->EchoLeveldBm;
1444
1445	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1446		"State\\B%d\\Modem\\SNR dB", nr);
1447	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SNRdb;
1448
1449	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1450		"State\\B%d\\Modem\\MAE", nr);
1451	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->MAE;
1452
1453	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1454		"State\\B%d\\Modem\\Local Retrains", nr);
1455	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalRetrains;
1456
1457	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1458		"State\\B%d\\Modem\\Remote Retrains", nr);
1459	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteRetrains;
1460
1461	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1462		"State\\B%d\\Modem\\Local Resyncs", nr);
1463	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalResyncs;
1464
1465	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1466		"State\\B%d\\Modem\\Remote Resyncs", nr);
1467	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteResyncs;
1468
1469	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1470		"State\\B%d\\Modem\\Disc Reason", nr);
1471	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->DiscReason;
1472
1473	pLib->modem_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1474}
1475
1476static void diva_create_parse_table(diva_strace_context_t *pLib) {
1477	int i;
1478
1479	for (i = 0; i < pLib->Channels; i++) {
1480		diva_create_line_parse_table(pLib, i);
1481		diva_create_modem_parse_table(pLib, i);
1482		diva_create_fax_parse_table(pLib, i);
1483	}
1484
1485	pLib->statistic_parse_first = pLib->cur_parse_entry;
1486
1487	/*
1488	  Outgoing Calls
1489	*/
1490	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1491	       "Statistics\\Outgoing Calls\\Calls");
1492	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1493		&pLib->InterfaceStat.outg.Calls;
1494
1495	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1496	       "Statistics\\Outgoing Calls\\Connected");
1497	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1498		&pLib->InterfaceStat.outg.Connected;
1499
1500	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1501	       "Statistics\\Outgoing Calls\\User Busy");
1502	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1503		&pLib->InterfaceStat.outg.User_Busy;
1504
1505	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1506	       "Statistics\\Outgoing Calls\\No Answer");
1507	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1508		&pLib->InterfaceStat.outg.No_Answer;
1509
1510	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1511	       "Statistics\\Outgoing Calls\\Wrong Number");
1512	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1513		&pLib->InterfaceStat.outg.Wrong_Number;
1514
1515	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1516	       "Statistics\\Outgoing Calls\\Call Rejected");
1517	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1518		&pLib->InterfaceStat.outg.Call_Rejected;
1519
1520	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1521	       "Statistics\\Outgoing Calls\\Other Failures");
1522	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1523		&pLib->InterfaceStat.outg.Other_Failures;
1524
1525	/*
1526	  Incoming Calls
1527	*/
1528	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1529	       "Statistics\\Incoming Calls\\Calls");
1530	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1531		&pLib->InterfaceStat.inc.Calls;
1532
1533	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1534	       "Statistics\\Incoming Calls\\Connected");
1535	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1536		&pLib->InterfaceStat.inc.Connected;
1537
1538	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1539	       "Statistics\\Incoming Calls\\User Busy");
1540	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1541		&pLib->InterfaceStat.inc.User_Busy;
1542
1543	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1544	       "Statistics\\Incoming Calls\\Call Rejected");
1545	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1546		&pLib->InterfaceStat.inc.Call_Rejected;
1547
1548	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1549	       "Statistics\\Incoming Calls\\Wrong Number");
1550	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1551		&pLib->InterfaceStat.inc.Wrong_Number;
1552
1553	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1554	       "Statistics\\Incoming Calls\\Incompatible Dst");
1555	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1556		&pLib->InterfaceStat.inc.Incompatible_Dst;
1557
1558	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1559	       "Statistics\\Incoming Calls\\Out of Order");
1560	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1561		&pLib->InterfaceStat.inc.Out_of_Order;
1562
1563	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1564	       "Statistics\\Incoming Calls\\Ignored");
1565	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1566		&pLib->InterfaceStat.inc.Ignored;
1567
1568	/*
1569	  Modem Statistics
1570	*/
1571	pLib->mdm_statistic_parse_first = pLib->cur_parse_entry;
1572
1573	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1574	       "Statistics\\Modem\\Disc Normal");
1575	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1576		&pLib->InterfaceStat.mdm.Disc_Normal;
1577
1578	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1579	       "Statistics\\Modem\\Disc Unspecified");
1580	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1581		&pLib->InterfaceStat.mdm.Disc_Unspecified;
1582
1583	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1584	       "Statistics\\Modem\\Disc Busy Tone");
1585	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1586		&pLib->InterfaceStat.mdm.Disc_Busy_Tone;
1587
1588	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1589	       "Statistics\\Modem\\Disc Congestion");
1590	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1591		&pLib->InterfaceStat.mdm.Disc_Congestion;
1592
1593	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1594	       "Statistics\\Modem\\Disc Carr. Wait");
1595	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1596		&pLib->InterfaceStat.mdm.Disc_Carr_Wait;
1597
1598	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1599	       "Statistics\\Modem\\Disc Trn Timeout");
1600	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1601		&pLib->InterfaceStat.mdm.Disc_Trn_Timeout;
1602
1603	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1604	       "Statistics\\Modem\\Disc Incompat.");
1605	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1606		&pLib->InterfaceStat.mdm.Disc_Incompat;
1607
1608	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1609	       "Statistics\\Modem\\Disc Frame Rej.");
1610	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1611		&pLib->InterfaceStat.mdm.Disc_Frame_Rej;
1612
1613	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1614	       "Statistics\\Modem\\Disc V42bis");
1615	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1616		&pLib->InterfaceStat.mdm.Disc_V42bis;
1617
1618	pLib->mdm_statistic_parse_last  = pLib->cur_parse_entry - 1;
1619
1620	/*
1621	  Fax Statistics
1622	*/
1623	pLib->fax_statistic_parse_first = pLib->cur_parse_entry;
1624
1625	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1626	       "Statistics\\FAX\\Disc Normal");
1627	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1628		&pLib->InterfaceStat.fax.Disc_Normal;
1629
1630	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1631	       "Statistics\\FAX\\Disc Not Ident.");
1632	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1633		&pLib->InterfaceStat.fax.Disc_Not_Ident;
1634
1635	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1636	       "Statistics\\FAX\\Disc No Response");
1637	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1638		&pLib->InterfaceStat.fax.Disc_No_Response;
1639
1640	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1641	       "Statistics\\FAX\\Disc Retries");
1642	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1643		&pLib->InterfaceStat.fax.Disc_Retries;
1644
1645	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1646	       "Statistics\\FAX\\Disc Unexp. Msg.");
1647	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1648		&pLib->InterfaceStat.fax.Disc_Unexp_Msg;
1649
1650	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1651	       "Statistics\\FAX\\Disc No Polling.");
1652	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1653		&pLib->InterfaceStat.fax.Disc_No_Polling;
1654
1655	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1656	       "Statistics\\FAX\\Disc Training");
1657	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1658		&pLib->InterfaceStat.fax.Disc_Training;
1659
1660	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1661	       "Statistics\\FAX\\Disc Unexpected");
1662	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1663		&pLib->InterfaceStat.fax.Disc_Unexpected;
1664
1665	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1666	       "Statistics\\FAX\\Disc Application");
1667	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1668		&pLib->InterfaceStat.fax.Disc_Application;
1669
1670	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1671	       "Statistics\\FAX\\Disc Incompat.");
1672	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1673		&pLib->InterfaceStat.fax.Disc_Incompat;
1674
1675	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1676	       "Statistics\\FAX\\Disc No Command");
1677	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1678		&pLib->InterfaceStat.fax.Disc_No_Command;
1679
1680	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1681	       "Statistics\\FAX\\Disc Long Msg");
1682	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1683		&pLib->InterfaceStat.fax.Disc_Long_Msg;
1684
1685	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1686	       "Statistics\\FAX\\Disc Supervisor");
1687	pLib->parse_table[pLib->cur_parse_entry++].variable = \
1688		&pLib->InterfaceStat.fax.Disc_Supervisor;
1689
1690	strcpy(p

Large files files are truncated, but you can click here to view the full file