sl@0: // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of the License "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: // e32test/usb/t_usb_device/src/activestatenotifier.cpp
sl@0: // USB Test Program T_USB_DEVICE, functional part.
sl@0: // Device-side part, to work against T_USB_HOST running on the host.
sl@0: // 
sl@0: //
sl@0: 
sl@0: #include "general.h"
sl@0: #include "activerw.h"									// CActiveRW
sl@0: #include "config.h"
sl@0: #include "activeControl.h"
sl@0: #include "activedevicestatenotifier.h"
sl@0: 
sl@0: extern CActiveControl* gActiveControl;
sl@0: extern RTest test;
sl@0: extern TBool gVerbose;
sl@0: extern TBool gSkip;
sl@0: extern TBool gStopOnFail;
sl@0: extern TBool gAltSettingOnNotify;
sl@0: extern TInt gSoakCount;
sl@0: extern CActiveRW* gRW[KMaxConcurrentTests];				// the USB read/write active object
sl@0: extern IFConfigPtr gInterfaceConfig [128] [KMaxInterfaceSettings];
sl@0: 
sl@0: //
sl@0: // --- class CActiveDeviceStateNotifier ---------------------------------------------------------
sl@0: //
sl@0: 
sl@0: CActiveDeviceStateNotifier::CActiveDeviceStateNotifier(CConsoleBase* aConsole, RDEVCLIENT* aPort, TUint aPortNumber)
sl@0: 	: CActive(EPriorityNormal),
sl@0: 	  iConsole(aConsole),
sl@0: 	  iPort(aPort),
sl@0: 	  iDeviceState(0),
sl@0: 	  iPortNumber(aPortNumber)
sl@0: 	{
sl@0: 	CActiveScheduler::Add(this);
sl@0: 	}
sl@0: 
sl@0: CActiveDeviceStateNotifier* CActiveDeviceStateNotifier::NewL(CConsoleBase* aConsole, RDEVCLIENT* aPort, TUint aPortNumber)
sl@0: 	{
sl@0: 	CActiveDeviceStateNotifier* self = new (ELeave) CActiveDeviceStateNotifier(aConsole, aPort, aPortNumber);
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL();
sl@0: 	CleanupStack::Pop();									// self
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: void CActiveDeviceStateNotifier::ConstructL()
sl@0: 	{}
sl@0: 
sl@0: 
sl@0: CActiveDeviceStateNotifier::~CActiveDeviceStateNotifier()
sl@0: 	{
sl@0: 	TUSB_VERBOSE_PRINT("CActiveDeviceStateNotifier::~CActiveDeviceStateNotifier()");
sl@0: 	Cancel();												// base class
sl@0: 	}
sl@0: 
sl@0: 
sl@0: void CActiveDeviceStateNotifier::DoCancel()
sl@0: 	{
sl@0: 	TUSB_VERBOSE_PRINT("CActiveDeviceStateNotifier::DoCancel()");
sl@0: 	iPort->AlternateDeviceStatusNotifyCancel();
sl@0: 	}
sl@0: 
sl@0: 
sl@0: void CActiveDeviceStateNotifier::RunL()
sl@0: 	{
sl@0: 	// This displays the device state.
sl@0: 	// In a real world program, the user could take here appropriate action (cancel a
sl@0: 	// transfer request or whatever).
sl@0: 	if (!(iDeviceState & KUsbAlternateSetting) && gVerbose)
sl@0: 		{
sl@0: 		switch (iDeviceState)
sl@0: 			{
sl@0: 		case EUsbcDeviceStateUndefined:
sl@0: 			TUSB_PRINT("Device State notifier: Undefined");
sl@0: 			break;
sl@0: 		case EUsbcDeviceStateAttached:
sl@0: 			TUSB_PRINT("Device State notifier: Attached");
sl@0: 			break;
sl@0: 		case EUsbcDeviceStatePowered:
sl@0: 			TUSB_PRINT("Device State notifier: Powered");
sl@0: 			break;
sl@0: 		case EUsbcDeviceStateDefault:
sl@0: 			TUSB_PRINT("Device State notifier: Default");
sl@0: 			break;
sl@0: 		case EUsbcDeviceStateAddress:
sl@0: 			TUSB_PRINT("Device State notifier: Address");
sl@0: 			break;
sl@0: 		case EUsbcDeviceStateConfigured:
sl@0: 			TUSB_PRINT("Device State notifier: Configured");
sl@0: 			break;
sl@0: 		case EUsbcDeviceStateSuspended:
sl@0: 			TUSB_PRINT("Device State notifier: Suspended");
sl@0: 			break;
sl@0: 		default:
sl@0: 			TUSB_PRINT("Device State notifier: ***BAD***");
sl@0: 			}
sl@0: 		}
sl@0: 	else if (iDeviceState & KUsbAlternateSetting)
sl@0: 		{
sl@0: 		TUint8 altSetting = iDeviceState & ~KUsbAlternateSetting;
sl@0: 		TUSB_PRINT2("Device State notifier: Alternate interface %d setting has changed: now %d",
sl@0: 					iPortNumber, altSetting);
sl@0: 
sl@0: 		// 	allocate endpoint DMA and double buffering for all endpoints on interface
sl@0: 		for (TUint8 ifNumber = 0; ifNumber < 128; ifNumber++)
sl@0: 			{
sl@0: 			IFConfigPtr newIfPtr = gInterfaceConfig[ifNumber][altSetting];
sl@0: 			if (newIfPtr)
sl@0: 				{
sl@0: 				if (newIfPtr->iPortNumber == iPortNumber)
sl@0: 					{
sl@0: 					// 	allocate endpoint DMA and double buffering for all endpoints on default interface
sl@0: 					for (TUint8 i = 1; i <= newIfPtr->iInfoPtr->iTotalEndpointsUsed; i++)
sl@0: 						{
sl@0: 						newIfPtr->iEpDMA[i-1] ? gActiveControl->AllocateEndpointDMA(iPort,(TENDPOINTNUMBER)i) : gActiveControl->DeAllocateEndpointDMA(iPort,(TENDPOINTNUMBER)i);
sl@0: 						#ifndef USB_SC
sl@0: 						newIfPtr->iEpDoubleBuff[i-1] ? gActiveControl->AllocateDoubleBuffering(iPort,(TENDPOINTNUMBER)i) : gActiveControl->DeAllocateDoubleBuffering(iPort,(TENDPOINTNUMBER)i);
sl@0: 						#endif
sl@0: 						}
sl@0: 					break;				
sl@0: 					}
sl@0: 				}
sl@0: 			}
sl@0: 							
sl@0: 		if (gAltSettingOnNotify)
sl@0: 			{
sl@0: 			for (TUint16 i =0; i < KMaxConcurrentTests; i++)
sl@0: 				{
sl@0: 				if (gRW[i])
sl@0: 					{
sl@0: 					TUSB_VERBOSE_PRINT1("Resuming alternate Setting - activeRW index %d",i);
sl@0: 					gRW[i]->ResumeAltSetting(altSetting);						
sl@0: 					}
sl@0: 				}
sl@0: 			}
sl@0: 		}
sl@0: 	Activate();
sl@0: 	}
sl@0: 
sl@0: 
sl@0: void CActiveDeviceStateNotifier::Activate()
sl@0: 	{
sl@0: 	__ASSERT_ALWAYS(!IsActive(), User::Panic(KActivePanic, 661));
sl@0: 	iPort->AlternateDeviceStatusNotify(iStatus, iDeviceState);
sl@0: 	SetActive();
sl@0: 	}
sl@0: 
sl@0: 
sl@0: // -eof-