Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Related Pages

SCTDdcCommandSender.cxx

00001 
00002 // This file contains the class definition to issue 
00003 // a non-transition command (inspired from DDC code package)
00004 //                  
00005 //    Created 01.04.03
00006 //    by A. Abdesselam
00008 
00009 #include <string>
00010 
00011 #include <is/isnamedinfo.h>
00012 #include "sctddc/SCTDdcCommandSender.hxx"
00013 #include <unistd.h> // for usleep
00014 
00015 using namespace std;
00016 
00017 
00018   //SCTDdcCommandSender(IPCPartition& p, string** ctrlList);
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 // ~SCTDdcCommandSender();
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   //find the controller name. the received name has the format: command.controller.response
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           // set the response command code
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         } // end of if(result.getValue() <0) 
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 //this method  (which overload the method below) is jsut for the purpose to use a defalut 
00105 //controller (*m_controllers[0])
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 == "*") // send the command to all the contrllers
00122     {
00123       // First subscription for the command results
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           // And now sending the command
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     }//end of if(ctrlName == "*")
00163       else 
00164     {
00165       // First subscription for the command result
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           // And now sending the command
00177           m_startTime = time(&m_startTime);
00178           m_ctrlNum = 1;
00179           
00180           // send command for an individual DDC controller
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   // wait until the command is finish the timeout sepnt
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     } //end while(...)
00224   return m_commandResponse;
00225 }
00226 
00227 // Help method (send command)
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 }

Generated on Fri Sep 16 18:01:58 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5