
/*


/******************************************************************************
 * vc_time() -- handle timeouts for sleeping opens and closes.
 *
 * If a sleep times out waiting for a response from the server board, this is
 * where we end up.  Flag the error and wake up the process.
 *****************************************************************************/

vc_time (sm)
    register shmq_t *sm;
{
    sm->sm_error = ETIMEDOUT;

    if (sm->sm_flags & SM_OPEN)
        sm->sm_flags &= ~SM_OPEN;
    else if (sm->sm_flags & SM_CLOSE)
        sm->sm_flags &= ~SM_CLOSE;

    wakeup (&sm->sm_error);
}

/*


/******************************************************************************
 * findshmq() -- find an available shared memory queue.
 *
 * Every stream to the server board requires a shared memory queue.
 *****************************************************************************/

shmq_t *
findshmq (brdno)
    int brdno;
{
    register int i;
    register shmq_t *sm;
    struct board *brd;

    brd = &boardtab[brdno];
    sm = brd->bd_shmq[0];
    for (i = 0; i < MAX_QUEUES; i++, sm++)
    {
        if (sm->sm_sula == NULL)
            break;
    }
    if (i == MAX_QUEUES)
    {
        printf ("\n No available shared memory queue.");
        return (0);
    }
    return (sm);
}
/*

 */


#ifdef  SBE_X25
/******************************************************************************
 * accept_call() -- accept an incoming XXX call from the server board.
 *
 * XLD will tell us when he has received a connect indication from the network.
 * We have to do some housekeeping to connect the call to a waiting getty
 * and restore XLD to a listening state.
 *****************************************************************************/

shmq_t *
accept_call (q, xg_p)
    queue_t *q;
    struct xgetty *xg_p;
{

    register shmq_t *newx_sm;     /* New Listen shmq */
    register mblk_t *mp;
    register struct board *brd;   /* Board with Incomming Call */
    register struct xldtable *xtab;
    XDcmd_t *lc;
    int len;                      /* block length */
    int id;
    int xltablen;                 /* Dummy argument for mbcopy */
    int vc_time ();
    shmq_t *findshmq ();


    brd = &boardtab[xg_p->xg_brdno];     /* Get Pointer to Board table */
    xtab = &(xldtbl[brd->bd_brdno]);

    /* ---  Build Listen STREAMS to take next Incomming Call --- */

    if ((newx_sm = findshmq (xg_p->xg_brdno))
        == (shmq_t *) 0)
    {
        printf (" No shmq available for new xlisten. \n");
        reject_call (xtab->xshm);
        return (SHMQNULL);
    }
    if ((mp = allocb (2, BPRI_HI)) == (mblk_t *) 0)
    {
        reject_call (xtab->xshm);        /* reject call */
        newx_sm->sm_sula = NULL;         /* Free Share Memory Queue */
        newx_sm->sm_flag.sf_l = NULL;
        return (SHMQNULL);               /* try again later */
    }
    mp->b_datap->db_type = M_OPEN;       /* build open message */
    *mp->b_wptr++ = XLD_PROTO;           /* type of port */
    *mp->b_wptr++ = 0;

    /* Use the process (getty) queues to handle incoming call */
    q->q_ptr = (caddr_t) brd;
    WR (q)->q_ptr = (caddr_t) newx_sm;
    newx_sm->sm_sula = (caddr_t) q;

    splstr ();
    WR (q)->q_count += shmput (newx_sm, mp);

    newx_sm->sm_flags |= SM_OPEN;        /* flag that this message needs
                                          * special processing */

    id = timeout (vc_time, newx_sm, VCOMTIMEOUT * HZ);

    sleep (&newx_sm->sm_error, PZERO);

    untimeout (id);

    if (newx_sm->sm_error)
    {
        reject_call (xtab->xshm);        /* Reject Call */
        newx_sm->sm_sula = NULL;         /* Free Share Memory Queue */
        newx_sm->sm_flag.sf_l = NULL;
        printf ("Error opening new XLISTEND. Please report this.\n");
        spl0 ();
        return (SHMQNULL);
    }
    newx_sm->sm_flags &= ~SM_OPEN;

    spl0 ();

    /* --- Send Listen Command --- */
    mp = mbcopy (xtab->xltab, &xltablen, BPRI_HI);
    xg_p->xg_sm = newx_sm;               /* Flag Getty waiting for Xd_lack
                                          * message */
    WR (q)->q_count += shmput (newx_sm, mp);

    /* Wait for Listen Response */
    sleep (xg_p, PZERO);
    xg_p->xg_sm = xtab->xshm;

    /* --- Accept Incoming Call --- */
    mp = allocb (sizeof (XDcmd_t), BPRI_HI);
    mp->b_datap->db_type = M_PROTO;
    lc = (XDcmd_t *) mp->b_rptr;
    lc->xc_type = Xd_cack;
    mp->b_wptr += sizeof (XDcmd_t);

    /* Link up incoming call stream with getty queue */
    q->q_ptr = (caddr_t) brd;
    WR (q)->q_ptr = (caddr_t) xtab->xshm;
    xtab->xshm->sm_sula = (caddr_t) q;

    WR (q)->q_count += shmput (xtab->xshm, mp);
    xtab->xshm = newx_sm;                /* Over Write old listening stream */
    xtab->xshm->sm_sula = (caddr_t) (&xtab->xl_queue);  /* Link with Dummy queue */

    return (((shmq_t *) (WR (q)->q_ptr)));      /* Return SM queue pointer */
}

/*
