1706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*-
2706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
3706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * All rights reserved.
4706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
5706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Redistribution and use in source and binary forms, with or without
6706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * modification, are permitted provided that the following conditions
7706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * are met:
8706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 1. Redistributions of source code must retain the above copyright
9706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    notice, this list of conditions and the following disclaimer.
10706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 2. Redistributions in binary form must reproduce the above copyright
11706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    notice, this list of conditions and the following disclaimer in the
12706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    documentation and/or other materials provided with the distribution.
13706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
14706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * SUCH DAMAGE.
25706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
26706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * $FreeBSD: src/usr.sbin/ppp/i4b.c,v 1.16.12.1 2010/12/21 17:10:29 kensmith Exp $
27706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
28706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
29706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/param.h>
30706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
31706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/un.h>
32706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#if defined(__OpenBSD__) || defined(__NetBSD__)
33706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/ioctl.h>
34706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
35706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/stat.h>
36706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
37706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <errno.h>
38706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <fcntl.h>
39706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifdef __NetBSD__
40706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netisdn/i4b_ioctl.h>
41706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netisdn/i4b_rbch_ioctl.h>
42706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#else
43706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <i4b/i4b_ioctl.h>
44706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <i4b/i4b_rbch_ioctl.h>
45706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
46706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdio.h>
47706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdlib.h>
48706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <string.h>
49706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sysexits.h>
50706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/uio.h>
51706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <termios.h>
52706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <unistd.h>
53706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
54706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "layer.h"
55706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "defs.h"
56706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mbuf.h"
57706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "log.h"
58706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "timer.h"
59706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lqr.h"
60706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "hdlc.h"
61706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "throughput.h"
62706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "fsm.h"
63706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lcp.h"
64706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ccp.h"
65706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "link.h"
66706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "async.h"
67706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "descriptor.h"
68706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "physical.h"
69706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mp.h"
70706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "chat.h"
71706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "auth.h"
72706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "chap.h"
73706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "cbcp.h"
74706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "datalink.h"
75706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "main.h"
76706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "i4b.h"
77706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
78706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define	Online(dev)	((dev)->mbits & TIOCM_CD)
79706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
80706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct i4bdevice {
81706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct device dev;		/* What struct physical knows about */
82706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct pppTimer Timer;	/* CD checks */
83706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int mbits;			/* Current DCD status */
84706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int carrier_seconds;		/* seconds before CD is *required* */
85706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh};
86706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
87706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define device2i4b(d) ((d)->type == I4B_DEVICE ? (struct i4bdevice *)d : NULL)
88706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
89706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehunsigned
90706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_DeviceSize(void)
91706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
92706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return sizeof(struct i4bdevice);
93706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
94706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
95706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
96706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * i4b_Timeout() watches the DCD signal and mentions it if it's status
97706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * changes.
98706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
99706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_Timeout(void *data)
101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct physical *p = data;
103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct i4bdevice *dev = device2i4b(p->handler);
104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int ombits, change;
105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  timer_Stop(&dev->Timer);
107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  dev->Timer.load = SECTICKS;		/* Once a second please */
108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  timer_Start(&dev->Timer);
109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  ombits = dev->mbits;
110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (p->fd >= 0) {
112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (ioctl(p->fd, TIOCMGET, &dev->mbits) < 0) {
113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogPHASE, "%s: ioctl error (%s)!\n", p->link.name,
114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 strerror(errno));
115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      datalink_Down(p->dl, CLOSE_NORMAL);
116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      timer_Stop(&dev->Timer);
117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return;
118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else
120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    dev->mbits = 0;
121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (ombits == -1) {
123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* First time looking for carrier */
124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (Online(dev))
125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogPHASE, "%s: %s: CD detected\n", p->link.name, p->name.full);
126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    else if (++dev->carrier_seconds >= dev->dev.cd.delay) {
127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogPHASE, "%s: %s: No carrier"
128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 " (increase ``set cd'' from %d ?)\n",
129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 p->link.name, p->name.full, dev->dev.cd.delay);
130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      timer_Stop(&dev->Timer);
131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      /* i4b_AwaitCarrier() will notice */
132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else {
133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      /* Keep waiting */
134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogDEBUG, "%s: %s: Still no carrier (%d/%d)\n",
135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 p->link.name, p->name.full, dev->carrier_seconds,
136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 dev->dev.cd.delay);
137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      dev->mbits = -1;
138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else {
140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    change = ombits ^ dev->mbits;
141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (change & TIOCM_CD) {
142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (dev->mbits & TIOCM_CD)
143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogDEBUG, "%s: offline -> online\n", p->link.name);
144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      else {
145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogDEBUG, "%s: online -> offline\n", p->link.name);
146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogPHASE, "%s: Carrier lost\n", p->link.name);
147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        datalink_Down(p->dl, CLOSE_NORMAL);
148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        timer_Stop(&dev->Timer);
149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else
151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogDEBUG, "%s: Still %sline\n", p->link.name,
152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 Online(dev) ? "on" : "off");
153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_StartTimer(struct physical *p)
158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct i4bdevice *dev = device2i4b(p->handler);
160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  timer_Stop(&dev->Timer);
162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  dev->Timer.load = SECTICKS;
163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  dev->Timer.func = i4b_Timeout;
164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  dev->Timer.name = "i4b CD";
165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  dev->Timer.arg = p;
166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogDEBUG, "%s: Using i4b_Timeout [%p]\n",
167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             p->link.name, i4b_Timeout);
168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  timer_Start(&dev->Timer);
169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_AwaitCarrier(struct physical *p)
173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct i4bdevice *dev = device2i4b(p->handler);
175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (dev->mbits == -1) {
177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (dev->Timer.state == TIMER_STOPPED) {
178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      dev->carrier_seconds = 0;
179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      i4b_StartTimer(p);
180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return CARRIER_PENDING;			/* Not yet ! */
182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return Online(dev) ? CARRIER_OK : CARRIER_LOST;
185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_Raw(struct physical *p)
189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int oldflag;
191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogDEBUG, "%s: Entering i4b_Raw\n", p->link.name);
193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  oldflag = fcntl(p->fd, F_GETFL, 0);
195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (oldflag < 0)
196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 0;
197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fcntl(p->fd, F_SETFL, oldflag | O_NONBLOCK);
198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 1;
200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_Offline(struct physical *p)
204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct i4bdevice *dev = device2i4b(p->handler);
206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (p->fd >= 0) {
208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    timer_Stop(&dev->Timer);
209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (Online(dev)) {
210706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      int dummy;
211706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
212706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      dummy = 1;
213706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      ioctl(p->fd, TIOCCDTR, &dummy);
214706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
215706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
216706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
217706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
218706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
219706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_Cooked(struct physical *p)
220706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
221706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int oldflag;
222706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
223706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  i4b_Offline(p);	/* In case of emergency close()s */
224706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
225706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((oldflag = fcntl(p->fd, F_GETFL, 0)) != -1)
226706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK);
227706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
228706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
229706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
230706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_StopTimer(struct physical *p)
231706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
232706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct i4bdevice *dev = device2i4b(p->handler);
233706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
234706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  timer_Stop(&dev->Timer);
235706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
236706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
237706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
238706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_Free(struct physical *p)
239706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
240706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct i4bdevice *dev = device2i4b(p->handler);
241706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
242706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  i4b_Offline(p);	/* In case of emergency close()s */
243706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  free(dev);
244706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
245706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
246706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic unsigned
247706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_Speed(struct physical *p)
248706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
249706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct termios ios;
250706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  unsigned ret;
251706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
252706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (tcgetattr(p->fd, &ios) == -1 ||
253706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      (ret = SpeedToUnsigned(cfgetispeed(&ios))) == 0)
254706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ret = 64000;
255706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
256706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return ret;
257706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
258706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
259706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic const char *
260706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_OpenInfo(struct physical *p)
261706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
262706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct i4bdevice *dev = device2i4b(p->handler);
263706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  static char buf[26];
264706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
265706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (Online(dev))
266706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    snprintf(buf, sizeof buf, "carrier took %ds", dev->carrier_seconds);
267706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else
268706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *buf = '\0';
269706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
270706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return buf;
271706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
272706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
273706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
274706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_Slot(struct physical *p)
275706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
276706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct stat st;
277706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
278706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (fstat(p->fd, &st) == 0)
279706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return minor(st.st_rdev);
280706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
281706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return -1;
282706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
283706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
284706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
285706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_device2iov(struct device *d, struct iovec *iov, int *niov,
286706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               int maxiov __unused, int *auxfd __unused, int *nauxfd __unused)
287706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
288706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct i4bdevice *dev = device2i4b(d);
289706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int sz = physical_MaxDeviceSize();
290706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
291706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  iov[*niov].iov_base = realloc(d, sz);
292706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (iov[*niov].iov_base == NULL) {
293706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogALERT, "Failed to allocate memory: %d\n", sz);
294706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    AbortProgram(EX_OSERR);
295706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
296706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  iov[*niov].iov_len = sz;
297706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  (*niov)++;
298706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
299706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (dev->Timer.state != TIMER_STOPPED) {
300706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    timer_Stop(&dev->Timer);
301706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    dev->Timer.state = TIMER_RUNNING;
302706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
303706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
304706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
305706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic struct device basei4bdevice = {
306706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  I4B_DEVICE,
307706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  "i4b",
308706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  0,
309706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  { CD_REQUIRED, DEF_I4BCDDELAY },
310706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  i4b_AwaitCarrier,
311706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  NULL,
312706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  i4b_Raw,
313706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  i4b_Offline,
314706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  i4b_Cooked,
315706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  NULL,
316706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  i4b_StopTimer,
317706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  i4b_Free,
318706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  NULL,
319706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  NULL,
320706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  i4b_device2iov,
321706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  i4b_Speed,
322706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  i4b_OpenInfo,
323706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  i4b_Slot
324706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh};
325706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
326706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct device *
327706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_iov2device(int type, struct physical *p, struct iovec *iov, int *niov,
328706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               int maxiov __unused, int *auxfd __unused, int *nauxfd __unused)
329706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
330706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (type == I4B_DEVICE) {
331706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    struct i4bdevice *dev = (struct i4bdevice *)iov[(*niov)++].iov_base;
332706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
333706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    dev = realloc(dev, sizeof *dev);	/* Reduce to the correct size */
334706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (dev == NULL) {
335706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogALERT, "Failed to allocate memory: %d\n",
336706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 (int)(sizeof *dev));
337706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      AbortProgram(EX_OSERR);
338706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
339706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
340706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Refresh function pointers etc */
341706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memcpy(&dev->dev, &basei4bdevice, sizeof dev->dev);
342706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
343706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    physical_SetupStack(p, dev->dev.name, PHYSICAL_NOFORCE);
344706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (dev->Timer.state != TIMER_STOPPED) {
345706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      dev->Timer.state = TIMER_STOPPED;
346706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      p->handler = &dev->dev;		/* For the benefit of StartTimer */
347706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      i4b_StartTimer(p);
348706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
349706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return &dev->dev;
350706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
351706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
352706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return NULL;
353706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
354706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
355706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct device *
356706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehi4b_Create(struct physical *p)
357706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
358706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct i4bdevice *dev;
359706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int oldflag, dial;
360706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  msg_vr_req_t req;
361706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  telno_t number;
362706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
363706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (p->fd < 0 || ioctl(p->fd, I4B_RBCH_VR_REQ, &req))
364706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Don't want this */
365706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return NULL;
366706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
367706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /*
368706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh   * We don't bother validating the version.... all versions of i4b that
369706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh   * support I4B_RBCH_VR_REQ are fair game :-)
370706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh   */
371706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
372706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (*p->name.full == '\0') {
373706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    physical_SetDevice(p, ttyname(p->fd));
374706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogDEBUG, "%s: Input is an i4b version %d.%d.%d isdn "
375706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               "device (%s)\n", p->link.name, req.version, req.release,
376706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               req.step, p->name.full);
377706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    dial = 0;
378706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else {
379706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogDEBUG, "%s: Opened %s (i4b version %d.%d.%d)\n",
380706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               p->link.name, p->name.full, req.version, req.release, req.step);
381706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    dial = 1;
382706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
383706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
384706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* We're gonna return an i4bdevice (unless something goes horribly wrong) */
385706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
386706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((dev = malloc(sizeof *dev)) == NULL) {
387706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Complete failure - parent doesn't continue trying to ``create'' */
388706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    close(p->fd);
389706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    p->fd = -1;
390706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return NULL;
391706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
392706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
393706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  memcpy(&dev->dev, &basei4bdevice, sizeof dev->dev);
394706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  memset(&dev->Timer, '\0', sizeof dev->Timer);
395706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  dev->mbits = -1;
396706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
397706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  switch (p->cfg.cd.necessity) {
398706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case CD_VARIABLE:
399706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      dev->dev.cd.delay = p->cfg.cd.delay;
400706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
401706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case CD_REQUIRED:
402706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      dev->dev.cd = p->cfg.cd;
403706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
404706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case CD_NOTREQUIRED:
405706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogWARN, "%s: Carrier must be set, using ``set cd %d!''\n",
406706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 p->link.name, dev->dev.cd.delay);
407706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case CD_DEFAULT:
408706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
409706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
410706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
411706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  oldflag = fcntl(p->fd, F_GETFL, 0);
412706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (oldflag < 0) {
413706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Complete failure - parent doesn't continue trying to ``create'' */
414706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
415706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogWARN, "%s: Open: Cannot get physical flags: %s\n",
416706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               p->link.name, strerror(errno));
417706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    i4b_Cooked(p);
418706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    close(p->fd);
419706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    p->fd = -1;
420706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    free(dev);
421706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return NULL;
422706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else
423706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK);
424706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
425706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (dial) {
426706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    strncpy(number, datalink_ChoosePhoneNumber(p->dl), sizeof number - 1);
427706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    number[sizeof number - 1] = '\0';
428706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (number[0] == '\0')
429706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      dial = 0;
430706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
431706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (dial && ioctl(p->fd, I4B_RBCH_DIALOUT, number) == -1) {
432706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Complete failure - parent doesn't continue trying to ``create'' */
433706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
434706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogWARN, "%s: ioctl(I4B_RBCH_DIALOUT): %s\n",
435706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               p->link.name, strerror(errno));
436706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    i4b_Cooked(p);
437706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    close(p->fd);
438706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    p->fd = -1;
439706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    free(dev);
440706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return NULL;
441706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
442706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
443706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  physical_SetupStack(p, dev->dev.name, PHYSICAL_FORCE_SYNC);
444706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
445706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return &dev->dev;
446706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
447