home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR3 / KA9Q212.ZIP / NR4USER.C < prev    next >
C/C++ Source or Header  |  1993-07-16  |  5KB  |  233 lines

  1. /* net/rom level 4 (transport) protocol user level calls
  2.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  3.  * non-commercial distribution only.
  4.  */
  5.  
  6. /****************************************************************************
  7. *    $Id: nr4user.c 1.2 93/07/16 11:47:50 ROOT_DOS Exp $
  8. *    14 Jul 93    1.2        GT    Fix warnings.                                    *
  9. ****************************************************************************/
  10.  
  11. #include <stdio.h>
  12. #include "global.h"
  13. #include "mbuf.h"
  14. #include "timer.h"
  15. #include "ax25.h"
  16. #include "lapb.h"
  17. #include "netrom.h"
  18. #include "nr4.h"
  19. #include <ctype.h>
  20. #include "ip.h"
  21.  
  22. #undef NR4DEBUG
  23.  
  24. #if    NETROM
  25.  
  26. /* Open a NET/ROM transport connection */
  27. struct nr4cb *
  28. open_nr4(local,remote,mode,r_upcall,t_upcall,s_upcall,user)
  29. struct nr4_addr *local ;    /* local node address */
  30. struct nr4_addr *remote ;    /* destination node address */
  31. int mode ;            /* active/passive/server */
  32. void (*r_upcall)() ;        /* received data upcall */
  33. void (*t_upcall)() ;        /* transmit upcall */
  34. void (*s_upcall)() ;        /* state change upcall */
  35. int user ;            /* user linkage area */
  36. {
  37.     struct nr4cb *cb ;
  38.     struct nr4hdr hdr ;
  39.     struct nr4_addr nr4tmp;
  40.  
  41.     if ((cb = new_n4circ()) == NULLNR4CB)
  42.         return NULLNR4CB ;        /* No circuits available */
  43.  
  44.     if(remote == NULLNRADDR){
  45.         remote = &nr4tmp;
  46.         setcall(remote->user," ");
  47.         setcall(remote->node," ");
  48.     }
  49.     
  50.     /* Stuff what info we can into control block */
  51.  
  52.     ASSIGN(cb->remote,*remote) ;
  53.     /* Save local address for connect retries */
  54.     ASSIGN(cb->local,*local) ;
  55.  
  56.     cb->r_upcall = r_upcall ;
  57.     cb->t_upcall = t_upcall ;
  58.     cb->s_upcall = s_upcall ;
  59.     cb->user = user ;
  60.     cb->clone = 0 ;
  61.  
  62.     switch(mode){
  63.     case AX_SERVER:
  64.         cb->clone = 1;
  65.     case AX_PASSIVE:    /* Note fall-thru */
  66.         cb->state = NR4STLISTEN;
  67.         return cb;
  68.     case AX_ACTIVE:
  69.         break;
  70.     }    
  71.     /* Format connect request header */
  72.  
  73.     hdr.opcode = NR4OPCONRQ ;
  74.     hdr.u.conreq.myindex = cb->mynum ;
  75.     hdr.u.conreq.myid = cb->myid ;
  76.     hdr.u.conreq.window = Nr4window ;
  77.     memcpy(hdr.u.conreq.user,local->user,AXALEN);
  78.  
  79.     /* If I have a unique callsign per interface, then a layer violation */
  80.     /* will be required to determine the "real" callsign for my */
  81.     /* (virtual) node.  This suggests that callsign-per-interface is not */
  82.     /* desirable, which answers *that* particular open question. */
  83.     
  84.     memcpy(hdr.u.conreq.node,local->node,AXALEN);
  85.  
  86.     /* Set and start connection retry timer */
  87.  
  88.     cb->cdtries = 1 ;
  89.     cb->srtt = Nr4irtt ;
  90.     set_timer(&cb->tcd,2 * cb->srtt);
  91.     cb->tcd.func = nr4cdtimeout ;
  92.     cb->tcd.arg = cb ;
  93.     start_timer(&cb->tcd) ;
  94.     
  95.     /* Send connect request packet */
  96.  
  97.     nr4sframe(remote->node,&hdr,NULLBUF) ;
  98.  
  99.     /* Set up initial state and signal state change */
  100.  
  101.     cb->state = NR4STDISC ;
  102.     nr4state(cb, NR4STCPEND) ;
  103.  
  104.     /* Return control block address */
  105.  
  106.     return cb ;
  107. }
  108.  
  109. /* Send a net/rom transport data packet */
  110. int
  111. send_nr4(cb,bp)
  112. struct nr4cb *cb ;
  113. struct mbuf *bp ;
  114. {
  115.     if (cb == NULLNR4CB || bp == NULLBUF)
  116.         return -1 ;
  117.     enqueue(&cb->txq,bp) ;
  118.     return nr4output(cb) ;
  119. }
  120.  
  121. /* Receive incoming net/rom transport data */
  122. struct mbuf *
  123. recv_nr4(cb,cnt)
  124. struct nr4cb *cb ;
  125. int16 cnt ;
  126. {
  127.     struct mbuf *bp ;
  128.  
  129.     if (cb->rxq == NULLBUF)
  130.         return NULLBUF ;
  131.  
  132.     if (cnt == 0) {
  133.         bp = cb->rxq ;            /* Just give `em everything */
  134.         cb->rxq = NULLBUF ;
  135.     }
  136.     else {
  137.         bp = ambufw(cnt);
  138.         bp->cnt = pullup(&cb->rxq,bp->data,cnt);
  139.     }
  140.     /* If this has un-choked us, reopen the window */
  141.     if (cb->qfull && len_p(cb->rxq) < Nr4qlimit) {
  142.         cb->qfull = 0 ;                /* Choke flag off */
  143.         nr4ackit(cb) ;        /* Get things rolling again */
  144.     }
  145.  
  146.     return bp ;
  147. }
  148.  
  149. /* Close a NET/ROM connection */
  150. void
  151. disc_nr4(cb)
  152. struct nr4cb *cb ;
  153. {
  154.     struct nr4hdr hdr ;
  155.     
  156.     if (cb->state == NR4STLISTEN) {
  157.         free_n4circ(cb);
  158.         return;
  159.     }
  160.     if (cb->state != NR4STCON)
  161.         return ;
  162.  
  163.     /* Format disconnect request packet */
  164.     
  165.     hdr.opcode = NR4OPDISRQ ;
  166.     hdr.yourindex = cb->yournum ;
  167.     hdr.yourid = cb->yourid ;
  168.  
  169.     /* Set and start timer */
  170.     
  171.     cb->cdtries = 1 ;
  172.     set_timer(&cb->tcd,2 * cb->srtt);
  173.     cb->tcd.func = nr4cdtimeout ;
  174.     cb->tcd.arg = cb ;
  175.     start_timer(&cb->tcd) ;
  176.  
  177.     /* Send packet */
  178.  
  179.     nr4sframe(cb->remote.node, &hdr, NULLBUF) ;
  180.  
  181.     /* Signal state change.  nr4state will take care of stopping */
  182.     /* the appropriate timers and resetting window pointers. */
  183.  
  184.     nr4state(cb, NR4STDPEND) ;
  185.     
  186. }
  187.  
  188. /* Abruptly terminate a NET/ROM transport connection */
  189. void
  190. reset_nr4(cb)
  191. struct nr4cb *cb ;
  192. {
  193.     cb->dreason = NR4RRESET ;
  194.     nr4state(cb,NR4STDISC) ;
  195. }
  196.  
  197.  
  198. /* Force retransmission on a NET/ROM transport connection */
  199. int
  200. kick_nr4(cb)
  201. struct nr4cb *cb ;
  202. {
  203.     unsigned seq ;
  204.     struct timer *t ;
  205.  
  206.     if(!nr4valcb(cb))
  207.         return -1 ;
  208.  
  209.     switch (cb->state) {
  210.       case NR4STCPEND:
  211.       case NR4STDPEND:
  212.           stop_timer(&cb->tcd) ;
  213.         nr4cdtimeout(cb) ;
  214.         break ;
  215.  
  216.       case NR4STCON:
  217.         if (cb->nextosend != cb->ackxpected) {    /* if send window is open: */
  218.             for (seq = cb->ackxpected ;
  219.                  nr4between(cb->ackxpected, seq, cb->nextosend) ;
  220.                  seq = (seq + 1) & NR4SEQMASK) {
  221.                 t = &cb->txbufs[seq % cb->window].tretry ;
  222.                 stop_timer(t) ;
  223.                 t->state = TIMER_EXPIRE ;    /* fool retry routine */
  224.             }
  225.             nr4txtimeout(cb) ;
  226.         }
  227.         break ;
  228.     }
  229.  
  230.     return 0 ;
  231. }
  232. #endif    /* NETROM */
  233.