/* "Dumb terminal" session command for serial lines
 * Copyright 1991 Phil Karn, KA9Q
 *
 *      Feb '91 Bill Simpson
 *              rlsd control and improved dialer
 */
/* mods by PA0GRI */
#include "global.h"
#include "mbuf.h"
#include "proc.h"
#include "iface.h"
#ifndef UNIX
#include "i8250.h"
#endif
#ifdef LINUX
#include "lxasy.h"
#endif
#include "asy.h"
#include "tty.h"
#include "session.h"
#include "socket.h"
#include "commands.h"
#include "devparam.h"
  
  
static void tip_out __ARGS((int dev,void *n1,void *n2));
  
  
/* Execute user telnet command */
int
dotip(argc,argv,p)
int argc;
char *argv[];
void *p;
{
    struct session *sp;
    register struct iface *ifp;
    struct asy *ap;
    char *ifn;
    int (*rawsave) __ARGS((struct iface *,struct mbuf *));
    int c;
  
    /*Make sure this comes from console - WG7J*/
    if(Curproc->input != Command->input)
        return 0;
  
    if((ifp = if_lookup(argv[1])) == NULLIF){
        tprintf(Badinterface,argv[1]);
        return 1;
    }
    ap=&Asy[ifp->dev];
    if( ifp->dev >= ASY_MAX || ap->iface != ifp ){
        tprintf("Interface %s not asy port\n",argv[1]);
        return 1;
    }
    if(ifp->raw == bitbucket){
        tprintf("tip or dialer session already active on %s\n",argv[1]);
        return 1;
    }
  
    /* Allocate a session descriptor */
    if((sp = newsession(argv[1],TIP,0)) == NULLSESSION){
        tputs(TooManySessions);
        return 1;
    }
  
    /* Save output handler and temporarily redirect output to null */
    rawsave = ifp->raw;
    ifp->raw = bitbucket;
  
    /* Suspend the packet input driver. Note that the transmit driver
     * is left running since we use it to send buffers to the line.
     */
    suspend(ifp->rxproc);
#ifdef POLLEDKISS
    suspend(ap->poller);
#endif
  
    /* Put tty into raw mode */
    sp->ttystate.echo = 0;
    sp->ttystate.edit = 0;
    sockmode(sp->output,SOCK_BINARY);
  
    /* Now fork into two paths, one rx, one tx */
    ifn = if_name( ifp, " tip out" );
    sp->proc1 = newproc(ifn,256,tip_out,ifp->dev,NULL,NULL,0);
    free( ifn );
  
    ifn = if_name( ifp, " tip in" );
    chname( Curproc, ifn );
    free( ifn );
  
    /* bring the line up (just in case) */
    if ( ifp->ioctl != NULL )
        (*ifp->ioctl)( ifp, PARAM_UP, TRUE, 0L );
  
    while((c = get_asy(ifp->dev)) != -1)
        tputc(c & 0x7f);
    tflush();
  
    killproc(sp->proc1);
    sp->proc1 = NULLPROC;
    ifp->raw = rawsave;
    resume(ifp->rxproc);
#ifdef POLLEDKISS
    resume(ap->poller);
#endif
    keywait(NULLCHAR,1);
    freesession(sp);
    return 0;
}
  
  
/* Output process, DTE version */
static void
tip_out(dev,n1,n2)
int dev;
void *n1,*n2;
{
    struct mbuf *bp;
    int c;
  
    while((c = recvchar(Curproc->input)) != EOF){
        if(c == '\n')
            c = '\r';               /* NL => CR */
        bp = pushdown(NULLBUF,1);
        bp->data[0] = (c & 0x7f);
        asy_send(dev,bp);
        Asy[dev].iface->lastsent = secclock();
    }
}
  
  
