simple-socket library 1.2.0
CANRawSocket.cpp
Go to the documentation of this file.
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
14
15void CANRawSocket::sendTo( const void* buffer, size_t len, std::string_view interface)
16{
17 sockaddr_can destAddr;
18 destAddr.can_family = AF_CAN;
19 destAddr.can_ifindex = getInterfaceIndex(interface);
20
21 int sent = TEMP_FAILURE_RETRY (::sendto( m_socket, (const raw_type*)buffer, len, 0, (sockaddr*)&destAddr, sizeof(destAddr)));
22
23 // Write out the whole buffer as a single message
24 if( sent != (int)len)
25 throw SocketException("Send failed (sendto)");
26}
27
28int CANRawSocket::receiveFrom( void* buffer, size_t len, std::string& interface)
29{
30 sockaddr_can clientAddr;
31 socklen_t addrLen = sizeof(clientAddr);
32
33 int ret = TEMP_FAILURE_RETRY (::recvfrom( m_socket, (raw_type*)buffer, len, 0, (sockaddr*)&clientAddr, &addrLen));
34 if( ret < 0)
35 throw SocketException("Receive failed (recvfrom)");
36
37 interface = getInterfaceName(clientAddr);
38 return ret;
39}
40
41int CANRawSocket::timedReceiveFrom( void* buffer, size_t len, std::string& interface, int timeout)
42{
43 struct pollfd poll;
44 poll.fd = m_socket;
45 poll.events = POLLIN | POLLPRI | POLLRDHUP;
46
47 int ret = TEMP_FAILURE_RETRY (::poll( &poll, 1, timeout));
48
49 if( ret == 0) return 0;
50 if( ret < 0) throw SocketException("Receive failed (poll)");
51
52 if( poll.revents & POLLRDHUP)
53 m_peerDisconnected = true;
54
55 if( poll.revents & POLLIN || poll.revents & POLLPRI)
56 return receiveFrom( buffer, len, interface);
57
58 return 0;
59}
60
61void CANRawSocket::setReceiveFilter( const can_filter* filter, size_t len)
62{
63 if( setsockopt( m_socket,
64 SOL_CAN_RAW,
65 CAN_RAW_FILTER,
66 (const raw_type*)filter,
67 sizeof(filter) * len) < 0)
68 throw SocketException("Set receive filter failed (setsockopt)");
69}
70
71void CANRawSocket::setErrorFilter( const can_filter* filter, size_t len)
72{
73 if( setsockopt( m_socket,
74 SOL_CAN_RAW,
75 CAN_RAW_ERR_FILTER,
76 (const raw_type*)filter,
77 sizeof(filter) * len) < 0)
78 throw SocketException("Set receive filter failed (setsockopt)");
79}
80
82{
83 int loopback = enable;
84 if( setsockopt( m_socket,
85 SOL_CAN_RAW,
86 CAN_RAW_LOOPBACK,
87 (raw_type*)&loopback,
88 sizeof(loopback)) < 0)
89 throw SocketException("Set local loopback failed (setsockopt)");
90}
91
93{
94 int recv_own_msgs = enable;
95 if( setsockopt( m_socket,
96 SOL_CAN_RAW,
97 CAN_RAW_RECV_OWN_MSGS,
98 (raw_type*)&recv_own_msgs,
99 sizeof(recv_own_msgs)) < 0)
100 throw SocketException("Set receive own messages failed (setsockopt)");
101}
static const int len
#define TEMP_FAILURE_RETRY(expression)
Definition TempFailure.h:8
Definition CANFrame.h:7
Structure of id and mask used by filters.
Definition CANFrame.h:40
void setErrorFilter(const can_filter *filters, size_t len)
void setLocalLoopback(bool enable)
int timedReceiveFrom(void *buffer, size_t len, std::string &interface, int timeout)
int receiveFrom(void *buffer, size_t len, std::string &interface)
void setReceiveFilter(const can_filter *filters, size_t len)
void sendTo(const void *buffer, size_t len, std::string_view interface)
void setReceiveOwnMessages(bool enable)
int getInterfaceIndex(std::string_view interface) const
get CAN interface index from interface name
Definition CANSocket.cpp:69
CANSocket(int type, int protocol)
allows a subclass to create new socket
Definition CANSocket.cpp:12
Signals a problem with the execution of a socket call.