216 lines
6.2 KiB
C
216 lines
6.2 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
|
|
#ifndef ISOBUSFS_CLI_H
|
|
#define ISOBUSFS_CLI_H
|
|
|
|
#include <sys/epoll.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "isobusfs_cmn.h"
|
|
#include "isobusfs_cmn_cm.h"
|
|
|
|
#define ISOBUSFS_CLI_MAX_EPOLL_EVENTS 10
|
|
#define ISOBUSFS_CLI_DEFAULT_WAIT_TIMEOUT_MS 1000 /* ms */
|
|
|
|
enum isobusfs_cli_state {
|
|
ISOBUSFS_CLI_STATE_CONNECTING,
|
|
ISOBUSFS_CLI_STATE_IDLE,
|
|
ISOBUSFS_CLI_STATE_NACKED, /* here is NACKed and not what you think */
|
|
ISOBUSFS_CLI_STATE_SELFTEST,
|
|
ISOBUSFS_CLI_STATE_WAIT_FS_PROPERTIES,
|
|
ISOBUSFS_CLI_STATE_WAIT_CURRENT_DIR,
|
|
ISOBUSFS_CLI_STATE_WAIT_CCD_RESP,
|
|
ISOBUSFS_CLI_STATE_WAIT_OF_RESP,
|
|
ISOBUSFS_CLI_STATE_WAIT_FILE_SIZE,
|
|
ISOBUSFS_CLI_STATE_WAIT_FILE,
|
|
ISOBUSFS_CLI_STATE_WAIT_VOLUME_STATUS,
|
|
ISOBUSFS_CLI_STATE_WAIT_CF_RESP,
|
|
ISOBUSFS_CLI_STATE_WAIT_SF_RESP, /* wait for seek file response */
|
|
ISOBUSFS_CLI_STATE_WAIT_RF_RESP, /* wait for read file response */
|
|
ISOBUSFS_CLI_STATE_MAX_WAITING,
|
|
|
|
ISOBUSFS_CLI_STATE_CONNECTING_DONE,
|
|
ISOBUSFS_CLI_STATE_GET_FS_PROPERTIES_DONE,
|
|
ISOBUSFS_CLI_STATE_GET_CURRENT_DIR_DONE,
|
|
ISOBUSFS_CLI_STATE_GET_CURRENT_DIR_FAIL,
|
|
ISOBUSFS_CLI_STATE_GET_FILE_SIZE_DONE,
|
|
ISOBUSFS_CLI_STATE_GET_FILE_DONE,
|
|
ISOBUSFS_CLI_STATE_VOLUME_STATUS_DONE,
|
|
ISOBUSFS_CLI_STATE_CCD_DONE,
|
|
ISOBUSFS_CLI_STATE_CCD_FAIL,
|
|
ISOBUSFS_CLI_STATE_OF_DONE,
|
|
ISOBUSFS_CLI_STATE_OF_FAIL,
|
|
ISOBUSFS_CLI_STATE_CF_DONE,
|
|
ISOBUSFS_CLI_STATE_CF_FAIL,
|
|
ISOBUSFS_CLI_STATE_SF_DONE,
|
|
ISOBUSFS_CLI_STATE_SF_FAIL,
|
|
ISOBUSFS_CLI_STATE_RF_CONT,
|
|
ISOBUSFS_CLI_STATE_RF_DONE,
|
|
ISOBUSFS_CLI_STATE_RF_FAIL,
|
|
ISOBUSFS_CLI_STATE_MAX_DONE,
|
|
|
|
ISOBUSFS_CLI_STATE_GET_FS_PROPERTIES,
|
|
ISOBUSFS_CLI_STATE_GET_CURRENT_DIR,
|
|
ISOBUSFS_CLI_STATE_GET_FILE_SIZE,
|
|
ISOBUSFS_CLI_STATE_GET_FILE,
|
|
ISOBUSFS_CLI_STATE_VOLUME_STATUS,
|
|
ISOBUSFS_CLI_STATE_TEST_CLEANUP,
|
|
ISOBUSFS_CLI_STATE_TEST_DONE,
|
|
ISOBUSFS_CLI_STATE_MAX_ACTIVE,
|
|
};
|
|
|
|
struct isobusfs_priv;
|
|
|
|
typedef int (*isobusfs_event_callback)(struct isobusfs_priv *priv,
|
|
struct isobusfs_msg *msg, void *ctx,
|
|
int error);
|
|
|
|
struct isobusfs_event {
|
|
isobusfs_event_callback cb;
|
|
struct timespec timeout;
|
|
/* fs_function is needed to identify package type for event
|
|
* subscription
|
|
*/
|
|
uint8_t fs_function;
|
|
int fd;
|
|
bool one_shot;
|
|
void *ctx;
|
|
};
|
|
|
|
struct isobusfs_priv {
|
|
int sock_ccm;
|
|
int sock_nack;
|
|
int sock_main;
|
|
int sock_bcast_rx;
|
|
struct isobusfs_cm_ccm ccm; /* file server status message */
|
|
|
|
bool run_selftest;
|
|
|
|
struct sockaddr_can sockname;
|
|
struct sockaddr_can peername;
|
|
|
|
struct isobusfs_stats stats;
|
|
|
|
uint8_t next_tan;
|
|
uint8_t cl_buf[1];
|
|
|
|
bool fs_is_active;
|
|
struct timespec fs_last_seen;
|
|
uint8_t fs_version;
|
|
uint8_t fs_max_open_files;
|
|
uint8_t fs_caps;
|
|
struct isobusfs_buf_log tx_buf_log;
|
|
enum isobusfs_cli_state state;
|
|
|
|
struct isobusfs_cmn cmn;
|
|
uint8_t handle;
|
|
|
|
uint32_t read_offset;
|
|
uint8_t *read_data;
|
|
size_t read_data_len;
|
|
|
|
bool interactive;
|
|
bool int_busy;
|
|
|
|
struct isobusfs_event *events;
|
|
uint num_events;
|
|
uint max_events;
|
|
|
|
enum isobusfs_error error_code;
|
|
};
|
|
|
|
/* isobusfs_cli_cm.c */
|
|
void isobusfs_cli_ccm_init(struct isobusfs_priv *priv);
|
|
int isobusfs_cli_ccm_send(struct isobusfs_priv *priv);
|
|
void isobusfs_cli_fs_detect_timeout(struct isobusfs_priv *priv);
|
|
int isobusfs_cli_rx_cg_cm(struct isobusfs_priv *priv, struct isobusfs_msg *msg);
|
|
int isobusfs_cli_property_req(struct isobusfs_priv *priv);
|
|
int isobusfs_cli_volume_status_req(struct isobusfs_priv *priv,
|
|
uint8_t volume_mode,
|
|
uint16_t path_name_length,
|
|
const char *volume_name);
|
|
|
|
/* isobusfs_cli_dh.c */
|
|
int isobusfs_cli_ccd_req(struct isobusfs_priv *priv, const char *name,
|
|
size_t name_len);
|
|
int isobusfs_cli_get_current_dir_req(struct isobusfs_priv *priv);
|
|
int isobusfs_cli_rx_cg_dh(struct isobusfs_priv *priv,
|
|
struct isobusfs_msg *msg);
|
|
int isobusfs_cli_send_and_register_ccd_event(struct isobusfs_priv *priv,
|
|
const char *name,
|
|
size_t name_len,
|
|
isobusfs_event_callback cb,
|
|
void *ctx);
|
|
int isobusfs_cli_send_and_register_gcd_event(struct isobusfs_priv *priv,
|
|
isobusfs_event_callback cb,
|
|
void *ctx);
|
|
|
|
/* isobusfs_cli_fa.c */
|
|
int isobusfs_cli_rx_cg_fa(struct isobusfs_priv *priv,
|
|
struct isobusfs_msg *msg);
|
|
int isobusfs_cli_fa_of_req(struct isobusfs_priv *priv, const char *name,
|
|
size_t name_len, uint8_t flags);
|
|
int isobusfs_cli_fa_cf_req(struct isobusfs_priv *priv, uint8_t handle);
|
|
int isobusfs_cli_fa_rf_req(struct isobusfs_priv *priv, uint8_t handle,
|
|
uint16_t count);
|
|
int isobusfs_cli_fa_sf_req(struct isobusfs_priv *priv, uint8_t handle,
|
|
uint8_t position_mode, int32_t offset);
|
|
|
|
int isobusfs_cli_send_and_register_fa_of_event(struct isobusfs_priv *priv,
|
|
const char *name,
|
|
size_t name_len,
|
|
uint8_t flags,
|
|
isobusfs_event_callback cb,
|
|
void *ctx);
|
|
int isobusfs_cli_send_and_register_fa_sf_event(struct isobusfs_priv *priv,
|
|
uint8_t handle,
|
|
uint8_t position_mode,
|
|
int32_t offset,
|
|
isobusfs_event_callback cb,
|
|
void *ctx);
|
|
int isobusfs_cli_send_and_register_fa_rf_event(struct isobusfs_priv *priv,
|
|
uint8_t handle,
|
|
uint16_t count,
|
|
isobusfs_event_callback cb,
|
|
void *ctx);
|
|
int isobusfs_cli_send_and_register_fa_cf_event(struct isobusfs_priv *priv,
|
|
uint8_t handle,
|
|
isobusfs_event_callback cb,
|
|
void *ctx);
|
|
|
|
/* isobusfs_cli_selftests.c */
|
|
void isobusfs_cli_run_self_tests(struct isobusfs_priv *priv);
|
|
|
|
/* isobusfs_cli_int.c */
|
|
void isobusfs_cli_int_start(struct isobusfs_priv *priv);
|
|
int isobusfs_cli_interactive(struct isobusfs_priv *priv);
|
|
|
|
/* isobusfs_cli.c */
|
|
int isobusfs_cli_process_events_and_tasks(struct isobusfs_priv *priv);
|
|
void isobusfs_cli_prepare_response_event(struct isobusfs_event *event, int sock,
|
|
uint8_t fs_function);
|
|
int isobusfs_cli_register_event(struct isobusfs_priv *priv,
|
|
const struct isobusfs_event *new_event);
|
|
|
|
static inline uint8_t isobusfs_cli_get_next_tan(struct isobusfs_priv *priv)
|
|
{
|
|
return priv->next_tan++;
|
|
}
|
|
|
|
static inline bool isobusfs_cli_tan_is_valid(uint8_t tan,
|
|
struct isobusfs_priv *priv)
|
|
{
|
|
uint8_t expected_tan = priv->next_tan == 0 ? 255 : priv->next_tan - 1;
|
|
|
|
if (tan != expected_tan) {
|
|
pr_err("%s: tan %d is not valid, expected tan %d\n", __func__,
|
|
tan, expected_tan);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#endif /* ISOBUSFS_CLI_H */
|