nopenpilot/cereal/messaging/socketmaster.cc

206 lines
5.6 KiB
C++
Raw Normal View History

#include <time.h>
2021-05-14 19:20:48 -06:00
#include <assert.h>
#include <stdlib.h>
#include <string>
2021-06-07 16:13:57 -06:00
#include <mutex>
2021-05-14 19:20:48 -06:00
#include "services.h"
2021-05-14 19:20:48 -06:00
#include "messaging.h"
const bool SIMULATION = (getenv("SIMULATION") != nullptr) && (std::string(getenv("SIMULATION")) == "1");
2020-08-12 18:37:05 -06:00
static inline uint64_t nanos_since_boot() {
struct timespec t;
clock_gettime(CLOCK_BOOTTIME, &t);
return t.tv_sec * 1000000000ULL + t.tv_nsec;
}
2020-08-12 18:37:05 -06:00
static const service *get_service(const char *name) {
for (const auto &it : services) {
if (strcmp(it.name, name) == 0) return &it;
}
return nullptr;
}
2020-08-12 18:37:05 -06:00
2021-06-07 16:13:57 -06:00
static inline bool inList(const std::vector<const char *> &list, const char *value) {
for (auto &v : list) {
if (strcmp(value, v) == 0) return true;
}
return false;
}
class MessageContext {
2020-08-12 18:37:05 -06:00
public:
2021-06-07 16:13:57 -06:00
MessageContext() : ctx_(nullptr) {};
~MessageContext() { delete ctx_; }
2021-06-07 16:13:57 -06:00
inline Context *context() {
std::call_once(init_flag, [=]() { ctx_ = Context::create(); });
return ctx_;
}
private:
Context *ctx_;
2021-06-07 16:13:57 -06:00
std::once_flag init_flag;
};
2021-06-07 16:13:57 -06:00
MessageContext message_context;
struct SubMaster::SubMessage {
std::string name;
SubSocket *socket = nullptr;
int freq = 0;
2021-05-14 19:20:48 -06:00
bool updated = false, alive = false, valid = true, ignore_alive;
uint64_t rcv_time = 0, rcv_frame = 0;
void *allocated_msg_reader = nullptr;
capnp::FlatArrayMessageReader *msg_reader = nullptr;
2021-03-29 17:54:22 -06:00
AlignedBuffer aligned_buf;
cereal::Event::Reader event;
};
2021-06-07 16:13:57 -06:00
SubMaster::SubMaster(const std::vector<const char *> &service_list, const char *address,
const std::vector<const char *> &ignore_alive) {
poller_ = Poller::create();
for (auto name : service_list) {
const service *serv = get_service(name);
assert(serv != nullptr);
2021-06-07 16:13:57 -06:00
SubSocket *socket = SubSocket::create(message_context.context(), name, address ? address : "127.0.0.1", true);
assert(socket != 0);
poller_->registerSocket(socket);
SubMessage *m = new SubMessage{
2021-05-14 19:20:48 -06:00
.name = name,
2020-08-12 18:37:05 -06:00
.socket = socket,
.freq = serv->frequency,
.ignore_alive = inList(ignore_alive, name),
2021-03-29 17:54:22 -06:00
.allocated_msg_reader = malloc(sizeof(capnp::FlatArrayMessageReader))};
2021-06-07 16:13:57 -06:00
m->msg_reader = new (m->allocated_msg_reader) capnp::FlatArrayMessageReader({});
messages_[socket] = m;
services_[name] = m;
}
}
2021-05-14 19:20:48 -06:00
void SubMaster::update(int timeout) {
for (auto &kv : messages_) kv.second->updated = false;
auto sockets = poller_->poll(timeout);
uint64_t current_time = nanos_since_boot();
2021-05-14 19:20:48 -06:00
std::vector<std::pair<std::string, cereal::Event::Reader>> messages;
for (auto s : sockets) {
Message *msg = s->receive(true);
if (msg == nullptr) continue;
SubMessage *m = messages_.at(s);
2021-05-14 19:20:48 -06:00
2021-06-07 16:13:57 -06:00
m->msg_reader->~FlatArrayMessageReader();
2021-08-22 23:13:11 -06:00
capnp::ReaderOptions options;
options.traversalLimitInWords = kj::maxValue; // Don't limit
m->msg_reader = new (m->allocated_msg_reader) capnp::FlatArrayMessageReader(m->aligned_buf.align(msg), options);
2021-03-29 17:54:22 -06:00
delete msg;
2021-05-14 19:20:48 -06:00
messages.push_back({m->name, m->msg_reader->getRoot<cereal::Event>()});
}
update_msgs(current_time, messages);
}
2021-08-22 23:13:11 -06:00
void SubMaster::update_msgs(uint64_t current_time, const std::vector<std::pair<std::string, cereal::Event::Reader>> &messages){
2021-05-14 19:20:48 -06:00
if (++frame == UINT64_MAX) frame = 1;
for(auto &kv : messages) {
auto m_find = services_.find(kv.first);
if (m_find == services_.end()){
continue;
}
SubMessage *m = m_find->second;
m->event = kv.second;
m->updated = true;
m->rcv_time = current_time;
2020-08-12 18:37:05 -06:00
m->rcv_frame = frame;
m->valid = m->event.getValid();
2021-05-14 19:20:48 -06:00
if (SIMULATION) m->alive = true;
}
2021-05-14 19:20:48 -06:00
if (!SIMULATION) {
for (auto &kv : messages_) {
SubMessage *m = kv.second;
m->alive = (m->freq <= (1e-5) || ((current_time - m->rcv_time) * (1e-9)) < (10.0 / m->freq));
}
}
}
2021-06-07 16:13:57 -06:00
bool SubMaster::all_(const std::vector<const char *> &service_list, bool valid, bool alive) {
int found = 0;
for (auto &kv : messages_) {
SubMessage *m = kv.second;
if (service_list.size() == 0 || inList(service_list, m->name.c_str())) {
2021-05-14 19:20:48 -06:00
found += (!valid || m->valid) && (!alive || (m->alive || m->ignore_alive));
}
}
return service_list.size() == 0 ? found == messages_.size() : found == service_list.size();
}
void SubMaster::drain() {
while (true) {
auto polls = poller_->poll(0);
if (polls.size() == 0)
break;
for (auto sock : polls) {
Message *msg = sock->receive(true);
delete msg;
}
}
}
2020-08-12 18:37:05 -06:00
bool SubMaster::updated(const char *name) const {
return services_.at(name)->updated;
}
2021-05-14 19:20:48 -06:00
bool SubMaster::alive(const char *name) const {
return services_.at(name)->alive;
}
bool SubMaster::valid(const char *name) const {
return services_.at(name)->valid;
}
2020-08-12 18:37:05 -06:00
uint64_t SubMaster::rcv_frame(const char *name) const {
return services_.at(name)->rcv_frame;
}
2021-05-14 19:20:48 -06:00
uint64_t SubMaster::rcv_time(const char *name) const {
return services_.at(name)->rcv_time;
}
2021-06-07 16:13:57 -06:00
cereal::Event::Reader &SubMaster::operator[](const char *name) const {
2020-08-12 18:37:05 -06:00
return services_.at(name)->event;
};
SubMaster::~SubMaster() {
delete poller_;
for (auto &kv : messages_) {
SubMessage *m = kv.second;
2021-06-07 16:13:57 -06:00
m->msg_reader->~FlatArrayMessageReader();
free(m->allocated_msg_reader);
delete m->socket;
delete m;
}
}
2021-06-07 16:13:57 -06:00
PubMaster::PubMaster(const std::vector<const char *> &service_list) {
for (auto name : service_list) {
assert(get_service(name) != nullptr);
2021-06-07 16:13:57 -06:00
PubSocket *socket = PubSocket::create(message_context.context(), name);
assert(socket);
sockets_[name] = socket;
}
}
2020-10-01 19:45:44 -06:00
int PubMaster::send(const char *name, MessageBuilder &msg) {
auto bytes = msg.toBytes();
return send(name, bytes.begin(), bytes.size());
}
PubMaster::~PubMaster() {
for (auto s : sockets_) delete s.second;
}