home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / internet / tcpipsrc / h / if / Radio / c / NR4USER < prev    next >
Text File  |  1992-02-15  |  6KB  |  219 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. #include <stdio.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include <time.h>
  10. #include <stdarg.h>
  11. #include "global.h"
  12. #include "mbuf.h"
  13. #include "timer.h"
  14. #include "ax25.h"
  15. #include "lapb.h"
  16. #include "netrom.h"
  17. #include "nr4.h"
  18.  
  19. #undef NR4DEBUG
  20.  
  21. /* Open a NET/ROM transport connection */
  22. struct nr4cb *open_nr4(struct ax25_addr *node, struct ax25_addr *user,
  23.                        void (*r_upcall)(), void (*t_upcall)(),
  24.                        void (*s_upcall)(), char *puser)
  25. {
  26.         struct nr4cb *cb ;
  27.         struct nr4hdr hdr ;
  28.  
  29.         if ((cb = new_n4circ()) == NULLNR4CB)
  30.                 return NULLNR4CB ;              /* No circuits available */
  31.  
  32.         /* Stuff what info we can into control block */
  33.  
  34.         cb->user = *node ;              /* When we initiate, user is remote node */
  35.         cb->node = *node ;
  36.         cb->luser = *user ;             /* Save local user for connect retries */
  37.         cb->r_upcall = r_upcall ;
  38.         cb->t_upcall = t_upcall ;
  39.         cb->s_upcall = s_upcall ;
  40.         cb->puser = puser ;
  41.  
  42.         /* Format connect request header */
  43.  
  44.         hdr.opcode = NR4OPCONRQ ;
  45.         hdr.u.conreq.myindex = cb->mynum ;
  46.         hdr.u.conreq.myid = cb->myid ;
  47.         hdr.u.conreq.window = Nr4window ;
  48.         hdr.u.conreq.user = *user ;
  49.  
  50.         /* The choice of mycall here is suspect.  If I have a unique */
  51.         /* callsign per interface, then a layer violation will be */
  52.         /* required to determine the "real" callsign for my (virtual) */
  53.         /* node.  This suggests that callsign-per-interface is not */
  54.         /* desirable, which answers *that* particular open question. */
  55.         
  56.         hdr.u.conreq.node = mycall ;
  57.  
  58.         /* Set and start connection retry timer */
  59.  
  60.         cb->cdtries = 1 ;
  61.         cb->srtt = Nr4irtt ;
  62.         cb->tcd.start = (2 * cb->srtt) / MSPTICK ;
  63.         cb->tcd.func = nr4cdtimeout ;
  64.         cb->tcd.arg = (char *)cb ;
  65.         start_timer(&cb->tcd) ;
  66.         
  67.         /* Send connect request packet */
  68.  
  69.         nr4sframe(node, &hdr, NULLBUF) ;
  70.  
  71.         /* Set up initial state and signal state change */
  72.  
  73.         cb->state = NR4STDISC ;
  74.         nr4state(cb, NR4STCPEND) ;
  75.  
  76.         /* Return control block address */
  77.  
  78.         return cb ;
  79. }
  80.  
  81. /* Send a net/rom transport data packet */
  82. int send_nr4(struct nr4cb *cb, struct mbuf *bp)
  83. {
  84.         if (cb == NULLNR4CB || bp == NULLBUF)
  85.                 return -1 ;
  86.         enqueue(&cb->txq,bp) ;
  87.         return nr4output(cb) ;
  88. }
  89.  
  90. /* Do printf on a net/rom connection */
  91. int nr4_printf(struct nr4cb *cb, char *message, ...)
  92. {
  93.         va_list argptr;
  94.         struct mbuf *bp;
  95.         int len;
  96.         register char *cp;
  97.  
  98.         if(cb == NULLNR4CB)
  99.                 return 0;
  100.  
  101.         if((bp = alloc_mbuf(512)) != NULLBUF)
  102.         {
  103.                 cp = bp->data;
  104.                 va_start(argptr,message);
  105.                 len = vsprintf(cp,message,argptr);
  106.                 va_end(argptr);
  107.                 cp = bp->data;
  108.                 bp->cnt = (strlen(cp));
  109.                 send_nr4(cb,bp);
  110.                 return len;
  111.         }
  112.         else    
  113.         {
  114.                 return 0;
  115.         }
  116. }
  117.  
  118. /* Receive incoming net/rom transport data */
  119. struct mbuf *recv_nr4(struct nr4cb *cb, int16 cnt)
  120. {
  121.         struct mbuf *bp ;
  122.  
  123.         cnt = cnt;
  124.  
  125.         if (cb->rxq == NULLBUF)
  126.                 return NULLBUF ;
  127.  
  128.         bp = cb->rxq ;                  /* Just give `em everything */
  129.         cb->rxq = NULLBUF ;
  130.  
  131.         /* Since we took everything, we always go unchoked.  If we */
  132.         /* ever change this code to use cnt, or make it a real packet */
  133.         /* delivery, there will have to be a check to see if the queue */
  134.         /* has gotten short enough yet. */
  135.  
  136.         if (cb->qfull) {
  137.                 cb->qfull = 0 ;                         /* Choke flag off */
  138.                 nr4ackit((char *)cb) ;          /* Get things rolling again */
  139.         }
  140.  
  141.         return bp ;
  142. }
  143.  
  144. /* Close a NET/ROM connection */
  145. void disc_nr4(struct nr4cb *cb)
  146. {
  147.         struct nr4hdr hdr ;
  148.         
  149.         if (cb->state != NR4STCON)
  150.                 return ;
  151.  
  152.         /* Format disconnect request packet */
  153.         
  154.         hdr.opcode = NR4OPDISRQ ;
  155.         hdr.yourindex = cb->yournum ;
  156.         hdr.yourid = cb->yourid ;
  157.  
  158.         /* Set and start timer */
  159.         
  160.         cb->cdtries = 1 ;
  161.         cb->tcd.start = (2 * cb->srtt) / MSPTICK ;
  162.         cb->tcd.func = nr4cdtimeout ;
  163.         cb->tcd.arg = (char *)cb ;
  164.         start_timer(&cb->tcd) ;
  165.  
  166.         /* Send packet */
  167.  
  168.         nr4sframe(&cb->node, &hdr, NULLBUF) ;
  169.  
  170.         /* Signal state change. nr4state will take care of */
  171.         /* stopping the appropriate timers and resetting */
  172.         /* window pointers. */
  173.  
  174.         nr4state(cb, NR4STDPEND) ;
  175.         
  176. }
  177.  
  178. /* Abruptly terminate a NET/ROM transport connection */
  179. void reset_nr4(struct nr4cb *cb)
  180. {
  181.         cb->dreason = NR4RRESET ;
  182.         nr4state(cb,NR4STDISC) ;
  183. }
  184.  
  185.  
  186. /* Force retransmission on a NET/ROM transport connection */
  187. int kick_nr4(struct nr4cb *cb)
  188. {
  189.         unsigned seq ;
  190.         struct timer *t ;
  191.  
  192.         if(!nr4valcb(cb))
  193.                 return -1 ;
  194.  
  195.         switch (cb->state) {
  196.           case NR4STCPEND:
  197.           case NR4STDPEND:
  198.                 stop_timer(&cb->tcd) ;
  199.                 nr4cdtimeout((char *)cb) ;
  200.                 break ;
  201.  
  202.           case NR4STCON:
  203.             if (cb->nextosend != cb->ackxpected) {      /* if send window is open: */
  204.                         for (seq = cb->ackxpected ;
  205.                                  nr4between(cb->ackxpected, seq, cb->nextosend) ;
  206.                                  seq = (seq + 1) & NR4SEQMASK) {
  207.                                 t = &cb->txbufs[seq % cb->window].tretry ;
  208.                                 stop_timer(t) ;
  209.                                 t->state = TIMER_EXPIRE ;       /* fool retry routine */
  210.                         }
  211.                         nr4txtimeout((char *)cb) ;
  212.                 }
  213.                 break ;
  214.         }
  215.  
  216.         return 0 ;
  217. }
  218.  
  219.