Symbian
Symbian OS Library

SYMBIAN OS V9.3

[Index] [Spacer] [Previous] [Next]



Connection Management


Purpose

Provides an interface for actively creating and managing connections.

Provides facilities, including support for multihoming, that are not available when creating connections by other methods.

Introduced with the implementation of the multihoming functionality, which allows multiple Circuit/Packet Switched Data connections to be active.

Replaces the RNif, RGenericAgent and RNifMonitor APIs used for connection startup in releases prior to 7.0S.

[Top]


Description

Implementation

The connection management API is implemented by RConnection.

RConnection objects are implemented as sub-sessions to the socket server, in the same way as RSocket and RHostResolver objects.

Connections and subconnections

An RConnection is the handle for an application onto an underlying interface. (But there may be a number of RConnections per interface).

Technologies such as W-CDMA and later releases of GPRS are capable of establishing multiple subconnections within a connection. This is supported by the management interface.

Note that all subconnections within a connection will have certain parameters in common, such as the Access Point Name in the case of GPRS and WCDMA. However, each subconnection may have a different Quality-of-Service.

Guidelines for use

RConnections need to be opened on an existing socket server session, RSocketServ.

In the API as a whole, there is an important distinction made between an RConnection object which has been newly opened on an socket server session but not yet associated with an underlying interface on the server, and one which is opened and associated. There are certain operations that require a RConnection object to be in the associated state to work successfully. The RConnection::Start() and RConnection::Attach() methods are used to associate an RConnection object with an interface.

There is no restriction on the number of RConnection objects per socket server session. It is also possible for several RConnection objects to refer to the same underlying interface. For example, several applications, each with its own socket server session and RConnection object, could refer to the same underlying interface. It is also technically possible for the said RConnection objects to be on the same socket server session, though this may be somewhat redundant.

Rather like RSocket/RHostResolver objects, an individual RConnection object is not designed to be used by multiple clients simultaneously (i.e. have multiple requests outstanding on it from different clients).

Although RConnection objects are automatically closed when the corresponding socket server session is closed, appropriate use of CleanupClosePushL(RConnection&) is more likely to ensure proper operation.

As mentioned earlier, RSocket and RHostResolver objects can be associated with an RConnection object via additions to their respective APIs. In this case, data will flow over the same underlying interface as the RConnection to which they have been associated. For this to work, the RSocket/RHostResolver/RConnection objects must all be on the same socket server session, and the RConnection object must have been previously opened and active (i.e. associated with an underlying interface).

Functionality

Provides clients with the following functionality:

[Top]


Examples

These examples show:

Implicit Connection Startup

In the following example, the application is unaware of the connection and does not have an instance of RConnection. This might be used if an application tries to connect a socket or resolve a name and the socket server detects that a connection has not been started. This example does not differ from previous versions of the Symbian OS.

Note that error handling is not included to aid clarity.

RSocketServ ss;
RSocket sock;
TRequestStatus status;

// Connect to the socket server
ss.Connect();

// Open a TCP socket 
sock.Open(ss, KAfInet, KSockStream, KProtocolInetTcp);

_LIT(KRasAddr,"10.159.24.13");
const TInt KEchoPort = 7;

TInetAddr destAddr;
destAddr.Input(KRasAddr);
destAddr.SetPort(KEchoPort);

// Request the Socket to connect to the destination (implicit Connection)
sock.Connect(destAddr, status);

Explicit Connection Startup

The following example shows how an application can start a connection explicitly via an RConnection instance, and tie an RHostResolver and RSocket to the connection started.

The application is able to override the connection preference settings in CommDb allowing it to specify the Network, IAP, ISP and bearer used. Code examples are given for the cases with and without overrides.

See TCommDbConnPref for information about how to set up the connection.

RSocketServ ss;
TRequestStatus status;
RConnection conn;

_LIT(KRasAddr,"10.159.24.13");
const TInt KEchoPort = 7;

TInetAddr destAddr;
destAddr.Input(KRasAddr);
destAddr.SetPort(KEchoPort);

// Connect to the socket server
ss.Connect();

// Open an RConnection object. Note that you must provide the RSocketServ object
conn.Open(ss);

// Create overrides
TCommDbConnPref prefs;
prefs. SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
prefs.SetDirection(ECommDbConnectionDirectionOutgoing);
prefs.SetIapId(4);

// Start an Outgoing Connection with overrides
conn.Start(prefs);

// Open a Host Resolver associated with the connection
RHostResolver hr;
hr.Open(ss, KAfInet, KProtocolInetTcp, conn);

// Open a Socket associated with the connection
RSocket sock;
sock.Open(ss, KAfInet, KSockStream, KProtocolInetTcp, conn);

// Request the Socket to connect to the destination
sock.Connect(destAddr, status);

Attaching to a Connection

The following example shows how an application can attach to an existing connection in order to gather information on the connection.

Note that error checking is included in this example.

//Open a session with the socket server
RSocketServ socketServer;
TInt err(KErrNone);
err = socketServer.Connect();
if(err != KErrNone) return err;

//Open a subsession with the socket server for the RConnection
RConnection myConnection;
err = myConnection.Open(socketServer);
if(err != KErrNone) return err;

//Start or attach the RConnection to an interface on the server
TUint connectionCount;
//Enumerate currently active connections across all socket servers
err = myConnection.EnumerateConnections(connectionCount);
if(err != KErrNone) return err;
if(connectionCount == 0) // if no connections are started
{
            err = myConnection.Start();
}
else
{
            TPckgBuf<TConnectionInfoV2> connectionInfo;
            err = myConnection.GetConnectionInfo(1, connectionInfo); // 1 = first active connection
            if(err!=KErrNone) return err;
            err = myConnection.Attach(connectionInfo, RConnection::EAttachTypeMonitor);
}

At this point myConnection points to a specific connection. Obviously the code snippet above could be expanded in several ways such as getting connection information for all connections and selecting a connection based on the information rather than simply selecting the first connection, as in this case.

Note for this and the next section that the number of connections and subconnections are not constant and can be expected to change during execution.

//Store subconnection information

TUint subConnectionCount(0);
err = myConnection.EnumerateSubConnections(subConnectionCount);
if(err != KErrNone) return err;

//TSubConnectionInfoGprsUmts is a superclass of TSubConnectionInfo, so we will use it
//to hold either GPRS/UMTS or CSD connection information as required. (CSD connection 
//information is held in a plain TSubConnectionInfo object).
TPckgBuf<TSubConnectionInfoGprsUmts> subConnectionInfo[subConnectionCount];
//note that for a CSD connection the subConnectionCount will be 1

for (TUint i=0; i<subConnectionCount; i++)
{
            err = myConnection.GetSubConnectionInfo(i, subConnectionInfo[i]);
            if(err != KErrNone) return err;
}

Once the connection has been attached it is possible to start querying individual subconnections.

From this point the client has access to subConnectionInfo().iSubConnectionUniqueId, which is the unique identifier for the subconnection that has been queried. Now that this value is available the client can make any further calls to subconnection specific functionality within the RConnection, for example querying the amount of data currently transferred by the specified subconnection.

TUint connectionuplinkVolume(0);
TUint connectiondownlinkVolume(0);
TUint subconnectionuplinkVolume(0);
TUint subconnectiondownlinkVolume(0);
TPckg<TUint> connectionUplinkVolume(connectionuplinkVolume);
TPckg<TUint> connectionDownlinkVolume(connectiondownlinkVolume);
TPckg<TUint> subConnectionUplinkVolume(subconnectionuplinkVolume);
TPckg<TUint> subConnectionDownlinkVolume(subconnectiondownlinkVolume);
TRequestStatus status;

//Query data transfer over the connection
myConnection.DataTransferredRequest(connectionUplinkVolume, connectionDownlinkVolume, status);

//Query data transfer over a specified subconnection
myConnection.DataTransferredRequest(subConnectionInfo[0]().iSubConnectionUniqueId, connectionUplinkVolume, connectionDownlinkVolume, status);