diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.cpp index be6ca900efc5bc5b7f19801443dccdeafaed77e6..143a805dcbf6615657a3156c0f7b225a8d8f0803 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.cpp @@ -100,24 +100,20 @@ namespace Silecs bool CNVConnection::open(PLC* thePLC) { - bool isOK = false; + //Controller is reachable at this stage (ping done from doOpen) + bool isOK = true; //all subscription is fine a priori - if (IeRfcPing((char *) thePLC->getName().c_str(), 0) == 0) - { - LOG(DEBUG) << "CNVConnection::open(): Controller is reachable (ping), then subscribe input variables"; - - isOK = true; //all subscription is fine a priori + LOG(DEBUG) << "CNVConnection::open(): Subscribe to all input variables"; - // Create all the subscriptions - blockMapType::iterator pBlockIter; - for(pBlockIter = thePLC->getBlockMap().begin(); pBlockIter != thePLC->getBlockMap().end(); ++pBlockIter) - { - //Attention: only CNVInputBlock has doSubscribe/unSubscribe feature (key-map can be used to select appropriate object) - if (pBlockIter->first.find(Block::whichAccessType(Input)) != std::string::npos) - { if (static_cast<CNVInputBlock*>(pBlockIter->second)->doSubscribe() == false) - { isOK = false; - break; - } + // Create all the subscriptions + blockMapType::iterator pBlockIter; + for(pBlockIter = thePLC->getBlockMap().begin(); pBlockIter != thePLC->getBlockMap().end(); ++pBlockIter) + { + //Attention: only CNVInputBlock has doSubscribe/unSubscribe feature (key-map can be used to select appropriate object) + if (pBlockIter->first.find(Block::whichAccessType(Input)) != std::string::npos) + { if (static_cast<CNVInputBlock*>(pBlockIter->second)->doSubscribe() == false) + { isOK = false; + break; } } } @@ -127,7 +123,7 @@ namespace Silecs bool CNVConnection::close(PLC* thePLC) { - LOG(DEBUG) << "CNVConnection::close(): unSubscribe input variables"; + LOG(DEBUG) << "CNVConnection::close(): unSubscribe all input variables"; // Delete all the subscription blockMapType::iterator pBlockIter; diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp index b9ad8cf696aa0e52f4a12f0cff3129066da593d3..77b3abc6265c7687e64c11ca3a192ea768dc56ee 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp @@ -90,7 +90,9 @@ namespace Silecs bool Connection::doOpen(PLC* thePLC) { //LOG((COMM|DIAG)) << "Start attempt to open connection ..."; .. commented, seem like this creates to many log-entries for KIBANA - bool justConnected = false; + bool isReachable = false; + bool isOpen = false; + bool justConnected = false; { Lock lock(connMux_); @@ -111,49 +113,54 @@ namespace Silecs if (isTimeToReconnect()) { - LOG((COMM|DIAG)) << "It's time to reconnect"; - - // It's time to open the connection according to the (re)connection timing - // Let's try several times with limited delay (some ms). - // It allows wake-up frozen PLC (SIEMENS in particular) after long stop period. - bool isOpen = false; - unsigned int nbConn = 2; //for fast low-level iteration - for(unsigned int i = 0; i<nbConn; i++) - { - LOG((COMM|DIAG)) << "Attempt to open PLC connection ...."; - isOpen = open(thePLC); - if(isOpen) - { - LOG((COMM|DIAG)) << "Connection opened successfully"; - break; - } - usleep(100000); // wait 100ms - } - if(!isOpen) - { - logError(thePLC); - return isConnected_; - } + if (isReachable = (IeRfcPing((char *) thePLC->getName().c_str(), NULL) == 0)) + { + LOG((COMM|DIAG)) << "It's time to reconnect"; + + // It's time to open the connection according to the (re)connection timing + // Let's try several times with limited delay (some ms). + // It allows wake-up frozen PLC (SIEMENS in particular) after long stop period. + bool isOpen = false; + unsigned int nbConn = 2; //for fast low-level iteration + for(unsigned int i = 0; i<nbConn; i++) + { + LOG((COMM|DIAG)) << "Attempt to open PLC connection ...."; + isOpen = open(thePLC); + if(isOpen) + { + LOG((COMM|DIAG)) << "Connection opened successfully"; + break; + } + usleep(100000); // wait 100ms + } + }//pingable? + + if(!isOpen) + { + logError(thePLC,isReachable); + return isConnected_; + } + + if (thePLC->isSharedConnection()) + { + LOG((COMM|DIAG)) << "Shared connection with " << thePLC->getName() << " is established."; + } + else + { + LOG((COMM|DIAG)) << "Connection with " << thePLC->getName() << + ":" << thePLC->theCluster_->getClassName() << + "/v" << thePLC->theCluster_->getClassVersion() << + " is established."; + } + + isAlive_ = true; + isConnected_ = true; + justConnected = true; //retentive registers synchronization is required! + + //Connection status has changed: update the diagnostic variables + LOG((COMM|DIAG)) << "Updating PLC status"; + updateStatus(thePLC); - if (thePLC->isSharedConnection()) - { - LOG((COMM|DIAG)) << "Shared connection with " << thePLC->getName() << " is established."; - } - else - { - LOG((COMM|DIAG)) << "Connection with " << thePLC->getName() << - ":" << thePLC->theCluster_->getClassName() << - "/v" << thePLC->theCluster_->getClassVersion() << - " is established."; - } - - isAlive_ = true; - isConnected_ = true; - justConnected = true; //retentive registers synchronization is required! - - //Connection status has changed: update the diagnostic variables - LOG((COMM|DIAG)) << "Updating PLC status"; - updateStatus(thePLC); } }//release lock @@ -323,12 +330,11 @@ namespace Silecs //------------------------------------------------------------------------------------------------------------------------------------------------ - void Connection::logError(PLC* thePLC) - { - std::string errorMsg = "Connection with " + thePLC->getName() + - ":" + thePLC->theCluster_->getClassName() + - "/v" + thePLC->theCluster_->getClassVersion() + - " has failed. "; + void Connection::logError(PLC* thePLC, bool isReachable) + { + std::string errorMsg = isReachable ? "Connection with " + thePLC->getName() + ":" + thePLC->theCluster_->getClassName() + + "/v" + thePLC->theCluster_->getClassVersion() + " has failed.\n" + : "Controller " + thePLC->getName() + " does not respond to ping, might be OFF!\n"; if (delayConn_ == LongTermConnection) { if (remainConn_ > 0) diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h index d168f7c1c98b8ad25047930d5951022a0b0449f6..7d350c76dc6782808f8bb5b1e4edb9aa7a8053c6 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h @@ -133,7 +133,7 @@ namespace Silecs */ void updateStatus(PLC* thePLC); - void logError(PLC* thePLC); + void logError(PLC* thePLC, bool isReachable); /*! * \fn isTimeToReconnect diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp index 1cc2c4d66b46312d45f836defb6ec18219d8ccea..edc58963efbc07137adb4321c116f5670b8bb85a 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp @@ -143,6 +143,24 @@ namespace Silecs throw SilecsException(__FILE__, __LINE__, CONFIG_CLIENT_PLC_NOT_CONSISTENT, message.str()); } } + + //Warn ACET service that a new connection is established (except for SilecsHeader) + if (theHeader_ != NULL) { + TRACE("cluster") << "ClassName=" << theCluster_->getClassName() << "|" << + "ClassVersion=" << theCluster_->getClassVersion() << "|" << + "Owner=" << localOwner_ << "|" << + "GenerationRelease=" << localRelease_ << "|" << + "GenerationDate=" << localDate_ << "|" << + "PlcChecksum=" << localChecksum_ << "|" << + "PlcDomain=" << domain_ << "|" << + "PlcHostname=" << name_ << "|" << + "PlcBrand=" << brand_ << "|" << + "PlcSystem=" << system_ << "|" << + "PlcModel=" << model_ << "|" << + "ProtocolAddress=" << baseAddr_ << "|" << + "ProtocolMode=" << protocolMode_ << "|" << + "InstanceNumber=" << deviceCol_.size(); + } };