diff -r 000000000000 -r 96e5fb8b040d kerneltest/f32test/shostmassstorage/msman/app/cdisplay.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/f32test/shostmassstorage/msman/app/cdisplay.cpp Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,718 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "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: +// USB Mass Storage Application - also used as an improvised boot loader mechanism +// +// + + + +/** + @file +*/ + +#include +#include + +#include "rusbotgsession.h" + +#include "usbtypes.h" +#include "mdrivedisplay.h" +#include "cdisplay.h" + +// Display positions and test constants +// Number of attached devices +static const TInt KRow_DevicesNumber = 13; +_LIT(KMsg_DevicesAttached, "USB Devices Attached = %d"); + +// Device Map +static const TInt KStartRow_DeviceMap = KRow_DevicesNumber + 2; +static const TInt KMaxRows_DeviceMap = 4; +_LIT(KMsg_DeviceMap_DriveList, "%d: "); // [drive index] +_LIT(KMsg_DeviceMap_DriveLunEntry, "%c "); // [drive letter] + + +// Drive Map +static const TInt KStartRow_DriveMap = KStartRow_DeviceMap + KMaxRows_DeviceMap; +static const TInt KMaxRows_DriveMap = 4; +_LIT(KMsg_DriveMap_EntryLetter, "%c token = %d"); // [drive letter] [token] +_LIT(KDbgMsg_DriveMap_EntryLetter, "*** %c token = %d"); // [drive letter] [token] + +// System Status +static const TInt KStartRow_UpTime = 28; +_LIT(KMsg_UpTime, "up time : %dh:%dm:%ds "); // use trailing space to overwrite any leftover chars in line + +static const TInt KStartRow_MemoryFree = 29; +_LIT(KMsg_MemoryFree, "mem (bytes) : 0x%X"); + +// User Keys +static const TInt KStartRow_UserKeys = 25; +_LIT(KMsgUser1Keys, "[Esc]=Quit [A-Z]=DriveInfo"); +_LIT(KMsgUser2Keys, "[F5]=Hub update"); + + +// Scroll Window status +_LIT(KScrollWindowStatus, "Page %d of %d"); + +// Available drives +static const TInt KStartRow_AvailableDrives = 1; +_LIT(KAvailDriveMsg, "Drives: "); + +_LIT(KDriveAtts,"DriveList %c: %02x "); + +// Drive info +static const TInt KStartRow_MsgWindow = 3; +static const TInt KStartRow_DriveInfo = KStartRow_MsgWindow; + +// **************************************************************************** + + +CScrollWindow* CScrollWindow::NewL(CConsoleBase& aConsole) + { + CScrollWindow* r = new (ELeave) CScrollWindow(aConsole); + CleanupStack::PushL(r); + r->ConstructL(); + CleanupStack::Pop(r); + return r; + } + + +void CScrollWindow::ConstructL() + { + + } + + +CScrollWindow::CScrollWindow(CConsoleBase& aConsole) +: iConsole(aConsole) + { + } + +CScrollWindow::~CScrollWindow() + { + iLineArray.Close(); + } + +void CScrollWindow::Reset() + { + iPage = 0; + iLineArray.Reset(); + } + + +void CScrollWindow::AppendL(const TDesC& aLine) + { + iTmpLine.Zero(); + iLineArray.AppendL(iTmpLine); + TInt last = iLineArray.Count() - 1; + iLineArray[last].Copy(aLine); + } + + +TLine* CScrollWindow::NewLineL() + { + iTmpLine.Zero(); + iLineArray.AppendL(iTmpLine); + TInt last = iLineArray.Count() - 1; + return &iLineArray[last]; + } + + +void CScrollWindow::Update() + { + TInt line = iPage * KPageLength; + + TInt row = KStartRow_DriveInfo; + do + { + iConsole.SetPos(0, row + line%KPageLength); + if (line < iLineArray.Count()) + { + iConsole.Printf(iLineArray[line]); + } + iConsole.ClearToEndOfLine(); + line++; + } + while (((line-1)%KPageLength) != (KPageLength - 1)); + iConsole.SetPos(0, KStartRow_DriveInfo + KPageLength); + iConsole.Printf(KScrollWindowStatus, iPage + 1, iLineArray.Count()/KPageLength + 1); + } + +void CScrollWindow::PageInc() + { + TInt lastPage = iLineArray.Count()/KPageLength; + if (iPage == lastPage) + { + iPage = 0; + } + else + { + iPage++; + } + } + + +void CScrollWindow::PageDec() + { + if (iPage == 0) + { + TInt lastPage = iLineArray.Count()/KPageLength; + iPage = lastPage; + } + else + { + iPage--; + } + } + + + +CDisplay* CDisplay::NewLC(RFs& aFs, CConsoleBase& aConsole) + { + CDisplay* r = new (ELeave) CDisplay(aFs, aConsole); + CleanupStack::PushL(r); + r->ConstructL(); + return r; + } + + +void CDisplay::ConstructL() + { + iScrollWindow = CScrollWindow::NewL(iConsole); + } + + +CDisplay::CDisplay(RFs& aFs, CConsoleBase& aConsole) +: iFs(aFs), + iConsole(aConsole) + { + iConsole.ClearScreen(); + } + + +CDisplay::~CDisplay() + { + delete iScrollWindow; + } + + +void CDisplay::Menu() + { + iConsole.SetPos(0, KStartRow_UserKeys); + iConsole.Printf(KMsgUser1Keys); + iConsole.SetPos(0, KStartRow_UserKeys + 1); + iConsole.Printf(KMsgUser2Keys); + iCursorPos = iConsole.CursorPos(); + } + + +void CDisplay::DriveListL() const +{ + TDriveList drivelist; + TRAPD(err, iFs.DriveList(drivelist)); + if (err) + { + return; + } + // A TDriveList (the list of available drives), is an array of + // 26 bytes. Each byte with a non zero value signifies that the + // corresponding drive is available. + TBuf iLineBuffer; + iLineBuffer = KAvailDriveMsg; + TChar driveLetter; + + for (TInt driveNumber = EDriveA; driveNumber <= EDriveZ;driveNumber++) + { + if (drivelist[driveNumber]) // if drive-list entry non-zero, drive is available + { + // overflow check + if (iLineBuffer.Length() == iLineBuffer.MaxLength()) + { + iLineBuffer[iLineBuffer.MaxLength() - 1] = '>'; + break; + } + + User::LeaveIfError(iFs.DriveToChar(driveNumber,driveLetter)); + + // The following line prints the drive letter followed by the hex value + // of the integer indicating that drive's attributes + RDebug::Print(KDriveAtts,TUint(driveLetter), drivelist[driveNumber]); + iLineBuffer.Append(driveLetter); + + } + } + + iConsole.SetPos(0, KStartRow_AvailableDrives); + iConsole.Printf(iLineBuffer); + iConsole.ClearToEndOfLine(); + CursorHome(); +} + + +void CDisplay::DevicesNumber(TInt aDevicesNumber) const + { + iConsole.SetPos(0, KRow_DevicesNumber); + iConsole.Printf(KMsg_DevicesAttached, aDevicesNumber); + iConsole.ClearToEndOfLine(); + } + + +void CDisplay::DriveMapL(const TDriveMap& aDriveMap) const + { + TChar letter; + + TInt i = 0; + + // Output to debug port + for (; i < aDriveMap.Count(); i++) + { + TToken token = aDriveMap[i]; + if (token) + { + User::LeaveIfError(iFs.DriveToChar(i, letter)); + RDebug::Print(KDbgMsg_DriveMap_EntryLetter, TUint(letter), token); + } + } + + // Output to console + TInt row = KStartRow_DriveMap; + for (i = (aDriveMap.Count() -1); i >= 0 && row < (KStartRow_DriveMap + KMaxRows_DriveMap); i--) + { + TToken token = aDriveMap[i]; + if (token) + { + User::LeaveIfError(iFs.DriveToChar(i, letter)); + iConsole.SetPos(0, row); + iConsole.Printf(KMsg_DriveMap_EntryLetter, TUint(letter), token); + iConsole.ClearToEndOfLine(); + row++; + } + } + + for (; row < KStartRow_DriveMap + KMaxRows_DriveMap; row++) + { + iConsole.SetPos(0, row); + iConsole.ClearToEndOfLine(); + } + } + + +void CDisplay::DeviceMapL(TInt aRow, TInt deviceIndex, const TDeviceMap& aDeviceMap) const + { + TChar letter; + TInt drive; + + // Output to debug port + RDebug::Printf("*** deviceIndex = %d", deviceIndex); + for (TInt lunIndex = 0; lunIndex < 16; lunIndex++) + { + drive = aDeviceMap[lunIndex]; + + if (drive == 0) + break; + + User::LeaveIfError(iFs.DriveToChar(drive, letter)); + RDebug::Printf("*** drive=%d %c", drive, TUint(letter)); + } + + // Output to console + if (aRow >= KMaxRows_DeviceMap) + { + return; + } + RDebug::Printf("-----> Device MAP %x", deviceIndex); + TInt row = KStartRow_DeviceMap + aRow; + iConsole.SetPos(0, row); + iConsole.Printf(KMsg_DeviceMap_DriveList, deviceIndex); + + for (TInt lunIndex = 0; lunIndex < 16; lunIndex++) + { + drive = aDeviceMap[lunIndex]; + + if (drive == 0) + break; + + User::LeaveIfError(iFs.DriveToChar(drive, letter)); + iConsole.Printf(KMsg_DeviceMap_DriveLunEntry, TUint(letter)); + iConsole.ClearToEndOfLine(); + } + } + + +void CDisplay::DeviceMapClear(TInt aRow) const + { + TInt row = KStartRow_DeviceMap; + + if (aRow > KMaxRows_DeviceMap) + return; + + for (row = KStartRow_DeviceMap + aRow; row < KStartRow_DeviceMap + KMaxRows_DeviceMap; row++) + { + iConsole.SetPos(0, row); + iConsole.ClearToEndOfLine(); + } + } + + +void CDisplay::GetDriveInfoL(TChar aChar) + { + iScrollWindow->Reset(); + + TDriveInfo driveInfo; + + TInt driveNumber; + User::LeaveIfError(iFs.CharToDrive(aChar, driveNumber)); + + TLine* line; + line = iScrollWindow->NewLineL(); + _LIT(KDrive,"Drive=%d %C"); + line->Format(KDrive, driveNumber, TInt(aChar.GetUpperCase())); + + iFs.Drive(driveInfo, driveNumber); + if (driveInfo.iDriveAtt == KDriveAbsent) + { + _LIT(KTxt_MappingDriveError, "Drive absent !"); + iScrollWindow->AppendL(KTxt_MappingDriveError); + return; + } + + FormatDriveInfoL(driveInfo); + + TVolumeInfo volumeInfo; + + TInt err = iFs.Volume(volumeInfo, driveNumber); + if (err != KErrNotReady) + // Volume() returns KErrNotReady if no volume present. + // In this case, check next drive number + { + FormatVolumeInfoL(volumeInfo); + } + } + + +void CDisplay::DriveInfo() + { + iScrollWindow->Update(); + CursorHome(); + } + +void CDisplay::FormatDriveInfoL(const TDriveInfo& aDriveInfo) + { + // Append battery, media and drive information to aBuffer + // Define descriptor constants using the _LIT macro + _LIT(KDriveInfo1, "iType=%02x iDriveAtt=%02x"); + _LIT(KDriveInfo2, "iBattery=%02x iMediaAtt=%02x"); + _LIT(KBatLow,"Battery low"); + _LIT(KBatGood,"Battery good"); + _LIT(KBatNotSupported,"Battery not supported"); + _LIT(KNotPresent,"No media present"); + _LIT(KFloppy,"Media is floppy disk"); + _LIT(KHard,"Media is hard disk"); + _LIT(KCDROM,"Media is CD-ROM"); + _LIT(KRam,"Media is RAM"); + _LIT(KFlash,"Media is flash"); + _LIT(KRom,"Media is ROM"); + _LIT(KRemote,"Media is remote"); + _LIT(KNANDFlash,"Media is NAND flash"); + _LIT(KUnknown,"Media unknownl"); + _LIT(KDriveAtts,"Drive attributes:"); + _LIT(KLocal," local"); + _LIT(KROMDrive," ROM"); + _LIT(KRedirected," redirected"); + _LIT(KSubstituted," substituted"); + _LIT(KInternal," internal"); + _LIT(KRemovable," removable"); + _LIT(KMediaAtts,"Media attributes:"); + _LIT(KDynamic," dynamic"); + _LIT(KDual," dual-density"); + _LIT(KFormattable," formattable"); + _LIT(KLockable," lockable"); + _LIT(KLocked," locked"); + _LIT(KHasPassword," has password"); + _LIT(KWriteProtected," write-protected"); + + TLine* line; + line = iScrollWindow->NewLineL(); + line->Format(KDriveInfo1, TInt(aDriveInfo.iType), TInt(aDriveInfo.iDriveAtt)); + + line = iScrollWindow->NewLineL(); + line->Format(KDriveInfo2, TInt(aDriveInfo.iBattery), TInt(aDriveInfo.iMediaAtt)); + + line = iScrollWindow->NewLineL(); + switch (aDriveInfo.iBattery) + { + case EBatLow: + line->Append(KBatLow); + break; + case EBatGood: + line->Append(KBatGood); + break; + default: + line->Append(KBatNotSupported); + } + + line = iScrollWindow->NewLineL(); + switch (aDriveInfo.iType) + { + case EMediaNotPresent: + line->Append(KNotPresent); + break; + case EMediaFloppy: + line->Append(KFloppy); + break; + case EMediaHardDisk: + line->Append(KHard); + break; + case EMediaCdRom: + line->Append(KCDROM); + break; + case EMediaRam: + line->Append(KRam); + break; + case EMediaFlash: + line->Append(KFlash); + break; + case EMediaRom: + line->Append(KRom); + break; + case EMediaRemote: + line->Append(KRemote); + break; + case EMediaNANDFlash: + line->Append(KNANDFlash); + break; + default: + line->Append(KUnknown); + + } + + // Drive Attributes + line = iScrollWindow->NewLineL(); + line->Append(KDriveAtts); + if (aDriveInfo.iDriveAtt & KDriveAttLocal) + { + line = iScrollWindow->NewLineL(); + line->Append(KLocal); + } + if (aDriveInfo.iDriveAtt & KDriveAttRom) + { + line = iScrollWindow->NewLineL(); + line->Append(KROMDrive); + } + if (aDriveInfo.iDriveAtt & KDriveAttRedirected) + { + line = iScrollWindow->NewLineL(); + line->Append(KRedirected); + } + if (aDriveInfo.iDriveAtt & KDriveAttSubsted) + { + line = iScrollWindow->NewLineL(); + line->Append(KSubstituted); + } + if (aDriveInfo.iDriveAtt & KDriveAttInternal) + { + line = iScrollWindow->NewLineL(); + line->Append(KInternal); + } + if (aDriveInfo.iDriveAtt & KDriveAttRemovable) + { + line = iScrollWindow->NewLineL(); + line->Append(KRemovable); + } + + // Media Attributes + line = iScrollWindow->NewLineL(); + line->Append(KMediaAtts); + if (aDriveInfo.iMediaAtt & KMediaAttVariableSize) + { + line = iScrollWindow->NewLineL(); + line->Append(KDynamic); + } + if (aDriveInfo.iMediaAtt & KMediaAttDualDensity) + { + line = iScrollWindow->NewLineL(); + line->Append(KDual); + } + if (aDriveInfo.iMediaAtt & KMediaAttFormattable) + { + line = iScrollWindow->NewLineL(); + line->Append(KFormattable); + } + if (aDriveInfo.iMediaAtt & KMediaAttWriteProtected) + { + line = iScrollWindow->NewLineL(); + line->Append(KWriteProtected); + } + if (aDriveInfo.iMediaAtt & KMediaAttLockable) + { + line = iScrollWindow->NewLineL(); + line->Append(KLockable); + } + + if (aDriveInfo.iMediaAtt & KMediaAttLocked) + { + line = iScrollWindow->NewLineL(); + line->Append(KLocked); + } + if (aDriveInfo.iMediaAtt & KMediaAttHasPassword) + { + line = iScrollWindow->NewLineL(); + line->Append(KHasPassword); + } + } + +void CDisplay::FormatVolumeInfoL(const TVolumeInfo& aVolumeInfo) + { + // Append volume information to line + _LIT(KUID, "Unique ID: 0x%08X"); + _LIT(KSize, "Size: 0x%LX bytes"); + _LIT(KFree, "Free space: 0x%LX bytes"); + _LIT(KVolName, "Volume name: %S"); + TLine* line; + line = iScrollWindow->NewLineL(); + line->Format(KUID, aVolumeInfo.iUniqueID); + line = iScrollWindow->NewLineL(); + line->Format(KSize, aVolumeInfo.iSize); + line = iScrollWindow->NewLineL(); + line->Format(KFree, aVolumeInfo.iFree); + line = iScrollWindow->NewLineL(); + line->Format(KVolName, &aVolumeInfo.iName); + + } + + +void CDisplay::UpTime(TUint aUpTime) const + { + TUint totalMins = aUpTime/60; + TUint totalHrs = totalMins/60; + iConsole.SetPos(0, KStartRow_UpTime); + iConsole.Printf(KMsg_UpTime, totalHrs, totalMins%60, aUpTime%60); + CursorHome(); + } + +void CDisplay::MemoryFree(TInt aBytes) const + { + iConsole.SetPos(0, KStartRow_MemoryFree); + iConsole.Printf(KMsg_MemoryFree, aBytes); + CursorHome(); + } + + +////////////////////////////////////////////////////////////////////////////// +// +// CMessageKeyProcessor +// +////////////////////////////////////////////////////////////////////////////// +CMessageKeyProcessor::CMessageKeyProcessor(CDisplay& aDisplay, RUsbOtgSession& aUsbOtgSession) +: CActive(CActive::EPriorityUserInput), + iDisplay(aDisplay), + iUsbOtgSession(aUsbOtgSession) + { + } + +CMessageKeyProcessor* CMessageKeyProcessor::NewLC(CDisplay& aDisplay, RUsbOtgSession& aUsbOtgSession) + { + CMessageKeyProcessor* self=new (ELeave) CMessageKeyProcessor(aDisplay, aUsbOtgSession); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + + +void CMessageKeyProcessor::ConstructL() + { + // Add to active scheduler + CActiveScheduler::Add(this); + RequestCharacter(); + } + + +CMessageKeyProcessor::~CMessageKeyProcessor() + { + // Make sure we're cancelled + Cancel(); + } + +void CMessageKeyProcessor::DoCancel() + { + iDisplay.ReadCancel(); + } + +void CMessageKeyProcessor::RunL() + { + // Handle completed request + ProcessKeyPressL(iDisplay.KeyCode()); + } + +void CMessageKeyProcessor::RequestCharacter() + { + // A request is issued to the CConsoleBase to accept a + // character from the keyboard. + iDisplay.Read(iStatus); + SetActive(); + } + +void CMessageKeyProcessor::ProcessKeyPressL(TKeyCode aKeyCode) + { + TBool done = HandleKeyL(aKeyCode); + + if (done) + { + CActiveScheduler::Stop(); + return; + } + + RequestCharacter(); + } + + +TBool CMessageKeyProcessor::HandleKeyL(TKeyCode aKeyCode) + { + TBool done = EFalse; + if (TChar(aKeyCode).IsAlpha()) + { + iDisplay.GetDriveInfoL(aKeyCode); + iDisplay.DriveInfo(); + return done; + } + + switch (aKeyCode) + { + case EKeyF5: + { + // Update USB status + iUsbOtgSession.DeviceInserted(); + iDisplay.DriveListL(); + } + break; + + case EKeyUpArrow: + case EKeyPageUp: + iDisplay.PageDec(); + iDisplay.DriveInfo(); + break; + case EKeyDownArrow: + case EKeyPageDown: + iDisplay.PageInc(); + iDisplay.DriveInfo(); + break; + case EKeyEscape: + done = ETrue; + break; + default: + break; + } + return done; + } + +