1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-30 11:36:13 +01:00

Reworked use of ringbuffer

This commit is contained in:
Harald Barth 2021-09-30 22:55:14 +02:00
parent 19b4893b5f
commit 426b27f0dd
3 changed files with 58 additions and 13 deletions

View File

@ -45,10 +45,11 @@ size_t RingStream::write(uint8_t b) {
return 1; return 1;
} }
int RingStream::read() { int RingStream::read(byte advance) {
if ((_pos_read==_pos_write) && !_overflow) return -1; // empty if ((_pos_read==_pos_write) && !_overflow) return -1; // empty
if (_pos_read == _mark) return -1;
byte b=_buffer[_pos_read]; byte b=_buffer[_pos_read];
_pos_read++; _pos_read += advance;
if (_pos_read==_len) _pos_read=0; if (_pos_read==_len) _pos_read=0;
_overflow=false; _overflow=false;
return b; return b;
@ -68,6 +69,7 @@ int RingStream::freeSpace() {
// mark start of message with client id (0...9) // mark start of message with client id (0...9)
void RingStream::mark(uint8_t b) { void RingStream::mark(uint8_t b) {
//DIAG(F("Mark1 len=%d count=%d pr=%d pw=%d m=%d"),_len, _count,_pos_read,_pos_write,_mark);
_mark=_pos_write; _mark=_pos_write;
write(b); // client id write(b); // client id
write((uint8_t)0); // count MSB placemarker write((uint8_t)0); // count MSB placemarker
@ -81,7 +83,12 @@ uint8_t RingStream::peekTargetMark() {
return _buffer[_mark]; return _buffer[_mark];
} }
void RingStream::info() {
DIAG(F("Info len=%d count=%d pr=%d pw=%d m=%d"),_len, _count,_pos_read,_pos_write,_mark);
}
bool RingStream::commit() { bool RingStream::commit() {
//DIAG(F("Commit1 len=%d count=%d pr=%d pw=%d m=%d"),_len, _count,_pos_read,_pos_write,_mark);
if (_overflow) { if (_overflow) {
DIAG(F("RingStream(%d) commit(%d) OVERFLOW"),_len, _count); DIAG(F("RingStream(%d) commit(%d) OVERFLOW"),_len, _count);
// just throw it away // just throw it away
@ -101,5 +108,7 @@ bool RingStream::commit() {
_mark++; _mark++;
if (_mark==_len) _mark=0; if (_mark==_len) _mark=0;
_buffer[_mark]=lowByte(_count); _buffer[_mark]=lowByte(_count);
_mark=_len+1;
//DIAG(F("Commit2 len=%d count=%d pr=%d pw=%d m=%d"),_len, _count,_pos_read,_pos_write,_mark);
return true; // commit worked return true; // commit worked
} }

View File

@ -28,14 +28,17 @@ class RingStream : public Print {
virtual size_t write(uint8_t b); virtual size_t write(uint8_t b);
using Print::write; using Print::write;
int read(); inline int read() { return read(1); };
inline int peek() { return read(0); };
int count(); int count();
int freeSpace(); int freeSpace();
void mark(uint8_t b); void mark(uint8_t b);
bool commit(); bool commit();
uint8_t peekTargetMark(); uint8_t peekTargetMark();
void info();
private: private:
int read(byte advance);
int _len; int _len;
int _pos_write; int _pos_write;
int _pos_read; int _pos_read;

View File

@ -52,18 +52,22 @@ static void handleData(void* arg, AsyncClient* client, void *data, size_t len) {
} }
} }
bool sendData(uint8_t clientId, char* data, int count) { //static AsyncClient *debugclient = NULL;
AsyncClient *client = clients[clientId];
bool sendData(AsyncClient *client, char* data, size_t count) {
size_t willsend = 0; size_t willsend = 0;
// reply to client // reply to client
if (client->canSend()) { if (client->canSend()) {
while (count > 0) { while (count > 0) {
willsend = client->add(data, count); // add checks for space() if (client->connected())
willsend = client->add(data, count); // add checks for space()
else
willsend = 0;
if (willsend < count) { if (willsend < count) {
DIAG(F("Willsend %d of count %d"), willsend, count); DIAG(F("Willsend %d of count %d"), willsend, count);
} }
if (client->send()) { if (client->connected() && client->send()) {
count = count - willsend; count = count - willsend;
data = data + willsend; data = data + willsend;
} else { } else {
@ -78,12 +82,23 @@ bool sendData(uint8_t clientId, char* data, int count) {
return false; return false;
} }
static void deleteClient(AsyncClient* client) {
uint8_t clientId;
for (clientId=0; clientId<clients.size(); clientId++){
if (clients[clientId] == client) break;
}
if (clientId < clients.size()) {
clients[clientId] = NULL;
}
}
static void handleDisconnect(void* arg, AsyncClient* client) { static void handleDisconnect(void* arg, AsyncClient* client) {
DIAG(F("client %s disconnected"), client->remoteIP().toString().c_str()); DIAG(F("client %s disconnected"), client->remoteIP().toString().c_str());
deleteClient(client);
} }
static void handleTimeOut(void* arg, AsyncClient* client, uint32_t time) { static void handleTimeOut(void* arg, AsyncClient* client, uint32_t time) {
DIAG(F("client ACK timeout ip: %s"), client->remoteIP().toString().c_str()); DIAG(F("client ACK timeout ip: %s"), client->remoteIP().toString().c_str());
deleteClient(client);
} }
@ -154,11 +169,27 @@ bool WifiESP::setup(const char *wifiESSID,
} }
void WifiESP::loop() { void WifiESP::loop() {
AsyncClient *client = NULL;
// Do something with outboundRing // Do something with outboundRing
// call sendData // call sendData
int clientId=outboundRing->read(); int clientId=outboundRing->peek();
if (clientId>=0) { if (clientId >= 0) {
if (clientId > clients.size()) {
// something is wrong with the ringbuffer position
outboundRing->info();
client = NULL;
} else {
client = clients[clientId];
}
// if (client != debugclient) {
// DIAG(F("new client pointer = %x from id %d"), client, clientId);
// debugclient = client;
// }
} else {
client = NULL;
}
if (clientId>=0 && client && client->connected() && client->canSend()) {
outboundRing->read();
int count=outboundRing->count(); int count=outboundRing->count();
//DIAG(F("Wifi reply client=%d, count=%d"), clientId,count); //DIAG(F("Wifi reply client=%d, count=%d"), clientId,count);
{ {
@ -174,9 +205,11 @@ void WifiESP::loop() {
} }
buffer[count]=0; buffer[count]=0;
//DIAG(F("SEND:%s COUNT:%d"),buffer,count); //DIAG(F("SEND:%s COUNT:%d"),buffer,count);
while (! sendData(clientId, buffer, count)) { uint8_t tries = 3;
while (! sendData(client, buffer, count)) {
DIAG(F("senData fail")); DIAG(F("senData fail"));
yield(); yield();
if (tries == 0) break;
} }
} }
} }