Skip to content

Commit a09c4ce

Browse files
committed
dropTransaction()/clean() refactoring
1 parent 604d170 commit a09c4ce

File tree

4 files changed

+30
-33
lines changed

4 files changed

+30
-33
lines changed

API.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,10 @@ void slave();
196196
```c
197197
void master();
198198
bool connect(IPAddress ip);
199-
bool disconnect(IPAddress ip); // Not implemented yet.
199+
bool disconnect(IPAddress ip);
200200
bool isTransaction(uint16_t id);
201201
bool isConnected(IPAddress ip);
202+
void dropTransactions();
202203
```
203204
204205
```c
@@ -209,7 +210,7 @@ Select behavior of executing read/write/pull/push. If autoConnect disabled (defa
209210

210211
### Callback example
211212

212-
```c
213+
```arduino
213214
ModbusIP mb;
214215
bool coil = false; // Define external variable to get/set value
215216
uint16_t cbCoilSet(TRegister* reg, uint16_t val) { // 'reg' is pointer to reg structure to modify, 'val' is new register value

keywords.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Modbus KEYWORD1
66
TRegister KEYWORD1
77
TTransaction KEYWORD1
88
TAddress KEYWORD1
9+
ResultCode KEYWORD1
910

1011
# Methods and Functions (KEYWORD2)
1112
master KEYWORD2
@@ -65,6 +66,10 @@ removeIsts KEYWORD2
6566
autoConnect KEYWORD2
6667
disconnect KEYWORD2
6768
dropTransactions KEYWORD2
69+
isCoil KEYWORD2
70+
isHreg KEYWORD2
71+
isIsts KEYWORD2
72+
isIreg KEYWORD2
6873

6974
# Constants and Macros (LITERAL1)
7075
BIT_VAL LITERAL1
@@ -91,4 +96,8 @@ EX_UNEXPECTED_RESPONSE LITERAL1
9196
EX_TIMEOUT LITERAL1
9297
EX_CONNECTION_LOST LITERAL1
9398
EX_CANCEL LITERAL1
99+
COIL LITERAL1
100+
HREG LITERAL1
101+
ISTS LITERAL1
102+
IREG LITERAL1
94103

src/ModbusIP_ESP8266.cpp

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,7 @@ void ModbusIP::task() {
152152

153153
uint16_t ModbusIP::send(IPAddress ip, TAddress startreg, cbTransaction cb, uint8_t unit, void* data, bool waitResponse) {
154154
#ifdef MODBUSIP_MAX_TRANSACIONS
155-
if (_trans.size() >= MODBUSIP_MAX_TRANSACIONS)
156-
return false;
155+
if (this->_trans.size() >= MODBUSIP_MAX_TRANSACIONS) return false;
157156
#endif
158157
int8_t p = getSlave(ip);
159158
if (p == -1 || !client[p]->connected())
@@ -171,7 +170,7 @@ uint16_t ModbusIP::send(IPAddress ip, TAddress startreg, cbTransaction cb, uint8
171170
if (client[p]->write(sbuf, send_len) != send_len)
172171
return false;
173172
client[p]->flush();
174-
if (waitResponse || true) {
173+
if (waitResponse) {
175174
TTransaction tmp;
176175
tmp.transactionId = transactionId;
177176
tmp.timestamp = millis();
@@ -194,16 +193,8 @@ void ModbusIP::onDisconnect(cbModbusConnect cb) {
194193
cbDisconnect = cb;
195194
}
196195

197-
bool ifExpired(TTransaction& t) {
198-
if (millis() - t.timestamp > MODBUSIP_TIMEOUT) {
199-
//if (t.cb)
200-
// t.cb(Modbus::EX_TIMEOUT, t.transactionId, nullptr);
201-
//free(t._frame);
202-
return true;
203-
}
204-
return false;
205-
}
206-
void ModbusIP::cleanup() { // Free clients if not connected and remove timedout transactions
196+
void ModbusIP::cleanup() {
197+
// Free clients if not connected
207198
for (uint8_t i = 0; i < MODBUSIP_MAX_CLIENTS; i++) {
208199
if (client[i] && !client[i]->connected()) {
209200
//IPAddress ip = client[i]->remoteIP();
@@ -213,20 +204,19 @@ void ModbusIP::cleanup() { // Free clients if not connected and remove timedout
213204
cbDisconnect(IPADDR_NONE);
214205
}
215206
}
216-
//_trans.erase(remove_if( _trans.begin(), _trans.end(), ifExpired ), _trans.end() );
217-
std::vector<TTransaction>::iterator it = std::find_if(_trans.begin(), _trans.end(), ifExpired);
218-
while (it != _trans.end()) {
219-
if (it->cb)
220-
it->cb(Modbus::EX_TIMEOUT, it->transactionId, nullptr);
221-
free(it->_frame);
222-
_trans.erase(it);
223-
it = std::find_if(it, _trans.end(), ifExpired);
207+
// Remove timedout transactions and forced event
208+
for (auto it = _trans.begin(); it != _trans.end();) {
209+
if (millis() - it->timestamp > MODBUSIP_TIMEOUT || it->forcedEvent != Modbus::EX_SUCCESS) {
210+
Modbus::ResultCode res = (it->forcedEvent != Modbus::EX_SUCCESS)?it->forcedEvent:Modbus::EX_TIMEOUT;
211+
it->cb(res, it->transactionId, nullptr);
212+
free(it->_frame);
213+
it = _trans.erase(it);
214+
} else
215+
it++;
224216
}
225-
226217
}
227218

228-
int8_t ModbusIP::getFreeClient() { // Returns free slot position
229-
//clientsCleanup();
219+
int8_t ModbusIP::getFreeClient() {
230220
for (uint8_t i = 0; i < MODBUSIP_MAX_CLIENTS; i++)
231221
if (!client[i])
232222
return i;
@@ -409,17 +399,13 @@ bool ModbusIP::disconnect(IPAddress ip) {
409399
}
410400

411401
void ModbusIP::dropTransactions() {
412-
for (auto &t : _trans) {
413-
if (t.cb)
414-
t.cb(EX_CANCEL, t.transactionId, nullptr);
415-
free(t._frame);
416-
}
417-
_trans.clear();
402+
for (auto &t : _trans) t.forcedEvent = EX_CANCEL;
418403
}
419404

420405
ModbusIP::~ModbusIP() {
421406
free(_frame);
422407
dropTransactions();
408+
cleanup();
423409
for (uint8_t i = 0; i < MODBUSIP_MAX_CLIENTS; i++) {
424410
client[i]->stop();
425411
delete client[i];

src/ModbusIP_ESP8266.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ typedef struct TTransaction {
3232
uint8_t* _frame = nullptr;
3333
void* data = nullptr;
3434
TAddress startreg;
35+
Modbus::ResultCode forcedEvent = Modbus::EX_SUCCESS; // EX_SUCCESS means no forced event here. Forced EX_SUCCESS is not possible.
3536
bool operator ==(const TTransaction &obj) const {
3637
return transactionId == obj.transactionId;
3738
}
@@ -59,7 +60,7 @@ class ModbusIP : public Modbus {
5960
bool autoConnectMode = false;
6061

6162
TTransaction* searchTransaction(uint16_t id);
62-
void cleanup(); // Free clients if not connected and remove timedout transactions
63+
void cleanup(); // Free clients if not connected and remove timedout transactions and transaction with forced events
6364
int8_t getFreeClient(); // Returns free slot position
6465
int8_t getSlave(IPAddress ip);
6566
int8_t getMaster(IPAddress ip);

0 commit comments

Comments
 (0)