10 Commits
Author SHA1 Message Date
Kyle SchwarzandJonathan Schwartz 4a38ebda34 Rework reconnection logic 2026-08-07 17:06:52 +00:00
Kyle Schwarz 4801a60598 Update libicsneo 2026-06-02 18:53:31 -04:00
Thomas StoddardandKyle Schwarz bd37f9f8a1 Bump libicsneo submodule for Servd default on 2026-05-08 15:04:44 -04:00
Kyle Schwarz 5612f583b8 Fix get_serials name 2026-04-07 15:42:27 -04:00
Kyle Schwarz a15b71d970 Add RPC 2026-04-03 13:57:09 -04:00
Kyle Schwarz 9f2896cfc0 Update libicsneo 2026-03-24 10:24:36 -04:00
Kyle Schwarz 2838f4488c Update libicsneo 2025-10-15 12:00:31 -04:00
Kyle Schwarz 8c7f306771 Update libicsneo 2025-06-19 19:21:59 -04:00
Kyle Schwarz 945a027b5b Update libicsneo 2025-05-07 10:02:46 -04:00
Kyle Schwarz 1acc51af7d Update copyright year to 2025 2025-05-07 10:02:27 -04:00
8 changed files with 518 additions and 568 deletions
+1
View File
@@ -1,3 +1,4 @@
[submodule "third-party/libicsneo"] [submodule "third-party/libicsneo"]
path = third-party/libicsneo path = third-party/libicsneo
url = https://github.com/intrepidcs/libicsneo.git url = https://github.com/intrepidcs/libicsneo.git
branch = master
+2 -2
View File
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.2) cmake_minimum_required(VERSION 3.2)
project(libicsneo-socketcan-daemon VERSION 3.3.0) project(libicsneo-socketcan-daemon VERSION 3.2.0)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
@@ -27,5 +27,5 @@ include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
add_subdirectory("third-party/libicsneo") add_subdirectory("third-party/libicsneo")
add_executable(libicsneo-socketcan-daemon src/main.cpp src/netlink.c) add_executable(libicsneo-socketcan-daemon src/main.cpp)
target_link_libraries(libicsneo-socketcan-daemon icsneocpp) target_link_libraries(libicsneo-socketcan-daemon icsneocpp)
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2016-2024 Intrepid Control Systems, Inc. Copyright (c) 2016-2025 Intrepid Control Systems, Inc.
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
+95
View File
@@ -0,0 +1,95 @@
# RPC
icsscand contains an RPC endpoint that can be used to control the libicsneo
instance within the daemon. To enable the RPC channel, add `--fifo-path <path>`
during launching. The provided path will be used to open a named FIFO, the path
should not exist prior to launching icsscand.
## lock_networks
Invokes `icsneo::Device::lockNetworks()` with the provided space separated
arguments and writes the results of the call to the provided client FIFO. This
call in non-blocking, with the return type indicating that the request was sent
to the device (it does not indicate that the network was successfully locked).
Use `get_network_mutex_status` to check the status of the lock request.
### Usage
- Request: `<api version> lock_networks <device serial> <netid integers, comma separated> <priority> <ttl, ms> <lock type> <client fifo path>`
- Response: `<0 or 1, with 0 indicating an error and 1 indicating success>`
- On error, check the icsscand logs for more detailed information
### Example
- API version: 1
- Service serial: ON0123
- Networks: `ETHERNET_01` & `ETHERNET_02`
- See `icsneo::Network::NetID` for values
- Priority: 2
- TTL (in ms): 1s
- Opened client FIFO path: `/tmp/tmp.AYkIg0b3np`
- This FIFO must be opened prior to invoking the RPC
`1 lock_networks ON0123 93,520 2 1000 /tmp/tmp.AYkIg0b3np`
## unlock_networks
Invokes `icsneo::Device::unlockNetworks()` with the provided space separated
arguments and writes the results of the call to the provided client FIFO.
### Usage
- Request: `<api version> unlock_networks <device serial> <netid integers, comma separated> <client fifo path>`
- Response: `<0 or 1, with 0 indicating an error and 1 indicating success>`
- On error, check the icsscand logs for more detailed information
### Example
- API version: 1
- Service serial: ON0123
- Networks: `ETHERNET_01` & `ETHERNET_02`
- See `icsneo::Network::NetID` for values
- Opened client FIFO path: `/tmp/tmp.KXY8SCXtux`
- This FIFO must be opened prior to invoking the RPC
`1 lock_networks ON0123 93,520 /tmp/tmp.KXY8SCXtux`
## get_network_mutex_status
Invokes `icsneo::Device::getNetworkMutexStatus()` with the provided space separated
arguments and writes the results of the call to the provided client FIFO.
### Usage
- Request: `<api version> get_network_mutex_status <device serial> <netid integer> <client fifo path>`
- Response (one of):
- `0`, error, check the icsscand logs for more detailed information
- `1 <owner client id> <type> <priority> <ttl, ms> <netid integers, comma separated> <event>`
### Example
- API version: 1
- Service serial: ON0123
- Network: `ETHERNET_01`
- See `icsneo::Network::NetID` for values
- Opened client FIFO path: `/tmp/tmp.4huaosZjhA`
- This FIFO must be opened prior to invoking the RPC
`1 get_network_mutex_status ON0123 93 /tmp/tmp.4huaosZjhA`
## get_serials
Returns a space separated list of devices serial numbers that isscand has open.
### Usage
- Request: `<api version> get_serials <client fifo path>`
- Response: `<0 or 1, with 0 indicating an error and 1 indicating success> [serial]...`
### Example
- API version: 1
- Opened client FIFO path: `/tmp/tmp.bBcUh5obRK`
- This FIFO must be opened prior to invoking the RPC
`1 get_serials /tmp/tmp.bBcUh5obRK`
+418 -452
View File
File diff suppressed because it is too large Load Diff
-99
View File
@@ -1,99 +0,0 @@
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <linux/if_link.h>
#include <linux/if_arp.h>
#include <linux/netlink.h>
#include <linux/can/netlink.h>
#include <linux/rtnetlink.h>
#include "netlink.h"
bool read_netlink_msgs(int s, msg_callback callback)
{
struct nlmsghdr buf[8192/sizeof(struct nlmsghdr)];
struct nlmsghdr *nh;
int len = recv(s, buf, sizeof(buf), 0);
for (nh = (struct nlmsghdr *) buf; NLMSG_OK (nh, len);
nh = NLMSG_NEXT (nh, len)) {
/* The end of multipart message */
if (nh->nlmsg_type == NLMSG_DONE) {
printf("Done\n");
return true;
}
if (nh->nlmsg_type == NLMSG_ERROR) {
printf("Error\n");
} else if (nh->nlmsg_type == RTM_NEWLINK) {
struct ifinfomsg *iface = NLMSG_DATA(nh);
int attrlen = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*iface));
if (iface->ifi_type == ARPHRD_CAN) {
for (struct rtattr *rta = IFLA_RTA(iface); RTA_OK(rta, attrlen); rta = RTA_NEXT(rta, attrlen)) {
switch(rta->rta_type) {
case IFLA_LINKINFO:
{
int attr2len = RTA_PAYLOAD(rta);
char *kind = NULL;
void *data = NULL;
int data_len;
for (struct rtattr *rta2 = RTA_DATA(rta); RTA_OK(rta2, attr2len);
rta2 = RTA_NEXT(rta2, attr2len)) {
switch (rta2->rta_type) {
case IFLA_INFO_KIND:
kind = RTA_DATA(rta2);
break;
case IFLA_INFO_DATA:
data = RTA_DATA(rta2);
data_len = RTA_PAYLOAD(rta2);
break;
}
}
if (kind && strcmp(kind, "can") == 0 && data) {
attr2len = data_len;
for (struct rtattr *rta2 = data; RTA_OK(rta2, attr2len);
rta2 = RTA_NEXT(rta2, attr2len)) {
if (callback) {
callback(iface->ifi_index, rta2->rta_type, RTA_DATA(rta2));
}
}
}
}
break;
}
}
}
}
}
}
int open_netlink_socket()
{
int s = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
if (s < 0) {
return -1;
}
struct sockaddr_nl addr = {
.nl_family = AF_NETLINK,
.nl_groups = RTMGRP_LINK,
};
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
return -1;
}
int group = RTMGRP_LINK;
if (setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof(group))) {
return -1;
}
return s;
}
-13
View File
@@ -1,13 +0,0 @@
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*msg_callback)(int /* ifindex */, int /* rta_type */, void * /* data */);
bool read_netlink_msgs(int s, msg_callback callback);
int open_netlink_socket();
#ifdef __cplusplus
}
#endif