# HG changeset patch # User hgs # Date 1278677600 -3600 # Node ID 189ece41fa29bad94cd4995b6e63e9ff5891ae67 # Parent a5496987b1da2601a4fa72e5b95c14fdd70617f4 201027_05 diff -r a5496987b1da -r 189ece41fa29 bsptemplate/asspandvariant/template_variant/bld.inf --- a/bsptemplate/asspandvariant/template_variant/bld.inf Thu Jul 01 17:57:33 2010 +0100 +++ b/bsptemplate/asspandvariant/template_variant/bld.inf Fri Jul 09 13:13:20 2010 +0100 @@ -82,7 +82,6 @@ medlffstemplate soundsctemplate soundsctemplate_v2 -camerasctemplate exi2s //epbus //exbusab diff -r a5496987b1da -r 189ece41fa29 bsptemplate/asspandvariant/template_variant/camerasc/camerasc.cpp --- a/bsptemplate/asspandvariant/template_variant/camerasc/camerasc.cpp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,535 +0,0 @@ -// Copyright (c) 2006-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: -// template\template_variant\camerasc\camerasc.cpp -// Implementation of the template shared chunk camera physical device driver (PDD). -// This file is part of the Template Base port -// -// -#include "camerasc_plat.h" - -_LIT(KCameraScPddName, "CameraSc.TE"); -_LIT(KCameraScDfcQueueName, "CameraSc.TE.DfcQ"); - -/** -Standard export function for PDD factories. This creates a DPhysicalDevice derived object, in this case, -DTemplateCameraScPddFactory. -*/ -DECLARE_STANDARD_PDD() - { - return new DTemplateCameraScPddFactory; - } - -/** -Constructor for the shared chunk camera PDD factory class. -*/ -DTemplateCameraScPddFactory::DTemplateCameraScPddFactory() - { - // We currently support only unit 0 - iUnitsMask = 0x01; - - // Set the version number for this device. This is used to allow code to specify that it requires a - // minimum version of the device in order to operate. If the version requested is less than this then - // the device is safe to be used - iVersion = RDevCameraSc::VersionRequired(); - } - -/** -Destructor for the shared chunk camera PDD factory class. -*/ -DTemplateCameraScPddFactory::~DTemplateCameraScPddFactory() - { - } - -/** -Second stage constructor for the shared chunk camera PDD factory class. This must at least set a name for -the driver object. -@return KErrNone if successful, otherwise one of the system wide error codes. -*/ -TInt DTemplateCameraScPddFactory::Install() - { - __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPddFactory::Install()")); - - TInt r; - - // Create a DFC queue so that handling of both camera hardware callbacks and requests made to the LDD from - // user mode can be processed in the same thread, to avoid the use of semaphores - if ((r = Kern::DynamicDfcQCreate(iDfcQ, 26, KCameraScDfcQueueName)) == KErrNone) - { - // All PDD factories must have a unique name - r = SetName(&KCameraScPddName); - } - - __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPddFactory::Install() => Returning %d", r)); - - return r; - } - -/** -Returns the PDD's capabilities. This is not used by the Symbian OS device driver framework -or by the LDD but is here as some LDDs will make use of it. -@param aDes A descriptor into which to write capability information. -*/ -void DTemplateCameraScPddFactory::GetCaps(TDes8& /*aDes*/) const - { - } - -/** -Called by the kernel's device driver framework to check if this PDD is suitable for use -with a logical channel. This is called in the context of the client thread which requested -the creation of a logical channel, through a call to RBusLogicalChannel::DoCreate(). The -thread is in a critical section. -@param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate() - This is used to determine which sensor to use. -@param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate(). -@param aVer The version number of the logical channel which will use this physical channel. -@return KErrNone if successful, otherwise one of the system wide error codes. -*/ -TInt DTemplateCameraScPddFactory::Validate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& aVer) - { - // Check that the version requested is less than or equal to the version of this PDD - if (!Kern::QueryVersionSupported(RDevCameraSc::VersionRequired(), aVer)) - { - return KErrNotSupported; - } - - // Check that the unit number specifies the available sensor - if ((aUnit < 0) || (aUnit > 0)) - { - return KErrNotSupported; - } - - return KErrNone; - } - -/** -Called by the kernel's device driver framework to create a physical channel object. This -is called in the context of the client thread which requested the creation of a logical -channel, through a call to RBusLogicalChannel::DoCreate(). The thread is in a critical section. -@param aChannel Set by this function to point to the created physical channel object. -@param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate(). -@param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate(). -@param aVer The version number of the logical channel which will use this physical channel. -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DTemplateCameraScPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/) - { - __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPddFactory::Create()")); - - // Create an instance of the PDD channel object that will work with the Template sensor - DTemplateCameraScPdd* pD = new DTemplateCameraScPdd; - - aChannel = pD; - TInt r = KErrNoMemory; - - if (pD) - { - r = pD->DoCreate(this, aUnit); - } - - __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPddFactory::Create() => Returning %d", r)); - - return r; - } - -/** -Called by SetUnitOpen() to see if a particular unit is open. When called, the -iUnitInfoMutex fast mutex will be taken, ensuring safe access to iUnitsOpenMask. -@param aUnit The unit number to be checked for being open. -@return ETrue if the unit specified by aUnit is already open, otherwise EFalse. -*/ -TBool DTemplateCameraScPddFactory::IsUnitOpen(TInt aUnit) - { - return (iUnitsOpenMask & (1 << aUnit)); - } - -/** -Attempt to change the state of the unit open state for a particular unit. -@param aUnit The unit number to be set to open or closed state. -@param aIsOpen The required new state for the unit; either ETrue to set the state - to open or EFalse to set the state to closed. -@return KErrNone if the state was updated successfully, otherwise KErrInUse if an attempt - was made to set the unit status to open while it is already open. -*/ -TInt DTemplateCameraScPddFactory::SetUnitOpen(TInt aUnit, TBool aIsOpen) - { - // Wait until it is safe to access the unit state mask - NKern::FMWait(&iUnitInfoMutex); - - // Fail a request to open a unit that is already open - if (aIsOpen && IsUnitOpen(aUnit)) - { - __KTRACE_CAM(Kern::Printf("+ DTemplateCameraScPddFactory::SetUnitOpen() => Unit %d is already in use", aUnit)); - - // Release the unit state mask mutex - NKern::FMSignal(&iUnitInfoMutex); - - return KErrInUse; - } - - // Set or clear the unit's open status bit as required - if (aIsOpen) - { - iUnitsOpenMask |= (1 << aUnit); - } - else - { - iUnitsOpenMask &= ~(1 << aUnit); - } - - // Release the unit state mask mutex - NKern::FMSignal(&iUnitInfoMutex); - - return KErrNone; - } - -/** -Constructor for the shared chunk camera PDD class. -*/ -DTemplateCameraScPdd::DTemplateCameraScPdd() - { - // Set the unit number to -1 to indicate that this channel has never been registered - // with the PDD factory - iUnit = -1; - - // The channel has been created but not yet configured */ - iState = EUnconfigured; - } - -/** -Destructor for the shared chunk camera PDD class. This is called in the context of the client thread -once an 'ECloseMsg' message has been sent to the device driver DFC thread. -*/ -DTemplateCameraScPdd::~DTemplateCameraScPdd() - { - delete [] iCapsBuffer; - delete iSensor; - - // Indicate that a physical channel is no longer open on this unit - if (iUnit >= 0) - { - iPhysicalDevice->SetUnitOpen(iUnit, EFalse); - } - } - -/** -Second stage constructor for the H4 camera PDD. -@param aPhysicalDevice A pointer to the factory class that is creating this PDD -@param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate(). -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DTemplateCameraScPdd::DoCreate(DTemplateCameraScPddFactory* aPhysicalDevice, TInt aUnit) - { - __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::DoCreate()")); - - TInt r; - - iPhysicalDevice = aPhysicalDevice; - - // Check that a physical channel hasn't already been opened on this unit - if ((r = iPhysicalDevice->SetUnitOpen(aUnit, ETrue)) == KErrNone) - { - iUnit = aUnit; - - // Create an abstracted sensor interface - if ((iSensor = new DTemplateSensorIf(*this, DfcQ(aUnit))) != NULL) - { - if ((r = iSensor->DoCreate()) == KErrNone) - { - // Setup the capabilities of this device for later reference - if ((r = iSensor->GetCaps(iCaps)) > 0) - { - // And save the size as returned from the sensor - iCapsSize = r; - - // Although iCaps now points to a TCameraCapsV02 structure, it is actually a variable - // sized structure that was allocated as an array of TUint8 so save it to a TUint8 - // ptr so that it can be deleted properly - iCapsBuffer = (TUint8*) iCaps; - - // Enable the clocks needed by the camera subsystem and power up the sensor - r = iSensor->RequestPower(); - - // Some sensors power themselves up automatically in their DoCreate() function, - // so take this into account here - if (r == KErrAlreadyExists) - { - r = KErrNone; - } - } - } - } - else - { - r = KErrNoMemory; - } - } - - __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::DoCreate() => Returning %d", r)); - - return r; - } - -/** -An appropriate DFC queue to use for processing client requests (that is, those that won't be processed -in the context of the client thread), and also for processing image completion requests from the sensor -will have been setup by the PDD factory. Anything needing to run in this same DFC thread can access the -queue via this function. -@param aUnit The unit number for which to get the DFC queue. -@return The DFC queue to be used. -*/ -TDfcQue* DTemplateCameraScPdd::DfcQ(TInt /*aUnit*/) - { - return iPhysicalDevice->iDfcQ; - } - -/** -Called by the LDD in order to query the capabilities of the PDD. -@param aCapsBuf A reference to a descriptor owned by the LDD, containing a TCameraCapsV02 structure - for the capabilities. -*/ -void DTemplateCameraScPdd::Caps(TDes8& aCapsBuf) const - { - __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::Caps()")); - - // The iCaps structure will already have been created by a call to iSensor->SetCaps() in DoCreate(). - // Simply copy it into the supplied TPckgBuf, taking into account the fact that the TCameraCapsV02 - // buffer is of a variable size *and* may be smaller or larger than the iCaps structure - TPtrC8 ptr((const TUint8*) iCaps, iCapsSize); - aCapsBuf.FillZ(aCapsBuf.MaxLength()); - aCapsBuf = ptr.Left(Min(ptr.Length(), aCapsBuf.MaxLength())); - - __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::Caps()")); - } - -/** -Called by the LDD to setup a new image configuration, including such things as image size, framerate -and pixel format. -@param aConfigBuf A reference to a TPckgBuf containing a TCameraConfigV02 configuration structure. -@return KErrNone if successful, otherwise one of the system wide error codes. -*/ -TInt DTemplateCameraScPdd::SetConfig(const TDesC8& aConfigBuf) - { - __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::SetConfig()")); - - TInt r; - - // It is only legal to call this if image capture is not already underway, so check for this - // before doing anything - if (iState <= EConfigured) - { - // Read the new configuration from the LDD into a local copy of the configuration structure, - // taking into account for compatibility that the TPckgBuf may be smaller or larger than the - // TCameraConfigV02 structure - TCameraConfigV02 config; - TPtr8 ptr((TUint8*) &config, sizeof(config)); - Kern::InfoCopy(ptr, aConfigBuf); - - // Save the new configuration for later and let the sensor also know about it - iConfig = config; - iSensor->SetConfig(config); - - // Signal success and set the channel to the configured state - r = KErrNone; - iState = EConfigured; - } - else - { - r = KErrInUse; - } - - __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::SetConfig() => Returning %d", r)); - - return r; - } - -/** -Begins capture into the address pointed to by aLinAddr and aPhysAddr. Both of these addresses point to -the same buffer; The address used by the sensor is hardware dependent. -@param aCaptureMode Whether to capture in video, viewfinder or single image mode. -@param aLinAddr The virtual address of the buffer into which to capture the image. -@param aPhysAddr The physical address of the buffer into which to capture the image. -@return KErrNone if successful, otherwise one of the other system wide error codes. -@pre SetConfig() must first have been called. -*/ -TInt DTemplateCameraScPdd::Start(TDevCamCaptureMode aCaptureMode, TLinAddr aLinAddr, TPhysAddr aPhysAddr) - { - __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::Start() => Configuring sensor for %d x %d capture", iConfig.iFrameSize.iWidth, iConfig.iFrameSize.iHeight)); - - // Ensure the precondition is met - __ASSERT_DEBUG((iState == EConfigured), Kern::Fault("camerasc", ENotConfigured)); - - // Save the capture mode for use when we call back into the LDD with the captured image - iCaptureMode = aCaptureMode; - - // And start the sensor running - TInt r = iSensor->Start(aCaptureMode, aLinAddr, aPhysAddr); - - // If everything was ok, set the channel to the capturing state - if (r == KErrNone) - { - iState = ECapturing; - } - - __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::Start() => Returning %d", r)); - - return r; - } - -/** -Sets the address of the buffer info which the next image will be captured. Called by the LDD for successive -images that are requested after the initial call to Start(). -@param aLinAddr The virtual address of the buffer into which to capture the image. -@param aPhysAddr The physical address of the buffer into which to capture the image. -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DTemplateCameraScPdd::CaptureNextImage(TLinAddr aLinAddr, TPhysAddr aPhysAddr) - { - __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::CaptureNextImage()")); - - // Pass the call directly to the sensor abstraction - TInt r = iSensor->CaptureNextImage(aLinAddr, aPhysAddr); - - __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::CaptureNextImage()=> Returning %d", r)); - - return(r); - } - -/** -Stops any image capturing that is currently underway. It is safe to call this without having called Start(). -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DTemplateCameraScPdd::Stop() - { - __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::Stop()")); - - // Pass the call directly to the sensor abstraction - iSensor->Stop(); - - // Det the channel back to the configured state as it is now safe to call Start() again - iState = EConfigured; - - __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::Stop()")); - - return KErrNone; - } - -/** -Power down the camera device. This is called by the LDD when the driver channel is being closed or -when the system is being powered down. This is always called in the context of the DFC thread. -*/ -void DTemplateCameraScPdd::PowerDown() - { - -#ifdef _DEBUG - - // Power off the camera - TInt r = iSensor->RelinquishPower(); - - // Not being able to power down indicates a serious programming error - __ASSERT_DEBUG((r == KErrNone), Kern::Fault("camerasc", ECannotPowerDown)); - -#else // ! _DEBUG - - // Power off the camera - iSensor->RelinquishPower(); - -#endif // ! _DEBUG - - } - -/** -Return the shared chunk creation information to be used by this device. -@param aChunkCreateInfo A structure to be filled with the settings required for this device. -*/ -void DTemplateCameraScPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo) - { - // Can be opened by any number of user side processes - aChunkCreateInfo.iType = TChunkCreateInfo::ESharedKernelMultiple; - // Use both L1 and L2 cache if available. LDD will take care of pre and post DMA cache handling -#ifdef __WINS__ - aChunkCreateInfo.iMapAttr = 0xFF000; -#else - aChunkCreateInfo.iMapAttr = EMapAttrCachedMax; -#endif - // Chunk owns the memory which will be freed when the chunk is destroyed - aChunkCreateInfo.iOwnsMemory = ETrue; - // Don't queue the chunk's destruction on an DFC - aChunkCreateInfo.iDestroyedDfc = NULL; - } - -/** -Returns the size of the variable sized capabilities structure in bytes. The buffer passed into -DTemplateCameraScPdd::GetCaps() must be at least this large to hold the fixed portion of the TCameraCapsV02 -structure, as well as the array of SDevCamPixelFormat structures that follows it. -@return The size in bytes of the variable sized capabilities structure. -*/ -TInt DTemplateCameraScPdd::CapsSize() - { - return iCapsSize; - } - -/** -Obtains information regarding the frame sizes and frame rates supported for a given combination of capture mode -and pixel format. -@param aCaptureMode The capture mode for which to obtain the information. -@param aUidPixelFormat The pixel format for which to obtain the information. -@param aFrameSizeCapsBuf A reference to an array of packaged SDevCamFrameSize structures, owned by the LDD, into - which to place the information. -@@return KErrNone if successful, else one of the other system wide error codes. -*/ -TInt DTemplateCameraScPdd::FrameSizeCaps(TDevCamCaptureMode aCaptureMode, TUidPixelFormat aUidPixelFormat, TDes8& aFrameSizeCapsBuf) - { - return iSensor->FrameSizeCaps(aCaptureMode, aUidPixelFormat, aFrameSizeCapsBuf); - } - -/** -Called by the sensor abstraction when an image is available. -@param aResult KErrNone if successful, otherwise one of the system wide error codes. -@param aLinAddr The virtual address of the buffer into which to capture the image. -@param aPhysAddr The physical address of the buffer into which to capture the image. -*/ -TInt DTemplateCameraScPdd::NotifyImageCaptureEvent(TInt aResult, TLinAddr& aLinAddr, TPhysAddr& aPhysAddr) - { - __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::NotifyImageCaptureEvent() => aResult = %d", aResult)); - - // Inform the LDD that a new image has been received - TInt r = iLdd->ImageCaptureCallback(iCaptureMode, aResult, &aLinAddr, &aPhysAddr); - - // If the LDD has returned KErrAbort then something has gone wrong, and if it has returned KErrNotReady - // then it has no more frames available, so call Stop() - if (r != KErrNone) - { - Stop(); - } - - __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::NotifyImageCaptureEvent() => Returning %d", r)); - - return r; - } - -TInt DTemplateCameraScPdd::SetBrightness(TUint /*aBrightness*/) - { - return KErrNone; - } - -TInt DTemplateCameraScPdd::SetContrast(TUint /*aContrast*/) - { - return KErrNone; - } - -TInt DTemplateCameraScPdd::SetColorEffect(TUint /*aColorEffect*/) - { - return KErrNone; - } - diff -r a5496987b1da -r 189ece41fa29 bsptemplate/asspandvariant/template_variant/camerasc/camerasc_plat.h --- a/bsptemplate/asspandvariant/template_variant/camerasc/camerasc_plat.h Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,342 +0,0 @@ -// Copyright (c) 2006-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: -// template\template_variant\camerasc\camerasc_plat.h -// Implementation of the Template shared chunk camera physical device driver (PDD). -// This file is part of the Template Base port -// -// - -#ifndef __CAMERASC_PLAT_H__ -#define __CAMERASC_PLAT_H__ - -#include -#include - -// Comment out the first #define, and uncomment the second #define in order to have debug -// output for the shared chunk camera driver -#define __KTRACE_CAM(s) -//#define __KTRACE_CAM(s) s - -/** Total number of image capture requests that can be handled by the sensor at one time */ -const TInt KTotalCameraRequests = 2; - -/** NaviEngine specific panics that can be thrown by the shared chunk camera driver */ -enum TTemplateCameraScPddPanic - { - /** Start() has been called before SetConfig() */ - ENotConfigured, - /** Unable to power down the camera hardware */ - ECannotPowerDown, - /** Buffer passed to DSensorIf::FrameSizeCaps() by LDD is too small */ - ECapsBufferTooSmall - }; - -/** -The physical device (factory class) for the NaviEngine shared chunk camera driver. - -This class is used by the device driver framework to instantiate one or more shared chunk camera driver -PDDs. An instance of one PDD is allowed for each physical sensor on the device. -*/ -class DTemplateCameraScPddFactory : public DPhysicalDevice - { -public: - - DTemplateCameraScPddFactory(); - ~DTemplateCameraScPddFactory(); - virtual TInt Install(); - virtual void GetCaps(TDes8 &aDes) const; - virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); - virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); - TBool IsUnitOpen(TInt aUnit); - TInt SetUnitOpen(TInt aUnit, TBool aIsOpen); - -private: - - /** The DFC queue to be used by both the LDD and the PDD to serialise access to the PDD. */ - TDynamicDfcQue* iDfcQ; - /** Mask to keep track of which units have a channel open on them. */ - TUint iUnitsOpenMask; - /** A mutex to protect access to the unit information mask. */ - NFastMutex iUnitInfoMutex; - - friend class DTemplateCameraScPdd; - }; - -/** -Defines the interface for notification of an image being captured. - -Used by concrete instances of the DSensorIf abstract base class in order to notify an observer class -(typically an DCameraScPdd derived class) that an image has been captured for processing. -*/ -class MSensorObserver - { -public: - - virtual TInt NotifyImageCaptureEvent(TInt aResult, TLinAddr& aLinAddr, TPhysAddr& aPhysAddr) = 0; - }; - -/** -Defines an abstract base class for implementing concrete classes for camera sensors. - -This class provides an abstract interface to the sensor; one class is derived from this and implemented -for each sensor available to the camera driver. -*/ -class DSensorIf : public DBase - { -public: - - /** - Second phase constructor for the sensor interface. Acquires any resources required for communication with the sensor. - When this returns, the sensor is ready for use. - */ - virtual TInt DoCreate() = 0; - - /** - Obtains information regarding the frame sizes and frame rates supported for a given combination of capture mode and pixel format. - @param aCaptureMode The capture mode for which to obtain the information. - @param aUidPixelFormat The pixel format for which to obtain the information. - @param aFrameSizeCapsBuf A referenced to an array of packaged SDevCamFrameSize structures into which to place the information. - @return KErrNone if successful, else one of the other system wide error codes. - */ - virtual TInt FrameSizeCaps(TDevCamCaptureMode aCaptureMode, TUidPixelFormat aUidPixelFormat, TDes8& aFrameSizeCapsBuf) = 0; - - /** - Obtains the capabilities of the sensor. This either interrogates the sensor to find out its capabilities, or hard codes - them into aCameraCaps, or a combination of the two. - @param aCameraCaps A reference to a ptr to the structure into which to place the capabilities of the sensor. - This structure is of a variable size and contains the fixed part, followed by an array of - SDevCamPixelFormat structures. - @return The size of the variable length structure pointed to by aCameraCaps if successful, else one of the other - system wide error codes. - */ - virtual TInt GetCaps(TCameraCapsV02*& aCameraCaps) = 0; - - /** - Powers up the sensor. - */ - virtual TInt RequestPower() = 0; - - /** - Powers down the sensor. - */ - virtual TInt RelinquishPower() = 0; - - /** - Configures the sensor for capture in the configuration previously set by SetConfig(), and begins capture into the - address pointed to by aLinAddr and aPhysAddr. Both of these addresses point to the same buffer; The address used - by the sensor is hardware dependent. - @param aCaptureMode Whether to capture in video, viewfinder or single image mode. - @param aLinAddr The virtual address of the buffer into which to capture the image. - @param aPhysAddr The physical address of the buffer into which to capture the image. - @return KErrNone if successful, otherwise one of the other system wide error codes. - @pre SetConfig() must first have been called. - */ - virtual TInt Start(TDevCamCaptureMode aCaptureMode, TLinAddr aLinAddr, TPhysAddr aPhysAddr) = 0; - - /** - Sets the address of the buffer into which the next image will be captured. If is common for this to be called by Start() as - well as by the class that owns the sensor interface. - @param aLinAddr The virtual address of the buffer into which to capture the image. - @param aPhysAddr The physical address of the buffer into which to capture the image. - @return KErrNone if successful, otherwise one of the other system wide error codes. - @pre Start() must first have been called. - */ - virtual TInt CaptureNextImage(TLinAddr aLinAddr, TPhysAddr aPhysAddr) = 0; - - /** - Stops any image capturing that is currently underway. It is safe to call this without having called Start(). - @return KErrNone if successful, otherwise one of the other system wide error codes. - */ - virtual TInt Stop() = 0; - - /** - Saves a configuration specifying such details as dimensions and pixel format in which the sensor should - capture images. The shared implementation of this contains generic code, but this can be overridden by - derived classes if desired. - @param aConfig A TCameraConfigV02 structure containing the settings to be used. - @return KErrNone if successful, otherwise one of the other system wide error codes. - */ - virtual TInt SetConfig(const TCameraConfigV02& aConfig); - -protected: - - /** Pointer to the observer to call when a frame of data is available */ - MSensorObserver* iObserver; - /** ETrue if capture is under way, else EFalse*/ - TBool iEnabled; - /** Width of the frames to be captured in pixels */ - TInt iWidth; - /** Height of the frames to be captured in pixels */ - TInt iHeight; - /** Number of bytes from the start of one line to the start of the next */ - TInt iLineOffset; - /** The number of requests setup ready for transfer */ - TInt iPendingRequests; - /** The next request to be setup ready for transfer */ - TUint iNextRequest; - /** The configuration in which to capture images */ - TCameraConfigV02 iConfig; - }; - -/** -This class provides an abstract interface to the Template sensor. -*/ -class DTemplateSensorIf : public DSensorIf - { -public: - - DTemplateSensorIf(MSensorObserver& aObserver, TDfcQue* aDFCQueue); - TInt DoCreate(); - ~DTemplateSensorIf(); - TInt BufferDoneCallback(TInt aResult); - void FillBuffer(TLinAddr aBuffer); - TInt FrameSizeCaps(TDevCamCaptureMode aCaptureMode, TUidPixelFormat aUidPixelFormat, TDes8& aFrameSizeCapsBuf); - TInt GetCaps(TCameraCapsV02*& aCameraCaps); - TInt RequestPower(); - TInt RelinquishPower(); - TInt Start(TDevCamCaptureMode aCaptureMode, TLinAddr aLinAddr, TPhysAddr aPhysAddr); - TInt Stop(); - TInt CaptureNextImage(TLinAddr aLinAddr, TPhysAddr aPhysAddr); - - // Static callbacks for various sensor related asynchronous functions - static TInt HostPowerCallback(TAny* aPtr, TAny* aPoweredUp); - static TInt SensorClkReqCallback(TAny* aPtr); - -private: - - /** X position at which to display the logo */ - TInt iX; - /** Y position at which to display the logo */ - TInt iY; - /** Current X direction and speed at which the logo is moving */ - TInt iXDirection; - /** Current Y direction and speed at which the logo is moving */ - TInt iYDirection; - /** Number of nanokernel ticks that represent the time to capture one frame */ - TInt iImageTimerTicks; - /** Timers used for emulating images being captured */ - NTimer iImageTimers[KTotalCameraRequests]; - /** DFC queue used for completing image capture requests */ - TDfcQue* iDFCQueue; - /** DFCs used for image capture timer callbacks happeing in our DFC thread */ - TDfc *iImageTimerDFCs[KTotalCameraRequests]; - - /* Used for cheesy animation effect */ - TUint8 iCounter; - TBool iFlipSwitch; - }; - -/** -The physical device driver for the NaviEngine shared chunk camera driver. - -This is the concrete implementation of the abstract DCameraScPdd base class. One instance of this -class will be created by the factory class per physical sensor on the device. Only one instance -per sensor can be instantiated at any given time. Access to the sensor itself is achieved via the -appropriate DSensorIf derived class. -*/ -class DTemplateCameraScPdd : public DCameraScPdd, public MSensorObserver - { -private: - - /** States in which the channel can be */ - enum TState - { - /** Channel created but not yet configured */ - EUnconfigured, - /** Channel configured but idle and not capturing images */ - EConfigured, - /** Channel capturing images */ - ECapturing - }; - -public: - - DTemplateCameraScPdd(); - TInt DoCreate(DTemplateCameraScPddFactory* aPhysicalDevice, TInt aUnit); - ~DTemplateCameraScPdd(); - TDfcQue* DfcQ(TInt aUnit); - void Caps(TDes8& aCapsBuf) const; - void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo); - TInt SetConfig(const TDesC8& aConfigBuf); - TInt Start(TDevCamCaptureMode aCaptureMode,TLinAddr aLinAddr, TPhysAddr aPhysAddr); - TInt CaptureNextImage(TLinAddr aLinAddr, TPhysAddr aPhysAddr); - TInt Stop(); - void PowerDown(); - TInt CapsSize(); - TInt FrameSizeCaps(TDevCamCaptureMode aCaptureMode, TUidPixelFormat aUidPixelFormat, TDes8& aFrameSizeCapsBuf); - - /** - Sets the sensor brightness to the desired setting. - - @param aValue A verified brightness setting. - @return KErrNone if successful, KErrNotSupported if not supported. - */ - TInt SetBrightness(TUint aBrightness); - - /** - Sets the sensor contrast to the desired setting. - - @param aValue A verified contrast setting. - @return KErrNone if successful, KErrNotSupported if not supported. - */ - TInt SetContrast(TUint aContrast); - - /** - Sets the sensor color effect to the desired setting. - - @param aValue A verified color effect setting. - @return KErrNone if successful, KErrNotSupported if not supported. - */ - TInt SetColorEffect(TUint aColorEffect); - -private: - - TInt NotifyImageCaptureEvent(TInt aResult, TLinAddr& aLinAddr, TPhysAddr& aPhysAddr); - -private: - - /** The unit number of this channel. The unit number determines the sensor used. */ - TInt iUnit; - /** A pointer to the PDD factory that created this device. */ - DTemplateCameraScPddFactory* iPhysicalDevice; - /** Ptr to a buffer large enough to hold the variable sized capabilities structure. */ - TUint8* iCapsBuffer; - /** The size of the variable sized capabilities structure. */ - TUint iCapsSize; - /** The capabilities of this device. */ - TCameraCapsV02* iCaps; - /** The current configuration of this device. */ - TCameraConfigV02 iConfig; - /** The current capture mode of the camera. */ - TDevCamCaptureMode iCaptureMode; - /** Abstracted interface to the sensor */ - DSensorIf* iSensor; - /** Current state of the channel (configured, capturing etc) */ - TState iState; - }; - -/** -XXX - This structure holds information pertaining to the logo to be rendered in -"photos" returned by the template camera driver. This structure is temporary and -should be removed when changing this template into a "real" camera driver. -*/ -struct SLogo - { - TUint iWidth; - TUint iHeight; - TUint8 iPixelData[80 * 61 * 3 + 1]; - TUint8 iPixelData2[80 * 61 * 3 + 1]; - }; - -#endif /* __CAMERASC_PLAT_H__ */ diff -r a5496987b1da -r 189ece41fa29 bsptemplate/asspandvariant/template_variant/camerasc/camerasc_sensor.cpp --- a/bsptemplate/asspandvariant/template_variant/camerasc/camerasc_sensor.cpp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,552 +0,0 @@ -// Copyright (c) 2006-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: -// template\template_variant\camerasc\camerasc_sensor.cpp -// Implementation of the template shared chunk camera physical device driver (PDD). -// This file is part of the Template Base port -// -// - -/** - @file -*/ - -#include "camerasc_plat.h" -#include - -// XXX - Temporary structure containing a logo to be displayed. Remove this when -// changing this template into a "real" camera driver -#include "logoyuv2.cpp" - - -#define RGBtoBGR565(red, green, blue) (((blue & 0xf8) << 8) | ((green & 0xfc) << 3) | ((red & 0xf8) >> 3)); - -#define YUVtoYUV565(luma, blueC, redC) (((luma & 0xf8) << 8) | ((blueC & 0xfc) << 3) | ((redC & 0xf8) >> 3)); - -// Frame sizes and their associated frame rates supported by the Template sensor. This selection was -// obtained by observation of typical formats supported by phones already on the market; It is arbitrary -// and can be easily added to if desired -static const SDevCamFrameSize FrameSizes[] = - { - { 320, 240, 1, 30 } , // QVGA - 0.075 MP - // XXX: Although not used in this template driver, the following are suggested standard frame sizes - // that should be implemented in your camera driver, as well as 320 x 240 above. Remember to change - // KNumFrameSizes below if you change the number of sizes defined in here! - { 640, 480, 1, 30 }, // VGA - 0.3 MP - { 800, 600, 1, 30 }, // SVGA - 0.5 MP - { 1024, 768, 1, 30 }, // XGA - 0.8 MP - { 2048, 1536, 1, 15 }, // QXGA - 3 MP - //{ 2560, 1600, 1, 30 } // WQXGA - 4.1 MP - }; - -// This constant must be updated if the number of frame sizes listed above changes -static const TInt KNumFrameSizes = sizeof(FrameSizes) / sizeof(SDevCamFrameSize); - -// Pixel formats supported by the three different capture modes. These are mapped onto the appropriate -// array of supported frame rates by the FrameSizeCaps() function -static const SDevCamPixelFormat PixelFormats[] = - { - // Image pixel formats - { EUidPixelFormatYUV_422Interleaved, KNumFrameSizes, 2 }, - - // Video pixel formats - { EUidPixelFormatYUV_422Interleaved, KNumFrameSizes, 2 }, - - // View finder pixel formats - { EUidPixelFormatYUV_422Interleaved, KNumFrameSizes, 2 } - - }; - -// These constants must be updated if the number of pixel formats listed above changes -static const TInt KNumImagePixelFormats = 1; -static const TInt KNumVideoPixelFormats = 1; -static const TInt KNumViewFinderPixelFormats = 1; - -// Alternate logo images after this many frames -static const TInt KAlternateLogoFrameInterval = 5; - -static void ImageTimerCallback(TAny* aSensorIf) - { - DTemplateSensorIf* sensor = (DTemplateSensorIf*) aSensorIf; - - // XXX - Call the buffer done function in the sensor class. In this case we are just emulating the - // interrupt and DFC callback that would happen when an image is captured, so we always pass in KErrNone. - // In a real driver, we would read the hardware here to check that the capture happened successfully and - // would pass in the appropriate error code - sensor->BufferDoneCallback(KErrNone); - } - -/** -Saves a configuration specifying such details as dimensions and pixel format in which the sensor should -capture images. -@param aConfig A TCameraConfigV02 structure containing the settings to be used. -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DSensorIf::SetConfig(const TCameraConfigV02& aConfig) - { - // Manual settings for flash mode, focus, white balance etc. are not supported by the sensor, - // so check for these and return KErrNotSupported if they have been requested - if ((aConfig.iFlashMode != ECamFlashNone) || - (aConfig.iExposureMode != ECamExposureAuto) || - (aConfig.iZoom != 0) /*|| - (aConfig.iWhiteBalanceMode != ECamWBAuto) || - (aConfig.iContrast != ECamContrastAuto) || - (aConfig.iBrightness != ECamBrightnessAuto)*/) - { - // XXX: Remove this once support is addded for these modes - return KErrNotSupported; - } - - // As well as saving the configuration, also save copies of the width and height for easy access, - // as they are accessed frequently, as well as the offset in bytes between lines - iConfig = aConfig; - iWidth = aConfig.iFrameSize.iWidth; - iHeight = aConfig.iFrameSize.iHeight; - iLineOffset = (iWidth * iConfig.iPixelFormat.iPixelWidthInBytes); - - return KErrNone; - } - -/** -Constructor for the Template sensor class. -*/ - -DTemplateSensorIf::DTemplateSensorIf(MSensorObserver& aObserver, TDfcQue* aDFCQueue) - : iDFCQueue(aDFCQueue) - { - iObserver = &aObserver; - iXDirection = iYDirection = 1; - - iCounter = 0; - iFlipSwitch = EFalse; - } - -/** -Second stage constructor for the Template sensor class. - -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DTemplateSensorIf::DoCreate() - { - __KTRACE_CAM(Kern::Printf("> DTemplateSensorIf::DoCreate()")); - - TInt r = KErrNone; - - for (TInt index = 0; index < KTotalCameraRequests; ++index) - { - if ((iImageTimerDFCs[index] = new TDfc(ImageTimerCallback, this, iDFCQueue, 0)) == NULL) - { - r = KErrNoMemory; - - break; - } - } - - __KTRACE_CAM(Kern::Printf("< DTemplateSensorIf::DoCreate() => Returning %d", r)); - - return r; - } - -/** -Destructor for the Template sensor class. -*/ -DTemplateSensorIf::~DTemplateSensorIf() - { - for (TInt index = 0; index < KTotalCameraRequests; ++index) - { - iImageTimers[index].Cancel(); - delete iImageTimerDFCs[index]; - } - } - -/** -Called by the underlying sensor class when an image has been captured. -@param aResult KErrNone if the image was captured successfully, otherwise one of - the other system wide error codes. -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DTemplateSensorIf::BufferDoneCallback(TInt aResult) - { - TInt r = KErrNone; - - NKern::LockedDec(iPendingRequests); - - TLinAddr linAddr; - TPhysAddr physAddr; - - // Call the LDD to let it know that an image capture has completed. If the LDD needs more images - // to be captured, then it will return KErrNone and the virtual and physical addresses of the - // next buffer to be filled will be returned in linAddr and physAddr respectively. Note that as - // will as starting a capture of an image in here, the LDD may also call CaptureNextImage() to start - // capture as well - r = iObserver->NotifyImageCaptureEvent(aResult, linAddr, physAddr); - - if (r == KErrNone) - { - iNextRequest = ((iNextRequest + 1) % KTotalCameraRequests); - NKern::LockedInc(iPendingRequests); - - // XXX: Temporary code to be removed in a real driver. Fill the buffer for testing - // with user side code - FillBuffer(linAddr); - - // XXX: Send buffer to sensor. Normally the address of the buffer passed in in aLinAddr and - // aPhysAddr would be programmed into the sensor and/or bus hardware here and an interrupt - // would be generated when the iamge had been captured into the buffer. In this simulated - // driver we will use a nanokernel timer to simulate this process - iImageTimers[iNextRequest].OneShot(iImageTimerTicks, *iImageTimerDFCs[iNextRequest]); - } - - return r; - } - -/** -Fills a buffer with a white background with a moving logo on top. -@param aBuffer Pointer to the buffer to be filled. -*/ -void DTemplateSensorIf::FillBuffer(TLinAddr aBuffer) - { - const TUint8* LogoData = Logo.iPixelData; - const TUint8* LogoData2 = Logo.iPixelData2; - TInt index = 0; - TInt numPixels = (iConfig.iFrameSize.iWidth * iConfig.iFrameSize.iHeight); - TUint yC, uC, vC; - TUint16* buffer = (TUint16*) aBuffer; - - // Alternate between the two logos for cheesy animation effect - if( ++iCounter == KAlternateLogoFrameInterval ) - { - iFlipSwitch ^= 1; - iCounter = 0; - } - - - // Set the "photo" background to be all white - memset(buffer, 0xff, (numPixels * 2)); - - // Point to the correct location in the buffer at which to render the logo - buffer += ((iY * iConfig.iFrameSize.iWidth) + iX); - - // Iterate through the data for the logo and copy it into the "photo" - for (TUint y = 0; y < Logo.iHeight; ++y) - { - for (TUint x = 0; x < Logo.iWidth; ++x) - { - // The logo is in 24 bit BGR format so read each pixel and convert it to 16 bit BGR565 - // before writing it into the "photo" buffer - if( iFlipSwitch ) - { - yC = LogoData[index]; - uC = LogoData[index + 1]; - vC = LogoData[index + 2]; - } - else - { - yC = LogoData2[index]; - uC = LogoData2[index + 1]; - vC = LogoData2[index + 2]; - } - - *buffer++ = YUVtoYUV565(yC, uC, vC); - // Point to the next source pixel - index += 3; - } - - // Point to the start of the next line in the buffer, taking into account that the logo - // is narrower than the buffer - buffer += (iConfig.iFrameSize.iWidth - Logo.iWidth); - } - - // Bounce the logo around in the X direction. This will take effect the next time this is called - iX += iXDirection; - - if (iX <= 0) - { - iX = 0; - iXDirection = -iXDirection; - } - else if (iX >= (TInt) (iConfig.iFrameSize.iWidth - Logo.iWidth)) - { - iX = (iConfig.iFrameSize.iWidth - Logo.iWidth); - iXDirection = -iXDirection; - } - - // Bounce the logo around in the Y direction. This will take effect the next time this is called - iY += iYDirection; - - if (iY <= 0) - { - iY = 0; - iYDirection = -iYDirection; - } - else if (iY >= (TInt) (iConfig.iFrameSize.iHeight - Logo.iHeight)) - { - iY = (iConfig.iFrameSize.iHeight - Logo.iHeight); - iYDirection = -iYDirection; - } - - // Now flush the cache to memory, taking into account the size of each pixel. This is not normally - // necessary but given that we are emulating a camera driver in software we must ensure that the - // cache is flushed to memory. This is because in a real driver the buffer will have been filled - // by DMA so upon return to the LDD, the LDD will discard the contents of the cache to ensure the - // DMA-written data is ok. In the case of filling the buffer using the CPU in this virtual camera - // driver, that would result in the data being discarded! - Cache::SyncMemoryBeforeDmaWrite((TLinAddr) aBuffer, (numPixels * iConfig.iPixelFormat.iPixelWidthInBytes)); - } - -/** -Based on the capture mode and pixel format passed in, copies an array of supported SFrameSize -structures into a buffer supplied by the LDD. These frame sizes and their associated frame rates -will reflect the capabilities of the given capture mode and pixel format. -@param aCaptureMode The capture mode for which to obtain the supported frame sizes. -@param aUidPixelFormat The UID of the pixel format (as defined in \epoc32\include\pixelformats.h) - for which to obtain the supported frame sizes. -@param aFrameSizeCapsBuf A reference to a descriptor that contains a buffer into which to place - the frame size structures. It is up to the LDD to ensure that this is - large enough to hold all of the frame sizes. -@return Always KErrNone. -*/ -TInt DTemplateSensorIf::FrameSizeCaps(TDevCamCaptureMode /*aCaptureMode*/, TUidPixelFormat /*aUidPixelFormat*/, TDes8& aFrameSizeCapsBuf) - { - TPtrC8 sourceFrameSizes((const TUint8*) FrameSizes, sizeof(FrameSizes)); - - // Ensure the buffer passed in from the LDD is large enough and copy the requested frame sizes - if (aFrameSizeCapsBuf.Size() < sourceFrameSizes.Size()) - { - Kern::Printf("*** ECapsBufferTooSmall: %d vs %d", - aFrameSizeCapsBuf.Size(), - sourceFrameSizes.Size()); - Kern::Fault("camerasc", ECapsBufferTooSmall); - } - - //__ASSERT_DEBUG((aFrameSizeCapsBuf.Size() >= sourceFrameSizes.Size()), Kern::Fault("camerasc", ECapsBufferTooSmall)); - aFrameSizeCapsBuf = sourceFrameSizes; - - return KErrNone; - } - -/** -Allocates a buffer large enough to hold the TCameraCapsV02 structure and its succeeding array of -pixel formats, and populates the structure and array with information about the capabilities of -the sensor. -@param aCameraCaps Reference to a pointer into which to place the pointer to allocated buffer -@return Size of the capabilities structure if successful, otherwise one of the other system wide - error codes. -*/ -TInt DTemplateSensorIf::GetCaps(TCameraCapsV02*& aCameraCaps) - { - // Allocate a buffer large enough to hold the TCameraCapsV02 structure and the array of pixel formats - // that will follow it - TInt r = (sizeof(TCameraCapsV02) + sizeof(PixelFormats)); - TUint8* capsBuffer = new TUint8[r]; - - if (capsBuffer) - { - aCameraCaps = (TCameraCapsV02*) capsBuffer; - - // No special modes are supported at the moment - aCameraCaps->iFlashModes = ECamFlashNone; - aCameraCaps->iExposureModes = ECamExposureAuto; // or None? - // do we still need whitebalance mode filed? - aCameraCaps->iWhiteBalanceModes = ECamWBAuto | ECamWBDaylight | ECamWBCloudy | ECamWBTungsten | ECamWBFluorescent | ECamWBFlash | ECamWBSnow | ECamWBBeach; - aCameraCaps->iMinZoom = 0; - aCameraCaps->iMaxZoom = 0; - aCameraCaps->iCapsMisc = KCamMiscContrast | KCamMiscBrightness | KCamMiscColorEffect; - - // There isn't really such thing as inwards or outwards orientation on an SDP, but we'll pretend it's - // an outwards facing camera - aCameraCaps->iOrientation = ECamOrientationOutwards; - - // Initialise the number of different pixel formats supported - aCameraCaps->iNumImagePixelFormats = KNumImagePixelFormats; - aCameraCaps->iNumVideoPixelFormats = KNumVideoPixelFormats; - aCameraCaps->iNumViewFinderPixelFormats = KNumViewFinderPixelFormats; - - for (TInt i = 0; i < ECamAttributeMax; i++) - { - if (ECamAttributeColorEffect == (TDevCamDynamicAttribute)(i)) - { - // WhiteBalance - // In case of white balance, we shouldn't use MIN and MAX values as some of them in between MIN and MAX can be missed out. - // As this is fake driver, There doesn't seem to be any major issue though. - aCameraCaps->iDynamicRange[i].iMin = ECamWBAuto; - aCameraCaps->iDynamicRange[i].iMax = ECamWBBeach; - aCameraCaps->iDynamicRange[i].iDefault = ECamWBAuto; - } - else - { - // TBC :: Contrast, Brightness - aCameraCaps->iDynamicRange[i].iMin = 0; - aCameraCaps->iDynamicRange[i].iMax = 6; - aCameraCaps->iDynamicRange[i].iDefault = 3; - } - } - - // Setup some descriptors pointing to the pixel format array and the array passed in by the LDD - // (located at the end of the TCameraCapsV02 structure) and copy the pixel format array - TPtrC8 sourcePixelFormats((const TUint8*) PixelFormats, sizeof(PixelFormats)); - TPtr8 destPixelFormats((capsBuffer + sizeof(TCameraCapsV02)), sizeof(PixelFormats), sizeof(PixelFormats)); - destPixelFormats = sourcePixelFormats; - } - else - { - r = KErrNoMemory; - } - - return r; - } - -/** -Powers up the sensor hardware. -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DTemplateSensorIf::RequestPower() - { - __KTRACE_CAM(Kern::Printf("> DTemplateSensorIf::RequestPower()")); - - TInt r = KErrNone; - - __KTRACE_CAM(Kern::Printf("< DTemplateSensorIf::RequestPower() => Returning %d", r)); - - return r; - } - -/** -Powers down the sensor hardware. -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DTemplateSensorIf::RelinquishPower() - { - __KTRACE_CAM(Kern::Printf("> DTemplateSensorIf::RelinquishPower()")); - - TInt r = KErrNone; - - __KTRACE_CAM(Kern::Printf("< DTemplateSensorIf::RelinquishPower() => Returning %d", r)); - - return r; - } - -/** -Begins capture of the next image into the buffer provided. This function assumes that -Start() has already been called to start capture. However, Stop() may also have been -subsequently called (for example to pause capture) and in this case, this function will -handle restarting the sensor. -@param aLinAddr A virtual pointer to the buffer into which to capture the image. -@param aPhysAddr A physical pointer to the buffer into which to capture the image. - This points to the same memory as aLinAddr. -@return KErrNone if successful. - KErrNotReady if there are no free requests to capture the image. - Otherwise one of the other system wide error codes. -*/ -TInt DTemplateSensorIf::CaptureNextImage(TLinAddr aLinAddr, TPhysAddr /*aPhysAddr*/) - { - TInt r = KErrNone; - - // Only start capturing the next image if there are any pending request slots available - if (iPendingRequests < KTotalCameraRequests) - { - // Queue a transfer on the next available channel and indicate that the channel is - // in use - iNextRequest = ((iNextRequest + 1) % KTotalCameraRequests); - NKern::LockedInc(iPendingRequests); - - // XXX: Temporary code to be removed in a real driver. Fill the buffer for testing - // with user side code. This is to simulate an image being captured into the buffer that - // has been passed in in aLinAddr. As well as aLinAddr, which points to the virtual - // address of the buffer, the LDD will pass in the physical address as well, in aPhysAddr. - // Depending on the underlying sensor hardware and/or bus in use, you will have to choose - // which of these to use - FillBuffer(aLinAddr); - - // XXX: Send buffer to sensor. Normally the address of the buffer passed in in aLinAddr and - // aPhysAddr would be programmed into the sensor and/or bus hardware here and an interrupt - // would be generated when the iamge had been captured into the buffer. In this simulated - // driver we will use a nanokernel timer to simulate this process - iImageTimers[iNextRequest].OneShot(iImageTimerTicks, *iImageTimerDFCs[iNextRequest]); - - // If capturing has not yet started or has been paused by Stop(), start it - if (!(iEnabled)) - { - iEnabled = ETrue; - } - } - else - { - r = KErrNotReady; - } - - return r; - } - -/** -Begins capture of the first image into the buffer provided. This function is similar to -CaptureNextImage(), except that it will perform any extra sensor intitialisation required -to start capture. -@param aCaptureMode The capture mode for which to start capturing. -@param aLinAddr A virtual pointer to the buffer into which to capture the image. -@param aPhysAddr A physical pointer to the buffer into which to capture the image. - This points to the same memory as aLinAddr. -@return KErrNone if successful - KErrInUse if capture is already under way. - KErrNotSupported if the frame size and/or frame rate are out of range. - Otherwise one of the other system wide error codes. -*/ -TInt DTemplateSensorIf::Start(TDevCamCaptureMode /*aCaptureMode*/, TLinAddr aLinAddr, TPhysAddr aPhysAddr) - { - __KTRACE_CAM(Kern::Printf("> DTemplateSensorIf::Start()")); - - TInt r = KErrNone; - - // XXX - In a real camera driver, in here we would initialise start the capturing process in here. - // When an image is captured, the sensor hardware (or maybe the CSI bus) will generate an - // which will then be enqueued into the DFC queue that was passed into the constructor of - // the sensor class. It is important to do the DFC processing in this DFC queue rather than - // a separate one because it ensures that fucntions in the PDD and LDD are called in a serialised - // manner, without the need for mutexts. In this example camera driver we will convert the - // framerate into a nanokernel tick count and will use an NTimer.OneShot() call to simulate - // the sensor interrupt and DFC callback. Divides are slow so we'll calculate the tick count - // here and will save it for later use - iImageTimerTicks = ((1000000 / NKern::TickPeriod()) / iConfig.iFrameRate); - - // XXX - Once the one off hardware initialisation has been done for starting a new capture, then - // subsequent captures can usually reuse the same code in CaptureNextImage() for starting - // the next capture - r = CaptureNextImage(aLinAddr, aPhysAddr); - - __KTRACE_CAM(Kern::Printf("< DTemplateSensorIf::Start() => Returning %d", r)); - - return r; - } - -/** -Stops capturing any image capture that is currently in progress. This function will act -more like a Pause() than a Stop() capturing can be restarted from where it was stopped. -*/ -TInt DTemplateSensorIf::Stop() - { - __KTRACE_CAM(Kern::Printf("> DTemplateSensorIf::Stop()")); - - iEnabled = EFalse; - iPendingRequests = iNextRequest = 0; - - // XXX - Cancel all of our pending image timer callbacks. In a real driver we would write to the - // sensor and/or bus hardware here to cause them to cancel any pending image captures - for (TInt index = 0; index < KTotalCameraRequests; ++index) - { - iImageTimers[index].Cancel(); - } - - __KTRACE_CAM(Kern::Printf("< DTemplateSensorIf::Stop()")); - - return KErrNone; - } diff -r a5496987b1da -r 189ece41fa29 bsptemplate/asspandvariant/template_variant/camerasc/logo.cpp --- a/bsptemplate/asspandvariant/template_variant/camerasc/logo.cpp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,883 +0,0 @@ -// Copyright (c) 2006-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: -// template\template_variant\camerasc\logo.cpp -// This file contains the binary data for the logo that gets rendered in the -// "photos" taken by this template camera driver. -// -// - -#include "camerasc_plat.h" - -/** The logo rendered in "photos" returned by the template camera driver. */ -const struct SLogo Logo = - { - 124, 47, - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\342\347\373\320\332\371\321\332\371\321\333\371\322\333\372\321\333\371" - "\322\333\371\322\333\371\321\333\371\321\332\371\322\333\371\321\332\371" - "\322\333\372\321\333\371\321\332\371\315\327\370\367\371\376\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\0""7\336\0K\341\0J\341\0L\343\0J\341" - "\0J\341\0L\343\0J\341\0I\341\36n\347\362\363\375\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\300\322\370\22`\346\0G\341\0J\341\0L\343\0A\340j\241\360\377\377\377\377" - "\377\377\364\367\376\213\252\361\7]\345\0K\341\0O\342\0O\342\0O\342\0O\342" - "\0P\344\0O\342\0O\342\0O\342\0O\342\0P\342\0O\342\0O\342\0P\344\0O\342\0" - "P\342\0H\3414q\347\317\334\370\377\377\377\377\377\377\377\377\377E{\351" - "\0F\340\0J\341\0L\341\0K\343\0C\341\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\267\314\367\0L\342" - "\0K\343\0J\341\0L\343\0J\341\0G\341\0M\342k\227\355\377\377\377\340\346\372" - "F\202\352\0E\342\0J\341\0K\341\0F\341(r\347\314\330\367\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377K\212\353\0I\340\0K\343\0J\341\0K\341\0K\341\0J\341\0?\341" - "\272\321\367\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\0L\343\0]\344\0_\346\0^" - "\344\0_\346\0_\346\0_\346\0]\344\0\\\344\0[\344[\215\354\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\310\327\371*q\347\0[\344\0]\345\0]\344\0T\343y\253\362\377\377\377" - "\365\367\374`\226\356\0S\343\0[\344\0^\345\0]\344\0^\345\0]\344\0^\345\0" - "]\344\0]\344\0_\346\0]\344\0_\346\0]\344\0]\344\0]\344\0_\344\0]\344\0]\344" - "\0_\346\0Y\344\0O\341\316\332\371\377\377\377\377\377\377Y\210\353\0X\343" - "\0]\345\0]\344\0\\\344\0U\342\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\374\374\375\215\256\361\0T\344\0]\344\0]\344" - "\0]\344\0\\\344\0Z\345\36m\347\267\310\367\377\377\377\377\377\377\343\351" - "\373Y\216\354\0W\343\0]\345\0_\344\0Z\344>\200\353\322\335\370\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\275\316\366%q\350\0[\344\0^\346\0_\344\0]\344\0^\345\0]\344" - "\0Y\343N\204\352\357\363\375\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\0J\341\0]\344\0]\344" - "\0]\345\0]\344\0]\344\0]\344\0]\345\0]\344\0[\344\4^\344\200\243\360\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\310\327\371*o\347\0Z\344\0]\345\0_\345\0U\343y\253\362\377\377\377" - "\256\305\365\36k\350\0Z\344\0]\345\0_\344\0]\345\0^\344\0]\344\0^\346\0^" - "\346\0\\\344\0^\344\0]\344\0\\\344\0^\346\0]\344\0]\344\0^\346\0]\344\0]" - "\344\0_\346\0]\344\0X\3444s\350\377\377\377\377\377\377Y\211\355\0X\343\0" - "]\344\0]\344\0^\346\0S\342\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\372\372\376\212\256\361\0K\343\0^\346\0]\344\0]\344\0\\\344" - "\0Y\344.w\350\334\341\371\377\377\377\377\377\377\377\377\377\343\351\373" - "Y\217\354\0X\345\0_\346\0]\344\0X\344>\200\353\322\335\371\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\375" - "\373\376>\204\352\0T\343\0]\345\0]\344\0]\344\0]\344\0_\346\0]\344\0]\345" - "\0N\342\243\276\364\377\376\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\0L\343\0]\344\0_\345\0]\344\0]\344" - "\0]\344\0^\344\0]\344\0^\345\0]\344\0Z\344\10b\345\234\266\363\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\310\327\370" - "*p\347\0Z\344\0]\345\0_\345\0U\343y\253\362\377\377\377s\250\361\0Q\342\0" - "^\345\0]\344\0]\344\0^\346\0]\344\1^\344\1]\344\1]\344\1]\345\1]\345\1]\345" - "\1]\344\1_\346\1]\344\1_\344\2_\346\0\\\344\0]\344\0]\344\0^\345\0]\344\0" - "H\342\377\377\377\377\377\377Y\211\354\0Z\345\0]\344\0^\345\0\\\344\0S\343" - "\377\377\377\377\377\377\377\377\377\377\377\377\363\366\375]\215\354\0N" - "\343\0^\345\0_\346\0]\344\0[\344\0^\345J\211\353\361\357\373\377\377\377" - "\377\377\377\377\377\377\377\377\377\343\351\372Y\217\354\0X\345\0]\344\0" - "_\346\0X\344>\200\352\322\335\370\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\230\265\364\24f\346\0[\344\0" - "]\345\0]\344\0]\344\0]\344\0]\344\0^\345\0]\345\0Z\344-o\350\353\360\375" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\0J\341\0_\344\0_\346\0]\344\1_\344%q\350\0\\\344\0]\344\0_\346" - "\0]\344\0_\346\0X\344\23i\347\304\322\370\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\310\330\370*q\350\0Z\344\0]\344\0]\345\0U\343" - "y\253\362\377\377\377y\253\362\0T\343\0_\346\0]\344\0]\345\20h\347V\213\355" - "r\231\356o\227\356o\227\356o\230\357o\230\357o\230\357m\227\356m\227\356" - "o\227\356o\227\357v\233\356/w\350\0^\344\0]\344\0]\344\0^\345\0M\342\343" - "\351\373\377\377\377Y\210\353\0X\343\0]\345\0]\344\0\\\344\0U\342\377\377" - "\377\377\377\377\377\377\377\356\362\374N\202\354\0Q\342\0^\345\0^\345\0" - "]\344\0\\\346\12a\345k\231\356\377\375\376\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\342\351\373W\216\354\0W\343\0_\346\0]\344\0" - "X\344>\201\353\322\335\371\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\346\353\373:\201\352\0V\343\0]\345\0^\344\0[\344" - "\32l\346\14d\346\0]\344\0]\344\0]\344\0_\345\0Q\344\204\251\361\374\375\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\0K\342\0]\344\0]\344\0\\\344\10c\347\260\301\365Q\207\352\0W\344\0_\345" - "\0]\344\0]\344\0]\344\0Y\3440y\350\342\350\373\377\377\377\377\377\377\377" - "\377\377\377\377\377\310\327\370*p\347\0Z\344\0^\345\0]\344\0T\343y\253\362" - "\377\377\377y\253\362\0T\343\0]\344\0_\345\0V\343u\242\357\377\375\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\344\373\20f" - "\346\0[\344\0]\344\0_\346\0P\343\311\325\367\377\377\377Y\210\353\0X\343" - "\0]\344\0^\345\0]\345\0S\343\377\377\377\377\377\377\334\345\371-n\347\0" - "T\343\0]\344\0_\346\0^\345\0Z\344\26j\350\226\263\363\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\343\351" - "\374Y\217\355\0X\345\0]\344\0]\345\0Y\344>\200\353\322\335\371\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\215\257\362" - "\17c\346\0\\\344\0]\345\0^\344\0U\344\206\254\361\216\252\362\22g\346\0[" - "\344\0]\344\0_\346\0\\\344\7Z\343\343\353\373\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\0L\343\0]\344\0]\344\0\\\344" - "\4_\345\264\305\366\373\375\375\27j\347\0Y\345\0]\344\0]\344\0^\345\0^\344" - "\0Y\344N\207\352\371\370\376\377\377\377\377\377\377\377\377\377\310\327" - "\370*q\350\0[\345\0_\346\0]\344\0T\343y\253\362\377\377\377y\253\362\0T\343" - "\0^\345\0_\346\0T\343}\251\361\370\371\376\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\352\354\373\20h\347\0[\344\0]\345\0^\344\0O" - "\342\313\330\370\377\377\377Y\211\354\0Y\344\0]\344\0_\346\0^\345\0U\344" - "\377\377\377\327\342\372\32d\345\0V\343\0]\344\0^\345\0]\344\0Z\344&t\350" - "\263\304\364\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\343\351\373Y\216\354\0W\344\0^\344\0" - "]\345\0Z\344>\202\353\322\335\371\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\317\332\3700y\350\0Y\345\0]\344\0]\344\0Z\344\14d\345" - "\313\335\371\377\377\377=\203\353\0Z\344\0]\344\0]\344\0_\345\0T\343d\224" - "\354\372\373\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\0J\341\0]\344\0]\344\0]\346\4_\345\257\302\365\377\377\377\327\342\372" - "\2^\344\0Y\344\0]\344\0_\346\0^\344\0\\\344\5^\345r\234\356\377\377\377\377" - "\377\377\377\377\377\310\327\371*o\347\0Z\344\0^\345\0]\344\0T\343y\253\362" - "\377\377\377y\253\361\0T\343\0_\346\0]\344\0T\343|\250\361\367\370\376\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\347\353\373\17g" - "\345\0[\344\0]\345\0_\344\0O\342\313\330\370\377\377\377Y\210\353\0Z\345" - "\0]\344\0^\345\0]\344\0X\343\314\333\370\7Y\343\0Z\345\0^\344\0^\345\0^\344" - "\0]\344/x\351\353\354\373\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\343\351\374" - "Y\217\355\0X\345\0_\344\0]\344\0Y\344>\201\351\322\335\370\377\377\377\377" - "\377\377\377\377\377\377\377\377\376\375\376n\235\357\1[\344\0]\344\0]\344" - "\0]\345\0T\343\221\263\362\373\372\376\377\377\377\271\311\365\24i\347\0" - "Z\344\0^\345\0]\345\0]\344\0R\342\317\335\371\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\0K\341\0^\345\0^\344\0]\346\4_\345\256\300" - "\364\377\377\377\377\377\376\262\307\365\1]\344\0[\344\0]\344\0]\344\0_\346" - "\0Z\344\12c\345\215\256\362\377\377\377\377\377\377\310\327\371*o\347\0Z" - "\344\0_\346\0]\344\0T\343y\253\362\377\377\377y\253\361\0U\344\0^\345\0]" - "\344\0T\343}\250\361\367\370\376\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\350\353\374\17g\346\0[\344\0]\344\0]\344\0P\343\314" - "\330\371\377\377\377Y\210\354\0X\343\0^\344\0_\346\0]\345\0[\344'r\350\0" - "V\343\0^\346\0^\344\0^\346\0\\\344\11c\345\223\262\362\377\376\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\343\351\373X\217\355\0W\343\0^\345\0^\345\0" - "Z\344>\200\352\322\335\370\377\377\377\377\377\377\377\377\377\377\377\377" - "\271\314\366%r\350\0Y\344\0^\345\0]\344\0Z\345)p\350\330\344\372\377\377" - "\377\377\377\377\377\377\377G\210\353\0[\344\0]\344\0]\344\0]\344\0X\344" - "A|\352\370\371\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0L\341\0" - "_\346\0_\344\0]\346\4_\345\256\300\364\377\377\377\377\377\377\376\376\376" - "\214\256\361\0Z\344\0\\\345\0^\344\0]\344\0^\345\0X\344\33n\347\270\314\366" - "\377\377\377\311\330\371*p\347\0Z\344\0^\345\0]\344\0T\343y\253\362\377\377" - "\377y\253\361\0T\343\0_\345\0^\345\0T\343|\250\360\367\370\376\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\347\353\373\17g\346\0\\" - "\345\0^\345\0^\344\0O\342\313\327\370\377\377\377Y\210\354\0Y\343\0]\344" - "\0_\346\0^\345\0V\343\354\354\374/y\350\0X\344\0]\344\0]\344\0_\345\0\\\345" - "\0Z\344o\231\357\361\364\375\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\342\351\373X\216\354" - "\0W\344\0_\346\0_\346\0Y\344>\202\353\322\335\372\377\377\377\377\377\377" - "\377\377\377\372\371\375]\226\355\0X\344\0]\344\0]\344\0]\345\0X\344\230" - "\270\363\372\370\375\376\375\376\374\373\376\377\377\377\320\330\367\34n" - "\347\0[\344\0^\345\0^\345\0_\345\0M\342\270\315\366\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\0K\341\0_\346\0^\344\0]\345\4`\346\256\301\365\377" - "\377\377\377\377\377\377\377\377\370\372\376b\222\355\0Y\345\0^\345\0]\344" - "\0_\345\0]\344\0V\344&v\351\334\346\372\321\335\371*q\350\0[\345\0^\345\0" - "^\344\0T\343y\253\361\377\377\377y\253\361\0U\344\0_\345\0_\345\0T\343~\250" - "\361\370\370\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\351\353\373\17g\345\0\\\345\0^\345\0^\344\0P\342\314\330\370\377\377" - "\377Y\210\353\0Y\344\0]\344\0^\345\0\\\344\0T\343\377\377\377\362\363\374" - "0y\350\0X\344\0\\\345\0_\344\0]\344\0\\\344\0Y\343Q\206\353\342\351\373\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\343\351\374Y\217\355\0X\345\0^\345\0^\345\0X\343>\201\353\322\335" - "\371\377\377\377\377\377\377\377\377\377\241\276\364\27h\347\0[\344\0]\344" - "\0]\344\0^\346\24e\346\177\250\361\241\277\365\233\272\363\233\272\363\232" - "\273\364\246\301\365\32m\347\0[\344\0^\345\0_\346\0_\346\0Z\344\"i\346\364" - "\365\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\0K\342\0^\345\0]\344\0\\\344" - "\4_\345\256\300\364\377\377\377\377\377\377\377\377\377\377\377\377\351\357" - "\374>~\351\0Y\345\0]\345\0]\344\0]\344\0^\345\0X\344I\212\354\265\310\365" - "1t\350\0Z\344\0^\345\0^\344\0U\344y\253\361\377\377\377y\253\362\0T\343\0" - "^\345\0_\345\0U\343y\245\361\372\371\376\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\347\351\373\20h\346\0[\344\0]\344\0]\345\0P" - "\342\312\326\370\377\377\377Y\210\353\0X\344\0^\345\0]\344\0\\\344\0U\344" - "\377\377\377\377\377\377\357\361\374=\202\353\3]\345\0\\\344\0]\344\0^\345" - "\0\\\344\0Y\344>|\351\300\325\370\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\343\351\373X\217\355\0X\344\0^\344\0^\345" - "\0Y\344>\200\352\322\335\370\377\377\377\377\377\377\346\354\374F\210\354" - "\0U\343\0]\344\0^\345\0]\344\0^\345\0\\\345\0U\343\0R\343\0R\343\0R\343\0" - "S\344\0T\344\0[\344\0^\345\0]\344\0^\345\0_\345\0^\345\0Q\344\224\264\363" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\0K\342\0]\344\0]\344\0]\345\4`\346\256" - "\301\365\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\317" - "\335\371\"p\350\0X\344\0^\345\0]\344\0]\344\0\\\344\11b\3454v\350(r\350\0" - "\\\345\0]\344\0^\345\0U\344y\253\361\377\377\377y\253\361\0T\343\0]\344\0" - "^\345\0Y\344A\202\352\270\315\366\331\343\372\324\340\372\325\340\372\325" - "\340\372\325\340\371\325\340\372\325\341\372\325\340\371\325\341\372\325" - "\341\372\334\345\372\234\271\364\12d\347\0\\\345\0]\344\0]\344\0O\343\323" - "\335\371\377\377\377Y\210\353\0X\343\0^\345\0]\345\0\\\344\0U\342\377\377" - "\377\377\377\377\377\377\377\377\377\377i\226\355\0\\\345\0Z\344\0^\345\0" - "]\345\0]\344\0X\343\32l\347\257\310\366\376\374\376\377\377\377\377\377\377" - "\377\377\377\377\377\377\342\351\373X\216\354\0W\343\0_\345\0^\345\0Z\345" - ">\200\352\322\335\371\377\377\377\377\377\377\217\262\362\15b\345\0\\\344" - "\0]\344\0^\345\0]\344\0]\344\0^\345\0]\344\0]\345\0^\344\0^\345\0]\344\0" - "]\344\0^\344\0]\344\0^\345\0]\344\0^\344\0_\346\0\\\345\0X\343\347\354\374" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\0J\341\0^\345\0]\344\0]\345\4_\345\256\301\365\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\256" - "\306\365\20e\345\0Z\345\0]\344\0^\345\0]\344\0\\\344\0Z\344\0[\344\0]\344" - "\0]\344\0^\345\0T\343y\253\362\377\377\377w\251\361\0T\344\0^\345\0]\344" - "\0^\345\0V\343\31h\3463t\350/r\3500s\3500r\3500s\3500r\3510s\3510r\3500s" - "\3510s\3513t\350\10a\345\0^\345\0^\345\0]\344\0]\344\0L\342\362\365\375\377" - "\377\377Y\210\354\0Y\344\0]\344\0^\345\0\\\344\0U\343\377\377\377\377\377" - "\377\377\377\377\377\377\377\376\375\377m\231\355\22f\346\0Y\344\0^\345\0" - "]\345\0]\345\0X\343\11b\346\230\267\363\356\362\375\377\377\377\377\377\377" - "\377\377\377\343\351\374Y\217\355\0W\343\0^\345\0]\344\0Z\344>\200\353\322" - "\335\371\377\377\377\321\335\3718~\351\0X\344\0]\345\0^\345\0]\344\0[\344" - "\0W\343\0V\343\0W\343\0V\343\0W\343\0W\344\0V\343\0V\343\0X\344\0V\343\0" - "Z\345\0]\344\0]\344\0^\345\0^\345\0U\344d\225\355\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\0K\342\0_\346\0^\345\0\\\344\4`\346\256\300\364\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\375\374\376\230\266\362" - "\6_\345\0[\344\0^\345\0]\344\0^\345\0]\344\0^\345\0]\344\0^\345\0]\344\0" - "T\343y\253\362\377\377\377\213\263\363\0\\\345\0]\345\0^\344\0]\344\0^\344" - "\0\\\345\0Z\344\0Z\344\0[\344\0Z\344\0[\345\0Z\344\0Z\344\0Z\344\0Z\344\0" - "Z\344\0Z\344\0]\345\0_\346\0]\344\0^\345\0[\344\0Y\344\377\377\377\377\377" - "\377Y\211\355\0Y\344\0^\345\0]\344\0\\\344\0U\344\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\376\376\232\266\363\20d\346\0Y\344" - "\0]\345\0]\344\0^\344\0[\345\0\\\344m\233\357\346\354\373\377\377\377\377" - "\377\377\343\351\374Y\217\355\0W\344\0]\344\0]\345\0Z\344>\201\353\324\337" - "\372\377\377\377{\245\360\0Z\344\0]\344\0]\345\0^\345\0X\344%u\350P\217\355" - "S\222\355R\223\355R\222\355R\222\355R\222\355R\222\355R\222\355R\223\356" - "V\224\355;\200\352\1^\345\0]\344\0]\344\0_\345\0]\345\0R\343\330\340\372" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\0K\342\0_\346\0^\345\0\\\344\4`\346\256\301\365\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\363\366\375s\236\356\1\\\344\0\\\345\0]\344\0^\345\0^\345\0^\345\0]\344" - "\0]\344\0^\345\0U\343y\253\362\377\377\377\321\334\370=\177\352\0V\343\0" - "]\344\0]\345\0^\344\0]\344\0]\344\0^\345\0]\344\0]\344\0^\345\0^\344\0]\344" - "\0^\345\0]\344\0_\346\0]\344\0]\344\0_\346\0]\344\0\\\344\0S\343|\242\360" - "\377\377\377\377\377\377X\210\354\0X\343\0^\345\0^\345\0\\\344\0U\344\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\233\267\364\34l\346\0V\343\0^\345\0^\344\0]\344\0[\345\0\\\344U" - "\212\353\326\340\372\377\377\377\346\353\374X\217\355\0X\344\0]\344\0]\345" - "\0Y\344>\201\352\333\343\372\305\326\371)t\350\0Y\344\0^\344\0]\345\0\\\344" - "\11a\345\246\301\364\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\355" - "\355\373!n\347\0[\344\0]\344\0_\345\0^\345\0V\343J\205\353\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0B\340" - "\0V\344\0U\343\0T\343\0W\344\251\275\364\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\344\353" - "\373R\212\354\0T\343\0U\343\0U\344\0V\344\0U\344\0U\343\0U\343\0V\344\0L" - "\341r\246\361\377\377\377\377\377\376\243\302\3641x\351\0[\344\0U\343\0W" - "\344\0W\343\0X\343\0W\343\0W\343\0X\344\0W\343\0X\343\0W\343\0W\343\0W\343" - "\0X\344\0W\343\0W\344\0X\344\0T\343\17b\345N\214\353\356\361\375\377\377" - "\377\377\377\377O\202\352\0P\342\0U\343\0V\344\0T\343\0L\342\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\262\307\365't\350\0R\344\0U\343\0U\344\0V\344\0S\343\0S\344" - "1u\351\256\311\366\332\342\371Q\211\353\0N\342\0V\344\0U\343\0P\3437|\351" - "\277\315\366`\230\356\0N\342\0U\343\0U\344\0U\343\0N\342^\223\356\353\357" - "\374\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\177\243" - "\357\0X\344\0T\343\0V\344\0U\343\0U\344\0D\341\252\302\365\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377T\223\355f\237\360" - "f\237\357d\236\357h\237\357\316\332\371\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\317\336\372g\236\356d\235\357f\237\360f\236\357f\237\360f\236\357f\236\357" - "f\236\357]\231\356\257\314\367\377\377\377\377\377\377\377\377\376\312\327" - "\370y\246\360S\221\355N\215\355O\215\354O\215\354O\215\354O\215\354O\216" - "\355O\215\355O\215\354O\215\354O\215\354O\214\354O\216\354O\215\354O\216" - "\355N\214\354Y\226\356\225\264\363\362\364\374\377\377\377\377\377\377\377" - "\377\377\233\267\363a\233\356e\237\357f\236\357e\235\357]\230\356\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\307\326\371[\231\357f\237\357f\237\360f\237" - "\357f\236\357c\236\357\\\230\356\215\265\362\340\347\372\235\275\364_\232" - "\356f\237\360f\236\357`\234\357\217\266\363\303\322\367\211\261\362`\233" - "\356f\237\357f\237\360f\236\357\\\230\356\277\326\370\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\351\354\373p\243\360" - "c\235\360f\237\357f\236\357f\237\360^\233\357\224\261\362\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372" - "\371\377\360\361\374\361\362\375\361\361\375\361\361\375\361\362\374\361" - "\362\375\361\362\375\361\362\374\361\362\375\361\361\375\361\361\375\361" - "\362\375\360\362\375\361\362\374\357\361\374\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\367\371\376\276" - "\317\366\355\361\374\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\366\370\375\265\311\366\320" - "\334\371\374\375\376\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\337\345\373v\250\361j\241\357" - "l\243\360\255\304\365\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\323\336\371\356\362\375\377" - "\377\377\377\377\377\256\303\364\32i\347\244\276\364\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\367\370" - "\376\262\312\366n\244\360l\243\360u\247\360\243\277\364\346\354\373\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\350\355" - "\374-s\350\201\246\357\367\371\376\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\356\361\3759~\351\24b\345\\" - "\224\355^\225\356\207\250\360\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377F\205\352\301\323\370" - "\377\377\377\377\377\377\270\313\3663y\351\254\303\365\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\356\362" - "\375b\223\355\0X\344P\212\353?~\352,p\350g\233\357\347\355\373\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\351\354\374\11d\347q\234" - "\355\367\370\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\203\245\361\0J\341\245\274\364\371\370\375\364" - "\365\375\343\352\373\377\377\377\377\377\377\355\360\374\363\364\375\377" - "\377\377\377\377\377\377\377\377\373\374\376\361\363\375\377\377\377\377" - "\376\376\356\357\374\372\372\376\377\377\377\377\377\377\371\371\375\365" - "\365\375\377\377\377\376\374\376\356\360\375\377\375\376\377\377\377\377" - "\377\377\377\377\377\377\377\377\373\372\376\356\360\374\377\375\376\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\366\366\376\357" - "\361\374\366\370\375\372\372\375\304\321\367\0Z\344\241\274\363\360\360\374" - "\372\373\376\352\355\374\300\315\366\355\361\375\377\377\377\355\357\374" - "\377\377\377\377\377\377\357\360\375\356\360\375\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\355\357\374\363\363\376\377\377\377" - "\370\371\376\367\370\376\377\377\377\377\377\377\377\377\377\360\363\375" - "f\226\355\37p\350\337\342\372\336\345\373v\244\361\7`\346\227\266\363\377" - "\377\377\377\377\377\377\377\376\356\360\374\372\371\376\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\367\367\375\356\360\375\377" - "\377\377\377\377\377\377\377\377\371\372\376\367\371\376\377\377\377\376" - "\374\376\361\362\374\372\372\376\377\377\377\377\377\377\351\354\373\16f" - "\346t\235\356\370\371\376\377\377\377\377\377\377\362\363\375\357\360\375" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\2Y\344#n\347\377\377\377\377\377\377" - "\377\377\377\377\377\377\367\371\376\200\247\360;\201\352>\203\353n\242\360" - "\357\360\374\377\377\377\322\342\372a\227\356\265\313\366S\221\355;\201\353" - "]\224\355\301\322\367\377\377\377\264\316\366y\245\360\244\301\365M\215\354" - "<\201\353h\232\356\322\337\371\377\377\377\377\377\377\306\326\370]\224\355" - ":\200\352S\220\355\272\320\367\373\373\376\377\377\377\365\366\375\215\263" - "\363G\210\3542|\351\234\272\364\224\262\3623y\351\0Y\344,w\3506~\352\261" - "\306\365N\215\354C\207\353\331\343\372\377\377\377=\202\352\323\333\370d" - "\234\356:\177\352A\206\353\224\263\362\377\377\377\377\377\377\377\377\376" - "\207\253\361:\202\353C\206\354\227\266\362\226\264\363\301\322\367\377\377" - "\377\377\377\377\377\377\377\360\363\375f\226\355\37q\350\357\360\374\377" - "\377\377\312\333\371\25d\346\\\225\356\377\377\377\320\337\371c\227\355:" - "\201\353L\213\354\251\307\366\377\377\376\377\377\377\366\366\375\222\267" - "\363A\206\353<\201\353m\235\357\332\344\372\377\377\377\320\335\371\231\266" - "\363\262\306\366e\233\356;\202\353T\221\354\306\327\367\377\377\377\352\354" - "\373\15f\345t\236\357\370\371\376\377\377\377\244\276\364E\207\353:\200\353" - "]\227\356\340\347\372\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\343\350\373\0I\342o\226\355\377\377\377\377\377\377" - "\377\377\377\375\374\377\223\261\362\2[\344g\231\356~\253\362\16_\345d\233" - "\356\377\377\377\300\330\371\0R\3438|\351[\221\355v\246\361\25d\346X\221" - "\355\377\377\377\224\274\364\0Z\3457{\352m\236\356j\237\357\17a\346u\244" - "\360\377\376\376\335\344\373D\203\3533z\351\201\255\3628|\351;z\351\325\342" - "\371\377\377\377\207\260\362\5_\345Q\215\355\214\266\362\276\322\370\260" - "\306\365V\215\354\0Z\344N\212\353j\235\357\312\327\370N\207\354\0I\341\303" - "\323\370\377\377\377\0N\3432z\3519x\351\235\302\365(n\347\0W\344\372\371" - "\375\377\377\377\245\274\363\0W\344`\225\356\204\257\362)l\346\36m\350\252" - "\277\363\377\377\377\377\377\377\377\377\377\360\363\375f\226\355\37q\350" - "\355\356\374\377\377\377\325\340\372&m\347Q\223\356\363\364\375M\207\353" - "\"q\347\202\255\361>\204\3523x\351\314\332\370\377\377\377\227\273\363\27" - "g\346Z\223\355q\241\357\30g\345f\226\355\361\363\375\303\323\3678{\352\31" - "h\346l\240\357\203\255\362\10c\345=|\351\353\361\375\356\357\374\15f\346" - "t\235\356\377\377\377\305\322\367\15c\344T\216\355\216\267\362\17a\346T\211" - "\352\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\321\333\371\0K\342\234\264\362\377\377\377\377\377\377\377\377\377\363" - "\367\375\31h\3469z\351\377\375\376\375\373\376k\231\356\13d\345\335\343\371" - "\313\337\372\0I\341+x\351\362\362\374\364\365\375]\223\355(u\350\343\347" - "\373\240\303\366\0I\342N\216\354\375\372\375\350\354\373A\203\352C\203\353" - "\354\357\373\224\270\364\23c\346\233\273\363\377\377\377\246\276\364\21c" - "\345\240\301\365\355\355\373,y\350@\201\352\332\343\372\377\377\377\377\377" - "\377\377\377\377\257\302\364\0Z\344\251\302\364\367\367\375\377\377\377\246" - "\273\364\0Q\343\305\324\370\377\377\377\0X\344\0H\342\325\336\372\377\377" - "\377\252\276\364\0I\341\270\310\365\377\377\377\12`\345'o\347\376\373\376" - "\377\377\377r\234\356\0Z\345\261\303\364\377\377\377\377\377\377\377\377" - "\377\360\363\375f\226\355\37q\350\355\356\374\377\377\377\317\336\371\24" - "b\345]\231\356\272\322\367\14_\345\212\257\362\377\377\377\266\314\366\40" - "k\347\211\264\363\366\366\375D\206\3539}\352\337\346\372\377\377\377e\230" - "\356\20a\345\277\326\367\316\331\370\36n\3478|\351\336\347\373\377\377\377" - "m\234\357\0V\344\307\332\371\356\356\374\15f\346t\236\356\377\377\377J\207" - "\353\16`\345\340\350\373\377\377\377s\233\356\0O\342\354\360\374\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\324\334\371\0L\342\250" - "\274\363\377\377\377\377\377\377\377\377\377\334\351\373\0R\343\204\245\361" - "\377\377\377\377\377\376\260\312\366\0Y\343\246\274\364\316\341\372\0Q\342" - "v\241\360\377\377\377\371\371\376}\251\360\37n\350\324\335\371\237\303\365" - "\0S\343\214\262\361\377\377\377\364\364\375Y\224\355;}\351\337\345\372g\240" - "\3572v\351\333\344\372\377\377\377\337\344\372%r\347\211\263\362\305\321" - "\367\30l\347\207\255\362\373\372\376\377\377\377\377\377\377\377\377\377" - "\267\310\366\0Y\344\260\307\366\377\377\377\377\377\377\254\300\364\0Q\343" - "\305\324\367\377\377\377\0T\343&l\347\377\377\377\377\377\377\333\340\372" - "\0I\341\242\270\362\370\371\376\0H\341u\233\356\377\377\377\377\377\377\260" - "\306\365\0W\344\261\303\364\377\377\377\377\377\377\377\377\377\360\363\375" - "f\225\355#s\350\377\373\376\377\377\377\214\261\361\11_\345\215\257\361\216" - "\266\363\36n\350\317\332\371\377\377\377\343\351\373<~\352f\235\357\271\312" - "\366\33i\346y\252\361\377\377\377\377\377\377\230\267\363\1Y\344\254\315" - "\366\323\333\371\32l\347\200\251\360\370\370\376\377\377\377\263\305\365" - "\3^\345\251\305\366\351\352\374\16g\346u\237\357\377\377\376\15g\346`\216" - "\354\377\377\377\377\377\377\305\321\366\0L\341\320\334\371\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\323\333\371\0K\342\246\273\363" - "\377\377\377\377\377\377\377\377\377\277\321\370\0T\343\252\300\365\377\377" - "\377\377\377\377\313\336\371\0S\343\217\256\363\320\342\372\0V\343\221\256" - "\362\377\377\377\371\371\376}\252\361\40n\347\326\336\371\235\302\365\7\\" - "\344\246\277\364\377\377\377\364\365\376Z\224\356=\177\352\317\331\370Y\225" - "\356\32j\347s\234\357\213\255\361w\236\357\6_\345\210\261\362\241\270\364" - "\10`\345\237\300\365\377\377\377\377\377\377\377\377\377\377\377\377\265" - "\307\366\0Z\345\257\306\366\377\377\376\377\377\377\253\300\365\0Q\344\305" - "\324\367\377\377\377\0R\343L\177\352\377\377\377\377\377\377\335\342\372" - "\0H\342\246\273\362\336\345\374\0L\341\237\270\363\377\377\377\377\377\377" - "\324\341\372\0S\343\261\303\364\377\377\377\377\377\377\377\377\377\360\363" - "\375k\230\356\0\\\344=\204\3536\201\352\24e\346W\215\354\345\352\373\200" - "\253\362\12a\346j\227\356\215\256\361o\232\356\21d\346[\226\356\242\272\364" - "\20a\344\206\263\363\377\377\377\377\377\377\270\313\366\25g\346\215\265" - "\362\304\321\367\33l\347\207\257\362\372\372\376\377\377\377\275\315\366" - "\10b\346\242\277\365\350\351\374\17g\347x\241\357\350\352\374\11e\345;z\351" - "\205\252\361\212\255\361m\227\355\0G\340\313\330\371\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\321\332\372\0K\341\253\277\364\377" - "\377\377\377\377\377\377\377\376\264\311\366\0W\344\265\307\364\377\377\377" - "\377\377\377\323\343\372\0R\343\212\252\361\320\342\372\0U\343\216\255\361" - "\377\377\377\370\371\376}\252\361\40o\350\327\337\372\235\302\365\12^\344" - "\250\301\365\377\377\377\364\364\375Z\224\356>\200\352\312\325\367V\223\356" - "\31g\347g\223\356y\236\356t\234\356_\220\354\277\323\370\225\261\363\0[\345" - "\257\314\366\377\377\377\377\377\377\377\377\377\377\377\377\265\307\366" - "\0Z\344\257\306\366\377\377\376\377\377\377\254\277\364\0P\343\305\325\367" - "\377\377\377\0R\343I}\353\377\377\377\377\377\377\335\341\373\0G\341\247" - "\273\362\330\342\373\0L\341\252\300\364\377\377\377\377\377\377\344\353\373" - "\0S\343\261\303\364\377\377\377\377\377\377\377\377\377\360\363\375k\231" - "\356\0]\344U\212\354o\236\357\236\275\364\345\354\373\375\374\376|\251\361" - "\7^\345]\215\355z\237\357s\233\356a\222\355\246\301\364\250\300\365\21c\346" - "\205\263\362\377\377\377\377\377\377\305\323\370\36n\347\205\257\361\300" - "\316\366\32l\347\206\256\362\371\371\376\377\377\377\275\315\366\10b\345" - "\243\277\365\350\351\374\17h\347x\241\357\340\343\373\11e\3467w\350v\234" - "\357w\235\357u\234\357U\214\354\337\346\373\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\346\354\374\0H\341y\234\360\377\377\377\377" - "\377\377\377\377\377\311\332\372\0S\343\223\257\361\377\377\377\377\377\377" - "\303\330\371\0W\345\237\270\363\316\341\372\0U\343\216\255\361\377\377\377" - "\371\371\376}\252\361\40o\347\326\336\371\235\302\364\11]\344\250\300\365" - "\377\377\377\364\364\376Z\224\356=\177\352\316\330\370W\224\3569{\352\306" - "\324\370\354\361\374\347\355\374\350\355\373\376\376\377\266\310\365\14d" - "\347\232\274\364\376\375\376\377\377\377\377\377\377\377\377\377\264\306" - "\365\0Y\344\257\306\365\377\377\376\377\377\377\254\300\365\0P\343\305\323" - "\367\377\377\377\0S\343I~\353\377\377\377\377\377\377\334\342\373\0H\340" - "\246\273\363\341\351\374\0K\342\241\270\362\377\377\377\377\377\376\304\324" - "\370\0U\343\261\303\364\377\377\377\377\377\377\377\377\377\360\363\375g" - "\227\355\33n\350\331\337\372\365\367\375\377\376\376\377\377\377\370\367" - "\376x\245\360\40n\350\272\314\367\356\362\375\350\356\374\350\356\374\374" - "\373\376\256\305\366\15_\345\201\260\362\377\377\377\377\377\377\253\302" - "\365\11`\345\237\303\365\316\330\370\31l\347\206\255\361\371\371\376\377" - "\377\377\270\311\366\6`\344\237\275\364\347\351\373\17h\346w\240\356\347" - "\351\373\5c\345k\226\355\345\354\373\351\357\374\350\356\374\347\355\374" - "\372\373\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\1W\343\15e\346\377\377\377\377\377\377\377\377\377\353\363\375" - "\0R\342\\\214\355\377\377\377\377\376\376\233\271\364\5`\345\303\320\367" - "\312\336\372\0V\343\216\256\362\377\377\377\370\371\376}\252\361\40n\347" - "\327\336\371\235\302\365\11^\345\250\300\365\377\377\377\364\364\376Z\224" - "\357;~\351\344\351\373e\236\360\27e\346\314\332\370\377\377\377\377\377\377" - "\377\377\377\377\377\377\320\332\370\30l\350\206\254\361\374\373\375\377" - "\377\377\377\377\377\377\377\377\265\306\366\0Y\344\262\310\365\377\377\377" - "\377\377\377\254\300\365\0Q\344\305\324\370\377\377\377\0T\344I}\352\377" - "\377\377\377\377\377\333\340\372\0G\340\245\272\363\377\377\377\0P\342d\220" - "\354\377\377\377\377\377\377\253\302\366\0X\344\260\303\364\377\377\377\377" - "\377\377\377\377\377\360\363\375f\225\355\40q\350\357\360\374\377\377\377" - "\377\377\377\377\377\377\376\375\376\204\257\361\22e\346\300\317\367\377" - "\377\377\377\377\377\377\377\377\377\377\377\311\327\370(r\350g\235\357\372" - "\371\375\377\377\377\217\262\362\16]\344\266\320\367\320\332\370\31k\347" - "\211\260\362\376\374\376\377\377\377{\242\360\0V\343\310\333\371\357\357" - "\374\15f\346s\235\356\377\377\377\3d\345>y\350\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377n\227\356\0M\343\220\256\362\377\374\375" - "\367\367\376\345\354\373@|\352\15d\346\344\347\373\360\361\3748w\350\21j" - "\347\375\372\376\305\332\371\0V\343\216\255\362\377\377\377\367\371\376}" - "\251\361\40o\347\326\336\371\235\302\365\11^\345\250\300\365\377\377\377" - "\364\364\375Z\225\355:}\351\343\352\373\253\304\365\22d\345_\224\355\361" - "\361\374\377\377\376\331\340\371\362\364\375\377\376\376;\202\352\21f\346" - "\277\321\367\377\376\376\357\362\375\377\377\377\261\304\366\0[\344\236\271" - "\362\376\373\376\377\376\376\254\301\364\0P\343\305\325\370\377\377\377\0" - "R\343G}\352\377\377\377\377\377\377\335\341\372\0H\341\243\271\363\377\377" - "\377F\177\351\0\\\344\317\327\370\333\343\371/t\350\1^\345\261\304\364\377" - "\377\377\377\377\377\377\377\377\360\363\375f\226\355\37p\350\354\356\374" - "\377\377\377\377\377\377\377\377\377\377\377\377\267\315\367\23b\345R\216" - "\354\361\361\374\377\376\377\323\334\371\343\350\372\374\373\376S\223\355" - "\27g\346\305\324\367\353\354\373>\201\352;{\351\336\346\372\314\327\370\33" - "m\350z\245\360\352\354\373\300\315\366\24h\346G\203\352\356\363\375\356\360" - "\374\15f\345s\236\356\377\377\377m\232\356\0X\344\233\266\363\377\377\377" - "\372\370\375\314\326\370\377\377\376\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\362\365\375E\177\351\0P\343\22j\347" - "\23j\347u\235\360\330\342\373\20^\344\5a\345\15f\346\7_\346\254\304\365\377" - "\377\377\273\323\370\0G\341\203\245\360\377\377\377\367\367\375q\241\360" - "\14b\345\321\332\371\222\274\363\0O\342\237\272\364\377\377\377\361\363\374" - "K\212\354)r\350\325\340\371\376\375\376s\237\356\4[\345\14e\346\24k\346\0" - "V\343\257\314\366\377\377\377\270\314\367\33k\346\5`\346\15g\346C\177\352" - "\351\360\374\351\354\373\1^\344\0]\344\7d\347\222\261\361\237\267\363\0B" - "\341\276\320\367\377\377\377\0E\3408r\351\377\377\377\377\377\377\327\334" - "\372\0""9\336\231\261\362\377\377\377\334\344\372\20^\344\0[\344\21g\345" - "Z\212\353\0]\344\260\304\364\377\377\377\377\377\377\377\377\377\355\361" - "\374X\215\354\13e\346\351\353\374\377\377\377\377\377\377\377\377\377\377" - "\377\377\362\365\375y\243\357\0X\344\15g\346\24k\350\0Z\345z\252\361\377" - "\377\377\312\331\370/w\347\0^\345\10c\345\25c\345\242\276\364\377\377\377" - "\307\324\367's\350\1`\346\21h\346\0X\344<{\352\322\336\371\377\377\377\346" - "\352\373\0Z\344g\224\355\372\372\376\365\365\3744u\350\0Y\345\26m\350\22" - "i\346\0N\342\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\354\360\374\270\320\367\240\275\364" - "\244\300\364\324\337\371\377\377\377\333\346\372\252\305\366\244\301\365" - "\312\333\371\377\375\376\377\377\377\366\371\376\325\344\372\356\362\374" - "\377\377\377\376\376\376\353\362\374\333\350\373\372\373\376\360\366\375" - "\330\345\372\362\365\375\377\377\377\376\376\376\345\356\374\340\352\373" - "\372\373\376\377\377\377\364\366\375\304\327\371\246\302\365\236\274\364" - "\276\324\370\363\370\375\377\377\377\375\375\376\334\347\373\253\306\365" - "\234\272\364\311\330\371\372\374\376\377\377\377\312\334\371\247\302\365" - "\234\273\364\334\345\372\362\366\375\323\343\372\367\371\376\377\377\377" - "\323\343\372\342\353\374\377\377\377\377\377\377\372\373\376\317\341\372" - "\361\364\375\377\377\377\377\377\377\351\360\374\300\326\370\324\344\373" - "\325\342\372\0U\343\254\300\363\377\377\377\377\377\377\377\377\377\375\375" - "\376\347\356\374\333\350\373\375\375\376\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\364\367\375\307\330\370\240\275\364\241\276" - "\364\266\316\367\352\362\375\377\377\377\377\376\376\332\345\373\253\306" - "\366\245\303\365\321\337\371\371\372\376\377\377\377\305\323\367\37o\347" - "S\215\354\234\273\363\275\324\371\347\355\374\377\377\377\377\377\377\374" - "\374\376\330\347\373\351\357\374\377\376\377\377\377\377\352\360\374\264" - "\315\370\242\276\364\237\274\365\314\337\372\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\375\375\376\376\375\376\377\377\376\377\377\377\377" - "\377\377\377\376\377\376\375\376\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\376\376\376\375\375\376\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\376\376\375\374\376\377\377\377\377\377\377\377" - "\377\377\377\377\377\376\375\376\375\375\376\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\376\266\310\365\262" - "\306\365\325\333\370\335\342\371I\202\352\0X\344\333\341\371\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\375\375\376\375\375\376\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\376\377\376\376\376\377\377\377\377\377\377" - "\377\377\377\305\323\367\32k\347\206\256\361\370\367\375\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\376\375\376\375\374\376\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\376\240\270\362\26b\346\0U\343\0W\344\10_\344\255\303\365" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\276\316\366\4]\345{\247\360\371\371" - "\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\371\372\376\353\361\374\346\360" - "\374\347\360\374\354\363\375\377\376\376\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\373\374\376\353\362\375\365\370\375\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - }; diff -r a5496987b1da -r 189ece41fa29 bsptemplate/asspandvariant/template_variant/camerasc/logoyuv2.cpp --- a/bsptemplate/asspandvariant/template_variant/camerasc/logoyuv2.cpp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1238 +0,0 @@ -// Copyright (c) 2006-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: -// template\template_variant\camerasc\logo.cpp -// This file contains the binary data for the logo that gets rendered in the -// "photos" taken by this template camera driver. -// -// - -#include "camerasc_plat.h" - -#ifdef __ARMCC__ -#pragma diag_suppress=177 // Disable the warning on LogoYUV not being in use -#endif -/** The logo rendered in "photos" returned by the template camera driver. */ -const struct SLogo Logo = - { - 80, 61, - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377" - "\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377" - "\377\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377" - "\376\377\377\377\377\377\372\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\376\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377" - "\374\377\377[\377\377\216QQ\222PPY\16\16\230\377\377\262\377\377\347\377\377\377\377\377\376\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377N\377\377\177jj\377\203" - "\203\354\203\203\302rr\310ll\27__\36\377\377\256\377\377\376\377\377\376\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377" - "\376\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\330\377\377Uee\375\200\200\375\200\200\376\200" - "\200\377\200\200\377\200\200\326\201\201&PP\344\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\0" - "\0\377\377\377\376\377\377\376\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\377\377\376\0" - "\0\377\377\377\377\377\377\374\377\377\377\377\377|\377\377\242bb\376\200\200\376\200\200\377" - "\200\200\373\200\200\322\201\201EPP\212\377\377\376\377\377\376\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\376\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\0" - "\0\332\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\0" - "\0\234\377\377c22\212>>\201>>,::{qq\375\200\200\377\200\200\221\200\200d\200" - "\200\0\204\204'\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\377\377\377\0" - "\0\376\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\376\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\334\377\377e\377\377\23CClCCb\6\6\342" - "\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\376\377\377\377\377\377\375\377\377\377\377\377\225\377\377J//z\177\177\307\203\203\255" - "\203\203z\203\203A\200\200\371\177\177\377\200\200\250\200\200\22\200\200" - "\0\204\204\22\377\377\317\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\376\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377" - "\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\376\377\377\377\377\377\315\377\377*\377\377\202dd\202\205\205~\205\205" - "\177ppV\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\376\377\377\377\377\377\317\377\377\"\36\36\351\205\205\376\200\200" - "\376\200\200\376\200\200\375\200\200\377\200\200\375\200\200\376\200\200" - "\376\200\200\377\200\200\202\200\200\30nnA\377\377\312\377\377\347\377\377\376\377\377\377" - "\377\377\377\377\377\377\377\377\354\377\377\334\377\377\335\377\377\335\377\377\336\377\377\265\377\377\12\0" - "\0\24\377\377\25\377\377\25\377\377\15\377\377k\377\377\333\377\377\335\377\377\336\377\377\377\377\377\377\0" - "\0\377\377\377\376\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\376\377\377\377\0" - "\0\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\204\377\377\277hh\375\200\200\375" - "\177\177\377\177\177\352\211\211=\1\1\377\377\377\377\377\377\377\377\377\376\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\274\5\5[\217" - "\217\376\177\177\376\200\200\377\200\200\376\200\200\376\200\200\377\200" - "\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200\377\200" - "\200\246\210\210\15\221\2217\12\12\377\377\377\370\377\377\251\377\377s\16\16%\24\24" - "\10\220\220\15\207\207\14\207\207\14\207\207g\207\207\215\207\207\212\207" - "\207\212\207\207\213\207\207\203\207\207*\207\207\14\207\207\15\210\210\3" - "]]H\13\13m\22\22\210\377\377\351\377\377\343\377\377\341\377\377\376\377\377\377\377\377\377\377\377" - "\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377" - "\376\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\204\377\377\317kk\377" - "\200\200\377\200\200\344\200\200\36\211\211G\1\1\377\377\377\377\377\377\376\377\377" - "\376\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377" - "\26\5\5\241\211\211\377\200\200\376\200\200\376\200\200\377\200\200\377\200" - "\200\251\200\200\226\200\200\261\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\376\200\200\371\205\205K88s11g110++Z}}a\210\210\350\177" - "\177\354\200\200\353\200\200\353\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\353\200\200\355\177" - "\177\276\203\203X\211\211Z\215\215\\..211\32""11\21""55\222\377\377\223\377\377\216" - "\377\377\262\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\376" - "\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\213\377\377\205" - "kk\377\200\200\344\200\200c\200\200\15\211\211%\377\377\251\377\377\370\377\377\377\0" - "\0\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\377\377\5\5\250\211\211\377\200\200\376\200\200\377\177\177\375\200\200\211" - "\205\205\0\211\211\0\211\211\0\211\211Z\211\211\256\212\212\377\200\200\376" - "\200\200\377\200\200\327\177\1774\204\2048\205\205\271\205\205\337\205\205" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\376\200\200\377\200\200\377\200\200\376\200\200\376\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\177\177" - "\377\205\205\317\205\205\272\205\205\275\210\210\246UUCUUMUUAUU/UU9DD\215" - "\377\377\243\377\377\346\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\376\377\377\376" - "\377\377\377\377\377\377\377\377\377\377\377\245\377\377\4kk\306\200\200\324\200\200=\200\200" - "\244\202\202SVVEWW5**\311\377\377\377\377\377\376\377\377\376\377\377\377\377\377\376\377\377\377" - "\377\377\376\377\377\377\377\377\377\377\377\244\5\5:\216\216\372\177\177\377\200\200\374" - "\200\200\233\205\205\0>>\235\10\10\303\13\13\305\13\13\205\13\13\4\2\2\224" - "\200\200\377\206\206\330\201\201%\177\1776\200\200\377\200\200\377\200\200" - "\377\200\200\376\200\200\377\200\200\376\200\200\376\200\200\377\200\200" - "\376\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200" - "\377\200\200\376\200\200\377\200\200\376\200\200\376\200\200\377\200\200" - "\377\200\200\376\200\200\377\200\200\377\200\200\377\177\177\377\200\200" - "\377\200\200\377\200\200\343\200\200\301\200\200\261~~1ss\6}}#\377\377?\377\377\266" - "\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\373\377\377\373\377\377\271\377\377\21\0" - "\0\12jj\347\200\200\376\200\200\377\200\200\375\177\177\377\200\200\377\201" - "\201\247\202\2026\31\31G\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377" - "\377\377\376\377\377\377\377\377\336\377\377""6\33\33\235\204\204\262yy\24vv\36\377\377\247\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\210\377\377?\377\377\336\1\1A\\\\,\202\202\377" - "\200\200\376\200\200\376\200\200\377\200\200\377\200\200\376\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377" - "\200\200\377\200\200\377\200\200\376\200\200\377\200\200\376\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377" - "\200\200\377\200\200\377\200\200\352\177\177V\204\204D}}\0**n\5\5\242\4\4" - "\351\377\377\374\377\377\377\377\377\24\377\377\0cc\30jj\233\207\207\376\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\177" - "\177\252\214\214F\15\15Y\3\3\377\377\377\376\377\377\376\377\377\377\377\377\376\377\377\377" - "\377\377\376\377\377\377\377\377\305\377\377""644*\11\11\264\377\377\350\377\377\377\377\377\376\377\377" - "\376\377\377\376\377\377\376\377\377\377\377\377\377\377\377\324\6\6\15\\\\\336\202\202\377\200" - "\200\376\200\200\377\200\200\376\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\376\200\200\377\200\200\377\200\200\377\200\200\376\200\200\311\206" - "\206e\215\2155^^2\36\36t\377\377\304\377\377O99\233\204\204\341\202\202\377\177\177" - "\377\200\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200" - "\377\200\200\376\200\200\377\177\177\377\212\212\0KK\307\377\377\377\377\377\376" - "\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377a\12" - "\12xvv\372\201\201\376\200\200\377\200\200\376\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\376\200" - "\200\377\200\200\377\200\200\377\177\177\377\202\202\244\201\201SDD\0GGt" - "``\377\200\200\377\200\200\377\177\177\317\202\202^\202\202_\202\202V\202" - "\202\322\200\200\377\177\177\376\200\200\376\200\200\377\200\200\377\177" - "\177DssP\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376" - "\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\376" - "\377\377\377\377\377\266\377\377\22\6\6\377\212\212\377\177\177\377\200\200\376\200\200" - "\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200" - "\376\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200\376\200\200" - "\376\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\376\200\200\377\200\200\376\200\200\376\200\200" - "\376\200\200\377\200\200\355\202\202E\202\202\0\201\201V\177\177\377\202" - "\202q\213\213\15kk\0ff\0ff\0dd?\201\201\377\200\200\377\200\200\377\200\200" - "\377\200\200\374\200\2004pp\256\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\376\377\377\376\377\377\377\377\377Z\377\377\332\210\210\377\177\177\376\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\376\200\200\376\200\200\377\200\200\376\200\200\377\200\200\376\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\376\200\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200" - "\376\200\200\377\200\200\377\200\200\376\200\200\375\200\200\375\200\200" - "\374\200\200\323\200\200\325\200\200\333\200\200\375\200\200\377\200\200" - "\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200" - "3\200\200\0\200\200\17[[\20\377\377\311\377\377\377\377\377\377\377\377\301\377\377\26\377\377@}" - "}\342\177\177\326\200\200\346\200\200\31\200\200\27oo\354\377\377\377\377\377\376" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\306\377\377@\24\24\374\205" - "\205\377\200\200\375\200\200\331\200\200\327\200\200\327\200\200\327\200" - "\200\327\200\200\330\200\200\377\200\200\377\200\200\377\200\200\376\200" - "\200\376\200\200\377\200\200\376\200\200\376\200\200\377\200\200\376\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\200" - "\200\377\200\200\377\200\200\376\200\200\333\200\200\327\200\200\305\200" - "\200o\200\200f\200\200f\200\200\0\200\200\0\200\200\0\200\200\277\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\376\200\200\375\200\200" - "\377\200\200\336\200\200\7\200\200\23\\\\\313\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\277\377\377r\377\377\0&&\0kk\0ff\0iim\377\377\372\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377I\377\377\202\201\201\377\177\177\377" - "\200\200\375\200\200%\200\200\16\200\200\17\200\200\17\200\200\17\200\200" - "\17\200\200\203\200\200\177\200\200\326\200\200\371\200\200\377\200\200\377" - "\200\200\376\200\200\377\200\200\376\200\200\377\200\200\376\200\200\376" - "\200\200\376\200\200\377\200\200\377\200\200\377\200\200\377\200\200\245" - "\200\200v\200\200\31\200\200\17\200\200\14\200\200\0\200\200\0\200\200\0" - "\200\200\0\200\200\0\200\200\0\200\200\224\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\200\200" - "I\200\200\15\\\\\276\377\377\377\377\377\376\377\377\376\377\377\376\377\377\377\377\377\377\377\377" - "\223\377\377s\377\377u\377\377\201\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\345\377\377$\377\377tyy\377\200\200\377\200\200\377\200" - "\200\221\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200" - "\200\0\200\200\40\200\200X\200\200\244\200\200\334\200\200\377\200\200\377" - "\200\200\375\200\200\376\200\200\376\200\200\377\200\200\377\200\200\350" - "\200\200\242\200\200O\200\200.\200\200\12\200\200\0\200\200\0\200\200\0\200" - "\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200" - "\230\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376\200\200" - "\377\200\200\376\200\200\377\200\200\216\200\200\20\\\\\275\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376" - "\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\252" - "\377\377\32XX\341\200\200\377\200\200\376\200\200\377\200\200\261\200\200\0\200" - "\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200" - "\1\200\200\4\200\200\33\200\200\"\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\"\200\200!\200\200\3\200\200\0\200\200\0\200" - "\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200" - "\0\200\200\0\200\200\0\200\200\0\200\200\226\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200" - "\200\377\200\200\26\\\\\273\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\372\377\377\202\377\377\31``\355\200\200\377\200\200" - "\377\200\200\376\200\200\377\200\200J\200\200\0\200\200\0\200\200\0\200\200" - "\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0" - "\200\200\20\200\200\265\200\200\374\200\200\377\200\200\32\200\200\0\200" - "\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200" - "\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\17" - "\200\200\275\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377" - "\200\200\377\200\200\376\200\200\377\200\200\265\177\177\21SS\273\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\354" - "\377\377>>>\0\211\211\226\177\177\377\200\200\376\200\200\376\200\200\377\200" - "\200\312\200\200\0\200\200\0\200\200\15\200\200_\200\200Z\200\200=\200\200" - "\10\200\200\0\200\200\0\200\200\0\200\200\0\200\200\10\200\200\235\200\200" - "\377\200\200\377\200\200(\200\200\0\200\200\0\200\200\0\200\200\0\200\200" - "\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\3\200\200\0\200\200\0" - "\200\200\0\200\200\0\200\200\27\200\200\273\200\200\377\200\200\376\200\200" - "\376\200\200\377\200\200\376\200\200\377\200\200\377\200\200\376\200\200" - "\377\200\200Jzz!\3\3\327\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377R\16\16\0qqf\200\200\333\200\200\377" - "\200\200\376\200\200\376\200\200\372\200\200y\200\200\12\200\200\0\200\200" - "\241\200\200\324\200\200\273\200\200\213\200\200\0\200\200\0\200\200\0\200" - "\200\16\200\200\267\200\200\377\200\200\377\200\200\377\200\200\35\200\200" - "\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\16\200\200\215\200\200" - "\276\200\200\267\200\200p\200\200\15\200\200\0\200\200\0\200\200>\200\200" - "\263\200\200\377\200\200\376\200\200\377\200\200\377\200\200\376\200\200" - "\377\200\200\376\200\200\377\200\200\377\200\200\275\177\177\31\202\202w" - "\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\340\377\377&\377\377\5\200\200\34\206\206\303\177\177\377\200" - "\200\377\200\200\377\200\200\374\200\200\313\200\200\213\200\200\0\200\200" - "\12\200\200\20\200\200\15\200\200\0\200\200\25\200\200\242\200\200\315\200" - "\200\377\200\200\375\200\200\377\200\200\346\200\200\16\200\200\0\200\200" - "\0\200\200\0\200\200\0\200\200\0\200\200\23\200\200Z\200\200_\200\200W\200" - "\200\11\200\200\0\200\200-\200\200\237\200\200\377\200\200\374\200\200\376" - "\200\200\376\200\200\377\200\200\377\200\200\377\200\200\376\200\200\377" - "\200\200\351\200\200z\200\200\23\206\206\4\10\10\377\377\377\377\377\377\376\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\375\377\377" - "\377\377\377\353\377\377""7\377\377\7\11\11\0\202\202|~~\332\200\200\371\200\200\371" - "\177\177\377\200\200\377\200\200\377\200\200\277\200\200\26\200\200\305\200" - "\200\377\200\200\371\200\200\377\200\200\377\200\200\376\200\200\377\200" - "\200\376\200\200\377\200\200\370\200\200\371\200\200\265\200\200*\200\200" - "1\200\2002\200\2001\200\200.\200\200.\200\200.\200\200+\200\200\223\200\200" - "\376\200\200\377\200\200\376\200\200\376\200\200\377\200\200\377\200\200" - "\377\200\200\376\200\200\376\200\200\374\200\200\377\200\200f\200\200\0\200" - "\200\0\207\207\224\377\377\377\377\377\376\377\377\376\377\377\376\377\377\377\377\377\376\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\375\377\377\377\377\377\377\377\377\251" - "\377\377\210\377\377""2::\14^^]__h\202\202\263\200\200\321\200\200\377\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376\200\200\376" - "\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376" - "\200\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377" - "\200\200\377\200\200\241\200\200N\200\200\5\200\2007\200\2007\205\205\6\35" - "\35\203\377\377\374\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377\377\377\376\0" - "\0\376\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377\0" - "\0\225\377\377)\2\2\0\212\212\0\200\200\17\200\200v\200\200\225\200\200\375\200" - "\200\377\200\200\376\200\200\376\200\200\377\200\200\377\200\200\376\200" - "\200\376\200\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\200" - "\200\376\200\200\377\200\200\377\200\200\377\200\200\314\177\177w\205\205" - "\0\210\210\12\207\207\316\177\177\377\200\200\377\177\177\247\204\204\6+" - "+I\377\377\331\377\377\377\377\377\377\377\377\376\377\377\376\377\377\376\377\377\377\377\377\376\377\377\377" - "\377\377\377\377\377\376\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\376\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377\222" - "\10\10\3\211\211V\200\200Z\200\200\0\200\200\4\200\200H\200\200\216\200\200" - "\377\200\200\376\200\200\376\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200\376\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\376\200\200\377\200\200\376\200\200\375\200\200\377\200\200\377\200\200" - "\260\200\200\224\177\177~\211\211\13\216\216\0::h\26\26\36!!\263\216\216" - "\377\177\177\377\200\200\377\200\200\266{{*oo\35\11\11\227\377\377\377\377\377\377" - "\377\377\376\377\377\376\377\377\377\377\377\377\377\377\302\377\377\377\377\377\377\377\377\377\377\377\375" - "\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376" - "\377\377\377\377\377\374\377\377\377\377\377/\377\377\23\10\10*\211\211\316\200\200\373\200\200" - "\324\200\200\13\200\200\0\200\200\0\200\200m\200\200\377\200\200\377\200" - "\200\376\200\200\376\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\376\200\200\375\200" - "\200\377\200\200\245\200\200\32\200\200\11\200\200\0\203\203\377\377\0F\377\377\316" - "\377\377\377\377\377,\377\377\0++\212\206\206\374\200\200\376\200\200\377\200\200\375" - "\200\2008\200\200\5}}O\377\377\377\377\377\376\377\377\376\377\377V\377\377!\377\377\14\377\377\40\0" - "\0""4\377\377\351\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\343\377\377\320\377\377l\6\6>\20\20\225~~\377\210\210\377\177\177" - "\377\177\177\350\202\202\336\201\201\17ff\20hh\0gg\0\200\200u\200\200\321" - "\200\200\377\200\200\376\200\200\377\200\200\376\200\200\377\200\200\346" - "\200\200\377\200\200\377\200\200\370\200\200\377\200\200\376\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\373" - "\200\200\236\200\200\0\200\200\0\206\206!\30\30k\377\377\216\377\377\377\377\377\377" - "\377\377\376\377\377\371\377\377""6\34\34\0dd\216\200\200\373\177\177\377\200\200\376" - "\200\200\377\200\200\301\200\200\12ii\22\20\20\207\27\27f\27\27\0**\21\220" - "\220a\210\210l\210\2107{{1\6\6\347\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376" - "\377\377\377\377\377\271\377\377\223\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377" - "\377\377\371\377\377\262\377\377\207\377\377\"66x88\222VV\372\214\214\377\200\200\377\177" - "\177\377\200\200\260\212\2122OO#CC\205\377\377\300\377\377\"\377\377\0\200\200\0\200" - "\200[\200\200\377\200\200\377\200\200\376\200\200\377\200\200\334\200\200" - "4\200\200\207\200\200\272\200\200g\200\200\337\200\200\377\200\200\376\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\275\200" - "\200\0\200\200\0\200\200\0||\260\32\32\377\377\377\377\377\377\376\377\377\376\377\377\376" - "\377\377\377\377\377\344\377\377:\377\377\0::y\202\202\377\177\177\377\200\200\376\200\200" - "\377\200\200\302\202\202A\211\211\0\210\210\0\210\210\12\207\207\246\177" - "\177\377\200\200\377\200\200\335\202\202\22TT\271\377\377\377\377\377\377\377\377\377" - "\377\377\376\377\377\377\377\377\253\377\377$\21\21""4jj.\7\7\270\377\377\377\377\377\377\377\377\375" - "\377\377\271\377\377*\6\6""0dd>ZZ\265\202\202\373\204\204\377\202\202\342\204\204" - "\312\206\206Z\211\211#||\33""88C\377\377\301\377\377\376\377\377\377\377\377""9\377\377\0\211" - "\211*\177\177\245\200\200\340\200\200\376\200\200\377\200\200\377\200\200" - "{\200\200\0\200\200i\200\200\262\200\200\0\200\200\257\200\200\377\200\200" - "\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\373\200\200" - "H\200\200\0\200\200\0\200\200\0||B\32\32\345\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\376\377\377\377\377\377\345\377\377""6\377\377\0\215\215r\206\206\375\177\177\377" - "\200\200\376\200\200\377\200\200\377\200\200h\200\2004\200\200\250\200\200" - "\377\200\200\377\200\200\377\200\200\326\202\202\17UU\270\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\225\377\377\27\377\377\347\204\204\373\201\201g\203\203\3\0" - "\0V\377\377S\377\377""1\377\377xww\260zz\337\200\200\370\200\200\377\200\200\350\177" - "\177J\205\205#HH\3**\7\4\4\256\5\5\315\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\277\377\377\0\6\6\20\215\215\270\202\202\377\177\177\376\200\200\377\200\200" - "\351\200\200,\200\200\0\200\200\334\200\200\252\200\200\0\200\200\256\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\370\200\200\"\200\200\0\200\200/\177\1774\211\211\0!!\226\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\376\377\377\375\377\377\377\377\377\377\377\377""0\6\6\0))\204" - "\210\210\374\177\177\375\200\200\376\200\200\377\200\200\370\200\200\377" - "\200\200\347\200\200O\200\200S\177\177U\204\204#uu=\377\377\377\377\377\377\377\377\376" - "\377\377\377\377\377\376\377\377:\377\377\370\212\212\377\177\177\376\200\200\377\177\177" - "\377\206\206)\206\2063\206\206d\207\207\377\200\200\377\200\200\375\200\200" - "\370\200\200a\200\200\0ss\20EE2\377\377\377\377\377\374\377\377\377\377\377\377\377\377\376\0" - "\0\377\377\377\376\377\377\376\377\377\377\377\377\267\377\377)\377\377\0""99\213\203\203\375\200" - "\200\377\200\200\376\200\200\373\200\200\374\200\200\377\200\200\265\200" - "\200e\200\200\377\200\200\376\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\376\200\200\376\200\200\377\200\200^\177\177\334\201\201'99" - "I\377\377\373\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377" - "\377\377\377\377\377\266\377\377\0==\233\201\201\373\177\177\377\200\200\376\200\200" - "\377\200\200\270\200\200\0\200\200\0\200\200\0\207\207\11\377\377M\377\377\377\0" - "\0\377\377\377\376\377\377\376\377\377\377\377\377\240\377\377h99\377\201\201\376\200\200\376" - "\200\200\376\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376" - "\200\200\372\200\200\244\200\200H\200\200\0\204\204K\377\377\312\377\377\377\377\377" - "\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\376\377\377\377\377\377\376\377\377\376\377\377" - "\377\377\377\373\377\377A==H\203\203\370\200\200\377\200\200\376\200\200\377\200" - "\200\377\200\200\375\200\200\377\200\200\377\200\200\377\200\200\376\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\200" - "\200\377\177\177\327\205\205*>>O\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\240\377\377\0AA" - "\205\200\200\373\200\200\377\200\200\377\200\200\345\200\200\213\200\200" - "\0\204\204\0OO\245\2\2\377\377\377\377\377\377\375\377\377\377\377\377\376\377\377\374\377\377G." - ".\234\177\177\377\177\177\376\200\200\376\200\200\376\200\200\374\200\200" - "\352\200\200\373\200\200\377\200\200\376\200\200\372\200\200\211\200\200" - "\0\200\200\0\204\204\355\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377" - "\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\376\377\377\377\377\377k==\213\203\203" - "\377\200\200\376\200\200\377\200\200\377\200\200\377\200\200\376\200\200" - "\377\200\200\377\200\200\375\200\200\377\200\200\376\200\200\377\200\200" - "\377\200\200\376\200\200\377\200\200\377\200\200{\205\205\31//F\377\377\377\0" - "\0\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\0" - "\0\377\377\377\376\377\377\377\377\377\377\377\377\257\377\377\0\201\201\341\200\200\377\200" - "\200\376\200\200\377\200\200\336\200\200\0\207\207I\36\36\370\377\377\377\377\377" - "\376\377\377\376\377\377\377\377\377\377\377\377\262\377\377\0PP\246\201\201\377\200\200\377" - "\200\200\377\200\200\377\200\200\373\200\200\"\200\200\332\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200:\200\200\0\204\204\223\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\376\377\377\346\377\377""2==M\203\203\241\200\200\377\200\200\377\200" - "\200\227\200\200\371\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\376\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\210\200\200\0\211\211\377\377\0\373\377\377\377\377\377\376\377\377\377\377\377\376\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\377\377" - "\377\377\377\233\377\377""2\201\201\377\200\200\377\200\200\377\200\200\376\200\200" - "\376\200\200s\207\207z!!\374\377\377\376\377\377\377\377\377\377\377\377\376\377\377\377\377\377" - "\371\377\377NFF\3{{\344\200\200\377\200\200\377\177\177\377\200\2005\200\200" - "\33\200\200\330\200\200\377\200\200\377\200\200\376\200\200\377\200\200\333" - "\200\200\15\204\204'\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\312\377\377\0==\0\203\203\0" - "\200\200\220\200\200$\200\200\2\200\200\26\200\200o\200\200=\200\200K\200" - "\200\331\200\200\376\200\200\377\200\200\344\200\200\344\200\200\344\200" - "\200\377\177\177~\200\200\0\204\204\266\377\377\377\377\377\376\377\377\376\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\0" - "\0\377\377\377\246\377\377\2\377\377\204\201\201\377\200\200\376\200\200\376\200\200" - "\377\200\200\331\200\200\0\204\204~\40\40\374\377\377\377\377\377\376\377\377\377\377\377" - "\377\377\377\376\377\377\377\377\377\255\377\377B\377\377\22bb#iiA\205\205\207\203\203\16\203" - "\203\36\203\203\330\177\177\377\200\200\377\200\200\376\200\200\376\200\200" - "\377\200\200t\204\204%\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\262\377\377:::\210\203\203" - "O\200\200\0\200\200F\200\200\214\200\200\21\200\200\0\200\200Q\200\200\40" - "\200\200\0\200\200\233\200\200\244\200\200\11\200\200\27\200\200\27\177\177" - "\37\201\2016ww\31\11\11\343\377\377\377\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\210" - "\377\377\31ss\377\177\177\376\200\200\376\200\200\377\200\200\372\177\177\201" - "\177\177\0--\246\377\377\375\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376" - "\377\377\377\377\377\377\377\377\311\377\377l\12\12q??v<<\12<<\37JJ\336\204\204\377\200\200" - "\377\200\200\377\200\200\377\200\200\241\177\177\22\214\214$\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\375\377\377@\14\14\230dd\321\201\201'\200\200\30\200\200\377\200\200" - "\345\200\200\31\200\200\11\200\200\232\200\200\354\200\200A\200\200\0\200" - "\200\31\200\200\210\200\200\337\200\200\331\200\200eqq\0\24\24\225\377\377\377" - "\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\355\377\377H\"\"\20ww\377\200\200\377\200" - "\200\377\200\200\377\200\200k\200\200\0++L\377\377\377\377\377\376\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\376\377\377\376" - "\377\377\377\377\377\311\377\377\2\32\32\244\220\220\272\201\201\372\177\177\277\177" - "\177\221\177\177\20\216\216\0\37\37V\377\377\377\377\377\377\377\377\376\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\375\377\377/\31\31T" - "\216\216\34\211\2114\211\211!\177\177\340\200\2006\200\200\0\200\200\0\200" - "\200Z\200\200\377\200\200Q\177\177\0\211\211\0\211\211~\203\203\377\177\177" - "\377\200\200Xhhz\377\377\372\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\350" - "\377\377""9OO\0\214\214r\177\177\377\200\200\346\177\177[\207\207\0\212\212>" - "\377\377\354\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\376\377\377\377\377\377\377\377\377\376\377\377\377\377\377\371\377\377_\377\377\0\15\15" - "\0mm6\201\201\0\201\201\0\207\207\0$$X\377\377\375\377\377\377\377\377\376\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\375\0" - "\0,\34\34\0LLm\377\377\317\377\377\0\210\210+\200\200\0\201\201\2\201\201\0\201\201" - "\35\201\201\250\200\200\37\207\207\5\377\377[\377\377\14LLD\202\202D}}#\377\377\346\0" - "\0\377\377\377\375\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\375\377\377\177\377\377\4\377\377" - "\1\202\202@\201\201\36\211\211\0\33\33.\1\1\377\377\377\377\377\377\375\377\377\376\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\260\377\377I\377\377G\377\377L\377\377A\377\377\314" - "\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\375\377\377e\377\377g\377\377\377\377\377\333\377\377\30" - "\11\11\10CC\216\377\377\370\377\377@\377\377""6\377\377\5JJ6\3\3y\377\377\377\377\377\213\377\377\16" - "aa\21\377\377\261\377\377\377\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377" - "\377\377\377\377\377\377n\377\377J\377\377G\377\377=\377\377\306\377\377\377\377\377\377\377\377\376\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\375\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\325\377\377\271\377\377\373\377\377\377\377\377\377\377\377\377" - "\377\377\253\377\377\377\377\377\377\377\377\377\377\377\377\377\377\275\377\377\277\377\377\377\377\377\375" - "\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\375\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\372\377\377\311" - "\377\377S\377\377\373\377\377\377\377\377\377\377\377\253\377\377S\377\377\373\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\354\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\376" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\376\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\376" - "\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\325\377\377\0@@\0\33\33\220\377\377" - "\377\377\377\304\377\377\24\16\16\0wwx\377\377\377\377\377\376\377\377\377\377\377_\377\377\36\377\377\320" - "\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377" - "\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376" - "\377\377\377\377\377\374\377\377""7\377\377\12CC\3\221\221&\2\2\322\377\377\10\377\377\203aa#\205" - "\205c\377\377\377\377\377\377\377\377O\377\377\3\23\23\32kk\40\377\377\326\377\377\37\377\377\201\377\377" - "\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\322\377\377\33??\252" - "\213\213P\205\205\0,,\0((JRR\377\206\206\236\203\203\0%%e**S**\0%%\257\214" - "\214\327\205\205\1RR\0((***\37\37\37\252\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377B\377\377\5\217\217\231\177\177c\177\177\0\206\206\0\206" - "\2061\203\203t\177\177q\177\177\0\206\206\0\206\206\0\206\206\0\206\206\377" - "\177\177\303\177\177\0\203\203H\206\206\344\206\206duup\26\26\377\377\377\377" - "\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\376\377\377\377\377\377\313\377\377\0oo+\201\201\0\200\200\0\200\200]\200" - "\200\325\200\200G\200\200E\200\200B\200\200\212\200\200\350\200\200]\200" - "\200\0\200\200\26\200\200\24\200\200\0\200\200a\200\200\271\200\200Pttw\36" - "\36\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\376\377\377\377\377\377\305\377\377\20\377\377F\200\200\377\200\200r\200" - "\200\233\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\275\200\200\266\200\200;\200\200" - "\6\200\200\12\200\200\0\200\200\0ss{\33\33\377\377\377\376\377\377\377\377\377\376\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\375\0" - "\0\210\377\377\1ppv\177\177\377\200\200\377\200\200\377\200\200\377\200\200\376" - "\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200c\200" - "\200Jvv\3""33\245\4\4\376\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377l\377\377\2ooy\177\177\370\200\200" - "\377\200\200\376\200\200\376\200\200\377\200\200\377\200\200\377\200\200" - "\376\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376\200\200" - "\377\200\200\377\200\200\376\200\200\377\177\177\336\200\200\12\214\214O" - "\31\31\377\377\377\376\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\376\377\377\377\377\377\265\377\377\11\17\17\10\211\211O\177\177\377\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200" - "\200\376\200\200\376\200\200\377\200\200\371\177\177g\210\210\4\21\21\333" - "\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\376\377\377\377\377\377\377\377\377\243\377\377\0\2\2\0\212\212\30\201\201b\177\177" - "\375\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\377\200\200\201\200\200\0\206\206a\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376" - "\377\377\376\377\377\377\377\377\250\377\377)\377\377\32//\0nn\16\201\201$\201\201\307\201\201" - "\312\202\202\312\200\200\312\200\200\312\200\200\312\200\200\312\200\200" - "\312\200\200\312\200\200\312\200\200\312\200\200\312\200\200\320\200\200" - "h\177\177\0\212\212\6\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\376\377\377\376\377\377\377\377\377\377\377\377" - "\320\377\377]\377\377""9II8KK)KK\0GG\0\203\203\0\206\206\0\206\206\0\206\206\0\206" - "\206\0\206\206\0\206\206\0\206\206\0\206\206\0\206\206\0\206\206\0\212\212" - "\0\\\\w\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\346\377\377\347\377\377\341\377\377\252\377\377\233$$\233''\233''\233''\233''\233''\233" - "''\233''\233''\233''\233''\234**\225\3\3\377\377\377\377\377\377\376\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377\376\377\377\376\377\377" - "\376\377\377\376\377\377\376\377\377\376\377\377\376\377\377\376\377\377\376\377\377\376\377\377\376\377\377" - "\376\377\377\376\377\377\376\377\377\376\377\377\376\377\377\376\377\377\377\377\377\376\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", - - - // second image - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377[\377\377\216QQ\222PPY\16\16\230\377\377\262\377\377\347\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377N\377\377\177jj\377\203" - "\203\354\203\203\302rr\310ll\27__\36\377\377\256\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\330\377\377Uee\375\200\200\375\200\200\376\200" - "\200\377\200\200\377\200\200\326\201\201&PP\344\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377|\377\377\242bb\376\200\200\376\200\200\377" - "\200\200\373\200\200\322\201\201EPP\212\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\332\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\234\377\377c22\212>>\201>>,::{qq\375\200\200\377\200\200\221\200\200d\200" - "\200\0\204\204'\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\334\377\377e\377\377\23CClCCb\6\6\342" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\225\377\377J//z\177\177\307\203\203\255" - "\203\203z\203\203A\200\200\371\177\177\377\200\200\250\200\200\22\200\200" - "\0\204\204\22\377\377\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\315\377\377*\377\377\202dd\202\205\205~\205\205" - "\177ppV\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\317\377\377\"\36\36\351\205\205\376\200\200" - "\376\200\200\376\200\200\375\200\200\377\200\200\375\200\200\376\200\200" - "\376\200\200\377\200\200\202\200\200\30nnA\377\377\312\377\377\347\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\354\377\377\334\377\377\335\377\377\335\377\377\336\377\377\265\377\377\12\0" - "\0\24\377\377\25\377\377\25\377\377\15\377\377k\377\377\333\377\377\335\377\377\336\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\204\377\377\277hh\375\200\200\375" - "\177\177\377\177\177\352\211\211=\1\1\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\274\5\5[\217" - "\217\376\177\177\376\200\200\377\200\200\376\200\200\376\200\200\377\200" - "\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200\377\200" - "\200\246\210\210\15\221\2217\12\12\377\377\377\377\377\377\251\377\377s\16\16%\24\24" - "\10\220\220\15\207\207\14\207\207\14\207\207g\207\207\215\207\207\212\207" - "\207\212\207\207\213\207\207\203\207\207*\207\207\14\207\207\15\210\210\3" - "]]H\13\13m\22\22\210\377\377\351\377\377\343\377\377\341\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\204\377\377\317kk\377" - "\200\200\377\200\200\344\200\200\36\211\211G\1\1\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\26\5\5\241\211\211\377\200\200\376\200\200\376\200\200\377\200\200\377\200" - "\200\251\200\200\226\200\200\261\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\376\200\200\371\205\205K88s11g110++Z}}a\210\210\350\177" - "\177\354\200\200\353\200\200\353\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\353\200\200\355\177" - "\177\276\203\203X\211\211Z\215\215\\..211\32""11\21""55\222\377\377\223\377\377\216" - "\377\377\262\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\213\377\377\205" - "kk\377\200\200\344\200\200c\200\200\15\211\211%\377\377\251\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\377\377\5\5\250\211\211\377\200\200\376\200\200\377\177\177\375\200\200\211" - "\205\205\0\211\211\0\211\211\0\211\211Z\211\211\256\212\212\377\200\200\376" - "\200\200\377\200\200\327\177\1774\204\2048\205\205\271\205\205\337\205\205" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\376\200\200\377\200\200\377\200\200\376\200\200\376\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\177\177" - "\377\205\205\317\205\205\272\205\205\275\210\210\246UUCUUMUUAUU/UU9DD\215" - "\377\377\243\377\377\346\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\245\377\377\4kk\306\200\200\324\200\200=\200\200" - "\244\202\202SVVEWW5**\311\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\244\5\5:\216\216\372\177\177\377\200\200\374" - "\200\200\233\205\205\0>>\235\10\10\303\13\13\305\13\13\205\13\13\4\2\2\224" - "\200\200\377\206\206\330\201\201%\177\1776\200\200\377\200\200\377\200\200" - "\377\200\200\376\200\200\377\200\200\376\200\200\376\200\200\377\200\200" - "\376\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200" - "\377\200\200\376\200\200\377\200\200\376\200\200\376\200\200\377\200\200" - "\377\200\200\376\200\200\377\200\200\377\200\200\377\177\177\377\200\200" - "\377\200\200\377\200\200\343\200\200\301\200\200\261~~1ss\6}}#\377\377?\377\377\266" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\271\377\377\21\0" - "\0\12jj\347\200\200\376\200\200\377\200\200\375\177\177\377\200\200\377\201" - "\201\247\202\2026\31\31G\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\336\377\377""6\33\33\235\204\204\262yy\24vv\36\377\377\247\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\210\377\377?\377\377\336\1\1A\\\\,\202\202\377" - "\200\200\376\200\200\376\200\200\377\200\200\377\200\200\376\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377" - "\200\200\377\200\200\377\200\200\376\200\200\377\200\200\376\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377" - "\200\200\377\200\200\377\200\200\352\177\177V\204\204D}}\0**n\5\5\242\4\4" - "\351\377\377\377\377\377\377\377\377\24\377\377\0cc\30jj\233\207\207\376\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\177" - "\177\252\214\214F\15\15Y\3\3\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\305\377\377""644*\11\11\264\377\377\350\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\324\6\6\15\\\\\336\202\202\377\200" - "\200\376\200\200\377\200\200\376\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\376\200\200\377\200\200\377\200\200\377\200\200\376\200\200\311\206" - "\206e\215\2155^^2\36\36t\377\377\304\377\377O99\233\204\204\341\202\202\377\177\177" - "\377\200\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200" - "\377\200\200\376\200\200\377\177\177\377\212\212\0KK\307\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377a\12" - "\12xvv\372\201\201\376\200\200\377\200\200\376\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\376\200" - "\200\377\200\200\377\200\200\377\177\177\377\202\202\244\201\201SDD\0GGt" - "``\377\200\200\377\200\200\377\177\177\317\202\202^\202\202_\202\202V\202" - "\202\322\200\200\377\177\177\376\200\200\376\200\200\377\200\200\377\177" - "\177DssP\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\266\377\377\22\6\6\377\212\212\377\177\177\377\200\200\376\200\200" - "\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200" - "\376\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200\376\200\200" - "\376\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\376\200\200\377\200\200\376\200\200\376\200\200" - "\376\200\200\377\200\200\355\202\202E\202\202\0\201\201V\177\177\377\202" - "\202q\213\213\15kk\0ff\0ff\0dd?\201\201\377\200\200\377\200\200\377\200\200" - "\377\200\200\374\200\2004pp\256\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377Z\377\377\332\210\210\377\177\177\376\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\376\200\200\376\200\200\377\200\200\376\200\200\377\200\200\376\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\376\200\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200" - "\376\200\200\377\200\200\377\200\200\376\200\200\375\200\200\375\200\200" - "\374\200\200\323\200\200\325\200\200\333\200\200\375\200\200\377\200\200" - "\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200" - "3\200\200\0\200\200\17[[\20\377\377\311\377\377\377\377\377\377\377\377\301\377\377\26\377\377@}" - "}\342\177\177\326\200\200\346\200\200\31\200\200\27oo\354\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\306\377\377@\24\24\374\205" - "\205\377\200\200\375\200\200\331\200\200\327\200\200\327\200\200\327\200" - "\200\327\200\200\330\200\200\377\200\200\377\200\200\377\200\200\376\200" - "\200\376\200\200\377\200\200\376\200\200\376\200\200\377\200\200\376\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\200" - "\200\377\200\200\377\200\200\376\200\200\333\200\200\327\200\200\305\200" - "\200o\200\200f\200\200f\200\200\0\200\200\0\200\200\0\200\200\277\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\376\200\200\375\200\200" - "\377\200\200\336\200\200\7\200\200\23\\\\\313\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\277\377\377r\377\377\0&&\0kk\0ff\0iim\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377I\377\377\202\201\201\377\177\177\377" - "\200\200\375\200\200%\200\200\16\200\200\17\200\200\17\200\200\17\200\200" - "\17\200\200\203\200\200\177\200\200\326\200\200\371\200\200\377\200\200\377" - "\200\200\376\200\200\377\200\200\376\200\200\377\200\200\376\200\200\376" - "\200\200\376\200\200\377\200\200\377\200\200\377\200\200\377\200\200\245" - "\200\200v\200\200\31\200\200\17\200\200\14\200\200\0\200\200\0\200\200\0" - "\200\200\0\200\200\0\200\200\0\200\200\224\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\200\200" - "I\200\200\15\\\\\276\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\223\377\377s\377\377u\377\377\201\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\345\377\377$\377\377tyy\377\200\200\377\200\200\377\200" - "\200\221\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200" - "\200\0\200\200\40\200\200X\200\200\244\200\200\334\200\200\377\200\200\377" - "\200\200\375\200\200\376\200\200\376\200\200\377\200\200\377\200\200\350" - "\200\200\242\200\200O\200\200.\200\200\12\200\200\0\200\200\0\200\200\0\200" - "\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200" - "\230\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376\200\200" - "\377\200\200\376\200\200\377\200\200\216\200\200\20\\\\\275\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\252" - "\377\377\32XX\341\200\200\377\200\200\376\200\200\377\200\200\261\200\200\0\200" - "\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200" - "\1\200\200\4\200\200\33\200\200\"\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\"\200\200!\200\200\3\200\200\0\200\200\0\200" - "\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200" - "\0\200\200\0\200\200\0\200\200\0\200\200\226\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200" - "\200\377\200\200\26\\\\\273\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\202\377\377\31``\355\200\200\377\200\200" - "\377\200\200\376\200\200\377\200\200J\200\200\0\200\200\0\200\200\0\200\200" - "\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0" - "\200\200\20\200\200\265\200\200\374\200\200\377\200\200\32\200\200\0\200" - "\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200" - "\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\17" - "\200\200\275\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377" - "\200\200\377\200\200\376\200\200\377\200\200\265\177\177\21SS\273\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\354" - "\377\377>>>\0\211\211\226\177\177\377\200\200\376\200\200\376\200\200\377\200" - "\200\312\200\200\0\200\200\0\200\200\15\200\200_\200\200Z\200\200=\200\200" - "\10\200\200\0\200\200\0\200\200\0\200\200\0\200\200\10\200\200\235\200\200" - "\377\200\200\377\200\200(\200\200\0\200\200\0\200\200\0\200\200\0\200\200" - "\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\3\200\200\0\200\200\0" - "\200\200\0\200\200\0\200\200\27\200\200\273\200\200\377\200\200\376\200\200" - "\376\200\200\377\200\200\376\200\200\377\200\200\377\200\200\376\200\200" - "\377\200\200Jzz!\3\3\327\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377R\16\16\0qqf\200\200\333\200\200\377" - "\200\200\376\200\200\376\200\200\372\200\200y\200\200\12\200\200\0\200\200" - "\241\200\200\324\200\200\273\200\200\213\200\200\0\200\200\0\200\200\0\200" - "\200\16\200\200\267\200\200\377\200\200\377\200\200\377\200\200\35\200\200" - "\0\200\200\0\200\200\0\200\200\0\200\200\0\200\200\16\200\200\215\200\200" - "\276\200\200\267\200\200p\200\200\15\200\200\0\200\200\0\200\200>\200\200" - "\263\200\200\377\200\200\376\200\200\377\200\200\377\200\200\376\200\200" - "\377\200\200\376\200\200\377\200\200\377\200\200\275\177\177\31\202\202w" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\340\377\377&\377\377\5\200\200\34\206\206\303\177\177\377\200" - "\200\377\200\200\377\200\200\374\200\200\313\200\200\213\200\200\0\200\200" - "\12\200\200\20\200\200\15\200\200\0\200\200\25\200\200\242\200\200\315\200" - "\200\377\200\200\375\200\200\377\200\200\346\200\200\16\200\200\0\200\200" - "\0\200\200\0\200\200\0\200\200\0\200\200\23\200\200Z\200\200_\200\200W\200" - "\200\11\200\200\0\200\200-\200\200\237\200\200\377\200\200\374\200\200\376" - "\200\200\376\200\200\377\200\200\377\200\200\377\200\200\376\200\200\377" - "\200\200\351\200\200z\200\200\23\206\206\4\10\10\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\353\377\377""7\377\377\7\11\11\0\202\202|~~\332\200\200\371\200\200\371" - "\177\177\377\200\200\377\200\200\377\200\200\277\200\200\26\200\200\305\200" - "\200\377\200\200\371\200\200\377\200\200\377\200\200\376\200\200\377\200" - "\200\376\200\200\377\200\200\370\200\200\371\200\200\265\200\200*\200\200" - "1\200\2002\200\2001\200\200.\200\200.\200\200.\200\200+\200\200\223\200\200" - "\376\200\200\377\200\200\376\200\200\376\200\200\377\200\200\377\200\200" - "\377\200\200\376\200\200\376\200\200\374\200\200\377\200\200f\200\200\0\200" - "\200\0\207\207\224\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\251" - "\377\377\210\377\377""2::\14^^]__h\202\202\263\200\200\321\200\200\377\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376\200\200\376" - "\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376" - "\200\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377" - "\200\200\377\200\200\241\200\200N\200\200\5\200\2007\200\2007\205\205\6\35" - "\35\203\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\225\377\377)\2\2\0\212\212\0\200\200\17\200\200v\200\200\225\200\200\375\200" - "\200\377\200\200\376\200\200\376\200\200\377\200\200\377\200\200\376\200" - "\200\376\200\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\200" - "\200\376\200\200\377\200\200\377\200\200\377\200\200\314\177\177w\205\205" - "\0\210\210\12\207\207\316\177\177\377\200\200\377\177\177\247\204\204\6+" - "+I\377\377\331\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\222" - "\10\10\3\211\211V\200\200Z\200\200\0\200\200\4\200\200H\200\200\216\200\200" - "\377\200\200\376\200\200\376\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\376\200\200\377\200\200\377\200\200\376\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\376\200\200\377\200\200\376\200\200\375\200\200\377\200\200\377\200\200" - "\260\200\200\224\177\177~\211\211\13\216\216\0::h\26\26\36!!\263\216\216" - "\377\177\177\377\200\200\377\200\200\266{{*oo\35\11\11\227\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\302\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377/\377\377\23\10\10*\211\211\316\200\200\373\200\200" - "\324\200\200\13\200\200\0\200\200\0\200\200m\200\200\377\200\200\377\200" - "\200\376\200\200\376\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\376\200\200\375\200" - "\200\377\200\200\245\200\200\32\200\200\11\200\200\0\203\203\377\377\0F\377\377\316" - "\377\377\377\377\377,\377\377\0++\212\206\206\374\200\200\376\200\200\377\200\200\375" - "\200\2008\200\200\5}}O\377\377\377\377\377\377\377\377\377\377\377V\377\377!\377\377\14\377\377\40\0" - "\0""4\377\377\351\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\343\377\377\320\377\377l\6\6>\20\20\225~~\377\210\210\377\177\177" - "\377\177\177\350\202\202\336\201\201\17ff\20hh\0gg\0\200\200u\200\200\321" - "\200\200\377\200\200\376\200\200\377\200\200\376\200\200\377\200\200\346" - "\200\200\377\200\200\377\200\200\370\200\200\377\200\200\376\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\373" - "\200\200\236\200\200\0\200\200\0\206\206!\30\30k\377\377\216\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377""6\34\34\0dd\216\200\200\373\177\177\377\200\200\376" - "\200\200\377\200\200\301\200\200\12ii\22\20\20\207\27\27f\27\27\0**\21\220" - "\220a\210\210l\210\2107{{1\6\6\347\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\271\377\377\223\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\262\377\377\207\377\377\"66x88\222VV\372\214\214\377\200\200\377\177" - "\177\377\200\200\260\212\2122OO#CC\205\377\377\300\377\377\"\377\377\0\200\200\0\200" - "\200[\200\200\377\200\200\377\200\200\376\200\200\377\200\200\334\200\200" - "4\200\200\207\200\200\272\200\200g\200\200\337\200\200\377\200\200\376\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\275\200" - "\200\0\200\200\0\200\200\0||\260\32\32\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\344\377\377:\377\377\0::y\202\202\377\177\177\377\200\200\376\200\200" - "\377\200\200\302\202\202A\211\211\0\210\210\0\210\210\12\207\207\246\177" - "\177\377\200\200\377\200\200\335\202\202\22TT\271\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\253\377\377$\21\21""4jj.\7\7\270\377\377\377\377\377\377\377\377\377" - "\377\377\271\377\377*\6\6""0dd>ZZ\265\202\202\373\204\204\377\202\202\342\204\204" - "\312\206\206Z\211\211#||\33""88C\377\377\301\377\377\377\377\377\377\377\377""9\377\377\0\211" - "\211*\177\177\245\200\200\340\200\200\376\200\200\377\200\200\377\200\200" - "{\200\200\0\200\200i\200\200\262\200\200\0\200\200\257\200\200\377\200\200" - "\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\373\200\200" - "H\200\200\0\200\200\0\200\200\0||B\32\32\345\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\345\377\377""6\377\377\0\215\215r\206\206\375\177\177\377" - "\200\200\376\200\200\377\200\200\377\200\200h\200\2004\200\200\250\200\200" - "\377\200\200\377\200\200\377\200\200\326\202\202\17UU\270\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\225\377\377\27\377\377\347\204\204\373\201\201g\203\203\3\0" - "\0V\377\377S\377\377""1\377\377xww\260zz\337\200\200\370\200\200\377\200\200\350\177" - "\177J\205\205#HH\3**\7\4\4\256\5\5\315\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\277\377\377\0\6\6\20\215\215\270\202\202\377\177\177\376\200\200\377\200\200" - "\351\200\200,\200\200\0\200\200\334\200\200\252\200\200\0\200\200\256\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\370\200\200\"\200\200\0\200\200/\177\1774\211\211\0!!\226\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377""0\6\6\0))\204" - "\210\210\374\177\177\375\200\200\376\200\200\377\200\200\370\200\200\377" - "\200\200\347\200\200O\200\200S\177\177U\204\204#uu=\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377:\377\377\370\212\212\377\177\177\376\200\200\377\177\177" - "\377\206\206)\206\2063\206\206d\207\207\377\200\200\377\200\200\375\200\200" - "\370\200\200a\200\200\0ss\20EE2\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\267\377\377)\377\377\0""99\213\203\203\375\200" - "\200\377\200\200\376\200\200\373\200\200\374\200\200\377\200\200\265\200" - "\200e\200\200\377\200\200\376\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\376\200\200\376\200\200\377\200\200^\177\177\334\201\201'99" - "I\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\266\377\377\0==\233\201\201\373\177\177\377\200\200\376\200\200" - "\377\200\200\270\200\200\0\200\200\0\200\200\0\207\207\11\377\377M\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\240\377\377h99\377\201\201\376\200\200\376" - "\200\200\376\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376" - "\200\200\372\200\200\244\200\200H\200\200\0\204\204K\377\377\312\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377A==H\203\203\370\200\200\377\200\200\376\200\200\377\200" - "\200\377\200\200\375\200\200\377\200\200\377\200\200\377\200\200\376\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\376\200\200\377\200" - "\200\377\177\177\327\205\205*>>O\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\240\377\377\0AA" - "\205\200\200\373\200\200\377\200\200\377\200\200\345\200\200\213\200\200" - "\0\204\204\0OO\245\2\2\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377G." - ".\234\177\177\377\177\177\376\200\200\376\200\200\376\200\200\374\200\200" - "\352\200\200\373\200\200\377\200\200\376\200\200\372\200\200\211\200\200" - "\0\200\200\0\204\204\355\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377k==\213\203\203" - "\377\200\200\376\200\200\377\200\200\377\200\200\377\200\200\376\200\200" - "\377\200\200\377\200\200\375\200\200\377\200\200\376\200\200\377\200\200" - "\377\200\200\376\200\200\377\200\200\377\200\200{\205\205\31//F\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\257\377\377\0\201\201\341\200\200\377\200" - "\200\376\200\200\377\200\200\336\200\200\0\207\207I\36\36\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\262\377\377\0PP\246\201\201\377\200\200\377" - "\200\200\377\200\200\377\200\200\373\200\200\"\200\200\332\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200:\200\200\0\204\204\223\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\346\377\377""2==M\203\203\241\200\200\377\200\200\377\200" - "\200\227\200\200\371\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\376\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\210\200\200\0\211\211\377\377\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\233\377\377""2\201\201\377\200\200\377\200\200\377\200\200\376\200\200" - "\376\200\200s\207\207z!!\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377NFF\3{{\344\200\200\377\200\200\377\177\177\377\200\2005\200\200" - "\33\200\200\330\200\200\377\200\200\377\200\200\376\200\200\377\200\200\333" - "\200\200\15\204\204'\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\312\377\377\0==\0\203\203\0" - "\200\200\220\200\200$\200\200\2\200\200\26\200\200o\200\200=\200\200K\200" - "\200\331\200\200\376\200\200\377\200\200\344\200\200\344\200\200\344\200" - "\200\377\177\177~\200\200\0\204\204\266\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\246\377\377\2\377\377\204\201\201\377\200\200\376\200\200\376\200\200" - "\377\200\200\331\200\200\0\204\204~\40\40\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\255\377\377B\377\377\22bb#iiA\205\205\207\203\203\16\203" - "\203\36\203\203\330\177\177\377\200\200\377\200\200\376\200\200\376\200\200" - "\377\200\200t\204\204%\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\262\377\377<::\211\203\203" - "O\200\200\0\200\200F\200\200\214\200\200\21\200\200\0\200\200Q\200\200\40" - "\200\200\0\200\200\233\200\200\244\200\200\12\200\200\30\200\200\27\200\200" - "\37\200\2006uu\31\11\11\343\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\210" - "\377\377\31ss\377\177\177\376\200\200\376\200\200\377\200\200\372\177\177\201" - "\177\177\0--\246\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\311\377\377l\12\12q??v<<\12<<\37JJ\336\204\204\377\200\200" - "\377\200\200\377\200\200\377\200\200\241\177\177\22\214\214$\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377A\14\14~dd\255\201\201+\200\200\30\200\200\377\200\200\345" - "\200\200\31\200\200\11\200\200\232\200\200\354\200\200A\200\200\0\200\200" - "\31\200\200\211\200\200\341\200\200\331\200\200f\203\203\0""88\226\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\355\377\377H\"\"\20ww\377\200\200\377\200" - "\200\377\200\200\377\200\200k\200\200\0++L\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\311\377\377\2\32\32\244\220\220\272\201\201\372\177\177\277\177" - "\177\221\177\177\20\216\216\0\37\37V\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377-\31\31\16" - "\212\212\6\177\177\0\200\200$\200\200\340\200\2007\200\200\0\200\200\0\200" - "\200Z\200\200\377\200\200R\200\200\0\200\200\0\200\200(\200\200\335\200\200" - "\377\200\200O\203\203H==\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\350\377\377""9OO\0\214\214r\177\177\377\200\200\346\177\177[\207\207\0\212\212" - ">\377\377\354\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377_\377\377\0\15\15" - "\0mm6\201\201\0\201\201\0\207\207\0$$X\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" - "\0.\31\31\0\210\210\0\200\200\0\200\200\13\200\200+\200\200\0\200\200\235" - "\200\200\0\200\200\31\200\200R\200\200\27\200\200\0\200\200\1\200\200\0\200" - "\200(\200\200D\200\200\0\203\203\4==\323\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\177\377\377\4\377\377\1\202\202@\201\201\36\211\211\0\33\33" - ".\1\1\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\260\377\377I\377\377G\377\377L\377\377A\377\377\314\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377,\31\31B\210\210\203\200\200\4\200\200\0\200\200\0\200\200\217\200" - "\200\374\200\200!\200\200\0\200\200\0\200\200\0\200\200\31\200\200\332\200" - "\200m\200\200\0\200\200\0\200\200\17\203\203\7==\324\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377n\377\377J\377\377G\377\377=\377\377\306\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\341\377\377\31\23\23>\210\210\373\200\200\22\200\200\0\200\200\12" - "\200\200\215\200\200\254\200\200g\200\200\0\200\200\0\200\200\0\200\200L" - "\200\200\377\200\200j\200\200\0\200\200[\200\200\244\203\203\26==\323\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\225\377\377\0hh\13\202\2021\200\200" - "\0\200\200}\200\200r\200\200\25\200\200\36\200\200\"\200\200\241\200\200" - "\216\200\200\4\200\200\13\200\200N\200\200\37\200\200\0\200\200\326\200\200" - "\311\203\203\32==\322\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\240\377\377\7\377\377\201" - "\211\211\232\177\177K\200\200\221\200\200\377\200\200\372\200\200\377\200" - "\200\377\200\200\377\200\200\376\200\200\377\200\200\236\200\200{\200\200" - "[\200\200\0\200\200\0\200\200\4\200\200\11\203\203\7==\331\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377""9\377\377\2\206\206\326\177\177\376\200\200\373\200\200" - "\377\200\200\376\200\200\376\200\200\377\200\200\377\200\200\377\200\200" - "\376\200\200\376\200\200\377\200\200\377\200\200\374\200\200\346\200\200" - "\350\200\200\323\200\200\26\203\203\14CCP\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\267" - "\377\377\20\377\377\"\205\205\311\177\177\377\200\200\377\200\200\375\200\200\377" - "\200\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377" - "\200\200\377\200\200\376\200\200\377\200\200\377\200\200\377\200\200\377" - "\200\200\377\177\177\203\213\213\0??\313\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377""7\0" - "\0\12""221\205\205\304\200\200\377\200\200\377\200\200\376\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\376\200" - "\200\377\200\200\377\200\200\377\200\200\376\200\200\377\200\200\377\200" - "\200\303\177\177\17\216\216\\\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\352\377\377$\377\377\0\221" - "\221\11\204\204z\200\200\305\177\177\377\200\200\377\200\200\376\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200" - "\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\372\200\200" - "*\211\211\2\377\377\331\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\352\377\377$\377\377\4//\0zz\7||D\200" - "\200\220\200\200\371\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200\200\377\200" - "\200\377\200\200\377\200\200(\200\200\0\177\177W\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\344\377\377r\377\377\30\377\377\21hh\23bb\6__\0\201\201\0\203\203" - "\0\203\203\0\203\203\0\203\203\0\203\203\0\203\203\0\203\203\0\203\203\0" - "\203\203\0\203\203\0\203\203\0\215\215\377\377\0\230\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\303\377\377\300\377\377\304\377\377\226\377\377c::a" - ">>a>>a>>a>>a>>a>>a>>a>>a>>a>>a>>bCCe\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377" - }; - diff -r a5496987b1da -r 189ece41fa29 bsptemplate/asspandvariant/template_variant/camerasctemplate.mmp --- a/bsptemplate/asspandvariant/template_variant/camerasctemplate.mmp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -// Copyright (c) 2006-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: -// template/template_variant/camerasctemplate.mmp -// soundsc.pdd Template shared chunk camera PDD -// -// - -/** - @file -*/ -#define __USING_ASSP_REGISTER_API__ -#define __USING_ASSP_INTERRUPT_API__ - -#include -#include "kernel/kern_ext.mmh" - -#if defined(WINS) || defined(WINSCW) -TARGET _template_camerasc.pdd -#else -// -// This will generate a file '_template_camerasc.pdd' -TARGET VariantTarget(camerasc,pdd) -#endif - -TARGETTYPE pdd -ROMTARGET camerasc.pdd - -OS_LAYER_SYSTEMINCLUDE_SYMBIAN -USERINCLUDE camerasc - -SOURCEPATH camerasc -SOURCE camerasc.cpp -SOURCE camerasc_sensor.cpp -SOURCE logoyuv2.cpp - -UID 0x100039d0 0x100039eb -VENDORID 0x70000001 - -CAPABILITY all - -SMPSAFE diff -r a5496987b1da -r 189ece41fa29 bsptemplate/asspandvariant/template_variant/rom/base_template.iby --- a/bsptemplate/asspandvariant/template_variant/rom/base_template.iby Thu Jul 01 17:57:33 2010 +0100 +++ b/bsptemplate/asspandvariant/template_variant/rom/base_template.iby Fri Jul 09 13:13:20 2010 +0100 @@ -62,8 +62,6 @@ device[VARID] =KERNEL_DIR\DEBUG_DIR\pipelib.ldd \sys\bin\pipelib.ldd device[VARID] =KERNEL_DIR\DEBUG_DIR\minkda.ldd \sys\bin\minkda.ldd extension[VARID]=KERNEL_DIR\DEBUG_DIR\exstart.dll \sys\bin\exstart.dll -device[VARID] =KERNEL_DIR\DEBUG_DIR\ecamerasc.ldd \sys\bin\ecamerasc.ldd -device[VARID] =KERNEL_DIR\DEBUG_DIR\_template_camerasc.pdd \sys\bin\camerasc.pdd // USB Drivers extension[VARID]=KERNEL_DIR\DEBUG_DIR\_template_usbcc.dll \sys\bin\usbcc.dll diff -r a5496987b1da -r 189ece41fa29 bsptemplate/asspandvariant/template_variant/rom/kernel.iby --- a/bsptemplate/asspandvariant/template_variant/rom/kernel.iby Thu Jul 01 17:57:33 2010 +0100 +++ b/bsptemplate/asspandvariant/template_variant/rom/kernel.iby Fri Jul 09 13:13:20 2010 +0100 @@ -66,8 +66,6 @@ device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\PIPELIB.LDD \sys\bin\pipelib.ldd device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\ESOUNDSC.LDD \sys\bin\esoundsc.ldd extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\EXSTART.DLL \sys\bin\exstart.dll -device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\ECAMERASC.LDD \sys\bin\ecamerasc.ldd -device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_CAMERASC.PDD \sys\bin\camerasc.pdd // USB Client device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\USBC.LDD \sys\bin\EUSBC.LDD diff -r a5496987b1da -r 189ece41fa29 build.config.xml --- a/build.config.xml Thu Jul 01 17:57:33 2010 +0100 +++ b/build.config.xml Fri Jul 09 13:13:20 2010 +0100 @@ -103,7 +103,6 @@ - @@ -187,7 +186,7 @@ - + @@ -260,17 +259,18 @@ - --> + - - @@ -278,13 +278,10 @@ - - - - \ No newline at end of file + diff -r a5496987b1da -r 189ece41fa29 kernel/eka/bld.inf --- a/kernel/eka/bld.inf Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/bld.inf Fri Jul 09 13:13:20 2010 +0100 @@ -41,7 +41,6 @@ #include "drivers/media/bld.inf" #include "drivers/trace/bld.inf" #include "drivers/usbc/bld.inf" -#include "drivers/camerasc/bld.inf" #include "drivers/display/bld.inf" #include "euser/bld.inf" #include "ewsrv/bld.inf" @@ -242,9 +241,6 @@ include/drivers/usbdi_hub.h drivers/ // include/drivers/usbdi_channel.h drivers/ // -include/drivers/camerasc.h drivers/ // -include/drivers/camerasc.inl drivers/ // - include/drivers/otgdi.h drivers/ include/drivers/crashflash.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(drivers/) @@ -365,8 +361,6 @@ include/d32usbdi_hubdriver.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(d32usbdi_hubdriver.inl) include/d32usbtransfers.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(d32usbtransfers.h) include/d32usbdescriptors.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(d32usbdescriptors.h) -include/d32camerasc.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(d32camerasc.h) -include/d32camerasc.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(d32camerasc.inl) include/d32otgdi.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(d32otgdi.h) include/d32otgdi.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(d32otgdi.inl) include/d32otgdi_errors.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(d32otgdi_errors.h) diff -r a5496987b1da -r 189ece41fa29 kernel/eka/bmarm/usbcscu.def --- a/kernel/eka/bmarm/usbcscu.def Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/bmarm/usbcscu.def Fri Jul 09 13:13:20 2010 +0100 @@ -18,4 +18,5 @@ Expire__15TEndpointBuffer @ 17 NONAME R3UNUSED ; TEndpointBuffer::Expire(void) TakeBuffer__15TEndpointBufferRPvRUiRiR14TRequestStatusUi @ 18 NONAME ; TEndpointBuffer::TakeBuffer(void *&, unsigned int &, int &, TRequestStatus &, unsigned int) Expire__15TEndpointBufferPv @ 19 NONAME R3UNUSED ; TEndpointBuffer::Expire(void *) + ResetAltSetting__16RDevUsbcScClient @ 20 NONAME R3UNUSED ; RDevUsbcScClient::ResetAltSetting(void) diff -r a5496987b1da -r 189ece41fa29 kernel/eka/drivers/camerasc/base_drivers_camerasc.mrp --- a/kernel/eka/drivers/camerasc/base_drivers_camerasc.mrp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -# component name "Camera Driver - Shared Chunk" - -component base_drivers_camerasc - -source \sf\os\kernelhwsrv\kernel\eka\drivers\camerasc -exports \sf\os\kernelhwsrv\kernel\eka\drivers\camerasc -binary \sf\os\kernelhwsrv\kernel\eka\drivers\camerasc all - -notes_source \component_defs\release.src - - - -ipr E \ No newline at end of file diff -r a5496987b1da -r 189ece41fa29 kernel/eka/drivers/camerasc/bld.inf --- a/kernel/eka/drivers/camerasc/bld.inf Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -// Copyright (c) 1998-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: -// e32/drivers/camerasc/bld.inf -// Shared Chunk Camera driver LDD -// -// - -/** - @file -*/ - -#include - -PRJ_PLATFORMS - -BASEDEFAULT - -PRJ_EXPORTS - -PRJ_MMPFILES - -#if !defined(WINS) || !defined(WINSCW) -ecamerasc -#endif diff -r a5496987b1da -r 189ece41fa29 kernel/eka/drivers/camerasc/cameraldd.cpp --- a/kernel/eka/drivers/camerasc/cameraldd.cpp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2223 +0,0 @@ -// Copyright (c) 2008-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: -// e32/drivers/camerasc/cameraldd.cpp -// -// - -#include -#include -#include - -//#define __KTRACE_CAM(s) s; -#define __KTRACE_CAM(s) - -#define DISCARD_COMPLETED_TO_AVOID_OVERFLOW - -static const char KCameraLddPanic[]="CameraSc LDD"; - -/** -Standard export function for LDDs. This creates a DLogicalDevice derived object, -in this case, DSoundScLddFactory. -*/ -DECLARE_STANDARD_LDD() - { - return new DCameraScLddFactory; - } - -/** -Constructor for the camera driver factory class. -*/ -DCameraScLddFactory::DCameraScLddFactory() - { -// iUnitsOpenMask=0; - - __KTRACE_CAM(Kern::Printf(">DCameraScLddFactory::DCameraScLddFactory")); - - // Set version number for this device. - iVersion=RDevCameraSc::VersionRequired(); - - // Indicate that units / PDD are supported. - iParseMask=KDeviceAllowUnit|KDeviceAllowPhysicalDevice; - - // Leave the units decision to the PDD - iUnitsMask=0xffffffff; - } - -/** -Second stage constructor for the camera driver factory class. -This must at least set a name for the driver object. -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DCameraScLddFactory::Install() - { - return(SetName(&KDevCameraScName)); - } - -/** -Return the 'capabilities' of the camera driver in general. -Called in the response to an RDevice::GetCaps() request. -@param aDes A user-side descriptor to write the capabilities information into. -*/ -void DCameraScLddFactory::GetCaps(TDes8 &aDes) const - { - // Create a capabilities object - TCapsDevCameraV01 caps; - caps.iVersion=iVersion; - - // Write it back to user memory - Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps)); - } - -/** -Called by the kernel's device driver framework to create a logical channel. -This is called in the context of the client thread which requested the creation of a logical -channel - through a call to RBusLogicalChannel::DoCreate(). -The thread is in a critical section. -@param aChannel Set by this function to point to the created logical channel. -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DCameraScLddFactory::Create(DLogicalChannelBase*& aChannel) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLddFactory::Create")); - - aChannel=new DCameraScLdd; - if (!aChannel) - return(KErrNoMemory); - - return(KErrNone); - } - -/** -Check whether a channel has is currently open on the specified unit. -@param aUnit The number of the unit to be checked. -@return ETrue if a channel is open on the specified channel, EFalse otherwise. -@pre The unit info. mutex must be held. -*/ -TBool DCameraScLddFactory::IsUnitOpen(TInt aUnit) - { - return(iUnitsOpenMask&(1<DCameraScLdd::DCameraScLdd")); - - iUnit=-1; // Invalid unit number - - // Get pointer to client thread's DThread object - iOwningThread=&Kern::CurrentThread(); - - // Open a reference on client thread so it's control block can't dissapear until - // this driver has finished with it. Note, this call to Open() can't fail since - // it is the thread we are currently running in - iOwningThread->Open(); - } - -/** -Destructor for the camera driver logical channel. -This is called in the context of the client thread once a 'ECloseMsg' message has been -sent to the device driver DFC thread. -*/ -DCameraScLdd::~DCameraScLdd() - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::~DCameraScLdd")); - - TInt captureMode; - - // Remove and delete the power handler. - if (iPowerHandler) - { - iPowerHandler->Remove(); - delete iPowerHandler; - } - - if (iCaptureModeConfig) - { - // Delete any buffers and shared chunk we created. - for (captureMode=0; captureMode < ECamCaptureModeMax; captureMode++) - { - if (iCaptureModeConfig[captureMode].iBufManager) - delete iCaptureModeConfig[captureMode].iBufManager; - } - - // Delete the buffer config. info. structure. - for (captureMode=0; captureMode < ECamCaptureModeMax; captureMode++) - { - if (iCaptureModeConfig[captureMode].iBufConfig) - Kern::Free(iCaptureModeConfig[captureMode].iBufConfig); - } - - if (iCaptureModeConfig) - delete[] iCaptureModeConfig; - } - // Close our reference on the client thread - Kern::SafeClose((DObject*&)iOwningThread,NULL); - - // Clear the 'units open mask' in the LDD factory. - if (iUnit>=0) - ((DCameraScLddFactory*)iDevice)->SetUnitOpen(iUnit,EFalse); - } - -/** -Second stage constructor for the camera driver - called by the kernel's device driver framework. -This is called in the context of the client thread which requested the creation of a logical channel -(e.g. through a call to RBusLogicalChannel::DoCreate()). -The thread is in a critical section. -@param aUnit The unit argument supplied by the client. This is checked by the PDD and not used here. -@param aInfo The info argument supplied by the client. Always NULL in this case. -@param aVer The version argument supplied by the client. -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DCameraScLdd::DoCreate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& aVer) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DoCreate")); - - // Check the client has EMultimediaDD capability. - if (!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by ECAMERA.LDD (Camera driver)"))) - return(KErrPermissionDenied); - - // Check that the camera driver version specified by the client is compatible. - if (!Kern::QueryVersionSupported(RDevCameraSc::VersionRequired(),aVer)) - return(KErrNotSupported); - - // Check that a channel hasn't already been opened on this unit. - TInt r=((DCameraScLddFactory*)iDevice)->SetUnitOpen(aUnit,ETrue); // Try to update 'units open mask' in the LDD factory. - if (r!=KErrNone) - return(r); - iUnit=aUnit; - - // Create the power handler - iPowerHandler=new DCameraScPowerHandler(this); - if (!iPowerHandler) - return(KErrNoMemory); - iPowerHandler->Add(); - - // Create the pending capture request list - r=iRequestQueue.Create(iOwningThread); - if (r!=KErrNone) - return(r); - - // Initialise the PDD - ((DCameraScPdd*)iPdd)->iLdd=this; - - // Setup the default camera config - iCaptureMode=ECamCaptureModeImage; - - iCaptureModeConfig = new TCaptureModeConfig[ECamCaptureModeMax]; - if(!iCaptureModeConfig) - return KErrNoMemory; - TInt capsSize = Pdd()->CapsSize(); - TInt captureMode; - TAny* capsBuf; - capsBuf = Kern::Alloc(capsSize); - if(!capsBuf) - return KErrNoMemory; - - // Query the driver for its capabilities and set a default pixel format - // and frame size for each available capture mode. - TPtr8 capsPtr( (TUint8*)capsBuf, capsSize, capsSize ); - Pdd()->Caps(capsPtr); - - TCameraCapsV02* caps = (TCameraCapsV02*) capsPtr.Ptr(); - SDevCamPixelFormat* pixelFormat = (SDevCamPixelFormat*) (caps + 1); - SDevCamFrameSize* frameSize; - TAny* frameSizeCapsBuf=0; - TPtr8 frameSizeCapsPtr(0,0,0); - - // Set the cache to hold the default dynamic attribute values. - iBrightnessValue = caps->iDynamicRange[ECamAttributeBrightness].iDefault; - iContrastValue = caps->iDynamicRange[ECamAttributeContrast].iDefault; - iColorEffectValue = caps->iDynamicRange[ECamAttributeColorEffect].iDefault; - - for (captureMode=0; captureMode < ECamCaptureModeMax; captureMode++) - { - if ((captureMode==ECamCaptureModeImage) && (caps->iNumImagePixelFormats==0)) - continue; - - if ((captureMode==ECamCaptureModeVideo) && (caps->iNumVideoPixelFormats==0)) - continue; - - if ((captureMode==ECamCaptureModeViewFinder) && (caps->iNumViewFinderPixelFormats==0)) - continue; - - iCaptureModeConfig[captureMode].iCamConfig.iPixelFormat=*pixelFormat; - frameSizeCapsBuf = Kern::Alloc(pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize)); - new (&frameSizeCapsPtr) TPtr8((TUint8*)frameSizeCapsBuf, pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize), pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize)); - r=Pdd()->FrameSizeCaps((TDevCamCaptureMode)captureMode, pixelFormat->iPixelFormat, frameSizeCapsPtr); - if(r!=KErrNone) - { - Kern::Free(frameSizeCapsBuf); - return r; - } - frameSize=(SDevCamFrameSize*) frameSizeCapsPtr.Ptr(); - iCaptureModeConfig[captureMode].iCamConfig.iFrameSize = *frameSize; - iCaptureModeConfig[captureMode].iCamConfig.iFrameRate = frameSize->iMinFrameRate; - Kern::Free(frameSizeCapsBuf); - - iCaptureModeConfig[captureMode].iCamConfig.iFlashMode = ECamFlashNone; - iCaptureModeConfig[captureMode].iCamConfig.iExposureMode = ECamExposureAuto; - iCaptureModeConfig[captureMode].iCamConfig.iWhiteBalanceMode = ECamWBAuto; - iCaptureModeConfig[captureMode].iCamConfig.iZoom = 0; - iCaptureModeConfig[captureMode].iCamConfig.iPixelWidthInBytes = 0; - } - Kern::Free(capsBuf); - // Setup the default buffer config. - r=ReAllocBufferConfigInfo(0); // Zeros the structure - if (r!=KErrNone) - return(r); - for (captureMode=0; captureMode < ECamCaptureModeMax; captureMode++) - { - iCaptureModeConfig[captureMode].iBufConfig->iNumBuffers=KDefaultNumClientBuffers; - } - - // Set up the correct DFC queue and enable the reception of client messages. - TDfcQue* dfcq=((DCameraScPdd*)iPdd)->DfcQ(aUnit); - SetDfcQ(dfcq); - iRestartDfc.SetDfcQ(dfcq); - iPowerDownDfc.SetDfcQ(dfcq); - iPowerUpDfc.SetDfcQ(dfcq); - iMsgQ.Receive(); - - __KTRACE_CAM(Kern::Printf("DCameraScLdd::Shutdown")); - - iState=EOpen; - - // Power down the hardware - Pdd()->PowerDown(); - - // Cancel any requests that we may be handling - DoCancel(RDevCameraSc::EAllRequests); - - // Make sure DFCs are not queued. - iRestartDfc.Cancel(); - iPowerDownDfc.Cancel(); - iPowerUpDfc.Cancel(); - } - -/** -Notification to the driver that a handle to it has been requested by a user thread. -The use of a camera driver channel is restricted here to a single thread (that has -EMultimediaDD capability). -@param aThread A pointer to thread which is requesting the handle. -@param aType Whether the requested handle is thread or process relative. -@return KErrNone, if the request is for a thread relative handle - originating from - the same the thread that created the channel object; - KErrAccessDenied, otherwise. -*/ -TInt DCameraScLdd::RequestUserHandle(DThread* aThread, TOwnerType aType) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::RequestUserHandle")); - - // Ensure that each channel can only be used by a single thread. - if (aType!=EOwnerThread || aThread!=iOwningThread) - return(KErrAccessDenied); - return(KErrNone); - } - -/** -Process a request on this logical channel -Called in the context of the client thread. -@param aReqNo The request number: - ==KMaxTInt: a 'DoCancel' message; - >=0: a 'DoControl' message with function number equal to value. - <0: a 'DoRequest' message with function number equal to ~value. -@param a1 The first request argument. For DoRequest(), this is a pointer to the TRequestStatus. -@param a2 The second request argument. For DoRequest(), this is a pointer to the 2 actual TAny* arguments. -@return The result of the request. This is ignored by device driver framework for DoRequest(). -*/ -TInt DCameraScLdd::Request(TInt aReqNo, TAny* a1, TAny* a2) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::Request(%d)",aReqNo)); - TInt r; - if (aReqNo(~RDevCameraSc::EMsgRequestMax)) - { - // Implement in the context of the kernel thread - prepare and issue a kernel message. - r=DLogicalChannel::Request(aReqNo,a1,a2); - } - else - { - // Implement in the context of the client thread. - // Decode the message type and dispatch it to the relevent handler function. - if ((TUint)aReqNo<(TUint)KMaxTInt) - r=DoControl(aReqNo,a1,a2); // DoControl - process the request. - - else if (aReqNo==KMaxTInt) - { - r=DoCancel((TInt)a1); // DoCancel - cancel the request. - } - - else - { - // DoRequest - TInt func=~aReqNo; - - // NotifyNewImage() during image capture mode is another case which must be handled in the kernel thread. - if (iCaptureMode==ECamCaptureModeImage && func==RDevCameraSc::ERequestNotifyNewImage) - r=DLogicalChannel::Request(aReqNo,a1,a2); - else - { - // Read the arguments from the client thread and process the request. - TAny* a[2]; - kumemget32(a,a2,sizeof(a)); - TRequestStatus* status=(TRequestStatus*)a1; - r=DoRequest(func,status,a[0],a[1]); - - // Complete request if there was an error - if (r!=KErrNone) - Kern::RequestComplete(iOwningThread,status,r); - r=KErrNone; - } - } - } - __KTRACE_CAM(Kern::Printf("=0, a 'DoControl' message with function number equal to iValue. - iValue<0, a 'DoRequest' message with function number equal to ~iValue. -*/ -void DCameraScLdd::HandleMsg(TMessageBase* aMsg) - { - TThreadMessage& m=*(TThreadMessage*)aMsg; - TInt id=m.iValue; - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::HandleMsg(%d)",id)); - - // Decode the message type and dispatch it to the relevent handler function. - if (id==(TInt)ECloseMsg) - { - // Channel close. - Shutdown(); - m.Complete(KErrNone,EFalse); - return; - } - else if (id<0) // The only DoRequest handled in the kernel thread is NotifyNewImage(ECamCaptureModeImage). - { - // DoRequest - TRequestStatus* pS=(TRequestStatus*)m.Ptr0(); - TInt r=DoRequest(~id,pS,m.Ptr1(),m.Ptr2()); - if (r!=KErrNone) - Kern::RequestComplete(iOwningThread,pS,r); - m.Complete(KErrNone,ETrue); - } - else - { - // Must be DoControl (Cancel is handled in the client thread). - TInt r=DoControl(id,m.Ptr0(),m.Ptr1()); - m.Complete(r,ETrue); - } - } - -/** -Process a synchronous 'DoControl' request. -This function is called in the context of the DFC thread. -@param aFunction The request number. -@param a1 The first request argument. -@param a2 The second request argument. -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DCameraScLdd::DoControl(TInt aFunction, TAny* a1, TAny* a2) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DoControl(%d)",aFunction)); - - TInt r=KErrNotSupported; - switch (aFunction) - { - case RDevCameraSc::EControlCaps: - { - r = GetSensorCaps(a1); - break; - } - case RDevCameraSc::EControlSetCaptureMode: - { - // Change the capture mode. - r=SetCaptureMode((TInt)a1); - break; - } - case RDevCameraSc::EControlSetCamConfig: - { - // Set the new camera configuration. - NKern::ThreadEnterCS(); - r=SetCamConfig((TInt)a1, (const TDesC8*)a2); - NKern::ThreadLeaveCS(); - break; - } - case RDevCameraSc::EControlGetCamConfig: - { - // Write the config to the client. - TPtrC8 ptr((const TUint8*)&iCaptureModeConfig[(TInt)a1].iCamConfig,sizeof(iCaptureModeConfig[(TInt)a1].iCamConfig)); - Kern::InfoCopy(*((TDes8*)a2),ptr); - r=KErrNone; - break; - } - case RDevCameraSc::EControlGetBufferConfig: - if (iCaptureModeConfig[(TInt)a1].iBufConfig) - { - // Write the buffer config to the client. - TPtrC8 ptr((const TUint8*)&(*iCaptureModeConfig[(TInt)a1].iBufConfig),iCaptureModeConfig[(TInt)a1].iBufConfigSize); - Kern::InfoCopy(*((TDes8*)a2),ptr); - r=KErrNone; - } - break; - case RDevCameraSc::EControlSetBufConfigChunkCreate: - // Need to be in critical section while deleting an exisiting config and creating a new one - NKern::ThreadEnterCS(); - r=SetBufConfig((TInt)a1,(TInt)a2); - NKern::ThreadLeaveCS(); - break; - case RDevCameraSc::EControlSetBufConfigChunkOpen: - SSetBufConfigChunkOpenInfo info; - r=Kern::ThreadRawRead(iOwningThread,a2,&info,sizeof(info)); - if (r==KErrNone) - { - // Need to be in critical section while deleting an exisiting config and creating a new one - NKern::ThreadEnterCS(); - r=SetBufConfig((TInt)a1,info.iBufferConfigBuf,info.iChunkHandle); - NKern::ThreadLeaveCS(); - } - break; - case RDevCameraSc::EControlChunkClose: - r=ChunkClose((TInt)a1); - break; - case RDevCameraSc::EControlStart: - r=Start(); - break; - case RDevCameraSc::EControlStop: - if (iState==ECapturing) - { - r=Pdd()->Stop(); - DoCancel(1<iImageBuffer[id].iId == id) - { - kumemput32(a2, &mgr->iImageBuffer[id].iChunkOffset, sizeof(TInt)); - r = KErrNone; - } - } - } - - break; - } - case RDevCameraSc::EControlCapsSize: - { - r = Pdd()->CapsSize(); - break; - } - case RDevCameraSc::EControlFrameSizeCaps: - { - r = GetFrameSizeCaps(a1, a2); - break; - } - - case RDevCameraSc::EControlSetDynamicAttribute: - { - NKern::ThreadEnterCS(); - r = SetDynamicAttribute((TInt)a1, (TUint)a2); - NKern::ThreadLeaveCS(); - break; - } - - case RDevCameraSc::EControlGetDynamicAttribute: - { - TInt attribute = (TInt)(a1); - TUint value = 0; - - r = GetDynamicAttribute(attribute, value); - if (r == KErrNone) - { - kumemput32(a2, &value, sizeof(TUint)); - } - - break; - } - - } - return(r); - } - -/** -Process an asynchronous 'DoRequest' request. -This function is called in the context of the DFC thread. -@param aFunction The request number. -@param aStatus A pointer to the TRequestStatus. -@param a1 The first request argument. -@param a2 The second request argument. -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DCameraScLdd::DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* /*a1*/, TAny* /*a2*/) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DoRequest(%d)",aFunction)); - - TInt r=KErrNotSupported; - switch (aFunction) - { - case RDevCameraSc::ERequestNotifyNewImage: - r=NotifyNewImage(aStatus); - break; - } - - __KTRACE_CAM(Kern::Printf("DCameraScLdd::DoCancel(%08x)",aMask)); - - if (aMask&(1<0), if successful; - otherwise one of the other system wide error codes, (a value <0). -@param aCamConfigBuf The supplied camera configuration. -@pre The thread must be in a critical section. -*/ -TInt DCameraScLdd::SetCamConfig(TInt aCaptureMode, const TDesC8* aCamConfigBuf) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::SetCamConfig()")); - - // Set the configuration of the sensor - TInt r=DoSetConfig(aCaptureMode, aCamConfigBuf); - return(r); - } - -/** -Allows changing of the dynamic settings. -Checks locally the validity of the arguments passed so as to increase performance by not -forcing a context switch. - -If the setting has been accepted by the sensor the new value is cached by the LDD so further -querying does not involve another context switch. - -@param aAttribute An enum identifying the dynamic attribute to change. -@param aValue The attributes value. -@return KErrNone if successful, KErrNotSupported if not supported, KErrArgument if aValue out of range. - Otherwise, one of the system wide error codes. -@pre The thread must be in a critical section. -*/ -TInt DCameraScLdd::SetDynamicAttribute(TInt aAttribute, TUint aValue) - { - TUint* attrCachePtr = NULL; - TInt err = KErrNotSupported; - - switch (aAttribute) - { - case ECamAttributeBrightness: - err = Pdd()->SetBrightness(aValue); - attrCachePtr = &iBrightnessValue; - break; - - case ECamAttributeContrast: - err = Pdd()->SetContrast(aValue); - attrCachePtr = &iContrastValue; - break; - - case ECamAttributeColorEffect: - err = Pdd()->SetColorEffect(aValue); - attrCachePtr = &iColorEffectValue; - break; - - default: - return err; - } - - if (err == KErrNone) - { - // Cache the set value. - __ASSERT_DEBUG(attrCachePtr, Kern::Fault(KCameraLddPanic, __LINE__)); - *attrCachePtr = aValue; - } - - return err; - } - - -/** -Allows querying of a dynamic setting. -The value is read from the cached LDD values. - -@param aAttribute An enum identifying the dynamic attribute to change. -@param aValue A reference to a variable that will receive the attribute value. -@return KErrNone if successful, KErrNotFound if aAttribute is an unsupported - setting. The parameter aValue is not changed if this function fails. -*/ -TInt DCameraScLdd::GetDynamicAttribute(TInt aAttribute, TUint& aValue) - { - switch (aAttribute) - { - case ECamAttributeBrightness: - aValue = iBrightnessValue; - break; - - case ECamAttributeContrast: - aValue = iContrastValue; - break; - - case ECamAttributeColorEffect: - aValue = iColorEffectValue; - break; - - default: - return KErrNotFound; - } - - return KErrNone; - } - - -/** -Updates the buffer configuration of the camera for the specified capture mode. -@return A handle to the shared chunk for the owning thread (a value >0), if successful; - otherwise one of the other system wide error codes, (a value <0). -*/ -TInt DCameraScLdd::SetBufConfig(TInt aCaptureMode, TInt aNumBuffers) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::SetBufConfig(CaptureMode=%d,NumBuffers=%d)",aCaptureMode,aNumBuffers)); - - // Free any memory and chunk already allocated - TInt r=ChunkClose(aCaptureMode); - if (r!=KErrNone) - return(r); - - // Allocate a new shared chunk and create the specified number of buffers within it. - TInt buffersize=((iCaptureModeConfig[aCaptureMode].iCamConfig.iFrameSize.iWidth*iCaptureModeConfig[aCaptureMode].iCamConfig.iFrameSize.iHeight) * iCaptureModeConfig[aCaptureMode].iCamConfig.iPixelWidthInBytes); - __KTRACE_CAM(Kern::Printf(">>DCameraScLdd::SetBufConfig - iFrameSize:%d, iPixelWidthInBytes:%d => bufferSize:%d",(iCaptureModeConfig[aCaptureMode].iCamConfig.iFrameSize.iWidth*iCaptureModeConfig[aCaptureMode].iCamConfig.iFrameSize.iHeight),iCaptureModeConfig[aCaptureMode].iCamConfig.iPixelWidthInBytes,buffersize)); - iCaptureModeConfig[aCaptureMode].iBufManager=new DBufferManager(this); - if (!iCaptureModeConfig[aCaptureMode].iBufManager) - return(KErrNoMemory); - r=iCaptureModeConfig[aCaptureMode].iBufManager->Create(aNumBuffers,buffersize); - if (r!=KErrNone) - return(r); - - // Update the LDD's chunk/buffer geometry info. - r=ReAllocBufferConfigInfo(aCaptureMode, aNumBuffers); - if (r!=KErrNone) - return(r); - iCaptureModeConfig[aCaptureMode].iBufManager->GetBufConfig(*iCaptureModeConfig[aCaptureMode].iBufConfig); - - // Create handle to the shared chunk for the owning thread. - r=Kern::MakeHandleAndOpen(iOwningThread,iCaptureModeConfig[aCaptureMode].iBufManager->iChunk); - if (r>0) - { - // And save the the chunk and handle for later. Normally the chunk handle will be closed when the chunk - // is closed, but if the chunk is re-allocated then it will need to be closed before re-allocation. - iCaptureModeConfig[aCaptureMode].iChunkHandle=r; - } - - __KTRACE_CAM(Kern::Printf("DCameraScLdd::SetConfig(Handle-%d)",aChunkHandle)); - - // Read the buffer config structure from the client. - TInt numBuffers; - TPtr8 ptr((TUint8*)&numBuffers,sizeof(numBuffers)); - TInt r=Kern::ThreadDesRead(iOwningThread,aBufferConfigBuf,ptr,0); - if (r!=KErrNone) - return(r); - // Calculate the minimum length of the descriptor. - TInt minDesLen=(numBuffers*sizeof(SBufSpecList))+sizeof(TSharedChunkBufConfigBase); - r=Kern::ThreadGetDesLength(iOwningThread,aBufferConfigBuf); - if (rCreate(*iCaptureModeConfig[aCaptureMode].iBufConfig,aChunkHandle,iOwningThread); - if (r!=KErrNone) - return(r); - - __KTRACE_CAM(Kern::Printf("DCameraScLdd::ChunkClose(Capture Mode-%d)",aCaptureMode)); - - if(iCaptureMode == aCaptureMode) - { - if (iState==ECapturing) - return(KErrInUse); - } - - // Delete any existing buffers - if (iCaptureModeConfig[aCaptureMode].iBufManager) - { - delete iCaptureModeConfig[aCaptureMode].iBufManager; - iCaptureModeConfig[aCaptureMode].iBufManager=NULL; - } - - // If a handle to the shared chunk was created, close it, using the handle of the thread on which - // it was created, in case a different thread is now calling us - if (iCaptureModeConfig[aCaptureMode].iChunkHandle>0) - { - Kern::CloseHandle(iOwningThread,iCaptureModeConfig[aCaptureMode].iChunkHandle); - iCaptureModeConfig[aCaptureMode].iChunkHandle=0; - } - - return(KErrNone); - } - -/** -Set the current capture mode and submits the camera configuration to the PDD, passing it as a descriptor -to support future changes to the config structure. - -@param aCaptureMode The capture mode that the camera switches to. -@return KErrNone if successful; - otherwise one of the other system-wide error codes. -*/ -TInt DCameraScLdd::SetCaptureMode(TInt aCaptureMode) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::SetCaptureMode(Mode-%d)",aCaptureMode)); - - TInt r=KErrNone; - if(aCaptureMode >= ECamCaptureModeMax || aCaptureMode < 0) - { - r=KErrNotFound; - return(r); - } - - if (!iCaptureModeConfig[aCaptureMode].iBufManager) - { - r=KErrNotReady; - return(r); - } - - iCaptureMode=(TDevCamCaptureMode)aCaptureMode; // The capture mode has already been checked for its validity. - - __KTRACE_CAM(Kern::Printf("DCameraScLdd::SetCaptureMode: iFrameSize:%dx%d)",iCaptureModeConfig[iCaptureMode].iCamConfig.iFrameSize.iWidth, iCaptureModeConfig[iCaptureMode].iCamConfig.iFrameSize.iHeight)); - - // Call the PDD to change the hardware configuration according to the new capture mode. - // Pass it as a descriptor - to support future changes to the config structure. - TPtr8 ptr((TUint8*)&iCaptureModeConfig[iCaptureMode].iCamConfig,sizeof(iCaptureModeConfig[iCaptureMode].iCamConfig),sizeof(iCaptureModeConfig[iCaptureMode].iCamConfig)); - r=Pdd()->SetConfig(ptr); - if (r!=KErrNone) - return(r); - return KErrNone; - } - - -/** -Process a start image capture request from the client - in the capture mode supplied. -If this is a free running mode then the PDD is called straight away to commence capturing frames. In one shot mode the driver postpones the capturing -of frames until a NotifyNewImage() request is received. -@return KErrNone if successful; whether capture mode was actually started or deferred until NotifyNewImage(); - KErrNotReady if SetConfig() has not been previously called; - otherwise one of the other system-wide error codes. -*/ -TInt DCameraScLdd::Start() - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::Start(Current Mode-%d)",iCaptureMode)); - - if (iState==ECapturing) - return(KErrInUse); - TInt r=KErrNone; - - // Only continue if the mode being started has been configured - if (iCaptureModeConfig[iCaptureMode].iBufManager) - iState=EConfigured; - - if (iState==EOpen) - r=KErrNotReady; - else if (iState==EConfigured) - { - iCaptureModeConfig[iCaptureMode].iBufManager->Reset(); - if (iCaptureMode!=ECamCaptureModeImage) - r=DoStart(); - if (r==KErrNone) - iState=ECapturing; - } - else - r=KErrGeneral; - return(r); - } - -/** -Start the PDD capturing images. -@return KErrNone if successful, otherwise one of the other system wide error codes. -*/ -TInt DCameraScLdd::DoStart() - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DoStart()")); - - DBufferManager* bufManager=iCaptureModeConfig[iCaptureMode].iBufManager; - TLinAddr linAddr=(bufManager->iChunkBase)+(bufManager->iCurrentBuffer->iChunkOffset); - TPhysAddr physAddr=bufManager->iCurrentBuffer->iPhysicalAddress; - TInt r=Pdd()->Start(iCaptureMode,linAddr,physAddr); - -/* - * James Cooper: Uncommenting this code will cause the ASSERT_DEBUG in SetImageCaptured() to fail - * if (r==KErrNone && bufManager->iNextBuffer) - { - linAddr=(bufManager->iChunkBase)+(bufManager->iNextBuffer->iChunkOffset); - physAddr=bufManager->iNextBuffer->iPhysicalAddress; - r=Pdd()->CaptureNextImage(linAddr,physAddr); - } -*/ - return(r); - } - -/** -Process a notify a new image request from the client. -If there is an image already available then the request is completed straight away, otherwise it is added to the capture request queue. -@param aStatus The request status to be signalled when the request is complete. If the request is successful then this is set - to the offset within the shared chunk where the record data resides. Alternatively, if an error occurs, - it will be set to one of the system wide error values. -@return KErrNone if successful - whether the request was completed or simply queued; - KErrNotReady if Start() hasn't been previousely called; - KErrInUse: if the client needs to free up buffers before further requests can be accepted; - KErrGeneral: if the client has more requests queued than there are buffers; - otherwise one of the other system wide error codes. -*/ -TInt DCameraScLdd::NotifyNewImage(TRequestStatus* aStatus) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::NotifyNewImage(%x) - iState(%d)",aStatus,iState)); - DBufferManager* bufManager=iCaptureModeConfig[iCaptureMode].iBufManager; - TInt r; - if (iState!=ECapturing || !bufManager) - return(KErrNotReady); - - NKern::FMWait(&iMutex); // Acquire the buffer/request list mutex. - if (iCaptureMode!=ECamCaptureModeImage) - { - // We're operating in one of the free running modes, see if an image is already available. - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::NotifyNewImage - Getting image for client")); - TImageBuffer* buf=bufManager->GetImageForClient(EFalse); - if (buf) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::NotifyNewImage - There is an image available already")); - // There is an image available already - complete the request. - r=buf->iResult; - NKern::FMSignal(&iMutex); // Release the buffer/request list mutex. - if (r==KErrNone) - { - // Only complete if successful here. Errors will be completed on returning from this method. - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::NotifyNewImage(iId:%d)",buf->iId)); - Kern::RequestComplete(iOwningThread,aStatus,(buf->iId)); - } - return(r); - } - - // The buffer 'completed' list is empty. If the 'in-use' list contains all the buffers apart from the one being filled - // then let the client know they need to free some buffers. - if (bufManager->iFreeBufferQ.IsEmpty() && !bufManager->iNextBuffer) - { - NKern::FMSignal(&iMutex); // Release the buffer/request list mutex. - return(KErrInUse); - } - } - else - { - // We're operating in one shot image capture mode. Check if the client needs to free up some buffers - // before we can accept the request. - if (bufManager->iCompletedBufferQ.IsEmpty() && bufManager->iFreeBufferQ.IsEmpty() && !bufManager->iNextBuffer) - { - NKern::FMSignal(&iMutex); // Release the buffer/request list mutex. - return(KErrInUse); - } - - // Enough buffers are available so we can start capturing data. First - // check that there isn't already a capture request in progress. - if (iRequestQueue.IsEmpty()) - { - // No previous request in progress so start the PDD. - NKern::FMSignal(&iMutex); // Release the buffer/request list mutex. - r=DoStart(); - if (r!=KErrNone) - return(r); - NKern::FMWait(&iMutex); // Acquire the buffer/request list mutex again. - } - } - - // Save the request in the pending queue and return. The request will be completed from the PDD and the DFC thread when - // an image is available. - r=iRequestQueue.Add(aStatus); - NKern::FMSignal(&iMutex); // Release the buffer/request list mutex. - return(r); - } - -/** -Process a release buffer request from the client. -@param aChunkOffset The chunk offset corresponding to the buffer to be freed. -@return KErrNone if successful; - KErrNotFound if no 'in use' buffer had the specified chunk offset; - KErrNotReady if the driver hasn't been configured for the current capture mode. -*/ -TInt DCameraScLdd::ReleaseBuffer(TInt aBufferId) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::ReleaseBuffer(%d)",aBufferId)); - if(!iCaptureModeConfig[iCaptureMode].iBufManager) - return KErrNotReady; - DBufferManager* bufManager=iCaptureModeConfig[iCaptureMode].iBufManager; - TInt chunkOffset = 0; - - TInt r=KErrNone; - /* The driver is left in an ECapturing state after capturing frames. However, it can be left in an - EConfigured state as a result of Stop() being called. Stop() cancels all pending capture requests and - leaves the driver in a state in which it can be restarted without needing reconfiguring. */ - if (iState!=EOpen && bufManager) - { - chunkOffset = bufManager->iImageBuffer[aBufferId].iChunkOffset; - TImageBuffer* buf=NULL; - NKern::FMWait(&iMutex); // Acquire the buffer/request list mutex. - buf=bufManager->FindInUseImage(chunkOffset); - NKern::FMSignal(&iMutex); // Release the buffer/request list mutex. - if (buf) - { - // The buffer specified by the client has been found in the 'in-use' list. - bufManager->Purge(buf); - } - else - r=KErrNotFound; - - if (r==KErrNone) - { - NKern::FMWait(&iMutex); // Acquire the buffer/request list mutex. - // Release it from the 'in-use list into the 'free' list. - r=bufManager->ReleaseImage(chunkOffset); - if (r>0) - { - // The buffer needs to be queued straight away - so signal this to the PDD - TLinAddr linAddr=(bufManager->iChunkBase)+(bufManager->iNextBuffer->iChunkOffset); - TPhysAddr physAddr=bufManager->iNextBuffer->iPhysicalAddress; - buf=bufManager->iNextBuffer; - NKern::FMSignal(&iMutex); // Release the buffer/request list mutex. - r=Pdd()->CaptureNextImage(linAddr,physAddr); - if (r==KErrNotReady) - r=KErrNone; - } - else - NKern::FMSignal(&iMutex); // Release the buffer/request list mutex. - } - } - else - r=KErrNotReady; - __KTRACE_CAM(Kern::Printf("DCameraScLdd::ImageCaptureCallback")); - - DBufferManager* bufManager=iCaptureModeConfig[iCaptureMode].iBufManager; - // Update the buffer list and get the next buffer for capture. - NKern::FMWait(&iMutex); // Acquire the buffer/request list mutex. - TImageBuffer* nextBuffer=bufManager->SetImageCaptured(aResult); // Puts the captured image's buffer in the completed buffer queue. - - // Check if there is a capture request pending. - if (!iRequestQueue.IsEmpty()) - { - // A capture request is pending. - TBool removeLast=((iCaptureMode==ECamCaptureModeImage) ? (TBool) ETrue : (TBool) EFalse); - TImageBuffer* buf=bufManager->GetImageForClient(removeLast); // Retrieved the captured image from the buffer in the completed buffer queue. - if (buf) - { - // Update the request pending list and complete the request. - TRequestStatus* rs=iRequestQueue.Remove(); - TInt reason=(buf->iResult==KErrNone) ? buf->iId : buf->iResult; - NKern::FMSignal(&iMutex); // Release the buffer/request list mutex. - buf->SyncMemoryAfterDmaRead(); - Kern::RequestComplete(iOwningThread,rs,reason); // Complete the request. - } - else - NKern::FMSignal(&iMutex); // Release the buffer/request list mutex. - } - else - NKern::FMSignal(&iMutex); // Release the buffer/request list mutex. - - // Now work out what instruction to give to the PDD - TInt r=KErrNone; - if (iCaptureMode==ECamCaptureModeImage) - { - // Image capture mode. If we've just completed a one shot request, see if there is yet another one pending. - if (!iRequestQueue.IsEmpty()) - { - // Another request is pending so let the PDD carry on. - // If an error occured we need to first stop and re-start image capture - if (aResult!=KErrNone) - { - iRestartDfc.Enque(); // Queue a DFC to re-start the PDD later. - r=KErrAbort; - } - } - else - { - r=KErrAbort; // End of image gather mode so stop the PDD. - } - } - else - { - // One of the free running modes. If an error occured we need to first stop and re-start image capture - if (aResult!=KErrNone) - { - iRestartDfc.Enque(); // Queue a DFC to re-start the PDD later. - r=KErrAbort; - } - } - - // If capture should continue, check if there is a further buffer available to use for image capture. - if (r==KErrNone) - { - if (nextBuffer) - { - *aLinAddr=(bufManager->iChunkBase)+(nextBuffer->iChunkOffset); - *aPhysAddr=nextBuffer->iPhysicalAddress; - } - else - r=KErrNotReady; - } - return(r); - } - -/** -Stores the camera configuration passed in from the user after checking and validating it. -@param aCaptureMode The capture mode for which the setting of the camera configuration is made. -@param aCamConfigBuf A buffer that contains the camera configuration. -@return KErrNone if successful - KErrInUse if the camera is capturing an image - KErrArgument if the camera configuration passed in is invalid - otherwise a system wide error code. -*/ -TInt DCameraScLdd::DoSetConfig(TInt aCaptureMode, const TDesC8* aCamConfigBuf) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DoSetConfig(CaptureMode=%d)",aCaptureMode)); - - if(iCaptureMode == aCaptureMode) - { - if (iState==ECapturing) - return(KErrInUse); - } - - // Read the config structure from the client - TCameraConfigV02 config; - TPtr8 ptr((TUint8*)&config,sizeof(config)); - TInt r=Kern::ThreadDesRead(iOwningThread,aCamConfigBuf,ptr,0); - if (r!=KErrNone) - return(r); - - // Check that it is compatible with this camera device - r=ValidateConfig(aCaptureMode, config); - if (r!=KErrNone) - { - if (r == KErrNotFound) - r = KErrArgument; - return(r); - } - - // We're about to replace any previous configuration - so set the - // status back to un-configured. A new buffer configuration must be calculated as a result of that. - //iState=EOpen; - - // Save the new configuration. - iCaptureModeConfig[aCaptureMode].iCamConfig=config; - iCaptureModeConfig[aCaptureMode].iFrameHeight=iCaptureModeConfig[aCaptureMode].iCamConfig.iFrameSize.iHeight; - iCaptureModeConfig[aCaptureMode].iFrameWidth=iCaptureModeConfig[aCaptureMode].iCamConfig.iFrameSize.iWidth; - - __KTRACE_CAM(Kern::Printf("DCameraScLdd::ValidateConfig")); - - TInt capsSize = Pdd()->CapsSize(); - NKern::ThreadEnterCS(); - TAny* capsBuf = Kern::Alloc(capsSize); - if(!capsBuf) - { - NKern::ThreadLeaveCS(); - return KErrNoMemory; - } - - TPtr8 capsPtr( (TUint8*)capsBuf, capsSize, capsSize ); - Pdd()->Caps(capsPtr); - NKern::ThreadLeaveCS(); - - TCameraCapsV02* camCaps = (TCameraCapsV02*) capsPtr.Ptr(); - - TInt r; - if(aCaptureMode==ECamCaptureModeImage && camCaps->iNumImagePixelFormats) - { - r=DoValidateConfig(camCaps, aCaptureMode, aConfig); - } - else if(aCaptureMode==ECamCaptureModeVideo && camCaps->iNumVideoPixelFormats) - { - r=DoValidateConfig(camCaps, aCaptureMode, aConfig); - } - else if(aCaptureMode==ECamCaptureModeViewFinder && camCaps->iNumViewFinderPixelFormats) - { - r=DoValidateConfig(camCaps, aCaptureMode, aConfig); - } - else - r=KErrNotSupported; - - if(r==KErrNone) - { - // Calculate the pixel width (in bytes) for the format specified - aConfig.iPixelWidthInBytes=aConfig.iPixelFormat.iPixelWidthInBytes; - } - - NKern::ThreadEnterCS(); - Kern::Free(capsBuf); - NKern::ThreadLeaveCS(); - - __KTRACE_CAM(Kern::Printf("DCameraScLdd::DoValidateConfig")); - TAny* frameSizeCapsBuf; - TInt frameSizeCapsSize; - SFrameSizeCapsInfo info; - SDevCamFrameSize* frameSize; - TUint i; - TUint l; - SDevCamPixelFormat* pixelFormat; - TUint start; - TUint end; - TInt r; - pixelFormat = (SDevCamPixelFormat*) (aCamCaps + 1); - if(aCaptureMode==ECamCaptureModeImage) - { - start=0; - end=aCamCaps->iNumImagePixelFormats; - } - else if(aCaptureMode==ECamCaptureModeVideo) - { - start=aCamCaps->iNumImagePixelFormats; - end=aCamCaps->iNumImagePixelFormats + aCamCaps->iNumVideoPixelFormats; - pixelFormat += aCamCaps->iNumImagePixelFormats; - } - else if(aCaptureMode==ECamCaptureModeViewFinder) - { - start=aCamCaps->iNumImagePixelFormats+aCamCaps->iNumVideoPixelFormats; - end=aCamCaps->iNumImagePixelFormats + aCamCaps->iNumVideoPixelFormats + aCamCaps->iNumViewFinderPixelFormats; - pixelFormat += aCamCaps->iNumImagePixelFormats; - pixelFormat += aCamCaps->iNumVideoPixelFormats; - } - else - return KErrNotSupported; - - for (i=start; iiPixelFormat) - { - info.iUidPixelFormat = pixelFormat->iPixelFormat; - info.iCaptureMode = (TDevCamCaptureMode) aCaptureMode; - frameSizeCapsSize = pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize); - NKern::ThreadEnterCS(); - frameSizeCapsBuf = Kern::Alloc(frameSizeCapsSize); - NKern::ThreadLeaveCS(); - if (!frameSizeCapsBuf) - { - return KErrNoMemory; - } - TPtr8 frameSizeCapsPtr( (TUint8*)frameSizeCapsBuf, frameSizeCapsSize, frameSizeCapsSize ); - if ((r = Pdd()->FrameSizeCaps(info.iCaptureMode, info.iUidPixelFormat, frameSizeCapsPtr)) == KErrNone) - { - frameSize = (SDevCamFrameSize*) frameSizeCapsPtr.Ptr(); - for(l=0; liNumFrameSizes; l++ ) - { - if (aConfig.iFrameSize.iWidth == frameSize->iWidth && - aConfig.iFrameSize.iHeight == frameSize->iHeight && - aConfig.iFrameRate >= frameSize->iMinFrameRate && - aConfig.iFrameRate <= frameSize->iMaxFrameRate) - { - NKern::ThreadEnterCS(); - Kern::Free(frameSizeCapsBuf); - NKern::ThreadLeaveCS(); - __KTRACE_CAM(Kern::Printf("DCameraScLdd::RestartDfc")); - - DCameraScLdd& drv=*(DCameraScLdd*)aChannel; - - if (!drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->iCurrentBuffer) - drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->iCurrentBuffer=drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->NextAvailableForCapture(); - __ASSERT_ALWAYS(drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->iCurrentBuffer,Kern::Fault(KCameraLddPanic,__LINE__)); - - if (!drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->iNextBuffer) - drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->iNextBuffer=drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->NextAvailableForCapture(); - - drv.DoStart(); - } - -/** -The DFC used to handle power down requests from the power manager before a transition into system -shutdown/standby. -@param aChannel A pointer to the camera driver logical channel object. -*/ -void DCameraScLdd::PowerDownDfc(TAny* aChannel) - { - DCameraScLdd& drv=*(DCameraScLdd*)aChannel; - drv.Shutdown(); - drv.iPowerHandler->PowerDownDone(); - } - -/** -The DFC used to handle power up requests from the power manager following a transition out of system standby. -@param aChannel A pointer to the camera driver logical channel object. -*/ -void DCameraScLdd::PowerUpDfc(TAny* aChannel) - { - DCameraScLdd& drv=*(DCameraScLdd*)aChannel; - drv.iPowerHandler->PowerUpDone(); - } - -void DCameraScLdd::PanicClientThread(TInt aReason) - { - Kern::ThreadKill(iOwningThread, EExitPanic, aReason, KDevCameraScName); - } - -/** -Retrieves the capabilities of the camera sensor. -@param aBuffer A pointer to a descriptor passed in by the user. -*/ -TInt DCameraScLdd::GetSensorCaps(TAny* aBuffer) - { - // Return the capabilities for this device. Read this from the PDD and - // then write it to the client - TInt capsSize = Pdd()->CapsSize(); - TInt bufferSize; - TInt maxBufferSize; - Kern::KUDesInfo(*((TDes8*)aBuffer), bufferSize, maxBufferSize); - if(capsSize>maxBufferSize) - { - return KErrArgument; - } - NKern::ThreadEnterCS(); - TAny* capsBuf = Kern::Alloc(capsSize); - if(!capsBuf) - { - NKern::ThreadLeaveCS(); - return KErrNoMemory; - } - - TPtr8 capsPtr( (TUint8*)capsBuf, capsSize, capsSize ); - Pdd()->Caps(capsPtr); - NKern::ThreadLeaveCS(); - Kern::InfoCopy(*((TDes8*)aBuffer), capsPtr.Ptr(), capsSize); - NKern::ThreadEnterCS(); - Kern::Free((TAny*)capsBuf); - NKern::ThreadLeaveCS(); - return KErrNone; - } - -/** -Retrieves the frame sizes supported for a given pixel format. -@param aBuffer A pointer to descriptor passed in by the user. -@param aFrameSizeCapsInfo A structure that holds information regarding the requested capabilities. -*/ -TInt DCameraScLdd::GetFrameSizeCaps(TAny* aBuffer, TAny* aFrameSizeCapsInfo) - { - __KTRACE_CAM(Kern::Printf(">DCameraScLdd::GetFrameSizeCaps()")); - TInt frameSizeCapsMaxSize; - TInt frameSizeCapsSize; - Kern::KUDesInfo(*((TDes8*)aBuffer),frameSizeCapsSize,frameSizeCapsMaxSize); - SFrameSizeCapsInfo info; - kumemget((TAny*)&info,aFrameSizeCapsInfo,sizeof(info)); - NKern::ThreadEnterCS(); - // Allocate memory on the heap for the frame size structure. - TAny* frameSizeCapsBuf = Kern::Alloc(frameSizeCapsMaxSize); - if (!frameSizeCapsBuf) - { - NKern::ThreadLeaveCS(); - return KErrNoMemory; - } - TPtr8 frameSizeCapsPtr( (TUint8*)frameSizeCapsBuf, frameSizeCapsMaxSize, frameSizeCapsMaxSize ); - // Request the frame sizes from the Pdd. - TInt r=Pdd()->FrameSizeCaps(info.iCaptureMode, info.iUidPixelFormat, frameSizeCapsPtr); - NKern::ThreadLeaveCS(); - if (r!=KErrNone) - { - NKern::ThreadEnterCS(); - Kern::Free((TAny*)frameSizeCapsBuf); - NKern::ThreadLeaveCS(); - return r; - } - Kern::InfoCopy(*((TDes8*)aBuffer),frameSizeCapsPtr.Ptr(), frameSizeCapsMaxSize); - NKern::ThreadEnterCS(); - Kern::Free((TAny*)frameSizeCapsBuf); - NKern::ThreadLeaveCS(); - return KErrNone; - } - - -/** -Constructor for the buffer manager. -*/ -DBufferManager::DBufferManager(DCameraScLdd* aLdd) - : iLdd(aLdd) - { -// iChunk=NULL; -// iNumBuffers=0; -// iImageBuffer=NULL; - } - -/** -Destructor for the buffer manager. -@pre The thread must be in a critical section. -*/ -DBufferManager::~DBufferManager() - { - if (iChunk) - Kern::ChunkClose(iChunk); - delete[] iImageBuffer; - } - -/** -Second stage constructor for the buffer manager. This version creates a shared chunk and a buffer object for each -buffer specified within this. Then it commits memory within the chunk for each of these buffers. This also involves the -creation of a set of buffer lists to manage the buffers. -@param aNumBuffers The number of buffers required in the shared chunk. -@param aBufferSize The size of each buffer required in the shared chunk. -@return KErrNone if successful, otherwise one of the other system wide error codes. -@pre The thread must be in a critical section. -*/ -TInt DBufferManager::Create(TInt aNumBuffers,TInt aBufferSize) - { - __KTRACE_CAM(Kern::Printf(">DBufferManager::Create(Bufs-%d,Sz-%d)",aNumBuffers,aBufferSize)); - - TInt r=CreateBufferLists(aNumBuffers); - if (r!=KErrNone) - return(r); - - // Calculate the size of the chunk required for the buffer configuration specified. - aBufferSize=Kern::RoundToPageSize(aBufferSize); - TInt pageSize=Kern::RoundToPageSize(1); - // Leave space for guard pages around each buffer. There is a guard page in between each buffer but - // NO guard page before the first buffer or after the last buffer - TUint64 chunkSize=TUint64(aBufferSize+pageSize)*aNumBuffers-pageSize; - if (chunkSize>(TUint64)KMaxTInt) - return(KErrNoMemory); // Need more than 2GB of memory! - - // Create the shared chunk. The PDD supplies most of the chunk create info - but not the maximum size. - TChunkCreateInfo info; - info.iMaxSize=(TInt)chunkSize; - iLdd->Pdd()->GetChunkCreateInfo(info); // Call down to the PDD for the rest. - - r = Kern::ChunkCreate(info,iChunk,iChunkBase,iChunkMapAttr); - if (r!=KErrNone) - return(r); - - // Commit memory in the chunk for each buffer. - TInt offset=0; - TBool isContiguous; - for (TInt i=0; iDBufferManager::Create(Handle-%d)",aChunkHandle)); - - // Validate the buffer configuration information - if (!aBufConfig.iFlags&KScFlagBufOffsetListInUse) - return(KErrArgument); - - TInt numBuffers=aBufConfig.iNumBuffers; - TInt r=CreateBufferLists(numBuffers); - if (r!=KErrNone) - return(r); - - DChunk* chunk; - chunk=Kern::OpenSharedChunk(anOwningThread,aChunkHandle,ETrue); - if (!chunk) - return(KErrBadHandle); - iChunk=chunk; - - // Read the physical address for the 1st buffer in order to determine the kernel address and the map attributes. - TInt bufferSizeInBytes=aBufConfig.iBufferSizeInBytes; - - SBufSpecList* bufferSpec=&aBufConfig.iSpec; - - TInt offset=bufferSpec[0].iBufferOffset; - - TPhysAddr physAddr; - r=Kern::ChunkPhysicalAddress(iChunk,offset,bufferSizeInBytes,iChunkBase,iChunkMapAttr,physAddr,NULL); - if (r!=KErrNone) - return(r); - - // Store the supplied buffer info. into each buffer object. - - for (TInt i=0; iDBufferManager::GetBufConfig")); - TInt numBuffers=iNumBuffers; - if (numBuffers<=0) - return; - - SBufSpecList* bufferSpec=&aBufConfig.iSpec; - - while (numBuffers--) - { - bufferSpec[numBuffers].iBufferOffset=iImageBuffer[numBuffers].iChunkOffset; - bufferSpec[numBuffers].iBufferId=iImageBuffer[numBuffers].iId; - } - - aBufConfig.iNumBuffers=iNumBuffers; - aBufConfig.iBufferSizeInBytes=iImageBuffer[0].iSize; // They're all the same size - so read from the 1st one. - aBufConfig.iFlags|=KScFlagBufOffsetListInUse; - return; - } - -/** -Allocate an array of buffer objects, - one for each buffer contained within the shared chunk. -@param aNumBuffers The number of buffer objects required. -@return KErrNone if successful, otherwise one of the other system wide error codes. -@pre The thread must be in a critical section. -*/ -TInt DBufferManager::CreateBufferLists(TInt aNumBuffers) - { - __KTRACE_CAM(Kern::Printf(">DBufferManager::CreateBufferLists(Bufs-%d)",aNumBuffers)); - - // Construct the array of buffers. - iNumBuffers=aNumBuffers; - iImageBuffer=new TImageBuffer[aNumBuffers]; - if (!iImageBuffer) - return(KErrNoMemory); - return(KErrNone); - } - -TInt DBufferManager::CommitMemoryForBuffer(TInt aChunkOffset,TInt aSize,TBool& aIsContiguous) - { - __KTRACE_CAM(Kern::Printf(">DBufferManager::CommitMemoryForBuffer(Offset-%x,Sz-%d)",aChunkOffset,aSize)); - - // Try for physically contiguous memory first. - TPhysAddr physicalAddress; - TInt r=Kern::ChunkCommitContiguous(iChunk,aChunkOffset,aSize,physicalAddress); - if (r==KErrNone) - { - aIsContiguous=ETrue; - return(r); - } - - // Commit memory that isn't contiguous instead. - aIsContiguous=EFalse; - r=Kern::ChunkCommit(iChunk,aChunkOffset,aSize); - return(r); - } - -/** -Reset all image buffer lists to reflect the state at the start of the image capture process. -@pre The buffer/request queue mutex must be held. -*/ -void DBufferManager::Reset() - { - __KTRACE_CAM(Kern::Printf(">DBufferManager::Reset")); - - TImageBuffer* pBuf; - - // Before reseting buffer lists, purge the cache for all cached buffers currently in use by client. - pBuf=(TImageBuffer*)iInUseBufferQ.First(); - SDblQueLink* anchor=&iInUseBufferQ.iA; - while (pBuf!=anchor) - { - Purge(pBuf); - pBuf=(TImageBuffer*)pBuf->iNext; - } - - // Start by reseting all the lists. - iFreeBufferQ.iA.iNext=iFreeBufferQ.iA.iPrev=&iFreeBufferQ.iA; - iCompletedBufferQ.iA.iNext=iCompletedBufferQ.iA.iPrev=&iCompletedBufferQ.iA; - iInUseBufferQ.iA.iNext=iInUseBufferQ.iA.iPrev=&iInUseBufferQ.iA; - - // Set the pointers to the current and the next record buffers. - pBuf=iImageBuffer; // This is the first buffer - iCurrentBuffer=pBuf++; - iNextBuffer = pBuf++; - - // Add all other buffers to the free list. - TImageBuffer* bufferLimit=iImageBuffer+iNumBuffers; - while(pBufSyncMemoryBeforeDmaRead(); - } - -/** -Update buffer lists after an image has been captured. -@param aResult The result of the image capture operation that has just completed. -@return A pointer to the next image buffer for capture - or NULL if none are available. -@pre The buffer/request queue mutex must be held. -*/ -TImageBuffer* DBufferManager::SetImageCaptured(TInt aResult) - { - // Take a copy of the buffer with the image just captured. - __ASSERT_DEBUG(iCurrentBuffer,Kern::Fault(KCameraLddPanic,__LINE__)); - TImageBuffer* cur=iCurrentBuffer; - - // Make the queued buffer the current one. - iCurrentBuffer=iNextBuffer; - - // Now we need to identify the next image buffer to queue. - iNextBuffer=NextAvailableForCapture(); - - // Now add the buffer with the image just captured to the 'completed' list. - if (cur) - { - cur->iResult=aResult; // Store the result of the capture operation in the image buffer object. - iCompletedBufferQ.Add(cur); - } - - __KTRACE_CAM(Kern::Printf("iChunkOffset,aResult)); - return(iNextBuffer); - } - -/** -Remove from the buffer lists the next buffer that is available to queue for transfer. -@return A pointer to the next image buffer for capture - or NULL if none are available. -@pre The buffer/request queue mutex must be held. -*/ -TImageBuffer* DBufferManager::NextAvailableForCapture() - { - // We need to identify the next image buffer to queue. Try to get one from the 'free' list. - TImageBuffer* buffer=(TImageBuffer*)iFreeBufferQ.GetFirst(); -#ifdef DISCARD_COMPLETED_TO_AVOID_OVERFLOW - // If there are none left on the 'free' list then take one from the completed list. - if (!buffer) - buffer=(TImageBuffer*)iCompletedBufferQ.GetFirst(); -#endif - return(buffer); - } - -/** -Get the next image from the 'completed' capture list. If there is no error associated with the buffer, -make it 'in use' by the client. Otherwise, return the buffer to the free list. -@param aRemoveLast If true, the buffer is removed from the tail of the completed capture list, otherwise - it is removed from the head of this list. -@return A pointer to the next completed image buffer - or NULL if there is no buffer available. -@pre The buffer/request queue mutex must be held. -*/ -TImageBuffer* DBufferManager::GetImageForClient(TBool aRemoveLast) - { - __KTRACE_CAM(Kern::Printf("Deque(); - - if (buffer->iResult==KErrNone) - iInUseBufferQ.Add(buffer); - else - iFreeBufferQ.Add(buffer); - } - return(buffer); - } - -/** -Release (move to free list) the 'in use' image specified by the given chunk offset. -@param aChunkOffset The chunk offset corresponding to the buffer to be freed. -@return The freed image buffer, or NULL if no 'in use' buffer had the specified chunk offset. -@return KErrNone if buffer moved to the free list; - 1 if the buffer needs to be queued straight away - KErrArgument if no 'in use' buffer had the specified chunk offset; -@pre The buffer/request queue mutex must be held. -*/ -TInt DBufferManager::ReleaseImage(TInt aChunkOffset) - { - __KTRACE_CAM(Kern::Printf(">DBufferManager::ReleaseImage(chunkOffset=%08x)",aChunkOffset)); - TInt r=KErrArgument; - - // Scan 'in use' list for the image buffer - TImageBuffer* pBuf; - pBuf=(TImageBuffer*)iInUseBufferQ.First(); - SDblQueLink* anchor=&iInUseBufferQ.iA; - while (pBuf!=anchor && pBuf->iChunkOffset!=aChunkOffset) - pBuf=(TImageBuffer*)pBuf->iNext; - - if (pBuf!=anchor) - { - // Buffer found in 'in-use' list. - if (!iNextBuffer) - { - // We need to signal the pdd to queue this buffer straight away. - iNextBuffer=(TImageBuffer*)pBuf->Deque(); - r=1; - } - else - { - // Move buffer to the free list. - iFreeBufferQ.Add(pBuf->Deque()); - r=KErrNone; - } - } - - __KTRACE_CAM(Kern::Printf("iChunkOffset : -1))); - return(r); - } - -/** -Find the 'in use' image specified by the given chunk offset -@param aChunkOffset The chunk offset corresponding to the buffer to be freed -@return The image buffer, or NULL if no 'in use' buffer had the specified chunk offset -@pre The buffer/request queue mutex must be held. -*/ -TImageBuffer* DBufferManager::FindInUseImage(TInt aChunkOffset) - { - // Scan 'in use' list for the image buffer - TImageBuffer* pBuf; - pBuf=(TImageBuffer*)iInUseBufferQ.First(); - SDblQueLink* anchor=&iInUseBufferQ.iA; - while (pBuf!=anchor && pBuf->iChunkOffset!=aChunkOffset) - pBuf=(TImageBuffer*)pBuf->iNext; - - return((pBuf!=anchor)?pBuf:NULL); - } - -/** -Constructor for the image buffer class. -Clears all member data -*/ -TImageBuffer::TImageBuffer() - { - memclr(this,sizeof(*this)); - } - -/** -Destructor for the image buffer class. -*/ -TImageBuffer::~TImageBuffer() - { - delete[] iPhysicalPages; - } - -/** -Second stage constructor for the image buffer class - get information on the memory -allocated to this buffer. -@param aChunk The chunk into which the memory is to be commited -@param aOffset The offset within aChunk for the start of the comitted memory. - Must be a multiple of the MMU page size. -@param aSize The number of bytes of memory commited. - Must be a multiple of the MMU page size. -@return KErrNone if successful, otherwise one of the other system wide error codes. -@pre The thread must be in a critical section. -*/ -TInt TImageBuffer::Create(DChunk* aChunk,TInt aOffset,TInt aSize, TInt aId, TBool aIsContiguous) - { - __KTRACE_CAM(Kern::Printf(">TImageBuffer::Create(Off-%x,Sz-%d,Contig-%d)",aOffset,aSize,aIsContiguous)); - - // Save info. on the chunk the buffer is in, and the offset and size of the buffer. - iChunk=aChunk; - iChunkOffset=aOffset; - iId=aId; - iSize=aSize; - - TInt r=KErrNone; - iPhysicalPages=NULL; - if (!aIsContiguous) - { - // Allocate an array for a list of the physical pages. - iPhysicalPages = new TPhysAddr[aSize/Kern::RoundToPageSize(1)+2]; - if (!iPhysicalPages) - r=KErrNoMemory; - } - - if (r==KErrNone) - { - // Get the physical addresses of the pages in the buffer. - TUint32 mapAttr; - r=Kern::ChunkPhysicalAddress(aChunk,aOffset,aSize,iLinearAddress,mapAttr,iPhysicalAddress,iPhysicalPages); - // r = 0 or 1 on success. (1 meaning the physical pages are not contiguous). - if (r==1) - { - // The physical pages are not contiguous. - iPhysicalAddress=KPhysAddrInvalid; // Mark the physical address as invalid. - r=(aIsContiguous) ? KErrGeneral : KErrNone; - } - if (r==0) - { - delete[] iPhysicalPages; // We shouldn't retain this info. if the physical pages are contiguous. - iPhysicalPages=NULL; - } - } - __KTRACE_CAM(Kern::Printf("iMapAttr&EMapAttrCachedMax) - { - Cache::SyncMemoryBeforeDmaRead(iLinearAddress,iSize); - } -#endif - } - -/** -Prepare a cacheable buffer for use by the CPU, after an image capture using DMA. -*/ -void TImageBuffer::SyncMemoryAfterDmaRead() - { -#ifndef __WINS__ - if (iChunk->iMapAttr&EMapAttrCachedMax) - { - Cache::SyncMemoryAfterDmaRead(iLinearAddress,iSize); - } -#endif - } - -/** -Constructor for the capture request queue. -*/ -TCameraScRequestQueue::TCameraScRequestQueue(NFastMutex* aMutexPtr) - : iMutexPtr(aMutexPtr) - { - iOwningThread=NULL; - memclr(&iRequest[0],sizeof(TCameraScRequest*)*KMaxCamScRequestsPending); - } - -/** -Destructor for the capture request queue. -*/ -TCameraScRequestQueue::~TCameraScRequestQueue() - { - for (TInt i=0 ; iiStatus=aStatus; - iPendRequestQ.Add(req); - return(KErrNone); - } - -/** -Retrieve the next request status pointer from the head of the capture request queue. -@return The request status pointer removed or NULL if the list is empty. -@pre The buffer/request queue mutex must be held. -*/ -TRequestStatus* TCameraScRequestQueue::Remove() - { - TRequestStatus* status=NULL; - TCameraScRequest* req=(TCameraScRequest*)iPendRequestQ.GetFirst(); - if (req) - { - status=req->iStatus; - iUnusedRequestQ.Add(req); - } - return(status); - } - -/** -Remove a specifc request status pointer from the the capture request queue, completing it with a 'KErrCancel' completion reason. -@param aStatus The request status pointer to be completed. -@pre The buffer/request queue mutex must be held. -*/ -void TCameraScRequestQueue::Cancel(TRequestStatus* aStatus) - { - // Find the entry concerned - TCameraScRequest* req=(TCameraScRequest*)iPendRequestQ.First(); - SDblQueLink* anchor=&iPendRequestQ.iA; - while (req!=anchor && req->iStatus!=aStatus) - req=(TCameraScRequest*)req->iNext; - if (req==anchor) - return; - - // Remove and cancel it. - req->Deque(); - iUnusedRequestQ.Add(req); - NKern::FMSignal(iMutexPtr); // Release the request list mutex while we complete the request. This is safe. - Kern::RequestComplete(iOwningThread,req->iStatus,KErrCancel); - NKern::FMWait(iMutexPtr); // Re-acquire the request list mutex. - } - -/** -Remove each request status pointer from the the capture request queue, completing each with a 'KErrCancel' completion reason. -@pre The buffer/request queue mutex must be held. -*/ -void TCameraScRequestQueue::CancelAll() - { - - TRequestStatus* status; - while ((status=Remove())!=NULL) - { - NKern::FMSignal(iMutexPtr); // Release the request list mutex while we complete the request. This is safe. - Kern::RequestComplete(iOwningThread,status,KErrCancel); - NKern::FMWait(iMutexPtr); // Re-acquire the request list mutex. - } - } - -/** -Constructor for the camera driver power handler class. -@param aChannel A pointer to the camera driver logical channel which owns this power handler. -*/ -DCameraScPowerHandler::DCameraScPowerHandler(DCameraScLdd* aChannel) -: DPowerHandler(KDevCameraScName), - iChannel(aChannel) - { - } - -/** -A request from the power manager for the power down of the camera device. -This is called during a transition of the phone into standby or power off. -@param aState The target power state; can be EPwStandby or EPwOff only. -*/ -void DCameraScPowerHandler::PowerDown(TPowerState aPowerState) - { - (void)aPowerState; - __KTRACE_CAM(Kern::Printf(">DCameraScPowerHandler::PowerDown(State-%d)",aPowerState)); - - // Power-down involves hardware access so queue a DFC to perform this from the driver thread. - iChannel->iPowerDownDfc.Enque(); - } - -/** -A request from the power manager for the power up of the camera device. -This is called during a transition of the phone out of standby. -*/ -void DCameraScPowerHandler::PowerUp() - { - __KTRACE_CAM(Kern::Printf(">DCameraScPowerHandler::PowerUp")); - - // Power-up involves hardware access so queue a DFC to perform this from the driver thread. - iChannel->iPowerUpDfc.Enque(); - } diff -r a5496987b1da -r 189ece41fa29 kernel/eka/drivers/camerasc/ecamerasc.mmp --- a/kernel/eka/drivers/camerasc/ecamerasc.mmp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -// Copyright (c) 2005-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: -// e32/drivers/camerasc/ecamerasc.mmp -// ecamerasc.ldd camera logical device driver -// -// - -/** - @file -*/ - -#include "../../kernel/kern_ext.mmh" - -OS_LAYER_SYSTEMINCLUDE_SYMBIAN - -TARGET ecamerasc.ldd -TARGETTYPE ldd - -SOURCE cameraldd.cpp - -UID 0 0x100000c9 -VENDORID 0x70000001 - -CAPABILITY all - -START WINS -win32_headers -END diff -r a5496987b1da -r 189ece41fa29 kernel/eka/drivers/dma/dma2_pil.cpp --- a/kernel/eka/drivers/dma/dma2_pil.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/drivers/dma/dma2_pil.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -22,23 +22,21 @@ #include -// Symbian Min() & Max() are broken, so we have to define them ourselves -inline TUint Min(TUint aLeft, TUint aRight) +// Symbian _Min() & _Max() are broken, so we have to define them ourselves +inline TUint _Min(TUint aLeft, TUint aRight) {return(aLeft < aRight ? aLeft : aRight);} -inline TUint Max(TUint aLeft, TUint aRight) +inline TUint _Max(TUint aLeft, TUint aRight) {return(aLeft > aRight ? aLeft : aRight);} -// Uncomment the following #define only when freezing the DMA2 export library. -//#define __FREEZE_DMA2_LIB -#ifdef __FREEZE_DMA2_LIB +// The following section is used only when freezing the DMA2 export library +/* TInt DmaChannelMgr::StaticExtension(TInt, TAny*) {return 0;} TDmaChannel* DmaChannelMgr::Open(TUint32, TBool, TUint) {return 0;} void DmaChannelMgr::Close(TDmaChannel*) {} EXPORT_C const TDmaTestInfo& DmaTestInfo() {static TDmaTestInfo a; return a;} EXPORT_C const TDmaV2TestInfo& DmaTestInfoV2() {static TDmaV2TestInfo a; return a;} -#endif // #ifdef __FREEZE_DMA2_LIB - +*/ static const char KDmaPanicCat[] = "DMA " __FILE__; @@ -202,7 +200,7 @@ { // TDmac needs to override this function if it has reported the channel // type for which the PIL calls it. - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); } @@ -211,7 +209,7 @@ { // TDmac needs to override this function if it has reported the channel // type for which the PIL calls it. - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); } @@ -265,7 +263,7 @@ } else { - iDesPool = new TDmaTransferArgs[iMaxDesCount]; + iDesPool = Kern::Alloc(iMaxDesCount * sizeof(TDmaTransferArgs)); r = iDesPool ? KErrNone : KErrNoMemory; } return r; @@ -450,7 +448,7 @@ TInt TDmac::InitHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) { // concrete controller must override if SDmacCaps::iHwDescriptors set - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); return KErrGeneral; } @@ -458,7 +456,7 @@ TInt TDmac::InitSrcHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) { // concrete controller must override if SDmacCaps::iAsymHwDescriptors set - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); return KErrGeneral; } @@ -466,7 +464,7 @@ TInt TDmac::InitDstHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) { // concrete controller must override if SDmacCaps::iAsymHwDescriptors set - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); return KErrGeneral; } @@ -502,7 +500,7 @@ TUint /*aTransferCount*/, TUint32 /*aPslRequestInfo*/) { // concrete controller must override if SDmacCaps::iHwDescriptors set - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); return KErrGeneral; } @@ -511,7 +509,7 @@ TUint /*aTransferCount*/, TUint32 /*aPslRequestInfo*/) { // concrete controller must override if SDmacCaps::iAsymHwDescriptors set - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); return KErrGeneral; } @@ -520,7 +518,7 @@ TUint /*aTransferCount*/, TUint32 /*aPslRequestInfo*/) { // concrete controller must override if SDmacCaps::iAsymHwDescriptors set - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); return KErrGeneral; } @@ -528,7 +526,7 @@ void TDmac::ChainHwDes(const SDmaDesHdr& /*aHdr*/, const SDmaDesHdr& /*aNextHdr*/) { // concrete controller must override if SDmacCaps::iHwDescriptors set - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); } @@ -536,7 +534,7 @@ const SDmaDesHdr& /*aNewHdr*/) { // concrete controller must override if SDmacCaps::iHwDescriptors set - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); } @@ -545,14 +543,14 @@ const SDmaDesHdr& /*aDstLastHdr*/, const SDmaDesHdr& /*aDstNewHdr*/) { // concrete controller must override if SDmacCaps::iAsymHwDescriptors set - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); } void TDmac::UnlinkHwDes(const TDmaChannel& /*aChannel*/, SDmaDesHdr& /*aHdr*/) { // concrete controller must override if SDmacCaps::iHwDescriptors set - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); } @@ -601,7 +599,7 @@ TUint32 TDmac::HwDesNumDstElementsTransferred(const SDmaDesHdr& /*aHdr*/) { // Concrete controller must override if SDmacCaps::iHwDescriptors set. - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); return 0; } @@ -609,7 +607,7 @@ TUint32 TDmac::HwDesNumSrcElementsTransferred(const SDmaDesHdr& /*aHdr*/) { // Concrete controller must override if SDmacCaps::iHwDescriptors set. - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); return 0; } @@ -856,7 +854,7 @@ } -TInt DDmaRequest::CheckMemFlags(const TDmaTransferConfig& aTarget, TUint aCount) const +TInt DDmaRequest::CheckMemFlags(const TDmaTransferConfig& aTarget) const { __KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::CheckMemFlags")); @@ -892,7 +890,7 @@ TUint rem = 0; TInt r = KErrNone; - while (1) + FOREVER { // If an element size is defined, make sure the fragment size is // greater or equal. @@ -1101,13 +1099,13 @@ aTransferArgs.iChannelCookie = iChannel.PslId(); // Client shouldn't specify contradictory or invalid things - TInt r = CheckMemFlags(aTransferArgs.iSrcConfig, count); + TInt r = CheckMemFlags(aTransferArgs.iSrcConfig); if (r != KErrNone) { __KTRACE_OPT(KPANIC, Kern::Printf("Error: CheckMemFlags(src)")); return r; } - r = CheckMemFlags(aTransferArgs.iDstConfig, count); + r = CheckMemFlags(aTransferArgs.iDstConfig); if (r != KErrNone) { __KTRACE_OPT(KPANIC, Kern::Printf("Error: CheckMemFlags(dst)")); @@ -1160,7 +1158,7 @@ // Max aligned length is used to make sure the beginnings of subtransfers // (i.e. fragments) are correctly aligned. const TUint max_aligned_len = (aMaxTransferLen & - ~(Max(align_mask_src, align_mask_dst))); + ~(_Max(align_mask_src, align_mask_dst))); __KTRACE_OPT(KDMA, Kern::Printf("max_aligned_len: %d", max_aligned_len)); // Client and PSL sane? __DMA_ASSERTD(max_aligned_len > 0); @@ -1235,8 +1233,8 @@ break; } // Compute fragment size - TUint c = Min(aMaxTransferLen, aCount); - __KTRACE_OPT(KDMA, Kern::Printf("c = Min(aMaxTransferLen, aCount) = %d", c)); + TUint c = _Min(aMaxTransferLen, aCount); + __KTRACE_OPT(KDMA, Kern::Printf("c = _Min(aMaxTransferLen, aCount) = %d", c)); // SRC if (mem_src && !(src.iFlags & KDmaMemIsContiguous)) @@ -1422,8 +1420,8 @@ break; } // Compute fragment size - TUint c = Min(aMaxTransferLen, aCount); - __KTRACE_OPT(KDMA, Kern::Printf("c = Min(aMaxTransferLen, aCount) = %d", c)); + TUint c = _Min(aMaxTransferLen, aCount); + __KTRACE_OPT(KDMA, Kern::Printf("c = _Min(aMaxTransferLen, aCount) = %d", c)); if (mem_src && !(src.iFlags & KDmaMemIsContiguous)) { @@ -1536,8 +1534,8 @@ break; } // Compute fragment size - TUint c = Min(aMaxTransferLen, aCount); - __KTRACE_OPT(KDMA, Kern::Printf("c = Min(aMaxTransferLen, aCount) = %d", c)); + TUint c = _Min(aMaxTransferLen, aCount); + __KTRACE_OPT(KDMA, Kern::Printf("c = _Min(aMaxTransferLen, aCount) = %d", c)); if (mem_dst && !(dst.iFlags & KDmaMemIsContiguous)) { @@ -1642,7 +1640,7 @@ // Max aligned length is used to make sure the beginnings of subtransfers // (i.e. fragments) are correctly aligned. const TUint max_aligned_len = (aMaxTransferLen & - ~(Max(align_mask_src, align_mask_dst))); + ~(_Max(align_mask_src, align_mask_dst))); __KTRACE_OPT(KDMA, Kern::Printf("max_aligned_len: %d", max_aligned_len)); // Client and PSL sane? __DMA_ASSERTD(max_aligned_len > 0); @@ -1724,8 +1722,8 @@ } __DMA_ASSERTD(iSrcDesCount == iDstDesCount); // Compute fragment size - TUint c = Min(aMaxTransferLen, aCount); - __KTRACE_OPT(KDMA, Kern::Printf("c = Min(aMaxTransferLen, aCount) = %d", c)); + TUint c = _Min(aMaxTransferLen, aCount); + __KTRACE_OPT(KDMA, Kern::Printf("c = _Min(aMaxTransferLen, aCount) = %d", c)); // SRC if (mem_src && !(src.iFlags & KDmaMemIsContiguous)) @@ -2815,7 +2813,7 @@ void TDmaChannel::DoQueue(const DDmaRequest& /*aReq*/) { // Must be overridden - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); } @@ -2834,7 +2832,7 @@ // To make sure this version of the function isn't called for channels for // which it isn't appropriate (and which therefore don't override it) we // put this check in here. - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); } @@ -2844,7 +2842,7 @@ // To make sure this version of the function isn't called for channels for // which it isn't appropriate (and which therefore don't override it) we // put this check in here. - __DMA_CANT_HAPPEN(); + __DMA_UNREACHABLE_DEFAULT(); } diff -r a5496987b1da -r 189ece41fa29 kernel/eka/drivers/iic/iic.cpp --- a/kernel/eka/drivers/iic/iic.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/drivers/iic/iic.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -26,6 +26,10 @@ // Global Controller pointer static DIicBusController* TheController = NULL; +#ifdef IIC_SIMULATED_PSL +DIicBusController*& gTheController = TheController; +#endif + // // Implementation of generic IicBus API for client interface // @@ -1014,63 +1018,8 @@ #endif -#ifdef IIC_SIMULATED_PSL -TVersion DIicPdd::VersionRequired() - { - const TInt KIicMajorVersionNumber=1; - const TInt KIicMinorVersionNumber=0; - const TInt KIicBuildVersionNumber=KE32BuildVersionNumber; - return TVersion(KIicMajorVersionNumber,KIicMinorVersionNumber,KIicBuildVersionNumber); - } - -/** Factory class constructor */ -DIicPdd::DIicPdd() - { - iVersion = DIicPdd::VersionRequired(); - } - -DIicPdd::~DIicPdd() - { - delete TheController; - } - -TInt DIicPdd::Install() - { - return(SetName(&KPddName)); - } +#ifndef IIC_SIMULATED_PSL -/** Called by the kernel's device driver framework to create a Physical Channel. */ -TInt DIicPdd::Create(DBase*& /*aChannel*/, TInt /*aUint*/, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/) - { - return KErrNone; - } - -/** Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.*/ -TInt DIicPdd::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer) - { - if (!Kern::QueryVersionSupported(DIicPdd::VersionRequired(),aVer)) - return(KErrNotSupported); - return KErrNone; - } - -/** Return the driver capabilities */ -void DIicPdd::GetCaps(TDes8& aDes) const - { - // Create a capabilities object - TCaps caps; - caps.iVersion = iVersion; - // Zero the buffer - TInt maxLen = aDes.MaxLength(); - aDes.FillZ(maxLen); - // Copy cpabilities - TInt size=sizeof(caps); - if(size>maxLen) - size=maxLen; - aDes.Copy((TUint8*)&caps,size); - } -#endif - -#ifndef IIC_SIMULATED_PSL // Client interface entry point DECLARE_EXTENSION_WITH_PRIORITY(KExtensionMaximumPriority-1) // highest priority after Resource Manager { @@ -1080,26 +1029,6 @@ TInt r=TheController->Create(); return r; } -#else -static DIicPdd* TheIicPdd; - -DECLARE_STANDARD_PDD() - { - TheController = new DIicBusController; - if(!TheController) - return NULL; - TInt r = TheController->Create(); - if(r == KErrNone) - { - TheIicPdd = new DIicPdd; - if(TheIicPdd) - return TheIicPdd; - } - - delete TheController; - return NULL; - } #endif - diff -r a5496987b1da -r 189ece41fa29 kernel/eka/drivers/resourceman/resourcecontrol.cpp --- a/kernel/eka/drivers/resourceman/resourcecontrol.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/drivers/resourceman/resourcecontrol.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2007-2010 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" @@ -403,6 +403,9 @@ //If dyanmic resource is deregistering, send notification to all clients requested for it if((pN->iCallback.iResourceId & KIdMaskDynamic) && (aClientId == KDynamicResourceDeRegistering)) { + pN->iCallback.iResult=aReturnCode; + pN->iCallback.iMutex = iResourceMutex; + pN->iCallback.iPendingRequestCount++; pN->iCallback.iResult = aReturnCode; pN->iCallback.iLevel = aState; pN->iCallback.iClientId = aClientId; @@ -418,14 +421,19 @@ (pN->iDirection && ((pN->iPreviousLevel < pN->iThreshold) && (aState >= pN->iThreshold))) || (!pN->iDirection && ((pN->iPreviousLevel > pN->iThreshold) && (aState <= pN->iThreshold)))) { - pN->iCallback.iResult=aReturnCode; - pN->iCallback.iLevel=aState; - pN->iCallback.iClientId = aClientId; + pN->iCallback.iResult=aReturnCode; + pN->iCallback.iMutex = iResourceMutex; + pN->iCallback.iPendingRequestCount++; + pN->iCallback.iLevel=aState; + pN->iCallback.iClientId = aClientId; pN->iCallback.iLevelOwnerId = aLevelOwnerId; + __KTRACE_OPT(KRESMANAGER, Kern::Printf("Notifications ClientId = 0x%x, ResourceId = %d, State = %d, Result = %d", pN->iCallback.iClientId, pN->iCallback.iResourceId, aState, aReturnCode)); PRM_POSTNOTIFICATION_SENT_TRACE - pN->iCallback.Enque(); + + pN->iCallback.Enque(); + } pN->iPreviousLevel = aState; //Update the state } @@ -708,6 +716,8 @@ TPowerResourceCb* pCb = aReq->ResourceCb(); if(pCb) { + pCb->iMutex = pRC->iResourceMutex; + pCb->iPendingRequestCount++; pCb->iResult=aReq->ReturnCode(); pCb->iLevel=aReq->Level(); pCb->iResourceId=aReq->ResourceId(); @@ -781,6 +791,8 @@ TPowerResourceCb* pCb = aReq->ResourceCb(); if(pCb) { + pCb->iMutex = pRC->iResourceMutex; + pCb->iPendingRequestCount++; pCb->iResult=aReq->ReturnCode(); pCb->iLevel=aReq->Level(); pCb->iResourceId=aReq->ResourceId(); @@ -2475,8 +2487,29 @@ #endif //Return if the resource is already in that state and client is also the same. if((aNewState == pR->iCachedLevel) && ((TInt)aClientId == pR->iLevelOwnerId)) - UNLOCK_RETURN(KErrNone); - + { + if(aCb) + { + //Invoke callback function + TUint ClientId = aClientId; + TUint ResourceId = aResourceId; + TInt Level = aNewState; + TInt LevelOwnerId = pR->iLevelOwnerId; + TInt Result = KErrNone; + TAny* Param = aCb->iParam; + aCb->iPendingRequestCount++; + UnLock(); + // Call the client specified callback function + aCb->iCallback(ClientId, ResourceId, Level, LevelOwnerId, Result, Param); + Lock(); + aCb->iPendingRequestCount--; + if(aCb->iPendingRequestCount == 0) + { + aCb->iResult = KErrCompletion; + } + } + UNLOCK_RETURN(KErrNone); + } PRM_CLIENT_CHANGE_STATE_START_TRACE //If long latency resource requested synchronously from DFC thread 0 Panic @@ -2616,16 +2649,29 @@ if(aResourceId & KIdMaskDynamic) ((DDynamicPowerResource*)pR)->UnLock(); #endif - UnLock(); if(aCb) { - //Invoke callback function - aCb->iCallback(req->ClientId(), aResourceId, req->Level(), pR->iLevelOwnerId, r, aCb->iParam); - //Mark the callback object to act properly during cancellation of this request. - aCb->iResult = KErrCompletion; - } + //Invoke callback function + TUint ClientId = req->ClientId(); + TUint ResourceId = aResourceId; + TInt Level = req->Level(); + TInt LevelOwnerId = pR->iLevelOwnerId; + TInt Result = r; + TAny* Param = aCb->iParam; + aCb->iPendingRequestCount++; + UnLock(); + // Call the client specified callback function + aCb->iCallback(ClientId, ResourceId, Level, LevelOwnerId, Result, Param); + Lock(); + aCb->iPendingRequestCount--; + if(aCb->iPendingRequestCount == 0) + { + aCb->iResult = KErrCompletion; + } + } + PRM_CLIENT_CHANGE_STATE_END_TRACE - return(r); + UNLOCK_RETURN(r); } } else if(pR->iLevelOwnerId == -1) @@ -2684,16 +2730,29 @@ if(aResourceId & KIdMaskDynamic) ((DDynamicPowerResource*)pR)->UnLock(); #endif - UnLock(); if(aCb) { - //Invoke callback function - aCb->iCallback(req->ClientId(), aResourceId, req->Level(), pR->iLevelOwnerId, r, aCb->iParam); - aCb->iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request. + //Invoke callback function + TUint ClientId = req->ClientId(); + TUint ResourceId = aResourceId; + TInt Level = req->Level(); + TInt LevelOwnerId = pR->iLevelOwnerId; + TInt Result = r; + TAny* Param = aCb->iParam; + aCb->iPendingRequestCount++; + UnLock(); + // Call the client specified callback function + aCb->iCallback(ClientId, ResourceId, Level, LevelOwnerId, Result, Param); + Lock(); + aCb->iPendingRequestCount--; + if(aCb->iPendingRequestCount == 0) + { + aCb->iResult = KErrCompletion; + } } __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::ChangeResourceState, Level = %d", req->Level())); PRM_CLIENT_CHANGE_STATE_END_TRACE - return r; + UNLOCK_RETURN(r); } /** @@ -2915,14 +2974,28 @@ PRM_RESOURCE_GET_STATE_START_TRACE if(aCached) //Call the callback directly { - UnLock(); - aCb.iCallback(aClientId, aResourceId, pR->iCachedLevel, pR->iLevelOwnerId, KErrNone, aCb.iParam); - aCb.iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request. + //Invoke callback function + TUint ClientId = aClientId; + TUint ResourceId = aResourceId; + TInt Level = pR->iCachedLevel; + TInt LevelOwnerId = pR->iLevelOwnerId; + TInt Result = KErrNone; + TAny* Param = aCb.iParam; + aCb.iPendingRequestCount++; + UnLock(); + // Call the client specified callback function + aCb.iCallback(ClientId, ResourceId, Level, LevelOwnerId, Result, Param); + Lock(); + aCb.iPendingRequestCount--; + if(aCb.iPendingRequestCount == 0) + { + aCb.iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request. + } #ifdef PRM_INSTRUMENTATION_MACRO TInt aState = pR->iCachedLevel; PRM_RESOURCE_GET_STATE_END_TRACE #endif - return(KErrNone); + UNLOCK_RETURN(KErrNone); } TPowerRequest* req=NULL; if(pR->LatencyGet()) @@ -2987,10 +3060,25 @@ if(aResourceId & KIdMaskDynamic) ((DDynamicPowerResource*)pR)->UnLock(); #endif - UnLock(); - // Call the client callback function directly as it is already executing in the context of client thread. - aCb.iCallback(aClientId, aResourceId, req->Level(), pR->iLevelOwnerId, r, aCb.iParam); - aCb.iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request. + + //Invoke callback function + TUint ClientId = aClientId; + TUint ResourceId = aResourceId; + TInt Level = req->Level(); + TInt LevelOwnerId = pR->iLevelOwnerId; + TInt Result = r; + TAny* Param = aCb.iParam; + aCb.iPendingRequestCount++; + UnLock(); + // Call the client specified callback function + aCb.iCallback(ClientId, ResourceId, Level, LevelOwnerId, Result, Param); + Lock(); + aCb.iPendingRequestCount--; + if(aCb.iPendingRequestCount == 0) + { + aCb.iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request. + } + UnLock(); } __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetResourceState(asynchronous), Level = %d", req->Level())); if(pR->LatencyGet()) diff -r a5496987b1da -r 189ece41fa29 kernel/eka/ewsrv/ky_capt.cpp --- a/kernel/eka/ewsrv/ky_capt.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/ewsrv/ky_capt.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -1,4 +1,4 @@ -// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 1996-2010 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" @@ -41,6 +41,10 @@ iCKarray.Close(); } +/** +@note This function can Leave and does not obey the +coding standard +*/ void CCaptureKeys::CheckCaptureKey(const TCaptureKey& aCaptureKey) { @@ -69,6 +73,10 @@ User::LeaveIfError(iCKarray.Insert(captureKey,0)); } +/** +@note This function can Leave and does not obey the +coding standard +*/ EXPORT_C void CCaptureKeys::SetCaptureKey(TUint32 aHandle, const TCaptureKey& aCaptureKey) // // Finds the first capture-key from the list that matches the handle and sets @@ -79,6 +87,10 @@ SetCaptureKey(aHandle,aCaptureKey,0); } +/** +@note This function can Leave and does not obey the +coding standard +*/ EXPORT_C void CCaptureKeys::SetCaptureKey(TUint32 aHandle, const TCaptureKey& aCaptureKey, TUint8 aPriority) // // Finds the first capture-key from the list that matches the handle and sets @@ -96,15 +108,6 @@ iCKarray[r]=captureKey; } -void CCaptureKeys::removeCaptureKey(TUint aIndex) -// -// Removes the capture-key at the given aIndex from the list -// - { - - iCKarray.Remove(aIndex); - } - EXPORT_C void CCaptureKeys::CancelCaptureKey(TUint32 aHandle) // // Removes the first capture-key from the list that matches the handle; diff -r a5496987b1da -r 189ece41fa29 kernel/eka/ewsrv/ky_tran.cpp --- a/kernel/eka/ewsrv/ky_tran.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/ewsrv/ky_tran.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -1,4 +1,4 @@ -// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 1996-2010 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" @@ -23,8 +23,21 @@ #include #include -enum {EDummy,EKeyDataConv,EKeyDataFunc,EKeyDataSettings}; - +/** +Ordinals of the functions which keymap dlls export. + +@note These values depend on the ordering of the exports. +If the existing def files were ever re-frozen, it would +lead to a runtime error. +*/ +enum + { + EDummy, + EKeyDataConv, ///< Access conversion tables, signature TLibFnDataConv + EKeyDataFunc, ///< Access function tables, signature TLibFnDataFunc + EKeyDataSettings ///< Access data needed for control code entry @see TCtrlDigits, signature TLibFnDataSetting + }; + EXPORT_C CKeyTranslator* CKeyTranslator::New() // // Return the actual key translator @@ -482,7 +495,9 @@ // typedef void (*TLibFnDataConv)(SConvTable &aConvTable, TUint &aConvTableFirstScanCode,TUint &aConvTableLastScanCode, SScanCodeBlockList &aKeypadScanCode,SKeyCodeList &aNonAutorepKeyCodes); -// +/** +Populates the object with conversion table data from aLibrary +*/ void TConvTable::Update(RLibrary aLibrary) #pragma warning (disable: 4705) { diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/d32camerasc.h --- a/kernel/eka/include/d32camerasc.h Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,711 +0,0 @@ -// Copyright (c) 2008-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: -// e32\include\d32camerasc.h -// User side class definition for the shared chunk camera driver. -// -// - -/** - @file - @internalAll - @prototype -*/ - -#ifndef __D32CAMERASC_H__ -#define __D32CAMERASC_H__ - -#include -#include -#include - -_LIT(KDevCameraScName,"CameraSc"); - -/** -Camera capability constants - bitmasks of possible flash modes. @see TCameraCapsV02. -*/ -/** Flash will automatically fire when required. */ -const TUint KCamFlashAuto = 0x0001; -/** Flash will always fire. */ -const TUint KCamFlashForced = 0x0002; -/** Reduced flash for general lighting */ -const TUint KCamFlashFillIn = 0x0004; -/** Red-eye reduction mode. */ -const TUint KCamFlashRedEyeReduce = 0x0008; -/** Flash at the moment when shutter opens. */ -const TUint KCamFlashSlowFrontSync = 0x0010; -/** Flash at the moment when shutter closes. */ -const TUint KCamFlashSlowRearSync = 0x0020; -/** User configurable setting */ -const TUint KCamFlashManual = 0x0040; - -/** -Camera capability constants - bitmasks of possible exposure modes. @see TCameraCapsV02. -*/ -/** Night-time setting for long exposures. */ -const TUint KCamExposureNight = 0x0001; -/** Backlight setting for bright backgrounds. */ -const TUint KCamExposureBacklight = 0x0002; -/** Centered mode for ignoring surroundings. */ -const TUint KCamExposureCenter = 0x0004; -/** Sport setting for very short exposures. */ -const TUint KCamExposureSport = 0x0008; -/** Generalised setting for very long exposures. */ -const TUint KCamExposureVeryLong = 0x0010; -/** Snow setting for daylight exposure. */ -const TUint KCamExposureSnow = 0x0020; -/** Beach setting for daylight exposure with reflective glare. */ -const TUint KCamExposureBeach = 0x0040; -/** Programmed exposure setting. */ -const TUint KCamExposureProgram = 0x0080; -/** Aperture setting is given priority. */ -const TUint KCamExposureAperturePriority = 0x0100; -/** Shutter speed setting is given priority. */ -const TUint KCamExposureShutterPriority = 0x0200; -/** User selectable exposure value setting. */ -const TUint KCamExposureManual = 0x0400; -/** Exposure night setting with colour removed to get rid of colour noise. */ -const TUint KCamExposureSuperNight = 0x0800; -/** Exposure for infra-red sensor on the camera */ -const TUint KCamExposureInfra = 0x1000; - -/** -Camera capability constants - bitmasks of possible white balance modes. @see TCameraCapsV02. -*/ -/** Normal daylight. */ -const TUint KCamWBDaylight = 0x0001; -/** Overcast daylight. */ -const TUint KCamWBCloudy = 0x0002; -/** Tungsten filament lighting. */ -const TUint KCamWBTungsten = 0x0004; -/** Fluorescent tube lighting */ -const TUint KCamWBFluorescent = 0x0008; -/** Flash lighting. */ -const TUint KCamWBFlash = 0x0010; -/** High contrast daylight primarily snowy */ -const TUint KCamWBSnow = 0x0020; -/** High contrast daylight primarily near the sea */ -const TUint KCamWBBeach = 0x0040; -/** User configurable mode */ -const TUint KCamWBManual = 0x0080; - -/** -Camera capability constants - bitmasks of other miscellaneous camera capabilities supported. @see TCameraCapsV02. -*/ -/** The camera has zoom capability. */ -const TUint KCamMiscZoom = 0x0001; -/** The camera supports contrast adjustment. */ -const TUint KCamMiscContrast = 0x0002; -/** The camera supports brightness adjustment. */ -const TUint KCamMiscBrightness = 0x0004; -/** The camera supports color effect adjustment. */ -const TUint KCamMiscColorEffect = 0x0008; - - -/** -Enumeration of capture modes in which to run the sensor. -*/ -enum TDevCamCaptureMode - { - /** Used to specify that still image mode is to be used. */ - ECamCaptureModeImage, - /** Used to specify that streaming video mode is to be used. */ - ECamCaptureModeVideo, - /** Used to specify that streaming viewfinder mode is to be used. */ - ECamCaptureModeViewFinder, - /** The last value here, helps keep track of the number of capture modes. */ - ECamCaptureModeMax - }; - -/** -Enumeration of camera flash modes. @see TCameraConfigV02. -*/ -enum TDevCamFlashMode - { - /** No flash, always supported. */ - ECamFlashNone=0x0000, - /** Flash will automatically fire when required. */ - ECamFlashAuto=0x0001, - /** Flash will always fire. */ - ECamFlashForced=0x0002, - /** Reduced flash for general lighting */ - ECamFlashFillIn=0x0004, - /** Red-eye reduction mode. */ - ECamFlashRedEyeReduce=0x0008, - /** Flash at the moment when shutter opens. */ - ECamFlashSlowFrontSync=0x0010, - /** Flash at the moment when shutter closes. */ - ECamFlashSlowRearSync=0x0020, - /** User configurable setting */ - ECamFlashManual=0x0040 - }; - -/** -Enumeration of camera exposure modes. @see TCameraConfigV02. -*/ -enum TDevCamExposureMode - { - /** Set exposure automatically. Default, always supported. */ - ECamExposureAuto=0x0000, - /** Night-time setting for long exposures. */ - ECamExposureNight=0x0001, - /** Backlight setting for bright backgrounds. */ - ECamExposureBacklight=0x0002, - /** Centered mode for ignoring surroundings. */ - ECamExposureCenter=0x0004, - /** Sport setting for very short exposures. */ - ECamExposureSport=0x0008, - /** Generalised setting for very long exposures. */ - ECamExposureVeryLong=0x0010, - /** Snow setting for daylight exposure. */ - ECamExposureSnow=0x0020, - /** Beach setting for daylight exposure with reflective glare. */ - ECamExposureBeach=0x0040, - /** Programmed exposure setting. */ - ECamExposureProgram=0x0080, - /** Aperture setting is given priority. */ - ECamExposureAperturePriority=0x0100, - /** Shutter speed setting is given priority. */ - ECamExposureShutterPriority=0x0200, - /** User selectable exposure value setting. */ - ECamExposureManual=0x0400, - /** Exposure night setting with colour removed to get rid of colour noise. */ - ECamExposureSuperNight=0x0800, - /** Exposure for infra-red sensor on the camera */ - ECamExposureInfra=0x1000 - }; - -/** -Enumeration of camera white balance modes. @see TCameraConfigV02. -*/ -enum TDevCamWhiteBalanceMode - { - /** Set white balance automatically. Default, always supported. */ - ECamWBAuto=0x0000, - /** Normal daylight. */ - ECamWBDaylight=0x0001, - /** Overcast daylight. */ - ECamWBCloudy=0x0002, - /** Tungsten filament lighting. */ - ECamWBTungsten=0x0004, - /** Fluorescent tube lighting */ - ECamWBFluorescent=0x0008, - /** Flash lighting. */ - ECamWBFlash=0x0010, - /** High contrast daylight primarily snowy */ - ECamWBSnow=0x0020, - /** High contrast daylight primarily near the sea */ - ECamWBBeach=0x0040, - /** User configurable mode */ - ECamWBManual=0x0080 - }; - -/** -Enumeration of possible directions in which the camera may point. @see TCameraCapsV02. -*/ -enum TDevCamOrientation - { - /** Outward pointing camera for taking pictures. Camera is directed away from the user. */ - ECamOrientationOutwards, - /** Inward pointing camera for conferencing. Camera is directed towards the user. */ - ECamOrientationInwards, - /** Mobile camera capable of multiple orientations. Camera orientation may be changed by the user. */ - ECamOrientationMobile, - /** Camera orientation is not known. */ - ECamOrientationUnknown - }; - -/** -Each item in the iPixelFormatSupported array is represented by an instance of this structure. -*/ -struct SDevCamPixelFormat - { - /** The UID of the pixel format supported */ - TUidPixelFormat iPixelFormat; - /** The number of frame sizes represented by the pixel format. */ - TUint iNumFrameSizes; - /** The pixel width in number of bytes */ - TUint iPixelWidthInBytes; - }; - -/** -Each frame size supported is represented by an instance of this structure. -*/ -struct SDevCamFrameSize - { - /** Width of the frame in pixels. */ - TUint iWidth; - /** Height of the frame in pixels. */ - TUint iHeight; - /** Minimum frame rate supported by this frame size. */ - TUint iMinFrameRate; - /** Maximum frame rate supported by this frame size. */ - TUint iMaxFrameRate; - }; - -/** -Lets us associate buffers to their mode when working out the buffer offset in a chunk. -**/ -class TDevCamBufferModeAndId - { -public: - TDevCamCaptureMode iCaptureMode; - TInt iId; - }; -typedef TPckgBuf TDevCamBufferModeAndIdBuf; - -/** -The general driver capabilites class - returned by the LDD factory in response to RDevice::GetCaps(). -*/ -class TCapsDevCameraV01 - { -public: - TVersion iVersion; - }; - -/** -Defines a list of settings that are changable often (dynamically) within a single use of the device. -*/ -enum TDevCamDynamicAttribute - { - ECamAttributeBrightness, - ECamAttributeContrast, - ECamAttributeColorEffect, - ECamAttributeMax - }; - -/** -Holds the range and interval (rate of change) values for a dynamic capability. -An array of these would be indexed by TDevCamDynamicAttribute -*/ -struct TDynamicRange - { - TUint iMin; - TUint iMax; - TUint iDefault; - }; - -/** -The main camera capabilities class. This is used to get the capabilities of a specific camera -device once a channel to it has been opened. -*/ -class TCameraCapsV02 - { -public : - /** The flash modes supported - a bit field. */ - TUint iFlashModes; - /** The exposure modes supported - a bit field. */ - TUint iExposureModes; - /** The white balance modes supported - a bit field. */ - TUint iWhiteBalanceModes; - /** The orientation of the camera device. */ - TDevCamOrientation iOrientation; - /** The minimum value that may be set for the zoom factor. Must be negative or zero. Negative values - represent macro functionality. @see TCameraCapsV02::iCapsMisc. @see TCameraConfigV02::iZoom. */ - TUint iMinZoom; - /** The maximum value that may be set for the zoom factor. Must be positive or zero. - @see TCameraCapsV02::iCapsMisc. @see TCameraConfigV02::iZoom. */ - TUint iMaxZoom; - /** Whether other miscellaneous capabilities are supported - a bitfield. These - capabilities include whether the device supports simultaneous capture modes, zoom capabilities, contrast - adjustment, brightness, and color effect adjustment. */ - TUint iCapsMisc; - /** Number of pixel formats supported in still image capture mode. - Will be set to 0 if image capture is not supported. */ - TUint iNumImagePixelFormats; - /** Number of pixel formats supported in video capture mode. - Will be set to 0 if image capture is not supported. */ - TUint iNumVideoPixelFormats; - /** Number of pixel formats supported in view finder capture mode. - Will be set to 0 if image capture is not supported. */ - TUint iNumViewFinderPixelFormats; - - /** An array specifying the range in values for settings as defined by TDevCamDynamicAttribute. - Indices for settings are in the order defined in TDevCamDynamicAttribute. - If the setting is not supported then the entry is still present for performance reasons, - i.e. indexing over searching. - @see TDevCamDynamicAttribute - @see TDynamicRange - */ - TDynamicRange iDynamicRange[ECamAttributeMax]; - - /** A variable length array specifying the pixel formats supported by the sensor. - The size of the TCameraCapsV02 structure is determined by each sensor's capabilities - thus the array of supported pixel formats is of variable length. It is stored in memory - exactly after TCameraCapsV02 whenever memory is allocated for it and the array cannot be - accessed by a private member. - SDevCamPixelFormat iPixelFormatsSupported[]; - */ - }; - -typedef TPckgBuf TCameraCapsV02Buf; - -/** -The camera configuration class. This is used to get and set the current -configuration of the camera. @see SDevCamFrameSize and @see SDevCamPixelFormat. -*/ -class TCameraConfigV02 - { -public: - /** The size of the image to get from the sensor. */ - SDevCamFrameSize iFrameSize; - /** The pixel format (RGB, YUV, RGB Bayer etc). */ - SDevCamPixelFormat iPixelFormat; - /** The frame rate (in frame/s). */ - TUint iFrameRate; - /** The flash mode setting. */ - TDevCamFlashMode iFlashMode; - /** The exposure mode setting. */ - TDevCamExposureMode iExposureMode; - /** The white balance mode setting. */ - TDevCamWhiteBalanceMode iWhiteBalanceMode; - /** The zoom factor. Can be zero, positive or negative, Negative values represent macro functionality.*/ - TInt iZoom; - /** Specifies the number of bytes used to store one pixel's worth of data. */ - TInt iPixelWidthInBytes; - }; -typedef TPckgBuf TCameraConfigV02Buf; - -/** A structure used to assemble arguments for the function RDevCameraSc::SetBufConfigChunkOpen() and to pass -these to the driver. */ -struct SSetBufConfigChunkOpenInfo - { - const TDesC8* iBufferConfigBuf; - TInt iChunkHandle; - }; - -/** A structure used to assemble arguments for the function RDevCameraSc::FrameSizeCaps() and to pass -these to the driver. */ -struct SFrameSizeCapsInfo - { - TUidPixelFormat iUidPixelFormat; - TDevCamCaptureMode iCaptureMode; - }; - -/** -The camera device driver API supporting shared chunks. This is the principle interface to communicate with -an attached camera. -*/ -class RDevCameraSc : public RBusLogicalChannel - { -public: - enum TRequest - /** - Asynchronous request types - */ - { - EMsgRequestMax=3, // All requests less than this value are handled in the driver DFC thread. - ERequestNotifyNewImage, - ENumRequests, - EAllRequests = (1< - -#endif // __D32CAMERASC_H__ diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/d32camerasc.inl --- a/kernel/eka/include/d32camerasc.inl Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,222 +0,0 @@ -// Copyright (c) 2006-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: -// e32\include\d32camerasc.inl -// -// - -inline TVersion RDevCameraSc::VersionRequired() - { - const TInt KCameraMajorVersionNumber=1; - const TInt KCameraMinorVersionNumber=0; - const TInt KCameraBuildVersionNumber=KE32BuildVersionNumber; - return TVersion(KCameraMajorVersionNumber,KCameraMinorVersionNumber,KCameraBuildVersionNumber); - } - -#ifndef __KERNEL_MODE__ - - -inline RDevCameraSc::RDevCameraSc() -: RBusLogicalChannel() - { - iCameraCaps = NULL; - iCapsSize = 0; - } - -inline TInt RDevCameraSc::Open(TInt aUnit) - { - TInt r=DoCreate(KDevCameraScName,VersionRequired(),aUnit,NULL,NULL,EOwnerThread); - if (KErrNone == r) - { - // Obtain the Capability structure size then allocate memory for it on client side - r=iCapsSize=DoControl(EControlCapsSize); - if (KErrNone > r) - { - iCapsSize = 0; - return r; - } - - TAny* capsBufPtr = User::Alloc(iCapsSize); - if(NULL == capsBufPtr) - { - Close(); - return KErrNoMemory; - } - - TPtr8 capsPtr((TUint8*)capsBufPtr, iCapsSize, iCapsSize); - // Fill the Capability structure - r = DoControl(EControlCaps,(TAny*)&capsPtr); - if (KErrNone > r) - { - iCapsSize = 0; - return r; - } - iCameraCaps = (TCameraCapsV02*) capsPtr.Ptr(); - } - - return r; - } - -inline void RDevCameraSc::Close() - { - if (iCameraCaps != NULL) - { - User::Free(iCameraCaps); - iCameraCaps = NULL; - } - iCapsSize = 0; - RBusLogicalChannel::Close(); - } - -inline TInt RDevCameraSc::Caps(TDes8& aCapsBuf) - { - if (aCapsBuf.MaxLength() < iCapsSize) - { - return KErrArgument; - } - - TPtrC8 ptr ((TUint8*)iCameraCaps, iCapsSize); - aCapsBuf = ptr; - return KErrNone; - } - -inline TPtrC8 RDevCameraSc::Caps() - { - TPtrC8 ptr((TUint8*)iCameraCaps, iCapsSize); - return ptr; - } - -inline TInt RDevCameraSc::SetBufConfigChunkCreate(TDevCamCaptureMode aCaptureMode, TInt aNumBuffers, RChunk& aChunk) - {return(aChunk.SetReturnedHandle(DoControl(EControlSetBufConfigChunkCreate,(TAny*)aCaptureMode,(TAny*)aNumBuffers)));} - -inline TInt RDevCameraSc::SetBufConfigChunkOpen(TDevCamCaptureMode aCaptureMode, const TDesC8& aBufferConfigBuf, RChunk& aChunk) - { - SSetBufConfigChunkOpenInfo info = {&aBufferConfigBuf, aChunk.Handle()}; - return(DoControl(EControlSetBufConfigChunkOpen,(TAny*)aCaptureMode,&info)); - } - -inline TInt RDevCameraSc::ChunkClose(TDevCamCaptureMode aCaptureMode) - {return(DoControl(EControlChunkClose,(TAny*)aCaptureMode));} - -inline TInt RDevCameraSc::SetCamConfig(TDevCamCaptureMode aCaptureMode,const TDesC8& aConfigBuf) - {return(DoControl(EControlSetCamConfig,(TAny*)aCaptureMode,(TAny*)&aConfigBuf));} - -inline void RDevCameraSc::GetCamConfig(TDevCamCaptureMode aCaptureMode, TDes8& aConfigBuf) - {DoControl(EControlGetCamConfig,(TAny*)aCaptureMode,(TAny*)&aConfigBuf);} - -inline void RDevCameraSc::GetBufferConfig(TDevCamCaptureMode aCaptureMode, TDes8& aConfigBuf) - {DoControl(EControlGetBufferConfig,(TAny*)aCaptureMode,(TAny*)&aConfigBuf);} - -inline TInt RDevCameraSc::SetCaptureMode(TDevCamCaptureMode aCaptureMode) - {return(DoControl(EControlSetCaptureMode,(TAny*)aCaptureMode));} - -inline TInt RDevCameraSc::Start() - {return(DoControl(EControlStart));} - -inline TInt RDevCameraSc::Stop() - {return(DoControl(EControlStop));} - -inline void RDevCameraSc::NotifyNewImage(TRequestStatus& aStatus) - {DoRequest(ERequestNotifyNewImage,aStatus);} - -inline void RDevCameraSc::NotifyNewImageCancel() - {DoCancel(1<iCapsMisc & mask ? KErrNone : KErrNotSupported); - } - -// -// -// -inline TInt RDevCameraSc::SetDynamicAttribute(TDevCamDynamicAttribute aAttribute, TUint aValue) - { - TInt err = CheckAttributeSupported(aAttribute); - if (err == KErrNone) - { - err = KErrArgument; - TDynamicRange &range = iCameraCaps->iDynamicRange[aAttribute]; - if ((aValue >= range.iMin) && (aValue <= range.iMax)) - { - err = DoControl(EControlSetDynamicAttribute, (TAny*)aAttribute, (TAny*)aValue); - } - } - - return err; - } - -// -// -// -inline TInt RDevCameraSc::GetDynamicAttribute(TDevCamDynamicAttribute aAttribute, TUint& aValue) - { - TInt err = CheckAttributeSupported(aAttribute); - if (err == KErrNone) - { - err = DoControl(EControlGetDynamicAttribute, (TAny*)aAttribute, (TAny*)&aValue); - } - - return err; - } -#endif // __KERNEL_MODE__ diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/drivers/camerasc.h --- a/kernel/eka/include/drivers/camerasc.h Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,460 +0,0 @@ -// Copyright (c) 2004-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: -// e32\include\drivers\camerasc.h -// -// - -/** - @file - @internalAll - @prototype -*/ - -#ifndef __CAMERASC_H__ -#define __CAMERASC_H__ - -#include -#include -#include -#include - -/** The default number of buffers available to the client. */ -const TInt KDefaultNumClientBuffers=6; - -/** The maximum number of client capture requests which may be outstanding at any time. */ -const TInt KMaxCamScRequestsPending=8; - -/** -@internalAll -@prototype -*/ -struct SBufSpecList - { - /** The first entry of the buffer offset list. This list holds the offset from the start of the chunk - for each buffer. This list is only valid if the flag KScFlagBufOffsetListInUse is set in - TSharedChunkBufConfigBase::iFlags. */ - TInt iBufferOffset; - TInt iBufferId; - }; - -/** -@internalAll -@prototype -*/ -class TCameraSharedChunkBufConfig : public TSharedChunkBufConfigBase - { -public: - struct SBufSpecList iSpec; - }; - -// Forward declarations -class TImageBuffer; -class DCameraScLdd; -class DBufferManager; - -/** -The physical device driver (PDD) base class for the camera driver. -@internalAll -@prototype -*/ -class DCameraScPdd : public DBase - { -public: - /** - Return the DFC queue to be used by this device. - @param aUnit The unit number for which to get the DFC queue. - @return The DFC queue to use. - */ - virtual TDfcQue* DfcQ(TInt aUnit)=0; - - /** - Return the capabilities of this camera device. - @param aCapsBuf A packaged TCameraCapsV02 object to be filled with the capabilities of the - device. This descriptor is in kernel memory and can be accessed directly. - @see TCameraCapsV02. - */ - virtual void Caps(TDes8& aCapsBuf) const=0; - - /** - Return data format information for a custom camera data format setting. Only required where support is - required for a data format that isn't supported by the LDD. Platforms which don't require support - for custom data settings need not implement this method. - @param aConfigBuf A packaged TCameraConfigV02 object containing the current camera driver configuration - (including an identifier for the custom setting required). This configuration object should be - updated by the PDD with the appropriate settings for the data format concerned. This descriptor - is in kernel memory and can be accessed directly. - @return KErrNone if successful, otherwise one of the other system wide error codes. - */ - virtual TInt SpecifyCustomConfig(TDes8& aConfigBuf); - - /** - Return the shared chunk create information to be used by this device. - @param aChunkCreateInfo A chunk create info. object to be to be filled with the settings - required for this device. - */ - virtual void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo)=0; - - /** - Configure or reconfigure the device using the the configuration supplied. - @param aConfigBuf A packaged TCameraConfigV02 object which contains the new configuration settings. - This descriptor is in kernel memory and can be accessed directly. - @return KErrNone if successful, otherwise one of the other system wide error codes. - @see TCameraConfigV02. - */ - virtual TInt SetConfig(const TDesC8& aConfigBuf)=0; - - /** - Start the camera - start pixel sourcing. - @param aCaptureMode The capture mode to start. @see TDevCamCaptureMode. - @param aLinAddr The linear address of the start of the first buffer to use for image capture. - @param aPhysAddr The physical address that corresponds to the linear address: aLinAddr. - @return KErrNone if successful; - otherwise one of the other system wide error codes. - */ - virtual TInt Start(TDevCamCaptureMode aCaptureMode,TLinAddr aLinAddr,TPhysAddr aPhysAddr)=0; - - /** - Sets the address of the buffer into which the next image will be captured. - @param aLinAddr The linear address of the start of the buffer to use to capture the image frame. - @param aPhysAddr The physical address that corresponds to the linear address: aLinAddr. - @return KErrNone if the capture has been initiated successfully; - KErrNotReady if the device is unable to accept the request for the moment; - otherwise one of the other system-wide error codes. - */ - virtual TInt CaptureNextImage(TLinAddr aLinAddr,TPhysAddr aPhysAddr)=0; - - /** - Stop the camera - stop pixel sourcing. - @return KErrNone if successful, otherwise one of the other system wide error codes. - */ - virtual TInt Stop()=0; - - /** - Power down the camera. - */ - virtual void PowerDown()=0; - - /** - Queries the driver for the size of the structure to be passed to RDevCameraSc::Caps(). - */ - virtual TInt CapsSize()=0; - - /** - Returns the supported frame sizes that correspond to the desired capture mode and pixel format passed in. - @param aCaptureMode The capture mode for which to obtain the information. - @param aUidPixelFormat The pixel format for which to obtain the information. - @param aFrameSizeCapsBuf An appropriately sized buffer to be filled with the supported frame sizes. - @return KErrNone, if successful, - KErrArgument, if an invalid capture mode or pixel format is specified, or if aFrameSizeCapsBuf is too small; - otherwise one of the other system-wide error codes. - @see SDevCamFrameSize - */ - virtual TInt FrameSizeCaps(TDevCamCaptureMode aCaptureMode, TUidPixelFormat aUidPixelFormat, TDes8& aFrameSizeCapsBuf)=0; - - /** - Sets the sensor brightness to the desired setting. - - @param aValue A verified brightness setting. - @return KErrNone if successful, KErrNotSupported if not supported. - */ - virtual TInt SetBrightness(TUint aValue) = 0; - - // SYM_BRANCH: Add support for setting of Dynamic Attributes. Contrast. - /** - Sets the sensor contrast to the desired setting. - - @param aValue A verified contrast setting. - @return KErrNone if successful, KErrNotSupported if not supported. - */ - virtual TInt SetContrast(TUint aValue) = 0; - - // SYM_BRANCH: Add support for setting of Dynamic Attributes. Colour Effect. - /** - Sets the sensor color effect to the desired setting. - - @param aValue A verified color effect setting. - @return KErrNone if successful, KErrNotSupported if not supported. - */ - virtual TInt SetColorEffect(TUint aValue) = 0; - -public: - DCameraScLdd* iLdd; - }; - -/** -The logical device (factory class) for the camera driver. -*/ -class DCameraScLddFactory : public DLogicalDevice - { -public: - DCameraScLddFactory(); - virtual TInt Install(); - virtual void GetCaps(TDes8 &aDes) const; - virtual TInt Create(DLogicalChannelBase*& aChannel); - TBool IsUnitOpen(TInt aUnit); - TInt SetUnitOpen(TInt aUnit,TBool aIsOpenSetting); -private: - /** Mask to keep track of which units have a channel open on them. */ - TUint iUnitsOpenMask; - /** A mutex to protect access to the unit info. mask. */ - NFastMutex iUnitInfoMutex; - }; - -/** -The class representing a single image buffer. -*/ -class TImageBuffer : public SDblQueLink - { -public: - TImageBuffer(); - ~TImageBuffer(); - TInt Create(DChunk* aChunk,TInt aOffset,TInt aSize,TInt aId,TBool aIsContiguous); - void SyncMemoryBeforeDmaRead(); - void SyncMemoryAfterDmaRead(); -public: - /** The buffer id */ - TInt iId; - /** The chunk used for this buffer */ - DChunk* iChunk; - /** The offset, in bytes, of the start of the buffer within the chunk. */ - TInt iChunkOffset; - /** The size of the buffer in bytes. */ - TInt iSize; - /** The virtual address of buffer. */ - TLinAddr iLinearAddress; - /** The physical address of buffer. KPhysAddrInvalid if the buffer is not physically contiguous. */ - TPhysAddr iPhysicalAddress; - /** A list of physical addresses for buffer pages. 0 if the buffer is physically contiguous. */ - TPhysAddr* iPhysicalPages; - /** This is the result of the transfer into this buffer. */ - TInt iResult; - }; - -/** -An object encapsulating an image capture request from the client. -*/ -class TCameraScRequest : public SDblQueLink - { -public: - inline TCameraScRequest() - {} -public: - /** The request status associated with the request - used to signal completion of the request and pass back a - completion code. */ - TRequestStatus* iStatus; - }; - -/** -An object encapsulating a queue of image capture requests from the client. -*/ -class TCameraScRequestQueue - { -public: - TCameraScRequestQueue(NFastMutex* aMutexPtr); - ~TCameraScRequestQueue(); - TInt Create(DThread* anOwningThread); - TInt Add(TRequestStatus* aStatus); - TRequestStatus* Remove(); - void Cancel(TRequestStatus* aStatus); - void CancelAll(); - inline TBool IsEmpty(); -private: - /** The queue of pending capture requests. */ - SDblQue iPendRequestQ; - /** The queue of unused capture requests. */ - SDblQue iUnusedRequestQ; - /** The actual array of request objects. */ - TCameraScRequest* iRequest[KMaxCamScRequestsPending]; - NFastMutex* iMutexPtr; - DThread* iOwningThread; - }; - -/** -The buffer manager base class. -*/ -class DBufferManager : public DBase - { -public: - DBufferManager(DCameraScLdd* aLdd); - ~DBufferManager(); - TInt Create(TInt aNumBuffers,TInt aBufferSize); - TInt Create(TCameraSharedChunkBufConfig& aBufConfig,TInt aChunkHandle,DThread* anOwningThread); - void GetBufConfig(TCameraSharedChunkBufConfig& aBufConfig); - void Reset(); - void Purge(TImageBuffer* aBuffer); - TImageBuffer* GetImageForClient(TBool aRemoveLast); - TImageBuffer* SetImageCaptured(TInt aResult); - TInt ReleaseImage(TInt aChunkOffset); - TImageBuffer* NextAvailableForCapture(); - TImageBuffer* FindInUseImage(TInt aChunkOffset); -protected: - TInt CreateBufferLists(TInt aNumBuffers); - TInt CommitMemoryForBuffer(TInt aChunkOffset,TInt aSize,TBool& aIsContiguous); -protected: - /** The owning LDD object. */ - DCameraScLdd* iLdd; - /** The chunk which contains the buffers. */ - DChunk* iChunk; - /** The linear address in kernel process for the start of the chunk. */ - TLinAddr iChunkBase; - /**< MMU mapping attributes that the chunk has actually been mapped with. */ - TUint32 iChunkMapAttr; - /** The number of buffers. */ - TInt iNumBuffers; - /** The actual array of buffer objects. */ - TImageBuffer* iImageBuffer; - /** The buffer currently being filled by image capture. (Not in any list). */ - TImageBuffer* iCurrentBuffer; - /** The next buffer to use for image capture. (Not in any list). */ - TImageBuffer* iNextBuffer; - /** A queue of those buffers which are currently free. */ - SDblQue iFreeBufferQ; - /** A queue of those buffers which currently contain captured images (and which aren't being used by the client). */ - SDblQue iCompletedBufferQ; - /** A queue of those buffers which are currently being used by the client. */ - SDblQue iInUseBufferQ; -private: - friend class DCameraScLdd; - }; - -/** -The configuration class that is specific for each capture mode. This allows the driver to maintain different configurations, -one for each capture mode, and make switching between capture modes faster. -*/ -class TCaptureModeConfig - { - private: - /** The handle to the chunk that is returned to the user side code. */ - TInt iChunkHandle; - /** The current configuration of the capture mode */ - TCameraConfigV02 iCamConfig; - /** The current configuration of the chunk. */ - TCameraSharedChunkBufConfig* iBufConfig; - /** The size in bytes of the chunk configuration info. structure. */ - TInt iBufConfigSize; - /** The current frame height. */ - TInt iFrameHeight; - /** The current frame width. */ - TInt iFrameWidth; - /** The buffer manager. */ - DBufferManager* iBufManager; - private: - friend class DCameraScLdd; - }; - -/** -The camera driver power handler class. -*/ -class DCameraScPowerHandler : public DPowerHandler - { -public: - DCameraScPowerHandler(DCameraScLdd* aChannel); - // Inherited from DPowerHandler - void PowerUp(); - void PowerDown(TPowerState aPowerState); -private: - DCameraScLdd* iChannel; - }; - -/** -The logical channel class for the camera driver. -*/ -class DCameraScLdd : public DLogicalChannel - { -public: - enum TState - { - /** Channel open - but not configured. */ - EOpen, - /** Channel configured - but inactive. */ - EConfigured, - /** Channel is active - capturing images. */ - ECapturing - }; -public: - DCameraScLdd(); - virtual ~DCameraScLdd(); - // Inherited from DLogicalChannel - virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); - virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2); - virtual void HandleMsg(TMessageBase* aMsg); - virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType); - inline DThread* OwningThread(); - inline TInt CurrentFrameHeight(); - inline TInt CurrentFrameWidth(); - void Shutdown(); - virtual TInt ImageCaptureCallback(TDevCamCaptureMode aCaptureMode,TInt aResult,TLinAddr* aLinAddr,TPhysAddr* aPhysAddr); - virtual void PanicClientThread(TInt aReason); -private: - TInt DoControl(TInt aFunction, TAny* a1, TAny* a2); - TInt DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2); - TInt DoCancel(TUint aMask); - TInt SetCaptureMode(TInt aCaptureMode); - TInt SetCamConfig(TInt aCaptureMode, const TDesC8* aCamConfigBuf); - TInt SetBufConfig(TInt aCaptureMode, const TDesC8* aBufferConfigBuf,TInt aChunkHandle); - TInt SetBufConfig(TInt aCaptureMode, TInt aNumBuffers); - TInt ChunkClose(TInt aCaptureMode); - TInt Start(); - TInt NotifyNewImage(TRequestStatus* aStatus); - TInt ReleaseBuffer(TInt aChunkOffset); - TInt DoSetConfig(TInt aCaptureMode, const TDesC8* aCamConfigBuf); - TInt ValidateConfig(TInt aCaptureMode, TCameraConfigV02 &aConfig); - TInt DoValidateConfig(TCameraCapsV02* aCamCaps, TInt &aCaptureMode, TCameraConfigV02 &aConfig); - TInt DoStart(); - TInt ReAllocBufferConfigInfo(TInt aCaptureMode, TInt aNumBuffers); - TInt ReAllocBufferConfigInfo(TInt aNumBuffers); - TInt GetSensorCaps(TAny* a1); - TInt GetFrameSizeCaps(TAny* a1, TAny* a2); - TInt GetDynamicAttribute(TInt aAttribute, TUint& aValue); - TInt SetDynamicAttribute(TInt aAttribute, TUint aValue); - inline DCameraScPdd* Pdd(); - static void RestartDfc(TAny* aChannel); - static void PowerUpDfc(TAny* aPtr); - static void PowerDownDfc(TAny* aPtr); -private: - /** An array of configurations for each capture mode. */ - TCaptureModeConfig* iCaptureModeConfig; - /** The unit number of this channel. */ - TInt iUnit; - /** The operating state of the channel. */ - TState iState; - /** A pointer to the owning client thread. */ - DThread* iOwningThread; - /** The current capture mode of the camera. */ - TDevCamCaptureMode iCaptureMode; - /** The pending request queue. */ - TCameraScRequestQueue iRequestQueue; - /** A mutex to protect access to the buffer lists and the pending request list. */ - NFastMutex iMutex; - /** The camera driver power handler. */ - DCameraScPowerHandler* iPowerHandler; - /** DFC used to re-start the PDD following a data capture error. */ - TDfc iRestartDfc; - /** DFC used to handle power down requests from the power manager before a transition into system shutdown/standby. */ - TDfc iPowerDownDfc; - /** DFC used to handle power up requests from the power manager following a transition out of system standby. */ - TDfc iPowerUpDfc; - - // Used as a cache for values successfully set by SetDynamicAttribute(). - TUint iBrightnessValue; - TUint iContrastValue; - TUint iColorEffectValue; - - friend class DCameraScPowerHandler; - friend class DBufferManager; - }; - -#include - -#endif // __CAMERASC_H__ diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/drivers/camerasc.inl --- a/kernel/eka/include/drivers/camerasc.inl Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -// Copyright (c) 2004-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: -// e32\include\drivers\camerasc.inl -// -// - -inline DCameraScPdd* DCameraScLdd::Pdd() - {return((DCameraScPdd*)iPdd);} - -inline DThread* DCameraScLdd::OwningThread() - {return(iOwningThread);} - -inline TInt DCameraScLdd::CurrentFrameHeight() - {return(iCaptureModeConfig[iCaptureMode].iFrameHeight);} - -inline TInt DCameraScLdd::CurrentFrameWidth() - {return(iCaptureModeConfig[iCaptureMode].iFrameWidth);} - -inline TInt DCameraScPdd::SpecifyCustomConfig(TDes8& /*aConfig*/) - {return(KErrArgument);} - -inline TBool TCameraScRequestQueue::IsEmpty() - {return(iPendRequestQ.IsEmpty());} diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/drivers/dma_hai.h --- a/kernel/eka/include/drivers/dma_hai.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/include/drivers/dma_hai.h Fri Jul 09 13:13:20 2010 +0100 @@ -172,11 +172,13 @@ { friend class DmaChannelMgr; -// The following two friend declarations will become obsolete once that -// functionality is owned and provided by the controller class instead of the -// request class. (TDmac::iFreeHdr could then also be made private.) -friend TInt DDmaRequest::ExpandDesList(TInt, TInt&, SDmaDesHdr*&, SDmaDesHdr*&); -friend void DDmaRequest::FreeDesList(TInt&, SDmaDesHdr*&, SDmaDesHdr*&); +// The following friend declaration will become obsolete once header +// pool manipulation functionality is owned and provided by the controller +// class instead of the request class. +// (TDmac::iFreeHdr could then also be made private.) +friend class DDmaRequest; + +friend class TSkelDmac; protected: /** Data required for creating a new instance. */ @@ -848,7 +850,7 @@ virtual void DoCancelAll(); virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr); -private: +protected: enum {EIdle = 0, ETransferring} iState; }; @@ -864,7 +866,7 @@ virtual void DoCancelAll(); virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr); -private: +protected: enum {EIdle = 0, ETransferring, ETransferringLast} iState; }; @@ -881,7 +883,7 @@ virtual void DoUnlink(SDmaDesHdr& aHdr); virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr); -private: +protected: enum {EIdle = 0, ETransferring} iState; }; @@ -901,7 +903,7 @@ virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr, SDmaDesHdr*& aDstCompletedHdr); -private: +protected: SDmaDesHdr* iSrcCurHdr; // source fragment being transferred or NULL SDmaDesHdr** iSrcNullPtr; // Pointer to NULL pointer following last source fragment SDmaDesHdr* iDstCurHdr; // destination fragment being transferred or NULL diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/drivers/dma_v2.h --- a/kernel/eka/include/drivers/dma_v2.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/include/drivers/dma_v2.h Fri Jul 09 13:13:20 2010 +0100 @@ -49,6 +49,15 @@ #define __DMA_INVARIANT() #endif +#ifdef __DMASIM__ +#ifdef __PRETTY_FUNCTION__ +#define __DMA_UNREACHABLE_DEFAULT() DMA_PSL_TRACE1("Calling default virtual: %s", __PRETTY_FUNCTION__) +#else +#define __DMA_UNREACHABLE_DEFAULT() DMA_PSL_TRACE("Calling default virtual function") +#endif +#else +#define __DMA_UNREACHABLE_DEFAULT() __DMA_CANT_HAPPEN() +#endif ////////////////////////////////////////////////////////////////////////////// // INTERFACE EXPOSED TO DEVICE-DRIVERS @@ -637,7 +646,7 @@ private: inline void OnDeque(); TInt CheckTransferConfig(const TDmaTransferConfig& aTarget, TUint aCount) const; - TInt CheckMemFlags(const TDmaTransferConfig& aTarget, TUint aCount) const; + TInt CheckMemFlags(const TDmaTransferConfig& aTarget) const; TInt AdjustFragmentSize(TUint& aFragSize, TUint aElementSize, TUint aFrameSize); TUint GetTransferCount(const TDmaTransferArgs& aTransferArgs) const; TUint GetMaxTransferlength(const TDmaTransferArgs& aTransferArgs, TUint aCount) const; diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/drivers/iic.h --- a/kernel/eka/include/drivers/iic.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/include/drivers/iic.h Fri Jul 09 13:13:20 2010 +0100 @@ -335,28 +335,6 @@ TInt8 iChanRwFlags; // Bit 0 for write, bit 1 for read }; -#ifdef IIC_SIMULATED_PSL -_LIT(KPddName,"iic.pdd"); - -NONSHARABLE_CLASS(DIicPdd) : public DPhysicalDevice - { -// Class to faciliate loading of the IIC classes -public: - class TCaps - { - public: - TVersion iVersion; - }; -public: - DIicPdd(); - ~DIicPdd(); - virtual TInt Install(); - virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); - virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); - virtual void GetCaps(TDes8& aDes) const; - inline static TVersion VersionRequired(); - }; -#endif #include diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/drivers/iic_transaction.h --- a/kernel/eka/include/drivers/iic_transaction.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/include/drivers/iic_transaction.h Fri Jul 09 13:13:20 2010 +0100 @@ -421,6 +421,7 @@ inline TIicBusTransaction(); // the client interface for creating half duplex transactions + // The parameter aPriority is required to be at least zero and less than KNumTrancPriorities. inline TIicBusTransaction(TDes8* aHeader, TIicBusTransfer* aHdTrans, TInt aPriority=0); inline ~TIicBusTransaction(); inline TInt SetHalfDuplexTrans(TDes8* aHeader, TIicBusTransfer* aHdTrans); diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/drivers/iic_transaction.inl --- a/kernel/eka/include/drivers/iic_transaction.inl Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/include/drivers/iic_transaction.inl Fri Jul 09 13:13:20 2010 +0100 @@ -65,7 +65,8 @@ iHeader(aHeader), iFlags(NULL), iState(EFree), iHalfDuplexTrans(aHdTrans), iFullDuplexTrans(NULL), iCallback(NULL) { - __ASSERT_ALWAYS((((TUint)aPriority<(TUint)KNumTrancPriorities)&&((TUint)aPriority>=0)),Kern::Fault("TIicBusTransaction",__LINE__)); + //Check that the requested priority is at least zero and less than KNumTrancPriorities. + __ASSERT_ALWAYS(((aPriority=0)),Kern::Fault("TIicBusTransaction",__LINE__)); __ASSERT_ALWAYS(aHeader && aHdTrans,Kern::Fault("TIicBusTransaction",__LINE__)); iKey = aPriority; } diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/drivers/resmanus_trace.h --- a/kernel/eka/include/drivers/resmanus_trace.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/include/drivers/resmanus_trace.h Fri Jul 09 13:13:20 2010 +0100 @@ -26,16 +26,6 @@ #define __RESMANUSCONTROL_TRACE_H__ #ifdef BTRACE_RESMANUS -//Function to format the output. -static void UsTraceFormatPrint(TDes8& aBuf, const char* aFmt, ...) - { - if(!(&aBuf)) - return; - VA_LIST list; - VA_START(list,aFmt); - Kern::AppendFormat(aBuf,aFmt,list); - } - //definition of subcategories. #define PRM_US_OPEN_CHANNEL_START BTrace::EOpenChannelUsStart #define PRM_US_OPEN_CHANNEL_END BTrace::EOpenChannelUsEnd @@ -52,31 +42,38 @@ #define PRM_US_CANCEL_SET_RESOURCE_STATE_START BTrace::ECancelSetResourceStateUsStart #define PRM_US_CANCEL_SET_RESOURCE_STATE_END BTrace::ECancelSetResourceStateUsEnd +#define APPEND_VAL(val) \ + { \ + printBuf.Append((TUint8 *)&(val), sizeof(val)); \ + } +#define APPEND_STRING(des_ptr) \ + { \ + TUint length = (des_ptr)->Length(); \ + printBuf.Append((TUint8 *)&length, sizeof(TUint)); \ + printBuf.Append(*(des_ptr)); \ + } + // Macro to output identification information provided in a request to open a channel #define PRM_US_OPEN_CHANNEL_START_TRACE \ { \ - TBuf8<256> printBuf; \ - printBuf.Zero(); \ - UsTraceFormatPrint(printBuf, "%S", iUserNameUsed); \ - BTraceContextN(BTrace::EResourceManagerUs, PRM_US_OPEN_CHANNEL_START, 0, (TInt)(iClient), printBuf.Ptr(), printBuf.Length()); \ + Kern::Printf("PRM_US_OPEN_CHANNEL_START_TRACE");\ + BTraceContextN(BTrace::EResourceManagerUs, PRM_US_OPEN_CHANNEL_START, (TInt)(iClient), iUserNameUsed->Length(), iUserNameUsed->Ptr(), iUserNameUsed->Length()); \ } // Macro to output identification information generated during a request to open a channel #define PRM_US_OPEN_CHANNEL_END_TRACE \ { \ - TBuf8<256> printBuf; \ - printBuf.Zero(); \ - UsTraceFormatPrint(printBuf, "%S", iUserNameUsed); \ - BTraceContextN(BTrace::EResourceManagerUs, PRM_US_OPEN_CHANNEL_END, 0, (TInt)(ClientHandle()), printBuf.Ptr(), printBuf.Length()); \ + BTraceContextN(BTrace::EResourceManagerUs, PRM_US_OPEN_CHANNEL_END, (TInt)(ClientHandle()), iUserNameUsed->Length(), iUserNameUsed->Ptr(), iUserNameUsed->Length()); \ } // Macro to output information provided for a request to register with the Resource Controller #define PRM_US_REGISTER_CLIENT_START_TRACE \ { \ - TBuf8<256> printBuf; \ + TUint32 stateRes32 = ((stateRes[0]&0xFF) << 16) | ((stateRes[1]&0xFF) << 8) | ((stateRes[2]&0xFF));\ + TBuf8<80> printBuf; \ printBuf.Zero(); \ - UsTraceFormatPrint(printBuf, "%S 0x%x %d", iUserNameUsed, (TInt)(ClientHandle()),(TInt)(stateRes[0])); \ - BTraceContextN(BTrace::EResourceManagerUs, PRM_US_REGISTER_CLIENT_START, (TInt)(stateRes[1]), (TInt)(stateRes[2]), printBuf.Ptr(), printBuf.Length()); \ + APPEND_STRING(iUserNameUsed); \ + BTraceContextN(BTrace::EResourceManagerUs, PRM_US_REGISTER_CLIENT_START, (TInt)ClientHandle(), stateRes32, printBuf.Ptr(), printBuf.Length()); \ } // Macro to output information after issuing a request to register with the Resource Controller @@ -88,10 +85,7 @@ // Macro to output information provided for a request to de-register with the Resource Controller #define PRM_US_DEREGISTER_CLIENT_START_TRACE \ { \ - TBuf8<256> printBuf; \ - printBuf.Zero(); \ - UsTraceFormatPrint(printBuf, "%S ", iUserNameUsed); \ - BTraceContextN(BTrace::EResourceManagerUs, PRM_US_DEREGISTER_CLIENT_START, 0, (TInt)(ClientHandle()), printBuf.Ptr(), printBuf.Length()); \ + BTraceContextN(BTrace::EResourceManagerUs, PRM_US_DEREGISTER_CLIENT_START, (TInt)(ClientHandle()), iUserNameUsed->Length(), iUserNameUsed->Ptr(), iUserNameUsed->Length()); \ } // Macro to output information after issuing a request to de-register with the Resource Controller @@ -103,72 +97,76 @@ // Macro to output information provided for a request to get the state of a resource #define PRM_US_GET_RESOURCE_STATE_START_TRACE \ { \ - TBuf8<256> printBuf; \ - printBuf.Zero(); \ - UsTraceFormatPrint(printBuf, "%S ", iUserNameUsed); \ + TBuf8<80> printBuf; \ + printBuf.Zero(); \ + APPEND_STRING(iUserNameUsed); \ BTraceContextN(BTrace::EResourceManagerUs, PRM_US_GET_RESOURCE_STATE_START, resourceId, (TInt)(ClientHandle()), printBuf.Ptr(), printBuf.Length()); \ } // Macro to output information on completion of a request to get the state of a resource #define PRM_US_GET_RESOURCE_STATE_END_TRACE \ { \ - TBuf8<256> printBuf; \ + TBuf8<80> printBuf; \ printBuf.Zero(); \ - UsTraceFormatPrint(printBuf, "%d %d", aClient, aResult); \ + APPEND_VAL(aClient); \ + APPEND_VAL(aResult); \ BTraceContextN(BTrace::EResourceManagerUs, PRM_US_GET_RESOURCE_STATE_END, aResourceId, aLevel, printBuf.Ptr(), printBuf.Length()); \ } // Macro to output information provided for a request to set the state of a resource #define PRM_US_SET_RESOURCE_STATE_START_TRACE \ { \ - TBuf8<256> printBuf; \ + TBuf8<80> printBuf; \ printBuf.Zero(); \ - UsTraceFormatPrint(printBuf, "%S %d", iUserNameUsed, (TInt)(ClientHandle())); \ + TInt ch = ClientHandle(); \ + APPEND_VAL(ch); \ + APPEND_STRING(iUserNameUsed); \ BTraceContextN(BTrace::EResourceManagerUs, PRM_US_SET_RESOURCE_STATE_START, resourceId, newState, printBuf.Ptr(), printBuf.Length()); \ } // Macro to output information on completion of a request to set the state of a resource #define PRM_US_SET_RESOURCE_STATE_END_TRACE \ { \ - TBuf8<256> printBuf; \ + TBuf8<80> printBuf; \ printBuf.Zero(); \ - UsTraceFormatPrint(printBuf, "%d %d", aClient, aResult); \ + APPEND_VAL(aClient); \ + APPEND_VAL(aResult); \ BTraceContextN(BTrace::EResourceManagerUs, PRM_US_SET_RESOURCE_STATE_END, aResourceId, aLevel, printBuf.Ptr(), printBuf.Length()); \ } // Macro to output information provided for a request to cancel the get resource state requests for a resource #define PRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE \ { \ - TBuf8<256> printBuf; \ - printBuf.Zero(); \ - UsTraceFormatPrint(printBuf, "%S ", iUserNameUsed); \ + TBuf8<80> printBuf; \ + printBuf.Zero(); \ + APPEND_STRING(iUserNameUsed); \ BTraceContextN(BTrace::EResourceManagerUs, PRM_US_CANCEL_GET_RESOURCE_STATE_START, aResourceId, (TInt)(ClientHandle()), printBuf.Ptr(), printBuf.Length()); \ } // Macro to output information on completion of a request to cancel the get resource state requests for a resource #define PRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE \ { \ - TBuf8<256> printBuf; \ - printBuf.Zero(); \ - UsTraceFormatPrint(printBuf, "%S ", iUserNameUsed); \ + TBuf8<80> printBuf; \ + printBuf.Zero(); \ + APPEND_STRING(iUserNameUsed); \ BTraceContextN(BTrace::EResourceManagerUs, PRM_US_CANCEL_GET_RESOURCE_STATE_END, aResourceId, (TInt)(ClientHandle()), printBuf.Ptr(), printBuf.Length()); \ } // Macro to output information provided for a request to cancel the set resource state requests for a resource #define PRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE \ { \ - TBuf8<256> printBuf; \ - printBuf.Zero(); \ - UsTraceFormatPrint(printBuf, "%S ", iUserNameUsed); \ + TBuf8<80> printBuf; \ + printBuf.Zero(); \ + APPEND_STRING(iUserNameUsed); \ BTraceContextN(BTrace::EResourceManagerUs, PRM_US_CANCEL_SET_RESOURCE_STATE_START, aResourceId, (TInt)(ClientHandle()), printBuf.Ptr(), printBuf.Length()); \ } // Macro to output information on completion of a request to cancel the get resource state requests for a resource #define PRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE \ { \ - TBuf8<256> printBuf; \ - printBuf.Zero(); \ - UsTraceFormatPrint(printBuf, "%S ", iUserNameUsed); \ + TBuf8<80> printBuf; \ + printBuf.Zero(); \ + APPEND_STRING(iUserNameUsed); \ BTraceContextN(BTrace::EResourceManagerUs, PRM_US_CANCEL_SET_RESOURCE_STATE_END, aResourceId, (TInt)(ClientHandle()), printBuf.Ptr(), printBuf.Length()); \ } diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/drivers/resource.h --- a/kernel/eka/include/drivers/resource.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/include/drivers/resource.h Fri Jul 09 13:13:20 2010 +0100 @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2007-2010 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" @@ -168,12 +168,37 @@ __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TPowerResourceCb::DfcFunc ClientId = 0x%x, ResourceId = %d, Level = %d, \ LevelOwnerId = %d, Result = %d", pCb->iClientId, pCb->iResourceId, pCb->iLevel, \ pCb->iLevelOwnerId, pCb->iResult)); - // Call the client specified callback function - pCb->iCallback(pCb->iClientId, pCb->iResourceId, pCb->iLevel, pCb->iLevelOwnerId, pCb->iResult, pCb->iParam); - pCb->iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request. + + pCb->Lock(); + TUint ClientId = pCb->iClientId; + TUint ResourceId = pCb->iResourceId; + TInt Level = pCb->iLevel; + TInt LevelOwnerId = pCb->iLevelOwnerId; + TInt Result = pCb->iResult; + TAny* Param = pCb->iParam; + pCb->UnLock(); + + // Call the client specified callback function + pCb->iCallback(ClientId, ResourceId, Level, LevelOwnerId, Result, Param); + + pCb->Lock(); + pCb->iPendingRequestCount--; + if(pCb->iPendingRequestCount == 0) + pCb->iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request. + pCb->UnLock(); PRM_CALLBACK_COMPLETION_TRACE } private: + void Lock() + { + NKern::ThreadEnterCS(); + Kern::MutexWait(*iMutex); + } + void UnLock() + { + Kern::MutexSignal(*iMutex); + NKern::ThreadLeaveCS(); + } TAny* iParam; //Stores the aPtr argument passed in the constructor, to be passed as 5th argument to the callback function TInt iResult; //Used to store the result aswell as binary usage count for the callback TInt iLevel; // Level of the resource @@ -181,6 +206,8 @@ TUint iResourceId; //Stores the ID of the resource whose state is changed/read asynchronously TUint iClientId; //Stores the ID of the client that requested the asynchronous operation TPowerResourceCbFn iCallback; //Callback function object + DMutex* iMutex; + TInt iPendingRequestCount; #ifdef PRM_CONTROLLER friend class DPowerResourceController; #endif diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/drivers/resourcecontrol_trace.h --- a/kernel/eka/include/drivers/resourcecontrol_trace.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/include/drivers/resourcecontrol_trace.h Fri Jul 09 13:13:20 2010 +0100 @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2007-2010 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" @@ -26,16 +26,6 @@ #define __RESOURCECONTROL_TRACE_H__ #ifdef BTRACE_RESOURCE_MANAGER -//Function to format the output. -static void TraceFormatPrint(TDes8& aBuf, const char* aFmt, ...) - { - if(aBuf.MaxLength() == 0) - return; - VA_LIST list; - VA_START(list,aFmt); - Kern::AppendFormat(aBuf,aFmt,list); - } - //definition of subcategories. #define PRM_REGISTER_RESOURCE BTrace::ERegisterResource #define PRM_REGISTER_CLIENT BTrace::ERegisterClient @@ -66,13 +56,27 @@ #define PRM_REGISTER_RESOURCE_DEPENDENCY BTrace::ERegisterResourceDependency #define PRM_DEREGISTER_RESOURCE_DEPENDENCY BTrace::EDeRegisterResourceDependency #endif + +#define APPEND_VAL(val) \ + { \ + printBuf.Append((TUint8 *)&(val), sizeof(val)); \ + } +#define APPEND_STRING(des_ptr) \ + { \ + TUint length = (des_ptr)->Length(); \ + printBuf.Append((TUint8 *)&length, sizeof(TUint)); \ + printBuf.Append(*(des_ptr)); \ + } + //Macro to output resource information #define PRM_REGISTER_RESOURCE_TRACE \ { \ TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %d %d %d", pR->iName, pResInfo->iMinLevel, pResInfo->iMaxLevel, \ - pResInfo->iDefaultLevel); \ + APPEND_VAL(pResInfo->iMinLevel); \ + APPEND_VAL(pResInfo->iMaxLevel); \ + APPEND_VAL(pResInfo->iDefaultLevel); \ + APPEND_STRING(pR->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_REGISTER_RESOURCE, resCount+1, pR, printBuf.Ptr(), \ printBuf.Length()); \ } @@ -80,15 +84,21 @@ //Macro to output client details. Used during client registration #define PRM_CLIENT_REGISTER_TRACE \ { \ + TBuf8<80> printBuf; \ + printBuf.Zero(); \ + APPEND_STRING(pC->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_REGISTER_CLIENT, aClientId, (TUint)pC, \ - pC->iName->Ptr(), pC->iName->Length()); \ + printBuf.Ptr(), printBuf.Length()); \ } //Used during client deregistration #define PRM_CLIENT_DEREGISTER_TRACE \ { \ + TBuf8<80> printBuf; \ + printBuf.Zero(); \ + APPEND_STRING(pC->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_DEREGISTER_CLIENT, aClientId, \ - (TUint)pC, pC->iName->Ptr(), pC->iName->Length()); \ + (TUint)pC, printBuf.Ptr(), printBuf.Length()); \ } //Used to resource state change operation.Used at the start of the operation. @@ -96,7 +106,9 @@ { \ TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %S %d", pC->iName, pR->iName, aNewState); \ + APPEND_VAL(aNewState); \ + APPEND_STRING(pC->iName); \ + APPEND_STRING(pR->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_CLIENT_STATE_CHANGE_START, pC->iClientId, \ aResourceId, printBuf.Ptr(), printBuf.Length()); \ } @@ -106,7 +118,10 @@ { \ TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %S %d %d", pC->iName, pR->iName, r, aNewState); \ + APPEND_VAL(r); \ + APPEND_VAL(aNewState); \ + APPEND_STRING(pC->iName); \ + APPEND_STRING(pR->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_CLIENT_STATE_CHANGE_END, pC->iClientId, \ aResourceId, printBuf.Ptr(), printBuf.Length()); \ } @@ -142,8 +157,6 @@ //Calling TraceFormatPrint just to avoid warning #define PRM_CALLBACK_COMPLETION_TRACE \ { \ - TPtr8 zeroDes(NULL, 0); \ - TraceFormatPrint(zeroDes, "%d", pCb->iClientId); \ BTraceContext8(BTrace::EResourceManager, PRM_CALLBACK_COMPLETE, pCb->iClientId, \ pCb->iResourceId); \ } @@ -156,9 +169,9 @@ #define PRM_PSL_RESOURCE_GET_STATE_START_TRACE \ { \ - TBuf8<80> printBuf; \ - printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S ", iName); \ + TBuf8<80> printBuf; \ + printBuf.Zero(); \ + APPEND_STRING(iName); \ BTraceContextN(BTrace::EResourceManager, PRM_PSL_RESOURCE_GET_STATE_START, aRequest.ClientId(), \ aRequest.ResourceId(), printBuf.Ptr(), printBuf.Length()); \ } @@ -168,7 +181,8 @@ { \ TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %S", pC->iName, pR->iName); \ + APPEND_STRING(pC->iName); \ + APPEND_STRING(pR->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_CLIENT_GET_STATE_START, pC->iClientId, aResourceId,\ printBuf.Ptr(), printBuf.Length());\ } @@ -177,7 +191,9 @@ { \ TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %d %d", iName, iCurLevel,retVal); \ + APPEND_VAL(iCurLevel); \ + APPEND_VAL(retVal); \ + APPEND_STRING(iName); \ BTraceContextN(BTrace::EResourceManager, PRM_PSL_RESOURCE_GET_STATE_END, aRequest.ClientId(), \ aRequest.ResourceId(), printBuf.Ptr(), printBuf.Length()); \ } @@ -187,7 +203,10 @@ { \ TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %S %d %d", pC->iName, pR->iName, aState, r); \ + APPEND_VAL(aState); \ + APPEND_VAL(r); \ + APPEND_STRING(pC->iName); \ + APPEND_STRING(pR->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_CLIENT_GET_STATE_END, pC->iClientId, aResourceId, \ printBuf.Ptr(), printBuf.Length());\ } @@ -197,7 +216,9 @@ { \ TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %S %d", pC->iName, pR->iName, r); \ + APPEND_VAL(r); \ + APPEND_STRING(pC->iName); \ + APPEND_STRING(pR->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_CANCEL_LONG_LATENCY_OPERATION, pC->iClientId, \ aResourceId, printBuf.Ptr(), printBuf.Length()); \ } @@ -206,7 +227,10 @@ { \ TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %d %d", iName, iCurLevel, aRequest.Level()); \ + APPEND_VAL(iCurLevel); \ + TInt RequestLevel = aRequest.Level(); \ + APPEND_VAL(RequestLevel); \ + APPEND_STRING(iName); \ BTraceContextN(BTrace::EResourceManager, PRM_PSL_RESOURCE_CHANGE_STATE_START, aRequest.ClientId(), \ aRequest.ResourceId(), printBuf.Ptr(), printBuf.Length()); \ } @@ -215,7 +239,11 @@ { \ TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %d %d %d", iName, iCurLevel, aRequest.Level(),retVal); \ + APPEND_VAL(iCurLevel); \ + TInt RequestLevel = aRequest.Level(); \ + APPEND_VAL(RequestLevel); \ + APPEND_VAL(retVal); \ + APPEND_STRING(iName); \ BTraceContextN(BTrace::EResourceManager, PRM_PSL_RESOURCE_CHANGE_STATE_END, aRequest.ClientId(), \ aRequest.ResourceId(), printBuf.Ptr(), printBuf.Length()); \ } @@ -224,7 +252,9 @@ { \ TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%d %d %S", iDefaultLevel, iFlags, iName); \ + APPEND_VAL(iDefaultLevel); \ + APPEND_VAL(iFlags); \ + APPEND_STRING(iName); \ BTraceContextN(BTrace::EResourceManager, PRM_PSL_RESOURCE_CREATE, iMinLevel, iMaxLevel, \ printBuf.Ptr(), printBuf.Length()); \ } @@ -233,8 +263,6 @@ //Calling TraceFormatPrint just to avoid warning #define PRM_BOOTING_TRACE \ { \ - TPtr8 zeroDes(NULL, 0); \ - TraceFormatPrint(zeroDes, "%d", aReason); \ BTraceContext4(BTrace::EResourceManager, PRM_BOOTING, (TUint)aReason); \ } @@ -242,12 +270,14 @@ //Macro to output static resource with dependency #define PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE \ { \ - TBuf8<80> pBuf; \ - pBuf.Zero(); \ - TraceFormatPrint(pBuf, "%S %d %d %d", pR->iName, pResInfo->iMinLevel, pResInfo->iMaxLevel, \ - pResInfo->iDefaultLevel); \ + TBuf8<80> printBuf; \ + printBuf.Zero(); \ + APPEND_VAL(pResInfo->iMinLevel); \ + APPEND_VAL(pResInfo->iMaxLevel); \ + APPEND_VAL(pResInfo->iDefaultLevel); \ + APPEND_STRING(pR->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY, pR->iResourceId, \ - pR, pBuf.Ptr(), pBuf.Length()); \ + pR, printBuf.Ptr(), printBuf.Length()); \ } //Macro to output dynamic resource registration. @@ -255,7 +285,9 @@ { \ TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %S %d", aClientPtr->iName, aPDRes->iName, aPDRes); \ + APPEND_VAL(aPDRes); \ + APPEND_STRING(aClientPtr->iName); \ + APPEND_STRING(aPDRes->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_REGISTER_DYNAMIC_RESOURCE, aClientPtr->iClientId, \ aPDRes->iResourceId, printBuf.Ptr(), printBuf.Length()); \ } @@ -265,7 +297,10 @@ { \ TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %S %d %d", aClientPtr->iName, pDR->iName, pDR, level); \ + APPEND_VAL(pDR); \ + APPEND_VAL(level); \ + APPEND_STRING(aClientPtr->iName); \ + APPEND_STRING(pDR->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_DEREGISTER_DYNAMIC_RESOURCE, aClientPtr->iClientId, \ pDR->iResourceId, printBuf.Ptr(), printBuf.Length()); \ } @@ -273,10 +308,14 @@ //Macro to output registration of resource dependency. #define PRM_REGISTER_RESOURCE_DEPENDENCY_TRACE \ { \ - TBuf8<256> printBuf; \ + TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %S %d %S %d %d", aClientPtr->iName, pR1->iName, pR2->iResourceId, \ - pR2->iName, pR1, pR2); \ + APPEND_VAL(pR2->iResourceId); \ + APPEND_VAL(pR1); \ + APPEND_VAL(pR2); \ + APPEND_STRING(aClientPtr->iName); \ + APPEND_STRING(pR1->iName); \ + APPEND_STRING(pR2->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_REGISTER_RESOURCE_DEPENDENCY, aClientPtr->iClientId, \ pR1->iResourceId, printBuf.Ptr(), printBuf.Length()); \ } @@ -284,10 +323,14 @@ //Macro to output deregistration of resource dependency. #define PRM_DEREGISTER_RESOURCE_DEPENDENCY_TRACE \ { \ - TBuf8<256> printBuf; \ + TBuf8<80> printBuf; \ printBuf.Zero(); \ - TraceFormatPrint(printBuf, "%S %S %d %S %d %d", aClientPtr->iName, pDR1->iName, pDR2->iResourceId, \ - pDR2->iName, pDR1, pDR2); \ + APPEND_VAL(pDR2->iResourceId); \ + APPEND_VAL(pDR1); \ + APPEND_VAL(pDR2); \ + APPEND_STRING(aClientPtr->iName); \ + APPEND_STRING(pDR1->iName); \ + APPEND_STRING(pDR2->iName); \ BTraceContextN(BTrace::EResourceManager, PRM_DEREGISTER_RESOURCE_DEPENDENCY, aClientPtr->iClientId, \ pDR1->iResourceId, printBuf.Ptr(), printBuf.Length()); \ } diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/e32btrace.h --- a/kernel/eka/include/e32btrace.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/include/e32btrace.h Fri Jul 09 13:13:20 2010 +0100 @@ -1437,462 +1437,500 @@ EPagingPageTableAlloc, }; - /** - Enumeration of sub-category values for trace category EResourceManager. - @see EResourceManager - @prototype 9.5 - */ - enum TResourceManager - { - /** - Trace output for resource registration. - - Trace data format: - - 4 bytes containing the Resource Id. - - 4 bytes containing the Resource address. - - N bytes containing the Resource name, where 0 < N < 32 - - 4 bytes containing the Resource Minimum Level - - 4 bytes containing the Resource Maximum Level - - 4 bytes containing the Resource Default Level - */ - ERegisterResource = 0, - - /** - Trace output for client registration - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing client address - - N bytes containing client name, where 0 < N < 32 - */ - ERegisterClient, - - /** - Trace output for client deregistration - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing client address - - N bytes containing client name, where 0 < N < 32 - */ - EDeRegisterClient, - - /** - Trace output for resource state change start operation - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - - N bytes containing client name, where 0 < N < 32 - - N bytes containing the Resource name, where 0 < N < 32 - - 4 bytes containing the Resource state - */ - ESetResourceStateStart, - - /** - Trace output for resource state change end operation - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - - N bytes containing client name, where 0 < N < 32 - - N bytes containing the Resource name, where 0 < N < 32 - - 4 bytes containing return value. - - 4 bytes containing the Resource state. - */ - ESetResourceStateEnd, - - /** - Trace output for registration for post notification - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - - 4 bytest containing the callback address - - 4 bytes containing return value. - */ - EPostNotificationRegister, - - /** - Trace output for deregistration for post notification - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - - 4 bytes containing the callback address - - 4 bytes containing the return value. - */ - EPostNotificationDeRegister, - - /** - Trace output for post notification sent. - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - */ - EPostNotificationSent, - - /** - Trace output for Callback complete - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - */ - ECallbackComplete, - - /** - Trace output for resource manager memory usage - - Trace data format: - - 4 bytes containing memory allocated in bytes. - */ - EMemoryUsage, - - /** - Trace output for get resource state start operation - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - - N bytes containing client name, where 0 < N < 32 - - N bytes containing the Resource name, where 0 < N < 32 - */ - EGetResourceStateStart, - - /** - Trace output for get resource state end operation - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - - N bytes containing client name, where 0 < N < 32 - - N bytes containing the Resource name, where 0 < N < 32 - - 4 bytes containing the Resource state - - 4 bytes containing return value. - */ - EGetResourceStateEnd, - - /** - Trace output for cancellation of long latency operation - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - - N bytes containing client name, where 0 < N < 32 - - N bytes containing the Resource name, where 0 < N < 32 - - 4 bytes containing return value - */ - ECancelLongLatencyOperation, - - /** - Trace output for booting of resource manager - - Trace data format: - - 4 bytes containing entry point - */ - EBooting, - - /** - Trace output for PSL resource state change operation - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - - N bytes containing the Resource name, where 0 < N < 32 - - 4 bytes containing the Resource current state - - 4 bytes containing the resource requested state - */ - EPslChangeResourceStateStart, - - /** - Trace output for PSL resource state change operation - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - - N bytes containing the Resource name, where 0 < N < 32 - - 4 bytes containing the Resource current state - - 4 bytes containing the resource requested state - - 4 bytes containing return value - */ - EPslChangeResourceStateEnd, - - /** - Trace output for get resource state start operation in PSL - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - - N bytes containing the Resource name, where 0 < N < 32 - */ - EPslGetResourceStateStart, - - /** - Trace output for get resource state end operation in PSL - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id. - - N bytes containing the Resource name, where 0 < N < 32 - - 4 bytes containing the Resource state - - 4 bytes containing return value. - */ - EPslGetResourceStateEnd, - - /** - Trace output for resource creation - - Trace data format: - - 4 bytes containing minimum value of resource - - 4 bytes containing maximum value of resource - - 4 bytes containing the default value of resource - - 4 bytes containing the properties of the resource - - N bytes containing the Resource name, where 0 < N < 32 - */ - EPslResourceCreate, - - /** - Trace output for static resource with dependency registration - - Trace data format: - - 4 bytes containing the Resource Id - - 4 bytes containing the Resource address - - N bytes containing the Resource name, where 0 < N < 32 - - 4 bytes containing the minimum value of resource - - 4 bytes containing the maximum value of resource - - 4 bytes containing the default value of resource - */ - ERegisterStaticResourceWithDependency, - - /** - Trace output for dynamic resource registration - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id - - N bytes containing the client name, where 0 < N < 32 - - N bytes containing the resource name, where 0 < N < 32 - - 4 bytes containing the resouce address - */ - ERegisterDynamicResource, - - /** - Trace output for dynamic resource deregistration - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id - - N bytes containing the client name, where 0 < N < 32 - - N bytes containing the resource name, where 0 < N < 32 - - 4 bytes containing the resource address - - 4 bytes containing the resource level. - */ - EDeRegisterDynamicResource, - - /** - Trace output for resource dependency registration - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id of first dependent resource - - N bytes containing the client name, where 0 < N < 32 - - N bytes containing the resource name of first dependent resource, where 0 < N < 32 - - 4 bytes containing the Resource Id of second dependent resource - - N bytes containing the resource name of second dependent resource, where 0 < N < 32 - - 4 bytes containing the address of first dependent resource - - 4 bytes containing the address of second dependent resource - */ - ERegisterResourceDependency, - - /** - Trace output for resource dependency deregistration - - Trace data format: - - 4 bytes containing clientId - - 4 bytes containing the Resource Id of first dependent resource - - N bytes containing the client name, where 0 < N < 32 - - N bytes containing the resource name of first dependent resource, where 0 < N < 32 - - 4 bytes containing the resource id of second dependent resource - - N bytes containing the resource name of second dependent resource, where 0 < N < 32 - - 4 bytes containing the address of first dependent resource - - 4 bytes containing the address of second dependent resource - */ - EDeRegisterResourceDependency - }; - /** - Enumeration of sub-category values for trace category EResourceManagerUs. - @see EResourceManagerUs - @prototype 9.5 - */ - enum TResourceManagerUs - { - /** - Trace output for the start of opening a channel to the Resource Controller. - - Trace data format: - - 4 bytes unused (displays 0) - - 4 bytes containing the client thread identifier. - - N bytes containing the client name, where 0 < N < 32 - */ - EOpenChannelUsStart = 0, - /** - Trace output for the end of opening a channel to the Resource Controller. - - Trace data format: - - 4 bytes unused (displays 0) - - 4 bytes containing the client identifier provided by the Resource Controller - - N bytes containing the client name, where 0 < N < 32 - */ - EOpenChannelUsEnd, - /** - Trace output for the start of registering a client with the Resource Controller. - - Trace data format: - - 4 bytes the number of concurrent change resource state operations to be supported - - 4 bytes the number of concurrent notification requests to be supported - - N bytes containing the client name, where 0 < N < 32 - - 4 bytes the number of concurrent get resource state operations to be supported - */ - ERegisterClientUsStart, - /** - Trace output for the end of registering a client with the Resource Controller. - - Trace data format: - - 4 bytes containing the client identifier provided by the Resource Controller. - - 4 bytes specifying the value returned from the call to Resource Controller's AllocReserve method - */ - ERegisterClientUsEnd, - /** - Trace output for the start of de-registering a client with the Resource Controller. - - Trace data format: - - 4 bytes unused (displays 0) - - 4 bytes containing the client identifier provided by the Resource Controller. - - N bytes containing the client name, where 0 < N < 32 - */ - EDeRegisterClientUsStart, - /** - Trace output for the end of registering a client with the Resource Controller. - - Trace data format: - - 4 bytes containing the client identifier provided by the Resource Controller. - */ - EDeRegisterClientUsEnd, - /** - Trace output for the start of a GetResourceState request to the Resource Controller. - - Trace data format: - - 4 bytes specifying the resource ID - - 4 bytes containing the client identifier provided by the Resource Controller. - - N bytes containing the client name, where 0 < N < 32 - */ - EGetResourceStateUsStart, - /** - Trace output for the end of a GetResourceState request to the Resource Controller. - - Trace data format: - - 4 bytes specifying the resource ID - - 4 bytes specifying the resource level - - 4 bytes containing the client identifier - - 4 bytes specifying the success code returned by the Resource Controller. - */ - EGetResourceStateUsEnd, - /** - Trace output for the start of a ChangeResourceState request to the Resource Controller. - - Trace data format: - - 4 bytes specifying the resource ID - - 4 bytes specifying the required state - - N bytes containing the client name, where 0 < N < 32 - - 4 bytes containing the client identifier provided by the Resource Controller. - */ - ESetResourceStateUsStart, - /** - Trace output for the end of a ChangeResourceState request to the Resource Controller. - - Trace data format: - - 4 bytes specifying the resource ID - - 4 bytes specifying the requested state - - 4 bytes containing the client identifier - - 4 bytes specifying the success code returned by the Resource Controller. - */ - ESetResourceStateUsEnd, - /** - Trace output for the start of a cancel GetResourceState request to the Resource Controller. - - Trace data format: - - 4 bytes specifying the resource ID - - 4 bytes containing the client identifier provided by the Resource Controller. - - N bytes containing the client name, where 0 < N < 32 - */ - ECancelGetResourceStateUsStart, - /** - Trace output for the end of a cancel GetResourceState request to the Resource Controller. - - Trace data format: - - 4 bytes specifying the resource ID - - 4 bytes containing the client identifier provided by the Resource Controller. - - N bytes containing the client name, where 0 < N < 32 - */ - ECancelGetResourceStateUsEnd, - /** - Trace output for the start of a cancel ChangeResourceState request to the Resource Controller. - - Trace data format: - - 4 bytes specifying the resource ID - - 4 bytes containing the client identifier provided by the Resource Controller. - - N bytes containing the client name, where 0 < N < 32 - */ - ECancelSetResourceStateUsStart, - /** - Trace output for the end of a cancel ChangeResourceState request to the Resource Controller. - - Trace data format: - - 4 bytes specifying the resource ID - - 4 bytes containing the client identifier provided by the Resource Controller. - - N bytes containing the client name, where 0 < N < 32 - */ - ECancelSetResourceStateUsEnd - }; - - /** - Enumeration of sub-category values for trace category EThreadPriority. - @see EThreadPriority - @internalTechnology - @prototype 9.3 - */ - enum TThreadPriority - { - /** - Trace output when a nanothread priority is changed. - - Trace data format: - - 4 bytes containing the context id (an NThread*) for the thread whose priority is changing. - - 4 bytes containing the new absolute priority. - */ - ENThreadPriority=0, - - /** - Trace output when a DThread's default priority is set. - - Trace data format: - - 4 bytes containing the context id (an NThread*) for the thread whose priority is changing. - - 4 bytes containing the iThreadPriority member - a value from enum ::TThrdPriority. - - 4 bytes containing the new default absolute priority. - */ - EDThreadPriority=1, - - /** - Trace output when a DProcess priority is changed. - - Trace data format: - - 4 bytes containing trace id (a DProcess*) for process. - - 4 bytes containing the new process priority, a value from enum ::TProcPriority - */ - EProcessPriority=2 - }; + /** + Enumeration of sub-category values for trace category EResourceManager. + @see EResourceManager + @prototype 9.5 + */ + enum TResourceManager + { + /** + Trace output for resource registration. + + Trace data format: + - 4 bytes containing the Resource Id. + - 4 bytes containing the Resource address. + - 4 bytes containing the Resource Minimum Level + - 4 bytes containing the Resource Maximum Level + - 4 bytes containing the Resource Default Level + - 4 bytes containing the length of resource name + - N bytes containing the Resource name, where 0 < N < 32 + */ + ERegisterResource = 0, + + /** + Trace output for client registration + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing client address + - 4 bytes containing the length of client name + - N bytes containing client name, where 0 < N < 32 + */ + ERegisterClient, + + /** + Trace output for client deregistration + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing client address + - 4 bytes containing the length of client name + - N bytes containing client name, where 0 < N < 32 + */ + EDeRegisterClient, + + /** + Trace output for resource state change start operation + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + - 4 bytes containing the Resource state + - 4 bytes containing the length of client name + - N bytes containing client name, where 0 < N < 32 + - 4 bytes containing the length of resource name + - N bytes containing the Resource name, where 0 < N < 32 + */ + ESetResourceStateStart, + + /** + Trace output for resource state change end operation + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + - 4 bytes containing return value. + - 4 bytes containing the Resource state. + - 4 bytes containing the length of client name + - N bytes containing client name, where 0 < N < 32 + - 4 bytes containing the length of resource name + - N bytes containing the Resource name, where 0 < N < 32 + */ + ESetResourceStateEnd, + + /** + Trace output for registration for post notification + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + - 4 bytest containing the callback address + - 4 bytes containing return value. + */ + EPostNotificationRegister, + + /** + Trace output for deregistration for post notification + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + - 4 bytes containing the callback address + - 4 bytes containing the return value. + */ + EPostNotificationDeRegister, + + /** + Trace output for post notification sent. + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + */ + EPostNotificationSent, + + /** + Trace output for Callback complete + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + */ + ECallbackComplete, + + /** + Trace output for resource manager memory usage + + Trace data format: + - 4 bytes containing memory allocated in bytes. + */ + EMemoryUsage, + + /** + Trace output for get resource state start operation + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + - 4 bytes containing the length of client name. + - N bytes containing client name, where 0 < N < 32 + - 4 bytes containing the length of resource name. + - N bytes containing the Resource name, where 0 < N < 32 + */ + EGetResourceStateStart, + + /** + Trace output for get resource state end operation + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + - 4 bytes containing the Resource state + - 4 bytes containing return value. + - 4 bytes containing the length of client name. + - N bytes containing client name, where 0 < N < 32 + - 4 bytes containing the length of resource name. + - N bytes containing the Resource name, where 0 < N < 32 + */ + EGetResourceStateEnd, + + /** + Trace output for cancellation of long latency operation + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + - 4 bytes containing return value + - 4 bytes containing the length of client name. + - N bytes containing client name, where 0 < N < 32 + - 4 bytes containing the length of resource name. + - N bytes containing the Resource name, where 0 < N < 32 + */ + ECancelLongLatencyOperation, + + /** + Trace output for booting of resource manager + + Trace data format: + - 4 bytes containing entry point + */ + EBooting, + + /** + Trace output for PSL resource state change operation + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + - 4 bytes containing the Resource current state + - 4 bytes containing the resource requested state + - 4 bytes containing the length of resource name. + - N bytes containing the Resource name, where 0 < N < 32 + */ + EPslChangeResourceStateStart, + + /** + Trace output for PSL resource state change operation + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + - 4 bytes containing the Resource current state + - 4 bytes containing the resource requested state + - 4 bytes containing return value + - 4 bytes containing the length of resource name. + - N bytes containing the Resource name, where 0 < N < 32 + */ + EPslChangeResourceStateEnd, + + /** + Trace output for get resource state start operation in PSL + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + - 4 bytes containing the length of resource name. + - N bytes containing the Resource name, where 0 < N < 32 + */ + EPslGetResourceStateStart, + + /** + Trace output for get resource state end operation in PSL + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id. + - 4 bytes containing the Resource state + - 4 bytes containing return value. + - 4 bytes containing the length of resource name. + - N bytes containing the Resource name, where 0 < N < 32 + */ + EPslGetResourceStateEnd, + + /** + Trace output for resource creation + + Trace data format: + - 4 bytes containing minimum value of resource + - 4 bytes containing maximum value of resource + - 4 bytes containing the default value of resource + - 4 bytes containing the properties of the resource + - 4 bytes containing the length of resource name. + - N bytes containing the Resource name, where 0 < N < 32 + */ + EPslResourceCreate, + + /** + Trace output for static resource with dependency registration + + Trace data format: + - 4 bytes containing the Resource Id + - 4 bytes containing the Resource address + - 4 bytes containing the minimum value of resource + - 4 bytes containing the maximum value of resource + - 4 bytes containing the default value of resource + - 4 bytes containing the length of resource name + - N bytes containing the Resource name, where 0 < N < 32 + */ + ERegisterStaticResourceWithDependency, + + /** + Trace output for dynamic resource registration + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id + - 4 bytes containing the resouce address + - 4 bytes containing the length of client name + - N bytes containing the client name, where 0 < N < 32 + - 4 bytes containing the length of resource name + - N bytes containing the resource name, where 0 < N < 32 + */ + ERegisterDynamicResource, + + /** + Trace output for dynamic resource deregistration + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id + - 4 bytes containing the resource address + - 4 bytes containing the resource level. + - 4 bytes containing the length of client name + - N bytes containing the client name, where 0 < N < 32 + - 4 bytes containing the length of resource name + - N bytes containing the resource name, where 0 < N < 32 + */ + EDeRegisterDynamicResource, + + /** + Trace output for resource dependency registration + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id of first dependent resource + - 4 bytes containing the Resource Id of second dependent resource + - 4 bytes containing the address of first dependent resource + - 4 bytes containing the address of second dependent resource + - 4 bytes containing the length of client name + - N bytes containing the client name, where 0 < N < 32 + - 4 bytes containing the length of resource name of first dependent resource + - N bytes containing the resource name of first dependent resource, where 0 < N < 32 + - 4 bytes containing the length of resource name of second dependent resource + - N bytes containing the resource name of second dependent resource, where 0 < N < 32 + */ + ERegisterResourceDependency, + + /** + Trace output for resource dependency deregistration + + Trace data format: + - 4 bytes containing clientId + - 4 bytes containing the Resource Id of first dependent resource + - 4 bytes containing the resource id of second dependent resource + - 4 bytes containing the address of first dependent resource + - 4 bytes containing the address of second dependent resource + - 4 bytes containing the length of client name + - N bytes containing the client name, where 0 < N < 32 + - 4 bytes containing the length of resource name of first dependent resource + - N bytes containing the resource name of first dependent resource, where 0 < N < 32 + - 4 bytes containing the length of resource name of second dependent resource + - N bytes containing the resource name of second dependent resource, where 0 < N < 32 + */ + EDeRegisterResourceDependency + }; + /** + Enumeration of sub-category values for trace category EResourceManagerUs. + @see EResourceManagerUs + @prototype 9.5 + */ + enum TResourceManagerUs + { + /** + Trace output for the start of opening a channel to the Resource Controller. + + Trace data format: + - 4 bytes containing the client thread identifier. + - 4 bytes containing the length of client name. + - N bytes containing the client name, where 0 < N < 32 + */ + EOpenChannelUsStart = 0, + /** + Trace output for the end of opening a channel to the Resource Controller. + + Trace data format: + - 4 bytes containing the client identifier provided by the Resource Controller + - 4 bytes containing the length of client name. + - N bytes containing the client name, where 0 < N < 32 + */ + EOpenChannelUsEnd, + /** + Trace output for the start of registering a client with the Resource Controller. + + Trace data format: + - 4 bytes containing the client identifier provided by the Resource Controller + - 1 bytes the number of concurrent change resource state operations to be supported + - 1 bytes the number of concurrent notification requests to be supported + - 1 bytes the number of concurrent get resource state operations to be supported + - 1 bytes unused + - 4 bytes containing the length of client name. + - N bytes containing the client name, where 0 < N < 32 + */ + ERegisterClientUsStart, + /** + Trace output for the end of registering a client with the Resource Controller. + + Trace data format: + - 4 bytes containing the client identifier provided by the Resource Controller. + - 4 bytes specifying the value returned from the call to Resource Controller's AllocReserve method + */ + ERegisterClientUsEnd, + /** + Trace output for the start of de-registering a client with the Resource Controller. + + Trace data format: + - 4 bytes containing the client identifier provided by the Resource Controller. + - 4 bytes containing the length of client name. + - N bytes containing the client name, where 0 < N < 32 + */ + EDeRegisterClientUsStart, + /** + Trace output for the end of registering a client with the Resource Controller. + + Trace data format: + - 4 bytes containing the client identifier provided by the Resource Controller. + */ + EDeRegisterClientUsEnd, + /** + Trace output for the start of a GetResourceState request to the Resource Controller. + + Trace data format: + - 4 bytes specifying the resource ID + - 4 bytes containing the client identifier provided by the Resource Controller. + - 4 bytes containing the length of client name. + - N bytes containing the client name, where 0 < N < 32 + */ + EGetResourceStateUsStart, + /** + Trace output for the end of a GetResourceState request to the Resource Controller. + + Trace data format: + - 4 bytes specifying the resource ID + - 4 bytes specifying the resource level + - 4 bytes containing the client identifier + - 4 bytes specifying the success code returned by the Resource Controller. + */ + EGetResourceStateUsEnd, + /** + Trace output for the start of a ChangeResourceState request to the Resource Controller. + + Trace data format: + - 4 bytes specifying the resource ID + - 4 bytes specifying the required state + - 4 bytes containing the client identifier provided by the Resource Controller. + - 4 bytes containing the length of client name. + - N bytes containing the client name, where 0 < N < 32 + */ + ESetResourceStateUsStart, + /** + Trace output for the end of a ChangeResourceState request to the Resource Controller. + + Trace data format: + - 4 bytes specifying the resource ID + - 4 bytes specifying the requested state + - 4 bytes containing the client identifier + - 4 bytes specifying the success code returned by the Resource Controller. + */ + ESetResourceStateUsEnd, + /** + Trace output for the start of a cancel GetResourceState request to the Resource Controller. + + Trace data format: + - 4 bytes specifying the resource ID + - 4 bytes containing the client identifier provided by the Resource Controller. + - 4 bytes containing the length of client name. + - N bytes containing the client name, where 0 < N < 32 + */ + ECancelGetResourceStateUsStart, + /** + Trace output for the end of a cancel GetResourceState request to the Resource Controller. + + Trace data format: + - 4 bytes specifying the resource ID + - 4 bytes containing the client identifier provided by the Resource Controller. + - 4 bytes containing the length of client name. + - N bytes containing the client name, where 0 < N < 32 + */ + ECancelGetResourceStateUsEnd, + /** + Trace output for the start of a cancel ChangeResourceState request to the Resource Controller. + + Trace data format: + - 4 bytes specifying the resource ID + - 4 bytes containing the client identifier provided by the Resource Controller. + - 4 bytes containing the length of client name. + - N bytes containing the client name, where 0 < N < 32 + */ + ECancelSetResourceStateUsStart, + /** + Trace output for the end of a cancel ChangeResourceState request to the Resource Controller. + + Trace data format: + - 4 bytes specifying the resource ID + - 4 bytes containing the client identifier provided by the Resource Controller. + - 4 bytes containing the length of client name. + - N bytes containing the client name, where 0 < N < 32 + */ + ECancelSetResourceStateUsEnd + }; + + /** + Enumeration of sub-category values for trace category EThreadPriority. + @see EThreadPriority + @internalTechnology + @prototype 9.3 + */ + enum TThreadPriority + { + /** + Trace output when a nanothread priority is changed. + + Trace data format: + - 4 bytes containing the context id (an NThread*) for the thread whose priority is changing. + - 4 bytes containing the new absolute priority. + */ + ENThreadPriority=0, + + /** + Trace output when a DThread's default priority is set. + + Trace data format: + - 4 bytes containing the context id (an NThread*) for the thread whose priority is changing. + - 4 bytes containing the iThreadPriority member - a value from enum ::TThrdPriority. + - 4 bytes containing the new default absolute priority. + */ + EDThreadPriority=1, + + /** + Trace output when a DProcess priority is changed. + + Trace data format: + - 4 bytes containing trace id (a DProcess*) for process. + - 4 bytes containing the new process priority, a value from enum ::TProcPriority + */ + EProcessPriority=2 + }; /** Enumeration of sub-category values for trace category EPagingMedia. diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/e32ktran.h --- a/kernel/eka/include/e32ktran.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/include/e32ktran.h Fri Jul 09 13:13:20 2010 +0100 @@ -1,4 +1,4 @@ -// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 1995-2010 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" @@ -28,37 +28,68 @@ #include #include #include -// + +/** +Represents a specific combination of modifier +keys. + +The definition will match a given a key combination +bitfield, if when anded with the mask iMask, it equals +iValue. Bitfields are made up of bits defined in TEventModifier. + +eg. to match Ctrl and Shift and not Fn modifiers + +iMask = EModifierShift | EModifierCtrl | EModifierFunc +iValue = EModifierShift | EModifierCtrl +*/ class TMaskedModifiers { public: - TUint iMask; - TUint iValue; + TUint iMask; //!< Mask to be binary anded with some value + TUint iValue; //!< Must match the masked bitfield }; -// + +/** +Defines different match types to be used +in TKeyCodePattern +*/ enum TPattern { - EAnyKey=0x00, - EAnyAlphaNumeric, - EAnyAlpha, - EAnyAlphaLowerCase, - EAnyAlphaUpperCase, - EAnyDecimalDigit, + EAnyKey=0x00, ///< match any key + EAnyAlphaNumeric, ///< match any alpha or numeric key + EAnyAlpha, ///< match any alpha key + EAnyAlphaLowerCase, ///< match any lower-case key + EAnyAlphaUpperCase, ///< match any upper-case key + EAnyDecimalDigit, ///< match any decimal digit EAnyDigitGivenRadix, - EAnyModifierKey, - EMatchKey=0x40, - EMatchKeyCaseInsens, - EMatchLeftOrRight + EAnyModifierKey, ///< match any modifier key (e.g. alt, fn, ctrl) + EMatchKey=0x40, ///< match if equal to keycode value in first field + EMatchKeyCaseInsens, ///< like EMatchKey but perform case-insensitive comparison + EMatchLeftOrRight ///< match if equal to keycode value or (keycode value + 1) }; -// + +/** +Defines a keypress using one of the match types defined in TPattern +and possibly a reference scan code. It is possible to specify generic +or specific keypresses eg. any decimal digit, or a particular +key, matched case insensitively. + +@see TPattern +*/ class TKeyCodePattern { public: - TUint16 iKeyCode; - TInt8 iPattern; + TUint16 iKeyCode; ///< Reference scancode, used when iPattern is EMatchKey, EMatchKeyCaseInsens, or EMatchLeftOrRight + TInt8 iPattern; ///< Comparison, of type TPattern TInt8 iFiller; }; -// + +/** +A Capture Key is a special key or key combination which should be +sent to a specific window-group, instead of the currently +active window. For example a camera application might request that +camera button events always be sent to it. +*/ class TCaptureKey { public: @@ -67,7 +98,10 @@ TUint iApp; TUint iHandle; }; -// + +/** +Used by CKeyTranslator to return translation results. +*/ class TKeyData { public: @@ -77,7 +111,12 @@ TBool iIsCaptureKey; TUint iKeyCode; }; -// + +/** +A set of TCaptureKey objects which is passed to a CKeyTranslator +when translating key events. This is so it can indicate if a +translated key event should be treated as a special Capture Key. +*/ class CCaptureKeys: public CBase { public: @@ -93,11 +132,19 @@ IMPORT_C void ProcessCaptureKeys(TKeyData &aKeyData) const; protected: void CheckCaptureKey(const TCaptureKey &aCaptureKey); - void removeCaptureKey(TUint index); protected: RArray iCKarray; }; -// + +/** +A CKeyTranslator derived object will be created by the window server +in order to translate key scancode data, contained in a TRawEvent, in to +generic logical key press, as defined in TKeyCode. Essentially, these +translations + +The translator object will perform the actual lookups using data from +a platform specific keymap DLL, conventionally named ekdata.dll. +*/ class CKeyTranslator: public CBase { public: diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/e32ver.h --- a/kernel/eka/include/e32ver.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/include/e32ver.h Fri Jul 09 13:13:20 2010 +0100 @@ -28,7 +28,7 @@ const TInt KE32MajorVersionNumber=2; const TInt KE32MinorVersionNumber=0; -const TInt KE32BuildVersionNumber=3102; +const TInt KE32BuildVersionNumber=3106; const TInt KMachineConfigurationMajorVersionNumber=1; const TInt KMachineConfigurationMinorVersionNumber=0; diff -r a5496987b1da -r 189ece41fa29 kernel/eka/include/k32keys.h --- a/kernel/eka/include/k32keys.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kernel/eka/include/k32keys.h Fri Jul 09 13:13:20 2010 +0100 @@ -1,4 +1,4 @@ -// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 1997-2010 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" @@ -70,6 +70,12 @@ /** +A contiguous range of logical scancodes of type, and ordering, as +defined in TStdScanCode. +Once aligned with an array of target keycodes, a pairwise +association between each scancode and its translation will +be defined. + @publishedPartner @released */ @@ -80,6 +86,9 @@ }; /** +An array of SScanCodeBlock scancode ranges. This allows +a discontiguous set of scancodes to be treated contiguously. + @publishedPartner @released */ @@ -90,27 +99,37 @@ }; /** +Associates an SScanCodeBlockList with +a specific set of target keycodes. This defines a concrete +translation for the scancodes in the scanCodes block list. + @publishedPartner @released */ struct SConvSubTable { - const TUint16 *pkeyCode; + const TUint16 *pkeyCode; //DClientDmaRequest::CallBack: TDmaResult result = %d, NKern::TContext context = %d", aResult, context)); @@ -503,7 +507,7 @@ Kern::QueueRequestComplete(self.iClient, self.iClientDataRequest, KErrNone); } -const TInt DDmaTestSession::KMaxChunkSize; +const TInt DDmaTestSession::KMaxChunkSize = 8 * KMega; TInt DDmaTestSession::RequestUserHandle(DThread* aThread, TOwnerType aType) { @@ -517,24 +521,31 @@ {} // called in thread critical section -TInt DDmaTestSession::DoCreate(TInt /*aUnit*/, const TDesC8* aInfo, const TVersion& /*aVer*/) +TInt DDmaTestSession::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/) { __NK_ASSERT_ALWAYS(iDfcQ == NULL); __NK_ASSERT_ALWAYS(iIsrCallbackDfcQ == NULL); TInt r = Kern::DynamicDfcQCreate(iDfcQ, KDFCThreadPriority, KDFCThreadName); if (r != KErrNone) + { + Kern::Printf("DDmaTestSession::DoCreate D_DMA_DFC_THREAD returned (%d)\n", r); return r; + } NKern::ThreadSetCpuAffinity((NThread*)(iDfcQ->iThread), KCpuAffinityAny); r = Kern::DynamicDfcQCreate(iIsrCallbackDfcQ, KDFCThreadPriority, KIsrCbDfcThreadName); if (r != KErrNone) + { + Kern::Printf("DDmaTestSession::DoCreate D_DMA_IsrCb_thread returned (%d)\n", r); return r; + } NKern::ThreadSetCpuAffinity((NThread*)(iIsrCallbackDfcQ->iThread), KCpuAffinityAny); iClient = &Kern::CurrentThread(); r = CreateSharedChunk(); + Kern::Printf("DDmaTestSession::DoCreate CreateSharedChunk returned (%d)\n", r); return r; } @@ -636,6 +647,18 @@ TInt r = ResumeDmaChannelByCookie(driverCookie); return r; } + case RDmaSession::ELinkChannel: + { + TUint driverCookie = reinterpret_cast(a1); + TInt r = LinkDmaChannelByCookie(driverCookie); + return r; + } + case RDmaSession::EUnlinkChannel: + { + TUint driverCookie = reinterpret_cast(a1); + TInt r = UnlinkDmaChannelByCookie(driverCookie); + return r; + } case RDmaSession::EFragmentCount: { TUint requestCookie = reinterpret_cast(a1); @@ -915,6 +938,64 @@ channel->CancelAll(); } +TInt DDmaTestSession::LinkDmaChannelByIndex(TInt aIndex) + { + __KTRACE_OPT(KDMA, Kern::Printf("LinkDmaChannelByIndex: %d", aIndex)); + __NK_ASSERT_DEBUG(aIndex < iChannels.Count()); + +#ifdef DMA_APIV2 + TDmaChannel* channel = iChannels[aIndex]; + return channel->LinkToChannel(channel); +#else + return KErrNotSupported; +#endif + } + +TInt DDmaTestSession::LinkDmaChannelByCookie(TUint aDriverCookie) + { + __KTRACE_OPT(KDMA, Kern::Printf("LinkDmaChannelByCookie: 0x%08x", aDriverCookie)); + const TInt index = CookieToChannelIndex(aDriverCookie); + + if(index >= 0) + { + TInt r = LinkDmaChannelByIndex(index); + return r; + } + else + { + return KErrNotFound; + } + } + +TInt DDmaTestSession::UnlinkDmaChannelByIndex(TInt aIndex) + { + __KTRACE_OPT(KDMA, Kern::Printf("UnlinkDmaChannelByIndex: %d", aIndex)); + __NK_ASSERT_DEBUG(aIndex < iChannels.Count()); + +#ifdef DMA_APIV2 + TDmaChannel* channel = iChannels[aIndex]; + return channel->LinkToChannel(NULL); +#else + return KErrNotSupported; +#endif + } + +TInt DDmaTestSession::UnlinkDmaChannelByCookie(TUint aDriverCookie) + { + __KTRACE_OPT(KDMA, Kern::Printf("UnlinkDmaChannelByCookie: 0x%08x", aDriverCookie)); + const TInt index = CookieToChannelIndex(aDriverCookie); + + if(index >= 0) + { + TInt r = UnlinkDmaChannelByIndex(index); + return r; + } + else + { + return KErrNotFound; + } + } + TInt DDmaTestSession::PauseDmaChannelByIndex(TInt aIndex) { __KTRACE_OPT(KDMA, Kern::Printf("PauseDmaChannelByIndex: %d", aIndex)); @@ -1152,7 +1233,10 @@ TChunkCreateInfo info; info.iType = TChunkCreateInfo::ESharedKernelSingle; info.iMaxSize = KMaxChunkSize; +#ifndef __WINS__ info.iMapAttr = EMapAttrFullyBlocking | EMapAttrUserRw; +#endif + info.iOwnsMemory = ETrue; info.iDestroyedDfc = NULL; @@ -1299,16 +1383,28 @@ newInfo.iMemMemPslInfo = aOldInfo.iMemMemPslInfo; newInfo.iMaxSbChannels = aOldInfo.iMaxSbChannels; - for(TInt i=0; i(aDriverCookie)); } + TInt ChannelLinking(TUint aDriverCookie) + { + return DoControl(ELinkChannel, reinterpret_cast(aDriverCookie)); + } + + TInt ChannelUnLinking(TUint aDriverCookie) + { + return DoControl(EUnlinkChannel, reinterpret_cast(aDriverCookie)); + } + TInt ChannelCaps(TUint aDriverCookie, SDmacCaps& aChannelCaps) { TDmacTestCaps caps; @@ -460,9 +476,16 @@ TInt Open() { - return DoCreate(KTestDmaLddName,TestDmaLddVersion(), 0, NULL, NULL, EOwnerThread); + TInt r = KErrNone; + r = DoCreate(KTestDmaLddNameHw,TestDmaLddVersion(), 0, NULL, NULL, EOwnerThread); + RDebug::Printf("RDmaSession::Open returned %d", r); + return r; } + TInt OpenSim() + { + return DoCreate(KTestDmaLddNameSim,TestDmaLddVersion(), 0, NULL, NULL, EOwnerThread); + } TInt RequestCreateOld(TUint aChannelCookie, TUint& aRequestCookie, TUint aMaxTransferSize=0) { @@ -571,15 +594,15 @@ TUint chunkHandle = DoControl(EOpenSharedChunk); return aChunk.SetReturnedHandle(chunkHandle); } - + TInt GetTestInfo(TDmaV2TestInfo& aInfo) { TPckg package(aInfo); return DoControl(EGetTestInfo, &package); } - static void SelfTest(); - + static void SelfTest(TBool aSimulatedDmac); + static void ApiTest(); #endif // __KERNEL_MODE__ @@ -664,7 +687,9 @@ EIsOpened, EIsrRedoRequest, ECancelAllChannel, - EQueueRequestWithReque + EQueueRequestWithReque, + ELinkChannel, + EUnlinkChannel, }; }; #endif // __D_DMA2_H__ diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/dmav2/d_dma2_cmn.cpp --- a/kerneltest/e32test/dmav2/d_dma2_cmn.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/e32test/dmav2/d_dma2_cmn.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -17,10 +17,20 @@ */ #ifdef __KERNEL_MODE__ #include + +#ifdef __DMASIM__ +#ifdef __WINS__ +typedef TLinAddr TPhysAddr; +#endif +static inline TPhysAddr LinToPhys(TLinAddr aLin) {return aLin;} +#else +static inline TPhysAddr LinToPhys(TLinAddr aLin) {return Epoc::LinearToPhysical(aLin);} +#endif #endif #include "d_dma2.h" + TInt Log2(TInt aNum) { TInt res = -1; @@ -240,7 +250,7 @@ iSrcAddr += aChunkBase; #ifdef __KERNEL_MODE__ - iSrcAddr = Epoc::LinearToPhysical(iSrcAddr); + iSrcAddr = LinToPhys(iSrcAddr); TEST_ASSERT(iSrcAddr != KPhysAddrInvalid); #endif } @@ -258,7 +268,7 @@ iDstAddr += aChunkBase; #ifdef __KERNEL_MODE__ - iDstAddr = Epoc::LinearToPhysical(iDstAddr); + iDstAddr = LinToPhys(iDstAddr); TEST_ASSERT(iDstAddr != KPhysAddrInvalid); #endif } @@ -321,9 +331,9 @@ void TAddressParms::MakePhysical() { #ifdef __KERNEL_MODE__ - iSrcAddr = Epoc::LinearToPhysical(iSrcAddr); + iSrcAddr = LinToPhys(iSrcAddr); TEST_ASSERT(iSrcAddr != KPhysAddrInvalid); - iDstAddr = Epoc::LinearToPhysical(iDstAddr); + iDstAddr = LinToPhys(iDstAddr); TEST_ASSERT(iDstAddr != KPhysAddrInvalid); #else TEST_FAULT; @@ -385,7 +395,7 @@ { TUint chunkStart = 0; #ifdef __KERNEL_MODE__ - chunkStart = Epoc::LinearToPhysical(aStart); + chunkStart = LinToPhys(aStart); TEST_ASSERT(chunkStart != KPhysAddrInvalid); #else chunkStart = aStart; diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/dmav2/dma2_sim.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/dmav2/dma2_sim.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,728 @@ +// Copyright (c) 2010 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: +// os/kernelhwsrv/kerneltest/e32test/dmav2/dma2_sim.cpp +// Partial simulation of DMA2 PSL +// +// + + +#include + +#include +#include + +#include "d_dma2.h" + +// Debug support +static const char KDmaPanicCat[] = "DMA PSL - " __FILE__; + +static const TInt KMaxTransferLen = 0x1000; // max transfer length for this DMAC +static const TInt KMemAlignMask = 0; // memory addresses passed to DMAC must be multiple of 8 +static const TInt KDesCount = 160; // Initial DMA descriptor count + +class TDmaDesc +// +// Hardware DMA descriptor +// + { +public: + enum {KStopBitMask = 1}; +public: + TPhysAddr iDescAddr; + TPhysAddr iSrcAddr; + TPhysAddr iDestAddr; + TUint32 iCmd; + }; + + +////////////////////////////////////////////////////////////////////////////// +// Test Support +////////////////////////////////////////////////////////////////////////////// + +/** +TO DO: Fill in to provide information to the V1 test harness (t_dma.exe) +*/ +TDmaTestInfo TestInfo = + { + 0, + 0, + 0, + 0, + NULL, + 0, + NULL, + 0, + NULL + }; + + +EXPORT_C const TDmaTestInfo& DmaTestInfo() +// +// +// + { + return TestInfo; + } + +/** +TO DO: Fill in to provide information to the V2 test harness (t_dma2.exe) +*/ +TDmaV2TestInfo TestInfov2 = + { + 0, + 0, + 0, + 0, + {0}, + 0, + {0}, + 1, + {0} + }; + +EXPORT_C const TDmaV2TestInfo& DmaTestInfoV2() + { + return TestInfov2; + } + + +////////////////////////////////////////////////////////////////////////////// +// Simulated channel +////////////////////////////////////////////////////////////////////////////// + +class MSimChannel + { +public: + virtual void PreOpen() {} + }; + +////////////////////////////////////////////////////////////////////////////// +// Derived Channel (Scatter/Gather) +////////////////////////////////////////////////////////////////////////////// + +const SDmacCaps KSimSgChanCaps = + {0, // TInt iChannelPriorities; + EFalse, // TBool iChannelPauseAndResume; + EFalse, // TBool iAddrAlignedToElementSize; + EFalse, // TBool i1DIndexAddressing; + EFalse, // TBool i2DIndexAddressing; + KDmaSyncAuto, // TUint iSynchronizationTypes; + KDmaBurstSizeAny, // TUint iBurstTransactions; + EFalse, // TBool iDescriptorInterrupt; + EFalse, // TBool iFrameInterrupt; + EFalse, // TBool iLinkedListPausedInterrupt; + EFalse, // TBool iEndiannessConversion; + KDmaGraphicsOpNone, // TUint iGraphicsOps; + EFalse, // TBool iRepeatingTransfers; + EFalse, // TBool iChannelLinking; + ETrue, // TBool iHwDescriptors; + EFalse, // TBool iSrcDstAsymmetry; + EFalse, // TBool iAsymHwDescriptors; + EFalse, // TBool iBalancedAsymSegments; + EFalse, // TBool iAsymCompletionInterrupt; + EFalse, // TBool iAsymDescriptorInterrupt; + EFalse, // TBool iAsymFrameInterrupt; + {0, 0, 0, 0, 0} // TUint32 iReserved[5]; + }; + +const SDmacCaps KSimSwChanCaps = + {0, // TInt iChannelPriorities; + EFalse, // TBool iChannelPauseAndResume; + EFalse, // TBool iAddrAlignedToElementSize; + EFalse, // TBool i1DIndexAddressing; + EFalse, // TBool i2DIndexAddressing; + KDmaSyncAuto, // TUint iSynchronizationTypes; + KDmaBurstSizeAny, // TUint iBurstTransactions; + EFalse, // TBool iDescriptorInterrupt; + EFalse, // TBool iFrameInterrupt; + EFalse, // TBool iLinkedListPausedInterrupt; + EFalse, // TBool iEndiannessConversion; + KDmaGraphicsOpNone, // TUint iGraphicsOps; + EFalse, // TBool iRepeatingTransfers; + EFalse, // TBool iChannelLinking; + EFalse, // TBool iHwDescriptors; + EFalse, // TBool iSrcDstAsymmetry; + EFalse, // TBool iAsymHwDescriptors; + EFalse, // TBool iBalancedAsymSegments; + EFalse, // TBool iAsymCompletionInterrupt; + EFalse, // TBool iAsymDescriptorInterrupt; + EFalse, // TBool iAsymFrameInterrupt; + {0, 0, 0, 0, 0} // TUint32 iReserved[5]; + }; + +class TEmptyChannel : public TDmaChannel, public MSimChannel + { +public: + // Virtual from TDmaChannel + void DoCancelAll(); + + void CallDefaultVirtuals(); + + // From MSimChannel + void PreOpen(); + }; + +void TEmptyChannel::DoCancelAll() + { + __DMA_CANT_HAPPEN(); + } + +void TEmptyChannel::CallDefaultVirtuals() + { + DMA_PSL_TRACE("Calling default virtual TDmaChannel functions"); + + const DDmaRequest* req = NULL; + SDmaDesHdr* hdr = NULL; + + DoQueue(*req); + DoDfc(*req, hdr); + DoDfc(*req, hdr, hdr); + + QueuedRequestCountChanged(); + } + +void TEmptyChannel::PreOpen() + { + CallDefaultVirtuals(); + } + +////////////////////////////////////////////////////////////////////////////// +// Derived SkelControllerSw Class +////////////////////////////////////////////////////////////////////////////// + +class TSkelDmac : public TDmac + { +public: + TSkelDmac(const SCreateInfo& aInfo); + TInt Create(const SCreateInfo& aInfo); +private: + // from TDmac (PIL pure virtual) + virtual void StopTransfer(const TDmaChannel& aChannel); + virtual TBool IsIdle(const TDmaChannel& aChannel); + virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags, + TUint aDstFlags, TUint32 aPslInfo); + virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aSrcFlags, + TUint aDstFlags, TUint32 aPslInfo); + + inline TDmaDesc* HdrToHwDes(const SDmaDesHdr& aHdr); + + void CallDefaultVirtuals(); + TInt TestPool(); + +public: + static const SCreateInfo KDmacInfoHw; + static const SCreateInfo KDmacInfoSw; + + TEmptyChannel iChannel; + }; + + +const TDmac::SCreateInfo TSkelDmac::KDmacInfoHw = + { + ETrue, // iCapsHwDes + KDesCount, // iDesCount + sizeof(TDmaDesc), // iDesSize +#ifndef __WINS__ + EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs +#endif + }; + +const TDmac::SCreateInfo TSkelDmac::KDmacInfoSw = + { + EFalse, // iCapsHwDes + KDesCount, // iDesCount + sizeof(TDmaTransferArgs), // iDesSize +#ifndef __WINS__ + EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs +#endif + }; + +static TSkelDmac SkelControllerSw(TSkelDmac::KDmacInfoSw); +static TSkelDmac SkelControllerHw(TSkelDmac::KDmacInfoHw); + + +TSkelDmac::TSkelDmac(const SCreateInfo& aInfo) +// +// Constructor. +// + : TDmac(aInfo) + { + // TODO remove this once DMAC can be created and destroyed from test LDD entry + // point + TInt r = Create(aInfo); + __NK_ASSERT_ALWAYS(r == KErrNone); + + CallDefaultVirtuals(); + r = TestPool(); + __NK_ASSERT_ALWAYS(r == KErrNone); + } + + +TInt TSkelDmac::Create(const SCreateInfo& aInfo) +// +// Second phase construction. +// + { + TInt r = TDmac::Create(aInfo); // Base class Create() + if (r == KErrNone) + { + __DMA_ASSERTA(ReserveSetOfDes(1) == KErrNone); + } + return r; + } + + +void TSkelDmac::StopTransfer(const TDmaChannel& aChannel) +// +// Stops a running channel. +// + { + const TUint8 i = static_cast(aChannel.PslId()); + + __KTRACE_OPT(KDMA, Kern::Printf(">TSkelDmac::StopTransfer channel=%d (unsupported)", i)); + + (void) i; + + } + + +TBool TSkelDmac::IsIdle(const TDmaChannel& aChannel) +// +// Returns the state of a given channel. +// + { + const TUint8 i = static_cast(aChannel.PslId()); + + __KTRACE_OPT(KDMA, Kern::Printf(">TSkelDmac::IsIdle channel=%d (unsupported)", i)); + + // TO DO (for instance): Return the state of the RUN bit of the channel. + // The return value should reflect the actual state. + (void) i; + + return ETrue; + } + + +TUint TSkelDmac::MaxTransferLength(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, + TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) +// +// Returns the maximum transfer length in bytes for a given transfer. +// + { + // TO DO: Determine the proper return value, based on the arguments. + + // For instance: + return KMaxTransferLen; + } + + +TUint TSkelDmac::AddressAlignMask(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, + TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) +// +// Returns the memory buffer alignment restrictions mask for a given transfer. +// + { + // TO DO: Determine the proper return value, based on the arguments. + + // For instance: + return KMemAlignMask; + } + + +inline TDmaDesc* TSkelDmac::HdrToHwDes(const SDmaDesHdr& aHdr) +// +// Changes return type of base class call. +// + { + return static_cast(TDmac::HdrToHwDes(aHdr)); + } + +/** +Call the default virtual functions on the TDmac, +that would never otherwise be called + +*/ +void TSkelDmac::CallDefaultVirtuals() + { + DMA_PSL_TRACE("Calling default virtual TDmac functions"); + + TDmaChannel* channel = NULL; + SDmaDesHdr* hdr = NULL; + + Transfer(*channel, *hdr); + Transfer(*channel, *hdr, *hdr); + + const TDmaTransferArgs args; + TInt r = KErrNone; + + r = InitHwDes(*hdr, args); + __NK_ASSERT_ALWAYS(r == KErrGeneral); + + r = InitSrcHwDes(*hdr, args); + __NK_ASSERT_ALWAYS(r == KErrGeneral); + + r = InitDstHwDes(*hdr, args); + __NK_ASSERT_ALWAYS(r == KErrGeneral); + + r = UpdateHwDes(*hdr, KPhysAddrInvalid, KPhysAddrInvalid, 0, 0); + __NK_ASSERT_ALWAYS(r == KErrGeneral); + + r = UpdateSrcHwDes(*hdr, KPhysAddrInvalid, 0, 0); + __NK_ASSERT_ALWAYS(r == KErrGeneral); + + r = UpdateDstHwDes(*hdr, KPhysAddrInvalid, 0, 0); + __NK_ASSERT_ALWAYS(r == KErrGeneral); + + ChainHwDes(*hdr, *hdr); + AppendHwDes(*channel, *hdr, *hdr); + AppendHwDes(*channel, *hdr, *hdr, *hdr, *hdr); + UnlinkHwDes(*channel, *hdr); + + TUint32 count = 0; + + count = HwDesNumDstElementsTransferred(*hdr); + __NK_ASSERT_ALWAYS(count == 0); + + count = HwDesNumSrcElementsTransferred(*hdr); + __NK_ASSERT_ALWAYS(count == 0); + } + +TInt TSkelDmac::TestPool() + { + DMA_PSL_TRACE("TSkelDmac::TestPool()"); + TInt count = 0; + SDmaDesHdr* hdr = iFreeHdr; + TAny* des = iDesPool; + + TInt r = KErrNone; + while(hdr->iNext) + { + TAny* receivedDes = NULL; + if(iCapsHwDes) + { + receivedDes = HdrToHwDes(*hdr); + } + else + { + TDmaTransferArgs& args = HdrToDes(*hdr); + receivedDes = &args; + } + + if(receivedDes != des) + { + DMA_PSL_TRACE1("TSkelDmac::TestPool() failure: count=%d", count); + r = KErrGeneral; + break; + } + + hdr = hdr->iNext; + des = (TAny*)((TUint)des + iDesSize); + count++; + } + + if(count != (KDesCount - 1)) + { + DMA_PSL_TRACE2("TSkelDmac::TestPool() failure: count = %d != (iMaxDesCount -1) = %d", count, KDesCount-1); + r = KErrUnknown; + } + return r; + } + +////////////////////////////////////////////////////////////////////////////// +// Simulated Fragmentation Dmac +////////////////////////////////////////////////////////////////////////////// + + +const SDmacCaps KSimAsymmChanCaps = + {0, // TInt iChannelPriorities; + EFalse, // TBool iChannelPauseAndResume; + EFalse, // TBool iAddrAlignedToElementSize; + EFalse, // TBool i1DIndexAddressing; + EFalse, // TBool i2DIndexAddressing; + KDmaSyncAuto, // TUint iSynchronizationTypes; + KDmaBurstSizeAny, // TUint iBurstTransactions; + EFalse, // TBool iDescriptorInterrupt; + EFalse, // TBool iFrameInterrupt; + EFalse, // TBool iLinkedListPausedInterrupt; + EFalse, // TBool iEndiannessConversion; + KDmaGraphicsOpNone, // TUint iGraphicsOps; + EFalse, // TBool iRepeatingTransfers; + EFalse, // TBool iChannelLinking; + ETrue, // TBool iHwDescriptors; + EFalse, // TBool iSrcDstAsymmetry; + ETrue, // TBool iAsymHwDescriptors; + EFalse, // TBool iBalancedAsymSegments; + EFalse, // TBool iAsymCompletionInterrupt; + EFalse, // TBool iAsymDescriptorInterrupt; + EFalse, // TBool iAsymFrameInterrupt; + {0, 0, 0, 0, 0} // TUint32 iReserved[5]; + }; + +const SDmacCaps KSimAsymmBalancedChanCaps = + {0, // TInt iChannelPriorities; + EFalse, // TBool iChannelPauseAndResume; + EFalse, // TBool iAddrAlignedToElementSize; + EFalse, // TBool i1DIndexAddressing; + EFalse, // TBool i2DIndexAddressing; + KDmaSyncAuto, // TUint iSynchronizationTypes; + KDmaBurstSizeAny, // TUint iBurstTransactions; + EFalse, // TBool iDescriptorInterrupt; + EFalse, // TBool iFrameInterrupt; + EFalse, // TBool iLinkedListPausedInterrupt; + EFalse, // TBool iEndiannessConversion; + KDmaGraphicsOpNone, // TUint iGraphicsOps; + EFalse, // TBool iRepeatingTransfers; + EFalse, // TBool iChannelLinking; + ETrue, // TBool iHwDescriptors; + EFalse, // TBool iSrcDstAsymmetry; + ETrue, // TBool iAsymHwDescriptors; + ETrue, // TBool iBalancedAsymSegments; + EFalse, // TBool iAsymCompletionInterrupt; + EFalse, // TBool iAsymDescriptorInterrupt; + EFalse, // TBool iAsymFrameInterrupt; + {0, 0, 0, 0, 0} // TUint32 iReserved[5]; + }; + + +class TAsymmDmac : public TDmac + { + struct THwDes + { + TUint iAddr; + TUint iLength; + TUint iCookie; + }; +public: + TAsymmDmac(); + TInt Create(); +private: + // Work around for compiler which forbids this + // class from accessing the protected, nested TDmac::SCreateInfo + using TDmac::SCreateInfo; + + // from TDmac (PIL pure virtual) + virtual void StopTransfer(const TDmaChannel& aChannel); + virtual TBool IsIdle(const TDmaChannel& aChannel); + virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags, + TUint aDstFlags, TUint32 aPslInfo); + virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aSrcFlags, + TUint aDstFlags, TUint32 aPslInfo); + // from TDmac (PIL virtual) + TInt InitSrcHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/); + TInt InitDstHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/); + + void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr); + void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr); + + inline THwDes* HdrToHwDes(const SDmaDesHdr& aHdr); + +private: + static const SCreateInfo KInfo; +public: + static const TInt iChannelCount; + TEmptyChannel iChannel; + }; + +const TAsymmDmac::SCreateInfo TAsymmDmac::KInfo = + { + ETrue, // iCapsHwDes + KDesCount, // iDesCount + sizeof(THwDes), // iDesSize +#ifndef __WINS__ + EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs +#endif + }; + +const TInt TAsymmDmac::iChannelCount = 1; + +static TAsymmDmac AsymController; + +TAsymmDmac::TAsymmDmac() +// +// Constructor. +// + : TDmac(KInfo) + { + // TODO remove this once DMAC can be created and destroyed from test LDD entry + // point + TInt r = Create(); + __NK_ASSERT_ALWAYS(r == KErrNone); + } + + +TInt TAsymmDmac::Create() +// +// Second phase construction. +// + { + TInt r = TDmac::Create(KInfo); // Base class Create() + if (r == KErrNone) + { + __DMA_ASSERTA(ReserveSetOfDes(iChannelCount) == KErrNone); + } + return r; + } + + +void TAsymmDmac::StopTransfer(const TDmaChannel& /*aChannel*/) +// +// Stops a running channel. +// + { + __DMA_CANT_HAPPEN(); + } + + +TBool TAsymmDmac::IsIdle(const TDmaChannel& /*aChannel*/) +// +// Returns the state of a given channel. +// + { + __DMA_CANT_HAPPEN(); + return ETrue; + } + + +TUint TAsymmDmac::MaxTransferLength(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, + TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) +// +// Returns the maximum transfer length in bytes for a given transfer. +// + { + // TO DO: Determine the proper return value, based on the arguments. + + // For instance: + return KMaxTransferLen; + } + + +TUint TAsymmDmac::AddressAlignMask(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, + TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) +// +// Returns the memory buffer alignment restrictions mask for a given transfer. +// + { + // TO DO: Determine the proper return value, based on the arguments. + + // For instance: + return KMemAlignMask; + } + + +inline TAsymmDmac::THwDes* TAsymmDmac::HdrToHwDes(const SDmaDesHdr& aHdr) +// +// Changes return type of base class call. +// + { + return static_cast(TDmac::HdrToHwDes(aHdr)); + } + +TInt TAsymmDmac::InitSrcHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) + { + return KErrNone; + } + +TInt TAsymmDmac::InitDstHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) + { + return KErrNone; + } + +void TAsymmDmac::ChainHwDes(const SDmaDesHdr& /*aHdr*/, const SDmaDesHdr& /*aNextHdr*/) + { + } + +void TAsymmDmac::UnlinkHwDes(const TDmaChannel& /*aChannel*/, SDmaDesHdr& /*aHdr*/) + { + } + + + +////////////////////////////////////////////////////////////////////////////// +// Channel Opening/Closing (Channel Allocator) +////////////////////////////////////////////////////////////////////////////// + +struct TChanEntry + { + TChanEntry(TDmac& aController, TDmaChannel& aChannel, const SDmacCaps& aCaps) + : + iController(aController), + iChannel(aChannel), + iCaps(aCaps) + {} + + TDmac& iController; + TDmaChannel& iChannel; + const SDmacCaps& iCaps; + }; + +const TChanEntry ChannelTable[] = + { + TChanEntry(SkelControllerSw, SkelControllerSw.iChannel, KSimSwChanCaps), + TChanEntry(SkelControllerHw, SkelControllerHw.iChannel, KSimSgChanCaps), + TChanEntry(AsymController, AsymController.iChannel, KSimAsymmChanCaps), + TChanEntry(AsymController, AsymController.iChannel, KSimAsymmBalancedChanCaps) + }; + +static const TInt KChannelCount = ARRAY_LENGTH(ChannelTable); + +TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId, TBool /*aDynChannel*/, TUint /*aPriority*/) +// +// +// + { + __KTRACE_OPT(KDMA, Kern::Printf(">DmaChannelMgr::Open aOpenId=%d", aOpenId)); + + __DMA_ASSERTA(aOpenId < static_cast(KChannelCount)); + + const TChanEntry& entry = ChannelTable[aOpenId]; + TDmaChannel* pC = &entry.iChannel; + if (pC->IsOpened()) + { + pC = NULL; + } + else + { + pC->iController = &entry.iController; + pC->iPslId = aOpenId; + pC->iDmacCaps = &entry.iCaps; + + // It is safe to signal here, + // setting iController marks the channel + // as taken + Signal(); + + static_cast(pC)->PreOpen(); + + Wait(); + } + return pC; + } + + +void DmaChannelMgr::Close(TDmaChannel* /*aChannel*/) +// +// +// + { + // NOP + } + + +TInt DmaChannelMgr::StaticExtension(TInt /*aCmd*/, TAny* /*aArg*/) +// +// +// + { + return KErrNotSupported; + } diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/dmav2/self_test.cpp --- a/kerneltest/e32test/dmav2/self_test.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/e32test/dmav2/self_test.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -31,12 +31,23 @@ static RTest test(_L("t_dma2 test framework tests")); -void RDmaSession::SelfTest() +void RDmaSession::SelfTest(TBool aSimulatedDmac) { test.Start(_L("Simple transfer test")); - test.Next(_L("Open session")); + RDmaSession session; - TInt r = session.Open(); + TInt r = KErrUnknown; + if (aSimulatedDmac) + { + test.Next(_L("Open session (simulated DMA)")); + r = session.OpenSim(); + } + else + { + test.Next(_L("Open session")); + r = session.Open(); + } + test_KErrNone(r); test.Next(_L("Get test info")); @@ -134,16 +145,19 @@ test.Printf(_L("cookie recived = 0x%08x\n"), reqCookieNewStyle ); test_KErrNone(r); - test.Next(_L("Fragment for ISR callback")); - const TInt size = 128 * KKilo; - TDmaTransferArgs transferArgs(0, size, size, KDmaMemAddr, KDmaSyncAuto, KDmaRequestCallbackFromIsr); - r = session.FragmentRequest(reqCookieNewStyle, transferArgs); - test_KErrNone(r); + if(!aSimulatedDmac) + { + test.Next(_L("Fragment for ISR callback")); + const TInt size = 128 * KKilo; + TDmaTransferArgs transferArgs(0, size, size, KDmaMemAddr, KDmaSyncAuto, KDmaRequestCallbackFromIsr); + r = session.FragmentRequest(reqCookieNewStyle, transferArgs); + test_KErrNone(r); - TIsrRequeArgs reque; - test.Next(_L("Queue ISR callback - with default re-queue")); - r = session.QueueRequestWithRequeue(reqCookieNewStyle, &reque, 1); - test_KErrNone(r); + TIsrRequeArgs reque; + test.Next(_L("Queue ISR callback - with default re-queue")); + r = session.QueueRequestWithRequeue(reqCookieNewStyle, &reque, 1); + test_KErrNone(r); + } test.Next(_L("Destroy new-style Dma request")); r = session.RequestDestroy(reqCookieNewStyle); @@ -166,78 +180,81 @@ test(chunk.IsWritable()); test(chunk.IsReadable()); - test.Next(_L("Fragment(old style)")); - const TInt size = 128 * KKilo; - TInt i; - for(i = 0; i<10; i++) - { - TUint64 time = 0; - TDmaTransferArgs transferArgs(0, size, size, KDmaMemAddr); - r = session.FragmentRequestOld(reqCookie, transferArgs, &time); - test_KErrNone(r); - if(gVerboseOutput) - { - test.Printf(_L("%lu us\n"), time); - } - } - - test.Next(_L("Queue")); - TRequestStatus status; - - for(i = 0; i<10; i++) + if(!aSimulatedDmac) { - TUint64 time = 0; - r = session.QueueRequest(reqCookie, status, 0, &time); - User::WaitForRequest(status); - test_KErrNone(r); - if(gVerboseOutput) + test.Next(_L("Fragment(old style)")); + const TInt size = 128 * KKilo; + TInt i; + for(i = 0; i<10; i++) { - test.Printf(_L("%lu us\n"), time); + TUint64 time = 0; + TDmaTransferArgs transferArgs(0, size, size, KDmaMemAddr); + r = session.FragmentRequestOld(reqCookie, transferArgs, &time); + test_KErrNone(r); + if(gVerboseOutput) + { + test.Printf(_L("%lu us\n"), time); + } } - } - if(newPil) - { - test.Next(_L("Fragment(new style)")); - TDmaTransferArgs transferArgs; - transferArgs.iSrcConfig.iAddr = 0; - transferArgs.iDstConfig.iAddr = size; - transferArgs.iSrcConfig.iFlags = KDmaMemAddr; - transferArgs.iDstConfig.iFlags = KDmaMemAddr; - transferArgs.iTransferCount = size; + test.Next(_L("Queue")); + TRequestStatus status; for(i = 0; i<10; i++) { TUint64 time = 0; - r = session.FragmentRequest(reqCookie, transferArgs, &time); + r = session.QueueRequest(reqCookie, status, 0, &time); + User::WaitForRequest(status); test_KErrNone(r); if(gVerboseOutput) { test.Printf(_L("%lu us\n"), time); } } - } - test.Next(_L("Queue")); - TCallbackRecord record; - r = session.QueueRequest(reqCookie, &record); - test_KErrNone(r); + if(newPil) + { + test.Next(_L("Fragment(new style)")); + TDmaTransferArgs transferArgs; + transferArgs.iSrcConfig.iAddr = 0; + transferArgs.iDstConfig.iAddr = size; + transferArgs.iSrcConfig.iFlags = KDmaMemAddr; + transferArgs.iDstConfig.iFlags = KDmaMemAddr; + transferArgs.iTransferCount = size; - test.Next(_L("check TCallbackRecord record")); - if(gVerboseOutput) - { - record.Print(); - } - const TCallbackRecord expected(TCallbackRecord::EThread, 1); - if(!(record == expected)) + for(i = 0; i<10; i++) + { + TUint64 time = 0; + r = session.FragmentRequest(reqCookie, transferArgs, &time); + test_KErrNone(r); + if(gVerboseOutput) + { + test.Printf(_L("%lu us\n"), time); + } + } + } + + test.Next(_L("Queue")); + TCallbackRecord record; + r = session.QueueRequest(reqCookie, &record); + test_KErrNone(r); + + test.Next(_L("check TCallbackRecord record")); + if(gVerboseOutput) { - test.Printf(_L("TCallbackRecords did not match")); - if(gVerboseOutput) + record.Print(); + } + const TCallbackRecord expected(TCallbackRecord::EThread, 1); + if(!(record == expected)) { - test.Printf(_L("expected:")); - expected.Print(); + test.Printf(_L("TCallbackRecords did not match")); + if(gVerboseOutput) + { + test.Printf(_L("expected:")); + expected.Print(); + } + TEST_FAULT; } - TEST_FAULT; } test.Next(_L("Destroy Dma request")); @@ -259,7 +276,6 @@ RTest::CloseHandleAndWaitForDestruction(session); test.End(); - } const SDmacCaps KTestCapSet = @@ -815,7 +831,12 @@ void SelfTests() { test.Next(_L("Running framework unit tests")); - RDmaSession::SelfTest(); +#ifndef __WINS__ + // Cannot connect real driver on Emulator - only + // simulator + RDmaSession::SelfTest(EFalse); +#endif + RDmaSession::SelfTest(ETrue); TDmaCapability::SelfTest(); TTestCase::SelfTest(); TTransferIter::SelfTest(); diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/dmav2/t_dma2.cpp --- a/kerneltest/e32test/dmav2/t_dma2.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/e32test/dmav2/t_dma2.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -131,6 +131,7 @@ if(iDmaSession.Handle() == KNullHandle) { TInt r = iDmaSession.Open(); + RDebug::Printf("CDmaTest::OpenDmaSession = %d\n", r); TEST_ASSERT(r == KErrNone); r = iDmaSession.OpenSharedChunk(iChunk); TEST_ASSERT(r == KErrNone); @@ -700,6 +701,87 @@ } ////////////////////////////////////////////////////////////////////// +// CPauseResumeNegTest +// +// -Open DMA Channel +// -Pause and Resume DMA channel +// -Check that KErrNotSupported is returned +// -Close DMA Channel +////////////////////////////////////////////////////////////////////// +CPauseResumeNegTest::~CPauseResumeNegTest() + { + } + +void CPauseResumeNegTest::RunTest() + { + OpenDmaSession(); + + //Open a single DMA channel for a transfer + OpenChannel(); + + RDebug::Printf("Resume unpaused idle channel"); + TInt r = iDmaSession.ChannelResume(iChannelSessionCookie); + TEST_ASSERT(KErrNotSupported == r); + + RDebug::Printf("Pause idle channel"); + r = iDmaSession.ChannelPause(iChannelSessionCookie); + TEST_ASSERT(KErrNotSupported == r); + + RDebug::Printf("Pause paused idle Channel"); + r = iDmaSession.ChannelPause(iChannelSessionCookie); + TEST_ASSERT(KErrNotSupported == r); + + RDebug::Printf("Resume paused idle channel"); + r = iDmaSession.ChannelResume(iChannelSessionCookie); + TEST_ASSERT(KErrNotSupported == r); + + CloseChannel(); + CloseDmaSession(); + } + +void CPauseResumeNegTest::PrintTestType() const + { + RDebug::RawPrint(_L("Pause and Resume API Test - Negative Test")); + } + +////////////////////////////////////////////////////////////////////// +// CLinkChannelTest +// +// -Open DMA Channel +// -Link and Unlink DMA channel +// -Check that KErrNotSupported is returned +// -Close DMA Channel +// +////////////////////////////////////////////////////////////////////// +CLinkChannelTest::~CLinkChannelTest() + { + } + +void CLinkChannelTest::RunTest() + { + OpenDmaSession(); + + //Open a single DMA channel for a transfer + OpenChannel(); + + RDebug::Printf("Linking DMA channels"); + TInt r = iDmaSession.ChannelLinking(iChannelSessionCookie); + TEST_ASSERT(KErrNotSupported == r); + + RDebug::Printf("Unlinking DMA channels"); + r = iDmaSession.ChannelUnLinking(iChannelSessionCookie); + TEST_ASSERT(KErrNotSupported == r); + + CloseChannel(); + CloseDmaSession(); + } + +void CLinkChannelTest::PrintTestType() const + { + RDebug::RawPrint(_L("Channel Linking API Test - Negative Test")); + } + +////////////////////////////////////////////////////////////////////// // COpenCloseTest ////////////////////////////////////////////////////////////////////// COpenCloseTest::~COpenCloseTest() @@ -1999,8 +2081,8 @@ case EEndiannessConversion: case EGraphicsOps: case ERepeatingTransfers: - case EChannelLinking: - TEST_FAULT; + case EChannelLinking: + return aChannelCaps.iChannelLinking == (TBool)iValue; case EHwDescriptors: return aChannelCaps.iHwDescriptors == (TBool)iValue; case ESrcDstAsymmetry: @@ -2502,13 +2584,81 @@ testRunner.AddTestCases(TestArray);//Add all test cases } - test.Next(_L("call TTestRunner::RunTests()\n")); testRunner.RunTests(); test.End(); } + +struct TSimTest + { + TUint iPslId; + TBool iFragment; + }; + +const TSimTest KSimTests[] = + { + {0, EFalse}, + {1, EFalse}, + {2, ETrue}, + {3, ETrue}, + }; + +const TInt KSimTestsCount = ARRAY_LENGTH(KSimTests); + +void RunSimDMATests() + { + test.Start(_L("Run simulated DMAC tests\n")); + + test.Next(_L("Open session")); + RDmaSession session; + TInt r = session.OpenSim(); + test_KErrNone(r); + + for(TInt i=0; i TestArray(StaticTestArray, ARRAY_LENGTH(StaticTestArray)); diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/eabi/d_dma2_simu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/eabi/d_dma2_simu.def Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,56 @@ +EXPORTS + _Z19CreateLogicalDevicev @ 1 NONAME + _Z11DmaTestInfov @ 2 NONAME + _Z13DmaTestInfoV2v @ 3 NONAME + _ZN11DDmaRequest11FreeDesListEv @ 4 NONAME + _ZN11DDmaRequest13ExpandDesListEi @ 5 NONAME + _ZN11DDmaRequest13FragmentCountEv @ 6 NONAME + _ZN11DDmaRequest14FreeDstDesListEv @ 7 NONAME + _ZN11DDmaRequest14FreeSrcDesListEv @ 8 NONAME + _ZN11DDmaRequest16DstFragmentCountEv @ 9 NONAME + _ZN11DDmaRequest16ExpandDstDesListEi @ 10 NONAME + _ZN11DDmaRequest16ExpandSrcDesListEi @ 11 NONAME + _ZN11DDmaRequest16SrcFragmentCountEv @ 12 NONAME + _ZN11DDmaRequest24EnableDstElementCountingEi @ 13 NONAME + _ZN11DDmaRequest24EnableSrcElementCountingEi @ 14 NONAME + _ZN11DDmaRequest25DisableDstElementCountingEv @ 15 NONAME + _ZN11DDmaRequest25DisableSrcElementCountingEv @ 16 NONAME + _ZN11DDmaRequest30TotalNumDstElementsTransferredEv @ 17 NONAME + _ZN11DDmaRequest30TotalNumSrcElementsTransferredEv @ 18 NONAME + _ZN11DDmaRequest5QueueEv @ 19 NONAME + _ZN11DDmaRequest8FragmentERK16TDmaTransferArgs @ 20 NONAME + _ZN11DDmaRequest8FragmentEmmijm @ 21 NONAME + _ZN11DDmaRequestC1ER11TDmaChannelPFvNS_7TResultEPvES3_i @ 22 NONAME + _ZN11DDmaRequestC1ER11TDmaChannelPFvj10TDmaResultPvP10SDmaDesHdrES3_j @ 23 NONAME + _ZN11DDmaRequestC2ER11TDmaChannelPFvNS_7TResultEPvES3_i @ 24 NONAME + _ZN11DDmaRequestC2ER11TDmaChannelPFvj10TDmaResultPvP10SDmaDesHdrES3_j @ 25 NONAME + _ZN11DDmaRequestD0Ev @ 26 NONAME + _ZN11DDmaRequestD1Ev @ 27 NONAME + _ZN11DDmaRequestD2Ev @ 28 NONAME + _ZN11TDmaChannel13LinkToChannelEPS_ @ 29 NONAME + _ZN11TDmaChannel14IsrRedoRequestEmmjmi @ 30 NONAME + _ZN11TDmaChannel15StaticExtensionEiPv @ 31 NONAME + _ZN11TDmaChannel16AddressAlignMaskEjjm @ 32 NONAME + _ZN11TDmaChannel17MaxTransferLengthEjjm @ 33 NONAME + _ZN11TDmaChannel18MissNextInterruptsEi @ 34 NONAME + _ZN11TDmaChannel4OpenERKNS_11SCreateInfoERPS_ @ 35 NONAME + _ZN11TDmaChannel5CloseEv @ 36 NONAME + _ZN11TDmaChannel5PauseEv @ 37 NONAME + _ZN11TDmaChannel6ResumeEv @ 38 NONAME + _ZN11TDmaChannel8DmacCapsEv @ 39 NONAME + _ZN11TDmaChannel8FailNextEi @ 40 NONAME + _ZN11TDmaChannel9CancelAllEv @ 41 NONAME + _ZN11TDmaChannel9ExtensionEiPv @ 42 NONAME + _ZN16TDmaTransferArgsC1ERK18TDmaTransferConfigS2_mjj15TDmaGraphicsOpsm @ 43 NONAME + _ZN16TDmaTransferArgsC1Ejjjjjj12TDmaAddrModejj13TDmaBurstSizej15TDmaGraphicsOpsm @ 44 NONAME + _ZN16TDmaTransferArgsC1Ev @ 45 NONAME + _ZN16TDmaTransferArgsC2ERK18TDmaTransferConfigS2_mjj15TDmaGraphicsOpsm @ 46 NONAME + _ZN16TDmaTransferArgsC2Ejjjjjj12TDmaAddrModejj13TDmaBurstSizej15TDmaGraphicsOpsm @ 47 NONAME + _ZN16TDmaTransferArgsC2Ev @ 48 NONAME + _ZN18TDmaTransferConfigC1Emj12TDmaAddrModej13TDmaBurstSizejjji @ 49 NONAME + _ZN18TDmaTransferConfigC1Emjjjiijj13TDmaBurstSizejji @ 50 NONAME + _ZN18TDmaTransferConfigC1Ev @ 51 NONAME + _ZN18TDmaTransferConfigC2Emj12TDmaAddrModej13TDmaBurstSizejjji @ 52 NONAME + _ZN18TDmaTransferConfigC2Emjjjiijj13TDmaBurstSizejji @ 53 NONAME + _ZN18TDmaTransferConfigC2Ev @ 54 NONAME + diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/eabi/i2c_masterstubs_ctrlessu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/eabi/i2c_masterstubs_ctrlessu.def Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,24 @@ +EXPORTS + _Z20CreatePhysicalDevicev @ 1 NONAME + _ZN20TIicBusSlaveCallback7DfcFuncEPv @ 2 NONAME + _ZN25DIicBusChannelMasterSlaveC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 3 NONAME + _ZN25DIicBusChannelMasterSlaveC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 4 NONAME + _ZN31DSimulatedIicBusChannelSlaveI2cC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 5 NONAME + _ZN31DSimulatedIicBusChannelSlaveI2cC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 6 NONAME + _ZN32DSimulatedIicBusChannelMasterI2cC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 7 NONAME + _ZN32DSimulatedIicBusChannelMasterI2cC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 8 NONAME + _ZN37DSimulatedIicBusChannelMasterSlaveI2cC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP32DSimulatedIicBusChannelMasterI2cP31DSimulatedIicBusChannelSlaveI2c @ 9 NONAME + _ZN37DSimulatedIicBusChannelMasterSlaveI2cC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP32DSimulatedIicBusChannelMasterI2cP31DSimulatedIicBusChannelSlaveI2c @ 10 NONAME + _ZTI19DIicBusChannelSlave @ 11 NONAME + _ZTI20DIicBusChannelMaster @ 12 NONAME + _ZTI25DIicBusChannelMasterSlave @ 13 NONAME + _ZTI31DSimulatedIicBusChannelSlaveI2c @ 14 NONAME + _ZTI32DSimulatedIicBusChannelMasterI2c @ 15 NONAME + _ZTI37DSimulatedIicBusChannelMasterSlaveI2c @ 16 NONAME + _ZTV19DIicBusChannelSlave @ 17 NONAME + _ZTV20DIicBusChannelMaster @ 18 NONAME + _ZTV25DIicBusChannelMasterSlave @ 19 NONAME + _ZTV31DSimulatedIicBusChannelSlaveI2c @ 20 NONAME + _ZTV32DSimulatedIicBusChannelMasterI2c @ 21 NONAME + _ZTV37DSimulatedIicBusChannelMasterSlaveI2c @ 22 NONAME + diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/eabi/i2c_slavestubs_ctrlessu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/eabi/i2c_slavestubs_ctrlessu.def Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,24 @@ +EXPORTS + _Z20CreatePhysicalDevicev @ 1 NONAME + _ZN20TIicBusSlaveCallback7DfcFuncEPv @ 2 NONAME + _ZN25DIicBusChannelMasterSlaveC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 3 NONAME + _ZN25DIicBusChannelMasterSlaveC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 4 NONAME + _ZN31DSimulatedIicBusChannelSlaveI2cC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 5 NONAME + _ZN31DSimulatedIicBusChannelSlaveI2cC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 6 NONAME + _ZN32DSimulatedIicBusChannelMasterI2cC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 7 NONAME + _ZN32DSimulatedIicBusChannelMasterI2cC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 8 NONAME + _ZN37DSimulatedIicBusChannelMasterSlaveI2cC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP32DSimulatedIicBusChannelMasterI2cP31DSimulatedIicBusChannelSlaveI2c @ 9 NONAME + _ZN37DSimulatedIicBusChannelMasterSlaveI2cC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP32DSimulatedIicBusChannelMasterI2cP31DSimulatedIicBusChannelSlaveI2c @ 10 NONAME + _ZTI19DIicBusChannelSlave @ 11 NONAME + _ZTI20DIicBusChannelMaster @ 12 NONAME + _ZTI25DIicBusChannelMasterSlave @ 13 NONAME + _ZTI31DSimulatedIicBusChannelSlaveI2c @ 14 NONAME + _ZTI32DSimulatedIicBusChannelMasterI2c @ 15 NONAME + _ZTI37DSimulatedIicBusChannelMasterSlaveI2c @ 16 NONAME + _ZTV19DIicBusChannelSlave @ 17 NONAME + _ZTV20DIicBusChannelMaster @ 18 NONAME + _ZTV25DIicBusChannelMasterSlave @ 19 NONAME + _ZTV31DSimulatedIicBusChannelSlaveI2c @ 20 NONAME + _ZTV32DSimulatedIicBusChannelMasterI2c @ 21 NONAME + _ZTV37DSimulatedIicBusChannelMasterSlaveI2c @ 22 NONAME + diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/group/bld.inf --- a/kerneltest/e32test/group/bld.inf Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/e32test/group/bld.inf Fri Jul 09 13:13:20 2010 +0100 @@ -136,16 +136,19 @@ rescontrol_psl support rescontrol_extended_psl support d_rescontrolcli support +d_rescontrolclisync support d_extendedrescontrolcli support d_prmacctstsim support ../resmanus/resourcecontrol support ../resmanus/resourcecontrollerextended support +../resmanus/d_resmanusbtrace support #endif // DMA kernel-side test harness for software-simulated DMA framework // software-simulated DMA framework d_dmasim support dmasim support +d_dma2_sim support // Examples for demand paging device driver migration d_pagingexample_1_pre support @@ -191,15 +194,20 @@ #if !defined(X86) ../iic/iic_psl/iic_testpsl support -../iic/iic_psl/spi support -../iic/iic_psl/i2c support +../iic/iic_psl/spi support +../iic/iic_psl/i2c support ../iic/iic_psl/d_iic_client support -../iic/iic_psl/d_iic_slaveclient support +../iic/iic_psl/d_iic_slaveclient support ../iic/iic_psl/spi_ctrless support ../iic/iic_psl/i2c_ctrless support ../iic/iic_psl/d_iic_client_ctrless support ../iic/iic_psl/d_iic_slaveclient_ctrless support + +../iic/iic_psl/i2c_masterstubs_ctrless support +../iic/iic_psl/i2c_slavestubs_ctrless support +../iic/iic_psl/d_iic_client_stubs support +../iic/iic_psl/d_iic_slaveclient_stubs support #endif #if !defined(WINS) && !defined(X86) @@ -830,7 +838,8 @@ t_wwins manual t_mmcpw manual -t_keys support +refkeymap support //Reference template keyboard look-up tables for T_KEYS test +t_keys // /E32TEST/Y2K tests t_y2k @@ -986,11 +995,13 @@ ../resmanus/t_resmanus ../resmanus/t_resmanuskern ../resmanus/t_resmanusextended +../resmanus/t_resmanusbtrace #endif // /E32TEST/RESOURCEMAN tests #if !defined X86 t_rescontrolcli +t_rescontrolclisync t_extendedrescontrolcli t_prmacctstsim #endif diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/group/d_dma2_sim.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/group/d_dma2_sim.mmp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,52 @@ +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "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: +// + +#include "kernel/kern_ext.mmh" + +target d_dma2_sim.ldd +targettype ldd + +// It is not actually necessary to export DMA API functions +// from this simulated binary +noexportlibrary + +deffile ../~/d_dma2_sim.def + +sourcepath ../../../../kernelhwsrv/kernel/eka/drivers/dma +source dma2_pil.cpp dma2_shared.cpp + +sourcepath ../dmav2 +source d_dma2.cpp d_dma2_cmn.cpp dma2_sim.cpp + + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +epocallowdlldata + +start wins +win32_headers +end + +capability all +VENDORID 0x70000001 + +#ifdef SMP +MACRO CPU_AFFINITY_ANY +#endif + +SMPSAFE + +MACRO DMA_APIV2 +MACRO __DMASIM__ diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/group/d_rescontrolclisync.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/group/d_rescontrolclisync.mmp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,40 @@ +// Copyright (c) 2010 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: +// e32test/group/d_rescontrolcli.mmp +// +// + +#include "kernel/kern_ext.mmh" + +target d_rescontrolclisync.ldd +targettype ldd +sourcepath ../resourceman/ +source d_rescontrolclisync.cpp +OS_LAYER_SYSTEMINCLUDE_SYMBIAN +library resourcecontroller.lib + +uid 0x100000af +vendorid 0x70000001 + +capability all +epocallowdlldata + +start wins +win32_headers +end + +macro CPU_AFFINITY_ANY +SMPSAFE + + diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/group/refkeymap.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/group/refkeymap.mmp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,46 @@ +// Copyright (c) 2010 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: +// e32test/group/refkeymap.mmp +// refekdata.dll Reference template keyboard look-up tables for T_KEYS test +// +// + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +target refkdata.dll +targettype dll + + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +sourcepath ../../../bsptemplate/asspandvariant/template_variant/specific +source keymap.cpp + +library euser.lib + +deffile ../../../kernel/eka/~/ekdata.def + +nostrictdef + +capability all + +uid 0x1000008d 0x100039e0 +vendorid 0x70000001 + +SMPSAFE +unpagedcode diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/group/t_camera_api.mmp --- a/kerneltest/e32test/group/t_camera_api.mmp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -// Copyright (c) 2005-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: -// e32test/group/t_camera_api.mmp -// -// - -target t_camera_api.exe -targettype exe -sourcepath ../multimedia -source t_camera_api.cpp -source t_camera_display.cpp -source t_camera_bitmap.cpp -library euser.lib hal.lib efsrv.lib -OS_LAYER_SYSTEMINCLUDE_SYMBIAN - -capability ALL -TCB -vendorid 0x70000001 -epocheapsize 1048576 16777216 - -SMPSAFE diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/group/t_camera_gen.mmp --- a/kerneltest/e32test/group/t_camera_gen.mmp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -// Copyright (c) 2005-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: -// e32test/group/t_camera_gen.mmp -// -// - -target t_camera_gen.exe -targettype exe -sourcepath ../multimedia -source t_camera_gen.cpp -source t_camera_display.cpp -library euser.lib hal.lib -OS_LAYER_SYSTEMINCLUDE_SYMBIAN - -capability ALL -TCB -vendorid 0x70000001 - - -SMPSAFE diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/group/t_rescontrolclisync.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/group/t_rescontrolclisync.mmp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,35 @@ +// Copyright (c) 2010 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: +// e32test/group/t_rescontrolcli.mmp +// +// + +target t_rescontrolclisync.exe +targettype exe +sourcepath ../resourceman/ +source t_rescontrolclisync.cpp +library euser.lib +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + + +capability all + +vendorid 0x70000001 + +start wins +win32_headers +end + + +SMPSAFE diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/iic_psl/d_iic_client_stubs.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/iic/iic_psl/d_iic_client_stubs.mmp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,54 @@ +// Copyright (c) 2008-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: +// e32test/group/d_iic_client_stubs.mmp +// Created for code coverage tests. + + +#include "kernel/kern_ext.mmh" + +target iic_client_stubs.ldd +targettype ldd + +//Both macros are only used for channel creation. It will create +//all 3 types of channels(Master, Slave, MasterSlave) when both +//macros are defined. For our code coverage improving tests, +//we need all these 3 types of channels, so we enable both macros here. +macro MASTER_MODE +macro SLAVE_MODE + +macro IIC_SIMULATED_PSL +macro STANDALONE_CHANNEL +macro IIC_STUBS + +sourcepath . +source iic_client.cpp +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +// un-comment the following if debug printing is required +//macro LOG_CLIENT + +library spi_ctrless.lib +library i2c_masterstubs_ctrless.lib + +uid 0x100000af 0x10286b4d +VENDORID 0x70000001 + +capability all +epocallowdlldata + +start wins +win32_headers +end + +SMPSAFE \ No newline at end of file diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/iic_psl/d_iic_slaveclient_stubs.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/iic/iic_psl/d_iic_slaveclient_stubs.mmp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,53 @@ +// Copyright (c) 2008-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: +// e32test/group/d_iic_slaveclient_stubs.mmp +// created for code coverage tests + +#include "kernel/kern_ext.mmh" + +target iic_slaveclient_stubs.ldd +targettype ldd + +//These macros are only used for channel creation +//In the code coverage tests, we need all three types of channels +//(Master, Slave, MasterSlave) to be tested, so enable both macros here. +macro MASTER_MODE +macro SLAVE_MODE + +macro IIC_SIMULATED_PSL + +macro STANDALONE_CHANNEL +macro IIC_STUBS + +sourcepath . +source iic_slaveclient.cpp +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +// un-comment the following if debug printing is required +//macro LOG_SLAVECLIENT + +library spi_ctrless.lib +library i2c_slavestubs_ctrless.lib + +uid 0x100000af 0x10286b4e +VENDORID 0x70000001 + +capability all +epocallowdlldata + +start wins +win32_headers +end + +SMPSAFE diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/iic_psl/i2c.cpp --- a/kerneltest/e32test/iic/iic_psl/i2c.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/e32test/iic/iic_psl/i2c.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -47,14 +47,15 @@ } #endif/*STANDALONE_CHANNEL*/ -#ifdef SLAVE_MODE +//Macros MASTER_MODE and SLAVE_MODE are intentionally omitted from this file +//This is for master and slave stubs to exercise the channel class, +//and we need these stubs for code coverage tests. LOCAL_C TInt16 AssignSlaveChanId() { static TInt16 iBaseSlaveChanId = KI2cSlaveChannelIdBase; I2C_PRINT(("I2C AssignSlaveChanId - on entry, iBaseSlaveChanId = 0x%x\n",iBaseSlaveChanId)); return iBaseSlaveChanId++; // Arbitrary, for illustration } -#endif/*SLAVE_MODE*/ NONSHARABLE_CLASS(DSimulatedI2cDevice) : public DPhysicalDevice { @@ -230,8 +231,6 @@ return new DSimulatedI2cDevice; } - -#ifdef MASTER_MODE #ifdef STANDALONE_CHANNEL EXPORT_C #endif @@ -253,6 +252,8 @@ if(r == KErrNone) SetDfcQ((TDfcQue*)iDynamicDfcQ); DSimulatedIicBusChannelMasterI2c::SetRequestDelayed(this,EFalse); + //Call to base class DoCreate(not strictly necessary) + DIicBusChannelMaster::DoCreate(); return r; } @@ -423,7 +424,8 @@ default: { Kern::Printf("aFunction %d is not recognised \n",aFunction); - r=KErrNotSupported; + //For default case call the base class method for consistent handling + r=DIicBusChannelMaster::StaticExtension(aFunction,NULL,NULL); } } @@ -433,11 +435,6 @@ return r; } -//#ifdef MASTER_MODE -#endif - -#ifdef SLAVE_MODE - void DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback(TAny* aPtr) { // To support simulating an asynchronous capture operation @@ -1042,7 +1039,8 @@ default: { Kern::Printf("aFunction %d is not recognised \n",aFunction); - r=KErrNotSupported; + //For default case call the base class method for consistent handling + r=DIicBusChannelSlave::StaticExtension(aFunction,NULL,NULL); } } #ifdef IIC_INSTRUMENTATION_MACRO @@ -1051,12 +1049,6 @@ return r; } - - -//#ifdef MASTER_MODE -#endif - -#if defined(MASTER_MODE) && defined(SLAVE_MODE) #ifdef STANDALONE_CHANNEL EXPORT_C #endif @@ -1107,15 +1099,13 @@ default: { Kern::Printf("aFunction %d is not recognised \n",aFunction); - r=KErrNotSupported; + //For default case call the base class method for consistent handling + r=DIicBusChannelMasterSlave::StaticExtension(aFunction,NULL,NULL); } } return r; } -//#if defined(MASTER_MODE) && defined(SLAVE_MODE) -#endif - diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/iic_psl/i2c.h --- a/kerneltest/e32test/iic/iic_psl/i2c.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/e32test/iic/iic_psl/i2c.h Fri Jul 09 13:13:20 2010 +0100 @@ -42,15 +42,15 @@ #endif/*STANDALONE_CHANNEL*/ -#if defined(MASTER_MODE) const TInt KI2cThreadPriority = 5; // Arbitrary, can be 0-7, 7 highest -#endif const TInt16 KI2cSlaveChannelIdBase = 0x1D00; // Arbitrary const TInt KI2cSlaveAsyncDelaySim = 20; // Arbitrary delay, for timer to simulate asynchronous processing -#ifdef MASTER_MODE +//Macros MASTER_MODE and SLAVE_MODE are intentionally omitted from this file +//This is for master and slave stubs to exercise the channel class, +//and we need these stubs for code coverage tests. class DSimulatedIicBusChannelMasterI2c : public DIicBusChannelMaster { // platform specific implementation @@ -87,9 +87,7 @@ #ifndef STANDALONE_CHANNEL TInt8 DSimulatedIicBusChannelMasterI2c::iCurrentChanNum = KI2cChannelNumBase; // Initialise static member of DSimulatedIicBusChannelMasterI2c #endif -#endif/*MASTER_MODE*/ -#ifdef SLAVE_MODE class DSimulatedIicBusChannelSlaveI2c : public DIicBusChannelSlave { public: @@ -150,9 +148,7 @@ NTimer iSlaveTimer; // Used to simulate an asynchronous capture operation TSpinLock iEventSpinLock; // To serialise simulated bus events - Rx, Tx or Rx+Tx }; -#endif/*SLAVE_MODE*/ -#if defined(MASTER_MODE) && defined(SLAVE_MODE) class DSimulatedIicBusChannelMasterSlaveI2c : public DIicBusChannelMasterSlave { public: @@ -163,6 +159,5 @@ TInt StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2); }; -#endif/*(MASTER_MODE) && (SLAVE_MODE)*/ #endif /*I2C_H_*/ diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/iic_psl/i2c_masterstubs_ctrless.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/iic/iic_psl/i2c_masterstubs_ctrless.mmp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,63 @@ +// Copyright (c) 2008-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: +// e32test/iic/iic_psl/i2c_masterstubs_ctrless.mmp +// + +macro STANDALONE_CHANNEL +#define STANDALONE_CHANNEL /*Only for iic_channel.mmh to pick up the needed source files*/ + +#include "../../../../kernel/eka/drivers/iic/iic_channel.mmh" + +//enable the SLAVE_MODE so all the functions defined in SLAVE_MODE can be tested. +macro SLAVE_MODE + + +target i2c_masterstubs_ctrless.pdd +targettype pdd + +sourcepath ../../../../kernel/eka/drivers/iic +source IIC_PIL_SOURCE + +sourcepath . +source i2c.cpp + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +macro IIC_SIMULATED_PSL +macro BUS_TYPE=(DIicBusChannel::EI2c) + +// un-comment the following if debug printing is required +//macro LOG_I2C + +// un-comment the following if BTRACE output is required +macro IIC_INSTRUMENTATION_MACRO + +deffile ../../~/i2c_masterstubs_ctrless.def + +uid 0x100039d0 0x10286b50 +VENDORID 0x70000001 + +//library ecust.lib +#ifdef WINS +library emulator.lib +#endif + +start wins +win32_library kernel32.lib +#if defined(VC32) +win32_library msvcrt.lib +#endif +end + +SMPSAFE \ No newline at end of file diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/iic_psl/i2c_slavestubs_ctrless.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/iic/iic_psl/i2c_slavestubs_ctrless.mmp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,62 @@ +// Copyright (c) 2008-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: +// e32test/iic/iic_psl/i2c_slave_stubs_ctrless.mmp +// + +macro STANDALONE_CHANNEL +#define STANDALONE_CHANNEL /*Only for iic_channel.mmh to pick up the needed source files*/ + +#include "../../../../kernel/eka/drivers/iic/iic_channel.mmh" + +macro MASTER_MODE + +target i2c_slavestubs_ctrless.pdd +targettype pdd + +sourcepath ../../../../kernel/eka/drivers/iic +source IIC_PIL_SOURCE + +sourcepath . +source i2c.cpp + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +macro IIC_SIMULATED_PSL +macro BUS_TYPE=(DIicBusChannel::EI2c) + +// un-comment the following if debug printing is required +//macro LOG_I2C + +// un-comment the following if BTRACE output is required +macro IIC_INSTRUMENTATION_MACRO + +deffile ../../~/i2c_slavestubs_ctrless.def + +uid 0x100039d0 0x10286b50 +VENDORID 0x70000001 + +//library ecust.lib +#ifdef WINS +library emulator.lib +#endif + +start wins +win32_library kernel32.lib +#if defined(VC32) +win32_library msvcrt.lib +#endif +end + +SMPSAFE + diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/iic_psl/iic_client.cpp --- a/kerneltest/e32test/iic/iic_psl/iic_client.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/e32test/iic/iic_psl/iic_client.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -112,8 +112,13 @@ #ifdef STANDALONE_CHANNEL +#ifdef IIC_STUBS +_LIT(KLddRootName,"iic_client_stubs"); +#else _LIT(KLddRootName,"iic_client_ctrless"); -#else +#endif/*IIC_STUBS*/ + +#else/*STANDALONE_CHANNEL*/ _LIT(KLddRootName,"iic_client"); #endif _LIT(KIicClientThreadName,"IicClientLddThread"); @@ -403,6 +408,7 @@ TInt StaticExtension(TUint aId, TUint aFunction, TAny* aParam1, TAny* aParam2); TInt CaptureChannel(TInt aBusId, TDes8* aConfigHdr, TIicBusSlaveCallback* aCallback, TInt& aChannelId, TBool aAsynch=NULL); TInt ReleaseChannel(TInt aChannelId); + TInt Spare1(TInt aBusId); public: inline void Lock() {Kern::MutexWait(*iArrayMutex);} inline void Unlock() {Kern::MutexSignal(*iArrayMutex);} @@ -1324,6 +1330,56 @@ return r; } +//this function is added for improving the code coverage of IIC. +//Spare1 is a placeholder for future expansion, and so returns KErrNotSupported. +#ifdef STANDALONE_CHANNEL +TInt DChannelIicClient::Spare1(TInt aBusId) + { + TInt r = KErrNone; + + TInt chanIndex = 0; + DIicClientChan* chanPtr = NULL; + if(r == KErrNone) + { + r = GetChanPtr(aBusId, chanIndex, chanPtr); + if(r == KErrNone) + { + if(!chanPtr) + { + r = KErrArgument; + } + else + { + switch(chanPtr->GetChanType()) + { + case DIicBusChannel::EMaster: + { + r = ((DIicBusChannelMaster*)(chanPtr->GetChannelPtr()))->Spare1(0,NULL,NULL); + break; + } + case DIicBusChannel::EMasterSlave: + { + r = KErrNotSupported; + break; + } + case DIicBusChannel::ESlave: + { + r = ((DIicBusChannelSlave*)(chanPtr->GetChannelPtr()))->Spare1(0,NULL,NULL); + break; + } + default: + { + r = KErrArgument; + } + } + } + } + } + return r; + } +#endif + +#ifndef IIC_STUBS void DChannelIicClient::DoCancel(TInt aMask) { // Cancel an outstanding request. @@ -1406,7 +1462,68 @@ return; } +#else/*IIC_STUBS*/ +//should only be called in IIC_STUBS mode +//DoCancel is used to cancel an asynchronous request which is still waiting in the queue and +//has not yet been handled by IIC. +//In the stub test, QueueTransaction should always return a KErrNotSupported error code +//So we pretend there is an request waiting in the queue that can be cancelled by calling DoCancel. +void DChannelIicClient::DoCancel(TInt aMask) + { + // Cancel an outstanding request. + CLIENT_PRINT(("DChannelIicClient::DoCancel invoked with aMask=0x%x\n", aMask)); + // inline void CancelAsyncOperation(TRequestStatus* aStatus, TInt aBusId) {TInt* parms[2]; parms[0]=(TInt*)aStatus; parms[1]=(TInt*)aBusId;DoCancel((TInt)&parms[0]);} + // aMask has the address on TInt* parms[2] + // parms[0] = TRequestStatus pointer + // parms[1] = Bus Identifier + TInt* parms[2]; + TInt r=Kern::ThreadRawRead(iClient,(TAny*)aMask,&(parms[0]),2*sizeof(TInt*)); + if(r!=KErrNone) + { + CLIENT_PRINT(("DChannelIicClient::DoCancel ERROR - Can't read parms[]\n")); + return; // Can't proceed if can't access request parameters + } + CLIENT_PRINT(("DChannelIicClient::DoCancel - TRequestStatus 0x%x, BusID = 0x%x\n",parms[0],parms[1])); + TRequestStatus* status= (TRequestStatus*)(parms[0]); + + //A valid transaction object is required here in order to exercise the API + TInt busIdI2c = (TInt)(parms[1]); + TConfigI2cBufV01* i2cBuf=NULL; + SET_BUS_TYPE(busIdI2c,EI2c); + SET_CHAN_NUM(busIdI2c,10); + // aDeviceId=1 ... 100kHz ... aTimeoutPeriod=100 ... aTransactionWaitCycles=10 - arbitrary paarmeters. + r=CreateI2cBuf(i2cBuf, EI2cAddr7Bit, 36, ELittleEndian, 100); + if(r!=KErrNone) + { + CLIENT_PRINT(("DChannelIicClient::DoCancel ERROR - Can't allocate memory for I2c buffer\n")); + return; // Can't proceed if can't access request parameters + } + + TIicBusTransfer* tfer = new TIicBusTransfer(TIicBusTransfer::EMasterWrite,8,i2cBuf); + if(tfer == NULL) + { + CLIENT_PRINT(("DChannelIicClient::DoCancel ERROR - Can't allocate memory for the transfer\n")); + delete i2cBuf; + return; + } + + TIicBusTransaction* transac = new TIicBusTransaction((TDes8*)i2cBuf, tfer); + if(transac == NULL) + { + CLIENT_PRINT(("DChannelIicClient::DoCancel ERROR - Can't allocate memory for the transaction\n")); + delete i2cBuf; + delete tfer; + return; + } + + r = CancelTransaction(busIdI2c, transac); + Kern::RequestComplete(iClient, status, r); + delete i2cBuf; + delete tfer; + delete transac; + } +#endif/*IIC_STUBS*/ // Function to support preamble testing void PreambleCallbackFunc(TIicBusTransaction* /*aTrans*/, TAny* aParam) @@ -2395,8 +2512,17 @@ r = channelInterface.TestInterface(); break; } + case(RBusDevIicClient::ETestSpare1): + { + r = Spare1((TInt)a1); + break; + } + case(RBusDevIicClient::ETestStaticEx): + { + r = StaticExtension((TUint32)a1, (TUint)RBusDevIicClient::ECtlIoNone, NULL, NULL); + break; + } #endif - default: { CLIENT_PRINT(("DChannelIicClient::DoControl - unrecognised value for aId=0x%x\n",aId)); diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/iic_psl/iic_slaveclient.cpp --- a/kerneltest/e32test/iic/iic_psl/iic_slaveclient.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/e32test/iic/iic_psl/iic_slaveclient.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -93,7 +93,11 @@ const TInt KMaxNumChannels = 2; // 1 "true" slave, one "dummy" #ifdef STANDALONE_CHANNEL +#ifdef IIC_STUBS +_LIT(KLddRootName,"iic_slaveclient_stubs"); +#else _LIT(KLddRootName,"iic_slaveclient_ctrless"); +#endif/*IIC_STUBS*/ #else _LIT(KLddRootName,"iic_slaveclient"); #endif @@ -164,6 +168,9 @@ TInt RegisterTxBuffer(TInt aChannelId, TPtr8 aTxBuffer, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset); TInt CaptureChannel(TInt aBusId, TDes8* aConfigHdr, TIicBusSlaveCallback* aCallback, TInt& aChannelId, TBool aAsynch=NULL); TInt ReleaseChannel(TInt aChannelId); +#ifdef STANDALONE_CHANNEL + TInt Spare1(TInt aBusId); +#endif private: TDynamicDfcQue* iDfcQue; TIicBusSlaveCallback* iNotif; @@ -471,6 +478,13 @@ DIicSlaveClientChan* aChanPtr = NULL; if(iCapturedChan.iChannelId == aChannelId) aChanPtr = iCapturedChan.iChannel; +#ifdef IIC_STUBS + //in the code coverage tests, a slave channel will not be captured before other slave + //operations get called, e.g. calling DIicBusChannelSlave::CaptureChannel in MASTER_MODE + //should return a KErrNotSupported. In controller-less mode, the client creates and manages its own channels. + //So in here, we pretend a slave channel has been captured and can be used for the current operation. + aChanPtr=iCapturedChan.iChannel; +#endif/*IIC_STUBS*/ if(!aChanPtr) return KErrArgument; if(aChanPtr->GetChanType() == DIicBusChannel::EMasterSlave) @@ -490,6 +504,13 @@ DIicSlaveClientChan* aChanPtr = NULL; if(iCapturedChan.iChannelId == aChannelId) aChanPtr = iCapturedChan.iChannel; +#ifdef IIC_STUBS + //in the code coverage tests, a slave channel will not be captured before other slave + //operations get called, e.g. calling DIicBusChannelSlave::CaptureChannel in MASTER_MODE + //should return a KErrNotSupported. In controller-less mode, the client creates and manages its own channels. + //So in here, we pretend a slave channel has been captured and can be used for the current operation. + aChanPtr=iCapturedChan.iChannel; +#endif/*IIC_STUBS*/ if(!aChanPtr) return KErrArgument; if(aChanPtr->GetChanType() == DIicBusChannel::EMasterSlave) @@ -529,6 +550,13 @@ DIicSlaveClientChan* aChanPtr = NULL; if(iCapturedChan.iChannelId == aChannelId) aChanPtr = iCapturedChan.iChannel; +#ifdef IIC_STUBS + //in the code coverage tests, a slave channel will not be captured before other slave + //operations get called, e.g. calling DIicBusChannelSlave::CaptureChannel in MASTER_MODE + //should return a KErrNotSupported. In controller-less mode, the client creates and manages its own channels. + //So in here, we pretend a slave channel has been captured and can be used for the current operation. + aChanPtr=iCapturedChan.iChannel; +#endif/*IIC_STUBS*/ if(!aChanPtr) return KErrArgument; if(aChanPtr->GetChanType() == DIicBusChannel::EMasterSlave) @@ -589,6 +617,13 @@ r = KErrArgument; } } +#ifdef IIC_STUBS + //if we try to capture a slave channel in MASTER_MODE, the capture should fail with KErrNotSupported. + //However, we need a slave channel to be captured before running most of slave operation + //tests,e.g. RegisterRxBuf. So in here, we pretend the channel is captured, and save + //the channel pointer in iCapturedChan, so it can be used for other slave operation tests. + iCapturedChan.iChannel = chanPtr; +#endif/*IIC_STUBS*/ // For synchronous capture, if successful then install the channel if(r == KErrNone) { @@ -630,6 +665,54 @@ #endif return r; } + +//this function is added for improving the code coverage of IIC. +//Spare1 is a placeholder for future expansion, so returns KErrNotSupported. +#ifdef STANDALONE_CHANNEL +TInt DChannelIicSlaveClient::Spare1(TInt aBusId) + { + TInt r = KErrNone; + DIicSlaveClientChan* chanPtr = NULL; + if(r == KErrNone) + { + r = GetChanPtr(aBusId, chanPtr); + if(r == KErrNone) + { + if(!chanPtr) + { + r = KErrArgument; + } + else + { + switch(chanPtr->GetChanType()) + { + case DIicBusChannel::EMaster: + { + r = ((DIicBusChannelMaster*)(chanPtr->GetChannelPtr()))->Spare1(0,NULL,NULL); + break; + } + case DIicBusChannel::EMasterSlave: + { + r = KErrNotSupported; + break; + } + case DIicBusChannel::ESlave: + { + r = ((DIicBusChannelSlave*)(chanPtr->GetChannelPtr()))->Spare1(0,NULL,NULL); + break; + } + default: + { + r = KErrArgument; + } + } + } + } + } + return r; + } +#endif + TInt DChannelIicSlaveClient::CbProcessOverUnderRunRxTx() { CLIENT_PRINT(("> DChannelIicSlaveClient::CbProcessOverUnderRunRxTx(), iTestOverUnderState=%d\n",iTestOverUnderState)); @@ -1335,7 +1418,13 @@ iFullDuplexReq |= (ERxAllBytes|ETxAllBytes); r = SetNotificationTrigger(parms[0],parms[1]); if(r == KErrTimedOut) + { + //the TRequestStatus is being completed with the error code to indicate + //that the timeout was detected, but KErrNone is returned because + //the requested notification settings were accepted. + Kern::RequestComplete(iClient, iStatus, r); r=KErrNone; // KErrTimedOut is returned if the Client has not interacted with IIC for a while + } break; } @@ -1532,7 +1621,23 @@ r = StaticExtension((TUint)a1, (TUint)ctrlIoVal, NULL, NULL); break; } - +#ifdef STANDALONE_CHANNEL + case(RBusDevIicClient::ETestSpare1): + { + //a1 represents a BusId passed from the user. + //Spare1 is a placeholder for future expansion. + r = Spare1((TInt)a1); + break; + } + case(RBusDevIicClient::ETestStaticEx): + { + //Passing a1, which represents a BusId, and the value of a function to StaticExtension. + //Using ECtlIoNone here, so StaticExtension will be called to execute the default case, + // but since this is only called when using stubs KErrNotSupported will be expected. + r = StaticExtension((TUint32)a1, (TUint)RBusDevIicClient::ECtlIoNone, NULL, NULL); + break; + } +#endif default: { CLIENT_PRINT(("DChannelIicSlaveClient::DoControl - unrecognised value for aId=0x%x\n",aId)); diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/iic_psl/iic_testpsl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/iic/iic_psl/iic_testpsl.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,106 @@ +// Copyright (c) 2008-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: +// e32test/iic/iic_psl/iic_testpsl.cpp +// + +#include +#include "iic_testpsl.h" + +// Global Controller pointer +extern DIicBusController*& gTheController; + +#ifndef IIC_SIMULATED_PSL + +#error iic_testpsl.cpp being built when IIC_SIMULATED_PSL is not defined + +#else + +TVersion DIicPdd::VersionRequired() + { + const TInt KIicMajorVersionNumber=1; + const TInt KIicMinorVersionNumber=0; + const TInt KIicBuildVersionNumber=KE32BuildVersionNumber; + return TVersion(KIicMajorVersionNumber,KIicMinorVersionNumber,KIicBuildVersionNumber); + } + +/** Factory class constructor */ +DIicPdd::DIicPdd() + { + iVersion = DIicPdd::VersionRequired(); + } + +DIicPdd::~DIicPdd() + { + delete gTheController; + } + +TInt DIicPdd::Install() + { + return(SetName(&KPddName)); + } + +/** Called by the kernel's device driver framework to create a Physical Channel. */ +TInt DIicPdd::Create(DBase*& /*aChannel*/, TInt /*aUint*/, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/) + { + return KErrNone; + } + +/** Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.*/ +TInt DIicPdd::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer) + { + if (!Kern::QueryVersionSupported(DIicPdd::VersionRequired(),aVer)) + return(KErrNotSupported); + return KErrNone; + } + +/** Return the driver capabilities */ +void DIicPdd::GetCaps(TDes8& aDes) const + { + // Create a capabilities object + TCaps caps; + caps.iVersion = iVersion; + // Zero the buffer + TInt maxLen = aDes.MaxLength(); + aDes.FillZ(maxLen); + // Copy cpabilities + TInt size=sizeof(caps); + if(size>maxLen) + size=maxLen; + aDes.Copy((TUint8*)&caps,size); + } + +static DIicPdd* TheIicPdd; + +DECLARE_STANDARD_PDD() + { + gTheController = new DIicBusController; + if(!gTheController) + return NULL; + TInt r = gTheController->Create(); + if(r == KErrNone) + { + TheIicPdd = new DIicPdd; + if(TheIicPdd) + return TheIicPdd; + } + + delete gTheController; + return NULL; + } + +#endif/*IIC_SIMULATED_PSL*/ + + + + diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/iic_psl/iic_testpsl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/iic/iic_psl/iic_testpsl.h Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,41 @@ +// Copyright (c) 2008-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: +// e32test/iic/iic_psl/iic_testpsl.h +// + +#ifndef IIC_TEST_PSL_H_ +#define IIC_TEST_PSL_H_ + +_LIT(KPddName,"iic.pdd"); + +NONSHARABLE_CLASS(DIicPdd) : public DPhysicalDevice + { +// Class to faciliate loading of the IIC classes +public: + class TCaps + { + public: + TVersion iVersion; + }; +public: + DIicPdd(); + ~DIicPdd(); + virtual TInt Install(); + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + virtual void GetCaps(TDes8& aDes) const; + inline static TVersion VersionRequired(); + }; + +#endif diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/iic_psl/iic_testpsl.mmp --- a/kerneltest/e32test/iic/iic_psl/iic_testpsl.mmp Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/e32test/iic/iic_psl/iic_testpsl.mmp Fri Jul 09 13:13:20 2010 +0100 @@ -28,9 +28,11 @@ sourcepath ../../../../kernel/eka/drivers/iic source iic.cpp iic_transaction.cpp +sourcepath . +source iic_testpsl.cpp OS_LAYER_SYSTEMINCLUDE_SYMBIAN -USERINCLUDE ../../../../kernel/eka/drivers/iic +USERINCLUDE . ../../../../kernel/eka/drivers/iic // un-comment the following if BTRACE output is required macro IIC_INSTRUMENTATION_MACRO diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/t_iic.cpp --- a/kerneltest/e32test/iic/t_iic.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/e32test/iic/t_iic.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -37,13 +37,28 @@ _LIT(KIicProxyFileNameRoot, "iic_client"); _LIT(KIicProxySlaveFileName, "iic_slaveclient.ldd"); // Kernel-side proxy LDD acting as a slave client of the IIC _LIT(KIicProxySlaveFileNameRoot, "iic_slaveclient"); +//These are used to exercise stub functions. +_LIT(KIicProxyFileNameStubs, "iic_client_stubs.ldd"); +_LIT(KIicProxyFileNameRootStubs, "iic_client_stubs"); +_LIT(KIicProxySlaveFileNameStubs, "iic_slaveclient_stubs.ldd"); +_LIT(KIicProxySlaveFileNameRootStubs, "iic_slaveclient_stubs"); + #ifdef IIC_SIMULATED_PSL _LIT(KSpiFileNameCtrlLess, "spi_ctrless.pdd"); // Simulated PSL bus implementation -_LIT(KI2cFileNameCtrlLess, "i2c_ctrless.pdd"); // Simulated PSL bus implementation +_LIT(KI2cFileNameCtrlLess, "i2c_ctrless.pdd"); // Simulated PSL bus implementation _LIT(KIicPslFileName, "iic_testpsl.pdd"); // Simulated PSL implementation _LIT(KSpiFileName, "spi.pdd"); // Simulated PSL bus implementation -_LIT(KI2cFileName, "i2c.pdd"); // Simulated PSL bus implementation +_LIT(KI2cFileName, "i2c.pdd"); // Simulated PSL bus implementation +//These are used to exercise stubs. The I2C pdd to use for stub tests will depend on +//whether Master, Slave mode has been selected. +#if defined(MASTER_MODE)&&!defined(SLAVE_MODE) +_LIT(KI2cFileNameStubs, "i2c_slavestubs_ctrless.pdd"); +#elif !defined(MASTER_MODE)&& defined(SLAVE_MODE) +_LIT(KI2cFileNameStubs, "i2c_masterstubs_ctrless.pdd"); +#else +_LIT(KI2cFileNameStubs, "i2c_ctrless.pdd"); +#endif #endif _LIT(KIicPslFileNameRoot, "iic.pdd"); @@ -730,6 +745,9 @@ //! of words. Wait for the TRequestStatus to be completed (with KErrNone). Specify a notification trigger for Tx and //! Tx Overrun, then use controlIO to instruct the simulated bus to unblock Master responses.Wait for the TRequestStatus //! to be completed. +//! +//! 12) Test the PIL behavior for a client timeout: request notification of an event but deliberately delay the client response. +//! The PIL should return KErrTimedOut when a subsequent request for a notification is made. //! //! @SYMTestExpectedResults 0) Kernel-side proxy client should return with KErrNone, exits otherwise. //! 1) Kernel-side proxy client should return with KErrNone, exits otherwise. @@ -750,6 +768,9 @@ //! TRequestStatus should be set to KErrNone, exits otherwise. //! 11) Kernel-side proxy client should return with KErrNone for each API call, exits otherwise. The associated //! TRequestStatus should be set to KErrNone in both cases, exits otherwise. +//! 12) Kernel-side proxy client should return with KErrNone for each API call, exits otherwise. The associated +//! TRequestStatus should be set to KErrNone in both cases, exits otherwise, except for when the client response +//! exceeds the timeout period, and the next request for a notification expects KErrTimedOut. //! //! @SYMTestPriority High //! @SYMTestStatus Implemented @@ -1189,6 +1210,50 @@ r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status); gTest(r==KErrNone); + //Test the PIL behavior for a client timeout: request notification of an event + //but deliberately delay the client response. The PIL should return KErrTimedOut + //when a subsequent request for a notification is made. + gTest.Printf(_L("Starting test for SendBusErrorAndReturn.\n")); + + // For Rx, specify buffer granularity=4 (32-bit words), 8 words to receive, offset of 16 bytes + // 64 bytes as 16 words: words 0-3 offset, words 4-11 data, words 12-15 unused + gTest.Printf(_L("Starting RegisterRxBuffer\n")); + r=gChanSlaveI2c.RegisterRxBuffer(chanId, 4, 8, 16); + gTest(r==KErrNone); + + // Now set the notification trigger + //TRequestStatus status; + triggerMask=ERxAllBytes; + + gTest.Printf(_L("Starting SetNotificationTrigger with ERxAllBytes\n")); + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status); + gTest(r==KErrNone); + // Now instruct the bus implementation to represent receipt of the required number of words from the bus master. + gTest.Printf(_L("Starting SimulateRxNWords\n")); + r=gChanSlaveI2c.SimulateRxNWords(busIdI2c, chanId, 8); + gTest(r==KErrNone); + // + // Wait for the notification + User::WaitForRequest(status); + r=status.Int(); + if(r != KErrNone) + { + gTest.Printf(_L("TRequestStatus value after receiving data = %d\n"),r); + gTest(r==KErrNone); + } + //Delay the client response to exceed the timeout period, and check that the next + //request for a notification encounters the expected error code. + User::After(1000 * 1000); + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status); + gTest(r==KErrNone); + User::WaitForRequest(status); + r = status.Int(); + if(r!=KErrTimedOut) + { + gTest.Printf(_L("TRequestStatus value = %d\n"),status.Int()); + gTest(r==KErrTimedOut); + } + gTest.Printf(_L("The test for SendBusErrorAndReturn is completed OK\n")); // Release the channel r = gChanSlaveI2c.ReleaseChannel( chanId ); gTest(r==KErrNone); @@ -1403,6 +1468,125 @@ } } +//Only get called in stand alone mode +LOCAL_C TInt IicTestStubs() + { + //Function to call the stub methods for Master and slave channels + //when Master and Slave functionality has not been built. The stubs + //return KErrNotSupported. + TInt r=KErrNone; + + TUint32 busIdI2c = 0; + TConfigI2cBufV01* i2cBuf=NULL; + TRequestStatus status; + + //Starting master channel stubs test. + //a valid transaction is required when calling the Master QueueTransaction stub. + //Use I2C channel here. In MASTER_MODE, channelId starting from 10, + //and 10 is a master channel + SET_BUS_TYPE(busIdI2c,EI2c); + SET_CHAN_NUM(busIdI2c,10); + // aDeviceId=1 ... 100kHz ... aTimeoutPeriod=100 ... aTransactionWaitCycles=10 - arbitrary paarmeters. + r=CreateI2cBuf(i2cBuf, EI2cAddr7Bit, 36, ELittleEndian, 100); + gTest(r==KErrNone); + + // Use a single transfer + _LIT(halfDuplexText,"Half Duplex Text"); + TBuf8<17> halfDuplexBuf_8; + halfDuplexBuf_8.Copy(halfDuplexText); + TUsideTferDesc* tfer = NULL; + r = CreateSingleUserSideTransfer(tfer, EMasterWrite, 8, &halfDuplexBuf_8, NULL); + gTest(r==KErrNone); + + // Create the transaction object + TUsideTracnDesc* tracn = NULL; + r = CreateSingleUserSideTransaction(tracn, EI2c, i2cBuf, tfer, NULL, 0, NULL, NULL); + gTest(r==KErrNone); + + // queue a synchronous transaction + gTest.Printf(_L("\n\nStarting synchronous QueueTransaction \n")); + r = gChanMasterI2c.QueueTransaction(busIdI2c, tracn); + gTest.Printf(_L("Synchronous QueueTransaction returned = %d\n"),r); + //Queueing a transaction in SLAVE_MODE should return KErrNotSupported + gTest(r==KErrNotSupported); + + // queue an asynchronous transaction and cancel the trasnaction + // QueueTransaction actually completes before CancelAsyncOperation with KErrNotSupported + // In test driver, we pretend the request is still in the queue and then cancel it. + gChanMasterI2c.QueueTransaction(status, busIdI2c, tracn); + gChanMasterI2c.CancelAsyncOperation(&status, busIdI2c); + User::WaitForRequest(status); + if(status != KErrNotSupported) + { + gTest.Printf(_L("TRequestStatus value after queue = %d\n"),status.Int()); + gTest(r==KErrNotSupported); + } + //spare1 is an unused method that is present to provide for future extension, + //which just returns KErrNotSupported. + r = gChanMasterI2c.TestSpare1(busIdI2c); + gTest(r == KErrNotSupported); + //StaticExtension is present for PSL implementations to override, the default + //implementation just returns KErrNotSupported + r = gChanMasterI2c.TestStaticExtension(busIdI2c); + gTest(r == KErrNotSupported); + //free the memory + delete i2cBuf; + delete tfer; + delete tracn; + + //Start to test slave channel operations + SET_BUS_TYPE(busIdI2c,EI2c); + SET_CHAN_NUM(busIdI2c,11); // 11 is the Slave channel number + // + // clock speed=36Hz, aTimeoutPeriod=100 - arbitrary parameter + r=CreateI2cBuf(i2cBuf, EI2cAddr7Bit, 36, ELittleEndian, 100); + gTest(r==KErrNone); + + // Synchronous capture of a Slave channel. + TInt chanId = 0; // Initialise to zero to silence compiler ... + gTest.Printf(_L("\n\nStarting synchronous CaptureChannel \n")); + r = gChanSlaveI2c.CaptureChannel(busIdI2c, i2cBuf, chanId ); + gTest.Printf(_L("Synchronous CaptureChannel returned = %d, aChanId=0x%x\n"),r,chanId); + gTest(r==KErrNotSupported); + + gTest.Printf(_L("Starting RegisterRxBuffer\n")); + r=gChanSlaveI2c.RegisterRxBuffer(chanId, 4, 8, 16); + gTest(r==KErrNotSupported); + + gTest.Printf(_L("\nStarting RegisterTxBuffer\n")); + r=gChanSlaveI2c.RegisterTxBuffer(chanId, 4, 12, 8); + gTest(r==KErrNotSupported); + // + // Now set the notification trigger + TInt triggerMask=ERxAllBytes; + + gTest.Printf(_L("Starting SetNotificationTrigger with ERxAllBytes\n")); + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status); + gTest(r==KErrNotSupported); + + r = gChanSlaveI2c.TestSpare1(busIdI2c); + gTest(r == KErrNotSupported); + r = gChanSlaveI2c.TestStaticExtension(busIdI2c); + gTest(r == KErrNotSupported); + delete i2cBuf; + + //Start to test MasterSlave channel operations + //Create a Master-Slave channel + RBusDevIicClient chanMasterSlaveI2c; + TBufC<18> proxyName; + proxyName = KIicProxyFileNameRootStubs; + r = chanMasterSlaveI2c.Open(proxyName); + gTest(r==KErrNone); + + SET_BUS_TYPE(busIdI2c,EI2c); + SET_CHAN_NUM(busIdI2c,12); // 12 is the MasterSlave channel number + r = chanMasterSlaveI2c.TestStaticExtension(busIdI2c); + gTest(r==KErrNotSupported); + chanMasterSlaveI2c.Close(); + + return KErrNone; + } + LOCAL_C TInt RunTests() // // Utility method to invoke the separate tests @@ -1619,6 +1803,63 @@ gTest.Next(_L("Free Simulated PSL SPI bus driver")); err = User::FreePhysicalDevice(KSpiFileNameCtrlLess); gTest(err==KErrNone); + + //For simplicity, the code coverage tests are executed in STANDALONE_CHANNEL mode + //All the changes are made in test code, and not affect PIL. + gTest.Next(_L("Start the code coverage tests")); + + gTest.Next(_L("Load Simulated PSL I2C bus driver")); + r = User::LoadPhysicalDevice(KI2cFileNameStubs); + gTest.Printf(_L("return value r=%d"),r); + gTest(r==KErrNone || r==KErrAlreadyExists); + + gTest.Next(_L("Load kernel-side proxy IIC client")); + r = User::LoadLogicalDevice(KIicProxyFileNameStubs); + gTest(r==KErrNone || r==KErrAlreadyExists); + + gTest.Next(_L("Load kernel-side proxy IIC slave client")); + r = User::LoadLogicalDevice(KIicProxySlaveFileNameStubs); + gTest(r==KErrNone || r==KErrAlreadyExists); + + __KHEAP_MARK; + TBufC<30> proxyNameStubs(KIicProxyFileNameRootStubs); + // Open a Master I2C channel to the kernel side proxy + r = gChanMasterI2c.Open(proxyNameStubs); + + gTest(r==KErrNone); + TBufC<35> proxySlaveNameStubs(KIicProxySlaveFileNameRootStubs); + + r = gChanSlaveI2c.Open(proxySlaveNameStubs); + gTest(r==KErrNone); + r = gChanSlaveI2c.InitSlaveClient(); + gTest(r==KErrNone); + + // Instigate tests + r = IicTestStubs(); + gTest(r==KErrNone); + + gTest.Printf(_L("Tests completed OK, about to close channel\n")); + gChanMasterI2c.Close(); + gChanSlaveI2c.Close(); + + UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0); + // Not safe to assume that heap clean-up has completed for the channels just closed, so insert a delay.(DEF145202) + User::After(20 * 1000); + __KHEAP_MARKEND; + + gTest.Next(_L("Free kernel-side proxy IIC client")); + + err = User::FreeLogicalDevice(KIicProxyFileNameRootStubs); + gTest(err==KErrNone || err==KErrAlreadyExists); + gTest.Next(_L("Free kernel-side proxy IIC slave client")); + err = User::FreeLogicalDevice(KIicProxySlaveFileNameRootStubs); + gTest(err==KErrNone || err==KErrAlreadyExists); + + gTest.Next(_L("Free Simulated PSL I2C bus driver")); + err = User::FreePhysicalDevice(KI2cFileNameStubs); + gTest(err==KErrNone); + + gTest.Next(_L("End the code coverage tests")); #else gTest.Printf(_L("Don't do the test if it is not IIC_SIMULATED_PSL")); #endif diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/iic/t_iic.h --- a/kerneltest/e32test/iic/t_iic.h Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/e32test/iic/t_iic.h Fri Jul 09 13:13:20 2010 +0100 @@ -301,7 +301,9 @@ EReleaseChan, /**< ReleaseChannel */ ERegisterRxBuffer, /**< Register a buffer for receiving data */ ERegisterTxBuffer, /**< Register a buffer for transmitting data */ - ESetNotifTrigger /**< Set the notification triggers */ + ESetNotifTrigger, /**< Set the notification triggers */ + ETestSpare1, + ETestStaticEx }; enum TStaticExt @@ -405,7 +407,9 @@ inline TInt SetNotifNoTrigger(TInt aChannelId, TInt aTrigger){return(DoControl(ECtrlIoNotifNoTrigger,(TAny*)aChannelId,(TAny*)aTrigger));}; inline void TestOverrunUnderrun(TInt aBusId, TInt aChannelId, TRequestStatus& aStatus) {DoRequest(ECtrlIoOvUndRunRxTx,aStatus,(TAny*)aBusId,(TAny*)aChannelId);} - + + inline TInt TestSpare1(TInt aBusId) {return (DoControl(ETestSpare1, (TAny*)aBusId));} + inline TInt TestStaticExtension(TInt aBusId) {return (DoControl(ETestStaticEx, (TAny*)aBusId));} #endif }; diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/multimedia/t_camera_api.cpp --- a/kerneltest/e32test/multimedia/t_camera_api.cpp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1487 +0,0 @@ -// Copyright (c) 2006-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: -// e32test\multimedia\t_camera_api.cpp -// -// - -#include -#include -#include -#include -#include "t_camera_display.h" -#include "t_camera_bitmap.h" -#include "d_mmcsc.h" - -_LIT(KTstLddFileName,"D_MMCSC.LDD"); -_LIT(KCamLddFileName,"ECAMERASC.LDD"); - -#ifdef __WINSCW__ -_LIT(KCamPddFileName,"_TEMPLATE_CAMERASC.PDD"); -#else -_LIT(KCamPddFileName,"CAMERASC.PDD"); -#endif - - -_LIT(KCamFreePddExtension,".*"); - -_LIT(KFrameSize, "%dx%d"); -_LIT(KSensor, "d:\\Sensor_"); -_LIT(KUnderscore, "_"); -_LIT(KBmp, ".bmp"); -_LIT(KJpeg, ".jpg"); -_LIT(KSpeedTaggedJpeg, ".stj"); - -LOCAL_D TCameraCapsV02* CameraCaps; -LOCAL_D TInt CapsSize; -LOCAL_D TAny* CapsBufPtr; -RTest Test(_L("T_CAMERA_API")); - -const TInt KNumVideoFramesToAllocate=6; -const TInt KNumVideoFramesToCapture=(KNumVideoFramesToAllocate-2); -const TInt KHeapSize=0x4000; -const TInt KUnit0=0; - -enum TSecThreadTestId - { - ESecThreadTestOpen, - ESecThreadTestDuplicateHandle, - ESecThreadReuseHandle - }; - -struct SSecondaryThreadInfo - { - TSecThreadTestId iTestId; - TInt iExpectedRetVal; - TThreadId iThreadId; - TInt iDrvHandle; - TInt iCameraModuleIndex; - }; - -LOCAL_C TInt secondaryThread(TAny* aTestInfo) - { - RTest stest(_L("Secondary test camera thread")); - stest.Title(); - - stest.Start(_L("Check which test to perform")); - SSecondaryThreadInfo sti =*((SSecondaryThreadInfo*)aTestInfo); - - TInt r; - switch(sti.iTestId) - { - case ESecThreadTestOpen: - { - stest.Next(_L("Open channel test")); - RDevCameraSc cam; - r=cam.Open(sti.iCameraModuleIndex); - stest(r==sti.iExpectedRetVal); - cam.Close(); - break; - } - case ESecThreadTestDuplicateHandle: - { - stest.Next(_L("Duplicate channel handle test")); - - // Get a reference to the main thread - which created the handle - RThread thread; - r=thread.Open(sti.iThreadId); - stest(r==KErrNone); - - // Duplicate the driver handle passed from the other thread - for this thread - RDevCameraSc cam; - cam.SetHandle(sti.iDrvHandle); - r=cam.Duplicate(thread); - stest(r==sti.iExpectedRetVal); - cam.Close(); - thread.Close(); - break; - } - case ESecThreadReuseHandle: - { - stest.Next(_L("Re-use channel test")); - RDevCameraSc* camPtr=(RDevCameraSc*)sti.iDrvHandle; - TCameraConfigV02Buf camConfBuf; - camPtr->GetCamConfig(ECamCaptureModeImage, camConfBuf); // This should cause a panic. - break; - } - default: - break; - } - - stest.End(); - return(KErrNone); - } - -/** Test for defect DEF135950. */ -LOCAL_C void DoCamDynamicSettingsTests(RDevCameraSc& aCam, RTest& aTest) - { - aTest.Next(_L("DYNAMIC SETTINGS TESTS")); - - aTest.Next(_L("Get the Caps size. Should be non-zero")); - TInt capsSize = aCam.CapsSize(); - aTest(capsSize>0); - - aTest.Next(_L("Get the Capabilities (driver owned copy).")); - TPtrC8 driverCopy = aCam.Caps(); - aTest(driverCopy.Ptr() != NULL); - aTest(driverCopy.Length()>0); - - aTest.Next(_L("Test failure (buffer too small).")); - TAny* capsBufPtr = User::Alloc(capsSize-1); - aTest(capsBufPtr != NULL); - TPtr8 smallBuf((TUint8*) capsBufPtr, capsSize-1, capsSize-1); - aTest(KErrArgument==aCam.Caps(smallBuf)); - User::Free(capsBufPtr); - - aTest.Next(_L("Get the Capabilities (client owned copy).")); - capsBufPtr = User::Alloc(capsSize); - aTest(capsBufPtr != NULL); - TPtr8 clientCopy((TUint8*) capsBufPtr, capsSize, capsSize); - aTest(KErrNone==aCam.Caps(clientCopy)); - aTest(clientCopy.Ptr() != NULL); - aTest(clientCopy.Length()>0); - - aTest.Next(_L("Obtain the range for Dynamic Settings from both copies (should be the same).")); - - TDynamicRange &driverRangeBrightness = ((TCameraCapsV02*)(driverCopy.Ptr()))->iDynamicRange[ECamAttributeBrightness]; - TDynamicRange &clientRangeBrightness = ((TCameraCapsV02*)(clientCopy.Ptr()))->iDynamicRange[ECamAttributeBrightness]; - - aTest(driverRangeBrightness.iMin == 0); - aTest(driverRangeBrightness.iMax == 6); - aTest(driverRangeBrightness.iMin == clientRangeBrightness.iMin); - aTest(driverRangeBrightness.iMax == clientRangeBrightness.iMax); - - TDynamicRange &driverRangeContrast = ((TCameraCapsV02*)(driverCopy.Ptr()))->iDynamicRange[ECamAttributeContrast]; - TDynamicRange &clientRangeContrast = ((TCameraCapsV02*)(clientCopy.Ptr()))->iDynamicRange[ECamAttributeContrast]; - - aTest(driverRangeContrast.iMin == 0); - aTest(driverRangeContrast.iMax == 6); - aTest(driverRangeContrast.iMin == clientRangeContrast.iMin); - aTest(driverRangeContrast.iMax == clientRangeContrast.iMax); - - TDynamicRange &driverRangeColorEffect = ((TCameraCapsV02*)(driverCopy.Ptr()))->iDynamicRange[ECamAttributeColorEffect]; - TDynamicRange &clientRangeColorEffect = ((TCameraCapsV02*)(clientCopy.Ptr()))->iDynamicRange[ECamAttributeColorEffect]; - - aTest(driverRangeColorEffect.iMin == 0); - aTest(driverRangeColorEffect.iMax == 7); // TBC::OV3640 set to 7, template driver set to 0x0040 (enum) - aTest(driverRangeColorEffect.iMin == clientRangeColorEffect.iMin); - aTest(driverRangeColorEffect.iMax == clientRangeColorEffect.iMax); - - aTest.Next(_L("Test for invalid Min range.")); - aTest(aCam.SetDynamicAttribute(ECamAttributeBrightness, driverRangeBrightness.iMin-1)==KErrArgument); - aTest(aCam.SetDynamicAttribute(ECamAttributeContrast, driverRangeContrast.iMin-1)==KErrArgument); - aTest(aCam.SetDynamicAttribute(ECamAttributeColorEffect, driverRangeColorEffect.iMin-1)==KErrArgument); - - aTest.Next(_L("Test for invalid Max range.")); - aTest(aCam.SetDynamicAttribute(ECamAttributeBrightness, driverRangeBrightness.iMax+1)==KErrArgument); - aTest(aCam.SetDynamicAttribute(ECamAttributeContrast, driverRangeContrast.iMax+1)==KErrArgument); - aTest(aCam.SetDynamicAttribute(ECamAttributeColorEffect, driverRangeColorEffect.iMax+1)==KErrArgument); - - aTest.Next(_L("Test all valid settings as reported by range - Brightness")); - for (TUint i=driverRangeBrightness.iMin; i <= driverRangeBrightness.iMax; ++i) - { - aTest(aCam.SetDynamicAttribute(ECamAttributeBrightness, i)==KErrNone); - } - - aTest.Next(_L("Test all valid settings as reported by range - Contrast")); - for (TUint j=driverRangeContrast.iMin; j <= driverRangeContrast.iMax; ++j) - { - aTest(aCam.SetDynamicAttribute(ECamAttributeContrast, j)==KErrNone); - } - - aTest.Next(_L("Test all valid settings as reported by range - ColorEffect")); - for (TUint k=driverRangeColorEffect.iMin; k <= driverRangeColorEffect.iMax; ++k) - { - aTest(aCam.SetDynamicAttribute(ECamAttributeColorEffect, k)==KErrNone); - } - - User::Free(capsBufPtr); - } - -/** Test for defect DEF135949. */ -LOCAL_C void DoCamBufferOffsetTests(RDevCameraSc& aCam, RTest& aTest, const SDevCamPixelFormat& aPixelFormat, const SDevCamFrameSize& aFrameSize, TUint aFrameRate) - { - TInt r; - - aTest.Next(_L("BUFFER ID OFFSET TESTS")); - aTest.Printf(_L("PixelFormat = %d, FrameSize = %d x %d\n"),aPixelFormat.iPixelFormat,aFrameSize.iWidth,aFrameSize.iHeight); - - // Configure Image Capture - aTest.Next(_L("Get the camera config of Image mode")); - TCameraConfigV02Buf camConfBuf; - aCam.GetCamConfig(ECamCaptureModeImage, camConfBuf); - TCameraConfigV02 &camConf=camConfBuf(); - - camConf.iFrameSize=aFrameSize; - camConf.iPixelFormat=aPixelFormat; - camConf.iFrameRate=aFrameRate; - - // Set the Image configuration. - aTest.Next(_L("Set the Get the camera config of Image mode")); - r=aCam.SetCamConfig(ECamCaptureModeImage,camConfBuf); - aTest(r==KErrNone); - aCam.GetCamConfig(ECamCaptureModeImage, camConfBuf); - PrintCamConf(camConf,aTest); - - // Create an Image chunk handle. - aTest.Next(_L("Create the Image chunk")); - RChunk imgChunkImage; - TInt numBuffers=KNumVideoFramesToAllocate; - r=aCam.SetBufConfigChunkCreate(ECamCaptureModeImage,numBuffers,imgChunkImage); - aTest(r==KErrNone); - - aTest.Next(_L("Read and display the Image buffer config")); - TMmSharedChunkBufConfig bufferConfig; - TPckg bufferConfigBuf(bufferConfig); - aCam.GetBufferConfig(ECamCaptureModeImage, bufferConfigBuf); - PrintBufferConf(bufferConfig,aTest); - - // Configure Video Capture - aTest.Next(_L("Get the camera config of Video mode")); - aCam.GetCamConfig(ECamCaptureModeVideo, camConfBuf); - camConf=camConfBuf(); - - camConf.iFrameSize=aFrameSize; - camConf.iPixelFormat=aPixelFormat; - camConf.iFrameRate=aFrameRate; - - // Set the video configuration. - aTest.Next(_L("Set the Get the camera config of Video mode")); - r=aCam.SetCamConfig(ECamCaptureModeVideo,camConfBuf); - aTest(r==KErrNone); - aCam.GetCamConfig(ECamCaptureModeVideo, camConfBuf); - PrintCamConf(camConf,aTest); - - // Create an Video chunk handle. - aTest.Next(_L("Create the Video chunk")); - RChunk chunkVideo; - numBuffers=KNumVideoFramesToAllocate; - r=aCam.SetBufConfigChunkCreate(ECamCaptureModeVideo,numBuffers,chunkVideo); - aTest(r==KErrNone); - - aTest.Next(_L("Read and display the Video buffer config")); - aCam.GetBufferConfig(ECamCaptureModeVideo, bufferConfigBuf); - PrintBufferConf(bufferConfig,aTest); - - // Test that stop still returns an error. - r=aCam.Stop(); - aTest(r==KErrGeneral); - - // Set the current capture mode to image - aTest.Next(_L("Set the camera in Image mode and capture a buffer, then requesting the buffer offset.")); - r=aCam.SetCaptureMode(ECamCaptureModeImage); - aTest(r==KErrNone); - - // Start the camera - r=aCam.Start(); - aTest(r==KErrNone); - - aTest.Next(_L("Issue a capture request")); - TRequestStatus rs1; - aCam.NotifyNewImage(rs1); - User::WaitForRequest(rs1); - TInt retId=rs1.Int(); - TInt retOffset=-1; - aTest(retId>=0); - aCam.BufferIdToOffset(ECamCaptureModeImage,retId,retOffset); - aTest.Printf(_L("Buffer offset: %d(%xH)\r\n"),retId,retOffset); - aTest(retOffset>=0); - - // Change capture mode - aTest.Next(_L("Set the capture mode to Video.")); - r=aCam.SetCaptureMode(ECamCaptureModeVideo); - aTest(r==KErrNone); - - aTest.Next(_L("Request again the offset for the buffer in Image mode.")); - aCam.BufferIdToOffset(ECamCaptureModeImage,retId,retOffset); - aTest.Printf(_L("Buffer offset: %d(%xH)\r\n"),retId,retOffset); - aTest(retOffset>=0); - - // Stop the camera. - r=aCam.Stop(); - aTest(r==KErrNone); - - aTest.Next(_L("Close the chunk")); - r=aCam.ChunkClose(ECamCaptureModeImage); - aTest(r==KErrNone); - r=aCam.ChunkClose(ECamCaptureModeVideo); - aTest(r==KErrNone); - } - - -LOCAL_C void DoCamOpenCapTests(RTest& aTest,TInt aCameraSensorIndex) - { - TInt r; - - // Open the camera driver to obtain the basic capabilities for use throughout the tests and - // then close it again so that it may be confirmed that opening multiple times is ok - aTest.Next(_L("CHANNEL OPEN AND CAPABILITIES TESTS")); - RDevCameraSc cam; - aTest.Next(_L("Open a channel on the camera driver")); - r=cam.Open(aCameraSensorIndex); - aTest(r==KErrNone); - - // Make sure that the driver can handle attempts to start it before it has been configured - aTest.Next(_L("Try to start/stop camera before its configured")); - r=cam.Start(); - aTest(r==KErrNotReady); - r=cam.Stop(); - aTest(r==KErrGeneral); - - aTest.Next(_L("Read the capabilities structure size of this device")); - CapsSize=cam.CapsSize(); - aTest.Next(_L("Read and display the capabilities of this device")); - CapsBufPtr = User::Alloc(CapsSize); - TPtr8 capsPtr( (TUint8*)CapsBufPtr, CapsSize, CapsSize ); - r=cam.Caps(capsPtr); - aTest(r==KErrNone); - CameraCaps = (TCameraCapsV02*) capsPtr.Ptr(); - PrintCamModes(CameraCaps,aTest); - - TAny* frameSizeCapsBuf; - SDevCamPixelFormat* pixelFormat; - TBuf<80> buf; - SDevCamFrameSize* frameSize; - TPtr8 frameSizeCapsPtr(0,0,0); - TUint fsCount, pfCount, theCount = 0; - - /* IMAGE */ - /* Use pixel formats from 0 to CapsBuf->iNumImagePixelFormats */ - buf.Zero(); - buf.Append(KCaptureModeImage); - buf.Append(_L("\r\n")); - aTest.Printf(buf); - pixelFormat = (SDevCamPixelFormat*) (CameraCaps + 1); - for (pfCount = theCount; pfCount < CameraCaps->iNumImagePixelFormats; pfCount++) - { - buf.Zero(); - AppendPixelFormat(buf, pixelFormat->iPixelFormat); - aTest.Printf(buf); - frameSizeCapsBuf = User::Alloc(pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize)); - new (&frameSizeCapsPtr) TPtr8((TUint8*)frameSizeCapsBuf, pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize), pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize)); - r=cam.FrameSizeCaps(ECamCaptureModeImage, pixelFormat->iPixelFormat, frameSizeCapsPtr); - aTest(r==KErrNone); - frameSize = (SDevCamFrameSize*) frameSizeCapsPtr.Ptr(); - for (fsCount = 0; fsCount < pixelFormat->iNumFrameSizes; fsCount++) - { - aTest.Printf(_L("%dx%d "),frameSize->iWidth,frameSize->iHeight); - frameSize++; - } - aTest.Printf(_L("\n")); - User::Free(frameSizeCapsBuf); - pixelFormat++; - } - - /* VIDEO */ - buf.Zero(); - buf.Append(KCaptureModeVideo); - buf.Append(_L("\r\n")); - aTest.Printf(buf); - pixelFormat = (SDevCamPixelFormat*) (CameraCaps + 1); - pixelFormat += CameraCaps->iNumImagePixelFormats; - theCount = CameraCaps->iNumImagePixelFormats + CameraCaps->iNumVideoPixelFormats; - for (pfCount = CameraCaps->iNumImagePixelFormats; pfCount < theCount; pfCount++) - { - buf.Zero(); - AppendPixelFormat(buf, pixelFormat->iPixelFormat); - aTest.Printf(buf); - frameSizeCapsBuf = User::Alloc(pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize)); - new (&frameSizeCapsPtr) TPtr8((TUint8*)frameSizeCapsBuf, pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize), pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize)); - r=cam.FrameSizeCaps(ECamCaptureModeVideo, pixelFormat->iPixelFormat, frameSizeCapsPtr); - aTest(r==KErrNone); - frameSize = (SDevCamFrameSize*) frameSizeCapsPtr.Ptr(); - for (fsCount = 0; fsCount < pixelFormat->iNumFrameSizes; fsCount++) - { - aTest.Printf(_L("%dx%d "),frameSize->iWidth,frameSize->iHeight); - frameSize++; - } - aTest.Printf(_L("\n")); - User::Free(frameSizeCapsBuf); - pixelFormat++; - } - - /* VIEW FINDER */ - buf.Zero(); - buf.Append(KCaptureModeViewFinder); - buf.Append(_L("\r\n")); - aTest.Printf(buf); - pixelFormat = (SDevCamPixelFormat*) (CameraCaps + 1); - pixelFormat += (CameraCaps->iNumImagePixelFormats + CameraCaps->iNumVideoPixelFormats); - theCount = CameraCaps->iNumImagePixelFormats + CameraCaps->iNumVideoPixelFormats + CameraCaps->iNumViewFinderPixelFormats; - for (pfCount = CameraCaps->iNumImagePixelFormats + CameraCaps->iNumVideoPixelFormats; pfCount < theCount; pfCount++) - { - buf.Zero(); - AppendPixelFormat(buf, pixelFormat->iPixelFormat); - aTest.Printf(buf); - frameSizeCapsBuf = User::Alloc(pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize)); - new (&frameSizeCapsPtr) TPtr8((TUint8*)frameSizeCapsBuf, pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize), pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize)); - r=cam.FrameSizeCaps(ECamCaptureModeViewFinder, pixelFormat->iPixelFormat, frameSizeCapsPtr); - aTest(r==KErrNone); - frameSize = (SDevCamFrameSize*) frameSizeCapsPtr.Ptr(); - for (fsCount = 0; fsCount < pixelFormat->iNumFrameSizes; fsCount++) - { - aTest.Printf(_L("%dx%d "),frameSize->iWidth,frameSize->iHeight); - frameSize++; - } - aTest.Printf(_L("\n")); - User::Free(frameSizeCapsBuf); - pixelFormat++; - } - - aTest.Next(_L("Try opening the same unit a second time.")); - RDevCameraSc cam2; - r=cam2.Open(aCameraSensorIndex); - aTest(r==KErrInUse); - - aTest.Next(_L("Open a channel from the 2nd thread without closing the 1st")); - RThread thread; - TRequestStatus stat; - SSecondaryThreadInfo sti; - - // Setup the 2nd thread to open a channel on the same unit - sti.iTestId=ESecThreadTestOpen; - sti.iExpectedRetVal=KErrInUse; - sti.iCameraModuleIndex=aCameraSensorIndex; - r=thread.Create(_L("Thread"),secondaryThread,KDefaultStackSize,KHeapSize,KHeapSize,&sti); - Test(r==KErrNone); - thread.Logon(stat); - thread.Resume(); - User::WaitForRequest(stat); - Test(stat.Int()==KErrNone); - Test(thread.ExitType()==EExitKill); - thread.Close(); - User::After(10000); // Wait 10ms - - aTest.Next(_L("Open a channel from the 2nd thread having closed the 1st")); - cam.Close(); // Close the 1st channel - sti.iTestId=ESecThreadTestOpen; - sti.iExpectedRetVal=KErrNone; - r=thread.Create(_L("Thread02"),secondaryThread,KDefaultStackSize,KHeapSize,KHeapSize,&sti); - Test(r==KErrNone); - thread.Logon(stat); - thread.Resume(); - User::WaitForRequest(stat); - Test(stat.Int()==KErrNone); - Test(thread.ExitType()==EExitKill); - thread.Close(); - User::After(10000); // Wait 10ms - - aTest.Next(_L("Re-open channel and duplicate it from 2nd thread")); - r=cam.Open(aCameraSensorIndex); // Re-open the channel - aTest(r==KErrNone); - sti.iTestId=ESecThreadTestDuplicateHandle; - sti.iExpectedRetVal=KErrAccessDenied; - sti.iThreadId=RThread().Id(); // Get the ID of this thread - sti.iDrvHandle=cam.Handle(); // Pass the channel handle - - r=thread.Create(_L("Thread03"),secondaryThread,KDefaultStackSize,KHeapSize,KHeapSize,&sti); // Create secondary thread - Test(r==KErrNone); - thread.Logon(stat); - thread.Resume(); - User::WaitForRequest(stat); - Test(stat.Int()==KErrNone); - Test(thread.ExitType()==EExitKill); - thread.Close(); - User::After(10000); // Wait 10ms - - aTest.Next(_L("Re-use the same channel from 2nd thread")); - sti.iTestId=ESecThreadReuseHandle; - sti.iDrvHandle=(TInt)&cam; // Pass a pointer to the channel - r=thread.Create(_L("Thread04"),secondaryThread,KDefaultStackSize,KHeapSize,KHeapSize,&sti); // Create secondary thread - Test(r==KErrNone); - thread.Logon(stat); - thread.Resume(); - User::WaitForRequest(stat); - TExitCategoryName exitCategoryName = thread.ExitCategory(); - Test.Printf(_L("Thread exit info: Cat:%S, Reason:%x, Type:%d\r\n"),&exitCategoryName,thread.ExitReason(),thread.ExitType()); - Test(thread.ExitType()==EExitPanic); // Secondary thread is expected to panic - Test(stat.Int()==KErrNone); - thread.Close(); - User::After(10000); // Wait 10ms - - cam.Close(); - } - -LOCAL_C void DoCamConfigTests(RDevCameraSc& aCam, RTest& aTest, TDevCamCaptureMode aCaptureMode, const SDevCamPixelFormat& aPixelFormat, const SDevCamFrameSize& aFrameSize) - { - TInt r; - - aTest.Next(_L("GETTING & SETTING CONFIG TESTS")); - aTest.Printf(_L("CaptureMode = %d, PixelFormat = %x, FrameSize = %d x %d\n"),aCaptureMode,aPixelFormat.iPixelFormat,aFrameSize.iWidth,aFrameSize.iHeight); - - aTest.Next(_L("Read and display the default camera config for requested capture mode")); - TCameraConfigV02Buf camConfBuf; - aCam.GetCamConfig(aCaptureMode, camConfBuf); - TCameraConfigV02 &camConf=camConfBuf(); - PrintCamConf(camConf,aTest); - - aTest.Next(_L("Read and display the default buffer config for requested capture mode")); - TMmSharedChunkBufConfig bufferConfig; - TPckg bufferConfigBuf(bufferConfig); - aCam.GetBufferConfig(aCaptureMode, bufferConfigBuf); - PrintBufferConf(bufferConfig,aTest); - - aTest.Next(_L("Setup the config - creating a chunk")); - camConf.iFrameSize=aFrameSize; - camConf.iPixelFormat=aPixelFormat; - camConf.iFrameRate=aFrameSize.iMaxFrameRate; - r=aCam.SetCamConfig(aCaptureMode, camConfBuf); - aTest(r==KErrNone); - RChunk chunk; - r=aCam.SetBufConfigChunkCreate(aCaptureMode, KNumVideoFramesToAllocate, chunk); - aTest(r==KErrNone); - aCam.GetCamConfig(aCaptureMode, camConfBuf); - PrintCamConf(camConf,aTest); - - aTest.Next(_L("Read and display the resulting buffer config")); - aCam.GetBufferConfig(aCaptureMode, bufferConfigBuf); - PrintBufferConf(bufferConfig,aTest); - - aTest.Next(_L("Close the chunk created")); - chunk.Close(); - - aTest.Next(_L("Open a channel on the test driver")); - RMmCreateSc tstDrv; - r=tstDrv.Open(); // Opening the channel results in the creation of a shared chunk. - aTest(r==KErrNone); - - aTest.Next(_L("Get a handle on its shared chunk")); - r=tstDrv.GetChunkHandle(chunk); // Get a handle on the shared chunk created by the test driver - aTest(r==KErrNone); - - aTest.Next(_L("Read and display the buffer config")); - TMmSharedChunkBufConfig bufferConfigTest; - TPckg bufferConfigBufTest(bufferConfigTest); - - // Get info on the buffers within the shared chunk - aTest.Next(_L("Get info. on the shared chunk")); - r=tstDrv.GetBufInfo(bufferConfigBufTest); - aTest(r==KErrNone); - - PrintBufferConf(bufferConfigTest,aTest); - aTest.Next(_L("Setup the config - supplying a chunk")); - r=aCam.SetBufConfigChunkOpen(aCaptureMode, bufferConfigBufTest, chunk); - aTest(r==KErrNone); - aCam.GetCamConfig(aCaptureMode, camConfBuf); - PrintCamConf(camConf,aTest); - aCam.GetBufferConfig(aCaptureMode, bufferConfigBufTest); - PrintBufferConf(bufferConfigTest,aTest); - - aTest.Next(_L("Close the chunk driver and the 2nd chunk")); - tstDrv.Close(); - chunk.Close(); - } - -LOCAL_C void DoCamVideoCaptureTests(RDevCameraSc& aCam, RTest& aTest, TDevCamCaptureMode aCaptureMode, const SDevCamPixelFormat& aPixelFormat, const SDevCamFrameSize& aFrameSize, TUint aFrameRate) - { - TInt r; - - aTest.Next(_L("VIDEO CAPTURE TESTS")); - aTest.Printf(_L("CaptureMode = %d, PixelFormat = %x, FrameSize = %d x %d\n"),aCaptureMode,aPixelFormat.iPixelFormat,aFrameSize.iWidth,aFrameSize.iHeight); - - // Configure Video or Viewfinder Capture - TCameraConfigV02Buf camConfBuf; - aCam.GetCamConfig(aCaptureMode, camConfBuf); - TCameraConfigV02 &camConf=camConfBuf(); - - camConf.iFrameSize=aFrameSize; - camConf.iPixelFormat=aPixelFormat; - camConf.iFrameRate=aFrameRate; - - // Set the camera configuration. - r=aCam.SetCamConfig(aCaptureMode,camConfBuf); - aTest(r==KErrNone); - aCam.GetCamConfig(aCaptureMode, camConfBuf); - PrintCamConf(camConf,aTest); - - // Create a chunk handle and trigger the buffer creation. - aTest.Next(_L("Setup the config - creating a chunk")); - RChunk chunkVideo; - TInt numBuffers=KNumVideoFramesToAllocate; - r=aCam.SetBufConfigChunkCreate(aCaptureMode,numBuffers,chunkVideo); - aTest(r==KErrNone); - - aTest.Next(_L("Read and display the resulting buffer config")); - TMmSharedChunkBufConfig bufferConfig; - TPckg bufferConfigBufVideo(bufferConfig); - aCam.GetBufferConfig(aCaptureMode, bufferConfigBufVideo); - PrintBufferConf(bufferConfig,aTest); - - // Request and print the camera and buffer configurations for all three capture modes - aTest.Next(_L("Read and display the camera configs")); - aCam.GetCamConfig(ECamCaptureModeVideo, camConfBuf); - PrintCamConf(camConf,aTest); - aCam.GetCamConfig(ECamCaptureModeImage, camConfBuf); - PrintCamConf(camConf,aTest); - aCam.GetCamConfig(ECamCaptureModeViewFinder, camConfBuf); - PrintCamConf(camConf,aTest); - - // Create and configure a display handler - TCamDisplayHandler dispHand; - r=dispHand.Init(); - aTest(r==KErrNone); - - if (aPixelFormat.iPixelFormat!=EUidPixelFormatJPEG && aPixelFormat.iPixelFormat!=EUidPixelFormatSpeedTaggedJPEG) - { - r=dispHand.SetConfig(aFrameSize,aPixelFormat); - aTest(r==KErrNone); - } - - // Test that stop still returns an error. - r=aCam.Stop(); - aTest(r==KErrGeneral); - - // Set the current capture mode - r=aCam.SetCaptureMode(aCaptureMode); - aTest(r==KErrNone); - - aTest.Next(_L("Start the camera in video mode")); - r=aCam.Start(); - aTest(r==KErrNone); - - aTest.Next(_L("Issue capture requests")); - aTest.Printf(_L("Request %d frames\r\n"),KNumVideoFramesToCapture); - // Issue new image requests immediately. We'll have to wait while the - // camera captures the images. - TRequestStatus rs[KNumVideoFramesToCapture]; - TInt i; - for (i=0 ; i=0); - aTest.Printf(_L("Getting buffer offset for... %d\n"), i); - aCam.BufferIdToOffset(aCaptureMode,retId,retOffset); - aTest.Printf(_L("Buffer%d(id:%d) offset: %d(%xH)\r\n"),i,retId,retOffset,retOffset); - aTest(retOffset>=0); - } - - TUint8* imgBase; - - // Display each image received for 333ms - for (i=0 ; i=0); - aCam.BufferIdToOffset(aCaptureMode,retId,retOffset); - aTest(retOffset>=0); - imgBase=chunkVideo.Base()+retOffset; - r=dispHand.Process(imgBase); - -#ifdef __WINSCW__ - aTest(r==KErrNotSupported); -#else - aTest(r==KErrNone); -#endif - - User::After(333000); // 0.33sec - } - } - - aTest.Next(_L("Free the buffers")); - for (i=0 ; i=0); - aCam.BufferIdToOffset(aCaptureMode,retId,retOffset); - aTest.Printf(_L("Buffer%d(id:%d) offset: %d(%xH)\r\n"),i,retId,retOffset,retOffset); - aTest(retOffset>=0); - } - - aTest.Next(_L("Stop the camera.")); - r=aCam.Stop(); - aTest(r==KErrNone); - - aTest.Next(_L("Start it again.")); - r=aCam.Start(); - aTest(r==KErrNone); - - aTest.Next(_L("Continuously display for 10 secs")); - RTimer tim; - tim.CreateLocal(); - TRequestStatus timStatus; - const TUint KTimeOut=10000000; // 10 seconds - tim.After(timStatus,KTimeOut); - aTest(timStatus==KRequestPending); - aCam.NotifyNewImage(rs[0]); - aCam.NotifyNewImage(rs[1]); - FOREVER - { - User::WaitForAnyRequest(); - if (timStatus!=KRequestPending) - { - aCam.NotifyNewImageCancel(); - User::WaitForRequest(rs[0]); - User::WaitForRequest(rs[1]); - break; - } - else if (rs[0]!=KRequestPending) - { - retId=rs[0].Int(); - aTest(retId>=0); - aCam.BufferIdToOffset(aCaptureMode,retId,retOffset); - aTest(retOffset>=0); - imgBase=chunkVideo.Base()+retOffset; - if (aPixelFormat.iPixelFormat!=EUidPixelFormatJPEG && aPixelFormat.iPixelFormat!=EUidPixelFormatSpeedTaggedJPEG) - { - r=dispHand.Process(imgBase); - -#ifdef __WINSCW__ - aTest(r==KErrNotSupported); -#else - aTest(r==KErrNone); -#endif - - } - r=aCam.ReleaseBuffer(retId); - aTest(r==KErrNone); - aCam.NotifyNewImage(rs[0]); - } - else if (rs[1]!=KRequestPending) - { - retId=rs[1].Int(); - aTest(retId>=0); - aCam.BufferIdToOffset(aCaptureMode,retId,retOffset); - aTest(retOffset>=0); - imgBase=chunkVideo.Base()+retOffset; - if (aPixelFormat.iPixelFormat!=EUidPixelFormatJPEG && aPixelFormat.iPixelFormat!=EUidPixelFormatSpeedTaggedJPEG) - { - r=dispHand.Process(imgBase); - -#ifdef __WINSCW__ - aTest(r==KErrNotSupported); -#else - aTest(r==KErrNone); -#endif - - } - r=aCam.ReleaseBuffer(retId); - aTest(r==KErrNone); - aCam.NotifyNewImage(rs[1]); - } - else - aTest(0); - } - - tim.Close(); - - aTest.Next(_L("Stop the camera.")); - r=aCam.Stop(); - aTest(r==KErrNone); - - aTest.Next(_L("Close the chunk")); - r=aCam.ChunkClose(aCaptureMode); - } - -LOCAL_C void DoCamImageCaptureTests(RDevCameraSc& aCam, RTest& aTest, TInt aCameraSensorIndex, const SDevCamPixelFormat& aPixelFormat, const SDevCamFrameSize& aFrameSize, TUint aFrameRate) - { - TInt r; - - aTest.Next(_L("IMAGE CAPTURE TESTS")); - aTest.Printf(_L("PixelFormat = %d, FrameSize = %d x %d\n"),aPixelFormat.iPixelFormat,aFrameSize.iWidth,aFrameSize.iHeight); - - // Configure Image Capture - TCameraConfigV02Buf camConfBuf; - aCam.GetCamConfig(ECamCaptureModeImage, camConfBuf); - TCameraConfigV02 &camConf=camConfBuf(); - - camConf.iFrameSize=aFrameSize; - camConf.iPixelFormat=aPixelFormat; - camConf.iFrameRate=aFrameRate; - - // Set the camera configuration. - r=aCam.SetCamConfig(ECamCaptureModeImage,camConfBuf); - aTest(r==KErrNone); - aCam.GetCamConfig(ECamCaptureModeImage, camConfBuf); - PrintCamConf(camConf,aTest); - - // Create a chunk handle and trigger the buffer creation. - aTest.Next(_L("Setup the config - creating a chunk")); - RChunk chunkImage; - TInt numBuffers=KNumVideoFramesToAllocate; - r=aCam.SetBufConfigChunkCreate(ECamCaptureModeImage,numBuffers,chunkImage); - aTest(r==KErrNone); - - aTest.Next(_L("Read and display the resulting buffer config")); - TMmSharedChunkBufConfig bufferConfig; - TPckg bufferConfigBufImage(bufferConfig); - aCam.GetBufferConfig(ECamCaptureModeImage, bufferConfigBufImage); - PrintBufferConf(bufferConfig,aTest); - - // Create and configure a display handler - TCamDisplayHandler dispHand; - r=dispHand.Init(); - aTest(r==KErrNone); - - if (aPixelFormat.iPixelFormat!=EUidPixelFormatJPEG && aPixelFormat.iPixelFormat!=EUidPixelFormatSpeedTaggedJPEG) - { - r=dispHand.SetConfig(aFrameSize,aPixelFormat); - aTest(r==KErrNone); - } - - // Test that stop still returns an error. - r=aCam.Stop(); - aTest(r==KErrGeneral); - - // Set the current capture mode - r=aCam.SetCaptureMode(ECamCaptureModeImage); - aTest(r==KErrNone); - - aTest.Next(_L("Start the camera in image capture mode")); - r=aCam.Start(); - aTest(r==KErrNone); - - aTest.Next(_L("Issue a capture request")); - TRequestStatus rs1; - aCam.NotifyNewImage(rs1); - User::WaitForRequest(rs1); - TInt retId=rs1.Int(); - TInt retOffset=-1; - aTest(retId>=0); - aCam.BufferIdToOffset(ECamCaptureModeImage,retId,retOffset); - aTest.Printf(_L("Buffer offset: %d(%xH)\r\n"),retId,retOffset); - aTest(retOffset>=0); - - TUint8* imgBase; - imgBase=chunkImage.Base()+retOffset; - - if (aPixelFormat.iPixelFormat!=EUidPixelFormatJPEG && aPixelFormat.iPixelFormat!=EUidPixelFormatSpeedTaggedJPEG) - { - // Display the image received for 1s - r=dispHand.Process(imgBase); - -#ifdef __WINSCW__ - aTest(r==KErrNotSupported); -#else - aTest(r==KErrNone); -#endif - - User::After(1000000); // 1 sec - } - - // Save the to do MMC card with a filename to indicate its size. If no MMC card is present - // then we will just display a warning rather than fail as this is an optional manual step - TBuf<100> fileName(KSensor); - fileName.AppendNum(aCameraSensorIndex); - fileName.Append(KUnderscore); - fileName.AppendFormat(KFrameSize, aFrameSize.iWidth, aFrameSize.iHeight); - fileName.Append(KUnderscore); - AppendPixelFormat(fileName, aPixelFormat.iPixelFormat); - - TBool wrote = ETrue; - RBitmap bitmap; - - if ((aPixelFormat.iPixelFormat == EUidPixelFormatJPEG) || (aPixelFormat.iPixelFormat == EUidPixelFormatSpeedTaggedJPEG)) - { - fileName.Append((aPixelFormat.iPixelFormat == EUidPixelFormatJPEG) ? KJpeg : KSpeedTaggedJpeg); - r=bitmap.WriteBuffer(fileName, imgBase, (aFrameSize.iWidth * aFrameSize.iHeight * aPixelFormat.iPixelWidthInBytes)); - } - else if ((aPixelFormat.iPixelFormat == EUidPixelFormatYUV_422Interleaved) || (aPixelFormat.iPixelFormat == EUidPixelFormatRGB_565)) - { - fileName.Append(KBmp); - r=bitmap.WriteBMP(fileName, imgBase, aPixelFormat, aFrameSize.iWidth, aFrameSize.iHeight); - } - else - { - wrote = EFalse; - } - - if (wrote) - { - if (r==KErrNone) - { - aTest.Printf(_L("Wrote image to %S\n"),&fileName); - } - else - { - aTest.Printf(_L("Warning: Unable to write %S (error = %d)\r\n"),&fileName,r); - } - } - - aTest.Next(_L("Free the buffer")); - r=aCam.ReleaseBuffer(retId); - aTest(r==KErrNone); - - aTest.Next(_L("Issue two consecutive capture requests")); - TRequestStatus rs2; - aCam.NotifyNewImage(rs1); - aCam.NotifyNewImage(rs2); - - User::WaitForRequest(rs1); - retId=rs1.Int(); - aTest(retId>=0); - aCam.BufferIdToOffset(ECamCaptureModeImage,retId,retOffset); - aTest.Printf(_L("Buffer0 offset: %d(%xH)\r\n"),retOffset,retOffset); - aTest(retOffset>=0); - - if (aPixelFormat.iPixelFormat!=EUidPixelFormatJPEG && aPixelFormat.iPixelFormat!=EUidPixelFormatSpeedTaggedJPEG) - { - // Display the image received for 1s - imgBase=chunkImage.Base()+retOffset; - r=dispHand.Process(imgBase); - -#ifdef __WINSCW__ - aTest(r==KErrNotSupported); -#else - aTest(r==KErrNone); -#endif - - User::After(1000000); // 1 sec - } - - r=aCam.ReleaseBuffer(retId); - aTest(r==KErrNone); - - User::WaitForRequest(rs2); - retId=rs2.Int(); - aTest(retId>=0); - aCam.BufferIdToOffset(ECamCaptureModeImage,retId,retOffset); - aTest.Printf(_L("Buffer1 offset: %d(%xH)\r\n"),retOffset,retOffset); - aTest(retOffset>=0); - - if (aPixelFormat.iPixelFormat!=EUidPixelFormatJPEG && aPixelFormat.iPixelFormat!=EUidPixelFormatSpeedTaggedJPEG) - { - // Display the image received for 1s - imgBase=chunkImage.Base()+retOffset; - r=dispHand.Process(imgBase); - -#ifdef __WINSCW__ - aTest(r==KErrNotSupported); -#else - aTest(r==KErrNone); -#endif - - User::After(1000000); // 1 sec - } - - r=aCam.ReleaseBuffer(retId); - aTest(r==KErrNone); - - aTest.Next(_L("Issue four more separate capture requests")); - for (TInt i=0 ; i<4 ; i++) - { - aCam.NotifyNewImage(rs1); - User::WaitForRequest(rs1); - retId=rs1.Int(); - aTest(retId>=0); - aCam.BufferIdToOffset(ECamCaptureModeImage,retId,retOffset); - aTest.Printf(_L("Buffer%d offset: %d(%xH)\r\n"),i,retOffset,retOffset); - aTest(retOffset>=0); - - if (aPixelFormat.iPixelFormat!=EUidPixelFormatJPEG && aPixelFormat.iPixelFormat!=EUidPixelFormatSpeedTaggedJPEG) - { - // Display the image received for 1s - imgBase=chunkImage.Base()+retOffset; - r=dispHand.Process(imgBase); - -#ifdef __WINSCW__ - aTest(r==KErrNotSupported); -#else - aTest(r==KErrNone); -#endif - - User::After(1000000); // 1 sec - } - } - - r=aCam.ReleaseBuffer(retId); - aTest(r==KErrNone); - - aTest.Next(_L("Stop the camera.")); - r=aCam.Stop(); - aTest(r==KErrNone); - - aTest.Next(_L("Close the chunk")); - r=aCam.ChunkClose(ECamCaptureModeImage); - aTest(r==KErrNone); - } - -LOCAL_C void DoCamCancelTests(RTest& aTest, TInt aCameraSensorIndex) - { - TInt bufferSize, r; - SDevCamFrameSize* frameSizes; - TCameraConfigV02Buf camConfBuf; - - aTest.Next(_L("CAPTURE CANCEL TESTS")); - - RDevCameraSc cam; - aTest.Next(_L("Open a channel on the camera driver")); - r=cam.Open(aCameraSensorIndex); - aTest(r==KErrNone); - - TInt numBuffers=KNumVideoFramesToAllocate; - SDevCamPixelFormat* pixelFormat = (SDevCamPixelFormat*) (CameraCaps + 1); - - // Test Image Capture, if supported - if (CameraCaps->iNumImagePixelFormats) - { - // If iNumImagePixelFormats is > 0 then the matching iNumFrameSizes should also be > 0 - Test(pixelFormat->iNumFrameSizes > 0); - frameSizes = new SDevCamFrameSize[pixelFormat->iNumFrameSizes]; - Test(frameSizes != NULL); - bufferSize = (sizeof(SDevCamFrameSize) * pixelFormat->iNumFrameSizes); - TPtr8 frameSizesBuf((TUint8*) frameSizes, bufferSize, bufferSize); - r = cam.FrameSizeCaps(ECamCaptureModeImage, pixelFormat->iPixelFormat, frameSizesBuf); - Test(r == KErrNone); - - cam.GetCamConfig(ECamCaptureModeImage, camConfBuf); - - camConfBuf().iFrameSize=frameSizes[0]; - camConfBuf().iPixelFormat=*pixelFormat; - camConfBuf().iFrameRate=frameSizes[0].iMaxFrameRate; - - // Set the camera configuration. - r=cam.SetCamConfig(ECamCaptureModeImage, camConfBuf); - aTest(r==KErrNone); - cam.GetCamConfig(ECamCaptureModeImage, camConfBuf); - PrintCamConf(camConfBuf(), aTest); - - // Create a chunk handle and trigger the buffer creation. - RChunk chunkImage; - aTest.Next(_L("Setup the config - creating a chunk for image capture")); - r=cam.SetBufConfigChunkCreate(ECamCaptureModeImage,numBuffers,chunkImage); - aTest(r==KErrNone); - - aTest.Next(_L("Read and display the resulting buffer config")); - TMmSharedChunkBufConfig bufferConfig; - TPckg bufferConfigBufImage(bufferConfig); - cam.GetBufferConfig(ECamCaptureModeImage, bufferConfigBufImage); - PrintBufferConf(bufferConfig,aTest); - - // Set the current capture mode - r=cam.SetCaptureMode(ECamCaptureModeImage); - aTest(r==KErrNone); - - aTest.Next(_L("Start the camera in image capture mode.")); - r=cam.Start(); - aTest(r==KErrNone); - - TRequestStatus rs[KNumVideoFramesToCapture]; - TInt retId, retOffset; - - aTest.Next(_L("Issue a request and then cancel it")); - cam.NotifyNewImage(rs[0]); - cam.NotifyNewImageCancel(); - User::WaitForRequest(rs[0]); - retId=rs[0].Int(); - aTest(retId==KErrCancel || retId>=0); - if (retId>=0) - { - cam.BufferIdToOffset(ECamCaptureModeImage,retId,retOffset); - aTest.Printf(_L("Buffer%d : %d\r\n"),retId,retOffset); - aTest(retOffset>=0); - cam.ReleaseBuffer(retId); - } - - aTest.Next(_L("Stop the camera.")); - r=cam.Stop(); - aTest(r==KErrNone); - - aTest.Next(_L("Close the Image chunk")); - chunkImage.Close(); - - delete [] frameSizes; - } - - // Skip past the image pixel formats - pixelFormat += CameraCaps->iNumImagePixelFormats; - - // Test Video Capture, if supported - if (CameraCaps->iNumVideoPixelFormats) - { - // If iNumVideoPixelFormats is > 0 then the matching iNumFrameSizes should also be > 0 - Test(pixelFormat->iNumFrameSizes > 0); - frameSizes = new SDevCamFrameSize[pixelFormat->iNumFrameSizes]; - Test(frameSizes != NULL); - bufferSize = (sizeof(SDevCamFrameSize) * pixelFormat->iNumFrameSizes); - TPtr8 frameSizesBuf((TUint8*) frameSizes, bufferSize, bufferSize); - r = cam.FrameSizeCaps(ECamCaptureModeImage, pixelFormat->iPixelFormat, frameSizesBuf); - Test(r == KErrNone); - - cam.GetCamConfig(ECamCaptureModeVideo, camConfBuf); - - camConfBuf().iFrameSize=frameSizes[0]; - camConfBuf().iPixelFormat=*pixelFormat; - camConfBuf().iFrameRate=frameSizes[0].iMaxFrameRate; - - // Set the camera configuration. - r=cam.SetCamConfig(ECamCaptureModeVideo, camConfBuf); - aTest(r==KErrNone); - cam.GetCamConfig(ECamCaptureModeVideo, camConfBuf); - PrintCamConf(camConfBuf(), aTest); - - // Create a chunk handle and trigger the buffer creation. - RChunk chunkVideo; - aTest.Next(_L("Setup the config - creating a chunk for video capture")); - r=cam.SetBufConfigChunkCreate(ECamCaptureModeVideo,numBuffers,chunkVideo); - aTest(r==KErrNone); - - aTest.Next(_L("Read and display the resulting buffer config")); - TMmSharedChunkBufConfig bufferConfig; - TPckg bufferConfigBufVideo(bufferConfig); - cam.GetBufferConfig(ECamCaptureModeVideo, bufferConfigBufVideo); - PrintBufferConf(bufferConfig,aTest); - - // Set the current capture mode - r=cam.SetCaptureMode(ECamCaptureModeVideo); - aTest(r==KErrNone); - - aTest.Next(_L("Start the camera in video mode")); - r=cam.Start(); - aTest(r==KErrNone); - - aTest.Next(_L("Issue capture requests and globally cancel them all")); - aTest.Printf(_L("Request %d frames\r\n"),KNumVideoFramesToCapture); - TRequestStatus rs[KNumVideoFramesToCapture]; - TInt i; - for (i=0 ; i=0); - if (retId>=0) - { - cam.BufferIdToOffset(ECamCaptureModeVideo,retId,retOffset); - aTest.Printf(_L("Buffer%d : %d\r\n"),retId,retOffset); - aTest(retOffset>=0); - cam.ReleaseBuffer(retId); - } - } - - aTest.Next(_L("Issue capture requests and individually cancel them all")); - aTest.Printf(_L("Request %d frames\r\n"),KNumVideoFramesToCapture); - - for (i=0 ; i=0); - if (retId>=0) - { - cam.BufferIdToOffset(ECamCaptureModeVideo,retId,retOffset); - aTest.Printf(_L("Buffer%d : %d\r\n"),retId,retOffset); - aTest(retOffset>=0); - cam.ReleaseBuffer(retId); - } - } - - aTest.Next(_L("Stop the camera.")); - r=cam.Stop(); - aTest(r==KErrNone); - - aTest.Next(_L("Close the Video chunk")); - chunkVideo.Close(); - - delete [] frameSizes; - } - - // Skip past the video pixel formats - pixelFormat += CameraCaps->iNumVideoPixelFormats; - - // Test Viewfinder Capture, if supported - if (CameraCaps->iNumViewFinderPixelFormats) - { - // If iNumViewFinderPixelFormats is > 0 then the matching iNumFrameSizes should also be > 0 - Test(pixelFormat->iNumFrameSizes > 0); - frameSizes = new SDevCamFrameSize[pixelFormat->iNumFrameSizes]; - Test(frameSizes != NULL); - bufferSize = (sizeof(SDevCamFrameSize) * pixelFormat->iNumFrameSizes); - TPtr8 frameSizesBuf((TUint8*) frameSizes, bufferSize, bufferSize); - r = cam.FrameSizeCaps(ECamCaptureModeViewFinder, pixelFormat->iPixelFormat, frameSizesBuf); - Test(r == KErrNone); - - cam.GetCamConfig(ECamCaptureModeViewFinder, camConfBuf); - - camConfBuf().iFrameSize=frameSizes[0]; - camConfBuf().iPixelFormat=*pixelFormat; - camConfBuf().iFrameRate=frameSizes[0].iMaxFrameRate; - - // Set the camera configuration. - r=cam.SetCamConfig(ECamCaptureModeViewFinder, camConfBuf); - aTest(r==KErrNone); - cam.GetCamConfig(ECamCaptureModeViewFinder, camConfBuf); - PrintCamConf(camConfBuf(), aTest); - - // Create a chunk handle and trigger the buffer creation. - RChunk chunkViewFinder; - aTest.Next(_L("Setup the config - creating a chunk for viewfinder capture")); - r=cam.SetBufConfigChunkCreate(ECamCaptureModeViewFinder,numBuffers,chunkViewFinder); - aTest(r==KErrNone); - - aTest.Next(_L("Read and display the resulting buffer config")); - TMmSharedChunkBufConfig bufferConfig; - TPckg bufferConfigBufViewFinder(bufferConfig); - cam.GetBufferConfig(ECamCaptureModeViewFinder, bufferConfigBufViewFinder); - PrintBufferConf(bufferConfig,aTest); - - aTest.Next(_L("Close the Viewfinder chunk")); - chunkViewFinder.Close(); - - delete [] frameSizes; - } - - aTest.Next(_L("Close the drivers")); - cam.Close(); - } - -void CameraTests(TInt aCameraSensorIndex) - { - TUint index, size; - Test.Printf(_L("Testing unit number: %d\r\n"),aCameraSensorIndex); - - // Perform some basic opening and multithreaded tests. We don't want just in time debugging during - // these tests - TBool justInTime=User::JustInTime(); - User::SetJustInTime(EFalse); - DoCamOpenCapTests(Test,aCameraSensorIndex); - User::SetJustInTime(justInTime); - - // Test request handling - DoCamCancelTests(Test, aCameraSensorIndex); - - // Re-open the camera driver for use below and to ensure that it can deal with being re-opened (it - // has already been opened and closed by DoCamOpenCapTests()) - RDevCameraSc cam; - Test.Next(_L("Open a channel on the camera driver")); - TInt r=cam.Open(aCameraSensorIndex); - Test(r==KErrNone); - - // Test Dynamic Settings, e.g. Brightness, Contrast, etc. - DoCamDynamicSettingsTests(cam, Test); - - // Go through all supported image, video and viewfinder pixel formats and perform configuration - // and capture tests on them all, for all supported frame sizes and frame rates - TInt bufferSize; - SDevCamFrameSize* frameSizes; - TBool imageConfigTestsDone=EFalse, videoConfigTestsDone=EFalse, viewFinderConfigTestsDone=EFalse; - SDevCamPixelFormat* pixelFormat = (SDevCamPixelFormat*) (CameraCaps + 1); - - for (index = 0; index < CameraCaps->iNumImagePixelFormats; ++index) - { - // If iNumImagePixelFormats is > 0 then the matching iNumFrameSizes should also be > 0 - Test(pixelFormat->iNumFrameSizes > 0); - Test.Printf(_L("Image pixel format %x, number of frame sizes = %d\n"), pixelFormat->iPixelFormat, pixelFormat->iNumFrameSizes); - frameSizes=new SDevCamFrameSize[pixelFormat->iNumFrameSizes]; - Test(frameSizes!=NULL); - bufferSize=(sizeof(SDevCamFrameSize) * pixelFormat->iNumFrameSizes); - TPtr8 frameSizesBuf((TUint8*) frameSizes, bufferSize, bufferSize); - r = cam.FrameSizeCaps(ECamCaptureModeImage, pixelFormat->iPixelFormat, frameSizesBuf); - Test(r == KErrNone); - - // Test camera configuration for image capture. This is only done once for the sake of - // test expediency - if (!imageConfigTestsDone) - { - imageConfigTestsDone = ETrue; - DoCamConfigTests(cam, Test, ECamCaptureModeImage, *pixelFormat, frameSizes[0]); - } - - // Test image capture mode - for (size = 0; size < pixelFormat->iNumFrameSizes; ++size) - { - DoCamImageCaptureTests(cam, Test, aCameraSensorIndex, *pixelFormat, frameSizes[size], frameSizes[size].iMaxFrameRate); - } - - // Test buffer offset - for (size = 0; size < pixelFormat->iNumFrameSizes; ++size) - { - DoCamBufferOffsetTests(cam, Test, *pixelFormat, frameSizes[size], frameSizes[size].iMaxFrameRate); - } - - delete [] frameSizes; - ++pixelFormat; - } - - for (index = 0; index < CameraCaps->iNumVideoPixelFormats; ++index) - { - // If iNumVideoPixelFormats is > 0 then the matching iNumFrameSizes should also be > 0 - Test(pixelFormat->iNumFrameSizes > 0); - Test.Printf(_L("Video pixel format %x, number of frame sizes = %d\n"), pixelFormat->iPixelFormat, pixelFormat->iNumFrameSizes); - frameSizes=new SDevCamFrameSize[pixelFormat->iNumFrameSizes]; - Test(frameSizes!=NULL); - bufferSize=(sizeof(SDevCamFrameSize) * pixelFormat->iNumFrameSizes); - TPtr8 frameSizesBuf((TUint8*) frameSizes, bufferSize, bufferSize); - r = cam.FrameSizeCaps(ECamCaptureModeVideo, pixelFormat->iPixelFormat, frameSizesBuf); - Test(r == KErrNone); - - // Test camera configuration for video capture. This is only done once for the sake of - // test expediency - if (!videoConfigTestsDone) - { - videoConfigTestsDone=ETrue; - DoCamConfigTests(cam, Test, ECamCaptureModeVideo, *pixelFormat, frameSizes[0]); - } - - // Test video capture mode - for (size = 0; size < pixelFormat->iNumFrameSizes; ++size) - { - DoCamVideoCaptureTests(cam, Test, ECamCaptureModeVideo, *pixelFormat,frameSizes[size], frameSizes[size].iMaxFrameRate); - } - delete [] frameSizes; - ++pixelFormat; - } - - for (index = 0; index < CameraCaps->iNumViewFinderPixelFormats; ++index) - { - // If iNumViewFinderPixelFormats is > 0 then the matching iNumFrameSizes should also be > 0 - Test(pixelFormat->iNumFrameSizes > 0); - Test.Printf(_L("Viewfinder pixel format %x, number of frame sizes = %d\n"), pixelFormat->iPixelFormat, pixelFormat->iNumFrameSizes); - frameSizes=new SDevCamFrameSize[pixelFormat->iNumFrameSizes]; - Test(frameSizes!=NULL); - bufferSize=(sizeof(SDevCamFrameSize) * pixelFormat->iNumFrameSizes); - TPtr8 frameSizesBuf((TUint8*) frameSizes, bufferSize, bufferSize); - r = cam.FrameSizeCaps(ECamCaptureModeViewFinder, pixelFormat->iPixelFormat, frameSizesBuf); - Test(r == KErrNone); - - // Test camera configuration for view finder capture. This is only done once for the sake of - // test expediency - if (!viewFinderConfigTestsDone) - { - viewFinderConfigTestsDone=ETrue; - DoCamConfigTests(cam, Test, ECamCaptureModeViewFinder, *pixelFormat, frameSizes[0]); - } - - // Test view finder capture mode - for (size = 0; size < pixelFormat->iNumFrameSizes; ++size) - { - DoCamVideoCaptureTests(cam, Test, ECamCaptureModeViewFinder, *pixelFormat, frameSizes[size], frameSizes[size].iMaxFrameRate); - } - delete [] frameSizes; - ++pixelFormat; - } - cam.Close(); - - // And free the global capabilities buffer that was allocated in DoCamOpenCapTests() - User::Free(CapsBufPtr); - } - -GLDEF_C TInt E32Main() - { - __UHEAP_MARK; - - Test.Title(); - Test.Start(_L("Camera module API test")); - - Test.Next(_L("Loading CAMERA PDD")); - TInt r=User::LoadPhysicalDevice(KCamPddFileName); - Test.Printf(_L("Returned %d\r\n"),r); - - if (r==KErrNotFound) - { - Test.Printf(_L("Shared chunk camera driver not supported - test skipped\r\n")); - Test.End(); - Test.Close(); - __UHEAP_MARKEND; - return(KErrNone); - } - - Test(r==KErrNone || r==KErrAlreadyExists); - - Test.Next(_L("Loading CAMERA LDD")); - r=User::LoadLogicalDevice(KCamLddFileName); - Test.Printf(_L("Returned %d\r\n"),r); - Test(r==KErrNone || r==KErrAlreadyExists); - - Test.Next(_L("Loading D_MMCSC LDD")); - r=User::LoadLogicalDevice(KTstLddFileName); - Test.Printf(_L("Returned %d\r\n"),r); - Test(r==KErrNone||r==KErrAlreadyExists); - - __KHEAP_MARK; - - if (User::CommandLineLength()>0) - { - TBuf<0x100> cmd; - TInt moduleIndex = KUnit0; - User::CommandLine(cmd); - Test(cmd.Length()>0); - if (cmd[0]>='0' && cmd[0]<='9') - moduleIndex=(TInt)(cmd[0]-'0'); - CameraTests(moduleIndex); - } - else // If no command line arguments are passed we perform tests on the module 0 and 1 - { - CameraTests(0); - } - - __KHEAP_MARKEND; - - // Free the PDDs and LDDs - Test.Next(_L("Freeing ECAMERASC LDD")); - r=User::FreeLogicalDevice(KDevCameraScName); - Test(r==KErrNone); - - Test.Next(_L("Freeing CAMERASC PDD")); - TFindPhysicalDevice fDr; - TFullName drivName; - TName searchName; - searchName.Append(KDevCameraScName); - searchName.Append(KCamFreePddExtension); - fDr.Find(searchName); - r=fDr.Next(drivName); - Test(r==KErrNone); - r=User::FreePhysicalDevice(drivName); - Test(r==KErrNone); - - Test.Next(_L("Freeing D_MMCSC LDD")); - r=User::FreeLogicalDevice(KDevMmCScName); - Test(r==KErrNone); - - Test.End(); - Test.Close(); - - __UHEAP_MARKEND; - return(KErrNone); - } diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/multimedia/t_camera_bitmap.cpp --- a/kerneltest/e32test/multimedia/t_camera_bitmap.cpp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,291 +0,0 @@ -// Copyright (c) 2008-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: -// e32test/multimedia/t_camera_bitmap.cpp -// This is a basic Windows bitmap file writer, that can be used for converting YUV422 data into -// RGB format and dumping it to a Windows .bmp file, for manual examination. -// -// - -#include -#include -#include "t_camera_bitmap.h" - -#define CLIP(a) if (a < 0) a = 0; else if (a > 255) a = 255; - -/** -Converts a RGB565 buffer into 24 bit RGB format in a second buffer. -@param aDest Pointer to the buffer into which to place the 24 bit RGB data -@param aSource Pointer to the buffer containing the RGB565 data to be converted -@param aWidth The width of the data in the buffer in pixels -@param aHeight The height of the data in the buffer in pixels -*/ -void RBitmap::RGBToRGB(TUint8* aDest, TUint8* aSource, TInt aWidth, TInt aHeight) - { - TUint16* source = (TUint16*) aSource; - TUint16 pixel; - - for (TInt y = 0; y < aHeight; ++y) - { - for (TInt x = 0; x < aWidth; ++x) - { - pixel = *source++; - *aDest++ = (TUint8) ((pixel & 0xf800) >> 8); - *aDest++ = (TUint8) ((pixel & 0x07e0) >> 3); - *aDest++ = (TUint8) ((pixel & 0x001f) << 3); - } - } - } - -/** -Converts a YUV422 buffer into 24 bit RGB format in a second buffer. -@param aDest Pointer to the buffer into which to place the 24 bit RGB data -@param aSource Pointer to the buffer containing the YUV422 data to be converted -@param aWidth The width of the data in the buffer in pixels -@param aHeight The height of the data in the buffer in pixels -*/ -void RBitmap::YUVToRGB(TUint8* aDest, TUint8* aSource, TInt aWidth, TInt aHeight) - { - TInt y, u, v, r, g, b; - - aDest += ((aWidth * 3) * (aHeight - 1)); - - for (TInt l = 0; l < aHeight; ++l) - { - for (TInt x = 0; x < (aWidth / 2); ++x) - { - u = (aSource[0] - 128); - v = (aSource[2] - 128); - y = (aSource[3] - 16); - - r = ((298 * y + 409 * u) / 256); - g = ((298 * y - 100 * v - 208 * u) / 256); - b = ((298 * y + 516 * v) / 256); - - CLIP(r); - CLIP(g); - CLIP(b); - - *aDest++ = (TUint8) r; - *aDest++ = (TUint8) g; - *aDest++ = (TUint8) b; - - y = (aSource[1] - 16); - - r = ((298 * y + 409 * u) / 256); - g = ((298 * y - 100 * v - 208 * u) / 256); - b = ((298 * y + 516 * v) / 256); - - CLIP(r); - CLIP(g); - CLIP(b); - - *aDest++ = (TUint8) r; - *aDest++ = (TUint8) g; - *aDest++ = (TUint8) b; - aSource += 4; - } - - aDest -= (aWidth * 3 * 2); - } - } - -/** -Converts a 32 bit long from whatever the host format is into little endian format in a user supplied buffer. -@param aBuffer Pointer to the buffer into which to write the value -@param aLong The value to be written -*/ -void RBitmap::PutLong(TUint8* aBuffer, TInt aLong) - { - *aBuffer++ = (TUint8) (aLong & 0xff); - *aBuffer++ = (TUint8) ((aLong >> 8) & 0xff); - *aBuffer++ = (TUint8) ((aLong >> 16) & 0xff); - *aBuffer++ = (TUint8) ((aLong >> 24) & 0xff); - } - -/** -Converts a 16 bit short from whatever the host format is into little endian format in a user supplied buffer. -@param aBuffer Pointer to the buffer into which to write the value -@param aShort The value to be written -*/ -void RBitmap::PutShort(TUint8* aBuffer, TInt16 aShort) - { - *aBuffer++ = (TUint8) (aShort & 0xff); - *aBuffer++ = (TUint8) ((aShort >> 8) & 0xff); - } - -/** -Writes a standard Windows .bmp header to a file, including the standard .bmp file header, followed -by a V3 DIB header. -@param aFile A reference to the file to which to write the header -@param aWidth The width of the bitmap in pixels -@param aHeight The height of the bitmap in pixels -@return KErrNone if write was successful, otherwise one of the other system wide error codes -*/ -TInt RBitmap::WriteHeader(RFile& aFile, TInt aWidth, TInt aHeight) - { - TBuf8<14> header(14); - TUint8* buffer = (TUint8*) header.Ptr(); - - header.Fill(0); - - header[0] = 'B'; - header[1] = 'M'; - PutLong((buffer + 2), (14 + 40 + (aWidth * aHeight * 3))); - PutLong((buffer + 10), (14 + 40)); - - TInt r = aFile.Write(header); - - if (r == KErrNone) - { - TBuf8<40> bitmapInfoHeader(40); - TUint8* buffer = (TUint8*) bitmapInfoHeader.Ptr(); - - bitmapInfoHeader.Fill(0); - - PutLong(buffer, 40); - PutLong((buffer + 4), aWidth); - PutLong((buffer + 8), aHeight); - PutShort((buffer + 12), 1); - PutShort((buffer + 14), 24); - PutLong((buffer + 20), (aWidth * aHeight * 3)); - - r = aFile.Write(bitmapInfoHeader); - } - - return r; - } - -/** -Converts a YUV422 or RGB565 buffer into 24 bit RGB format and writes it to a file. -@param aFile A reference to the file to which to write the data -@param aBuffer A pointer to the buffer containing the data to be converted and written -@param aPixelFormat UID specifying the format of the source data -@param aWidth The width of the data in the buffer in pixels -@param aHeight The height of the data in the buffer in pixels -@return KErrNone if write was successful, otherwise one of the other system wide error codes -*/ -TInt RBitmap::WriteBitmapData(RFile& aFile, TUint8* aBuffer, SDevCamPixelFormat aPixelFormat, TInt aWidth, TInt aHeight) - { - TInt length = (aWidth * aHeight * 3); - TUint8* rgbBuffer = new TUint8[length]; - - TInt r = KErrNone; - - if (rgbBuffer) - { - if (aPixelFormat.iPixelFormat == EUidPixelFormatYUV_422Interleaved) - { - YUVToRGB(rgbBuffer, aBuffer, aWidth, aHeight); - } - else if (aPixelFormat.iPixelFormat == EUidPixelFormatRGB_565) - { - RGBToRGB(rgbBuffer, aBuffer, aWidth, aHeight); - } - else - { - r = KErrNotSupported; - } - - if (r == KErrNone) - { - TPtr8 buffer(rgbBuffer, length, length); - r = aFile.Write(buffer); - } - - delete [] rgbBuffer; - } - else - { - r = KErrNoMemory; - } - - return r; - } - -/** -Converts a YUV422 or RGB565 buffer into 24 bit RGB format and writes it to a Windows .bmp file. -@param aFileName A reference to the fully qualified name of the file to write the .bmp file to -@param aBuffer A pointer to the buffer containing the data to be converted and written -@param aPixelFormat UID specifying the format of the source data -@param aWidth The width of the data in the buffer in pixels -@param aHeight The height of the data in the buffer in pixels -@return KErrNone if write was successful, otherwise one of the other system wide error codes -*/ -TInt RBitmap::WriteBMP(const TDesC& aFileName, TUint8* aBuffer, SDevCamPixelFormat aPixelFormat, TInt aWidth, TInt aHeight) - { - TInt r; - RFile file; - RFs fs; - - if ((r = fs.Connect()) == KErrNone) - { - if ((r = file.Replace(fs, aFileName, EFileWrite)) == KErrNone) - { - if ((r = WriteHeader(file, aWidth, aHeight)) == KErrNone) - { - r = WriteBitmapData(file, aBuffer, aPixelFormat, aWidth, aHeight); - } - - file.Close(); - - // If anything went wrong, delete the file so that we do not leave partial files that - // might cause confusion - if (r != KErrNone) - { - fs.Delete(aFileName); - } - } - - fs.Close(); - } - - return r; - } - -/** -Dumps a buffer straight to disk, without any kind of processing. -@param aFileName A reference to the fully qualified name of the file to write the file to -@param aBuffer A pointer to the buffer containing the data to be converted written -@param aSize The size of the buffer to be written, in bytes -@return KErrNone if write was successful, otherwise one of the other system wide error codes -*/ -TInt RBitmap::WriteBuffer(const TDesC& aFileName, TUint8* aBuffer, TInt aSize) - { - TInt r; - RFile file; - RFs fs; - - if ((r = fs.Connect()) == KErrNone) - { - if ((r = file.Replace(fs, aFileName, EFileWrite)) == KErrNone) - { - TPtrC8 buffer(aBuffer, aSize); - - r = file.Write(buffer); - - file.Close(); - - // If anything went wrong, delete the file so that we do not leave partial files that - // might cause confusion - if (r != KErrNone) - { - fs.Delete(aFileName); - } - } - - fs.Close(); - } - - return r; - } diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/multimedia/t_camera_bitmap.h --- a/kerneltest/e32test/multimedia/t_camera_bitmap.h Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -// Copyright (c) 2008-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: -// e32test/multimedia/t_camera_bitmap.h -// This is a basic Windows bitmap file writer, that can be used for converting YUV422 data into -// RGB format and dumping it to a Windows .bmp file, for manual examination. -// -// - -#if !defined(__T_CAMERA_BITMAP_H__) -#define __T_CAMERA_BITMAP_H__ - -#include -#include - -class RBitmap - { -public: - - TInt WriteBMP(const TDesC& aFileName, TUint8* aBuffer, SDevCamPixelFormat aPixelFormat, TInt aWidth, TInt aHeight); - TInt WriteBuffer(const TDesC& aFileName, TUint8* aBuffer, TInt aSize); - -private: - - void RGBToRGB(TUint8* aDest, TUint8* aSource, TInt aWidth, TInt aHeight); - void YUVToRGB(TUint8* aDest, TUint8* aSource, TInt aWidth, TInt aHeight); - void PutLong(TUint8* aBuffer, TInt aLong); - void PutShort(TUint8* aBuffer, TInt16 aShort); - TInt WriteHeader(RFile& aFile, TInt aWidth, TInt aHeight); - TInt WriteBitmapData(RFile& aFile, TUint8* aBuffer, SDevCamPixelFormat aPixelFormat, TInt aWidth, TInt aHeight); - }; - -#endif // ! __T_CAMERA_BITMAP_H__ diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/multimedia/t_camera_display.cpp --- a/kerneltest/e32test/multimedia/t_camera_display.cpp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,388 +0,0 @@ -// Copyright (c) 2006-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: -// e32test\multimedia\t_camera_display.cpp -// -// - -#include -#include -#include -#include -#include "t_camera_display.h" - -_LIT(KFrameSizeConfTitle,"Current frame size :"); -_LIT(KFrameSize, " %d x %d"); - -#define CLIP(a) if (a < 0) a = 0; else if (a > 255) a = 255; - -/** -Constructor -*/ -TCamDisplayHandler::TCamDisplayHandler() - {} - -/** -Initialise the display handler. -@return KErrNone if write was successful, otherwise one of the other system wide error codes. -*/ -TInt TCamDisplayHandler::Init() - { - TScreenInfoV01 screenInfo; - TPckg screenInfoBuf(screenInfo); - UserSvr::ScreenInfo(screenInfoBuf); - iVideoAddress = (TUint8*) screenInfo.iScreenAddress; - iScreenWidth = screenInfo.iScreenSize.iWidth; - iScreenHeight = screenInfo.iScreenSize.iHeight; - - TPckgBuf videoInfoBuf; - UserSvr::HalFunction(EHalGroupDisplay, EDisplayHalCurrentModeInfo, &videoInfoBuf, NULL); - iBitsPerPixel = videoInfoBuf().iBitsPerPixel; - - return(KErrNone); - } - -TInt TCamDisplayHandler::Min(TInt aA, TInt aB) - { - return (aA < aB) ? aA : aB; - } - -TInt TCamDisplayHandler::SetConfig(const SDevCamFrameSize& aSize,const SDevCamPixelFormat& aPixelFormat) - { - if (aPixelFormat.iPixelFormat==EUidPixelFormatYUV_422Interleaved || aPixelFormat.iPixelFormat==EUidPixelFormatRGB_565) - iPixelFormat=aPixelFormat; - else - return(KErrArgument); - - iWidth = aSize.iWidth; - iHeight = aSize.iHeight; - - return(KErrNone); - } - -/** -Post process a received image. -@return KErrNone if write was successful, otherwise one of the other system wide error codes. -*/ -TInt TCamDisplayHandler::Process(TUint8* aImageBaseAddress) - { - switch (iPixelFormat.iPixelFormat) - { - case EUidPixelFormatYUV_422Interleaved: - return(ProcessYUV422(aImageBaseAddress)); - case EUidPixelFormatRGB_565: - return(ProcessRGB565(aImageBaseAddress)); - default: - return(KErrNotSupported); - } - } - -/** -Post process a received RGB565 image. -@return KErrNone if write was successful, otherwise one of the other system wide error codes. -*/ -TInt TCamDisplayHandler::ProcessRGB565(TUint8* aImageBaseAddress) - { - TUint16* source = (TUint16*) aImageBaseAddress; - TUint16 pixel; - TInt sourceModulo, destModulo, width, height; - TInt r = KErrNone; - - // Determine whether the screen or the picture to display is the widest, and calculate modulos - // and clipping sizes appropriately - if (iWidth < iScreenWidth) - { - width = iWidth; - sourceModulo = 0; - destModulo = (iScreenWidth - iWidth); - } - else - { - width = iScreenWidth; - sourceModulo = (iWidth - iScreenWidth); - destModulo = 0; - } - - // Determine whether the screen or the picture to display is the highest - height = (iHeight < iScreenHeight) ? iHeight : iScreenHeight; - - if (iBitsPerPixel == 16) - { - TUint16* dest = (TUint16*) iVideoAddress; - - // Loop around and copy the data directly onto the screen - for (TInt line = 0; line < height; ++line) - { - for (TInt x = 0; x < width; ++x) - { - *dest++ = *source++; - } - - source += sourceModulo; - dest += destModulo; - } - } - else if (iBitsPerPixel == 32) - { - TUint8* dest = iVideoAddress; - - destModulo *= 4; - - // Loop around and convert whatever part of the picture will fit onto the screen into BGRA, - // writing it directly onto the screen - for (TInt line = 0; line < height; ++line) - { - for (TInt x = 0; x < width; ++x) - { - pixel = *source++; - *dest++= (TUint8) ((pixel & 0x001f) << 3); - *dest++= (TUint8) ((pixel & 0x07e0) >> 3); - *dest++= (TUint8) ((pixel & 0xf800) >> 8); - *dest++ = 0xff; - } - - source += sourceModulo; - dest += destModulo; - } - } - else - { - r = KErrNotSupported; - } - - return r; - } - -/** -Post process a received YUV422 image. -@return KErrNone if write was successful, otherwise one of the other system wide error codes. -*/ -TInt TCamDisplayHandler::ProcessYUV422(TUint8* aImageBaseAddress) - { - TUint16* dest16 = (TUint16*) iVideoAddress; - TUint32* dest32 = (TUint32*) iVideoAddress; - TUint8* source = aImageBaseAddress; - TInt y, u, v, r, g, b, sourceModulo, destModulo, width, height; - TInt retVal = KErrNone; - - // Determine whether the screen or the picture to display is the widest, and calculate modulos - // and clipping sizes appropriately - if (iWidth < iScreenWidth) - { - width = (iWidth / 2); - sourceModulo = 0; - destModulo = (iScreenWidth - iWidth); - } - else - { - width = (iScreenWidth / 2); - sourceModulo = ((iWidth - iScreenWidth) * 2); - destModulo = 0; - } - - // Determine whether the screen or the picture to display is the highest - height = (iHeight < iScreenHeight) ? iHeight : iScreenHeight; - - // Only 16 and 32 bits per pixel are supported. It is also assumed that 16 bit will be RGB565 and - // 32 bit will be BGRA. You will need to add support for new formats if required - if ((iBitsPerPixel == 16) || (iBitsPerPixel == 32)) - { - // Loop around and convert whatever part of the picture will fit onto the screen into RGB565 or BGRA, - // writing it directly onto the screen - for (TInt line = 0; line < height; ++line) - { - for (TInt x = 0; x < width; ++x) - { - u = (source[0] - 128); - v = (source[2] - 128); - y = (source[3] - 16); - - r = ((298 * y + 409 * u) / 256); - g = ((298 * y - 100 * v - 208 * u) / 256); - b = ((298 * y + 516 * v) / 256); - - CLIP(r); - CLIP(g); - CLIP(b); - - if (iBitsPerPixel == 16) - { - *dest16++ = (TUint16) (((b & 0xf8) << 8) | ((g & 0xfc) << 3) | ((r & 0xf8) >> 3)); - } - else - { - *dest32++ = (0xff000000 | (r << 16) | (g << 8) | b); - } - - y = (source[1] - 16); - - r = ((298 * y + 409 * u) / 256); - g = ((298 * y - 100 * v - 208 * u) / 256); - b = ((298 * y + 516 * v) / 256); - - CLIP(r); - CLIP(g); - CLIP(b); - - if (iBitsPerPixel == 16) - { - *dest16++ = (TUint16) (((b & 0xf8) << 8) | ((g & 0xfc) << 3) | ((r & 0xf8) >> 3)); - } - else - { - *dest32++ = (0xff000000 | (r << 16) | (g << 8) | b); - } - - source += 4; - } - - source += sourceModulo; - dest16 += destModulo; - dest32 += destModulo; - } - } - else - { - retVal = KErrNotSupported; - } - - return retVal; - } - -/** -Appends a string representing a pixel format UID onto a descriptor. -@param aBuffer Reference to the descriptor into which to append the string. It is up to the - caller to ensure that this is large enough. -@param aPixelFormat UID of the pixel format to be converted into a string. -*/ -void AppendPixelFormat(TDes& aBuffer, TUidPixelFormat aPixelFormat) - { - if (aPixelFormat == EUidPixelFormatRGB_565) - aBuffer.Append(KPixelFormatRGB_565); - else if (aPixelFormat == EUidPixelFormatYUV_422Interleaved) - aBuffer.Append(KPixelFormatYUV_422Interleaved); - else if (aPixelFormat == EUidPixelFormatSpeedTaggedJPEG) - aBuffer.Append(KPixelFormatSpeedTaggedJPEG); - else if (aPixelFormat == EUidPixelFormatJPEG) - aBuffer.Append(KPixelFormatJPEG); - else - aBuffer.Append(KPixelFormatUnknown); - } - -void PrintCamModes(TCameraCapsV02* aCaps,RTest& aTest) - { - TBuf<80> buf; - - // Display the supported capture modes - buf.Zero(); - buf.Append(KCaptureModeCapsTitle); - if (aCaps->iNumImagePixelFormats) - buf.Append(KCaptureModeImage); - if (aCaps->iNumVideoPixelFormats) - buf.Append(KCaptureModeVideo); - if (aCaps->iNumViewFinderPixelFormats) - buf.Append(KCaptureModeViewFinder); - buf.Append(_L("\r\n")); - aTest.Printf(buf); - - // Display the supported video pixel formats - TUint i; - SDevCamPixelFormat* pixelFormat; - if (aCaps->iNumImagePixelFormats) - { - buf.Zero(); - buf.Append(KPixelFormatCapsTitle); - buf.Append(KCaptureModeImage); - pixelFormat = (SDevCamPixelFormat*) (aCaps + 1); - for (i = 0; i < aCaps->iNumImagePixelFormats; i++) - { - AppendPixelFormat(buf, pixelFormat->iPixelFormat); - pixelFormat++; - } - buf.Append(_L("\r\n")); - aTest.Printf(buf); - } - - if (aCaps->iNumVideoPixelFormats) - { - buf.Zero(); - buf.Append(KPixelFormatCapsTitle); - buf.Append(KCaptureModeVideo); - pixelFormat = (SDevCamPixelFormat*) (aCaps + 1); - for (i = aCaps->iNumImagePixelFormats; i < (aCaps->iNumImagePixelFormats + aCaps->iNumVideoPixelFormats); i++) - { - AppendPixelFormat(buf, pixelFormat->iPixelFormat); - pixelFormat++; - } - buf.Append(_L("\r\n")); - aTest.Printf(buf); - } - - if (aCaps->iNumViewFinderPixelFormats) - { - buf.Zero(); - buf.Append(KPixelFormatCapsTitle); - buf.Append(KCaptureModeViewFinder); - pixelFormat = (SDevCamPixelFormat*) (aCaps + 1); - i = aCaps->iNumImagePixelFormats + aCaps->iNumImagePixelFormats + 1; - for (i = aCaps->iNumImagePixelFormats + aCaps->iNumVideoPixelFormats; i < (aCaps->iNumImagePixelFormats + aCaps->iNumVideoPixelFormats + aCaps->iNumViewFinderPixelFormats); i++) - { - AppendPixelFormat(buf, pixelFormat->iPixelFormat); - pixelFormat++; - } - buf.Append(_L("\r\n")); - aTest.Printf(buf); - } - } - -void PrintCamConf(TCameraConfigV02& aConf,RTest& aTest) - { - TBuf<80> buf; - - // Display the current frame size - buf.Zero(); - buf.Append(KFrameSizeConfTitle); - buf.AppendFormat(KFrameSize, aConf.iFrameSize.iWidth, aConf.iFrameSize.iHeight); - buf.Append(_L("\r\n")); - aTest.Printf(buf); - - // Display the current pixel format - buf.Zero(); - buf.Append(KPixelFormatConfTitle); - AppendPixelFormat(buf, aConf.iPixelFormat.iPixelFormat); - buf.Append(_L("\r\n")); - aTest.Printf(buf); - - // Display the current frame rate - buf.Zero(); - buf.Format(_L("Current frame rate : %d fps\r\n"),aConf.iFrameRate); - aTest.Printf(buf); - } - -void PrintBufferConf(TMmSharedChunkBufConfig& aBufConf,RTest& aTest) - { - TBuf<80> buf(0); - - SBufSpecList* tempSpec = aBufConf.iSpec; - - // Display the buffer configuration - buf.Format(_L("Buffer Config : NumBufs:%d Size:%xH\r\n"),aBufConf.iNumBuffers,aBufConf.iBufferSizeInBytes); - aTest.Printf(buf); - if (aBufConf.iFlags & KScFlagBufOffsetListInUse) - { - buf.Format(_L(" Offsets[%08xH,%08xH,%08xH,%08xH]\r\n"),tempSpec[0].iBufferOffset,tempSpec[1].iBufferOffset,tempSpec[2].iBufferOffset,tempSpec[3].iBufferOffset); - aTest.Printf(buf); - buf.Format(_L(" Offsets[%08xH,%08xH,%08xH,%08xH]\r\n"),tempSpec[4].iBufferOffset,tempSpec[5].iBufferOffset,tempSpec[6].iBufferOffset,tempSpec[7].iBufferOffset); - aTest.Printf(buf); - } - } diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/multimedia/t_camera_display.h --- a/kerneltest/e32test/multimedia/t_camera_display.h Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -// Copyright (c) 2006-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: -// e32test\multimedia\t_camera_display.h -// -// - -#if !defined(__T_CAMERA_DISPLAY_H__) -#define __T_CAMERA_DISPLAY_H__ - -#include -#include -#include -#include "d_mmcsc.h" - -_LIT(KCaptureModeCapsTitle, "Capture modes: "); -_LIT(KCaptureModeImage, "Image "); -_LIT(KCaptureModeVideo, "Video "); -_LIT(KCaptureModeViewFinder, "ViewFinder "); - -_LIT(KPixelFormatCapsTitle, "Pixel formats: "); -_LIT(KPixelFormatConfTitle, "Current pixel format: "); -_LIT(KPixelFormatUnknown, "Pixel Format Unknown (Other) "); -_LIT(KPixelFormatRGB_565, "RGB565 "); -_LIT(KPixelFormatYUV_422Interleaved, "YUV422 Interleaved "); -_LIT(KPixelFormatSpeedTaggedJPEG, "Speed Tagged JPEG "); -_LIT(KPixelFormatJPEG, "JPEG "); - -class TCamDisplayHandler - { -public: - TCamDisplayHandler(); - TInt Init(); - TInt SetConfig(const SDevCamFrameSize& aSize,const SDevCamPixelFormat& aPixelFormat); - TInt Process(TUint8* aImageBaseAddress); -private: - TInt Min(TInt aA, TInt aB); - TInt ProcessRGB565(TUint8* aImageBaseAddress); - TInt ProcessYUV422(TUint8* aImageBaseAddress); -private: - /** Pixel format of the data to be converted and displayed */ - SDevCamPixelFormat iPixelFormat; - /** Address of the top left hand corner of screen memory */ - TUint8* iVideoAddress; - /** Width of the frame to be displayed, in pixels */ - TUint iWidth; - /** Height of the frame to be displayed, in pixels */ - TUint iHeight; - /** Width of the screen, in pixels */ - TUint iScreenWidth; - /** Height of the screen, in pixels */ - TUint iScreenHeight; - /** Number of bits per pixel */ - TInt iBitsPerPixel; - }; - -void AppendPixelFormat(TDes& aBuffer, TUidPixelFormat aPixelFormat); -void PrintCamModes(TCameraCapsV02* aCaps,RTest& aTest); -void PrintCamConf(TCameraConfigV02& aConf,RTest& aTest); -void PrintBufferConf(TMmSharedChunkBufConfig& aBufConf,RTest& aTest); - -#endif // __T_CAMERA_DISPLAY_H__ diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/multimedia/t_camera_gen.cpp --- a/kerneltest/e32test/multimedia/t_camera_gen.cpp Thu Jul 01 17:57:33 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,494 +0,0 @@ -// Copyright (c) 2004-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: -// e32test\multimedia\t_camera_gen.cpp -// -// - -#include -#include -#include -#include -#include "t_camera_display.h" -#include "d_mmcsc.h" - -_LIT(KTstLddFileName,"D_MMCSC.LDD"); -_LIT(KCamLddFileName,"ECAMERASC.LDD"); - -#ifdef __WINSCW__ -_LIT(KCamPddFileName,"_TEMPLATE_CAMERASC.PDD"); -#else -_LIT(KCamPddFileName,"CAMERASC.PDD"); -#endif - -_LIT(KCamFreePddExtension,".*"); - -const TInt KUnit0=0; -const TInt KFrameRate=30; // Run the test at 30fps - -class CCameraHandler; - -RTest test(_L("T_CAMERA_GEN")); -CCameraHandler* camera; - -/** -Wait for a key press, but timeout so automated tests -are unaffected -*/ -void util_getch_withtimeout(TUint aSecs) - { - TRequestStatus keyStat; - test.Console()->Read(keyStat); - RTimer timer; - test(timer.CreateLocal()==KErrNone); - TRequestStatus timerStat; - timer.After(timerStat,aSecs*1000000); - User::WaitForRequest(timerStat,keyStat); - if(keyStat!=KRequestPending) - (void)test.Console()->KeyCode(); - timer.Cancel(); - timer.Close(); - test.Console()->ReadCancel(); - User::WaitForAnyRequest(); - } - -// Define the frame number to capture -// For image capture this should be zero. -const TInt64 KFrameNumberToCapture= 50; - -/// Defines camera handler -class CCameraHandler : public CActive - { -public: - static CCameraHandler* NewL(); - ~CCameraHandler(); - TInt SetConfig(TDevCamCaptureMode aCaptureMode, SDevCamFrameSize aSize,SDevCamPixelFormat aPixelFormat,TBool aCreateChunk,TInt aNumBuffers); - void GetConfig(TDevCamCaptureMode aCaptureMode); - TInt GetCaps(); - TInt SetFirstConfig(TUint aOffset); - TInt Start(TDevCamCaptureMode aCaptureMode); - TInt Stop(); - void SetCaptureMode(TDevCamCaptureMode aCaptureMode); -private: - CCameraHandler(); - virtual void RunL(); - virtual void DoCancel(); - TInt Init(); -private: - TCamDisplayHandler iDispHandler[ECamCaptureModeMax]; - RDevCameraSc iCamera; - RChunk iChunk[ECamCaptureModeMax]; - TInt iFrameCount; - TDevCamCaptureMode iCaptureMode; - TInt iCapsSize; - TAny* iCapsBufPtr; - TCameraCapsV02* iCameraCaps; - }; - -CCameraHandler::CCameraHandler() : CActive(EPriorityStandard) -// -// Constructor for the camera handler -// - { - // Active object priority is set to normal - } - -CCameraHandler::~CCameraHandler() -// -// Destructor for the camera handler -// - { - for (TInt captureMode=0; captureMode < ECamCaptureModeMax; captureMode++) - iChunk[captureMode].Close(); - if(iCapsBufPtr) - User::Free(iCapsBufPtr); - iCamera.Close(); - // Cancel any active request - CActive::Cancel(); - } - -void CCameraHandler::DoCancel() - { - - } - -CCameraHandler* CCameraHandler::NewL() -// -// Create active camera -// - { - test.Printf(_L("NewL\r\n")); - CCameraHandler *cc = new (ELeave) CCameraHandler; - TInt r=cc->Init(); - if (r!=KErrNone) - User::Leave(r); - CActiveScheduler::Add(cc); - return(cc); - } - -TInt CCameraHandler::Init() -// -// Initialise hardware -// - { - test.Printf(_L("Init\r\n")); - TInt r; - for (TInt captureMode=0; captureMode < ECamCaptureModeMax; captureMode++) - { - r=iDispHandler[captureMode].Init(); - if (r!=KErrNone) - return(r); - } - - // Open camera driver channel - r=iCamera.Open(KUnit0); - return(r); - } - -void CCameraHandler::SetCaptureMode(TDevCamCaptureMode aCaptureMode) - { - iCaptureMode=aCaptureMode; - } - -TInt CCameraHandler::GetCaps() - { - test.Printf(_L("GetCaps\r\n")); - iCapsSize=iCamera.CapsSize(); - iCapsBufPtr = User::Alloc(iCapsSize); - TPtr8 capsPtr( (TUint8*)iCapsBufPtr, iCapsSize, iCapsSize ); - TInt r = iCamera.Caps(capsPtr); - if(r!=KErrNone) - return r; - iCameraCaps = (TCameraCapsV02*) capsPtr.Ptr(); - - test.Printf(_L("Number of supported pixel formats:%d\r\n"),iCameraCaps->iNumVideoPixelFormats); - return r; - } - -void CCameraHandler::GetConfig(TDevCamCaptureMode aCaptureMode) - { - test.Printf(_L("GetConfig\r\n")); - // Config camera - TCameraConfigV02Buf configBuf; - TCameraConfigV02 &config=configBuf(); - - iCamera.GetCamConfig(aCaptureMode, configBuf); - - test.Printf(_L("Pixel Format:%d\r\n"),config.iPixelFormat); - test.Printf(_L("Frame Size :%d\r\n"),config.iFrameSize); - test.Printf(_L("Frame rate :%dfps\r\n"),config.iFrameRate); - } - -TInt CCameraHandler::SetFirstConfig(TUint aOffset) - { - test.Printf(_L("SetFirstConfig\r\n")); - TInt ret; - TAny* frameSizeCapsBuf=0; - SDevCamPixelFormat* pixelFormat; - SDevCamFrameSize* frameSize; - TPtr8 frameSizeCapsPtr(0,0,0); - pixelFormat = (SDevCamPixelFormat*) (iCameraCaps + 1); - - if(camera->iCameraCaps->iNumVideoPixelFormats) - { - pixelFormat = pixelFormat + iCameraCaps->iNumImagePixelFormats + iCameraCaps->iNumVideoPixelFormats; - frameSizeCapsBuf = User::Alloc(pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize)); - new (&frameSizeCapsPtr) TPtr8((TUint8*)frameSizeCapsBuf, pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize), pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize)); - ret=iCamera.FrameSizeCaps(ECamCaptureModeImage, pixelFormat->iPixelFormat, frameSizeCapsPtr); - test(ret==KErrNone); - frameSize = (SDevCamFrameSize*) frameSizeCapsPtr.Ptr(); - if((pixelFormat->iNumFrameSizes>aOffset) && aOffset) - frameSize += aOffset; - ret=camera->SetConfig(ECamCaptureModeVideo,*frameSize,*pixelFormat,ETrue,3); - test(ret==KErrNone); - User::Free(frameSizeCapsBuf); - return(KErrNone); - } - else - return(KErrNotSupported); - } - -TInt CCameraHandler::SetConfig(TDevCamCaptureMode aCaptureMode, SDevCamFrameSize aSize,SDevCamPixelFormat aPixelFormat,TBool aCreateChunk,TInt aNumBuffers) - { - test.Printf(_L("SetConfig\r\n")); - TInt r=iDispHandler[aCaptureMode].SetConfig(aSize,aPixelFormat); - if (r!=KErrNone) - return(r); - - // Config camera - TCameraConfigV02Buf configBuf; - TCameraConfigV02 &config=configBuf(); - iCamera.GetCamConfig(aCaptureMode, configBuf); // Load defaults - - config.iFrameSize=aSize; - config.iPixelFormat=aPixelFormat; - config.iFrameRate=KFrameRate; - - TMmSharedChunkBufConfig bufferConfig; - TPckg bufferConfigBuf(bufferConfig); - - r=iCamera.SetCamConfig(aCaptureMode,configBuf); - if (r!=KErrNone) - return(r); - - if (aCreateChunk) - { - r=iCamera.SetBufConfigChunkCreate(aCaptureMode,aNumBuffers,iChunk[aCaptureMode]); - if (r!=KErrNone) - return(r); - } - else - { - // 'aNumBuffers' is ignored here, D_MMCSC.LDD currently uses 2 buffers - - RMmCreateSc tstDrv; - r=tstDrv.Open(); - if (r!=KErrNone) - return(r); - r=tstDrv.GetChunkHandle(iChunk[aCaptureMode]); // Get a handle on the shared chunk created by the test driver - if (r!=KErrNone) - return(r); - r=tstDrv.GetBufInfo(bufferConfigBuf); - if (r!=KErrNone) - return(r); - r=iCamera.SetBufConfigChunkOpen(aCaptureMode,bufferConfigBuf,iChunk[aCaptureMode]); - if (r!=KErrNone) - return(r); - - tstDrv.Close(); - } - - iCamera.GetBufferConfig(aCaptureMode, bufferConfigBuf); - PrintBufferConf(bufferConfig,test); - - return(r); - } - -TInt CCameraHandler::Start(TDevCamCaptureMode aCaptureMode) -// -// Set object active, start getting images from the camera -// - { - test.Printf(_L("Start\r\n")); - // Set object active - iFrameCount=0; - SetActive(); - iCamera.SetCaptureMode(aCaptureMode); - // Add request for a new image - TInt r=iCamera.Start(); - if (r==KErrNone) - iCamera.NotifyNewImage(iStatus); - return(r); - } - -void CCameraHandler::RunL() -// -// Handles a new request -// - { - TInt retId=iStatus.Int(); - TInt retOffset=-1; - iCamera.BufferIdToOffset(iCaptureMode,retId,retOffset); - if (retId>=0) - { - TUint8* imgBase=iChunk[iCaptureMode].Base()+retOffset; - TInt r=iDispHandler[iCaptureMode].Process(imgBase); - -#ifdef __WINSCW__ - test(r==KErrNotSupported); -#else - test(r==KErrNone); -#endif - - // Release the buffer - test(iCamera.ReleaseBuffer(retId)==KErrNone); - iFrameCount++; - } - else - test.Printf(_L("Capture error (%d)\r\n"),retId); - - if (iFrameCountGetConfig(ECamCaptureModeVideo); - camera->SetCaptureMode(ECamCaptureModeVideo); - test.Next(_L("Starting camera")); - ret=camera->Start(ECamCaptureModeVideo); - test.Printf(_L("Start returned %d\r\n"),ret); - test(ret==KErrNone); - - // Calculate frame rate. - // We store cuurent time before receiving data from the camera and - // after to have received KFrameNumberToCapture pictures, we calculate - // time elapsed during the reception. - TTimeIntervalMicroSeconds microseconds ; - TTime now; - TTime iTime; - now.HomeTime(); - - test.Next(_L("Starting active scheduler")); - // Start active scheduler - CActiveScheduler::Start(); - - // We have received all pictures, so we store the new current time - iTime.HomeTime(); - - // We keep this time in microseconds to be more precise - microseconds = iTime.MicroSecondsFrom(now) ; - - TInt64 timeElapsed = microseconds.Int64(); - - // We store in this variable, integer value of the frame rate - TInt64 intFrameRate = (TInt64)((KFrameNumberToCapture *1000000)/timeElapsed); - - // We store in this variable, decimal value of the frame rate - TInt64 milliFrameRate = (TInt64)((KFrameNumberToCapture *1000000)%timeElapsed); - milliFrameRate = (milliFrameRate*1000) / timeElapsed; - - test.Printf(_L(" Frame rate for frames received : %d.%03d frames per second\r\n"), static_cast(intFrameRate), static_cast(milliFrameRate)); - test.Printf(_L(" Frame rate expected : %d.000 frames per second\r\n"),KFrameRate); - test.Next(_L("Stopping camera")); - // Stop Camera - ret=camera->Stop(); - test(ret==KErrNone); - } - -// -// Test program main part -// -TInt E32Main() - { - __UHEAP_MARK; - - test.Title(); - test.Start(_L("Camera module GEN test")); - - test.Next(_L("Loading CAMERA PDD")); - TInt ret=User::LoadPhysicalDevice(KCamPddFileName); - test.Printf(_L("Returned %d\r\n"),ret); - - if (ret==KErrNotFound) - { - test.Printf(_L("Shared chunk camera driver not supported - test skipped\r\n")); - test.End(); - test.Close(); - __UHEAP_MARKEND; - return(KErrNone); - } - - test(ret==KErrNone || ret==KErrAlreadyExists); - - test.Next(_L("Loading CAMERA LDD")); - ret=User::LoadLogicalDevice(KCamLddFileName); - test.Printf(_L("Returned %d\r\n"),ret); - test(ret==KErrNone || ret==KErrAlreadyExists); - - test.Next(_L("Loading D_MMCSC LDD")); - ret=User::LoadLogicalDevice(KTstLddFileName); - test.Printf(_L("Returned %d\r\n"),ret); - test(ret==KErrNone||ret==KErrAlreadyExists); - - __KHEAP_MARK; - - // Construct and install the active scheduler - test.Next(_L("Initialising active scheduler")); - CActiveScheduler *exampleScheduler = new (ELeave) CActiveScheduler(); - // Install as the active scheduler - CActiveScheduler::Install(exampleScheduler); - - // Create camera handler - test.Next(_L("Creating camera handler")); - camera = CCameraHandler::NewL(); - - test.Next(_L("+ Getting Camera Capabilities")); - ret=camera->GetCaps(); - test(ret==KErrNone); - - // SetConfig - test.Next(_L("Setting Camera Configuration")); - ret=camera->SetFirstConfig(0); - test(ret==KErrNone); - TestRecording(); - - // Repeat with a different configuration - test.Next(_L("Resetting Camera Configuration")); - ret=camera->SetFirstConfig(1); - test(ret==KErrNone); - TestRecording(); - - delete camera; - delete exampleScheduler; - - __KHEAP_MARKEND; - - // Free the PDDs and LDDs - test.Next(_L("Freeing ECAMERASC LDD")); - ret=User::FreeLogicalDevice(KDevCameraScName); - test(ret==KErrNone); - - test.Next(_L("Freeing CAMERASC PDD")) ; - TFindPhysicalDevice fDr; - TFullName drivName; - TName searchName; - searchName.Append(KDevCameraScName); - searchName.Append(KCamFreePddExtension); - fDr.Find(searchName); - ret=fDr.Next(drivName); - test(ret==KErrNone); - ret=User::FreePhysicalDevice(drivName); - test(ret==KErrNone); - - test.Next(_L("Freeing D_MMCSC LDD")); - ret=User::FreeLogicalDevice(KDevMmCScName); - test(ret==KErrNone); - - test.Printf(_L("Hit any key to continue\r\n")); - util_getch_withtimeout(5); - - test.End(); - test.Close(); - - __UHEAP_MARKEND; - - return KErrNone; - } diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/resmanus/d_resmanusbtrace.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/resmanus/d_resmanusbtrace.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,351 @@ +// Copyright (c) 2010 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: +// e32test\resmanus\d_resmanusbtrace.cpp +// +// + +#include +#include +#include +#include +#include +#include "d_resmanusbtraceconst.h" +#include "d_resmanusbtrace.h" + +class DTestFactory : public DLogicalDevice +// +// Test LDD factory +// + { +public: + DTestFactory(); + virtual TInt Install(); //overriding pure virtual + virtual void GetCaps(TDes8& aDes) const; //overriding pure virtual + virtual TInt Create(DLogicalChannelBase*& aChannel); //overriding pure virtual + }; + +class DTest1 : public DLogicalChannelBase +// +// Test logical channel +// + { +public: + virtual ~DTest1(); +protected: + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2); + +private: + TInt DoSendLog(TLogInfo* aInfo); + TInt ClientHandle() { return KClientHandle; } + }; + + + +DECLARE_STANDARD_LDD() + { + return new DTestFactory; + } + +// +// Constructor +// +DTestFactory::DTestFactory() + { + + } + +TInt DTestFactory::Create(DLogicalChannelBase*& aChannel) + { +// +// Create new channel +// + aChannel=new DTest1; + return aChannel?KErrNone:KErrNoMemory; + } + +TInt DTestFactory::Install() +// +// Install the LDD - overriding pure virtual +// + { + return SetName(&KLddName); + } + +void DTestFactory::GetCaps(TDes8& /*aDes*/) const +// +// Get capabilities - overriding pure virtual +// + { + } + +TInt DTest1::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/) +// +// Create channel +// + { + return KErrNone; + } + +DTest1::~DTest1() +// +// Destructor +// + { + } + +TInt DTest1::Request(TInt aReqNo, TAny* a1, TAny* /*a2*/) + { + + // 'Control' functions... + switch(aReqNo) + { + // DoControl + case RLddTest1::ECONTROL_SENDLOG: + TLogInfo info; + DoSendLog(&info); + Kern::ThreadRawWrite(&Kern::CurrentThread(), a1, &info, sizeof(info)); + break; + } + + return KErrNone; + } + +class TestResource + { +public: + TestResource(const TDesC8& aName, TInt aDefaultLevel) + { + iName = (HBuf8*)&aName; + iDefaultLevel = aDefaultLevel; + } + HBuf* iName; + TInt iDefaultLevel; + TInt iResourceId; + }; + +struct TestClient + { + TDes8* iName; + TInt iClientId; + }; + +struct TestCallback + { + TInt iResourceId; + TInt iClientId; + }; + +struct TestNotification + { + TestCallback iCallback; + }; + +class TestRequest + { +public: + TInt ResourceId() {return iResourceId;} + TInt ClientId() {return iClientId;} + TInt Level() {return iLevel;} + TInt iResourceId; + TInt iClientId; + TInt iLevel; + }; + +TInt DTest1::DoSendLog(TLogInfo* aInfo) + { + TInt r = KErrNoMemory; + + TInt iClient = (TInt) KClient; + TBuf<80> Buffer; + TDes8* iUserNameUsed = &Buffer; + Buffer.Append(KCLIENTNAME); + Kern::Printf("PRM_US_OPEN_CHANNEL_START_TRACE"); + PRM_US_OPEN_CHANNEL_START_TRACE + + Kern::Printf("PRM_US_OPEN_CHANNEL_END_TRACE %x", (TInt)ClientHandle()); + PRM_US_OPEN_CHANNEL_END_TRACE + + TUint8 stateRes[3] = {KStatsRes1, KStatsRes2, KStatsRes3}; + Kern::Printf("PRM_US_REGISTER_CLIENT_START_TRACE"); + PRM_US_REGISTER_CLIENT_START_TRACE + + Kern::Printf("PRM_US_REGISTER_CLIENT_END_TRACE"); + PRM_US_REGISTER_CLIENT_END_TRACE + + Kern::Printf("PRM_US_DEREGISTER_CLIENT_START_TRACE"); + PRM_US_DEREGISTER_CLIENT_START_TRACE + + Kern::Printf("PRM_US_DEREGISTER_CLIENT_END_TRACE"); + PRM_US_DEREGISTER_CLIENT_END_TRACE + + TUint resourceId = KResourceId; + Kern::Printf("PRM_US_GET_RESOURCE_STATE_START_TRACE"); + PRM_US_GET_RESOURCE_STATE_START_TRACE + + TUint aResourceId = KResourceId; + TUint aLevel = KLevel; + TUint aClient = KClient; + TUint aResult = KResult; + Kern::Printf("PRM_US_GET_RESOURCE_STATE_END_TRACE"); + PRM_US_GET_RESOURCE_STATE_END_TRACE + + TUint newState = KLevel; + Kern::Printf("PRM_US_SET_RESOURCE_STATE_START_TRACE"); + PRM_US_SET_RESOURCE_STATE_START_TRACE + + Kern::Printf("PRM_US_SET_RESOURCE_STATE_END_TRACE"); + PRM_US_SET_RESOURCE_STATE_END_TRACE + + Kern::Printf("PRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE"); + PRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE + + Kern::Printf("PRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE"); + PRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE + + Kern::Printf("PRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE"); + PRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE + + Kern::Printf("PRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE"); + PRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE + + TPowerResourceInfoV01 ResourceInfo; + TPowerResourceInfoV01* pResInfo = &ResourceInfo; + TestResource Resource(KRESOURCENAME, KDefaultLevel); + TestResource* pR = &Resource; + pResInfo->iMinLevel = KMinLevel; + pResInfo->iMaxLevel = KMaxLevel; + pResInfo->iDefaultLevel = KDefaultLevel; + TUint resCount = KResCount; + Kern::Printf("PRM_REGISTER_RESOURCE_TRACE"); + PRM_REGISTER_RESOURCE_TRACE + + TUint aClientId = KClientId; + TBuf8<80> ClientName(KCLIENTNAME); + SPowerResourceClient ResourceClient; + SPowerResourceClient* pC = &ResourceClient; + pC->iName = &ClientName; + Kern::Printf("PRM_CLIENT_REGISTER_TRACE"); + PRM_CLIENT_REGISTER_TRACE + + Kern::Printf("PRM_CLIENT_DEREGISTER_TRACE"); + PRM_CLIENT_DEREGISTER_TRACE + + TInt aNewState = KLevel; + pC->iClientId = KClientId; + Kern::Printf("PRM_CLIENT_CHANGE_STATE_START_TRACE"); + PRM_CLIENT_CHANGE_STATE_START_TRACE + + pC->iClientId = KClientId; + Kern::Printf("PRM_CLIENT_CHANGE_STATE_END_TRACE"); + PRM_CLIENT_CHANGE_STATE_END_TRACE + + TestNotification aN; + TestNotification* pN = &aN; + pN->iCallback.iResourceId = KResourceId; + + Kern::Printf("PRM_POSTNOTIFICATION_REGISTER_TRACE"); + PRM_POSTNOTIFICATION_REGISTER_TRACE + + Kern::Printf("PRM_POSTNOTIFICATION_DEREGISTER_TRACE"); + PRM_POSTNOTIFICATION_DEREGISTER_TRACE + + Kern::Printf("PRM_POSTNOTIFICATION_SENT_TRACE"); + PRM_POSTNOTIFICATION_SENT_TRACE + + TestCallback* pCb = &(pN->iCallback); + pCb->iClientId = KClientId; + Kern::Printf("PRM_CALLBACK_COMPLETION_TRACE"); + PRM_CALLBACK_COMPLETION_TRACE + + TInt size = KSize; + PRM_MEMORY_USAGE_TRACE + + TestRequest aRequest; + aRequest.iClientId = KClientId; + aRequest.iResourceId = KResourceId; + + TDesC8* iName = iUserNameUsed; + Kern::Printf("PRM_PSL_RESOURCE_GET_STATE_START_TRACE"); + PRM_PSL_RESOURCE_GET_STATE_START_TRACE + + Kern::Printf("PRM_RESOURCE_GET_STATE_START_TRACE"); + PRM_RESOURCE_GET_STATE_START_TRACE + + TInt retVal = KRetVal; + TInt iCurLevel = KLevel; + TInt aState = KLevel; + Kern::Printf("PRM_PSL_RESOURCE_GET_STATE_END_TRACE"); + PRM_PSL_RESOURCE_GET_STATE_END_TRACE + + Kern::Printf("PRM_RESOURCE_GET_STATE_END_TRACE"); + PRM_RESOURCE_GET_STATE_END_TRACE + + Kern::Printf("PRM_RESOURCE_CANCEL_LONGLATENCY_OPERATION_TRACE"); + PRM_RESOURCE_CANCEL_LONGLATENCY_OPERATION_TRACE + + aRequest.iLevel = KLevel; + Kern::Printf("PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE"); + PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE + + Kern::Printf("PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE"); + PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE + + TInt iDefaultLevel = KDefaultLevel; + TInt iFlags = KFlags; + TInt iMinLevel = KMinLevel; + TInt iMaxLevel = KMaxLevel; + TInt aReason = KErrNoMemory; + Kern::Printf("PRM_PSL_RESOURCE_CREATE_TRACE"); + PRM_PSL_RESOURCE_CREATE_TRACE + + Kern::Printf("PRM_BOOTING_TRACE"); + PRM_BOOTING_TRACE + + TestResource* aPDRes = &Resource; + aPDRes->iResourceId = KResourceId; + TestClient Client; + TestClient* aClientPtr = &Client; + aClientPtr->iName = &ClientName; + aClientPtr->iClientId = KClientId; + Kern::Printf("PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE"); + PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE + + TestResource* pDR = &Resource; + TInt level = KLevel; + Kern::Printf("PRM_REGISTER_DYNAMIC_RESOURCE_TRACE"); + PRM_REGISTER_DYNAMIC_RESOURCE_TRACE + + Kern::Printf("PRM_DEREGISTER_DYNAMIC_RESOURCE_TRACE"); + PRM_DEREGISTER_DYNAMIC_RESOURCE_TRACE + + TestResource* pR1 = &Resource; + TestResource* pR2 = &Resource; + Kern::Printf("PRM_REGISTER_RESOURCE_DEPENDENCY_TRACE"); + PRM_REGISTER_RESOURCE_DEPENDENCY_TRACE + + TestResource* pDR1 = &Resource; + TestResource* pDR2 = &Resource; + Kern::Printf("PRM_DEREGISTER_RESOURCE_DEPENDENCY_TRACE"); + PRM_DEREGISTER_RESOURCE_DEPENDENCY_TRACE + + aInfo->iPR = &Resource; + aInfo->iPC = &ResourceClient; + aInfo->iPN = pN; + aInfo->iPCb = pCb; + aInfo->iPClient = &Client; + aInfo->iPCallback = &(pN->iCallback); + + return KErrNone; + } diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/resmanus/d_resmanusbtrace.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/resmanus/d_resmanusbtrace.h Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,46 @@ +// Copyright (c) 2010 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: +// e32test\resmanus\d_resmanusbtrace.h +// +// + +#if !defined(__D_RESMANUSBTRACE_H__) +#define __D_RESMANUSBTRACE_H__ + +#include +#ifndef __KERNEL_MODE__ +#include +#endif + +_LIT(KLddName,"D_RESMANUSBTRACE.LDD"); + +class RLddTest1 : public RBusLogicalChannel + { +public: + enum TControl + { + ECONTROL_SENDLOG + }; + +public: +#ifndef __KERNEL_MODE__ + + inline TInt Open() + { return DoCreate(KLddName,TVersion(0,1,1),KNullUnit,NULL,NULL); } + inline TInt SendLog(TLogInfo* aInfo) + { return DoControl(ECONTROL_SENDLOG, aInfo); } + +#endif + }; +#endif //__D_RESMANUSBTRACE_H__ diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/resmanus/d_resmanusbtrace.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/resmanus/d_resmanusbtrace.mmp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,39 @@ +// Copyright (c) 2010 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: +// e32test/resmanus/d_resmanusbtrace.mmp +// +// + +#include "kernel/kern_ext.mmh" + +TARGET d_resmanusbtrace.ldd +TARGETTYPE LDD +SOURCEPATH . +SOURCE d_resmanusbtrace.cpp + + +EPOCALLOWDLLDATA + +UID 0x100000af +VENDORID 0x70000001 + +macro BTRACE_RESMANUS +macro BTRACE_RESOURCE_MANAGER +macro PRM_ENABLE_EXTENDED_VERSION +capability all + +start wins +win32_headers +end +SMPSAFE diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/resmanus/d_resmanusbtraceconst.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/resmanus/d_resmanusbtraceconst.h Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,54 @@ +// Copyright (c) 2010 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: +// e32test\resmanus\d_resmanusbtraceconst.h +// +// + +#ifndef D_RESMANUSBTRACECONST_H_ +#define D_RESMANUSBTRACECONST_H_ + + +const TUint KClientId = 0x12345678; +const TInt KClientHandle = 0x10; +const TUint8 KStatsRes1 = 0x20; +const TUint8 KStatsRes2 = 0x21; +const TUint8 KStatsRes3 = 0x22; +const TUint KResourceId = 0x80; +const TUint KLevel = 0x90; +const TUint KClient = 0xC800FFFF; +const TUint KResult = 0x100; +const TInt KMinLevel = -99; +const TInt KMaxLevel = 99; +const TInt KDefaultLevel = 50; +const TInt KResCount = 20; +const TInt KSize = 999; +const TInt KRetVal = KErrNoMemory; +const TUint KFlags = 0xAAAAAAAA; + +_LIT8(KRESOURCENAME, "ResourceName"); +_LIT8(KCLIENTNAME, "ClientName"); + +struct TLogInfo + { + TAny* iPR; + TAny* iPC; + TAny* iPN; + TAny* iPCb; + TAny* iPClient; + TAny* iPCallback; + }; + + + +#endif /* D_RESMANUSBTRACECONST_H_ */ diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/resmanus/t_resmanusbtrace.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/resmanus/t_resmanusbtrace.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,754 @@ +// Copyright (c) 2010 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: +// e32test\resmanus\t_resmanusbtrace.cpp +// +// + +#include +#include +#include +#include +#include +#include +#include +#include "d_resmanusbtraceconst.h" +#include "d_resmanusbtrace.h" + +_LIT(KLddFileName, "D_RESMANUSBTRACE.LDD"); + +RLddTest1 ldd; +GLDEF_D RTest test(_L("T_RESMANUSBTRACE")); + +TInt BTraceHeaderSize = 0; + +RBTrace Trace; +TUint8* BufferPtr; +TInt Count; +TLogInfo LogInfo; + +CConsoleBase* console; + +class CTestTraceBase + { +public: + CTestTraceBase(TUint8** aBufferPtrAddr, TInt aHeaderSize) : + iBufferPtrAddr(aBufferPtrAddr), iHeaderSize(aHeaderSize) + { + iBuffer.Zero(); + } + void SkipHeader() + { + *iBufferPtrAddr += iHeaderSize; + } + TInt Compare() + { + TInt i = 0; + TPtrC8 ptr2(*iBufferPtrAddr, iBuffer.Length()); + TUint length = iBuffer.Length(); + length = (length + 0x3) & (~0x3); + + for(i = 0; i < ptr2.Length(); i++) + { + test.Printf(_L("%02x "), ptr2.Ptr()[i]); + } + test.Printf(_L("\n")); + for(i = 0; i < iBuffer.Length(); i++) + { + test.Printf(_L("%02x "), iBuffer.Ptr()[i]); + } + test.Printf(_L("\n")); + + *iBufferPtrAddr += length; + return (iBuffer.Compare(ptr2)==0)?KErrNone:KErrCorrupt; + } + void AppendUInt(TUint aVal) + { + iBuffer.Append((TUint8*)&aVal, sizeof(TUint)); + } + void AppendInt(TInt aVal) + { + iBuffer.Append((TUint8*)&aVal, sizeof(TInt)); + } + void AppendDes(const TDesC8& aDesPtr) + { + iBuffer.Append(aDesPtr); + } + TUint8** iBufferPtrAddr; + TBuf8<80> iBuffer; + TInt iHeaderSize; + }; + +class Test_PRM_US_OPEN_CHANNEL_START_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_OPEN_CHANNEL_START_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClient); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_US_OPEN_CHANNEL_END_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_OPEN_CHANNEL_END_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt((TUint)KClientHandle); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_US_REGISTER_CLIENT_START_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_REGISTER_CLIENT_START_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientHandle); + TUint32 stateRes32 = ((KStatsRes1&0xFF) << 16) | ((KStatsRes2&0xFF) << 8) | ((KStatsRes3&0xFF)); + AppendUInt(stateRes32); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_US_REGISTER_CLIENT_END_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_REGISTER_CLIENT_END_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientHandle); + AppendInt(KRetVal); + } + }; + +class Test_PRM_US_DEREGISTER_CLIENT_START_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_DEREGISTER_CLIENT_START_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientHandle); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_US_DEREGISTER_CLIENT_END_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_DEREGISTER_CLIENT_END_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientHandle); + } + }; + +class Test_PRM_US_GET_RESOURCE_STATE_START_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_GET_RESOURCE_STATE_START_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KResourceId); + AppendUInt(KClientHandle); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_US_GET_RESOURCE_STATE_END_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_GET_RESOURCE_STATE_END_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KResourceId); + AppendUInt(KLevel); + AppendUInt(KClient); + AppendUInt(KResult); + } + }; + +class Test_PRM_US_SET_RESOURCE_STATE_START_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_SET_RESOURCE_STATE_START_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KResourceId); + AppendUInt(KLevel); + AppendUInt(KClientHandle); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_US_SET_RESOURCE_STATE_END_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_SET_RESOURCE_STATE_END_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KResourceId); + AppendUInt(KLevel); + AppendUInt(KClient); + AppendUInt(KResult); + } + }; + +class Test_PRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KResourceId); + AppendUInt(KClientHandle); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KResourceId); + AppendUInt(KClientHandle); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KResourceId); + AppendUInt(KClientHandle); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE : public CTestTraceBase + { +public: + Test_PRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KResourceId); + AppendUInt(KClientHandle); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_REGISTER_RESOURCE_TRACE : public CTestTraceBase + { +public: + Test_PRM_REGISTER_RESOURCE_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KResCount+1); + AppendUInt((TUint)(LogInfo.iPR)); + AppendInt(KMinLevel); + AppendUInt(KMaxLevel); + AppendUInt(KDefaultLevel); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + } + }; + +class Test_PRM_CLIENT_REGISTER_TRACE : public CTestTraceBase + { +public: + Test_PRM_CLIENT_REGISTER_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt((TUint)LogInfo.iPC); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; +class Test_PRM_CLIENT_DEREGISTER_TRACE : public CTestTraceBase + { +public: + Test_PRM_CLIENT_DEREGISTER_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt((TUint)LogInfo.iPC); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_CLIENT_CHANGE_STATE_START_TRACE : public CTestTraceBase + { +public: + Test_PRM_CLIENT_CHANGE_STATE_START_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt(KLevel); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + } + }; + +class Test_PRM_CLIENT_CHANGE_STATE_END_TRACE : public CTestTraceBase + { +public: + Test_PRM_CLIENT_CHANGE_STATE_END_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendInt(KRetVal); + AppendUInt(KLevel); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + } + }; + +class Test_PRM_POSTNOTIFICATION_REGISTER_TRACE : public CTestTraceBase + { +public: + Test_PRM_POSTNOTIFICATION_REGISTER_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt((TUint)(LogInfo.iPCallback)); + AppendInt(KRetVal); + } + }; + +class Test_PRM_POSTNOTIFICATION_DEREGISTER_TRACE : public CTestTraceBase + { +public: + Test_PRM_POSTNOTIFICATION_DEREGISTER_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt((TUint)(LogInfo.iPCallback)); + AppendInt(KRetVal); + } + }; + +class Test_PRM_POSTNOTIFICATION_SENT_TRACE : public CTestTraceBase + { +public: + Test_PRM_POSTNOTIFICATION_SENT_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + } + }; + +class Test_PRM_CALLBACK_COMPLETION_TRACE : public CTestTraceBase + { +public: + Test_PRM_CALLBACK_COMPLETION_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + } + }; + +class Test_PRM_MEMORY_USAGE_TRACE : public CTestTraceBase + { +public: + Test_PRM_MEMORY_USAGE_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KSize); + } + }; + +class Test_PRM_PSL_RESOURCE_GET_STATE_START_TRACE : public CTestTraceBase + { +public: + Test_PRM_PSL_RESOURCE_GET_STATE_START_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_RESOURCE_GET_STATE_START_TRACE : public CTestTraceBase + { +public: + Test_PRM_RESOURCE_GET_STATE_START_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + } + }; + +class Test_PRM_PSL_RESOURCE_GET_STATE_END_TRACE : public CTestTraceBase + { +public: + Test_PRM_PSL_RESOURCE_GET_STATE_END_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt(KLevel); + AppendInt(KRetVal); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_RESOURCE_GET_STATE_END_TRACE : public CTestTraceBase + { +public: + Test_PRM_RESOURCE_GET_STATE_END_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt(KLevel); + AppendInt(KRetVal); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + } + }; + +class Test_PRM_RESOURCE_CANCEL_LONGLATENCY_OPERATION_TRACE : public CTestTraceBase + { +public: + Test_PRM_RESOURCE_CANCEL_LONGLATENCY_OPERATION_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendInt(KRetVal); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + } + }; + +class Test_PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE : public CTestTraceBase + { +public: + Test_PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt(KLevel); + AppendUInt(KLevel); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE : public CTestTraceBase + { +public: + Test_PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt(KLevel); + AppendUInt(KLevel); + AppendInt(KRetVal); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_PSL_RESOURCE_CREATE_TRACE : public CTestTraceBase + { +public: + Test_PRM_PSL_RESOURCE_CREATE_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendInt(KMinLevel); + AppendInt(KMaxLevel); + AppendInt(KDefaultLevel); + AppendUInt(KFlags); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + } + }; + +class Test_PRM_BOOTING_TRACE : public CTestTraceBase + { +public: + Test_PRM_BOOTING_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendInt(KErrNoMemory); + } + }; + +class Test_PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE : public CTestTraceBase + { +public: + Test_PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KResourceId); + AppendUInt((TUint)(LogInfo.iPR)); + AppendInt(KMinLevel); + AppendInt(KMaxLevel); + AppendInt(KDefaultLevel); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + } + }; + +class Test_PRM_REGISTER_DYNAMIC_RESOURCE_TRACE : public CTestTraceBase + { +public: + Test_PRM_REGISTER_DYNAMIC_RESOURCE_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt((TUint)(LogInfo.iPR)); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + } + }; + +class Test_PRM_DEREGISTER_DYNAMIC_RESOURCE_TRACE : public CTestTraceBase + { +public: + Test_PRM_DEREGISTER_DYNAMIC_RESOURCE_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt((TUint)(LogInfo.iPR)); + AppendUInt(KLevel); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + } + }; + +class Test_PRM_REGISTER_RESOURCE_DEPENDENCY_TRACE : public CTestTraceBase + { +public: + Test_PRM_REGISTER_RESOURCE_DEPENDENCY_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt(KResourceId); + AppendUInt((TUint)(LogInfo.iPR)); + AppendUInt((TUint)(LogInfo.iPR)); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + } + }; + +class Test_PRM_DEREGISTER_RESOURCE_DEPENDENCY_TRACE : public CTestTraceBase + { +public: + Test_PRM_DEREGISTER_RESOURCE_DEPENDENCY_TRACE() : CTestTraceBase(&BufferPtr, BTraceHeaderSize) + { + AppendUInt(KClientId); + AppendUInt(KResourceId); + AppendUInt(KResourceId); + AppendUInt((TUint)(LogInfo.iPR)); + AppendUInt((TUint)(LogInfo.iPR)); + AppendUInt(KCLIENTNAME.iTypeLength); + AppendDes(KCLIENTNAME); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + AppendUInt(KRESOURCENAME.iTypeLength); + AppendDes(KRESOURCENAME); + } + }; + +void TestMacro() + { + const TInt numCpus = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0); + if(numCpus>1) + { + BTraceHeaderSize = 20; + } + else + { + BTraceHeaderSize = 12; + } + + Test_PRM_US_OPEN_CHANNEL_START_TRACE testPRM_US_OPEN_CHANNEL_START_TRACE; //0 + Test_PRM_US_OPEN_CHANNEL_END_TRACE testPRM_US_OPEN_CHANNEL_END_TRACE; //1 + Test_PRM_US_REGISTER_CLIENT_START_TRACE testPRM_US_REGISTER_CLIENT_START_TRACE; //2 + Test_PRM_US_REGISTER_CLIENT_END_TRACE testPRM_US_REGISTER_CLIENT_END_TRACE; //3 + Test_PRM_US_DEREGISTER_CLIENT_START_TRACE testPRM_US_DEREGISTER_CLIENT_START_TRACE; //4 + Test_PRM_US_DEREGISTER_CLIENT_END_TRACE testPRM_US_DEREGISTER_CLIENT_END_TRACE; //5 + Test_PRM_US_GET_RESOURCE_STATE_START_TRACE testPRM_US_GET_RESOURCE_STATE_START_TRACE; //6 + Test_PRM_US_GET_RESOURCE_STATE_END_TRACE testPRM_US_GET_RESOURCE_STATE_END_TRACE; //7 + Test_PRM_US_SET_RESOURCE_STATE_START_TRACE testPRM_US_SET_RESOURCE_STATE_START_TRACE; //8 + Test_PRM_US_SET_RESOURCE_STATE_END_TRACE testPRM_US_SET_RESOURCE_STATE_END_TRACE; //9 + Test_PRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE testPRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE; //10 + Test_PRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE testPRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE; //11 + Test_PRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE testPRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE; //12 + Test_PRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE testPRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE; //13 + Test_PRM_REGISTER_RESOURCE_TRACE testPRM_REGISTER_RESOURCE_TRACE; //14 + Test_PRM_CLIENT_REGISTER_TRACE testPRM_CLIENT_REGISTER_TRACE; //15 + Test_PRM_CLIENT_DEREGISTER_TRACE testPRM_CLIENT_DEREGISTER_TRACE; //16 + Test_PRM_CLIENT_CHANGE_STATE_START_TRACE testPRM_CLIENT_CHANGE_STATE_START_TRACE; //17 + Test_PRM_CLIENT_CHANGE_STATE_END_TRACE testPRM_CLIENT_CHANGE_STATE_END_TRACE; //18 + Test_PRM_POSTNOTIFICATION_REGISTER_TRACE testPRM_POSTNOTIFICATION_REGISTER_TRACE; //19 + Test_PRM_POSTNOTIFICATION_DEREGISTER_TRACE testPRM_POSTNOTIFICATION_DEREGISTER_TRACE; //20 + Test_PRM_POSTNOTIFICATION_SENT_TRACE testPRM_POSTNOTIFICATION_SENT_TRACE; //21 + Test_PRM_CALLBACK_COMPLETION_TRACE testPRM_CALLBACK_COMPLETION_TRACE; //22 + Test_PRM_MEMORY_USAGE_TRACE testPRM_MEMORY_USAGE_TRACE; //23 + Test_PRM_PSL_RESOURCE_GET_STATE_START_TRACE testPRM_PSL_RESOURCE_GET_STATE_START_TRACE; //24 + Test_PRM_RESOURCE_GET_STATE_START_TRACE testPRM_RESOURCE_GET_STATE_START_TRACE; //25 + Test_PRM_PSL_RESOURCE_GET_STATE_END_TRACE testPRM_PSL_RESOURCE_GET_STATE_END_TRACE; //26 + Test_PRM_RESOURCE_GET_STATE_END_TRACE testPRM_RESOURCE_GET_STATE_END_TRACE; //27 + Test_PRM_RESOURCE_CANCEL_LONGLATENCY_OPERATION_TRACE testPRM_RESOURCE_CANCEL_LONGLATENCY_OPERATION_TRACE; //28 + Test_PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE testPRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE; //29 + Test_PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE testPRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE; //30 + Test_PRM_PSL_RESOURCE_CREATE_TRACE testPRM_PSL_RESOURCE_CREATE_TRACE; //31 + Test_PRM_BOOTING_TRACE testPRM_BOOTING_TRACE; //32 + Test_PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE testPRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE; //33 + Test_PRM_REGISTER_DYNAMIC_RESOURCE_TRACE testPRM_REGISTER_DYNAMIC_RESOURCE_TRACE; //34 + Test_PRM_DEREGISTER_DYNAMIC_RESOURCE_TRACE testPRM_DEREGISTER_DYNAMIC_RESOURCE_TRACE; //35 + Test_PRM_REGISTER_RESOURCE_DEPENDENCY_TRACE testPRM_REGISTER_RESOURCE_DEPENDENCY_TRACE; //36 + Test_PRM_DEREGISTER_RESOURCE_DEPENDENCY_TRACE testPRM_DEREGISTER_RESOURCE_DEPENDENCY_TRACE; //37 + +// const TInt KNumTest = 38; + CTestTraceBase* TestArray[] = + { + &testPRM_US_OPEN_CHANNEL_START_TRACE, + &testPRM_US_OPEN_CHANNEL_END_TRACE, + &testPRM_US_REGISTER_CLIENT_START_TRACE, + &testPRM_US_REGISTER_CLIENT_END_TRACE, + &testPRM_US_DEREGISTER_CLIENT_START_TRACE, + &testPRM_US_DEREGISTER_CLIENT_END_TRACE, + &testPRM_US_GET_RESOURCE_STATE_START_TRACE, + &testPRM_US_GET_RESOURCE_STATE_END_TRACE, + &testPRM_US_SET_RESOURCE_STATE_START_TRACE, + &testPRM_US_SET_RESOURCE_STATE_END_TRACE, + &testPRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE, + &testPRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE, + &testPRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE, + &testPRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE, + &testPRM_REGISTER_RESOURCE_TRACE, + &testPRM_CLIENT_REGISTER_TRACE, + &testPRM_CLIENT_DEREGISTER_TRACE, + &testPRM_CLIENT_CHANGE_STATE_START_TRACE, + &testPRM_CLIENT_CHANGE_STATE_END_TRACE, + &testPRM_POSTNOTIFICATION_REGISTER_TRACE, + &testPRM_POSTNOTIFICATION_DEREGISTER_TRACE, + &testPRM_POSTNOTIFICATION_SENT_TRACE, + &testPRM_CALLBACK_COMPLETION_TRACE, + &testPRM_MEMORY_USAGE_TRACE, + &testPRM_PSL_RESOURCE_GET_STATE_START_TRACE, + &testPRM_RESOURCE_GET_STATE_START_TRACE, + &testPRM_PSL_RESOURCE_GET_STATE_END_TRACE, + &testPRM_RESOURCE_GET_STATE_END_TRACE, + &testPRM_RESOURCE_CANCEL_LONGLATENCY_OPERATION_TRACE, + &testPRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE, + &testPRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE, + &testPRM_PSL_RESOURCE_CREATE_TRACE, + &testPRM_BOOTING_TRACE, + &testPRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE, + &testPRM_REGISTER_DYNAMIC_RESOURCE_TRACE, + &testPRM_DEREGISTER_DYNAMIC_RESOURCE_TRACE, + &testPRM_REGISTER_RESOURCE_DEPENDENCY_TRACE, + &testPRM_DEREGISTER_RESOURCE_DEPENDENCY_TRACE + }; + + TInt r = KErrNone; + + for(TUint i = 0; i < sizeof(TestArray)/sizeof(CTestTraceBase*); i++) + { + TestArray[i]->SkipHeader(); + test.Printf(_L("\n\nTest number %d\n\n"), i); + r = TestArray[i]->Compare(); + test(r==KErrNone); + } + + } + +void DoTests() + { + TInt r = KErrNone; + + test.Printf(_L("Loading logical device \n")); + r=User::LoadLogicalDevice(KLddFileName); + test(r == KErrNone); + + test.Printf(_L("Opening of logical device\n")); + r = ldd.Open(); + test(r == KErrNone); + + Trace.Open(); + TInt OrgBufSize = Trace.BufferSize(); + if(OrgBufSize<1024) + Trace.ResizeBuffer(1024); + + Trace.Empty(); + Trace.SetMode(RBTrace::EEnable); + + Trace.SetFilter(BTrace::EResourceManagerUs, ETrue); + Trace.SetFilter(BTrace::EResourceManager, ETrue); + + test.Printf(_L("Test Cat 19 is enabled")); + test(Trace.Filter(19)); + test.Printf(_L("Test Cat 20 is enabled")); + test(Trace.Filter(20)); + + test.Printf(_L("Send log\n")); + r = ldd.SendLog(&LogInfo); + test(r == KErrNone); + + Trace.GetData(BufferPtr); + + TestMacro(); + + Trace.DataUsed(); + + Trace.SetFilter(BTrace::EResourceManagerUs, EFalse); + Trace.SetFilter(BTrace::EResourceManager, EFalse); + + if(OrgBufSize<1024) + Trace.ResizeBuffer(1024); + + Trace.Close(); + + test.Printf(_L("\nClosing the channel\n")); + ldd.Close(); + + test.Printf(_L("Freeing logical device\n")); + r = User::FreeLogicalDevice(KLddFileName);; + test(r==KErrNone); + + + } + +GLDEF_C TInt E32Main() + { + test.Start(_L("T_RESMANUSBTRACE")); + console = test.Console(); + DoTests(); + test.End(); + test.Close(); + + return(KErrNone); + } diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/resmanus/t_resmanusbtrace.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/resmanus/t_resmanusbtrace.mmp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,31 @@ +// Copyright (c) 2010 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: +// e32test/t_resmanusbtrace.mmp +// +// + +TARGET t_resmanusbtrace.exe +TARGETTYPE EXE +SOURCEPATH . +SOURCE t_resmanusbtrace.cpp +LIBRARY euser.lib +OS_LAYER_SYSTEMINCLUDE_SYMBIAN +USERINCLUDE . + +library btracec.lib +capability all + +VENDORID 0x70000001 + +SMPSAFE diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/resourceman/d_rescontrolclisync.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/resourceman/d_rescontrolclisync.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,419 @@ +// Copyright (c) 2010 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: +// e32test\resourceman\d_rescontrolclisync.cpp +// +// + +#include +#include +#include +#include "d_rescontrolclisync.h" + +#include "resourceman_psl/rescontrol_psl.h" + +_LIT(KTestPowerRCName, "D_RESCONTROLCLISYNC.LDD"); + + +const TInt KTestResManLddThreadPriority = 0x5; +const TUint KResourceId = 16; // DMLSHLGLSPResource +const TInt KResourceMax = 65; +const TInt KResourceMin = 10; + +_LIT(KTestResManLddThread, "TestResManLddThread"); +_LIT(KTestResManLddHelperThread, "TestResManLddHelperThread"); +_LIT(KTestResManLddCallbackThread, "TestResManLddCallbackThread"); +_LIT(KResClientName1, "ResTestClient1"); +_LIT(KResClientName2, "ResTestClient2"); + +class DTestResManLdd; +/** +The logical device (factory class) for the resource manager client side test. +*/ +class DTestResManLddFactory : public DLogicalDevice + { +public: + enum { + ESignallerCallback, + EWaiterCallback + }; + DTestResManLddFactory(); + ~DTestResManLddFactory(); + virtual TInt Install(); + virtual void GetCaps(TDes8 &aDes) const; + virtual TInt Create(DLogicalChannelBase*& aChannel); + + NFastSemaphore iSemaphore1; // fast semaphore for helper queue + NFastSemaphore iSemaphore2; // fast semaphore for call back thread + + TInt iResourceClientRegisterCount; + TDynamicDfcQue* iLddQue; // dfc que for logical channel (also running the primary ChangeResourceState + TDynamicDfcQue* iLddHelperQue; // helper dfc que to execute the secondary ChangeResourceState + TDynamicDfcQue* iCallbackQue; // dfc que for call back + + DTestResManLdd* iChannel1; + DTestResManLdd* iChannel2; + TInt iCallbackState; + TPowerResourceCb* iAsyncResourceCallback; + }; + +/** Logical channel class for Resource manager test LDD */ +class DTestResManLdd : public DLogicalChannel + { +public: + DTestResManLdd(); + virtual ~DTestResManLdd(); + // Inherited from DLogicalChannel + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + virtual void HandleMsg(TMessageBase* aMsg); + + DThread* iClientThreadPtr; + TRequestStatus* iStatus; + TUint iResClientId; + TDfc* iWaitAndChangeResourceDfc; + +private: + TInt DoControl(TInt aFunction, TAny* a1, TAny* a2); + TInt DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2); + TInt DoCancel(TUint aMask); + }; + +void AsyncResourceCallbackFn(TUint /*aClientId*/, TUint /*aResourceId*/, TInt /*aLevel*/, TInt /*aLevelOwnerId*/, TInt aResult, TAny* aParam) + { + // call back function, always run on call back dfc queue + Kern::Printf(">AsyncResourceCallbackFn 0x%x", &(Kern::CurrentThread().iNThread)); + DTestResManLddFactory* pLddFactory = (DTestResManLddFactory*)aParam; + DTestResManLdd* pLdd = NULL; + + if(pLddFactory->iCallbackState == DTestResManLddFactory::ESignallerCallback) + { + pLdd = pLddFactory->iChannel1; + Kern::Printf("AsyncResourceCallbackFn cond 1 signal [#3.1]"); + NKern::FSSignal(&(pLddFactory->iSemaphore1)); + + Kern::Printf("AsyncResourceCallbackFn cond 1 wait [#3.2]"); + NKern::FSWait(&(pLddFactory->iSemaphore2)); + + Kern::Printf("AsyncResourceCallbackFn cond 1 wake up [#3.3]"); + } + else if(pLddFactory->iCallbackState == DTestResManLddFactory::EWaiterCallback) + { + pLdd = pLddFactory->iChannel2; + // aResult should be equal to KErrNone (not KErrCompletion) + Kern::Printf("AsyncResourceCallbackFn cond 2 r = %d [#2.5]", aResult); + } + else + { + Kern::Fault("AsyncResourceCallbackFn", __LINE__); + } + + Kern::RequestComplete(pLdd->iClientThreadPtr, pLdd->iStatus, aResult); + pLdd->iStatus = NULL; + Kern::Printf("WaitAndChangeResourceDfcFn 0x%x [#2.1]", &(Kern::CurrentThread().iNThread)); + DTestResManLdd* pLdd = (DTestResManLdd*)aLdd; + DTestResManLddFactory* pLddFactory = (DTestResManLddFactory*)(pLdd->iDevice); + + Kern::Printf(" WaitAndChangeResourceDfcFn - Wait for Semaphore [#2.2]"); + NKern::FSWait(&(pLddFactory->iSemaphore1)); + + Kern::Printf(" WaitAndChangeResourceDfcFn - ChangeResourceState [#2.3]"); + pLddFactory->iCallbackState = DTestResManLddFactory::EWaiterCallback; + PowerResourceManager::ChangeResourceState(pLdd->iResClientId, KResourceId, KResourceMax, pLddFactory->iAsyncResourceCallback); + + Kern::Printf(" WaitAndChangeResourceDfcFn - signal [#2.4]"); + NKern::FSSignal(&(pLddFactory->iSemaphore2)); + + delete pLdd->iWaitAndChangeResourceDfc; + Kern::Printf("Destroy(); + if(iLddHelperQue) + iLddHelperQue->Destroy(); + if(iCallbackQue) + iCallbackQue->Destroy(); + + if(iAsyncResourceCallback) + delete iAsyncResourceCallback; + } + +/** Entry point for this driver */ +DECLARE_STANDARD_LDD() + { + DTestResManLddFactory* p = new DTestResManLddFactory; + if(!p) + return NULL; + + TInt r = KErrNone; + + r = Kern::DynamicDfcQCreate(p->iLddQue, KTestResManLddThreadPriority, KTestResManLddThread); + if(r != KErrNone) + { + return NULL; + } + Kern::Printf("iLddQue 0x%x", p->iLddQue->iThread); + + r = Kern::DynamicDfcQCreate(p->iLddHelperQue, KTestResManLddThreadPriority, KTestResManLddHelperThread); + if(r != KErrNone) + { + p->iLddQue->Destroy(); + return NULL; + } + p->iSemaphore1.iOwningThread = (NThreadBase*)(p->iLddHelperQue->iThread); + Kern::Printf("iSemaphore1 owning thread 0x%x", p->iSemaphore1.iOwningThread); + + r = Kern::DynamicDfcQCreate(p->iCallbackQue, KTestResManLddThreadPriority, KTestResManLddCallbackThread); + if(r != KErrNone) + { + p->iLddQue->Destroy(); + p->iLddHelperQue->Destroy(); + return NULL; + } + p->iSemaphore2.iOwningThread = (NThreadBase*)(p->iCallbackQue->iThread); + Kern::Printf("iSemaphore2 owning thread 0x%x", p->iSemaphore2.iOwningThread); + + p->iAsyncResourceCallback = new TPowerResourceCb(AsyncResourceCallbackFn, p, + p->iCallbackQue, 5); + +#ifdef __SMP__ + NKern::ThreadSetCpuAffinity((NThread*)(p->iLddQue->iThread), 0); + NKern::ThreadSetCpuAffinity((NThread*)(p->iLddHelperQue->iThread), 0); + NKern::ThreadSetCpuAffinity((NThread*)(p->iCallbackQue->iThread), 1); +#endif + + r = DSimulatedPowerResourceController::CompleteResourceControllerInitialisation(); + if(r != KErrNone) + Kern::Fault("PRM INIT FAILED", __LINE__); + return p; + } + +/** Second stage constuctor */ +TInt DTestResManLddFactory::Install() + { + return(SetName(&KTestPowerRCName)); + } + +/** Device capabilities */ +void DTestResManLddFactory::GetCaps(TDes8& aDes)const + { + // Create a capabilities object + RTestResMan::TCaps caps; + caps.iVersion = iVersion; + // Write it back to user memory + Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps)); + } + + +TInt DTestResManLddFactory::Create(DLogicalChannelBase*& aChannel) + { + aChannel = new DTestResManLdd(); + if(!aChannel) + return KErrNoMemory; + if(!iChannel1) + iChannel1 = (DTestResManLdd*)aChannel; + else if(!iChannel2) + iChannel2 = (DTestResManLdd*)aChannel; + else + { + delete aChannel; + return KErrInUse; + } + return KErrNone; + } + +/** Constructor */ +DTestResManLdd::DTestResManLdd() + { + iClientThreadPtr=&Kern::CurrentThread(); + iResClientId = 0; + + // Increase the DThread's ref count so that it does not close without us + ((DObject*)iClientThreadPtr)->Open(); + } + +/** Destructor */ +DTestResManLdd::~DTestResManLdd() + { + Kern::SafeClose((DObject*&)iClientThreadPtr,NULL); + } + +/** Second stage constructor. */ +TInt DTestResManLdd::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer) + { + // Check version + if (!Kern::QueryVersionSupported(RTestResMan::VersionRequired(),aVer)) + return KErrNotSupported; + + SetDfcQ(((DTestResManLddFactory*)iDevice)->iLddQue); + iMsgQ.Receive(); + return KErrNone; + } + +/** Process a message for this logical channel */ +void DTestResManLdd::HandleMsg(TMessageBase* aMsg) + { + TThreadMessage& m=*(TThreadMessage*)aMsg; + TInt id=m.iValue; + + if (id==(TInt)ECloseMsg) + { + // Channel close. + m.Complete(KErrNone,EFalse); + return; + } + else if (id==KMaxTInt) + { + // DoCancel + m.Complete(KErrNone,ETrue); + return; + } + else if (id<0) + { + // DoRequest + TRequestStatus* pS=(TRequestStatus*)m.Ptr0(); + TInt r=DoRequest(~id,pS,m.Ptr1(),m.Ptr2()); + if (r!=KErrNone) + Kern::RequestComplete(iClientThreadPtr,pS,r); + m.Complete(KErrNone,ETrue); + } + else + { + // DoControl + TInt r=DoControl(id,m.Ptr0(),m.Ptr1()); + m.Complete(r,ETrue); + } + } + +/** + Process synchronous 'control' requests +*/ +TInt DTestResManLdd::DoControl(TInt aFunction, TAny* /*a1*/, TAny* /*a2*/) + { + TInt r = KErrNone; + + switch(aFunction) + { + case RTestResMan::ERegisterClient: + { + Kern::Printf("RTestResMan::ERegisterClient"); + if(iResClientId!=0) + { + r = KErrInUse; + break; + } + if(((DTestResManLddFactory*)iDevice)->iResourceClientRegisterCount==0) + { + r = PowerResourceManager::RegisterClient(iResClientId, KResClientName1); + } + else if(((DTestResManLddFactory*)iDevice)->iResourceClientRegisterCount==1) + { + r = PowerResourceManager::RegisterClient(iResClientId, KResClientName2); + } + else + r = KErrInUse; + + (((DTestResManLddFactory*)iDevice)->iResourceClientRegisterCount)++; + + break; + } + case RTestResMan::EDeRegisterClient: + { + Kern::Printf("RTestResMan::EDeRegisterClient"); + if(iResClientId==0) + { + r = KErrArgument; + break; + } + r = PowerResourceManager::DeRegisterClient(iResClientId); + break; + } + case RTestResMan::EPrintResourceInfo: + { + Kern::Printf("RTestResMan::EPrintResourceInfo"); + TPowerResourceInfoBuf01 info; + info.SetLength(0); + Kern::Printf("EPrintResourceInfo"); + r = PowerResourceManager::GetResourceInfo(iResClientId,KResourceId,&info); + Kern::Printf("EPrintResourceInfo:%S", info().iResourceName); + break; + } + default: + { + r = KErrNotSupported; + break; + } + } + return r; + + } + + +TInt DTestResManLdd::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* /*a1*/, TAny* /*a2*/) + { + TInt r = KErrNone; + + if(r != KErrNone) + Kern::RequestComplete(iClientThreadPtr, aStatus, r); + switch(aReqNo) + { + case RTestResMan::EWaitAndChangeResource: + // Queue a dfc which wait for the semaphore and then call ChangeResourceState + Kern::Printf("RTestResMan::EWaitAndChangeResource 0x%x [#1.1]", &(Kern::CurrentThread().iNThread)); + if(iStatus) + { + r = KErrInUse; + break; + } + iStatus = aStatus; + + iWaitAndChangeResourceDfc = new TDfc(WaitAndChangeResourceDfcFn, this, + ((DTestResManLddFactory*)iDevice)->iLddHelperQue, 5); + iWaitAndChangeResourceDfc->Enque(); + + break; + case RTestResMan::EChangeResourceAndSignal: + // call ChangeResourceState and signal the semaphore + Kern::Printf("RTestResMan::EChangeResourceAndSignal 0x%x [#1.2]", &(Kern::CurrentThread().iNThread)); + if(iStatus) + { + r = KErrInUse; + break; + } + iStatus = aStatus; + PowerResourceManager::ChangeResourceState(iResClientId, KResourceId, KResourceMin, + ((DTestResManLddFactory*)iDevice)->iAsyncResourceCallback); + ((DTestResManLddFactory*)iDevice)->iCallbackState = DTestResManLddFactory::ESignallerCallback; + + break; + default: + break; + } + return r; + } diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/resourceman/d_rescontrolclisync.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/resourceman/d_rescontrolclisync.h Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,101 @@ +// Copyright (c) 2010 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: +// e32test\resourceman\d_rescontrolclisync.h +// +// + +#ifndef __D_RESCONTROLCLISYNC_H__ +#define __D_RESCONTROLCLISYNC_H__ + +#include +#include +#ifndef __KERNEL_MODE__ +#include +#endif + +_LIT(KLddFileName, "D_RESCONTROLCLISYNC.LDD"); +_LIT(KLddName, "D_RESCONTROLCLISYNC.LDD"); +_LIT(KPddFileName, "resourcecontroller.pdd"); +_LIT(KPddName, "resourcecontroller.pdd"); + + +/** User side logical channel */ +class RTestResMan : public RBusLogicalChannel + { +public: + // Structure for holding driver capabilities information + class TCaps + { + public: + TVersion iVersion; + }; + +private: + enum TControl //Request types for synchronous operation. + { + ERegisterClient, + EDeRegisterClient, + EPrintResourceInfo, + ERegisterNotification, + EDeRegisterNotification, + EMaxControl, + + }; + enum TRequest //Request types for asynchronous operation + { + EWaitAndChangeResource = EMaxControl + 1, + EChangeResourceAndSignal, + EMaxRequest, + }; + friend class DTestResManLdd; +public: + TInt Open(); + TInt PrintResourceInfo() + {return DoControl(EPrintResourceInfo);} + TInt RegisterClient() + {return DoControl(ERegisterClient);} + TInt DeRegisterClient() + {return DoControl(EDeRegisterClient);} + TInt RegisterNotification() + {return DoControl(ERegisterNotification);} + TInt DeRegisterNotification() + {return DoControl(EDeRegisterNotification);} + void WaitAndChangeResource(TRequestStatus& aStatus) + {DoRequest(EWaitAndChangeResource, aStatus);} + void ChangeResourceAndSignal(TRequestStatus& aStatus) + {DoRequest(EChangeResourceAndSignal, aStatus);} + + inline static TVersion VersionRequired(); + + }; + +inline TVersion RTestResMan::VersionRequired() + { + const TInt KMajorVersionNumber=1; + const TInt KMinorVersionNumber=0; + const TInt KBuildVersionNumber=KE32BuildVersionNumber; + return TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); + } + +#ifndef __KERNEL_MODE__ + +/** Open a channel for the driver.*/ +TInt RTestResMan::Open() + { + return DoCreate(KLddName, VersionRequired(), KNullUnit, &KPddName, NULL, EOwnerProcess, EFalse); + } + + +#endif //__KERNEL_MODE__ +#endif //__D_RESCONTROLCLISYNC_H__ diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/resourceman/t_rescontrolclisync.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/resourceman/t_rescontrolclisync.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -0,0 +1,120 @@ +// Copyright (c) 2010 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: +// e32test\resourceman\t_rescontrolclisync.cpp +// TestCase Description: +// This test harness is to test the unsafe setup of power request call back object +// inside resourcecontrol.cpp. The memeber variable of TPowerRequestCb should not +// be corrupted when a second ChangeResourceState is execute during the call back +// function is running. +// +// + +#include +#include +#include +#include +#include +#include "d_rescontrolclisync.h" + + + +LOCAL_D RTest test(_L("T_RESCONTROLCLISYNC")); +RTestResMan lddChan; +RTestResMan lddChan2; + +#define TESTANDCLEAN(x) TestAndClean(x,__LINE__) + +void TestAndClean(TBool aTestValid, TInt aLine) + { + if(!aTestValid) + { + lddChan.DeRegisterClient(); + lddChan2.DeRegisterClient(); + lddChan.Close(); + lddChan2.Close(); + User::FreeLogicalDevice(KLddFileName); + User::FreePhysicalDevice(KPddFileName); + RDebug::Printf("Test fail at line %d", aLine); + test.HandleError(EFalse, aLine, (TText *)__FILE__); + } + } + +GLDEF_C TInt E32Main() + { + test.Title(); + test.Start(_L("Testing Resource Manager...\n")); + + test.Next(_L("Load Physical device")); + TInt r = User::LoadPhysicalDevice(KPddFileName); + test(r==KErrNone || r==KErrAlreadyExists); + test.Next(_L("Load Logical Device")); + r=User::LoadLogicalDevice(KLddFileName); + test(r==KErrNone || r==KErrAlreadyExists); + test.Next(_L("Open Logical Channel 1")); + r = lddChan.Open(); + test(r==KErrNone); + test.Next(_L("Open Logical Channel 2")); + r = lddChan2.Open(); + test(r==KErrNone); + + test.Next(_L("Register client 1")); + r = lddChan.RegisterClient(); + RDebug::Printf("Register client 1 return r = %d", r); + TESTANDCLEAN(r==KErrNone); + + test.Next(_L("Register client 2")); + r = lddChan2.RegisterClient(); + RDebug::Printf("Register client 2 return r = %d", r); + TESTANDCLEAN(r==KErrNone); + + test.Next(_L("Print resource info")); + r = lddChan.PrintResourceInfo(); + RDebug::Printf("Print resource info return r = %d", r); + TESTANDCLEAN(r==KErrNone); + + TRequestStatus RequestStatus; + TRequestStatus RequestStatus2; + + test.Next(_L("WaitAndChangeResource")); + lddChan.WaitAndChangeResource(RequestStatus); + + test.Next(_L("ChangeResourceAndSignal")); + lddChan2.ChangeResourceAndSignal(RequestStatus2); + + User::WaitForRequest(RequestStatus); + TESTANDCLEAN(RequestStatus.Int()==KErrNone); + User::WaitForRequest(RequestStatus2); + TESTANDCLEAN(RequestStatus2.Int()==KErrNone); + + test.Next(_L("De-register client 1")); + r = lddChan.DeRegisterClient(); + test(r==KErrNone); + + test.Next(_L("De-register client 2")); + r = lddChan2.DeRegisterClient(); + test(r==KErrNone); + + test.Printf(_L("Closing the channel\n")); + lddChan.Close(); + lddChan2.Close(); + test.Printf(_L("Freeing logical device\n")); + r = User::FreeLogicalDevice(KLddFileName); + test(r==KErrNone); + r = User::FreePhysicalDevice(KPddFileName); + test(r==KErrNone); + test.End(); + test.Close(); + return KErrNone; + } + diff -r a5496987b1da -r 189ece41fa29 kerneltest/e32test/window/t_keys.cpp --- a/kerneltest/e32test/window/t_keys.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/e32test/window/t_keys.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -1,4 +1,4 @@ -// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 1996-2010 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" @@ -14,10 +14,11 @@ // e32test\window\t_keys.cpp // // - +#define __E32TEST_EXTENSION__ #include #include #include +#include #include const TBool KEY_UP=ETrue; @@ -25,6 +26,8 @@ const TBool EXPECT_NO_KEY_PRESS=EFalse; const TBool EXPECT_KEY_PRESS=ETrue; +_LIT(REFKDATA, "REFKDATA"); + LOCAL_D RTest test(_L("T_KEYS")); LOCAL_D CKeyTranslator *KeyTranslator; LOCAL_D CCaptureKeys *CaptureKeys; @@ -135,7 +138,73 @@ CaptureKeys->Construct(); + + test.Printf(_L("Load template EKData dll \n")); // Test with rfkdata.dll + TInt res=KeyTranslator->ChangeKeyData(REFKDATA); + test_KErrNone(res); + + /* Test the AddCapture failure case */ + TCaptureKey ck; + ck.iModifiers.iMask = 11; + ck.iModifiers.iValue = 100; + ck.iKeyCodePattern.iKeyCode = EKeyNull; + ck.iKeyCodePattern.iPattern = EAnyKey; + ck.iApp = 111; + ck.iHandle = 123; + + TInt r = KErrNone; + TRAP(r, CaptureKeys->AddCaptureKeyL(ck)); + test_Equal(r, KErrArgument); + + /* Test the AddCapture success case */ + ck.iModifiers.iMask = 11; + ck.iModifiers.iValue = 1; + + TRAP(r, CaptureKeys->AddCaptureKeyL(ck)); + test_KErrNone(r); + + /* Test the SetCapture case */ + TCaptureKey replaceck; + replaceck.iModifiers.iMask = 0; + replaceck.iModifiers.iValue = 0; + replaceck.iKeyCodePattern.iKeyCode = EKeyNull; + replaceck.iKeyCodePattern.iPattern = EAnyKey; + replaceck.iApp = 222; + replaceck.iHandle = 456; + + /* Test the SetCapture failure case */ + CaptureKeys->SetCaptureKey(replaceck.iHandle, ck); + + /* Test the SetCapture success case */ + CaptureKeys->SetCaptureKey(ck.iHandle, replaceck, 0x80); + + /* Test the Cancelcapture failure case */ + CaptureKeys->CancelCaptureKey(ck.iHandle); + + /* Let us add one more with a different set of mask to test ProcessCaptureKeys */ + ck.iModifiers.iMask = 11; + ck.iModifiers.iValue = 1; + ck.iKeyCodePattern.iKeyCode = EKeyNull; + ck.iKeyCodePattern.iPattern = EMatchLeftOrRight+1; + ck.iApp = 111; + ck.iHandle = 123; + + TRAP(r, CaptureKeys->AddCaptureKeyL(ck)); + test_KErrNone(r); + + /* Let us add one more with a different set of mask to test ProcessCaptureKeys */ + ck.iModifiers.iMask = 11; + ck.iModifiers.iValue = 1; + ck.iKeyCodePattern.iKeyCode = EKeyNull; + ck.iKeyCodePattern.iPattern = EAnyKey; + ck.iApp = 333; + ck.iHandle = 789; + + TRAP(r, CaptureKeys->AddCaptureKeyL(ck)); + test_KErrNone(r); + TUint scancode=EStdKeyLeftArrow; + // // Test that the special keys pass through and anything after // or before raises an error @@ -259,6 +328,29 @@ testAccents('6','E',0xea); */ + + /* Test the CancelAllCaptureKeys failure case */ + CaptureKeys->CancelAllCaptureKeys(ck.iApp); + + /* Test the CancelCaptureKey success case */ + CaptureKeys->CancelCaptureKey(replaceck.iHandle); + + /* Now add a CaptureKey to test CancelAllCaptureKeys success case */ + ck.iModifiers.iMask = 11; + ck.iModifiers.iValue = 1; + ck.iKeyCodePattern.iKeyCode = EKeyNull; + ck.iKeyCodePattern.iPattern = EAnyKey; + ck.iApp = 111; + ck.iHandle = 123; + + TRAP(r, CaptureKeys->AddCaptureKeyL(ck)); + test_KErrNone(r); + + /* Test CancelAllCaptureKeys success case */ + CaptureKeys->CancelAllCaptureKeys(ck.iApp); + + delete CaptureKeys; + test.End(); return(KErrNone); } diff -r a5496987b1da -r 189ece41fa29 kerneltest/f32test/filesystem/fat/t_mount.cpp --- a/kerneltest/f32test/filesystem/fat/t_mount.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/f32test/filesystem/fat/t_mount.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -629,12 +629,12 @@ bDriveFinalised = DoCheckVolumeFinalised(gDriveNum); test(!bDriveFinalised); //-- the volume has become "unfinalised" - //-- 2.1 open a file, try to finalise; Shall dail with KErrInUse + //-- 2.1 open a file, try to finalise; This should be OK nRes = file.Replace(TheFs, KFileName, EFileWrite | EFileRead); test_KErrNone(nRes); nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); - test(nRes==KErrInUse); //-- can't finalise drives with opened objects + test_KErrNone(nRes); file.Close(); @@ -1274,7 +1274,6 @@ PrintDrvInfo(TheFs, gDriveNum); InitGlobals(); - TestNotifyDiskSpace(); //------------------------------------- diff -r a5496987b1da -r 189ece41fa29 kerneltest/f32test/server/t_misc.cpp --- a/kerneltest/f32test/server/t_misc.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/f32test/server/t_misc.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -20,6 +20,10 @@ #include #include "t_server.h" +#include "f32_test_utils.h" +using namespace F32_Test_Utils; + + // If there is an NFE media driver present, then because of the way EDeleteNotify requests work, // the data retrieved from a deleted file will not be a buffer full of zero's, but instead a buffer // full of decrypted zero's @@ -30,11 +34,13 @@ #pragma setlocale("english") #endif -GLDEF_D RTest test(_L("T_MISC")); +RTest test(_L("T_MISC")); + +TInt gDriveNum = -1; const TUint KBufLength = 0x100; -LOCAL_C void Test1() +static void Test1() // // Open, write to and read from a file // @@ -59,7 +65,7 @@ file.Close(); } -LOCAL_C void Test2() +static void Test2() // // Open and read from a file // @@ -80,7 +86,7 @@ test_KErrNone(r); } -LOCAL_C void Test3() +static void Test3() // // Create nested directories // @@ -109,7 +115,7 @@ test_Value(r, r == KErrNone || r==KErrAlreadyExists); } -LOCAL_C void Test4() +static void Test4() // // Test returned error values // @@ -172,7 +178,7 @@ dir.Close(); } -LOCAL_C void Test5() +static void Test5() // // Read files directly from the rom // @@ -270,7 +276,7 @@ } } -LOCAL_C void Test6() +static void Test6() // // Test rom return values // @@ -289,7 +295,7 @@ test_Value(r, r == KErrAccessDenied); } -LOCAL_C void Test7() +static void Test7() // // Test cache // @@ -327,7 +333,7 @@ test(entry.iType==uid2); } -LOCAL_C void Test8() +static void Test8() // // Test IsValidName // @@ -536,7 +542,7 @@ } } -LOCAL_C void Test9() +static void Test9() // // Test IsFileInRom // @@ -563,7 +569,7 @@ } } -LOCAL_C void Test10() +static void Test10() // // Test drive names // @@ -660,7 +666,7 @@ } -LOCAL_C void Test11() +static void Test11() // // Miscellaneous tests // @@ -677,7 +683,7 @@ test_Value(r, r == KErrBadName); } -LOCAL_C void Test12() +static void Test12() // // Test SetNotifyUser and GetNotifyUser // @@ -696,7 +702,7 @@ test(notifyState); } -LOCAL_C void Test13() +static void Test13() // // Test return values from RFs::Volume on cf-cards // @@ -728,84 +734,37 @@ void DoTest14(TInt aDrvNum); TInt CreateStuffedFile(RFs& aFs, const TDesC& aFileName, TUint aFileSize); -TInt CreateEmptyFile(RFs& aFs, const TDesC& aFileName, TUint aFileSize); TBool CheckFileContents(RFs& aFs, const TDesC& aFileName); #ifndef __NFE_MEDIA_DRIVER_PRESENT__ TBool CheckBufferContents(const TDesC8& aBuffer, TUint aPrintBaseAddr=0); #endif /** -Testing unallocated data initialization vulnerability in RFile -This test is performed on RAM drives and non-removable media that supports DeleteNotify (KMediaAttDeleteNotify flag) -e.g. XSR NAND + Testing unallocated data initialization vulnerability in RFile + This test is performed on RAM drives and non-removable media that supports DeleteNotify (KMediaAttDeleteNotify flag) + e.g. XSR NAND */ -LOCAL_C void Test14() +static void Test14() { - TInt nRes; test.Next(_L("Testing unallocated data initialization vulnerability in RFile")); - TDriveList driveList; - TDriveInfo driveInfo; - - //-- 1. get drives list - nRes=TheFs.DriveList(driveList); - test_KErrNone(nRes); - - //-- 2. walk through all drives, performing the test only on suitable ones - for (TInt drvNum=0; drvNum boolPckg; + + //-- 1. get "Finalised" state by using the API + nRes = TheFs.QueryVolumeInfoExt(aDriveNo, EIsDriveFinalised, boolPckg); + test_KErrNone(nRes); + + return boolPckg(); +} + + +//-------------------------------------------------------- +/** + This is a file system - agnostic test that verifies RFs::FinaliseDrive() API + There are also file system - specific tests that check similar functionallity (see t_mount for example) + +*/ +void TestDriveFinalisation() +{ + test.Next(_L("TestDriveFinalisation(). Testing RFs::FinaliseDrives() API\n")); + + + if((!Is_Fat(TheFs, gDriveNum) && !Is_ExFat(TheFs, gDriveNum)) || Is_Fat12(TheFs, gDriveNum) ) + { + test.Printf(_L("This test can't be performed on current file system, skipping.\n")); + return; + } + + TVolumeInfo v; + TInt nRes; + + nRes = TheFs.Volume(v); + test(nRes==KErrNone); + + if(v.iDrive.iMediaAtt & KMediaAttVariableSize) + { + test.Printf(_L("Skipping. RAM drive not tested.\n")); + return; + } + + + TBool bDriveFinalised; + + //============= 1. finalise the drive (RW mode) and check the result + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + //-- 1.1 finalise the drive second time EFinal_RW -> EFinal_RW shall work + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + //============= 2. create a file. Shall succeed (EFinal_RW), the volume shall become unfinalised + + RFile file; + _LIT(KFileName, "\\my_file1.dat"); + _LIT8(KSomeData, "this is some data"); + + nRes = CreateEmptyFile(TheFs, KFileName, 128000); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(!bDriveFinalised); //-- the volume has become "unfinalised" + + //---------------------------------------------------------------------------------- + //-- test volume finalisation with opened objects + + //-- 2.1 having opened files should be OK for volume finalisation + + //-- 2.1.1 RW finalisation; after the volume finalised it should be possible to write to the opened file + nRes = file.Open(TheFs, KFileName, EFileWrite | EFileWriteDirectIO); + test_KErrNone(nRes); + + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + nRes = file.Write(0, KSomeData); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(!bDriveFinalised); //-- the volume should become "unfinalised" + + //-- 2.1.2 RO finalisation; after the volume finalised it shouldn't be possible to write to the opened file + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + nRes = file.Write(0, KSomeData); + test(nRes == KErrAccessDenied); //-- no write access to the volume + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); //-- the volume should become "unfinalised" + + file.Close(); + + //-- remount FS, the drive shall become RW + nRes = RemountFS(TheFs, gDriveNum); + test_KErrNone(nRes); + + + //-- 2.2 having opened directories should be OK for volume finalisation + _LIT(KDirName, "\\Dir11235tt\\"); + MakeDir(KDirName); + RDir dir; + + //-- 2.2.1 RW finalisation; after the volume finalised it should be possible to have write access to it + nRes = dir.Open(TheFs, KDirName, KEntryAttNormal); + test_KErrNone(nRes); + + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + nRes = CreateEmptyFile(TheFs, KFileName, 128000); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(!bDriveFinalised); + + //-- 2.1.2 RO finalisation; after the volume finalised it shouldn't be possible to write to it + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + nRes = CreateEmptyFile(TheFs, KFileName, 128000); + test(nRes == KErrAccessDenied); //-- no write access to the volume + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); //-- the volume should become "unfinalised" + + dir.Close(); + + //-- remount FS, the drive shall become RW + nRes = RemountFS(TheFs, gDriveNum); + test_KErrNone(nRes); + + //-- 2.3 having opened disk access objects, like formats or raw disks makes finalisation impossible + RFormat format; + RRawDisk rawDisk; + TInt fmtCnt; + + //-- 2.3.1 format + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); + test_KErrNone(nRes); + + nRes = format.Open(TheFs, gSessionPath, EFullFormat, fmtCnt); + test_KErrNone(nRes); + + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); + test(nRes == KErrInUse); + + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); + test(nRes == KErrInUse); + + format.Close(); + + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); + test_KErrNone(nRes); + + //-- 2.3.2 raw disk + nRes = rawDisk.Open(TheFs, gDriveNum); + test_KErrNone(nRes); + + + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); + test(nRes == KErrInUse); + + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); + test(nRes == KErrInUse); + + rawDisk.Close(); + + //-- 2.4 Volume finalisation and file system dismounting + + //-- 2.4.1 "graceful" dismounting should finalise the drive correctly + + //-- "unfinalise the volume" + nRes = CreateEmptyFile(TheFs, KFileName, 128000); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(!bDriveFinalised); + + TFSDescriptor fsDesc; + nRes = GetFileSystemDescriptor(TheFs, gDriveNum, fsDesc); + test_KErrNone(nRes); + + //-- gracefully dismount the file system + nRes = TheFs.DismountFileSystem(fsDesc.iFsName, gDriveNum); + test_KErrNone(nRes); + + //-- mount it back + nRes = MountFileSystem(TheFs, gDriveNum, fsDesc); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + //-- 2.4.2 "forced" dismounting, usually happens when "graceful doesn't work, because there are files opened on the volume. + //-- Should also finalise the drive correctly + + //-- "unfinalise the volume" + nRes = CreateEmptyFile(TheFs, KFileName, 128000); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(!bDriveFinalised); + + //-- open a file on the volume, this will prevent graceful dismounting + nRes = file.Open(TheFs, KFileName, EFileWrite | EFileWriteDirectIO); + test_KErrNone(nRes); + + nRes = GetFileSystemDescriptor(TheFs, gDriveNum, fsDesc); + test_KErrNone(nRes); + + //-- try gracefully dismount the file system + nRes = TheFs.DismountFileSystem(fsDesc.iFsName, gDriveNum); + test(nRes == KErrInUse); //-- no luck, as expected + + //-- now do dismounting by force + TRequestStatus rqStat; + TheFs.NotifyDismount(gDriveNum, rqStat, EFsDismountForceDismount); + User::WaitForRequest(rqStat); + test_KErrNone(rqStat.Int()); + + nRes = file.Write(0, KSomeData); + test(nRes == KErrNotReady); + + file.Close(); + + //-- mount it back + nRes = MountFileSystem(TheFs, gDriveNum, fsDesc); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + //============= 3. test "unfinalise API" + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EForceUnfinalise); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(!bDriveFinalised); //-- the volume has become "unfinalised" + + //============= 4. test finalisation into RO mode + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); //-- the volume becomes RO + test_KErrNone(nRes); + + //-- try to write a file on RO volume; it shall fail with KErrAccessDenied + nRes = CreateEmptyFile(TheFs, KFileName, 128000); + test(nRes == KErrAccessDenied); + file.Close(); + + //-- 4.1 try to finalise into EFinal_RW mode, shall fail with KErrAccessDenied + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); + test(nRes == KErrAccessDenied); + + //-- 4.2 "unfinalise" the volume, it still shall remain RO + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EForceUnfinalise); + test_KErrNone(nRes); + + //-- try to write a file on RO volume; it shall fail with KErrAccessDenied + nRes = CreateEmptyFile(TheFs, KFileName, 128000); + test(nRes == KErrAccessDenied); + file.Close(); + + //-- remount FS, the drive shall become RW + nRes = RemountFS(TheFs, gDriveNum); + test_KErrNone(nRes); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + //-- try to write a file on RW volume, shall be OK + nRes = CreateEmptyFile(TheFs, KFileName, 128000); + test(nRes == KErrNone); + file.Close(); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(!bDriveFinalised); + + //============= 5. test various finalisation modes + + //-- 5.1 Not finalised -> EFinal_RW (KErrNone) + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); + test(nRes == KErrNone); + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + //-- 5.2 EFinal_RW -> EFinal_RO (KErrNone) + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); + test(nRes == KErrNone); + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + //-- 5.2 EFinal_RO -> EFinal_RW (KErrAccessDenied) + nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); + test(nRes == KErrAccessDenied); + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + //-- 5.3 restore + nRes = RemountFS(TheFs, gDriveNum); + test_KErrNone(nRes); + + + //============= 6. test old RFs::FinaliseDrives API + + nRes = CreateEmptyFile(TheFs, KFileName, 128000); + test(nRes == KErrNone); + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(!bDriveFinalised); + + TheFs.FinaliseDrives(); //-- shall work as TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW) but for ALL drives + + bDriveFinalised = IsVolumeFinalised(gDriveNum); + test(bDriveFinalised); + + nRes = CreateEmptyFile(TheFs, KFileName, 128000); + test(nRes == KErrNone); + + + +} + + +void CallTestsL() { + //-- set up console output + F32_Test_Utils::SetConsole(test.Console()); + TInt nRes=TheFs.CharToDrive(gDriveToTest, gDriveNum); + test_KErrNone(nRes); + + PrintDrvInfo(TheFs, gDriveNum); + + TestDriveFinalisation(); Test1(); Test2(); Test3(); @@ -1418,4 +1706,5 @@ Test14(); Test15(); TestGetMediaSerialNumber(); + } diff -r a5496987b1da -r 189ece41fa29 kerneltest/f32test/server/t_proxydrive1.cpp --- a/kerneltest/f32test/server/t_proxydrive1.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/kerneltest/f32test/server/t_proxydrive1.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -24,7 +24,7 @@ using namespace F32_Test_Utils; -GLDEF_D RTest test(_L("T_PROXYDRIVE1")); +RTest test(_L("T_PROXYDRIVE1")); TInt GetRemovableDrive(TInt aDriveNumber) @@ -81,7 +81,7 @@ -GLDEF_C void CallTestsL() +void CallTestsL() { TInt drive; TInt err=RFs::CharToDrive(gDriveToTest,drive); @@ -96,7 +96,7 @@ TInt r; - TInt localDriveNumber = GetRemovableDrive(drive); + TInt localDriveNumber = GetRemovableDrive(drive); //-- local _physical_ drive number if (localDriveNumber < 0) { test.Printf(_L("Not a removable drive, skipping test\n")); @@ -113,16 +113,25 @@ TBuf<1> p2; TInt driveNumber = EDriveM; + //-- this is a hack - mount the proxy drive to the existing one with alive file system just to check + //-- that it works. + r = TheFs.MountProxyDrive(driveNumber, KBitProxyDrive, &p1, &p2); test.Printf(_L("MountProxyDrive(%d, %S) r %d\n"), driveNumber, &KBitProxyDrive, r); test (r >= 0); - _LIT(KFileSystem, "FAT"); - r = TheFs.MountFileSystem(KFileSystem, driveNumber); - test.Printf(_L("MountFileSystem(%S) r %d\n"), &KFileSystem, r); + //-- query existing file system name on the drive that we are be parasiting on. + TFSName fsName; + r = TheFs.FileSystemName(fsName, drive); + test(r == KErrNone); + + + r = TheFs.MountFileSystem(fsName, driveNumber); + test.Printf(_L("MountFileSystem(%S) r %d\n"), &fsName, r); test(r == KErrNone); + RFs fs; r = fs.Connect(); test(r == KErrNone); @@ -135,8 +144,8 @@ test.Printf(_L("RDir::Open(%S) r %d\n"), &dirPath, r); - r = TheFs.DismountFileSystem(KFileSystem, driveNumber); - test.Printf(_L("DismountFileSystem(%S) r %d\n"), &KFileSystem, r); + r = TheFs.DismountFileSystem(fsName, driveNumber); + test.Printf(_L("DismountFileSystem(%S) r %d\n"), &fsName, r); test (r == KErrInUse); // dismount failed - attempt a forced dismount @@ -144,7 +153,7 @@ TheFs.NotifyDismount(driveNumber, stat, EFsDismountForceDismount); User::WaitForRequest(stat); r = stat.Int(); - test.Printf(_L("DismountFileSystem(%S, EFsDismountForceDismount) r %d\n"), &KFileSystem, r); + test.Printf(_L("DismountFileSystem(%S, EFsDismountForceDismount) r %d\n"), &fsName, r); test (r == KErrNone); r = TheFs.DismountProxyDrive(driveNumber); diff -r a5496987b1da -r 189ece41fa29 package_definition.xml --- a/package_definition.xml Thu Jul 01 17:57:33 2010 +0100 +++ b/package_definition.xml Fri Jul 09 13:13:20 2010 +0100 @@ -50,9 +50,6 @@ - - - diff -r a5496987b1da -r 189ece41fa29 userlibandfileserver/fileserver/group/release.txt --- a/userlibandfileserver/fileserver/group/release.txt Thu Jul 01 17:57:33 2010 +0100 +++ b/userlibandfileserver/fileserver/group/release.txt Fri Jul 09 13:13:20 2010 +0100 @@ -1,3 +1,11 @@ +Version 2.00.3052 +================= +(Made by famustaf 01/07/2010) + +1. dlyokhin + 1. ou1cimx1#424702 FAT, exFAT should allow volume finalisation even if it has opened files or directories + + Version 2.00.3051 ================= (Made by vfebvre 21/06/2010) diff -r a5496987b1da -r 189ece41fa29 userlibandfileserver/fileserver/inc/f32fsys.inl --- a/userlibandfileserver/fileserver/inc/f32fsys.inl Thu Jul 01 17:57:33 2010 +0100 +++ b/userlibandfileserver/fileserver/inc/f32fsys.inl Fri Jul 09 13:13:20 2010 +0100 @@ -270,53 +270,48 @@ __IS_DRIVETHREAD(); iDriveFlags |= ENotifyOff; } + /** - Locks the drive.This function acquires iLock mutex. - */ inline void TDrive::Lock() {iLock.Wait();} + /** - UnLocks the drive.This function signals the iLock mutex. - */ - inline void TDrive::UnLock() {iLock.Signal();} /** - -Gets the reserved space of a drive - @return Amount of space reserved in bytes. - */ - inline TInt TDrive::ReservedSpace() const - {return iReservedSpace;} + { + return iReservedSpace; + } /** - -Reserves a space of a drive. + Reserves space on a drive. The amount of 'reserved space' is subtracted + from the amount of available free space on the volume reported by file system, when the user + queries it. -@param aReservedSpace Amount of space to reserve in bytes. - + @param aReservedSpace Amount of space to reserve in bytes. */ inline void TDrive::SetReservedSpace(const TInt aReservedSpace) - {iReservedSpace=aReservedSpace; } + { + iReservedSpace=aReservedSpace; + } /** - -Sets the rugged flag in the drive object. + Sets the 'rugged mode' flag in the drive object. The file system associated with this TDrive object + can use this flag for changing its behaviour. + For example, FAT file system if this flag is set, operates in 'Rugged FAT' mode, when the performance is + sacrificed for the sake of reliability. -@param Flag to set or clear the rugged flag. -@see IsRugged() - + @param aIsRugged the 'rugged mode' flag. */ - inline void TDrive::SetRugged(TBool aIsRugged) { if (!aIsRugged) @@ -326,17 +321,13 @@ } /** - -Returns whether the current drive is running as rugged Fat -or not.If IsRugged flag is set then in the event of power -failure fat/metadata will be in a valid state if the scandrive -utility is run immediately after. - -@return Is rugged fat flag. + @return 'Is rugged' flag. + See TDrive::SetRugged() */ - inline TBool TDrive::IsRugged() const - {return !(iDriveFlags & ENotRugged); } + { + return !(iDriveFlags & ENotRugged); + } /** @@ -451,64 +442,69 @@ {Drive().SetNotifyOff();} +//--------------------------------------------------------------------------------------------------------------------------------- +/** + + Increment mount's lock counter. This happens on following events: + - RemoveResource() call, when file (share) or directory is closed + - AddDiskAccess() call, when disk access object (like Format or RawDisk access) is opened on the mount. + + See also: CMountCB::LockStatus() +*/ +inline void CMountCB::IncLock() + { + iLockMount++; + } + + +//--------------------------------------------------------------------------------------------------------------------------------- /** -Locks the mount by incrementing the internal lock counter. + Decrement mount's lock counter. This happens on following events: + + AddResource() call when file (share) or directory is opened on the mount + RemoveDiskAccess() call when disk access object (like Format or RawDisk access) is closed. + + See also: CMountCB::LockStatus() +*/ +inline void CMountCB::DecLock() + { + iLockMount--; + } -The mount becomes locked on formatting or on the opening of a resource -(a file or a directory) or raw disk subsession. -A format, resource or raw disk subsession can only be opened if the mount -is not locked. +//--------------------------------------------------------------------------------------------------------------------------------- + +/** + @return value of the Mount's lock counter value. + + The meaning of 'iLockMount' is overloaded a bit, it's value is: + 0 when there are no files, directories, formats and any other objects opened on the mount + >0 when there are disk access objects opened (raw disk access or format) + <0 when there are files or directories opened on the mount, and the value reflects their total number */ -inline void CMountCB::IncLock() - {iLockMount++;} - +inline TInt CMountCB::LockStatus() const + { + return iLockMount; + } -/** -Unlocks the mount by decrementing the internal lock counter. - -The mount becomes locked on formatting or on the opening of a resource -(a file or a directory) or raw disk subsession. -A format, resource or raw disk subsession can only be opened if the mount -is not locked. -*/ -inline void CMountCB::DecLock() - {iLockMount--;} - - - - -/** -Gets the current lock status. - -It delivers the current lock status by returning the internal lock counter. - -@return The current lock status. -*/ -inline TInt CMountCB::LockStatus() const - {return(iLockMount);} - - - - +//--------------------------------------------------------------------------------------------------------------------------------- /** Tests whether the mount is currently locked. A mount is locked when the internal lock counter is greater than zero. -On creation, the lock counter is set to zero. + This happens when a format, resource or raw disk subsession is opened on the mount. -The mount becomes locked on formatting or on the opening of a resource -(a file or a directory) or raw disk subsession. -A format, resource or raw disk subsession can only be opened if the mount -is not locked. + See also: CMountCB::LockStatus() -@return True if the mount is locked, false, otherwise. + @return True if the mount is locked by having disk access objects opened */ inline TBool CMountCB::Locked() const - {return iLockMount>0; } + { + return iLockMount > 0; + } @@ -537,7 +533,9 @@ /** */ inline TInt64 CMountCB::Size() const - {return(iSize);} + { + return iSize; + } @@ -547,14 +545,19 @@ @param aMountNumber - The unique mount number */ const TInt KMountDismounted = 0x80000000; + inline void CMountCB::SetMountNumber(TInt aMountNumber) - { iMountNumber = (aMountNumber &~ KMountDismounted); } + { + iMountNumber = (aMountNumber & ~KMountDismounted); + } /** -Set the mount to be dismounted + Set the mount flag indicating that it is in 'dismounted' state. + The CMountCB object in this case is still alive, but any attempts to access resources on this + mount result in KErrDismounted. */ inline void CMountCB::SetDismounted(TBool aDismounted) { @@ -568,21 +571,23 @@ /** -Returns the unique mount number @return The unique mount number */ inline TInt CMountCB::MountNumber() const - { return(iMountNumber &~ KMountDismounted); } + { + return(iMountNumber &~ KMountDismounted); + } /** -Returns ETrue if the mount is flagged as dismounted. @return ETrue if the mount is flagged as dismounted */ inline TBool CMountCB::IsDismounted() const - { return(iMountNumber & KMountDismounted); } + { + return(iMountNumber & KMountDismounted); + } diff -r a5496987b1da -r 189ece41fa29 userlibandfileserver/fileserver/inc/f32ver.h --- a/userlibandfileserver/fileserver/inc/f32ver.h Thu Jul 01 17:57:33 2010 +0100 +++ b/userlibandfileserver/fileserver/inc/f32ver.h Fri Jul 09 13:13:20 2010 +0100 @@ -58,6 +58,6 @@ @see TVersion */ -const TInt KF32BuildVersionNumber=3051; +const TInt KF32BuildVersionNumber=3052; // #endif diff -r a5496987b1da -r 189ece41fa29 userlibandfileserver/fileserver/sfat32/sl_mnt.cpp --- a/userlibandfileserver/fileserver/sfat32/sl_mnt.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/userlibandfileserver/fileserver/sfat32/sl_mnt.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -551,10 +551,8 @@ return; } - if(LockStatus() != 0) - {//-- can't finalise the volume if it has opened objects and not in the consistent state. - //-- Theoretically, we can finalise the mount if we have files opened only for read, but at present, - //-- it's impossible to detect such situation. + if(Locked()) + {//-- can't finalise the volume if it has opened disk access objects, like Format or RawAccess User::Leave(KErrInUse); } @@ -4295,7 +4293,7 @@ TInt nRes; if(LockStatus()!=0) - { + {//-- can't run if the volume has opened objects, like files, directories, formats etc. __PRINT(_L("CFatMountCB::ScanDrive() locked!\n")); return KErrInUse; } diff -r a5496987b1da -r 189ece41fa29 userlibandfileserver/fileserver/sfat32/sl_mnt32.cpp --- a/userlibandfileserver/fileserver/sfat32/sl_mnt32.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/userlibandfileserver/fileserver/sfat32/sl_mnt32.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -218,8 +218,8 @@ void CFatMountCB::SetVolumeCleanL(TBool aClean) { - //-- The volume can't be set clean if there are objects opened on it. This precondition must be checked before calling this function - if(aClean && LockStatus()!=0) + //-- The volume can't be set clean if there are disk access objects opened on it. This precondition must be checked before calling this function + if(aClean && Locked()) { __PRINT1(_L("#- CFatMountCB::SetVolumeCleanL drive:%d isn't free!"),DriveNumber()); ASSERT(0); diff -r a5496987b1da -r 189ece41fa29 userlibandfileserver/fileserver/sfile/sf_drv.cpp --- a/userlibandfileserver/fileserver/sfile/sf_drv.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/userlibandfileserver/fileserver/sfile/sf_drv.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -2173,8 +2173,9 @@ /** -Dismounts the current mount. This is method is called from outside, so do some finalisation work on mount. + Gracefully dismounts the current mount. This is method is called from outside, so do some finalisation work on mount. After calling this function there is no current mount on the drive. + */ EXPORT_C void TDrive::Dismount() { @@ -2184,10 +2185,12 @@ if (!iCurrentMount) return; + //-- try to do the best flushing file caches TRAP_IGNORE(FlushCachedFileInfoL()); //-- try our best to finalise the mount (the mount can decide to do some job during finalisation, e.g. write some data) - TRAP_IGNORE(iCurrentMount->FinaliseMountL()); + //-- finalise the mount in RO mode, we are dismounting the FS anyway + TRAP_IGNORE(iCurrentMount->FinaliseMountL(RFs::EFinal_RO)); DoDismount(); } @@ -2196,8 +2199,7 @@ /** -Forcibly dismounts the current mount and prevents it being remounted. -After calling this function there is no current mount on the drive. + Dismounts the current mount by force. */ void TDrive::ForceDismount() { @@ -2209,7 +2211,15 @@ return; TRAP_IGNORE(FlushCachedFileInfoL()); - iCurrentMount->SetDismounted(); //! this affects TDrive::ReMount() + + //-- try our best to finalise the mount (the mount can decide to do some job during finalisation, e.g. write some data) + //-- finalise the mount in RO mode, we are dismounting the FS anyway + TRAP_IGNORE(iCurrentMount->FinaliseMountL(RFs::EFinal_RO)); + + //-- mark the mount as 'Dismounted'; this invalidates all object handles until the mount is successfully "remounted". + //-- if there are still some objects opened on this mount, CMountCB::Close() won't destroy it until all objects are closed. + iCurrentMount->SetDismounted(); + DoDismount(); } diff -r a5496987b1da -r 189ece41fa29 userlibandfileserver/fileserver/sfile/sf_utl.cpp --- a/userlibandfileserver/fileserver/sfile/sf_utl.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/userlibandfileserver/fileserver/sfile/sf_utl.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -613,9 +613,11 @@ } -// -// Returns ETrue if aDes only contains spaces or is zero length -// + +/** + @return ETrue if aDes only contains spaces or is zero length + Note that _all_ UNICODE space characters are treated as usual spaces +*/ static TBool IsSpace(const TDesC& aDes) { @@ -890,38 +892,43 @@ return powerGood; } +//--------------------------------------------------------------------------------------------------------------------------------- +/** + Decrement mount's lock counter when the mount resource, like a file or directory is opened. + See also: CMountCB::LockStatus() +*/ void AddResource(CMountCB& aMount) -// -// Decrement resource counters -// { __CHECK_DRIVETHREAD(aMount.Drive().DriveNumber()); __ASSERT_DEBUG(aMount.LockStatus()<=0,Fault(ERawDiskBadAccessCount2)); aMount.DecLock(); } +/** + Increment mount's lock counter when the mount resource, like a file or directory is closed. + See also: CMountCB::LockStatus() +*/ void RemoveResource(CMountCB& aMount) -// -// Increment resource counters -// { __ASSERT_DEBUG(aMount.LockStatus()<0,Fault(ERawDiskBadAccessCount1)); aMount.IncLock(); } +/** + Increment mount's lock counter when the disk access (Format, Raw disk) is opened on the mount + See also: CMountCB::LockStatus() +*/ void AddDiskAccess(CMountCB& aMount) -// -// Increment resource counters -// { aMount.IncLock(); } +/** + Decrement mount's lock counter when the disk access (Format, Raw disk) is closed on the mount + See also: CMountCB::LockStatus() +*/ void RemoveDiskAccess(CMountCB& aMount) -// -// Decrement resource counters -// { aMount.DecLock(); } diff -r a5496987b1da -r 189ece41fa29 userlibandfileserver/fileserver/sfsrv/cl_cli.cpp --- a/userlibandfileserver/fileserver/sfsrv/cl_cli.cpp Thu Jul 01 17:57:33 2010 +0100 +++ b/userlibandfileserver/fileserver/sfsrv/cl_cli.cpp Fri Jul 09 13:13:20 2010 +0100 @@ -3259,7 +3259,7 @@ @return KErrNone on success, KErrArgument if the function arguments are invalid - KErrInUse if the drive has opened objects (files, directories etc.) and therefore can not be finalised + KErrInUse if the drive has opened disk access objects (format, raw disk access, etc) and therefore can not be finalised KErrCorrupt if the drive is corrupt. System wide error codes otherwise.