using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace IFS
{
public enum CopyDiskBlock
{
Version = 1,
SendDiskParamsR = 2,
HereAreDiskParams = 3,
StoreDisk = 4,
RetrieveDisk = 5,
HereIsDiskPage = 6,
EndOfTransfer = 7,
SendErrors = 8,
HereAreErrors = 9,
No = 10,
Yes = 11,
Comment = 12,
Login = 13,
SendDiskParamsW = 14,
}
struct VersionBlock
{
public VersionBlock(ushort version, string herald)
{
Version = version;
Herald = new BCPLString(herald);
Length = (ushort)((6 + herald.Length + 2) / 2); // +2 for length of BCPL string and to round up to next word length
Command = (ushort)CopyDiskBlock.Version;
}
public ushort Length;
public ushort Command;
public ushort Version;
public BCPLString Herald;
}
public class CopyDiskServer : BSPProtocol
{
///
/// Called by dispatcher to send incoming data destined for this protocol.
///
///
public override void RecvData(PUP p)
{
throw new NotImplementedException();
}
public override void InitializeServerForChannel(BSPChannel channel)
{
// spwan new worker thread with new BSP channel
Thread newThread = new Thread(new ParameterizedThreadStart(CopyDiskServerThread));
newThread.Start(channel);
}
private void CopyDiskServerThread(object obj)
{
BSPChannel channel = (BSPChannel)obj;
while(true)
{
// Retrieve length of this block (in bytes):
int length = channel.ReadUShort() * 2;
// Sanity check that length is a reasonable value.
if (length > 2048)
{
// TODO: shut down channel
throw new InvalidOperationException(String.Format("Insane block length ({0})", length));
}
// Retrieve type
CopyDiskBlock blockType = (CopyDiskBlock)channel.ReadUShort();
// Read rest of block
byte[] data = new byte[length];
channel.Read(ref data, data.Length - 4, 4);
switch(blockType)
{
case CopyDiskBlock.Version:
VersionBlock vbIn = (VersionBlock)Serializer.Deserialize(data, typeof(VersionBlock));
Console.WriteLine("Copydisk client is version {0}, '{1}'", vbIn.Version, vbIn.Herald.ToString());
// Send the response:
VersionBlock vbOut = new VersionBlock(vbIn.Version, "IFS CopyDisk of 26-Jan-2016");
channel.Send(Serializer.Serialize(vbOut));
break;
case CopyDiskBlock.Login:
break;
default:
Console.WriteLine("Unhandled CopyDisk block {0}", blockType);
break;
}
}
}
}
}