2012-02-26 19:13:23 -04:00
using System.Reflection ;
2011-09-08 22:31:32 -03:00
using System.Text ;
using System.Net ; // dns, ip address
using System.Net.Sockets ; // tcplistner
2012-02-26 19:13:23 -04:00
using log4net ;
2012-03-01 09:27:03 -04:00
using ArdupilotMega.Controls ;
2011-09-08 22:31:32 -03:00
namespace System.IO.Ports
{
public class UdpSerial : ArdupilotMega . ICommsSerial
{
2012-02-26 19:13:23 -04:00
private static readonly ILog log = LogManager . GetLogger ( MethodBase . GetCurrentMethod ( ) . DeclaringType ) ;
2011-09-08 22:31:32 -03:00
UdpClient client = new UdpClient ( ) ;
IPEndPoint RemoteIpEndPoint = new IPEndPoint ( IPAddress . Any , 0 ) ;
byte [ ] rbuffer = new byte [ 0 ] ;
int rbufferread = 0 ;
public int WriteBufferSize { get ; set ; }
public int WriteTimeout { get ; set ; }
public int ReceivedBytesThreshold { get ; set ; }
public bool RtsEnable { get ; set ; }
~ UdpSerial ( )
{
this . Close ( ) ;
client = null ;
}
public UdpSerial ( )
{
//System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
//System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
Port = "14550" ;
}
2011-12-29 06:31:42 -04:00
public void toggleDTR ( )
{
}
2011-09-08 22:31:32 -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-01 09:27:03 -04:00
public bool IsOpen { get { if ( client . Client = = null ) return false ; return client . Client . Connected ; } }
2011-09-08 22:31:32 -03:00
public bool DtrEnable
{
get ;
set ;
}
public void Open ( )
{
if ( client . Client . Connected )
{
2012-02-26 19:13:23 -04:00
log . Info ( "udpserial socket already open" ) ;
2011-09-08 22:31:32 -03:00
return ;
}
2012-03-01 09:27:03 -04:00
ProgressReporterDialogue frmProgressReporter = new ProgressReporterDialogue
{
StartPosition = System . Windows . Forms . FormStartPosition . CenterScreen ,
Text = "Connecting Mavlink UDP"
} ;
frmProgressReporter . DoWork + = frmProgressReporter_DoWork ;
frmProgressReporter . UpdateProgressAndStatus ( - 1 , "Connecting Mavlink UDP" ) ;
2012-03-03 20:42:42 -04:00
ArdupilotMega . ThemeManager . ApplyThemeTo ( frmProgressReporter ) ;
2012-03-01 09:27:03 -04:00
frmProgressReporter . RunBackgroundOperationAsync ( ) ;
}
void frmProgressReporter_DoWork ( object sender , ArdupilotMega . Controls . ProgressWorkerEventArgs e )
{
2011-09-08 22:31:32 -03:00
string dest = Port ;
2012-03-01 09:27:03 -04:00
if ( ArdupilotMega . MainV2 . config [ "UDP_port" ] ! = null )
dest = ArdupilotMega . MainV2 . config [ "UDP_port" ] . ToString ( ) ;
2011-09-08 22:31:32 -03:00
ArdupilotMega . Common . InputBox ( "Listern Port" , "Enter Local port (ensure remote end is already sending)" , ref dest ) ;
Port = dest ;
2012-03-01 09:27:03 -04:00
ArdupilotMega . MainV2 . config [ "UDP_port" ] = Port ;
2011-09-08 22:31:32 -03:00
client = new UdpClient ( int . Parse ( Port ) ) ;
2012-03-01 09:27:03 -04:00
while ( true )
{
( ( ProgressReporterDialogue ) sender ) . UpdateProgressAndStatus ( - 1 , "Waiting for UDP" ) ;
System . Threading . Thread . Sleep ( 500 ) ;
if ( ( ( ProgressReporterDialogue ) sender ) . doWorkArgs . CancelRequested )
{
( ( ProgressReporterDialogue ) sender ) . doWorkArgs . CancelAcknowledged = true ;
try
{
client . Close ( ) ;
}
catch { }
return ;
}
if ( BytesToRead > 0 )
break ;
}
if ( BytesToRead = = 0 )
return ;
2011-09-22 09:32:43 -03:00
2011-09-08 22:31:32 -03:00
try
{
client . Receive ( ref RemoteIpEndPoint ) ;
2012-02-26 19:13:23 -04:00
log . InfoFormat ( "NetSerial connecting to {0} : {1}" , RemoteIpEndPoint . Address , RemoteIpEndPoint . Port ) ;
2011-09-08 22:31:32 -03:00
client . Connect ( RemoteIpEndPoint ) ;
}
2012-03-01 09:27:03 -04:00
catch ( Exception ex )
{
2012-02-26 19:13:23 -04:00
if ( client ! = null & & client . Client . Connected )
{
client . Close ( ) ;
}
2012-03-01 09:27:03 -04:00
log . Info ( ex . ToString ( ) ) ;
2012-03-09 11:18:12 -04:00
System . Windows . Forms . CustomMessageBox . Show ( "Please check your Firewall settings\nPlease try running this command\n1. Run the following command in an elevated command prompt to disable Windows Firewall temporarily:\n \nNetsh advfirewall set allprofiles state off\n \nNote: This is just for test; please turn it back on with the command 'Netsh advfirewall set allprofiles state on'.\n" ) ;
2011-09-08 22:31:32 -03:00
throw new Exception ( "The socket/serialproxy is closed " + e ) ;
}
}
void VerifyConnected ( )
{
if ( client = = null | | ! IsOpen )
{
throw new Exception ( "The socket/serialproxy is closed" ) ;
}
}
public int Read ( byte [ ] readto , int offset , int length )
{
VerifyConnected ( ) ;
try
{
if ( length < 1 ) { return 0 ; }
if ( rbufferread = = rbuffer . Length )
{
2011-12-21 09:29:37 -04:00
MemoryStream r = new MemoryStream ( ) ;
while ( client . Available > 0 )
{
Byte [ ] b = client . Receive ( ref RemoteIpEndPoint ) ;
r . Write ( b , 0 , b . Length ) ;
}
rbuffer = r . ToArray ( ) ;
2011-09-08 22:31:32 -03:00
rbufferread = 0 ;
}
Array . Copy ( rbuffer , rbufferread , readto , offset , length ) ;
rbufferread + = length ;
return length ;
}
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 . Send ( write , length ) ;
}
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 ( "UdpSerial DiscardInBuffer {0}" , size ) ;
2011-09-08 22:31:32 -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 ( )
{
2012-03-01 09:27:03 -04:00
if ( client . Client ! = null & & client . Client . Connected )
2011-09-08 22:31:32 -03:00
{
client . Client . Close ( ) ;
client . Close ( ) ;
}
client = new UdpClient ( ) ;
}
}
}