示例#1
0
/*
 * i4b_Timeout() watches the DCD signal and mentions it if it's status
 * changes.
 */
static void
i4b_Timeout(void *data)
{
  struct physical *p = data;
  struct i4bdevice *dev = device2i4b(p->handler);
  int ombits, change;

  timer_Stop(&dev->Timer);
  dev->Timer.load = SECTICKS;		/* Once a second please */
  timer_Start(&dev->Timer);
  ombits = dev->mbits;

  if (p->fd >= 0) {
    if (ioctl(p->fd, TIOCMGET, &dev->mbits) < 0) {
      log_Printf(LogPHASE, "%s: ioctl error (%s)!\n", p->link.name,
                 strerror(errno));
      datalink_Down(p->dl, CLOSE_NORMAL);
      timer_Stop(&dev->Timer);
      return;
    }
  } else
    dev->mbits = 0;

  if (ombits == -1) {
    /* First time looking for carrier */
    if (Online(dev))
      log_Printf(LogPHASE, "%s: %s: CD detected\n", p->link.name, p->name.full);
    else if (++dev->carrier_seconds >= dev->dev.cd.delay) {
      log_Printf(LogPHASE, "%s: %s: No carrier"
                 " (increase ``set cd'' from %d ?)\n",
                 p->link.name, p->name.full, dev->dev.cd.delay);
      timer_Stop(&dev->Timer);
      /* i4b_AwaitCarrier() will notice */
    } else {
      /* Keep waiting */
      log_Printf(LogDEBUG, "%s: %s: Still no carrier (%d/%d)\n",
                 p->link.name, p->name.full, dev->carrier_seconds,
                 dev->dev.cd.delay);
      dev->mbits = -1;
    }
  } else {
    change = ombits ^ dev->mbits;
    if (change & TIOCM_CD) {
      if (dev->mbits & TIOCM_CD)
        log_Printf(LogDEBUG, "%s: offline -> online\n", p->link.name);
      else {
        log_Printf(LogDEBUG, "%s: online -> offline\n", p->link.name);
        log_Printf(LogPHASE, "%s: Carrier lost\n", p->link.name);
        datalink_Down(p->dl, CLOSE_NORMAL);
        timer_Stop(&dev->Timer);
      }
    } else
      log_Printf(LogDEBUG, "%s: Still %sline\n", p->link.name,
                 Online(dev) ? "on" : "off");
  }
}
示例#2
0
static int
physical_DescriptorWrite(struct fdescriptor *d, struct bundle *bundle,
                         const fd_set *fdset)
{
  struct physical *p = descriptor2physical(d);
  int nw, result = 0;

  if (p->out == NULL)
    p->out = link_Dequeue(&p->link);

  if (p->out) {
    nw = physical_Write(p, MBUF_CTOP(p->out), p->out->m_len);
    log_Printf(LogDEBUG, "%s: DescriptorWrite: wrote %d(%lu) to %d\n",
               p->link.name, nw, (unsigned long)p->out->m_len, p->fd);
    if (nw > 0) {
      p->out->m_len -= nw;
      p->out->m_offset += nw;
      if (p->out->m_len == 0)
	p->out = m_free(p->out);
      result = 1;
    } else if (nw < 0) {
      if (errno == EAGAIN)
        result = 1;
      else if (errno != ENOBUFS) {
	log_Printf(LogPHASE, "%s: write (%d): %s\n", p->link.name,
                   p->fd, strerror(errno));
        datalink_Down(p->dl, CLOSE_NORMAL);
      }
    }
    /* else we shouldn't really have been called !  select() is broken ! */
  }

  return result;
}
示例#3
0
void
physical_DescriptorRead(struct fdescriptor *d, struct bundle *bundle,
                        const fd_set *fdset)
{
  struct physical *p = descriptor2physical(d);
  u_char *rbuff;
  int n, found;

  rbuff = p->input.buf + p->input.sz;

  /* something to read */
  n = physical_Read(p, rbuff, sizeof p->input.buf - p->input.sz);
  log_Printf(LogDEBUG, "%s: DescriptorRead: read %d/%d from %d\n",
             p->link.name, n, (int)(sizeof p->input.buf - p->input.sz), p->fd);
  if (n <= 0) {
    if (n < 0)
      log_Printf(LogPHASE, "%s: read (%d): %s\n", p->link.name, p->fd,
                 strerror(errno));
    else
      log_Printf(LogPHASE, "%s: read (%d): Got zero bytes\n",
                 p->link.name, p->fd);
    datalink_Down(p->dl, CLOSE_NORMAL);
    return;
  }

  rbuff -= p->input.sz;
  n += p->input.sz;

  if (p->link.lcp.fsm.state <= ST_CLOSED) {
    if (p->type != PHYS_DEDICATED) {
      found = hdlc_Detect((u_char const **)&rbuff, n, physical_IsSync(p));
      if (rbuff != p->input.buf)
        log_WritePrompts(p->dl, "%.*s", (int)(rbuff - p->input.buf),
                         p->input.buf);
      p->input.sz = n - (rbuff - p->input.buf);

      if (found) {
        /* LCP packet is detected. Turn ourselves into packet mode */
        log_Printf(LogPHASE, "%s: PPP packet detected, coming up\n",
                   p->link.name);
        log_SetTtyCommandMode(p->dl);
        datalink_Up(p->dl, 0, 1);
        link_PullPacket(&p->link, rbuff, p->input.sz, bundle);
        p->input.sz = 0;
      } else
        bcopy(rbuff, p->input.buf, p->input.sz);
    } else
      /* In -dedicated mode, we just discard input until LCP is started */
      p->input.sz = 0;
  } else if (n > 0)
    link_PullPacket(&p->link, rbuff, n, bundle);
}
示例#4
0
文件: lqr.c 项目: 2asoft/freebsd
static void
SendLqrReport(void *v)
{
  struct lcp *lcp = (struct lcp *)v;
  struct physical *p = link2physical(lcp->fsm.link);

  timer_Stop(&p->hdlc.lqm.timer);

  if (p->hdlc.lqm.method & LQM_LQR) {
    if (p->hdlc.lqm.lqr.resent > 5) {
      /* XXX: Should implement LQM strategy */
      log_Printf(LogPHASE, "%s: ** Too many LQR packets lost **\n",
                lcp->fsm.link->name);
      log_Printf(LogLQM, "%s: Too many LQR packets lost\n",
                lcp->fsm.link->name);
      p->hdlc.lqm.method = 0;
      datalink_Down(p->dl, CLOSE_NORMAL);
    } else {
      SendLqrData(lcp);
      p->hdlc.lqm.lqr.resent++;
    }
  } else if (p->hdlc.lqm.method & LQM_ECHO) {
    if ((p->hdlc.lqm.echo.seq_sent > 5 &&
         p->hdlc.lqm.echo.seq_sent - 5 > p->hdlc.lqm.echo.seq_recv) ||
        (p->hdlc.lqm.echo.seq_sent <= 5 &&
         p->hdlc.lqm.echo.seq_sent > p->hdlc.lqm.echo.seq_recv + 5)) {
      log_Printf(LogPHASE, "%s: ** Too many LCP ECHO packets lost **\n",
                lcp->fsm.link->name);
      log_Printf(LogLQM, "%s: Too many LCP ECHO packets lost\n",
                lcp->fsm.link->name);
      p->hdlc.lqm.method = 0;
      datalink_Down(p->dl, CLOSE_NORMAL);
    } else
      SendEchoReq(lcp);
  }
  if (p->hdlc.lqm.method && p->hdlc.lqm.timer.load)
    timer_Start(&p->hdlc.lqm.timer);
}
示例#5
0
static void
ether_DescriptorRead(struct fdescriptor *d, struct bundle *bundle,
                     const fd_set *fdset)
{
  struct physical *p = descriptor2physical(d);
  struct etherdevice *dev = device2ether(p->handler);

  if (dev->cs >= 0 && FD_ISSET(dev->cs, fdset)) {
    ether_MessageIn(dev);
    if (dev->connected == CARRIER_LOST) {
      log_Printf(LogPHASE, "%s: Device disconnected\n", p->link.name);
      datalink_Down(p->dl, CLOSE_NORMAL);
      return;
    }
  }

  if (physical_IsSet(d, fdset))
    physical_DescriptorRead(d, bundle, fdset);
}