Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

249 lines
6.3 KiB

  1. /*
  2. *
  3. * NOTES:
  4. *
  5. * REVISIONS:
  6. * xxxddMMMyy
  7. * TSC17May93: Added SmartSerialPort :: SYSTClosePort()
  8. * TSC31May93: Added define for _theConfigManager, changed SmartSerialPort
  9. * to native NT, added error logging
  10. * srt28Mar96: Added plug-n-play cable support for simple.
  11. * srt15Apr96: Added plug-n-play cable support for smart.
  12. * pam04Apr96: Changed to accomodate CWC
  13. * srl100696: changed ExitWindowsEx to InitiateSystomShutdown to support clean shut down of
  14. * mirrored drives
  15. * srl100696: commented out the lines to set pins high in simpleportwrite. This will keep
  16. * the (simple only) ups from shutting off before op. system has a chance to shut down.
  17. * mds29Dec97: Set pins high in simple SYSTWriteToPort to correctly shutdown
  18. * UPS when using a Share-Ups in Confirmed Mode
  19. * tjg12Jan98: Fixed return code from SYSTWriteToPort (for TURN_OFF_UPS case)
  20. *
  21. * v-stebe 29Jul2000 Fixed PREfix error (bug #112602)
  22. */
  23. #include "cdefine.h"
  24. extern "C" {
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <windows.h>
  28. }
  29. #include "_defs.h"
  30. #include "serport.h"
  31. #include "err.h"
  32. #include "upsdev.h"
  33. #include "cfgmgr.h"
  34. #include "cfgcodes.h"
  35. #include "codes.h"
  36. #include "timerman.h"
  37. #include "errlogr.h"
  38. #include "utils.h"
  39. extern "C"{
  40. #include "upsreg.h"
  41. }
  42. #define ComMAXREADBUFSIZE 128
  43. #define ComMAXWRITEBUFSIZE 128
  44. #define ComMAXPORTNAMESIZE 10
  45. #define INTERCHARACTER_DELAY 20 // Delay in msec between char writes
  46. #define LOW_BATTERY_RETRYS 3
  47. #define WRITEWAIT 50L
  48. #define READWAIT 50L
  49. #define PORTNAME_LENGTH 100
  50. INT UpsCommDevice::CreatePort()
  51. {
  52. CHAR szSignallingType[32];
  53. TCHAR szPortName[PORTNAME_LENGTH];
  54. CHAR szPortType[32];
  55. INT err = ErrNO_ERROR;
  56. _theConfigManager->Get(CFG_UPS_SIGNALLING_TYPE, szSignallingType);
  57. _theConfigManager->Get(CFG_UPS_PORT_TYPE, szPortType);
  58. InitUPSConfigBlock();
  59. GetUPSConfigPort(szPortName, PORTNAME_LENGTH);
  60. if (strcmp(szSignallingType, "Smart") == 0)
  61. {
  62. if (strcmp(szPortType, "Serial") == 0)
  63. {
  64. thePort = new SmartSerialPort(szPortName, theCableType);
  65. }
  66. }
  67. else if (strcmp(szSignallingType, "Simple") == 0)
  68. {
  69. if (strcmp(szPortType, "Serial") == 0)
  70. {
  71. //thePort = new SimpleSerialPort(szPortName);
  72. }
  73. }
  74. if (!thePort)
  75. {
  76. err = ErrINVALID_VALUE;
  77. }
  78. return err;
  79. }
  80. INT SmartSerialPort::SYSTOpenPort()
  81. {
  82. INT err = ErrNO_ERROR;
  83. // If the port is already open, close it before trying to open it again
  84. if (FileHandle != INVALID_HANDLE_VALUE) {
  85. CloseHandle (FileHandle);
  86. FileHandle = INVALID_HANDLE_VALUE;
  87. }
  88. FileHandle = CreateFile(theSmartSerialPortName,
  89. GENERIC_READ | GENERIC_WRITE,
  90. 0, NULL, OPEN_EXISTING, 0,
  91. NULL);
  92. if (FileHandle != INVALID_HANDLE_VALUE) {
  93. // If we get here, we have a good comm port handle
  94. DCB dcb;
  95. GetCommState(FileHandle, &dcb);
  96. // If here, a good handle and a filled-in dcb. So, set the comm params
  97. dcb.BaudRate = 2400;
  98. dcb.ByteSize = 8;
  99. dcb.Parity = NOPARITY;
  100. dcb.StopBits = ONESTOPBIT;
  101. dcb.EvtChar = '\n';
  102. dcb.fOutxCtsFlow = FALSE;
  103. dcb.fDtrControl = DTR_CONTROL_ENABLE;
  104. if (theCableType == PNP) {
  105. dcb.fRtsControl = RTS_CONTROL_DISABLE;
  106. }
  107. else {
  108. dcb.fRtsControl = RTS_CONTROL_ENABLE;
  109. }
  110. //ClearCommBreak(FileHandle);
  111. SetCommState(FileHandle, &dcb);
  112. SetCommMask(FileHandle, EV_RXFLAG);
  113. //
  114. // Set so we dont block\n
  115. //
  116. COMMTIMEOUTS wait_time;
  117. memset (&wait_time, 0, (DWORD) sizeof (COMMTIMEOUTS));
  118. wait_time.ReadTotalTimeoutMultiplier = 1L;
  119. wait_time.ReadTotalTimeoutConstant = (DWORD)0;
  120. SetCommTimeouts(FileHandle, &wait_time);
  121. CHAR buf[128];
  122. USHORT len = sizeof(buf);
  123. // Clear the port to avoid reading garbage
  124. while (SYSTReadFromPort(buf, (USHORT *) &len, 500L) == ErrNO_ERROR);
  125. err = ErrNO_ERROR;
  126. }
  127. else {
  128. err = ErrOPEN_FAILED;
  129. }
  130. return err;
  131. }
  132. INT SmartSerialPort::SYSTWriteToPort(CHAR* lpszBuf)
  133. {
  134. DWORD bytes_written;
  135. DWORD com_errors;
  136. COMSTAT com_status;
  137. INT err = ErrNO_ERROR;
  138. INT first_char = TRUE;
  139. while (*lpszBuf) {
  140. if(!first_char) {
  141. Sleep(theWaitTime);
  142. }
  143. else {
  144. first_char = FALSE;
  145. }
  146. ClearCommError(FileHandle, &com_errors, &com_status);
  147. if(!WriteFile(FileHandle, lpszBuf, 1L, &bytes_written, NULL)) {
  148. err = ErrWRITE_FAILED;
  149. break;
  150. }
  151. lpszBuf++;
  152. }
  153. return(err);
  154. }
  155. INT SmartSerialPort::SYSTReadFromPort(PCHAR readbuf, USHORT* size,
  156. ULONG timeout)
  157. {
  158. INT err = ErrNO_ERROR;
  159. USHORT buffer_size = *size;
  160. DWORD com_errors;
  161. COMSTAT com_status;
  162. ClearCommError(FileHandle, &com_errors, &com_status);
  163. *size = 0;
  164. DWORD bytes_read = 0;
  165. Sleep(WRITEWAIT);
  166. ULONG time_slept = WRITEWAIT;
  167. while(buffer_size>0) {
  168. CHAR read_char;
  169. INT rval = ReadFile(FileHandle,(PVOID)&read_char, 1, &bytes_read,
  170. NULL);
  171. if(rval) {
  172. if(bytes_read == 1) {
  173. readbuf[*size] = read_char;
  174. (*size)++;
  175. if(read_char == '\n') {
  176. break;
  177. }
  178. buffer_size--;
  179. }
  180. else {
  181. if(time_slept < timeout) {
  182. Sleep(READWAIT);
  183. time_slept += READWAIT;
  184. }
  185. else {
  186. err = ErrREAD_FAILED;
  187. break;
  188. }
  189. }
  190. }
  191. else {
  192. err = ErrREAD_FAILED;
  193. break;
  194. }
  195. }
  196. readbuf[*size] = '\0';
  197. return err;
  198. }
  199. INT SmartSerialPort :: SYSTClosePort()
  200. {
  201. CloseHandle (FileHandle);
  202. FileHandle = INVALID_HANDLE_VALUE;
  203. return (ErrNO_ERROR);
  204. }