📄 sys-ecos.c
字号:
* output - Output PPP packet. */voidoutput(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 __ECOSstatic 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_STATUSvoid 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; } }}#endifstatic 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). */voidwait_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. */voidwait_time(timo) struct timeval *timo;{db_printf("%s called\n", __PRETTY_FUNCTION__);}//==========================================================================/* * read_packet - get a PPP packet from the serial device. */intread_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. */voidppp_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. */voidppp_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. */voidppp_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. */intccp_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. */voidccp_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. */intccp_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. */intget_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. */intset_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 + -