|
||
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.
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.
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.
RConnection
s 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).
Provides clients with the following functionality:
Opening and closing the connection
Starting a connection, which means associating it with a new underlying interface
Attaching the RConnection
instance to an existing
interface
Stopping the connection, which means disassociating it from the underlying interface
Obtaining progress information and notification during connection start-up
Notifying when subconnections come up and go down
Notifying when there is a service change for the connection
Notifying when a given amount of data has been sent or received on a connection or subconnection
Reading CommDB fields specific to an active connection
Collecting statistical information on the network connection and subconnections. A UI component can display the collected statistical information in order to allow the user to examine the status of connections. The information that can be gathered is the following:
All available internet access point names and internet access point 'friendly' names as appropriate for each network (GPRS/UMTS) connection
Enumerating the currently active connections and subconnections
The current status of all network connections e.g. active/suspended
The amount of data (in bytes) transferred uplink and downlink by the network connection and subconnections
The amount of time each network connection has been active (in seconds)
The current status of the connection and subconnections with respect to data transfer, i.e. active/inactive
The Quality of Service profile associated with each Packet Data Protocol (GPRS/UMTS) context, e.g. low/medium/high
These examples show:
Implicit connection startup
Explicit connection startup
Attaching to a subconnection
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);
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);
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);