diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.cpp index 6f91e021fd6c84ed8c4dfd7b45e2475c4fc59eb9..277098cd2604f7f7c5c105161f98e26f75dce4d9 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.cpp @@ -25,6 +25,9 @@ namespace Silecs SNAP7Connection::SNAP7Connection(PLC* thePLC) : Connection(thePLC) { + rackNb_ = 0; //rackNb - common rack is 0 so far + slotNb_ = -1; //slotNb - depends on hardware configuration (scan is required the first connect) + recvClient_ = Cli_Create(); sendClient_ = Cli_Create(); LOG(ALLOC) << "SNAP7Connection (create) PLC/Cluster: " << thePLC->getName() << "/" << thePLC->theCluster_->getClassName(); @@ -40,14 +43,17 @@ namespace Silecs bool SNAP7Connection::open(PLC* thePLC) { int err = 0; + bool ret = false; + int slotNb; //Slot number is not required, so try to connect on different slots (1..31), depending on hardware layout. int *slotsScan; - int slotsS7400[4] = { 3,4,2,1 }; //slot scan - most common layout S7-400 - int slotsS71x00[4] = { 1,2,3,4 }; //slot scan - most common layout S7-1200, S7-1500 - int slotsDefault[4] = { 2,3,4,1 }; //slot scan - most common layout S7-other (S7-300, ET200S) - int rackNb = 0; //rackNb - common rack is 0 so far - int slotNb; + int slotsS7400[4] = { 3,2,4,1 }; //slot scan - most common layout S7-400 + int slotsS71x00[4] = { 1,2,3,4 }; //slot scan - most common layout S7-1200, S7-1500 + int slotsDefault[4] = { 2,3,4,1 }; //slot scan - most common layout S7-other (S7-300, ET200S) + int nbMaxSlot = ((slotNb_ == -1) ? 4 : 1); //slots scan only the first time (slotNb_ == -1) + + switch (thePLC->getModelID()) { @@ -60,27 +66,36 @@ namespace Silecs slotsScan = slotsDefault; //S7-300, ET200S } - for(int i=0; i<4; i++) + for(int i=0; i<nbMaxSlot; i++) { slotNb = slotsScan[i]; - err = Cli_ConnectTo(recvClient_, thePLC->getIPAddress().c_str(), rackNb, slotNb); - if (err) // next slot - { - LOG(DEBUG) << "SNAP7 connection (channel-2) failed on PLC/rack/slot: " << thePLC->getName() << "/" << rackNb << "/" << slotNb <<". SNAP7[" << err << "]: " << getSNAP7ErrorMessage(err); - break; - } - LOG(DEBUG) << "SNAP7 connect (channel-1) successful on PLC/rack/slot: " << thePLC->getName() << "/" << rackNb << "/" << slotNb; - //We managed to open the first channel, just open the second one on the same slot. - err = Cli_ConnectTo(sendClient_, thePLC->getIPAddress().c_str(), rackNb, slotNb); - if (err) // next slot + + err = ((slotNb_ == -1) ? Cli_ConnectTo(recvClient_, thePLC->getIPAddress().c_str(), rackNb_, slotNb) : + Cli_Connect(recvClient_)); + + if (err == 0) { - LOG(DEBUG) << "SNAP7 connection (channel-2) failed on PLC/rack/slot: " << thePLC->getName() << "/" << rackNb << "/" << slotNb <<". SNAP7[" << err << "]: " << getSNAP7ErrorMessage(err); - break; + LOG(DEBUG) << "SNAP7 connect (channel-1) successful on PLC/rack/slot: " << thePLC->getName() << "/" << rackNb_ << "/" << slotNb; + + //We managed to open the first channel, just open the second one on the same slot. + err = ((slotNb_ == -1) ? Cli_ConnectTo(sendClient_, thePLC->getIPAddress().c_str(), rackNb_, slotNb) : + Cli_Connect(sendClient_)); + + if (err != 0) + { + LOG(DEBUG) << "SNAP7 connection (channel-2) failed on PLC/rack/slot: " << thePLC->getName() << "/" << rackNb_ << "/" << slotNb <<". SNAP7[" << err << "]: " << getSNAP7ErrorMessage(err); + continue; + } + + LOG(DEBUG) << "SNAP7 connect (channel-2) successful on PLC/rack/slot: " << thePLC->getName() << "/" << rackNb_ << "/" << slotNb; + + slotNb_ = slotNb; //connection is ok we can store the valid slot number for the next (re)connection (will be faster). + ret = true; + break; } - LOG(DEBUG) << "SNAP7 connect (channel-2) successful on PLC/rack/slot: " << thePLC->getName() << "/" << rackNb << "/" << slotNb; - return true; + LOG(DEBUG) << "SNAP7 connection (channel-1) failed on PLC/rack/slot: " << thePLC->getName() << "/" << rackNb_ << "/" << slotNb <<". SNAP7[" << err << "]: " << getSNAP7ErrorMessage(err); } - return false; + return (ret); } diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h index 6e156f7cca3a93c330c5bae0126b341ae1c6dcb4..9ff8ba453eee21629f68468711d06492af072c22 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h @@ -55,6 +55,9 @@ namespace Silecs bool open(PLC* thePLC); bool close(PLC* thePLC); + int rackNb_; //rackNb - common rack is 0 by default + int slotNb_; //slotNb - depends on hardware configuration (scan is required the first connect) + std::string getSNAP7ErrorMessage(int err); };