|
|
||
A NIFMAN configuration daemon is a plug-in that allows the network interface components to be configured after the link-layer has been established. This document describes how to implement such a plug-in. It has the following sections:
NIFMAN is the Symbian OS component that establishes and manages network interfaces. Plug-ins called agents provide functionality to set up network interfaces, such as dialling up an Internet access provider; another set of plug-ins called NIFs provide data transfer over the interface. For example, PPP is implemented as a NIF plug-in.
As of v8.0, NIFMAN supports a new type of plug-in: one for configuring NIFs. This new plug-in permits configuration of the NIF over a newly established interface, such as PPP, just before a higher-level protocol such as TCP/IP is started. This allows, for example, the obtaining and setting of the IP address for the interface. Providing configuration functionality as a plug-in allows new configuration mechanisms to be added without rewriting the NIF; additionally, this allows a configuration plug-in to be used with different NIFs.
The following figure shows the main components involved:
As shown, the NIFMAN configuration daemon architecture consists of two parts:
An ECom plug-in for NIFMAN. The ECom plug-in's role is manage the interface between NIFMAN and the actual configuration daemon. The ECom plug-in is referred to as the configuration daemon manager.
The configuration daemon. The configuration daemon is a Symbian OS server that runs in its own process, rather than in the NIFMAN thread. Licensees can write new configuration daemons.
The framework for configuration daemons was introduced at v8.0. A DHCP daemon was also implemented. In v8.1, the daemon API was enhanced so that a Mobile IP daemon could be implemented. The additions give support for:
deregistration events: this notifies the daemon when the interface is shutting down.
For Mobile IP, this gives the phone the opportunity to deregister its foreign agent care-of address with the home agent.
Alternatively, the daemon can instruct NIFMAN to maintain the logical state of a user's session (IP address, PPP state and above layers as well as the radio link session information), while releasing the resources associated with the air-link. This is called "fast dormant mode".
inter-PDSN handoff events: when mobile IP handoff happens in CDMA network, the network requests that PPP is renegotiated. The daemon is notified when the PPP link layer re-negotiation is started, and when it is completed.
After renegotiation is completed, a mobile IP daemon should complete the Mobile IP handoff procedure described in sections 5.1 and 5.2 in the 3GPP2 standard C.S0037, "Signaling Conformance Specification for cdma2000 Wireless IP Networks".
progress notifications: Mobile IP is required to
report progress notifications as it registers/deregisters with/from the foreign
agent. The notifications are passed by NIFMAN to the sockets client, through
RConnection::ProgressNotification(), for the current
interface.
The configuration daemon manager can only handle one outstanding daemon request at a time. If a request is already being processed, NIFMAN can, however, queue a deregistration request and dispatch it upon completion of the previous request. Other types of request are not queued. This permits the handling of the following scenarios:
Deregistration notification during registration.
Deregistration notification during an Ioctl request.
Deregistration notification when the daemon is being requested to enter fast dormant mode.
Daemons are loaded on demand when a connection is started that
requires network layer configuration. The ECom configuration daemon manager (if
any) to use for a connection is specified in the SERVICE_CONFIG_DAEMON_MANAGER_NAME field in
CommDb's Dial Out ISP, GPRS and CDMA2000
Packet Service tables. The daemon server (if any) to use for a connection is
specified in the SERVICE_CONFIG_DAEMON_NAME field in
CommDb's Dial Out ISP, GPRS and CDMA2000 Packet Service tables.
To implement a configuration daemon, you will need to write a Symbian OS server in the standard way, as described in Using Client/Server.
The name given the server in CServer::Start()
should match the name used in the CommDb
SERVICE_CONFIG_DAEMON_NAME field.
The server must handle six message types in its session
ServiceL() function. These message types are explained
below:
Configuration allows the daemon to configure the interface as it starts up
Deregistration allows the daemon to take action when the interface is shutting down
PPP renegotiation events allows the daemon to take action when PPP is renegotiated
Progress notifications allows the daemon to notify clients of events
Ioctl commands allows the daemon to handle daemon-specific requests from clients
Cancellation and Cancellation mask messages allows asynchronous requests to the daemon to be cancelled
A typical ServiceL() implementation that tests for
these messages types and calls functions to handle them is as follows:
void CEgConfigDaemonSession::ServiceL(const RMessage2& aMessage)
{
switch (aMessage.Function())
{
case EConfigDaemonConfigure:
ConfigureL(aMessage);
break;
case EConfigDaemonDeregister:
DeregisterL(aMessage);
break;
case EConfigDaemonLinkLayerDown:
LinkLayerDownL(aMessage);
break;
case EConfigDaemonLinkLayerUp:
LinkLayerUpL(aMessage);
break;
case EConfigDaemonProgress:
ProgressL(aMessage);
break;
case EConfigDaemonIoctl:
IoctlL(aMessage);
break;
case EConfigDaemonCancel:
Cancel(aMessage);
break;
case EConfigDaemonCancelMask:
CancelMask(aMessage);
break;
default:
User::Leave(KErrNotSupported);
break;
}
}
The following sections describe each of these message types.
A EConfigDaemonConfigure message is received when a
new connection is requested. Specifically, it occurs when a NIF calls
MNifIfNotify::LinkLayerUp() to indicate to NIFMAN that the
link layer is up.
The message has a single data buffer parameter providing a
TConnectionInfoBuf object. This packages a
TConnectionInfo object that specifies the IDs of CommDb
IAP and Network records used for the connection.
The following code reads the CommDb IAP ID from a received message:
TConnectionInfoBuf conInfoBuf;
aMessage.Read(0, conInfoBuf);
TConnectionInfo conInfo = conInfoBuf();
TInt iap = conInfo.iIapId;
This information allows the daemon to access the relevant CommDb
records, and to update the fields. A Mobile IP daemon would obtain a
care-of-address for the phone and set the IP address for the interface using
RSocket::SetOpt(KSoInetConfigInterface, KSolInetIfCtrl,
interfaceInfoBuf).
The message request is asynchronous, and can be cancelled with a
EConfigDaemonCancel or
EConfigDaemonCancelMask request, discussed in
Cancellation
below.
Configuration of the daemon may be interrupted by the expiry of
the NIFMAN idle timer if the configuration is slow, or if the idle timeouts are
short. To overcome this, it may be necessary for the configuration daemon to
disable and subsequently re-enable idle timers at appropriate times using
RConnection::SetOpt(KCOLProvider, KConnDisableTimers, ETrue). Note
that NIFMAN will wait indefinitely for a configuration daemon to finish
configuration of the interface if the idle timers have been disabled. The
configuration daemon must be implemented robustly to ensure that the request is
always terminated.
A EConfigDaemonDeregister message is received when
an interface is shutting down because of:
The NIFMAN idle timer expiring. This timer shuts down the interface if there has not been activity for a specified time. There are three time-out values, which are set in the CommDb bearer table:
LAST_SESSION_CLOSED_TIMEOUT:
time-out used if there are no ESock RConnection objects
and no sockets for the interface
LAST_SOCKET_CLOSED_TIMEOUT: time-out
used if there are RConnection objects, but no sockets, for
the interface
LAST_SOCKET_ACTIVITY_TIMEOUT:
time-out used if there are any sockets for the interface
RConnection::Stop() being called on the
interface.
When it receives a deregistration message, the configuration daemon can decide to do one of two things:
Instruct NIFMAN to continue to shut down the interface.
A CDMA Mobile IP daemon can at this time deregister the phone's care-of-address with the home agent.
Instruct NIFMAN to go into fast dormant mode. NIFMAN then keeps the NIF and the agent loaded, and stops the idle timer.
After the daemon instructs NIFMAN to go into fast dormant
mode, it is up to the daemon to tell NIFMAN when the link is up again. It does
this by issuing a KConfigDaemonFinishedDormantMode
progress notification (for how to do this, see
progress notifications
below). NIFMAN will then set the link state to indicate that it is up, and
restart the idle timer.
The deregistration message has two parameters:
0: an integer in parameter identifying the cause of the deregistration request.
This is an enum
EConfigDaemonDeregisterCause value, being either
EConfigDaemonDeregisterCauseTimer, meaning the
deregistration was caused by the NIFMAN idle timer, or
EConfigDaemonDeregisterCauseStop, meaning the
deregistration was caused by RConnection::Stop().
1: a TDes8*
out parameter
identifying what action NIFMAN should take.
The daemon should package into this output buffer an enum
EConfigDaemonDeregisterAction value. The defined values
are EConfigDaemonDeregisterActionStop, meaning to stop the
interface, or EConfigDaemonDeregisterActionPreserve,
meaning to preserve the interface state (i.e. go into fast dormant
mode).
The message request is asynchronous, and can be cancelled with a
EConfigDaemonCancel or
EConfigDaemonCancelMask request, discussed in
Cancellation below.
Deregistration can be interrupted by the NIFMAN idle timer expiring. See Configuration for details of how to handle this.
PPP renegotiation events occur when inter-PDSN handoff in a CDMA network. This happens as follows:
When the inter-PDSN handoff happens, the network sends an LCP Config Request to the phone's PPP.
The phone's PPP begins to renegotiate. While this happens, the PPP NIF goes to a down state, and the outgoing data flows are blocked.
A EConfigDaemonLinkLayerDown
notification is sent to the configuration daemon to inform it that this process
has started.
When PPP re-negotiation is finished, the PPP NIF will go to an up state again, and the outgoing data are unblocked.
A EConfigDaemonLinkLayerUp notification
is sent to the configuration daemon to inform it that this has occurred. The
mobile IP daemon can then go on to complete the Mobile IP handoff.
A daemon can report progress notifications at any time while
running. These notifications are received by NIFMAN and passed to ESock and all
ESock clients that subscribed to progress notifications
(RConnection::ProgressNotification()) for the current
interface.
The daemon receives an EConfigDaemonProgress
message requesting progress notifications immediately after it is loaded. The
message has a single out parameter, a
TDaemonProgressBuf, which packages a
TDaemonProgress object. This has integer fields to hold
the progress stage and any error code (these fields correspond to those in the
TNifProgress object that the client will receive from
RConnection::ProgressNotification().) To pass back a
notification, the daemon should write its progress information into this
parameter and complete this message. NIFMAN will then handle the notification
and reissue a progress request to the daemon.
The daemon can define whatever stages are appropriate to its
function. As noted in Deregistration, there is one
special predefined stage,
KConfigDaemonFinishedDormantMode, that is used when
resuming the link from dormant mode.
The NIFMAN configuration plug-in that calls the daemon provides progress notifications for a range of generic events. These are:
|
A EConfigDaemonIoctl message is received when a
client issues a RConnection::Ioctl() call. The
configuration daemon can define its own set of ioctl commands, appropriate to
its function.
All four message parameters are used:
0: an integer specifying the ioctl option level
1: an integer specifying the ioctl option name
2: a pointer to a caller supplied data buffer
(TDes8*). This is optional. If set, the message handler can read
data from the buffer, and write back to it to return data to the caller.
3: an integer specifying the maximum length of the caller supplied data buffer. This is 0 if no buffer was supplied.
The following code gets the option level and name from the
message, and for messages that supply a data buffer (length>0) calls a
handler function HandleClientRequestL(), writing back the returned
buffer into the message.
TUint optionLevel = aMessage.Int0();
TUint optionName = aMessage.Int1();
TInt length = aMessage.Int3();
if (length>0)
{
HBufC8* buffer = HBufC8::NewMaxLC(length);
TPtr8 ptr = buffer->Des();
aMessage.ReadL(2, ptr);
HandleClientRequestL(optionLevel, optionName, &ptr);
aMessage.Write(2, ptr);
CleanupStack::PopAndDestroy(buffer);
aMessage.Complete(KErrNone);
}
The message request is asynchronous, and can be cancelled with a
EConfigDaemonCancel or
EConfigDaemonCancelMask request, discussed in
Cancellation below.
A EConfigDaemonCancel message cancels any
outstanding request apart from for progress notifications. It has no
parameters. The service function should complete the message and cancel any
current asynchronous operations.
A EConfigDaemonCancelMask message has a
single integer parameter. If this is
KConfigDaemonOpMaskProgress, then the request is to cancel
progress notifications. If it is
KConfigDaemonOpMaskGeneral, then the request is to cancel
any other outstanding operation (i.e. the same as
EConfigDaemonCancel).
A sample configuration daemon is provided in
generic/comms-infras/nifman/te_connectioncontrol/configdaemon/.