//#pragma once #ifndef DeliverModule_H_ #define DeliverModule_H_ #include #include #include #include #include #include #define FMT_HEADER_ONLY #include "format.h" #include "format.cc" #include "DIOS.Dev.IODevice.hpp" namespace std { using fmt::format; using fmt::format_error; using fmt::formatter; } using std::string; using std::atomic_bool; namespace DIOS::Dev::MODLE::SerialGPM { //Serial General Processing Module //日志等级 enum LOG_V2_LEVEL { LOG_V2_FATAL = 0, // Fatal Error. LOG_V2_ERROR = 1, // Error. LOG_V2_WARNING = 2, // Warning. LOG_V2_DEBUG = 3, // Debug. LOG_V2_INFO = 4 // Information. }; //通过回调函数调用上层处理函数 typedef void __stdcall SendCommands(const char* pData, unsigned long DataLength, void* ptrObj); //通过回调函数写日志 typedef void __stdcall WriteLog(const char* pData, LOG_V2_LEVEL level); //指令类型结构体 class tagCommandType { public: bool bIsFirstSend; //是否第一个发送 int nIsResend; //是否重发:0 不重发,n>0 重发n次(ACK与CP一共的) bool bIsWait; //是否等待 int nWaitingTime; //等待时间 bool bIsWaitforSelf; //是否等待自己 int nWaitingSelfTime; //等待自己时间 bool bIsWaitforACK; //是否等待ACK int nWaitingACKTime; //等待ACK时间 bool bIsWaitforCP; //是否等待CP int nWatingCPTime; //等待CP时间 bool bIsClearSendVector; //是否清空发送队列 bool bIsClearSamePriority; //是否清除同样的优先级 bool bIsReplace; //是否替换CMD头相同的指令 bool bIsPrintLog; //是否打印日志 tagCommandType(bool isPrintLog = false, bool isFirstSend = false, int isResend = 0, bool isWait = false, int waitingTime = 0, bool isWaitforSelf = false, int watingSelfCPtime = 0, bool isWaitforACK = false, int waitingACKTime = 0, bool isWaitforCP = false, int watingCPtime = 0, bool isClearSendVector = false, bool isClearSamePriority = false, bool isReplace = true); bool operator ==(const tagCommandType& value); }; //发送指令结构体 struct tagCommandStruct { string strCommand; //指令内容 int nCommmandType; //指令类型:tagCommandType list number tagCommandStruct(); tagCommandStruct(string& cmd, int type); tagCommandStruct(char* cmd, int lengh, int type); tagCommandStruct& operator =(const tagCommandStruct& value); }; //串口处理层 class CDeliverModule { public: CDeliverModule(); ~CDeliverModule(void); public://发送线程相关的函数 bool InitSendModle(void* ptrObj, SendCommands* pSendData, WriteLog * logFun = NULL); void EixtSendModle(); //设置日志回调函数 bool SetLogFun(WriteLog* logFun); //设置优先级: 依次设置指令类型,默认包含一个等级 0,代表直接发送无等待 int SetPriority(bool isPrintLog = false, bool isFirstSend = false, int isResend = 0, bool isWait = false, int waitingTime = 0, bool isWaitforSelf = false, int watingSelftime = 0, bool isWaitforACK = false, int waitingACKTime = 0, bool isWaitforCP = false, int watingCPtime = 0, bool isClearSendVector = false, bool isClearSamePriority = false); int SetPriority_V2(bool isWaitforACK = true, int waitingACKTime = 350, bool isResend = true, bool isClearSendVector = false, bool isFirstSend = false, bool isWaitforCP = false, int watingCPtime = 3000, bool isClearSamePriority = false); //设置优先级指令是否替换指令头相同的指令 int SetPriority_Replace(int nPriority, bool isReplace); //设置发送指令 RET_STATUS ProcessCommand(string strCommand, int nType = 0, int nCMDHeadLengh = 0); RET_STATUS ProcessCommand(char* strCommand, int nLengh, int nType = 0, int nCMDHeadLengh = 0); //设置ACK,CP指令头 void SetACKCMDHead(char* strCommand, int nLengh); void SetCPCMDHead(char* strCommand, int nLengh); void SetSpeSelfHead(map cmdHeadmap); //设置设备处于错误 void SetCurrentStatus(bool isUnitState); //获取当前错误 bool GetCurrentState(); //获取当前处理指令 string GetCurrentCommand(); //获取当前命令优先级 int GetCurrentCommandPriority(); //收到返回 bool CheckReceive(const char * cmd, int nCMDHeadLengh = 0); void ReceiveSelf(bool isPrintLog = true); void ReceiveACK(bool IsACK = true, bool isPrintLog = true); void ReceiveCP(bool IsCP = true, bool isPrintLog = true); private: //开启发送线程 bool StartSendingCommandsThread(); void StopSendingCommandsThread(); void SendCommand(string strcommand, int commandtype, bool isPrintLog = true); static DWORD SendingCommandsThread(LPVOID pParam); bool ReProcessCommand(tagCommandStruct strCommand); void* m_ClientControl; //模块对象 SendCommands* m_pSendData; //发送数据 WriteLog* m_pLogFun; //日志记录接口 HANDLE m_hSendingThreadToggleEvent; //发送事件 HANDLE m_SendingCommandsThread; //发送线程 //int m_nSendingCommandsThreadId; //发送线程ID atomic_bool m_bSendingCommandsThreadExit; //发送线程退出标志 std::mutex m_iCriticalSection; //指令队列锁 std::deque m_Commondvector; //指令发送队列 std::vector m_CommondType; //指令类型队列 string m_strACKHead; //设置ACK指令头 string m_strCPHead; //设置CP指令头 map m_SpeSelfMap; //设置特殊Self指令头对照表(适用于发送的指令头与返回的指令头不同,且区别于ACK、CP这种固定的返回头的情况) tagCommandStruct m_strcurrentcmd; //当前指令 HANDLE m_hSelfEvent; //Self事件 HANDLE m_hACKEvent; //ACK事件 HANDLE m_hCPEvent; //CP事件 int m_nRsubmit; //当前重试次数 atomic_bool m_bSendEnable; //设备是否可发送 HANDLE m_hUnitStateChangeEvent; //设备状态变更事件 }; } #endif