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.

317 lines
10 KiB

  1. /*
  2. *
  3. * NOTES:
  4. *
  5. * REVISIONS:
  6. * ker02DEC92: Initial breakout of sensor classes into indiv files
  7. * ker04DEC92: Initial Filling in of Member Functions
  8. * SjA11Dec92: Validate method now returns ErrNO_ERROR rather than VALID.
  9. * pcy17Dec92: Now I do StateSensor::Validate before doing my own.
  10. * pcy16Feb93: No longer need to register for UPS_STATE
  11. * pcy16Feb93: Get transfer cause and ignore if self test
  12. * ajr22Feb93: included utils.h
  13. * jod05Apr93: Added changes for Deep Discharge
  14. * cad09Sep93: Fix for lights test causing events
  15. * pcy09Sep93: Check LINE_AVAILABILITY to make sure line is bad
  16. * pcy10Sep93: Hopefully this works now
  17. * pcy18Sep93: Cleaned up line condition handling
  18. * pcy20Sep93: handle line fails during tests and sim pwr fail
  19. * pcy12Oct93: 2 ABNORMALS to cause a line bad (fixes LF during cal)
  20. * pcy13Apr94: Use automatic variables decrease dynamic mem allocation
  21. * djs16Mar95: changed upsstate.h to sysstate.h
  22. * cgm10Apr96: Destructor should unregister
  23. */
  24. #define INCL_BASE
  25. #define INCL_DOS
  26. #define INCL_NOPM
  27. #include "cdefine.h"
  28. extern "C" {
  29. #if (C_OS & C_OS2)
  30. #include <os2.h>
  31. #endif
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include <malloc.h>
  35. #include <string.h>
  36. }
  37. #include "ulinecon.h"
  38. #include "comctrl.h"
  39. #include "device.h"
  40. #include "event.h"
  41. #include "utils.h"
  42. #include "sysstate.h"
  43. #include "timerman.h"
  44. #define QCOMMAND 0
  45. #define NINECOMMAND 1
  46. UtilityLineConditionSensor :: UtilityLineConditionSensor(PDevice aParent, PCommController aCommController)
  47. : StateSensor(aParent, aCommController, UTILITY_LINE_CONDITION),
  48. theInformationSource(0), theLineFailCount(0), theUpsState(0)
  49. {
  50. storeState(LINE_GOOD);
  51. theCommController->RegisterEvent(UTILITY_LINE_CONDITION, this);
  52. theDevice->RegisterEvent(BATTERY_CALIBRATION_CONDITION, this);
  53. theDevice->RegisterEvent(SIMULATE_POWER_FAIL, this);
  54. theDevice->RegisterEvent(SELF_TEST_STATE, this);
  55. }
  56. INT UtilityLineConditionSensor::Update(PEvent anEvent)
  57. {
  58. INT err = ErrNO_ERROR;
  59. INT aCode = anEvent->GetCode();
  60. PCHAR aValue = anEvent->GetValue();
  61. switch(aCode)
  62. {
  63. case BATTERY_CALIBRATION_CONDITION:
  64. switch(atoi(aValue))
  65. {
  66. case BATTERY_CALIBRATION_IN_PROGRESS:
  67. theCommController->UnregisterEvent(UTILITY_LINE_CONDITION, this);
  68. theCommController->RegisterEvent(LINE_CONDITION_TEST, this);
  69. theInformationSource = NINECOMMAND;
  70. break;
  71. case NO_BATTERY_CALIBRATION:
  72. case NO_BATTERY_CALIBRATION_IN_PROGRESS:
  73. case BATTERY_CALIBRATION_CANCELLED:
  74. if (theInformationSource == NINECOMMAND)
  75. {
  76. theCommController->UnregisterEvent(LINE_CONDITION_TEST, this);
  77. theCommController->RegisterEvent(UTILITY_LINE_CONDITION, this);
  78. theInformationSource = QCOMMAND;
  79. }
  80. break;
  81. }
  82. break;
  83. case LINE_CONDITION_TEST:
  84. //
  85. // Convert the event to a UTILITY_LINE_CONDITION event and
  86. // send it to myself
  87. //
  88. switch(atoi(aValue))
  89. {
  90. case ABNORMAL_CONDITION:
  91. {
  92. //
  93. // Only after the second successive abnormal condition should
  94. // we bother with this. This is so we ignore ABNORMAL_COND
  95. // events at the start of deep discharge
  96. //
  97. if(theLineFailCount > 0)
  98. {
  99. CHAR lbtmp[31];
  100. sprintf(lbtmp, "%d", LINE_BAD);
  101. if ((err = StateSensor::Validate(UTILITY_LINE_CONDITION,
  102. lbtmp)) == ErrNO_ERROR)
  103. {
  104. Event evt(UTILITY_LINE_CONDITION, LINE_BAD);
  105. storeValue(lbtmp);
  106. UpdateObj::Update(&evt);
  107. }
  108. }
  109. else
  110. {
  111. theLineFailCount++;
  112. }
  113. }
  114. break;
  115. case NO_ABNORMAL_CONDITION:
  116. {
  117. theLineFailCount = 0;
  118. CHAR lbtmp[31];
  119. sprintf(lbtmp, "%d", LINE_GOOD);
  120. if ((err = StateSensor::Validate(UTILITY_LINE_CONDITION,
  121. lbtmp)) == ErrNO_ERROR)
  122. {
  123. Event evt(UTILITY_LINE_CONDITION, LINE_GOOD);
  124. storeValue(lbtmp);
  125. UpdateObj::Update(&evt);
  126. }
  127. }
  128. break;
  129. } // switch for case LINE_CONDITION_TEST
  130. break;
  131. case UTILITY_LINE_CONDITION:
  132. if ((err = Validate(aCode, aValue)) == ErrNO_ERROR)
  133. {
  134. storeValue(aValue);
  135. UpdateObj::Update(anEvent);
  136. }
  137. break;
  138. case SIMULATE_POWER_FAIL:
  139. switch(atoi(aValue))
  140. {
  141. case SIMULATE_POWER_FAIL:
  142. SET_BIT(theUpsState, SIMULATE_POWER_FAIL_BIT);
  143. break;
  144. case SIMULATE_POWER_FAIL_OVER:
  145. CLEAR_BIT(theUpsState, SIMULATE_POWER_FAIL_BIT);
  146. break;
  147. }
  148. break;
  149. case SELF_TEST_STATE:
  150. switch(atoi(aValue))
  151. {
  152. case SELF_TEST_IN_PROGRESS:
  153. SET_BIT(theUpsState, SELF_TEST_BIT);
  154. break;
  155. case NO_SELF_TEST_IN_PROGRESS:
  156. CLEAR_BIT(theUpsState, SELF_TEST_BIT);
  157. break;
  158. }
  159. break;
  160. }
  161. return err;
  162. }
  163. INT UtilityLineConditionSensor::Validate(INT aCode, const PCHAR aValue)
  164. {
  165. INT err = ErrNO_ERROR;
  166. if (aCode != theSensorCode)
  167. {
  168. err = ErrINVALID_CODE;
  169. }
  170. else if(IS_STATE(UPS_STATE_IN_SELF_TEST))
  171. {
  172. err = ErrTEST_IN_PROGRESS;
  173. }
  174. else
  175. {
  176. switch(atoi(aValue))
  177. {
  178. case LINE_GOOD:
  179. {
  180. theLineFailCount = 0;
  181. //
  182. // Make sure line is good to handle UPSLinkism
  183. // that doesnt change tranfer cause when line
  184. // fails during self test or sim pwrfail
  185. //
  186. CHAR line_state[32];
  187. theCommController->Get(LINE_CONDITION_TEST,
  188. line_state);
  189. if(atoi(line_state) == ABNORMAL_CONDITION)
  190. {
  191. err = ErrINVALID_VALUE;
  192. }
  193. break;
  194. }
  195. case LINE_BAD:
  196. //
  197. // Dont do this if we're a BackUPS
  198. //
  199. if (theDevice->IsA() != BACKUPS)
  200. {
  201. //
  202. // If we're in DeepDischarge ignore LINE_BAD events
  203. //
  204. if(theInformationSource != NINECOMMAND)
  205. {
  206. //
  207. // If we're simulating a power fail
  208. // don't try to stop the event
  209. //
  210. if(!(IS_STATE(UPS_STATE_SIMULATED_POWER_FAIL)))
  211. {
  212. CHAR transfer_cause[32];
  213. CHAR self_test[32];
  214. CHAR line_state[32];
  215. //
  216. // If transfer is due to a self test double check
  217. // to see if line is bad
  218. //
  219. theCommController->Get(TRANSFER_CAUSE, transfer_cause);
  220. _itoa(SELF_TEST_TRANSFER, self_test, 10);
  221. if (strcmp(transfer_cause, self_test) == 0)
  222. {
  223. //
  224. // Make sure line is bad to handle UPSLinkism
  225. // that doesnt change tranfer cause when line
  226. // fails during self test or sim pwrfail
  227. //
  228. theCommController->Get(LINE_CONDITION_TEST, line_state);
  229. if(atoi(line_state) == NO_ABNORMAL_CONDITION)
  230. {
  231. err = ErrINVALID_VALUE;
  232. }
  233. else
  234. {
  235. //
  236. // Wait a while to handle UPS-Linkism for
  237. // the 9 command that returns 00 at the start
  238. // of a self test
  239. //
  240. _theTimerManager->Wait(3000L);
  241. theCommController->Get(LINE_CONDITION_TEST, line_state);
  242. if(atoi(line_state) == NO_ABNORMAL_CONDITION)
  243. {
  244. err = ErrINVALID_VALUE;
  245. }
  246. }
  247. }
  248. //
  249. // Same for Lights Test
  250. //
  251. CHAR ups_status[32];
  252. theDevice->Get(UPS_STATE, ups_status);
  253. if (atoi(ups_status) & UPS_STATE_IN_LIGHTS_TEST)
  254. {
  255. err = ErrINVALID_VALUE;
  256. }
  257. }
  258. }
  259. } // if (!= BACKUPS)
  260. break;
  261. default:
  262. err = ErrINVALID_VALUE;
  263. break;
  264. }
  265. if (err == ErrNO_ERROR)
  266. {
  267. err = StateSensor::Validate(aCode, aValue);
  268. }
  269. }
  270. return err;
  271. }
  272. UtilityLineConditionSensor :: ~UtilityLineConditionSensor()
  273. {
  274. if (theCommController)
  275. theCommController->UnregisterEvent(UTILITY_LINE_CONDITION, this);
  276. if (theDevice) {
  277. theDevice->UnregisterEvent(BATTERY_CALIBRATION_CONDITION, this);
  278. theDevice->UnregisterEvent(SIMULATE_POWER_FAIL, this);
  279. theDevice->UnregisterEvent(SELF_TEST_STATE, this);
  280. }
  281. }