ModbusClient.cin

Fix some issues with sending and receiving packets

ModbusTcp.cin
  Don't assume the connection is ready when TcpOpen says so. Wait for OnTcpOpen() to confirm
This commit is contained in:
Jonny007-MKD 2014-07-15 12:42:05 +00:00
parent 6ddb12d98f
commit 7704769468
2 changed files with 21 additions and 14 deletions

View File

@ -586,7 +586,7 @@ void ModbusWriteRegisters(word address, long count, word values[])
// FC16: Write Multiple Registers (AOs)
offset = 0;
while (count > 0 && (address + offset) < devEndAddr)
while (count > 0 && (address + offset) > devEndAddr)
{
addressO = address + offset;
curCount = count > gMaxRegsPerWrite ? gMaxRegsPerWrite : count;
@ -786,6 +786,15 @@ void _OnModbusReceive(dword socket, long result, dword address, dword port, byte
// Size of zero indicates that the socket was closed by the communication peer.
writeDbg(ConnWarning, "OnModbusReceive: Socket closed by peer");
_ModbusDisconnect();
for (long TxID : gQueueSent)
{
writeDbg(ConnWarning, "OnModbusReceive: Moving 0x%04X back to pending queue", TxID);
memcpy(gQueuePending[TxID], gQueueSent[TxID]); // Move back to pending queue
gQueueSent.Remove(TxID);
gQueuePending[TxID].Timeouts = 0;
gQueuePending[TxID].TimeoutTicks = 0;
}
}
else
{
@ -975,8 +984,7 @@ void _ModbusSend(byte buffer[], word length, word TxID)
memcpy(gQueuePending[TxID], qe);
writeDbg(ConnDebug, "Appended packet 0x%04X to pending queue", TxID);
if (gQueuePending.Size() == 1 && gQueueSent.Size() == 0 && gSocketState == OK) // start timer if connection established
_ModbusStartQueue();
_ModbusStartQueue();
}
// This method will start the timer. Nothing special :)
@ -984,8 +992,11 @@ void _ModbusSend(byte buffer[], word length, word TxID)
// It gets called by _ModbusSend() and OnEthReceivePacket() in ModbusEil.cin
void _ModbusStartQueue()
{
writeDbg(ConnDebug, "Starting Timer gtModbusRobin");
setTimerCyclic(gtModbusRobin, 1);
if (gSocketState >= CLOSED && (gQueuePending.Size() > 0 || gQueueSent.Size() > 0))
{
writeDbg(ConnDebug, "Starting Timer gtModbusRobin");
setTimerCyclic(gtModbusRobin, 1);
}
}
/// <-ModbusSend>
@ -1047,9 +1058,9 @@ on timer gtModbusRobin
}
// Stop timer to reduce load and latency of first new packet
if (gSocketState == ERROR || gQueueSent.Size() == 0 && gQueuePending.Size() == 0)
if (gSocketState != OK || gQueueSent.Size() == 0 && gQueuePending.Size() == 0)
{
writeDbg(ConnDebug, "gtModbusRobin: Stopping Timer");
writeDbg(ConnDebug, "gtModbusRobin: Stopping Timer. Queue Sent: %d, Queue Pending: %d", gQueueSent.Size(), gQueuePending.Size());
this.Cancel();
}
}

View File

@ -105,12 +105,8 @@ word _ModbusConnectTo(dword remoteIp, word remotePort)
}
return 0;
}
else
{
writeDbg(ConnInfo, "_ModbusConnectTo: Successfully connected to server");
gSocketState = OK;
return 0;
}
gSocketState = CONNECTING; // Don't set state OK because the Stack doesn't tell us WSAEWOULDBLOCK
return 0;
}
// This method will be called when TcpSocket.Connect() had to defer the result (and returned WSAEWOULDBLOCK).
@ -208,7 +204,6 @@ word _ModbusSnd(byte buffer[], word length)
}
bin_to_strhex(buffer, str);
writeDbg(ConnDebug, "_ModbusSnd: %s (Länge: %d)", str, length);
if (gSocket.Send(buffer, length) != 0)
{
@ -223,6 +218,7 @@ word _ModbusSnd(byte buffer[], word length)
}
// else: tough luck!
}
writeDbg(ConnDebug, "_ModbusSnd: %s (Länge: %d)", str, length);
return 0;
}