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.
 
 
 

237 lines
6.2 KiB

#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <winsock2.h>
#include <chrono>
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <string>
#include <thread>
#include <vector>
//
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
#define PORT 19903
using namespace std;
typedef struct {
uint32_t eventid;
int32_t data[4];
} iflytop_xsync_event_report_packet_t;
static std::ofstream* logfile;
/**
* @brief 获取 年月日时分秒:毫秒
*
* @return string
*/
static const char* gettime_str() {
time_t t = time(0);
static char tmp[64];
strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&t));
struct tm* tt = localtime(&t);
// sprintf(tmp, "%s:%03d", tmp, GetTickCount() % 1000);
return tmp;
}
static string getlogfilename() {
time_t t = time(0);
char tmp[64];
strftime(tmp, sizeof(tmp), "%Y%m%d_%H%M%S.log", localtime(&t));
return tmp;
}
/**
* @brief 写日志到文件中
*/
bool log_file_init() {
// 创建日志文件
logfile = new ofstream(getlogfilename(), ios::app);
if (logfile == NULL) {
printf("创建日志文件失败\n");
return false;
}
return true;
}
void log(const char* fmt, ...) {
char buf[1024] = {0};
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
cout << buf;
}
void logd(const char* fmt, ...) {
char buf[1024] = {0};
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
if (logfile) {
*logfile << buf;
logfile->flush();
}
cout << buf;
}
#define LOGD(fmt, ...) logd("[%s] INFO : " fmt "\n", gettime_str(), ##__VA_ARGS__);
int64_t gettime() {
auto currentTime = std::chrono::system_clock::now();
return currentTime.time_since_epoch().count() / 1000000;
}
typedef struct {
uint32_t tc0;
uint32_t tc1;
uint32_t subframe;
} Timecode64_t;
typedef struct {
uint8_t hour;
uint8_t minute;
uint8_t second;
uint8_t frame;
uint8_t subframe;
} XsyncTimecode_t;
XsyncTimecode_t timecode64ToXsyncTimeCode(Timecode64_t tc64) {
uint8_t frameuints = tc64.tc0 & 0x0f;
uint8_t frame10s = (tc64.tc0 >> 8) & 0x3;
uint8_t seconduints = (tc64.tc0 >> 16) & 0x0f;
uint8_t second10s = (tc64.tc0 >> 24) & 0x07;
uint8_t minuteuints = tc64.tc1 & 0x0f;
uint8_t minute10s = (tc64.tc1 >> 8) & 0x07;
uint8_t houruints = (tc64.tc1 >> 16) & 0x0f;
uint8_t hour10s = (tc64.tc1 >> 24) & 0x03;
XsyncTimecode_t timecode;
timecode.hour = hour10s * 10 + houruints;
timecode.minute = minute10s * 10 + minuteuints;
timecode.second = second10s * 10 + seconduints;
timecode.frame = frame10s * 10 + frameuints;
timecode.subframe = tc64.subframe;
return timecode;
}
int main(int argc, char* argv[]) {
// 初始化网络环境
log_file_init();
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
LOGD("WSAStartup failed");
return -1;
}
// 建立一个UDP的socket
SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == SOCKET_ERROR) {
LOGD("create socket failed");
return -1;
}
// 绑定地址信息
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
bool bOptval = true;
int32_t iret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptval, sizeof(bOptval));
if (iret != 0) {
LOGD("setsockopt fail: %s", WSAGetLastError());
return -1;
}
int ret = ::bind(sock, (sockaddr*)&serverAddr, sizeof(sockaddr));
if (ret != 0) {
LOGD("bind failed");
return -1;
}
char buf[512];
while (TRUE) {
memset(buf, 0, 512);
sockaddr_in clientAddr;
memset(&clientAddr, 0, sizeof(sockaddr_in));
int clientAddrLen = sizeof(sockaddr);
// 接收客户端发来的数据
int ret = recvfrom(sock, buf, 512, 0, (sockaddr*)&clientAddr, &clientAddrLen);
iflytop_xsync_event_report_packet_t* packet = (iflytop_xsync_event_report_packet_t*)buf;
uint32_t stm32_ticket = packet->data[3];
uint32_t stm32_send_delay = packet->data[4];
Timecode64_t tc64;
tc64.tc0 = packet->data[0];
tc64.tc1 = packet->data[1];
tc64.subframe = packet->data[2];
XsyncTimecode_t timecode = timecode64ToXsyncTimeCode(tc64);
static int64_t lastrxticket;
static uint32_t laststm32ticket = 0;
static int32_t et1 = 0;
static int32_t et2 = 0;
static int32_t et3 = 0;
static int32_t et4 = 0;
static Timecode64_t lasttimecode64;
static int32_t lastdifftime = 0;
static int32_t lastdiffstm32;
int64_t nowticket = gettime();
int64_t difftime = nowticket - lastrxticket;
int64_t diffstm32 = stm32_ticket - laststm32ticket;
static int32_t totalPacketNum = 0;
totalPacketNum++;
{
if (abs(difftime - lastdifftime) > 4) {
et1++;
LOGD("exception_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
if (abs(diffstm32 - lastdiffstm32) > 2) {
et2++;
LOGD("exception_2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
if (stm32_send_delay > 1) {
et3++;
LOGD("exception_3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
if (memcmp(&lasttimecode64, &tc64, sizeof(Timecode64_t)) == 0) {
et4++;
LOGD("exception_4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
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, //
timecode.hour, timecode.minute, timecode.second, timecode.frame, timecode.subframe, //
stm32_ticket, diffstm32, stm32_send_delay, //
et1 / 2, et2, et3, et4, totalPacketNum);
}
lasttimecode64 = tc64;
//
lastrxticket = nowticket;
laststm32ticket = stm32_ticket;
lastdifftime = difftime;
lastdiffstm32 = diffstm32;
// 发一个数据包返回给客户
}
return 0;
}