From 5640cb77df371c853b3c9ae2244315bf93e9e7ce Mon Sep 17 00:00:00 2001 From: zhaohe Date: Sat, 18 Mar 2023 12:55:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0GPS=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmakepc.cmake | 8 ++- src/service/H8922S_gps_Info_reader.cpp | 108 +++++++++++++++++++++++++++++++ src/service/H8922S_gps_Info_reader.hpp | 80 +++++++++++++++++++++++ src/test/test_H8922S_gps_info_reader.cpp | 43 ++++++++++++ 4 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 src/service/H8922S_gps_Info_reader.cpp create mode 100644 src/service/H8922S_gps_Info_reader.hpp create mode 100644 src/test/test_H8922S_gps_info_reader.cpp diff --git a/cmakepc.cmake b/cmakepc.cmake index 0cee32a..bc58715 100644 --- a/cmakepc.cmake +++ b/cmakepc.cmake @@ -56,4 +56,10 @@ set(DEP_LINK_LIBRARIES # curlpp curl ) zadd_executable_simple(TARGET test_aiui_service.out SRC -src/test_aiui_service.cpp) \ No newline at end of file + src/test_aiui_service.cpp) + +zadd_executable_simple( + TARGET test_H8922S_gps_info_reader.out SRC + src/test/test_H8922S_gps_info_reader.cpp + src/service/H8922S_gps_Info_reader.cpp + ) diff --git a/src/service/H8922S_gps_Info_reader.cpp b/src/service/H8922S_gps_Info_reader.cpp new file mode 100644 index 0000000..45a500a --- /dev/null +++ b/src/service/H8922S_gps_Info_reader.cpp @@ -0,0 +1,108 @@ +#include "H8922S_gps_Info_reader.hpp" + +#include +#include +#include +#include + +#include +#include +#include + +using namespace iflytop; +using namespace core; +using namespace std; + +static vector split(const string &s, char delimiter) { + vector tokens; + string token; + istringstream tokenStream(s); + while (getline(tokenStream, token, delimiter)) { + tokens.push_back(token); + } + return tokens; +} + +H8922SGPSInfoReader::H8922SGPSInfoReader() {} + +void H8922SGPSInfoReader::initialize(int port) { + m_port = port; + startListenUDPServer(); +} +// "GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50"; +// "GNRMC, ,V, , , , , , , ,,,N*4D +void H8922SGPSInfoReader::processGPRMCMessage(string grpminfo) { + logger->debug("rx: {}", grpminfo); + GPSINFO gps; + vector fields = split(grpminfo, ','); + if (fields.size() != 13) { + logger->warn("invalid GPRMC message: {},{}", grpminfo, fields.size()); + return; + } + gps.header = fields[0]; + gps.time = fields[1]; + gps.status = fields[2]; + gps.latitude = fields[3]; + gps.lat_dir = fields[4]; + gps.longitude = fields[5]; + gps.long_dir = fields[6]; + gps.speed = fields[7]; + gps.course = fields[8]; + gps.date = fields[9]; + gps.mag_var = fields[10]; + gps.mag_var_dir = fields[11]; + + // fields[12] = A*50 ,mod = A, checksum = 50 + vector modeAndChecksum = split(fields[12], '*'); + if (modeAndChecksum.size() != 2) { + logger->warn("invalid GPRMC:modAndChecksum message: {},{}", fields[12], modeAndChecksum.size()); + return; + } + gps.mode = modeAndChecksum[0]; + gps.checksum = modeAndChecksum[1]; + + onMessage(gps); +} + +void H8922SGPSInfoReader::startListenUDPServer() { + thread.reset(new Thread("H8922SGPSInfoReaderThread", [this]() { + ThisThread thisThread; + + int sock; + struct sockaddr_in server_addr, client_addr; + socklen_t client_len = sizeof(client_addr); + int server_port = m_port; + char buffer[1024]; + + // 创建UDP套接字 + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + logger->error("create udp socket failed"); + return; + } + + // 设置服务器地址信息 + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = htonl(INADDR_ANY); + server_addr.sin_port = htons(server_port); + + // 绑定UDP套接字到本地端口 + if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { + logger->error("bind udp socket failed"); + close(sock); + return; + } + + logger->info("start listen udp port {}", server_port); + while (!thisThread.getExitFlag()) { + // 接收UDP消息 + memset(buffer, 0, sizeof(buffer)); + if (recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, &client_len) < 0) { + logger->error("receive udp message failed"); + continue; + } + + processGPRMCMessage(buffer); + } + })); +} diff --git a/src/service/H8922S_gps_Info_reader.hpp b/src/service/H8922S_gps_Info_reader.hpp new file mode 100644 index 0000000..3719de1 --- /dev/null +++ b/src/service/H8922S_gps_Info_reader.hpp @@ -0,0 +1,80 @@ +// +// Created by zwsd +// + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iflytopcpp/core/basic/nod/nod.hpp" +#include "iflytopcpp/core/spdlogfactory/logger.hpp" +#include "iflytopcpp/core/thread/thread.hpp" + +/** + * @brief + * + * service: H8922SGPSInfoReader + * + * 监听事件: + * 依赖状态: + * 依赖服务: + * 作用: + * + */ + +namespace iflytop { +using namespace std; +using namespace core; +class H8922SGPSInfoReader : public enable_shared_from_this { + ENABLE_LOGGER(H8922SGPSInfoReader); + + public: + class GPSINFO { + public: + string header; + string time; + string status; + string latitude; + string lat_dir; + string longitude; + string long_dir; + string speed; + string course; + string date; + string mag_var; + string mag_var_dir; + string mode; + string checksum; + + public: + string toString() { + // return header + "," + time + "," + status + "," + latitude + "," + lat_dir + "," + longitude + "," + long_dir + + // "," + speed + "," + course + "," + date + "," + mag_var + "," + mag_var_dir + "," + mode + "*" + checksum; + + return fmt::format("{},{},{},{},{},{},{},{},{},{},{},{},{}*{}", header, time, status, latitude, lat_dir, longitude, + long_dir, speed, course, date, mag_var, mag_var_dir, mode, checksum); + } + }; + + int socket_fd; + + unique_ptr thread; + nod::signal onMessage; + int m_port; + + public: + H8922SGPSInfoReader(); + void initialize(int port); + + private: + void startListenUDPServer(); + void processGPRMCMessage(string grpminfo); +}; +} // namespace iflytop \ No newline at end of file diff --git a/src/test/test_H8922S_gps_info_reader.cpp b/src/test/test_H8922S_gps_info_reader.cpp new file mode 100644 index 0000000..28603b7 --- /dev/null +++ b/src/test/test_H8922S_gps_info_reader.cpp @@ -0,0 +1,43 @@ +#include "zlinuxcomponents/zmainhelper.hpp" +// +#include "configs/zconfig.hpp" +#include "iflytopcpp/core/spdlogfactory/logger.hpp" +#include "iflytopcpp/core/thread/thread.hpp" +#include "spdlog/spdlog.h" +#include "version.hpp" +#include "zlinuxcomponents/rootfs_auto_update/rootfs_auto_update.hpp" +#include "zservice_container/zservice_container.hpp" +// +#include "service/device_io_service.hpp" +#include "service/device_io_service_mock.hpp" +#include "service/light_control_service.hpp" +#include "service/report_service.hpp" +#include "zlinuxcomponents/aiui_ws/aiui_service.hpp" + +// +#include + +#include +#include + +#include "service/H8922S_gps_Info_reader.hpp" +#include "zlinuxcomponents/aiui_ws/aiui.h" + +// +using namespace iflytop; +using namespace core; +using namespace std; +using namespace clipp; + +ZMAIN(); +void Main::onSIGINT() { exit(0); } + +int Main::main(int argc, char *argv[]) { + H8922SGPSInfoReader h8922SGPSInfoReader; + h8922SGPSInfoReader.initialize(8922); + h8922SGPSInfoReader.onMessage.connect( + [&](H8922SGPSInfoReader::GPSINFO gpsinfo) { logger->info("gpsinfo: {}", gpsinfo.toString()); }); + while (1) { + sleep(1); + } +}