# include "Arduino.h"
# include "SerialChannel.h"
byte SerialChannel : : nextId = 1 ;
SerialChannel * SerialChannel : : first = 0 ;
SerialChannel : : Message SerialChannel : : buffer1 [ SerialChannel : : MaxPendingMessages ] ;
SerialChannel : : Message SerialChannel : : buffer2 [ SerialChannel : : MaxPendingMessages ] ;
volatile SerialChannel : : Message * SerialChannel : : backBuffer ;
volatile byte SerialChannel : : backBufferPos ;
byte SerialChannel : : frontBufferSize ;
SerialChannel : : Message dummyMessage ;
SerialChannel : : SerialChannel ( const char * name_ )
: next ( 0 )
, id ( ( byte ) - 1 )
, name ( name_ )
{
if ( first = = 0 )
first = this ;
else
{
SerialChannel * c = first ;
while ( c - > next ! = 0 ) c = c - > next ;
c - > next = this ;
}
id = nextId + + ;
}
void SerialChannel : : beginWriteInChannel ( byte id , short byteCount , unsigned long time )
{
Serial . write ( " START " ) ;
Serial . write ( id ) ;
writeULong ( time ) ;
writeShort ( byteCount ) ;
}
void SerialChannel : : write ( byte * data , short byteCount , unsigned long time )
{
beginWrite ( byteCount , time ) ;
continueWrite ( data , byteCount ) ;
}
void SerialChannel : : beginWrite ( short byteCount , unsigned long time )
{
if ( time = = ( unsigned long ) - 1 )
time = micros ( ) ;
handleConnection ( ) ;
beginWriteInChannel ( id , byteCount , time ) ;
}
void SerialChannel : : continueWrite ( byte * data , short byteCount )
{
Serial . write ( data , byteCount ) ;
}
void SerialChannel : : write ( const char * text , unsigned long time )
{
write ( ( byte * ) text , strlen ( text ) , time ) ;
}
SerialChannel : : Message & SerialChannel : : append ( byte * data , short byteCount , unsigned long time )
{
if ( time = = ( unsigned long ) - 1 )
time = micros ( ) ;
if ( backBufferPos > = MaxPendingMessages )
{
Message & msg = ( ( Message * ) backBuffer ) [ MaxPendingMessages - 1 ] ;
msg . id = id ;
msg . data = ( byte * ) " OVERFLOW " ;
msg . byteCount = 8 ;
msg . time = time ;
msg . longArg0 = 0 ;
return dummyMessage ;
}
else
{
Message & msg = ( ( Message * ) backBuffer ) [ backBufferPos + + ] ;
msg . id = id ;
msg . data = data ;
msg . byteCount = byteCount ;
msg . time = time ;
msg . longArg0 = 0 ;
return msg ;
}
}
void SerialChannel : : append ( const char * text , unsigned long time )
{
append ( ( byte * ) text , strlen ( text ) , time ) ;
}
void SerialChannel : : appendInt ( const char * text , short textLength , int arg0 , unsigned long time )
{
Message & msg = append ( ( byte * ) text , textLength , time ) ;
msg . longArg0 = arg0 | 0x40000000 ;
}
void SerialChannel : : swap ( )
{
backBuffer = backBuffer = = buffer1 ? buffer2 : buffer1 ;
frontBufferSize = backBufferPos ;
backBufferPos = 0 ;
}
void SerialChannel : : flush ( )
{
handleConnection ( ) ;
Message * frontBuffer = backBuffer = = buffer1 ? buffer2 : buffer1 ;
for ( Message * msg = frontBuffer ; msg < frontBuffer + frontBufferSize ; + + msg )
{
char params [ 32 ] ;
params [ 0 ] = 0 ;
if ( ( msg - > longArg0 & 0x40000000 ) ! = 0 )
sprintf ( params , " ;arg0=%ld " , msg - > longArg0 & ~ 0x40000000 ) ;
short paramsSize = strlen ( params ) ;
beginWriteInChannel ( msg - > id , msg - > byteCount + paramsSize , msg - > time ) ;
Serial . write ( msg - > data , msg - > byteCount ) ;
if ( paramsSize > 0 )
Serial . write ( params , paramsSize ) ;
Serial . flush ( ) ;
}
}
void SerialChannel : : writeShort ( short num )
{
Serial . write ( ( byte * ) & num , 2 ) ;
}
void SerialChannel : : writeULong ( unsigned long num )
{
Serial . write ( ( byte * ) & num , 4 ) ;
}
void SerialChannel : : handleConnection ( )
{
int b = Serial . read ( ) ;
if ( b = = ( int ) ' C ' )
{
Serial . write ( " CONNECTION " ) ;
SerialChannel * c = first ;
while ( c )
{
Serial . write ( " START " ) ;
Serial . write ( 0 ) ;
Serial . write ( " ChannelInit " ) ;
Serial . write ( c - > id ) ;
writeShort ( strlen ( c - > name ) ) ;
Serial . write ( c - > name ) ;
c = c - > next ;
}
Serial . flush ( ) ;
}
}