usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/src/referencepolicyplugin.cpp
changeset 0 c9bc50fca66e
child 15 f92a4f87e424
equal deleted inserted replaced
-1:000000000000 0:c9bc50fca66e
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #include "referencepolicyplugin.h"
       
    24 #include <centralrepository.h>
       
    25 #include <e32std.h>
       
    26 #include <usb/usblogger.h>
       
    27 #include <usb/hostms/msmm_policy_def.h>
       
    28 #include "refppnotificationman.h"
       
    29 #include "srvpanic.h"
       
    30  
       
    31 #ifdef __FLOG_ACTIVE
       
    32 _LIT8(KLogComponent, "UsbHostMsmmRefPP");
       
    33 #endif
       
    34 
       
    35 //  Global Variables
       
    36 const TUid KHostMsRepositoryUid = {0x10285c46};
       
    37 const TUint32 KPermittedRangeUid = 0x00010000;
       
    38 const TUint32 KForbiddenListUid = 0x00010001;
       
    39 const TUint32 KMaxHistoryCountUid = 0x00010002;
       
    40 const TUint32 KOTGCapableSuspendTimeUid = 0x00010003;
       
    41 const TUint32 KMediaPollingTimeUid = 0x00010004;
       
    42 const TUint32 KHistoryCountUid = 0x00010100;
       
    43 const TUint32 KFirstHistoryUid = 0x00010101;
       
    44 
       
    45 const TUint KHistoryGranularity = 0x8;
       
    46 const TUint KPermittedDrvRangeBufLen = 0x3;
       
    47 
       
    48 CReferencePolicyPlugin::~CReferencePolicyPlugin()
       
    49     {
       
    50     LOG_FUNC
       
    51     Cancel();
       
    52     ClearHistory(); // Remove all buffered history record.
       
    53     delete iRepository;
       
    54     delete iNotificationMan;
       
    55     iFs.Close();
       
    56     }
       
    57 
       
    58 CReferencePolicyPlugin* CReferencePolicyPlugin::NewL()
       
    59     {
       
    60     LOG_STATIC_FUNC_ENTRY
       
    61     CReferencePolicyPlugin* self = new (ELeave) CReferencePolicyPlugin;
       
    62     CleanupStack::PushL(self);
       
    63     self->ConstructL();
       
    64     CleanupStack::Pop(self);
       
    65     
       
    66     return self;
       
    67     }
       
    68 
       
    69 void CReferencePolicyPlugin::RetrieveDriveLetterL(TText& aDriveName,
       
    70         const TPolicyRequestData& aData, TRequestStatus& aStatus)
       
    71     {
       
    72     LOG_FUNC
       
    73     Cancel();
       
    74     aStatus = KRequestPending;
       
    75     iClientStatus = &aStatus;    
       
    76 
       
    77     RetrieveDriveLetterL(aDriveName, aData);
       
    78     // In a licensee owned policy plugin, it shall complete client 
       
    79     // request in RunL() in general 
       
    80     Complete(KErrNone);
       
    81     }
       
    82 
       
    83 void CReferencePolicyPlugin::CancelRetrieveDriveLetter()
       
    84     {
       
    85     LOG_FUNC
       
    86     Cancel();
       
    87     }
       
    88 
       
    89 void CReferencePolicyPlugin::SaveLatestMountInfoL(
       
    90         const TPolicyMountRecord& aData, TRequestStatus& aStatus)
       
    91     {
       
    92     LOG_FUNC    
       
    93     Cancel();
       
    94     aStatus = KRequestPending;
       
    95     iClientStatus = &aStatus;
       
    96 
       
    97     SaveLatestMountInfoL(aData);
       
    98     // In a licensee owned policy plugin, it shall complete client 
       
    99     // request in RunL() in general 
       
   100     Complete(KErrNone);
       
   101     }
       
   102 
       
   103 void CReferencePolicyPlugin::CancelSaveLatestMountInfo()
       
   104     {
       
   105     LOG_FUNC
       
   106     Cancel();
       
   107     }
       
   108 
       
   109 void CReferencePolicyPlugin::SendErrorNotificationL(
       
   110         const THostMsErrData& aErrData)
       
   111     {
       
   112     LOG_FUNC
       
   113     iNotificationMan->SendErrorNotificationL(aErrData);
       
   114     }
       
   115 
       
   116 void CReferencePolicyPlugin::GetSuspensionPolicy(TSuspensionPolicy& aPolicy)
       
   117     {
       
   118     LOG_FUNC
       
   119     aPolicy = iSuspensionPolicy;
       
   120     }
       
   121 
       
   122 void CReferencePolicyPlugin::DoCancel()
       
   123     {
       
   124     LOG_FUNC
       
   125     // No more work need to do in current implementation of reference
       
   126     // policy plugin. 
       
   127     // In a licensee owned policy plugin, it shall complete client 
       
   128     // request here with KErrCancel.
       
   129     }
       
   130 
       
   131 void CReferencePolicyPlugin::RunL()
       
   132     {
       
   133     LOG_FUNC
       
   134     // No more work need to do in current implementation of reference
       
   135     // policy plugin. 
       
   136     // In a licensee owned policy plugin, it shall complete client 
       
   137     // request here with a proper error code.
       
   138     }
       
   139 
       
   140 CReferencePolicyPlugin::CReferencePolicyPlugin() :
       
   141 CMsmmPolicyPluginBase(),
       
   142 iHistory(KHistoryGranularity)
       
   143     {
       
   144     LOG_FUNC
       
   145     CActiveScheduler::Add(this);
       
   146     }
       
   147 
       
   148 void CReferencePolicyPlugin::ConstructL()
       
   149     {
       
   150     LOG_FUNC
       
   151     iRepository = CRepository::NewL(KHostMsRepositoryUid);
       
   152     User::LeaveIfError(iFs.Connect());
       
   153     iNotificationMan = CMsmmPolicyNotificationManager::NewL();
       
   154     RetrieveHistoryL();
       
   155     AvailableDriveListL();
       
   156     TInt value = 0;
       
   157     User::LeaveIfError(iRepository->Get(
       
   158             KOTGCapableSuspendTimeUid, value));
       
   159     iSuspensionPolicy.iOtgSuspendTime = value;
       
   160     User::LeaveIfError(iRepository->Get(
       
   161             KMediaPollingTimeUid, value));
       
   162     iSuspensionPolicy.iStatusPollingInterval = value;
       
   163     }
       
   164 
       
   165 void CReferencePolicyPlugin::RetrieveDriveLetterL(TText& aDriveName,
       
   166         const TPolicyRequestData& aData)
       
   167     {
       
   168     LOG_FUNC
       
   169 
       
   170     TDriveList availableNames;
       
   171     FilterFsForbiddenDriveListL(availableNames);
       
   172 
       
   173     if (!availableNames.Length())
       
   174         {
       
   175         // Not any drive letter available
       
   176         User::Leave(KErrNotFound);
       
   177         }
       
   178 
       
   179     // According to REQ8922, When a particular Logical Unit is mounted 
       
   180     // for the first time, RefPP shall always try to allocate an 
       
   181     // available and unused drive letter to it. Only if such a drive letter
       
   182     // can not be found, RefPP shall use the first one in available name
       
   183     // list;
       
   184     
       
   185     // Initialize aDriveName by the first available drive letter
       
   186     aDriveName = availableNames[0];
       
   187     // Find first such drive letter from available letter list. If it can
       
   188     // be found, it will be used.
       
   189     FindFirstNotUsedDriveLetter(availableNames, aDriveName);    
       
   190     // Search history record
       
   191     TInt historyIndex = SearchHistoryByLogicUnit(aData);
       
   192     if (KErrNotFound != historyIndex)
       
   193         {
       
   194         // Find a match one in history
       
   195         const TPolicyMountRecord& history = *iHistory[historyIndex];
       
   196         TInt location = availableNames.Locate(TChar(history.iDriveName));
       
   197         if (KErrNotFound != location)
       
   198             {
       
   199             // And it is available now. RefPP allocate it to the 
       
   200             // LU currently mounted.
       
   201             aDriveName = history.iDriveName;
       
   202             }
       
   203         }
       
   204     }
       
   205 
       
   206 void CReferencePolicyPlugin::SaveLatestMountInfoL(
       
   207         const TPolicyMountRecord& aData)
       
   208     {
       
   209     LOG_FUNC
       
   210 
       
   211     if (iMaxHistoryRecCount == 0) // This policy disable history
       
   212         {
       
   213         return;
       
   214         }
       
   215     
       
   216     TPolicyMountRecord* historyRecord = 
       
   217             new (ELeave) TPolicyMountRecord(aData);
       
   218     CleanupStack::PushL(historyRecord);
       
   219     TInt historyIndex = SearchHistoryByLogicUnit(aData.iLogicUnit);
       
   220     if (KErrNotFound == historyIndex)
       
   221     	{
       
   222         // No matched record exist
       
   223 		if (iHistory.Count() == iMaxHistoryRecCount)
       
   224 			{
       
   225 			// Remove the oldest entity
       
   226 			delete iHistory[0];
       
   227 			iHistory.Remove(0);
       
   228 			}
       
   229     	}
       
   230     else
       
   231     	{
       
   232     	// Remove the replaced entity
       
   233     	delete iHistory[historyIndex];
       
   234     	iHistory.Remove(historyIndex);
       
   235     	}
       
   236     iHistory.AppendL(historyRecord); // Push the new entity
       
   237     CleanupStack::Pop(historyRecord);
       
   238 
       
   239     TUint32 historyRecordUid = KFirstHistoryUid;
       
   240     User::LeaveIfError(iRepository->Set(KHistoryCountUid, iHistory.Count()));
       
   241     for (TInt index = 0; index < iHistory.Count(); index++)
       
   242         {
       
   243         TPckg<TPolicyMountRecord> historyPckg(*iHistory[index]);
       
   244         User::LeaveIfError(iRepository->Set(historyRecordUid++, historyPckg));
       
   245         }
       
   246     }
       
   247 
       
   248 void CReferencePolicyPlugin::Complete(TInt aError)
       
   249     {
       
   250     LOG_FUNC
       
   251     User::RequestComplete(iClientStatus, aError);
       
   252     }
       
   253 
       
   254 void CReferencePolicyPlugin::PrepareAvailableDriveList()
       
   255     {
       
   256     LOG_FUNC
       
   257     iAvailableDrvList.SetLength(KMaxDrives);
       
   258     iAvailableDrvList.Fill(0, KMaxDrives);
       
   259     }
       
   260 
       
   261 void CReferencePolicyPlugin::AvailableDriveListL()
       
   262     {
       
   263     LOG_FUNC
       
   264     TBuf8<KPermittedDrvRangeBufLen> permittedRange;
       
   265     TDriveList forbiddenList;
       
   266 
       
   267     PrepareAvailableDriveList();
       
   268 
       
   269     User::LeaveIfError(iRepository->Get(KPermittedRangeUid, permittedRange));
       
   270     User::LeaveIfError(iRepository->Get(KForbiddenListUid, forbiddenList));
       
   271 
       
   272     for (TInt index = 'A'; index <= 'Z'; index++ )
       
   273         {
       
   274         if ((index >= permittedRange[0]) && (index <= permittedRange[1]))
       
   275             {
       
   276             if (KErrNotFound == forbiddenList.Locate(TChar(index)))
       
   277                 {
       
   278                 // Permitted
       
   279                 iAvailableDrvList[index - 'A'] = 0x01;
       
   280                 }
       
   281             }
       
   282         }
       
   283     }
       
   284 
       
   285 void CReferencePolicyPlugin::FilterFsForbiddenDriveListL(
       
   286         TDriveList& aAvailableNames)
       
   287     {
       
   288     LOG_FUNC
       
   289     TDriveList names;
       
   290     names.SetLength(KMaxDrives);
       
   291 
       
   292     TDriveList drives;
       
   293     User::LeaveIfError(iFs.DriveList(drives));
       
   294 
       
   295     TUint count(0);
       
   296     for (TInt index = 0; index < KMaxDrives; index++ )
       
   297         {
       
   298         if ((drives[index] == 0x0) && (iAvailableDrvList[index]))
       
   299             {
       
   300             names[count++] = index+'A';
       
   301             }
       
   302         }
       
   303     names.SetLength(count);
       
   304     aAvailableNames = names;
       
   305     }
       
   306 
       
   307 void CReferencePolicyPlugin::FindFirstNotUsedDriveLetter(
       
   308         const TDriveList& aAvailableNames,
       
   309         TText& aDriveName)
       
   310     {
       
   311     LOG_FUNC
       
   312     TDriveList usedLetter;
       
   313     TUint index = 0;
       
   314     for (index = 0; index < iHistory.Count(); index++)
       
   315         {
       
   316         const TPolicyMountRecord& record = *iHistory[index];
       
   317         usedLetter.Append(TChar(record.iDriveName));
       
   318         }
       
   319     for (index = 0; index < aAvailableNames.Length(); index++)
       
   320         {
       
   321         if (usedLetter.Locate(aAvailableNames[index]) == KErrNotFound)
       
   322             {
       
   323             aDriveName = aAvailableNames[index];
       
   324             return; // A unused drive letter found out
       
   325             }
       
   326         }
       
   327     }
       
   328 
       
   329 // Retrieve history from CR
       
   330 void CReferencePolicyPlugin::RetrieveHistoryL()
       
   331     {
       
   332     LOG_FUNC
       
   333     // Read history record number from CR
       
   334     TInt historyCount(0);
       
   335     User::LeaveIfError(
       
   336             iRepository->Get(KMaxHistoryCountUid, iMaxHistoryRecCount));
       
   337     User::LeaveIfError(iRepository->Get(KHistoryCountUid, historyCount));
       
   338 
       
   339     TUint32 historyRecordUid = KFirstHistoryUid;
       
   340     if (historyCount)
       
   341         {
       
   342         TPolicyMountRecord historyRecord;
       
   343         TPckg<TPolicyMountRecord> historyArray(historyRecord);        
       
   344         for (TInt index = 0; index < historyCount; index++)
       
   345             {
       
   346             User::LeaveIfError(iRepository->Get(historyRecordUid++, 
       
   347                     historyArray));
       
   348             TPolicyMountRecord* record = new (ELeave) TPolicyMountRecord;
       
   349             memcpy(record, &historyRecord, sizeof(TPolicyMountRecord));
       
   350             CleanupStack::PushL(record);
       
   351             iHistory.AppendL(record);
       
   352             CleanupStack::Pop(record);
       
   353             }
       
   354         }
       
   355     }
       
   356 
       
   357 // Remove all buffered history
       
   358 void CReferencePolicyPlugin::ClearHistory()
       
   359     {
       
   360     LOG_FUNC
       
   361     iHistory.ResetAndDestroy();
       
   362     iHistory.Close();
       
   363     }
       
   364 
       
   365 // Search in history for a logic unit	
       
   366 TInt CReferencePolicyPlugin::SearchHistoryByLogicUnit(
       
   367         const TPolicyRequestData& aLogicUnit) const
       
   368     {
       
   369     LOG_FUNC
       
   370     TInt ret(KErrNotFound);
       
   371     TUint count = iHistory.Count();
       
   372     for (TUint index = 0; index < count; index ++)
       
   373         {
       
   374         const TPolicyMountRecord& record = *iHistory[index];
       
   375         const TPolicyRequestData& logicalUnit = record.iLogicUnit;
       
   376 
       
   377         if ((logicalUnit.iVendorId == aLogicUnit.iVendorId) &&
       
   378                 (logicalUnit.iProductId == aLogicUnit.iProductId) &&
       
   379                 (logicalUnit.iBcdDevice == aLogicUnit.iBcdDevice) &&
       
   380                 (logicalUnit.iConfigurationNumber == aLogicUnit.iConfigurationNumber) &&
       
   381                 (logicalUnit.iInterfaceNumber == aLogicUnit.iInterfaceNumber) &&
       
   382                 (logicalUnit.iSerialNumber == aLogicUnit.iSerialNumber) &&
       
   383                 (logicalUnit.iOtgInformation == aLogicUnit.iOtgInformation))
       
   384             {
       
   385             // Matched
       
   386             return index;
       
   387             }
       
   388         }
       
   389     // Can't find any matched records
       
   390     return ret;
       
   391     }
       
   392 
       
   393 // End of file