public async Task<bool> ProgramP1(IPAddress address, byte[] firmware, IProgress<string> progress)
{
return await Task<bool>.Run(() =>
{
try
{
using (var udpClient = new UdpClient(new IPEndPoint(IPAddress.Any, 0)))
{
udpClient.Client.ReceiveTimeout = 60000;
udpClient.Connect(new IPEndPoint(address, 1024));
byte[] cmd = new byte[8 + 256];
cmd[0] = 0xef;
cmd[1] = 0xfe;
cmd[2] = 0x03;
cmd[3] = 0x02;
IPEndPoint from = new IPEndPoint(0, 0);
udpClient.Send(cmd, 64);
progress.Report("Erasing");
var response = udpClient.Receive(ref from);
if (response.Length >= 3 && response[2] == 0x03)
{
udpClient.Client.ReceiveTimeout = 6000;
progress.Report("Programming");
cmd[2] = 0x03;
cmd[3] = 0x01;
int blocks = firmware.Length / 256;
if (firmware.Length % 256 != 0) blocks++;
cmd[4] = (byte)(blocks >> 24);
cmd[5] = (byte)((blocks >> 16) & 0xff);
cmd[6] = (byte)((blocks >> 8) & 0xff);
cmd[7] = (byte)((blocks) & 0xff);
for (int block = 0; block < blocks; block++)
{
progress.Report("Programming " + block * 100 / blocks + "%");
int len = Math.Min(256, firmware.Length - block * 256);
Array.Copy(firmware, block * 256, cmd, 8, len);
Array.Fill<byte>(cmd, 0xff, len + 8, 256 - len);
udpClient.Send(cmd, 8 + 256);
// check response except for last
if (block < blocks - 1)
{
response = udpClient.Receive(ref from);
if (response.Length < 3 || response[2] != 0x04)
{
throw new Exception($"Programming failed at block {block}");
}
}
}
}
else
{
progress.Report("Erase Failed ");
return false;
}
}
progress.Report("Programming Complete");
return true;
}
catch(Exception e)
{
errorlog.logException(e, "Program P1");
progress.Report("Programming Failed");
return false;
}
});
}