Implement patty_strlcpy() for portability and correctness, to provide
BSD strlcpy() functionality for glibc systems while ensuring a nul
terminated string is written to a destination, truncating the source
string by one byte if need be to make room for the nul terminator
Changes:
* Implement patty_ax25_if_reset() to allow pattyd(8) to attempt to
reset the network interface in the event of an I/O error
* Move existing link resetting code in src/aprs_is.c to
patty_ax25_aprs_is_reset(); allow src/server.c to call this rather
than within src/aprs_is.c itself
* Implement patty_kiss_tnc_reset(); this simply sets errno to ENOSYS
and returns -1 for the time being
Implement patty_ax25_if_ready() to provide a means of testing an
interface's readiness for performing I/O; this may also be used in the
future for some interface drivers which may require occasional keepalive
timers to maintain a link
Rename patty_ax25_sock_assembler_ready() to assembler_pending() to
better fit naming conventions; ready() is meant more for "does this
channel have any I/O readiness conditions", whereas pending() is best
suited for "does this state machine have a frame pending receipt"
Rename patty_ax25_if_ready() to if_pending() in src/if.c, as well as in
each driver implementing this method and any direct invocations of said
driver methods
Changes:
* Remove interface name argument from patty_ax25_if_new()
* Add interface name argument to patty_ax25_server_if_add()
* Add interface name argument to patty_daemon_if_add()
* In src/server.c, implement 'struct if_entry' to hold the interface
name, file descriptor, and pointer to a patty_ax25_if object, to
recouple names to their respective interfaces
* Add a return argument to patty_bin_if_create() to store a pointer
to a new interface name created from a declaration
Refactor handle_sock_raw() in src/server.c to remove usage of
patty_kiss_tnc_recv() in favor of its component methods:
* patty_kiss_tnc_fill()
* patty_kiss_tnc_drain()
* patty_kiss_tnc_ready()
* patty_kiss_tnc_flush()
Fix issue handling SOCK_RAW frames wherein patty_ax25_sock_send() is
used instead of patty_ax25_if_send() to send frames through the
interface bound to the socket
Split patty_ax25_if_recv() into the following parts:
* patty_ax25_if_fill(), to fill the internal PHY buffer
* patty_ax25_if_drain(), to drain the internal PHY buffer and decode
any data present in the buffer
* patty_ax25_if_ready(), to test if a complete frame has been
decoded
* patty_ax25_if_flush(), to return the final number of bytes decoded
in the PHY buffer and reset the decoding state
Other changes:
* Implement a finite state machine for decoding KISS traffic in
src/tnc.c, patty_ax25_kiss_drain()
* Refactor src/server.c, handle_iface() to use the aforementioned
frame receive/decode methods
Changes:
* Implement patty_ax25_if_driver type, providing a vtable with
pointers to methods implementing an AX.25 interface PHY
* Implement patty_ax25_if_name() to return a pointer to the name
string of an AX.25 interface
* Decouple patty_kiss_tnc from src/if.c using patty_ax25_if_driver
* Remove port input/output arguments from patty_kiss_tnc_send()
and patty_kiss_tnc_recv(), respectively; use 0 as the default,
but keep the port argument in patty_kiss_frame_send()
* Implement patty_ax25_if_fd() to return file descriptor backing a
PHY; use this rather than patty_kiss_tnc_fd() in src/server.c to
further decouple interfaces from their implementation
* Remove 'enum patty_ax25_if_type' type; refactor constructor
patty_ax25_if_new() to no longer take this as an argument, but
rather a patty_ax25_if_driver to use to instantiate the PHY
with the information pointer passed
* Break out patty_kiss_tnc code from src/kiss.c into src/tnc.c,
leaving only patty_kiss_frame_send() in the original; this is
needed to prevent a cyclic dependency within patty_ax25_sock and
other areas
* Rename patty_bin_if_config() to patty_bin_if_create(); a separate
patty_bin_if_config() will likely be created later as necessary
to change an existing interface
* Split PHY-specific interface configuration code into separate
delegates in bin/if.c
* Implement usage of patty_error to better capture internal error
states not currently representable with semantic error numbers
while configuring and instantiating PHYs
* Pass patty_error object to patty_bin_kiss_config() to receive
detailed error information
Changes:
* Implement src/conf.c, patty_conf_read(), to read a configuration
file to support a OpenBSD-style configuration file format
* Implement bin/pattyd.c to use patty_conf_read() to read a
configuration file and apply its settings to a patty_daemon
object as it is read; also implement a --standalone|-s flag to
allow the user to start a patty server without having to write
a configuration file
* Refactor patty_daemon_if_add() to accept a patty_ax25_if object;
this is necessary as bin/pattyd.c needs to be able to validate
the addresses given in a configuration file 'if' statement
* Refactor patty_ax25_server_new() to no longer accept a client
socket path; instead, patty_ax25_server_start() now accepts the
client socket path
* Remove the client socket 'path' member from patty_ax25_server in
src/server.c
* Refactor patty_kiss_tnc_new() to accept only one argument, a
patty_kiss_tnc_info object containing flags and settings needed
to open a device, use an existing file descriptor, or change
termios settings as appropriate
* Remove patty_kiss_tnc_new_fd(), as its functionality now exists
in patty_kiss_tnc_new() itself
* Add a 'flags' field to patty_kiss_tnc_info; use this bit field
to determine whether a path or file descriptor is provided by
the caller
* Make patty_ax25_if_new() accept an interface name argument, as
names are explicitly required when declaring new interfaces in
configuration files
* Make patty_kiss_tnc_new() able to accept /dev/ptmx as a device
name, regardless of whether this character device exists on a
given platform; when provided, a pseudo TTY pair is allocated
with openpty()
* Refactor examples/ax25dump.c to use the new patty_kiss_tnc_new()
calling convention
* Refactor examples/decode.c to use the new patty_kiss_tnc_new()
calling convention
* Remove examples/daemon.c in favor of bin/pattyd.c
* Rename examples/patty.conf to examples/pattyd.conf; modify to
provide values which would actually function
Implement src/daemon.c to provide a high level method to instantiate a
patty server
Changes:
* Refactor src/server.c, src/route.c, src/if.c methods which accept
callsign arguments to use a patty_ax25_addr pointer instead; this
has significantly reduced the number of redundant calls to
patty_ax25_pton()
* Decouple patty_ax25_addr from patty_ax25_if_info types when
creating new interfaces with patty_ax25_if_new(); instead, take a
separate patty_ax25_addr argument
* Split patty_ax25_server_run() into the following methods:
- patty_ax25_server_start()
- patty_ax25_server_stop()
- patty_ax25_server_event_handle()
This is intended to allow possible integration into other event
loops.
* Implement src/daemon.c to allow quick instantiation of a server,
interfaces, and routes, and to encapsulate the setting of
configuration variables; callsigns and interface names are handled
as character strings
* Rename examples/server.c to examples/daemon.c; reimplement in
terms of the patty_daemon code
*
Rename patty_ax25_sock.rx_buf to io_buf, as the buffer is not used for
receiving frames from an interface, but rather from reading local data
to write to a remote peer
Other changes:
* Fix issue wherein patty_ax25_sock.n_maxlen_tx was not used for
reading local data when sending I frames
Changes:
* Ensure Timer T1 is stopped when Timer T3 is active
* Ensure Timer T1 is started when an acknowledgement from the peer
does not acknowledge all I frames previously sent
Stop flow before sending last I frame in window; furthermore, this last
I frame will have the P/F flag set to 1, to implicitly request a RR, RNR
or REJ response as appropriate
Start Timer T3 when starting Timer T1 after expiry, to avoid a situation
wherein two RR command polling frames may be sent within close proximity
of one another
When handling I frames, stop Timer T2 if the number of unacknowledged
frames has reached k/2
Other changes:
* Provide annotations from the AX.25 v2.2 standards document
* Improve implementation of I frame reception P/F procedure
Always send RR when Timer T3 runs out, as we are not likely (with modern
hardware with MMUs) to be unable to receive; furthermore, RNR would have
only been sent erroneously if the outward flow of traffic had been
stopped
Changes:
* Use patty_ax25_sock_reset() when receiving a FRMR, SABM, or SABME
frame
* Reply to an SABM or SABME frame with a UA when received by an
ESTABLISHED socket
Implement AX.25 v2.2, Section 6.4.6 "Receiving Acknowledgement"
semantics more consistently
Changes:
* Add frame_ack() method in src/server.c to unify logic for
acknowledging frames and handling I frame transmission flow
control
* Ensure that the Timer T1 retry counter is reset as appropriate
when Timer T1 is restarted
* Add excerpts from the AX.25 v2.2 documentation to accompanying
code to better document the purpose of important aspects of the
state machine and protocol
* When receiving an S frame with N(R) acknowledgement of a frame
sent earlier than indicated by V(S), set V(S) to that N(R) value
* Implement patty_ax25_sock_resend_pending() as a means to resend
one frame previously sent which remains unacknowledged; this
uses V(S) to determine the frame to resend, and increments V(S) if
there was indeed an unacknowledged frame
* Call patty_ax25_sock_resend_pending() in src/server.c, method
handle_sock() to send a single frame previously sent but pending
acknowledgement
Changes:
* Make patty_ax25_sock_ack() take a N(R) argument directly, rather
than having the caller specify N(R)-1
* Only perform acknowledgement of frames within the range between
V(A) and N(R)-1
Implement patty_timer_init() to allow the caller to specify a timer
value to use each time patty_timer_start() is called, obviating the need
to pass the same argument redundantly; if the timer value must be
changed, then another call to patty_timer_init() may be used