Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

Committer:
switches
Date:
Fri Nov 11 20:59:50 2016 +0000
Revision:
0:5c4d7b2438d3
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
switches 0:5c4d7b2438d3 1 PPP interface for lwIP
switches 0:5c4d7b2438d3 2
switches 0:5c4d7b2438d3 3 Author: Sylvain Rochet
switches 0:5c4d7b2438d3 4
switches 0:5c4d7b2438d3 5 Table of Contents:
switches 0:5c4d7b2438d3 6
switches 0:5c4d7b2438d3 7 1 - Supported PPP protocols and features
switches 0:5c4d7b2438d3 8 2 - Raw API PPP example for all protocols
switches 0:5c4d7b2438d3 9 3 - PPPoS input path (raw API, IRQ safe API, TCPIP API)
switches 0:5c4d7b2438d3 10 4 - Thread safe PPP API (PPPAPI)
switches 0:5c4d7b2438d3 11 5 - Notify phase callback (PPP_NOTIFY_PHASE)
switches 0:5c4d7b2438d3 12 6 - Upgrading from lwIP <= 1.4.x to lwIP >= 2.0.x
switches 0:5c4d7b2438d3 13
switches 0:5c4d7b2438d3 14
switches 0:5c4d7b2438d3 15
switches 0:5c4d7b2438d3 16 1 Supported PPP protocols and features
switches 0:5c4d7b2438d3 17 ======================================
switches 0:5c4d7b2438d3 18
switches 0:5c4d7b2438d3 19 Supported Low level protocols:
switches 0:5c4d7b2438d3 20 * PPP over serial using HDLC-like framing, such as wired dialup modems
switches 0:5c4d7b2438d3 21 or mobile telecommunications GPRS/EDGE/UMTS/HSPA+/LTE modems
switches 0:5c4d7b2438d3 22 * PPP over Ethernet, such as xDSL modems
switches 0:5c4d7b2438d3 23 * PPP over L2TP (Layer 2 Tunneling Protocol) LAC (L2TP Access Concentrator),
switches 0:5c4d7b2438d3 24 IP tunnel over UDP, such as VPN access
switches 0:5c4d7b2438d3 25
switches 0:5c4d7b2438d3 26 Supported auth protocols:
switches 0:5c4d7b2438d3 27 * PAP, Password Authentication Protocol
switches 0:5c4d7b2438d3 28 * CHAP, Challenge-Handshake Authentication Protocol, also known as CHAP-MD5
switches 0:5c4d7b2438d3 29 * MSCHAPv1, Microsoft version of CHAP, version 1
switches 0:5c4d7b2438d3 30 * MSCHAPv2, Microsoft version of CHAP, version 2
switches 0:5c4d7b2438d3 31 * EAP, Extensible Authentication Protocol
switches 0:5c4d7b2438d3 32
switches 0:5c4d7b2438d3 33 Supported address protocols:
switches 0:5c4d7b2438d3 34 * IPCP, IP Control Protocol, IPv4 addresses negotiation
switches 0:5c4d7b2438d3 35 * IP6CP, IPv6 Control Protocol, IPv6 link-local addresses negotiation
switches 0:5c4d7b2438d3 36
switches 0:5c4d7b2438d3 37 Supported encryption protocols:
switches 0:5c4d7b2438d3 38 * MPPE, Microsoft Point-to-Point Encryption
switches 0:5c4d7b2438d3 39
switches 0:5c4d7b2438d3 40 Supported compression or miscellaneous protocols, for serial links only:
switches 0:5c4d7b2438d3 41 * PFC, Protocol Field Compression
switches 0:5c4d7b2438d3 42 * ACFC, Address-and-Control-Field-Compression
switches 0:5c4d7b2438d3 43 * ACCM, Asynchronous-Control-Character-Map
switches 0:5c4d7b2438d3 44 * VJ, Van Jacobson TCP/IP Header Compression
switches 0:5c4d7b2438d3 45
switches 0:5c4d7b2438d3 46
switches 0:5c4d7b2438d3 47
switches 0:5c4d7b2438d3 48 2 Raw API PPP example for all protocols
switches 0:5c4d7b2438d3 49 =======================================
switches 0:5c4d7b2438d3 50
switches 0:5c4d7b2438d3 51 As usual, raw API for lwIP means the lightweight API which *MUST* only be used
switches 0:5c4d7b2438d3 52 for NO_SYS=1 systems or called inside lwIP core thread for NO_SYS=0 systems.
switches 0:5c4d7b2438d3 53
switches 0:5c4d7b2438d3 54 /*
switches 0:5c4d7b2438d3 55 * Globals
switches 0:5c4d7b2438d3 56 * =======
switches 0:5c4d7b2438d3 57 */
switches 0:5c4d7b2438d3 58
switches 0:5c4d7b2438d3 59 /* The PPP control block */
switches 0:5c4d7b2438d3 60 ppp_pcb *ppp;
switches 0:5c4d7b2438d3 61
switches 0:5c4d7b2438d3 62 /* The PPP IP interface */
switches 0:5c4d7b2438d3 63 struct netif ppp_netif;
switches 0:5c4d7b2438d3 64
switches 0:5c4d7b2438d3 65
switches 0:5c4d7b2438d3 66 /*
switches 0:5c4d7b2438d3 67 * PPP status callback
switches 0:5c4d7b2438d3 68 * ===================
switches 0:5c4d7b2438d3 69 *
switches 0:5c4d7b2438d3 70 * PPP status callback is called on PPP status change (up, down, …) from lwIP
switches 0:5c4d7b2438d3 71 * core thread
switches 0:5c4d7b2438d3 72 */
switches 0:5c4d7b2438d3 73
switches 0:5c4d7b2438d3 74 /* PPP status callback example */
switches 0:5c4d7b2438d3 75 static void status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
switches 0:5c4d7b2438d3 76 struct netif *pppif = ppp_netif(pcb);
switches 0:5c4d7b2438d3 77 LWIP_UNUSED_ARG(ctx);
switches 0:5c4d7b2438d3 78
switches 0:5c4d7b2438d3 79 switch(err_code) {
switches 0:5c4d7b2438d3 80 case PPPERR_NONE: {
switches 0:5c4d7b2438d3 81 #if LWIP_DNS
switches 0:5c4d7b2438d3 82 ip_addr_t ns;
switches 0:5c4d7b2438d3 83 #endif /* LWIP_DNS */
switches 0:5c4d7b2438d3 84 printf("status_cb: Connected\n");
switches 0:5c4d7b2438d3 85 #if PPP_IPV4_SUPPORT
switches 0:5c4d7b2438d3 86 printf(" our_ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr));
switches 0:5c4d7b2438d3 87 printf(" his_ipaddr = %s\n", ipaddr_ntoa(&pppif->gw));
switches 0:5c4d7b2438d3 88 printf(" netmask = %s\n", ipaddr_ntoa(&pppif->netmask));
switches 0:5c4d7b2438d3 89 #if LWIP_DNS
switches 0:5c4d7b2438d3 90 ns = dns_getserver(0);
switches 0:5c4d7b2438d3 91 printf(" dns1 = %s\n", ipaddr_ntoa(&ns));
switches 0:5c4d7b2438d3 92 ns = dns_getserver(1);
switches 0:5c4d7b2438d3 93 printf(" dns2 = %s\n", ipaddr_ntoa(&ns));
switches 0:5c4d7b2438d3 94 #endif /* LWIP_DNS */
switches 0:5c4d7b2438d3 95 #endif /* PPP_IPV4_SUPPORT */
switches 0:5c4d7b2438d3 96 #if PPP_IPV6_SUPPORT
switches 0:5c4d7b2438d3 97 printf(" our6_ipaddr = %s\n", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
switches 0:5c4d7b2438d3 98 #endif /* PPP_IPV6_SUPPORT */
switches 0:5c4d7b2438d3 99 break;
switches 0:5c4d7b2438d3 100 }
switches 0:5c4d7b2438d3 101 case PPPERR_PARAM: {
switches 0:5c4d7b2438d3 102 printf("status_cb: Invalid parameter\n");
switches 0:5c4d7b2438d3 103 break;
switches 0:5c4d7b2438d3 104 }
switches 0:5c4d7b2438d3 105 case PPPERR_OPEN: {
switches 0:5c4d7b2438d3 106 printf("status_cb: Unable to open PPP session\n");
switches 0:5c4d7b2438d3 107 break;
switches 0:5c4d7b2438d3 108 }
switches 0:5c4d7b2438d3 109 case PPPERR_DEVICE: {
switches 0:5c4d7b2438d3 110 printf("status_cb: Invalid I/O device for PPP\n");
switches 0:5c4d7b2438d3 111 break;
switches 0:5c4d7b2438d3 112 }
switches 0:5c4d7b2438d3 113 case PPPERR_ALLOC: {
switches 0:5c4d7b2438d3 114 printf("status_cb: Unable to allocate resources\n");
switches 0:5c4d7b2438d3 115 break;
switches 0:5c4d7b2438d3 116 }
switches 0:5c4d7b2438d3 117 case PPPERR_USER: {
switches 0:5c4d7b2438d3 118 printf("status_cb: User interrupt\n");
switches 0:5c4d7b2438d3 119 break;
switches 0:5c4d7b2438d3 120 }
switches 0:5c4d7b2438d3 121 case PPPERR_CONNECT: {
switches 0:5c4d7b2438d3 122 printf("status_cb: Connection lost\n");
switches 0:5c4d7b2438d3 123 break;
switches 0:5c4d7b2438d3 124 }
switches 0:5c4d7b2438d3 125 case PPPERR_AUTHFAIL: {
switches 0:5c4d7b2438d3 126 printf("status_cb: Failed authentication challenge\n");
switches 0:5c4d7b2438d3 127 break;
switches 0:5c4d7b2438d3 128 }
switches 0:5c4d7b2438d3 129 case PPPERR_PROTOCOL: {
switches 0:5c4d7b2438d3 130 printf("status_cb: Failed to meet protocol\n");
switches 0:5c4d7b2438d3 131 break;
switches 0:5c4d7b2438d3 132 }
switches 0:5c4d7b2438d3 133 case PPPERR_PEERDEAD: {
switches 0:5c4d7b2438d3 134 printf("status_cb: Connection timeout\n");
switches 0:5c4d7b2438d3 135 break;
switches 0:5c4d7b2438d3 136 }
switches 0:5c4d7b2438d3 137 case PPPERR_IDLETIMEOUT: {
switches 0:5c4d7b2438d3 138 printf("status_cb: Idle Timeout\n");
switches 0:5c4d7b2438d3 139 break;
switches 0:5c4d7b2438d3 140 }
switches 0:5c4d7b2438d3 141 case PPPERR_CONNECTTIME: {
switches 0:5c4d7b2438d3 142 printf("status_cb: Max connect time reached\n");
switches 0:5c4d7b2438d3 143 break;
switches 0:5c4d7b2438d3 144 }
switches 0:5c4d7b2438d3 145 case PPPERR_LOOPBACK: {
switches 0:5c4d7b2438d3 146 printf("status_cb: Loopback detected\n");
switches 0:5c4d7b2438d3 147 break;
switches 0:5c4d7b2438d3 148 }
switches 0:5c4d7b2438d3 149 default: {
switches 0:5c4d7b2438d3 150 printf("status_cb: Unknown error code %d\n", err_code);
switches 0:5c4d7b2438d3 151 break;
switches 0:5c4d7b2438d3 152 }
switches 0:5c4d7b2438d3 153 }
switches 0:5c4d7b2438d3 154
switches 0:5c4d7b2438d3 155 /*
switches 0:5c4d7b2438d3 156 * This should be in the switch case, this is put outside of the switch
switches 0:5c4d7b2438d3 157 * case for example readability.
switches 0:5c4d7b2438d3 158 */
switches 0:5c4d7b2438d3 159
switches 0:5c4d7b2438d3 160 if (err_code == PPPERR_NONE) {
switches 0:5c4d7b2438d3 161 return;
switches 0:5c4d7b2438d3 162 }
switches 0:5c4d7b2438d3 163
switches 0:5c4d7b2438d3 164 /* ppp_close() was previously called, don't reconnect */
switches 0:5c4d7b2438d3 165 if (err_code == PPPERR_USER) {
switches 0:5c4d7b2438d3 166 /* ppp_free(); -- can be called here */
switches 0:5c4d7b2438d3 167 return;
switches 0:5c4d7b2438d3 168 }
switches 0:5c4d7b2438d3 169
switches 0:5c4d7b2438d3 170 /*
switches 0:5c4d7b2438d3 171 * Try to reconnect in 30 seconds, if you need a modem chatscript you have
switches 0:5c4d7b2438d3 172 * to do a much better signaling here ;-)
switches 0:5c4d7b2438d3 173 */
switches 0:5c4d7b2438d3 174 ppp_connect(pcb, 30);
switches 0:5c4d7b2438d3 175 /* OR ppp_listen(pcb); */
switches 0:5c4d7b2438d3 176 }
switches 0:5c4d7b2438d3 177
switches 0:5c4d7b2438d3 178
switches 0:5c4d7b2438d3 179 /*
switches 0:5c4d7b2438d3 180 * Creating a new PPPoS session
switches 0:5c4d7b2438d3 181 * ============================
switches 0:5c4d7b2438d3 182 *
switches 0:5c4d7b2438d3 183 * In lwIP, PPPoS is not PPPoSONET, in lwIP PPPoS is PPPoSerial.
switches 0:5c4d7b2438d3 184 */
switches 0:5c4d7b2438d3 185
switches 0:5c4d7b2438d3 186 #include "netif/ppp/pppos.h"
switches 0:5c4d7b2438d3 187
switches 0:5c4d7b2438d3 188 /*
switches 0:5c4d7b2438d3 189 * PPPoS serial output callback
switches 0:5c4d7b2438d3 190 *
switches 0:5c4d7b2438d3 191 * ppp_pcb, PPP control block
switches 0:5c4d7b2438d3 192 * data, buffer to write to serial port
switches 0:5c4d7b2438d3 193 * len, length of the data buffer
switches 0:5c4d7b2438d3 194 * ctx, optional user-provided callback context pointer
switches 0:5c4d7b2438d3 195 *
switches 0:5c4d7b2438d3 196 * Return value: len if write succeed
switches 0:5c4d7b2438d3 197 */
switches 0:5c4d7b2438d3 198 static u32_t output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx) {
switches 0:5c4d7b2438d3 199 return uart_write(UART, data, len);
switches 0:5c4d7b2438d3 200 }
switches 0:5c4d7b2438d3 201
switches 0:5c4d7b2438d3 202 /*
switches 0:5c4d7b2438d3 203 * Create a new PPPoS interface
switches 0:5c4d7b2438d3 204 *
switches 0:5c4d7b2438d3 205 * ppp_netif, netif to use for this PPP link, i.e. PPP IP interface
switches 0:5c4d7b2438d3 206 * output_cb, PPPoS serial output callback
switches 0:5c4d7b2438d3 207 * status_cb, PPP status callback, called on PPP status change (up, down, …)
switches 0:5c4d7b2438d3 208 * ctx_cb, optional user-provided callback context pointer
switches 0:5c4d7b2438d3 209 */
switches 0:5c4d7b2438d3 210 ppp = pppos_create(&ppp_netif,
switches 0:5c4d7b2438d3 211 output_cb, status_cb, ctx_cb);
switches 0:5c4d7b2438d3 212
switches 0:5c4d7b2438d3 213
switches 0:5c4d7b2438d3 214 /*
switches 0:5c4d7b2438d3 215 * Creating a new PPPoE session
switches 0:5c4d7b2438d3 216 * ============================
switches 0:5c4d7b2438d3 217 */
switches 0:5c4d7b2438d3 218
switches 0:5c4d7b2438d3 219 #include "netif/ppp/pppoe.h"
switches 0:5c4d7b2438d3 220
switches 0:5c4d7b2438d3 221 /*
switches 0:5c4d7b2438d3 222 * Create a new PPPoE interface
switches 0:5c4d7b2438d3 223 *
switches 0:5c4d7b2438d3 224 * ppp_netif, netif to use for this PPP link, i.e. PPP IP interface
switches 0:5c4d7b2438d3 225 * ethif, already existing and setup Ethernet interface to use
switches 0:5c4d7b2438d3 226 * service_name, PPPoE service name discriminator (not supported yet)
switches 0:5c4d7b2438d3 227 * concentrator_name, PPPoE concentrator name discriminator (not supported yet)
switches 0:5c4d7b2438d3 228 * status_cb, PPP status callback, called on PPP status change (up, down, …)
switches 0:5c4d7b2438d3 229 * ctx_cb, optional user-provided callback context pointer
switches 0:5c4d7b2438d3 230 */
switches 0:5c4d7b2438d3 231 ppp = pppoe_create(&ppp_netif,
switches 0:5c4d7b2438d3 232 &ethif,
switches 0:5c4d7b2438d3 233 service_name, concentrator_name,
switches 0:5c4d7b2438d3 234 status_cb, ctx_cb);
switches 0:5c4d7b2438d3 235
switches 0:5c4d7b2438d3 236
switches 0:5c4d7b2438d3 237 /*
switches 0:5c4d7b2438d3 238 * Creating a new PPPoL2TP session
switches 0:5c4d7b2438d3 239 * ===============================
switches 0:5c4d7b2438d3 240 */
switches 0:5c4d7b2438d3 241
switches 0:5c4d7b2438d3 242 #include "netif/ppp/pppol2tp.h"
switches 0:5c4d7b2438d3 243
switches 0:5c4d7b2438d3 244 /*
switches 0:5c4d7b2438d3 245 * Create a new PPPoL2TP interface
switches 0:5c4d7b2438d3 246 *
switches 0:5c4d7b2438d3 247 * ppp_netif, netif to use for this PPP link, i.e. PPP IP interface
switches 0:5c4d7b2438d3 248 * netif, optional already existing and setup output netif, necessary if you
switches 0:5c4d7b2438d3 249 * want to set this interface as default route to settle the chicken
switches 0:5c4d7b2438d3 250 * and egg problem with VPN links
switches 0:5c4d7b2438d3 251 * ipaddr, IP to connect to
switches 0:5c4d7b2438d3 252 * port, UDP port to connect to (usually 1701)
switches 0:5c4d7b2438d3 253 * secret, L2TP secret to use
switches 0:5c4d7b2438d3 254 * secret_len, size in bytes of the L2TP secret
switches 0:5c4d7b2438d3 255 * status_cb, PPP status callback, called on PPP status change (up, down, …)
switches 0:5c4d7b2438d3 256 * ctx_cb, optional user-provided callback context pointer
switches 0:5c4d7b2438d3 257 */
switches 0:5c4d7b2438d3 258 ppp = pppol2tp_create(&ppp_netif,
switches 0:5c4d7b2438d3 259 struct netif *netif, ip_addr_t *ipaddr, u16_t port,
switches 0:5c4d7b2438d3 260 u8_t *secret, u8_t secret_len,
switches 0:5c4d7b2438d3 261 ppp_link_status_cb_fn link_status_cb, void *ctx_cb);
switches 0:5c4d7b2438d3 262
switches 0:5c4d7b2438d3 263
switches 0:5c4d7b2438d3 264 /*
switches 0:5c4d7b2438d3 265 * Initiate PPP client connection
switches 0:5c4d7b2438d3 266 * ==============================
switches 0:5c4d7b2438d3 267 */
switches 0:5c4d7b2438d3 268
switches 0:5c4d7b2438d3 269 /* Set this interface as default route */
switches 0:5c4d7b2438d3 270 ppp_set_default(ppp);
switches 0:5c4d7b2438d3 271
switches 0:5c4d7b2438d3 272 /*
switches 0:5c4d7b2438d3 273 * Basic PPP client configuration. Can only be set if PPP session is in the
switches 0:5c4d7b2438d3 274 * dead state (i.e. disconnected). We don't need to provide thread-safe
switches 0:5c4d7b2438d3 275 * equivalents through PPPAPI because those helpers are only changing
switches 0:5c4d7b2438d3 276 * structure members while session is inactive for lwIP core. Configuration
switches 0:5c4d7b2438d3 277 * only need to be done once.
switches 0:5c4d7b2438d3 278 */
switches 0:5c4d7b2438d3 279
switches 0:5c4d7b2438d3 280 /* Ask the peer for up to 2 DNS server addresses. */
switches 0:5c4d7b2438d3 281 ppp_set_usepeerdns(ppp, 1);
switches 0:5c4d7b2438d3 282
switches 0:5c4d7b2438d3 283 /* Auth configuration, this is pretty self-explanatory */
switches 0:5c4d7b2438d3 284 ppp_set_auth(ppp, PPPAUTHTYPE_ANY, "login", "password");
switches 0:5c4d7b2438d3 285
switches 0:5c4d7b2438d3 286 /*
switches 0:5c4d7b2438d3 287 * Initiate PPP negotiation, without waiting (holdoff=0), can only be called
switches 0:5c4d7b2438d3 288 * if PPP session is in the dead state (i.e. disconnected).
switches 0:5c4d7b2438d3 289 */
switches 0:5c4d7b2438d3 290 u16_t holdoff = 0;
switches 0:5c4d7b2438d3 291 ppp_connect(ppp, holdoff);
switches 0:5c4d7b2438d3 292
switches 0:5c4d7b2438d3 293
switches 0:5c4d7b2438d3 294 /*
switches 0:5c4d7b2438d3 295 * Initiate PPP server listener
switches 0:5c4d7b2438d3 296 * ============================
switches 0:5c4d7b2438d3 297 */
switches 0:5c4d7b2438d3 298
switches 0:5c4d7b2438d3 299 /*
switches 0:5c4d7b2438d3 300 * Basic PPP server configuration. Can only be set if PPP session is in the
switches 0:5c4d7b2438d3 301 * dead state (i.e. disconnected). We don't need to provide thread-safe
switches 0:5c4d7b2438d3 302 * equivalents through PPPAPI because those helpers are only changing
switches 0:5c4d7b2438d3 303 * structure members while session is inactive for lwIP core. Configuration
switches 0:5c4d7b2438d3 304 * only need to be done once.
switches 0:5c4d7b2438d3 305 */
switches 0:5c4d7b2438d3 306 ip4_addr_t addr;
switches 0:5c4d7b2438d3 307
switches 0:5c4d7b2438d3 308 /* Set our address */
switches 0:5c4d7b2438d3 309 IP4_ADDR(&addr, 192,168,0,1);
switches 0:5c4d7b2438d3 310 ppp_set_ipcp_ouraddr(ppp, &addr);
switches 0:5c4d7b2438d3 311
switches 0:5c4d7b2438d3 312 /* Set peer(his) address */
switches 0:5c4d7b2438d3 313 IP4_ADDR(&addr, 192,168,0,2);
switches 0:5c4d7b2438d3 314 ppp_set_ipcp_hisaddr(ppp, &addr);
switches 0:5c4d7b2438d3 315
switches 0:5c4d7b2438d3 316 /* Set primary DNS server */
switches 0:5c4d7b2438d3 317 IP4_ADDR(&addr, 192,168,10,20);
switches 0:5c4d7b2438d3 318 ppp_set_ipcp_dnsaddr(ppp, 0, &addr);
switches 0:5c4d7b2438d3 319
switches 0:5c4d7b2438d3 320 /* Set secondary DNS server */
switches 0:5c4d7b2438d3 321 IP4_ADDR(&addr, 192,168,10,21);
switches 0:5c4d7b2438d3 322 ppp_set_ipcp_dnsaddr(ppp, 1, &addr);
switches 0:5c4d7b2438d3 323
switches 0:5c4d7b2438d3 324 /* Auth configuration, this is pretty self-explanatory */
switches 0:5c4d7b2438d3 325 ppp_set_auth(ppp, PPPAUTHTYPE_ANY, "login", "password");
switches 0:5c4d7b2438d3 326
switches 0:5c4d7b2438d3 327 /* Require peer to authenticate */
switches 0:5c4d7b2438d3 328 ppp_set_auth_required(ppp, 1);
switches 0:5c4d7b2438d3 329
switches 0:5c4d7b2438d3 330 /*
switches 0:5c4d7b2438d3 331 * Only for PPPoS, the PPP session should be up and waiting for input.
switches 0:5c4d7b2438d3 332 *
switches 0:5c4d7b2438d3 333 * Note: for PPPoS, ppp_connect() and ppp_listen() are actually the same thing.
switches 0:5c4d7b2438d3 334 * The listen call is meant for future support of PPPoE and PPPoL2TP server
switches 0:5c4d7b2438d3 335 * mode, where we will need to negotiate the incoming PPPoE session or L2TP
switches 0:5c4d7b2438d3 336 * session before initiating PPP itself. We need this call because there is
switches 0:5c4d7b2438d3 337 * two passive modes for PPPoS, ppp_set_passive and ppp_set_silent.
switches 0:5c4d7b2438d3 338 */
switches 0:5c4d7b2438d3 339 ppp_set_silent(pppos, 1);
switches 0:5c4d7b2438d3 340
switches 0:5c4d7b2438d3 341 /*
switches 0:5c4d7b2438d3 342 * Initiate PPP listener (i.e. wait for an incoming connection), can only
switches 0:5c4d7b2438d3 343 * be called if PPP session is in the dead state (i.e. disconnected).
switches 0:5c4d7b2438d3 344 */
switches 0:5c4d7b2438d3 345 ppp_listen(ppp);
switches 0:5c4d7b2438d3 346
switches 0:5c4d7b2438d3 347
switches 0:5c4d7b2438d3 348 /*
switches 0:5c4d7b2438d3 349 * Closing PPP connection
switches 0:5c4d7b2438d3 350 * ======================
switches 0:5c4d7b2438d3 351 */
switches 0:5c4d7b2438d3 352
switches 0:5c4d7b2438d3 353 /*
switches 0:5c4d7b2438d3 354 * Initiate the end of the PPP session, without carrier lost signal
switches 0:5c4d7b2438d3 355 * (nocarrier=0), meaning a clean shutdown of PPP protocols.
switches 0:5c4d7b2438d3 356 * You can call this function at anytime.
switches 0:5c4d7b2438d3 357 */
switches 0:5c4d7b2438d3 358 u8_t nocarrier = 0;
switches 0:5c4d7b2438d3 359 ppp_close(ppp, nocarrier);
switches 0:5c4d7b2438d3 360 /*
switches 0:5c4d7b2438d3 361 * Then you must wait your status_cb() to be called, it may takes from a few
switches 0:5c4d7b2438d3 362 * seconds to several tens of seconds depending on the current PPP state.
switches 0:5c4d7b2438d3 363 */
switches 0:5c4d7b2438d3 364
switches 0:5c4d7b2438d3 365 /*
switches 0:5c4d7b2438d3 366 * Freeing a PPP connection
switches 0:5c4d7b2438d3 367 * ========================
switches 0:5c4d7b2438d3 368 */
switches 0:5c4d7b2438d3 369
switches 0:5c4d7b2438d3 370 /*
switches 0:5c4d7b2438d3 371 * Free the PPP control block, can only be called if PPP session is in the
switches 0:5c4d7b2438d3 372 * dead state (i.e. disconnected). You need to call ppp_close() before.
switches 0:5c4d7b2438d3 373 */
switches 0:5c4d7b2438d3 374 ppp_free(ppp);
switches 0:5c4d7b2438d3 375
switches 0:5c4d7b2438d3 376
switches 0:5c4d7b2438d3 377
switches 0:5c4d7b2438d3 378 3 PPPoS input path (raw API, IRQ safe API, TCPIP API)
switches 0:5c4d7b2438d3 379 =====================================================
switches 0:5c4d7b2438d3 380
switches 0:5c4d7b2438d3 381 Received data on serial port should be sent to lwIP using the pppos_input()
switches 0:5c4d7b2438d3 382 function or the pppos_input_tcpip() function.
switches 0:5c4d7b2438d3 383
switches 0:5c4d7b2438d3 384 If NO_SYS is 1 and if PPP_INPROC_IRQ_SAFE is 0 (the default), pppos_input()
switches 0:5c4d7b2438d3 385 is not IRQ safe and then *MUST* only be called inside your main loop.
switches 0:5c4d7b2438d3 386
switches 0:5c4d7b2438d3 387 Whatever the NO_SYS value, if PPP_INPROC_IRQ_SAFE is 1, pppos_input() is IRQ
switches 0:5c4d7b2438d3 388 safe and can be safely called from an interrupt context, using that is going
switches 0:5c4d7b2438d3 389 to reduce your need of buffer if pppos_input() is called byte after byte in
switches 0:5c4d7b2438d3 390 your rx serial interrupt.
switches 0:5c4d7b2438d3 391
switches 0:5c4d7b2438d3 392 if NO_SYS is 0, the thread safe way outside an interrupt context is to use
switches 0:5c4d7b2438d3 393 the pppos_input_tcpip() function to pass input data to the lwIP core thread
switches 0:5c4d7b2438d3 394 using the TCPIP API. This is thread safe in all cases but you should avoid
switches 0:5c4d7b2438d3 395 passing data byte after byte because it uses heavy locking (mailbox) and it
switches 0:5c4d7b2438d3 396 allocates pbuf, better fill them !
switches 0:5c4d7b2438d3 397
switches 0:5c4d7b2438d3 398 if NO_SYS is 0 and if PPP_INPROC_IRQ_SAFE is 1, you may also use pppos_input()
switches 0:5c4d7b2438d3 399 from an RX thread, however pppos_input() is not thread safe by itself. You can
switches 0:5c4d7b2438d3 400 do that *BUT* you should NEVER call pppos_connect(), pppos_listen() and
switches 0:5c4d7b2438d3 401 ppp_free() if pppos_input() can still be running, doing this is NOT thread safe
switches 0:5c4d7b2438d3 402 at all. Using PPP_INPROC_IRQ_SAFE from an RX thread is discouraged unless you
switches 0:5c4d7b2438d3 403 really know what you are doing, your move ;-)
switches 0:5c4d7b2438d3 404
switches 0:5c4d7b2438d3 405
switches 0:5c4d7b2438d3 406 /*
switches 0:5c4d7b2438d3 407 * Fonction to call for received data
switches 0:5c4d7b2438d3 408 *
switches 0:5c4d7b2438d3 409 * ppp, PPP control block
switches 0:5c4d7b2438d3 410 * buffer, input buffer
switches 0:5c4d7b2438d3 411 * buffer_len, buffer length in bytes
switches 0:5c4d7b2438d3 412 */
switches 0:5c4d7b2438d3 413 void pppos_input(ppp, buffer, buffer_len);
switches 0:5c4d7b2438d3 414
switches 0:5c4d7b2438d3 415 or
switches 0:5c4d7b2438d3 416
switches 0:5c4d7b2438d3 417 void pppos_input_tcpip(ppp, buffer, buffer_len);
switches 0:5c4d7b2438d3 418
switches 0:5c4d7b2438d3 419
switches 0:5c4d7b2438d3 420
switches 0:5c4d7b2438d3 421 4 Thread safe PPP API (PPPAPI)
switches 0:5c4d7b2438d3 422 ==============================
switches 0:5c4d7b2438d3 423
switches 0:5c4d7b2438d3 424 There is a thread safe API for all corresponding ppp_* functions, you have to
switches 0:5c4d7b2438d3 425 enable LWIP_PPP_API in your lwipopts.h file, then see
switches 0:5c4d7b2438d3 426 include/netif/ppp/pppapi.h, this is actually pretty obvious.
switches 0:5c4d7b2438d3 427
switches 0:5c4d7b2438d3 428
switches 0:5c4d7b2438d3 429
switches 0:5c4d7b2438d3 430 5 Notify phase callback (PPP_NOTIFY_PHASE)
switches 0:5c4d7b2438d3 431 ==========================================
switches 0:5c4d7b2438d3 432
switches 0:5c4d7b2438d3 433 Notify phase callback, enabled using the PPP_NOTIFY_PHASE config option, let
switches 0:5c4d7b2438d3 434 you configure a callback that is called on each PPP internal state change.
switches 0:5c4d7b2438d3 435 This is different from the status callback which only warns you about
switches 0:5c4d7b2438d3 436 up(running) and down(dead) events.
switches 0:5c4d7b2438d3 437
switches 0:5c4d7b2438d3 438 Notify phase callback can be used, for example, to set a LED pattern depending
switches 0:5c4d7b2438d3 439 on the current phase of the PPP session. Here is a callback example which
switches 0:5c4d7b2438d3 440 tries to mimic what we usually see on xDSL modems while they are negotiating
switches 0:5c4d7b2438d3 441 the link, which should be self-explanatory:
switches 0:5c4d7b2438d3 442
switches 0:5c4d7b2438d3 443 static void ppp_notify_phase_cb(ppp_pcb *pcb, u8_t phase, void *ctx) {
switches 0:5c4d7b2438d3 444 switch (phase) {
switches 0:5c4d7b2438d3 445
switches 0:5c4d7b2438d3 446 /* Session is down (either permanently or briefly) */
switches 0:5c4d7b2438d3 447 case PPP_PHASE_DEAD:
switches 0:5c4d7b2438d3 448 led_set(PPP_LED, LED_OFF);
switches 0:5c4d7b2438d3 449 break;
switches 0:5c4d7b2438d3 450
switches 0:5c4d7b2438d3 451 /* We are between two sessions */
switches 0:5c4d7b2438d3 452 case PPP_PHASE_HOLDOFF:
switches 0:5c4d7b2438d3 453 led_set(PPP_LED, LED_SLOW_BLINK);
switches 0:5c4d7b2438d3 454 break;
switches 0:5c4d7b2438d3 455
switches 0:5c4d7b2438d3 456 /* Session just started */
switches 0:5c4d7b2438d3 457 case PPP_PHASE_INITIALIZE:
switches 0:5c4d7b2438d3 458 led_set(PPP_LED, LED_FAST_BLINK);
switches 0:5c4d7b2438d3 459 break;
switches 0:5c4d7b2438d3 460
switches 0:5c4d7b2438d3 461 /* Session is running */
switches 0:5c4d7b2438d3 462 case PPP_PHASE_RUNNING:
switches 0:5c4d7b2438d3 463 led_set(PPP_LED, LED_ON);
switches 0:5c4d7b2438d3 464 break;
switches 0:5c4d7b2438d3 465
switches 0:5c4d7b2438d3 466 default:
switches 0:5c4d7b2438d3 467 break;
switches 0:5c4d7b2438d3 468 }
switches 0:5c4d7b2438d3 469 }
switches 0:5c4d7b2438d3 470
switches 0:5c4d7b2438d3 471
switches 0:5c4d7b2438d3 472
switches 0:5c4d7b2438d3 473 6 Upgrading from lwIP <= 1.4.x to lwIP >= 2.0.x
switches 0:5c4d7b2438d3 474 ===============================================
switches 0:5c4d7b2438d3 475
switches 0:5c4d7b2438d3 476 PPP API was fully reworked between 1.4.x and 2.0.x releases. However porting
switches 0:5c4d7b2438d3 477 from previous lwIP version is pretty easy:
switches 0:5c4d7b2438d3 478
switches 0:5c4d7b2438d3 479 * Previous PPP API used an integer to identify PPP sessions, we are now
switches 0:5c4d7b2438d3 480 using ppp_pcb* control block, therefore all functions changed from "int ppp"
switches 0:5c4d7b2438d3 481 to "ppp_pcb *ppp"
switches 0:5c4d7b2438d3 482
switches 0:5c4d7b2438d3 483 * struct netif was moved outside the PPP structure, you have to provide a netif
switches 0:5c4d7b2438d3 484 for PPP interface in pppoX_create() functions
switches 0:5c4d7b2438d3 485
switches 0:5c4d7b2438d3 486 * PPP session are not started automatically after you created them anymore,
switches 0:5c4d7b2438d3 487 you have to call ppp_connect(), this way you can configure the session before
switches 0:5c4d7b2438d3 488 starting it.
switches 0:5c4d7b2438d3 489
switches 0:5c4d7b2438d3 490 * Previous PPP API used CamelCase, we are now using snake_case.
switches 0:5c4d7b2438d3 491
switches 0:5c4d7b2438d3 492 * Previous PPP API mixed PPPoS and PPPoE calls, this isn't the case anymore,
switches 0:5c4d7b2438d3 493 PPPoS functions are now prefixed pppos_ and PPPoE functions are now prefixed
switches 0:5c4d7b2438d3 494 pppoe_, common functions are now prefixed ppp_.
switches 0:5c4d7b2438d3 495
switches 0:5c4d7b2438d3 496 * New PPPERR_ error codes added, check you have all of them in your status
switches 0:5c4d7b2438d3 497 callback function
switches 0:5c4d7b2438d3 498
switches 0:5c4d7b2438d3 499 * Only the following include files should now be used in user application:
switches 0:5c4d7b2438d3 500 #include "netif/ppp/pppapi.h"
switches 0:5c4d7b2438d3 501 #include "netif/ppp/pppos.h"
switches 0:5c4d7b2438d3 502 #include "netif/ppp/pppoe.h"
switches 0:5c4d7b2438d3 503 #include "netif/ppp/pppol2tp.h"
switches 0:5c4d7b2438d3 504
switches 0:5c4d7b2438d3 505 Functions from ppp.h can be used, but you don't need to include this header
switches 0:5c4d7b2438d3 506 file as it is already included by above header files.
switches 0:5c4d7b2438d3 507
switches 0:5c4d7b2438d3 508 * PPP_INPROC_OWNTHREAD was broken by design and was removed, you have to create
switches 0:5c4d7b2438d3 509 your own serial rx thread
switches 0:5c4d7b2438d3 510
switches 0:5c4d7b2438d3 511 * PPP_INPROC_MULTITHREADED option was misnamed and confusing and was renamed
switches 0:5c4d7b2438d3 512 PPP_INPROC_IRQ_SAFE, please read the "PPPoS input path" documentation above
switches 0:5c4d7b2438d3 513 because you might have been fooled by that
switches 0:5c4d7b2438d3 514
switches 0:5c4d7b2438d3 515 * If you used tcpip_callback_with_block() on ppp_ functions you may wish to use
switches 0:5c4d7b2438d3 516 the PPPAPI API instead.
switches 0:5c4d7b2438d3 517
switches 0:5c4d7b2438d3 518 * ppp_sighup and ppp_close functions were merged using an optional argument
switches 0:5c4d7b2438d3 519 "nocarrier" on ppp_close.
switches 0:5c4d7b2438d3 520
switches 0:5c4d7b2438d3 521 * DNS servers are now only remotely asked if LWIP_DNS is set and if
switches 0:5c4d7b2438d3 522 ppp_set_usepeerdns() is set to true, they are now automatically registered
switches 0:5c4d7b2438d3 523 using the dns_setserver() function so you don't need to do that in the PPP
switches 0:5c4d7b2438d3 524 callback anymore.
switches 0:5c4d7b2438d3 525
switches 0:5c4d7b2438d3 526 * PPPoS does not use the SIO API anymore, as such it now requires a serial
switches 0:5c4d7b2438d3 527 output callback in place of sio_write
switches 0:5c4d7b2438d3 528
switches 0:5c4d7b2438d3 529 * PPP_MAXIDLEFLAG is now in ms instead of jiffies