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

337 lines
8.4 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*
*
* NOTES:
*
* REVISIONS:
* pcy24Nov92: Use apc.h. Remove Popups and event log (now in App).
* SjA11Dec92: Registers events with the theUps now. Doesn't update twice now.
* pcy11Dec92: include smartups.h instead of backups.h
* pcy11Dec92: Initialize theCommController in the constructor
* ane16Dec92: Comment out passing of gets/sets to host object, handled in app now
* ane05Jan93: Added code to support slaves
* ane11Jan93: Register for additional events when a slave
* pcy26Jan93: Construct SmartUps/BackUps based on ini file
* pcy26Jan93: Return construction errors in theObjectStatus
* ane03Feb93: Added state and SetInvalid and state checking
* pcy16Feb93: Get rid of SORRY CHARLIE debug msg
* tje24Feb93: Added Windows support
* jod14May93: Added Matrix changes.
* cad10Jun93: Added MeasureUPS support
* cad15Jul93: Moved add-ons to under smart comm
* cad04Aug93: Fixed up admin shutdown handling
* cad27Aug93: Added handler for is measureups attached get
* cad14Sep93: Handling measureups non-null, but not really there
* cad20Oct93: Better MUPS checking
* cad27Oct93: even better than that
* jod02Nov93: Added CIBC conditional statements
* cad11Nov93: Changed handling of Comm Lost
* cad17Nov93: .. more little fixups
* rct21Dec93: fixed bug in Get()
* pcy08Apr94: Trim size, use static iterators, dead code removal
* ajr22Aug94: Lets not auto-detect mups because of ShareUps problems.
* ajr14Feb96: Sinix merge
* cgm29Feb96: Delete the created UPS if lost comm in first 3-10 sec
* djs22Feb96: Changed to new firmware rev interface
* cgm29Feb96: (NetWare) Override switch
* cgm17Apr96: Delete the ups before commcontroller
* cgm17Apr96: Don't create measureups without valid ups object
* djs17May96: Added DarkStar device
* srt02Apr97: Added fix for potential bug
* tjg02Dec97: Changed darkstar to symmetra
* tjg26Jan98: Added Stop method
* clk13May98: When getting value for IS_SYMMETRA, always get value from UPS
* mholly12May1999: special handling of TURN_OFF_SMART_MODE code
*
* v-stebe 29Jul2000 Fixed PREfix error (bug #112614)
*/
#include "cdefine.h"
extern "C" {
#include <stdio.h>
#include <stdlib.h>
}
#include "_defs.h"
#include "apc.h"
#include "cdevice.h"
#include "devctrl.h"
#include "ups.h"
#include "err.h"
#include "dispatch.h"
#include "smartups.h"
#include "matrix.h"
#include "codes.h"
#include "cfgmgr.h"
#include "dcomctrl.h"
DeviceController::DeviceController(PMainApplication anApp)
: Controller(),
theApplication(anApp),
slaveEnabled(FALSE),
theUps((PUps)NULL)
{
INT err = ErrNO_ERROR;
theCommController = new DevComContrl(this);
theCommController->RegisterEvent(COMMUNICATION_STATE, this);
theCommController->RegisterEvent(SHUTDOWN,this);
theCommController->RegisterEvent(UPS_OFF_PENDING,this);
theObjectStatus = theCommController->GetObjectStatus();
if(theObjectStatus == ErrNO_ERROR) {
if (theUps) {
theObjectStatus = theUps->GetObjectStatus();
}
}
else {
theUps = (PUps)NULL;
}
theApplication->RegisterEvent(EXIT_THREAD_NOW, this);
}
DeviceController::~DeviceController()
{
theApplication->UnregisterEvent(EXIT_THREAD_NOW, this);
// Must delete theUps object before theCommController
delete theUps;
theUps = (PUps)NULL;
delete theCommController;
theCommController = (PCommController)NULL;
}
INT DeviceController::Initialize()
{
INT err = ErrNO_ERROR;
theCommController->Initialize();
return err;
}
INT DeviceController::CreateUps()
{
INT err = ErrNO_ERROR;
CHAR value[32];
if (!theUps) {
_theConfigManager->Get(CFG_UPS_SIGNALLING_TYPE, value);
if( (_strcmpi(value, "SIMPLE") == 0) || (slaveEnabled == TRUE)) {
theUps = new BackUps(this, theCommController);
}
else {
FirmwareRevSensor theFirmwareRevSensor(((PDevice)NULL), theCommController);
CHAR Is_Ups_A_Symmetra[32];
theFirmwareRevSensor.Get(IS_SYMMETRA,Is_Ups_A_Symmetra);
if (_strcmpi(Is_Ups_A_Symmetra,"Yes") == 0) {
theUps = new Matrix(this, theCommController);
}
else {
CHAR Is_Ups_A_Matrix[32];
theFirmwareRevSensor.Get(IS_MATRIX,Is_Ups_A_Matrix);
if (_strcmpi(Is_Ups_A_Matrix,"Yes") == 0) {
theUps = new Matrix(this, theCommController);
}
else {
theUps = new SmartUps(this, theCommController);
if ((theUps->GetObjectStatus()) == ErrSMART_MODE_FAILED) {
delete theUps;
theUps = (PUps) NULL;
}
}
}
}
if (theUps) {
theUps->Initialize();
theDispatcher->RefreshEventRegistration(theUps, this);
theCommController->GetDevice()->OkToPoll();
}
}
return err;
}
INT DeviceController::Get(INT code, PCHAR aValue)
{
INT err = ErrNO_ERROR;
INT comm = FALSE;
switch(code/1000)
{
case UPS/1000:
if (code == COMMUNICATION_STATE) {
if (theCommController) {
err = theCommController->Get(COMMUNICATION_STATE, aValue);
}
else {
sprintf(aValue, "%d", COMMUNICATION_LOST);
}
}
else if (theUps && theCommController &&
!(theCommController->GetDevice()->HasLostComm())) {
err = theUps->Get(code, aValue);
}
else if (theUps && (code == IS_SYMMETRA)) {
err = theUps->Get(code, aValue);
}
else {
err = ErrINVALID_VALUE;
}
break;
case MEASURE_UPS/1000:
if (code == IS_MEASURE_UPS_ATTACHED) {
strcpy(aValue, "No");
}
else {
err = ErrNO_MEASURE_UPS;
}
break;
case INTERNAL/1000:
if ((code == RETRY_CONSTRUCT) && theCommController) {
err = theCommController->Get(code, aValue);
}
break;
case IS_LINE_FAIL_RUN_TIME_ENABLED/1000:
theApplication->Get(code, aValue);
break;
}
return err;
}
INT DeviceController::Set(INT code, const PCHAR aValue)
{
INT err = ErrNO_ERROR;
switch(code/1000) {
case UPS/1000:
if (theUps && theCommController &&
!(theCommController->GetDevice()->HasLostComm())) {
if (TURN_OFF_SMART_MODE == code) {
err = theCommController->Set(code, aValue);
}
else {
err = theUps->Set(code, aValue);
}
}
break;
case MEASURE_UPS/1000:
err = ErrNO_MEASURE_UPS;
break;
case INTERNAL/1000:
if ((code == RETRY_CONSTRUCT) && theCommController) {
err = theCommController->Set(code, aValue);
}
break;
}
return err;
}
INT DeviceController::Update(PEvent anEvent)
{
switch (anEvent->GetCode()) {
case COMMUNICATION_STATE:
if (atoi(anEvent->GetValue()) == COMMUNICATION_ESTABLISHED) {
CreateUps();
}
else {
if(theUps) {
CHAR val[32];
theUps->Get(UPS_STATE, val);
if(atoi(val) & UPS_STATE_ON_BATTERY) {
anEvent->SetValue(COMMUNICATION_LOST_ON_BATTERY);
}
}
}
break;
}
INT err;
if ( (theCommController->GetDevice()->HasLostComm() == FALSE) ||
(anEvent!=NULL && anEvent->GetCode()==COMMUNICATION_STATE &&
atoi(anEvent->GetValue()) != COMMUNICATION_ESTABLISHED))
{
err = UpdateObj::Update(anEvent);
}
return err;
}
INT DeviceController::RegisterEvent(INT id, UpdateObj* object)
{
INT err = UpdateObj::RegisterEvent(id,object);
if (err == ErrNO_ERROR) {
if (id == SHUTDOWN_STATUS ||
id == ADMIN_SHUTDOWN ||
id == CANCEL_SHUTDOWN) {
theApplication->RegisterEvent(id, this);
}
else {
switch(id/1000) {
case UPS/1000:
if (theUps) {
err = theUps->RegisterEvent(id, object);
}
break;
case MEASURE_UPS/1000:
break;
}
}
}
return err;
}
VOID DeviceController::SetInvalid()
{
}
VOID DeviceController::Stop()
{
if (theCommController) {
theCommController->Stop();
}
}