#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cereal/gen/cpp/log.capnp.h" #include "common/params.h" #include "common/swaglog.h" #include "common/timing.h" #include "ublox_msg.h" volatile int do_exit = 0; // Flag for process exit on signal void set_do_exit(int sig) { do_exit = 1; } using namespace ublox; int ubloxd_main(poll_ubloxraw_msg_func poll_func, send_gps_event_func send_func) { LOGW("starting ubloxd"); signal(SIGINT, (sighandler_t) set_do_exit); signal(SIGTERM, (sighandler_t) set_do_exit); UbloxMsgParser parser; void *context = zmq_ctx_new(); void *gpsLocationExternal = zmq_socket(context, ZMQ_PUB); zmq_bind(gpsLocationExternal, "tcp://*:8032"); void *ubloxGnss = zmq_socket(context, ZMQ_PUB); zmq_bind(ubloxGnss, "tcp://*:8033"); // ubloxRaw = 8042 void *subscriber = zmq_socket(context, ZMQ_SUB); zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0); zmq_connect(subscriber, "tcp://127.0.0.1:8042"); while (!do_exit) { zmq_msg_t msg; zmq_msg_init(&msg); int err = poll_func(gpsLocationExternal, ubloxGnss, subscriber, &msg); if(err < 0) { LOGE_100("zmq_poll error %s in %s", strerror(errno ), __FUNCTION__); break; } else if(err == 0) { continue; } // format for board, make copy due to alignment issues, will be freed on out of scope auto amsg = kj::heapArray((zmq_msg_size(&msg) / sizeof(capnp::word)) + 1); memcpy(amsg.begin(), zmq_msg_data(&msg), zmq_msg_size(&msg)); capnp::FlatArrayMessageReader cmsg(amsg); cereal::Event::Reader event = cmsg.getRoot(); const uint8_t *data = event.getUbloxRaw().begin(); size_t len = event.getUbloxRaw().size(); size_t bytes_consumed = 0; while(bytes_consumed < len && !do_exit) { size_t bytes_consumed_this_time = 0U; if(parser.add_data(data + bytes_consumed, (uint32_t)(len - bytes_consumed), bytes_consumed_this_time)) { // New message available if(parser.msg_class() == CLASS_NAV) { if(parser.msg_id() == MSG_NAV_PVT) { LOGD("MSG_NAV_PVT"); auto words = parser.gen_solution(); if(words.size() > 0) { auto bytes = words.asBytes(); send_func(parser.msg_class(), parser.msg_id(), gpsLocationExternal, bytes.begin(), bytes.size(), 0); } } else LOGW("Unknown nav msg id: 0x%02X", parser.msg_id()); } else if(parser.msg_class() == CLASS_RXM) { if(parser.msg_id() == MSG_RXM_RAW) { LOGD("MSG_RXM_RAW"); auto words = parser.gen_raw(); if(words.size() > 0) { auto bytes = words.asBytes(); send_func(parser.msg_class(), parser.msg_id(), ubloxGnss, bytes.begin(), bytes.size(), 0); } } else if(parser.msg_id() == MSG_RXM_SFRBX) { LOGD("MSG_RXM_SFRBX"); auto words = parser.gen_nav_data(); if(words.size() > 0) { auto bytes = words.asBytes(); send_func(parser.msg_class(), parser.msg_id(), ubloxGnss, bytes.begin(), bytes.size(), 0); } } else LOGW("Unknown rxm msg id: 0x%02X", parser.msg_id()); } else LOGW("Unknown msg class: 0x%02X", parser.msg_class()); parser.reset(); } bytes_consumed += bytes_consumed_this_time; } zmq_msg_close(&msg); } zmq_close(subscriber); zmq_close(gpsLocationExternal); zmq_close(ubloxGnss); zmq_ctx_destroy(context); return 0; }