public string ReadResponse(ISerialPort port, int timeout) { string buffer = string.Empty; try { do { if (_receiveNow.WaitOne(timeout, false)) { string t = port.ReadExisting(); buffer += t; } else { if (buffer.Length > 0) { throw new ApplicationException("Response received is incomplete."); } else { throw new ApplicationException("No data received from phone."); } } }while (!buffer.EndsWith("\r\nOK\r\n") && !buffer.EndsWith("\r\n> ") && !buffer.EndsWith("\r\nERROR\r\n")); } catch (Exception ex) { throw ex; } return(buffer); }
/// <summary> /// Gets an observable sequence of all the characters received by a serial port. /// </summary> /// <param name="port">The port that is to be the data source.</param> /// <returns><see cref="IObservable{char}" /> - an observable sequence of characters.</returns> public static IObservable <char> ReceivedCharacters(this ISerialPort port) { var observableEvents = port.ObservableDataReceivedEvents(); var observableCharacterSequence = from args in observableEvents where args.EventArgs.EventType == SerialData.Chars from character in port.ReadExisting() select character; return(observableCharacterSequence); }
internal SysExMessage RunCommand(SysExMessage msg, int Timeout = 30) { if (sp.BytesToRead != 0) //clear the buffer from any sent bytes previously sp.ReadExisting(); Send(msg.ToArray()); var r = ReadSysEx(Timeout); if (r.Command != msg.Command) throw new ArrayTypeMismatchException($"Command Mismatch. Command Sent: '{msg.Command}', Command Read: '{r.Command}'"); return r; }
/// <summary> /// Gets an event handler (delegate) that handles the SerialDataReceived event from a serial port. /// if the event type is <see cref="SerialData.Chars" /> then the received characters are read from /// the serial port buffer and passed on to a subscribed observer by calling the OnNext method. /// OnNext is called once for each received character. If the event type is /// <see cref="SerialData.Eof" /> then the observer's OnCompleted method is called. /// </summary> /// <param name="port">The data source.</param> /// <param name="observer">The subscribed observer.</param> /// <returns>SerialDataReceivedEventHandler.</returns> /// <remarks> /// The documentation for <see cref="System.IO.Ports.SerialPort" /> states that: "Note that this /// method can leave trailing lead bytes in the internal buffer, which makes the BytesToRead value /// greater than zero". In that situation, we would enter an infinite loop trying to read from en /// empty stream, which would only terminate when more data arrives at the serial port and /// eventually gets flushed into the input stream. Therefore, we use <c>Thread.Yield()</c> within /// the receive loop to give other threads (including the serial port) a chance to run. /// </remarks> private static SerialDataReceivedEventHandler ReactiveDataReceivedEventHandler(ISerialPort port, IObserver <char> observer) { var log = ServiceLocator.LogService; var receiveEventHandler = new SerialDataReceivedEventHandler((sender, e) => { switch (e.EventType) { case SerialData.Eof: observer.OnCompleted(); break; case SerialData.Chars: try { while (port.BytesToRead > 0) { var inputBuffer = port.ReadExisting(); foreach (var character in inputBuffer) { observer.OnNext(character); } Thread.Yield(); // There's no point in spinning on an empty stream. } } catch (InvalidOperationException ex) { log.Error() .Message("The serial port may have closed while a transaction was waiting for data") .Exception(ex) .Write(); observer.OnError(ex); } break; default: log.Warn() .Message("Ignoring unexpected serial data received event: {type}", e.EventType) .Write(); break; } }); return(receiveEventHandler); }