SCSIResponsePDU.cs 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* Copyright (C) 2012-2016 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using Utilities;
  11. namespace ISCSI
  12. {
  13. public class SCSIResponsePDU : ISCSIPDU
  14. {
  15. public bool BidirectionalReadResidualOverflow;
  16. public bool BidirectionalReadResidualUnderflow;
  17. public bool ResidualOverflow;
  18. public bool ResidualUnderflow;
  19. public ISCSIResponseName Response;
  20. public SCSIStatusCodeName Status;
  21. public uint SNACKTag;
  22. public uint StatSN;
  23. public uint ExpCmdSN;
  24. public uint MaxCmdSN;
  25. public uint ExpDataSN;
  26. public uint BidirectionalReadResidualCount;
  27. public uint ResidualCount;
  28. public SCSIResponsePDU() : base()
  29. {
  30. OpCode = ISCSIOpCodeName.SCSIResponse;
  31. Final = true;
  32. }
  33. public SCSIResponsePDU(byte[] buffer) : base(buffer)
  34. {
  35. BidirectionalReadResidualOverflow = (OpCodeSpecificHeader[0] & 0x10) != 0;
  36. BidirectionalReadResidualUnderflow = (OpCodeSpecificHeader[0] & 0x08) != 0;
  37. ResidualOverflow = (OpCodeSpecificHeader[0] & 0x04) != 0;
  38. ResidualUnderflow = (OpCodeSpecificHeader[0] & 0x02) != 0;
  39. Response = (ISCSIResponseName)OpCodeSpecificHeader[1];
  40. Status = (SCSIStatusCodeName)OpCodeSpecificHeader[2];
  41. SNACKTag = BigEndianConverter.ToUInt32(OpCodeSpecific, 0);
  42. StatSN = BigEndianConverter.ToUInt32(OpCodeSpecific, 4);
  43. ExpCmdSN = BigEndianConverter.ToUInt32(OpCodeSpecific, 8);
  44. MaxCmdSN = BigEndianConverter.ToUInt32(OpCodeSpecific, 12);
  45. ExpDataSN = BigEndianConverter.ToUInt32(OpCodeSpecific, 16);
  46. BidirectionalReadResidualCount = BigEndianConverter.ToUInt32(OpCodeSpecific, 20);
  47. ResidualCount = BigEndianConverter.ToUInt32(OpCodeSpecific, 24);
  48. }
  49. public override byte[] GetBytes()
  50. {
  51. if (BidirectionalReadResidualOverflow)
  52. {
  53. OpCodeSpecificHeader[0] |= 0x10;
  54. }
  55. if (BidirectionalReadResidualUnderflow)
  56. {
  57. OpCodeSpecificHeader[0] |= 0x08;
  58. }
  59. if (ResidualOverflow)
  60. {
  61. OpCodeSpecificHeader[0] |= 0x04;
  62. }
  63. if (ResidualUnderflow)
  64. {
  65. OpCodeSpecificHeader[0] |= 0x02;
  66. }
  67. OpCodeSpecificHeader[1] = (byte)Response;
  68. OpCodeSpecificHeader[2] = (byte)Status;
  69. Array.Copy(BigEndianConverter.GetBytes(SNACKTag), 0, OpCodeSpecific, 0, 4);
  70. Array.Copy(BigEndianConverter.GetBytes(StatSN), 0, OpCodeSpecific, 4, 4);
  71. Array.Copy(BigEndianConverter.GetBytes(ExpCmdSN), 0, OpCodeSpecific, 8, 4);
  72. Array.Copy(BigEndianConverter.GetBytes(MaxCmdSN), 0, OpCodeSpecific, 12, 4);
  73. Array.Copy(BigEndianConverter.GetBytes(ExpDataSN), 0, OpCodeSpecific, 16, 4);
  74. Array.Copy(BigEndianConverter.GetBytes(BidirectionalReadResidualCount), 0, OpCodeSpecific, 20, 4);
  75. Array.Copy(BigEndianConverter.GetBytes(ResidualCount), 0, OpCodeSpecific, 24, 4);
  76. return base.GetBytes();
  77. }
  78. }
  79. }