Commit Graph
26 Commits
Author SHA1 Message Date
Oliver Hartkopp 8355b57133 isobusfs: fix printf format specifiers in log messages
Several log messages used format specifiers which did not match the
types of the provided arguments (e.g. %d or %i for size_t/ssize_t,
%ld for int64_t/time_t and size_t for the '.*' precision). On 64 bit
hosts (and for int64_t/time_t on 32 bit hosts) this leads to wrong
output or undefined behaviour when the log level is enabled.

Additionally the seek response position was compared to the requested
offset without le32toh() conversion which fails on big endian hosts.

Fix the format specifiers and add the missing le32toh() conversion.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
2026-10-14 19:25:06 +02:00
Oliver Hartkopp aa54819b65 isobusfs: pack the protocol structures
The isobusfs protocol structures describe the message layout defined in
ISO 11783-13 but were not packed. The compiler added padding bytes in
front of 16/32 bit values which follow an odd number of bytes, e.g. the
Read File Request (8 bytes according to C.3.5.2) had a size of 10 bytes
and the count value at the wrong position. Server and client of the
can-utils used the same structures and understood each other but the
messages were not compatible to other ISOBUS devices. Additionally the
padding bytes sent uninitialized content.

Add __attribute__((__packed__)) to all protocol structures as it is
already done in j1939_vehicle_position.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
2026-10-14 10:21:56 +00:00
Oliver Hartkopp 8222f517b7 isobusfs: cli: use htole16() for the path name length in requests
The Change Current Directory and Open File requests assigned the path
name length to the little endian name_len element without conversion,
which leads to wrong values on big endian hosts.

Use htole16() as it is already done in the other requests.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
2026-10-14 10:21:56 +00:00
Oliver Hartkopp 775611dba2 isobusfs: srv: add missing break statements in current directory response
The switch statement which maps the errors of the current directory
access check to the ISOBUS FS error codes had no break statements. Due
to the fall through every error was reported as ISOBUSFS_ERR_OTHER.

Add the missing break statements.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
2026-10-14 10:21:56 +00:00
Oliver Hartkopp cd0ff30788 isobusfs: srv: check strdup() result when adding a new handle
The path of a handle is also used to mark the handle slot as used. When
strdup() failed the handle was returned to the client but the slot was
still marked as free and got reused (and the file descriptor of the
first user got lost) with the next open request.

Return -ENOMEM when the path can not be allocated. The callers close the
file descriptor and the handle slot remains unused.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
2026-10-14 10:21:56 +00:00
Oliver Hartkopp 3a980d83e0 isobusfs: srv: free handle path when closing the handle
The path of an opened file or directory handle is allocated with
strdup() but was not freed when the handle got closed. Every open/close
sequence leaked the path string.

Free the path before clearing the handle.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
2026-10-14 10:21:56 +00:00
Oliver Hartkopp 13dc8e9cc5 isobusfs: srv: check name length against the received message length
The Change Current Directory and Volume Status requests used the path
and volume name length from the request without checking it against
the received message length. Short messages with a big name length made
the server process stale content of the receive buffer as path or
volume name.

Check the name length against the message length, use le16toh() for the
CCD name length and fix the debug output of the volume name.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
2026-10-14 10:21:56 +00:00
Oliver Hartkopp d5571a5bc3 isobusfs: srv: pad short Read File responses within the allocated buffer
The Read File response buffer was allocated for the response header and
the requested data only. Short responses (e.g. count = 0) are extended to
ISOBUSFS_MIN_TRANSFER_LENGH which read beyond the allocated buffer and
sent heap content to the client.

Allocate at least ISOBUSFS_MIN_TRANSFER_LENGH bytes and fill the unused
bytes with 0xff.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
2026-10-14 10:21:56 +00:00
Oliver Hartkopp 33f7ddb5ed isobusfs: srv: check handle state and owner for read and seek requests
Read File and Seek File requests only checked the handle index to be
within the handles array. Unused or closed handle slots are zeroed
(fd = 0, dir = NULL), so a read request on such a handle read from the
server's stdin and sent the content to the client. Additionally every
client was able to read and seek handles opened by other clients.

Add isobusfs_srv_get_client_handle() which only returns handles that
are in use and have been opened by the requesting client.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
2026-10-14 10:21:56 +00:00
Oleksij RempelandOliver Hartkopp c7a02c0258 isobusfs: fix directory read and seek semantics to match ISO 11783-13
Fix directory operations to comply with ISO 11783-13:2021 (sections
C.3.4.2 and C.3.5.2), which specifies that directory operations differ
significantly from standard file operations:
- The Count parameter in a Read File request represents the number of
  directory entries to read, not the number of bytes.
- The Offset parameter in a Seek File request represents the logical
  entry index, not a byte offset.

The previous implementation treated directories strictly as files,
using byte-based offsets and counts. This resulted in incorrect seeking
behavior and protocol violations when listing directories.

Align the implementation with the standard by:

1. Server side:
   - Introduce isobusfs_srv_dir_entry_visible() to consistently
     filter out invalid (unreadable, hidden, oversized) entries. This
     ensures that entry indices remain stable.
   - Implement isobusfs_srv_dir_skip_entries() to advance the
     directory stream by logical visible entries rather than bytes.
   - Update the Read File handler to interpret count as the
     maximum number of entries and return the number of entries read
     in the response header.
   - Update the Seek File handler to seek by entry index.

2. Client side:
   - Calculate the request count based on the number of minimal-size
     entries that fit into the maximum data length.
   - Interpret the response count as the number of entries received
     rather than the byte length of the payload.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
2026-10-14 10:21:56 +00:00
Oleksij RempelandOliver Hartkopp a63fd488b2 isobusfs: treat interactive exit as control flow, not error
The cmd_exit() function used -EINTR to signal a clean exit from the
interactive mode. This is semantically incorrect because EINTR is an
errno value meant for system call interruptions, not application-level
control flow.

Stop using -EINTR for cmd_exit(). Introduce ISOBUSFS_CLI_RET_EXIT (a
positive return code) to distinguish control flow from actual errors.
Map this to exit code 0 in main(), keeping negative errno values for
real errors. This makes the exit path explicit and prevents confusion
with actual interrupted system calls.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
2026-10-14 10:21:55 +00:00
Oleksij RempelandOliver Hartkopp 64280dc9c3 isobusfs: selftest: Handle read requests larger than file size
Add expected_size field to test patterns to properly validate cases
where the requested read size exceeds the actual file size. This allows
testing the server's behavior when clients request more data than is
available.

When a read request is larger than the file, the server correctly
returns data up to EOF. The test framework now distinguishes between
this expected scenario and genuine read failures.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
[socketcan: addressed review comments from PR #629:
 - keep uint32_t instead of size_t for offset/read_size/expected_size:
   ISO 11783-13 limits the file offset (Seek File) and the file size
   (directory entry) to 32 bit, so uint32_t matches the protocol. The
   sum offset + read_size can exceed 32 bit (see UINT32_MAX pattern)
   and is therefore calculated in int64_t. size_t would not help here
   as it is only 32 bit wide on 32 bit targets.
 - remaining_size is a signed int64_t: the signed type is needed to
   detect the 'remaining_size < 0' case (server returned more data than
   requested) and int64_t holds the 33 bit sum on all platforms.
 - fix printf format for the uint32_t read_offset (%zu -> %u)]
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
2026-10-14 10:21:55 +00:00
Marc Kleine-Budde e8130a3575 treewide: fix typos 2025-03-03 10:18:25 +01:00
Yegor Yefremov 72a9fd8ccd isobusfs: fix typos
Typos were found with codespell.

Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
2025-03-02 15:44:40 +01:00
Oleksij Rempel af95ee0c6d move part of isobusfs code to the libj1939
Move part of isobusfs which can be reused by other applications to the
libj1939. By the way, reuse some of new libj1939 code in the j1939cat.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
2024-06-06 13:53:19 +02:00
Marc Kleine-Budde e0bb44c908 isobusfs_cmn: isobusfs_print_timestamp(): always use 64-bit for time stamp formatting
Using C99 `unsigned long long` to format `struct timeval`'s `tv_sec`
and `tv_usec`, fix incorrect print under some 32bit platform which
using time64.
2024-05-29 14:27:34 +02:00
Oleksij Rempel 8012b3b23d isobusfs: address snprintf truncation warning with explicit limits
Modify the isobusfs_log function in isobusfs_cmn.c to explicitly limit
the lengths of the time_buffer, level_str, and log_entry strings in
the snprintf format string to 40, 10, and 150 characters respectively.
This change acknowledges that truncation may still occur, but it is now
explicit and controlled.

This change silences the following warning:
cmake -DCMAKE_BUILD_TYPE=Debug -D CMAKE_C_COMPILER=gcc -B build
cmake --build build

/home/isobusfs/isobusfs_cmn.c: In function 'isobusfs_log':
/home/isobusfs/isobusfs_cmn.c:104:30: warning: '%s' directive output
may be truncated writing up to 191 bytes into a region of size between
182 and 245 [-Wformat-truncation=]
  104 |                  "[%s] [%s]: %s", time_buffer, level_str, log_entry);
      |                              ^~                           ~~~~~~~~~
/home/isobusfs/isobusfs_cmn.c:103:9: note: 'snprintf' output 12 or more
bytes (assuming 266) into a destination of size 256
  103 |         snprintf(complete_log_entry, sizeof(complete_log_entry),
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  104 |                  "[%s] [%s]: %s", time_buffer, level_str, log_entry);
      |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
2024-05-29 10:54:18 +02:00
Oleksij Rempel 06ab86226a isobusfs_srv_cm: do not try to add padding beyond the buffer
The memset in isobusfs_srv_volume_status_resp() was attempting to make a
padding beyond the buffer. Fix it.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
2024-05-25 07:57:16 +02:00
Oleksij Rempel fc742c574e isobusfs_srv_cm: make sure we do le16toh/htole16 conversation for name_len
name_len is __le16. We need always convert it to host byte order.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
2024-05-25 07:57:16 +02:00
Oleksij Rempel 1e8bc8fd34 isobusfs: do not kill application on error_queue error
Kernel may notify us about some error, which may happens if the bus was
in the error state. But this is not a good reason to kill application,
especially the server side.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
2024-05-25 07:57:16 +02:00
Oliver HartkoppandGitHub 8d7d7650d4 can-utils: fix sign-compare warnings (#513)
Fixing several build issues reported by Gary Bisson when he was building
can-utils with clang (AOSP14).

URL: https://github.com/linux-can/can-utils/pull/512
Reported-by: Gary Bisson (https://github.com/gibsson)

Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
2024-04-24 20:02:02 +02:00
Oleksij Rempel 91a93353ae isobusfs: fix clang warnings
Fix following clang warnings:
  CC       isobusfs/isobusfs_srv_fa.o
  isobusfs/isobusfs_srv_fa.c:387:6: warning: variable 'handle' is used
  uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
        if (ret < 0) {
            ^~~~~~~
  isobusfs/isobusfs_srv_fa.c:411:15: note: uninitialized use occurs here
        res.handle = handle;
                     ^~~~~~
  isobusfs/isobusfs_srv_fa.c:387:2: note: remove the 'if' if its condition is
  always false
        if (ret < 0) {
        ^~~~~~~~~~~~~~
  isobusfs/isobusfs_srv_fa.c:368:6: warning: variable 'handle' is used
  uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
        if (name_len > ISOBUSFS_MAX_PATH_NAME_LENGTH) {
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  isobusfs/isobusfs_srv_fa.c:411:15: note: uninitialized use occurs here
        res.handle = handle;
                     ^~~~~~
  isobusfs/isobusfs_srv_fa.c:368:2: note: remove the 'if' if its condition is
  always false
        if (name_len > ISOBUSFS_MAX_PATH_NAME_LENGTH) {
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  isobusfs/isobusfs_srv_fa.c:362:6: warning: variable 'handle' is used
  uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
        if (name_len > msg->len - sizeof(*req)) {
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  isobusfs/isobusfs_srv_fa.c:411:15: note: uninitialized use occurs here
        res.handle = handle;
                     ^~~~~~
  isobusfs/isobusfs_srv_fa.c:362:2: note: remove the 'if' if its condition is
  always false
        if (name_len > msg->len - sizeof(*req)) {
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  isobusfs/isobusfs_srv_fa.c:356:6: warning: variable 'handle' is used
  uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
        if (!client) {
            ^~~~~~~
  isobusfs/isobusfs_srv_fa.c:411:15: note: uninitialized use occurs here
        res.handle = handle;
                     ^~~~~~
  isobusfs/isobusfs_srv_fa.c:356:2: note: remove the 'if' if its condition is
  always false
        if (!client) {
        ^~~~~~~~~~~~~~
  isobusfs/isobusfs_srv_fa.c:352:16: note: initialize the variable 'handle' to
  silence this warning
        uint8_t handle;
                      ^
                       = '\0'
  isobusfs/isobusfs_srv_fa.c:505:9: warning: variable 'entry_count' set but not
  used [-Wunused-but-set-variable]
        size_t entry_count = 0;
               ^
  5 warnings generated.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
2024-03-22 10:44:17 +01:00
Gennadij Sergej Yatskov 5bebe13cc1 Fixes musl build for ARMv7
See also 0e0a033
2024-02-20 11:06:13 +01:00
Marc Kleine-Budde 7c56863047 isobusfs_cmn: isobusfs_get_timeout_ms(): fix print on 32 bit archs
Fixes the following warning:

| isobusfs/isobusfs_cmn.c: In function 'isobusfs_get_timeout_ms':
| isobusfs/isobusfs_cmn.c:140:51: warning: format '%ld' expects argument of type 'long int', but argument 2 has type 'int64_t' {aka 'long long int'} [-Wformat=]
|   140 |                         warn("timeout too long: %ld ms", time_diff);
|       |                                                 ~~^      ~~~~~~~~~
|       |                                                   |      |
|       |                                                   |      int64_t {aka long long int}
|       |                                                   long int
|       |                                                 %lld
2024-02-13 14:08:27 +01:00
Oleksij Rempel 939e4d7e8c isobusfs: change license to LGPL-2.0-only
Before more contributions will come, change the license and make this
project usable as a library.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
2024-02-04 19:15:25 +01:00
Oleksij RempelandOleksij Rempel 42edaeaf52 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>
2024-02-02 13:44:07 +01:00