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.

1070 lines
28 KiB

  1. /*
  2. * pcy28jun96: Added IS_ stuff for menus
  3. * pcy28jun96: Cleaned up. Handles BackUps. Removed 1G.
  4. * pcy18Jul96: Made to work with old back ends
  5. * pcy19Jul96: Made to work with for backups
  6. * djs31Jul96: And still more IS_ stuff....
  7. * das17Oct96: Prevented EVENT_LOG_UPDATE data from getting overwritten
  8. * srt16Dec96: Added values to 220v allowed values list.
  9. * inf25Feb97: Loaded localisable strings from the resource file
  10. * srt04Jun97: Added IS_EXT_SLEEP_UPS case to get.
  11. * srt09Jun97: Added a parent that is an Update obj.
  12. * ntf20Aug97: If connected to an "old" Back-UPS Pro (simple) with Smart in
  13. * the INI file, with a PnP cable attached, and when compiled
  14. * with VC++ 4.2 then FirmwareRevManager constructor crashed
  15. * because passed a NULL pointer to strdup, add check for this,
  16. * and allocated an empty string.
  17. * ntf20Aug97: Added free(theValue) in ReInitialize
  18. * tjgOct1097: Implemented IsDarkStar method
  19. * tjgOct1597: Fixed IS_LIGHTS_TEST Get ... not supported by DarkStar
  20. * tjg10Nov97: Fixed IsDarkStar to check for NULL values
  21. * tjg02Dec97: Changed darkstar to symmetra
  22. * tjg30Jan98: Added destructor
  23. * clk27Sep98: Added IS_MULTIBYTE and IS_SINGLEBYTE to get (determines
  24. * if we're using a single byte resource file or multibyte)
  25. *
  26. * v-stebe 29Jul2000 Added checks for mem. alloc. failures (bug #46334)
  27. */
  28. #include "cdefine.h"
  29. #include "apc.h"
  30. #include "err.h"
  31. #include "codes.h"
  32. #include "cfgmgr.h"
  33. #include "firmman.h"
  34. #include "utils.h"
  35. extern "C" {
  36. #include <stdio.h>
  37. #include <string.h>
  38. #include <stdlib.h>
  39. }
  40. // @@@ start
  41. // @@@ end
  42. //-------------------------------------------------------------------
  43. // Global internal constants for class
  44. const INT UPS_MODEL_CHAR = 0;
  45. const INT REVISION_LETTER_CHAR = 1;
  46. const INT UTILITY_VOLTAGE_CHAR = 2;
  47. const CHAR SU_250_FIRMWARE_CHAR = '2';
  48. const CHAR SU_370_FIRMWARE_CHAR = '3';
  49. const CHAR SU_400_FIRMWARE_CHAR = '4';
  50. const CHAR SU_600_FIRMWARE_CHAR = '6';
  51. const CHAR SU_900_FIRMWARE_CHAR = '7';
  52. const CHAR SU_1250_FIRMWARE_CHAR = '8';
  53. const CHAR SU_2000_FIRMWARE_CHAR = '9';
  54. const CHAR PO_3000_FIRMWARE_CHAR = '0';
  55. const CHAR PO_5000_FIRMWARE_CHAR = '5';
  56. const CHAR SU_100_VOLT_CHAR = 'A';
  57. const CHAR SU_120_VOLT_CHAR = 'D';
  58. const CHAR SU_208_VOLT_CHAR = 'M';
  59. const CHAR SU_220_VOLT_CHAR = 'I';
  60. const CHAR SU_200_VOLT_CHAR = 'J';
  61. const CHAR BACKUPS_CHAR = 'Q';
  62. const CHAR FIRST_GEN_CHAR = 'A';
  63. const CHAR SECOND_GEN_CHAR = 'Q';
  64. const CHAR THIRD_GEN_CHAR = 'W';
  65. const FIRMWARE_LENGTH_C = 3;
  66. //-------------------------------------------------------------------
  67. // Description: Constructor
  68. //-------------------------------------------------------------------
  69. FirmwareRevManager :: FirmwareRevManager(PUpdateObj aParent, PCHAR aFirmwareRevChars) :
  70. theParent(aParent),
  71. theValue(NULL)
  72. {
  73. if (aFirmwareRevChars != NULL) {
  74. theValue = _strdup(aFirmwareRevChars);
  75. }
  76. else {
  77. theValue = (char *) malloc(1);
  78. if (theValue != NULL) {
  79. *theValue = '\0';
  80. }
  81. }
  82. }
  83. FirmwareRevManager :: ~FirmwareRevManager()
  84. {
  85. if (theValue) {
  86. free(theValue);
  87. theValue = NULL;
  88. }
  89. }
  90. //-------------------------------------------------------------------
  91. // Description: Save new firmware rev value. This method avoids
  92. // the destruction/creation cycle necessary
  93. // otherwise.
  94. //-------------------------------------------------------------------
  95. VOID FirmwareRevManager :: ReInitialize(PCHAR aFirmwareRevChars)
  96. {
  97. if (theValue) {
  98. free(theValue);
  99. theValue = NULL;
  100. }
  101. if (aFirmwareRevChars) {
  102. theValue = _strdup(aFirmwareRevChars);
  103. }
  104. }
  105. //-------------------------------------------------------------------
  106. // Description: Class identifier
  107. //-------------------------------------------------------------------
  108. INT FirmwareRevManager :: IsA() const
  109. {
  110. return FIRMWAREREVMANAGER;
  111. }
  112. //-------------------------------------------------------------------
  113. // Description: Check for a 100 volt UPS
  114. //-------------------------------------------------------------------
  115. INT FirmwareRevManager :: Is100VoltUps()
  116. {
  117. INT answer = FALSE;
  118. if (theValue) {
  119. if (theValue[UTILITY_VOLTAGE_CHAR] == SU_100_VOLT_CHAR) {
  120. answer = TRUE;
  121. }
  122. }
  123. return answer;
  124. }
  125. //-------------------------------------------------------------------
  126. // Description: Check for a 120 volt UPS
  127. //-------------------------------------------------------------------
  128. INT FirmwareRevManager :: Is120VoltUps()
  129. {
  130. INT answer = FALSE;
  131. if (theValue) {
  132. if (theValue[UTILITY_VOLTAGE_CHAR] == SU_120_VOLT_CHAR) {
  133. answer = TRUE;
  134. }
  135. }
  136. return answer;
  137. }
  138. //-------------------------------------------------------------------
  139. // Description: Check for a 200 volt UPS
  140. //-------------------------------------------------------------------
  141. INT FirmwareRevManager :: Is200VoltUps()
  142. {
  143. if(theValue) {
  144. return (theValue[UTILITY_VOLTAGE_CHAR] == SU_200_VOLT_CHAR);
  145. }
  146. else {
  147. return FALSE;
  148. }
  149. }
  150. //-------------------------------------------------------------------
  151. // Description: Check for a 208 volt UPS
  152. //-------------------------------------------------------------------
  153. INT FirmwareRevManager :: Is208VoltUps()
  154. {
  155. if(theValue) {
  156. return (theValue[UTILITY_VOLTAGE_CHAR] == SU_208_VOLT_CHAR);
  157. }
  158. else {
  159. return FALSE;
  160. }
  161. }
  162. //-------------------------------------------------------------------
  163. // Description: Check for a 220 volt UPS
  164. //-------------------------------------------------------------------
  165. INT FirmwareRevManager :: Is220VoltUps()
  166. {
  167. if(theValue) {
  168. return (theValue[UTILITY_VOLTAGE_CHAR] == SU_220_VOLT_CHAR);
  169. }
  170. else {
  171. return FALSE;
  172. }
  173. }
  174. //-------------------------------------------------------------------
  175. // Description: Check for a 250 volt UPS
  176. //-------------------------------------------------------------------
  177. INT FirmwareRevManager :: Is250()
  178. {
  179. INT answer = FALSE;
  180. if (theValue) {
  181. if (theValue[UPS_MODEL_CHAR] == SU_250_FIRMWARE_CHAR) {
  182. answer = TRUE;
  183. }
  184. }
  185. return answer;
  186. }
  187. //-------------------------------------------------------------------
  188. // Description: Check for a 370 volt UPS
  189. //-------------------------------------------------------------------
  190. INT FirmwareRevManager :: Is370()
  191. {
  192. INT answer = FALSE;
  193. if (theValue) {
  194. if (theValue[UPS_MODEL_CHAR] == SU_370_FIRMWARE_CHAR) {
  195. answer = TRUE;
  196. }
  197. }
  198. return answer;
  199. }
  200. //-------------------------------------------------------------------
  201. // Description: Check for a 400 volt UPS
  202. //-------------------------------------------------------------------
  203. INT FirmwareRevManager :: Is400()
  204. {
  205. INT answer = FALSE;
  206. if (theValue) {
  207. if (theValue[UPS_MODEL_CHAR] == SU_400_FIRMWARE_CHAR) {
  208. answer = TRUE;
  209. }
  210. }
  211. return answer;
  212. }
  213. //-------------------------------------------------------------------
  214. // Description: Check for a 370 volt UPS
  215. //-------------------------------------------------------------------
  216. INT FirmwareRevManager :: Is400_or_370()
  217. {
  218. INT answer = FALSE;
  219. if (Is400() || Is370())
  220. {
  221. answer = TRUE;
  222. }
  223. return answer;
  224. }
  225. //-------------------------------------------------------------------
  226. // Description: Check for a 600 volt UPS
  227. //-------------------------------------------------------------------
  228. INT FirmwareRevManager :: Is600()
  229. {
  230. INT answer = FALSE;
  231. if (theValue) {
  232. if (theValue[UPS_MODEL_CHAR] == SU_600_FIRMWARE_CHAR) {
  233. answer = TRUE;
  234. }
  235. }
  236. return answer;
  237. }
  238. //-------------------------------------------------------------------
  239. // Description: Check for a 900 volt UPS
  240. //-------------------------------------------------------------------
  241. INT FirmwareRevManager :: Is900()
  242. {
  243. INT answer = FALSE;
  244. if (theValue) {
  245. if (theValue[UPS_MODEL_CHAR] == SU_900_FIRMWARE_CHAR) {
  246. answer = TRUE;
  247. }
  248. }
  249. return answer;
  250. }
  251. //-------------------------------------------------------------------
  252. // Description: Check for a 1250 volt UPS
  253. //-------------------------------------------------------------------
  254. INT FirmwareRevManager :: Is1250()
  255. {
  256. INT answer = FALSE;
  257. if (theValue) {
  258. if (theValue[UPS_MODEL_CHAR] == SU_1250_FIRMWARE_CHAR) {
  259. answer = TRUE;
  260. }
  261. }
  262. return answer;
  263. }
  264. //-------------------------------------------------------------------
  265. // Description: Check for a 2000 volt UPS
  266. //-------------------------------------------------------------------
  267. INT FirmwareRevManager :: Is2000()
  268. {
  269. INT answer = FALSE;
  270. if (theValue) {
  271. if (theValue[UPS_MODEL_CHAR] == SU_2000_FIRMWARE_CHAR) {
  272. answer = TRUE;
  273. }
  274. }
  275. return answer;
  276. }
  277. //-------------------------------------------------------------------
  278. // Description: Check for a 3000 volt UPS
  279. //-------------------------------------------------------------------
  280. INT FirmwareRevManager :: Is3000()
  281. {
  282. INT answer = FALSE;
  283. if (theValue) {
  284. if (theValue[UPS_MODEL_CHAR] == PO_3000_FIRMWARE_CHAR) {
  285. answer = TRUE;
  286. }
  287. }
  288. return answer;
  289. }
  290. //-------------------------------------------------------------------
  291. // Description: Check for a 5000 volt UPS
  292. //-------------------------------------------------------------------
  293. INT FirmwareRevManager :: Is5000()
  294. {
  295. INT answer = FALSE;
  296. if (theValue) {
  297. if (theValue[UPS_MODEL_CHAR] == PO_5000_FIRMWARE_CHAR) {
  298. answer = TRUE;
  299. }
  300. }
  301. return answer;
  302. }
  303. //-------------------------------------------------------------------
  304. // Description: Check for a Matrix
  305. //-------------------------------------------------------------------
  306. INT FirmwareRevManager :: IsMatrix()
  307. {
  308. return (Is3000() || Is5000());
  309. }
  310. //-------------------------------------------------------------------
  311. // Description: Dark Stars are not supported on old back-ends
  312. //-------------------------------------------------------------------
  313. INT FirmwareRevManager :: IsSymmetra()
  314. {
  315. INT err = FALSE;
  316. CHAR value[10];
  317. theParent->Get(DECIMAL_FIRMWARE_REV, value);
  318. if (value) {
  319. PCHAR token = strtok(value, ".");
  320. if (token) {
  321. INT sku = atoi(token);
  322. if (sku >= 200 && sku <= 279) {
  323. err = TRUE;
  324. }
  325. }
  326. }
  327. return (err);
  328. }
  329. //-------------------------------------------------------------------
  330. // Description: XL units are not supported on old back-ends
  331. //-------------------------------------------------------------------
  332. INT FirmwareRevManager :: IsXL()
  333. {
  334. return FALSE;
  335. }
  336. //-------------------------------------------------------------------
  337. // Description: Get the number of internal battery packs.
  338. //-------------------------------------------------------------------
  339. VOID FirmwareRevManager :: GetNumberOfInternalBatteryPacks(PCHAR aValue)
  340. {
  341. INT Number_Of_Internal_Packs = 1;
  342. if (IsMatrix())
  343. {
  344. Number_Of_Internal_Packs = 0;
  345. }
  346. _itoa(Number_Of_Internal_Packs,aValue,10);
  347. }
  348. //-------------------------------------------------------------------
  349. // Description: Check for a Back-UPS
  350. //-------------------------------------------------------------------
  351. INT FirmwareRevManager :: IsBackUps()
  352. {
  353. //
  354. // Set to -1 to indicate unitialized;
  355. //
  356. static INT im_a_backups = -1;
  357. //
  358. // If we haven't done so already, go check the INI file to see if
  359. // we're using simple signalling. To us, anything that uses simple
  360. // signalling is BackUPS
  361. //
  362. if(im_a_backups == -1) {
  363. CHAR signalling_type[128];
  364. _theConfigManager->Get(CFG_UPS_SIGNALLING_TYPE, signalling_type);
  365. if(_strcmpi(signalling_type, "Simple") == 0) {
  366. im_a_backups = TRUE;
  367. }
  368. else {
  369. im_a_backups = FALSE;
  370. }
  371. }
  372. return im_a_backups;
  373. }
  374. //-------------------------------------------------------------------
  375. // Description: Check for a first gen UPS and only a first gen UPS
  376. //-------------------------------------------------------------------
  377. INT FirmwareRevManager :: IsFirstGen()
  378. {
  379. INT answer = FALSE;
  380. if (theValue) {
  381. if ((theValue[REVISION_LETTER_CHAR] >= FIRST_GEN_CHAR) &&
  382. (theValue[REVISION_LETTER_CHAR] < SECOND_GEN_CHAR)){
  383. answer = TRUE;
  384. }
  385. }
  386. return answer;
  387. }
  388. //-------------------------------------------------------------------
  389. // Description: Check for a second gen and only second gen UPS
  390. //-------------------------------------------------------------------
  391. INT FirmwareRevManager :: IsSecondGen()
  392. {
  393. INT answer = FALSE;
  394. if (theValue) {
  395. if ((theValue[REVISION_LETTER_CHAR] >= SECOND_GEN_CHAR) &&
  396. (theValue[REVISION_LETTER_CHAR] < THIRD_GEN_CHAR)) {
  397. answer = TRUE;
  398. }
  399. }
  400. return answer;
  401. }
  402. //-------------------------------------------------------------------
  403. // Description: Check for a third gen UPS or greater The upper
  404. // bound should be modified when a fourth gen UPS
  405. // exists.
  406. //-------------------------------------------------------------------
  407. INT FirmwareRevManager :: IsThirdGen()
  408. {
  409. INT answer = FALSE;
  410. if (theValue) {
  411. if (theValue[REVISION_LETTER_CHAR] >= THIRD_GEN_CHAR) {
  412. answer = TRUE;
  413. }
  414. }
  415. return answer;
  416. }
  417. //-------------------------------------------------------------------
  418. // Description: Determine UPS name based on firmware rev
  419. //-------------------------------------------------------------------
  420. VOID FirmwareRevManager::GetUPSNameFromFirmware(PCHAR aValue)
  421. {
  422. const INT Maximum_UPS_Name_Length_C = 10;
  423. CHAR model_char[Maximum_UPS_Name_Length_C];
  424. GetUPSModelChar(model_char);
  425. INT err =_theConfigManager->Get(CFG_UPS_MODEL_BASE +
  426. atoi(model_char), aValue);
  427. if ((err != ErrNO_ERROR) && (err != ErrDEFAULT_VALUE_USED)) {
  428. err = ErrNO_ERROR;
  429. strcpy(aValue, "UNKNOWN MODEL");
  430. }
  431. }
  432. //-------------------------------------------------------------------
  433. // Description: Determine UPS model character
  434. //-------------------------------------------------------------------
  435. VOID FirmwareRevManager::GetUPSModelChar(PCHAR aValue)
  436. {
  437. if(theValue) {
  438. _itoa(theValue[UPS_MODEL_CHAR],aValue,10);
  439. }
  440. else {
  441. _itoa(FALSE,aValue,10);
  442. }
  443. }
  444. //-------------------------------------------------------------------
  445. // Description: Determine UPS firmware rev character
  446. //-------------------------------------------------------------------
  447. CHAR FirmwareRevManager::GetFirmwareRevChar(VOID)
  448. {
  449. return theValue[REVISION_LETTER_CHAR];
  450. }
  451. //-------------------------------------------------------------------
  452. // Description: Determine country code
  453. //-------------------------------------------------------------------
  454. VOID FirmwareRevManager::GetCountryCode(PCHAR aValue)
  455. {
  456. if (theValue) {
  457. _itoa(theValue[UTILITY_VOLTAGE_CHAR],aValue,10);
  458. }
  459. else {
  460. _itoa(FALSE,aValue,10);
  461. }
  462. }
  463. //-------------------------------------------------------------------------
  464. // Description: Public interface to return firmware rev parameters.
  465. //-------------------------------------------------------------------------
  466. INT FirmwareRevManager::Get(INT aCode, PCHAR aValue)
  467. {
  468. INT err = ErrNO_ERROR;
  469. //
  470. // Back-UPS only handle a few codes. Handle it separately.
  471. //
  472. if(IsBackUps()) {
  473. switch(aCode) {
  474. case IS_BACKUPS:
  475. strcpy(aValue,"Yes");
  476. break;
  477. case UPS_MODEL:
  478. strcpy(aValue,"Back-UPS");
  479. break;
  480. // Do not overwrite data
  481. case EVENT_LOG_UPDATE:
  482. break;
  483. //
  484. // These are for compatibility for pre-Viper back-ends who
  485. // won't answer us
  486. //
  487. case IS_FLEX_EVENTS:
  488. case IS_EVENT_LOGGING:
  489. strcpy(aValue, "Yes");
  490. break;
  491. case SUPPORTED_FEATURES:
  492. sprintf(
  493. aValue,
  494. "%d,%d,%d,%d,%d",
  495. UTILITY_LINE_CONDITION,
  496. BATTERY_CONDITION,
  497. TURN_OFF_UPS_ON_BATTERY,
  498. TURN_OFF_UPS,
  499. TURN_ON_SMART_MODE);
  500. break;
  501. default:
  502. //
  503. // Unless we specifically say we support something, we don't.
  504. //
  505. strcpy(aValue, "No");
  506. break;
  507. }
  508. }
  509. else {
  510. //
  511. // All other UPSs are handled here
  512. //
  513. switch(aCode)
  514. {
  515. case COUNTRY_CODE:
  516. GetCountryCode(aValue);
  517. break;
  518. case UPSMODEL_CHAR:
  519. GetUPSModelChar(aValue);
  520. break;
  521. case IS_BACKUPS:
  522. //
  523. // Back-UPS are handled earlier. This code is for smart UPSs only.
  524. //
  525. strcpy(aValue,"No");
  526. break;
  527. case IS_FIRST_GEN:
  528. {
  529. if(IsFirstGen()) {
  530. strcpy(aValue,"Yes");
  531. }
  532. else {
  533. strcpy(aValue,"No");
  534. }
  535. }
  536. break;
  537. case IS_SECOND_GEN:
  538. {
  539. //
  540. // For now we lie and say third gens are second gens. Third gen
  541. // feature support is asked individually. Eventually we should
  542. // never have to ask what UPS we are, just if we support the feature.
  543. //
  544. if(IsSecondGen() || IsThirdGen()) {
  545. strcpy(aValue,"Yes");
  546. }
  547. else {
  548. strcpy(aValue,"No");
  549. }
  550. }
  551. break;
  552. case IS_THIRD_GEN:
  553. {
  554. if(IsThirdGen()) {
  555. strcpy(aValue,"Yes");
  556. }
  557. else {
  558. strcpy(aValue,"No");
  559. }
  560. }
  561. break;
  562. case IS_MATRIX:
  563. if (IsMatrix()) {
  564. strcpy(aValue,"Yes");
  565. }
  566. else {
  567. strcpy(aValue,"No");
  568. }
  569. break;
  570. case IS_SYMMETRA:
  571. if (IsSymmetra()) {
  572. strcpy(aValue,"Yes");
  573. }
  574. else {
  575. strcpy(aValue,"No");
  576. }
  577. break;
  578. case SUPPORTED_FEATURES:
  579. sprintf(
  580. aValue,
  581. "%d,%d,%d,%d,%d",
  582. UTILITY_LINE_CONDITION,
  583. BATTERY_CONDITION,
  584. TURN_OFF_UPS_ON_BATTERY,
  585. TURN_OFF_UPS,
  586. TURN_ON_SMART_MODE);
  587. break;
  588. //
  589. // All UPSs do this, or they better
  590. //
  591. case IS_SELF_TEST:
  592. case IS_SIMULATE_POWER_FAIL:
  593. strcpy(aValue,"Yes");
  594. break;
  595. case IS_LIGHTS_TEST:
  596. if (IsSymmetra()) {
  597. strcpy(aValue, "No");
  598. }
  599. else {
  600. strcpy(aValue, "Yes");
  601. }
  602. break;
  603. //
  604. // 2G features and later. If UPSs don't these they should
  605. case IS_FREQUENCY:
  606. case IS_BATTERY_CAPACITY:
  607. case IS_BATTERY_VOLTAGE:
  608. case IS_COPYRIGHT:
  609. case IS_RUNTIME_REMAINING:
  610. case IS_SENSITIVITY:
  611. case IS_LOW_BATTERY_DURATION:
  612. case IS_ALARM_DELAY:
  613. case IS_SHUTDOWN_DELAY:
  614. case IS_TURN_ON_DELAY:
  615. case IS_MANUFACTURE_DATE:
  616. case IS_SERIAL_NUMBER:
  617. case IS_UPS_ID:
  618. case IS_UTILITY_VOLTAGE:
  619. case IS_OUTPUT_VOLTAGE:
  620. case IS_UPS_LOAD:
  621. case IS_BATTERY_DATE:
  622. case IS_SELF_TEST_SCHEDULE:
  623. case IS_BATTERY_CALIBRATION:
  624. case IS_RATED_OUTPUT_VOLTAGE:
  625. case IS_HIGH_TRANSFER_VOLTAGE:
  626. case IS_LOW_TRANSFER_VOLTAGE:
  627. strcpy(aValue,"Yes");
  628. break;
  629. //
  630. // Dark-Star and Matrix don't do this
  631. //
  632. case IS_SMARTBOOST:
  633. if(IsSymmetra() || IsMatrix()) {
  634. strcpy(aValue,"No");
  635. }
  636. else {
  637. strcpy(aValue,"Yes");
  638. }
  639. break;
  640. //
  641. // Smart-Trim is supported only 3G Smart-UPSs
  642. //
  643. case IS_SMARTTRIM:
  644. {
  645. if (IsSecondGen() || IsMatrix() || IsSymmetra()) {
  646. strcpy(aValue,"No");
  647. }
  648. else {
  649. strcpy(aValue,"Yes");
  650. }
  651. }
  652. break;
  653. //
  654. // Matrix doesn't do this. WHo knows why?
  655. //
  656. case IS_MIN_RETURN_CAPACITY:
  657. {
  658. if (IsMatrix()) {
  659. strcpy(aValue,"No");
  660. }
  661. else {
  662. strcpy(aValue,"Yes");
  663. }
  664. }
  665. break;
  666. //
  667. // All post 2G UPSs should implement this.
  668. //
  669. case IS_CTRL_Z:
  670. {
  671. if (IsSecondGen()) {
  672. strcpy(aValue,"No");
  673. }
  674. else {
  675. strcpy(aValue,"Yes");
  676. }
  677. }
  678. break;
  679. //
  680. // Special things the Smart-UPS 400 and 250 do.
  681. //
  682. case IS_LOAD_SENSING:
  683. {
  684. if (Is400_or_370()||Is250() ) {
  685. strcpy(aValue,"Yes");
  686. }
  687. else {
  688. strcpy(aValue,"No");
  689. }
  690. }
  691. break;
  692. //
  693. // Things the Smart-UPS 400 and 250 can't do.
  694. //
  695. case IS_TURN_OFF_WITH_DELAY:
  696. case IS_EEPROM_PROGRAM_CAPABLE:
  697. case IS_ADMIN_SHUTDOWN:
  698. {
  699. if (Is400_or_370()||Is250() ) {
  700. strcpy(aValue,"No");
  701. }
  702. else {
  703. strcpy(aValue,"Yes");
  704. }
  705. }
  706. break;
  707. //
  708. // Only Matrix and Dark-Star do bypass
  709. case IS_BYPASS:
  710. if(IsMatrix() || IsSymmetra()) {
  711. strcpy(aValue,"Yes");
  712. }
  713. else {
  714. strcpy(aValue,"No");
  715. }
  716. break;
  717. //
  718. // This is really for 2G Smart-UPS only. All other UPSs should
  719. // be able to tell us themself with CTRL-Z
  720. //
  721. case HIGH_TRANSFER_VALUES:
  722. {
  723. if ( Is100VoltUps() ) {
  724. strcpy(aValue, "108,110,112,114");
  725. }
  726. else if ( Is208VoltUps() ) {
  727. if(IsMatrix()) {
  728. strcpy(aValue, "240,244,248,252");
  729. }
  730. else {
  731. strcpy(aValue, "224,229,234,239");
  732. }
  733. }
  734. else if ( Is220VoltUps() )
  735. strcpy(aValue, "253,264,271,280");
  736. else {
  737. // 120 Volt UPS
  738. strcpy(aValue, "129,132,135,138");
  739. }
  740. }
  741. break;
  742. //
  743. // This is really for 2G Smart-UPS only. All other UPSs should
  744. // be able to tell us themself with CTRL-Z
  745. //
  746. case LOW_TRANSFER_VALUES:
  747. {
  748. if ( !Is120VoltUps() ) {
  749. if ( Is100VoltUps() ) {
  750. if(GetFirmwareRevChar() < 'T') {
  751. strcpy(aValue, "081,083,085,087");
  752. }
  753. else if(GetFirmwareRevChar() == 'T') {
  754. strcpy(aValue, "081,083,087,090");
  755. }
  756. else {
  757. strcpy(aValue, "081,085,090,092");
  758. }
  759. }
  760. else if ( Is208VoltUps() ) {
  761. if(IsMatrix()) {
  762. strcpy(aValue, "156");
  763. }
  764. else {
  765. strcpy(aValue, "168,172,177,182");
  766. }
  767. }
  768. else if ( Is220VoltUps() ) {
  769. strcpy(aValue, "188,196,204,208");
  770. }
  771. }
  772. // 120 Volt UPS
  773. else {
  774. strcpy(aValue, "097,100,103,106");
  775. }
  776. }
  777. break;
  778. case RATED_OUTPUT_VALUES:
  779. {
  780. if (Is120VoltUps()) {
  781. strcpy(aValue, "115");
  782. }
  783. else if (Is100VoltUps()) {
  784. strcpy(aValue, "100");
  785. }
  786. else if ( Is208VoltUps() ) {
  787. strcpy(aValue, "208");
  788. }
  789. else if ( Is220VoltUps() ) {
  790. strcpy(aValue, "220,225,230,240");
  791. }
  792. else if ( Is200VoltUps() ) {
  793. strcpy(aValue, "200");
  794. }
  795. else {
  796. //
  797. // We screwed up, but return something meaningful.
  798. //
  799. strcpy(aValue, "115");
  800. }
  801. }
  802. break;
  803. //
  804. // For those UPSs too dumb to know
  805. //
  806. case SINGLE_HIGH_TRANSFER_VALUE:
  807. {
  808. if ( Is120VoltUps() ) {
  809. strcpy(aValue, "132");
  810. }
  811. else if ( Is100VoltUps() ) {
  812. strcpy(aValue, "110");
  813. }
  814. else if ( Is208VoltUps() ) {
  815. strcpy(aValue, "229");
  816. }
  817. else if ( Is220VoltUps() ) {
  818. strcpy(aValue, "253");
  819. }
  820. }
  821. break;
  822. //
  823. // For those UPSs too dumb to know
  824. //
  825. case SINGLE_LOW_TRANSFER_VALUE:
  826. {
  827. if ( Is120VoltUps() ) {
  828. strcpy(aValue, "103");
  829. }
  830. else if ( Is100VoltUps() ) {
  831. strcpy(aValue, "85");
  832. }
  833. else if ( Is208VoltUps() ) {
  834. strcpy(aValue, "177");
  835. }
  836. else if ( Is220VoltUps() ) {
  837. strcpy(aValue, "196");
  838. }
  839. }
  840. break;
  841. case UPS_NAME:
  842. GetUPSNameFromFirmware(aValue);
  843. break;
  844. case INTERNAL_BATTERY_PACKS:
  845. GetNumberOfInternalBatteryPacks(aValue);
  846. break;
  847. //
  848. // External packs are editable only on XL UPSs. UPSs like
  849. // Matrix and Dark-Star are smart enough to figure it out
  850. // themself
  851. //
  852. case EXTERNAL_PACKS_CHANGEABLE:
  853. {
  854. if(IsXL()) {
  855. strcpy(aValue,"Yes");
  856. }
  857. else {
  858. strcpy(aValue,"No");
  859. }
  860. }
  861. break;
  862. case MAX_VOLTAGE_RANGE_VALUE:
  863. {
  864. if ( Is120VoltUps() ) {
  865. strcpy(aValue, "140");
  866. }
  867. else if ( Is100VoltUps() ) {
  868. strcpy(aValue, "130");
  869. }
  870. else if (Is208VoltUps() || Is200VoltUps()) {
  871. strcpy(aValue, "260");
  872. }
  873. else if ( Is220VoltUps() ) {
  874. strcpy(aValue, "280");
  875. }
  876. }
  877. break;
  878. case MIN_VOLTAGE_RANGE_VALUE:
  879. {
  880. if ( Is120VoltUps() ) {
  881. strcpy(aValue, "90");
  882. }
  883. else if ( Is100VoltUps() ) {
  884. strcpy(aValue, "80");
  885. }
  886. else if (Is208VoltUps() || Is200VoltUps()) {
  887. strcpy(aValue, "160");
  888. }
  889. else if ( Is220VoltUps() ) {
  890. strcpy(aValue, "180");
  891. }
  892. }
  893. break;
  894. //
  895. // These are for compatibility for pre-Viper back-ends who
  896. // won't answer us
  897. //
  898. case IS_FLEX_EVENTS:
  899. case IS_EVENT_LOGGING:
  900. case IS_DATA_LOGGING:
  901. case IS_UPS_TEMPERATURE:
  902. strcpy(aValue, "Yes");
  903. break;
  904. case DECIMAL_FIRMWARE_REV:
  905. case FIRMWARE_REV:
  906. strcpy(aValue, theValue);
  907. break;
  908. case IS_EXT_SLEEP_UPS:
  909. strcpy(aValue,"No");
  910. if (IsThirdGen() && // Not supported by 2nd gen and matrix units
  911. !IsMatrix()) {
  912. CHAR theDFRev[32], *tmp;
  913. err = theParent->Get(DECIMAL_FIRMWARE_REV,theDFRev); //fails if comm lost...now what?
  914. if (err == ErrNO_ERROR) {
  915. strtok(theDFRev,".");
  916. tmp = strtok(NULL,".");
  917. if (tmp && atoi(tmp) >= 11) { // middle # of dec firm rev must be >=11
  918. strcpy(aValue,"Yes");
  919. }
  920. }
  921. }
  922. break;
  923. default:
  924. strcpy(aValue, "No");
  925. break;
  926. }
  927. }
  928. return err;
  929. }