kerneltest/e32test/usbho/t_usbdi/src/PBASE-T_USBDI-0478.cpp
changeset 253 d37db4dcc88d
parent 0 a41df078684a
child 257 3e88ff8f41d5
equal deleted inserted replaced
252:0a40b8675b23 253:d37db4dcc88d
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    17 //
    17 //
    18 
    18 
    19 #include "PBASE-T_USBDI-0478.h"
    19 #include "PBASE-T_USBDI-0478.h"
    20 #include "testpolicy.h"
    20 #include "testpolicy.h"
    21 #include "modelleddevices.h"
    21 #include "modelleddevices.h"
       
    22 #include "OstTraceDefinitions.h"
       
    23 #ifdef OST_TRACE_COMPILER_IN_USE
       
    24 #include "PBASE-T_USBDI-0478Traces.h"
       
    25 #endif
    22 
    26 
    23 
    27 
    24 namespace NUnitTesting_USBDI
    28 namespace NUnitTesting_USBDI
    25 	{
    29 	{
    26 	
    30 	
    27 _LIT(KTestCaseId,"PBASE-T_USBDI-0478");
    31 _LIT(KTestCaseId,"PBASE-T_USBDI-0478");
    28 const TFunctorTestCase<CUT_PBASE_T_USBDI_0478,TBool> CUT_PBASE_T_USBDI_0478::iFunctor(KTestCaseId);	
    32 const TFunctorTestCase<CUT_PBASE_T_USBDI_0478,TBool> CUT_PBASE_T_USBDI_0478::iFunctor(KTestCaseId);	
    29 
    33 
    30 CUT_PBASE_T_USBDI_0478* CUT_PBASE_T_USBDI_0478::NewL(TBool aHostRole)
    34 CUT_PBASE_T_USBDI_0478* CUT_PBASE_T_USBDI_0478::NewL(TBool aHostRole)
    31 	{
    35 	{
       
    36 	OstTraceFunctionEntry1( CUT_PBASE_T_USBDI_0478_NEWL_ENTRY, aHostRole );
    32 	CUT_PBASE_T_USBDI_0478* self = new (ELeave) CUT_PBASE_T_USBDI_0478(aHostRole);
    37 	CUT_PBASE_T_USBDI_0478* self = new (ELeave) CUT_PBASE_T_USBDI_0478(aHostRole);
    33 	CleanupStack::PushL(self);
    38 	CleanupStack::PushL(self);
    34 	self->ConstructL();
    39 	self->ConstructL();
    35 	CleanupStack::Pop(self);
    40 	CleanupStack::Pop(self);
       
    41 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_NEWL_EXIT, ( TUint )( self ) );
    36 	return self;
    42 	return self;
    37 	}
    43 	}
    38 	
    44 	
    39 
    45 
    40 CUT_PBASE_T_USBDI_0478::CUT_PBASE_T_USBDI_0478(TBool aHostRole)
    46 CUT_PBASE_T_USBDI_0478::CUT_PBASE_T_USBDI_0478(TBool aHostRole)
    41 :	CBaseTestCase(KTestCaseId,aHostRole),
    47 :	CBaseTestCase(KTestCaseId,aHostRole),
    42 	iCaseStep(EInProgress)
    48 	iCaseStep(EInProgress)
    43 	{
    49 	{
       
    50 	OstTraceFunctionEntryExt( CUT_PBASE_T_USBDI_0478_CUT_PBASE_T_USBDI_0478_ENTRY, this );
       
    51 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_CUT_PBASE_T_USBDI_0478_EXIT, this );
    44 	} 
    52 	} 
    45 
    53 
    46 
    54 
    47 void CUT_PBASE_T_USBDI_0478::ConstructL()
    55 void CUT_PBASE_T_USBDI_0478::ConstructL()
    48 	{
    56 	{
       
    57 	OstTraceFunctionEntry1( CUT_PBASE_T_USBDI_0478_CONSTRUCTL_ENTRY, this );
    49 	iTestDevice = new RUsbDeviceA(this);
    58 	iTestDevice = new RUsbDeviceA(this);
    50 	BaseConstructL();
    59 	BaseConstructL();
       
    60 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_CONSTRUCTL_EXIT, this );
    51 	}
    61 	}
    52 
    62 
    53 
    63 
    54 CUT_PBASE_T_USBDI_0478::~CUT_PBASE_T_USBDI_0478()
    64 CUT_PBASE_T_USBDI_0478::~CUT_PBASE_T_USBDI_0478()
    55 	{
    65 	{
    56 	LOG_FUNC
    66 	OstTraceFunctionEntry1( CUT_PBASE_T_USBDI_0478_CUT_PBASE_T_USBDI_0478_ENTRY_DUP01, this );
    57 	
    67 	
    58 	Cancel();
    68 	Cancel();
    59 
    69 
    60 	// Close the interfaces
    70 	// Close the interfaces
    61 	
    71 	
    68 	if(!IsHost() && iTestDevice)
    78 	if(!IsHost() && iTestDevice)
    69 		{
    79 		{
    70 		iTestDevice->Close();
    80 		iTestDevice->Close();
    71 		}		
    81 		}		
    72 	delete iTestDevice;
    82 	delete iTestDevice;
       
    83 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_CUT_PBASE_T_USBDI_0478_EXIT_DUP01, this );
    73 	}
    84 	}
    74 	
    85 	
    75 void CUT_PBASE_T_USBDI_0478::ExecuteHostTestCaseL()	
    86 void CUT_PBASE_T_USBDI_0478::ExecuteHostTestCaseL()	
    76 	{
    87 	{
    77 	LOG_FUNC
    88     OstTraceFunctionEntry1( CUT_PBASE_T_USBDI_0478_EXECUTEHOSTTESTCASEL_ENTRY, this );
    78 
    89 
    79 	// Create the actor for the Function Driver Framework 
    90 	// Create the actor for the Function Driver Framework 
    80 	
    91 	
    81 	iActorFDF = CActorFDF::NewL(*this);
    92 	iActorFDF = CActorFDF::NewL(*this);
    82 
    93 
    89 	iActorFDF->Monitor();
   100 	iActorFDF->Monitor();
    90 	
   101 	
    91 	// Start the connection timeout timer
   102 	// Start the connection timeout timer
    92 
   103 
    93 	TimeoutIn(30);
   104 	TimeoutIn(30);
       
   105 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_EXECUTEHOSTTESTCASEL_EXIT, this );
    94 	}
   106 	}
    95 	
   107 	
    96 void CUT_PBASE_T_USBDI_0478::HostDoCancel()
   108 void CUT_PBASE_T_USBDI_0478::HostDoCancel()
    97 	{
   109 	{
    98 	LOG_FUNC
   110     OstTraceFunctionEntry1( CUT_PBASE_T_USBDI_0478_HOSTDOCANCEL_ENTRY, this );
    99 
   111 
   100 	// Cancel the timeout timer for activity
   112 	// Cancel the timeout timer for activity
   101 
   113 
   102 	CancelTimeout();
   114 	CancelTimeout();
       
   115 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_HOSTDOCANCEL_EXIT, this );
   103 	}
   116 	}
   104 	
   117 	
   105 	
   118 	
   106 void CUT_PBASE_T_USBDI_0478::ExecuteDeviceTestCaseL()	
   119 void CUT_PBASE_T_USBDI_0478::ExecuteDeviceTestCaseL()	
   107 	{
   120 	{
   108 	LOG_FUNC
   121     OstTraceFunctionEntry1( CUT_PBASE_T_USBDI_0478_EXECUTEDEVICETESTCASEL_ENTRY, this );
   109 
   122 
   110 	// Create the test device for this test case
   123 	// Create the test device for this test case
   111 
   124 
   112 	iTestDevice->OpenL(TestCaseId());
   125 	iTestDevice->OpenL(TestCaseId());
   113 	iTestDevice->SubscribeToReports(iStatus);
   126 	iTestDevice->SubscribeToReports(iStatus);
   114 	SetActive();
   127 	SetActive();
   115 
   128 
   116 	// Connect the test device to the host
   129 	// Connect the test device to the host
   117 
   130 
   118 	iTestDevice->SoftwareConnect();
   131 	iTestDevice->SoftwareConnect();
       
   132 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_EXECUTEDEVICETESTCASEL_EXIT, this );
   119 	}
   133 	}
   120 	
   134 	
   121 void CUT_PBASE_T_USBDI_0478::DeviceDoCancel()
   135 void CUT_PBASE_T_USBDI_0478::DeviceDoCancel()
   122 	{
   136 	{
   123 	LOG_FUNC
   137     OstTraceFunctionEntry1( CUT_PBASE_T_USBDI_0478_DEVICEDOCANCEL_ENTRY, this );
   124 
   138 
   125 	// Cancel the test device
   139 	// Cancel the test device
   126 	
   140 	
   127 	iTestDevice->CancelSubscriptionToReports();
   141 	iTestDevice->CancelSubscriptionToReports();
       
   142 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_DEVICEDOCANCEL_EXIT, this );
   128 	}
   143 	}
   129 	
   144 	
   130 	
   145 	
   131 void CUT_PBASE_T_USBDI_0478::DeviceStateChangeL(RUsbDevice::TDeviceState aPreviousState,
   146 void CUT_PBASE_T_USBDI_0478::DeviceStateChangeL(RUsbDevice::TDeviceState aPreviousState,
   132 	RUsbDevice::TDeviceState aNewState,TInt aCompletionCode)
   147 	RUsbDevice::TDeviceState aNewState,TInt aCompletionCode)
   133 	{
   148 	{
   134 	LOG_FUNC
   149     OstTraceFunctionEntryExt( CUT_PBASE_T_USBDI_0478_DEVICESTATECHANGEL_ENTRY, this );
   135 
   150 
   136 	Cancel();
   151 	Cancel();
       
   152 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_DEVICESTATECHANGEL_EXIT, this );
   137 	}
   153 	}
   138 	
   154 	
   139 	
   155 	
   140 void CUT_PBASE_T_USBDI_0478::DeviceInsertedL(TUint aDeviceHandle)
   156 void CUT_PBASE_T_USBDI_0478::DeviceInsertedL(TUint aDeviceHandle)
   141 	{
   157 	{
   142 	LOG_FUNC
   158     OstTraceFunctionEntryExt( CUT_PBASE_T_USBDI_0478_DEVICEINSERTEDL_ENTRY, this );
   143 
   159 
   144 	Cancel();
   160 	Cancel();
   145 	TInt err(KErrNone);
   161 	TInt err(KErrNone);
   146 	
   162 	
   147 	// Validate that device is as expected
   163 	// Validate that device is as expected
   148 	CUsbTestDevice& testDevice = iActorFDF->DeviceL(aDeviceHandle);
   164 	CUsbTestDevice& testDevice = iActorFDF->DeviceL(aDeviceHandle);
   149 	if(testDevice.SerialNumber().Compare(TestCaseId()) != 0)
   165 	if(testDevice.SerialNumber().Compare(TestCaseId()) != 0)
   150 		{
   166 		{
   151 		// Incorrect device for this test case	
   167 		// Incorrect device for this test case	
   152 
   168 
   153 		RDebug::Printf("<Warning %d> Incorrect device serial number (%S) connected for this test case (%S)",
   169 		OstTraceExt3(TRACE_NORMAL, CUT_PBASE_T_USBDI_0478_DEVICEINSERTEDL, "<Warning %d> Incorrect device serial number (%S) connected for this test case (%S)",
   154 			KErrNotFound,&testDevice.SerialNumber(),&TestCaseId());
   170 			KErrNotFound,testDevice.SerialNumber(),TestCaseId());
   155 
   171 
   156 		// Start the connection timeout again
   172 		// Start the connection timeout again
   157 
   173 
   158 		TimeoutIn(30);
   174 		TimeoutIn(30);
       
   175 		OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_DEVICEINSERTEDL_EXIT, this );
   159 		return;
   176 		return;
   160 		}
   177 		}
   161 	
   178 	
   162 	TUint32 token0,token1;
   179 	TUint32 token0,token1;
   163 	err = testDevice.Device().GetTokenForInterface(0,token0);
   180 	err = testDevice.Device().GetTokenForInterface(0,token0);
   164 	if(err != KErrNone)
   181 	if(err != KErrNone)
   165 		{
   182 		{
   166 		RDebug::Printf("<Error %d> Token for interface 0 could not be retrieved",err);
   183 		OstTrace1(TRACE_NORMAL, CUT_PBASE_T_USBDI_0478_DEVICEINSERTEDL_DUP01, "<Error %d> Token for interface 0 could not be retrieved",err);
   167 		return TestFailed(err);
   184 		return TestFailed(err);
   168 		}
   185 		}
   169 	err = iUsbInterface0.Open(token0); // Default interface setting 0
   186 	err = iUsbInterface0.Open(token0); // Default interface setting 0
   170 	if(err != KErrNone)
   187 	if(err != KErrNone)
   171 		{
   188 		{
   172 		RDebug::Printf("<Error %d> Unable to open interface 0 using token %d",err,token0);
   189 		OstTraceExt2(TRACE_NORMAL, CUT_PBASE_T_USBDI_0478_DEVICEINSERTEDL_DUP02, "<Error %d> Unable to open interface 0 using token %d",err,token0);
   173 		return TestFailed(err);
   190 		return TestFailed(err);
   174 		}
   191 		}
   175 
   192 
   176 	err = testDevice.Device().GetTokenForInterface(1,token1);
   193 	err = testDevice.Device().GetTokenForInterface(1,token1);
   177 	if(err != KErrNone)
   194 	if(err != KErrNone)
   178 		{
   195 		{
   179 		RDebug::Printf("<Error %d> Token for interface 1 could not be retrieved",err);
   196 		OstTrace1(TRACE_NORMAL, CUT_PBASE_T_USBDI_0478_DEVICEINSERTEDL_DUP03, "<Error %d> Token for interface 1 could not be retrieved",err);
   180 		return TestFailed(err);
   197 		return TestFailed(err);
   181 		}
   198 		}
   182 
   199 
   183 	err = iUsbInterface1.Open(token1);
   200 	err = iUsbInterface1.Open(token1);
   184 	if(err != KErrNone)
   201 	if(err != KErrNone)
   185 		{
   202 		{
   186 		RDebug::Printf("<Error %d> Unable to open interface using token %d",err,token1);
   203 		OstTraceExt2(TRACE_NORMAL, CUT_PBASE_T_USBDI_0478_DEVICEINSERTEDL_DUP04, "<Error %d> Unable to open interface using token %d",err,token1);
   187 		return TestFailed(err);
   204 		return TestFailed(err);
   188 		}
   205 		}
   189 
   206 
   190 	// Acting as another FD open the interface
   207 	// Acting as another FD open the interface
   191 	
   208 	
   192 	err = iDuplicateUsbInterface1.Open(token1);
   209 	err = iDuplicateUsbInterface1.Open(token1);
   193 	if(err == KErrNone)
   210 	if(err == KErrNone)
   194 		{
   211 		{
   195 		TBuf<64> msg;
   212 		TBuf<64> msg;
   196 		msg.Format(_L("<Error> Able to open a concurrent hande to an interface"));
   213 		msg.Format(_L("<Error> Able to open a concurrent hande to an interface"));
   197 		RDebug::Print(msg);
   214 		OstTrace0(TRACE_NORMAL, CUT_PBASE_T_USBDI_0478_DEVICEINSERTEDL_DUP05, msg);
   198 		iCaseStep = EFailed;
   215 		iCaseStep = EFailed;
   199 		TTestCaseFailed request(KErrCompletion,msg);
   216 		TTestCaseFailed request(KErrCompletion,msg);
   200 		iControlEp0->SendRequest(request,this);
   217 		iControlEp0->SendRequest(request,this);
       
   218 		OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_DEVICEINSERTEDL_EXIT_DUP01, this );
   201 		return;
   219 		return;
   202 		}
   220 		}
   203 	RDebug::Printf("Attempt to open concurrent interface handle failed with: %d",err);
   221 	OstTrace1(TRACE_NORMAL, CUT_PBASE_T_USBDI_0478_DEVICEINSERTEDL_DUP06, "Attempt to open concurrent interface handle failed with: %d",err);
   204 	
   222 	
   205 	// Inform client device test case successful 
   223 	// Inform client device test case successful 
   206 	User::After(1000000);
   224 	User::After(1000000);
   207 	iCaseStep = EPassed;
   225 	iCaseStep = EPassed;
   208 	TTestCasePassed request;
   226 	TTestCasePassed request;
   209 	iControlEp0->SendRequest(request,this);
   227 	iControlEp0->SendRequest(request,this);
       
   228 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_DEVICEINSERTEDL_EXIT_DUP02, this );
   210 	}
   229 	}
   211 	
   230 	
   212 	
   231 	
   213 void CUT_PBASE_T_USBDI_0478::Ep0TransferCompleteL(TInt aCompletionCode)
   232 void CUT_PBASE_T_USBDI_0478::Ep0TransferCompleteL(TInt aCompletionCode)
   214 	{
   233 	{
   215 	LOG_FUNC
   234 	OstTraceFunctionEntryExt( CUT_PBASE_T_USBDI_0478_EP0TRANSFERCOMPLETEL_ENTRY, this );
   216 	
   235 	
   217 	RDebug::Printf("Ep0TransferCompleteL with aCompletionCode = %d",aCompletionCode);
   236 	OstTrace1(TRACE_NORMAL, CUT_PBASE_T_USBDI_0478_EP0TRANSFERCOMPLETEL, "Ep0TransferCompleteL with aCompletionCode = %d",aCompletionCode);
   218 	
   237 	
   219 	if(aCompletionCode != KErrNone)
   238 	if(aCompletionCode != KErrNone)
   220 		{	
   239 		{	
   221 		TBuf<256> msg;
   240 		TBuf<256> msg;
   222 		msg.Format(_L("<Error %d> Transfer to control endpoint 0 was not successful"),aCompletionCode);
   241 		msg.Format(_L("<Error %d> Transfer to control endpoint 0 was not successful"),aCompletionCode);
   223 		RDebug::Print(msg);
   242 		OstTrace0(TRACE_NORMAL, CUT_PBASE_T_USBDI_0478_EP0TRANSFERCOMPLETEL_DUP01, msg);
   224 		}
   243 		}
   225 
   244 
   226 	if(iCaseStep == EPassed)
   245 	if(iCaseStep == EPassed)
   227 		{	
   246 		{	
   228 		if(aCompletionCode == KErrNone)
   247 		if(aCompletionCode == KErrNone)
   235 	
   254 	
   236 	if(iCaseStep == EFailed)
   255 	if(iCaseStep == EFailed)
   237 		{
   256 		{
   238 		return TestFailed(KErrCompletion);
   257 		return TestFailed(KErrCompletion);
   239 		}
   258 		}
       
   259 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_EP0TRANSFERCOMPLETEL_EXIT, this );
   240 	}
   260 	}
   241 	
   261 	
   242 	
   262 	
   243 void CUT_PBASE_T_USBDI_0478::DeviceRemovedL(TUint aDeviceHandle)
   263 void CUT_PBASE_T_USBDI_0478::DeviceRemovedL(TUint aDeviceHandle)
   244 	{
   264 	{
   245 	LOG_FUNC
   265     OstTraceFunctionEntryExt( CUT_PBASE_T_USBDI_0478_DEVICEREMOVEDL_ENTRY, this );
   246 
   266 
   247 	// The test device should not be removed until the test case has passed
   267 	// The test device should not be removed until the test case has passed
   248 	// so this test case has not completed, and state this event as an error
   268 	// so this test case has not completed, and state this event as an error
   249 
   269 
   250 	TestFailed(KErrDisconnected);
   270 	TestFailed(KErrDisconnected);
       
   271 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_DEVICEREMOVEDL_EXIT, this );
   251 	}
   272 	}
   252 	
   273 	
   253 	
   274 	
   254 void CUT_PBASE_T_USBDI_0478::BusErrorL(TInt aError)
   275 void CUT_PBASE_T_USBDI_0478::BusErrorL(TInt aError)
   255 	{
   276 	{
   256 	LOG_FUNC
   277     OstTraceFunctionEntryExt( CUT_PBASE_T_USBDI_0478_BUSERRORL_ENTRY, this );
   257 
   278 
   258 	// This test case handles no failiures on the bus
   279 	// This test case handles no failiures on the bus
   259 	
   280 	
   260 	TestFailed(aError);	
   281 	TestFailed(aError);	
       
   282 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_BUSERRORL_EXIT, this );
   261 	}
   283 	}
   262 
   284 
   263 void CUT_PBASE_T_USBDI_0478::HostRunL()
   285 void CUT_PBASE_T_USBDI_0478::HostRunL()
   264 	{
   286 	{
   265 	LOG_FUNC
   287     OstTraceFunctionEntry1( CUT_PBASE_T_USBDI_0478_HOSTRUNL_ENTRY, this );
   266 
   288 
   267 	// Obtain the completion code
   289 	// Obtain the completion code
   268 	TInt completionCode(iStatus.Int());
   290 	TInt completionCode(iStatus.Int());
   269 	
   291 	
   270 	if(completionCode == KErrNone)
   292 	if(completionCode == KErrNone)
   271 		{
   293 		{
   272 		// Action timeout
   294 		// Action timeout
   273 		RDebug::Printf("<Error> Action timeout");
   295 		OstTrace0(TRACE_NORMAL, CUT_PBASE_T_USBDI_0478_HOSTRUNL, "<Error> Action timeout");
   274 		TestFailed(KErrTimedOut);
   296 		TestFailed(KErrTimedOut);
   275 		}
   297 		}
   276 	else
   298 	else
   277 		{
   299 		{
   278 		RDebug::Printf("<Error %d> Timeout timer could not complete",completionCode);
   300 		OstTrace1(TRACE_NORMAL, CUT_PBASE_T_USBDI_0478_HOSTRUNL_DUP01, "<Error %d> Timeout timer could not complete",completionCode);
   279 		TestFailed(completionCode);
   301 		TestFailed(completionCode);
   280 		}
   302 		}
       
   303 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_HOSTRUNL_EXIT, this );
   281 	}
   304 	}
   282 
   305 
   283 void CUT_PBASE_T_USBDI_0478::DeviceRunL()
   306 void CUT_PBASE_T_USBDI_0478::DeviceRunL()
   284 	{
   307 	{
   285 	LOG_FUNC
   308 	OstTraceFunctionEntry1( CUT_PBASE_T_USBDI_0478_DEVICERUNL_ENTRY, this );
   286 	
   309 	
   287 	// Disconnect the device
   310 	// Disconnect the device
   288 	
   311 	
   289 	iTestDevice->SoftwareDisconnect();
   312 	iTestDevice->SoftwareDisconnect();
   290 	
   313 	
   291 	// Complete the test case request
   314 	// Complete the test case request
   292 	
   315 	
   293 	TestPolicy().SignalTestComplete(iStatus.Int());
   316 	TestPolicy().SignalTestComplete(iStatus.Int());
   294 	}
   317 	OstTraceFunctionExit1( CUT_PBASE_T_USBDI_0478_DEVICERUNL_EXIT, this );
   295 
   318 	}
   296 	
   319 
   297 	}
   320 	
       
   321 	}