/// <summary> /// Decode MSG_GETBLKLIST message /// </summary> /// <param name="data">Data to be decoded.</param> /// <param name="index">Started index.</param> /// <returns>The MSG_GETBLKLIST struct.</returns> private MSG_GETBLKLIST DecodeMSG_GETBLKLIST(byte[] data, ref int index) { MSG_GETBLKLIST ret = new MSG_GETBLKLIST(); 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.NeededBlocksRangeCount = MarshalHelper.GetUInt32(data, ref index, false); ret.NeededBlockRanges = new BLOCK_RANGE[ret.NeededBlocksRangeCount]; for (int i = 0; i < ret.NeededBlocksRangeCount; i++) { ret.NeededBlockRanges[i].Index = MarshalHelper.GetUInt32(data, ref index, false); ret.NeededBlockRanges[i].Count = MarshalHelper.GetUInt32(data, ref index, false); } return(ret); }
/// <summary> /// Create a MsgGetBlkList request. /// </summary> /// <param name="segmentId">The segmentId.</param> /// <param name="blockRanges">The needed BlockRanges.</param> /// <param name="cryptoAlgoIdValues">The cryptoAlgoId.</param> /// <param name="msgTypeValues">The msgType.</param> /// <returns>MsgGetBlkList request.</returns> public PccrrGETBLKLISTRequestPacket CreateMsgGetBlkListRequest( byte[] segmentId, BLOCK_RANGE[] blockRanges, CryptoAlgoId_Values cryptoAlgoIdValues, MsgType_Values msgTypeValues) { if (segmentId == null) { segmentId = new byte[0]; } if (blockRanges == null) { blockRanges = new BLOCK_RANGE[0]; } PccrrGETBLKLISTRequestPacket packet = new PccrrGETBLKLISTRequestPacket(); MSG_GETBLKLIST msgGetBlkListReq = new MSG_GETBLKLIST(); byte[] zeroPad = new byte[0] { }; msgGetBlkListReq.SegmentID = segmentId; msgGetBlkListReq.SizeOfSegmentID = (uint)segmentId.Length; msgGetBlkListReq.NeededBlockRanges = blockRanges; msgGetBlkListReq.NeededBlocksRangeCount = (uint)blockRanges.Length; msgGetBlkListReq.ZeroPad = zeroPad; MESSAGE_HEADER messageHeader = PccrrUtitlity.CreateMessageHeader(cryptoAlgoIdValues, msgTypeValues, new ProtoVersion { MajorVersion = 1, MinorVersion = 0 }); packet.MsgGetBLKLIST = msgGetBlkListReq; packet.MessageHeader = messageHeader; return(packet); }
/// <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_GETBLKLIST message /// </summary> /// <param name="data">Data to be decoded.</param> /// <param name="index">Started index.</param> /// <returns>The MSG_GETBLKLIST struct.</returns> private MSG_GETBLKLIST DecodeMSG_GETBLKLIST(byte[] data, ref int index) { MSG_GETBLKLIST ret = new MSG_GETBLKLIST(); 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.NeededBlocksRangeCount = MarshalHelper.GetUInt32(data, ref index, false); ret.NeededBlockRanges = new BLOCK_RANGE[ret.NeededBlocksRangeCount]; for (int i = 0; i < ret.NeededBlocksRangeCount; i++) { ret.NeededBlockRanges[i].Index = MarshalHelper.GetUInt32(data, ref index, false); ret.NeededBlockRanges[i].Count = MarshalHelper.GetUInt32(data, ref index, false); } return ret; }
/// <summary> /// Create a MsgGetBlkList request. /// </summary> /// <param name="segmentId">The segmentId.</param> /// <param name="blockRanges">The needed BlockRanges.</param> /// <param name="cryptoAlgoIdValues">The cryptoAlgoId.</param> /// <param name="msgTypeValues">The msgType.</param> /// <returns>MsgGetBlkList request.</returns> public PccrrGETBLKLISTRequestPacket CreateMsgGetBlkListRequest( byte[] segmentId, BLOCK_RANGE[] blockRanges, CryptoAlgoId_Values cryptoAlgoIdValues, MsgType_Values msgTypeValues) { if (segmentId == null) { segmentId = new byte[0]; } if (blockRanges == null) { blockRanges = new BLOCK_RANGE[0]; } PccrrGETBLKLISTRequestPacket packet = new PccrrGETBLKLISTRequestPacket(); MSG_GETBLKLIST msgGetBlkListReq = new MSG_GETBLKLIST(); byte[] zeroPad = new byte[0] { }; msgGetBlkListReq.SegmentID = segmentId; msgGetBlkListReq.SizeOfSegmentID = (uint)segmentId.Length; msgGetBlkListReq.NeededBlockRanges = blockRanges; msgGetBlkListReq.NeededBlocksRangeCount = (uint)blockRanges.Length; msgGetBlkListReq.ZeroPad = zeroPad; MESSAGE_HEADER messageHeader = PccrrUtitlity.CreateMessageHeader(cryptoAlgoIdValues, msgTypeValues, new ProtoVersion { MajorVersion = 1, MinorVersion = 0 }); packet.MsgGetBLKLIST = msgGetBlkListReq; packet.MessageHeader = messageHeader; return packet; }
/// <summary> /// MSG_GETBLKLIST structure capture. /// </summary> /// <param name="getBlkList">MSG_GETBLKLIST object.</param> private void VerifyGetBlkList(MSG_GETBLKLIST getBlkList) { // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R82"); // Verify MS-PCCRR requirement: MS-PCCRR_R82 // If GetBlkList.NeededBlockRanges is not null, means it contains a request for blocks of content. Site.CaptureRequirementIfIsNotNull( getBlkList.NeededBlockRanges, 82, @"[In MSG_GETBLKLIST]The MSG_GETBLKLIST (GetBlockList) message contains a request for a download block list."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R84"); // Verify MS-PCCRR requirement: MS-PCCRR_R84 Site.CaptureRequirementIfAreEqual<uint>( (uint)getBlkList.SegmentID.Length, getBlkList.SizeOfSegmentID, 84, @"[In MSG_GETBLKLIST]SizeOfSegmentID (4 bytes): Size, in bytes. of the subsequent SegmentID field."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R85"); // Verify MS-PCCRR requirement: MS-PCCRR_R85 bool isVerifyR85 = getBlkList.SizeOfSegmentID >= 0x00000000 && getBlkList.SizeOfSegmentID <= 0xFFFFFFFF; Site.CaptureRequirementIfIsTrue( isVerifyR85, 85, @"[In MSG_GETBLKLIST][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_R88"); // Verify MS-PCCRR requirement: MS-PCCRR_R88 Site.CaptureRequirementIfAreEqual<int>( 32, getBlkList.SegmentID.Length, 88, @"[In MSG_GETBLKLIST][SizeOfSegmentID (4 bytes)][Implementations ]MUST support content with 32-byte SegmentIDs.<4>"); if (null != getBlkList.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 getBlkList.ZeroPad) { if (b != 0) { isAllZero = false; break; } } // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R92"); // Verify MS-PCCRR requirement: MS-PCCRR_R92 bool isVerifyR92 = isAllZero; Site.CaptureRequirementIfIsTrue( isVerifyR92, 92, @"[In MSG_GETBLKLIST][ZeroPad (variable)]The value of each byte MUST be set to zero."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R93"); // Verify MS-PCCRR requirement: MS-PCCRR_R93 bool isVerifyR93 = getBlkList.ZeroPad.Length >= 0 && getBlkList.ZeroPad.Length <= 3; Site.CaptureRequirementIfIsTrue( isVerifyR93, 93, @"[In MSG_GETBLKLIST][ZeroPad (variable)]This field[ZeroPad ] is 0 to 3 bytes in length, as required."); } // Verify requirement MS-PCCRR_R87 and MS-PCCRR_R112 string isR87Implementated = Site.Properties.Get("PCCRR.SHOULDMAY.R87Implementated"); bool isR112Satisfied = getBlkList.SizeOfSegmentID >= 0x00000000 && getBlkList.SizeOfSegmentID <= 0xFFFFFFFF; if (isWindows) { // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R112"); // Verify MS-PCCRR requirement: MS-PCCRR_R112 Site.CaptureRequirementIfIsTrue( isR112Satisfied, 112, @"[In MSG_GETBLKLIST][SizeOfSegmentID (4 bytes)]Implementations support all allowed SegmentID lengths.[In windows]"); if (null == isR87Implementated) { Site.Properties.Add("PCCRR.SHOULDMAY.R87Implementated", Boolean.TrueString); isR87Implementated = Boolean.TrueString; } } if (null != isR87Implementated) { bool implement = Boolean.Parse(isR87Implementated); bool isSatisfied = isR112Satisfied; // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R87"); // Verify MS-PCCRR requirement: MS-PCCRR_R87 Site.CaptureRequirementIfAreEqual<bool>( implement, isSatisfied, 87, @"[In MSG_GETBLKLIST][SizeOfSegmentID (4 bytes)]Implementations SHOULD support all allowed SegmentID lengths"); } // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R94"); // Verify MS-PCCRR requirement: MS-PCCRR_R94 Site.CaptureRequirementIfAreEqual<uint>( getBlkList.NeededBlocksRangeCount, (uint)getBlkList.NeededBlockRanges.Length, 94, @"[In MSG_GETBLKLIST]NeededBlocksRangeCount (4 bytes): Number of items in the subsequent block range array."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R95"); // Verify MS-PCCRR requirement: MS-PCCRR_R95 bool isVerifyR95 = getBlkList.NeededBlocksRangeCount >= 0x00000000 && getBlkList.NeededBlocksRangeCount <= 0xFFFFFFFF; Site.CaptureRequirementIfIsTrue( isVerifyR95, 95, @"[In MSG_GETBLKLIST][NeededBlocksRangeCount (4 bytes)]The syntactic range of this field is from 0x00000000 to 0xFFFFFFFF."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R96"); // Verify MS-PCCRR requirement: MS-PCCRR_R96 bool isVerifyR96 = getBlkList.NeededBlocksRangeCount >= 1 && getBlkList.NeededBlocksRangeCount <= 256; Site.CaptureRequirementIfIsTrue( isVerifyR96, 96, @"[In MSG_GETBLKLIST][NeededBlocksRangeCount (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."); // Capture directly, cause it won't get the packet if the client didn't specify a right server address Site.CaptureRequirement( 193, @"[In MSG_GETBLKLIST Initiation]To initiate a Retrieval Protocol query for the list of block ranges on a server, the higher-layer applications MUST specify a server address."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R194"); // Verify MS-PCCRR requirement: MS-PCCRR_R194 bool isVerifyR194 = true; Site.CaptureRequirementIfIsTrue( isVerifyR194, 194, @"[In MSG_GETBLKLIST Initiation]To initiate a Retrieval Protocol query for the list of block ranges on a server, the higher-layer applications MUST specify a segment ID."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R195"); // Verify MS-PCCRR requirement: MS-PCCRR_R195 bool isVerifyR195 = getBlkList.NeededBlocksRangeCount == (uint)getBlkList.NeededBlockRanges.Length && true; Site.CaptureRequirementIfIsTrue( isVerifyR195, 195, @"[In MSG_GETBLKLIST Initiation]To initiate a Retrieval Protocol query for the list of block ranges on a server, the higher-layer applications MUST specify a set of block ranges within 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( 196, @"[In MSG_GETBLKLIST Initiation]The client instance of the Retrieval Protocol instantiation MUST construct a GetBlockList message ."); // 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( 197, @"[In MSG_GETBLKLIST Initiation]The client instance of the Retrieval Protocol instantiation MUST send a GetBlockList message (MSG_GETBLKLIST (section 2.2.4.2)) to the server."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R171"); // Verify MS-PCCRR requirement: MS-PCCRR_R171 bool isVerifyR171 = getBlkList.NeededBlockRanges != null && getBlkList.SegmentID != null; Site.CaptureRequirementIfIsTrue( isVerifyR171, 171, @"[In Protocol Details]BlockList request/response: A client initiates a GetBlockList request (MSG_GETBLKLIST (section 2.2.4.2)) to a server in order to query the list of content blocks available on the server for a given segment ID, and a list of block ranges within the segment, by sending a MSG_GETBLKLIST request."); }