Files
tbf/NfcC7_DLL/NfcHanler/MessageEngine.cs
T

4305 lines
218 KiB
C#

using System.Collections;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using GlobalIPerlUtility;
using Microsoft.VisualBasic;
using NA2WNFC;
using NfcC7_DLL.NfcHanler.FieldLogicStaging;
using NfcC7_DLL.NfcHanler.FieldLogicStaging.GlobalIPerlTags;
using NfcC7_DLL.NfcHanler.FieldLogicStaging.SterlingMetrologyTags;
using NfcC7_DLL.NfcHanler.Utils;
using Sensus;
using Sensus.Protocols.FlexNet;
using Sensus.Protocols.FlexNet.FNv2;
using Sensus.Protocols.FlexNet.FNv2.NA2WParameters;
using Sensus.Protocols.FlexNet.Serial;
using Sensus.Protocols.FlexNet.Serial.FNv2;
using Log = NfcC7_DLL.NfcHanler.Utils.Log;
using MeterSize = NfcC7_DLL.NfcHanler.FieldLogicStaging.SterlingMetrologyTags.MeterSize;
using NA2WProductType = NfcC7_DLL.NfcHanler.FieldLogicStaging.NA2WProductType;
using NfcCommand_InventoryRead = NfcC7_DLL.NfcHanler.Protocols.NfcCommand_InventoryRead;
using NfcCommand_NdefRead = NfcC7_DLL.NfcHanler.Protocols.NfcCommand_NdefRead;
using Ping_NA2WDataReport_NA2WWater_TimeValues = Sensus.Protocols.FlexNet.Ping_NA2WDataReport_NA2WWater_TimeValues;
using TemperatureCalibration = NfcC7_DLL.NfcHanler.FieldLogicStaging.GlobalIPerlTags.TemperatureCalibration;
namespace NfcC7_DLL.NfcHanler
{
public class MessageEngine
{
private const byte WIDTH_MASK = 0x07;
private WindowViewModel windowViewModel = null;
private ISerialConnection serialManager = null;
string currentFilename = "";
DateTime lastCSVExport;
private UInt16 sessionId = 0;
StringBuilder csvString;
public MessageEngine()
{
receiveQueue = new BlockingQueue<FrameEventArgs<IFrame>>();
eventThread = ThreadHelpers.MakeThread("FrameEventLoop", FrameEventLoop);
eventThread.IsBackground = true;
eventThread.Start();
}
public WindowViewModel ViewModel
{
set
{
windowViewModel = value;
SetComPortList(GetPortNames());
windowViewModel.LogWithDescription = true;
windowViewModel.LogWithHexString = true;
windowViewModel.LogChargingData = false;
}
}
public void OpenClose()
{
if (windowViewModel.IsOpen)
{
if (serialManager is NfcReader)
{
NfcReader nfcReader = (NfcReader)serialManager;
nfcReader.TagEvent -= NfcReader_TagEvent;
}
else if (serialManager is CmdLinkGen2Link)
{
CmdLinkGen2Link cmdLinkGen2Link = (CmdLinkGen2Link)serialManager;
cmdLinkGen2Link.TagEvent -= NfcReader_TagEvent;
}
else if (serialManager is MeterTestHatLink)
{
MeterTestHatLink meterTestHatLink = (MeterTestHatLink)serialManager;
meterTestHatLink.TagEvent -= NfcReader_TagEvent;
}
serialManager.Close();
serialManager = null;
windowViewModel.IsOpen = false;
}
else
{
String comPortString = windowViewModel.ComPortSelectedItem;
try
{
if (windowViewModel.LinkSelectedItem == "NFC Reader")
{
NfcReader nfcReader = new NfcReader(windowViewModel.ComPortSelectedItem);
nfcReader.TagEvent += NfcReader_TagEvent;
serialManager = nfcReader;
}
else if (windowViewModel.LinkSelectedItem == "CmdLink II")
{
CmdLinkGen2Link cmdLink2Link = new CmdLinkGen2Link(windowViewModel.ComPortSelectedItem);
cmdLink2Link.TagEvent += NfcReader_TagEvent;
serialManager = cmdLink2Link;
}
else if (windowViewModel.LinkSelectedItem == "Meter Test Hat")
{
MeterTestHatLink meterTestHatLink = new MeterTestHatLink(windowViewModel.ComPortSelectedItem);
meterTestHatLink.TagEvent += NfcReader_TagEvent;
serialManager = meterTestHatLink;
}
else
{
serialManager = new SerialManager(windowViewModel.ComPortSelectedItem);
}
serialManager.Open();
if (serialManager.IsConnected)
{
serialManager.MessageReceived += MessageReceived;
windowViewModel.IsOpen = true;
}
}
catch (Exception e)
{
serialManager = null;
}
}
}
private void NfcReader_TagEvent(object sender, TagEventArgs e)
{
//viewModel.NfcTagDetected = e.Present;
if ((e.Present ) && (serialManager is NfcReader))
{
NfcReader nfcReader = (NfcReader)serialManager;
NfcTargetDetails nfcTargetDetails = nfcReader.NfcTargetDetails;
if (nfcTargetDetails.DeviceId != windowViewModel.DeviceId)
{
windowViewModel.ResetValues();
windowViewModel.DeviceId = nfcTargetDetails.DeviceId;
Byte productType = 0;
Byte.TryParse(nfcTargetDetails.ProductType, out productType);
windowViewModel.ProductType = productType;
windowViewModel.ProductTypeVersion = nfcTargetDetails.ProductVersion;
}
}
else if ((e.Present) && (serialManager is CmdLinkGen2Link))
{
CmdLinkGen2Link cmdLinkGen2Link = (CmdLinkGen2Link)serialManager;
NfcTargetDetails nfcTargetDetails = cmdLinkGen2Link.NfcTargetDetails;
if (nfcTargetDetails.DeviceId != windowViewModel.DeviceId)
{
windowViewModel.ResetValues();
windowViewModel.DeviceId = nfcTargetDetails.DeviceId;
Byte productType = 0;
Byte.TryParse(nfcTargetDetails.ProductType, out productType);
windowViewModel.ProductType = productType;
windowViewModel.ProductTypeVersion = nfcTargetDetails.ProductVersion;
}
}
else if ((e.Present) && (serialManager is MeterTestHatLink))
{
MeterTestHatLink meterTestHatLink = (MeterTestHatLink)serialManager;
NfcTargetDetails nfcTargetDetails = meterTestHatLink.NfcTargetDetails;
if (nfcTargetDetails.DeviceId != windowViewModel.DeviceId)
{
windowViewModel.ResetValues();
windowViewModel.DeviceId = nfcTargetDetails.DeviceId;
Byte productType = 0;
Byte.TryParse(nfcTargetDetails.ProductType, NumberStyles.HexNumber, null, out productType);
windowViewModel.ProductType = productType;
windowViewModel.ProductTypeVersion = nfcTargetDetails.ProductVersion;
Utility.Log.Write(String.Format("Found NFC tag {0} (PT: {1}, PV: {2}, ID: {3}).", nfcTargetDetails.TagId, productType, nfcTargetDetails.ProductVersion, nfcTargetDetails.DeviceId));
}
}
}
public void Link(String command)
{
String[] cmdArgs = command.Split(new char[] { ' ' }, 2);
if (cmdArgs[0].Equals("PortRefresh"))
{
if (windowViewModel.LinkSelectedItem == "NFC Reader")
{
SetComPortList(NFCReader.GetAvailableReaders().ToArray());
windowViewModel.IsNfcFeaturesEnabled = true;
}
else
{
SetComPortList(GetPortNames());
windowViewModel.IsNfcFeaturesEnabled = (windowViewModel.LinkSelectedItem == "CmdLink II") || (windowViewModel.LinkSelectedItem == "Meter Test Hat");
}
}
else if (cmdArgs[0].Equals("NfcRefresh"))
{
if (serialManager is NfcReader reader && reader.IsConnected)
{
byte[] ndefData = reader.Get_Ndef_Data();
byte[] ramData = reader.Get_RMA_Data();
windowViewModel.NfcNdefParseText = $"NDEF Records:\n{ndefData.ToHexString()}\n";
foreach (NdefRecord record in reader.GetNdefRecords())
{
windowViewModel.NfcNdefParseText += record.Payload.ToString();
}
GlobalIPerlRma esaapPomNfcRma = new GlobalIPerlRma(ramData);
windowViewModel.NfcRmaParseText = esaapPomNfcRma.ToString();
}
}
}
private enum EngineerTestCommandList
{
WdReset = 0x00, /// Watchdog Reset Test
PulseOut = 0x01, /// Pulse out test
TxBup = 0x02, /// Transmit Activity BUP
DisplaySwitchOpen = 0x03, /// Generate Display Switch Open event
DisplaySwitchClose = 0x04, /// Generate Display Switch Close event
PowerSwitch = 0x05, /// Power Domain Control
ComaSleep = 0x06, /// Enter Coma Sleep, power down all power domains
ExternalFlashTest = 0x07, /// External flash write/read test
NfcEepromTest = 0x08, /// NFC EEPROM write/read test
OpticalLedToggle = 0x09, /// Toggle optical data LED on
TxPeriodicReading = 0x0A, /// Start or stop transmission of a periodic reading
}
public void Read(string tagDescription)
{
List<byte> GlobalIPerlTag = new List<byte>();
if (tagDescription.Length != 0)
{
string[] tag = tagDescription.Split(',');
for (int i = 0; i < tag.Length; i++)
{
GlobalIPerlTag GlobalIPerlTagItem;
if (Enum.TryParse(tag[i], true, out GlobalIPerlTagItem))
{
System.Console.WriteLine((int)GlobalIPerlTagItem);
GlobalIPerlTag.Add((byte)GlobalIPerlTagItem);
}
}
}
if (GlobalIPerlTag.Count != 0)
{
ParameterReadCommand parameterReadCommand = new ParameterReadCommand(TagMap.GlobalIPerl, GlobalIPerlTag);
SendNa2wSerial(parameterReadCommand, false);
}
}
public void ReadSterling(string tagDescription)
{
List<byte> GlobalIPerlTag = new List<byte>();
if (tagDescription.Length != 0)
{
string[] tag = tagDescription.Split(',');
for (int i = 0; i < tag.Length; i++)
{
SterlingMetrologyTag GlobalIPerlTagItem;
if (Enum.TryParse(tag[i], true, out GlobalIPerlTagItem))
{
System.Console.WriteLine((int)GlobalIPerlTagItem);
GlobalIPerlTag.Add((byte)GlobalIPerlTagItem);
}
}
}
if (GlobalIPerlTag.Count != 0)
{
ParameterReadCommand parameterReadCommand = new ParameterReadCommand((TagMap)0x05, GlobalIPerlTag);
SendNa2wSerial(parameterReadCommand, false);
}
}
public void Write(string tagDescription)
{
List<NA2WParameter> na2wParamList = new List<NA2WParameter>();
List<byte> tagReadList = new List<byte>();
if (tagDescription.Length != 0)
{
string[] tags = tagDescription.Split(',');
for (int i = 0; i < tags.Length; i++)
{
string tag = tags[i];
if (tag.Equals("SerialNumber"))
{
if (windowViewModel.SerialNumberNew.Length != 0)
{
UInt64 value = UInt64.Parse(windowViewModel.SerialNumberNew);
SerialNumber serialNumber = new SerialNumber(value);
na2wParamList.Add(serialNumber);
}
}
else if (tag.Equals("RfPowerLevel"))
{
Byte powerLevel;
if (Conversion.TryParseHexOrDecString(windowViewModel.RfPowerLevelNew, out powerLevel))
{
RfPowerLevel paPowerLevel = new RfPowerLevel();
paPowerLevel.PowerLevel = powerLevel;
na2wParamList.Add(paPowerLevel);
}
}
else if (tag.Equals("DeviceId"))
{
UInt32 id;
if (
(windowViewModel.DeviceIdNew.Length != 0)
&& Conversion.TryParseHexOrDecString(windowViewModel.DeviceIdNew, out id)
)
{
DeviceId deviceId = new DeviceId();
deviceId.Id = id;
na2wParamList.Add(deviceId);
}
}
else if (tag.Equals("TcxoCorrection"))
{
System.Console.WriteLine(tagDescription + " = " + windowViewModel.TcxoCorrectionNew);
Int16 correction;
if (
(windowViewModel.TcxoCorrectionNew.Length != 0)
&& Conversion.TryParseHexOrDecString(windowViewModel.TcxoCorrectionNew, out correction)
)
{
TcxoCorrection tcxoCorrection = new TcxoCorrection();
tcxoCorrection.Correction = correction;
na2wParamList.Add(tcxoCorrection);
}
}
else if (tag.Equals("TemperatureCalibration"))
{
SByte calOffset;
if (
(windowViewModel.TemperatureCalOffsetNew.Length != 0)
&& Conversion.TryParseHexOrDecString(windowViewModel.TemperatureCalOffsetNew, out calOffset)
)
{
TemperatureCalibration temperatureCalibration = new TemperatureCalibration();
temperatureCalibration.CalOffset = calOffset;
na2wParamList.Add(temperatureCalibration);
// Update corrected temperature
tagReadList.Add((byte)GlobalIPerlTag.Temperature);
}
}
else if (tag.Equals("VbatCalibration"))
{
SByte calOffset;
UInt16 calSlope;
if (
Conversion.TryParseHexOrDecString(windowViewModel.VbatCalOffsetNew, out calOffset)
&& Conversion.TryParseHexOrDecString(windowViewModel.VbatCalSlopeNew, out calSlope)
)
{
VbatCalibration vbatCalibration = new VbatCalibration();
vbatCalibration.CalOffset = calOffset;
vbatCalibration.CalSlope = calSlope;
na2wParamList.Add(vbatCalibration);
// Update corrected Vbat
tagReadList.Add((byte)GlobalIPerlTag.Vbat);
}
}
else if (tag.Equals("VsysCalibration"))
{
SByte calOffset;
UInt16 calSlope;
if (
Conversion.TryParseHexOrDecString(windowViewModel.VsysCalOffsetNew, out calOffset)
&& Conversion.TryParseHexOrDecString(windowViewModel.VsysCalSlopeNew, out calSlope)
)
{
VsysCalibration vsysCalibration = new VsysCalibration();
vsysCalibration.CalOffset = calOffset;
vsysCalibration.CalSlope = calSlope;
na2wParamList.Add(vsysCalibration);
// Update corrected Vsys
tagReadList.Add((byte)GlobalIPerlTag.Vsys);
}
}
else if (tag.Equals("ManufacturingNote"))
{
string note = windowViewModel.ManufacturingNoteNew;
if (note.Length > 64)
{
note = note.Substring(0, 64);
}
ManufacturingNote manufacturingNote = new ManufacturingNote();
manufacturingNote.NoteParsed = note;
na2wParamList.Add(manufacturingNote);
}
else if (tag.Equals("RHumidCalOffset"))
{
SByte calOffset;
if (
(windowViewModel.RHumidCalOffsetNew.Length != 0)
&& Conversion.TryParseHexOrDecString(windowViewModel.RHumidCalOffsetNew, out calOffset)
)
{
HumidityCalibration rHumidCalibration = new HumidityCalibration();
rHumidCalibration.CalOffset = calOffset;
na2wParamList.Add(rHumidCalibration);
// Update corrected humidity
tagReadList.Add((byte)GlobalIPerlTag.RHumid);
tagReadList.Add((byte)GlobalIPerlTag.RHumidCalOffset);
}
}
}
}
if (na2wParamList.Count != 0)
{
ParameterWriteCommand parameterWriteCommand = new ParameterWriteCommand(na2wParamList);
SendNa2wSerial(parameterWriteCommand, false);
}
Thread.Sleep(1000);
if (tagReadList.Count != 0)
{
ParameterReadCommand parameterReadCommand = new ParameterReadCommand(TagMap.GlobalIPerl, tagReadList);
SendNa2wSerial(parameterReadCommand, false);
}
}
public void WriteSterling(string tagDescription)
{
List<NA2WParameter> na2wParamList = new List<NA2WParameter>();
List<byte> tagReadList = new List<byte>();
if (tagDescription.Length != 0)
{
string[] tags = tagDescription.Split(',');
for (int i = 0; i < tags.Length; i++)
{
string tag = tags[i];
if (tag.Equals("FactoryId"))
{
FactoryId factoryId =
new FactoryId();
factoryId.FactoryID = windowViewModel.FactoryIdNew;
na2wParamList.Add(factoryId);
}
if (tag.Equals("CustomerId"))
{
CustomerId customerId =
new CustomerId();
customerId.CustomerID = windowViewModel.CustomerIdNew;
na2wParamList.Add(customerId);
}
if (tag.Equals("BuildInfo"))
{
BuildInformation buildInfo =
new BuildInformation();
buildInfo.BuildInfo = windowViewModel.BuildInfoNew;
na2wParamList.Add(buildInfo);
}
if (tag.Equals("ManufactureDate"))
{
ManufactureDate manufactureDate =
new ManufactureDate();
manufactureDate.Date = windowViewModel.ManufactureDateNew;
na2wParamList.Add(manufactureDate);
}
if (tag.Equals("MeterState"))
{
MeterState meterState =
new MeterState();
meterState.Mode = windowViewModel.SterlingMeterStateNew;
na2wParamList.Add(meterState);
}
if (tag.Equals("OpticalDataMode"))
{
OpticalDataMode opticalDataMode =
new OpticalDataMode();
opticalDataMode.Mode = windowViewModel.OpticalDataModeNew;
na2wParamList.Add(opticalDataMode);
}
if (tag.Equals("DisplayTimeout"))
{
if (windowViewModel.DisplayTimeout.Length != 0)
{
DisplayTimeout displayTimeoutSet =
new DisplayTimeout();
displayTimeoutSet.Timeout = Byte.Parse(windowViewModel.DisplayTimeoutNew);
na2wParamList.Add(displayTimeoutSet);
}
}
if (tag.Equals("ASICTemperatureCalibration"))
{
Int16 calibration;
if (
(windowViewModel.ASICTemperatureCalibrationNew.Length != 0)
&& Conversion.TryParseHexOrDecString(windowViewModel.ASICTemperatureCalibrationNew, out calibration)
)
{
TemperatureCalibration tempCal =
new TemperatureCalibration();
tempCal.TemperatureCal = calibration;
na2wParamList.Add(tempCal);
// Update corrected temperature
tagReadList.Add((byte)SterlingMetrologyTag.Temperature);
}
}
if (tag.Equals("EmptyPipeParameters"))
{
if (
(windowViewModel.EPParam_ImpedanceThresholdNew.Length != 0)
&& (windowViewModel.EPParam_EmptyTimeThresholdNew.Length != 0)
&& (windowViewModel.EPParam_HydrationDurationNew.Length != 0)
)
{
EmptyPipeParameters emptyPipeParameters =
new EmptyPipeParameters();
emptyPipeParameters.ImpedanceThreshold = UInt16.Parse(windowViewModel.EPParam_ImpedanceThresholdNew);
emptyPipeParameters.EmptyTimeThreshold = Byte.Parse(windowViewModel.EPParam_EmptyTimeThresholdNew);
emptyPipeParameters.HydrationDuration_hr = Byte.Parse(windowViewModel.EPParam_HydrationDurationNew);
na2wParamList.Add(emptyPipeParameters);
}
}
if (tag.Equals("MagneticTamperParameters"))
{
if (
(windowViewModel.MTParam_MaxPercentErrorNew.Length != 0)
&& (windowViewModel.MTParam_DetectionCountsNew.Length != 0)
&& (windowViewModel.MTParam_PidSettlingTimeNew.Length != 0)
&& (windowViewModel.MTParam_DriveLowNew.Length != 0)
&& (windowViewModel.MTParam_DriveHighNew.Length != 0)
)
{
MagneticTamperParameters magneticTamperParameters =
new MagneticTamperParameters();
magneticTamperParameters.MaxPercentError = Byte.Parse(windowViewModel.MTParam_MaxPercentErrorNew);
magneticTamperParameters.DetectionCounts = Byte.Parse(windowViewModel.MTParam_DetectionCountsNew);
magneticTamperParameters.PidSettlingTime_s = Byte.Parse(windowViewModel.MTParam_PidSettlingTimeNew);
magneticTamperParameters.DriveLow = Byte.Parse(windowViewModel.MTParam_DriveLowNew);
magneticTamperParameters.DriveHigh = Byte.Parse(windowViewModel.MTParam_DriveHighNew);
na2wParamList.Add(magneticTamperParameters);
}
}
if (tag.Equals("ReverseVolumeBufferParameters"))
{
if (
(windowViewModel.RVBParam_Threshold_qmlNew.Length != 0)
&& (windowViewModel.RVBParam_Leak_qml_sNew.Length != 0)
)
{
ReverseVolumeBufferParameters reverseVolumeBufferParameters =
new ReverseVolumeBufferParameters();
reverseVolumeBufferParameters.Threshold_qml = UInt32.Parse(windowViewModel.RVBParam_Threshold_qmlNew);
reverseVolumeBufferParameters.Leak_qml_s = UInt16.Parse(windowViewModel.RVBParam_Leak_qml_sNew);
na2wParamList.Add(reverseVolumeBufferParameters);
}
}
if (tag.Equals("MagneticFieldDriveParameters"))
{
if (
(windowViewModel.MFDParam_DriveTimeNew.Length != 0)
&& (windowViewModel.MFDParam_FieldFitA0New.Length != 0)
&& (windowViewModel.MFDParam_FieldFitA1New.Length != 0)
&& (windowViewModel.MFDParam_FieldDriveStepMagnitudeNew.Length != 0)
&& (windowViewModel.MFDParam_FieldControlHysteresis_mGNew.Length != 0)
)
{
MagneticFieldDriveParameters magneticFieldDriveParameters =
new MagneticFieldDriveParameters();
magneticFieldDriveParameters.DriveTime = Byte.Parse(windowViewModel.MFDParam_DriveTimeNew);
magneticFieldDriveParameters.FieldFitA0 = Int32.Parse(windowViewModel.MFDParam_FieldFitA0New);
magneticFieldDriveParameters.FieldFitA1 = Int32.Parse(windowViewModel.MFDParam_FieldFitA1New);
magneticFieldDriveParameters.FieldDriveStepMagnitude = UInt16.Parse(windowViewModel.MFDParam_FieldDriveStepMagnitudeNew);
magneticFieldDriveParameters.FieldControlHysteresis_mG = UInt16.Parse(windowViewModel.MFDParam_FieldControlHysteresis_mGNew);
na2wParamList.Add(magneticFieldDriveParameters);
}
}
if (tag.Equals("InputRangeParameters"))
{
if (
(windowViewModel.IRParam_AdcRailingHighThresholdNew.Length != 0)
&& (windowViewModel.IRParam_AdcRailingLowThresholdNew.Length != 0)
&& (windowViewModel.IRParam_MaxAdcThresholdNew.Length != 0)
&& (windowViewModel.IRParam_MaxElectrodeDeltaNew.Length != 0)
&& (windowViewModel.IRParam_EmfAlarmHoldoffHoursNew.Length != 0)
&& (windowViewModel.IRParam_AdcNoiseThresholdNew.Length != 0)
&& (windowViewModel.IRParam_RawImpedanceClampNew.Length != 0)
&& (windowViewModel.IRParam_MaxFlowRateNew.Length != 0)
&& (windowViewModel.IRParam_MaxFlowRateAlarmCountNew.Length != 0)
&& (windowViewModel.IRParam_FlowRateStdDevInvSlopeNew.Length != 0)
)
{
InputRangeParameters inputRangeParameters =
new InputRangeParameters();
inputRangeParameters.AdcRailingHighThreshold = UInt32.Parse(windowViewModel.IRParam_AdcRailingHighThresholdNew);
inputRangeParameters.AdcRailingLowThreshold = UInt32.Parse(windowViewModel.IRParam_AdcRailingLowThresholdNew);
inputRangeParameters.MaxAdcThreshold = UInt32.Parse(windowViewModel.IRParam_MaxAdcThresholdNew);
inputRangeParameters.MaxElectrodeDelta = UInt16.Parse(windowViewModel.IRParam_MaxElectrodeDeltaNew);
inputRangeParameters.EmfAlarmHoldoffHours = Byte.Parse(windowViewModel.IRParam_EmfAlarmHoldoffHoursNew);
inputRangeParameters.AdcNoiseThreshold = UInt16.Parse(windowViewModel.IRParam_AdcNoiseThresholdNew);
inputRangeParameters.RawImpedanceClamp = UInt32.Parse(windowViewModel.IRParam_RawImpedanceClampNew);
inputRangeParameters.MaxFlowRate = UInt16.Parse(windowViewModel.IRParam_MaxFlowRateNew);
inputRangeParameters.MaxFlowRateAlarmCount = Byte.Parse(windowViewModel.IRParam_MaxFlowRateAlarmCountNew);
inputRangeParameters.FlowRateStdDevInvSlope = Byte.Parse(windowViewModel.IRParam_FlowRateStdDevInvSlopeNew);
na2wParamList.Add(inputRangeParameters);
}
}
if (tag.Equals("LowFlowParameters"))
{
if (
(windowViewModel.LFParam_EntryRateNew.Length != 0)
&& (windowViewModel.LFParam_EntryTimeNew.Length != 0)
&& (windowViewModel.LFParam_ExitRateNew.Length != 0)
&& (windowViewModel.LFParam_ExitTimeNew.Length != 0)
&& (windowViewModel.LFParam_LowPowerDelay_minNew.Length != 0)
)
{
LowFlowParameters lowFlowParameters =
new LowFlowParameters();
lowFlowParameters.EntryRate = UInt16.Parse(windowViewModel.LFParam_EntryRateNew);
lowFlowParameters.EntryTime = UInt16.Parse(windowViewModel.LFParam_EntryTimeNew);
lowFlowParameters.ExitRate = UInt16.Parse(windowViewModel.LFParam_ExitRateNew);
lowFlowParameters.ExitTime = UInt16.Parse(windowViewModel.LFParam_ExitTimeNew);
lowFlowParameters.LowPowerDelay_min = Byte.Parse(windowViewModel.LFParam_LowPowerDelay_minNew);
na2wParamList.Add(lowFlowParameters);
}
}
if (tag.Equals("ImpedanceDriveParameters"))
{
if (
(windowViewModel.IDParam_DriveStrengthNew.Length != 0)
)
{
ImpedanceDriveParameters impedanceDriveParameters =
new ImpedanceDriveParameters();
impedanceDriveParameters.DriveStrength = Byte.Parse(windowViewModel.IDParam_DriveStrengthNew);
na2wParamList.Add(impedanceDriveParameters);
}
}
if (tag.Equals("CalibrationFactor"))
{
if (
(windowViewModel.CalibrationFactorNew.Length != 0)
)
{
CalibrationFactor calibrationFactor =
new CalibrationFactor();
calibrationFactor.Setting = UInt16.Parse(windowViewModel.CalibrationFactorNew);
na2wParamList.Add(calibrationFactor);
}
}
if (tag.Equals("ZeroFlowOffsetParameters"))
{
if (
(windowViewModel.ZFParam_ZeroFlowOffsetNew.Length != 0)
&& (windowViewModel.ZFParam_ZeroFlowOffsetThresholdNew.Length != 0)
)
{
ZeroFlowOffsetParameters zeroFlowOffsetParameters =
new ZeroFlowOffsetParameters();
zeroFlowOffsetParameters.ZeroFlowOffset = UInt16.Parse(windowViewModel.ZFParam_ZeroFlowOffsetNew);
zeroFlowOffsetParameters.ZeroFlowOffsetThreshold = UInt16.Parse(windowViewModel.ZFParam_ZeroFlowOffsetThresholdNew);
na2wParamList.Add(zeroFlowOffsetParameters);
}
}
if (tag.Equals("MeterSize"))
{
MeterSize meterSize =
new MeterSize();
meterSize.Size = windowViewModel.SterlingMeterSizeNew;
na2wParamList.Add(meterSize);
}
if (tag.Equals("TargetFieldParameters"))
{
if (
(windowViewModel.TFParam_NormalPowerTargetFieldNew.Length != 0)
&& (windowViewModel.TFParam_LowPowerTargetFieldNew.Length != 0)
&& (windowViewModel.TFParam_HighPowerTargetFieldNew.Length != 0)
)
{
TargetFieldParameters targetFieldParameters =
new TargetFieldParameters();
targetFieldParameters.NormalPowerTargetField = UInt16.Parse(windowViewModel.TFParam_NormalPowerTargetFieldNew);
targetFieldParameters.LowPowerTargetField = UInt16.Parse(windowViewModel.TFParam_LowPowerTargetFieldNew);
targetFieldParameters.HighPowerTargetField = UInt16.Parse(windowViewModel.TFParam_HighPowerTargetFieldNew);
na2wParamList.Add(targetFieldParameters);
}
}
if (tag.Equals("SpreadSpectrumParameters"))
{
if (
(windowViewModel.SSParam_DisableSpreadSpectrumNew.Length != 0)
&& (windowViewModel.SSParam_AlwaysUseFullRateBagsNew.Length != 0)
&& (windowViewModel.SSParam_PowerUpNew.Length != 0)
&& (windowViewModel.SSParam_HighNoiseNew.Length != 0)
&& (windowViewModel.SSParam_EmptyPipeNew.Length != 0)
&& (windowViewModel.SSParam_BadAdcNew.Length != 0)
&& (windowViewModel.SSParam_InitLearningCompleteCountNew.Length != 0)
&& (windowViewModel.SSParam_MinOffsetLearningSampleCountNew.Length != 0)
&& (windowViewModel.SSParam_AdcShiftUpdateIntervalNew.Length != 0)
&& (windowViewModel.SSParam_MaxPreviousAdcAgeNew.Length != 0)
&& (windowViewModel.SSParam_AdcOffsetLearningGuardNew.Length != 0)
&& (windowViewModel.SSParam_DisplacementCorrectionCountNew.Length != 0)
)
{
SpreadSpectrumParameters spreadSpectrumParameters =
new SpreadSpectrumParameters();
spreadSpectrumParameters.DisableSpreadSpectrum = Boolean.Parse(windowViewModel.SSParam_DisableSpreadSpectrumNew);
spreadSpectrumParameters.AlwaysUseFullRateBags = Boolean.Parse(windowViewModel.SSParam_AlwaysUseFullRateBagsNew);
spreadSpectrumParameters.PowerUp = Byte.Parse(windowViewModel.SSParam_PowerUpNew);
spreadSpectrumParameters.HighNoise = Byte.Parse(windowViewModel.SSParam_HighNoiseNew);
spreadSpectrumParameters.EmptyPipe = Byte.Parse(windowViewModel.SSParam_EmptyPipeNew);
spreadSpectrumParameters.BadAdc = Byte.Parse(windowViewModel.SSParam_BadAdcNew);
spreadSpectrumParameters.InitLearningCompleteCount = UInt16.Parse(windowViewModel.SSParam_InitLearningCompleteCountNew);
spreadSpectrumParameters.MinOffsetLearningSampleCount = UInt16.Parse(windowViewModel.SSParam_MinOffsetLearningSampleCountNew);
spreadSpectrumParameters.AdcShiftUpdateInterval = Byte.Parse(windowViewModel.SSParam_AdcShiftUpdateIntervalNew);
spreadSpectrumParameters.MaxPreviousAdcAge = Byte.Parse(windowViewModel.SSParam_MaxPreviousAdcAgeNew);
spreadSpectrumParameters.AdcOffsetLearningGuard = UInt16.Parse(windowViewModel.SSParam_AdcOffsetLearningGuardNew);
spreadSpectrumParameters.DisplacementCorrectionCount = Byte.Parse(windowViewModel.SSParam_DisplacementCorrectionCountNew);
na2wParamList.Add(spreadSpectrumParameters);
}
}
}
}
if (na2wParamList.Count != 0)
{
ParameterWriteCommand parameterWriteCommand = new ParameterWriteCommand(na2wParamList);
parameterWriteCommand.TagMap = (TagMap)5;
SendNa2wSerial(parameterWriteCommand, false);
}
Thread.Sleep(1000);
if (tagReadList.Count != 0)
{
ParameterReadCommand parameterReadCommand = new ParameterReadCommand((TagMap)5, tagReadList);
SendNa2wSerial(parameterReadCommand, false);
}
}
public void SetOpticalEnableCommand(string command)
{
bool isValidAction = false;
OpticalDataMode opticalDataModeSet = new OpticalDataMode();
if (command.Equals("Enable"))
{
opticalDataModeSet.Mode = OpticalDataMode.Enable;
isValidAction = true;
}
else if (command.Equals("Disable"))
{
opticalDataModeSet.Mode = OpticalDataMode.Disable;
isValidAction = true;
}
if (isValidAction)
{
// Send command to disable/enable Optical Data.
ParameterWriteCommand parameterWriteCommand = new ParameterWriteCommand(opticalDataModeSet);
SendNa2wSerial(parameterWriteCommand, false);
}
}
public void SessionCommand(string command)
{
if (command.Equals("Open"))
{
CommDeviceSessionOpen commDeviceSessionOpen = new CommDeviceSessionOpen();
commDeviceSessionOpen.HostParsed = "GlobalIPerlUtility";
SendNa2wSerial(commDeviceSessionOpen, false);
}
else if (command.Equals("Close"))
{
CommDeviceSessionClose commDeviceSessionClose = new CommDeviceSessionClose();
commDeviceSessionClose.SessionID = sessionId;
SendNa2wSerial(commDeviceSessionClose, false);
}
}
public void FileCommand(string command)
{
String[] cmdArgs = command.Split(new char[] { ' ' }, 2);
if (cmdArgs[0].Equals("ExportConfiguration"))
{
Session session = new Session();
session.Save(cmdArgs[1]);
}
else if (cmdArgs[0].Equals("ImportConfiguration"))
{
Session session = new Session();
session.Load(cmdArgs[1]);
}
else if (cmdArgs[0].Equals("ReadAll"))
{
ReadAllTags();
}
else if (cmdArgs[0].Equals("SaveTags"))
{
String fileName = TagsToCsv(null);
Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " : Tags saved to " + fileName + "\n");
}
else if (cmdArgs[0].Equals("Diagnostics"))
{
string[] files = cmdArgs[1].Split(new char[] { ',' });
string mapFile = string.Empty;
string outputFile = string.Empty;
if (files.Length > 0)
{
outputFile = files[0];
if (files.Length > 1)
{
mapFile = files[1];
}
}
SaveDiagnostics(outputFile, mapFile);
}
}
public void CopyCommand(string command)
{
if (command.Length != 0)
{
string[] commands = command.Split(',');
for (int i = 0; i < commands.Length; i++)
{
string commandIndex = commands[i];
if (commandIndex.Equals("RadioConfiguration"))
{
windowViewModel.TcxoCorrectionNew = windowViewModel.TcxoCorrection;
windowViewModel.RfPowerLevelNew = windowViewModel.RfPowerLevel.Split(' ')[0];
}
else if (commandIndex.Equals("FactoryId"))
{
windowViewModel.FactoryIdNew = windowViewModel.FactoryId;
}
else if (commandIndex.Equals("CustomerId"))
{
windowViewModel.CustomerIdNew = windowViewModel.CustomerId;
}
else if (commandIndex.Equals("BuildInfo"))
{
windowViewModel.BuildInfoNew = windowViewModel.BuildInfo;
}
else if (commandIndex.Equals("ManufactureDate"))
{
UInt32.TryParse(windowViewModel.ManufactureDate, out UInt32 manufactureDate);
windowViewModel.ManufactureDateNew = manufactureDate;
}
else if (commandIndex.Equals("MeterSize"))
{
MeterSizeComboBoxItem comboBoxItem = windowViewModel.MeterSizeCollection.Where(x => x.Name == windowViewModel.SterlingMeterSize).FirstOrDefault();
windowViewModel.SterlingMeterSizeNew = (null != comboBoxItem ? comboBoxItem.Value : (byte)0);
}
else if (commandIndex.Equals("DisplayTimeout"))
{
windowViewModel.DisplayTimeoutNew = windowViewModel.DisplayTimeout;
}
else if (commandIndex.Equals("ZeroFlowOffsetParameters"))
{
windowViewModel.ZFParam_ZeroFlowOffsetNew = windowViewModel.ZFParam_ZeroFlowOffset;
windowViewModel.ZFParam_ZeroFlowOffsetThresholdNew = windowViewModel.ZFParam_ZeroFlowOffsetThreshold;
}
else if (commandIndex.Equals("EmptyPipeParameters"))
{
windowViewModel.EPParam_ImpedanceThresholdNew = windowViewModel.EPParam_ImpedanceThreshold;
windowViewModel.EPParam_EmptyTimeThresholdNew = windowViewModel.EPParam_EmptyTimeThreshold;
windowViewModel.EPParam_HydrationDurationNew = windowViewModel.EPParam_HydrationDuration;
}
else if (commandIndex.Equals("InputRangeParameters"))
{
windowViewModel.IRParam_AdcRailingHighThresholdNew = windowViewModel.IRParam_AdcRailingHighThreshold;
windowViewModel.IRParam_AdcRailingLowThresholdNew = windowViewModel.IRParam_AdcRailingLowThreshold;
windowViewModel.IRParam_MaxAdcThresholdNew = windowViewModel.IRParam_MaxAdcThreshold;
windowViewModel.IRParam_MaxElectrodeDeltaNew = windowViewModel.IRParam_MaxElectrodeDelta;
windowViewModel.IRParam_EmfAlarmHoldoffHoursNew = windowViewModel.IRParam_EmfAlarmHoldoffHours;
windowViewModel.IRParam_AdcNoiseThresholdNew = windowViewModel.IRParam_AdcNoiseThreshold;
windowViewModel.IRParam_RawImpedanceClampNew = windowViewModel.IRParam_RawImpedanceClamp;
windowViewModel.IRParam_MaxFlowRateNew = windowViewModel.IRParam_MaxFlowRate;
windowViewModel.IRParam_MaxFlowRateAlarmCountNew = windowViewModel.IRParam_MaxFlowRateAlarmCount;
windowViewModel.IRParam_FlowRateStdDevInvSlopeNew = windowViewModel.IRParam_FlowRateStdDevInvSlope;
}
else if (commandIndex.Equals("LowFlowParameters"))
{
windowViewModel.LFParam_EntryRateNew = windowViewModel.LFParam_EntryRate;
windowViewModel.LFParam_EntryTimeNew = windowViewModel.LFParam_EntryTime;
windowViewModel.LFParam_ExitRateNew = windowViewModel.LFParam_ExitRate;
windowViewModel.LFParam_ExitTimeNew = windowViewModel.LFParam_ExitTime;
windowViewModel.LFParam_LowPowerDelay_minNew = windowViewModel.LFParam_LowPowerDelay_min;
}
else if (commandIndex.Equals("ImpedanceDriveParameters"))
{
windowViewModel.IDParam_DriveStrengthNew = windowViewModel.IDParam_DriveStrength;
}
else if (commandIndex.Equals("MagneticFieldDriveParameters"))
{
windowViewModel.MFDParam_DriveTimeNew = windowViewModel.MFDParam_DriveTime;
windowViewModel.MFDParam_FieldFitA0New = windowViewModel.MFDParam_FieldFitA0;
windowViewModel.MFDParam_FieldFitA1New = windowViewModel.MFDParam_FieldFitA1;
windowViewModel.MFDParam_FieldDriveStepMagnitudeNew = windowViewModel.MFDParam_FieldDriveStepMagnitude;
windowViewModel.MFDParam_FieldControlHysteresis_mGNew = windowViewModel.MFDParam_FieldControlHysteresis_mG;
}
else if (commandIndex.Equals("MagneticTamperParameters"))
{
windowViewModel.MTParam_MaxPercentErrorNew = windowViewModel.MTParam_MaxPercentError;
windowViewModel.MTParam_DetectionCountsNew = windowViewModel.MTParam_DetectionCounts;
windowViewModel.MTParam_PidSettlingTimeNew = windowViewModel.MTParam_PidSettlingTime;
windowViewModel.MTParam_DriveLowNew = windowViewModel.MTParam_DriveLow;
windowViewModel.MTParam_DriveHighNew = windowViewModel.MTParam_DriveHigh;
}
else if (commandIndex.Equals("ReverseVolumeBufferParameters"))
{
windowViewModel.RVBParam_Threshold_qmlNew = windowViewModel.RVBParam_Threshold_qml;
windowViewModel.RVBParam_Leak_qml_sNew = windowViewModel.RVBParam_Leak_qml_s;
}
else if (commandIndex.Equals("TargetFieldParameters"))
{
windowViewModel.TFParam_NormalPowerTargetFieldNew = windowViewModel.TFParam_NormalPowerTargetField;
windowViewModel.TFParam_LowPowerTargetFieldNew = windowViewModel.TFParam_LowPowerTargetField;
windowViewModel.TFParam_HighPowerTargetFieldNew = windowViewModel.TFParam_HighPowerTargetField;
}
else if (commandIndex.Equals("SpreadSpectrumParameters"))
{
windowViewModel.SSParam_DisableSpreadSpectrumNew = windowViewModel.SSParam_DisableSpreadSpectrum;
windowViewModel.SSParam_AlwaysUseFullRateBagsNew = windowViewModel.SSParam_AlwaysUseFullRateBags;
windowViewModel.SSParam_PowerUpNew = windowViewModel.SSParam_PowerUp;
windowViewModel.SSParam_HighNoiseNew = windowViewModel.SSParam_HighNoise;
windowViewModel.SSParam_EmptyPipeNew = windowViewModel.SSParam_EmptyPipe;
windowViewModel.SSParam_BadAdcNew = windowViewModel.SSParam_BadAdc;
windowViewModel.SSParam_InitLearningCompleteCountNew = windowViewModel.SSParam_InitLearningCompleteCount;
windowViewModel.SSParam_MinOffsetLearningSampleCountNew = windowViewModel.SSParam_MinOffsetLearningSampleCount;
windowViewModel.SSParam_AdcShiftUpdateIntervalNew = windowViewModel.SSParam_AdcShiftUpdateInterval;
windowViewModel.SSParam_MaxPreviousAdcAgeNew = windowViewModel.SSParam_MaxPreviousAdcAge;
windowViewModel.SSParam_AdcOffsetLearningGuardNew = windowViewModel.SSParam_AdcOffsetLearningGuard;
windowViewModel.SSParam_DisplacementCorrectionCountNew = windowViewModel.SSParam_DisplacementCorrectionCount;
}
}
}
}
public void FactoryResetCommand()
{
UInt32 resetFlags = 0;
if (windowViewModel.FactoryResetId) resetFlags |= 0x0001;
if (windowViewModel.FactoryResetCalibration) resetFlags |= 0x0002;
//if (windowViewModel.FactoryResetConfiguration) resetFlags |= 0x0008;
if (windowViewModel.FactoryResetEventLog) resetFlags |= 0x0010;
if (windowViewModel.FactoryResetStatistics) resetFlags |= 0x0004;
if (windowViewModel.FactoryResetProductTime) resetFlags |= 0x0008;
FactoryTestCommand_FactoryReset factTestFactoryReset = new FactoryTestCommand_FactoryReset();
factTestFactoryReset.ProductType = (byte)NA2WProductType.GlobalIPerl;
factTestFactoryReset.ResetFlags = resetFlags;
factTestFactoryReset.ResetDelay = 1000;
SendNa2wSerial(factTestFactoryReset, false);
}
public void TestCommand(string command)
{
if (command.Equals("EngineeringCw"))
{
UInt32 frequency;
Byte duration;
UInt16 transceiverPower;
if (
UInt32.TryParse(windowViewModel.TxEng_Frequency, out frequency)
&& Byte.TryParse(windowViewModel.TxEng_Duration, out duration)
&& UInt16.TryParse(windowViewModel.TxEng_TransceiverPower, out transceiverPower)
)
{
FactoryTestCommand_EngineeringCw factTestCmdEngCw = new FactoryTestCommand_EngineeringCw();
factTestCmdEngCw.Frequency = frequency;
factTestCmdEngCw.Duration = duration;
factTestCmdEngCw.TransceiverPower = transceiverPower;
factTestCmdEngCw.FemPower = 0; // Ignored
factTestCmdEngCw.AttenuatorPower = 0; // Ignored
SendNa2wSerial(factTestCmdEngCw, false);
}
}
else if (command.Equals("EngineeringFcc"))
{
UInt32 frequency;
Byte duration;
UInt16 transceiverPower;
if (
UInt32.TryParse(windowViewModel.TxEng_Frequency, out frequency)
&& Byte.TryParse(windowViewModel.TxEng_Duration, out duration)
&& UInt16.TryParse(windowViewModel.TxEng_TransceiverPower, out transceiverPower)
)
{
FactoryTestCommand_EngineeringFcc factTestCmdEngFcc = new FactoryTestCommand_EngineeringFcc();
factTestCmdEngFcc.Modulation = 10; // SensusRF 100k
factTestCmdEngFcc.Frequency = frequency;
factTestCmdEngFcc.Duration = duration;
factTestCmdEngFcc.TransceiverPower = transceiverPower;
factTestCmdEngFcc.FemPower = 0; // Ignored
factTestCmdEngFcc.AttenuatorPower = 0; // Ignored
SendNa2wSerial(factTestCmdEngFcc, false);
}
}
else if (command.Equals("RegulatoryCw"))
{
UInt32 frequency;
Byte duration;
if (
UInt32.TryParse(windowViewModel.Tx_Frequency, out frequency)
&& Byte.TryParse(windowViewModel.Tx_Duration, out duration)
)
{
FactoryTestCommand_RegulatoryCw factTestCmdRegCw = new FactoryTestCommand_RegulatoryCw();
factTestCmdRegCw.Frequency = frequency;
factTestCmdRegCw.Duration = duration;
factTestCmdRegCw.PowerLevel = Int16.MaxValue; // Ignored
SendNa2wSerial(factTestCmdRegCw, false);
}
}
else if (command.Equals("RegulatoryFcc"))
{
UInt32 frequency;
Byte duration;
if (
UInt32.TryParse(windowViewModel.Tx_Frequency, out frequency)
&& Byte.TryParse(windowViewModel.Tx_Duration, out duration)
)
{
FactoryTestCommand_RegulatoryFcc factTestCmdRegFcc = new FactoryTestCommand_RegulatoryFcc();
factTestCmdRegFcc.Modulation = 10; // SensusRF 100k
factTestCmdRegFcc.Frequency = frequency;
factTestCmdRegFcc.Duration = duration;
factTestCmdRegFcc.PowerLevel = Int16.MaxValue; // Ignored
SendNa2wSerial(factTestCmdRegFcc, false);
}
}
else if (command.Equals("FrequencyCount"))
{
FactoryTestCommand_FrequencyCount factTestFrequencyCount = new FactoryTestCommand_FrequencyCount();
factTestFrequencyCount.Reserved = 0;
SendNa2wSerial(factTestFrequencyCount, false);
}
else if (command.Equals("LockDebugInterface"))
{
FactoryTestCommand_LockDebugInterface lockDebugInterface = new FactoryTestCommand_LockDebugInterface();
SendNa2wSerial(lockDebugInterface, false);
}
}
public partial class Ping_Normal : Sensus.Protocols.FlexNet.Ping
{
public Ping_Normal()
: base()
{
PingType = PingType.Normal;
Init();
}
partial void Init();
public static new Ping_Normal Parse(byte[] buffer, uint offset)
{
return Command.Parse<Ping_Normal>(buffer, offset, CommandLength);
}
}
public void SendPacket(String type)
{
if (type.Equals("Radio"))
{
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = 0x02; // Activity BUP // KGI is this correct?
SendNa2wSerial(engineeringTestCommand, false);
}
else if (type.Equals("ActivityBup"))
{
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = 0x02; // Activity BUP
SendNa2wSerial(engineeringTestCommand, false);
}
#if false // this is an example of sending the set tfx params command as a radio frame
else if (type.Equals("StartPeriodicReadingTransmit"))
{
byte[] payload = new byte[] {
0xAC, 0xC5, // SyncWord
0x1A, // FlexType 10, FlexInfo (1 = downlink)
0x00, 0x00, 0x00, 0x00, // TFX ID
0x12, 0xC0, // Length (18 bytes) & FEC Type (3/4 K=4)
// MAC Header
0x00, 0x40, // Downlink Flags (0 = SessionId) 1(4:6)(4 = Source)(Register)
// MAC Payload
// MAC Payload Header
0x80, 0x03, // Channel (:4), SignaturePresent (:1), Reserved (:2), Length (:9 - 7 = 1+12+1/2)
0xF3, // CmdMsgCode = 0xF3 - Set TFXv2 Parameters
// Set TFXv2 Parameters
0x00, // Version (:4), Reserved (:4)
0x2f, // Device Type (DT47)
0b00111010, // Time Changed (:1), MTR Changed (:1), History Size Changed (:1), TFXv2 State Changed (:1), Active State Changed (:1), Meter Sample Rate Changed (:1), History Scale Changed (:1), Reset History (:1)
0x00, 0x00, 0x00, 0x00, // Epoch Time
0x00, // History Size
(byte)((windowViewModel.MeterTransmitRateNew) | (1<<3) | (1<<5)), // MTR (:3)(), TFXv2 State (:2)(1=active), Active State (:1)(1), Meter Type Changed (:1), Encoder Digits Changed (:1)
0x00, // Meter Units Changed (:1), Meter Sample Rate (:3)(0=5min), Meter Type (:4)
0x00, // Encoder Digits (:3), Reading Resolution Changed (:1), Reading Resolution (:4)
0x00, // History Scale (:2), Meter Units (:3), Reserved (:3)
0x00, // padding
0x00, 0x00, 0x00, 0x00 // CRC
};
UInt32 txAddr;
if (!Conversion.TryParseHexOrDecString(windowViewModel.DeviceIdNew, out txAddr))
{
txAddr = 0x123456;
}
/* Update the DUT address in the payload */
payload.Write<UInt32>(txAddr, (uint)(3) * 8, 32);
/* Calculate and update the CRC */
var crc = ~CRC32.Calculate(payload, 3, payload.Length - 7);
payload.Write<UInt32>(crc, (uint)(payload.Length - 4) * 8, 32);
Frame frame = new Frame(payload);
SendNa2wSerial(frame, false);
}
#endif
else if (type.Equals("StartPeriodicReadingTransmit"))
{
byte[] txPeriodicReading = new byte[] {
0x01, // Active
(byte)(windowViewModel.MeterTransmitRateNew), // MTR
};
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.TxPeriodicReading;
engineeringTestCommand.Payload = new Frame(txPeriodicReading);
SendNa2wSerial(engineeringTestCommand, false);
}
#if false // this is an example of sending the set tfx params command as a radio frame
else if (type.Equals("StopPeriodicReadingTransmit"))
{
byte[] payload = new byte[] {
0xAC, 0xC5, // SyncWord
0x1A, // FlexType 10, FlexInfo (1 = downlink)
0x00, 0x00, 0x00, 0x00, // TFX ID
0x12, 0xC0, // Length (18 bytes) & FEC Type (3/4 K=4)
// MAC Header
0x00, 0x40, // Downlink Flags (0 = SessionId) 1(4:6)(4 = Source)(Register)
// MAC Payload
// MAC Payload Header
0x80, 0x03, // Channel (:4), SignaturePresent (:1), Reserved (:2), Length (:9 - 7 = 1+12+1/2)
0xF3, // CmdMsgCode = 0xF3 - Set TFXv2 Parameters
// Set TFXv2 Parameters
0x00, // Version (:4), Reserved (:4)
0x2f, // Device Type (DT47)
0b00111010, // Time Changed (:1), MTR Changed (:1), History Size Changed (:1), TFXv2 State Changed (:1), Active State Changed (:1), Meter Sample Rate Changed (:1), History Scale Changed (:1), Reset History (:1)
0x00, 0x00, 0x00, 0x00, // Epoch Time
0x00, // History Size
(0) | (0<<3) | (0<<5), // MTR (:3)(6=12seconds), TFXv2 State (:2)(1=active), Active State (:1)(1), Meter Type Changed (:1), Encoder Digits Changed (:1)
0x00, // Meter Units Changed (:1), Meter Sample Rate (:3)(0=5min), Meter Type (:4)
0x00, // Encoder Digits (:3), Reading Resolution Changed (:1), Reading Resolution (:4)
0x00, // History Scale (:2), Meter Units (:3), Reserved (:3)
0x00, // padding
0x00, 0x00, 0x00, 0x00 // CRC
};
UInt32 txAddr;
if (!Conversion.TryParseHexOrDecString(windowViewModel.DeviceIdNew, out txAddr))
{
txAddr = 0x123456;
}
/* Update the DUT address in the payload */
payload.Write<UInt32>(txAddr, (uint)(3) * 8, 32);
/* Calculate and update the CRC */
var crc = ~CRC32.Calculate(payload, 3, payload.Length - 7);
payload.Write<UInt32>(crc, (uint)(payload.Length - 4) * 8, 32);
Frame frame = new Frame(payload);
SendNa2wSerial(frame, false);
}
#endif
else if (type.Equals("StopPeriodicReadingTransmit"))
{
byte[] txPeriodicReading = new byte[] {
0x00, // not Active
0x00, // MTR
};
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.TxPeriodicReading;
engineeringTestCommand.Payload = new Frame(txPeriodicReading);
SendNa2wSerial(engineeringTestCommand, false);
}
else if (type.Equals("Na2wSerial"))
{
try
{
byte[] data = Conversion.HexStringToBytes(windowViewModel.SerialSendData);
if (data.Length > 0)
{
byte code = data[0];
uint payloadLength = (uint)(data.Length - 1);
byte[] payload = new byte[payloadLength];
Array.Copy(data, 1, payload, 0, payloadLength);
SerialCommand serialCommand = new SerialCommand(code, payload);
serialCommand.Bake();
SendNa2wSerial(serialCommand, false);
}
}
catch
{
}
}
}
public void ListenCommand(String type)
{
if (type.Equals("RadioOn"))
{
Byte modulation;
UInt32 frequency;
if (UInt32.TryParse(windowViewModel.Rx_Frequency, out frequency))
{
RadioListenV1 radioListen = new RadioListenV1();
radioListen.PortId = 0x00;
radioListen.DataRate = RadioReceiveDataRate._100kbps;
radioListen.RadioReceiveModulation = (RadioReceiveModulationType)6; // RadioReceiveModulationType._2GFSK_TFX;
radioListen.Frequency = frequency;
if (windowViewModel.Rx_Sensitivity == "Low")
{
radioListen.Sensitivity = 0x01;
}
SendNa2wSerial(radioListen, false);
}
}
else if (type.Equals("RadioOff"))
{
RadioListenV1 radioListen = new RadioListenV1();
radioListen.PortId = 0x00;
radioListen.Frequency = 0x00000; // 0 indicates stop
radioListen.DataRate = RadioReceiveDataRate._100kbps;
radioListen.RadioReceiveModulation = (RadioReceiveModulationType)6; // RadioReceiveModulationType._2GFSK_TFX;
SendNa2wSerial(radioListen, false);
}
else if (type.Equals("RSSI"))
{
Byte modulation;
UInt32 frequency;
if (UInt32.TryParse(windowViewModel.Rx_Frequency, out frequency))
{
FactoryTestCommand_SampleRfSignal sampleRfSignal = new FactoryTestCommand_SampleRfSignal();
sampleRfSignal.Samples = 8;
sampleRfSignal.DataRate = RadioReceiveDataRate._100kbps;
sampleRfSignal.Frequency = frequency;
if (windowViewModel.Rx_Sensitivity == "Low")
{
sampleRfSignal.Sensitivity = 0x01;
}
SendNa2wSerial(sampleRfSignal, false);
}
}
}
public void ResetCommand(String type)
{
if (type.Equals("SW"))
{
ResetSoftware resetSoftware = new ResetSoftware();
resetSoftware.ResetDelay = 1; // 1 ms
SendNa2wSerial(resetSoftware, false);
}
else if (type.Equals("WD"))
{
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.WdReset;
SendNa2wSerial(engineeringTestCommand, false);
}
}
public void PowerDomainCommand(string param)
{
BitArray powerDomainComamndBits = new BitArray(4 * 8); // four bytes of payload
byte[] powerDomainComamndPayload = new byte[4];
if (windowViewModel.PowerDomainEnable_ExternalFlash)
{
powerDomainComamndBits.Set(0x00, true);
}
if (windowViewModel.PowerDomainEnable_RadioTx)
{
powerDomainComamndBits.Set(0x02, true);
}
if (windowViewModel.PowerDomainEnable_RadioRx)
{
powerDomainComamndBits.Set(0x03, true);
}
if (windowViewModel.PowerDomainEnable_Nfc)
{
powerDomainComamndBits.Set(0x0A, true);
}
if (windowViewModel.PowerDomainEnable_Rail)
{
powerDomainComamndBits.Set(0x16, true);
}
if (windowViewModel.PowerDomainEnable_MetrologyAsic)
{
powerDomainComamndBits.Set(0x1C, true);
}
if (windowViewModel.PowerDomainEnable_OpticalLed)
{
powerDomainComamndBits.Set(0x1D, true);
}
if (param == "Enable")
{
powerDomainComamndBits.Set(0x1F, true);
}
else if (param == "Disable")
{
powerDomainComamndBits.Set(0x1F, false);
}
// Convert to byte array with little endianness.
bool bitVal;
uint writeIdx;
int byteIdx, bitIdx;
for (byteIdx = 0; byteIdx < 4; byteIdx++)
{
for (bitIdx = 0; bitIdx < 8; bitIdx++)
{
bitVal = powerDomainComamndBits[byteIdx * 8 + bitIdx];
writeIdx = (uint)(byteIdx * 8) + (uint)(bitIdx);
powerDomainComamndPayload.Write(bitVal, writeIdx, 1);
}
}
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.PowerSwitch;
engineeringTestCommand.Payload = new Frame(powerDomainComamndPayload);
SendNa2wSerial(engineeringTestCommand, false);
}
public void ComaSleepCommand()
{
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.ComaSleep;
SendNa2wSerial(engineeringTestCommand, false);
}
public void ExternalFlashTest(String param)
{
byte[] extFlashTestComamndPayload = new byte[7];
byte startAddrVal = 0;
byte stopAddrVal = 0;
UInt16 cyclesVal = 0;
UInt16 failuresVal = 0;
if (param == "Start")
{
if (Conversion.TryParseHexOrDecString(windowViewModel.ExtFlashStart, out startAddrVal)
&& Conversion.TryParseHexOrDecString(windowViewModel.ExtFlashStop, out stopAddrVal)
&& (windowViewModel.ExtFlashTest_InfiniteCycles || Conversion.TryParseHexOrDecString(windowViewModel.ExtFlashCycles, out cyclesVal))
&& (windowViewModel.ExtFlashTest_InfiniteFailures || Conversion.TryParseHexOrDecString(windowViewModel.ExtFlashFailures, out failuresVal))
)
{
extFlashTestComamndPayload[0] = startAddrVal;
extFlashTestComamndPayload[1] = stopAddrVal;
if (windowViewModel.ExtFlashTest_InfiniteCycles == false)
{
extFlashTestComamndPayload[2] = (byte)(cyclesVal & 0xFF);
extFlashTestComamndPayload[3] = (byte)((cyclesVal >> 8) & 0xFF);
}
else
{
cyclesVal = 0xFFFF;
extFlashTestComamndPayload[2] = (byte)(cyclesVal & 0xFF);
extFlashTestComamndPayload[3] = (byte)((cyclesVal >> 8) & 0xFF);
}
if (windowViewModel.ExtFlashTest_InfiniteFailures == false)
{
extFlashTestComamndPayload[4] = (byte)(failuresVal & 0xFF);
extFlashTestComamndPayload[5] = (byte)((failuresVal >> 8) & 0xFF);
}
else
{
cyclesVal = 0xFFFF;
extFlashTestComamndPayload[4] = (byte)(cyclesVal & 0xFF);
extFlashTestComamndPayload[5] = (byte)((cyclesVal >> 8) & 0xFF);
}
}
else
{
// Parameter parsing failed, do nothing.
System.Console.WriteLine("Malformed parameters.\n");
return;
}
if (windowViewModel.ExtFlashPatternSelectedItem == "0x55")
{
extFlashTestComamndPayload[6] = (byte)0x55;
}
else if (windowViewModel.ExtFlashPatternSelectedItem == "0xAA")
{
extFlashTestComamndPayload[6] = (byte)0xAA;
}
}
else if (param == "Stop")
{
// Do nothing. Cycle count of 0 will cancel the test.
}
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.ExternalFlashTest;
engineeringTestCommand.Payload = new Frame(extFlashTestComamndPayload);
SendNa2wSerial(engineeringTestCommand, false);
}
public void OpticalDataLedTest(String param)
{
byte[] opticalDataLedTestComamndPayload = new byte[1];
if (param.Equals("LedOn"))
{
opticalDataLedTestComamndPayload[0] = 0x01;
}
else if (param.Equals("LedOff"))
{
opticalDataLedTestComamndPayload[0] = 0x00;
}
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.OpticalLedToggle;
engineeringTestCommand.Payload = new Frame(opticalDataLedTestComamndPayload);
SendNa2wSerial(engineeringTestCommand, false);
}
public void NfcEepromTest(String param)
{
byte[] nfcEepromTestComamndPayload = new byte[9];
UInt16 startAddrVal = 0;
UInt16 stopAddrVal = 0;
UInt16 cyclesVal = 0;
UInt16 failuresVal = 0;
if (param == "Start")
{
if (Conversion.TryParseHexOrDecString(windowViewModel.NfcEepromStart, out startAddrVal)
&& Conversion.TryParseHexOrDecString(windowViewModel.NfcEepromStop, out stopAddrVal)
&& (windowViewModel.NfcEepromTest_InfiniteCycles || Conversion.TryParseHexOrDecString(windowViewModel.NfcEepromCycles, out cyclesVal))
&& (windowViewModel.NfcEepromTest_InfiniteFailures || Conversion.TryParseHexOrDecString(windowViewModel.NfcEepromFailures, out failuresVal))
)
{
nfcEepromTestComamndPayload[0] = (byte)(startAddrVal & 0xFF);
nfcEepromTestComamndPayload[1] = (byte)((startAddrVal >> 8) & 0xFF);
nfcEepromTestComamndPayload[2] = (byte)(stopAddrVal & 0xFF);
nfcEepromTestComamndPayload[3] = (byte)((stopAddrVal >> 8) & 0xFF);
if (windowViewModel.NfcEepromTest_InfiniteCycles == false)
{
nfcEepromTestComamndPayload[4] = (byte)(cyclesVal & 0xFF);
nfcEepromTestComamndPayload[5] = (byte)((cyclesVal >> 8) & 0xFF);
}
else
{
cyclesVal = 0xFFFF;
nfcEepromTestComamndPayload[4] = (byte)(cyclesVal & 0xFF);
nfcEepromTestComamndPayload[5] = (byte)((cyclesVal >> 8) & 0xFF);
}
if (windowViewModel.NfcEepromTest_InfiniteFailures == false)
{
nfcEepromTestComamndPayload[6] = (byte)(failuresVal & 0xFF);
nfcEepromTestComamndPayload[7] = (byte)((failuresVal >> 8) & 0xFF);
}
else
{
cyclesVal = 0xFFFF;
nfcEepromTestComamndPayload[6] = (byte)(cyclesVal & 0xFF);
nfcEepromTestComamndPayload[7] = (byte)((cyclesVal >> 8) & 0xFF);
}
}
else
{
// Parameter parsing failed, do nothing.
System.Console.WriteLine("Malformed parameters.\n");
return;
}
if (windowViewModel.NfcEepromPatternSelectedItem == "0x55")
{
nfcEepromTestComamndPayload[8] = (byte)0x55;
}
else if (windowViewModel.NfcEepromPatternSelectedItem == "0xAA")
{
nfcEepromTestComamndPayload[8] = (byte)0xAA;
}
}
else if (param == "Stop")
{
// Do nothing. Cycle count of 0 will cancel the test.
}
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.NfcEepromTest;
engineeringTestCommand.Payload = new Frame(nfcEepromTestComamndPayload);
SendNa2wSerial(engineeringTestCommand, false);
}
public void RefreshComPortListCommand()
{
SetComPortList(GetPortNames());
}
public void ClearCommand(string type)
{
if (type.Equals("RadioReceive"))
{
windowViewModel.ClearRadioReceived();
}
}
public void MemoryReadCommand(String type)
{
if (type.Equals("Start"))
{
UInt32 address;
UInt16 bytes;
String memoryType = windowViewModel.MemoryReadTypeSelectedValue;
if (
Conversion.TryParseHexOrDecString(windowViewModel.MemoryReadAddress, out address)
&& Conversion.TryParseHexOrDecString(windowViewModel.MemoryReadBytes, out bytes)
)
{
MemoryReadCommand memoryReadCommand = new MemoryReadCommand();
memoryReadCommand.Address = address;
memoryReadCommand.NumBytes = bytes;
if (memoryType.Equals("Serial Flash"))
{
memoryReadCommand.Source = 1;
}
else if (memoryType.Equals("Processor"))
{
memoryReadCommand.Source = 0;
}
SendNa2wSerial(memoryReadCommand, false);
}
}
else if (type.Equals("Stop"))
{
}
}
public void EventSendCommand()
{
#if false
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.ESAAPPulseOutputModule;
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.GenerateEvent;
String eventData = windowViewModel.EventSendData.Trim();
if (eventData.Length > 0)
{
if (eventData.Length > 32)
{
eventData = eventData.Substring(0, 32);
}
eventData += '\0';
engineeringTestCommand.Payload = new Frame(eventData.ToASCIIBytes());
}
SendNa2wSerial(engineeringTestCommand, false);
#endif
}
public void ParseCommand(String type)
{
if (type.Equals("Frame"))
{
try
{
byte[] data = Conversion.HexStringToBytes(windowViewModel.FrameParseHexString);
if (data.Length > 0)
{
if (data[0] == 0x1b)
{
ISerialMessageFrame message = (ISerialMessageFrame)ClassicSerialMessageFrame.Parse(data, 0);
windowViewModel.FrameParseText = message.ToString();
}
else if (data[0] == 0x6b)
{
ISerialMessageFrame message = (ISerialMessageFrame)NA2WSerialFrame.Parse(data, 0, (uint)data.Length);
windowViewModel.FrameParseText = message.ToString();
}
}
else
{
windowViewModel.FrameParseText = "";
}
}
catch
{
windowViewModel.FrameParseText = "";
}
}
else if (type.Equals("Stats"))
{
if (windowViewModel.StatsLogSelectedIndex >= 0)
{
// Instantiate the regular expression object.
Regex r = new Regex(@"\((\d+)\)$", RegexOptions.IgnoreCase);
// Match the regular expression pattern against a text string.
Match m = r.Match(windowViewModel.StatsLogCollection[windowViewModel.StatsLogSelectedIndex].Id);
String idMatchString = "";
if (m.Success)
{
Group g = m.Groups[1];
CaptureCollection cc = g.Captures;
Capture c = cc[0];
idMatchString = c.ToString();
}
byte moduleId = Byte.Parse(idMatchString);
byte revision = Byte.Parse(windowViewModel.StatsLogCollection[windowViewModel.StatsLogSelectedIndex].Revision);
byte[] data = Conversion.HexStringToBytes(windowViewModel.StatsLogCollection[windowViewModel.StatsLogSelectedIndex].Data);
windowViewModel.StatsParseText = GlobalIPerlStatistics.Parse((ModuleId)moduleId, revision, data);
}
else
{
windowViewModel.StatsParseText = "";
}
}
}
public void NfcCommand(String type)
{
if (type.Equals("Inventory"))
{
NfcCommand_InventoryRead nfcCommand = new NfcCommand_InventoryRead();
SendNa2wSerial(nfcCommand, false);
}
else if (type.Equals("NDEF Read"))
{
NfcCommand_NdefRead nfcCommand = new NfcCommand_NdefRead();
SendNa2wSerial(nfcCommand, false);
}
}
public void LcdCommand(String type)
{
bool valid = false;
UInt16 duration = 0;
UInt16 period = 0;
byte width = 0;
if (type.Equals("Normal"))
{
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.NormalOperation;
SendNa2wSerial(nfcControlTestCommand, false);
}
else if (type.Equals("SegmentsOn"))
{
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.SegmentsOn;
SendNa2wSerial(nfcControlTestCommand, false);
}
else if (type.Equals("SegmentsOff"))
{
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.SegmentsOff;
SendNa2wSerial(nfcControlTestCommand, false);
}
else if (type.Equals("EvenSegmentsOn"))
{
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.EvenSegmentsOn;
SendNa2wSerial(nfcControlTestCommand, false);
}
else if (type.Equals("OddSegmentsOn"))
{
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.OddSegmentsOn;
SendNa2wSerial(nfcControlTestCommand, false);
}
else if (type.Equals("PowerOff"))
{
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.DisplayPowerOff;
SendNa2wSerial(nfcControlTestCommand, false);
}
else if (type.Equals("TestSequence"))
{
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.TestSequence;
SendNa2wSerial(nfcControlTestCommand, false);
}
else if (type.Equals("SwitchOpen"))
{
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = (byte)3;
SendNa2wSerial(engineeringTestCommand, false);
}
else if (type.Equals("SwitchClose"))
{
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = (byte)4;
SendNa2wSerial(engineeringTestCommand, false);
}
}
public byte[] BuildSensusRFPam(UInt32 srfAddress, byte[] pamPayload, byte[] key)
{
bool encrypted = (key != null);
// Sync 04 25
// Length 3D
// Type 20 (PAM)
// Counter 91
// Address FF C3 87 E9
// CRC 21 96
// PAM Code F8
// PAM Payload 99
// Enc CRC C4 2B
// CRC A8 A1
byte[] srfFrame = new byte[2 + 9 + pamPayload.Length + (encrypted ? 2 : 0) + 2];
// Sync
srfFrame[0] = 0x04;
srfFrame[1] = 0x25;
// Header
// byte Length
// byte AppCode - 32 (PAM)
// byte Counter
// UInt32 Address
// UInt16 HeaderCrc
srfFrame[2] = (byte)(11 + pamPayload.Length + (encrypted ? 2 : 0)); // Header (7) + CRC (2) + PAM Payload + Encryption CRC (2) + Payload CRC (2)
srfFrame[3] = (byte)Sensus.Protocols.SensusRF.TelegramType.PAM;
srfFrame[4] = 1; // Counter.AppSequence = 0x01
srfFrame.Write<UInt32>(srfAddress, (8 * 5), 32, ByteOrder.BigEndian);
UInt16 headerCRC = CRC16.SIRT.Calculate(srfFrame, 2, 7);
srfFrame.Write<UInt16>(headerCRC, (8 * 9), 16, ByteOrder.BigEndian);
// PAM
// byte PamPayload
Array.Copy(pamPayload, 0, srfFrame, 11, pamPayload.Length);
byte[] encryptedData;
int plaintextLength = srfFrame.Length - 2 /* sync */ - 9 /* header and header CRC */ - 2 /* frameCrc */;
if (encrypted)
{
// UInt16 PayloadCrc (Encrypt CRC)
UInt16 payloadCRC = CRC16.SIRT.Calculate(
(
CRC16.SIRT.Calculate(new byte[] { (byte)((srfAddress >> 16) & 0xFF), (byte)((srfAddress >> 8) & 0xFF), (byte)(srfAddress & 0xFF) })
),
srfFrame,
11,
plaintextLength - 2
);
srfFrame.Write<UInt16>(payloadCRC, (uint)(8 * (11 + plaintextLength - 2)), 16, ByteOrder.BigEndian);
// Encrypt
byte[] plaintextData = new byte[plaintextLength];
Array.Copy(srfFrame, 11, plaintextData, 0, plaintextLength);
encryptedData = Sensus.Protocols.SensusRF.TelegramFrame.Encrypt(srfAddress, srfFrame[4], plaintextData, key);
Array.Copy(encryptedData, 0, srfFrame, 11, plaintextLength);
}
else
{
encryptedData = new byte[plaintextLength];
Array.Copy(srfFrame, 11, encryptedData, 0, plaintextLength);
}
// CRC
UInt16 frameCRC = CRC16.SIRT.Calculate(encryptedData);
srfFrame.Write<UInt16>(frameCRC, (uint)(8 * (srfFrame.Length - 2)), 16, ByteOrder.BigEndian);
return srfFrame;
}
public byte[] BuildSensusRFPam(UInt32 srfAddress, byte[] pamPayload, bool encrypt)
{
return BuildSensusRFPam(srfAddress, pamPayload, encrypt ? SensusRfKey() : null);
}
public byte[] BuildSensusRFPam(UInt32 srfAddress, byte[] pamPayload)
{
return BuildSensusRFPam(srfAddress, pamPayload, true);
}
private byte[] PrependAuthLevel(byte[] payload, String levelName)
{
byte[] authPin = new byte[0];
if (levelName.Equals("Level 1"))
{
if (windowViewModel.SRfPin1SelectedItem.Equals("Default"))
{
authPin = new byte[] { 67, 0x01, 0x14, 0x30, 0x68, 0xD0 };
}
}
else if (levelName.Equals("Level 2"))
{
authPin = new byte[] { 67, 0x02, 0x14, 0x0E, 0x80, 0x40 };
}
else if (levelName.Equals("Level 3"))
{
authPin = new byte[] { 67, 0x03, 0x63, 0x93, 0x73, 0x22 };
}
byte[] newPayload = new byte[authPin.Length + payload.Length];
Array.Copy(authPin, newPayload, authPin.Length);
Array.Copy(payload, 0, newPayload, authPin.Length, payload.Length);
return newPayload;
}
public void SensusRfCommand(String type)
{
if (type.Equals("TxBup"))
{
if (false)
{
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.TxBup;
SendNa2wSerial(engineeringTestCommand, false);
}
UInt32 flexNetAddress;
if (Conversion.TryParseHexOrDecString(windowViewModel.DeviceId, out flexNetAddress))
{
Ping_NA2WDataReport_NA2WWater_TimeValues dataReport = new Ping_NA2WDataReport_NA2WWater_TimeValues();
ClassicNA2WCommandFrame commandFrame = new ClassicNA2WCommandFrame(dataReport);
commandFrame.FlexNetID = flexNetAddress;
SerialRadioFrameMessage radioFrame = new SerialRadioFrameMessage(commandFrame);
radioFrame.RadioFrameType = RadioFrameType.FlexNetV1;
SendNa2wSerial(radioFrame);
}
}
else if (type.Equals("CustomPam"))
{
UInt32 sensusRfAddress;
String pamPayload = windowViewModel.PamPayload.Trim();
if (Conversion.TryParseHexOrDecString(windowViewModel.DeviceId, out sensusRfAddress))
{
byte[] pamPayloadArray = ByteArray.FromHexString(pamPayload);
// Add authorization
String authLevel = windowViewModel.SRfAuthSelectedItem;
pamPayloadArray = PrependAuthLevel(pamPayloadArray, authLevel);
byte[] srfCmdFrame = BuildSensusRFPam(sensusRfAddress, pamPayloadArray);
SerialRadioFrameMessage radioFrame = new SerialRadioFrameMessage(new Frame(srfCmdFrame));
radioFrame.RadioFrameType = RadioFrameType.SensusRF;
SendNa2wSerial(radioFrame);
}
}
}
public void TestTotalizerCommand(String type)
{
if (type.Equals("Reset"))
{
TestTotalizer testTotalizer =
new TestTotalizer();
testTotalizer.Value = 0;
List<NA2WParameter> na2wParamList = new List<NA2WParameter>();
na2wParamList.Add(testTotalizer);
ParameterWriteCommand parameterWriteCommand = new ParameterWriteCommand(na2wParamList);
parameterWriteCommand.TagMap = (TagMap)5;
SendNa2wSerial(parameterWriteCommand, false);
}
}
public void SendHandshake()
{
// Send Factory Sleep Open command
FactoryTestOpen factoryTestOpen = new FactoryTestOpen();
factoryTestOpen.SleepTime = GlobalIPerlUtility.Properties.Settings.Default.SleepTime;
SendNa2wSerial(factoryTestOpen, ParameterReadResponse._Code);
}
void MessageReceived(object sender, ReceptionEventArgs<ISerialMessageFrame> args)
{
ISerialMessageFrame message = args.Frame;
LogIncoming(message);
if (message.Payload is ParameterReadResponse)
{
ParameterReadResponse parameterReadResponse = (ParameterReadResponse)message.Payload;
if (parameterReadResponse.TagMap == TagMap.GlobalIPerl)
{
List<NA2WParameter> na2wParameterList = parameterReadResponse.Parameters;
foreach (NA2WParameter na2wParameter in na2wParameterList)
{
switch (na2wParameter.Tag)
{
case ((byte)GlobalIPerlTag.SerialNumber):
windowViewModel.SerialNumber = na2wParameter.Value.Read<UInt64>(0).ToString();
break;
case ((byte)GlobalIPerlTag.DeviceId):
UInt32 deviceId = na2wParameter.Value.Read<UInt32>(0);
if (0xefffffff == deviceId)
{
windowViewModel.DeviceId = "0xEFFFFFFF";
}
else
{
windowViewModel.DeviceId = deviceId.ToString();
}
break;
case ((byte)GlobalIPerlTag.TcxoCorrection):
windowViewModel.TcxoCorrection = na2wParameter.Value.Read<Int16>(0).ToString();
break;
case ((byte)GlobalIPerlTag.PcbVariantId):
windowViewModel.PcbVariantId = na2wParameter.Value[0];
break;
case ((byte)GlobalIPerlTag.PcbVariantIdAdc):
windowViewModel.PcbVariantIdAdc = "0x" + na2wParameter.Value.Read<UInt16>(0).ToString("X4");
break;
case ((byte)GlobalIPerlTag.InitialPcbVariantIdAdc):
windowViewModel.InitialPcbVariantIdAdc = "0x" + na2wParameter.Value.Read<UInt16>(0).ToString("X4");
break;
case ((byte)GlobalIPerlTag.ProductTypeVersion):
String productTypeVersion = "R";
if (0x80 == (na2wParameter.Value[1] & 0x80))
{
productTypeVersion = "B";
}
productTypeVersion += ((uint)((na2wParameter.Value[1] & 0x70) >> 4)).ToString("X1") + ".";
productTypeVersion += ((uint)(na2wParameter.Value[1] & 0x0f)).ToString("X1") + ".";
productTypeVersion += na2wParameter.Value[0].ToString("X2");
windowViewModel.ProductTypeVersion = productTypeVersion;
break;
case ((byte)GlobalIPerlTag.RfPowerLevel):
windowViewModel.RfPowerLevel = "0x" + na2wParameter.Value.Read<Byte>(0).ToString("X2") + " (" + na2wParameter.Value.Read<Byte>(0).ToString() + ")";
break;
case ((byte)GlobalIPerlTag.ProductType):
windowViewModel.ProductType = na2wParameter.Value[0];
break;
case ((byte)GlobalIPerlTag.Capabilities):
{
string capabilities = "";
if (na2wParameter.Value.Read<bool>(0, 1)) { capabilities += "FNv1 "; }
if (na2wParameter.Value.Read<bool>(1, 1)) { capabilities += "FNv2 "; }
if (na2wParameter.Value.Read<bool>(2, 1)) { capabilities += "SRF "; }
if (na2wParameter.Value.Read<bool>(3, 1)) { capabilities += "WMBUS "; }
if (na2wParameter.Value.Read<bool>(4, 1)) { capabilities += "NFC "; }
if (na2wParameter.Value.Read<bool>(5, 1)) { capabilities += "NFC-FN "; }
if (na2wParameter.Value.Read<bool>(6, 1)) { capabilities += "ASK-TX "; }
if (na2wParameter.Value.Read<bool>(7, 1)) { capabilities += "TR "; }
if (na2wParameter.Value.Read<bool>(8, 1)) { capabilities += "ML-TX"; }
capabilities = capabilities.Trim();
capabilities = capabilities.Replace(' ', ',');
windowViewModel.Capabilities = capabilities;
}
break;
case ((byte)GlobalIPerlTag.Mode):
{
string mode = "";
int systemState = na2wParameter.Value.Read<byte>(0, 5);
int topLevelState = na2wParameter.Value.Read<byte>(5, 2);
int cellularState = na2wParameter.Value.Read<byte>(7, 4);
bool factoryFlag = na2wParameter.Value.Read<bool>(11);
bool debugBlockFlag = na2wParameter.Value.Read<bool>(12);
if ((systemState & 1) != 0) mode += "P ";
else if ((systemState & 2) != 0) mode += "S ";
else if ((systemState & 4) != 0) mode += "A ";
else if ((systemState & 8) != 0) mode += "D ";
else if ((systemState & 16) != 0) mode += "E ";
else mode += "? ";
if (0 == topLevelState) mode += "I ";
else if (1 == topLevelState) mode += "W ";
else if (2 == topLevelState) mode += "L ";
else if (3 == topLevelState) mode += "M ";
if ((cellularState & 7) == 0) mode += "! ";
else if ((cellularState & 7) == 1) mode += "C ";
else if ((cellularState & 7) == 2) mode += "r ";
else if ((cellularState & 7) == 3) mode += "R ";
else if ((cellularState & 7) == 4) mode += "T ";
else if ((cellularState & 7) == 5) mode += "F ";
else mode += "? ";
if (factoryFlag) mode += "FT ";
if (debugBlockFlag) mode += "DB ";
mode = mode.Trim();
windowViewModel.Mode = mode;
}
break;
case ((byte)GlobalIPerlTag.SystemTime):
{
windowViewModel.SystemTime = "0x" + na2wParameter.Value.Read<UInt64>(0).ToString("X8");
break;
}
case ((byte)GlobalIPerlTag.ProductTime):
{
windowViewModel.ProductTime = na2wParameter.Value.Read<UInt32>(0).ToString() + " secs";
break;
}
case ((byte)GlobalIPerlTag.Temperature):
windowViewModel.Temperature = ((sbyte)(na2wParameter.Value[0])).ToString() + "C";
break;
case ((byte)GlobalIPerlTag.TemperatureAdc):
windowViewModel.TemperatureAdc = "0x" + na2wParameter.Value.Read<UInt16>(0).ToString("X4");
windowViewModel.Temperature = ((sbyte)(na2wParameter.Value[2])).ToString() + "C";
break;
case ((byte)GlobalIPerlTag.TemperatureCalibration):
windowViewModel.TemperatureCalOffset = (sbyte)(na2wParameter.Value[0]);
break;
case ((byte)GlobalIPerlTag.Vbat):
windowViewModel.Vbat = ((double)(na2wParameter.Value.Read<UInt16>(0)) / 1000).ToString("F3") + "V";
break;
case ((byte)GlobalIPerlTag.VbatAdc):
windowViewModel.VbatAdc = "0x" + na2wParameter.Value.Read<UInt16>(0).ToString("X4");
windowViewModel.Vbat = ((double)(na2wParameter.Value.Read<UInt16>(16)) / 1000).ToString("F3") + "V";
break;
case ((byte)GlobalIPerlTag.VbatCalibration):
windowViewModel.VbatCalOffset = (sbyte)(na2wParameter.Value[0]);
windowViewModel.VbatCalSlope = na2wParameter.Value.Read<UInt16>(8);
break;
case ((byte)GlobalIPerlTag.Vsys):
windowViewModel.Vsys = ((double)(na2wParameter.Value.Read<UInt16>(0)) / 1000).ToString("F3") + "V";
break;
case ((byte)GlobalIPerlTag.VsysAdc):
windowViewModel.VsysAdc = "0x" + na2wParameter.Value.Read<UInt16>(0).ToString("X4");
windowViewModel.Vsys = ((double)(na2wParameter.Value.Read<UInt16>(16)) / 1000).ToString("F3") + "V";
break;
case ((byte)GlobalIPerlTag.VsysCalibration):
windowViewModel.VsysCalOffset = (sbyte)(na2wParameter.Value[0]);
windowViewModel.VsysCalSlope = na2wParameter.Value.Read<UInt16>(8);
break;
case ((byte)GlobalIPerlTag.ProcessorId):
string uuid = "";
for (int i = 0; i < 16; i++)
{
uuid += na2wParameter.Value[i].ToString("X2") + " ";
}
windowViewModel.ProcessorUuid = uuid;
if (na2wParameter.Value.Length >= 20)
{
windowViewModel.ProcessorFlashSize = na2wParameter.Value.Read<UInt16>(16 * 8, 16).ToString() + "kB";
windowViewModel.ProcessorRamSize = na2wParameter.Value.Read<UInt16>(18 * 8, 16).ToString() + "kB";
}
else
{
windowViewModel.ProcessorFlashSize = "";
windowViewModel.ProcessorRamSize = "";
}
break;
case ((byte)GlobalIPerlTag.TransceiverId):
{
string id = "";
id += na2wParameter.Value[0].ToString("X2") + "-"; // Family
id += String.Format("{0}.{1}.{2}.{3}", na2wParameter.Value[1], na2wParameter.Value[2], na2wParameter.Value[3], na2wParameter.Value[4]);
windowViewModel.RadioChip = id;
}
break;
case ((byte)GlobalIPerlTag.SerialFlashId):
{
string id = "";
id += na2wParameter.Value[0].ToString("X2") + "-"; // Family
id += na2wParameter.Value[1].ToString("X2") + na2wParameter.Value[2].ToString("X2") + "-"; // Part
id += na2wParameter.Value[3].ToString("X2"); // Revision
windowViewModel.SerialFlashId = id;
}
break;
case ((byte)GlobalIPerlTag.NfcTagId):
{
string id = "";
id += na2wParameter.Value[0].ToString("X2") + "-"; // Family
id += na2wParameter.Value[1].ToString("X2") + na2wParameter.Value[2].ToString("X2") + "-"; // Part
id += na2wParameter.Value[3].ToString("X2") + "-"; // Revision
// UUID
for (int i = 0; i < 8; i++)
{
id += na2wParameter.Value[4 + i].ToString("X2") + " ";
}
windowViewModel.NfcTagId = id;
}
break;
case ((byte)GlobalIPerlTag.MetrologyId):
{
string id = "";
id += na2wParameter.Value[0].ToString("X2") + "-"; // Family
id += na2wParameter.Value[1].ToString("X2"); // Revision
windowViewModel.MetrologyId = id;
}
break;
case ((byte)GlobalIPerlTag.SecurityCoprocessorId):
{
string id = "";
id += na2wParameter.Value[0].ToString("X2") + "-"; // Family
id += String.Format("{0}.{1}.{2}.{3}", na2wParameter.Value[1], na2wParameter.Value[2], na2wParameter.Value[3], na2wParameter.Value[4]);
windowViewModel.SecurityCoprocessorId = id;
}
break;
case ((byte)GlobalIPerlTag.Reading):
{
UInt32 billingVolume = na2wParameter.Value.Read<UInt32>(16 * 0, 32);
byte units = (byte)(na2wParameter.Value[4]);
string reading = billingVolume.ToString() + " ";
if (units == 19)
{
reading += "l";
}
else
{
reading += "(" + units + ")";
}
reading = reading.Trim();
windowViewModel.Reading = reading;
}
break;
case ((byte)GlobalIPerlTag.Alarms):
{
string alarms = "";
if ((na2wParameter.Value[0] & 0x01) != 0) alarms += "wMB ";
if ((na2wParameter.Value[0] & 0x02) != 0) alarms += "MA ";
if ((na2wParameter.Value[0] & 0x04) != 0) alarms += "BP ";
if ((na2wParameter.Value[0] & 0x08) != 0) alarms += "Bf ";
if ((na2wParameter.Value[0] & 0x10) != 0) alarms += "MetUn ";
if ((na2wParameter.Value[0] & 0x20) != 0) alarms += "MT ";
if ((na2wParameter.Value[0] & 0x40) != 0) alarms += "Leak ";
if ((na2wParameter.Value[0] & 0x80) != 0) alarms += "LBat ";
alarms = alarms.Trim();
alarms = alarms.Replace(' ', ',');
windowViewModel.Alarms = alarms;
}
break;
case ((byte)GlobalIPerlTag.ActivityCredits):
windowViewModel.ActivityCredits = na2wParameter.Value.Read<UInt16>(0).ToString();
break;
case ((byte)GlobalIPerlTag.ManufacturingNote):
windowViewModel.ManufacturingNote = na2wParameter.Value.Read<string>(0, 64 * 8);
break;
case ((byte)GlobalIPerlTag.ResetInfo):
{
UInt16 totalResetCount = na2wParameter.Value.Read<UInt16>(0);
UInt16 wdResetCount = na2wParameter.Value.Read<UInt16>(16);
UInt16 swResetCount = na2wParameter.Value.Read<UInt16>(32);
UInt16 fwdlResetCount = na2wParameter.Value.Read<UInt16>(48);
UInt32 lastResetCause = na2wParameter.Value.Read<UInt32>(64);
windowViewModel.ResetInfo = "Cnt: " + String.Format("{0:00000} ", totalResetCount);
windowViewModel.ResetInfo += "WD: " + String.Format("{0:00000} ", wdResetCount);
windowViewModel.ResetInfo += "SW: " + String.Format("{0:00000} ", swResetCount);
windowViewModel.ResetInfo += "UPG: " + String.Format("{0:00000} ", fwdlResetCount);
String lastResetCauseName = "Unknown";
// Convert to FG2x causes
switch (lastResetCause)
{
case (1 << 0):
lastResetCauseName = "Power On";
break;
case (1 << 1):
lastResetCauseName = "External Pin";
break;
case (1 << 2):
lastResetCauseName = "EM4";
break;
case (1 << 3):
lastResetCauseName = "Watchdog 0";
break;
case (1 << 4):
lastResetCauseName = "Watchdog 1";
break;
case (1 << 5):
lastResetCauseName = "Lockup";
break;
case (1 << 6):
lastResetCauseName = "System Request";
break;
case (1 << 7):
lastResetCauseName = "BOD DVDD";
break;
case (1 << 8):
lastResetCauseName = "BOD DVDD LE";
break;
case (1 << 9):
lastResetCauseName = "BOD Decouple";
break;
case (1 << 10):
lastResetCauseName = "BOD AVDD";
break;
case (1 << 11):
lastResetCauseName = "BOD IOVDD";
break;
case ((uint)1 << 31):
lastResetCauseName = "DCDC VREGIN";
break;
}
windowViewModel.ResetInfo += "Last Reason: " + lastResetCauseName;
}
break;
case ((byte)GlobalIPerlTag.FlashCrc):
{
UInt16 crc = na2wParameter.Value.Read<ushort>(0);
windowViewModel.FlashCrc = crc;
break;
}
case ((byte)GlobalIPerlTag.RHumidId):
{
windowViewModel.RHumidId = "" + (char)na2wParameter.Value.Read<sbyte>(8) + (char)na2wParameter.Value.Read<sbyte>(0)
+ (na2wParameter.Value[2] | na2wParameter.Value[3] << 8);
break;
}
case ((byte)GlobalIPerlTag.RHumid):
{
windowViewModel.RHumid = na2wParameter.Value.Read<sbyte>(0).ToString() + "%";
break;
}
case ((byte)GlobalIPerlTag.RHumidCalOffset):
{
windowViewModel.RHumidCalOffset = na2wParameter.Value.Read<sbyte>(0);
break;
}
}
}
// Look for factory handshake: ParameterRead with 2 parameters - Product Type and Product Type Version
if ((2 == na2wParameterList.Count)
&& (na2wParameterList[0].Tag == (byte)GlobalIPerlTag.ProductType)
&& (na2wParameterList[1].Tag == (byte)GlobalIPerlTag.ProductTypeVersion)
)
{
if (windowViewModel.IsFactoryHandshakeEnabled)
{
Thread t = new Thread(new ThreadStart(SendHandshake));
t.Start();
}
}
}
if (parameterReadResponse.TagMap == (TagMap)0x05)
{
List<NA2WParameter> na2wParameterList = parameterReadResponse.Parameters;
foreach (NA2WParameter na2wParameter in na2wParameterList)
{
switch (na2wParameter.Tag)
{
case ((byte)SterlingMetrologyTag.FactoryId):
const byte FACTORY_ID_NUM_BYTES = (12);
windowViewModel.FactoryId = na2wParameter.Value.Read<string>(0 * 8, FACTORY_ID_NUM_BYTES * 8);
break;
case ((byte)SterlingMetrologyTag.CustomerId):
const byte CUSTOMER_ID_NUM_BYTES = (12);
windowViewModel.CustomerId = na2wParameter.Value.Read<string>(0 * 8, CUSTOMER_ID_NUM_BYTES * 8);
break;
case ((byte)SterlingMetrologyTag.BuildInformation):
const byte BUILD_INFO_NUM_BYTES = (14);
windowViewModel.BuildInfo = na2wParameter.Value.Read<string>(0 * 8, BUILD_INFO_NUM_BYTES * 8);
break;
case ((byte)SterlingMetrologyTag.ManufactureDate):
{
UInt32 manufactureDate = na2wParameter.Value.Read<UInt32>(0 * 8, 32);
windowViewModel.ManufactureDate = manufactureDate.ToString();
}
break;
case ((byte)SterlingMetrologyTag.CalibrationStatus):
String fwVersion = "R";
if (0x80 == (na2wParameter.Value[6] & 0x80))
{
fwVersion = "B";
}
fwVersion += ((uint)((na2wParameter.Value[6] & 0x70) >> 4)).ToString("X1") + ".";
fwVersion += ((uint)(na2wParameter.Value[6] & 0x0f)).ToString("X1") + ".";
fwVersion += na2wParameter.Value[5].ToString("X2");
String calibrationStatus =
String.Format(
"{0} {1} {2} {3}",
na2wParameter.Value.Read<Byte>(0 * 8),
na2wParameter.Value.Read<UInt32>(1 * 8),
fwVersion,
na2wParameter.Value.Read<UInt32>(7 * 8)
);
windowViewModel.SterlingCalibrationStatus = calibrationStatus;
break;
case ((byte)SterlingMetrologyTag.Reading):
{
UInt32 totalizer = na2wParameter.Value.Read<UInt32>(0 * 8, 32);
windowViewModel.Reading_Totalizer = totalizer.ToString("D9");
sbyte digits = na2wParameter.Value.Read<sbyte>(4 * 8, 8);
windowViewModel.Reading_Digits = digits.ToString();
sbyte shift = na2wParameter.Value.Read<sbyte>(5 * 8, 8);
windowViewModel.Reading_Shift = shift.ToString();
sbyte resolution = na2wParameter.Value.Read<sbyte>(6 * 8, 8);
windowViewModel.Reading_Resolution = resolution.ToString();
double billing = totalizer;
billing *= Math.Pow(10, resolution);
UInt32 billingNumber = (UInt32)billing;
UInt32 billingFraction = (UInt32)( totalizer - (billingNumber * Math.Pow(10, -resolution) ) );
String billingNumberString = billingNumber.ToString("000000000");
String billingFractionString = billingFraction.ToString("000000000");
int resolutionLocation = -resolution;
int amrStartLocation = -shift;
int clip = 9 - (digits - (resolutionLocation - amrStartLocation) );
if (clip > 0) billingNumberString = billingNumberString.Substring(clip);
int fractionDigits = resolutionLocation - amrStartLocation;
if (resolutionLocation > 0) billingFractionString = billingFractionString.Substring(9 - resolutionLocation);
if (fractionDigits > 0) billingFractionString = billingFractionString.Substring(0, fractionDigits);
windowViewModel.Reading = billingNumberString + "." + billingFractionString;
windowViewModel.Reading_Units = na2wParameter.Value.Read<byte>(7 * 8, 8).ToString();
windowViewModel.Reading_FlowDirection = na2wParameter.Value.Read<sbyte>(8 * 8, 8).ToString();
windowViewModel.Reading_FlowRate = na2wParameter.Value.Read<Int16>(9 * 8, 16).ToString();
}
break;
case ((byte)SterlingMetrologyTag.MeterState):
{
byte meterState = na2wParameter.Value.Read<byte>(0, 8);
String meterStateString = String.Format("0x{0:X2} - Unknown", meterState);
foreach (MeterStateComboBoxItem meterStateComboBoxItem in windowViewModel.MeterStateCollection)
{
if (meterStateComboBoxItem.Value == meterState)
{
meterStateString = meterStateComboBoxItem.Name;
break;
}
}
windowViewModel.SterlingMeterState = meterStateString;
}
break;
case ((byte)SterlingMetrologyTag.OpticalDataMode):
{
byte mode = na2wParameter.Value.Read<byte>(0, 8);
String opticalDataModeString = String.Format("0x{0:X2} - Unknown", mode);
foreach (OpticalModeComboBoxItem opticalModeComboBoxItem in windowViewModel.OpticalModeCollection)
{
if (opticalModeComboBoxItem.Value == mode)
{
opticalDataModeString = opticalModeComboBoxItem.Name;
break;
}
}
windowViewModel.OpticalDataMode = opticalDataModeString;
break;
}
case ((byte)SterlingMetrologyTag.DisplayTimeout):
{
windowViewModel.DisplayTimeout = na2wParameter.Value.Read<byte>(0 * 8).ToString();
}
break;
case ((byte)SterlingMetrologyTag.TestTotalizer):
{
UInt32 testTotalizer = na2wParameter.Value.Read<UInt32>(0 * 8, 32);
windowViewModel.TestTotalizer = testTotalizer.ToString("D9");
}
break;
case ((byte)SterlingMetrologyTag.Temperature):
{
Int16 temperature_tC = na2wParameter.Value.Read<Int16>(0 * 8, 16);
double temperature_C = (temperature_tC / 10.0); // Convert reading to just degrees C
windowViewModel.ASICTemperature = temperature_C.ToString() + "C";
Int16 temperatureMax_tC = na2wParameter.Value.Read<Int16>(2 * 8, 16);
double temperatureMax_C = (temperatureMax_tC / 10.0); // Convert reading to just degrees C
windowViewModel.ASICTemperatureMax = temperatureMax_C.ToString() + "C";
Int16 temperatureMin_tC = na2wParameter.Value.Read<Int16>(4 * 8, 16);
double temperatureMin_C = (temperatureMin_tC / 10.0); // Convert reading to just degrees C
windowViewModel.ASICTemperatureMin = temperatureMin_C.ToString() + "C";
}
break;
case ((byte)SterlingMetrologyTag.TemperatureAdc):
{
UInt16 temperatureAdc = na2wParameter.Value.Read<UInt16>(0 * 8, 16);
windowViewModel.ASICTemperatureAdc = "0x" + temperatureAdc.ToString("X4");
Int16 Temperature_tC = na2wParameter.Value.Read<Int16>(2 * 8, 16);
double Temperature_C = (Temperature_tC / 10.0); // Convert reading to just degrees C
windowViewModel.ASICTemperature = Temperature_C.ToString() + "C";
}
break;
case ((byte)SterlingMetrologyTag.TemperatureCalibration):
{
Int16 temperatureCal = na2wParameter.Value.Read<Int16>(0 * 8, 16);
windowViewModel.ASICTemperatureCalibration = temperatureCal;
}
break;
case ((byte)SterlingMetrologyTag.Vbat):
{
UInt16 vbat_mV = na2wParameter.Value.Read<UInt16>(0 * 8, 16);
double vbat_V = ((double)vbat_mV / 1000.0); // Convert reading from mV to just V
windowViewModel.ASICVbat = vbat_V.ToString("F3") + "V";
UInt16 vbatMax_mV = na2wParameter.Value.Read<UInt16>(2 * 8, 16);
double vbatMax_V = ((double)vbatMax_mV / 1000.0); // Convert reading from mV to just V
windowViewModel.ASICVbatMax = vbatMax_V.ToString("F3") + "V";
UInt16 vbatMin_mV = na2wParameter.Value.Read<UInt16>(4 * 8, 16);
double vbatMin_V = ((double)vbatMin_mV / 1000.0); // Convert reading from mV to just V
windowViewModel.ASICVbatMin = vbatMin_V.ToString("F3") + "V";
}
break;
case ((byte)SterlingMetrologyTag.VbatAdc):
{
UInt16 vbatAdc = na2wParameter.Value.Read<UInt16>(0 * 8, 16);
windowViewModel.ASICVbatAdc = "0x" + vbatAdc.ToString("X4");
UInt16 vbat_mV = na2wParameter.Value.Read<UInt16>(2 * 8, 16);
double vbat_V = ((double)vbat_mV / 1000.0); // Convert reading from mV to just V
windowViewModel.ASICVbat = vbat_V.ToString("F3") + "V";
}
break;
case (byte)SterlingMetrologyTag.DisplaySwitchAdc:
{
UInt32 reading = na2wParameter.Value.Read<UInt32>(0 * 8, 32);
windowViewModel.DisplaySwitchReading = "0x" + reading.ToString("X8");
Byte state = na2wParameter.Value.Read<Byte>(4 * 8, 8);
if (1 == state)
{
windowViewModel.DisplaySwitchState = String.Format("Closed (0x{0,2:X2})", state);
}
else if (2 == state)
{
windowViewModel.DisplaySwitchState = String.Format("Opened (0x{0,2:X2})", state);
}
else
{
windowViewModel.DisplaySwitchState = String.Format("Unknown (0x{0,2:X2})", state);
}
}
break;
case ((byte)SterlingMetrologyTag.EmptyPipeParameters):
windowViewModel.EPParam_ImpedanceThreshold = na2wParameter.Value.Read<UInt16>(0 * 8).ToString();
windowViewModel.EPParam_EmptyTimeThreshold = na2wParameter.Value.Read<Byte>(2 * 8).ToString();
windowViewModel.EPParam_HydrationDuration = na2wParameter.Value.Read<Byte>(3 * 8).ToString();
break;
case ((byte)SterlingMetrologyTag.MagneticFieldDriveParameters):
windowViewModel.MFDParam_DriveTime = na2wParameter.Value.Read<Byte>(0 * 8).ToString();
windowViewModel.MFDParam_FieldFitA0 = na2wParameter.Value.Read<Int32>(1 * 8).ToString();
windowViewModel.MFDParam_FieldFitA1 = na2wParameter.Value.Read<Int32>(5 * 8).ToString();
windowViewModel.MFDParam_FieldDriveStepMagnitude = na2wParameter.Value.Read<UInt16>(9 * 8).ToString();
windowViewModel.MFDParam_FieldControlHysteresis_mG = na2wParameter.Value.Read<UInt16>(11 * 8).ToString();
break;
case ((byte)SterlingMetrologyTag.MagneticTamperParameters):
windowViewModel.MTParam_MaxPercentError = na2wParameter.Value.Read<Byte>(0 * 8).ToString();
windowViewModel.MTParam_DetectionCounts = na2wParameter.Value.Read<Byte>(1 * 8).ToString();
windowViewModel.MTParam_PidSettlingTime = na2wParameter.Value.Read<Byte>(2 * 8).ToString();
windowViewModel.MTParam_DriveLow = na2wParameter.Value.Read<Byte>(3 * 8).ToString();
windowViewModel.MTParam_DriveHigh = na2wParameter.Value.Read<Byte>(4 * 8).ToString();
break;
case ((byte)SterlingMetrologyTag.ReverseVolumeBufferParameters):
windowViewModel.RVBParam_Threshold_qml = na2wParameter.Value.Read<UInt32>(0 * 8).ToString();
windowViewModel.RVBParam_Leak_qml_s = na2wParameter.Value.Read<UInt16>(4 * 8).ToString();
break;
case ((byte)SterlingMetrologyTag.InputRangeParameters):
windowViewModel.IRParam_AdcRailingHighThreshold = na2wParameter.Value.Read<UInt32>(0 * 8).ToString();
windowViewModel.IRParam_AdcRailingLowThreshold = na2wParameter.Value.Read<UInt32>(4 * 8).ToString();
windowViewModel.IRParam_MaxAdcThreshold = na2wParameter.Value.Read<UInt32>(8 * 8).ToString();
windowViewModel.IRParam_MaxElectrodeDelta = na2wParameter.Value.Read<UInt16>(12 * 8).ToString();
windowViewModel.IRParam_EmfAlarmHoldoffHours = na2wParameter.Value.Read<Byte>(14 * 8).ToString();
windowViewModel.IRParam_AdcNoiseThreshold = na2wParameter.Value.Read<UInt16>(15 * 8).ToString();
windowViewModel.IRParam_RawImpedanceClamp = na2wParameter.Value.Read<UInt32>(17 * 8).ToString();
windowViewModel.IRParam_MaxFlowRate = na2wParameter.Value.Read<UInt16>(21 * 8).ToString();
windowViewModel.IRParam_MaxFlowRateAlarmCount = na2wParameter.Value.Read<Byte>(23 * 8).ToString();
windowViewModel.IRParam_FlowRateStdDevInvSlope = na2wParameter.Value.Read<Byte>(24 * 8).ToString();
break;
case ((byte)SterlingMetrologyTag.LowFlowParameters):
windowViewModel.LFParam_EntryRate = na2wParameter.Value.Read<UInt16>(0 * 8).ToString();
windowViewModel.LFParam_EntryTime = na2wParameter.Value.Read<UInt16>(2 * 8).ToString();
windowViewModel.LFParam_ExitRate = na2wParameter.Value.Read<UInt16>(4 * 8).ToString();
windowViewModel.LFParam_ExitTime = na2wParameter.Value.Read<UInt16>(6 * 8).ToString();
windowViewModel.LFParam_LowPowerDelay_min = na2wParameter.Value.Read<Byte>(8 * 8).ToString();
break;
case ((byte)SterlingMetrologyTag.ImpedanceDriveParameters):
windowViewModel.IDParam_DriveStrength = na2wParameter.Value.Read<Byte>(0 * 8).ToString();
break;
case ((byte)SterlingMetrologyTag.CalibrationFactor):
windowViewModel.CalibrationFactor = na2wParameter.Value.Read<UInt16>(0 * 8).ToString();
break;
case ((byte)SterlingMetrologyTag.ZeroFlowOffsetParameters):
windowViewModel.ZFParam_ZeroFlowOffset = na2wParameter.Value.Read<UInt16>(0 * 8).ToString();
windowViewModel.ZFParam_ZeroFlowOffsetThreshold = na2wParameter.Value.Read<UInt16>(2 * 8).ToString();
break;
case ((byte)SterlingMetrologyTag.TargetFieldParameters):
windowViewModel.TFParam_NormalPowerTargetField = na2wParameter.Value.Read<UInt16>(0 * 8).ToString();
windowViewModel.TFParam_LowPowerTargetField = na2wParameter.Value.Read<UInt16>(2 * 8).ToString();
windowViewModel.TFParam_HighPowerTargetField = na2wParameter.Value.Read<UInt16>(4 * 8).ToString();
break;
case ((byte)SterlingMetrologyTag.SpreadSpectrumParameters):
windowViewModel.SSParam_DisableSpreadSpectrum = na2wParameter.Value.Read<Boolean>(0, 1).ToString();
windowViewModel.SSParam_AlwaysUseFullRateBags = na2wParameter.Value.Read<Boolean>(1, 1).ToString();
windowViewModel.SSParam_PowerUp = na2wParameter.Value.Read<Byte>(1 * 8).ToString();
windowViewModel.SSParam_HighNoise = na2wParameter.Value.Read<Byte>(2 * 8).ToString();
windowViewModel.SSParam_EmptyPipe = na2wParameter.Value.Read<Byte>(3 * 8).ToString();
windowViewModel.SSParam_BadAdc = na2wParameter.Value.Read<Byte>(4 * 8).ToString();
windowViewModel.SSParam_InitLearningCompleteCount = na2wParameter.Value.Read<UInt16>(5 * 8).ToString();
windowViewModel.SSParam_MinOffsetLearningSampleCount = na2wParameter.Value.Read<UInt16>(7 * 8).ToString();
windowViewModel.SSParam_AdcShiftUpdateInterval = na2wParameter.Value.Read<Byte>(9 * 8).ToString();
windowViewModel.SSParam_MaxPreviousAdcAge = na2wParameter.Value.Read<Byte>(10 * 8).ToString();
windowViewModel.SSParam_AdcOffsetLearningGuard = na2wParameter.Value.Read<UInt16>(11 * 8).ToString();
windowViewModel.SSParam_DisplacementCorrectionCount = na2wParameter.Value.Read<Byte>(13 * 8).ToString();
break;
case ((byte)SterlingMetrologyTag.MeterSize):
{
byte meterSize = na2wParameter.Value.Read<byte>(0, 8);
String meterSizeString = String.Format("0x{0:X2} - Unknown", meterSize);
foreach (MeterSizeComboBoxItem meterSizeComboBoxItem in windowViewModel.MeterSizeCollection)
{
if (meterSizeComboBoxItem.Value == meterSize)
{
meterSizeString = meterSizeComboBoxItem.Name;
break;
}
}
windowViewModel.SterlingMeterSize = meterSizeString;
}
break;
}
}
}
}
else if (message.Payload is SerialRadioFrameMessage)
{
SerialRadioFrameMessage serialRadioFrameMessage = (SerialRadioFrameMessage)message.Payload;
string timeStamp = DateTime.Now.ToLongTimeString(); // serialRadioReceiveMessageV1.TimeStamp.ToString();
string description = "";
ChannelizedFlexNetId channelizedFlexNetId = new ChannelizedFlexNetId();
if ((serialRadioFrameMessage.Payload is ClassicFlexNetMessageFrame) || ((SyncWord)serialRadioFrameMessage.Payload.ToArray().Read<UInt16>(0, 16) == SyncWord.Classic))
{
description = "Classic";
ClassicFlexNetMessageFrame frame = ClassicFlexNetMessageFrame.Parse(serialRadioFrameMessage.Payload.ToArray(), 0);
channelizedFlexNetId.ID = frame.FlexNetID;
channelizedFlexNetId.Channel = 0;
description += ", " + frame.FlexNetID;
description += ", " + String.Format("0x{0:X2} (", frame.AppCode) + frame.AppCode + ")";
description += frame.Payload.ToString();
}
else
{
byte[] payload = serialRadioFrameMessage.Payload.ToBytes();
if (payload.Length > 9)
{
SyncWord syncWord = (SyncWord)payload.Read<UInt16>(0, 16);
FlexType flexType = (FlexType)payload.Read<byte>(16, 4);
if (
(syncWord == SyncWord.Classic)
|| ((syncWord == SyncWord.GFSK) && (flexType == FlexType.NALinePowered))
)
{
UInt32 flexNetId = payload.Read<UInt32>(32, 28);
bool downlinkFlag = payload.Read<bool>(64, 1);
description = "FT1, " + (downlinkFlag ? "DL, " : "UL, ") + flexNetId;
channelizedFlexNetId.ID = flexNetId;
}
else if ((syncWord == (SyncWord)0xc5ac) && (flexType == (FlexType)10))
{
UInt32 TfxId = payload.Read<UInt32>(24, 32);
bool downlinkFlag = payload.Read<bool>(20, 1);
if (15 <= payload.Length)
{
byte cmdOrAppCode = payload.Read<byte>(8 * 15, 8);
if (0xF3 == cmdOrAppCode && 40 <= payload.Length)
{
byte version = payload.Read<byte>(8 * 16, 4);
byte deviceType = payload.Read<byte>(8 * 17, 8);
UInt32 epochTime = payload.Read<UInt32>(8 * 18, 32);
byte historySize = payload.Read<byte>(8 * 22, 8);
byte meterTransmitRate = payload.Read<byte>(8 * 23, 3);
byte tfxState = payload.Read<byte>(8 * 23 + 3, 2);
bool activeState = payload.Read<bool>(8 * 23 + 5, 1);
byte meterSampleRate = payload.Read<byte>(8 * 24 + 5, 3);
byte meterType = payload.Read<byte>(8 * 25, 4);
byte readingResolution = payload.Read<byte>(8 * 25 + 4, 4);
byte encoderDigits = payload.Read<byte>(8 * 26, 3);
byte historyScale = payload.Read<byte>(8 * 26 + 3, 2);
byte meterUnits = payload.Read<byte>(8 * 26 + 5, 3);
byte[] customerSerialNumber = payload.Read<byte[]>(8 * 27, 8 * 13);
description = "FT10, "
+ (downlinkFlag ? "DL, " : "UL, ")
+ TfxId
+ ", TFX Params, "
+ $"V:{version},DT:{deviceType},T:{epochTime},HS:{historySize},MTR:{meterTransmitRate},S:{tfxState},A:{activeState},MSR:{meterSampleRate},MT:{meterType},Res:{readingResolution},Dig:{encoderDigits},Scale:{historyScale},Units:{meterUnits}"
+ $",SN:{ASCIIEncoding.ASCII.GetString(customerSerialNumber).Trim()}";
}
else
{
description = "FT10, " + (downlinkFlag ? "DL, " : "UL, ") + TfxId + ", " + cmdOrAppCode;
}
}
else
{
description = "FT10, " + (downlinkFlag ? "DL, " : "UL, ") + TfxId;
}
}
else if (syncWord == (SyncWord)(0x2504))
{
// SensusRF
byte length = payload[2];
uint appCodeIndex = 3;
if (length < 8)
{
// No length byte, length fixed to 13 bytes
length = 13;
appCodeIndex = 2;
}
Sensus.Protocols.SensusRF.TelegramType telegramType = (Sensus.Protocols.SensusRF.TelegramType)(payload[appCodeIndex]);
byte counter = payload[appCodeIndex + 1];
UInt32 radioAddress = payload.Read<UInt32>((appCodeIndex + 2) * 8, 32, ByteOrder.BigEndian);
if ((telegramType == Sensus.Protocols.SensusRF.TelegramType.BUPWithLAT) || (telegramType == Sensus.Protocols.SensusRF.TelegramType.BUPWithoutLAT))
{
// Buf[0] - App Code
// Buf[1] - FlexNet Counter
// Buf[2] - Module Address
// Buf[3] - Module Address
// Buf[4] - Module Address
// Buf[5] - Module Address
// Buf[6] - Display Volume
// Buf[7] - Display Volume
// Buf[8] - Display Volume
// Buf[9] - Display Volume
// Buf[10] - Alarms
// Buf[11] - crc
// Buf[12] - crc
// Decrypt Volume through CRC. Only method I found in Sensus.dll was a static function
// in TelegramFrame class. TelegramFrame is a serial packet from/to SIRT. The decrypt
// function appears to work well.
byte[] encryptedTelegramData = new byte[7];
Array.Copy(payload, (int)appCodeIndex + 6, encryptedTelegramData, 0, 7);
UInt16 rawActualCRC = encryptedTelegramData.Read<UInt16>((uint)(encryptedTelegramData.Length - 2) * 8, 16, ByteOrder.BigEndian);
UInt16 actualCRC = 0x0000;
UInt16 expectedCRC = 0xffff;
byte[] plaintext = new byte[0];
byte[] key = SensusRfDecryptKey();
if (null != key)
{
plaintext = Sensus.Protocols.SensusRF.TelegramFrame.Decrypt(radioAddress, counter, encryptedTelegramData, key);
actualCRC = plaintext.Read<UInt16>((uint)(plaintext.Length - 2) * 8, 16, ByteOrder.BigEndian);
expectedCRC = CRC16.SIRT.Calculate(
(
length == 0x0d
? CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
: CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 16) & 0xFF), (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
),
plaintext,
0,
plaintext.Length - 2
);
}
// CRCs will match if decryption was successful
if (actualCRC == expectedCRC)
{
UInt32 volume = plaintext.Read<UInt32>((0) * 8, 32, ByteOrder.BigEndian);
description = telegramType.ToString() + ", " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + String.Format(" {0:d8} (0x{0:X4})", volume, volume);
// Create frame event
BupReceived(radioAddress, new Frame(plaintext));
}
else if (rawActualCRC == 0) // Unencrypted has CRC set to 0
{
UInt32 volume = encryptedTelegramData.Read<UInt32>((0) * 8, 32, ByteOrder.BigEndian);
description = telegramType.ToString() + " (unencrypted), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + String.Format(" {0:d8} (0x{0:X4})", volume, volume);
// Create frame event
BupReceived(radioAddress, new Frame(encryptedTelegramData));
}
else
{
description = telegramType.ToString() + ", " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", Decryption Failed" + ", " + encryptedTelegramData.ToHexString();
}
}
else if (telegramType == Sensus.Protocols.SensusRF.TelegramType.PAM)
{
// Header
// byte Length (includes header and payload CRC)
// byte AppCode - 32 (PAM) - appCodeIndex
// byte Counter - appCodeIndex + 1
// UInt32 Address - appCodeIndex + 2, 3, 4, 5
// UInt16 HeaderCrc - appCodeIndex + 6, 7
// byte PamCode - 144 (0x90)
// byte PamLen
// byte FlexNetFrame[SENSUS_RF_PAM_ENCAP_FLEXNET_FRAME_LENGTH] (46)
// Decrypt Volume through CRC. Only method I found in Sensus.dll was a static function
// in TelegramFrame class. TelegramFrame is a serial packet from/to SIRT. The decrypt
// function appears to work well.
int encyptPayloadLength = length - 7 /* header */ - 2 /* header CRC */ - 2 /*payload CRC */;
byte[] encryptedTelegramData = new byte[encyptPayloadLength];
Array.Copy(payload, (int)appCodeIndex + 8, encryptedTelegramData, 0, encyptPayloadLength);
UInt16 rawActualCRC = encryptedTelegramData.Read<UInt16>((uint)(encryptedTelegramData.Length - 2) * 8, 16, ByteOrder.BigEndian);
UInt16 actualCRC = 0x0000;
UInt16 expectedCRC = 0xffff;
byte[] plaintext = new byte[0];
byte[] key = SensusRfDecryptKey();
if (null != key)
{
plaintext = Sensus.Protocols.SensusRF.TelegramFrame.Decrypt(radioAddress, counter, encryptedTelegramData, key);
actualCRC = plaintext.Read<UInt16>((uint)(plaintext.Length - 2) * 8, 16, ByteOrder.BigEndian);
expectedCRC = CRC16.SIRT.Calculate(
(
length == 0x0d
? CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
: CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 16) & 0xFF), (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
),
plaintext,
0,
plaintext.Length - 2
);
// CRCs will match if decryption was successful
if (actualCRC == expectedCRC)
{
byte pamCode = plaintext[0];
if (pamCode == 144)
{
int pamLen = plaintext[1];
byte[] pamData = new byte[pamLen];
Array.Copy(plaintext, (int)2, pamData, 0, pamLen);
description = "PAM-FN , " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + pamData.ToHexString();
}
else
{
description = "PAM, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + plaintext.ToHexString();
}
}
else
{
description = "PAM, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", Decryption Failed" + ", " + encryptedTelegramData.ToHexString();
}
}
else // Assume unencrypted - Data could be garbage
{
byte pamCode = encryptedTelegramData[0];
if (pamCode == 144)
{
int pamLen = encryptedTelegramData[1];
byte[] pamData = new byte[pamLen];
Array.Copy(encryptedTelegramData, (int)2, pamData, 0, pamLen);
description = "PAM-FN (unencrypted), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + pamData.ToHexString();
}
else
{
description = "PAM (unencrypted), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + encryptedTelegramData.ToHexString();
}
}
}
else if (telegramType == Sensus.Protocols.SensusRF.TelegramType.SEMI)
{
// Header
// byte Length (includes header and payload CRC)
// byte AppCode - 32 (PAM) - appCodeIndex
// byte Counter - appCodeIndex + 1
// UInt32 Address - appCodeIndex + 2, 3, 4, 5
// UInt16 HeaderCrc - appCodeIndex + 6, 7
// byte PamCode - 144 (0x90)
// byte PamLen
// byte FlexNetFrame[SENSUS_RF_PAM_ENCAP_FLEXNET_FRAME_LENGTH] (46)
// Decrypt Volume through CRC. Only method I found in Sensus.dll was a static function
// in TelegramFrame class. TelegramFrame is a serial packet from/to SIRT. The decrypt
// function appears to work well.
int encyptPayloadLength = length - 7 /* header */ - 2 /* header CRC */ - 2 /*payload CRC */;
byte[] encryptedTelegramData = new byte[encyptPayloadLength];
Array.Copy(payload, (int)appCodeIndex + 8, encryptedTelegramData, 0, encyptPayloadLength);
UInt16 rawActualCRC = encryptedTelegramData.Read<UInt16>((uint)(encryptedTelegramData.Length - 2) * 8, 16, ByteOrder.BigEndian);
UInt16 actualCRC = 0x0000;
UInt16 expectedCRC = 0xffff;
byte[] plaintext = new byte[0];
byte[] key = SensusRfDecryptKey();
if (null != key)
{
plaintext = Sensus.Protocols.SensusRF.TelegramFrame.Decrypt(radioAddress, counter, encryptedTelegramData, key);
actualCRC = plaintext.Read<UInt16>((uint)(plaintext.Length - 2) * 8, 16, ByteOrder.BigEndian);
expectedCRC = CRC16.SIRT.Calculate(
(
length == 0x0d
? CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
: CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 16) & 0xFF), (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
),
plaintext,
0,
plaintext.Length - 2
);
// CRCs will match if decryption was successful
if (actualCRC == expectedCRC)
{
description = "SEMI, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter;
UInt32 read = plaintext.Read<UInt32>(0 * 8, 32, ByteOrder.BigEndian);
byte alarms = plaintext.Read<byte>(4 * 8, 8, ByteOrder.BigEndian);
byte pamStatus = plaintext.Read<byte>(5 * 8, 8, ByteOrder.BigEndian);
byte pamRssi = plaintext.Read<byte>(6 * 8, 8, ByteOrder.BigEndian);
byte meterType = plaintext.Read<byte>(7 * 8, 8, ByteOrder.BigEndian);
description += String.Format(", MT=0x{0:X2}, Status=0x{1:X2}, RSSI=0x{2:X2}, Read=0x{3:X8}, Alarms=0x{4:X2}", meterType, pamStatus, pamRssi, read, alarms);
description += ", " + plaintext.ToHexString();
if (meterType == IPerlS4.MeterType)
{
SemiReceived(radioAddress, new IPerlS4Semi(plaintext));
}
}
else
{
description = "SEMI, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", Decryption Failed, " + encryptedTelegramData.ToHexString();
}
}
else // Assume unencrypted - Data could be garbage
{
description = "SEMI (raw), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter;
UInt32 read = encryptedTelegramData.Read<UInt32>(0 * 8, 32, ByteOrder.BigEndian);
byte alarms = encryptedTelegramData.Read<byte>(4 * 8, 8, ByteOrder.BigEndian);
byte pamStatus = encryptedTelegramData.Read<byte>(5 * 8, 8, ByteOrder.BigEndian);
byte pamRssi = encryptedTelegramData.Read<byte>(6 * 8, 8, ByteOrder.BigEndian);
byte meterType = encryptedTelegramData.Read<byte>(7 * 8, 8, ByteOrder.BigEndian);
description += String.Format(", MT=0x{0:X2}, Status=0x{1:X2}, RSSI=0x{2:X2}, Read=0x{3:X8}, Alarms=0x{4:X2}", meterType, pamStatus, pamRssi, read, alarms);
description += ", " + encryptedTelegramData.ToHexString();
if (meterType == IPerlS4.MeterType)
{
SemiReceived(radioAddress, new IPerlS4Semi(encryptedTelegramData));
}
}
}
else if (telegramType == Sensus.Protocols.SensusRF.TelegramType.Debug)
{
int encyptPayloadLength = length - 7 /* header */ - 2 /* header CRC */ - 2 /*payload CRC */;
byte[] encryptedTelegramData = new byte[encyptPayloadLength];
Array.Copy(payload, (int)appCodeIndex + 8, encryptedTelegramData, 0, encyptPayloadLength);
byte[] key = SensusRfDecryptKey();
if (null != key)
{
byte[] plaintext = Sensus.Protocols.SensusRF.TelegramFrame.Decrypt(radioAddress, counter, encryptedTelegramData, key);
UInt16 actualCRC = plaintext.Read<UInt16>((uint)(plaintext.Length - 2) * 8, 16, ByteOrder.BigEndian);
UInt16 expectedCRC = CRC16.SIRT.Calculate(
(
length == 0x0d
? CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
: CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 16) & 0xFF), (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
),
plaintext,
0,
plaintext.Length - 2
);
// CRCs will match if decryption was successful
if (actualCRC == expectedCRC)
{
description = "Debug, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + plaintext.ToHexString();
}
else
{
description = "Debug, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", Decryption Failed, " + encryptedTelegramData.ToHexString();
}
}
else // Assume unencrypted - Data could be garbage
{
description = "Debug (raw), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + encryptedTelegramData.ToHexString();
}
}
else if (telegramType == Sensus.Protocols.SensusRF.TelegramType.LOG)
{
int encyptPayloadLength = length - 7 /* header */ - 2 /* header CRC */ - 2 /*payload CRC */;
byte[] encryptedTelegramData = new byte[encyptPayloadLength];
Array.Copy(payload, (int)appCodeIndex + 8, encryptedTelegramData, 0, encyptPayloadLength);
byte[] key = SensusRfDecryptKey();
if (null != key)
{
byte[] plaintext = Sensus.Protocols.SensusRF.TelegramFrame.Decrypt(radioAddress, counter, encryptedTelegramData, key);
UInt16 actualCRC = plaintext.Read<UInt16>((uint)(plaintext.Length - 2) * 8, 16, ByteOrder.BigEndian);
UInt16 expectedCRC = CRC16.SIRT.Calculate(
(
length == 0x0d
? CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
: CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 16) & 0xFF), (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
),
plaintext,
0,
plaintext.Length - 2
);
// CRCs will match if decryption was successful
if (actualCRC == expectedCRC)
{
Sensus.Protocols.SensusRF.LOGTelegram logTelegram = Sensus.Protocols.SensusRF.LOGTelegram.Parse(plaintext, 0, (uint)plaintext.Length);
description = "LOG, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + plaintext.ToHexString();
description += logTelegram.ToString();
LogReceived(radioAddress, logTelegram);
}
else
{
description = "LOG, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", Decryption Failed, " + encryptedTelegramData.ToHexString();
}
}
else // Assume unencrypted - Data could be garbage
{
Sensus.Protocols.SensusRF.LOGTelegram logTelegram = Sensus.Protocols.SensusRF.LOGTelegram.Parse(encryptedTelegramData, 0, (uint)encryptedTelegramData.Length);
description = "LOG (raw), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + encryptedTelegramData.ToHexString();
description += logTelegram.ToString();
LogReceived(radioAddress, logTelegram);
}
}
else if (telegramType == Sensus.Protocols.SensusRF.TelegramType.FlexNet)
{
// byte DataType; ///< 0x00 for BUP, 0x01 for message
// union
// {
// struct
// {
// UInt16 TimeSync; ///<
// byte FnCount;
// byte FlexNetFrame[43]; ///< Classic frame including 2 byte sync and CRC
// } Bup;
// struct
// {
// byte PamStatus; ///<
// byte Rssi;
// byte FlexNetFrame[43]; ///< Classic frame including 2 byte sync and CRC
// } Message;
// }
int encyptPayloadLength = length - 7 /* header */ - 2 /* header CRC */ - 2 /*payload CRC */;
byte[] encryptedTelegramData = new byte[encyptPayloadLength];
Array.Copy(payload, (int)appCodeIndex + 8, encryptedTelegramData, 0, encyptPayloadLength);
UInt16 rawActualCRC = encryptedTelegramData.Read<UInt16>((uint)(encryptedTelegramData.Length - 2) * 8, 16, ByteOrder.BigEndian);
UInt16 actualCRC = 0x0000;
UInt16 expectedCRC = 0xffff;
byte[] plaintext = new byte[0];
byte[] key = SensusRfDecryptKey();
if (null != key)
{
plaintext = Sensus.Protocols.SensusRF.TelegramFrame.Decrypt(radioAddress, counter, encryptedTelegramData, key);
actualCRC = plaintext.Read<UInt16>((uint)(plaintext.Length - 2) * 8, 16, ByteOrder.BigEndian);
expectedCRC = CRC16.SIRT.Calculate(
(
length == 0x0d
? CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
: CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 16) & 0xFF), (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
),
plaintext,
0,
plaintext.Length - 2
);
// CRCs will match if decryption was successful
if (actualCRC == expectedCRC)
{
byte dataType = plaintext[0];
if (dataType == 0)
{
// BUP
UInt16 timeSync = plaintext.Read<UInt16>((1 * 8), 16, ByteOrder.BigEndian);
byte fnCount = plaintext[3];
int plaintextLen = plaintext.Length - 4;
byte[] flexNetFrame = new byte[plaintextLen];
Array.Copy(plaintext, 4, flexNetFrame, 0, plaintextLen);
description = "FN-BUP , " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + timeSync + ", " + fnCount + ", " + flexNetFrame.ToHexString();
}
else
{
// Message
byte pamStatus = plaintext[1];
byte rssi = plaintext[2];
byte[] flexNetFrame = new byte[43];
Array.Copy(plaintext, 3, flexNetFrame, 0, 43);
description = "FN-Msg, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + pamStatus + ", " + rssi + ", " + flexNetFrame.ToHexString();
NA2WMessageFrame fnMsgFrame = NA2WMessageFrame.Parse(flexNetFrame, 0);
FlexNetReceived(radioAddress, fnMsgFrame);
}
}
else
{
description = "FN, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", Decryption Failed";
}
}
// CRCs will match if decryption was successful
if (actualCRC == expectedCRC)
{
byte dataType = plaintext[0];
if (dataType == 0)
{
// BUP
UInt16 timeSync = plaintext.Read<UInt16>((1 * 8), 16, ByteOrder.BigEndian);
byte fnCount = plaintext[3];
int plaintextLen = plaintext.Length - 4;
byte[] flexNetFrame = new byte[plaintextLen];
Array.Copy(plaintext, 4, flexNetFrame, 0, plaintextLen);
description = "FN-BUP , " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + timeSync + ", " + fnCount + ", " + flexNetFrame.ToHexString();
}
else
{
// Message
byte pamStatus = plaintext[1];
byte rssi = plaintext[2];
byte[] flexNetFrame = new byte[43];
Array.Copy(plaintext, 3, flexNetFrame, 0, 43);
description = "FN-Msg, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + pamStatus + ", " + rssi + ", " + flexNetFrame.ToHexString();
NA2WMessageFrame fnMsgFrame = NA2WMessageFrame.Parse(flexNetFrame, 0);
FlexNetReceived(radioAddress, fnMsgFrame);
}
}
else // Assume unencrypted - Data could be garbage
{
byte dataType = encryptedTelegramData[0];
if (dataType == 0)
{
// BUP
UInt16 timeSync = encryptedTelegramData.Read<UInt16>((1 * 8), 16, ByteOrder.BigEndian);
byte fnCount = encryptedTelegramData[3];
int plaintextLen = encryptedTelegramData.Length - 4;
byte[] flexNetFrame = new byte[plaintextLen];
Array.Copy(encryptedTelegramData, 4, flexNetFrame, 0, plaintextLen);
description = "FN-BUP (unencrypted) , " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + timeSync + ", " + fnCount + ", " + flexNetFrame.ToHexString();
}
else
{
// Message
byte pamStatus = encryptedTelegramData[1];
byte rssi = encryptedTelegramData[2];
byte[] flexNetFrame = new byte[43];
Array.Copy(encryptedTelegramData, 3, flexNetFrame, 0, 43);
description = "FN-Msg (unencrypted), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + pamStatus + ", " + rssi + ", " + flexNetFrame.ToHexString();
NA2WMessageFrame fnMsgFrame = NA2WMessageFrame.Parse(flexNetFrame, 0);
FlexNetReceived(radioAddress, fnMsgFrame);
}
}
}
else
{
description = telegramType.ToString() + ", " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter;
}
}
else if (serialRadioFrameMessage.RadioFrameType == RadioFrameType.WMBUS)
{
// typedef struct
// {
// uint8_t L; ///< Length field, does not include CRC bytes... If ((L-9) % 16) != 0 then the last block will contain ((L-9) % 16) bytes of data
// WMBus_ControlField_t C; ///< Control field
// WMBus_ManufacturerId_t M; ///< Manufacturer Id field
// union
// {
// struct
// {
// uint32_t MeterId; ///< Serial number of the meter
// uint8_t Version; ///< Meter version number
// uint8_t DeviceType; ///< Meter device type
// };
// uint8_t A[6]; ///< Address field
// };
// } WMBus_TBlock1_t;
uint block1Offset = 3;
String packetTypeStr = "T2";
if (syncWord == (SyncWord)0x543D)
{
block1Offset = 2;
packetTypeStr = "T1";
}
UInt32 meterId = 0;
UInt32 meterIdRaw = payload.Read<UInt32>((4 + block1Offset) * 8, 32);
for (int i = 3; i >= 0; i--)
{
meterId *= 100;
meterId += 10 * ((uint)(payload[block1Offset + 4 + i]) >> 4) + ((uint)(payload[block1Offset + 4 + i]) & 0x0f);
}
UInt16 manufacturerIdRaw = payload.Read<UInt16>((block1Offset + 2) * 8, 16);
byte[] manufacturerIdAscii = new byte[3];
manufacturerIdAscii[0] = (byte)(((manufacturerIdRaw >> 10) & 0x001F) + 64);
manufacturerIdAscii[1] = (byte)(((manufacturerIdRaw >> 5) & 0x001F) + 64);
manufacturerIdAscii[2] = (byte)(((manufacturerIdRaw) & 0x001F) + 64);
byte version = payload[block1Offset + 8];
Utility.WMBusDeviceType deviceType = (Utility.WMBusDeviceType)(payload[block1Offset + 9]);
description = "WMBUS, " + packetTypeStr + ", " + String.Format("{0:D8}, (0x{1:X8}), ", meterId, meterIdRaw);
description += deviceType.ToString() + " - " + manufacturerIdAscii.ToASCIIString() + String.Format(" - 0x{0:X2}", version);
channelizedFlexNetId.ID = meterId;
}
}
else
{
description = serialRadioFrameMessage.Payload.ToBytes().ToHexString();
}
}
double temp;
temp = double.NaN;
string signal = String.Format("{0:0.0}", temp);
temp = double.NaN;
string noise = String.Format("{0:0.0}", temp);
bool postReception = true;
if (windowViewModel.RadioReceiveFilterEnabled)
{
ChannelizedFlexNetId filterChannelizedFlexNetId;
if (ChannelizedFlexNetId.TryParseFlexNetID(windowViewModel.RadioReceiveFilterFnid, out filterChannelizedFlexNetId))
{
postReception = ((uint)(channelizedFlexNetId.ID) == (uint)(filterChannelizedFlexNetId.ID));
}
}
if (postReception)
{
ReceivedMessage receivedMessage = new ReceivedMessage()
{
TimeStamp = timeStamp,
Description = description,
Signal = signal,
Noise = noise
};
windowViewModel.Add(receivedMessage);
}
}
else if (message.Payload is SerialEventNotification)
{
SerialEventNotification serialEventNotification = (SerialEventNotification)message.Payload;
EventNotification eventNotification = new EventNotification();
Frame notification = (Frame)(serialEventNotification.Payload);
byte[] notificationBytes = notification.ToBytes();
SByte idNum = notificationBytes.Read<SByte>((0 * 8) + 0, 8);
UInt64 timeStamp = notificationBytes.Read<UInt64>((1 * 8) + 0, 64);
UInt16 numDataBytes = notificationBytes.Read<UInt16>((9 * 8) + 0, 16);
UInt16 fileIdNum = notificationBytes.Read<UInt16>((11 * 8) + 0, 16);
UInt16 lineNum = notificationBytes.Read<UInt16>((13 * 8) + 0, 16);
UInt16 eventDataLength = (UInt16)((numDataBytes <= notificationBytes.Length - 15) ? numDataBytes : (notificationBytes.Length - 15));
byte[] eventData = new byte[eventDataLength];
Array.Copy(notificationBytes, 15, eventData, 0, eventDataLength);
eventNotification.TimeStamp = DateTime.Now.ToLongTimeString(); // String.Format("{0}", timeStamp);
eventNotification.Data = eventData.ToHexString();
GlobalIPerlEvent iPerlEvent = new GlobalIPerlEvent(idNum, eventData, fileIdNum, lineNum);
eventNotification.Id = iPerlEvent.Name;
eventNotification.File = iPerlEvent.File;
eventNotification.Line = fileIdNum.ToString();
eventNotification.Description = iPerlEvent.Description;
windowViewModel.Add(eventNotification);
}
else if (message.Payload is FactoryTestCommandComplete)
{
FactoryTestCommandComplete ftcComplete = (FactoryTestCommandComplete)message.Payload;
if (ftcComplete.TestCommand == 0x06)
{
// Sample RF Signal - additional data is 2 byte signal value in 10th dBm
byte[] data = ftcComplete.AdditionalData;
if (data.Length > 1)
{
Int16 signalLevel = data.Read<Int16>(0, 16);
double temp;
temp = ((double)(signalLevel) / 10);
string raw = String.Format("{0:0.0}", temp);
signalLevel = data.Read<Int16>(16, 16);
temp = ((double)(signalLevel) / 10);
string signalCw = String.Format("{0:0.0}", temp);
signalLevel = data.Read<Int16>(32, 16);
temp = ((double)(signalLevel) / 10);
string signalMod = String.Format("{0:0.0}", temp);
string timeStamp = DateTime.Now.ToLongTimeString();
ReceivedMessage receivedMessage = new ReceivedMessage()
{
TimeStamp = timeStamp,
Description = "RSSI" + " (" + raw + ", " + signalCw + ")",
Signal = signalMod,
Noise = ""
};
windowViewModel.Add(receivedMessage);
}
}
else if (ftcComplete.TestCommand == 0x07)
{
UInt32 testCount = (UInt32)(
ftcComplete.AdditionalData[0] << 0
| ftcComplete.AdditionalData[1] << 8
| ftcComplete.AdditionalData[2] << 16
| ftcComplete.AdditionalData[3] << 24
);
Utility.Log.Write($"Frequency Count Test Result: {testCount:N0} Hz\n");
windowViewModel.Test32kHzResult = testCount.ToString("N0") + " Hz";
}
}
else if (message.Payload is CommandErrorResponse)
{
CommandErrorResponse commandErrorResponse = (CommandErrorResponse)message.Payload;
LogError("Error Code: " + String.Format("{0:X2}", commandErrorResponse.ErrorCode));
}
else if (message.Payload is MemoryDataResponse)
{
MemoryDataResponse memoryDataResponse = (MemoryDataResponse)message.Payload;
byte[] data = memoryDataResponse.Data;
int numberOfBytes = data.Length;
String dataString = "";
uint address = memoryDataResponse.Address;
uint index = 0;
while (numberOfBytes > 16)
{
byte[] lineData = data.Read<byte[]>(index * 8, 16 * 8);
dataString += (memoryDataResponse.Source == 0 ? "P" : "F") + String.Format(" 0x{0:X8}: ", address) + lineData.ToHexString() + System.Environment.NewLine;
index += 16;
address += 16;
numberOfBytes -= 16;
}
if (numberOfBytes > 0)
{
byte[] lineData = data.Read<byte[]>(index * 8, (uint)(8 * numberOfBytes));
dataString += (memoryDataResponse.Source == 0 ? "P" : "F") + String.Format(" 0x{0:X8}: ", address) + lineData.ToHexString() + System.Environment.NewLine;
}
windowViewModel.MemoryReadData += dataString;
}
}
private byte[] SensusRfKey()
{
return windowViewModel.KeyManager.GetKey(windowViewModel.SRfKeySelectedItem);
//if (windowViewModel.SRfKeySelectedItem == "Anglian")
//{
// return AnglianKey.Value;
//}
//else
//{
// return ThamesKey.Value;
//}
}
private byte[] SensusRfDecryptKey()
{
return SensusRfKey();
}
public void BupReceived(UInt32 address, IFrame frame)
{
FrameEventArgs<IFrame> e = new FrameEventArgs<IFrame>(FrameEvent.ActivityBup, address, frame);
receiveQueue.Enqueue(e);
}
public void SemiReceived(UInt32 address, IFrame frame)
{
FrameEventArgs<IFrame> e = new FrameEventArgs<IFrame>(FrameEvent.Semi, address, frame);
receiveQueue.Enqueue(e);
}
public void LogReceived(UInt32 address, IFrame frame)
{
FrameEventArgs<IFrame> e = new FrameEventArgs<IFrame>(FrameEvent.Log, address, frame);
receiveQueue.Enqueue(e);
}
public void FlexNetReceived(UInt32 address, IFrame frame)
{
FrameEventArgs<IFrame> e = new FrameEventArgs<IFrame>(FrameEvent.FlexNetFrame, address, frame);
receiveQueue.Enqueue(e);
}
public void MessageReceived(FrameEventArgs<IFrame> e)
{
receiveQueue.Enqueue(e);
}
public event EventHandler<FrameEventArgs<IFrame>> FrameReceived;
private void FrameEventLoop()
{
while (true)
{
var newMessage = receiveQueue.Dequeue().Cast<IFrame>();
if (newMessage.FrameEvent == FrameEvent.Log)
{
DumpLog(newMessage.Address, newMessage.Frame);
}
try
{
FrameReceived.Raise(this, newMessage);
}
catch (Exception ex)
{
Utility.Log.Write("Exception trying to notify of received frame: " + ex.ToString() + Environment.NewLine);
}
}
}
private Thread eventThread;
private BlockingQueue<FrameEventArgs<IFrame>> receiveQueue;
#if false
private string PomCollectionItemToName(Collection<PomComboBoxItem> collection, string value)
{
string name = "Unknown: " + value;
PomComboBoxItem item = collection.Where(i => i.Value == value).FirstOrDefault();
if (null != item)
{
name = item.Name;
}
return name;
}
private string PomCollectionItemToName(Collection<PomComboBoxItem> collection, byte value)
{
string valueString = String.Format("{0}", value);
return PomCollectionItemToName(collection, valueString);
}
#endif
private void DumpLog(UInt32 address, IFrame logFrame)
{
Utility.Log.Write(logFrame.ToString() + System.Environment.NewLine);
}
public ClassicSerialMessageFrame SendFlexNetSerial(ISerialCommand cmd, bool responseExpected, UInt32 timeoutMs)
{
ClassicSerialCommandFrame cmdFrame = new ClassicSerialCommandFrame(0x00, cmd);
cmdFrame.Bake();
LogOutgoing(cmdFrame);
return serialManager.SendFlexNetSerial(cmdFrame, responseExpected, timeoutMs);
}
public ClassicSerialMessageFrame SendFlexNetSerial(ISerialCommand cmd, bool responseExpected)
{
return SendFlexNetSerial(cmd, responseExpected, 3000);
}
public NA2WSerialFrame SendNa2wSerial(ISerialCommand cmd, bool responseExpected, UInt32 timeoutMs)
{
NA2WSerialFrame cmdFrame = new NA2WSerialFrame(cmd);
cmdFrame.Bake();
LogOutgoing(cmdFrame);
return serialManager.SendNa2wSerial(cmdFrame, responseExpected, timeoutMs);
}
public NA2WSerialFrame SendNa2wSerial(ISerialCommand cmd, bool responseExpected)
{
NA2WSerialFrame cmdFrame = new NA2WSerialFrame(cmd);
cmdFrame.Bake();
LogOutgoing(cmdFrame);
return serialManager.SendNa2wSerial(cmdFrame, responseExpected);
}
public NA2WSerialFrame SendNa2wSerial(IFrame frame, bool responseExpected)
{
NA2WSerialFrame cmdFrame = new NA2WSerialFrame(frame);
// set the radio frame type if this is a FNV2 radio frame
if ( (frame is Frame)
&& (0xAC == (frame as Frame)[0])
&& (0xC5 == (frame as Frame)[1])
&& (cmdFrame.Payload is NetworkMessage)
&& ((cmdFrame.Payload as NetworkMessage).Payload is SerialRadioFrameMessage)
)
{
((cmdFrame.Payload as NetworkMessage).Payload as SerialRadioFrameMessage).RadioFrameType = RadioFrameType.FlexNetV2;
}
cmdFrame.Bake();
LogOutgoing(cmdFrame);
return serialManager.SendNa2wSerial(cmdFrame, responseExpected);
}
public NA2WSerialFrame SendNa2wSerial(ISerialCommand cmd, byte responseCommandCode)
{
NA2WSerialFrame cmdFrame = new NA2WSerialFrame(cmd);
cmdFrame.Bake();
LogOutgoing(cmdFrame);
return serialManager.SendNa2wSerial(cmdFrame, responseCommandCode);
}
public void SendNa2wSerial(ISerialMessage msg)
{
NA2WSerialFrame msgFrame = new NA2WSerialFrame(msg);
msgFrame.Bake();
LogOutgoing(msgFrame);
serialManager.SendNa2wSerial(msgFrame, false);
}
/// <summary>
/// The format string used for time stamps. Default is"yyyy-MM-dd HH:mm:ss.fffzz" which is
/// the Sensus standard logging date format.
/// </summary>
public static string TimeFormatString = "yyyy-MM-dd HH:mm:ss.fffzz";
void LogIncoming(ISerialMessageFrame message)
{
if (windowViewModel.LogWithDescription)
{
String messageType = message.Payload.GetType().ToString();
String messageName = messageType.Substring(messageType.LastIndexOf('.') + 1);
Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " < " + messageName + "\n");
}
if (windowViewModel.LogWithHexString) Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " < " + message.ToHexString() + "\n");
if (windowViewModel.LogWithDetails) Utility.Log.Write(message.ToString() + "\n");
}
void LogOutgoing(ClassicSerialCommandFrame command)
{
if (windowViewModel.LogClearOnCommand) Log.Clear();
if (windowViewModel.LogWithDescription)
{
String commandType = command.Payload.GetType().ToString();
String commandName = commandType.Substring(commandType.LastIndexOf('.') + 1);
Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " > " + commandName + "\n");
}
if (windowViewModel.LogWithHexString) Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " > " + command.ToHexString() + "\n");
if (windowViewModel.LogWithDetails) Utility.Log.Write(command.ToString() + "\n");
}
void LogOutgoing(NA2WSerialFrame command)
{
if (windowViewModel.LogClearOnCommand) Log.Clear();
if (windowViewModel.LogWithDescription)
{
if (command.Payload is NetworkCommand)
{
NetworkCommand networkCommand = (NetworkCommand)command.Payload;
String commandType = networkCommand.Payload.GetType().ToString();
String commandName = commandType.Substring(commandType.LastIndexOf('.') + 1);
Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " > " + commandName + "\n");
}
else if (command.Payload is NetworkMessage)
{
NetworkMessage networkMessage = (NetworkMessage)command.Payload;
String commandType = networkMessage.Payload.GetType().ToString();
String commandName = commandType.Substring(commandType.LastIndexOf('.') + 1);
Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " > " + commandName + "\n");
}
}
if (windowViewModel.LogWithHexString) Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " > " + command.ToHexString() + "\n");
if (windowViewModel.LogWithDetails) Utility.Log.Write(command.ToString() + "\n");
}
void LogError(String error)
{
if (windowViewModel.LogWithDescription)
{
Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " - " + error + "\n");
}
}
private void SetComPortList(String[] list)
{
ObservableCollection<String> comPortObservableCollection = new ObservableCollection<String>();
foreach (String s in list)
{
comPortObservableCollection.Add(s);
}
// Set collection
windowViewModel.ComPortObservableCollection = comPortObservableCollection;
// Default to first item in collection
if (list.Length > 0)
{
windowViewModel.ComPortSelectedItem = list[0];
}
}
/// <summary>
/// Static member function that returns a sorted string array of all the
/// COM port names found in the system.
/// </summary>
/// <returns>{"COM1","COM7",...,"COM40",...,COMn}</returns>
private string[] GetPortNames()
{
string[] ports = Sensus.COMUtils.GetPortNames().ToArray();
Array.Sort(ports, new ComCompare());
return ports;
}
public void SaveDefaultConfigurationValues()
{
GlobalIPerlUtility.Properties.Settings.Default.Configuration_DeviceId = windowViewModel.DeviceIdNew;
GlobalIPerlUtility.Properties.Settings.Default.Configuration_SerialNumber = windowViewModel.SerialNumberNew;
GlobalIPerlUtility.Properties.Settings.Default.Configuration_ManufacturingNote = windowViewModel.ManufacturingNoteNew;
GlobalIPerlUtility.Properties.Settings.Default.Configuration_TemperatureCalOffset = windowViewModel.TemperatureCalOffsetNew;
GlobalIPerlUtility.Properties.Settings.Default.Configuration_VbatCalOffset = windowViewModel.VbatCalOffsetNew;
GlobalIPerlUtility.Properties.Settings.Default.Configuration_VbatCalSlope = windowViewModel.VbatCalSlopeNew;
GlobalIPerlUtility.Properties.Settings.Default.Configuration_VsysCalOffset = windowViewModel.VsysCalOffsetNew;
GlobalIPerlUtility.Properties.Settings.Default.Configuration_VsysCalSlope = windowViewModel.VsysCalSlopeNew;
GlobalIPerlUtility.Properties.Settings.Default.Configuration_TcxoCorrection = windowViewModel.TcxoCorrectionNew;
GlobalIPerlUtility.Properties.Settings.Default.Configuration_PaOffPowerLevel = windowViewModel.RfPowerLevelNew;
GlobalIPerlUtility.Properties.Settings.Default.Configuration_ButtonPressAction = windowViewModel.ButtonPressAction;
}
public void LoadDefaultConfigurationValues()
{
windowViewModel.DeviceIdNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_DeviceId;
windowViewModel.SerialNumberNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_SerialNumber;
windowViewModel.ManufacturingNoteNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_ManufacturingNote;
windowViewModel.TemperatureCalOffsetNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_TemperatureCalOffset;
windowViewModel.VbatCalOffsetNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_VbatCalOffset;
windowViewModel.VbatCalSlopeNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_VbatCalSlope;
windowViewModel.VsysCalOffsetNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_VsysCalOffset;
windowViewModel.VsysCalSlopeNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_VsysCalSlope;
windowViewModel.TcxoCorrectionNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_TcxoCorrection;
windowViewModel.RfPowerLevelNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_PaOffPowerLevel;
windowViewModel.ButtonPressAction = GlobalIPerlUtility.Properties.Settings.Default.Configuration_ButtonPressAction;
}
public void SaveDefaultCommandValues()
{
GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngFrequency = windowViewModel.TxEng_Frequency;
GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngDuration = windowViewModel.TxEng_Duration;
GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngTransceiverPower = windowViewModel.TxEng_TransceiverPower;
GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngModulation = windowViewModel.TxEng_Modulation;
GlobalIPerlUtility.Properties.Settings.Default.Command_TxFrequency = windowViewModel.Tx_Frequency;
GlobalIPerlUtility.Properties.Settings.Default.Command_TxDuration = windowViewModel.Tx_Duration;
GlobalIPerlUtility.Properties.Settings.Default.Command_TxModulation = windowViewModel.Tx_Modulation;
GlobalIPerlUtility.Properties.Settings.Default.Command_RxFrequency = windowViewModel.Rx_Frequency;
GlobalIPerlUtility.Properties.Settings.Default.Command_RxModulation = windowViewModel.Rx_Modulation;
GlobalIPerlUtility.Properties.Settings.Default.Command_RxSensitivity = windowViewModel.Rx_Sensitivity;
}
public void LoadDefaultCommandValues()
{
windowViewModel.TxEng_Frequency = GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngFrequency;
windowViewModel.TxEng_Duration = GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngDuration;
windowViewModel.TxEng_TransceiverPower = GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngTransceiverPower;
windowViewModel.TxEng_Modulation = GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngModulation;
windowViewModel.Tx_Frequency = GlobalIPerlUtility.Properties.Settings.Default.Command_TxFrequency;
windowViewModel.Tx_Duration = GlobalIPerlUtility.Properties.Settings.Default.Command_TxDuration;
windowViewModel.Tx_Modulation = GlobalIPerlUtility.Properties.Settings.Default.Command_TxModulation;
windowViewModel.Rx_Frequency = GlobalIPerlUtility.Properties.Settings.Default.Command_RxFrequency;
windowViewModel.Rx_Modulation = GlobalIPerlUtility.Properties.Settings.Default.Command_RxModulation;
windowViewModel.Rx_Sensitivity = GlobalIPerlUtility.Properties.Settings.Default.Command_RxSensitivity;
}
public void FwdlTaskProgressCallback(Object task, Double percentDone, String statusString)
{
windowViewModel.UpgradePercent = percentDone;
if (statusString != null)
{
windowViewModel.UpgradeStatus = statusString;
}
}
public void FwdlTaskCompletionCallback(Object task, bool successfullyCompleted)
{
windowViewModel.UpgradeActive = false;
_serialFirmwareDownloadTask = null;
}
private SerialFirmwareDownloadTask _serialFirmwareDownloadTask = null;
public void FwdlCommand(string type)
{
if (type.Equals("Start"))
{
_serialFirmwareDownloadTask = new SerialFirmwareDownloadTask(windowViewModel.UpgradeFileName, this, (ushort)(serialManager is MeterTestHatLink ? 8 : 10));
_serialFirmwareDownloadTask.TaskProgressCallback = FwdlTaskProgressCallback;
windowViewModel.UpgradeActive = true;
_serialFirmwareDownloadTask.Start(FwdlTaskCompletionCallback);
}
else if (type.Equals("Stop"))
{
if (_serialFirmwareDownloadTask != null)
{
_serialFirmwareDownloadTask.Stop();
}
}
}
public void EventLogTaskProgressCallback(Object task, Double percentDone, String statusString)
{
if (statusString != null)
{
windowViewModel.EventLogStatus = statusString;
}
}
public void EventLogTaskCompletionCallback(Object task, bool successfullyCompleted)
{
windowViewModel.EventLogActive = false;
_eventLogTask = null;
}
public void EventLogTaskLogCallback(Object task, EventNotification eventNotification)
{
windowViewModel.AddToEventLog(eventNotification);
}
private EventLogTask _eventLogTask = null;
public void EventLogCommand(string type)
{
if (type.Equals("Start"))
{
String timeFrameString = windowViewModel.EventLogTimeFrameSelectedValue;
UInt32 timeFrameSec = 0xffffffff;
if (!string.IsNullOrEmpty(timeFrameString))
{
if (timeFrameString.Equals("Last Hour"))
{
timeFrameSec = 60 * 60;
}
else if (timeFrameString.Equals("Last Day"))
{
timeFrameSec = 60 * 60 * 24;
}
else if (timeFrameString.Equals("Last Week"))
{
timeFrameSec = 60 * 60 * 24 * 7;
}
else if (timeFrameString.Equals("Last 30 Days"))
{
timeFrameSec = 60 * 60 * 24 * 7 * 30;
}
}
windowViewModel.EventLogActive = true;
windowViewModel.ClearEventLog();
_eventLogTask = new EventLogTask(this);
_eventLogTask.TaskProgressCallback = EventLogTaskProgressCallback;
_eventLogTask.TaskLogCallback = EventLogTaskLogCallback;
_eventLogTask.TimeFrame = timeFrameSec;
_eventLogTask.Start(EventLogTaskCompletionCallback);
}
else if (type.Equals("Stop"))
{
if (_eventLogTask != null)
{
_eventLogTask.Stop();
}
}
else if (type.Equals("Export"))
{
String fileName = EventLogToCsv(null);
if (fileName != null)
{
windowViewModel.EventLogStatus = "Exported to " + fileName;
}
else
{
windowViewModel.EventLogStatus = "Error trying to export";
}
}
}
public string EventLogToCsv(string folder)
{
string separator = ",";
StringBuilder builder = new StringBuilder(Convert.ToString((char)65279));
ObservableCollection<EventNotification> eventNotificationCollection = windowViewModel.EventLogCollection;
// Build header
List<string> tempList = new List<string>();
tempList.Add("Event");
tempList.Add("Time Stamp");
tempList.Add("Description");
tempList.Add("Raw Data");
builder.Append(string.Join(separator, tempList)).Append(Environment.NewLine);
// Populate data
for (int i = 0; i < eventNotificationCollection.Count; i++)
{
tempList = new List<string>();
tempList.Add("\"" + eventNotificationCollection[i].Id + "\"");
tempList.Add(eventNotificationCollection[i].TimeStamp);
tempList.Add("\"" + eventNotificationCollection[i].Description + "\"");
tempList.Add(eventNotificationCollection[i].Data);
builder.Append(string.Join(separator, tempList)).Append(Environment.NewLine);
}
builder.ToString();
// Save to CSV
try
{
string destination = "cl" + windowViewModel.SerialNumber + "_" + DateTime.Now.ToString("dd_MM_yyyy_HH_mm") + "_event_log";
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
destination = destination.Replace(c, '_');
}
if (string.IsNullOrEmpty(folder))
{
folder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
}
destination = folder + "\\" + destination + ".csv";
FileStream fs = new FileStream(destination, FileMode.Create, FileAccess.Write);
StreamWriter objWrite = new StreamWriter(fs);
objWrite.Write(builder);
objWrite.Close();
return destination;
}
catch (Exception ex)
{
return null;
}
}
public void StatsLogTaskProgressCallback(Object task, Double percentDone, String statusString)
{
if (statusString != null)
{
windowViewModel.StatsLogStatus = statusString;
}
}
public void StatsLogTaskCompletionCallback(Object task, bool successfullyCompleted)
{
windowViewModel.StatsLogActive = false;
_statsLogTask = null;
}
public void StatsLogTaskLogCallback(Object task, StatisticsEntry statisticsEntry)
{
windowViewModel.AddToStatsLog(statisticsEntry);
}
private StatsLogTask _statsLogTask = null;
public void StatsLogCommand(string type)
{
if (type.Equals("Start"))
{
windowViewModel.StatsLogActive = true;
windowViewModel.ClearStatsLog();
_statsLogTask = new StatsLogTask(this);
_statsLogTask.TaskProgressCallback = StatsLogTaskProgressCallback;
_statsLogTask.TaskLogCallback = StatsLogTaskLogCallback;
_statsLogTask.Start(StatsLogTaskCompletionCallback);
}
else if (type.Equals("Stop"))
{
if (_statsLogTask != null)
{
_statsLogTask.Stop();
}
}
else if (type.Equals("Export"))
{
String fileName = StatsLogToCsv(null);
if (fileName != null)
{
windowViewModel.StatsLogStatus = "Exported to " + fileName;
}
else
{
windowViewModel.StatsLogStatus = "Error trying to export";
}
}
}
public string StatsLogToCsv(string folder)
{
string separator = ",";
StringBuilder builder = new StringBuilder(Convert.ToString((char)65279));
ObservableCollection<StatisticsEntry> statsNotificationCollection = windowViewModel.StatsLogCollection;
// Build header
List<string> tempList = new List<string>();
tempList.Add("Module");
tempList.Add("Revision");
tempList.Add("Data");
builder.Append(string.Join(separator, tempList)).Append(Environment.NewLine);
// Populate data
for (int i = 0; i < statsNotificationCollection.Count; i++)
{
tempList = new List<string>();
tempList.Add("\"" + statsNotificationCollection[i].Id + "\"");
tempList.Add(statsNotificationCollection[i].Revision);
tempList.Add(statsNotificationCollection[i].Data);
builder.Append(string.Join(separator, tempList)).Append(Environment.NewLine);
}
// Save to CSV
try
{
string destination = "gi_" + windowViewModel.SerialNumber + "_" + DateTime.Now.ToString("dd_MM_yyyy_HH_mm") + "_stats";
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
destination = destination.Replace(c, '_');
}
if (string.IsNullOrEmpty(folder))
{
folder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
}
destination = folder + "\\" + destination + ".csv";
FileStream fs = new FileStream(destination, FileMode.Create, FileAccess.Write);
StreamWriter objWrite = new StreamWriter(fs);
objWrite.Write(builder);
objWrite.Close();
return destination;
}
catch (Exception ex)
{
Utility.Log.Write($"\n\n!!!!!!\n{ex.Message}\n{ex.StackTrace}\n!!!!!!\n\n");
return null;
}
}
public string TagsToCsv(string folder)
{
try
{
string destination = "gi_" + windowViewModel.DeviceId + "_" + DateTime.Now.ToString("dd_MM_yyyy_HH_mm") + "_tags";
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
destination = destination.Replace(c, '_');
}
if (string.IsNullOrEmpty(folder))
{
folder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
}
destination = folder + "\\" + destination + ".json";
var options = new JsonSerializerOptions { WriteIndented = true };
string jsonString = JsonSerializer.Serialize(windowViewModel, options);
File.WriteAllText(destination, jsonString);
return destination;
}
catch (Exception ex)
{
Utility.Log.Write($"\n\n!!!!!!\n{ex.Message}\n{ex.StackTrace}\n!!!!!!\n\n");
return null;
}
}
private void ReadAllTagsTask()
{
List<byte> tagReadList = new List<byte>();
ParameterReadCommand parameterReadCommand;
foreach (GlobalIPerlTag value in System.Enum.GetValues(typeof(GlobalIPerlTag)))
{
tagReadList.Add((byte)value);
if (tagReadList.Count == 5)
{
parameterReadCommand = new ParameterReadCommand(TagMap.GlobalIPerl, tagReadList);
NA2WSerialFrame response = SendNa2wSerial(parameterReadCommand, ParameterReadResponse._Code); // Wait for response (ParameterRead data) and parse.
if (response != null)
{
// Have to parse because we awaited for it
MessageReceived(this, new ReceptionEventArgs<ISerialMessageFrame>(response));
}
tagReadList = new List<byte>();
}
}
if (tagReadList.Count != 0)
{
parameterReadCommand = new ParameterReadCommand(TagMap.GlobalIPerl, tagReadList);
NA2WSerialFrame response = SendNa2wSerial(parameterReadCommand, ParameterReadResponse._Code); // Wait for response (ParameterRead data) and parse.
if (response != null)
{
// Have to parse because we awaited for it
MessageReceived(this, new ReceptionEventArgs<ISerialMessageFrame>(response));
}
}
foreach (SterlingMetrologyTag value in System.Enum.GetValues(typeof(SterlingMetrologyTag)))
{
tagReadList.Add((byte)value);
if (tagReadList.Count == 5)
{
parameterReadCommand = new ParameterReadCommand((TagMap)0x05, tagReadList);
NA2WSerialFrame response = SendNa2wSerial(parameterReadCommand, ParameterReadResponse._Code); // Wait for response (ParameterRead data) and parse.
if (response != null)
{
// Have to parse because we awaited for it
MessageReceived(this, new ReceptionEventArgs<ISerialMessageFrame>(response));
}
tagReadList = new List<byte>();
}
}
if (tagReadList.Count != 0)
{
parameterReadCommand = new ParameterReadCommand((TagMap)0x05, tagReadList);
NA2WSerialFrame response = SendNa2wSerial(parameterReadCommand, ParameterReadResponse._Code); // Wait for response (ParameterRead data) and parse.
if (response != null)
{
// Have to parse because we awaited for it
MessageReceived(this, new ReceptionEventArgs<ISerialMessageFrame>(response));
}
}
}
public void ReadAllTags()
{
System.Threading.Tasks.Task readAllTagsTask = new System.Threading.Tasks.Task(ReadAllTagsTask);
readAllTagsTask.Start();
}
public void DiagTaskProgressCallback(Object task, Double percentDone, String statusString)
{
if (statusString != null)
{
windowViewModel.DiagStatus = statusString;
}
}
public void DiagTaskCompletionCallback(Object task, bool successfullyCompleted)
{
windowViewModel.DiagActive = false;
_diagTask = null;
}
public void DiagTaskLogCallback(Object task, EventNotification eventNotification)
{
// TBD:
}
private DiagTask _diagTask = null;
private void SaveDiagnostics(string outputFile, string mapFile)
{
windowViewModel.DiagActive = true;
_diagTask = new DiagTask(this);
_diagTask.TaskProgressCallback = DiagTaskProgressCallback;
_diagTask.TaskLogCallback = DiagTaskLogCallback;
_diagTask.Start(DiagTaskCompletionCallback);
_diagTask.OutputFile = outputFile;
_diagTask.MapFile = mapFile;
_diagTask.ViewModel = windowViewModel;
_diagTask.Start(DiagTaskCompletionCallback);
}
} // end class
public partial class Ping_Normal : Sensus.Protocols.FlexNet.Ping
{
public Ping_Normal()
: base()
{
PingType = PingType.Normal;
Init();
}
partial void Init();
public static new Ping_Normal Parse(byte[] buffer, uint offset)
{
return Command.Parse<Ping_Normal>(buffer, offset, CommandLength);
}
}
public enum FrameEvent
{
Undefined,
ActivityBup,
Semi,
Log,
FlexNetFrame
}
public class FrameEventArgs<TFrame> : EventArgs where TFrame : IFrame
{
public FrameEventArgs()
: this(default(TFrame))
{
}
public FrameEventArgs(TFrame rxFrame)
: this(FrameEvent.Undefined, 0, rxFrame)
{
}
public FrameEventArgs(UInt32 address, TFrame rxFrame)
: this(FrameEvent.Undefined, address, rxFrame)
{
}
public FrameEventArgs(FrameEvent frameEvent, UInt32 address, TFrame rxFrame)
: base()
{
FrameEvent = frameEvent;
Address = address;
Frame = rxFrame;
Timestamp = RelativeTime.Now;
}
//
// Summary:
// Event type
public FrameEvent FrameEvent { get; set; }
//
// Summary:
// Time that the frame was received.
public RelativeTime Timestamp { get; set; }
//
// Summary:
// Frame received by the communication device.
public TFrame Frame { get; set; }
//
/// <summary>
/// Address frame targets
public UInt32 Address { get; set; }
public FrameEventArgs<TNewFrame> Cast<TNewFrame>() where TNewFrame : TFrame
{
return new FrameEventArgs<TNewFrame>() { FrameEvent = FrameEvent, Timestamp = Timestamp, Frame = (TNewFrame)Frame, Address = Address };
}
}
}