The GetBlocks message contains a request for blocks of content. It is used to retrieve a set of blocks defined by a single BLOCK_ARRAY_RANGE.
Ejemplo n.º 1
0
        /// <summary>
        /// Decode MSG_GETBLKS message.
        /// </summary>
        /// <param name="data">Data to be decoded.</param>
        /// <param name="index">Started index.</param>
        /// <returns>The MSG_GETBLKS struct.</returns>
        private MSG_GETBLKS DecodeMSG_GETBLKS(byte[] data, ref int index)
        {
            MSG_GETBLKS ret = new MSG_GETBLKS();

            ret.SizeOfSegmentID = MarshalHelper.GetUInt32(data, ref index, false);
            ret.SegmentID       = MarshalHelper.GetBytes(data, ref index, (int)ret.SizeOfSegmentID);
            ret.ZeroPad         = MarshalHelper.GetBytes(data, ref index, (int)ret.SizeOfSegmentID % 4);

            if (ret.ZeroPad == null)
            {
                ret.ZeroPad = new byte[0];
            }

            ret.ReqBlockRangeCount = MarshalHelper.GetUInt32(data, ref index, false);
            ret.ReqBlockRanges     = new BLOCK_RANGE[ret.ReqBlockRangeCount];

            for (int i = 0; i < ret.ReqBlockRangeCount; i++)
            {
                ret.ReqBlockRanges[i].Index = MarshalHelper.GetUInt32(data, ref index, false);
                ret.ReqBlockRanges[i].Count = MarshalHelper.GetUInt32(data, ref index, false);
            }

            ret.SizeOfDataForVrfBlock = MarshalHelper.GetUInt32(data, ref index, false);
            ret.DataForVrfBlock       = MarshalHelper.GetBytes(data, ref index, (int)ret.SizeOfDataForVrfBlock);

            if (ret.DataForVrfBlock == null)
            {
                ret.DataForVrfBlock = new byte[0];
            }

            return(ret);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Create a MsgGetBlks request.
        /// </summary>
        /// <param name="segmentId">The segmentId.</param>
        /// <param name="cryptoAlgoIdValues">The cryptoAlgoId.</param>
        /// <param name="msgTypeValues">The msgType.</param>
        /// <returns>MsgGetBlks request.</returns>
        public PccrrGETBLKSRequestPacket CreateMsgGetBlksRequest(
            byte[] segmentId,
            CryptoAlgoId_Values cryptoAlgoIdValues,
            MsgType_Values msgTypeValues)
        {
            if (segmentId == null)
            {
                segmentId = new byte[0];
            }

            PccrrGETBLKSRequestPacket packet = new PccrrGETBLKSRequestPacket();

            MSG_GETBLKS msgGetBlksReq = new MSG_GETBLKS();

            msgGetBlksReq.DataForVrfBlock = null;
            byte[] zeroPad = new byte[0] {
            };
            BLOCK_RANGE[] reqBlockRanges = new BLOCK_RANGE[1];
            reqBlockRanges[0].Index             = 0;
            reqBlockRanges[0].Count             = 1;
            msgGetBlksReq.ReqBlockRanges        = reqBlockRanges;
            msgGetBlksReq.ReqBlockRangeCount    = (uint)reqBlockRanges.Length;
            msgGetBlksReq.ZeroPad               = zeroPad;
            msgGetBlksReq.SizeOfSegmentID       = (uint)segmentId.Length;
            msgGetBlksReq.SizeOfDataForVrfBlock = 0;
            msgGetBlksReq.SegmentID             = segmentId;
            MESSAGE_HEADER messageHeader = PccrrUtitlity.CreateMessageHeader(cryptoAlgoIdValues, msgTypeValues, new ProtoVersion {
                MajorVersion = 1, MinorVersion = 0
            });

            packet.MsgGetBLKS    = msgGetBlksReq;
            packet.MessageHeader = messageHeader;

            return(packet);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Decode request message.
        /// </summary>
        /// <param name="rawdata">The raw data.</param>
        /// <param name="uri">The request uri.</param>
        /// <param name="method">The request method.</param>
        /// <returns>The PccrrPacket.</returns>
        public PccrrPacket DecodeRequestMessage(byte[] rawdata, Uri uri, HttpMethod method)
        {
            if (rawdata == null)
            {
                throw new ArgumentNullException("rawdata");
            }

            if (rawdata.Length == 0)
            {
                throw new ArgumentException("The rawdata should not be empty.");
            }

            int messageLength = 0;

            messageLength = rawdata.Length;

            PccrrPacket packet = null;

            if (messageLength > 0)
            {
                int index = 0;

                REQUEST_MESSAGE ret = new REQUEST_MESSAGE();
                ret.MESSAGEHEADER = this.DecodeMessageHeader(rawdata, ref index);

                switch (ret.MESSAGEHEADER.MsgType)
                {
                case MsgType_Values.MSG_NEGO_REQ:
                    PccrrNegoRequestPacket pccrrNegoRequestPacket = new PccrrNegoRequestPacket();

                    MSG_NEGO_REQ msgNEGOREQ = this.DecodeMSG_NEGO_REQ(rawdata, ref index);
                    pccrrNegoRequestPacket.MsgNegoReq    = msgNEGOREQ;
                    pccrrNegoRequestPacket.MessageHeader = ret.MESSAGEHEADER;
                    pccrrNegoRequestPacket.Method        = method;
                    pccrrNegoRequestPacket.Uri           = uri;
                    packet = pccrrNegoRequestPacket;
                    break;

                case MsgType_Values.MSG_GETBLKLIST:
                    PccrrGETBLKLISTRequestPacket pccrrGETBLKLISTRequestPacket = new PccrrGETBLKLISTRequestPacket();

                    MSG_GETBLKLIST msgGETBLKLIST = this.DecodeMSG_GETBLKLIST(rawdata, ref index);
                    pccrrGETBLKLISTRequestPacket.MsgGetBLKLIST = msgGETBLKLIST;
                    pccrrGETBLKLISTRequestPacket.MessageHeader = ret.MESSAGEHEADER;
                    pccrrGETBLKLISTRequestPacket.Method        = method;
                    pccrrGETBLKLISTRequestPacket.Uri           = uri;
                    packet = pccrrGETBLKLISTRequestPacket;
                    break;

                case MsgType_Values.MSG_GETBLKS:
                    PccrrGETBLKSRequestPacket pccrrGETBLKSRequestPacket = new PccrrGETBLKSRequestPacket();

                    MSG_GETBLKS msgGETBLKS = this.DecodeMSG_GETBLKS(rawdata, ref index);
                    pccrrGETBLKSRequestPacket.MsgGetBLKS    = msgGETBLKS;
                    pccrrGETBLKSRequestPacket.MessageHeader = ret.MESSAGEHEADER;
                    pccrrGETBLKSRequestPacket.Method        = method;
                    pccrrGETBLKSRequestPacket.Uri           = uri;
                    packet = pccrrGETBLKSRequestPacket;
                    break;

                case MsgType_Values.MSG_GETSEGLIST:
                    PccrrGetSegListRequestPacket pccrrGetSegListRequestPacket = new PccrrGetSegListRequestPacket();
                    pccrrGetSegListRequestPacket.MsgGetSegList = TypeMarshal.ToStruct <MSG_GETSEGLIST>(rawdata, ref index);
                    pccrrGetSegListRequestPacket.MessageHeader = ret.MESSAGEHEADER;
                    pccrrGetSegListRequestPacket.Method        = method;
                    pccrrGetSegListRequestPacket.Uri           = uri;
                    packet = pccrrGetSegListRequestPacket;
                    break;
                }
            }

            return(packet);
        }
        /// <summary>
        /// Decode MSG_GETBLKS message.
        /// </summary>
        /// <param name="data">Data to be decoded.</param>
        /// <param name="index">Started index.</param>
        /// <returns>The MSG_GETBLKS struct.</returns>
        private MSG_GETBLKS DecodeMSG_GETBLKS(byte[] data, ref int index)
        {
            MSG_GETBLKS ret = new MSG_GETBLKS();

            ret.SizeOfSegmentID = MarshalHelper.GetUInt32(data, ref index, false);
            ret.SegmentID = MarshalHelper.GetBytes(data, ref index, (int)ret.SizeOfSegmentID);
            ret.ZeroPad = MarshalHelper.GetBytes(data, ref index, (int)ret.SizeOfSegmentID % 4);

            if (ret.ZeroPad == null)
            {
                ret.ZeroPad = new byte[0];
            }

            ret.ReqBlockRangeCount = MarshalHelper.GetUInt32(data, ref index, false);
            ret.ReqBlockRanges = new BLOCK_RANGE[ret.ReqBlockRangeCount];

            for (int i = 0; i < ret.ReqBlockRangeCount; i++)
            {
                ret.ReqBlockRanges[i].Index = MarshalHelper.GetUInt32(data, ref index, false);
                ret.ReqBlockRanges[i].Count = MarshalHelper.GetUInt32(data, ref index, false);
            }

            ret.SizeOfDataForVrfBlock = MarshalHelper.GetUInt32(data, ref index, false);
            ret.DataForVrfBlock = MarshalHelper.GetBytes(data, ref index, (int)ret.SizeOfDataForVrfBlock);

            if (ret.DataForVrfBlock == null)
            {
                ret.DataForVrfBlock = new byte[0];
            }

            return ret;
        }
        /// <summary>
        /// Create a MsgGetBlks request.
        /// </summary>
        /// <param name="segmentId">The segmentId.</param>
        /// <param name="cryptoAlgoIdValues">The cryptoAlgoId.</param>
        /// <param name="msgTypeValues">The msgType.</param>
        /// <returns>MsgGetBlks request.</returns>
        public PccrrGETBLKSRequestPacket CreateMsgGetBlksRequest(
            byte[] segmentId,
            CryptoAlgoId_Values cryptoAlgoIdValues,
            MsgType_Values msgTypeValues)
        {
            if (segmentId == null)
            {
                segmentId = new byte[0];
            }

            PccrrGETBLKSRequestPacket packet = new PccrrGETBLKSRequestPacket();

            MSG_GETBLKS msgGetBlksReq = new MSG_GETBLKS();
            msgGetBlksReq.DataForVrfBlock = null;
            byte[] zeroPad = new byte[0] { };
            BLOCK_RANGE[] reqBlockRanges = new BLOCK_RANGE[1];
            reqBlockRanges[0].Index = 0;
            reqBlockRanges[0].Count = 1;
            msgGetBlksReq.ReqBlockRanges = reqBlockRanges;
            msgGetBlksReq.ReqBlockRangeCount = (uint)reqBlockRanges.Length;
            msgGetBlksReq.ZeroPad = zeroPad;
            msgGetBlksReq.SizeOfSegmentID = (uint)segmentId.Length;
            msgGetBlksReq.SizeOfDataForVrfBlock = 0;
            msgGetBlksReq.SegmentID = segmentId;
            MESSAGE_HEADER messageHeader = PccrrUtitlity.CreateMessageHeader(cryptoAlgoIdValues, msgTypeValues, new ProtoVersion { MajorVersion = 1, MinorVersion = 0 });
            packet.MsgGetBLKS = msgGetBlksReq;
            packet.MessageHeader = messageHeader;

            return packet;
        }
        /// <summary>
        /// MSG_GETBLKS structure capture
        /// </summary>
        /// <param name="getBlks">MSG_GETBLKS object</param>
        private void VerifyGetBlocks(MSG_GETBLKS getBlks)
        {
            // Verify requirement MS-PCCRR_R61 and MS-PCCRR_R113
            string isR61Implementated = Site.Properties.Get("PCCRR.SHOULDMAY.R61Implementated");
            bool isR113Satisfied = getBlks.ReqBlockRanges.Length == 1;

            if (isWindows)
            {
                //
                // Add the debug information
                //
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R113");

                // Verify MS-PCCRR requirement: MS-PCCRR_R113
                Site.CaptureRequirementIfIsTrue(
                    isR113Satisfied,
                    113,
                    @"[In MESSAGE_HEADER][MsgType (4 bytes)] Since only one block will be returned, a MSG_GETBLKS
                    message specify only a single range containing only a single block.[In windows]");

                if (null == isR61Implementated)
                {
                    Site.Properties.Add("PCCRR.SHOULDMAY.R61Implementated", Boolean.TrueString);
                    isR61Implementated = Boolean.TrueString;
                }
            }

            if (null != isR61Implementated)
            {
                bool implement = Boolean.Parse(isR61Implementated);
                bool isSatisfied = isR113Satisfied;

                //
                // Add the debug information
                //
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R61");

                // Verify MS-PCCRR requirement: MS-PCCRR_R61
                Site.CaptureRequirementIfAreEqual<bool>(
                    implement,
                    isSatisfied,
                    61,
                    @"[In MESSAGE_HEADER][MsgType (4 bytes)] Since only one block will be returned,
                    a MSG_GETBLKS message SHOULD specify only a single range containing only a single block.");
            }

            //
            // Add the debug information
            //
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R101");

            // Verify MS-PCCRR requirement: MS-PCCRR_R101
            Site.CaptureRequirementIfAreEqual<uint>(
                (uint)getBlks.SegmentID.Length,
                getBlks.SizeOfSegmentID,
                101,
                @"[In MSG_GETBLKS]SizeOfSegmentID (4 bytes):  Size in bytes of the subsequent SegmentID field.");

            //
            // Add the debug information
            //
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R102");

            // Verify MS-PCCRR requirement: MS-PCCRR_R102
            bool isVerifyR102 = getBlks.SizeOfSegmentID >= 0x00000000 && getBlks.SizeOfSegmentID <= 0xFFFFFFFF;

            Site.CaptureRequirementIfIsTrue(
                isVerifyR102,
                102,
                @"[In MSG_GETBLKS][SizeOfSegmentID (4 bytes)]The syntactic range of this field[SegmentID field]
                is from 0x00000000 to 0xFFFFFFFF.");

            //
            // Add the debug information
            //
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R105");

            // Verify MS-PCCRR requirement: MS-PCCRR_R105
            Site.CaptureRequirementIfAreEqual<int>(
                32,
                getBlks.SegmentID.Length,
                105,
                @"[In MSG_GETBLKS][SizeOfSegmentID (4 bytes)][Implementations]MUST support content with 32-byte
                SegmentIDs.<6>");

            if (null != getBlks.ZeroPad)
            {
                bool isAllZero = true;

                // If the length is zero, the flag will remain in true
                // else, the bytes will be checked in foreach statements
                foreach (byte b in getBlks.ZeroPad)
                {
                    if (b != 0)
                    {
                        isAllZero = false;
                        break;
                    }
                }

                //
                // Add the debug information
                //
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R110");

                // Verify MS-PCCRR requirement: MS-PCCRR_R110
                bool isVerifyR110 = getBlks.ZeroPad.Length >= 0 && getBlks.ZeroPad.Length <= 3;

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR110,
                    110,
                    @"[In MSG_GETBLKS]This field[ZeroPad (variable)] is 0 to 3 bytes in length, as required.");

                //
                // Add the debug information
                //
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R109");

                // Verify MS-PCCRR requirement: MS-PCCRR_R109
                bool isVerifyR109 = isAllZero;

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR109,
                    109,
                    @"[In MSG_GETBLKS][ZeroPad (variable)]The value of each byte MUST be set to zero.");
            }

            // Verify requirement MS-PCCRR_R104 and MS-PCCRR_R111
            string isR104Implementated = Site.Properties.Get("PCCRR.SHOULDMAY.R104Implementated");
            bool isR111Satisfied = getBlks.SizeOfSegmentID >= 0x00000000 && getBlks.SizeOfSegmentID <= 0xFFFFFFFF;

            if (isWindows)
            {
                //
                // Add the debug information
                //
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R111");

                // Verify MS-PCCRR requirement: MS-PCCRR_R111
                Site.CaptureRequirementIfIsTrue(
                    isR111Satisfied,
                    111,
                    @"[In MSG_GETBLKS][SizeOfSegmentID (4 bytes)]Implementations support all allowed
                    SegmentID lengths.[In windows]");

                if (null == isR104Implementated)
                {
                    Site.Properties.Add("PCCRR.SHOULDMAY.R104Implementated", Boolean.TrueString);
                    isR104Implementated = Boolean.TrueString;
                }
            }

            if (null != isR104Implementated)
            {
                bool implement = Boolean.Parse(isR104Implementated);
                bool isSatisfied = isR111Satisfied;

                //
                // Add the debug information
                //
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R104");

                // Verify MS-PCCRR requirement: MS-PCCRR_R104
                Site.CaptureRequirementIfAreEqual<bool>(
                    implement,
                    isSatisfied,
                    104,
                    @"[In MSG_GETBLKS][SizeOfSegmentID (4 bytes)]Implementations SHOULD support all
                    allowed SegmentID lengths");
            }

            //
            // Add the debug information
            //
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R114");

            // Verify MS-PCCRR requirement: MS-PCCRR_R114
            Site.CaptureRequirementIfAreEqual<uint>(
                (uint)getBlks.ReqBlockRanges.Length,
                getBlks.ReqBlockRangeCount,
                114,
                @"[In MSG_GETBLKS]ReqBlockRangeCount (4 bytes):  Number of items in the subsequent block range array.");

            //
            // Add the debug information
            //
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R115");

            // Verify MS-PCCRR requirement: MS-PCCRR_R115
            bool isVerifyR115 = getBlks.ReqBlockRangeCount >= 0x00000000
                && getBlks.ReqBlockRangeCount <= 0xFFFFFFFF;

            Site.CaptureRequirementIfIsTrue(
                isVerifyR115,
                115,
                @"[In MSG_GETBLKS]The syntactic range of this field[ReqBlockRangeCount (4 bytes)] is
                from 0x00000000 to 0xFFFFFFFF.");

            //
            // Add the debug information
            //
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R116");

            // Verify MS-PCCRR requirement: MS-PCCRR_R116
            bool isVerifyR116 = getBlks.ReqBlockRangeCount >= 1
                && getBlks.ReqBlockRangeCount <= 256;

            Site.CaptureRequirementIfIsTrue(
                isVerifyR116,
                116,
                @"[In MSG_GETBLKS][ReqBlockRangeCount (4 bytes)]The effective range of this field MUST be
                between 1 and 256 inclusive, because there cannot be more than 256 non-overlapping and non-contiguous
                ranges in a maximum segment size of 512 blocks.");

            //
            // Add the debug information
            //
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R118");

            Site.CaptureRequirement(
                118,
                @"[In MSG_GETBLKS][ReqBlockRanges (variable)]RegBlockRanges MUST specify a block range containing
                only one block.");

            //
            // Add the debug information
            //
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R119");

            // Verify MS-PCCRR requirement: MS-PCCRR_R119
            Site.CaptureRequirementIfAreEqual<int>(
                getBlks.DataForVrfBlock.Length,
                (int)getBlks.SizeOfDataForVrfBlock,
                119,
                @"[In MSG_GETBLKS]SizeOfDataForVrfBlock (4 bytes):  Size in bytes of the subsequent
                DataForVrfBlock field.");

            // Verify requirement MS-PCCRR_R120 and MS-PCCRR_R121
            string isR120Implementated = Site.Properties.Get("PCCRR.SHOULDMAY.R120Implementated");
            bool isR121Satisfied = getBlks.SizeOfDataForVrfBlock == 0;

            if (isWindows)
            {
                //
                // Add the debug information
                //
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R121");

                // Verify MS-PCCRR requirement: MS-PCCRR_R121
                Site.CaptureRequirementIfIsTrue(
                    isR121Satisfied,
                    121,
                    @"[In MSG_GETBLKS]This[SizeOfDataForVrfBlock (4 bytes)] field is zero.[In windows]");

                if (null == isR120Implementated)
                {
                    Site.Properties.Add("PCCRR.SHOULDMAY.R120Implementated", Boolean.TrueString);
                    isR120Implementated = Boolean.TrueString;
                }
            }

            if (null != isR120Implementated)
            {
                bool implement = Boolean.Parse(isR120Implementated);
                bool isSatisfied = isR121Satisfied;

                //
                // Add the debug information
                //
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R120");

                // Verify MS-PCCRR requirement: MS-PCCRR_R120
                Site.CaptureRequirementIfAreEqual<bool>(
                    implement,
                    isSatisfied,
                    120,
                    @"[In MSG_GETBLKS]This[SizeOfDataForVrfBlock (4 bytes)] field SHOULD be zero.");
            }

            // Verify requirement MS-PCCRR_R123 and MS-PCCRR_R124
            string isR123Implementated = Site.Properties.Get("PCCRR.SHOULDMAY.R123Implementated");
            bool isR124Satisfied = getBlks.DataForVrfBlock.Length == 0;

            if (isWindows)
            {
                //
                // Add the debug information
                //
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R124");

                // Verify MS-PCCRR requirement: MS-PCCRR_R124
                Site.CaptureRequirementIfIsTrue(
                    isR124Satisfied,
                    124,
                    @"[In MSG_GETBLKS][DataForVrfBlock (variable)]This field is empty.[In windows]");

                if (null == isR123Implementated)
                {
                    Site.Properties.Add("PCCRR.SHOULDMAY.R123Implementated", Boolean.TrueString);
                    isR123Implementated = Boolean.TrueString;
                }
            }

            if (null != isR123Implementated)
            {
                bool implement = Boolean.Parse(isR123Implementated);
                bool isSatisfied = isR124Satisfied;

                //
                // Add the debug information
                //
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R123");

                // Verify MS-PCCRR requirement: MS-PCCRR_R123
                Site.CaptureRequirementIfAreEqual<bool>(
                    implement,
                    isSatisfied,
                    123,
                    @"[In MSG_GETBLKS][DataForVrfBlock (variable)]This field SHOULD be empty.");
            }

            // Capture directly, because it won't get the packet if the client didn't specify a right server address.
            Site.CaptureRequirement(
                201,
                @"[In MSG_GETBLKS Initiation]To initiate a Retrieval Protocol request for specific block ranges,
                the higher-layer applications MUST specify a server address.");

            //
            // Add the debug information
            //
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R202");

            // Verify MS-PCCRR requirement: MS-PCCRR_R202
            bool isVerifyR202 = true;

            Site.CaptureRequirementIfIsTrue(
                isVerifyR202,
                202,
                @"[In MSG_GETBLKS Initiation]To initiate a Retrieval Protocol request for specific block ranges,
                the higher-layer applications MUST specify a segment ID.");

            //
            // Add the debug information
            //
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R203");

            // Verify MS-PCCRR requirement: MS-PCCRR_R203
            bool isVerifyR203 = (uint)getBlks.ReqBlockRanges.Length == getBlks.ReqBlockRangeCount && true;

            Site.CaptureRequirementIfIsTrue(
                isVerifyR203,
                203,
                @"[In MSG_GETBLKS Initiation]To initiate a Retrieval Protocol request for specific block ranges,
                the higher-layer applications MUST specify a set of block ranges with the segment identified
                by the segment ID.");

            // Capture directly, because it won't send a GetBlocklist message to the server if the client
            // did not construct an instance of the Retrieval Protocol instantiation.
            Site.CaptureRequirement(
                204,
                @"[In MSG_GETBLKS Initiation]The client instance of the Retrieval Protocol MUST construct
                a GetBlocks message.");

            //
            // Add the debug information
            //
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R174");

            // Verify MS-PCCRR requirement: MS-PCCRR_R174
            bool isVerifyR174 = getBlks.ReqBlockRanges != null && getBlks.SegmentID != null;

            Site.CaptureRequirementIfIsTrue(
                isVerifyR174,
                174,
                @"[In Protocol Details]Blocks request/response: A client initiates a GetBlocks request
                (MSG_GETBLKS (section 2.2.4.3)) to a server to retrieve a specific block of a given segment,
                which is identified by the segment ID and the index of the block in the segment.");

            //
            // Add the debug information
            //
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R175");

            // Since the request is received, the following requirement can be verified directly
            Site.CaptureRequirement(
                175,
                @"[In Protocol Details][Blocks request/response]It[client] does this by sending
                a MSG_GETBLKS request.");
        }