2012-04-24 10:49:27 -03:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.IO.Ports;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2012-11-04 04:45:39 -04:00
|
|
|
|
using System.Management;
|
|
|
|
|
using ArdupilotMega.Utilities;
|
2012-11-27 10:06:59 -04:00
|
|
|
|
using System.Reflection;
|
2012-04-24 10:49:27 -03:00
|
|
|
|
|
|
|
|
|
namespace ArdupilotMega.Comms
|
|
|
|
|
{
|
2012-05-07 11:25:56 -03:00
|
|
|
|
public class SerialPort : System.IO.Ports.SerialPort,ICommsSerial
|
2012-04-24 10:49:27 -03:00
|
|
|
|
{
|
2012-11-09 23:16:51 -04:00
|
|
|
|
static bool serialportproblem = false;
|
|
|
|
|
|
2012-11-15 07:18:53 -04:00
|
|
|
|
protected override void Dispose(bool disposing)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2012-11-27 10:06:59 -04:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Type mytype = typeof(System.IO.Ports.SerialPort);
|
|
|
|
|
FieldInfo field = mytype.GetField("internalSerialStream", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
|
|
|
Stream stream = (Stream)field.GetValue(this);
|
|
|
|
|
|
|
|
|
|
if (stream != null)
|
|
|
|
|
{
|
|
|
|
|
stream.Dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
|
2012-11-15 07:18:53 -04:00
|
|
|
|
base.Dispose(disposing);
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-24 10:49:27 -03:00
|
|
|
|
public new void Open()
|
|
|
|
|
{
|
2012-09-19 20:37:36 -03:00
|
|
|
|
// 500ms write timeout - win32 api default
|
|
|
|
|
this.WriteTimeout = 500;
|
|
|
|
|
|
2012-04-24 10:49:27 -03:00
|
|
|
|
if (base.IsOpen)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
base.Open();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void toggleDTR()
|
|
|
|
|
{
|
2012-12-12 19:46:24 -04:00
|
|
|
|
bool open = this.IsOpen;
|
|
|
|
|
Console.WriteLine("toggleDTR " + this.IsOpen);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (!open)
|
|
|
|
|
this.Open();
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
2012-04-24 10:49:27 -03:00
|
|
|
|
|
|
|
|
|
|
2012-12-12 19:46:24 -04:00
|
|
|
|
base.DtrEnable = false;
|
|
|
|
|
base.RtsEnable = false;
|
2012-04-24 10:49:27 -03:00
|
|
|
|
|
2012-12-12 19:46:24 -04:00
|
|
|
|
System.Threading.Thread.Sleep(50);
|
2012-04-24 10:49:27 -03:00
|
|
|
|
|
2012-12-12 19:46:24 -04:00
|
|
|
|
base.DtrEnable = true;
|
|
|
|
|
base.RtsEnable = true;
|
2012-04-24 10:49:27 -03:00
|
|
|
|
|
2012-12-12 19:46:24 -04:00
|
|
|
|
System.Threading.Thread.Sleep(50);
|
2012-04-24 10:49:27 -03:00
|
|
|
|
|
2012-12-12 19:46:24 -04:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (!open)
|
|
|
|
|
this.Close();
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
Console.WriteLine("toggleDTR done " + this.IsOpen);
|
2012-04-24 10:49:27 -03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public new static string[] GetPortNames()
|
|
|
|
|
{
|
|
|
|
|
List<string> allPorts = new List<string>();
|
|
|
|
|
|
|
|
|
|
if (Directory.Exists("/dev/"))
|
|
|
|
|
{
|
|
|
|
|
if (Directory.Exists("/dev/serial/by-id/"))
|
|
|
|
|
allPorts.AddRange(Directory.GetFiles("/dev/serial/by-id/", "*"));
|
|
|
|
|
allPorts.AddRange(Directory.GetFiles("/dev/", "ttyACM*"));
|
|
|
|
|
allPorts.AddRange(Directory.GetFiles("/dev/", "ttyUSB*"));
|
2012-07-22 04:51:05 -03:00
|
|
|
|
allPorts.AddRange(Directory.GetFiles("/dev/", "rfcomm*"));
|
2012-04-24 10:49:27 -03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string[] ports = System.IO.Ports.SerialPort.GetPortNames()
|
|
|
|
|
.Select(p => p.TrimEnd())
|
|
|
|
|
.Select(FixBlueToothPortNameBug)
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
|
|
|
|
allPorts.AddRange(ports);
|
|
|
|
|
|
|
|
|
|
return allPorts.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-04 04:45:39 -04:00
|
|
|
|
internal static string GetNiceName(string port)
|
|
|
|
|
{
|
2012-11-09 23:16:51 -04:00
|
|
|
|
if (serialportproblem)
|
|
|
|
|
return "";
|
|
|
|
|
|
|
|
|
|
DateTime start = DateTime.Now;
|
2012-11-04 04:45:39 -04:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_SerialPort"); // Win32_USBControllerDevice
|
|
|
|
|
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
|
|
|
|
|
foreach (ManagementObject obj2 in searcher.Get())
|
|
|
|
|
{
|
2012-11-09 23:16:51 -04:00
|
|
|
|
//DeviceID
|
2012-11-04 04:45:39 -04:00
|
|
|
|
if (obj2.Properties["DeviceID"].Value.ToString().ToUpper() == port.ToUpper())
|
2012-11-09 23:16:51 -04:00
|
|
|
|
{
|
|
|
|
|
DateTime end = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
if ((end - start).TotalSeconds > 5)
|
|
|
|
|
serialportproblem = true;
|
|
|
|
|
|
2012-11-04 04:45:39 -04:00
|
|
|
|
return obj2.Properties["Name"].Value.ToString();
|
2012-11-09 23:16:51 -04:00
|
|
|
|
}
|
2012-11-04 04:45:39 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
2012-11-09 23:16:51 -04:00
|
|
|
|
|
2012-11-04 04:45:39 -04:00
|
|
|
|
return "";
|
|
|
|
|
}
|
2012-04-24 10:49:27 -03:00
|
|
|
|
|
|
|
|
|
// .NET bug: sometimes bluetooth ports are enumerated with bogus characters
|
|
|
|
|
// eg 'COM10' becomes 'COM10c' - one workaround is to remove the non numeric
|
|
|
|
|
// char. Annoyingly, sometimes a numeric char is added, which means this
|
|
|
|
|
// does not work in all cases.
|
|
|
|
|
// See http://connect.microsoft.com/VisualStudio/feedback/details/236183/system-io-ports-serialport-getportnames-error-with-bluetooth
|
|
|
|
|
private static string FixBlueToothPortNameBug(string portName)
|
|
|
|
|
{
|
|
|
|
|
if (!portName.StartsWith("COM"))
|
|
|
|
|
return portName;
|
|
|
|
|
var newPortName = "COM"; // Start over with "COM"
|
|
|
|
|
foreach (var portChar in portName.Substring(3).ToCharArray()) // Remove "COM", put the rest in a character array
|
|
|
|
|
{
|
|
|
|
|
if (char.IsDigit(portChar))
|
|
|
|
|
newPortName += portChar.ToString(); // Good character, append to portName
|
|
|
|
|
// else
|
|
|
|
|
//log.WarnFormat("Bad (Non Numeric) character in port name '{0}' - removing", portName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newPortName;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|