00001 /* 00002 * Copyright (C) 2002 by Call Direct Cellular Solutions Pty. Ltd. All rights reserved. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions 00006 * are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the copyright holders nor the names of 00014 * contributors may be used to endorse or promote products derived 00015 * from this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY CALL DIRECT CELLULAR SOLUTIONS AND CONTRIBUTORS 00018 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00019 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00020 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CALL DIRECT 00021 * CELLULAR SOLUTIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00022 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00023 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00024 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 00025 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00026 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 00027 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00028 * SUCH DAMAGE. 00029 * 00030 * For additional information see http://www.calldirect.com.au/ 00031 * - 00032 * Copyright (C) 2001-2004 by egnite Software GmbH. All rights reserved. 00033 * 00034 * Redistribution and use in source and binary forms, with or without 00035 * modification, are permitted provided that the following conditions 00036 * are met: 00037 * 00038 * 1. Redistributions of source code must retain the above copyright 00039 * notice, this list of conditions and the following disclaimer. 00040 * 2. Redistributions in binary form must reproduce the above copyright 00041 * notice, this list of conditions and the following disclaimer in the 00042 * documentation and/or other materials provided with the distribution. 00043 * 3. All advertising materials mentioning features or use of this 00044 * software must display the following acknowledgement: 00045 * 00046 * This product includes software developed by egnite Software GmbH 00047 * and its contributors. 00048 * 00049 * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS 00050 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00051 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00052 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE 00053 * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00054 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00055 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00056 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 00057 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00058 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 00059 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00060 * SUCH DAMAGE. 00061 * 00062 * For additional information see http://www.ethernut.de/ 00063 * 00064 */ 00065 00066 /* 00067 * $Log$ 00068 * Revision 1.12 2008/08/28 11:12:15 haraldkipp 00069 * Added interface flags, which will be required to implement Ethernet ioctl 00070 * functions. 00071 * 00072 * Revision 1.11 2008/08/11 06:59:42 haraldkipp 00073 * BSD types replaced by stdint types (feature request #1282721). 00074 * 00075 * Revision 1.10 2007/07/17 18:32:27 haraldkipp 00076 * Fixed bug #1369171, memory leak in NutPppClose(). Thanks to Sergey Danilov. 00077 * 00078 * Revision 1.9 2007/05/02 11:22:51 haraldkipp 00079 * Added multicast table entry. 00080 * 00081 * Revision 1.8 2006/03/29 01:23:52 olereinhardt 00082 * Signednes of strings 00083 * 00084 * Revision 1.7 2005/04/30 16:42:41 chaac 00085 * Fixed bug in handling of NUTDEBUG. Added include for cfg/os.h. If NUTDEBUG 00086 * is defined in NutConf, it will make effect where it is used. 00087 * 00088 * Revision 1.6 2004/03/16 16:48:27 haraldkipp 00089 * Added Jan Dubiec's H8/300 port. 00090 * 00091 * Revision 1.5 2004/03/14 10:12:29 haraldkipp 00092 * Bugfix, failed to compile 00093 * 00094 * Revision 1.4 2004/03/08 11:15:32 haraldkipp 00095 * HDLC functions moved to async HDLC driver. 00096 * 00097 * Revision 1.3 2003/08/14 15:21:01 haraldkipp 00098 * Bugfix, allow HDLC flag to mark end _and_ begin 00099 * 00100 * Revision 1.2 2003/08/05 20:05:11 haraldkipp 00101 * DNS removed from interface 00102 * 00103 * Revision 1.1.1.1 2003/05/09 14:40:48 haraldkipp 00104 * Initial using 3.2.1 00105 * 00106 * Revision 1.2 2003/05/06 18:33:50 harald 00107 * PPP hack for simple UART support, functions reordered. 00108 * 00109 * Revision 1.1 2003/03/31 14:53:08 harald 00110 * Prepare release 3.1 00111 * 00112 */ 00113 00114 #include <cfg/os.h> 00115 #include <string.h> 00116 #include <io.h> 00117 #include <fcntl.h> 00118 00119 #include <net/if_var.h> 00120 #include <net/ppp.h> 00121 00122 #include <sys/heap.h> 00123 #include <sys/event.h> 00124 #include <sys/timer.h> 00125 #include <sys/thread.h> 00126 00127 #include <dev/ppp.h> 00128 #include <netinet/ppp_fsm.h> 00129 #include <dev/ahdlc.h> 00130 00131 #ifdef NUTDEBUG 00132 #include <net/netdebug.h> 00133 #endif 00134 00139 00140 static PPPDCB dcb_ppp; 00141 00142 00143 /* 00144 * Pass reads to the physical driver for now. 00145 */ 00146 static int NutPppRead(NUTFILE * fp, void *buffer, int size) 00147 { 00148 return _read(((PPPDCB *) (fp->nf_dev->dev_dcb))->dcb_fd, buffer, size); 00149 } 00150 00151 /* 00152 * Pass writes to the physical driver for now. 00153 */ 00154 static int NutPppWrite(NUTFILE * fp, CONST void *buffer, int len) 00155 { 00156 return _write(((PPPDCB *) (fp->nf_dev->dev_dcb))->dcb_fd, buffer, len); 00157 } 00158 00159 /* 00160 * Pass writes to the physical driver for now. 00161 */ 00162 #ifdef __HARVARD_ARCH__ 00163 static int NutPppWrite_P(NUTFILE * fp, PGM_P buffer, int len) 00164 { 00165 return _write_P(((PPPDCB *) (fp->nf_dev->dev_dcb))->dcb_fd, buffer, len); 00166 } 00167 #endif 00168 00188 static int NutPppIOCtl(NUTDEVICE * dev, int req, void *conf) 00189 { 00190 int rc = 0; 00191 00192 switch (req) { 00193 case LCP_OPEN: 00194 LcpOpen(dev); 00195 break; 00196 00197 case LCP_CLOSE: 00198 LcpClose(dev); 00199 break; 00200 00201 case LCP_LOWERUP: 00202 LcpLowerUp(dev); 00203 break; 00204 00205 case LCP_LOWERDOWN: 00206 LcpLowerDown(dev); 00207 break; 00208 00209 default: 00210 rc = _ioctl(((PPPDCB *) (dev->dev_dcb))->dcb_fd, req, conf); 00211 break; 00212 } 00213 return rc; 00214 } 00215 00216 /* 00217 * \brief Enable the link layer to come up. 00218 * 00219 * The underlying hardware driver should have established a physical 00220 * connection before calling this function. 00221 * 00222 * \param name Physical device name optionally followed by username 00223 * and password, each separated by a slash. 00224 * 00225 */ 00226 static NUTFILE *NutPppOpen(NUTDEVICE * dev, CONST char *name, int mode, int acc) 00227 { 00228 NUTFILE *fp; 00229 uint8_t i; 00230 char *cp; 00231 char *sp; 00232 char pdn[9]; 00233 PPPDCB *dcb = dev->dev_dcb; 00234 00235 /* Clear our device control block. */ 00236 memset(dcb, 0, sizeof(PPPDCB)); 00237 00238 /* Get the first part of the name, it specifies the physical device. */ 00239 for (cp = (char *) name, i = 0; *cp && *cp != '/' && i < sizeof(pdn) - 1; i++) { 00240 pdn[i] = *cp++; 00241 } 00242 pdn[i] = 0; 00243 00244 /* Open the pysical device. */ 00245 if ((dcb->dcb_fd = _open(pdn, _O_RDWR | _O_BINARY)) == -1) { 00246 return NUTFILE_EOF; 00247 } 00248 00249 /* 00250 * Allocate a file structure to return. 00251 */ 00252 if ((fp = NutHeapAlloc(sizeof(NUTFILE))) == 0) { 00253 return NUTFILE_EOF; 00254 } 00255 fp->nf_next = 0; 00256 fp->nf_dev = dev; 00257 fp->nf_fcb = 0; 00258 00259 /* 00260 * Extract user name and password and store it in our device control 00261 * block. It will be used later by the authentication layer. 00262 */ 00263 if (*cp == '/') { 00264 for (sp = ++cp, i = 0; *sp && *sp != '/'; sp++, i++); 00265 if (i) { 00266 dcb->dcb_user = NutHeapAlloc(i + 1); 00267 for (sp = (char*)dcb->dcb_user; *cp && *cp != '/';) 00268 *sp++ = *cp++; 00269 *sp = 0; 00270 } 00271 if (*cp == '/') { 00272 for (sp = ++cp, i = 0; *sp && *sp != '/'; sp++, i++); 00273 if (i) { 00274 dcb->dcb_pass = NutHeapAlloc(i + 1); 00275 for (sp = (char*)dcb->dcb_pass; *cp && *cp != '/';) 00276 *sp++ = *cp++; 00277 *sp = 0; 00278 } 00279 } 00280 } 00281 00282 /* Enable all layers to come up. */ 00283 IpcpOpen(dev); 00284 00285 return fp; 00286 } 00287 00288 00289 /* 00290 * Start closing connection. 00291 */ 00292 static int NutPppClose(NUTFILE * fp) 00293 { 00294 PPPDCB *dcb = fp->nf_dev->dev_dcb; 00295 00296 IpcpClose(fp->nf_dev); 00297 _close(dcb->dcb_fd); 00298 00299 if (dcb->dcb_user) 00300 NutHeapFree(dcb->dcb_user); 00301 if (dcb->dcb_pass) 00302 NutHeapFree(dcb->dcb_pass); 00303 NutHeapFree(fp); 00304 00305 return 0; 00306 } 00307 00318 static int NutPppInit(NUTDEVICE * dev) 00319 { 00320 return NutPppInitStateMachine(dev); 00321 } 00322 00326 IFNET ifn_ppp = { 00327 IFT_PPP, 00328 0, 00329 {0, 0, 0, 0, 0, 0} 00330 , 00331 0, 00332 0, 00333 0, 00334 PPP_MRU, 00335 0, 00336 0, 00337 0, 00338 NutPppInput, 00339 0, 00340 NutPppOutput 00341 }; 00342 00350 NUTDEVICE devPpp = { 00351 0, /* Pointer to next device, dev_next. */ 00352 {'p', 'p', 'p', 0, 0, 0, 0, 0, 0} 00353 , /* Unique device name, dev_name. */ 00354 IFTYP_NET, /* Type of device, dev_type. */ 00355 0, /* Base address, dev_base. */ 00356 0, /* First interrupt number, dev_irq. */ 00357 &ifn_ppp, /* Interface control block, dev_icb. */ 00358 &dcb_ppp, /* Driver control block, dev_dcb. */ 00359 NutPppInit, /* Driver initialization routine, dev_init(). */ 00360 NutPppIOCtl, /* Driver specific control function, dev_ioctl(). */ 00361 NutPppRead, /* Read from device, dev_read. */ 00362 NutPppWrite, /* Write to device, dev_write. */ 00363 #ifdef __HARVARD_ARCH__ 00364 NutPppWrite_P, /* Write data from program space to device, dev_write_P. */ 00365 #endif 00366 NutPppOpen, /* Open a device or file, dev_open. */ 00367 NutPppClose, /* Close a device or file, dev_close. */ 00368 0 /* Request file size. */ 00369 }; 00370