summaryrefslogtreecommitdiffstats
path: root/low-can-binding/binding
diff options
context:
space:
mode:
Diffstat (limited to 'low-can-binding/binding')
-rw-r--r--low-can-binding/binding/application-generated.cpp182
-rw-r--r--low-can-binding/binding/low-can-cb.cpp116
-rw-r--r--low-can-binding/binding/low-can-subscription.cpp114
-rw-r--r--low-can-binding/binding/low-can-subscription.hpp13
4 files changed, 382 insertions, 43 deletions
diff --git a/low-can-binding/binding/application-generated.cpp b/low-can-binding/binding/application-generated.cpp
index 47fdafa5..bd1837fc 100644
--- a/low-can-binding/binding/application-generated.cpp
+++ b/low-can-binding/binding/application-generated.cpp
@@ -449,6 +449,188 @@ application_t::application_t()
})}
} // end signals vector
})} // end message_definition entry
+#ifdef USE_FEATURE_ISOTP
+, {std::make_shared<message_definition_t>(message_definition_t{"ls",0x111,"",16,66,frequency_clock_t(5.00000f),true,
+ { // beginning signals vector
+ {std::make_shared<signal_t> (signal_t{
+ "sig1.1",// generic_name
+ 0,// bit_position
+ 16,// bit_size
+ 1.00000f,// factor
+ 0.00000f,// offset
+ 0,// min_value
+ 0,// max_value
+ frequency_clock_t(0.00000f),// frequency
+ true,// send_same
+ false,// force_send_changed
+ {
+ },// states
+ true,// writable
+ nullptr,// decoder
+ nullptr,// encoder
+ false,// received
+ std::make_pair<bool, int>(false, 0),// multiplex
+ 0,// is_big_endian
+ 0,// is_signed
+ ""// unit
+ })},
+ {std::make_shared<signal_t> (signal_t{
+ "sig1.2",// generic_name
+ 16,// bit_position
+ 16,// bit_size
+ 1.00000f,// factor
+ 0.00000f,// offset
+ 0,// min_value
+ 0,// max_value
+ frequency_clock_t(0.00000f),// frequency
+ true,// send_same
+ false,// force_send_changed
+ {
+ },// states
+ true,// writable
+ nullptr,// decoder
+ nullptr,// encoder
+ false,// received
+ std::make_pair<bool, int>(false, 0),// multiplex
+ 0,// is_big_endian
+ 0,// is_signed
+ ""// unit
+ })},
+ {std::make_shared<signal_t> (signal_t{
+ "sig2.1",// generic_name
+ 32,// bit_position
+ 16,// bit_size
+ 1.00000f,// factor
+ 0.00000f,// offset
+ 0,// min_value
+ 0,// max_value
+ frequency_clock_t(0.00000f),// frequency
+ true,// send_same
+ false,// force_send_changed
+ {
+ },// states
+ true,// writable
+ nullptr,// decoder
+ nullptr,// encoder
+ false,// received
+ std::make_pair<bool, int>(false, 0),// multiplex
+ 0,// is_big_endian
+ 0,// is_signed
+ ""// unit
+ })},
+ {std::make_shared<signal_t> (signal_t{
+ "sig2.2",// generic_name
+ 48,// bit_position
+ 16,// bit_size
+ 1.00000f,// factor
+ 0.00000f,// offset
+ 0,// min_value
+ 0,// max_value
+ frequency_clock_t(0.00000f),// frequency
+ true,// send_same
+ false,// force_send_changed
+ {
+ },// states
+ true,// writable
+ nullptr,// decoder
+ nullptr,// encoder
+ false,// received
+ std::make_pair<bool, int>(false, 0),// multiplex
+ 0,// is_big_endian
+ 0,// is_signed
+ ""// unit
+ })},
+ {std::make_shared<signal_t> (signal_t{
+ "sig3.1",// generic_name
+ 64,// bit_position
+ 16,// bit_size
+ 1.00000f,// factor
+ 0.00000f,// offset
+ 0,// min_value
+ 0,// max_value
+ frequency_clock_t(0.00000f),// frequency
+ true,// send_same
+ false,// force_send_changed
+ {
+ },// states
+ true,// writable
+ nullptr,// decoder
+ nullptr,// encoder
+ false,// received
+ std::make_pair<bool, int>(false, 0),// multiplex
+ 0,// is_big_endian
+ 0,// is_signed
+ ""// unit
+ })},
+ {std::make_shared<signal_t> (signal_t{
+ "sig3.2",// generic_name
+ 80,// bit_position
+ 16,// bit_size
+ 1.00000f,// factor
+ 0.00000f,// offset
+ 0,// min_value
+ 0,// max_value
+ frequency_clock_t(0.00000f),// frequency
+ true,// send_same
+ false,// force_send_changed
+ {
+ },// states
+ true,// writable
+ nullptr,// decoder
+ nullptr,// encoder
+ false,// received
+ std::make_pair<bool, int>(false, 0),// multiplex
+ 0,// is_big_endian
+ 0,// is_signed
+ ""// unit
+ })},
+ {std::make_shared<signal_t> (signal_t{
+ "sig4.1",// generic_name
+ 96,// bit_position
+ 16,// bit_size
+ 1.00000f,// factor
+ 0.00000f,// offset
+ 0,// min_value
+ 0,// max_value
+ frequency_clock_t(0.00000f),// frequency
+ true,// send_same
+ false,// force_send_changed
+ {
+ },// states
+ true,// writable
+ nullptr,// decoder
+ nullptr,// encoder
+ false,// received
+ std::make_pair<bool, int>(false, 0),// multiplex
+ 0,// is_big_endian
+ 0,// is_signed
+ ""// unit
+ })},
+ {std::make_shared<signal_t> (signal_t{
+ "sig4.2",// generic_name
+ 112,// bit_position
+ 16,// bit_size
+ 1.00000f,// factor
+ 0.00000f,// offset
+ 0,// min_value
+ 0,// max_value
+ frequency_clock_t(0.00000f),// frequency
+ true,// send_same
+ false,// force_send_changed
+ {
+ },// states
+ true,// writable
+ nullptr,// decoder
+ nullptr,// encoder
+ false,// received
+ std::make_pair<bool, int>(false, 0),// multiplex
+ 0,// is_big_endian
+ 0,// is_signed
+ ""// unit
+ })}
+ } // end signals vector
+ })} // end message_definition entry
+#endif
#ifdef USE_FEATURE_J1939
, {std::make_shared<message_definition_t>(message_definition_t{"j1939",61442,"ETC1",8,18,frequency_clock_t(5.00000f),true,
{ // beginning signals vector
diff --git a/low-can-binding/binding/low-can-cb.cpp b/low-can-binding/binding/low-can-cb.cpp
index c677b172..2c6e2be3 100644
--- a/low-can-binding/binding/low-can-cb.cpp
+++ b/low-can-binding/binding/low-can-cb.cpp
@@ -334,6 +334,12 @@ static event_filter_t generate_filter(json_object* args)
if (json_object_object_get_ex(filter, "max", &obj)
&& (json_object_is_type(obj, json_type_double) || json_object_is_type(obj, json_type_int)))
{event_filter.max = (float)json_object_get_double(obj);}
+ if (json_object_object_get_ex(filter, "rx_id", &obj)
+ && (json_object_is_type(obj, json_type_int)))
+ {event_filter.rx_id = (canid_t) json_object_get_int(obj);}
+ if (json_object_object_get_ex(filter, "tx_id", &obj)
+ && (json_object_is_type(obj, json_type_int)))
+ {event_filter.tx_id = (canid_t) json_object_get_int(obj);}
}
return event_filter;
}
@@ -515,7 +521,7 @@ static int send_frame(struct canfd_frame& cfd, const std::string& bus_name, sock
}
}
*/
-static int send_message(message_t *message, const std::string& bus_name, uint32_t flags)
+static int send_message(message_t *message, const std::string& bus_name, uint32_t flags, event_filter_t &event_filter, std::shared_ptr<signal_t> signal)
{
if(bus_name.empty())
{
@@ -526,14 +532,22 @@ static int send_message(message_t *message, const std::string& bus_name, uint32_
if( cd.count(bus_name) == 0)
{
- cd[bus_name] = std::make_shared<low_can_subscription_t>(low_can_subscription_t());
+ cd[bus_name] = std::make_shared<low_can_subscription_t>(low_can_subscription_t(event_filter));
}
+ cd[bus_name]->set_signal(signal);
+
if(flags&BCM_PROTOCOL)
{
return low_can_subscription_t::tx_send(*cd[bus_name], message, bus_name);
}
+#ifdef USE_FEATURE_ISOTP
+ else if(flags&ISOTP_PROTOCOL)
+ {
+ return low_can_subscription_t::isotp_send(*cd[bus_name], message, bus_name);
+ }
+#endif
#ifdef USE_FEATURE_J1939
else if(flags&J1939_PROTOCOL)
{
@@ -547,7 +561,8 @@ static int send_message(message_t *message, const std::string& bus_name, uint32_
}
-static void write_raw_frame(afb_req_t request, const std::string& bus_name, message_t *message, struct json_object *can_data, uint32_t flags)
+static void write_raw_frame(afb_req_t request, const std::string& bus_name, message_t *message,
+ struct json_object *can_data, uint32_t flags, event_filter_t &event_filter)
{
struct utils::signals_found sf;
@@ -570,17 +585,22 @@ static void write_raw_frame(afb_req_t request, const std::string& bus_name, mess
AFB_DEBUG("CAN_MAX_DLEN");
message->set_maxdlen(CAN_MAX_DLEN);
}
+
+ if(sf.signals[0]->get_message()->is_isotp())
+ {
+ flags = ISOTP_PROTOCOL;
+ message->set_maxdlen(MAX_ISOTP_FRAMES * message->get_maxdlen());
+ }
+ }
+
+#ifdef USE_FEATURE_J1939
+ if(flags&J1939_PROTOCOL)
+ {
+ message->set_maxdlen(J1939_MAX_DLEN);
}
+#endif
- if((message->get_length()> 0 && (
- ((flags&BCM_PROTOCOL) && (
- (message->get_length() <= CANFD_MAX_DLEN * MAX_BCM_CAN_FRAMES && message->get_flags() & CAN_FD_FRAME)
- || (message->get_length() <= CAN_MAX_DLEN * MAX_BCM_CAN_FRAMES && !(message->get_flags() & CAN_FD_FRAME))
- ))
- #ifdef USE_FEATURE_J1939
- || (message->get_length() <= J1939_MAX_DLEN && flags&J1939_PROTOCOL)
- #endif
- )))
+ if(message->get_length() > 0 && message->get_length() <= message->get_maxdlen())
{
std::vector<uint8_t> data;
for (int i = 0 ; i < message->get_length() ; i++)
@@ -601,6 +621,10 @@ static void write_raw_frame(afb_req_t request, const std::string& bus_name, mess
{
afb_req_fail(request, "Invalid", "Frame J1939");
}
+ else if(flags&ISOTP_PROTOCOL)
+ {
+ afb_req_fail(request, "Invalid", "Frame ISOTP");
+ }
else
{
afb_req_fail(request, "Invalid", "Frame");
@@ -608,7 +632,7 @@ static void write_raw_frame(afb_req_t request, const std::string& bus_name, mess
return;
}
- if(! send_message(message, application_t::instance().get_can_bus_manager().get_can_device_name(bus_name),flags))
+ if(! send_message(message, application_t::instance().get_can_bus_manager().get_can_device_name(bus_name), flags, event_filter, sf.signals[0]))
{
afb_req_success(request, nullptr, "Message correctly sent");
}
@@ -624,7 +648,7 @@ static void write_raw_frame(afb_req_t request, const std::string& bus_name, mess
}
-static void write_frame(afb_req_t request, const std::string& bus_name, json_object *json_value)
+static void write_frame(afb_req_t request, const std::string& bus_name, json_object *json_value, event_filter_t &event_filter)
{
message_t *message;
int id;
@@ -640,7 +664,7 @@ static void write_frame(afb_req_t request, const std::string& bus_name, json_obj
"can_data", &can_data))
{
message = new can_message_t(0,(uint32_t)id,(uint32_t)length,false,0,data,0);
- write_raw_frame(request,bus_name,message,can_data,BCM_PROTOCOL);
+ write_raw_frame(request,bus_name,message,can_data,BCM_PROTOCOL,event_filter);
}
#ifdef USE_FEATURE_J1939
else if(!wrap_json_unpack(json_value, "{si, si, so !}",
@@ -649,7 +673,7 @@ static void write_frame(afb_req_t request, const std::string& bus_name, json_obj
"data", &can_data))
{
message = new j1939_message_t((uint32_t)length,data,0,J1939_NO_NAME,(pgn_t)id,J1939_NO_ADDR);
- write_raw_frame(request,bus_name,message,can_data,J1939_PROTOCOL);
+ write_raw_frame(request,bus_name,message,can_data,J1939_PROTOCOL, event_filter);
}
#endif
else
@@ -660,7 +684,7 @@ static void write_frame(afb_req_t request, const std::string& bus_name, json_obj
delete message;
}
-static void write_signal(afb_req_t request, const std::string& name, json_object *json_value)
+static void write_signal(afb_req_t request, const std::string& name, json_object *json_value, event_filter_t &event_filter)
{
struct canfd_frame cfd;
struct utils::signals_found sf;
@@ -679,7 +703,7 @@ static void write_signal(afb_req_t request, const std::string& name, json_object
return;
}
- std::shared_ptr<signal_t>& sig = sf.signals[0];
+ std::shared_ptr<signal_t> sig = sf.signals[0];
if(! sig->get_writable())
{
afb_req_fail_f(request, "%s isn't writable. Message not sent.", sig->get_name().c_str());
@@ -696,6 +720,10 @@ static void write_signal(afb_req_t request, const std::string& name, json_object
{
flags = J1939_PROTOCOL;
}
+ else if(sig->get_message()->is_isotp())
+ {
+ flags = ISOTP_PROTOCOL;
+ }
else
{
flags = BCM_PROTOCOL;
@@ -704,7 +732,7 @@ static void write_signal(afb_req_t request, const std::string& name, json_object
// cfd = encoder_t::build_frame(sig, value);
message_t *message = encoder_t::build_message(sig,value,false,false);
- if(! send_message(message, sig->get_message()->get_bus_device_name(), flags) && send)
+ if(! send_message(message, sig->get_message()->get_bus_device_name(), flags, event_filter, sig) && send)
{
afb_req_success(request, nullptr, "Message correctly sent");
}
@@ -727,25 +755,43 @@ static void write_signal(afb_req_t request, const std::string& name, json_object
void write(afb_req_t request)
{
- struct json_object* args = nullptr, *json_value = nullptr;
- const char *name = nullptr;
-
+ struct json_object* args = nullptr, *json_value = nullptr, *name = nullptr;
args = afb_req_json(request);
- // Process about Raw CAN message on CAN bus directly
- if (args != NULL && ! wrap_json_unpack(args, "{ss, so !}",
- "bus_name", &name,
- "frame", &json_value))
- write_frame(request, name, json_value);
-
- // Search signal then encode value.
- else if(args != NULL &&
- ! wrap_json_unpack(args, "{ss, so !}",
- "signal_name", &name,
- "signal_value", &json_value))
- write_signal(request, std::string(name), json_value);
+ if(args != NULL)
+ {
+ event_filter_t event_filter = generate_filter(args);
+
+ if(json_object_object_get_ex(args,"bus_name",&name))
+ {
+ if(json_object_object_get_ex(args,"frame",&json_value))
+ {
+ write_frame(request, (std::string)json_object_get_string(name), json_value, event_filter);
+ }
+ else
+ {
+ afb_req_fail(request, "Error", "Request argument malformed");
+ }
+ }
+ else if(json_object_object_get_ex(args,"signal_name",&name))
+ {
+ if(json_object_object_get_ex(args,"signal_value",&json_value))
+ {
+ write_signal(request, (std::string)json_object_get_string(name), json_value, event_filter);
+ }
+ else
+ {
+ afb_req_fail(request, "Error", "Request argument malformed");
+ }
+ }
+ else {
+ afb_req_fail(request, "Error", "Request argument malformed");
+ }
+ }
else
- afb_req_fail(request, "Error", "Request argument malformed");
+ {
+ afb_req_fail(request, "Error", "Request argument null");
+ }
}
static struct json_object *get_signals_value(const std::string& name)
diff --git a/low-can-binding/binding/low-can-subscription.cpp b/low-can-binding/binding/low-can-subscription.cpp
index 0f4bf0c9..6d02b101 100644
--- a/low-can-binding/binding/low-can-subscription.cpp
+++ b/low-can-binding/binding/low-can-subscription.cpp
@@ -22,6 +22,10 @@
#include "../utils/socketcan-bcm.hpp"
#include "../can/can-encoder.hpp"
+#ifdef USE_FEATURE_ISOTP
+#include "../utils/socketcan-isotp.hpp"
+#endif
+
#ifdef USE_FEATURE_J1939
#include "../utils/socketcan-j1939/socketcan-j1939-data.hpp"
#endif
@@ -212,6 +216,16 @@ float low_can_subscription_t::get_max() const
return event_filter_.max;
}
+canid_t low_can_subscription_t::get_rx_id() const
+{
+ return event_filter_.rx_id;
+}
+
+canid_t low_can_subscription_t::get_tx_id() const
+{
+ return event_filter_.tx_id;
+}
+
std::shared_ptr<utils::socketcan_t> low_can_subscription_t::get_socket()
{
return socket_;
@@ -232,11 +246,27 @@ void low_can_subscription_t::set_max(float max)
event_filter_.max = max;
}
+void low_can_subscription_t::set_rx_id(canid_t rx_id)
+{
+ event_filter_.rx_id = rx_id;
+}
+
+void low_can_subscription_t::set_tx_id(canid_t tx_id)
+{
+ event_filter_.tx_id = tx_id;
+}
+
void low_can_subscription_t::set_index(int index)
{
index_ = index;
}
+void low_can_subscription_t::set_signal(std::shared_ptr<signal_t> signal)
+{
+ signal_ = signal;
+}
+
+
/// @brief Based upon which object is a subscribed CAN signal or diagnostic message
/// it will open the socket with the required CAN bus device name.
///
@@ -265,6 +295,36 @@ int low_can_subscription_t::open_socket(low_can_subscription_t &subscription, co
}
subscription.index_ = (int)subscription.socket_->socket();
}
+#ifdef USE_FEATURE_ISOTP
+ else if(flags&ISOTP_PROTOCOL)
+ {
+ if(subscription.signal_ != nullptr)
+ {
+ canid_t rx = NO_CAN_ID;
+ canid_t tx = NO_CAN_ID;
+ if(flags&ISOTP_SEND)
+ {
+ rx = subscription.get_rx_id();
+ tx = subscription.signal_->get_message()->get_id();
+ }
+ else if(flags&ISOTP_RECEIVE)
+ {
+ rx = subscription.signal_->get_message()->get_id();
+ tx = subscription.get_tx_id();
+ }
+ std::shared_ptr<utils::socketcan_isotp_t> socket = std::make_shared<utils::socketcan_isotp_t>();
+ ret = socket->open(subscription.signal_->get_message()->get_bus_device_name(),rx,tx);
+ subscription.socket_ = socket;
+ }
+ else if(!bus_name.empty())
+ {
+ std::shared_ptr<utils::socketcan_isotp_t> socket = std::make_shared<utils::socketcan_isotp_t>();
+ ret = socket->open(bus_name, subscription.get_rx_id(),subscription.get_tx_id());
+ subscription.socket_ = socket;
+ }
+ subscription.index_ = (int)subscription.socket_->socket();
+ }
+#endif
#ifdef USE_FEATURE_J1939
else if(flags&J1939_ADDR_CLAIM_PROTOCOL)
{
@@ -374,6 +434,18 @@ int low_can_subscription_t::create_rx_filter_j1939(low_can_subscription_t &subsc
}
#endif
+int low_can_subscription_t::create_rx_filter_isotp(low_can_subscription_t &subscription, std::shared_ptr<signal_t> sig)
+{
+ subscription.signal_= sig;
+
+ // Make sure that socket is opened.
+ if(open_socket(subscription,"",ISOTP_PROTOCOL|ISOTP_RECEIVE) < 0)
+ {
+ return -1;
+ }
+ return 0;
+}
+
/// @brief Create a RX_SETUP receive job to be used by the BCM socket for a CAN signal
/// subscription
///
@@ -462,18 +534,27 @@ int low_can_subscription_t::create_rx_filter_can(low_can_subscription_t &subscri
int low_can_subscription_t::create_rx_filter(std::shared_ptr<signal_t> sig)
{
- #ifdef USE_FEATURE_J1939
- if(sig->get_message()->is_j1939())
+ if(!sig->get_message()->is_isotp() && !sig->get_message()->is_j1939())
+ {
+ return low_can_subscription_t::create_rx_filter_can(*this, sig);
+ }
+#ifdef USE_FEATURE_ISOTP
+ else if(sig->get_message()->is_isotp())
+ {
+ return low_can_subscription_t::create_rx_filter_isotp(*this,sig);
+ }
+#endif
+#ifdef USE_FEATURE_J1939
+ else if(sig->get_message()->is_j1939())
{
return low_can_subscription_t::create_rx_filter_j1939(*this, sig);
}
+#endif
else
{
- #endif
- return low_can_subscription_t::create_rx_filter_can(*this, sig);
- #ifdef USE_FEATURE_J1939
+ AFB_ERROR("Signal can't be j1939 and isotp");
+ return -1;
}
- #endif
}
@@ -607,3 +688,24 @@ int low_can_subscription_t::j1939_send(low_can_subscription_t &subscription, mes
return 0;
}
#endif
+
+
+int low_can_subscription_t::isotp_send(low_can_subscription_t &subscription, message_t *message, const std::string& bus_name)
+{
+ //struct bcm_msg bcm_msg = subscription.make_bcm_head(TX_SEND, cfd.can_id);
+ //subscription.add_one_bcm_frame(cfd, bcm_msg);
+
+ if(subscription.open_socket(subscription, bus_name, ISOTP_PROTOCOL|ISOTP_SEND) < 0)
+ {
+ return -1;
+ }
+
+ can_message_t *cm = static_cast<can_message_t*>(message);
+ if(subscription.socket_->write_message(*cm) < 0)
+ {
+ AFB_ERROR("Error write iso tp message");
+ return -1;
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/low-can-binding/binding/low-can-subscription.hpp b/low-can-binding/binding/low-can-subscription.hpp
index b152e4b2..3f2c3acd 100644
--- a/low-can-binding/binding/low-can-subscription.hpp
+++ b/low-can-binding/binding/low-can-subscription.hpp
@@ -35,10 +35,12 @@ struct event_filter_t
float frequency; ///< frequency - Maximum frequency which will be received and pushed to a subscribed event.
float min; ///< min - Minimum value that the signal doesn't have to go below to be pushed.
float max; ///< max - Maximum value that the signal doesn't have to go above to be pushed.
+ canid_t rx_id;
+ canid_t tx_id;
- event_filter_t() : frequency{0}, min{-__FLT_MAX__}, max{__FLT_MAX__} {};
+ event_filter_t() : frequency{0}, min{-__FLT_MAX__}, max{__FLT_MAX__}, rx_id{NO_CAN_ID}, tx_id{NO_CAN_ID} {};
bool operator==(const event_filter_t& ext) const {
- return frequency == ext.frequency && min == ext.min && max == ext.max;
+ return frequency == ext.frequency && min == ext.min && max == ext.max && rx_id == ext.rx_id && tx_id == ext.tx_id;
}
};
@@ -84,12 +86,17 @@ public:
float get_frequency() const;
float get_min() const;
float get_max() const;
+ canid_t get_rx_id() const;
+ canid_t get_tx_id() const;
std::shared_ptr<utils::socketcan_t> get_socket();
void set_frequency(float freq);
void set_min(float min);
void set_max(float max);
void set_index(int index);
+ void set_rx_id(canid_t rx_id);
+ void set_tx_id(canid_t tx_id);
+ void set_signal(std::shared_ptr<signal_t> signal);
static struct bcm_msg make_bcm_head(uint32_t opcode, uint32_t can_id = 0, uint32_t flags = 0, const struct timeval& timeout = {0,0}, const struct timeval& frequency_thinning = {0,0});
static void add_one_bcm_frame(struct canfd_frame& cfd, struct bcm_msg& bcm_msg);
@@ -101,8 +108,10 @@ public:
int create_rx_filter(std::shared_ptr<diagnostic_message_t> sig);
static int create_rx_filter_can(low_can_subscription_t &subscription, std::shared_ptr<signal_t> sig);
static int create_rx_filter_j1939(low_can_subscription_t &subscription, std::shared_ptr<signal_t> sig);
+ static int create_rx_filter_isotp(low_can_subscription_t &subscription, std::shared_ptr<signal_t> sig);
static int create_rx_filter_bcm(low_can_subscription_t &subscription, bcm_msg& bcm_msg);
static int tx_send(low_can_subscription_t &subscription, message_t *message, const std::string& bus_name);
static int j1939_send(low_can_subscription_t &subscription, message_t *message, const std::string& bus_name);
+ static int isotp_send(low_can_subscription_t &subscription, message_t *message, const std::string& bus_name);
};