00001
00002
00003 #include <fesa-core/Server/AbstractServerEquipment.h>
00004
00005 #include <fesa-core/Server/AbstractServerController.h>
00006 #include <fesa-core/Server/AbstractServerAction.h>
00007 #include <fesa-core/Server/AbstractServerDeviceClass.h>
00008 #include <fesa-core/RDADeviceServer/SubscriptionTreeManager.h>
00009 #include <fesa-core/RDADeviceServer/FesaDeviceServer.h>
00010 #include <fesa-core/DataStore/EquipmentData.h>
00011 #include <fesa-core/DataStore/AbstractDeviceFactory.h>
00012 #include <fesa-core/DataStore/GlobalDevice.h>
00013 #include <fesa-core/Core/AbstractEquipment.h>
00014 #include <fesa-core/Utilities/ProcessConfiguration.h>
00015 #include <fesa-core/Diagnostic/Diagnostics.h>
00016
00017 #include <cmw-log/Logger.h>
00018
00019
00020 namespace
00021 {
00022
00023 CMW::Log::Logger& logger = CMW::Log::LoggerFactory::getLogger("FESA.FWK.fesa-core.Server.AbstractServerEquipment");
00024 const std::string diagTopic = fesa::DiagnosticUtils::rdaTrackingStr;
00025
00026 }
00027
00028
00029 namespace fesa
00030 {
00031
00032 AbstractServerEquipment* AbstractServerEquipment::theInstance_ = NULL;
00033
00034
00035 AbstractServerEquipment::AbstractServerEquipment()
00036 {
00037 const ProcessConfiguration* configuration = AbstractEquipment::getInstance()->getProcessConfiguration();
00038 bool useFastUpdate = (configuration->getStringValue(PropertyTag::CLIENT_UPDATE_POLICY) == "fast") ? true : false;
00039 pSubscriptionTreeManager_ = new SubscriptionTreeManager(useFastUpdate);
00040 theInstance_ = this;
00041
00042
00043
00044
00045 const std::string rdaServerName = getServerNameFromConfigurationFile();
00046 FesaDeviceServer::initCMW();
00047 pFesaDeviceServer_ = new FesaDeviceServer(rdaServerName, configuration, pSubscriptionTreeManager_);
00048 pServerController_ = new AbstractServerController(*pSubscriptionTreeManager_);
00049 }
00050
00051
00052 void AbstractServerEquipment::initialize()
00053 {
00054 EquipmentData* eqData = EquipmentData::getInstance();
00055 *(eqData->serverUp_) = false;
00056
00057
00058 if (*(eqData->serverProcessID_ )!= 0)
00059 {
00060
00061 if(kill(*(eqData->serverProcessID_), SIGFESA_CHECK_PROCESS_ALIVE) == 0)
00062 {
00063
00064 throw FesaException(__FILE__, __LINE__, FesaErrorServerProcessAlreadyExists.c_str());
00065 }
00066 else
00067 {
00068 if (errno != ESRCH)
00069 {
00070
00071 throw FesaException(__FILE__, __LINE__, FesaErrorNoPermissionToSendSignals.c_str());
00072 }
00073 }
00074 }
00075 *(eqData->serverProcessID_) = getpid();
00076
00077 AbstractComponentEquipment::initialize();
00078 pServerController_->initialize();
00079
00080
00081 }
00082
00083
00084 void AbstractServerEquipment::start(RunMode runMode)
00085 {
00086 pServerController_->start();
00087
00088
00089 pFesaDeviceServer_->start();
00090
00091
00092 *(EquipmentData::getInstance()->serverUp_) = true;
00093
00094 if ( runMode == blocking )
00095 {
00096 waitSignal();
00097 }
00098 }
00099
00100
00101 AbstractServerEquipment::~AbstractServerEquipment()
00102 {
00103 LOG_DEBUG_IF(logger, "Shutting down RDA interface ");
00104
00105 FesaDeviceServer::shutDown();
00106 if (pFesaDeviceServer_ !=NULL)
00107 {
00108 delete(pFesaDeviceServer_);
00109 }
00110
00111
00112 AbstractServerAction::releaseStaticObjects();
00113 if (pServerController_ != NULL)
00114 {
00115 delete pServerController_;
00116 pServerController_ = NULL;
00117 }
00118
00119 LOG_DEBUG_IF(logger, "Server equipment removed ");
00120
00121 }
00122
00123
00124 AbstractServerDeviceClass* AbstractServerEquipment::getDeviceClassFromDeviceName(const std::string& devicename)
00125 {
00126 std::vector<AbstractDeviceClass*>::iterator iter = abstractDeviceClassCol_.begin();
00127 std::vector<AbstractDeviceClass*>::iterator end = abstractDeviceClassCol_.end();
00128
00129 for (; iter != end; ++iter)
00130 {
00131 try
00132 {
00133 AbstractDeviceFactory* factory = (*iter)->getDeviceFactory();
00134
00135 if (factory->getDevice(devicename) != NULL)
00136 {
00137 return static_cast<AbstractServerDeviceClass*> (*iter);
00138 }
00139 else if((factory->getGlobalDevice() != 0 ) && (factory->getGlobalDevice()->getName() == devicename))
00140 {
00141 return static_cast<AbstractServerDeviceClass*> (*iter);
00142 }
00143 }
00144 catch (FesaException& ex)
00145 {
00146 if (ex.getErrorCode() != FesaErrorUnknownDevice)
00147 throw ex;
00148
00149 }
00150 }
00151
00152 throw FesaException(__FILE__, __LINE__, FesaErrorUnknownDevice.c_str(), devicename.c_str());
00153 }
00154
00155
00156 void AbstractServerEquipment::reportErrorToAllSubscribers(std::string Message)
00157 {
00158 AbstractEquipment* eqp = AbstractEquipment::getInstance();
00159 const std::vector<AbstractDeviceClass*>& classCol = eqp->getServerComponent()->getDeviceClassCol();
00160
00161 std::vector<AbstractDeviceClass*>::const_iterator iter;
00162 for (iter = classCol.begin(); iter != classCol.end(); iter++)
00163 {
00164 (static_cast<AbstractServerDeviceClass*> (*iter))->reportErrorToSubscribers(Message);
00165 }
00166 }
00167
00168
00169 AbstractServerController* AbstractServerEquipment::getServerController()
00170 {
00171 return pServerController_;
00172 }
00173
00174
00175 void AbstractServerEquipment::waitSignal()
00176 {
00177 sigset_t sigset;
00178 sigemptyset(&sigset);
00179 sigaddset(&sigset, SIGTSTP);
00180 pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
00181
00182 sigemptyset(&sigset);
00183 sigaddset(&sigset, SIGHUP);
00184 sigaddset(&sigset, SIGINT);
00185 sigaddset(&sigset, SIGQUIT);
00186 sigaddset(&sigset, SIGILL);
00187 sigaddset(&sigset, SIGTRAP);
00188 sigaddset(&sigset, SIGABRT);
00189 sigaddset(&sigset, SIGBUS);
00190 sigaddset(&sigset, SIGFPE);
00191 sigaddset(&sigset, SIGSEGV);
00192 sigaddset(&sigset, SIGTERM);
00193 sigaddset(&sigset, SIGSTKFLT);
00194 sigaddset(&sigset, SIGSTOP);
00195 sigaddset(&sigset, SIGTTIN);
00196 sigaddset(&sigset, SIGTTOU);
00197 sigaddset(&sigset, SIGFESA_RT_DOWN);
00198 sigaddset(&sigset, SIGFESA_NOTIFICATION_FAILURE);
00199 sigaddset(&sigset, SIGFESA_CHECK_PROCESS_ALIVE);
00200
00201 int32_t signalID;
00202 for (;;)
00203 {
00204 sigwait(&sigset, &signalID);
00205
00206 if(signalID == SIGFESA_CHECK_PROCESS_ALIVE)
00207 {
00208 continue;
00209 }
00210
00211
00212
00213 if(signalID == SIGFESA_RT_DOWN)
00214 {
00215 std::string errorStr("Server process received signal from RT: RT is going down.");
00216 LOG_WARNING_IF(logger, errorStr);
00217 pSubscriptionTreeManager_->reportInternalError(std::string("FesaInternalError"), -signalID, std::string("RealTime process is missing."));
00218
00219 continue;
00220 }
00221
00222 if(signalID == SIGFESA_NOTIFICATION_FAILURE)
00223 {
00224 std::string errorStr("Server process received signal from RT: Notification queue is full.");
00225 LOG_WARNING_IF(logger, errorStr);
00226 pSubscriptionTreeManager_->reportInternalError(std::string("FesaInternalError"), -signalID, std::string("Notification failure (queue is full)."));
00227
00228 continue;
00229 }
00230
00231 EquipmentData* eqData = EquipmentData::getInstance();
00232 *(eqData->serverUp_) = false;
00233 std::string errorStr("Fatal signal received, shutting down Server process.");
00234 LOG_WARNING_IF(logger, errorStr);
00235
00236
00237
00238
00239 pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
00240 signal(signalID, SIG_DFL);
00241 raise(signalID);
00242 }
00243 return;
00244 }
00245
00246
00247 const std::string AbstractServerEquipment::getServerNameFromConfigurationFile()
00248 {
00249 const ProcessConfiguration* configuration = AbstractEquipment::getInstance()->getProcessConfiguration();
00250 std::string rdaServerName(configuration->getCMWServerName());
00251 if (rdaServerName.empty() == false)
00252 {
00253 const boost::shared_ptr<Diagnostics>& diagnostics = AbstractEquipment::getInstance()->getDiagnostics();
00254 DiagnosticUtils::DiagnosticMessage diagMsg;
00255 diagMsg.side = DiagnosticUtils::framework;
00256 diagMsg.source = DiagnosticUtils::server;
00257 std::ostringstream traceStrStream;
00258 traceStrStream << "Forcing RDADeviceServer name to '" << rdaServerName << "'";
00259 diagMsg.msg = traceStrStream.str();
00260 diagnostics->log(diagTopic, diagMsg);
00261 }
00262 else
00263 {
00264 rdaServerName += AbstractEquipment::getInstance()->getEquipmentName();
00265 rdaServerName += ".";
00266 rdaServerName += AbstractEquipment::getInstance()->getHostName();
00267 }
00268 return rdaServerName;
00269 }
00270
00271 }