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.

411 lines
10 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 "basetype.h"
#include "bufferloop.h"
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
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);
}
inline void ChangeFileNameExt(char *name, const char *ext)
{
char *p = strrchr(name, '.');
if(p) *(p+1) = 0;
strcat(name, ext);
}
//解析事件回调函数类型
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,LPVOID lp);
//数据帧编帧、解析抽象类
class CFrameAbstract : public CBufferLoop {
public:
CFrameAbstract() :
FrameLength(32), HeadLength(2), CheckLength(1), CheckPos(31), FrameType(ftNone),
bphrasing(FALSE), bFileOpen(FALSE), nFlushCount(0),
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;
}
}
protected:
UINT16 FrameLength; //帧长
UINT16 HeadLength; //帧头长度
UINT16 CheckLength; //帧内保存校验字节的长度
UINT16 CheckPos; //帧内保存校验字节的位置
TFrameType FrameType; //帧格式类型
public:
char Name[20];
BYTE Head[13];
BOOL bphrasing;
TFrameType GetFrameType(){return FrameType;}
UINT16 GetFrameLength(){return FrameLength;}
UINT16 GetHeadLength(){return HeadLength;}
private:
BOOL bFileOpen;
INT32 nFlushCount;
char strModuleName[1024];
char strAppPath[1024];
public:
char strDataPath[1024];
protected:
char strDataName[1024];
FILE * hFileOrg;
FILE * hFileCheck;
FILE * hFileNotCheck;
BOOL FullFrame() //因为没有整个256做校验排除长短帧进行查找两个
{
int HeaderPos, HeaderPos2;
HeaderPos = FindHead(0, Length() - HeadLength); //
if (0 == HeaderPos) {
//帧头在最前面
if (OnCheck()) //用256 257
DoCheck();
else {
HeaderPos2 = FindHead(HeadLength, Length() - HeadLength);
if (HeaderPos2 >= 0)
{
Drop((UINT16) HeaderPos2);
TRACE("Diu >= 0\n");
return FALSE;
}
else
{ TRACE("Diu < 0\n");
DoDropBYTE((UINT16) (Length()-(HeadLength-1)));
return TRUE;
}
}
}
else if (HeaderPos < 0)
{
//没找到帧头
DoDropBYTE((UINT16) (Length()-(HeadLength-1)));
}
else
{
//丢弃帧头前的数据
DoDropBYTE((UINT16) HeaderPos);
TRACE("Diu < 0\n");
}
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 int Count)
{
assert(Count > 0);
CountFrameAll++;
CountBYTEDrop += Count;
CountFrameDrop++;
OnDataDropFrame(Count);
Drop(Count);
}
void DoDropBYTE(const int Count)
{
if(Count <= 0) return;
assert(Count > 0);
CountBYTEDrop += Count;
OnDataDropBYTE(Count);
Drop(Count);
}
int FindHead(int Start, const int Length)
{
if((Start < 0) || (Length <=0 )) return -1;
assert((Start >= 0) && (Length > 0));
BYTE* p = Addr() + Start;
while (Start < (Length-HeadLength+1))
{
if (memcmp(p, Head, HeadLength) == 0)
return Start;
p++;
Start++;
}
return -1;
}
virtual BOOL OnCheck() //帧校验函数
{
return 1;
BYTE* p = Addr();
struCHECK ck=CheckCRC(p+2);
if (1 == CheckLength)
{
return (ck.C0== p[CheckPos]) ? TRUE : FALSE;
}
else if (2 == CheckLength)
{
return ((p[CheckPos]==ck.C1)&&(p[CheckPos+1]==ck.C0));
}
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 int Count) //无效字节段事件函数,需用户自行编制处理函数
{
if (funcDropBYTE != NULL) funcDropBYTE(this, Count);
}
virtual void OnDataDropFrame(const int 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,funcCheckParam);
Distribute();
Show();
if(bFileOpen) fwrite(Addr(), FrameLength, 1, hFileCheck);
}
public:
UINT32 funcDropBYTEParam;
UINT32 funcDropFrameParam;
UINT32 funcNotCheckParam;
LPVOID 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,LPVOID Param = NULL){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+HeadLength)) //
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 Encode(){}
virtual void Decode(){}
virtual void Distribute(){}
public:
virtual void Show(){}
};
#endif // !defined(AFX_FRAMERECIEVE_H__79D92644_4FC6_49FB_A28B_59EF7305C25A__INCLUDED_)