You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PayloadAPP/Src/include/FrameRecieve.h

596 lines
15 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#ifndef __FRAME_RECIEVE_H
#define __FRAME_RECIEVE_H
#include "framelib/basetype.h"
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <math.h>
#define ROUND_INT8(v) ((INT8)((floor)(v+0.5)))
#define ROUND_UINT8(v) ((UINT8)((floor)(v+0.5)))
#define ROUND_INT16(v) ((INT16)((floor)(v+0.5)))
#define ROUND_UINT16(v) ((UINT16)((floor)(v+0.5)))
#define ROUND_INT32(v) ((INT32)((floor)(v+0.5)))
#define ROUND_UINT32(v) ((UINT32)((floor)(v+0.5)))
const BYTE FLAG_PLAT = 0xE0;
const BYTE PLAT_Manual = 0x00 << 5;
const BYTE PLAT_Auto = 0x01 << 5;
const BYTE PLAT_Locking = 0x02 << 5;
const BYTE PLAT_Leading = 0x03 << 5;
const BYTE PLAT_Scaning = 0x04 << 5;
const BYTE PLAT_Reseting = 0x05 << 5;
const BYTE PLAT_Init = 0x06 << 5;
const BYTE FLAG_TRACKER = 0x1C;
const BYTE TRACKER_Normal = 0x00 << 2;
const BYTE TRACKER_Error = 0x01 << 2;
const BYTE TRACKER_Lost = 0x02 << 2;
const BYTE TRACKER_Corr = 0x03 << 2;
const BYTE TRACKER_GBlack = 0x04 << 2;
const BYTE TRACKER_GWhite = 0x05 << 2;
const BYTE TRACKER_ShowFreeze = 0x06 << 2;
const BYTE TRACKER_Freeze = 0x07 << 2;
const BYTE FLAG_LIFTER = 0x03;
const BYTE LIFTER_Top = 0x00;
const BYTE LIFTER_Bottom = 0x01;
const BYTE LIFTER_Uping = 0x02;
const BYTE LIFTER_Downing = 0x03;
const BYTE FLAG_EO = 0xC0;
const BYTE EO_Working = 0x00 << 6;
const BYTE EO_Error = 0x01 << 6;
const BYTE EO_Heating = 0x02 << 6;
const BYTE EO_Heated = 0x03 << 6;
const BYTE FLAG_PAYLOAD = 0x20;
const BYTE PAYLOAD_EO = 0x00 << 5;
const BYTE PAYLOAD_HW = 0x01 << 5;
const BYTE FLAG_HW = 0x18;
const BYTE HW_Working = 0x00 << 3;
const BYTE HW_Error = 0x01 << 3;
const BYTE HW_Manual = 0x02 << 3;
const BYTE HW_Auto = 0x03 << 3;
const BYTE FLAG_LASER = 0x07;
const BYTE LASER_Normal = 0x00;
const BYTE LASER_Error = 0x01;
const BYTE LASER_Close = 0x02;
const BYTE LASER_Standby = 0x03;
const BYTE LASER_On = 0x04;
const BYTE LASER_Off = 0x05;
const double AngRatiode = 360.0 / 65535.0;
const double AngRatioen = 65535.0 / 360.0;
typedef enum { ftFJu, //按飞机平台上行协议校验
ftFJd, //按飞机平台下行协议校验
ftEOu, //按稳定平台上行协议校验
ftEOd, //按稳定平台下行协议校验
ftCJu, //按测距测角上行协议校验
ftCJd, //按测距测角下行协议校验
ftQBu, //按情报上行协议校验
ftQBd, //按情报下行协议校验
ftCKd, //按测控下行协议校验
ftSFu, ftSFd, ftFKu, ftFKd, ftEOGCSu, ftEOSBu, ftTXd, ftTXd_8B, ftTXd_8B_SM, ftTXd_8B_SAR, //图像复接数据协议
ftEOU_8B,
ftMIMUu, //MIMU上行协议数据协议
ftMIMUd, //MIMU下行协议数据协议
ftGPSu, //GPS上行协议数据协议
ftGPSd, //GPS下行协议数据协议
ftBDu, //北斗上行协议数据协议
ftBDd, //北斗下行协议数据协议
ftPOWERu, //飞控计算机发送到电源管理器的数据帧
ftPOWERd, //电源管理器发送到飞控计算机的数据帧
ftOILu, //飞控计算机发送到油量传感器的数据帧
ftOILd, //油量传感器发送到飞控计算机的数据帧
ftMAGu, //飞控计算机发送到电子罗盘的数据帧
ftMAGd, //电子罗盘发送到飞控计算机的数据帧
ftGKu, //飞控计算机发送到高度/空速传感器的数据帧
ftGKd, //高度/空速传感器发送到飞控计算机的数据帧
ftNone //自定义校验
} TFrameType;
inline double RoundMax(double v, double vmax)
{
return fmod(v, vmax);
// while (v < 0)
// v += vmax;
// while (v > vmax)
// v -= vmax;
// return v;
}
inline void ChangeFileNameExt(char *name, const char *ext)
{
char *p = strrchr(name, '.');
if(p) *(p+1) = 0;
strcat(name, ext);
}
//循环缓冲区类
class CBufferLoop {
private:
int FSize; //缓冲区大小
int FStart; //有效数据头
int FEnd; //有效数据尾
int FLength; //有效数据长度
BYTE* FBuffer; //缓冲区地址
protected:
INT16 Append(const unsigned char* Src, const UINT32 alen)
{
INT16 len = (alen > (UINT32) FSize) ? FSize : (INT16) alen;
assert(len > 0);
//缓存剩余空间不够Length
if ((len + FLength) >= FSize)
len = FSize - FLength;
if ((len + FEnd) >= FSize) {
//缓存内数据块后部空间不够Length将数据块移到缓存首地址
memcpy(FBuffer, FBuffer + FStart, FLength);
FStart = 0;
FEnd = FLength;
}
memcpy(FBuffer + FEnd, Src, len);
FEnd += len;
FLength += len;
return len;
}
void Drop(const UINT16 len)
{
assert(len > 0);
if (len > FLength) {
FStart = 0;
FEnd = 0;
FLength = 0;
} else {
FStart += len;
FLength -= len;
}
}
int Size(){return FSize;}
int Length(){return FLength;}
public:
CBufferLoop() : FSize(1000), FStart(0), FEnd(0), FLength(0), FBuffer(0)
{
FBuffer = new unsigned char[FSize];
memset(FBuffer, 0, FSize);
};
CBufferLoop(const CBufferLoop& abl)
: FSize(abl.FSize), FStart(abl.FStart), FEnd(abl.FEnd),
FLength(abl.FLength), FBuffer(0)
{
FBuffer = new unsigned char[FSize];
memcpy(FBuffer, abl.FBuffer, FSize);
}
virtual ~CBufferLoop(){
delete[] FBuffer;
FBuffer = 0;
}
CBufferLoop& operator=(const CBufferLoop& abl)
{
if (this == &abl)
return *this; // 见条款17
if (FBuffer)
delete[] FBuffer;
FSize = abl.FSize;
FStart = abl.FStart;
FEnd = abl.FEnd;
FLength = abl.FLength;
FBuffer = new unsigned char[FSize];
memcpy(FBuffer, abl.FBuffer, FSize);
return *this;
}
BYTE* const Addr() {return FBuffer + FStart;}
void Reset()
{
memset(FBuffer, 0, FSize);
FStart = 0;
FEnd = 0;
FLength = 0;
}
};
class CSimpleCriticalSection {
private:
CRITICAL_SECTION FSection;
public:
CSimpleCriticalSection(){InitializeCriticalSection(&FSection);}
virtual ~CSimpleCriticalSection(){DeleteCriticalSection(&FSection);}
void Enter(){EnterCriticalSection(&FSection);}
void Leave(){LeaveCriticalSection(&FSection);}
};
//解析事件回调函数类型
class CFrameAbstract;
typedef void (CALLBACK *FLDropBYTECALLBACK)(CFrameAbstract* frm, UINT16 Count);
typedef void (CALLBACK *FLDropFrameCALLBACK)(CFrameAbstract* frm, UINT16 Count);
typedef void (CALLBACK *FLNotCheckCALLBACK)(CFrameAbstract* frm);
typedef void (CALLBACK *FLCheckCALLBACK)(CFrameAbstract* frm);
//数据帧编帧、解析抽象类
class CFrameAbstract : public CBufferLoop {
public:
CFrameAbstract() :
FrameLength(32),
HeadLength(2),
CheckLength(1),
CheckPos(31),
FrameType(ftNone),
bphrasing(FALSE),
bFileOpen(FALSE),
nFlushCount(0),
cs(new CSimpleCriticalSection()),
hFileOrg(NULL),
hFileCheck(NULL),
hFileNotCheck(NULL),
funcDropBYTE(NULL),
funcDropFrame(NULL),
funcNotCheck(NULL),
funcCheck(NULL),
CountBYTEAll(0),
CountBYTEDrop(0),
CountFrameAll(0),
CountFrameCheck(0),
CountFrameNotCheck(0),
CountFrameDrop(0),
funcDropBYTEParam(NULL),
funcDropFrameParam(NULL),
funcNotCheckParam(NULL),
funcCheckParam(NULL)
{};
virtual ~CFrameAbstract(){
funcDropBYTE = NULL;
funcDropFrame = NULL;
funcNotCheck = NULL;
funcCheck = NULL;
funcDropBYTEParam = NULL;
funcDropFrameParam = NULL;
funcNotCheckParam = NULL;
funcCheckParam = NULL;
while (TRUE == bphrasing){
Sleep(100);
}
if(bFileOpen){
fclose(hFileOrg);
fclose(hFileCheck);
fclose(hFileNotCheck);
bFileOpen = FALSE;
}
delete cs;
}
protected:
UINT16 FrameLength; //帧长
UINT16 HeadLength; //帧头长度
UINT16 CheckLength; //帧内保存校验字节的个数
UINT16 CheckPos; //帧内保存校验字节的位置
TFrameType FrameType; //帧格式类型
public:
char Name[20];
BYTE Head[12];
TFrameType GetFrameType(){return FrameType;}
UINT16 GetFrameLength(){return FrameLength;}
UINT16 GetHeadLength(){return HeadLength;}
private:
BOOL bphrasing;
BOOL bFileOpen;
INT32 nFlushCount;
CSimpleCriticalSection* cs;
char strModuleName[1024];
char strAppPath[1024];
public:
char strDataPath[1024];
protected:
char strDataName[1024];
FILE * hFileOrg;
FILE * hFileCheck;
FILE * hFileNotCheck;
virtual BOOL FullFrame()
{
int HeaderPos, HeaderPos2;
HeaderPos = FindHead(0, Length() - HeadLength);
if (0 == HeaderPos){
//帧头在最前面
if (OnCheck()){
DoCheck();
}
else //校验没通过
{
HeaderPos2 = FindHead(HeadLength, Length() - HeadLength);
if ((HeaderPos2 >= 0) && (HeaderPos2 < FrameLength))
{
DoDropFrame((UINT16) HeaderPos2);
}
else if (HeaderPos2 < 0)
{
if (Length() <= FrameLength + (HeadLength - 1))
{
if (HeadLength == 1)
DoNotCheck();
else
{
BYTE* p = Addr();
if (p[FrameLength - (HeadLength - 1)] != Head[0])
DoNotCheck();
else
return TRUE;
}
} else
DoNotCheck();
}
else
{
DoNotCheck();
}
}
} else if (HeaderPos < 0) {
//没找到帧头
DoDropBYTE((UINT16) (FrameLength - HeadLength));
} else {
//丢弃帧头前的数据
DoDropBYTE((UINT16) HeaderPos);
}
return FALSE;
}
void DoCheck()
{
assert(FrameLength > 0);
++CountFrameAll;
++CountFrameCheck;
OnDataCheck();
Drop(FrameLength);
}
void DoNotCheck()
{
assert(FrameLength > 0);
++CountFrameAll;
CountBYTEDrop += FrameLength;
++CountFrameNotCheck;
OnDataNotCheck();
Drop(FrameLength);
}
void DoDropFrame(const UINT16 Count)
{
assert(Count > 0);
++CountFrameAll;
CountBYTEDrop += Count;
++CountFrameDrop;
OnDataDropFrame(Count);
Drop(Count);
}
void DoDropBYTE(const UINT16 Count)
{
assert(Count > 0);
CountBYTEDrop += Count;
OnDataDropBYTE(Count);
Drop(Count);
}
int FindHead(int Start, const int Length)
{
assert((Start >= 0) && (Length > 0));
BYTE* p = Addr() + Start;
while (Start < Length) {
if (memcmp(p, Head, HeadLength) == 0)
return Start;
++p;
++Start;
}
return -1;
}
virtual BOOL OnCheck() //帧校验函数
{
BYTE* p = Addr();
struCHECK ck=CheckCRC(p);
if (1 == CheckLength)
{
return (ck.C0== p[CheckPos]) ? TRUE : FALSE;
}
else if (2 == CheckLength)
{
return ((p[CheckPos]==ck.C0)&&(p[CheckPos+1]==ck.C1));
}
else
{
return false;
}
}
protected:
FLDropBYTECALLBACK funcDropBYTE;
FLDropFrameCALLBACK funcDropFrame;
FLNotCheckCALLBACK funcNotCheck;
FLCheckCALLBACK funcCheck;
INT32 CountBYTEAll; //接收到的全部字节数
INT32 CountBYTEDrop; //丢弃的字节数
INT32 CountFrameAll; //全部帧计数
INT32 CountFrameCheck; //有效帧计数
INT32 CountFrameNotCheck; //校验错的帧计数
INT32 CountFrameDrop; //短帧计数
virtual void OnDataDropBYTE(const UINT16 Count) //无效字节段事件函数,需用户自行编制处理函数
{
if (funcDropBYTE != NULL) funcDropBYTE(this, Count);
}
virtual void OnDataDropFrame(const UINT16 Count) //短帧事件函数,需用户自行编制处理函数
{
if (funcDropFrame != NULL) funcDropFrame(this, Count);
}
virtual void OnDataNotCheck() //帧校验错事件函数,需用户自行编制处理函数
{
//Decode();
if (funcNotCheck != NULL) funcNotCheck(this);
//Distribute();
//Show();
if(bFileOpen) fwrite(Addr(), FrameLength, 1, hFileNotCheck);
}
virtual void OnDataCheck() //有效帧事件函数,需用户自行编制处理函数
{
Decode();
if (funcCheck != NULL) funcCheck(this);
Distribute();
Show();
if(bFileOpen) fwrite(Addr(), FrameLength, 1, hFileCheck);
}
public:
UINT32 funcDropBYTEParam;
UINT32 funcDropFrameParam;
UINT32 funcNotCheckParam;
UINT32 funcCheckParam;
void SetDropBYTECallback(FLDropBYTECALLBACK fun, UINT32 Param = 0){ funcDropBYTE = fun; funcDropBYTEParam = Param;}
void SetDropFrameCallback(FLDropFrameCALLBACK fun, UINT32 Param = 0){ funcDropFrame = fun; funcDropFrameParam = Param;}
void SetNotCheckCallback(FLNotCheckCALLBACK fun, UINT32 Param = 0){ funcNotCheck = fun; funcNotCheckParam = Param;}
void SetCheckCallback(FLCheckCALLBACK fun, UINT32 Param = 0){ funcCheck = fun; funcCheckParam = Param;}
void SetSaveStatus(BOOL IsSave, const char *name = NULL)
{
if(IsSave){
GetModuleFileName(GetModuleHandle(NULL), strModuleName, 1024);
char *p = strrchr(strModuleName, '\\');
if(p) strncpy(strAppPath, strModuleName, p - strModuleName);
else strcpy(strAppPath, strModuleName);
time_t ltime;
struct tm *t;
time( &ltime );
t = localtime( &ltime );
sprintf(strDataPath, "%s\\RecordOrg-%04d%02d%02d", strAppPath, t->tm_year, t->tm_mon, t->tm_mday);
char temp[1024];
sprintf(temp, "%04d%02d%02d %02d%02d%02d", t->tm_year + 1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
CreateDirectory((LPCSTR)strDataPath, NULL);
if(name == NULL){
sprintf(strDataName, "%s\\%s-%s.dat", strDataPath, temp, Name);
}
else{
sprintf(strDataName, "%s\\%s-%s.dat", strDataPath, temp, name);
}
if((hFileOrg = fopen(strDataName, "wb")) != NULL){
strcpy(temp, strDataName);
ChangeFileNameExt(temp,"chk");
if((hFileCheck = fopen(temp, "wb")) != NULL){
strcpy(temp, strDataName);
ChangeFileNameExt(temp,"err");
if((hFileNotCheck = fopen(temp, "wb")) != NULL){
bFileOpen = TRUE;
}
else{
fclose(hFileCheck);
fclose(hFileOrg);
}
bFileOpen = TRUE;
}
else{
fclose(hFileOrg);
}
}
}
else{
if(bFileOpen){
fclose(hFileOrg);
fclose(hFileCheck);
fclose(hFileNotCheck);
bFileOpen = FALSE;
}
}
}
void ResetCount()
{
//用于计数清零
CountBYTEAll = 0L;
CountBYTEDrop = 0L;
CountFrameAll = 0L;
CountFrameCheck = 0L;
CountFrameNotCheck = 0L;
CountFrameDrop = 0L;
}
void Phrase(const BYTE* Src, const UINT32 Count)
{
cs->Enter();
int ReadCount;
UINT32 LeftCount = Count;
const BYTE* psrc = Src;
bphrasing = TRUE;
while (LeftCount > 0)
{
ReadCount = Append(psrc, LeftCount);
psrc += ReadCount;
LeftCount -= ReadCount;
CountBYTEAll += ReadCount;
while (Length() >= FrameLength)
if (FullFrame())
break;
}
try{
if(bFileOpen)
{
fwrite(Src, Count, 1, hFileOrg);
if((CountBYTEAll - nFlushCount) > 40960)
{
fflush(hFileOrg);
fflush(hFileCheck);
fflush(hFileNotCheck);
nFlushCount = CountBYTEAll;
}
}
}
catch (...)
{
cs->Leave();
bphrasing = FALSE;
}
cs->Leave();
bphrasing = FALSE;
}
INT32 GetCountBYTEAll(){return CountBYTEAll;}
INT32 GetCountBYTEDrop(){return CountBYTEDrop;}
INT32 GetCountFrameAll(){return CountFrameAll;}
INT32 GetCountFrameCheck(){return CountFrameCheck;}
INT32 GetCountFrameNotCheck(){return CountFrameNotCheck;}
INT32 GetCountFrameDrop(){return CountFrameDrop;}
//output
protected:
virtual void FrameCrc(BYTE* p)
{
struCHECK ck=CheckCRC(p);
if (CheckLength==1)
{
p[CheckPos]=ck.C0;
}
if (CheckLength==2)
{
p[CheckPos] = ck.C0;
p[CheckPos+1]=ck.C1;
}
}
public:
virtual BYTE* SendPrepare()
{
BYTE* po;
po = Addr();
Encode();
FrameCrc(po);
return(po);
}
virtual struCHECK CheckCRC(BYTE* const p) = 0;
protected:
virtual void Decode(){}
virtual void Distribute(){}
virtual void Encode(){}
public:
virtual void Show(){}
};
#endif // !defined(AFX_FRAMERECIEVE_H__79D92644_4FC6_49FB_A28B_59EF7305C25A__INCLUDED_)