#ifndef __FRAME_RECIEVE_H #define __FRAME_RECIEVE_H #include "framelib/basetype.h" #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include #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( <ime ); t = localtime( <ime ); 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_)