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 08ee03d7e9dd551d6ed8b9991d6d89116c6cb4c8..493a6bd14225672ac052e04830083ab3bb4d27bb 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp @@ -78,14 +78,14 @@ bool MBConnection::close(PLC* thePLC) int MBConnection::mbWriteFrames(modbus_t* ctx, long start_addr, uint16_t count, uint8_t* data) { uint16_t *srcp = (uint16_t*)data; - int word_count, byte_count; + uint16_t word_count, byte_count; while (count) { - word_count = (count > MAX_WRITE_DATA_SIZE) ? MAX_WRITE_DATA_SIZE / 2 : (count / 2) + (count % 2); - byte_count = (word_count * 2); + word_count = static_cast<uint16_t>((count > MAX_WRITE_DATA_SIZE) ? MAX_WRITE_DATA_SIZE / 2 : (count / 2) + (count % 2)); + byte_count = static_cast<uint16_t>(word_count * 2); - if (modbus_write_registers(ctx, start_addr, word_count, srcp) != word_count) + if (modbus_write_registers(ctx, static_cast<int>(start_addr), static_cast<int>(word_count), srcp) != word_count) { return -1; } @@ -93,7 +93,7 @@ int MBConnection::mbWriteFrames(modbus_t* ctx, long start_addr, uint16_t count, //srcp += byte_count-(count%2); srcp += word_count; start_addr += word_count; - count -= (byte_count - (count % 2)); + count = static_cast<uint16_t>(count - (byte_count - (count % 2))); } return 0; @@ -121,7 +121,7 @@ int MBConnection::mbReadFrames(modbus_t* ctx, long start_addr, uint16_t count, u byte_count = (word_count * 2); - if (modbus_read_registers(ctx, start_addr, word_count, destp) != word_count) + if (modbus_read_registers(ctx, static_cast<int>(start_addr), static_cast<int>(word_count), destp) != word_count) { return -1; } @@ -129,7 +129,7 @@ int MBConnection::mbReadFrames(modbus_t* ctx, long start_addr, uint16_t count, u //destp += (byte_count-(count%2)); destp += word_count; start_addr += word_count; - count -= (byte_count - (count % 2)); + count = static_cast<uint16_t>(count - (byte_count - (count % 2))); } return 0; @@ -157,7 +157,7 @@ int MBConnection::readData(PLC* thePLC, long address, unsigned long offset, unsi //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; + long addr = (address + offset) / 2; //DATA topic makes sense with RECV one if (RECV & Log::topics_) @@ -192,7 +192,7 @@ int MBConnection::writeData(PLC* thePLC, long address, unsigned long offset, uns //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; + long addr = (address + offset) / 2; //DATA topic makes sense with SEND one if (SEND & Log::topics_) @@ -251,4 +251,5 @@ bool MBConnection::checkError(PLC* thePLC, int err, bool retry) } // namespace + #endif //MODBUS_SUPPORT_ENABLED diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBHardware.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBHardware.cpp index 35a51cf8283f238ce77c6e6a6416434b38821b97..bf7a8fbb53ca1a8fd3f3c246a3ca07bda03e61f1 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBHardware.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBHardware.cpp @@ -42,14 +42,14 @@ void IeMdbSetTime(unsigned char *dt, time_t epoch) // to PLC Swapping can do it directly during data transferring */ - dt[1] = _tobcd(dscst->tm_sec); + dt[1] = static_cast<char>(_tobcd(dscst->tm_sec)); dt[0] = 0x00; /*not used*/ - dt[3] = _tobcd(dscst->tm_hour); - dt[2] = _tobcd(dscst->tm_min); - dt[5] = _tobcd(dscst->tm_mon+1); - dt[4] = _tobcd(dscst->tm_mday); - dt[7] = _tobcd(2000/100); - dt[6] = _tobcd(dscst->tm_year-100); + dt[3] = static_cast<char>(_tobcd(dscst->tm_hour)); + dt[2] = static_cast<char>(_tobcd(dscst->tm_min)); + dt[5] = static_cast<char>(_tobcd(dscst->tm_mon+1)); + dt[4] = static_cast<char>(_tobcd(dscst->tm_mday)); + dt[7] = static_cast<char>(_tobcd(2000/100)); + dt[6] = static_cast<char>(_tobcd(dscst->tm_year-100)); } /*----------------------------------------------------------*/ @@ -95,4 +95,5 @@ double IeMdbGetTime(unsigned char *dt) // from PLC return((double)plctm + ms); } + #endif //MODBUS_SUPPORT_ENABLED diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Hardware.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Hardware.cpp index a19ef7d4109a45c6332f1ce0ac347d837f4cb2d4..f008e5ba7a465bd2e187b929f00fbe24812cbf4f 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Hardware.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Hardware.cpp @@ -33,12 +33,12 @@ void IeRfcSetTime(unsigned char *dt, time_t epoch) // to PLC dt[7] = 0; // not used at the moment dt[6] = 0; // not used at the moment - dt[5] = _tobcd(dscst->tm_sec); - dt[4] = _tobcd(dscst->tm_min); - dt[3] = _tobcd(dscst->tm_hour); - dt[2] = _tobcd(dscst->tm_mday); - dt[1] = _tobcd(dscst->tm_mon+1); - dt[0] = _tobcd(dscst->tm_year-100); + dt[5] = static_cast<char>(_tobcd(dscst->tm_sec)); + dt[4] = static_cast<char>(_tobcd(dscst->tm_min)); + dt[3] = static_cast<char>(_tobcd(dscst->tm_hour)); + dt[2] = static_cast<char>(_tobcd(dscst->tm_mday)); + dt[1] = static_cast<char>(_tobcd(dscst->tm_mon+1)); + dt[0] = static_cast<char>(_tobcd(dscst->tm_year-100)); } /*----------------------------------------------------------*/ 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 5597a7b0f3cbcbb8b141f356d00771533eb6c313..0dc8956148721e0e3113c7934c8c9ffd3274aabd 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp @@ -116,7 +116,8 @@ namespace Silecs if (isTimeToReconnect()) { - if (isReachable = (ping((char *) thePLC->getName().c_str(), NULL) == 0)) + isReachable = (ping((char *)thePLC->getName().c_str(), NULL) == 0); + if (isReachable) { LOG((COMM|DIAG)) << "It's time to reconnect"; @@ -472,7 +473,7 @@ namespace Silecs /*check any port to detect if the host is OFF*/ rsock.sin_port=htons(102); - if (connect_nonb(s,(struct sockaddr *)(&rsock),sizeof(rsock), ts) == -1) + if (connect_nonb(s,(struct sockaddr *)(&rsock), sizeof(rsock), static_cast<int>(ts)) == -1) { /*if hostname is OFF, connect() fails on TIMEOUT*/ if ((errno == ETIMEDOUT) || (errno == EHOSTDOWN) || (errno == EHOSTUNREACH)) { @@ -506,7 +507,7 @@ namespace Silecs hp = gethostbyname(hostName); if (hp) { - addr.s_addr = *((unsigned long int *) hp->h_addr); + addr.s_addr = static_cast<in_addr_t>(*((unsigned long int *) hp->h_addr)); ipstr = inet_ntoa(addr); } } diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.cpp index d87120f3b163f79d77e22b9b765414d9bc1755b2..207f3c89fc5b47bbe1d37f06ef188104ab563c7c 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.cpp @@ -14,8 +14,6 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #ifdef NI_SUPPORT_ENABLED -#include "CNVBlock.h" - #include <silecs-communication/interface/equipment/SilecsCluster.h> #include <silecs-communication/interface/equipment/SilecsDevice.h> #include <silecs-communication/interface/utility/Thread.h> @@ -30,133 +28,134 @@ #include <silecs-communication/interface/utility/SilecsException.h> #include <silecs-communication/interface/utility/SilecsLog.h> #include <silecs-communication/interface/utility/StringUtilities.h> +#include <silecs-communication/interface/equipment/CNVBlock.h> namespace Silecs { - /* Check for errors */ - void CNVBlock::errChk(int code) - { - if(code != 0) - { - LOG(DEBUG) << "CNV Exception raised: " << std::string(CNVGetErrorDescription(code)); - throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, std::string(CNVGetErrorDescription(code))+" in block "+ name_); - } - } - - //------------------------------------------------------------------------------------------- - //------ CNVBlock - //------------------------------------------------------------------------------------------- - - CNVBlock::CNVBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType): - Block(thePLC, blockNode,accessType) - { - // associate buffer pointer with created buffer - pBuffer_ = (CNVData*)& buffer_; - } - - CNVBlock::~CNVBlock() - { - } - - //------------------------------------------------------------------------------------------- - //------ CNVInputBlock - //------------------------------------------------------------------------------------------- - - CNVInputBlock::CNVInputBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType) : - CNVBlock(thePLC, blockNode, accessType) - { - if (DEBUG & Log::topics_) LOG(ALLOC) << "Block (create): " << name_ << ", CNV: " << getPLC()->getName() << ", access: Input" << ", address: " << address_ << ", mem-size: " << memSize_ ;//<< ", buffer-size: " << bufferSize_; - - handle_ = NULL; - subscriptionFlag_ = false; + /* Check for errors */ + void CNVBlock::errChk(int code) + { + if(code != 0) + { + LOG(DEBUG) << "CNV Exception raised: " << std::string(CNVGetErrorDescription(code)); + throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, std::string(CNVGetErrorDescription(code))+" in block "+ name_); + } + } + + //------------------------------------------------------------------------------------------- + //------ CNVBlock + //------------------------------------------------------------------------------------------- + + CNVBlock::CNVBlock(PLC* thePLC, ElementXML* pDesignEl, AccessType accessType, AccessArea accessArea, std::vector<ElementXML*>* pDesignBlockRegisterElCol): + Block(thePLC, pDesignEl, accessType, accessArea, pDesignBlockRegisterElCol) + { + // associate buffer pointer with created buffer + pBuffer_ = (CNVData*)& buffer_; + } + + CNVBlock::~CNVBlock() + { + } + + //------------------------------------------------------------------------------------------- + //------ CNVInputBlock + //------------------------------------------------------------------------------------------- + + CNVInputBlock::CNVInputBlock(PLC* thePLC, ElementXML* pDesignEl, AccessType accessType, AccessArea accessArea, std::vector<ElementXML*>* pDesignBlockRegisterElCol) : + CNVBlock(thePLC, pDesignEl, accessType, accessArea, pDesignBlockRegisterElCol) + { + if (DEBUG & Log::topics_) LOG(ALLOC) << "Block (create): " << name_ << ", CNV: " << getPLC()->getName() << ", access: Input" << ", hasMaster: " << (hasMasterRegister() ? "yes" : "no") << ", hasSlave: " << (hasSlaveRegister() ? "yes" : "no") << ", address: " << address_ << ", mem-size: " << memSize_ ;//<< ", buffer-size: " << bufferSize_; + + handle_ = NULL; + subscriptionFlag_ = false; // Creates receive task which relies on the block exchange - if (getPLC()->getProtocolModeID() == BlockMode) - pAction_ = new CNVRecvBlockMode(this, name_ + "_" + getPLC()->getName()); - else - pAction_ = new CNVRecvDeviceMode(this, name_ + "_" + getPLC()->getName()); - - WrapperAction wrapperAction(pAction_); - pTask_ = new Task<WrapperAction>(WrapperAction::function, wrapperAction); - } - - CNVInputBlock::~CNVInputBlock() - { - } - - bool CNVInputBlock::doSubscribe() - { - if(!subscriptionFlag_) - { + if (getPLC()->getProtocolModeID() == BlockMode) + pAction_ = new CNVRecvBlockMode(this, name_ + "_" + getPLC()->getName()); + else + pAction_ = new CNVRecvDeviceMode(this, name_ + "_" + getPLC()->getName()); + + WrapperAction wrapperAction(pAction_); + pTask_ = new Task<WrapperAction>(WrapperAction::function, wrapperAction); + } + + CNVInputBlock::~CNVInputBlock() + { + } + + bool CNVInputBlock::doSubscribe() + { + if(!subscriptionFlag_) + { LOG(ALLOC) << "CNVInputBlock::doSubscribe (create-buffer):" << name_ << std::endl; - int numberOfDevice = thePLC_->getDeviceMap().size(); - handle_ = (CNVBufferedSubscriber*)calloc(numberOfDevice,sizeof(CNVBufferedSubscriber)); + int numberOfDevice = static_cast<int>(thePLC_->getDeviceMap().size()); + handle_ = (CNVBufferedSubscriber*)calloc(numberOfDevice,sizeof(CNVBufferedSubscriber)); subscriptionFlag_ = true; //subscription is fine a priori - deviceVectorType::iterator pDeviceIter; - int i=0; - for(pDeviceIter = thePLC_->getDeviceMap().begin(); pDeviceIter != thePLC_->getDeviceMap().end(); ++pDeviceIter) - { - - std::string blockAddress = "\\\\"+thePLC_->getName()+"\\'" - +thePLC_->theCluster_->getClassName()+"-"+thePLC_->theCluster_->getClassVersion()+"'\\" - + pDeviceIter->second->getLabel()+"\\"+name_; - - LOG(DEBUG) << "doSubscribe(): Subscribing to address: " << blockAddress; - - int code = CNVCreateBufferedSubscriber(blockAddress.c_str(), 0 , 0, 2, CNVWaitForever, 0, &handle_[i]); - - if(code != 0) - { LOG(DEBUG) << "doSubscribe(): CNV Exception raised: " << std::string(CNVGetErrorDescription(code)); - unSubscribe(); //dispose subscription resources if any and update subscriptionFlag_ - break; - } - i++; - } - } - return subscriptionFlag_; - } - - void CNVInputBlock::unSubscribe() - { - if(handle_!=NULL) - { - LOG(ALLOC) << "CNVInputBlock::unSubscribe (dispose):" << name_ << std::endl; - - for(unsigned int i=0; i<thePLC_->getDeviceMap().size(); i++) - { + deviceVectorType::iterator pDeviceIter; + int i=0; + for(pDeviceIter = thePLC_->getDeviceMap().begin(); pDeviceIter != thePLC_->getDeviceMap().end(); ++pDeviceIter) + { + + std::string blockAddress = "\\\\"+thePLC_->getName()+"\\'" + +thePLC_->theCluster_->getClassName()+"-"+thePLC_->theCluster_->getClassVersion()+"'\\" + + pDeviceIter->second->getLabel()+"\\"+name_; + + LOG(DEBUG) << "doSubscribe(): Subscribing to address: " << blockAddress; + + int code = CNVCreateBufferedSubscriber(blockAddress.c_str(), 0 , 0, 2, (int)CNVWaitForever, 0, &handle_[i]); + + if(code != 0) + { LOG(DEBUG) << "doSubscribe(): CNV Exception raised: " << std::string(CNVGetErrorDescription(code)); + unSubscribe(); //dispose subscription resources if any and update subscriptionFlag_ + break; + } + i++; + } + } + return subscriptionFlag_; + } + + void CNVInputBlock::unSubscribe() + { + if(handle_!=NULL) + { + LOG(ALLOC) << "CNVInputBlock::unSubscribe (dispose):" << name_ << std::endl; + + for(unsigned int i=0; i<thePLC_->getDeviceMap().size(); i++) + { int code = CNVDispose(handle_[i]); if(code != 0) { LOG(DEBUG) << "unSubscribe(): CNV Exception raised: " << std::string(CNVGetErrorDescription(code)); break; } - } - free(handle_); - handle_ = NULL; - subscriptionFlag_ = false; - } - } - - - CNVBufferedSubscriber* CNVInputBlock::getHandle(std::string deviceName) - { - int i=0; - deviceVectorType::iterator pDeviceIter; - for(pDeviceIter = thePLC_->getDeviceMap().begin(); pDeviceIter != thePLC_->getDeviceMap().end(); ++pDeviceIter) - { - if(pDeviceIter->second->getLabel()==deviceName) - return &handle_[i]; - i++; - } - return NULL; - } - - //------------------------------------------------------------------------------------------- - //------ CNVOutputBlock - //------------------------------------------------------------------------------------------- + } + free(handle_); + handle_ = NULL; + subscriptionFlag_ = false; + } + } + + + CNVBufferedSubscriber* CNVInputBlock::getHandle(std::string deviceName) + { + int i=0; + deviceVectorType::iterator pDeviceIter; + for(pDeviceIter = thePLC_->getDeviceMap().begin(); pDeviceIter != thePLC_->getDeviceMap().end(); ++pDeviceIter) + { + if(pDeviceIter->second->getLabel()==deviceName) + return &handle_[i]; + i++; + } + return NULL; + } + + //------------------------------------------------------------------------------------------- + //------ CNVOutputBlock + //------------------------------------------------------------------------------------------- void CNVOutputBlock::createDataValue(Silecs::Register* regRef, CNVData* builderRef) { if(regRef->isScalar()) @@ -267,81 +266,82 @@ namespace Silecs } } - CNVOutputBlock::CNVOutputBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType) : - CNVBlock(thePLC, blockNode, accessType) - { - if (DEBUG & Log::topics_) LOG(ALLOC) << "Block (create): " << name_ << ", CNV: " << getPLC()->getName() << ", access: Output" << ", address: " << address_ << ", mem-size: " << memSize_;// << ", buffer-size: " << bufferSize_; + CNVOutputBlock::CNVOutputBlock(PLC* thePLC, ElementXML* pDesignEl, AccessType accessType, AccessArea accessArea, std::vector<ElementXML*>* pDesignBlockRegisterElCol) : + CNVBlock(thePLC, pDesignEl, accessType, accessArea, pDesignBlockRegisterElCol) + { + if (DEBUG & Log::topics_) LOG(ALLOC) << "Block (create): " << name_ << ", CNV: " << getPLC()->getName() << ", access: Output" << ", hasMaster: " << (hasMasterRegister() ? "yes" : "no") << ", hasSlave: " << (hasSlaveRegister() ? "yes" : "no") << ", address: " << address_ << ", mem-size: " << memSize_;// << ", buffer-size: " << bufferSize_; - /* ALLOCATE THE BUFFER */ - deviceVectorType deviceCol = thePLC->getDeviceMap(); - Device* currentDev = deviceCol[0].second; - std::vector<Register*> regCol = currentDev->getRegisterCollection(name_); + /* ALLOCATE THE BUFFER */ + deviceVectorType deviceCol = thePLC->getDeviceMap(); + Device* currentDev = deviceCol[0].second; + std::vector<Register*> regCol = currentDev->getRegisterCollection(name_); - //Allocate the CNVStruct for the buffer - int numberOfReg = regCol.size(); + //Allocate the CNVStruct for the buffer + int numberOfReg = static_cast<int>(regCol.size()); CNVData *structBuilder = (CNVData*)calloc(numberOfReg,sizeof(CNVData)); //allocate space for number of register in the block // Creates send task which relies on the block exchange - if (getPLC()->getProtocolModeID() == BlockMode) - { - // ALLOCATE A OUTPUT BLOCK IN BLOCK MODE - int numberOfDevice = thePLC->getDeviceMap().size(); - - CNVData *arrayBuilder = (CNVData*)calloc(numberOfDevice,sizeof(CNVData)*numberOfReg); //allocate space for number of device in the device array - - for(int j=0;j<numberOfDevice;j++) - { - // for each register in the current block - for(int i=0;i<numberOfReg;i++) - { - createDataValue(regCol[i], &structBuilder[i]); - } - - errChk(CNVCreateStructDataValue (&arrayBuilder[j], // data handler - structBuilder, // input structure - numberOfReg)); // number of fields - } - - long unsigned int dimensions[1] = {numberOfDevice}; - errChk(CNVCreateArrayDataValue (&buffer_, // data handler - CNVStruct, // array type - arrayBuilder, // input array - 1, // mono-dimensional array - dimensions)); // array length - - pAction_ = new CNVSendBlockMode(this, name_ + "_" + getPLC()->getName()); - - free(arrayBuilder); - } - else - { - // ALLOCATE A OUTPUT BLOCK IN DEVICE MODE - // for each register in the current block - for(int i=0;i<numberOfReg;i++) - { + if (getPLC()->getProtocolModeID() == BlockMode) + { + // ALLOCATE A OUTPUT BLOCK IN BLOCK MODE + int numberOfDevice = static_cast<int>(thePLC->getDeviceMap().size()); + + CNVData *arrayBuilder = (CNVData*)calloc(numberOfDevice,sizeof(CNVData)*numberOfReg); //allocate space for number of device in the device array + + for(int j=0;j<numberOfDevice;j++) + { + // for each register in the current block + for(int i=0;i<numberOfReg;i++) + { + createDataValue(regCol[i], &structBuilder[i]); + } + + errChk(CNVCreateStructDataValue (&arrayBuilder[j], // data handler + structBuilder, // input structure + numberOfReg)); // number of fields + } + + long unsigned int dimensions[1] = {numberOfDevice}; + errChk(CNVCreateArrayDataValue (&buffer_, // data handler + CNVStruct, // array type + arrayBuilder, // input array + 1, // mono-dimensional array + dimensions)); // array length + + pAction_ = new CNVSendBlockMode(this, name_ + "_" + getPLC()->getName()); + + free(arrayBuilder); + } + else + { + // ALLOCATE A OUTPUT BLOCK IN DEVICE MODE + // for each register in the current block + for(int i=0;i<numberOfReg;i++) + { createDataValue(regCol[i], &structBuilder[i]); - } - errChk(CNVCreateStructDataValue (&buffer_, // data handler - structBuilder, // input structure - numberOfReg)); // number of fields + } + errChk(CNVCreateStructDataValue (&buffer_, // data handler + structBuilder, // input structure + numberOfReg)); // number of fields - pAction_ = new CNVSendDeviceMode(this, name_ + "_" + getPLC()->getName()); - } + pAction_ = new CNVSendDeviceMode(this, name_ + "_" + getPLC()->getName()); + } for(int i=0;i<numberOfReg;i++) // TO check if works CNVDisposeData(structBuilder[i]); free(structBuilder); - WrapperAction wrapperAction(pAction_); - pTask_ = new Task<WrapperAction>(WrapperAction::function, wrapperAction); - } + WrapperAction wrapperAction(pAction_); + pTask_ = new Task<WrapperAction>(WrapperAction::function, wrapperAction); + } - CNVOutputBlock::~CNVOutputBlock() - { - if (DEBUG & Log::topics_) LOG(ALLOC) << "CNVOutputBlock (delete): " << name_; + CNVOutputBlock::~CNVOutputBlock() + { + if (DEBUG & Log::topics_) LOG(ALLOC) << "CNVOutputBlock (delete): " << name_; - CNVDisposeData(*((CNVData*)pBuffer_)); - } + CNVDisposeData(*((CNVData*)pBuffer_)); + } } + #endif //NI_SUPPORT_ENABLED diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.cpp index c7c0b8a4bf3e5fd9e096ccf601a329909e53c17f..fd9eb806ec3efc2a63959adfdfff7198ff4ee53a 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.cpp @@ -18,26 +18,26 @@ namespace Silecs { - // Constructor from super class - CNVRegister::CNVRegister(Device* theDevice, ElementXML* pDesignEl) : Register(theDevice, pDesignEl) - { - } - - // Specialized Destructor - CNVRegister::~CNVRegister() - { - - } - - /* Check for errors */ - void CNVRegister::errChk(int code) - { - if(code != 0) - { - LOG(DEBUG) << "CNV Exception raised: " << CNVGetErrorDescription(code); - throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, std::string(CNVGetErrorDescription(code))+" in register "+ name_); - } - } + // Constructor from super class + CNVRegister::CNVRegister(Device* theDevice, ElementXML* pDesignEl) : Register(theDevice, pDesignEl) + { + } + + // Specialized Destructor + CNVRegister::~CNVRegister() + { + + } + + /* Check for errors */ + void CNVRegister::errChk(int code) + { + if(code != 0) + { + LOG(DEBUG) << "CNV Exception raised: " << CNVGetErrorDescription(code); + throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, std::string(CNVGetErrorDescription(code))+" in register "+ name_); + } + } template <typename T> inline void CNVRegister::swapInputArray2D(FormatType F, uint32_t dim1, uint32_t dim2) @@ -105,94 +105,94 @@ namespace Silecs void CNVRegister::swapOutputFloat64Array2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<double>(Float64, dim1, dim2); } void CNVRegister::swapOutputDateArray2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<double>(Date, dim1, dim2); } - void CNVRegister::setRegIntoStructBuffer(CNVData *buffer,int bufferSize, CNVData reg, int regOffset) - { - - CNVData *temp = (CNVData*)calloc(bufferSize,sizeof(CNVData)); - try{ - // split struct into fields - errChk(CNVGetStructFields (*buffer,temp,bufferSize)); - - // Dispose the single value that will be replaced - errChk(CNVDisposeData(temp[regOffset])); - - // substitute value inside the appropriated field - temp[regOffset] = reg; - - // re-packs up the struct - errChk(CNVSetStructDataValue(*buffer,temp,bufferSize)); - } - catch (const SilecsException& ex) - { - // Cleanup before forwarding the exception - for(int i=0;i<bufferSize;i++) - CNVDisposeData(temp[i]); - free(temp); - throw; - } - // Dispose the temporary CNV data - for(int i=0;i<bufferSize;i++) - CNVDisposeData(temp[i]); - // Free the pointer - free(temp); - } - - - CNVData CNVRegister::getRegfromStructBuffer(CNVData buffer,int bufferSize, int regOffset) - { - - CNVData *allFields = (CNVData*)calloc(bufferSize,sizeof(CNVData)); - CNVData returnValue; - try{ - // split struct into fields - errChk(CNVGetStructFields(buffer,allFields,bufferSize)); - - returnValue = allFields[regOffset]; - } - catch (const SilecsException& ex) - { - // Cleanup before forwarding the exception - for(int i=0;i<bufferSize;i++) - if(i!=regOffset) - errChk(CNVDisposeData(allFields[i])); - free(allFields); - throw; - } - - for(int i=0;i<bufferSize;i++) - if(i!=regOffset) - errChk(CNVDisposeData(allFields[i])); - - free(allFields); - // return the researched index - return returnValue; - } - - void CNVRegister::importValue(void* pBuffer, timeval ts) - { - LOG(DEBUG) << "CNVRegister::importValue Reg " << name_ << " dim1: " << dimension1_ << " dim2: " << dimension2_; - - unsigned long structBufferSize = this->getDevice()->getRegisterCollection(this->getBlockName()).size(); - - CNVData regContent; // will contain the register value in a CNVData format. + void CNVRegister::setRegIntoStructBuffer(CNVData *buffer,int bufferSize, CNVData reg, int regOffset) + { + + CNVData *temp = (CNVData*)calloc(bufferSize,sizeof(CNVData)); + try{ + // split struct into fields + errChk(CNVGetStructFields (*buffer,temp,bufferSize)); + + // Dispose the single value that will be replaced + errChk(CNVDisposeData(temp[regOffset])); + + // substitute value inside the appropriated field + temp[regOffset] = reg; + + // re-packs up the struct + errChk(CNVSetStructDataValue(*buffer,temp,bufferSize)); + } + catch (const SilecsException& ex) + { + // Cleanup before forwarding the exception + for(int i=0;i<bufferSize;i++) + CNVDisposeData(temp[i]); + free(temp); + throw; + } + // Dispose the temporary CNV data + for(int i=0;i<bufferSize;i++) + CNVDisposeData(temp[i]); + // Free the pointer + free(temp); + } + + + CNVData CNVRegister::getRegfromStructBuffer(CNVData buffer,int bufferSize, int regOffset) + { + + CNVData *allFields = (CNVData*)calloc(bufferSize,sizeof(CNVData)); + CNVData returnValue; + try{ + // split struct into fields + errChk(CNVGetStructFields(buffer,allFields,bufferSize)); + + returnValue = allFields[regOffset]; + } + catch (const SilecsException& ex) + { + // Cleanup before forwarding the exception + for(int i=0;i<bufferSize;i++) + if(i!=regOffset) + errChk(CNVDisposeData(allFields[i])); + free(allFields); + throw; + } + + for(int i=0;i<bufferSize;i++) + if(i!=regOffset) + errChk(CNVDisposeData(allFields[i])); + + free(allFields); + // return the researched index + return returnValue; + } + + void CNVRegister::importValue(void* pBuffer, timeval ts) + { + LOG(DEBUG) << "CNVRegister::importValue Reg " << name_ << " dim1: " << dimension1_ << " dim2: " << dimension2_; + + unsigned long structBufferSize = this->getDevice()->getRegisterCollection(this->getBlockName()).size(); + + CNVData regContent; // will contain the register value in a CNVData format. if (this->getDevice()->getPLC()->getProtocolModeID()==DeviceMode) - { - // DEVICE MODE { BlockStruct.reg(1-n) } - regContent = getRegfromStructBuffer((CNVData)(*(CNVData*) pBuffer), structBufferSize, address_); - } - else - { - // BLOCK MODE { Device[BlockStruct.reg(1-n)] } - LOG(ERROR) << "Block mode not supported for shared variables."; - throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, "Block mode not supported for shared variables. Error in register "+ name_); - } - - if( dimension2_ == 1) // scalar or 1d array - { - if( dimension1_== 1 ) // the register contains a scalar - { - // extract the register out of the struct + { + // DEVICE MODE { BlockStruct.reg(1-n) } + regContent = getRegfromStructBuffer((CNVData)(*(CNVData*) pBuffer), static_cast<int>(structBufferSize), static_cast<int>(address_)); + } + else + { + // BLOCK MODE { Device[BlockStruct.reg(1-n)] } + LOG(ERROR) << "Block mode not supported for shared variables."; + throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, "Block mode not supported for shared variables. Error in register "+ name_); + } + + if( dimension2_ == 1) // scalar or 1d array + { + if( dimension1_== 1 ) // the register contains a scalar + { + // extract the register out of the struct switch(format_) { case uInt8: { errChk(CNVGetScalarDataValue(regContent, CNVUInt8, pRecvValue_)); break; } @@ -606,7 +606,7 @@ namespace Silecs if (this->getDevice()->getPLC()->getProtocolModeID()==DeviceMode) { // DEVICE MODE { BlockStruct.reg(1-n) } - setRegIntoStructBuffer((CNVData*) pBuffer,structBufferSize, regContent, address_); + setRegIntoStructBuffer((CNVData*) pBuffer, static_cast<int>(structBufferSize), regContent, static_cast<int>(address_)); } else { @@ -626,7 +626,7 @@ namespace Silecs if (this->getDevice()->getPLC()->getProtocolModeID()==DeviceMode) { // DEVICE MODE { BlockStruct.reg(1-n) } - regContent = getRegfromStructBuffer((CNVData)(*(CNVData*) pBuffer), structBufferSize, address_); + regContent = getRegfromStructBuffer((CNVData)(*(CNVData*) pBuffer), static_cast<int>(structBufferSize), static_cast<int>(address_)); } else { @@ -750,7 +750,7 @@ namespace Silecs if (this->getDevice()->getPLC()->getProtocolModeID()==DeviceMode) { // DEVICE MODE { BlockStruct.reg(1-n) } - setRegIntoStructBuffer((CNVData*) pBuffer,structBufferSize, regContent, address_); + setRegIntoStructBuffer((CNVData*) pBuffer, static_cast<int>(structBufferSize), regContent, static_cast<int>(address_)); } else { @@ -781,4 +781,5 @@ namespace Silecs } } } + #endif //NI_SUPPORT_ENABLED diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp index f576e8b1e414b3e1d97f81bc2d57055c9e8bdc6d..5037f289bbe48b9bc1def024e08e3a0242ad0ff0 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp @@ -42,7 +42,7 @@ namespace Silecs /// Generic methods for byte-swapping ---------------------------------------------- uint16_t PLCRegister::_swaps(uint16_t s) { - return ( ((s & 0x00ff) << 8) + ((s & 0xff00) >> 8) ); + return static_cast<uint16_t>( ((s & 0x00ff) << 8) + ((s & 0xff00) >> 8) ); } uint32_t PLCRegister::_swapl(uint32_t l) @@ -252,7 +252,7 @@ namespace Silecs if ((format_ == Int8) || (format_ == uInt8)) { //Some PLC use more than 1 byte for this format (exp.: SCHNEIDER aligns char on 16bits) - unsigned int step = memSize_ / dimension1_ / dimension2_ / size_; + unsigned int step = static_cast<unsigned int>(memSize_ / dimension1_ / dimension2_ / size_); /*TODO: * Optimization a tester: utiliser un memcpy si (step == 1) au lieu du for * (idem pour l'export) @@ -337,7 +337,7 @@ namespace Silecs if ((format_ == Int8) || (format_ == uInt8)) { //Some PLC use more than 1 byte for this format (exp.: SCHNEIDER aligns char on 16bits) - unsigned int step = memSize_ / dimension1_ / dimension2_ / size_; + unsigned int step = static_cast<unsigned int>(memSize_ / dimension1_ / dimension2_ / size_); for (unsigned int i=0; i<dimension1_; i++) { @@ -427,7 +427,7 @@ namespace Silecs std::string** pRecvStringValue_ = static_cast<std::string**>(pRecvValue_); //Some PLC use more than 1 byte for this format (exp.: SIEMENS aligns string on 16bits address) - unsigned int step = memSize_ / dimension1_ / dimension2_ / size_; + unsigned int step = static_cast<unsigned int>(memSize_ / dimension1_ / dimension2_ / size_); // for each string of the single/double array - for (unsigned long i=0; i<(dimension1_*dimension2_); i++) // scalar has dim1=dim2=1 @@ -451,7 +451,7 @@ namespace Silecs std::string** pSendStringValue_ = static_cast<std::string**>(pSendValue_); //Some PLC use more than 1 byte for this format (exp.: SIEMENS aligns string on 16bits address) - unsigned int step = memSize_ / dimension1_ / dimension2_ / size_; + unsigned int step = static_cast<unsigned int>(memSize_ / dimension1_ / dimension2_ / size_); // for each string of the single/double array - for (unsigned long i=0; i<dimension1_*dimension2_; i++) // scalar has dim1=dim2=1 @@ -474,7 +474,7 @@ namespace Silecs std::string** pRecvStringValue_ = static_cast<std::string**>(pRecvValue_); //Some PLC use more than 1 byte for this format (exp.: SCHNEIDER aligns char on 16bits) - unsigned int step = memSize_ / dimension1_ / dimension2_ / size_; + unsigned int step = static_cast<unsigned int>(memSize_ / dimension1_ / dimension2_ / size_); // for each string of the single/double array - for (unsigned long i=0; i<(dimension1_*dimension2_); i++) // scalar has dim1=dim2=1 @@ -498,7 +498,7 @@ namespace Silecs std::string** pSendStringValue_ = static_cast<std::string**>(pSendValue_); // Some PLC use more than 1 byte for this format (exp.: SCHNEIDER aligns char on 16bits) - unsigned int step = memSize_ / dimension1_ / dimension2_ / size_; + unsigned int step = static_cast<unsigned int>(memSize_ / dimension1_ / dimension2_ / size_); // for each string of the single/double array - for (unsigned long i=0; i<dimension1_*dimension2_; i++) // scalar has dim1=dim2=1 diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp index eb2c96bed8dc8450a5db1cc17a352d6e78c69b67..8b37e63dcee54327ff40fbf4e25b857034fcb5f3 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp @@ -38,10 +38,21 @@ namespace Silecs // Update Device ElementXML attributes label_ = deviceNode.getAttribute("label"); StringUtilities::fromString(address_,deviceNode.getAttribute("address") ); - StringUtilities::fromString(ai_address_,deviceNode.getAttribute("AI-address") ); - StringUtilities::fromString(ao_address_,deviceNode.getAttribute("AO-address") ); - StringUtilities::fromString(di_address_,deviceNode.getAttribute("DI-address") ); - StringUtilities::fromString(do_address_,deviceNode.getAttribute("DO-address") ); + + //For backward compatibility reason, IO addresses could be undefined. + //It will be initialized to (-1) by default. + ai_address_ = -1; + ao_address_ = -1; + di_address_ = -1; + do_address_ = -1; + if(deviceNode.hasAttribute("AI-address")) + StringUtilities::fromString(ai_address_,deviceNode.getAttribute("AI-address") ); + if(deviceNode.hasAttribute("AO-address")) + StringUtilities::fromString(ao_address_,deviceNode.getAttribute("AO-address") ); + if(deviceNode.hasAttribute("DI-address")) + StringUtilities::fromString(di_address_,deviceNode.getAttribute("DI-address") ); + if(deviceNode.hasAttribute("DO-address")) + StringUtilities::fromString(do_address_,deviceNode.getAttribute("DO-address") ); LOG(ALLOC) << "Creating SilecsDevice: " << label_; diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp index 6831c73ba0d29e02d8427ea3329767b83f20a30b..d3d40ea13f03dcf3a0bae1e0fb0b07ef80c82835 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp @@ -481,8 +481,8 @@ namespace Silecs if (dimension1_ != dim) throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName()); // conversion from Type-source to Type-destination - for(unsigned long i=0; i<dimension1_; i++) - ((Tdst*)pSendValue_)[i] = pVal[i]; + for(unsigned long i=0; i<dimension1_; i++) + static_cast<Tdst*>(pSendValue_)[i] = static_cast<Tdst>(pVal[i]); isInitialized_ = true; //the register value has been set once at least } @@ -497,7 +497,7 @@ namespace Silecs throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName()); // conversion from Type-source to Type-destination for(unsigned long i=0; i<(dimension1_*dimension2_); i++) - ((Tdst*)pSendValue_)[i] = ((Tsrc*)pVal)[i]; + static_cast<Tdst*>(pSendValue_)[i] = static_cast<Tdst>(pVal[i]); isInitialized_ = true; //the register value has been set once at least } @@ -647,7 +647,7 @@ namespace Silecs unsigned long Register::getDimension(uint16_t whichDim) { return ((whichDim == 2) ? dimension2_ : dimension1_); } uint32_t Register::getDimension1() { return dimension1_; } uint32_t Register::getDimension2() { return dimension2_; } - uint32_t Register::getLength() {return length_; } + uint32_t Register::getLength() {return static_cast<uint32_t>(length_); }; FormatType Register::getFormat() { return format_; } std::string Register::getBlockName() { return blockName_; } std::string Register::getFormatAsString() { return FormatTypeString[format_]; } @@ -775,7 +775,7 @@ namespace Silecs for (unsigned int i=0; i<nbLoop; i++) { if ((i==maxSize) && (nbLoop > 2*maxSize)) - { i = nbLoop - maxSize; + { i = static_cast<unsigned int>(nbLoop - maxSize); os << ".... "; } diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsException.cpp b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsException.cpp index 82d05084b4d30b5c48995219191a70011763f595..54f3747c1ed3e2ba6aa56cdeb12fea868b3dd94e 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsException.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsException.cpp @@ -129,7 +129,7 @@ namespace Silecs break; case XML_ATTRIBUTE_NOT_FOUND: errCategory_ = XML_PARSING_FAULT; - errMessage_ = "XML Attribute not found within the parameters file."; + errMessage_ = "XML Attribute not found."; break; case XML_DATA_NOT_CONSISTENT: errCategory_ = XML_PARSING_FAULT; diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.cpp b/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.cpp index 2dbcffce08d99754af5902cc543fc8076bd0e183..f4503b85a6e4f49c80a0c06565c2d7b46b1fcdf9 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.cpp @@ -112,9 +112,9 @@ namespace Silecs void StringUtilities::toLower(std::string& str) { //cannot used std::transform() method because of ppc4 support! - for(unsigned int i=0;i<str.length();i++) - { str[i] = tolower(str[i]); - } + for(unsigned int i=0;i<str.length();i++) + { str[i] = static_cast<char>(tolower(str[i])); + } } } // namespace diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/TimeStamp.h b/silecs-communication-cpp/src/silecs-communication/interface/utility/TimeStamp.h index 2eaf76cc634afa6f2cd6992be2f9d5f52f321629..51e968a255222feb5732f91d523c320c26e6f104 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/utility/TimeStamp.h +++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/TimeStamp.h @@ -76,7 +76,7 @@ namespace Silecs { double getTimeOfDay(double unit) { timeval lCurrent; ::gettimeofday(&lCurrent, 0); - return (double)((lCurrent.tv_sec*YS_UNIT + lCurrent.tv_usec)*(unit/YS_UNIT)); + return ((static_cast<double>(lCurrent.tv_sec)*YS_UNIT + static_cast<double>(lCurrent.tv_usec))*(unit/YS_UNIT)); } protected: