windows-nt/Source/XPSP1/NT/ds/netapi/svcdlls/upssvc/apcsmart/servapp.cxx

436 lines
14 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*
*
* REVISIONS:
*/
#include "cdefine.h"
extern "C" {
#include <stdlib.h>
}
#include "_defs.h"
#include "servapp.h"
#include "codes.h"
#include "cfgmgr.h"
#include "trans.h"
#include "timerman.h"
#include "sysstate.h"
#include "event.h"
#include "utils.h"
// Retry a failed construction every 3 seconds
//const INT RETRY_CONSTRUCT_DELAY = 3000;
const INT RETRY_CONSTRUCT_DELAY = 3;
// When setting the port name, it might fix comm on its own
// making this == 0 will force a rebuild immediately, on
// the same thread
//
// #define WAIT_FOR_SET_TO_WORK 250 // 1/4 seconds
#define WAIT_FOR_SET_TO_WORK 1 /* 1 second */
// theDeviceControllerInitialized values
#define NEVER_DONE 0
#define IN_PROGRESS 1
#define COMPLETED 2
// This should be initialized in the main module
PServerApplication _theApp = NULL;
//-------------------------------------------------------------------
ServerApplication::ServerApplication() :
theTimerID(0),
theDeviceControllerInitialized(NEVER_DONE),
theForceDeviceRebuildFlag(FALSE),
theDeviceController((PDeviceController)NULL)
{
_theApp = this;
}
//-------------------------------------------------------------------
ServerApplication::~ServerApplication()
{
if (theTimerID) {
if (_theTimerManager) {
_theTimerManager->CancelTimer(theTimerID);
}
theTimerID = 0;
}
}
//-------------------------------------------------------------------
INT ServerApplication::Start()
{
// set the timezone variables
SetTimeZone();
Event start_event(MONITORING_STATUS, MONITORING_STARTED);
Update(&start_event);
CreateDeviceController((PEvent)NULL);
InitializeDeviceController();
return ErrNO_ERROR;
}
//-------------------------------------------------------------------
VOID ServerApplication::Quit()
{
DisableEvents(); //srt28Mar97
// Tell everyone that the service is stopping
Event start_event(MONITORING_STATUS, MONITORING_STOPPED);
Update(&start_event);
// Stop all active threads ... NOTE that they are stopped
// in a specific order. theDataLog is independent and is stopped first,
// theDeviceController will stop the UPS polling. theServerController
// will stop all incoming client requests and current connections. Finally,
// theTimerManager will stop executing timed events.
if (theDeviceController) {
theDeviceController->Stop();
}
if (_theTimerManager) {
_theTimerManager->Stop();
}
// Return to simple signalling
theDeviceController->Set(TURN_OFF_SMART_MODE, NULL);
delete theDeviceController;
theDeviceController = NULL;
delete _theTimerManager;
_theTimerManager = theTimerManager = NULL;
}
//-------------------------------------------------------------------
INT ServerApplication::Set(INT code,const PCHAR value)
{
INT err = ErrNO_ERROR;
switch(code/1000) {
case 0: // Ups
case 1: // Measure ups
if (theDeviceController) {
err = theDeviceController->Set(code,value);
}
else {
err = ErrCOMMUNICATION_LOST;
}
break;
case 2: // Host
if (code == RESET_UPS_COMM_PORT) {
// Set this TRUE. If just setting the .ini file value
// causes the retry to succeed, then the flag will be
// reset and we won't bother forcing a rebuild
// Note that by sending the event on the timer thread,
// we serialize with the retries.
//
theForceDeviceRebuildFlag = TRUE;
Event ev(COMMUNICATION_STATE, UPS_COMM_PORT_CHANGED);
#if (WAIT_FOR_SET_TO_WORK > 0)
_theTimerManager->SetTheTimer(WAIT_FOR_SET_TO_WORK, &ev, this);
#else
Update(&ev);
#endif
}
break;
}
return err;
}
//-------------------------------------------------------------------
INT ServerApplication::Set(PTransactionItem trans)
{
INT err = ErrNO_ERROR;
return err;
}
//-------------------------------------------------------------------
INT ServerApplication::Get(INT code, PCHAR value)
{
INT err = ErrNO_ERROR;
switch(code/1000) {
case 0: // Ups
if (code == SYSTEM_STATE || code == UPS_STATE) {
//
// Really all we want is sytem state. Ups state hangs around
// to be compatible with old software (PowerNet)
//
ULONG system_state = 0;
if (theDeviceController) {
value[0] = 0;
err = theDeviceController->Get(COMMUNICATION_STATE, value);
ULONG comm_state = atol(value);
if (comm_state == COMMUNICATION_ESTABLISHED) {
//
// Only get UPS State if we have Comm
//
value[0] = 0;
err = theDeviceController->Get(UPS_STATE, value);
system_state = atol(value);
//
// Just to make sure
//
CLEAR_BIT(system_state, COMMUNICATIONS_BIT);
CLEAR_BIT(system_state, SHUTDOWN_IN_PROGRESS_BIT);
}
else {
//
// pcy - I don't know why we don't return communication
// lost as an error here, but we do below.
//
SET_BIT(system_state, COMMUNICATIONS_BIT);
}
_ltoa(system_state, value, 10);
}
else {
SET_BIT(system_state, COMMUNICATIONS_BIT);
_ltoa(system_state, value, 10);
err = ErrCOMMUNICATION_LOST;
}
break;
}
case 1: // Measure ups
value[0] = 0;
if (theDeviceController) {
err = theDeviceController->Get(code,value);
}
else {
err = ErrCOMMUNICATION_LOST;
}
break;
case 2: // Host
// printf("Getting from host\n");
value[0] = 0;
break;
}
return err;
}
//-------------------------------------------------------------------
INT ServerApplication::Get(PTransactionItem trans)
{
INT err = ErrNO_ERROR;
return err;
}
//-------------------------------------------------------------------
INT ServerApplication::Update(PEvent anEvent)
{
INT err = ErrNO_ERROR;
int sentEventOn = FALSE;
// If the communication is lost or we change ports, then
// schedule a rebuild of the device controller
if (anEvent->GetCode() == COMMUNICATION_STATE) {
switch(atoi(anEvent->GetValue())) {
case UPS_COMM_PORT_CHANGED:
if (theForceDeviceRebuildFlag) {
err = MainApplication::Update(anEvent);
sentEventOn = TRUE;
theDeviceController->Set(RETRY_CONSTRUCT, "Yes");
}
break;
case COMMUNICATION_ESTABLISHED:
if (theDeviceControllerInitialized == NEVER_DONE) {
err = InitializeDeviceController();
}
theForceDeviceRebuildFlag = FALSE;
// Fall through
}
}
if (!sentEventOn) {
err = MainApplication::Update(anEvent);
}
return err;
}
//-------------------------------------------------------------------
VOID ServerApplication::DisableEvents()
{
if (theDeviceController) {
theDeviceController->UnregisterEvent(UTILITY_LINE_CONDITION,this);
theDeviceController->UnregisterEvent(BATTERY_CONDITION,this);
theDeviceController->UnregisterEvent(RUN_TIME_EXPIRED,this);
theDeviceController->UnregisterEvent(RUN_TIME_REMAINING,this);
theDeviceController->UnregisterEvent(UPS_OFF_PENDING,this);
// Register with the device for Shutdown - this will happen when the
// server is a slave
theDeviceController->UnregisterEvent(SHUTDOWN,this);
theDeviceController->UnregisterEvent(SMART_BOOST_STATE,this);
theDeviceController->UnregisterEvent(SMART_TRIM_STATE,this);
theDeviceController->UnregisterEvent(UPS_LOAD,this);
theDeviceController->UnregisterEvent(COMMUNICATION_STATE,this);
theDeviceController->UnregisterEvent(SELF_TEST_RESULT,this);
theDeviceController->UnregisterEvent(BATTERY_CALIBRATION_CONDITION,this);
theDeviceController->UnregisterEvent(MIN_LINE_VOLTAGE,this);
theDeviceController->UnregisterEvent(MAX_LINE_VOLTAGE,this);
theDeviceController->UnregisterEvent(BYPASS_MODE, this);
theDeviceController->UnregisterEvent(MATRIX_FAN_STATE, this);
theDeviceController->UnregisterEvent(BYPASS_POWER_SUPPLY_CONDITION, this);
theDeviceController->UnregisterEvent(SMART_CELL_SIGNAL_CABLE_STATE, this);
theDeviceController->UnregisterEvent(REDUNDANCY_STATE, this);
theDeviceController->UnregisterEvent(UPS_MODULE_ADDED, this);
theDeviceController->UnregisterEvent(UPS_MODULE_REMOVED, this);
theDeviceController->UnregisterEvent(UPS_MODULE_FAILED, this);
theDeviceController->UnregisterEvent(BATTERY_ADDED, this);
theDeviceController->UnregisterEvent(BATTERY_REMOVED, this);
theDeviceController->UnregisterEvent(IM_OK, this);
theDeviceController->UnregisterEvent(IM_FAILED, this);
theDeviceController->UnregisterEvent(IM_INSTALLATION_STATE, this);
theDeviceController->UnregisterEvent(RIM_INSTALLATION_STATE, this);
theDeviceController->UnregisterEvent(RIM_OK, this);
theDeviceController->UnregisterEvent(RIM_FAILED, this);
theDeviceController->UnregisterEvent(SYSTEM_FAN_STATE, this);
theDeviceController->UnregisterEvent(BYPASS_CONTACTOR_STATE, this);
theDeviceController->UnregisterEvent(INPUT_BREAKER_STATE, this);
theDeviceController->UnregisterEvent(UPS_TEMPERATURE, this);
// MeasureUPS Events
theDeviceController->UnregisterEvent(AMBIENT_TEMPERATURE,this);
theDeviceController->UnregisterEvent(HUMIDITY,this);
theDeviceController->UnregisterEvent(CONTACT_STATE,this);
theDeviceController->UnregisterEvent(IM_STATUS,this);
theDeviceController->UnregisterEvent(RIM_STATUS,this);
theDeviceController->UnregisterEvent(BATTERY_REPLACEMENT_CONDITION,this);
}
}
//-------------------------------------------------------------------
INT ServerApplication::CreateDeviceController (PEvent anEvent)
{
INT err = ErrNO_ERROR;
// printf("Entering CreateDeviceController\n");
// Delete any existing device controller
if (theDeviceController) {
delete theDeviceController;
theDeviceController = (PDeviceController)NULL;
}
// Now create a new device controller
theDeviceController = new DeviceController(this);
theDeviceController->RegisterEvent(UTILITY_LINE_CONDITION,this);
theDeviceController->RegisterEvent(BATTERY_CONDITION,this);
theDeviceController->RegisterEvent(RUN_TIME_EXPIRED,this);
theDeviceController->RegisterEvent(RUN_TIME_REMAINING,this);
theDeviceController->RegisterEvent(UPS_OFF_PENDING,this);
// Register with the device for Shutdown - this will happen when the
// server is a slave
theDeviceController->RegisterEvent(SHUTDOWN,this);
theDeviceController->RegisterEvent(SMART_BOOST_STATE,this);
theDeviceController->RegisterEvent(SMART_TRIM_STATE,this);
theDeviceController->RegisterEvent(UPS_LOAD,this);
theDeviceController->RegisterEvent(COMMUNICATION_STATE,this);
theDeviceController->RegisterEvent(SELF_TEST_RESULT,this);
theDeviceController->RegisterEvent(BATTERY_CALIBRATION_CONDITION,this);
theDeviceController->RegisterEvent(MIN_LINE_VOLTAGE,this);
theDeviceController->RegisterEvent(MAX_LINE_VOLTAGE,this);
theDeviceController->RegisterEvent(BYPASS_MODE, this);
theDeviceController->RegisterEvent(MATRIX_FAN_STATE, this);
theDeviceController->RegisterEvent(BYPASS_POWER_SUPPLY_CONDITION, this);
theDeviceController->RegisterEvent(SMART_CELL_SIGNAL_CABLE_STATE, this);
theDeviceController->RegisterEvent(REDUNDANCY_STATE, this);
theDeviceController->RegisterEvent(UPS_MODULE_ADDED, this);
theDeviceController->RegisterEvent(UPS_MODULE_REMOVED, this);
theDeviceController->RegisterEvent(UPS_MODULE_FAILED, this);
theDeviceController->RegisterEvent(BATTERY_ADDED, this);
theDeviceController->RegisterEvent(BATTERY_REMOVED, this);
theDeviceController->RegisterEvent(IM_STATUS, this);
theDeviceController->RegisterEvent(IM_OK, this);
theDeviceController->RegisterEvent(IM_FAILED, this);
theDeviceController->RegisterEvent(IM_INSTALLATION_STATE, this);
theDeviceController->RegisterEvent(RIM_INSTALLATION_STATE, this);
theDeviceController->RegisterEvent(RIM_STATUS, this);
theDeviceController->RegisterEvent(RIM_OK, this);
theDeviceController->RegisterEvent(RIM_FAILED, this);
theDeviceController->RegisterEvent(SYSTEM_FAN_STATE, this);
theDeviceController->RegisterEvent(BYPASS_CONTACTOR_STATE, this);
theDeviceController->RegisterEvent(INPUT_BREAKER_STATE, this);
theDeviceController->RegisterEvent(UPS_TEMPERATURE, this);
theDeviceController->RegisterEvent(TOTAL_INVERTERS, this);
theDeviceController->RegisterEvent(NUMBER_BAD_INVERTERS, this);
theDeviceController->RegisterEvent(BAD_BATTERY_PACKS, this);
theDeviceController->RegisterEvent(EXTERNAL_BATTERY_PACKS, this);
theDeviceController->RegisterEvent(BATTERY_REPLACEMENT_CONDITION, this);
// MeasureUPS Events
theDeviceController->RegisterEvent(AMBIENT_TEMPERATURE,this);
theDeviceController->RegisterEvent(HUMIDITY,this);
theDeviceController->RegisterEvent(CONTACT_STATE,this);
return err;
}
//-------------------------------------------------------------------
INT ServerApplication::InitializeDeviceController()
{
INT err = theDeviceController->GetObjectStatus();
// Make sure that the object constructed ok
if (err == ErrNO_ERROR) {
theDeviceControllerInitialized = IN_PROGRESS;
err = theDeviceController->Initialize();
if (err == ErrNO_ERROR) {
theDeviceControllerInitialized = COMPLETED;
}
}
return err;
}
//-------------------------------------------------------------------