setserial alternative

Hello!
Perhaps a bit offtopic, but could Ioninja perform some configurations similars to what "setserial" does?
The reason it that I have working with a Moxa RS232/485/422 device (UPORT 1250), and the mode (232/485/422) is configured using setserial (eg. setserial /dev/ttyUSB0 port 1). It would be useful to me to be able to configure it from inside ioninja (and to be franc, it would solve a problem I currently have, as I am not able to make setserial work well in my ARM device... any idea would be welcome :-)).
Regards!
Thank you

Hello Jose!

IO Ninja supports Python scripting now, so the easiest road to victory would be to find (or ask GPT/Claude to write) a snippet of Python equivalent of setserial.

A quick search reveals that setserial calls TIOCSSERIAL with struct serial_struct -- we just need to convert it to Python.

Claude wrote this:

import fcntl, struct, os

DEVICE = "/dev/ttyUSB0"

# ioctl request numbers (from <asm-generic/ioctls.h>)
TIOCGSERIAL = 0x541E   # get struct serial_struct
TIOCSSERIAL = 0x541F   # set struct serial_struct

# struct serial_struct — from <linux/serial.h>. Each format char below maps
# 1:1 to a field, in order. Native alignment (default '@', no </>/! prefix)
# reproduces the compiler's padding, so this is correct on both 64- and 32-bit.
#
#  idx  fmt  C type            field            off64  note
#  ---  ---  ----------------  ---------------  -----  -------------------------
#   0   i    int               type                 0
#   1   i    int               line                 4  ttyS index
#   2   I    unsigned int      port                 8  <-- set by `setserial port N`
#   3   i    int               irq                 12
#   4   i    int               flags               16
#   5   i    int               xmit_fifo_size      20
#   6   i    int               custom_divisor      24
#   7   i    int               baud_base           28
#   8   H    unsigned short    close_delay         32
#   9   c    char              io_type             34
#  10   c    char              reserved_char[1]    35
#            (1 byte pad)                          36  align int hub6 to 4
#  11   i    int               hub6                36
#  12   H    unsigned short    closing_wait        40
#  13   H    unsigned short    closing_wait2       42
#            (4 bytes pad, 64-bit)                 44  align pointer to 8
#  14   P    void *            iomem_base          48
#  15   H    unsigned short    iomem_reg_shift     56
#  16   I    unsigned int      port_high           60
#  17   L    unsigned long     iomap_base          64
#            total size: 72 bytes (64-bit); 60 bytes (32-bit)
FMT = "iiIiiiiiHcciHHPHIL"

PORT = 2  # field index of `port` in the tuple above

fd = os.open(DEVICE, os.O_RDWR | os.O_NOCTTY)
try:
    # Read-modify-write: pull the real struct, change only `port`, write it back.
    # This preserves every other field (and any padding) exactly as the kernel
    # returned it, so we never depend on constructing the struct from scratch.
    size = struct.calcsize(FMT)
    buf = fcntl.ioctl(fd, TIOCGSERIAL, bytes(size))
    fields = list(struct.unpack(FMT, buf))

    fields[PORT] = 1          # == `setserial /dev/ttyUSB0 port 1`

    fcntl.ioctl(fd, TIOCSSERIAL, struct.pack(FMT, *fields))
finally:
    os.close(fd)

Please note -- I didn't actually run it. But the code looks about right. Let me know if it works with your Moxa!