* Copyright (c) University of British Columbia, 1984
* Copyright (C) Computer Science Department IV,
* University of Erlangen-Nuremberg, Germany, 1992
* Copyright (c) 1991, 1992 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by the
* Laboratory for Computation Vision and the Computer Science Department
* of the the University of British Columbia and the Computer Science
* Department (IV) of the University of Erlangen-Nuremberg, Germany.
* %sccs.include.redist.c%
* @(#)pk_output.c 7.13 (Berkeley) %G%
#include <sys/socketvar.h>
#include <netccitt/x25.h>
#include <netccitt/pk_var.h>
struct mbuf_cache pk_output_cache
= {0 }, pk_input_cache
;
register struct pklcd
*lcp
;
register struct x25_packet
*xp
;
register struct pkcb
*pkp
= lcp
-> lcd_pkp
;
if (lcp
== 0 || pkp
== 0) {
printf ("pk_output: zero arg\n");
while ((m
= nextpk (lcp
)) != NULL
) {
xp
= mtod (m
, struct x25_packet
*);
switch (pk_decode (xp
) + lcp
-> lcd_state
) {
* All the work is already done - just set the state and
lcp
-> lcd_state
= SENT_CALL
;
lcp
-> lcd_timer
= pk_t21
;
* Just set the state to allow packet to flow and send the
case CALL_ACCEPTED
+ RECEIVED_CALL
:
lcp
-> lcd_state
= DATA_TRANSFER
;
* Just set the state. Keep the LCD around till the clear
* confirmation is returned.
case CLEAR
+ RECEIVED_CALL
:
case CLEAR
+ DATA_TRANSFER
:
lcp
-> lcd_state
= SENT_CLEAR
;
lcp
-> lcd_timer
= pk_t23
;
case CLEAR_CONF
+ RECEIVED_CLEAR
:
case CLEAR_CONF
+ SENT_CLEAR
:
lcp
-> lcd_state
= READY
;
case DATA
+ DATA_TRANSFER
:
lcp
-> lcd_input_window
=
(lcp
-> lcd_rsn
+ 1) % MODULUS
;
SPR(xp
, lcp
-> lcd_input_window
);
lcp
-> lcd_last_transmitted_pr
= lcp
-> lcd_input_window
;
lcp
-> lcd_ssn
= (lcp
-> lcd_ssn
+ 1) % MODULUS
;
if (lcp
-> lcd_ssn
== ((lcp
-> lcd_output_window
+ lcp
-> lcd_windowsize
) % MODULUS
))
lcp
-> lcd_window_condition
= TRUE
;
case INTERRUPT
+ DATA_TRANSFER
:
lcp
-> lcd_intrconf_pending
= TRUE
;
case INTERRUPT_CONF
+ DATA_TRANSFER
:
case RNR
+ DATA_TRANSFER
:
lcp
-> lcd_input_window
=
(lcp
-> lcd_rsn
+ 1) % MODULUS
;
SPR(xp
, lcp
-> lcd_input_window
);
lcp
-> lcd_last_transmitted_pr
= lcp
-> lcd_input_window
;
case RESET
+ DATA_TRANSFER
:
lcp
-> lcd_reset_condition
= TRUE
;
case RESET_CONF
+ DATA_TRANSFER
:
lcp
-> lcd_reset_condition
= FALSE
;
* A restart should be only generated internally. Therefore
* all logic for restart is in the pk_restart routine.
lcp
-> lcd_timer
= pk_t20
;
* Restarts are all handled internally. Therefore all the
* logic for the incoming restart packet is handled in the
case RESTART_CONF
+ READY
:
pk_trace (pkp
-> pk_xcp
, m
, "P-Out");
/* Pass the packet on down to the link layer */
if (pk_input_cache
.mbc_size
|| pk_input_cache
.mbc_oldsize
) {
mbuf_cache(&pk_input_cache
, m
);
(*pkp
-> pk_lloutput
) (pkp
-> pk_llnext
, m
, pkp
-> pk_rt
);
* This procedure returns the next packet to send or null. A
* packet is composed of one or more mbufs.
register struct mbuf
*m
, *n
;
struct socket
*so
= lcp
-> lcd_so
;
register struct sockbuf
*sb
= & (so
? so
-> so_snd
: lcp
-> lcd_sb
);
if (lcp
-> lcd_template
) {
lcp
-> lcd_template
= NULL
;
if (lcp
-> lcd_rnr_condition
|| lcp
-> lcd_window_condition
||
lcp
-> lcd_reset_condition
)
if ((m
= sb
-> sb_mb
) == 0)
sb
-> sb_mb
= m
-> m_nextpkt
;
for (n
= m
; n
; n
= n
-> m_next
)