usbmgmt/usbmgrtest/t_ncm/src/ncmtestconsole.cpp
changeset 28 f1fd07aa74c9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_ncm/src/ncmtestconsole.cpp	Wed Jul 07 14:16:40 2010 +0800
@@ -0,0 +1,565 @@
+/*
+* Copyright (c) 2002-2009 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:
+*
+*/
+
+/** @file
+ @internalComponent
+ @test
+ */
+
+
+#include "ncmtestconsole.h"
+#include "ncmtestdefines.hrh"
+#include "commandengine.h"
+#include "devicewatcher.h"
+#include "servicewatcher.h"
+#include "ncmwatcher.h"
+#include "exitcommand.h"
+#include "setncmiapcommand.h"
+#include "simpancommand.h"
+#include "tcpcommand.h"
+
+#include <commdb.h>
+#include <commdbconnpref.h>
+#include <nifman.h>
+#include <es_enum.h>
+
+//#include <ncm/ncmuiinterfaces.h>
+using namespace UsbNcm;
+
+//The app parameter
+_LIT(KArgDemo, "DEMO");
+
+//Set the display item length
+//every display item has fixed length. It will be displayed screen permanently.
+//The details about how to use display item is in CUsbNcmConsole::DrawL()
+TInt gDisplayItemLength[] = {
+			DISPLAY_USB_SERVICE_STATE_LEN,			//EUsbServiceStateItem
+			DISPLAY_USB_DEVICE_STATE_LEN,			//EUsbDeviceStateItem
+			DISPLAY_NCM_CONN_STATE_LEN,			//ENcmConnStatusItem
+			DISPLAY_NCM_CONN_IP_LEN,				//ENcmConnIpItem
+			DISPLAY_UPLINK_CONN_STATE_LEN,			//EUplinkConnStatusItem
+			DISPLAY_UPLINK_CONN_IP_LEN,				//EUplinkConnIpItem
+			DISPLAY_NCM_BTPAN_LEN,				//ENcmBtPanItem
+			DISPLAY_AGENT_STATE_LEN,				//ENcmAgentStateItem
+			DISPLAY_AUTH_SETTING_LEN,				//EAuthorisationSettingItem
+			DISPLAY_NCM_CONNECTION_STATE
+							};
+
+void Panic(TInt aPanic)
+	{
+	User::Panic(_L("NcmTestConsole"), aPanic);
+	}
+
+
+void RunConsoleL()
+	{
+	TInt cmdLineLength(User::CommandLineLength());
+	HBufC* cmdLine = HBufC::NewMaxLC(cmdLineLength);
+	TPtr cmdLinePtr = cmdLine->Des();
+	User::CommandLine(cmdLinePtr);
+
+	TLex args(*cmdLine);
+	// args are separated by spaces
+	args.SkipSpace(); 
+	
+	TPtrC cmdToken = args.NextToken();
+	HBufC* tc = HBufC::NewLC(80);
+	*tc = cmdToken;
+	
+	TBool isDemo = EFalse;
+	
+	//Find if there is 'DEMO' or not.
+	while (tc->Length())
+		{
+		TInt pos = tc->FindF(KArgDemo);
+		if ( pos != KErrNotFound )
+			{ 
+			isDemo = ETrue;
+			break;
+			}
+		
+		// next parameter
+		*tc = args.NextToken();
+		}
+	CleanupStack::PopAndDestroy(tc);
+	CleanupStack::PopAndDestroy(cmdLine);
+
+	CUsbNcmConsole* console = CUsbNcmConsole::NewLC(isDemo);
+	console->StartL();
+	CleanupStack::PopAndDestroy(console);
+	}
+
+TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	CActiveScheduler* activeScheduler = new CActiveScheduler;
+	TInt err = KErrNoMemory;
+	if(cleanup && activeScheduler)
+		{
+		CActiveScheduler::Install(activeScheduler);
+		TRAP(err,RunConsoleL());
+		}
+	delete activeScheduler;
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return err;
+	}
+
+CUsbNcmConsoleEvent* CUsbNcmConsoleEvent::NewL()
+	{	
+	CUsbNcmConsoleEvent* self = new(ELeave) CUsbNcmConsoleEvent();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	
+	}
+
+CUsbNcmConsoleEvent::CUsbNcmConsoleEvent()
+	{	
+	}
+
+CUsbNcmConsoleEvent::~CUsbNcmConsoleEvent()
+	{
+	iLink.Deque();
+	iEvent.Close();
+	}
+	
+void CUsbNcmConsoleEvent::ConstructL()
+	{
+	User::LeaveIfError(iEvent.Create(NUM_CHARACTERS_ON_LINE-1));	
+	}
+
+
+CUsbNcmConsole* CUsbNcmConsole::NewLC(TBool aDemo)
+/**
+Constructs a CUsbNcmConsole object.
+  @param  aDemo 	Indicate start NCM control app and NCM automaticly or manually
+
+When iDemo is ETrue, means ncmtestconsole starts as a demo. It will ask user to set ncm iap and
+uplink iap.Then user can experience the NCM function by plug/unplug usb cable. 
+*/
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbNcmConsole* self = new(ELeave) CUsbNcmConsole(aDemo);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+	
+CUsbNcmConsole::~CUsbNcmConsole()
+	{
+	LOG_FUNC
+
+	//If Ncm control app is not stopped, stop it.
+	//destroy all commands
+	delete iKeys;
+
+	//destroy event list
+	TDblQueIter<CUsbNcmConsoleEvent> iter(iEventList);
+	CUsbNcmConsoleEvent* event = NULL;
+	while((event = iter++) != NULL)
+		{
+		delete event;
+		}
+
+	//delete iStartWatcherCallback;
+
+	//destroy all watches
+	delete iSharedStateWatcher;
+	delete iDeviceWatcher;
+	delete iServiceWatcher;
+	
+	iUsb.Close();
+		
+	delete iConsole;
+
+	//Destroy all display items
+	for(TInt i=0; i<ELastItem; i++)
+		{
+		iDisplayArray[i].Close();
+		}
+	iDisplayArray.Close();
+
+	Cancel();
+	
+	}
+
+CUsbNcmConsole::CUsbNcmConsole(TBool aDemo)
+	: CActive(EPriorityLow) // Low so all notifications that want to be serviced will be done first
+	, iHelp(EFalse)
+	, iDemo(aDemo)
+	, iEventList(_FOFF(CUsbNcmConsoleEvent, iLink))
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUsbNcmConsole::ConstructL()
+	{
+	LOG_FUNC
+	
+	//Init Display Item
+	iDisplayArray.ReserveL(ELastItem);
+	CreateDisplayItemL();
+
+	iConsole = Console::NewL(KUsbNcmConsoleTitle, TSize(-1,-1));
+	User::LeaveIfError(iUsb.Connect());
+	__FLOG_STATIC0(KSubSys, KLogComponent , _L8("iUsb.Connect() successful"));
+	
+	//Init event list
+	for(TInt i=0; i< NUM_EVENT_ON_SCREEN; ++i)
+		{
+		CUsbNcmConsoleEvent* nullEvent = CUsbNcmConsoleEvent::NewL();
+		iEventList.AddFirst(*nullEvent);
+		}
+	__FLOG_STATIC0(KSubSys, KLogComponent , _L8("Create event list successful"));		
+
+
+	//Start watcher
+	//iDeviceWatcher = CDeviceWatcher::NewL(*this);
+	//iServiceWatcher = CServiceWatcher::NewL(*this);
+	// iUplinkConnectionWatcher = CUplinkWatcher::NewL(*this);
+	
+	__FLOG_STATIC0(KSubSys, KLogComponent , _L8("Create watchers successful"));
+
+	//create command engine
+	iKeys = CNcmCommandEngine::NewL(*this);
+	
+	//add commands
+	CNcmCommandBase* command = NULL;
+
+	//the command to set ncm iap
+	command = CSetNcmIapCommand::NewL(*this, 'n');
+	iKeys->RegisterCommand(command);
+	//Get the default iap used by ncm
+	TInt defaultIap = 0;
+	((CSetNcmIapCommand*)command)->GetDefaultIapL(defaultIap);
+	SetLocalIapId(defaultIap);	
+
+	//the command to simulate PAN actvie/inactive
+	command = CSimPANCommand::NewL(*this, 'p');
+	iKeys->RegisterCommand(command);
+
+	//the command to create a connection from PC to H4 and make data transfer
+	command = CTcpCommand::NewL(*this, 'v', ETrue, ETrue);
+	iKeys->RegisterCommand(command);
+	//the command to create a connection from H4 to PC and make data transfer
+	command = CTcpCommand::NewL(*this, 'i', ETrue, EFalse);
+	iKeys->RegisterCommand(command);
+
+	command = CTcpCommand::NewL(*this , 'r', EFalse, ETrue);
+	iKeys->RegisterCommand(command);
+	command = CTcpCommand::NewL(*this , 's', EFalse, EFalse);
+	iKeys->RegisterCommand(command);
+
+	//here to add new command
+	
+	//the command to quit 
+	command = CExitCommand::NewL(*this, 'q');
+	iKeys->RegisterCommand(command);
+	
+	//Monitor the status published by NCM agent
+	iSharedStateWatcher = CSharedStateWatcher::NewL(*this);
+	}
+
+void CUsbNcmConsole::StartL()
+	{
+	//Output the init state to screen
+	DrawL();
+	//Do StartWatcherCommand if 'demo' is the command parameter
+	if(iDemo)
+		{
+//		iStartWatcherCallback->CallBack();
+		}
+	CActiveScheduler::Start();
+	}
+	
+void CUsbNcmConsole::Stop() const
+	{
+	CActiveScheduler::Stop();
+	}
+
+void CUsbNcmConsole::DoCancel()
+	{
+	}
+
+void CUsbNcmConsole::RunL()
+	{
+	DrawL();
+	}
+
+TInt CUsbNcmConsole::RunError(TInt aError)
+	{
+	User::Panic(_L("CUsbNcmConsole"), aError);
+	return aError;
+	}
+
+void CUsbNcmConsole::ScheduleDraw(TUint aKey)
+/**
+Called by commands and monitors.To notify main console there's new infomation to show.
+  @param  aKey 	Display type. '1'-'9' - display the command help
+  							  'E' - display the events.
+  							  '0' - back from command help	
+*/
+	{
+	iHelp = aKey;
+	if(!IsActive())
+		{
+		SetActive();
+		TRequestStatus* status = &iStatus;
+		User::RequestComplete(status, KErrNone);
+		}
+	}
+	
+RUsb& CUsbNcmConsole::Usb()
+	{
+	return iUsb;
+	}
+
+void CUsbNcmConsole::SetLocalIapId(TInt aId)
+/**
+Set the Ncm Iap which will be monitored and displayed on screen
+  @param  aId 	The Ncm Iap Id
+*/
+	{
+	iLocalIapId = aId;
+	ScheduleDraw('E');
+	}
+
+void CUsbNcmConsole::NotifyEvent(CUsbNcmConsoleEvent* aEvent)
+/**
+Called by commands and monitors. To tell main console to display the new event.
+  @param  aEvent 	Event reported by commands and monitors
+*/
+	{
+	//Console can't display a NULL event
+	__ASSERT_ALWAYS(aEvent, Panic(ENcmEventIsNull));
+	//Console can't display a string more than one line
+	__ASSERT_ALWAYS(aEvent->iEvent.Length() <= NUM_CHARACTERS_ON_LINE, Panic(ENcmEventLengthValid));
+
+	iEventList.AddFirst(*aEvent);
+	CUsbNcmConsoleEvent* theLastEvent = iEventList.Last();
+	delete theLastEvent;
+
+	ScheduleDraw('E');
+	}
+
+void CUsbNcmConsole::DrawL()
+/**
+Display all infomation on screen. 
+There are two parts on the screen. One is permanent info. It will display all kinds of states such as USB device state,
+USB service state, NCM state, and so on. The other is event info show. It will display the events reported by monitors
+and commands. It also used to show command help when user need command help. 
+*/
+	{
+	iConsole->ClearScreen();
+	// First line is the server version number 
+	TVersionName versionName = iVersion.Name();
+	iConsole->Printf(_L(
+		//          1         2         3         4         5
+		// 12345678901234567890123456789012345678901234567890123
+		"Server Version: %S             %S\n"
+		),
+		&versionName, &iDisplayArray[EAuthorisationSettingItem]
+		);
+
+	
+	iConsole->Printf(_L("Service: %S    Device: %S\n"), 
+			&iDisplayArray[EUsbServiceStateItem], &iDisplayArray[EUsbDeviceStateItem]);
+	iConsole->Printf(_L("NCM Iap:%2d state:%S IP:%S\n"), 
+			iLocalIapId, &iDisplayArray[ENcmConnStatusItem], &iDisplayArray[ENcmConnIpItem]);
+	iConsole->Printf(_L("Active:%S NcmConnection:%S\n"), 
+			&iDisplayArray[ENcmBtPanItem], &iDisplayArray[ENcmAgentStateItem]);
+    iConsole->Printf(_L("Ncm connection:%S\n"), &iDisplayArray[ENcmConnectionStateItem]);
+	
+	if ((iHelp > 0) && (iHelp <=9))
+		{
+		iConsole->Printf(_L("Press 0 to quit help\n\n"));
+		//Display the command help
+		iKeys->PrintHelp(iHelp);
+		}
+	else
+		{
+		iConsole->Printf(_L("Press 1 to 9 to get menu help\n\n"));
+		//Display the event list
+		TDblQueIter<CUsbNcmConsoleEvent> iter(iEventList);
+		CUsbNcmConsoleEvent* event = NULL;
+		while((event = iter++) != NULL)
+			{
+			iConsole->Printf(event->iEvent.Left(NUM_CHARACTERS_ON_LINE-1));
+			iConsole->Printf(_L("\n"));
+			}
+		}
+	}
+	
+
+void CUsbNcmConsole::CreateDisplayItemL()
+/**
+Init the display item.
+*/
+	{
+	for(TInt i = 0; i < ELastItem; i++)
+		{
+		RBuf buf;
+		iDisplayArray.AppendL(buf);
+		iDisplayArray[i].CreateL(gDisplayItemLength[i]);
+		}
+	}
+
+void CUsbNcmConsole::SetDisplayItem(TInt aIndex, TDes& aInfo)
+/**
+Called by commands and monitors to show the changed info in screen
+*/
+	{
+	//Prevent array is out of bound
+	__ASSERT_ALWAYS(((aIndex < ELastItem) && (aIndex >= 0)), Panic(ENcmDisplayItemVaild));
+	
+	iDisplayArray[aIndex].SetLength(0);
+	iDisplayArray[aIndex].Copy(aInfo);
+	
+	ScheduleDraw('E');
+	}
+
+TInt CUsbNcmConsole::LocalIapId() const
+	{
+	return iLocalIapId;
+	}
+
+const TDes& CUsbNcmConsole::GetDisplayItem(TInt aIndex)
+	{
+	//Prevent array is out of bound
+	__ASSERT_ALWAYS(((aIndex < ELastItem) && (aIndex >= 0)), Panic(ENcmDisplayItemVaild));
+
+	return iDisplayArray[aIndex];
+	}
+
+
+TInt CUsbNcmConsole::DoCommandCallback(TAny *aThisPtr)
+	{
+	CNcmCommandBase* command = static_cast<CNcmCommandBase*>(aThisPtr);
+	TRAPD(err,command->DoCommandL());
+	if(err != KErrNone)
+		{
+		User::Panic(_L("DoCommandCallback"), err);
+		}
+	return err;
+	}
+
+
+TInt CUsbNcmConsole::DrawAvailableIapsL()
+/**
+Display commsdb's iaps on console
+@return the count of iaps
+*/
+	{
+	LOG_FUNC
+	__FLOG_STATIC0(KSubSys, KLogComponent , _L8("CNcmTestUtil::DrawAvailableIapsL"));
+
+	iConsole->Printf(_L("CommDB IAPs:\n"));
+	iConsole->Printf(_L("ID: Name\n"));
+	
+	//Get commsdb handle
+	CCommsDatabase* db = CCommsDatabase::NewL();
+	__FLOG_STATIC0(KSubSys, KLogComponent , _L8("Get CommsDatabase ok"));	
+	CleanupStack::PushL(db);
+	
+	//Get Iap table infomation
+	CCommsDbTableView* iapTableView = db->OpenTableLC(TPtrC(IAP));
+	__FLOG_STATIC0(KSubSys, KLogComponent , _L8("OpenTableLC ok"));
+
+	
+	TUint32 iapId;
+	TBuf<128> iapName;
+	TInt iapCount = 0;
+	
+	for (TInt iapTableErr = iapTableView->GotoFirstRecord(); iapTableErr == KErrNone; iapTableErr = iapTableView->GotoNextRecord())
+		{
+		//Get every IAP
+		iapTableView->ReadTextL(TPtrC(COMMDB_NAME), iapName);
+		iapTableView->ReadUintL(TPtrC(COMMDB_ID), iapId);
+		
+		__FLOG_STATIC2(KSubSys, KLogComponent , _L8("Read: %d: %S"), iapId, &iapName);
+
+		iConsole->Printf(_L("%d: %S\n"), iapId, &iapName);		
+		iapCount++;
+		}
+
+	if (0 == iapCount)
+		{
+		iConsole->Printf(_L("No available IAP!\n"));
+		}
+		
+	CleanupStack::PopAndDestroy(2); // iapTableView, db
+	return iapCount;
+	
+	}
+
+TBool CUsbNcmConsole::AttachConnectionL(TInt aIap, RConnection& aConnection)
+/**
+Try to attach the connection specified by iIapId. If attach failed or no specified connection,return false
+*/
+	{
+	LOG_FUNC
+	__FLOG_STATIC1(KSubSys, KLogComponent , _L8("AttachConnectionL aIap=%d"), aIap);
+
+	TBool result = ETrue;
+	TUint count = 0;
+	//Get active connections
+	User::LeaveIfError(aConnection.EnumerateConnections(count));
+	__FLOG_STATIC2(KSubSys, KLogComponent , _L8("active connection count = %d, watch iap = %d"), count, aIap);
+
+	TBool hasConnection = EFalse;
+	for(TInt i = 1; i <= count; i++)
+		{
+		TPckgBuf<TConnectionInfo> info;
+		User::LeaveIfError(aConnection.GetConnectionInfo(i,info));
+		TUint32 id = info().iIapId;
+		__FLOG_STATIC2(KSubSys, KLogComponent , _L8("aIap=%d, id=%d"), aIap, id);
+		
+		if(id == aIap)
+			{
+			hasConnection = ETrue;
+			//The connection is the connection specified by aIap
+			__FLOG_STATIC0(KSubSys, KLogComponent , _L8("Got it!"));			
+
+			//Attach the connection
+			TInt err = aConnection.Attach(info, RConnection::EAttachTypeMonitor);	
+			if(err != KErrNone)
+				{
+				result = EFalse;
+				__FLOG_STATIC1(KSubSys, KLogComponent , _L8("Attach error[%d]"), err);
+				}
+			else
+				{
+				__FLOG_STATIC0(KSubSys, KLogComponent , _L8("Attach it!"));	
+				}
+			break;
+			}
+		}
+
+	if(!hasConnection)
+		{
+		//connection not found;
+		__FLOG_STATIC0(KSubSys, KLogComponent , _L8("No connection found!"));			
+		result = EFalse;		
+		}
+
+	return result;
+
+	}