diff options
Diffstat (limited to 'low-can-binding/binding')
-rw-r--r-- | low-can-binding/binding/application-generated.cpp | 182 | ||||
-rw-r--r-- | low-can-binding/binding/low-can-cb.cpp | 116 | ||||
-rw-r--r-- | low-can-binding/binding/low-can-subscription.cpp | 114 | ||||
-rw-r--r-- | low-can-binding/binding/low-can-subscription.hpp | 13 |
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); }; |