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 5e3e73ab69ef945495197ea460100768ebf936c4..0623f576898847e299d3f62dc98ae3e1bc9772cf 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.cpp @@ -105,8 +105,18 @@ namespace Silecs { return writeData(thePLC, address, offset, size, pBuffer); } - int CNVConnection::readInput(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) {return 0;} - int CNVConnection::writeOutput(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) {return 0;} + int CNVConnection::readIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) + { + + LOG(ERROR) << "Read IO not supported for CNV"; + return 0; + } + + int CNVConnection::writeIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) + { + LOG(ERROR) << "Write IO not supported for CNV"; + return 0; + } bool CNVConnection::open(PLC* thePLC) { diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.h b/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.h index bb3fa70c0222868064c0490b7a86595c4782f44c..98a30c4f847093e00bc424bd5e67d85b4075ee39 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.h +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.h @@ -80,8 +80,8 @@ namespace Silecs unsigned char* buffer){return -1;}; int readMemory(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); int writeMemory(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); - int readInput(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); - int writeOutput(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); + int readIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); + int writeIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); private: // Subscriber diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp index ed4960f1a1e4e01595ee1c7434bdac9bc193c516..9e31237b9947d97471ad46cf37944e582cea8fe9 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp @@ -26,224 +26,248 @@ namespace Silecs { - MBConnection::MBConnection(PLC* thePLC) : Connection(thePLC) - { - LOG(ALLOC) << "MBConnection (create): " << thePLC->getName(); + + MBConnection::MBConnection(PLC* thePLC) : Connection(thePLC) + { + LOG(ALLOC) << "MBConnection (create): " << thePLC->getName(); //Connection use IP address to limit the naming-server accesses readCtx_ = modbus_new_tcp((char *) thePLC->getIPAddress().c_str(), MODBUS_TCP_DEFAULT_PORT /*=502*/); writeCtx_ = modbus_new_tcp((char *) thePLC->getIPAddress().c_str(), MODBUS_TCP_DEFAULT_PORT /*=502*/); /*TODO: To be adjusted with the next stable libmodbus release (>3.1.1) - which will fix the current timeout response time issue (see libmodbus forum). + which will fix the current timeout response time issue (see libmodbus forum). - Define Modbus response timeout - struct timeval response_timeout; - response_timeout.tv_sec = 0; - response_timeout.tv_usec = 10000; + Define Modbus response timeout + struct timeval response_timeout; + response_timeout.tv_sec = 0; + response_timeout.tv_usec = 10000; - modbus_set_response_timeout(readCtx_ , &response_timeout); - modbus_set_response_timeout(writeCtx_ , &response_timeout); - */ + modbus_set_response_timeout(readCtx_ , &response_timeout); + modbus_set_response_timeout(writeCtx_ , &response_timeout); + */ modbus_set_slave(readCtx_, 1); //modbus_set_debug(readCtx_, TRUE); - } + } - MBConnection::~MBConnection() - { - //Close the connection before removing resources - //disable(); must be done before removing resource + + MBConnection::~MBConnection() + { + //Close the connection before removing resources + //disable(); must be done before removing resource modbus_free(writeCtx_); modbus_free(readCtx_); - } + } - bool MBConnection::open(PLC* thePLC) - { - int readErr = modbus_connect(readCtx_); + + bool MBConnection::open(PLC* thePLC) + { + int readErr = modbus_connect(readCtx_); int writeErr = modbus_connect(writeCtx_); - return ((readErr != -1) && (writeErr != -1)); - } + return ((readErr != -1) && (writeErr != -1)); + } - bool MBConnection::close(PLC* thePLC) - { - modbus_close(readCtx_); + + bool MBConnection::close(PLC* thePLC) + { + modbus_close(readCtx_); modbus_close(writeCtx_); - return true; - } + return true; + } - int MBConnection::readData(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) - { - int rc = 0; - //Schneider uses 16bit alignment memory. Block address is expressed in bytes, must be an even value! - if (address % 2) throw SilecsException(__FILE__, __LINE__, PARAM_INCORRECT_BLOCK_ADDRESS, StringUtilities::toString(address)); + /*----------------------------------------------------------*/ + int MBConnection::mbWriteData(modbus_t* ctx, uint16_t start_addr, uint16_t count, uint8_t* data) + { + uint16_t *srcp = (uint16_t*)data; + int word_count, byte_count; + int rc; - /* . There is one read-channel per PLC connection. It must be protected against concurrent access. - * . The write-channel is independent and can be accessed in parallel. - * . The global action (open,close,etc.) must be protected from any concurrent access. - * Attention! - * Mutexes are defined with recursive option. It allows doOpen method re-calling readData - * method by executing register synchronization if required. - */ + while(count) + { + word_count = (count > MAX_WRITE_DATA_SIZE) ? MAX_WRITE_DATA_SIZE/2 : (count/2)+(count%2); + byte_count = (word_count * 2); - //(re)connect the PLC if needed and (re)synchronize the retentive registers - if (doOpen(thePLC)) - { - //connection is established then acquire data - readLock(); - //Schneider uses 16bit alignment memory. Block address is expressed in bytes (==> /2) - unsigned short addr = ((unsigned short)address + (unsigned short)offset)/2; + if ((rc = modbus_write_registers(ctx, start_addr, word_count, srcp)) != word_count) + { + return rc; + } - //DATA topic makes sense with RECV one - if (RECV & Log::topics_) LOG(DATA) << "Read data, address: %MW" << addr << ", byte-size: " << size; + //srcp += byte_count-(count%2); + srcp += word_count; + start_addr += word_count; + count -= (byte_count - (count%2)); + } - rc = mbReadData(readCtx_, addr, (unsigned short)size, pBuffer); - checkError(thePLC, rc, false);// close the connection, will try again at the next access - readUnlock(); - } - return rc; - } + return rc; + } - int MBConnection::writeData(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) - { - int rc = 0; - //Schneider uses 16bit alignment memory. Block address is expressed in bytes, must be an even value! - if (address % 2) throw SilecsException(__FILE__, __LINE__, PARAM_INCORRECT_BLOCK_ADDRESS, StringUtilities::toString(address)); + /*----------------------------------------------------------*/ + int MBConnection::mbReadData(modbus_t* ctx, uint16_t start_addr, uint16_t count, uint8_t* data) + { + uint16_t *destp = (uint16_t*)data; + int word_count, byte_count; + int rc; - /* . There is one read-channel per PLC connection. It must be protected against concurrent access. - * . The write-channel is independent and can be accessed in parallel. - * . The global action (open,close,etc.) must be protected from any concurrent access. - * Attention! - * Mutexes are defined with recursive option. It allows doOpen method re-calling sendData - * method by executing register synchronization if required. - */ + while(count) { - //(re)connect the PLC if needed and (re)synchronize the retentive registers - if (doOpen(thePLC)) + if (count > MAX_READ_DATA_SIZE) + { + /*'word_count' is a word counter*/ + word_count = MAX_READ_DATA_SIZE/2; + } + else { - //connection is established then send data - writeLock(); - //Schneider uses 16bit alignment memory. Block address is expressed in bytes (==> /2) - unsigned short addr = ((unsigned short)address + (unsigned short)offset)/2; + /*'word_count' is a word counter*/ + word_count = (count/2) + (count%2); + } - //DATA topic makes sense with SEND one - if (SEND & Log::topics_) LOG(DATA) << "Write data, address: %MW" << addr << ", byte-size: " << size; + byte_count = (word_count * 2); - rc = mbWriteData(writeCtx_, (unsigned short)addr, (unsigned short)size, pBuffer); - checkError(thePLC, rc, false);// close the connection, will try again at the next access - writeUnlock(); + if ((rc = modbus_read_registers(ctx, start_addr, word_count, destp)) != word_count) + { + return rc; } - return rc; - } - int MBConnection::readMemory(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) - { - return readData(thePLC, address, offset, size, pBuffer); + //destp += (byte_count-(count%2)); + destp += word_count; + start_addr += word_count; + count -= (byte_count - (count%2)); } - int MBConnection::writeMemory(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) - { - return writeData(thePLC, address, offset, size, pBuffer); - } + return rc; + } - int MBConnection::readInput(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) + + int MBConnection::readData(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) + { + int rc = 0; + int error = 0; + + //Schneider uses 16bit alignment memory. Block address is expressed in bytes, must be an even value! + if (address % 2) throw SilecsException(__FILE__, __LINE__, PARAM_INCORRECT_BLOCK_ADDRESS, StringUtilities::toString(address)); + + /* . There is one read-channel per PLC connection. It must be protected against concurrent access. + * . The write-channel is independent and can be accessed in parallel. + * . The global action (open,close,etc.) must be protected from any concurrent access. + * Attention! + * Mutexes are defined with recursive option. It allows doOpen method re-calling readData + * method by executing register synchronization if required. + */ + + //(re)connect the PLC if needed and (re)synchronize the retentive registers + if (doOpen(thePLC)) { - return readData(thePLC, address, offset, size, pBuffer); + //connection is established then acquire data + readLock(); + //Schneider uses 16bit alignment memory. Block address is expressed in bytes (==> /2) + unsigned short addr = ((unsigned short)address + (unsigned short)offset)/2; + + //DATA topic makes sense with RECV one + if (RECV & Log::topics_) LOG(DATA) << "Read data, address: %MW" << addr << ", byte-size: " << size; + + rc = mbReadData(readCtx_, addr, (unsigned short)size, pBuffer); + + checkError(thePLC, rc, false); // close the connection, will try again at the next access + if (!checkError(thePLC, rc, false)) + error = 0; + else + error = rc; + + readUnlock(); } + return error; + } + + + int MBConnection::writeData(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) + { + int rc = 0; + int error = 0; - int MBConnection::writeOutput(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) + //Schneider uses 16bit alignment memory. Block address is expressed in bytes, must be an even value! + if (address % 2) throw SilecsException(__FILE__, __LINE__, PARAM_INCORRECT_BLOCK_ADDRESS, StringUtilities::toString(address)); + + /* . There is one read-channel per PLC connection. It must be protected against concurrent access. + * . The write-channel is independent and can be accessed in parallel. + * . The global action (open,close,etc.) must be protected from any concurrent access. + * Attention! + * Mutexes are defined with recursive option. It allows doOpen method re-calling sendData + * method by executing register synchronization if required. + */ + + //(re)connect the PLC if needed and (re)synchronize the retentive registers + if (doOpen(thePLC)) { - return writeData(thePLC, address, offset, size, pBuffer); + //connection is established then send data + writeLock(); + //Schneider uses 16bit alignment memory. Block address is expressed in bytes (==> /2) + unsigned short addr = ((unsigned short)address + (unsigned short)offset)/2; + + //DATA topic makes sense with SEND one + if (SEND & Log::topics_) LOG(DATA) << "Write data, address: %MW" << addr << ", byte-size: " << size; + + rc = mbWriteData(writeCtx_, (unsigned short)addr, (unsigned short)size, pBuffer); + checkError(thePLC, rc, false); // close the connection, will try again at the next access + if (!checkError(thePLC, rc, false)) + error = 0; + else + error = rc; + + writeUnlock(); } + return error; + } - /*----------------------------------------------------------*/ - int MBConnection::mbWriteData(modbus_t* ctx, uint16_t start_addr, uint16_t count, uint8_t* data) - { - uint16_t *srcp = (uint16_t*)data; - int word_count, byte_count; - int rc; - while(count) - { - word_count = (count > MAX_WRITE_DATA_SIZE) ? MAX_WRITE_DATA_SIZE/2 : (count/2)+(count%2); - byte_count = (word_count * 2); - - if ((rc = modbus_write_registers(ctx, start_addr, word_count, srcp)) != word_count) - { - return rc; - } - - //srcp += byte_count-(count%2); - srcp += word_count; - start_addr += word_count; - count -= (byte_count - (count%2)); - } + int MBConnection::readMemory(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) + { + return readData(thePLC, address, offset, size, pBuffer); + } - return rc; - } - /*----------------------------------------------------------*/ - int MBConnection::mbReadData(modbus_t* ctx, uint16_t start_addr, uint16_t count, uint8_t* data) - { - uint16_t *destp = (uint16_t*)data; - int word_count, byte_count; - int rc; + int MBConnection::writeMemory(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) + { + return writeData(thePLC, address, offset, size, pBuffer); + } - while(count) - { - if (count > MAX_READ_DATA_SIZE) - { - /*'word_count' is a word counter*/ - word_count = MAX_READ_DATA_SIZE/2; - } - else - { - /*'word_count' is a word counter*/ - word_count = (count/2) + (count%2); - } - - byte_count = (word_count * 2); - - if ((rc = modbus_read_registers(ctx, start_addr, word_count, destp)) != word_count) - { - return rc; - } - - //destp += (byte_count-(count%2)); - destp += word_count; - start_addr += word_count; - count -= (byte_count - (count%2)); - } + int MBConnection::readIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) + { + return readData(thePLC, address, offset, size, pBuffer); + } - return rc; - } -//------------------------------------------------------------------------------------------------------------------- - bool MBConnection::checkError(PLC* thePLC, int rc, bool retry) - { + int MBConnection::writeIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) + { + return writeData(thePLC, address, offset, size, pBuffer); + } - if (rc == -1) - { - LOG(COMM) << "Transaction failure with PLC: " << thePLC->getName() << " " << modbus_strerror(errno); - - if (retry) - { - LOG(COMM) << "Try to reconnect the PLC: " << thePLC->getName(); - if (reOpen(thePLC)) - { // can repeat the request after the connection was successfully reopened - return true; - } - // reconnection has failed again, just close the connection - LOG(COMM) << "Unable to reconnect the PLC: " << thePLC->getName(); - } - // no retry, we just want to close (use default case) - doClose(thePLC, /*withLock =*/true); + + //------------------------------------------------------------------------------------------------------------------- + bool MBConnection::checkError(PLC* thePLC, int rc, bool retry) + { + + if (rc == -1) { + LOG(COMM) << "Transaction failure with PLC: " << thePLC->getName() << " " << modbus_strerror(errno); + + if (retry) + { + LOG(COMM) << "Try to reconnect the PLC: " << thePLC->getName(); + if (reOpen(thePLC)) + { // can repeat the request after the connection was successfully reopened + return true; } - return false; + // reconnection has failed again, just close the connection + LOG(COMM) << "Unable to reconnect the PLC: " << thePLC->getName(); + } + // no retry, we just want to close (use default case) + doClose(thePLC, /*withLock =*/true); } + return false; + } } // namespace #endif //MODBUS_SUPPORT_ENABLED diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.h b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.h index 46317ec6a920a7e32b86a4b5b32e48c98e7630f0..003fd6a4e6a6af37dd1e963a08e40af139b6462e 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.h +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.h @@ -37,8 +37,8 @@ namespace Silecs int readMemory(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); int writeMemory(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); - int readInput(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); - int writeOutput(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); + int readIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); + int writeIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); private: modbus_t* readCtx_; 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 065bdc619ce39392c1d7bdbfc25d3bc474bbd316..471db7e8148d7467b1f624e55646f055dd3a9413 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.cpp @@ -273,7 +273,7 @@ int SNAP7Connection::writeMemory(PLC* thePLC, unsigned long DBn, unsigned long o return err; } -int SNAP7Connection::readInput(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) +int SNAP7Connection::readIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) { int err = 0; //(re)connect the PLC if needed and (re)synchronize the retentive registers @@ -290,7 +290,7 @@ int SNAP7Connection::readInput(PLC* thePLC, unsigned long address, unsigned long return err; } -int SNAP7Connection::writeOutput(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) +int SNAP7Connection::writeIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer) { int err = 0; //(re)connect the PLC if needed and (re)synchronize the retentive registers 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 d09d02fa3bfde7cd9d5197b819a45822bdf7650b..030a25f2cd263030d0851eb1a6e6189e53d2316f 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h @@ -45,8 +45,8 @@ namespace Silecs int writeData(PLC* thePLC, unsigned long DBn, unsigned long offset, unsigned long size, unsigned char* pBuffer); int readMemory(PLC* thePLC, unsigned long DBn, unsigned long offset, unsigned long size, unsigned char* pBuffer); int writeMemory(PLC* thePLC, unsigned long DBn, unsigned long offset, unsigned long size, unsigned char* pBuffer); - int readInput(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); - int writeOutput(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); + int readIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); + int writeIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer); //Extension Silecs methods int coldRestart(PLC* thePLC); 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 7d560e3c79e6073c15e243197ecbbb230d7bdd07..93cd441a540faa3c88d81d28b00f07b648a301d6 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp @@ -451,32 +451,22 @@ namespace Silecs if ((s=socket(AF_INET,SOCK_STREAM,0)) == -1) { - #ifdef COMMENT - printf("#Error - Can't create socket: %s\n", strerror(errno)); - #endif + LOG(ERROR) << "Can't create socket: " << strerror(errno); return RFC_SYS_ERROR; } /* Set TCP_NODELAY option to force immediate TCP/IP acknowledgement */ if ((pent=getprotobyname("TCP")) == NULL) { - #ifdef COMMENT - printf("#Error - Can't configure socket: %s\n", strerror(errno)); - #endif + LOG(ERROR) << "Can't configure socket: " << strerror(errno); return RFC_SYS_ERROR; } if (setsockopt(s,pent->p_proto,TCP_NODELAY,&val,4) == -1) { - #ifdef COMMENT - printf("#Error - Can't configure socket: %s\n", strerror(errno)); - #endif + LOG(ERROR) << "Can't configure socket: " << strerror(errno); return RFC_SYS_ERROR; } - #ifdef COMMENT - printf("#Comment - Socket created: %i\n", s); - #endif - rsock.sin_addr.s_addr=inet_addr(ip); rsock.sin_family=AF_INET; /*check any port to detect if the host is OFF*/ 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 62c19c7c939f0ea99a2c2fc519ebcacf04b046b4..4c5b9a74b9a4e6ed26b33ca0f9db8119baae1d78 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h @@ -42,18 +42,6 @@ namespace Silecs Connection(PLC* thePLC); virtual ~Connection(); - virtual int readData(PLC* thePLC, - unsigned long address, - unsigned long offset, - unsigned long size, - unsigned char* buffer) = 0; - - virtual int writeData(PLC* thePLC, - unsigned long address, - unsigned long offset, - unsigned long size, - unsigned char* buffer) = 0; - virtual int readMemory(PLC* thePLC, unsigned long address, unsigned long offset, @@ -66,13 +54,13 @@ namespace Silecs unsigned long size, unsigned char* buffer) = 0; - virtual int readInput(PLC* thePLC, + virtual int readIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* buffer) = 0; - virtual int writeOutput(PLC* thePLC, + virtual int writeIO(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, @@ -178,7 +166,7 @@ namespace Silecs * intermediate connect_nonb() function is used to perform a non-blockant connection. * intermediate rfcPing() function is used to check if PLC is ON */ - int ping(char *hostName, char *plcIP); + static int ping(char *hostName, char *plcIP); // Communication Diagnostic & Monitoring static bool isAlive_; // PLC has repliyed to the ping: true/false diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.cpp index 8b34eecf8eb3d00a0a602dba2c0bcb96c533d4f5..e34cd5c81b97081395c4c9a7988b86388dfd67b2 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.cpp @@ -85,20 +85,10 @@ namespace Silecs //begin critical section Lock lock(bufferMux_); switch (theBlock_->getAccessArea()) { - case Memory: { - errorCode = pConn->readMemory( - theBlock_->getPLC(), - usedAddress, //Base address (or DBn) of the block - usedDeviceOffset, //Device data address within the block - usedSize, //Get one device-block only - pBuffer //Buffer to store the data - ); - break; - } case Digital: case Analog: { - errorCode = pConn->readInput( + errorCode = pConn->readIO( theBlock_->getPLC(), usedAddress, //Base address (or DBn) of the block usedDeviceOffset, //Device data address within the block @@ -107,9 +97,10 @@ namespace Silecs ); break; } + case Memory: default: { - errorCode = pConn->readData( + errorCode = pConn->readMemory( theBlock_->getPLC(), usedAddress, //Base address (or DBn) of the block usedDeviceOffset, //Device data address within the block @@ -151,20 +142,10 @@ namespace Silecs //begin critical section Lock lock(bufferMux_); switch (theBlock_->getAccessArea()) { - case Memory: { - errorCode = pConn->readMemory( - theBlock_->getPLC(), - theBlock_->getAddress(), //Base address (or DBn) of the block - 0, //Get all devices from the first one - ((PLCBlock*)theBlock_)->getBufferSize(), //Get blocks of all devices (full buffer size) - (unsigned char*)theBlock_->getBuffer() //Buffer to store the data (full buffer) - ); - break; - } case Digital: case Analog: { - errorCode = pConn->readInput( + errorCode = pConn->readIO( theBlock_->getPLC(), theBlock_->getAddress(), //Base address (or DBn) of the block 0, //Get all devices from the first one @@ -173,9 +154,10 @@ namespace Silecs ); break; } + case Memory: default: { - errorCode = pConn->readData( + errorCode = pConn->readMemory( theBlock_->getPLC(), theBlock_->getAddress(), //Base address (or DBn) of the block 0, //Get all devices from the first one @@ -247,20 +229,10 @@ namespace Silecs //begin critical section Lock lock(bufferMux_); switch (theBlock_->getAccessArea()) { - case Memory: { - errorCode = pConn->readMemory( - theBlock_->getPLC(), - usedDeviceAddress, //Base address (or DBn) of the device - usedBlockAddress, //Block data address within the device - usedSize, //Get one device-block only - (unsigned char*)theBlock_->getBuffer() //Buffer to store the data - ); - break; - } case Digital: case Analog: { - errorCode = pConn->readInput( + errorCode = pConn->readIO( theBlock_->getPLC(), usedDeviceAddress, //Base address (or DBn) of the device usedBlockAddress, //Block data address within the device @@ -269,9 +241,10 @@ namespace Silecs ); break; } + case Memory: default: { - errorCode = pConn->readData( + errorCode = pConn->readMemory( theBlock_->getPLC(), usedDeviceAddress, //Base address (or DBn) of the device usedBlockAddress, //Block data address within the device @@ -317,20 +290,10 @@ namespace Silecs //begin critical section Lock lock(bufferMux_); switch (theBlock_->getAccessArea()) { - case Memory: { - errorCode = pConn->readMemory( - theBlock_->getPLC(), - pDev->getAddress(), //Base address (or DBn) of the device - theBlock_->getAddress(), //Block data address within the device - theBlock_->getMemSize(), //Get one device-block only - (unsigned char*)theBlock_->getBuffer() //Buffer to store the data - ); - break; - } case Digital: case Analog: { - errorCode = pConn->readInput( + errorCode = pConn->readIO( theBlock_->getPLC(), pDev->getAddress(), //Base address (or DBn) of the device theBlock_->getAddress(), //Block data address within the device @@ -338,9 +301,11 @@ namespace Silecs (unsigned char*)theBlock_->getBuffer() //Buffer to store the data ); - } default: + } + case Memory: + default: { - errorCode = pConn->readData( + errorCode = pConn->readMemory( theBlock_->getPLC(), pDev->getAddress(), //Base address (or DBn) of the device theBlock_->getAddress(), //Block data address within the device diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.cpp index a1cad4081cac0c5e7ba45c1dad2096de6dc8ea7f..5c781e2e3373e2413ae3482f6d2a6193920c0e99 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.cpp @@ -84,21 +84,10 @@ namespace Silecs } switch (theBlock_->getAccessArea()) { - case Memory: - { - errorCode = pConn->writeMemory( - theBlock_->getPLC(), - usedAddress, //Base address (or DBn) of the block - usedDeviceOffset, //Device data address within the block - usedSize, //Set one device-block only - pBuffer //Buffer which contain the data - ); - break; - } case Digital: case Analog: { - errorCode = pConn->writeOutput( + errorCode = pConn->writeIO( theBlock_->getPLC(), usedAddress, //Base address (or DBn) of the block usedDeviceOffset, //Device data address within the block @@ -107,8 +96,9 @@ namespace Silecs ); break; } + case Memory: default: - errorCode = pConn->writeData( + errorCode = pConn->writeMemory( theBlock_->getPLC(), usedAddress, //Base address (or DBn) of the block usedDeviceOffset, //Device data address within the block @@ -151,21 +141,10 @@ namespace Silecs } switch (theBlock_->getAccessArea()) { - case Memory: - { - errorCode = pConn->writeMemory( - theBlock_->getPLC(), - theBlock_->getAddress(), //Base address (or DBn) of the block - 0, //Set all devices from the first one - ((PLCBlock*)theBlock_)->getBufferSize(), //Set blocks of all devices (full buffer size) - (unsigned char*)theBlock_->getBuffer() //Buffer which contain the data (full buffer) - ); - break; - } case Digital: case Analog: { - errorCode = pConn->writeOutput( + errorCode = pConn->writeIO( theBlock_->getPLC(), theBlock_->getAddress(), //Base address (or DBn) of the block 0, //Set all devices from the first one @@ -174,8 +153,9 @@ namespace Silecs ); break; } + case Memory: default: - errorCode = pConn->writeData( + errorCode = pConn->writeMemory( theBlock_->getPLC(), theBlock_->getAddress(), //Base address (or DBn) of the block 0, //Set all devices from the first one @@ -236,21 +216,10 @@ namespace Silecs } switch (theBlock_->getAccessArea()) { - case Memory: - { - errorCode = pConn->writeMemory( - theBlock_->getPLC(), - usedDeviceAddress, //Base address (or DBn) of the device - usedBlockAddress, //Block data address within the device - usedSize, //Set one device-block only - (unsigned char*)theBlock_->getBuffer() //Buffer which contain the data - ); - break; - } case Digital: case Analog: { - errorCode = pConn->writeOutput( + errorCode = pConn->writeIO( theBlock_->getPLC(), usedDeviceAddress, //Base address (or DBn) of the device usedBlockAddress, //Block data address within the device @@ -259,8 +228,9 @@ namespace Silecs ); break; } + case Memory: default: - errorCode = pConn->writeData( + errorCode = pConn->writeMemory( theBlock_->getPLC(), usedDeviceAddress, //Base address (or DBn) of the device usedBlockAddress, //Block data address within the device @@ -300,21 +270,10 @@ namespace Silecs } switch (theBlock_->getAccessArea()) { - case Memory: - { - errorCode = pConn->writeMemory( - theBlock_->getPLC(), - pDev->getAddress(), //Base address (or DBn) of the device - theBlock_->getAddress(), //Block data address within the device - theBlock_->getMemSize(), //Set one device-block only - (unsigned char*)theBlock_->getBuffer() //Buffer which contain the data - ); - break; - } case Digital: case Analog: { - errorCode = pConn->writeOutput( + errorCode = pConn->writeIO( theBlock_->getPLC(), pDev->getAddress(), //Base address (or DBn) of the device theBlock_->getAddress(), //Block data address within the device @@ -323,8 +282,9 @@ namespace Silecs ); break; } + case Memory: default: - errorCode = pConn->writeData( + errorCode = pConn->writeMemory( theBlock_->getPLC(), pDev->getAddress(), //Base address (or DBn) of the device theBlock_->getAddress(), //Block data address within the device