Implementing Services in a Server Application

An application must do the following steps to become a server application and to implement a service.

Implementing the server

To enable an application support instantiation as a new server application instance, do the following steps:

  1. Use the EikServerApp.h header file, or a suitable System-GUI specialisation of this class.

  2. Derive a server class from CEikAppServer, or suitable System-GUI specialisation of this class

  3. Override the CApaApplication::NewAppServerL() function to create a new server instance.

The following example code shows how an application can become a server application.

class CServer1Server : public CEikAppServer
    {
    public:
        CApaAppServiceBase* CreateServiceL(TUid aServiceType) const;
    };

class CServer1Application : public CEikApplication
    {
    private:
        // from CApaApplication
        CApaDocument* CreateDocumentL();
        TUid AppDllUid() const;
        void NewAppServerL(CApaAppServer*& aAppServer);
    };

void CServer1Application::NewAppServerL(CApaAppServer*& aAppServer)
    {
    aAppServer = new(ELeave) CServer1Server;
    }

Note: The application must only complete first stage construction of the new application and the framework will handle the rest of the construction.

Implementing services

To implement a service in a server application, do the following steps:

  1. Identify the service support provided for the service in the platform.

  2. Include the service support's server support header and link to the service support DLL.

  3. Derive an implementation class from the services abstract base class.

  4. Implement the virtual functions to handle requests from the client.

  5. Define the security policy for the service.

  6. Override the CApaAppServer::CreateServiceL() function to create new instances of the service.

The following example code shows how a server application may implement a chat service.

class CMyAppChatterSession : public CChatService
    {
    public:
        void Receive(TDes& aMessage);
    };

void CMyAppChatterSession::Receive(TDes& aMessage)
    {
    // very crude case shift
    for (TInt ii=0; ii<aMessage.Length(); ii++)
        {
        TText& c = aMessage[ii];
        if ('A' <= c && c <= 'z')
            c = c ^ 0x20;
        }
    Send(aMessage);
    }

CApaAppServiceBase* CServer1Server::CreateServiceL(TUid aType) const
    {
    if (aType == KInterAppChatType)
        return new(ELeave) CMyAppChatterSession();
    else
        return CEikAppServer::CreateServiceL(aType);
    }

Implementing a security policy

The server application framework allows server to check the capabilities of a client.

CPolicyServer::TCustomResult CApaAppServer::CreateServiceSecurityCheckL(TUid aServiceType, const RMessage2& aMsg, TInt& aAction, TSecurityInfo& aMissing);

A server application may override this to check that the client has sufficient capabilities to use this service.

For example, this server application checks that the client has NetworkServices capability (see TCapability::ECapabilityNetworkServices) before it can connect to this service implementation:

static _LIT_SECURITY_POLICY_C1(KServiceAppChatPolicy, ECapabilityNetworkServices);

CPolicyServer::TCustomResult CServer1Server::CreateServiceSecurityCheckL(TUid aServiceType, const    RMessage2& aMsg, TInt& aAction, TSecurityInfo& aMissing)
    {
        if (aServiceType == KInterAppChatType && KServiceAppChatPolicy().CheckPolicy(aMsg, aMissing, __PLATSEC_DIAGNOSTIC_STRING("KServiceAppChatPolicy"))
            return CPolicyServer::EPass;
        else
            return CPolicyServer::EFail;
    }

Service implementations can also check capabilities for individual service messages by overriding the CApaAppServiceBase::SecurityCheckL() function.

CPolicyServer::TCustomResult CApaAppServiceBase::SecurityCheckL(const RMessage2& aMsg, TInt& aAction, TSecurityInfo& aMissing);

For example, the following code checks that the client has ReadUserData capability (see TCapability::ECapabilityReadUserData) before allowing it to receive messages:

static _LIT_SECURITY_POLICY_C1(KServiceAppChatReceivePolicy, ECapabilityReadUserData);

CPolicyServer::TCustomResult CMyAppChatterSession::SecurityCheckL(const RMessage2& aMsg, TInt& aAction, TSecurityInfo& aMissing)
    {
        if (aMsg.Function() == EInterAppChatReceive && KServiceAppChatReceivePolicy().CheckPolicy(aMsg, aMissing, __PLATSEC_DIAGNOSTIC_STRING("KServiceAppChatReceivePolicy"))
            return CPolicyServer::EPass;
        else
            return CPolicyServer::EFail;
    }

Note: If a client fails a security check then it returns an error code to the client.