2011-02-23 21:47:18 +01:00
# include "w5100.h"
# include "socket.h"
2010-03-30 20:09:55 +02:00
extern " C " {
# include "string.h"
}
# include "WProgram.h"
# include "Ethernet.h"
# include "Client.h"
# include "Server.h"
2011-02-23 21:47:18 +01:00
uint16_t Client : : _srcport = 1024 ;
2010-03-30 20:09:55 +02:00
2011-02-23 21:47:18 +01:00
Client : : Client ( uint8_t sock ) : _sock ( sock ) {
2010-03-30 20:09:55 +02:00
}
2011-02-23 21:47:18 +01:00
Client : : Client ( uint8_t * ip , uint16_t port ) : _ip ( ip ) , _port ( port ) , _sock ( MAX_SOCK_NUM ) {
2010-03-30 20:09:55 +02:00
}
uint8_t Client : : connect ( ) {
2011-02-23 21:47:18 +01:00
if ( _sock ! = MAX_SOCK_NUM )
2010-03-30 20:09:55 +02:00
return 0 ;
2011-02-23 21:47:18 +01:00
2010-03-30 20:09:55 +02:00
for ( int i = 0 ; i < MAX_SOCK_NUM ; i + + ) {
2011-02-23 21:47:18 +01:00
uint8_t s = W5100 . readSnSR ( i ) ;
if ( s = = SnSR : : CLOSED | | s = = SnSR : : FIN_WAIT ) {
2010-03-30 20:09:55 +02:00
_sock = i ;
break ;
}
}
2011-02-23 21:47:18 +01:00
if ( _sock = = MAX_SOCK_NUM )
2010-03-30 20:09:55 +02:00
return 0 ;
2011-02-23 21:47:18 +01:00
2010-03-30 20:09:55 +02:00
_srcport + + ;
2011-02-23 21:47:18 +01:00
if ( _srcport = = 0 ) _srcport = 1024 ;
socket ( _sock , SnMR : : TCP , _srcport , 0 ) ;
2010-03-30 20:09:55 +02:00
if ( ! : : connect ( _sock , _ip , _port ) ) {
2011-02-23 21:47:18 +01:00
_sock = MAX_SOCK_NUM ;
2010-03-30 20:09:55 +02:00
return 0 ;
}
2011-02-23 21:47:18 +01:00
while ( status ( ) ! = SnSR : : ESTABLISHED ) {
2010-03-30 20:09:55 +02:00
delay ( 1 ) ;
2011-02-23 21:47:18 +01:00
if ( status ( ) = = SnSR : : CLOSED ) {
_sock = MAX_SOCK_NUM ;
2010-03-30 20:09:55 +02:00
return 0 ;
}
}
2011-02-23 21:47:18 +01:00
2010-03-30 20:09:55 +02:00
return 1 ;
}
void Client : : write ( uint8_t b ) {
2011-02-23 21:47:18 +01:00
if ( _sock ! = MAX_SOCK_NUM )
2010-03-30 20:09:55 +02:00
send ( _sock , & b , 1 ) ;
}
void Client : : write ( const char * str ) {
2011-02-23 21:47:18 +01:00
if ( _sock ! = MAX_SOCK_NUM )
2010-03-30 20:09:55 +02:00
send ( _sock , ( const uint8_t * ) str , strlen ( str ) ) ;
}
void Client : : write ( const uint8_t * buf , size_t size ) {
2011-02-23 21:47:18 +01:00
if ( _sock ! = MAX_SOCK_NUM )
2010-03-30 20:09:55 +02:00
send ( _sock , buf , size ) ;
}
int Client : : available ( ) {
2011-02-23 21:47:18 +01:00
if ( _sock ! = MAX_SOCK_NUM )
return W5100 . getRXReceivedSize ( _sock ) ;
2010-03-30 20:09:55 +02:00
return 0 ;
}
int Client : : read ( ) {
uint8_t b ;
if ( ! available ( ) )
return - 1 ;
recv ( _sock , & b , 1 ) ;
return b ;
}
2011-02-23 21:47:18 +01:00
int Client : : peek ( ) {
uint8_t b ;
if ( ! available ( ) )
return - 1 ;
: : peek ( _sock , & b ) ;
return b ;
}
2010-03-30 20:09:55 +02:00
void Client : : flush ( ) {
while ( available ( ) )
read ( ) ;
}
void Client : : stop ( ) {
2011-02-23 21:47:18 +01:00
if ( _sock = = MAX_SOCK_NUM )
2010-03-30 20:09:55 +02:00
return ;
2011-02-23 21:47:18 +01:00
2010-03-30 20:09:55 +02:00
// attempt to close the connection gracefully (send a FIN to other side)
disconnect ( _sock ) ;
unsigned long start = millis ( ) ;
2011-02-23 21:47:18 +01:00
2010-03-30 20:09:55 +02:00
// wait a second for the connection to close
2011-02-23 21:47:18 +01:00
while ( status ( ) ! = SnSR : : CLOSED & & millis ( ) - start < 1000 )
2010-03-30 20:09:55 +02:00
delay ( 1 ) ;
2011-02-23 21:47:18 +01:00
2010-03-30 20:09:55 +02:00
// if it hasn't closed, close it forcefully
2011-02-23 21:47:18 +01:00
if ( status ( ) ! = SnSR : : CLOSED )
2010-03-30 20:09:55 +02:00
close ( _sock ) ;
2011-02-23 21:47:18 +01:00
2010-03-30 20:09:55 +02:00
EthernetClass : : _server_port [ _sock ] = 0 ;
2011-02-23 21:47:18 +01:00
_sock = MAX_SOCK_NUM ;
2010-03-30 20:09:55 +02:00
}
uint8_t Client : : connected ( ) {
2011-02-23 21:47:18 +01:00
if ( _sock = = MAX_SOCK_NUM ) return 0 ;
uint8_t s = status ( ) ;
return ! ( s = = SnSR : : LISTEN | | s = = SnSR : : CLOSED | | s = = SnSR : : FIN_WAIT | |
( s = = SnSR : : CLOSE_WAIT & & ! available ( ) ) ) ;
2010-03-30 20:09:55 +02:00
}
uint8_t Client : : status ( ) {
2011-02-23 21:47:18 +01:00
if ( _sock = = MAX_SOCK_NUM ) return SnSR : : CLOSED ;
return W5100 . readSnSR ( _sock ) ;
2010-03-30 20:09:55 +02:00
}
// the next three functions are a hack so we can compare the client returned
// by Server::available() to null, or use it as the condition in an
// if-statement. this lets us stay compatible with the Processing network
// library.
uint8_t Client : : operator = = ( int p ) {
2011-02-23 21:47:18 +01:00
return _sock = = MAX_SOCK_NUM ;
2010-03-30 20:09:55 +02:00
}
uint8_t Client : : operator ! = ( int p ) {
2011-02-23 21:47:18 +01:00
return _sock ! = MAX_SOCK_NUM ;
2010-03-30 20:09:55 +02:00
}
Client : : operator bool ( ) {
2011-02-23 21:47:18 +01:00
return _sock ! = MAX_SOCK_NUM ;
2010-03-30 20:09:55 +02:00
}