aboutsummaryrefslogtreecommitdiffstats
path: root/low-can-binding/binding
diff options
context:
space:
mode:
authorRomain Forlot <romain.forlot@iot.bzh>2019-11-26 16:18:41 +0100
committerRomain Forlot <romain.forlot@iot.bzh>2019-11-28 16:11:46 +0100
commit451598fa9ce4e57a00c9312c04839e0b3dcdf320 (patch)
tree49a6341d98f1a6ca34320d5f6512ac08df1cccfd /low-can-binding/binding
parent68d8bc019fab3e73654a330baf6b8dd7c11859ca (diff)
Integrate the J1939 features : address claiming and write.
This commit allows to write J1939 messages and add the management of the address claiming. Bug-AGL: SPEC-2386 Bug-AGL: SPEC-2976 Signed-off-by: Arthur Guyader <arthur.guyader@iot.bzh> Change-Id: I1bb95a7ba6f6ebe463319c3972d9d46897181d51 Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
Diffstat (limited to 'low-can-binding/binding')
-rw-r--r--low-can-binding/binding/application.cpp19
-rw-r--r--low-can-binding/binding/application.hpp16
-rw-r--r--low-can-binding/binding/low-can-cb.cpp92
-rw-r--r--low-can-binding/binding/low-can-subscription.cpp119
-rw-r--r--low-can-binding/binding/low-can-subscription.hpp4
5 files changed, 202 insertions, 48 deletions
diff --git a/low-can-binding/binding/application.cpp b/low-can-binding/binding/application.cpp
index f0f008c5..d93bf0cf 100644
--- a/low-can-binding/binding/application.cpp
+++ b/low-can-binding/binding/application.cpp
@@ -154,3 +154,22 @@ bool application_t::isEngineOn()
return engine_on;
}
+
+#ifdef USE_FEATURE_J1939
+std::shared_ptr<utils::socketcan_t> application_t::get_socket_address_claiming()
+{
+ return subscription_address_claiming_->get_socket();
+}
+
+std::shared_ptr<low_can_subscription_t> application_t::get_subscription_address_claiming()
+{
+ return subscription_address_claiming_;
+}
+
+
+void application_t::set_subscription_address_claiming(std::shared_ptr<low_can_subscription_t> new_subscription)
+{
+ subscription_address_claiming_ = new_subscription;
+}
+
+#endif \ No newline at end of file
diff --git a/low-can-binding/binding/application.hpp b/low-can-binding/binding/application.hpp
index b73ace71..a5d2285c 100644
--- a/low-can-binding/binding/application.hpp
+++ b/low-can-binding/binding/application.hpp
@@ -26,6 +26,10 @@
#include "../can/message-set.hpp"
#include "../can/signals.hpp"
#include "../diagnostic/diagnostic-manager.hpp"
+#ifdef USE_FEATURE_J1939
+ #include "../utils/socketcan-j1939/socketcan-j1939-data.hpp"
+ #include "../utils/socketcan-j1939/socketcan-j1939-addressclaiming.hpp"
+#endif
///
/// @brief Class represents a configuration attached to the binding.
@@ -48,7 +52,10 @@ class application_t
std::vector<std::shared_ptr<message_set_t> > message_set_; ///< Vector holding all message set from JSON signals description file
std::map<std::string, std::shared_ptr<low_can_subscription_t> > can_devices_; ///< Map containing all independant opened CAN sockets, key is the socket int value.
-
+#ifdef USE_FEATURE_J1939
+ std::shared_ptr<low_can_subscription_t> subscription_address_claiming_; ///< Subscription holding the socketcan J1939 which is in charge of handling the address claiming protocol
+ //std::shared_ptr<utils::socketcan_j1939_addressclaiming_t> socket_address_claiming_;
+#endif
application_t(); ///< Private constructor with implementation generated by the AGL generator.
public:
@@ -84,6 +91,13 @@ class application_t
void set_active_message_set(uint8_t id);
+#ifdef USE_FEATURE_J1939
+ std::shared_ptr<utils::socketcan_t> get_socket_address_claiming();
+
+ std::shared_ptr<low_can_subscription_t> get_subscription_address_claiming();
+
+ void set_subscription_address_claiming(std::shared_ptr<low_can_subscription_t> new_subscription);
+#endif
/*
/// TODO: implement this function as method into can_bus class
/// @brief Pre initialize actions made before CAN bus initialization
diff --git a/low-can-binding/binding/low-can-cb.cpp b/low-can-binding/binding/low-can-cb.cpp
index 9c21b675..5fdd961e 100644
--- a/low-can-binding/binding/low-can-cb.cpp
+++ b/low-can-binding/binding/low-can-cb.cpp
@@ -26,7 +26,6 @@
#include <thread>
#include <wrap-json.h>
#include <systemd/sd-event.h>
-
#include "openxc.pb.h"
#include "application.hpp"
#include "../can/can-encoder.hpp"
@@ -37,6 +36,10 @@
#include "../diagnostic/diagnostic-message.hpp"
#include "../utils/openxc-utils.hpp"
+#ifdef USE_FEATURE_J1939
+ #include "../can/message/j1939-message.hpp"
+ #include <linux/can/j1939.h>
+#endif
///******************************************************************************
///
/// SystemD event loop Callbacks
@@ -82,18 +85,27 @@ static void push_n_notify(std::shared_ptr<message_t> m)
int read_message(sd_event_source *event_source, int fd, uint32_t revents, void *userdata)
{
+
low_can_subscription_t* can_subscription = (low_can_subscription_t*)userdata;
if ((revents & EPOLLIN) != 0)
{
- std::shared_ptr<utils::socketcan_t> s = can_subscription->get_socket();
- std::shared_ptr<message_t> message = s->read_message();
-
- // Sure we got a valid CAN message ?
- if (! message->get_id() == 0 && ! message->get_length() == 0)
+ utils::signals_manager_t& sm = utils::signals_manager_t::instance();
+ std::lock_guard<std::mutex> subscribed_signals_lock(sm.get_subscribed_signals_mutex());
+ if(can_subscription->get_index() != -1)
{
- push_n_notify(message);
+ std::shared_ptr<utils::socketcan_t> s = can_subscription->get_socket();
+ if(s->socket() && s->socket() != -1)
+ {
+ std::shared_ptr<message_t> message = s->read_message();
+
+ // Sure we got a valid CAN message ?
+ if (! message->get_id() == 0 && ! message->get_length() == 0 && message->get_msg_format() != message_format_t::INVALID)
+ {
+ push_n_notify(message);
+ }
+ }
}
}
@@ -164,8 +176,8 @@ static int subscribe_unsubscribe_signal(afb_req_t request,
if( (ret = s[sub_index]->unsubscribe(request)) < 0)
return ret;
+ s.find(sub_index)->second->set_index(-1);
s.erase(sub_index);
-
return ret;
}
@@ -227,7 +239,9 @@ static int subscribe_unsubscribe_diagnostic_messages(afb_req_t request,
else
{
if(sig->get_supported())
- {AFB_DEBUG("%s cancelled due to unsubscribe", sig->get_name().c_str());}
+ {
+ AFB_DEBUG("%s cancelled due to unsubscribe", sig->get_name().c_str());
+ }
else
{
AFB_WARNING("signal: %s isn't supported. Canceling operation.", sig->get_name().c_str());
@@ -240,7 +254,6 @@ static int subscribe_unsubscribe_diagnostic_messages(afb_req_t request,
rets++;
}
-
return rets;
}
@@ -493,6 +506,10 @@ static int send_frame(struct canfd_frame& cfd, const std::string& bus_name, sock
{
return low_can_subscription_t::tx_send(*cd[bus_name], cfd, bus_name);
}
+ else if(type == socket_type::J1939)
+ {
+ return low_can_subscription_t::j1939_send(*cd[bus_name], cfd, bus_name);
+ }
else{
return -1;
}
@@ -517,6 +534,12 @@ static int send_message(message_t *message, const std::string& bus_name, socket_
{
return low_can_subscription_t::tx_send(*cd[bus_name], message, bus_name);
}
+#ifdef USE_FEATURE_J1939
+ else if(type == socket_type::J1939)
+ {
+ return low_can_subscription_t::j1939_send(*cd[bus_name], message, bus_name);
+ }
+#endif
else
{
return -1;
@@ -548,6 +571,10 @@ static void write_raw_frame(afb_req_t request, const std::string& bus_name, mess
{
afb_req_fail(request, "Invalid", "Data array must hold 1 to 8 values.");
}
+ else if(type == socket_type::J1939)
+ {
+ afb_req_fail(request, "Invalid", "Data array too large");
+ }
else
{
afb_req_fail(request, "Invalid", "Invalid socket type");
@@ -583,6 +610,16 @@ static void write_frame(afb_req_t request, const std::string& bus_name, json_obj
message = new can_message_t(CANFD_MAX_DLEN,(uint32_t)id,(uint32_t)length,message_format_t::STANDARD,false,0,data,0);
write_raw_frame(request,bus_name,message,can_data,socket_type::BCM);
}
+#ifdef USE_FEATURE_J1939
+ else if(!wrap_json_unpack(json_value, "{si, si, so !}",
+ "pgn", &id,
+ "length", &length,
+ "data", &can_data))
+ {
+ message = new j1939_message_t(J1939_MAX_DLEN,(uint32_t)length,message_format_t::J1939,data,0,J1939_NO_NAME,(pgn_t)id,J1939_NO_ADDR);
+ write_raw_frame(request,bus_name,message,can_data,socket_type::J1939);
+ }
+#endif
else
{
afb_req_fail(request, "Invalid", "Frame object malformed");
@@ -800,8 +837,9 @@ void list(afb_req_t request)
/// @return Exit code, zero if success.
int init_binding(afb_api_t api)
{
- uint32_t ret = 1;
- can_bus_t& can_bus_manager = application_t::instance().get_can_bus_manager();
+ int ret = 1;
+ application_t& application = application_t::instance();
+ can_bus_t& can_bus_manager = application.get_can_bus_manager();
can_bus_manager.set_can_devices();
can_bus_manager.start_threads();
@@ -829,8 +867,38 @@ int init_binding(afb_api_t api)
subscribe_unsubscribe_diagnostic_messages(request, true, sf.diagnostic_messages, event_filter, s, true);
}
+
+#ifdef USE_FEATURE_J1939
+ std::vector<std::shared_ptr<message_definition_t>> current_messages_definition = application.get_messages_definition();
+ for(std::shared_ptr<message_definition_t> message_definition: current_messages_definition)
+ {
+ if(message_definition->is_j1939())
+ {
+ std::shared_ptr<low_can_subscription_t> low_can_j1939 = std::make_shared<low_can_subscription_t>();
+
+ application.set_subscription_address_claiming(low_can_j1939);
+
+ ret = low_can_subscription_t::open_socket(*low_can_j1939,
+ message_definition->get_bus_device_name(),
+ socket_type::J1939_ADDR_CLAIM);
+ if(ret < 0)
+ {
+ AFB_ERROR("Error open socket address claiming for j1939 protocol");
+ return -1;
+ }
+
+// std::shared_ptr<low_can_subscription_t> saddrclaim = application.get_subscription_address_claiming();
+
+ add_to_event_loop(low_can_j1939);
+ break;
+ }
+ }
+#endif
+
if(ret)
+ {
AFB_ERROR("There was something wrong with CAN device Initialization.");
+ }
return ret;
}
diff --git a/low-can-binding/binding/low-can-subscription.cpp b/low-can-binding/binding/low-can-subscription.cpp
index b31fe48e..bb488887 100644
--- a/low-can-binding/binding/low-can-subscription.cpp
+++ b/low-can-binding/binding/low-can-subscription.cpp
@@ -20,9 +20,8 @@
#include "application.hpp"
#include "canutil/write.h"
#include "../utils/socketcan-bcm.hpp"
-
#ifdef USE_FEATURE_J1939
- #include "../utils/socketcan-j1939.hpp"
+#include "../utils/socketcan-j1939/socketcan-j1939-data.hpp"
#endif
low_can_subscription_t::low_can_subscription_t()
@@ -226,40 +225,24 @@ void low_can_subscription_t::set_max(float max)
event_filter_.max = max;
}
+void low_can_subscription_t::set_index(int index)
+{
+ index_ = index;
+}
+
/// @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.
///
/// @return INVALID_SOCKET on failure, else positive integer
-int low_can_subscription_t::open_socket(low_can_subscription_t &subscription, const std::string& bus_name)
+int low_can_subscription_t::open_socket(low_can_subscription_t &subscription, const std::string& bus_name, socket_type type)
{
- int ret = 0;
+ int ret = -1;
if(! subscription.socket_)
{
-
- #ifdef USE_FEATURE_J1939
- if((subscription.signal_ != nullptr || !bus_name.empty()) && subscription.signal_->get_message()->is_j1939())
+ switch (type)
{
- name_t name = J1939_NO_NAME;
- pgn_t pgn = J1939_NO_PGN;
- uint8_t addr = J1939_NO_ADDR;
- pgn = subscription.signal_->get_message()->get_id();
- if( subscription.signal_ != nullptr)
- {
- std::shared_ptr<utils::socketcan_j1939_t> socket = std::make_shared<utils::socketcan_j1939_t>();
- ret = socket->open(subscription.signal_->get_message()->get_bus_device_name(), name, pgn, addr);
- subscription.socket_ = socket;
- }
- else if ( !bus_name.empty())
+ case socket_type::BCM:
{
- std::shared_ptr<utils::socketcan_j1939_t> socket = std::make_shared<utils::socketcan_j1939_t>();
- ret = socket->open(bus_name, name, pgn, addr);
- subscription.socket_ = socket;
- }
- subscription.index_ = (int)subscription.socket_->socket();
- }
- else
- {
- #endif
if( subscription.signal_ != nullptr)
{
subscription.socket_ = std::make_shared<utils::socketcan_bcm_t>();
@@ -276,13 +259,56 @@ int low_can_subscription_t::open_socket(low_can_subscription_t &subscription, co
ret = subscription.socket_->open(bus_name);
}
subscription.index_ = (int)subscription.socket_->socket();
- #ifdef USE_FEATURE_J1939
+ break;
+ }
+#ifdef USE_FEATURE_J1939
+ case socket_type::J1939_ADDR_CLAIM:
+ {
+ pgn_t pgn = J1939_NO_PGN;
+ if(!bus_name.empty())
+ {
+ std::shared_ptr<utils::socketcan_j1939_addressclaiming_t> socket = std::make_shared<utils::socketcan_j1939_addressclaiming_t>();
+ ret = socket->open(bus_name, pgn);
+ subscription.socket_ = socket;
+ }
+ subscription.index_ = (int)subscription.socket_->socket();
+ break;
+ }
+ case socket_type::J1939:
+ {
+ pgn_t pgn = J1939_NO_PGN;
+ if(subscription.signal_ != nullptr)
+ {
+ pgn = subscription.signal_->get_message()->get_id();
+ std::shared_ptr<utils::socketcan_j1939_data_t> socket = std::make_shared<utils::socketcan_j1939_data_t>();
+ ret = socket->open(subscription.signal_->get_message()->get_bus_device_name(), pgn);
+ subscription.socket_ = socket;
+ }
+ else if(!bus_name.empty())
+ {
+ std::shared_ptr<utils::socketcan_j1939_data_t> socket = std::make_shared<utils::socketcan_j1939_data_t>();
+ ret = socket->open(bus_name, pgn);
+ subscription.socket_ = socket;
+ }
+ subscription.index_ = (int)subscription.socket_->socket();
+ break;
+ }
+#endif
+ default:
+ {
+ AFB_ERROR("Socket format not supported");
+ return INVALID_SOCKET;
+ break;
+ }
}
- #endif
+ }
+ else{
+ ret = subscription.socket_->socket();
}
return ret;
}
+
/// @brief Builds a BCM message head but doesn't set can_frame.
///
/// @returns a bcm_msg with the msg_head parts set and can_frame
@@ -328,7 +354,7 @@ int low_can_subscription_t::create_rx_filter_j1939(low_can_subscription_t &subsc
subscription.signal_= sig;
// Make sure that socket is opened.
- if(open_socket(subscription) < 0)
+ if(open_socket(subscription,"",socket_type::J1939) < 0)
{
return -1;
}
@@ -421,7 +447,7 @@ int low_can_subscription_t::create_rx_filter(std::shared_ptr<diagnostic_message_
int low_can_subscription_t::create_rx_filter_bcm(low_can_subscription_t &subscription, struct bcm_msg& bcm_msg)
{
// Make sure that socket is opened.
- if(subscription.open_socket(subscription) < 0)
+ if(subscription.open_socket(subscription,"",socket_type::BCM) < 0)
{return -1;}
// If it's not an OBD2 CAN ID then just add a simple RX_SETUP job
@@ -463,8 +489,10 @@ int low_can_subscription_t::tx_send(low_can_subscription_t &subscription, messag
canfd_frame cfd = cm->convert_to_canfd_frame();
subscription.add_one_bcm_frame(cfd, bcm_msg);
- if(subscription.open_socket(subscription, bus_name) < 0)
- {return -1;}
+ if(subscription.open_socket(subscription, bus_name,socket_type::BCM) < 0)
+ {
+ return -1;
+ }
cm->set_bcm_msg(bcm_msg);
subscription.socket_->write_message(*cm);
@@ -474,4 +502,27 @@ int low_can_subscription_t::tx_send(low_can_subscription_t &subscription, messag
}
return 0;
-} \ No newline at end of file
+}
+
+#ifdef USE_FEATURE_J1939
+int low_can_subscription_t::j1939_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, socket_type::J1939) < 0)
+ {
+ return -1;
+ }
+
+ j1939_message_t *jm = static_cast<j1939_message_t*>(message);
+ jm->set_sockname(jm->get_pgn(),J1939_NO_NAME,J1939_NO_ADDR);
+ if(subscription.socket_->write_message(*jm) < 0)
+ {
+ AFB_ERROR("Error write j1939 message");
+ return -1;
+ }
+
+ return 0;
+}
+#endif \ 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 5ea1cf17..d0462ecb 100644
--- a/low-can-binding/binding/low-can-subscription.hpp
+++ b/low-can-binding/binding/low-can-subscription.hpp
@@ -89,11 +89,12 @@ public:
void set_frequency(float freq);
void set_min(float min);
void set_max(float max);
+ void set_index(int index);
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);
- static int open_socket(low_can_subscription_t &subscription, const std::string& bus_name = "");
+ static int open_socket(low_can_subscription_t &subscription, const std::string& bus_name = "", socket_type type = socket_type::INVALID);
int create_rx_filter(std::shared_ptr<signal_t> sig);
int create_rx_filter(std::shared_ptr<diagnostic_message_t> sig);
@@ -102,4 +103,5 @@ public:
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);
};