⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sys-ecos.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
 * output - Output PPP packet.
 */
void
output(unit, p, len)
    int unit;
    u_char *p;
    int len;
{
    Cyg_ErrNo err;
    struct uio uio;
    struct iovec iov;
    int s;
    
    if (debug)
	log_packet(p, len, "sent ", LOG_DEBUG);


    iov.iov_base    = p;
    iov.iov_len     = len;
    uio.uio_iov     = &iov;
    uio.uio_iovcnt  = 1;
    uio.uio_resid   = len;
    uio.uio_segflg  = UIO_USERSPACE;
    uio.uio_rw      = UIO_WRITE;

    s = splsoftnet();
    
    err = cyg_ppp_pppwrite( &ppp_tty, &uio, 0 );

    splx(s);
    
    if( err != 0 )
        syslog(LOG_ERR, "write: %d",err);

}

//==========================================================================

#ifdef __ECOS

static void wait_input_alarm(cyg_handle_t alarm, cyg_addrword_t data)
{
    cyg_thread_release( ppp_tty.pppd_thread );
    ppp_tty.pppd_wakeup = 1;
}

#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
void cyg_ppp_serial_callback( cyg_serial_line_status_t *s,
                                     CYG_ADDRWORD priv )
{
    externC int kill_link;

//    db_printf("serial callback %d %x\n",s->which, s->value );

    if( s->which == CYGNUM_SERIAL_STATUS_CARRIERDETECT )
    {
        if( s->value == 0 )
        {
            // CD lost
            kill_link = 1;
            cyg_thread_release( ppp_tty.pppd_thread );
            ppp_tty.pppd_wakeup = 1;
        }
        else
        {
            // CD up
            ppp_tty.carrier_detected = 1;
        }
    }
}
#endif

static void cyg_ppp_tx_thread(CYG_ADDRWORD arg)
{
    ppp_tty.tx_thread_running = true;

    // Wait for the PPPD thread to get going and start the PPP
    // initialization phase.
    while(phase == PHASE_DEAD )
        cyg_thread_delay(100);

    // Now loop until the link goes back down.
    while( phase != PHASE_DEAD )
    {
        cyg_semaphore_wait( &ppp_tty.tx_sem );

        if( phase == PHASE_DEAD )
            break;
        
        // Call into PPP driver to get transmissions going. This is
        // only called if some other thread has failed to transmit all
        // of a packet due to a full buffer, or flow control.

        cyg_ppp_pppstart( &ppp_tty );
    }

db_printf("%s exiting\n", __PRETTY_FUNCTION__);        
    ppp_tty.tx_thread_running = false;
    cyg_thread_exit();
}

#endif


//==========================================================================
/*
 * wait_input - wait until there is data available on ttyfd,
 * for the length of time specified by *timo (indefinite
 * if timo is NULL).
 */
void
wait_input(timo)
    struct timeval *timo;
{
    // If there are any packets still waiting on the input queue then
    // return immediately to let the PPPD handle them.
    if (cyg_ppp_pppcheck(&ppp_tty) != 0)
        return;

    if( timo != NULL )
    {
        cyg_tick_count_t trigger = timo->tv_sec*ppp_rtc_resolution.divisor;

        // If the timeval has a microseconds value, just add another
        // second on to the trigger time. These are after all just
        // timeouts, not accurate timings, so a bit of imprecision
        // will not hurt.
        if( timo->tv_usec != 0 )
            trigger += ppp_rtc_resolution.divisor;            

        trigger += cyg_current_time();

        // We set the alarm to retrigger after a second. This is in
        // case it catches cyg_io_read() at an uninterruptible
        // point. The alarm is disabled as soon as the read returns,
        // so the retrigger will usually not happen.
        cyg_alarm_initialize( ppp_tty.alarm,
                              trigger,
                              ppp_rtc_resolution.divisor );
    }
    
    for(;;)
    {
        int s;
        int len = 1;
        Cyg_ErrNo err;
        cyg_serial_buf_info_t info;
        cyg_uint32 ilen = sizeof(info);

#if 1
        // Work out how many bytes are waiting in the serial device
        // buffer and read them all at once. If there are none, we
        // just wait for a single character to arrive.
       
        if( cyg_io_get_config( ppp_tty.t_handle, CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO,
                               &info, &ilen ) == 0 && info.rx_count > 1 )
        {
            len = info.rx_count-1;
            if( len > sizeof(inbuf) )
                len = sizeof(inbuf);
        }
#endif
        
        if( timo != NULL )
            cyg_alarm_enable( ppp_tty.alarm );

        err = cyg_io_read( ppp_handle, &inbuf, &len );

        if( timo != NULL )
            cyg_alarm_disable( ppp_tty.alarm );
        
//        db_printf("read: err %d len %d byte %02x\n",err,len,inbuf[0]);
        
        if( err == 0 )
        {
            int i;
            
            // Pass all input data to PPP driver for analysis. If this
            // turns out to be for the PPPD, it will call
            // pppasyncctlp() which in turn will set
            // ppp_tty.pppd_wakeup. We detect that on return from
            // pppinput() and return to the caller to do pppd
            // processing.

            s = splsoftnet();
            
            for( i = 0; i < len; i++ )
            {
                err = cyg_ppp_pppinput( inbuf[i], &ppp_tty );
                
                if( err != 0 )
                    syslog( LOG_ERR, "pppinput error: %d", err);

            }

            splx(s);
            
        }
        else if( err != -EINTR )
            syslog( LOG_ERR, "Read error: %d",err);

        if( ppp_tty.pppd_wakeup )
        {
            ppp_tty.pppd_wakeup = 0;
            break;
        }
    }
}

//==========================================================================
/*
 * wait_time - wait for a given length of time or until a
 * signal is received.
 */
void
wait_time(timo)
    struct timeval *timo;
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
}


//==========================================================================
/*
 * read_packet - get a PPP packet from the serial device.
 */
int
read_packet(buf)
    u_char *buf;
{
    int err;
    struct uio uio;
    struct iovec iov;
    int len = PPP_MTU + PPP_HDRLEN;
    int s;
    
//db_printf("%s called\n", __PRETTY_FUNCTION__);
    
    iov.iov_base        = buf;
    iov.iov_len         = len;
    uio.uio_iov         = &iov;
    uio.uio_iovcnt      = 1;
    uio.uio_resid       = len;
    uio.uio_segflg      = UIO_USERSPACE;
    uio.uio_rw          = UIO_READ;

    s = splsoftnet();
    
    err = cyg_ppp_pppread( &ppp_tty, &uio, 0 );

    splx(s);
    
    if( err == EWOULDBLOCK )
        return -1;
    
    if( err != 0 )
    {
        syslog(LOG_ERR, "pppread: %d",err);
        die(1);
    }

    len -= uio.uio_resid;

    return len;
}

//==========================================================================
/*
 * ppp_send_config - configure the transmit characteristics of
 * the ppp interface.
 */
void
ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
    int unit, mtu;
    u_int32_t asyncmap;
    int pcomp, accomp;
{
    u_int x;
    struct ifreq ifr;
    int err;
    int s;
    
//    db_printf("%s: unit %d mtu %d asyncmap %08x pcomp %08x accomp %08x\n", __PRETTY_FUNCTION__,
//              unit,mtu,asyncmap,pcomp,accomp);
    
    strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
    ifr.ifr_mtu = mtu;
    if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0) {
	syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %d",errno);
	quit();
    }


    s = splsoftnet();
    
    if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSASYNCMAP, (caddr_t) &asyncmap, 0)) < 0) {
	syslog(LOG_ERR, "ioctl(PPPIOCSASYNCMAP): %d",err);
    }

    if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) < 0) {
	syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %d",err);
    }
    x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT;
    x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC;
    if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSFLAGS, (caddr_t) &x, 0)) < 0) {
	syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %d",err);
    }

    splx(s);
}


//==========================================================================
/*
 * ppp_set_xaccm - set the extended transmit ACCM for the interface.
 */
void
ppp_set_xaccm(unit, accm)
    int unit;
    ext_accm accm;
{
    int error;
    int s;
    
//db_printf("%s called\n", __PRETTY_FUNCTION__);

    s = splsoftnet();
        
    error = cyg_ppp_ppptioctl( &ppp_tty, PPPIOCSXASYNCMAP, (caddr_t)accm, 0 );

    splx(s);
    
    if( error != 0 )
	syslog(LOG_WARNING, "ioctl(set extended ACCM): %d",error);
}


//==========================================================================
/*
 * ppp_recv_config - configure the receive-side characteristics of
 * the ppp interface.
 */
void
ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
    int unit, mru;
    u_int32_t asyncmap;
    int pcomp, accomp;
{
    int x;
    int err;
    int s;

    s = splsoftnet();
    
    if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSMRU, (caddr_t) &mru, 0)) < 0) {
	syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %d",err);
    }
    if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap, 0)) < 0) {
	syslog(LOG_ERR, "ioctl(PPPIOCSRASYNCMAP): %d",err);
    }
    if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) < 0) {
	syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %d",err);
    }
    x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC;
    if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSFLAGS, (caddr_t) &x, 0)) < 0) {
	syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %d",err);
    }

    splx(s);
}

//==========================================================================
/*
 * ccp_test - ask kernel whether a given compression method
 * is acceptable for use.  Returns 1 if the method and parameters
 * are OK, 0 if the method is known but the parameters are not OK
 * (e.g. code size should be reduced), or -1 if the method is unknown.
 */
int
ccp_test(unit, opt_ptr, opt_len, for_transmit)
    int unit, opt_len, for_transmit;
    u_char *opt_ptr;
{
    struct ppp_option_data data;
    int s;
    
    data.ptr = opt_ptr;
    data.length = opt_len;
    data.transmit = for_transmit;
//db_printf("%s called\n", __PRETTY_FUNCTION__);

    s = splsoftnet();
        
    errno = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSCOMPRESS, (caddr_t) &data, 0 );

    splx(s);
    
    if (errno == 0)        
	return 1;
    else return (errno == ENOBUFS)? 0: -1;
    
}

//==========================================================================
/*
 * ccp_flags_set - inform kernel about the current state of CCP.
 */
void
ccp_flags_set(unit, isopen, isup)
    int unit, isopen, isup;
{
    int x;

    int err;
//db_printf("%s called\n", __PRETTY_FUNCTION__);
    if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) != 0) {
	syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %d",err);
	return;
    }
    x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN;
    x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP;
    if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSFLAGS, (caddr_t) &x,0)) != 0)
	syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %d",err);
}

//==========================================================================
/*
 * ccp_fatal_error - returns 1 if decompression was disabled as a
 * result of an error detected after decompression of a packet,
 * 0 otherwise.  This is necessary because of patent nonsense.
 */
int
ccp_fatal_error(unit)
    int unit;
{
    int x;
    int err;
    
db_printf("%s called\n", __PRETTY_FUNCTION__);
    if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) != 0) {
	syslog(LOG_ERR, "ioctl(PPPIOCGFLAGS): %d",err);
	return 0;
    }
    return x & SC_DC_FERROR;
}

//==========================================================================
/*
 * get_idle_time - return how long the link has been idle.
 */
int
get_idle_time(u, ip)
    int u;
    struct ppp_idle *ip;
{
    return cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGIDLE, (caddr_t)ip, 0) == 0;
}


//==========================================================================

#ifdef PPP_FILTER
/*
 * set_filters - transfer the pass and active filters to the kernel.
 */
int
set_filters(pass, active)
    struct bpf_program *pass, *active;
{
    int ret = 1;

db_printf("%s called\n", __PRETTY_FUNCTION__);
    if (pass->bf_len > 0) {
	if (ioctl(ppp_fd, PPPIOCSPASS, pass) < 0) {
	    syslog(LOG_ERR, "Couldn't set pass-filter in kernel: %m");
	    ret = 0;
	}
    }
    if (active->bf_len > 0) {
	if (ioctl(ppp_fd, PPPIOCSACTIVE, active) < 0) {
	    syslog(LOG_ERR, "Couldn't set active-filter in kernel: %m");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -