mtpfws/mtpfw/inc/cmtpparserrouter.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:11:40 +0200
changeset 0 d0791faffa3f
child 3 8b094906a049
permissions -rw-r--r--
Revision: 201003 Kit: 201005

// Copyright (c) 2006-2009 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:
//

/**
 @file
 @internalTechnology
*/

#ifndef CMTPPARSERROUTER_H
#define CMTPPARSERROUTER_H

#include <e32cmn.h>
#include <mtp/tmtptyperequest.h>

#include "cmtpdataprovidercontroller.h"
#include "mtpdebug.h"
#include "rmtpframework.h"

class CMTPConnection;
class CMTPDataProvider;
class MMTPConnection;
class TMTPTypeEvent;

/**
Implements the MTP framework parser/router singleton. 

The MTP framework parser/router singleton is responsible for directing received
MTP operation request (and event) datasets to the appropriate data provider(s) 
for processing, and performs the following major functions: 
    
    1.  Parses received operation request and event datasets to extract and 
        coarse grain validate routing data (@see ParseOperationRequestL).
    2.  Executes one or more routing algorithms to select the set of data 
        provider targets able to service the operation or event 
        (@see RouteOperationRequestL).
    3.  (Optionally) dispatches the request or event (@see ProcessRequestL).
    
There are two basic scenarios which the parser/router must handle, and a 
different set of APIs is provided for each. These scenarios are:

    1.  The initial routing of operations as they are first received. This 
        routing is initiated by the MTP framework using the @see ProcessRequestL 
        API. This API executes all three of the functions identified above.
    2.  The secondary routing of those operations which cannot be dispatched 
        directly. Either because they require the combined processing 
        capabilities of multiple data providers to produce an aggregated 
        response, or; because they cannot be routed using data available during
        the operation request phase and can only be routed to their final 
        target using data available during the operation data phase. This 
        secondary routing is performed by the MTP framework's proxy data 
        provider using the @see ParseOperationRequestL and 
        @see RouteOperationRequestL APIs. These APIs respectively execute the 
        first two functions identified above, which are separated in order to 
        allow additional information to be added to the routing data by the 
        proxy data provider. The third function identified above is not executed 
        in this scenario, since a very different dispatching mechanism must be 
        used by the proxy data provider. 

The parser/router implements a number of different routing algorithm types, 
some of which are further decomposed into sub-types to achieve a finer level of 
routing granularity and control. In combination these algorithms support the 
following general routing mechanisms:
    
    1.  Device - A subset of device oriented MTP operations are always 
        dispatched to the device data provider.
    2.  Proxy - A subset of MTP operations cannot be dispatched directly. 
        Either they require the combined processing capabilities of multiple 
        data providers to produce an aggregated response, or cannot be routed 
        using data available from the operation dataset alone. These operations
        are dispatched to the proxy data provider for additional processing. 
    3.  Object Handle - MTP object handles generated by the MTP framework are 
        encoded with a data provider identifier to efficiently route those MTP 
        operations which supply an object handle as a parameter.
    4.  StorageID - MTP storage identifiers generated by the MTP framework are 
        encoded with a data provider identifier to efficiently route those MTP 
        operations which supply a storage identifier as a parameter.
    5.  Operation Parameter - On being loaded each data provider supplies a set 
        of configuration data (MTP operation codes, event codes, object 
        property codes, device property codes, and storage system types) which 
        collectively define the set of MTP operation requests that it wishes to 
        receive.
    6.  Request Registration - Data providers may optionally register MTP 
        operation request datasets with the framework which, when subsequently 
        matched, will be routed to them. This mechanism is used to route those 
        MTP operation types which are paired to complete over two transaction 
        cycles (e.g. SendObjectInfo/SendObject). It may also be used to route 
        vendor extension operation requests.

The following routing algorithm types are implemeted:

    1.  Operation Parameter Routing

        Operation parameter routing is the primary routing mechanism and by 
        default is enabled for both initial and secondary proxy routing 
        scenarios. Operation parameter routing involves selecting one or more 
        data provider targets using routing data obtained from or related to 
        the supplied operation dataset parameters using one of the following 
        sub-types:
        
        o   Parameter lookup routing sub-types, which match operation dataset 
            parameter data with the set of supported capabilities registered 
            by each data provider on being loaded, or;
        o   Parameter decode routing sub-types, which extract data provider 
            target identifiers encoded into the parameter data itself.

        The parameter lookup routing sub-types are table driven and utilise 
        binary search techniques to minimise processing overhead. The 
        following parameter lookup routing sub-types (tables) are implemented,
        each characterised by the combination of parameters they require to map
        to a routing target:
        
        o   DevicePropCode
        o   ObjectPropCode
        o   OperationCode
        o   StorageType
        o   FormatCode + FormatSubcode
        o   FormatCode + OperationCode
        o   StorageType + OperationCode
        o   FormatCode + FormatSubcode + StorageType

        These routing tables may be further characterised by modifier flags 
        which e.g. allow or disallow duplicate entries, or specify ascending 
        or descending sort orders which in turn can manipulate the order in 
        which proxy targets are processed.

        The parameter decode routing sub-types extract routing target 
        identifiers directly from the operation dataset parameter data itself. 
        The following parameter decode routing sub-types are implemented:

        o   Object Handle
        o   StorageID
        
    2.  Framework Routing

        By default, framework routing is enabled during initial operation 
        routing only and not during secondary proxy routing. Framework routing 
        directs a sub-set of MTP operations to one or other of the framework 
        data providers. Using one of the following routing sub-types: 
        
        o   Device DP. A fixed sub-set of MTP operations are always dispatched 
            to the device data provider.
        o   Proxy DP. A fixed sub-set of MTP operations are always dispatched 
            to the proxy data provider. In addition, any operations which yield
            multiple routing targets will also be routed to the proxy data 
            provider.
            
    3.  Request Registration Routing

        By default, request registration routing is enabled during initial 
        operation routing only and not during secondary proxy routing. Data 
        providers may optionally register MTP operation request datasets with 
        the framework which, when subsequently matched, will be routed to them.
        This mechanism is used to process those MTP operation types which are 
        paired to complete over two transaction cycles (e.g. 
        SendObjectInfo/SendObject). It may also be used to route vendor 
        extension operation requests.

        Request registration routing does not implement any routing sub-types.

@internalTechnology
 
*/
class CMTPParserRouter : public CBase
    {
public:
        
    /**
    Defines the MTP operation routing parameter data, which is an output of the 
    parser/routers @see ParseOperationRequestL API and an input to the 
    @see RouteOperationRequestL API. 
    */
    class TRoutingParameters
        {
    public: 
    
        /**
        The routing parameter type identifiers. Note that not all parameter
        types may be defined, only those deemed necessary to route the 
        associated operation dataset.
        */
        enum TParameterType
            {
            /**
            The DevicePropCode parameter.
            */
            EParamDevicePropCode,
            
            /**
            The object FormatCode parameter.
            */
            EParamFormatCode,
            
            /**
            The object format sub-code parameter. This parameter is undefined 
            unless @see EFormatCode contains a value of 
            @see EMTPFormatCodeAssociation, in which case this parameter should
            the specify the MTP association type code.
            */
            EParamFormatSubCode,
            
            /**
            The ObjectHandle parameter.
            */
            EParamObjectHandle,
            
            /**
            The ObjectPropCode parameter.
            */
            EParamObjectPropCode,
            
            /**
            The StorageId parameter.
            */
            EParamStorageId,
            
            /**
            The storage system type parameter.
            */
            EParamStorageSystemType,
            
            /**
            The invalid dataset flag. When set, this flag indicates that an 
            operation dataset validation check failed.
            */
            EFlagInvalid,
            
            /**
            The routing type codes. This flag is intended for internal use 
            only.
            */
            EFlagRoutingTypes,
            
            /**
            The ServiceID parameter.
            */
            EParamServiceId,
            
            /**
            */
            ENumTypes
            };
        
    public: 
    
        IMPORT_C TRoutingParameters(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection);
        TRoutingParameters(const TRoutingParameters& aParams);
    
        IMPORT_C MMTPConnection& Connection() const;
        IMPORT_C TUint Param(TParameterType aId) const;
        IMPORT_C void Reset();
        IMPORT_C const TMTPTypeRequest& Request() const; 
        IMPORT_C void SetParam(TParameterType aId, TUint aVal);
        
    private: // Not owned
    
        /**
        The handle of the MTP connection on which the operation is being
        processed.
        */
        MMTPConnection&        			iConnection;
        
        /**
        The operation dataset.
        */
        const TMTPTypeRequest&			iRequest; 
        
    private: // Owned
    
        TUint                           iParameterData[ENumTypes];
        TFixedArray<TUint, ENumTypes>	iParameters;
        };

public:

    static CMTPParserRouter* NewL(); 
    virtual ~CMTPParserRouter();
    
    IMPORT_C void ConfigureL();
    IMPORT_C TBool OperationSupportedL(TUint16 aOperation) const;
    IMPORT_C void ParseOperationRequestL(TRoutingParameters& aParams) const;
    IMPORT_C void RouteOperationRequestL(const TRoutingParameters& aParams, RArray<TUint>& aTargets) const;
    IMPORT_C TBool RouteRequestRegisteredL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) const;
    
    void ProcessEventL(const TMTPTypeEvent& aEvent, CMTPConnection& aConnection) const;
    void ProcessRequestL(const TMTPTypeRequest& aRequest, CMTPConnection& aConnection) const;
    void RouteRequestRegisterL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection, TInt aId);
    void RouteRequestUnregisterL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection);

private: // Owned

    /**
    Defines the routing type codes. These codes are partitioned into 
    two sub-fields as follows:
    
        1.  Bits  0-15 - routing type identifier.
        2.	Bits 16-23 - unused.
        3.  Bits 24-31 - routing type modifier flags.
    */
    enum TRoutingType
        {
        /**
        The routing type modifier flags mask.
        */
        ETypeFlagMask            	= 0xFF000000,
        
        /**
        The single target flag. When set this flag will result in at most one
        eligible routing target being selected. If multiple eligible targets 
        exists then the first eligible target will be selected.
        */
        ETypeFlagSingleTarget       = 0x01000000,
        
        /**
        The routing type identifier mask.
        */
        ETypeMask                   = 0x0000FFFF,
        
        /**
        The framework routing type identifier.
        */
        ETypeFramework              = 0x00000001,
        
        /**
        The operation parameter routing type identifier.
        */
        ETypeOperationParameter		= 0x00000002,
        
        /**
        The request registration routing type identifier.
        */
        ETypeRequestRegistration	= 0x00000004,
        };
    
    /**
    Defines the routing sub-type codes. These codes are partitioned into 
    two sub-fields as follows:
    
        1.  Bits  0-15 - routing sub-type (map) index.
        2.  Bits 16-23 - routing sub-type modifier flags.
        3.  Bits 24-31 - routing sub-type parameter count type.
    */
    enum TRoutingSubType
        {
        /**
        The routing sub-type identifier (table index) mask.
        */
        ESubTypeIndexMask                        	= 0x0000FFFF,
        
        /**
        The routing sub-type modifier bit flags mask.
        */
        ESubTypeFlagMask                            = 0x00FF0000,
        
        /**
        The null flag bits.
        */
        ESubTypeFlagNone                            = 0x00000000,
        
        /**
        The duplicates enabled flag bits. When set this flag indicates that 
        duplicate routing table entries are permitted.
        */
        ESubTypeFlagEnableDuplicates                = 0x00010000,
        
        /**
        The order descending flag bits. When set this flag indicates that 
        routing table entries are to be arranged in descending rather than 
        ascending order.
        */
        ESubTypeFlagOrderDescending               	= 0x00020000,
        
        /**
        The routing sub-type parameter count mask.
        */
        ESubTypeParamsMask                       	= 0xFF000000,
        
        /**
        The zero parameter count code.
        */
        ESubTypeParams0                           	= 0x00000000,
        
        /**
        The one parameter count code.
        */
        ESubTypeParams1                          	= 0x01000000,
        
        /**
        The two parameter count code.
        */
        ESubTypeParams2                           	= 0x02000000,
        
        /**
        The three parameter count code.
        */
        ESubTypeParams3                           	= 0x03000000,
        
        /**
        The DevicePropCode operation parameter lookup routing sub-type.
        */
        ESubTypeDevicePropCode                  	= (0x00000000 | ESubTypeParams1 | ESubTypeFlagNone),
        
        /**
        The ObjectPropCode operation parameter lookup routing sub-type.
        */
        ESubTypeObjectPropCode                   	= (0x00000001 | ESubTypeParams1 | ESubTypeFlagEnableDuplicates),
        
        /**
        The OperationCode operation parameter lookup routing sub-type.
        */
        ESubTypeOperationCode                    	= (0x00000002 | ESubTypeParams1 | ESubTypeFlagEnableDuplicates),
        
        /**
        The StorageType operation parameter lookup routing sub-type.
        */
        ESubTypeStorageType                     	= (0x00000003 | ESubTypeParams1 | ESubTypeFlagEnableDuplicates),
        
        /**
        The FormatCode + FormatSubcode operation parameter lookup routing 
        sub-type.
        */
        ESubTypeFormatCodeFormatSubcode          	= (0x00000004 | ESubTypeParams2 | (ESubTypeFlagEnableDuplicates | ESubTypeFlagOrderDescending)),
        
        /**
        The FormatCode + OperationCode operation parameter lookup routing 
        sub-type.
        */
        ESubTypeFormatCodeOperationCode          	= (0x00000005 | ESubTypeParams2 | ESubTypeFlagEnableDuplicates),
        
        /**
        The StorageType + OperationCode operation parameter lookup routing 
        sub-type.
        */
        ESubTypeStorageTypeOperationCode            = (0x00000006 | ESubTypeParams2 | ESubTypeFlagEnableDuplicates),
        
        /**
        The FormatCode + FormatSubcode + StorageType operation parameter 
        lookup routing sub-type.
        */
        ESubTypeFormatCodeFormatSubcodeStorageType	= (0x00000007 | ESubTypeParams3 | ESubTypeFlagNone),
        
        /**
        The ServiceID operation parameter lookup routing sub-type.
        */
        ESubTypeServiceIDOperationCode              = (0x00000008 | ESubTypeParams1 | ESubTypeFlagNone),
        
        /**
        The device DP framework routing sub-type.
        */
        ESubTypeDpDevice                            = (0x00000009 | ESubTypeParams0 | ESubTypeFlagNone),
        
        /**
        The proxy DP framework routing sub-type.
        */
        ESubTypeDpProxy                         	= (0x0000000A | ESubTypeParams0 | ESubTypeFlagNone),
        
        /**
        The object owner operation parameter decode routing sub-type.
        */
        ESubTypeOwnerObject                     	= (0x0000000B | ESubTypeParams0 | ESubTypeFlagNone),
        
        /**
        The storage owner operation parameter decode routing sub-type.
        */
        ESubTypeOwnerStorage                        = (0x0000000C | ESubTypeParams0 | ESubTypeFlagNone),
        
        /**
        The default request registration routing sub-type.
        */
        ESubTypeRequestRegistration             	= (0x0000000D | ESubTypeParams0 | ESubTypeFlagNone),
        
        };
        
    /**
    Defines the routing parameter IDs.
    */
    enum TRoutingParams
        {
        /**
        The first parameter.
        */
        EParam1 = 0,
        
        /**
        The second parameter.
        */
        EParam2 = 1
        
        /**
        The third parameter.
        */,
        EParam3 = 2,
        };

    /**
    Implements a simple single parameter map table entry which associates a 
    single routing parameter value and target data provider identifier pair. 
    */
    class TMap
        {
    public:
    
        TMap(TUint aFrom);
        TMap(TUint aFrom, TUint aTo, TUint aSubType);
    
    public:
    
        /**
        The routing parameter.
        */
        TUint   iFrom;
        
        /**
        The routing table sub-type code.
        */
        TUint   iSubType;
    
        /**
        The routing target data provider identifier.
        */
        TUint	iTo;
        };

    /**
    Implements a generic, multi-parameter routing table data structure. This 
    table implements owns EITHER:

        1.  A container of @see TMap node objects if implementing a single 
            parameter table or the final level (n) of a multi-parameter table,
            OR;
        2.  A container of @see CMap branch objects if implementing an 
            intermediate level (1 .. n-1) of a multi-parameter table.
    */
    class CMap : public CBase
        {            
    public:
    
        static CMap* NewLC(TUint aSubType);
        ~CMap();
        
        TUint From() const;
        void InitParamsL(RArray<TUint>& aFrom) const;
        void InsertL(const RArray<TUint>& aFrom, TUint aTo);
        void GetToL(const RArray<TUint>& aFrom, RArray<TUint>& aTo) const;
        TUint SubType() const;
        
#ifdef __FLOG_ACTIVE
        void FLOGMapL(RArray<TUint>& aFrom) const;
        void FLOGMapEntryL(const RArray<TUint>& aFrom, TUint aTo) const;
#endif
        
    private:
    
        static CMap* NewLC(TUint aFrom, TUint aSubType);
        CMap(TUint aFrom, TUint aSubType);
        void ConstructL();
        
        TInt BranchFind(TUint aFrom) const;
        TUint BranchInsertL(TUint aFrom);
        TInt NodeFind(TUint aFrom) const;
        TInt NodeFind(const TMap& aNode) const;
        TUint NodeInsertL(const TMap& aMap);
        TUint Param(const RArray<TUint>& aFrom) const;
        TUint ParamIdx(const RArray<TUint>& aFrom) const;
        void SelectTargetAllL(const RArray<TUint>& aFrom, RArray<TUint>& aTo) const;
        void SelectTargetMatchingL(const RArray<TUint>& aFrom, RArray<TUint>& aTo) const;
        void SelectTargetSingleL(const RArray<TUint>& aFrom, RArray<TUint>& aTo) const;
        
        static TInt BranchOrderFromAscending(const CMap& aL, const CMap& aR);
        static TInt BranchOrderFromDescending(const CMap& aL, const CMap& aR);
        static TInt BranchOrderFromKeyAscending(const TUint* aL, const CMap& aR);
        static TInt BranchOrderFromKeyDescending(const TUint* aL, const CMap& aR);
        static TInt NodeOrderFromAscending(const TMap& aL, const TMap& aR);
        static TInt NodeOrderFromDescending(const TMap& aL, const TMap& aR);
        static TInt NodeOrderFromKeyAscending(const TUint* aL, const TMap& aR);
        static TInt NodeOrderFromKeyDescending(const TUint* aL, const TMap& aR);
        static TInt NodeOrderFromToAscending(const TMap& aL, const TMap& aR);
        static TInt NodeOrderFromToDescending(const TMap& aL, const TMap& aR);
        
    private:

        /**
        FLOGGER debug trace member variable.
        */
        __FLOG_DECLARATION_MEMBER_MUTABLE;
 
        /**
        The routing parameter.
        */
        TUint               iFrom;
        
        /**
        The routing table sub-type code.
        */
        TUint               iSubType;
        
        /**
        The @see CMap branch object container. This container is only populated
        if implementing an intermediate level (1 .. n-1) of a multi-parameter 
        table.
        */
        RPointerArray<CMap> iToBranches;
        
        /**
        The @see TMap node object container. This container is only populated 
        if implementing a single parameter table or the final level (n) of a 
        multi-parameter table.
        */
        RArray<TMap>        iToNodes;
        };
    
private:
    
    CMTPParserRouter();
    void ConstructL();
    
    static void GetMapParameterIdsL(TUint aSubType, RArray<TUint>& aP1Codes, RArray<TUint>& aP2Codes, RArray<TUint>& aP3Codes);
    static void SelectTargetL(TUint aTarget, RArray<TUint>& aTargets);
    
    void Configure1ParameterMapL(TUint aSubType, const RArray<TUint>& aP1Codes);
    void Configure2ParameterMapL(TUint aSubType, const RArray<TUint>& aP1Codes, const RArray<TUint>& aP2Codes);
    void Configure3ParameterMapL(TUint aSubType, const RArray<TUint>& aP1Codes, const RArray<TUint>& aP2Codes, const RArray<TUint>& aP3Codes);
    void GetConfigParametersL(const CMTPDataProvider& aDp, const RArray<TUint>& aCodes, RArray<TUint>& aParams) const;
    void GetRoutingSubTypesL(RArray<TRoutingParameters>& aParams, RArray<TUint>& aRoutingSubTypes, RArray<TUint>& aValidationSubTypes) const;
    void GetRoutingSubTypesDeleteRequestL(RArray<TRoutingParameters>& aParams, RArray<TUint>& aRoutingSubTypes, RArray<TUint>& aValidationSubTypes) const;
    void GetRoutingSubTypesCopyMoveRequestL(RArray<TRoutingParameters>& aParams, RArray<TUint>& aRoutingSubTypes, RArray<TUint>& aValidationSubTypes) const;
    void GetRoutingSubTypesGetObjectPropListRequestL(RArray<TRoutingParameters>& aParams, RArray<TUint>& aRoutingSubTypes, RArray<TUint>& aValidationSubTypes) const;
    void GetRoutingSubTypesSendObjectPropListRequestL(RArray<TRoutingParameters>& aParams, RArray<TUint>& aRoutingSubTypes, RArray<TUint>& aValidationSubTypes) const;
    void GetRoutingSubTypesDeleteObjectPropListL(RArray<TRoutingParameters>& aParams, RArray<TUint>& aRoutingSubTypes, RArray<TUint>& aValidationSubTypes) const;
    void GetRoutingSubTypesGetFormatCapabilitiesL(RArray<TRoutingParameters>& aParams, RArray<TUint>& aRoutingSubTypes, RArray<TUint>& aValidationSubTypes) const;
    void ParseOperationRequestParameterL(TMTPTypeRequest::TElements aParam, TRoutingParameters::TParameterType aType, TRoutingParameters& aParams) const;
    void RouteOperationRequestNParametersL(TUint aRoutingSubType, const TRoutingParameters& aParams, RArray<TUint>& aTargets) const;
    void RouteOperationRequest0ParametersL(TUint aRoutingSubType, const TRoutingParameters& aParams, RArray<TUint>& aTargets) const;
    TUint RoutingTargetL(const TMTPTypeRequest& aRequest, CMTPConnection& aConnection) const;
    void SelectSubTypeRoutingL(TRoutingSubType aSubType, RArray<TUint>& aRoutingSubTypes, RArray<TUint>& aValidationSubTypes, RArray<TRoutingParameters>& aParams) const; 
    void SelectSubTypeValidationL(TRoutingSubType aSubType, RArray<TUint>& aValidationSubTypes) const;
    void ValidateTargetsL(const TRoutingParameters& aParams, const RArray<TUint>& aValidationSubTypes, RArray<TUint>& aTargets) const;

    static TUint Flags(TUint aSubType);
    static TUint Index(TUint aSubType);
    static TUint Params(TUint aSubType);
    static TUint ParamsCount(TUint aSubType);
    static TUint SubType(TUint aIndex, TUint aFlags, TUint aParamsCount);
    
#ifdef __FLOG_ACTIVE
    void FLOGMapsL() const;
#endif

private: // Owned

    /**
    FLOGGER debug trace member variable.
    */
    __FLOG_DECLARATION_MEMBER_MUTABLE;
    
    /**
    The operation parameter routing sub-type map tables.
    */
    RPointerArray<CMap> iMaps;
    
    /**
    The framework singletons.
    */
    RMTPFramework       iSingletons;
    };

#endif // CMTPPARSERROUTER_H