Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TCP Slip support #153

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 175 additions & 0 deletions SLIPEncodedTCP.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#include "SLIPEncodedTCP.h"
#include <Client.h>
/*
CONSTRUCTOR
*/
//instantiate with the tranmission layer

SLIPEncodedTCP::SLIPEncodedTCP(Client &s){
tcpClient = &s;
rstate = CHAR;
}

static const uint8_t eot = 0300;
static const uint8_t slipesc = 0333;
static const uint8_t slipescend = 0334;
static const uint8_t slipescesc = 0335;
/*
tcpClient METHODS
*/
bool SLIPEncodedTCP::endofPacket()
{
if(rstate == SECONDEOT)
{
rstate = CHAR;
return true;
}
if (rstate==FIRSTEOT)
{
if(tcpClient->available())
{
uint8_t c =tcpClient->peek();
if(c==eot)
{
tcpClient->read(); // throw it on the floor
}
}
rstate = CHAR;
return true;
}
return false;
}
int SLIPEncodedTCP::available(){
back:
int cnt = tcpClient->available();

if(cnt==0)
return 0;
if(rstate==CHAR)
{
uint8_t c =tcpClient->peek();
if(c==slipesc)
{
rstate = SLIPESC;
tcpClient->read(); // throw it on the floor
goto back;
}
else if( c==eot)
{
rstate = FIRSTEOT;
tcpClient->read(); // throw it on the floor
goto back;
}
return 1; // we may have more but this is the only sure bet
}
else if(rstate==SLIPESC)
return 1;
else if(rstate==FIRSTEOT)
{
if(tcpClient->peek()==eot)
{
rstate = SECONDEOT;
tcpClient->read(); // throw it on the floor
return 0;
}
rstate = CHAR;
}else if (rstate==SECONDEOT) {
rstate = CHAR;
}

return 0;

}

//reads a byte from the buffer
int SLIPEncodedTCP::read(){
back:
uint8_t c = tcpClient->read();
if(rstate==CHAR)
{
if(c==slipesc)
{
rstate=SLIPESC;
goto back;
}
else if(c==eot){

return -1; // xxx this is an error
}
return c;
}
else
if(rstate==SLIPESC)
{
rstate=CHAR;
if(c==slipescend)
return eot;
else if(c==slipescesc)
return slipesc;
else {
// insert some error code here
return -1;
}

}
else
return -1;
}

// as close as we can get to correct behavior
int SLIPEncodedTCP::peek(){
uint8_t c = tcpClient->peek();
if(rstate==SLIPESC)
{
if(c==slipescend)
return eot;
else if(c==slipescesc)
return slipesc;
}
return c;
}

//the arduino and wiring libraries have different return types for the write function
#if defined(WIRING) || defined(BOARD_DEFS_H)

//encode SLIP
void SLIPEncodedTCP::write(uint8_t b){
if(b == eot){
tcpClient->write(slipesc);
return tcpClient->write(slipescend);
} else if(b==slipesc) {
tcpClient->write(slipesc);
return tcpClient->write(slipescesc);
} else {
return tcpClient->write(b);
}
}
void SLIPEncodedTCP::write(const uint8_t *buffer, size_t size) { while(size--) write(*buffer++); }
#else
//encode SLIP
size_t SLIPEncodedTCP::write(uint8_t b){
if(b == eot){
tcpClient->write(slipesc);
return tcpClient->write(slipescend);
} else if(b==slipesc) {
tcpClient->write(slipesc);
return tcpClient->write(slipescesc);
} else {
return tcpClient->write(b);
}
}
size_t SLIPEncodedTCP::write(const uint8_t *buffer, size_t size) { size_t result=0; while(size--) result = write(*buffer++); return result; }

#endif

//SLIP specific method which begins a transmitted packet
void SLIPEncodedTCP::beginPacket() { tcpClient->write(eot); }

//signify the end of the packet with an EOT
void SLIPEncodedTCP::endPacket(){
tcpClient->write(eot);
}

void SLIPEncodedTCP::flush(){
tcpClient->flush();
}
48 changes: 48 additions & 0 deletions SLIPEncodedTCP.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Extends the TCP client class to encode SLIP over TCP
*/

#ifndef SLIPEncodedTCP_H
#define SLIPEncodedTCP_H

#include "Arduino.h"
#include <Stream.h>
#include <Client.h>


class SLIPEncodedTCP: public Stream{

private:
enum erstate {CHAR, FIRSTEOT, SECONDEOT, SLIPESC } rstate;

//the TCP client used
Client * tcpClient;

public:
SLIPEncodedTCP(Client & );

int available();
int read();
int peek();
void flush();
void beginPacket(); // SLIP specific method which begins a transmitted packet
void endPacket(); // SLIP specific method which ends a transmittedpacket
bool endofPacket(); // SLIP specific method which indicates that an EOT was received

//the arduino and wiring libraries have different return types for the write function
#if defined(WIRING) || defined(BOARD_DEFS_H)
void write(uint8_t b);
void write(const uint8_t *buffer, size_t size);

#else
//overrides the Stream's write function to encode SLIP
size_t write(uint8_t b);
size_t write(const uint8_t *buffer, size_t size);

//using Print::write;
#endif

};


#endif
59 changes: 59 additions & 0 deletions examples/ETC_EOS_TCP/ETC_EOS_TCP.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Example for ETC EOS Conasoles, sending und receiving pings
#include "Ethernet.h"
#include "OSCMessage.h"
#include "SLIPEncodedTCP.h"

uint8_t mac[] = {0x90, 0xA2, 0xDA, 0x10, 0x14, 0x48};
IPAddress localIP(10, 101, 1, 201); // IP of your Arduino
IPAddress dns(10, 101, 1, 201); // IP of your DNS server
IPAddress subnet(255, 255, 0, 0); // your subnet
IPAddress eosIP(10, 101, 1, 100); // IP of your console
uint16_t eosTcpPort = 3037; // use default EOS Slip port

EthernetClient tcp;
SLIPEncodedTCP slip (tcp);

void setup() {
Serial.begin(9600);
Ethernet.begin(mac, localIP, dns ,subnet);
if (!tcp.connected()) {
tcp.stop();
tcp.connect(eosIP, eosTcpPort);
}
}

void loop() {
OSCMessage msg;
static unsigned long lastTimeSent;
static int32_t pingNum;
unsigned long curTime;

// look if there is a new meassage, if yes print ping data
if (slip.available()) {
while (!slip.endofPacket()) {
while (slip.available()) {
msg.fill(slip.read());
}
}
if (msg.fullMatch("/eos/out/ping")) {
Serial.print("Ping Number ");
Serial.print(msg.getInt(0));
Serial.println(" received");
}
}

// send a ping every second
curTime = millis();
if (curTime - lastTimeSent > 1000) {
OSCMessage ping("/eos/ping");
ping.add(pingNum++);
if (!tcp.connected()) {
tcp.stop();
tcp.connect(eosIP, eosTcpPort);
}
slip.beginPacket();
ping.send(slip);
slip.endPacket();
lastTimeSent = curTime;
}
}
1 change: 1 addition & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ endofTransmission KEYWORD1
SLIPEncodedSerial KEYWORD3
SLIPEncodedUSBSerial KEYWORD3
SLIPEncodedSPISerial KEYWORD3
SLIPEncodedTCP KEYWORD3
oscTime KEYWORD1
adcRead KEYWORD1
capacitanceRead KEYWORD1
Expand Down