*
*********************************************************************************/
-CanBus_c::CanBus_c(afb_binding_interface *itf, const std:string& dev_name)
+can_bus_t::can_bus_t(afb_binding_interface *itf, const std:string& dev_name)
+ : interface{itf}, deviceName{dev_name}
{
- interface = itf;
- deviceName = dev_name;
}
-int CanBus_c::open()
+int can_bus_t::open()
{
const int canfd_on = 1;
struct ifreq ifr;
struct timeval timeout = {1, 0};
- DEBUG(interface, "open_can_dev: CAN Handler socket : %d", socket);
- if (socket >= 0)
- close(socket);
+ DEBUG(interface_, "open_can_dev: CAN Handler socket : %d", can_socket_);
+ if (can_socket_ >= 0)
+ return 0;
- socket = socket(PF_CAN, SOCK_RAW, CAN_RAW);
+ can_socket_ = ::socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (socket < 0)
{
- ERROR(interface, "open_can_dev: socket could not be created");
+ ERROR(interface_, "open_can_dev: socket could not be created");
}
else
{
/* Set timeout for read */
- setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
+ ::setsockopt(can_socket_, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
/* try to switch the socket into CAN_FD mode */
- if (setsockopt(socket, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on)) < 0)
+ if (::setsockopt(can_socket_, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on)) < 0)
{
- NOTICE(interface, "open_can_dev: Can not switch into CAN Extended frame format.");
- is_fdmode_on = false;
+ NOTICE(interface_, "open_can_dev: Can not switch into CAN Extended frame format.");
+ is_fdmode_on_ = false;
} else {
- is_fdmode_on = true;
+ is_fdmode_on_ = true;
}
/* Attempts to open a socket to CAN bus */
- strcpy(ifr.ifr_name, device);
- if(ioctl(socket, SIOCGIFINDEX, &ifr) < 0)
- ERROR(interface, "open_can_dev: ioctl failed");
+ ::strcpy(ifr.ifr_name, device);
+ if(ioctl(can_socket_, SIOCGIFINDEX, &ifr) < 0)
+ ERROR(interface_, "open_can_dev: ioctl failed");
else
{
txAddress.can_family = AF_CAN;
txAddress.can_ifindex = ifr.ifr_ifindex;
/* And bind it to txAddress */
- if (bind(socket, (struct sockaddr *)&txAddress, sizeof(txAddress)) < 0)
+ if (::bind(can_socket_, (struct sockaddr *)&txAddress_, sizeof(txAddress_)) < 0)
{
- ERROR(interface, "open_can_dev: bind failed");
+ ERROR(interface_, "open_can_dev: bind failed");
}
else
{
- fcntl(socket, F_SETFL, O_NONBLOCK);
+ ::fcntl(can_socket_, F_SETFL, O_NONBLOCK);
return 0;
}
}
- close(socket);
- socket = -1;
+ close();
}
return -1;
}
-int CanBus_c::close()
+int can_bus_t::close()
{
- close(socket);
- socket = -1;
+ ::close(can_socket_);
+ can_socket_ = -1;
}
-void CanBus_c::start_threads()
+
+canfd_frame can_bus_t::can_read()
{
- std::queue <CanMessage_c> can_message_q;
+ ssize_t nbytes;
+ int maxdlen;
+ canfd_frame canfd_frame;
+
+ /* Test that socket is really opened */
+ if (can_socket_ < 0)
+ {
+ ERROR(interface_, "read_can: Socket unavailable. Closing thread.");
+ is_running_ = false;
+ }
+
+ nbytes = ::read(can_socket_, &canfd_frame, CANFD_MTU);
- th_reading = std::thread(can_reader, interface, socket, can_message_q);
- th_decoding = std::thread(can_decoder, interface, can_message_q, can_message_q);
- th_pushing = std::thread(can_event_push, interface, can_message_q);
+ switch(nbytes)
+ {
+ case CANFD_MTU:
+ DEBUG(interface_, "read_can: Got an CAN FD frame with length %d", canfd_frame.len);
+ maxdlen = CANFD_MAX_DLEN;
+ break;
+ case CAN_MTU:
+ DEBUG(interface_, "read_can: Got a legacy CAN frame with length %d", canfd_frame.len);
+ maxdlen = CAN_MAX_DLEN;
+ break;
+ default:
+ if (errno == ENETDOWN)
+ ERROR(interface_, "read_can: %s interface down", device);
+ ERROR(interface_, "read_can: Error reading CAN bus");
+ ::memset(&canfd_frame, 0, sizeof(canfd_frame));
+ break;
+ }
+
+ return canfd_frame;
+}
+
+void can_bus_t::start_threads()
+{
+ th_reading_ = std::thread(can_reader, interface, socket, can_message_q_);
+ is_running_ = true;
+
+ th_decoding_ = std::thread(can_decoder, interface, can_message_q, can_message_q_);
+ th_pushing_ = std::thread(can_event_push, interface, can_message_q_);
}
/*
- * Send a can message from a CanMessage_c object.
+ * Return is_running_ bool
*/
-int CanBus_c::send_can_message(CanMessage_c can_msg)
+bool can_bus_t::is_running()
+{
+ return is_running_;
+}
+
+/*
+ * Send a can message from a can_message_t object.
+ */
+int can_bus_t::send_can_message(can_message_t &can_msg)
{
int nbytes;
canfd_frame *f;
f = can_msg.convert_to_canfd_frame();
- if(socket >= 0)
+ if(can_socket_ >= 0)
{
- nbytes = sendto(socket, &f, sizeof(struct canfd_frame), 0,
+ nbytes = ::sendto(can_socket_, &f, sizeof(struct canfd_frame), 0,
(struct sockaddr*)&txAddress, sizeof(txAddress));
if (nbytes == -1)
{
- ERROR(interface, "send_can_message: Sending CAN frame failed.");
+ ERROR(interface_, "send_can_message: Sending CAN frame failed.");
return -1;
}
return nbytes;
}
else
{
- ERROR(interface, "send_can_message: socket not initialized. Attempt to reopen can device socket.");
- open_can_dev();
+ ERROR(interface_, "send_can_message: socket not initialized. Attempt to reopen can device socket.");
+ open();
}
return 0;
}
+/*
+ * Get a CanMessage from can_message_q and return it
+ * then point to the next CanMessage in queue.
+ *
+ * Return the next queue element or NULL if queue is empty.
+ */
+can_message_t* can_bus_t::next_can_message()
+{
+ if(! can_message_q_.empty())
+ {
+ can_message_t can_msg = can_message_q_.front();
+ can_message_q_.pop()
+ return &can_msg;
+ }
+
+ return nullptr;
+}
+
+void can_bus_t::insert_new_can_message(can_message_t &can_msg)
+{
+ can_message_q_.push(can_msg);
+}
+
+/*
+ * Get a VehicleMessage from vehicle_message_q and return it
+ * then point to the next VehicleMessage in queue.
+ *
+ * Return the next queue element or NULL if queue is empty.
+ */
+openxc_VehicleMessage* can_bus_t::next_vehicle_message()
+{
+ if(! vehicle_message_q_.empty())
+ {
+ openxc_VehicleMessage v_msg = vehicle_message_q_.front();
+ vehicle_message_q_.pop();
+ return &v_msg;
+ }
+
+ return nullptr;
+}
+
+void can_bus_t::insert_new_vehicle_message(openxc_VehicleMessage *v_msg)
+{
+ vehicle_message_q_.push(v_msg);
+}
/********************************************************************************
*
* CanMessage method implementation
*
*********************************************************************************/
-uint32_t CanMessage_c::get_id()
+uint32_t can_message_t::get_id() const
{
return id;
}
-int CanMessage_c::get_format()
+int can_message_t::get_format() const
{
return format;
}
-uint8_t CanMessage_c::get_data()
+uint8_t can_message_t::get_data() const
{
return data;
}
-uint8_t CanMessage_c::get_lenght()
+uint8_t can_message_t::get_lenght() const
{
return lenght;
}
-void CanMessage_c::set_id(uint32_t new_id)
+void can_message_t::set_id(uint32_t new_id)
{
switch(format):
case CanMessageFormat::SIMPLE:
ERROR(interface, "ERROR: Can set id, not a compatible format or format not set prior to set id.");
}
-void CanMessage_c::set_format(CanMessageFormat new_format)
+void can_message_t::set_format(CanMessageFormat new_format)
{
if(new_format == CanMessageFormat::SIMPLE || new_format == CanMessageFormat::EXTENDED)
format = new_format;
ERROR(interface, "ERROR: Can set format, wrong format chosen");
}
-void CanMessage_c::set_data(uint8_t new_data)
+void can_message_t::set_data(uint8_t new_data)
{
data = new_data;
}
-void CanMessage_c::set_lenght(uint8_t new_length)
+void can_message_t::set_lenght(uint8_t new_length)
{
lenght = new_lenght;
}
*
* params: canfd_frame pointer
*/
-void CanMessage_c::convert_from_canfd_frame(canfd_frame *frame)
+void can_message_t::convert_from_canfd_frame(canfd_frame *frame)
{
lenght = (canfd_frame->len > maxdlen) ? maxdlen : canfd_frame->len;
memcpy(data, canfd_frame->data, lenght);
return 0;
} else if (sizeof(canfd_frame->data) >= CAN_MAX_DLEN)
- ERROR(interface, "CanMessage_c: canfd_frame data too long to be stored into CanMessage object");
+ ERROR(interface, "can_message_t: canfd_frame data too long to be stored into CanMessage object");
}
canfd_frame* convert_to_canfd_frame()