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.

353 lines
11 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "xsync.hpp"
  2. #define ENABLE_LOG
  3. #ifdef ENABLE_LOG
  4. #include "../src/logger.hpp"
  5. #endif
  6. #define TAG "XSYNC"
  7. using namespace iflytop;
  8. static uint32_t ipToUint32(const std::string &ipAddress, bool &suc) {
  9. uint32_t result = 0;
  10. std::istringstream iss(ipAddress);
  11. std::string segment;
  12. int i = 0;
  13. while (std::getline(iss, segment, '.')) {
  14. uint32_t octet = std::stoi(segment);
  15. if (octet > 255) {
  16. suc = false;
  17. return 0;
  18. }
  19. result |= (octet << ((3 - i) * 8));
  20. i++;
  21. }
  22. if (i != 4) {
  23. suc = false;
  24. return 0;
  25. }
  26. suc = true;
  27. uint32_t result_n = 0;
  28. result_n |= ((result & 0xff000000) >> 24);
  29. result_n |= ((result & 0x00ff0000) >> 8);
  30. result_n |= ((result & 0x0000ff00) << 8);
  31. result_n |= ((result & 0x000000ff) << 24);
  32. return result_n;
  33. }
  34. Xsync::Xsync(/* args */) {}
  35. Xsync &Xsync::Ins() {
  36. static Xsync xsync;
  37. return xsync;
  38. }
  39. void Xsync::initialize(I_XSUDPFactory *xsync_udp_factory) { m_xsync_udp_factory = xsync_udp_factory; }
  40. xs_error_code_t Xsync::connect(string xsync_ip) {
  41. lock_guard<recursive_mutex> lock(lock_);
  42. m_xsync_ip = xsync_ip;
  43. disConnect();
  44. /**
  45. * @brief m_xsync_reg_udp
  46. */
  47. xs_error_code_t ecode = kxs_ec_success;
  48. auto xsync_reg_udp = m_xsync_udp_factory->createXSUDP();
  49. ecode = xsync_reg_udp->initialize("0.0.0.0", IFLYTOP_XSYNC_SERVICE_PC_PORT);
  50. if (ecode != kxs_ec_success) {
  51. return ecode;
  52. }
  53. /**
  54. * @brief m_xsync_timecode_udp_listener
  55. */
  56. auto xsync_timecode_udp_listener = m_xsync_udp_factory->createXSUDP();
  57. ecode = xsync_timecode_udp_listener->initialize("0.0.0.0", IFLYTOP_XSYNC_TIMECODE_REPORT_PC_PORT);
  58. if (ecode != kxs_ec_success) {
  59. return ecode;
  60. }
  61. ecode = xsync_timecode_udp_listener->startReceive([this](XsyncNetAdd &from, uint8_t *data, size_t length) { parseTimecodeMsgAndReport(from, data, length); });
  62. if (ecode != kxs_ec_success) {
  63. return ecode;
  64. }
  65. /**
  66. * @brief m_xsync_camera_sync_udp_listener
  67. */
  68. auto xsync_camera_sync_udp_listener = m_xsync_udp_factory->createXSUDP();
  69. ecode = xsync_camera_sync_udp_listener->initialize("0.0.0.0", IFLYTOP_XSYNC_CAMERA_SYNC_PACKET_PC_PORT);
  70. if (ecode != kxs_ec_success) {
  71. return ecode;
  72. }
  73. ecode = xsync_camera_sync_udp_listener->startReceive([this](XsyncNetAdd &from, uint8_t *data, size_t length) { parseCameraSyncMsgAndReport(from, data, length); });
  74. if (ecode != kxs_ec_success) {
  75. return ecode;
  76. }
  77. m_xsync_reg_udp = xsync_reg_udp;
  78. m_xsync_timecode_udp_listener = xsync_timecode_udp_listener;
  79. m_xsync_camera_sync_udp_listener = xsync_camera_sync_udp_listener;
  80. m_net_state = kxsync_net_state_connected;
  81. return ecode;
  82. }
  83. xs_error_code_t Xsync::disConnect() {
  84. lock_guard<recursive_mutex> lock(lock_);
  85. if (m_xsync_reg_udp != nullptr) {
  86. m_xsync_reg_udp->stopReceive();
  87. m_xsync_reg_udp = nullptr;
  88. }
  89. if (m_xsync_timecode_udp_listener != nullptr) {
  90. m_xsync_timecode_udp_listener->stopReceive();
  91. m_xsync_timecode_udp_listener = nullptr;
  92. }
  93. if (m_xsync_camera_sync_udp_listener != nullptr) {
  94. m_xsync_camera_sync_udp_listener->stopReceive();
  95. m_xsync_camera_sync_udp_listener = nullptr;
  96. }
  97. m_net_state = kxsync_net_state_disconnect;
  98. return kxs_ec_success;
  99. }
  100. xsync_net_state_t Xsync::getNetState() { return m_net_state; }
  101. void Xsync::regOnTimecodeMsg(xsync_on_timecode_msg_t on_timecode_msg_cb) { m_on_timecode_msg_cb = on_timecode_msg_cb; }
  102. void Xsync::regOnCameraSyncMsg(xsync_on_camera_sync_msg_t on_camera_sync_msg_cb) { m_on_camera_sync_msg_cb = on_camera_sync_msg_cb; }
  103. xs_error_code_t Xsync::xsync_send_cmd_block(iflytop_xsync_packet_header_t *cmd, iflytop_xsync_packet_header_t *rx_data, int32_t buffersize, int32_t overtime_ms) {
  104. lock_guard<recursive_mutex> lock(lock_);
  105. if (!m_xsync_reg_udp) return kxs_ec_lose_connect;
  106. m_xsync_reg_udp->clearRxBuffer();
  107. cmd->index = txpacket_index++;
  108. XsyncNetAdd toadd = {m_xsync_ip, IFLYTOP_XSYNC_SERVICE_XSYNC_PORT};
  109. xs_error_code_t ecode = //
  110. m_xsync_reg_udp->sendto(toadd, (const char *)cmd, sizeof(iflytop_xsync_packet_header_t) + cmd->ndata * 4, nullptr);
  111. if (ecode != kxs_ec_success) {
  112. return ecode;
  113. }
  114. XsyncNetAdd fromadd;
  115. while (true) {
  116. // ZLOGI(TAG, "start rx wait for rxdata");
  117. ecode = m_xsync_reg_udp->receive((char *)rx_data, buffersize, fromadd, overtime_ms);
  118. // ZLOGI(TAG, "end rx wait for rxdata");
  119. if (ecode != kxs_ec_success) {
  120. return ecode;
  121. }
  122. if (rx_data->index != cmd->index) {
  123. // ZLOGI(TAG, "packet index error %d %d", cmd->index, rx_data->index);
  124. continue;
  125. }
  126. break;
  127. }
  128. return (xs_error_code_t)rx_data->data[0];
  129. }
  130. xs_error_code_t Xsync::reg_write(uint32_t regadd, uint32_t regvalue, uint32_t &regbackvalue, int32_t overtime_ms) {
  131. /**
  132. * @brief
  133. *
  134. *
  135. * kxsync_packet_type_reg_write
  136. * tx: regadd,regdata
  137. * rx: ecode,regdata
  138. */
  139. uint8_t txdata[128] = {0};
  140. uint8_t rxdata[128] = {0};
  141. iflytop_xsync_packet_header_t *txpacket = (iflytop_xsync_packet_header_t *)txdata;
  142. iflytop_xsync_packet_header_t *rxpacket = (iflytop_xsync_packet_header_t *)rxdata;
  143. txpacket->type = kxsync_packet_type_cmd;
  144. txpacket->index = txpacket_index++;
  145. txpacket->cmd = kxsync_packet_type_reg_write;
  146. txpacket->ndata = 2;
  147. txpacket->data[0] = regadd;
  148. txpacket->data[1] = regvalue;
  149. auto ecode = xsync_send_cmd_block(txpacket, rxpacket, sizeof(rxdata), overtime_ms);
  150. if (ecode != kxs_ec_success) {
  151. return ecode;
  152. }
  153. regbackvalue = rxpacket->data[1];
  154. return ecode;
  155. }
  156. xs_error_code_t Xsync::reg_read(uint32_t regadd, uint32_t &regvalue, int32_t overtime_ms) {
  157. /**
  158. * @brief
  159. *
  160. *
  161. * kxsync_packet_type_reg_write
  162. * tx: regadd,regdata
  163. * rx: ecode,regdata
  164. */
  165. uint8_t txdata[128] = {0};
  166. uint8_t rxdata[128] = {0};
  167. iflytop_xsync_packet_header_t *txpacket = (iflytop_xsync_packet_header_t *)txdata;
  168. iflytop_xsync_packet_header_t *rxpacket = (iflytop_xsync_packet_header_t *)rxdata;
  169. txpacket->type = kxsync_packet_type_cmd;
  170. txpacket->index = txpacket_index++;
  171. txpacket->cmd = kxsync_packet_type_reg_read;
  172. txpacket->ndata = 2;
  173. txpacket->data[0] = regadd;
  174. txpacket->data[1] = regvalue;
  175. auto ecode = xsync_send_cmd_block(txpacket, rxpacket, sizeof(rxdata), overtime_ms);
  176. if (ecode != kxs_ec_success) {
  177. return ecode;
  178. }
  179. regvalue = rxpacket->data[1];
  180. return ecode;
  181. }
  182. xs_error_code_t Xsync::reg_read_muti(uint32_t regadd, uint32_t nreg, vector<uint32_t> &regvalues, int32_t overtime_ms) {
  183. /**
  184. * @brief
  185. *
  186. *
  187. * kxsync_packet_type_reg_read_regs
  188. * tx: regstartadd,nreg
  189. * rx: ecode,regdatas
  190. */
  191. uint8_t txdata[128] = {0};
  192. uint8_t rxdata[1280] = {0};
  193. iflytop_xsync_packet_header_t *txpacket = (iflytop_xsync_packet_header_t *)txdata;
  194. iflytop_xsync_packet_header_t *rxpacket = (iflytop_xsync_packet_header_t *)rxdata;
  195. txpacket->type = kxsync_packet_type_cmd;
  196. txpacket->index = txpacket_index++;
  197. txpacket->cmd = kxsync_packet_type_reg_read_regs;
  198. txpacket->ndata = 2;
  199. txpacket->data[0] = regadd;
  200. txpacket->data[1] = nreg;
  201. auto ecode = xsync_send_cmd_block(txpacket, rxpacket, sizeof(rxdata), overtime_ms);
  202. if (ecode != kxs_ec_success) {
  203. return ecode;
  204. }
  205. if (rxpacket->ndata > 0) {
  206. for (int i = 0; i < rxpacket->ndata - 1; i++) {
  207. regvalues.push_back(rxpacket->data[i + 1]);
  208. }
  209. }
  210. return ecode;
  211. }
  212. void Xsync::parseTimecodeMsgAndReport(XsyncNetAdd &from, uint8_t *data, size_t length) {
  213. //
  214. iflytop_timecode_report_packet_t *packet = (iflytop_timecode_report_packet_t *)data;
  215. xysnc_timecode_t timecode;
  216. /**
  217. * @brief
  218. *
  219. * 01 02 03 04 01 02 03 04
  220. *
  221. */
  222. uint8_t frameuints = packet->timecode0 & 0x0f;
  223. uint8_t frame10s = (packet->timecode0 >> 8) & 0x3;
  224. uint8_t seconduints = (packet->timecode0 >> 16) & 0x0f;
  225. uint8_t second10s = (packet->timecode0 >> 24) & 0x03;
  226. uint8_t minuteuints = packet->timecode1 & 0x0f;
  227. uint8_t minute10s = (packet->timecode1 >> 8) & 0x03;
  228. uint8_t houruints = (packet->timecode1 >> 16) & 0x0f;
  229. uint8_t hour10s = (packet->timecode1 >> 24) & 0x03;
  230. timecode.hour = hour10s * 10 + houruints;
  231. timecode.minute = minute10s * 10 + minuteuints;
  232. timecode.second = second10s * 10 + seconduints;
  233. timecode.frame = frame10s * 10 + frameuints;
  234. if (m_on_timecode_msg_cb) m_on_timecode_msg_cb(&timecode);
  235. }
  236. void Xsync::parseCameraSyncMsgAndReport(XsyncNetAdd &from, uint8_t *data, size_t length) {
  237. uint32_t count = 0;
  238. uint32_t data0 = data[7];
  239. uint32_t data1 = data[6];
  240. uint32_t data2 = data[5];
  241. uint32_t data3 = data[4];
  242. count = data0 + (data1 << 8) + (data2 << 16) + (data3 << 24);
  243. xysnc_camera_sync_data_t camera_sync_data;
  244. camera_sync_data.frameIndex = count;
  245. if (m_on_camera_sync_msg_cb) m_on_camera_sync_msg_cb(&camera_sync_data);
  246. }
  247. // xsync_stm32_action_generator_new_mac, //
  248. // xsync_stm32_action_factory_reset, //
  249. // xsync_stm32_action_reboot, //
  250. // xsync_stm32_action_storage_cfg,
  251. xs_error_code_t Xsync::generatorNewMac() { return doaction(xsync_stm32_action_generator_new_mac, 0, nullptr, 2000); }
  252. xs_error_code_t Xsync::factoryReset() { return doaction(xsync_stm32_action_factory_reset, 0, nullptr, 1000); }
  253. xs_error_code_t Xsync::reboot() { return doaction(xsync_stm32_action_reboot, 0, nullptr); }
  254. xs_error_code_t Xsync::storageConfig() { return doaction(xsync_stm32_action_storage_cfg, 0, nullptr, 1000); }
  255. xs_error_code_t Xsync::changeNetworkConfig(string ip, string mask, string gateway) {
  256. uint32_t ip32 = 0;
  257. uint32_t mask32 = 0;
  258. uint32_t gateway32 = 0;
  259. xs_error_code_t ecode;
  260. bool suc = false;
  261. ip32 = (uint32_t)ipToUint32(ip.c_str(), suc);
  262. if (!suc) return kxs_ec_param_error;
  263. mask32 = (uint32_t)ipToUint32(mask.c_str(), suc);
  264. if (!suc) return kxs_ec_param_error;
  265. gateway32 = (uint32_t)ipToUint32(gateway.c_str(), suc);
  266. if (!suc) return kxs_ec_param_error;
  267. uint32_t readbak = 0;
  268. ecode = reg_write(kxsync_reg_stm32_ip, ip32, readbak);
  269. if (ecode != kxs_ec_success) return ecode;
  270. ecode = reg_write(kxsync_reg_stm32_netmask, mask32, readbak);
  271. if (ecode != kxs_ec_success) return ecode;
  272. ecode = reg_write(kxsync_reg_stm32_gw, gateway32, readbak);
  273. if (ecode != kxs_ec_success) return ecode;
  274. ecode = storageConfig();
  275. if (ecode != kxs_ec_success) return ecode;
  276. return kxs_ec_success;
  277. }
  278. xs_error_code_t Xsync::clearXsyncCameraSyncIndexCount() {
  279. uint32_t readbak = 0;
  280. return reg_write(kxsync_reg_stm32_camera_sync_signal_count, 0, readbak);
  281. }
  282. xs_error_code_t Xsync::doaction(uint32_t action, uint32_t actionval, uint32_t *ackreturn, int32_t overtime_ms) {
  283. //
  284. uint32_t readbak = 0;
  285. xs_error_code_t ecode;
  286. ecode = reg_write(kxsync_reg_stm32_action_val0, actionval, readbak);
  287. if (ecode != kxs_ec_success) return ecode;
  288. ecode = reg_write(kxsync_reg_stm32_action0, action, readbak, overtime_ms);
  289. if (ecode != kxs_ec_success) return ecode;
  290. if (ackreturn) *ackreturn = readbak;
  291. return ecode;
  292. }