1 //
2 //    This file is part of Dire Wolf, an amateur radio packet TNC.
3 //
4 //    Copyright (C) 2016, 2017, 2018  John Langner, WB2OSZ
5 //
6 //    This program is free software: you can redistribute it and/or modify
7 //    it under the terms of the GNU General Public License as published by
8 //    the Free Software Foundation, either version 2 of the License, or
9 //    (at your option) any later version.
10 //
11 //    This program is distributed in the hope that it will be useful,
12 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //    GNU General Public License for more details.
15 //
16 //    You should have received a copy of the GNU General Public License
17 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 //
19 
20 
21 /*------------------------------------------------------------------
22  *
23  * Name:	ax25_link
24  *
25  * Purpose:	Data Link State Machine.
26  *		Establish connections and transfer data in the proper
27  *		order with retries.
28  *
29  * Description:
30  *
31  *		Typical sequence for establishing a connection
32  *		initiated by a client application.  Try version 2.2,
33  *		get refused, and fall back to trying version 2.0.
34  *
35  *
36  *	State		Client App		State Machine		Peer
37  *	-----		----------		-------------		----
38  *
39  *	0 disc
40  *			Conn. Req  --->
41  *						SABME  --->
42  *	5 await 2.2
43  *								  <---	FRMR or DM *note
44  *						SABM  --->
45  *	1 await 2.0
46  *								  <---	UA
47  *					  <---	CONN Ind.
48  *	3 conn
49  *
50  *
51  *		Typical sequence when other end initiates connection.
52  *
53  *
54  *	State		Client App		State Machine		Peer
55  *	-----		----------		-------------		----
56  *
57  *	0 disc
58  *								  <---	SABME or SABM
59  *						UA  --->
60  *					  <---	CONN Ind.
61  *	3 conn
62  *
63  *
64  *	*note:
65  *
66  * 	After carefully studying the v2.2 spec, I expected a 2.0 implementation to send
67  *	FRMR in response to SABME.  This is important.  If a v2.2 implementation
68  *	gets FRMR, in response to SABME, it switches to v2.0 and sends SABM instead.
69  *
70  *	The v2.0 protocol spec, section 2.3.4.3.3.1, states that FRMR should be sent when
71  *	an invalid or not implemented command is received.  That all fits together.
72  *
73  *	In testing, I found that the KPC-3+ sent DM.
74  *
75  *	I can see where they might get that idea.
76  *	The v2.0 spec says that when in disconnected mode, it should respond to any
77  *	command other than SABM or UI frame with a DM response with P/F set to 1.
78  *	I think it was implemented wrong.  2.3.4.3.3.1 should take precedence.
79  *
80  *	The TM-D710 does absolutely nothing in response to SABME.
81  *	Not responding at all is just plain wrong.   To work around this, I put
82  *	in a special hack to start sending SABM after a certain number of
83  *	SABME go unanswered.   There is more discussion in the User Guide.
84  *
85  * References:
86  *		* AX.25 Amateur Packet-Radio Link-Layer Protocol Version 2.0, October 1984
87  *
88  * 			https://www.tapr.org/pub_ax25.html
89  *			http://lea.hamradio.si/~s53mv/nbp/nbp/AX25V20.pdf
90  *
91  *			At first glance, they look pretty much the same, but the second one
92  *			is more complete with 4 appendices, including a state table.
93  *
94  *		* AX.25 Link Access Protocol for Amateur Packet Radio Version 2.2 Revision: July 1998
95  *
96  *			https://www.tapr.org/pdf/AX25.2.2.pdf
97  *
98  *		* AX.25 Link Access Protocol for Amateur Packet Radio Version 2.2 Revision: July 1998
99  *
100  *			http://www.ax25.net/AX25.2.2-Jul%2098-2.pdf
101  *
102  *			I accidentally stumbled across this one when searching for some sort of errata
103  *			list for the original protocol specification.
104  *
105  *				"This is a new version of the 1998 standard. It has had all figures
106  *				 redone using Microsoft Visio. Errors in the SDL have been corrected."
107  *
108  *			The SDL diagrams are dated 2006.  I wish I had known about this version, with
109  *			several corrections, before doing most of the implementation.  :-(
110  *
111  *			The title page still says July 1998 so it's not immediately obvious this
112  *			is different than the one on the TAPR site.
113  *
114  *		* AX.25  ...  Latest revision, in progress.
115  *
116  *			http://www.nj7p.org/
117  *
118  *			This is currently being revised in cooperation with software authors
119  *			who have noticed some issues during implementation.
120  *
121  *		The functions here are based on the SDL diagrams but turned inside out.
122  *		It seems more intuitive to have a function for each type of input and then decide
123  *		what to do depending on the state.  This also reduces duplicate code because we
124  *		often see the same flow chart segments, for the same input, appearing in multiple states.
125  *
126  * Errata:	The protocol spec has many places that appear to be errors or are ambiguous so I wasn't
127  *		sure what to do.  These should be annotated with "erratum" comments so we can easily go
128  *		back and revisit them.
129  *
130  * X.25:	The AX.25 protocol is based on, but does not necessarily adhere to, the X.25 protocol.
131  *		Consulting this might provide some insights where the AX.25 spec is not clear.
132  *
133  *			http://www.itu.int/rec/T-REC-X.25-199610-I/en/
134  *
135  * Version 1.4, released April 2017:
136  *
137  *		Features tested reasonably well:
138  *
139  *			Connect to/from a KPC-3+ and send I frames in both directions.
140  *			Same with TM-D710A.
141  *			v2.2 connect between two instances of direwolf.  (Can't find another v2.2 for testing.)
142  *			Modulo 8 & 128 sequence numbers.
143  *			Recovery from simulated transmission errors using either REJ or SREJ.
144  *			XID frame for parameter negotiation.
145  *			Segments to allow data larger than max info part size.
146  *
147  *		Implemented but not tested properly:
148  *
149  *			Connecting thru digipeater(s).
150  *			Acting as a digipeater.
151  *			T3 timer.
152  *			Compatibility with additional types of TNC.
153  *
154  * Version 1.5, December 2017:
155  *
156  *		Implemented Multi Selective Reject.
157  *		More efficient generation of SREJ frames.
158  *		Reduced number of duplicate I frames sent for both REJ and SREJ cases.
159  *		Avoided unnecessary RR when I frame could take care of the ack.
160  *		(This led to issue 132 where outgoing data sometimes got stuck in the queue.)
161  *
162  *------------------------------------------------------------------*/
163 
164 #include "direwolf.h"
165 
166 
167 #include <stdlib.h>
168 #include <string.h>
169 #include <assert.h>
170 #include <stdio.h>
171 #include <ctype.h>
172 #include <math.h>
173 
174 
175 #include "ax25_pad.h"
176 #include "ax25_pad2.h"
177 #include "xid.h"
178 #include "textcolor.h"
179 #include "dlq.h"
180 #include "tq.h"
181 #include "ax25_link.h"
182 #include "dtime_now.h"
183 #include "server.h"
184 #include "ptt.h"
185 
186 
187 #define MIN(a,b) ((a)<(b)?(a):(b))
188 #define MAX(a,b) ((a)>(b)?(a):(b))
189 
190 // Debug switches for different types of information.
191 // Should have command line options instead of changing source and recompiling.
192 
193 static int s_debug_protocol_errors = 1;	// Less serious Protocol errors.
194 					// Useful for debugging but unnecessarily alarming other times.
195 
196 static int s_debug_client_app = 0;	// Interaction with client application.
197 					// dl_connect_request, dl_data_request, dl_data_indication, etc.
198 
199 static int s_debug_radio = 0;		// Received frames and channel busy status.
200 					// lm_data_indication, lm_channel_busy
201 static int s_debug_variables = 0;	// Variables, state changes.
202 
203 static int s_debug_retry = 0;		// Related to lost I frames, REJ, SREJ, timeout, resending.
204 
205 static int s_debug_timers = 0;		// Timer details.
206 
207 static int s_debug_link_handle = 0;	// Create data link state machine or pick existing one,
208 					// based on my address, peer address, client app index, and radio channel.
209 
210 static int s_debug_stats = 0;		// Statistics when connection is closed.
211 
212 static int s_debug_misc = 0;		// Anything left over that might be interesting.
213 
214 
215 /*
216  * AX.25 data link state machine.
217  *
218  * One instance for each link identified by
219  *	[ client, channel, owncall, peercall ]
220  */
221 
222 enum dlsm_state_e {
223 	state_0_disconnected = 0,
224 	state_1_awaiting_connection = 1,
225 	state_2_awaiting_release = 2,
226 	state_3_connected = 3,
227 	state_4_timer_recovery = 4,
228 	state_5_awaiting_v22_connection = 5 };
229 
230 
231 typedef struct ax25_dlsm_s {
232 
233 	int magic1;				// Look out for bad pointer or corruption.
234 #define MAGIC1 0x11592201
235 
236 	struct ax25_dlsm_s *next;		// Next in linked list.
237 
238 	int stream_id;				// Unique number for each stream.
239 						// Internally we use a pointer but this is more user-friendly.
240 
241 	int chan;				// Radio channel being used.
242 
243 	int client;				// We have have multiple client applications,
244 						// each with their own links.  We need to know
245 						// which client should receive the data or
246 						// notifications about state changes.
247 
248 
249 	char addrs[AX25_MAX_REPEATERS][AX25_MAX_ADDR_LEN];
250 						// Up to 10 addresses, same order as in frame.
251 
252 	int num_addr;				// Number of addresses.  Should be in range 2 .. 10.
253 
254 #define OWNCALL AX25_SOURCE
255 						// addrs[OWNCALL] is owncall for this end of link.
256 						// Note that we are acting on behalf of
257 						// a client application so the APRS mycall
258 						// might not be relevent.
259 
260 #define PEERCALL AX25_DESTINATION
261 						// addrs[PEERCALL] is call for other end.
262 
263 
264 	double start_time;			// Clock time when this was allocated.  Used only for
265 						// debug output for timestamps relative to start.
266 
267 	enum dlsm_state_e state;		// Current state.
268 
269 	int modulo;				// 8 or 128.
270 						// Determines whether we have one or two control
271 						// octets.  128 allows a much larger window size.
272 
273 	enum srej_e srej_enable;		// Is other end capable of processing SREJ?  (Am I allowed to send it?)
274 						// Starts out as 'srej_none' for v2.0 or 'srej_single' for v2.2.
275 						// Can be changed to 'srej_multi' with XID exchange.
276 						// Should be used only with modulo 128.  (Is this enforced?)
277 
278 	int n1_paclen;				// Maximum length of information field, in bytes.
279 						// Starts out as 256 but can be negotiated higher.
280 						// (Protocol Spec has this in bits.  It is in bytes here.)
281 						// "PACLEN" in configuration file.
282 
283 	int n2_retry;				// Maximum number of retries permitted.
284 						// Typically 10.
285 						// "RETRY" parameter in configuration file.
286 
287 
288 	int k_maxframe;				// Window size. Defaults to 4 (mod 8) or 32 (mod 128).
289 						// Maximum number of unacknowledged information
290 						// frames that can be outstanding.
291 						// "MAXFRAME" or "EMAXFRAME" parameter in configuration file.
292 
293 	int rc;					// Retry count.  Give up after n2.
294 
295 	int vs;					// 4.2.4.1. Send State Variable V(S)
296 						// The send state variable exists within the TNC and is never sent.
297 						// It contains the next sequential number to be assigned to the next
298 						// transmitted I frame.
299 						// This variable is updated with the transmission of each I frame.
300 
301 	int va;					// 4.2.4.5. Acknowledge State Variable V(A)
302 						// The acknowledge state variable exists within the TNC and is never sent.
303 						// It contains the sequence number of the last frame acknowledged by
304 						// its peer [V(A)-1 equals the N(S) of the last acknowledged I frame].
305 
306 	int vr;					// 4.2.4.3. Receive State Variable V(R)
307 						// The receive state variable exists within the TNC.
308 						// It contains the sequence number of the next expected received I frame
309 						// This variable is updated upon the reception of an error-free I frame
310 						// whose send sequence number equals the present received state variable value.
311 
312 	int layer_3_initiated;			// SABM(E) was sent by request of Layer 3; i.e. DL-CONNECT request primitive.
313 						// I think this means that it is set only if we initiated the connection.
314 						// It would not be set if we are in the middle of accepting a connection from the other station.
315 
316 // Next 5 are called exception conditions.
317 
318 	int peer_receiver_busy;			// Remote station is busy and can't receive I frames.
319 
320 	int reject_exception;			// A REJ frame has been sent to the remote station. (boolean)
321 
322 						// This is used only when receving an I frame, in states 3 & 4, SREJ not enabled.
323 						// When an I frame has an unepected N(S),
324 						//   - if not already set, set it and send REJ.
325 						// When an I frame with expected N(S) is received, clear it.
326 						// This would prevent us from sending additional REJ while
327 						// waiting for result from first one.
328 						// What happens if the REJ gets lost?   Is it resent somehow?
329 
330 	int own_receiver_busy;			// Layer 3 is busy and can't receive I frames.
331 						// We have no API to convey this information so it should always be 0.
332 
333 	int acknowledge_pending;		// I frames have been successfully received but not yet
334 						// acknowledged TO the remote station.
335 						// Set when receiving the next expected I frame and P=0.
336 						// This gets cleared by sending any I, RR, RNR, REJ.
337 						// Cleared when sending SREJ with F=1.
338 
339 // Timing.
340 
341 	float srt;				// Smoothed roundtrip time in seconds.
342 						// This is used to dynamically adjust t1v.
343 						// Sometimes the flow chart has SAT instead of SRT.
344 						// I think that is a typographical error.
345 
346 	float t1v;				// How long to wait for an acknowlegement before resending.
347 						// Value used when starting timer T1, in seconds.
348 						// "FRACK" parameter in some implementations.
349 						// Typically it might be 3 seconds after frame has been
350 						// sent.  Add more for each digipeater in path.
351 						// Here it is dynamically adjusted.
352 
353 // Set initial value for T1V.
354 // Multiply FRACK by 2*m+1, where m is number of digipeaters.
355 
356 #define INIT_T1V_SRT	\
357 	    S->t1v = g_misc_config_p->frack * (2 * (S->num_addr - 2) + 1); \
358 	    S->srt = S->t1v / 2.0;
359 
360 
361 	int radio_channel_busy;			// Either due to DCD or PTT.
362 
363 
364 // Timer T1.
365 
366 // Timer values all use the usual unix time() value but double precision
367 // so we can have fractions of seconds.
368 
369 // T1 is used for retries along with the retry counter, "rc."
370 // When timer T1 is started, the value is obtained from t1v plus the current time.
371 
372 
373 // Appropriate functions should be used rather than accessing the values directly.
374 
375 
376 
377 // This gets a little tricky because we need to pause the timers when the radio
378 // channel is busy.  Suppose we sent an I frame and set T1 to 4 seconds so we could
379 // take corrective action if there is no response in a reasonable amount of time.
380 // What if some other station has the channel tied up for 10 seconds?   We don't want
381 // T1 to timeout and start a retry sequence.  The solution is to pause the timers while
382 // the channel is busy.  We don't want to get a timer expiry event when t1_exp is in
383 // the past if it is currently paused.  When it is un-paused, the expiration time is adjusted
384 // for the amount of time it was paused.
385 
386 
387 	double t1_exp;				// This is the time when T1 will expire or 0 if not running.
388 
389 	double t1_paused_at;			// Time when it was paused or 0 if not paused.
390 
391 	float t1_remaining_when_last_stopped;	// Number of seconds that were left on T1 when it was stopped.
392 						// This is used to fine tune t1v.
393 						// Set to negative initially to mean invalid, don't use in calculation.
394 
395 	int t1_had_expired;			// Set when T1 expires.
396 						// Cleared for start & stop.
397 
398 
399 // Timer T3.
400 
401 // T3 is used to terminate connection after extended inactivity.
402 
403 
404 // Similar to T1 except there is not mechanism to capture the remaining time when it is stopped
405 // and it is not paused when the channel is busy.
406 
407 
408 	double t3_exp;				// When it expires or 0 if not running.
409 
410 #define T3_DEFAULT 300.0			// Copied 5 minutes from Ax.25 for Linux.
411 						// http://www.linux-ax25.org/wiki/Run_time_configurable_parameters
412 						// D710A also defaults to 30*10 = 300 seconds.
413 						// Should it be user-configurable?
414 						// KPC-3+ and TM-D710A have "CHECK" command for this purpose.
415 
416 // Statistics for testing purposes.
417 
418 // Count how many frames of each type we received.
419 // This is easy to do because they all come in thru lm_data_indication.
420 // Counting outgoing could probably be done in lm_data_request so
421 // it would not have to be scattered all over the place.  TBD
422 
423 	int count_recv_frame_type[frame_not_AX25+1];
424 
425 	int peak_rc_value;			// Peak value of retry count (rc).
426 
427 
428 // For sending data.
429 
430 	cdata_t *i_frame_queue;		// Connected data from client which has not been transmitted yet.
431 						// Linked list.
432 						// The name is misleading because these are just blocks of
433 						// data, not "I frames" at this point.  The name comes from
434 						// the protocol specification.
435 
436 	cdata_t *txdata_by_ns[128];		// Data which has already been transmitted.
437 						// Indexed by N(S) in case it gets lost and needs to be sent again.
438 						// Cleared out when we get ACK for it.
439 
440 	int magic3;				// Look out for out of bounds for above.
441 #define MAGIC3 0x03331301
442 
443 	cdata_t *rxdata_by_ns[128];		// "Receive buffer"
444 						// Data which has been received out of sequence.
445 						// Indexed by N(S).
446 
447 	int magic2;				// Look out for out of bounds for above.
448 #define MAGIC2 0x02221201
449 
450 
451 
452 // "Management Data Link"  (MDL) state machine for XID exchange.
453 
454 
455 	enum mdl_state_e { mdl_state_0_ready=0, mdl_state_1_negotiating=1 } mdl_state;
456 
457 	int mdl_rc;				// Retry count, waiting to get XID response.
458 						// The spec has provision for a separate maximum, NM201, but we
459 						// just use the regular N2 same as other retries.
460 
461 	double tm201_exp;			// Timer.  Similar to T1.
462 						// The spec mentions a separate timeout value but
463 						// we will just use the same as T1.
464 
465 	double tm201_paused_at;			// Time when it was paused or 0 if not paused.
466 
467 // Segment reassembler.
468 
469 	cdata_t *ra_buff;			// Reassembler buffer.  NULL when in ready state.
470 
471 	int ra_following;			// Most recent number following to predict next expected.
472 
473 
474 } ax25_dlsm_t;
475 
476 
477 /*
478  * List of current state machines for each link.
479  * There is potential many client apps, each with multiple links
480  * connected all at the same time.
481  *
482  * Everything coming thru here should be from a single thread.
483  * The Data Link Queue should serialize all processing.
484  * Therefore, we don't have to worry about critical regions.
485  */
486 
487 static ax25_dlsm_t *list_head = NULL;
488 
489 
490 /*
491  * Registered callsigns for incoming connections.
492  */
493 
494 #define RC_MAGIC 0x08291951
495 
496 typedef struct reg_callsign_s {
497 	char callsign[AX25_MAX_ADDR_LEN];
498 	int chan;
499 	int client;
500 	struct reg_callsign_s *next;
501 	int magic;
502 } reg_callsign_t;
503 
504 static reg_callsign_t *reg_callsign_list = NULL;
505 
506 
507 // Use these, rather than setting variables directly, to make debug out easier.
508 
509 #define SET_VS(n) {	S->vs = (n);								\
510 		    	if (s_debug_variables) {						\
511 			  text_color_set(DW_COLOR_DEBUG);					\
512 		          dw_printf ("V(S) = %d at %s %d\n", S->vs, __func__, __LINE__);	\
513 		        }									\
514 			assert (S->vs >= 0 && S->vs < S->modulo);				\
515 		  }
516 
517 // If other guy acks reception of an I frame, we should never get an REJ or SREJ
518 // asking for it again.  When we update V(A), we should be able to remove the saved
519 // transmitted data, and everything preceding it, from S->txdata_by_ns[].
520 
521 #define SET_VA(n) {	S->va = (n);								\
522 		    	if (s_debug_variables) {						\
523 			  text_color_set(DW_COLOR_DEBUG);					\
524 		          dw_printf ("V(A) = %d at %s %d\n", S->va, __func__, __LINE__);	\
525 		        }									\
526 			assert (S->va >= 0 && S->va < S->modulo);				\
527 	                int x = AX25MODULO(n-1, S->modulo, __FILE__, __func__, __LINE__);	\
528 	                while (S->txdata_by_ns[x] != NULL) {					\
529 	                  cdata_delete (S->txdata_by_ns[x]);					\
530 	                  S->txdata_by_ns[x] = NULL;						\
531 	                  x = AX25MODULO(x-1, S->modulo, __FILE__, __func__, __LINE__);		\
532 	                }									\
533 		  }
534 
535 #define SET_VR(n) {	S->vr = (n);								\
536 		    	if (s_debug_variables) {						\
537 			  text_color_set(DW_COLOR_DEBUG);					\
538 		          dw_printf ("V(R) = %d at %s %d\n", S->vr, __func__, __LINE__);	\
539 		        }									\
540 			assert (S->vr >= 0 && S->vr < S->modulo);				\
541 		  }
542 
543 #define SET_RC(n) {	S->rc = (n);								\
544 	                if (s_debug_variables) {						\
545 			  text_color_set(DW_COLOR_DEBUG);					\
546 		          dw_printf ("rc = %d at %s %d, state = %d\n", S->rc, __func__, __LINE__, S->state);		\
547 		        }									\
548 		  }
549 
550 
551 //TODO:  Make this a macro so we can simplify calls yet keep debug output if something goes wrong.
552 
553 #if 0
554 #define AX25MODULO(n) ax25modulo((n), S->modulo, __FILE__, __func__, __LINE__)
555 static int ax25modulo(int n, int m, const char *file, const char *func, int line)
556 #else
AX25MODULO(int n,int m,const char * file,const char * func,int line)557 static int AX25MODULO(int n, int m, const char *file, const char *func, int line)
558 #endif
559 {
560 	if (m != 8 && m != 128) {
561 	  text_color_set(DW_COLOR_ERROR);
562 	  dw_printf ("INTERNAL ERROR: %d modulo %d, %s, %s, %d\n", n, m, file, func, line);
563 	  m = 8;
564 	}
565 	// Use masking, rather than % operator, so negative numbers are handled properly.
566 	return (n & (m-1));
567 }
568 
569 
570 // Test whether we can send more or if we need to wait
571 // because we have reached 'maxframe' outstanding frames.
572 // Argument must be 'S'.
573 
574 #define WITHIN_WINDOW_SIZE(x) (x->vs != AX25MODULO(x->va + x->k_maxframe, x->modulo, __FILE__, __func__, __LINE__))
575 
576 
577 // Timer macros to provide debug output with location from where they are called.
578 
579 #define START_T1	start_t1(S, __func__, __LINE__)
580 #define IS_T1_RUNNING	is_t1_running(S, __func__, __LINE__)
581 #define STOP_T1		stop_t1(S, __func__, __LINE__)
582 #define PAUSE_T1	pause_t1(S, __func__, __LINE__)
583 #define RESUME_T1	resume_t1(S, __func__, __LINE__)
584 
585 #define START_T3	start_t3(S, __func__, __LINE__)
586 #define STOP_T3		stop_t3(S, __func__, __LINE__)
587 
588 #define START_TM201	start_tm201(S, __func__, __LINE__)
589 #define STOP_TM201	stop_tm201(S, __func__, __LINE__)
590 #define PAUSE_TM201	pause_tm201(S, __func__, __LINE__)
591 #define RESUME_TM201	resume_tm201(S, __func__, __LINE__)
592 
593 
594 static void dl_data_indication (ax25_dlsm_t *S, int pid, char *data, int len);
595 
596 static void i_frame (ax25_dlsm_t *S, cmdres_t cr, int p, int nr, int ns, int pid, char *info_ptr, int info_len);
597 static void i_frame_continued (ax25_dlsm_t *S, int p, int ns, int pid, char *info_ptr, int info_len);
598 static int is_ns_in_window (ax25_dlsm_t *S, int ns);
599 static void send_srej_frames (ax25_dlsm_t *S, int *resend, int count, int allow_f1);
600 static void rr_rnr_frame (ax25_dlsm_t *S, int ready, cmdres_t cr, int pf, int nr);
601 static void rej_frame (ax25_dlsm_t *S, cmdres_t cr, int pf, int nr);
602 static void srej_frame (ax25_dlsm_t *S, cmdres_t cr, int pf, int nr, unsigned char *info_ptr, int info_len);
603 
604 static void sabm_e_frame (ax25_dlsm_t *S, int extended, int p);
605 static void disc_frame (ax25_dlsm_t *S, int f);
606 static void dm_frame (ax25_dlsm_t *S, int f);
607 static void ua_frame (ax25_dlsm_t *S, int f);
608 static void frmr_frame (ax25_dlsm_t *S);
609 static void ui_frame (ax25_dlsm_t *S, cmdres_t cr, int pf);
610 static void xid_frame (ax25_dlsm_t *S, cmdres_t cr, int pf, unsigned char *info_ptr, int info_len);
611 static void test_frame (ax25_dlsm_t *S, cmdres_t cr, int pf, unsigned char *info_ptr, int info_len);
612 
613 static void t1_expiry (ax25_dlsm_t *S);
614 static void t3_expiry (ax25_dlsm_t *S);
615 static void tm201_expiry (ax25_dlsm_t *S);
616 
617 static void nr_error_recovery (ax25_dlsm_t *S);
618 static void clear_exception_conditions (ax25_dlsm_t *S);
619 static void transmit_enquiry (ax25_dlsm_t *S);
620 static void select_t1_value (ax25_dlsm_t *S);
621 static void establish_data_link (ax25_dlsm_t *S);
622 static void set_version_2_0 (ax25_dlsm_t *S);
623 static void set_version_2_2 (ax25_dlsm_t *S);
624 static int  is_good_nr (ax25_dlsm_t *S, int nr);
625 static void i_frame_pop_off_queue (ax25_dlsm_t *S);
626 static void discard_i_queue (ax25_dlsm_t *S);
627 static void invoke_retransmission (ax25_dlsm_t *S, int nr_input);
628 static void check_i_frame_ackd (ax25_dlsm_t *S, int nr);
629 static void check_need_for_response (ax25_dlsm_t *S, ax25_frame_type_t frame_type, cmdres_t cr, int pf);
630 static void enquiry_response (ax25_dlsm_t *S, ax25_frame_type_t frame_type, int f);
631 
632 static void enter_new_state(ax25_dlsm_t *S, enum dlsm_state_e new_state, const char *from_func, int from_line);
633 
634 static void mdl_negotiate_request (ax25_dlsm_t *S);
635 static void initiate_negotiation (ax25_dlsm_t *S, struct xid_param_s *param);
636 static void negotiation_response (ax25_dlsm_t *S, struct xid_param_s *param);
637 static void complete_negotiation (ax25_dlsm_t *S, struct xid_param_s *param);
638 
639 
640 // Use macros above rather than calling these directly.
641 
642 static void start_t1 (ax25_dlsm_t *S, const char *from_func, int from_line);
643 static void stop_t1 (ax25_dlsm_t *S, const char *from_func, int from_line);
644 static int is_t1_running (ax25_dlsm_t *S, const char *from_func, int from_line);
645 static void pause_t1 (ax25_dlsm_t *S, const char *from_func, int from_line);
646 static void resume_t1 (ax25_dlsm_t *S, const char *from_func, int from_line);
647 
648 static void start_t3 (ax25_dlsm_t *S, const char *from_func, int from_line);
649 static void stop_t3 (ax25_dlsm_t *S, const char *from_func, int from_line);
650 
651 static void start_tm201 (ax25_dlsm_t *S, const char *from_func, int from_line);
652 static void stop_tm201 (ax25_dlsm_t *S, const char *from_func, int from_line);
653 static void pause_tm201 (ax25_dlsm_t *S, const char *from_func, int from_line);
654 static void resume_tm201 (ax25_dlsm_t *S, const char *from_func, int from_line);
655 
656 
657 
658 /*
659  * Configuration settings from file or command line.
660  */
661 
662 static struct misc_config_s  *g_misc_config_p;
663 
664 
665 /*-------------------------------------------------------------------
666  *
667  * Name:        ax25_link_init
668  *
669  * Purpose:     Initialize the ax25_link module.
670  *
671  * Inputs:	pconfig		- misc. configuration from config file or command line.
672  *				  Beacon stuff ended up here.
673  *
674  * Outputs:	Remember required information for future use.  That's all.
675  *
676  *--------------------------------------------------------------------*/
677 
ax25_link_init(struct misc_config_s * pconfig)678 void ax25_link_init (struct misc_config_s *pconfig)
679 {
680 
681 /*
682  * Save parameters for later use.
683  */
684 	g_misc_config_p = pconfig;
685 
686 } /* end ax25_link_init */
687 
688 
689 
690 
691 /*------------------------------------------------------------------------------
692  *
693  * Name:	get_link_handle
694  *
695  * Purpose:	Find existing (or possibly create) state machine for a given link.
696  *		It should be possible to have a large number of links active at the
697  *		same time.  They are uniquely identified by
698  *		(owncall, peercall, client id, radio channel)
699  *		Note that we could have multiple client applications, all sharing one
700  *		TNC, on the same or different radio channels, completely unware of each other.
701  *
702  * Inputs:	addrs		- Owncall, peercall, and optional digipeaters.
703  *				  For ease of passing this around, it is an array in the
704  *				  same order as in the frame.
705  *
706  *		num_addr	- Number of addresses, 2 thru 10.
707  *
708  *		chan		- Radio channel number.
709  *
710  *		client		- Client app number.
711  *				  We allow multiple concurrent applications with the
712  *				  AGW network protocol.  These are identified as 0, 1, ...
713  *				  We don't know this for an incoming frame from the radio
714  *				  so it is -1 at this point. At a later time will will
715  *				  associate the stream with the right client.
716  *
717  *		create		- True if OK to create a new one.
718  *				  Otherwise, return only one already existing.
719  *
720  *				  This should always be true for outgoing frames.
721  *				  For incoming frames this would be true only for SABM(e)
722  *				  with all digipeater fields marked as used.
723  *
724  *				  Here, we will also check to see if it is in our
725  *				  registered callsign list.
726  *
727  * Returns:	Handle for data link state machine.
728  *		NULL if not found and 'create' is false.
729  *
730  * Description:	Try to find an existing entry matching owncall, peercall, channel,
731  *		and client.  If not found create a new one.
732  *
733  *------------------------------------------------------------------------------*/
734 
735 static int next_stream_id = 0;
736 
get_link_handle(char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN],int num_addr,int chan,int client,int create)737 static ax25_dlsm_t *get_link_handle (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, int chan, int client, int create)
738 {
739 
740 	ax25_dlsm_t *p;
741 
742 
743 	if (s_debug_link_handle) {
744 	  text_color_set(DW_COLOR_DECODED);
745 	  dw_printf ("get_link_handle (%s>%s, chan=%d, client=%d, create=%d)\n",
746 				addrs[AX25_SOURCE], addrs[AX25_DESTINATION], chan, client, create);
747 	}
748 
749 
750 // Look for existing.
751 
752 	if (client == -1) {				// from the radio.
753 							// address order is reversed for compare.
754 	  for (p = list_head; p != NULL; p = p->next) {
755 
756 	    if (p->chan == chan &&
757 	        strcmp(addrs[AX25_DESTINATION], p->addrs[OWNCALL]) == 0 &&
758 	        strcmp(addrs[AX25_SOURCE], p->addrs[PEERCALL]) == 0) {
759 
760 	      if (s_debug_link_handle) {
761 	        text_color_set(DW_COLOR_DECODED);
762 	        dw_printf ("get_link_handle returns existing stream id %d for incoming.\n", p->stream_id);
763 	      }
764 	      return (p);
765 	    }
766 	  }
767 	}
768 	else {						// from client app
769 	  for (p = list_head; p != NULL; p = p->next) {
770 
771 	    if (p->chan == chan &&
772 	        p->client == client &&
773 	        strcmp(addrs[AX25_SOURCE], p->addrs[OWNCALL]) == 0 &&
774 	        strcmp(addrs[AX25_DESTINATION], p->addrs[PEERCALL]) == 0) {
775 
776 	      if (s_debug_link_handle) {
777 	        text_color_set(DW_COLOR_DECODED);
778 	        dw_printf ("get_link_handle returns existing stream id %d for outgoing.\n", p->stream_id);
779 	      }
780 	      return (p);
781 	    }
782 	  }
783 	}
784 
785 
786 // Could not find existing.  Should we create a new one?
787 
788 	if ( ! create) {
789 	  if (s_debug_link_handle) {
790 	    text_color_set(DW_COLOR_DECODED);
791 	    dw_printf ("get_link_handle: Search failed. Do not create new.\n");
792 	  }
793 	  return (NULL);
794 	}
795 
796 
797 // If it came from the radio, search for destination our registered callsign list.
798 
799 	int incoming_for_client = -1;		// which client app registered the callsign?
800 
801 
802 	if (client == -1) {				// from the radio.
803 
804 	  reg_callsign_t *r, *found;
805 
806 	  found = NULL;
807 	  for (r = reg_callsign_list; r != NULL && found == NULL; r = r->next) {
808 
809 	    if (strcmp(addrs[AX25_DESTINATION], r->callsign) == 0 && chan == r->chan) {
810 	      found = r;
811 	      incoming_for_client = r->client;
812 	    }
813 	  }
814 
815 	  if (found == NULL) {
816 	    if (s_debug_link_handle) {
817 	      text_color_set(DW_COLOR_DECODED);
818 	      dw_printf ("get_link_handle: not for me.  Ignore it.\n");
819 	    }
820 	    return (NULL);
821 	  }
822 	}
823 
824 // Create new data link state machine.
825 
826 	p = calloc (sizeof(ax25_dlsm_t), 1);
827 	p->magic1 = MAGIC1;
828 	p->start_time = dtime_now();
829 	p->stream_id = next_stream_id++;
830 	p->modulo = 8;
831 
832 	p->chan = chan;
833 	p->num_addr = num_addr;
834 
835 // If it came in over the radio, we need to swap source/destination and reverse any digi path.
836 
837 	if (incoming_for_client >= 0) {
838 	  strlcpy (p->addrs[AX25_SOURCE],      addrs[AX25_DESTINATION], sizeof(p->addrs[AX25_SOURCE]));
839 	  strlcpy (p->addrs[AX25_DESTINATION], addrs[AX25_SOURCE],      sizeof(p->addrs[AX25_DESTINATION]));
840 
841 	  int j = AX25_REPEATER_1;
842 	  int k = num_addr - 1;
843 	  while (k >= AX25_REPEATER_1) {
844 	    strlcpy (p->addrs[j],      addrs[k], sizeof(p->addrs[j]));
845 	    j++;
846 	    k--;
847 	  }
848 
849 	  p->client = incoming_for_client;
850 	}
851 	else {
852 	  memcpy (p->addrs, addrs, sizeof(p->addrs));
853 	  p->client = client;
854 	}
855 
856 	p->state = state_0_disconnected;
857 	p->t1_remaining_when_last_stopped = -999;		// Invalid, don't use.
858 
859 	p->magic2 = MAGIC2;
860 	p->magic3 = MAGIC3;
861 
862 	// No need for critical region because this should all be in one thread.
863 	p->next = list_head;
864 	list_head = p;
865 
866 	if (s_debug_link_handle) {
867 	  text_color_set(DW_COLOR_DECODED);
868 	  dw_printf ("get_link_handle returns NEW stream id %d\n", p->stream_id);
869 	}
870 
871 	return (p);
872 }
873 
874 
875 
876 
877 
878 
879 //###################################################################################
880 //###################################################################################
881 //
882 //  Data Link state machine for sending data in connected mode.
883 //
884 //	Incoming:
885 //
886 //		Requests from the client application.  Set s_debug_client_app for debugging.
887 //
888 //			dl_connect_request
889 //			dl_disconnect_request
890 //			dl_outstanding_frames_request	- (mine) Ask about outgoing queue for a link.
891 //			dl_data_request			- send connected data
892 //			dl_unit_data_request		- not implemented.  APRS & KISS bypass this
893 //			dl_flow_off			- not implemented.  Not in AGW API.
894 //			dl_flow_on			- not implemented.  Not in AGW API.
895 // 			dl_register_callsign		- Register callsigns(s) for incoming connection requests.
896 // 			dl_unregister_callsign		- Unregister callsigns(s) ...
897 //			dl_client_cleanup		- Clean up after client which has disappeared.
898 //
899 //		Stuff from the radio channel.  Set s_debug_radio for debugging.
900 //
901 //			lm_data_indication		- Received frame.
902 //			lm_channel_busy			- Change in PTT or DCD.
903 //			lm_seize_confirm		- We have started to transmit.
904 //
905 //		Timer expiration.  Set s_debug_timers for debugging.
906 //
907 //			dl_timer_expiry
908 //
909 //	Outgoing:
910 //
911 //		To the client application:
912 //
913 //			dl_data_indication		- received connected data.
914 //
915 //		To the transmitter:
916 //
917 //			lm_data_request			- Queue up a frame for transmission.
918 //
919 //			lm_seize_request		- Start transmitter when possible.
920 //							  lm_seize_confirm will be called when it has.
921 //
922 //
923 //  It is important that all requests come thru the data link queue so
924 //  everything is serialized.
925 //  We don't have to worry about being reentrant or critical regions.
926 //  Nothing here should consume a significant amount of time.
927 //  i.e. There should be no sleep delay or anything that would block waiting on someone else.
928 //
929 //###################################################################################
930 //###################################################################################
931 
932 
933 
934 /*------------------------------------------------------------------------------
935  *
936  * Name:	dl_connect_request
937  *
938  * Purpose:	Client app wants to connect to another station.
939  *
940  * Inputs:	E	- Event from the queue.
941  *			  The caller will free it.
942  *
943  * Description:
944  *
945  *------------------------------------------------------------------------------*/
946 
dl_connect_request(dlq_item_t * E)947 void dl_connect_request (dlq_item_t *E)
948 {
949 	ax25_dlsm_t *S;
950 	int ok_to_create = 1;
951 	int old_version;
952 	int n;
953 
954 	if (s_debug_client_app) {
955 	  text_color_set(DW_COLOR_DEBUG);
956 	  dw_printf ("dl_connect_request ()\n");
957 	}
958 
959 	text_color_set(DW_COLOR_INFO);
960 	dw_printf ("Attempting connect to %s ...\n", E->addrs[PEERCALL]);
961 
962 	S = get_link_handle (E->addrs, E->num_addr, E->chan, E->client, ok_to_create);
963 
964 	switch (S->state) {
965 
966 	  case 	state_0_disconnected:
967 
968 	    INIT_T1V_SRT;
969 
970 // See if destination station is in list for v2.0 only.
971 
972 	    old_version = 0;
973 	    for (n = 0; n < g_misc_config_p->v20_count && ! old_version; n++) {
974 	      if (strcmp(E->addrs[AX25_DESTINATION],g_misc_config_p->v20_addrs[n]) == 0) {
975 	        old_version = 1;
976 	      }
977 	    }
978 
979 	    if (old_version || g_misc_config_p->maxv22 == 0) {		// Don't attempt v2.2.
980 
981 	      set_version_2_0 (S);
982 
983 	      establish_data_link (S);
984 	      S->layer_3_initiated = 1;
985 	      enter_new_state (S, state_1_awaiting_connection, __func__, __LINE__);
986 	    }
987 	    else {					// Try v2.2 first, then fall back if appropriate.
988 
989 	      set_version_2_2 (S);
990 
991 	      establish_data_link (S);
992 	      S->layer_3_initiated = 1;
993 	      enter_new_state (S, state_5_awaiting_v22_connection, __func__, __LINE__);
994 	    }
995 	    break;
996 
997 	  case 	state_1_awaiting_connection:
998 	  case 	state_5_awaiting_v22_connection:
999 
1000 	    discard_i_queue(S);
1001 	    S->layer_3_initiated = 1;
1002 	    // Keep current state.
1003 	    break;
1004 
1005 	  case 	state_2_awaiting_release:
1006 
1007 	    // Keep current state.
1008 	    break;
1009 
1010 	  case 	state_3_connected:
1011 	  case 	state_4_timer_recovery:
1012 
1013 	    discard_i_queue(S);
1014 	    establish_data_link(S);
1015 	    S->layer_3_initiated = 1;
1016 	    // My enhancement.  Original always sent SABM and went to state 1.
1017 	    // If we were using v2.2, why not reestablish with that?
1018 	    enter_new_state (S, S->modulo == 128 ? state_5_awaiting_v22_connection : state_1_awaiting_connection, __func__, __LINE__);
1019 	    break;
1020 	}
1021 
1022 } /* end dl_connect_request */
1023 
1024 
1025 /*------------------------------------------------------------------------------
1026  *
1027  * Name:	dl_disconnect_request
1028  *
1029  * Purpose:	Client app wants to terminate connection with another station.
1030  *
1031  * Inputs:	E	- Event from the queue.
1032  *			  The caller will free it.
1033  *
1034  * Outputs:
1035  *
1036  * Description:
1037  *
1038  *------------------------------------------------------------------------------*/
1039 
dl_disconnect_request(dlq_item_t * E)1040 void dl_disconnect_request (dlq_item_t *E)
1041 {
1042 	ax25_dlsm_t *S;
1043 	int ok_to_create = 1;
1044 
1045 
1046 	if (s_debug_client_app) {
1047 	  text_color_set(DW_COLOR_DEBUG);
1048 	  dw_printf ("dl_disconnect_request ()\n");
1049 	}
1050 
1051 	text_color_set(DW_COLOR_INFO);
1052 	dw_printf ("Disconnect from %s ...\n", E->addrs[PEERCALL]);
1053 
1054 	S = get_link_handle (E->addrs, E->num_addr, E->chan, E->client, ok_to_create);
1055 
1056 	switch (S->state) {
1057 
1058 	  case 	state_0_disconnected:
1059 
1060 	    // DL-DISCONNECT *confirm*
1061 	    text_color_set(DW_COLOR_INFO);
1062 	    dw_printf ("Stream %d: Disconnected from %s.\n", S->stream_id, S->addrs[PEERCALL]);
1063 	    server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
1064 	    break;
1065 
1066 	  case 	state_1_awaiting_connection:
1067 	  case 	state_5_awaiting_v22_connection:
1068 
1069 // TODO: "requeue."  Not sure what to do here.
1070 // If we put it back in the queue we will get it back again probably still in same state.
1071 // Need a way to defer it until the next state change.
1072 
1073 	    break;
1074 
1075 	  case 	state_2_awaiting_release:
1076 	    {
1077 	      // We have previously started the disconnect sequence and are waiting
1078 	      // for a UA from the other guy.  Meanwhile, the application got
1079 	      // impatient and sent us another disconnect request.  What should
1080 	      // we do?  Ignore it and let the disconnect sequence run its
1081 	      // course?  Or should we complete the sequence without waiting
1082 	      // for the other guy to ack?
1083 
1084 	      // Erratum.  Flow chart simply says "DM (expedited)."
1085 	      // This is the only place we have expedited.  Is this correct?
1086 
1087 	      cmdres_t cr = cr_res;	// DM can only be response.
1088 	      int p = 0;
1089 	      int nopid = 0;		// PID applies only to I and UI frames.
1090 
1091 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, cr, frame_type_U_DM, p, nopid, NULL, 0);
1092 	      lm_data_request (S->chan, TQ_PRIO_0_HI, pp);	// HI means expedited.
1093 
1094 	      // Erratum: Shouldn't we inform the user when going to disconnected state?
1095 	      // Notifying the application, here, is my own enhancement.
1096 
1097 	      text_color_set(DW_COLOR_INFO);
1098 	      dw_printf ("Stream %d: Disconnected from %s.\n", S->stream_id, S->addrs[PEERCALL]);
1099 	      server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
1100 
1101 	      STOP_T1;
1102 	      enter_new_state (S, state_0_disconnected, __func__, __LINE__);
1103 	    }
1104 	    break;
1105 
1106 	  case 	state_3_connected:
1107 	  case 	state_4_timer_recovery:
1108 
1109 	    discard_i_queue (S);
1110 	    SET_RC(0);			// I think this should be 1 but I'm not that worried about it.
1111 
1112 	    cmdres_t cmd = cr_cmd;
1113 	    int p = 1;
1114 	    int nopid = 0;
1115 
1116 	    packet_t pp = ax25_u_frame (S->addrs, S->num_addr, cmd, frame_type_U_DISC, p, nopid, NULL, 0);
1117 	    lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
1118 
1119 	    STOP_T3;
1120 	    START_T1;
1121 	    enter_new_state (S, state_2_awaiting_release, __func__, __LINE__);
1122 
1123 	    break;
1124 	}
1125 
1126 } /* end dl_disconnect_request */
1127 
1128 
1129 /*------------------------------------------------------------------------------
1130  *
1131  * Name:	dl_data_request
1132  *
1133  * Purpose:	Client app wants to send data to another station.
1134  *
1135  * Inputs:	E	- Event from the queue.
1136  *			  The caller will free it.
1137  *
1138  * Description:	Append the transmit data block to the I frame queue for later processing.
1139  *
1140  *		We also perform the segmentation handling here.
1141  *
1142  *		C6.1 Segmenter State Machine
1143  *		Only the following DL primitives will be candidates for modification by the segmented
1144  *		state machine:
1145 
1146  *		* DL-DATA Request. The user employs this primitive to provide information to be
1147  *		transmitted using connection-oriented procedures; i.e., using I frames. The
1148  *		segmenter state machine examines the quantity of data to be transmitted. If the
1149  *		quantity of data to be transmitted is less than or equal to the data link parameter
1150  *		N1, the segmenter state machine passes the primitive through transparently. If the
1151  *		quantity of data to be transmitted exceeds the data link parameter N1, the
1152  *		segmenter chops up the data into segments of length N1-2 octets. Each segment is
1153  *		prepended with a two octet header. (See Figures 3.1 and 3.2.) The segments are
1154  *		then turned over to the Data-link State Machine for transmission, using multiple DL
1155  *		Data Request primitives. All segments are turned over immediately; therefore the
1156  *		Data-link State Machine will transmit them consecutively on the data link.
1157  *
1158  * Erratum:	Not sure how to interpret that.  See example below for how it was implemented.
1159  *
1160  * Version 1.6:	Bug 252.  Segmentation was occuring for a V2.0 link.  From the spec:
1161  *			"The receipt of an XID response from the other station establishes that both
1162  *			stations are using AX.25 version 2.2 or higher and enables the use of the
1163  *			segmenter/reassembler and selective reject."
1164  *			"The segmenter/reassembler procedure is only enabled if both stations on the
1165  *			link are using AX.25 version 2.2 or higher."
1166  *
1167  *		The Segmenter Ready State SDL has no decision based on protocol version.
1168  *
1169  *------------------------------------------------------------------------------*/
1170 
1171 static void data_request_good_size (ax25_dlsm_t *S, cdata_t *txdata);
1172 
1173 
dl_data_request(dlq_item_t * E)1174 void dl_data_request (dlq_item_t *E)
1175 {
1176 	ax25_dlsm_t *S;
1177 	int ok_to_create = 1;
1178 
1179 
1180 	S = get_link_handle (E->addrs, E->num_addr, E->chan, E->client, ok_to_create);
1181 
1182 	if (s_debug_client_app) {
1183 	  text_color_set(DW_COLOR_DEBUG);
1184 	  dw_printf ("dl_data_request (\"");
1185 	  ax25_safe_print (E->txdata->data, E->txdata->len, 1);
1186 	  dw_printf ("\") state=%d\n", S->state);
1187 	}
1188 
1189 	if (E->txdata->len <= S->n1_paclen) {
1190 	  data_request_good_size (S, E->txdata);
1191 	  E->txdata = NULL;	// Now part of transmit I frame queue.
1192 	  return;
1193 	}
1194 
1195 #define DIVROUNDUP(a,b) (((a)+(b)-1) / (b))
1196 
1197 // Erratum: Don't do V2.2 segmentation for a V2.0 link.
1198 // In this case, we can just split it into multiple frames not exceeding the specified max size.
1199 // Hopefully the receiving end treats it like a stream and doesn't care about length of each frame.
1200 
1201 	if (S->modulo == 8) {
1202 
1203 	  int num_frames = 0;
1204 	  int remaining_len = E->txdata->len;
1205 	  int offset = 0;
1206 
1207 	  while (remaining_len > 0) {
1208 	    int this_len = MIN(remaining_len, S->n1_paclen);
1209 
1210 	    cdata_t *new_txdata = cdata_new(E->txdata->pid, E->txdata->data + offset, this_len);
1211 	    data_request_good_size (S, new_txdata);
1212 
1213 	    offset += this_len;
1214 	    remaining_len -= this_len;
1215 	    num_frames++;
1216 	  }
1217 
1218 	  if (num_frames != DIVROUNDUP(E->txdata->len, S->n1_paclen) || remaining_len != 0) {
1219 	    text_color_set(DW_COLOR_ERROR);
1220 	    dw_printf ("INTERNAL ERROR, Segmentation line %d, data length = %d, N1 = %d, num frames = %d, remaining len = %d\n",
1221 					__LINE__, E->txdata->len, S->n1_paclen, num_frames, remaining_len);
1222 	  }
1223 	  cdata_delete (E->txdata);
1224 	  E->txdata = NULL;
1225 	  return;
1226 	}
1227 
1228 // More interesting case.
1229 // It is too large to fit in one frame so we segment it.
1230 
1231 // As an example, suppose we had 6 bytes of data "ABCDEF".
1232 
1233 // If N1 >= 6, it would be sent normally.
1234 
1235 //	(addresses)
1236 //	(control bytes)
1237 //	PID, typically 0xF0
1238 //	'A'	- first byte of information field
1239 //	'B'
1240 //	'C'
1241 //	'D'
1242 //	'E'
1243 //	'F'
1244 
1245 // Now consider the case where it would not fit.
1246 // We would change the PID to 0x08 meaning a segment.
1247 // The information part is the segment identifier of this format:
1248 //
1249 //	x xxxxxxx
1250 //	| ---+---
1251 //	|    |
1252 //	|    +- Number of additional segments to follow.
1253 //	|
1254 //	+- '1' means it is the first segment.
1255 
1256 // If N1 = 4, it would be split up like this:
1257 
1258 //	(addresses)
1259 //	(control bytes)
1260 //	PID = 0x08	means segment
1261 //	0x82	- Start of info field.
1262 //		  MSB set indicates FIRST segment.
1263 //		  2, in lower 7 bits, means 2 more segments to follow.
1264 //	0xF0	- original PID, typical value.
1265 //	'A'	- For the FIRST segment, we have PID and N1-2 data bytes.
1266 //	'B'
1267 
1268 //	(addresses)
1269 //	(control bytes)
1270 //	PID = 0x08	means segment
1271 //	0x01	- Means 1 more segment follows.
1272 //	'C'	- For subsequent (not first) segments, we have up to N1-1 data bytes.
1273 //	'D'
1274 //	'E'
1275 
1276 //	(addresses)
1277 //	(control bytes)
1278 //	PID = 0x08
1279 //	0x00 - 0 means no more to follow.  i.e.  This is the last.
1280 //	'E'
1281 
1282 
1283 // Number of segments is ceiling( (datalen + 1 ) / (N1 - 1))
1284 
1285 // we add one to datalen for the original PID.
1286 // We subtract one from N1 for the segment identifier header.
1287 
1288 #define DIVROUNDUP(a,b) (((a)+(b)-1) / (b))
1289 
1290 // Compute number of segments.
1291 // We will decrement this before putting it in the frame so the first
1292 // will have one less than this number.
1293 
1294 	int nseg_to_follow = DIVROUNDUP(E->txdata->len + 1, S->n1_paclen - 1);
1295 
1296 	if (nseg_to_follow < 2 || nseg_to_follow > 128) {
1297 	  text_color_set(DW_COLOR_ERROR);
1298 	  dw_printf ("INTERNAL ERROR, Segmentation line %d, data length = %d, N1 = %d, number of segments = %d\n",
1299 					__LINE__, E->txdata->len, S->n1_paclen, nseg_to_follow);
1300 	  cdata_delete (E->txdata);
1301 	  E->txdata = NULL;
1302 	  return;
1303 	}
1304 
1305 	int orig_offset = 0;
1306 	int remaining_len = E->txdata->len;
1307 
1308 // First segment.
1309 
1310 	int seglen;
1311 	struct {
1312 	  char header;		// 0x80 + number of segments to follow.
1313 	  char original_pid;
1314 	  char segdata[AX25_N1_PACLEN_MAX];
1315 	} first_segment;
1316 	cdata_t *new_txdata;
1317 
1318 	nseg_to_follow--;
1319 
1320 	first_segment.header = 0x80 | nseg_to_follow;
1321 	first_segment.original_pid = E->txdata->pid;
1322 	seglen = MIN(S->n1_paclen - 2, remaining_len);
1323 
1324 	if (seglen < 1 || seglen > S->n1_paclen - 2 || seglen > remaining_len || seglen > (int)(sizeof(first_segment.segdata))) {
1325 	  text_color_set(DW_COLOR_ERROR);
1326 	  dw_printf ("INTERNAL ERROR, Segmentation line %d, data length = %d, N1 = %d, segment length = %d, number to follow = %d\n",
1327 					__LINE__, E->txdata->len, S->n1_paclen, seglen, nseg_to_follow);
1328 	  cdata_delete (E->txdata);
1329 	  E->txdata = NULL;
1330 	  return;
1331 	}
1332 
1333 	memcpy (first_segment.segdata, E->txdata->data + orig_offset, seglen);
1334 
1335 	new_txdata = cdata_new(AX25_PID_SEGMENTATION_FRAGMENT, (char*)(&first_segment), seglen+2);
1336 
1337 	data_request_good_size (S, new_txdata);
1338 
1339 	orig_offset += seglen;
1340 	remaining_len -= seglen;
1341 
1342 
1343 // Subsequent segments.
1344 
1345 	do {
1346 	  struct {
1347 	    char header;		// Number of segments to follow.
1348 	    char segdata[AX25_N1_PACLEN_MAX];
1349 	  } subsequent_segment;
1350 
1351 	  nseg_to_follow--;
1352 
1353 	  subsequent_segment.header = nseg_to_follow;
1354 	  seglen = MIN(S->n1_paclen - 1, remaining_len);
1355 
1356 	  if (seglen < 1 || seglen > S->n1_paclen - 1 || seglen > remaining_len || seglen > (int)(sizeof(subsequent_segment.segdata))) {
1357 	    text_color_set(DW_COLOR_ERROR);
1358 	    dw_printf ("INTERNAL ERROR, Segmentation line %d, data length = %d, N1 = %d, segment length = %d, number to follow = %d\n",
1359 					__LINE__, E->txdata->len, S->n1_paclen, seglen, nseg_to_follow);
1360 	    cdata_delete (E->txdata);
1361 	    E->txdata = NULL;
1362 	    return;
1363 	  }
1364 
1365 	  memcpy (subsequent_segment.segdata, E->txdata->data + orig_offset, seglen);
1366 
1367 	  new_txdata = cdata_new(AX25_PID_SEGMENTATION_FRAGMENT, (char*)(&subsequent_segment), seglen+1);
1368 
1369 	  data_request_good_size (S, new_txdata);
1370 
1371 	  orig_offset += seglen;
1372 	  remaining_len -= seglen;
1373 
1374 	} while (nseg_to_follow > 0);
1375 
1376 	if (remaining_len != 0 || orig_offset != E->txdata->len) {
1377 	  text_color_set(DW_COLOR_ERROR);
1378 	  dw_printf ("INTERNAL ERROR, Segmentation line %d, data length = %d, N1 = %d, remaining length = %d (not 0), orig offset = %d (not %d)\n",
1379 					__LINE__, E->txdata->len, S->n1_paclen, remaining_len, orig_offset, E->txdata->len);
1380 	}
1381 
1382 	cdata_delete (E->txdata);
1383 	E->txdata = NULL;
1384 
1385 } /* end dl_data_request */
1386 
1387 
data_request_good_size(ax25_dlsm_t * S,cdata_t * txdata)1388 static void data_request_good_size (ax25_dlsm_t *S, cdata_t *txdata)
1389 {
1390 	switch (S->state) {
1391 
1392 	  case 	state_0_disconnected:
1393 	  case 	state_2_awaiting_release:
1394 /*
1395  * Discard it.
1396  */
1397 	    cdata_delete (txdata);
1398 	    break;
1399 
1400 	  case 	state_1_awaiting_connection:
1401 	  case 	state_5_awaiting_v22_connection:
1402 /*
1403  * Erratum?
1404  * The flow chart shows "push on I frame queue" if layer 3 initiated
1405  * is NOT set.  This seems backwards but I don't understand enough yet
1406  * to make a compelling argument that it is wrong.
1407  * Implemented as in flow chart.
1408  * TODO: Get better understanding of what'layer_3_initiated' means.
1409  */
1410 	    if (S->layer_3_initiated) {
1411 	      cdata_delete (txdata);
1412 	      break;
1413 	    }
1414 	    // otherwise fall thru.
1415 
1416 	  case 	state_3_connected:
1417 	  case 	state_4_timer_recovery:
1418 /*
1419  * "push on I frame queue"
1420  * Append to the end would have been a better description because push implies a stack.
1421  */
1422 
1423 	    if (S->i_frame_queue == NULL) {
1424 	      txdata->next = NULL;
1425 	      S->i_frame_queue = txdata;
1426 	    }
1427 	    else {
1428 	      cdata_t *plast = S->i_frame_queue;
1429 	      while (plast->next != NULL) {
1430 	        plast = plast->next;
1431 	      }
1432 	      txdata->next = NULL;
1433 	      plast->next = txdata;
1434 	    }
1435 	    break;
1436 	}
1437 
1438 	// v1.5 change in strategy.
1439 	// New I frames, not sent yet, are delayed until after processing anything in the received transmission.
1440 	// Give the transmit process a kick unless other side is busy or we have reached our window size.
1441 	// Previously we had i_frame_pop_off_queue here which would start sending new stuff before we
1442 	// finished dealing with stuff already in progress.
1443 
1444 	switch (S->state) {
1445 
1446 	  case 	state_3_connected:
1447 	  case 	state_4_timer_recovery:
1448 
1449 	    if ( ( ! S->peer_receiver_busy ) &&
1450 	            WITHIN_WINDOW_SIZE(S) ) {
1451 	      S->acknowledge_pending = 1;
1452 	      lm_seize_request (S->chan);
1453 	    }
1454 	    break;
1455 
1456 	  default:
1457 	    break;
1458 	}
1459 
1460 } /* end data_request_good_size */
1461 
1462 
1463 /*------------------------------------------------------------------------------
1464  *
1465  * Name:	dl_register_callsign
1466  *		dl_unregister_callsign
1467  *
1468  * Purpose:	Register / Unregister callsigns that we will accept connections for.
1469  *
1470  * Inputs:	E	- Event from the queue.
1471  *			  The caller will free it.
1472  *
1473  * Outputs:	New item is pushed on the head of the reg_callsign_list.
1474  *		We don't bother checking for duplicates so the most recent wins.
1475  *
1476  * Description:	The data link state machine does not use MYCALL from the APRS configuration.
1477  *		For outgoing frames, the client supplies the source callsign.
1478  *		For incoming connection requests, we need to know what address(es) to respond to.
1479  *
1480  *		Note that one client application can register multiple callsigns for
1481  *		multiple channels.
1482  *		Different clients can register different different addresses on the same channel.
1483  *
1484  *------------------------------------------------------------------------------*/
1485 
dl_register_callsign(dlq_item_t * E)1486 void dl_register_callsign (dlq_item_t *E)
1487 {
1488 	reg_callsign_t *r;
1489 
1490 	if (s_debug_client_app) {
1491 	  text_color_set(DW_COLOR_DEBUG);
1492 	  dw_printf ("dl_register_callsign (%s, chan=%d, client=%d)\n", E->addrs[0], E->chan, E->client);
1493 	}
1494 
1495 	r = calloc(sizeof(reg_callsign_t),1);
1496 	strlcpy (r->callsign, E->addrs[0], sizeof(r->callsign));
1497 	r->chan = E->chan;
1498 	r->client = E->client;
1499 	r->next = reg_callsign_list;
1500 	r->magic = RC_MAGIC;
1501 
1502 	reg_callsign_list = r;
1503 
1504 } /* end dl_register_callsign */
1505 
1506 
dl_unregister_callsign(dlq_item_t * E)1507 void dl_unregister_callsign (dlq_item_t *E)
1508 {
1509 	reg_callsign_t *r, *prev;
1510 
1511 	if (s_debug_client_app) {
1512 	  text_color_set(DW_COLOR_DEBUG);
1513 	  dw_printf ("dl_unregister_callsign (%s, chan=%d, client=%d)\n", E->addrs[0], E->chan, E->client);
1514 	}
1515 
1516 	prev = NULL;
1517 	r = reg_callsign_list;
1518 	while (r != NULL) {
1519 
1520 	  assert (r->magic == RC_MAGIC);
1521 
1522 	  if (strcmp(r->callsign,E->addrs[0]) == 0 && r->chan == E->chan && r->client == E->client) {
1523 
1524 	    if (r == reg_callsign_list) {
1525 
1526 	      reg_callsign_list = r->next;
1527 	      memset (r, 0, sizeof(reg_callsign_t));
1528 	      free (r);
1529 	      r = reg_callsign_list;
1530 	    }
1531 	    else {
1532 
1533 	      prev->next = r->next;
1534 	      memset (r, 0, sizeof(reg_callsign_t));
1535 	      free (r);
1536 	      r = prev->next;
1537 	    }
1538 	  }
1539 	  else {
1540 	    prev = r;
1541 	    r = r->next;
1542 	  }
1543 	}
1544 
1545 } /* end dl_unregister_callsign */
1546 
1547 
1548 
1549 /*------------------------------------------------------------------------------
1550  *
1551  * Name:	dl_outstanding_frames_request
1552  *
1553  * Purpose:	Client app wants to know how many frames are still on their way
1554  *		to other station.  This is handy for flow control.  We would like
1555  *		to keep the pipeline filled sufficiently to take advantage of a
1556  *		large window size (MAXFRAMES).  It is also good to know that the
1557  *		the last packet sent was actually received before we commence
1558  *		the disconnect.
1559  *
1560  * Inputs:	E	- Event from the queue.
1561  *			  The caller will free it.
1562  *
1563  * Outputs:	This gets back to the AGW server which sends the 'Y' reply.
1564  *
1565  * Description:	This is the sum of:
1566  *		- Incoming connected data, from application still in the queue.
1567  *		- I frames which have been transmitted but not yet acknowleged.
1568  *
1569  *------------------------------------------------------------------------------*/
1570 
dl_outstanding_frames_request(dlq_item_t * E)1571 void dl_outstanding_frames_request (dlq_item_t *E)
1572 {
1573 	ax25_dlsm_t *S;
1574 	int ok_to_create = 0;	// must exist already.
1575 
1576 
1577 	if (s_debug_client_app) {
1578 	  text_color_set(DW_COLOR_DEBUG);
1579 	  dw_printf ("dl_outstanding_frames_request ( to %s )\n", E->addrs[PEERCALL]);
1580 	}
1581 
1582 	S = get_link_handle (E->addrs, E->num_addr, E->chan, E->client, ok_to_create);
1583 
1584 	if (S == NULL) {
1585 	  text_color_set(DW_COLOR_ERROR);
1586 	  dw_printf ("Can't get outstanding frames for %s -> %s, chan %d\n", E->addrs[OWNCALL], E->addrs[PEERCALL], E->chan);
1587 	  server_outstanding_frames_reply (E->chan, E->client, E->addrs[OWNCALL], E->addrs[PEERCALL], 0);
1588 	  return;
1589 	}
1590 
1591 // Add up these
1592 //
1593 //	cdata_t *i_frame_queue;			// Connected data from client which has not been transmitted yet.
1594 //						// Linked list.
1595 //						// The name is misleading because these are just blocks of
1596 //						// data, not "I frames" at this point.  The name comes from
1597 //						// the protocol specification.
1598 //
1599 //	cdata_t *txdata_by_ns[128];		// Data which has already been transmitted.
1600 //						// Indexed by N(S) in case it gets lost and needs to be sent again.
1601 //						// Cleared out when we get ACK for it.
1602 
1603 	int count1 = 0;
1604 	cdata_t *incoming;
1605 	for (incoming = S->i_frame_queue; incoming != NULL; incoming = incoming->next) {
1606 	  count1++;
1607 	}
1608 
1609 	int count2 = 0;
1610 	int k;
1611 	for (k = 0; k < S->modulo; k++) {
1612 	  if (S->txdata_by_ns[k] != NULL) {
1613 	    count2++;
1614 	  }
1615 	}
1616 
1617 	server_outstanding_frames_reply (S->chan, S->client, S->addrs[OWNCALL], S->addrs[PEERCALL], count1 + count2);
1618 
1619 } // end dl_outstanding_frames_request
1620 
1621 
1622 
1623 /*------------------------------------------------------------------------------
1624  *
1625  * Name:	dl_client_cleanup
1626  *
1627  * Purpose:	Client app has gone away.  Clean up any data associated with it.
1628  *
1629  * Inputs:	E	- Event from the queue.
1630  *			  The caller will free it.
1631  *
1632 
1633  * Description:	By client application we mean something that attached with the
1634  *		AGW network protocol.
1635  *
1636  *		Clean out anything related to the specfied client application.
1637  *		This would include state machines and registered callsigns.
1638  *
1639  *------------------------------------------------------------------------------*/
1640 
dl_client_cleanup(dlq_item_t * E)1641 void dl_client_cleanup (dlq_item_t *E)
1642 {
1643 	ax25_dlsm_t *S;
1644 	ax25_dlsm_t *dlprev;
1645 	reg_callsign_t *r, *rcprev;
1646 
1647 
1648 	if (s_debug_client_app) {
1649 	  text_color_set(DW_COLOR_INFO);
1650 	  dw_printf ("dl_client_cleanup (%d)\n", E->client);
1651 	}
1652 
1653 
1654 	dlprev = NULL;
1655 	S = list_head;
1656 	while (S != NULL) {
1657 
1658 	  // Look for corruption or double freeing.
1659 
1660 	  assert (S->magic1 == MAGIC1);
1661 	  assert (S->magic2 == MAGIC2);
1662 	  assert (S->magic3 == MAGIC3);
1663 
1664 	  if (S->client == E->client ) {
1665 
1666 	    int n;
1667 
1668 	    if (s_debug_stats) {
1669 	      text_color_set(DW_COLOR_INFO);
1670 	      dw_printf ("%d  I frames received\n",    S->count_recv_frame_type[frame_type_I]);
1671 
1672 	      dw_printf ("%d  RR frames received\n",   S->count_recv_frame_type[frame_type_S_RR]);
1673 	      dw_printf ("%d  RNR frames received\n",  S->count_recv_frame_type[frame_type_S_RNR]);
1674 	      dw_printf ("%d  REJ frames received\n",  S->count_recv_frame_type[frame_type_S_REJ]);
1675 	      dw_printf ("%d  SREJ frames received\n", S->count_recv_frame_type[frame_type_S_SREJ]);
1676 
1677 	      dw_printf ("%d  SABME frames received\n", S->count_recv_frame_type[frame_type_U_SABME]);
1678 	      dw_printf ("%d  SABM frames received\n",  S->count_recv_frame_type[frame_type_U_SABM]);
1679 	      dw_printf ("%d  DISC frames received\n",  S->count_recv_frame_type[frame_type_U_DISC]);
1680 	      dw_printf ("%d  DM frames received\n",    S->count_recv_frame_type[frame_type_U_DM]);
1681 	      dw_printf ("%d  UA frames received\n",    S->count_recv_frame_type[frame_type_U_UA]);
1682 	      dw_printf ("%d  FRMR frames received\n",  S->count_recv_frame_type[frame_type_U_FRMR]);
1683 	      dw_printf ("%d  UI frames received\n",    S->count_recv_frame_type[frame_type_U_UI]);
1684 	      dw_printf ("%d  XID frames received\n",   S->count_recv_frame_type[frame_type_U_XID]);
1685 	      dw_printf ("%d  TEST frames received\n",  S->count_recv_frame_type[frame_type_U_TEST]);
1686 
1687 	      dw_printf ("%d  peak retry count\n",      S->peak_rc_value);
1688 	    }
1689 
1690 	    if (s_debug_client_app) {
1691 	      text_color_set(DW_COLOR_DEBUG);
1692 	      dw_printf ("dl_client_cleanup: remove %s>%s\n", S->addrs[AX25_SOURCE], S->addrs[AX25_DESTINATION]);
1693 	    }
1694 
1695 	    discard_i_queue (S);
1696 
1697 	    for (n = 0; n < 128; n++) {
1698 	      if (S->txdata_by_ns[n] != NULL) {
1699 	        cdata_delete (S->txdata_by_ns[n]);
1700 	        S->txdata_by_ns[n] = NULL;
1701 	      }
1702 	    }
1703 
1704 	    for (n = 0; n < 128; n++) {
1705 	      if (S->rxdata_by_ns[n] != NULL) {
1706 	        cdata_delete (S->rxdata_by_ns[n]);
1707 	        S->rxdata_by_ns[n] = NULL;
1708 	      }
1709 	    }
1710 
1711 	    if (S->ra_buff != NULL) {
1712 	      cdata_delete (S->ra_buff);
1713 	      S->ra_buff = NULL;
1714 	    }
1715 
1716 	    // Put into disconnected state.
1717 	    // If "connected" indicator (e.g. LED) was on, this will turn it off.
1718 
1719 	    enter_new_state (S, state_0_disconnected, __func__, __LINE__);
1720 
1721 	    // Take S out of list.
1722 
1723 	    S->magic1 = 0;
1724 	    S->magic2 = 0;
1725 	    S->magic3 = 0;
1726 
1727 	    if (S == list_head) {		// first one on list.
1728 
1729 	      list_head = S->next;
1730 	      free (S);
1731 	      S = list_head;
1732 	    }
1733 	    else {				// not the first one.
1734 	      dlprev->next = S->next;
1735 	      free (S);
1736 	      S = dlprev->next;
1737 	    }
1738 	  }
1739 	  else {
1740 	    dlprev = S;
1741 	    S = S->next;
1742 	  }
1743 	}
1744 
1745 /*
1746  * If there are no link state machines (streams) remaining, there should be no txdata items still allocated.
1747  */
1748 	if (list_head == NULL) {
1749 	  cdata_check_leak();
1750 	}
1751 
1752 /*
1753  * Remove registered callsigns for this client.
1754  */
1755 
1756 	rcprev = NULL;
1757 	r = reg_callsign_list;
1758 	while (r != NULL) {
1759 
1760 	  assert (r->magic == RC_MAGIC);
1761 
1762 	  if (r->client == E->client) {
1763 
1764 	    if (r == reg_callsign_list) {
1765 
1766 	      reg_callsign_list = r->next;
1767 	      memset (r, 0, sizeof(reg_callsign_t));
1768 	      free (r);
1769 	      r = reg_callsign_list;
1770 	    }
1771 	    else {
1772 
1773 	      rcprev->next = r->next;
1774 	      memset (r, 0, sizeof(reg_callsign_t));
1775 	      free (r);
1776 	      r = rcprev->next;
1777 	    }
1778 	  }
1779 	  else {
1780 	    rcprev = r;
1781 	    r = r->next;
1782 	  }
1783 	}
1784 
1785 } /* end dl_client_cleanup */
1786 
1787 
1788 
1789 /*------------------------------------------------------------------------------
1790  *
1791  * Name:	dl_data_indication
1792  *
1793  * Purpose:	send connected data to client application.
1794  *
1795  * Inputs:	pid		- Protocol ID.
1796  *
1797  *		data		- Pointer to array of bytes.
1798  *
1799  *		len		- Number of bytes in data.
1800  *
1801  *
1802  * Description:	TODO:  We perform reassembly of segments here if necessary.
1803  *
1804  *------------------------------------------------------------------------------*/
1805 
dl_data_indication(ax25_dlsm_t * S,int pid,char * data,int len)1806 static void dl_data_indication (ax25_dlsm_t *S, int pid, char *data, int len)
1807 {
1808 
1809 
1810 
1811 // Now it gets more interesting. We need to combine segments before passing it along.
1812 
1813 // See example in dl_data_request.
1814 
1815 	if (S->ra_buff == NULL) {
1816 
1817 // Ready state.
1818 
1819 	  if (pid != AX25_PID_SEGMENTATION_FRAGMENT) {
1820 	    server_rec_conn_data (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], pid, data, len);
1821 	    return;
1822 	  }
1823 	  else if (data[0] & 0x80) {
1824 
1825 // Ready state, First segment.
1826 
1827 	    S->ra_following = data[0] & 0x7f;
1828 	    int total = (S->ra_following + 1) * (len - 1) - 1;		// len should be other side's N1
1829 	    S->ra_buff = cdata_new(data[1], NULL, total);
1830 	    S->ra_buff->size = total;	// max that we are expecting.
1831 	    S->ra_buff->len = len - 2;	// how much accumulated so far.
1832 	    memcpy (S->ra_buff->data, data + 2, len - 2);
1833 	  }
1834 	  else {
1835 	    text_color_set(DW_COLOR_ERROR);
1836 	    dw_printf ("Stream %d: AX.25 Reassembler Protocol Error Z: Not first segment in ready state.\n", S->stream_id);
1837 	  }
1838 	}
1839 	else {
1840 
1841 // Reassembling data state
1842 
1843 	  if (pid != AX25_PID_SEGMENTATION_FRAGMENT) {
1844 
1845 	    server_rec_conn_data (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], pid, data, len);
1846 
1847 	    text_color_set(DW_COLOR_ERROR);
1848 	    dw_printf ("Stream %d: AX.25 Reassembler Protocol Error Z: Not segment in reassembling state.\n", S->stream_id);
1849 	    cdata_delete(S->ra_buff);
1850 	    S->ra_buff = NULL;
1851 	    return;
1852 	  }
1853 	  else if (data[0] & 0x80) {
1854 	    text_color_set(DW_COLOR_ERROR);
1855 	    dw_printf ("Stream %d: AX.25 Reassembler Protocol Error Z: First segment in reassembling state.\n", S->stream_id);
1856 	    cdata_delete(S->ra_buff);
1857 	    S->ra_buff = NULL;
1858 	    return;
1859 	  }
1860 	  else if ((data[0] & 0x7f) != S->ra_following - 1) {
1861 	    text_color_set(DW_COLOR_ERROR);
1862 	    dw_printf ("Stream %d: AX.25 Reassembler Protocol Error Z: Segments out of sequence.\n", S->stream_id);
1863 	    cdata_delete(S->ra_buff);
1864 	    S->ra_buff = NULL;
1865 	    return;
1866 	  }
1867 	  else {
1868 
1869 // Reassembling data state, Not first segment.
1870 
1871 	    S->ra_following = data[0] & 0x7f;
1872 	    if (S->ra_buff->len + len - 1 <= S->ra_buff->size) {
1873 	      memcpy (S->ra_buff->data + S->ra_buff->len, data + 1, len - 1);
1874 	      S->ra_buff->len += len - 1;
1875 	    }
1876 	    else {
1877 	      text_color_set(DW_COLOR_ERROR);
1878 	      dw_printf ("Stream %d: AX.25 Reassembler Protocol Error Z: Segments exceed buffer space.\n", S->stream_id);
1879 	      cdata_delete(S->ra_buff);
1880 	      S->ra_buff = NULL;
1881 	      return;
1882 	    }
1883 
1884 	    if (S->ra_following == 0) {
1885 // Last one.
1886 	      server_rec_conn_data (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], S->ra_buff->pid, S->ra_buff->data, S->ra_buff->len);
1887 	      cdata_delete(S->ra_buff);
1888 	      S->ra_buff = NULL;
1889 	    }
1890 	  }
1891 	}
1892 
1893 
1894 } /* end dl_data_indication */
1895 
1896 
1897 
1898 /*------------------------------------------------------------------------------
1899  *
1900  * Name:	lm_channel_busy
1901  *
1902  * Purpose:	Change in DCD or PTT status for channel so we know when it is busy.
1903  *
1904  * Inputs:	E	- Event from the queue.
1905  *
1906  *		E->chan		- Radio channel number.
1907  *
1908  *		E->activity	- OCTYPE_PTT for my transmission start/end.
1909  *				- OCTYPE_DCD if we hear someone else.
1910  *
1911  *		E->status	- 1 for active or 0 for quiet.
1912  *
1913  * Outputs:	S->radio_channel_busy
1914  *
1915  *		T1 & TM201 paused/resumed if running.
1916  *
1917  * Description:	We need to pause the timers when the channel is busy.
1918  *
1919  *------------------------------------------------------------------------------*/
1920 
1921 static int dcd_status[MAX_CHANS];
1922 static int ptt_status[MAX_CHANS];
1923 
lm_channel_busy(dlq_item_t * E)1924 void lm_channel_busy (dlq_item_t *E)
1925 {
1926 	int busy;
1927 
1928 	assert (E->chan >= 0 && E->chan < MAX_CHANS);
1929 	assert (E->activity == OCTYPE_PTT || E->activity == OCTYPE_DCD);
1930 	assert (E->status == 1 || E->status == 0);
1931 
1932 	switch (E->activity) {
1933 
1934 	  case OCTYPE_DCD:
1935 
1936 	    if (s_debug_radio) {
1937 	      text_color_set(DW_COLOR_DEBUG);
1938 	      dw_printf ("lm_channel_busy: DCD chan %d = %d\n", E->chan, E->status);
1939 	    }
1940 
1941 	    dcd_status[E->chan] = E->status;
1942 	    break;
1943 
1944 	  case OCTYPE_PTT:
1945 
1946 	    if (s_debug_radio) {
1947 	      text_color_set(DW_COLOR_DEBUG);
1948 	      dw_printf ("lm_channel_busy: PTT chan %d = %d\n", E->chan, E->status);
1949 	    }
1950 
1951 	    ptt_status[E->chan] = E->status;
1952 	    break;
1953 
1954 	  default:
1955 	    break;
1956 	}
1957 
1958 	busy = dcd_status[E->chan] | ptt_status[E->chan];
1959 
1960 /*
1961  * We know if the given radio channel is busy or not.
1962  * This must be applied to all data link state machines associated with that radio channel.
1963  */
1964 
1965 	ax25_dlsm_t *S;
1966 
1967 	for (S = list_head; S != NULL; S = S->next) {
1968 
1969 	  if (E->chan == S->chan) {
1970 
1971 	    if (busy && ! S->radio_channel_busy) {
1972 	      S->radio_channel_busy = 1;
1973 	      PAUSE_T1;
1974 	      PAUSE_TM201;
1975 	    }
1976 	    else if ( ! busy && S->radio_channel_busy) {
1977 	      S->radio_channel_busy = 0;
1978 	      RESUME_T1;
1979 	      RESUME_TM201;
1980 	    }
1981 	  }
1982 	}
1983 
1984 } /* end lm_channel_busy */
1985 
1986 
1987 
1988 
1989 /*------------------------------------------------------------------------------
1990  *
1991  * Name:	lm_seize_confirm
1992  *
1993  * Purpose:	Notification the the channel is clear.
1994  *
1995  * Description:	C4.2.  This primitive indicates to the Data-link State Machine that
1996  *		the transmission opportunity has arrived.
1997  *
1998  * Version 1.5:	Originally this only invoked inquiry_response to provide an ack if not already
1999  *		taken care of by an earlier frame in this transmission.
2000  *		After noticing the unnecessary I frame duplication and differing N(R) in the same
2001  *		transmission, I came to the conclusion that we should delay sending of new
2002  *		(not resends as a result of rej or srej) frames until after after processing
2003  *		of everything in the incoming transmission.
2004  *		The protocol spec simply has "I frame pops off queue" without any indication about
2005  *		what might trigger this event.
2006  *
2007  *------------------------------------------------------------------------------*/
2008 
lm_seize_confirm(dlq_item_t * E)2009 void lm_seize_confirm (dlq_item_t *E)
2010 {
2011 
2012 	assert (E->chan >= 0 && E->chan < MAX_CHANS);
2013 
2014 	ax25_dlsm_t *S;
2015 
2016 	for (S = list_head; S != NULL; S = S->next) {
2017 
2018 	  if (E->chan == S->chan) {
2019 
2020 
2021 	    switch (S->state) {
2022 
2023 	      case 	state_0_disconnected:
2024 	      case 	state_1_awaiting_connection:
2025 	      case 	state_2_awaiting_release:
2026 	      case 	state_5_awaiting_v22_connection:
2027 
2028 	        break;
2029 
2030 	      case 	state_3_connected:
2031 	      case 	state_4_timer_recovery:
2032 
2033 	        // v1.5 change in strategy.
2034 	        // New I frames, not sent yet, are delayed until after processing anything in the received transmission.
2035 	        // Previously we started sending new frames, from the client app, as soon as they arrived.
2036 	        // Now, we first take care of those in progress before throwing more into the mix.
2037 
2038 	        i_frame_pop_off_queue(S);
2039 
2040 	        // Need an RR if we didn't have I frame send the necessary ack.
2041 
2042 	        if (S->acknowledge_pending) {
2043 	          S->acknowledge_pending = 0;
2044 	          enquiry_response (S, frame_not_AX25, 0);
2045 	        }
2046 
2047 // Implementation difference: The flow chart for state 3 has LM-RELEASE Request here.
2048 // I don't think I need it because the transmitter will turn off
2049 // automatically once the queue is empty.
2050 
2051 // Erratum: The original spec had LM-SEIZE request here, for state 4, which didn't seem right.
2052 // The 2006 revision has LM-RELEASE Request so states 3 & 4 are the same.
2053 
2054 	        break;
2055 	    }
2056 	  }
2057 	}
2058 
2059 } /* lm_seize_confirm */
2060 
2061 
2062 
2063 /*------------------------------------------------------------------------------
2064  *
2065  * Name:	lm_data_indication
2066  *
2067  * Purpose:	We received some sort of frame over the radio.
2068  *
2069  * Inputs:	E	- Event from the queue.
2070  *			  Caller is responsible for freeing it.
2071  *
2072  * Description:	First determine if is of interest to me.  Two cases:
2073  *
2074  *		(1) We already have a link handle for (from-addr, to-addr, channel).
2075  *			This could have been set up by an outgoing connect request.
2076  *
2077  *		(2) It is addressed to one of the registered callsigns.  This would
2078  *			catch the case of incoming connect requests.  The APRS MYCALL
2079  *			is not involved at all.  The attached client app might have
2080  *			much different ideas about what the station is called or
2081  *			aliases it might respond to.
2082  *
2083  *------------------------------------------------------------------------------*/
2084 
lm_data_indication(dlq_item_t * E)2085 void lm_data_indication (dlq_item_t *E)
2086 {
2087 	ax25_frame_type_t ftype;
2088 	char desc[80];
2089 	cmdres_t cr;
2090 	int pf;
2091 	int nr;
2092 	int ns;
2093 	ax25_dlsm_t *S;
2094 	int client_not_applicable = -1;
2095 	int n;
2096 	int any_unused_digi;
2097 
2098 
2099 	if (E->pp == NULL) {
2100 	  text_color_set(DW_COLOR_ERROR);
2101 	  dw_printf ("Internal Error, packet pointer is null.  %s %s %d\n", __FILE__, __func__, __LINE__);
2102 	  return;
2103 	}
2104 
2105 	E->num_addr = ax25_get_num_addr(E->pp);
2106 
2107 // Digipeating is not done here so consider only those with no unused digipeater addresses.
2108 
2109 	any_unused_digi = 0;
2110 
2111 	for (n = AX25_REPEATER_1; n < E->num_addr; n++) {
2112 	  if ( ! ax25_get_h(E->pp, n)) {
2113 	    any_unused_digi = 1;
2114 	  }
2115 	}
2116 
2117 	if (any_unused_digi) {
2118 	  if (s_debug_radio) {
2119 	    text_color_set(DW_COLOR_DEBUG);
2120 	    dw_printf ("lm_data_indication (%d, %s>%s) - ignore due to unused digi address.\n", E->chan, E->addrs[AX25_SOURCE], E->addrs[AX25_DESTINATION]);
2121 	  }
2122 	  return;
2123 	}
2124 
2125 // Copy addresses from frame into event structure.
2126 
2127 	for (n = 0; n < E->num_addr; n++) {
2128 	  ax25_get_addr_with_ssid (E->pp, n, E->addrs[n]);
2129 	}
2130 
2131 	if (s_debug_radio) {
2132 	  text_color_set(DW_COLOR_DEBUG);
2133 	  dw_printf ("lm_data_indication (%d, %s>%s)\n", E->chan, E->addrs[AX25_SOURCE], E->addrs[AX25_DESTINATION]);
2134 	}
2135 
2136 // Look for existing, or possibly create new, link state matching addresses and channel.
2137 
2138 // In most cases, we can ignore the frame if we don't have a corresponding
2139 // data link state machine.  However, we might want to create a new one for SABM or SABME.
2140 // get_link_handle will check to see if the destination matches my address.
2141 
2142 // TODO: This won't work right because we don't know the modulo yet.
2143 // Maybe we should have a shorter form that only returns the frame type.
2144 // That is all we need at this point.
2145 
2146 	ftype = ax25_frame_type (E->pp, &cr, desc, &pf, &nr, &ns);
2147 
2148 	S = get_link_handle (E->addrs, E->num_addr, E->chan, client_not_applicable,
2149 				(ftype == frame_type_U_SABM) | (ftype == frame_type_U_SABME));
2150 
2151 	if (S == NULL) {
2152 	  return;
2153 	}
2154 
2155 /*
2156  * There is not a reliable way to tell if a frame, out of context, has modulo 8 or 128
2157  * sequence numbers.  This needs to be supplied from the data link state machine.
2158  *
2159  * We can't do this until we get the link handle.
2160  */
2161 
2162 	ax25_set_modulo (E->pp, S->modulo);
2163 
2164 /*
2165  * Now we need to use ax25_frame_type again because the previous results, for nr and ns, might be wrong.
2166  */
2167 
2168 	ftype = ax25_frame_type (E->pp, &cr, desc, &pf, &nr, &ns);
2169 
2170 // Gather statistics useful for testing.
2171 
2172 	if (ftype <= frame_not_AX25) {
2173 	  S->count_recv_frame_type[ftype]++;
2174 	}
2175 
2176 	switch (ftype) {
2177 
2178 	  case frame_type_I:
2179 	    if (cr != cr_cmd) {
2180 	      text_color_set(DW_COLOR_ERROR);
2181 	      dw_printf ("Stream %d: AX.25 Protocol Error S: %s must be COMMAND.\n", S->stream_id, desc);
2182 	    }
2183 	    break;
2184 
2185 	  case frame_type_S_RR:
2186 	  case frame_type_S_RNR:
2187 	  case frame_type_S_REJ:
2188 	    if (cr != cr_cmd && cr != cr_res) {
2189 	      text_color_set(DW_COLOR_ERROR);
2190 	      dw_printf ("Stream %d: AX.25 Protocol Error: %s must be COMMAND or RESPONSE.\n", S->stream_id, desc);
2191 	    }
2192 	    break;
2193 
2194 	  case frame_type_U_SABME:
2195 	  case frame_type_U_SABM:
2196 	  case frame_type_U_DISC:
2197 	    if (cr != cr_cmd) {
2198 	      text_color_set(DW_COLOR_ERROR);
2199 	      dw_printf ("Stream %d: AX.25 Protocol Error: %s must be COMMAND.\n", S->stream_id, desc);
2200 	    }
2201 	    break;
2202 
2203 // Erratum: The AX.25 spec is not clear about whether SREJ should be command, response, or both.
2204 // The underlying X.25 spec clearly says it is reponse only.  Let's go with that.
2205 
2206 	  case frame_type_S_SREJ:
2207 	  case frame_type_U_DM:
2208 	  case frame_type_U_UA:
2209 	  case frame_type_U_FRMR:
2210 	    if (cr != cr_res) {
2211 	      text_color_set(DW_COLOR_ERROR);
2212 	      dw_printf ("Stream %d: AX.25 Protocol Error: %s must be RESPONSE.\n", S->stream_id, desc);
2213 	    }
2214 	    break;
2215 
2216 	  case frame_type_U_XID:
2217 	  case frame_type_U_TEST:
2218 	    if (cr != cr_cmd && cr != cr_res) {
2219 	      text_color_set(DW_COLOR_ERROR);
2220 	      dw_printf ("Stream %d: AX.25 Protocol Error: %s must be COMMAND or RESPONSE.\n", S->stream_id, desc);
2221 	    }
2222 	    break;
2223 
2224 	  case frame_type_U_UI:
2225 	    // Don't test at this point in case an APRS frame gets thru.
2226 	    // APRS doesn't specify what to put in the Source and Dest C bits.
2227 	    // In practice we see all 4 possble combinations.
2228 	    // I have an opinion about what would be "correct" (discussed elsewhere)
2229 	    // but in practice no one seems to care.
2230 	    break;
2231 
2232 	  case frame_type_U:
2233 	  case frame_not_AX25:
2234 	    // not expected.
2235 	    break;
2236 	}
2237 
2238 
2239 	switch (ftype) {
2240 
2241 	  case frame_type_I:           // Information
2242 	    {
2243 	      int pid;
2244 	      unsigned char *info_ptr;
2245 	      int info_len;
2246 
2247 	      pid = ax25_get_pid (E->pp);
2248 	      info_len = ax25_get_info (E->pp, &info_ptr);
2249 
2250 	      i_frame (S, cr, pf, nr, ns, pid, (char *)info_ptr, info_len);
2251 	    }
2252 	    break;
2253 
2254 	  case frame_type_S_RR:        // Receive Ready - System Ready To Receive
2255 	    rr_rnr_frame (S, 1, cr, pf, nr);
2256 	    break;
2257 
2258 	  case frame_type_S_RNR:       // Receive Not Ready - TNC Buffer Full
2259 	    rr_rnr_frame (S, 0, cr, pf, nr);
2260 	    break;
2261 
2262 	  case frame_type_S_REJ:       // Reject Frame - Out of Sequence or Duplicate
2263 	    rej_frame (S, cr, pf, nr);
2264 	    break;
2265 
2266 	  case frame_type_S_SREJ:      // Selective Reject - Ask for selective frame(s) repeat
2267 	    {
2268 	      unsigned char *info_ptr;
2269 	      int info_len;
2270 
2271 	      info_len = ax25_get_info (E->pp, &info_ptr);
2272 	      srej_frame (S, cr, pf, nr, info_ptr, info_len);
2273 	    }
2274 	    break;
2275 
2276 	  case frame_type_U_SABME:     // Set Async Balanced Mode, Extended
2277 	    sabm_e_frame (S, 1, pf);
2278 	    break;
2279 
2280 	  case frame_type_U_SABM:      // Set Async Balanced Mode
2281 	    sabm_e_frame (S, 0, pf);
2282 	    break;
2283 
2284 	  case frame_type_U_DISC:      // Disconnect
2285 	    disc_frame (S, pf);
2286 	    break;
2287 
2288 	  case frame_type_U_DM:        // Disconnect Mode
2289 	    dm_frame (S, pf);
2290 	    break;
2291 
2292 	  case frame_type_U_UA:        // Unnumbered Acknowledge
2293 	    ua_frame (S, pf);
2294 	    break;
2295 
2296 	  case frame_type_U_FRMR:      // Frame Reject
2297 	    frmr_frame (S);
2298 	    break;
2299 
2300 	  case frame_type_U_UI:        // Unnumbered Information
2301 	    ui_frame (S, cr, pf);
2302 	    break;
2303 
2304 	  case frame_type_U_XID:       // Exchange Identification
2305 	    {
2306 	      unsigned char *info_ptr;
2307 	      int info_len;
2308 
2309 	      info_len = ax25_get_info (E->pp, &info_ptr);
2310 
2311 	      xid_frame (S, cr, pf, info_ptr, info_len);
2312 	    }
2313 	    break;
2314 
2315 	  case frame_type_U_TEST:      // Test
2316 	    {
2317 	      unsigned char *info_ptr;
2318 	      int info_len;
2319 
2320 	      info_len = ax25_get_info (E->pp, &info_ptr);
2321 
2322 	      test_frame (S, cr, pf, info_ptr, info_len);
2323 	    }
2324 	    break;
2325 
2326 	  case frame_type_U:           // other Unnumbered, not used by AX.25.
2327 	    break;
2328 
2329 	  case frame_not_AX25:         // Could not get control byte from frame.
2330 	    break;
2331 	}
2332 
2333 // An incoming frame might have ack'ed frames we sent or indicated peer is no longer busy.
2334 // Rather than putting this test in many places, where those conditions, may have changed,
2335 // we will try to catch them all on this single path.
2336 // Start transmission if we now have some outgoing data ready to go.
2337 // (Added in 1.5 beta 3 for issue 132.)
2338 
2339 	if ( S->i_frame_queue != NULL &&
2340 		(S->state == state_3_connected || S->state == state_4_timer_recovery) &&
2341 		( ! S->peer_receiver_busy ) &&
2342 		WITHIN_WINDOW_SIZE(S) ) {
2343 
2344 	  //S->acknowledge_pending = 1;
2345 	  lm_seize_request (S->chan);
2346 	}
2347 
2348 } /* end lm_data_indication */
2349 
2350 
2351 
2352 /*------------------------------------------------------------------------------
2353  *
2354  * Name:	i_frame
2355  *
2356  * Purpose:	Process I Frame.
2357  *
2358  * Inputs:	S	- Data Link State Machine.
2359  *		cr	- Command or Response.  We have already issued an error if not command.
2360  *		p	- Poll bit.  Assuming we checked earlier that it was a command.
2361  *			  The meaning is described below.
2362  *		nr	- N(R) from the frame.  Next expected seq. for other end.
2363  *		ns	- N(S) from the frame.  Seq. number of this incoming frame.
2364  *		pid	- protocol id.
2365  *		info_ptr - pointer to information part of frame.
2366  *		info_len - Number of bytes in information part of frame.
2367  *			   Should be in range of 0 thru n1_paclen.
2368  *
2369  * Description:
2370  *		6.4.2. Receiving I Frames
2371  *
2372  *		The reception of I frames that contain zero-length information fields is reported to the next layer; no information
2373  *		field will be transferred.
2374  *
2375  *		6.4.2.1. Not Busy
2376  *
2377  *		If a TNC receives a valid I frame (one with a correct FCS and whose send sequence number equals the
2378  *		receiver's receive state variable) and is not in the busy condition, it accepts the received I frame, increments its
2379  *		receive state variable, and acts in one of the following manners:
2380  *
2381  *		a) If it has an I frame to send, that I frame may be sent with the transmitted N(R) equal to its receive state
2382  *		variable V(R) (thus acknowledging the received frame). Alternately, the TNC may send an RR frame with N(R)
2383  *		equal to V(R), and then send the I frame.
2384  *
2385  *		or b) If there are no outstanding I frames, the receiving TNC sends an RR frame with N(R) equal to V(R). The
2386  *		receiving TNC may wait a small period of time before sending the RR frame to be sure additional I frames are
2387  *		not being transmitted.
2388  *
2389  *		6.4.2.2. Busy
2390  *
2391  *		If the TNC is in a busy condition, it ignores any received I frames without reporting this condition, other than
2392  *		repeating the indication of the busy condition.
2393  *		If a busy condition exists, the TNC receiving the busy condition indication polls the sending TNC periodically
2394  *		until the busy condition disappears.
2395  *		A TNC may poll the busy TNC periodically with RR or RNR frames with the P bit set to "1".
2396  *
2397  *		6.4.6. Receiving Acknowledgement
2398  *
2399  *		Whenever an I or S frame is correctly received, even in a busy condition, the N(R) of the received frame is
2400  *		checked to see if it includes an acknowledgement of outstanding sent I frames. The T1 timer is canceled if the
2401  *		received frame actually acknowledges previously unacknowledged frames. If the T1 timer is canceled and there
2402  *		are still some frames that have been sent that are not acknowledged, T1 is started again. If the T1 timer expires
2403  *		before an acknowledgement is received, the TNC proceeds with the retransmission procedure outlined in Section
2404  *		6.4.11.
2405  *
2406  *
2407  *		6.2. Poll/Final (P/F) Bit Procedures
2408  *
2409  *		The next response frame returned to an I frame with the P bit set to "1", received during the information
2410  *		transfer state, is an RR, RNR or REJ response with the F bit set to "1".
2411  *
2412  *		The next response frame returned to a S or I command frame with the P bit set to "1", received in the
2413  *		disconnected state, is a DM response frame with the F bit set to "1".
2414  *
2415  *------------------------------------------------------------------------------*/
2416 
i_frame(ax25_dlsm_t * S,cmdres_t cr,int p,int nr,int ns,int pid,char * info_ptr,int info_len)2417 static void i_frame (ax25_dlsm_t *S, cmdres_t cr, int p, int nr, int ns, int pid, char *info_ptr, int info_len)
2418 {
2419 	switch (S->state) {
2420 
2421 	  case 	state_0_disconnected:
2422 
2423 	    // Logic from flow chart for "all other commands."
2424 
2425 	    if (cr == cr_cmd) {
2426 	      cmdres_t r = cr_res;	// DM response with F taken from P.
2427 	      int f = p;
2428 	      int nopid = 0;		// PID applies only for I and UI frames.
2429 
2430 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, r, frame_type_U_DM, f, nopid, NULL, 0);
2431 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
2432 	    }
2433 	    break;
2434 
2435 	  case 	state_1_awaiting_connection:
2436 	  case 	state_5_awaiting_v22_connection:
2437 
2438 	    // Ignore it.  Keep same state.
2439 	    break;
2440 
2441 	  case 	state_2_awaiting_release:
2442 
2443 	    // Logic from flow chart for "I, RR, RNR, REJ, SREJ commands."
2444 
2445 	    if (cr == cr_cmd && p == 1) {
2446 	      cmdres_t r = cr_res;	// DM response with F = 1.
2447 	      int f = 1;
2448 	      int nopid = 0;		// PID applies only for I and UI frames.
2449 
2450 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, r, frame_type_U_DM, f, nopid, NULL, 0);
2451 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
2452 	    }
2453 	    break;
2454 
2455 	  case 	state_3_connected:
2456 	  case 	state_4_timer_recovery:
2457 
2458 	    // Look carefully.  The original had two tiny differences between the two states.
2459 	    // In the 2006 version, these differences no longer exist.
2460 
2461 	    // Erratum: SDL asks: Is information field length <= N1 (paclen).
2462 	    // (github issue 102 - Thanks to KK6WHJ for pointing this out.)
2463 	    // Just because we are limiting the size of our transmitted data, it doesn't mean
2464 	    // that the other end will be doing the same.  With v2.2, the XID frame can be
2465 	    // used to negotiate a maximum info length but with v2.0, there is no way for the
2466 	    // other end to know our paclen value.
2467 
2468 	    if (info_len >= 0 && info_len <= AX25_MAX_INFO_LEN) {
2469 
2470 	      if (is_good_nr(S,nr)) {
2471 
2472 	        // Erratum?
2473 	        // I wonder if this difference is intentional or if only one place was
2474 	        // was modified after a cut-n-paste of the flow chart segment.
2475 
2476 		// Erratum: Discrepancy between original and 2006 version.
2477 
2478 		// Pattern noticed:  Anytime we have "is_good_nr" which tests for V(A) <= N(R) <= V(S),
2479 		// we should always call "check_i_frame_ackd" or at least set V(A) from N(R).
2480 
2481 #if 0	// Erratum: original - states 3 & 4 differ here.
2482 
2483 	        if (S->state == state_3_connected) {
2484 	          // This sets "S->va = nr" and also does some timer stuff.
2485 	          check_i_frame_ackd (S,nr);
2486 	        }
2487 	        else {
2488 	          SET_VA(nr);
2489 	        }
2490 
2491 #else 	// 2006 version - states 3 & 4 same here.
2492 
2493 	        // This sets "S->va = nr" and also does some timer stuff.
2494 
2495 	        check_i_frame_ackd (S,nr);
2496 #endif
2497 
2498 // Erratum: v1.5 - My addition.
2499 // I noticed that we sometimes got stuck in state 4 and rc crept up slowly even though
2500 // we received 'I' frames with N(R) values indicating that the other side received everything
2501 // that we sent.  Eventually rc could reach the limit and we would get an error.
2502 // If we are in state 4, and other guy ack'ed last I frame we sent, transition to state 3.
2503 // We had a similar situation for RR/RNR for cases other than response, F=1.
2504 
2505 	        if (S->state == state_4_timer_recovery && S->va == S->vs) {
2506 
2507 	          STOP_T1;
2508 	          select_t1_value (S);
2509 	          START_T3;
2510 	          SET_RC(0);
2511 	          enter_new_state (S, state_3_connected, __func__, __LINE__);
2512 	        }
2513 
2514 	        if (S->own_receiver_busy) {
2515 	          // This should be unreachable because we currently don't have a way to set own_receiver_busy.
2516 	          // But we might the capability someday so implement this while we are here.
2517 
2518 	          if (p == 1) {
2519 	            cmdres_t cr = cr_res;	// Erratum: The use of "F" in the flow chart implies that RNR is a response
2520 						// in this case, but I'm not confident about that.  The text says frame.
2521 	            int f = 1;
2522 	            int nr = S->vr;
2523 	            packet_t pp;
2524 
2525 	            pp = ax25_s_frame (S->addrs, S->num_addr, cr, frame_type_S_RNR, S->modulo, nr, f, NULL, 0);
2526 
2527 	            // I wonder if this difference is intentional or if only one place was
2528 	            // was modified after a cut-n-paste of the flow chart segment.
2529 
2530 #if 0 // Erratum: Original - state 4 has expedited.
2531 
2532 	            if (S->state == state_4_timer_recovery) {
2533 	              lm_data_request (S->chan, TQ_PRIO_0_HI, pp);		// "expedited"
2534 	            }
2535 	            else {
2536 	              lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
2537 	            }
2538 #else // 2006 version - states 3 & 4 the same.
2539 
2540 	            lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
2541 
2542 #endif
2543 	            S->acknowledge_pending = 0;
2544 	          }
2545 
2546 	        }
2547 	        else {		// Own receiver not busy.
2548 
2549 		  i_frame_continued (S, p, ns, pid, info_ptr, info_len);
2550 	        }
2551 
2552 
2553 	      }
2554 	      else {		// N(R) not in expected range.
2555 
2556 	        nr_error_recovery (S);
2557 	        // my enhancement.  See below.
2558 	        enter_new_state (S, S->modulo == 128 ? state_5_awaiting_v22_connection : state_1_awaiting_connection, __func__, __LINE__);
2559 	      }
2560 	    }
2561 	    else {		// Bad information length.
2562 				// Wouldn't even get to CRC check if not octet aligned.
2563 
2564 	      text_color_set(DW_COLOR_ERROR);
2565 	      dw_printf ("Stream %d: AX.25 Protocol Error O: Information part length, %d, not in range of 0 thru %d.\n", S->stream_id, info_len, AX25_MAX_INFO_LEN);
2566 
2567 	      establish_data_link (S);
2568 	      S->layer_3_initiated = 0;
2569 
2570 	      // The original spec always sent SABM and went to state 1.
2571 	      // I was thinking, why not use v2.2 instead of we were already connected with v2.2?
2572 	      // My version of establish_data_link combined the two original functions and
2573 	      // already uses SABME or SABM based on S->modulo.
2574 
2575 	      enter_new_state (S, S->modulo == 128 ? state_5_awaiting_v22_connection : state_1_awaiting_connection, __func__, __LINE__);
2576 	    }
2577 	    break;
2578 	}
2579 
2580 } /* end i_frame */
2581 
2582 
2583 
2584 /*------------------------------------------------------------------------------
2585  *
2586  * Name:	i_frame_continued
2587  *
2588  * Purpose:	The I frame processing logic gets pretty complicated.
2589  *		Some of it has been split out into a separate function to make
2590  *		things more readable.
2591  *		We have already done some error checking and processed N(R).
2592  *		This is used for both states 3 & 4.
2593  *
2594  * Inputs:	S	- Data Link State Machine.  We are in state 3.
2595  *		p	- Poll bit.
2596  *		ns	- N(S) from the frame.  Seq. number of this incoming frame.
2597  *		pid	- protocol id.
2598  *		info_ptr - pointer to information part of frame.
2599  *		info_len - Number of bytes in information part of frame.  Already verified.
2600  *
2601  * Description:
2602  *
2603  *		4.3.2.3. Reject (REJ) Command and Response
2604  *
2605  *		The reject frame requests retransmission of I frames starting with N(R). Any frames sent with a sequence
2606  *		number of N(R)-1 or less are acknowledged. Additional I frames which may exist may be appended to the
2607  *		retransmission of the N(R) frame.
2608  *		Only one reject frame condition is allowed in each direction at a time. The reject condition is cleared by the
2609  *		proper reception of I frames up to the I frame that caused the reject condition to be initiated.
2610  *		The status of the TNC at the other end of the link is requested by sending a REJ command frame with the P bit
2611  *		set to one.
2612  *
2613  *		4.3.2.4. Selective Reject (SREJ) Command and Response
2614  *
2615  * 	(Erratum: SREJ is only response with F bit.)
2616  *
2617  *		The selective reject, SREJ, frame is used by the receiving TNC to request retransmission of the single I frame
2618  *		numbered N(R). If the P/F bit in the SREJ frame is set to "1", then I frames numbered up to N(R)-1 inclusive are
2619  *		considered as acknowledged. However, if the P/F bit in the SREJ frame is set to "0", then the N(R) of the SREJ
2620  *		frame does not indicate acknowledgement of I frames.
2621  *
2622  *		Each SREJ exception condition is cleared (reset) upon receipt of the I frame with an N(S) equal to the N(R)
2623  *		of the SREJ frame.
2624  *
2625  *		A receiving TNC may transmit one or more SREJ frames, each containing a different N(R) with the P bit set
2626  *		to "0", before one or more earlier SREJ exception conditions have been cleared. However, a SREJ is not
2627  *		transmitted if an earlier REJ exception condition has not been cleared as indicated in Section 4.5.4. (To do so
2628  *		would request retransmission of an I frame that would be retransmitted by the REJ operation.) Likewise, a REJ
2629  *		frame is not transmitted if one or more earlier SREJ exception conditions have not been cleared as indicated in
2630  *
2631  *		Section 4.5.4.
2632  *
2633  *		I frames transmitted following the I frame indicated by the SREJ frame are not retransmitted as the result of
2634  *		receiving a SREJ frame. Additional I frames awaiting initial transmission may be transmitted following the
2635  *		retransmission of the specific I frame requested by the SREJ frame.
2636  *
2637  *
2638  *		6.4.4. Reception of Out-of-Sequence Frames
2639  *
2640  *		6.4.4.1. Implicit Reject (REJ)
2641  *
2642  *		When an I frame is received with a correct FCS but its send sequence number N(S) does not match the current
2643  *		receiver's receive state variable, the frame is discarded. A REJ frame is sent with a receive sequence number
2644  *		equal to one higher than the last correctly received I frame if an uncleared N(S) sequence error condition has not
2645  *		been previously established. The received state variable and poll bit of the discarded frame is checked and acted
2646  *		upon, if necessary.
2647  *		This mode requires no frame queueing and frame resequencing at the receiver. However, because the mode
2648  *		requires transmission of frames that may not be in error, its throughput is not as high as selective reject. This
2649  *		mode is ineffective on systems with long round-trip delays and high data rates.
2650  *
2651  *		6.4.4.2. Selective Reject (SREJ)
2652  *
2653  *		When an I frame is received with a correct FCS but its send sequence number N(S) does not match the current
2654  *		receiver's receive state variable, the frame is retained. SREJ frames are sent with a receive sequence number
2655  *		equal to the value N(R) of the missing frame, and P=1 if an uncleared SREJ condition has not been previously
2656  *		established. If an SREJ condition is already pending, an SREJ will be sent with P=0. The received state variable
2657  *		and poll bit of the received frame are checked and acted upon, if necessary.
2658  *		This mode requires frame queueing and frame resequencing at the receiver. The holding of frames can
2659  *		consume precious buffer space, especially if the user device has limited memory available and several active
2660  *		links are operational.
2661  *
2662  *		6.4.4.3. Selective Reject-Reject (SREJ/REJ)
2663  *
2664  *	(Erratum: REJ/SREJ should not be mixed.  Basic (mod 8) allows only REJ.
2665  *		  Extended (mod 128) gives you a choice of one or the other for a link.)
2666  *
2667  *		When an I frame is received with a correct FCS but its send sequence number N(S) does not match the current
2668  *		receiver's receive state variable, and if N(S) indicates 2 or more frames are missing, a REJ frame is transmitted.
2669  *		All subsequently received frames are discarded until the lost frame is correctly received. If only one frame is
2670  *		missing, a SREJ frame is sent with a receive sequence number equal to the value N(R) of the missing frame. The
2671  *		received state variable and poll bit of the received frame are checked and acted upon. If another frame error
2672  *		occurs prior to recovery of the SREJ condition, the receiver saves all frames received after the first errored frame
2673  *		and discards frames received after the second errored frame until the first errored frame is recovered. Then, a
2674  *		REJ is issued to recover the second errored frame and all subsequent discarded frames.
2675  *
2676  *------------------------------------------------------------------------------*/
2677 
i_frame_continued(ax25_dlsm_t * S,int p,int ns,int pid,char * info_ptr,int info_len)2678 static void i_frame_continued (ax25_dlsm_t *S, int p, int ns, int pid, char *info_ptr, int info_len)
2679 {
2680 
2681 	if (ns == S->vr) {
2682 
2683 // The receive sequence number, N(S), is the same as what we were expecting, V(R).
2684 // Send it to the application and increment the next expected.
2685 // It is possible that this was resent and we tucked away others with the following
2686 // sequence numbers.  If so, process them too.
2687 
2688 
2689 	  SET_VR(AX25MODULO(S->vr + 1, S->modulo, __FILE__, __func__, __LINE__));
2690 	  S->reject_exception = 0;
2691 
2692 
2693 	  if (s_debug_client_app) {
2694 	    text_color_set(DW_COLOR_DEBUG);
2695 	    dw_printf ("call dl_data_indication() at %s %d, N(S)=%d, V(R)=%d, \"", __func__, __LINE__, ns, S->vr);
2696 	    ax25_safe_print (info_ptr, info_len, 1);
2697 	    dw_printf ("\"\n");
2698 	  }
2699 
2700 	  dl_data_indication (S, pid, info_ptr, info_len);
2701 
2702 	  if (S->rxdata_by_ns[ns] != NULL) {
2703 	    // There is a possibility that we might have another received frame stashed
2704 	    // away from 8 or 128 (modulo) frames back.  Remove it so it doesn't accidently
2705 	    // show up at some future inopportune time.
2706 
2707 	    cdata_delete (S->rxdata_by_ns[ns]);
2708 	    S->rxdata_by_ns[ns] = NULL;
2709 
2710 	  }
2711 
2712 
2713 	  while (S->rxdata_by_ns[S->vr] != NULL) {
2714 
2715 	    // dl_data_indication - send connected data to client application.
2716 
2717 	    if (s_debug_client_app) {
2718 	      text_color_set(DW_COLOR_DEBUG);
2719 	      dw_printf ("call dl_data_indication() at %s %d, N(S)=%d, V(R)=%d, data=\"", __func__, __LINE__, ns, S->vr);
2720 	      ax25_safe_print (S->rxdata_by_ns[S->vr]->data, S->rxdata_by_ns[S->vr]->len, 1);
2721 	      dw_printf ("\"\n");
2722 	    }
2723 
2724 	    dl_data_indication (S, S->rxdata_by_ns[S->vr]->pid, S->rxdata_by_ns[S->vr]->data, S->rxdata_by_ns[S->vr]->len);
2725 
2726 	    // Don't keep around anymore after sending it to client app.
2727 
2728 	    cdata_delete (S->rxdata_by_ns[S->vr]);
2729 	    S->rxdata_by_ns[S->vr] = NULL;
2730 
2731 	    SET_VR(AX25MODULO(S->vr + 1, S->modulo, __FILE__, __func__, __LINE__));
2732 	  }
2733 
2734 	  if (p) {
2735 
2736 // Mentioned in section 6.2.
2737 // The next response frame returned to an I frame with the P bit set to "1", received during the information
2738 // transfer state, is an RR, RNR or REJ response with the F bit set to "1".
2739 
2740 	    int f = 1;
2741 	    int nr = S->vr;		// Next expected sequence number.
2742 	    cmdres_t cr = cr_res;	// response with F set to 1.
2743 	    packet_t pp;
2744 
2745 	    pp = ax25_s_frame (S->addrs, S->num_addr, cr, frame_type_S_RR, S->modulo, nr, f, NULL, 0);
2746 	    lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
2747 	    S->acknowledge_pending = 0;
2748 	  }
2749 	  else if ( ! S->acknowledge_pending) {
2750 
2751     	    S->acknowledge_pending = 1;  // Probably want to set this before the LM-SEIZE Request
2752 					// in case the LM-SEIZE Confirm gets processed before we
2753 					// return from it.
2754 
2755 	    // Force start of transmission even if the transmit frame queue is empty.
2756 	    // Notify me, with lm_seize_confirm, when transmission has started.
2757 	    // When that event arrives, we check acknowledge_pending and send something
2758 	    // to be determined later.
2759 
2760 	    lm_seize_request (S->chan);
2761 	  }
2762 	}
2763 	else if (S->reject_exception) {
2764 
2765 // This is not the sequence we were expecting.
2766 // We previously sent REJ, asking for a resend so don't send another.
2767 // In this case, send RR only if the Poll bit is set.
2768 // Again, reference section 6.2.
2769 
2770 	  if (p) {
2771 	    int f = 1;
2772 	    int nr = S->vr;		// Next expected sequence number.
2773 	    cmdres_t cr = cr_res;	// response with F set to 1.
2774 	    packet_t pp;
2775 
2776 	    pp = ax25_s_frame (S->addrs, S->num_addr, cr, frame_type_S_RR, S->modulo, nr, f, NULL, 0);
2777 	    lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
2778 	    S->acknowledge_pending = 0;
2779 	  }
2780 	}
2781 	else if (S->srej_enable == srej_none) {
2782 
2783 // The received sequence number is not the expected one and we can't use SREJ.
2784 // The old v2.0 approach is to send and REJ with the number we are expecting.
2785 // This can be very inefficient.  For example if we received 1,3,4,5,6 in one transmission,
2786 // we discard 3,4,5,6, and tell the other end to resend everything starting with 2.
2787 
2788 // At one time, I had some doubts about when to use command or response for REJ.
2789 // I now believe that reponse, as implied by setting F in the flow chart, is correct.
2790 
2791 	  int f = p;
2792 	  int nr = S->vr;		// Next expected sequence number.
2793 	  cmdres_t cr = cr_res;		// response with F copied from P in I frame.
2794 	  packet_t pp;
2795 
2796 	  S->reject_exception = 1;
2797 
2798 	  if (s_debug_retry) {
2799 	      text_color_set(DW_COLOR_ERROR);	// make it more noticable.
2800 	      dw_printf ("sending REJ, at %s %d, SREJ not enabled case, V(R)=%d", __func__, __LINE__, S->vr);
2801 	  }
2802 
2803 	  pp = ax25_s_frame (S->addrs, S->num_addr, cr, frame_type_S_REJ, S->modulo, nr, f, NULL, 0);
2804 	  lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
2805 
2806 	  S->acknowledge_pending = 0;
2807 	}
2808 	else {
2809 
2810 // Selective reject is enabled so we can use the more efficient method.
2811 // This is normally enabled for v2.2 but XID can be used to change that.
2812 // First we save the current frame so we can retrieve it later after getting the fill in.
2813 
2814 	  if (S->modulo != 128) {
2815 	    text_color_set(DW_COLOR_ERROR);
2816 	    dw_printf ("INTERNAL ERROR: Should not be sending SREJ in basic (modulo 8) mode.\n");
2817 	  }
2818 
2819 #if 1
2820 
2821 // Erratum:  AX.25 protocol spec did not handle SREJ very well.
2822 // Based on X.25 section 2.4.6.4.
2823 
2824 
2825 	  if (is_ns_in_window(S, ns)) {
2826 
2827 // X.25 2.4.6.4 (b)
2828 // v(R) < N(S) < V(R)+k so it is in the expected range.
2829 // Save it in the receive buffer.
2830 
2831 	    if (S->rxdata_by_ns[ns] != NULL) {
2832 	      cdata_delete (S->rxdata_by_ns[ns]);
2833 	      S->rxdata_by_ns[ns] = NULL;
2834 	    }
2835 	    S->rxdata_by_ns[ns] = cdata_new(pid, info_ptr, info_len);
2836 
2837 	    if (s_debug_misc) {
2838 	      dw_printf ("%s %d, save to rxdata_by_ns N(S)=%d, V(R)=%d, \"", __func__, __LINE__, ns, S->vr);
2839 	      ax25_safe_print (info_ptr, info_len, 1);
2840 	      dw_printf ("\"\n");
2841 	    }
2842 
2843 	    if (p == 1) {
2844 	      int f = 1;
2845 	      enquiry_response (S, frame_type_I, f);
2846 	    }
2847 	    else if (S->own_receiver_busy) {
2848 	      cmdres_t cr = cr_res;	// send RNR response
2849 	      int f = 0;	// we know p=0 here.
2850 	      int nr = S->vr;
2851 	      packet_t pp;
2852 
2853 	      pp = ax25_s_frame (S->addrs, S->num_addr, cr, frame_type_S_RNR, S->modulo, nr, f, NULL, 0);
2854 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
2855 	    }
2856 	    else if (S->rxdata_by_ns[ AX25MODULO(ns - 1, S->modulo, __FILE__, __func__, __LINE__)] == NULL) {
2857 
2858 // Ask for missing frames when we don't have N(S)-1 in the receive buffer.
2859 
2860 // In version 1.4:
2861 // We end up sending more SREJ than necessary and and get back redundant information.  Example:
2862 // When we see 113 missing, we ask for a resend.
2863 // When we see 115 & 116 missing, a cummulative SREJ asks for everything.
2864 // The other end dutifully sends 113 twice.
2865 //
2866 // [0.4] DW1>DW0:(SREJ res, n(r)=113, f=0)
2867 // [0.4] DW1>DW0:(SREJ res, n(r)=113, f=1)<0xe6><0xe8>
2868 //
2869 // [0L] DW0>DW1:(I cmd, n(s)=113, n(r)=11, p=0, pid=0xf0)0114 send data<0x0d>
2870 // [0L] DW0>DW1:(I cmd, n(s)=113, n(r)=11, p=0, pid=0xf0)0114 send data<0x0d>
2871 // [0L] DW0>DW1:(I cmd, n(s)=115, n(r)=11, p=0, pid=0xf0)0116 send data<0x0d>
2872 // [0L] DW0>DW1:(I cmd, n(s)=116, n(r)=11, p=0, pid=0xf0)0117 send data<0x0d>
2873 
2874 
2875 // Version 1.5:
2876 // Don't generate duplicate requests for gaps in the same transmission.
2877 
2878 // Ideally, we might wait until carrier drops and then use one Multi-SREJ for entire transmission but
2879 // we will keep that for another day.
2880 // Probably need a flag similar to acknowledge_pending (or ask_resend_count, here) and the ask_for_resend array.
2881 // It could then be processed first in lm_seize_confirm.
2882 
2883 	      int ask_for_resend[128];
2884 	      int ask_resend_count = 0;
2885 	      int x;
2886 
2887 // Version 1.5
2888 // Erratum:  AX.25 says use F=0 here.  Doesn't make sense.
2889 // We would want to set F when sending N(R) = V(R).
2890 //	      int allow_f1 = 0;		// F=1 from X.25 2.4.6.4 b) 3)
2891 	      int allow_f1 = 1;		// F=1 from X.25 2.4.6.4 b) 3)
2892 
2893 // send only for this gap, not cummulative from V(R).
2894 
2895 	      int last = AX25MODULO(ns - 1, S->modulo, __FILE__, __func__, __LINE__);
2896 	      int first = last;
2897 	      while (first != S->vr && S->rxdata_by_ns[AX25MODULO(first - 1, S->modulo, __FILE__, __func__, __LINE__)] == NULL) {
2898 	        first = AX25MODULO(first - 1, S->modulo, __FILE__, __func__, __LINE__);
2899 	      }
2900 	      x = first;
2901 	      do {
2902 	        ask_for_resend[ask_resend_count++] = AX25MODULO(x, S->modulo, __FILE__, __func__, __LINE__);
2903 	        x = AX25MODULO(x + 1, S->modulo, __FILE__, __func__, __LINE__);
2904 	      } while (x != AX25MODULO(last + 1, S->modulo, __FILE__, __func__, __LINE__));
2905 
2906 	      send_srej_frames (S, ask_for_resend, ask_resend_count, allow_f1);
2907 	    }
2908 	  }
2909 	  else {
2910 
2911 // X.25 2.4.6.4 a)
2912 // N(S) is not in expected range.  Discard it.  Send response if P=1.
2913 
2914 	    if (p == 1) {
2915 	      int f = 1;
2916 	      enquiry_response (S, frame_type_I, f);
2917 	    }
2918 
2919 	  }
2920 
2921 #else  // my earlier attempt before taking a close look at X.25 spec.
2922 	// Keeping it around for a little while because I might want to
2923 	// use earlier technique of sending only needed SREJ for any second
2924 	// and later gaps in a single multiframe transmission.
2925 
2926 
2927 	  if (S->rxdata_by_ns[ns] != NULL) {
2928 	    cdata_delete (S->rxdata_by_ns[ns]);
2929 	    S->rxdata_by_ns[ns] = NULL;
2930 	  }
2931 	  S->rxdata_by_ns[ns] = cdata_new(pid, info_ptr, info_len);
2932 
2933 	  S->outstanding_srej[ns] = 0;	// Don't care if it was previously set or not.
2934 					// We have this one so there is no outstanding SREJ for it.
2935 
2936 	  if (s_debug_misc) {
2937 	    dw_printf ("%s %d, save to rxdata_by_ns N(S)=%d, V(R)=%d, \"", __func__, __LINE__, ns, S->vr);
2938 	    ax25_safe_print (info_ptr, info_len, 1);
2939 	    dw_printf ("\"\n");
2940 	  }
2941 
2942 
2943 
2944 
2945 	  if (selective_reject_exception(S) == 0) {
2946 
2947 // Erratum:  This is vastly different than the SDL in the AX.25 protocol spec.
2948 // That would use SREJ if only one was missing and REJ instead.
2949 // Here we do not mix the them.
2950 // This agrees with the X.25 protocol spec that says use one or the other.  Not both.
2951 
2952 // Suppose we had incoming I frames 0, 3, 7.
2953 // 0 was already processed and V(R)=1 meaning that is the next expected.
2954 // At this point we area processing N(S)=3.
2955 // In this case, we need to ask for a resend of 1 & 2.
2956 // More generally, the range of V(R) thru N(S)-1.
2957 
2958 	    int ask_for_resend[128];
2959 	    int ask_resend_count = 0;
2960 	    int i;
2961 	    int allow_f1 = 1;
2962 
2963 text_color_set(DW_COLOR_ERROR);
2964 dw_printf ("%s:%d, zero exceptions, V(R)=%d, N(S)=%d\n", __func__, __LINE__, S->vr, ns);
2965 
2966 	    for (i = S->vr; i != ns; i = AX25MODULO(i+1, S->modulo, __FILE__, __func__, __LINE__)) {
2967 	      ask_for_resend[ask_resend_count++] = i;
2968 	    }
2969 
2970 	    send_srej_frames (S, ask_for_resend, ask_resend_count, allow_f1);
2971 	  }
2972 	  else {
2973 
2974 // Erratum: The SDL says ask for N(S) which is clearly wrong because that's what we just received.
2975 // Instead we want to ask for any missing frames up to but not including N(S).
2976 
2977 // Let's continue with the example above.  I frames with N(S) of 0, 3, 7.
2978 // selective_reject_exception is non zero meaning there are outstanding requests to resend specified I frames.
2979 // V(R) is still 1 because 0 is the last one received with contiguous N(S) values.
2980 // 3 has been saved into S->rxdata_by_ns.
2981 // We now have N(S)=7.   We want to ask for a resend of 4, 5, 6.
2982 // This can be achieved by searching S->rxdata_by_ns, starting with N(S)-1, and counting
2983 // how many empty slots we have before finding a saved frame.
2984 
2985 	    int ask_resend_count = 0;
2986 	    int first;
2987 
2988 text_color_set(DW_COLOR_ERROR);
2989 dw_printf ("%s:%d, %d srej exceptions, V(R)=%d, N(S)=%d\n", __func__, __LINE__, selective_reject_exception(S), S->vr, ns);
2990 
2991 	    first = AX25MODULO(ns - 1, S->modulo, __FILE__, __func__, __LINE__);
2992 	    while (S->rxdata_by_ns[first] == NULL) {
2993 	      if (first == AX25MODULO(S->vr - 1, S->modulo, __FILE__, __func__, __LINE__)) {
2994 	        //  Oops!  Went too far.  This I frame was already processed.
2995 		text_color_set(DW_COLOR_ERROR);
2996 	        dw_printf ("INTERNAL ERROR calulating what to put in SREJ, %s line %d\n", __func__, __LINE__);
2997 	        dw_printf ("V(R)=%d, N(S)=%d, SREJ exception=%d, first=%d, ask_resend_count=%d\n", S->vr, ns, selective_reject_exception(S), first, ask_resend_count);
2998 		int k;
2999 	        for (k=0; k<128; k++) {
3000 	          if (S->rxdata_by_ns[k] != NULL) {
3001 	            dw_printf ("rxdata_by_ns[%d] has data\n", k);
3002 	          }
3003 	        }
3004 	        break;
3005 	      }
3006 	      ask_resend_count++;
3007 	      first = AX25MODULO(first - 1, S->modulo, __FILE__, __func__, __LINE__);
3008 	    }
3009 
3010 	    // Go beyond the slot where we already have an I frame.
3011 	    first = AX25MODULO(first + 1, S->modulo, __FILE__, __func__, __LINE__);
3012 
3013 	    // The ask_resend_count could be 0.  e.g. We got 4 rather than 7 in this example.
3014 
3015 	    if (ask_resend_count > 0) {
3016 	      int ask_for_resend[128];
3017 	      int n;
3018 	      int allow_f1 = 1;
3019 
3020 	      for (n = 0; n < ask_resend_count; n++) {
3021 	        ask_for_resend[n] = AX25MODULO(first + n, S->modulo, __FILE__, __func__, __LINE__);;
3022 	      }
3023 
3024 	      send_srej_frames (S, ask_for_resend, ask_resend_count, allow_f1);
3025 	    }
3026 
3027 	  } /* end SREJ exception */
3028 
3029 #endif	// my earlier attempt.
3030 
3031 
3032 
3033 
3034 // Erratum:  original has following but 2006 rev does not.
3035 // I think the 2006 version is correct.
3036 // SREJ does not always satisfy the need for ack.
3037 // There is a special case where F=1.  We take care of that inside of send_srej_frames.
3038 
3039 #if 0
3040 	  S->acknowledge_pending = 0;
3041 #endif
3042 
3043 	} /* end srej enabled */
3044 
3045 
3046 } /* end i_frame_continued */
3047 
3048 
3049 
3050 /*------------------------------------------------------------------------------
3051  *
3052  * Name:	is_ns_in_window
3053  *
3054  * Purpose:	Is the N(S) value of the incoming I frame in the expected range?
3055  *
3056  * Inputs:	ns		- Sequence from I frame.
3057  *
3058  * Description:	With selective reject, it is possible that we could receive a repeat of
3059  *		an I frame with N(S) less than V(R).  In this case, we just want to
3060  *		discard it rather than getting upset and reestablishing the connection.
3061  *
3062  *		The X.25 spec,section 2.4.6.4 (b) asks whether  V(R) < N(S) < V(R)+k.
3063  *
3064  *		The problem here is that it depends on the value of k for the other end.
3065  *		X.25 says that both sides need to agree on a common value of k ahead of time.
3066  *		We might have k=8 for our sending but the other side could have k=32 so
3067  *		this test could fail.
3068  *
3069  *		As a hack, we could use the value 63 here.  If too small we would discard
3070  *		I frames that are in the acceptable range because they would be >= V(R)+k.
3071  *		On the other hand, if this value is too big, the range < V(R) would not be
3072  *		large enough and we would accept frame we shouldn't.
3073  *		As a practical matter, using a window size that large is pretty unlikely.
3074  *		Maybe I could put a limit of 63, rather than 127 in the configuration.
3075  *
3076  *------------------------------------------------------------------------------*/
3077 
3078 #define GENEROUS_K 63
3079 
is_ns_in_window(ax25_dlsm_t * S,int ns)3080 static int is_ns_in_window (ax25_dlsm_t *S, int ns)
3081 {
3082 	int adjusted_vr, adjusted_ns, adjusted_vrpk;
3083 	int result;
3084 
3085 /* Shift all values relative to V(R) before comparing so we won't have wrap around. */
3086 
3087 #define adjust_by_vr(x) (AX25MODULO((x) - S->vr, S->modulo, __FILE__, __func__, __LINE__))
3088 
3089 	adjusted_vr   = adjust_by_vr(S->vr);	// A clever compiler would know it is zero.
3090 	adjusted_ns   = adjust_by_vr(ns);
3091 	adjusted_vrpk = adjust_by_vr(S->vr + GENEROUS_K);
3092 
3093 	result = adjusted_vr < adjusted_ns && adjusted_ns < adjusted_vrpk;
3094 
3095 	if (s_debug_retry) {
3096 	  text_color_set(DW_COLOR_DEBUG);
3097 	  dw_printf ("is_ns_in_window,  V(R) %d < N(S) %d < V(R)+k %d, returns %d\n", S->vr, ns, S->vr + GENEROUS_K, result);
3098 	}
3099 
3100 	return (result);
3101 }
3102 
3103 
3104 /*------------------------------------------------------------------------------
3105  *
3106  * Name:	send_srej_frames
3107  *
3108  * Purpose:	Ask for a resend of I frames with specified sequence numbers.
3109  *
3110  * Inputs:	resend		- Array of N(S) values for missing I frames.
3111  *
3112  *		count		- Number of items in array.
3113  *
3114  *		allow_f1	- When true, set F=1 when asking for V(R).
3115  *
3116  *					X.25 section 2.4.6.4 b) 3) says F should be set to 0
3117  *						when receiving I frame out of sequence.
3118  *
3119  *					X.25 sections 2.4.6.11 & 2.3.5.2.2 say set F to 1 when
3120  *						responding to command with P=1.  (our enquiry_response function).
3121  *
3122  * Version 1.5:	The X.25 protocol spec allows additional sequence numbers in one frame
3123  *		by using the INFO part.
3124  *		By default that feature is off but can be negotiated with XID.
3125  *		We should be able to use this between two direwolf stations while
3126  *		maintaining compatibility with the original AX.25 v2.2.
3127  *
3128  *------------------------------------------------------------------------------*/
3129 
3130 
send_srej_frames(ax25_dlsm_t * S,int * resend,int count,int allow_f1)3131 static void send_srej_frames (ax25_dlsm_t *S, int *resend, int count, int allow_f1)
3132 {
3133 	int f;			// Set if we are ack-ing one before.
3134 	int nr;
3135 	cmdres_t cr = cr_res;	// SREJ is always response.
3136 	int i;
3137 
3138 	packet_t pp;
3139 
3140 	if (count <= 0) {
3141 	  text_color_set(DW_COLOR_ERROR);
3142 	  dw_printf ("INTERNAL ERROR, count=%d, %s line %d\n", count, __func__, __LINE__);
3143 	  return;
3144 	}
3145 
3146 	if (s_debug_retry) {
3147 	  text_color_set(DW_COLOR_INFO);
3148 	  dw_printf ("%s line %d\n", __func__, __LINE__);
3149 	  //dw_printf ("state=%d, count=%d, k=%d, V(R)=%d, SREJ exeception=%d\n", S->state, count, S->k_maxframe, S->vr, selective_reject_exception(S));
3150 	  dw_printf ("state=%d, count=%d, k=%d, V(R)=%d\n", S->state, count, S->k_maxframe, S->vr);
3151 
3152 	  dw_printf ("resend[]=");
3153 	  for (i = 0; i < count; i++) {
3154 	    dw_printf (" %d", resend[i]);
3155 	  }
3156 	  dw_printf ("\n");
3157 
3158 	  dw_printf ("rxdata_by_ns[]=");
3159 	  for (i = 0; i < 128; i++) {
3160 	    if (S->rxdata_by_ns[i] != NULL) {
3161 	      dw_printf (" %d", i);
3162 	    }
3163 	  }
3164 	  dw_printf ("\n");
3165 	}
3166 
3167 
3168 // Something is wrong!  We ask for more than the window size.
3169 
3170 	if (count > S->k_maxframe) {
3171 
3172 	  text_color_set(DW_COLOR_ERROR);
3173 	  dw_printf ("INTERNAL ERROR - Extreme number of SREJ, %s line %d\n", __func__, __LINE__);
3174 	  dw_printf ("state=%d, count=%d, k=%d, V(R)=%d\n", S->state, count, S->k_maxframe, S->vr);
3175 
3176 	  dw_printf ("resend[]=");
3177 	  for (i = 0; i < count; i++) {
3178 	    dw_printf (" %d", resend[i]);
3179 	  }
3180 	  dw_printf ("\n");
3181 
3182 	  dw_printf ("rxdata_by_ns[]=");
3183 	  for (i = 0; i < 128; i++) {
3184 	    if (S->rxdata_by_ns[i] != NULL) {
3185 	      dw_printf (" %d", i);
3186 	    }
3187 	  }
3188 	  dw_printf ("\n");
3189 	}
3190 
3191 // Multi-SREJ - Use info part for additional sequence number(s) instead of sending separate SREJ for each.
3192 
3193 	if (S->srej_enable == srej_multi && count > 1) {
3194 
3195 	  unsigned char info[128];
3196 	  int info_len = 0;
3197 
3198 	  for (i = 1; i < count; i++) {		// skip first one
3199 
3200 	    if (resend[i] < 0 || resend[i] >= S->modulo) {
3201 	      text_color_set(DW_COLOR_ERROR);
3202 	      dw_printf ("INTERNAL ERROR, additional nr=%d, modulo=%d, %s line %d\n", resend[i], S->modulo, __func__, __LINE__);
3203 	    }
3204 
3205 	    // There is also a form to specify a range but I don't
3206 	    // think it is worth the effort to generate it.  Maybe later.
3207 
3208 	    if (S->modulo == 8) {
3209 	      info[info_len++] = resend[i] << 5;
3210 	    }
3211 	    else {
3212 	      info[info_len++] = resend[i] << 1;
3213 	    }
3214 	  }
3215 
3216 	  f = 0;
3217 	  nr = resend[0];
3218 	  f = allow_f1 && (nr == S->vr);
3219 					// Possibly set if we are asking for the next after
3220 					// the last one received in contiguous order.
3221 
3222 					// This could only apply to the first in
3223 					// the list so this would not go in the loop.
3224 
3225 	  if (f) {			// In this case the other end is being
3226 					// informed of my V(R) so no additional
3227 					// RR etc. is needed.
3228 					// TODO:  Need to think about this.
3229 	    S->acknowledge_pending = 0;
3230 	  }
3231 
3232 	  if (nr < 0 || nr >= S->modulo) {
3233 	    text_color_set(DW_COLOR_ERROR);
3234 	    dw_printf ("INTERNAL ERROR, nr=%d, modulo=%d, %s line %d\n", nr, S->modulo, __func__, __LINE__);
3235 	    nr = AX25MODULO(nr, S->modulo, __FILE__, __func__, __LINE__);
3236 	  }
3237 
3238 	  pp = ax25_s_frame (S->addrs, S->num_addr, cr, frame_type_S_SREJ, S->modulo, nr, f, info, info_len);
3239 	  lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
3240 	  return;
3241 	}
3242 
3243 // Multi-SREJ not enabled.  Send separate SREJ for each desired sequence number.
3244 
3245 	for (i = 0; i < count; i++) {
3246 
3247 	  nr = resend[i];
3248 	  f = allow_f1 && (nr == S->vr);
3249 					// Possibly set if we are asking for the next after
3250 					// the last one received in contiguous order.
3251 
3252 	  if (f) {
3253 					// In this case the other end is being
3254 					// informed of my V(R) so no additional
3255 					// RR etc. is needed.
3256 	    S->acknowledge_pending = 0;
3257 	  }
3258 
3259 	  if (nr < 0 || nr >= S->modulo) {
3260 	    text_color_set(DW_COLOR_ERROR);
3261 	    dw_printf ("INTERNAL ERROR, nr=%d, modulo=%d, %s line %d\n", nr, S->modulo, __func__, __LINE__);
3262 	    nr = AX25MODULO(nr, S->modulo, __FILE__, __func__, __LINE__);
3263 	  }
3264 
3265 	  pp = ax25_s_frame (S->addrs, S->num_addr, cr, frame_type_S_SREJ, S->modulo, nr, f, NULL, 0);
3266 	  lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
3267 	}
3268 
3269 } /* end send_srej_frames */
3270 
3271 
3272 
3273 /*------------------------------------------------------------------------------
3274  *
3275  * Name:	rr_rnr_frame
3276  *
3277  * Purpose:	Process RR or RNR Frame.
3278  *		Processing is the essentially the same so they are handled by a single function.
3279  *
3280  * Inputs:	S	- Data Link State Machine.
3281  *		ready	- True for RR, false for RNR
3282  *		cr	- Is this command or response?
3283  *		pf	- Poll/Final bit.
3284  *		nr	- N(R) from the frame.
3285  *
3286  * Description:	4.3.2.1. Receive Ready (RR) Command and Response
3287  *
3288  *		Receive Ready accomplishes the following:
3289  *		a) indicates that the sender of the RR is now able to receive more I frames;
3290  *		b) acknowledges properly received I frames up to, and including N(R)-1;and
3291  *		c) clears a previously-set busy condition created by an RNR command having been sent.
3292  *		The status of the TNC at the other end of the link can be requested by sending an RR command frame with the
3293  *		P-bit set to one.
3294  *
3295  *		4.3.2.2. Receive Not Ready (RNR) Command and Response
3296  *
3297  *		Receive Not Ready indicates to the sender of I frames that the receiving TNC is temporarily busy and cannot
3298  *		accept any more I frames. Frames up to N(R)-1 are acknowledged. Frames N(R) and above that may have been
3299  *		transmitted are discarded and must be retransmitted when the busy condition clears.
3300  *		The RNR condition is cleared by the sending of a UA, RR, REJ or SABM(E) frame.
3301  *		The status of the TNC at the other end of the link is requested by sending an RNR command frame with the
3302  *		P bit set to one.
3303  *
3304  *------------------------------------------------------------------------------*/
3305 
3306 
rr_rnr_frame(ax25_dlsm_t * S,int ready,cmdres_t cr,int pf,int nr)3307 static void rr_rnr_frame (ax25_dlsm_t *S, int ready, cmdres_t cr, int pf, int nr)
3308 {
3309 
3310 	// dw_printf ("rr_rnr_frame (ready=%d, cr=%d, pf=%d, nr=%d) state=%d\n", ready, cr, pf, nr, S->state);
3311 
3312 	switch (S->state) {
3313 
3314 	  case 	state_0_disconnected:
3315 
3316 	    if (cr == cr_cmd) {
3317 	      cmdres_t r = cr_res;	// DM response with F taken from P.
3318 	      int f = pf;
3319 	      int nopid = 0;		// PID only for I and UI frames.
3320 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, r, frame_type_U_DM, f, nopid, NULL, 0);
3321 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
3322 	    }
3323 	    break;
3324 
3325 	  case 	state_1_awaiting_connection:
3326 	  case 	state_5_awaiting_v22_connection:
3327 
3328 	    // do nothing.
3329 	    break;
3330 
3331 	  case 	state_2_awaiting_release:
3332 
3333 	    // Logic from flow chart for "I, RR, RNR, REJ, SREJ commands."
3334 
3335 	    if (cr == cr_cmd && pf == 1) {
3336 	      cmdres_t r = cr_res;	// DM response with F = 1.
3337 	      int f = 1;
3338 	      int nopid = 0;		// PID applies only for I and UI frames.
3339 
3340 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, r, frame_type_U_DM, f, nopid, NULL, 0);
3341 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
3342 	    }
3343 
3344 // Erratum: We have a disagreement here between original and 2006 version.
3345 // RR, RNR, REJ, SREJ responses would fall under "all other primitives."
3346 // In the original, we simply ignore it and stay in state 2.
3347 // The 2006 version, page 94,  says go into "1 awaiting connection" state.
3348 // That makes no sense to me.
3349 
3350 	    break;
3351 
3352 	  case 	state_3_connected:
3353 
3354 	    S->peer_receiver_busy = ! ready;
3355 
3356 // Erratum: the flow charts have unconditional check_need_for_response here.
3357 // I don't recall exactly why I added the extra test for command and P=1.
3358 // It might have been because we were reporting error A for response with F=1.
3359 // Other than avoiding that error message, this is functionally equivalent.
3360 
3361 	    if (cr == cr_cmd && pf) {
3362 	      check_need_for_response (S, ready ? frame_type_S_RR : frame_type_S_RNR, cr, pf);
3363 	    }
3364 
3365 	    if (is_good_nr(S,nr)) {
3366 	      // dw_printf ("rr_rnr_frame (), line %d, state=%d, good nr=%d, calling check_i_frame_ackd\n", __LINE__, S->state, nr);
3367 
3368 	      check_i_frame_ackd (S, nr);
3369 	    }
3370 	    else {
3371 	      if (s_debug_retry) {
3372 	        text_color_set(DW_COLOR_DEBUG);
3373 	        dw_printf ("rr_rnr_frame (), line %d, state=%d, bad nr, calling nr_error_recovery\n", __LINE__, S->state);
3374 	      }
3375 
3376 	      nr_error_recovery (S);
3377 	      // My enhancement.  Original always sent SABM and went to state 1.
3378 	      enter_new_state (S, S->modulo == 128 ? state_5_awaiting_v22_connection : state_1_awaiting_connection, __func__, __LINE__);
3379 	    }
3380 
3381 	    break;
3382 
3383 	  case 	state_4_timer_recovery:
3384 
3385 	    S->peer_receiver_busy = ! ready;
3386 
3387 	    if (cr == cr_res && pf == 1) {
3388 
3389 // RR/RNR Response with F==1.
3390 
3391 	      if (s_debug_retry) {
3392 	        text_color_set(DW_COLOR_DEBUG);
3393 	        dw_printf ("rr_rnr_frame (), Response, f=%d, line %d, state=%d, good nr, calling check_i_frame_ackd\n", pf, __LINE__, S->state);
3394 	      }
3395 
3396 	      STOP_T1;
3397 	      select_t1_value(S);
3398 
3399 	      if (is_good_nr(S,nr)) {
3400 
3401 	        SET_VA(nr);
3402 	        if (S->vs == S->va) {		// all caught up with ack from other guy.
3403 	          START_T3;
3404 	          SET_RC(0);			// My enhancement.  See Erratum note in select_t1_value.
3405 	          enter_new_state (S, state_3_connected, __func__, __LINE__);
3406 	        }
3407 	        else {
3408 	          invoke_retransmission (S, nr);
3409 // my addition
3410 
3411 // Erratum: We sent I frame(s) and want to timeout if no ack comes back.
3412 // We also sent N(R) so no need for extra RR at the end only for that.
3413 
3414 	          STOP_T3;
3415 	          START_T1;
3416 	          S->acknowledge_pending = 0;
3417 
3418 // end of my addition
3419 	        }
3420 	      }
3421 	      else {
3422 	        nr_error_recovery (S);
3423 
3424 // Erratum: Another case of my enhancement.
3425 // The flow charts go into state 1 after nr_error_recovery.
3426 // I use state 5 instead if we were oprating in extended (modulo 128) mode.
3427 
3428 	        enter_new_state (S, S->modulo == 128 ? state_5_awaiting_v22_connection : state_1_awaiting_connection, __func__, __LINE__);
3429 	      }
3430 	    }
3431 	    else {
3432 
3433 // RR/RNR command, either P value.
3434 // RR/RNR response, F==0
3435 
3436 	      if (cr == cr_cmd && pf == 1) {
3437 	        int f = 1;
3438 	        enquiry_response (S, ready ? frame_type_S_RR : frame_type_S_RNR, f);
3439 	      }
3440 
3441 	      if (is_good_nr(S,nr)) {
3442 
3443 	        SET_VA(nr);
3444 
3445 // Erratum: v1.5 - my addition.
3446 // I noticed that we sometimes got stuck in state 4 and rc crept up slowly even though
3447 // we received RR frames with N(R) values indicating that the other side received everything
3448 // that we sent.  Eventually rc could reach the limit and we would get an error.
3449 // If we are in state 4, and other guy ack'ed last I frame we sent, transition to state 3.
3450 // The same thing was done for receving I frames after check_i_frame_ackd.
3451 
3452 // Thought: Could we simply call check_i_frame_ackd, for consistency, rather than only setting V(A)?
3453 
3454 	        if (cr == cr_res && pf == 0) {
3455 
3456 	          if (S->vs == S->va) {		// all caught up with ack from other guy.
3457 	            STOP_T1;
3458 	            select_t1_value (S);
3459 	            START_T3;
3460 	            SET_RC(0);
3461 	            enter_new_state (S, state_3_connected, __func__, __LINE__);
3462 	          }
3463 	        }
3464 	      }
3465 	      else {
3466 	        nr_error_recovery (S);
3467 	        enter_new_state (S, S->modulo == 128 ? state_5_awaiting_v22_connection : state_1_awaiting_connection, __func__, __LINE__);
3468 	      }
3469 	    }
3470 	    break;
3471 	}
3472 
3473 } /* end rr_rnr_frame */
3474 
3475 
3476 
3477 /*------------------------------------------------------------------------------
3478  *
3479  * Name:	rej_frame
3480  *
3481  * Purpose:	Process REJ Frame.
3482  *
3483  * Inputs:	S	- Data Link State Machine.
3484  *		cr	- Is this command or response?
3485  *		pf	- Poll/Final bit.
3486  *		nr	- N(R) from the frame.
3487  *
3488  * Description:	4.3.2.2. Receive Not Ready (RNR) Command and Response
3489  *
3490  *		... The RNR condition is cleared by the sending of a UA, RR, REJ or SABM(E) frame. ...
3491  *
3492  *
3493  *		4.3.2.3. Reject (REJ) Command and Response
3494  *
3495  *		The reject frame requests retransmission of I frames starting with N(R). Any frames sent with a sequence
3496  *		number of N(R)-1 or less are acknowledged. Additional I frames which may exist may be appended to the
3497  *		retransmission of the N(R) frame.
3498  *		Only one reject frame condition is allowed in each direction at a time. The reject condition is cleared by the
3499  *		proper reception of I frames up to the I frame that caused the reject condition to be initiated.
3500  *		The status of the TNC at the other end of the link is requested by sending a REJ command frame with the P bit
3501  *		set to one.
3502  *
3503  *		4.4.3. Reject (REJ) Recovery
3504  *
3505  *		The REJ frame requests a retransmission of I frames following the detection of a N(S) sequence error. Only
3506  *		one outstanding "sent REJ" condition is allowed at a time. This condition is cleared when the requested I frame
3507  *		has been received.
3508  *		A TNC receiving the REJ command clears the condition by resending all outstanding I frames (up to the
3509  *		window size), starting with the frame indicated in N(R) of the REJ frame.
3510  *
3511  *
3512  *		4.4.5.1. T1 Timer Recovery
3513  *
3514  *		If a transmission error causes a TNC to fail to receive (or to receive and discard) a single I frame, or the last I
3515  *		frame in a sequence of I frames, then the TNC does not detect a send-sequence-number error and consequently
3516  *		does not transmit a REJ/SREJ. The TNC that transmitted the unacknowledged I frame(s) following the completion
3517  *		of timeout period T1, takes appropriate recovery action to determine when I frame retransmission as described
3518  *		in Section 6.4.10 should begin. This condition is cleared by the reception of an acknowledgement for the sent
3519  *		frame(s), or by the link being reset.
3520  *
3521  *		6.2. Poll/Final (P/F) Bit Procedures
3522  *
3523  *		The response frame returned by a TNC depends on the previous command received, as described in the
3524  *		following paragraphs.
3525  *		...
3526  *
3527  *		The next response frame returned to an I frame with the P bit set to "1", received during the information5
3528  *		transfer state, is an RR, RNR or REJ response with the F bit set to "1".
3529  *
3530  *		The next response frame returned to a supervisory command frame with the P bit set to "1", received during
3531  *		the information transfer state, is an RR, RNR or REJ response frame with the F bit set to "1".
3532  *		...
3533  *
3534  *		The P bit is used in conjunction with the timeout recovery condition discussed in Section 4.5.5.
3535  *		When not used, the P/F bit is set to "0".
3536  *
3537  *		6.4.4.1. Implicit Reject (REJ)
3538  *
3539  *		When an I frame is received with a correct FCS but its send sequence number N(S) does not match the current
3540  *		receiver's receive state variable, the frame is discarded. A REJ frame is sent with a receive sequence number
3541  *		equal to one higher than the last correctly received I frame if an uncleared N(S) sequence error condition has not
3542  *		been previously established. The received state variable and poll bit of the discarded frame is checked and acted
3543  *		upon, if necessary.
3544  *		This mode requires no frame queueing and frame resequencing at the receiver. However, because the mode
3545  *		requires transmission of frames that may not be in error, its throughput is not as high as selective reject. This
3546  *		mode is ineffective on systems with long round-trip delays and high data rates.
3547  *
3548  *		6.4.7. Receiving REJ
3549  *
3550  *		After receiving a REJ frame, the transmitting TNC sets its send state variable to the same value as the REJ
3551  *		frame's received sequence number in the control field. The TNC then retransmits any I frame(s) outstanding at
3552  *		the next available opportunity in accordance with the following:
3553  *
3554  *		a) If the TNC is not transmitting at the time and the channel is open, the TNC may begin retransmission of the
3555  *		I frame(s) immediately.
3556  *		b) If the TNC is operating on a full-duplex channel transmitting a UI or S frame when it receives a REJ frame,
3557  *		it may finish sending the UI or S frame and then retransmit the I frame(s).
3558  *		c) If the TNC is operating in a full-duplex channel transmitting another I frame when it receives a REJ frame,
3559  *		it may abort the I frame it was sending and start retransmission of the requested I frames immediately.
3560  *		d) The TNC may send just the one I frame outstanding, or it may send more than the one indicated if more I
3561  *		frames followed the first unacknowledged frame, provided that the total to be sent does not exceed the flowcontrol
3562  *		window (k frames).
3563  *		If the TNC receives a REJ frame with the poll bit set, it responds with either an RR or RNR frame with the
3564  *		final bit set before retransmitting the outstanding I frame(s).
3565  *
3566  *------------------------------------------------------------------------------*/
3567 
rej_frame(ax25_dlsm_t * S,cmdres_t cr,int pf,int nr)3568 static void rej_frame (ax25_dlsm_t *S, cmdres_t cr, int pf, int nr)
3569 {
3570 
3571 	switch (S->state) {
3572 
3573 	  case 	state_0_disconnected:
3574 
3575 	    // states 0 and 2 are very similar with one tiny little difference.
3576 
3577 	    if (cr == cr_cmd) {
3578 	      cmdres_t r = cr_res;	// DM response with F taken from P.
3579 	      int f = pf;
3580 	      int nopid = 0;		// PID is only for I and UI.
3581 
3582 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, r, frame_type_U_DM, f, nopid, NULL, 0);
3583 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
3584 	    }
3585 	    break;
3586 
3587 	  case 	state_1_awaiting_connection:
3588 	  case 	state_5_awaiting_v22_connection:
3589 	    // Do nothing.
3590 	    break;
3591 
3592 	  case 	state_2_awaiting_release:
3593 
3594 	    if (cr == cr_cmd && pf == 1) {
3595 	      cmdres_t r = cr_res;	// DM response with F = 1.
3596 	      int f = 1;
3597 	      int nopid = 0;
3598 
3599 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, r, frame_type_U_DM, f, nopid, NULL, 0);
3600 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
3601 	    }
3602 
3603 // Erratum: We have a disagreement here between original and 2006 version.
3604 // RR, RNR, REJ, SREJ responses would fall under "all other primitives."
3605 // In the original, we simply ignore it and stay in state 2.
3606 // The 2006 version, page 94,  says go into "1 awaiting connection" state.
3607 // That makes no sense to me.
3608 
3609 	    break;
3610 
3611 	  case 	state_3_connected:
3612 
3613 	    S->peer_receiver_busy = 0;
3614 
3615 // Receipt of the REJ "frame" (either command or response) causes us to
3616 // start resending I frames at the specified number.
3617 
3618 // I think there are 3 possibilities here:
3619 // Response is used when incoming I frame processing detects one is missing.
3620 // In this case, F is copied from the I frame P bit.  I don't think we care here.
3621 // Command with P=1 is used during timeout recovery.
3622 // The rule is that we are supposed to send a response with F=1 for I, RR, RNR, or REJ with P=1.
3623 
3624 	    check_need_for_response (S, frame_type_S_REJ, cr, pf);
3625 
3626 	    if (is_good_nr(S,nr)) {
3627 	      SET_VA(nr);
3628 	      STOP_T1;
3629 	      STOP_T3;
3630 	      select_t1_value(S);
3631 
3632 	      invoke_retransmission (S, nr);
3633 
3634 // my addition
3635 // Erratum: We sent I frame(s) and want to timeout if no ack comes back.
3636 // We also sent N(R) so no need for extra RR at the end only for that.
3637 
3638 // We ran into cases where I frame(s) would be resent but lost.
3639 // T1 was stopped so we just waited and waited and waited instead of trying again.
3640 // I added the following after each invoke_retransmission.
3641 // This seems clearer than hiding the timer stuff inside of it.
3642 
3643 	      // T3 is already stopped.
3644 	      START_T1;
3645 	      S->acknowledge_pending = 0;
3646 	    }
3647 	    else {
3648 	      nr_error_recovery (S);
3649 	      enter_new_state (S, S->modulo == 128 ? state_5_awaiting_v22_connection : state_1_awaiting_connection, __func__, __LINE__);
3650 	    }
3651 	    break;
3652 
3653 	  case 	state_4_timer_recovery:
3654 
3655 	    S->peer_receiver_busy = 0;
3656 
3657 	    if (cr == cr_res && pf == 1) {
3658 
3659 	      STOP_T1;
3660 	      select_t1_value(S);
3661 
3662 	      if (is_good_nr(S,nr)) {
3663 
3664 	        SET_VA(nr);
3665 	        if (S->vs == S->va) {
3666 	          START_T3;
3667 	          SET_RC(0);			// My enhancement.  See Erratum note in select_t1_value.
3668 	          enter_new_state (S, state_3_connected, __func__, __LINE__);
3669 	        }
3670 	        else {
3671 	          invoke_retransmission (S, nr);
3672 // my addition.
3673 // Erratum: We sent I frame(s) and want to timeout if no ack comes back.
3674 // We also sent N(R) so no need for extra RR at the end only for that.
3675 
3676 	          STOP_T3;
3677 	          START_T1;
3678 	          S->acknowledge_pending = 0;
3679 	        }
3680 	      }
3681 	      else {
3682 	        nr_error_recovery (S);
3683 	        enter_new_state (S, S->modulo == 128 ? state_5_awaiting_v22_connection : state_1_awaiting_connection, __func__, __LINE__);
3684 	      }
3685 	    }
3686 	    else {
3687 	      if (cr == cr_cmd && pf == 1) {
3688 	        int f = 1;
3689 	        enquiry_response (S, frame_type_S_REJ, f);
3690 	      }
3691 
3692 	      if (is_good_nr(S,nr)) {
3693 
3694 	        SET_VA(nr);
3695 
3696 	        if (S->vs != S->va) {
3697 	          // Observation:  RR/RNR state 4 is identical but it doesn't have invoke_retransmission here.
3698 	          invoke_retransmission (S, nr);
3699 // my addition.
3700 // Erratum: We sent I frame(s) and want to timeout if no ack comes back.
3701 // We also sent N(R) so no need for extra RR at the end only for that.
3702 
3703 	          STOP_T3;
3704 	          START_T1;
3705 	          S->acknowledge_pending = 0;
3706 	        }
3707 
3708 	      }
3709 	      else {
3710 	        nr_error_recovery (S);
3711 	        enter_new_state (S, S->modulo == 128 ? state_5_awaiting_v22_connection : state_1_awaiting_connection, __func__, __LINE__);
3712 	      }
3713 	    }
3714 	    break;
3715 	}
3716 
3717 } /* end rej_frame */
3718 
3719 
3720 /*------------------------------------------------------------------------------
3721  *
3722  * Name:	srej_frame
3723  *
3724  * Purpose:	Process SREJ Response.
3725  *
3726  * Inputs:	S	- Data Link State Machine.
3727  *		cr	- Is this command or response?
3728  *		f	- Final bit.   When set, it is ack-ing up thru N(R)-1
3729  *		nr	- N(R) from the frame.  Peer has asked for a resend of I frame with this N(S).
3730  *		info	- Information field, used only for Multi-SREJ
3731  *		info_len - Information field length, bytes.
3732  *
3733  * Description:	4.3.2.4. Selective Reject (SREJ) Command and Response
3734  *
3735  *		The selective reject, SREJ, frame is used by the receiving TNC to request retransmission of the single I frame
3736  *		numbered N(R). If the P/F bit in the SREJ frame is set to "1", then I frames numbered up to N(R)-1 inclusive are
3737  *		considered as acknowledged. However, if the P/F bit in the SREJ frame is set to "0", then the N(R) of the SREJ
3738  *		frame does not indicate acknowledgement of I frames.
3739  *
3740  *		Each SREJ exception condition is cleared (reset) upon receipt of the I frame with an N(S) equal to the N(R)
3741  *		of the SREJ frame.
3742  *
3743  *		A receiving TNC may transmit one or more SREJ frames, each containing a different N(R) with the P bit set
3744  *		to "0", before one or more earlier SREJ exception conditions have been cleared. However, a SREJ is not
3745  *		transmitted if an earlier REJ exception condition has not been cleared as indicated in Section 4.5.4. (To do so
3746  *		would request retransmission of an I frame that would be retransmitted by the REJ operation.) Likewise, a REJ
3747  *		frame is not transmitted if one or more earlier SREJ exception conditions have not been cleared as indicated in
3748  *		Section 4.5.4.
3749  *
3750  *		I frames transmitted following the I frame indicated by the SREJ frame are not retransmitted as the result of
3751  *		receiving a SREJ frame. Additional I frames awaiting initial transmission may be transmitted following the
3752  *		retransmission of the specific I frame requested by the SREJ frame.
3753  *
3754  * Erratum:	The section above always refers to SREJ "frames."  There doesn't seem to be any clue about when
3755  *		command vs. response would be used.  When we look in the flow charts, we see that we generate only
3756  *		responses but the code is there to process command and response slightly differently.
3757  *
3758  * Description:	4.4.4. Selective Reject (SREJ) Recovery
3759  *
3760  *		The SREJ command/response initiates more-efficient error recovery by requesting the retransmission of a
3761  *		single I frame following the detection of a sequence error. This is an advancement over the earlier versions in
3762  *		which the requested I frame was retransmitted togther with all additional I frames subsequently transmitted and
3763  *		successfully received.
3764  *
3765  *		When a TNC sends one or more SREJ commands, each with the P bit set to "0" or "1", or one or more SREJ
3766  *		responses, each with the F bit set to "0", and the "sent SREJ" conditions are not cleared when the TNC is ready
3767  *		to issue the next response frame with the F bit set to "1", the TNC sends a SREJ response with the F bit set to "1",
3768  *		with the same N(R) as the oldest unresolved SREJ frame.
3769  *
3770  *		Because an I or S format frame with the F bit set to "1" can cause checkpoint retransmission, a TNC does not
3771  *		send SREJ frames until it receives at least one in-sequence I frame, or it perceives by timeout that the checkpoint
3772  *		retransmission will not be initiated at the remote TNC.
3773  *
3774  *		With respect to each direction of transmission on the data link, one or more "sent SREJ" exception conditions
3775  *		from a TNC to another TNC may be established at a time. A "sent SREJ" exception condition is cleared when
3776  *		the requested I frame is received.
3777  *
3778  *		The SREJ frame may be repeated when a TNC perceives by timeout that a requested I frame will not be
3779  *		received, because either the requested I frame or the SREJ frame was in error or lost.
3780  *
3781  *		When appropriate, a TNC receiving one or more SREJ frames initiates retransmission of the individual I
3782  *		frames indicated by the N(R) contained in each SREJ frame. After having retransmitted the above frames, new
3783  *		I frames are transmitted later if they become available.
3784  *
3785  *		When a TNC receives and acts on one or more SREJ commands, each with the P bit set to "0", or an SREJ
3786  *		command with the P bit set to "1", or one or more SREJ responses each with the F bit set to "0", it disables any
3787  *		action on the next SREJ response frame if that SREJ frame has the F bit set to "1" and has the same N(R) (i.e.,
3788  *		the same value and the same numbering cycle) as a previously actioned SREJ frame, and if the resultant
3789  *		retransmission was made following the transmission of the P bit set to a "1".
3790  *		When the SREJ mechanism is used, the receiving station retains correctly-received I frames and delivers
3791  *		them to the higher layer in sequence number order.
3792  *
3793  *
3794  *		6.4.4.2. Selective Reject (SREJ)
3795  *
3796  *		When an I frame is received with a correct FCS but its send sequence number N(S) does not match the current
3797  *		receiver's receive state variable, the frame is retained. SREJ frames are sent with a receive sequence number
3798  *		equal to the value N(R) of the missing frame, and P=1 if an uncleared SREJ condition has not been previously
3799  *		established. If an SREJ condition is already pending, an SREJ will be sent with P=0. The received state variable
3800  *		and poll bit of the received frame are checked and acted upon, if necessary.
3801  *
3802  *		This mode requires frame queueing and frame resequencing at the receiver. The holding of frames can
3803  *		consume precious buffer space, especially if the user device has limited memory available and several active
3804  *		links are operational.
3805  *
3806  *
3807  *		6.4.4.3. Selective Reject-Reject (SREJ/REJ)
3808  *
3809  *		When an I frame is received with a correct FCS but its send sequence number N(S) does not match the current
3810  *		receiver's receive state variable, and if N(S) indicates 2 or more frames are missing, a REJ frame is transmitted.
3811  *		All subsequently received frames are discarded until the lost frame is correctly received. If only one frame is
3812  *		missing, a SREJ frame is sent with a receive sequence number equal to the value N(R) of the missing frame. The
3813  *		received state variable and poll bit of the received frame are checked and acted upon. If another frame error
3814  *		occurs prior to recovery of the SREJ condition, the receiver saves all frames received after the first errored frame
3815  *		and discards frames received after the second errored frame until the first errored frame is recovered. Then, a
3816  *		REJ is issued to recover the second errored frame and all subsequent discarded frames.
3817  *
3818  * X.25:	States that SREJ is only response.  I'm following that and it simplifies matters.
3819  *
3820  * X.25 2.4.6.6.1 & 2.4.6.6.2 make a distinction between F being 0 or 1 besides copying N(R) into V(A).
3821  *		They talk about sending a poll under some conditions.
3822  *		We don't do that here.  It seems to work reliably so leave well enough alone.
3823  *
3824  *------------------------------------------------------------------------------*/
3825 
3826 static int resend_for_srej (ax25_dlsm_t *S, int nr, unsigned char *info, int info_len);
3827 
srej_frame(ax25_dlsm_t * S,cmdres_t cr,int f,int nr,unsigned char * info,int info_len)3828 static void srej_frame (ax25_dlsm_t *S, cmdres_t cr, int f, int nr, unsigned char *info, int info_len)
3829 {
3830 
3831 	switch (S->state) {
3832 
3833 	  case 	state_0_disconnected:
3834 
3835 	    break;
3836 
3837 	  case 	state_1_awaiting_connection:
3838 	  case 	state_5_awaiting_v22_connection:
3839 	    // Do nothing.
3840 
3841 	    // Erratum: The original spec said stay in same state.  (Seems correct.)
3842 	    // 2006 revision shows state 5 transitioning into 1.  I think that is wrong.
3843 	    // probably a cut-n-paste from state 1 to 5 and that part not updated.
3844 	    break;
3845 
3846 	  case 	state_2_awaiting_release:
3847 
3848 	    // Erratum: Flow chart says send DM(F=1) for "I, RR, RNR, REJ, SREJ commands" and P=1.
3849 	    // It is wrong for two reasons.
3850 	    // If SREJ was a command, the P flag has a different meaning than the other Supervisory commands.
3851 	    // It means ack reception of frames up thru N(R)-1;  it is not a poll to get a response.
3852 
3853 	    // Based on X.25, I don't think SREJ can be a command.
3854 	    // It should say, "I, RR, RNR, REJ commands"
3855 
3856 	    // Erratum: We have a disagreement here between original and 2006 version.
3857 	    // RR, RNR, REJ, SREJ responses would fall under "all other primitives."
3858 	    // In the original, we simply ignore it and stay in state 2.
3859 	    // The 2006 version, page 94,  says go into "1 awaiting connection" state.
3860 	    // That makes no sense to me.
3861 
3862 	    break;
3863 
3864 	  case 	state_3_connected:
3865 
3866 	    S->peer_receiver_busy = 0;
3867 
3868 	    // Erratum:  Flow chart has "check need for response here."
3869 
3870 	    // check_need_for_response() does the following:
3871 	    // - for command & P=1, send RR or RNR.
3872 	    // - for response & F=1, error A.
3873 
3874 	   // SREJ can only be a response.  We don't want to produce an error when F=1.
3875 
3876 	    if (is_good_nr(S,nr)) {
3877 
3878 	      if (f) {
3879 	        SET_VA(nr);
3880 	      }
3881 	      STOP_T1;
3882 	      START_T3;
3883 	      select_t1_value(S);
3884 
3885 
3886 	      int num_resent = resend_for_srej (S, nr, info, info_len);
3887 	      if (num_resent) {
3888 
3889 // my addition
3890 // Erratum: We sent I frame(s) and want to timeout if no ack comes back.
3891 // We also sent N(R), from V(R), so no need for extra RR at the end only for that.
3892 
3893 // We would sometimes end up in a situation where T1 was stopped on
3894 // both ends and everyone would wait for the other guy to timeout and do something.
3895 // My solution was to Start T1 after every place we send an I frame if not already there.
3896 
3897 	        STOP_T3;
3898 	        START_T1;
3899 	        S->acknowledge_pending = 0;
3900 	      }
3901 	      // keep same state.
3902 	    }
3903 	    else {
3904 	      nr_error_recovery (S);
3905 	      // Erratum?  Flow chart shows state 1 but that would not be appropriate if modulo is 128.
3906 	      enter_new_state (S, S->modulo == 128 ? state_5_awaiting_v22_connection : state_1_awaiting_connection, __func__, __LINE__);
3907 	    }
3908 	    break;
3909 
3910 	  case 	state_4_timer_recovery:
3911 
3912 	    if (s_debug_timers) {
3913 	      text_color_set(DW_COLOR_ERROR);
3914 	      dw_printf ("state 4 timer recovery, %s %d  nr=%d, f=%d\n", __func__, __LINE__, nr, f);
3915 	    }
3916 
3917 	    S->peer_receiver_busy = 0;
3918 
3919 	    // Erratum:  Original Flow chart has "check need for response here."
3920 	    // The 2006 version correctly removed it.
3921 
3922 	    // check_need_for_response() does the following:
3923 	    // - for command & P=1, send RR or RNR.
3924 	    // - for response & F=1, error A.
3925 
3926 	    // SREJ can only be a response.  We don't want to produce an error when F=1.
3927 
3928 
3929 	    // The flow chart splits into two paths for command/response with a lot of duplication.
3930 	    // Command path has been omitted because SREJ can only be response.
3931 
3932 	    STOP_T1;
3933 	    select_t1_value(S);
3934 
3935 	    if (is_good_nr(S,nr)) {
3936 
3937 	      if (f) {				// f=1 means ack up thru previous sequence.
3938 						// Erratum:  2006 version tests "P".  Original has "F."
3939 	        SET_VA(nr);
3940 
3941 	        if (s_debug_timers) {
3942 	          text_color_set(DW_COLOR_ERROR);
3943 	          dw_printf ("state 4 timer recovery, %s %d    set v(a)= %d\n", __func__, __LINE__, S->va);
3944 	        }
3945 	      }
3946 
3947 	      if (S->vs == S->va) {		// ACKs all caught up.  Back to state 3.
3948 
3949 			// Erratum:  I think this is unreachable.
3950 			// If the other side is asking for I frame with sequence X, it must have
3951 			// received X+1 or later.  That means my V(S) must be X+2 or greater.
3952 			// So, I don't think we can ever have V(S) == V(A) here.
3953 			// If we were to remove the 'if' test and true part, case 4 would then
3954 			// be exactly the same as state 4.  We need to rely on RR to get us
3955 			// back to state 3.
3956 
3957 	        START_T3;
3958 	        SET_RC(0);			// My enhancement.  See Erratum note in select_t1_value.
3959 	        enter_new_state (S, state_3_connected, __func__, __LINE__);
3960 
3961 	        // text_color_set(DW_COLOR_ERROR);
3962 	        // dw_printf ("state 4 timer recovery, go to state 3 \n");
3963 	      }
3964 	      else {
3965 
3966 // Erratum: Difference between two AX.25 revisions.
3967 
3968 #if 1	// This is from the original protocol spec.
3969 	// Resend I frame with N(S) equal to the N(R) in the SREJ.
3970 
3971 	        //text_color_set(DW_COLOR_ERROR);
3972 	        //dw_printf ("state 4 timer recovery, send requested frame(s) \n");
3973 
3974 	        int num_resent = resend_for_srej (S, nr, info, info_len);
3975 	        if (num_resent) {
3976 // my addition
3977 // Erratum: We sent I frame(s) and want to timeout if no ack comes back.
3978 // We also sent N(R), from V(R), so no need for extra RR at the end only for that.
3979 
3980 // We would sometimes end up in a situation where T1 was stopped on
3981 // both ends and everyone would wait for the other guy to timeout and do something.
3982 // My solution was to Start T1 after every place we send an I frame if not already there.
3983 
3984 	          STOP_T3;
3985 	          START_T1;
3986 	          S->acknowledge_pending = 0;
3987 	        }
3988 #else	// Erratum!  This is from the 2006 revision.
3989 	// We should resend only the single requested I frame.
3990 	// I think there was a cut-n-paste from the REJ flow chart and this particular place did not get changed.
3991 
3992 	        invoke_retransmission(S);
3993 #endif
3994 	      }
3995 	    }
3996 	    else {
3997 	      nr_error_recovery (S);
3998 	      enter_new_state (S, S->modulo == 128 ? state_5_awaiting_v22_connection : state_1_awaiting_connection, __func__, __LINE__);
3999 	    }
4000 	    break;
4001 	}
4002 
4003 } /* end srej_frame */
4004 
4005 /*------------------------------------------------------------------------------
4006  *
4007  * Name:	resend_for_srej
4008  *
4009  * Purpose:	Resend the I frame(s) specified in SREJ response.
4010  *
4011  * Inputs:	S	- Data Link State Machine.
4012  *		nr	- N(R) from the frame.  Peer has asked for a resend of I frame with this N(S).
4013  *		info	- Information field, might contain additional sequence numbers for Multi-SREJ.
4014  *		info_len - Information field length, bytes.
4015  *
4016  * Returns:	Number of frames sent.  Should be at least one.
4017  *
4018  * Description:	Simply resend requested frame(s).
4019  *		The calling context will worry about the F bit and other state stuff.
4020  *
4021  *------------------------------------------------------------------------------*/
4022 
resend_for_srej(ax25_dlsm_t * S,int nr,unsigned char * info,int info_len)4023 static int resend_for_srej (ax25_dlsm_t *S, int nr, unsigned char *info, int info_len)
4024 {
4025 	cmdres_t cr = cr_cmd;
4026 	int i_frame_nr = S->vr;
4027 	int i_frame_ns = nr;
4028 	int p = 0;
4029 	int num_resent = 0;
4030 
4031 	// Resend I frame with N(S) equal to the N(R) in the SREJ.
4032 	// Additional sequence numbers can be in optional information part.
4033 
4034 	cdata_t *txdata = S->txdata_by_ns[i_frame_ns];
4035 
4036 	if (txdata != NULL) {
4037 	  packet_t pp = ax25_i_frame (S->addrs, S->num_addr, cr, S->modulo, i_frame_nr, i_frame_ns, p, txdata->pid, (unsigned char *)(txdata->data), txdata->len);
4038 	  // dw_printf ("calling lm_data_request for I frame, %s line %d\n", __func__, __LINE__);
4039 	  lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
4040 	  num_resent++;
4041 	}
4042 	else {
4043 	  text_color_set(DW_COLOR_ERROR);
4044 	  dw_printf ("Stream %d: INTERNAL ERROR for SREJ.  I frame for N(S)=%d is not available.\n", S->stream_id, i_frame_ns);
4045 	}
4046 
4047 // Multi-SREJ if there is an information part.
4048 
4049 	int j;
4050 	for (j = 0; j < info_len; j++) {
4051 
4052 		// We can have a single sequence number like this:
4053 		//    	xxx00000	(mod 8)
4054 		//	xxxxxxx0	(mod 128)
4055 		// or we can have span (mod 128 only) like this, with the first and last:
4056 		//	xxxxxxx1
4057 		//	xxxxxxx1
4058 		//
4059 		// Note that the sequence number is shifted left by one
4060 		// and if the LSB is set, there should be two adjacent bytes
4061 		// with it set.
4062 
4063 	  if (S->modulo == 8) {
4064 	    i_frame_ns = (info[j] >> 5) & 0x07;	// no provision for span.
4065 	  }
4066 	  else {
4067 	    i_frame_ns = (info[j] >> 1) & 0x7f;	// TODO: test LSB and possible loop here.
4068 	  }
4069 
4070 	  txdata = S->txdata_by_ns[i_frame_ns];
4071 	  if (txdata != NULL) {
4072 	    packet_t pp = ax25_i_frame (S->addrs, S->num_addr, cr, S->modulo, i_frame_nr, i_frame_ns, p, txdata->pid, (unsigned char *)(txdata->data), txdata->len);
4073 	    lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
4074 	    num_resent++;
4075 	  }
4076 	  else {
4077 	    text_color_set(DW_COLOR_ERROR);
4078 	    dw_printf ("Stream %d: INTERNAL ERROR for Multi-SREJ.  I frame for N(S)=%d is not available.\n", S->stream_id, i_frame_ns);
4079 	  }
4080 	}
4081 	return (num_resent);
4082 
4083 } /* end resend_for_srej */
4084 
4085 
4086 
4087 
4088 /*------------------------------------------------------------------------------
4089  *
4090  * Name:	sabm_e_frame
4091  *
4092  * Purpose:	Process SABM or SABME Frame.
4093  *
4094  * Inputs:	S	- Data Link State Machine.
4095  *
4096  *		extended - True for SABME.  False for SABM.
4097  *
4098  *		p	- Poll bit.   TODO:  What does it mean in this case?
4099  *
4100  * Description: This is a request, from the other end, to establish a connection.
4101  *
4102  *		4.3.3.1. Set Asynchronous Balanced Mode (SABM) Command
4103  *
4104  *		The SABM command places two Terminal Node Comtrollers (TNC) in the asynchronous balanced mode
4105  *		(modulo 8). This a balanced mode of operation in which both devices are treated as equals or peers.
4106  *
4107  *		Information fields are not allowed in SABM commands. Any outstanding I frames left when the SABM
4108  *		command is issued remain unacknowledged.
4109  *
4110  *		The TNC confirms reception and acceptance of a SABM command by sending a UA response frame at the
4111  *		earliest opportunity. If the TNC is not capable of accepting a SABM command, it responds with a DM frame if
4112  *		possible.
4113  *
4114  *		4.3.3.2. Set Asynchronous Balanced Mode Extended (SABME) Command
4115  *
4116  *		The SABME command places two TNCs in the asynchronous balanced mode extended (modulo 128). This
4117  *		is a balanced mode of operation in which both devices are treated as equals or peers.
4118  *		Information fields are not allowed in SABME commands. Any outstanding I frames left when the SABME
4119  *		command is issued remains unacknowledged.
4120  *
4121  *		The TNC confirms reception and acceptance of a SABME command by sending a UA response frame at the
4122  *		earliest opportunity. If the TNC is not capable of accepting a SABME command, it responds with a DM frame.
4123  *
4124  *		A TNC that uses a version of AX.25 prior to v2.2 responds with a FRMR. ** (see note below)
4125  *
4126  *
4127  * Note:	The KPC-3+, which does not appear to support v2.2, responds with a DM.
4128  *		The 2.0 spec, section 2.3.4.3.5, states, "While a DXE is in the disconnected mode, it will respond
4129  *		to any command other than a SABM or UI frame with a DM response with the P/F bit set to 1."
4130  *		I think it is a bug in the KPC but I can see how someone might implement it that way.
4131  *		However, another place says FRMR is sent for any unrecognized frame type.  That would seem to take priority.
4132  *
4133  *------------------------------------------------------------------------------*/
4134 
sabm_e_frame(ax25_dlsm_t * S,int extended,int p)4135 static void sabm_e_frame (ax25_dlsm_t *S, int extended, int p)
4136 {
4137 
4138 	switch (S->state) {
4139 
4140 	  case 	state_0_disconnected:
4141 
4142 	    // Flow chart has decision: "Able to establish?"
4143 	    // I think this means, are we willing to accept connection requests?
4144 	    // We are always willing to accept connections.
4145 	    // Of course, we wouldn't get this far if local callsigns were not "registered."
4146 
4147 	    if (extended) {
4148 	      set_version_2_2 (S);
4149 	    }
4150 	    else {
4151 	      set_version_2_0 (S);
4152 	    }
4153 
4154 	    cmdres_t res = cr_res;
4155 	    int f = p;			// I don't understand the purpose of "P" in SABM/SABME
4156 					// but we dutifully copy it into "F" for the UA response.
4157 	    int nopid = 0;		// PID is only for I and UI.
4158 
4159 	    packet_t pp = ax25_u_frame (S->addrs, S->num_addr, res, frame_type_U_UA, f, nopid, NULL, 0);
4160 	    lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
4161 
4162 	    clear_exception_conditions (S);
4163 
4164 	    SET_VS(0);
4165 	    SET_VA(0);
4166 	    SET_VR(0);
4167 
4168 	    text_color_set(DW_COLOR_INFO);
4169 	    dw_printf ("Stream %d: Connected to %s.  (%s)\n", S->stream_id, S->addrs[PEERCALL], extended ? "v2.2" : "v2.0");
4170 
4171 	    // dl connect indication - inform the client app.
4172 	    int incoming = 1;
4173 	    server_link_established (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], incoming);
4174 
4175 	    INIT_T1V_SRT;
4176 
4177 	    START_T3;
4178 	    SET_RC(0);			// My enhancement.  See Erratum note in select_t1_value.
4179 	    enter_new_state (S, state_3_connected, __func__, __LINE__);
4180 	    break;
4181 
4182 	  case 	state_1_awaiting_connection:
4183 
4184 	    // Don't combine with state 5.  They are slightly different.
4185 
4186 	    if (extended) {		// SABME - respond with DM, enter state 5.
4187 	      cmdres_t res = cr_res;
4188 	      int f = p;
4189 	      int nopid = 0;
4190 
4191 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, res, frame_type_U_DM, f, nopid, NULL, 0);
4192 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
4193 	      enter_new_state (S, state_5_awaiting_v22_connection, __func__, __LINE__);
4194 	    }
4195 	    else {			// SABM - respond with UA.
4196 
4197 	      // Erratum!  2006 version shows SAMBE twice for state 1.
4198 	      // First one should be SABM in last page of Figure C4.2
4199 	      // Original appears to be correct.
4200 
4201 	      cmdres_t res = cr_res;
4202 	      int f = p;
4203 	      int nopid = 0;
4204 
4205 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, res, frame_type_U_UA, f, nopid, NULL, 0);
4206 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
4207 	      // stay in state 1.
4208 	    }
4209 	    break;
4210 
4211 	  case 	state_5_awaiting_v22_connection:
4212 
4213 	    if (extended) {		// SABME - respond with UA
4214 	      cmdres_t res = cr_res;
4215 	      int f = p;
4216 	      int nopid = 0;
4217 
4218 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, res, frame_type_U_UA, f, nopid, NULL, 0);
4219 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
4220 	      // stay in state 5
4221 	    }
4222 	    else {			// SABM, respond with UA, enter state 1
4223 	      cmdres_t res = cr_res;
4224 	      int f = p;
4225 	      int nopid = 0;
4226 
4227 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, res, frame_type_U_UA, f, nopid, NULL, 0);
4228 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
4229 	      enter_new_state (S, state_1_awaiting_connection, __func__, __LINE__);
4230 	    }
4231 	    break;
4232 
4233 	  case 	state_2_awaiting_release:
4234 
4235 	    // Erratum! Flow charts don't list SABME for state 2.
4236 	    // Probably just want to treat it the same as SABM here.
4237 
4238 	    {
4239 	      cmdres_t res = cr_res;
4240 	      int f = p;
4241 	      int nopid = 0;
4242 
4243 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, res, frame_type_U_DM, f, nopid, NULL, 0);
4244 	      lm_data_request (S->chan, TQ_PRIO_0_HI, pp);	// expedited
4245 	      // stay in state 2.
4246 	    }
4247 	    break;
4248 
4249 	  case 	state_3_connected:
4250 	  case 	state_4_timer_recovery:
4251 
4252 	    {
4253 	      cmdres_t res = cr_res;
4254 	      int f = p;
4255 	      int nopid = 0;
4256 
4257 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, res, frame_type_U_UA, f, nopid, NULL, 0);
4258 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
4259 
4260 	      // State 3 & 4 handling are the same except for this one difference.
4261 	      if (S->state == state_4_timer_recovery) {
4262 	        if (extended) {
4263 	          set_version_2_2 (S);
4264 	        }
4265 	        else {
4266 	          set_version_2_0 (S);
4267 	        }
4268 	      }
4269 
4270 	      clear_exception_conditions (S);
4271 	      if (s_debug_protocol_errors) {
4272 	        text_color_set(DW_COLOR_ERROR);
4273 	        dw_printf ("Stream %d: AX.25 Protocol Error F: Data Link reset; i.e. SABM(e) received in state %d.\n", S->stream_id, S->state);
4274 	      }
4275 	      if (S->vs != S->va) {
4276 	        discard_i_queue (S);
4277 	        // dl connect indication
4278 	        int incoming = 1;
4279 	        server_link_established (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], incoming);
4280 	      }
4281 	      STOP_T1;
4282 	      START_T3;
4283 	      SET_VS(0);
4284 	      SET_VA(0);
4285 	      SET_VR(0);
4286 	      SET_RC(0);			// My enhancement.  See Erratum note in select_t1_value.
4287 	      enter_new_state (S, state_3_connected, __func__, __LINE__);
4288 	    }
4289 	    break;
4290 	}
4291 
4292 } /* end sabm_e_frame */
4293 
4294 
4295 
4296 /*------------------------------------------------------------------------------
4297  *
4298  * Name:	disc_frame
4299  *
4300  * Purpose:	Process DISC command.
4301  *
4302  * Inputs:	S	- Data Link State Machine.
4303  *		p	- Poll bit.
4304  *
4305  * Description:	4.3.3.3. Disconnect (DISC) Command
4306  *
4307  *		The DISC command terminates a link session between two stations. An information field is not permitted in
4308  *		a DISC command frame.
4309  *
4310  *		Prior to acting on the DISC frame, the receiving TNC confirms acceptance of the DISC by issuing a UA
4311  *		response frame at its earliest opportunity. The TNC sending the DISC enters the disconnected state when it
4312  *		receives the UA response.
4313  *
4314  *		Any unacknowledged I frames left when this command is acted upon remain unacknowledged.
4315  *
4316  *
4317  *		6.3.4. Link Disconnection
4318  *
4319  *		While in the information-transfer state, either TNC may indicate a request to disconnect the link by transmitting
4320  *		a DISC command frame and starting timer T1.
4321  *
4322  *		After receiving a valid DISC command, the TNC sends a UA response frame and enters the disconnected
4323  *		state. After receiving a UA or DM response to a sent DISC command, the TNC cancels timer T1 and enters the
4324  *		disconnected state.
4325  *
4326  *		If a UA or DM response is not correctly received before T1 times out, the DISC frame is sent again and T1 is
4327  *		restarted. If this happens N2 times, the TNC enters the disconnected state.
4328  *
4329  *------------------------------------------------------------------------------*/
4330 
disc_frame(ax25_dlsm_t * S,int p)4331 static void disc_frame (ax25_dlsm_t *S, int p)
4332 {
4333 
4334 	switch (S->state) {
4335 
4336 	  case 	state_0_disconnected:
4337 	  case 	state_1_awaiting_connection:
4338 	  case 	state_5_awaiting_v22_connection:
4339 
4340 	    {
4341 	      cmdres_t res = cr_res;
4342 	      int f = p;
4343 	      int nopid = 0;
4344 
4345 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, res, frame_type_U_DM, f, nopid, NULL, 0);
4346 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
4347 	    }
4348 	    // keep current state, 0, 1, or 5.
4349 	    break;
4350 
4351 	  case 	state_2_awaiting_release:
4352 
4353 	    {
4354 	      cmdres_t res = cr_res;
4355 	      int f = p;
4356 	      int nopid = 0;
4357 
4358 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, res, frame_type_U_UA, f, nopid, NULL, 0);
4359 	      lm_data_request (S->chan, TQ_PRIO_0_HI, pp);		// expedited
4360 	    }
4361 	    // keep current state, 2.
4362 	    break;
4363 
4364 	  case 	state_3_connected:
4365 	  case 	state_4_timer_recovery:
4366 
4367 	    {
4368 	      discard_i_queue (S);
4369 
4370 	      cmdres_t res = cr_res;
4371 	      int f = p;
4372 	      int nopid = 0;
4373 
4374 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, res, frame_type_U_UA, f, nopid, NULL, 0);
4375 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
4376 
4377 	      // dl disconnect *indication*
4378 	      text_color_set(DW_COLOR_INFO);
4379 	      dw_printf ("Stream %d: Disconnected from %s.\n", S->stream_id, S->addrs[PEERCALL]);
4380 	      server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
4381 
4382 	      STOP_T1;
4383 	      STOP_T3;
4384 	      enter_new_state (S, state_0_disconnected, __func__, __LINE__);
4385 	    }
4386 	    break;
4387 	}
4388 
4389 } /* end disc_frame */
4390 
4391 
4392 
4393 /*------------------------------------------------------------------------------
4394  *
4395  * Name:	dm_frame
4396  *
4397  * Purpose:	Process DM Response Frame.
4398  *
4399  * Inputs:	S	- Data Link State Machine.
4400  *		f	- Final bit.
4401  *
4402  * Description:	4.3.3.1. Set Asynchronous Balanced Mode (SABM) Command
4403  *
4404  *		The TNC confirms reception and acceptance of a SABM command by sending a UA response frame at the
4405  *		earliest opportunity. If the TNC is not capable of accepting a SABM command, it responds with a DM frame if
4406  *		possible.
4407  *
4408  *		The TNC confirms reception and acceptance of a SABME command by sending a UA response frame at the
4409  *		earliest opportunity. If the TNC is not capable of accepting a SABME command, it responds with a DM frame.
4410  *
4411  *		A TNC that uses a version of AX.25 prior to v2.2 responds with a FRMR.
4412  *		( I think the KPC-3+ has a bug - it replys with DM - WB2OSZ )
4413  *
4414  *		4.3.3.5. Disconnected Mode (DM) Response
4415  *
4416  *		The disconnected mode response is sent whenever a TNC receives a frame other than a SABM(E) or UI
4417  *		frame while in a disconnected mode. The disconnected mode response also indicates that the TNC cannot
4418  *		accept a connection at the moment. The DM response does not have an information field.
4419  *		Whenever a SABM(E) frame is received and it is determined that a connection is not possible, a DM frame is
4420  *		sent. This indicates that the called station cannot accept a connection at that time.
4421  *		While a TNC is in the disconnected mode, it responds to any command other than a SABM(E) or UI frame
4422  *		with a DM response with the P/F bit set to "1".
4423  *
4424  *		4.3.3.6. Unnumbered Information (UI) Frame
4425  *
4426  *		A received UI frame with the P bit set causes a response to be transmitted. This response is a DM frame when
4427  *		in the disconnected state, or an RR (or RNR, if appropriate) frame in the information transfer state.
4428  *
4429  *		6.3.1. AX.25 Link Connection Establishment
4430  *
4431  *		If the distant TNC receives a SABM command and cannot enter the indicated state, it sends a DM frame.
4432  *		When the originating TNC receives a DM response to its SABM(E) frame, it cancels its T1 timer and does
4433  *		not enter the information-transfer state.
4434  *
4435  *		6.3.4. Link Disconnection
4436  *
4437  *		After receiving a valid DISC command, the TNC sends a UA response frame and enters the disconnected
4438  *		state. After receiving a UA or DM response to a sent DISC command, the TNC cancels timer T1 and enters the
4439  *		disconnected state.
4440  *
4441  *		6.5. Resetting Procedure
4442  *
4443  *		If a DM response is received, the TNC enters the disconnected state and stops timer T1. If timer T1 expires
4444  *		before a UA or DM response frame is received, the SABM(E) is retransmitted and timer T1 restarted. If timer T1
4445  *		expires N2 times, the TNC enters the disconnected state. Any previously existing link conditions are cleared.
4446  *		Other commands or responses received by the TNC before completion of the reset procedure are discarded.
4447  *
4448  * Erratum:	The flow chart shows the same behavior for states 1 and 5.
4449  *		For state 5, I think we should treat DM the same as FRMR.
4450  *
4451  *------------------------------------------------------------------------------*/
4452 
4453 
dm_frame(ax25_dlsm_t * S,int f)4454 static void dm_frame (ax25_dlsm_t *S, int f)
4455 {
4456 	switch (S->state) {
4457 
4458 	  case 	state_0_disconnected:
4459 	    // Do nothing.
4460 	    break;
4461 
4462 	  case 	state_1_awaiting_connection:
4463 
4464 	    if (f == 1) {
4465 	      discard_i_queue (S);
4466 	      // dl disconnect *indication*
4467 	      text_color_set(DW_COLOR_INFO);
4468 	      dw_printf ("Stream %d: Disconnected from %s.\n", S->stream_id, S->addrs[PEERCALL]);
4469 	      server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
4470 	      STOP_T1;
4471 	      enter_new_state (S, state_0_disconnected, __func__, __LINE__);
4472 	    }
4473 	    else {
4474 	      // keep current state.
4475 	    }
4476 	    break;
4477 
4478 	  case 	state_2_awaiting_release:
4479 
4480 	    if (f == 1) {
4481 
4482 	      // Erratum! Original flow chart, page 91, shows DL-CONNECT confirm.
4483 	      // It should clearly be DISconnect rather than Connect.
4484 
4485 	      // 2006 has DISCONNECT *Indication*.
4486 	      // Should it be indication or confirm?  Not sure.
4487 
4488 	      // dl disconnect *confirm*
4489 	      text_color_set(DW_COLOR_INFO);
4490 	      dw_printf ("Stream %d: Disconnected from %s.\n", S->stream_id, S->addrs[PEERCALL]);
4491 	      server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
4492 	      STOP_T1;
4493 	      enter_new_state (S, state_0_disconnected, __func__, __LINE__);
4494 	    }
4495 	    else {
4496 	      // keep current state.
4497 	    }
4498 	    break;
4499 
4500 	  case 	state_3_connected:
4501 	  case 	state_4_timer_recovery:
4502 
4503 	    if (s_debug_protocol_errors) {
4504 	      text_color_set(DW_COLOR_ERROR);
4505 	      dw_printf ("Stream %d: AX.25 Protocol Error E: DM received in state %d.\n", S->stream_id, S->state);
4506 	    }
4507 	    // dl disconnect *indication*
4508 	    text_color_set(DW_COLOR_INFO);
4509 	    dw_printf ("Stream %d: Disconnected from %s.\n", S->stream_id, S->addrs[PEERCALL]);
4510 	    server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
4511 	    discard_i_queue (S);
4512 	    STOP_T1;
4513 	    STOP_T3;
4514 	    enter_new_state (S, state_0_disconnected, __func__, __LINE__);
4515 	    break;
4516 
4517 	  case 	state_5_awaiting_v22_connection:
4518 
4519 #if 0
4520 	    // Erratum: The flow chart says we should do this.
4521 	    // I'm not saying it is wrong.  I just found it necessary to change this
4522 	    // to work around an apparent bug in a popular hardware TNC.
4523 
4524 	    if (f == 1) {
4525 	      discard_i_queue (S);
4526 	      // dl disconnect *indication*
4527 	      text_color_set(DW_COLOR_INFO);
4528 	      dw_printf ("Stream %d: Disconnected from %s.\n", S->stream_id, S->addrs[PEERCALL]);
4529 	      server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
4530 	      STOP_T1;
4531 	      enter_new_state (S, state_0_disconnected, __func__, __LINE__);
4532 	    }
4533 	    else {
4534 	      // keep current state.
4535 	    }
4536 #else
4537 	    // Erratum: This is not in original spec.  It's copied from the FRMR case.
4538 
4539 	    // I was expecting FRMR to mean the other end did not understand v2.2.
4540 	    // Experimentation, with KPC-3+, revealed that we get DM instead.
4541 	    // One part of the the 2.0 spec sort of indicates this might be intentional.
4542 	    // But another part more clearly states it should be FRMR.
4543 
4544 	    // At first I thought it was an error in the protocol spec.
4545 	    // Later, I tend to believe it was just implemented wrong in the KPC-3+.
4546 
4547 	    if (f == 1) {
4548 	      text_color_set(DW_COLOR_INFO);
4549 	      dw_printf ("%s doesn't understand AX.25 v2.2.  Trying v2.0 ...\n", S->addrs[PEERCALL]);
4550 
4551 	      INIT_T1V_SRT;
4552 
4553 	      // Erratum: page 105.   We are in state 5 so I think that means modulo is 128,
4554 	      // k is probably something > 7, and selective reject is enabled.
4555 	      // At the end of this we go to state 1.
4556 	      // It seems to me, that we really want to set version 2.0 in here so we have
4557 	      // compatible settings.
4558 
4559 	      set_version_2_0 (S);
4560 
4561 	      establish_data_link (S);
4562 	      S->layer_3_initiated = 1;
4563 	      enter_new_state (S, state_1_awaiting_connection, __func__, __LINE__);
4564 	    }
4565 #endif
4566 	    break;
4567 	}
4568 
4569 } /* end dm_frame */
4570 
4571 
4572 
4573 
4574 /*------------------------------------------------------------------------------
4575  *
4576  * Name:	UA_frame
4577  *
4578  * Purpose:	Process UA Response Frame.
4579  *
4580  * Inputs:	S	- Data Link State Machine.
4581  *		f	- Final bit.
4582  *
4583  * Description:	4.3.3.4. Unnumbered Acknowledge (UA) Response
4584  *
4585  *		The UA response frame acknowledges the reception and acceptance of a SABM(E) or DISC command
4586  *		frame. A received command is not actually processed until the UA response frame is sent. Information fields are
4587  *		not permitted in a UA frame.
4588  *
4589  *		4.4.1. TNC Busy Condition
4590  *
4591  *		When a TNC is temporarily unable to receive I frames (e.g., when receive buffers are full), it sends a Receive
4592  *		Not Ready (RNR) frame. This informs the sending TNC that the receiving TNC cannot handle any more I
4593  *		frames at the moment. This receiving TNC clears this condition by the sending a UA, RR, REJ or SABM(E)
4594  *		command frame.
4595  *
4596  *		6.2. Poll/Final (P/F) Bit Procedures
4597  *
4598  *		The response frame returned by a TNC depends on the previous command received, as described in the
4599  *		following paragraphs.
4600  *		The next response frame returned by the TNC to a SABM(E) or DISC command with the P bit set to "1" is a
4601  *		UA or DM response with the F bit set to "1".
4602  *
4603  *		6.3.1. AX.25 Link Connection Establishment
4604  *
4605  *		To connect to a distant TNC, the originating TNC sends a SABM command frame to the distant TNC and
4606  *		starts its T1 timer. If the distant TNC exists and accepts the connect request, it responds with a UA response
4607  *		frame and resets all of its internal state variables (V(S), V(A) and V(R)). Reception of the UA response frame by
4608  *		the originating TNC causes it to cancel the T1 timer and set its internal state variables to "0".
4609  *
4610  *		6.5. Resetting Procedure
4611  *
4612  *		A TNC initiates a reset procedure whenever it receives an unexpected UA response frame, or after receipt of
4613  *		a FRMR frame from a TNC using an older version of the protocol.
4614  *
4615  *------------------------------------------------------------------------------*/
4616 
ua_frame(ax25_dlsm_t * S,int f)4617 static void ua_frame (ax25_dlsm_t *S, int f)
4618 {
4619 	switch (S->state) {
4620 
4621 	  case 	state_0_disconnected:
4622 
4623 	    // Erratum: flow chart says errors C and D.  Neither one really makes sense.
4624 	    // "Unexpected UA in states 3, 4, or 5."	We are in state 0 here.
4625 	    // "UA received without F=1 when SABM or DISC was sent P=1."
4626 
4627 	    if (s_debug_protocol_errors) {
4628 	      text_color_set(DW_COLOR_ERROR);
4629 	      dw_printf ("Stream %d: AX.25 Protocol Error C: Unexpected UA in state %d.\n", S->stream_id, S->state);
4630 	    }
4631 	    break;
4632 
4633 	  case 	state_1_awaiting_connection:
4634 	  case 	state_5_awaiting_v22_connection:
4635 
4636 	    if (f == 1) {
4637 	      if (S->layer_3_initiated) {
4638 	        text_color_set(DW_COLOR_INFO);
4639 	        // TODO: add via if apppropriate.
4640 	        dw_printf ("Stream %d: Connected to %s.  (%s)\n", S->stream_id, S->addrs[PEERCALL], S->state == state_5_awaiting_v22_connection ? "v2.2" : "v2.0");
4641 	        // There is a subtle difference here between connect confirm and indication.
4642 	        // connect *confirm* means "has been made"
4643 		// The AGW API distinguishes between incoming (initiated by other station) and
4644 		// outgoing (initiated by me) connections.
4645 	        int incoming = 0;
4646 	        server_link_established (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], incoming);
4647 	      }
4648 	      else if (S->vs != S->va) {
4649 #if 1
4650 		// Erratum: 2006 version has this.
4651 
4652 	        INIT_T1V_SRT;
4653 
4654 		START_T3;		// Erratum:  Rather pointless because we immediately stop it below.
4655 					// In the original flow chart, that is.
4656 					// I think there is an error as explained below.
4657 					// In my version this is still pointless because we start T3 later.
4658 
4659 #else
4660 	        // Erratum: Original version has this.
4661 	        // I think this could be harmful.
4662 	        // The client app might have been impatient and started sending
4663 	        // information already.  I don't see why we would want to discard it.
4664 
4665 	        discard_i_queue (S);
4666 #endif
4667 	        text_color_set(DW_COLOR_INFO);
4668 	        dw_printf ("Stream %d: Connected to %s.  (%s)\n", S->stream_id, S->addrs[PEERCALL], S->state == state_5_awaiting_v22_connection ? "v2.2" : "v2.0");
4669 
4670 	        // Erratum: 2006 version says DL-CONNECT *confirm* but original has *indication*.
4671 
4672 	        // connect *indication* means "has been requested".
4673 	        // *confirm* seems right because we got a reply from the other side.
4674 
4675 		int incoming = 0;
4676 	        server_link_established (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], incoming);
4677 	      }
4678 
4679 	      STOP_T1;
4680 #if 1				// My version.
4681 	      START_T3;
4682 #else				// As shown in flow chart.
4683 	      STOP_T3;		// Erratum?  I think this is wrong.
4684 				// We are about to enter state 3.   When in state 3 either T1 or T3 should be
4685 				// running.  In state 3, we always see start one / stop the other pairs except where
4686 				// we are about to enter a different state.
4687 				// Since there is nothing outstanding where we expect a response, T1 would
4688 				// not be started.
4689 #endif
4690 	      SET_VS(0);
4691 	      SET_VA(0);
4692 	      SET_VR(0);
4693 	      select_t1_value (S);
4694 
4695 // Erratum:  mdl_negotiate_request does not appear in the SDL flow chart.
4696 // It is mentioned here:
4697 //
4698 // C5.3 Internal Operation of the Machine
4699 //
4700 // The Management Data link State Machine handles the negotiation/notification of
4701 // operational parameters. It uses a single command/response exchange to negotiate the
4702 // final values of negotiable parameters.
4703 //
4704 // The station initiating the AX.25 connection will send an XID command after it receives
4705 // the UA frame. If the other station is using a version of AX.25 earlier than 2.2, it will
4706 // respond with an FRMR of the XID command and the default version 2.0 parameters will
4707 // be used. If the other station is using version 2.2 or better, it will respond with an XID
4708 // response.
4709 
4710 	      if (S->state == state_5_awaiting_v22_connection) {
4711 	        mdl_negotiate_request (S);
4712 	      }
4713 
4714 	      SET_RC(0);			// My enhancement.  See Erratum note in select_t1_value.
4715 	      enter_new_state (S, state_3_connected, __func__, __LINE__);
4716 	    }
4717 	    else {
4718 	      if (s_debug_protocol_errors) {
4719 	        text_color_set(DW_COLOR_ERROR);
4720 	        dw_printf ("Stream %d: AX.25 Protocol Error D: UA received without F=1 when SABM or DISC was sent P=1.\n", S->stream_id);
4721 	      }
4722 	      // stay in current state, either 1 or 5.
4723 	    }
4724 	    break;
4725 
4726 	  case 	state_2_awaiting_release:
4727 
4728 	    // Erratum: 2006 version is missing yes/no labels on this test.
4729 	    // DL-ERROR Indication does not mention error D.
4730 
4731 	    if (f == 1) {
4732 	      text_color_set(DW_COLOR_INFO);
4733 	      dw_printf ("Stream %d: Disconnected from %s.\n", S->stream_id, S->addrs[PEERCALL]);
4734 	      server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
4735 	      STOP_T1;
4736 	      enter_new_state (S, state_0_disconnected, __func__, __LINE__);
4737 	    }
4738 	    else {
4739 	      if (s_debug_protocol_errors) {
4740 	        text_color_set(DW_COLOR_ERROR);
4741 	        dw_printf ("Stream %d: AX.25 Protocol Error D: UA received without F=1 when SABM or DISC was sent P=1.\n", S->stream_id);
4742 	      }
4743 	      // stay in same state.
4744 	    }
4745 	    break;
4746 
4747 	  case 	state_3_connected:
4748 	  case 	state_4_timer_recovery:
4749 
4750 	    if (s_debug_protocol_errors) {
4751 	      text_color_set(DW_COLOR_ERROR);
4752 	      dw_printf ("Stream %d: AX.25 Protocol Error C: Unexpected UA in state %d.\n", S->stream_id, S->state);
4753 	    }
4754 	    establish_data_link (S);
4755 	    S->layer_3_initiated = 0;
4756 
4757 	    // Erratum? Flow chart goes to state 1.  Wouldn't we want this to be state 5 if modulo is 128?
4758 	    enter_new_state (S, S->modulo == 128 ? state_5_awaiting_v22_connection : state_1_awaiting_connection, __func__, __LINE__);
4759 	    break;
4760 	}
4761 
4762 } /* end ua_frame */
4763 
4764 
4765 
4766 /*------------------------------------------------------------------------------
4767  *
4768  * Name:	frmr_frame
4769  *
4770  * Purpose:	Process FRMR Response Frame.
4771  *
4772  * Inputs:	S	- Data Link State Machine.
4773  *
4774  * Description:	4.3.3.2. Set Asynchronous Balanced Mode Extended (SABME) Command
4775  *		...
4776  *		The TNC confirms reception and acceptance of a SABME command by sending a UA response frame at the
4777  *		earliest opportunity. If the TNC is not capable of accepting a SABME command, it responds with a DM frame.
4778  *		A TNC that uses a version of AX.25 prior to v2.2 responds with a FRMR.
4779  *
4780  *		4.3.3.9. FRMR Response Frame
4781  *
4782  *		The FRMR response is removed from the standard for the following reasons:
4783  *		a) UI frame transmission was not allowed during FRMR recovery;
4784  *		b) During FRMR recovery, the link could not be reestablished by the station that sent the FRMR;
4785  *		c) The above functions are better handled by simply resetting the link with a SABM(E) + UA exchange;
4786  *		d) An implementation that receives and process FRMRs but does not transmit them is compatible with older
4787  *		   versions of the standard; and
4788  *		e) SDL is simplified and removes the need for one state.
4789  *		This version of AX.25 operates with previous versions of AX.25. It does not generate a FRMR Response
4790  *		frame, but handles error conditions by resetting the link.
4791  *
4792  *		6.3.2. Parameter Negotiation Phase
4793  *
4794  *		Parameter negotiation occurs at any time. It is accomplished by sending the XID command frame and
4795  *		receiving the XID response frame. Implementations of AX.25 prior to version 2.2 respond to an XID command
4796  *		frame with a FRMR response frame. The TNC receiving the FRMR uses a default set of parameters compatible
4797  *		with previous versions of AX.25.
4798  *
4799  *		6.5. Resetting Procedure
4800  *
4801  *		The link resetting procedure initializes both directions of data flow after a unrecoverable error has occurred.
4802  *		This resetting procedure is used only in the information-transfer state of an AX.25 link.
4803  *		A TNC initiates a reset procedure whenever it receives an unexpected UA response frame, or after receipt of
4804  *		a FRMR frame from a TNC using an older version of the protocol.
4805  *
4806  *------------------------------------------------------------------------------*/
4807 
4808 
frmr_frame(ax25_dlsm_t * S)4809 static void frmr_frame (ax25_dlsm_t *S)
4810 {
4811 	switch (S->state) {
4812 
4813 	  case 	state_0_disconnected:
4814 	  case 	state_1_awaiting_connection:
4815 	  case 	state_2_awaiting_release:
4816 	    // Ignore it.  Keep current state.
4817 	    break;
4818 
4819 	  case 	state_3_connected:
4820 	  case 	state_4_timer_recovery:
4821 
4822 	    if (s_debug_protocol_errors) {
4823 	      text_color_set(DW_COLOR_ERROR);
4824 	      dw_printf ("Stream %d: AX.25 Protocol Error K: FRMR not expected in state %d.\n", S->stream_id, S->state);
4825 	    }
4826 
4827 	    set_version_2_0 (S);	// Erratum: FRMR can only be sent by v2.0.
4828 					// Need to force v2.0.  Should be added to flow chart.
4829 	    establish_data_link (S);
4830 	    S->layer_3_initiated = 0;
4831 	    enter_new_state (S, state_1_awaiting_connection, __func__, __LINE__);
4832 	    break;
4833 
4834 	  case 	state_5_awaiting_v22_connection:
4835 
4836 	    text_color_set(DW_COLOR_INFO);
4837 	    dw_printf ("%s doesn't understand AX.25 v2.2.  Trying v2.0 ...\n", S->addrs[PEERCALL]);
4838 
4839 	    INIT_T1V_SRT;
4840 
4841 	    set_version_2_0 (S);		// Erratum: Need to force v2.0.  This is not in flow chart.
4842 
4843 	    establish_data_link (S);
4844 	    S->layer_3_initiated = 1;		// Erratum?  I don't understand the difference here.
4845 						// State 1 clears it.  State 5 sets it.  Why not the same?
4846 
4847 	    enter_new_state (S, state_1_awaiting_connection, __func__, __LINE__);
4848 	    break;
4849 	}
4850 
4851 // part of state machine for the XID negotiation.
4852 
4853 // I would not expect this to happen.
4854 // To get here:
4855 //	We sent SABME.  (not SABM)
4856 //	Other side responded with UA so it understands v2.2.
4857 //	We sent XID command which puts us int the negotiating state.
4858 // Presumably this is in response to the XID and not something else.
4859 
4860 // Anyhow, we will fall back to v2.0 parameters.
4861 
4862 	switch (S->mdl_state) {
4863 
4864 	  case 	mdl_state_0_ready:
4865 	    break;
4866 
4867 	  case 	mdl_state_1_negotiating:
4868 
4869 	    set_version_2_0 (S);
4870 	    S->mdl_state = mdl_state_0_ready;
4871 	    break;
4872 	}
4873 
4874 } /* end frmr_frame */
4875 
4876 
4877 /*------------------------------------------------------------------------------
4878  *
4879  * Name:	ui_frame
4880  *
4881  * Purpose:	Process XID frame for negotiating protocol parameters.
4882  *
4883  * Inputs:	S	- Data Link State Machine.
4884  *
4885  *		cr	- Is it command or response?
4886  *
4887  *		pf	- Poll/Final bit.
4888  *
4889  * Description:	4.3.3.6. Unnumbered Information (UI) Frame
4890  *
4891  *		The Unnumbered Information frame contains PID and information fields and passes information along the
4892  *		link outside the normal information controls. This allows information fields to be exchanged on the link, bypassing
4893  *		flow control.
4894  *
4895  *		Because these frames cannot be acknowledged, if one such frame is obliterated, it cannot be recovered.
4896  *		A received UI frame with the P bit set causes a response to be transmitted. This response is a DM frame when
4897  *		in the disconnected state, or an RR (or RNR, if appropriate) frame in the information transfer state.
4898  *
4899  * Reality:	The data link state machine was an add-on after APRS and client APIs were already done.
4900  *		UI frames don't go thru here for normal operation.
4901  *		The only reason we have this function is so that we can send a response to a UI command with P=1.
4902  *
4903  *------------------------------------------------------------------------------*/
4904 
ui_frame(ax25_dlsm_t * S,cmdres_t cr,int pf)4905 static void ui_frame (ax25_dlsm_t *S, cmdres_t cr, int pf)
4906 {
4907 	if (cr == cr_cmd && pf == 1) {
4908 
4909 	  switch (S->state) {
4910 
4911 	    case 	state_0_disconnected:
4912 	    case 	state_1_awaiting_connection:
4913 	    case 	state_2_awaiting_release:
4914 	    case 	state_5_awaiting_v22_connection:
4915 	      {
4916 	        cmdres_t r = cr_res;	// DM response with F taken from P.
4917 	        int nopid = 0;		// PID applies only for I and UI frames.
4918 
4919 	        packet_t pp = ax25_u_frame (S->addrs, S->num_addr, r, frame_type_U_DM, pf, nopid, NULL, 0);
4920 	        lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
4921 	      }
4922 	      break;
4923 
4924 	    case 	state_3_connected:
4925 	    case 	state_4_timer_recovery:
4926 
4927 	      enquiry_response (S, frame_type_U_UI, pf);
4928 	      break;
4929 	  }
4930 	}
4931 
4932 } /* end ui_frame */
4933 
4934 
4935 
4936 /*------------------------------------------------------------------------------
4937  *
4938  * Name:	xid_frame
4939  *
4940  * Purpose:	Process XID frame for negotiating protocol parameters.
4941  *
4942  * Inputs:	S	- Data Link State Machine.
4943  *
4944  *		cr	- Is it command or response?
4945  *
4946  *		pf	- Poll/Final bit.
4947  *
4948  * Description:	4.3.3.7 Exchange Identification (XID) Frame
4949  *
4950  *		The Exchange Identification frame causes the addressed station to identify itself, and
4951  *		to provide its characteristics to the sending station. An information field is optional within
4952  *		the XID frame. A station receiving an XID command returns an XID response unless a UA
4953  *		response to a mode setting command is awaiting transmission, or a FRMR condition
4954  *		exists.
4955  *
4956  *		The XID frame complies with ISO 8885. Only those fields applicable to AX.25 are
4957  *		described. All other fields are set to an appropriate value. This implementation is
4958  *		compatible with any implementation which follows ISO 8885. Only the general-purpose
4959  *		XID information field identifier is required in this version of AX.25.
4960  *
4961  *		The information field consists of zero or more information elements. The information
4962  *		elements start with a Format Identifier (FI) octet. The second octet is the Group Identifier
4963  *		(GI). The third and forth octets form the Group Length (GL). The rest of the information
4964  *		field contains parameter fields.
4965  *
4966  *		The FI takes the value 82 hex for the general-purpose XID information. The GI takes
4967  *		the value 80 hex for the parameter-negotiation identifier. The GL indicates the length of
4968  *		the associated parameter field. This length is expressed as a two-octet binary number
4969  *		representing the length of the associated parameter field in octets. The high-order bits of
4970  *		length value are in the first of the two octets. A group length of zero indicates the lack of
4971  *		an associated parameter field and that all parameters assume their default values. The GL
4972  *		does not include its own length or the length of the GI.
4973  *
4974  *		The parameter field contains a series of Parameter Identifier (PI), Parameter Length
4975  *		(PL), and Parameter Value (PV) set structures, in that order. Each PI identifies a
4976  *		parameter and is one octet in length. Each PL indicates the length of the associated PV in
4977  *		octets, and is one octet in length. Each PV contains the parameter value and is PL octets
4978  *		in length. The PL does not include its own length or the length of its associated PI. A PL
4979  *		value of zero indicates that the associated PV is absent; the parameter assumes the
4980  *		default value. A PI/PL/PV set may be omitted if it is not required to convey information, or
4981  *		if present values for the parameter are to be used. The PI/PL/PV fields are placed into the
4982  *		information field of the XID frame in ascending order. There is only one entry for each
4983  *		PI/PL/PV field used. A parameter field containing an unrecognized PI is ignored. An
4984  *		omitted parameter field assumes the currently negotiated value.
4985  *
4986  *------------------------------------------------------------------------------*/
4987 
4988 
xid_frame(ax25_dlsm_t * S,cmdres_t cr,int pf,unsigned char * info_ptr,int info_len)4989 static void xid_frame (ax25_dlsm_t *S, cmdres_t cr, int pf, unsigned char *info_ptr, int info_len)
4990 {
4991 	struct xid_param_s param;
4992 	char desc[150];
4993 	int ok;
4994 	unsigned char xinfo[40];
4995 	int xlen;
4996 	cmdres_t res = cr_res;
4997 	int f = 1;
4998 	int nopid = 0;
4999 	packet_t pp;
5000 
5001 
5002 	switch (S->mdl_state) {
5003 
5004 	  case 	mdl_state_0_ready:
5005 
5006 	    if (cr == cr_cmd) {
5007 
5008 	      if (pf == 1) {
5009 
5010 // Take parameters sent by other station.
5011 // Generally we take minimum of what he wants and what I can do.
5012 // Adjust my working configuration and send it back.
5013 
5014 	        ok = xid_parse (info_ptr, info_len, &param, desc, sizeof(desc));
5015 
5016 		if (ok) {
5017 		  negotiation_response (S, &param);
5018 
5019 	          xlen = xid_encode (&param, xinfo, res);
5020 
5021 	          pp = ax25_u_frame (S->addrs, S->num_addr, res, frame_type_U_XID, f, nopid, xinfo, xlen);
5022 	          lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5023 	        }
5024 	      }
5025 	      else {
5026 	        text_color_set(DW_COLOR_ERROR);
5027 	        dw_printf ("Stream %d: AX.25 Protocol Error MDL-A: XID command without P=1.\n", S->stream_id);
5028 	      }
5029 	    }
5030 	    else {
5031 	      text_color_set(DW_COLOR_ERROR);
5032 	      dw_printf ("Stream %d: AX.25 Protocol Error MDL-B: Unexpected XID response.\n", S->stream_id);
5033 	    }
5034 	    break;
5035 
5036 	  case 	mdl_state_1_negotiating:
5037 
5038 	    if (cr == cr_res) {
5039 
5040 	      if (pf == 1) {
5041 
5042 // Got expected response.  Copy into my working parameters.
5043 
5044 	        ok = xid_parse (info_ptr, info_len, &param, desc, sizeof(desc));
5045 
5046 	        if (ok) {
5047 		  complete_negotiation (S, &param);
5048 	        }
5049 
5050 	        S->mdl_state = mdl_state_0_ready;
5051 	        STOP_TM201;
5052 
5053 //#define TEST_TEST 1
5054 
5055 #if TEST_TEST		// Send TEST command to see how it responds.
5056 			// We currently have no Client API for sending this or reporting result.
5057 		{
5058 	          char info[80] = "The quick brown fox jumps over the lazy dog.";
5059 	          cmdres_t cmd = cr_cmd;
5060 	          int p = 0;
5061 	          int nopid = 0;
5062 	          packet_t pp;
5063 
5064 	          pp = ax25_u_frame (S->addrs, S->num_addr, cmd, frame_type_U_TEST, p, nopid, (unsigned char *)info, (int)strlen(info));
5065 	          lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5066 	        }
5067 #endif
5068 	      }
5069 	      else {
5070 	        text_color_set(DW_COLOR_ERROR);
5071 	        dw_printf ("Stream %d: AX.25 Protocol Error MDL-D: XID response without F=1.\n", S->stream_id);
5072 	      }
5073 	    }
5074 	    else {
5075 	      // Not expecting to receive a command when I sent one.
5076 	      // Flow chart says requeue but I just drop it.
5077 	      // The other end can retry and maybe I will be back to ready state by then.
5078 	    }
5079 	    break;
5080 	}
5081 
5082 } /* end xid_frame */
5083 
5084 
5085 /*------------------------------------------------------------------------------
5086  *
5087  * Name:	test_frame
5088  *
5089  * Purpose:	Process TEST command for checking link.
5090  *
5091  * Inputs:	S	- Data Link State Machine.
5092  *
5093  *		cr	- Is it command or response?
5094  *
5095  *		pf	- Poll/Final bit.
5096  *
5097  * Description:	4.3.3.8. Test (TEST) Frame
5098  *
5099  *		The Test command causes the addressed station to respond with the TEST response at the first respond
5100  *		opportunity; this performs a basic test of the data-link control. An information field is optional with the TEST
5101  *		command. If present, the received information field is returned, if possible, by the addressed station, with the
5102  *		TEST response. The TEST command has no effect on the mode or sequence variables maintained by the station.
5103  *
5104  *		A FRMR condition may be established if the received TEST command information field exceeds the maximum
5105  *		defined storage capability of the station. If a FRMR response is not returned for this condition, a TEST response
5106  *		without an information field is returned.
5107  *
5108  *		The station considers the data-link layer test terminated on receipt of the TEST response, or when a time-out
5109  *		period has expired. The results of the TEST command/response exchange are made available for interrogation
5110  *		by a higher layer.
5111  *
5112  * Erratum:	TEST frame is not mentioned in the SDL flow charts.
5113  *		Don't know how P/F is supposed to be used.
5114  *		Here, the response sends back what was received in the command.
5115  *
5116  *------------------------------------------------------------------------------*/
5117 
5118 
test_frame(ax25_dlsm_t * S,cmdres_t cr,int pf,unsigned char * info_ptr,int info_len)5119 static void test_frame (ax25_dlsm_t *S, cmdres_t cr, int pf, unsigned char *info_ptr, int info_len)
5120 {
5121 	cmdres_t res = cr_res;
5122 	int f = pf;
5123 	int nopid = 0;
5124 	packet_t pp;
5125 
5126 	if (cr == cr_cmd) {
5127 	  pp = ax25_u_frame (S->addrs, S->num_addr, res, frame_type_U_TEST, f, nopid, info_ptr, info_len);
5128 	  lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5129 	}
5130 
5131 } /* end test_frame */
5132 
5133 
5134 
5135 /*------------------------------------------------------------------------------
5136  *
5137  * Name:	dl_timer_expiry
5138  *
5139  * Purpose:	Some timer expired.  Figure out which one and act accordingly.
5140  *
5141  * Inputs:	none.
5142  *
5143  *------------------------------------------------------------------------------*/
5144 
dl_timer_expiry(void)5145 void dl_timer_expiry (void)
5146 {
5147 	ax25_dlsm_t *p;
5148 	double now = dtime_now();
5149 
5150 // Examine all of the data link state machines.
5151 // Process only those where timer:
5152 //	- is running.
5153 //	- is not paused.
5154 //	- expiration time has arrived or passed.
5155 
5156 	for (p = list_head; p != NULL; p = p->next) {
5157 	  if (p->t1_exp != 0 && p->t1_paused_at == 0 && p->t1_exp <= now) {
5158 	    p->t1_exp = 0;
5159 	    p->t1_paused_at = 0;
5160 	    p->t1_had_expired = 1;
5161 	    t1_expiry (p);
5162 	  }
5163 	}
5164 
5165 	for (p = list_head; p != NULL; p = p->next) {
5166 	  if (p->t3_exp != 0 && p->t3_exp <= now) {
5167 	    p->t3_exp = 0;
5168 	    t3_expiry (p);
5169 	  }
5170 	}
5171 
5172 	for (p = list_head; p != NULL; p = p->next) {
5173 	  if (p->tm201_exp != 0 && p->tm201_paused_at == 0 && p->tm201_exp <= now) {
5174 	    p->tm201_exp = 0;
5175 	    p->tm201_paused_at = 0;
5176 	    tm201_expiry (p);
5177 	  }
5178 	}
5179 
5180 } /* end dl_timer_expiry */
5181 
5182 
5183 /*------------------------------------------------------------------------------
5184  *
5185  * Name:	t1_expiry
5186  *
5187  * Purpose:	Handle T1 timer expiration for outstanding I frame or P-bit.
5188  *
5189  * Inputs:	S	- Data Link State Machine.
5190  *
5191  * Description:	4.4.5.1. T1 Timer Recovery
5192  *
5193  *		If a transmission error causes a TNC to fail to receive (or to receive and discard) a single I frame, or the last I
5194  *		frame in a sequence of I frames, then the TNC does not detect a send-sequence-number error and consequently
5195  *		does not transmit a REJ/SREJ. The TNC that transmitted the unacknowledged I frame(s) following the completion
5196  *		of timeout period T1, takes appropriate recovery action to determine when I frame retransmission as described
5197  *		in Section 6.4.10 should begin. This condition is cleared by the reception of an acknowledgement for the sent
5198  *		frame(s), or by the link being reset.
5199  *
5200  *		6.7.1.1. Acknowledgment Timer T1
5201  *
5202  *		T1, the Acknowledgement Timer, ensures that a TNC does not wait indefinitely for a response to a frame it
5203  *		sends. This timer cannot be expressed in absolute time; the time required to send frames varies greatly with the
5204  *		signaling rate used at Layer 1. T1 should take at least twice the amount of time it would take to send maximum
5205  *		length frame to the distant TNC and get the proper response frame back from the distant TNC. This allows time
5206  *		for the distant TNC to do some processing before responding.
5207  *		If Layer 2 repeaters are used, the value of T1 should be adjusted according to the number of repeaters through
5208  *		which the frame is being transferred.
5209  *
5210  *------------------------------------------------------------------------------*/
5211 
5212 // Make timer start, stop, expiry a different color to stand out.
5213 
5214 #define DW_COLOR_DEBUG_TIMER DW_COLOR_ERROR
5215 
5216 
t1_expiry(ax25_dlsm_t * S)5217 static void t1_expiry (ax25_dlsm_t *S)
5218 {
5219 
5220 	if (s_debug_timers) {
5221 	  double now = dtime_now();
5222 
5223 	  text_color_set(DW_COLOR_DEBUG_TIMER);
5224 	  dw_printf ("t1_expiry (), [now=%.3f], state=%d, rc=%d\n", now - S->start_time, S->state, S->rc);
5225 	}
5226 
5227 	switch (S->state) {
5228 
5229 	  case 	state_0_disconnected:
5230 
5231 	    // Ignore it.
5232 	    break;
5233 
5234 	  case 	state_1_awaiting_connection:
5235 	  case 	state_5_awaiting_v22_connection:
5236 
5237 	    // MAXV22 hack.
5238 	    // If we already sent the maximum number of SABME, fall back to v2.0 SABM.
5239 
5240 	    if (S->state == state_5_awaiting_v22_connection && S->rc == g_misc_config_p->maxv22) {
5241 	      set_version_2_0 (S);
5242 	      enter_new_state (S, state_1_awaiting_connection, __func__, __LINE__);
5243 	    }
5244 
5245 	    if (S->rc == S->n2_retry) {
5246 	      discard_i_queue(S);
5247 	      text_color_set(DW_COLOR_INFO);
5248 	      dw_printf ("Failed to connect to %s after %d tries.\n", S->addrs[PEERCALL], S->n2_retry);
5249 	      server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 1);
5250 	      enter_new_state (S, state_0_disconnected, __func__, __LINE__);
5251 	    }
5252 	    else {
5253 	      cmdres_t cmd = cr_cmd;
5254 	      int p = 1;
5255 	      int nopid = 0;
5256 
5257 	      packet_t pp;
5258 
5259 	      SET_RC(S->rc+1);
5260 	      if (S->rc > S->peak_rc_value) S->peak_rc_value = S->rc;	// Keep statistics.
5261 
5262 	      pp = ax25_u_frame (S->addrs, S->num_addr, cmd, (S->state == state_5_awaiting_v22_connection) ? frame_type_U_SABME : frame_type_U_SABM, p, nopid, NULL, 0);
5263 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5264 	      select_t1_value(S);
5265 	      START_T1;
5266 	      // Keep same state.
5267 	    }
5268 	    break;
5269 
5270 	  case 	state_2_awaiting_release:
5271 
5272 	    if (S->rc == S->n2_retry) {
5273 	      text_color_set(DW_COLOR_INFO);
5274 	      dw_printf ("Stream %d: Disconnected from %s.\n", S->stream_id, S->addrs[PEERCALL]);
5275 	      server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
5276 	      enter_new_state (S, state_0_disconnected, __func__, __LINE__);
5277 	    }
5278 	    else {
5279 	      cmdres_t cmd = cr_cmd;
5280 	      int p = 1;
5281 	      int nopid = 0;
5282 
5283 	      packet_t pp;
5284 
5285 	      SET_RC(S->rc+1);
5286 	      if (S->rc > S->peak_rc_value) S->peak_rc_value = S->rc;
5287 
5288 	      pp = ax25_u_frame (S->addrs, S->num_addr, cmd, frame_type_U_DISC, p, nopid, NULL, 0);
5289 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5290 	      select_t1_value(S);
5291 	      START_T1;
5292 	      // stay in same state
5293 	    }
5294 	    break;
5295 
5296 	  case 	state_3_connected:
5297 
5298 	    SET_RC(1);
5299 	    transmit_enquiry (S);
5300 	    enter_new_state (S, state_4_timer_recovery, __func__, __LINE__);
5301 	    break;
5302 
5303 	  case 	state_4_timer_recovery:
5304 
5305 	    if (S->rc == S->n2_retry) {
5306 
5307 // Erratum: 2006 version, page 103, is missing yes/no labels on decision blocks.
5308 
5309 	      if (S->va != S->vs) {
5310 
5311 	        if (s_debug_protocol_errors) {
5312 	          text_color_set(DW_COLOR_ERROR);
5313 	          dw_printf ("Stream %d: AX.25 Protocol Error I: %d timeouts: unacknowledged sent data.\n", S->stream_id, S->n2_retry);
5314 	        }
5315 	      }
5316 	      else if (S->peer_receiver_busy) {
5317 
5318 	        if (s_debug_protocol_errors) {
5319 	          text_color_set(DW_COLOR_ERROR);
5320 	          dw_printf ("Stream %d: AX.25 Protocol Error U: %d timeouts: extended peer busy condition.\n", S->stream_id, S->n2_retry);
5321 	        }
5322 	      }
5323 	      else {
5324 
5325 	        if (s_debug_protocol_errors) {
5326 	          text_color_set(DW_COLOR_ERROR);
5327 	          dw_printf ("Stream %d: AX.25 Protocol Error T: %d timeouts: no response to enquiry.\n", S->stream_id, S->n2_retry);
5328 	        }
5329 	      }
5330 
5331 	      // Erratum:  Flow chart says DL-DISCONNECT "request" in both original and 2006 revision.
5332 	      // That is clearly wrong because a "request" would come FROM the higher level protocol/client app.
5333 	      // I think it should be "indication" rather than "confirm" because the peer condition is unknown.
5334 
5335 	      // dl disconnect *indication*
5336 	      text_color_set(DW_COLOR_INFO);
5337 	      dw_printf ("Stream %d: Disconnected from %s due to timeouts.\n", S->stream_id, S->addrs[PEERCALL]);
5338 	      server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 1);
5339 
5340 	      discard_i_queue (S);
5341 
5342 	      cmdres_t cr = cr_res;	// DM can only be response.
5343 	      int f = 0;		// Erratum: Assuming F=0 because it is not response to P=1
5344 	      int nopid = 0;
5345 
5346 	      packet_t pp = ax25_u_frame (S->addrs, S->num_addr, cr, frame_type_U_DM, f, nopid, NULL, 0);
5347 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5348 
5349 	      enter_new_state (S, state_0_disconnected, __func__, __LINE__);
5350 	    }
5351 	    else {
5352 	      SET_RC(S->rc+1);
5353 	      if (S->rc > S->peak_rc_value) S->peak_rc_value = S->rc;	// gather statistics.
5354 
5355 	      transmit_enquiry (S);
5356 	      // Keep same state.
5357 	    }
5358 	    break;
5359 	}
5360 
5361 } /* end t1_expiry */
5362 
5363 
5364 /*------------------------------------------------------------------------------
5365  *
5366  * Name:	t3_expiry
5367  *
5368  * Purpose:	Handle T3 timer expiration.
5369  *
5370  * Inputs:	S	- Data Link State Machine.
5371  *
5372  * Description:	TODO:  still don't understand this.
5373  *
5374  *		4.4.5.2. Timer T3 Recovery
5375  *
5376  *		Timer T3 ensures that the link is still functional during periods of low information transfer. When T1 is not
5377  *		running (no outstanding I frames), T3 periodically causes the TNC to poll the other TNC of a link. When T3
5378  *		times out, an RR or RNR frame is transmitted as a command with the P bit set, and then T1 is started. When a
5379  *		response to this command is received, T1 is stopped and T3 is started. If T1 expires before a response is
5380  *		received, then the waiting acknowledgement procedure (Section 6.4.11) is executed.
5381  *
5382  *		6.7.1.3. Inactive Link Timer T3
5383  *
5384  *		T3, the Inactive Link Timer, maintains link integrity whenever T1 is not running. It is recommended that
5385  *		whenever there are no outstanding unacknowledged I frames or P-bit frames (during the information-transfer
5386  *		state), an RR or RNR frame with the P bit set to "1" be sent every T3 time units to query the status of the other
5387  *		TNC. The period of T3 is locally defined, and depends greatly on Layer 1 operation. T3 should be greater than
5388  *		T1; it may be very large on channels of high integrity.
5389  *
5390  *------------------------------------------------------------------------------*/
5391 
t3_expiry(ax25_dlsm_t * S)5392 static void t3_expiry (ax25_dlsm_t *S)
5393 {
5394 
5395 	if (s_debug_timers) {
5396 	  double now = dtime_now();
5397 
5398 	  text_color_set(DW_COLOR_DEBUG_TIMER);
5399 	  dw_printf ("t3_expiry (), [now=%.3f]\n", now - S->start_time);
5400 	}
5401 
5402 	switch (S->state) {
5403 
5404 	  case 	state_0_disconnected:
5405 	  case 	state_1_awaiting_connection:
5406 	  case 	state_5_awaiting_v22_connection:
5407 	  case 	state_2_awaiting_release:
5408 	  case 	state_4_timer_recovery:
5409 
5410 	    break;
5411 
5412 	  case 	state_3_connected:
5413 
5414 // Erratum: Original sets RC to 0, 2006 revision sets RC to 1 which makes more sense.
5415 
5416 	    SET_RC(1);
5417 	    transmit_enquiry (S);
5418 	    enter_new_state (S, state_4_timer_recovery, __func__, __LINE__);
5419 	    break;
5420 	}
5421 
5422 } /* end t3_expiry */
5423 
5424 
5425 
5426 /*------------------------------------------------------------------------------
5427  *
5428  * Name:	tm201_expiry
5429  *
5430  * Purpose:	Handle TM201 timer expiration.
5431  *
5432  * Inputs:	S	- Data Link State Machine.
5433  *
5434  * Description:	This is used when waiting for a response to an XID command.
5435  *
5436  *------------------------------------------------------------------------------*/
5437 
5438 
tm201_expiry(ax25_dlsm_t * S)5439 static void tm201_expiry (ax25_dlsm_t *S)
5440 {
5441 
5442 	struct xid_param_s param;
5443 	unsigned char xinfo[40];
5444 	int xlen;
5445 	cmdres_t cmd = cr_cmd;
5446 	int p = 1;
5447 	int nopid = 0;
5448 	packet_t pp;
5449 
5450 
5451 	if (s_debug_timers) {
5452 	  double now = dtime_now();
5453 
5454 	  text_color_set(DW_COLOR_DEBUG_TIMER);
5455 	  dw_printf ("tm201_expiry (), [now=%.3f], state=%d, rc=%d\n", now - S->start_time, S->state, S->rc);
5456 	}
5457 
5458 	switch (S->mdl_state) {
5459 
5460 	  case 	mdl_state_0_ready:
5461 
5462 // Timer shouldn't be running when in this state.
5463 
5464 	    break;
5465 
5466 	  case 	mdl_state_1_negotiating:
5467 
5468 	    S->mdl_rc++;
5469 	    if (S->mdl_rc > S->n2_retry) {
5470               text_color_set(DW_COLOR_ERROR);
5471               dw_printf ("Stream %d: AX.25 Protocol Error MDL-C: Management retry limit exceeded.\n", S->stream_id);
5472 	      S->mdl_state = mdl_state_0_ready;
5473 	    }
5474 	    else {
5475 	      // No response.  Ask again.
5476 
5477               initiate_negotiation (S, &param);
5478 
5479 	      xlen = xid_encode (&param, xinfo, cmd);
5480 
5481 	      pp = ax25_u_frame (S->addrs, S->num_addr, cmd, frame_type_U_XID, p, nopid, xinfo, xlen);
5482 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5483 
5484 	      START_TM201;
5485 	    }
5486 	    break;
5487 	}
5488 
5489 } /* end tm201_expiry */
5490 
5491 
5492 //###################################################################################
5493 //###################################################################################
5494 //
5495 //		Subroutines from protocol spec, pages 106 - 109
5496 //
5497 //###################################################################################
5498 //###################################################################################
5499 
5500 // FIXME: continue review here.
5501 
5502 
5503 /*------------------------------------------------------------------------------
5504  *
5505  * Name:	nr_error_recovery
5506  *
5507  * Purpose:	Try to recover after receiving an expected N(r) value.
5508  *
5509  *------------------------------------------------------------------------------*/
5510 
nr_error_recovery(ax25_dlsm_t * S)5511 static void nr_error_recovery (ax25_dlsm_t *S)
5512 {
5513 	if (s_debug_protocol_errors) {
5514 	  text_color_set(DW_COLOR_ERROR);
5515 	  dw_printf ("Stream %d: AX.25 Protocol Error J: N(r) sequence error.\n", S->stream_id);
5516 	}
5517 	establish_data_link (S);
5518 	S->layer_3_initiated = 0;
5519 
5520 } /* end nr_error_recovery */
5521 
5522 
5523 /*------------------------------------------------------------------------------
5524  *
5525  * Name:	establish_data_link
5526  *		(Combined with "establish extended data link")
5527  *
5528  * Purpose:	Send SABM or SABME to other station.
5529  *
5530  * Inputs:	S->
5531  *			addrs		destination, source, and optional digi addresses.
5532  *			num_addr	Number of addresses.  Should be 2 .. 10.
5533  *			modulo		Determines if we send SABME or SABM.
5534  *
5535  * Description:	Original spec had two different functions that differed
5536  *		only by sending SABM or SABME.  Here they are combined into one.
5537  *
5538  *------------------------------------------------------------------------------*/
5539 
establish_data_link(ax25_dlsm_t * S)5540 static void establish_data_link (ax25_dlsm_t *S)
5541 {
5542 	cmdres_t cmd = cr_cmd;
5543 	int p = 1;
5544 	packet_t pp;
5545 	int nopid = 0;
5546 
5547 	clear_exception_conditions (S);
5548 
5549 // Erratum:  We have an off-by-one error here.
5550 // Flow chart shows setting RC to 0 and we end up sending SAMB(e) 11 times when N2 (RETRY) is 10.
5551 // It should be 1 rather than 0.
5552 
5553 	SET_RC(1);
5554 	pp = ax25_u_frame (S->addrs, S->num_addr, cmd, (S->modulo == 128) ? frame_type_U_SABME : frame_type_U_SABM, p, nopid, NULL, 0);
5555 	lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5556 	STOP_T3;
5557 	START_T1;
5558 
5559 } /* end establish_data_link */
5560 
5561 
5562 
5563 /*------------------------------------------------------------------------------
5564  *
5565  * Name:	clear_exception_conditions
5566  *
5567  *------------------------------------------------------------------------------*/
5568 
clear_exception_conditions(ax25_dlsm_t * S)5569 static void clear_exception_conditions (ax25_dlsm_t *S)
5570 {
5571 	S->peer_receiver_busy = 0;
5572 	S->reject_exception = 0;
5573 	S->own_receiver_busy = 0;
5574 	S->acknowledge_pending = 0;
5575 
5576 // My enhancement.  If we are establishing a new connection, we should discard any saved out of sequence incoming I frames.
5577 
5578 	int n;
5579 
5580 	for (n = 0; n < 128; n++) {
5581 	  if (S->rxdata_by_ns[n] != NULL) {
5582 	    cdata_delete (S->rxdata_by_ns[n]);
5583 	    S->rxdata_by_ns[n] = NULL;
5584 	  }
5585 	}
5586 
5587 // We retain the transmit I frame queue so we can continue after establishing a new connection.
5588 
5589 } /* end clear_exception_conditions */
5590 
5591 
5592 /*------------------------------------------------------------------------------
5593  *
5594  * Name:	transmit_enquiry, page 106
5595  *
5596  * Purpose:	This is called only when a timer expires.
5597  *
5598  *		T1:	We sent I frames and timed out waiting for the ack.
5599  *			Poke the other end to determine how much it got so far
5600  *			so we know where to continue.
5601  *
5602  *		T3:	Not activity for substantial amount of time.
5603  *			Poke the other end to see if it is still there.
5604  *
5605  *
5606  * Observation:	This is the only place where we send RR command with P=1.
5607  *
5608  * Sequence of events:
5609  *
5610  *		We send some I frames to the other guy.
5611  *		There are outstanding sent I frames for which we did not receive ACK.
5612  *
5613  *		Timer 1 expires when we are in state 3: send RR/RNR command P=1 (here). Enter state 4.
5614  *		Timer 1 expires when we are in state 4: same until max retry count is exceeded.
5615  *
5616  *					Other guy gets RR/RNR command P=1.
5617  *					Same action for either state 3 or 4.
5618  *					Whether he has outstanding un-ack'ed sent I frames is irrelevent.
5619  *					He calls "enquiry response" which sends RR/RNR response F=1.
5620  *					(Read about detour 1 below and in enquiry_response.)
5621  *
5622  *		I get back RR/RNR response F=1.  Still in state 4.
5623  *		Of course, N(R) gets copied into V(A).
5624  *		Now here is the interesting part.
5625  *		If the ACKs are caught up, i.e.  V(A) == V(S), stop T1 and enter state 3.
5626  *		Otherwise, "invoke retransmission" to resend everything after N(R).
5627  *
5628  *
5629  * Detour 1:	You were probably thinking, "Suppose SREJ is enabled and the other guy
5630  *		had a record of the SREJ frames sent which were not answered by filled in
5631  *		I frames.  Why not send the SREJ again instead of backing up and resending
5632  *		stuff which already got there OK?"
5633  *
5634  *		The code to handle incoming SREJ in state 4 is there but stop T1 is in the
5635  *		wrong place as mentioned above.
5636  *
5637  *------------------------------------------------------------------------------*/
5638 
transmit_enquiry(ax25_dlsm_t * S)5639 static void transmit_enquiry (ax25_dlsm_t *S)
5640 {
5641 	int p = 1;
5642 	int nr = S->vr;
5643 	cmdres_t cmd = cr_cmd;
5644 	packet_t pp;
5645 
5646 	if (s_debug_retry) {
5647 	  text_color_set(DW_COLOR_ERROR);
5648 	  dw_printf ("\n****** TRANSMIT ENQUIRY   RR/RNR cmd P=1 ****** state=%d, rc=%d\n\n", S->state, S->rc);
5649 	}
5650 
5651 // This is the ONLY place that we send RR/RNR *command* with P=1.
5652 // Everywhere else should be response.
5653 // I don't think we ever use RR/RNR command P=0 but need to check on that.
5654 
5655 	pp = ax25_s_frame (S->addrs, S->num_addr, cmd, S->own_receiver_busy ? frame_type_S_RNR : frame_type_S_RR, S->modulo, nr, p, NULL, 0);
5656 
5657 	lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5658 
5659 	S->acknowledge_pending = 0;
5660 	START_T1;
5661 
5662 } /* end transmit_enquiry */
5663 
5664 
5665 
5666 /*------------------------------------------------------------------------------
5667  *
5668  * Name:	enquiry_response
5669  *
5670  * Inputs:	frame_type	- Type of frame received or frame_not_AX25 for LM seize confirm.
5671  *				  I think that this function is being called from too many
5672  *				  different contexts where it really needs to react differently.
5673  *				  So pass in more information about where we are coming from.
5674  *
5675  *		F 		- Always specified as parameter in the references.
5676  *
5677  * Description:	This is called for:
5678  *		- UI command with P=1 then F=1.
5679  *		- LM seize confirm with ack pending then F=0.  (TODO: not clear on this yet.)
5680  *			TODO:  I think we want to ensure that this function is called ONLY
5681  *			for RR/RNR/I command with P=1.  LM Seize confirm can do its own thing and
5682  *			not get involved in this complication.
5683  *		- check_need_for_response(), command & P=1, then F=1
5684  *		- RR/RNR/REJ command & P=1, then F=1
5685  *
5686  *		In all cases, we see that F has been specified, usually 1 because it is
5687  *		a response to a command with P=1.
5688  *		Specifying F would imply response when the flow chart says RR/RNR command.
5689  *		The documentation says:
5690  *
5691  *		6.2. Poll/Final (P/F) Bit Procedures
5692  *
5693  *		The next response frame returned to an I frame with the P bit set to "1", received during the information
5694  *		transfer state, is an RR, RNR or REJ response with the F bit set to "1".
5695  *
5696  *		The next response frame returned to a supervisory command frame with the P bit set to "1", received during
5697  *		the information transfer state, is an RR, RNR or REJ response frame with the F bit set to "1".
5698  *
5699  * Erattum!	The flow chart says RR/RNR *command* but I'm confident it should be response.
5700  *
5701  * Erratum:	Ax.25 spec has nothing here for SREJ.  See X.25 2.4.6.11 for explanation.
5702  *
5703  *------------------------------------------------------------------------------*/
5704 
enquiry_response(ax25_dlsm_t * S,ax25_frame_type_t frame_type,int f)5705 static void enquiry_response (ax25_dlsm_t *S, ax25_frame_type_t frame_type, int f)
5706 {
5707 	cmdres_t cr = cr_res;		// Response, not command as seen in flow chart.
5708 	int nr = S->vr;
5709 	packet_t pp;
5710 
5711 
5712 	if (s_debug_retry) {
5713 	  text_color_set(DW_COLOR_ERROR);
5714 	  dw_printf ("\n****** ENQUIRY RESPONSE  F=%d ******\n\n", f);
5715 	}
5716 
5717 #if 1			// Detour 1
5718 
5719 			// My addition,  Based on X.25 2.4.6.11.
5720 			// Only for RR, RNR, I.
5721 			// See sequence of events in transmit_enquiry comments.
5722 
5723 	if (f == 1 && (frame_type == frame_type_S_RR || frame_type == frame_type_S_RNR || frame_type == frame_type_I)) {
5724 
5725 	  if (S->own_receiver_busy) {
5726 
5727 // I'm busy.
5728 
5729 	    pp = ax25_s_frame (S->addrs, S->num_addr, cr, frame_type_S_RNR, S->modulo, nr, f, NULL, 0);
5730 	    lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5731 
5732 	    S->acknowledge_pending = 0;		// because we sent N(R) from V(R).
5733 	  }
5734 
5735 	  else if (S->srej_enable == srej_single || S->srej_enable == srej_multi) {
5736 
5737 
5738 // SREJ is enabled. This is based on X.25 2.4.6.11.
5739 
5740 	    if (S->modulo != 128) {
5741 	      text_color_set(DW_COLOR_ERROR);
5742 	      dw_printf ("INTERNAL ERROR: enquiry response should not be sending SREJ for modulo 8.\n");
5743 	    }
5744 
5745 // Suppose we received I frames with N(S) of 0, 3, 7.
5746 // V(R) is still 1 because 0 is the last one received with contiguous N(S) values.
5747 // 3 and 7 have been saved into S->rxdata_by_ns.
5748 // We have outstanding requests to resend 1, 2, 4, 5, 6.
5749 // Either those requests or the replies got lost.
5750 // The other end timed out and asked us what is happening by sending RR/RNR command P=1.
5751 
5752 // First see if we have any out of sequence frames in the receive buffer.
5753 
5754 	    int last;
5755 	    last = AX25MODULO(S->vr - 1, S->modulo, __FILE__, __func__, __LINE__);
5756 	    while (last != S->vr && S->rxdata_by_ns[last] == NULL) {
5757 	      last = AX25MODULO(last - 1, S->modulo, __FILE__, __func__, __LINE__);
5758 	    }
5759 
5760 	    if (last != S->vr) {
5761 
5762 // Ask for missing frames to be sent again.		X.25 2.4.6.11 b) & 2.3.5.2.2
5763 
5764 	      int resend[128];
5765 	      int count = 0;
5766 	      int j;
5767 	      int allow_f1 = 1;
5768 
5769 	      j = S->vr;
5770 	      while (j != last) {
5771 	        if (S->rxdata_by_ns[j] == NULL) {
5772 	          resend[count++] = j;
5773 	        }
5774 	        j = AX25MODULO(j + 1, S->modulo, __FILE__, __func__, __LINE__);
5775 	      }
5776 
5777 	      send_srej_frames (S, resend, count, allow_f1);
5778 	    }
5779 	    else {
5780 
5781 // Not waiting for fill in of missing frames.		X.25 2.4.6.11 c)
5782 
5783 	      pp = ax25_s_frame (S->addrs, S->num_addr, cr, frame_type_S_RR, S->modulo, nr, f, NULL, 0);
5784 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5785 
5786 	      S->acknowledge_pending = 0;
5787 	    }
5788 
5789 	  } else {
5790 
5791 // SREJ not enabled.
5792 // One might get the idea that it would make sense send REJ here if the reject exception is set.
5793 // However, I can't seem to find that buried in X.25 2.4.5.9.
5794 // And when we look at what happens when RR response, F=1 is received in state 4, it is
5795 // effectively REJ when N(R) is not the same as V(S).
5796 
5797 	    if (s_debug_retry) {
5798 	      text_color_set(DW_COLOR_ERROR);
5799 	      dw_printf ("\n****** ENQUIRY RESPONSE srej not enbled, sending RR resp F=%d ******\n\n", f);
5800 	    }
5801 
5802 	    pp = ax25_s_frame (S->addrs, S->num_addr, cr, frame_type_S_RR, S->modulo, nr, f, NULL, 0);
5803 	    lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5804 
5805 	    S->acknowledge_pending = 0;
5806 	  }
5807 
5808 	} // end of RR,RNR,I cmd with P=1
5809 
5810 	else {
5811 
5812 // For cases other than (RR, RNR, I) command, P=1.
5813 
5814 	  pp = ax25_s_frame (S->addrs, S->num_addr, cr, S->own_receiver_busy ? frame_type_S_RNR : frame_type_S_RR, S->modulo, nr, f, NULL, 0);
5815 	  lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5816 
5817 	  S->acknowledge_pending = 0;
5818 	}
5819 
5820 #else
5821 
5822 // As found in AX.25 spec.
5823 // Erratum:  This is woefully inadequate when SREJ is enabled.
5824 // Erratum:  Flow chart says RR/RNR command but I'm confident it should be response.
5825 
5826 	pp = ax25_s_frame (S->addrs, S->num_addr, cr, S->own_receiver_busy ? frame_type_S_RNR : frame_type_S_RR, S->modulo, nr, f, NULL, 0);
5827 	lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5828 
5829 	S->acknowledge_pending = 0;
5830 
5831 # endif
5832 
5833 } /* end enquiry_response */
5834 
5835 
5836 
5837 
5838 /*------------------------------------------------------------------------------
5839  *
5840  * Name:	invoke_retransmission
5841  *
5842  * Inputs:	nr_input	- Resend starting with this.
5843  *			  	  Continue will all up to and including current V(S) value.
5844  *
5845  * Description:	Resend one or more frames that have already been sent.
5846  *		Should always send at least one.
5847  *
5848  *		This is probably the result of getting REJ asking for a resend.
5849  *
5850  * Context:	I would expect the caller to clear 'acknowledge_pending' after calling this
5851  *		because we sent N(R), from V(R), to ack what was received from other guy.
5852  *		I would also expect Stop T3 & Start T1 at the same place.
5853  *
5854  *------------------------------------------------------------------------------*/
5855 
invoke_retransmission(ax25_dlsm_t * S,int nr_input)5856 static void invoke_retransmission (ax25_dlsm_t *S, int nr_input)
5857 {
5858 
5859 // Original flow chart showed saving V(S) into temp variable x,
5860 // using V(S) as loop control variable, and finally restoring it
5861 // to original value before returning.
5862 // Here we just a local variable instead of messing with it.
5863 // This should be equivalent but safer.
5864 
5865 	int local_vs;
5866 	int sent_count = 0;
5867 
5868 	if (s_debug_misc) {
5869 	  text_color_set(DW_COLOR_ERROR);
5870 	  dw_printf ("invoke_retransmission(): starting with %d, state=%d, rc=%d, \n", nr_input, S->state, S->rc);
5871 	}
5872 
5873 // I don't think we should be here if SREJ is enabled.
5874 // TODO: Figure out why this happens occasionally.
5875 
5876 //	if (S->srej_enable != srej_none) {
5877 //	  text_color_set(DW_COLOR_ERROR);
5878 //	  dw_printf ("Internal Error, Did not expect to be here when SREJ enabled.  %s %s %d\n", __FILE__, __func__, __LINE__);
5879 //	}
5880 
5881 	if (S->txdata_by_ns[nr_input] == NULL) {
5882 	  text_color_set(DW_COLOR_ERROR);
5883 	  dw_printf ("Internal Error, Can't resend starting with N(S) = %d.  It is not available.  %s %s %d\n", nr_input, __FILE__, __func__, __LINE__);
5884 	  return;
5885 	}
5886 
5887 
5888 	local_vs = nr_input;
5889 	do {
5890 
5891 	  if (S->txdata_by_ns[local_vs] != NULL) {
5892 
5893 	    cmdres_t cr = cr_cmd;
5894 	    int ns = local_vs;
5895 	    int nr = S->vr;
5896  	    int p = 0;
5897 
5898 	    if (s_debug_misc) {
5899 	      text_color_set(DW_COLOR_INFO);
5900 	      dw_printf ("invoke_retransmission(): Resending N(S) = %d\n", ns);
5901 	    }
5902 
5903 	    packet_t pp = ax25_i_frame (S->addrs, S->num_addr, cr, S->modulo, nr, ns, p,
5904 		S->txdata_by_ns[ns]->pid, (unsigned char *)(S->txdata_by_ns[ns]->data), S->txdata_by_ns[ns]->len);
5905 
5906 	    lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
5907 	    // Keep it around in case we need to send again.
5908 
5909 	    sent_count++;
5910 	  }
5911 	  else {
5912 	    text_color_set(DW_COLOR_ERROR);
5913 	    dw_printf ("Internal Error, state=%d, need to retransmit N(S) = %d for REJ but it is not available.  %s %s %d\n", S->state, local_vs, __FILE__, __func__, __LINE__);
5914 	  }
5915 	  local_vs = AX25MODULO(local_vs + 1, S->modulo, __FILE__, __func__, __LINE__);
5916 
5917 	} while (local_vs != S->vs);
5918 
5919 	if (sent_count == 0) {
5920 	  text_color_set(DW_COLOR_ERROR);
5921 	  dw_printf ("Internal Error, Nothing to retransmit. N(R)=%d, %s %s %d\n", nr_input, __FILE__, __func__, __LINE__);
5922 	}
5923 
5924 }  /* end invoke_retransmission */
5925 
5926 
5927 
5928 /*------------------------------------------------------------------------------
5929  *
5930  * Name:	check_i_frame_ackd
5931  *
5932  * Purpose:
5933  *
5934  * Inputs:	nr	- N(R) from I or S frame, acknowledging receipt thru N(R)-1.
5935  *			  i.e. The next one expected by the peer is N(R).
5936  *
5937  * Outputs:	S->va	- updated from nr.
5938  *
5939  * Description:	This is called for:
5940  *		- 'I' frame received and N(R) is in expected range, states 3 & 4.
5941  *		- RR/RNR command with p=1 received and N(R) is in expected range, state 3 only.
5942  *
5943  *------------------------------------------------------------------------------*/
5944 
check_i_frame_ackd(ax25_dlsm_t * S,int nr)5945 static void check_i_frame_ackd (ax25_dlsm_t *S, int nr)
5946 {
5947 	if (S->peer_receiver_busy) {
5948 	  SET_VA(nr);
5949 
5950 	  // Erratum?  This looks odd to me.
5951 	  // It doesn't seem right that we would have T3 and T1 running at the same time.
5952 	  // Normally we stop one when starting the other.
5953 	  // Should this be Stop T3 instead?
5954 
5955 	  START_T3;
5956 	  if ( ! IS_T1_RUNNING) {
5957 	    START_T1;
5958 	  }
5959 	}
5960 	else if (nr == S->vs) {
5961 	  SET_VA(nr);
5962 	  STOP_T1;
5963 	  START_T3;
5964 	  select_t1_value (S);
5965 	}
5966 	else if (nr != S->va) {
5967 
5968 	  if (s_debug_misc) {
5969 	    text_color_set(DW_COLOR_DEBUG);
5970 	    dw_printf ("check_i_frame_ackd n(r)=%d, v(a)=%d,  Set v(a) to new value %d\n", nr, S->va, nr);
5971 	  }
5972 
5973 	  SET_VA(nr);
5974 	  START_T1;			// Erratum?  Flow chart says "restart" rather than "start."
5975 					// Is this intentional, what is the difference?
5976 	}
5977 
5978 } /* check_i_frame_ackd */
5979 
5980 
5981 
5982 /*------------------------------------------------------------------------------
5983  *
5984  * Name:	check_need_for_response
5985  *
5986  * Inputs:	frame_type	- frame_type_S_RR, etc.
5987  *
5988  *		cr		- Is it a command or response?
5989  *
5990  *		pf		- P/F from the frame.
5991  *
5992  * Description:	This is called for RR, RNR, and REJ frames.
5993  *		If it is a command with P=1, we reply with RR or RNR with F=1.
5994  *
5995  *------------------------------------------------------------------------------*/
5996 
check_need_for_response(ax25_dlsm_t * S,ax25_frame_type_t frame_type,cmdres_t cr,int pf)5997 static void check_need_for_response (ax25_dlsm_t *S, ax25_frame_type_t frame_type, cmdres_t cr, int pf)
5998 {
5999 	if (cr == cr_cmd && pf == 1) {
6000 	  int f = 1;
6001 	  enquiry_response (S, frame_type, f);
6002 	}
6003 	else if (cr == cr_res && pf == 1) {
6004 	  if (s_debug_protocol_errors) {
6005 	    text_color_set(DW_COLOR_ERROR);
6006 	    dw_printf ("Stream %d: AX.25 Protocol Error A: F=1 received but P=1 not outstanding.\n", S->stream_id);
6007 	  }
6008 	}
6009 
6010 } /* end check_need_for_response */
6011 
6012 
6013 
6014 /*------------------------------------------------------------------------------
6015  *
6016  * Name:	ui_check
6017  *
6018  * Description:	I don't think we need this because UI frames are processed
6019  *		without going thru the data link state machine.
6020  *
6021  *------------------------------------------------------------------------------*/
6022 
6023 /*------------------------------------------------------------------------------
6024  *
6025  * Name:	select_t1_value
6026  *
6027  * Purpose:	Dynamically adjust the T1 timeout value, commonly a fixed time known as FRACK.
6028  *
6029  * Inputs:	S->rc			Retry counter.
6030  *
6031  *		S->srt			Smoothed roundtrip time in seconds.
6032  *
6033  *		S->t1_remaining_when_last_stopped
6034  *					Seconds left on T1 when it is stopped.
6035  *
6036  * Outputs:	S->srt			New smoothed roundtrip time.
6037  *
6038  *		S->t1v			How long to wait for an acknowlegement before resending.
6039  *					Value used when starting timer T1, in seconds.
6040  *					Here it is dynamically adjusted.
6041  *
6042  * Description:	How long should we wait for an ACK before sending again or giving up?
6043  *		some implementations have a fixed length time.  This is usually the FRACK parameter,
6044  *		typically 3 seconds (D710A) or 4 seconds (KPC-3+).
6045  *
6046  *		This should be increased for each digipeater in the path.
6047  *		Here it is dynamically adjusted by taking the average time it takes to get a response
6048  *		and then we double it.
6049  *
6050  * Rambling:	It seems like a good idea to adapt to channel conditions, such as digipeater delays,
6051  *		but it is fraught with peril if you are not careful.
6052  *
6053  *		For example, if we accept an incoming connection and only receive some I frames and
6054  *		send no I frames, T1 never gets started.  In my earlier attempt, 't1_remaining_when_last_stopped'
6055  *		had the initial value of 0 lacking any reason to set it differently.   The calculation here
6056  *		then kept pushing t1v up up up.  After receiving 20 I frames and sending none,
6057  *		t1v was over 300 seconds!!!
6058  *
6059  *		We need some way to indicate that 't1_remaining_when_last_stopped' is not valid and
6060  *		not to use it.  Rather than adding a new variable, it is set to a negative value
6061  *		initially to mean it has not been set yet.  That solves one problem.
6062  *
6063  *		T1 is paused whenever the channel is busy, either transmitting or receiving,
6064  *		so the measured time could turn out to be a tiny fraction of a second, much less than
6065  *		the frame transmission time.
6066  *		If this gets too low, an unusually long random delay, before the sender's transmission,
6067  *		could exceed this.  I put in a lower limit for t1v, currently 1 second.
6068  *
6069  *		What happens if we get multiple timeouts because we don't get a response?
6070  *		For example, when we try to connect to a station which is not there, a KPC-3+ will give
6071  *		up and report failure after 10 tries x 4 sec = 40 seconds.
6072  *
6073  *		The algorithm in the AX.25 protocol spec shows increasing timeout values.
6074  *		It might seem like a good idea but either it was not thought out very well
6075  *		or I am not understanding it.  If it is doubled each time, it gets awful large
6076  *		very quickly.   If we try to connect to a station which is not there,
6077  *		we want to know within a minute, not an hour later.
6078  *
6079  *		Keeping with the spirit of increasing the time but keeping it sane,
6080  *		I increase the time linearly by a fraction of a second.
6081  *
6082  *------------------------------------------------------------------------------*/
6083 
6084 
select_t1_value(ax25_dlsm_t * S)6085 static void select_t1_value (ax25_dlsm_t *S)
6086 {
6087 	float old_srt = S->srt;
6088 
6089 
6090 // Erratum:  I don't think this test for RC == 0 is valid.
6091 // We would need to set RC to 0 whenever we enter state 3 and we don't do that.
6092 // I think a more appropriate test would be to check if we are in state 3.
6093 // When things are going smoothly, it makes sense to fine tune timeout based on smoothed round trip time.
6094 // When in some other state, we might want to slowly increase the time to minimize collisions.
6095 // Maybe the solution is to set RC=0 when we enter state 3.
6096 
6097 // TODO: come back and revisit this.
6098 
6099 	if (S->rc == 0) {
6100 
6101 	  if (S->t1_remaining_when_last_stopped >= 0) {		// Negative means invalid, don't use it.
6102 
6103 	    // This is an IIR low pass filter.
6104 	    // Algebraically equivalent to version in AX.25 protocol spec but I think the
6105 	    // original intent is clearer by having 1/8 appear only once.
6106 
6107 	    S->srt = 7./8. * S->srt + 1./8. * ( S->t1v - S->t1_remaining_when_last_stopped );
6108 	  }
6109 
6110 	  // We pause T1 when the channel is busy.
6111 	  // This includes both receiving someone else and us transmitting.
6112 	  // This can result in the round trip time going down to almost nothing.
6113 	  // My enhancement is to prevent srt from going below one second so
6114 	  // t1v should never be less than 2 seconds.
6115 	  // When t1v was allowed to go down to 1, we got occastional timeouts
6116 	  // even under ideal conditions, probably due to random CSMA delay time.
6117 
6118 	  if (S->srt < 1) {
6119 
6120 	    S->srt = 1;
6121 
6122 	    // Add another 2 seconds for each digipeater in path.
6123 
6124 	    if (S->num_addr > 2) {
6125 	      S->srt += 2 * (S->num_addr - 2);
6126 	    }
6127 	  }
6128 
6129 	  S->t1v = S->srt * 2;
6130 	}
6131 	else {
6132 
6133 	  if (S->t1_had_expired) {
6134 
6135 	    // This goes up exponentially if implemented as documented!
6136 	    // For example, if we were trying to connect to a station which is not there, we
6137 	    // would retry after 3, the 8, 16, 32, ...  and not time out for over an hour.
6138 	    // That's ridiculous.   Let's try increasing it by a quarter second each time.
6139 	    // We now give up after about a minute.
6140 
6141 	    // NO! S->t1v = powf(2, S->rc+1) * S->srt;
6142 
6143 	    S->t1v = S->rc * 0.25 + S->srt * 2;
6144 	  }
6145 	}
6146 
6147 	if (s_debug_timers) {
6148 	  text_color_set(DW_COLOR_DEBUG);
6149 	  dw_printf ("Stream %d: select_t1_value, rc = %d, t1 remaining = %.3f, old srt = %.3f, new srt = %.3f, new t1v = %.3f\n",
6150 		S->stream_id, S->rc, S->t1_remaining_when_last_stopped, old_srt, S->srt, S->t1v);
6151 	}
6152 
6153 
6154 	if (S->t1v < 0.99 || S->t1v > 30) {
6155 	  text_color_set(DW_COLOR_ERROR);
6156 	  dw_printf ("INTERNAL ERROR?  Stream %d: select_t1_value, rc = %d, t1 remaining = %.3f, old srt = %.3f, new srt = %.3f, Extreme new t1v = %.3f\n",
6157 		S->stream_id, S->rc, S->t1_remaining_when_last_stopped, old_srt, S->srt, S->t1v);
6158 	}
6159 
6160 } /* end select_t1_value */
6161 
6162 
6163 /*------------------------------------------------------------------------------
6164  *
6165  * Name:	set_version_2_0
6166  *
6167  * Erratum:	Flow chart refers to T2 which doesn't appear anywhere else.
6168  *
6169  *------------------------------------------------------------------------------*/
6170 
set_version_2_0(ax25_dlsm_t * S)6171 static void set_version_2_0 (ax25_dlsm_t *S)
6172 {
6173 	S->srej_enable = srej_none;
6174 	S->modulo = 8;
6175 	S->n1_paclen = g_misc_config_p->paclen;
6176 	S->k_maxframe = g_misc_config_p->maxframe_basic;
6177 	S->n2_retry = g_misc_config_p->retry;
6178 
6179 } /* end set_version_2_0 */
6180 
6181 
6182 /*------------------------------------------------------------------------------
6183  *
6184  * Name:	set_version_2_2
6185  *
6186  *------------------------------------------------------------------------------*/
6187 
set_version_2_2(ax25_dlsm_t * S)6188 static void set_version_2_2 (ax25_dlsm_t *S)
6189 {
6190 	S->srej_enable = srej_single;	// Start with single.
6191 					// Can be increased to multi with XID exchange.
6192 	S->modulo = 128;
6193 	S->n1_paclen = g_misc_config_p->paclen;
6194 	S->k_maxframe = g_misc_config_p->maxframe_extended;
6195 	S->n2_retry = g_misc_config_p->retry;
6196 
6197 } /* end set_version_2_2 */
6198 
6199 
6200 
6201 
6202 /*------------------------------------------------------------------------------
6203  *
6204  * Name:	is_good_nr
6205  *
6206  * Purpose:	Evaluate condition "V(a) <= N(r) <= V(s)" which appears in flow charts
6207  *		for incoming I, RR, RNR, REJ, and SREJ frames.
6208  *
6209  * Inputs:	S		- state machine.  Contains V(a) and V(s).
6210  *
6211  *		nr		- N(r) found in the incoming frame.
6212  *
6213  * Description:	This determines whether the Received Sequence Number, N(R), is in
6214  *		the expected range for normal processing or if we have an error
6215  *		condition that needs recovery.
6216  *
6217  *		This gets tricky due to the wrap around of sequence numbers.
6218  *
6219  *		4.2.4.4. Received Sequence Number N(R)
6220  *
6221  *		The received sequence number exists in both I and S frames.
6222  *		Prior to sending an I or S frame, this variable is updated to equal that
6223  *		of the received state variable, thus implicitly acknowledging the proper
6224  *		reception of all frames up to and including N(R)-1.
6225  *
6226  * Pattern noticed:  Anytime we have "is_good_nr" returning true, we should always
6227  *			- set V(A) from N(R) or
6228  *			- call "check_i_frame_ackd" which does the same and some timer stuff.
6229  *
6230  *------------------------------------------------------------------------------*/
6231 
6232 
is_good_nr(ax25_dlsm_t * S,int nr)6233 static int is_good_nr (ax25_dlsm_t *S, int nr)
6234 {
6235 	int adjusted_va, adjusted_nr, adjusted_vs;
6236 	int result;
6237 
6238 /* Adjust all values relative to V(a) before comparing so we won't have wrap around. */
6239 
6240 #define adjust_by_va(x) (AX25MODULO((x) - S->va, S->modulo, __FILE__, __func__, __LINE__))
6241 
6242 	adjusted_va = adjust_by_va(S->va);	// A clever compiler would know it is zero.
6243 	adjusted_nr = adjust_by_va(nr);
6244 	adjusted_vs = adjust_by_va(S->vs);
6245 
6246 	result = adjusted_va <= adjusted_nr && adjusted_nr <= adjusted_vs;
6247 
6248 	if (s_debug_misc) {
6249 	  text_color_set(DW_COLOR_DEBUG);
6250 	  dw_printf ("is_good_nr,  V(a) %d <= nr %d <= V(s) %d, returns %d\n", S->va, nr, S->vs, result);
6251 	}
6252 
6253 	return (result);
6254 
6255 } /* end is_good_nr */
6256 
6257 
6258 
6259 /*------------------------------------------------------------------------------
6260  *
6261  * Name:	i_frame_pop_off_queue
6262  *
6263  * Purpose:	Transmit an I frame if we have one in the queue and conditions are right.
6264  *		This appears two slightly different ways in the flow charts:
6265  *		"frame pop off queue"
6266  *		"I frame pops off queue"
6267  *
6268  * Inputs:	i_frame_queue		- Remove items from here.
6269  *		peer_receiver_busy	- If other end not busy.
6270  *		V(s)			- and we haven't reached window size.
6271  *		V(a)
6272  *		k
6273  *
6274  * Outputs:	v(s) is incremented for each processed.
6275  *		acknowledge_pending = 0
6276  *
6277  *------------------------------------------------------------------------------*/
6278 
i_frame_pop_off_queue(ax25_dlsm_t * S)6279 static void i_frame_pop_off_queue (ax25_dlsm_t *S)
6280 {
6281 
6282 
6283 	if (s_debug_misc) {
6284 	  //text_color_set(DW_COLOR_DEBUG);
6285 	  //dw_printf ("i_frame_pop_off_queue () state=%d\n", S->state);
6286 	}
6287 
6288 // TODO:  Were we expecting something in the queue?
6289 // or is empty an expected situation?
6290 
6291 	if (S->i_frame_queue == NULL) {
6292 
6293 	  if (s_debug_misc) {
6294 	    // TODO: add different switch for I frame queue.
6295 	    //text_color_set(DW_COLOR_DEBUG);
6296 	    //dw_printf ("i_frame_pop_off_queue () queue is empty get out, line %d\n", __LINE__);
6297 	  }
6298 
6299 	  // I Frame queue is empty.
6300 	  // Nothing to see here, folks.  Move along.
6301 	  return;
6302 	}
6303 
6304 	switch (S->state) {
6305 
6306 	  case 	state_1_awaiting_connection:
6307 	  case 	state_5_awaiting_v22_connection:
6308 
6309 	    if (s_debug_misc) {
6310 	      //text_color_set(DW_COLOR_DEBUG);
6311 	      //dw_printf ("i_frame_pop_off_queue () line %d\n", __LINE__);
6312 	    }
6313 
6314 	    // This seems to say remove the I Frame from the queue and discard it if "layer 3 initiated" is set.
6315 
6316 	    // For the case of removing it from the queue and putting it back in we just leave it there.
6317 
6318 	    // Erratum?  The flow chart seems to be backwards.
6319 	    // It would seem like we want to keep it if we are further along in the connection process.
6320 	    // I don't understand the intention here, and can't make a compelling argument on why it
6321 	    // is backwards, so it is implemented as documented.
6322 
6323 	    if (S->layer_3_initiated) {
6324 	      cdata_t *txdata;
6325 
6326 	      if (s_debug_misc) {
6327 	        //text_color_set(DW_COLOR_DEBUG);
6328 	        //dw_printf ("i_frame_pop_off_queue () discarding due to L3 init. line %d\n", __LINE__);
6329 	      }
6330 	      txdata = S->i_frame_queue;		// Remove from head of list.
6331 	      S->i_frame_queue = txdata->next;
6332 	      cdata_delete (txdata);
6333 	    }
6334 	    break;
6335 
6336 	  case 	state_3_connected:
6337 	  case 	state_4_timer_recovery:
6338 
6339 	    if (s_debug_misc) {
6340 	      //text_color_set(DW_COLOR_DEBUG);
6341 	      //dw_printf ("i_frame_pop_off_queue () state %d, line %d\n", S->state, __LINE__);
6342 	    }
6343 
6344 	    while ( ( ! S->peer_receiver_busy ) &&
6345 	            S->i_frame_queue != NULL &&
6346 	            WITHIN_WINDOW_SIZE(S) ) {
6347 
6348 	      cdata_t *txdata;
6349 
6350 	      txdata = S->i_frame_queue;		// Remove from head of list.
6351 	      S->i_frame_queue = txdata->next;
6352 	      txdata->next = NULL;
6353 
6354 	      cmdres_t cr = cr_cmd;
6355 	      int ns = S->vs;
6356 	      int nr = S->vr;
6357  	      int p = 0;
6358 
6359 	      if (s_debug_misc || s_debug_radio) {
6360 	        //dw_printf ("i_frame_pop_off_queue () ns=%d, queue for transmit \"", ns);
6361 	        //ax25_safe_print (txdata->data, txdata->len, 1);
6362 	        //dw_printf ("\"\n");
6363 	      }
6364 	      packet_t pp = ax25_i_frame (S->addrs, S->num_addr, cr, S->modulo, nr, ns, p, txdata->pid, (unsigned char *)(txdata->data), txdata->len);
6365 
6366 	      if (s_debug_misc) {
6367 	        //text_color_set(DW_COLOR_DEBUG);
6368 	        //dw_printf ("calling lm_data_request for I frame, %s line %d\n", __func__, __LINE__);
6369 	      }
6370 
6371 	      lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
6372 
6373 	      // Stash in sent array in case it gets lost and needs to be sent again.
6374 
6375 	      if (S->txdata_by_ns[ns] != NULL) {
6376 	        cdata_delete (S->txdata_by_ns[ns]);
6377 	      }
6378 	      S->txdata_by_ns[ns] = txdata;
6379 
6380 	      SET_VS(AX25MODULO(S->vs + 1, S->modulo, __FILE__, __func__, __LINE__));		// increment sequence of last sent.
6381 
6382 	      S->acknowledge_pending = 0;
6383 
6384 // Erratum:  I think we always want to restart T1 when an I frame is sent.
6385 // Otherwise we could time out too soon.
6386 #if 1
6387 	      STOP_T3;
6388 	      START_T1;
6389 #else
6390 	      if ( ! IS_T1_RUNNING) {
6391 	        STOP_T3;
6392 	        START_T1;
6393 	      }
6394 #endif
6395 	    }
6396 	    break;
6397 
6398 	  case 	state_0_disconnected:
6399 	  case 	state_2_awaiting_release:
6400 
6401 	    // Do nothing.
6402 	    break;
6403 	}
6404 
6405 } /* end i_frame_pop_off_queue */
6406 
6407 
6408 
6409 
6410 /*------------------------------------------------------------------------------
6411  *
6412  * Name:	discard_i_queue
6413  *
6414  * Purpose:	Discard any data chunks waiting to be sent.
6415  *
6416  *------------------------------------------------------------------------------*/
6417 
6418 
discard_i_queue(ax25_dlsm_t * S)6419 static void discard_i_queue (ax25_dlsm_t *S)
6420 {
6421 	cdata_t *t;
6422 
6423 	while (S->i_frame_queue != NULL) {
6424 
6425 	  t = S->i_frame_queue;
6426 	  S->i_frame_queue = S->i_frame_queue->next;
6427 	  cdata_delete (t);
6428 	}
6429 
6430 } /* end discard_i_queue */
6431 
6432 
6433 
6434 /*------------------------------------------------------------------------------
6435  *
6436  * Name:	enter_new_state
6437  *
6438  * Purpose:	Switch to new state.
6439  *
6440  * Description:	Use a function, rather than setting variable directly, so we have
6441  *		one common point for debug output and possibly other things we
6442  *		might want to do at a state change.
6443  *
6444  *------------------------------------------------------------------------------*/
6445 
6446 // TODO:  requeuing???
6447 
enter_new_state(ax25_dlsm_t * S,enum dlsm_state_e new_state,const char * from_func,int from_line)6448 static void enter_new_state (ax25_dlsm_t *S, enum dlsm_state_e new_state, const char *from_func, int from_line)
6449 {
6450 
6451 	if (s_debug_variables) {
6452 	  text_color_set(DW_COLOR_ERROR);
6453 	  dw_printf ("\n");
6454 	  dw_printf (">>> NEW STATE = %d, previously %d, called from %s %d <<<\n", new_state, S->state, from_func, from_line);
6455 	  dw_printf ("\n");
6456 	}
6457 
6458 	assert (new_state >= 0 && new_state <= 5);
6459 
6460 
6461 	if (( new_state == state_3_connected || new_state == state_4_timer_recovery) &&
6462 	       S->state != state_3_connected &&  S->state != state_4_timer_recovery ) {
6463 
6464 	  ptt_set (OCTYPE_CON, S->chan, 1);		// Turn on connected indicator if configured.
6465 	}
6466 	else if (( new_state != state_3_connected && new_state != state_4_timer_recovery) &&
6467 	         (  S->state == state_3_connected ||  S->state == state_4_timer_recovery ) ) {
6468 
6469 	  ptt_set (OCTYPE_CON, S->chan, 0);		// Turn off connected indicator if configured.
6470 							// Ideally we should look at any other link state machines
6471 							// for this channel and leave the indicator on if any
6472 							// are connected.  I'm not that worried about it.
6473 	}
6474 
6475 	S->state = new_state;
6476 
6477 } /* end enter_new_state */
6478 
6479 
6480 
6481 /*------------------------------------------------------------------------------
6482  *
6483  * Name:	mdl_negotiate_request
6484  *
6485  * Purpose:	After receiving UA, in response to SABME, this starts up the XID exchange.
6486  *
6487  * Description:	Send XID command.
6488  *		Start timer TM201 so we can retry if timeout waiting for response.
6489  *		Enter MDL negotiating state.
6490  *
6491  *------------------------------------------------------------------------------*/
6492 
mdl_negotiate_request(ax25_dlsm_t * S)6493 static void mdl_negotiate_request (ax25_dlsm_t *S)
6494 {
6495 	struct xid_param_s param;
6496 	unsigned char xinfo[40];
6497 	int xlen;
6498 	cmdres_t cmd = cr_cmd;
6499 	int p = 1;
6500 	int nopid = 0;
6501 	packet_t pp;
6502 	int n;
6503 
6504 // At least one known [partial] v2.2 implementation understands SABME but not XID.
6505 // Rather than wasting time, sending XID repeatedly until giving up, we have a workaround.
6506 // The configuration file can contain a list of stations known not to respond to XID.
6507 // Obviously this applies only to v2.2 because XID was not part of v2.0.
6508 
6509 	for (n = 0; n < g_misc_config_p->noxid_count; n++) {
6510 	  if (strcmp(S->addrs[PEERCALL],g_misc_config_p->noxid_addrs[n]) == 0) {
6511 	    return;
6512 	  }
6513 	}
6514 
6515 	switch (S->mdl_state) {
6516 
6517 	  case 	mdl_state_0_ready:
6518 
6519 	    initiate_negotiation (S, &param);
6520 
6521 	    xlen = xid_encode (&param, xinfo, cmd);
6522 
6523 	    pp = ax25_u_frame (S->addrs, S->num_addr, cmd, frame_type_U_XID, p, nopid, xinfo, xlen);
6524 	    lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
6525 
6526 	    S->mdl_rc = 0;
6527 	    START_TM201;
6528 	    S->mdl_state = mdl_state_1_negotiating;
6529 
6530 	    break;
6531 
6532 	  case 	mdl_state_1_negotiating:
6533 
6534 	    // SDL says "requeue" but I don't understand how it would be useful or how to do it.
6535 	    break;
6536 	}
6537 
6538 } /* end mdl_negotiate_request */
6539 
6540 
6541 /*------------------------------------------------------------------------------
6542  *
6543  * Name:	initiate_negotiation
6544  *
6545  * Purpose:	Used when preparing the XID *command*.
6546  *
6547  * Description:	Prepare set of parameters to request from the other station.
6548  *
6549  *------------------------------------------------------------------------------*/
6550 
initiate_negotiation(ax25_dlsm_t * S,struct xid_param_s * param)6551 static void initiate_negotiation (ax25_dlsm_t *S, struct xid_param_s *param)
6552 {
6553 	    param->full_duplex = 0;
6554 	    switch (S->srej_enable) {
6555 	      case srej_single:
6556 	      case srej_multi:
6557 	        param->srej = srej_multi;	// see if other end reconizes it.
6558 	        break;
6559 	      case srej_none:
6560 	      default:
6561 	        param->srej = srej_none;
6562 	        break;
6563 	    }
6564 
6565 	    param->modulo = S->modulo;
6566 	    param->i_field_length_rx = S->n1_paclen;	// Hmmmm.  Should we ask for what the user
6567 							// specified for PACLEN or offer the maximum
6568 							// that we can handle, AX25_N1_PACLEN_MAX?
6569 	    param->window_size_rx = S->k_maxframe;
6570 	    param->ack_timer = (int)(g_misc_config_p->frack * 1000);
6571 	    param->retries = S->n2_retry;
6572 }
6573 
6574 
6575 /*------------------------------------------------------------------------------
6576  *
6577  * Name:	negotiation_response
6578  *
6579  * Purpose:	Used when receiving the XID command and preparing the XID response.
6580  *
6581  * Description:	Take what other station has asked for and reduce if we have lesser capabilities.
6582  *		For example if other end wants 8k information part we reduce it to 2k.
6583  *		Ack time and retries are the opposite, we take the maximum.
6584  *
6585  * Question:	If the other send leaves anything undefined should we leave it
6586  *		undefined or fill in what we would like before sending it back?
6587  *
6588  *		The original version of the protocol spec left this open.
6589  *		The 2006 revision, in red, says we should fill in defaults for anything
6590  *		not specified.  This makes sense.  We send back a complete set of parameters
6591  *		so both ends should agree.
6592  *
6593  *------------------------------------------------------------------------------*/
6594 
negotiation_response(ax25_dlsm_t * S,struct xid_param_s * param)6595 static void negotiation_response (ax25_dlsm_t *S, struct xid_param_s *param)
6596 {
6597 
6598 // TODO: Integrate with new full duplex capability in v1.5.
6599 
6600 	param->full_duplex = 0;
6601 
6602 // Other end might want 8.
6603 // Seems unlikely.  If it implements XID it should have modulo 128.
6604 
6605 	if (param->modulo == modulo_unknown) {
6606 	  param->modulo = 8;			// Not specified.  Set default.
6607 	}
6608 	else {
6609 	  param->modulo = MIN(param->modulo, 128);
6610 	}
6611 
6612 // We can do REJ or SREJ but won't combine them.
6613 // Erratum:  2006 version, section, 4.3.3.7 says default selective reject - reject.
6614 // We can't do that.
6615 
6616 	if (param->srej == srej_not_specified) {
6617 	  param->srej = (param->modulo == 128) ? srej_single : srej_none;	// not specified, set default
6618 	}
6619 
6620 // We can currently do up to 2k.
6621 // Take minimum of that and what other guy asks for.
6622 
6623 	if (param->i_field_length_rx == G_UNKNOWN) {
6624 	  param->i_field_length_rx = 256;	// Not specified, take default.
6625 	}
6626 	else {
6627 	  param->i_field_length_rx = MIN(param->i_field_length_rx, AX25_N1_PACLEN_MAX);
6628 	}
6629 
6630 // In theory extended mode can have window size of 127 but
6631 // I'm limiting it to 63 for the reason mentioned in the SREJ logic.
6632 
6633 	if (param->window_size_rx == G_UNKNOWN) {
6634 	  param->window_size_rx = (param->modulo == 128) ? 32 : 4;	// not specified, set default.
6635 	}
6636 	else {
6637 	  if (param->modulo == 128)
6638 	    param->window_size_rx = MIN(param->window_size_rx, AX25_K_MAXFRAME_EXTENDED_MAX);
6639 	  else
6640 	    param->window_size_rx = MIN(param->window_size_rx, AX25_K_MAXFRAME_BASIC_MAX);
6641 	}
6642 
6643 // Erratum: Unclear.  Is the Acknowledgement Timer before or after compensating for digipeaters
6644 // in the path?  e.g.  Typically TNCs use the FRACK parameter for this and it often defaults to 3.
6645 // However, the actual timeout value might be something like FRACK*(2*m+1) where m is the number of
6646 // digipeaters in the path.  I'm assuming this is the FRACK value and any additional time, for
6647 // digipeaters will be added in locally at each end on top of this exchanged value.
6648 
6649 	if (param->ack_timer == G_UNKNOWN) {
6650 	  param->ack_timer = 3000;		// not specified, set default.
6651 	}
6652 	else {
6653 	  param->ack_timer = MAX(param->ack_timer, (int)(g_misc_config_p->frack * 1000));
6654 	}
6655 
6656 	if (param->retries == G_UNKNOWN) {
6657 	  param->retries = 10;		// not specified, set default.
6658 	}
6659 	else {
6660 	  param->retries = MAX(param->retries, S->n2_retry);
6661 	}
6662 
6663 // IMPORTANT:  Take values we have agreed upon and put into my running configuration.
6664 
6665 	complete_negotiation(S, param);
6666 }
6667 
6668 
6669 /*------------------------------------------------------------------------------
6670  *
6671  * Name:	complete_negotiation
6672  *
6673  * Purpose:	Used when preparing or receiving the XID *response*.
6674  *
6675  * Description:	Take set of parameters which we have agreed upon and apply
6676  *		to the running configuration.
6677  *
6678  * TODO:	Should do some checking here in case other station
6679  *		sends something crazy.
6680  *
6681  *------------------------------------------------------------------------------*/
6682 
complete_negotiation(ax25_dlsm_t * S,struct xid_param_s * param)6683 static void complete_negotiation (ax25_dlsm_t *S, struct xid_param_s *param)
6684 {
6685 	if (param->srej != srej_not_specified) {
6686 	  S->srej_enable = param->srej;
6687 	}
6688 
6689 	if (param->modulo != modulo_unknown) {
6690 	  // Disaster if aren't agreeing on this.
6691 	  S->modulo = param->modulo;
6692 	}
6693 
6694 	if (param->i_field_length_rx != G_UNKNOWN) {
6695 	  S->n1_paclen = param->i_field_length_rx;
6696 	}
6697 
6698 	if (param->window_size_rx != G_UNKNOWN) {
6699 	  S->k_maxframe = param->window_size_rx;
6700 	}
6701 
6702 	if (param->ack_timer != G_UNKNOWN) {
6703 	  S->t1v = param->ack_timer * 0.001;
6704 	}
6705 
6706 	if (param->retries != G_UNKNOWN) {
6707 	    S->n2_retry = param->retries;
6708 	}
6709 }
6710 
6711 
6712 
6713 
6714 
6715 //###################################################################################
6716 //###################################################################################
6717 //
6718 //  Timers.
6719 //
6720 //	Start.
6721 //	Stop.
6722 //	Pause (when channel busy) & resume.
6723 //	Is it running?
6724 //	Did it expire before being stopped?
6725 //	When will next one expire?
6726 //
6727 //###################################################################################
6728 //###################################################################################
6729 
6730 
start_t1(ax25_dlsm_t * S,const char * from_func,int from_line)6731 static void start_t1 (ax25_dlsm_t *S, const char *from_func, int from_line)
6732 {
6733 	double now = dtime_now();
6734 
6735 	if (s_debug_timers) {
6736 	  text_color_set(DW_COLOR_DEBUG_TIMER);
6737 	  dw_printf ("Start T1 for t1v = %.3f sec, rc = %d, [now=%.3f] from %s %d\n", S->t1v, S->rc, now - S->start_time, from_func, from_line);
6738 	}
6739 
6740 	S->t1_exp = now + S->t1v;
6741 	if (S->radio_channel_busy) {
6742 	  S->t1_paused_at = now;
6743 	}
6744 	else {
6745 	  S->t1_paused_at = 0;
6746 	}
6747 	S->t1_had_expired = 0;
6748 
6749 } /* end start_t1 */
6750 
6751 
stop_t1(ax25_dlsm_t * S,const char * from_func,int from_line)6752 static void stop_t1 (ax25_dlsm_t *S, const char *from_func, int from_line)
6753 {
6754 	double now = dtime_now();
6755 
6756 	RESUME_T1;		// adjust expire time if paused.
6757 
6758 	if (S->t1_exp == 0.0) {
6759 	  // Was already stopped.
6760 	}
6761 	else {
6762 	  S->t1_remaining_when_last_stopped = S->t1_exp - now;
6763 	  if (S->t1_remaining_when_last_stopped < 0) S->t1_remaining_when_last_stopped = 0;
6764 	}
6765 
6766 // Normally this would be at the top but we don't know time remaining at that point.
6767 
6768 	if (s_debug_timers) {
6769 	  text_color_set(DW_COLOR_DEBUG_TIMER);
6770 	  if (S->t1_exp == 0.0) {
6771 	    dw_printf ("Stop T1. Wasn't running, [now=%.3f] from %s %d\n", now - S->start_time, from_func, from_line);
6772 	  }
6773 	  else {
6774 	    dw_printf ("Stop T1, %.3f remaining, [now=%.3f] from %s %d\n", S->t1_remaining_when_last_stopped, now - S->start_time, from_func, from_line);
6775 	  }
6776 	}
6777 
6778 	S->t1_exp = 0.0;		// now stopped.
6779 	S->t1_had_expired = 0;		// remember that it did not expire.
6780 
6781 } /* end stop_t1 */
6782 
6783 
is_t1_running(ax25_dlsm_t * S,const char * from_func,int from_line)6784 static int is_t1_running (ax25_dlsm_t *S, const char *from_func, int from_line)
6785 {
6786 	int result = S->t1_exp != 0.0;
6787 
6788 	if (s_debug_timers) {
6789 	  text_color_set(DW_COLOR_DEBUG);
6790 	  dw_printf ("is_t1_running?  returns %d\n", result);
6791 	}
6792 
6793 	return (result);
6794 
6795 } /* end is_t1_running */
6796 
6797 
pause_t1(ax25_dlsm_t * S,const char * from_func,int from_line)6798 static void pause_t1 (ax25_dlsm_t *S, const char *from_func, int from_line)
6799 {
6800 
6801 	if (S->t1_exp == 0.0) {
6802 	  // Stopped so there is nothing to do.
6803 	}
6804 	else if (S->t1_paused_at == 0.0) {
6805 	  // Running and not paused.
6806 
6807 	  double now = dtime_now();
6808 
6809 	  S->t1_paused_at = now;
6810 
6811 	  if (s_debug_timers) {
6812 	    text_color_set(DW_COLOR_DEBUG);
6813 	    dw_printf ("Paused T1 with %.3f still remaining, [now=%.3f] from %s %d\n", S->t1_exp - now, now - S->start_time, from_func, from_line);
6814 	  }
6815 	}
6816 	else {
6817 	  if (s_debug_timers) {
6818 	    text_color_set(DW_COLOR_DEBUG);
6819 	    dw_printf ("T1 error: Didn't expect pause when already paused.\n");
6820 	  }
6821 	}
6822 
6823 } /* end pause_t1 */
6824 
6825 
resume_t1(ax25_dlsm_t * S,const char * from_func,int from_line)6826 static void resume_t1 (ax25_dlsm_t *S, const char *from_func, int from_line)
6827 {
6828 	if (S->t1_exp == 0.0) {
6829 	  // Stopped so there is nothing to do.
6830 	}
6831 	else if (S->t1_paused_at == 0.0) {
6832 	  // Running but not paused.
6833 	}
6834 	else {
6835 	  double now = dtime_now();
6836 	  double paused_for_sec = now - S->t1_paused_at;
6837 
6838 	  S->t1_exp += paused_for_sec;
6839 	  S->t1_paused_at = 0.0;
6840 
6841 	  if (s_debug_timers) {
6842 	    text_color_set(DW_COLOR_DEBUG);
6843 	    dw_printf ("Resumed T1 after pausing for %.3f sec, %.3f still remaining, [now=%.3f]\n", paused_for_sec, S->t1_exp - now, now - S->start_time);
6844 	  }
6845 	}
6846 
6847 } /* end resume_t1 */
6848 
6849 
6850 
6851 
6852 // T3 is a lot simpler.
6853 // Here we are talking about minutes of inactivity with the peer
6854 // rather than expecting a response within seconds where timing is more critical.
6855 // We don't need to capture remaining time when stopped.
6856 // I don't think there is a need to pause it due to the large time frame.
6857 
6858 
start_t3(ax25_dlsm_t * S,const char * from_func,int from_line)6859 static void start_t3 (ax25_dlsm_t *S, const char *from_func, int from_line)
6860 {
6861 	double now = dtime_now();
6862 
6863 	if (s_debug_timers) {
6864 	  text_color_set(DW_COLOR_DEBUG_TIMER);
6865 	  dw_printf ("Start T3 for %.3f sec, [now=%.3f] from %s %d\n", T3_DEFAULT, now - S->start_time, from_func, from_line);
6866 	}
6867 
6868 	S->t3_exp = now + T3_DEFAULT;
6869 }
6870 
stop_t3(ax25_dlsm_t * S,const char * from_func,int from_line)6871 static void stop_t3 (ax25_dlsm_t *S, const char *from_func, int from_line)
6872 {
6873 	if (s_debug_timers) {
6874 	  double now = dtime_now();
6875 
6876 	  text_color_set(DW_COLOR_DEBUG_TIMER);
6877 	  if (S->t3_exp == 0.0) {
6878 	    dw_printf ("Stop T3. Wasn't running.\n");
6879 	  }
6880 	  else {
6881 	    dw_printf ("Stop T3, %.3f remaining, [now=%.3f] from %s %d\n", S->t3_exp - now, now - S->start_time, from_func, from_line);
6882 	  }
6883 	}
6884 	S->t3_exp = 0.0;
6885 }
6886 
6887 
6888 
6889 // TM201 is similar to T1.
6890 // It needs to be paused whent the channel is busy.
6891 // Simpler because we don't need to keep track of time remaining when stopped.
6892 
6893 
6894 
start_tm201(ax25_dlsm_t * S,const char * from_func,int from_line)6895 static void start_tm201 (ax25_dlsm_t *S, const char *from_func, int from_line)
6896 {
6897 	double now = dtime_now();
6898 
6899 	if (s_debug_timers) {
6900 	  text_color_set(DW_COLOR_DEBUG_TIMER);
6901 	  dw_printf ("Start TM201 for t1v = %.3f sec, rc = %d, [now=%.3f] from %s %d\n", S->t1v, S->rc, now - S->start_time, from_func, from_line);
6902 	}
6903 
6904 	S->tm201_exp = now + S->t1v;
6905 	if (S->radio_channel_busy) {
6906 	  S->tm201_paused_at = now;
6907 	}
6908 	else {
6909 	  S->tm201_paused_at = 0;
6910 	}
6911 
6912 } /* end start_tm201 */
6913 
6914 
stop_tm201(ax25_dlsm_t * S,const char * from_func,int from_line)6915 static void stop_tm201 (ax25_dlsm_t *S, const char *from_func, int from_line)
6916 {
6917 	double now = dtime_now();
6918 
6919 	if (s_debug_timers) {
6920 	  text_color_set(DW_COLOR_DEBUG_TIMER);
6921 	  dw_printf ("Stop TM201.  [now=%.3f] from %s %d\n", now - S->start_time, from_func, from_line);
6922 	}
6923 
6924 	S->tm201_exp = 0.0;		// now stopped.
6925 
6926 } /* end stop_tm201 */
6927 
6928 
6929 
pause_tm201(ax25_dlsm_t * S,const char * from_func,int from_line)6930 static void pause_tm201 (ax25_dlsm_t *S, const char *from_func, int from_line)
6931 {
6932 
6933 	if (S->tm201_exp == 0.0) {
6934 	  // Stopped so there is nothing to do.
6935 	}
6936 	else if (S->tm201_paused_at == 0.0) {
6937 	  // Running and not paused.
6938 
6939 	  double now = dtime_now();
6940 
6941 	  S->tm201_paused_at = now;
6942 
6943 	  if (s_debug_timers) {
6944 	    text_color_set(DW_COLOR_DEBUG);
6945 	    dw_printf ("Paused TM201 with %.3f still remaining, [now=%.3f] from %s %d\n", S->tm201_exp - now, now - S->start_time, from_func, from_line);
6946 	  }
6947 	}
6948 	else {
6949 	  if (s_debug_timers) {
6950 	    text_color_set(DW_COLOR_DEBUG);
6951 	    dw_printf ("TM201 error: Didn't expect pause when already paused.\n");
6952 	  }
6953 	}
6954 
6955 } /* end pause_tm201 */
6956 
6957 
resume_tm201(ax25_dlsm_t * S,const char * from_func,int from_line)6958 static void resume_tm201 (ax25_dlsm_t *S, const char *from_func, int from_line)
6959 {
6960 	if (S->tm201_exp == 0.0) {
6961 	  // Stopped so there is nothing to do.
6962 	}
6963 	else if (S->tm201_paused_at == 0.0) {
6964 	  // Running but not paused.
6965 	}
6966 	else {
6967 	  double now = dtime_now();
6968 	  double paused_for_sec = now - S->tm201_paused_at;
6969 
6970 	  S->tm201_exp += paused_for_sec;
6971 	  S->tm201_paused_at = 0.0;
6972 
6973 	  if (s_debug_timers) {
6974 	    text_color_set(DW_COLOR_DEBUG);
6975 	    dw_printf ("Resumed TM201 after pausing for %.3f sec, %.3f still remaining, [now=%.3f]\n", paused_for_sec, S->tm201_exp - now, now - S->start_time);
6976 	  }
6977 	}
6978 
6979 } /* end resume_tm201 */
6980 
6981 
6982 
6983 
6984 
ax25_link_get_next_timer_expiry(void)6985 double ax25_link_get_next_timer_expiry (void)
6986 {
6987 	double tnext = 0;
6988 	ax25_dlsm_t *p;
6989 
6990 	for (p = list_head; p != NULL; p = p->next) {
6991 
6992 	  // Consider if running and not paused.
6993 
6994 	  if (p->t1_exp != 0 && p->t1_paused_at == 0) {
6995 	    if (tnext == 0) {
6996 	      tnext = p->t1_exp;
6997 	    }
6998 	    else if (p->t1_exp < tnext) {
6999 	      tnext = p->t1_exp;
7000 	    }
7001 	  }
7002 
7003 	  if (p->t3_exp != 0) {
7004 	    if (tnext == 0) {
7005 	      tnext = p->t3_exp;
7006 	    }
7007 	    else if (p->t3_exp < tnext) {
7008 	      tnext = p->t3_exp;
7009 	    }
7010 	  }
7011 
7012 	  if (p->tm201_exp != 0 && p->tm201_paused_at == 0) {
7013 	    if (tnext == 0) {
7014 	      tnext = p->tm201_exp;
7015 	    }
7016 	    else if (p->tm201_exp < tnext) {
7017 	      tnext = p->tm201_exp;
7018 	    }
7019 	  }
7020 
7021 	}
7022 
7023 	if (s_debug_timers > 1) {
7024 	  text_color_set(DW_COLOR_DEBUG);
7025 	  if (tnext == 0.0) {
7026 	    dw_printf ("ax25_link_get_next_timer_expiry returns none.\n");
7027 	  }
7028 	  else {
7029 	    dw_printf ("ax25_link_get_next_timer_expiry returns %.3f sec from now.\n",
7030 				tnext - dtime_now());
7031 	  }
7032 	}
7033 
7034 	return (tnext);
7035 
7036 } /* end ax25_link_get_next_timer_expiry */
7037 
7038 
7039 /* end ax25_link.c */
7040