diff -r 6b1d113cdff3 -r 6638e7f4bd8f telephonyprotocols/secondarypdpcontextumtsdriver/spudman/src/mux.cpp --- a/telephonyprotocols/secondarypdpcontextumtsdriver/spudman/src/mux.cpp Mon May 03 13:37:20 2010 +0300 +++ b/telephonyprotocols/secondarypdpcontextumtsdriver/spudman/src/mux.cpp Thu May 06 15:10:38 2010 +0100 @@ -1,375 +1,375 @@ -// Copyright (c) 2004-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: -// SPUD data multiplexer -// -// - -/** - @file - @internalComponent -*/ - -#include "mux.h" -#include -#include - -// Flow control constants expected by the upper protocol stack -const TInt KStopSending = 0; -const TInt KContinueSending = 1; - -#ifdef __FLOG_ACTIVE -#define SPUDMUX_LOG(x) iBindMan->SpudMan()->x -#else -#define SPUDMUX_LOG(x) -#endif - - -// -// CSpudMux -// - - -CSpudMux::CSpudMux(CSpudMan& aNifBase) - : CNifIfBase(aNifBase) - { - } - -CSpudMux::~CSpudMux() - { - // Notify BindMan to delete the pointer to this object - if (iBindMan) - { - iBindMan->MuxClosed(); - } - } - -/** -Constructs the mux object - -@param aBindMan Reference to BindMan object -*/ -void CSpudMux::Construct(CBindMan& aBindMan) - { - iBindMan = &aBindMan; - - // Create a unique interface name - iIfName.Format(_L("%S[0x%08x]"), &KSpudName, this); - } - -/** -Binds SPUD to the TCP/IP stack. - -@param aId Pointer to network stack object (CProtocolBase*) -@leave KErrInUse if SPUD is already bound -*/ -void CSpudMux::BindL(TAny* aId) - { - iBindMan->SetProtocolBaseL(static_cast(aId)); - } - - -/** -Fills in the info object with NIF information. - -@param aInfo object to hold information on return -*/ -void CSpudMux::Info(TNifIfInfo& aInfo) const - { - // Get the binder for the first (default) lower NIF. - CSpudBinderRef* ref = NULL; - TRAPD(err, ref = iBindMan->GetAnyRefL()); - if (err == KErrNone) - { - // Read the protocol supported value from the lower NIF - ref->NifBase()->Info(aInfo); - ASSERT((aInfo.iFlags & (KNifIfIsBase | KNifIfUsesNotify | KNifIfCreatedByLink)) == (KNifIfIsBase | KNifIfUsesNotify | KNifIfCreatedByLink)); - } - else - { - aInfo.iProtocolSupported=KProtocolUnknown; - } - - // Overwrite these values with our own - aInfo.iName.Copy(iIfName); - aInfo.iVersion = TVersion(KSpudMajorVersionNumber, KSpudMinorVersionNumber, KSpudBuildVersionNumber); - aInfo.iFlags = KNifIfIsBase | KNifIfUsesNotify | KNifIfCreatedByLink; - } - -/** -Takes packets from the IP stack and demultiplexes them by sending each on to -the appropriate lower NIF for processing. The packets are assumed to be -ordered correctly, as appropriate for the QoS guarantees given to each. -This function's responsibility is to pass each packet to the appropriate -lower NIF for processing, where each lower NIF handles a single PDP context. - -@param aPacket MBuf chain containing packet -@param aSource Passed unchanged to lower NIF -@return 1 for a successful send, 0 to tell upper layer to flow off -*/ -TInt CSpudMux::Send(RMBufChain& aPacket, TAny* aSource) - { - // GUQoS places the context ID for the outgoing packet into the Port field - // in the RMBufChain info header. - const RMBufPktInfo* info = RMBufPacket::PeekInfoInChain(aPacket); - TUint contextId(info->iDstAddr.Port()); - if (contextId >= static_cast(KMaxPdpContexts)) - { - // Context ID is illegal; use 0 instead and try to continue - SPUDMUX_LOG(__FLOG_1(_L("CSpudMux::Send context id %d is out of range; using 0 instead"), contextId)); - contextId = 0; - } - const TContextId id(static_cast(contextId)); - - // Get the binder for the appropriate lower NIF. - CSpudBinderRef* ref = NULL; - TRAPD(err, ref = iBindMan->GetRefL(id)); - if (err != KErrNone) - { - // That's odd--GUQoS is sending to an invalid context. - // Redirect it to the first valid context instead. - SPUDMUX_LOG(__FLOG_1(_L("CSpudMux::Send context id %d is invalid; searching for another"), id)); - TRAPD(err, ref = iBindMan->GetAnyRefL()); - if (err != KErrNone) - { - // Something is really wrong here! No contexts available at all! - SPUDMUX_LOG(__FLOG_0(_L("Nowhere to send data! Dropping packet"))); - return err; - } - } - TInt rc = ref->NifBase()->Send(aPacket, aSource); - - // See if NIF is flowing off data on this context - if ((rc == KStopSending) && iBindMan->SpudMan()->AreQoSEventsEnabled()) - { - // Send flow off indication via GUQoS instead - iBindMan->SpudMan()->StopSending(id); - rc = KContinueSending; // Successful send indication - } - return rc; - } - -/** -Processes notifications from agent. - -@param aEvent event type -@param aInfo data associated with event -@return error code -*/ -TInt CSpudMux::Notification(TAgentToNifEventType aEvent, void* aInfo) - { - SPUDMUX_LOG(__FLOG_1(_L("CSpudMux::Notification received event %d"), aEvent)); - TInt rc = KErrNotSupported; - switch (aEvent) - { - case EAgentToNifEventTypeModifyInitialTimer: - case EAgentToNifEventTypeDisableTimers: - case EAgentToNifEventTypeEnableTimers: - // Send notification to all lower NIFs - rc = KErrNotReady; - TContextId i; - for (i=0; i < KMaxPdpContexts; ++i) - { - CSpudBinderRef* ref = NULL; - TRAP(rc, ref = iBindMan->GetRefL(i)); - if (rc == KErrNone) - { - rc = ref->NifBase()->Notification(aEvent, aInfo); - } - } - break; - - case EAgentToNifEventTypeDisableConnection: - SPUDMUX_LOG(__FLOG_0(_L("CSpudMux::Notification received EAgentToNifEventTypeDisableConnection"))); - // TODO: How to handle this event? Just fall through and ignore for now. - default: - break; - } - - return rc; - } - -/** -Returns the current state of the interface - -@return TIfStatus indicating the current state of the interface -*/ -TInt CSpudMux::State() - { - // Get the binder for the first (default) lower NIF. - CSpudBinderRef* ref = NULL; - TRAPD(err, ref = iBindMan->GetAnyRefL()); - if (err != KErrNone) - { - return EIfDown; - } - - // Use the state of the first lower NIF as the state of the SPUD - return ref->NifBase()->State(); - } - -/** -Controls the NIF - -@param aLevel The intended level for this control option -@param aName The name of the control option -@param aOption Any data associated with this control option, contained within a TPckg(Buf) -@param aSource If provided, an identifier for the source of the control option; by default, zero -@return KErrNone if successful; otherwise one of the standard Symbian OS error codes -*/ -TInt CSpudMux::Control(TUint aLevel, TUint aName, TDes8& aOption, TAny* aSource) - { - if (aLevel==KSOLInterface) - { - switch (aName) - { - // From elsewhere - case KSoIfInfo: - case KSoIfInfo6: - case KSoIfConfig: - case KSoIfCompareAddr: - case KSoIfGetConnectionInfo: - case KSoIfHardwareAddr: - { - // Get the binder for the first (default) lower NIF. - CSpudBinderRef* ref = NULL; - TRAPD(err, ref = iBindMan->GetAnyRefL()); - if (err != KErrNone) - { - return err; - } - return ref->NifBase()->Control(aLevel, aName, aOption, aSource); - } - - default: - // Unknown event - // Assume it's for GUQoS, so let SpudMan handle it and error out the unknown ones - // These include: - // KSoIfControllerPlugIn - // KRegisterEventHandler - // KContextSetEvents - // KNifSetDefaultQoS - // KContextCreate - // KContextDelete - // KContextActivate - // KContextQoSSet - // KContextTFTModify - // KContextModifyActive - return iBindMan->SpudMan()->GuqosInput(aName, aOption); - } - } - return KErrNotSupported; - } - -// -// CSpudProtocol -// - - -CSpudProtocol::CSpudProtocol() - { - } - -CSpudProtocol::~CSpudProtocol() - { - } - -/** -Constructs the SpudProtocol object - -@param aBindMan reference to BindMan object -*/ -void CSpudProtocol::Construct(CBindMan& aBindMan) - { - iBindMan = &aBindMan; - } - -void CSpudProtocol::SetProtocolBaseL(CProtocolBase* aProtocolBase) - { - if(iProtocolBase) - { - SPUDMUX_LOG(__FLOG_0(_L("CSpudProtocol::SetProtocolBaseL already bound to protocol"))); - User::Leave(KErrInUse); - } - - iProtocolBase = aProtocolBase; - ASSERT(iProtocolBase); - } - - -void CSpudProtocol::Identify(TServerProtocolDesc *aDesc) const - { - ASSERT(iProtocolBase); - iProtocolBase->Identify(aDesc); - } - -/** -Receives an indication that the lower NIF is ready to send packets. - -@param aProtocol CNifIfBase pointer of lower NIF -*/ -void CSpudProtocol::StartSending(CProtocolBase* aProtocol) - { - TContextId id = KAllContexts; - TRAPD(rc, id = iBindMan->FindContextIdL(reinterpret_cast(aProtocol))); - __ASSERT_ALWAYS(rc == KErrNone, iBindMan->SpudMan()->Panic()); - iBindMan->SpudMan()->StartSending(id); - } - -/** -Receives PDU from the lower NIF and passes it to the upper protocol layer. - -@param aChain Datagram to process -@param aSourceProtocol CNifIfBase pointer of lower NIF (ignored) -*/ -void CSpudProtocol::Process(RMBufChain& aChain, CProtocolBase* /*aSourceProtocol*/) - { - ASSERT(iProtocolBase); - iProtocolBase->Process(aChain, reinterpret_cast(iBindMan->SpudMux())); - } - -/** -Receives PDU from the lower NIF and passes it to the upper protocol layer. - -@param aPDU Datagram to process -@param aFrom Source address -@param aTo Destination address -@param aSourceProtocol (ignored) -*/ -void CSpudProtocol::Process(TDes8& aPDU, TSockAddr* aFrom, TSockAddr* aTo, CProtocolBase* /*aSourceProtocol*/) - { - ASSERT(iProtocolBase); - iProtocolBase->Process(aPDU, aFrom, aTo, reinterpret_cast(iBindMan->SpudMux())); - } - -/** -Propagates error conditions up the stack, eventually to socket service providers. - -@param aError The error code -@param aSourceProtocol (ignored) -*/ -void CSpudProtocol::Error(TInt aError, CProtocolBase* /*aSourceProtocol*/) - { - ASSERT(iProtocolBase); - iProtocolBase->Error(aError, reinterpret_cast(iBindMan->SpudMux())); - } - -/** -Calls StartSending on the upper network protocol. -*/ -void CSpudProtocol::DoStartSending() const - { - ASSERT(iProtocolBase); - iProtocolBase->StartSending(reinterpret_cast(iBindMan->SpudMux())); - } - +// Copyright (c) 2004-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: +// SPUD data multiplexer +// +// + +/** + @file + @internalComponent +*/ + +#include "mux.h" +#include +#include + +// Flow control constants expected by the upper protocol stack +const TInt KStopSending = 0; +const TInt KContinueSending = 1; + +#ifdef __FLOG_ACTIVE +#define SPUDMUX_LOG(x) iBindMan->SpudMan()->x +#else +#define SPUDMUX_LOG(x) +#endif + + +// +// CSpudMux +// + + +CSpudMux::CSpudMux(CSpudMan& aNifBase) + : CNifIfBase(aNifBase) + { + } + +CSpudMux::~CSpudMux() + { + // Notify BindMan to delete the pointer to this object + if (iBindMan) + { + iBindMan->MuxClosed(); + } + } + +/** +Constructs the mux object + +@param aBindMan Reference to BindMan object +*/ +void CSpudMux::Construct(CBindMan& aBindMan) + { + iBindMan = &aBindMan; + + // Create a unique interface name + iIfName.Format(_L("%S[0x%08x]"), &KSpudName, this); + } + +/** +Binds SPUD to the TCP/IP stack. + +@param aId Pointer to network stack object (CProtocolBase*) +@leave KErrInUse if SPUD is already bound +*/ +void CSpudMux::BindL(TAny* aId) + { + iBindMan->SetProtocolBaseL(static_cast(aId)); + } + + +/** +Fills in the info object with NIF information. + +@param aInfo object to hold information on return +*/ +void CSpudMux::Info(TNifIfInfo& aInfo) const + { + // Get the binder for the first (default) lower NIF. + CSpudBinderRef* ref = NULL; + TRAPD(err, ref = iBindMan->GetAnyRefL()); + if (err == KErrNone) + { + // Read the protocol supported value from the lower NIF + ref->NifBase()->Info(aInfo); + ASSERT((aInfo.iFlags & (KNifIfIsBase | KNifIfUsesNotify | KNifIfCreatedByLink)) == (KNifIfIsBase | KNifIfUsesNotify | KNifIfCreatedByLink)); + } + else + { + aInfo.iProtocolSupported=KProtocolUnknown; + } + + // Overwrite these values with our own + aInfo.iName.Copy(iIfName); + aInfo.iVersion = TVersion(KSpudMajorVersionNumber, KSpudMinorVersionNumber, KSpudBuildVersionNumber); + aInfo.iFlags = KNifIfIsBase | KNifIfUsesNotify | KNifIfCreatedByLink; + } + +/** +Takes packets from the IP stack and demultiplexes them by sending each on to +the appropriate lower NIF for processing. The packets are assumed to be +ordered correctly, as appropriate for the QoS guarantees given to each. +This function's responsibility is to pass each packet to the appropriate +lower NIF for processing, where each lower NIF handles a single PDP context. + +@param aPacket MBuf chain containing packet +@param aSource Passed unchanged to lower NIF +@return 1 for a successful send, 0 to tell upper layer to flow off +*/ +TInt CSpudMux::Send(RMBufChain& aPacket, TAny* aSource) + { + // GUQoS places the context ID for the outgoing packet into the Port field + // in the RMBufChain info header. + const RMBufPktInfo* info = RMBufPacket::PeekInfoInChain(aPacket); + TUint contextId(info->iDstAddr.Port()); + if (contextId >= static_cast(KMaxPdpContexts)) + { + // Context ID is illegal; use 0 instead and try to continue + SPUDMUX_LOG(__FLOG_1(_L("CSpudMux::Send context id %d is out of range; using 0 instead"), contextId)); + contextId = 0; + } + const TContextId id(static_cast(contextId)); + + // Get the binder for the appropriate lower NIF. + CSpudBinderRef* ref = NULL; + TRAPD(err, ref = iBindMan->GetRefL(id)); + if (err != KErrNone) + { + // That's odd--GUQoS is sending to an invalid context. + // Redirect it to the first valid context instead. + SPUDMUX_LOG(__FLOG_1(_L("CSpudMux::Send context id %d is invalid; searching for another"), id)); + TRAPD(err, ref = iBindMan->GetAnyRefL()); + if (err != KErrNone) + { + // Something is really wrong here! No contexts available at all! + SPUDMUX_LOG(__FLOG_0(_L("Nowhere to send data! Dropping packet"))); + return err; + } + } + TInt rc = ref->NifBase()->Send(aPacket, aSource); + + // See if NIF is flowing off data on this context + if ((rc == KStopSending) && iBindMan->SpudMan()->AreQoSEventsEnabled()) + { + // Send flow off indication via GUQoS instead + iBindMan->SpudMan()->StopSending(id); + rc = KContinueSending; // Successful send indication + } + return rc; + } + +/** +Processes notifications from agent. + +@param aEvent event type +@param aInfo data associated with event +@return error code +*/ +TInt CSpudMux::Notification(TAgentToNifEventType aEvent, void* aInfo) + { + SPUDMUX_LOG(__FLOG_1(_L("CSpudMux::Notification received event %d"), aEvent)); + TInt rc = KErrNotSupported; + switch (aEvent) + { + case EAgentToNifEventTypeModifyInitialTimer: + case EAgentToNifEventTypeDisableTimers: + case EAgentToNifEventTypeEnableTimers: + // Send notification to all lower NIFs + rc = KErrNotReady; + TContextId i; + for (i=0; i < KMaxPdpContexts; ++i) + { + CSpudBinderRef* ref = NULL; + TRAP(rc, ref = iBindMan->GetRefL(i)); + if (rc == KErrNone) + { + rc = ref->NifBase()->Notification(aEvent, aInfo); + } + } + break; + + case EAgentToNifEventTypeDisableConnection: + SPUDMUX_LOG(__FLOG_0(_L("CSpudMux::Notification received EAgentToNifEventTypeDisableConnection"))); + // TODO: How to handle this event? Just fall through and ignore for now. + default: + break; + } + + return rc; + } + +/** +Returns the current state of the interface + +@return TIfStatus indicating the current state of the interface +*/ +TInt CSpudMux::State() + { + // Get the binder for the first (default) lower NIF. + CSpudBinderRef* ref = NULL; + TRAPD(err, ref = iBindMan->GetAnyRefL()); + if (err != KErrNone) + { + return EIfDown; + } + + // Use the state of the first lower NIF as the state of the SPUD + return ref->NifBase()->State(); + } + +/** +Controls the NIF + +@param aLevel The intended level for this control option +@param aName The name of the control option +@param aOption Any data associated with this control option, contained within a TPckg(Buf) +@param aSource If provided, an identifier for the source of the control option; by default, zero +@return KErrNone if successful; otherwise one of the standard Symbian OS error codes +*/ +TInt CSpudMux::Control(TUint aLevel, TUint aName, TDes8& aOption, TAny* aSource) + { + if (aLevel==KSOLInterface) + { + switch (aName) + { + // From elsewhere + case KSoIfInfo: + case KSoIfInfo6: + case KSoIfConfig: + case KSoIfCompareAddr: + case KSoIfGetConnectionInfo: + case KSoIfHardwareAddr: + { + // Get the binder for the first (default) lower NIF. + CSpudBinderRef* ref = NULL; + TRAPD(err, ref = iBindMan->GetAnyRefL()); + if (err != KErrNone) + { + return err; + } + return ref->NifBase()->Control(aLevel, aName, aOption, aSource); + } + + default: + // Unknown event + // Assume it's for GUQoS, so let SpudMan handle it and error out the unknown ones + // These include: + // KSoIfControllerPlugIn + // KRegisterEventHandler + // KContextSetEvents + // KNifSetDefaultQoS + // KContextCreate + // KContextDelete + // KContextActivate + // KContextQoSSet + // KContextTFTModify + // KContextModifyActive + return iBindMan->SpudMan()->GuqosInput(aName, aOption); + } + } + return KErrNotSupported; + } + +// +// CSpudProtocol +// + + +CSpudProtocol::CSpudProtocol() + { + } + +CSpudProtocol::~CSpudProtocol() + { + } + +/** +Constructs the SpudProtocol object + +@param aBindMan reference to BindMan object +*/ +void CSpudProtocol::Construct(CBindMan& aBindMan) + { + iBindMan = &aBindMan; + } + +void CSpudProtocol::SetProtocolBaseL(CProtocolBase* aProtocolBase) + { + if(iProtocolBase) + { + SPUDMUX_LOG(__FLOG_0(_L("CSpudProtocol::SetProtocolBaseL already bound to protocol"))); + User::Leave(KErrInUse); + } + + iProtocolBase = aProtocolBase; + ASSERT(iProtocolBase); + } + + +void CSpudProtocol::Identify(TServerProtocolDesc *aDesc) const + { + ASSERT(iProtocolBase); + iProtocolBase->Identify(aDesc); + } + +/** +Receives an indication that the lower NIF is ready to send packets. + +@param aProtocol CNifIfBase pointer of lower NIF +*/ +void CSpudProtocol::StartSending(CProtocolBase* aProtocol) + { + TContextId id = KAllContexts; + TRAPD(rc, id = iBindMan->FindContextIdL(reinterpret_cast(aProtocol))); + __ASSERT_ALWAYS(rc == KErrNone, iBindMan->SpudMan()->Panic()); + iBindMan->SpudMan()->StartSending(id); + } + +/** +Receives PDU from the lower NIF and passes it to the upper protocol layer. + +@param aChain Datagram to process +@param aSourceProtocol CNifIfBase pointer of lower NIF (ignored) +*/ +void CSpudProtocol::Process(RMBufChain& aChain, CProtocolBase* /*aSourceProtocol*/) + { + ASSERT(iProtocolBase); + iProtocolBase->Process(aChain, reinterpret_cast(iBindMan->SpudMux())); + } + +/** +Receives PDU from the lower NIF and passes it to the upper protocol layer. + +@param aPDU Datagram to process +@param aFrom Source address +@param aTo Destination address +@param aSourceProtocol (ignored) +*/ +void CSpudProtocol::Process(TDes8& aPDU, TSockAddr* aFrom, TSockAddr* aTo, CProtocolBase* /*aSourceProtocol*/) + { + ASSERT(iProtocolBase); + iProtocolBase->Process(aPDU, aFrom, aTo, reinterpret_cast(iBindMan->SpudMux())); + } + +/** +Propagates error conditions up the stack, eventually to socket service providers. + +@param aError The error code +@param aSourceProtocol (ignored) +*/ +void CSpudProtocol::Error(TInt aError, CProtocolBase* /*aSourceProtocol*/) + { + ASSERT(iProtocolBase); + iProtocolBase->Error(aError, reinterpret_cast(iBindMan->SpudMux())); + } + +/** +Calls StartSending on the upper network protocol. +*/ +void CSpudProtocol::DoStartSending() const + { + ASSERT(iProtocolBase); + iProtocolBase->StartSending(reinterpret_cast(iBindMan->SpudMux())); + } +