#include "socketcan-raw.hpp"
+#include <net/if.h>
+#include <sys/ioctl.h>
+
namespace utils
{
- /// @brief Construct a default, invalid, socket.
- socketcan_raw_t::socketcan_raw_t()
- : socketcan_t{}, socket_{INVALID_SOCKET}
- {}
-
- /// @brief Construct a socket by moving an existing one.
- socketcan_raw_t::socketcan_raw_t(socketcan_raw_t&& s)
- : socket_{s.socket_}
+ /// @brief Bind the socket.
+ /// @return 0 if success.
+ int socketcan_raw_t::bind(const struct sockaddr* addr, socklen_t len)
{
- s.socket_ = INVALID_SOCKET;
- }
-
- /// @brief Destruct the socket.
- socketcan_raw_t::~socketcan_raw_t()
- {
- if(socket_ != INVALID_SOCKET)
- ::close(socket_);
+ return socket_ != INVALID_SOCKET ? ::bind(socket_, addr, len) : 0;
}
/// @brief Open a raw socket CAN.
close();
struct ifreq ifr;
- socket_ = open(PF_CAN, SOCK_RAW, CAN_RAW);
+ socket_ = socketcan_t::open(PF_CAN, SOCK_RAW, CAN_RAW);
// Attempts to open a socket to CAN bus
::strcpy(ifr.ifr_name, device_name.c_str());
}
return socket_;
}
+
+ socketcan_raw_t& operator>>(socketcan_raw_t& s, can_message_t& cm)
+ {
+ struct canfd_frame frame;
+
+ const struct sockaddr_can& addr = s.get_tx_address();
+ socklen_t addrlen = sizeof(addr);
+ struct ifreq ifr;
+
+ ssize_t nbytes = ::recvfrom(s.socket(), &frame, sizeof(frame), 0, (struct sockaddr*)&addr, &addrlen);
+ ifr.ifr_ifindex = addr.can_ifindex;
+ ioctl(s.socket(), SIOCGIFNAME, &ifr);
+
+ DEBUG(binder_interface, "Data available: %i bytes read", (int)nbytes);
+ DEBUG(binder_interface, "read: Found on bus %s:\n id: %X, length: %X, data %02X%02X%02X%02X%02X%02X%02X%02X", ifr.ifr_name, frame.can_id, frame.len,
+ frame.data[0], frame.data[1], frame.data[2], frame.data[3], frame.data[4], frame.data[5], frame.data[6], frame.data[7]);
+
+ struct timeval tv;
+ ioctl(s.socket(), SIOCGSTAMP, &tv);
+ uint64_t timestamp = 1000000 * tv.tv_sec + tv.tv_usec;
+ cm = ::can_message_t::convert_from_frame(frame , nbytes, timestamp);
+
+ return s;
+ }
}
\ No newline at end of file