00001
00002
00003
00004
00005
00006
00008
00009 #include <string>
00010
00011
00012 #include <is/info.h>
00013 #include <is/infodictionary.h>
00014 #include <is/infoiterator.h>
00015 #include <is/inforeceiver.h>
00016 #include <is/infoT.h>
00017 #include "sctddc/SCTDdcCommandSender.hxx"
00018 #include <unistd.h>
00019
00020 using namespace std;
00021
00022
00023
00024 SCTDdcCommandSender::SCTDdcCommandSender(IPCPartition& partition, string** ctrlList)
00025 : m_partition(partition), m_commandAllowed(true), m_commandResponse(-99999), m_ctrlNum(0),
00026 m_controllers(ctrlList)
00027 {
00028 m_receiver = new ISInfoReceiver(partition);
00029 }
00030
00031
00032 SCTDdcCommandSender::~SCTDdcCommandSender()
00033 {
00034 delete m_receiver;
00035 }
00036
00037 void callback(ISCallbackInfo* cbInfo)
00038 {
00039 SCTDdcCommandSender* sctDdcCommandSender = (SCTDdcCommandSender*)(cbInfo->parameter());
00040
00041 DdcNtCommandResponse result(sctDdcCommandSender->getPartition(),
00042 (char*)cbInfo->name(), 0);
00043 string infoName(cbInfo->name());
00044
00045 string ctrlName;
00046
00047
00048 ctrlName = infoName.substr(infoName.find('.')+1);
00049 ctrlName = ctrlName.substr(ctrlName.find('.')+1);
00050 ctrlName = ctrlName.substr(0, ctrlName.find("response")-1);
00051
00052 if(cbInfo->reason() != is::Deleted)
00053 {
00054 if(cbInfo->type() == result.type())
00055 {
00056 cbInfo->value(result);
00057 sctDdcCommandSender->setCommandResponse(result.getValue());
00058 if(result.getValue() <0)
00059 {
00060 cerr << "SCTDdcCommandSender: Result of the "
00061 << sctDdcCommandSender->getCommand() << " command on " << ctrlName << " is ";
00062
00063
00064 switch(result.getValue())
00065 {
00066 case COMM_ERR_OK:
00067 cerr << "OK" << endl;
00068 break;
00069 case COMM_ERR_NAME:
00070 cerr << "INVALIDE COMMAND NAME" << endl;
00071 break;
00072 case COMM_ERR_DCSDP:
00073 cerr << "COMMAND NOT DEFINED PROPERLY IN DCS" << endl;
00074 break;
00075 case COMM_ERR_TIMEOUT:
00076 cerr << "TIMEOUT" << endl;
00077 break;
00078 case COMM_ERR_CONNECT:
00079 cerr << "PVSS IS UNAVAILABLE" << endl;
00080 break;
00081 case COMM_ERR_CONNBROKEN:
00082 cerr << "CONNECTION TO DCS LOST" << endl;
00083 break;
00084 case COMM_ERR_NTDESC:
00085 cerr << "INVALID COMMAND DEFINITION IN IS" << endl;
00086 break;
00087
00088 default:
00089 cerr << "USER'S ERROR STATUS = " << result.getValue()
00090 <<". THIS IS NOT DEFINED "<< endl;
00091 }
00092 }
00093 sctDdcCommandSender->getReceiver()->unsubscribe(infoName.c_str());
00094 result.remove();
00095 if(sctDdcCommandSender->decreaseCtrlNum() == 0)
00096 {
00097 sctDdcCommandSender->ddcRemoveCommand(ctrlName);
00098 sctDdcCommandSender->ddcRemoveCommand();
00099
00100 sctDdcCommandSender->setCommandAllowedTrue();
00101 }
00102 }
00103 else
00104 cerr << "SCTDdcCommandSender: Incorrect response. Assume "
00105 << "an internal error" << endl;
00106 }
00107 }
00108
00109
00110
00111 int SCTDdcCommandSender::ddcSendCommand(string& commandName,
00112 string& commParameters, unsigned int timeout)
00113 {
00114 string ctrlName = *m_controllers[0];
00115 return ddcSendCommand(ctrlName, commandName, commParameters, timeout);
00116 }
00117
00118 int SCTDdcCommandSender::ddcSendCommand(string ctrlName, string& commandName,
00119 string& commParameters, unsigned int timeout)
00120 {
00121 ISInfo::Status rc;
00122 string respName;
00123 if(isValidCtrl(ctrlName))
00124 {
00125 m_ctrlNum = 0;
00126 if(ctrlName == "*")
00127 {
00128
00129 for(unsigned int i=0; m_controllers[i] != 0; i++)
00130 {
00131 respName = makeResponseName(*m_controllers[i], commandName);
00132 rc = m_receiver->subscribe(respName.c_str(), callback, (void*)this);
00133 if(rc == ISInfo::Success)
00134 {
00135 m_ctrlNum += 1;
00136 cerr << "SCTDdcCommandSender_INFO: Subscribed for " << respName << endl;
00137 }
00138 else
00139 {
00140 cerr << "DdcComander_WARNING: response of " << *m_controllers[i]
00141 << " is not subscribed for: ERROR code = " << rc << endl;
00142 }
00143 }
00144
00145 if(m_ctrlNum == 0)
00146 {
00147 cerr << "SCTDdcCommandSender_ERROR: No response is subscribed" << endl;
00148 cerr << " ======> No IS server to send command" << endl;
00149 }
00150 else
00151 {
00152
00153
00154
00155 string commEntryName(COMMAND_SERVER);
00156
00157 commEntryName = commEntryName + ".DdcNtCommand";
00158
00159 m_timeout = (timeout == 0) ? DEFAULT_TIMEOUT : timeout;
00160 m_startTime = time(&m_startTime);
00161
00162 __ddcSendCommand(commEntryName, commandName,
00163 commParameters, m_timeout);
00164 m_commandName = commandName;
00165 m_commandAllowed = false;
00166 }
00167 }
00168 else
00169 {
00170
00171 respName = makeResponseName(ctrlName, commandName);
00172 rc = m_receiver->subscribe(respName.c_str(), callback, (void*)this);
00173 if(rc != ISInfo::Success)
00174 {
00175 cerr << "SCTDdcCommandSender_ERROR: " << respName
00176 << " DdcNtCommandResponse subscription fault " << rc << endl;
00177 cerr << " ======> No IS server to send command" << endl;;
00178 }
00179 else
00180 {
00181
00182 m_startTime = time(&m_startTime);
00183 m_ctrlNum = 1;
00184
00185
00186 string commEntryName(COMMAND_SERVER);
00187 commEntryName = commEntryName + ".DdcNtCommand" + '.' + ctrlName;
00188 m_timeout = (timeout == 0) ? DEFAULT_TIMEOUT : timeout;
00189
00190 __ddcSendCommand(commEntryName, commandName,
00191 commParameters, m_timeout);
00192
00193 m_commandName = commandName;
00194 m_commandAllowed = false;
00195 }
00196 }
00197 }
00198 else
00199 {
00200 cerr << "SCTDdcCommandSender_ERROR: Invalid controller name " << ctrlName << endl;
00201 }
00202
00203
00204 time_t now;
00205 while(!m_commandAllowed)
00206 {
00207 usleep(10);
00208 now = time(&now);
00209
00210 if(now - m_startTime > m_timeout)
00211 {
00212 for(unsigned int i=0; m_controllers[i] != 0; i++)
00213 {
00214 string respEntryName = COMMAND_SERVER;
00215 respEntryName = respEntryName + '.' + commandName + '.'
00216 + *m_controllers[i] + ".response";
00217 m_receiver->unsubscribe(respEntryName.c_str());
00218
00219 ddcRemoveCommand(*m_controllers[i]);
00220 ddcRemoveCommand();
00221
00222 m_commandAllowed = true;
00223 }
00224 cerr << "SCTDdcCommandSender: Result of the "
00225 << getCommand() << " command is TIMEOUT" << endl;
00226 break;
00227 }
00228 }
00229 return m_commandResponse;
00230 }
00231
00232
00233 bool SCTDdcCommandSender::__ddcSendCommand(string& isEntryName, string& commandName,
00234 string& commParameters, unsigned int timeout)
00235 {
00236 ISInfo::Status rs;
00237 bool ok = true;
00238
00239 DdcNtCommand* command = new DdcNtCommand(m_partition, (char*)isEntryName.c_str());
00240
00241 if(command->isExist())
00242 {
00243 cerr << "SCTDdcCommandSender_ERROR: Previous command for the same controller(s)"
00244 << " seems to be still running" << endl;
00245 ok = false;
00246 }
00247 else
00248 {
00249 command->setCommName(commandName);
00250 command->setParValue(commParameters);
00251 command->setTimeout(timeout);
00252
00253 rs = command->checkin();
00254
00255 if(rs != ISInfo::Success) {
00256 cerr << "SCTDdcCommandSender_ERROR: " << isEntryName
00257 << " command sending fault " << rs << endl;
00258 ok = false;
00259 }
00260 }
00261 delete command;
00262 return(ok);
00263 }
00264
00265
00266 bool SCTDdcCommandSender::ddcRemoveCommand(string& ctrlName)
00267 {
00268 ISInfo::Status rs;
00269 bool ok = true;
00270 string commEntryName(COMMAND_SERVER);
00271
00272 commEntryName = commEntryName + ".DdcNtCommand" + '.' + ctrlName;
00273 DdcNtCommand* command = new DdcNtCommand(m_partition, (char*)commEntryName.c_str());
00274 rs = command->remove();
00275 if(rs == ISInfo::CommFailure) {
00276 cerr << "SCTDdcCommandSender_ERROR: " << COMMAND_SERVER
00277 << " is not running in " << m_partition.name() << endl;
00278 ok = false;
00279 }
00280 delete command;
00281 return(ok);
00282 }
00283
00284
00285 bool SCTDdcCommandSender::ddcRemoveCommand()
00286 {
00287 ISInfo::Status rs;
00288 bool ok = true;
00289 string commEntryName(COMMAND_SERVER);
00290
00291 commEntryName = commEntryName + ".DdcNtCommand";
00292 DdcNtCommand* command = new DdcNtCommand(m_partition, (char*)commEntryName.c_str());
00293 rs = command->remove();
00294 if(rs == ISInfo::CommFailure) {
00295 cerr << "SCTDdcCommandSender_ERROR: " << COMMAND_SERVER
00296 << " is not running in " << m_partition.name() << endl;
00297 ok = false;
00298 }
00299 delete command;
00300 return(ok);
00301 }
00302
00303 string SCTDdcCommandSender::makeResponseName(string& ctrlName, string& commandName)
00304 {
00305 string isEntry(COMMAND_SERVER);
00306
00307 isEntry += '.' + commandName + '.' + ctrlName + ".response";
00308 return(isEntry);
00309 }
00310
00311
00312 bool SCTDdcCommandSender::isValidCtrl(string& name)
00313 {
00314 if(name == "*")
00315 {
00316 return(true);
00317 }
00318 else
00319 {
00320 int i = 0;
00321 while(m_controllers[i] != 0)
00322 {
00323 if(*m_controllers[i] == name) return(true);
00324 i++;
00325 }
00326 return(false);
00327 }
00328 }