upnp/upnpstack/ssdpserver/inc/upnpudpserver.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:12:20 +0200
changeset 0 f5a58ecadc66
permissions -rw-r--r--
Revision: 201003

/** @file
 * Copyright (c) 2005-2008 Nokia Corporation and/or its subsidiary(-ies). 
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
 * which accompanies  this distribution, and is available 
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
 * Initial Contributors:
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
 *
 * Description:  Declares main application class.
 *
 */

#ifndef C_CUPNPUDPSERVER_H
#define C_CUPNPUDPSERVER_H

// INCLUDES
#include <e32base.h>
#include <es_sock.h>
#include <es_enum.h>
#include <in_sock.h>
#include <commdbconnpref.h>
#include "upnpssdpmessage.h"
#include "upnpmessageobserver.h"
#include "upnpconnectionmanagerproxy.h"

// FORWARD DECLARATIONS
class CUpnpHttpMessage;
class CUpnpUdpSendRequest;

// CONSTANTS
static const TUint KDefaultStartPort = 2000;
static const TUint KDefaultMulticastPort = 1900;
static const TUint32 KDefaultMulticastAddress = INET_ADDR(239,255,255,250);
static const TUint KAddressLength = 35;
static const TInt KSendTimerLimit = 10;
static const TUint KSendingDelay = 15000; //DLNA specyfies that: UPnP network devices must not send more than 10 ssdp:alive messages
//on a single network interface in any given 200 ms period. So 15ms delay between each message
//should be sufficient 15ms = 15000 microseconds.
static const TUint32 KDefaultAutoIPAddress = INET_ADDR(169,254,255,255);

// DATA TYPES
typedef CUpnpHttpMessage CUdpMessage;

// CLASS DECLARATION

/**
 *  MUpnpUdpServerObserver is used as interface-class for message delivery
 *  from CUpnpUdpServer to CUpnpSsdpServer
 *
 *  @since Series60 2.0
 */
class MUpnpUdpServerObserver
    {
public:
    // New functions

    /**
     * Notifies udp message reception
     * @param aMessage UDP message received
     */
    virtual void UdpMessageReceivedL( CUdpMessage* aMessage ) = 0;

    };

// CLASS DECLARATION

/**
 *  CUpnpUdpServer is a base class for CUpnpSsdpServer and it contains all
 *  "real" methods, as CUpnpSsdpServer contains logical functions.
 *
 *  @since Series60 2.0
 */
NONSHARABLE_CLASS(CUpnpUdpServer) : public CActive,
        public MUpnpMessageObserver
    {
public:
    // Constructors and destructor

    /**
     * C++ default constructor.
     * @param aSocketServ Pointer to SocketServer used.
     * @param aObserver Pointer to class derived from MUpnpUdpServerObserver.
     * Used for callbacks.
     * @param aListeningPort Listening port.
     * @return A new CUpnpUdpServer instance.
     */
    CUpnpUdpServer( RSocketServ* aSocketServ,
        MUpnpUdpServerObserver* aObserver, TInt aListeningPort );

    /**
     * Destructor.
     */
    ~CUpnpUdpServer();

public:
    // New functions

    /**
     * Returns ETrue if udp server stared, EFalse otherwise
     * @since Series60 3.2
     * @return stared flag
     */
    TBool IsStarted();

    /**
     * Active Object RunL.
     * @since Series60 2.0
     */
    void RunL();

    /**
     * Callback for RunL leave situations.
     * @since Series60 2.0
     * @param aError contains the error code that caused the RunL leave.
     * @return KErrNone.
     */
    TInt RunError( TInt aError );

    /**
     * Active Object DoCancel.
     * @since Series60 2.0
     */
    void DoCancel();

    /**
     * Starts to listen for address.
     * @since Series60 2.0
     */
    void OpenL();

    /**
     * Closes the server.
     * @since Series60 2.0
     */
    void Close();

    /**
     * Sets the server ready for receiving.
     * @since Series60 2.0
     */
    void ReceiveL();

    /**
     * Sends aBuffer to IP address anAddr.
     * @since Series60 2.0
     * @param aBuffer Buffer that is to be sent.
     * @param anAddr Address that aBuffer is to be sent.
     */
    void SendL( TDesC8& aBuffer, TInetAddr& anAddr );

    /**
     * Prepares server for receiving after sending.
     * @since Series60 2.0
     */
    void SendDoneL();

    /**
     * From MUpnpAddressObserver
     * This function will be invoke if IP Address of UPnP changes
     */
    IMPORT_C void AddressChangedL( TInetAddr& aAddr );

protected:

    // DATA TYPES
    enum TSsdpValidity
        {
        // Message is valid SSDP message.
        EMessageOk,
        // Message is missing some essential headers.
        EHeadersMissing,
        // Name of method is not "M-SEARCH".
        EHeaderNotMSearch,
        // Value of MX header is not numerical.
        EErrorInMxConversion,
        // Value of MX header not valid.
        EInvalidMXValue,
        // Value of MAN header not valid.
        EInvalidManHeader,
        // Value of ST header not valid.
        EInvalidStHeader,
        // Value of HOST header not valid.
        EInvalidHostHeader,
        // Message is not valid SSDP response.
        EBadSsdpResponse,
        // Value of CACHE-CONTROL header not valid.
        EInvalidCacheControlHeader
        };

    /**
     * Checks that given SSDP message is valid.
     * @since Series60 2.0
     * @param aMsg Message to validate.
     * @return Error code. KErrNone, if valid message.
     */
    TSsdpValidity ValidateSsdpMessageL( CUpnpSsdpMessage* aMsg );

    /**
     * Function gets called when message's timer expires.
     * @since Series60 2.0
     * @param aMessage Pointer to message that has expired.
     */
    void MessageExpiredL( CUpnpHttpMessage* aMessage );

    /**
     * Function ompares  two line ignoring number of space between elements
     * @since Series60 2.0
     * @param aValue current value
     * @param aPattern pattern value
     * @return true if equal, else false
     */
    TBool CompareLinesL( const TDesC8& aValue, const TDesC8& aPattern );

    /**
     * Sets socket option which  adds address to multicast group
     */
    void JoinMulticastGroupL();

    /**
     * Sets socket configuration specific to multicast server
     */
    void ApplyMulticastSocketSettingsL();

    /**
     * Sets socket common configuration
     */
    void ApplyCommonSocketSettingsL();

    /**
     * Open socket and starts receiving datagrams
     */
    void OpenSocketAndStartReceiveL();

    /**
     * Refresh IP address and change auto ip status accordingly
     */
    void RefreshLocalAddressInfo();

private:

    /**
     * Function continue procesing queued request or switch to receive mode
     * @since Series60 3.2
     */
    void RestartOrContinueProcessingL();

    /**
     * Function continue send procesing
     * @return ETrue if processing restarted
     * @since Series60 3.2
     */
    TBool RestartOrContinueSendProcessingL();

    /**
     * Function calculates MX value
     * @return MX value
     * @since Series60 3.2
     */
    TInt CalculateMxValue( const TDesC8& aMxString );

    /**
     * Function queues response for M-Serach message 
     * @param Message to be sent after timer elapse
     * @since Series60 MCL
     */
    void AddPendingTimerMessageL( CUpnpSsdpMessage* aMessage );

protected:

    /**
     * Used from CUpnpSsdpServer to construct the CUpnpUdpServer correctly.
     * @since Series60 2.0
     */
    void UdpConstructL();

    // DATA TYPES
    enum TState
        {
        EClosed,
        EOpen,
        EReceiving,
        ESending,
        ESendingTimer, // new state introduced to handle delay timer between sending messages
        ESendDone
        };

protected:

    // State of CUpnpUdpServer defined as TState
    TState iState;

    // Random seed that is used for generating random timeouts
    // for sending SSDP responses.
    TInt64 iRandomSeed;

    // Address of remote client returned by RSocket::RecvFrom() function
    TInetAddr iClientAddr;

    // Address of remote host, e.g. destination of message
    TInetAddr iSenderAddress;

    // Flags of UDP message
    TUint iMulticastFlags;

    // List of messages that are waiting to be sent.
    RPointerArray<CUpnpUdpSendRequest> iSendRequestList;

    // Pointer to observer, CUpnpSsdpServer
    MUpnpUdpServerObserver* iObserver;

    // Pointer to RSocketServer, that is used to bind
    // sockets
    RSocketServ* iSocketServ;

    // Socket that is used to receive (and send) SSDP messages.
    RSocket iSocket;

    // Port number of CUpnpUdpServer
    TUint iServerPort;

    // Buffer that is used for receiving messages.
    HBufC8* iMessage;

    // Pointer to receive buffer.
    TPtr8 iMessagePtr;

    // Buffer that is used for sending
    HBufC8* iSendMessage;

    // Array that holds list of messages which are waiting
    // for sending after their timers have expired.
    CArrayPtrSeg<CUpnpSsdpMessage>* iPendingTimerMessages;

    // IAP ID of the connection
    TInt iActiveIap;

    // Connection for opened sockets
    CUpnpConnectionManagerProxy* iConnectionManagerProxy;

    // Timer used to introduce delays to prevent from sending
    // SSDP messages more often than one in 20ms time period.
    RTimer iSendTimer;

    // indicate if server is started, socket was opened correctly
    TBool iIsStarted;

    //Local IP Address of Server
    TInetAddr iLocalInterfaceAddress;
    
    // If the interface goes to AutoIp address
    TBool iAutoIP;
    };

#endif // C_CUPNPUDPSERVER_H
// End of File