📄 udconfig.c
字号:
/* $Header: "%n Ver=%v %f LastEdit=%w Locker=%l" */
/* "UDCONFIG.C Ver=8 5-Dec-97,10:59:02 LastEdit=JIMV Locker=***_NOBODY_***" */
/***********************************************************************\
* *
* Copyright Wonderware Software Development Corp. 1992-1997 *
* *
* ThisFileName="L:\ww\dde_serv\src\udsample\udconfig.c" *
* LastEditDate="1997 Dec 05 10:59:00" *
* *
\***********************************************************************/
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <types.h>
#include <stat.h>
#include <io.h>
#include <time.h>
#include <timeb.h>
#include <direct.h>
#include "ntconv.h"
#include "hmemcpy.h"
#include "chainmgr.h"
#include "config.h"
#include "udgetstr.h"
#include "udselbox.h"
#include "rc.h"
#include "getradio.h"
#include "getintg.h"
#include "wwassert.h"
#include "tmpbuf.h"
#include "lmem.h"
#include "protypes.h"
#include "protocol.h"
#include "udprot.h"
#include "cmdlnpth.h"
#include "wwcomdlg.h"
#include "portfncs.h"
#include "filefncs.h"
#include "uddefs.h"
#include "Utitech.h"
#include "udpntscn.h"
#include "CheckItem.h"
USES_ASSERT
#define MAX_COIL_READ_SIZE 2040
#define MAX_REG_READ_SIZE 255
extern int iAllocatedDevices;
extern HANDLE hInst;
extern HWND hWndParent;
extern char szCfgPath[];
extern BOOL WriteConfigInASCII;
extern BOOL bUsesComPorts;
extern BOOL bUsesBoards;
/***********************************************************************/
BOOL bUsesComPorts /* =TRUE if ComPorts are used */
#ifdef USES_COMPORTS
= TRUE;
#else
= FALSE;
#endif
BOOL bUsesBoards /* =TRUE if Boards are used */
#ifdef USES_BOARDS
= TRUE;
#else
= FALSE;
#endif
WW_CP_PARAMS comPort[NUM_COMPORTS]; /* array of com port configurations */
CHAIN BoardCfgList; /* linked list of board configurations */
CHAIN TopicCfgList; /* linked list of topic configurations */
/***********************************************************************/
static LPTOPIC_CFG lpTopicCfgToEdit;
static LPBOARD_CFG lpBoardCfgToEdit;
static WW_CP_PARAMS DefaultCpParams;
static char defTopicName[33];
static BYTE defTopicAddress = 1;
static WORD defCoilReadSize = 2000;
static WORD defRegReadSize = 125;
static LONG defUpdateInterval = 1000L;
static BYTE newTopicEntry;
static DWORD dwEditChannelID = 0;
static char defBoardName[33] = "UD:0";
static WORD memSeg;
//static WORD ioAddr; // This is a bug, should be int
static int ioAddr;
static BOARD_CFG DefaultBoardParams;
static BYTE newBoardEntry;
/***********************************************************************
* Prototypes *
***********************************************************************/
/***********************************************************************/
/* exported functions for configuration dialogs */
#ifdef __cplusplus
extern "C" {
#endif
void FAR *CALLBACK GetHeadTopicCfg( void );
void far *CALLBACK GetNextTopicCfg( void far *lpTopicCfg );
char far *CALLBACK GetTopicCfgName( void far *lpTopicCfg );
void CALLBACK DeleteTopicCfg( HWND hWnd, void far *lpTopicCfg );
void CALLBACK AddTopicCfg( HWND hWnd );
void CALLBACK ConfigTopicCfg( HWND hWnd, void far *lpTopicCfg, BOOL bModifyAllowed );
BOOL WINAPI TopicDialogProc(HWND, UINT, WPARAM, LPARAM);
int CALLBACK ConfigureSaveCallback( void );
void FAR *CALLBACK GetHeadBoardCfg( void );
void far *CALLBACK GetNextBoardCfg( void far *lpBoardCfg );
char far *CALLBACK GetBoardCfgName( void far *lpBoardCfg );
void CALLBACK DeleteBoardCfg( HWND hWnd, void FAR *lpBoardCfg);
void CALLBACK AddBoardCfg( HWND hWnd );
void CALLBACK ConfigBoardCfg( HWND hWnd, void FAR *lpBoardCfg, BOOL bModifyAllowed );
BOOL WINAPI BoardDialogProc(HWND, UINT, WPARAM, LPARAM);
#ifdef __cplusplus
}
#endif
/***********************************************************************/
/* local functions */
#define COMPORT_CHANNEL_TYPE 0
#define BOARD_CHANNEL_TYPE 1
static int WINAPI GetChannelType (DWORD dwChannelID);
static VOID WINAPI InitTopicParamPort(LPSTNPARAM, DWORD);
static BOOL WINAPI ConfigureSave(void);
static LPSTR WINAPI GetConfigFilePath(LPSTR);
static VOID WINAPI TopicCfgDeleteFromList(LPTOPIC_CFG lpTopicCfg);
static VOID WINAPI BoardCfgDeleteFromList(LPBOARD_CFG lpBoardToDelete);
static VOID WINAPI TopicCfgCheckDelete(HWND hDlg, LPTOPIC_CFG lpTopicCfg);
static VOID WINAPI InitChannelNameComboBox(HWND hDlg);
static BOOL WINAPI TopicCfgCheckName(HWND hDlg, LPTOPIC_CFG lpTopicCfg, LPSTR lpszTopicName);
static DWORD WINAPI BoardCfgGetID(LPBOARD_CFG lpBoardCfg);
static VOID WINAPI BoardCfgGetName(LPBOARD_CFG lpBoardCfg, LPSTR boardName);
static LPBOARD_CFG WINAPI BoardCfgFromID(DWORD dwBoardID);
static VOID WINAPI BoardCfgCheckDelete(HWND hDlg, LPBOARD_CFG lpBoardCfg);
static BOOL WINAPI BoardCfgCheckName(HWND hDlg, LPBOARD_CFG lpBoardCfg, LPSTR lpszName);
static BOOL WINAPI ValidHexNumber(PSTR p);
/***********************************************************************
***********************************************************************
* TOPIC NAME VALIDATION routines *
***********************************************************************
***********************************************************************/
/***********************************************************************/
/** Check list of configured topics for matching name.
Fields for the corresponding stations are initialized here.
returns TRUE if found **/
BOOL
WINAPI
ValidateTopic(LPSTR lpszTopicName,
LPSTNPARAM lpTopicParam)
{
LPTOPIC_CFG lpTopicCfg;
BOOL found;
CHAINSCANNER topic_scanner;
#ifdef DEBUG_CALL_TRAFFIC
if (Verbose)
debug ("ValidateTopic: %Fs", lpszTopicName);
#endif
/* initialize return value */
found = FALSE;
/* search for topic with indicated name */
lpTopicCfg = (LPTOPIC_CFG) FindFirstItem (&TopicCfgList,
SCAN_FROM_HEAD, /* search forward */
TopicCfgNameMatch, /* check if name matches */
(LPSTR) lpszTopicName, /* comparison value */
&topic_scanner); /* used for FindNextItem */
if (lpTopicCfg != (LPTOPIC_CFG) NULL) {
/* topic found, copy parameters */
InitTopicParamPort(lpTopicParam, lpTopicCfg->tc_channelID);
lpTopicParam->spUpdatePeriod = lpTopicCfg->tc_updateInterval;
/*******************************************************\
Any protocol dependent data structure fields must
be initialized here.
\*******************************************************/
lpTopicParam->spCoilReadSize = lpTopicCfg->tc_coilReadSize;
lpTopicParam->spRegReadSize = lpTopicCfg->tc_regReadSize;
lpTopicParam->spTopicID = lpTopicCfg->tc_topicAddress;
found = TRUE;
}
/* indicate whether topic was found */
return (found);
} /* ValidateTopic */
/***********************************************************************/
/** get type of port according to how I/O channels are being used
and the channel ID number, if appropriate **/
int
WINAPI
GetChannelType (DWORD dwChannelID)
{
int iChannelType;
/* determine what type of channel is being configured */
if (bUsesComPorts && bUsesBoards)
{
/* both types of channel available, determine type by channel ID */
if (dwChannelID <= MAX_COMPORT)
iChannelType = COMPORT_CHANNEL_TYPE; /* ComPort */
else
iChannelType = BOARD_CHANNEL_TYPE; /* Board */
}
else
{
/* only one type of channel available, determine which type */
if (bUsesComPorts)
iChannelType = COMPORT_CHANNEL_TYPE; /* ComPort */
else
iChannelType = BOARD_CHANNEL_TYPE; /* Board */
}
return (iChannelType);
} /* GetChannelType */
/***********************************************************************/
/** initialize topic parameter structure and port selection **/
static
VOID
WINAPI
InitTopicParamPort(LPSTNPARAM lpTopicParam, DWORD dwChannelID)
{
int iChannelType;
int i;
int iMax;
char ch;
char FAR *lpModeString;
LPBOARD_CFG lpBoardCfg;
/* determine what type of channel is being configured */
iChannelType = GetChannelType (dwChannelID);
/* handle initialization according to channel type */
if (iChannelType == COMPORT_CHANNEL_TYPE)
{
/* I/O channel is a ComPort */
/* get set-up mode string for I/O channel */
WWFormCpModeString( &comPort[0], (UINT)dwChannelID, lpTopicParam->spConfigString);
/* get pointer to mode string */
lpModeString = (char FAR *) &lpTopicParam->spConfigString[0];
/* copy string until end or ':' */
iMax = sizeof(lpTopicParam->spChannelName)-1;
i = 0; ch = *(lpModeString++);
while (ch && (ch != ':') && (i < iMax)) {
lpTopicParam->spChannelName[i++] = ch;
ch = *(lpModeString++);
}
lpTopicParam->spChannelName[i] = '\0';
/* get memory segment, I/O address for I/O channel */
lpTopicParam->spMemSegment = 0;
lpTopicParam->spIoAddr = 0;
/* set reply timeout for I/O channel */
lpTopicParam->spReplyTimeout = (int) comPort[dwChannelID-1].uReplyTimeout;
}
else
{
/* I/O channel is a board */
/* get pointer to indicated board */
lpBoardCfg = BoardCfgFromID(dwChannelID);
assert(lpBoardCfg);
/* get name of I/O channel */
lstrcpy(lpTopicParam->spChannelName, lpBoardCfg->cp_name);
/* get set-up mode string for I/O channel */
lpTopicParam->spConfigString[0] = '\0';
/* get memory segment, I/O address for I/O channel */
lpTopicParam->spMemSegment = lpBoardCfg->cp_memSegment;
lpTopicParam->spIoAddr = lpBoardCfg->cp_ioAddr;
/* set reply timeout for I/O channel */
lpTopicParam->spReplyTimeout = lpBoardCfg->cp_replyTimeout;
}
} /* InitTopicParamPort */
/***********************************************************************
***********************************************************************
* POINT NAME VALIDATION routines *
***********************************************************************
***********************************************************************/
/***********************************************************************/
/** tables for point name validation **/
/** The process of validating names can be done "brute force",
comparing strings, getting addresses, and looking for special
characters as is appropriate to the device protocol.
The following example shows point name validation using a table approach.
The example server has two memory ranges:
V memory -- variables, 16 bit cells, address range 1-512
C memory -- counters, 16 bit cells, address range 1-512
**/
/***********************************************\
Device specific names and identifiers go here
\***********************************************/
/* pattern types */
#define P_NONE 0
#define P_ADD 1 /* address only */
#define P_ADDS 2 /* address with suffix */
#define P_BIT 3 /* address with bit select */
#define P_STR 4 /* start and end addresses for string */
#define P_STRS 5 /* start and end addresses for string with suffix */
/******************************************************************\
Define the pattern table to suit the needs of the device.
The first entry in each table element should always be a string.
A '9' represents any string of decimal digits.
A '?' represents a single-character "wild card" character.
Everything else must be a literal match.
\******************************************************************/
/* pattern table */
#define MNE_LEN 6 /* max length of pattern mnemonics */
typedef struct tagPATTERNENTRY /* table element structure */
{char mne[MNE_LEN+1]; /* point mnemonic pattern */
int pattern_type; /* pattern type */
int dataType; /* point data type */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -