--- 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 <nifmbuf.h>
-#include <in6_if.h>
-
-// 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<CProtocolBase*>(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<TUint>(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<TContextId>(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<CNifIfBase*>(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<CProtocolBase*>(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<CProtocolBase*>(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<CProtocolBase*>(iBindMan->SpudMux()));
- }
-
-/**
-Calls StartSending on the upper network protocol.
-*/
-void CSpudProtocol::DoStartSending() const
- {
- ASSERT(iProtocolBase);
- iProtocolBase->StartSending(reinterpret_cast<CProtocolBase*>(iBindMan->SpudMux()));
- }
-