I'm trying to implement the original XMODEM protocol (128-byte packets with 1-byte checksum) in C#. So far just implementing the send file side of things. I get the 0x15 (NAK) from the client and send my packet, but the client doesn't "see" it, it just sends a NAK again after 3 seconds. Instead of serial communications I am doing this over a socket. (TcpClient GetStream() returns the NetworkStream being used in this class). I have tried a few different telnet terminal clients including Qodem, SyncTERM and Tera Term. Same thing happens in all of them - so what'd I miss? Thanks
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
public class xmodem
{
private int offset = 0;
private byte packetNumber = 1;
public NetworkStream stream;
public byte[] file;
public void SendFileToClient()
{
offset = 0;
while (true)
{
int b = stream.ReadByte();
Console.Write(b.ToString("X2") + " ");
switch(b)
{
case 0x01: //SOH
break;
case 0x02: //STX
//SendPacket1kCRC();
break;
case 0x04: //EOT
break;
case 0x06: //ACK
packetNumber++;
offset += 0x80;
SendPacket128CS();
break;
case 0x15: //NAK
SendPacket128CS();
break;
case 0x17: //ETB
break;
case 0x18: //CAN
break;
case 0x43: //"C"
//SendPacket1kCRC();
break;
}
}
}
private void SendPacket128CS()
{
byte packetInverse = (byte)(0xFF - (int)packetNumber);
var packetData = file.Skip(offset).Take(offset + 0x80);
var cs = ComputeAdditionChecksum(packetData.ToArray());
var packet = new List<byte>();
packet.Add(0x01); //SOH
packet.Add(packetNumber);
packet.Add(packetInverse);
packet.AddRange(packetData);
packet.Add(cs);
Console.WriteLine("Sending packet 128CS " + packetNumber.ToString() + " " + packet.ToArray().Length.ToString());
stream.Write(packet.ToArray(), 0, packet.ToArray().Length);
stream.Flush();
}
public static byte ComputeAdditionChecksum(byte[] data)
{
byte check = 0;
for (int i = 0; i < data.Length; i++)
{
check += data[i];
}
return check;
}
}