|
|
/*
* * NOTES: * * REVISIONS: * xxxddMMMyy * TSC17May93: Added SmartSerialPort :: SYSTClosePort() * TSC31May93: Added define for _theConfigManager, changed SmartSerialPort * to native NT, added error logging * srt28Mar96: Added plug-n-play cable support for simple. * srt15Apr96: Added plug-n-play cable support for smart. * pam04Apr96: Changed to accomodate CWC * srl100696: changed ExitWindowsEx to InitiateSystomShutdown to support clean shut down of * mirrored drives * srl100696: commented out the lines to set pins high in simpleportwrite. This will keep * the (simple only) ups from shutting off before op. system has a chance to shut down. * mds29Dec97: Set pins high in simple SYSTWriteToPort to correctly shutdown * UPS when using a Share-Ups in Confirmed Mode * tjg12Jan98: Fixed return code from SYSTWriteToPort (for TURN_OFF_UPS case) * * v-stebe 29Jul2000 Fixed PREfix error (bug #112602) */
#include "cdefine.h"
extern "C" { #include <stdlib.h>
#include <string.h>
#include <windows.h>
}
#include "_defs.h"
#include "serport.h"
#include "err.h"
#include "upsdev.h"
#include "cfgmgr.h"
#include "cfgcodes.h"
#include "codes.h"
#include "timerman.h"
#include "errlogr.h"
#include "utils.h"
extern "C"{ #include "upsreg.h"
} #define ComMAXREADBUFSIZE 128
#define ComMAXWRITEBUFSIZE 128
#define ComMAXPORTNAMESIZE 10
#define INTERCHARACTER_DELAY 20 // Delay in msec between char writes
#define LOW_BATTERY_RETRYS 3
#define WRITEWAIT 50L
#define READWAIT 50L
#define PORTNAME_LENGTH 100
INT UpsCommDevice::CreatePort() { CHAR szSignallingType[32]; TCHAR szPortName[PORTNAME_LENGTH]; CHAR szPortType[32]; INT err = ErrNO_ERROR; _theConfigManager->Get(CFG_UPS_SIGNALLING_TYPE, szSignallingType); _theConfigManager->Get(CFG_UPS_PORT_TYPE, szPortType); InitUPSConfigBlock();
GetUPSConfigPort(szPortName, PORTNAME_LENGTH);
if (strcmp(szSignallingType, "Smart") == 0) { if (strcmp(szPortType, "Serial") == 0) { thePort = new SmartSerialPort(szPortName, theCableType); } } else if (strcmp(szSignallingType, "Simple") == 0) { if (strcmp(szPortType, "Serial") == 0) { //thePort = new SimpleSerialPort(szPortName);
} } if (!thePort) { err = ErrINVALID_VALUE; } return err; }
INT SmartSerialPort::SYSTOpenPort() { INT err = ErrNO_ERROR;
// If the port is already open, close it before trying to open it again
if (FileHandle != INVALID_HANDLE_VALUE) { CloseHandle (FileHandle); FileHandle = INVALID_HANDLE_VALUE; } FileHandle = CreateFile(theSmartSerialPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (FileHandle != INVALID_HANDLE_VALUE) { // If we get here, we have a good comm port handle
DCB dcb; GetCommState(FileHandle, &dcb); // If here, a good handle and a filled-in dcb. So, set the comm params
dcb.BaudRate = 2400; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcb.EvtChar = '\n'; dcb.fOutxCtsFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_ENABLE; if (theCableType == PNP) { dcb.fRtsControl = RTS_CONTROL_DISABLE; } else { dcb.fRtsControl = RTS_CONTROL_ENABLE; } //ClearCommBreak(FileHandle);
SetCommState(FileHandle, &dcb);
SetCommMask(FileHandle, EV_RXFLAG);
//
// Set so we dont block\n
//
COMMTIMEOUTS wait_time; memset (&wait_time, 0, (DWORD) sizeof (COMMTIMEOUTS)); wait_time.ReadTotalTimeoutMultiplier = 1L; wait_time.ReadTotalTimeoutConstant = (DWORD)0; SetCommTimeouts(FileHandle, &wait_time); CHAR buf[128]; USHORT len = sizeof(buf); // Clear the port to avoid reading garbage
while (SYSTReadFromPort(buf, (USHORT *) &len, 500L) == ErrNO_ERROR);
err = ErrNO_ERROR; } else { err = ErrOPEN_FAILED; } return err; }
INT SmartSerialPort::SYSTWriteToPort(CHAR* lpszBuf) { DWORD bytes_written; DWORD com_errors; COMSTAT com_status;
INT err = ErrNO_ERROR;
INT first_char = TRUE;
while (*lpszBuf) { if(!first_char) { Sleep(theWaitTime); } else { first_char = FALSE; }
ClearCommError(FileHandle, &com_errors, &com_status); if(!WriteFile(FileHandle, lpszBuf, 1L, &bytes_written, NULL)) { err = ErrWRITE_FAILED; break; }
lpszBuf++; } return(err); }
INT SmartSerialPort::SYSTReadFromPort(PCHAR readbuf, USHORT* size, ULONG timeout) { INT err = ErrNO_ERROR; USHORT buffer_size = *size;
DWORD com_errors; COMSTAT com_status; ClearCommError(FileHandle, &com_errors, &com_status);
*size = 0; DWORD bytes_read = 0; Sleep(WRITEWAIT); ULONG time_slept = WRITEWAIT;
while(buffer_size>0) { CHAR read_char; INT rval = ReadFile(FileHandle,(PVOID)&read_char, 1, &bytes_read, NULL); if(rval) { if(bytes_read == 1) { readbuf[*size] = read_char; (*size)++; if(read_char == '\n') { break; } buffer_size--; } else { if(time_slept < timeout) { Sleep(READWAIT); time_slept += READWAIT; } else { err = ErrREAD_FAILED; break; } }
} else { err = ErrREAD_FAILED; break; } } readbuf[*size] = '\0'; return err; }
INT SmartSerialPort :: SYSTClosePort() { CloseHandle (FileHandle); FileHandle = INVALID_HANDLE_VALUE; return (ErrNO_ERROR); }
|