networkcontrol/qoslib/src/qoslib.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <f32file.h>
       
    17 #include <es_ini.h>
       
    18 
       
    19 
       
    20 #include "qosliblog.h"
       
    21 
       
    22 #include "qoslib.h"
       
    23 #include "pfqosparser.h"
       
    24 #include "pfqos.h"
       
    25 #include "qos_ini.h"
       
    26 #include "qoslib_glob.h"
       
    27 #include "pfqos_stream.h"
       
    28 
       
    29 
       
    30 //
       
    31 // DLL entry point
       
    32 //
       
    33 GLDEF_C TInt E32Dll()
       
    34 	{
       
    35 	return(KErrNone);
       
    36 	}
       
    37 
       
    38 //
       
    39 CRequest* CRequest::NewL(CQoSRequestBase* aOwner, TUint aBufSize)
       
    40 	{
       
    41 	CRequest* request = new (ELeave) CRequest(aOwner);
       
    42 	CleanupStack::PushL(request);
       
    43 	request->ConstructL(aBufSize);
       
    44 	CleanupStack::Pop();
       
    45 	return request;
       
    46 	}
       
    47 
       
    48 CRequest::~CRequest()
       
    49 	{
       
    50 	delete iMsg;
       
    51 	}
       
    52 
       
    53 CRequest::CRequest(CQoSRequestBase* aOwner) : iOwner(aOwner)
       
    54 	{
       
    55 	iMsg = NULL;
       
    56 	}
       
    57 
       
    58 void CRequest::ConstructL(TUint aBufSize)
       
    59 	{
       
    60 	iMsg = CPfqosStream::NewL(aBufSize);
       
    61 	};
       
    62 
       
    63 
       
    64 //
       
    65 class CSender : public CActive
       
    66 	{
       
    67 	public:
       
    68 	static CSender* NewL(CQoSMan* aManager, TInt aPriority=EPriorityStandard);
       
    69 	~CSender();
       
    70 	void Send(CRequest* aRequest);
       
    71 	void ClearPendingRequest(CQoSRequestBase* aRequest);
       
    72 
       
    73 	protected:
       
    74 	CSender(CQoSMan* aManager, TInt aPriority);
       
    75 	void ConstructL();
       
    76 	void RunL();
       
    77 	void DoCancel();
       
    78 
       
    79 	private:
       
    80 	CQoSMan* iManager;
       
    81 	CRequest* iCurrentRequest;
       
    82 	TSglQue<CRequest> iRequests;
       
    83 	};
       
    84 
       
    85 CSender* CSender::NewL(CQoSMan* aManager, TInt aPriority)
       
    86 	{
       
    87 	CSender* sender = new (ELeave) CSender(aManager, aPriority);
       
    88 	CleanupStack::PushL(sender);
       
    89 	sender->ConstructL();
       
    90 	CleanupStack::Pop();
       
    91 	return sender;
       
    92 	}
       
    93 
       
    94 CSender::CSender(CQoSMan* aManager, TInt aPriority) : CActive(aPriority), iManager(aManager)
       
    95 	{
       
    96 	CActiveScheduler::Add(this);
       
    97 	iRequests.SetOffset(_FOFF(CRequest, iLink));
       
    98 	iCurrentRequest=NULL;
       
    99 	}
       
   100 
       
   101 void CSender::ConstructL()
       
   102 	{
       
   103 	}
       
   104 
       
   105 CSender::~CSender()
       
   106 	{
       
   107 	if (IsActive())
       
   108 		Cancel();
       
   109 
       
   110 	delete iCurrentRequest;
       
   111 
       
   112 	while (!iRequests.IsEmpty())
       
   113 		{
       
   114 		CRequest* request = iRequests.First();
       
   115 		iRequests.Remove(*request);
       
   116 		delete request;
       
   117 		}
       
   118 	iRequests.Reset();
       
   119 	}
       
   120 
       
   121 void CSender::Send(CRequest* aRequest)
       
   122 	{
       
   123 	if (IsActive())
       
   124 		iRequests.AddLast(*aRequest);
       
   125 	else
       
   126 		{
       
   127 		iCurrentRequest = aRequest;
       
   128 		iCurrentRequest->iMsg->Send(iManager->Socket(), iStatus);
       
   129 		SetActive();
       
   130 		}
       
   131 	}
       
   132 
       
   133 void CSender::ClearPendingRequest(CQoSRequestBase* aRequest)
       
   134 	{
       
   135 	if (iCurrentRequest != NULL)
       
   136 		{
       
   137 		if (iCurrentRequest->iOwner == aRequest)
       
   138 			iCurrentRequest->iOwner = NULL;
       
   139 		}
       
   140 	}
       
   141 
       
   142 void CSender::RunL()
       
   143 	{
       
   144 	TInt err = iStatus.Int();
       
   145 	if (err && iCurrentRequest->iOwner)
       
   146 		iCurrentRequest->iOwner->NotifyError(err);
       
   147 
       
   148 	delete iCurrentRequest;
       
   149 	iCurrentRequest = NULL;
       
   150 
       
   151 	if (!iRequests.IsEmpty())
       
   152 		{
       
   153 		CRequest* request = iRequests.First();
       
   154 		iRequests.Remove(*request);
       
   155 		iCurrentRequest = request;
       
   156 		iCurrentRequest->iMsg->Send(iManager->Socket(), iStatus);
       
   157 		SetActive();
       
   158 		}
       
   159 	}
       
   160 
       
   161 void CSender::DoCancel()
       
   162 	{
       
   163 	iManager->Socket().CancelWrite();
       
   164 	}
       
   165 
       
   166 
       
   167 //
       
   168 CQoSMan* CQoSMan::NewL(TInt aPriority)
       
   169 	{
       
   170 	CQoSMan* manager;
       
   171 	manager = QoSManGlobals::Get();
       
   172 	if (!manager)
       
   173 		{
       
   174 		manager = new (ELeave) CQoSMan(aPriority);
       
   175 		CleanupStack::PushL(manager);
       
   176 		manager->ConstructL();
       
   177 		CleanupStack::Pop();
       
   178 		QoSManGlobals::Set(manager);
       
   179 		}
       
   180 	manager->Open();
       
   181 	return manager;
       
   182 	}
       
   183 
       
   184 void CQoSMan::ConstructL()
       
   185 	{
       
   186 	_LIT(KDescPfqos, "pfqos");
       
   187 	User::LeaveIfError(iSocketServer.Connect());
       
   188 	User::LeaveIfError(iSocket.Open(iSocketServer, KDescPfqos));
       
   189 
       
   190 	iSender = CSender::NewL(this);
       
   191 	iBuf = HBufC8::NewL(KQoSDefaultBufSize);
       
   192 	TPtr8 tmp(iBuf->Des());
       
   193 	iRecBuf.Set(tmp);
       
   194 	iUid.Set(RProcess().Type());
       
   195 	iSocket.Recv(iRecBuf, 0, iStatus);
       
   196 	SetActive();
       
   197 	}
       
   198 
       
   199 CQoSMan::CQoSMan(TInt aPriority) : CActive(aPriority), iRecBuf(0,0)
       
   200 	{
       
   201 	CActiveScheduler::Add(this);
       
   202 	iRefCount = 0;
       
   203 	iChannels.SetOffset(_FOFF(CChannel, iNext));
       
   204 	iStaticPolicies.SetOffset(_FOFF(CPolicy,iNext));
       
   205 	iNotifyPending = EFalse;
       
   206 	iShutdown = EFalse;
       
   207 	}
       
   208 
       
   209 void CQoSMan::Close()
       
   210 	{
       
   211 	if (--iRefCount <= 0)
       
   212 		{
       
   213 		if (iNotifyPending)
       
   214 			iShutdown = ETrue;
       
   215 		else
       
   216 			delete this;
       
   217 		}
       
   218 	}
       
   219 
       
   220 CQoSMan::~CQoSMan()
       
   221 	{
       
   222 	while (!iChannels.IsEmpty())
       
   223 		{
       
   224 		CChannel* channel = iChannels.First();
       
   225 		iChannels.Remove(*channel);
       
   226 		delete channel;
       
   227 		}
       
   228 	iChannels.Reset();
       
   229 
       
   230 	while (!iStaticPolicies.IsEmpty())
       
   231 		{
       
   232 		CPolicy* policy = iStaticPolicies.First();
       
   233 		iStaticPolicies.Remove(*policy);
       
   234 		delete policy;
       
   235 		}
       
   236 	iStaticPolicies.Reset();
       
   237 
       
   238 	delete iSender;
       
   239 
       
   240 	if (IsActive())
       
   241 		Cancel();
       
   242 
       
   243 	iSocket.Close();
       
   244 	iSocketServer.Close();
       
   245 	delete iBuf;
       
   246 	QoSManGlobals::Set(NULL);
       
   247 	}
       
   248 
       
   249 CChannel* CQoSMan::OpenQoSChannelL(RSocket& aSocket)
       
   250 	{
       
   251 	CChannel* channel = CChannel::NewL(this, aSocket, NULL);
       
   252 	iChannels.AddLast(*channel);
       
   253 	return channel;
       
   254 	}
       
   255 
       
   256 void CQoSMan::RemoveQoSChannel(CChannel* aChannel)
       
   257 	{
       
   258 	TSglQueIter<CChannel> iter(iChannels);
       
   259 	CChannel* channel;
       
   260 	while ((channel = iter++) != NULL)
       
   261 		{
       
   262 		if (channel == aChannel)
       
   263 			{
       
   264 			iChannels.Remove(*aChannel);
       
   265 			break;
       
   266 			}
       
   267 		}
       
   268 	}
       
   269 
       
   270 void CQoSMan::SetQoSL(CChannel& aChannel)
       
   271 	{
       
   272 	CRequest* request = CRequest::NewL(&aChannel, KQoSDefaultBufSize);
       
   273 	request->iMsg->Init(EPfqosConfigChannel);
       
   274 	request->iMsg->AddQoSParameters(aChannel.GetPolicy().iQoS);
       
   275 	request->iMsg->AddChannel(aChannel.ChannelId());
       
   276 
       
   277 	TQoSExtensionQueueIter iter(aChannel.GetPolicy().Extensions());
       
   278 	CExtensionBase *extension;
       
   279 	while ((extension=iter++) != NULL)
       
   280 		request->iMsg->AddExtensionPolicy(extension->Data());
       
   281 	iSender->Send(request);
       
   282 	}
       
   283 
       
   284 void CQoSMan::CreateL(CChannel& aChannel, const TQoSSelector& aSelector)
       
   285 	{
       
   286 	CRequest* request = CRequest::NewL(&aChannel, KQoSDefaultBufSize);
       
   287 	request->iMsg->Init(EPfqosCreateChannel);
       
   288 	request->iMsg->AddSelector((TUint8)aSelector.Protocol(), iUid.UidType(), EPfqosFlowspecPolicy, aSelector.IapId(), EPfqosApplicationPriority, TPtr(0,0));
       
   289 	request->iMsg->AddSrcAddress(aSelector.GetSrc(), aSelector.GetSrcMask(), (TUint16)aSelector.MaxPortSrc()); 
       
   290 	request->iMsg->AddDstAddress(aSelector.GetDst(), aSelector.GetDstMask(), (TUint16)aSelector.MaxPortDst()); 
       
   291 	request->iMsg->AddChannel(0);
       
   292 	request->iMsg->AddQoSParameters(aChannel.GetPolicy().iQoS);
       
   293 	TQoSExtensionQueueIter iter(aChannel.GetPolicy().Extensions());
       
   294 	CExtensionBase *extension;
       
   295 	while ((extension=iter++) != NULL)
       
   296 		request->iMsg->AddExtensionPolicy(extension->Data());
       
   297 	Send(request);
       
   298 	}
       
   299 
       
   300 void CQoSMan::OpenExistingL(CChannel& aChannel, const TQoSSelector& aSelector)
       
   301 	{
       
   302 	CRequest* request = CRequest::NewL(&aChannel, KQoSDefaultBufSize);
       
   303 	request->iMsg->Init(EPfqosOpenExistingChannel);
       
   304 	request->iMsg->AddSelector((TUint8)aSelector.Protocol(), iUid.UidType(), EPfqosFlowspecPolicy, aSelector.IapId(), EPfqosApplicationPriority, TPtr(0,0));
       
   305 	request->iMsg->AddSrcAddress(aSelector.GetSrc(), aSelector.GetSrcMask(), (TUint16)aSelector.MaxPortSrc()); 
       
   306 	request->iMsg->AddDstAddress(aSelector.GetDst(), aSelector.GetDstMask(), (TUint16)aSelector.MaxPortDst()); 
       
   307 	request->iMsg->AddChannel(0);
       
   308 	Send(request);
       
   309 	}
       
   310 
       
   311 void CQoSMan::JoinL(CChannel& aChannel, const TQoSSelector& aSelector)
       
   312 	{
       
   313 	CRequest* request = CRequest::NewL(&aChannel, KQoSDefaultBufSize);
       
   314 	request->iMsg->Init(EPfqosJoin);
       
   315 	request->iMsg->AddSelector((TUint8)aSelector.Protocol(), iUid.UidType(), EPfqosFlowspecPolicy, aSelector.IapId(), EPfqosApplicationPriority, TPtr(0,0));
       
   316 	request->iMsg->AddSrcAddress(aSelector.GetSrc(), aSelector.GetSrcMask(), (TUint16)aSelector.MaxPortSrc()); 
       
   317 	request->iMsg->AddDstAddress(aSelector.GetDst(), aSelector.GetDstMask(), (TUint16)aSelector.MaxPortDst()); 
       
   318 	request->iMsg->AddChannel(aChannel.ChannelId());
       
   319 	Send(request);
       
   320 	}
       
   321 
       
   322 
       
   323 void CQoSMan::LeaveL(CChannel& aChannel, const TQoSSelector& aSelector)
       
   324 	{
       
   325 	CRequest* request = CRequest::NewL(&aChannel, KQoSDefaultBufSize);
       
   326 	request->iMsg->Init(EPfqosLeave);
       
   327 	request->iMsg->AddSelector((TUint8)aSelector.Protocol(), iUid.UidType(), EPfqosFlowspecPolicy, aSelector.IapId(), EPfqosApplicationPriority, TPtr(0,0));
       
   328 	request->iMsg->AddSrcAddress(aSelector.GetSrc(), aSelector.GetSrcMask(), (TUint16)aSelector.MaxPortSrc()); 
       
   329 	request->iMsg->AddDstAddress(aSelector.GetDst(), aSelector.GetDstMask(), (TUint16)aSelector.MaxPortDst()); 
       
   330 	request->iMsg->AddChannel(aChannel.ChannelId());
       
   331 	Send(request);
       
   332 	}
       
   333 
       
   334 
       
   335 //
       
   336 // Notify informs applications about events received from the kernel. 
       
   337 // A callback function is called, if application has registered for the event.
       
   338 // Selector is matched against flows to find out if an application ought to be notified.
       
   339 //
       
   340 void CQoSMan::Notify(TPfqosMessage& aMsg)
       
   341 	{
       
   342 	if (!aMsg.iBase.iMsg)
       
   343 		return;
       
   344 
       
   345 	switch (aMsg.iBase.iMsg->pfqos_msg_type)
       
   346 		{
       
   347 
       
   348 	case EPfqosEvent:
       
   349 		ExecEvent(aMsg);
       
   350 		return;
       
   351 
       
   352 	case EPfqosFlush:
       
   353 		// All policies have been deleted from the kernel. 
       
   354 		// Inform applications with POLICY_EVENT_QOS_FAILURE.
       
   355 		Flush();
       
   356 		break;
       
   357 
       
   358 	case EPfqosUpdate:
       
   359 	case EPfqosDelete:
       
   360 	case EPfqosAdd:
       
   361 	case EPfqosGet:
       
   362 	case EPfqosReject:
       
   363 	case EPfqosDump:
       
   364 	case EPfqosConfigure:
       
   365 	case EPfqosJoin:
       
   366 	case EPfqosLeave:
       
   367 	case EPfqosCreateChannel:
       
   368 	case EPfqosOpenExistingChannel:
       
   369 	case EPfqosDeleteChannel:
       
   370 	case EPfqosConfigChannel:
       
   371 	case EPfqosLoadFile:
       
   372 	case EPfqosUnloadFile:
       
   373 		ExecReply(aMsg);
       
   374 		break;
       
   375 	default:
       
   376 		break;
       
   377 		}
       
   378 	}
       
   379 
       
   380 // Flush deletes all flowinfo in CQoSMan. If aEvent > 0, inform applications.
       
   381 void CQoSMan::Flush()
       
   382 	{
       
   383 	while (!iStaticPolicies.IsEmpty())
       
   384 		{
       
   385 		CPolicy* policy = iStaticPolicies.First();
       
   386 		if (policy)
       
   387 			{
       
   388 			iStaticPolicies.Remove(*policy);
       
   389 			delete policy;
       
   390 			}
       
   391 		}
       
   392 	iStaticPolicies.Reset();
       
   393 	}
       
   394 
       
   395 
       
   396 CChannel* CQoSMan::Match(TPfqosMessage& aMsg)
       
   397 	{
       
   398 	if (!aMsg.iChannel.iExt)
       
   399 		return NULL;
       
   400 
       
   401 	TSglQueIter<CChannel> iter(iChannels);
       
   402 	CChannel* channel;
       
   403 	while ((channel = iter++) != NULL)
       
   404 		{
       
   405 		if (channel->Match(aMsg.iChannel.iExt->channel_id))
       
   406 			return channel;
       
   407 		}
       
   408 	return NULL;
       
   409 	}
       
   410 
       
   411 
       
   412 CChannel* CQoSMan::MatchChannelReply(TPfqosMessage& aMsg, TUint8 aMsgType)
       
   413 	{
       
   414 	if (aMsgType == EPfqosCreateChannel || aMsgType == EPfqosJoin || 
       
   415 	aMsgType == EPfqosLeave)
       
   416 	if (aMsg.iSrcAddr.iExt == NULL || aMsg.iDstAddr.iExt == NULL || aMsg.iSelector.iExt == NULL)
       
   417 		return NULL;
       
   418 
       
   419 	TSglQueIter<CChannel> iter(iChannels);
       
   420 	CChannel* channel;
       
   421 
       
   422 	while ((channel = iter++) != NULL)
       
   423 		{
       
   424 		if (channel->MatchReply(aMsg, aMsgType))
       
   425 			return channel;
       
   426 		}
       
   427 	return NULL;
       
   428 	}
       
   429 
       
   430 CPolicy* CQoSMan::MatchPolicyReply(TPfqosMessage& aMsg, TUint8 aMsgType)
       
   431 	{
       
   432 	TSglQueIter<CPolicy> iter(iStaticPolicies);
       
   433 	CPolicy* policy;
       
   434 
       
   435 	while ((policy = iter++) != NULL)
       
   436 		{
       
   437 		if (policy->MatchReply(aMsg, aMsgType))
       
   438 			return policy;
       
   439 		}
       
   440 	return NULL;
       
   441 	}
       
   442 
       
   443 //
       
   444 // POLICY_EVENT message has to contain <header, selector, srcaddr, dstaddr, policy_event,(flowspec)>
       
   445 // flowspec is mandatory for all others but POLICY_EVENT_QOS_FAILURE event.
       
   446 //
       
   447 void CQoSMan::ExecEvent(TPfqosMessage& aMsg)
       
   448 	{
       
   449 	if (aMsg.iEvent.iExt == NULL || aMsg.iFlowSpec.iExt == NULL)
       
   450 		return;
       
   451 
       
   452 	TUint event = aMsg.iEvent.iExt->event_type;
       
   453 	switch (event)
       
   454 		{
       
   455 	case KPfqosEventReceivers:
       
   456 	case KPfqosEventSenders:
       
   457 		break;
       
   458 
       
   459 	default:
       
   460 		if (aMsg.iChannel.iExt)
       
   461 			{
       
   462 			TSglQueIter<CChannel> iter(iChannels);
       
   463 			CChannel* channel;
       
   464 			while ((channel = iter++) != NULL)
       
   465 				{
       
   466 				if (channel->Match(aMsg.iChannel.iExt->channel_id))
       
   467 					channel->ProcessEvent(aMsg);
       
   468 				}
       
   469 			}
       
   470 		else
       
   471 			{
       
   472 			if (aMsg.iSrcAddr.iExt == NULL || aMsg.iDstAddr.iExt == NULL || aMsg.iSelector.iExt == NULL)
       
   473 				return;
       
   474 			TSglQueIter<CPolicy> iter(iStaticPolicies);
       
   475 			CPolicy* policy;
       
   476 			while ((policy = iter++) != NULL)
       
   477 				policy->ProcessEvent(aMsg);
       
   478 			}
       
   479 		break;
       
   480 		}
       
   481 	}
       
   482 
       
   483 
       
   484 void CQoSMan::ExecReply(TPfqosMessage& aMsg)
       
   485 	{
       
   486 	TUint8 type = aMsg.iBase.iMsg->pfqos_msg_type;
       
   487 	CChannel* request = MatchChannelReply(aMsg, type);
       
   488 	if (request)
       
   489 		request->ProcessReply(aMsg);
       
   490 	else
       
   491 		{
       
   492 		if (aMsg.iSrcAddr.iExt == NULL || aMsg.iDstAddr.iExt == NULL || aMsg.iSelector.iExt == NULL)
       
   493 			return;
       
   494 		CPolicy* policy = MatchPolicyReply(aMsg, type);
       
   495 		if (policy)
       
   496 			policy->ProcessReply(aMsg);
       
   497 		}
       
   498 	}
       
   499 
       
   500 void CQoSMan::RunL()
       
   501 	{
       
   502 	if (iStatus.Int() == KErrNone)
       
   503 		{
       
   504 		TPfqosMessage msg(iRecBuf);
       
   505 		__ASSERT_DEBUG(msg.iError == KErrNone, User::Panic(_L("CQoSMan*::RunL(): Msg corrupted"),msg.iError));
       
   506 		// Should log the error
       
   507 		if (msg.iError == KErrNone)
       
   508 			{
       
   509 			iNotifyPending = ETrue;
       
   510 
       
   511 			LOG(Log::Printf(_L("CQoSMan::RunL() - [%d] "),msg.iBase.iMsg->pfqos_msg_errno));
       
   512 
       
   513 			Notify(msg);
       
   514 			iNotifyPending = EFalse;
       
   515 			}
       
   516 		}
       
   517 
       
   518 	if (!iShutdown)
       
   519 		{
       
   520 		iRecBuf.Zero();
       
   521 		iSocket.Recv(iRecBuf, 0, iStatus);
       
   522 		SetActive();
       
   523 		}
       
   524 	else
       
   525 		delete this;
       
   526 	}
       
   527 
       
   528 void CQoSMan::DoCancel()
       
   529 	{
       
   530 	iSocket.CancelRecv();
       
   531 	}
       
   532 
       
   533 CPolicy* CQoSMan::OpenQoSPolicyL(const TQoSSelector& aSelector)
       
   534 	{
       
   535 	CPolicy* policy = CPolicy::NewL(this, aSelector);
       
   536 	iStaticPolicies.AddLast(*policy);
       
   537 	return policy;
       
   538 	}
       
   539 
       
   540 void CQoSMan::RemoveQoSPolicy(CPolicy* aPolicy)
       
   541 	{
       
   542 	TSglQueIter<CPolicy> iter(iStaticPolicies);
       
   543 	CPolicy* policy;
       
   544 	while ((policy = iter++) != NULL)
       
   545 		{
       
   546 		if (policy == aPolicy)
       
   547 			{
       
   548 			iStaticPolicies.Remove(*aPolicy);
       
   549 			return;
       
   550 			}
       
   551 		}
       
   552 	}
       
   553 
       
   554 CPolicy* CQoSMan::FindPolicy(const TQoSSelector& aSelector)
       
   555 	{
       
   556 	TSglQueIter<CPolicy> iter(iStaticPolicies);
       
   557 	CPolicy* policy;
       
   558 
       
   559 	while ((policy=iter++) != NULL)
       
   560 		{
       
   561 		if (policy->Match(aSelector))
       
   562 			return policy;
       
   563 		}
       
   564 	return NULL;
       
   565 	}
       
   566 
       
   567 void CQoSMan::ClearPendingRequest(CQoSRequestBase* aRequest)
       
   568 	{
       
   569 	iSender->ClearPendingRequest(aRequest);
       
   570 	}
       
   571 
       
   572 void CQoSMan::Send(CRequest* aRequest)
       
   573 	{
       
   574 	iSender->Send(aRequest);
       
   575 	}
       
   576