Compare commits

...

6 Commits

Author SHA1 Message Date
Paul Hollinsky b5d56bc740 v2.1.0
Update copyright date
Update to libicsneo v0.3.0
Report transmits down to the kernel for echo
Allow filtering devices by serial number
2022-03-31 18:18:33 -04:00
Paul Hollinsky 9ba6f2cec5 Update copyright date to 2022 2022-03-31 18:13:23 -04:00
Paul Hollinsky c7db3cbcf0 Refactor for libicsneo v0.3.0 API changes 2022-03-31 15:41:19 -04:00
Paul Hollinsky 616a8ddbce Report transmit receipts to kernel
These will be used for IFF_ECHO
2022-03-31 15:40:28 -04:00
Paul Hollinsky dcec89f2da Allow filtering devices by serial number 2022-03-31 13:51:03 -04:00
Paul Hollinsky 919bcccffc Fix arguments with the wrong ordering for ip link set 2021-04-28 10:27:31 -04:00
6 changed files with 48 additions and 23 deletions

View File

@ -1,3 +1,9 @@
v2.1.0
Update copyright date
Update to libicsneo v0.3.0
Report transmits down to the kernel for echo
Allow filtering devices by serial number
v2.0.3
Update copyright date
Update to libicsneo v0.2.0

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.2)
project(libicsneo-socketcan-daemon VERSION 2.0.3)
project(libicsneo-socketcan-daemon VERSION 2.1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
include(GNUInstallDirs)

View File

@ -1,4 +1,4 @@
Copyright (c) 2016-2021 Intrepid Control Systems, Inc.
Copyright (c) 2016-2022 Intrepid Control Systems, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -1,4 +1,4 @@
Version 2.0.3
Version 2.1.0
This is the usermode daemon for the Intrepid Control Systems SocketCAN support. This daemon requires that ```intrepid.ko``` is loaded on your system.
@ -24,6 +24,6 @@ On Ubuntu or other Debian-based systems, run `sudo apt install git cmake gcc lib
10. CAN interfaces will have been created, but are "down" or, in other words, not enabled for transmit and receive yet. You can see them with `ip link`. They will be labelled `can0`, `can1`, and etc. They will have an alias listed which corresponds to the serial number of the device and network on that device.
11. Enable the CAN interface with `sudo ip link set up can0`, replacing `can0` with whichever interface you'd like to enable
11. Enable the CAN interface with `sudo ip link set can0 up`, replacing `can0` with whichever interface you'd like to enable
12. You can now use any SocketCAN application with this interface. A good package for testing is the `can-utils` package. You can get this package with `sudo apt install can-utils`. A good testing tool which comes with this package is `candump`. Running `candump can0` will print a line for every incoming frame.

View File

@ -20,6 +20,8 @@
#include <icsneo/icsneocpp.h>
#include <icsneo/communication/message/neomessage.h>
#include <icsneo/communication/message/message.h>
#include <icsneo/communication/network.h>
#include <icsneo/communication/message/callback/canmessagecallback.h>
#include <generated/buildinfo.h>
@ -49,6 +51,7 @@ int driverPatch = 0;
int maxInterfaces = 0; // From driver
int sharedMemSize = 0; // From driver
void* sharedMemory = nullptr;
std::string serialFilter;
std::atomic<bool> stopRunning(false);
@ -85,8 +88,15 @@ public:
const std::string& getName() const { return name; }
uint8_t* getRxBox() { return rxBox; }
const uint8_t* getRxBox() const { return rxBox; }
void addReceivedMessageToQueue(const std::shared_ptr<icsneo::Message>& msg) {
auto neomessage = icsneo::CreateNeoMessage(msg);
void addReceivedMessageToQueue(const std::shared_ptr<icsneo::CANMessage>& msg) {
const auto neomessageGeneric = icsneo::CreateNeoMessage(msg);
if (neomessageGeneric.messageType != neomessagetype_t(icsneo::Message::Type::Frame)) {
LOG(LOG_DEBUG, "could not create a neomessage_can_t\n");
return;
}
const auto& neomessage = *reinterpret_cast<const neomessage_can_t*>(&neomessageGeneric);
size_t bytesNeeded = sizeof(neomessage) + neomessage.length;
std::lock_guard<std::mutex> lg(rxBoxLock);
if(ssize_t((rxBoxCurrentPosition - rxBox) + bytesNeeded) > RX_BOX_SIZE) {
@ -187,12 +197,13 @@ void header() {
void usage(std::string executableName) {
std::cerr << "The libicsneo SocketCAN Usermode Daemon\n";
std::cerr << "Copyright 2019-2020 Intrepid Control Systems, Inc.\n\n";
std::cerr << "Copyright 2019-2022 Intrepid Control Systems, Inc.\n\n";
std::cerr << "Usage: " << executableName << " [option]\n\n";
std::cerr << "Options:\n";
std::cerr << "\t-d, --daemon\t\tRun as a daemon in the background\n";
std::cerr << "\t-h, -?, --help, --usage\t\tShow this help page\n";
std::cerr << "\t --devices\t\tList supported devices\n";
std::cerr << "\t --filter <serial>\tOnly connect to devices with serial\n\t\t\t\t\tnumbers starting with this filter\n";
}
void terminateSignal(int signal) {
@ -215,9 +226,14 @@ void searchForDevices() {
if(alreadyOpen)
continue;
const std::string serial = dev->getSerial();
// If we have a serial filter, make sure our serial starts with the given filter
if(!serialFilter.empty() && serial.rfind(serialFilter, 0) != 0)
continue;
// Now open the device
OpenDevice newDevice(dev);
const std::string serial = newDevice.device->getSerial();
Lazy<bool> firstTimeFailedToOpen([&serial]() {
return std::find(failedToOpen.begin(), failedToOpen.end(), serial) == failedToOpen.end();
});
@ -270,8 +286,6 @@ void searchForDevices() {
// Create rx listener
newDevice.device->addMessageCallback(icsneo::CANMessageCallback([serial](std::shared_ptr<icsneo::Message> message) {
if(message->transmitted)
return;
auto canMessage = std::static_pointer_cast<icsneo::CANMessage>(message);
const OpenDevice* openDevice = nullptr;
std::lock_guard<std::mutex> lg(openDevicesMutex);
@ -344,13 +358,8 @@ void deviceSearchThread() {
}
int main(int argc, char** argv) {
if(argc > 2) {
usage(argv[0]);
return EX_USAGE;
}
if(argc == 2) {
const std::string arg = argv[1];
for(int i = 1; i != argc; i++) {
const std::string arg = argv[i];
if(arg == "-d" || arg == "--daemon") {
runningAsDaemon = true;
} else if(arg == "-h" || arg == "--help" || arg == "-?" || arg == "--usage") {
@ -362,6 +371,9 @@ int main(int argc, char** argv) {
for(auto& dev : icsneo::GetSupportedDevices())
std::cout << '\t' << dev << std::endl;
return EXIT_SUCCESS;
} else if(arg == "--filter" && i + 1 <= argc) {
serialFilter = argv[++i];
transform(serialFilter.begin(), serialFilter.end(), serialFilter.begin(), ::toupper);
} else {
usage(argv[0]);
return EX_USAGE;
@ -477,10 +489,16 @@ int main(int argc, char** argv) {
// Send!
uint8_t* currentPosition = GET_TX_BOX(info.tx_box_index);
while(info.count--) {
neomessage_t* msg = reinterpret_cast<neomessage_t*>(currentPosition);
currentPosition += sizeof(neomessage_t);
neomessage_frame_t* msg = reinterpret_cast<neomessage_frame_t*>(currentPosition);
currentPosition += sizeof(neomessage_frame_t);
msg->data = currentPosition;
currentPosition += msg->length;
if(msg->type != neonettype_t(icsneo::Network::Type::CAN)) {
LOG(LOG_ERR, "Message dropped, kernel sent a non-CAN message\n");
continue;
}
bool sent = false;
std::lock_guard<std::mutex> lg(openDevicesMutex);
for(auto& dev : openDevices) {
@ -488,8 +506,9 @@ int main(int argc, char** argv) {
if(netifPair.second->getKernelHandle() != msg->netid)
continue;
msg->netid = static_cast<uint16_t>(netifPair.first);
auto tx = icsneo::CreateMessageFromNeoMessage(msg);
if(!dev.device->transmit(tx))
auto txMsg = icsneo::CreateMessageFromNeoMessage(reinterpret_cast<neomessage_t*>(msg));
auto tx = std::dynamic_pointer_cast<icsneo::Frame>(txMsg);
if(!tx || !dev.device->transmit(tx))
break;
sent = true;
break;

@ -1 +1 @@
Subproject commit b09f85693fef5e5513f099648cdf165ade5d20f2
Subproject commit 0ff12300f34be54ec7d3380a4ab6693a7d7c3fb1