xsync上位机
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
6.2 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <time.h>
  4. #include <winsock2.h>
  5. #include <chrono>
  6. #include <fstream>
  7. #include <functional>
  8. #include <iostream>
  9. #include <list>
  10. #include <map>
  11. #include <memory>
  12. #include <mutex>
  13. #include <set>
  14. #include <sstream>
  15. #include <string>
  16. #include <thread>
  17. #include <vector>
  18. //
  19. #include <Windows.h>
  20. #pragma comment(lib, "ws2_32.lib")
  21. #define PORT 19903
  22. using namespace std;
  23. typedef struct {
  24. uint32_t eventid;
  25. int32_t data[4];
  26. } iflytop_xsync_event_report_packet_t;
  27. static std::ofstream* logfile;
  28. /**
  29. * @brief :
  30. *
  31. * @return string
  32. */
  33. static const char* gettime_str() {
  34. time_t t = time(0);
  35. static char tmp[64];
  36. strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&t));
  37. struct tm* tt = localtime(&t);
  38. // sprintf(tmp, "%s:%03d", tmp, GetTickCount() % 1000);
  39. return tmp;
  40. }
  41. static string getlogfilename() {
  42. time_t t = time(0);
  43. char tmp[64];
  44. strftime(tmp, sizeof(tmp), "%Y%m%d_%H%M%S.log", localtime(&t));
  45. return tmp;
  46. }
  47. /**
  48. * @brief
  49. */
  50. bool log_file_init() {
  51. // 创建日志文件
  52. logfile = new ofstream(getlogfilename(), ios::app);
  53. if (logfile == NULL) {
  54. printf("创建日志文件失败\n");
  55. return false;
  56. }
  57. return true;
  58. }
  59. void log(const char* fmt, ...) {
  60. char buf[1024] = {0};
  61. va_list args;
  62. va_start(args, fmt);
  63. vsprintf(buf, fmt, args);
  64. va_end(args);
  65. cout << buf;
  66. }
  67. void logd(const char* fmt, ...) {
  68. char buf[1024] = {0};
  69. va_list args;
  70. va_start(args, fmt);
  71. vsprintf(buf, fmt, args);
  72. va_end(args);
  73. if (logfile) {
  74. *logfile << buf;
  75. logfile->flush();
  76. }
  77. cout << buf;
  78. }
  79. #define LOGD(fmt, ...) logd("[%s] INFO : " fmt "\n", gettime_str(), ##__VA_ARGS__);
  80. int64_t gettime() {
  81. auto currentTime = std::chrono::system_clock::now();
  82. return currentTime.time_since_epoch().count() / 1000000;
  83. }
  84. typedef struct {
  85. uint32_t tc0;
  86. uint32_t tc1;
  87. uint32_t subframe;
  88. } Timecode64_t;
  89. typedef struct {
  90. uint8_t hour;
  91. uint8_t minute;
  92. uint8_t second;
  93. uint8_t frame;
  94. uint8_t subframe;
  95. } XsyncTimecode_t;
  96. XsyncTimecode_t timecode64ToXsyncTimeCode(Timecode64_t tc64) {
  97. uint8_t frameuints = tc64.tc0 & 0x0f;
  98. uint8_t frame10s = (tc64.tc0 >> 8) & 0x3;
  99. uint8_t seconduints = (tc64.tc0 >> 16) & 0x0f;
  100. uint8_t second10s = (tc64.tc0 >> 24) & 0x07;
  101. uint8_t minuteuints = tc64.tc1 & 0x0f;
  102. uint8_t minute10s = (tc64.tc1 >> 8) & 0x07;
  103. uint8_t houruints = (tc64.tc1 >> 16) & 0x0f;
  104. uint8_t hour10s = (tc64.tc1 >> 24) & 0x03;
  105. XsyncTimecode_t timecode;
  106. timecode.hour = hour10s * 10 + houruints;
  107. timecode.minute = minute10s * 10 + minuteuints;
  108. timecode.second = second10s * 10 + seconduints;
  109. timecode.frame = frame10s * 10 + frameuints;
  110. timecode.subframe = tc64.subframe;
  111. return timecode;
  112. }
  113. int main(int argc, char* argv[]) {
  114. // 初始化网络环境
  115. log_file_init();
  116. WSADATA wsa;
  117. if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
  118. LOGD("WSAStartup failed");
  119. return -1;
  120. }
  121. // 建立一个UDP的socket
  122. SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  123. if (sock == SOCKET_ERROR) {
  124. LOGD("create socket failed");
  125. return -1;
  126. }
  127. // 绑定地址信息
  128. sockaddr_in serverAddr;
  129. serverAddr.sin_family = AF_INET;
  130. serverAddr.sin_port = htons(PORT);
  131. serverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
  132. bool bOptval = true;
  133. int32_t iret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptval, sizeof(bOptval));
  134. if (iret != 0) {
  135. LOGD("setsockopt fail: %s", WSAGetLastError());
  136. return -1;
  137. }
  138. int ret = ::bind(sock, (sockaddr*)&serverAddr, sizeof(sockaddr));
  139. if (ret != 0) {
  140. LOGD("bind failed");
  141. return -1;
  142. }
  143. char buf[512];
  144. while (TRUE) {
  145. memset(buf, 0, 512);
  146. sockaddr_in clientAddr;
  147. memset(&clientAddr, 0, sizeof(sockaddr_in));
  148. int clientAddrLen = sizeof(sockaddr);
  149. // 接收客户端发来的数据
  150. int ret = recvfrom(sock, buf, 512, 0, (sockaddr*)&clientAddr, &clientAddrLen);
  151. iflytop_xsync_event_report_packet_t* packet = (iflytop_xsync_event_report_packet_t*)buf;
  152. uint32_t stm32_ticket = packet->data[3];
  153. uint32_t stm32_send_delay = packet->data[4];
  154. Timecode64_t tc64;
  155. tc64.tc0 = packet->data[0];
  156. tc64.tc1 = packet->data[1];
  157. tc64.subframe = packet->data[2];
  158. XsyncTimecode_t timecode = timecode64ToXsyncTimeCode(tc64);
  159. static int64_t lastrxticket;
  160. static uint32_t laststm32ticket = 0;
  161. static int32_t et1 = 0;
  162. static int32_t et2 = 0;
  163. static int32_t et3 = 0;
  164. static int32_t et4 = 0;
  165. static Timecode64_t lasttimecode64;
  166. static int32_t lastdifftime = 0;
  167. static int32_t lastdiffstm32;
  168. int64_t nowticket = gettime();
  169. int64_t difftime = nowticket - lastrxticket;
  170. int64_t diffstm32 = stm32_ticket - laststm32ticket;
  171. static int32_t totalPacketNum = 0;
  172. totalPacketNum++;
  173. {
  174. if (abs(difftime - lastdifftime) > 4) {
  175. et1++;
  176. LOGD("exception_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
  177. }
  178. if (abs(diffstm32 - lastdiffstm32) > 2) {
  179. et2++;
  180. LOGD("exception_2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
  181. }
  182. if (stm32_send_delay > 1) {
  183. et3++;
  184. LOGD("exception_3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
  185. }
  186. if (memcmp(&lasttimecode64, &tc64, sizeof(Timecode64_t)) == 0) {
  187. et4++;
  188. LOGD("exception_4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
  189. }
  190. LOGD("pcticket:%ld(%10d) tc:%2d:%2d:%2d:%2d:%2d stm32ticket:%10d(%10d) stm32_send_delay:%d et:(%d %d %d %d)/%d", nowticket, difftime, //
  191. timecode.hour, timecode.minute, timecode.second, timecode.frame, timecode.subframe, //
  192. stm32_ticket, diffstm32, stm32_send_delay, //
  193. et1 / 2, et2, et3, et4, totalPacketNum);
  194. }
  195. lasttimecode64 = tc64;
  196. //
  197. lastrxticket = nowticket;
  198. laststm32ticket = stm32_ticket;
  199. lastdifftime = difftime;
  200. lastdiffstm32 = diffstm32;
  201. // 发一个数据包返回给客户
  202. }
  203. return 0;
  204. }