diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 01:02:30 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 01:02:30 +0000 |
commit | 76cb841cb886eef6b3bee341a2266c76578724ad (patch) | |
tree | f5892e5ba6cc11949952a6ce4ecbe6d516d6ce58 /drivers/isdn/hardware/eicon/maintidi.c | |
parent | Initial commit. (diff) | |
download | linux-76cb841cb886eef6b3bee341a2266c76578724ad.tar.xz linux-76cb841cb886eef6b3bee341a2266c76578724ad.zip |
Adding upstream version 4.19.249.upstream/4.19.249upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
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 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))); +} |