// SPDX-License-Identifier: LGPL-2.0-only // SPDX-FileCopyrightText: 2023 Oleksij Rempel #ifndef ISOBUSFS_SRV_H #define ISOBUSFS_SRV_H #include #include #include #include #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 */