Add SerialFirmwareDownloadTask to NfcC7_DLL for firmware upgrade handling
This commit is contained in:
parent
96408eaef3
commit
0a45d66c0b
7
NfcC7_DLL/NfcHanler/ArchEventId.cs
Normal file
7
NfcC7_DLL/NfcHanler/ArchEventId.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace NfcC7_DLL.NfcHanler;
|
||||
|
||||
public enum ArchEventId: sbyte
|
||||
{
|
||||
Arch_EventId_Invalid = -2,
|
||||
Arch_EventId_DataContinuation = -1,
|
||||
}
|
||||
17
NfcC7_DLL/NfcHanler/ComCompare.cs
Normal file
17
NfcC7_DLL/NfcHanler/ComCompare.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System.Collections;
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler;
|
||||
|
||||
public class ComCompare : IComparer
|
||||
{
|
||||
int IComparer.Compare(Object x, Object y)
|
||||
{
|
||||
string sx = (string)x;
|
||||
string sy = (string)y;
|
||||
|
||||
int intx = int.Parse(sx.Substring(3));
|
||||
int inty = int.Parse(sy.Substring(3));
|
||||
|
||||
return (intx.CompareTo(inty));
|
||||
}
|
||||
}
|
||||
561
NfcC7_DLL/NfcHanler/DiagTask.cs
Normal file
561
NfcC7_DLL/NfcHanler/DiagTask.cs
Normal file
@ -0,0 +1,561 @@
|
||||
using System.Globalization;
|
||||
using Sensus.Protocols.FlexNet.FNv2;
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler
|
||||
{
|
||||
class DiagTask
|
||||
{
|
||||
private static readonly string ERASED_MEMORY = "FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF";
|
||||
|
||||
private MessageEngine messageEngine;
|
||||
private WindowViewModel windowViewModel = null;
|
||||
|
||||
private TaskCompletionCallbackDelegate taskCompletionCallback;
|
||||
private TaskProgressCallbackDelegate taskProgessCallback;
|
||||
private TaskLogCallbackDelegate taskLogCallback;
|
||||
|
||||
private bool haltExecution;
|
||||
|
||||
private System.Threading.Timer timer;
|
||||
|
||||
/// <summary>
|
||||
/// Progress and status
|
||||
/// </summary>
|
||||
private int progress = 0;
|
||||
private string status = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Memory read variables
|
||||
/// </summary>
|
||||
private UInt32 address;
|
||||
private UInt32 endAddress;
|
||||
private UInt16 addressInc;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the number of times to execute a wait loop
|
||||
/// </summary>
|
||||
private int waitCount;
|
||||
|
||||
public TaskProgressCallbackDelegate TaskProgressCallback
|
||||
{
|
||||
set
|
||||
{
|
||||
taskProgessCallback = value;
|
||||
}
|
||||
}
|
||||
|
||||
public TaskLogCallbackDelegate TaskLogCallback
|
||||
{
|
||||
set
|
||||
{
|
||||
taskLogCallback = value;
|
||||
}
|
||||
}
|
||||
|
||||
private enum AlgorithmState
|
||||
{
|
||||
Idle,
|
||||
ReadAllTags,
|
||||
ReadStats,
|
||||
SaveStats,
|
||||
ReadEvents,
|
||||
SaveEvents,
|
||||
GetEventLogMemory,
|
||||
NextEventLogMemory,
|
||||
SaveEventLogMemory,
|
||||
GetReadingLogMemory,
|
||||
NextReadingLogMemory,
|
||||
SaveReadingLogMemory,
|
||||
GetTraceMemory,
|
||||
NextTraceMemory,
|
||||
SaveTraceMemory,
|
||||
GetSemi,
|
||||
Finished
|
||||
};
|
||||
|
||||
AlgorithmState timerState = AlgorithmState.Idle;
|
||||
bool waitingForAck = false;
|
||||
string folder = string.Empty;
|
||||
|
||||
public DiagTask(MessageEngine messageEngine)
|
||||
{
|
||||
this.messageEngine = messageEngine;
|
||||
|
||||
taskProgessCallback = null;
|
||||
|
||||
timer = new System.Threading.Timer(TimerCb, null, Timeout.Infinite, Timeout.Infinite);
|
||||
}
|
||||
|
||||
public string MapFile { get; set; }
|
||||
public string OutputFile { get; set; }
|
||||
|
||||
public WindowViewModel ViewModel
|
||||
{
|
||||
set
|
||||
{
|
||||
windowViewModel = value;
|
||||
|
||||
windowViewModel.LogWithDescription = true;
|
||||
windowViewModel.LogWithHexString = true;
|
||||
windowViewModel.LogChargingData = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool Start(TaskCompletionCallbackDelegate taskCompletionCallback)
|
||||
{
|
||||
bool retValue = false;
|
||||
|
||||
folder = Path.GetDirectoryName(OutputFile);
|
||||
|
||||
this.taskCompletionCallback = taskCompletionCallback;
|
||||
|
||||
if (messageEngine != null)
|
||||
{
|
||||
// Write to log upgrade details
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Extracting Diagnostic Info" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, "Starting...");
|
||||
}
|
||||
|
||||
ReadAllTags();
|
||||
|
||||
timer.Change(1000, Timeout.Infinite);
|
||||
|
||||
retValue = true;
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
// Signal to halt execution
|
||||
haltExecution = true;
|
||||
|
||||
// Signal completion but not successful
|
||||
ExtractComplete(false);
|
||||
}
|
||||
|
||||
private void ExtractComplete(bool successful)
|
||||
{
|
||||
timerState = AlgorithmState.Idle;
|
||||
timer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
|
||||
if (haltExecution || !successful)
|
||||
{
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Aborting Diagnostic Extraction." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
}
|
||||
else if (successful)
|
||||
{
|
||||
Utility.Log.Write("");
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Diagnostic Extraction Completed Successfully." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
Utility.Log.Write("");
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Diagnostic Extraction Failed." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
}
|
||||
|
||||
if (taskCompletionCallback != null)
|
||||
{
|
||||
taskCompletionCallback(this, successful);
|
||||
}
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, "Diagnostic info extracted");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void TimerCb(object state)
|
||||
{
|
||||
int dueTime = 1000;
|
||||
|
||||
switch (timerState)
|
||||
{
|
||||
case AlgorithmState.Idle:
|
||||
break;
|
||||
|
||||
case AlgorithmState.ReadAllTags:
|
||||
{
|
||||
status = "Saved all tags";
|
||||
|
||||
String fileName = messageEngine.TagsToCsv(folder);
|
||||
|
||||
// Append tags to output file
|
||||
try
|
||||
{
|
||||
File.AppendAllText(OutputFile, File.ReadAllText(fileName));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
status = e.Message;
|
||||
Utility.Log.Write(e.Message);
|
||||
Utility.Log.Write(e.StackTrace);
|
||||
}
|
||||
Utility.Log.Write(DateTime.Now.ToString(MessageEngine.TimeFormatString) + " : Tags saved to " + fileName + "\n");
|
||||
|
||||
timerState = AlgorithmState.ReadStats;
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.ReadStats:
|
||||
{
|
||||
status = "Reading statistics";
|
||||
|
||||
messageEngine.StatsLogCommand("Start");
|
||||
|
||||
waitCount = 30;
|
||||
|
||||
timerState= AlgorithmState.SaveStats;
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.SaveStats:
|
||||
{
|
||||
if (!windowViewModel.StatsLogActive || --waitCount <= 0)
|
||||
{
|
||||
status = "Saved statistics";
|
||||
|
||||
messageEngine.StatsLogCommand("Stop");
|
||||
string fileName = messageEngine.StatsLogToCsv(folder);
|
||||
|
||||
// Append stats to output file
|
||||
try
|
||||
{
|
||||
File.AppendAllText(OutputFile, File.ReadAllText(fileName));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
status = e.Message;
|
||||
Utility.Log.Write(e.Message);
|
||||
Utility.Log.Write(e.StackTrace);
|
||||
}
|
||||
Utility.Log.Write(DateTime.Now.ToString(MessageEngine.TimeFormatString) + " : Stats log saved to " + fileName + "\n");
|
||||
|
||||
timerState = AlgorithmState.ReadEvents;
|
||||
dueTime = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.ReadEvents:
|
||||
{
|
||||
status = "Getting event log";
|
||||
windowViewModel.EventLogTimeFrameSelectedValue = "Full";
|
||||
messageEngine.EventLogCommand("Start");
|
||||
|
||||
waitCount = 20;
|
||||
timerState = AlgorithmState.SaveEvents;
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.SaveEvents:
|
||||
{
|
||||
if (!windowViewModel.EventLogActive || --waitCount <= 0)
|
||||
{
|
||||
status = "Saved event log";
|
||||
|
||||
messageEngine.EventLogCommand("Stop");
|
||||
string fileName = messageEngine.EventLogToCsv(folder);
|
||||
|
||||
// Append events to output file
|
||||
try
|
||||
{
|
||||
File.AppendAllText(OutputFile, File.ReadAllText(fileName));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
status = e.Message;
|
||||
Utility.Log.Write(e.Message);
|
||||
Utility.Log.Write(e.StackTrace);
|
||||
}
|
||||
Utility.Log.Write(DateTime.Now.ToString(MessageEngine.TimeFormatString) + " : Event log saved to " + fileName + "\n");
|
||||
|
||||
timerState = AlgorithmState.GetEventLogMemory;
|
||||
dueTime = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.GetEventLogMemory:
|
||||
{
|
||||
status = "Getting event log memory";
|
||||
|
||||
address = 0x08066000;
|
||||
endAddress = 0x0806C000;
|
||||
addressInc = 0x0080;
|
||||
windowViewModel.MemoryReadData = string.Empty;
|
||||
MemoryReadCommand memoryReadCmd = new MemoryReadCommand();
|
||||
memoryReadCmd.NumBytes = 128;
|
||||
memoryReadCmd.Source = 0;
|
||||
memoryReadCmd.Address = address;
|
||||
messageEngine.SendNa2wSerial(memoryReadCmd, false);
|
||||
|
||||
timerState = AlgorithmState.NextEventLogMemory;
|
||||
dueTime = 100;
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.NextEventLogMemory:
|
||||
{
|
||||
address += addressInc;
|
||||
if ( (address >= endAddress) ||
|
||||
windowViewModel.MemoryReadData.Contains(ERASED_MEMORY) )
|
||||
{
|
||||
timerState = AlgorithmState.SaveEventLogMemory;
|
||||
dueTime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = $"Reading@{address.ToString("X8")}";
|
||||
|
||||
MemoryReadCommand memoryReadCmd = new MemoryReadCommand();
|
||||
memoryReadCmd.NumBytes = 128;
|
||||
memoryReadCmd.Source = 0;
|
||||
memoryReadCmd.Address = address;
|
||||
messageEngine.SendNa2wSerial(memoryReadCmd, false);
|
||||
|
||||
dueTime = 100;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.SaveEventLogMemory:
|
||||
{
|
||||
status = "Saved event log memory";
|
||||
try
|
||||
{
|
||||
File.AppendAllText(OutputFile, windowViewModel.MemoryReadData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
status = ex.Message;
|
||||
Utility.Log.Write(ex.ToString());
|
||||
Utility.Log.Write(ex.StackTrace);
|
||||
}
|
||||
|
||||
timerState = AlgorithmState.GetReadingLogMemory;
|
||||
dueTime = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.GetReadingLogMemory:
|
||||
{
|
||||
status = "Reading Log";
|
||||
|
||||
windowViewModel.MemoryReadData = string.Empty;
|
||||
address = 0x0806C000;
|
||||
endAddress = 0x08070000;
|
||||
addressInc = 0x0080;
|
||||
MemoryReadCommand memoryReadCmd = new MemoryReadCommand();
|
||||
memoryReadCmd.NumBytes = 128;
|
||||
memoryReadCmd.Source = 0;
|
||||
memoryReadCmd.Address = address;
|
||||
messageEngine.SendNa2wSerial(memoryReadCmd, false);
|
||||
|
||||
timerState = AlgorithmState.NextReadingLogMemory;
|
||||
dueTime = 100;
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.NextReadingLogMemory:
|
||||
{
|
||||
address += addressInc;
|
||||
if ( (address >= endAddress) ||
|
||||
windowViewModel.MemoryReadData.Contains(ERASED_MEMORY) )
|
||||
{
|
||||
timerState = AlgorithmState.SaveReadingLogMemory;
|
||||
dueTime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = $"Reading@{address.ToString("X8")}";
|
||||
|
||||
MemoryReadCommand memoryReadCmd = new MemoryReadCommand();
|
||||
memoryReadCmd.NumBytes = 128;
|
||||
memoryReadCmd.Source = 0;
|
||||
memoryReadCmd.Address = address;
|
||||
messageEngine.SendNa2wSerial(memoryReadCmd, false);
|
||||
|
||||
dueTime = 100;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.SaveReadingLogMemory:
|
||||
{
|
||||
status = "Saved reading log memory";
|
||||
|
||||
try
|
||||
{
|
||||
File.AppendAllText(OutputFile, windowViewModel.MemoryReadData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
status = ex.Message;
|
||||
Utility.Log.Write(ex.ToString());
|
||||
Utility.Log.Write(ex.StackTrace);
|
||||
}
|
||||
|
||||
timerState = AlgorithmState.GetTraceMemory;
|
||||
dueTime = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.GetTraceMemory:
|
||||
{
|
||||
UInt32 traceStart = 0x2000745c;
|
||||
if (!string.IsNullOrWhiteSpace(MapFile) && File.Exists(MapFile))
|
||||
{
|
||||
string[] map = File.ReadAllLines(MapFile);
|
||||
string[] lines = Array.FindAll(map, p => p.Contains("WMBusTrack__Log"));
|
||||
if (lines.Length > 0)
|
||||
{
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (!line.Contains("__LogEntry") && line.Contains("0x"))
|
||||
{
|
||||
string hexString = line.Substring(line.IndexOf("0x") + 2, 8);
|
||||
traceStart = UInt32.Parse(hexString, NumberStyles.HexNumber);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
UInt32 traceEnd = traceStart + 0x180;
|
||||
address = traceStart;
|
||||
endAddress = traceEnd;
|
||||
addressInc = 0x80;
|
||||
windowViewModel.MemoryReadData = string.Empty;
|
||||
|
||||
status = $"Reading trace memory@{traceStart.ToString("X8")}";
|
||||
|
||||
MemoryReadCommand memoryReadCmd = new MemoryReadCommand();
|
||||
memoryReadCmd.NumBytes = 128;
|
||||
memoryReadCmd.Source = 0;
|
||||
memoryReadCmd.Address = address;
|
||||
messageEngine.SendNa2wSerial(memoryReadCmd, false);
|
||||
|
||||
timerState = AlgorithmState.NextTraceMemory;
|
||||
dueTime = 100;
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.NextTraceMemory:
|
||||
{
|
||||
address += addressInc;
|
||||
if (address < endAddress)
|
||||
{
|
||||
status = $"Reading@{address.ToString("X8")}";
|
||||
|
||||
MemoryReadCommand memoryReadCmd = new MemoryReadCommand();
|
||||
memoryReadCmd.NumBytes = 128;
|
||||
memoryReadCmd.Source = 0;
|
||||
memoryReadCmd.Address = address;
|
||||
messageEngine.SendNa2wSerial(memoryReadCmd, false);
|
||||
|
||||
dueTime = 100;
|
||||
}
|
||||
else if (address == endAddress)
|
||||
{
|
||||
status = $"Reading@{address.ToString("X8")}";
|
||||
|
||||
MemoryReadCommand memoryReadCmd = new MemoryReadCommand();
|
||||
memoryReadCmd.NumBytes = 4;
|
||||
memoryReadCmd.Source = 0;
|
||||
memoryReadCmd.Address = address;
|
||||
messageEngine.SendNa2wSerial(memoryReadCmd, false);
|
||||
|
||||
dueTime = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
timerState = AlgorithmState.SaveTraceMemory;
|
||||
dueTime = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.SaveTraceMemory:
|
||||
{
|
||||
status = "Saved trace memory";
|
||||
|
||||
try
|
||||
{
|
||||
File.AppendAllText(OutputFile, "\n" + windowViewModel.MemoryReadData);
|
||||
Utility.Log.Write(DateTime.Now.ToString(MessageEngine.TimeFormatString) + " : Trace memory saved to " + OutputFile + "\n");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
status = ex.Message;
|
||||
Utility.Log.Write(ex.ToString());
|
||||
Utility.Log.Write(ex.StackTrace);
|
||||
}
|
||||
|
||||
timerState = AlgorithmState.GetSemi;
|
||||
dueTime = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.GetSemi:
|
||||
{
|
||||
windowViewModel.SRfKeySelectedItem = "None";
|
||||
windowViewModel.SRfAuthSelectedItem = "Default";
|
||||
windowViewModel.PamPayload = "00";
|
||||
messageEngine.SensusRfCommand("CustomPam");
|
||||
timerState = AlgorithmState.Finished;
|
||||
dueTime = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case AlgorithmState.Finished:
|
||||
{
|
||||
status = "Diagnostic extraction finished.";
|
||||
progress = 99;
|
||||
|
||||
ExtractComplete(true);
|
||||
|
||||
dueTime = Timeout.Infinite;
|
||||
}
|
||||
break;
|
||||
|
||||
} // end switch
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, ++progress, status);
|
||||
}
|
||||
|
||||
timer.Change(dueTime, Timeout.Infinite);
|
||||
}
|
||||
|
||||
private void ReadAllTags()
|
||||
{
|
||||
timerState = AlgorithmState.ReadAllTags;
|
||||
progress = 1;
|
||||
status = "Reading all tags";
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, progress, status);
|
||||
}
|
||||
|
||||
messageEngine.ReadAllTags();
|
||||
}
|
||||
|
||||
} // end class
|
||||
}
|
||||
459
NfcC7_DLL/NfcHanler/EventLogTask.cs
Normal file
459
NfcC7_DLL/NfcHanler/EventLogTask.cs
Normal file
@ -0,0 +1,459 @@
|
||||
using NfcC7_DLL.NfcHanler.FieldLogicStaging;
|
||||
using Sensus;
|
||||
using Sensus.Protocols.FlexNet;
|
||||
using Sensus.Protocols.FlexNet.FNv2;
|
||||
using Sensus.Protocols.FlexNet.FNv2.NA2WParameters;
|
||||
using Sensus.Protocols.FlexNet.Serial.FNv2;
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler
|
||||
{
|
||||
class EventLogTask
|
||||
{
|
||||
private MessageEngine messageEngine;
|
||||
|
||||
private TaskCompletionCallbackDelegate taskCompletionCallback;
|
||||
private TaskProgressCallbackDelegate taskProgessCallback;
|
||||
private TaskLogCallbackDelegate taskLogCallback;
|
||||
private ushort blocksPerCommand = 1;
|
||||
|
||||
private bool haltExecution;
|
||||
|
||||
private System.Threading.Timer timer;
|
||||
|
||||
public TaskProgressCallbackDelegate TaskProgressCallback
|
||||
{
|
||||
set
|
||||
{
|
||||
taskProgessCallback = value;
|
||||
}
|
||||
}
|
||||
|
||||
public TaskLogCallbackDelegate TaskLogCallback
|
||||
{
|
||||
set
|
||||
{
|
||||
taskLogCallback = value;
|
||||
}
|
||||
}
|
||||
private enum AlgorithmState
|
||||
{
|
||||
IDLE,
|
||||
READ_SERIAL_NUMBER,
|
||||
READ_EVENTS
|
||||
};
|
||||
|
||||
public bool AckLoadBlock { get; set; }
|
||||
|
||||
public UInt32 TimeFrame { get; set; }
|
||||
|
||||
AlgorithmState timerState = AlgorithmState.IDLE;
|
||||
bool waitingForAck = false;
|
||||
|
||||
UInt64 extractTime = 0x0000;
|
||||
UInt16 eventCount = 0;
|
||||
UInt64 serialNumber = 0;
|
||||
UInt32 numberOfEvents = 0;
|
||||
List<byte> fragments = new List<byte>();
|
||||
|
||||
|
||||
public EventLogTask(MessageEngine messageEngine)
|
||||
{
|
||||
this.messageEngine = messageEngine;
|
||||
|
||||
TimeFrame = 0xffffffff;
|
||||
|
||||
taskProgessCallback = null;
|
||||
|
||||
timer = new System.Threading.Timer(TimerCb, null, Timeout.Infinite, Timeout.Infinite);
|
||||
}
|
||||
|
||||
|
||||
public bool Start(TaskCompletionCallbackDelegate taskCompletionCallback)
|
||||
{
|
||||
bool retValue = false;
|
||||
|
||||
this.taskCompletionCallback = taskCompletionCallback;
|
||||
extractTime = 0;
|
||||
eventCount = 0;
|
||||
numberOfEvents = 0;
|
||||
fragments = new List<byte>();
|
||||
|
||||
if (messageEngine != null)
|
||||
{
|
||||
// Write to log upgrade details
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Extracting Event Log" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, "Starting...");
|
||||
}
|
||||
|
||||
SendSessionQueryCmd();
|
||||
|
||||
timer.Change(1000, Timeout.Infinite);
|
||||
|
||||
retValue = true;
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
// Signal to halt execution
|
||||
haltExecution = true;
|
||||
|
||||
// Signal completion but not successful
|
||||
ExtractComplete(false);
|
||||
}
|
||||
private void ExtractComplete(bool successful)
|
||||
{
|
||||
timerState = AlgorithmState.IDLE;
|
||||
timer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
|
||||
if (haltExecution || !successful)
|
||||
{
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Aborting Log Extraction." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
}
|
||||
else if (successful)
|
||||
{
|
||||
Utility.Log.Write("");
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Log Extraction Completed Successfully." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
Utility.Log.Write("");
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Log Extraction Failed." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
}
|
||||
|
||||
if (taskCompletionCallback != null)
|
||||
{
|
||||
taskCompletionCallback(this, successful);
|
||||
}
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, eventCount.ToString() + " event extracted");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void TimerCb(object state)
|
||||
{
|
||||
if (timerState != AlgorithmState.IDLE)
|
||||
{
|
||||
SendEventReadCmd();
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessReply(NA2WSerialFrame message)
|
||||
{
|
||||
UnknownResponse unknownResponse = message.Unwrap<UnknownResponse>();
|
||||
|
||||
if ((null != unknownResponse) && (unknownResponse.CommandCode == 0x12))
|
||||
{
|
||||
// Event Data Response
|
||||
byte[] payload = unknownResponse.Contents;
|
||||
UInt64 messageTimeMs = (UInt64)payload.Read<UInt32>((1 * 8) + 0, 32) * 1000; // Message time in payload is in seconds
|
||||
byte numberOfEvents = payload.Read<byte>((5 * 8) + 0, 7);
|
||||
|
||||
if (numberOfEvents == 0)
|
||||
{
|
||||
ExtractComplete(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
timer.Change(1000, Timeout.Infinite);
|
||||
|
||||
uint offset = 6;
|
||||
while (numberOfEvents != 0)
|
||||
{
|
||||
UInt16 dataLength = payload.Read<UInt16>((offset + 9) * 8 + 0, 16);
|
||||
|
||||
if (taskLogCallback != null)
|
||||
{
|
||||
sbyte id = payload.Read<sbyte>((offset * 8) + 0, 8);
|
||||
|
||||
if (id == (sbyte) ArchEventId.Arch_EventId_Invalid)
|
||||
{
|
||||
ExtractComplete(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt64 timeStampMs = payload.Read<UInt64>((offset + 1) * 8 + 0, 64);
|
||||
UInt16 fileID = payload.Read<UInt16>((offset + 11) * 8 + 0, 16);
|
||||
UInt16 lineNumber = payload.Read<UInt16>((offset + 13) * 8 + 0, 16);
|
||||
byte[] data = new byte[dataLength];
|
||||
Array.Copy(payload, offset + 15, data, 0, dataLength);
|
||||
|
||||
GlobalIPerlEvent iPerlEvent = new GlobalIPerlEvent(id, data, fileID, lineNumber);
|
||||
|
||||
DateTime dateTime = DateTime.Now;
|
||||
// Calculate time of event. Message Time should allows be greater than event time
|
||||
if (messageTimeMs > timeStampMs)
|
||||
{
|
||||
Double timeDiffMs = (Double)timeStampMs - (Double)messageTimeMs; // Time in past
|
||||
dateTime = dateTime.AddMilliseconds(timeDiffMs);
|
||||
}
|
||||
|
||||
EventNotification eventNotification = new EventNotification();
|
||||
eventNotification.Id = iPerlEvent.Name;
|
||||
eventNotification.File = iPerlEvent.File;
|
||||
eventNotification.Line = lineNumber.ToString();
|
||||
eventNotification.TimeStamp = dateTime.ToString();
|
||||
eventNotification.Description = iPerlEvent.Description;
|
||||
eventNotification.Data = data.ToHexString();
|
||||
|
||||
taskLogCallback(this, eventNotification);
|
||||
|
||||
extractTime = timeStampMs + 1;
|
||||
|
||||
eventCount++;
|
||||
}
|
||||
}
|
||||
|
||||
numberOfEvents--;
|
||||
offset += (uint)dataLength + 15U;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (message.Payload is NetworkResponse networkResponse)
|
||||
{
|
||||
|
||||
if (networkResponse.Payload is ParameterReadResponse parameterReadResponse)
|
||||
{
|
||||
if (parameterReadResponse.TagMap == TagMap.GlobalIPerl)
|
||||
{
|
||||
List<NA2WParameter> na2wParameterList = parameterReadResponse.Parameters;
|
||||
|
||||
foreach (NA2WParameter na2wParameter in na2wParameterList)
|
||||
{
|
||||
switch (na2wParameter.Tag)
|
||||
{
|
||||
case ((byte)GlobalIPerlTag.SerialNumber):
|
||||
{
|
||||
serialNumber = na2wParameter.Value.Read<UInt64>(0);
|
||||
|
||||
SendInitialEventReadCmd();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (networkResponse.Payload is FragmentedFrame fragment)
|
||||
{
|
||||
var tmp = fragment.Code;
|
||||
tmp = fragment.CommandCode;
|
||||
var payloadLength = fragment.PayloadLength;
|
||||
byte[] payload = fragment.Content;
|
||||
byte version = payload.Read<byte>(0, 4);
|
||||
byte map = payload.Read<byte>(0 + 4, 4);
|
||||
UInt32 messageTime = payload.Read<UInt32>(8 * 1) * 1000;
|
||||
byte numberEvents = payload.Read<byte>(8 * 5, 7);
|
||||
|
||||
if (numberEvents > numberOfEvents)
|
||||
{
|
||||
numberOfEvents = numberEvents;
|
||||
}
|
||||
#if false
|
||||
else
|
||||
{
|
||||
eventCount = Convert.ToUInt16(numberOfEvents - numberEvents);
|
||||
if (eventCount == 0)
|
||||
{
|
||||
ExtractComplete(true);
|
||||
}
|
||||
}
|
||||
fragments.AddRange(payload);
|
||||
#else
|
||||
fragments.AddRange(payload);
|
||||
for (uint offset = 6; offset < payloadLength && numberEvents > 0; )
|
||||
{
|
||||
try
|
||||
{
|
||||
// event
|
||||
sbyte id = payload.Read<sbyte>((offset * 8) + 0, 8);
|
||||
|
||||
if (id == (sbyte)ArchEventId.Arch_EventId_Invalid)
|
||||
{
|
||||
ExtractComplete(true);
|
||||
break;
|
||||
}
|
||||
else if ((offset + 15) < payload.Length)
|
||||
{
|
||||
UInt64 timeStampMs = payload.Read<UInt64>((offset + 1) * 8 + 0, 64);
|
||||
UInt16 dataLength = payload.Read<UInt16>((offset + 9) * 8 + 0, 16);
|
||||
UInt16 fileID = payload.Read<UInt16>((offset + 11) * 8 + 0, 16);
|
||||
UInt16 lineNumber = payload.Read<UInt16>((offset + 13) * 8 + 0, 16);
|
||||
byte[] data = new byte[dataLength];
|
||||
|
||||
if ((offset + 15 + dataLength) > payloadLength)
|
||||
{
|
||||
dataLength = Convert.ToUInt16(payloadLength - offset - 15);
|
||||
}
|
||||
Array.Copy(payload, offset + 15, data, 0, dataLength);
|
||||
|
||||
GlobalIPerlEvent iPerlEvent = new GlobalIPerlEvent(id, data, fileID, lineNumber);
|
||||
|
||||
DateTime dateTime = DateTime.Now;
|
||||
// Calculate time of event. Message Time should allows be greater than event time
|
||||
if (messageTime > timeStampMs)
|
||||
{
|
||||
Double timeDiffMs = (Double)timeStampMs - (Double)messageTime; // Time in past
|
||||
dateTime = dateTime.AddMilliseconds(timeDiffMs);
|
||||
}
|
||||
|
||||
EventNotification eventNotification = new EventNotification();
|
||||
eventNotification.Id = iPerlEvent.Name;
|
||||
eventNotification.File = iPerlEvent.File;
|
||||
eventNotification.Line = lineNumber.ToString();
|
||||
eventNotification.TimeStamp = dateTime.ToString();
|
||||
eventNotification.Description = iPerlEvent.Description;
|
||||
eventNotification.Data = data.ToHexString();
|
||||
|
||||
taskLogCallback(this, eventNotification);
|
||||
|
||||
extractTime = timeStampMs + 1;
|
||||
|
||||
eventCount++;
|
||||
|
||||
offset += dataLength + 15U;
|
||||
|
||||
numberEvents--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((offset + 14) < payloadLength)
|
||||
{
|
||||
UInt64 timeStampMs = payload.Read<UInt64>((offset + 1) * 8 + 0, 64);
|
||||
byte dataLength = payload.Read<byte>((offset + 9) * 8 + 0, 16);
|
||||
UInt16 fileID = payload.Read<UInt16>((offset + 11) * 8 + 0, 16);
|
||||
UInt16 lineNumber = payload.Read<UInt16>((offset + 13) * 8 + 0, 16);
|
||||
}
|
||||
else if ((offset + 12) < payloadLength)
|
||||
{
|
||||
UInt64 timeStampMs = payload.Read<UInt64>((offset + 1) * 8 + 0, 64);
|
||||
byte dataLength = payload.Read<byte>((offset + 9) * 8 + 0, 16);
|
||||
UInt16 fileID = payload.Read<UInt16>((offset + 11) * 8 + 0, 16);
|
||||
}
|
||||
else if ((offset + 10) < payloadLength)
|
||||
{
|
||||
UInt64 timeStampMs = payload.Read<UInt64>((offset + 1) * 8 + 0, 64);
|
||||
byte dataLength = payload.Read<byte>((offset + 9) * 8 + 0, 16);
|
||||
}
|
||||
else if ((offset + 9) < payloadLength)
|
||||
{
|
||||
UInt64 timeStampMs = payload.Read<UInt64>((offset + 1) * 8 + 0, 64);
|
||||
}
|
||||
}
|
||||
|
||||
offset = payloadLength;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Utility.Log.Write($"Exception: {ex.Message}\n{ex.StackTrace}\n");
|
||||
timer.Change(1000, Timeout.Infinite);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
timer.Change(1000, Timeout.Infinite);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TBD:
|
||||
timer.Change(1000, Timeout.Infinite);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TBD:
|
||||
timer.Change(1000, Timeout.Infinite);
|
||||
}
|
||||
}
|
||||
private void SendSessionQueryCmd()
|
||||
{
|
||||
List<byte> tagList = new List<byte>();
|
||||
tagList.Add((byte)GlobalIPerlTag.SerialNumber);
|
||||
|
||||
timerState = AlgorithmState.READ_SERIAL_NUMBER;
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, "Read Serial Number Sent");
|
||||
}
|
||||
|
||||
// Send message request
|
||||
ParameterReadCommand parameterReadCommand = new ParameterReadCommand(TagMap.GlobalIPerl, tagList);
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(parameterReadCommand, ParameterReadResponse._Code);
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendInitialEventReadCmd()
|
||||
{
|
||||
EventReadV1 eventReadV1 = new EventReadV1();
|
||||
|
||||
eventReadV1.Time = TimeFrame;
|
||||
eventReadV1.ReadAfterTime = true;
|
||||
// eventReadV1.NumberOfEvents = 127;
|
||||
eventReadV1.NumberOfEvents = 9; // Limit to 9 because fragments over NFC not working. 250ish is MTU size.
|
||||
|
||||
timerState = AlgorithmState.READ_EVENTS;
|
||||
|
||||
// Send message request
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(eventReadV1, true);
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, "Initial EventRead sent");
|
||||
}
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendEventReadCmd()
|
||||
{
|
||||
EventReadV0 eventReadV0 = new EventReadV0();
|
||||
|
||||
eventReadV0.Time = extractTime;
|
||||
eventReadV0.ReadAfterTime = true;
|
||||
// eventReadV0.NumberOfEvents = 127;
|
||||
eventReadV0.NumberOfEvents = 9; // Limit to 9 because fragments over NFC not working. 250ish is MTU size.
|
||||
|
||||
timerState = AlgorithmState.READ_EVENTS;
|
||||
|
||||
// Send message request
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(eventReadV0, true);
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, eventCount.ToString() + " events extracted");
|
||||
}
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
232
NfcC7_DLL/NfcHanler/GlobalIPerlEvent.cs
Normal file
232
NfcC7_DLL/NfcHanler/GlobalIPerlEvent.cs
Normal file
@ -0,0 +1,232 @@
|
||||
|
||||
using Sensus;
|
||||
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler;
|
||||
|
||||
|
||||
|
||||
public class GlobalIPerlEvent
|
||||
{
|
||||
public static readonly string[] ApplicationEventIDNames =
|
||||
{
|
||||
"ApplicationEvent_SelfTestCompleted"
|
||||
};
|
||||
|
||||
public static readonly string[] SterlingEventIDNames =
|
||||
{
|
||||
"SterlingEvent_CtrlInit",
|
||||
"SterlingEvent_CtrlStart",
|
||||
"SterlingEvent_CtrlStop",
|
||||
"SterlingEvent_CtrlReset",
|
||||
"SterlingEvent_DrvInit",
|
||||
"SterlingEvent_DrvReset" ,
|
||||
"SterlingEvent_DrvResetFailure",
|
||||
"SterlingEvent_DrvSampleError",
|
||||
"SterlingEvent_DrvFifoOverrun",
|
||||
"SterlingEvent_FieldChanged",
|
||||
"SterlingEvent_AsicError",
|
||||
"SterlingEvent_ConfigError",
|
||||
"SterlingEvent_MetrologyError",
|
||||
"SterlingEvent_HWError",
|
||||
"SterlingEvent_IrqOverlap",
|
||||
|
||||
"SterlingEvent_FieldNegativeOrZero",
|
||||
|
||||
"SterlingEvent_HeartbeatMissing",
|
||||
"SterlingEvent_MetrologyDebug",
|
||||
};
|
||||
|
||||
|
||||
// Add possible file names to dictionary below
|
||||
// Dictionary uses the first byte of the given fileID to identify the
|
||||
// module, then indexing into the list associated with the specific module
|
||||
// with the file index will retrieve appropriate file label
|
||||
private static readonly Dictionary<byte, List<string>> FileLabels = new Dictionary<byte, List<string>>()
|
||||
{
|
||||
{ ((byte)ModuleID.ModuleID_Application), new List<string> { "Application - factory", } },
|
||||
{ ((byte)ModuleID.ModuleID_Sterling), new List<string> { "Sterling - IPerlAsicDriver",
|
||||
"Sterling - IPerlAsicFieldControl",
|
||||
"Sterling - SterlingWaterRegisterMetrology",} },
|
||||
};
|
||||
|
||||
// Add possible architecture-defined event ID names to dictionary below
|
||||
// Dictionary uses the first byte of the given fileID to identify the
|
||||
// module, then extracts associated string
|
||||
private static readonly Dictionary<sbyte, string> archEventIDLabels = new Dictionary<sbyte, string>()
|
||||
{
|
||||
{ ((sbyte)ArchEventId.Arch_EventId_Invalid), "Event ID invalid" },
|
||||
{ ((sbyte)ArchEventId.Arch_EventId_DataContinuation), "Event ID data continuation" },
|
||||
};
|
||||
|
||||
// Add possible event ID names to dictionary below
|
||||
// Dictionary uses the first byte of the given fileID to identify the
|
||||
// module, then indexing into the list associated with the specific module
|
||||
// with the file index will retrieve appropriate file label
|
||||
private static readonly Dictionary<byte, List<string>> eventIDLabels = new Dictionary<byte, List<string>>()
|
||||
{
|
||||
{ ((byte)ModuleID.ModuleID_Application), new List<string>(ApplicationEventIDNames) },
|
||||
{ ((byte)ModuleID.ModuleID_Sterling), new List<string>(SterlingEventIDNames) },
|
||||
};
|
||||
|
||||
// Sterling driver errors
|
||||
private static readonly Dictionary<sbyte, string> sterlingDriverErrorLabels = new Dictionary<sbyte, string>()
|
||||
{
|
||||
{ ((sbyte)SterlingDriverError.SterlingDvr_Error_BlockInvalid), "Block invalid" },
|
||||
{ ((sbyte)SterlingDriverError.SterlingDvr_Error_ResetFailed), "Reset failed" },
|
||||
{ ((sbyte)SterlingDriverError.SterlingDvr_Error_Timeout), "Timeout" },
|
||||
{ ((sbyte)SterlingDriverError.SterlingDvr_Error_CommsFailure), "Communications failure" },
|
||||
{ ((sbyte)SterlingDriverError.SterlingDvr_Error_ConfigInvalid), "Configuration invalid" },
|
||||
{ ((sbyte)SterlingDriverError.SterlingDvr_Error_None), "No error" },
|
||||
{ ((sbyte)SterlingDriverError.SterlingDvr_Error_StateAlreadyValid), "State already valid" },
|
||||
{ ((sbyte)SterlingDriverError.SterlingDvr_Error_Retried), "Retried" },
|
||||
};
|
||||
|
||||
public static string GetFileLabel(ushort encodedFileID)
|
||||
{
|
||||
byte module = (byte)(encodedFileID >> 8); // First 8 bits
|
||||
byte fileIndex = (byte)(encodedFileID & 0xFF); // Last 8 bits
|
||||
|
||||
if (!FileLabels.TryGetValue(module, out var labels))
|
||||
{
|
||||
return "Unknown module ID";
|
||||
}
|
||||
|
||||
if (fileIndex >= labels.Count)
|
||||
{
|
||||
return "Unknown file index";
|
||||
}
|
||||
|
||||
return labels[fileIndex];
|
||||
}
|
||||
|
||||
public static string GetEventIDLabel(ushort encodedFileID, sbyte id)
|
||||
{
|
||||
// Check if this is an architecture-defined event (Arch. event IDs will be negative)
|
||||
if(id < 0)
|
||||
{
|
||||
if (!archEventIDLabels.TryGetValue(id, out string archIdLabel))
|
||||
{
|
||||
return "Unknown event ID";
|
||||
}
|
||||
|
||||
return archIdLabel;
|
||||
}
|
||||
|
||||
byte module = (byte)(encodedFileID >> 8);
|
||||
if (!eventIDLabels.TryGetValue(module, out var idLabels))
|
||||
{
|
||||
return "Unknown event ID";
|
||||
}
|
||||
|
||||
if (id >= idLabels.Count)
|
||||
{
|
||||
return "Unknown event ID";
|
||||
}
|
||||
|
||||
return idLabels[id];
|
||||
}
|
||||
|
||||
public GlobalIPerlEvent(sbyte id, byte[] data, UInt16 fileID, UInt16 lineNumber)
|
||||
{
|
||||
_id = id;
|
||||
_data = data;
|
||||
_fileID = fileID;
|
||||
_lineNumber = lineNumber;
|
||||
|
||||
Name = "Unknown";
|
||||
Description = string.Empty;
|
||||
File = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
File = GetFileLabel(_fileID);
|
||||
Name = GetEventIDLabel(_fileID, _id);
|
||||
|
||||
switch (Name)
|
||||
{
|
||||
case ("ApplicationEvent_SelfTestCompleted"):
|
||||
{
|
||||
Description = "Line number: " + (_lineNumber.ToString());
|
||||
Description += Environment.NewLine + "Tests executed: " + (_data.Read<UInt32>((0 * 8) + 0, 32).ToString()) +
|
||||
Environment.NewLine + "Tests failed: " + (_data.Read<UInt32>((4 * 8) + 0, 32).ToString());
|
||||
}
|
||||
break;
|
||||
case ("SterlingEvent_FieldNegativeOrZero"):
|
||||
{
|
||||
Description = "Line number: " + (_lineNumber.ToString());
|
||||
Description += Environment.NewLine + "Field per drive time (micro-Gauss): " + (_data.Read<Int32>(0, 32).ToString()); // signed 4 bytes of uG data
|
||||
}
|
||||
break;
|
||||
case ("SterlingEvent_DrvInit"):
|
||||
case ("SterlingEvent_DrvReset"):
|
||||
case ("SterlingEvent_DrvResetFailure"):
|
||||
case ("SterlingEvent_DrvSampleError"):
|
||||
case ("SterlingEvent_DrvFifoOverrun"):
|
||||
case ("SterlingEvent_HWError"):
|
||||
case ("SterlingEvent_AsicError"):
|
||||
case ("SterlingEvent_MetrologyDebug"):
|
||||
{
|
||||
if ((_data.Length == 0))
|
||||
{
|
||||
Description = "Line number: " + (_lineNumber.ToString());
|
||||
break;
|
||||
}
|
||||
|
||||
// Sterling driver event data:
|
||||
// bytes[0:3] - ErrorCode (of type SterlingDriverError)
|
||||
// bytes[4:7] - ErrorLine (specific to sterling driver that uses this error struct)
|
||||
// bytes[8:11] - Context data (if any)
|
||||
|
||||
Description = "Line number: " + (_data.Read<Int32>((4 * 8) + 0, 32).ToString());
|
||||
sbyte errorCode = (sbyte)_data.Read<Int32>((0 * 8) + 0, 32);
|
||||
if (!sterlingDriverErrorLabels.TryGetValue(errorCode, out string ErrorName))
|
||||
{
|
||||
ErrorName = "unknown error";
|
||||
}
|
||||
Description += Environment.NewLine + "Event context: " + ErrorName + ". Code: " + errorCode.ToString();
|
||||
|
||||
UInt32 additionalData = _data.Read<UInt32>((8 * 8) + 0, 32);
|
||||
if (additionalData != UInt32.MaxValue)
|
||||
{
|
||||
Description += Environment.NewLine + "Context data: " + additionalData.ToString();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Description = "Line number: " + (_lineNumber.ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
File = "Parsing Error (" + (SByte)fileID + ")";
|
||||
Name = "Parsing Error (" + (SByte)id + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String Name
|
||||
{
|
||||
private set;
|
||||
get;
|
||||
}
|
||||
|
||||
public String File
|
||||
{
|
||||
private set;
|
||||
get;
|
||||
}
|
||||
|
||||
public String Description
|
||||
{
|
||||
private set;
|
||||
get;
|
||||
}
|
||||
|
||||
sbyte _id;
|
||||
byte[] _data;
|
||||
UInt16 _fileID;
|
||||
UInt16 _lineNumber;
|
||||
}
|
||||
@ -17,6 +17,7 @@ using Sensus.Protocols.FlexNet.FNv2;
|
||||
using Sensus.Protocols.FlexNet.FNv2.NA2WParameters;
|
||||
using Sensus.Protocols.FlexNet.Serial;
|
||||
using Sensus.Protocols.FlexNet.Serial.FNv2;
|
||||
using Conversion = NfcC7_DLL.NfcHanler.Utils.Conversion;
|
||||
using Log = NfcC7_DLL.NfcHanler.Utils.Log;
|
||||
using MeterSize = NfcC7_DLL.NfcHanler.FieldLogicStaging.SterlingMetrologyTags.MeterSize;
|
||||
using NA2WProductType = NfcC7_DLL.NfcHanler.FieldLogicStaging.NA2WProductType;
|
||||
@ -538,7 +539,7 @@ namespace NfcC7_DLL.NfcHanler
|
||||
{
|
||||
TemperatureCalibration tempCal =
|
||||
new TemperatureCalibration();
|
||||
tempCal.TemperatureCal = calibration;
|
||||
//tempCal.TemperatureCal = calibration;
|
||||
na2wParamList.Add(tempCal);
|
||||
|
||||
// Update corrected temperature
|
||||
@ -1724,7 +1725,7 @@ namespace NfcC7_DLL.NfcHanler
|
||||
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);
|
||||
//windowViewModel.StatsParseText = GlobalIPerlStatistics.Parse((ModuleId)moduleId, revision, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1999,7 +2000,7 @@ namespace NfcC7_DLL.NfcHanler
|
||||
{
|
||||
// Send Factory Sleep Open command
|
||||
FactoryTestOpen factoryTestOpen = new FactoryTestOpen();
|
||||
factoryTestOpen.SleepTime = GlobalIPerlUtility.Properties.Settings.Default.SleepTime;
|
||||
factoryTestOpen.SleepTime = 0x10;
|
||||
|
||||
SendNa2wSerial(factoryTestOpen, ParameterReadResponse._Code);
|
||||
}
|
||||
@ -3308,7 +3309,7 @@ namespace NfcC7_DLL.NfcHanler
|
||||
manufacturerIdAscii[2] = (byte)(((manufacturerIdRaw) & 0x001F) + 64);
|
||||
|
||||
byte version = payload[block1Offset + 8];
|
||||
Utility.WMBusDeviceType deviceType = (Utility.WMBusDeviceType)(payload[block1Offset + 9]);
|
||||
WMBusDeviceType deviceType = (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);
|
||||
@ -3370,11 +3371,11 @@ namespace NfcC7_DLL.NfcHanler
|
||||
eventNotification.TimeStamp = DateTime.Now.ToLongTimeString(); // String.Format("{0}", timeStamp);
|
||||
eventNotification.Data = eventData.ToHexString();
|
||||
|
||||
GlobalIPerlEvent iPerlEvent = new GlobalIPerlEvent(idNum, eventData, fileIdNum, lineNum);
|
||||
/*GlobalIPerlEvent iPerlEvent = new GlobalIPerlEvent(idNum, eventData, fileIdNum, lineNum);
|
||||
eventNotification.Id = iPerlEvent.Name;
|
||||
eventNotification.File = iPerlEvent.File;
|
||||
eventNotification.Line = fileIdNum.ToString();
|
||||
eventNotification.Description = iPerlEvent.Description;
|
||||
eventNotification.Description = iPerlEvent.Description;*/
|
||||
|
||||
windowViewModel.Add(eventNotification);
|
||||
}
|
||||
@ -3749,7 +3750,7 @@ namespace NfcC7_DLL.NfcHanler
|
||||
|
||||
public void SaveDefaultConfigurationValues()
|
||||
{
|
||||
GlobalIPerlUtility.Properties.Settings.Default.Configuration_DeviceId = windowViewModel.DeviceIdNew;
|
||||
/* GlobalIPerlUtility.Properties.Settings.Default.Configuration_DeviceId = windowViewModel.DeviceIdNew;
|
||||
GlobalIPerlUtility.Properties.Settings.Default.Configuration_SerialNumber = windowViewModel.SerialNumberNew;
|
||||
GlobalIPerlUtility.Properties.Settings.Default.Configuration_ManufacturingNote = windowViewModel.ManufacturingNoteNew;
|
||||
|
||||
@ -3763,11 +3764,11 @@ namespace NfcC7_DLL.NfcHanler
|
||||
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.DeviceIdNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_DeviceId;
|
||||
windowViewModel.SerialNumberNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_SerialNumber;
|
||||
windowViewModel.ManufacturingNoteNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_ManufacturingNote;
|
||||
|
||||
@ -3781,11 +3782,11 @@ namespace NfcC7_DLL.NfcHanler
|
||||
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_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;
|
||||
@ -3798,11 +3799,11 @@ namespace NfcC7_DLL.NfcHanler
|
||||
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_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;
|
||||
@ -3815,7 +3816,7 @@ namespace NfcC7_DLL.NfcHanler
|
||||
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)
|
||||
{
|
||||
|
||||
@ -25,7 +25,7 @@ using Log = NfcC7_DLL.NfcHanler.Utils.Log;
|
||||
|
||||
namespace GlobalIPerlUtility
|
||||
{
|
||||
class MeterTestHatLink : ISerialConnection, IDisposable
|
||||
public class MeterTestHatLink : ISerialConnection, IDisposable
|
||||
{
|
||||
private SerialManager serialManager = null;
|
||||
private UInt16 sessionId = 0;
|
||||
|
||||
76
NfcC7_DLL/NfcHanler/ModuleId.cs
Normal file
76
NfcC7_DLL/NfcHanler/ModuleId.cs
Normal file
@ -0,0 +1,76 @@
|
||||
namespace NfcC7_DLL.NfcHanler;
|
||||
|
||||
public enum ModuleId
|
||||
{
|
||||
Statistics = 0,
|
||||
FlexNetTransmitter = 1,
|
||||
FlexNetReceiver = 2,
|
||||
FlexNetCommandProcess = 3,
|
||||
WbDbProcess = 4,
|
||||
Scheduler = 5,
|
||||
Si446xRadio = 6,
|
||||
SensusRfTransmitter = 7,
|
||||
SensusRfReceiver = 8,
|
||||
MomComProcess = 9,
|
||||
TfwChannel = 10,
|
||||
SensusRfProcess = 11,
|
||||
TfxHost = 12,
|
||||
System = 13,
|
||||
Board = 14,
|
||||
UpgradeProcess = 15,
|
||||
Sensor = 16,
|
||||
Ads1220 = 17,
|
||||
BatChan = 18,
|
||||
Eeprom = 19,
|
||||
Flash = 20,
|
||||
MeChan = 21,
|
||||
ReChan = 22,
|
||||
DailyTimeSync = 23,
|
||||
CpDriver = 24,
|
||||
NvProcess = 25,
|
||||
WaterStack = 26,
|
||||
GasStack = 27,
|
||||
WaterChannel = 28,
|
||||
GasChannel = 29,
|
||||
RectifierMonitorStack = 30,
|
||||
AskDriver = 31,
|
||||
UnlicensedFlexnet = 32,
|
||||
Application = 33,
|
||||
FlexNetV1Parser = 34,
|
||||
SensusRfEndpoint = 35,
|
||||
SensusRfMetrology = 36,
|
||||
FlexNetV1Upgrade = 37,
|
||||
FlexNetSerialUpgrade = 38,
|
||||
UpgradeProcessFlexNetV1 = 39,
|
||||
UpgradeProcessSerial = 40,
|
||||
UpgradeImage = 41,
|
||||
UpgradeFlasher = 42,
|
||||
GasRegister = 43,
|
||||
NfcTag = 44,
|
||||
IrdaAdapter = 45,
|
||||
Ui1236Slave = 46,
|
||||
Na2wIrdaRegister = 47,
|
||||
Na2wIrdaStack = 48,
|
||||
Valve = 49,
|
||||
SensusRfLink = 50,
|
||||
Bq25713Driver = 51,
|
||||
Bt121Driver = 52,
|
||||
CommunicationDevice = 53,
|
||||
WMBusStack = 54,
|
||||
CriticalRead = 55,
|
||||
FnUdp = 56,
|
||||
WiredCommsStack = 57,
|
||||
RawMetrologyChannel = 58,
|
||||
WaterStackAgnostic = 59,
|
||||
St25DvxxDriver = 60,
|
||||
FskRailDriver = 61,
|
||||
WaterStackEncoder = 62,
|
||||
FbProcess = 63,
|
||||
WMBusTracker = 64,
|
||||
}
|
||||
|
||||
public enum ModuleID
|
||||
{
|
||||
ModuleID_Application = 33,
|
||||
ModuleID_Sterling = 71,
|
||||
}
|
||||
62
NfcC7_DLL/NfcHanler/ReadMe.md
Normal file
62
NfcC7_DLL/NfcHanler/ReadMe.md
Normal file
@ -0,0 +1,62 @@
|
||||
# Program tbfDBBackup
|
||||
Program is designed to backup, upgrade, compare and restore database.
|
||||
Only for advanced users!
|
||||
* Program is written in C# and .NET 8.0.
|
||||
* Program is using MySql.Data.MySqlClient.
|
||||
* Program using mysqldump.exe in some cases.
|
||||
* Program is designed for Windows.
|
||||
* Program is designed to use with MySQL.
|
||||
|
||||
## Program features
|
||||
* Backup database.
|
||||
* Upgrade database.
|
||||
* Compare database.
|
||||
* Restore database.
|
||||
|
||||
|
||||
### Backup database.
|
||||
We can use this program to define a backup procedure. Can work like a cron job, or services to run backup procedure.
|
||||
|
||||
### Upgrade database.
|
||||
We can use this program to define an upgrade procedure. Can work cyclic or one time per run.
|
||||
|
||||
# Description about program parameters
|
||||
|
||||
The program operates as a command-line driver, accepting parameters to control its behavior.
|
||||
|
||||
## Configuration
|
||||
When using a configuration file, the program can function autonomously, execute a single-use procedure, or encapsulate the operation as an opaque process.
|
||||
|
||||
## Dirrect commnad-line
|
||||
|
||||
### List of cmd commands
|
||||
|
||||
|
||||
## Cmd Help
|
||||
|
||||
### Connect to database via cmd
|
||||
|
||||
```aiignore
|
||||
mysql -h 127.0.0.1 -P 3306 -u root
|
||||
```
|
||||
Under database, we can create our own schema or use standard SQL syntax. For example:
|
||||
```aiignore
|
||||
"CREATE DATABASE slm-end;"
|
||||
```
|
||||
|
||||
### Reload dump to new schema
|
||||
```aiignore
|
||||
PS C:\xampp\mysql\bin> Get-Content "C:\Users\micha\git\sensus\tbfDBBackup\tbfDBBackup\bin\Debug\net8.0\old.sql" |
|
||||
>> .\mysql.exe -h 127.0.0.1 -P 3306 -u root --one-database slm-end
|
||||
```
|
||||
```aiignore
|
||||
PS C:\xampp\mysql\bin> Get-Content "C:\Users\micha\git\sensus\tbfDBBackup\tbfDBBackup\bin\Debug\net8.0\old-r.sql" |
|
||||
>> .\mysql.exe -h 127.0.0.1 -P 3306 -u root --one-database slm-end-r
|
||||
```
|
||||
|
||||
##Release Examples
|
||||
|
||||
###Transitions tables to update
|
||||
```aiignore
|
||||
PS tbfDBBackup_Release> .\tbfDBBackup.exe update-by-schema slm50-250709-1549.sql schema-mapping-transition.json
|
||||
```
|
||||
810
NfcC7_DLL/NfcHanler/SerialFirmwareDownloadTask.cs
Normal file
810
NfcC7_DLL/NfcHanler/SerialFirmwareDownloadTask.cs
Normal file
@ -0,0 +1,810 @@
|
||||
using System.Diagnostics;
|
||||
using NfcC7_DLL.NfcHanler.FieldLogicStaging;
|
||||
using Sensus;
|
||||
using Sensus.Protocols.FlexNet;
|
||||
using Sensus.Protocols.FlexNet.FNv2;
|
||||
using Sensus.Protocols.FlexNet.Serial;
|
||||
using Sensus.Protocols.FlexNet.Serial.FNv2;
|
||||
using NA2WProductType = Sensus.Protocols.FlexNet.NA2WProductType;
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler
|
||||
{
|
||||
public delegate void TaskCompletionCallbackDelegate(Object task, bool successfullyCompleted);
|
||||
public delegate void TaskProgressCallbackDelegate(Object task, Double percentDone, String statusString);
|
||||
public delegate void TaskLogCallbackDelegate(Object task, EventNotification eventNotification);
|
||||
|
||||
class SerialFirmwareDownloadTask
|
||||
{
|
||||
private String fwFileName;
|
||||
private Utils.FirmwareImage fwImage;
|
||||
private MessageEngine messageEngine;
|
||||
|
||||
private TaskCompletionCallbackDelegate taskCompletionCallback;
|
||||
private TaskProgressCallbackDelegate taskProgessCallback;
|
||||
private ushort blocksPerCommand = 1;
|
||||
|
||||
private bool haltExecution;
|
||||
|
||||
private System.Threading.Timer timer;
|
||||
private UInt16 currentBlock;
|
||||
|
||||
private UInt16 currentMissingBlock;
|
||||
private UInt16[] missingBlock;
|
||||
|
||||
private UInt16 interBlockDelayMs = 300;
|
||||
private UInt16 checkImageTimeOutMs = 15000;
|
||||
private UInt16 loadStartTimeOutMs = 30000;
|
||||
private UInt16 flashDeviceTimeOutMs = 15000;
|
||||
|
||||
public TaskProgressCallbackDelegate TaskProgressCallback
|
||||
{
|
||||
set
|
||||
{
|
||||
taskProgessCallback = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private enum AlgorithmState
|
||||
{
|
||||
IDLE,
|
||||
BEGIN,
|
||||
LOAD_START,
|
||||
BLOCKS,
|
||||
CHECK_IMAGE,
|
||||
MISSING_BLOCKS,
|
||||
FLASH,
|
||||
CANCEL,
|
||||
RESET
|
||||
};
|
||||
|
||||
public bool AckLoadBlock { get; set; }
|
||||
|
||||
AlgorithmState timerState = AlgorithmState.IDLE;
|
||||
bool waitingForAck = false;
|
||||
UInt16 sessionId = 0;
|
||||
Stopwatch stopwatch;
|
||||
|
||||
public SerialFirmwareDownloadTask(String fwFileName, MessageEngine messageEngine, ushort blocksPerCommand)
|
||||
{
|
||||
this.fwFileName = fwFileName;
|
||||
this.fwImage = new Utils.FirmwareImage(fwFileName);
|
||||
this.messageEngine = messageEngine;
|
||||
this.blocksPerCommand = blocksPerCommand;
|
||||
|
||||
AckLoadBlock = true;
|
||||
|
||||
taskProgessCallback = null;
|
||||
|
||||
timer = new System.Threading.Timer(TimerCb, null, Timeout.Infinite, Timeout.Infinite);
|
||||
}
|
||||
|
||||
public SerialFirmwareDownloadTask(String fwFileName, MessageEngine messageEngine) : this(fwFileName, messageEngine, 1)
|
||||
{
|
||||
}
|
||||
|
||||
public bool Start(TaskCompletionCallbackDelegate taskCompletionCallback)
|
||||
{
|
||||
bool retValue = false;
|
||||
|
||||
this.taskCompletionCallback = taskCompletionCallback;
|
||||
|
||||
if (messageEngine != null)
|
||||
{
|
||||
// Write to log upgrade details
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Performing Firmware Upgrade to:" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Filename\t\t= " + fwFileName + System.Environment.NewLine);
|
||||
DeviceType devType = (DeviceType)fwImage.DeviceType;
|
||||
Utility.Log.Write("# Device Type\t\t= " + fwImage.DeviceType.ToString() + " - " + devType.ToString() + System.Environment.NewLine);
|
||||
if (fwImage.Version != null)
|
||||
{
|
||||
Utility.Log.Write("# FW Version\t\t= " + fwImage.Version.ToString() + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Compatability\t= " + fwImage.Compatibility.ToString() + System.Environment.NewLine);
|
||||
NA2WProductType prodType = (NA2WProductType)fwImage.Compatibility;
|
||||
Utility.Log.Write("# Product Type\t= " + fwImage.Compatibility + " - " + prodType.ToString() + System.Environment.NewLine);
|
||||
}
|
||||
Utility.Log.Write("# File CRC\t\t= " + fwImage.CRC.ToString() + " (" + fwImage.CRC.ToString("X8") + ")" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# File Size\t\t= " + fwImage.ImageSize.ToString() + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Num Blocks\t\t= " + fwImage.BlockCount.ToString() + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
|
||||
timerState = AlgorithmState.BEGIN;
|
||||
timer.Change(500, Timeout.Infinite);
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, "Starting upgrade...");
|
||||
}
|
||||
|
||||
if (DeviceType.SLCLightController == devType)
|
||||
{
|
||||
interBlockDelayMs = 150;
|
||||
}
|
||||
|
||||
stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
retValue = true;
|
||||
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
// TODO:
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
// TODO:
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
// Send a Cancel
|
||||
timerState = AlgorithmState.RESET; // AlgorithmState.CANCEL;
|
||||
|
||||
// Signal to halt execution
|
||||
//haltExecution = true;
|
||||
|
||||
// Signal completion but not successful
|
||||
//FirmwareDownloadComplete(false);
|
||||
}
|
||||
|
||||
private void TimerCb(object state)
|
||||
{
|
||||
if (haltExecution)
|
||||
{
|
||||
timerState = AlgorithmState.IDLE;
|
||||
}
|
||||
if (AlgorithmState.BEGIN == timerState)
|
||||
{
|
||||
SendLoadStartCmd();
|
||||
}
|
||||
else if (AlgorithmState.BLOCKS == timerState)
|
||||
{
|
||||
if (fwImage.BlockCount > currentBlock)
|
||||
{
|
||||
ISerialCommand blockLoadCommand;
|
||||
// Send next block
|
||||
if (blocksPerCommand <= 1)
|
||||
{
|
||||
blockLoadCommand = CreateLoadBlockCmd(currentBlock);
|
||||
|
||||
currentBlock++;
|
||||
}
|
||||
else
|
||||
{
|
||||
blockLoadCommand = CreateLoadBlockCmd(currentBlock, blocksPerCommand);
|
||||
|
||||
currentBlock += blocksPerCommand;
|
||||
}
|
||||
|
||||
// Make sure currentBlock is not greater than block count
|
||||
if (currentBlock > fwImage.BlockCount)
|
||||
{
|
||||
currentBlock = fwImage.BlockCount;
|
||||
}
|
||||
|
||||
// Update task bar
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
Double percent = ((Double)currentBlock) * 100 / fwImage.BlockCount;
|
||||
|
||||
String statusString = "" + (currentBlock) + "/" + (fwImage.BlockCount - currentBlock);
|
||||
|
||||
taskProgessCallback(this, percent, statusString);
|
||||
}
|
||||
|
||||
waitingForAck = true;
|
||||
timer.Change(
|
||||
(blocksPerCommand <= 1 ? interBlockDelayMs : 3 * interBlockDelayMs),
|
||||
Timeout.Infinite
|
||||
);
|
||||
|
||||
// Send message request
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(blockLoadCommand, true, (uint)(blocksPerCommand <= 1 ? interBlockDelayMs : 3 * interBlockDelayMs));
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timerState = AlgorithmState.CHECK_IMAGE;
|
||||
timer.Change(checkImageTimeOutMs, Timeout.Infinite);
|
||||
|
||||
SendCheckImageCommand();
|
||||
}
|
||||
}
|
||||
else if (AlgorithmState.CHECK_IMAGE == timerState)
|
||||
{
|
||||
timerState = AlgorithmState.CHECK_IMAGE;
|
||||
timer.Change(checkImageTimeOutMs, Timeout.Infinite);
|
||||
|
||||
SendCheckImageCommand();
|
||||
}
|
||||
else if (AlgorithmState.MISSING_BLOCKS == timerState)
|
||||
{
|
||||
if (currentMissingBlock < missingBlock.Length)
|
||||
{
|
||||
// Send next block
|
||||
ISerialCommand blockLoadCommand = CreateLoadBlockCmd(missingBlock[currentMissingBlock]);
|
||||
|
||||
// Send message request
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(blockLoadCommand, true);
|
||||
|
||||
// Update task bar
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 100, "Block Load backfill");
|
||||
}
|
||||
|
||||
// Update state
|
||||
currentMissingBlock++;
|
||||
|
||||
timer.Change(interBlockDelayMs, Timeout.Infinite);
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timerState = AlgorithmState.CHECK_IMAGE;
|
||||
timer.Change(checkImageTimeOutMs, Timeout.Infinite);
|
||||
|
||||
SendCheckImageCommand();
|
||||
}
|
||||
}
|
||||
else if (AlgorithmState.CANCEL == timerState)
|
||||
{
|
||||
timerState = AlgorithmState.IDLE;
|
||||
timer.Change(500, Timeout.Infinite);
|
||||
|
||||
SendCancelCmd();
|
||||
}
|
||||
else if (AlgorithmState.RESET == timerState)
|
||||
{
|
||||
timerState = AlgorithmState.IDLE;
|
||||
timer.Change(500, Timeout.Infinite);
|
||||
|
||||
SendResetCmd();
|
||||
}
|
||||
else
|
||||
{
|
||||
Utility.Log.Write("Timeout Occurred During Upgrade." + System.Environment.NewLine);
|
||||
|
||||
// Signal to halt execution
|
||||
haltExecution = true;
|
||||
|
||||
// Signal completion but not successful
|
||||
FirmwareDownloadComplete(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void FirmwareDownloadComplete(bool successful)
|
||||
{
|
||||
timerState = AlgorithmState.IDLE;
|
||||
timer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
// Get the elapsed time as a TimeSpan value.
|
||||
TimeSpan ts = stopwatch.Elapsed;
|
||||
|
||||
// Format and display the TimeSpan value.
|
||||
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
|
||||
ts.Hours, ts.Minutes, ts.Seconds,
|
||||
ts.Milliseconds / 10);
|
||||
|
||||
|
||||
if (haltExecution || !successful)
|
||||
{
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Aborting Firmware Upgrade." + System.Environment.NewLine);
|
||||
}
|
||||
else if (successful)
|
||||
{
|
||||
Utility.Log.Write("");
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Upgrade Completed Successfully." + System.Environment.NewLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
Utility.Log.Write("");
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Upgrade Completed Failed." + System.Environment.NewLine);
|
||||
}
|
||||
|
||||
|
||||
Utility.Log.Write("# " + elapsedTime + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
|
||||
if (taskCompletionCallback != null)
|
||||
{
|
||||
taskCompletionCallback(this, successful);
|
||||
}
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, "");
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessReply(ClassicSerialMessageFrame message)
|
||||
{
|
||||
// Is this an Ack/Nck
|
||||
if ((0x01 == message.MessageAddress) && (0x01 == message.PayloadLength))
|
||||
{
|
||||
byte commandCode = message.CommandCode;
|
||||
|
||||
// Is this an Ack
|
||||
if (0x00 == (message.Payload[0] & 0x80))
|
||||
{
|
||||
// Message ACKed. React based on command type.
|
||||
switch (commandCode)
|
||||
{
|
||||
case (0xb8):
|
||||
{
|
||||
if (AlgorithmState.LOAD_START == timerState)
|
||||
{
|
||||
// Load Start ACKed. Start sending blocks.
|
||||
currentBlock = 0;
|
||||
timerState = AlgorithmState.BLOCKS;
|
||||
timer.Change(interBlockDelayMs, Timeout.Infinite);
|
||||
}
|
||||
else if (AlgorithmState.FLASH == timerState)
|
||||
{
|
||||
// Flash ACKed. We are done.
|
||||
FirmwareDownloadComplete(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case (0xb9):
|
||||
{
|
||||
if (AlgorithmState.BLOCKS == timerState)
|
||||
{
|
||||
if (waitingForAck)
|
||||
{
|
||||
waitingForAck = false;
|
||||
|
||||
// Force next load block to be sent
|
||||
timer.Change(0, Timeout.Infinite);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Message NACKed. React based on command type.
|
||||
switch (commandCode)
|
||||
{
|
||||
case (0xb8):
|
||||
{
|
||||
if (timerState == AlgorithmState.LOAD_START)
|
||||
{
|
||||
// Load Start NACKed. Cancel.
|
||||
FirmwareDownloadComplete(false);
|
||||
}
|
||||
else if (AlgorithmState.FLASH == timerState)
|
||||
{
|
||||
// Flash NACKed. Cancel.
|
||||
FirmwareDownloadComplete(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((0x01 == message.MessageAddress) && (0xb8 == message.CommandCode) && (0x02 == message.Payload[0]))
|
||||
{
|
||||
// Check image reponse. Subcommand in serial response field.
|
||||
if (0x01 == message.PayloadLength)
|
||||
{
|
||||
// This is an ACK to the check image command. Assume ready to FLASH
|
||||
timerState = AlgorithmState.FLASH;
|
||||
timer.Change(flashDeviceTimeOutMs, Timeout.Infinite);
|
||||
|
||||
SendFlashImageCmd();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check Image response
|
||||
byte numberOfRecords = message.Payload[1];
|
||||
UInt16 firstMissingBlock = (UInt16)(message.Payload[2] + (message.Payload[3] << 8));
|
||||
|
||||
if (0 == numberOfRecords)
|
||||
{
|
||||
timerState = AlgorithmState.FLASH;
|
||||
timer.Change(flashDeviceTimeOutMs, Timeout.Infinite);
|
||||
|
||||
SendFlashImageCmd();
|
||||
}
|
||||
else if ((1 == numberOfRecords) && (0xffff == firstMissingBlock))
|
||||
{
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# CRC Mismatch. Download corrupted." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
|
||||
FirmwareDownloadComplete(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
missingBlock = new UInt16[numberOfRecords];
|
||||
for (int i = 0; i < numberOfRecords; i++)
|
||||
{
|
||||
UInt16 block = (UInt16)(message.Payload[2 + 2 * i] + (message.Payload[3 + 2 * i] << 8));
|
||||
missingBlock[i] = block;
|
||||
|
||||
}
|
||||
currentMissingBlock = 0;
|
||||
|
||||
timerState = AlgorithmState.MISSING_BLOCKS;
|
||||
timer.Change(interBlockDelayMs, Timeout.Infinite);
|
||||
}
|
||||
}
|
||||
} // else if ((0x01 == frame.MessageAddress) && (0xb8 == frame.CommandCode) && (0x00 == frame.Payload[0]) && (0x02 == frame.Payload[1]))
|
||||
else if ((0x01 == message.MessageAddress) && (0xb8 == message.CommandCode) && (0x16 == message.Payload.Length))
|
||||
{
|
||||
// Check image reponse with incorrect format from legacy products. No subcommand. Length is fixed to 0x16 bytes. Status
|
||||
// in first byte. Rest of check image response (number of blocks) starts at second byte.
|
||||
byte numberOfRecords = message.Payload[1];
|
||||
UInt16 firstMissingBlock = (UInt16)(message.Payload[2] + (message.Payload[3] << 8));
|
||||
|
||||
if (0 == numberOfRecords)
|
||||
{
|
||||
timerState = AlgorithmState.FLASH;
|
||||
timer.Change(flashDeviceTimeOutMs, Timeout.Infinite);
|
||||
|
||||
SendFlashImageCmd();
|
||||
}
|
||||
else if ((1 == numberOfRecords) && (0xffff == firstMissingBlock))
|
||||
{
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# CRC Mismatch. Download corrupted." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
|
||||
FirmwareDownloadComplete(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
missingBlock = new UInt16[numberOfRecords];
|
||||
for (int i = 0; i < numberOfRecords; i++)
|
||||
{
|
||||
UInt16 block = (UInt16)(message.Payload[2 + 2 * i] + (message.Payload[3 + 2 * i] << 8));
|
||||
missingBlock[i] = block;
|
||||
|
||||
}
|
||||
currentMissingBlock = 0;
|
||||
|
||||
timerState = AlgorithmState.MISSING_BLOCKS;
|
||||
timer.Change(interBlockDelayMs, Timeout.Infinite);
|
||||
}
|
||||
} // else if ((0x01 == frame.MessageAddress) && (0xb8 == frame.CommandCode) && (0x00 == frame.Payload[0]) && (0x02 == frame.Payload[1]))
|
||||
else if ((0x01 == message.MessageAddress) && (0xb8 == message.CommandCode) && (0x00 == message.Payload[0]) && (0x02 == message.Payload[1]))
|
||||
{
|
||||
// Check image reponse with incorrect format that was in early versions of Omni ER+ and Sonix IQ. Subcommand in byte after serial
|
||||
// response field. Subcommand should be in serial response field.
|
||||
if (0x02 == message.PayloadLength)
|
||||
{
|
||||
// This is an ACK to the check image command. Assume ready to FLASH
|
||||
timerState = AlgorithmState.FLASH;
|
||||
timer.Change(flashDeviceTimeOutMs, Timeout.Infinite);
|
||||
|
||||
SendFlashImageCmd();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check Image response
|
||||
byte numberOfRecords = message.Payload[2];
|
||||
UInt16 firstMissingBlock = (UInt16)(message.Payload[3] + (message.Payload[4] << 8));
|
||||
|
||||
if (0 == numberOfRecords)
|
||||
{
|
||||
timerState = AlgorithmState.FLASH;
|
||||
timer.Change(flashDeviceTimeOutMs, Timeout.Infinite);
|
||||
|
||||
SendFlashImageCmd();
|
||||
}
|
||||
else if ((1 == numberOfRecords) && (0xffff == firstMissingBlock))
|
||||
{
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# CRC Mismatch. Download corrupted." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
|
||||
FirmwareDownloadComplete(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
missingBlock = new UInt16[numberOfRecords];
|
||||
for (int i = 0; i < numberOfRecords; i++)
|
||||
{
|
||||
UInt16 block = (UInt16)(message.Payload[3 + 2 * i] + (message.Payload[4 + 2 * i] << 8));
|
||||
missingBlock[i] = block;
|
||||
|
||||
}
|
||||
currentMissingBlock = 0;
|
||||
|
||||
timerState = AlgorithmState.MISSING_BLOCKS;
|
||||
timer.Change(interBlockDelayMs, Timeout.Infinite);
|
||||
}
|
||||
}
|
||||
} // else if ((0x01 == frame.MessageAddress) && (0xb8 == frame.CommandCode) && (0x00 == frame.Payload[0]) && (0x02 == frame.Payload[1]))
|
||||
else if ((0x01 == message.MessageAddress) && (0xb8 == message.CommandCode) && (0x00 == message.Payload[0]) && (0x03 == message.Payload.Length))
|
||||
{
|
||||
// Load Flash ACK with time to flash value. Time value in Payload[1] and Payload[2]. For example: 1B 01 B8 03 00 19 00 F0 28
|
||||
if (AlgorithmState.FLASH == timerState)
|
||||
{
|
||||
// Flash ACKed. We are done.
|
||||
FirmwareDownloadComplete(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessReply(NA2WSerialFrame message)
|
||||
{
|
||||
if (message.Payload is NetworkResponse)
|
||||
{
|
||||
NetworkResponse networkResponse = (NetworkResponse)message.Payload;
|
||||
|
||||
if (networkResponse.Payload is CommandErrorResponse)
|
||||
{
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Error." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
|
||||
FirmwareDownloadComplete(false);
|
||||
}
|
||||
else if (networkResponse.Payload is FwMaintenanceResponse_MissingBlocks)
|
||||
{
|
||||
// Utility.Log.Write("Missing " + System.Environment.NewLine);
|
||||
|
||||
FwMaintenanceResponse_MissingBlocks missingBlocksRsp = (FwMaintenanceResponse_MissingBlocks)networkResponse.Payload;
|
||||
|
||||
// Check Image response
|
||||
byte blockCount = missingBlocksRsp.BlockCount;
|
||||
|
||||
if (0 == blockCount)
|
||||
{
|
||||
timerState = AlgorithmState.FLASH;
|
||||
timer.Change(flashDeviceTimeOutMs, Timeout.Infinite);
|
||||
|
||||
SendFlashImageCmd();
|
||||
}
|
||||
else if ((1 == blockCount) && (0xffff == missingBlocksRsp.Block[0]))
|
||||
{
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# CRC Mismatch. Download corrupted." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
|
||||
FirmwareDownloadComplete(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
missingBlock = new UInt16[blockCount];
|
||||
for (int i = 0; i < blockCount; i++)
|
||||
{
|
||||
missingBlock[i] = missingBlocksRsp.Block[i];
|
||||
}
|
||||
currentMissingBlock = 0;
|
||||
|
||||
timerState = (AlgorithmState.LOAD_START == timerState ? AlgorithmState.BLOCKS : AlgorithmState.MISSING_BLOCKS);
|
||||
timer.Change(interBlockDelayMs, Timeout.Infinite);
|
||||
}
|
||||
} // else if (networkResponse.Payload is FwMaintenanceResponse_MissingBlocks)
|
||||
else if (networkResponse.Payload is FwMaintenanceResponse_Status)
|
||||
{
|
||||
// Utility.Log.Write("Status " + System.Environment.NewLine);
|
||||
|
||||
FwMaintenanceResponse_Status status = (FwMaintenanceResponse_Status)networkResponse.Payload;
|
||||
|
||||
if ( ((AlgorithmState.BLOCKS == timerState) || ((AlgorithmState.MISSING_BLOCKS == timerState))) && (status.State == 1 /* Active */))
|
||||
{
|
||||
if (waitingForAck)
|
||||
{
|
||||
waitingForAck = false;
|
||||
|
||||
// Force next load block to be sent
|
||||
timer.Change(0, Timeout.Infinite);
|
||||
}
|
||||
}
|
||||
else if ((AlgorithmState.FLASH == timerState) && (status.State == 2 /* Flashing */))
|
||||
{
|
||||
// Flash ACKed. We are done.
|
||||
FirmwareDownloadComplete(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void SendLoadStartCmd()
|
||||
{
|
||||
FwMaintenance_LoadStartV1 fwLoadStart = new FwMaintenance_LoadStartV1();
|
||||
|
||||
fwLoadStart.DeviceType = (byte)fwImage.DeviceType;
|
||||
fwLoadStart.ImageCrc = fwImage.CRC;
|
||||
fwLoadStart.ImageSize = fwImage.ImageSize;
|
||||
fwLoadStart.ProductType = fwImage.Compatibility;
|
||||
fwLoadStart.ProductTypeVersion = fwImage.Version.ToShort().ReverseByteOrder();
|
||||
|
||||
timerState = AlgorithmState.LOAD_START;
|
||||
timer.Change(loadStartTimeOutMs, Timeout.Infinite);
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, "Load Start Sent");
|
||||
}
|
||||
|
||||
// Send message request
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(fwLoadStart, true, loadStartTimeOutMs);
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
|
||||
private ISerialCommand CreateLoadBlockCmd(UInt16 blockNum)
|
||||
{
|
||||
FwMaintenance_LoadBlockV1 firmwareBlockLoad = new FwMaintenance_LoadBlockV1();
|
||||
|
||||
firmwareBlockLoad.DeviceType = (byte)fwImage.DeviceType;
|
||||
firmwareBlockLoad.ProductType = (byte)fwImage.Compatibility;
|
||||
firmwareBlockLoad.BlockSize = 19;
|
||||
int blockCount = 1;
|
||||
firmwareBlockLoad.BlockCount = (byte)blockCount;
|
||||
byte[] data = new byte[21];
|
||||
int block = 0;
|
||||
data.Write<UInt16>((UInt16)(blockNum + block), 0, 16);
|
||||
Array.Copy(fwImage.Blocks[blockNum + block].ToArray(), 0, data, 2, 19);
|
||||
firmwareBlockLoad.Payload = new Frame(data);
|
||||
|
||||
return firmwareBlockLoad;
|
||||
}
|
||||
|
||||
|
||||
private ISerialCommand CreateLoadBlockCmd(UInt16 blockNum, int blocksPerCommand)
|
||||
{
|
||||
FwMaintenance_LoadBlockV1 firmwareBlockLoad = new FwMaintenance_LoadBlockV1();
|
||||
|
||||
firmwareBlockLoad.DeviceType = (byte)fwImage.DeviceType;
|
||||
firmwareBlockLoad.ProductType = (byte)fwImage.Compatibility;
|
||||
firmwareBlockLoad.BlockSize = 19;
|
||||
// Limit blocks based on number remaining
|
||||
int blockCount = blocksPerCommand;
|
||||
if (blockCount > fwImage.BlockCount - blockNum)
|
||||
{
|
||||
blockCount = fwImage.BlockCount - blockNum;
|
||||
}
|
||||
firmwareBlockLoad.BlockCount = (byte)blockCount;
|
||||
|
||||
byte[] data = new byte[blockCount * (2 + 19)];
|
||||
// Copy blocks into payload
|
||||
int block = 0;
|
||||
for (; block < blockCount; block++)
|
||||
{
|
||||
data.Write<UInt16>((UInt16)(blockNum + block), (uint)(block * 21 * 8), 16);
|
||||
Array.Copy(fwImage.Blocks[blockNum + block].ToArray(), 0, data, (21 * block) + 2, 19);
|
||||
}
|
||||
firmwareBlockLoad.Payload = new Frame(data);
|
||||
|
||||
return firmwareBlockLoad;
|
||||
}
|
||||
|
||||
private void SendCheckImageCommand()
|
||||
{
|
||||
FwMaintenance_CheckImageV1 checkImage = new FwMaintenance_CheckImageV1();
|
||||
checkImage.DeviceType = (byte)fwImage.DeviceType;
|
||||
checkImage.ProductType = fwImage.Compatibility;
|
||||
checkImage.ImageBlocks = fwImage.BlockCount;
|
||||
checkImage.ImageCrc = fwImage.CRC;
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 100, "Check Image Sent");
|
||||
}
|
||||
|
||||
// Send message request
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(checkImage, true);
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendFlashImageCmd()
|
||||
{
|
||||
FwMaintenance_LoadFlashV1 loadFlash = new FwMaintenance_LoadFlashV1();
|
||||
|
||||
loadFlash.DeviceType = (byte)fwImage.DeviceType;
|
||||
loadFlash.ProductType = fwImage.Compatibility;
|
||||
loadFlash.ImageBlocks = fwImage.BlockCount;
|
||||
loadFlash.ImageCrc = fwImage.CRC;
|
||||
loadFlash.SegmentCount = fwImage.SegmentCount;
|
||||
|
||||
int numSegs = fwImage.SegmentCount;
|
||||
byte[] segmentDescriptorData = new byte[0];
|
||||
for (int seg = 0; seg < numSegs; seg++)
|
||||
{
|
||||
FwMaintenance_SegmentDescriptor segmentDescriptor = new FwMaintenance_SegmentDescriptor(
|
||||
(uint)(fwImage.Segments[seg].Address),
|
||||
(ushort)(fwImage.Segments[seg].BlockCount)
|
||||
);
|
||||
segmentDescriptorData = segmentDescriptorData.Concat(segmentDescriptor.ToBytes()).ToArray();
|
||||
}
|
||||
loadFlash.Payload = new Frame(segmentDescriptorData);
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 100, "Load Flash Sent");
|
||||
}
|
||||
|
||||
// Send message request
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(loadFlash, true);
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendCancelCmd()
|
||||
{
|
||||
FwMaintenance_CancelV1 cancel = new FwMaintenance_CancelV1();
|
||||
|
||||
cancel.DeviceType = (byte)fwImage.DeviceType;
|
||||
cancel.ProductType = fwImage.Compatibility;
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 100, "Cancel Sent");
|
||||
}
|
||||
|
||||
// Send message request
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(cancel, true);
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendResetCmd()
|
||||
{
|
||||
FwMaintenance_ResetV1 reset = new FwMaintenance_ResetV1();
|
||||
|
||||
reset.DeviceType = (byte)fwImage.DeviceType;
|
||||
reset.ProductType = fwImage.Compatibility;
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 100, "Reset Sent");
|
||||
}
|
||||
|
||||
// Send message request
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(reset, true);
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
71
NfcC7_DLL/NfcHanler/Session.cs
Normal file
71
NfcC7_DLL/NfcHanler/Session.cs
Normal file
@ -0,0 +1,71 @@
|
||||
namespace NfcC7_DLL.NfcHanler
|
||||
{
|
||||
|
||||
class Session
|
||||
{
|
||||
public Session()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize RF_Offsetts file
|
||||
/// </summary>
|
||||
/// <param name="filename">file to be deserialized</param>
|
||||
/// <returns>object type RF_Offsetts with information read</returns>
|
||||
public bool Load(string filename)
|
||||
{
|
||||
#if false
|
||||
try
|
||||
{
|
||||
// Create an instance of the XmlSerializer specifying type and namespace.
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(ConfigurationData));
|
||||
|
||||
// A FileStream is needed to read the XML document.
|
||||
FileStream fs = new FileStream(filename, FileMode.Open);
|
||||
XmlReader reader = XmlReader.Create(fs);
|
||||
|
||||
// Use the Deserialize method to restore the object's state.
|
||||
ConfigurationData = (ConfigurationData)serializer.Deserialize(reader);
|
||||
fs.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize RF_Offsetts object and save it to file
|
||||
/// </summary>
|
||||
/// <param name="settings">object to be serialized </param>
|
||||
/// <param name="filename">File to write data to</param>
|
||||
/// <returns>false on error</returns>
|
||||
public bool Save(string filename)
|
||||
{
|
||||
#if false
|
||||
try
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(ConfigurationData));
|
||||
|
||||
/* Create a StreamWriter to write with.
|
||||
* First create a FileStream object, and create the StreamWriter specifying an Encoding to use. */
|
||||
FileStream fs = new FileStream(filename, FileMode.Create);
|
||||
TextWriter writer = new StreamWriter(fs, new UTF8Encoding());
|
||||
|
||||
// Serialize using the XmlTextWriter.
|
||||
serializer.Serialize(writer, ConfigurationData);
|
||||
writer.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
390
NfcC7_DLL/NfcHanler/StatsLogTask.cs
Normal file
390
NfcC7_DLL/NfcHanler/StatsLogTask.cs
Normal file
@ -0,0 +1,390 @@
|
||||
using NfcC7_DLL.NfcHanler.FieldLogicStaging;
|
||||
using Sensus;
|
||||
using Sensus.Protocols.FlexNet;
|
||||
using Sensus.Protocols.FlexNet.FNv2;
|
||||
using Sensus.Protocols.FlexNet.FNv2.NA2WParameters;
|
||||
using Sensus.Protocols.FlexNet.Serial.FNv2;
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler
|
||||
{
|
||||
public delegate void StatsLogCallbackDelegate(Object task, StatisticsEntry statisticsEntry);
|
||||
|
||||
public class ModuleStatisticsDescriptor
|
||||
{
|
||||
public UInt16 ModuleId { get; set; }
|
||||
public Byte StatisticsRevision { get; set; }
|
||||
public UInt16 NumberOfBytes { get; set; }
|
||||
public byte[] Data { get; set; }
|
||||
}
|
||||
|
||||
class StatsLogTask
|
||||
{
|
||||
private MessageEngine messageEngine;
|
||||
|
||||
private TaskCompletionCallbackDelegate taskCompletionCallback;
|
||||
private TaskProgressCallbackDelegate taskProgessCallback;
|
||||
private StatsLogCallbackDelegate taskLogCallback;
|
||||
|
||||
private bool haltExecution;
|
||||
|
||||
private System.Threading.Timer timer;
|
||||
|
||||
private List<ModuleStatisticsDescriptor> moduleDescriptorList = new List<ModuleStatisticsDescriptor>();
|
||||
|
||||
public TaskProgressCallbackDelegate TaskProgressCallback
|
||||
{
|
||||
set
|
||||
{
|
||||
taskProgessCallback = value;
|
||||
}
|
||||
}
|
||||
|
||||
public StatsLogCallbackDelegate TaskLogCallback
|
||||
{
|
||||
set
|
||||
{
|
||||
taskLogCallback = value;
|
||||
}
|
||||
}
|
||||
private enum AlgorithmState
|
||||
{
|
||||
IDLE,
|
||||
READ_SERIAL_NUMBER,
|
||||
READ_OVERVIEW,
|
||||
READ_STATISTICS
|
||||
};
|
||||
|
||||
public bool AckLoadBlock { get; set; }
|
||||
|
||||
public UInt32 TimeFrame { get; set; }
|
||||
|
||||
AlgorithmState timerState = AlgorithmState.IDLE;
|
||||
|
||||
UInt16 moduleIndex = 0;
|
||||
UInt64 serialNumber = 0;
|
||||
|
||||
public StatsLogTask(MessageEngine messageEngine)
|
||||
{
|
||||
this.messageEngine = messageEngine;
|
||||
|
||||
TimeFrame = 0xffffffff;
|
||||
|
||||
taskProgessCallback = null;
|
||||
|
||||
timer = new System.Threading.Timer(TimerCb, null, Timeout.Infinite, Timeout.Infinite);
|
||||
}
|
||||
|
||||
|
||||
public bool Start(TaskCompletionCallbackDelegate taskCompletionCallback)
|
||||
{
|
||||
bool retValue = false;
|
||||
|
||||
this.taskCompletionCallback = taskCompletionCallback;
|
||||
moduleIndex = 0;
|
||||
|
||||
if (messageEngine != null)
|
||||
{
|
||||
// Write to log upgrade details
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Extracting Statistics" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, "Starting...");
|
||||
}
|
||||
|
||||
SendSessionQueryCmd();
|
||||
|
||||
timer.Change(1000, Timeout.Infinite);
|
||||
|
||||
retValue = true;
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
// Signal to halt execution
|
||||
haltExecution = true;
|
||||
|
||||
// Signal completion but not successful
|
||||
ExtractComplete(false);
|
||||
}
|
||||
private void ExtractComplete(bool successful)
|
||||
{
|
||||
timerState = AlgorithmState.IDLE;
|
||||
timer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
|
||||
if (haltExecution || !successful)
|
||||
{
|
||||
Utility.Log.Write("" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Aborting Statistics Extraction." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
}
|
||||
else if (successful)
|
||||
{
|
||||
Utility.Log.Write("");
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Statistics Extraction Completed Successfully." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
Utility.Log.Write("");
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
Utility.Log.Write("# Statistics Extraction Failed." + System.Environment.NewLine);
|
||||
Utility.Log.Write("# -----------------------------------------------------" + System.Environment.NewLine);
|
||||
}
|
||||
|
||||
if (taskCompletionCallback != null)
|
||||
{
|
||||
taskCompletionCallback(this, successful);
|
||||
}
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, moduleIndex.ToString() + " modules extracted");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void TimerCb(object state)
|
||||
{
|
||||
if (timerState == AlgorithmState.READ_SERIAL_NUMBER)
|
||||
{
|
||||
SendSessionQueryCmd();
|
||||
}
|
||||
else if (timerState == AlgorithmState.READ_OVERVIEW)
|
||||
{
|
||||
SendStatisticsOverviewCmd();
|
||||
}
|
||||
else if (timerState == AlgorithmState.READ_STATISTICS)
|
||||
{
|
||||
SendModuleStatisticsCmd();
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessReply(NA2WSerialFrame message)
|
||||
{
|
||||
UnknownResponse unknownResponse = message.Unwrap<UnknownResponse>();
|
||||
|
||||
if ((null != unknownResponse) && (unknownResponse.CommandCode == 0x14))
|
||||
{
|
||||
byte[] payload = unknownResponse.Contents;
|
||||
|
||||
byte reportId = payload.Read<byte>(0);
|
||||
|
||||
switch (reportId)
|
||||
{
|
||||
case (0): // Statistics Overview
|
||||
{
|
||||
UInt16 moduleCount = payload.Read<UInt16>(8 * 4);
|
||||
|
||||
moduleDescriptorList = new List<ModuleStatisticsDescriptor>();
|
||||
uint offset = 6;
|
||||
int payloadBytes = (int)(payload.Length - offset);
|
||||
|
||||
while (payloadBytes >= 5)
|
||||
{
|
||||
UInt16 moduleId = payload.Read<UInt16>(8 * (offset));
|
||||
Byte statisticsRevision = payload.Read<Byte>(8 * (offset + 2));
|
||||
UInt16 numberOfBytes = payload.Read<UInt16>(8 * (offset + 3));
|
||||
|
||||
ModuleStatisticsDescriptor moduleDescriptor = new ModuleStatisticsDescriptor();
|
||||
moduleDescriptor.ModuleId = moduleId;
|
||||
moduleDescriptor.StatisticsRevision = statisticsRevision;
|
||||
moduleDescriptor.NumberOfBytes = numberOfBytes;
|
||||
|
||||
moduleDescriptorList.Add(moduleDescriptor);
|
||||
|
||||
offset += 5;
|
||||
payloadBytes -= 5;
|
||||
}
|
||||
|
||||
SendModuleStatisticsCmd();
|
||||
}
|
||||
break;
|
||||
|
||||
case (1): // Module Statistics
|
||||
{
|
||||
ModuleStatisticsDescriptor moduleDescriptor = moduleDescriptorList[moduleIndex];
|
||||
byte productType = payload.Read<byte>(8 * 1);
|
||||
UInt16 moduleId = payload.Read<UInt16>(8 * 2);
|
||||
if (moduleDescriptor.ModuleId == moduleId)
|
||||
{
|
||||
byte statisticsRevistion = payload.Read<byte>(8 * 4);
|
||||
UInt16 byteOffset = payload.Read<UInt16>(8 * 5);
|
||||
UInt16 byteCount = payload.Read<UInt16>(8 * 7);
|
||||
|
||||
if (null != moduleDescriptor.Data)
|
||||
{
|
||||
if (byteOffset == moduleDescriptor.Data.Length)
|
||||
{
|
||||
byte[] data = new byte[byteOffset + byteCount];
|
||||
|
||||
Array.Copy(moduleDescriptor.Data, 0, data, 0, moduleDescriptor.Data.Length);
|
||||
Array.Copy(payload, 9, data, byteOffset, byteCount);
|
||||
|
||||
moduleDescriptor.Data = data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] data = new byte[byteCount];
|
||||
|
||||
Array.Copy(payload, 9, data, 0, byteCount);
|
||||
|
||||
moduleDescriptor.Data = data;
|
||||
}
|
||||
|
||||
if (moduleDescriptor.NumberOfBytes == moduleDescriptor.Data.Length)
|
||||
{
|
||||
StatisticsEntry statisticsEntry = new StatisticsEntry();
|
||||
statisticsEntry.Id = ((ModuleId)(moduleDescriptor.ModuleId)).ToString() + " (" + moduleDescriptor.ModuleId.ToString() + ")";
|
||||
statisticsEntry.Revision = moduleDescriptor.StatisticsRevision.ToString();
|
||||
statisticsEntry.ByteCount = moduleDescriptor.Data.Length.ToString();
|
||||
statisticsEntry.Data = moduleDescriptor.Data.ToHexString();
|
||||
|
||||
taskLogCallback(this, statisticsEntry);
|
||||
|
||||
moduleIndex++;
|
||||
}
|
||||
|
||||
SendModuleStatisticsCmd();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (moduleDescriptorList.Count == 0)
|
||||
{
|
||||
ExtractComplete(true);
|
||||
}
|
||||
}
|
||||
else if (message.Payload is NetworkResponse)
|
||||
{
|
||||
NetworkResponse networkResponse = (NetworkResponse)message.Payload;
|
||||
|
||||
if (networkResponse.Payload is ParameterReadResponse)
|
||||
{
|
||||
ParameterReadResponse parameterReadResponse = (ParameterReadResponse)networkResponse.Payload;
|
||||
|
||||
if (parameterReadResponse.TagMap == TagMap.GlobalIPerl)
|
||||
{
|
||||
List<NA2WParameter> na2wParameterList = parameterReadResponse.Parameters;
|
||||
|
||||
foreach (NA2WParameter na2wParameter in na2wParameterList)
|
||||
{
|
||||
switch (na2wParameter.Tag)
|
||||
{
|
||||
case ((byte)GlobalIPerlTag.SerialNumber):
|
||||
{
|
||||
serialNumber = na2wParameter.Value.Read<UInt64>(0);
|
||||
|
||||
SendStatisticsOverviewCmd();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void SendSessionQueryCmd()
|
||||
{
|
||||
List<byte> tagList = new List<byte>();
|
||||
tagList.Add((byte)GlobalIPerlTag.SerialNumber);
|
||||
|
||||
timerState = AlgorithmState.READ_SERIAL_NUMBER;
|
||||
timer.Change(1000, Timeout.Infinite);
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, "Read Serial Number Sent");
|
||||
}
|
||||
|
||||
// Send message request
|
||||
ParameterReadCommand parameterReadCommand = new ParameterReadCommand(TagMap.GlobalIPerl, tagList);
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(parameterReadCommand, ParameterReadResponse._Code);
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendStatisticsOverviewCmd()
|
||||
{
|
||||
DataReportRequest_StatisticsOverview statisticsOverview = new DataReportRequest_StatisticsOverview();
|
||||
|
||||
timerState = AlgorithmState.READ_OVERVIEW;
|
||||
timer.Change(1000, Timeout.Infinite);
|
||||
|
||||
// Send message request
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(statisticsOverview, true);
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, "Statistics Overview sent");
|
||||
}
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendModuleStatisticsCmd()
|
||||
{
|
||||
if (moduleDescriptorList.Count > moduleIndex)
|
||||
{
|
||||
ModuleStatisticsDescriptor moduleDescriptor = moduleDescriptorList[moduleIndex];
|
||||
|
||||
uint byteOffset = 0;
|
||||
uint numberOfBytes = moduleDescriptor.NumberOfBytes;
|
||||
if (null != moduleDescriptor.Data)
|
||||
{
|
||||
byteOffset = (uint)moduleDescriptor.Data.Length;
|
||||
numberOfBytes -= (uint)moduleDescriptor.Data.Length;
|
||||
}
|
||||
if (numberOfBytes > 100)
|
||||
{
|
||||
numberOfBytes = 100;
|
||||
}
|
||||
|
||||
DataReportRequest_ModuleStatistics moduleStatistics = new DataReportRequest_ModuleStatistics();
|
||||
moduleStatistics.ModuleId = moduleDescriptor.ModuleId;
|
||||
moduleStatistics.ByteOffset = (ushort)byteOffset;
|
||||
moduleStatistics.ByteCount = (ushort)numberOfBytes;
|
||||
|
||||
timerState = AlgorithmState.READ_STATISTICS;
|
||||
timer.Change(1000, Timeout.Infinite);
|
||||
|
||||
// Send message request
|
||||
NA2WSerialFrame response = messageEngine.SendNa2wSerial(moduleStatistics, true);
|
||||
|
||||
if (taskProgessCallback != null)
|
||||
{
|
||||
taskProgessCallback(this, 0, moduleIndex.ToString() + " events extracted");
|
||||
}
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
ProcessReply(response);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ExtractComplete(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
14
NfcC7_DLL/NfcHanler/SterlingDriverError.cs
Normal file
14
NfcC7_DLL/NfcHanler/SterlingDriverError.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace NfcC7_DLL.NfcHanler;
|
||||
|
||||
public enum SterlingDriverError
|
||||
{
|
||||
SterlingDvr_Error_BlockInvalid = -5, //< A block read from the hardware was invalid. Potential comms or hardware failure.
|
||||
SterlingDvr_Error_ResetFailed = -4, //< The reset of the hardware failed. This is a critical error!
|
||||
SterlingDvr_Error_Timeout = -3, //< A timeout of some kind occurred in the driver
|
||||
SterlingDvr_Error_CommsFailure = -2, //< A communications failure occurred between the host micro and the hardware
|
||||
SterlingDvr_Error_ConfigInvalid = -1, //< Configuration did not pass validation
|
||||
SterlingDvr_Error_None = 0, //< No errors reported on the last operation
|
||||
SterlingDvr_Error_StateAlreadyValid = 1, //< The state was already valid so a function was most than likely called twice
|
||||
SterlingDvr_Error_Retried = 2, //< The operation succeeded but required a retry at some point
|
||||
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler.Utils
|
||||
@ -518,7 +519,7 @@ namespace NfcC7_DLL.NfcHanler.Utils
|
||||
|
||||
public static Boolean verifyGFTsha(BinaryReader bRdr)
|
||||
{
|
||||
using (SHA256Cng fileSHA = new SHA256Cng())
|
||||
using (SHA256 fileSHA = SHA256.Create())
|
||||
{
|
||||
bRdr.BaseStream.Position = 0;
|
||||
byte[] computedSHA = fileSHA.ComputeHash(bRdr.ReadBytes(sha256Chunk.numBytesInSHA));
|
||||
@ -661,7 +662,7 @@ namespace NfcC7_DLL.NfcHanler.Utils
|
||||
// SHA-256 starts at numBytesInSignature + 1 because the verification block version number is fisrt
|
||||
Array.Copy(decompBlockData, numBytesInSignature + 1, verfBuf, 0, _SIG_LEN/2);
|
||||
|
||||
using (SHA256Cng blockSHA = new SHA256Cng())
|
||||
using (SHA256 blockSHA = SHA256.Create())
|
||||
{
|
||||
byte[] computedSHA = blockSHA.ComputeHash(decompBlockData, 0, numBytesInSignature);
|
||||
for (int i = 0; i < computedSHA.Length; i++)
|
||||
|
||||
87
NfcC7_DLL/NfcHanler/wmbus.cs
Normal file
87
NfcC7_DLL/NfcHanler/wmbus.cs
Normal file
@ -0,0 +1,87 @@
|
||||
namespace NfcC7_DLL.NfcHanler
|
||||
{
|
||||
public enum WMBusDeviceType
|
||||
{
|
||||
Other = 0x00,
|
||||
Oil = 0x01,
|
||||
Electricity = 0x02,
|
||||
Gas = 0x03,
|
||||
Head = 0x04,
|
||||
Stream = 0x05,
|
||||
WarmWater_30_90 = 0x06,
|
||||
Water = 0x07,
|
||||
HeatCostAllocator = 0x08,
|
||||
#if false
|
||||
static String (self):
|
||||
|
||||
if (self.address[5] >= 0x40):
|
||||
return 'Reserved'
|
||||
|
||||
return {
|
||||
0x00: 'Other',
|
||||
0x01: 'Oil',
|
||||
0x02: 'Electricity',
|
||||
0x03: 'Gas',
|
||||
0x04: 'Head',
|
||||
0x05: 'Steam ',
|
||||
0x06: 'Warm water (30-90 °C)',
|
||||
0x07: 'Water ',
|
||||
0x08: 'Heat cost allocator ',
|
||||
0x09: 'Compressed air ',
|
||||
0x0A: 'Cooling load meter (Volume measured at return temperature: outlet)',
|
||||
0x0B: 'Cooling load meter (Volume measured at flow temperature: inlet)',
|
||||
0x0C: 'Heat (Volume measured at flow temperature: inlet)',
|
||||
0x0D: 'Heat / Cooling load meter',
|
||||
0x0E: 'Bus / System component',
|
||||
0x0F: 'Unknown medium',
|
||||
0x10: 'Reserved for consumption meter',
|
||||
0x11: 'Reserved for consumption meter',
|
||||
0x12: 'Reserved for consumption meter',
|
||||
0x13: 'Reserved for consumption meter',
|
||||
0x14: 'Calorific value',
|
||||
0x15: 'Hot water (≥ 90 °C)',
|
||||
0x16: 'Cold water',
|
||||
0x17: 'Dual register (hot/cold) water meter',
|
||||
0x18: 'Pressure',
|
||||
0x19: 'A/D Converter',
|
||||
0x1A: 'Smoke detector',
|
||||
0x1B: 'Room sensor (eg temperature or humidity)',
|
||||
0x1C: 'Gas detector',
|
||||
0x1D: 'Reserved for sensors',
|
||||
0x1F: 'Reserved for sensors',
|
||||
0x20: 'Breaker (electricity)',
|
||||
0x21: 'Valve (gas or water)',
|
||||
0x22: 'Reserved for switching devices',
|
||||
0x23: 'Reserved for switching devices',
|
||||
0x24: 'Reserved for switching devices',
|
||||
0x25: 'Customer unit (display device)',
|
||||
0x26: 'Reserved for customer units',
|
||||
0x27: 'Reserved for customer units',
|
||||
0x28: 'Waste water',
|
||||
0x29: 'Garbage',
|
||||
0x2A: 'Reserved for Carbon dioxide',
|
||||
0x2B: 'Reserved for environmental meter',
|
||||
0x2C: 'Reserved for environmental meter',
|
||||
0x2D: 'Reserved for environmental meter',
|
||||
0x2E: 'Reserved for environmental meter',
|
||||
0x2F: 'Reserved for environmental meter',
|
||||
0x30: 'Reserved for system devices',
|
||||
0x31: 'Reserved for communication controller',
|
||||
0x32: 'Reserved for unidirectional repeater',
|
||||
0x33: 'Reserved for bidirectional repeater',
|
||||
0x34: 'Reserved for system devices',
|
||||
0x35: 'Reserved for system devices',
|
||||
0x36: 'Radio converter (system side)',
|
||||
0x37: 'Radio converter (meter side)',
|
||||
0x38: 'Reserved for system devices',
|
||||
0x39: 'Reserved for system devices',
|
||||
0x3A: 'Reserved for system devices',
|
||||
0x3B: 'Reserved for system devices',
|
||||
0x3C: 'Reserved for system devices',
|
||||
0x3D: 'Reserved for system devices',
|
||||
0x3E: 'Reserved for system devices',
|
||||
0x3F: 'Reserved for system devices'
|
||||
}.get(self.address[5], 'get_device_type(): type unknown')
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ using System.ComponentModel;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using NfcC7_DLL.NfcHanler;
|
||||
using NfcC7_DLL.NfcHanler.Utils;
|
||||
using ICommand = System.Windows.Input.ICommand;
|
||||
|
||||
namespace NfcC7_DLL
|
||||
|
||||
Loading…
Reference in New Issue
Block a user