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.
120 lines
3.9 KiB
120 lines
3.9 KiB
#pragma once
|
|
|
|
#include <cstring>
|
|
#include <map>
|
|
#include <set>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <utility>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include "opendbc/can/logger.h"
|
|
#include "opendbc/can/common_dbc.h"
|
|
|
|
#define INFO printf
|
|
#define WARN printf
|
|
#define DEBUG(...)
|
|
//#define DEBUG printf
|
|
|
|
#define MAX_BAD_COUNTER 5
|
|
#define CAN_INVALID_CNT 5
|
|
|
|
// Car specific functions
|
|
void pedal_setup_signal(Signal &sig, const std::string& dbc_name, int line_num);
|
|
void tesla_setup_signal(Signal &sig, const std::string& dbc_name, int line_num);
|
|
|
|
unsigned int honda_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d);
|
|
unsigned int toyota_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d);
|
|
unsigned int subaru_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d);
|
|
unsigned int chrysler_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d);
|
|
unsigned int volkswagen_mqb_meb_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d);
|
|
unsigned int xor_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d);
|
|
unsigned int hkg_can_fd_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d);
|
|
unsigned int fca_giorgio_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d);
|
|
unsigned int pedal_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d);
|
|
unsigned int tesla_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d);
|
|
|
|
#define DBC_ASSERT(condition, message) \
|
|
do { \
|
|
if (!(condition)) { \
|
|
std::stringstream is; \
|
|
is << "[" << dbc_name << ":" << line_num << "] " << message; \
|
|
throw std::runtime_error(is.str()); \
|
|
} \
|
|
} while (false)
|
|
|
|
inline bool endswith(const std::string& str, const char* suffix) {
|
|
return str.find(suffix, str.length() - strlen(suffix)) != std::string::npos;
|
|
}
|
|
|
|
struct CanFrame {
|
|
long src;
|
|
uint32_t address;
|
|
std::vector<uint8_t> dat;
|
|
};
|
|
|
|
struct CanData {
|
|
uint64_t nanos;
|
|
std::vector<CanFrame> frames;
|
|
};
|
|
|
|
class MessageState {
|
|
public:
|
|
std::string name;
|
|
uint32_t address;
|
|
unsigned int size;
|
|
|
|
std::vector<Signal> parse_sigs;
|
|
std::vector<double> vals;
|
|
std::vector<std::vector<double>> all_vals;
|
|
|
|
uint64_t last_seen_nanos;
|
|
uint64_t check_threshold;
|
|
|
|
uint8_t counter;
|
|
uint8_t counter_fail;
|
|
|
|
bool ignore_checksum = false;
|
|
bool ignore_counter = false;
|
|
|
|
bool parse(uint64_t nanos, const std::vector<uint8_t> &dat);
|
|
bool update_counter_generic(int64_t v, int cnt_size);
|
|
};
|
|
|
|
class CANParser {
|
|
private:
|
|
const int bus;
|
|
const DBC *dbc = NULL;
|
|
std::unordered_map<uint32_t, MessageState> message_states;
|
|
|
|
public:
|
|
bool can_valid = false;
|
|
bool bus_timeout = false;
|
|
uint64_t first_nanos = 0;
|
|
uint64_t last_nonempty_nanos = 0;
|
|
uint64_t bus_timeout_threshold = 0;
|
|
uint64_t can_invalid_cnt = CAN_INVALID_CNT;
|
|
|
|
CANParser(int abus, const std::string& dbc_name,
|
|
const std::vector<std::pair<uint32_t, int>> &messages);
|
|
CANParser(int abus, const std::string& dbc_name, bool ignore_checksum, bool ignore_counter);
|
|
std::set<uint32_t> update(const std::vector<CanData> &can_data);
|
|
MessageState *getMessageState(uint32_t address) { return &message_states.at(address); }
|
|
|
|
protected:
|
|
void UpdateCans(const CanData &can, std::set<uint32_t> &updated_addresses);
|
|
void UpdateValid(uint64_t nanos);
|
|
};
|
|
|
|
class CANPacker {
|
|
private:
|
|
const DBC *dbc = NULL;
|
|
std::map<std::pair<uint32_t, std::string>, Signal> signal_lookup;
|
|
std::map<uint32_t, uint32_t> counters;
|
|
|
|
public:
|
|
CANPacker(const std::string& dbc_name);
|
|
std::vector<uint8_t> pack(uint32_t address, const std::vector<SignalPackValue> &values);
|
|
const Msg* lookup_message(uint32_t address);
|
|
};
|
|
|