private T ParseResponse <T>(ProtocolDataUnit pdu) where T : BaseResponse, new() { BaseResponse resp; switch (pdu.OpCode) { case OpCode.LoginResponse: resp = new LoginResponse(); break; case OpCode.LogoutResponse: resp = new LogoutResponse(); break; case OpCode.ReadyToTransfer: resp = new ReadyToTransferPacket(); break; case OpCode.Reject: resp = new RejectPacket(); break; case OpCode.ScsiDataIn: resp = new DataInPacket(); break; case OpCode.ScsiResponse: resp = new Response(); break; case OpCode.TextResponse: resp = new TextResponse(); break; default: throw new InvalidProtocolException("Unrecognized response opcode: " + pdu.OpCode); } resp.Parse(pdu); if (resp.StatusPresent) { SeenStatusSequenceNumber(resp.StatusSequenceNumber); } T result = resp as T; if (result == null) { throw new InvalidProtocolException("Unexpected response, expected " + typeof(T) + ", got " + result.GetType()); } return(result); }
public void Close(LogoutReason reason) { LogoutRequest req = new LogoutRequest(this); byte[] packet = req.GetBytes(reason); _stream.Write(packet, 0, packet.Length); _stream.Flush(); ProtocolDataUnit pdu = ReadPdu(); LogoutResponse resp = ParseResponse <LogoutResponse>(pdu); if (resp.Response != LogoutResponseCode.ClosedSuccessfully) { throw new InvalidProtocolException("Target indicated failure during logout: " + resp.Response); } _stream.Close(); }