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