|
- #include "ModbusBackend.h"
- #include "QBuffer"
-
-
- CModbusBackend::CModbusBackend(CModbusRepository *Repo)
- {
- mModbusTCPSocketHandle = 0;
- mDataLinkValid = false;
- mModbusRepo = Repo;
- mModbusMode = MODBUS_INVALID_MODE;
- mTransactionIDCounter = 0;
- mDeviceID = 1;//0xFF;
-
- mModbusMaxRetry = MODBUS_RETRY_MAX_COUNT;
- mModbusRequestTimeout = MODBUS_RETRY_DELAY;
- }
-
- CModbusBackend::~CModbusBackend()
- {
-
- }
-
- void CModbusBackend::ModbusDataReady()
- {
-
- CModbusTransaction Transaction;
- QByteArray InData = mModbusTCPSocketHandle->readAll();
-
- QBuffer FileBuffer(&InData);
- FileBuffer.open(QIODevice::ReadOnly);
- FileBuffer.seek(0);
- QDataStream *TransactionDataStrm = new QDataStream(&FileBuffer);
- *TransactionDataStrm >> Transaction.mHeader;
- *TransactionDataStrm >> Transaction.mPDU.mFunctionCode;
- Transaction.mPDU.mData = InData.right(Transaction.mHeader.mMessageLength - 2); //-2 to remove Device ID and Function Code.
-
- // qDebug("modbus data received %s",InData.toHex().data());
- // qDebug("Transaction ID 0x%X",Transaction.mHeader.mTransactionID);
- // qDebug("Message Length %d",Transaction.mHeader.mMessageLength);
- // qDebug("Protocol ID 0x%X",Transaction.mHeader.mProtocolID);
- // qDebug("Unit ID 0x%X",Transaction.mHeader.mUnitID);
-
- // qDebug("Function Code 0x%X",Transaction.mPDU.mFunctionCode);
- // qDebug("Data %s",Transaction.mPDU.mData.toHex().data());
-
- if(mModbusMode == MODBUS_MASTER_MODE)
- {
- AnalyzeModbusResponse(Transaction);
- }
- else if( mModbusMode == MODBUS_SLAVE_MODE)
- {
- AnalyzeModbusRequest(Transaction);
- }
- else
- {
- qDebug("Illegal modbus backend mode...");
- }
-
- emit ModbusRX();
- }
-
- void CModbusBackend::ModbusLinkDisconnected()
- {
- qDebug("Modbus link disconnected");
- mDataLinkValid = false;
- }
-
-
- //In client mode. This is the request from the master.
- int CModbusBackend::AnalyzeModbusRequest(CModbusTransaction Transaction)
- {
- if(Transaction.mHeader.mProtocolID != 0)
- {
- //Invalid protocol... what can we do?
- return 0;
- }
-
- switch(Transaction.mPDU.mFunctionCode)
- {
- case MODBUS_FCT_READ_HOLDING_REGISTERS:
- {
- bool ok = true;
- unsigned short StartAdress = 0;
- StartAdress = Transaction.mPDU.mData[0]&0xFF;
- StartAdress <<= 8;
- StartAdress += Transaction.mPDU.mData[1]&0xFF;
- unsigned short NbRegisters = 0;
- NbRegisters = Transaction.mPDU.mData[2]&0xFF;
- NbRegisters <<= 8;
- NbRegisters += Transaction.mPDU.mData[3]&0xFF;
-
- //Validate nb of registers
- if(NbRegisters < 1 || NbRegisters > MODBUS_MAX_NB_REGISTERS)
- {
- SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE);
- // emit ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_READ_HOLDING_REGISTERS);
- ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_READ_HOLDING_REGISTERS);
- return 0;
- }
-
- //Validate data range
- if(!mModbusRepo->IsHRValid(StartAdress,NbRegisters))
- {
- qDebug("Reg invalid");
- //Send negative response
- SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
- // emit ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,MODBUS_FCT_READ_HOLDING_REGISTERS);
- ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,MODBUS_FCT_READ_HOLDING_REGISTERS);
- return 0;
- }
-
- QByteArray data = mModbusRepo->GetHRData(StartAdress,NbRegisters,&ok);
-
- // qDebug("Slave Rx Read Holding Registers. Address: %d, Nb Reg: %d",StartAdress, NbRegisters);
- // qDebug("Data: %s",data.toHex().data());
-
- //The response to a HR reading needs the byte count before the data.
- quint8 ByteCount = data.size();
- data.prepend(ByteCount);
- SendModbusResponse(Transaction, data);
-
- //All OK
-
- break;
- }
- case MODBUS_WRITE_SINGLE_REGISTER:
- {
- unsigned short StartAdress = 0;
-
- StartAdress = Transaction.mPDU.mData[0]&0xFF;
- StartAdress <<= 8;
- StartAdress += Transaction.mPDU.mData[1]&0xFF;
-
- //Validate data range
- if(!mModbusRepo->IsHRValid(StartAdress,1))
- {
- qDebug("Reg invalid");
- //Send negative response
- SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
- // emit ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,MODBUS_WRITE_SINGLE_REGISTER);
- ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,MODBUS_WRITE_SINGLE_REGISTER);
- return 0;
- }
-
- //Extract data.
- QByteArray data = Transaction.mPDU.mData.right(2);
-
- //Write register data
- mModbusRepo->WriteHRData(StartAdress,1,data);
-
- // qDebug("Slave Rx Write Single Register. Address: %d, Value: 0x%s",StartAdress, data.toHex().data());
- // qDebug("Data: %s",data.toHex().data());
-
- data = Transaction.mPDU.mData.left(4); //The response corresponds to the Reg. Address & the value. Which is the first 4 bytes of the initial request.
- SendModbusResponse(Transaction, data);
- // emit RegistersDatabaseUpdated(StartAdress,1);
- RegistersDatabaseUpdated(StartAdress,1);
-
- break;
- }
- case MODBUS_FCT_WRITE_MULTIPLE_REGISTERS:
- {
- unsigned short StartAdress = 0;
- StartAdress = Transaction.mPDU.mData[0]&0xFF;
- StartAdress <<= 8;
- StartAdress += Transaction.mPDU.mData[1]&0xFF;
-
- unsigned short NbRegisters = 0;
- NbRegisters = Transaction.mPDU.mData[2]&0xFF;
- NbRegisters <<= 8;
- NbRegisters += Transaction.mPDU.mData[3]&0xFF;
-
- quint8 ByteCount = Transaction.mPDU.mData[4];
-
- //Validate nb of registers
- if(NbRegisters < 1 || NbRegisters > 0x7D || ByteCount != (NbRegisters*2))
- {
- qDebug("Invalid register number or byte count ");
- SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE);
- // emit ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS);
- ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS);
- return 0;
- }
-
- //Validate data range
- if(!mModbusRepo->IsHRValid(StartAdress,NbRegisters))
- {
- qDebug("Reg invalid");
- //Send negative response
- SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
- // emit ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS);
- ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS);
- return 0;
- }
-
- //Extract data.
- QByteArray data = Transaction.mPDU.mData.right(ByteCount);
-
- //Write register data
- mModbusRepo->WriteHRData(StartAdress,NbRegisters,data);
-
- // qDebug("Slave Rx Write Multiple Registers. Address: %d, Nb Reg: %d",StartAdress, NbRegisters);
- // qDebug("Data: %s",data.toHex().data());
-
- data = Transaction.mPDU.mData.left(4); //The response corresponds to the Start Adress and Nb of Regs. Which is the first 4 bytes of the initial request.
- SendModbusResponse(Transaction, data);
-
- // emit RegistersDatabaseUpdated(StartAdress,NbRegisters);
- RegistersDatabaseUpdated(StartAdress,NbRegisters);
-
- break;
- }
- default:
- {
- //Received "Illegal function code". Send the exception code to master
- //TODO: Log this.
- qDebug("Slave received illegal function code from master: 0x%x",Transaction.mPDU.mFunctionCode);
- SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_FCT);
- // emit ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_FCT,Transaction.mPDU.mFunctionCode);
- ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_FCT,Transaction.mPDU.mFunctionCode);
- break;
- }
- }
-
-
- return 1;
- }
-
- int CModbusBackend::SendModbusResponse(CModbusTransaction RequestTransaction, QByteArray Data)
- {
- QByteArray ModbusPacket;
-
- QBuffer Buffer(&ModbusPacket);
- Buffer.open(QIODevice::WriteOnly|QIODevice::Unbuffered);
- Buffer.seek(0);
- QDataStream *PacketDataStrm = new QDataStream(&Buffer);
-
- //For a response, the header will be the same as the original request, except for the msg. length.
- //Set the appropriate msg length.
- RequestTransaction.mHeader.mMessageLength = Data.size() + 2; //+2 to add function code & Unit ID.
- RequestTransaction.mPDU.mData = Data;
-
- *PacketDataStrm << RequestTransaction.mHeader;
- *PacketDataStrm << RequestTransaction.mPDU.mFunctionCode;
- Buffer.close();
- ModbusPacket.append(Data);
-
-
- qDebug("Response packet: %s",ModbusPacket.toHex().data());
-
- mModbusTCPSocketHandle->write(ModbusPacket);
-
- delete PacketDataStrm;
-
- return RET_OK;
- }
-
- //In Master mode. This is the response from slave to a previously sent request.
- int CModbusBackend::AnalyzeModbusResponse(CModbusTransaction Transaction)
- {
- if(Transaction.mHeader.mProtocolID != 0)
- {
- //Invalid protocol... what can we do?
- return RET_ERROR;
- }
-
- //Find matching request and remove it from the queue...
- CModbusRequest *Request;
- bool Found = false;
- for(int i = 0; i < mRequestsList.size(); i++)
- {
- if(mRequestsList.at(i)->mHeader.mTransactionID == Transaction.mHeader.mTransactionID)
- {
- Request = mRequestsList.takeAt(i); //Remove from queue and keep a copy
- Request->mRequestTimer->stop(); //Stop the resend timer
- Found = true;
- }
- }
-
- if(Found == false)
- {
- //Invalid request number. This should happen only if a very long delay exists in the comm.
- //TODO: Log this...
- qDebug("Master received response to a non existent request!!!");
- return RET_ERROR;
- }
-
- //check if we have an exception response
- if((Transaction.mPDU.mFunctionCode & MODBUS_EXCEPTION_FCT_MASK) != 0)
- {
- //we have an exception response... something went wrong.
- quint8 ExceptionCode = Transaction.mPDU.mData[0];
-
- //TODO: Manage this!
- qDebug("Master Rx exception code %d to request %d",ExceptionCode,Request->mPDU.mFunctionCode);
- emit ModbusResponseException(ExceptionCode,Request->mPDU.mFunctionCode);
- delete Request;
- return RET_ERROR;
- }
-
- switch(Transaction.mPDU.mFunctionCode)
- {
- case MODBUS_FCT_READ_HOLDING_REGISTERS:
- {
- quint8 ByteCount = 0;
- ByteCount = Transaction.mPDU.mData.at(0);
-
- if((Request->mNbRegisters*2) != ByteCount)
- {
- //Inconsistency between the data range and the data count.
- //TODO: Log the error.
- qDebug("Master eceived a wrong data size in response for a MODBUS_FCT_READ_HOLDING_REGISTERS request");
- emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_READ_HOLDING_REGISTERS);
- delete Request;
- return RET_ERROR;
- }
-
- QByteArray RegisterValues = Transaction.mPDU.mData.right(ByteCount);
-
-
- // qDebug("Master Rx Read Holding Registers Response.");
- // qDebug("Data: %s",RegisterValues.toHex().data());
-
- mModbusRepo->WriteHRData(Request->mStartAddress,Request->mNbRegisters,RegisterValues);
- RegistersDatabaseUpdated(Request->mStartAddress, Request->mNbRegisters);
-
- break;
- }
- case MODBUS_WRITE_SINGLE_REGISTER:
- {
- quint16 RegAddress = 0;
- RegAddress = Transaction.mPDU.mData[0]&0xFF;
- RegAddress <<= 8;
- RegAddress += Transaction.mPDU.mData[1]&0xFF;
-
- if(Request->mStartAddress != RegAddress)
- {
- //Inconsistency between the request Adress and response Adress.
- //TODO: Log the error.
- qDebug("Master received a wrong Register Adress in response for a MODBUS_WRITE_SINGLE_REGISTER request. Expected [%d], Rx[%d]",Request->mStartAddress, RegAddress);
- emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_WRITE_SINGLE_REGISTER);
- delete Request;
- return RET_ERROR;
- }
- // qDebug("Master Rx Write Single Register response. Address: %d,",RegAddress);
- // qDebug("Data: %s",Transaction.mPDU.mData.toHex().data());
-
- //Everything seems good.
-
- break;
- }
- case MODBUS_FCT_WRITE_MULTIPLE_REGISTERS:
- {
- unsigned short StartAdress = 0;
- StartAdress = Transaction.mPDU.mData[0]&0xFF;
- StartAdress <<= 8;
- StartAdress += Transaction.mPDU.mData[1]&0xFF;
-
- unsigned short NbRegisters = 0;
- NbRegisters = Transaction.mPDU.mData[2]&0xFF;
- NbRegisters <<= 8;
- NbRegisters += Transaction.mPDU.mData[3]&0xFF;
-
- if(StartAdress != Request->mStartAddress || NbRegisters != Request->mNbRegisters)
- {
- //Inconsistency between the request Adress or NbRegisters and response.
- //TODO: Log the error.
- qDebug("Master Received a wrong Register Adress or NbRegisters in response for a MODBUS_FCT_WRITE_MULTIPLE_REGISTERS request");
- emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS);
- delete Request;
- return RET_ERROR;
- }
-
- // qDebug("Master Rx Write Multiple Registers response. Address: %d, Nb Reg: %d",StartAdress, NbRegisters);
- // qDebug("Data: %s",Transaction.mPDU.mData.toHex().data());
-
- //All is good.
-
- break;
- }
- default:
- {
- //Received "Illegal function code" response
- //TODO: Log this.
- qDebug("Master received illegal function code 0x%x",Transaction.mPDU.mFunctionCode);
- emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_FCT,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS);
- break;
- }
- }
-
-
- delete Request;
- return 1;
- }
-
- int CModbusBackend::SendModbusRequest(CModbusRequest *Request)
- {
- QByteArray ModbusPacket;
-
- QBuffer Buffer(&ModbusPacket);
- Buffer.open(QIODevice::WriteOnly|QIODevice::Unbuffered);
- Buffer.seek(0);
- QDataStream *PacketDataStrm = new QDataStream(&Buffer);
-
- *PacketDataStrm << Request->mHeader;
- *PacketDataStrm << Request->mPDU.mFunctionCode;
- Buffer.close();
- ModbusPacket.append(Request->mPDU.mData);
-
- qDebug("Request packet: %s",ModbusPacket.toHex().data());
-
- mModbusTCPSocketHandle->write(ModbusPacket);
- mModbusTCPSocketHandle->flush();
- return RET_OK;
- }
-
- int CModbusBackend::SendErrorResponse(CModbusTransaction RequestTransaction, quint8 ErrorCode)
- {
- QByteArray ModbusPacket;
-
- QBuffer Buffer(&ModbusPacket);
- Buffer.open(QIODevice::WriteOnly|QIODevice::Unbuffered);
- Buffer.seek(0);
- QDataStream *PacketDataStrm = new QDataStream(&Buffer);
-
- //For a response, the header will be the same as the original request, except for the msg. length.
- //Set the appropriate msg length.
- RequestTransaction.mHeader.mMessageLength = 3; //Unit ID, function code & Exception code.
-
- *PacketDataStrm << RequestTransaction.mHeader;
- Buffer.close();
- ModbusPacket.append(RequestTransaction.mPDU.mFunctionCode + 0x80);
- ModbusPacket.append(ErrorCode);
-
-
- qDebug("Sending error code %d. Error packet: %s",ErrorCode,ModbusPacket.toHex().data());
-
- mModbusTCPSocketHandle->write(ModbusPacket);
-
- delete PacketDataStrm;
-
- return RET_OK;
- }
-
-
- int CModbusBackend::SendReadHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount)
- {
- //First, validate that the reading range is within our repo
- if(mModbusRepo->IsHRValid(StartAddress,RegisterCount) == false)
- {
- qDebug("Trying to send a read HR in an invalid range");
- return RET_ERROR;
- }
-
- //Create a request.
- CModbusRequest *NewRequest = new CModbusRequest;
- NewRequest->mStartAddress = StartAddress;
- NewRequest->mNbRegisters = RegisterCount;
- connect(NewRequest->mRequestTimer,SIGNAL(timeout()),this,SLOT(RequestTimerExpired()));
-
- NewRequest->mPDU.mData.clear();
- NewRequest->mPDU.mFunctionCode = MODBUS_FCT_READ_HOLDING_REGISTERS;
-
- quint8 HighByte, LowByte;
- LowByte = StartAddress & 0x00FF;
- HighByte = (StartAddress >> 8) & 0x00FF;
- NewRequest->mPDU.mData.append(HighByte);
- NewRequest->mPDU.mData.append(LowByte);
-
- LowByte = RegisterCount & 0x00FF;
- HighByte = (RegisterCount >> 8) & 0x00FF;
- NewRequest->mPDU.mData.append(HighByte);
- NewRequest->mPDU.mData.append(LowByte);
-
- NewRequest->mHeader.mMessageLength = NewRequest->mPDU.mData.size() + 2;
- NewRequest->mHeader.mProtocolID = 0;
- NewRequest->mHeader.mTransactionID = (qint16)GetNewTransactionID();
- NewRequest->mHeader.mUnitID = mDeviceID;
-
- mRequestsList.append(NewRequest);
-
- SendModbusRequest(NewRequest);
-
- NewRequest->mRequestTimer->start(mModbusRequestTimeout);
-
-
- return RET_OK;
-
- }
-
- int CModbusBackend::SendWriteHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount)
- {
- //First, validate that the reading range is within our repo
- if(mModbusRepo->IsHRValid(StartAddress,RegisterCount) == false)
- {
- qDebug("Trying to send a read HR in an invalid range");
- return RET_ERROR;
- }
-
- if(RegisterCount > MODBUS_MAX_NB_REGISTERS)
- {
- return RET_ERROR;
- }
-
- //Get data.
- bool OK;
- QByteArray RegData = mModbusRepo->GetHRData(StartAddress,RegisterCount,&OK);
- if(OK == false)
- {
- return RET_ERROR;
- }
-
- //Create a request.
- CModbusRequest *NewRequest = new CModbusRequest;
- NewRequest->mStartAddress = StartAddress;
- NewRequest->mNbRegisters = RegisterCount;
- connect(NewRequest->mRequestTimer,SIGNAL(timeout()),this,SLOT(RequestTimerExpired()));
-
- NewRequest->mPDU.mData.clear();
- NewRequest->mPDU.mFunctionCode = MODBUS_FCT_WRITE_MULTIPLE_REGISTERS;
-
- //Start address
- quint8 HighByte, LowByte;
- LowByte = StartAddress & 0x00FF;
- HighByte = (StartAddress >> 8) & 0x00FF;
- NewRequest->mPDU.mData.append(HighByte);
- NewRequest->mPDU.mData.append(LowByte);
-
- //Nb registers
- LowByte = RegisterCount & 0x00FF;
- HighByte = (RegisterCount >> 8) & 0x00FF;
- NewRequest->mPDU.mData.append(HighByte);
- NewRequest->mPDU.mData.append(LowByte);
-
- //Byte Count
- NewRequest->mPDU.mData.append(RegData.size());
-
- //Datal
- NewRequest->mPDU.mData.append(RegData);
-
- NewRequest->mHeader.mMessageLength = NewRequest->mPDU.mData.size() + 2;
- NewRequest->mHeader.mProtocolID = 0;
- NewRequest->mHeader.mTransactionID = (qint16)GetNewTransactionID();
- NewRequest->mHeader.mUnitID = mDeviceID;
-
- mRequestsList.append(NewRequest);
-
- SendModbusRequest(NewRequest);
-
- NewRequest->mRequestTimer->start(mModbusRequestTimeout);
-
-
- return RET_OK;
- }
-
- int CModbusBackend::SendWriteSingleRegisterRequest(quint16 Address)
- {
- if(Address == 2000)
- {
- qDebug("Write single reg 2000");
- }
- //First, validate that the reading range is within our repo
- if(mModbusRepo->IsHRValid(Address,1) == false)
- {
- qDebug("Trying to send a read HR in an invalid range");
- return RET_ERROR;
- }
-
- //Get data.
- bool OK;
- QByteArray RegData = mModbusRepo->GetHRData(Address,1,&OK);
- if(OK == false)
- {
- return RET_ERROR;
- }
-
- //Create a request.
- CModbusRequest *NewRequest = new CModbusRequest;
- NewRequest->mStartAddress = Address;
- NewRequest->mNbRegisters = 1;
- connect(NewRequest->mRequestTimer,SIGNAL(timeout()),this,SLOT(RequestTimerExpired()));
-
- NewRequest->mPDU.mData.clear();
- NewRequest->mPDU.mFunctionCode = MODBUS_WRITE_SINGLE_REGISTER;
-
- quint8 HighByte, LowByte;
- LowByte = Address & 0x00FF;
- HighByte = (Address >> 8) & 0x00FF;
- NewRequest->mPDU.mData.append(HighByte);
- NewRequest->mPDU.mData.append(LowByte);
-
- // LowByte = RegData & 0x00FF;
- // HighByte = (RegData >> 8) & 0x00FF;
- // NewRequest->mPDU.mData.append(HighByte);
- // NewRequest->mPDU.mData.append(LowByte);
-
- NewRequest->mPDU.mData.append(RegData);
-
- NewRequest->mHeader.mMessageLength = NewRequest->mPDU.mData.size() + 2;
- NewRequest->mHeader.mProtocolID = 0;
- NewRequest->mHeader.mTransactionID = (qint16)GetNewTransactionID();
- NewRequest->mHeader.mUnitID = mDeviceID;
-
- mRequestsList.append(NewRequest);
-
- SendModbusRequest(NewRequest);
-
- NewRequest->mRequestTimer->start(mModbusRequestTimeout);
-
-
- return RET_OK;
- }
-
- void CModbusBackend::RequestTimerExpired()
- {
- //find the expired request
- for(int i = 0; i < mRequestsList.size(); i++)
- {
- if(mRequestsList.at(i)->mRequestTimer->isActive() == false)
- {
- if(mRequestsList.at(i)->mRetries >= mModbusMaxRetry)
- {
- //The max number of retry has been reached. The device is probably offline.
-
- qDebug("Modbus Master: Request sent to slave without response");
-
- delete mRequestsList[i];
- mRequestsList.removeAt(i);
-
-
- //TODO: Manage this situation (log?)
-
- return;
- }
- else
- {
- SendModbusRequest(mRequestsList[i]);
- mRequestsList.at(i)->mRequestTimer->start(mModbusRequestTimeout);
- mRequestsList[i]->mRetries++;
- }
- }
- }
- }
-
- quint16 CModbusBackend::GetNewTransactionID()
- {
- quint16 ID = mTransactionIDCounter++;
-
- if(mTransactionIDCounter == 0xFFFF - 10)
- {
- mTransactionIDCounter = 0;
- }
-
- return ID;
- }
-
-
-
- CModbusRequest::CModbusRequest():
- mRetries(0)
- {
- mRequestTimer = new QTimer;
- mRequestTimer->setSingleShot(true);
- }
- CModbusRequest::~CModbusRequest()
- {
- delete mRequestTimer;
- }
-
-
-
-
-
- QDataStream &operator<<(QDataStream &out, const CModbusHeader &source)
- {
- out << source.mTransactionID
- << source.mProtocolID
- << source.mMessageLength
- << source.mUnitID
- ;
-
- return out;
- }
-
- QDataStream &operator>>(QDataStream &in, CModbusHeader &dest)
- {
- in >> dest.mTransactionID
- >> dest.mProtocolID
- >> dest.mMessageLength
- >> dest.mUnitID
- ;
-
- return in;
- }
-
- //Virtual function that should not even get called...
- void CModbusBackend::ModbusResponseException(quint8 ExceptionCode, quint8 FctCode)
- {
- qDebug("ModbusResponseException called from within slave object... weird stuff!");
- }
-
- //Virtual function that should not even get called...
- void CModbusBackend::ModbusRequestException(quint8 ExceptionCode, quint8 FctCode)
- {
- qDebug("ModbusResponseException called from within master object... weird stuff!");
- }
|