//OpenSCADA file: tsubsys.cpp /*************************************************************************** * Copyright (C) 2003-2022 by Roman Savochenko, * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; version 2 of the License. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "tsys.h" #include "tmess.h" #include "tsubsys.h" using namespace OSCADA; //************************************************* //* TSubSYS * //************************************************* TSubSYS::TSubSYS( const string &id, bool modi ) : mStart(false), mModSys(modi), mMod(-1), mId(id) { if(subModule()) mMod = grpAdd("mod_", true); if(mess_lev() == TMess::Debug) SYS->cntrIter(objName(), 1); } TSubSYS::~TSubSYS( ) { nodeDelAll(); if(mess_lev() == TMess::Debug) SYS->cntrIter(objName(), -1); } string TSubSYS::objName( ) { return TCntrNode::objName()+":TSubSYS"; } TSYS &TSubSYS::owner( ) const { return *(TSYS*)nodePrev(); } void TSubSYS::modList( vector &list ) { if(!subModule()) throw err_sys(_("Subsystem is not modular!")); chldList(mMod,list); } bool TSubSYS::modPresent( const string &name ) { if(!subModule()) throw err_sys(_("Subsystem is not modular!")); return chldPresent(mMod,name); } void TSubSYS::modAdd( TModule *modul ) { if(!subModule()) throw err_sys(_("Subsystem is not modular!")); if(chldPresent(mMod,modul->modId())) return; mess_sys(TMess::Info, _("Module '%s' connecting."), modul->modId().c_str()); chldAdd(mMod, modul, s2i(modul->modInfo("HighPriority"))?0:-1); if(mess_lev() == TMess::Debug) { vector list; modul->modInfo(list); for(unsigned iOpt = 0; iOpt < list.size(); iOpt++) mess_sys(TMess::Debug, "-> %s: %s", _(list[iOpt].c_str()), modul->modInfo(list[iOpt]).c_str()); } } void TSubSYS::modDel( const string &name ) { if(!subModule()) throw err_sys(_("Subsystem is not modular!")); chldDel(mMod, name); mess_sys(TMess::Info, _("Module '%s' disconnecting."), name.c_str()); } AutoHD TSubSYS::modAt( const string &name ) const { if(!subModule()) throw err_sys(_("Subsystem is not modular!")); return chldAt(mMod,name); } void TSubSYS::unload( ) { //Delete all child nodes passes holded vector nLs; for(int iCh = 0; iCh < grpSize(); iCh++) { chldList(iCh, nLs); for(unsigned iN = 0; iN < nLs.size(); iN++) try { chldDel(iCh, nLs[iN]); } catch(...) { } } } void TSubSYS::subStart( ) { mess_sys(TMess::Debug, _("Subsystem starting.")); if(!SYS->security().at().grpPresent(subId())) { SYS->security().at().grpAdd(subId(), ""); SYS->security().at().grpAt(subId()).at().setDescr(subName()); SYS->security().at().grpAt(subId()).at().setSysItem(true); SYS->security().at().grpAt(subId()).at().userAdd("root"); SYS->security().at().grpAt(subId()).at().modifClr(); } if(!subModule()) return; vector list; modList(list); AutoHD mO; for(unsigned iM = 0; iM < list.size(); iM++) try { modAt(list[iM]).at().modStart(); } catch(TError &err) { mess_err(err.cat.c_str(), "%s", err.mess.c_str()); mess_sys(TMess::Error, _("Error starting the module '%s'."), list[iM].c_str()); } mStart = true; } void TSubSYS::subStop( ) { mess_sys(TMess::Debug, _("Subsystem stopping.")); if(!subModule()) return; vector list; modList(list); AutoHD mO; for(unsigned iM = 0; iM < list.size(); iM++) try { modAt(list[iM]).at().modStop(); } catch(TError &err) { mess_err(err.cat.c_str(), "%s", err.mess.c_str()); mess_sys(TMess::Error, _("Error stopping the module '%s'."), list[iM].c_str()); } mStart = false; } void TSubSYS::perSYSCall( unsigned int cnt ) { if(!subModule()) return; vector list; modList(list); for(unsigned iM = 0; iM < list.size(); iM++) try{ modAt(list[iM]).at().perSYSCall(cnt); } catch(TError &err) { mess_err(err.cat.c_str(), "%s", err.mess.c_str()); } } string TSubSYS::optDescr( ) { if(!subModule()) return ""; string rez; vector list; modList(list); for(unsigned iM = 0; iM < list.size(); iM++) rez += modAt(list[iM]).at().optDescr(); return rez; } void TSubSYS::cntrCmdProc( XMLNode *opt ) { //Service commands process string a_path = opt->attr("path"); if(a_path == "/serv/redundant") { //Redundant service requests if(ctrChkNode(opt,"st",RWRWR_,"root",SDAQ_ID,SEC_RD)) { //State opt->setAttr("inProc", "0"); return; } } //Get page info if(opt->name() == "info") { TCntrNode::cntrCmdProc(opt); ctrMkNode("oscada_cntr",opt,-1,"/",_("Subsystem: ")+subName(),R_R_R_); ctrMkNode("branches",opt,-1,"/br","",R_R_R_); if(TUIS::icoGet(subId(),NULL,true).size()) ctrMkNode("img",opt,-1,"/ico","",R_R_R_); if(subModule()) { ctrMkNode("grp",opt,-1,"/br/mod_",_("Module"),R_R_R_,"root","root",1,"idm","1"); if(ctrMkNode("area",opt,-1,"/mod",_("Modules"),R_R_R_,"root","root")) ctrMkNode("list",opt,-1,"/mod/br",_("Modules"),R_R_R_,"root","root",3,"tp","br","idm","1","br_pref","mod_"); } return; } //Process command to page if(a_path == "/ico" && ctrChkNode(opt)) { string itp; opt->setText(TSYS::strEncode(TUIS::icoGet(subId(),&itp),TSYS::base64)); opt->setAttr("tp",itp); } else if(subModule() && (a_path == "/br/mod_" || a_path == "/mod/br") && ctrChkNode(opt,"get",R_R_R_,"root","root",SEC_RD)) { vector list; modList(list); for(unsigned iA = 0; iA < list.size(); iA++) opt->childAdd("el")->setAttr("id",list[iA])->setText(modAt(list[iA]).at().modName()); } else TCntrNode::cntrCmdProc(opt); }