can-utils/isobusfs/isobusfs_srv.h

174 lines
5.7 KiB
C

// SPDX-License-Identifier: LGPL-2.0-only
// SPDX-FileCopyrightText: 2023 Oleksij Rempel <linux@rempel-privat.de>
#ifndef ISOBUSFS_SRV_H
#define ISOBUSFS_SRV_H
#include <stdbool.h>
#include <stdint.h>
#include <sys/epoll.h>
#include <dirent.h>
#include "isobusfs_cmn.h"
#include "isobusfs_cmn_cm.h"
#define ISOBUSFS_SRV_VERSION 4
#define ISOBUSFS_SRV_MAX_CTRL_SOCKETS 1
#define ISOBUSFS_SRV_MAX_CLIENT_SOCKETS 255
#define ISOBUSFS_SRV_MAX_EPOLL_EVENTS (ISOBUSFS_SRV_MAX_CTRL_SOCKETS + \
ISOBUSFS_SRV_MAX_CLIENT_SOCKETS)
#define ISOBUSFS_SRV_MAX_OPENED_HANDLES 255
/*
* ISO 11783-13:2021 standard does not explicitly specify a maximum number of
* clients that can be supported on the network. However, the ISO 11783 standard
* is built on top of the SAE J1939 protocol, which has a maximum of 238
* available addresses for nodes. This number is calculated from the available
* address range for assignment to nodes on the network, which includes 127
* addresses in the range 1-127 and 111 addresses in the range 248-254,
* inclusive. Some addresses in the total range (0-255) are reserved for
* specific purposes, such as broadcast messages and null addresses.
*
* The maximum number of 238 nodes includes both clients and servers, so the
* actual number of clients that can be supported will be less than 238.
*
* It is important to note that the practical limit of clients in an ISO
* 11783-13 network could be lower due to factors such as network bandwidth,
* performance constraints of the individual devices, and the complexity of the
* network.
*/
#define ISOBUSFS_SRV_MAX_CLIENTS 237
enum isobusfs_srv_fss_state {
ISOBUSFS_SRV_STATE_IDLE = 0, /* send status with 2000ms interval */
ISOBUSFS_SRV_STATE_STAT_CHANGE_1, /* send status with 200ms interval */
ISOBUSFS_SRV_STATE_STAT_CHANGE_2, /* send status with 200ms interval */
ISOBUSFS_SRV_STATE_STAT_CHANGE_3, /* send status with 200ms interval */
ISOBUSFS_SRV_STATE_STAT_CHANGE_4, /* send status with 200ms interval */
ISOBUSFS_SRV_STATE_STAT_CHANGE_5, /* send status with 200ms interval */
ISOBUSFS_SRV_STATE_BUSY, /* send status with 200ms interval */
};
struct isobusfs_srv_client {
int sock;
struct timespec last_received;
uint8_t addr;
uint8_t tan;
uint8_t version;
char current_dir[ISOBUSFS_SRV_MAX_PATH_LEN];
};
struct isobusfs_srv_volume {
char *name;
char *path;
bool removable;
bool writeable;
int refcount;
struct isobusfs_srv_client *clients[ISOBUSFS_SRV_MAX_CLIENTS];
};
struct isobusfs_srv_handles {
char *path;
int refcount;
int fd;
off_t offset;
int32_t dir_pos;
DIR *dir;
struct isobusfs_srv_client *clients[ISOBUSFS_SRV_MAX_CLIENTS];
};
struct isobusfs_srv_priv {
/* incoming traffic from peers */
int sock_in;
/*
* egress only File Server Status broadcast packets with different
* prio
*/
int sock_fss;
/*
* bidirectional socket for NACK packets.
* ISO 11783-3:2018 5.4.5 Acknowledgement
*/
int sock_nack;
struct sockaddr_can addr;
int server_version;
/* fs status related variables */
struct isobusfs_cm_fss st; /* file server status message */
enum isobusfs_srv_fss_state st_state;
struct isobusfs_stats st_msg_stats;
/* client related variables */
struct isobusfs_srv_client clients[ISOBUSFS_SRV_MAX_CLIENTS];
int clients_count;
struct isobusfs_buf_log tx_buf_log;
struct libj1939_cmn cmn;
struct isobusfs_srv_volume volumes[ISOBUSFS_SRV_MAX_VOLUMES];
int volume_count;
int removable_volumes_count;
const char *default_volume;
/* manufacturer-specific directory */
char mfs_dir[9];
uint64_t local_name;
struct isobusfs_srv_handles handles[ISOBUSFS_SRV_MAX_OPENED_HANDLES];
int handles_count;
};
/* isobusfs_srv.c */
int isobusfs_srv_send_error(struct isobusfs_srv_priv *priv,
struct isobusfs_msg *msg, enum isobusfs_error err);
int isobusfs_srv_sendto(struct isobusfs_srv_priv *priv,
struct isobusfs_msg *msg, const void *buf,
size_t buf_size);
/* isobusfs_srv_cm_fss.c */
void isobusfs_srv_fss_init(struct isobusfs_srv_priv *priv);
int isobusfs_srv_fss_send(struct isobusfs_srv_priv *priv);
/* isobusfs_srv_cm.c */
int isobusfs_srv_rx_cg_cm(struct isobusfs_srv_priv *priv,
struct isobusfs_msg *msg);
void isobusfs_srv_remove_timeouted_clients(struct isobusfs_srv_priv *priv);
void isobusfs_srv_init_clients(struct isobusfs_srv_priv *priv);
struct isobusfs_srv_client *isobusfs_srv_get_client(
struct isobusfs_srv_priv *priv, uint8_t addr);
struct isobusfs_srv_client *isobusfs_srv_get_client_by_msg(
struct isobusfs_srv_priv *priv, struct isobusfs_msg *msg);
/* isobusfs_srv_dh.c */
int isobusfs_srv_rx_cg_dh(struct isobusfs_srv_priv *priv,
struct isobusfs_msg *msg);
int isobusfs_path_to_linux_path(struct isobusfs_srv_priv *priv,
const char *isobusfs_path, size_t isobusfs_path_size,
char *linux_path, size_t linux_path_size);
int isobusfs_check_current_dir_access(struct isobusfs_srv_priv *priv,
const char *path, size_t path_size);
int isobusfs_convert_relative_to_absolute(struct isobusfs_srv_priv *priv,
const char *current_dir,
const char *rel_path,
size_t rel_path_size, char *abs_path,
size_t abs_path_size);
void isobusfs_srv_set_default_current_dir(struct isobusfs_srv_priv *priv,
struct isobusfs_srv_client *client);
/* isobusfs_srv_vh.c */
int isobusfs_srv_rx_cg_vh(struct isobusfs_srv_priv *priv,
struct isobusfs_msg *msg);
/* isobusfs_srv_fh.c */
int isobusfs_srv_rx_cg_fh(struct isobusfs_srv_priv *priv,
struct isobusfs_msg *msg);
/* isobusfs_srv_fa.c */
int isobusfs_srv_rx_cg_fa(struct isobusfs_srv_priv *priv,
struct isobusfs_msg *msg);
void isobusfs_srv_remove_client_from_handles(struct isobusfs_srv_priv *priv,
struct isobusfs_srv_client *client);
#endif /* ISOBUSFS_SRV_H */