private bool OSExclusiveAccess(IConnection connection) { var isLtoFlashPort = connection.Type == INTV.Core.Model.Device.ConnectionType.Serial; if (isLtoFlashPort) { var portIdString = SerialPortConnection.GetSerialPortIdFromDevTtyPath(connection.Name); if (!string.IsNullOrEmpty(portIdString)) { var portIdParts = portIdString.Split('-'); if (portIdParts.Length >= 3) { var vendorAndName = portIdParts[1]; isLtoFlashPort = vendorAndName.StartsWith(SanitizedVendorName + '_' + SanitizedProductName); } } } return(isLtoFlashPort); }
// TODO Delete this. This was an old implementation of sending ROM to Intellicart. #if IMPLEMENT_DOWNLOAD /// <summary> /// Loads the ROM at the given path onto the Intellicart. /// </summary> /// <remarks>The ROM at <paramref name="romPath"/> must be in the .rom format /// specified by the Intellicart documentation.</remarks> public void DownloadRom(string romPath) { using (var rom = FileUtilities.OpenFileStream(romPath)) { using (var port = new SerialPortConnection(SerialPort)) { port.Port.BaudRate = BaudRate; port.WriteTimeout = Timeout; // default port settings are 8,N,1 with no handshaking port.Open(); rom.CopyTo(port.WriteStream); // If we close the port too soon after writing, the Intellicart // will time out reading data from the stream. This is likely // due to buffering, and that the streams get disposed when // the port and file streams are disposed. System.Threading.Thread.Sleep(4000); } } }
/// <summary> /// Initializes a new instance of the <see cref="ArduinoWS281XDeviceDefinition"/> class. /// </summary> /// <param name="port">The name of the serial-port to connect to.</param> /// <param name="baudRate">The baud-rate of the serial-connection.</param> public ArduinoWS281XDeviceDefinition(string port, int baudRate = 115200) { SerialConnection = new SerialPortConnection(port, baudRate); }
private static void DownloadRom(AsyncTaskData taskData) { SingleInstanceApplication.Instance.IsBusy = true; var data = (DownloadTaskData)taskData; var romPath = PrepareRom(data); data.UpdateTaskProgress(0, string.Format(CultureInfo.CurrentCulture, Resources.Strings.DownloadRom_Update_Format, romPath)); var cancelled = data.AcceptCancelIfRequested(); if (!cancelled) { using (var rom = FileUtilities.OpenFileStream(romPath)) { var configData = new Dictionary <string, object>() { { SerialPortConnection.PortNameConfigDataName, data.Intellicart.SerialPort } }; using (var port = SerialPortConnection.Create(configData)) { port.BaudRate = data.Intellicart.BaudRate; port.WriteTimeout = data.Intellicart.Timeout * 1000; // default port settings are 8,N,1 with no handshaking var bytesRemaining = (int)rom.Length; var totalBytes = rom.Length; var bytesPerSecond = data.Intellicart.BaudRate / 8; var bytesWritten = 0; var estimatedDownloadTime = ((double)rom.Length / bytesPerSecond) + 4; // give it time to finish var estimatedTimeRemaining = estimatedDownloadTime; var percentDone = 0.0; // Would like to respond to cancel requests somewhat quickly. So, let's // write out small enough chunks even at the slowest baud rate... var bytesPerWrite = (data.Intellicart.BaudRate / 2400) * 128; System.Diagnostics.Debug.Assert(bytesPerWrite > 0, "How did we get zero bytes to write?!"); port.Open(); var stopwatch = System.Diagnostics.Stopwatch.StartNew(); byte[] buffer = new byte[bytesPerWrite]; while (!cancelled && (bytesRemaining > 0)) { var updateText = string.Format(CultureInfo.CurrentCulture, Resources.Strings.DownloadRom_UpdateTitle_Format, data.Name, Math.Max(0, (int)estimatedTimeRemaining)); data.UpdateTaskTitle(updateText); bytesPerWrite = Math.Min(bytesPerWrite, bytesRemaining); var bytesRead = rom.Read(buffer, 0, bytesPerWrite); bytesWritten += bytesRead; bytesRemaining -= bytesRead; updateText = string.Format(CultureInfo.CurrentCulture, Resources.Strings.DownloadRom_Update_Format, romPath); estimatedTimeRemaining = estimatedDownloadTime - stopwatch.Elapsed.TotalSeconds; percentDone = stopwatch.Elapsed.TotalSeconds / estimatedDownloadTime; data.UpdateTaskProgress(percentDone, updateText); port.WriteStream.Write(buffer, 0, bytesRead); cancelled = data.AcceptCancelIfRequested(); } // If we close the port too soon after writing, the Intellicart will time out reading data from the stream. // This is likely due to buffering, and that the streams get disposed when the port and file streams are // disposed. On Mac in particular, the write out to the port may complete far more quickly than what the // math would indicate, based on observation. This implies one of the following: // a) Even though the synchronous write was called, the underlying implementation is asynchronous // b) It could be that the driver itself is "lying" to the underlying implementation // c) Buffering, either in the driver, kernel, or other API layers, misleads the higher-level APIs var timedOut = false; while (!cancelled && !timedOut) { var message = string.Format(Resources.Strings.DownloadRom_UpdateTitle_Format, data.Name, Math.Max(0, (int)estimatedTimeRemaining)); data.UpdateTaskTitle(message); System.Threading.Thread.Sleep(250); cancelled = data.AcceptCancelIfRequested(); var updateText = string.Format(CultureInfo.CurrentCulture, Resources.Strings.DownloadRom_Update_Format, romPath); estimatedTimeRemaining = estimatedDownloadTime - stopwatch.Elapsed.TotalSeconds; percentDone = Math.Max(100, stopwatch.Elapsed.TotalSeconds / estimatedDownloadTime); data.UpdateTaskProgress(percentDone, updateText); timedOut = estimatedTimeRemaining < 0; } } } } }
private static void OnSerialPortConnection(string portname) { SerialPortConnection?.Invoke(portname); }
/// <summary> /// Initializes a new instance of SerialPortConnectionViewModel. /// </summary> /// <param name="port">The serial port connection model.</param> public SerialPortConnectionViewModel(SerialPortConnection port) { _port = port; }
/// <summary> /// Initializes a new instances of SerialPortSelectorViewModel. /// </summary> /// <param name="prompt">The prompt to display in the port selection area.</param> /// <param name="availablePorts">The available ports.</param> /// <param name="disabledPorts">Non-selectable ports.</param> /// <param name="selectedSerialPort">The currently selected port.</param> /// <param name="baudRates">Available baud rates to choose from.</param> /// <param name="defaultBaudRate">The default baud rate.</param> /// <param name="checkPortAvailability">If <c>true</c>, check the port to see if it is already in use before adding it to the selection list.</param> /// <param name="inclusionFilter">If <c>null</c> or it returns <c>true</c>, ports from all available ports are included.</param> public SerialPortSelectorViewModel(string prompt, IEnumerable <string> availablePorts, IEnumerable <string> disabledPorts, string selectedSerialPort, IEnumerable <int> baudRates, int defaultBaudRate, bool checkPortAvailability, Predicate <IConnection> inclusionFilter) { InclusionFilter = inclusionFilter; if (!string.IsNullOrWhiteSpace(prompt)) { Prompt = prompt; } else { Prompt = Resources.Strings.SelectSerialPortDialog_Message; } if (baudRates == null) { BaudRates = new ObservableCollection <BaudRateViewModel>(new[] { new BaudRateViewModel(defaultBaudRate) }); } else { BaudRates = new ObservableCollection <BaudRateViewModel>(baudRates.Select(r => new BaudRateViewModel(r))); } var ports = availablePorts; if ((ports == null) || !ports.Any()) { ports = inclusionFilter == null ? SerialPortConnection.AvailablePorts : SerialPortConnection.GetAvailablePorts(inclusionFilter); } if (ports != null) { AvailableSerialPorts = new ObservableCollection <SerialPortViewModel>(ports.OrderBy(p => p).Select(p => new SerialPortViewModel(p))); } else { AvailableSerialPorts = new ObservableCollection <SerialPortViewModel>(); } if (disabledPorts == null) { DisabledSerialPorts = new ObservableCollection <string>(); } else { DisabledSerialPorts = new ObservableCollection <string>(disabledPorts); } if (checkPortAvailability) { var portsInUse = INTV.Shared.Model.Device.SerialPortConnection.PortsInUse; foreach (var portInUse in portsInUse.Where(p => (InclusionFilter == null) || InclusionFilter(Connection.CreatePseudoConnection(p, ConnectionType.Serial)))) { DisabledSerialPorts.Add(portInUse); } } foreach (var disabledPort in DisabledSerialPorts.Where(p => (InclusionFilter == null) || InclusionFilter(Connection.CreatePseudoConnection(p, ConnectionType.Serial))).OrderBy(p => p).Reverse()) { var viewModel = AvailableSerialPorts.FirstOrDefault(p => p.PortName == disabledPort); if (viewModel == null) { viewModel = new SerialPortViewModel(disabledPort, false); } else { viewModel.IsSelectable = false; AvailableSerialPorts.Remove(viewModel); } if (AvailableSerialPorts.Count == 0) { AvailableSerialPorts.Add(viewModel); } else { AvailableSerialPorts.Insert(0, viewModel); } } _selectedSerialPort = selectedSerialPort; _selectedSerialPortViewModel = AvailableSerialPorts.FirstOrDefault(p => p.PortName == _selectedSerialPort); DefaultBaudRate = defaultBaudRate; _selectedBaudRate = defaultBaudRate; _selectedBaudRateViewModel = BaudRates.FirstOrDefault(b => b.BaudRate == defaultBaudRate); INTV.Shared.Interop.DeviceManagement.DeviceChange.DeviceAdded += DeviceAdded; INTV.Shared.Interop.DeviceManagement.DeviceChange.DeviceRemoved += DeviceRemoved; }
private static void CheckDevices(AsyncTaskData taskData) { var data = (CheckForDevicesTaskData)taskData; var validPorts = new HashSet <string>(); data.ValidDevicePorts = validPorts; var potentialPorts = data.LtoFlashViewModel.AvailableDevicePorts.Except(data.CurrentDevices).ToList(); if (!string.IsNullOrWhiteSpace(data.LastKnownPort) && (potentialPorts.Count > 1) && potentialPorts.Remove(data.LastKnownPort)) { potentialPorts.Insert(0, data.LastKnownPort); } foreach (var portName in potentialPorts) { var maxRetries = 1; for (var retry = 0; retry < maxRetries; ++retry) { if (data.AcceptCancelIfRequested()) { break; } var errorLogger = Properties.Settings.Default.EnablePortLogging ? new Logger(Configuration.Instance.GetPortLogPath(portName)) : null; try { var isValidDevicePort = false; var configData = new Dictionary <string, object>() { { SerialPortConnection.PortNameConfigDataName, portName } }; using (var port = SerialPortConnection.Create(configData)) { if (Properties.Settings.Default.EnablePortLogging) { port.EnableLogging(Configuration.Instance.GetPortLogPath(portName)); } port.LogPortMessage("CheckForDevices: BEGIN"); data.UpdateTaskProgress(0, string.Format(Resources.Strings.DeviceSearch_Task_Progress_Format, portName)); port.BaudRate = Device.DefaultBaudRate; port.Handshake = Device.Handshake; port.Open(); var numRetry = 4; var timeout = 1100; for (var i = 0; !data.AcceptCancelIfRequested() && (i < numRetry); ++i) { if (!data.AcceptCancelIfRequested()) { if (port.IsOpen && port.WaitForBeacon(timeout)) { isValidDevicePort = true; } } } port.LogPortMessage("CheckForDevices: END"); } if (!data.AcceptCancelIfRequested() && isValidDevicePort) { if (Properties.Settings.Default.AutomaticallyConnectToDevices && data.AutoConnect) { data.ReportedAnyAutoConnectDevices |= true; var creationInfo = new Dictionary <string, object>() { { DeviceCreationInfo.ConfigName, new DeviceCreationInfo(true, true, ActivationMode.ActivateIfFirst) } }; INTV.Shared.Interop.DeviceManagement.DeviceChange.ReportDeviceAdded(data, portName, Core.Model.Device.ConnectionType.Serial, creationInfo); data.Task.CancelTask(); } else { validPorts.Add(portName); } } } catch (UnauthorizedAccessException) { // Access is denied to the port or the current process, or another process on the system, // already has the specified COM port open either by a SerialPort instance or in unmanaged code. if (errorLogger != null) { errorLogger.Log("CheckForDevices: UnauthorizedAccessException on port " + portName); } maxRetries = RetryCount; System.Threading.Thread.Sleep(500); } catch (ArgumentOutOfRangeException) { // One or more of the properties for this instance are invalid. For example, the Parity, DataBits, // or Handshake properties are not valid values; the BaudRate is less than or equal to zero; the // ReadTimeout or WriteTimeout property is less than zero and is not InfiniteTimeout. if (errorLogger != null) { errorLogger.Log("CheckForDevices: ArgumentOutOfRangeException on port " + portName); } } catch (ArgumentException) { // The port name does not begin with "COM", or the file type of the port is not supported. if (errorLogger != null) { errorLogger.Log("CheckForDevices: ArgumentException on port " + portName); } } catch (System.IO.IOException) { // The port is in an invalid state, or an attempt to set the state of the underlying port failed. // For example, the parameters passed from this SerialPort object were invalid. if (errorLogger != null) { errorLogger.Log("CheckForDevices: IOException on port " + portName); } } catch (InvalidOperationException) { // The specified port on the current instance of the SerialPort is already open. if (errorLogger != null) { errorLogger.Log("CheckForDevices: InvalidOperationException on port " + portName); } } catch (Exception e) { // Caught some unexpected exception. if (errorLogger != null) { errorLogger.Log("CheckForDevices: Exception on port " + portName + " with message: " + e.Message); } throw; } } } if (data.CancelRequsted) { validPorts.Clear(); } }