📄 sys-ecos.c
字号:
* 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 + -