#pragma once #define SCF_API #define SCF_C_API extern "C" #include #include #include #include "ResDataObject.h" #include "CcosLock.h" #include "CcosThread.h" typedef enum _SCF_Error { SCF_UNKNOWN = -99, SCF_NOMEMORY, SCF_OPEN_FAILED,//打开端口失败 SCF_READ_FAILED,//读失败 SCF_WRITE_FAILED,//写失败 SCF_DISCONNETED,//连接断开 SCF_LOCK_FAILED,//锁失败 SCF_BUSY,//被占用 SCF_PARAMETER_ERR,//连接参数不对 SCF_OVERFLOW, SCF_NOPACKET, SCF_TIMEOUT, SCF_FAILED = 0, SCF_SUCCEED } SCF_ERR; typedef enum _Packet_Result { PACKET_USELESS = -1,//不需要的数据包,直接丢弃 PACKET_NOPACKET,//没有数据包 PACKET_ISPACKET//有数据包 } PACKET_RET; typedef enum _SCF_Transfertype { SCF_PACKET_TRANSFER = 0,//使用DeQueNotifyPacket&QueNotifyPacket SCF_NORMAL_TRANSFER//使用通用读取方式 } SCF_TRANSFERTYPE; typedef PACKET_RET(*PacketParser)(const char* pRecData, uint32_t nLength, uint32_t& PacketLength); SCF_C_API void* MallocSCFPacket();//申请SCFPACKET SCF_C_API void ReleaseSCFPacket(void* pObj);//释放SCFPACKET class SCF_API SCFPacket { protected: char* m_PacketBuff; uint32_t m_PacketBuffLen; uint32_t m_PacketLength; bool ReAlloc(uint32_t BaseLen); public: SCFPacket(); SCFPacket(char* pData, uint32_t Length); virtual ~SCFPacket(); bool SetBuffLen(uint32_t Len); uint32_t GetBuffLen(); SCFPacket& operator = (const SCFPacket& tValue); int SetPacket(const char* pData, uint32_t Length); int AddTail(const char* pData, uint32_t Length); void SetPacketLen(uint32_t Len); uint32_t GetPacketLen(); operator char* (); int GetPacket(char* pData, uint32_t Length); }; class SCF_API SCFBuffer : public CcosLock { uint32_t m_CurPacketIdx; SCFPacket* m_pPacket[2]; public: SCFBuffer(); ~SCFBuffer(); bool SetBuff(uint32_t Len); int Add(const char* data, uint32_t len); int Del(uint32_t len); const char* GetBuff(); uint32_t GetPacketLen(); void ClearData(); }; class SCF_API SCF : public CcosLock, public Ccos_Thread { public: SCF(void); virtual ~SCF(); void* m_LibHandle; PacketParser m_pPacketParser; SCF_TRANSFERTYPE m_TransferType; //根路径是SCF路径,pFileName是偏移值,如 "COM\COM2.log" void InitSCF(const char* pLogFileName = NULL); //设置本地属性 特定通信情况下需要,串口,网络,USB的连接不需要设置 bool SetSourceAttribute(ResDataObject& Sourceprameters); //设置连接,参数也由json传过来 /* -- 串口类型 { "type":"COM", "port":"COM1", "baudrate":"3200", "bytesize":"8", "parity":"1", "stopbits":"1" } */ /* -- 网络类型 { "type":"TCPIP", "ip":"192.168.2.77", "port":"2020" } */ void SetBuffersize(uint32_t NormalPackSize, uint32_t MaxBuffLimit); virtual int Connect(ResDataObject& Connectprameters, PacketParser callback, SCF_TRANSFERTYPE TransferType = SCF_NORMAL_TRANSFER, uint32_t CommunicateTimeout = 0); //断开连接 virtual void Disconnect(); //判断是否连接 virtual bool isConnected(); //获取连接类型,由继承类实现 virtual const char* GetConnectionType(); //获取连接参数 ResDataObject GetConnectionAttributes(); //发数据 virtual int SendPacket(const char* pPacket, uint32_t length, uint32_t timeout); virtual int SendPacket(SCFPacket* pPacket, uint32_t timeout); //读数据 int ReceivePacket(char* pPacket, uint32_t length, uint32_t timeout); int ReceivePacket(SCFPacket* pPacket, uint32_t timeout); uint32_t GetReceivePacketSize(); uint32_t GetNotifyPacketSize(); //获取SCF收到Notify后通知的事件句柄 ////将不需要的数据包存入Notify数据缓存队列 int QueNotifyPacket(const char* pPacket, uint32_t length); int QueNotifyPacket(SCFPacket* pPacket); //读取Notify数据缓存中的数据包,当SCF处于解锁状态下接收的数据都会放入Notify缓存中,需要调用DeQueNotifyPacket来读取缓存中的数据包,读取成功返回接收数据的实际长度,失败返回SCF_ERR int DeQueNotifyPacket(char* pPacket, uint32_t length, uint32_t timeout); int DeQueNotifyPacket(SCFPacket* pPacket, uint32_t timeout); //SCF的锁 uint32_t SCFLock(uint32_t timeout); void SCFUnLock(); //被动掉线事件 void PassiveDisconnected(); uint32_t GetCommunicateTimeout(); protected: pthread_cond_t m_NotifyCond; pthread_cond_t m_ReceiveCond; pthread_mutex_t m_NotifyMutex; pthread_mutex_t m_ReceiveMutex; bool m_NotifyFlag; bool m_ReceiveFlag; uint32_t m_CommunicateTimeout; ResDataObject m_ConnectionParams; uint32_t MaxComLen; uint32_t NormalPackLen; uint32_t ReadWaitTime; SCFBuffer m_RawBuffer; SCFPacket* m_pTransferBuffer; SCFPacket* m_pRtoNBuffer; void* m_pNotifybuffer; void* m_pReceivebuffer; bool StartSCFServer(); void StopSCFServer(); int ProcessCmd(const char* data, int datalength); int ReceivetoNotify(); int ReceivetoNotify_Ex(); int WritetoNotify(const char* pPacket, int length); virtual bool Exec(); int ReadData(char* pPacket, uint32_t length, uint32_t timeout); }; SCF_C_API SCF* LoadScf(const char* pFilename); SCF_C_API void UnLoadScf(SCF* pHandle); typedef SCF* (*GetSCF_Proc)(); typedef void (*ReleaseSCF_Proc)(SCF*);