#include "cereal/messaging/messaging.h" #include "selfdrive/pandad/panda.h" #include "opendbc/can/common.h" void can_list_to_can_capnp_cpp(const std::vector &can_list, std::string &out, bool sendcan, bool valid) { MessageBuilder msg; auto event = msg.initEvent(valid); auto canData = sendcan ? event.initSendcan(can_list.size()) : event.initCan(can_list.size()); int j = 0; for (auto it = can_list.begin(); it != can_list.end(); it++, j++) { auto c = canData[j]; c.setAddress(it->address); c.setDat(kj::arrayPtr((uint8_t*)it->dat.data(), it->dat.size())); c.setSrc(it->src); } const uint64_t msg_size = capnp::computeSerializedSizeInWords(msg) * sizeof(capnp::word); out.resize(msg_size); kj::ArrayOutputStream output_stream(kj::ArrayPtr((unsigned char *)out.data(), msg_size)); capnp::writeMessage(output_stream, msg); } // Converts a vector of Cap'n Proto serialized can strings into a vector of CanData structures. void can_capnp_to_can_list_cpp(const std::vector &strings, std::vector &can_list, bool sendcan) { AlignedBuffer aligned_buf; can_list.reserve(strings.size()); for (const auto &str : strings) { // extract the messages capnp::FlatArrayMessageReader reader(aligned_buf.align(str.data(), str.size())); cereal::Event::Reader event = reader.getRoot(); auto frames = sendcan ? event.getSendcan() : event.getCan(); // Add new CanData entry CanData &can_data = can_list.emplace_back(); can_data.nanos = event.getLogMonoTime(); can_data.frames.reserve(frames.size()); // Populate CAN frames for (const auto &frame : frames) { CanFrame &can_frame = can_data.frames.emplace_back(); can_frame.src = frame.getSrc(); can_frame.address = frame.getAddress(); // Copy CAN data auto dat = frame.getDat(); can_frame.dat.assign(dat.begin(), dat.end()); } } }