Move SerialPortCommunication to MatterControl.Printing project
This commit is contained in:
parent
3e012ca610
commit
369835d314
15 changed files with 2592 additions and 18 deletions
128
MatterControl.Printing/Communication/FoundStringCallBacks.cs
Normal file
128
MatterControl.Printing/Communication/FoundStringCallBacks.cs
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
Copyright (c) 2014, Lars Brubaker
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MatterHackers.SerialPortCommunication
|
||||
{
|
||||
public class FoundStringEventArgs : EventArgs
|
||||
{
|
||||
public bool CallbackWasCalled { get; set; }
|
||||
|
||||
private bool sendToDelegateFunctions = true;
|
||||
private string lineToCheck;
|
||||
|
||||
public FoundStringEventArgs(string lineReceived)
|
||||
{
|
||||
this.lineToCheck = lineReceived.Trim();
|
||||
}
|
||||
|
||||
public string LineToCheck { get { return lineToCheck; } }
|
||||
|
||||
public bool SendToDelegateFunctions
|
||||
{
|
||||
get
|
||||
{
|
||||
return sendToDelegateFunctions;
|
||||
}
|
||||
set
|
||||
{
|
||||
sendToDelegateFunctions = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FoundStringCallbacks
|
||||
{
|
||||
public Dictionary<string, EventHandler<FoundStringEventArgs> > dictionaryOfCallbacks = new Dictionary<string, EventHandler<FoundStringEventArgs>>();
|
||||
|
||||
public void AddCallbackToKey(string key, EventHandler<FoundStringEventArgs> value)
|
||||
{
|
||||
if (dictionaryOfCallbacks.ContainsKey(key))
|
||||
{
|
||||
dictionaryOfCallbacks[key] += value;
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionaryOfCallbacks.Add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveCallbackFromKey(string key, EventHandler<FoundStringEventArgs> value)
|
||||
{
|
||||
if (dictionaryOfCallbacks.ContainsKey(key))
|
||||
{
|
||||
if (dictionaryOfCallbacks[key] == null)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
dictionaryOfCallbacks[key] -= value;
|
||||
if (dictionaryOfCallbacks[key] == null)
|
||||
{
|
||||
dictionaryOfCallbacks.Remove(key);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FoundStringStartsWithCallbacks : FoundStringCallbacks
|
||||
{
|
||||
public void CheckForKeys(FoundStringEventArgs e)
|
||||
{
|
||||
foreach (var pair in this.dictionaryOfCallbacks)
|
||||
{
|
||||
if (e.LineToCheck.StartsWith(pair.Key))
|
||||
{
|
||||
e.CallbackWasCalled = true;
|
||||
pair.Value(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FoundStringContainsCallbacks : FoundStringCallbacks
|
||||
{
|
||||
public void CheckForKeys(FoundStringEventArgs e)
|
||||
{
|
||||
foreach (var pair in this.dictionaryOfCallbacks)
|
||||
{
|
||||
if (e.LineToCheck.Contains(pair.Key))
|
||||
{
|
||||
e.CallbackWasCalled = true;
|
||||
pair.Value(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
Copyright (c) 2014, Kevin Pope
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace MatterHackers.SerialPortCommunication.FrostedSerial
|
||||
{
|
||||
#if USE_STANDARD_SERIAL
|
||||
|
||||
public class CSharpSerialPortWrapper : IFrostedSerialPort
|
||||
{
|
||||
private System.IO.Ports.SerialPort port;
|
||||
|
||||
internal CSharpSerialPortWrapper(string serialPortName)
|
||||
{
|
||||
if (FrostedSerialPortFactory.GetAppropriateFactory("RepRap").IsWindows)
|
||||
{
|
||||
try
|
||||
{
|
||||
SerialPortFixer.Execute(serialPortName);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
port = new System.IO.Ports.SerialPort(serialPortName);
|
||||
}
|
||||
|
||||
public int ReadTimeout
|
||||
{
|
||||
get { return port.ReadTimeout; }
|
||||
set { port.ReadTimeout = value; }
|
||||
}
|
||||
|
||||
public string ReadExisting()
|
||||
{
|
||||
return port.ReadExisting();
|
||||
}
|
||||
|
||||
public int BytesToRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return port.BytesToRead;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
port.Dispose();
|
||||
}
|
||||
|
||||
public bool IsOpen
|
||||
{
|
||||
get { return port.IsOpen; }
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
port.Open();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
try
|
||||
{
|
||||
port.Close();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public int WriteTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return port.WriteTimeout;
|
||||
}
|
||||
set
|
||||
{
|
||||
port.WriteTimeout = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int BaudRate
|
||||
{
|
||||
get
|
||||
{
|
||||
return port.BaudRate;
|
||||
}
|
||||
set
|
||||
{
|
||||
port.BaudRate = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool RtsEnable
|
||||
{
|
||||
get
|
||||
{
|
||||
return port.RtsEnable;
|
||||
}
|
||||
set
|
||||
{
|
||||
port.RtsEnable = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool DtrEnable
|
||||
{
|
||||
get
|
||||
{
|
||||
return port.DtrEnable;
|
||||
}
|
||||
set
|
||||
{
|
||||
port.DtrEnable = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(string str)
|
||||
{
|
||||
port.Write(str);
|
||||
}
|
||||
|
||||
public void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
port.Write(buffer, offset, count);
|
||||
}
|
||||
|
||||
public int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
return port.Read(buffer, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,925 @@
|
|||
/*
|
||||
Copyright (c) 2014, Kevin Pope
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using MatterHackers.Agg.Platform;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace MatterHackers.SerialPortCommunication.FrostedSerial
|
||||
{
|
||||
[MonitoringDescription("")]
|
||||
[System.ComponentModel.DesignerCategory("")]
|
||||
public class FrostedSerialPort : Component, IFrostedSerialPort
|
||||
{
|
||||
public const int InfiniteTimeout = -1;
|
||||
private const int DefaultReadBufferSize = 4096;
|
||||
private const int DefaultWriteBufferSize = 2048;
|
||||
private const int DefaultBaudRate = 9600;
|
||||
private const int DefaultDataBits = 8;
|
||||
private const Parity DefaultParity = Parity.None;
|
||||
private const StopBits DefaultStopBits = StopBits.One;
|
||||
|
||||
private bool is_open;
|
||||
private int baud_rate;
|
||||
private Parity parity;
|
||||
private StopBits stop_bits;
|
||||
private Handshake handshake;
|
||||
private int data_bits;
|
||||
private bool break_state = false;
|
||||
private bool dtr_enable = false;
|
||||
private bool rts_enable = false;
|
||||
private IFrostedSerialStream stream;
|
||||
private Encoding encoding = Encoding.ASCII;
|
||||
private string new_line = Environment.NewLine;
|
||||
private string port_name;
|
||||
private int read_timeout = InfiniteTimeout;
|
||||
private int write_timeout = InfiniteTimeout;
|
||||
private int readBufferSize = DefaultReadBufferSize;
|
||||
private int writeBufferSize = DefaultWriteBufferSize;
|
||||
private object error_received = new object();
|
||||
private object data_received = new object();
|
||||
private object pin_changed = new object();
|
||||
|
||||
public FrostedSerialPort() :
|
||||
this(FrostedSerialPort.GetDefaultPortName(), DefaultBaudRate, DefaultParity, DefaultDataBits, DefaultStopBits)
|
||||
{
|
||||
}
|
||||
|
||||
public FrostedSerialPort(IContainer container)
|
||||
: this()
|
||||
{
|
||||
// TODO: What to do here?
|
||||
}
|
||||
|
||||
public FrostedSerialPort(string portName) :
|
||||
this(portName, DefaultBaudRate, DefaultParity, DefaultDataBits, DefaultStopBits)
|
||||
{
|
||||
}
|
||||
|
||||
public FrostedSerialPort(string portName, int baudRate) :
|
||||
this(portName, baudRate, DefaultParity, DefaultDataBits, DefaultStopBits)
|
||||
{
|
||||
}
|
||||
|
||||
public FrostedSerialPort(string portName, int baudRate, Parity parity) :
|
||||
this(portName, baudRate, parity, DefaultDataBits, DefaultStopBits)
|
||||
{
|
||||
}
|
||||
|
||||
public FrostedSerialPort(string portName, int baudRate, Parity parity, int dataBits) :
|
||||
this(portName, baudRate, parity, dataBits, DefaultStopBits)
|
||||
{
|
||||
}
|
||||
|
||||
public FrostedSerialPort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits)
|
||||
{
|
||||
port_name = portName;
|
||||
baud_rate = baudRate;
|
||||
data_bits = dataBits;
|
||||
stop_bits = stopBits;
|
||||
this.parity = parity;
|
||||
}
|
||||
|
||||
// On non-Android platforms simply return true as port access validation isn't applicable
|
||||
public static bool EnsureDeviceAccess()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Regex linuxDefaultUIFilter = new Regex("/dev/ttyS*\\d+", RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
||||
|
||||
private static IEnumerable<string> FilterPortsForMac(List<string> allPorts)
|
||||
{
|
||||
IEnumerable<string> filteredPorts;
|
||||
|
||||
if (AggContext.OperatingSystem == OSType.X11)
|
||||
{
|
||||
// A default and naive filter that works well on Ubuntu 14
|
||||
filteredPorts = allPorts.Where(portName => portName != "/dev/tty" && !linuxDefaultUIFilter.Match(portName).Success);
|
||||
}
|
||||
else
|
||||
{
|
||||
// looks_like_mac -- serialPort.StartsWith("/dev/tty."); looks_like_pc -- serialPort.StartsWith("COM")
|
||||
filteredPorts = allPorts.Where(portName => portName.StartsWith("/dev/tty.")
|
||||
|| portName.StartsWith("COM")
|
||||
|| portName == "Emulator");
|
||||
}
|
||||
|
||||
return filteredPorts.Any() ? filteredPorts : allPorts;
|
||||
}
|
||||
|
||||
public static bool MockPortsForTest = false;
|
||||
|
||||
public static string[] GetPortNames(bool filter = true)
|
||||
{
|
||||
var p = Environment.OSVersion.Platform;
|
||||
List<string> serial_ports = new List<string>();
|
||||
|
||||
// Are we on Unix?
|
||||
if (MockPortsForTest)
|
||||
{
|
||||
serial_ports.Add("COM-TestA");
|
||||
serial_ports.Add("COM-TestB");
|
||||
serial_ports.Add("COM-TestC");
|
||||
serial_ports.Add("COM-Test0");
|
||||
serial_ports.Add("COM-Test1");
|
||||
}
|
||||
else if (p == PlatformID.Unix || p == PlatformID.MacOSX)
|
||||
{
|
||||
string[] ttys = Directory.GetFiles("/dev/", "tty*");
|
||||
|
||||
// If filtering was not requested, return the raw listing of /dev/tty* - (subsequent filtering happens in client code)
|
||||
if (!filter)
|
||||
{
|
||||
return ttys;
|
||||
}
|
||||
|
||||
// Probe for Linux-styled devices: /dev/ttyS* or /dev/ttyUSB*
|
||||
foreach (string dev in ttys)
|
||||
{
|
||||
if (dev != "/dev/tty" && dev.StartsWith("/dev/tty") && !dev.StartsWith("/dev/ttyC"))
|
||||
{
|
||||
serial_ports.Add(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if USE_STANDARD_SERIAL
|
||||
using (RegistryKey subkey = Registry.LocalMachine.OpenSubKey("HARDWARE\\DEVICEMAP\\SERIALCOMM"))
|
||||
{
|
||||
if (subkey != null)
|
||||
{
|
||||
string[] names = subkey.GetValueNames();
|
||||
foreach (string value in names)
|
||||
{
|
||||
string port = subkey.GetValue(value, "").ToString();
|
||||
if (port != "")
|
||||
serial_ports.Add(port);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
serial_ports.Add("Emulator");
|
||||
#endif
|
||||
|
||||
return FilterPortsForMac(serial_ports).ToArray();
|
||||
}
|
||||
|
||||
public static string GetDefaultPortName()
|
||||
{
|
||||
string[] ports = FrostedSerialPort.GetPortNames();
|
||||
if (ports.Length > 0)
|
||||
{
|
||||
return ports[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if (p == 4 || p == 128 || p == 6)
|
||||
return "ttyS0"; // Default for Unix
|
||||
else
|
||||
return "COM1"; // Default for Windows
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||||
public Stream BaseStream
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckOpen();
|
||||
return (Stream)stream;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValueAttribute(DefaultBaudRate)]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
public int BaudRate
|
||||
{
|
||||
get
|
||||
{
|
||||
return baud_rate;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
if (is_open)
|
||||
stream.SetAttributes(value, parity, data_bits, stop_bits, handshake);
|
||||
|
||||
baud_rate = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||||
public bool BreakState
|
||||
{
|
||||
get
|
||||
{
|
||||
return break_state;
|
||||
}
|
||||
set
|
||||
{
|
||||
CheckOpen();
|
||||
if (value == break_state)
|
||||
return; // Do nothing.
|
||||
|
||||
stream.SetBreakState(value);
|
||||
break_state = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||||
public int BytesToRead
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckOpen();
|
||||
return stream.BytesToRead;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||||
public int BytesToWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckOpen();
|
||||
return stream.BytesToWrite;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||||
public bool CDHolding
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckOpen();
|
||||
return (stream.GetSignals() & SerialSignal.Cd) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||||
public bool CtsHolding
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckOpen();
|
||||
return (stream.GetSignals() & SerialSignal.Cts) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValueAttribute(DefaultDataBits)]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
public int DataBits
|
||||
{
|
||||
get
|
||||
{
|
||||
return data_bits;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 5 || value > 8)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
if (is_open)
|
||||
stream.SetAttributes(baud_rate, parity, value, stop_bits, handshake);
|
||||
|
||||
data_bits = value;
|
||||
}
|
||||
}
|
||||
|
||||
//[MonoTODO("Not implemented")]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
[DefaultValue(false)]
|
||||
public bool DiscardNull
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
// LAMESPEC: Msdn states that an InvalidOperationException exception
|
||||
// is fired if the port is not open, which is *not* happening.
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||||
public bool DsrHolding
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckOpen();
|
||||
return (stream.GetSignals() & SerialSignal.Dsr) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValueAttribute(false)]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
public bool DtrEnable
|
||||
{
|
||||
get
|
||||
{
|
||||
return dtr_enable;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == dtr_enable)
|
||||
return;
|
||||
if (is_open)
|
||||
stream.SetSignal(SerialSignal.Dtr, value);
|
||||
|
||||
dtr_enable = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||||
[MonitoringDescription("")]
|
||||
public Encoding Encoding
|
||||
{
|
||||
get
|
||||
{
|
||||
return encoding;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
|
||||
encoding = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValueAttribute(Handshake.None)]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
public Handshake Handshake
|
||||
{
|
||||
get
|
||||
{
|
||||
return handshake;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < Handshake.None || value > Handshake.RequestToSendXOnXOff)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
if (is_open)
|
||||
stream.SetAttributes(baud_rate, parity, data_bits, stop_bits, value);
|
||||
|
||||
handshake = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public bool IsOpen
|
||||
{
|
||||
get
|
||||
{
|
||||
return is_open;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValueAttribute("\n")]
|
||||
[Browsable(false)]
|
||||
[MonitoringDescription("")]
|
||||
public string NewLine
|
||||
{
|
||||
get
|
||||
{
|
||||
return new_line;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
if (value.Length == 0)
|
||||
throw new ArgumentException("NewLine cannot be null or empty.", "value");
|
||||
|
||||
new_line = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValueAttribute(DefaultParity)]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
public Parity Parity
|
||||
{
|
||||
get
|
||||
{
|
||||
return parity;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < Parity.None || value > Parity.Space)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
if (is_open)
|
||||
stream.SetAttributes(baud_rate, value, data_bits, stop_bits, handshake);
|
||||
|
||||
parity = value;
|
||||
}
|
||||
}
|
||||
|
||||
//[MonoTODO("Not implemented")]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
[DefaultValue(63)]
|
||||
public byte ParityReplace
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
[DefaultValue("COM1")] // silly Windows-ism. We should ignore it.
|
||||
public string PortName
|
||||
{
|
||||
get
|
||||
{
|
||||
return port_name;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (is_open)
|
||||
throw new InvalidOperationException("Port name cannot be set while port is open.");
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
if (value.Length == 0 || value.StartsWith("\\\\"))
|
||||
throw new ArgumentException("value");
|
||||
|
||||
port_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValueAttribute(DefaultReadBufferSize)]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
public int ReadBufferSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return readBufferSize;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (is_open)
|
||||
throw new InvalidOperationException();
|
||||
if (value <= 0)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
if (value <= DefaultReadBufferSize)
|
||||
return;
|
||||
|
||||
readBufferSize = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValueAttribute(InfiniteTimeout)]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
public int ReadTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return read_timeout;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0 && value != InfiniteTimeout)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
if (is_open)
|
||||
stream.ReadTimeout = value;
|
||||
|
||||
read_timeout = value;
|
||||
}
|
||||
}
|
||||
|
||||
//[MonoTODO("Not implemented")]
|
||||
[DefaultValueAttribute(1)]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
public int ReceivedBytesThreshold
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValueAttribute(false)]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
public bool RtsEnable
|
||||
{
|
||||
get
|
||||
{
|
||||
return rts_enable;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == rts_enable)
|
||||
return;
|
||||
if (is_open)
|
||||
stream.SetSignal(SerialSignal.Rts, value);
|
||||
|
||||
rts_enable = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValueAttribute(DefaultStopBits)]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
public StopBits StopBits
|
||||
{
|
||||
get
|
||||
{
|
||||
return stop_bits;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < StopBits.One || value > StopBits.OnePointFive)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
if (is_open)
|
||||
stream.SetAttributes(baud_rate, parity, data_bits, value, handshake);
|
||||
|
||||
stop_bits = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValueAttribute(DefaultWriteBufferSize)]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
public int WriteBufferSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return writeBufferSize;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (is_open)
|
||||
throw new InvalidOperationException();
|
||||
if (value <= 0)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
if (value <= DefaultWriteBufferSize)
|
||||
return;
|
||||
|
||||
writeBufferSize = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValueAttribute(InfiniteTimeout)]
|
||||
[Browsable(true)]
|
||||
[MonitoringDescription("")]
|
||||
public int WriteTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return write_timeout;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0 && value != InfiniteTimeout)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
if (is_open)
|
||||
stream.WriteTimeout = value;
|
||||
|
||||
write_timeout = value;
|
||||
}
|
||||
}
|
||||
|
||||
// methods
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!is_open)
|
||||
return;
|
||||
|
||||
is_open = false;
|
||||
// Do not close the base stream when the finalizer is run; the managed code can still hold a reference to it.
|
||||
if (disposing)
|
||||
stream.Close();
|
||||
stream = null;
|
||||
}
|
||||
|
||||
public void DiscardInBuffer()
|
||||
{
|
||||
CheckOpen();
|
||||
stream.DiscardInBuffer();
|
||||
}
|
||||
|
||||
public void DiscardOutBuffer()
|
||||
{
|
||||
CheckOpen();
|
||||
stream.DiscardOutBuffer();
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
if (is_open)
|
||||
throw new InvalidOperationException("Port is already open");
|
||||
|
||||
stream = new FrostedSerialPortStream(port_name, baud_rate, data_bits, parity, stop_bits, dtr_enable,
|
||||
rts_enable, handshake, read_timeout, write_timeout, readBufferSize, writeBufferSize);
|
||||
|
||||
is_open = true;
|
||||
}
|
||||
|
||||
public int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
CheckOpen();
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException("buffer");
|
||||
if (offset < 0 || count < 0)
|
||||
throw new ArgumentOutOfRangeException("offset or count less than zero.");
|
||||
|
||||
if (buffer.Length - offset < count)
|
||||
throw new ArgumentException("offset+count",
|
||||
"The size of the buffer is less than offset + count.");
|
||||
|
||||
return stream.Read(buffer, offset, count);
|
||||
}
|
||||
|
||||
public int Read(char[] buffer, int offset, int count)
|
||||
{
|
||||
CheckOpen();
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException("buffer");
|
||||
if (offset < 0 || count < 0)
|
||||
throw new ArgumentOutOfRangeException("offset or count less than zero.");
|
||||
|
||||
if (buffer.Length - offset < count)
|
||||
throw new ArgumentException("offset+count",
|
||||
"The size of the buffer is less than offset + count.");
|
||||
|
||||
int c, i;
|
||||
for (i = 0; i < count && (c = ReadChar()) != -1; i++)
|
||||
buffer[offset + i] = (char)c;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
internal int read_byte()
|
||||
{
|
||||
byte[] buff = new byte[1];
|
||||
if (stream.Read(buff, 0, 1) > 0)
|
||||
return buff[0];
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int ReadByte()
|
||||
{
|
||||
CheckOpen();
|
||||
return read_byte();
|
||||
}
|
||||
|
||||
public int ReadChar()
|
||||
{
|
||||
CheckOpen();
|
||||
|
||||
byte[] buffer = new byte[16];
|
||||
int i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
int b = read_byte();
|
||||
if (b == -1)
|
||||
return -1;
|
||||
buffer[i++] = (byte)b;
|
||||
char[] c = encoding.GetChars(buffer, 0, 1);
|
||||
if (c.Length > 0)
|
||||
return (int)c[0];
|
||||
} while (i < buffer.Length);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public string ReadExisting()
|
||||
{
|
||||
CheckOpen();
|
||||
|
||||
int count = BytesToRead;
|
||||
byte[] bytes = new byte[count];
|
||||
|
||||
int n = stream.Read(bytes, 0, count);
|
||||
return new String(encoding.GetChars(bytes, 0, n));
|
||||
}
|
||||
|
||||
public string ReadLine()
|
||||
{
|
||||
return ReadTo(new_line);
|
||||
}
|
||||
|
||||
public string ReadTo(string value)
|
||||
{
|
||||
CheckOpen();
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
if (value.Length == 0)
|
||||
throw new ArgumentException("value");
|
||||
|
||||
// Turn into byte array, so we can compare
|
||||
byte[] byte_value = encoding.GetBytes(value);
|
||||
int current = 0;
|
||||
List<byte> seen = new List<byte>();
|
||||
|
||||
while (true)
|
||||
{
|
||||
int n = read_byte();
|
||||
if (n == -1)
|
||||
break;
|
||||
seen.Add((byte)n);
|
||||
if (n == byte_value[current])
|
||||
{
|
||||
current++;
|
||||
if (current == byte_value.Length)
|
||||
return encoding.GetString(seen.ToArray(), 0, seen.Count - byte_value.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
current = (byte_value[0] == n) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
return encoding.GetString(seen.ToArray());
|
||||
}
|
||||
|
||||
public void Write(string str)
|
||||
{
|
||||
CheckOpen();
|
||||
if (str == null)
|
||||
throw new ArgumentNullException("str");
|
||||
|
||||
byte[] buffer = encoding.GetBytes(str);
|
||||
Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
public void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
CheckOpen();
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException("buffer");
|
||||
|
||||
if (offset < 0 || count < 0)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
if (buffer.Length - offset < count)
|
||||
throw new ArgumentException("offset+count",
|
||||
"The size of the buffer is less than offset + count.");
|
||||
|
||||
stream.Write(buffer, offset, count);
|
||||
}
|
||||
|
||||
public void Write(char[] buffer, int offset, int count)
|
||||
{
|
||||
CheckOpen();
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException("buffer");
|
||||
|
||||
if (offset < 0 || count < 0)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
if (buffer.Length - offset < count)
|
||||
throw new ArgumentException("offset+count",
|
||||
"The size of the buffer is less than offset + count.");
|
||||
|
||||
byte[] bytes = encoding.GetBytes(buffer, offset, count);
|
||||
stream.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
public void WriteLine(string str)
|
||||
{
|
||||
Write(str + new_line);
|
||||
}
|
||||
|
||||
private void CheckOpen()
|
||||
{
|
||||
if (!is_open)
|
||||
throw new InvalidOperationException("Specified port is not open.");
|
||||
}
|
||||
|
||||
internal void OnErrorReceived(SerialErrorReceivedEventArgs args)
|
||||
{
|
||||
SerialErrorReceivedEventHandler handler =
|
||||
(SerialErrorReceivedEventHandler)Events[error_received];
|
||||
|
||||
if (handler != null)
|
||||
handler(this, args);
|
||||
}
|
||||
|
||||
internal void OnDataReceived(SerialDataReceivedEventArgs args)
|
||||
{
|
||||
SerialDataReceivedEventHandler handler =
|
||||
(SerialDataReceivedEventHandler)Events[data_received];
|
||||
|
||||
if (handler != null)
|
||||
handler(this, args);
|
||||
}
|
||||
|
||||
internal void OnDataReceived(SerialPinChangedEventArgs args)
|
||||
{
|
||||
SerialPinChangedEventHandler handler =
|
||||
(SerialPinChangedEventHandler)Events[pin_changed];
|
||||
|
||||
if (handler != null)
|
||||
handler(this, args);
|
||||
}
|
||||
|
||||
// events
|
||||
[MonitoringDescription("")]
|
||||
public event SerialErrorReceivedEventHandler ErrorReceived
|
||||
{
|
||||
add { Events.AddHandler(error_received, value); }
|
||||
remove { Events.RemoveHandler(error_received, value); }
|
||||
}
|
||||
|
||||
[MonitoringDescription("")]
|
||||
public event SerialPinChangedEventHandler PinChanged
|
||||
{
|
||||
add { Events.AddHandler(pin_changed, value); }
|
||||
remove { Events.RemoveHandler(pin_changed, value); }
|
||||
}
|
||||
|
||||
[MonitoringDescription("")]
|
||||
public event SerialDataReceivedEventHandler DataReceived
|
||||
{
|
||||
add { Events.AddHandler(data_received, value); }
|
||||
remove { Events.RemoveHandler(data_received, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
Copyright (c) 2014, Kevin Pope
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.Platform;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace MatterHackers.SerialPortCommunication.FrostedSerial
|
||||
{
|
||||
public class FrostedSerialPortFactory
|
||||
{
|
||||
[DllImport("SetSerial", SetLastError = true)]
|
||||
private static extern int set_baud(string portName, int baud_rate);
|
||||
|
||||
static Dictionary<string, FrostedSerialPortFactory> availableFactories = new Dictionary<string,FrostedSerialPortFactory>();
|
||||
|
||||
public static FrostedSerialPortFactory GetAppropriateFactory(string driverType)
|
||||
{
|
||||
lock(availableFactories)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (availableFactories.Count == 0)
|
||||
{
|
||||
// always add a serial port this is a raw port
|
||||
availableFactories.Add("Raw", new FrostedSerialPortFactory());
|
||||
|
||||
// add in any plugins that we find with other factories.
|
||||
var portFactories = PluginFinder.CreateInstancesOf<FrostedSerialPortFactory>();
|
||||
|
||||
foreach (FrostedSerialPortFactory plugin in portFactories)
|
||||
{
|
||||
availableFactories.Add(plugin.GetDriverType(), plugin);
|
||||
}
|
||||
|
||||
// If we did not find a RepRap driver add the default.
|
||||
if (!availableFactories.ContainsKey("RepRap"))
|
||||
{
|
||||
availableFactories.Add("RepRap", new FrostedSerialPortFactory());
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(driverType)
|
||||
&& availableFactories.ContainsKey(driverType))
|
||||
{
|
||||
return availableFactories[driverType];
|
||||
}
|
||||
|
||||
return availableFactories["RepRap"];
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new FrostedSerialPortFactory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual protected string GetDriverType()
|
||||
{
|
||||
return "RepRap";
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr securityAttrs, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
|
||||
|
||||
//Windows-only function
|
||||
public virtual bool SerialPortAlreadyOpen(string portName)
|
||||
{
|
||||
if (AggContext.OperatingSystem == OSType.Windows)
|
||||
{
|
||||
const int dwFlagsAndAttributes = 0x40000000;
|
||||
const int GENERIC_READ = unchecked((int)0x80000000);
|
||||
const int GENERIC_WRITE = 0x40000000;
|
||||
|
||||
//Borrowed from Microsoft's Serial Port Open Method :)
|
||||
using (SafeFileHandle hFile = CreateFile(@"\\.\" + portName, GENERIC_READ | GENERIC_WRITE, 0, IntPtr.Zero, 3, dwFlagsAndAttributes, IntPtr.Zero))
|
||||
{
|
||||
hFile.Close();
|
||||
return hFile.IsInvalid;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected FrostedSerialPortFactory()
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsWindows
|
||||
{
|
||||
get
|
||||
{
|
||||
PlatformID id = Environment.OSVersion.Platform;
|
||||
return id == PlatformID.Win32Windows || id == PlatformID.Win32NT; // WinCE not supported
|
||||
}
|
||||
}
|
||||
|
||||
public virtual IFrostedSerialPort Create(string serialPortName)
|
||||
{
|
||||
#if __ANDROID__
|
||||
//Create an instance of a FrostedSerialPort
|
||||
IFrostedSerialPort newPort = null;
|
||||
newPort = new FrostedSerialPort(serialPortName);
|
||||
return newPort;
|
||||
#else
|
||||
IFrostedSerialPort newPort = null;
|
||||
// if we can find a mac helper class (to get us 250k)
|
||||
string appBundle = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
|
||||
if (File.Exists(Path.Combine(appBundle, "libFrostedSerialHelper.dylib")))
|
||||
{
|
||||
// use it
|
||||
newPort = new FrostedSerialPort(serialPortName);
|
||||
}
|
||||
else // use the c# native serial port
|
||||
{
|
||||
#if USE_STANDARD_SERIAL
|
||||
newPort = new CSharpSerialPortWrapper(serialPortName);
|
||||
#endif
|
||||
}
|
||||
|
||||
return newPort;
|
||||
#endif // ANDROID
|
||||
}
|
||||
|
||||
public virtual IFrostedSerialPort CreateAndOpen(string serialPortName, int baudRate, bool DtrEnableOnConnect)
|
||||
{
|
||||
#if __ANDROID__
|
||||
//Create an instance of a FrostedSerialPort and open it
|
||||
IFrostedSerialPort newPort = Create(serialPortName);
|
||||
|
||||
newPort.BaudRate = baudRate;
|
||||
if (DtrEnableOnConnect)
|
||||
{
|
||||
newPort.DtrEnable = true;
|
||||
}
|
||||
|
||||
// Set the read/write timeouts
|
||||
newPort.ReadTimeout = 500;
|
||||
newPort.WriteTimeout = 500;
|
||||
newPort.Open();
|
||||
|
||||
return newPort;
|
||||
#else
|
||||
IFrostedSerialPort newPort = Create(serialPortName);
|
||||
|
||||
bool isLinux = !(newPort is FrostedSerialPort) && !IsWindows;
|
||||
bool customBaudAssignment = isLinux && baudRate > 115200;
|
||||
|
||||
// Only set serial port .BaudRate when not using Linux workaround
|
||||
if (!customBaudAssignment)
|
||||
{
|
||||
newPort.BaudRate = baudRate;
|
||||
}
|
||||
|
||||
if (DtrEnableOnConnect)
|
||||
{
|
||||
newPort.DtrEnable = true;
|
||||
}
|
||||
|
||||
// Set the read/write timeouts
|
||||
newPort.ReadTimeout = 500;
|
||||
newPort.WriteTimeout = 500;
|
||||
|
||||
newPort.Open();
|
||||
|
||||
if (customBaudAssignment)
|
||||
{
|
||||
// Once mono has enforced its ANSI baud rate policy(in SerialPort.Open), reset the baud rate to the user specified
|
||||
// value by calling set_baud in libSetSerial.so
|
||||
set_baud(serialPortName, baudRate);
|
||||
}
|
||||
|
||||
return newPort;
|
||||
#endif // ANDROID
|
||||
}
|
||||
|
||||
public virtual bool SerialPortIsAvailable(string serialPortName)
|
||||
{
|
||||
try
|
||||
{
|
||||
return FrostedSerialPort.GetPortNames().Any(portName => string.Compare(portName, serialPortName, true) == 0);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,531 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MatterHackers.SerialPortCommunication.FrostedSerial
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public unsafe struct tDeviceInfo
|
||||
{
|
||||
public uint c_iflag;
|
||||
public uint c_oflag;
|
||||
public uint c_cflag;
|
||||
public uint c_lflag;
|
||||
|
||||
public fixed byte c_cc[20];
|
||||
public uint c_ispeed;
|
||||
public uint c_ospeed;
|
||||
}
|
||||
|
||||
internal class FrostedSerialPortStream : Stream, IFrostedSerialStream, IDisposable
|
||||
{
|
||||
private int fd;
|
||||
private int read_timeout;
|
||||
private int write_timeout;
|
||||
private bool disposed;
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern int open_serial(string portName);
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern int set_attributes(int fd, int baudRate, Parity parity, int dataBits, StopBits stopBits, Handshake handshake);
|
||||
|
||||
public FrostedSerialPortStream(string portName, int baudRate, int dataBits, Parity parity, StopBits stopBits,
|
||||
bool dtrEnable, bool rtsEnable, Handshake handshake, int readTimeout, int writeTimeout,
|
||||
int readBufferSize, int writeBufferSize)
|
||||
{
|
||||
fd = open_serial(portName);
|
||||
if (fd == -1)
|
||||
{
|
||||
ThrowIOException();
|
||||
}
|
||||
|
||||
TryBaudRate(baudRate);
|
||||
|
||||
int canSetAttributes = set_attributes(fd, baudRate, parity, dataBits, stopBits, handshake);
|
||||
|
||||
if (canSetAttributes != 0)
|
||||
{
|
||||
throw new IOException(canSetAttributes.ToString()); // Probably Win32Exc for compatibility
|
||||
}
|
||||
|
||||
read_timeout = readTimeout;
|
||||
write_timeout = writeTimeout;
|
||||
|
||||
SetSignal(SerialSignal.Dtr, dtrEnable);
|
||||
|
||||
if (handshake != Handshake.RequestToSend &&
|
||||
handshake != Handshake.RequestToSendXOnXOff)
|
||||
{
|
||||
SetSignal(SerialSignal.Rts, rtsEnable);
|
||||
}
|
||||
}
|
||||
|
||||
private int SetupBaudRate(int baudRate)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern int tcgetattr(int fd, tDeviceInfo newtio);
|
||||
|
||||
private int TCGetAttribute(int fd, tDeviceInfo newtio)
|
||||
{
|
||||
int result = tcgetattr(fd, newtio);
|
||||
return result;
|
||||
}
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern int tcsetattr(int fd, uint optional_actions, tDeviceInfo newtio);
|
||||
|
||||
private int TCSetAttribute(int fd, uint optional_actions, tDeviceInfo newtio)
|
||||
{
|
||||
return tcsetattr(fd, optional_actions, newtio);
|
||||
}
|
||||
|
||||
private int CFSetISpeed(tDeviceInfo newtio, int baudRate)
|
||||
{
|
||||
newtio.c_ispeed = (uint)baudRate;
|
||||
return (int)newtio.c_ispeed;
|
||||
}
|
||||
|
||||
private int CFSetOSpeed(tDeviceInfo newtio, int baudRate)
|
||||
{
|
||||
newtio.c_ospeed = (uint)baudRate;
|
||||
return (int)newtio.c_ospeed;
|
||||
}
|
||||
|
||||
private bool SetFrostedAttributes(int fd, int baudRate, Parity parity, int dataBits, StopBits stopBits, Handshake handshake)
|
||||
{
|
||||
tDeviceInfo newtio = new tDeviceInfo();
|
||||
if (TCGetAttribute(fd, newtio) == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
newtio.c_cflag |= (uint)(e_c_oflag.CLOCAL | e_c_oflag.CREAD);
|
||||
// there is no defenition for e_c_lflag.ECHOL that I can find. It was in the list of or'ed flags below
|
||||
unchecked
|
||||
{
|
||||
newtio.c_lflag &= (uint)-(int)(e_c_lflag.ICANON | e_c_lflag.ECHO | e_c_lflag.ECHOE | e_c_lflag.ECHOK | e_c_lflag.ECHONL | e_c_lflag.ISIG | e_c_lflag.IEXTEN);
|
||||
}
|
||||
newtio.c_oflag &= (uint)(e_c_oflag.OPOST);
|
||||
newtio.c_iflag = (uint)e_c_iflag.IGNBRK;
|
||||
|
||||
baudRate = SetupBaudRate(baudRate);
|
||||
|
||||
unchecked
|
||||
{
|
||||
newtio.c_cflag &= (uint)-(uint)e_c_oflag.CSIZE;
|
||||
}
|
||||
|
||||
switch (dataBits)
|
||||
{
|
||||
case 5:
|
||||
newtio.c_cflag |= (uint)e_c_oflag.CS5;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
newtio.c_cflag |= (uint)e_c_oflag.CS6;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
newtio.c_cflag |= (uint)e_c_oflag.CS6;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
default:
|
||||
newtio.c_cflag |= (uint)e_c_oflag.CS8;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (stopBits)
|
||||
{
|
||||
case StopBits.None:
|
||||
break;
|
||||
|
||||
case StopBits.One:
|
||||
unchecked
|
||||
{
|
||||
newtio.c_cflag &= (uint)-(uint)e_c_oflag.CSTOPB;
|
||||
}
|
||||
break;
|
||||
|
||||
case StopBits.Two:
|
||||
newtio.c_cflag |= (uint)e_c_oflag.CSTOPB;
|
||||
break;
|
||||
|
||||
case StopBits.OnePointFive:
|
||||
break;
|
||||
}
|
||||
|
||||
unchecked
|
||||
{
|
||||
newtio.c_iflag &= (uint)-(uint)(e_c_iflag.INPCK | e_c_iflag.ISTRIP);
|
||||
}
|
||||
|
||||
switch (parity)
|
||||
{
|
||||
case Parity.None: /* None */
|
||||
newtio.c_cflag &= ~(uint)(e_c_oflag.PARENB | e_c_oflag.PARODD);
|
||||
break;
|
||||
|
||||
case Parity.Odd: /* Odd */
|
||||
newtio.c_cflag |= (uint)(e_c_oflag.PARENB | e_c_oflag.PARODD);
|
||||
break;
|
||||
|
||||
case Parity.Even: /* Even */
|
||||
newtio.c_cflag &= ~(uint)(e_c_oflag.PARODD);
|
||||
newtio.c_cflag |= (uint)(e_c_oflag.PARENB);
|
||||
break;
|
||||
|
||||
case Parity.Mark: /* Mark */
|
||||
/* XXX unhandled */
|
||||
break;
|
||||
|
||||
case Parity.Space: /* Space */
|
||||
/* XXX unhandled */
|
||||
break;
|
||||
}
|
||||
|
||||
newtio.c_iflag &= ~(uint)(e_c_iflag.IXOFF | e_c_iflag.IXON);
|
||||
#if CRTSCTS
|
||||
newtio.c_cflag &= ~CRTSCTS;
|
||||
#endif //* def CRTSCTS */
|
||||
|
||||
switch (handshake)
|
||||
{
|
||||
case Handshake.None: /* None */
|
||||
/* do nothing */
|
||||
break;
|
||||
|
||||
case Handshake.RequestToSend: /* RequestToSend (RTS) */
|
||||
#if CRTSCTS
|
||||
newtio.c_cflag |= CRTSCTS;
|
||||
#endif //* def CRTSCTS */
|
||||
break;
|
||||
|
||||
case Handshake.RequestToSendXOnXOff: /* RequestToSendXOnXOff (RTS + XON/XOFF) */
|
||||
#if CRTSCTS
|
||||
newtio.c_cflag |= CRTSCTS;
|
||||
#endif //* def CRTSCTS */
|
||||
/* fall through */
|
||||
case Handshake.XOnXOff: /* XOnXOff */
|
||||
newtio.c_iflag |= (uint)(e_c_iflag.IXOFF | e_c_iflag.IXON);
|
||||
break;
|
||||
}
|
||||
|
||||
if (CFSetOSpeed(newtio, baudRate) < 0 || CFSetISpeed(newtio, baudRate) < 0 ||
|
||||
TCSetAttribute(fd, (uint)e_tcsetaatr.TCSANOW, newtio) < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//return set_attributes(fd, baudRate, parity, dataBits, sb, hs);
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override int ReadTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return read_timeout;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0 && value != FrostedSerialPort.InfiniteTimeout)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
read_timeout = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override int WriteTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return write_timeout;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0 && value != FrostedSerialPort.InfiniteTimeout)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
write_timeout = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
// If used, this _could_ flush the serial port
|
||||
// buffer (not the SerialPort class buffer)
|
||||
}
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern int read_serial(int fd, byte[] buffer, int offset, int count);
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern bool poll_serial(int fd, out int error, int timeout);
|
||||
|
||||
public override int Read([In, Out] byte[] buffer, int offset, int count)
|
||||
{
|
||||
CheckDisposed();
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException("buffer");
|
||||
if (offset < 0 || count < 0)
|
||||
throw new ArgumentOutOfRangeException("offset or count less than zero.");
|
||||
|
||||
if (buffer.Length - offset < count)
|
||||
throw new ArgumentException("offset+count",
|
||||
"The size of the buffer is less than offset + count.");
|
||||
|
||||
int error;
|
||||
bool poll_result = poll_serial(fd, out error, read_timeout);
|
||||
if (error == -1)
|
||||
ThrowIOException();
|
||||
|
||||
if (!poll_result)
|
||||
{
|
||||
// see bug 79735 http://bugzilla.ximian.com/show_bug.cgi?id=79735
|
||||
// should the next line read: return -1;
|
||||
throw new TimeoutException();
|
||||
}
|
||||
|
||||
int result = read_serial(fd, buffer, offset, count);
|
||||
if (result == -1)
|
||||
ThrowIOException();
|
||||
return result;
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern int write_serial(int fd, byte[] buffer, int offset, int count, int timeout);
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
CheckDisposed();
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException("buffer");
|
||||
|
||||
if (offset < 0 || count < 0)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
if (buffer.Length - offset < count)
|
||||
throw new ArgumentException("offset+count",
|
||||
"The size of the buffer is less than offset + count.");
|
||||
|
||||
// FIXME: this reports every write error as timeout
|
||||
if (write_serial(fd, buffer, offset, count, write_timeout) < 0)
|
||||
throw new TimeoutException("The operation has timed-out");
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed)
|
||||
return;
|
||||
|
||||
disposed = true;
|
||||
if (close_serial(fd) != 0)
|
||||
{
|
||||
//Don't do anything
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern int close_serial(int fd);
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
((IDisposable)this).Dispose();
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~FrostedSerialPortStream()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
private void CheckDisposed()
|
||||
{
|
||||
if (disposed)
|
||||
throw new ObjectDisposedException(GetType().FullName);
|
||||
}
|
||||
|
||||
public void SetAttributes(int baud_rate, Parity parity, int data_bits, StopBits sb, Handshake hs)
|
||||
{
|
||||
if (!SetFrostedAttributes(fd, baud_rate, parity, data_bits, sb, hs))
|
||||
ThrowIOException();
|
||||
}
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern int get_bytes_in_buffer(int fd, int input);
|
||||
|
||||
public int BytesToRead
|
||||
{
|
||||
get
|
||||
{
|
||||
int result = get_bytes_in_buffer(fd, 1);
|
||||
if (result == -1)
|
||||
ThrowIOException();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public int BytesToWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
int result = get_bytes_in_buffer(fd, 0);
|
||||
if (result == -1)
|
||||
ThrowIOException();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern int discard_buffer(int fd, bool inputBuffer);
|
||||
|
||||
public void DiscardInBuffer()
|
||||
{
|
||||
if (discard_buffer(fd, true) != 0)
|
||||
ThrowIOException();
|
||||
}
|
||||
|
||||
public void DiscardOutBuffer()
|
||||
{
|
||||
if (discard_buffer(fd, false) != 0)
|
||||
ThrowIOException();
|
||||
}
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern SerialSignal get_signals(int fd, out int error);
|
||||
|
||||
public SerialSignal GetSignals()
|
||||
{
|
||||
int error;
|
||||
SerialSignal signals = get_signals(fd, out error);
|
||||
if (error == -1)
|
||||
ThrowIOException();
|
||||
|
||||
return signals;
|
||||
}
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern int set_signal(int fd, SerialSignal signal, bool value);
|
||||
|
||||
public void SetSignal(SerialSignal signal, bool value)
|
||||
{
|
||||
if (signal < SerialSignal.Cd || signal > SerialSignal.Rts ||
|
||||
signal == SerialSignal.Cd ||
|
||||
signal == SerialSignal.Cts ||
|
||||
signal == SerialSignal.Dsr)
|
||||
throw new Exception("Invalid internal value");
|
||||
|
||||
if (set_signal(fd, signal, value) == -1)
|
||||
ThrowIOException();
|
||||
}
|
||||
|
||||
[DllImport("FrostedSerialHelper", SetLastError = true)]
|
||||
private static extern int breakprop(int fd);
|
||||
|
||||
public void SetBreakState(bool value)
|
||||
{
|
||||
if (value)
|
||||
if (breakprop(fd) == -1)
|
||||
ThrowIOException();
|
||||
}
|
||||
|
||||
[DllImport("libc")]
|
||||
private static extern IntPtr strerror(int errnum);
|
||||
|
||||
private static void ThrowIOException()
|
||||
{
|
||||
int errnum = Marshal.GetLastWin32Error();
|
||||
string error_message = Marshal.PtrToStringAnsi(strerror(errnum));
|
||||
|
||||
throw new IOException(error_message);
|
||||
}
|
||||
|
||||
[DllImport("FrostedSerialHelper")]
|
||||
private static extern bool is_baud_rate_legal(int baud_rate);
|
||||
|
||||
private void TryBaudRate(int baudRate)
|
||||
{
|
||||
if (!is_baud_rate_legal(baudRate))
|
||||
{
|
||||
// this kind of exception to be compatible with MSDN API
|
||||
throw new ArgumentOutOfRangeException("baudRate",
|
||||
"Given baud rate is not supported on this platform.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
Copyright (c) 2014, Kevin Pope
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace MatterHackers.SerialPortCommunication.FrostedSerial
|
||||
{
|
||||
public delegate void SerialDataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e);
|
||||
|
||||
public delegate void SerialPinChangedEventHandler(object sender, SerialPinChangedEventArgs e);
|
||||
|
||||
public delegate void SerialErrorReceivedEventHandler(object sender, SerialErrorReceivedEventArgs e);
|
||||
|
||||
public interface IFrostedSerialPort
|
||||
{
|
||||
bool RtsEnable { get; set; }
|
||||
|
||||
bool DtrEnable { get; set; }
|
||||
|
||||
int BaudRate { get; set; }
|
||||
|
||||
int BytesToRead { get; }
|
||||
|
||||
void Write(string str);
|
||||
|
||||
void Write(byte[] buffer, int offset, int count);
|
||||
|
||||
int WriteTimeout { get; set; }
|
||||
|
||||
int ReadTimeout { get; set; }
|
||||
|
||||
string ReadExisting();
|
||||
|
||||
int Read(byte[] buffer, int offset, int count);
|
||||
|
||||
bool IsOpen { get; }
|
||||
|
||||
void Open();
|
||||
|
||||
void Close();
|
||||
|
||||
void Dispose();
|
||||
}
|
||||
|
||||
internal enum SerialSignal
|
||||
{
|
||||
None = 0,
|
||||
Cd = 1, // Carrier detect
|
||||
Cts = 2, // Clear to send
|
||||
Dsr = 4, // Data set ready
|
||||
Dtr = 8, // Data terminal ready
|
||||
Rts = 16 // Request to send
|
||||
}
|
||||
|
||||
public enum Handshake
|
||||
{
|
||||
None,
|
||||
XOnXOff,
|
||||
RequestToSend,
|
||||
RequestToSendXOnXOff
|
||||
}
|
||||
|
||||
public enum StopBits
|
||||
{
|
||||
None,
|
||||
One,
|
||||
Two,
|
||||
OnePointFive
|
||||
}
|
||||
|
||||
public enum Parity
|
||||
{
|
||||
None,
|
||||
Odd,
|
||||
Even,
|
||||
Mark,
|
||||
Space
|
||||
}
|
||||
|
||||
public enum SerialError
|
||||
{
|
||||
RXOver = 1,
|
||||
Overrun = 2,
|
||||
RXParity = 4,
|
||||
Frame = 8,
|
||||
TXFull = 256
|
||||
}
|
||||
|
||||
public enum SerialData
|
||||
{
|
||||
Chars = 1,
|
||||
Eof
|
||||
}
|
||||
|
||||
public enum SerialPinChange
|
||||
{
|
||||
CtsChanged = 8,
|
||||
DsrChanged = 16,
|
||||
CDChanged = 32,
|
||||
Break = 64,
|
||||
Ring = 256
|
||||
}
|
||||
|
||||
public class SerialDataReceivedEventArgs : EventArgs
|
||||
{
|
||||
internal SerialDataReceivedEventArgs(SerialData eventType)
|
||||
{
|
||||
this.eventType = eventType;
|
||||
}
|
||||
|
||||
// properties
|
||||
|
||||
public SerialData EventType
|
||||
{
|
||||
get
|
||||
{
|
||||
return eventType;
|
||||
}
|
||||
}
|
||||
|
||||
private SerialData eventType;
|
||||
}
|
||||
|
||||
public class SerialPinChangedEventArgs : EventArgs
|
||||
{
|
||||
internal SerialPinChangedEventArgs(SerialPinChange eventType)
|
||||
{
|
||||
this.eventType = eventType;
|
||||
}
|
||||
|
||||
// properties
|
||||
|
||||
public SerialPinChange EventType
|
||||
{
|
||||
get
|
||||
{
|
||||
return eventType;
|
||||
}
|
||||
}
|
||||
|
||||
private SerialPinChange eventType;
|
||||
}
|
||||
|
||||
public class SerialErrorReceivedEventArgs : EventArgs
|
||||
{
|
||||
internal SerialErrorReceivedEventArgs(SerialError eventType)
|
||||
{
|
||||
this.eventType = eventType;
|
||||
}
|
||||
|
||||
// properties
|
||||
|
||||
public SerialError EventType
|
||||
{
|
||||
get
|
||||
{
|
||||
return eventType;
|
||||
}
|
||||
}
|
||||
|
||||
private SerialError eventType;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
|
||||
namespace MatterHackers.SerialPortCommunication.FrostedSerial
|
||||
{
|
||||
internal interface IFrostedSerialStream : IDisposable
|
||||
{
|
||||
int Read(byte[] buffer, int offset, int count);
|
||||
|
||||
void Write(byte[] buffer, int offset, int count);
|
||||
|
||||
void SetAttributes(int baud_rate, Parity parity, int data_bits, StopBits sb, Handshake hs);
|
||||
|
||||
void DiscardInBuffer();
|
||||
|
||||
void DiscardOutBuffer();
|
||||
|
||||
SerialSignal GetSignals();
|
||||
|
||||
void SetSignal(SerialSignal signal, bool value);
|
||||
|
||||
void SetBreakState(bool value);
|
||||
|
||||
void Close();
|
||||
|
||||
int BytesToRead { get; }
|
||||
|
||||
int BytesToWrite { get; }
|
||||
|
||||
int ReadTimeout { get; set; }
|
||||
|
||||
int WriteTimeout { get; set; }
|
||||
}
|
||||
}
|
||||
218
MatterControl.Printing/Communication/SerialPortFixer.cs
Normal file
218
MatterControl.Printing/Communication/SerialPortFixer.cs
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
// Copyright 2010-2014 Zach Saw
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace MatterHackers.SerialPortCommunication.FrostedSerial
|
||||
{
|
||||
public class SerialPortFixer : IDisposable
|
||||
{
|
||||
public static void Execute(string portName)
|
||||
{
|
||||
using (new SerialPortFixer(portName))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (m_Handle != null)
|
||||
{
|
||||
m_Handle.Close();
|
||||
m_Handle = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion IDisposable Members
|
||||
|
||||
#region Implementation
|
||||
|
||||
private const int DcbFlagAbortOnError = 14;
|
||||
private const int CommStateRetries = 10;
|
||||
private SafeFileHandle m_Handle;
|
||||
|
||||
private SerialPortFixer(string portName)
|
||||
{
|
||||
const int dwFlagsAndAttributes = 0x40000000;
|
||||
const int dwAccess = unchecked((int)0xC0000000);
|
||||
|
||||
if ((portName == null) || !portName.StartsWith("COM", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new ArgumentException("Invalid Serial Port", "portName");
|
||||
}
|
||||
SafeFileHandle hFile = CreateFile(@"\\.\" + portName, dwAccess, 0, IntPtr.Zero, 3, dwFlagsAndAttributes, IntPtr.Zero);
|
||||
|
||||
if (hFile.IsInvalid)
|
||||
{
|
||||
WinIoError();
|
||||
}
|
||||
try
|
||||
{
|
||||
int fileType = GetFileType(hFile);
|
||||
if ((fileType != 2) && (fileType != 0))
|
||||
{
|
||||
throw new ArgumentException("Invalid Serial Port", "portName");
|
||||
}
|
||||
m_Handle = hFile;
|
||||
InitializeDcb();
|
||||
}
|
||||
catch
|
||||
{
|
||||
hFile.Close();
|
||||
m_Handle = null;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern int FormatMessage(int dwFlags, HandleRef lpSource, int dwMessageId, int dwLanguageId,
|
||||
StringBuilder lpBuffer, int nSize, IntPtr arguments);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern bool GetCommState(SafeFileHandle hFile, ref Dcb lpDcb);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern bool SetCommState(SafeFileHandle hFile, ref Dcb lpDcb);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern bool ClearCommError(SafeFileHandle hFile, ref int lpErrors, ref Comstat lpStat);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode,
|
||||
IntPtr securityAttrs, int dwCreationDisposition,
|
||||
int dwFlagsAndAttributes, IntPtr hTemplateFile);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern int GetFileType(SafeFileHandle hFile);
|
||||
|
||||
private void InitializeDcb()
|
||||
{
|
||||
Dcb dcb = new Dcb();
|
||||
GetCommStateNative(ref dcb);
|
||||
dcb.Flags &= ~(1u << DcbFlagAbortOnError);
|
||||
SetCommStateNative(ref dcb);
|
||||
}
|
||||
|
||||
private static string GetMessage(int errorCode)
|
||||
{
|
||||
StringBuilder lpBuffer = new StringBuilder(0x200);
|
||||
if (
|
||||
FormatMessage(0x3200, new HandleRef(null, IntPtr.Zero), errorCode, 0, lpBuffer, lpBuffer.Capacity,
|
||||
IntPtr.Zero) != 0)
|
||||
{
|
||||
return lpBuffer.ToString();
|
||||
}
|
||||
return "Unknown Error";
|
||||
}
|
||||
|
||||
private static int MakeHrFromErrorCode(int errorCode)
|
||||
{
|
||||
return (int)(0x80070000 | (uint)errorCode);
|
||||
}
|
||||
|
||||
private static void WinIoError()
|
||||
{
|
||||
int errorCode = Marshal.GetLastWin32Error();
|
||||
throw new IOException(GetMessage(errorCode), MakeHrFromErrorCode(errorCode));
|
||||
}
|
||||
|
||||
private void GetCommStateNative(ref Dcb lpDcb)
|
||||
{
|
||||
int commErrors = 0;
|
||||
Comstat comStat = new Comstat();
|
||||
|
||||
for (int i = 0; i < CommStateRetries; i++)
|
||||
{
|
||||
if (!ClearCommError(m_Handle, ref commErrors, ref comStat))
|
||||
{
|
||||
WinIoError();
|
||||
}
|
||||
if (GetCommState(m_Handle, ref lpDcb))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (i == CommStateRetries - 1)
|
||||
{
|
||||
WinIoError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCommStateNative(ref Dcb lpDcb)
|
||||
{
|
||||
int commErrors = 0;
|
||||
Comstat comStat = new Comstat();
|
||||
|
||||
for (int i = 0; i < CommStateRetries; i++)
|
||||
{
|
||||
if (!ClearCommError(m_Handle, ref commErrors, ref comStat))
|
||||
{
|
||||
WinIoError();
|
||||
}
|
||||
if (SetCommState(m_Handle, ref lpDcb))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (i == CommStateRetries - 1)
|
||||
{
|
||||
WinIoError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Nested type: COMSTAT
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct Comstat
|
||||
{
|
||||
public readonly uint Flags;
|
||||
public readonly uint cbInQue;
|
||||
public readonly uint cbOutQue;
|
||||
}
|
||||
|
||||
#endregion Nested type: COMSTAT
|
||||
|
||||
#region Nested type: DCB
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct Dcb
|
||||
{
|
||||
public readonly uint DCBlength;
|
||||
public readonly uint BaudRate;
|
||||
public uint Flags;
|
||||
public readonly ushort wReserved;
|
||||
public readonly ushort XonLim;
|
||||
public readonly ushort XoffLim;
|
||||
public readonly byte ByteSize;
|
||||
public readonly byte Parity;
|
||||
public readonly byte StopBits;
|
||||
public readonly byte XonChar;
|
||||
public readonly byte XoffChar;
|
||||
public readonly byte ErrorChar;
|
||||
public readonly byte EofChar;
|
||||
public readonly byte EvtChar;
|
||||
public readonly ushort wReserved1;
|
||||
}
|
||||
|
||||
#endregion Nested type: DCB
|
||||
|
||||
#endregion Implementation
|
||||
}
|
||||
}
|
||||
158
MatterControl.Printing/Communication/TermiosH.cs
Normal file
158
MatterControl.Printing/Communication/TermiosH.cs
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
using System;
|
||||
|
||||
namespace MatterHackers.SerialPortCommunication.FrostedSerial
|
||||
{
|
||||
public enum e_cc_c
|
||||
{
|
||||
/* Indices into c_cc array. Default values in parentheses. POSIX Table 7-5. */
|
||||
VEOF = 0, /* cc_c[VEOF] = EOF char (^D) */
|
||||
VEOL = 1, /* cc_c[VEOL] = EOL char (undef) */
|
||||
VERASE = 2, /* cc_c[VERASE] = ERASE char (^H) */
|
||||
VINTR = 3, /* cc_c[VINTR] = INTR char (DEL) */
|
||||
VKILL = 4, /* cc_c[VKILL] = KILL char (^U) */
|
||||
VMIN = 5, /* cc_c[VMIN] = MIN value for timer */
|
||||
VQUIT = 6, /* cc_c[VQUIT] = QUIT char (^\) */
|
||||
VTIME = 7, /* cc_c[VTIME] = TIME value for timer */
|
||||
VSUSP = 8, /* cc_c[VSUSP] = SUSP (^Z, ignored) */
|
||||
VSTART = 9, /* cc_c[VSTART] = START char (^S) */
|
||||
VSTOP = 10, /* cc_c[VSTOP] = STOP char (^Q) */
|
||||
//_POSIX_VDISABLE =(cc_t)0xFF, /* You can't even generate this /*
|
||||
/* character with 'normal' keyboards.
|
||||
* But some language specific keyboards
|
||||
* can generate 0xFF. It seems that all
|
||||
* 256 are used, so cc_t should be a
|
||||
* short...
|
||||
*/
|
||||
|
||||
SIZE = 20, /* size of cc_c array, some extra space * for extensions. */
|
||||
};
|
||||
|
||||
/* Values for termios c_iflag bit map. POSIX Table 7-2. */
|
||||
|
||||
[Flags]
|
||||
public enum e_c_iflag
|
||||
{
|
||||
BRKINT = 0x0001, /* signal interrupt on break */
|
||||
ICRNL = 0x0002, /* map CR to NL on input */
|
||||
IGNBRK = 0x0004, /* ignore break */
|
||||
IGNCR = 0x0008, /* ignore CR */
|
||||
IGNPAR = 0x0010, /* ignore characters with parity errors */
|
||||
INLCR = 0x0020, /* map NL to CR on input */
|
||||
INPCK = 0x0040, /* enable input parity check */
|
||||
ISTRIP = 0x0080, /* mask off 8th bit */
|
||||
IXOFF = 0x0100, /* enable start/stop input control */
|
||||
IXON = 0x0200, /* enable start/stop output control */
|
||||
PARMRK = 0x0400, /* mark parity errors in the input queue */
|
||||
};
|
||||
|
||||
/* Values for termios c_oflag bit map. POSIX Sec. 7.1.2.3. */
|
||||
|
||||
[Flags]
|
||||
public enum e_c_oflag
|
||||
{
|
||||
OPOST = 0x0001, /* perform output processing */
|
||||
|
||||
/* Values for termios c_cflag bit map. POSIX Table 7-3. */
|
||||
CLOCAL = 0x0001, /* ignore modem status lines */
|
||||
CREAD = 0x0002, /* enable receiver */
|
||||
CSIZE = 0x000C, /* number of bits per character */
|
||||
CS5 = 0x0000, /* if CSIZE is CS5, characters are 5 bits */
|
||||
CS6 = 0x0004, /* if CSIZE is CS6, characters are 6 bits */
|
||||
CS7 = 0x0008, /* if CSIZE is CS7, characters are 7 bits */
|
||||
CS8 = 0x000C, /* if CSIZE is CS8, characters are 8 bits */
|
||||
CSTOPB = 0x0010, /* send 2 stop bits if set, else 1 */
|
||||
HUPCL = 0x0020, /* hang up on last close */
|
||||
PARENB = 0x0040, /* enable parity on output */
|
||||
PARODD = 0x0080, /* use odd parity if set, else even */
|
||||
};
|
||||
|
||||
/* Values for termios c_lflag bit map. POSIX Table 7-4. */
|
||||
|
||||
[Flags]
|
||||
public enum e_c_lflag
|
||||
{
|
||||
ECHO = 0x0001, /* enable echoing of input characters */
|
||||
ECHOE = 0x0002, /* echo ERASE as backspace */
|
||||
ECHOK = 0x0004, /* echo KILL */
|
||||
ECHONL = 0x0008, /* echo NL */
|
||||
ICANON = 0x0010, /* canonical input (erase and kill enabled) */
|
||||
IEXTEN = 0x0020, /* enable extended functions */
|
||||
ISIG = 0x0040, /* enable signals */
|
||||
NOFLSH = 0x0080, /* disable flush after interrupt or quit */
|
||||
TOSTOP = 0x0100, /* send SIGTTOU (job control, not implemented*/
|
||||
};
|
||||
|
||||
/* Values for the baud rate settings. POSIX Table 7-6. */
|
||||
|
||||
[Flags]
|
||||
public enum e_baud_rate
|
||||
{
|
||||
B0 = 0x0000, /* hang up the line */
|
||||
B50 = 0x1000, /* 50 baud */
|
||||
B75 = 0x2000, /* 75 baud */
|
||||
B110 = 0x3000, /* 110 baud */
|
||||
B134 = 0x4000, /* 134.5 baud */
|
||||
B150 = 0x5000, /* 150 baud */
|
||||
B200 = 0x6000, /* 200 baud */
|
||||
B300 = 0x7000, /* 300 baud */
|
||||
B600 = 0x8000, /* 600 baud */
|
||||
B1200 = 0x9000, /* 1200 baud */
|
||||
B1800 = 0xA000, /* 1800 baud */
|
||||
B2400 = 0xB000, /* 2400 baud */
|
||||
B4800 = 0xC000, /* 4800 baud */
|
||||
B9600 = 0xD000, /* 9600 baud */
|
||||
B19200 = 0xE000, /* 19200 baud */
|
||||
B38400 = 0xF000, /* 38400 baud */
|
||||
};
|
||||
|
||||
/* Optional actions for tcsetattr(). POSIX Sec. 7.2.1.2. */
|
||||
|
||||
[Flags]
|
||||
public enum e_tcsetaatr
|
||||
{
|
||||
TCSANOW = 1, /* changes take effect immediately */
|
||||
TCSADRAIN = 2, /* changes take effect after output is done */
|
||||
TCSAFLUSH = 3, /* wait for output to finish and flush input */
|
||||
};
|
||||
|
||||
/* Queue_selector values for tcflush(). POSIX Sec. 7.2.2.2. */
|
||||
|
||||
[Flags]
|
||||
public enum e_tcflush
|
||||
{
|
||||
TCIFLUSH = 1, /* flush accumulated input data */
|
||||
TCOFLUSH = 2, /* flush accumulated output data */
|
||||
TCIOFLUSH = 3, /* flush accumulated input and output data */
|
||||
};
|
||||
|
||||
/* Action values for tcflow(). POSIX Sec. 7.2.2.2. */
|
||||
|
||||
[Flags]
|
||||
public enum e_tcflow
|
||||
{
|
||||
TCOOFF = 1, /* suspend output */
|
||||
TCOON = 2, /* restart suspended output */
|
||||
TCIOFF = 3, /* transmit a STOP character on the line */
|
||||
TCION = 4, /* transmit a START character on the line */
|
||||
};
|
||||
|
||||
internal static class testCLass
|
||||
{
|
||||
private static void TestFunc()
|
||||
{
|
||||
uint c_cflag = 0;
|
||||
uint c_lflag = 0;
|
||||
uint c_oflag = 0;
|
||||
//uint c_iflag = 0;
|
||||
c_cflag |= (uint)(e_c_oflag.CLOCAL | e_c_oflag.CREAD);
|
||||
//c_lflag &= (uint)-(e_c_lflag.ICANON | e_c_lflag.ECHO | e_c_lflag.ECHOE | e_c_lflag.ECHOK | e_c_lflag.ECHOL | e_c_lflag.ECHONL | e_c_lflag.ISIG | e_c_lflag.IEXTEN);
|
||||
// not supported in docs I can find ECHOL
|
||||
unchecked
|
||||
{
|
||||
c_lflag &= (uint)-(uint)(e_c_lflag.ICANON | e_c_lflag.ECHO | e_c_lflag.ECHOE | e_c_lflag.ECHOK | e_c_lflag.ECHONL | e_c_lflag.ISIG | e_c_lflag.IEXTEN);
|
||||
}
|
||||
c_oflag &= (uint)(e_c_oflag.OPOST);
|
||||
//c_iflag = (uint)e_c_iflag.IGNBRK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,16 +17,17 @@
|
|||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG;USE_STANDARD_SERIAL</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DefineConstants>TRACE;USE_STANDARD_SERIAL</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
|
|
@ -45,6 +46,15 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Communication\FoundStringCallBacks.cs" />
|
||||
<Compile Include="Communication\FrostedSerial\CSharpSerialPortWrapper.cs" />
|
||||
<Compile Include="Communication\FrostedSerial\FrostedSerialPort.cs" />
|
||||
<Compile Include="Communication\FrostedSerial\FrostedSerialPortFactory.cs" />
|
||||
<Compile Include="Communication\FrostedSerial\FrostedSerialStream.cs" />
|
||||
<Compile Include="Communication\FrostedSerial\IFrostedSerialPort.cs" />
|
||||
<Compile Include="Communication\FrostedSerial\IFrostedSerialStream.cs" />
|
||||
<Compile Include="Communication\SerialPortFixer.cs" />
|
||||
<Compile Include="Communication\TermiosH.cs" />
|
||||
<Compile Include="GCode\GCodeFile.cs" />
|
||||
<Compile Include="GCode\GCodeMemoryFile.cs" />
|
||||
<Compile Include="GCode\GCodeFileStreamed.cs" />
|
||||
|
|
|
|||
|
|
@ -583,10 +583,6 @@
|
|||
<Project>{D3E41B4E-BFBB-44CA-94C8-95C00F754FDD}</Project>
|
||||
<Name>VectorMath</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="Submodules\agg-sharp\SerialPortCommunication\SerialPortCommunication.csproj">
|
||||
<Project>{D3ABF72C-64C2-4E51-A119-E077210FA990}</Project>
|
||||
<Name>SerialPortCommunication</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="Submodules\MatterSlice\MatterSlice.csproj">
|
||||
<Project>{C46CA728-DD2F-4DD1-971A-AAA89D9DFF95}</Project>
|
||||
<Name>MatterSlice</Name>
|
||||
|
|
|
|||
|
|
@ -79,9 +79,9 @@
|
|||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Submodules\agg-sharp\SerialPortCommunication\SerialPortCommunication.csproj">
|
||||
<Project>{D3ABF72C-64C2-4E51-A119-E077210FA990}</Project>
|
||||
<Name>SerialPortCommunication</Name>
|
||||
<ProjectReference Include="..\MatterControl.Printing\MatterControl.Printing.csproj">
|
||||
<Project>{97d5ade3-c1b4-4b46-8a3e-718a4f7f079f}</Project>
|
||||
<Name>MatterControl.Printing</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 95e733a96dd969922769292967959a339964c92b
|
||||
Subproject commit dbe5a9eb4460cc7950927a51304ef2678e1b872b
|
||||
|
|
@ -86,6 +86,10 @@
|
|||
<Project>{0b8d6f56-bd7f-4426-b858-d9292b084656}</Project>
|
||||
<Name>MatterControl</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\MatterControl.Printing\MatterControl.Printing.csproj">
|
||||
<Project>{97d5ade3-c1b4-4b46-8a3e-718a4f7f079f}</Project>
|
||||
<Name>MatterControl.Printing</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\PrinterEmulator\PrinterEmulator.csproj">
|
||||
<Project>{bb58ca42-991b-41b7-bde7-dcd2911df8b9}</Project>
|
||||
<Name>PrinterEmulator</Name>
|
||||
|
|
@ -118,10 +122,6 @@
|
|||
<Project>{545B6912-77FF-4B34-BA76-6C3D6A32BE6A}</Project>
|
||||
<Name>RenderOpenGl</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Submodules\agg-sharp\SerialPortCommunication\SerialPortCommunication.csproj">
|
||||
<Project>{D3ABF72C-64C2-4E51-A119-E077210FA990}</Project>
|
||||
<Name>SerialPortCommunication</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Submodules\agg-sharp\Tests\Agg.Tests\Agg.Tests.csproj">
|
||||
<Project>{195cbe56-e654-437b-ab05-3be1b9452497}</Project>
|
||||
<Name>Agg.Tests</Name>
|
||||
|
|
|
|||
|
|
@ -131,10 +131,6 @@
|
|||
<Project>{545b6912-77ff-4b34-ba76-6c3d6a32be6a}</Project>
|
||||
<Name>RenderOpenGl</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Submodules\agg-sharp\SerialPortCommunication\SerialPortCommunication.csproj">
|
||||
<Project>{D3ABF72C-64C2-4E51-A119-E077210FA990}</Project>
|
||||
<Name>SerialPortCommunication</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Submodules\agg-sharp\Tests\Agg.Tests\Agg.Tests.csproj">
|
||||
<Project>{195CBE56-E654-437B-AB05-3BE1B9452497}</Project>
|
||||
<Name>Agg.Tests</Name>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue