diff -r ac20d6a0a19d -r b982c3e940f3 telephonyprotocols/secondarypdpcontextumtsdriver/spudman/src/mux.cpp --- a/telephonyprotocols/secondarypdpcontextumtsdriver/spudman/src/mux.cpp Mon Aug 09 17:43:08 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,375 +0,0 @@ -// 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())); - } -