1*41592Ssklower /* Copyright (c) University of British Columbia, 1984 */ 2*41592Ssklower 3*41592Ssklower #include "../h/param.h" 4*41592Ssklower #include "../h/systm.h" 5*41592Ssklower #include "../h/mbuf.h" 6*41592Ssklower #include "../h/socket.h" 7*41592Ssklower #include "../h/socketvar.h" 8*41592Ssklower #include "../h/protosw.h" 9*41592Ssklower #include "../h/errno.h" 10*41592Ssklower 11*41592Ssklower #include "../net/if.h" 12*41592Ssklower 13*41592Ssklower #include "../netccitt/pk.h" 14*41592Ssklower #include "../netccitt/pk_var.h" 15*41592Ssklower #include "../netccitt/x25.h" 16*41592Ssklower 17*41592Ssklower struct mbuf *nextpk (); 18*41592Ssklower 19*41592Ssklower pk_output (lcp) 20*41592Ssklower register struct pklcd *lcp; 21*41592Ssklower { 22*41592Ssklower register struct x25_packet *xp; 23*41592Ssklower register struct mbuf *m; 24*41592Ssklower register struct pkcb *pkp = lcp -> lcd_pkp; 25*41592Ssklower 26*41592Ssklower if (lcp == 0 || pkp == 0) { 27*41592Ssklower printf ("pk_output: zero arg\n"); 28*41592Ssklower return; 29*41592Ssklower } 30*41592Ssklower 31*41592Ssklower while ((m = nextpk (lcp)) != NULL) { 32*41592Ssklower xp = mtod (m, struct x25_packet *); 33*41592Ssklower 34*41592Ssklower switch (pk_decode (xp) + lcp -> lcd_state) { 35*41592Ssklower /* 36*41592Ssklower * All the work is already done - just set the state and 37*41592Ssklower * pass to peer. 38*41592Ssklower */ 39*41592Ssklower case CALL + READY: 40*41592Ssklower lcp -> lcd_state = SENT_CALL; 41*41592Ssklower lcp -> lcd_timer = pk_t21; 42*41592Ssklower break; 43*41592Ssklower 44*41592Ssklower /* 45*41592Ssklower * Just set the state to allow packet to flow and send the 46*41592Ssklower * confirmation. 47*41592Ssklower */ 48*41592Ssklower case CALL_ACCEPTED + RECEIVED_CALL: 49*41592Ssklower lcp -> lcd_state = DATA_TRANSFER; 50*41592Ssklower break; 51*41592Ssklower 52*41592Ssklower /* 53*41592Ssklower * Just set the state. Keep the LCD around till the clear 54*41592Ssklower * confirmation is returned. 55*41592Ssklower */ 56*41592Ssklower case CLEAR + RECEIVED_CALL: 57*41592Ssklower case CLEAR + SENT_CALL: 58*41592Ssklower case CLEAR + DATA_TRANSFER: 59*41592Ssklower lcp -> lcd_state = SENT_CLEAR; 60*41592Ssklower lcp -> lcd_retry = 0; 61*41592Ssklower /* fall through */ 62*41592Ssklower 63*41592Ssklower case CLEAR + SENT_CLEAR: 64*41592Ssklower lcp -> lcd_timer = pk_t23; 65*41592Ssklower lcp -> lcd_retry++; 66*41592Ssklower break; 67*41592Ssklower 68*41592Ssklower case CLEAR_CONF + RECEIVED_CLEAR: 69*41592Ssklower case CLEAR_CONF + SENT_CLEAR: 70*41592Ssklower case CLEAR_CONF + READY: 71*41592Ssklower lcp -> lcd_state = READY; 72*41592Ssklower break; 73*41592Ssklower 74*41592Ssklower case DATA + DATA_TRANSFER: 75*41592Ssklower PS(xp) = lcp -> lcd_ssn; 76*41592Ssklower PR(xp) = lcp -> lcd_input_window; 77*41592Ssklower lcp -> lcd_last_transmitted_pr = lcp -> lcd_input_window; 78*41592Ssklower lcp -> lcd_ssn = (lcp -> lcd_ssn + 1) % MODULUS; 79*41592Ssklower if (lcp -> lcd_ssn == ((lcp -> lcd_output_window + pkp->pk_xcp->xc_pwsize) % MODULUS)) 80*41592Ssklower lcp -> lcd_window_condition = TRUE; 81*41592Ssklower break; 82*41592Ssklower 83*41592Ssklower case INTERRUPT + DATA_TRANSFER: 84*41592Ssklower xp -> packet_data = 0; 85*41592Ssklower lcp -> lcd_intrconf_pending = TRUE; 86*41592Ssklower break; 87*41592Ssklower 88*41592Ssklower case INTERRUPT_CONF + DATA_TRANSFER: 89*41592Ssklower break; 90*41592Ssklower 91*41592Ssklower case RR + DATA_TRANSFER: 92*41592Ssklower lcp -> lcd_input_window = (lcp -> lcd_input_window + 1) % MODULUS; 93*41592Ssklower PR(xp) = lcp -> lcd_input_window; 94*41592Ssklower lcp -> lcd_last_transmitted_pr = lcp -> lcd_input_window; 95*41592Ssklower break; 96*41592Ssklower 97*41592Ssklower case RNR + DATA_TRANSFER: 98*41592Ssklower PR(xp) = lcp -> lcd_input_window; 99*41592Ssklower lcp -> lcd_last_transmitted_pr = lcp -> lcd_input_window; 100*41592Ssklower break; 101*41592Ssklower 102*41592Ssklower case RESET + DATA_TRANSFER: 103*41592Ssklower lcp -> lcd_reset_condition = TRUE; 104*41592Ssklower break; 105*41592Ssklower 106*41592Ssklower case RESET_CONF + DATA_TRANSFER: 107*41592Ssklower lcp -> lcd_reset_condition = FALSE; 108*41592Ssklower break; 109*41592Ssklower 110*41592Ssklower /* 111*41592Ssklower * A restart should be only generated internally. Therefore 112*41592Ssklower * all logic for restart is in the pk_restart routine. 113*41592Ssklower */ 114*41592Ssklower case RESTART + READY: 115*41592Ssklower lcp -> lcd_timer = pk_t20; 116*41592Ssklower break; 117*41592Ssklower 118*41592Ssklower /* 119*41592Ssklower * Restarts are all handled internally. Therefore all the 120*41592Ssklower * logic for the incoming restart packet is handled in the 121*41592Ssklower * pk_input routine. 122*41592Ssklower */ 123*41592Ssklower case RESTART_CONF + READY: 124*41592Ssklower break; 125*41592Ssklower 126*41592Ssklower default: 127*41592Ssklower m_freem (m); 128*41592Ssklower return; 129*41592Ssklower } 130*41592Ssklower 131*41592Ssklower /* Trace the packet. */ 132*41592Ssklower pk_trace (pkp -> pk_xcp, xp, "P-Out"); 133*41592Ssklower 134*41592Ssklower /* Pass the packet on down to the link layer */ 135*41592Ssklower (*pkp -> pk_output) (m, pkp -> pk_xcp); 136*41592Ssklower } 137*41592Ssklower } 138*41592Ssklower 139*41592Ssklower /* 140*41592Ssklower * This procedure returns the next packet to send or null. A 141*41592Ssklower * packet is composed of one or more mbufs. 142*41592Ssklower */ 143*41592Ssklower 144*41592Ssklower struct mbuf * 145*41592Ssklower nextpk (lcp) 146*41592Ssklower struct pklcd *lcp; 147*41592Ssklower { 148*41592Ssklower register struct socket *so = lcp -> lcd_so; 149*41592Ssklower register struct mbuf *m = 0, *n; 150*41592Ssklower 151*41592Ssklower if (lcp -> lcd_template) { 152*41592Ssklower m = dtom (lcp -> lcd_template); 153*41592Ssklower lcp -> lcd_template = NULL; 154*41592Ssklower } else { 155*41592Ssklower if (lcp -> lcd_rnr_condition || lcp -> lcd_window_condition || 156*41592Ssklower lcp -> lcd_reset_condition) 157*41592Ssklower return (NULL); 158*41592Ssklower 159*41592Ssklower if (so == 0) 160*41592Ssklower return (NULL); 161*41592Ssklower 162*41592Ssklower if ((m = so -> so_snd.sb_mb) == 0) 163*41592Ssklower return (NULL); 164*41592Ssklower 165*41592Ssklower n = m; 166*41592Ssklower while (n) { 167*41592Ssklower sbfree (&so -> so_snd, n); 168*41592Ssklower #ifndef BSD4_3 169*41592Ssklower if ((int) n -> m_act == 1) 170*41592Ssklower break; 171*41592Ssklower #endif 172*41592Ssklower n = n -> m_next; 173*41592Ssklower } 174*41592Ssklower 175*41592Ssklower #ifdef BSD4_3 176*41592Ssklower so->so_snd.sb_mb = m->m_act; 177*41592Ssklower m->m_act = 0; 178*41592Ssklower #else 179*41592Ssklower if (n) { 180*41592Ssklower so -> so_snd.sb_mb = n -> m_next; 181*41592Ssklower n -> m_next = 0; 182*41592Ssklower } 183*41592Ssklower #endif 184*41592Ssklower } 185*41592Ssklower 186*41592Ssklower return (m); 187*41592Ssklower } 188