/* * nr4subr.c: subroutines for net/rom transport layer. * Copyright 1989 by Daniel M. Frank, W9NK. Permission granted for * non-commercial distribution only. */ #include #include "global.h" #include "mbuf.h" #include "timer.h" #include "ax25.h" #include "netrom.h" #include "nr4.h" #include "lapb.h" #include /* Get a free circuit table entry, and allocate a circuit descriptor. * Initialize control block circuit number and ID fields. * Return a pointer to the circuit control block if successful, * NULLNR4CB if not. */ struct nr4cb * new_n4circ() { int i ; struct nr4cb *cb ; for (i = 0 ; i < NR4MAXCIRC ; i++) /* find a free circuit */ if (Nr4circuits[i].ccb == NULLNR4CB) break ; if (i == NR4MAXCIRC) /* no more circuits */ return NULLNR4CB ; cb = Nr4circuits[i].ccb = (struct nr4cb *)callocw(1,sizeof(struct nr4cb)); cb->mynum = i ; cb->myid = Nr4circuits[i].cid ; return cb ; } /* Set the window size for a circuit and allocate the buffers for * the transmit and receive windows. Set the control block window * parameter. Return 0 if successful, -1 if not. */ int init_nr4window(cb, window) struct nr4cb *cb ; unsigned window ; { if (window == 0 || window > NR4MAXWIN) /* reject silly window sizes */ return -1 ; cb->txbufs = (struct nr4txbuf *)callocw(window,sizeof(struct nr4txbuf)); cb->rxbufs = (struct nr4rxbuf *)callocw(window,sizeof(struct nr4rxbuf)); cb->window = window ; return 0 ; } /* Free a circuit. Deallocate the control block and buffers, and * increment the circuit ID. No return value. */ void free_n4circ(cb) struct nr4cb *cb ; { unsigned circ ; if (cb == NULLNR4CB) return ; circ = cb->mynum ; if (cb->txbufs != (struct nr4txbuf *)0) free(cb->txbufs) ; if (cb->rxbufs != (struct nr4rxbuf *)0) free(cb->rxbufs) ; /* Better be safe than sorry: */ free_q(&cb->txq) ; free_q(&cb->rxq) ; free(cb) ; if (circ > NR4MAXCIRC) /* Shouldn't happen. */ return ; Nr4circuits[circ].ccb = NULLNR4CB ; Nr4circuits[circ].cid++ ; } /* See if any open circuit matches the given parameters. This is used * to prevent opening multiple circuits on a duplicate connect request. * Returns the control block address if a match is found, or NULLNR4CB * otherwise. */ struct nr4cb * match_n4circ(index, id, user, node) int index ; /* index of remote circuit */ int id ; /* id of remote circuit */ char *user ; /* address of remote user */ char *node ; /* address of originating node */ { int i ; struct nr4cb *cb ; for (i = 0 ; i < NR4MAXCIRC ; i++) { if ((cb = Nr4circuits[i].ccb) == NULLNR4CB) continue ; /* not an open circuit */ if (cb->yournum == index && cb->yourid == id && addreq(cb->remote.user,user) && addreq(cb->remote.node,node)) return cb ; } /* if we get to here, we didn't find a match */ return NULLNR4CB ; } /* Validate the index and id of a local circuit, returning the control * block if it is valid, or NULLNR4CB if it is not. */ struct nr4cb * get_n4circ(index, id) int index ; /* local circuit index */ int id ; /* local circuit id */ { struct nr4cb *cb ; if (index >= NR4MAXCIRC) return NULLNR4CB ; if ((cb = Nr4circuits[index].ccb) == NULLNR4CB) return NULLNR4CB ; if (cb->myid == id) return cb ; else return NULLNR4CB ; } /* Return 1 if b is "between" (modulo the size of an unsigned char) * a and c, 0 otherwise. */ int nr4between(a, b, c) unsigned a, b, c ; { if ((a <= b && b < c) || (c < a && a <= b) || (b < c && c < a)) return 1 ; else return 0 ; } /* Set up default timer values, etc., in newly connected control block. */ void nr4defaults(cb) struct nr4cb *cb ; { int i ; struct timer *t ; if (cb == NULLNR4CB) return ; /* Set up the ACK and CHOKE timers */ set_timer(&cb->tack,Nr4acktime) ; cb->tack.func = nr4ackit ; cb->tack.arg = cb ; set_timer(&cb->tchoke,Nr4choketime) ; cb->tchoke.func = nr4unchoke ; cb->tchoke.arg = cb ; cb->rxpastwin = cb->window ; /* Don't actually set the timers, since this is done */ /* in nr4sbuf */ for (i = 0 ; i < cb->window ; i++) { t = &cb->txbufs[i].tretry ; t->func = nr4txtimeout ; t->arg = cb ; } } /* See if this control block address is valid */ int nr4valcb(cb) struct nr4cb *cb ; { int i ; if (cb == NULLNR4CB) return 0 ; for (i = 0 ; i < NR4MAXCIRC ; i++) if (Nr4circuits[i].ccb == cb) return 1 ; return 0 ; } void nr_garbage(red) int red; { int i; struct nr4cb *ncp; for(i=0;irxq); } }