📄 ancillarypacket.cpp
字号:
/*+++ *******************************************************************\
*
* Copyright and Disclaimer:
*
* ---------------------------------------------------------------
* This software is provided "AS IS" without warranty of any kind,
* either expressed or implied, including but not limited to the
* implied warranties of noninfringement, merchantability and/or
* fitness for a particular purpose.
* ---------------------------------------------------------------
*
* Copyright (c) 2008 Conexant Systems, Inc.
* All rights reserved.
*
\******************************************************************* ---*/
#include "AncillaryPacket.h"
const DWORD HEADER_SIZE = 6;
/////////////////////////////////////////////////////////////////////////////////////////
AncillaryPacket::AncillaryPacket() :
_bytes_expected(0),
_bytes_in_buffer(0)
{
}
/////////////////////////////////////////////////////////////////////////////////////////
//AncillaryPacket::submitData
//
// Submit a data buffer to be checked if it is an ancillary packet. We first attempt
// to get the packet header, because, with the header, we can verify rather or not it
// is actually an ancillary packet, and get the number of bytes expected in the rest
// of the packet. Then we copy the remaining bytes in the packet. The user of the
// class will call isBufferComplete() to check for a completed buffer after
// making this call.
//
// Returns the number of bytes copied. Returns 0 if the packet is not a valid ancillary
// packet.
//
DWORD AncillaryPacket::submitData(PBYTE p_data, DWORD bytes_available)
{
DWORD total_bytes_copied = 0;
//First try to get the header of the packet
// 6
if(_bytes_in_buffer < HEADER_SIZE) //_bytes_in_buffer will be zero when initialized
{
DWORD bytes_to_copy = HEADER_SIZE - _bytes_in_buffer;
if(bytes_to_copy > bytes_available)
{
bytes_to_copy = bytes_available;
}
RtlCopyMemory(&_data_buffer[_bytes_in_buffer], p_data, bytes_to_copy);
_bytes_in_buffer += bytes_to_copy;
//Update the buffer to reflect the data we used.
p_data += bytes_to_copy;
bytes_available -= bytes_to_copy;
total_bytes_copied += bytes_to_copy;
//Return now if we didn't have enough data to save the header.
if(_bytes_in_buffer < HEADER_SIZE)
{
return bytes_to_copy;
}
//If we now have the entire header, verify the header, and fill in the
// expected bytes based on the data count.
if(verifyHeader())
{
BYTE data_count = (((_data_buffer[5] & 0xF) << 2)); // package length
_bytes_expected = data_count + 1;
}
else
{
//Invalid packet
return FALSE;
}
}
//At this point, we should successfully have the header. Now copy any additional
// data bytes
if(_bytes_in_buffer < (HEADER_SIZE + _bytes_expected))
{
//If this ever hits, MAX_ANCILLARY_PACKET_BYTES must be adjusted upward.
// if the packet is valid.
if((HEADER_SIZE + _bytes_expected) > MAX_ANCILLARY_PACKET_BYTES)
{
//Return that the packet is invalid rather than copying past the
// end of the buffer.
return FALSE;
}
//Get the bytes to copy
DWORD bytes_to_copy = (_bytes_expected + HEADER_SIZE) - _bytes_in_buffer;
if(bytes_to_copy > bytes_available)
{
bytes_to_copy = bytes_available;
}
//Copy the data bytes
RtlCopyMemory(&_data_buffer[_bytes_in_buffer], p_data, bytes_to_copy);
_bytes_in_buffer += bytes_to_copy;
total_bytes_copied += bytes_to_copy;
}
return total_bytes_copied;
}
/////////////////////////////////////////////////////////////////////////////////////////
//AncillaryPacket::getDataID
//
// When we have a completed packet, this will return the data ID (DID) field of the packet
// allowing the type of the packet to be identified.
//
BYTE AncillaryPacket::getDataID()
{
return _data_buffer[3];
}
/////////////////////////////////////////////////////////////////////////////////////////
//AncillaryPacket::verifyHeader
//
// Verify that the header of the packet starts with 00 FF FF
//
BOOLEAN AncillaryPacket::verifyHeader()
{
if((_data_buffer[0] == 0) &&
(_data_buffer[1] == 0xFF) &&
(_data_buffer[2] == 0xFF))
{
return TRUE;
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////////////////
//AncillaryPacket::isPacketComplete
//
//Check if the current packet is complete after submiting a data buffer
//
BOOLEAN AncillaryPacket::isPacketComplete()
{
return ((_bytes_in_buffer == (HEADER_SIZE + _bytes_expected)) &&
(_bytes_expected != 0));
}
/////////////////////////////////////////////////////////////////////////////////////////
//AncillaryPacket::getBuffer
//
//Get the buffer and the buffer size. This is called by the parse buffer classes
//
PBYTE AncillaryPacket::getBuffer(PDWORD p_buffer_size)
{
*p_buffer_size = HEADER_SIZE + _bytes_expected;
return (PBYTE) _data_buffer;
}
/////////////////////////////////////////////////////////////////////////////////////////
//AncillaryPacket::clearData
//
//Clear any part of a buffer left in the class. This should be done after a completed
// packet has been parsed so that the class is ready for the next use. It also should
// be called if a partial, invalid packet has been read.
//
VOID AncillaryPacket::clearData()
{
_bytes_expected = 0;
_bytes_in_buffer = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -