2011-10-12 10:37:39 -03:00
using System ;
using System.Collections.Generic ;
using System.ComponentModel ;
2012-02-26 19:13:23 -04:00
using System.Reflection ;
2011-10-12 10:37:39 -03:00
using System.Text ;
using System.IO.Ports ;
using System.Threading ;
using System.Net ; // dns, ip address
using System.Net.Sockets ; // tcplistner
2012-02-26 19:13:23 -04:00
using log4net ;
2011-10-12 10:37:39 -03:00
2012-04-24 10:49:27 -03:00
namespace ArdupilotMega.Comms
2011-10-12 10:37:39 -03:00
{
2012-04-24 10:49:27 -03:00
public class TcpSerial : ArdupilotMega . Comms . ICommsSerial
2011-10-12 10:37:39 -03:00
{
2012-02-26 19:13:23 -04:00
private static readonly ILog log = LogManager . GetLogger ( MethodBase . GetCurrentMethod ( ) . DeclaringType ) ;
2011-10-12 10:37:39 -03:00
TcpClient client = new TcpClient ( ) ;
IPEndPoint RemoteIpEndPoint = new IPEndPoint ( IPAddress . Any , 0 ) ;
byte [ ] rbuffer = new byte [ 0 ] ;
int rbufferread = 0 ;
2012-03-21 09:13:08 -03:00
int retrys = 3 ;
2011-10-12 10:37:39 -03:00
public int WriteBufferSize { get ; set ; }
public int WriteTimeout { get ; set ; }
public bool RtsEnable { get ; set ; }
~ TcpSerial ( )
{
this . Close ( ) ;
client = null ;
}
public TcpSerial ( )
{
//System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
//System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
Port = "5760" ;
}
2011-12-29 06:31:42 -04:00
public void toggleDTR ( )
{
}
2011-10-12 10:37:39 -03:00
public string Port { get ; set ; }
public int ReadTimeout
{
get ; // { return client.ReceiveTimeout; }
set ; // { client.ReceiveTimeout = value; }
}
public int ReadBufferSize { get ; set ; }
public int BaudRate { get ; set ; }
public StopBits StopBits { get ; set ; }
public Parity Parity { get ; set ; }
public int DataBits { get ; set ; }
public string PortName { get ; set ; }
public int BytesToRead
{
get { return client . Available + rbuffer . Length - rbufferread ; }
}
2012-03-28 09:45:16 -03:00
public int BytesToWrite { get { return 0 ; } }
2011-11-19 20:17:17 -04:00
public bool IsOpen { get { try { return client . Client . Connected ; } catch { return false ; } } }
2011-10-12 10:37:39 -03:00
public bool DtrEnable
{
get ;
set ;
}
public void Open ( )
{
if ( client . Client . Connected )
{
2012-02-26 19:13:23 -04:00
log . Warn ( "tcpserial socket already open" ) ;
2011-10-12 10:37:39 -03:00
return ;
}
string dest = Port ;
string host = "127.0.0.1" ;
2012-03-01 09:27:03 -04:00
if ( ArdupilotMega . MainV2 . config [ "TCP_port" ] ! = null )
dest = ArdupilotMega . MainV2 . config [ "TCP_port" ] . ToString ( ) ;
if ( ArdupilotMega . MainV2 . config [ "TCP_host" ] ! = null )
host = ArdupilotMega . MainV2 . config [ "TCP_host" ] . ToString ( ) ;
2012-04-24 10:49:27 -03:00
if ( System . Windows . Forms . DialogResult . Cancel = = ArdupilotMega . Common . InputBox ( "remote host" , "Enter host name/ip (ensure remote end is already started)" , ref host ) )
2011-10-29 00:34:38 -03:00
{
2012-02-20 07:30:47 -04:00
throw new Exception ( "Canceled by request" ) ;
2011-10-29 00:34:38 -03:00
}
2012-04-24 10:49:27 -03:00
if ( System . Windows . Forms . DialogResult . Cancel = = ArdupilotMega . Common . InputBox ( "remote Port" , "Enter remote port" , ref dest ) )
2011-10-29 00:34:38 -03:00
{
2012-02-20 07:30:47 -04:00
throw new Exception ( "Canceled by request" ) ;
2011-10-29 00:34:38 -03:00
}
2011-10-12 10:37:39 -03:00
Port = dest ;
2012-03-01 09:27:03 -04:00
ArdupilotMega . MainV2 . config [ "TCP_port" ] = Port ;
ArdupilotMega . MainV2 . config [ "TCP_host" ] = host ;
2011-10-12 10:37:39 -03:00
client = new TcpClient ( host , int . Parse ( Port ) ) ;
client . NoDelay = true ;
client . Client . NoDelay = true ;
2012-02-20 07:30:47 -04:00
VerifyConnected ( ) ;
2011-10-12 10:37:39 -03:00
return ;
}
void VerifyConnected ( )
{
if ( client = = null | | ! IsOpen )
{
2011-11-19 20:17:17 -04:00
try
{
client . Close ( ) ;
}
catch { }
2012-03-21 09:13:08 -03:00
// this should only happen if we have established a connection in the first place
if ( client ! = null & & retrys > 0 )
{
client . Connect ( ArdupilotMega . MainV2 . config [ "TCP_host" ] . ToString ( ) , int . Parse ( ArdupilotMega . MainV2 . config [ "TCP_port" ] . ToString ( ) ) ) ;
retrys - - ;
}
2011-10-12 10:37:39 -03:00
throw new Exception ( "The socket/serialproxy is closed" ) ;
}
}
public int Read ( byte [ ] readto , int offset , int length )
{
VerifyConnected ( ) ;
try
{
if ( length < 1 ) { return 0 ; }
return client . Client . Receive ( readto , offset , length , SocketFlags . None ) ;
}
catch { throw new Exception ( "Socket Closed" ) ; }
}
public int ReadByte ( )
{
VerifyConnected ( ) ;
int count = 0 ;
while ( this . BytesToRead = = 0 )
{
System . Threading . Thread . Sleep ( 1 ) ;
if ( count > ReadTimeout )
throw new Exception ( "NetSerial Timeout on read" ) ;
count + + ;
}
byte [ ] buffer = new byte [ 1 ] ;
Read ( buffer , 0 , 1 ) ;
return buffer [ 0 ] ;
}
public int ReadChar ( )
{
return ReadByte ( ) ;
}
public string ReadExisting ( )
{
VerifyConnected ( ) ;
byte [ ] data = new byte [ client . Available ] ;
if ( data . Length > 0 )
Read ( data , 0 , data . Length ) ;
string line = Encoding . ASCII . GetString ( data , 0 , data . Length ) ;
return line ;
}
public void WriteLine ( string line )
{
VerifyConnected ( ) ;
line = line + "\n" ;
Write ( line ) ;
}
public void Write ( string line )
{
VerifyConnected ( ) ;
byte [ ] data = new System . Text . ASCIIEncoding ( ) . GetBytes ( line ) ;
Write ( data , 0 , data . Length ) ;
}
public void Write ( byte [ ] write , int offset , int length )
{
VerifyConnected ( ) ;
try
{
client . Client . Send ( write , length , SocketFlags . None ) ;
}
catch { } //throw new Exception("Comport / Socket Closed"); }
}
public void DiscardInBuffer ( )
{
VerifyConnected ( ) ;
int size = client . Available ;
byte [ ] crap = new byte [ size ] ;
2012-02-26 19:13:23 -04:00
log . InfoFormat ( "TcpSerial DiscardInBuffer {0}" , size ) ;
2011-10-12 10:37:39 -03:00
Read ( crap , 0 , size ) ;
}
public string ReadLine ( ) {
byte [ ] temp = new byte [ 4000 ] ;
int count = 0 ;
int timeout = 0 ;
while ( timeout < = 100 )
{
if ( ! this . IsOpen ) { break ; }
if ( this . BytesToRead > 0 )
{
byte letter = ( byte ) this . ReadByte ( ) ;
temp [ count ] = letter ;
if ( letter = = '\n' ) // normal line
{
break ;
}
count + + ;
if ( count = = temp . Length )
break ;
timeout = 0 ;
} else {
timeout + + ;
System . Threading . Thread . Sleep ( 5 ) ;
}
}
Array . Resize < byte > ( ref temp , count + 1 ) ;
return Encoding . ASCII . GetString ( temp , 0 , temp . Length ) ;
}
public void Close ( )
{
2011-11-19 20:17:17 -04:00
try
{
if ( client . Client . Connected )
{
client . Client . Close ( ) ;
client . Close ( ) ;
}
}
catch { }
try
2011-10-12 10:37:39 -03:00
{
client . Close ( ) ;
}
2011-11-19 20:17:17 -04:00
catch { }
2011-10-12 10:37:39 -03:00
client = new TcpClient ( ) ;
}
}
}