williamr@2: // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). williamr@2: // All rights reserved. williamr@2: // This component and the accompanying materials are made available williamr@4: // under the terms of "Eclipse Public License v1.0" williamr@2: // which accompanies this distribution, and is available williamr@4: // at the URL "http://www.eclipse.org/legal/epl-v10.html". williamr@2: // williamr@2: // Initial Contributors: williamr@2: // Nokia Corporation - initial contribution. williamr@2: // williamr@2: // Contributors: williamr@2: // williamr@2: // Description: williamr@2: // williamr@2: williamr@2: /** williamr@2: @file williamr@2: @publishedAll williamr@2: @released williamr@2: */ williamr@2: williamr@2: #ifndef REMCONINTERFACESELECTOR_H williamr@2: #define REMCONINTERFACESELECTOR_H williamr@2: williamr@2: #include williamr@2: #include williamr@2: #include williamr@4: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: class CRemConInterfaceBase; williamr@4: class CBulkReceiver; williamr@2: class CReceiver; williamr@2: class MRemConErrorObserver; williamr@4: class RRemConInterfaceFeatures; williamr@4: class RSpecificThreadCallBack; williamr@4: class CRemConInterfaceDetailsArray; williamr@4: class RNestableLock; williamr@4: class RRemConController; williamr@4: class RRemConTarget; williamr@4: class RRemConBulk; williamr@4: class RRemCon; williamr@2: williamr@2: // Panic information williamr@2: _LIT(KRemConIfSelPanicCat, "RemConIfSel"); williamr@2: enum williamr@2: { williamr@2: /** The client has given a bad message type. */ williamr@2: ERemConIfSelBadMessageType = 0, williamr@2: williamr@2: /** The client has already called OpenTargetL successfully. williamr@2: williamr@2: This is no longer an illegal condition and so the panic will never williamr@2: be raised. williamr@2: */ williamr@2: ERemConIfSelTargetSessionAlreadyExists = 1, williamr@2: williamr@2: /** The client has already called OpenControllerL successfully. williamr@2: williamr@2: This is no longer an illegal condition and so the panic will never williamr@2: be raised. williamr@2: */ williamr@2: ERemConIfSelControllerSessionAlreadyExists = 2, williamr@2: williamr@2: /** The client has created (and registered) an outer layer interface of a williamr@2: type which is already registered. */ williamr@2: ERemConIfSelInterfaceOfThatTypeAlreadyRegistered = 3, williamr@2: williamr@2: /** The client has not offended- there is a defect in some layer of the williamr@2: Remote Control system. */ williamr@2: ERemConIfSelInternalError = 4, williamr@2: williamr@2: /** An outer-layer interface has been instantiated (and registered with williamr@2: the intermediate layer) after OpenControllerL or OpenTargetL has been williamr@2: successfully called. */ williamr@2: ERemConIfSelTardyInterfaceRegistration = 5, williamr@2: williamr@2: /** OpenControllerL has not successfully been called before using an API williamr@2: which expects a controller session to have been created. */ williamr@2: ERemConIfSelNoControllerSession = 6, williamr@2: williamr@2: /** OpenTargetL has not successfully been called before using an API which williamr@2: expects a target session to have been created. */ williamr@2: ERemConIfSelNoTargetSession = 7, williamr@2: williamr@2: /** Neither OpenControllerL not OpenTargetL has been successfully called williamr@2: before using an API which expects either a controller or a target session williamr@2: to have been created. */ williamr@2: ERemConIfSelNoSession = 8, williamr@2: williamr@2: /** An outer layer DLL has instantiated CRemConInterfaceBase with an williamr@2: illegal client type. */ williamr@2: ERemConIfSelUndefinedClientType = 9, williamr@2: williamr@2: /** An implementation of CRemConInterfaceBase::GetInterface does not williamr@2: provide an implementation of MRemConInterfaceIf. */ williamr@2: ERemConIfSelNoInterfaceImplementation = 10, williamr@4: williamr@4: /** A client has created bulk interfaces in multiple different threads, williamr@4: all bulk interfaces must be created in the same thread*/ williamr@4: ERemConIfSelMultipleBulkInterfaceThreads = 11, williamr@2: }; williamr@2: williamr@2: /** williamr@2: CRemConInterfaceSelector is only instantiable via its NewL function. It is not williamr@2: derivable. williamr@2: */ williamr@2: NONSHARABLE_CLASS(CRemConInterfaceSelector) : public CBase williamr@2: { williamr@2: public: williamr@2: /** williamr@2: Factory method. williamr@2: @return Ownership of a new CRemConInterfaceSelector. williamr@2: */ williamr@2: IMPORT_C static CRemConInterfaceSelector* NewL(); williamr@2: williamr@2: /** Destructor. */ williamr@2: IMPORT_C ~CRemConInterfaceSelector(); williamr@2: williamr@2: public: williamr@2: /** williamr@2: Register the interface with the selector. This is called by the williamr@2: interface's BaseConstructL. Takes ownership of aInterface. williamr@2: This function is not to be called outside of remconinterfacebase.dll. It is available for compatibility with previous williamr@2: versions, but it is intended to be called only by CRemConInterfaceBase::BaseConstructL. williamr@2: CRemConInterfaceBase-derived classes should indirectly perform a RegisterInterfaceL, by calling williamr@2: CRemConInterfaceBase::BaseConstructL from their construction functions. williamr@2: @param aInterface The interface. williamr@2: */ williamr@2: IMPORT_C void RegisterInterfaceL(CRemConInterfaceBase& aInterface); williamr@2: williamr@4: /** williamr@4: Register the interface with the selector. This is called by the williamr@4: interface's BaseConstructL. Takes ownership of aInterface. williamr@4: This function is not to be called outside of remconinterfacebase.dll. It is available for compatibility with previous williamr@4: versions, but it is intended to be called only by CRemConInterfaceBase::BaseConstructL. williamr@4: CRemConInterfaceBase-derived classes should indirectly perform a RegisterInterfaceL, by calling williamr@4: CRemConInterfaceBase::BaseConstructL from their construction functions. williamr@4: @param aInterface The interface. williamr@4: @param aRemConInterfaceFeatures The operation IDs of the interface. Ownership is retained by the caller. Any necessary williamr@4: data will be copied by the interface selector. williamr@4: */ williamr@4: void RegisterInterfaceL(CRemConInterfaceBase& aInterface, RRemConInterfaceFeatures& aRemConInterfaceFeatures); williamr@2: /** williamr@2: Register an error observer. This is provided to allow the client to williamr@2: discover when an error has occurred passively. williamr@2: williamr@2: @param aObserver An error observer to be notified on a passive error. williamr@2: NULL to stop receiving notifications. williamr@2: */ williamr@2: IMPORT_C void RegisterErrorObserver(MRemConErrorObserver* aObserver); williamr@2: williamr@2: /** williamr@2: Opens a controller session to RemCon. The session is connectionless until williamr@2: such time as GoConnectionOriented may be called. williamr@2: @leave KErrInUse If a controller session is already open. williamr@2: */ williamr@2: IMPORT_C void OpenControllerL(); williamr@2: williamr@2: /** williamr@2: Makes the controller session (which must already exist- use williamr@2: OpenControllerL) connection-oriented. williamr@2: @param aConnection The remote to talk to. williamr@2: */ williamr@2: IMPORT_C void GoConnectionOrientedL(const TRemConAddress& aConnection); williamr@2: williamr@2: /** williamr@2: Makes the controller session (which must already exist- use williamr@2: OpenControllerL) connectionless. williamr@2: */ williamr@2: IMPORT_C void GoConnectionlessL(); williamr@2: williamr@2: /** williamr@2: Brings up a bearer-level connection. williamr@2: The controller session must already exist (use OpenControllerL) and williamr@2: be connection-oriented. williamr@2: @param aStatus TRequestStatus for asynchronous completion. williamr@2: */ williamr@2: IMPORT_C void ConnectBearer(TRequestStatus& aStatus); williamr@2: williamr@2: /** williamr@2: Cancels interest in the completion of a ConnectBearer request. williamr@2: @return KErrNone. williamr@2: */ williamr@2: IMPORT_C TInt ConnectBearerCancel(); williamr@2: williamr@2: /** williamr@2: Destroys a bearer-level connection. williamr@2: The controller session must already exist (use OpenControllerL) and be williamr@2: connection-oriented. williamr@2: @param aStatus TRequestStatus for asynchronous completion. williamr@2: */ williamr@2: IMPORT_C void DisconnectBearer(TRequestStatus& aStat); williamr@2: williamr@2: /** williamr@2: Cancels interest in the completion of a DisconnectBearer request. williamr@2: @return KErrNone. williamr@2: */ williamr@2: IMPORT_C TInt DisconnectBearerCancel(); williamr@2: williamr@2: /** williamr@2: Opens a target session to RemCon. williamr@2: @leave KErrInUse If a target session is already open. williamr@2: */ williamr@2: IMPORT_C void OpenTargetL(); williamr@2: williamr@2: /** williamr@4: Opens a target session to RemCon. williamr@4: @param aPlayerType The type of player williamr@4: @param aPlayerSubType The sub-type of the player williamr@4: @param aPlayerName The name of the player in UTF-8. williamr@4: @leave KErrInUse If a target session is already open. williamr@4: */ williamr@4: IMPORT_C void OpenTargetL(TPlayerType aPlayerType, TPlayerSubType aPlayerSubType, const TDesC8& aPlayerName); williamr@4: /** williamr@2: Sends a message to the remote device(s). williamr@2: There should be only one command and response outstanding at any one time. williamr@2: Send cannot be called again until aStatus is completed. williamr@2: @panic RemConClient 4 If a send is already outstanding williamr@2: @param aStatus TRequestStatus for asynchronous completion. williamr@2: @param aInterfaceUid The UID of the concrete (outer-layer) interface williamr@2: sending the message. williamr@2: @param aOperationId The interface-specific operation identifier. williamr@2: @param aNumRemotes On success, the number of remotes the message was williamr@2: successfully sent to. williamr@2: @param aMsgType Whether the message is a command or a response. williamr@2: @param aData Any associated message data in interface-specific format. williamr@2: */ williamr@2: IMPORT_C void Send(TRequestStatus& aStatus, williamr@2: TUid aInterfaceUid, williamr@2: TUint aOperationId, williamr@2: TUint& aNumRemotes, williamr@2: TRemConMessageType aMsgType, williamr@2: const TDesC8& aData = KNullDesC8()); williamr@2: williamr@2: /** williamr@2: Sends a message to the remote device(s). williamr@2: @param aStatus TRequestStatus for asynchronous completion. williamr@2: @param aInterfaceUid The UID of the concrete (outer-layer) interface williamr@2: sending the message. williamr@2: @param aOperationId The interface-specific operation identifier. williamr@2: @param aNumRemotes On success, the number of remotes the message was williamr@2: successfully sent to. williamr@2: @param aMsgType Whether the message is a command or a response. williamr@2: @param aMsgSubType The subtype of the command of response williamr@2: @param aData Any associated message data in interface-specific format. williamr@2: */ williamr@2: IMPORT_C void Send(TRequestStatus& aStatus, williamr@2: TUid aInterfaceUid, williamr@2: TUint aOperationId, williamr@2: TUint& aNumRemotes, williamr@2: TRemConMessageType aMsgType, williamr@2: TRemConMessageSubType aMsgSubType, williamr@2: const TDesC8& aData = KNullDesC8()); williamr@2: williamr@4: /** williamr@4: Sends a williamr@4: */ williamr@4: IMPORT_C void SendNotify(TRequestStatus& aStatus, williamr@4: TUid aInterfaceUid, williamr@4: TUint aOperationId, williamr@4: TRemConMessageType aMsgType, williamr@4: TRemConMessageSubType aMsgSubType, williamr@4: const TDesC8& aData = KNullDesC8()); williamr@2: williamr@2: /** williamr@4: This method is for internal sub-system use only and should be not be used otherwise. williamr@2: Sends a message to the remote device(s), without waiting for the send to complete williamr@2: @param aInterfaceUid The UID of the concrete (outer-layer) interface williamr@2: sending the message. williamr@2: @param aOperationId The interface-specific operation identifier. williamr@2: @param aMsgType Whether the message is a command or a response. williamr@2: @param aData Any associated message data in interface-specific format. williamr@2: */ williamr@2: IMPORT_C TInt SendUnreliable( williamr@2: TUid aInterfaceUid, williamr@2: TUint aOperationId, williamr@2: TRemConMessageType aMsgType, williamr@2: const TDesC8& aData = KNullDesC8()); williamr@2: williamr@2: /** williamr@4: This method is for internal sub-system use only and should be not be used otherwise. williamr@2: Sends a message to the remote device(s), without waiting for the send to complete williamr@2: @param aInterfaceUid The UID of the concrete (outer-layer) interface williamr@2: sending the message. williamr@2: @param aOperationId The interface-specific operation identifier. williamr@2: @param aMsgType Whether the message is a command or a response. williamr@2: @param aMsgSubType The subtype of the command of response williamr@2: @param aData Any associated message data in interface-specific format. williamr@2: */ williamr@2: IMPORT_C TInt SendUnreliable( williamr@2: TUid aInterfaceUid, williamr@2: TUint aOperationId, williamr@2: TRemConMessageType aMsgType, williamr@2: TRemConMessageSubType aMsgSubType, williamr@2: const TDesC8& aData = KNullDesC8()); williamr@2: williamr@2: /** williamr@2: Cancels interest in the completion of a Send request. williamr@2: @param aMsgType The type of the message, the completion of the send of williamr@2: which we are not interested in. This is needed because a single williamr@2: CRemConInterfaceSelector may have two sends outstanding at once, one on williamr@2: a controller session and another on a target session. williamr@2: @return KErrNone. williamr@2: */ williamr@2: IMPORT_C TInt SendCancel(TRemConMessageType aMsgType); williamr@4: williamr@4: /** williamr@4: This method is for internal sub-system use only and should be not be used otherwise. williamr@4: Sends a message to the remote device(s) through the bulk path. williamr@4: There should be only one response outstanding at any one time. williamr@4: Send cannot be called again until aStatus is completed. williamr@4: @panic RemConClient 4 If a send is already outstanding williamr@4: @param aStatus TRequestStatus for asynchronous completion. williamr@4: @param aInterfaceUid The UID of the concrete (outer-layer) interface williamr@4: sending the message. williamr@4: @param aOperationId The interface-specific operation identifier. williamr@4: @param aData Any associated message data in interface-specific format. williamr@4: */ williamr@4: IMPORT_C void SendBulk(TRequestStatus& aStatus, williamr@4: TUid aInterfaceUid, williamr@4: TUint aOperationId, williamr@4: const TDesC8& aData = KNullDesC8()); williamr@4: williamr@4: /** williamr@4: This method is for internal sub-system use only and should be not be used otherwise. williamr@4: Sends a message to the remote device(s) through the bulk path, without williamr@4: waiting for the send to complete. williamr@4: @param aInterfaceUid The UID of the concrete (outer-layer) interface williamr@4: sending the message. williamr@4: @param aOperationId The interface-specific operation identifier. williamr@4: @param aData Any associated message data in interface-specific format. williamr@4: */ williamr@4: IMPORT_C TInt SendBulkUnreliable( williamr@4: TUid aInterfaceUid, williamr@4: TUint aOperationId, williamr@4: const TDesC8& aData = KNullDesC8()); williamr@4: williamr@4: /** williamr@4: This method is for internal sub-system use only and should be not be used otherwise. williamr@4: Cancels interest in the completion of a BulkSend request. williamr@4: @return KErrNone. williamr@4: */ williamr@4: IMPORT_C TInt SendBulkCancel(); williamr@2: williamr@2: /** williamr@2: Only called internally, by the Active Object which sucks messages out of williamr@2: RemCon. Note that the message type is not given- it is interpolated from williamr@2: the type of the session doing the receiving. williamr@2: @param aInterfaceUid Interface UID of the new message. williamr@2: @param aOperationId Operation ID of the new message. williamr@4: @param aMsgSubType The message subtype. williamr@4: @param aRemoteAddress The address of the remote which sent the message. williamr@2: @param aData Data associated with the new message. williamr@2: @param aType The type of session which received the message (from which williamr@2: the type of the message can be interpolated). williamr@2: */ williamr@2: void ReceiveComplete(TUid aInterfaceUid, williamr@2: TUint aOperationId, williamr@2: TRemConMessageSubType aMsgSubType, williamr@4: const TRemConAddress& aRemoteAddress, williamr@2: const TDesC8& aData, williamr@2: TRemConClientType aType); williamr@4: williamr@4: /** williamr@4: Only called internally, by the Active Object which sucks messages out of williamr@4: RemCon. Note that the message type is not given- it is interpolated from williamr@4: the type of the session doing the receiving. williamr@4: @param aInterfaceUid Interface UID of the new message. williamr@4: @param aOperationId Operation ID of the new message. williamr@4: @param aData Data associated with the new message. williamr@4: */ williamr@4: void BulkReceiveComplete(TUid aInterfaceUid, williamr@4: TUint aOperationId, williamr@4: const TDesC8& aData); williamr@2: williamr@2: /** williamr@2: Only called internally, by the Active Object which sucks messages out of williamr@2: RemCon. This is called in the case of a session error. williamr@2: williamr@2: @param The error that has occurred. If this is KErrServerTerminated, the williamr@2: error is fatal and the session must be restarted before any new williamr@2: messages can be received. williamr@2: */ williamr@2: void Error(TInt aError); williamr@4: williamr@4: /** williamr@4: Only called internally, by the Active Object which sucks messages out of williamr@4: RemCon Bulk Server. This is called in the case of a session error. williamr@4: williamr@4: @param The error that has occurred. If this is KErrServerTerminated, the williamr@4: error is fatal and the session must be restarted before any new williamr@4: messages can be received. williamr@4: */ williamr@4: void BulkError(TInt aError); williamr@4: williamr@4: /** williamr@4: Only called internally, by the Active Object which sucks messages out of williamr@4: RemCon (bulk server). williamr@4: */ williamr@4: void BulkSessionConnectL(); williamr@2: williamr@2: /** williamr@2: Getter for the current set of connections in the system (not just those williamr@2: associated with this session). The client is responsible for cleaning up williamr@2: aConnections- the addresses will be on the heap. williamr@2: @param aConnections A collection of remote addresses, representing all the williamr@2: currently extant connections. williamr@2: @return Error. williamr@2: */ williamr@2: IMPORT_C TInt GetConnections(TSglQue& aConnections); williamr@2: williamr@2: /** williamr@2: Notification for changes in the set of connections. williamr@2: @param aStatus TRequestStatus for asynchronous completion. williamr@2: */ williamr@2: IMPORT_C void NotifyConnectionsChange(TRequestStatus& aStatus); williamr@2: williamr@2: /** williamr@2: Cancels interest in the completion of an outstanding williamr@2: NotifyConnectionsChange operation. williamr@2: @return KErrNone. williamr@2: */ williamr@2: IMPORT_C TInt NotifyConnectionsChangeCancel(); williamr@2: williamr@2: /** williamr@2: To determine if a target session has been opened. williamr@2: @return EFalse if no session has been opened, ETrue otherwise. williamr@2: */ williamr@2: IMPORT_C TBool TargetOpened() const; williamr@2: williamr@2: /** williamr@2: To determine if a controller session has been opened. williamr@2: @return EFalse if no session has been opened, ETrue otherwise. williamr@2: */ williamr@2: IMPORT_C TBool ControllerOpened() const; williamr@2: williamr@2: private: williamr@2: CRemConInterfaceSelector(); williamr@4: void ConstructL(); williamr@2: williamr@2: private: // utility williamr@2: void AssertSession(RRemCon* aSess, TInt aPanicCode) const; williamr@2: TInt TryToReconnect(); williamr@4: TInt TryToReconnectBulk(); williamr@4: void OpenTargetCommonL(); williamr@4: void RegisterInterfaceCommonL(CRemConInterfaceBase& aInterface, const TDesC8& aFeatures); williamr@4: void RegisterInterestedApisL(TRemConClientType aType); williamr@4: williamr@4: void EstablishBulkThreadBindingL(); williamr@4: williamr@4: static TInt StaticBulkCleanup(TAny* aSelf); williamr@4: void BulkCleanup(); williamr@4: TBool BulkOpened() const; williamr@2: williamr@2: private: // owned williamr@4: CRemConInterfaceDetailsArray* iInterfaces; williamr@2: williamr@4: RRemConController* iControllerSession; williamr@4: RRemConTarget* iTargetSession; williamr@4: RRemConBulk* iBulkSession; williamr@2: williamr@2: CReceiver* iTargetReceiver; williamr@2: CReceiver* iControllerReceiver; williamr@4: CBulkReceiver* iBulkReceiver; williamr@2: williamr@2: /** For all registered interfaces, this is the size of the biggest williamr@2: operation-associated data lump. */ williamr@4: TUint iControlMaxDataLength; williamr@4: TUint iBulkMaxDataLength; williamr@2: williamr@2: // The session to use for NotifyConnectionsChange and williamr@2: // NotifyConnectionsChangeCancel. It doesn't matter which we use- just one williamr@2: // that's connected will do. The only interesting bit is that the session williamr@2: // we called NotifyConnectionsChange on should be the one we call williamr@2: // NotifyConnectionsChangeCancel on, but as sessions are only closed when williamr@2: // 'this' comes down that's not a complication. williamr@2: RRemCon* iNotificationSession; williamr@2: williamr@2: TRemConAddress iAddress; williamr@4: williamr@4: RHeap* iBulkHeap; williamr@4: RThread iBulkThread; williamr@4: RHeap* iSharedThreadHeap; williamr@4: RSpecificThreadCallBack* iBulkCleanupCall; williamr@4: RNestableLock* iLock; williamr@2: private: // unowned williamr@2: MRemConErrorObserver* iErrorObserver; williamr@2: }; williamr@2: williamr@2: #endif // REMCONINTERFACESELECTOR_H