xpp: README: hwid attribute of the xpd sysfs node
[dahdi/tools.git] / ppp / dahdi.c
1 /* dahdi.c - pppd plugin to implement PPP over DAHDI HDLC channel.
2  *
3  * Copyright 2002  Digium, Inc. 
4  *                 Mark Spencer <markster@digium.inc>
5  *
6  * Borrows from PPPoE by Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
7  *                Jamal Hadi Salim <hadi@cyberus.ca>
8  *
9  * which in turn...
10  *
11  * Borrows heavily from the PPPoATM plugin by Mitchell Blank Jr.,
12  * which is based in part on work from Jens Axboe and Paul Mackerras.
13  *
14  */
15
16 /*
17  * See http://www.asterisk.org for more information about
18  * the Asterisk project. Please do not directly contact
19  * any of the maintainers of this project for assistance;
20  * the project provides a web site, mailing lists and IRC
21  * channels for your use.
22  *
23  * This program is free software, distributed under the terms of
24  * the GNU General Public License Version 2 as published by the
25  * Free Software Foundation. See the LICENSE file included with
26  * this program for more details.
27  */
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/ioctl.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <unistd.h>
35 #include <errno.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38
39 #include <pppd/pppd.h>
40 #include <pppd/fsm.h>
41 #include <pppd/lcp.h>
42 #include <pppd/ipcp.h>
43 #include <pppd/ccp.h>
44 #include <pppd/pathnames.h>
45
46 #include <dahdi/user.h>
47
48 extern int new_style_driver;
49
50 const char pppd_version[] = VERSION;
51
52 #define _PATH_DAHDI_OPT         _ROOT_PATH "/etc/ppp/options."
53
54 #define DAHDI_MTU       (DAHDI_DEFAULT_MTU_MRU - 16)
55 extern int kill_link;
56 int     retries = 0;
57
58 int setdevname_dahdi(const char *cp);
59
60 static option_t dahdi_options[] = {
61         { "device name", o_wild, (void *) &setdevname_dahdi,
62           "Serial port device name",
63           OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG  | OPT_A2STRVAL | OPT_STATIC,
64           devnam},
65         { NULL }
66 };
67
68 static int dahdi_fd = -1;
69 static int dahdi_chan = 0;
70
71 static int connect_dahdi(void)
72 {
73     
74     struct dahdi_params dahdi_params;
75     int res;
76     int x;
77
78     info("DAHDI device is '%s'\n", devnam);
79
80     strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
81
82     if (strlen(devnam) && strcmp(devnam, "stdin")) {
83         /* Get the channel number */
84         dahdi_chan = atoi(devnam);
85         if (dahdi_chan < 1) {
86                 fatal("'%s' is not a valid device name\n", devnam);
87                 return -1;
88         }
89
90         /* Open /dev/dahdi/channel interface */
91         dahdi_fd = open("/dev/dahdi/channel", O_RDWR);
92         if (dahdi_fd < 0) {
93                 fatal("Unable to open DAHDI channel interface: '%s'\n", strerror(errno));
94                 return dahdi_fd;
95         }
96
97         /* Specify which channel we really want */
98         x = dahdi_chan;
99         res = ioctl(dahdi_fd, DAHDI_SPECIFY, &x);
100         if (res) {
101                 fatal("Unable to specify channel %d: %s\n", dahdi_chan, strerror(errno));
102                 close(dahdi_fd);
103                 dahdi_fd = -1;
104                 return -1;
105         }
106     } else
107         dahdi_fd = STDIN_FILENO;
108
109
110     /* Get channel parameters */
111     memset(&dahdi_params, 0, sizeof(dahdi_params));
112     dahdi_params.channo = -1;
113
114     res = ioctl(dahdi_fd, DAHDI_GET_PARAMS, &dahdi_params);
115
116     if (res) {
117         fatal("Device '%s' does not appear to be a DAHDI device\n", devnam ? devnam : "<stdin>");
118     }
119
120     x = 1;
121
122     /* Throw into HDLC/PPP mode */
123     res = ioctl(dahdi_fd, DAHDI_HDLCPPP, &x);
124
125     if (res) {
126         fatal("Unable to put device '%s' into HDLC mode\n", devnam);
127         close(dahdi_fd);
128         dahdi_fd = -1;
129         return -1;
130     }
131
132     /* Once the logging is fixed, print a message here indicating
133        connection parameters */
134     dahdi_chan = dahdi_params.channo;
135     info("Connected to DAHDI device '%s' (%d)\n", dahdi_params.name, dahdi_params.channo);
136
137     return dahdi_fd;
138 }
139
140 static void disconnect_dahdi(void)
141 {
142     int res;
143     int x = 0;
144     /* Throw out of HDLC mode */
145     res = ioctl(dahdi_fd, DAHDI_HDLCPPP, &x);
146
147     if (res) {
148         warn("Unable to take device '%s' out of HDLC mode\n", devnam);
149     }
150
151     /* Close if it's not stdin */
152     if (strlen(devnam))
153         close(dahdi_fd);
154     warn("Disconnect from DAHDI");
155
156 }
157
158
159 static int setspeed_dahdi(const char *cp)
160 {
161     return 0;
162 }
163
164 static void dahdi_extra_options()
165 {
166     int ret;
167     char buf[256];
168     snprintf(buf, 256, _PATH_DAHDI_OPT "%s",devnam);
169     if(!options_from_file(buf, 0, 0, 1))
170         exit(EXIT_OPTION_ERROR);
171
172 }
173
174
175
176 static void send_config_dahdi(int mtu,
177                               u_int32_t asyncmap,
178                               int pcomp,
179                               int accomp)
180 {
181     int sock;
182
183     if (mtu > DAHDI_MTU) {
184         warn("Couldn't increase MTU to %d.", mtu);
185         mtu = DAHDI_MTU;
186     }
187 }
188
189
190 static void recv_config_dahdi(int mru,
191                               u_int32_t asyncmap,
192                               int pcomp,
193                               int accomp)
194 {
195     if (mru > DAHDI_MTU)
196         error("Couldn't increase MRU to %d", mru);
197 }
198
199 static void set_xaccm_pppoe(int unit, ext_accm accm)
200 {
201     /* NOTHING */
202 }
203
204
205
206 struct channel dahdi_channel;
207
208 /* Check is cp is a valid DAHDI device
209  * return either 1 if "cp" is a reasonable thing to name a device
210  * or die.
211  * Note that we don't actually open the device at this point
212  * We do need to fill in:
213  *   devnam: a string representation of the device
214  */
215
216 int (*old_setdevname_hook)(const char* cp) = NULL;
217 int setdevname_dahdi(const char *cp)
218 {
219     int ret;
220     int chan;
221
222     /* If already set, forgoe */
223     if (strlen(devnam))
224         return 1;
225
226
227     if (strcmp(cp, "stdin")) {
228         ret = sscanf(cp, "%d", &chan);
229         if (ret != 1) {
230                 fatal("DAHDI: Invalid channel: '%s'\n", cp);
231                 return -1;
232         }
233     }
234
235     dahdi_copy_string(devnam, cp, sizeof(devnam));
236
237     info("Using DAHDI device '%s'\n", devnam);
238
239     ret = 1;
240
241     if( ret == 1 && the_channel != &dahdi_channel ){
242
243         the_channel = &dahdi_channel;
244
245         modem = 0;
246
247         lcp_allowoptions[0].neg_accompression = 0;
248         lcp_wantoptions[0].neg_accompression = 0;
249
250         lcp_allowoptions[0].neg_pcompression = 0;
251         lcp_wantoptions[0].neg_pcompression = 0;
252
253         ccp_allowoptions[0].deflate = 0 ;
254         ccp_wantoptions[0].deflate = 0 ;
255
256         ipcp_allowoptions[0].neg_vj=0;
257         ipcp_wantoptions[0].neg_vj=0;
258
259         ccp_allowoptions[0].bsd_compress = 0;
260         ccp_wantoptions[0].bsd_compress = 0;
261
262         lcp_allowoptions[0].neg_asyncmap = 0;
263         lcp_wantoptions[0].neg_asyncmap = 0;
264
265     }
266     return ret;
267 }
268
269
270
271 void plugin_init(void)
272 {
273     if (!ppp_available() && !new_style_driver)
274         fatal("Kernel doesn't support ppp_generic needed for DAHDI PPP");
275     add_options(dahdi_options);
276
277     info("DAHDI Plugin Initialized");
278 }
279
280 struct channel dahdi_channel = {
281     options: dahdi_options,
282     process_extra_options: &dahdi_extra_options,
283     check_options: NULL,
284     connect: &connect_dahdi,
285     disconnect: &disconnect_dahdi,
286     establish_ppp: &generic_establish_ppp,
287     disestablish_ppp: &generic_disestablish_ppp,
288     send_config: &send_config_dahdi,
289     recv_config: &recv_config_dahdi,
290     close: NULL,
291     cleanup: NULL
292 };
293