RSubConnection API Tutorial

How to use an RSubConnection.

Procedure

  1. Use the Open() method to open an RSubConnection object on an ESOCK session.

    The RConnection must already be active. A sub-connection type is passed as a parameter to this method. It is then attached to the default sub-connection that is the RConnection, or creates a sub-connection. When an application calls the RSubConnection API, a system wide error code is returned. When it is successful, it returns KErrNone.

  2. Use the Add() method to move the socket from the default sub-connection to the RSubConnection.

  3. The Remove() method returns the socket to the default sub-connection.

  4. Use the GetParameters() and SetParameters() methods are to retrieve and set bundles of properties on the sub-connection.

  5. The GetParameters() returns KErrNotReady if properties are not negotiated.

  6. The SetParameters() method, like the Add() and Remove() methods returns an error code indicating the success or failure of the request to perform the action.

  7. When the properties are negotiated either the CSubConGenEventParamsGranted or CSubConGenEventParamsRejected event is notified for each family within the parameter bundle.

  8. Use the EventNotification() methods to asynchronously register for event notifications.

    The methods support filtering of events in two different ways, through a Boolean flag to receive notification of generic or all events, and through an array of TEventFilter.

  9. Use CancelEventNotification() method cancel the registration for event notifications.

Connecting to the default SubConnection example

In the following example, the application connects to the default sub-connection to set the properties. When it has set properties on the default sub-connection, the application tries to connect a socket over the default sub-connection.

RSocketServ ss;
RConnection conn;
RSubConnection subconn;
RSocket sock;
TRequestStatus status;

// Connect to ESOCK
ss.Connect();

// Open a Connection
conn.Open(ss, KAfInet);

// Start the connection
conn.Start(status);
User::WaitForRequest(status);

// Attach to the default sub-connection
subconn.Open(ss, RSubConnection::EAttachToDefault, conn);

// Set Properties of the default sub-connection
subconn.SetParameters(…);

// Open a TCP socket on the connection (this is the same as using the default sub-connection)
sock.Open(ss, KAfInet, KSockStream, KProtocolInetTcp, conn);

_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 over the default sub-connection
sock.Connect(destAddr, status);

Creating a sub-connection - Socket connected over the SubConnection example

The following example shows how an application can use a sub-connection through an RSubConnection instance. It attaches an RSocket to the sub-connection.

RSocketServ ss;
RConnection conn;
RSubConnection subconn;
RSocket sock;
TRequestStatus status;

// Connect to ESOCK
ss.Connect();

// Open an Connection
conn.Open(ss, KAfInet);

// Start the connection
conn.Start(status);
User::WaitForRequest(status);

// Create a new sub-connection
subconn.Open(ss, RSubConnection::ECreateNew, conn);

// Set Properties of the sub-connection
subconn.SetParameters(…);

// Open a TCP socket on the sub-connection
sock.Open(ss, KAfInet, KSockStream, KProtocolInetTcp, subconn);

_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 over the sub-connection
sock.Connect(destAddr, status);

Creating a new sub-connection - Adding an already connected socket example

The following example shows how an application can use a sub-connection through an RSubConnection instance. It attaches a connected RSocket to the sub-connection.

RSocketServ ss;
RConnection conn;
RSubConnection subconn;
RSocket sock;
TRequestStatus status;

// Connect to ESOCK
ss.Connect();

// Open a Connection
conn.Open(ss, KAfInet);

// Start the connection
conn.Start(status);
User::WaitForRequest(status);

// Open a TCP socket on the connection
sock.Open(ss, KAfInet, KSockStream, KProtocolInetTcp, conn);

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

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

// Connect the Socket to the destination over the connection (default sub-connection)
sock.Connect(destAddr, status);

// Create a new sub-connection
subconn.Open(ss, RSubConnection::ECreateNew, conn);

// Set Properties of the sub-connection
subconn.SetParameters(…);

// Move the connected socket onto the new sub-connection
TRequestStatus status;
subconn.Add(sock, status);

// Wait for socket to added
User::WaitForRequest(status);

Creating and setting properties for a SubConnection example

The following example shows how an application creates and sets the QoS properties. It assigns the properties to a sub-connection.

// Create the container for all sub connection parameters
RSubConParameterBundle subconParams;
CleanupClosePushL(subconParams);

// Create a container for QoS sub connection parameters (Param bundle takes ownership)
CSubConParameterFamily* qosFamily = CSubConParameterFamily::NewL(subconParams,
    KSubConQoSFamily);

// Create the requested generic parameter set for QoS (Qos family takes ownership)
CSubConQosGenericParamSet* reqGenericParams = CSubConQosGenericParamSet::NewL(*qosFamily,                               
    CSubConParameterFamily::ERequested);

// Set the requested Generic Parameters
reqGenericParams->SetDownlinkBandwidth(128);
reqGenericParams->SetUplinkBandwidth(64);

// Create the acceptable generic parameter set for QoS (Qos family takes ownership)
CSubConQosGenericParamSet* accGenericParams = CSubConQosGenericParamSet::NewL(*qosFamily,                               
    CSubConParameterFamily::EAcceptable);

// Set the acceptable Generic Parameters
accGenericParams->SetDownlinkBandwidth(48);
accGenericParams->SetUplinkBandwidth(32);

// Create a requested technology specific parameter set for QoS (Qos family takes ownership)
CSubConQosR99ParamSet* reqRel99Params = CSubConQosR99ParamSet::NewL(*qosFamily,
    CSubConParameterFamily::ERequested);

// Set the requested Technology Specific Params
reqRel99Params->SetMaxSDUSize(1024);

// Create a acceptable technology specific parameter set for QoS (Qos family takes ownership)
CSubConQosR99ParamSet* accRel99Params = CSubConQosR99ParamSet::NewL(*qosFamily,
    CSubConParameterFamily::EAcceptable);

// Set the acceptable Technology Specific Params
accRel99Params->SetMaxSDUSize(512);

// Now open the sub-connection as normal…
………
………
// Create a new sub-connection
subconn.Open(ss, RSubConnection::ECreateNew, conn);

// Set Properties of the sub-connection
subconn.SetParameters(subconParams);

// Destroy parameters
CleanupStack::PopAndDestroy();         // subconParams

// Open a TCP socket on the sub-connection
sock.Open(ss, KAfInet, KSockStream, KProtocolInetTcp, subconn);

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

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

// Connect the Socket to the destination over the sub-connection
sock.Connect(destAddr, status);
User::WaitForRequest(status);

// Fetch the granted qos
RSubConParameterBundle grantedParams;
subconn.GetParameters(grantedParams);

Registering for events example

The following example shows how an application can register events that occur on a sub-connection. In this example the application registers for notification of all events.

// Create the container for all sub connection parameters
RSubConParameterBundle subconParams;
CleanupClosePushL(subconParams);

………
………
// Create and initialise parameters sets as above
………
………

// Create a new sub-connection
subconn.Open(ss, RSubConnection::ECreateNew, conn);

TNotificationEventBuf eventBuffer;
TRequestStatus eventStatus;
subconn.EventNotification(eventBuffer, EFalse, eventStatus);

// Set Properties of the sub-connection
subconn.SetParameters(subconParams);

// Destroy parameters
CleanupStack::PopAndDestroy();         // subconParams

// Open and connect a TCP socket on the sub-connection
sock.Open(ss, KAfInet, KSockStream, KProtocolInetTcp, subconn);
sock.Connect(destAddr, status);
User::WaitForRequest(status);

// Negotiation may not occur until a socket is assigned to the sub-connection
// First event should be cSubConGenEventDataClientJoining
User::WaitForRequest(eventStatus);

// Next we’d expect a CSubconGenEventParamsGranted/ CSubconGenEventParamsRejected
subconn.EventNotification(eventBuffer, EFalse, eventStatus);
User::WaitForRequest(eventStatus);

Registering for events – Using filters

The following example code shows how to register for specific events using filters. In this example the application registers for notification when sub-connection parameters are granted or rejected. Each TEventFilter contains events of the factory UID and mask of event IDs.

// Create the container for all sub connection parameters
RSubConParameterBundle subconParams;
CleanupClosePushL(subconParams);

………
………
// Create and initialise parameters sets as above
………
………

// Create a new sub-connection
subconn.Open(ss, RSubConnection::ECreateNew, conn);

// Create event filter
TEventFilter filter;
filter.iEventGroupUid = KSubConnGenericEventsImplUid;
filter.iEventMask = KSubConGenericEventParamsRejected | KSubConGenericEventParamsGranted;

// Register for event
TNotificationEventBuf eventBuffer;
TRequestStatus eventStatus;
subconn.EventNotification(eventBuffer, &filter, 1, eventStatus);

// Set Properties of the sub-connection
subconn.SetParameters(subconParams);

// Destroy parameters
CleanupStack::PopAndDestroy();         // subconParams

// Open and connect a TCP socket on the sub-connection
sock.Open(ss, KAfInet, KSockStream, KProtocolInetTcp, subconn);
sock.Connect(destAddr, status);
User::WaitForRequest(status);

// Event should be CSubconGenEventParamsGranted/CSubconGenEventParamsRejected
User::WaitForRequest(eventStatus);

Extracting information from received events example

The following example code shows how to extract the information contained within an event notification when it is received.

// Create the container for all sub connection parameters
RSubConParameterBundle subconParams;
CleanupClosePushL(subconParams);

………
………
// Create and initialise parameters sets as above
………
………

// Create a new sub-connection
subconn.Open(ss, RSubConnection::ECreateNew, conn);

// Create filter, register for events, and set parameters as above
……
subconn.EventNotification(eventBuffer, &filter, 1, eventStatus);
……

// Open and connect a TCP socket on the sub-connection
……

// Receive the event notification
User::WaitForRequest(eventStatus);

CSubConNotificationEvent* event;
event = CSubConNotificationEvent::NewL(eventBuffer);
CleanupStack::PushL (event);

if (event->GroupId() == KSubConnGenericEventsImplUid
    && event->Id() == CSubConGenEventParamsRejected)
    {
    CSubConGenEventParamsRejected* rejectedEvent =
        static_cast< CSubConGenEventParamsRejected*>(event);

    TInt error = rejectedEvent->Error();
    ……
    // Do something with the error
    ……
    }

CleanupStack::PopAndDestroy (event);