mirror of
https://github.com/linux-can/can-utils.git
synced 2026-09-23 08:31:09 +02:00
Implement ISOBUS File Server (FS) Interface as a Personal Project
Introduce the ISOBUS File Server (FS) interface, compatible with ISO 11783-13. The implementation utilizes the kernel's existing CAN J1939 socket support. For testing following setup can be used: ip link add type vcan ip l s dev vcan0 up j1939acd -r 64-95 -c /tmp/1122334455667788.jacd 1122334455667788 vcan0 & j1939acd -r 96-127 -c /tmp/1122334455667789.jacd 1122334455667789 vcan0 & sleep 1 isobusfs-srv -i vcan0 -n 1122334455667788 -v vol1:/path/to/export/ isobusfs-cli -i vcan0 -n 0x1122334455667789 -m 0x1122334455667788 -I Interactive mode currently support following commands: exit - exit interactive mode quit - exit interactive mode help - show this help dmesg - show log buffer selftest - run selftest ls - list directory ll - list directory with long listing format cd - change directory pwd - print name of current/working directory get - get file Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
This commit is contained in:
committed by
Oleksij Rempel
parent
6004c64f06
commit
42edaeaf52
@@ -0,0 +1,126 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: 2023 Oleksij Rempel <linux@rempel-privat.de>
|
||||
/*
|
||||
* This file implements Annex C.1.2 File Server Status according to
|
||||
* ISO 11783-13:2021.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <poll.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "isobusfs_srv.h"
|
||||
|
||||
/*
|
||||
* isobusfs_srv_fss_init - Initialize the file server status structure
|
||||
* @priv: Pointer to the private data structure of the ISOBUS file server
|
||||
*
|
||||
* This function initializes the file server status structure, which
|
||||
* represents the status of the file server according to Annex C.1.2
|
||||
* of ISO 11783-13:2021.
|
||||
*/
|
||||
void isobusfs_srv_fss_init(struct isobusfs_srv_priv *priv)
|
||||
{
|
||||
struct isobusfs_cm_fss *st = &priv->st;
|
||||
|
||||
st->fs_function =
|
||||
isobusfs_cg_function_to_buf(ISOBUSFS_CG_CONNECTION_MANAGMENT,
|
||||
ISOBUSFS_CM_F_FS_STATUS);
|
||||
st->status = 0;
|
||||
st->num_open_files = 0;
|
||||
memset(st->reserved, 0xFF, sizeof(st->reserved));
|
||||
}
|
||||
|
||||
/*
|
||||
* isobusfs_srv_fss_get_rate - Get the rate of File Server Status transmission
|
||||
* @priv: Pointer to the private data structure of the ISOBUS file server
|
||||
*
|
||||
* Returns: the transmission rate of the File Server Status messages depending
|
||||
* on the current state of the file server.
|
||||
*/
|
||||
static unsigned int isobusfs_srv_fss_get_rate(struct isobusfs_srv_priv *priv)
|
||||
{
|
||||
switch (priv->st_state) {
|
||||
case ISOBUSFS_SRV_STATE_IDLE:
|
||||
return ISOBUSFS_CM_F_FS_STATUS_IDLE_RATE;
|
||||
/*
|
||||
* On every change of Byte 2 "File Server Status" send max 5 status
|
||||
* messages per second.
|
||||
*/
|
||||
case ISOBUSFS_SRV_STATE_STAT_CHANGE_1: /* fall through */
|
||||
case ISOBUSFS_SRV_STATE_STAT_CHANGE_2: /* fall through */
|
||||
case ISOBUSFS_SRV_STATE_STAT_CHANGE_3: /* fall through */
|
||||
case ISOBUSFS_SRV_STATE_STAT_CHANGE_4: /* fall through */
|
||||
case ISOBUSFS_SRV_STATE_STAT_CHANGE_5:
|
||||
priv->st_state--;
|
||||
return ISOBUSFS_CM_F_FS_STATUS_BUSY_RATE;
|
||||
case ISOBUSFS_SRV_STATE_BUSY:
|
||||
return ISOBUSFS_CM_F_FS_STATUS_BUSY_RATE;
|
||||
default:
|
||||
pr_warn("%s:%i: unknown state %d", __func__, __LINE__,
|
||||
priv->st_state);
|
||||
}
|
||||
|
||||
/*
|
||||
* In case something is wrong, fall back to idle rate to not spam the
|
||||
* bus.
|
||||
*/
|
||||
return ISOBUSFS_CM_F_FS_STATUS_IDLE_RATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* isobusfs_srv_fss_send - Send periodic File Server Status messages
|
||||
* @priv: Pointer to the private data structure of the ISOBUS file server
|
||||
*
|
||||
* Returns: 0 if the message was sent successfully, a negative error code
|
||||
* otherwise.
|
||||
*/
|
||||
int isobusfs_srv_fss_send(struct isobusfs_srv_priv *priv)
|
||||
{
|
||||
unsigned int next_msg_rate;
|
||||
int64_t time_diff;
|
||||
int ret;
|
||||
|
||||
/* Test if it is proper time to send next status message. */
|
||||
time_diff = timespec_diff_ms(&priv->cmn.next_send_time,
|
||||
&priv->cmn.last_time);
|
||||
if (time_diff > ISOBUSFS_CM_F_FS_STATUS_RATE_JITTER) {
|
||||
/* too early to send next message */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (time_diff < -ISOBUSFS_CM_F_FS_STATUS_RATE_JITTER) {
|
||||
pr_warn("too late to send next fs status message: %ld ms",
|
||||
time_diff);
|
||||
}
|
||||
|
||||
/* Make sure we send the message with the latest stats */
|
||||
if (priv->st_msg_stats.tskey_sch != priv->st_msg_stats.tskey_ack)
|
||||
pr_warn("previous message was not acked");
|
||||
|
||||
/* send periodic file servers status messages. */
|
||||
ret = send(priv->sock_fss, &priv->st, sizeof(priv->st), MSG_DONTWAIT);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
pr_warn("Failed to send FS status message, error code: %d (%s)",
|
||||
ret, strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_debug("> tx FS status: 0x%02x, opened files: %d",
|
||||
priv->st.status, priv->st.num_open_files);
|
||||
|
||||
/* Calculate time for the next status message */
|
||||
next_msg_rate = isobusfs_srv_fss_get_rate(priv);
|
||||
priv->cmn.next_send_time = priv->cmn.last_time;
|
||||
timespec_add_ms(&priv->cmn.next_send_time, next_msg_rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user