PREV NEXT INDEX



12. PPP Driver

The PPP packet driver is a set of libraries in Dynamic C that allows the user to establish a PPP (Point-to-Point Protocol) link over a full-duplex serial line between a Rabbit-based controller and another system that supports PPP.

A common use of the PPP protocol is the transfer of IP packets between a remote host and an Internet Service Provider (ISP) over a modem connection. The PPP packet driver supports the transfer of Internet Protocol (IP) data and is compatible with all TCP/IP libraries for the Rabbit.

The PPP packet driver was derived from source code originally written by Darby Corporate Solutions (DCS).

12.1 PPP Libraries

The PPP driver is in two library files.

PPPLINK.LIB contains:

PPP.LIB contains:

A third library, MODEM.LIB, contains functions for controlling an external modem through a full RS232 link.

12.2 Operation Details

The first step is to configure whatever transport medium will be used for the PPP connection. For directly connecting a serial line to the peer, the two serial data lines TX and RX may be adequate. The most common situation, however, will be some sort of modem.

12.2.1 The Modem Interface

The interface between a modem and a controller is either a true RS232 interface or a variation on RS232 that uses TTL voltage levels for all of the signals. The latter are used by board-mounted modem modules. If an external modem is used, an RS232 transceiver chip is needed to convert RS232 voltages to logic signals and vice versa. A full RS232 connection has 3 outputs and 5 inputs from the controllers point of view. In RS232 terminology, the controller is referred to as the DTE (Data Terminal Equipment). Modems and other peripherals are referred to as DCE's (Data Communications Equipment).

The specifics of a dial-up PPP connection are dependant on the modem hardware and the ISP.

12.2.1.1 Rabbit Pin Connections to Modem

The modem control library, MODEM.LIB, defines default connections to the Rabbit as follows:

RS232 Signal Rabbit Pin Direction
DTR
PB6
out
RTS
PB7
out
CTS
PB0
in
DCD
PB2
in
RI
PB3
in
DSR
PB4
in
TD
PC2
out
RD
PC3
in

12.2.2 Flow Control

Hardware flow control is implemented for the Rabbit PPP system. It follows the RS232 convention of using Ready To Send (RTS) and Clear To Send (CTS) lines. Flow control is usually required for baud rates above 9600. Flow control can be enabled or disabled by PPPflowcontrolOn()and PPPflowcontrolOff(), respectively. Flow control is off by default.

12.2.3 Serial Port C

By default the PPP link is established using serial port C. It can be changed, but it requires some #define changes near the top of PPPLINK.LIB in the section starting with PPP_SERDR. If a modem is used, some rewriting of MODEM.LIB is also required.

12.3 Software Implementation Overview

The first stage in dial-up PPP is to establish a modem connection with the ISP. The function ModemInit() opens the serial port, then detects if there is a modem connected and ready. It does this by sending "AT" to the modem a set number of times until it receives an "OK" response. This should work with any Hayes-compatible modem, which is the standard today. At this point the modem is ready and commands can be sent to it using ModemSend(). Remember to include a carriage return "\r" at the end of each command sent.

The function ModemExpect() is used to wait for a character sequence to occur. Normally the first use of this in a program is to determine that the modem has connected. When a connection occurs, the modem will send a string along the lines of "CONNECT AT x" or something similar. ModemExpect() can be set to listen for this. Once connected, the ISP may either attempt PPP negotiation immediately, or request a user name and password first. In the latter case, a sequence of ModemSend() and ModemExpect() calls are used to handle this (see See "Authentication Sequence" on page 304).

Eventually the ISP will begin PPP negotiation. At this stage ModemClose() should be called to shutdown normal serial operation. After calling sock_init() and doing any other necessary TCP/IP initialization, PPPinit() is called, followed by any necessary PPP option initialization, and finally a call to PPPstart().

Once the PPP connection is established through a successful call to PPPstart(), the user can send packets to the peer using the TCP/IP libraries.

12.3.1 Defining Network Parameters

The following parameters must be defined at compile time:


// Sets the TCP/IP stack to use PPP. This should be "pppoe.lib" when using PPP over Ethernet.
#define PKTDRV "ppp.lib"

// In the most common case, the Rabbit will be dialing into an ISP. The ISP will usually wish to
// assign the IP address. Setting the IP address to 0.0.0.0 indicates that the Rabbit does not have a
// valid address when started. If the Rabbit has a permanent address or will be dialed into,
// MY_IP_ADDRESS should be set to a proper IP address.
#define MY_IP_ADDRESS "0.0.0.0"

// This is a parameter intended for Ethernet and other shared network schemes. Since PPP is a 
// single point-to-point link, all traffic must be routed through a peer. There is no such thing as
// "local" traffic. A netmask of 255.255.255.255 causes all addresses to be routed to.
#define MY_NETMASK "255.255.255.255"

// This is the address of the host that will perform routing for the Rabbit. (With PPP this is always
// the peer.) If the ISP assigns a gateway machine to use, then define MY_GATEWAY to that. If the
// gateway is not known, defining PPP_PEERROUTE will make a gateway out of whatever
// machine you connect to, i.e. the Rabbit will use whatever address the peer uses when identifying
// itself during PPP negotiation. PPP_PEERROUTE will work under most circumstances, but a
// static gateway address may be needed for special cases.
#define MY_GATEWAY "10.1.1.1"

// This works the same as with Ethernet: it defines a host that will resolve names into IP addresses.
#define MY_NAMESERVER "10.1.1.2"

12.3.1.1 IP Addresses

When the Rabbit and the peer are establishing a connection, they negotiate what their IP addresses will be. When the Rabbit is connecting to an ISP, an IP address will be assigned to it by the ISP. In some cases, such as the Rabbit acting as a dial-in ISP, IP addresses for the Rabbit and the peer should be set by the Rabbit. This is done using PPPnegotiateIP().

12.3.2 Configuration Options

The following configuration options are supported by the Rabbit PPP system:
Table 3. Configuration Options
LCP Configuration Option Type Field Meaning of Option Type
01 MRU (Maximum-Receive-Unit)
02 ACCM (Async-Control-Character-Map)
03 Auth (Authentication-Type): PAP only
05 Magic Number
07 PFC (Protocol-Field-Compression)
08 ACFC (Address-and-Control-Field-Compression)

For more information on these options, refer to RFC 1661: The Point-to-Point Protocol (PPP) at:


 http://rfc.asuka.net/rfc/rfc1661.html

12.3.3 Authentication

The PPP library supports an optional authentication phase. Both the authentication of a peer and being authenticated by a peer are done using Password Authentication Protocol (PAP). This is a simple two-way handshake only done upon initial link establishment.

The most common case is when the Rabbit must authenticate itself to the ISP it is connecting to. This is configured using PPPsetAuthenticatee(), which sets the username and password the Rabbit will use.

A different situation arises when the Rabbit needs to authenticate a connecting peer. This is necessary when the Rabbit is being dialed into. PPPsetAuthenticator() sets a name and password that will be required from the peer before a connection will be established.

12.3.3.1 Authentication Sequence

A common situation with dial-up PPP is that an ISP will want to authenticate the dialer before PPP negotiation. There are no real standards for doing this, so each ISP is potentially different. The best way to develop a correct sequence of ModemSend() and ModemExpect() commands is to connect to the ISP using a terminal program on a PC. You can then take note of the necessary sequence to start PPP negotiation.

Here is a hypothetical session as seen by a terminal program. Characters typed in and sent to the ISP or the modem are displayed in bold.

AT
OK
ATDT5554545
OK
CONNECT 28800
Welcome to someisp.com
Login?
rabbit
Password:Ilikecarrots
Logging in as rabbit
Start PPP $*($}}}}}$}$#$#${@#>>}}FF}}$}

From this session we could use ModemSend() and ModemExpect() to create a dial-up function like this:


int myDialUp(){
if(ModemOpen(57600) == 0){
return 0;
}
if(ModemInit() == 0){
return 0;
}
ModemSend("ATDT5554545\r");
if (ModemExpect("OK", 2000) == 0)){
return 0; //something is wrong with the modem
}
if(ModemExpect("CONNECT", 30000) == 0){
return 0; //didn't connect to the ISP
}
if(ModemExpect("Login?", 5000) == 0){
return 0;
}
ModemSend("rabbit\r");
if(ModemExpect("word:", 5000) == 0){
return 0;
}
ModemSend("Ilikecarrots\r");
if(ModemExpect("PPP", 5000) == 0){
return 0; //probably a failed login
}
ModemClose();
sock_init();
PPPinit(57600);
PPPflowcontrolOn();
return 1; //all done
}

As you can see, ModemExpect() will pick up any part of the received string. Clever use of this allows the initialization to be fairly generic, but subtle differences between ISP's will often require customized sequences such as this.

12.3.4 Link Teardown

Tearing down the link must also be done in stages. First, a terminate request must be sent to the peer. This is done with PPPshutdown(). PPPshutdown() will return once an acknowledgement has been sent by the peer, or after a time out period. This is followed by a call to PPPclose, which unloads the PPP serial driver. If the connection is via a modem, the modem must then be hung up. First the regular serial driver is reopened with ModemOpen(). ModemHangup() sends the hang up and reset commands to the modem. Finally, a call to ModemClose() shuts down the serial driver.

12.4 Functions

This section describes the functions that compose the PPP driver and the functions for modem control.

Using Cofunctions

Establishing a PPP connection over a modem is time-consuming. Depending on the baud rate negotiated by the modem, the whole process can take 30 seconds or more. Much of this time is spent by the controller waiting for a response from the other end. In a practical application, where the controller has other tasks to perform, this may be unacceptable. For this, there are cofunction versions of all of the functions that wait for responses from the peer. There are still parts of the initialization process that create delays, but the effect is much smaller.


CofModemExpect



int CofModemExpect(char *send_string, unsigned long timeout);

Description

Listens for a specific string to be sent by the modem. Yields to other tasks while waiting for input.

Parameters

send_string

A NULL-terminated string to listen for.

timeout

Maximum wait in milliseconds for a character.

Return value

1: The expected string was received.
0: A timeout occurred before receiving the string.

Library

MODEM.LIB


CofModemHangup



int CofModemHangup();

Description

Sends "ATH" and "ATZ" commands. Yields to other tasks while waiting for responses.

Return value

1: Success
0: Modem not responding

Library

MODEM.LIB


CofModemInit



int CofModemInit();

Description

Resets modem with AT, ATZ commands. Yields to other tasks while waiting for responses.

Return value

1: Success
0: Modem not responding

Library

MODEM.LIB


CofModemSend



void CofModemSend(char *send_string);

Description

Sends a string to the modem. Yields to other tasks while sending.

Parameters

send_string

A NULL-terminated string to be sent to the modem.

Library

MODEM.LIB


CofPPPshutdown



int CofPPPshutdown(unsigned long timeout);

Description

Sends a Link Terminate Request packet. Waits for the link to be torn down.

Parameters

timeout

Number of milliseconds to wait before giving up on a response from the peer. Yields to other tasks while waiting.

Return value

1:Shutdown succeeded
0: Shutdown timed out

Library


PPP.LIB

CofPPPstart



int CofPPPstart(unsigned long timeout, int retry);

Description

Starts link negotiation process with a connected peer. Yields to other tasks.

Parameters

timeout

The number of milliseconds to wait between phases of negotiation before starting over.

retry

Number of times to retry the connection

Return value

1: Negotiation succeeded;
0: A link could not be negotiated.

Library

PPP.LIB


ModemClose



void ModemClose();

Description

Closes the serial driver down.

Library

MODEM.LIB


ModemConnected



int ModemConnected();

Description

Returns true if the DCD line is asserted, meaning the modem is connected to a remote carrier.

Return value

1: DCD line is active
0: DCD inactive (nothing connected)

Library

MODEM.LIB


ModemExpect



int ModemExpect(char *send_string, unsigned long timeout);

Description

Listens for a specific string to be sent by the modem.

Parameters

send_string

A NULL-terminated string to listen for.

timeout

Maximum wait in milliseconds for a character

Return value

1: The expected string was received
0: A timeout occurred before receiving the string

Library

MODEM.LIB


ModemHangup



int ModemHangup();

Description

Sends "ATH" and "ATZ" commands

Return value

1: Success
0: Modem not responding

Library

MODEM.LIB


ModemInit



int ModemInit();

Description

Resets modem with AT, ATZ commands.

Return value

1: Success
0: Modem not responding

Library

MODEM.LIB


ModemOpen



int ModemOpen(unsigned long baud);

Description

Starts up communication with an external modem.

Parameters

baud

The baud rate for communicating with the modem.

Return value

1: External modem detected
0: Not connected to external modem

Library

MODEM.LIB


ModemReady



int ModemReady();

Description

Returns true if the DSR line is asserted.

Return value

1: DSR line is active
0: DSR inactive (nothing connected)

Library

MODEM.LIB


ModemRinging



int ModemRinging();

Description

Returns true if the RI line is asserted, meaning that the line is ringing.

Return value

1: RI line is active
0: RI inactive (nothing connected)

Library

MODEM.LIB


ModemSend



void ModemSend(char *send_string);

Description

Sends a string to the modem.

Parameters

send_string

A NULL-terminated string to be sent to the modem.

Library

MODEM.LIB


ModemStartPPP



void ModemStartPPP();

Description

Hands control of the serial line over to the PPP driver.

Library

MODEM.LIB


PPPclose



void PPPclose();

Description

Closes the serial port and unloads the PPP interrupt service routine.

Library

PPPLINK.LIB


PPPinit



void PPPinit(unsigned long baud)

Description

Initializes the PPP driver, sets parameters. Must be called immediately following a call to sock_init().

Parameters

baud

The baud rate of the serial port PPP is running on (port C by default).

Library

PPP.LIB


PPPflowcontrolOff



void PPPflowcontrolOff()

Description

Deactivates hardware flow control for the serial link.

Library

PPPLINK.LIB


PPPflowcontrolOn



void PPPflowcontrolOn()

Description

Activates hardware flow control for the serial link. The pins used for flow control are defined in PPPLINK.LIB as follows:

PPP_CTSPORT: the port address for the CTS input line.
PPP_CTSPIN: the pin number of the CTS input line.
PPP_RTSPORT: the port address of the RTS output line.
PPP_RTSSHADOW: the name of the port's shadow register.
PPP_RTSPIN: the pin number of the RTS output line.

Library

PPPLINK.LIB


PPPstart



int PPPstart(unsigned long timeout, int retry);

Description

Starts link negotiation process with a connected peer.

Parameters

timeout

Number of milliseconds to wait between phases of negotiation before starting over.

retry

Number of times to retry the connection.

Return value

1: Negotiation succeeded;
0: A link could not be negotiated.

Library

PPP.LIB


PPPnegotiateIP



void PPPnegotiateIP(unsigned long local_ip, unsigned long remote_ip);

Description

Sets PPP driver to negotiate IP addresses for itself and the remote peer. Otherwise, the system will rely on the remote peer to set addresses.

Parameters

local_ip

IP number to use for this PPP connection.

remote_ip

IP number that the remote peer should be set to.

Library

PPP.LIB


PPPnegotiateDNS



void PPPnegotiateDNS(unsigned long dns_ip);

Description

Sets PPP driver to configure a DNS address for the remote peer.

Parameters

dns_ip

IP number for the DNS server

Library

PPP.LIB


PPPsetAuthenticatee



void PPPsetAuthenticatee(char *username, char *password);

Description

Sets the driver up to send a PAP authentication message to a peer when requested.

Parameters

username

The username to send to the peer. The argument string is not copied, so the argument string must stay constant.

password

The password to send to the peer. The argument string is not copied, so the argument string must stay constant

Library

PPP.LIB


PPPsetAuthenticator



void PPPsetAuthenticator(char *username, char *password);

Description

Sets the driver up to require a PAP authentication message from a peer. Negotiation will fail unless the peer sends the specified username/password pair. This function is generally used when the Rabbit is acting as a dial-in server.

Parameters

username

The user name that the peer must match for the link to proceed.

password

The password that the peer must match for the link to proceed.

Library

PPP.LIB


PPPshutdown



int PPPshutdown(unsigned long timeout);

Description

Sends a Link Terminate Request packet. Waits for link to be torn down.

Parameters

timeout

Number of milliseconds to wait before giving up on a response from the peer.

Return value

1: Shutdown succeeded
0: Shutdown timed out

Library

PPP.LIB


ResetPPP



void ResetPPP( );

Description

Under normal operations, this function will not be needed; the modem control functions make it unnecessary. There are, however, conditions that may make it useful.

Library

PPP.LIB


Z-World
http://www.zworld.com
Voice: 530.757.3737
Fax: 530.757.3792 or 530.753.5141
sales@zworld.com
PREV NEXT INDEX