diff options
Diffstat (limited to 'drivers/isdn/hardware/eicon/maintidi.c')
-rw-r--r-- | drivers/isdn/hardware/eicon/maintidi.c | 2194 |
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 00000000000..23960cb6eaa --- /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, "Unknon 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, "Unknon 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; + diva_strace_read_uint (pVar, &l2_state); + + 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))); +} + |