mbed-os

Fork of mbed-os by erkin yucel

Committer:
elessair
Date:
Sun Oct 23 15:10:02 2016 +0000
Revision:
0:f269e3021894
Initial commit

Who changed what in which revision?

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