|
|
/*
* * 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(); } }
|