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