private byte[] ReadData(int expectedBytes, bool isEcho) { var list = new List <byte>(); var data = port.ReadAll(); list.AddRange(data); // if we are expecting an echo response and the first byte received was a NAK (15) then don't bother waiting for more data if (isEcho && data.Length > 0 && data[0] == (byte)EchoStatus.NAK) { return(list.ToArray()); // caller will log the NAK } // if we didn't get the expected number of bytes then try to read more data within a timeout period if (expectedBytes > 0) { int retryCount = 0; while (list.Count == 0 && ++retryCount <= Constants.readDataRetries) { port.Wait(Constants.readDataRetryTime); data = port.ReadAll(); list.AddRange(data); } if (list.Count < expectedBytes) { do { port.Wait(Constants.readDataTimeout); data = port.ReadAll(); list.AddRange(data); } while (data.Length > 0); } // if we are expecting an echo response and the first byte received was a NAK (15) then don't bother waiting for more data if (isEcho && list.Count > 0 && list[0] == (byte)EchoStatus.NAK) { return(list.ToArray()); // caller will log the NAK } if (list.Count < expectedBytes) { if (list.Count > 0) { logger.WarnFormat("Could not read the expected number of bytes from the serial port; BytesRead='{0}', Expected={1}, Received={2}, Timeout={3}ms", Utilities.ByteArrayToString(list.ToArray()), expectedBytes, list.Count, Constants.readDataTimeout); } else { logger.WarnFormat("Could not read the expected number of bytes from the serial port; Expected={0}, Received=0, Timeout={1}ms", expectedBytes, Constants.readDataTimeout); } } } return(list.ToArray()); }
public Dictionary <PropertyKey, int> Connect(InsteonConnection connection) { port?.Close(); port = SerialPortCreator.Create(connection); port.Open(); byte[] input = { Constants.MessageStartByte, (byte)InsteonModemSerialCommand.GetImInfo }; var properties = new Dictionary <PropertyKey, int>(); var response = new List <byte>(); try { for (int i = 1; i <= Constants.negotiateRetries; ++i) { logger.DebugFormat("TX: {0}", Utilities.ByteArrayToString(input)); port.Write(input); port.Wait(Constants.openTimeout); var output = port.ReadAll(); if (output.Length <= 0) { Thread.Sleep(100); continue; // try again } response.Clear(); response.AddRange(output); while (output.Length > 0 && response.Count < 9) { port.Wait(Constants.openTimeout); output = port.ReadAll(); response.AddRange(output); } logger.DebugFormat("RX: {0}", Utilities.ByteArrayToString(response.ToArray())); int offset = 0; // determins the start location of the actual message returned for (int j = 0; j < response.Count; ++j) { if (response[j] == Constants.MessageStartByte) { offset = j; } } if (response.Count >= offset + 9 && response[offset] == Constants.MessageStartByte && response[offset + 1] == (byte)InsteonModemSerialCommand.GetImInfo && response[offset + 8] == Constants.MessageEndByte) { properties[PropertyKey.Address] = response[offset + 2] << 16 | response[offset + 3] << 8 | response[offset + 4]; properties[PropertyKey.DevCat] = response[offset + 5]; properties[PropertyKey.SubCat] = response[offset + 6]; properties[PropertyKey.FirmwareVersion] = response[offset + 7]; break; // found } } } finally { if (response.Count == 0) { throw new IOException("Failed to open port, timeout waiting for response from port."); } if (properties.Keys.Count == 0) { port.Close(); port = null; throw new IOException("Failed to open port, unable to negotiate with INSTEON controller."); } } logger.DebugFormat("Successfully negotiated with INSTEON controller on connection '{0}'...", connection); port.SetNotify(DataAvailable); return(properties); }
public Dictionary<PropertyKey, int> Connect(InsteonConnection connection) { port?.Close(); port = SerialPortCreator.Create(connection); port.Open(); byte[] input = { Constants.MessageStartByte, (byte)InsteonModemSerialCommand.GetImInfo }; var properties = new Dictionary<PropertyKey, int>(); var response = new List<byte>(); try { for (int i = 1; i <= Constants.negotiateRetries; ++i) { logger.DebugFormat("TX: {0}", Utilities.ByteArrayToString(input)); port.Write(input); port.Wait(Constants.openTimeout); var output = port.ReadAll(); if (output.Length <= 0) { Thread.Sleep(100); continue; // try again } response.Clear(); response.AddRange(output); while (output.Length > 0 && response.Count < 9) { port.Wait(Constants.openTimeout); output = port.ReadAll(); response.AddRange(output); } logger.DebugFormat("RX: {0}", Utilities.ByteArrayToString(response.ToArray())); int offset = 0; // determins the start location of the actual message returned for (int j = 0; j < response.Count; ++j) { if (response[j] == Constants.MessageStartByte) { offset = j; } } if (response.Count >= offset + 9 && response[offset] == Constants.MessageStartByte && response[offset + 1] == (byte)InsteonModemSerialCommand.GetImInfo && response[offset + 8] == Constants.MessageEndByte) { properties[PropertyKey.Address] = response[offset + 2] << 16 | response[offset + 3] << 8 | response[offset + 4]; properties[PropertyKey.DevCat] = response[offset + 5]; properties[PropertyKey.SubCat] = response[offset + 6]; properties[PropertyKey.FirmwareVersion] = response[offset + 7]; break; // found } } } finally { if (response.Count == 0) { throw new IOException("Failed to open port, timeout waiting for response from port."); } if (properties.Keys.Count == 0) { port.Close(); port = null; throw new IOException("Failed to open port, unable to negotiate with INSTEON controller."); } } logger.DebugFormat("Successfully negotiated with INSTEON controller on connection '{0}'...", connection); port.SetNotify(DataAvailable); return properties; }
public Dictionary <PropertyKey, int> Connect(InsteonConnection connection) { if (port != null) { port.Close(); } port = SerialPortCreator.Create(connection); port.Open(); byte[] input = new byte[] { 0x02, 0x60 }; Dictionary <PropertyKey, int> properties = new Dictionary <PropertyKey, int>(); List <byte> response = new List <byte>(); try { for (int i = 1; i <= Constants.negotiateRetries; ++i) { Log.WriteLine("TX: {0}", Utilities.ByteArrayToString(input)); port.Write(input); port.Wait(Constants.openTimeout); byte[] output = port.ReadAll(); if (output.Length <= 0) { Thread.Sleep(100); continue; // try again } response.Clear(); response.AddRange(output); while (output.Length > 0 && response.Count < 9) { port.Wait(Constants.openTimeout); output = port.ReadAll(); response.AddRange(output); } Log.WriteLine("RX: {0}", Utilities.ByteArrayToString(response.ToArray())); int offset = 0; for (int j = 0; j < response.Count; ++j) { if (response[j] == 0x02) { offset = j; } } if (response.Count >= offset + 9 && response[offset] == 0x02 && response[offset + 1] == 0x60 && response[offset + 8] == 0x06) { properties[PropertyKey.Address] = response[offset + 2] << 16 | response[offset + 3] << 8 | response[offset + 4]; properties[PropertyKey.DevCat] = response[offset + 5]; properties[PropertyKey.SubCat] = response[offset + 6]; properties[PropertyKey.FirmwareVersion] = response[offset + 7]; break; // found } } } finally { if (response.Count == 0) { throw new IOException("Failed to open port, timeout waiting for response from port."); } if (properties.Keys.Count == 0) { port.Close(); port = null; throw new IOException("Failed to open port, unable to negotiate with INSTEON controller."); } } Log.WriteLine("Successfully negotiated with INSTEON controller on connection '{0}'...", connection); port.SetNotify(DataAvailable); return(properties); }