telephonyprotocols/pdplayer/src/pdp_contention.cpp
changeset 69 b982c3e940f3
equal deleted inserted replaced
59:ac20d6a0a19d 69:b982c3e940f3
       
     1 // Copyright (c) 2010 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 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include "OstTraceDefinitions.h"
       
    22 #ifdef OST_TRACE_COMPILER_IN_USE
       
    23 #include "pdp_contentionTraces.h"
       
    24 #endif
       
    25 
       
    26 
       
    27 #include <pdpmcpr.h>
       
    28 #include <pdp_contention.h>
       
    29 #include <mbmsengine.h>
       
    30 #include <etelpckt.h>
       
    31 #include <pcktcs.h>
       
    32 
       
    33 CContextTypeChecker::CContextTypeChecker(RPacketService& aPacketService, MContextEventsObserver& aCallback):CActive(EPriorityStandard),
       
    34     iPacketService(aPacketService), iCallback(aCallback)
       
    35     {
       
    36     CActiveScheduler::Add(this);
       
    37     }
       
    38 
       
    39 CContextTypeChecker::~CContextTypeChecker()
       
    40     {
       
    41     iContextName = NULL;
       
    42     }
       
    43 
       
    44 void CContextTypeChecker::Start(const TName* aContextName)
       
    45     {
       
    46     iContextName = aContextName;
       
    47     iPacketService.EnumerateContextsInNif(iStatus, *iContextName, iCountInNif);
       
    48     SetActive();
       
    49     }
       
    50 
       
    51 void CContextTypeChecker::RunL()
       
    52     {
       
    53     User::LeaveIfError(iStatus.Int());
       
    54     if (iCountInNif == 1) // This is a primary context
       
    55         {
       
    56         iCallback.PrimaryContextAddedL(iContextName);
       
    57         }
       
    58     else
       
    59         {
       
    60         iCallback.SecondaryContextAdded(iContextName);
       
    61         }
       
    62     }
       
    63 
       
    64 void CContextTypeChecker::DoCancel()
       
    65     {
       
    66     iPacketService.CancelAsyncRequest(EPacketEnumerateContextsInNif);
       
    67     }
       
    68 
       
    69 TInt CContextTypeChecker::RunError(TInt aError)
       
    70     {
       
    71     // Report an error
       
    72     iCallback.ContextTypeCheckingError(iContextName, aError);
       
    73     return KErrNone; // Make ActiveScheduler happy
       
    74     }
       
    75 
       
    76 
       
    77 CPrimaryContextsMonitor::CPrimaryContextsMonitor(RPacketService& aPacketService, MContentionObserver& aCallback) : CActive(EPriorityStandard),
       
    78     iPacketService(aPacketService), iCallback(aCallback)
       
    79     {
       
    80     CActiveScheduler::Add(this);
       
    81     }
       
    82 
       
    83 CPrimaryContextsMonitor::~CPrimaryContextsMonitor()
       
    84     {
       
    85     Cancel();
       
    86     iContextMonitors.ResetAndDestroy();
       
    87     delete iContextTypeChecker;
       
    88     iAddedContextsNames.ResetAndDestroy();
       
    89     }
       
    90 
       
    91 void CPrimaryContextsMonitor::StartL()
       
    92     {
       
    93     iContextTypeChecker = new(ELeave) CContextTypeChecker(iPacketService, *this);
       
    94     iState = EEnumeratingContexts;
       
    95     iPacketService.EnumerateNifs(iStatus, iInitialNifsCount);
       
    96     SetActive();
       
    97     }
       
    98 
       
    99 void CPrimaryContextsMonitor::PrimaryContextAddedL(const TName* aContextName)
       
   100     {
       
   101     // Create new status monitor for this context
       
   102     StartContextStatusMonitoringL(*aContextName);
       
   103     RemoveContextNameAndCheckNext(aContextName);
       
   104     }
       
   105 
       
   106 void CPrimaryContextsMonitor::SecondaryContextAdded(const TName* aContextName)
       
   107     {
       
   108     // This is not a primary context, just delete its name.
       
   109     RemoveContextNameAndCheckNext(aContextName);
       
   110     }
       
   111 
       
   112 void CPrimaryContextsMonitor::RemoveContextNameAndCheckNext(const TName* aContextName)
       
   113     {
       
   114     TInt nameIndex = iAddedContextsNames.Find(aContextName);
       
   115     __ASSERT_DEBUG(nameIndex != KErrNotFound, User::Invariant());
       
   116     delete iAddedContextsNames[nameIndex];
       
   117     iAddedContextsNames.Remove(nameIndex);
       
   118 
       
   119     if (iAddedContextsNames.Count() > 1)
       
   120         // Should be more than one here, coz we are waiting for new context added all the time,
       
   121         // so the last one item is always empty.
       
   122         {
       
   123         iContextTypeChecker->Start(iAddedContextsNames[0]);
       
   124         }
       
   125     }
       
   126 
       
   127 void CPrimaryContextsMonitor::PrimaryContextDeleted(const CContextStatusMonitor* aContextStatusMonitor)
       
   128     {
       
   129     if (aContextStatusMonitor->IsPassedThroughActiveState())
       
   130         {
       
   131         iCallback.ContentionResolved();
       
   132         }
       
   133     DeleteContextStatusMonitor(aContextStatusMonitor);
       
   134     }
       
   135 
       
   136 void CPrimaryContextsMonitor::ContextTypeCheckingError(const TName* aContextName, TInt aError)
       
   137     {
       
   138     RemoveContextNameAndCheckNext(aContextName);
       
   139     ProcessError(aError);
       
   140     }
       
   141 
       
   142 
       
   143 void CPrimaryContextsMonitor::ContextMonitoringError(const CContextStatusMonitor* aContextStatusMonitor, TInt aError)
       
   144     {
       
   145     DeleteContextStatusMonitor(aContextStatusMonitor);
       
   146     ProcessError(aError);
       
   147     }
       
   148 
       
   149 void CPrimaryContextsMonitor::DeleteContextStatusMonitor(const CContextStatusMonitor* aContextStatusMonitor)
       
   150     {
       
   151     TInt monitorIndex = iContextMonitors.Find(aContextStatusMonitor);
       
   152     __ASSERT_DEBUG(monitorIndex != KErrNotFound, User::Invariant());
       
   153     delete iContextMonitors[monitorIndex];
       
   154     iContextMonitors.Remove(monitorIndex);
       
   155     }
       
   156 
       
   157 void CPrimaryContextsMonitor::ProcessError(TInt aError)
       
   158     {
       
   159     __ASSERT_DEBUG(aError != KErrNone, User::Invariant());
       
   160     OstTraceDef1(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CPRIMARYCONTEXTSMONITOR_PROCESSERROR_1, ("PDP context monitoring error: %d"), aError);
       
   161     (void)aError;  //needed for debug builds 
       
   162     }
       
   163 
       
   164 void CPrimaryContextsMonitor::RunL()
       
   165     {
       
   166     User::LeaveIfError(iStatus.Int());
       
   167     SwitchStateL();
       
   168     RPacketService::TNifInfoV2Pckg nifInfoV2Pckg(iCurrentNifInfo);
       
   169     switch(iState)
       
   170         {
       
   171         case EGettingInfo:
       
   172             StartContextStatusMonitoringL(iCurrentNifInfo.iContextName);
       
   173             iPacketService.GetNifInfo(iStatus, iCurrentNifIndex, nifInfoV2Pckg);
       
   174             ++iCurrentNifIndex;
       
   175             SetActive();
       
   176             break;
       
   177         case EListening:
       
   178             // All functions in RPacketService and RPacketContext,
       
   179             // that can be used to check if context is primary, are asynchronous.
       
   180             // We could not call them here, coz can miss some events from NotifyContextAdded
       
   181             // So subscribe to NotifyContextAdded as soon as possible and check context
       
   182             // type using CContextTypeChecker active object
       
   183             TName *contextName = new (ELeave) TName;
       
   184             CleanupStack::PushL(contextName);
       
   185             iAddedContextsNames.AppendL(contextName);
       
   186             CleanupStack::Pop(contextName);
       
   187             // subscribe to NotifyContextAdded
       
   188             iPacketService.NotifyContextAdded(iStatus, *contextName);
       
   189             SetActive();
       
   190             // if there are any items in iAddedContextsNames except that one that has been added above, i.e count > 1
       
   191             // starting asynchronous context type checking
       
   192             if (!iContextTypeChecker->IsActive() && iAddedContextsNames.Count()>1)
       
   193                 {
       
   194                 iContextTypeChecker->Start(iAddedContextsNames[0]);
       
   195                 }
       
   196             break;
       
   197         }
       
   198     }
       
   199 void CPrimaryContextsMonitor::DoCancel()
       
   200     {
       
   201     switch(iState)
       
   202         {
       
   203         case EEnumeratingContexts:
       
   204             iPacketService.CancelAsyncRequest(EPacketEnumerateNifs);
       
   205             break;
       
   206         case EGettingInfo:
       
   207             iPacketService.CancelAsyncRequest(EPacketGetNifInfo);
       
   208             break;
       
   209         case EListening:
       
   210             iPacketService.CancelAsyncRequest(EPacketNotifyContextAdded);
       
   211             break;
       
   212         }
       
   213 
       
   214     }
       
   215 
       
   216 TInt CPrimaryContextsMonitor::RunError(TInt aError)
       
   217     {
       
   218     // Process an error
       
   219     ProcessError(aError);
       
   220     return KErrNone; // Make ActiveScheduler happy
       
   221     }
       
   222 
       
   223 
       
   224 void CPrimaryContextsMonitor::SwitchStateL()
       
   225     {
       
   226     if (iState == EEnumeratingContexts)
       
   227         {
       
   228         if (iInitialNifsCount > 0)
       
   229             {
       
   230             iState = EGettingInfo;
       
   231             }
       
   232         else
       
   233             {
       
   234             iState = EListening;
       
   235             }
       
   236         }
       
   237     else if (iState == EGettingInfo && iCurrentNifIndex == iInitialNifsCount)
       
   238         {
       
   239         StartContextStatusMonitoringL(iCurrentNifInfo.iContextName);
       
   240         iState = EListening;
       
   241         }
       
   242     }
       
   243 
       
   244 void CPrimaryContextsMonitor::StartContextStatusMonitoringL(const TName& aContextName)
       
   245     {
       
   246     CContextStatusMonitor* newStatusMonitor = new (ELeave) CContextStatusMonitor(iPacketService, *this);
       
   247     CleanupStack::PushL(newStatusMonitor);
       
   248     iContextMonitors.AppendL(newStatusMonitor);
       
   249     CleanupStack::Pop(newStatusMonitor);
       
   250     newStatusMonitor->StartL(aContextName);
       
   251     }
       
   252 
       
   253 CContextStatusMonitor::CContextStatusMonitor(RPacketService& aPacketService, MContextEventsObserver& aCallback):CActive(EPriorityStandard),
       
   254     iPacketService(aPacketService), iCallback(aCallback)
       
   255     {
       
   256     CActiveScheduler::Add(this);
       
   257     }
       
   258 
       
   259 CContextStatusMonitor::~CContextStatusMonitor()
       
   260     {
       
   261     Cancel();
       
   262     iPacketContext.Close();
       
   263     }
       
   264 
       
   265 TBool CContextStatusMonitor::StartL(const TName& aContextName)
       
   266     {
       
   267     iContextName.Copy(aContextName);
       
   268     User::LeaveIfError(iPacketContext.OpenExistingContext(iPacketService, iContextName));
       
   269     User::LeaveIfError(iPacketContext.GetStatus(iContextStatus));
       
   270 
       
   271     if (iContextStatus == RPacketContext::EStatusDeleted)
       
   272         {
       
   273         return EFalse;
       
   274         }
       
   275 
       
   276     if (iContextStatus == RPacketContext::EStatusActive ||
       
   277         iContextStatus == RPacketContext::EStatusSuspended ||
       
   278         iContextStatus == RPacketContext::EStatusDeactivating)
       
   279         {
       
   280         iWasActive = ETrue;
       
   281         }
       
   282 
       
   283     iPacketContext.NotifyStatusChange(iStatus, iContextStatus);
       
   284     SetActive();
       
   285     return ETrue;
       
   286     }
       
   287 
       
   288 void CContextStatusMonitor::RunL()
       
   289     {
       
   290     User::LeaveIfError(iStatus.Int());
       
   291     if (iContextStatus == RPacketContext::EStatusActive)
       
   292         {
       
   293         iWasActive = ETrue;
       
   294         }
       
   295 
       
   296     if (iContextStatus == RPacketContext::EStatusDeleted)
       
   297         {
       
   298         iPacketContext.CancelAsyncRequest(EPacketContextNotifyStatusChange);
       
   299         iCallback.PrimaryContextDeleted(this);
       
   300         }
       
   301     else
       
   302         {
       
   303         iPacketContext.NotifyStatusChange(iStatus, iContextStatus);
       
   304         SetActive();
       
   305         }
       
   306     }
       
   307 
       
   308 void CContextStatusMonitor::DoCancel()
       
   309     {
       
   310     iPacketContext.CancelAsyncRequest(EPacketContextNotifyStatusChange);
       
   311     }
       
   312 
       
   313 TInt CContextStatusMonitor::RunError(TInt aError)
       
   314     {
       
   315     iCallback.ContextMonitoringError(this, aError);
       
   316     return KErrNone;
       
   317     }
       
   318 
       
   319 
       
   320 CPdpContentionManager* CPdpContentionManager::NewL(const ESock::CTierManagerBase& aTierManager, RPacketService& aPacketService)
       
   321     {
       
   322     CPdpContentionManager* self = new (ELeave) CPdpContentionManager(aTierManager);
       
   323     CleanupStack::PushL(self);
       
   324     self->ConstructL(aPacketService);
       
   325     CleanupStack::Pop(self);
       
   326     return self;
       
   327     }
       
   328 
       
   329 CPdpContentionManager::CPdpContentionManager(const ESock::CTierManagerBase& aTierManager):
       
   330 CContentionManager(aTierManager)
       
   331     {
       
   332     }
       
   333 
       
   334 CPdpContentionManager::~CPdpContentionManager()
       
   335     {
       
   336     delete iPrimaryContextsMonitor;
       
   337     }
       
   338 
       
   339 void CPdpContentionManager::ConstructL(RPacketService& aPacketService)
       
   340     {
       
   341     iPrimaryContextsMonitor = new (ELeave) CPrimaryContextsMonitor(aPacketService, *this);
       
   342     }
       
   343 
       
   344 void CPdpContentionManager::StartMonitoringL()
       
   345     {
       
   346     if (iPrimaryContextsMonitor)
       
   347         {
       
   348         iPrimaryContextsMonitor->StartL();
       
   349         }
       
   350     }
       
   351 
       
   352 void CPdpContentionManager::ContentionResolved(const TContentionRequestItem& aContentionRequest, TBool aResult)
       
   353     {
       
   354     CPdpMetaConnectionProvider* pdpMcpr = static_cast<CPdpMetaConnectionProvider*>(aContentionRequest.iMcpr);
       
   355     
       
   356     pdpMcpr->ContentionResolved(aContentionRequest.iPendingCprId, aResult);
       
   357     }
       
   358 
       
   359 void CPdpContentionManager::ContentionOccured(ESock::CMetaConnectionProviderBase& aMcpr)
       
   360     {
       
   361     CPdpMetaConnectionProvider& pdpMcpr = static_cast<CPdpMetaConnectionProvider&>(aMcpr);
       
   362     
       
   363     pdpMcpr.ContentionOccured();
       
   364     }
       
   365 
       
   366 void CPdpContentionManager::ReportContentionAvailabilityStatus(ESock::CMetaConnectionProviderBase& aMcpr, const ESock::TAvailabilityStatus& aStatus) const
       
   367     {
       
   368     CPdpMetaConnectionProvider& pdpMcpr = static_cast<CPdpMetaConnectionProvider&>(aMcpr);
       
   369     
       
   370     pdpMcpr.ReportContentionAvailabilityStatus(aStatus);
       
   371     }
       
   372