97 lines
2.5 KiB
C++
97 lines
2.5 KiB
C++
/*
|
|
|
|
Copyright (c) 2015, 2016 Hubert Denkmair
|
|
|
|
This file is part of cangaroo.
|
|
|
|
cangaroo is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
cangaroo is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
#include "SocketCanDriver.h"
|
|
#include "SocketCanInterface.h"
|
|
#include <core/Backend.h>
|
|
|
|
#include <sys/socket.h>
|
|
#include <linux/if.h>
|
|
#include <linux/if_arp.h>
|
|
#include <linux/can/netlink.h>
|
|
#include <netlink/route/link.h>
|
|
#include <netlink/route/link/can.h>
|
|
#include <errno.h>
|
|
#include <cstring>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
|
|
SocketCanDriver::SocketCanDriver(Backend &backend)
|
|
: CanDriver(backend)
|
|
{
|
|
}
|
|
|
|
SocketCanDriver::~SocketCanDriver() {
|
|
}
|
|
|
|
bool SocketCanDriver::update() {
|
|
|
|
deleteAllInterfaces();
|
|
|
|
struct nl_sock *sock = nl_socket_alloc();
|
|
struct nl_cache *cache;
|
|
|
|
nl_connect(sock, NETLINK_ROUTE);
|
|
int result = rtnl_link_alloc_cache(sock, AF_UNSPEC, &cache);
|
|
|
|
if (result < 0) {
|
|
log_error(QString("Could not access netlink device list: %1").arg(result));
|
|
} else {
|
|
|
|
for (struct nl_object *obj = nl_cache_get_first(cache); obj!=0; obj=nl_cache_get_next(obj)) {
|
|
struct rtnl_link *link = (struct rtnl_link *)obj;
|
|
|
|
if (rtnl_link_get_arptype(link)==ARPHRD_CAN) {
|
|
SocketCanInterface *intf = createOrUpdateInterface(rtnl_link_get_ifindex(link), QString(rtnl_link_get_name(link)));
|
|
intf->readConfigFromLink(link);
|
|
}
|
|
}
|
|
}
|
|
|
|
nl_cache_free(cache);
|
|
nl_close(sock);
|
|
nl_socket_free(sock);
|
|
|
|
return true;
|
|
}
|
|
|
|
QString SocketCanDriver::getName() {
|
|
return "SocketCAN";
|
|
}
|
|
|
|
SocketCanInterface *SocketCanDriver::createOrUpdateInterface(int index, QString name) {
|
|
|
|
foreach (CanInterface *intf, getInterfaces()) {
|
|
SocketCanInterface *scif = dynamic_cast<SocketCanInterface*>(intf);
|
|
if (scif->getIfIndex() == index) {
|
|
scif->setName(name);
|
|
return scif;
|
|
}
|
|
}
|
|
|
|
|
|
SocketCanInterface *scif = new SocketCanInterface(this, index, name);
|
|
addInterface(scif);
|
|
return scif;
|
|
}
|