/// <summary>Creates a SerialDeviceEndpoint from a valid connection string.</summary> /// <param name="connectionString">The connection string.</param> /// <returns>A populated <see cref="SerialDeviceEndpoint" />.</returns> /// <exception cref="ArgumentException"></exception> /// <remarks> /// <para> /// Valid connection strings must match the following regular expression grammar: /// <code lang="regex"> /// ^((COM|com)\d{1,3})(:((\d{3,7})(,(None|Even|Odd|Mark|Space))?(,(7|8))?(,(Zero|OnePointFive|One|Two))?(,(nodtr|dtr))?(,(norts|rts))?(,(None|XOnXOff|RequestToSend|RequestToSendXOnXOff))?)?)?$ /// </code> /// </para> /// <para> /// Since that is a rather unfriendly expression to human eyes, one way to determine correct /// connection string syntax is to create a specimen endpoint, passing in the required /// configuration as constructor parameters. Then, write the object to an output stream. The /// ToString method will write out a syntactically correct connection string. There are many /// ways to accomplish this. For example, you can use the C# Interactive window in Visual /// Studio, write a unit test, use Windows PowerShell or an utility such as LINQPad. In /// LINQPad, the following fragment will suffice: /// <code lang="csharp"> /// var endpoint = new SerialDeviceEndpoint("COM1"); // Pass in whatever parameters you need /// endpoint.Dump(); /// </code> /// </para> /// <para> /// It is probably best to avoid creating connection strings directly as this will tend to be /// error prone, especially if it is from user-supplied input. Instead, create a user interface /// that gathers all of the serial parameters from the user. For an ASCOM driver, this will /// likely be part of the Setup Dialog. Save all the user-supplied data in your settings. Then /// generate a connection string by creating a <see cref="SerialDeviceEndpoint" />, passing the /// user settings in as constructor parameters. Finally, use <see cref="ToString" /> or the /// <see cref="DeviceEndpoint.DeviceAddress" /> property to retrieve the corresponding /// connection string. The connection string can either be saved along with user settings and /// used 'as-is' in the next session, or it can be dynamically regenerated on demand using the /// above technique - the choice is yours. It is also up to you whether or not you decide to /// make the connection string visible to the user. /// </para> /// </remarks> public static SerialDeviceEndpoint FromConnectionString(string connectionString) { Contract.Requires(!string.IsNullOrWhiteSpace(connectionString)); Contract.Ensures(Contract.Result <DeviceEndpoint>() != null); var matches = SerialRegex.Match(connectionString); if (!matches.Success) { throw new ArgumentException( "Not a valid serial connection string; Example: COM127:9600,None,8,One,dtr,norts", nameof(connectionString)); } var portName = matches.Groups["PortName"].Value; var baud = CaptureGroupOrDefault(matches, "Baud", 9600); var parity = CaptureGroupOrDefault(matches, "Parity", Parity.None); var databits = CaptureGroupOrDefault(matches, "DataBits", 8); var stopbits = CaptureGroupOrDefault(matches, "StopBits", StopBits.One); var assertDtr = CaptureGroupOrDefault(matches, "DTR", "dtr") .Equals("dtr", StringComparison.InvariantCultureIgnoreCase); var assertRts = CaptureGroupOrDefault(matches, "RTS", "rts") .Equals("rts", StringComparison.InvariantCultureIgnoreCase); var handshake = CaptureGroupOrDefault(matches, "Handshake", Handshake.None); var endpoint = new SerialDeviceEndpoint(portName, baud, parity, databits, stopbits, assertDtr, assertRts, handshake); return(endpoint); }
/// <summary>Initializes a new instance of the <see cref="SerialCommunicationChannel" /> class.</summary> /// <param name="endpoint">The device endpoint.</param> /// <param name="port">The port.</param> /// <exception cref="System.ArgumentException">Expected a SerialDeviceEndpoint</exception> public SerialCommunicationChannel(DeviceEndpoint endpoint, ISerialPort port = null) { if (!(endpoint is SerialDeviceEndpoint)) { throw new ArgumentException("Expected a SerialDeviceEndpoint"); } this.endpoint = endpoint as SerialDeviceEndpoint; Port = port ?? CreateSerialPort(this.endpoint); observableReceiveSequence = Port.ToObservableCharacterSequence() .Trace("Serial Receive") .Publish(); }
private ISerialPort CreateSerialPort(SerialDeviceEndpoint endpoint) { Contract.Requires(endpoint != null); var port = new SerialPort { PortName = endpoint.PortName, BaudRate = endpoint.BaudRate, Parity = endpoint.Parity, DataBits = endpoint.DataBits, StopBits = endpoint.StopBits, RtsEnable = endpoint.RtsEnable, DtrEnable = endpoint.DtrEnable, Encoding = endpoint.Encoding, Handshake = endpoint.Handshake }; return(port); }