📄 maintidi.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, "Unknon IDI Ind (DMA mode): %02x", Ind); } p += (this_ind_length+1); total_length -= (4 + this_ind_length); } } break; case MAN_INFO_IND: if (process_idi_info (pLib, (diva_man_var_header_t*)p)) { return (-1); } break; case MAN_EVENT_IND: if (process_idi_event (pLib, (diva_man_var_header_t*)p)) { return (-1); } break; case MAN_TRACE_IND: if (pLib->trace_on == 1) { /* Ignore first trace event that is result of EVENT_ON operation */ pLib->trace_on++; } else { /* Delivery XLOG buffer to application */ if (pLib->user_proc_table.trace_proc) { (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context, &pLib->instance, pLib->Adapter, p, pLib->e.R->PLength); } } break; default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -