Skip to content

Commit

Permalink
CANParser: parse DBC from stream (commaai#718)
Browse files Browse the repository at this point in the history
  • Loading branch information
deanlee committed Oct 18, 2022
1 parent dde0ff6 commit c131dce
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 20 deletions.
11 changes: 11 additions & 0 deletions can/common_dbc.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ struct DBC {
std::vector<Val> vals;
};

typedef struct ChecksumState {
int checksum_size;
int counter_size;
int checksum_start_bit;
int counter_start_bit;
bool little_endian;
SignalType checksum_type;
unsigned int (*calc_checksum)(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d);
} ChecksumState;

DBC* dbc_parse(const std::string& dbc_path);
DBC* dbc_parse_from_stream(const std::string &dbc_name, std::istream &stream, ChecksumState *checksum = nullptr);
const DBC* dbc_lookup(const std::string& dbc_name);
std::vector<std::string> get_dbc_names();
33 changes: 13 additions & 20 deletions can/dbc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,6 @@ inline std::string& trim(std::string& s, const char* t = " \t\n\r\f\v") {
return s.erase(0, s.find_first_not_of(t));
}

typedef struct ChecksumState {
int checksum_size;
int counter_size;
int checksum_start_bit;
int counter_start_bit;
bool little_endian;
SignalType checksum_type;
unsigned int (*calc_checksum)(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d);
} ChecksumState;

ChecksumState* get_checksum(const std::string& dbc_name) {
ChecksumState* s = nullptr;
if (startswith(dbc_name, {"honda_", "acura_"})) {
Expand Down Expand Up @@ -107,14 +97,7 @@ void set_signal_type(Signal& s, ChecksumState* chk, const std::string& dbc_name,
}
}

DBC* dbc_parse(const std::string& dbc_path) {
std::ifstream infile(dbc_path);
if (!infile) return nullptr;

const std::string dbc_name = std::filesystem::path(dbc_path).filename();

std::unique_ptr<ChecksumState> checksum(get_checksum(dbc_name));

DBC* dbc_parse_from_stream(const std::string &dbc_name, std::istream &stream, ChecksumState *checksum) {
uint32_t address = 0;
std::set<uint32_t> address_set;
std::set<std::string> msg_name_set;
Expand All @@ -134,7 +117,7 @@ DBC* dbc_parse(const std::string& dbc_path) {
int line_num = 0;
std::smatch match;
// TODO: see if we can speed up the regex statements in this loop, SG_ is specifically the slowest
while (std::getline(infile, line)) {
while (std::getline(stream, line)) {
line = trim(line);
line_num += 1;
if (startswith(line, "BO_ ")) {
Expand Down Expand Up @@ -168,7 +151,7 @@ DBC* dbc_parse(const std::string& dbc_path) {
sig.is_signed = match[offset + 5].str() == "-";
sig.factor = std::stod(match[offset + 6].str());
sig.offset = std::stod(match[offset + 7].str());
set_signal_type(sig, checksum.get(), dbc_name, line_num);
set_signal_type(sig, checksum, dbc_name, line_num);
if (sig.is_little_endian) {
sig.lsb = sig.start_bit;
sig.msb = sig.start_bit + sig.size - 1;
Expand Down Expand Up @@ -213,6 +196,16 @@ DBC* dbc_parse(const std::string& dbc_path) {
return dbc;
}

DBC* dbc_parse(const std::string& dbc_path) {
std::ifstream infile(dbc_path);
if (!infile) return nullptr;

const std::string dbc_name = std::filesystem::path(dbc_path).filename();

std::unique_ptr<ChecksumState> checksum(get_checksum(dbc_name));
return dbc_parse_from_stream(dbc_name, infile, checksum.get());
}

const std::string get_dbc_root_path() {
char *basedir = std::getenv("BASEDIR");
if (basedir != NULL) {
Expand Down

0 comments on commit c131dce

Please sign in to comment.