simple-socket library 1.5.0
Loading...
Searching...
No Matches
CANRawSocket.cpp
1#include "CANRawSocket.h"
2#include "TempFailure.h"
3
4#include <sys/socket.h>
5#include <linux/can.h>
6#include <linux/can/raw.h>
7#include <poll.h>
8
9using namespace NET;
10
12: CANSocket( SOCK_RAW, CAN_RAW)
13{}
14
15void CANRawSocket::send( const ::can_frame& frame)
16{
17 SimpleSocket::send( &frame, sizeof(frame));
18}
19
20int CANRawSocket::receive( ::can_frame& frame)
21{
22 return SimpleSocket::receive( &frame, sizeof(frame));
23}
24
25int CANRawSocket::timedReceive( ::can_frame& frame, int timeout)
26{
27 return SimpleSocket::timedReceive( &frame, sizeof(frame), timeout);
28}
29
30void CANRawSocket::sendTo( const ::can_frame& frame, std::string_view interface)
31{
32 sockaddr_can destAddr;
33 destAddr.can_family = AF_CAN;
34 destAddr.can_ifindex = getInterfaceIndex(interface);
35
36 int sent = TEMP_FAILURE_RETRY (::sendto( m_socket, (const raw_type*)&frame, sizeof(frame), 0, (sockaddr*)&destAddr, sizeof(destAddr)));
37
38 // Write out the whole buffer as a single message
39 if( sent != sizeof(frame))
40 throw SocketException("Send failed (sendto)");
41}
42
43int CANRawSocket::receiveFrom( ::can_frame& frame, std::string& interface)
44{
45 sockaddr_can clientAddr;
46 socklen_t addrLen = sizeof(clientAddr);
47
48 int ret = TEMP_FAILURE_RETRY (::recvfrom( m_socket, (raw_type*)&frame, sizeof(frame), 0, (sockaddr*)&clientAddr, &addrLen));
49 if( ret < 0)
50 throw SocketException("Receive failed (recvfrom)");
51
52 interface = getInterfaceName(clientAddr);
53 return ret;
54}
55
56int CANRawSocket::timedReceiveFrom( ::can_frame& frame, std::string& interface, int timeout)
57{
58 struct pollfd poll;
59 poll.fd = m_socket;
60 poll.events = POLLIN | POLLPRI | POLLRDHUP;
61
62 int ret = TEMP_FAILURE_RETRY (::poll( &poll, 1, timeout));
63
64 if( ret == 0) return 0;
65 if( ret < 0) throw SocketException("timedReceive failed (poll)");
66
67 if( poll.revents & POLLRDHUP || poll.revents & POLLHUP)
68 m_peerDisconnected = true;
69
70 if( poll.revents & POLLIN || poll.revents & POLLPRI)
71 return receiveFrom( frame, interface);
72
73 if( poll.revents & (POLLERR | POLLNVAL))
74 throw SocketException("timedReceive failed (poll)");
75
76 return 0;
77}
78
79void CANRawSocket::setReceiveFilter( const ::can_filter* filter, size_t len)
80{
81 if( ::setsockopt( m_socket, SOL_CAN_RAW, CAN_RAW_FILTER, filter, sizeof(::can_filter) * len) < 0)
82 throw SocketException("Set receive filter failed (setsockopt)");
83}
84
85void CANRawSocket::setErrorFilter( ::can_err_mask_t filter)
86{
87 if( ::setsockopt( m_socket, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &filter, sizeof(::can_err_mask_t)) < 0)
88 throw SocketException("Set error filter failed (setsockopt)");
89}
90
92{
93 const int value = enable;
94 if( ::setsockopt( m_socket, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &value, sizeof(value)) < 0)
95 throw SocketException("Set local loopback failed (setsockopt)");
96}
97
99{
100 const int value = enable;
101 if( ::setsockopt( m_socket, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &value, sizeof(value)) < 0)
102 throw SocketException("Set receive own messages failed (setsockopt)");
103}
void sendTo(const ::can_frame &frame, std::string_view interface)
int receiveFrom(::can_frame &frame, std::string &interface)
void setReceiveFilter(const ::can_filter *filters, size_t len)
void setLocalLoopback(bool enable)
int receive(::can_frame &frame)
(overload) receive can frame from a bound socket
int timedReceiveFrom(::can_frame &frame, std::string &interface, int timeout)
void send(const ::can_frame &frame)
(overload) send can_frame through a connected socket
int timedReceive(::can_frame &frame, int timeout)
(overload) receive can frame from a bound socket with timeout
void setErrorFilter(::can_err_mask_t filter)
void setReceiveOwnMessages(bool enable)
int getInterfaceIndex(std::string_view interface) const
get CAN interface index from interface name
Definition CANSocket.cpp:71
CANSocket(int type, int protocol)
allows a subclass to create new socket
Definition CANSocket.cpp:14
int timedReceive(void *buffer, size_t len, int timeout)
receive data from a bound socket, return after the given timespan
int send(const void *buffer, size_t len)
send data through a connected socket
int receive(void *buffer, size_t len)
receive data from a bound socket
Signals a problem with the execution of a socket call.