kerneltest/f32test/shostmassstorage/msman/app/cdisplay.cpp
changeset 9 96e5fb8b040d
child 6 0173bcd7697c
--- /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 <e32cons.h>
+#include <f32file.h>
+
+#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<KDisplayWidth> 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;
+    }
+
+