2196 lines
67 KiB
C
2196 lines
67 KiB
C
/*
|
|
*
|
|
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)));
|
|
}
|
|
|