SCF.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. #pragma once
  2. // 下列 ifdef 块是创建使从 DLL 导出更简单的
  3. // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 SCF_EXPORTS
  4. // 符号编译的。在使用此 DLL 的
  5. // 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
  6. // SCF_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
  7. // 符号视为是被导出的。
  8. #ifndef SCF_EXPORTS
  9. #ifdef _WIN64
  10. #ifdef _DEBUG
  11. #pragma comment(lib, "SCFX64D.lib")
  12. #else
  13. #pragma comment(lib, "SCFX64.lib")
  14. #endif
  15. #else
  16. #ifdef _DEBUG
  17. #pragma comment(lib, "SCFD.lib")
  18. #else
  19. #pragma comment(lib, "SCF.lib")
  20. #endif
  21. #endif
  22. #endif
  23. #ifdef SCF_EXPORTS
  24. #define SCF_API __declspec(dllexport)
  25. #define SCF_C_API extern "C" __declspec(dllexport)
  26. #else
  27. #define SCF_API __declspec(dllimport)
  28. #define SCF_C_API extern "C" __declspec(dllimport)
  29. #endif
  30. #include "ResDataObject.h"
  31. #include "DiosLock.h"
  32. #include "logger.h"
  33. #include "DiosThread.h"
  34. typedef enum _SCF_Error {
  35. SCF_UNKNOWN=-99,
  36. SCF_NOMEMORY,
  37. SCF_OPEN_FAILED,//打开端口失败
  38. SCF_READ_FAILED,//读失败
  39. SCF_WRITE_FAILED,//写失败
  40. SCF_DISCONNETED,//连接断开
  41. SCF_LOCK_FAILED,//锁失败
  42. SCF_BUSY,//被占用
  43. SCF_PARAMETER_ERR,//连接参数不对
  44. SCF_OVERFLOW,
  45. SCF_NOPACKET ,
  46. SCF_TIMEOUT,
  47. SCF_FAILED = 0,
  48. SCF_SUCCEED
  49. }SCF_ERR;
  50. typedef enum _Packet_Result {
  51. PACKET_USELESS = -1,//不需要的数据包,直接丢弃
  52. PACKET_NOPACKET,//没有数据包
  53. PACKET_ISPACKET//有数据包
  54. }PACKET_RET;
  55. typedef enum _SCF_Transfertype {
  56. SCF_PACKET_TRANSFER = 0,//使用DeQueNotifyPacket&QueNotifyPacket
  57. SCF_NORMAL_TRANSFER //使用通用读取方式
  58. }SCF_TRANSFERTYPE;
  59. typedef PACKET_RET(*PacketParser)(const char * pRecData, DWORD nLength, DWORD & PacketLength);
  60. SCF_C_API PVOID MallocSCFPacket();//申请SCFPACKET
  61. SCF_C_API void ReleaseSCFPacket(PVOID pObj);//释放SCFPACKET
  62. // 此类是从 SCF.dll 导出的
  63. class SCF_API SCFPacket
  64. {
  65. protected:
  66. char* m_PacketBuff;
  67. DWORD m_PacketBuffLen;
  68. DWORD m_PacketLength;
  69. bool ReAlloc(DWORD BaseLen);
  70. public:
  71. SCFPacket();
  72. SCFPacket(char* pData, DWORD Length);
  73. virtual ~SCFPacket();
  74. bool SetBuffLen(DWORD Len);
  75. DWORD GetBuffLen();
  76. SCFPacket& operator = (const SCFPacket &tValue);
  77. int SetPacket(const char* pData, DWORD Length);
  78. int AddTail(const char* pData, DWORD Length);
  79. void SetPacketLen(DWORD Len);
  80. DWORD GetPacketLen();
  81. operator char*();
  82. int GetPacket(char* pData, DWORD Length);
  83. };
  84. class SCF_API SCFBuffer : public DiosLock
  85. {
  86. DWORD m_CurPacketIdx;
  87. SCFPacket *m_pPacket[2];
  88. public:
  89. SCFBuffer();
  90. ~SCFBuffer();
  91. bool SetBuff(DWORD Len);
  92. int Add(const char * data, DWORD len);
  93. int Del(DWORD len);
  94. const char *GetBuff();
  95. DWORD GetPacketLen();
  96. void ClearData();
  97. };
  98. class SCF_API SCF : public DiosLock, public Dios_Thread
  99. {
  100. public:
  101. SCF(void);
  102. virtual ~SCF();
  103. HMODULE m_LibHandle;
  104. Logger *m_pSCFLogger;
  105. PacketParser m_pPacketParser;
  106. SCF_TRANSFERTYPE m_TransferType;
  107. //根路径是SCF路径,pFileName是偏移值,如 "COM\COM2.log"
  108. void InitSCF(const char *pLogFileName = NULL);
  109. //设置本地属性 特定通信情况下需要,串口,网络,USB的连接不需要设置
  110. bool SetSourceAttribute(ResDataObject & Sourceprameters) ;
  111. //设置连接,参数也由json传过来
  112. /* -- 串口类型
  113. {
  114. "type":"COM",
  115. "port":"COM1",
  116. "baudrate":"3200",
  117. "bytesize":"8",
  118. "parity":"1",
  119. "stopbits":"1"
  120. }
  121. */
  122. /* -- 网络类型
  123. {
  124. "type":"TCPIP",
  125. "ip":"192.168.2.77",
  126. "port":"2020"
  127. }
  128. */
  129. void SetBuffersize(DWORD NormalPackSize, DWORD MaxBuffLimit);
  130. virtual int Connect(ResDataObject & Connectprameters, PacketParser callback, SCF_TRANSFERTYPE TransferType = SCF_NORMAL_TRANSFER, DWORD CommunicateTimeout = 0);
  131. //断开连接
  132. virtual void Disconnect();
  133. //判断是否连接
  134. virtual bool isConnected() ;
  135. //获取连接类型,由继承类实现
  136. virtual const char* GetConnectionType();
  137. //获取连接参数
  138. ResDataObject GetConnectionAttributes();
  139. //发数据
  140. virtual int SendPacket(const char *pPacket, DWORD length, DWORD timeout);
  141. virtual int SendPacket(SCFPacket *pPacket, DWORD timeout);
  142. //读数据
  143. int ReceivePacket(char *pPacket, DWORD length, DWORD timeout);
  144. int ReceivePacket(SCFPacket *pPacket, DWORD timeout);
  145. DWORD GetReceivePacketSize();
  146. DWORD GetNotifyPacketSize();
  147. HANDLE GetScfNotifyHandle() ;//获取SCF收到Notify后通知的事件句柄
  148. ////将不需要的数据包存入Notify数据缓存队列
  149. int QueNotifyPacket(const char *pPacket, DWORD length);
  150. int QueNotifyPacket(SCFPacket *pPacket);
  151. //读取Notify数据缓存中的数据包,当SCF处于解锁状态下接收的数据都会放入Notify缓存中,需要调用DeQueNotifyPacket来读取缓存中的数据包,读取成功返回接收数据的实际长度,失败返回SCF_ERR
  152. int DeQueNotifyPacket(char *pPacket, DWORD length, DWORD timeout);
  153. int DeQueNotifyPacket(SCFPacket *pPacket, DWORD timeout);
  154. //SCF的锁
  155. DWORD SCFLock(DWORD timeout);
  156. void SCFUnLock();
  157. //被动掉线事件
  158. void SetPassiveDisconnectEvt(HANDLE evt);
  159. void PassiveDisconnected();
  160. DWORD GetCommunicateTimeout();
  161. protected:
  162. HANDLE m_PassiveDisconEvt;
  163. OVERLAPPED m_osRead;
  164. OVERLAPPED m_osWrite;
  165. // TODO: 在此添加您的方法。
  166. virtual int ReadData(char *pPacket, DWORD length, DWORD timeout);
  167. //virtual int ReadData(SCFPacket *pPacket, DWORD timeout);
  168. DWORD m_CommunicateTimeout;
  169. ResDataObject m_ConnectionParams;
  170. //---------------server part
  171. DWORD MaxComLen;
  172. DWORD NormalPackLen;
  173. DWORD ReadWaitTime;
  174. SCFBuffer m_RawBuffer;
  175. SCFPacket* m_pTransferBuffer;//将Receive数据转入Notify
  176. SCFPacket* m_pRtoNBuffer;//将Receive数据转入Notify
  177. bool StartSCFServer();//开启读线程
  178. void StopSCFServer();//关闭读线程
  179. int ProcessCmd(const char * data, int datalength);
  180. int ReceivetoNotify();
  181. int ReceivetoNotify_Ex();
  182. int WritetoNotify(const char *pPacket, int length);
  183. virtual bool Exec();
  184. PVOID m_pNotifybuffer;
  185. PVOID m_pReceivebuffer;
  186. HANDLE m_hNotifyhandle;
  187. HANDLE m_hReceivehandle;
  188. HANDLE EventHandleWrite; // 当命令写入时,发送事件
  189. HANDLE EventHandleRead; // 当读取到命令时,发送事件
  190. HANDLE ThreadHandleRead;
  191. DWORD ThreadIDRead; // 读线程ID
  192. };
  193. SCF_C_API SCF* LoadScf(const char *pFilename);
  194. SCF_C_API void UnLoadScf(SCF* pHandle);
  195. typedef SCF * (*GetSCF_Proc)();
  196. typedef void (*ReleaseSCF_Proc)(SCF *);