class SignalobardMsgReadHandler : public SessionVectChar::ReadHandler
{
public:
SignalobardMsgReadHandler() = delete;
SignalobardMsgReadHandler(SignalobardMsgReadHandler _in v) = delete;
SignalobardMsgReadHandler(sNetPack * _in data_ptr, size_t _in package_size = sizeof(sNetPack) )
: last_time_(bzrobot::Now())
, data_ptr_(data_ptr)
, package_size_one_(package_size)
, package_check_sum_(0)
, cache_buffer_size_(0)
, cache_buffer_()
{
}
virtual ~SignalobardMsgReadHandler()
{
}
inline int GetPackHeadFirstIndex( char buffer[], int one_package_size, unsigned char package_head_value )
{
int continue_equal_times = 0;
for ( int i = 0; i < one_package_size; ++i )
{
if ( (unsigned char)buffer[i] == package_head_value )
{
++continue_equal_times;
if ( continue_equal_times == PackageHeadByte_ )
{
return (i-(PackageHeadByte_-1));
}
}
else
{
continue_equal_times = 0;
}
}
return -1;
}
unsigned short CalculateCheckSum ( char buffer_[], int package_size )
{
unsigned short check_sum = 0;
for ( int i = 0; i < package_size-2; ++i )
{
check_sum += (unsigned char)buffer_[i];
}
return check_sum;
}
bzrobot::Duration _rt BlankTime() const
{
return bzrobot::Now() - last_time_;
}
protected:
bzrobot::Result _rt RunMain(typename SessionVectChar::ReadHandler::OutputType _ut output,
typename SessionVectChar::ReadHandler::InputType _in input,
typename SessionVectChar::ReadHandler::OptionType _in option) final
{
last_time_ = bzrobot::Now();
if(!data_ptr_)
{
return BZROBOT_SIGNAL_BOARD_MSG_ERROR;
}
TO_2_BYTE WORDtemp;
const std::vector<char>& input_data = input;
//存包,然后根据包长决定是否取包,多包时取用最新包
memcpy ( &cache_buffer_[cache_buffer_size_], input_data.data(), input_data.size() );
cache_buffer_size_ = cache_buffer_size_ + input_data.size();
//只要缓存长度大于单个包长度,即循环进行取包,以防缓存数据堆积
while ( cache_buffer_size_ >= package_size_one_ )
{
//获取数据包头在缓存中的位置
int pack_head_index = GetPackHeadFirstIndex ( cache_buffer_, package_size_one_, PackageHeadValue_ );
//未找到包头,丢弃该部分,返回等待新的接收数据
if ( pack_head_index == -1 )
{
BZROBOT_WARNNING("SiganlBoardMsg: Not find pack head index");
cache_buffer_size_ = cache_buffer_size_ - ( pack_head_index + package_size_one_ );
return BZROBOT_SIGNAL_BOARD_MSG_ERROR;
}
//找到包头,且缓存长度足够取包
if ( pack_head_index + package_size_one_ <= cache_buffer_size_ )
{
memcpy( WORDtemp.b, &cache_buffer_[pack_head_index + package_size_one_ - 2], 2 );
//确认包校验和是否相等:相等取出数据,将取出的包段及其之前的部分丢弃
if ( CalculateCheckSum( cache_buffer_, package_size_one_ ) == WORDtemp.data16 )
{
memcpy(data_ptr_, &cache_buffer_[pack_head_index], package_size_one_);
cache_buffer_size_ = cache_buffer_size_ - ( pack_head_index + package_size_one_ );
}
//确认包校验和是否相等:不相等取出数据,将该包段及其之前的部分丢弃
else
{
BZROBOT_WARNNING("SiganlBoardMsg: Check sum not equal");
cache_buffer_size_ = cache_buffer_size_ - ( pack_head_index + package_size_one_ );
}
}
//找到包头,但缓存长度不够取包,丢弃包头之前的部分
else
{
BZROBOT_WARNNING("SiganlBoardMsg: Not whole package");
cache_buffer_size_ = cache_buffer_size_ - pack_head_index;
}
}
return BZROBOT_SIGNAL_BOARD_MSG_SUCCEED;
}
sNetPack * data_ptr_;
size_t package_size_one_;
size_t cache_buffer_size_;
const unsigned char PackageHeadValue_ = 0xA5;
const int PackageHeadByte_ = 4;
const static int CacheBufferMaxSize_ = 1024;
char cache_buffer_[CacheBufferMaxSize_];
unsigned short package_check_sum_;
bzrobot::Time last_time_;
};