Setting up PPP
This paper provides helpful information about how to get started with Ethernut's PPP.
PPP, the Point to Point Protocol can be used to encapsulate IP and other packets on a serial link. As its name implies, the link is established between two points only. The initiator is called the PPP client, which connects to the PPP server on the other end of the line. The current Ethernut implementation supports the client mode only. Thus, Ethernut can actively call another party, but is not able to answer incoming calls. However, as soon as a PPP session has been established, either party may run TCP or UDP servers or clients.
PPP is a complex protocol with many parameters. Unlike Ethernet connections, several steps are required to establish a session.
Hardware
Device Initialization
First of all the serial interface has to be initialized. On Nut/OS an UART is used and must be registered.
NutRegisterDevice(&devAhdlc0, 0, 0);
Nut/OS implements PPP itself as a device. Thus, the application has to register it as well.
NutRegisterDevice(&devPpp, 0, 0);
pppcom = _open("ppp:uart0/user/passwd", _O_RDWR | _O_BINARY);uart0.
If there is a new driver at any later time, you only need to change
the line containing NutRegisterDevice().
The next part must contain the user's name, followed by the corresponding password. If your provider doesn't require authentication, you can simply leave them out. Remember, that PPP can be used for dialing into remote hosts over a public telephone network. That's why some login information is typically required. Do not mixup login with PPP authentication. User logins, which are rarely required, can be handled by NutChat() before PPP is actually activated. We will soon discuss this function. PPP authentication on the other hand is part of the negotiation between the PPP client (Ethernut) and the PPP server (ISP). This negotiation will later run automatically in the background and is out of our control. Thus we need to provide this information before the negotiation actually starts.
If the open call for the PPP device succeeds, it returns a handle for this device, which can be used to set the baudrate. For this kind of special device functions, Nut/OS offers the ioctl() routine.
u_long lctl = 38400; _ioctl(pppcom, UART_SETSPEED, &lctl);
Up to this point, nothing has been transmitted. Both, the UART and the PPP device just sit there, waiting for data to be transmitted or received.
Dialing Out
PPP can be used with many different serial hardware. The most simple is a direct serial cable. However, most systems will use a modem connected to a telephone line or a GPRS modem. Let's try a simple modem first.
We use the US Robotics Courier Dual Standard V34+, a quite old part, but still useful. You can use almost any model, preferable one with Hayes compatible command set.
After initialization ur PPP interface is still inactive and the UART device can be used in a normal fashion, sending and receiving single characters. This way we can talk to the modem, sending Hayes commands and receiving responses.
Fortunately Nut/OS offers the NutChat() routine, which executes a simple chat script and returns its result. In general, chat scripts are made of one or more pairs of strings. The first part of such a pair is the string, that is expected and the second part is the one to be sent. A simple chat script looks like this
"'' AT OK ATD555 CONNECT"
CONNECT 38400/ARQIt is not unusual, that the modem will respond with a different string, like BUSY if it detects, that the dialed number is occupied. NutChat() offers a variety of functions to handle such situations. Here is a more advanced example
"TIMEOUT 10 ABORT BUSY ABORT 'NO CARRIER' '' ATZ OK ATDT555 CONNECT"You may have noted the hyphens with 'NO CARRIER'. These are required to make this a single string within the script.
Finally the keyword REPORT may be used to store the last modem response in a buffer, which can be accessed through the global u_char pointer chat_report after NutChat() returned. This is quite useful to check the complete connection string returned by the modem.
Modems are picky devices and NutChat() allows to use special characters to further control them.
\b Backspace character
\c Suppresses carriage return at the end of a send string
\d Delay 1 second
\n Line feed character
\N Null character
\p Delay 100 milliseconds
\r Carriage return character
\s Space character
\t Tab character
\\ Backslash character
\DDD Character DDD, where DDD are up to three octal digitsIt's likely, that you need to consult your modem's manual to find out more. It is also a good idea to try the modem commands with your PC and a terminal emulator first.
Network Interface Setup
As soon as the modem connection is active, the application needs
to configure the PPP network device.
rc = NutNetIfConfig("ppp", 0, 0, 0);PPP adds four layers to the Ethernut TCP/IP stack.
HDLC PPP in HDLC-like Framing (RFC 1662)
LCP PPP LCP Extensions (RFC 1570)
PAP PPP Authentication Protocols (RFC 1334)
IPCP Internet Protocol Control Protocol (RFC 1332)As stated above, the PPP interface is still inactive after its initialization and even after the PPP device has been opened. However, opening the PPP device initialized the states of all PPP layers. Opening the PPP device puts both, the IPCP and the LCP layer in the STARTING mode. In this mode, the layers will neither accept any input nor generate any output.
When the application calls NutNetIfConfig(), the RS232 interface will be handed over to the HDLC layer. When this happens, all transmitted data is packed into HDLC frames and all received data is expected to be packed in HDLC frames. In addition, the HDLC layer will report to the LCP layer, that it is up and running.
As soon as the LCP layer is informed, that the lower layer is up, it will send out a request through the HDLC layer. Assuming, that the modem is still connected, this request will be packed into a HDLC frame and send via modem to the remote. The remote's stack works in the same way and consequently sends out an LCP request. In simple words, more or less at the same time both sides will receive a LCP request.
The HDLC layer passes incoming LCP telegrams to the LCP layer by calling NutLcpInput(). The LCP request telegram contains a list of options, which the other side prefers to use during the upcoming session. Valid options are the maximum number of bytes in a single telegram or the type of authentication. Each side will now make up its mind about this request and either accept, not accept or reject the requested options. The difference between not accepting an option and rejecting it is as follows: A rejected option is not negotiable, which means, that the responding side simply doesn't provide it. An option is not accepted, if the other side is generally able to provide this function, but not in the requested way. As an example, a node may provide authentication, but not the type of authentication requested by the remote. The server may request CHAP authentication, but the client is only able to provide PAP authentication.
If a requested option is declined, the requester will decide, wether it makes sense to further continue. Thus, the requester may not allow any other authentication than CHAP. If the remote doesn't accept this, it will send a LCP termination request to shut down the conversation. As long as unacknowledged options are negotiable, both sides continue to send requests and responses.
When finally all options had been accepted by both sides, LCP will send a LOWER UP report to the IPCP layer, or, if any authentication has been negotiated, initiate the authentication protocol. At the time of this writing, Ethernut supports PAP only. The bad thing about PAP is, that passwords are not encrypted when passed to the remote. Allthough telephone lines are considered safe, some hosts may not accept authentication without encryption.
If authentication fails due to wrong passwords or illegal user names, the authentication layer will inform the IPCP layer, that the lower layer is down. And step by step all layers go down and finally disable the HDLC driver.
If authentication succeeds, the IPCP layer will be informed, that its lower layer is up and IPCP starts negotiating in a similar way as LCP did before. Of course, IPCP negotiates different options, mainly IP addresses. If the application called NutNetIfConfig() with IP address set to zero, Ethernut will accept any local IP address for its PPP network interface.
Hanging Up
Terminating a session is not as easy as it might look first. The host, that wants to terminate a session sends an LCP TERM request, waits a few seconds for a LCP TERM acknowledge and shuts down all layers. If the host receives a LCP TERM request, it responds with a LCP TERM acknowledge and shuts down all layers.
The problem that remains is the modem connection. The modems are not PPP aware. They simply transport any kind of binary data from one end to the other. Assuming that the other side hangs up reilable, we may not bother about the Ethernut modem. If the other side hangs up, our modem will recognize this and hangs up too. But at least this is no fair play.
One solution would be to use the idle timeout, which most modems support. If no traffic is generated within a specified time, the modem will automatically hang up. As you can imagine, this method is not really reliable and additionally causes the connection to stay alive longer than neccessary.
Most Hayes compatible modems offer escape sequence detection. If they receive three consecutive + characters, they will change back to command mode. So we can send the ATH command to hang up. Again, this is unreliable too. Practice shows, that the detection of +++ works quite seldom.
The solution is, using a hardware handshake line. Usually DTR is used for this purpose. The Ethernut Board does not provide DTR, but RTS. Either the modem can be configured to drop the connection on RTS or we need a special adapter cable to route the RTS output on the Ethernut board to the DTR input of the Modem.
PPP Debugging
As stated above, most problems arise during NutNetIfConfig(), when the PPP session is established. Fortunately Nut/OS offers some debug capabilities to track down these problems.
To save code and data space, debugging is not build in by default. It requires to rebuild the libraries with debug code included.
Nut/OS debug output goes to a serial RS232 interface. As we used the standard UART to connect the modem, we need a second one. If your Ethernut is still ATmega103 based, you got a real problem here, because this chip has a single UART only. You need to attach an external UART and rewrite the debug device driver or replace the ATmega103 with an ATmega128. It is clear, that this will be a project of its own.
For Ethernut 1.3 the second UART is available at the expansion port, but you still need some additional hardware, because these signals are TTL level and needs to be shifted to RS232 levels.
As a lucky owner of Ethernut 2.0, you can use jumper JP to route both UARTs to the DB-9 connector.
You still need a special adapter cable to distribute receive and transmit lines of both UARTs to two separate DB-9 connectors, but this is done in a few minutes and doesn't require more than basic soldering skills.
Using GPRS
Using the mobile telephone network doesn't differ much from using standard telephone lines and modems. In fact, the GPRS devices, that are, for example, build into modern mobile phones, act like Hayes compatible modems. Even better, because the GPRS command set is much more standardized.
Related RFCs
RFC 1332
The PPP Internet Protocol Control Protocol (IPCP)
RFC 1377
The PPP OSI Network Layer Control Protocol (OSINLCP)
RFC 1378
The PPP AppleTalk Control Protocol (ATCP)
RFC 1471
The Definitions of Managed Objects for the Link Control Protocol of the
Point-to-Point Protocol
RFC 1472
The Definitions of Managed Objects for the Security Protocols of the
Point-to-Point Protocol
RFC 1473
The Definitions of Managed Objects for the IP Network Control Protocol of the
Point-to-Point Protocol
RFC 1474
The Definitions of Managed Objects for the Bridge Network Control Protocol of
the Point-to-Point Protocol
RFC 1547
Requirements for an Internet Standard Point-to-Point Protocol
RFC 1552
The PPP Internetwork Packet Exchange Control Protocol (IPXCP)
RFC 1553
Compressing IPX Headers Over WAN Media (CIPX)
RFC 1570
PPP LCP Extensions
RFC 1598
PPP in X.25
RFC 1618
PPP over ISDN
RFC 1661
The Point-to-Point Protocol (PPP)
RFC 1662
PPP in HDLC-like Framing
RFC 1663
PPP Reliable Transmission
RFC 1762
The PPP DECnet Phase IV Control Protocol (DNCP)
RFC 1763
The PPP Banyan Vines Control Protocol (BVCP)
RFC 1764
The PPP XNS IDP Control Protocol (XNSCP)
RFC 1962
The PPP Compression Control Protocol (CCP)
RFC 1963
PPP Serial Data Transport Protocol (SDTP)
RFC 1967
PPP LZS-DCP Compression Protocol (LZS-DCP)
RFC 1968
The PPP Encryption Control Protocol (ECP)
RFC 1973
PPP in Frame Relay
RFC 1974
PPP Stac LZS Compression Protocol
RFC 1975
PPP Magnalink Variable Resource Compression
RFC 1976
PPP for Data Compression in Data Circuit-Terminating Equipment (DCE)
RFC 1977
PPP BSD Compression Protocol
RFC 1978
PPP Predictor Compression Protocol
RFC 1979
PPP Deflate Protocol
RFC 1989
PPP Link Quality Monitoring
RFC 1990
The PPP Multilink Protocol (MP)
RFC 1993
PPP Gandalf FZA Compression Protocol
RFC 1994
PPP Challenge Handshake Authentication Protocol (CHAP)
RFC 2043
The PPP SNA Control Protocol (SNACP)
RFC 2097
The PPP NetBIOS Frames Control Protocol (NBFCP)
RFC 2118
Microsoft Point-To-Point Compression (MPPC) Protocol
RFC 2125
The PPP Bandwidth Allocation Protocol (BAP) The PPP Bandwidth Allocation
Control Protocol (BACP)
RFC 2153
PPP Vendor Extensions
RFC 2284
PPP Extensible Authentication Protocol (EAP)
RFC 2363
PPP Over FUNI
RFC 2364
PPP over AAL5
RFC 2419
The PPP DES Encryption Protocol, Version 2 (DESE-bis)
RFC 2420
The PPP Triple-DES Encryption Protocol (3DESE)
RFC 2433
Microsoft PPP CHAP Extensions
RFC 2484
PPP LCP Internationalization Configuration Option
RFC 2615
PPP over SONET/SDH
RFC 2661
Layer Two Tunneling Protocol 'L2TP'
RFC 2701
Multi-link Multi-node PPP
RFC 2716
PPP EAP TLS Authentication Protocol
RFC 2759
Microsoft PPP CHAP Extensions, Version 2
RFC 2823
PPP over Simple Data Link (SDL) using SONET/SDH with ATM-like framing
RFC 3078
Microsoft Point-To-Point Encryption (MPPE) Protocol
RFC 3153
PPP Multiplexed
RFC 3255
Extending PPP over SONET/SDH, with virtual concatenation, high order and low
order payloads
RFC 3336
PPP over Asynchronous Transfer Mode Adaptation Layer 2
RFC 3518
Point-to-Point Protocol (PPP) Bridging Control Protocol (BCP)
