TCPIP

TCP/IP

Serial communication is sufficient for point-to-point transmission of data, but the physical constraints imposed, and the relative slowness of the transport, prohibits its use for multipoint communication. Networking technologies support communication between multiple devices and employ an addressing mechanism for identification of each machine. Very fast speeds can be achieved through the use of mediums such as Ethernet.

The most common network protocol suite is TCP / IP , which consists of several protocols over two layers . At the network layer, the Internet Protocol ( IP ) and Internet Control Message Protocol ( ICMP ) protocols are employed, while at the transport layer, Transmission Control Protocol ( TCP ) and User Datagram Protocol ( UDP ) operate .

UDP is an unreliable protocol that provides a datagram (connectionless) service and is suited to simple query and response applications. TCP is reliable and provides stream-oriented connections using data packet sequence numbers to coordinate transmission. Services such as FTP, telnet, email delivery by SMTP and Web services via HTTP are defined at this level, with each service being assigned a specific port number. (A port is an endpoint to a logical connection. Numbers are used to distinguish between different logical channels on the same network interface.)

At the network level, the ICMP protocol detects and announces network errors and congestion. The IP protocol is responsible for routing the data between networks and employs an addressing system to achieve this. IPv4 is supported, and Series 60 2.x adds support for IPv6 with a dual stack implementation provided by Symbian OS 7.0s.

IPv6

A primary motivation for the introduction of IPv6 was the need for more IP addresses. An increase in address size from 32-bit to 128-bit means that it supports more levels of addressing hierarchy and ultimately more unique addresses. There are further differences between IPv4 and IPv6, in particular the format of the headers, but in general, applications do not need to be concerned about the IP version. However, if an address is to be stored, displayed or manipulated, then you will need to check whether it is an IPv4 or IPv6 address, as the size and format of the addresses differ . This can be achieved through a call to TInetAddr::Family() .

IPv6 also offers increased performance and enhanced security and is mandated by 3GPP standards.

TCP/IP Programming for Series 60

To communicate over TCP/IP you use the Sockets API, specifying the TCP/IP family as the protocol. The general principles of sockets programming, are followed, as described in the Sockets section. An important point to note is that a network interface needs to be started to provide the transport for the connection. There can be many Internet Access Points ( IAP s) defined (the device may know many different ways to connect to the Internet), and you can choose whichever one you wish to use, or just use the default setup.

Besides the Sockets API, other important components include the connection management API, RConnection , which allows an application to use a specific Internet Access Point; NIFMAN , a server to control network interfaces; and the communications database, CommDB , which stores all of the configuration settings. This section describes the Series 60 implementation of TCP/IP and shows you the steps required to create a TCP/IP connection. The differences between Series 60 1.x and Series 60 2.x are also discussed.

CommDB

Information relating to communications settings (IAPs, ISPs, GPRS, modems, locations, charge cards, proxies and WAP) is held in a Symbian OS database. A series of relational tables store the data, with the database being managed by the communications database server, CommDB. Applications can access and modify the settings through CommDB, with the underlying DBMS ensuring the integrity of the database. Users can use the Settings application to view and manipulate the details stored. Note that the database not only stores connection details but also maintains user preferences.

Series 60 1.x defines the CApDataHandler class to enable easy reading and updating of IAP settings. In Series 60 2.x this is replaced by CApUtils . The CApAccessPointItem class is used to represent an individual access point.

Multihoming

Series 60 2.x supports multihoming, which means that several network interfaces can be active at one time. For users, this means that they can access many services, such as MMS, Internet and WAP, simultaneously , with each one using a different technology or setting to connect to the Internet. So a dial-up connection along with several Packet Switched Data ( PSD ) connections could be active, each with its own IP address and each potentially on a different network.

You may encounter the term PDP (Packet Data Protocol) context in discussions about multihoming. Essentially a PDP context refers to a set of information relating to, for example, security, billing, Quality of Service and routing, which describes a mobile wireless service call or session.


Series 60 1.x is effectively "single- homed "that is, it allows only one network interface to be active at a time, and although applications can use the RGenericAgent API to request a connection through a specific IAP, the request will not be successful if another connection is already active. A single-homed system can also lead to problems relating to security and billing, as the TCP/IP stack may not route RSocket and RHostResolver requests through the correct interface. The RConnection API introduced in Series 60 2.x allows an application to specify which IAP is used, and so prevents these problems.

RConnection

The RConnection API, exported by ESOCK , offers full support for multihoming and overcomes the security and billing problems mentioned earlier. Essentially the RConnection API can be used to provide the following functionality:

  • Starting and stopping interfaceswith or without overriding the preferences specified in CommDb .

  • Monitoring progress during start-up of an interface.

  • Indicating when interfaces start and stop.

  • Enumerating active connections.

  • Retrieving statistics on traffic sent and received on an interface.

  • Indicating when subconnections (PDP contexts) start and stop.

  • Reading CommDb fields specific to an active connection.

RConnection objects are implemented as Symbian OS Socket Server subsessions, so they need to be opened on an existing RSocketServ session. Multiple RConnection objects can be defined on a single RSocketServ session, but an individual RConnection object must be used by only a single client. However, it is possible for several RConnection objects to refer to the same underlying interface.

Explicit Connections

If you want to use RConnection to create an explicit interface connection for your TCP/IP sockets, the general procedure is:

  • Connect to the Symbian OS Socket Server.

  • Open an RConnection on the Socket Server.

  • Create IAP preferences using TCommDbConnPref (this is optional).

  • Start the outgoing connectionwith preference overrides if required, using RConnection::Start() .

  • Optionally open a host resolver associated with the connection for DNS look-ups using RHostResolver::Open() .

  • Open a socket associated with the connection using RSocket::Open() .

  • Request the socket to connect to the destination RSocket::Connect() .

Most of these steps have been explained in the Sockets section, but an example, TcpipMultihomingEx , is provided to show the extra stages required. Note once more that RConnection , explicit connections and multihoming are not available in Series 60 1.x, and so this application is Series 60 2. x-specific .

The purpose of the TcpipMultihomingEx example is to read the current date and time from a Daytime Server. To do this, you simply need to connect to an appropriate server on port 13.

The Internet Assigned Numbers Authority (IANA) maintains a list of well-known ports. Port 13 is defined as the port number for the Daytime service. Connection to this port results in the current date and time being sent out.


The following code segment shows the data members of the class CTcpipMultiHomingExEngine :

 TEngineState                  iEngineStatus; CTcpipMultiHomingExAppUi&     iAppUi; RSocket                       iSocket; RConnection                   iRConn; RSocketServ                   iSocketServ; RHostResolver                 iResolver; TNameEntry                    iNameEntry; TNameRecord                   iNameRecord; CTcpipMultiHomingExTimer*     iTimer; TInetAddr                     iAddress; TInt                          iPort; TBuf<KMaxServerNameLength>    iServerName; TBuf8<KReadBufferSize>        iBuffer; TSockXfrLength                iLength; 

The first step, as always, is connecting to the Symbian OS Socket Server. This is done in the CTcpipMultiHomingExEngine::ConstructL() function, as shown in the earlier Sockets section. You then create an RConnection object on the Socket Server, leaving if there are any errors:

 //Open an RConnection on the Socket Server User::LeaveIfError(iRConn.Open(iSocketServ)); 

You can now decide which IAP you want your application to use. By default, the user will be presented with a list of the available IAPs from which to select. Alternatively you can specify a particular access point in your code, either by selecting one from CommDb or by creating a new one. The class TCommDbConnPref can be used to set the preference. If you wish to define an alternative IAP, to be used in case of failure of the preferred connection, TCommDbMultiConnPref is available. You need to consider whether you want the user to be notified of the connection being used. The enumeration TCommDbDialogPref defines the available options that can be passed to TCommDbConnPref::SetDialogPreference() . If you have specified more than one IAP, then it is recommended that you do warn the user if it is the second choice that is being used ( ECommDbDialogPrefWarn ). The use of TCommDbConnPref is shown in the code below. (Note that this code is not taken from TcpipMultihomingEx, as this example allows the user to select the IAP from the list available.)

 // Set the required IAP TCommDbConnPref prefs; prefs.SetDialogPreference(ECommDbDialogPrefDoNotPrompt); prefs.SetDirection(ECommDbConnectionDirectionOutgoing) prefs.SetIapId(2); 

You then call one of the implementations of RConnection::Start() . If you have defined your IAP preference(s) then they should be passed through; although, if you decide to allow the user to select an IAP, this is not necessary. In the example TcpipMultihomingEx , the user chooses the IAP.

There is a synchronous form of RConnection::Start() , but the asynchronous form (as always) is preferred. In the TcpipMultihomingEx example, CTcpipMultiHomingExEngine is an Active Object and issues the request passing through its iStatus . It uses a simple state machine, represented by iState , to manage the connection process.

 // Start the connection iRConn.Start(iStatus); ChangeStatus(ERConnStarting); iTimer->After(KTimeOut); SetActive(); 

CTcpipMultiHomingExEngine::RunL() will be called when the Active Object completes. To determine whether or not the connection was started successfully, iStatus should be tested .

If DNS lookup is required, you can open an RHostResolver object and associate it with the RConnection . The socket should also be opened and associated with the RConnection . This ensures that the data flows over the same underlying interface. Note that KAfInet should always be specified as the address family argument for both RSocket::Open() and RHostResolver::Open() :

 User::LeaveIfError(iResolver.Open(iSocketServ, KAfInet, KProtocolInetUdp, iRConn)); ... User::LeaveIfError(iSocket.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp, iRConn)); 

The destination you wish to connect to is specified using the TInetAddr class. TInetAddr is the generic Socket Server address class for TCP/IP and can store either an IPv4 or IPv6 address. The Input() method takes the IP address as a tdesC& which can be of either formatthis is particularly useful if the IP address has been entered into a dialog box by the user. If you have an IPv4 address in the form of a TUint32 , or an IPv6 address in the form TIp6Addr , then SetAddress() can be called instead. In this example, the connection is to port 13.

RSocket::Connect() is asynchronous, so the iStatus member of CTcpipMultiHomingExEngine is also passed in, and the state machine is updated:

 // Initiate socket connection iSocket.Connect(iAddress, iStatus); ChangeStatus(EConnecting); // Start a timeout iTimer->After(KTimeOut); SetActive(); 

It is strongly recommended that you set up a timer, so that if there is a problem connecting to the specified address, you can time-out the connection. Remember that if your timer does expire before your connection completes, you must cleanup correctly, canceling the connection attempt and closing the socket.


Transferring Data

Once the socket is connected, data can be transferred using the techniques described in the Sockets section. In this example, the time is read from the DAYTIME server (connecting on port 13) using RSocket::RcvOneOrMore() . This is an asynchronous function that completes as soon as any data is available. The data is written to the descriptor, iBuffer , and the length of the data received is written to iLength .

 iSocket.RecvOneOrMore(iBuffer, 0, iStatus, iLength); ChangeStatus(EReading); SetActive(); 

Closing the Connections

It is important that once all of the required reading and writing has completed, all of the handles are closed. As was mentioned in the Sockets section, it is good practice to make the DoCancel() function responsible for the clean-up of sockets and other subsessions, and for Cancel() to be called from the destructor.

 void CTcpipMultiHomingExEngine::DoCancel()    {    iTimer->Cancel();    TEngineState state = ENotConnected;    // Cancel appropriate request to socket    switch (iEngineStatus)       {       case EDestroyed:          state = EDestroyed;       case ENotConnected:       case ERConnStarting:       case EConnecting:       case EConnected:       case ELookingUp:       case EReading:          if (iRConn.SubSessionHandle() != 0)             {             iRConn.Close();             }          if (iResolver.SubSessionHandle() != 0)             {             iResolver.Cancel();             iResolver.Close();             }          if (iSocket.SubSessionHandle() != 0)             {             iSocket.CancelAll();             iSocket.Close();             }          break;       default:          User::Panic(KPanicTcpipMultiHomingExEngine, ETcpipMultiHomingExBadStatus);          break;       }    ChangeStatus(state);    } 

Note that closing the RConnection will not necessarily stop the underlying connection, as other clients may still be using ithowever, the system will take care of this.

There is an RConnection::Stop() function, but this will cause the connection to be terminated even if it is being used elsewhere. Generally you should not use this!


Finally, the session to the Socket Server itself is closed in the destructor:

 CTcpipMultiHomingExEngine::~CTcpipMultiHomingExEngine()    {    ...    if (iSocketServ.Handle() != 0)       {       iSocketServ.Close();       }    } 

Implicit Connections

Although RConnection can be used to start an interface, it is not necessary for an application to complete this step. RSocket::Connect() or RHostResolver::GetByName() will automatically cause an interface to be started, with the Symbian OS Socket Server opening a default connection. The availability of this implicit connection provides compatibility across all versions of Series 60, as the code to produce the implicit connection in Series 60 2.x is the same as the code required to start a TCP/IP (implicit) connection in Series 60 1.x. Note, however, that applications that used RNif and RGenericAgent to explicitly specify a connection in Series 60 1.x will still have to be modified to work with Series 60 2.x.

The application TcpIpImpEx provides an example implementation of an implicit connection. Again, the purpose of the application, apart from demonstrating TCP/IP techniques, is to simply connect to a DAYTIME server (port 13) and display the date and time values returned. As an implicit connection is used, this example will work for any version of Series 60.

The example code is taken from the class CTcpipImpExEngine . The important members of this class are shown here:

 RSocketServ iSocketServ; RSocket iSocket; 

As with the explicit connection, a call to RSocketServ::Connect() is made during construction. The implicit connection is made in the engine's ConnectL() function:

 void CTcpipImpExEngine::ConnectL(TUint32 aAddr)    {    // Initiate attempt to connect to a socket by IP address    if (iEngineStatus == ENotConnected)       {       // Open a TCP socket       User::LeaveIfError(iSocket.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp));       // Set up address information       iAddress.SetPort(iPort);       iAddress.SetAddress(aAddr);       // Initiate socket connection       iSocket.Connect(iAddress, iStatus);       ChangeStatus(EConnecting);       // Start a timeout       iTimer->After(KTimeOut);       SetActive();       }    } 

Once the implicit connection has been made, the method to read the data from the server is identical to that explained in the TcpipMultihomingEx example.



Developing Series 60 Applications. A Guide for Symbian OS C++ Developers
Developing Series 60 Applications: A Guide for Symbian OS C++ Developers: A Guide for Symbian OS C++ Developers
ISBN: 0321227220
EAN: 2147483647
Year: 2003
Pages: 139

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net