/// <summary> /// Public constructor for the Receiver class. /// </summary> /// <param name="serialPort">The serial port object to which the receiver is connected</param> /// <param name="portName">The name of the port (i.e. COM1, COM2, etc.)</param> /// <param name="dispatcher">The event queue dispatcher where events generated by this class are sent</param> /// <remarks> /// After opening the port, the constructor calls the init() method which determines whether the hardware connect /// is, in fact, a VEMCO reciever and then proceeds to configure it. After returning, the constructor then instructs /// the receiver to start sending "Real Time" data. Finally the run() method is called and the objects stays in /// the run method until it shutdown() is called. With the exception of whether the class in run()ing or not, no state /// is maintained by the class. /// </remarks> public Receiver(string serialNumber, string model, Dispatcher dispatcher) { VEMCO_SerialNumber = serialNumber; VEMCO_Model = model; Dictionary<int, string> configFiles = new Dictionary<int, string>(); this.TTL = DEFAULT_TTL; this.serialPort = serialPort; this.portName = portName; this.dispatcher = dispatcher; //serialPort.Open(); encoder = null; //init(); if (encoder != null) { //this.textReader = new StreamReader(serialPort.BaseStream, serialPort.Encoding); //Object[] r = {"0"}; //write("RTMPROFILE", r); //write("START"); //Thread.Sleep(500); //while (serialPort.BytesToRead > 0) //{ // dispatcher.enqueueEvent(new NoteReceiver("Read: " + serialPort.ReadExisting(), // this, this.portName, this.VEMCO_SerialNumber, this.VEMCO_Model, this.encoder.encoderConfig)); //} //run(); dispatcher.enqueueEvent(new NewReceiver(this, this.portName, this.VEMCO_SerialNumber, this.VEMCO_Model, this.encoder.encoderConfig)); } else { ReceiverExceptions re = new ReceiverExceptions(this, "(FATAL) Failed to configure encoder during init().", true); //dispatcher.enqueueEvent(new ExcepReceiver(re,re.fatal, // this, "test port name", this.VEMCO_SerialNumber, this.VEMCO_Model, this.encoder.encoderConfig)); //serialPort.Close(); //throw re; } }
/// <summary> /// Objects of this class spend most of their execution time in this method. It simply waits asynchronously (control /// is returned to the constructor and then returned here on an interrupt) for data. When data is read it is packaged /// and sent to the event dispatcher. /// </summary> /// <returns></returns> /// <exception cref="ReceiverExceptions">Thrown when the EOF is reached on the read stream (contains an /// EndOfStreamException</exception> public async Task run() { while (goState > 0) { var ret = string.Empty; var buffer = new char[1]; // Not the most efficient... while (!ret.Contains("\n") && (!ret.Contains("\r"))) { var charsRead = await textReader.ReadAsync(buffer, 0, 1); if (charsRead == 0) { EndOfStreamException eose = new EndOfStreamException(); ReceiverExceptions re = new ReceiverExceptions(this,"End of stream reached on serial port.",true,eose); dispatcher.enqueueEvent(new ExcepReceiver(re, re.fatal, this, this.portName, this.VEMCO_SerialNumber, this.VEMCO_Model, this.encoder.encoderConfig)); throw re; } ret += buffer[0]; } if (ret.Length > 1) { dispatcher.enqueueEvent(new UnparsedMessage(ret, this, this.portName, this.VEMCO_SerialNumber, this.VEMCO_Model, this.encoder.encoderConfig)); } } goState = -1; }