Very simple bytestuffed protocolThe version here is crafted so it can be tested on an Arduino Should be easy portable Jens byteStuff on Ard no 1
// JDN oct 2024
// simple byte stuffing protocol
// WARNING: no check on timeout in rx as well as tx
//
// NB tx and RX buf size is 64 on ardino uno and mega
//
// bytestuff is inserted and removed on the fly so ...
// SPECIAL:
// In the example we use TX and RX on Serial "1" port - the same port
// So for test you have to connect TX and RX pins
// On an UNO its pin 0 and 1
// WHEN UPLOADING REMOVE THE CONNECTION OTHERWISE UPLOAD FAIL
//
//vrs 0.13
// start of frame delimiter - is inserted automaticly
#define SOT '['
// end of frame delimiter - is inserted automaticly
#define EOT ']'
// Byte stuffing value
#define STUFFBYTE 'S'
// nr of restart in rxPkg if a SOT occurs after forst SOT and before the wanted EOT
#define NRRESTART 1
// define rx and tx ports
#define TXPORT Serial
#define RXPORT Serial
//-----------------------------------------------
// tx pgk lgt do not include SOF and EOF
void txPkg(const char *src, int lgt) {
char b;
//1. txSOF
TXPORT.write(SOT);
//2: tx message
while (0 < lgt) {
b = *src;
switch (b) {
case SOT: // bytesstuffing now ?
case EOT: // just add more chars if needed
case STUFFBYTE:
b = ~b;
TXPORT.write(STUFFBYTE);
TXPORT.write(b);
break;
default:
TXPORT.write(b);
}
lgt--;
if (0 < lgt)
src++;
}
//3. tx EOT
TXPORT.write(EOT);
}
//----
void emptyRxBuf() {
delay(100); // why ?? dont know ! :-)
while (RXPORT.available())
RXPORT.read();
}
uint8_t getNextByte() {
char b;
while (RXPORT.available() < 1)
;
b = RXPORT.read();
return (b);
}
int rxPkg(uint8_t *dest, int maxLgt) {
int bytesRcv = 0;
uint8_t b, noRestart;
uint8_t *p;
noRestart = NRRESTART;
p = dest;
//1. read SOT - start of Frame
while (1) {
b = getNextByte();
if (b == SOT)
break;
}
//2. assumption EOF is not in tlg - only as EOF
// read message and EOT
// NB if your buffer fills up before EOT is received length returned is negative
while (1) {
b = getNextByte();
//hm lost EOT so start on next pkg
if (SOT == b) { // start again
noRestart--;
if (noRestart < 0) {
bytesRcv = -9999;
goto outhere;
}
p = dest;
bytesRcv = 0;
break;
}
if (EOT == b) {
goto outhere;
} else {
if (b == STUFFBYTE) {
b = getNextByte(); // drop stuff Symbol and get next char
b = ~b; //destuff// --------------------
}
*p = b;
p++;
bytesRcv++;
// rx user buffer full ?
if (maxLgt <= bytesRcv) {
bytesRcv = -bytesRcv; // negativ value indicates for caller buffer full
goto outhere; // before we did get EOT !!
}
}
}
// 3. return nr of bytes rcv not including SOF and EOF
outhere:
return bytesRcv;
}
uint8_t rcvBuf[100];
char bf[] = "1234S45[]0";
int nrRcv = 0;
void setup() {
Serial.begin(115200);
Serial.println("\n----");
Serial.println(__FILE__);
Serial.println(__DATE__);
Serial.println(sizeof(bf));
Serial.println("--<>--");
delay(100);
// empty buf
emptyRxBuf();
delay(500);
//test
txPkg(bf, sizeof(bf));
delay(500);
nrRcv = rxPkg(rcvBuf, 100);
delay(100);
// results of test
Serial.println("\n---after test");
Serial.print("tx: ");
Serial.println(sizeof(bf));
Serial.print("rx: ");
Serial.println(nrRcv);
if (nrRcv == sizeof(bf))
Serial.println("same number of chr received as transmitted");
else
Serial.println("did not receive same number as transmitted");
Serial.println((char *)rcvBuf);
Serial.println("--eof");
}
void loop() {}
|