/* * * 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 #include #include } #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); }