summaryrefslogtreecommitdiff
path: root/drivers/isdn/hardware/eicon/maintidi.c
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-08-05 17:04:01 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-08-05 17:04:01 -0300
commit57f0f512b273f60d52568b8c6b77e17f5636edc0 (patch)
tree5e910f0e82173f4ef4f51111366a3f1299037a7b /drivers/isdn/hardware/eicon/maintidi.c
Initial import
Diffstat (limited to 'drivers/isdn/hardware/eicon/maintidi.c')
-rw-r--r--drivers/isdn/hardware/eicon/maintidi.c2194
1 files changed, 2194 insertions, 0 deletions
diff --git a/drivers/isdn/hardware/eicon/maintidi.c b/drivers/isdn/hardware/eicon/maintidi.c
new file mode 100644
index 000000000..2ee789f95
--- /dev/null
+++ b/drivers/isdn/hardware/eicon/maintidi.c
@@ -0,0 +1,2194 @@
+/*
+ *
+ Copyright (c) Eicon Networks, 2000.
+ *
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
+ *
+ Eicon File Revision : 1.9
+ *
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+ *
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+ *
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include "platform.h"
+#include "kst_ifc.h"
+#include "di_defs.h"
+#include "maintidi.h"
+#include "pc.h"
+#include "man_defs.h"
+
+
+extern void diva_mnt_internal_dprintf(dword drv_id, dword type, char *p, ...);
+
+#define MODEM_PARSE_ENTRIES 16 /* amount of variables of interest */
+#define FAX_PARSE_ENTRIES 12 /* amount of variables of interest */
+#define LINE_PARSE_ENTRIES 15 /* amount of variables of interest */
+#define STAT_PARSE_ENTRIES 70 /* amount of variables of interest */
+
+/*
+ LOCAL FUNCTIONS
+*/
+static int DivaSTraceLibraryStart(void *hLib);
+static int DivaSTraceLibraryStop(void *hLib);
+static int SuperTraceLibraryFinit(void *hLib);
+static void *SuperTraceGetHandle(void *hLib);
+static int SuperTraceMessageInput(void *hLib);
+static int SuperTraceSetAudioTap(void *hLib, int Channel, int on);
+static int SuperTraceSetBChannel(void *hLib, int Channel, int on);
+static int SuperTraceSetDChannel(void *hLib, int on);
+static int SuperTraceSetInfo(void *hLib, int on);
+static int SuperTraceClearCall(void *hLib, int Channel);
+static int SuperTraceGetOutgoingCallStatistics(void *hLib);
+static int SuperTraceGetIncomingCallStatistics(void *hLib);
+static int SuperTraceGetModemStatistics(void *hLib);
+static int SuperTraceGetFaxStatistics(void *hLib);
+static int SuperTraceGetBLayer1Statistics(void *hLib);
+static int SuperTraceGetBLayer2Statistics(void *hLib);
+static int SuperTraceGetDLayer1Statistics(void *hLib);
+static int SuperTraceGetDLayer2Statistics(void *hLib);
+
+/*
+ LOCAL FUNCTIONS
+*/
+static int ScheduleNextTraceRequest(diva_strace_context_t *pLib);
+static int process_idi_event(diva_strace_context_t *pLib,
+ diva_man_var_header_t *pVar);
+static int process_idi_info(diva_strace_context_t *pLib,
+ diva_man_var_header_t *pVar);
+static int diva_modem_event(diva_strace_context_t *pLib, int Channel);
+static int diva_fax_event(diva_strace_context_t *pLib, int Channel);
+static int diva_line_event(diva_strace_context_t *pLib, int Channel);
+static int diva_modem_info(diva_strace_context_t *pLib,
+ int Channel,
+ diva_man_var_header_t *pVar);
+static int diva_fax_info(diva_strace_context_t *pLib,
+ int Channel,
+ diva_man_var_header_t *pVar);
+static int diva_line_info(diva_strace_context_t *pLib,
+ int Channel,
+ diva_man_var_header_t *pVar);
+static int diva_ifc_statistics(diva_strace_context_t *pLib,
+ diva_man_var_header_t *pVar);
+static diva_man_var_header_t *get_next_var(diva_man_var_header_t *pVar);
+static diva_man_var_header_t *find_var(diva_man_var_header_t *pVar,
+ const char *name);
+static int diva_strace_read_int(diva_man_var_header_t *pVar, int *var);
+static int diva_strace_read_uint(diva_man_var_header_t *pVar, dword *var);
+static int diva_strace_read_asz(diva_man_var_header_t *pVar, char *var);
+static int diva_strace_read_asc(diva_man_var_header_t *pVar, char *var);
+static int diva_strace_read_ie(diva_man_var_header_t *pVar,
+ diva_trace_ie_t *var);
+static void diva_create_parse_table(diva_strace_context_t *pLib);
+static void diva_trace_error(diva_strace_context_t *pLib,
+ int error, const char *file, int line);
+static void diva_trace_notify_user(diva_strace_context_t *pLib,
+ int Channel,
+ int notify_subject);
+static int diva_trace_read_variable(diva_man_var_header_t *pVar,
+ void *variable);
+
+/*
+ Initialize the library and return context
+ of the created trace object that will represent
+ the IDI adapter.
+ Return 0 on error.
+*/
+diva_strace_library_interface_t *DivaSTraceLibraryCreateInstance(int Adapter,
+ const diva_trace_library_user_interface_t *user_proc,
+ byte *pmem) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)pmem;
+ int i;
+
+ if (!pLib) {
+ return NULL;
+ }
+
+ pmem += sizeof(*pLib);
+ memset(pLib, 0x00, sizeof(*pLib));
+
+ pLib->Adapter = Adapter;
+
+ /*
+ Set up Library Interface
+ */
+ pLib->instance.hLib = pLib;
+ pLib->instance.DivaSTraceLibraryStart = DivaSTraceLibraryStart;
+ pLib->instance.DivaSTraceLibraryStop = DivaSTraceLibraryStop;
+ pLib->instance.DivaSTraceLibraryFinit = SuperTraceLibraryFinit;
+ pLib->instance.DivaSTraceMessageInput = SuperTraceMessageInput;
+ pLib->instance.DivaSTraceGetHandle = SuperTraceGetHandle;
+ pLib->instance.DivaSTraceSetAudioTap = SuperTraceSetAudioTap;
+ pLib->instance.DivaSTraceSetBChannel = SuperTraceSetBChannel;
+ pLib->instance.DivaSTraceSetDChannel = SuperTraceSetDChannel;
+ pLib->instance.DivaSTraceSetInfo = SuperTraceSetInfo;
+ pLib->instance.DivaSTraceGetOutgoingCallStatistics = \
+ SuperTraceGetOutgoingCallStatistics;
+ pLib->instance.DivaSTraceGetIncomingCallStatistics = \
+ SuperTraceGetIncomingCallStatistics;
+ pLib->instance.DivaSTraceGetModemStatistics = \
+ SuperTraceGetModemStatistics;
+ pLib->instance.DivaSTraceGetFaxStatistics = \
+ SuperTraceGetFaxStatistics;
+ pLib->instance.DivaSTraceGetBLayer1Statistics = \
+ SuperTraceGetBLayer1Statistics;
+ pLib->instance.DivaSTraceGetBLayer2Statistics = \
+ SuperTraceGetBLayer2Statistics;
+ pLib->instance.DivaSTraceGetDLayer1Statistics = \
+ SuperTraceGetDLayer1Statistics;
+ pLib->instance.DivaSTraceGetDLayer2Statistics = \
+ SuperTraceGetDLayer2Statistics;
+ pLib->instance.DivaSTraceClearCall = SuperTraceClearCall;
+
+
+ if (user_proc) {
+ pLib->user_proc_table.user_context = user_proc->user_context;
+ pLib->user_proc_table.notify_proc = user_proc->notify_proc;
+ pLib->user_proc_table.trace_proc = user_proc->trace_proc;
+ pLib->user_proc_table.error_notify_proc = user_proc->error_notify_proc;
+ }
+
+ if (!(pLib->hAdapter = SuperTraceOpenAdapter(Adapter))) {
+ diva_mnt_internal_dprintf(0, DLI_ERR, "Can not open XDI adapter");
+ return NULL;
+ }
+ pLib->Channels = SuperTraceGetNumberOfChannels(pLib->hAdapter);
+
+ /*
+ Calculate amount of parte table entites necessary to translate
+ information from all events of onterest
+ */
+ pLib->parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \
+ STAT_PARSE_ENTRIES + \
+ LINE_PARSE_ENTRIES + 1) * pLib->Channels;
+ pLib->parse_table = (diva_strace_path2action_t *)pmem;
+
+ for (i = 0; i < 30; i++) {
+ pLib->lines[i].pInterface = &pLib->Interface;
+ pLib->lines[i].pInterfaceStat = &pLib->InterfaceStat;
+ }
+
+ pLib->e.R = &pLib->RData;
+
+ pLib->req_busy = 1;
+ pLib->rc_ok = ASSIGN_OK;
+
+ diva_create_parse_table(pLib);
+
+ return ((diva_strace_library_interface_t *)pLib);
+}
+
+static int DivaSTraceLibraryStart(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+
+ return (SuperTraceASSIGN(pLib->hAdapter, pLib->buffer));
+}
+
+/*
+ Return (-1) on error
+ Return (0) if was initiated or pending
+ Return (1) if removal is complete
+*/
+static int DivaSTraceLibraryStop(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+
+ if (!pLib->e.Id) { /* Was never started/assigned */
+ return (1);
+ }
+
+ switch (pLib->removal_state) {
+ case 0:
+ pLib->removal_state = 1;
+ ScheduleNextTraceRequest(pLib);
+ break;
+
+ case 3:
+ return (1);
+ }
+
+ return (0);
+}
+
+static int SuperTraceLibraryFinit(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+ if (pLib) {
+ if (pLib->hAdapter) {
+ SuperTraceCloseAdapter(pLib->hAdapter);
+ }
+ return (0);
+ }
+ return (-1);
+}
+
+static void *SuperTraceGetHandle(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+
+ return (&pLib->e);
+}
+
+/*
+ After library handle object is gone in signaled state
+ this function should be called and will pick up incoming
+ IDI messages (return codes and indications).
+*/
+static int SuperTraceMessageInput(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+ int ret = 0;
+ byte Rc, Ind;
+
+ if (pLib->e.complete == 255) {
+ /*
+ Process return code
+ */
+ pLib->req_busy = 0;
+ Rc = pLib->e.Rc;
+ pLib->e.Rc = 0;
+
+ if (pLib->removal_state == 2) {
+ pLib->removal_state = 3;
+ return (0);
+ }
+
+ if (Rc != pLib->rc_ok) {
+ int ignore = 0;
+ /*
+ Auto-detect amount of events/channels and features
+ */
+ if (pLib->general_b_ch_event == 1) {
+ pLib->general_b_ch_event = 2;
+ ignore = 1;
+ } else if (pLib->general_fax_event == 1) {
+ pLib->general_fax_event = 2;
+ ignore = 1;
+ } else if (pLib->general_mdm_event == 1) {
+ pLib->general_mdm_event = 2;
+ ignore = 1;
+ } else if ((pLib->ChannelsTraceActive < pLib->Channels) && pLib->ChannelsTraceActive) {
+ pLib->ChannelsTraceActive = pLib->Channels;
+ ignore = 1;
+ } else if (pLib->ModemTraceActive < pLib->Channels) {
+ pLib->ModemTraceActive = pLib->Channels;
+ ignore = 1;
+ } else if (pLib->FaxTraceActive < pLib->Channels) {
+ pLib->FaxTraceActive = pLib->Channels;
+ ignore = 1;
+ } else if (pLib->audio_trace_init == 2) {
+ ignore = 1;
+ pLib->audio_trace_init = 1;
+ } else if (pLib->eye_pattern_pending) {
+ pLib->eye_pattern_pending = 0;
+ ignore = 1;
+ } else if (pLib->audio_tap_pending) {
+ pLib->audio_tap_pending = 0;
+ ignore = 1;
+ }
+
+ if (!ignore) {
+ return (-1); /* request failed */
+ }
+ } else {
+ if (pLib->general_b_ch_event == 1) {
+ pLib->ChannelsTraceActive = pLib->Channels;
+ pLib->general_b_ch_event = 2;
+ } else if (pLib->general_fax_event == 1) {
+ pLib->general_fax_event = 2;
+ pLib->FaxTraceActive = pLib->Channels;
+ } else if (pLib->general_mdm_event == 1) {
+ pLib->general_mdm_event = 2;
+ pLib->ModemTraceActive = pLib->Channels;
+ }
+ }
+ if (pLib->audio_trace_init == 2) {
+ pLib->audio_trace_init = 1;
+ }
+ pLib->rc_ok = 0xff; /* default OK after assign was done */
+ if ((ret = ScheduleNextTraceRequest(pLib))) {
+ return (-1);
+ }
+ } else {
+ /*
+ Process indication
+ Always 'RNR' indication if return code is pending
+ */
+ Ind = pLib->e.Ind;
+ pLib->e.Ind = 0;
+ if (pLib->removal_state) {
+ pLib->e.RNum = 0;
+ pLib->e.RNR = 2;
+ } else if (pLib->req_busy) {
+ pLib->e.RNum = 0;
+ pLib->e.RNR = 1;
+ } else {
+ if (pLib->e.complete != 0x02) {
+ /*
+ Look-ahead call, set up buffers
+ */
+ pLib->e.RNum = 1;
+ pLib->e.R->P = (byte *)&pLib->buffer[0];
+ pLib->e.R->PLength = (word)(sizeof(pLib->buffer) - 1);
+
+ } else {
+ /*
+ Indication reception complete, process it now
+ */
+ byte *p = (byte *)&pLib->buffer[0];
+ pLib->buffer[pLib->e.R->PLength] = 0; /* terminate I.E. with zero */
+
+ switch (Ind) {
+ case MAN_COMBI_IND: {
+ int total_length = pLib->e.R->PLength;
+ word this_ind_length;
+
+ while (total_length > 3 && *p) {
+ Ind = *p++;
+ this_ind_length = (word)p[0] | ((word)p[1] << 8);
+ p += 2;
+
+ switch (Ind) {
+ case MAN_INFO_IND:
+ if (process_idi_info(pLib, (diva_man_var_header_t *)p)) {
+ return (-1);
+ }
+ break;
+ case MAN_EVENT_IND:
+ if (process_idi_event(pLib, (diva_man_var_header_t *)p)) {
+ return (-1);
+ }
+ break;
+ case MAN_TRACE_IND:
+ if (pLib->trace_on == 1) {
+ /*
+ Ignore first trace event that is result of
+ EVENT_ON operation
+ */
+ pLib->trace_on++;
+ } else {
+ /*
+ Delivery XLOG buffer to application
+ */
+ if (pLib->user_proc_table.trace_proc) {
+ (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
+ &pLib->instance, pLib->Adapter,
+ p, this_ind_length);
+ }
+ }
+ break;
+ default:
+ diva_mnt_internal_dprintf(0, DLI_ERR, "Unknown IDI Ind (DMA mode): %02x", Ind);
+ }
+ p += (this_ind_length + 1);
+ total_length -= (4 + this_ind_length);
+ }
+ } break;
+ case MAN_INFO_IND:
+ if (process_idi_info(pLib, (diva_man_var_header_t *)p)) {
+ return (-1);
+ }
+ break;
+ case MAN_EVENT_IND:
+ if (process_idi_event(pLib, (diva_man_var_header_t *)p)) {
+ return (-1);
+ }
+ break;
+ case MAN_TRACE_IND:
+ if (pLib->trace_on == 1) {
+ /*
+ Ignore first trace event that is result of
+ EVENT_ON operation
+ */
+ pLib->trace_on++;
+ } else {
+ /*
+ Delivery XLOG buffer to application
+ */
+ if (pLib->user_proc_table.trace_proc) {
+ (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
+ &pLib->instance, pLib->Adapter,
+ p, pLib->e.R->PLength);
+ }
+ }
+ break;
+ default:
+ diva_mnt_internal_dprintf(0, DLI_ERR, "Unknown IDI Ind: %02x", Ind);
+ }
+ }
+ }
+ }
+
+ if ((ret = ScheduleNextTraceRequest(pLib))) {
+ return (-1);
+ }
+
+ return (ret);
+}
+
+/*
+ Internal state machine responsible for scheduling of requests
+*/
+static int ScheduleNextTraceRequest(diva_strace_context_t *pLib) {
+ char name[64];
+ int ret = 0;
+ int i;
+
+ if (pLib->req_busy) {
+ return (0);
+ }
+
+ if (pLib->removal_state == 1) {
+ if (SuperTraceREMOVE(pLib->hAdapter)) {
+ pLib->removal_state = 3;
+ } else {
+ pLib->req_busy = 1;
+ pLib->removal_state = 2;
+ }
+ return (0);
+ }
+
+ if (pLib->removal_state) {
+ return (0);
+ }
+
+ if (!pLib->general_b_ch_event) {
+ if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\B Event", pLib->buffer))) {
+ return (-1);
+ }
+ pLib->general_b_ch_event = 1;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (!pLib->general_fax_event) {
+ if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\FAX Event", pLib->buffer))) {
+ return (-1);
+ }
+ pLib->general_fax_event = 1;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (!pLib->general_mdm_event) {
+ if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\Modem Event", pLib->buffer))) {
+ return (-1);
+ }
+ pLib->general_mdm_event = 1;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (pLib->ChannelsTraceActive < pLib->Channels) {
+ pLib->ChannelsTraceActive++;
+ sprintf(name, "State\\B%d\\Line", pLib->ChannelsTraceActive);
+ if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
+ pLib->ChannelsTraceActive--;
+ return (-1);
+ }
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (pLib->ModemTraceActive < pLib->Channels) {
+ pLib->ModemTraceActive++;
+ sprintf(name, "State\\B%d\\Modem\\Event", pLib->ModemTraceActive);
+ if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
+ pLib->ModemTraceActive--;
+ return (-1);
+ }
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (pLib->FaxTraceActive < pLib->Channels) {
+ pLib->FaxTraceActive++;
+ sprintf(name, "State\\B%d\\FAX\\Event", pLib->FaxTraceActive);
+ if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
+ pLib->FaxTraceActive--;
+ return (-1);
+ }
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (!pLib->trace_mask_init) {
+ word tmp = 0x0000;
+ if (SuperTraceWriteVar(pLib->hAdapter,
+ pLib->buffer,
+ "Trace\\Event Enable",
+ &tmp,
+ 0x87, /* MI_BITFLD */
+ sizeof(tmp))) {
+ return (-1);
+ }
+ pLib->trace_mask_init = 1;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (!pLib->audio_trace_init) {
+ dword tmp = 0x00000000;
+ if (SuperTraceWriteVar(pLib->hAdapter,
+ pLib->buffer,
+ "Trace\\AudioCh# Enable",
+ &tmp,
+ 0x87, /* MI_BITFLD */
+ sizeof(tmp))) {
+ return (-1);
+ }
+ pLib->audio_trace_init = 2;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (!pLib->bchannel_init) {
+ dword tmp = 0x00000000;
+ if (SuperTraceWriteVar(pLib->hAdapter,
+ pLib->buffer,
+ "Trace\\B-Ch# Enable",
+ &tmp,
+ 0x87, /* MI_BITFLD */
+ sizeof(tmp))) {
+ return (-1);
+ }
+ pLib->bchannel_init = 1;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (!pLib->trace_length_init) {
+ word tmp = 30;
+ if (SuperTraceWriteVar(pLib->hAdapter,
+ pLib->buffer,
+ "Trace\\Max Log Length",
+ &tmp,
+ 0x82, /* MI_UINT */
+ sizeof(tmp))) {
+ return (-1);
+ }
+ pLib->trace_length_init = 1;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (!pLib->trace_on) {
+ if (SuperTraceTraceOnRequest(pLib->hAdapter,
+ "Trace\\Log Buffer",
+ pLib->buffer)) {
+ return (-1);
+ }
+ pLib->trace_on = 1;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (pLib->trace_event_mask != pLib->current_trace_event_mask) {
+ if (SuperTraceWriteVar(pLib->hAdapter,
+ pLib->buffer,
+ "Trace\\Event Enable",
+ &pLib->trace_event_mask,
+ 0x87, /* MI_BITFLD */
+ sizeof(pLib->trace_event_mask))) {
+ return (-1);
+ }
+ pLib->current_trace_event_mask = pLib->trace_event_mask;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if ((pLib->audio_tap_pending >= 0) && (pLib->audio_tap_mask != pLib->current_audio_tap_mask)) {
+ if (SuperTraceWriteVar(pLib->hAdapter,
+ pLib->buffer,
+ "Trace\\AudioCh# Enable",
+ &pLib->audio_tap_mask,
+ 0x87, /* MI_BITFLD */
+ sizeof(pLib->audio_tap_mask))) {
+ return (-1);
+ }
+ pLib->current_audio_tap_mask = pLib->audio_tap_mask;
+ pLib->audio_tap_pending = 1;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if ((pLib->eye_pattern_pending >= 0) && (pLib->audio_tap_mask != pLib->current_eye_pattern_mask)) {
+ if (SuperTraceWriteVar(pLib->hAdapter,
+ pLib->buffer,
+ "Trace\\EyeCh# Enable",
+ &pLib->audio_tap_mask,
+ 0x87, /* MI_BITFLD */
+ sizeof(pLib->audio_tap_mask))) {
+ return (-1);
+ }
+ pLib->current_eye_pattern_mask = pLib->audio_tap_mask;
+ pLib->eye_pattern_pending = 1;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (pLib->bchannel_trace_mask != pLib->current_bchannel_trace_mask) {
+ if (SuperTraceWriteVar(pLib->hAdapter,
+ pLib->buffer,
+ "Trace\\B-Ch# Enable",
+ &pLib->bchannel_trace_mask,
+ 0x87, /* MI_BITFLD */
+ sizeof(pLib->bchannel_trace_mask))) {
+ return (-1);
+ }
+ pLib->current_bchannel_trace_mask = pLib->bchannel_trace_mask;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (!pLib->trace_events_down) {
+ if (SuperTraceTraceOnRequest(pLib->hAdapter,
+ "Events Down",
+ pLib->buffer)) {
+ return (-1);
+ }
+ pLib->trace_events_down = 1;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (!pLib->l1_trace) {
+ if (SuperTraceTraceOnRequest(pLib->hAdapter,
+ "State\\Layer1",
+ pLib->buffer)) {
+ return (-1);
+ }
+ pLib->l1_trace = 1;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (!pLib->l2_trace) {
+ if (SuperTraceTraceOnRequest(pLib->hAdapter,
+ "State\\Layer2 No1",
+ pLib->buffer)) {
+ return (-1);
+ }
+ pLib->l2_trace = 1;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ for (i = 0; i < 30; i++) {
+ if (pLib->pending_line_status & (1L << i)) {
+ sprintf(name, "State\\B%d", i + 1);
+ if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
+ return (-1);
+ }
+ pLib->pending_line_status &= ~(1L << i);
+ pLib->req_busy = 1;
+ return (0);
+ }
+ if (pLib->pending_modem_status & (1L << i)) {
+ sprintf(name, "State\\B%d\\Modem", i + 1);
+ if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
+ return (-1);
+ }
+ pLib->pending_modem_status &= ~(1L << i);
+ pLib->req_busy = 1;
+ return (0);
+ }
+ if (pLib->pending_fax_status & (1L << i)) {
+ sprintf(name, "State\\B%d\\FAX", i + 1);
+ if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
+ return (-1);
+ }
+ pLib->pending_fax_status &= ~(1L << i);
+ pLib->req_busy = 1;
+ return (0);
+ }
+ if (pLib->clear_call_command & (1L << i)) {
+ sprintf(name, "State\\B%d\\Clear Call", i + 1);
+ if (SuperTraceExecuteRequest(pLib->hAdapter, name, pLib->buffer)) {
+ return (-1);
+ }
+ pLib->clear_call_command &= ~(1L << i);
+ pLib->req_busy = 1;
+ return (0);
+ }
+ }
+
+ if (pLib->outgoing_ifc_stats) {
+ if (SuperTraceReadRequest(pLib->hAdapter,
+ "Statistics\\Outgoing Calls",
+ pLib->buffer)) {
+ return (-1);
+ }
+ pLib->outgoing_ifc_stats = 0;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (pLib->incoming_ifc_stats) {
+ if (SuperTraceReadRequest(pLib->hAdapter,
+ "Statistics\\Incoming Calls",
+ pLib->buffer)) {
+ return (-1);
+ }
+ pLib->incoming_ifc_stats = 0;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (pLib->modem_ifc_stats) {
+ if (SuperTraceReadRequest(pLib->hAdapter,
+ "Statistics\\Modem",
+ pLib->buffer)) {
+ return (-1);
+ }
+ pLib->modem_ifc_stats = 0;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (pLib->fax_ifc_stats) {
+ if (SuperTraceReadRequest(pLib->hAdapter,
+ "Statistics\\FAX",
+ pLib->buffer)) {
+ return (-1);
+ }
+ pLib->fax_ifc_stats = 0;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (pLib->b1_ifc_stats) {
+ if (SuperTraceReadRequest(pLib->hAdapter,
+ "Statistics\\B-Layer1",
+ pLib->buffer)) {
+ return (-1);
+ }
+ pLib->b1_ifc_stats = 0;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (pLib->b2_ifc_stats) {
+ if (SuperTraceReadRequest(pLib->hAdapter,
+ "Statistics\\B-Layer2",
+ pLib->buffer)) {
+ return (-1);
+ }
+ pLib->b2_ifc_stats = 0;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (pLib->d1_ifc_stats) {
+ if (SuperTraceReadRequest(pLib->hAdapter,
+ "Statistics\\D-Layer1",
+ pLib->buffer)) {
+ return (-1);
+ }
+ pLib->d1_ifc_stats = 0;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (pLib->d2_ifc_stats) {
+ if (SuperTraceReadRequest(pLib->hAdapter,
+ "Statistics\\D-Layer2",
+ pLib->buffer)) {
+ return (-1);
+ }
+ pLib->d2_ifc_stats = 0;
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ if (!pLib->IncomingCallsCallsActive) {
+ pLib->IncomingCallsCallsActive = 1;
+ sprintf(name, "%s", "Statistics\\Incoming Calls\\Calls");
+ if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
+ pLib->IncomingCallsCallsActive = 0;
+ return (-1);
+ }
+ pLib->req_busy = 1;
+ return (0);
+ }
+ if (!pLib->IncomingCallsConnectedActive) {
+ pLib->IncomingCallsConnectedActive = 1;
+ sprintf(name, "%s", "Statistics\\Incoming Calls\\Connected");
+ if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
+ pLib->IncomingCallsConnectedActive = 0;
+ return (-1);
+ }
+ pLib->req_busy = 1;
+ return (0);
+ }
+ if (!pLib->OutgoingCallsCallsActive) {
+ pLib->OutgoingCallsCallsActive = 1;
+ sprintf(name, "%s", "Statistics\\Outgoing Calls\\Calls");
+ if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
+ pLib->OutgoingCallsCallsActive = 0;
+ return (-1);
+ }
+ pLib->req_busy = 1;
+ return (0);
+ }
+ if (!pLib->OutgoingCallsConnectedActive) {
+ pLib->OutgoingCallsConnectedActive = 1;
+ sprintf(name, "%s", "Statistics\\Outgoing Calls\\Connected");
+ if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
+ pLib->OutgoingCallsConnectedActive = 0;
+ return (-1);
+ }
+ pLib->req_busy = 1;
+ return (0);
+ }
+
+ return (0);
+}
+
+static int process_idi_event(diva_strace_context_t *pLib,
+ diva_man_var_header_t *pVar) {
+ const char *path = (char *)&pVar->path_length + 1;
+ char name[64];
+ int i;
+
+ if (!strncmp("State\\B Event", path, pVar->path_length)) {
+ dword ch_id;
+ if (!diva_trace_read_variable(pVar, &ch_id)) {
+ if (!pLib->line_init_event && !pLib->pending_line_status) {
+ for (i = 1; i <= pLib->Channels; i++) {
+ diva_line_event(pLib, i);
+ }
+ return (0);
+ } else if (ch_id && ch_id <= pLib->Channels) {
+ return (diva_line_event(pLib, (int)ch_id));
+ }
+ return (0);
+ }
+ return (-1);
+ }
+
+ if (!strncmp("State\\FAX Event", path, pVar->path_length)) {
+ dword ch_id;
+ if (!diva_trace_read_variable(pVar, &ch_id)) {
+ if (!pLib->pending_fax_status && !pLib->fax_init_event) {
+ for (i = 1; i <= pLib->Channels; i++) {
+ diva_fax_event(pLib, i);
+ }
+ return (0);
+ } else if (ch_id && ch_id <= pLib->Channels) {
+ return (diva_fax_event(pLib, (int)ch_id));
+ }
+ return (0);
+ }
+ return (-1);
+ }
+
+ if (!strncmp("State\\Modem Event", path, pVar->path_length)) {
+ dword ch_id;
+ if (!diva_trace_read_variable(pVar, &ch_id)) {
+ if (!pLib->pending_modem_status && !pLib->modem_init_event) {
+ for (i = 1; i <= pLib->Channels; i++) {
+ diva_modem_event(pLib, i);
+ }
+ return (0);
+ } else if (ch_id && ch_id <= pLib->Channels) {
+ return (diva_modem_event(pLib, (int)ch_id));
+ }
+ return (0);
+ }
+ return (-1);
+ }
+
+ /*
+ First look for Line Event
+ */
+ for (i = 1; i <= pLib->Channels; i++) {
+ sprintf(name, "State\\B%d\\Line", i);
+ if (find_var(pVar, name)) {
+ return (diva_line_event(pLib, i));
+ }
+ }
+
+ /*
+ Look for Moden Progress Event
+ */
+ for (i = 1; i <= pLib->Channels; i++) {
+ sprintf(name, "State\\B%d\\Modem\\Event", i);
+ if (find_var(pVar, name)) {
+ return (diva_modem_event(pLib, i));
+ }
+ }
+
+ /*
+ Look for Fax Event
+ */
+ for (i = 1; i <= pLib->Channels; i++) {
+ sprintf(name, "State\\B%d\\FAX\\Event", i);
+ if (find_var(pVar, name)) {
+ return (diva_fax_event(pLib, i));
+ }
+ }
+
+ /*
+ Notification about loss of events
+ */
+ if (!strncmp("Events Down", path, pVar->path_length)) {
+ if (pLib->trace_events_down == 1) {
+ pLib->trace_events_down = 2;
+ } else {
+ diva_trace_error(pLib, 1, "Events Down", 0);
+ }
+ return (0);
+ }
+
+ if (!strncmp("State\\Layer1", path, pVar->path_length)) {
+ diva_strace_read_asz(pVar, &pLib->lines[0].pInterface->Layer1[0]);
+ if (pLib->l1_trace == 1) {
+ pLib->l1_trace = 2;
+ } else {
+ diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
+ }
+ return (0);
+ }
+ if (!strncmp("State\\Layer2 No1", path, pVar->path_length)) {
+ char *tmp = &pLib->lines[0].pInterface->Layer2[0];
+ dword l2_state;
+ if (diva_strace_read_uint(pVar, &l2_state))
+ return -1;
+
+ switch (l2_state) {
+ case 0:
+ strcpy(tmp, "Idle");
+ break;
+ case 1:
+ strcpy(tmp, "Layer2 UP");
+ break;
+ case 2:
+ strcpy(tmp, "Layer2 Disconnecting");
+ break;
+ case 3:
+ strcpy(tmp, "Layer2 Connecting");
+ break;
+ case 4:
+ strcpy(tmp, "SPID Initializing");
+ break;
+ case 5:
+ strcpy(tmp, "SPID Initialised");
+ break;
+ case 6:
+ strcpy(tmp, "Layer2 Connecting");
+ break;
+
+ case 7:
+ strcpy(tmp, "Auto SPID Stopped");
+ break;
+
+ case 8:
+ strcpy(tmp, "Auto SPID Idle");
+ break;
+
+ case 9:
+ strcpy(tmp, "Auto SPID Requested");
+ break;
+
+ case 10:
+ strcpy(tmp, "Auto SPID Delivery");
+ break;
+
+ case 11:
+ strcpy(tmp, "Auto SPID Complete");
+ break;
+
+ default:
+ sprintf(tmp, "U:%d", (int)l2_state);
+ }
+ if (pLib->l2_trace == 1) {
+ pLib->l2_trace = 2;
+ } else {
+ diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
+ }
+ return (0);
+ }
+
+ if (!strncmp("Statistics\\Incoming Calls\\Calls", path, pVar->path_length) ||
+ !strncmp("Statistics\\Incoming Calls\\Connected", path, pVar->path_length)) {
+ return (SuperTraceGetIncomingCallStatistics(pLib));
+ }
+
+ if (!strncmp("Statistics\\Outgoing Calls\\Calls", path, pVar->path_length) ||
+ !strncmp("Statistics\\Outgoing Calls\\Connected", path, pVar->path_length)) {
+ return (SuperTraceGetOutgoingCallStatistics(pLib));
+ }
+
+ return (-1);
+}
+
+static int diva_line_event(diva_strace_context_t *pLib, int Channel) {
+ pLib->pending_line_status |= (1L << (Channel - 1));
+ return (0);
+}
+
+static int diva_modem_event(diva_strace_context_t *pLib, int Channel) {
+ pLib->pending_modem_status |= (1L << (Channel - 1));
+ return (0);
+}
+
+static int diva_fax_event(diva_strace_context_t *pLib, int Channel) {
+ pLib->pending_fax_status |= (1L << (Channel - 1));
+ return (0);
+}
+
+/*
+ Process INFO indications that arrive from the card
+ Uses path of first I.E. to detect the source of the
+ infication
+*/
+static int process_idi_info(diva_strace_context_t *pLib,
+ diva_man_var_header_t *pVar) {
+ const char *path = (char *)&pVar->path_length + 1;
+ char name[64];
+ int i, len;
+
+ /*
+ First look for Modem Status Info
+ */
+ for (i = pLib->Channels; i > 0; i--) {
+ len = sprintf(name, "State\\B%d\\Modem", i);
+ if (!strncmp(name, path, len)) {
+ return (diva_modem_info(pLib, i, pVar));
+ }
+ }
+
+ /*
+ Look for Fax Status Info
+ */
+ for (i = pLib->Channels; i > 0; i--) {
+ len = sprintf(name, "State\\B%d\\FAX", i);
+ if (!strncmp(name, path, len)) {
+ return (diva_fax_info(pLib, i, pVar));
+ }
+ }
+
+ /*
+ Look for Line Status Info
+ */
+ for (i = pLib->Channels; i > 0; i--) {
+ len = sprintf(name, "State\\B%d", i);
+ if (!strncmp(name, path, len)) {
+ return (diva_line_info(pLib, i, pVar));
+ }
+ }
+
+ if (!diva_ifc_statistics(pLib, pVar)) {
+ return (0);
+ }
+
+ return (-1);
+}
+
+/*
+ MODEM INSTANCE STATE UPDATE
+
+ Update Modem Status Information and issue notification to user,
+ that will inform about change in the state of modem instance, that is
+ associuated with this channel
+*/
+static int diva_modem_info(diva_strace_context_t *pLib,
+ int Channel,
+ diva_man_var_header_t *pVar) {
+ diva_man_var_header_t *cur;
+ int i, nr = Channel - 1;
+
+ for (i = pLib->modem_parse_entry_first[nr];
+ i <= pLib->modem_parse_entry_last[nr]; i++) {
+ if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
+ if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
+ diva_trace_error(pLib, -3, __FILE__, __LINE__);
+ return (-1);
+ }
+ } else {
+ diva_trace_error(pLib, -2, __FILE__, __LINE__);
+ return (-1);
+ }
+ }
+
+ /*
+ We do not use first event to notify user - this is the event that is
+ generated as result of EVENT ON operation and is used only to initialize
+ internal variables of application
+ */
+ if (pLib->modem_init_event & (1L << nr)) {
+ diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE);
+ } else {
+ pLib->modem_init_event |= (1L << nr);
+ }
+
+ return (0);
+}
+
+static int diva_fax_info(diva_strace_context_t *pLib,
+ int Channel,
+ diva_man_var_header_t *pVar) {
+ diva_man_var_header_t *cur;
+ int i, nr = Channel - 1;
+
+ for (i = pLib->fax_parse_entry_first[nr];
+ i <= pLib->fax_parse_entry_last[nr]; i++) {
+ if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
+ if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
+ diva_trace_error(pLib, -3, __FILE__, __LINE__);
+ return (-1);
+ }
+ } else {
+ diva_trace_error(pLib, -2, __FILE__, __LINE__);
+ return (-1);
+ }
+ }
+
+ /*
+ We do not use first event to notify user - this is the event that is
+ generated as result of EVENT ON operation and is used only to initialize
+ internal variables of application
+ */
+ if (pLib->fax_init_event & (1L << nr)) {
+ diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE);
+ } else {
+ pLib->fax_init_event |= (1L << nr);
+ }
+
+ return (0);
+}
+
+/*
+ LINE STATE UPDATE
+ Update Line Status Information and issue notification to user,
+ that will inform about change in the line state.
+*/
+static int diva_line_info(diva_strace_context_t *pLib,
+ int Channel,
+ diva_man_var_header_t *pVar) {
+ diva_man_var_header_t *cur;
+ int i, nr = Channel - 1;
+
+ for (i = pLib->line_parse_entry_first[nr];
+ i <= pLib->line_parse_entry_last[nr]; i++) {
+ if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
+ if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
+ diva_trace_error(pLib, -3, __FILE__, __LINE__);
+ return (-1);
+ }
+ } else {
+ diva_trace_error(pLib, -2 , __FILE__, __LINE__);
+ return (-1);
+ }
+ }
+
+ /*
+ We do not use first event to notify user - this is the event that is
+ generated as result of EVENT ON operation and is used only to initialize
+ internal variables of application
+
+ Exception is is if the line is "online". In this case we have to notify
+ user about this confition.
+ */
+ if (pLib->line_init_event & (1L << nr)) {
+ diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
+ } else {
+ pLib->line_init_event |= (1L << nr);
+ if (strcmp(&pLib->lines[nr].Line[0], "Idle")) {
+ diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
+ }
+ }
+
+ return (0);
+}
+
+/*
+ Move position to next vatianle in the chain
+*/
+static diva_man_var_header_t *get_next_var(diva_man_var_header_t *pVar) {
+ byte *msg = (byte *)pVar;
+ byte *start;
+ int msg_length;
+
+ if (*msg != ESC) return NULL;
+
+ start = msg + 2;
+ msg_length = *(msg + 1);
+ msg = (start + msg_length);
+
+ if (*msg != ESC) return NULL;
+
+ return ((diva_man_var_header_t *)msg);
+}
+
+/*
+ Move position to variable with given name
+*/
+static diva_man_var_header_t *find_var(diva_man_var_header_t *pVar,
+ const char *name) {
+ const char *path;
+
+ do {
+ path = (char *)&pVar->path_length + 1;
+
+ if (!strncmp(name, path, pVar->path_length)) {
+ break;
+ }
+ } while ((pVar = get_next_var(pVar)));
+
+ return (pVar);
+}
+
+static void diva_create_line_parse_table(diva_strace_context_t *pLib,
+ int Channel) {
+ diva_trace_line_state_t *pLine = &pLib->lines[Channel];
+ int nr = Channel + 1;
+
+ if ((pLib->cur_parse_entry + LINE_PARSE_ENTRIES) >= pLib->parse_entries) {
+ diva_trace_error(pLib, -1, __FILE__, __LINE__);
+ return;
+ }
+
+ pLine->ChannelNumber = nr;
+
+ pLib->line_parse_entry_first[Channel] = pLib->cur_parse_entry;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Framing", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Framing[0];
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Line", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Line[0];
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Layer2", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer2[0];
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Layer3", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer3[0];
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Remote Address", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLine->RemoteAddress[0];
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Remote SubAddr", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLine->RemoteSubAddress[0];
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Local Address", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLine->LocalAddress[0];
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Local SubAddr", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLine->LocalSubAddress[0];
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\BC", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_BC;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\HLC", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_HLC;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\LLC", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_LLC;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Charges", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Charges;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Call Reference", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->CallReference;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Last Disc Cause", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLine->LastDisconnecCause;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\User ID", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->UserID[0];
+
+ pLib->line_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
+}
+
+static void diva_create_fax_parse_table(diva_strace_context_t *pLib,
+ int Channel) {
+ diva_trace_fax_state_t *pFax = &pLib->lines[Channel].fax;
+ int nr = Channel + 1;
+
+ if ((pLib->cur_parse_entry + FAX_PARSE_ENTRIES) >= pLib->parse_entries) {
+ diva_trace_error(pLib, -1, __FILE__, __LINE__);
+ return;
+ }
+ pFax->ChannelNumber = nr;
+
+ pLib->fax_parse_entry_first[Channel] = pLib->cur_parse_entry;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\FAX\\Event", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Event;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\FAX\\Page Counter", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Page_Counter;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\FAX\\Features", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Features;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\FAX\\Station ID", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Station_ID[0];
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\FAX\\Subaddress", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Subaddress[0];
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\FAX\\Password", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Password[0];
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\FAX\\Speed", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Speed;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\FAX\\Resolution", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Resolution;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\FAX\\Paper Width", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Width;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\FAX\\Paper Length", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Length;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\FAX\\Scanline Time", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Scanline_Time;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\FAX\\Disc Reason", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Disc_Reason;
+
+ pLib->fax_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
+}
+
+static void diva_create_modem_parse_table(diva_strace_context_t *pLib,
+ int Channel) {
+ diva_trace_modem_state_t *pModem = &pLib->lines[Channel].modem;
+ int nr = Channel + 1;
+
+ if ((pLib->cur_parse_entry + MODEM_PARSE_ENTRIES) >= pLib->parse_entries) {
+ diva_trace_error(pLib, -1, __FILE__, __LINE__);
+ return;
+ }
+ pModem->ChannelNumber = nr;
+
+ pLib->modem_parse_entry_first[Channel] = pLib->cur_parse_entry;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\Event", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Event;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\Norm", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Norm;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\Options", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Options;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\TX Speed", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->TxSpeed;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\RX Speed", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxSpeed;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\Roundtrip ms", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RoundtripMsec;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\Symbol Rate", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SymbolRate;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\RX Level dBm", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxLeveldBm;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\Echo Level dBm", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->EchoLeveldBm;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\SNR dB", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SNRdb;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\MAE", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->MAE;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\Local Retrains", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalRetrains;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\Remote Retrains", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteRetrains;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\Local Resyncs", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalResyncs;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\Remote Resyncs", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteResyncs;
+
+ sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+ "State\\B%d\\Modem\\Disc Reason", nr);
+ pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->DiscReason;
+
+ pLib->modem_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
+}
+
+static void diva_create_parse_table(diva_strace_context_t *pLib) {
+ int i;
+
+ for (i = 0; i < pLib->Channels; i++) {
+ diva_create_line_parse_table(pLib, i);
+ diva_create_modem_parse_table(pLib, i);
+ diva_create_fax_parse_table(pLib, i);
+ }
+
+ pLib->statistic_parse_first = pLib->cur_parse_entry;
+
+ /*
+ Outgoing Calls
+ */
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Outgoing Calls\\Calls");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.outg.Calls;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Outgoing Calls\\Connected");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.outg.Connected;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Outgoing Calls\\User Busy");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.outg.User_Busy;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Outgoing Calls\\No Answer");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.outg.No_Answer;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Outgoing Calls\\Wrong Number");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.outg.Wrong_Number;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Outgoing Calls\\Call Rejected");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.outg.Call_Rejected;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Outgoing Calls\\Other Failures");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.outg.Other_Failures;
+
+ /*
+ Incoming Calls
+ */
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Incoming Calls\\Calls");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.inc.Calls;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Incoming Calls\\Connected");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.inc.Connected;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Incoming Calls\\User Busy");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.inc.User_Busy;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Incoming Calls\\Call Rejected");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.inc.Call_Rejected;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Incoming Calls\\Wrong Number");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.inc.Wrong_Number;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Incoming Calls\\Incompatible Dst");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.inc.Incompatible_Dst;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Incoming Calls\\Out of Order");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.inc.Out_of_Order;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Incoming Calls\\Ignored");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.inc.Ignored;
+
+ /*
+ Modem Statistics
+ */
+ pLib->mdm_statistic_parse_first = pLib->cur_parse_entry;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Modem\\Disc Normal");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.mdm.Disc_Normal;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Modem\\Disc Unspecified");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.mdm.Disc_Unspecified;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Modem\\Disc Busy Tone");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.mdm.Disc_Busy_Tone;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Modem\\Disc Congestion");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.mdm.Disc_Congestion;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Modem\\Disc Carr. Wait");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.mdm.Disc_Carr_Wait;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Modem\\Disc Trn Timeout");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.mdm.Disc_Trn_Timeout;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Modem\\Disc Incompat.");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.mdm.Disc_Incompat;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Modem\\Disc Frame Rej.");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.mdm.Disc_Frame_Rej;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\Modem\\Disc V42bis");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.mdm.Disc_V42bis;
+
+ pLib->mdm_statistic_parse_last = pLib->cur_parse_entry - 1;
+
+ /*
+ Fax Statistics
+ */
+ pLib->fax_statistic_parse_first = pLib->cur_parse_entry;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Normal");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Normal;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Not Ident.");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Not_Ident;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc No Response");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_No_Response;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Retries");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Retries;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Unexp. Msg.");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Unexp_Msg;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc No Polling.");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_No_Polling;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Training");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Training;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Unexpected");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Unexpected;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Application");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Application;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Incompat.");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Incompat;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc No Command");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_No_Command;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Long Msg");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Long_Msg;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Supervisor");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Supervisor;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc SUB SEP PWD");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_SUB_SEP_PWD;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Invalid Msg");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Invalid_Msg;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Page Coding");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Page_Coding;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc App Timeout");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_App_Timeout;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\FAX\\Disc Unspecified");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.fax.Disc_Unspecified;
+
+ pLib->fax_statistic_parse_last = pLib->cur_parse_entry - 1;
+
+ /*
+ B-Layer1"
+ */
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\B-Layer1\\X-Frames");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.b1.X_Frames;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\B-Layer1\\X-Bytes");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.b1.X_Bytes;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\B-Layer1\\X-Errors");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.b1.X_Errors;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\B-Layer1\\R-Frames");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.b1.R_Frames;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\B-Layer1\\R-Bytes");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.b1.R_Bytes;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\B-Layer1\\R-Errors");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.b1.R_Errors;
+
+ /*
+ B-Layer2
+ */
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\B-Layer2\\X-Frames");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.b2.X_Frames;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\B-Layer2\\X-Bytes");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.b2.X_Bytes;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\B-Layer2\\X-Errors");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.b2.X_Errors;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\B-Layer2\\R-Frames");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.b2.R_Frames;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\B-Layer2\\R-Bytes");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.b2.R_Bytes;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\B-Layer2\\R-Errors");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.b2.R_Errors;
+
+ /*
+ D-Layer1
+ */
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\D-Layer1\\X-Frames");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.d1.X_Frames;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\D-Layer1\\X-Bytes");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.d1.X_Bytes;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\D-Layer1\\X-Errors");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.d1.X_Errors;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\D-Layer1\\R-Frames");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.d1.R_Frames;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\D-Layer1\\R-Bytes");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.d1.R_Bytes;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\D-Layer1\\R-Errors");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.d1.R_Errors;
+
+ /*
+ D-Layer2
+ */
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\D-Layer2\\X-Frames");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.d2.X_Frames;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\D-Layer2\\X-Bytes");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.d2.X_Bytes;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\D-Layer2\\X-Errors");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.d2.X_Errors;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\D-Layer2\\R-Frames");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.d2.R_Frames;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\D-Layer2\\R-Bytes");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.d2.R_Bytes;
+
+ strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+ "Statistics\\D-Layer2\\R-Errors");
+ pLib->parse_table[pLib->cur_parse_entry++].variable = \
+ &pLib->InterfaceStat.d2.R_Errors;
+
+
+ pLib->statistic_parse_last = pLib->cur_parse_entry - 1;
+}
+
+static void diva_trace_error(diva_strace_context_t *pLib,
+ int error, const char *file, int line) {
+ if (pLib->user_proc_table.error_notify_proc) {
+ (*(pLib->user_proc_table.error_notify_proc))(\
+ pLib->user_proc_table.user_context,
+ &pLib->instance, pLib->Adapter,
+ error, file, line);
+ }
+}
+
+/*
+ Delivery notification to user
+*/
+static void diva_trace_notify_user(diva_strace_context_t *pLib,
+ int Channel,
+ int notify_subject) {
+ if (pLib->user_proc_table.notify_proc) {
+ (*(pLib->user_proc_table.notify_proc))(pLib->user_proc_table.user_context,
+ &pLib->instance,
+ pLib->Adapter,
+ &pLib->lines[Channel],
+ notify_subject);
+ }
+}
+
+/*
+ Read variable value to they destination based on the variable type
+*/
+static int diva_trace_read_variable(diva_man_var_header_t *pVar,
+ void *variable) {
+ switch (pVar->type) {
+ case 0x03: /* MI_ASCIIZ - syting */
+ return (diva_strace_read_asz(pVar, (char *)variable));
+ case 0x04: /* MI_ASCII - string */
+ return (diva_strace_read_asc(pVar, (char *)variable));
+ case 0x05: /* MI_NUMBER - counted sequence of bytes */
+ return (diva_strace_read_ie(pVar, (diva_trace_ie_t *)variable));
+ case 0x81: /* MI_INT - signed integer */
+ return (diva_strace_read_int(pVar, (int *)variable));
+ case 0x82: /* MI_UINT - unsigned integer */
+ return (diva_strace_read_uint(pVar, (dword *)variable));
+ case 0x83: /* MI_HINT - unsigned integer, hex representetion */
+ return (diva_strace_read_uint(pVar, (dword *)variable));
+ case 0x87: /* MI_BITFLD - unsigned integer, bit representation */
+ return (diva_strace_read_uint(pVar, (dword *)variable));
+ }
+
+ /*
+ This type of variable is not handled, indicate error
+ Or one problem in management interface, or in application recodeing
+ table, or this application should handle it.
+ */
+ return (-1);
+}
+
+/*
+ Read signed integer to destination
+*/
+static int diva_strace_read_int(diva_man_var_header_t *pVar, int *var) {
+ byte *ptr = (char *)&pVar->path_length;
+ int value;
+
+ ptr += (pVar->path_length + 1);
+
+ switch (pVar->value_length) {
+ case 1:
+ value = *(char *)ptr;
+ break;
+
+ case 2:
+ value = (short)GET_WORD(ptr);
+ break;
+
+ case 4:
+ value = (int)GET_DWORD(ptr);
+ break;
+
+ default:
+ return (-1);
+ }
+
+ *var = value;
+
+ return (0);
+}
+
+static int diva_strace_read_uint(diva_man_var_header_t *pVar, dword *var) {
+ byte *ptr = (char *)&pVar->path_length;
+ dword value;
+
+ ptr += (pVar->path_length + 1);
+
+ switch (pVar->value_length) {
+ case 1:
+ value = (byte)(*ptr);
+ break;
+
+ case 2:
+ value = (word)GET_WORD(ptr);
+ break;
+
+ case 3:
+ value = (dword)GET_DWORD(ptr);
+ value &= 0x00ffffff;
+ break;
+
+ case 4:
+ value = (dword)GET_DWORD(ptr);
+ break;
+
+ default:
+ return (-1);
+ }
+
+ *var = value;
+
+ return (0);
+}
+
+/*
+ Read zero terminated ASCII string
+*/
+static int diva_strace_read_asz(diva_man_var_header_t *pVar, char *var) {
+ char *ptr = (char *)&pVar->path_length;
+ int length;
+
+ ptr += (pVar->path_length + 1);
+
+ if (!(length = pVar->value_length)) {
+ length = strlen(ptr);
+ }
+ memcpy(var, ptr, length);
+ var[length] = 0;
+
+ return (0);
+}
+
+/*
+ Read counted (with leading length byte) ASCII string
+*/
+static int diva_strace_read_asc(diva_man_var_header_t *pVar, char *var) {
+ char *ptr = (char *)&pVar->path_length;
+
+ ptr += (pVar->path_length + 1);
+ memcpy(var, ptr + 1, *ptr);
+ var[(int)*ptr] = 0;
+
+ return (0);
+}
+
+/*
+ Read one information element - i.e. one string of byte values with
+ one length byte in front
+*/
+static int diva_strace_read_ie(diva_man_var_header_t *pVar,
+ diva_trace_ie_t *var) {
+ char *ptr = (char *)&pVar->path_length;
+
+ ptr += (pVar->path_length + 1);
+
+ var->length = *ptr;
+ memcpy(&var->data[0], ptr + 1, *ptr);
+
+ return (0);
+}
+
+static int SuperTraceSetAudioTap(void *hLib, int Channel, int on) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+
+ if ((Channel < 1) || (Channel > pLib->Channels)) {
+ return (-1);
+ }
+ Channel--;
+
+ if (on) {
+ pLib->audio_tap_mask |= (1L << Channel);
+ } else {
+ pLib->audio_tap_mask &= ~(1L << Channel);
+ }
+
+ /*
+ EYE patterns have TM_M_DATA set as additional
+ condition
+ */
+ if (pLib->audio_tap_mask) {
+ pLib->trace_event_mask |= TM_M_DATA;
+ } else {
+ pLib->trace_event_mask &= ~TM_M_DATA;
+ }
+
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+static int SuperTraceSetBChannel(void *hLib, int Channel, int on) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+
+ if ((Channel < 1) || (Channel > pLib->Channels)) {
+ return (-1);
+ }
+ Channel--;
+
+ if (on) {
+ pLib->bchannel_trace_mask |= (1L << Channel);
+ } else {
+ pLib->bchannel_trace_mask &= ~(1L << Channel);
+ }
+
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+static int SuperTraceSetDChannel(void *hLib, int on) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+
+ if (on) {
+ pLib->trace_event_mask |= (TM_D_CHAN | TM_C_COMM | TM_DL_ERR | TM_LAYER1);
+ } else {
+ pLib->trace_event_mask &= ~(TM_D_CHAN | TM_C_COMM | TM_DL_ERR | TM_LAYER1);
+ }
+
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+static int SuperTraceSetInfo(void *hLib, int on) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+
+ if (on) {
+ pLib->trace_event_mask |= TM_STRING;
+ } else {
+ pLib->trace_event_mask &= ~TM_STRING;
+ }
+
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+static int SuperTraceClearCall(void *hLib, int Channel) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+
+ if ((Channel < 1) || (Channel > pLib->Channels)) {
+ return (-1);
+ }
+ Channel--;
+
+ pLib->clear_call_command |= (1L << Channel);
+
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+/*
+ Parse and update cumulative statistice
+*/
+static int diva_ifc_statistics(diva_strace_context_t *pLib,
+ diva_man_var_header_t *pVar) {
+ diva_man_var_header_t *cur;
+ int i, one_updated = 0, mdm_updated = 0, fax_updated = 0;
+
+ for (i = pLib->statistic_parse_first; i <= pLib->statistic_parse_last; i++) {
+ if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
+ if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
+ diva_trace_error(pLib, -3 , __FILE__, __LINE__);
+ return (-1);
+ }
+ one_updated = 1;
+ if ((i >= pLib->mdm_statistic_parse_first) && (i <= pLib->mdm_statistic_parse_last)) {
+ mdm_updated = 1;
+ }
+ if ((i >= pLib->fax_statistic_parse_first) && (i <= pLib->fax_statistic_parse_last)) {
+ fax_updated = 1;
+ }
+ }
+ }
+
+ /*
+ We do not use first event to notify user - this is the event that is
+ generated as result of EVENT ON operation and is used only to initialize
+ internal variables of application
+ */
+ if (mdm_updated) {
+ diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE);
+ } else if (fax_updated) {
+ diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE);
+ } else if (one_updated) {
+ diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE);
+ }
+
+ return (one_updated ? 0 : -1);
+}
+
+static int SuperTraceGetOutgoingCallStatistics(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+ pLib->outgoing_ifc_stats = 1;
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+static int SuperTraceGetIncomingCallStatistics(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+ pLib->incoming_ifc_stats = 1;
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+static int SuperTraceGetModemStatistics(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+ pLib->modem_ifc_stats = 1;
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+static int SuperTraceGetFaxStatistics(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+ pLib->fax_ifc_stats = 1;
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+static int SuperTraceGetBLayer1Statistics(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+ pLib->b1_ifc_stats = 1;
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+static int SuperTraceGetBLayer2Statistics(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+ pLib->b2_ifc_stats = 1;
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+static int SuperTraceGetDLayer1Statistics(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+ pLib->d1_ifc_stats = 1;
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+static int SuperTraceGetDLayer2Statistics(void *hLib) {
+ diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
+ pLib->d2_ifc_stats = 1;
+ return (ScheduleNextTraceRequest(pLib));
+}
+
+dword DivaSTraceGetMemotyRequirement(int channels) {
+ dword parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \
+ STAT_PARSE_ENTRIES + \
+ LINE_PARSE_ENTRIES + 1) * channels;
+ return (sizeof(diva_strace_context_t) + \
+ (parse_entries * sizeof(diva_strace_path2action_t)));
+}