home *** CD-ROM | disk | FTP | other *** search
- /* User subroutines for AX.25 */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <time.h>
- #include <stdarg.h>
- #include "global.h"
- #include "mbuf.h"
- #include "timer.h"
- #include "iface.h"
- #include "ax25.h"
- #include "lapb.h"
-
- /* Open an AX.25 connection */
- struct ax25_cb *open_ax25(struct ax25 *addr, int16 window,
- void (*r_upcall)(), void (*t_upcall)(),
- void (*s_upcall)(),
- struct interface *iface, char *user)
- {
- struct ax25_cb *axp;
-
- if((axp = cr_ax25(&addr->dest)) == NULLAX25)
- return NULLAX25;
- axp->addr = *addr;
- if(addr->ndigis != 0){
- axp->t1.start *= (addr->ndigis + 1);
- axp->t2.start *= (addr->ndigis + 1);
- axp->t3.start *= (addr->ndigis + 1);
- }
- axp->window = window;
- axp->r_upcall = r_upcall;
- axp->t_upcall = t_upcall;
- axp->s_upcall = s_upcall;
- axp->interface = iface;
- axp->user = user;
-
- switch(axp->state){
- case DISCONNECTED:
- /* Don't send anything if the connection already exists */
- est_link(axp);
- lapbstate(axp,SETUP);
- break;
- case SETUP:
- free_q(&axp->txq);
- break;
- case DISCPENDING: /* Ignore */
- case FRAMEREJECT:
- break;
- case RECOVERY:
- case CONNECTED:
- free_q(&axp->txq);
- est_link(axp);
- lapbstate(axp,SETUP);
- break;
- }
- return axp;
- }
-
- /* Send data on an AX.25 connection. Caller must provide PID */
- int send_ax25(struct ax25_cb *axp, struct mbuf *bp)
- {
- if(axp == NULLAX25 || bp == NULLBUF)
- return -1;
- enqueue(&axp->txq,bp);
- return lapb_output(axp);
- }
-
- /* Do printf on a ax25 connection */
- int aprintf(struct ax25_cb *axp, char *message, ...)
- {
- va_list argptr;
- struct mbuf *bp;
- int len;
- register char *cp;
-
- if(axp == NULLAX25)
- return 0;
-
- if((bp = alloc_mbuf(axp->paclen+1)) != NULLBUF)
- {
- va_start(argptr,message);
- cp = bp->data;
- *cp++ = PID_NO_L3;
- len = vsprintf(cp,message,argptr);
- va_end(argptr);
- cp = bp->data;
- cp++;
- bp->cnt = (strlen(cp) + 1);
- send_ax25(axp,bp);
- return len;
- }
- else
- {
- return 0;
- }
- }
-
- /* Receive incoming data on an AX.25 connection */
- struct mbuf *recv_ax25(register struct ax25_cb *axp, int16 cnt)
- {
- struct mbuf *bp;
-
- cnt = cnt;
-
- if(axp->rxq == NULLBUF)
- return NULLBUF;
-
- bp = axp->rxq;
- axp->rxq = NULLBUF;
-
- /* If this has un-busied us, send a RR to reopen the window */
- if(len_mbuf(bp) >= axp->window)
- sendctl(axp,RESPONSE,RR);
- return bp;
- }
-
- /* Close an AX.25 connection */
- void disc_ax25(struct ax25_cb *axp)
- {
- switch(axp->state){
- case DISCONNECTED:
- break; /* Ignored */
- case SETUP:
- free_q(&axp->txq);
- case DISCPENDING:
- lapbstate(axp,DISCONNECTED);
- del_ax25(axp);
- break;
- case CONNECTED:
- case RECOVERY:
- case FRAMEREJECT:
- free_q(&axp->txq);
- axp->retries = 0;
- sendctl(axp,COMMAND,DISC|PF);
- stop_timer(&axp->t3);
- start_timer(&axp->t1);
- lapbstate(axp,DISCPENDING);
- break;
- }
- }
-
- /* Verify that axp points to a valid ax25 control block */
- int ax25val(struct ax25_cb *axp)
- {
- register struct ax25_cb *axp1;
- register int i;
-
- if(axp == NULLAX25)
- return 0; /* Null pointer can't be valid */
- for(i=0; i < NHASH; i++)
- for(axp1 = ax25_cb[i];axp1 != NULLAX25; axp1 = axp1->next)
- if(axp1 == axp)
- return 1;
- return 0;
- }
-
- /* Force a retransmission */
- int kick_ax25(struct ax25_cb *axp)
- {
- if(!ax25val(axp))
- return -1;
- recover((int *)axp);
- return 0;
- }
-
- /* Abruptly terminate an AX.25 connection */
- void reset_ax25(struct ax25_cb *axp)
- {
- lapbstate(axp,DISCONNECTED);
- del_ax25(axp);
- }
-