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