示例#1
0
int
sacom_activate(struct device *self, enum devact act)
{
    struct sacom_softc *sc = (struct sacom_softc *)self;
    int s, rv = 0;

    s = splserial();
    COM_LOCK(sc);
    switch (act) {
    case DVACT_ACTIVATE:
        rv = EOPNOTSUPP;
        break;

    case DVACT_DEACTIVATE:
        if (sc->sc_hwflags & (COM_HW_CONSOLE|COM_HW_KGDB)) {
            rv = EBUSY;
            break;
        }

        if (sc->disable != NULL && sc->enabled != 0) {
            (*sc->disable)(sc);
            sc->enabled = 0;
        }
        break;
    }

    COM_UNLOCK(sc);
    splx(s);
    return rv;
}
示例#2
0
void svrGwsRequest(bool _debug_output,SerialCom* comm,int* nTimer) {
    if (COM_TEST) {
        COM_LOCK(SECOND_TICKS);    //occupy serial port
        SVR_DEBUG(_debug_output,VT100_RESET VT100_INVERT "(%d,%03d)Radio query...\n",
                  nTimer_ticks,static_chp.m_nCommBusy);
        static char* cmd = "rfinfo 2\n";
        ScSend(comm, cmd, strlen(cmd));
        EnableTimer(*nTimer,SECOND_TICKS);
    }
}
示例#3
0
void
sacom_shutdown(struct sacom_softc *sc)
{
    struct tty *tp = sc->sc_tty;
    int s;

    s = splserial();
    COM_LOCK(sc);

    /* Clear any break condition set with TIOCSBRK. */
    sacom_break(sc, 0);

    /*
     * Hang up if necessary.  Wait a bit, so the other side has time to
     * notice even if we immediately open the port again.
     * Avoid tsleeping above splhigh().
     */
    if (ISSET(tp->t_cflag, HUPCL)) {
        sacom_modem(sc, 0);
        COM_UNLOCK(sc);
        splx(s);
        /* XXX tsleep will only timeout */
        (void) tsleep(sc, TTIPRI, ttclos, hz);
        s = splserial();
        COM_LOCK(sc);
    }

    /* Turn off interrupts. */
    sc->sc_cr3 = 0;
    bus_space_write_4(sc->sc_iot, sc->sc_ioh, SACOM_CR3, sc->sc_cr3);

    if (sc->disable) {
#ifdef DIAGNOSTIC
        if (!sc->enabled)
            panic("sacom_shutdown: not enabled?");
#endif
        (*sc->disable)(sc);
        sc->enabled = 0;
    }
    COM_UNLOCK(sc);
    splx(s);
}
示例#4
0
void svrNoiseFloorSwitchChan(bool _debug_output,SerialCom* comm,int *timerSwitch) {
    if (COM_TEST) {
        //switch channel periodically for noise floor detecting
        SVR_DEBUG(_debug_output,VT100_RESET VT100_STYLE_ALERT "\n(%d,%03d)Switch channel      ",nTimer_ticks,static_chp.m_nCommBusy);
        svrNextChannel(comm,&static_chp,timerSwitch);
        PRE_SCAN_COMMAND(comm,"setrxatten 0 0");
        PRE_SCAN_COMMAND(comm,"setrxatten 1 36");
        cur_chan_scan_done = false;
        COM_LOCK(PERIOD_SWITCH * MSEC_TICKS);    //occupy serial port for 500 ms
    }
}
示例#5
0
static void
sacom_enable_debugport(struct sacom_softc *sc)
{
    bus_space_tag_t iot = sc->sc_iot;
    bus_space_handle_t ioh = sc->sc_ioh;
    int s;

    s = splserial();
    COM_LOCK(sc);
    sc->sc_cr3 = CR3_RXE | CR3_TXE;
    bus_space_write_4(iot, ioh, SACOM_CR3, sc->sc_cr3);
    COM_UNLOCK(sc);
    splx(s);
}
示例#6
0
void
sacomstart(struct tty *tp)
{
    struct sacom_softc *sc =
        device_lookup_private(&sacom_cd, COMUNIT(tp->t_dev));
    bus_space_tag_t iot = sc->sc_iot;
    bus_space_handle_t ioh = sc->sc_ioh;
    int s;

    if (COM_ISALIVE(sc) == 0)
        return;

    s = spltty();
    if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
        goto out;
    if (!ttypull(tp))
        goto out;

    /* Grab the first contiguous region of buffer space. */
    {
        u_char *tba;
        int tbc;

        tba = tp->t_outq.c_cf;
        tbc = ndqb(&tp->t_outq, 0);

        (void)splserial();
        COM_LOCK(sc);

        sc->sc_tba = tba;
        sc->sc_tbc = tbc;
    }

    SET(tp->t_state, TS_BUSY);
    sc->sc_tx_busy = 1;

    /* Enable transmit completion interrupts if necessary. */
    if (!ISSET(sc->sc_cr3, CR3_TIE)) {
        SET(sc->sc_cr3, CR3_TIE);
        bus_space_write_4(iot, ioh, SACOM_CR3, sc->sc_cr3);
    }

    /* Output the first chunk of the contiguous buffer. */
    sacom_filltx(sc);

    COM_UNLOCK(sc);
out:
    splx(s);
    return;
}
示例#7
0
/*
 * Stop output on a line.
 */
void
sacomstop(struct tty *tp, int flag)
{
    struct sacom_softc *sc =
        device_lookup_private(&sacom_cd, COMUNIT(tp->t_dev));
    int s;

    s = splserial();
    COM_LOCK(sc);
    if (ISSET(tp->t_state, TS_BUSY)) {
        /* Stop transmitting at the next chunk. */
        sc->sc_tbc = 0;
        sc->sc_heldtbc = 0;
        if (!ISSET(tp->t_state, TS_TTSTOP))
            SET(tp->t_state, TS_FLUSH);
    }
    COM_UNLOCK(sc);
    splx(s);
}
示例#8
0
int
sacomhwiflow(struct tty *tp, int block)
{
#if 0
    struct sacom_softc *sc =
        device_lookup_private(&sacom_cd, COMUNIT(tp->t_dev));
    int s;

    if (COM_ISALIVE(sc) == 0)
        return 0;

    if (sc->sc_mcr_rts == 0)
        return 0;

    s = splserial();
    COM_LOCK(sc);

    if (block) {
        if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
            SET(sc->sc_rx_flags, RX_TTY_BLOCKED);
            sacom_hwiflow(sc);
        }
    } else {
        if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
            CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
            sacom_schedrx(sc);
        }
        if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
            CLR(sc->sc_rx_flags, RX_TTY_BLOCKED);
            sacom_hwiflow(sc);
        }
    }

    COM_UNLOCK(sc);
    splx(s);
#endif
    return 1;
}
示例#9
0
int
sacomparam(struct tty *tp, struct termios *t)
{
    struct sacom_softc *sc =
        device_lookup_private(&sacom_cd, COMUNIT(tp->t_dev));
    int ospeed = SACOMSPEED(t->c_ospeed);
    u_int cr0;
    int s;

    if (COM_ISALIVE(sc) == 0)
        return EIO;

    /* Check requested parameters. */
    if (ospeed < 0)
        return EINVAL;
    if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
        return EINVAL;

    /*
     * For the console, always force CLOCAL and !HUPCL, so that the port
     * is always active.
     */
    if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) ||
            ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
        SET(t->c_cflag, CLOCAL);
        CLR(t->c_cflag, HUPCL);
    }

    /*
     * If there were no changes, don't do anything.  This avoids dropping
     * input and improves performance when all we did was frob things like
     * VMIN and VTIME.
     */
    if (tp->t_ospeed == t->c_ospeed &&
            tp->t_cflag == t->c_cflag)
        return 0;

    cr0 = cflag2cr0(t->c_cflag);

    s = splserial();
    COM_LOCK(sc);

    sc->sc_cr0 = cr0;

    sc->sc_speed = ospeed;

    /* And copy to tty. */
    tp->t_ispeed = 0;
    tp->t_ospeed = t->c_ospeed;
    tp->t_cflag = t->c_cflag;

    if (!sc->sc_heldchange) {
        if (sc->sc_tx_busy) {
            sc->sc_heldtbc = sc->sc_tbc;
            sc->sc_tbc = 0;
            sc->sc_heldchange = 1;
        } else
            sacom_loadchannelregs(sc);
    }

    if (!ISSET(t->c_cflag, CHWFLOW)) {
        /* Disable the high water mark. */
        if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
            CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
            sacom_schedrx(sc);
        }
        if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
            CLR(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
            sacom_hwiflow(sc);
        }
    }

    COM_UNLOCK(sc);
    splx(s);

    (void) (*tp->t_linesw->l_modem)(tp, 1);

#ifdef COM_DEBUG
    if (sacom_debug)
        comstatus(sc, "comparam ");
#endif

    return 0;
}
示例#10
0
int
sacomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
    struct sacom_softc *sc =
        device_lookup_private(&sacom_cd, COMUNIT(dev));
    struct tty *tp = sc->sc_tty;
    int error;
    int s;

    if (COM_ISALIVE(sc) == 0)
        return EIO;

    error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l);
    if (error != EPASSTHROUGH)
        return error;

    error = ttioctl(tp, cmd, data, flag, l);
    if (error != EPASSTHROUGH)
        return error;

    error = 0;

    s = splserial();
    COM_LOCK(sc);

    switch (cmd) {
    case TIOCSBRK:
        sacom_break(sc, 1);
        break;

    case TIOCCBRK:
        sacom_break(sc, 0);
        break;

    case TIOCSDTR:
        sacom_modem(sc, 1);
        break;

    case TIOCCDTR:
        sacom_modem(sc, 0);
        break;

    case TIOCGFLAGS:
        *(int *)data = sc->sc_swflags;
        break;

    case TIOCSFLAGS:
        error = kauth_authorize_device_tty(l->l_cred,
                                           KAUTH_DEVICE_TTY_PRIVSET, tp);
        if (error)
            break;
        sc->sc_swflags = *(int *)data;
        break;

    case TIOCMSET:
    case TIOCMBIS:
    case TIOCMBIC:
        tiocm_to_sacom(sc, cmd, *(int *)data);
        break;

    case TIOCMGET:
        *(int *)data = sacom_to_tiocm(sc);
        break;

    default:
        error = EPASSTHROUGH;
        break;
    }

    COM_UNLOCK(sc);
    splx(s);

#ifdef COM_DEBUG
    if (sacom_debug)
        comstatus(sc, "comioctl ");
#endif

    return error;
}
示例#11
0
int
sacomopen(dev_t dev, int flag, int mode, struct lwp *l)
{
    struct sacom_softc *sc;
    struct tty *tp;
    int s, s2;
    int error;

    sc = device_lookup_private(&sacom_cd, COMUNIT(dev));
    if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK) ||
            sc->sc_rbuf == NULL)
        return ENXIO;

    if (!device_is_active(&sc->sc_dev))
        return ENXIO;

    tp = sc->sc_tty;

    if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
        return (EBUSY);

    s = spltty();

    /*
     * Do the following iff this is a first open.
     */
    if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
        struct termios t;

        tp->t_dev = dev;

        s2 = splserial();
        COM_LOCK(sc);

        if (sc->enable) {
            if ((*sc->enable)(sc)) {
                COM_UNLOCK(sc);
                splx(s2);
                splx(s);
                printf("%s: device enable failed\n",
                       sc->sc_dev.dv_xname);
                return EIO;
            }
            sc->enabled = 1;
            sacom_config(sc);
        }

        /* Turn on interrupts. */
        sc->sc_cr3 = CR3_RXE | CR3_TXE | CR3_RIE | CR3_TIE;
        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SACOM_CR3,
                          sc->sc_cr3);


        COM_UNLOCK(sc);
        splx(s2);

        /*
         * Initialize the termios status to the defaults.  Add in the
         * sticky bits from TIOCSFLAGS.
         */
        t.c_ispeed = 0;
        if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
            t.c_ospeed = sacomconsrate;
            t.c_cflag = sacomconscflag;
        } else {
            t.c_ospeed = TTYDEF_SPEED;
            t.c_cflag = TTYDEF_CFLAG;
        }
        if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
            SET(t.c_cflag, CLOCAL);
        if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
            SET(t.c_cflag, CRTSCTS);
        if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF))
            SET(t.c_cflag, MDMBUF);
        /* Make sure sacomparam() will do something. */
        tp->t_ospeed = 0;
        (void) sacomparam(tp, &t);
        tp->t_iflag = TTYDEF_IFLAG;
        tp->t_oflag = TTYDEF_OFLAG;
        tp->t_lflag = TTYDEF_LFLAG;
        ttychars(tp);
        ttsetwater(tp);

        s2 = splserial();
        COM_LOCK(sc);

        /*
         * Turn on DTR.  We must always do this, even if carrier is not
         * present, because otherwise we'd have to use TIOCSDTR
         * immediately after setting CLOCAL, which applications do not
         * expect.  We always assert DTR while the device is open
         * unless explicitly requested to deassert it.
         */
        sacom_modem(sc, 1);

        /* Clear the input ring, and unblock. */
        sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
        sc->sc_rbavail = SACOM_RING_SIZE;
        sacom_iflush(sc);
        CLR(sc->sc_rx_flags, RX_ANY_BLOCK);
        sacom_hwiflow(sc);

#ifdef COM_DEBUG
        if (sacom_debug)
            comstatus(sc, "sacomopen  ");
#endif

        COM_UNLOCK(sc);
        splx(s2);
    }

    splx(s);

    error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK));
    if (error)
        goto bad;

    error = (*tp->t_linesw->l_open)(dev, tp);
    if (error)
        goto bad;

    return 0;

bad:
    if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
        /*
         * We failed to open the device, and nobody else had it opened.
         * Clean up the state as appropriate.
         */
        sacom_shutdown(sc);
    }

    return error;
}
示例#12
0
int
sacomintr(void *arg)
{
    struct sacom_softc *sc = arg;
    bus_space_tag_t iot = sc->sc_iot;
    bus_space_handle_t ioh = sc->sc_ioh;
    u_char *put, *end;
    u_int cc;
    u_int sr0, sr1;

    if (COM_ISALIVE(sc) == 0)
        return 0;

    COM_LOCK(sc);
    sr0 = bus_space_read_4(iot, ioh, SACOM_SR0);
    if (!sr0) {
        COM_UNLOCK(sc);
        return 0;
    }
    if (ISSET(sr0, SR0_EIF))
        /* XXX silently discard error bits */
        bus_space_read_4(iot, ioh, SACOM_DR);
    if (ISSET(sr0, SR0_RBB))
        bus_space_write_4(iot, ioh, SACOM_SR0, SR0_RBB);
    if (ISSET(sr0, SR0_REB)) {
        bus_space_write_4(iot, ioh, SACOM_SR0, SR0_REB);
#if defined(DDB) || defined(KGDB)
#ifndef DDB_BREAK_CHAR
        if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
            console_debugger();
        }
#endif
#endif /* DDB || KGDB */
    }


    end = sc->sc_ebuf;
    put = sc->sc_rbput;
    cc = sc->sc_rbavail;

    sr1 = bus_space_read_4(iot, ioh, SACOM_SR1);
    if (ISSET(sr0, SR0_RFS | SR0_RID)) {
        if (!ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
            while (cc > 0) {
                if (!ISSET(sr1, SR1_RNE)) {
                    bus_space_write_4(iot, ioh, SACOM_SR0,
                                      SR0_RID);
                    break;
                }
                put[0] = bus_space_read_4(iot, ioh, SACOM_DR);
                put[1] = sr1;
#if defined(DDB) && defined(DDB_BREAK_CHAR)
                if (put[0] == DDB_BREAK_CHAR &&
                        ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
                    console_debugger();

                    sr1 = bus_space_read_4(iot, ioh, SACOM_SR1);
                    continue;
                }
#endif
                put += 2;
                if (put >= end)
                    put = sc->sc_rbuf;
                cc--;

                sr1 = bus_space_read_4(iot, ioh, SACOM_SR1);
            }

            /*
             * Current string of incoming characters ended because
             * no more data was available or we ran out of space.
             * Schedule a receive event if any data was received.
             * If we're out of space, turn off receive interrupts.
             */
            sc->sc_rbput = put;
            sc->sc_rbavail = cc;
            if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
                sc->sc_rx_ready = 1;

            /* XXX do RX hardware flow control */

            /*
             * If we're out of space, disable receive interrupts
             * until the queue has drained a bit.
             */
            if (!cc) {
                SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
                CLR(sc->sc_cr3, CR3_RIE);
                bus_space_write_4(iot, ioh, SACOM_CR3,
                                  sc->sc_cr3);
            }
        } else {
#ifdef DIAGNOSTIC
            panic("sacomintr: we shouldn't reach here");
#endif
            CLR(sc->sc_cr3, CR3_RIE);
            bus_space_write_4(iot, ioh, SACOM_CR3, sc->sc_cr3);
        }
    }

    /*
     * Done handling any receive interrupts. See if data can be
     * transmitted as well. Schedule tx done event if no data left
     * and tty was marked busy.
     */
    sr0 = bus_space_read_4(iot, ioh, SACOM_SR0);
    if (ISSET(sr0, SR0_TFS)) {
        /*
         * If we've delayed a parameter change, do it now, and restart
         * output.
         * XXX sacom_loadchannelregs() waits TX completion,
         * XXX resulting in ~0.1s hang (300bps, 4 bytes) in worst case
         */
        if (sc->sc_heldchange) {
            sacom_loadchannelregs(sc);
            sc->sc_heldchange = 0;
            sc->sc_tbc = sc->sc_heldtbc;
            sc->sc_heldtbc = 0;
        }

        /* Output the next chunk of the contiguous buffer, if any. */
        if (sc->sc_tbc > 0) {
            sacom_filltx(sc);
        } else {
            /* Disable transmit completion interrupts if necessary. */
            if (ISSET(sc->sc_cr3, CR3_TIE)) {
                CLR(sc->sc_cr3, CR3_TIE);
                bus_space_write_4(iot, ioh, SACOM_CR3,
                                  sc->sc_cr3);
            }
            if (sc->sc_tx_busy) {
                sc->sc_tx_busy = 0;
                sc->sc_tx_done = 1;
            }
        }
    }
    COM_UNLOCK(sc);

    /* Wake up the poller. */
    softint_schedule(sc->sc_si);

#if NRND > 0 && defined(RND_COM)
    rnd_add_uint32(&sc->rnd_source, iir | lsr);
#endif
    return 1;
}
示例#13
0
static inline void
sacom_rxsoft(struct sacom_softc *sc, struct tty *tp)
{
    int (*rint)(int, struct tty *) = tp->t_linesw->l_rint;
    u_char *get, *end;
    u_int cc, scc;
    u_char sr1;
    int code;
    int s;

    end = sc->sc_ebuf;
    get = sc->sc_rbget;
    scc = cc = SACOM_RING_SIZE - sc->sc_rbavail;

    while (cc) {
        code = get[0];
        sr1 = get[1];
        if (ISSET(sr1, SR1_FRE))
            SET(code, TTY_FE);
        if (ISSET(sr1, SR1_PRE))
            SET(code, TTY_PE);
        if ((*rint)(code, tp) == -1) {
            /*
             * The line discipline's buffer is out of space.
             */
            if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
                /*
                 * We're either not using flow control, or the
                 * line discipline didn't tell us to block for
                 * some reason.  Either way, we have no way to
                 * know when there's more space available, so
                 * just drop the rest of the data.
                 */
                get += cc << 1;
                if (get >= end)
                    get -= SACOM_RING_SIZE << 1;
                cc = 0;
            } else {
                /*
                 * Don't schedule any more receive processing
                 * until the line discipline tells us there's
                 * space available (through comhwiflow()).
                 * Leave the rest of the data in the input
                 * buffer.
                 */
                SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
            }
            break;
        }
        get += 2;
        if (get >= end)
            get = sc->sc_rbuf;
        cc--;
    }

    if (cc != scc) {
        sc->sc_rbget = get;
        s = splserial();
        COM_LOCK(sc);

        cc = sc->sc_rbavail += scc - cc;
        /* Buffers should be ok again, release possible block. */
        if (cc >= 1) {
            if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
                CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
                SET(sc->sc_cr3, CR3_RIE);
                bus_space_write_4(sc->sc_iot, sc->sc_ioh,
                                  SACOM_CR3, sc->sc_cr3);
            }
        }
        COM_UNLOCK(sc);
        splx(s);
    }
}
示例#14
0
int svrCmdHandler(SerialCom* comm,GWS_MESSAGE* gws_msg,CommandHandlerPara* para) {
    char command[64];
    char parameter[32];
    int* nTimer = &(para->m_nCommBusy);
    int region = 0;
    int nId = para->m_nIdentifier;
    P_GWS_KPI pKpi = para->m_pKpi;

    RW_KPI_VAR(nId,region,pKpi->m_radio.m_nRegion);
    strcpy(parameter, gws_msg->m_command.m_sPara);
    switch (gws_msg->m_command.m_nReq) {
    case SCAN_CHAN:
    case SCAN_FIXED_CHAN:
        if (MIN_CHANNEL(region) <= para->m_nOriginChannel && para->m_nOriginChannel <= MAX_CHANNEL(region)) {
            COM_LOCK(1000 * MSEC_TICKS);    //occupy serial port for 500 ms
            RW_KPI_VAR(nId,latest_rxcal,pKpi->m_radio.m_bRXCal);
            RW_KPI_VAR(nId,latest_rxgain,pKpi->m_radio.m_nRXGain);
            PRE_SCAN_COMMAND(comm,"setrxcal 0");
            PRE_SCAN_COMMAND(comm,"setrxgain 0");
            para->m_nCurrentChannel = para->m_nOriginChannel;
            CHANNEL_SCAN_ON_OFF(para->m_uChanScan,gws_msg->m_command.m_nReq == SCAN_FIXED_CHAN ?
                                SCANNING_FIXED_INIT : SCANNING_ALL_INIT);
            gws_msg->m_nType = 0;
        } else {
            svrSetErrorNo(GWS_ERROR_INVALIDATE_CHANNEL);
        }
        break;
    case STOP_CHAN:
        if (para->m_uChanScan == SCANNING_FIXED_READ) {
            CHANNEL_SCAN_ON_OFF(para->m_uChanScan, SCANNING_FIXED_DONE);
        } else {
            CHANNEL_SCAN_ON_OFF(para->m_uChanScan, SCANNING_DONE);
            APP_SCAN_COMMAND(comm,static_chp.m_nOriginChannel);
        }
        gws_msg->m_nType = 0;
        break;
    case SET_TXON:
        if (*nTimer <= 0) {
            COM_LOCK(500 * MSEC_TICKS);    //occupy serial port for 500 ms
            sprintf(command, "tx%s\n", parameter);
            ScSend(comm, command, strlen(command));
            gws_msg->m_nType = 0;
        }
        break;
    case SET_RXON:
        if (*nTimer <= 0) {
            COM_LOCK(500 * MSEC_TICKS);    //occupy serial port for 500 ms
            sprintf(command, "rx%s\n", parameter);
            ScSend(comm, command, strlen(command));
            gws_msg->m_nType = 0;
        }
        break;
    case SET_TXCAL:
        if (*nTimer <= 0) {
            COM_LOCK(500 * MSEC_TICKS);    //occupy serial port for 500 ms
            sprintf(command, "settxcal %s\n", parameter);
            ScSend(comm, command, strlen(command));
            gws_msg->m_nType = 0;
        }
    case SET_RXCAL:
        if (*nTimer <= 0) {
            COM_LOCK(500 * MSEC_TICKS);    //occupy serial port for 500 ms
            sprintf(command, "setrxcal %s\n", parameter);
            ScSend(comm, command, strlen(command));
            gws_msg->m_nType = 0;
        }
        break;
    case SET_REGION:
        if (*nTimer <= 0) {
            COM_LOCK(500 * MSEC_TICKS);    //occupy serial port for 500 ms
            sprintf(command, "setregion %s\n", parameter);
            ScSend(comm, command, strlen(command));
            gws_msg->m_nType = 0;
        }
        break;
    case SET_CHAN:
        if (*nTimer <= 0) {
            int new_channel = para->m_nOriginChannel;
            COM_LOCK(500 * MSEC_TICKS);    //occupy serial port for 500 ms
            CHANNEL_SCAN_ON_OFF(para->m_uChanScan,false);
            if (IsNumber(parameter)) {
                new_channel = atoi(parameter);
            } else if (parameter[0] == 'x') {
                new_channel --;
                if (new_channel < MIN_CHANNEL(region)) new_channel = MAX_CHANNEL(region);
            } else if (parameter[0] == 'v') {
                new_channel ++;
                if (new_channel > MAX_CHANNEL(region)) new_channel = MIN_CHANNEL(region);
            }
            para->m_nCurrentChannel = new_channel;
            para->m_nOriginChannel = svrSetChannel(comm, region,para->m_nCurrentChannel,&timer_chan_switch);
            gws_msg->m_nType = 0;
        }
        break;
    case SET_TXPWR:
        if (*nTimer <= 0) {
            COM_LOCK(500 * MSEC_TICKS);    //occupy serial port for 500 ms
            sprintf(command, "settxpwr %s\n", parameter);
            ScSend(comm, command, strlen(command));
            gws_msg->m_nType = 0;
        }
        break;
    case SET_GAIN:
        if (*nTimer <= 0) {
            COM_LOCK(500 * MSEC_TICKS);    //occupy serial port for 500 ms
            sprintf(command, "setrxgain %s\n", parameter);
            ScSend(comm, command, strlen(command));
            gws_msg->m_nType = 0;
        }
        break;
    case SET_MODE:
        if (*nTimer <= 0) {
            COM_LOCK(500 * MSEC_TICKS);    //occupy serial port for 500 ms
            sprintf(command, "config_%s", parameter);
            system(command);
            usleep(1000000);
            system("reboot");
            gws_msg->m_nType = 0;
        }
        break;
    case SET_TXATT:
        if (*nTimer <= 0) {
            COM_LOCK(500 * MSEC_TICKS);    //occupy serial port for 500 ms
            sprintf(command, "settxatten %s\n", parameter);
            ScSend(comm, command, strlen(command));
            gws_msg->m_nType = 0;
        }
        break;
    case SET_BANDWIDTH:
        set_wifi_bandwidth(parameter);
        gws_msg->m_nType = 0;
        break;
    case WIFI_TXPW:
        PipeShellCommand(   para->m_shell, "iw", "dev",
                            para->m_ifName, "set", "txpower", "fixed",
                            gws_msg->m_command.m_sPara, NULL);
        gws_msg->m_nType = 0;
        break;
    case 'Q':
    case 'q':
        CHANNEL_SCAN_ON_OFF(para->m_uChanScan,false);
        SetTimerOut(*nTimer);
        gws_msg->m_nType = 0;
        break;
    case SHUTDOWN:
#ifdef  _GWS_DEBUG
        ShowStatusBar("Shutdown Server.");
#endif
        gws_msg->m_nType = 0;
        return 0;
    default:
        gws_msg->m_nType = 0;
    }
    return 1;
}