#include "can-message.hpp"
#include "../low-can-binding.hpp"
#include "canutil/write.h"
+#include "../bitfield/bitfield.h"
/// @brief Class constructor
///
{
return index_;
}
+utils::socketcan_t& can_bus_dev_t::get_socket()
+{
+ return can_socket_;
}
/// @brief Open the can socket and returning it
struct utils::canfd_bcm_msg bcm_msg;
uint8_t bit_size = s.get_bit_size();
- float val = (float)exp2(bit_size);
- uint64_t filter = eightbyte_encode_float(val, s.get_bit_position(), bit_size, s.get_factor(), s.get_offset());
+ float val = (float)exp2(bit_size)-1;
bcm_msg.msg_head.opcode = RX_SETUP;
bcm_msg.msg_head.can_id = can_id;
bcm_msg.msg_head.nframes = 1;
- U64_DATA(&bcm_msg.frames[0]) = filter;
+ bitfield_encode_float(val, s.get_bit_position(), bit_size, s.get_factor(), s.get_offset(), bcm_msg.frames[0].data, CANFD_MAX_DLEN);
if(can_socket_ << bcm_msg)
return 0;
std::map<std::string, std::shared_ptr<can_bus_dev_t>> can_bus_t::can_devices_;
+/// @brief Listen for all device sockets and fill can_messages_queue with them.
+/// Reading blocks until message arrive on listened sockets.
+///
+/// @return 0 if ok -1 if not
+int can_bus_t::can_reader()
+{
+ fd_set rfds;
+ int sock_max = INVALID_SOCKET;
+
+ FD_ZERO(&rfds);
+
+ for(auto& can_dev : can_devices_)
+ {
+ FD_SET(can_dev.second->get_socket().socket(), &rfds);
+ if (sock_max < can_dev.second->get_socket().socket())
+ sock_max = can_dev.second->get_socket().socket();
+ }
+
+ int ret;
+ while(is_reading_)
+ {
+ ret = select(sock_max + 1, &rfds, nullptr, nullptr, nullptr);
+
+ if(ret == -1)
+ perror("select()");
+ else if(ret > 0)
+ {
+ for(const auto& s: can_devices_)
+ {
+ if(FD_ISSET(s.second->get_socket().socket(), &rfds))
+ {
+ can_message_t msg;
+ s.second->get_socket() >> msg;
+ push_new_can_message(msg);
+ }
+ }
+ }
+ else
+ printf("Timeout\n");
+ }
+ return 0;
+}
+
/// @brief Will make the decoding operation on a classic CAN message. It will not
/// handle CAN commands nor diagnostic messages that have their own method to get
/// this happens.
/// and push subscribed events.
void can_bus_t::start_threads()
{
+ is_reading_ = true;
+ th_reading_ = std::thread(&can_bus_t::can_reader, this);
+ if(!th_reading_.joinable())
+ is_reading_ = false;
+
is_decoding_ = true;
th_decoding_ = std::thread(&can_bus_t::can_decode_message, this);
if(!th_decoding_.joinable())
/// they'll finish their job.
void can_bus_t::stop_threads()
{
+ is_reading_ = false;
is_decoding_ = false;
is_pushing_ = false;
}
can_bus_t::can_devices_[device]->configure();
DEBUG(binder_interface, "%s: Start reading thread", __FUNCTION__);
NOTICE(binder_interface, "%s: %s device opened and reading", __FUNCTION__, device.c_str());
- can_bus_t::can_devices_[device]->start_reading(*this);
+ //can_bus_t::can_devices_[device]->start_reading(*this);
i++;
}
else
int process_can_signals(can_message_t& can_message);
int process_diagnostic_signals(diagnostic_manager_t& manager, const can_message_t& can_message);
+ int can_reader();
+ std::thread th_reading_; ///< Thread handling read the socket can device filling can_message_q_ queue of can_bus_t
+ bool is_reading_ = false; ///< boolean telling whether or not reading is running or not
+
void can_decode_message();
std::thread th_decoding_; ///< thread that'll handle decoding a can frame
bool is_decoding_ = false; ///< boolean member controling thread while loop