merge
authorTom Sutcliffe <thomas.sutcliffe@accenture.com>
Wed, 22 Sep 2010 10:56:39 +0100
changeset 79 f3d01c9dd099
parent 78 6a2083f7eeb8 (diff)
parent 76 b9edfff731fb (current diff)
child 80 ed15378514e0
merge
documentation/change_history.pod
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build/s60/tb92/vt100usbcons_preamble.script	Wed Sep 22 10:56:39 2010 +0100
@@ -0,0 +1,17 @@
+#!fshell
+# vt100usbcons_preamble.script
+# 
+# Copyright (c) 2010 Accenture. All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the "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:
+# Accenture - Initial contribution
+#
+
+# This is needed to prevent TRK from hogging the USB port on DFS.
+
+kill --all --match trkserver*
+sleep 1 # Give USB time to clean up trk's death
--- a/commands/usb/usb.cpp	Fri Sep 17 20:28:05 2010 +0100
+++ b/commands/usb/usb.cpp	Wed Sep 22 10:56:39 2010 +0100
@@ -68,6 +68,9 @@
 	}
 
 #define CASE_LIT(x) case x: { _LIT(KName, #x); return &KName; }
+#define CASE_LIT2(x, y) case x: { _LIT(KName, y); return &KName; }
+
+_LIT(KUnknown, "?");
 
 const TDesC* DeviceState(TUsbDeviceState aState)
 	{
@@ -82,7 +85,6 @@
 		CASE_LIT(EUsbDeviceStateSuspended);
 		default:
 			{
-			_LIT(KUnknown, "?");
 			return &KUnknown;
 			}
 		}
@@ -98,10 +100,19 @@
 		CASE_LIT(EUsbServiceStopping);
 		CASE_LIT(EUsbServiceFatalError);
 		default:
-			{
-			_LIT(KUnknown, "?");
 			return &KUnknown;
-			}
+		}
+	}
+
+const TDesC* ClassName(TUid aClass)
+	{
+	switch (aClass.iUid)
+		{
+		CASE_LIT2(0x101FBF22, "ACM");
+		CASE_LIT2(0x101fbf24, "Obex");
+		CASE_LIT2(0x10204bbc, "Mass storage");
+		default:
+			return &KUnknown;
 		}
 	}
 
@@ -118,10 +129,26 @@
 	Printf(_L("Usb Service state = %S (%d)\r\n"), ServiceState(servicestate), servicestate);
 
 	RArray<TInt> ids;
+	CleanupClosePushL(ids);
 	LeaveIfErr(iUsb.GetPersonalityIds(ids), _L("Couldn't get personalities ids"));
 	for (TInt i = 0; i < ids.Count(); i++)
 		{
 		Printf(_L("Personality %d\r\n"), ids[i]);
+		RArray<TUid> classUids;
+		CleanupClosePushL(classUids);
+		TInt err = iUsb.GetSupportedClasses(ids[i], classUids);
+		if (err)
+			{
+			PrintWarning(_L("Couldn't get classes for personality %d, err=%d"), ids[i], err);
+			}
+		else
+			{
+			for (TInt classIdx = 0; classIdx < classUids.Count(); classIdx++)
+				{
+				Printf(_L("    0x%08x (%S)\r\n"), classUids[classIdx], ClassName(classUids[classIdx]));
+				}
+			}
+		CleanupStack::PopAndDestroy(&classUids);
 		}
 
 	if (iArguments.IsPresent(&iPersonality))
@@ -132,4 +159,5 @@
 		LeaveIfErr(stat.Int(), _L("Couldn't start USB personality %d"), iPersonality);
 		Printf(_L("USB started ok.\r\n"));
 		}
+	CleanupStack::PopAndDestroy(&ids);
 	}
--- a/core/group/autostart.script	Fri Sep 17 20:28:05 2010 +0100
+++ b/core/group/autostart.script	Wed Sep 22 10:56:39 2010 +0100
@@ -11,4 +11,4 @@
 # Accenture - Initial contribution
 #
 
-source $SCRIPT_PATH\comm.script
+source comm.script
--- a/core/group/comm.script	Fri Sep 17 20:28:05 2010 +0100
+++ b/core/group/comm.script	Wed Sep 22 10:56:39 2010 +0100
@@ -31,6 +31,9 @@
 # QEMU simulator - assumes you're using 2nd emulated serial port for fshell, ie with options similar to "-serial file:rdebug.txt -serial COMx"
 variant qemu && export ARGS "--console vt100busdevcons --console-title pdd=eserial,ldd=ecomm,rate=115200,port=1"
 
+# Bridge - terminal keyboard is broken for some reason, but USB now works
+variant -u 0x85001100 && export ARGS "--console vt100usbcons --console-title port=ACM::1,personality=1"
+
 # Add new variants here
 
 
--- a/documentation/change_history.pod	Fri Sep 17 20:28:05 2010 +0100
+++ b/documentation/change_history.pod	Wed Sep 22 10:56:39 2010 +0100
@@ -28,6 +28,16 @@
 
 =back
 
+=head2 Release 002 [Not yet released]
+
+=over 5
+
+=item *
+
+Added support for automatically starting a USB personality to vt100usbcons via a new C<personality=x> key-value pair. See the L<vt100usbcons|vt100cons/usb variant> documentation for more information.
+
+=back
+
 =head2 Release 001
 
 =over 5
--- a/plugins/consoles/vt100cons/doc/vt100cons.pod	Fri Sep 17 20:28:05 2010 +0100
+++ b/plugins/consoles/vt100cons/doc/vt100cons.pod	Wed Sep 22 10:56:39 2010 +0100
@@ -122,7 +122,27 @@
 
 =head2 USB Variant
 
-Vt100usbcons behaves the same as the serial variant, with the exception that it waits for USB to enumerate into a personality that supports ACM if not already present. In other words it waits for the USB cable to be inserted before trying to open the port. If necessary it also waits for the user to select a config that includes some USB serial ports. It expects the C<--console-title> argument to be of the format C<ACM::x> where x is the port number. This number is platform-specific but is usually 0 or 1. Generally this will be taken care of already in the platform-specific build of the toolkit and you can just launch the "fshell (USB)" icon.
+Vt100usbcons behaves the same as the serial variant, with the exception that it waits for USB to enumerate into a personality that supports ACM if not already present. In other words it waits for the USB cable to be inserted before trying to open the port. If necessary it also waits for the user to select a config that includes some USB serial ports. 
+
+vt100usbcons.dll is configured via the C<--console-title> string in a similar way to the serial variant. The follow keyword / value pairs are supported:
+
+=over 5
+
+=item * C<port=name>
+
+The USB port name. This is platform specific but is usually C<ACM::0> or C<ACM::1>. Generally this will be taken care of already in the platform-specific configuration and you can just launch the "fshell (USB)" icon or run "comm.script".
+
+=item * C<personality=value>
+
+If it is necessary to start a USB personality before connecting, specify the personality number here, for example C<personality=1>. This parameter is not usually needed except on some text-shell builds.
+
+=back
+
+Example usage:
+
+  fshell --console vt100usbcons --console-title port=ACM::1,personality=1
+
+For compatibility with earlier releases, the C<port=> may be ommitted if there are no other configuration parameters. For example "fshell --console vt100usbcons --console-title ACM::1".
 
 =head2 Bluetooth Variant
 
--- a/plugins/consoles/vt100cons/src/usb/vtc_usb.cpp	Fri Sep 17 20:28:05 2010 +0100
+++ b/plugins/consoles/vt100cons/src/usb/vtc_usb.cpp	Wed Sep 22 10:56:39 2010 +0100
@@ -20,6 +20,14 @@
 	return new CUsbConsole;
 	}
 	
+TUsbPortConfig::TUsbPortConfig()
+	:iPort(KNullDesC), iPersonality(-1)
+	{
+	}
+
+#define ErrOrDebug(err) (((err) < 0  && (err) != KErrAlreadyExists) ? EError : EDebug)
+
+
 //______________________________________________________________________________
 //						CUsbConsole
 CUsbConsole::CUsbConsole()
@@ -33,18 +41,19 @@
 	
 void CUsbConsole::ConstructL(const TDesC& aTitle)
 	{
+	TUsbPortConfig portConfig;
+	User::LeaveIfError(ReadConfig(aTitle, portConfig));
+
 	User::LeaveIfError(iUsb.Connect());
 	
 	TRequestStatus stat;
-	// assume USB device already started
-	/*iUsb.Start(stat);
-	User::WaitForRequest(stat);
-	// KErrAccessDenied returned if already started;
-	if (stat.Int()!=KErrAccessDenied)
+	if (portConfig.iPersonality >= 0)
 		{
-		Message(EError, KUsbError, stat.Int(), 1);
-		User::LeaveIfError(stat.Int());
-		}*/
+		iUsb.TryStart(portConfig.iPersonality, stat);
+		User::WaitForRequest(stat);
+		User::After(500000); // Ugh need to wait for the TryStart to finish. There's probably some other async notification I could wait on but I'm in a hurry to get this working...
+		Message(ErrOrDebug(stat.Int()), _L("Starting USB personality %d returned %d"), portConfig.iPersonality, stat.Int());
+		}
 
 	// Wait for an enumeration that supports ACM (this is so that if the device defaulted to say mass storage and was then reconfigured to a personality with ACM, we wait for the ACM reconfiguration
 	TBool gotAcm = EFalse;
@@ -52,12 +61,15 @@
 		{
 		TUsbDeviceState usbState;
 		User::LeaveIfError(iUsb.GetDeviceState(usbState));
-		if (usbState & EUsbDeviceStateConfigured)
+		if (usbState & (EUsbDeviceStateConfigured|EUsbDeviceStatePowered)) // We should only need to check for EUsbDeviceStateConfigured, but some HW doesn't go to configured state if the cable is inserted before USB is started
 			{
 			// Check if we have ACM
 			TInt currentPersonality;
-			User::LeaveIfError(iUsb.GetCurrentPersonalityId(currentPersonality));
-			User::LeaveIfError(iUsb.ClassSupported(currentPersonality, KECACMUid, gotAcm));
+			TInt err = iUsb.GetCurrentPersonalityId(currentPersonality);
+			if (!err)
+				{
+				err = iUsb.ClassSupported(currentPersonality, KECACMUid, gotAcm);
+				}
 			_LIT(KGotIt, "Current USB personality has ACM, proceeding");
 			_LIT(KNotGotIt, "Current USB personality doesn't have ACM, waiting for re-enumeration");
 			if (gotAcm) Message(EInformation, KGotIt);
@@ -69,7 +81,7 @@
 			// We're not enumerated, or we are but don't have ACM. So wait for a (re-)enumeration
 			_LIT(KWaitingForEnumeration, "Waiting for USB enumeration (please connect USB cable)");
 			Message(EInformation, KWaitingForEnumeration);
-			iUsb.DeviceStateNotification(EUsbDeviceStateConfigured, usbState, stat);
+			iUsb.DeviceStateNotification(EUsbDeviceStateConfigured|EUsbDeviceStatePowered, usbState, stat);
 			User::WaitForRequest(stat);
 			if (stat.Int() != KErrNone)
 				{
@@ -77,8 +89,8 @@
 				Message(EError, KUsbError, stat.Int());
 				User::Leave(stat.Int());
 				}
-			_LIT(KUsbEnumerated, "USB cable connected.");
-			Message(EInformation, KUsbEnumerated);
+			_LIT(KUsbEnumerated, "USB state changed to %d.");
+			Message(EInformation, KUsbEnumerated, usbState);
 			}
 		}
 	
@@ -107,7 +119,46 @@
 		Message(EInformation, _L("Preamble script failed with %d"), err);
 		}
 
-	//TODO should we ensure that the port passed in here is an ACM::%s port?
-	Message(EInformation, _L("Opening %S"), &aTitle);
-	CVtcSerialConsole::ConstructL(aTitle);
+	Message(EInformation, _L("Opening %S"), &portConfig.iPort);
+	CVtcSerialConsole::ConstructL(portConfig.iPort);
 	}
+
+TInt CUsbConsole::ReadConfig(const TDesC& aConfigDes, TUsbPortConfig& aConfig)
+	{
+	_LIT(KKeywordPort, "port");
+	_LIT(KKeywordPersonality, "personality");
+
+	TBool keywordFound(EFalse);
+	TLex lex(aConfigDes);
+	while (!lex.Eos())
+		{
+		TPtrC keyword;
+		TPtrC value;
+		TInt err = ReadKeywordValuePair(lex, keyword, value);
+		if (err != KErrNone)
+			{
+			break;
+			}
+
+		if (keyword == KKeywordPort)
+			{
+			aConfig.iPort.Set(value);
+			keywordFound = ETrue;
+			}
+		else if (keyword == KKeywordPersonality)
+			{
+			TLex lex(value);
+			TInt err = lex.Val(aConfig.iPersonality);
+			if (err) return err;
+			keywordFound = ETrue;
+			}
+		}
+
+	if (!keywordFound)
+		{
+		// Treat unrecognised string as a port (to preserve backwards compatibility with earlier releases).
+		aConfig.iPort.Set(aConfigDes);
+		}
+
+	return KErrNone;
+	}
--- a/plugins/consoles/vt100cons/src/usb/vtc_usb.h	Fri Sep 17 20:28:05 2010 +0100
+++ b/plugins/consoles/vt100cons/src/usb/vtc_usb.h	Wed Sep 22 10:56:39 2010 +0100
@@ -17,6 +17,15 @@
 #include <usbman.h>
 #include "vtc_serial.h"
 
+class TUsbPortConfig
+	{
+public:
+	TUsbPortConfig();
+
+	TPtrC iPort;
+	TInt iPersonality;
+	};
+
 NONSHARABLE_CLASS(CUsbConsole) : public CVtcSerialConsole
 	{
 public:
@@ -25,6 +34,9 @@
 private: // From CVtcSerialConsole.
 	virtual void ConstructL(const TDesC& aTitle);
 private:
+	TInt ReadConfig(const TDesC& aConfigDes, TUsbPortConfig& aConfig);
+
+private:
 	RUsb iUsb;
 	};
 
--- a/plugins/consoles/vt100cons/src/vtc_busdevcons.cpp	Fri Sep 17 20:28:05 2010 +0100
+++ b/plugins/consoles/vt100cons/src/vtc_busdevcons.cpp	Wed Sep 22 10:56:39 2010 +0100
@@ -106,7 +106,8 @@
 		else if (keyword == KKeywordPort)
 			{
 			TLex lex(value);
-			User::LeaveIfError(lex.Val(aConfig.iPort));
+			TInt err = lex.Val(aConfig.iPort);
+			if (err) return err;
 			keywordFound = ETrue;
 			}
 		else if (keyword == KKeywordRate)