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
Implement frame segmentation/reassembly state machine as per AX.25 v2.2
specifications, as per Section 6.6 "Disassembler/Reassembler" and
associated appendices
When a remote station wishes to connect by sending an XID frame, use
Timer T1 to send an XID response up to the retry count before closing
the socket pending negotiation
Changes:
* Add validation to accept() to ensure file descriptors provided
refer to SOCK_STREAM sockets in the SOCK_LISTENING state
* Rather than writing a reply to the patty client socket when
accepting a SABM or SABME request, write a message to the
remote end of the listening socket; this avoids issues wherein
a client receives an unexpected accept() response that may be
unrelated to another pending request; this also allows client
code to use select(2) on listening sockets
* In patty_client_accept(), send the initial request to validate
that the local socket can accept connections, and then wait for
a connection to be made, reading a message written to the
listening socket from the patty server
* Allow select(2) to notify on accepted connections
Changes:
* Replace usage of gettimeofday() with clock_gettime() in the main
event loop, patty_ax25_server_run(), as gettimeofday() apparently
goes backwards in time occasionally, as per:
https://bugzilla.redhat.com/show_bug.cgi?id=174390
Thanks Iain MM0ROR!
* Fix patty_timer_expired() to properly return true if the
remaining number of seconds is zero, but the remaining higher
precision time is less than zero
* Implement patty_timer_sub() to subtract two struct timespec
values, as glibc lacks timespecsub()
Changes:
* Implement handle_sock_dgram() to specifically handle datagram
(UI frame-only) sockets; this fixes issues wherein logic
specific to SOCK_STREAM timers would be erroneously applied
to datagram sockets
* Always tick Timers T1, T2 and T3
* Some slight code reorganization for improved readability of
control flow