Revision: 201001 PDK_3.0.g
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 02:02:59 +0200
changeset 0 c9bc50fca66e
child 3 be39042dca40
child 4 dc8eed082680
child 12 e9d124871462
Revision: 201001 Kit: 201005
group/bld.inf
layers.sysdef.xml
package_definition.xml
sysdef_1_4_0.dtd
usb_info/usb_metadata/usb_metadata.mrp
usb_plat/group/bld.inf
usbmgmt/usbclassandmgrdocs/USBDI-Unit Test Design.EAP
usbmgmt/usbclassandmgrdocs/USB_Control_App_UML_Diagrams.eap
usbmgmt/usbclassandmgrdocs/USB_FDF_Model.EAP
usbmgmt/usbclassandmgrdocs/USB_Host_and_OTG_Test_Harness_Design.eap
usbmgmt/usbclassandmgrdocs/USB_MSMM_Design.eap
usbmgmt/usbclassandmgrdocs/usb_documentation.history.xml
usbmgmt/usbclassandmgrdocs/usb_documentation.mrp
usbmgmt/usbmgr/conf/usbmanager.confml
usbmgmt/usbmgr/device/bld.inf
usbmgmt/usbmgr/device/classcontroller/BWINS/usbclasscontrolleru.def
usbmgmt/usbmgr/device/classcontroller/EABI/usbclasscontrollerU.DEF
usbmgmt/usbmgr/device/classcontroller/SRC/CUsbClassControllerBase.cpp
usbmgmt/usbmgr/device/classcontroller/SRC/CUsbClassControllerIterator.cpp
usbmgmt/usbmgr/device/classcontroller/SRC/CUsbClassControllerPlugIn.cpp
usbmgmt/usbmgr/device/classcontroller/group/UsbClassController.mmp
usbmgmt/usbmgr/device/classcontroller/group/bld.inf
usbmgmt/usbmgr/device/classcontroller/public/CUsbClassControllerBase.h
usbmgmt/usbmgr/device/classcontroller/public/CUsbClassControllerIterator.h
usbmgmt/usbmgr/device/classcontroller/public/CUsbClassControllerPlugIn.h
usbmgmt/usbmgr/device/classcontroller/public/MUsbClassControllerNotify.h
usbmgmt/usbmgr/device/classdrivers/acm/bld.inf
usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/INC/CUsbACMClassController.h
usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/SRC/101fbf20.rss
usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/SRC/CUsbACMClassController.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/SRC/CUsbAcmClassImpCollection.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/group/AcmClassController.mmp
usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/group/AcmClassControllerBase.mmp
usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/group/NumberOfAcmFunctions.ini
usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/group/bld.inf
usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/group/t_regport_AcmClassController.mmp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/EABI/acmserverU.def
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/bwins/acmserverU.def
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/group/acmserver.mmp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/group/bld.inf
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/inc/acmserverclient.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/inc/acmserverimpl.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/public/acmserver.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/src/acmserver.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/src/acmserverclient.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/src/acmserverimpl.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/bld.inf
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/BWINS/ECACMu.def
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/EABI/ecacmU.DEF
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/group/BLD.INF
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/group/ECACM.MMP
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/group/ecacm.ini
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmConstants.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmPanic.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmPort.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmPortFactory.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmPortObserver.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmReader.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmUtils.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmWriter.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ActiveDataAvailableNotifier.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ActiveReadOneOrMoreReader.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ActiveReader.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ActiveWriter.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/BreakController.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/BreakObserver.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/CdcAcmClass.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/CdcControlInterface.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/CdcControlInterfaceReader.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/CdcControlInterfaceRequestHandler.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/CdcDataInterface.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/CdcInterfaceBase.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ClassDescriptor.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/HostPushedChangeObserver.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/LittleEndianPacker.INL
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/NotifyDataAvailableObserver.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ReadObserver.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ReadOneOrMoreObserver.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/RegistrationPort.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/RequestHeader.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/WriteObserver.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/acmcapability.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/acmcontroller.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/acmserver.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/acmserversecuritypolicy.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/acmsession.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/linkstatenotifier.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/public/AcmConfig.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/public/AcmInterface.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/public/acmserverconsts.h
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/AcmPort.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/AcmPortFactory.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/AcmReader.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/AcmWriter.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ActiveDataAvailableNotifier.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ActiveReadOneOrMoreReader.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ActiveReader.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ActiveWriter.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/BreakController.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/CdcAcmClass.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/CdcControlInterface.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/CdcControlInterfaceReader.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/CdcDataInterface.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/CdcInterfaceBase.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ClassDescriptor.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/DllMain.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/RegistrationPort.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/RequestHeader.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/acmserver.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/acmsession.cpp
usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/linkstatenotifier.cpp
usbmgmt/usbmgr/device/classdrivers/bld.inf
usbmgmt/usbmgr/device/classdrivers/ms/bld.inf
usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/group/BLD.INF
usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/group/msclasscontroller.mmp
usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/inc/CUsbMsClassController.h
usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/inc/usbms.rh
usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/src/10204bbb.rss
usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/src/CUsbMsClassController.cpp
usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/src/CUsbMsClassImpCollection.cpp
usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/src/usbms.rss
usbmgmt/usbmgr/device/classdrivers/obex/bld.inf
usbmgmt/usbmgr/device/classdrivers/obex/classcontroller/group/BLD.INF
usbmgmt/usbmgr/device/classdrivers/obex/classcontroller/group/ObexClassController.mmp
usbmgmt/usbmgr/device/classdrivers/obex/classcontroller/inc/CUsbObexClassController.h
usbmgmt/usbmgr/device/classdrivers/obex/classcontroller/src/101fbf27.rss
usbmgmt/usbmgr/device/classdrivers/obex/classcontroller/src/CUsbObexClassController.cpp
usbmgmt/usbmgr/device/classdrivers/obex/classcontroller/src/CUsbObexClassImpCollection.cpp
usbmgmt/usbmgr/device/classdrivers/whcm/bld.inf
usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/INC/CUsbWHCMClassController.h
usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/SRC/101fbf23.rss
usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/SRC/CUsbWHCMClassController.cpp
usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/SRC/CUsbWHCMClassImpCollection.cpp
usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/group/WHCMClassController.mmp
usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/group/bld.inf
usbmgmt/usbmgr/device/inf-files/symusb2k-XP.inf
usbmgmt/usbmgr/device/inf-files/symusb_98_6.inf
usbmgmt/usbmgr/device/inf-files/symusb_98_7.inf
usbmgmt/usbmgr/device/inf-files/symusb_98_9.inf
usbmgmt/usbmgr/device/inf-files/symusb_com.inf
usbmgmt/usbmgr/group/BLD.INF
usbmgmt/usbmgr/group/RELEASE.TXT
usbmgmt/usbmgr/group/Usbman.iby
usbmgmt/usbmgr/group/Usbmanbin.iby
usbmgmt/usbmgr/group/Usbmanrsc.iby
usbmgmt/usbmgr/group/usb.iby
usbmgmt/usbmgr/group/usb_manager.history.xml
usbmgmt/usbmgr/group/usb_manager.mrp
usbmgmt/usbmgr/host/bld.inf
usbmgmt/usbmgr/host/fdf/production/BLD.INF
usbmgmt/usbmgr/host/fdf/production/client/BWINS/usbhoststacku.def
usbmgmt/usbmgr/host/fdf/production/client/EABI/usbhoststacku.def
usbmgmt/usbmgr/host/fdf/production/client/group/bld.inf
usbmgmt/usbmgr/host/fdf/production/client/group/usbhoststack.mmp
usbmgmt/usbmgr/host/fdf/production/client/group/usbhoststack_base.mmp
usbmgmt/usbmgr/host/fdf/production/client/group/usbhoststack_over_dummyusbdi.mmp
usbmgmt/usbmgr/host/fdf/production/client/group/usbhoststack_over_dummyusbdi_bld.inf
usbmgmt/usbmgr/host/fdf/production/client/public/usbhosterrors.h
usbmgmt/usbmgr/host/fdf/production/client/public/usbhoststack.h
usbmgmt/usbmgr/host/fdf/production/client/src/session.cpp
usbmgmt/usbmgr/host/fdf/production/fdcbase/BWINS/fdcbaseu.def
usbmgmt/usbmgr/host/fdf/production/fdcbase/EABI/fdcbaseu.def
usbmgmt/usbmgr/host/fdf/production/fdcbase/group/bld.inf
usbmgmt/usbmgr/host/fdf/production/fdcbase/group/fdcbase.mmp
usbmgmt/usbmgr/host/fdf/production/fdcbase/group/fdcbase_base_bld.inf
usbmgmt/usbmgr/host/fdf/production/fdcbase/group/fdcbase_over_dummyusbdi_bld.inf
usbmgmt/usbmgr/host/fdf/production/fdcbase/public/fdcinterface.h
usbmgmt/usbmgr/host/fdf/production/fdcbase/public/fdcplugin.h
usbmgmt/usbmgr/host/fdf/production/fdcbase/public/fdcplugin.hrh
usbmgmt/usbmgr/host/fdf/production/fdcbase/public/fdcpluginobserver.h
usbmgmt/usbmgr/host/fdf/production/fdcbase/src/fdcplugin.cpp
usbmgmt/usbmgr/host/fdf/production/fdcbase/src/fdcpluginobserver.cpp
usbmgmt/usbmgr/host/fdf/production/fdf.iby
usbmgmt/usbmgr/host/fdf/production/server/group/bld.inf
usbmgmt/usbmgr/host/fdf/production/server/group/fdf.mmp
usbmgmt/usbmgr/host/fdf/production/server/group/fdf_base.mmp
usbmgmt/usbmgr/host/fdf/production/server/group/fdf_over_dummyusbdi.mmp
usbmgmt/usbmgr/host/fdf/production/server/group/fdf_over_dummyusbdi_bld.inf
usbmgmt/usbmgr/host/fdf/production/server/inc/activewaitforbusevent.h
usbmgmt/usbmgr/host/fdf/production/server/inc/activewaitforecomevent.h
usbmgmt/usbmgr/host/fdf/production/server/inc/deviceproxy.h
usbmgmt/usbmgr/host/fdf/production/server/inc/event.h
usbmgmt/usbmgr/host/fdf/production/server/inc/eventqueue.h
usbmgmt/usbmgr/host/fdf/production/server/inc/fdcproxy.h
usbmgmt/usbmgr/host/fdf/production/server/inc/fdf.h
usbmgmt/usbmgr/host/fdf/production/server/inc/fdfserver.h
usbmgmt/usbmgr/host/fdf/production/server/inc/fdfsession.h
usbmgmt/usbmgr/host/fdf/production/server/inc/utils.h
usbmgmt/usbmgr/host/fdf/production/server/public/fdfapi.h
usbmgmt/usbmgr/host/fdf/production/server/public/fdfcaps.mmh
usbmgmt/usbmgr/host/fdf/production/server/src/activewaitforbusevent.cpp
usbmgmt/usbmgr/host/fdf/production/server/src/activewaitforecomevent.cpp
usbmgmt/usbmgr/host/fdf/production/server/src/deviceproxy.cpp
usbmgmt/usbmgr/host/fdf/production/server/src/event.cpp
usbmgmt/usbmgr/host/fdf/production/server/src/eventqueue.cpp
usbmgmt/usbmgr/host/fdf/production/server/src/fdcproxy.cpp
usbmgmt/usbmgr/host/fdf/production/server/src/fdf.cpp
usbmgmt/usbmgr/host/fdf/production/server/src/fdfserver.cpp
usbmgmt/usbmgr/host/fdf/production/server/src/fdfsession.cpp
usbmgmt/usbmgr/host/fdf/production/server/src/main.cpp
usbmgmt/usbmgr/host/fdf/production/server/src/utils.cpp
usbmgmt/usbmgr/host/fdf/reference/reffdc/group/bld.inf
usbmgmt/usbmgr/host/fdf/reference/reffdc/group/reffdc.mmp
usbmgmt/usbmgr/host/fdf/reference/reffdc/inc/reffdc.h
usbmgmt/usbmgr/host/fdf/reference/reffdc/src/reffdc.cpp
usbmgmt/usbmgr/host/fdf/reference/reffdc/src/reffdc.rss
usbmgmt/usbmgr/host/fdf/reference/reffdc/src/reffdcmain.cpp
usbmgmt/usbmgr/host/fdf/test/fdf_over_dummyusbdi/bld.inf
usbmgmt/usbmgr/host/fdf/test/t_fdf/BLD.INF
usbmgmt/usbmgr/host/fdf/test/t_fdf/FdfTest.cpp
usbmgmt/usbmgr/host/fdf/test/t_fdf/FdfTest.h
usbmgmt/usbmgr/host/fdf/test/t_fdf/Tests.h
usbmgmt/usbmgr/host/fdf/test/t_fdf/activeconsole.cpp
usbmgmt/usbmgr/host/fdf/test/t_fdf/activeconsole.h
usbmgmt/usbmgr/host/fdf/test/t_fdf/activetest.cpp
usbmgmt/usbmgr/host/fdf/test/t_fdf/t_fdf.iby
usbmgmt/usbmgr/host/fdf/test/t_fdf/t_fdf.mmp
usbmgmt/usbmgr/host/fdf/test/t_fdf/testbase.cpp
usbmgmt/usbmgr/host/fdf/test/t_fdf/testbase.h
usbmgmt/usbmgr/host/fdf/test/t_fdf/testmanager.h
usbmgmt/usbmgr/host/functiondrivers/ms/bld.inf
usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/group/bld.inf
usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/group/msfdc.iby
usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/group/msfdc.mmp
usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/inc/msfdc.h
usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/inc/utils.h
usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/src/msfdc.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/src/msfdc.rss
usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/src/msfdcmain.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/bwins/msmmsession_over_dummycomponentu.def
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/eabi/msmmsession_over_dummycomponentu.def
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/eabi/msmmsessionu.def
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/group/bld.inf
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/group/msmmclient.mmp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/group/msmmclient_base.mmp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/group/msmmclient_over_dummycomponent.mmp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/public/msmmclient.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/src/msmmclient.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/group/bld.inf
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/group/msmm_over_dummycomponent_bld.inf
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/group/usbhostmsmm.iby
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/inc/srvdef.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/inc/srvpanic.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/conf/usbmanager_10285c46.crml
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/data/10285c46.rss
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/data/10285c46.txt
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/group/bld.inf
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/group/referencepolicyplugin.mmh
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/group/referencepolicyplugin.mmp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/group/refpp_over_dummycomponent.mmp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/inc/referenceplugin.hrh
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/inc/referencepolicyplugin.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/inc/refppnotificationman.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/src/proxy.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/src/referencepolicyplugin.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/src/refppnotificationman.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/group/bld.inf
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/group/refppnotifier.iby
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/group/refppnotifier.mmp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/inc/refppdialog.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/inc/refppnotifier.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/inc/refppnotifier.hrh
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/src/dialog.rss
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/src/refppdialog.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/src/refppnotifier.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/src/refppnotifier.rss
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/group/bld.inf
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/group/msmmserver.mmp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/group/msmmserver_base.mmp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/group/msmmserver_over_dummycomponent.mmp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/eventhandler.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/eventhandler.inl
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/eventqueue.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/eventqueue.inl
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/handlerinterface.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmm_internal_def.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmmengine.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmmnodebase.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmmserver.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmmserver.inl
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmmsession.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmmterminator.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/srvsec.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/subcommandbase.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/subcommands.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/hostmscaps.mmh
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/msmm_policy_def.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/msmm_pub_def.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/msmmpolicypluginbase.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/msmmpolicypluginbase.inl
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/policyplugin.hrh
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/policypluginnotifier.hrh
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/srverr.h
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/eventhandler.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/eventqueue.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/main.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmengine.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmnodebase.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmserver.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmsession.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmterminator.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/subcommandbase.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/subcommands.cpp
usbmgmt/usbmgr/host/functiondrivers/ms/msmm/test/msmm_over_dummycomponent/bld.inf
usbmgmt/usbmgr/inifile/inc/inifile.h
usbmgmt/usbmgr/inifile/src/inifile.cpp
usbmgmt/usbmgr/logger/BWINS/usbloggerU.DEF
usbmgmt/usbmgr/logger/EABI/usbloggerU.DEF
usbmgmt/usbmgr/logger/group/BLD.INF
usbmgmt/usbmgr/logger/group/usblogger.MMP
usbmgmt/usbmgr/logger/group/usblogger.mmh
usbmgmt/usbmgr/logger/public/usblogger.h
usbmgmt/usbmgr/logger/src/usblogger.cpp
usbmgmt/usbmgr/test/cit/ROMConfig/group/bld.inf
usbmgmt/usbmgr/test/cit/ROMConfig/group/testserversymbianexcludeusb.mmp
usbmgmt/usbmgr/test/cit/ROMConfig/inc/cteststepusbromconfig001.h
usbmgmt/usbmgr/test/cit/ROMConfig/inc/cteststepusbromconfig002.h
usbmgmt/usbmgr/test/cit/ROMConfig/inc/cteststepusbromconfig003.h
usbmgmt/usbmgr/test/cit/ROMConfig/inc/cteststepusbromconfig004.h
usbmgmt/usbmgr/test/cit/ROMConfig/inc/cteststepusbromconfigbase.h
usbmgmt/usbmgr/test/cit/ROMConfig/inc/testserversymbianexcludeusb.h
usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_CIT_P581_UsbExcluded.script
usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_CIT_P581_UsbIncluded.script
usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_INC_ROMCONFIG_001.script
usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_INC_ROMCONFIG_002.script
usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_INC_ROMCONFIG_003.script
usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_INC_ROMCONFIG_004.script
usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_ROMCONFIG_001.script
usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_ROMCONFIG_002.script
usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_ROMCONFIG_003.script
usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_ROMCONFIG_004.script
usbmgmt/usbmgr/test/cit/ROMConfig/src/cteststepusbromconfig001.cpp
usbmgmt/usbmgr/test/cit/ROMConfig/src/cteststepusbromconfig002.cpp
usbmgmt/usbmgr/test/cit/ROMConfig/src/cteststepusbromconfig003.cpp
usbmgmt/usbmgr/test/cit/ROMConfig/src/cteststepusbromconfig004.cpp
usbmgmt/usbmgr/test/cit/ROMConfig/src/cteststepusbromconfigbase.cpp
usbmgmt/usbmgr/test/cit/ROMConfig/src/testserversymbianexcludeusb.cpp
usbmgmt/usbmgr/test/cit/ROMConfig/testdata/UsbRomConfig.ini
usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite.xml
usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/TestExecuteServers/TestServerSymbianExcludeUsb.xml
usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbExcSuite.xml
usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbExcSuite/UsbRomConfig001.xml
usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbExcSuite/UsbRomConfig002.xml
usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbExcSuite/UsbRomConfig003.xml
usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbExcSuite/UsbRomConfig004.xml
usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbIncSuite.xml
usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbIncSuite/UsbIncRomConfig001.xml
usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbIncSuite/UsbIncRomConfig002.xml
usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbIncSuite/UsbIncRomConfig003.xml
usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbIncSuite/UsbIncRomConfig004.xml
usbmgmt/usbmgr/usbman/bld.inf
usbmgmt/usbmgr/usbman/chargingplugin/conf/usbmanager_10208dd7.crml
usbmgmt/usbmgr/usbman/chargingplugin/group/10208DD7.txt
usbmgmt/usbmgr/usbman/chargingplugin/group/UsbBatteryChargingPlugin.mmp
usbmgmt/usbmgr/usbman/chargingplugin/group/UsbBatteryChargingPluginBase.mmp
usbmgmt/usbmgr/usbman/chargingplugin/group/UsbBatteryChargingPluginotg.mmp
usbmgmt/usbmgr/usbman/chargingplugin/group/bld.inf
usbmgmt/usbmgr/usbman/chargingplugin/inc/default/cusbbatterycharginglicenseehooks.h
usbmgmt/usbmgr/usbman/chargingplugin/inc/idpinwatcher.h
usbmgmt/usbmgr/usbman/chargingplugin/inc/otgstatewatcher.h
usbmgmt/usbmgr/usbman/chargingplugin/inc/reenumerator.h
usbmgmt/usbmgr/usbman/chargingplugin/inc/vbuswatcher.h
usbmgmt/usbmgr/usbman/chargingplugin/public/CUsbBatteryChargingPlugin.h
usbmgmt/usbmgr/usbman/chargingplugin/public/chargingstates.h
usbmgmt/usbmgr/usbman/chargingplugin/public/devicestatetimer.h
usbmgmt/usbmgr/usbman/chargingplugin/public/motgobserver.h
usbmgmt/usbmgr/usbman/chargingplugin/public/repositorynotifier.h
usbmgmt/usbmgr/usbman/chargingplugin/public/usbbatterycharging.h
usbmgmt/usbmgr/usbman/chargingplugin/src/10208DD7.rss
usbmgmt/usbmgr/usbman/chargingplugin/src/CUsbBatteryChargingPlugin.cpp
usbmgmt/usbmgr/usbman/chargingplugin/src/CUsbBatteryChargingPluginMain.cpp
usbmgmt/usbmgr/usbman/chargingplugin/src/chargingstates.cpp
usbmgmt/usbmgr/usbman/chargingplugin/src/devicestatetimer.cpp
usbmgmt/usbmgr/usbman/chargingplugin/src/idpinwatcher.cpp
usbmgmt/usbmgr/usbman/chargingplugin/src/otgstatewatcher.cpp
usbmgmt/usbmgr/usbman/chargingplugin/src/reenumerator.cpp
usbmgmt/usbmgr/usbman/chargingplugin/src/repositorynotifier.cpp
usbmgmt/usbmgr/usbman/chargingplugin/src/vbuswatcher.cpp
usbmgmt/usbmgr/usbman/client/BWINS/USBMANU.DEF
usbmgmt/usbmgr/usbman/client/BWINS/usbman_over_dummyusbdiu.def
usbmgmt/usbmgr/usbman/client/EABI/usbmanU.DEF
usbmgmt/usbmgr/usbman/client/SRC/RUsb.cpp
usbmgmt/usbmgr/usbman/client/group/BLD.INF
usbmgmt/usbmgr/usbman/client/group/Usbman.mmp
usbmgmt/usbmgr/usbman/client/group/Usbman_over_dummyusbdi.mmp
usbmgmt/usbmgr/usbman/client/public/usbman.h
usbmgmt/usbmgr/usbman/client/public/usbstates.h
usbmgmt/usbmgr/usbman/extensionplugin/BWINS/usbmanextensionpluginu.def
usbmgmt/usbmgr/usbman/extensionplugin/EABI/usbmanextensionpluginu.def
usbmgmt/usbmgr/usbman/extensionplugin/group/UsbManExtensionPlugin.mmp
usbmgmt/usbmgr/usbman/extensionplugin/group/bld.inf
usbmgmt/usbmgr/usbman/extensionplugin/public/CUsbManExtensionPlugin.h
usbmgmt/usbmgr/usbman/extensionplugin/public/MUsbManExtensionPluginObserver.h
usbmgmt/usbmgr/usbman/extensionplugin/src/CUsbManExtensionPlugin.cpp
usbmgmt/usbmgr/usbman/extensionplugin/src/MUsbManExtensionPluginObserver.cpp
usbmgmt/usbmgr/usbman/server/INC/CPersonality.h
usbmgmt/usbmgr/usbman/server/INC/CPersonality.inl
usbmgmt/usbmgr/usbman/server/INC/CUsbDevice.h
usbmgmt/usbmgr/usbman/server/INC/CUsbDevice.inl
usbmgmt/usbmgr/usbman/server/INC/CUsbDeviceStateWatcher.h
usbmgmt/usbmgr/usbman/server/INC/CUsbDeviceStateWatcher.inl
usbmgmt/usbmgr/usbman/server/INC/CUsbDummyClassController.h
usbmgmt/usbmgr/usbman/server/INC/CUsbOtg.h
usbmgmt/usbmgr/usbman/server/INC/CUsbScheduler.h
usbmgmt/usbmgr/usbman/server/INC/CUsbServer.h
usbmgmt/usbmgr/usbman/server/INC/CUsbServer.inl
usbmgmt/usbmgr/usbman/server/INC/CUsbSession.h
usbmgmt/usbmgr/usbman/server/INC/UsbSettings.h
usbmgmt/usbmgr/usbman/server/INC/UsbUtils.h
usbmgmt/usbmgr/usbman/server/INC/UsbmanServerSecurityPolicy.h
usbmgmt/usbmgr/usbman/server/INC/cusbhost.h
usbmgmt/usbmgr/usbman/server/INC/cusbhostwatcher.h
usbmgmt/usbmgr/usbman/server/INC/cusbotgwatcher.h
usbmgmt/usbmgr/usbman/server/INC/musbinternalobservers.h
usbmgmt/usbmgr/usbman/server/INC/musbotghostnotifyobserver.h
usbmgmt/usbmgr/usbman/server/SRC/CPersonality.cpp
usbmgmt/usbmgr/usbman/server/SRC/CUsbDevice.cpp
usbmgmt/usbmgr/usbman/server/SRC/CUsbDeviceStateWatcher.cpp
usbmgmt/usbmgr/usbman/server/SRC/CUsbDummyClassController.cpp
usbmgmt/usbmgr/usbman/server/SRC/CUsbOtg.cpp
usbmgmt/usbmgr/usbman/server/SRC/CUsbScheduler.cpp
usbmgmt/usbmgr/usbman/server/SRC/CUsbServer.cpp
usbmgmt/usbmgr/usbman/server/SRC/CUsbSession.cpp
usbmgmt/usbmgr/usbman/server/SRC/UsbSvr.cpp
usbmgmt/usbmgr/usbman/server/SRC/UsbUtils.cpp
usbmgmt/usbmgr/usbman/server/SRC/cusbhost.cpp
usbmgmt/usbmgr/usbman/server/SRC/cusbhostwatcher.cpp
usbmgmt/usbmgr/usbman/server/SRC/cusbotgwatcher.cpp
usbmgmt/usbmgr/usbman/server/SRC/usbman.rls
usbmgmt/usbmgr/usbman/server/SRC/usbman.rss
usbmgmt/usbmgr/usbman/server/SRC/usbman_01.rls
usbmgmt/usbmgr/usbman/server/SRC/usbman_02.rls
usbmgmt/usbmgr/usbman/server/SRC/usbman_03.rls
usbmgmt/usbmgr/usbman/server/SRC/usbman_10.rls
usbmgmt/usbmgr/usbman/server/SRC/usbmanlubbockobex.rss
usbmgmt/usbmgr/usbman/server/SRC/usbmanmtp.rss
usbmgmt/usbmgr/usbman/server/SRC/usbmanmtprndis.rss
usbmgmt/usbmgr/usbman/server/SRC/usbmanrndis.rss
usbmgmt/usbmgr/usbman/server/data/AsyncStart.ini
usbmgmt/usbmgr/usbman/server/data/AsyncStop.ini
usbmgmt/usbmgr/usbman/server/data/BadStart0CI.ini
usbmgmt/usbmgr/usbman/server/data/BadStart1CI.ini
usbmgmt/usbmgr/usbman/server/data/BadStart2CI.ini
usbmgmt/usbmgr/usbman/server/data/BadStop0CI.ini
usbmgmt/usbmgr/usbman/server/data/BadStop1CI.ini
usbmgmt/usbmgr/usbman/server/data/BadStop2CI.ini
usbmgmt/usbmgr/usbman/server/data/SyncStart.ini
usbmgmt/usbmgr/usbman/server/data/SyncStop.ini
usbmgmt/usbmgr/usbman/server/data/demo_mcci_usbman.rh
usbmgmt/usbmgr/usbman/server/data/nice.ini
usbmgmt/usbmgr/usbman/server/data/test.ini
usbmgmt/usbmgr/usbman/server/group/BLD.INF
usbmgmt/usbmgr/usbman/server/group/Usbsvr.mmp
usbmgmt/usbmgr/usbman/server/group/backup_registration.xml
usbmgmt/usbmgr/usbman/server/group/dummyCCinifiles.iby
usbmgmt/usbmgr/usbman/server/group/t_Usbman_dummyCC.mmp
usbmgmt/usbmgr/usbman/server/group/usbsvrbase.mmp
usbmgmt/usbmgr/usbman/server/group/usbsvrotg.mmp
usbmgmt/usbmgr/usbman/server/group/usbsvrotg_dummyusbdi.mmp
usbmgmt/usbmgr/usbman/server/public/MUsbDeviceNotify.h
usbmgmt/usbmgr/usbman/server/public/UsbClassUids.h
usbmgmt/usbmgr/usbman/server/public/Usb_std.h
usbmgmt/usbmgr/usbman/server/public/UsbmanInternalConstants.h
usbmgmt/usbmgr/usbman/server/public/rusb.h
usbmgmt/usbmgr/usbman/server/public/usberrors.h
usbmgmt/usbmgr/usbman/server/public/usbhostdefs.h
usbmgmt/usbmgr/usbman/server/public/usbman.rh
usbmgmt/usbmgr/usbman/server/public/usbotgdefs.h
usbmgmt/usbmgr/usbman/server/public/usbshared.h
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerClientSession/BWINS/classControllerClientSessionU.DEF
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerClientSession/EABI/classControllerClientSessionU.DEF
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerClientSession/group/ClassControllerClientSession.mmp
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerClientSession/group/bld.inf
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerClientSession/inc/classControllerClientSession.h
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerClientSession/src/classControllerClientSession.cpp
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/group/Bld.inf
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/group/classControllerServerSession.mmp
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/inc/classContServer.h
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/inc/classContServerSession.h
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/inc/obexInitiator.h
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/src/classContServer.cpp
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/src/classContServerSession.cpp
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/src/main.cpp
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/src/obexInitiator.cpp
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/group/CUsbObexClassController.mmp
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/group/bld.inf
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/inc/CUsbObexClassController.h
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/src/1027433a.rss
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/src/CUsbObexClassController.cpp
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/src/CUsbObexClassImpCollection.cpp
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/src/obexusbman.rss
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/bld.inf
usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/public/clientServerShared.h
usbmgmt/usbmgrtest/ObexClassController/bld.inf
usbmgmt/usbmgrtest/ObexClassController/test/group/Bld.inf
usbmgmt/usbmgrtest/ObexClassController/test/group/simpleObexApp.IBY
usbmgmt/usbmgrtest/ObexClassController/test/group/simpleObexApp.mmp
usbmgmt/usbmgrtest/ObexClassController/test/inc/Contactsbak.vcf
usbmgmt/usbmgrtest/ObexClassController/test/inc/Contactsbak2.vcf
usbmgmt/usbmgrtest/ObexClassController/test/inc/Contactsbak3.vcf
usbmgmt/usbmgrtest/ObexClassController/test/inc/obexAppConstants.h
usbmgmt/usbmgrtest/ObexClassController/test/inc/simpleObexApp.h
usbmgmt/usbmgrtest/ObexClassController/test/inc/simpleObexAppConstants.h
usbmgmt/usbmgrtest/ObexClassController/test/inc/simpleObexClient.h
usbmgmt/usbmgrtest/ObexClassController/test/inc/simpleObexServer.h
usbmgmt/usbmgrtest/ObexClassController/test/src/simpleObexApp.cpp
usbmgmt/usbmgrtest/ObexClassController/test/src/simpleObexClient.cpp
usbmgmt/usbmgrtest/ObexClassController/test/src/simpleObexServer.cpp
usbmgmt/usbmgrtest/T_usb/BWINS/T_usbU.DEF
usbmgmt/usbmgrtest/T_usb/EABI/T_usbU.DEF
usbmgmt/usbmgrtest/T_usb/group/T_usb.mmp
usbmgmt/usbmgrtest/T_usb/group/bld.inf
usbmgmt/usbmgrtest/T_usb/inc/UsbManTest1.h
usbmgmt/usbmgrtest/T_usb/inc/UsbStep.h
usbmgmt/usbmgrtest/T_usb/inc/UsbSuite.h
usbmgmt/usbmgrtest/T_usb/inc/UsbTest1.h
usbmgmt/usbmgrtest/T_usb/inc/UsbTest2.h
usbmgmt/usbmgrtest/T_usb/scripts/t_usb.script
usbmgmt/usbmgrtest/T_usb/scripts/t_usb1.script
usbmgmt/usbmgrtest/T_usb/scripts/t_usb2.script
usbmgmt/usbmgrtest/T_usb/scripts/t_usb3.ini
usbmgmt/usbmgrtest/T_usb/scripts/t_usb3.script
usbmgmt/usbmgrtest/T_usb/scripts/t_usb4.script
usbmgmt/usbmgrtest/T_usb/scripts/t_usb5.script
usbmgmt/usbmgrtest/T_usb/scripts/t_usb6.script
usbmgmt/usbmgrtest/T_usb/scripts/t_usb7.script
usbmgmt/usbmgrtest/T_usb/scripts/t_usb_sample.ini
usbmgmt/usbmgrtest/T_usb/scripts/t_usbman1.ini
usbmgmt/usbmgrtest/T_usb/scripts/t_usbman1.script
usbmgmt/usbmgrtest/T_usb/scripts/t_usbman2.ini
usbmgmt/usbmgrtest/T_usb/src/UsbManTest1.cpp
usbmgmt/usbmgrtest/T_usb/src/UsbStep.cpp
usbmgmt/usbmgrtest/T_usb/src/UsbSuite.cpp
usbmgmt/usbmgrtest/T_usb/src/UsbTest1.cpp
usbmgmt/usbmgrtest/T_usb/src/UsbTest2.cpp
usbmgmt/usbmgrtest/automation/makerom.pl
usbmgmt/usbmgrtest/automation/processLogs.pl
usbmgmt/usbmgrtest/automation/rom.armv5.81b.config
usbmgmt/usbmgrtest/automation/rom.armv5.90.config
usbmgmt/usbmgrtest/automation/rom.thumb.81a.config
usbmgmt/usbmgrtest/automation/runcmd.pl
usbmgmt/usbmgrtest/automation/runtests.pl
usbmgmt/usbmgrtest/automation/start.mbc
usbmgmt/usbmgrtest/automation/start.rss
usbmgmt/usbmgrtest/automation/tests.armv5.81b.config
usbmgmt/usbmgrtest/automation/tests.armv5.90.config
usbmgmt/usbmgrtest/automation/tests.thumb.81a.config
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/IndividualRom.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/IndividualRom/t_usbmancomponent_4.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/IndividualRom/t_usbmancomponent_5.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Component.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Component/t_usbmancomponent_1.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration/t_usbmanintegration.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected/t_usbmanconnected_1.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected/t_usbmanconnected_2.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected/t_usbmanconnected_3.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected/t_usbmanconnected_4.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected/t_usbmanconnected_5.xml
usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected/t_usbmanconnected_6.xml
usbmgmt/usbmgrtest/csy/t_ecacm/group/T_csyaccess.mmp
usbmgmt/usbmgrtest/csy/t_ecacm/group/bld.inf
usbmgmt/usbmgrtest/csy/t_ecacm/src/t_csyaccess.cpp
usbmgmt/usbmgrtest/group/bld.inf
usbmgmt/usbmgrtest/group/tacmcsy.oby
usbmgmt/usbmgrtest/group/usb_test.history.xml
usbmgmt/usbmgrtest/group/usb_test.mrp
usbmgmt/usbmgrtest/showcaps/group/bld.inf
usbmgmt/usbmgrtest/showcaps/group/showcaps.mmp
usbmgmt/usbmgrtest/showcaps/src/showcaps.cpp
usbmgmt/usbmgrtest/startusb/group/bld.inf
usbmgmt/usbmgrtest/startusb/group/startusb.iby
usbmgmt/usbmgrtest/startusb/group/startusb.mmp
usbmgmt/usbmgrtest/startusb/src/startusb.cpp
usbmgmt/usbmgrtest/startusb2/group/bld.inf
usbmgmt/usbmgrtest/startusb2/group/startusb2.mmp
usbmgmt/usbmgrtest/startusb2/src/startusb2.cpp
usbmgmt/usbmgrtest/stopusb/group/bld.inf
usbmgmt/usbmgrtest/stopusb/group/stopusb.iby
usbmgmt/usbmgrtest/stopusb/group/stopusb.mmp
usbmgmt/usbmgrtest/stopusb/src/stopusb.cpp
usbmgmt/usbmgrtest/t_acm/group/bld.inf
usbmgmt/usbmgrtest/t_acm/group/t_acm.iby
usbmgmt/usbmgrtest/t_acm/group/t_acm.mmp
usbmgmt/usbmgrtest/t_acm/src/t_acm.cpp
usbmgmt/usbmgrtest/t_acm_cc/group/bld.inf
usbmgmt/usbmgrtest/t_acm_cc/group/t_acm_cc.mmp
usbmgmt/usbmgrtest/t_acm_cc/src/t_acm_cc.cpp
usbmgmt/usbmgrtest/t_acm_pub_sub/data/numberofacmfunctions.ini
usbmgmt/usbmgrtest/t_acm_pub_sub/group/Bld.inf
usbmgmt/usbmgrtest/t_acm_pub_sub/group/t_acm_pub_sub.iby
usbmgmt/usbmgrtest/t_acm_pub_sub/group/t_acm_pub_sub.mmp
usbmgmt/usbmgrtest/t_acm_pub_sub/inc/CommonFramework.h
usbmgmt/usbmgrtest/t_acm_pub_sub/src/t_acm_pub_sub.cpp
usbmgmt/usbmgrtest/t_acm_spec/group/bld.inf
usbmgmt/usbmgrtest/t_acm_spec/group/t_acm_spec.mmp
usbmgmt/usbmgrtest/t_acm_spec/src/t_acm_spec.cpp
usbmgmt/usbmgrtest/t_acm_wins/group/bld.inf
usbmgmt/usbmgrtest/t_acm_wins/group/t_acm_wins.mmp
usbmgmt/usbmgrtest/t_acm_wins/src/t_acm_wins.cpp
usbmgmt/usbmgrtest/t_catc/group/bld.inf
usbmgmt/usbmgrtest/t_catc/group/t_catc.mmp
usbmgmt/usbmgrtest/t_catc/src/t_catc.cpp
usbmgmt/usbmgrtest/t_charging_arm/group/bld.inf
usbmgmt/usbmgrtest/t_charging_arm/group/t_usbchargingarm.iby
usbmgmt/usbmgrtest/t_charging_arm/group/t_usbchargingarm.mmp
usbmgmt/usbmgrtest/t_charging_arm/inc/Tests.h
usbmgmt/usbmgrtest/t_charging_arm/inc/activeconsole.h
usbmgmt/usbmgrtest/t_charging_arm/inc/testbase.h
usbmgmt/usbmgrtest/t_charging_arm/inc/testmanager.h
usbmgmt/usbmgrtest/t_charging_arm/inc/usbchargingarmtest.h
usbmgmt/usbmgrtest/t_charging_arm/src/activeconsole.cpp
usbmgmt/usbmgrtest/t_charging_arm/src/activetest.cpp
usbmgmt/usbmgrtest/t_charging_arm/src/testbase.cpp
usbmgmt/usbmgrtest/t_charging_arm/src/usbchargingarmtest.cpp
usbmgmt/usbmgrtest/t_charging_emu/group/BLD.INF
usbmgmt/usbmgrtest/t_charging_emu/group/TestPlugin.mmp
usbmgmt/usbmgrtest/t_charging_emu/group/TestPluginotg.mmp
usbmgmt/usbmgrtest/t_charging_emu/group/t_usbcharging.iby
usbmgmt/usbmgrtest/t_charging_emu/group/tbatterycharging.mmp
usbmgmt/usbmgrtest/t_charging_emu/group/tbatterychargingrepositorywriter.mmp
usbmgmt/usbmgrtest/t_charging_emu/inc/CUsbBatteryChargingTestPlugin.h
usbmgmt/usbmgrtest/t_charging_emu/inc/activepropertysubscribercharging.h
usbmgmt/usbmgrtest/t_charging_emu/inc/dummyldd.h
usbmgmt/usbmgrtest/t_charging_emu/inc/tbatterycharging.h
usbmgmt/usbmgrtest/t_charging_emu/inc/tbatterychargingdefinitions.h
usbmgmt/usbmgrtest/t_charging_emu/inc/tpropertybatterycharging.h
usbmgmt/usbmgrtest/t_charging_emu/src/1020DEA7.rss
usbmgmt/usbmgrtest/t_charging_emu/src/CUsbBatteryChargingTestPlugin.cpp
usbmgmt/usbmgrtest/t_charging_emu/src/activepropertysubscribercharging.cpp
usbmgmt/usbmgrtest/t_charging_emu/src/t_charging.txt
usbmgmt/usbmgrtest/t_charging_emu/src/tbatterycharging.cpp
usbmgmt/usbmgrtest/t_charging_emu/src/tpropertybatterycharging.cpp
usbmgmt/usbmgrtest/t_headlessecacm/group/bld.inf
usbmgmt/usbmgrtest/t_headlessecacm/group/t_headlessecacm.mmp
usbmgmt/usbmgrtest/t_multi_acm/group/bld.inf
usbmgmt/usbmgrtest/t_multi_acm/group/t_multi_acm.mmp
usbmgmt/usbmgrtest/t_multi_acm/src/t_multiple_acm.cpp
usbmgmt/usbmgrtest/t_termusb/group/bld.inf
usbmgmt/usbmgrtest/t_termusb/group/t_termusb.iby
usbmgmt/usbmgrtest/t_termusb/group/t_termusb.mmp
usbmgmt/usbmgrtest/t_termusb/src/t_termusb.cpp
usbmgmt/usbmgrtest/t_termusb2/group/bld.inf
usbmgmt/usbmgrtest/t_termusb2/group/t_termusb2.mmp
usbmgmt/usbmgrtest/t_termusb2/src/t_termusb2.cpp
usbmgmt/usbmgrtest/t_usb_cable_detect/group/bld.inf
usbmgmt/usbmgrtest/t_usb_cable_detect/group/t_usb_cable_detect.mmp
usbmgmt/usbmgrtest/t_usb_cable_detect/src/t_usb_cable_detect.cpp
usbmgmt/usbmgrtest/t_usbman/group/bld.inf
usbmgmt/usbmgrtest/t_usbman/group/t_usbman.mmp
usbmgmt/usbmgrtest/t_usbman/src/t_usbman.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/EABI/stub1ccU.def
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/group/BLD.INF
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/group/Stub1CC.iby
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/group/Stub1CC.mmp
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/group/stub1cc.ini
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/inc/Stub1CC.h
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/src/10203284.rss
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/src/Stub1CC.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/src/Stub1CCImpCollection.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/EABI/stub2ccU.def
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/group/BLD.INF
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/group/Stub2CC.iby
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/group/Stub2CC.mmp
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/group/stub2cc.ini
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/inc/Stub2CC.h
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/src/10203286.rss
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/src/Stub2CC.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/src/Stub2CCImpCollection.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/EABI/stub3ccU.def
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/group/BLD.INF
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/group/Stub3CC.iby
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/group/Stub3CC.mmp
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/group/stub3cc.ini
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/inc/Stub3CC.h
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/src/10203288.rss
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/src/Stub3CC.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/src/Stub3CCImpCollection.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/group/BLD.INF
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/group/T_UsbManager.mmp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/group/t_UsbManager.oby
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/group/t_UsbManagerComponent_4.oby
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/group/t_UsbManagerComponent_5.oby
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/group/t_usbms_cable_detect.mmp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CCancelStartInterest.h
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CCancelStopInterest.h
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CSimCablePulling.h
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CStartNewPersonality.h
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CStartPersonality.h
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CStartStopPersonality.h
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CStopPersonality.h
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CUsbComponentTest.h
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CUsbMsComponentTest.h
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CUsbTestStepBase.h
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/T_UsbManagerServer.h
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmancomponent_1.script
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmancomponent_4.script
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmancomponent_5.script
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanconnected_1.script
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanconnected_2.script
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanconnected_3.script
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanconnected_4.script
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanconnected_5.script
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanconnected_6.script
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanintegration.script
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmscccomponent.script
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CCancelStartInterest.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CCancelStopInterest.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CSimCablePulling.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CStartNewPersonality.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CStartPersonality.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CStartStopPersonality.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CStopPersonality.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CUsbComponentTest.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CUsbMsComponentTest.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CUsbTestStepBase.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/T_UsbManagerServer.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/t_usbms_cable_detect.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/testdata/stub1cctest.ini
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/testdata/t_usbmancomponent.ini
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/testdata/t_usbmanintegration.ini
usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/testdata/usbman1.rss
usbmgmt/usbmgrtest/t_usbmanager_suite/group/bld.inf
usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/group/BLD.INF
usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/group/te_msclasscontroller.iby
usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/group/te_msclasscontroller.mmp
usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/inc/CUsbMsTestServer.h
usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/inc/CUsbMsTestStep.h
usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/scripts/te_msclasscontroller.ini
usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/scripts/te_msclasscontroller.script
usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/src/CUsbMsTestServer.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/src/CUsbMsTestStep.cpp
usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/src/usbms.rss
usbmgmt/usbmgrtest/t_usbmodem/group/bld.inf
usbmgmt/usbmgrtest/t_usbmodem/group/t_usbmodem.iby
usbmgmt/usbmgrtest/t_usbmodem/group/t_usbmodem.mmp
usbmgmt/usbmgrtest/t_usbmodem/inc/t_usbmodem.h
usbmgmt/usbmgrtest/t_usbmodem/src/t_usbmodem.cpp
usbmgmt/usbmgrtest/t_whcm_cc/group/bld.inf
usbmgmt/usbmgrtest/t_whcm_cc/group/t_whcm_cc.mmp
usbmgmt/usbmgrtest/t_whcm_cc/src/t_whcm_cc.cpp
usbmgmt/usbmgrtest/usbcontrolapp/controlappbinder/controlappbinder.cpp
usbmgmt/usbmgrtest/usbcontrolapp/controlappbinder/controlappbinder.h
usbmgmt/usbmgrtest/usbcontrolapp/controlappbinder/controlappbinder.mmp
usbmgmt/usbmgrtest/usbcontrolapp/exampleusbcontrolapp/exampleusbcontrolapp.cpp
usbmgmt/usbmgrtest/usbcontrolapp/exampleusbcontrolapp/exampleusbcontrolapp.h
usbmgmt/usbmgrtest/usbcontrolapp/exampleusbcontrolapp/exampleusbcontrolapp.mmp
usbmgmt/usbmgrtest/usbcontrolapp/group/bld.inf
usbmgmt/usbmgrtest/usbcontrolapp/group/usbcontrolapp.oby
usbmgmt/usbmgrtest/usbcontrolapp/shared/usbcontrolappshared.h
usbmgmt/usbmgrtest/usbcontrolapp/testusbawareapp/testusbawareapp.cpp
usbmgmt/usbmgrtest/usbcontrolapp/testusbawareapp/testusbawareapp.h
usbmgmt/usbmgrtest/usbcontrolapp/testusbawareapp/testusbawareapp.mmp
usbmgmt/usbmgrtest/usbcontrolapp/usbviewer/usbviewer.cpp
usbmgmt/usbmgrtest/usbcontrolapp/usbviewer/usbviewer.h
usbmgmt/usbmgrtest/usbcontrolapp/usbviewer/usbviewer.mmp
usbmgmt/usbmgrtest/usbmsapp/BLD.INF
usbmgmt/usbmgrtest/usbmsapp/usbms.iby
usbmgmt/usbmgrtest/usbmsapp/usbms.oby
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/BWINS/usbms_stub1ccU.DEF
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/BWINS/usbms_stub2ccU.DEF
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/BWINS/usbms_stub3ccU.DEF
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/group/BLD.INF
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/group/usbms_stub1cc.mmp
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/group/usbms_stub2cc.mmp
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/group/usbms_stub3cc.mmp
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/inc/usbms_stub.h
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/10203284.rss
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/10203286.rss
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/10203288.rss
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/Stub1CCImpCollection.cpp
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/Stub2CCImpCollection.cpp
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/Stub3CCImpCollection.cpp
usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/usbms_stub.cpp
usbmgmt/usbmgrtest/usbmsapp/usbmsapp.cpp
usbmgmt/usbmgrtest/usbmsapp/usbmsapp.h
usbmgmt/usbmgrtest/usbmsapp/usbmsapp.mmp
usbmgmt/usbmgrtest/usbtestconsole/bld.inf
usbmgmt/usbmgrtest/usbtestconsole/usbtestconsole.cpp
usbmgmt/usbmgrtest/usbtestconsole/usbtestconsole.h
usbmgmt/usbmgrtest/usbtestconsole/usbtestconsole.mmp
usbmgmt/usbmgrtest/usbtestconsole/usbtestconsole.oby
usbmgmt/usbmgrtest/winapp/test.bat
usbmgmt/usbmgrtest/winapp/usbcheck.exe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,24 @@
+/*
+* Copyright (c) 2006 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:  Build information file for project ?myapp
+*
+*/
+
+
+PRJ_PLATFORMS
+
+
+/* include subsystems build info */
+#include "../usb_plat/group/bld.inf"
+#include "../usbextension/group/bld.inf"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layers.sysdef.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!DOCTYPE SystemDefinition SYSTEM "sysdef_1_4_0.dtd" [
+  <!ENTITY layer_real_source_path "sf/os/usb" >
+]>
+
+<SystemDefinition name="usb" schema="1.4.0">
+  <systemModel>
+    <layer name="os_layer">
+      <module name="usb">
+        <unit unitID="lcdo.usb" mrp="" bldFile="&layer_real_source_path;/group" name="usb" />
+      </module>
+    </layer>
+  </systemModel>
+</SystemDefinition>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/package_definition.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SystemDefinition schema="3.0.0">
+  <package id="usb" name="USB" levels="adaptation hw-if plugin framework server app-if">
+    <collection id="usbldd" name="USB Logical Device Drivers" level="hw-if">
+      <!-- usbclientdrivers  to be moved here from kernelhwsrv-->
+    </collection>
+    <collection id="usbmgmt" name="USB Management" level="server">
+      <component id="usbmgr" name="USB Manager" purpose="optional">
+        <unit version="2" bldFile="usbmgmt/usbmgr/group" mrp="usbmgmt/usbmgr/group/usb_manager.mrp"/>
+      </component>
+      <component id="usbmgrtest" name="USB Manager Tests" introduced="7.0" purpose="development" filter="test">
+        <unit version="2" mrp="usbmgmt/usbmgrtest/group/usb_test.mrp" bldFile="usbmgmt/usbmgrtest/group"/>
+      </component>
+      <component id="usbclassandmgrdocs" name="USB Class and Manager Documentation" purpose="development" class="doc">
+        <unit mrp="usbmgmt/usbclassandmgrdocs/usb_documentation.mrp"/>
+      </component>
+    </collection>
+    <collection id="usb_info" name="USB Info" level="app-if">
+      <component id="usb_metadata" name="USB Metadata" class="config" introduced="^3" purpose="development" target="desktop">
+        <unit mrp="usb_info/usb_metadata/usb_metadata.mrp"/>
+      </component>
+    </collection>
+  </package>
+</SystemDefinition>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdef_1_4_0.dtd	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,86 @@
+ <!ELEMENT SystemDefinition (systemModel?, build?)>
+ <!ATTLIST SystemDefinition
+  name CDATA #REQUIRED
+  schema CDATA #REQUIRED>
+ <!ELEMENT systemModel (layer+)>
+ <!ELEMENT layer (logicalset* | module*)*>
+ <!ATTLIST layer
+  name CDATA #REQUIRED
+  levels CDATA #IMPLIED
+  span CDATA #IMPLIED>
+ <!ELEMENT logicalset (logicalsubset* | module* | unit* | package* | prebuilt*)*>
+ <!ATTLIST logicalset name CDATA #REQUIRED>
+ <!ELEMENT logicalsubset (module* | unit* | package* | prebuilt*)*>
+ <!ATTLIST logicalsubset name CDATA #REQUIRED>
+ <!ELEMENT module (component* | unit* | package* | prebuilt*)*>
+ <!ATTLIST module
+  name CDATA #REQUIRED
+  level CDATA #IMPLIED>
+ <!ELEMENT component (unit* | package* | prebuilt*)*>
+ <!ATTLIST component name CDATA #REQUIRED>
+ <!ELEMENT unit EMPTY>
+ <!ATTLIST unit
+  unitID ID #REQUIRED
+  name CDATA #REQUIRED
+  mrp CDATA #REQUIRED
+  filter CDATA #IMPLIED
+  bldFile CDATA #REQUIRED
+  priority CDATA #IMPLIED
+  contract CDATA #IMPLIED>
+ <!ELEMENT package EMPTY>
+ <!ATTLIST package
+  name CDATA #REQUIRED
+  mrp CDATA #REQUIRED
+  filter CDATA #IMPLIED
+  contract CDATA #IMPLIED>
+ <!ELEMENT prebuilt EMPTY>
+ <!ATTLIST prebuilt
+  name CDATA #REQUIRED
+  version CDATA #REQUIRED
+  late (Y|N) #IMPLIED
+  filter CDATA #IMPLIED
+  contract CDATA #IMPLIED>
+ <!ELEMENT build (option* | target+ | targetList+ | unitList+ | configuration+)*>
+ <!ELEMENT unitList (unitRef+)>
+ <!ATTLIST unitList
+  name ID #REQUIRED
+  description CDATA #REQUIRED>
+ <!ELEMENT unitRef EMPTY>
+ <!ATTLIST unitRef unit IDREF #REQUIRED>
+ <!ELEMENT targetList EMPTY>
+ <!ATTLIST targetList
+  name ID #REQUIRED
+  description CDATA #REQUIRED
+  target IDREFS #REQUIRED>
+ <!ELEMENT target EMPTY>
+ <!ATTLIST target
+  name ID #REQUIRED
+  abldTarget CDATA #REQUIRED
+  description CDATA #REQUIRED>
+ <!ELEMENT option EMPTY>
+ <!ATTLIST option
+  name ID #REQUIRED
+  abldOption CDATA #REQUIRED
+  description CDATA #REQUIRED
+  enable (Y | N | y | n) #REQUIRED>
+ <!ELEMENT configuration (unitListRef+ | layerRef+ | task+)*>
+ <!ATTLIST configuration
+  name ID #REQUIRED
+  description CDATA #REQUIRED
+  filter CDATA #REQUIRED>
+ <!ELEMENT task ( unitListRef* , (buildLayer | specialInstructions))>
+ <!ELEMENT unitListRef EMPTY>
+ <!ATTLIST unitListRef unitList IDREF #REQUIRED>
+ <!ELEMENT layerRef EMPTY>
+ <!ATTLIST layerRef layerName CDATA #REQUIRED>
+ <!ELEMENT buildLayer EMPTY>
+ <!ATTLIST buildLayer
+  command CDATA #REQUIRED
+  targetList IDREFS #IMPLIED
+  unitParallel (Y | N | y | n) #REQUIRED
+  targetParallel (Y | N | y | n) #IMPLIED>
+ <!ELEMENT specialInstructions EMPTY>
+ <!ATTLIST specialInstructions
+  name CDATA #REQUIRED
+  cwd CDATA #REQUIRED
+  command CDATA #REQUIRED>  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb_info/usb_metadata/usb_metadata.mrp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,6 @@
+component           usb_metadata
+source   \sf\os\usb\usb_info\usb_metadata 
+source   \sf\os\usb\package_definition.xml
+source   \sf\os\usb\distribution.policy.s60
+notes_source      \component_defs\release.src
+ipr T 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb_plat/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 2007 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:  Build information file
+*
+*/
+
+
+PRJ_PLATFORMS
+DEFAULT
+
+#include "../usb_audio_stream_plugin_api/group/bld.inf"
+
+PRJ_EXPORTS
+
+PRJ_MMPFILES
+
+PRJ_TESTMMPFILES
+
+PRJ_TESTEXPORTS
Binary file usbmgmt/usbclassandmgrdocs/USBDI-Unit Test Design.EAP has changed
Binary file usbmgmt/usbclassandmgrdocs/USB_Control_App_UML_Diagrams.eap has changed
Binary file usbmgmt/usbclassandmgrdocs/USB_FDF_Model.EAP has changed
Binary file usbmgmt/usbclassandmgrdocs/USB_Host_and_OTG_Test_Harness_Design.eap has changed
Binary file usbmgmt/usbclassandmgrdocs/USB_MSMM_Design.eap has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbclassandmgrdocs/usb_documentation.history.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<relnotes name="DEVELOPERLIBRARY">
+  <purpose>
+    Documentation for USB.
+  </purpose>
+
+  <defect number="DEF125990" title="USB Documentation directory includes project review documents" revision="003">
+    Project mgt documents removed
+  </defect>
+
+  <preq number="1782" title="USB Host and on-the-go for pre-installed drivers" revision="002"/>
+  <preq number="1576" title="State change plug-in interface to USB Manager (for charging)" revision="001"/>
+</relnotes>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbclassandmgrdocs/usb_documentation.mrp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+# Copyright (c) 2003-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:
+# 
+#
+#
+
+
+component	usb_documentation
+
+source	\sf\os\usb\usbmgmt\usbclassandmgrdocs\
+
+notes_source	\component_defs\release.src
+
+
+ipr D 
+
Binary file usbmgmt/usbmgr/conf/usbmanager.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,19 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "classcontroller/group/bld.inf"
+#include "classdrivers/bld.inf"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classcontroller/BWINS/usbclasscontrolleru.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,18 @@
+EXPORTS
+	??0CUsbClassControllerBase@@IAE@AAVMUsbClassControllerNotify@@H@Z @ 1 NONAME ; protected: __thiscall CUsbClassControllerBase::CUsbClassControllerBase(class MUsbClassControllerNotify &,int)
+	??0CUsbClassControllerIterator@@QAE@AAV?$RPointerArray@VCUsbClassControllerBase@@@@@Z @ 2 NONAME ; public: __thiscall CUsbClassControllerIterator::CUsbClassControllerIterator(class RPointerArray<class CUsbClassControllerBase> &)
+	??0CUsbClassControllerPlugIn@@IAE@AAVMUsbClassControllerNotify@@H@Z @ 3 NONAME ; protected: __thiscall CUsbClassControllerPlugIn::CUsbClassControllerPlugIn(class MUsbClassControllerNotify &,int)
+	??1CUsbClassControllerBase@@UAE@XZ @ 4 NONAME ; public: virtual __thiscall CUsbClassControllerBase::~CUsbClassControllerBase(void)
+	??1CUsbClassControllerIterator@@UAE@XZ @ 5 NONAME ; public: virtual __thiscall CUsbClassControllerIterator::~CUsbClassControllerIterator(void)
+	??1CUsbClassControllerPlugIn@@UAE@XZ @ 6 NONAME ; public: virtual __thiscall CUsbClassControllerPlugIn::~CUsbClassControllerPlugIn(void)
+	?Compare@CUsbClassControllerBase@@SAHABV1@0@Z @ 7 NONAME ; public: static int __cdecl CUsbClassControllerBase::Compare(class CUsbClassControllerBase const &,class CUsbClassControllerBase const &)
+	?Current@CUsbClassControllerIterator@@QAEPAVCUsbClassControllerBase@@XZ @ 8 NONAME ; public: class CUsbClassControllerBase * __thiscall CUsbClassControllerIterator::Current(void)
+	?First@CUsbClassControllerIterator@@QAEHXZ @ 9 NONAME ; public: int __thiscall CUsbClassControllerIterator::First(void)
+	?NewL@CUsbClassControllerPlugIn@@SAPAV1@VTUid@@AAVMUsbClassControllerNotify@@@Z @ 10 NONAME ; public: static class CUsbClassControllerPlugIn * __cdecl CUsbClassControllerPlugIn::NewL(class TUid,class MUsbClassControllerNotify &)
+	?Next@CUsbClassControllerIterator@@QAEHXZ @ 11 NONAME ; public: int __thiscall CUsbClassControllerIterator::Next(void)
+	?Owner@CUsbClassControllerBase@@QBEAAVMUsbClassControllerNotify@@XZ @ 12 NONAME ; public: class MUsbClassControllerNotify & __thiscall CUsbClassControllerBase::Owner(void)const 
+	?Previous@CUsbClassControllerIterator@@QAEHXZ @ 13 NONAME ; public: int __thiscall CUsbClassControllerIterator::Previous(void)
+	?Seek@CUsbClassControllerIterator@@QAEHPAVCUsbClassControllerBase@@@Z @ 14 NONAME ; public: int __thiscall CUsbClassControllerIterator::Seek(class CUsbClassControllerBase *)
+	?StartupPriority@CUsbClassControllerBase@@QBEHXZ @ 15 NONAME ; public: int __thiscall CUsbClassControllerBase::StartupPriority(void)const 
+	?State@CUsbClassControllerBase@@QBE?AW4TUsbServiceState@@XZ @ 16 NONAME ; public: enum TUsbServiceState  __thiscall CUsbClassControllerBase::State(void)const 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classcontroller/EABI/usbclasscontrollerU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+EXPORTS
+	_ZN23CUsbClassControllerBase7CompareERKS_S1_ @ 1 NONAME
+	_ZN23CUsbClassControllerBaseC2ER25MUsbClassControllerNotifyi @ 2 NONAME
+	_ZN23CUsbClassControllerBaseD0Ev @ 3 NONAME
+	_ZN23CUsbClassControllerBaseD1Ev @ 4 NONAME
+	_ZN23CUsbClassControllerBaseD2Ev @ 5 NONAME
+	_ZN25CUsbClassControllerPlugIn4NewLE4TUidR25MUsbClassControllerNotify @ 6 NONAME
+	_ZN25CUsbClassControllerPlugInC2ER25MUsbClassControllerNotifyi @ 7 NONAME
+	_ZN25CUsbClassControllerPlugInD0Ev @ 8 NONAME
+	_ZN25CUsbClassControllerPlugInD1Ev @ 9 NONAME
+	_ZN25CUsbClassControllerPlugInD2Ev @ 10 NONAME
+	_ZN27CUsbClassControllerIterator4NextEv @ 11 NONAME
+	_ZN27CUsbClassControllerIterator4SeekEP23CUsbClassControllerBase @ 12 NONAME
+	_ZN27CUsbClassControllerIterator5FirstEv @ 13 NONAME
+	_ZN27CUsbClassControllerIterator7CurrentEv @ 14 NONAME
+	_ZN27CUsbClassControllerIterator8PreviousEv @ 15 NONAME
+	_ZN27CUsbClassControllerIteratorC1ER13RPointerArrayI23CUsbClassControllerBaseE @ 16 NONAME
+	_ZN27CUsbClassControllerIteratorC2ER13RPointerArrayI23CUsbClassControllerBaseE @ 17 NONAME
+	_ZN27CUsbClassControllerIteratorD0Ev @ 18 NONAME
+	_ZN27CUsbClassControllerIteratorD1Ev @ 19 NONAME
+	_ZN27CUsbClassControllerIteratorD2Ev @ 20 NONAME
+	_ZNK23CUsbClassControllerBase15StartupPriorityEv @ 21 NONAME
+	_ZNK23CUsbClassControllerBase5OwnerEv @ 22 NONAME
+	_ZNK23CUsbClassControllerBase5StateEv @ 23 NONAME
+	_ZTI23CUsbClassControllerBase @ 24 NONAME ; #<TI>#
+	_ZTI25CUsbClassControllerPlugIn @ 25 NONAME ; #<TI>#
+	_ZTV23CUsbClassControllerBase @ 26 NONAME ; #<VT>#
+	_ZTV25CUsbClassControllerPlugIn @ 27 NONAME ; #<VT>#
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classcontroller/SRC/CUsbClassControllerBase.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 1997-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:
+* Implements part of UsbMan USB Class Controller Framework.
+* All USB classes to be managed by UsbMan must derive
+* from this class.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <cusbclasscontrollerbase.h>
+#include <musbclasscontrollernotify.h>
+
+
+/**
+ * Constructor.
+ *
+ * @param aOwner Owner and manager of this object
+ * @param aStartupPriority The priority of the Class Controller (the 
+ * priorities of all present Class Controllers determines the order in which 
+ * they are started).
+ */
+EXPORT_C CUsbClassControllerBase::CUsbClassControllerBase(
+	MUsbClassControllerNotify& aOwner, TInt aStartupPriority)
+	: CActive(EPriorityStandard), iStartupPriority(aStartupPriority),
+	  iState(EUsbServiceIdle), iOwner(aOwner)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+/**
+ * Destructor.
+ */
+EXPORT_C CUsbClassControllerBase::~CUsbClassControllerBase()
+	{
+	}
+
+/**
+ * Fetch the owner of the USB class controller.
+ *
+ * @return	The owner of the USB class controller
+ */
+EXPORT_C MUsbClassControllerNotify& CUsbClassControllerBase::Owner() const
+	{
+	return iOwner;
+	}
+
+/**
+ * Get the state of this USB class controller.
+ *
+ * @return	The state of this USB class controller
+ */
+EXPORT_C TUsbServiceState CUsbClassControllerBase::State() const
+	{
+	return iState;
+	}
+
+/**
+ * Get the startup priority of this USB class controller.
+ *
+ * @return	The startup priority of this USB class controller
+ */
+EXPORT_C TInt CUsbClassControllerBase::StartupPriority() const
+	{
+	return iStartupPriority;
+	}
+
+EXPORT_C TInt CUsbClassControllerBase::Compare(const CUsbClassControllerBase& aFirst,
+	const CUsbClassControllerBase& aSecond)
+	{
+	if (aFirst.StartupPriority() < aSecond.StartupPriority()) {
+		return -1;
+	}
+	else if (aFirst.StartupPriority() > aSecond.StartupPriority()) {
+		return 1;
+	}
+	return 0;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classcontroller/SRC/CUsbClassControllerIterator.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,139 @@
+/*
+* Copyright (c) 1997-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:
+* Implements a helper class for iterating over CUsbClassControllerBase 
+* objects.
+*
+*/
+
+/**
+ @file
+*/
+
+
+#include <cusbclasscontrolleriterator.h>
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBSVR");
+#endif
+
+// Panic category only used in debug builds
+#ifdef _DEBUG
+_LIT( KUsbCcIteratorPanicCategory, "UsbCcIterator" );
+#endif
+
+/**
+ * Panic codes for the USB Class Controller Iterator.
+ */
+enum TUsbCcIteratorPanic
+	{
+	/** Class controller index is out of range */
+	EIndexOutOfRange  = 0,
+	};
+
+
+/**
+ * Constructor. Initialises the internal reference to a class array.
+ */
+EXPORT_C CUsbClassControllerIterator::CUsbClassControllerIterator(
+	RPointerArray<CUsbClassControllerBase>& aClassControllerArray)
+	: iClassControllerArray(aClassControllerArray)
+{
+}
+
+/**
+ * Destructor.
+ */
+ EXPORT_C CUsbClassControllerIterator::~CUsbClassControllerIterator()
+	{
+	}
+
+/**
+ * Sets the iterator to the first USB class.
+ *
+ * @return KErrNotFound if there are no USB classes.
+ */
+ EXPORT_C TInt CUsbClassControllerIterator::First()
+	{
+	if (iClassControllerArray.Count() > 0)
+		{
+		iClassControllerIndex = 0;
+		return KErrNone;
+		}
+	return KErrNotFound;
+	}
+
+/**
+ * Sets the iterator to the next USB class.
+ *
+ * @return KErrNotFound if there are no more classes
+ */
+EXPORT_C TInt CUsbClassControllerIterator::Next()
+	{
+	if (iClassControllerIndex < (iClassControllerArray.Count()-1))
+		{
+		iClassControllerIndex++;
+		return KErrNone;
+		}
+	return KErrNotFound;
+	}
+
+/**
+ * Sets the iterator to the previous USB class.
+ *
+ * @return KErrNotFound if there are no more classes
+ */
+EXPORT_C TInt CUsbClassControllerIterator::Previous()
+	{
+	if (iClassControllerIndex > 0)
+		{
+		iClassControllerIndex--;
+		return KErrNone;
+		}
+	return KErrNotFound;
+	}
+
+/**
+ * Finds the specified class in the list of USB classes.
+ *
+ * @return KErrNotFound if the class isn't in the array
+ */
+EXPORT_C TInt CUsbClassControllerIterator::Seek(
+	CUsbClassControllerBase* aClassController)
+	{
+	TInt ret = iClassControllerArray.Find(aClassController);
+
+	if (ret != KErrNotFound)
+		iClassControllerIndex = ret;
+	else
+		return KErrNotFound;
+
+	return KErrNone;
+	}
+
+/**
+ * Gets the current class the iterator's pointing to.
+ *
+ * @return The current class the iterator refers to
+ */
+EXPORT_C CUsbClassControllerBase* CUsbClassControllerIterator::Current()
+	{
+	__ASSERT_DEBUG((iClassControllerIndex >= 0) &&
+		(iClassControllerIndex < iClassControllerArray.Count()),
+		_USB_PANIC(KUsbCcIteratorPanicCategory, EIndexOutOfRange));
+
+	return iClassControllerArray[iClassControllerIndex];
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classcontroller/SRC/CUsbClassControllerPlugIn.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 1997-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:
+* Implements part of UsbMan USB Class Controller Framework.
+* All USB classes to be managed by UsbMan must derive
+* from this class.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <cusbclasscontrollerplugin.h>
+#include <ecom/ecom.h>
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBSVR");
+#endif
+	
+/**
+ * Constructor.
+ *
+ */
+
+EXPORT_C CUsbClassControllerPlugIn::CUsbClassControllerPlugIn(
+	MUsbClassControllerNotify& aOwner, TInt aStartupPriority)
+	: CUsbClassControllerBase(aOwner, aStartupPriority)
+	{
+	}
+
+/**
+ * Constructs a CUsbClassControllerPlugIn object.
+ *
+ * @return	A new CUsbClassControllerPlugIn object	
+ */
+
+EXPORT_C CUsbClassControllerPlugIn* CUsbClassControllerPlugIn::NewL(TUid aImplementationId, 
+	MUsbClassControllerNotify& aOwner) 
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	return (reinterpret_cast<CUsbClassControllerPlugIn*>(REComSession::CreateImplementationL
+		(aImplementationId, _FOFF(CUsbClassControllerPlugIn, iPrivateEComUID),
+			(TAny*) &aOwner)));
+	}
+
+
+/**
+ * Destructor.
+ */
+EXPORT_C CUsbClassControllerPlugIn::~CUsbClassControllerPlugIn()
+	{
+	REComSession::DestroyedImplementation(iPrivateEComUID);
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classcontroller/group/UsbClassController.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 1997-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:
+* usbclassconstroller.mmp
+* USBClassController.dll USB Class Controller Plugin Framework
+*
+*/
+
+/**
+ @file
+*/
+
+
+target			usbclasscontroller.dll //Recommended unpaged
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+targettype		dll
+uid             0x1000008d 0x101fe1da
+VENDORID 0x70000001
+
+sourcepath		../SRC
+source			CUsbClassControllerBase.cpp
+source			CUsbClassControllerPlugIn.cpp
+source			CUsbClassControllerIterator.cpp
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+library			euser.lib
+library			ecom.lib
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classcontroller/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+PRJ_EXPORTS
+../public/CUsbClassControllerBase.h		SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(cusbclasscontrollerbase.h)
+../public/CUsbClassControllerPlugIn.h	SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(cusbclasscontrollerplugin.h)
+../public/CUsbClassControllerIterator.h	SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(cusbclasscontrolleriterator.h)
+../public/MUsbClassControllerNotify.h	SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(musbclasscontrollernotify.h)
+
+PRJ_MMPFILES
+UsbClassController.mmp		// Base DLL for CC functionality
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classcontroller/public/CUsbClassControllerBase.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,139 @@
+/*
+* Copyright (c) 1997-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:
+* Implements part of UsbMan USB Class Framework.
+* All USB classes to be managed by UsbMan must derive
+* from this class.
+*
+*/
+
+/**
+ @file
+*/
+
+#ifndef __CUSBCLASSCONTROLLERBASE_H__
+#define __CUSBCLASSCONTROLLERBASE_H__
+
+#include <e32base.h>
+#include <usbstates.h>
+
+class MUsbClassControllerNotify;
+class TUsbDescriptor;
+
+class CUsbClassControllerBase : public CActive
+/** Base class for Class Controllers.
+
+  @publishedPartner
+  @released 
+ */
+	{
+public:
+	/** Owner
+		@return The owner of the class controller.
+		*/
+	IMPORT_C MUsbClassControllerNotify& Owner() const;
+
+	/** State
+		@return The service state.
+		*/
+	IMPORT_C TUsbServiceState State() const;
+
+	/** StartupPriority
+		@return The relative priority of this class controller.
+		*/
+	IMPORT_C TInt StartupPriority() const;
+
+	/** Compare
+		Static function to compare two class controllers on the basis of their 
+		startup priorities.
+		@param aFirst First class controller.
+		@param aSecond Second class controller.
+		@return Result of comparison of two class controllers.
+		*/
+	IMPORT_C static TInt Compare(const CUsbClassControllerBase&  aFirst, 
+		const CUsbClassControllerBase& aSecond);
+		
+public: // Functions derived from CActive to be implemented by derived classes.
+	/** RunL
+		Framework function. Class controllers are Active Objects, and may if 
+		relevant use that to register interfaces asynchronously.
+		*/
+	virtual void RunL() = 0;
+	
+	/** DoCancel
+		Framework function. 
+		*/
+	virtual void DoCancel() = 0;
+	
+	/** RunError
+		@param aError The error with which RunL left.
+		@return Error. 
+		*/
+	virtual TInt RunError(TInt aError) = 0;
+
+public:
+	/** Destructor
+	*/
+	IMPORT_C virtual ~CUsbClassControllerBase();
+
+public:
+	/** Start
+		Called by the server to get this class controller to register its 
+		interfaces.
+		@param aStatus TRequestStatus to signal completion of the request.
+		*/
+	virtual void Start(TRequestStatus& aStatus) = 0;
+
+	/** Stop
+		Called by the server to get this class controller to deregister its 
+		interfaces.
+		@param aStatus TRequestStatus to signal completion of the request.
+		*/
+	virtual void Stop(TRequestStatus& aStatus) = 0;
+
+	/** GetDescriptorInfo
+		Returns information on the class controller's descriptors.
+		@param aDescriptorInfo Structure to return information in.
+		*/
+	virtual void GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const = 0;
+
+protected:
+	/** Constructor
+		@param aOwner Owner.
+		@param aStartupPriority Relative startup priority of this class controller.
+		*/
+	IMPORT_C CUsbClassControllerBase(MUsbClassControllerNotify& aOwner, TInt aStartupPriority);
+
+protected:
+	/**
+		The relative priority of this class controller. The class controllers 
+		are sorted using their priorities to determine what order to start 
+		them in. 
+		*/
+	const TInt iStartupPriority;
+
+	/**
+		The current service state. This must be kept up-to-date depending on 
+		whether this class controller's interfaces are registered or not.
+		*/
+	TUsbServiceState iState;
+
+	/**
+		Owner.
+		*/
+	MUsbClassControllerNotify& iOwner;
+	};
+
+#endif //__CUSBCLASSCONTROLLERBASE_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classcontroller/public/CUsbClassControllerIterator.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,92 @@
+/*
+* Copyright (c) 1997-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:
+* Defines a helper class used to iterate over a set of USB classes.
+*
+*/
+
+/**
+ @file
+*/
+
+#ifndef __CUSBCLASSCONTROLLERITERATOR_H__
+#define __CUSBCLASSCONTROLLERITERATOR_H__
+
+#include <e32base.h>
+
+class CUsbClassControllerBase;
+
+/** This class is used by CUsbDevice and potentially 
+ * CUsbClassControllerBase-derived classes to iterate over a collection of 
+ * CUsbClassControllerBase objects.
+
+  @publishedPartner
+  @released
+ */
+NONSHARABLE_CLASS(CUsbClassControllerIterator) : public CBase
+	{
+public:
+	/** Constructor
+		@param aClassControllerArray Array of class controllers.
+		*/
+	IMPORT_C CUsbClassControllerIterator(RPointerArray<CUsbClassControllerBase>& aClassControllerArray);
+
+	/** Destructor.
+	*/
+	IMPORT_C ~CUsbClassControllerIterator();
+
+	/** First
+		Sets the iterator to the first class controller.
+		@return Error.
+		*/
+	IMPORT_C TInt First();
+
+	/** Next
+		Sets the iterator to the next class controller.
+		@return Error.
+		*/
+	IMPORT_C TInt Next();
+
+	/** Previous
+		Sets the iterator to the previous class controller.
+		@return Error.
+		*/
+	IMPORT_C TInt Previous();
+
+	/** Seek
+		Sets the current class controller to that given, if it's in the array.
+		@param aClassController The class controller we want to find.
+		@return Error.
+		*/
+	IMPORT_C TInt Seek(CUsbClassControllerBase* aClassController);
+
+	/** Current
+		@return The current class controller. Does not return ownership.
+		*/
+	IMPORT_C CUsbClassControllerBase* Current();
+
+private:
+	/**
+		The array of class controllers.
+		*/
+	RPointerArray<CUsbClassControllerBase>& iClassControllerArray;
+
+	/**
+		Index of current class controller.
+		*/
+	TInt iClassControllerIndex;
+	};
+
+
+#endif //__CUSBCLASSCONTROLLERITERATOR_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classcontroller/public/CUsbClassControllerPlugIn.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,71 @@
+/*
+* Copyright (c) 1997-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:
+* Implements part of UsbMan USB Class Framework.
+* All USB classes to be managed by UsbMan must derive
+* from this class.
+*
+*/
+
+/**
+ @file
+*/
+
+#ifndef CUSBCLASSCONTROLLERPLUGIN_H__
+#define CUSBCLASSCONTROLLERPLUGIN_H__
+
+#include <cusbclasscontrollerbase.h>
+
+
+class MUsbClassControllerNotify;
+
+class CUsbClassControllerPlugIn : public CUsbClassControllerBase
+/** Base class for dynamic Class Controllers, implemented as ECOM plugins.
+
+  @publishedPartner
+  @released
+  */
+	{
+public: 
+	/** Factory function
+		@param aImplementationId The UID of this implementation.
+		@param aOwner Interface to talk to the server.
+		@return Ownership of a new CUsbClassControllerPlugIn.
+		*/
+	IMPORT_C static CUsbClassControllerPlugIn* NewL(TUid aImplementationId, 
+													MUsbClassControllerNotify& aOwner);
+
+	/** Destructor
+	*/
+	IMPORT_C virtual ~CUsbClassControllerPlugIn();
+
+
+
+protected:
+	/** Constructor
+		@param aOwner Interface to talk to the server.
+		@param aStartupPriority The relative priority of this class controller.
+		*/
+	IMPORT_C CUsbClassControllerPlugIn(MUsbClassControllerNotify& aOwner, TInt aStartupPriority);
+
+protected:
+	/**
+		UID given to us by ECOM when the instance is created. Used when the 
+		instance is destroyed.
+	*/
+	TUid iPrivateEComUID;
+	};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classcontroller/public/MUsbClassControllerNotify.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 1997-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:
+* MClassControllerNotify.h
+* Implements part of the USB Class API Framework
+* This is the mixin used by the USB classes to notify UsbMan of failures,
+* and to get an iterator over the set of classes UsbMan owns.
+*
+*/
+
+/**
+ @file
+*/
+
+#ifndef __MUSBCLASSCONTROLLERNOTIFY_H__
+#define __MUSBCLASSCONTROLLERNOTIFY_H__
+
+#include <e32def.h>
+
+class CUsbClassControllerIterator;
+
+/** The MUsbClassControllerNotify class
+ *
+ * Implements part of the USB Class API Framework.
+ * This is the mixin used by the USB classes to notify UsbMan of any changes
+ * in their state.
+
+  @publishedPartner
+  @released
+ */
+class MUsbClassControllerNotify
+	{
+public:
+	/**
+	 * Creates and returns a new iterator over USB classes. The caller takes
+	 * ownership of this iterator.
+	 *
+	 * @return A new iterator
+	 */
+	 virtual CUsbClassControllerIterator*
+		UccnGetClassControllerIteratorL() = 0;
+
+	/**
+	 * Called when a USB class has received an unexpected error and should be
+	 * shut down.
+	 *
+	 * @param aError The error code
+	 */
+	 virtual void UccnError(TInt aError) = 0;
+	};
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,19 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "classimplementation/bld.inf"
+#include "classcontroller/group/bld.inf"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/INC/CUsbACMClassController.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,127 @@
+/**
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class API and talks to C32
+* to manage the ACM.CSY that is used to provide a virtual
+* serial port service to clients
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBACMCLASSCONTROLLER_H__
+#define __CUSBACMCLASSCONTROLLER_H__
+
+#include <e32std.h>
+#include <cusbclasscontrollerplugin.h>
+#ifdef USE_ACM_REGISTRATION_PORT
+#include <c32comm.h>
+#else
+#include <usb/acmserver.h>
+#endif
+class MUsbClassControllerNotify;
+class CIniFile;
+
+const TInt KAcmStartupPriority = 3;
+const TUint KDefaultNumberOfAcmFunctions = 1;
+const TInt KMaximumAcmFunctions = 15;
+
+const TInt KAcmNumberOfInterfacesPerAcmFunction = 2; // data and control interfaces
+// The name of the ini file specifying the number of ACM functions required and optionally their interface names
+_LIT(KAcmFunctionsIniFileName, "NumberOfAcmFunctions.ini");
+_LIT(KAcmConfigSection,"ACM_CONF");
+_LIT(KNumberOfAcmFunctionsKeyWord,"NumberOfAcmFunctions");
+
+_LIT(KAcmSettingsSection,"ACM %d");
+_LIT(KAcmProtocolNum,"ProtocolNum");
+_LIT(KAcmControlIfcName,"ControlInterfaceName");
+_LIT(KAcmDataIfcName,"DataInterfaceName");
+
+// Lengths of the various bits of the ACM descriptor. Taken from the USB
+// WMCDC specification, v1.0.
+const TInt KAcmInterfaceDescriptorLength = 3;
+const TInt KAcmCcHeaderDescriptorLength = 5;
+const TInt KAcmFunctionalDescriptorLength = 4;
+const TInt KAcmCcUfdDescriptorLength = 5;
+const TInt KAcmNotificationEndpointDescriptorLength = 7;
+const TInt KAcmDataClassInterfaceDescriptorLength = 3;
+const TInt KAcmDataClassHeaderDescriptorLength = 5;
+const TInt KAcmDataClassEndpointInDescriptorLength = 7;
+const TInt KAcmDataClassEndpointOutDescriptorLength = 7;
+
+const TInt KAcmDescriptorLength =
+	KAcmInterfaceDescriptorLength +
+	KAcmCcHeaderDescriptorLength +
+	KAcmFunctionalDescriptorLength +
+	KAcmCcUfdDescriptorLength +
+	KAcmNotificationEndpointDescriptorLength +
+	KAcmDataClassInterfaceDescriptorLength +
+	KAcmDataClassHeaderDescriptorLength +
+	KAcmDataClassEndpointInDescriptorLength +
+	KAcmDataClassEndpointOutDescriptorLength;
+	
+/**
+ * The CUsbACMClassController class
+ *
+ * Implements the USB Class Controller API and manages the ACM.CSY
+ */
+NONSHARABLE_CLASS(CUsbACMClassController) : public CUsbClassControllerPlugIn
+	{
+
+public: // New functions.
+	static CUsbACMClassController* NewL(MUsbClassControllerNotify& aOwner);
+
+public: // Functions derived from CBase.
+	virtual ~CUsbACMClassController();
+
+public: // Functions derived from CActive.
+	virtual void RunL();
+	virtual void DoCancel();
+	virtual TInt RunError(TInt aError);
+
+public: // Functions derived from CUsbClassControllerBase
+	virtual void Start(TRequestStatus& aStatus);
+	virtual void Stop(TRequestStatus& aStatus);
+
+	virtual void GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const;
+
+protected:
+	CUsbACMClassController(MUsbClassControllerNotify& aOwner);
+	void ConstructL();
+
+private:
+	void DoStartL();
+	void ReadAcmConfigurationL();
+	void DoStop();
+	void ReadAcmIniDataL(CIniFile* aIniFile, TUint aCount, RBuf& aAcmControlIfcName, RBuf& aAcmDataIfcName);
+
+private:
+#ifdef USE_ACM_REGISTRATION_PORT
+	RCommServ iCommServer;
+	RComm iComm;
+#else
+	RAcmServer iAcmServer;
+#endif
+	TInt iNumberOfAcmFunctions; 
+	TFixedArray<TUint8, KMaximumAcmFunctions> iAcmProtocolNum;
+	TFixedArray<RBuf, KMaximumAcmFunctions> iAcmControlIfcName;
+	TFixedArray<RBuf, KMaximumAcmFunctions> iAcmDataIfcName;
+	};
+
+#endif //__CUSBACMCLASSCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/SRC/101fbf20.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x101fbf20;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x101fbf21;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x101fbf22;
+					version_no = 1;
+					display_name = "ACM";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/SRC/CUsbACMClassController.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,443 @@
+/*
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class Controller API and talks to C32 or ACM server 
+* to manage the ECACM.CSY that is used to provide a virtual serial port service 
+* to clients.
+*
+*/
+
+/**
+ @file
+*/
+
+#include "CUsbACMClassController.h"
+#include <usb_std.h>
+#include <acminterface.h>
+#include <usb/acmserver.h>		
+#include "inifile.h"
+#include "UsbmanInternalConstants.h"
+#include <usb/usblogger.h>
+#include "acmserverconsts.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ACMCC");
+#endif
+
+
+// Panic category 
+_LIT( KAcmCcPanicCategory, "UsbAcmCc" );
+
+
+/**
+ * Panic codes for the USB ACM Class Controller.
+ */
+enum TAcmCcPanic
+	{
+	/** Start called while in an illegal state */
+	EBadApiCallStart = 0,
+	/** Asynchronous function called (not needed, as all requests complete synchronously) */
+	EUnusedFunction = 1,
+	/** Error reading ini file. */
+	EPanicBadIniFile = 2,		
+	/** Bad value for the iNumberOfAcmFunctions member.*/
+	EPanicBadNumberOfAcmFunctions = 3,
+	/** Stop called while in an illegal state */
+	EBadApiCallStop = 4,
+	};
+
+
+/**
+ * Constructs a CUsbACMClassController object
+ *
+ * @param	aOwner	USB Device that owns and manages the class
+ *
+ * @return	A new CUsbACMClassController object
+ */
+CUsbACMClassController* CUsbACMClassController::NewL(MUsbClassControllerNotify& aOwner)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbACMClassController* self = new (ELeave) CUsbACMClassController(aOwner);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/**
+ * Destructor
+ */
+CUsbACMClassController::~CUsbACMClassController()
+	{
+	Cancel();
+
+#ifdef USE_ACM_REGISTRATION_PORT
+	iComm.Close();
+	iCommServer.Close();
+#else
+	// Clean up any interface name strings
+	for ( TUint i = 0 ; i < KMaximumAcmFunctions ; i++ )
+		{
+		iAcmControlIfcName[i].Close();
+		iAcmDataIfcName[i].Close();
+		}
+	iAcmServer.Close();
+#endif // USE_ACM_REGISTRATION_PORT
+	}
+
+/**
+ * Constructor.
+ *
+ * @param	aOwner	USB Device that owns and manages the class
+ */
+CUsbACMClassController::CUsbACMClassController(
+	MUsbClassControllerNotify& aOwner)
+	: CUsbClassControllerPlugIn(aOwner, KAcmStartupPriority),	
+	iNumberOfAcmFunctions(KDefaultNumberOfAcmFunctions)
+	{
+	// Initialise all elements to KDefaultAcmProtocolNum.
+	for ( TUint ii = 0 ; ii < KMaximumAcmFunctions ; ii++ )
+		{
+		iAcmProtocolNum[ii] = KDefaultAcmProtocolNum;
+		// iAcmControlIfcName[ii] and iAcmDataIfcName[ii] are already set to empty strings (RBuf);
+		}
+	}
+
+/**
+ * 2nd Phase Construction.
+ */
+void CUsbACMClassController::ConstructL()
+	{
+	//open ini file to find out how many acm functions are needed and read in their configuration data
+	ReadAcmConfigurationL();
+
+	// Prepare to use whichever mechanism is enabled to control bringing ACM 
+	// functions up and down.
+#ifdef USE_ACM_REGISTRATION_PORT
+
+	LEAVEIFERRORL(iCommServer.Connect());
+	LEAVEIFERRORL(iCommServer.LoadCommModule(KAcmCsyName));
+	TName portName(KAcmSerialName);
+	portName.AppendFormat(_L("::%d"), 666);
+	// Open the registration port in shared mode in case other ACM CCs want to 
+	// open it.
+	LEAVEIFERRORL(iComm.Open(iCommServer, portName, ECommShared)); 
+
+#else
+
+	LEAVEIFERRORL(iAcmServer.Connect());
+
+#endif // USE_ACM_REGISTRATION_PORT
+	}
+
+/**
+* Searches numberofacmfunctions.ini file for protocol number and for control and data
+* interface names, leaving if any is not found.
+*/
+void CUsbACMClassController::ReadAcmIniDataL(CIniFile* aIniFile, TUint aCount, RBuf& aAcmControlIfcName, RBuf& aAcmDataIfcName)
+	{
+	LOG_FUNC
+	
+	TName sectionName;
+	TInt  protocolNum;
+
+#ifdef __FLOG_ACTIVE
+	TName acmProtocolNum(KAcmProtocolNum);
+	TBuf8<KMaxName> narrowAcmProtocolNum;
+	narrowAcmProtocolNum.Copy(acmProtocolNum);
+#endif
+	LOGTEXT3(_L8("\tLooking for ACM Section %d, keyword \"%S\""), aCount+1, &narrowAcmProtocolNum);
+
+	sectionName.Format(KAcmSettingsSection,(aCount+1));
+	
+#ifdef __FLOG_ACTIVE
+	// Set up useful narrow logging strings.
+	TBuf8<KMaxName> narrowSectionName;
+	narrowSectionName.Copy(sectionName);
+#endif
+	LOGTEXT2(_L8("\t  Section Name %S"), &narrowSectionName);
+
+	if (aIniFile->FindVar(sectionName, KAcmProtocolNum(), protocolNum))
+		{
+		LOGTEXT3(_L8("\tACM Section %d: Protocol No %d"),aCount+1, protocolNum);
+		iAcmProtocolNum[aCount] = static_cast<TUint8>(protocolNum);
+		}
+
+	// Search ini file for interface names. If either of the interface names does not exist then the
+	// descriptors remain at zero length. This is caught in DoStartL and the descriptors defaulted.
+	// Using this method saves memory on storing copies of the default interface names.
+	TPtrC ptrControlIfcName;
+	if (aIniFile->FindVar(sectionName, KAcmControlIfcName(), ptrControlIfcName))
+		{
+		TPtrC ptrDataIfcName;
+		if (aIniFile->FindVar(sectionName, KAcmDataIfcName(), ptrDataIfcName))
+			{
+			// Only copy the data if both interface names are valid
+			aAcmControlIfcName.CreateL(ptrControlIfcName);
+			aAcmControlIfcName.CleanupClosePushL();
+			aAcmDataIfcName.CreateL(ptrDataIfcName);
+			CleanupStack::Pop(&aAcmControlIfcName);
+			}
+		}
+	
+#ifdef __FLOG_ACTIVE
+	// Set up useful narrow logging strings.
+	TName dbgControlIfcName(aAcmControlIfcName);
+	TBuf8<KMaxName> narrowControlIfcName;
+	narrowControlIfcName.Copy(dbgControlIfcName);
+
+	TName dbgDataIfcName(aAcmDataIfcName);
+	TBuf8<KMaxName> narrowDataIfcName;
+	narrowDataIfcName.Copy(dbgDataIfcName);
+#endif
+	LOGTEXT2(_L8("\t  Control Interface Name %S"), &narrowControlIfcName);
+	LOGTEXT2(_L8("\t  Data Interface Name %S"), &narrowDataIfcName);
+	}
+	
+/**
+Called when class Controller constructed 
+It opens a numberofacmfunctions.ini file and gets the info from there
+Error behaviour: 
+If the ini file is not found the number of ACM functions, their protocol 
+settings and interface names will be the default values.
+If a memory error occurs then leaves with KErrNoMemory.
+If the ini file is created but the file contains invalid configuration then panic.
+*/
+void CUsbACMClassController::ReadAcmConfigurationL()
+	{
+	LOG_FUNC
+	
+	// The number of ACM functions should at this point be as set in the 
+	// constructor.
+	__ASSERT_DEBUG(static_cast<TUint>(iNumberOfAcmFunctions) == KDefaultNumberOfAcmFunctions, 
+		_USB_PANIC(KAcmCcPanicCategory, EPanicBadNumberOfAcmFunctions));
+	
+	LOGTEXT3(_L("\ttrying to open file \"%S\" in directory \"%S\""), 
+		&KAcmFunctionsIniFileName, &KUsbManPrivatePath);
+	
+	// First find the file
+	CIniFile* iniFile = NULL;
+	TRAPD (error, iniFile = CIniFile::NewL(KAcmFunctionsIniFileName, KUsbManPrivatePath));
+	
+	if (error == KErrNotFound)
+		{	
+		LOGTEXT(_L8("\tfile not found"));
+		}
+	else if (error != KErrNone)
+		{
+		LOGTEXT(_L8("\tini file was found, but couldn't be opened"));
+		LEAVEL(error);	
+		}
+	else 
+		{
+		LOGTEXT(_L8("\tOpened ini file"));
+		LOGTEXT3(_L("\tLooking for Section \"%S\", keyword \"%S\""), 
+			&KAcmConfigSection, &KNumberOfAcmFunctionsKeyWord);
+
+		CleanupStack::PushL(iniFile);
+		if ( !iniFile->FindVar(KAcmConfigSection(), KNumberOfAcmFunctionsKeyWord(), iNumberOfAcmFunctions) )
+			{
+			// PANIC since this should only happen in development environment. 
+			// The file is incorrectly written.
+			LOGTEXT(_L8("\tCan't find item"));
+			_USB_PANIC(KAcmCcPanicCategory, EPanicBadNumberOfAcmFunctions);
+			}
+					
+		LOGTEXT2(_L8("\tini file specifies %d ACM function(s)"), iNumberOfAcmFunctions);
+		
+		for ( TUint i = 0 ; i < iNumberOfAcmFunctions ; i++ )
+			{
+	 		 // Search ini file for the protocol number and interface names for 
+	 		 // the function, using defaults if any are not found.
+	 		 // May leave with KErrNoMemory.
+	 		 ReadAcmIniDataL(iniFile, i, iAcmControlIfcName[i], iAcmDataIfcName[i]);
+	 		 }
+		CleanupStack::PopAndDestroy(iniFile);
+		}
+	}
+	
+/**
+ * Called by UsbMan when it wants to start the USB ACM class. This always
+ * completes immediately.
+ *
+ * @param aStatus The caller's request status, filled in with an error code
+ */
+void CUsbACMClassController::Start(TRequestStatus& aStatus)
+	{
+	LOG_FUNC;
+
+	// We should always be idle when this function is called (guaranteed by
+	// CUsbSession).
+	__ASSERT_DEBUG( iState == EUsbServiceIdle, _USB_PANIC(KAcmCcPanicCategory, EBadApiCallStart) );
+
+	TRequestStatus* reportStatus = &aStatus;
+	TRAPD(err, DoStartL());
+	iState = (err == KErrNone) ? EUsbServiceStarted : EUsbServiceIdle;
+	User::RequestComplete(reportStatus, err);
+	}
+
+void CUsbACMClassController::DoStartL()
+	{
+	LOG_FUNC
+
+	iState = EUsbServiceStarting;
+
+#ifdef USE_ACM_REGISTRATION_PORT
+
+	// Create ACM functions.
+	TUint acmSetting;
+	for ( TUint i = 0 ; i < iNumberOfAcmFunctions ; i++ )
+		{
+		// indicate the number of ACMs to create, and its protocol number (in the 3rd-lowest byte)
+		acmSetting = 1 | (static_cast<TUint>(iAcmProtocolNum[i])<< 16); 
+		TInt err = iComm.SetSignalsToMark(acmSetting);
+		if ( err != KErrNone )
+			{
+			LOGTEXT2(_L8("    SetSignalsToMark error = %d"), err);
+			if (i != 0)
+				{
+				// Must clear any ACMs that have completed.
+				// only other than KErrNone if C32 Server fails
+				(void)iComm.SetSignalsToSpace(i);
+				}
+			LEAVEL(err);
+			}
+		}
+
+#else // use ACM server
+
+	// Create ACM functions
+	for ( TInt i = 0 ; i < iNumberOfAcmFunctions ; i++ )
+		{
+		TInt err;
+		// Check for zero length descriptor and default it if so
+		if (iAcmControlIfcName[i].Length())
+			{
+			err = iAcmServer.CreateFunctions(1, iAcmProtocolNum[i], iAcmControlIfcName[i], iAcmDataIfcName[i]);
+			}
+		else
+			{
+			err = iAcmServer.CreateFunctions(1, iAcmProtocolNum[i], KControlIfcName, KDataIfcName);
+			}
+
+		if ( err != KErrNone )
+			{
+			LOGTEXT2(_L8("\tFailed to create ACM function. Error: %d"), err);
+			if (i != 0)
+				{
+				//Must clear any ACMs that have been completed
+				iAcmServer.DestroyFunctions(i);
+				LOGTEXT2(_L8("\tDestroyed %d Interfaces"), i);
+				}
+			LEAVEL(err);
+			}
+		}
+
+#endif // USE_ACM_REGISTRATION_PORT
+	
+	LOGTEXT2(_L8("\tCreated %d ACM Interfaces"), iNumberOfAcmFunctions);
+	}
+
+/**
+ * Called by UsbMan when it wants to stop the USB ACM class.
+ *
+ * @param aStatus The caller's request status: always set to KErrNone
+ */
+void CUsbACMClassController::Stop(TRequestStatus& aStatus)
+	{
+	LOG_FUNC;
+
+	// We should always be started when this function is called (guaranteed by
+	// CUsbSession).
+	__ASSERT_DEBUG( iState == EUsbServiceStarted, _USB_PANIC(KAcmCcPanicCategory, EBadApiCallStop) );
+
+	TRequestStatus* reportStatus = &aStatus;
+	DoStop();
+	User::RequestComplete(reportStatus, KErrNone);
+	}
+
+/**
+ * Gets information about the descriptor which this class provides.
+ *
+ * @param aDescriptorInfo Descriptor info structure filled in by this function
+ */
+void CUsbACMClassController::GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const
+	{
+	LOG_FUNC;
+
+	aDescriptorInfo.iLength = KAcmDescriptorLength;
+	aDescriptorInfo.iNumInterfaces = KAcmNumberOfInterfacesPerAcmFunction*(iNumberOfAcmFunctions);
+	}
+
+/**
+Destroys ACM functions we've already brought up.
+ */
+void CUsbACMClassController::DoStop()
+	{
+	LOG_FUNC;
+
+	if (iState == EUsbServiceStarted)
+		{
+#ifdef USE_ACM_REGISTRATION_PORT
+		TInt err = iComm.SetSignalsToSpace(iNumberOfAcmFunctions);
+		__ASSERT_DEBUG(err == KErrNone, User::Invariant());
+		//the implementation in CRegistrationPort always return KErrNone
+		(void)err;
+		// If there is an error here, USBSVR will just ignore it, but 
+		// it indicates that our interfaces are still up. We know the CSY 
+		// doesn't raise an error, but an IPC error may have occurred. This is 
+		// a problem with USBSVR in general- Stops are more or less assumed to 
+		// work.
+#else
+		// Destroy interfaces. Can't do anything with an error here.
+		static_cast<void>(iAcmServer.DestroyFunctions(iNumberOfAcmFunctions));
+#endif // USE_ACM_REGISTRATION_PORT
+		
+		LOGTEXT2(_L8("\tDestroyed %d Interfaces"), iNumberOfAcmFunctions);
+
+		iState = EUsbServiceIdle;
+		}
+	}
+
+/**
+ * Standard active object RunL. Never called because this class has no
+ * asynchronous requests.
+ */
+void CUsbACMClassController::RunL()
+	{
+	__ASSERT_DEBUG( EFalse, _USB_PANIC(KAcmCcPanicCategory, EUnusedFunction) );
+	}
+
+/**
+ * Standard active object cancellation function. Never called because this
+ * class has no asynchronous requests.
+ */
+void CUsbACMClassController::DoCancel()
+	{
+	__ASSERT_DEBUG( EFalse, _USB_PANIC(KAcmCcPanicCategory, EUnusedFunction) );
+	}
+
+/**
+ * Standard active object error function. Never called because this class has
+ * no asynchronous requests, and hence its RunL is never called.
+ *
+ * @param aError The error code (unused)
+ * @return Always KErrNone to avoid an active scheduler panic
+ */
+TInt CUsbACMClassController::RunError(TInt /*aError*/)
+	{
+	__ASSERT_DEBUG( EFalse, _USB_PANIC(KAcmCcPanicCategory, EUnusedFunction) );
+	return KErrNone;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/SRC/CUsbAcmClassImpCollection.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 1997-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:
+* Defines the implementation collection for the ACM class controller.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32base.h>
+#include <e32std.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include "CUsbACMClassController.h"
+
+// Define the private interface UIDs
+const TImplementationProxy UsbCCImplementationTable[] =
+    {
+	IMPLEMENTATION_PROXY_ENTRY(0x101fbf22, CUsbACMClassController::NewL),
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(UsbCCImplementationTable) / sizeof(TImplementationProxy);
+
+    return UsbCCImplementationTable;
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/group/AcmClassController.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 1997-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:
+* ACMClassController.dll USB ACM Class Controller plug in, used to load/start/stop the ECACM CSY
+*
+*/
+
+/**
+ @file
+*/
+
+
+target acmclasscontroller.dll //Recommended unpaged
+
+start resource ../SRC/101fbf20.rss
+target acmclasscontroller.rsc
+END
+
+LIBRARY acmserver.lib
+
+#include "AcmClassControllerBase.mmp"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/group/AcmClassControllerBase.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,43 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+targettype plugin
+
+UID              	0x10009d8d 0x101fbf20
+VENDORID 0x70000001
+
+SOURCEPATH		../SRC
+SOURCE			CUsbAcmClassImpCollection.cpp
+SOURCE			CUsbACMClassController.cpp
+
+SOURCEPATH		../../../../../inifile/src
+SOURCE			inifile.cpp
+
+USERINCLUDE		../INC
+USERINCLUDE		../../../../../inifile/inc
+USERINCLUDE		../../classimplementation/ecacm/public
+USERINCLUDE		../../../../../usbman/server/public
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY			euser.lib 
+LIBRARY			usbclasscontroller.lib
+LIBRARY			efsrv.lib
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/group/NumberOfAcmFunctions.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,17 @@
+//[ACM X] is referring to the Xth ACM *function*
+//which is accessed by the (X-1)th ACM *port*.
+
+
+[ACM_CONF]
+NumberOfAcmFunctions= 1
+
+[ACM 1]
+ProtocolNum= 1     //0x01 - code taken from USBCDC 1.1 Table 17- Hayes compatible modem
+//ControlInterfaceName= CDCUserControlInterface
+//DataInterfaceName= CDCUserDataInterface
+
+//[AMC 2]
+//ProtocolNum= 255  //0xFF - Vendor-specific
+//ControlInterfaceName= CDCSpecificControlInterface
+//DataInterfaceName= CDCSpecificDataInterface
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+PRJ_EXPORTS
+NumberOfAcmFunctions.ini	/epoc32/data/z/private/101fe1db/numberofacmfunctions.ini
+
+PRJ_MMPFILES
+
+//
+// Note the ACM Class controller must be built
+// on all platforms
+//
+
+// ACM Class Controller plugin support ACM::1 functions by default.  The number of 
+// ACM functions can be changed by editing NumberOfAcmFunctions.ini file
+AcmClassController.mmp		
+
+PRJ_TESTMMPFILES
+
+// Old-style ACM Class Controller, using the registration port - used for regression testing
+t_regport_AcmClassController.mmp
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/group/t_regport_AcmClassController.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/*
+* 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 "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:
+* t_regport_ACMClassController.dll Test USB ACM Class Controller 
+* plugin using registration port to control ACM interfaces.
+*
+*/
+
+/**
+ @file
+*/
+
+// This macro means the ACM Class Controller uses the deprecated registration 
+// port mechanism to control ACM functions.
+MACRO USE_ACM_REGISTRATION_PORT
+
+target t_regport_acmclasscontroller.dll
+
+start resource ../SRC/101fbf20.rss
+target t_regport_acmclasscontroller.rsc
+END
+
+LIBRARY c32.lib
+
+#include "AcmClassControllerBase.mmp"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/EABI/acmserverU.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,12 @@
+EXPORTS
+	_ZN10RAcmServer15CreateFunctionsEj @ 1 NONAME
+	_ZN10RAcmServer15CreateFunctionsEjh @ 2 NONAME
+	_ZN10RAcmServer16DestroyFunctionsEj @ 3 NONAME
+	_ZN10RAcmServer5CloseEv @ 4 NONAME
+	_ZN10RAcmServer7ConnectEv @ 5 NONAME
+	_ZN10RAcmServerC1Ev @ 6 NONAME
+	_ZN10RAcmServerC2Ev @ 7 NONAME
+	_ZN10RAcmServerD1Ev @ 8 NONAME
+	_ZN10RAcmServerD2Ev @ 9 NONAME
+	_ZN10RAcmServer15CreateFunctionsEjhRK7TDesC16S2_ @ 10 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/bwins/acmserverU.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,10 @@
+EXPORTS
+	??0RAcmServer@@QAE@XZ @ 1 NONAME ; RAcmServer::RAcmServer(void)
+	??1RAcmServer@@QAE@XZ @ 2 NONAME ; RAcmServer::~RAcmServer(void)
+	?Connect@RAcmServer@@QAEHXZ @ 3 NONAME ; int RAcmServer::Connect(void)
+	?CreateFunctions@RAcmServer@@QAEHI@Z @ 4 NONAME ; int RAcmServer::CreateFunctions(unsigned int)
+	?CreateFunctions@RAcmServer@@QAEHIE@Z @ 5 NONAME ; int RAcmServer::CreateFunctions(unsigned int, unsigned char)
+	?DestroyFunctions@RAcmServer@@QAEHI@Z @ 6 NONAME ; int RAcmServer::DestroyFunctions(unsigned int)
+	?Close@RAcmServer@@QAEXXZ @ 7 NONAME ; void RAcmServer::Close(void)
+	?CreateFunctions@RAcmServer@@QAEHIEABVTDesC16@@0@Z @ 8 NONAME ; int RAcmServer::CreateFunctions(unsigned int, unsigned char, class TDesC16 const &, class TDesC16 const &)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/group/acmserver.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+/*
+* 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 "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:
+* acmserver.dll Client side DLL for interaction with ACM function 
+* server.
+*
+*/
+
+/**
+ @file
+*/
+
+TARGET			acmserver.dll
+CAPABILITY 		NetworkControl LocalServices NetworkServices CommDD ProtServ
+TARGETTYPE		DLL
+
+// dll uid + unique uid
+UID      0x10005054 0x10281A7E
+
+VENDORID 0x70000001
+
+SOURCEPATH      ../src								  
+SOURCE			acmserver.cpp
+SOURCE			acmserverimpl.cpp
+SOURCE			acmserverclient.cpp
+
+USERINCLUDE		../inc
+USERINCLUDE		../../ecacm/public
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY			euser.lib 
+LIBRARY			c32.lib
+
+#include <usb/usblogger.mmh>
+
+UNPAGED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,26 @@
+/*
+* 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 "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
+*/
+
+PRJ_EXPORTS
+../public/acmserver.h		SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/acmserver.h)
+
+PRJ_MMPFILES
+acmserver.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/inc/acmserverclient.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,50 @@
+/*
+* 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 "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
+ @internalTechnology
+*/
+
+#ifndef __ACMSERVERCLIENT_H__
+#define __ACMSERVERCLIENT_H__
+
+#include <e32base.h>
+
+/**
+Client-side interface to the ACM server to create new ACM functions.
+This class MUST NOT be used outside Symbian.
+*/
+NONSHARABLE_CLASS(RAcmServerClient) : public RSessionBase
+	{
+public:
+	RAcmServerClient();
+	~RAcmServerClient();
+
+public:
+	TInt Connect();
+	TVersion Version() const;
+
+public:
+	TInt CreateFunctions(const TUint aNoAcms, const TUint8 aProtocolNum, const TDesC& aAcmControlIfcName, const TDesC& aAcmDataIfcName);
+	TInt DestroyFunctions(const TUint aNoAcms);
+
+private:
+	void ConnectL();
+	};
+
+#endif // __ACMSERVERCLIENT_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/inc/acmserverimpl.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,57 @@
+/*
+* 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 "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
+ @internalTechnology
+*/
+
+#ifndef __ACMSERVERIMPL_H__
+#define __ACMSERVERIMPL_H__
+
+#include <e32base.h>
+#include <c32comm.h>
+#include "acmserverclient.h"
+
+/**
+This is the 'body' of the RAcmServer - CAcmServerImpl handle-body system. 
+Handle-body enables us to alter the implementation of ACM control whilst 
+maintaining the same binary interface with clients.
+This class MUST NOT be used outside Symbian.
+Specifically, it is responsible for making sure that the ECACM CSY is loaded 
+(= ACM server running) and connecting an IPC channel to the ACM server.
+*/
+NONSHARABLE_CLASS(CAcmServerImpl) : public CBase
+	{
+public:
+	static CAcmServerImpl* NewL();
+	~CAcmServerImpl();
+
+public:
+	TInt CreateFunctions(const TUint aNoAcms, const TUint8 aProtocolNum, const TDesC& aAcmControlIfcName, const TDesC& aAcmDataIfcName);
+	TInt DestroyFunctions(const TUint aNoAcms);
+
+private:
+	CAcmServerImpl();
+	void ConstructL();
+
+private:
+	RCommServ iCommServ;
+	RAcmServerClient iAcmServerClient;
+	};
+
+#endif // __ACMSERVERIMPL_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/public/acmserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,114 @@
+/*
+* 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 "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
+ @publishedPartner
+ @released
+*/
+
+#ifndef __ACMSERVER_H__
+#define __ACMSERVER_H__
+
+#include <e32base.h>
+
+class CAcmServerImpl;
+
+/**
+Client interface to the ACM server to create new ACM functions.
+This class is intended to be used both inside and outside Symbian to bring up 
+and tear down ACM functions.
+*/
+NONSHARABLE_CLASS(RAcmServer)
+	{
+public:
+	/** 
+	Standard constructor. Does not connect the handle to the service provider. 
+	*/
+	IMPORT_C RAcmServer();
+
+	/** 
+	Standard destructor. Does not disconnect the handle from the service 
+	provider. 
+	*/
+	IMPORT_C ~RAcmServer();
+
+public:
+	/**
+	Connects this handle to the service provider.
+	@return Error.
+	*/
+	IMPORT_C TInt Connect();
+
+	/**
+	Closes this handle to the service provider. If the handle has been 
+	successfully Connected, it must eventually be Closed.
+	*/
+	IMPORT_C void Close();
+
+public:
+	/**
+	Creates aNoAcms ACM functions using the default settings.
+	The default setting includes KDefaultAcmProtocolNum- protocol code 0x01 
+	(Hayes compatible, from USBCDC 1.1 Table 17).
+	@param aNoAcms Number of ACM functions to be created.
+	@return Error.
+	*/
+	IMPORT_C TInt CreateFunctions(const TUint aNoAcms);
+
+	/**
+	Creates aNoAcms ACM functions using the protocol number given (as defined 
+	in USBCDC 1.1 - Table 17).
+	@param aNoAcms Number of ACM functions to be created.
+	@param aProtocolNum Protocol setting for the ACM functions to be created.
+	@return Error.
+	*/
+	IMPORT_C TInt CreateFunctions(const TUint aNoAcms, const TUint8 aProtocolNum);
+
+	/**
+	Creates aNoAcms ACM functions using the protocol number given (as defined 
+	in USBCDC 1.1 - Table 17).
+	@param aNoAcms Number of ACM functions to be created.
+	@param aProtocolNum Protocol setting for the ACM function to be created.
+	@param aAcmControlIfcName Control Interface Name for the ACM function to be created.
+	@param aAcmDataIfcName Data Interface Name for the ACM function to be created.
+	@return Error.
+	*/
+	IMPORT_C TInt CreateFunctions(const TUint aNoAcms, const TUint8 aProtocolNum, const TDesC& aAcmControlIfcName, const TDesC& aAcmDataIfcName);
+
+	/**
+	Destroys aNoAcms ACM functions.
+	Class Controllers MUST NOT destroy more ACM functions than they have 
+	successfully created.
+	@param aNoAcms Number of ACM interfaces to destroy.
+	@return Error.
+	*/
+	IMPORT_C TInt DestroyFunctions(const TUint aNoAcms);
+
+private:
+	/** 
+	Private copy constructor to avoid problems with multiple ownership of 
+	RAcmServerImpls.
+	*/
+	RAcmServer(const RAcmServer& aObjectToCopy);
+
+private: // owned
+	// The 'body' used by this handle.
+	CAcmServerImpl* iImpl;	
+	};
+
+#endif // __ACMSERVER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/src/acmserver.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,125 @@
+/*
+* 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 "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
+*/
+
+#include <e32base.h>
+#include <usb/acmserver.h>
+#include "acmserverimpl.h"
+#include <usb/usblogger.h>
+#include "acmserverconsts.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ACMSVRCLI");
+#endif
+
+/** Panic category for users of RAcmServer. */
+#ifdef _DEBUG
+_LIT(KAcmSrvPanicCat, "ACMSVR");
+#endif
+
+/** Panic codes for users of RAcmServer. */
+enum TAcmServerClientPanic
+	{
+	/** The handle has not been connected. */
+	EPanicNotConnected = 0,
+	
+	/** The handle has already been connected. */
+	EPanicAlreadyConnected = 1,
+
+	/** The client has requested to instantiate zero ACM functions, which 
+	makes no sense. */
+	EPanicCantInstantiateZeroAcms = 2,
+	
+	/** The client has requested to destroy zero ACM functions, which makes no 
+	sense. */
+	EPanicCantDestroyZeroAcms = 3,
+
+	/** Close has not been called before destroying the object. */
+	EPanicNotClosed = 4,
+	};
+
+EXPORT_C RAcmServer::RAcmServer() 
+ :	iImpl(NULL)
+	{
+	LOG_FUNC
+	}
+	   
+EXPORT_C RAcmServer::~RAcmServer()
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG(!iImpl, _USB_PANIC(KAcmSrvPanicCat, EPanicNotClosed));
+	}
+
+EXPORT_C TInt RAcmServer::Connect()
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG(!iImpl, _USB_PANIC(KAcmSrvPanicCat, EPanicAlreadyConnected));
+	TRAPD(err, iImpl = CAcmServerImpl::NewL());
+	return err;
+	}
+
+EXPORT_C void RAcmServer::Close()
+	{
+	LOG_FUNC
+
+	delete iImpl;
+	iImpl = NULL;
+	}
+
+EXPORT_C TInt RAcmServer::CreateFunctions(const TUint aNoAcms)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taNoAcms = %d"), aNoAcms);
+
+	__ASSERT_DEBUG(iImpl, _USB_PANIC(KAcmSrvPanicCat, EPanicNotConnected));
+	__ASSERT_DEBUG(aNoAcms, _USB_PANIC(KAcmSrvPanicCat, EPanicCantInstantiateZeroAcms));
+	return iImpl->CreateFunctions(aNoAcms, KDefaultAcmProtocolNum, KControlIfcName, KDataIfcName);
+	}
+							
+EXPORT_C TInt RAcmServer::CreateFunctions(const TUint aNoAcms, const TUint8 aProtocolNum)
+	{
+	LOG_FUNC
+	LOGTEXT3(_L8("\taNoAcms = %d, aProtocolNum = %d"), aNoAcms, aProtocolNum);
+
+	__ASSERT_DEBUG(iImpl, _USB_PANIC(KAcmSrvPanicCat, EPanicNotConnected));
+	__ASSERT_DEBUG(aNoAcms, _USB_PANIC(KAcmSrvPanicCat, EPanicCantInstantiateZeroAcms));
+	return iImpl->CreateFunctions(aNoAcms, aProtocolNum, KControlIfcName, KDataIfcName);
+	}
+
+EXPORT_C TInt RAcmServer::CreateFunctions(const TUint aNoAcms, const TUint8 aProtocolNum, const TDesC& aAcmControlIfcName, const TDesC& aAcmDataIfcName)
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG(iImpl, _USB_PANIC(KAcmSrvPanicCat, EPanicNotConnected));
+	__ASSERT_DEBUG(aNoAcms, _USB_PANIC(KAcmSrvPanicCat, EPanicCantInstantiateZeroAcms));
+	return iImpl->CreateFunctions(aNoAcms, aProtocolNum, aAcmControlIfcName, aAcmDataIfcName);
+	}
+
+EXPORT_C TInt RAcmServer::DestroyFunctions(const TUint aNoAcms)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taNoAcms = %d"), aNoAcms);
+
+	__ASSERT_DEBUG(iImpl, _USB_PANIC(KAcmSrvPanicCat, EPanicNotConnected));
+	__ASSERT_DEBUG(aNoAcms, _USB_PANIC(KAcmSrvPanicCat, EPanicCantDestroyZeroAcms));
+	return iImpl->DestroyFunctions(aNoAcms);
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/src/acmserverclient.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,90 @@
+/*
+* 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 "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
+*/
+
+#include <e32base.h>
+#include "acmserverclient.h"
+#include "acmserverconsts.h"
+#include <usb/usblogger.h>
+#include <usb/acmserver.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ACMSVRCLI");
+#endif
+
+/** Constructor */
+RAcmServerClient::RAcmServerClient() 
+	{
+	LOG_FUNC
+	}
+	   
+/** Destructor */
+RAcmServerClient::~RAcmServerClient()
+	{
+	LOG_FUNC
+	}
+
+/**
+Getter for the version of the server.
+@return Version of the server
+*/
+TVersion RAcmServerClient::Version() const
+	{
+	LOG_FUNC
+
+	return TVersion(	KAcmSrvMajorVersionNumber,
+						KAcmSrvMinorVersionNumber,
+						KAcmSrvBuildNumber
+					);
+	}
+
+/**
+Connect the handle to the server.
+Must be called before all other methods (except Version and Close).
+@return Symbian error code
+*/
+TInt RAcmServerClient::Connect()
+	{
+	LOG_FUNC
+
+	return CreateSession(KAcmServerName, Version(), 1);
+	}
+
+TInt RAcmServerClient::CreateFunctions(const TUint aNoAcms, const TUint8 aProtocolNum, const TDesC& aAcmControlIfcName, const TDesC& aAcmDataIfcName)
+	{
+	LOG_FUNC
+	LOGTEXT5(_L("\taNoAcms = %d, aProtocolNum = %d, Control Ifc Name = %S, Data Ifc Name = %S"),
+			aNoAcms, aProtocolNum, &aAcmControlIfcName, &aAcmDataIfcName);
+
+	TIpcArgs args;
+	args.Set(0, aNoAcms);
+	args.Set(1, aProtocolNum);
+	args.Set(2, &aAcmControlIfcName);
+	args.Set(3, &aAcmDataIfcName);
+	return SendReceive(EAcmCreateAcmFunctions, args);
+	}
+
+TInt RAcmServerClient::DestroyFunctions(const TUint aNoAcms)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taNoAcms = %d"), aNoAcms);
+
+	return SendReceive(EAcmDestroyAcmFunctions, TIpcArgs(aNoAcms));
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/acmserver/src/acmserverimpl.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,89 @@
+/*
+* 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 "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
+*/
+
+#include <e32base.h>
+#include "acmserverimpl.h"
+#include <usb/usblogger.h>
+#include <acminterface.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ACMSVRCLI");
+#endif
+
+/** Constructor */
+CAcmServerImpl::CAcmServerImpl() 
+	{
+	LOG_FUNC
+	}
+	   
+/** Destructor */
+CAcmServerImpl::~CAcmServerImpl()
+	{
+	LOG_FUNC
+
+	iCommServ.Close();
+	iAcmServerClient.Close();
+	}
+
+/**
+2-phase construction.
+@return Ownership of a new CAcmServerImpl.
+*/
+CAcmServerImpl* CAcmServerImpl::NewL()
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CAcmServerImpl* self = new(ELeave) CAcmServerImpl;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+void CAcmServerImpl::ConstructL()
+	{
+	LOG_FUNC
+
+	// In order to connect a session, the ECACM CSY must be loaded (it 
+	// contains the server).
+	LEAVEIFERRORL(iCommServ.Connect());
+	LEAVEIFERRORL(iCommServ.LoadCommModule(KAcmCsyName));
+	// NB RCommServ::Close undoes LoadCommModule.
+	LEAVEIFERRORL(iAcmServerClient.Connect());
+	// iCommServ is eventually cleaned up in our destructor. It must be held 
+	// open at least as long as our session on the ACM server, otherwise 
+	// there's a risk the ACM server will be pulled from under our feet.
+	}
+
+TInt CAcmServerImpl::CreateFunctions(const TUint aNoAcms, const TUint8 aProtocolNum, const TDesC& aAcmControlIfcName, const TDesC& aAcmDataIfcName)
+	{
+	LOG_FUNC
+
+	return iAcmServerClient.CreateFunctions(aNoAcms, aProtocolNum, aAcmControlIfcName, aAcmDataIfcName);
+	}
+
+TInt CAcmServerImpl::DestroyFunctions(const TUint aNoAcms)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taNoAcms = %d"), aNoAcms);
+
+	return iAcmServerClient.DestroyFunctions(aNoAcms);
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,19 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "acmserver/group/bld.inf"
+#include "ecacm/group/bld.inf"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/BWINS/ECACMu.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,3 @@
+EXPORTS
+	LibEntryL @ 1 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/EABI/ecacmU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,3 @@
+EXPORTS
+	LibEntryL @ 1 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 1999-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:
+* Build information for USB class support
+*
+*/
+
+/**
+ @file
+*/
+
+
+PRJ_EXPORTS
+../public/AcmInterface.h 		SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(acminterface.h)
+ecacm.ini						/epoc32/data/z/system/data/ecacm.ini
+../public/AcmConfig.h				SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/acmconfig.h)
+
+PRJ_MMPFILES
+ECACM.MMP
+
+PRJ_TESTEXPORTS
+../public/acmserverconsts.h 	SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/acmserverconsts.h)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/group/ECACM.MMP	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 1997-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:
+* Top-level project file for ECACM.CSY
+* ecacm.csy Comms server plug-in for USB
+*
+*/
+
+/**
+ @file
+*/
+
+
+TARGET			ecacm.csy
+CAPABILITY CommDD PowerMgmt ReadDeviceData WriteDeviceData TrustedUI ProtServ NetworkControl NetworkServices LocalServices ReadUserData WriteUserData
+TARGETTYPE		dll
+
+NOEXPORTLIBRARY
+
+//
+// We have a laggard, ill-defined UID3 which must be kept
+// for old platforms for BC.  For newer platforms, we use
+// KUidECACM = 0x10201EF6
+//
+uid			0x10005054 0x10201EF6
+
+SOURCEPATH		../src
+SOURCE			AcmPort.cpp
+SOURCE			AcmPortFactory.cpp 
+SOURCE			AcmReader.cpp
+SOURCE			AcmWriter.cpp
+SOURCE			linkstatenotifier.cpp
+SOURCE			ActiveReader.cpp 
+SOURCE			ActiveReadOneOrMoreReader.cpp
+SOURCE			ActiveWriter.cpp
+SOURCE			BreakController.cpp
+SOURCE			CdcAcmClass.cpp 
+SOURCE			CdcInterfaceBase.cpp		
+SOURCE			CdcControlInterface.cpp 	
+SOURCE			CdcControlInterfaceReader.cpp 
+SOURCE			CdcDataInterface.cpp		
+SOURCE			ClassDescriptor.cpp 
+SOURCE			DllMain.cpp 
+SOURCE			RegistrationPort.cpp 
+SOURCE			RequestHeader.cpp 
+SOURCE			acmserver.cpp
+SOURCE			acmsession.cpp
+SOURCE			ActiveDataAvailableNotifier.cpp
+
+SOURCEPATH		../../../../../../inifile/src
+SOURCE			inifile.cpp
+
+USERINCLUDE 	../inc
+USERINCLUDE 	../public
+USERINCLUDE		../../../../../../inifile/inc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY 		euser.lib 
+LIBRARY 		c32.lib
+LIBRARY			efsrv.lib
+
+#include <usb/usblogger.mmh>
+
+VENDORID 0x70000001
+
+UNPAGED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/group/ecacm.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,21 @@
+; 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 "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:
+; Ini file for ECACM plug-in ( EPOC Comms Abstract Control Model Comms System Module ).
+; 
+;
+
+
+[HostUSBDeviceDriver]
+CanHandleZLP= 0;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmConstants.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __ACMCONSTANTS_H__
+#define __ACMCONSTANTS_H__
+
+#include <e32def.h>
+
+const TUint KEcacmAOPriority = 10;
+
+#endif // __ACMCONSTANTS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmPanic.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __ACMPANIC_H__
+#define __ACMPANIC_H__
+
+/**
+ * Panic codes. These all represent programming errors.
+ */
+enum TAcmPanic
+	{
+	///< Mainly NULL pointers.
+	EPanicInternalError 	= 0, 
+
+	///< Illegal state in a state machine.
+	EPanicIllegalState		= 1, 
+	
+	///< Unknown device state event
+	EPanicUnknownDeviceState= 2, 
+	};
+
+_LIT(KAcmPanicCat, "ECACM");
+
+#endif // __ACMPANIC_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmPort.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,159 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __ACMPORT_H__
+#define __ACMPORT_H__
+
+#include <cs_port.h>
+#include "CdcAcmClass.h"
+#include "HostPushedChangeObserver.h"
+#include "BreakObserver.h"
+
+class CAcmPortFactory;
+class CAcmReader;
+class CAcmWriter;
+class MAcmPortObserver;
+
+NONSHARABLE_CLASS(CAcmPort) :	public CPort, 
+					public MHostPushedChangeObserver,
+					public MBreakObserver
+/**
+ * Concrete ACM port type, derived from C32's CPort.
+ */
+	{
+public:
+	static CAcmPort* NewL(const TUint aUnit, MAcmPortObserver& aFactory);
+	~CAcmPort();
+
+public:
+	void SetAcm(CCdcAcmClass* aAcm);
+	inline CCdcAcmClass* Acm();
+
+private:
+	CAcmPort(const TUint aUnit, MAcmPortObserver& aFactory);
+	void ConstructL();
+
+private: // from CPort
+	virtual void StartRead(const TAny* aClientBuffer,TInt aLength);
+	virtual void ReadCancel();
+	virtual TInt QueryReceiveBuffer(TInt& aLength) const;
+	virtual void ResetBuffers(TUint aFlags);
+	virtual void StartWrite(const TAny* aClientBuffer,TInt aLength);
+	virtual void WriteCancel();
+	virtual void Break(TInt aTime);
+	virtual void BreakCancel();
+	virtual TInt GetConfig(TDes8& aDes) const;
+	virtual TInt SetConfig(const TDesC8& aDes);
+	virtual TInt SetServerConfig(const TDesC8& aDes);
+	virtual TInt GetServerConfig(TDes8& aDes);
+	virtual TInt GetCaps(TDes8& aDes);
+	virtual TInt GetSignals(TUint& aSignals);
+	virtual TInt SetSignalsToMark(TUint aSignals);
+	virtual TInt SetSignalsToSpace(TUint aSignals);
+	virtual TInt GetReceiveBufferLength(TInt& aLength) const;
+	virtual TInt SetReceiveBufferLength(TInt aSignals);
+	virtual void Destruct();
+	virtual void FreeMemory();
+	virtual void NotifySignalChange(TUint aSignalMask);
+	virtual void NotifySignalChangeCancel();
+	virtual void NotifyConfigChange();
+	virtual void NotifyConfigChangeCancel();
+	virtual void NotifyFlowControlChange();
+	virtual void NotifyFlowControlChangeCancel();
+	virtual void NotifyBreak();
+	virtual void NotifyBreakCancel();
+	virtual void NotifyDataAvailable();
+	virtual void NotifyDataAvailableCancel();
+	virtual void NotifyOutputEmpty();
+	virtual void NotifyOutputEmptyCancel();
+	virtual TInt GetFlowControlStatus(TFlowControl& aFlowControl);
+	virtual TInt GetRole(TCommRole& aRole);
+	virtual TInt SetRole(TCommRole aRole);
+
+private: // from MBreakObserver
+	void BreakRequestCompleted();
+	void BreakStateChange();
+
+private: // from MHostPushedChangeObserver
+	virtual void HostConfigChange(const TCommConfigV01& aConfig);
+	virtual void HostSignalChange(TBool aDtr, TBool aRts);
+
+private: // utility
+	TInt SetSignals(TUint32 aNewSignals);
+	void HandleConfigNotification(TBps aBps,
+		TDataBits aDataBits,
+		TParity aParity,
+		TStopBits aStopBits,
+		TUint aHandshake);
+	// iSignals stores the lines in DCE mode- these functions convert between 
+	// this and whatever the client expects, according to our current mode.
+	TUint32 ConvertSignals(TUint32 aSignals) const;
+	TUint32 ConvertAndFilterSignals(TUint32 aSignals) const;
+	TInt DoSetBufferLengths(TUint aLength);
+
+public: // owned data
+	TCommConfigV01 iCommConfig;
+	TCommNotificationPckg iCommNotificationDes;
+	TCommNotificationV01& iCommNotification;
+
+private: // unowned
+	CCdcAcmClass* iAcm;
+	MAcmPortObserver& iObserver;
+
+private: // owned
+	CAcmReader* iReader;
+	CAcmWriter* iWriter;					
+
+	// Current server configuration settings
+	TCommServerConfigV01 iCommServerConfig;
+	// Flag indicating whether there is a current signal line change 
+	// notification request outstanding
+	TBool iNotifySignalChange;
+	// Flag indicating whether there is a current configuration change 
+	// notification request outstanding
+	TBool iNotifyConfigChange;
+	// Flag indicating whether there is a current break notification 
+	// request outstanding
+	TBool iNotifyBreak;
+	// The current emulated signal lines
+	TUint32 iSignals;						
+	// The signal mask associated with the current signal change notification 
+	// request
+	TUint iNotifySignalMask;				
+	// Role of the serial port (DTE or DCE)
+	TCommRole iRole;			
+	TBool iCancellingBreak;
+	// Flag indicating whether we're currently requesting a break.
+	TBool iBreak;
+
+	// The port number.
+	const TUint iUnit;
+	};
+
+// Inlines
+
+CCdcAcmClass* CAcmPort::Acm()
+/**
+ * Accessor function for the ACM class.
+ *
+ * @return Pointer to the port's ACM class instance.
+ */
+	{
+	return iAcm;
+	}
+
+#endif // __ACMPORT_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmPortFactory.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __ACMPORTFACTORY_H__
+#define __ACMPORTFACTORY_H__
+
+#include <cs_port.h>
+#include "AcmPortObserver.h"
+#include "RegistrationPort.h"
+#include "acmcontroller.h"
+#include <e32property.h>
+#include <usb/acmconfig.h>
+
+class CCdcAcmClass;
+class CAcmPort;
+class CAcmServer;
+
+NONSHARABLE_CLASS(CAcmPortFactory) : public CSerial, 
+						public MAcmController,
+						public MAcmPortObserver
+/**
+ * Definition of concrete CSerial-derived type.
+ */
+	{
+public:
+	static CAcmPortFactory* NewL();
+	~CAcmPortFactory();
+	
+private:
+	CAcmPortFactory();
+	void ConstructL();
+
+private: // from CSerial
+	TSecurityPolicy PortPlatSecCapability(TUint aPort) const;
+	virtual CPort* NewPortL(const TUint aUnit);
+	virtual void Info(TSerialInfo &aSerialInfo);
+
+private: // from MAcmController
+	TInt CreateFunctions(const TUint aNoAcms, const TUint8 aProtocolNum, const TDesC16& aAcmControlIfcName, const TDesC16& aAcmDataIfcName);
+	void DestroyFunctions(const TUint aNoAcms);
+
+private: // from MAcmPortObserver
+	void AcmPortClosed(const TUint aUnit);
+
+private: // utility
+	void CreateFunctionL(const TUint8 aProtocolNum, const TDesC16& aAcmControlIfcName, const TDesC16& aAcmDataIfcName);
+	void CheckAcmArray();
+	void LogPortsAndFunctions();
+	void PublishAcmConfig();
+
+private: // unowned
+	RPointerArray<CAcmPort> iAcmPortArray;
+	
+private: // owned
+	RPointerArray<CCdcAcmClass>  iAcmClassArray;
+	CAcmServer* iAcmServer;
+	RProperty iAcmProperty;
+	TPckgBuf<TPublishedAcmConfigs> iConfigBuf;
+	TBool iOwned;
+	};
+
+#endif // __ACMPORTFACTORY_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmPortObserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __ACMPORTOBSERVER_H__
+#define __ACMPORTOBSERVER_H__
+
+class MAcmPortObserver
+/**
+ * Interface for notification of the ACM port being closed.
+ */
+	{
+public:
+	virtual void AcmPortClosed(const TUint aUnit) = 0;
+	};
+
+#endif // __ACMPORTOBSERVER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmReader.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,203 @@
+/*
+* Copyright (c) 2003-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:
+*
+*/
+
+#ifndef __ACMREADER_H__
+#define __ACMREADER_H__
+
+#include <e32std.h>
+#include <d32comm.h>
+#include "ReadObserver.h"
+#include "ReadOneOrMoreObserver.h"
+#include "NotifyDataAvailableObserver.h"
+
+class CCdcAcmClass;
+class CAcmPort;
+
+NONSHARABLE_CLASS(CAcmReader) : public CBase,
+					public MReadObserver,
+					public MReadOneOrMoreObserver,
+					public MNotifyDataAvailableObserver
+/**
+ * CAcmReader maintains the port's read buffer, fields requests from the port 
+ * (its client) for data, and administers getting more data from the LDD. 
+ * 
+ * It presents an interface for requesting data- whether the required data is 
+ * immediately available in the buffer or not, it eventually completes the 
+ * client (port)'s request using CPort::IPCWrite and CPort::ReadCompleted.
+ *
+ * It uses the CCdcAcmClass to ask for more data from the host. Consequently 
+ * it implements MReadObserver and MReadOneOrMoreObserver to be notified when 
+ * data has come in.
+ */
+	{
+public:
+	static CAcmReader* NewL(CAcmPort& aPort, 
+		TUint aBufSize);
+	~CAcmReader();
+
+public: // APIs for reading
+	void Read(const TAny* aClientBuffer, TUint aMaxLen);
+	void ReadOneOrMore(const TAny* aClientBuffer, TUint aMaxLen);
+	void ReadCancel();
+	void NotifyDataAvailable();
+	void NotifyDataAvailableCancel();
+	inline TBool IsNotifyDataAvailableQueryPending() const; 
+
+public: // buffer APIs
+	TUint BufLen() const;
+	inline TUint BufSize() const;
+	void ResetBuffer();
+	TInt SetBufSize(TUint aSize);
+	void SetTerminators(const TCommConfigV01& aConfig);
+
+private: 
+	CAcmReader(CAcmPort& aPort,
+		TUint aBufSize);
+	void ConstructL();
+
+private: // from MReadObserver
+	void ReadCompleted(TInt aError);
+
+private: // from MReadOneOrMoreObserver
+	void ReadOneOrMoreCompleted(TInt aError);
+
+private: // from MNotifyDataAvailableObserver
+	void NotifyDataAvailableCompleted(TInt aError);
+
+private: // utilities
+	inline TBool BufWrap() const;
+	void CheckBufferEmptyAndResetPtrs();
+	void CheckNewRequest(const TAny* aClientBuffer, TUint aMaxLen);
+	void CheckForBufferedTerminatorsAndProceed();
+
+	void WriteBackData(TUint aLength);
+	void CompleteRequest(TInt aError);
+		
+	void ReadWithoutTerminators();
+	void ReadWithTerminators();
+	
+	void IssueRead();
+	void IssueReadOneOrMore();
+
+	TInt FindTerminator() const;
+	TInt PartialFindTerminator(TUint8* aFrom, TUint8* aTo, TInt& aPos) const;
+	
+private: // owned- information on the current request from the port (if any)
+
+	enum TRequestType
+			{
+			ERead,
+			EReadOneOrMore,
+			ENotifyDataAvailable
+			};
+
+	NONSHARABLE_STRUCT(TRequestData)
+		{
+		// Pointer to the client's memory to put the data into. This is also 
+		// used as a flag for whether we have an outstanding request or not.
+		const TAny* iClientPtr; 
+		// type of the current request
+		TRequestType iRequestType;
+		};
+	// This struct is populated when a new client request comes in.
+	TRequestData iCurrentRequest;
+
+private: // owned- information on our attempt to satisfy the current request 
+	// from the port (if any)
+
+	// Starts as the amount of data requested by the client.
+	// This may not be the same as the 
+	// amount of data given back to the client when the request is 
+	// completed, for instance if the read is a one-or-more, or if 
+	// terminators are defined.
+	// Will be the number of bytes remaining to be read before we can 
+	// complete the client's request.
+	TUint iLengthToGo; 
+
+	// Offset into iClientPtr to write more data to using IPCWrite.
+	TUint iOffsetIntoClientsMemory;
+
+private: // owned- information on the buffer
+	
+	// The current actual size of the buffer.
+	TUint iBufSize;
+
+	// Our buffer of data.
+	HBufC8* iBuffer;
+
+	// These TUints are pointers to various places in iBuffer. 
+
+	// Pointer to where data will be placed into our buffer (from the LDD).
+	TUint8* iInPtr; 
+	// Pointer to where data will leave our buffer (to go up to the client).
+	TUint8* iOutPtr; 
+	// Pointer to the start of the buffer.
+	TUint8* iBufStart;
+	
+	// Descriptor pointer into iBuffer. We use this in Read and ReadOneOrMore 
+	// calls to the LDD to get data written into iBuffer.
+	TPtr8 iInBuf;
+
+private: // owned- information on the terminator characters
+	TUint iTerminatorCount;
+	TFixedArray<TText8, KConfigMaxTerminators> iTerminator;
+
+private: // unowned
+	// Used to access the (RComm) client's memory and to complete their 
+	// request. Also accesses the ACM class through the port. (The ACM class 
+	// may come and go, following the lifetime of the registration port, not 
+	// the ACM port.)
+	CAcmPort& iPort; 
+	};
+
+TBool CAcmReader::BufWrap() const
+/**
+ * This function indicates whether the circular buffer has wrapped.
+ *
+ * @return TBool Indication of whether the buffer has wrapped.
+ */
+	{
+	TBool ret = EFalse;
+	if ( iOutPtr > iInPtr )
+		{
+		ret =  ETrue;
+		}
+
+	return ret;
+	}
+
+TUint CAcmReader::BufSize() const
+/**
+ * Accessor for current buffer size.
+ *
+ * @return The current buffer size.
+ */
+	{
+	return iBufSize;
+	}
+
+TBool CAcmReader::IsNotifyDataAvailableQueryPending() const
+/**
+ * check if a NotifyDataAvailable query is in progress
+ *
+ * @return ETrue if a NotifyDataAvailable query is pending, EFalse if not.
+ */
+	{ 
+	return ((iCurrentRequest.iClientPtr)&&(ENotifyDataAvailable==iCurrentRequest.iRequestType));
+	}
+
+#endif // __ACMREADER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmUtils.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __ACMUTILS_H__
+#define __ACMUTILS_H__
+
+#include <e32std.h>
+
+// Macros to save a bit of ROM space in release builds- the checking form of 
+// Pop only really needs to be run once anyway.
+#ifdef _DEBUG
+#define CLEANUPSTACK_POP(aaa)	CleanupStack::Pop(aaa)
+#else
+#define CLEANUPSTACK_POP(aaa)	CleanupStack::Pop()
+#endif
+
+#endif // __ACMUTILS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/AcmWriter.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,104 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __ACMWRITER_H__
+#define __ACMWRITER_H__
+
+#include <e32base.h>
+#include "WriteObserver.h"
+
+class CAcmPort;
+
+NONSHARABLE_CLASS(CAcmWriter) : public CBase, 
+					public MWriteObserver
+/**
+ * CAcmWriter presents an interface for writing data to the bulk endpoint on 
+ * the LDD.
+ * Note that we reject write requests bigger than the buffer. We also don't 
+ * support KConfigWriteBufferedComplete, so client requests are turned into 
+ * one write request on the LDD. When the LDD request completes, we complete 
+ * to the client. 
+ */
+	{
+public:
+	static CAcmWriter* NewL(CAcmPort& aPort, TUint aBufSize);
+	~CAcmWriter();
+
+public: // APIs for writing
+	void Write(const TAny* aClientBuffer, TUint aLength);
+	void WriteCancel();
+
+public: // buffer APIs
+	void ResetBuffer();
+	TInt SetBufSize(TUint aSize);
+
+private:
+	CAcmWriter(CAcmPort& aPort, TUint aBufSize);
+	void ConstructL();
+
+private: // from MWriteObserver
+	void WriteCompleted(TInt aError);
+
+private: // utility
+	void ReadDataFromClient();
+	void CheckNewRequest(const TAny* aClientBuffer, TUint aLength);
+	void CompleteRequest(TInt aError);
+	void IssueWrite();
+
+private: // owned- information on the current request from the port (if any)
+
+	NONSHARABLE_STRUCT(TRequestData)
+		{
+		// Pointer to the client's memory to get the data to write.
+		const TAny* iClientPtr;
+
+		// Number of bytes to write.
+		TUint iLength;
+		};
+	// This struct is populated when a new client request comes in.
+	TRequestData iCurrentRequest;
+
+private: // owned- information on our attempt to satisfy the current request 
+	// from the port (if any)
+
+	// Offset into iClientPtr to get more data from using IPCRead.
+	TUint iOffsetIntoClientsMemory;
+
+	// Number of bytes remaining to be written before we can complete the 
+	// client's request.
+	TUint iLengthToGo;
+
+private: // owned- information on the buffer
+
+	// The current actual size of the buffer.
+	TUint iBufSize; 
+
+	// Our buffer of data. This is for temporarily storing RComm client data 
+	// while we are writing it to the LDD.
+	HBufC8* iBuffer;	
+	
+	// Descriptor pointer into iBuffer. We use this in Write calls to the LDD.
+	TPtr8 iBuf;
+
+private: // unowned
+	// Used to access the (RComm) client's memory and to complete their 
+	// request. Also accesses the ACM class through the port. (The ACM class 
+	// may come and go, but not the ACM port.)
+	CAcmPort& iPort; 
+	};
+
+#endif // __ACMWRITER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ActiveDataAvailableNotifier.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef __ACTIVEDATAAVAILABLENOTIFIER_H__
+#define __ACTIVEDATAAVAILABLENOTIFIER_H__
+
+#include <e32base.h>
+#include <d32usbc.h>
+
+class RDevUsbcClient;
+class MNotifyDataAvailableObserver;
+
+NONSHARABLE_CLASS(CActiveDataAvailableNotifier) : public CActive
+/**
+ * Active object used to notify the parent when there is data available 
+ * to be read from the LDD.  Since the LDD does not support this functionality 
+ * directly RDevUsbcClient::ReadOneOrMore() is used instead, specifying a 
+ * zero byte read into a descriptor which is owned by the class.
+ */
+	{
+public: 									   
+	static CActiveDataAvailableNotifier* NewL(MNotifyDataAvailableObserver& aParent, 
+		RDevUsbcClient& aLdd, TEndpointNumber aEndpoint);
+	~CActiveDataAvailableNotifier();
+
+public:
+	void NotifyDataAvailable();
+
+private:
+	CActiveDataAvailableNotifier(MNotifyDataAvailableObserver& aParent, 
+		RDevUsbcClient& aLdd, TEndpointNumber aEndpoint);
+
+private: // from CActive
+	virtual void DoCancel();
+	virtual void RunL();
+
+private: // unowned
+	MNotifyDataAvailableObserver& iParent;
+	RDevUsbcClient& iLdd;
+
+private: // owned
+	TEndpointNumber iEndpoint;
+	TBuf8<1> iUnusedBuf;	// passed to the LDD in order to carry out the zero byte read (length must be > 0)
+	};
+
+#endif // __ACTIVEDATAAVAILABLENOTIFIER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ActiveReadOneOrMoreReader.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,56 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __ACTIVEREADONEORMOREREADER_H__
+#define __ACTIVEREADONEORMOREREADER_H__
+
+#include <e32base.h>
+#include <d32usbc.h>
+
+class RDevUsbcClient;
+class MReadOneOrMoreObserver;
+
+NONSHARABLE_CLASS(CActiveReadOneOrMoreReader) : public CActive
+/**
+ * Active object to post ReadOneOrMore requests on the LDD.
+ */
+	{
+public: 									   
+	static CActiveReadOneOrMoreReader* NewL(MReadOneOrMoreObserver& aParent, 
+		RDevUsbcClient& aLdd, TEndpointNumber aEndpoint);
+	~CActiveReadOneOrMoreReader();
+
+public:
+	void ReadOneOrMore(TDes8& aDes, TInt aLength);
+
+private:
+	CActiveReadOneOrMoreReader(MReadOneOrMoreObserver& aParent, 
+		RDevUsbcClient& aLdd, TEndpointNumber aEndpoint);
+
+private: // from CActive
+	virtual void DoCancel();
+	virtual void RunL();
+
+private: // unowned
+	MReadOneOrMoreObserver& iParent;
+	RDevUsbcClient& iLdd;
+
+private: // owned
+	TEndpointNumber iEndpoint;
+	};
+
+#endif // __ACTIVEREADONEORMOREREADER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ActiveReader.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,54 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __ACTIVEREADER_H__
+#define __ACTIVEREADER_H__
+
+#include <e32base.h>
+#include <d32usbc.h>
+
+class RDevUsbcClient;
+class MReadObserver;
+
+NONSHARABLE_CLASS(CActiveReader) : public CActive
+/**
+ * Active object to post read requests on the LDD.
+ */
+	{
+public: 									  
+	static CActiveReader* NewL(MReadObserver& aParent, RDevUsbcClient& aLdd, TEndpointNumber aEndpoint);
+	~CActiveReader();
+
+public:
+	void Read(TDes8& aDes, TInt aLen);
+
+private:
+	CActiveReader(MReadObserver& aParent, RDevUsbcClient& aLdd, TEndpointNumber aEndpoint);
+
+private: // from CActive
+	virtual void DoCancel();
+	virtual void RunL();
+
+private: // unowned
+	MReadObserver& iParent;
+	RDevUsbcClient& iLdd;
+
+private: // owned
+	TEndpointNumber iEndpoint;
+	};
+
+#endif // __ACTIVEREADER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ActiveWriter.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __ACTIVEWRITER_H__
+#define __ACTIVEWRITER_H__
+
+#include <e32base.h>
+#include <d32usbc.h>
+
+class RDevUsbcClient;
+class MWriteObserver;
+
+NONSHARABLE_CLASS(CActiveWriter) : public CActive
+/**
+ * Active object to post write requests on the LDD.
+ */
+	{
+public: 									   
+	static CActiveWriter* NewL(MWriteObserver& aParent, RDevUsbcClient& aLdd, TEndpointNumber aEndpoint);
+	~CActiveWriter();
+
+public:
+	void Write(const TDesC8& aDes, 
+		TInt aLen, 
+		TBool aZlp);
+
+private:
+	CActiveWriter(MWriteObserver& aParent, RDevUsbcClient& aLdd, TEndpointNumber aEndpoint);
+
+private: // from CActive
+	virtual void DoCancel();
+	virtual void RunL();
+
+private: // unowned
+	MWriteObserver& iParent;
+	RDevUsbcClient& iLdd;
+
+private: // owned
+	TEndpointNumber iEndpoint;
+
+	enum TWritingState
+		{
+		EFirstMessagePart,
+		EFinalMessagePart,
+		ECompleteMessage,		
+		};
+		
+	enum
+		{
+		KMaxPacketSize = 64, 
+		};
+		
+	TWritingState iWritingState;
+	TPtrC8 iFirstPortion;
+	TPtrC8 iSecondPortion;
+	};
+
+#endif // __ACTIVEWRITER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/BreakController.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,101 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __BREAKCONTROLLER_H__
+#define __BREAKCONTROLLER_H__
+
+#include <e32base.h>
+ 
+class CCdcAcmClass;
+class MHostPushedChangeObserver;
+
+NONSHARABLE_CLASS(CBreakController) : public CActive
+/**
+ * Break (timed signal) handler
+ *
+ * This class provides a simple active object that manages the timing aspect 
+ * of a break: there is only one of these, that is used to manage both 
+ * client-induced breaks (routed in via the ACM port) and break commands sent 
+ * here from the (USB) Host.
+ *
+ * Note that only one of the device and the host can be 'in charge of' a 
+ * break. If the host, say, is dealing with a timed break, then it is illegal 
+ * for the device to issue a timed break, though the host may override the 
+ * timed break with a new timed break or a locked break. 
+ */
+	{
+public:
+	enum TRequester
+		{
+		ENone,
+		EDevice,
+		EHost,
+		};
+
+	enum TState
+		{
+		EInactive,
+		ETiming,
+		ELocked,
+		ENumStates
+		};
+
+public:
+	static CBreakController* NewL(CCdcAcmClass& aParentAcm);
+	~CBreakController();
+
+public: // API for requesting breaks
+	TInt BreakRequest(TRequester aRequester, 
+		TState aState, 
+		TTimeIntervalMicroSeconds32 aDelay = 0);
+
+private:
+	CBreakController(CCdcAcmClass& aParentAcm);
+	void ConstructL();
+
+private:
+	void StateMachine(TState aBreakState, TTimeIntervalMicroSeconds32 aDelay);
+
+	void Publish(TState aNewState);
+
+	static TBool ScInvalid(CBreakController *aThis, 
+		TTimeIntervalMicroSeconds32 aDelay);
+	static TBool ScInactive(CBreakController *aThis, 
+		TTimeIntervalMicroSeconds32 aDelay);
+	static TBool ScSetTimer(CBreakController *aThis, 
+		TTimeIntervalMicroSeconds32 aDelay);
+	static TBool ScLocked(CBreakController *aThis, 
+		TTimeIntervalMicroSeconds32 aDelay);
+
+private: // from CActive
+	void RunL();
+	void DoCancel();
+
+private: // owned
+	typedef TBool ( *PBFNT ) (CBreakController *aThis, 
+		TTimeIntervalMicroSeconds32 aDelay);
+	PBFNT StateDispatcher[ENumStates][ENumStates];
+	RTimer iTimer;
+	TState iBreakState;
+	// Whoever's in charge of the current break.
+	TRequester iRequester;
+
+private: // unowned
+	CCdcAcmClass&	  iParentAcm;	///< use to tell (USB) Host about changes
+	};
+
+#endif // __BREAKCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/BreakObserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,40 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __BREAKOBSERVER_H__
+#define __BREAKOBSERVER_H__
+
+#include <e32std.h>
+ 
+class MBreakObserver
+/**
+ * Interface for notifications of break changes.
+ */
+	{
+public:
+	/**
+	 * Called when an MBreakObserver-requested break has completed. 
+	 */
+	virtual void BreakRequestCompleted() = 0;
+	/**
+	 * Called when the break state has changed (i.e. it has been off and gone 
+	 * either timed or locked, or if it was on and has gone off).
+	 */
+	virtual void BreakStateChange() = 0;
+	};
+
+#endif // __BREAKOBSERVER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/CdcAcmClass.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,184 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __CDCACMCLASS_H__
+#define __CDCACMCLASS_H__
+
+#include <d32comm.h>
+#include "CdcControlInterfaceRequestHandler.h"
+#include "BreakController.h"
+ 
+class MHostPushedChangeObserver;
+class MBreakObserver;
+class MReadObserver;
+class MReadOneOrMoreObserver;
+class MNotifyDataAvailableObserver;
+class MWriteObserver;
+class CCdcControlInterface;
+class CCdcDataInterface;
+
+NONSHARABLE_CLASS(CCdcAcmClass) :	public CBase, 
+						public MCdcCommsClassRequestHandler
+/**
+ * The Communication Device Class Abstract Control Model class.
+ * This class owns and controls the classes that handle the ACM data and 
+ * control interfaces.
+ * Instantiation of this class instantiates an ACM function.
+ */
+	{
+public:
+	enum TUsbParity ///< Serial port emulated parity setting. Taken directly 
+		// from the spec.
+		{
+		EUsbParityNone	= 0,
+		EUsbParityOdd	= 1,
+		EUsbParityEven	= 2,
+		EUsbParityMark	= 3,
+		EUsbParitySpace = 4
+		};
+
+	enum TUsbStopBits ///< Serial port emulated stop bit setting. Taken 
+		// directly from the spec.
+		{
+		EUsbStopBitOne		 = 0,
+		EUsbStopBitOnePtFive = 1,
+		EUsbStopBitTwo		 = 2
+		};
+
+	enum TUsbDataBits ///< Serial port emulated data bit setting. Taken 
+		// directly from the spec.
+		{
+		EUsbDataBitsFive	= 5,
+		EUsbDataBitsSix 	= 6,
+		EUsbDataBitsSeven	= 7,
+		EUsbDataBitsEight	= 8,
+		EUsbDataBitsSixteen = 16
+		};
+
+	enum TUsbCommFeatureSelector
+		{
+		EUsbCommFeatureSelectAbstractState = 0x01,
+		EUsbCommFeatureSelectCountryCode   = 0x02
+		};
+
+	enum TUsbAbstractStateBits
+		{
+		EUsbAbstractStateNoBits 	   = 0x0000,
+		EUsbAbstractStateIdleSetting   = 0x0001,
+		EUsbAbstractStateDataMultiplex = 0x0002
+		};
+
+	NONSHARABLE_CLASS(TUsbConfig)	///< Serial port emulated configuration
+		{
+	public:
+		TUint		 iChangedMembers;
+		TUint32 	 iRate; 			///< The line rate
+		TUsbDataBits iDataBits; 		///< The number of data bits
+		TUsbStopBits iStopBits; 		///< The number of stop bits
+		TUsbParity	 iParity;			///< The parity
+		};
+
+public:
+	static CCdcAcmClass* NewL(const TUint8 aProtocolNum, const TDesC16& aAcmControlIfcName, const TDesC16& aAcmDataIfcName);
+	~CCdcAcmClass();
+
+public:
+	void SetCallback(MHostPushedChangeObserver* aCallback);
+	void SetBreakCallback(MBreakObserver* aBreakCallback);
+	void Read(MReadObserver& aObserver, TDes8 &aDes);
+	void Read(MReadObserver& aObserver, TDes8 &aDes,TInt aLength);
+	void ReadOneOrMore(MReadOneOrMoreObserver& aObserver, TDes8 &aDes);
+	void ReadOneOrMore(MReadOneOrMoreObserver& aObserver, TDes8 &aDes, TInt aLength);
+	void ReadCancel();
+	void NotifyDataAvailable(MNotifyDataAvailableObserver& aObserver);
+	void NotifyDataAvailableCancel();
+
+	void Write(MWriteObserver& aObserver, const TDesC8& aDes);
+	void Write(MWriteObserver& aObserver, const TDesC8& aDes, TInt aLength);
+	void WriteCancel();
+
+	TInt SendSerialState(TBool aRing, TBool aDsr, TBool aDcd);
+
+public: // API for requesting a timed or locked break, and for turning the 
+	// break off.
+	TInt BreakRequest(CBreakController::TRequester aRequester, 
+		CBreakController::TState aState,
+		TTimeIntervalMicroSeconds32 aDelay = 0);
+
+public: // used by the break controller
+	TBool RingState() const;
+	TBool DsrState() const;
+	TBool DcdState() const;
+
+	// Accessor for break state
+	TBool BreakActive() const;
+	void SetBreakActive(TBool aBreakActive);
+	
+	MHostPushedChangeObserver* Callback();
+	MBreakObserver* BreakCallback();
+
+private:
+	CCdcAcmClass();
+	void ConstructL(const TUint8 aProtocolNum);
+	void ConstructL(const TUint8 aProtocolNum, const TDesC16& aControlIfcName, const TDesC16& aDataIfcName);
+
+private: // from MCdcCommsClassRequestHandler
+	virtual TInt HandleSendEncapCommand(const TDesC8& aData);
+	virtual TInt HandleGetEncapResponse(TDes8& aReturnData);
+	virtual TInt HandleSetCommFeature(const TUint16 aSelector, 
+		const TDes8& aData);
+	virtual TInt HandleGetCommFeature(const TUint16 aSelector, 
+		TDes8& aReturnData);
+	virtual TInt HandleClearCommFeature(const TUint16 aSelector);
+	virtual TInt HandleSetLineCoding(const TDesC8& aData);
+	virtual TInt HandleGetLineCoding(TDes8& aReturnData);
+	virtual TInt HandleSetControlLineState(TBool aRtsState,TBool aDtrState);
+	virtual TInt HandleSendBreak(TUint16 aDuration);
+
+private: // utility
+	void SetDefaultAcm(void);
+	static void ConvertUsbConfigCodingToEpoc(const TUsbConfig& aUsbConfig, 
+		TCommConfigV01& aEpocConfig);
+	TInt HandleNewAbstractState(const TUint16 aAbstractState);
+	TInt HandleNewCountryCode(const TUint16 aCountryCode);
+
+private: // unowned
+	MHostPushedChangeObserver* iCallback;
+	MBreakObserver* iBreakCallback;
+
+private: // owned
+	CBreakController* iBreakController; ///< The BREAK state machine
+	CCdcControlInterface* iControl; ///< The control interface
+	CCdcDataInterface* iData; ///< The data interface
+
+	TUint16 		iAcmState; ///< The multiplexed and idle state
+	TUint16 		iCountryCode; ///< The country code from ISO 3166
+	TUsbConfig		iUsbConfig; ///< The USB Configuration
+	TBool			iRtsState; ///< The emulated RTS state
+	TBool			iDtrState; ///< The eumlated DTR state
+
+	TBool			iAcmDataMultiplex; ///< derived from bit D1 of iACMState
+	TBool			iAcmIdleSetting; ///< derived from bit D0 of iACMState
+
+	TBool			iRingState; 	///< Saved RING state
+	TBool			iDsrState;		///< Saved DSR state
+	TBool			iDcdState;		///< Saved DCD state
+
+	TBool			iBreakActive;		///< Locally controlled BREAK state
+	};
+
+#endif // __CDCACMCLASS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/CdcControlInterface.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,87 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __CDCCONTROLINTERFACE_H__
+#define __CDCCONTROLINTERFACE_H__
+
+#include "CdcInterfaceBase.h"
+
+class CCdcAcmClass;
+class CCdcControlInterfaceReader;
+
+NONSHARABLE_CLASS(CCdcControlInterface) : public CCdcInterfaceBase
+/**
+ * ACM control interface subclass.
+ */
+	{
+public:
+	static CCdcControlInterface* NewL(CCdcAcmClass& aParent, const TUint8 aProtocolNum, const TDesC16& aIfcName);
+	~CCdcControlInterface();
+
+public:
+	TInt SetupClassSpecificDescriptor(TUint8 aDataInterfaceNumber);
+	TInt SendNetworkConnection(TBool aValue);
+	TInt SendSerialState(TBool aOverRun, 
+		TBool aParity, 
+		TBool aFraming, 
+		TBool aRing, 
+		TBool aBreak,
+		TBool aTxCarrier,
+		TBool aRxCarrier);
+
+public:
+	static inline TReal32 GetF32( TUint8** aPPbuf );
+	static inline void	  PutF32( TUint8** aPPbuf, TReal32 aF32 );
+
+	static inline TUint32 GetU32( TUint8** aPPbuf );
+	static inline void	  PutU32( TUint8** aPPbuf, TUint32 aU32 );
+
+	static inline TUint16 GetU16( TUint8** aPPbuf );
+	static inline void	  PutU16( TUint8** aPPbuf,TUint16 aU16 );
+
+	static inline TUint8 GetU08( TUint8** aPPbuf );
+	static inline void	 PutU08( TUint8** aPPbuf, TUint8 aU8 );
+
+private:
+	CCdcControlInterface(const TUint8 aProtocolNum, const TDesC16& aIfcName);
+	void ConstructL(CCdcAcmClass& aParent);
+
+private: // from CCdcClassBase
+	TInt SetUpInterface();
+
+private: // utility
+	TInt WriteData(TEndpointNumber aEndPoint, TDes8& aDes, TInt aLength);
+
+private: // owned
+	CCdcControlInterfaceReader* iReader;	///< Handle on the read object
+
+	TUint16 iSerialState;				///< local copy of the flagset
+	const TUint8 iProtocolNum;
+
+	enum
+		{
+		///< Max packet size sent on Interrupt endpoint
+		KMaxPacketTypeInterrupt = 64,	
+		///< Interrupt endpoint poll time in ms
+		KPollInterval  = 128, 
+		KWriteDataTimeout = 500000,
+		};
+	};
+
+#include "LittleEndianPacker.INL"
+
+#endif // __CDCCONTROLINTERFACE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/CdcControlInterfaceReader.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __CDCCONTROLINTERFACEREADER_H__
+#define __CDCCONTROLINTERFACEREADER_H__
+
+#include <e32base.h>
+#include "RequestHeader.h"
+#include "acmcapability.h"
+
+class MCdcCommsClassRequestHandler;
+class RDevUsbcClient;
+
+NONSHARABLE_CLASS(CCdcControlInterfaceReader) : public CActive
+/**
+ * Deals with reading control information from the LDD.
+ */
+	{
+public:
+	static CCdcControlInterfaceReader* NewL(
+		MCdcCommsClassRequestHandler& aParent, 
+		RDevUsbcClient& aLdd);
+	~CCdcControlInterfaceReader();
+
+private:
+	CCdcControlInterfaceReader(MCdcCommsClassRequestHandler& aParent, 
+		RDevUsbcClient& aLdd);
+
+private: // utility
+	void HandleReadCompletion(TInt aError);
+	
+	void DecodeMessageHeader();
+	void DecodeMessageDataWithResponseRequired();
+	void DecodeMessageData();
+
+	void ReadMessageHeader();
+	void ReadMessageData(TUint aLength);
+
+private: // from CActive
+	void RunL();
+	void DoCancel();
+
+private: // unowned
+	MCdcCommsClassRequestHandler& iParent;
+	RDevUsbcClient& iLdd;			
+
+private: // owned
+	TBuf8<KUsbRequestHdrSize> iMessageHeader; ///< Raw message header
+
+	enum
+		{
+		KAcmControlReadBufferLength = 256, ///< Size of the ACM control read 
+		///< buffer
+
+		// Request IDs- see p16 of UBSCDC1.1 Table 4.
+		KGetEncapsulated = 0x01, ///< GET_ENCAPSULATED_RESPONSE
+		KGetCommFeature  = 0x03, ///< GET_COMM_FEATURE
+		KGetLineCoding	 = 0x21, ///< GET_LINE_CODING
+
+		KSendEncapsulated	 = 0x00, ///< SEND_ENCAPSULATED_COMMAND
+		KSetCommFeature 	 = 0x02, ///< SET_COMM_FEATURE
+		KClearCommFeature	 = 0x04, ///< CLEAR_COMM_FEATURE
+		KSetLineCoding		 = 0x20, ///< SET_LINE_CODING
+		KSetControlLineState = 0x22, ///< SET_CONTROL_LINE_STATE
+		KSendBreak			 = 0x23, ///< SEND_BREAK
+		};
+
+	enum TReaderState
+		{
+		EWaitingForHeader = 0,	///< Waiting for message header
+		EWaitingForData = 1,	///< Waiting for message data
+		};
+
+	TBuf8<KAcmControlReadBufferLength> iMessageData;	///< Message data
+	///< Decoded message header
+	TUsbRequestHdr iRequestHeader;						
+	TReaderState iState;								///< Reader state
+	};
+
+#endif // __CDCCONTROLINTERFACEREADER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/CdcControlInterfaceRequestHandler.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,84 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __CDCCOMMSCLASSREQUESTHANDLER_H__
+#define __CDCCOMMSCLASSREQUESTHANDLER_H__
+
+#include <e32std.h>
+
+class MCdcCommsClassRequestHandler
+/**
+ * Interface for control interface requests from the host. Called by the 
+ * reader on the control endpoint (ep0) when it decodes a relevant command.
+ */
+	{
+public:
+/**
+ * Callback for Send Encap Command requests
+ * @param aData Message data.
+ */
+	virtual TInt HandleSendEncapCommand(const TDesC8& aData) = 0;
+/**
+ * Callback for Get Encapsulated Response requests
+ * @param aReturnData Message data.
+ */
+	virtual TInt HandleGetEncapResponse(TDes8& aReturnData) = 0;
+/**
+ * Callback for Set Comm Feature requests
+ * @param aSelector The source of wValue control over feature selection
+ * @param aData   The multiplexed data/idle state or country code from ISO 3166
+ */
+	virtual TInt HandleSetCommFeature(const TUint16 aSelector, 
+		const TDes8& aData) = 0;
+/**
+ * Callback for Get Comm Feature requests
+ * @param aSelector The source of wValue control over feature selection
+ * @param aReturnData The multiplexed data/idle state or country code from ISO 
+ * 3166
+ */
+	virtual TInt HandleGetCommFeature(const TUint16 aSelector, 
+		TDes8& aReturnData) = 0;
+/**
+ * Callback for Clear Comm Feature requests
+ * @param aSelector
+ */
+	virtual TInt HandleClearCommFeature(const TUint16 aSelector) = 0;
+/**
+ * Callback for Set Line Coding requests
+ * @param aData Message data.
+ */
+	virtual TInt HandleSetLineCoding(const TDesC8& aData) = 0;
+/**
+ * Callback for Get Line Coding requests
+ * @param aReturnData Message data.
+ */
+	virtual TInt HandleGetLineCoding(TDes8& aReturnData) = 0;
+/**
+ * Callback for Set Control Line State requests
+ * @param aRtsState RTS state.
+ * @param aDtrState DTR state.
+ */
+	virtual TInt HandleSetControlLineState(TBool aRtsState,
+										   TBool aDtrState) = 0;
+/**
+ * Callback for Send Break requests
+ * @param aDuration Duration of the break in microseconds
+ */
+	virtual TInt HandleSendBreak(TUint16 aDuration) = 0;
+	};
+
+#endif // __CDCCOMMSCLASSREQUESTHANDLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/CdcDataInterface.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,126 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __CDCDATAINTERFACE_H__
+#define __CDCDATAINTERFACE_H__
+
+#include "CdcInterfaceBase.h"
+#include "WriteObserver.h"
+#include "ReadObserver.h"
+#include "ReadOneOrMoreObserver.h"
+#include "linkstatenotifier.h"
+#include "NotifyDataAvailableObserver.h"
+
+
+
+class CActiveReadOneOrMoreReader;
+class CActiveReader;
+class CActiveDataAvailableNotifier;
+class CActiveWriter;
+class CIniFile;
+
+NONSHARABLE_CLASS(CCdcDataInterface) :	public CCdcInterfaceBase,
+							public MReadObserver,
+							public MReadOneOrMoreObserver,
+							public MWriteObserver,
+							public MLinkStateObserver,
+							public MNotifyDataAvailableObserver
+/**
+ * ACM data interface subclass.
+ */
+	{
+public:
+	static CCdcDataInterface* NewL(const TDesC16& aIfcName);
+	~CCdcDataInterface();
+
+public:
+	void Write(MWriteObserver& aObserver, const TDesC8& aDes, TInt aLen);
+	void CancelWrite();
+	void Read(MReadObserver& aObserver, TDes8& aDes, TInt aMaxLen);
+	void ReadOneOrMore(MReadOneOrMoreObserver& aObserver, 
+		TDes8 &aDes, 
+		TInt aMaxLen);
+	void CancelRead();
+	void NotifyDataAvailable(MNotifyDataAvailableObserver& aObserver);
+	void CancelNotifyDataAvailable();
+
+private:
+	CCdcDataInterface();
+	CCdcDataInterface(const TDesC16& aIfcName);
+	void ConstructL();
+
+private: // from MReadOneOrMoreObserver
+	void ReadOneOrMoreCompleted(TInt aError);
+
+private: // from MReadObserver
+	void ReadCompleted(TInt aError);
+
+private: // from MWriteObserver
+	void WriteCompleted(TInt aError);
+
+private: // from CCdcClassBase
+	TInt SetUpInterface();
+
+private: // from MLinkStateObserver
+	void MLSOStateChange(TInt aPacketSize);
+
+private: // from MNotifyDataAvailableObserver
+	void NotifyDataAvailableCompleted(TInt aError);
+
+private: 
+	void GetHostZLPHandlingFromFile();
+
+private: // owned
+	CActiveReadOneOrMoreReader* iReadOneOrMoreReader;
+	CActiveReader* iReader;
+	CActiveWriter* iWriter;
+	CActiveDataAvailableNotifier* iDataAvailableNotifier;
+	CLinkStateNotifier* iLinkState;
+	TBool iHostCanHandleZLPs;  ///< Host USB Device Driver can cope with Zero Length Packets
+	TInt iPacketSize;
+
+private: // unowned
+	MReadObserver* iReadObserver;
+	MReadOneOrMoreObserver* iReadOneOrMoreObserver;
+	MWriteObserver* iWriteObserver;
+	MNotifyDataAvailableObserver* iNotifyDataAvailableObserver;
+
+#ifdef __HEADLESS_ACM_TEST_CODE__
+	// This code is for testing the performance of the stack at the 
+	// RDevUsbcClient level. Issue a Read or ReadOneOrMore at the RComm level, 
+	// and it will be passed to the LDD. When it completes, it will Write the 
+	// data back. When that completes, it will again Read/ROOM. It basically 
+	// enters an infinite loop, doing loopback. Drive this from the PC end 
+	// using serial.exe.
+private: // owned
+	// The buffer to do repeated Read/ReadOneOrMore into and Writes from.
+	TBuf8<4096> iHeadlessAcmBuffer;
+	// The length of the initial Read/ROOM request- we continue to use this 
+	// value in subsequent Read/ROOM requests.
+	TUint iHeadlessReadLength;
+	// Whether we're currently using Read or ROOM. 
+	enum THeadlessReadType
+		{
+		EUnknown,
+		ERead,
+		EReadOneOrMore
+		};
+	THeadlessReadType iHeadlessReadType;
+#endif // __HEADLESS_ACM_TEST_CODE__
+	};
+
+#endif // __CDCDATAINTERFACE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/CdcInterfaceBase.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __CDCINTERFACEBASE_H__
+#define __CDCINTERFACEBASE_H__
+
+#include <e32base.h>
+#include <d32usbc.h>
+
+NONSHARABLE_CLASS(CCdcInterfaceBase) : public CBase
+/**
+ * Base class for ACM interface subclasses.
+ */
+	{
+public:
+	~CCdcInterfaceBase();
+
+public:
+	TInt GetInterfaceNumber(TUint8& aIntNumber);
+
+protected:
+	CCdcInterfaceBase(const TDesC16& aIfcName);
+	void BaseConstructL();
+
+private:
+	virtual TInt SetUpInterface() = 0;
+
+protected: // owned
+	RDevUsbcClient iLdd;			///< The Ldd to use.
+	TPtrC16 iIfcName;
+	};
+
+#endif // __CDCINTERFACEBASE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ClassDescriptor.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,81 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __CLASSDESCRIPTOR_H__
+#define __CLASSDESCRIPTOR_H__
+
+#include <e32std.h>
+#include "acmcapability.h"
+
+#ifdef DISABLE_ACM_CF_COUNTRY_SETTING
+
+	const TUint   KUSBClassSpecificBufferSize = 14;
+
+#elif defined ENABLE_ACM_CF_COUNTRY_SETTING
+
+	const TUint   KUsbCommNumCountries = 1;
+	const TUint16 KUsbCommCountryCode0 = (('G'<<8)+'B');
+	const TUint   KUSBClassSpecificBufferSize = 18 + (2*KUsbCommNumCountries);
+
+#endif
+
+NONSHARABLE_CLASS(TUsbCsClassDescriptor) 	///< Class-specific descriptor
+	{
+public:
+	TUint8	iHdrSize;			///< Header size
+	TUint8	iHdrType;			///< Type
+	TUint8	iHdrSubType;		///< Sub-type
+	TUint16 iHdrBcdCDC; 		///< CDC version no in binary coded decimal
+	TUint8	iAcmSize;			///< ACM descriptor size
+	TUint8	iAcmType;			///< ACM type
+	TUint8	iAcmSubType;		///< ACM sub-type
+	TUint8	iAcmCapabilities;	///< ACM capabilities
+	TUint8	iUnSize;			///< Union descriptor size
+	TUint8	iUnType;			///< Union descriptor type
+	TUint8	iUnSubType; 		///< Union descriptor sub-type
+	TUint8	iUnMasterInterface; ///< Master interface number
+	TUint8	iUnSlaveInterface;	///< Slave interface number
+
+#if defined(DISABLE_ACM_CF_COUNTRY_SETTING)
+
+	// no functional descriptor needed
+
+#elif defined(ENABLE_ACM_CF_COUNTRY_SETTING)
+
+	// CDC Country Selection Functional Descriptor
+	TUint8 iCsSize;    ///< Country Selection descriptor size
+	TUint8 iCsType;    ///< Country Selection descriptor type
+	TUint8 iCsSubType; ///< Country Selection descriptor sub-type
+	TUint8 iCsRelDate; ///< Country Selection (string ddmmyyyy) ISO-3166 date
+	TUint16 iCsCountryCode[KUsbCommNumCountries];
+
+#endif
+
+public:
+	TDes8& Des();
+
+private:
+	enum
+		{
+		///< Size of the ACM class-specific descriptor
+		KUsbClassSpecificBufferSize = 14,
+		};
+
+	TBuf8<KUsbClassSpecificBufferSize> iBuffer;
+	};
+
+#endif // __CLASSDESCRIPTOR_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/HostPushedChangeObserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __HOSTPUSHEDCHANGEOBSERVER_H__
+#define __HOSTPUSHEDCHANGEOBSERVER_H__
+
+#include <e32std.h>
+#include <d32comm.h>
+ 
+class MHostPushedChangeObserver
+/**
+ * The CSY callback interface. This class provides methods that enable the ACM 
+ * class to inform the CSY of changes pushed by the host.
+ */
+	{
+public:
+	virtual void HostConfigChange(const TCommConfigV01& aConfig) = 0;
+	virtual void HostSignalChange(TBool aDtr, TBool aRts) = 0;
+	};
+
+#endif // __HOSTPUSHEDCHANGEOBSERVER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/LittleEndianPacker.INL	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,136 @@
+/*
+* Copyright (c) 2003-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 LittleEndianPacker.INL
+ *
+ * Implements inline macro functions used to interface between USB
+ * (little-endian) byte buffers and standard data types.
+ *
+ * The implementation uses inline macros (for speed) that are used to 
+ * step down a little-endian USB buffer to extract and insert members.
+ *
+ * The functions update the given buffer index so that they can be 
+ * used in sequence to extract or pack successive parts of a message.
+ *
+ * Although these functions are of more general use than just the CDC 
+ * application, they are located here pending possible promotion into 
+ * the chapter.9 area, where they would become available for use in 
+ * other classes, e.g. HID
+ *
+ * Copyright (c) 2003 Symbian Ltd.	All rights reserved.
+ */
+
+#ifndef __LITTLEENDIANPACKER_INL__
+#define __LITTLEENDIANPACKER_INL__
+
+#include <e32def.h>
+
+/* ------------------------------------------------------------------------- */
+
+typedef union _FloatInt
+	{
+	TUint32 uVal;
+	TReal32 fVal;
+	}
+	UFloatInt;
+
+inline TReal32 CCdcControlInterface::GetF32( TUint8** aPPbuf )
+	{
+	UFloatInt retval;
+
+	retval.uVal = GetU32(aPPbuf);
+
+	return retval.fVal;
+	};
+
+inline void CCdcControlInterface::PutF32( TUint8** aPPbuf, TReal32 aF32 )
+	{
+	UFloatInt inval;
+
+	inval.fVal = aF32;
+
+	PutU32(aPPbuf,inval.uVal);
+	};
+
+/* ------------------------------------------------------------------------- */
+
+inline TUint32 CCdcControlInterface::GetU32( TUint8** aPPbuf )
+	{
+	TUint8* pbuf = *aPPbuf;
+	
+	*aPPbuf = pbuf + sizeof(TUint32);
+
+	return (TUint32)( (pbuf[3] << 24 ) | ( pbuf[2] << 16 ) | ( pbuf[1] << 8 ) | ( pbuf[0] ) );
+	};
+
+inline void CCdcControlInterface::PutU32( TUint8** aPPbuf, TUint32 aU32 )
+	{
+	TUint8* pbuf = *aPPbuf;
+	
+	*aPPbuf = pbuf + sizeof(TUint32);
+
+	pbuf[3] = (TUint8) ((aU32 >> 24)	   ); // mask not needed, only 8 bits left
+	pbuf[2] = (TUint8) ((aU32 >> 16) & 0xFF);
+	pbuf[1] = (TUint8) ((aU32 >>  8) & 0xFF);
+	pbuf[0] = (TUint8) ((aU32	   ) & 0xFF); // shift not needed, mask takes 8 bits
+	};
+
+/* ------------------------------------------------------------------------- */
+
+inline TUint16 CCdcControlInterface::GetU16( TUint8** aPPbuf )
+	{
+	TUint8* pbuf = *aPPbuf;
+	
+	*aPPbuf = pbuf + sizeof(TUint16);
+
+	return (TUint16) ( ( pbuf[1] << 8) | ( pbuf[0] ) );
+	};
+
+inline void CCdcControlInterface::PutU16( TUint8** aPPbuf, TUint16 aU16 )
+	{
+	TUint8* pbuf = *aPPbuf;
+
+	*aPPbuf = pbuf + sizeof(TUint16);
+	
+	pbuf[3] = (TUint8) ((aU16 >> 8) 	  ); // mask not needed, only 8 bits left
+	pbuf[0] = (TUint8) ((aU16	  ) & 0xFF); // shift not needed, mask takes 8 bits
+	};
+
+/* ------------------------------------------------------------------------- */
+
+inline TUint8 CCdcControlInterface::GetU08( TUint8** aPPbuf )
+	{
+	TUint8* pbuf = *aPPbuf;
+	
+	*aPPbuf = pbuf + sizeof(TUint8);
+
+	return (TUint8) ( pbuf[0] );
+	};
+
+inline void CCdcControlInterface::PutU08( TUint8** aPPbuf, TUint8 aU8 )
+	{
+	TUint8* pbuf = *aPPbuf;
+
+	*aPPbuf = pbuf + sizeof(TUint8);
+	
+	pbuf[0] = (aU8);
+	};
+
+/* ------------------------------------------------------------------------- */
+#endif // __LITTLEENDIANPACKER_INL__
+/* ------------------------------------------------------------------------- */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/NotifyDataAvailableObserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef __NOTIFYDATAAVAILABLEOBSERVER_H__
+#define __NOTIFYDATAAVAILABLEOBSERVER_H__
+
+#include <e32std.h>
+
+class MNotifyDataAvailableObserver
+/**
+ * Notification that data is available to be read from the device driver.
+ */
+	{
+public:
+	virtual void NotifyDataAvailableCompleted(TInt aError) = 0;
+	};
+
+#endif // __NOTIFYDATAAVAILABLEOBSERVER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ReadObserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __READOBSERVER_H__
+#define __READOBSERVER_H__
+
+#include <e32std.h>
+
+class MReadObserver
+/** 
+ * An interface for notification of read completions.
+ */
+	{
+public:
+	virtual void ReadCompleted(TInt aError) = 0;
+	};
+
+
+#endif // __READOBSERVER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/ReadOneOrMoreObserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __READONEORMOREOBSERVER_H__
+#define __READONEORMOREOBSERVER_H__
+
+#include <e32std.h>
+
+class MReadOneOrMoreObserver
+/**
+ * Interface for notifications of read one or more completions.
+ */
+	{
+public:
+	virtual void ReadOneOrMoreCompleted(TInt aError) = 0;
+	};
+
+#endif // __READONEORMOREOBSERVER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/RegistrationPort.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,90 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __REGISTRATIONPORT_H__
+#define __REGISTRATIONPORT_H__
+
+#include <cs_port.h>
+
+class MAcmController;
+
+/**
+The registration port.
+This is a deprecated method for controlling (bringing up and down) ACM 
+functions.
+ACM Class Controllers open a registration port and use SetSignalsToMark and 
+SetSignalsToSpace to bring ACM functions up and down.
+The newer method involved creating a session on the ACM server (RAcmServer) 
+and using the APIs provided.
+*/
+NONSHARABLE_CLASS(CRegistrationPort) : public CPort
+	{
+public:
+	static CRegistrationPort* NewL(MAcmController& aAcmController, 
+		TUint aUnit);
+	~CRegistrationPort();
+
+private:
+	CRegistrationPort(MAcmController& aAcmController);
+	void ConstructL(TUint aUnit);
+
+private: // from CPort
+	virtual void StartRead(const TAny* aClientBuffer,TInt aLength);
+	virtual void ReadCancel();
+	virtual TInt QueryReceiveBuffer(TInt& aLength) const;
+	virtual void ResetBuffers(TUint aFlags);
+	virtual void StartWrite(const TAny* aClientBuffer,TInt aLength);
+	virtual void WriteCancel();
+	virtual void Break(TInt aTime);
+	virtual void BreakCancel();
+	virtual TInt GetConfig(TDes8& aDes) const;
+	virtual TInt SetConfig(const TDesC8& aDes);
+	virtual TInt SetServerConfig(const TDesC8& aDes);
+	virtual TInt GetServerConfig(TDes8& aDes);
+	virtual TInt GetCaps(TDes8& aDes);
+	virtual TInt GetSignals(TUint& aSignals);
+	virtual TInt SetSignalsToMark(TUint aNoAcms);
+	virtual TInt SetSignalsToSpace(TUint aNoAcms);
+	virtual TInt GetReceiveBufferLength(TInt& aLength) const;
+	virtual TInt SetReceiveBufferLength(TInt aLength);
+	virtual void Destruct();
+	virtual void FreeMemory();
+	virtual void NotifySignalChange(TUint aSignalMask);
+	virtual void NotifySignalChangeCancel();
+	virtual void NotifyConfigChange();
+	virtual void NotifyConfigChangeCancel();
+	virtual void NotifyFlowControlChange();
+	virtual void NotifyFlowControlChangeCancel();
+	virtual void NotifyBreak();
+	virtual void NotifyBreakCancel();
+	virtual void NotifyDataAvailable();
+	virtual void NotifyDataAvailableCancel();
+	virtual void NotifyOutputEmpty();
+	virtual void NotifyOutputEmptyCancel();
+	virtual TInt GetFlowControlStatus(TFlowControl& aFlowControl);
+	virtual TInt GetRole(TCommRole& aRole);
+	virtual TInt SetRole(TCommRole aRole);
+
+private: // unowned
+	MAcmController& iAcmController;
+
+private: // owned
+	// Dummy role of the serial port (DTE or DCE)
+	TCommRole iRole;			
+	};
+
+#endif // __REGISTRATIONPORT_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/RequestHeader.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,43 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __REQUESTHEADER_H__
+#define __REQUESTHEADER_H__
+
+#include <e32std.h>
+
+const TUint KUsbRequestHdrSize = 8; ///< Size of the request header
+
+NONSHARABLE_CLASS(TUsbRequestHdr)		///< Class-specific header structure
+	{
+public:
+	TUint8	iRequestType;	///< Request type
+	TUint8	iRequest;		///< Request number
+	TUint16 iValue; 		///< Request value
+	TUint16 iIndex; 		///< Request index
+	TUint16 iLength;		///< Request length
+
+public:
+	static TInt Decode(const TDesC8& aBuffer, TUsbRequestHdr& aTarget);
+	const TDesC8& Des();
+	TBool IsDataResponseRequired() const;
+
+private:
+	TBuf8<KUsbRequestHdrSize> iBuffer;
+	};
+
+#endif // __REQUESTHEADER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/WriteObserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __WRITEOBSERVER_H__
+#define __WRITEOBSERVER_H__
+
+#include <e32std.h>
+
+class MWriteObserver
+/** 
+ * An interface for notification of write completions.
+ */
+	{
+public:
+	virtual void WriteCompleted(TInt aError) = 0;
+	};
+
+
+#endif // __WRITEOBSERVER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/acmcapability.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,98 @@
+/*
+* Copyright (c) 1997-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:
+* Defines USB CDC Control Class supported feature subset
+*
+*/
+
+/**
+ @file
+*/
+
+#ifndef __ACMCAPABILITY_H__
+#define __ACMCAPABILITY_H__
+
+/** 
+ *	Country Code Selection -------------------------------
+ */
+#undef	 ENABLE_ACM_CF_COUNTRY_SETTING
+#define DISABLE_ACM_CF_COUNTRY_SETTING
+
+#if( defined(DISABLE_ACM_CF_COUNTRY_SETTING) && defined(ENABLE_ACM_CF_COUNTRY_SETTING) )
+
+	#error Country-Setting Feature Cannot be Both Enabled and Disabled
+
+#elif defined(DISABLE_ACM_CF_COUNTRY_SETTING)
+
+	// feature is not present
+
+#elif defined(ENABLE_ACM_CF_COUNTRY_SETTING)
+
+	// feature is present
+
+#else
+
+	#error Uncontrolled Country-Setting Feature
+
+#endif
+
+/** 
+ *	Abstract State Selection (Idle) ----------------------
+ */
+#undef	 ENABLE_ACM_CF_IDLE_SETTING
+#define DISABLE_ACM_CF_IDLE_SETTING
+
+#if( defined(DISABLE_ACM_CF_IDLE_SETTING) && defined(ENABLE_ACM_CF_IDLE_SETTING) )
+
+	#error Abstract Idle Setting Feature Cannot be Both Enabled and Disabled
+
+#elif defined(DISABLE_ACM_CF_IDLE_SETTING)
+
+	// feature is not present
+
+#elif defined(ENABLE_ACM_CF_IDLE_SETTING)
+
+	// feature is present
+
+#else
+
+	#error Uncontrolled Abstract Idle Setting Feature
+
+#endif
+
+/** 
+ *	Abstract State Selection (Multiplex) -----------------
+ */
+#undef	 ENABLE_ACM_CF_DATA_MULTIPLEX
+#define DISABLE_ACM_CF_DATA_MULTIPLEX
+
+#if( defined(DISABLE_ACM_CF_DATA_MULTIPLEX) && defined(ENABLE_ACM_CF_DATA_MULTIPLEX) )
+
+	#error Abstract Data Multiplex Feature Cannot be Both Enabled and Disabled
+
+#elif defined(DISABLE_ACM_CF_DATA_MULTIPLEX)
+
+	// feature is not present
+
+#elif defined(ENABLE_ACM_CF_DATA_MULTIPLEX)
+
+	// feature is present
+
+#else
+
+	#error Uncontrolled Abstract Data Multiplex Feature
+
+#endif
+
+#endif // __ACMCAPABILITY_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/acmcontroller.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __ACMCONTROLLER_H__
+#define __ACMCONTROLLER_H__
+
+#include <e32base.h>
+
+class MAcmController
+
+/**
+ * Interface for bringing up and down ACM functions.
+ * Used by both the (deprecated) registration port method of controlling ACM 
+ * functions, and by the 'ACM server' method.
+ */
+	{
+public:
+	virtual TInt CreateFunctions(const TUint aNoAcms, const TUint8 aProtocolNum, const TDesC& aAcmControlIfcName, const TDesC& aAcmDataIfcName) = 0;
+	virtual void DestroyFunctions(const TUint aNoAcms) = 0;
+	};
+
+#endif // __ACMCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/acmserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,50 @@
+/*
+* 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 "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
+*/
+
+#ifndef ACMSERVER_H
+#define ACMSERVER_H
+
+#include <e32base.h>
+
+class MAcmController;
+
+/**
+The ACM server class - this is created/owned by the ACM Port Factory.
+Clients can use this server to create and destroy ACM functions.
+*/
+NONSHARABLE_CLASS(CAcmServer) : public CPolicyServer
+	{
+public:
+	static CAcmServer* NewL(MAcmController& aAcmController);
+	~CAcmServer();
+
+private:
+	CAcmServer(MAcmController& aAcmController);
+	
+private: // from CPolicyServer
+	CSession2* NewSessionL(const TVersion &aVersion, const RMessage2& aMessage) const;
+	
+private: // unowned
+	MAcmController& iAcmController;
+	};
+
+#endif // ACMSERVER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/acmserversecuritypolicy.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,70 @@
+/*
+* 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 "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:
+* Server Security Policy definitions.
+*
+*/
+
+/**
+ @file 
+ @internalComponent
+*/
+ 
+#ifndef ACMSERVERSECURITYPOLICY_H
+#define ACMSERVERSECURITYPOLICY_H
+
+#include <e32base.h>
+#include "acmserverconsts.h"
+
+/** ACM Server Security Policy Definition */
+const TUint KAcmServerRangeCount = 2;
+
+const TInt KAcmServerRanges[KAcmServerRangeCount] = 
+	{
+	EAcmCreateAcmFunctions, 			/** pass */
+	EAcmDestroyAcmFunctions + 1,		/** fail (to KMaxTInt) */
+	};
+
+/** Index numbers into KAcmServerElements[] */
+const TInt KPolicyUsbsvr = 0;
+
+/** Mapping IPCs to policy element */
+const TUint8 KAcmServerElementsIndex[KAcmServerRangeCount] = 
+	{
+	KPolicyUsbsvr,					/** All (valid) APIs */
+	CPolicyServer::ENotSupported,	/** remainder of possible IPCs */
+	};
+
+/** Individual policy elements */
+const CPolicyServer::TPolicyElement KAcmServerElements[] = 
+	{
+		{ 
+		// These caps are those of USBSVR's process. This is the recommended 
+		// way to check that an API is called by a specific process only. [The 
+		// alternative would be an SID check.]
+		_INIT_SECURITY_POLICY_C5(ECapabilityCommDD, ECapabilityNetworkControl, ECapabilityNetworkServices, ECapabilityLocalServices, ECapabilityProtServ), CPolicyServer::EFailClient 
+		},
+	};
+
+/** Main policy */
+const CPolicyServer::TPolicy KAcmServerPolicy = 
+	{
+	CPolicyServer::EAlwaysPass, /** Specifies all connect attempts should pass */
+	KAcmServerRangeCount,
+	KAcmServerRanges,
+	KAcmServerElementsIndex,
+	KAcmServerElements,
+	};
+	
+#endif // ACMSERVERSECURITYPOLICY_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/acmsession.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,51 @@
+/*
+* 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 "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
+*/
+
+#ifndef ACMSESSION_H
+#define ACMSESSION_H
+
+#include <e32base.h>
+
+class MAcmController;
+
+NONSHARABLE_CLASS(CAcmSession) : public CSession2
+	{
+public:
+	static CAcmSession* NewL(MAcmController& aAcmController);
+	~CAcmSession();
+
+private:
+	CAcmSession(MAcmController& aAcmController);
+	void CreateFunctionsL(const RMessage2& aMessage);
+		
+private: // from CSession2
+	/**
+	Called when a message is received from the client.
+	@param aMessage Message received from the client.
+	*/
+	void ServiceL(const RMessage2& aMessage);
+
+private: // unowned
+	MAcmController& iAcmController;
+	};
+
+#endif // ACMSESSION_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/inc/linkstatenotifier.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,74 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef __LINKSTATENOTIFIER_H__
+#define __LINKSTATENOTIFIER_H__
+
+#include <e32base.h> 
+
+class RDevUsbcClient;
+
+
+const TInt KMaxPacketTypeBulkFS = 64;
+const TInt KMaxPacketTypeBulkHS = 512;
+
+const TInt KDefaultMaxPacketTypeBulk = KMaxPacketTypeBulkFS;
+
+
+class MLinkStateObserver
+/**
+ * Interface for notifications of link state events.
+ */
+	{
+public:
+	virtual void MLSOStateChange(TInt aPacketSize) = 0;
+	};
+
+NONSHARABLE_CLASS(CLinkStateNotifier) : public CActive
+/**
+ * Active object to request link state notifications.
+ */
+	{
+public:
+	static CLinkStateNotifier* NewL(MLinkStateObserver& aParent, 
+		RDevUsbcClient& aUsb);
+	~CLinkStateNotifier();
+	
+	void Start();
+
+private: // from CActive
+	virtual void DoCancel();
+	virtual void RunL();
+	virtual TInt RunError(TInt aError);
+
+private:
+	CLinkStateNotifier(MLinkStateObserver& aParent, RDevUsbcClient& aUsb);
+
+private:
+	void LinkUp();
+	void LinkDown();
+
+private: // unowned
+	MLinkStateObserver& iParent; ///< Observer
+	RDevUsbcClient& iUsb;		///< The Ldd to use
+
+private: // owned
+	TUint iUsbState;		///< Bitmask representing the endpoints
+	TInt iPacketSize;
+	};
+
+#endif // __LINKSTATENOTIFIER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/public/AcmConfig.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,126 @@
+/*
+* Copyright (c) 2007-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 
+ @publishedPartner
+ @released
+*/
+
+#ifndef __ACMCONFIG_H__
+#define __ACMCONFIG_H__
+
+#include <e32base.h>
+
+/**
+Constant to use as the key when subscribing to the ACM function
+configuration data.
+*/
+static const TInt32 KAcmKey = 0x1028577C;
+
+/**
+Structure describing the ACM function configuration
+*/
+NONSHARABLE_STRUCT(TAcmConfig)
+	{
+	/**
+	iProtocol
+	iProtocol is the only field used at this time. Stores the protocol 
+	that this AcmFunction was created to use.
+	*/
+	TUint8 iProtocol;	
+	/**
+	Reserved for future use
+	*/
+	TInt8 iReserved8Bit1; 
+	/**
+	Reserved for future use
+	*/
+	TInt8 iReserved8Bit2;
+	/**
+	Reserved for future use
+	*/
+	TInt8 iReserved8Bit3;
+	/**
+	Reserved for future use
+	*/
+	TInt32 iReserved1;
+	/**
+	Reserved for future use
+	*/
+	TInt32 iReserved2;
+	/**
+	Reserved for future use
+	*/
+	TInt32 iReserved3;
+	/**
+	Reserved for future use
+	*/
+	TInt32 iReserved4;
+	};
+
+/**
+Structure to hold TAcmConfig structs and publish all available 
+configurations in a single wrapper.
+*/
+NONSHARABLE_STRUCT(TPublishedAcmConfigs)
+	{	
+	/**
+	Constant to define the maximum number of ACM functions it should
+	be possible to create. Used to calculate the size of the byte
+	array to allocate when publishing the data.
+	*/
+	static const TInt16 KAcmMaxFunctions = 8;
+				   			
+	/**
+	iAcmConfigVersion
+	Version 1 is the only valid version at this time.
+	*/
+	TUint		iAcmConfigVersion;
+	/**
+	iAcmCount
+	iAcmCount defines number of valid AcmConfigs in sequence. Only AcmConfigs
+	with an array index < AcmCount are valid. If iAcmCount == 0 then there  
+	are no valid AcmConfigs at this time.
+	*/
+	TUint		iAcmCount; 
+	
+	/**
+	iAcmConfig
+	Array of TAcmConfig structs to hold the available Acm configurations
+	*/
+	TAcmConfig	iAcmConfig[KAcmMaxFunctions];
+	
+	/**
+	Reserved for future use
+	*/
+	TInt32 iReserved1;
+	/**
+	Reserved for future use
+	*/
+	TInt32 iReserved2;
+		/**
+	Reserved for future use
+	*/
+	TInt32 iReserved3;
+	/**
+	Reserved for future use
+	*/
+	TInt32 iReserved4;	
+	};
+
+#endif //__ACMCONFIG_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/public/AcmInterface.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __ACMINTERFACE_H__
+#define __ACMINTERFACE_H__
+
+/** @file
+Public interface to ECACM CSY.
+@publishedPartner
+@released
+*/
+
+#include <e32std.h>
+
+/**
+The root of the CSY filename. Use this in LoadCommModule.
+*/
+_LIT(KAcmCsyName, "ECACM"); 
+
+/**
+The name of the CSerial, and consequently the root of the ACM port name 
+ACM::0. Use this in Open (and UnloadCommModule, if you're not closing your 
+session anyway).
+*/
+_LIT(KAcmSerialName, "ACM"); 
+
+/**
+Lowest valid value of %d in calls to Open(_L("ACM::%d")).
+For the highest valid value of %d in calls to Open(_L("ACM::%d")), use RCommServ::GetPortInfo.
+Note that if USB services are stopped/idle (see RUsb::GetServiceState) the high unit value will 
+be incorrect. Under these circumstances, no ACM ports are may be opened, but TSerialInfo cannot
+express this.
+When USB services are starting/started/stopping, the given high unit will accurately reflect 
+the highest available port number. Note that this numerical value will depend on the current 
+USB personality (see RUsb) and also potentially whether USB is fully started or in a transitional
+state (starting or stopping).
+*/
+const TUint KAcmLowUnit = 0;
+
+/**
+@deprecated RCommServ::GetPortInfo is the preferred method for determining the number of available ports.
+@see RCommServ::GetPortInfo
+*/	
+const TUint KAcmHighUnit = 0; 
+
+#endif // __ACMINTERFACE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/public/acmserverconsts.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,70 @@
+/*
+* 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 "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
+*/
+
+#ifndef ACMSERVERCONSTS_H
+#define ACMSERVERCONSTS_H
+
+#include <e32base.h>
+
+_LIT(KAcmServerName, "!AcmSrv");
+
+/** Version numbers. */
+const TInt8 KAcmSrvMajorVersionNumber = 1;
+const TInt8 KAcmSrvMinorVersionNumber = 1;
+const TInt16 KAcmSrvBuildNumber = 0;
+
+/** IPC messages supported by the server. */
+enum TAcmIpc
+	{
+	EAcmCreateAcmFunctions				= 0, // the 1st message must be 0 for CPolicyServer to start up
+	EAcmDestroyAcmFunctions				= 1,		
+	};
+	
+/** Panic category with which the ACM server panics the client. */
+_LIT(KAcmSrvPanic,"ACMServer");
+
+/** Panic codes with which the ACM server panics the client. */
+enum TAcmSvrPanic
+	{
+	/** The client has sent a bad IPC message number. */
+	EAcmBadAcmMessage		 = 0,
+	};
+
+/**
+Default protocol number for ACM ports. Taken from USBCDC 1.1 Table 17
+@internalTechnology
+*/	
+const TUint8 KDefaultAcmProtocolNum = 0x01; // Hayes compatible modem
+
+/**
+Default control interface name for ACM ports.
+@internalTechnology
+*/	
+_LIT16(KControlIfcName, "CDC Comms Interface");
+
+/**
+Default data interface name for ACM ports.
+@internalTechnology
+*/	
+_LIT16(KDataIfcName, "CDC Data Interface");
+
+#endif // ACMSERVERCONSTS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/AcmPort.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,1654 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <acminterface.h>
+#include <usb/usblogger.h>
+#include "AcmPort.h"
+#include "AcmPortFactory.h"
+#include "AcmUtils.h"
+#include "AcmWriter.h"
+#include "AcmReader.h"
+#include "AcmPanic.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+const TUint KCapsRate=(   KCapsBps50
+						| KCapsBps75
+						| KCapsBps110
+						| KCapsBps134
+						| KCapsBps150
+						| KCapsBps300
+						| KCapsBps600
+						| KCapsBps1200
+						| KCapsBps1800
+						| KCapsBps2000
+						| KCapsBps2400
+						| KCapsBps3600
+						| KCapsBps4800
+						| KCapsBps7200
+						| KCapsBps9600
+						| KCapsBps19200
+						| KCapsBps38400
+						| KCapsBps57600
+						| KCapsBps115200
+						| KCapsBps230400
+						| KCapsBps460800
+						| KCapsBps576000
+						| KCapsBps115200
+						| KCapsBps4000000 );
+const TUint KCapsDataBits=KCapsData8;		
+const TUint KCapsStopBits=KCapsStop1;		
+const TUint KCapsParity=KCapsParityNone;	
+const TUint KCapsHandshaking=(
+						  KCapsSignalCTSSupported
+						| KCapsSignalDSRSupported
+						| KCapsSignalRTSSupported
+						| KCapsSignalDTRSupported); 
+const TUint KCapsSignals=(
+							KCapsSignalCTSSupported
+						|	KCapsSignalDSRSupported
+						|	KCapsSignalRTSSupported
+						|	KCapsSignalDTRSupported);
+const TUint KCapsFifo = 0;
+const TUint KCapsSIR = 0; ///< Serial Infrared capabilities
+const TUint KCapsNotification = KNotifySignalsChangeSupported;			
+const TUint KCapsRoles = 0; 				
+const TUint KCapsFlowControl = 0;							
+
+const TBps		KDefaultDataRate = EBps115200;		
+const TDataBits KDefaultDataBits = EData8;			
+const TParity	KDefaultParity	 = EParityNone; 	
+const TStopBits KDefaultStopBits = EStop1;			
+const TUint 	KDefaultHandshake = 0;	
+///< Default XON character is <ctrl>Q				
+const TText8	KDefaultXon 	 = 17; 
+///< Default XOFF character is <ctrl>S
+const TText8	KDefaultXoff	 = 19; 
+
+// Starting size of each of the receive and transmit buffers.
+const TUint KDefaultBufferSize = 0x1000;
+
+CAcmPort* CAcmPort::NewL(const TUint aUnit, MAcmPortObserver& aFactory)
+/**
+ * Make a new CPort for the comm server
+ *
+ * @param aFactory The observer of the port, to be notified when the port 
+ * closes.
+ * @param aUnit The port number.
+ * @return Ownership of a newly created CAcmPort object
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CAcmPort* self = new(ELeave) CAcmPort(aUnit, aFactory);
+	CleanupClosePushL(*self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+void CAcmPort::ConstructL()
+/**
+ * Standard second phase constructor. Create owned classes and initialise the 
+ * port.
+ */
+	{
+	iReader = CAcmReader::NewL(*this, KDefaultBufferSize);
+	iWriter = CAcmWriter::NewL(*this, KDefaultBufferSize);
+
+	TName name;
+	name.Num(iUnit);
+	LEAVEIFERRORL(SetName(&name));
+
+	iCommServerConfig.iBufFlags = 0;
+	iCommServerConfig.iBufSize = iReader->BufSize();
+
+	iCommConfig.iRate			= KDefaultDataRate;
+	iCommConfig.iDataBits		= KDefaultDataBits;
+	iCommConfig.iParity 		= KDefaultParity;
+	iCommConfig.iStopBits		= KDefaultStopBits;
+	iCommConfig.iHandshake		= KDefaultHandshake;
+	iCommConfig.iParityError	= 0;
+	iCommConfig.iFifo			= 0;
+	iCommConfig.iSpecialRate	= 0;
+	iCommConfig.iTerminatorCount= 0;
+	iCommConfig.iXonChar		= KDefaultXon;
+	iCommConfig.iXoffChar		= KDefaultXoff;
+	iCommConfig.iParityErrorChar= 0;
+	iCommConfig.iSIREnable		= ESIRDisable;
+	iCommConfig.iSIRSettings	= 0;
+	}
+
+CAcmPort::CAcmPort(const TUint aUnit, MAcmPortObserver& aObserver) 
+ :	iCommNotification(iCommNotificationDes()),
+	iObserver(aObserver),
+	iUnit(aUnit)
+/**
+ * Constructor.
+ *
+ * @param aObserver The observer of the port, to be notified when the port 
+ * closes.
+ * @param aUnit The port number.
+ */
+	{
+	}
+
+void CAcmPort::StartRead(const TAny* aClientBuffer, TInt aLength)
+/**
+ * Downcall from C32. Queue a read.
+ *
+ * @param aClientBuffer pointer to the client's buffer
+ * @param aLength number of bytes to read
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+	LOGTEXT3(_L8("\taClientBuffer=0x%08x, aLength=%d"),
+		aClientBuffer, aLength);
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		ReadCompleted(KErrAccessDenied);
+		return;
+		}
+
+	// Analyse the request and call the relevant API on the data reader. NB We 
+	// do not pass requests for zero bytes to the data reader. They are an 
+	// RComm oddity we should handle here.
+	__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	if(iReader->IsNotifyDataAvailableQueryPending())
+		{
+		ReadCompleted(KErrInUse);
+		return;
+		}
+
+	if ( aLength < 0 )
+		{
+		iReader->ReadOneOrMore(aClientBuffer, static_cast<TUint>(-aLength));
+		}
+	else if ( aLength > 0 )
+		{
+		iReader->Read(aClientBuffer, static_cast<TUint>(aLength));
+		}
+	else
+		{
+		// Obscure RComm API feature- complete zero-length Read immediately, 
+		// to indicate that the hardware is powered up.
+		LOGTEXT(_L8("\tcompleting immediately with KErrNone"));
+		ReadCompleted(KErrNone);
+		}
+	}
+
+void CAcmPort::ReadCancel()
+/**
+ * Downcall from C32. Cancel a read.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return;
+		}
+
+	__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iReader->ReadCancel();
+	}
+
+TInt CAcmPort::QueryReceiveBuffer(TInt& aLength) const
+/**
+ * Downcall from C32. Get the amount of data in the receive buffer.
+ *
+ * @param aLength reference to where the amount will be written to
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+	
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	aLength = static_cast<TInt>(iReader->BufLen());
+	LOGTEXT2(_L8("\tlength=%d"), aLength);
+	return KErrNone;
+	}
+
+void CAcmPort::ResetBuffers(TUint aFlags)
+/**
+ * Downcall from C32. Reset zero or more of the Tx and Rx buffers.
+ *
+ * @param aFlags Flags indicating which buffer(s) to reset.
+ */
+	{
+	LOG_LINE
+	LOGTEXT2(_L8(">>CAcmPort::ResetBuffers aFlags = %d"), aFlags);
+
+	if ( aFlags & KCommResetRx )
+		{
+		LOGTEXT(_L8("\tresetting Rx buffer"));
+		__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		iReader->ResetBuffer();
+		}
+
+	if ( aFlags & KCommResetTx )
+		{
+		LOGTEXT(_L8("\tresetting Tx buffer"));
+		__ASSERT_DEBUG(iWriter, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		iWriter->ResetBuffer();
+		}
+
+	LOGTEXT(_L8("<<CAcmPort::ResetBuffers"));
+	}
+
+void CAcmPort::StartWrite(const TAny* aClientBuffer, TInt aLength)
+/**
+ * Downcall from C32. Queue a write
+ *
+ * @param aClientBuffer pointer to the Client's buffer
+ * @param aLength number of bytes to write
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+	LOGTEXT3(_L8("\taClientBuffer=0x%08x, aLength=%d"),
+		aClientBuffer, aLength);
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		WriteCompleted(KErrAccessDenied);
+		return;
+		}
+
+	if ( aLength < 0 )
+		{
+		// Negative length makes no sense.
+		LOGTEXT(_L8("\taLength is negative- "
+			"completing immediately with KErrArgument"));
+		WriteCompleted(KErrArgument);
+		return;
+		}
+
+	// NB We pass zero-byte writes down to the LDD as normal. This results in 
+	// a zero-length packet being sent to the host.
+
+	__ASSERT_DEBUG(iWriter, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iWriter->Write(aClientBuffer, static_cast<TUint>(aLength));
+	}
+
+void CAcmPort::WriteCancel()
+/**
+ * Downcall from C32. Cancel a pending write
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+	
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return;
+		}
+
+	__ASSERT_DEBUG(iWriter, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iWriter->WriteCancel();
+	}
+
+void CAcmPort::Break(TInt aTime)
+/**
+ * Downcall from C32. Send a break signal to the host.
+ * Note that it is assumed that the NotifyBreak() request only applies to 
+ * break signals sent from the host.
+ *
+ * @param aTime Length of break in microseconds
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+	LOGTEXT2(_L8("\taTime=%d (microseconds)"), aTime);
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return;
+		}
+
+	iBreak = ETrue;
+	iCancellingBreak = EFalse;
+
+	// Use the time value directly as microseconds are given. We are a USB 
+	// 'device' so the RComm client is always on the device side.
+	TInt err = iAcm->BreakRequest(CBreakController::EDevice,
+		CBreakController::ETiming,
+		TTimeIntervalMicroSeconds32(aTime));
+	LOGTEXT2(_L8("\tBreakRequest = %d"), err);
+	// Note that the break controller may refuse our request if a host-driven 
+	// break is outstanding.
+	if ( err )
+		{
+		LOGTEXT2(_L8("\tcalling BreakCompleted with %d"), err);
+		iBreak = EFalse;
+		BreakCompleted(err);
+		}						
+	}
+
+void CAcmPort::BreakCancel()
+/**
+ * Downcall from C32. Cancel a pending break.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return;
+		}
+	
+	iCancellingBreak = ETrue;
+
+	TInt err = iAcm->BreakRequest(CBreakController::EDevice,
+		CBreakController::EInactive);
+	// Note that the device cannot turn off a break if there's a host-driven 
+	// break in progress.
+	LOGTEXT2(_L8("\tBreakRequest = %d"), err);
+	if ( err )
+		{
+		iCancellingBreak = EFalse;
+		}
+
+	// Whether BreakOff worked or not, reset our flag saying we're no longer 
+	// interested in any subsequent completion anyway.
+	iBreak = EFalse;
+	}
+
+TInt CAcmPort::GetConfig(TDes8& aDes) const
+/**
+ * Downcall from C32. Pass a config request. Only supports V01.
+ *
+ * @param aDes config will be written to this descriptor 
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	if ( aDes.Length() < static_cast<TInt>(sizeof(TCommConfigV01)) )
+		{
+		LOGTEXT(_L8("\t***not supported"));
+		return KErrNotSupported;
+		}
+
+	TCommConfig commConfigPckg;
+	TCommConfigV01& commConfig = commConfigPckg();
+	commConfig = iCommConfig;
+	
+	aDes.Copy(commConfigPckg);
+
+	LOGTEXT2(_L8("\tiCommConfig.iRate = %d"), iCommConfig.iRate);
+	LOGTEXT2(_L8("\tiCommConfig.iDataBits = %d"), iCommConfig.iDataBits);
+	LOGTEXT2(_L8("\tiCommConfig.iStopBits = %d"), iCommConfig.iStopBits);
+	LOGTEXT2(_L8("\tiCommConfig.iParity = %d"), iCommConfig.iParity);
+	LOGTEXT2(_L8("\tiCommConfig.iHandshake = %d"), iCommConfig.iHandshake);
+	LOGTEXT2(_L8("\tiCommConfig.iParityError = %d"), 
+		iCommConfig.iParityError);
+	LOGTEXT2(_L8("\tiCommConfig.iFifo = %d"), iCommConfig.iFifo);
+	LOGTEXT2(_L8("\tiCommConfig.iSpecialRate = %d"), 
+		iCommConfig.iSpecialRate);
+	LOGTEXT2(_L8("\tiCommConfig.iTerminatorCount = %d"), 
+		iCommConfig.iTerminatorCount);
+	LOGTEXT2(_L8("\tiCommConfig.iSIREnable = %d"), iCommConfig.iSIREnable);
+	LOGTEXT2(_L8("\tiCommConfig.iSIRSettings = %d"), 
+		iCommConfig.iSIRSettings);
+
+	return KErrNone;
+	}
+
+TInt CAcmPort::SetConfig(const TDesC8& aDes)
+/**
+ * Downcall from C32. Set config on the port using a TCommConfigV01 package.
+ *
+ * @param aDes descriptor containing the new config
+ * @return Error
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	LOGTEXT4(_L8("\tlength of argument %d, TCommConfigV01 %d, "
+		"TCommConfigV02 %d"), 
+		aDes.Length(), 
+		(TInt)sizeof(TCommConfigV01),
+		(TInt)sizeof(TCommConfigV02));
+
+	if ( aDes.Length() < static_cast<TInt>(sizeof(TCommConfigV01)) )
+		{
+		LOGTEXT(_L8("\t***not supported"));
+		return KErrNotSupported;
+		}
+
+	TCommConfig configPckg;
+	configPckg.Copy(aDes);
+	TCommConfigV01& config = configPckg();
+
+	LOGTEXT2(_L8("\tiCommConfig.iRate = %d"), config.iRate);
+	LOGTEXT2(_L8("\tiCommConfig.iDataBits = %d"), config.iDataBits);
+	LOGTEXT2(_L8("\tiCommConfig.iStopBits = %d"), config.iStopBits);
+	LOGTEXT2(_L8("\tiCommConfig.iParity = %d"), config.iParity);
+	LOGTEXT2(_L8("\tiCommConfig.iHandshake = %d"), config.iHandshake);
+	LOGTEXT2(_L8("\tiCommConfig.iParityError = %d"), config.iParityError);
+	LOGTEXT2(_L8("\tiCommConfig.iFifo = %d"), config.iFifo);
+	LOGTEXT2(_L8("\tiCommConfig.iSpecialRate = %d"), config.iSpecialRate);
+	LOGTEXT2(_L8("\tiCommConfig.iTerminatorCount = %d"), 
+		config.iTerminatorCount);
+	LOGTEXT2(_L8("\tiCommConfig.iSIREnable = %d"), config.iSIREnable);
+	LOGTEXT2(_L8("\tiCommConfig.iSIRSettings = %d"), config.iSIRSettings);
+
+	// Tell the reader object about the new terminators. Pass the whole config 
+	// struct by reference for ease.
+	iReader->SetTerminators(config);
+
+	HandleConfigNotification(config.iRate,
+		config.iDataBits,
+		config.iParity,
+		config.iStopBits,
+		config.iHandshake);
+	iCommConfig = config;
+
+	return KErrNone;
+	}
+
+void CAcmPort::HandleConfigNotification(TBps aRate,
+										TDataBits aDataBits,
+										TParity aParity,
+										TStopBits aStopBits,
+										TUint aHandshake)
+/**
+ * Construct and complete the config notification data structure.
+ * @param aRate 		New data rate
+ * @param aDataBits 	New number of data bits
+ * @param aParity		New parity check setting
+ * @param aStopBits 	New stop bit setting
+ * @param aHandshake	New handshake setting
+ */
+	{
+	LOGTEXT(_L8(">>CAcmPort::HandleConfigNotification"));
+	LOGTEXT2(_L8("\taRate = %d"), aRate);
+	LOGTEXT2(_L8("\taDataBits = %d"), aDataBits);
+	LOGTEXT2(_L8("\taStopBits = %d"), aStopBits);
+	LOGTEXT2(_L8("\taParity = %d"), aParity);
+	LOGTEXT2(_L8("\taHandshake = %d"), aHandshake);
+			
+	iCommNotification.iChangedMembers = 0;
+
+	iCommNotification.iRate = aRate;
+	if ( iCommConfig.iRate != aRate )
+		{
+		iCommNotification.iChangedMembers |= KRateChanged;
+		}
+
+	iCommNotification.iDataBits = aDataBits;
+	if ( iCommConfig.iDataBits != aDataBits )
+		{
+		iCommNotification.iChangedMembers |= KDataFormatChanged;
+		}
+
+	iCommNotification.iParity = aParity;
+	if ( iCommConfig.iParity != aParity )
+		{
+		iCommNotification.iChangedMembers |= KDataFormatChanged;
+		}
+
+	iCommNotification.iStopBits = aStopBits;
+	if ( iCommConfig.iStopBits != aStopBits )
+		{
+		iCommNotification.iChangedMembers |= KDataFormatChanged;
+		}
+
+	iCommNotification.iHandshake = aHandshake;
+	if ( iCommConfig.iHandshake != aHandshake )
+		{
+		iCommNotification.iChangedMembers |= KHandshakeChanged;
+		}
+
+	if ( iCommNotification.iChangedMembers )
+		{
+		LOGTEXT(_L8("\tcalling ConfigChangeCompleted with KErrNone"));
+		ConfigChangeCompleted(iCommNotificationDes,KErrNone);
+		iNotifyConfigChange = EFalse;
+		}
+
+	LOGTEXT(_L8("<<CAcmPort::HandleConfigNotification"));
+	}
+
+TInt CAcmPort::SetServerConfig(const TDesC8& aDes)
+/**
+ * Downcall from C32. Set server config using a TCommServerConfigV01 package.
+ *
+ * @param aDes package with new server configurations
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	if ( aDes.Length() < static_cast<TInt>(sizeof(TCommServerConfigV01)) )
+		{
+		LOGTEXT(_L8("\t***not supported"));
+		return KErrNotSupported;
+		}
+
+	TCommServerConfig serverConfigPckg;
+	serverConfigPckg.Copy(aDes);
+	TCommServerConfigV01& serverConfig = serverConfigPckg();
+
+	if ( serverConfig.iBufFlags != KCommBufferFull )
+		{
+		LOGTEXT(_L8("\t***not supported"));
+		return KErrNotSupported;
+		}
+
+	// Apply the buffer size setting to Rx and Tx buffers. 
+	TInt err = DoSetBufferLengths(serverConfig.iBufSize);
+	if ( err )
+		{
+		// Failure- the buffer lengths will have been left as they were, so 
+		// just return error.
+		LOGTEXT2(_L8("\t***DoSetBufferLengths=%d"), err);
+		return err;
+		}
+
+	// Changed buffer sizes OK. Note that new config.
+	iCommServerConfig = serverConfig;
+	return KErrNone;
+	}
+
+TInt CAcmPort::GetServerConfig(TDes8& aDes)
+/**
+ * Downcall from C32. Get the server configs. Only supports V01.
+ *
+ * @param aDes server configs will be written to this descriptor
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	if ( aDes.Length() < static_cast<TInt>(sizeof(TCommServerConfigV01)) )
+		{
+		LOGTEXT(_L8("\t***not supported"));
+		return KErrNotSupported;
+		}
+
+	TCommServerConfig* serverConfigPckg = 
+		reinterpret_cast<TCommServerConfig*>(&aDes);
+	TCommServerConfigV01& serverConfig = (*serverConfigPckg)();
+
+	serverConfig = iCommServerConfig;
+	return KErrNone;
+	}
+
+TInt CAcmPort::GetCaps(TDes8& aDes)
+/**
+ * Downcall from C32. Get the port's capabilities. Supports V01 and V02. 
+ *
+ * @param aDes caps will be written to this descriptor
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	TCommCaps2 capsPckg;
+	TCommCapsV02& caps = capsPckg();
+
+	switch ( aDes.Length() )
+		{
+	case sizeof(TCommCapsV02):
+		{
+		caps.iNotificationCaps = (KCapsNotification | KNotifyDataAvailableSupported);
+		caps.iRoleCaps = KCapsRoles;
+		caps.iFlowControlCaps = KCapsFlowControl;
+		}
+		// no break is deliberate
+	case sizeof(TCommCapsV01):
+		{
+		caps.iRate = KCapsRate;
+		caps.iDataBits = KCapsDataBits;
+		caps.iStopBits = KCapsStopBits;
+		caps.iParity = KCapsParity;
+		caps.iHandshake = KCapsHandshaking;
+		caps.iSignals = KCapsSignals;
+		caps.iFifo = KCapsFifo;
+		caps.iSIR = KCapsSIR;
+		}
+		break;
+	default:
+		{
+		LOGTEXT(_L8("\t***bad argument"));
+		return KErrArgument;
+		}
+		}
+
+	aDes.Copy(capsPckg.Left(aDes.Length()));
+
+	return KErrNone;
+	}
+
+TInt CAcmPort::GetSignals(TUint& aSignals)
+/**
+ * Downcall from C32. Get the status of the signal pins
+ *
+ * @param aSignals signals will be written to this descriptor
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	aSignals = ConvertSignals(iSignals);
+
+	LOGTEXT3(_L8("iSignals=0x%x, aSignals=0x%x"),
+		iSignals, aSignals);
+	return KErrNone;
+	}
+
+TInt CAcmPort::SetSignalsToMark(TUint aSignals)
+/**
+ * Downcall from C32. Set selected signals to high (logical 1)
+ *
+ * @param aSignals bitmask with the signals to be set
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	TUint32 newSignals = iSignals | ConvertAndFilterSignals(aSignals);
+	TInt err = SetSignals(newSignals);
+	if ( err )
+		{
+		LOGTEXT2(_L8("***SetSignals = %d"), err);
+		return err;
+		}
+
+	LOGTEXT3(_L8("iSignals=0x%x, aSignals=0x%x"),
+		iSignals, aSignals);
+	return KErrNone;
+	}
+
+TInt CAcmPort::SetSignalsToSpace(TUint aSignals)
+/**
+ * Downcall from C32. Set selected signals to low (logical 0)
+ *
+ * @param aSignals bitmask with the signals to be cleared
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	TUint32 newSignals = iSignals & ~ConvertAndFilterSignals(aSignals);
+	TInt err = SetSignals(newSignals);
+	if ( err )
+		{
+		LOGTEXT2(_L8("***SetSignals = %d"), err);
+		return err;
+		}
+
+	LOGTEXT3(_L8("iSignals=0x%x, aSignals=0x%x"),
+		iSignals, aSignals);
+	return KErrNone;
+	}
+
+TInt CAcmPort::SetSignals(TUint32 aNewSignals)
+/**
+ * Handle a request by the client to change signal state. This function pushes 
+ * the change to the host, completes any outstanding notifications, and stores
+ * the new signals in iSignals if there are no errors.
+ *
+ * @param aSignals bitmask with the signals to be set
+ * @return Error.
+ */
+	{
+	LOG_FUNC
+
+	TBool ring =((aNewSignals & KSignalRNG)==KSignalRNG);
+	TBool dsr  =((aNewSignals & KSignalDSR)==KSignalDSR);
+	TBool dcd  =((aNewSignals & KSignalDCD)==KSignalDCD);
+ 
+ 
+ 	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	TInt err = iAcm->SendSerialState(ring,dsr,dcd);
+	if ( err )
+		{
+		LOGTEXT2(_L8("\t***SendSerialState = %d- returning"), err);
+		return err;
+		}
+
+	// Report the new signals if they have changed and notification mask shows
+	// the upper layer wanted to be sensitive to these signals
+	if ( iNotifySignalChange )
+		{
+		TUint32 changedSignals = ( iSignals ^ aNewSignals ) & iNotifySignalMask;
+		if ( changedSignals != 0 )
+			{
+			// Mark which signals have changed
+			// Could do something like:
+			//     changedSignalsMask = ( changedSignals & (KSignalRNG|KSignalDCD|KSignalDSR) ) * KSignalChanged
+			// but this relies on the how the signal constants are formed in d32comm.h
+			TUint32 changedSignalsMask = 0;
+			if ( ( changedSignals & KSignalRNG ) != 0 )
+				{
+				changedSignalsMask |= KRNGChanged;
+				}
+			if ( ( changedSignals & KSignalDCD ) != 0 )
+				{
+				changedSignalsMask |= KDCDChanged;
+				}
+			if ( ( changedSignals & KSignalDSR ) != 0 )
+				{
+				changedSignalsMask |= KDSRChanged;
+				}
+
+			// Report correctly mapped signals that client asked for
+			LOGTEXT(_L8("\tcalling SignalChangeCompleted with KErrNone"));
+			TUint32 signals = ConvertSignals ( changedSignalsMask | ( aNewSignals & iNotifySignalMask ) );
+			SignalChangeCompleted ( signals, KErrNone );
+			iNotifySignalChange = EFalse;
+			}
+		}
+
+	// Store new signals in iSignals
+	iSignals = aNewSignals;
+
+	return KErrNone;
+	}
+
+TUint32 CAcmPort::ConvertAndFilterSignals(TUint32 aSignals) const
+/**
+ * This function maps from signals used for the port's current role
+ * to the DCE signals used internally, filtering out signals that are
+ * inputs for the current role.
+ *
+ * This would be used, for example, to parse the signals specified by the 
+ * client for a "SetSignals" request before storage in the iSignals member 
+ * variable (always DCE).
+ *
+ * @param aSignals Input signals.
+ * @return The signals, with the lines switched round according to the port's 
+ * role.
+ */
+	{
+	LOG_FUNC
+
+	TUint32 signals = 0;
+
+	// note that this never allows the client to use this method
+	// to diddle the BREAK state
+
+	// handle role-specific mapping
+	if ( iRole == ECommRoleDTE )
+		{
+		// Ignore DSR, DCD, RI and CTS as these are DTE inputs.
+
+		// Map DTR to DSR
+		if((aSignals&KSignalDTR)==KSignalDTR)
+			{
+			signals|=KSignalDSR;
+			}
+
+		// Map RTS to CTS
+		if((aSignals&KSignalRTS)==KSignalRTS)
+			{
+			signals|=KSignalCTS;
+			}
+		}
+	else	// iRole==EDce
+		{
+		// Ignore RTS and DTR as these are DCE inputs and therefore cannot be set.
+		// Keep mapping of DSR, CTS, DCD and RI.
+		signals |= aSignals & 
+			(	KSignalDSR
+			|	KSignalCTS
+			|	KSignalDCD
+			|	KSignalRNG);
+		}
+
+	return signals;
+	}
+
+TUint32 CAcmPort::ConvertSignals(TUint32 aSignals) const
+/**
+ * This function converts the given signals between the internal mapping
+ * and the client mapping, taking into account the port's currnt role.
+ * As the mapping is one to one, the input can be either the client or
+ * internal signals.
+ *
+ * This would be used, for example, to parse the signals being sent to the 
+ * client in a "GetSignals" request, or to parse the signals sent from the
+ * client when setting up a notification.
+ *
+ * It should not be used for "SetSignals", as it does not take into account
+ * what signals are inputs or outputs for the current role.
+ *
+ * @param aSignals Input signals (internal or client).
+ * @return Output signals.
+ * port is.
+ */
+	{
+	LOG_FUNC
+
+	// Swap signals around if the client is expecting DTE signalling
+	if ( iRole == ECommRoleDTE )
+		{
+		TUint32 swappedSignals = 0;
+
+		// Map DSR to DTR
+		if ( ( aSignals & KSignalDSR ) == KSignalDSR )
+			{
+			swappedSignals |= KSignalDTR;
+			}
+		if ( ( aSignals & KSignalDTR ) == KSignalDTR )
+			{
+			swappedSignals |= KSignalDSR;
+			}
+		if ( ( aSignals & KDSRChanged ) != 0 )
+			{
+			swappedSignals |= KDTRChanged;
+			}
+		if ( ( aSignals & KDTRChanged ) != 0 )
+			{
+			swappedSignals |= KDSRChanged;
+			}
+
+		// Map CTS to RTS
+		if ( ( aSignals&KSignalCTS ) == KSignalCTS )
+			{
+			swappedSignals|=KSignalRTS;
+			}
+		if ( ( aSignals&KSignalRTS ) == KSignalRTS )
+			{
+			swappedSignals|=KSignalCTS;
+			}
+		if ( ( aSignals & KCTSChanged ) != 0 )
+			{
+			swappedSignals |= KRTSChanged;
+			}
+		if ( ( aSignals & KRTSChanged ) != 0 )
+			{
+			swappedSignals |= KCTSChanged;
+			}
+
+		// Put remapped signals back in
+		const TUint32 KSwapSignals = KSignalDSR | KSignalDTR | KSignalCTS | KSignalRTS
+									| KDSRChanged | KDTRChanged | KCTSChanged | KRTSChanged;
+		aSignals = ( aSignals & ~KSwapSignals ) | swappedSignals;
+		}
+
+	return aSignals;
+	}
+
+TInt CAcmPort::GetReceiveBufferLength(TInt& aLength) const
+/**
+ * Downcall from C32. Get size of Rx buffer. Note that the Rx and Tx 
+ * buffers are assumed by the RComm API to always have the same size. 
+ * We don't check here, but the value returned should be the size of the Tx 
+ * buffer also.
+ *
+ * @param aLength reference to where the length will be written to
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	aLength = static_cast<TInt>(iReader->BufSize());
+	LOGTEXT2(_L8("\tlength=%d"), aLength);
+	return KErrNone;
+	}
+
+TInt CAcmPort::DoSetBufferLengths(TUint aLength)
+/**
+ * Utility to set the sizes of the Rx and Tx buffers. On failure, the buffers 
+ * will be left at the size they were.
+ *
+ * @param aLength The size required.
+ * @return Error.
+ */
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taLength=%d"), aLength);
+
+	__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	// Sart trying to resize buffers. Start with the reader. 
+	// Before we start though, set some stuff up we may need later (see 
+	// comments below).
+	const TUint oldSize = iReader->BufSize();
+	HBufC* dummyBuffer = HBufC::New(static_cast<TInt>(oldSize));
+	if ( !dummyBuffer )
+		{
+		// If we can't allocate the dummy buffer, we can't guarantee that we 
+		// can roll back this API safely if it fails halfway through. So abort 
+		// the entire operation.
+		LOGTEXT(_L8("\t***failed to allocate dummy buffer- "
+			"returning KErrNoMemory"));
+		return KErrNoMemory;
+		}
+
+	TInt ret = iReader->SetBufSize(aLength);
+	if ( ret )
+		{
+		// A failure in SetBufSize will have maintained the old buffer 
+		// (i.e. at its old size). This is a safe failure case- simply 
+		// clean up and return the error to the client.
+		delete dummyBuffer;
+		LOGTEXT2(_L8("\t***SetBufSize on reader failed with %d"), ret);
+		return ret;
+		}
+
+	// OK, the Rx buffer has been resized, now for the Tx buffer...
+	__ASSERT_DEBUG(iWriter, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	ret = iWriter->SetBufSize(aLength);
+	if ( ret )
+		{
+		// Failure! The Tx buffer is still safe, at its old size. However, 
+		// to maintain the integrity of the API we need to reset the Rx 
+		// buffer back to the old size. To make sure that this will work, free 
+		// the dummy buffer we initially allocated.
+		delete dummyBuffer;
+		LOGTEXT2(_L8("\t***SetBufSize on writer failed with %d"), ret);
+		TInt err = iReader->SetBufSize(oldSize);
+		__ASSERT_DEBUG(!err, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		static_cast<void>(err);
+		// Now both buffers are at the size they started at, and the 
+		// request failed with error code 'ret'.
+		return ret;
+		}
+
+	// We seem to have successfully resized both buffers... clean up and 
+	// return.
+	delete dummyBuffer;
+	
+	LOGTEXT(_L8("\treturning KErrNone"));
+	return KErrNone;
+	}
+
+TInt CAcmPort::SetReceiveBufferLength(TInt aLength)
+/**
+ * Downcall from C32. Set the size of Rx buffer. Note that the Rx and Tx 
+ * buffers are assumed by the RComm API to always have the same size. 
+ * Therefore set the size of the Tx buffer also.
+ *
+ * @param aLength new length of Tx and Rx buffer
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+	LOGTEXT2(_L8("\taLength=%d"), aLength);
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	TInt ret = DoSetBufferLengths(static_cast<TUint>(aLength));
+	LOGTEXT2(_L8("\tDoSetBufferLengths=%d"), ret);
+	LOGTEXT2(_L8("\treturning %d"), ret);
+	return ret;
+	}
+
+void CAcmPort::Destruct()
+/**
+ * Downcall from C32. Destruct - we must (eventually) call delete this
+ */
+	{
+	LOG_FUNC
+
+	delete this;
+	}
+
+void CAcmPort::FreeMemory()
+/**
+ * Downcall from C32. Attempt to reduce our memory foot print.
+ * Implemented to do nothing.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+	}
+
+void CAcmPort::NotifyDataAvailable()
+/**
+ * Downcall from C32. Notify client when data is available. 
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		NotifyDataAvailableCompleted(KErrAccessDenied);
+		return;
+		}
+	__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	iReader->NotifyDataAvailable();		
+	}
+
+void CAcmPort::NotifyDataAvailableCancel()
+/**
+ * Downcall from C32. Cancel an outstanding data available notification. Note 
+ * that C32 actually completes the client's request for us.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return;
+		}
+	__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	iReader->NotifyDataAvailableCancel();
+	}
+
+TInt CAcmPort::GetFlowControlStatus(TFlowControl& /*aFlowControl*/)
+/**
+ * Downcall from C32. Get the flow control status. NB This is not supported.
+ *
+ * @param aFlowControl flow control status will be written to this descriptor
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	LOGTEXT(_L8("\t***not supported"));
+	return KErrNotSupported;
+	}
+
+void CAcmPort::NotifyOutputEmpty()
+/**
+ * Downcall from C32. Notify the client when the output buffer is empty. Note 
+ * that this is not supported. Write requests only complete when the data has 
+ * been sent to the LDD (KConfigWriteBufferedComplete is not supported) so 
+ * it's not very useful.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		NotifyOutputEmptyCompleted(KErrAccessDenied);
+		return;
+		}
+
+	LOGTEXT(_L8("\t***not supported"));
+	NotifyOutputEmptyCompleted(KErrNotSupported);
+	}
+
+void CAcmPort::NotifyOutputEmptyCancel()
+/**
+ * Downcall from C32. Cancel a pending request to be notified when the output 
+ * buffer is empty. Note that C32 actually completes the client's request for 
+ * us.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+	}
+
+void CAcmPort::NotifyBreak()
+/**
+ * Downcall from C32. Notify a client of a host-driven break on the serial 
+ * line.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		BreakNotifyCompleted(KErrAccessDenied);
+		return;
+		}
+
+	// C32 protects us against this.
+	__ASSERT_DEBUG(!iNotifyBreak, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	iNotifyBreak = ETrue;
+	}
+
+void CAcmPort::NotifyBreakCancel()
+/**
+ * Downcall from C32. Cancel a pending notification of a serial line break. 
+ * Note that C32 actually completes the client's request for us.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return;
+		}
+
+	iNotifyBreak = EFalse;
+	}
+
+void CAcmPort::BreakRequestCompleted()
+/**
+ * Callback for completion of a break request. 
+ * This is called when the break state next goes inactive after a break has 
+ * been requested from the ACM port. 
+ * This is implemented to complete the RComm client's Break request.
+ */
+ 	{
+	LOG_FUNC
+
+	if ( !iCancellingBreak )
+		{
+		LOGTEXT(_L8("\tcalling BreakCompleted with KErrNone"));
+		BreakCompleted(KErrNone);
+		}
+	else
+		{
+		LOGTEXT(_L8("\tbreak is being cancelled- "
+			"letting C32 complete the request"));
+		}
+	// In the event of an RComm::BreakCancel, this function is called 
+	// sychronously with CAcmPort::BreakCancel, and C32 will complete the 
+	// original RComm::Break request with KErrCancel when that returns. So we 
+	// only need to complete it if there isn't a cancel going on.
+	iBreak = EFalse;
+	iCancellingBreak = EFalse;
+	}
+
+void CAcmPort::BreakStateChange()
+/**
+ * Callback for a change in the break state. 
+ * This is called both when the break state changes because the RComm client 
+ * wanted it to, and when the break state changes because the host asked us 
+ * to.
+ * This is implemented to update our signal line flags, complete 
+ * NotifySignalChange requests, and complete NotifyBreak requests.
+ */
+ 	{
+	LOG_FUNC
+
+	// TODO: what if no iAcm?
+
+	// Take a copy of the current signal state for comparison later
+	TUint32 oldSignals = iSignals;
+
+	// grab the state of the BREAK from the ACM class that manages
+	// it and apply the appropriate flag state to the local iSignals
+	if ( iAcm && iAcm->BreakActive() )
+		{
+		LOGTEXT(_L8("\tbreak is active"));
+		iSignals |= KSignalBreak;
+		}
+	else
+		{
+		LOGTEXT(_L8("\tbreak is inactive"));
+		iSignals &= ~KSignalBreak;
+		}
+
+	// first tell the client (if interested, and if it's not a client-driven 
+	// break) that there has been a BREAK event of some sort (either into or 
+	// out of the break-active condition...
+	if ( iNotifyBreak && !iBreak )
+		{
+		LOGTEXT(_L8("\tcalling BreakNotifyCompleted with KErrNone"));
+		BreakNotifyCompleted(KErrNone);
+		iNotifyBreak = EFalse;
+		}
+
+	// and now tell the client (again if interested) the new state
+	// of the BREAK signal, if it has changed
+	if (	iNotifySignalChange
+		&&	( ( iNotifySignalMask & ( iSignals ^ oldSignals ) ) != 0 ) )
+		{
+		// Report correctly mapped signals that client asked for
+		LOGTEXT(_L8("\tcalling SignalChangeCompleted with KErrNone"));
+		TUint32 signals = ConvertSignals ( KBreakChanged | ( iSignals & iNotifySignalMask ) );
+		SignalChangeCompleted( signals, KErrNone);
+		iNotifySignalChange = EFalse;
+		}
+	}
+
+void CAcmPort::NotifyFlowControlChange()
+/**
+ * Downcall from C32. Notify a client of a change in the flow control state. 
+ * Note that this is not supported.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		FlowControlChangeCompleted(EFlowControlOn, KErrAccessDenied);
+		return;
+		}
+
+	LOGTEXT(_L8("\t***not supported"));
+	FlowControlChangeCompleted(EFlowControlOn,KErrNotSupported);
+	}
+
+void CAcmPort::NotifyFlowControlChangeCancel()
+/**
+ * Downcall from C32. Cancel a pending request to be notified when the flow 
+ * control state changes. Note that C32 actually completes the client's 
+ * request for us.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+	}
+
+void CAcmPort::NotifyConfigChange()
+/**
+ * Downcall from C32. Notify a client of a change to the serial port 
+ * configuration.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		ConfigChangeCompleted(iCommNotificationDes, KErrAccessDenied);
+		return;
+		}
+
+	if ( iNotifyConfigChange )
+		{
+		LOGTEXT(_L8("\t***in use"));
+		ConfigChangeCompleted(iCommNotificationDes,KErrInUse);
+		}
+	else
+		{
+		iNotifyConfigChange = ETrue;
+		}
+	}
+
+void CAcmPort::NotifyConfigChangeCancel()
+/**
+ * Downcall from C32. Cancel a pending request to be notified of a change to 
+ * the serial port configuration. Note that C32 actually completes the 
+ * client's request for us.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return;
+		}
+
+	iNotifyConfigChange = EFalse;
+	}
+
+void CAcmPort::HostConfigChange(const TCommConfigV01& aConfig)
+/**
+ * Callback from a "host-pushed" configuration change packet.
+ *
+ * @param aConfig	New configuration data.
+ */
+	{
+	LOG_FUNC
+
+	HandleConfigNotification(aConfig.iRate,
+		aConfig.iDataBits,
+		aConfig.iParity,
+		aConfig.iStopBits,
+		iCommConfig.iHandshake);
+	iCommConfig.iRate = aConfig.iRate;
+	iCommConfig.iDataBits = aConfig.iDataBits;
+	iCommConfig.iParity = aConfig.iParity;
+	iCommConfig.iStopBits = aConfig.iStopBits;
+	}
+
+void CAcmPort::NotifySignalChange(TUint aSignalMask)
+/**
+ * Downcall from C32. Notify a client of a change to the signal lines.
+ */
+	{
+	LOG_LINE
+	LOGTEXT2(_L8(">>CAcmPort::NotifySignalChange aSignalMask=0x%08x"), 
+		aSignalMask);
+
+	if ( iNotifySignalChange )
+		{
+		if ( !iAcm )
+			{
+			LOGTEXT(_L8("\t***access denied"));
+			SignalChangeCompleted(0, KErrAccessDenied);
+			}
+		else
+			{
+			LOGTEXT(_L8("\t***in use"));
+			SignalChangeCompleted(0, KErrInUse);
+			}
+		}
+	else
+		{
+		iNotifySignalChange = ETrue;
+		// convert signals to internal format
+		// no need to filter as can notify on inputs or outputs
+		iNotifySignalMask = ConvertSignals(aSignalMask);
+		}
+
+	LOGTEXT(_L8("<<CAcmPort::NotifySignalChange"));
+	}
+
+void CAcmPort::NotifySignalChangeCancel()
+/**
+ * Downcall from C32. Cancel a pending client request to be notified about a 
+ * change to the signal lines. Note that C32 actually completes the client's 
+ * request for us.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return;
+		}
+
+	iNotifySignalChange = EFalse;
+	}
+
+void CAcmPort::HostSignalChange(TBool aDtr, TBool aRts)
+/**
+ * Callback from a "host-pushed" line state change.
+ *
+ * @param aDtr The state of the DTR signal.
+ * @param aRts The state of the RTS signal.
+ */
+	{
+	LOGTEXT3(_L8(">>CAcmPort::HostSignalChange aDtr=%d, aRts=%d"), aDtr, aRts);
+
+	// Take a copy of the current signal state for comparison later
+	TUint32 oldSignals = iSignals;
+
+	if ( aDtr )
+		{
+		iSignals |= KSignalDTR;
+		}
+	else
+		{
+		iSignals &= (~KSignalDTR);
+		}
+
+	if ( aRts )
+		{
+		iSignals |= KSignalRTS;
+		}
+	else
+		{
+		iSignals &= (~KSignalRTS);
+		}
+
+	// Report the new state of the signals if they have changed
+	// and the mask shows the upper layer wanted to be sensitive to these signals.
+	if ( iNotifySignalChange )
+		{
+		// Create bitfield of changed signals that client is interested in
+		TUint32 changedSignals = ( iSignals ^ oldSignals ) & iNotifySignalMask;
+		LOGTEXT5(_L8("\tiSignals=%x, oldSignals=%x, changedSignals=%x, iNotifySignalMask=%x")
+						,iSignals, oldSignals, changedSignals, iNotifySignalMask);
+		if ( changedSignals != 0 )
+			{
+			// Mark which signals have changed
+			TUint32 changedSignalsMask = 0;
+			if ( ( changedSignals & KSignalDTR ) != 0 )
+				{
+				changedSignalsMask |= KDTRChanged;
+				}
+			if ( ( changedSignals & KSignalRTS ) != 0 )
+				{
+				changedSignalsMask |= KRTSChanged;
+				}
+			LOGTEXT2(_L8("\tchangedSignalsMask=%x"), changedSignalsMask);
+
+			// Report correctly mapped signals that client asked for
+			TUint32 signals = ConvertSignals ( changedSignalsMask | ( iSignals & iNotifySignalMask ) );
+			LOGTEXT2(_L8("\tcalling SignalChangeCompleted with KErrNone, signals=%x"), signals);
+			SignalChangeCompleted( signals, KErrNone);
+			iNotifySignalChange = EFalse;
+			}
+		}
+
+	LOGTEXT(_L8("<<CAcmPort::HostSignalChange"));
+	}
+
+TInt CAcmPort::GetRole(TCommRole& aRole)
+/**
+ * Downcall from C32. Get the role of this port unit
+ *
+ * @param aRole reference to where the role will be written to
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	if ( !iAcm )
+		{
+		LOGTEXT(_L8("\t***access denied"));
+		return KErrAccessDenied;
+		}
+
+	aRole = iRole;
+	LOGTEXT2(_L8("\trole=%d"), aRole);
+	return KErrNone;
+	}
+
+TInt CAcmPort::SetRole(TCommRole aRole)
+/**
+ * Downcall from C32. Set the role of this port unit
+ *
+ * @param aRole the new role
+ * @return Error.
+ */
+	{
+	LOG_LINE
+	LOGTEXT2(_L8(">>CAcmPort::SetRole aRole=%d"), aRole);
+
+	TInt ret = KErrNone;
+	if ( !iAcm )
+		{
+		ret = KErrAccessDenied;
+		}
+	else
+		{
+		iRole = aRole;
+		}
+
+	LOGTEXT2(_L8("<<CAcmPort::SetRole ret=%d"), ret);
+	return ret;
+	}
+
+void CAcmPort::SetAcm(CCdcAcmClass* aAcm)
+/**
+ * Called by the factory when the ACM interface for this port is about to be 
+ * either created or destroyed. 
+ * If it's going to be destroyed, we must cancel any currently outstanding 
+ * requests on the reader and writer objects, complete any outstanding 
+ * requests with KErrAccessDenied, and refuse any new requests with the same 
+ * error until the registration port is back open again. 
+ * If it's going to be opened, we simply remember it and use it to pass future 
+ * client requests onto the bus.
+ *
+ * @param aAcm The new ACM (may be NULL).
+ */
+	{
+	LOGTEXT3(_L8(">>CAcmPort::SetAcm aAcm = 0x%08x, iAcm = 0x%08x"), aAcm, iAcm);
+	
+	if ( !aAcm )
+		{
+		// Cancel any outstanding operations on the reader and writer.
+		__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		iReader->ReadCancel();
+		__ASSERT_DEBUG(iWriter, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		iWriter->WriteCancel();
+
+		// Complete any outstanding requests
+		LOGTEXT(_L8("\tcompleting outstanding requests with KErrAccessDenied"));
+		SignalChangeCompleted(iSignals,KErrAccessDenied);
+		ReadCompleted(KErrAccessDenied);
+		WriteCompleted(KErrAccessDenied);
+		ConfigChangeCompleted(iCommNotificationDes,KErrAccessDenied);
+		NotifyDataAvailableCompleted(KErrAccessDenied);
+		NotifyOutputEmptyCompleted(KErrAccessDenied);
+		BreakNotifyCompleted(KErrAccessDenied);
+		FlowControlChangeCompleted(EFlowControlOn, KErrAccessDenied);
+		}
+	else
+		{
+		__ASSERT_DEBUG(!iAcm, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		aAcm->SetCallback(this);
+		// Set the port as the observer of break events.
+		aAcm->SetBreakCallback(this);
+		}
+
+	iAcm = aAcm;
+	
+	LOGTEXT(_L8("<<CAcmPort::SetAcm"));
+	}
+
+CAcmPort::~CAcmPort()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	delete iReader;
+	delete iWriter;
+	
+	// Remove this as a sink for the ACM class to call back about host-pushed 
+	// changes.
+	if ( iAcm )
+		{
+		LOGTEXT(_L8("\tiAcm exists- calling SetCallback(NULL)"));
+		iAcm->SetCallback(NULL);
+		}
+
+	LOGTEXT(_L8("\tcalling AcmPortClosed on observer"));
+	iObserver.AcmPortClosed(iUnit);
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/AcmPortFactory.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,429 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include "AcmPortFactory.h"
+#include "AcmUtils.h"
+#include <acminterface.h>
+#include "AcmPort.h"
+#include "AcmPanic.h"
+#include "acmserver.h"
+#include "CdcAcmClass.h"
+#include <usb/usblogger.h>
+#include "c32comm_internal.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+// Do not move this into a header file. It must be kept private to the CSY. It 
+// is the secret information that enables the old (registration port) 
+// mechanism allowing the USB Manager to set up ACM interfaces.
+const TUint KRegistrationPortUnit = 666;
+
+CAcmPortFactory* CAcmPortFactory::NewL()
+/**
+ * Make a new CAcmPortFactory
+ *
+ * @return Ownership of a newly created CAcmPortFactory object
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CAcmPortFactory* self = new(ELeave) CAcmPortFactory;
+	CleanupClosePushL(*self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+	
+CAcmPortFactory::CAcmPortFactory()
+/**
+ * Constructor.
+ */
+	{
+	iVersion = TVersion(
+		KEC32MajorVersionNumber, 
+		KEC32MinorVersionNumber, 
+		KEC32BuildVersionNumber);
+	iConfigBuf().iAcmConfigVersion = 1;
+	iOwned = EFalse;
+	}
+
+void CAcmPortFactory::ConstructL()
+/**
+ * Second phase constructor.
+ */
+	{
+	LEAVEIFERRORL(SetName(&KAcmSerialName)); 
+	iAcmServer = CAcmServer::NewL(*this);
+	
+	TInt err = RProperty::Define(KUidSystemCategory, KAcmKey, RProperty::EByteArray, TPublishedAcmConfigs::KAcmMaxFunctions);
+	if(err == KErrAlreadyExists)
+		{	
+		LEAVEIFERRORL(iAcmProperty.Attach(KUidSystemCategory, KAcmKey, EOwnerThread));
+		//Since the P&S data already exists we need to retrieve it
+		LEAVEIFERRORL(iAcmProperty.Get(iConfigBuf));
+		}
+	else if(err == KErrNone)
+		{
+		//A blank iConfigBuf already exists at this point to we don't need to do anything to it
+		//before publishing the P&S data
+		LEAVEIFERRORL(iAcmProperty.Attach(KUidSystemCategory, KAcmKey, EOwnerThread));
+		PublishAcmConfig();
+		iOwned = ETrue;
+		}
+	else
+		{
+		LEAVEIFERRORL(err); //This will always leave, but a log will be created at least.	
+		}
+		
+	}
+
+/**
+ * Utility function for publishing the TPublishedAcmConfigs data
+ * @pre Requires iAcmProperty to be attached before it is called
+ */
+void CAcmPortFactory::PublishAcmConfig()
+	{
+	// Update the publish and subscribe info
+	TInt err = iAcmProperty.Set(iConfigBuf);
+	__ASSERT_DEBUG(err == KErrNone, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	(void)err;
+	}
+
+TSecurityPolicy CAcmPortFactory::PortPlatSecCapability (TUint aPort) const
+/**
+ * Called by C32 when it needs to check the capabilities of a client against the 
+ * capabilites required to perform C32 defered operations on this port, aPort. 
+ *
+ * @param aPort The number of the port.
+ * @return a security policy
+ */
+	//return the security policy for the given port number, aPort.  
+	{
+	LOG_FUNC
+	
+	TSecurityPolicy securityPolicy; 
+	if ( aPort == KRegistrationPortUnit ) 
+		{
+		securityPolicy = TSecurityPolicy(ECapabilityNetworkControl);
+		}
+	else
+		{
+		securityPolicy = TSecurityPolicy(ECapabilityLocalServices);	
+		}
+	return securityPolicy;	 	
+	}
+
+void CAcmPortFactory::AcmPortClosed(const TUint aUnit)
+/**
+ * Called by an ACM port when it is closed. 
+ *
+ * @param aUnit The port number of the closing port.
+ */
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taUnit = %d"), aUnit);
+
+	// I would assert that the calling port is stored in our array, but if we 
+	// ran out of memory during CAcmPort::NewL, this function would be called 
+	// from the port's destructor, but the slot in the port array would still 
+	// be NULL. 
+
+	// Reset the slot in our array of ports. 
+	const TUint index = aUnit - KAcmLowUnit;
+	iAcmPortArray[index] = NULL;
+
+#ifdef _DEBUG
+	LogPortsAndFunctions();
+#endif
+	}
+
+CAcmPortFactory::~CAcmPortFactory()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	// Delete ACM instances. We could assert that the ACM Class Controller has 
+	// caused them all to be destroyed, but if we do that, and USBSVR panics 
+	// while it's Started, it will result in C32 panicking too, which is 
+	// undesirable. TODO: I'm not sure about this philosophy. 
+	iAcmClassArray.ResetAndDestroy();
+
+	// We don't need to clean this array up because C32 will not shut us down 
+	// while ports are still open on us.
+	iAcmPortArray.Close();
+	
+	// Detach the local handles
+	iAcmProperty.Close();
+
+	// Remove the RProperty entries if they are owned by this instance of the PortFactory
+	if(iOwned)
+		{
+		RProperty::Delete(KUidSystemCategory, KAcmKey);		
+		}
+	
+	delete iAcmServer;
+	}
+
+CPort* CAcmPortFactory::NewPortL(const TUint aUnit)
+/**
+ * Downcall from C32. Create a new port for the supplied unit number.
+ *
+ * @param aUnit Port unit number
+ */
+	{
+	LOG_LINE
+	LOGTEXT2(_L8(">>CAcmPortFactory::NewPortL aUnit=%d"), aUnit);
+
+	CPort* port = NULL;
+
+	TUint lowerLimit = KAcmLowUnit; // This non-const TUint avoids compiler remarks (low-level warnings) for the following comparisons..
+	// ACM ports
+	if ( (aUnit >= lowerLimit) && aUnit < static_cast<TUint>( iAcmClassArray.Count()) + KAcmLowUnit)
+		{
+		// Can only create an ACM port if the corresponding ACM interface 
+		// itself has been created. We keep the slots in the  iAcmClassArray array 
+		// up-to-date with how many ACM interface instances have been created.
+		const TUint index = aUnit - KAcmLowUnit;
+		if ( iAcmPortArray[index] )
+			{
+			LEAVEIFERRORL(KErrInUse); // TODO: is this ever executed?
+			}						   
+		iAcmPortArray[index] = CAcmPort::NewL(aUnit, *this);
+		iAcmPortArray[index]->SetAcm( iAcmClassArray[index]);
+		port = iAcmPortArray[index];		
+		}
+	// Registration port
+	else if ( aUnit == KRegistrationPortUnit )
+		{
+		port = CRegistrationPort::NewL(*this, KRegistrationPortUnit);
+		}
+	else 
+		{
+		LEAVEIFERRORL(KErrAccessDenied);
+		}
+
+#ifdef _DEBUG
+	LogPortsAndFunctions();
+#endif
+
+	LOGTEXT2(_L8("<<CAcmPortFactory::NewPortL port=0x%08x"), port);
+	return port;
+	}
+
+void CAcmPortFactory::DestroyFunctions(const TUint aNoAcms)
+/**
+ * Utility to delete ACM functions in the array. Deletes ACM functions and 
+ * resizes the ACM array down. Also tells each of the affected ACM ports that 
+ * its function has gone down.
+ *
+ * @param aNoAcms Number of ACM interfaces to destroy.
+ */
+	{
+	LOGTEXT2(_L8(">>CAcmPortFactory::DestroyFunctions aNoAcms = %d"), aNoAcms);
+
+#ifdef _DEBUG
+	CheckAcmArray();
+#endif
+
+	for ( TUint ii = 0 ; ii < aNoAcms ; ii++ )
+		{
+		const TUint index =  iAcmClassArray.Count() - 1;
+		
+		// Inform the relevant ACM ports, if any, so they can complete 
+		// outstanding requests. NB The ACM port array should have been padded 
+		// up adequately, but not necessarily filled with ports.
+		if ( iAcmPortArray[index] )
+			{
+			iAcmPortArray[index]->SetAcm(NULL);
+			// Don't remove slots from the ACM port array, because higher-
+			// indexed ports might still be open.
+			}
+
+		// Destroy ACM interface.
+		delete iAcmClassArray[index];
+		iAcmClassArray.Remove(index);	
+		}
+		
+	//decrement the published configurations counter
+	iConfigBuf().iAcmCount -= aNoAcms;
+	PublishAcmConfig();
+	
+#ifdef _DEBUG
+	CheckAcmArray();
+	LogPortsAndFunctions();
+#endif
+
+	LOGTEXT(_L8("<<CAcmPortFactory::DestroyFunctions"));
+	}
+
+void CAcmPortFactory::CheckAcmArray()
+/**
+ * Utility to check that each slot in the ACM interface array points to 
+ * something valid. NB It is the ACM port array which may contain empty slots.
+ */
+	{
+	LOG_FUNC
+
+	for ( TUint ii  = 0; ii < static_cast<TUint>( iAcmClassArray.Count()) ; ii++ )
+		{
+		__ASSERT_DEBUG( iAcmClassArray[ii], _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		}
+	}
+
+TInt CAcmPortFactory::CreateFunctions(const TUint aNoAcms, const TUint8 aProtocolNum, const TDesC16& aAcmControlIfcName, const TDesC16& aAcmDataIfcName)
+/**
+ * Tries to create the ACM functions.
+ * 
+ * @param aNoAcms Number of ACM functions to create.
+ * @param aProtocolNum Protocol setting to use for these ACM functions.
+ * @param aAcmControlIfcName Control Interface Name or a null descriptor
+ * @param aAcmDataIfcName Data Interface Name or a null descriptor
+ */
+	{
+	LOGTEXT5(_L("\taNoAcms = %d, aProtocolNum = %d, Control Ifc Name = %S, Data Ifc Name = %S"),
+			aNoAcms, aProtocolNum, &aAcmControlIfcName, &aAcmDataIfcName);
+
+#ifdef _DEBUG
+	CheckAcmArray();
+#endif
+
+	TInt ret = KErrNone;
+
+	// Create the ACM class instances.
+	for ( TUint ii = 0 ; ii < aNoAcms ; ii++ )
+		{
+		LOGTEXT2(_L8("\tabout to create ACM instance %d"), ii);
+		TRAP(ret, CreateFunctionL(aProtocolNum, aAcmControlIfcName, aAcmDataIfcName));
+		if ( ret != KErrNone )
+			{
+			// Destroy the most recent ACMs that _did_ get created.
+			DestroyFunctions(ii);
+			break;
+			}
+		}
+
+	// all the ACM Functions should now have been created. publish the data
+	PublishAcmConfig();
+
+#ifdef _DEBUG
+	CheckAcmArray();
+	LogPortsAndFunctions();
+#endif
+
+	LOGTEXT2(_L8("<<CAcmPortFactory::CreateFunctions ret = %d"), ret);
+	return ret;
+	}
+
+void CAcmPortFactory::CreateFunctionL(const TUint8 aProtocolNum, const TDesC16& aAcmControlIfcName, const TDesC16& aAcmDataIfcName)
+/**
+ * Creates a single ACM function, appending it to the  iAcmClassArray array.
+ */
+	{
+	LOG_FUNC
+
+	LOGTEXT3(_L8("\tiAcmPortArray.Count() = %d,  iAcmClassArray.Count() = %d"), 
+		iAcmPortArray.Count(),  iAcmClassArray.Count());
+
+	LOGTEXT4(_L("\taProtocolNum = %d, Control Ifc Name = %S, Data Ifc Name = %S"),
+			aProtocolNum, &aAcmControlIfcName, &aAcmDataIfcName);
+
+	CCdcAcmClass* acm = CCdcAcmClass::NewL(aProtocolNum, aAcmControlIfcName, aAcmDataIfcName);
+	CleanupStack::PushL(acm);
+
+	// If there isn't already a slot in the ACM port array corresponding to 
+	// this ACM interface instance, create one. 
+	if ( iAcmPortArray.Count() <  iAcmClassArray.Count() + 1 )
+		{
+		LOGTEXT(_L8("\tappending a slot to the ACM port array"));
+		LEAVEIFERRORL(iAcmPortArray.Append(NULL));
+		}
+
+	LEAVEIFERRORL(iAcmClassArray.Append(acm));
+	CleanupStack::Pop(acm);
+	
+	// If there's an ACM port at the relevant index (held open from when USB 
+	// was previously Started, perhaps) then tell it about its new ACM 
+	// interface.
+	if ( iAcmPortArray[iAcmClassArray.Count() - 1] )
+		{
+		LOGTEXT3(_L8("\tinforming CAcmPort instance %d of acm 0x%08x"),  iAcmClassArray.Count() - 1, acm);
+		iAcmPortArray[iAcmClassArray.Count() - 1]->SetAcm(acm);
+		}
+ 
+	// update the TPublishedAcmConfig with the current details
+	iConfigBuf().iAcmConfig[iConfigBuf().iAcmCount].iProtocol = aProtocolNum;
+	iConfigBuf().iAcmCount++;
+	//don't update the p&s data here, do it in CreateFunctions after the construction of 
+	//all the requested functions
+	}
+
+void CAcmPortFactory::Info(TSerialInfo& aSerialInfo)
+/**
+ * Get info about this CSY, fill in the supplied structure.
+ *
+ * @param aSerialInfo where info will be written to
+ */
+	{
+	// NB Our TSerialInfo does not advertise the existence of the registration 
+	// port.
+	LOG_FUNC
+
+	_LIT(KSerialDescription, "USB Serial Port Emulation via ACM");	
+	aSerialInfo.iDescription = KSerialDescription;
+	aSerialInfo.iName = KAcmSerialName;
+	aSerialInfo.iLowUnit = KAcmLowUnit;
+	aSerialInfo.iHighUnit = (iAcmPortArray.Count()==0) ? 0 : (iAcmPortArray.Count()-1);
+	// See comments in AcmInterface.h 
+	}
+
+void CAcmPortFactory::LogPortsAndFunctions()
+/**
+ * Utility to log in a tabular form all the ACM function instances and any 
+ * associated ports. 
+ * The number of ACM functions listed is the number we have been asked to 
+ * make which we have made successfully. All the ACM 
+ * functions listed should be pointing somewhere (enforced by CheckAcmArray). 
+ * Any or all of the ACM ports may be NULL, indicating simply that the client 
+ * side hasn't opened an RComm on that ACM port yet. 
+ * It may also be the case that there are more ACM port slots than there are 
+ * ACM functions slots. This just means that USB is in a more 'Stopped' state 
+ * than it has been in the past- the ports in these slots may still be open, 
+ * so the ACM port array must retain slots for them.
+ * All this is just so the logging gives a clear picture of the functions and 
+ * port open/closed history of the CSY.
+ */
+	{
+	TUint ii;
+
+	// Log ACM functions and corresponding ports.
+	for ( ii = 0 ; ii < static_cast<TUint>( iAcmClassArray.Count()) ; ii++ )
+		{
+		LOGTEXT5(_L8("\t iAcmClassArray[%d] = 0x%08x, iAcmPortArray[%d] = 0x%08x"), ii,  iAcmClassArray[ii], ii, iAcmPortArray[ii]);
+		}
+	// Log any ports extending beyond where we currently have ACM interfaces.
+	for ( ; ii < static_cast<TUint>(iAcmPortArray.Count()) ; ii++ )
+		{
+		LOGTEXT4(_L8("\t iAcmClassArray[%d] = <no slot>, iAcmPortArray[%d] = 0x%08x"), ii, ii, iAcmPortArray[ii]);
+		}
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/AcmReader.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,870 @@
+/*
+* Copyright (c) 2003-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:
+*
+*/
+
+#include <cs_port.h>
+#include "AcmReader.h"
+#include "AcmUtils.h"
+#include "ActiveReader.h"
+#include "ActiveReadOneOrMoreReader.h"
+#include "CdcAcmClass.h"
+#include "AcmPanic.h"
+#include "AcmPort.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CAcmReader* CAcmReader::NewL(CAcmPort& aPort,
+							 TUint aBufSize)
+/**
+ * Factory function.
+ *
+ * @param aPort The CAcmPort parent.
+ * @param aBufSize The size of the buffer.
+ * @return Ownership of a new CAcmReader.
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CAcmReader* self = new(ELeave) CAcmReader(aPort, aBufSize);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CLEANUPSTACK_POP(self);
+	return self;
+	}
+
+CAcmReader::~CAcmReader()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	ReadCancel();
+	
+	delete iBuffer;
+	}
+
+CAcmReader::CAcmReader(CAcmPort& aPort,
+					   TUint aBufSize)
+/**
+ * Constructor.
+ *
+ * @param aPort The CPort parent.
+ * @param aBufSize The size of the buffer.
+ */
+ :	iBufSize(aBufSize),
+	iInBuf(NULL,0,0),
+	iPort(aPort)
+	{
+	}
+
+void CAcmReader::ConstructL()
+/**
+ * 2nd-phase construction.
+ */
+	{
+	// Create iBuffer. 
+	LOGTEXT(_L8("\tabout to create iBuffer"));
+	LEAVEIFERRORL(SetBufSize(iBufSize));
+	}
+
+void CAcmReader::Read(const TAny* aClientBuffer, TUint aMaxLen)
+/**
+ * Read API.
+ *
+ * @param aClientBuffer Pointer to the client's memory space.
+ * @param aMaxLen Maximum length to read.
+ */
+	{
+	LOG_FUNC
+	LOGTEXT3(_L8("\taClientBuffer=0x%08x, aMaxLen=%d"), 
+		aClientBuffer, aMaxLen);
+
+	// Check we're open to requests and make a note of interesting data.
+	// including iLengthToGo
+	CheckNewRequest(aClientBuffer, aMaxLen);
+	iCurrentRequest.iRequestType = ERead;
+
+	// A read larger than our internal buffer limit will result in us doing
+	// multiple reads to the ports below. 
+	// We used to just refuse the request with a KErrNoMemory.
+	if ( iTerminatorCount == 0 )
+		{
+		ReadWithoutTerminators();
+		}
+	else
+		{
+		ReadWithTerminators();
+		}
+	}
+
+void CAcmReader::ReadWithoutTerminators()
+/**
+ * Process a read request given that no terminator characters are set.
+ */
+	{
+	LOG_FUNC
+	
+	// Can we complete immediately from the buffer?
+	const TUint bufLen = BufLen();
+	LOGTEXT2(_L8("\thave %d bytes in buffer"), bufLen);
+	LOGTEXT2(_L8("\tLength to go is %d bytes"), iLengthToGo);
+	if ( iLengthToGo <= bufLen )
+		{
+		LOGTEXT2(_L8("\tcompleting request immediately from buffer with %d "
+			"bytes"), iLengthToGo);
+		WriteBackData(iLengthToGo);
+		CompleteRequest(KErrNone);
+		return;
+		}
+
+	// There isn't enough in the buffer to complete the request, so we write 
+	// back as much as we have, and issue a Read for more.
+	if ( bufLen )
+		{
+		LOGTEXT2(_L8("\twriting back %d bytes"), bufLen);
+		// Write back as much data as we've got already.
+		WriteBackData(bufLen);
+		}
+
+	// Issue a read for the data we still need. 
+	LOGTEXT2(_L8("\tRequesting read - require %d bytes"),iLengthToGo);
+	IssueRead();
+	}
+
+void CAcmReader::ReadWithTerminators()
+/**
+ * Process a read request given that terminator characters are set.
+ */
+	{
+	LOG_FUNC
+
+	// Can we complete immediately from the buffer? Search the buffer we have 
+	// for any terminators. If found, complete back to the client. If not 
+	// found, start issuing ReadOneOrMores until we either find one or run out 
+	// of client buffer.
+
+	const TUint bufLen = BufLen();
+	LOGTEXT2(_L8("\tbufLen = %d"), bufLen);
+	if ( bufLen )
+		{
+		CheckForBufferedTerminatorsAndProceed();
+		return;
+		}
+
+	// There's no buffered data. Get some.
+	IssueReadOneOrMore();
+	}
+
+void CAcmReader::ReadOneOrMore(const TAny* aClientBuffer, TUint aMaxLen)
+/**
+ * ReadOneOrMore API. Note that this is implemented to completely ignore 
+ * terminator characters.
+ *
+ * @param aClientBuffer Pointer to the client's memory space.
+ * @param aMaxLen Maximum length to read.
+ */
+	{
+	LOG_FUNC
+	LOGTEXT3(_L8("\taClientBuffer=0x%08x, aMaxLen=%d"), 
+		aClientBuffer, aMaxLen);
+
+	// Check we're open to requests and make a note of interesting data.
+	CheckNewRequest(aClientBuffer, aMaxLen);
+
+	iCurrentRequest.iRequestType = EReadOneOrMore;	
+	
+	// Check to see if there's anything in our buffer- if there is, we can 
+	// complete immediately.
+	const TUint bufLen = BufLen();
+	LOGTEXT2(_L8("\tbufLen = %d"), bufLen);
+	if ( bufLen )
+		{
+		// Complete request with what's in the buffer
+		LOGTEXT2(_L8("\tcompleting request immediately from buffer with %d "
+			"bytes"), bufLen);
+		WriteBackData(bufLen);
+		CompleteRequest(KErrNone);
+		return;
+		}
+
+	// Get some more data.
+	IssueReadOneOrMore();
+	}
+
+void CAcmReader::NotifyDataAvailable()
+/** 
+ * NotifyDataAvailable API. If a request is pending completes the client with KErrInUse.
+ */
+	{
+	LOG_FUNC
+	if(iCurrentRequest.iClientPtr) // a request is pending
+		{
+		iPort.NotifyDataAvailableCompleted(KErrInUse);
+		return;
+		}
+	iCurrentRequest.iClientPtr = iBuffer;
+	iCurrentRequest.iRequestType = ENotifyDataAvailable;	 	
+	iPort.Acm()->NotifyDataAvailable(*this);		
+	} 
+		
+void CAcmReader::NotifyDataAvailableCancel()
+/**
+ * NotifyDataAvailableCancel API. Issues a ReadCancel() to abort pending requests on the LDD  
+ *
+ */
+	{
+	LOG_FUNC	
+	if (ENotifyDataAvailable == iCurrentRequest.iRequestType)
+		{
+		// Cancel any outstanding request on the LDD.		
+		if (iPort.Acm())
+			{
+			LOGTEXT(_L8("\tiPort.Acm() exists- calling NotifyDataAvailableCancel() on it"));
+			iPort.Acm()->NotifyDataAvailableCancel();
+			}
+		// Reset our flag to say there's no current outstanding request. What's 
+		// already in our buffer can stay there.
+		iCurrentRequest.iClientPtr = NULL;
+		}	
+	}
+
+void CAcmReader::ReadCancel()
+/**
+ * Cancel API. Cancels any outstanding (Read or ReadOneOrMore) request.
+ */
+	{
+	LOG_FUNC
+
+	if (ENotifyDataAvailable != iCurrentRequest.iRequestType)
+		{
+		// Cancel any outstanding request on the LDD.
+		if (iPort.Acm())
+			{
+			LOGTEXT(_L8("\tiPort.Acm() exists- calling ReadCancel on it"));
+			iPort.Acm()->ReadCancel();
+			}
+		
+		// Reset our flag to say there's no current outstanding request. What's 
+		// already in our buffer can stay there.
+		iCurrentRequest.iClientPtr = NULL;
+		}
+	}
+	
+TUint CAcmReader::BufLen() const
+/**
+ * This function returns the amount of data (in bytes) still remaining in the 
+ * circular buffer.
+ *
+ * @return Length of data in buffer.
+ */
+	{
+	LOGTEXT(_L8(">>CAcmReader::BufLen"));
+
+	TUint len = 0;
+	if ( BufWrap() )
+		{
+		LOGTEXT(_L8("\tbuf wrapped"));
+		len = iBufSize - ( iOutPtr - iInPtr );
+		}
+	else
+		{
+		LOGTEXT(_L8("\tbuf not wrapped"));
+		len = iInPtr - iOutPtr;
+		}
+
+	LOGTEXT2(_L8("<<CAcmReader::BufLen len=%d"), len);
+	return len;
+	}
+
+void CAcmReader::ResetBuffer()
+/**
+ * Called by the port to clear the buffer.
+ */
+	{
+	LOG_FUNC
+
+	// A request is outstanding- C32 should protect against this.
+	__ASSERT_DEBUG(!iCurrentRequest.iClientPtr, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	// Reset the pointers. All data is 'lost'.
+	iOutPtr = iInPtr = iBufStart;
+	}
+
+TInt CAcmReader::SetBufSize(TUint aSize)
+/**
+ * Called by the port to set the buffer size. Also used as a utility by us to 
+ * create the buffer at instantiation. Note that this causes what was in the 
+ * buffer at the time to be lost.
+ *
+ * @param aSize The required size of the buffer.
+ */
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taSize=%d"), aSize);
+
+	if ( iCurrentRequest.iClientPtr )
+		{
+		// A request is outstanding. C32 does not protect us against this.
+		LOGTEXT(_L8("\t***a request is outstanding- returning KErrInUse"));
+		return KErrInUse;
+		}
+
+	// Create the new buffer.
+	HBufC8* newBuf = HBufC8::New(aSize);
+	if ( !newBuf )
+		{
+		LOGTEXT(_L8("\tfailed to create new buffer- returning KErrNoMemory"));
+		return KErrNoMemory;
+		}
+	delete iBuffer;
+	iBuffer = newBuf;
+
+	// Update pointers etc.
+	TPtr8 ptr = iBuffer->Des();
+	iBufStart = const_cast<TUint8*>(reinterpret_cast<const TUint8*>(ptr.Ptr()));
+	iBufSize = aSize;
+	CheckBufferEmptyAndResetPtrs();
+
+	return KErrNone;
+	}
+
+void CAcmReader::SetTerminators(const TCommConfigV01& aConfig)
+/**
+ * API to change the terminator characters.
+ *
+ * @param aConfig The new configuration.
+ */
+	{
+	LOG_FUNC
+	
+	// C32 protects the port against having config set while there's a request 
+	// outstanding.
+	__ASSERT_DEBUG(!iCurrentRequest.iClientPtr, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	iTerminatorCount = aConfig.iTerminatorCount;
+	LOGTEXT2(_L8("\tnow %d terminators:"), iTerminatorCount);
+	for ( TUint ii = 0; ii < static_cast<TUint>(KConfigMaxTerminators) ; ii++ )
+		{
+		iTerminator[ii] = aConfig.iTerminator[ii];
+		LOGTEXT2(_L8("\t\t%d"), iTerminator[ii]);
+		}
+	}
+	
+void CAcmReader::ReadCompleted(TInt aError)
+/**
+ * Called by lower classes when an LDD Read completes. 
+ *
+ * @param aError Error.
+ */
+	{
+	LOGTEXT2(_L8(">>CAcmReader::ReadCompleted aError=%d"), aError);						   	
+
+	const TUint justRead = static_cast<TUint>(iInBuf.Length());
+	LOGTEXT3(_L8("\tiInBuf length=%d, iLengthToGo=%d"), 
+		justRead,
+		iLengthToGo);
+
+	// This protects against a regression in the LDD- read requests shouldn't 
+	// ever complete with zero bytes and KErrNone.
+	if ( justRead == 0 && aError == KErrNone )
+		{
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError);
+		}
+
+	// The new data will have been added to our buffer. Move iInPtr up by the 
+	// length just read.
+	iInPtr += justRead;
+
+	if ( aError )
+		{
+		// If the read failed, we complete back to the client and don't do 
+		// anything more. (We don't want to get into retry strategies.) In a 
+		// multi-stage Read the client will get any data already written back 
+		// to them with IPCWrite.
+		CompleteRequest(aError);
+		return;
+		}
+
+	// calling this will write the data to the clients address space
+	// it will also complete the request if we've given the client enough data
+	// or will reissue another read if not
+	ReadWithoutTerminators();
+	
+	LOGTEXT(_L8("<<CAcmReader::ReadCompleted"));
+	}
+
+void CAcmReader::ReadOneOrMoreCompleted(TInt aError)
+/**
+ * Called by lower classes when an LDD ReadOneOrMore completes. 
+ *
+ * @param aError Error.
+ */
+	{
+	LOGTEXT2(_L8(">>CAcmReader::ReadOneOrMoreCompleted aError=%d"), aError);						   	
+
+	const TUint justRead = static_cast<TUint>(iInBuf.Length());
+	LOGTEXT2(_L8("\tjustRead = %d"), justRead);
+
+	// The new data will have been added to our buffer. Move iInPtr 
+	// up by the length just read.
+	iInPtr += justRead;
+
+	if ( aError )
+		{
+		// If the ReadOneOrMore failed, we complete back to the client and 
+		// don't do anything more. The client will get any data already 
+		// written back to them with IPCWrite.
+		CompleteRequest(aError);
+		return;
+		}
+
+	// TODO: may the LDD complete ROOM with zero bytes, eg if a ZLP comes in?
+	// NB The LDD is at liberty to complete a ReadPacket request with zero 
+	// bytes and KErrNone, if the given packet was zero-length (a ZLP). In 
+	// this case, we have to reissue the packet read until we do get some 
+	// data. 
+	if ( justRead == 0 )
+		{
+		LOGTEXT(_L8("\twe appear to have a ZLP- reissuing ReadOneOrMore"));
+		IssueReadOneOrMore();
+		return;
+		}
+
+	if ( EReadOneOrMore == iCurrentRequest.iRequestType )
+		{
+		// Complete the client's request with as much data as we can. NB 
+		// Opinion may be divided over whether to do this, or complete with 
+		// just 1 byte. We implement the more generous approach.
+		LOGTEXT2(_L8("\tcurrent request is ReadOneOrMore- completing with "
+			"%d bytes"), justRead);
+		WriteBackData(justRead);
+		CompleteRequest(KErrNone);
+		}
+	else
+		{
+		// Outstanding request is a Read with terminators. (Except for 
+		// ReadOneOrMore, we only request LDD::ReadOneOrMore in this case.)
+
+		// Process the buffer for terminators. 
+		LOGTEXT(_L8("\tcurrent request is Read with terminators"));
+		CheckForBufferedTerminatorsAndProceed();
+		}
+
+	LOGTEXT(_L8("<<CAcmReader::ReadOneOrMoreCompleted"));
+	}
+
+void CAcmReader::NotifyDataAvailableCompleted(TInt aError)
+	{
+/**
+ * Called by lower classes when data has arrived at the LDD after a 
+ * NotifyDataAvailable request has been posted on the port. 
+ *
+ * @param aError Error.
+ */
+	LOGTEXT2(_L8(">>CAcmReader::NotifyDataAvailableCompleted aError=%d"), aError);	
+		
+	// If the NotifyDataAvailable request failed, we complete back 
+	// to the client and don't do anything more.
+	CompleteRequest(aError);		
+	
+	LOGTEXT(_L8("<<CAcmReader::NotifyDataAvailableCompleted"));	
+	}
+
+void CAcmReader::CheckBufferEmptyAndResetPtrs()
+/**
+ * Utility to assert that the buffer is empty and to reset the read and write 
+ * pointers to the beginning of the buffer. We reset them there to cut down on 
+ * fiddling around wrapping at the end of the buffer.
+ */
+	{
+	LOGTEXT(_L8("CAcmReader::CheckBufferEmptyAndResetPtrs"));
+
+	if ( BufLen() != 0 )
+		{
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError);
+		}
+
+	iOutPtr = iInPtr = iBufStart;
+	}
+
+void CAcmReader::CheckNewRequest(const TAny* aClientBuffer, TUint aMaxLen)
+/**
+ * Utility function to check a Read or ReadOneOrMore request from the port. 
+ * Also checks that there isn't a request already outstanding. Makes a note of 
+ * the relevant parameters and sets up internal counters.
+ *
+ * @param aClientBuffer Pointer to the client's memory space.
+ * @param aMaxLen Maximum length to read.
+ */
+	{
+	// The port should handle zero-length reads, not us.
+	__ASSERT_DEBUG(aMaxLen > 0, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	__ASSERT_DEBUG(aMaxLen <= static_cast<TUint>(KMaxTInt), 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	// Check we have no outstanding request already.
+	if ( iCurrentRequest.iClientPtr )// just panic in case of concurrent Read or ReadOneOrMore queries.
+		{							 // in case of NotifyDataAvailable queries, we already have completed the client with KErrInUse.
+									 // This code is kept for legacy purpose. That justifies the existence of IsNotifyDataAvailableQueryPending
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError);
+		}
+	// Sanity check on what C32 gave us.
+	__ASSERT_DEBUG(aClientBuffer, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	// Make a note of interesting data.
+	iCurrentRequest.iClientPtr = aClientBuffer;
+	iLengthToGo = aMaxLen;
+	iOffsetIntoClientsMemory = 0;
+	}
+
+void CAcmReader::CheckForBufferedTerminatorsAndProceed()
+/**
+ * Checks for terminator characters in the buffer. Completes the client's 
+ * request if possible, and issues further ReadOneOrMores for the appropriate 
+ * amount if not.
+ */
+	{
+	LOG_FUNC
+
+	TInt ret = FindTerminator();
+	LOGTEXT2(_L8("\tFindTerminator = %d"), ret);
+	if ( ret < KErrNone )
+		{
+		LOGTEXT(_L8("\tno terminator found"));
+		const TUint bufLen = BufLen();
+		LOGTEXT2(_L8("\tbufLen = %d"), bufLen);
+		// No terminator was found. Does the buffer already exceed the 
+		// client's descriptor?
+		if ( bufLen >= iLengthToGo )
+			{
+			// Yes- complete as much data to the client as their 
+			// descriptor can handle.
+			LOGTEXT2(_L8("\tbuffer >= client descriptor- "
+				"writing back %d bytes"), iLengthToGo);
+			WriteBackData(iLengthToGo);
+			CompleteRequest(KErrNone);
+			}
+		else
+			{
+			// No- write back the data we've got and issue a request to get 
+			// some more data. 
+			WriteBackData(bufLen);
+			IssueReadOneOrMore();
+			}
+		}
+	else
+		{
+		LOGTEXT(_L8("\tterminator found!"));
+		// Will the terminator position fit within the client's descriptor?
+		if ( static_cast<TUint>(ret) <= iLengthToGo )
+			{
+			// Yes- complete (up to the terminator) back to the client.
+			LOGTEXT2(_L8("\tterminator will fit in client's descriptor- "
+				"writing back %d bytes"), ret);
+			WriteBackData(static_cast<TUint>(ret));
+			CompleteRequest(KErrNone);
+			}
+		else
+			{
+			// No- complete as much data to the client as their descriptor can 
+			// handle.
+			LOGTEXT2(_L8("\tterminator won't fit in client's descriptor- "
+				"writing back %d bytes"), iLengthToGo);
+			WriteBackData(iLengthToGo);
+			CompleteRequest(KErrNone);
+			}
+		}
+	}
+
+void CAcmReader::WriteBackData(TUint aLength)
+/**
+ * This function writes back data to the client address space. The write will 
+ * be performed in one go if the data to be written back is not wrapped across 
+ * the end of the circular buffer. If the data is wrapped, the write is done 
+ * in two stages. The read pointer is updated to reflect the data consumed, as 
+ * is the counter for remaining data required by the client (iLengthToGo), and 
+ * the pointer into the client's memory (iOffsetIntoClientsMemory).
+ *
+ * @param aLength Amount of data to write back.
+ */
+	{
+	LOGTEXT2(_L8("CAcmReader::WriteBackData aLength = %d"), aLength);
+	LOGTEXT2(_L8("\tBufLen() = %d"), BufLen());
+
+	LOGTEXT2(_L8("\tBufLen() = %d"), BufLen());
+
+	__ASSERT_DEBUG(aLength <= BufLen(), 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	const TUint lenBeforeWrap = iBufStart + iBufSize - iOutPtr;
+
+	LOGTEXT2(_L8("\tiOutPtr=%d"), iOutPtr - iBufStart);
+	LOGTEXT2(_L8("\tiInPtr=%d"), iInPtr - iBufStart);
+	LOGTEXT2(_L8("\tiOffsetIntoClientsMemory=%d"), iOffsetIntoClientsMemory);
+	LOGTEXT2(_L8("\tlenBeforeWrap=%d"), lenBeforeWrap);
+	
+	if ( aLength > lenBeforeWrap )
+		{ 
+		// We'll have to do this in two stages...
+		LOGTEXT(_L8("\twriting back in two stages"));
+
+		__ASSERT_DEBUG(BufWrap(), 
+			_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+		// Stage 1...
+		TPtrC8 ptrBeforeWrap(iOutPtr, lenBeforeWrap);
+		TInt err = iPort.IPCWrite(iCurrentRequest.iClientPtr,
+			ptrBeforeWrap,
+			iOffsetIntoClientsMemory);
+		LOGTEXT2(_L8("\tIPCWrite = %d"), err);
+		__ASSERT_DEBUG(!err, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		static_cast<void>(err);
+		iOffsetIntoClientsMemory += lenBeforeWrap;
+
+		// Stage 2...
+		TInt seg2Len = aLength - lenBeforeWrap;
+		TPtrC8 ptrAfterWrap(iBufStart, seg2Len);
+		err = iPort.IPCWrite(iCurrentRequest.iClientPtr,
+			ptrAfterWrap,
+			iOffsetIntoClientsMemory);
+		LOGTEXT2(_L8("\tIPCWrite = %d"), err);
+		__ASSERT_DEBUG(!err, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		iOffsetIntoClientsMemory += seg2Len;
+
+		// and set the pointers to show that we've consumed the data...
+		iOutPtr = iBufStart + seg2Len;
+		LOGTEXT(_L8("\twrite in two segments completed"));
+		}
+	else // We can do it in one go...
+		{
+		LOGTEXT(_L8("\twriting in one segment"));
+
+		TPtrC8 ptr(iOutPtr, aLength);
+		TInt err = iPort.IPCWrite(iCurrentRequest.iClientPtr,
+			ptr,
+			iOffsetIntoClientsMemory);
+		LOGTEXT2(_L8("\tIPCWrite = %d"), err);
+		__ASSERT_DEBUG(!err, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		static_cast<void>(err);
+		iOffsetIntoClientsMemory += aLength;
+
+		// Set the pointers to show that we've consumed the data...
+		iOutPtr += aLength;
+		LOGTEXT(_L8("\twrite in one segment completed"));
+		}
+
+	LOGTEXT2(_L8("\tiOutPtr=%d"), iOutPtr - iBufStart);
+	LOGTEXT2(_L8("\tiOffsetIntoClientsMemory=%d"), iOffsetIntoClientsMemory);
+
+	// Adjust iLengthToGo
+	__ASSERT_DEBUG(iLengthToGo >= aLength, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iLengthToGo -= aLength;
+	}
+
+void CAcmReader::CompleteRequest(TInt aError)
+/**
+ * Utility to reset our 'outstanding request' flag and complete the client's 
+ * request back to them. Does not actually write back data to the client's 
+ * address space.
+ * 
+ * @param aError The error code to complete with.
+ */
+	{
+	LOGTEXT2(_L8("CAcmReader::CompleteRequest aError=%d"), aError);
+
+	// Set our flag to say that we no longer have an outstanding request.
+	iCurrentRequest.iClientPtr = NULL;
+
+	if(ENotifyDataAvailable==iCurrentRequest.iRequestType)
+		{
+		LOGTEXT2(_L8("\tcalling NotifyDataAvailableCompleted with error %d"), aError);
+		iPort.NotifyDataAvailableCompleted(aError);	
+		}
+	else // read and readoneormore
+		{
+		LOGTEXT2(_L8("\tcalling ReadCompleted with error %d"), aError);
+		iPort.ReadCompleted(aError);
+		}
+	}
+
+void CAcmReader::IssueRead()
+/**
+ * Issues a read request for N bytes, where N is the minimum of iLengthToGo, 
+ * the LDD's limit on Read requests, and how far we are from the end of our 
+ * buffer. Used when trying to satisfy an RComm Read without terminators.
+ * We enforce that the buffer is empty, so we don't have to worry about the 
+ * buffer being wrapped and the consequent risk of overwriting.
+ */
+	{
+	LOG_FUNC
+
+	CheckBufferEmptyAndResetPtrs();
+
+	LOGTEXT2(_L8("\tiBufSize = %d"), iBufSize);
+	LOGTEXT2(_L8("\tiInPtr = %d"), iInPtr - iBufStart);
+
+	const TUint lenBeforeWrap = iBufStart + iBufSize - iInPtr;
+	
+	LOGTEXT2(_L8("\tiLengthToGo = %d"), iLengthToGo);
+	LOGTEXT2(_L8("\tlenBeforeWrap = %d"), lenBeforeWrap);
+
+	const TUint limit = Min(static_cast<TInt>(iLengthToGo), 
+		static_cast<TInt>(lenBeforeWrap));
+	LOGTEXT2(_L8("\tissuing read for %d bytes"), limit);
+	iInBuf.Set(iInPtr, 0, limit);
+	__ASSERT_DEBUG(iPort.Acm(), 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iPort.Acm()->Read(*this, iInBuf, limit);
+	}
+
+void CAcmReader::IssueReadOneOrMore()
+/**
+ * Issues a read request for N bytes, where N is the minimum of iLengthToGo, 
+ * and how far we are from the end of our buffer. Used when trying to satisfy 
+ * an RComm ReadOneOrMore.
+ * We enforce that the buffer is empty, so we don't have to worry about the 
+ * buffer being wrapped and the consequent risk of overwriting.
+ */
+	{
+	LOG_FUNC
+
+	CheckBufferEmptyAndResetPtrs();
+
+	LOGTEXT2(_L8("\tiBufSize = %d"), iBufSize);
+	LOGTEXT2(_L8("\tiInPtr = %d"), iInPtr - iBufStart);
+
+	const TUint lenBeforeWrap = iBufStart + iBufSize - iInPtr;
+	
+	LOGTEXT2(_L8("\tiLengthToGo = %d"), iLengthToGo);
+	LOGTEXT2(_L8("\tlenBeforeWrap = %d"), lenBeforeWrap);
+
+	const TUint limit1 = Min(static_cast<TInt>(lenBeforeWrap), iLengthToGo);
+	
+	LOGTEXT2(_L8("\tissuing read one or more for %d bytes"), limit1);
+	iInBuf.Set(iInPtr, 0, limit1);
+	__ASSERT_DEBUG(iPort.Acm(), 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iPort.Acm()->ReadOneOrMore(*this, iInBuf, limit1);
+	}
+
+TInt CAcmReader::FindTerminator() const
+/**
+ * This function searches the circular buffer for one of a number of 
+ * termination characters.
+ * The search is conducted between the read and write pointers. The function 
+ * copes with the wrapping of the buffer.
+ *
+ * @return If positive: the number of bytes between where iOutPtr is pointing 
+ * at and where the terminator was found inclusive. Takes wrapping into 
+ * account. If negative: error.
+ */
+	{
+	LOGTEXT(_L8(">>CAcmReader::FindTerminator"));
+
+	TInt pos = 0;
+	TInt ret = KErrNone;
+	if ( !BufWrap() )
+		{
+		ret = PartialFindTerminator(iOutPtr, iInPtr, pos);
+		if ( !ret )
+			{
+			// Buffer wasn't wrapped, terminator found.
+			ret = pos;
+			}
+		}
+	else
+		{
+		ret = PartialFindTerminator(iOutPtr, iBufStart+iBufSize, pos);
+		if ( !ret )
+			{
+			// Buffer was wrapped, but terminator was found in the section 
+			// before the wrap.
+			ret = pos;
+			}
+		else
+			{
+			ret = PartialFindTerminator(iBufStart, iInPtr, pos);
+			if ( !ret )
+				{
+				// Buffer was wrapped, terminator was found in the wrapped 
+				// section.
+				const TUint lenBeforeWrap = iBufStart + iBufSize - iOutPtr;
+				ret = pos + lenBeforeWrap;
+				}
+			}
+		}
+
+	// Check we're returning what we said we would.
+	__ASSERT_DEBUG(ret != KErrNone, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	
+	LOGTEXT2(_L8("<<CAcmReader::FindTerminator ret=%d"), ret);
+	return ret;
+	}
+
+TInt CAcmReader::PartialFindTerminator(TUint8* aFrom, 
+									   TUint8* aTo, 
+									   TInt& aPos) const
+/**
+ * This function searches the buffer for one of a number of termination 
+ * characters. The search is conducted between the pointers given. The 
+ * function only searches a continuous buffer space, and does not respect the 
+ * circular buffer wrap.
+ *
+ * @param aFrom The pointer at which to start searching.
+ * @param aTo The pointer one beyond where to stop searching.
+ * @param aPos The number of bytes beyond (and including) aFrom the terminator 
+ * was found. That is, if the terminator was found adjacent to aFrom, aPos 
+ * will be 2- the client can take this as meaning that 2 bytes are to be 
+ * written back to the RComm client (aFrom and the one containing the 
+ * terminator).
+ * @return KErrNone- a terminator was found. KErrNotFound- no terminator was 
+ * found.
+ */
+	{
+	LOG_FUNC
+
+	aPos = 1;
+	LOGTEXT3(_L8("\taFrom=%d, aTo=%d"), aFrom-iBufStart, aTo-iBufStart);
+
+	for ( TUint8* p = aFrom ; p < aTo ; p++, aPos++ )
+		{
+		for ( TUint i = 0 ; i < iTerminatorCount ; i++ )
+			{
+			__ASSERT_DEBUG(p, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+			if ( *p == iTerminator[i] )
+				{
+				LOGTEXT3(_L8("\tterminator %d found at aPos %d"), 
+					iTerminator[i], aPos);
+				return KErrNone;
+				}
+			}
+		}
+	
+	LOGTEXT(_L8("\tno terminator found"));
+	return KErrNotFound;
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/AcmWriter.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,307 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <usb/usblogger.h>
+#include "AcmWriter.h"
+#include "AcmPort.h"
+#include "AcmPanic.h"
+#include "AcmUtils.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CAcmWriter* CAcmWriter::NewL(CAcmPort& aPort, 
+							 TUint aBufSize)
+/**
+ * Factory function.
+ *
+ * @param aPort Owning CAcmPort object.
+ * @param aBufSize Required buffer size.
+ * @return Ownership of a newly created CAcmWriter object
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CAcmWriter* self = new(ELeave) CAcmWriter(aPort, aBufSize);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CLEANUPSTACK_POP(self);
+	return self;
+	}
+
+CAcmWriter::~CAcmWriter()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	WriteCancel();
+
+	delete iBuffer;
+	}
+
+void CAcmWriter::Write(const TAny* aClientBuffer, TUint aLength)
+/**
+ * Queue a write.
+ *
+ * @param aClientBuffer pointer to the Client's buffer
+ * @param aLength Number of bytes to write
+ */
+	{
+	LOGTEXT3(_L8("CAcmWriter::Write aClientBuffer=0x%08x, aLength=%d"), 
+		aClientBuffer, aLength);
+
+	// Check we're open to requests and make a note of interesting data.
+	CheckNewRequest(aClientBuffer, aLength);
+
+	// If the write size greater than the current buffer size then the
+	// request will now complete over multiple operations. (This used to 
+	// simply reject the write request with KErrNoMemory)
+	
+	// Get as much data as we can from the client into our buffer
+	ReadDataFromClient();
+	// ...and write as much as we've got to the LDD
+	IssueWrite();
+	}
+
+void CAcmWriter::WriteCancel()
+/**
+ * Cancel a write.
+ */
+	{
+	LOG_FUNC
+
+	// Cancel any outstanding request on the LDD.
+	if ( iPort.Acm() )
+		{
+		LOGTEXT(_L8("\tiPort.Acm() exists- calling WriteCancel on it"));
+		iPort.Acm()->WriteCancel();
+		}
+
+	// Reset our flag to say there's no current outstanding request. What's 
+	// already in our buffer can stay there.
+	iCurrentRequest.iClientPtr = NULL;
+	}
+
+void CAcmWriter::ResetBuffer()
+/**
+ * Called by the port to clear the buffer.
+ */
+	{
+	LOG_FUNC
+
+	// A request is outstanding- C32 should protect against this.
+	__ASSERT_DEBUG(!iCurrentRequest.iClientPtr, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	// Don't have anything to do. There are no pointers to reset. This 
+	// function may in the future (if we support KConfigWriteBufferedComplete) 
+	// do work, so leave the above assertion in.
+	}
+
+TInt CAcmWriter::SetBufSize(TUint aSize)
+/**
+ * Called by the port to set the buffer size. Also used as a utility by us to 
+ * create the buffer at instantiation. 
+ *
+ * @param aSize The required size of the buffer.
+ */
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taSize=%d"), aSize);
+
+	if ( iCurrentRequest.iClientPtr )
+		{
+		// A request is outstanding. C32 does not protect us against this.
+		LOGTEXT(_L8("\t***a request is outstanding- returning KErrInUse"));
+		return KErrInUse;
+		}
+
+	// Create the new buffer.
+	HBufC8* newBuf = HBufC8::New(static_cast<TInt>(aSize));
+	if ( !newBuf )
+		{
+		LOGTEXT(_L8("\tfailed to create new buffer- returning KErrNoMemory"));
+		return KErrNoMemory;
+		}
+	delete iBuffer;
+	iBuffer = newBuf;
+	iBuf.Set(iBuffer->Des());
+	iBufSize = aSize;
+
+	return KErrNone;
+	}
+
+CAcmWriter::CAcmWriter(CAcmPort& aPort, 
+					   TUint aBufSize)
+/**
+ * Constructor.
+ *
+ * @param aPort The CPort parent.
+ * @param aBufSize The size of the buffer.
+ */
+ :	iBufSize(aBufSize),
+	iBuf(NULL,0,0),
+	iPort(aPort)
+	{
+	}
+
+void CAcmWriter::ConstructL()
+/**
+ * 2nd-phase constructor. 
+ */
+	{
+	// Create the required buffer.
+	LOGTEXT(_L8("\tabout to create iBuffer"));
+	LEAVEIFERRORL(SetBufSize(iBufSize));
+	}
+
+void CAcmWriter::WriteCompleted(TInt aError)
+/**
+ * This function is called when a write on the LDD has completed. 
+ * This checks whether any data remains to be written, if so the 
+ * read and write requests are re-issued until there in no data 
+ * left or an error occurs.
+ *
+ * @param aError Error with which the write completed.
+ */
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taError=%d"), aError);						   	
+
+	if(iLengthToGo == 0 || aError != KErrNone)
+		{
+		LOGTEXT2(_L8("\tcompleting request with %d"), aError);
+		CompleteRequest(aError);	
+		}
+	else
+		{
+		//there is some data remaining to be read so reissue the Read & Write 
+		//requests until there is no data left.
+		ReadDataFromClient();
+		IssueWrite();
+		}
+	}
+
+void CAcmWriter::ReadDataFromClient()
+/**
+ * Read data from the client space into the internal buffer, prior to writing.
+ */
+	{
+	LOG_FUNC
+	TPtr8 ptr((TUint8*)iBuf.Ptr(),
+			  0,
+			  Min(iBuf.MaxLength(), iLengthToGo));
+
+	TInt err = iPort.IPCRead(iCurrentRequest.iClientPtr,
+			ptr,
+			static_cast<TInt>(iOffsetIntoClientsMemory));	
+	LOGTEXT2(_L8("\tIPCRead = %d"), err);
+	iBuf.SetLength(ptr.Length());
+	__ASSERT_DEBUG(!err, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	
+	static_cast<void>(err);
+
+	// Increase our pointer (into the client's space) of already-read data.
+	iOffsetIntoClientsMemory += iBuf.Length();
+	}
+
+
+
+void CAcmWriter::CheckNewRequest(const TAny* aClientBuffer, TUint aLength)
+/**
+ * Utility function to check a new request from the port. 
+ * Also checks that there isn't a request already outstanding. Makes a note of 
+ * the relevant parameters and sets up internal counters.
+ *
+ * @param aClientBuffer Pointer to the client's memory space.
+ * @param aLength Length to write.
+ */
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG(aLength <= static_cast<TUint>(KMaxTInt), 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	// Check we have no outstanding request already.
+	if ( iCurrentRequest.iClientPtr )
+		{
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError);
+		}
+	// Sanity check on what C32 gave us.
+	__ASSERT_DEBUG(aClientBuffer, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	// Make a note of interesting data.
+	iCurrentRequest.iLength = aLength;
+	iCurrentRequest.iClientPtr = aClientBuffer;
+	
+	iLengthToGo = aLength;
+	iOffsetIntoClientsMemory = 0;
+	}
+
+void CAcmWriter::CompleteRequest(TInt aError)
+/**
+ * Utility to reset our 'outstanding request' flag and complete the client's 
+ * request back to them. 
+ * 
+ * @param aError The error code to complete with.
+ */
+	{
+	LOGTEXT2(_L8("CAcmWriter::CompleteRequest aError=%d"), aError);
+
+	// Set our flag to say that we no longer have an outstanding request.
+	iCurrentRequest.iClientPtr = NULL;
+
+	LOGTEXT2(_L8("\tcalling WriteCompleted with %d"), aError);
+	iPort.WriteCompleted(aError);
+	}
+
+void CAcmWriter::IssueWrite()
+/**
+ * Writes a batch of data from our buffer to the LDD. Currently writes the 
+ * entire load of buffered data in one go.
+ */
+	{
+	LOG_FUNC
+
+	LOGTEXT2(_L8("\tissuing Write of %d bytes"), iBuf.Length());
+	__ASSERT_DEBUG(iPort.Acm(), 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iPort.Acm()->Write(*this, 
+		iBuf, 
+		iBuf.Length());
+	
+#ifdef DEBUG
+	// A Zero Length Packet is an acceptable packet so iBuf.Length == 0 is acceptable, 
+	// if we receive this and the request length > 0 then we may have a problem so check 
+	// that the LengthToGo is also 0, if it is not then we may end up looping through this
+	// code until a driver write error occurs which may never happen. 
+	// This is not expected to occur but the test is in here just to be safe.
+	if(iBuf.Length() == 0 && iCurrentRequest.Length() != 0 && iLengthToGo != 0)
+		{
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError);
+		}
+#endif
+	// Update our counter of remaining data to write. 
+	iLengthToGo -= iBuf.Length();
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ActiveDataAvailableNotifier.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,168 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include <e32std.h>
+#include <d32usbc.h>
+#include "ActiveDataAvailableNotifier.h"
+#include "AcmConstants.h"
+#include "AcmPanic.h"
+#include "AcmUtils.h"
+#include "NotifyDataAvailableObserver.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CActiveDataAvailableNotifier::CActiveDataAvailableNotifier(
+								MNotifyDataAvailableObserver& aParent, 
+								RDevUsbcClient& aLdd,
+								TEndpointNumber aEndpoint)
+ :	CActive(KEcacmAOPriority), 
+	iParent(aParent),
+	iLdd(aLdd),
+	iEndpoint(aEndpoint)
+/**
+ * Constructor.
+ *
+ * @param aParent The object that will be notified if a 
+ * NotifyDataAvailable() request has been made and incoming data 
+ * arrives at the LDD.
+ * @param aLdd The LDD handle to be used for posting read requests.
+ * @param aEndpoint The endpoint to read from.
+ */
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CActiveDataAvailableNotifier::~CActiveDataAvailableNotifier()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	Cancel();
+	}
+
+CActiveDataAvailableNotifier* CActiveDataAvailableNotifier::NewL(
+								MNotifyDataAvailableObserver& aParent, 
+								RDevUsbcClient& aLdd,
+								TEndpointNumber aEndpoint)
+/**
+ * Standard two phase constructor.
+ *
+ * @param aParent The object that will be notified if a 
+ * NotifyDataAvailable() request has been made and incoming data 
+ * arrives at the LDD.
+ * @param aLdd The LDD handle to be used for posting read requests.
+ * @param aEndpoint The endpoint to read from.
+ * @return Ownership of a new CActiveReadOneOrMoreReader object.
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CActiveDataAvailableNotifier* self = 
+		new(ELeave) CActiveDataAvailableNotifier(aParent, aLdd, aEndpoint);
+	return self;
+	}
+
+void CActiveDataAvailableNotifier::NotifyDataAvailable()
+/**
+ * When incoming data arrives at the LDD notify the caller.
+ */
+	{
+	LOGTEXT(_L8(">>CActiveDataAvailableNotifier::NotifyDataAvailable"));
+
+	iLdd.ReadOneOrMore(iStatus, iEndpoint, iUnusedBuf, 0);
+	SetActive();
+
+	LOGTEXT(_L8("<<CActiveDataAvailableNotifier::NotifyDataAvailable"));
+	}
+
+void CActiveDataAvailableNotifier::DoCancel()
+/**
+ * Cancel an outstanding request.
+ */
+	{
+	LOG_FUNC
+
+	iLdd.ReadCancel(iEndpoint);
+	}
+
+void CActiveDataAvailableNotifier::RunL()
+/**
+ * This function will be called when the zero byte ReadOneOrMore() call on the LDD
+ * completes. This could have been caused by the receipt of a Zero Length Packet in
+ * which case there is no data available to be read. In this situation 
+ * NotifyDataAvailable() is called again, otherwise the parent is notified.
+ * We also have to be careful about getting into an infinite loop if the cable has 
+ * been detached.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+	LOGTEXT2(_L8("\tiStatus = %d"), iStatus.Int());
+	
+	TBool complete = EFalse;
+	TInt completeErr = KErrNone;
+
+	TInt recBufSize;
+	TInt err = iLdd.QueryReceiveBuffer(iEndpoint, recBufSize);
+	if ( err == KErrNone )
+		{
+		if ( recBufSize != 0 )
+			{
+			// There is data available.
+			complete = ETrue;
+			completeErr = KErrNone;
+			}
+		else
+			{
+			// There is no data available. This may be because we got a ZLP, but 
+			// before we simply repost the notification, check to see if the LDD 
+			// is still working. If there isn't then we should complete to the 
+			// client to avoid getting ourselves into an infinite loop.
+			if ( iStatus.Int() == KErrNone )
+				{
+				NotifyDataAvailable();
+				}
+			else
+				{
+				complete = ETrue;
+				// The Active Reader and Active Writer objects pass LDD-specific 
+				// errors straight up the stack, so I don't see a problem with 
+				// doing the same here. [As opposed to genericising them into 
+				// KErrCommsLineFail for instance.]
+				completeErr = iStatus.Int();
+				}
+			}
+		}
+	else // QueryReceiveBuffer failed
+		{
+		complete = ETrue;
+		completeErr = err;
+		}
+
+	if ( complete )
+		{
+		iParent.NotifyDataAvailableCompleted(completeErr);
+		}
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ActiveReadOneOrMoreReader.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,125 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <e32std.h>
+#include <d32usbc.h>
+#include "ActiveReadOneOrMoreReader.h"
+#include "AcmConstants.h"
+#include "AcmPanic.h"
+#include "AcmUtils.h"
+#include "ReadOneOrMoreObserver.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CActiveReadOneOrMoreReader::CActiveReadOneOrMoreReader(
+								MReadOneOrMoreObserver& aParent, 
+								RDevUsbcClient& aLdd,
+								TEndpointNumber aEndpoint)
+ :	CActive(KEcacmAOPriority), 
+	iParent(aParent),
+	iLdd(aLdd),
+	iEndpoint(aEndpoint)
+/**
+ * Constructor.
+ *
+ * @param aParent The object that will be notified when read requests 
+ * complete.
+ * @param aLdd The LDD handle to be used for posting read requests.
+ * @param aEndpoint The endpoint to read from.
+ */
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CActiveReadOneOrMoreReader::~CActiveReadOneOrMoreReader()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	Cancel();
+	}
+
+CActiveReadOneOrMoreReader* CActiveReadOneOrMoreReader::NewL(
+								MReadOneOrMoreObserver& aParent, 
+								RDevUsbcClient& aLdd,
+								TEndpointNumber aEndpoint)
+/**
+ * Standard two phase constructor.
+ *
+ * @param aParent The object that will be notified when read requests 
+ * complete.
+ * @param aLdd The LDD handle to be used for posting read requests.
+ * @param aEndpoint The endpoint to read from.
+ * @return Ownership of a new CActiveReadOneOrMoreReader object.
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CActiveReadOneOrMoreReader* self = 
+		new(ELeave) CActiveReadOneOrMoreReader(aParent, aLdd, aEndpoint);
+	return self;
+	}
+
+void CActiveReadOneOrMoreReader::ReadOneOrMore(TDes8& aDes, TInt aLength)
+/**
+ * Read as much data as the LDD can supply up to the given limit.
+ *
+ * @param aDes A descriptor into which the data will be read.
+ * @param aLength The length to read.
+ */
+	{
+	LOGTEXT2(_L8(">>CActiveReadOneOrMoreReader::ReadOneOrMore "
+		"aLength=%d"), aLength);
+
+	iLdd.ReadOneOrMore(iStatus, iEndpoint, aDes, aLength);
+	SetActive();
+
+	LOGTEXT(_L8("<<CActiveReadOneOrMoreReader::ReadOneOrMore"));
+	}
+
+void CActiveReadOneOrMoreReader::DoCancel()
+/**
+ * Cancel an outstanding request.
+ */
+	{
+	LOG_FUNC
+
+	iLdd.ReadCancel(iEndpoint);
+	}
+
+void CActiveReadOneOrMoreReader::RunL()
+/**
+ * This function will be called when the request completes. It notifies the 
+ * parent class of the completion.
+ */
+	{
+	LOG_LINE
+	LOGTEXT2(_L8(">>CActiveReadOneOrMoreReader::RunL iStatus=%d"), 
+		iStatus.Int());
+
+	iParent.ReadOneOrMoreCompleted(iStatus.Int());
+
+	LOGTEXT(_L8("<<CActiveReadOneOrMoreReader::RunL"));
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ActiveReader.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,116 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <e32std.h>
+#include <d32usbc.h>
+#include "ActiveReader.h"
+#include "AcmConstants.h"
+#include "AcmPanic.h"
+#include "ReadObserver.h"
+#include "AcmUtils.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CActiveReader::CActiveReader(MReadObserver& aParent, RDevUsbcClient& aLdd, TEndpointNumber aEndpoint)
+ :	CActive(KEcacmAOPriority), 
+	iParent(aParent),
+	iLdd(aLdd),
+	iEndpoint(aEndpoint)
+/**
+ * Constructor.
+ *
+ * @param aParent The object that will be notified when read requests 
+ * complete.
+ * @param aLdd The LDD handle to be used for posting read requests.
+ * @param aEndpoint The endpoint to read from.
+ */
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CActiveReader::~CActiveReader()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	Cancel();
+	}
+
+CActiveReader* CActiveReader::NewL(MReadObserver& aParent, 
+								   RDevUsbcClient& aLdd,
+								   TEndpointNumber aEndpoint)
+/**
+ * Standard two phase constructor.
+ *
+ * @param aParent The object that will be notified when read requests 
+ * complete.
+ * @param aLdd The LDD handle to be used for posting read requests.
+ * @param aEndpoint The endpoint to read from.
+ * @return Ownership of a new CActiveReader object.
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CActiveReader* self = new(ELeave) CActiveReader(aParent, aLdd, aEndpoint);
+	return self;
+	}
+
+void CActiveReader::Read(TDes8& aDes, TInt aLen)
+/**
+ * Read the given length of data from the LDD.
+ *
+ * @param aDes A descriptor into which to read.
+ * @param aLen The length to read.
+ */
+	{
+	LOG_FUNC
+
+	iLdd.Read(iStatus, iEndpoint, aDes, aLen); 
+	SetActive();
+	}
+
+void CActiveReader::DoCancel()
+/**
+ * Cancel an outstanding read.
+ */
+	{
+	LOG_FUNC
+
+	iLdd.ReadCancel(iEndpoint);
+	}
+
+void CActiveReader::RunL()
+/**
+ * This function will be called when the read completes. It notifies the 
+ * parent class of the completion.
+ */
+	{
+	LOG_LINE
+	LOGTEXT2(_L8(">>CActiveReader::RunL iStatus=%d"), iStatus.Int());
+
+	iParent.ReadCompleted(iStatus.Int());
+
+	LOGTEXT(_L8("<<CActiveReader::RunL"));
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ActiveWriter.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,182 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <e32std.h>
+#include <d32usbc.h>
+#include "ActiveWriter.h"
+#include "AcmConstants.h"
+#include "AcmPanic.h"
+#include "WriteObserver.h"
+#include "AcmUtils.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CActiveWriter::CActiveWriter(MWriteObserver& aParent, RDevUsbcClient& aLdd, TEndpointNumber aEndpoint)
+ :	CActive(KEcacmAOPriority), 
+	iParent(aParent),
+	iLdd(aLdd),
+	iEndpoint(aEndpoint),
+	iFirstPortion(NULL, 0),
+	iSecondPortion(NULL, 0)
+/**
+ * Constructor.
+ *
+ * @param aParent The object that will be notified when write requests 
+ * complete.
+ * @param aLdd The LDD handle to be used for posting write requests.
+ * @param aEndpoint The endpoint to write to.
+ */
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CActiveWriter::~CActiveWriter()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	Cancel();
+	}
+
+CActiveWriter* CActiveWriter::NewL(MWriteObserver& aParent, 
+								   RDevUsbcClient& aLdd,
+								   TEndpointNumber aEndpoint)
+/**
+ * Standard two phase constructor.
+ *
+ * @param aParent The object that will be notified when write requests 
+ * complete.
+ * @param aLdd The LDD handle to be used for posting write requests.
+ * @param aEndpoint The endpoint to write to.
+ * @return Ownership of a new CActiveWriter object.
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CActiveWriter* self = new(ELeave) CActiveWriter(aParent, aLdd, aEndpoint);
+	return self;
+	}
+
+void CActiveWriter::Write(const TDesC8& aDes, 
+					TInt aLen, 
+					TBool aZlp)
+/**
+ * Write the given data to the LDD.
+ *
+ * @param aDes A descriptor to write.
+ * @param aLen The length to write.
+ * @param aZlp Whether ZLP termination may be required.
+ */
+	{
+	LOGTEXT(_L8(">>CActiveWriter::Write"));
+
+	if ( aZlp )
+		{
+		// the driver can be relied on to correctly handle appended ZLPs
+		// so use them when necessary..
+		iLdd.Write(iStatus, iEndpoint, aDes, aLen, ETrue);
+		iWritingState = ECompleteMessage;
+		}
+	else
+		{
+		// do we need to send this descriptor in two portions to
+		// avoid finishing the last packet on a 64 byte boundary ( avoiding
+		// expectations of a ZLP by drivers that would handle them ) ?
+		
+		// If the write request is for zero bytes a 'split' would be erroneous.
+		TBool full64BytePacket = ( aLen % KMaxPacketSize ) ? EFalse : ETrue;
+		
+		if ( full64BytePacket == EFalse || aLen == 0 )
+			{
+			iLdd.Write(iStatus, iEndpoint, aDes, aLen, EFalse);
+			iWritingState = ECompleteMessage;
+			LOGTEXT2(_L8("CActiveWriter::Writing %d bytes"), aLen);
+			}
+		else
+			{
+			// we do need to split the descriptor, sending aLen-1 bytes now 
+			// and sending a second portion with the remaining 1 byte later
+			iFirstPortion.Set(aDes.Left(aLen-1));
+			
+			// Use of Left here ensures that if we've been passed a descriptor
+			// longer than aLen (doesn't *currently* happen), we don't corrupt
+			// data.
+			iSecondPortion.Set(aDes.Left(aLen).Right(1));
+			
+			iLdd.Write(iStatus, iEndpoint, iFirstPortion, aLen-1, EFalse);
+			
+			iWritingState = EFirstMessagePart;
+			LOGTEXT3(_L8("CActiveWriter::Writing %d bytes of the %d"), aLen-1, aLen);
+			}
+		}
+	SetActive();
+
+	LOGTEXT(_L8("<<CActiveWriter::Write"));
+	}
+
+void CActiveWriter::DoCancel()
+/**
+ * Cancel an outstanding write.
+ */
+	{
+	LOG_FUNC
+
+	iLdd.WriteCancel(iEndpoint);
+	}
+
+void CActiveWriter::RunL()
+/**
+ * This function will be called when the write completes. It notifies the 
+ * parent class of the completion.
+ */
+	{
+	LOG_LINE
+	LOGTEXT2(_L8(">>CActiveWriter::RunL iStatus=%d"), iStatus.Int());
+	
+	if ( iWritingState == EFirstMessagePart )
+		{
+		if ( iStatus.Int() == KErrNone )
+			{			
+			// now send the second part..
+			iLdd.Write(iStatus, iEndpoint, iSecondPortion, iSecondPortion.Length(), EFalse);
+			iWritingState = EFinalMessagePart;
+			LOGTEXT(_L8("CActiveWriter::Writing 1 byte to complete original nx64 byte message"));
+
+			SetActive();
+			}
+		else
+			{
+			// the writing of the first part failed
+			iParent.WriteCompleted(iStatus.Int());
+			}
+		}
+	else 
+		{
+		// iWritingState == ECompleteMessage or EFinalMessagePart
+		iParent.WriteCompleted(iStatus.Int());
+		}
+		
+	LOGTEXT(_L8("<<CActiveWriter::RunL"));
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/BreakController.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,346 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include "BreakController.h"
+#include "CdcAcmClass.h"
+#include "AcmUtils.h"
+#include "HostPushedChangeObserver.h"
+#include "AcmPanic.h"
+#include "BreakObserver.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CBreakController::CBreakController(CCdcAcmClass& aParentAcm)
+/**
+ * Constructor.
+ * 
+ * @param aParentAcm Observer.
+ */
+ :	CActive(CActive::EPriorityStandard),
+	iBreakState(EInactive),
+	iParentAcm(aParentAcm)
+	{
+	CActiveScheduler::Add(this);
+
+	// now populate the state machine that manages the transfers between
+	// the declared state values of TBreakState.
+	TInt oldBS;
+	TInt newBS;
+
+	for ( oldBS = 0 ; oldBS < ENumStates ; oldBS++ )
+		{
+		for ( newBS = 0 ; newBS < ENumStates ; newBS++ )
+			{
+			StateDispatcher[oldBS][newBS] = ScInvalid;
+			}
+		}
+
+	// Note that these state transitions are the simple states of the machine. 
+	// Checking which entity is currently in control of the break (if any) is 
+	// done elsewhere.
+	//				Old State -> New State
+	//				|			 |
+	StateDispatcher[EInactive  ][ETiming   ] = &ScSetTimer;
+	StateDispatcher[EInactive  ][ELocked   ] = &ScLocked;
+
+	StateDispatcher[ETiming    ][EInactive ] = &ScInactive;
+	StateDispatcher[ETiming    ][ETiming   ] = &ScSetTimer;
+	StateDispatcher[ETiming    ][ELocked   ] = &ScLocked;
+
+	StateDispatcher[ELocked    ][EInactive ] = &ScInactive;
+	StateDispatcher[ELocked    ][ETiming   ] = &ScSetTimer; 
+	}
+
+CBreakController* CBreakController::NewL(CCdcAcmClass& aParentAcm)
+/**
+ * Factory function.
+ *
+ * @param aParentAcm Parent.
+ * @return Ownership of a new CBreakController object.
+ */ 
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CBreakController* self = new(ELeave) CBreakController(aParentAcm);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CLEANUPSTACK_POP(self);
+	return self;
+	}
+
+void CBreakController::ConstructL()
+/**
+ * 2nd-phase constructor.
+ */
+	{
+	LEAVEIFERRORL(iTimer.CreateLocal());
+	}
+
+CBreakController::~CBreakController()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	Cancel();
+	iTimer.Close();
+	}
+
+void CBreakController::RunL()
+/**
+ * Called by the active scheduler; handles timer completion.
+ */
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	// check the status to see if the timer has matured, if so go straight 
+	// to INACTIVE state (and publish new state)
+	if ( iStatus == KErrNone )
+		{
+		// Use iRequester to turn the break off. This should not fail.
+		TInt err = BreakRequest(iRequester, EInactive);
+		static_cast<void>(err);
+		__ASSERT_DEBUG(!err, 
+			_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		}
+	}
+
+void CBreakController::DoCancel()
+/**
+ * Called by the framework; handles cancelling the outstanding timer request.
+ */
+	{
+	LOG_FUNC
+
+	iTimer.Cancel();
+	}
+
+TInt CBreakController::BreakRequest(TRequester aRequester, 
+									TState aState, 
+									TTimeIntervalMicroSeconds32 aDelay)
+/**
+ * Make a break-related request.
+ *
+ * @param aRequester The entity requesting the break.
+ * @param aState The request- either a locked break, a timed break, or to 
+ * make the break inactive.
+ * @param aDelay The time delay, only used for a timed break.
+ * @return Error, for instance if a different entity already owns the break.
+ */
+ 	{
+	LOG_FUNC
+	LOGTEXT4(_L8("\taRequester = %d, aState = %d, aDelay = %d"), 
+		aRequester, aState, aDelay.Int());	  
+
+	// Check the validity of the request.
+	if ( aRequester != iRequester && iRequester != ENone )
+		{
+		LOGTEXT3(_L8("\t*** %d is in charge- cannot service request "
+			"from %d- returning KErrInUse"), iRequester, aRequester);
+		return KErrInUse;
+		}
+
+	iRequester = aRequester;
+
+	StateMachine(aState, aDelay);
+
+	// Reset the owner member if relevant.
+	if ( aState == EInactive )
+		{
+		iRequester = ENone;
+		}
+
+	return KErrNone;
+	}
+
+void CBreakController::StateMachine(TState aBreakState, 
+									TTimeIntervalMicroSeconds32 aDelay)
+/**
+ * The generic BREAK state machine.
+ *
+ * @param aBreakState The state to go to now.
+ * @param aDelay Only used if going to a breaking state, the delay.
+ */
+	{
+	LOG_FUNC
+
+	TBool resultOK = EFalse;
+
+	// Invoke the desired function.
+	PBFNT pfsDispatch = StateDispatcher[iBreakState][aBreakState];
+	__ASSERT_DEBUG(pfsDispatch, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	resultOK = ( *pfsDispatch )(this, aDelay);
+
+	if ( resultOK )
+		{
+		LOGTEXT(_L8("\tbreak state dispatcher returned *SUCCESS*"));
+
+		// check to see if the state change will need to result
+		// in a modification to the public state of BREAK which is
+		// either NO-BREAK == EBreakInactive
+		//	   or BREAK-ON == (anything else)
+		if(    ( iBreakState != aBreakState )
+			&& (
+				   ( iBreakState == EInactive )
+				|| ( aBreakState == EInactive )
+			   )
+		  )
+			{
+			Publish(aBreakState);
+			}
+
+		// accept the state change ready for next time
+		iBreakState = aBreakState;
+		}
+	else
+		{
+		LOGTEXT(_L8("\tbreak state dispatcher returned *FAILURE*"));
+		}
+	}
+
+void CBreakController::Publish(TState aNewState)
+/**
+ * Pointer-safe method to inform the (USB) Host and the Client of BREAK 
+ * changes.
+ *
+ * @param aNewState The next state we're about to go to.
+ */
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taNewState = %d"), aNewState);
+
+	__ASSERT_DEBUG(aNewState != iBreakState, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	// send the new BREAK state off to the USB Host
+	// this function is normally used so that ACMCSY can send client 
+	// changes to RING, DSR and DCD to the USB Host, however we use
+	// it here to force it to refresh all states together with the
+	// new BREAK state.
+	// TODO: check return value
+	iParentAcm.SendSerialState(
+		iParentAcm.RingState(),
+		iParentAcm.DsrState(),
+		iParentAcm.DcdState());
+
+	// inform the ACM Class client that the BREAK signal has just changed,
+	// this should cause it to be toggled there.
+	if( iParentAcm.BreakCallback() )
+		{
+		LOGTEXT(_L8("\tabout to call back break state change"));
+		iParentAcm.BreakCallback()->BreakStateChange();
+		}
+
+	// If we're going to the inactive state, and if the device is interested, 
+	// we tell the MBreakObserver (ACM port) that the break has completed. 
+	if ( aNewState == EInactive )
+		{
+		LOGTEXT(_L8("\tnew state is break-inactive"));
+		if ( iRequester == EDevice )
+			{
+			LOGTEXT(_L8("\tdevice is interested"));
+			if( iParentAcm.BreakCallback() )
+				{
+				LOGTEXT(_L8("\tabout to call back break completion"));
+				iParentAcm.BreakCallback()->BreakRequestCompleted(); 
+				}
+			}
+
+		// We just got to break-inactive state. Blank the requester record.
+		iRequester = ENone;
+		}
+	}
+
+/**
+ * +----------------------------------------------+
+ * | Set of state-machine functions to be used in |
+ * | a two-dimensional dispatcher matrix		  |
+ * +----------------------------------------------+
+ */
+
+TBool CBreakController::ScInvalid(CBreakController *aThis, 
+								  TTimeIntervalMicroSeconds32 aDelay)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	static_cast<void>(aThis); // remove warning 
+	static_cast<void>(aDelay); // remove warning
+	
+	return( EFalse );
+	}
+
+TBool CBreakController::ScInactive(CBreakController *aThis, 
+								   TTimeIntervalMicroSeconds32 aDelay)
+	{
+	LOG_STATIC_FUNC_ENTRY
+	
+	static_cast<void>(aDelay); // remove warning
+
+	// this may have been called while a BREAK is already current, cancel the 
+	// timer.
+	aThis->Cancel();
+
+	aThis->iParentAcm.SetBreakActive(EFalse);
+
+	return( ETrue );
+	}
+
+TBool CBreakController::ScSetTimer(CBreakController *aThis, 
+								   TTimeIntervalMicroSeconds32 aDelay)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	// don't try to set any delay if the caller wants something impossible
+	if ( aDelay.Int() <= 0 )
+		{
+		return( EFalse );
+		}
+
+	aThis->Cancel(); // in case we're already active.
+
+	aThis->iTimer.After(aThis->iStatus, aDelay);
+	aThis->SetActive();
+
+	aThis->iParentAcm.SetBreakActive(ETrue);
+
+	return( ETrue );
+	}
+
+TBool CBreakController::ScLocked(CBreakController *aThis, 
+								 TTimeIntervalMicroSeconds32 aDelay)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	static_cast<void>(aDelay); // remove warning
+
+	// this may have been called while a BREAK is already current, so cancel 
+	// the timer.
+	aThis->Cancel();
+
+	aThis->iParentAcm.SetBreakActive(ETrue);
+
+	return( ETrue );
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/CdcAcmClass.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,1077 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include "CdcAcmClass.h"
+#include "CdcControlInterface.h"
+#include "CdcDataInterface.h"
+#include "AcmPanic.h"
+#include "AcmUtils.h"
+#include "HostPushedChangeObserver.h"
+#include "BreakController.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CCdcAcmClass::CCdcAcmClass()
+/**
+ * Constructor.
+ */
+	{
+	SetDefaultAcm();
+	}
+
+CCdcAcmClass* CCdcAcmClass::NewL(const TUint8 aProtocolNum, const TDesC16& aAcmControlIfcName, const TDesC16& aAcmDataIfcName)
+/**
+ * Create a new CCdcAcmClass object
+ *
+ * @return Ownership of a new CCdcAcmClass object
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CCdcAcmClass* self = new(ELeave) CCdcAcmClass;
+	CleanupStack::PushL(self);
+	self->ConstructL(aProtocolNum, aAcmControlIfcName, aAcmDataIfcName);
+	CLEANUPSTACK_POP(self);
+	return self;
+	}
+
+void CCdcAcmClass::ConstructL(const TUint8 aProtocolNum, const TDesC16& aControlIfcName, const TDesC16& aDataIfcName)
+/**
+ * 2nd-phase construction. Creates both the control and data objects.
+ * @param aProtocolNum contains the Table 17 protocol number.
+ * @param aControlIfcName contains the interface name
+ * @param aDataIfcName contains the interface name
+ */
+	{
+	TUint8 interfaceNumber;
+	TInt res;
+
+	LOGTEXT(_L8("\tabout to create control interface with name"));
+	iControl = CCdcControlInterface::NewL(*this, aProtocolNum, aControlIfcName);
+
+	LOGTEXT(_L8("\tabout to create data interface with name"));
+	iData = CCdcDataInterface::NewL(aDataIfcName);
+
+	iBreakController = CBreakController::NewL(*this);
+
+	LOGTEXT(_L8("\tabout to call GetInterfaceNumber"));
+	res = iData->GetInterfaceNumber(interfaceNumber);
+	if ( res )
+		{
+		LOGTEXT2(_L8("\tGetInterfaceNumber=%d"), res);
+		LEAVEIFERRORL(res);
+		}
+
+	LOGTEXT(_L8("\tabout to call SetupClassSpecificDescriptor"));
+	res = iControl->SetupClassSpecificDescriptor(interfaceNumber);
+	if ( res )
+		{
+		LOGTEXT2(_L8("\tSetupClassSpecificDescriptor=%d"), res);
+		LEAVEIFERRORL(res);
+		}
+	}
+
+CCdcAcmClass::~CCdcAcmClass()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	delete iControl;
+	delete iData;
+	delete iBreakController;
+	}
+
+void CCdcAcmClass::SetCallback(MHostPushedChangeObserver* aCallback)
+/**
+ * Set the ACM class callback object. This cannot be done at construction 
+ * because the ACM class and the port have different lifetimes.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcAcmClass::SetCallback aCallback=0x%08x"), aCallback);
+
+	iCallback = aCallback;
+
+	// remember that this function can also be called to
+	// unset the callback when it is given a NULL pointer
+	if ( iCallback )
+		{
+		// send off whatever has been seen from Host
+		// requests to change the line coding
+		TCommConfigV01 epocConfig;
+		ConvertUsbConfigCodingToEpoc(iUsbConfig,epocConfig);
+		iCallback->HostConfigChange(epocConfig);
+
+		// send off whatever has been seen from Host
+		// requests to set the control line state
+		iCallback->HostSignalChange(iDtrState,iRtsState);
+		}
+	
+	LOGTEXT(_L8("<<CCdcAcmClass::SetCallback"));
+	}
+
+void CCdcAcmClass::SetBreakCallback(MBreakObserver* aBreakCallback)
+/**
+ * Set the observer for break events. This cannot be done at construction 
+ * because the ACM class and the port have different lifetimes.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcAcmClass::SetBreakCallback aBreakCallback=0x%08x"), 
+		aBreakCallback);
+
+	iBreakCallback = aBreakCallback;
+
+	LOGTEXT(_L8("<<CCdcAcmClass::SetBreakCallback"));
+	}
+
+void CCdcAcmClass::ReadOneOrMore(MReadOneOrMoreObserver& aObserver, TDes8& aDes)
+/**
+ * Read from the bus a specified amount but complete if any data arrives.
+ *
+ * @param aObserver The observer to notify completion to.
+ * @param aDes Descriptor to read into
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcAcmClass::ReadOneOrMore aObserver=0x%08x"), 
+		&aObserver);
+
+	ReadOneOrMore(aObserver, aDes, aDes.Length());
+
+	LOGTEXT(_L8("<<CCdcAcmClass::ReadOneOrMore"));
+	}
+
+void CCdcAcmClass::ReadOneOrMore(MReadOneOrMoreObserver& aObserver, 
+								 TDes8& aDes, 
+								 TInt aLength)
+/**
+ * Read from the bus a specified amount but complete if any data arrives.
+ *
+ * @param aObserver The observer to notify completion to.
+ * @param aDes Descriptor to read into
+ * @param aLength Amount of data to read
+ */
+	{
+	LOGTEXT3(_L8(">>CCdcAcmClass::ReadOneOrMore aObserver=0x%08x, "
+		"aLength=%d"), 
+			&aObserver, aLength);
+
+	__ASSERT_DEBUG(iData, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iData->ReadOneOrMore(aObserver, aDes, aLength);
+
+	LOGTEXT(_L8("<<CCdcAcmClass::ReadOneOrMore"));
+	}
+
+void CCdcAcmClass::Read(MReadObserver& aObserver, TDes8& aDes)
+/**
+ * Read from the bus
+ *
+ * @param aObserver The observer to notify completion to.
+ * @param aDes Descriptor to read into.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcAcmClass::Read aObserver=0x%08x"), &aObserver);
+
+	Read(aObserver, aDes, aDes.Length());
+
+	LOGTEXT(_L8("<<CCdcAcmClass::Read"));
+	}
+
+void CCdcAcmClass::Read(MReadObserver& aObserver, TDes8& aDes, TInt aLength)
+/**
+ * Read from the bus a specified amount.
+ *
+ * @param aObserver The observer to notify completion to.
+ * @param aDes Descriptor to read into.
+ * @param aLength Amount of data to read.
+ */
+	{
+	LOGTEXT3(_L8(">>CCdcAcmClass::Read aObserver=0x%08x, aLength=%d"), 
+		&aObserver, aLength);
+
+	__ASSERT_DEBUG(iData, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iData->Read(aObserver, aDes, aLength);
+
+	LOGTEXT(_L8("<<CCdcAcmClass::Read"));
+	}
+
+void CCdcAcmClass::ReadCancel()
+/**
+ * Cancel a read request.
+ */
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG(iData, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iData->CancelRead();
+	}
+
+void CCdcAcmClass::Write(MWriteObserver& aObserver, const TDesC8& aDes)
+/**
+ * Write to the bus.
+ *
+ * @param aObserver The observer to notify completion to.
+ * @param aDes Descriptor containing the data to be written.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcAcmClass::Write aObserver=0x%08x"), 
+		&aObserver);
+
+	Write(aObserver, aDes, aDes.Length());
+
+	LOGTEXT(_L8("<<CCdcAcmClass::Write"));
+	}
+
+void CCdcAcmClass::Write(MWriteObserver& aObserver, 
+						 const TDesC8& aDes, 
+						 TInt aLength)
+/**
+ * Write to the bus the specified ammount.
+ *
+ * @param aObserver The observer to notify completion to.
+ * @param aDes Descriptor containing the data to be written.
+ * @param aLength The amount of data to write.
+ */
+	{
+	LOGTEXT3(_L8(">>CCdcAcmClass::Write aObserver=0x%08x, aLength=%d"), 
+		&aObserver, aLength);
+
+	__ASSERT_DEBUG(iData, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iData->Write(aObserver, aDes, aLength);
+
+	LOGTEXT(_L8("<<CCdcAcmClass::Write"));
+	}
+
+void CCdcAcmClass::WriteCancel()
+/**
+ * Cancel the write request.
+ */
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG(iData, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iData->CancelWrite();
+	}
+
+TInt CCdcAcmClass::HandleGetCommFeature(const TUint16 aSelector, 
+										TDes8& aReturnData)
+/**
+ * Callback for Get Comm Feature requests.
+ *
+ * @param aSelector Multiplex control for the feature is held in wValue field
+ * @param aReturnData Descriptor containing the multiplexed and idle state of 
+ *					the ACM device or the country code from ISO 3166.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcAcmClass::HandleGetCommFeature aSelector=%d"), 
+		aSelector); 
+
+	TInt ret = KErrNone;
+
+	// check the feature selector from the header and reject if invalid,
+	// otherwise deal with it.
+	switch ( aSelector )
+		{
+	case EUsbCommFeatureSelectAbstractState:
+		{
+		aReturnData.SetLength(2);
+
+		TUint8* pbuffer;
+		TUint8** ppbuffer;
+		pbuffer = &aReturnData[0];
+		ppbuffer = &pbuffer;
+		
+		CCdcControlInterface::PutU16(ppbuffer,iAcmState);
+
+		LOGTEXT2(_L8("\tAbstract State [0x%04X]"), iAcmState);
+		}
+		break;
+
+	case EUsbCommFeatureSelectCountryCode:
+		{
+#if defined(DISABLE_ACM_CF_COUNTRY_SETTING)
+
+		aReturnData.SetLength(0);
+		LOGTEXT(_L8("\tCountry Code Not Supported"));
+		ret = KErrNotSupported;
+
+#elif defined(ENABLE_ACM_CF_COUNTRY_SETTING)
+
+		aReturnData.SetLength(2);
+
+		TUint8* pbuffer;
+		TUint8** ppbuffer;
+		pbuffer = &aReturnData[0];
+		ppbuffer = &pbuffer;
+		
+		CCdcControlInterface::PutU16(ppbuffer,iCountryCode);
+
+		LOGTEXT2(_L8("\tCountry Code [0x%04X]"), iCountryCode);
+
+#endif
+		}
+		break;
+
+	default:
+		aReturnData.SetLength(0);
+		LOGTEXT(_L8("\tBad Selector"));
+		ret = KErrUnknown;
+		}
+
+	LOGTEXT2(_L8("<<CCdcAcmClass::HandleGetCommFeature ret=%d"), ret); 
+	return ret;
+	}
+
+TInt CCdcAcmClass::HandleClearCommFeature(const TUint16 aSelector)
+/**
+ * Callback for Clear Comm Feature requests
+ * @param aSelector Multiplex control for the feature is held in wValue field
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcAcmClass::HandleClearCommFeature aSelector=%d"), 
+		aSelector);
+
+	TInt ret = KErrNone;
+
+	// check the feature selector from the header and reject if invalid,
+	// otherwise deal with it.
+	switch ( aSelector )
+		{
+	case EUsbCommFeatureSelectAbstractState:
+		{
+		// reset to guaranteed-success default, so ignore return value
+		static_cast<void>(HandleNewAbstractState(EUsbAbstractStateDataMultiplex));
+		LOGTEXT2(_L8("\tAbstract State [0x%04X]"), iAcmState);
+		}
+		break;
+	
+	case EUsbCommFeatureSelectCountryCode:
+		{
+#if defined(DISABLE_ACM_CF_COUNTRY_SETTING)
+
+		LOGTEXT(_L8("\tCountry Code Not Supported"));
+		ret = KErrNotSupported;
+
+#elif defined(ENABLE_ACM_CF_COUNTRY_SETTING)
+
+		HandleNewCountryCode(KUsbCommCountryCode0);
+		LOGTEXT2(_L8("\tCountry Code [0x%04X]"), iCountryCode);
+
+#endif
+		}
+		break;
+	
+	default:
+		{
+		LOGTEXT(_L8("\tBad Selector"));
+		ret = KErrUnknown;
+		}
+		}
+
+	LOGTEXT2(_L8("<<CCdcAcmClass::HandleClearCommFeature ret=%d"), ret);
+	return ret;
+	}
+
+TInt CCdcAcmClass::HandleSetLineCoding(const TDesC8& aData)
+/**
+ * Callback for Set Line Coding requests.
+ * This function extracts the parameters from the host packet, stores them 
+ * locally, then converts them to an EPOC format and passes them up to the CSY 
+ * class.
+ * Note that we are intentionally keeping two copies of the settings in the 
+ * CSY: the "host pushed" settings and the "client pushed" settings.  Since 
+ * the EPOC machine is a "device" rather than a "host", it can't push 
+ * configuration changes to the host. We are therefore propagating host-pushed 
+ * configuration changes to the C32 client, but not propagating C32 client 
+ * configuration requests back to the host.
+ * 
+ * @param aData Descriptor containing the new data rate, stop bits, parity and 
+ * data bit settings.
+ */
+	{
+	LOG_FUNC
+
+	if (aData.Length() != 7) // TODO: magic number?
+		{
+		LOGTEXT(_L8("\t***buffer too small"));
+		return KErrGeneral;
+		}
+
+	TUint8*  pbuffer;
+	TUint8** ppbuffer;
+	pbuffer = const_cast<TUint8*>(&aData[0]);
+	ppbuffer = &pbuffer;
+
+	iUsbConfig.iRate	 =				  CCdcControlInterface::GetU32(ppbuffer);
+	iUsbConfig.iStopBits = static_cast<TUsbStopBits>(CCdcControlInterface::GetU08(ppbuffer));
+	iUsbConfig.iParity	 = static_cast<TUsbParity>(CCdcControlInterface::GetU08(ppbuffer));
+	iUsbConfig.iDataBits = static_cast<TUsbDataBits>(CCdcControlInterface::GetU08(ppbuffer));
+
+	if ( iCallback )
+		{
+		TCommConfigV01 epocConfig;
+
+		ConvertUsbConfigCodingToEpoc(iUsbConfig, epocConfig);
+
+		iCallback->HostConfigChange(epocConfig);
+		}
+
+	return KErrNone;
+	}
+
+void CCdcAcmClass::SetDefaultAcm()
+/**
+ * Reset the data fields to a set of known default values. Will be used when 
+ * we implement restart, which involves a host re-enumeration without 
+ * destroying the ACM class, so we need a function to reset the ACM to 
+ * defaults.
+ */
+	{
+	iUsbConfig.iRate	 = 115200;
+	iUsbConfig.iStopBits = EUsbStopBitOne;
+	iUsbConfig.iParity	 = EUsbParityNone;
+	iUsbConfig.iDataBits = EUsbDataBitsEight;
+
+	iAcmState	 = EUsbAbstractStateDataMultiplex;
+	iCountryCode = 0x2A2A;	// 0x2A2A is "**"- just an invalid code
+
+	iAcmDataMultiplex = (iAcmState & EUsbAbstractStateDataMultiplex) 
+		? ETrue : EFalse;
+	iAcmIdleSetting   = (iAcmState & EUsbAbstractStateIdleSetting) 
+		? ETrue : EFalse;
+
+	iRtsState = EFalse;
+	iDtrState = EFalse;
+
+	iRingState = EFalse;
+	iDsrState  = EFalse;
+	iDcdState  = EFalse;
+
+	iBreakActive = EFalse;
+	}
+
+void CCdcAcmClass::ConvertUsbConfigCodingToEpoc(const TUsbConfig& aUsbConfig, 
+								  TCommConfigV01& aEpocConfig)
+/**
+ * Convert configuration information received from a Host in "USB" format to 
+ * the native "EPOC" configuration format.
+ *
+ * @param aUsbConfig	The USB configuration to be converted from.
+ * @param aEpocConfig	The EPOC configuration to be converted to.
+ */
+	{
+	switch ( aUsbConfig.iDataBits )
+		{
+	case EUsbDataBitsFive:
+		aEpocConfig.iDataBits = EData5;
+		break;
+
+	case EUsbDataBitsSix:
+		aEpocConfig.iDataBits = EData6;
+		break;
+
+	case EUsbDataBitsSeven:
+		aEpocConfig.iDataBits = EData7;
+		break;
+
+	case EUsbDataBitsEight:
+		aEpocConfig.iDataBits = EData8;
+		break;
+
+	// EPOC doesn't support this, so map it to "8" for the time being...
+	case EUsbDataBitsSixteen:		
+		aEpocConfig.iDataBits = EData8;
+		break;
+
+	// Map any other signals to "8"...
+	default:						
+		aEpocConfig.iDataBits = EData8;
+		break;
+		}
+
+	switch ( aUsbConfig.iStopBits )
+		{
+	case EUsbStopBitOne:
+		aEpocConfig.iStopBits = EStop1;
+		break;
+
+	// EPOC doesn't have any "1.5" setting, so go for "1".
+	case EUsbStopBitOnePtFive:		
+		aEpocConfig.iStopBits = EStop1;
+		break;
+
+	case EUsbStopBitTwo:
+		aEpocConfig.iStopBits = EStop2;
+		break;
+
+	// Map any other signals to "1"...
+	default:						
+		aEpocConfig.iStopBits = EStop1;
+		break;
+		}
+
+	switch ( aUsbConfig.iParity )
+		{
+	case EUsbParityNone:
+		aEpocConfig.iParity = EParityNone;
+		break;
+
+	case EUsbParityOdd:
+		aEpocConfig.iParity = EParityOdd;
+		break;
+
+	case EUsbParityEven:
+		aEpocConfig.iParity = EParityEven;
+		break;
+
+	case EUsbParityMark:
+		aEpocConfig.iParity = EParityMark;
+		break;
+
+	case EUsbParitySpace:
+		aEpocConfig.iParity = EParitySpace;
+		break;
+
+	// Map any other signals to "No Parity"...
+	default:						
+		aEpocConfig.iParity = EParityNone;
+		break;
+		}
+
+	static const TUint32 KUsbDataRate[] = { 50,	75, 	110,	
+									 134,	150,	300,		
+									 600,	1200,	1800,		
+									 2000,	2400,	3600,
+									 4800,	7200,	9600,	
+									 19200, 38400,	57600,		
+									 115200,230400, 460800, 	
+									 576000,1152000,4000000};
+
+	static const TBps KEpocDataRate[] = {	EBps50,    EBps75,	   EBps110, 
+									EBps134,   EBps150,    EBps300, 
+									EBps600,   EBps1200,   EBps1800,	
+									EBps2000,  EBps2400,   EBps3600,
+									EBps4800,  EBps7200,   EBps9600,	
+									EBps19200, EBps38400,  EBps57600,	
+									EBps115200,EBps230400, EBps460800,	
+									EBps576000,EBps1152000,EBps4000000};
+
+	aEpocConfig.iRate = EBpsSpecial;	// Default to "Special"
+	TInt arraySize = sizeof(KUsbDataRate)/sizeof(TUint32);
+	for ( TInt i = 0 ; i < arraySize ; i++ )
+		{
+		if ( aUsbConfig.iRate == KUsbDataRate[i] )
+			{
+			aEpocConfig.iRate = KEpocDataRate[i];
+			break;
+			}
+		}
+	}
+
+TInt CCdcAcmClass::HandleNewAbstractState(const TUint16 aAbstractState)
+/**
+ * Handle new Abstract State as received from Host, check values
+ * and inform client watcher (if registered)
+ * @param aAbstractState	The new Abstract State which contains
+ *							significant bits D0 and D1 where:
+ *
+ *	D0 controls 'idle setting'			 -> iAcmIdleSetting
+ *	D1 controls 'data multiplexed state' -> iAcmDataMultiplex
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcAcmClass::HandleNewAbstractState aAbstractState=%d"), 
+		aAbstractState);
+
+	TBool	multiplex;
+	TBool	idle;
+
+	TUint16 newstate;
+
+	TInt ret;
+
+	// collect local booleans from incoming combo ready to do local
+	// discrepancy check
+	multiplex = (aAbstractState & EUsbAbstractStateDataMultiplex) 
+		? ETrue : EFalse;
+	idle	  = (aAbstractState & EUsbAbstractStateIdleSetting) 
+		? ETrue : EFalse;
+
+	// apply any necessary overrides due to incomplete ACM class
+	// support (this may change the local booleans and also may be
+	// the reason to inform caller of a failure)
+	ret = KErrNone;
+
+	if ( multiplex != iAcmDataMultiplex )
+		{
+#if defined(DISABLE_ACM_CF_DATA_MULTIPLEX)
+		// if this selector is disabled then the attempt to change the
+		// bit must fail
+		ret = KErrNotSupported;
+
+		multiplex = iAcmDataMultiplex;
+#endif
+		}
+
+	if ( idle != iAcmIdleSetting )
+		{
+#if defined(DISABLE_ACM_CF_IDLE_SETTING)
+		// if this selector is disabled then the attempt to change the
+		// bit must fail
+		ret = KErrNotSupported;
+
+		idle = iAcmIdleSetting;
+#endif
+		}
+
+	// save the new booleans into the private store
+	iAcmDataMultiplex = multiplex;
+	iAcmIdleSetting   = idle;
+
+	// recreate the private combo from these booleans
+	newstate = static_cast<TUint16>(	
+			( iAcmIdleSetting ? EUsbAbstractStateIdleSetting : EUsbAbstractStateNoBits )
+		|	( iAcmDataMultiplex ? EUsbAbstractStateDataMultiplex : EUsbAbstractStateNoBits)
+		);
+
+	// discrepancy check to see if the client application needs to be 
+	// informed, note that the callback may not have been placed.
+	if( iAcmState != newstate )
+		{
+		LOGTEXT2(_L8("\tNew Combo [0x%04X]"), newstate);
+
+		if ( iCallback )
+			{
+			// If there was such a function in class 
+			// MHostPushedChangeObserver, notify 
+			// via iCallback->HostAbstractStateChange(newstate);
+			LOGTEXT(_L8("\tHas No Notification Method in class MHostPushedChangeObserver"));
+			}
+		}
+
+	// and save the new state ready for next check
+	iAcmState = newstate;
+
+	LOGTEXT2(_L8("<<CCdcAcmClass::HandleNewAbstractState ret=%d"), ret);
+	return ret;
+	}
+
+TInt CCdcAcmClass::HandleNewCountryCode(const TUint16 aCountryCode)
+/**
+ * Handle new Country Setting as received from Host, check values
+ * and inform client watcher (if registered)
+ *
+ * @param aCountryCode	The new Country Code as defined in ISO-3166
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcAcmClass::HandleNewCountryCode aCountryCode=%d"), 
+		aCountryCode);
+
+	TInt ret;
+
+#if defined(DISABLE_ACM_CF_COUNTRY_SETTING)
+
+	// cite the incoming parameter to suppress 'unreferenced formal parameter'
+	// warning and then set the return value to show this code does not handle
+	// the country code.
+	(void)aCountryCode;
+
+	ret = KErrNotSupported;
+
+#else
+
+	// check the received code against the array in the descriptor
+	// and confirm it is one of those present, otherwise return
+	// 'unknown' : for now, just pretend it always works
+	iCountryCode = aCountryCode;
+
+	ret = KErrNone;
+
+#endif
+
+	LOGTEXT2(_L8("<<CCdcAcmClass::HandleNewCountryCode ret=%d"), ret);
+	return ret;
+	}
+
+TInt CCdcAcmClass::HandleSendEncapCommand(const TDesC8& /*aData*/)
+/**
+ * Callback for Send Encapsulated Command requests
+ *
+ * @param aData Pointer to the Encapsulated message
+ */
+	{
+	LOG_FUNC
+
+	LOGTEXT(_L8("\t***not supported"));
+
+	return KErrNotSupported;
+	}
+
+TInt CCdcAcmClass::HandleGetEncapResponse(TDes8& /*aReturnData*/)
+/**
+ * Callback for Get Encapsulated Response requests
+ *
+ * @param aReturnData Pointer to the Response field
+ */
+	{
+	LOG_FUNC
+
+	LOGTEXT(_L8("\t***not supported"));
+
+	return KErrNotSupported;
+	}
+
+TInt CCdcAcmClass::HandleSetCommFeature(const TUint16 aSelector, 
+										const TDes8& aData)
+/**
+ * Callback for Set Comm Feature requests.
+ *
+ * @param aSelector Multiplex control for the feature is held in wValue field
+ * @param aData 	Descriptor containing the multiplexed and idle state of 
+ *					the ACM device or the country code from ISO 3166.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcAcmClass::HandleSetCommFeature aSelector=%d"), 
+		aSelector);
+
+	// reject any message that has malformed data
+	if ( aData.Length() != 2 )
+		{
+		LOGTEXT2(_L8("\t***aData.Length (%d) incorrect"), aData.Length());
+		LOGTEXT2(_L8("<<CCdcAcmClass::HandleSetCommFeature ret=%d"), 
+			KErrArgument);
+		return KErrArgument;
+		}
+
+	TInt ret = KErrNone;
+
+	// check the feature selector from the header and reject if invalid,
+	// otherwise deal with it.
+	switch ( aSelector )
+		{
+	case EUsbCommFeatureSelectAbstractState:
+		{
+		TUint16 newstate;
+
+		TUint8* pbuffer;
+		TUint8** ppbuffer;
+		pbuffer = const_cast<TUint8*>(&aData[0]);
+		ppbuffer = &pbuffer;
+		
+		newstate = CCdcControlInterface::GetU16(ppbuffer);
+
+		if ( newstate != iAcmState )
+			{
+			ret = HandleNewAbstractState(newstate);
+
+			LOGTEXT4(_L8("\tHandleNewAbstractState=%d [0x%04X]->[0x%04X]"),
+					ret, iAcmState, newstate);
+			}
+		}
+		break;
+
+	case EUsbCommFeatureSelectCountryCode:
+		{
+#if defined(DISABLE_ACM_CF_COUNTRY_SETTING)
+
+		LOGTEXT(_L8("Country Code Not Supported"));
+		ret = KErrNotSupported;
+
+#elif defined(ENABLE_ACM_CF_COUNTRY_SETTING)
+
+		TUint16 newcountry;
+
+		TUint8* pbuffer;
+		TUint8** ppbuffer;
+		pbuffer = &aData[0];
+		ppbuffer = &pbuffer;
+
+		newcountry = CCdcControlInterface::GetU16(ppbuffer);
+
+		if( newcountry != iCountryCode )
+			{
+			ret = HandleNewCountryCode(newcountry);
+
+			LOGTEXT4(_L8("\tHandleNewCountryCode=%d [0x%04X]->[0x%04X]"),
+					ret, iCountryCode, newcountry);
+			}
+
+#endif
+		break;
+		}
+
+	default:
+		{
+		LOGTEXT(_L8("\tBad Selector"));
+		ret = KErrUnknown;
+		}
+		}
+
+	LOGTEXT2(_L8("<<CCdcAcmClass::HandleSetCommFeature ret=%d"), ret);
+	return ret;
+	}
+
+TInt CCdcAcmClass::HandleGetLineCoding(TDes8& aReturnData)
+/**
+ * Callback for Get Line Coding requests.
+ * Note that this function returns the configuration set by the host, rather 
+ * than the one configured by the C32 client.
+ *
+ * @param aReturnData Descriptor containing the data rate, number of stop 
+ * bits, parity and data bits.
+ */
+	{
+	LOG_FUNC
+
+	aReturnData.SetLength(7);
+
+	TUint8* pbuffer;
+	TUint8** ppbuffer;
+	pbuffer = &aReturnData[0];
+	ppbuffer = &pbuffer;
+
+	CCdcControlInterface::PutU32(ppbuffer,		   iUsbConfig.iRate    );
+	CCdcControlInterface::PutU08(ppbuffer, static_cast<TUint8>(iUsbConfig.iStopBits));
+	CCdcControlInterface::PutU08(ppbuffer, static_cast<TUint8>(iUsbConfig.iParity  ));
+	CCdcControlInterface::PutU08(ppbuffer, static_cast<TUint8>(iUsbConfig.iDataBits));
+
+	return KErrNone;
+	}
+
+TInt CCdcAcmClass::HandleSetControlLineState(TBool aRtsState, TBool aDtrState)
+/**
+ * Callback for Set Control Line State requests
+ *
+ * @param aRtsState RTS state.
+ * @param aDtrState DTR state.
+ */
+	{
+	LOGTEXT3(_L8(">>CCdcAcmClass::HandleSetControlLineState aRtsState=%d, "
+		"aDtrState=%d"),
+			aRtsState, aDtrState);
+
+	iRtsState	= aRtsState;
+	iDtrState	= aDtrState;
+	if ( iCallback )
+		{
+		iCallback->HostSignalChange(iDtrState,iRtsState);
+		}
+
+	LOGTEXT(_L8("<<CCdcAcmClass::HandleSetControlLineState ret=0"));
+	return KErrNone;
+	}
+
+TInt CCdcAcmClass::HandleSendBreak(TUint16 aDuration)
+/**
+ * Callback for Send Break requests
+ *
+ * @param aDuration Duration of the break in milliseconds.
+ */
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taDuration = %d"), aDuration);
+
+	TInt ret = KErrNone;
+
+	// timing value as given is checked for 'special' values
+	if ( aDuration == 0 )
+		{
+		ret = iBreakController->BreakRequest(CBreakController::EHost,
+			CBreakController::EInactive);
+		}
+	else if ( aDuration == 0xFFFF )
+		{
+		ret = iBreakController->BreakRequest(CBreakController::EHost,
+			CBreakController::ELocked); // i.e. locked ON, until further 
+		// notice.
+		}
+	else
+		{
+		ret = iBreakController->BreakRequest(CBreakController::EHost, 
+			CBreakController::ETiming,
+			// Convert from host-supplied milliseconds to microseconds.
+			aDuration*1000);
+		}
+
+	LOGTEXT2(_L8("\tret = %d"), ret);
+	return ret;
+	}
+
+TInt CCdcAcmClass::SendSerialState(TBool aRing, TBool aDsr, TBool aDcd)
+/**
+ * Send a change in serial state to the host.
+ *
+ * Note that Overrun, Parity and Framing errors are not currently supported, 
+ * so are stubbed out with EFalse.
+ *
+ * Note that the BREAK signal is managed locally in the break controller
+ * Active Object.
+ */
+	{
+	LOGTEXT4(_L8(">>CCdcAcmClass::SendSerialState aRing=%d, "
+		"aDsr=%d, aDcd=%d"), 
+			aRing, aDsr, aDcd);
+
+	// stub non-supported flags
+	TBool overrun = EFalse;
+	TBool parity  = EFalse;
+	TBool framing = EFalse;
+
+	// Save incoming state flags for possible use when notifying break
+	// changes.
+	iRingState = aRing;
+	iDsrState  = aDsr;
+	iDcdState  = aDcd;
+
+	// send new state off to the host (this will use an interrupt transfer, 
+	// and will handle all discrepancy checking to suppress same-state 
+	// notifications)
+	TInt ret = iControl->SendSerialState(overrun,
+		parity,
+		framing,
+		aRing,
+		BreakActive(),
+		aDsr,
+		aDcd);
+
+	LOGTEXT2(_L8("<<CCdcAcmClass::SendSerialState ret=%d"), ret);
+	return ret;
+	}
+
+TBool CCdcAcmClass::BreakActive() const
+/**
+ * Simply pass the state of the local BREAK flag back to caller
+ *
+ * @return Break flag.
+ */
+	{
+	return iBreakActive;
+	}
+
+TBool CCdcAcmClass::RingState() const
+/**
+ * Accessor for the ring state.
+ *
+ * @return Whether RNG is set or not.
+ */
+	{
+	return iRingState;
+	}
+
+TBool CCdcAcmClass::DsrState() const
+/**
+ * Accessor for the DSR state.
+ *
+ * @return Whether DSR is set or not.
+ */
+	{
+	return iDsrState;
+	}
+
+TBool CCdcAcmClass::DcdState() const
+/**
+ * Accessor for the DCD state.
+ *
+ * @return Whether DCD is set or not.
+ */
+	{
+	return iDcdState;
+	}
+
+void CCdcAcmClass::SetBreakActive(TBool aBreakActive)
+/**
+ * Sets the break flag on or off.
+ *
+ * @param aBreakActive The break flag is set to this value.
+ */
+	{
+	iBreakActive = aBreakActive;
+	}
+
+MHostPushedChangeObserver* CCdcAcmClass::Callback()
+/**
+ * Accessor for the MHostPushedChangeObserver callback.
+ *
+ * @return The observer of host-pushed changes.
+ */
+	{
+	return iCallback;
+	}
+
+MBreakObserver* CCdcAcmClass::BreakCallback()
+/**
+ * Accessor for the MBreakObserver callback.
+ *
+ * @return The observer of break changes.
+ */
+	{
+	return iBreakCallback;
+	}
+
+TInt CCdcAcmClass::BreakRequest(CBreakController::TRequester aRequester, 
+								CBreakController::TState aState, 
+								TTimeIntervalMicroSeconds32 aDelay)
+/**
+ * Make a break-related request.
+ *
+ * @param aRequester The entity requesting the break.
+ * @param aState The request- either a locked break, a timed break, or to 
+ * make the break inactive.
+ * @param aDelay The time delay, only used for a timed break.
+ * @return Error, for instance if a different entity already owns the break.
+ */
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG(iBreakController, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	TInt err = iBreakController->BreakRequest(aRequester, aState, aDelay);
+	LOGTEXT2(_L8("\tBreakRequest = %d"), err);
+	return err;
+	}
+
+void CCdcAcmClass::NotifyDataAvailable(MNotifyDataAvailableObserver& aObserver)
+/**
+ * Notify the caller when data is available to be read from the LDD.
+ *
+ * @param aObserver The observer to notify completion to.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcAcmClass::NotifyDataAvailable aObserver=0x%08x"), &aObserver);
+
+	__ASSERT_DEBUG(iData, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iData->NotifyDataAvailable(aObserver);
+
+	LOGTEXT(_L8("<<CCdcAcmClass::NotifyDataAvailable"));
+	}
+
+void CCdcAcmClass::NotifyDataAvailableCancel()
+/**
+ * Cancel the request to be notified (when data is available to be read from the LDD).
+ */
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG(iData, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iData->CancelNotifyDataAvailable();
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/CdcControlInterface.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,509 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <e32std.h>
+#include <e32base.h>
+#include <e32svr.h>
+#include <c32comm.h>
+#include "CdcControlInterface.h"
+#include "CdcControlInterfaceReader.h"
+#include "ClassDescriptor.h"
+#include "CdcAcmClass.h"
+#include "AcmPanic.h"
+#include "AcmUtils.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CCdcControlInterface::CCdcControlInterface(const TUint8 aProtocolNum, const TDesC16& aIfcName)
+/**
+ * Constructor using interface name.
+ * @param aProtocolNum Contains the Table 17 protocol number.
+ * @param aIfcName contains the interface name
+ */
+ :	CCdcInterfaceBase(aIfcName), 
+	iSerialState(0xFFFF),
+	iProtocolNum(aProtocolNum)
+	{
+	}
+
+CCdcControlInterface* CCdcControlInterface::NewL(CCdcAcmClass& aParent, const TUint8 aProtocolNum, const TDesC16& aIfcName)
+/**
+ * Create a new CCDCCommClass object and construct it using interface name
+ * This call will return an object with a valid USB configuration
+ *
+ * @param aParent Pointer to the Port using this object
+ * @param aProtocolNum contains the Table 17 protocol number.
+ * @param aIfcName Contains the interface name
+ * @return A pointer to the new object
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	LOGTEXT2(_L("\tControl Ifc Name = %S"), &aIfcName);
+
+	CCdcControlInterface* self = new(ELeave) CCdcControlInterface(aProtocolNum, aIfcName);
+	CleanupStack::PushL(self);
+	self->ConstructL(aParent);
+	CLEANUPSTACK_POP(self);
+	return self;
+	}
+
+void CCdcControlInterface::ConstructL(CCdcAcmClass& aParent)
+/**
+ * 2nd-phase construction.
+ * This call registers the object with the USB device driver
+ *
+ * @param aParent The ACM class.
+ */
+	{
+	BaseConstructL();
+
+	iReader  = CCdcControlInterfaceReader::NewL(aParent, iLdd);
+
+	LOGTEXT2(_L8("\tcreated CdcControlInterface iProtocolNum = %d"), iProtocolNum);
+	}
+
+TInt CCdcControlInterface::SetUpInterface()
+/**
+ * Set up the interface for use. This involves finding a "Interrupt IN" 
+ * endpoint and, if found, configuring the interface.
+ */
+	{
+	LOGTEXT(_L8(">>CCdcControlInterface::SetUpInterface"));
+
+	TUsbDeviceCaps dCaps;
+	TInt ret = iLdd.DeviceCaps(dCaps);
+	LOGTEXT(_L8("\tchecking result of DeviceCaps"));
+	if ( ret )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), ret);
+		return ret;
+		}
+
+	const TUint KRequiredNumberOfEndpoints = 1; // in addition to endpoint 0.
+
+	const TUint totalEndpoints = static_cast<TUint>(dCaps().iTotalEndpoints);
+	LOGTEXT2(_L8("\tiTotalEndpoints = %d"), totalEndpoints);
+	if ( totalEndpoints < KRequiredNumberOfEndpoints )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), 
+			KErrGeneral);
+		return KErrGeneral;
+		}
+	
+	// Endpoints
+	TUsbcEndpointData data[KUsbcMaxEndpoints];
+	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
+	ret = iLdd.EndpointCaps(dataptr);
+	LOGTEXT(_L8("\tchecking result of EndpointCaps"));
+	if ( ret )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), ret);
+		return ret;
+		}
+
+	// Set the active interface
+	TUsbcInterfaceInfoBuf ifc;
+	TBool epFound = EFalse;
+	for ( TUint i = 0 ; i < totalEndpoints ; i++ )
+		{
+		const TUsbcEndpointCaps* caps = &data[i].iCaps;
+		__ASSERT_DEBUG(caps, 
+			_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+		if (data[i].iInUse)
+			{
+			continue;
+			}
+
+		if ((caps->iTypesAndDir & (KUsbEpTypeInterrupt | KUsbEpDirIn)) == 
+			(KUsbEpTypeInterrupt | KUsbEpDirIn))
+			{
+			// EEndpoint1 is interrupt endpoint
+			ifc().iEndpointData[0].iType  = KUsbEpTypeInterrupt;
+			ifc().iEndpointData[0].iDir   = KUsbEpDirIn; 
+
+			//get the max packet size it can potentially support
+			//it's possible that it can support Isoch (1023) which is greater
+			//than max for Int at 64
+			TInt maxSize = Min(caps->MaxPacketSize(), KMaxPacketTypeInterrupt);
+			
+			ifc().iEndpointData[0].iSize  = maxSize;
+
+			ifc().iEndpointData[0].iInterval = KPollInterval; 
+			epFound = ETrue;
+			break;
+			}
+		}
+	LOGTEXT(_L8("\tchecking epFound"));
+	if ( !epFound )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), 
+			KErrGeneral);
+		return KErrGeneral;
+		}
+
+	ifc().iString = &iIfcName;
+	ifc().iTotalEndpointsUsed = KRequiredNumberOfEndpoints;
+	// Codes taken from USBCDC 1.1.
+	ifc().iClass.iClassNum	  = 0x02; // Table 15- Communication Interface Class
+	ifc().iClass.iSubClassNum = 0x02; // Table 16- Abstract Control Model
+	ifc().iClass.iProtocolNum = iProtocolNum; // Table 17
+
+	LOGTEXT(_L8("\tabout to call SetInterface"));
+	// Zero effectively indicates that alternate interfaces are not used.
+	ret = iLdd.SetInterface(0, ifc);
+
+	LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), ret);
+	return ret;
+	}
+
+TInt CCdcControlInterface::SetupClassSpecificDescriptor(
+							TUint8 aDataInterfaceNumber)
+/**
+ * Setup the Class Descriptors
+ *
+ * @param aDataInterfaceNumber The interface number of the data class
+ * @return Error.
+ */
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taDataInterfaceNumber = %d"), aDataInterfaceNumber);
+
+	TInt res;
+
+	TUsbCsClassDescriptor descriptor;
+
+	// Header Functional Descriptor- table 26
+	descriptor.iHdrSize 		 = 0x05; // bFunctionLength
+	descriptor.iHdrType 		 = 0x24; // bDescriptorType- CS_INTERFACE
+	descriptor.iHdrSubType		 = 0x00; // Table 25- Header FD
+	descriptor.iHdrBcdCDC		 = 0x0110; // release number
+
+	// Abstract Control Management Functional Descriptor- table 28
+	descriptor.iAcmSize 		 = 0x04; // bFunctionLength
+	descriptor.iAcmType 		 = 0x24; // bDescriptorType- CS_INTERFACE
+	descriptor.iAcmSubType		 = 0x02; // Table 25- ACM FD
+	descriptor.iAcmCapabilities  = 0x0f; // capabilities- all
+
+	// Union functional descriptor- table 33
+	descriptor.iUnSize			 = 0x05; // bFunctionLength
+	descriptor.iUnType			 = 0x24; // bDescriptorType- CS_INTERFACE
+	descriptor.iUnSubType		 = 0x06; // Table 25- Union FD
+	// Set the control interface as the master...
+	res = GetInterfaceNumber(descriptor.iUnMasterInterface);
+	// ... and the data interface as the slave.
+	descriptor.iUnSlaveInterface = aDataInterfaceNumber;
+
+#if defined(DISABLE_ACM_CF_COUNTRY_SETTING)
+
+	// no functional descriptor needed
+
+#elif defined(ENABLE_ACM_CF_COUNTRY_SETTING)
+
+	// CDC Country Selection Functional Descriptor
+	descriptor.iCsSize			 = 0x04 + (0x02*KUsbCommNumCountries); // bFunctionLength
+	descriptor.iCsType			 = 0x24; // bDescriptorType- CS_INTERFACE
+	descriptor.iCsSubType		 = 0x07; // Table 25- Country Selection FD
+	descriptor.iCsRelDate		 = 0x07; // Release date of ISO3166 country codes.
+	descriptor.iCsCountryCode[0] = KUsbCommCountryCode0; // Country cide
+
+#endif
+
+	if ( res )
+		{
+		LOGTEXT2(_L8("\t***GetInterfaceNumber=%d"), res);
+		return res;
+		}
+
+	LOGTEXT(_L8("\tabout to call SetCSInterfaceDescriptorBlock"));
+	res = iLdd.SetCSInterfaceDescriptorBlock(0, descriptor.Des());
+	if ( res )
+		{
+		LOGTEXT2(_L8("\t***SetCSInterfaceDescriptorBlock=%d"), res);
+		return res;
+		}
+
+	return KErrNone;
+	}
+
+CCdcControlInterface::~CCdcControlInterface()
+/**
+ * Destructor
+ */
+	{
+	LOG_FUNC
+
+	delete iReader;
+	}
+
+/**
+ * Special data object used to send a NETWORK_CONNECTION notification
+ * up to the (USB) Host, using whatever size is available on the
+ * control endpoint (derived in the driver below)
+ */
+const TUint KUSBNotificationNetworkConnectionSize = 8;
+
+NONSHARABLE_CLASS(TUSBNotificationNetworkConnection)
+	{
+public:
+	TUint8	bmRequestType;	///< Request type
+	TUint8	bNotification;	///< Notification number
+	TUint16 wValue; 		///< Notification value
+	TUint16 wIndex; 		///< Notification index
+	TUint16 wLength;		///< Notification length
+public:
+	TDes8&	PackBuffer();
+
+private:
+	TBuf8<KUSBNotificationNetworkConnectionSize> iBuffer;
+	};
+
+TDes8& TUSBNotificationNetworkConnection::PackBuffer()
+/**
+ * This function packs the TUSBNotificationSerialState class into a 
+ * byte buffer with the correct byte alignment for transmission on 
+ * the little-endian USB bus.
+ */
+	{
+	iBuffer.SetLength(KUSBNotificationNetworkConnectionSize);
+
+	iBuffer[0] = bmRequestType;
+	iBuffer[1] = bNotification;
+	iBuffer[2] = static_cast<TUint8>( wValue	& 0x00ff);
+	iBuffer[3] = static_cast<TUint8>((wValue	& 0xff00) >> 8);
+	iBuffer[4] = static_cast<TUint8>( wIndex	& 0x00ff);
+	iBuffer[5] = static_cast<TUint8>((wIndex	& 0xff00) >> 8);
+	iBuffer[6] = static_cast<TUint8>( wLength & 0x00ff);
+	iBuffer[7] = static_cast<TUint8>((wLength & 0xff00) >> 8);
+
+	return iBuffer;
+	}
+
+TInt CCdcControlInterface::SendNetworkConnection(TBool aValue)
+/**
+ * Sends a Network Connection message to the host.
+ * Note that this function has not been tested. It is included for 
+ * completeness as it may need to be used in modem (DCE) mode. However, it is 
+ * unclear how a C32 client would indicate to the CSY that a network 
+ * connection had been established.
+ *
+ * @param aValue	ETrue if Network Connected
+ * @return Error.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcControlInterface::SendNetworkConnection aValue=%d"), 
+		aValue);
+
+	// form the message and prime it down to the interrupt handler
+	// (that is 'interrupt' in the USB sense)
+
+	// Note that this does not need to be aware of endian-ness, this
+	// is taken care of in the PackBuffer() function.
+	TUSBNotificationNetworkConnection notification;
+
+	notification.bmRequestType = 0xA1;
+	notification.bNotification = 0x00; // NETWORK_CONNECTION
+	notification.wValue 	   = static_cast<TUint16>((aValue)?0x0001:0x0000); //1 - connected, 0 - disconnected
+	notification.wIndex 	   = static_cast<TUint16>((aValue)?0x0001:0x0000);
+	notification.wLength       = 0x00;
+
+	TInt ret = WriteData(EEndpoint1, 
+		notification.PackBuffer(), 
+		notification.PackBuffer().Length());
+
+	LOGTEXT2(_L8("<<CCdcControlInterface::SendNetworkConnection ret=%d"), ret);
+	return ret;
+	}
+
+/**
+ * Special data object used to send a SERIAL_STATE notification
+ * up to the (USB) Host, using whatever size is available on the
+ * control endpoint (derived in the driver below)
+ */
+const TUint KUSBNotificationSerialStateSize = 10;
+
+NONSHARABLE_CLASS(TUSBNotificationSerialState)
+	{
+public:
+	TUint8	bmRequestType;	///< Request type
+	TUint8	bNotification;	///< Notification number
+	TUint16 wValue; 		///< Notification value
+	TUint16 wIndex; 		///< Notification index
+	TUint16 wLength;		///< Notification length
+	TUint16 wData;			///< 2-byte data payload
+public:
+	TDes8&	PackBuffer();
+
+private:
+	TBuf8<KUSBNotificationSerialStateSize> iBuffer;
+	};
+
+TDes8& TUSBNotificationSerialState::PackBuffer()
+/**
+ * This function packs the TUSBNotificationSerialState class into a 
+ * byte buffer with the correct byte alignment for transmission on 
+ * the little-endian USB bus.
+ */
+	{
+	iBuffer.SetLength(KUSBNotificationSerialStateSize);
+
+	iBuffer[0] = bmRequestType;
+	iBuffer[1] = bNotification;
+	iBuffer[2] = static_cast<TUint8>( wValue	& 0x00ff);
+	iBuffer[3] = static_cast<TUint8>((wValue	& 0xff00) >> 8);
+	iBuffer[4] = static_cast<TUint8>( wIndex	& 0x00ff);
+	iBuffer[5] = static_cast<TUint8>((wIndex	& 0xff00) >> 8);
+	iBuffer[6] = static_cast<TUint8>( wLength & 0x00ff);
+	iBuffer[7] = static_cast<TUint8>((wLength & 0xff00) >> 8);
+	iBuffer[8] = static_cast<TUint8>( wData & 0x00ff);
+	iBuffer[9] = static_cast<TUint8>((wData & 0xff00) >> 8);
+
+	return iBuffer;
+	}
+
+TInt CCdcControlInterface::SendSerialState(TBool aOverRun, 
+									 TBool aParity, 
+									 TBool aFraming, 
+									 TBool aRing,
+									 TBool aBreak, 
+									 TBool aTxCarrier, 
+									 TBool aRxCarrier)
+/**
+ * Sends a Serial State message to the host
+ * 
+ * @param aOverRun True if data discarded due to overrun
+ * @param aParity True if a parity error has occured
+ * @param aFraming True if a framing error has occured
+ * @param aRing True if the device is Ringing
+ * @param aBreak True if the device is detecting a break condition
+ * @param aTxCarrier True if the transmit carrier is present
+ * @param aRxCarrier True if the receive carrier is present
+ * @return Error.
+ */
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taOverRun=%d"), aOverRun);
+	LOGTEXT2(_L8("\taParity=%d"), aParity);
+	LOGTEXT2(_L8("\taFraming=%d"), aFraming);
+	LOGTEXT2(_L8("\taRing=%d"), aRing);
+	LOGTEXT2(_L8("\taBreak=%d"), aBreak);
+	LOGTEXT2(_L8("\taTxCarrier=%d"), aTxCarrier);
+	LOGTEXT2(_L8("\taRxCarrier=%d"), aRxCarrier);
+
+	// First work out what might need to be sent by assembling the bits into 
+	// the correct places. See CDC spec table 69 (UART state bitmap values).
+	TUint16 data = static_cast<TUint16>
+					(
+						(aRxCarrier 	) |
+						(aTxCarrier << 1) |
+						(aBreak 	<< 2) |
+						(aRing		<< 3) |
+						(aFraming	<< 4) |
+						(aParity	<< 5) |
+						(aOverRun	<< 6)
+					);
+
+	// now check to see if this has created a different state than
+	// last time it was sent, if it is the same, don't bother to
+	// send it off.
+	if ( data == iSerialState )
+		{
+		LOGTEXT(_L8("\tdata == iSerialState"));
+		return KErrNone;
+		}
+
+	// state is different, store local to the class object ready for
+	// testing next time through
+	iSerialState = data;
+
+	// now form the message and prime it down to the interrupt handler
+	// (that is 'interrupt' in the USB sense)
+
+	// Note that this does not need to be aware of endian-ness, this
+	// is taken care of in the PackBuffer() function.
+	TUSBNotificationSerialState notification;
+
+	notification.bmRequestType = 0xA1;
+	notification.bNotification = 0x20; // SERIAL_STATE
+	notification.wValue 	   = 0x0000;
+	notification.wIndex 	   = 0x0000;
+	notification.wLength	   = 0x0002;
+	notification.wData		   = data;
+
+	TInt ret = WriteData(	EEndpoint1, 
+							notification.PackBuffer(), 
+							notification.PackBuffer().Length());
+	LOGTEXT2(_L8("\tWriteData = %d"), ret);
+
+	return ret;
+	}
+
+TInt CCdcControlInterface::WriteData(TEndpointNumber aEndPoint, 
+							   TDes8& aDes, 
+							   TInt aLength)
+/**
+ *
+ *
+ * @param aEndPoint
+ * @param aDes
+ * @param aLength
+ */
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taEndpoint=%d"), aEndPoint);
+
+	TInt ret;
+	RTimer timer;
+	ret = timer.CreateLocal();
+	if ( ret )
+		{
+		LOGTEXT2(_L8("\ttimer.CreateLocal = %d- returning"), ret);
+		return ret;
+		}
+	TRequestStatus status;
+	TRequestStatus timerStatus;
+	LOGTEXT(_L8("\tAttempting to write data to control interface"));
+	iLdd.Write(status, aEndPoint, aDes, aLength);
+	timer.After(timerStatus, KWriteDataTimeout);
+	User::WaitForRequest(status, timerStatus);
+	if ( timerStatus != KRequestPending )
+		{
+		// Timeout occurred, silently ignore error condition.
+		// Assuming that the line has been disconnected
+		LOGTEXT(_L8("CCdcControlInterface::WriteData() - Timeout occurred"));
+		iLdd.WriteCancel(aEndPoint);
+		User::WaitForRequest(status);
+		ret = timerStatus.Int();
+		}
+	else
+		{
+		LOGTEXT(_L8("CCdcControlInterface::WriteData() - Write completed"));
+		timer.Cancel();
+		User::WaitForRequest(timerStatus);
+		ret = status.Int();
+		}
+
+	LOGTEXT2(_L8("\treturning %d"), ret);
+	return ret;
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/CdcControlInterfaceReader.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,413 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <e32std.h>
+#include <d32usbc.h>
+#include "CdcControlInterfaceReader.h"
+#include "AcmPanic.h"
+#include "AcmUtils.h"
+#include "CdcControlInterfaceRequestHandler.h"
+#include "AcmConstants.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CCdcControlInterfaceReader::CCdcControlInterfaceReader(
+				MCdcCommsClassRequestHandler& aParent, 
+				RDevUsbcClient& aLdd)
+:	CActive(KEcacmAOPriority),
+	iParent(aParent),
+	iLdd(aLdd)
+/**
+ * Constructor.
+ *
+ * @param aParent	Observer (ACM port)
+ * @param aLdd		The USB LDD handle to be used.
+ */
+	{
+	CActiveScheduler::Add(this);
+	ReadMessageHeader();
+	}
+
+CCdcControlInterfaceReader::~CCdcControlInterfaceReader()
+/**
+ * Destructor
+ */
+	{
+	LOG_FUNC
+
+	Cancel(); //Call CActive::Cancel()	 
+	}
+
+CCdcControlInterfaceReader* CCdcControlInterfaceReader::NewL(
+	MCdcCommsClassRequestHandler& aParent, 
+	RDevUsbcClient& aLdd)
+/**
+ * Create a new CCdcControlInterfaceReader object and start reading
+ *
+ * @param aParent	Observer (ACM port)
+ * @param aLdd		The USB LDD handle to be used.
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CCdcControlInterfaceReader* self = new(ELeave) CCdcControlInterfaceReader(
+		aParent, 
+		aLdd);
+	return self;
+	}
+
+void CCdcControlInterfaceReader::RunL()
+/**
+ * This function will be called when a read completes.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcControlInterfaceReader::RunL iStatus=%d"), iStatus.Int());
+	HandleReadCompletion(iStatus.Int());
+	LOGTEXT(_L8("<<CCdcControlInterfaceReader::RunL"));
+	}
+
+void CCdcControlInterfaceReader::DoCancel()
+/**
+ * Cancel an outstanding read.
+ */
+	{
+	LOG_FUNC
+	iLdd.ReadCancel(EEndpoint0);
+	}
+
+void CCdcControlInterfaceReader::HandleReadCompletion(TInt aError)
+/**
+ * This will be called when a new packet has been received.
+ * Since "Header" packets may have an associated "Data" packet, which is sent 
+ * immediately following the header, this class implements a state machine. 
+ * Therefore, it will wait until both "Header" and, if necessary, "Data" 
+ * packets have been received before decoding.
+ *
+ * @param aError Error
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcControlInterfaceReader::HandleReadCompletion "
+		"aError=%d"), aError);
+
+	if ( aError )
+		{
+		ReadMessageHeader();			  
+		LOGTEXT(_L8("<<CCdcControlInterfaceReader::HandleReadCompletion"));
+		return;
+		}
+
+	LOGTEXT2(_L8("\tcompleted with iState=%d"),iState);
+	switch ( iState)
+		{
+	case EWaitingForHeader:
+		{
+		DecodeMessageHeader();
+		}
+		break;
+
+	case EWaitingForData:
+		{
+		DecodeMessageData();
+		}
+		break;
+
+	default:
+		{
+		_USB_PANIC(KAcmPanicCat, EPanicIllegalState);
+		}
+		break;
+		}
+
+	LOGTEXT(_L8("<<CCdcControlInterfaceReader::HandleReadCompletion"));
+	}
+
+void CCdcControlInterfaceReader::DecodeMessageHeader()
+/**
+ * This function decodes a message header. It determines whether the host 
+ * requires some data in response and dispatches the request appropriately.
+ */
+	{
+	LOG_FUNC
+
+	if ( TUsbRequestHdr::Decode(iMessageHeader, iRequestHeader) != KErrNone )
+		{
+		LOGTEXT(_L8("\t- Unable to decode request header!"));
+		// Stall bus- unknown message. If this fails, there's nothing we can 
+		// do.
+		static_cast<void>(iLdd.EndpointZeroRequestError()); 
+		ReadMessageHeader();
+		return;
+		}
+
+	LOGTEXT2(_L8("\t- New read! Request 0x%x"), iRequestHeader.iRequest);
+
+	if ( iRequestHeader.IsDataResponseRequired() )
+		{
+		DecodeMessageDataWithResponseRequired();
+		}
+	else if ( iRequestHeader.iLength == 0 )
+		{
+		iMessageData.SetLength(0);
+		DecodeMessageData();
+		}
+	else
+		{
+		ReadMessageData(iRequestHeader.iLength);
+		}
+	}
+
+void CCdcControlInterfaceReader::DecodeMessageDataWithResponseRequired()
+/**
+ * Decode a message which requires data to be sent to the host in response.
+ */
+	{
+	LOG_FUNC
+
+	LOGTEXT2(_L8("\t- New read! Request 0x%x"), iRequestHeader.iRequest);
+	TBuf8<KAcmControlReadBufferLength> returnBuffer;
+
+	switch ( iRequestHeader.iRequest )
+		{
+	case KGetEncapsulated:
+		{
+		if ( iParent.HandleGetEncapResponse(returnBuffer) == KErrNone )
+			{
+			// Write Back data here
+			// At least ack the packet or host will keep sending. If this 
+			// fails, the host will ask again until we do successfully reply.
+			static_cast<void>(iLdd.SendEp0StatusPacket()); 
+			}
+		else
+			{
+			// Stall bus- unknown message. If this fails, there's nothing we 
+			// can do.
+			static_cast<void>(iLdd.EndpointZeroRequestError()); 
+			}
+		}
+		break;
+
+	case KGetCommFeature:
+		{
+		if ( iParent.HandleGetCommFeature(iRequestHeader.iValue, returnBuffer) 
+			== KErrNone )
+			{
+			TRequestStatus status;
+			iLdd.Write(status, EEndpoint0,
+						returnBuffer, 
+						returnBuffer.Length(),
+						EFalse);
+			User::WaitForRequest(status);
+			// If this failed, the host will ask again until we do 
+			// successfully reply.
+			}
+		else
+			{
+			// Stall bus- unknown message. If this fails, there's nothing we 
+			// can do.
+			static_cast<void>(iLdd.EndpointZeroRequestError()); 
+			}
+		}
+		break;
+
+	case KGetLineCoding:
+		{
+		if ( iParent.HandleGetLineCoding(returnBuffer) == KErrNone )
+			{
+			TRequestStatus status;
+			iLdd.Write(status, EEndpoint0,
+						returnBuffer,
+						7,
+						EFalse);
+			User::WaitForRequest(status);
+			}
+		else
+			{
+			// Stall bus- unknown message. If this fails, there's nothing we 
+			// can do.
+			static_cast<void>(iLdd.EndpointZeroRequestError()); 
+			}
+		}
+		break;
+
+	default:
+		{
+		LOGTEXT2(_L8("\t- request number not recognised (%d)"),
+			iRequestHeader.iRequest);
+		// Stall bus- unknown message. If this fails, there's nothing we can 
+		// do.
+		static_cast<void>(iLdd.EndpointZeroRequestError()); 
+		}
+		break;
+		}
+
+	ReadMessageHeader();
+	}
+
+void CCdcControlInterfaceReader::DecodeMessageData()
+/**
+ * Decode a message that does not require any data to be sent to the host in 
+ * response. In all the requests here, the completion of the class-specific 
+ * function is ack'ed by sending an endpoint zero status packet. The request 
+ * can be nack'ed by signalling an endpoint zero request error.
+ */
+	{
+	LOG_FUNC
+
+	if ( iMessageData.Length() != iRequestHeader.iLength )
+		{
+		LOGTEXT(_L8("\t- Data length is incorrect"));
+		ReadMessageHeader();
+		return;
+		}
+
+	LOGTEXT2(_L8("\tNew read! Request %d"), iRequestHeader.iRequest);
+
+	switch ( iRequestHeader.iRequest )
+		{
+	case KSendEncapsulated:
+		if(iParent.HandleSendEncapCommand(iMessageData) == KErrNone)
+			{
+			// If this fails, the host will send again.
+			static_cast<void>(iLdd.SendEp0StatusPacket());
+			}
+		else
+			{
+			// Stall bus- unknown message. If this fails, there's nothing we 
+			// can do.
+			static_cast<void>(iLdd.EndpointZeroRequestError()); 
+			}
+		break;
+	case KSetCommFeature:
+		if(iParent.HandleSetCommFeature(iRequestHeader.iValue,iMessageData) 
+			== KErrNone)
+			{
+			// If this fails, the host will send again.
+			static_cast<void>(iLdd.SendEp0StatusPacket());
+			}
+		else
+			{
+			// Stall bus- unknown message. If this fails, there's nothing we 
+			// can do.
+			static_cast<void>(iLdd.EndpointZeroRequestError()); 
+			}
+		break;
+	case KClearCommFeature:
+		if(iParent.HandleClearCommFeature(iRequestHeader.iValue) == KErrNone)
+			{
+			// If this fails, the host will send again.
+			static_cast<void>(iLdd.SendEp0StatusPacket());
+			}
+		else
+			{
+			// Stall bus- unknown message. If this fails, there's nothing we 
+			// can do.
+			static_cast<void>(iLdd.EndpointZeroRequestError()); 
+			}
+		break;
+	case KSetLineCoding:
+		if(iParent.HandleSetLineCoding(iMessageData) == KErrNone)
+			{
+			// If this fails, the host will send again.
+			static_cast<void>(iLdd.SendEp0StatusPacket());
+			}
+		else
+			{
+			// Stall bus- unknown message. If this fails, there's nothing we 
+			// can do.
+			static_cast<void>(iLdd.EndpointZeroRequestError()); 
+			}
+		break;
+	case KSetControlLineState:
+		if(iParent.HandleSetControlLineState(
+				// See CDC spec table 69 (UART state bitmap values)...
+			   (iRequestHeader.iValue & 0x0002) ? ETrue : EFalse, // bTxCarrier
+			   (iRequestHeader.iValue & 0x0001) ? ETrue : EFalse) // bRxCarrier
+				== KErrNone)
+			{
+			// If this fails, the host will send again.
+			static_cast<void>(iLdd.SendEp0StatusPacket());
+			}
+		else
+			{
+			// Stall bus- unknown message. If this fails, there's nothing we 
+			// can do.
+			static_cast<void>(iLdd.EndpointZeroRequestError()); 
+			}
+		break;
+	case KSendBreak:
+		// The time value sent from the host is in milliseconds.
+		if(iParent.HandleSendBreak(iRequestHeader.iValue) == KErrNone)
+			{
+			// If this fails, the host will send again.
+			static_cast<void>(iLdd.SendEp0StatusPacket());
+			}
+		else
+			{
+			// Stall bus- unknown message. If this fails, there's nothing we 
+			// can do.
+			static_cast<void>(iLdd.EndpointZeroRequestError()); 
+			}
+		break;
+	default:
+		LOGTEXT2(_L8("\t***request number not recognised (%d)"),
+			iRequestHeader.iRequest);
+		// Stall bus- unknown message. If this fails, there's nothing we can 
+		// do.
+		static_cast<void>(iLdd.EndpointZeroRequestError()); 
+		break;
+		}
+
+	ReadMessageHeader();
+	}
+
+void CCdcControlInterfaceReader::ReadMessageHeader()
+/**
+ * Post a read request and set the state to indicate that we're waiting for a 
+ * message header.
+ */
+	{
+	LOG_FUNC
+
+	iState = EWaitingForHeader;
+
+	iLdd.ReadPacket(iStatus, EEndpoint0, iMessageHeader, KUsbRequestHdrSize);
+	SetActive();
+	}
+
+void CCdcControlInterfaceReader::ReadMessageData(TUint aLength)
+/**
+ * Post a read request and set the state to indicate that we're waiting for 
+ * some message data.
+ *
+ * @param aLength Length of data to read.
+ */
+	{
+	LOG_FUNC
+
+	LOGTEXT2(_L8("\tqueuing read, length = %d"),aLength);
+
+	iState = EWaitingForData;
+
+	iLdd.Read(iStatus, EEndpoint0, iMessageData, static_cast<TInt>(aLength));
+	SetActive();
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/CdcDataInterface.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,581 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <e32std.h>
+#include "CdcDataInterface.h"
+#include "ActiveReader.h"
+#include "ActiveWriter.h"
+#include "AcmPanic.h"
+#include "AcmUtils.h"
+#include "ActiveReadOneOrMoreReader.h"
+#include "ActiveDataAvailableNotifier.h"
+#include "inifile.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+#ifdef __HEADLESS_ACM_TEST_CODE__
+#pragma message ("Building headless ACM (performance test code for RDevUsbcClient)")
+#endif // __HEADLESS_ACM_TEST_CODE__
+
+CCdcDataInterface::CCdcDataInterface(const TDesC16& aIfcName)
+/**
+ * Overloaded Constructor using interface name.
+ * @param aIfcName contains the interface name
+ */
+ :	CCdcInterfaceBase(aIfcName),
+ 	iPacketSize(KDefaultMaxPacketTypeBulk)
+	{
+	}
+
+CCdcDataInterface* CCdcDataInterface::NewL(const TDesC16& aIfcName)
+/**
+ * Create a new CCdcDataInterface object and construct it using interface name
+ * This call will return an object with a valid USB configuration
+ *
+ * @param aParent Observer.
+ * @param aIfcName Contains the interface name
+ * @return A pointer to the new object
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	LOGTEXT2(_L("\tData Ifc Name = %S"), &aIfcName);
+
+	CCdcDataInterface* self = new (ELeave) CCdcDataInterface(aIfcName);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CLEANUPSTACK_POP(self);
+	return self;
+	}
+
+void CCdcDataInterface::ConstructL()
+/**
+ * Construct the object
+ * This call registers the object with the USB device driver
+ *
+ * @param aParent Observer.
+ */
+	{
+	BaseConstructL();
+
+	iReadOneOrMoreReader  = CActiveReadOneOrMoreReader::NewL(*this, iLdd, EEndpoint2);
+	iReader = CActiveReader::NewL(*this, iLdd, EEndpoint2);
+	iDataAvailableNotifier = CActiveDataAvailableNotifier::NewL(*this, iLdd, EEndpoint2);
+	iWriter = CActiveWriter::NewL(*this, iLdd, EEndpoint1);
+	iLinkState = CLinkStateNotifier::NewL(*this, iLdd);
+	
+	iLinkState->Start();
+
+	LOGTEXT(_L8("\tchecking ecacm.ini"));
+	iHostCanHandleZLPs = EFalse;
+	GetHostZLPHandlingFromFile();
+	LOGTEXT(_L8("\tfinished checking ecacm.ini"));
+	}
+
+TInt CCdcDataInterface::SetUpInterface()
+/**
+ * Retrieves the device capabilities and searches for suitable input and 
+ * output bulk endpoints. If suitable endpoints are found, an interface 
+ * descriptor for the endpoints is registered with the LDD.
+ */
+	{
+	LOGTEXT(_L8(">>CCdcDataInterface::SetUpInterface"));
+
+	TUsbDeviceCaps dCaps;
+	TInt ret = iLdd.DeviceCaps(dCaps);
+	LOGTEXT(_L8("\tchecking result of DeviceCaps"));
+	if ( ret )
+		{
+		LOGTEXT2(_L8("<<CCdcDataInterface::SetUpInterface ret=%d"), ret);
+		return ret;
+		}
+
+	TInt maxBulkPacketSize = (dCaps().iHighSpeed) ? KMaxPacketTypeBulkHS : KMaxPacketTypeBulkFS;
+	const TUint KRequiredNumberOfEndpoints = 2;
+
+	const TUint totalEndpoints = static_cast<TUint>(dCaps().iTotalEndpoints);
+	LOGTEXT2(_L8("\tiTotalEndpoints = %d"), totalEndpoints);
+	if ( totalEndpoints < KRequiredNumberOfEndpoints )
+		{
+		LOGTEXT2(_L8("<<CCdcDataInterface::SetUpInterface ret=%d"), 
+			KErrGeneral);
+		return KErrGeneral;
+		}
+	
+	// Endpoints
+	TUsbcEndpointData data[KUsbcMaxEndpoints];
+	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
+	ret = iLdd.EndpointCaps(dataptr);
+	LOGTEXT(_L8("\tchecking result of EndpointCaps"));
+	if ( ret )
+		{
+		LOGTEXT2(_L8("<<CCdcDataInterface::SetUpInterface ret=%d"), ret);
+		return ret;
+		}
+
+	// 
+	TUsbcInterfaceInfoBuf ifc;
+	TBool foundIn = EFalse;
+	TBool foundOut = EFalse;
+
+	for ( TUint i = 0; !(foundIn && foundOut) && i < totalEndpoints; i++ )
+		{
+		const TUsbcEndpointCaps* caps = &data[i].iCaps;
+		__ASSERT_DEBUG(caps, 
+			_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		if (data[i].iInUse)
+			continue;
+
+		//get the max packet size it can potentially support
+		//it's possible that it can support Isoch (1023) which is greater
+		//than max for Bulk at 64
+		const TInt maxSize = Min (	maxBulkPacketSize, 
+									caps->MaxPacketSize() );
+
+		const TUint KBulkInFlags = KUsbEpTypeBulk | KUsbEpDirIn;
+		const TUint KBulkOutFlags = KUsbEpTypeBulk | KUsbEpDirOut;
+
+		// use EEndPoint1 for TX (IN) EEndpoint1
+		if (! foundIn && (caps->iTypesAndDir & KBulkInFlags) == KBulkInFlags)
+			{
+
+			ifc().iEndpointData[0].iType  = KUsbEpTypeBulk;
+			ifc().iEndpointData[0].iDir   = KUsbEpDirIn; 
+
+			//get the max packet size it can potentially support
+			//it's possible that it can support Isoch (1023) which is greater
+			//than max for Bulk at 64
+			ifc().iEndpointData[0].iSize  = maxSize;
+			foundIn = ETrue;
+			}
+		// use EEndPoint2 for RX (OUT) endpoint
+		else if (	!foundOut 
+			&&		(caps->iTypesAndDir & KBulkOutFlags) == KBulkOutFlags
+			)
+			{
+			// EEndpoint2 is going to be our RX (OUT, read) endpoint
+			ifc().iEndpointData[1].iType  = KUsbEpTypeBulk;
+			ifc().iEndpointData[1].iDir   = KUsbEpDirOut;
+
+			//get the max packet size it can potentially support
+			//it's possible that it can support Isoch (1023) which is greater
+			//than max for Bulk at 64
+			ifc().iEndpointData[1].iSize  = maxSize;
+			foundOut = ETrue;
+			}
+		}
+
+	if (! (foundIn && foundOut))
+		{
+		LOGTEXT2(_L8("<<CCdcDataInterface::SetUpInterface ret=%d"), 
+			KErrGeneral);
+		return KErrGeneral;
+		}
+
+		// If the device supports USB High-speed, then we request 64KB buffers
+		// (otherwise the default 4KB ones will do).
+
+	TUint bandwidthPriority = (EUsbcBandwidthOUTDefault | EUsbcBandwidthINDefault);
+	if (dCaps().iHighSpeed)
+		{
+		bandwidthPriority = (EUsbcBandwidthOUTPlus2 | EUsbcBandwidthINPlus2);
+		}
+
+	ifc().iString = &iIfcName;
+	ifc().iTotalEndpointsUsed = KRequiredNumberOfEndpoints;
+	ifc().iClass.iClassNum	  = 0x0A; // Table 18- Data Interface Class
+	ifc().iClass.iSubClassNum = 0x00; // Section 4.6- unused.
+	ifc().iClass.iProtocolNum = 0x00; // Table 19- no class specific protocol required
+
+	// Indicate that this interface does not expect any control transfers 
+	// from EP0.
+	ifc().iFeatureWord |= KUsbcInterfaceInfo_NoEp0RequestsPlease;
+
+	LOGTEXT(_L8("\tcalling SetInterface"));
+	// Zero effectively indicates that alternate interfaces are not used.
+	ret = iLdd.SetInterface(0, ifc, bandwidthPriority);
+
+	LOGTEXT2(_L8("<<CCdcDataInterface::SetUpInterface ret=%d"), ret);
+	return ret;
+	}
+
+
+void CCdcDataInterface::MLSOStateChange(TInt aPacketSize)
+	{
+	iPacketSize = aPacketSize;
+	}
+
+
+CCdcDataInterface::~CCdcDataInterface()
+/**
+ * Destructor. Cancel and destroy the child classes.
+ */
+	{
+	LOG_FUNC
+
+	delete iLinkState;
+	delete iReadOneOrMoreReader;
+	delete iReader;
+	delete iWriter;
+	delete iDataAvailableNotifier;
+	}
+
+void CCdcDataInterface::Write(MWriteObserver& aObserver, 
+						  const TDesC8& aDes, 
+						  TInt aLen)
+/**
+ * Write data down the interface
+ * 
+ * @param aObserver The observer to notify of completion.
+ * @param aDes Descriptor containing the data to be sent
+ * @param aLen Length of the data to be sent
+ */
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG(!iWriteObserver, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	iWriteObserver = &aObserver;
+
+	__ASSERT_DEBUG(iWriter, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	
+	if ( iHostCanHandleZLPs )
+		{
+		
+		// Make sure the driver sends a Zero Length Packet if required (i.e. if the 
+		// data size is an exact multiple of the endpoint's packet size). 
+		TBool requestZlp = ( aLen % iPacketSize ) ? EFalse : ETrue;
+		iWriter->Write(aDes, aLen, requestZlp); 
+		}
+	else
+		{
+		iWriter->Write(aDes, aLen, EFalse); 
+		}
+		
+	LOGTEXT(_L8("<<CCdcDataInterface::Write"));
+	}
+
+void CCdcDataInterface::WriteCompleted(TInt aError)
+/**
+ * Called when a write request completes.
+ *
+ * @param aError Error.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcDataInterface::WriteCompleted aError=%d"), aError);
+
+#ifdef __HEADLESS_ACM_TEST_CODE__
+	// Issue another Read or ReadOneOrMore as appropriate.
+	// If the Write completed with an error, we panic, as it's invalidating 
+	// the test.
+	__ASSERT_DEBUG(aError == KErrNone, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	switch ( iHeadlessReadType )
+		{
+	case ERead:
+		LOGTEXT2(_L8("__HEADLESS_ACM_TEST_CODE__- issuing Read for %d bytes"), 
+			iHeadlessReadLength);
+		__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		iReader->Read(iHeadlessAcmBuffer, iHeadlessReadLength);
+		break;
+	case EReadOneOrMore:
+		LOGTEXT2(_L8("__HEADLESS_ACM_TEST_CODE__- issuing ReadOneOrMore for %d bytes"), 
+			iHeadlessReadLength);
+		__ASSERT_DEBUG(iReadOneOrMoreReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+		iReadOneOrMoreReader->ReadOneOrMore(iHeadlessAcmBuffer, iHeadlessReadLength);
+		break;
+	case EUnknown:
+	default:
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError);
+		break;
+		}
+#else
+	// In case the write observer wants to post another write synchronously on 
+	// being informed that this write has completed, use this little 'temp' 
+	// fiddle.
+	__ASSERT_DEBUG(iWriteObserver, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	MWriteObserver* temp = iWriteObserver;
+	iWriteObserver = NULL;
+	LOGTEXT(_L8("\tcalling WriteCompleted on observer"));
+	temp->WriteCompleted(aError);
+#endif // __HEADLESS_ACM_TEST_CODE__
+
+	LOGTEXT(_L8("<<CCdcDataInterface::WriteCompleted"));
+	}
+
+void CCdcDataInterface::CancelWrite()
+/**
+ * Cancel an outstanding write request
+ */
+	{
+	LOG_FUNC
+	
+	__ASSERT_DEBUG(iWriter, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	iWriter->Cancel();
+
+	iWriteObserver = NULL;
+	}
+
+void CCdcDataInterface::Read(MReadObserver& aObserver, 
+							 TDes8& aDes, 
+							 TInt aMaxLen)
+/**
+ * Read data from the interface. As the LDD supports an appropriate function, 
+ * this request can be passed straight down. 
+ *
+ * @param aObserver The observer to notify of completion.
+ * @param aDes Descriptor to put the read data in
+ * @param aMaxLen Number of bytes to read
+ */
+	{
+	LOG_FUNC
+
+#ifdef __HEADLESS_ACM_TEST_CODE__
+	LOGTEXT(_L8("__HEADLESS_ACM_TEST_CODE__"));
+	// Issue a Read using our special internal buffer.
+	iHeadlessReadType = ERead;
+	iHeadlessReadLength = aMaxLen;
+	static_cast<void>(&aObserver);
+	static_cast<void>(&aDes);
+	__ASSERT_DEBUG(aMaxLen <= iHeadlessAcmBuffer.MaxLength(), 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iReader->Read(iHeadlessAcmBuffer, aMaxLen);
+#else
+	__ASSERT_DEBUG(!iReadObserver, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iReadObserver = &aObserver;
+
+	__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iReader->Read(aDes, aMaxLen);
+#endif // __HEADLESS_ACM_TEST_CODE__
+	}
+
+void CCdcDataInterface::ReadOneOrMore(MReadOneOrMoreObserver& aObserver, 
+								  TDes8& aDes, 
+								  TInt aMaxLen)
+/**
+ * Read a given amount of data from the interface, but complete if any data 
+ * arrives.
+ *
+ * @param aObserver The observer to notify of completion.
+ * @param aDes Descriptor to put the read data in
+ * @param aMaxLen Number of bytes to read
+ */
+	{
+	LOG_FUNC
+
+#ifdef __HEADLESS_ACM_TEST_CODE__
+	LOGTEXT(_L8("__HEADLESS_ACM_TEST_CODE__"));
+	// Issue a ReadOneOrMore using our special internal buffer.
+	iHeadlessReadType = EReadOneOrMore;
+	iHeadlessReadLength = aMaxLen;
+	static_cast<void>(&aObserver);
+	static_cast<void>(&aDes);
+	__ASSERT_DEBUG(aMaxLen <= iHeadlessAcmBuffer.MaxLength(), 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	__ASSERT_DEBUG(iReadOneOrMoreReader, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iReadOneOrMoreReader->ReadOneOrMore(iHeadlessAcmBuffer, aMaxLen);
+#else
+	__ASSERT_DEBUG(!iReadOneOrMoreObserver, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iReadOneOrMoreObserver = &aObserver;
+
+	__ASSERT_DEBUG(iReadOneOrMoreReader, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iReadOneOrMoreReader->ReadOneOrMore(aDes, aMaxLen);
+#endif // __HEADLESS_ACM_TEST_CODE__
+	}
+
+void CCdcDataInterface::ReadOneOrMoreCompleted(TInt aError)
+/**
+ * The completion function, called when a ReadOneOrMore request is completed 
+ * by the LDD.
+ *
+ * @param aError The result of the read request.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcDataInterface::ReadOneOrMoreCompleted aError=%d"), 
+		aError);
+
+#ifdef __HEADLESS_ACM_TEST_CODE__
+	LOGTEXT2(_L8("__HEADLESS_ACM_TEST_CODE__- issuing Write for %d bytes"),
+		iHeadlessAcmBuffer.Length());
+	// Write back the data just read.
+	// If the ReadOneOrMore completed with an error, we panic, as it's 
+	// invalidating the test.
+	__ASSERT_DEBUG(aError == KErrNone, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	__ASSERT_DEBUG(iWriter, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iWriter->Write(iHeadlessAcmBuffer, iHeadlessAcmBuffer.Length(), EFalse); 
+#else
+	__ASSERT_DEBUG(iReadOneOrMoreObserver, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	// See comment in WriteCompleted.
+	MReadOneOrMoreObserver* temp = iReadOneOrMoreObserver;
+	iReadOneOrMoreObserver = NULL;
+	LOGTEXT(_L8("\tcalling ReadOneOrMoreCompleted on observer"));
+	temp->ReadOneOrMoreCompleted(aError);
+#endif // __HEADLESS_ACM_TEST_CODE__
+
+	LOGTEXT(_L8("<<CCdcDataInterface::ReadOneOrMoreCompleted"));
+	}
+
+void CCdcDataInterface::ReadCompleted(TInt aError)
+/**
+ * Called by the active reader object when it completes.
+ *
+ * @param aError Error.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcDataInterface::ReadCompleted aError=%d"), aError);
+
+#ifdef __HEADLESS_ACM_TEST_CODE__
+	LOGTEXT2(_L8("__HEADLESS_ACM_TEST_CODE__- issuing Write for %d bytes"),
+		iHeadlessAcmBuffer.Length());
+	// Write back the data just read.
+	// If the Read completed with an error, we panic, as it's invalidating the 
+	// test.				 
+	__ASSERT_DEBUG(aError == KErrNone,
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	__ASSERT_DEBUG(iWriter, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iWriter->Write(iHeadlessAcmBuffer, iHeadlessAcmBuffer.Length(), EFalse); 
+#else
+	__ASSERT_DEBUG(iReadObserver, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	// See comment in WriteCompleted.
+	MReadObserver* temp = iReadObserver;
+	iReadObserver = NULL;
+	LOGTEXT(_L8("\tcalled ReadCompleted on observer"));
+	temp->ReadCompleted(aError);
+#endif // __HEADLESS_ACM_TEST_CODE__
+
+	LOGTEXT(_L8("<<CCdcDataInterface::ReadCompleted"));
+	}
+
+void CCdcDataInterface::CancelRead()
+/**
+ * Cancel an outstanding read request
+ */
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG(iReader, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	__ASSERT_DEBUG(iReadOneOrMoreReader, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	iReader->Cancel();
+	iReadOneOrMoreReader->Cancel();
+	iReadObserver = NULL;
+	iReadOneOrMoreObserver = NULL;
+	}
+
+
+void CCdcDataInterface::GetHostZLPHandlingFromFile()
+/**
+ * Opens the ECACM.ini file to check on the capabilities of the host device.
+ * If the ini file cannot be found or read successfully, the default setting i.e. the
+ * host device CANNOT handle Zero Length Packets (set in CCdcAcmClass::ConstructL()),
+ * is kept.		
+ */
+	{
+	LOG_FUNC
+	
+	CIniFile* iniFile = NULL;
+
+	_LIT(KEcacmIniFilename, "ecacm.ini" );
+	_LIT(KEcacmIniFilePath, "\\system\\data\\" );
+	
+	TRAPD(error, iniFile = CIniFile::NewL(KEcacmIniFilename, KEcacmIniFilePath));
+
+	if (error == KErrNone)
+		{
+		TInt hostHandlesZLPs = 1;
+	
+		_LIT(KHostUSBDeviceDriver, "HostUSBDeviceDriver");
+		_LIT(KCanHandleZLP, "CanHandleZLP");
+	
+		if ( iniFile->FindVar(KHostUSBDeviceDriver, KCanHandleZLP(), hostHandlesZLPs))
+			{			
+			iHostCanHandleZLPs = (( hostHandlesZLPs == 1 ) ? ETrue : EFalse ); 
+		
+			LOGTEXT2(_L8("\tecacm.ini: CanHandleZLP=%d"), hostHandlesZLPs);
+			}
+			
+		delete iniFile;	
+		}
+	}
+	
+void CCdcDataInterface::NotifyDataAvailableCompleted(TInt aError)
+/**
+ * Called by the active data available notifier object when it completes.
+ *
+ * @param aError Error.
+ */
+	{
+	LOGTEXT2(_L8(">>CCdcDataInterface::NotifyDataAvailableCompleted aError=%d"), aError);	
+	
+	// See comment in WriteCompleted.
+	MNotifyDataAvailableObserver* temp = iNotifyDataAvailableObserver;
+	iNotifyDataAvailableObserver = NULL;
+	LOGTEXT(_L8("\tcalled NotifyDataAvailableCompleted on observer"));
+	temp->NotifyDataAvailableCompleted(aError);
+	
+	LOGTEXT(_L8("<<CCdcDataInterface::NotifyDataAvailableCompleted"));
+	}
+	
+void CCdcDataInterface::NotifyDataAvailable(MNotifyDataAvailableObserver& aObserver)
+/**
+ * Complete if any data arrives.
+ *
+ * @param aObserver The observer to notify of completion.
+ */
+	{
+	LOG_FUNC
+		
+	__ASSERT_DEBUG(!iNotifyDataAvailableObserver, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iNotifyDataAvailableObserver = &aObserver;
+
+	__ASSERT_DEBUG(iDataAvailableNotifier, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+	iDataAvailableNotifier->NotifyDataAvailable();
+	}
+
+void CCdcDataInterface::CancelNotifyDataAvailable()
+/**
+ * Cancel notification of arrival of data.
+ */
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG(iDataAvailableNotifier, _USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	iDataAvailableNotifier->Cancel();
+	iNotifyDataAvailableObserver = NULL;	
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/CdcInterfaceBase.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,139 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <e32std.h>
+#include "CdcInterfaceBase.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CCdcInterfaceBase::CCdcInterfaceBase(const TDesC16& aIfcName)
+/**
+ * Constructor.
+ *
+ * @param aIfcName The name of the interface.
+ */
+	{
+	iIfcName.Set(aIfcName);
+	}
+
+void CCdcInterfaceBase::BaseConstructL()
+/**
+ * Construct the object
+ * This call registers the object with the USB device driver
+ */
+	{
+	LOGTEXT(_L8("\tcalling RDevUsbcClient::Open"));
+	// 0 is assumed to mean ep0
+	TInt ret = iLdd.Open(0); 
+	if ( ret )
+		{
+		LOGTEXT2(_L8("\tRDevUsbcClient::Open = %d"), ret);
+		LEAVEIFERRORL(ret); 
+		}
+
+	ret = SetUpInterface();
+	if ( ret )
+		{
+		LOGTEXT2(_L8("\tSetUpInterface = %d"), ret);
+		LEAVEIFERRORL(ret);
+		}
+	}
+
+CCdcInterfaceBase::~CCdcInterfaceBase()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	if ( iLdd.Handle() )
+		{
+		LOGTEXT(_L8("\tLDD handle exists"));
+
+		// Don't bother calling ReleaseInterface- the base driver spec says 
+		// that Close does it for us.
+
+		LOGTEXT(_L8("\tclosing LDD session"));
+		iLdd.Close();
+		}
+	}
+
+TInt CCdcInterfaceBase::GetInterfaceNumber(TUint8& aIntNumber)
+/**
+ * Get my interface number
+ *
+ * @param aIntNumber My interface number
+ * @return Error.
+ */
+	{
+	LOG_FUNC
+
+	TInt interfaceSize = 0;
+
+	// 0 means the main interface in the LDD API
+	TInt res = iLdd.GetInterfaceDescriptorSize(0, interfaceSize);
+
+	if ( res )
+		{
+		LOGTEXT2(_L8("\t***GetInterfaceDescriptorSize()=%d"), res);
+		return res;
+		}
+
+	HBufC8* interfaceBuf = HBufC8::New(interfaceSize);
+	if ( !interfaceBuf )
+		{
+		LOGTEXT(_L8("\t***failed to create interfaceBuf- "
+			"returning KErrNoMemory"));
+		return KErrNoMemory;
+		}
+
+	TPtr8 interfacePtr = interfaceBuf->Des();
+	interfacePtr.SetLength(0);
+	// 0 means the main interface in the LDD API
+	res = iLdd.GetInterfaceDescriptor(0, interfacePtr); 
+
+	if ( res )
+		{
+		delete interfaceBuf;
+		LOGTEXT2(_L8("\t***GetInterfaceDescriptor()=%d"), res);
+		return res;
+		}
+
+#ifdef __FLOG_ACTIVE
+	LOGTEXT2(_L8("\t***interface length = %d"), interfacePtr.Length());
+	for ( TInt i = 0 ; i < interfacePtr.Length() ; i++ )
+		{
+		LOGTEXT2(_L8("\t***** %x"),interfacePtr[i]);
+		}
+#endif
+
+	const TUint8* buffer = reinterpret_cast<const TUint8*>(interfacePtr.Ptr());
+	// 2 is where the interface number is, according to the LDD API
+	aIntNumber = buffer[2]; 
+
+	LOGTEXT2(_L8("\tinterface number = %d"), aIntNumber);
+
+	delete interfaceBuf;
+
+	return KErrNone;
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ClassDescriptor.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,81 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include "ClassDescriptor.h"
+#include "AcmPanic.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+TDes8& TUsbCsClassDescriptor::Des()
+/**
+ * This function packs the TUsbCsClassDescriptor class into a descriptor with 
+ * the correct byte alignment for transmission on the USB bus.
+ *
+ * @return Correctly-aligned buffer. NB The buffer returned is a member of 
+ * this class and has the same lifetime.
+ */
+	{
+	TUint index = 0;
+
+	iBuffer.SetLength(KUsbClassSpecificBufferSize);
+
+	iBuffer[index++] = iHdrSize;
+	iBuffer[index++] = iHdrType;
+	iBuffer[index++] = iHdrSubType;
+	iBuffer[index++] = (TUint8) ( iHdrBcdCDC & 0x00ff);
+	iBuffer[index++] = (TUint8) ((iHdrBcdCDC & 0xff00) >> 8);
+	iBuffer[index++] = iAcmSize;
+	iBuffer[index++] = iAcmType;
+	iBuffer[index++] = iAcmSubType;
+	iBuffer[index++] = iAcmCapabilities;
+	iBuffer[index++] = iUnSize;
+	iBuffer[index++] = iUnType;
+	iBuffer[index++] = iUnSubType;
+	iBuffer[index++] = iUnMasterInterface;
+	iBuffer[index++] = iUnSlaveInterface;
+
+#if defined(DISABLE_ACM_CF_COUNTRY_SETTING)
+
+	// no functional descriptor needed
+
+#elif defined(ENABLE_ACM_CF_COUNTRY_SETTING)
+
+	// CDC Country Selection Functional Descriptor
+	iBuffer[index++] = iCsSize;
+	iBuffer[index++] = iCsType;
+	iBuffer[index++] = iCsSubType;
+	iBuffer[index++] = iCsRelDate;
+
+	for ( TUint scan = 0 ; scan < KUsbCommNumCountries ; scan++ )
+		{
+		iBuffer[index++] = (TUint8) (iCsCountryCode[scan] & 0x00ff);
+		iBuffer[index++] = (TUint8) ((iCsCountryCode[scan] & 0xff00) >> 8);
+		}
+
+#endif
+
+	__ASSERT_DEBUG(index == KUsbClassSpecificBufferSize, 
+		_USB_PANIC(KAcmPanicCat, EPanicInternalError));
+
+	return iBuffer;
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/DllMain.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <e32std.h>
+#include <cs_port.h>
+#include "AcmPortFactory.h"
+
+extern "C" IMPORT_C CSerial* LibEntryL(void);	
+
+EXPORT_C CSerial* LibEntryL()
+/**
+ * Lib main entry point
+ */
+	{	
+	return (CAcmPortFactory::NewL());
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/RegistrationPort.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,513 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include "RegistrationPort.h"
+#include "AcmConstants.h"
+#include "AcmUtils.h"
+#include <usb/acmserver.h>
+#include "acmcontroller.h"
+#include <usb/usblogger.h>
+#include "acmserverconsts.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CRegistrationPort* CRegistrationPort::NewL(MAcmController& aAcmController, 
+										   TUint aUnit)
+/**
+ * Factory function.
+ *
+ * @param aOwner Observer (the port factory).
+ * @param aUnit The port number.
+ * @return Ownership of a newly created CRegistrationPort object
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CRegistrationPort* self = new(ELeave) CRegistrationPort(aAcmController);
+	CleanupClosePushL(*self);
+	self->ConstructL(aUnit);
+	CleanupStack::Pop();
+	return self;
+	}
+
+void CRegistrationPort::ConstructL(TUint aUnit)
+/**
+ * 2nd-phase constructor. 
+ *
+ * @param aUnit The port number.
+ */
+	{
+	LOG_FUNC
+
+	TName name;
+	name.Num(aUnit);
+	LEAVEIFERRORL(SetName(&name));
+	}
+
+CRegistrationPort::CRegistrationPort(MAcmController& aAcmController) 
+/**
+ * Constructor.
+ *
+ * @param aAcmController To use when creating and destroying ACM functions.
+ */
+ :	iAcmController(aAcmController)
+	{
+	}
+
+void CRegistrationPort::StartRead(const TAny* /*aClientBuffer*/, 
+								  TInt /*aLength*/)
+/**
+ * Queue a read
+ *
+ * @param aClientBuffer pointer to the Client's buffer
+ * @param aLength number of bytes to read
+ */
+	{
+	LOG_FUNC
+
+	ReadCompleted(KErrNotSupported);
+	}
+
+void CRegistrationPort::ReadCancel()
+/**
+ * Cancel a read
+ */
+	{
+	LOG_FUNC
+
+	ReadCompleted(KErrNotSupported);
+	}
+
+
+TInt CRegistrationPort::QueryReceiveBuffer(TInt& /*aLength*/) const
+/**
+ * Get the size of the receive buffer
+ *
+ * @param aLength reference to where the size will be written to
+ * @return KErrNotSupported always.
+ */
+	{
+	LOG_FUNC
+
+	return KErrNotSupported;
+	}
+
+void CRegistrationPort::ResetBuffers(TUint)
+/**
+ * Reset Tx and Rx buffers.
+ * Not supported.
+ */
+	{
+	LOG_FUNC
+	}
+
+void CRegistrationPort::StartWrite(const TAny* /*aClientBuffer*/, 
+								   TInt /*aLength*/)
+/**
+ * Queue a write
+ *
+ * @param aClientBuffer pointer to the Client's buffer
+ * @param aLength number of bytes to write
+ */
+	{
+	LOG_FUNC
+
+	WriteCompleted(KErrNotSupported);
+	}
+
+void CRegistrationPort::WriteCancel()
+/**
+ * Cancel a pending write
+ */
+	{
+	LOG_FUNC
+
+	WriteCompleted(KErrNotSupported);
+	}
+
+void CRegistrationPort::Break(TInt /*aTime*/)
+/**
+ * Send a break signal to the host.
+ *
+ * @param aTime Length of break in microseconds
+ */
+	{
+	LOG_FUNC
+
+	BreakCompleted(KErrNotSupported);
+	}
+
+void CRegistrationPort::BreakCancel()
+/**
+ * Cancel a pending break.
+ */
+	{
+	LOG_FUNC
+	}
+
+TInt CRegistrationPort::GetConfig(TDes8& /*aDes*/) const
+/**
+ * Pass a config request
+ *
+ * @param aDes config will be written to this descriptor 
+ * @return Error
+ */
+	{
+	LOG_FUNC
+
+	return KErrNotSupported;
+	}
+
+TInt CRegistrationPort::SetConfig(const TDesC8& /*aDes*/)
+/**
+ * Set up the comm port.
+ *
+ * @param aDes descriptor containing the new config
+ * @return Error
+ */
+	{
+	LOG_FUNC
+
+	return KErrNotSupported;
+	}
+
+TInt CRegistrationPort::SetServerConfig(const TDesC8& /*aDes*/)
+/**
+ * Set the server config.
+ *
+ * @param aDes package with new server configurations
+ * @return Error
+ */
+	{
+	LOG_FUNC
+
+	return KErrNotSupported;
+	}
+
+TInt CRegistrationPort::GetServerConfig(TDes8& /*aDes*/)
+/**
+ * Get the server configs
+ *
+ * @param aDes server configs will be written to this descriptor
+ * @return Error
+ */
+	{
+	LOG_FUNC
+	
+	return KErrNotSupported;
+	}
+
+TInt CRegistrationPort::GetCaps(TDes8& /*aDes*/)
+/**
+ * Read capabilities from the driver
+ *
+ * @param aDes caps will be written to this descriptor
+ * @return Error
+ */
+	{
+	LOG_FUNC
+
+	return KErrNotSupported;
+	}
+
+TInt CRegistrationPort::GetSignals(TUint& /*aSignals*/)
+/**
+ * Get the status of the signal pins
+ *
+ * @param aSignals signals will be written to this descriptor
+ * @return Error
+ */
+	{
+	LOG_FUNC
+
+	return KErrNotSupported;
+	}
+
+TInt CRegistrationPort::SetSignalsToMark(TUint aAcmField)
+/**
+ * Set selected signals to high (logical 1).
+ * 
+ * Used in the registration port as an API to create aNoAcms ACM interfaces.
+ * This method of creating interfaces is deprecated, use the ACM Server instead.
+ *
+ * @param aAcmField Low 2 bytes- number of ACM interfaces to create. High 2 
+ * bytes- protocol number (from USBCDC 1.1 Table 17).
+ * @return Error
+ */
+	{
+	LOGTEXT2(_L8(">>CRegistrationPort::SetSignalsToMark aAcmField = 0x%x"), aAcmField);
+
+	// Extract number of interfaces and protocol number
+	//	low 2 bytes represent the number of ACMs
+	//	high 2 bytes represent the protocol number to use
+	TUint interfaces = aAcmField & 0x0000FFFF;
+	TUint8 protocolNumber = (aAcmField & 0xFFFF0000) >> 16;
+	
+	// If there is no protocol number, assume the default
+	// i.e. the client is not using this interface to set the protocol number
+	// NOTE: This means you cannot set a protocol number of 0 - to do this use the ACM Server.
+	protocolNumber = protocolNumber ? protocolNumber : KDefaultAcmProtocolNum;
+
+	TInt ret = iAcmController.CreateFunctions(interfaces, protocolNumber, KControlIfcName, KDataIfcName);
+
+	LOGTEXT2(_L8("<<CRegistrationPort::SetSignalsToMark ret = %d"), ret);
+	return ret;
+	}
+
+TInt CRegistrationPort::SetSignalsToSpace(TUint aNoAcms)
+/**
+ * Set selected signals to low (logical 0)
+ *
+ * Used in the registration port as an API to destroy aNoAcms ACM interfaces.
+ * This method of destroying interfaces is depricated, use the ACM Server instead.
+ *
+ * @param aNoAcms Number of ACM interfaces to destroy.
+ * @return Error
+ */
+	{
+	LOGTEXT2(_L8(">>CRegistrationPort::SetSignalsToSpace aNoAcms = %d"), aNoAcms);
+
+	iAcmController.DestroyFunctions(aNoAcms);
+
+	LOGTEXT(_L8("<<CRegistrationPort::SetSignalsToSpace ret = KErrNone"));
+	return KErrNone;
+	}
+
+TInt CRegistrationPort::GetReceiveBufferLength(TInt& /*aLength*/) const
+/**
+ * Get size of Tx and Rx buffer
+ *
+ * @param aLength reference to where the length will be written to
+ * @return Error
+ */
+	{
+	LOG_FUNC
+
+	return KErrNotSupported;
+	}
+
+TInt CRegistrationPort::SetReceiveBufferLength(TInt /*aLength*/)
+/**
+ * Set the size of Tx and Rx buffer
+ *
+ * @param aLength new length of Tx and Rx buffer
+ * @return Error
+ */
+	{
+	LOG_FUNC
+
+	return KErrNotSupported;
+	}
+
+void CRegistrationPort::Destruct()
+/**
+ * Destruct - we must (eventually) call delete this
+ */
+	{
+	LOG_FUNC
+
+	delete this;
+	}
+
+void CRegistrationPort::FreeMemory()
+/**
+ * Attempt to reduce our memory foot print.
+ */
+	{
+	LOG_FUNC
+	}
+
+void CRegistrationPort::NotifyDataAvailable()
+/**
+ * Notify client when data is available
+ */
+	{
+	LOG_FUNC
+
+	NotifyDataAvailableCompleted(KErrNotSupported);
+	}
+
+void CRegistrationPort::NotifyDataAvailableCancel()
+/**
+ * Cancel an outstanding data availalbe notification
+ */
+	{
+	LOG_FUNC
+
+	NotifyDataAvailableCompleted(KErrNotSupported);
+	}
+
+TInt CRegistrationPort::GetFlowControlStatus(TFlowControl& /*aFlowControl*/)
+/**
+ * Get the flow control status
+ *
+ * @param aFlowControl flow control status will be written to this descriptor
+ * @return Error
+ */
+	{
+	LOG_FUNC
+
+	return KErrNotSupported;
+	}
+
+void CRegistrationPort::NotifyOutputEmpty()
+/**
+ * Notify the client when the output buffer is empty.
+ */
+	{
+	LOG_FUNC
+	
+	NotifyOutputEmptyCompleted(KErrNotSupported);
+	}
+
+void CRegistrationPort::NotifyOutputEmptyCancel()
+/**
+ * Cancel a pending request to be notified when the output buffer is empty.
+ */
+	{
+	LOG_FUNC
+
+	NotifyOutputEmptyCompleted(KErrNotSupported);
+	}
+
+void CRegistrationPort::NotifyBreak()
+/**
+ * Notify a client of a break on the serial line.
+ */
+	{
+	LOG_FUNC
+
+	BreakNotifyCompleted(KErrNotSupported);
+	}
+
+void CRegistrationPort::NotifyBreakCancel()
+/**
+ * Cancel a pending notification of a serial line break.
+ */
+	{
+	LOG_FUNC
+
+	BreakNotifyCompleted(KErrNotSupported);
+	}
+
+void CRegistrationPort::NotifyFlowControlChange()
+/**
+ * Notify a client of a change in the flow control state.
+ */
+	{
+	LOG_FUNC
+	
+	FlowControlChangeCompleted(EFlowControlOn,KErrNotSupported);
+	}
+
+void CRegistrationPort::NotifyFlowControlChangeCancel()
+/**
+ * Cancel a pending request to be notified when the flow control state changes.
+ */
+	{
+	LOG_FUNC
+
+	FlowControlChangeCompleted(EFlowControlOn,KErrNotSupported);
+	}
+
+void CRegistrationPort::NotifyConfigChange()
+/**
+ * Notify a client of a change to the serial port configuration.
+ */
+	{
+	LOG_FUNC
+
+	ConfigChangeCompleted(KNullDesC8, KErrNotSupported);
+	}
+
+void CRegistrationPort::NotifyConfigChangeCancel()
+/**
+ * Cancel a pending request to be notified of a change to the serial port 
+ * configuration.
+ */
+	{
+	LOG_FUNC
+
+	ConfigChangeCompleted(KNullDesC8, KErrNotSupported);
+	}
+
+void CRegistrationPort::NotifySignalChange(TUint /*aSignalMask*/)
+/**
+ * Notify a client of a change to the signal lines.
+ */
+	{
+	LOG_FUNC
+
+	SignalChangeCompleted(0, KErrNotSupported);
+	}
+
+void CRegistrationPort::NotifySignalChangeCancel()
+/**
+ * Cancel a pending client request to be notified about a change to the signal 
+ * lines.
+ */
+	{
+	LOG_FUNC
+
+	SignalChangeCompleted(0, KErrNotSupported);
+	}
+
+TInt CRegistrationPort::GetRole(TCommRole& aRole)
+/**
+ * Get the role of this port unit
+ *
+ * @param aRole reference to where the role will be written to
+ * @return Error
+ */
+	{
+	LOG_FUNC
+	aRole = iRole;
+	LOGTEXT2(_L8("\trole=%d"), aRole);
+	return KErrNone;
+	}
+
+TInt CRegistrationPort::SetRole(TCommRole aRole)
+/**
+ * Set the role of this port unit
+ *
+ * @param aRole the new role
+ * @return Error
+ */
+	{
+	LOG_FUNC
+
+	// This is required to keep C32 happy while opening the port.
+	// All we do is store the role and return it if asked.
+	// Note that this is needed for multiple ACM ports because C32 doesn't 
+	// check the return value for multiple ports so opening registration port 
+	// more than once will fail.
+	iRole = aRole;
+	return KErrNone; 
+	}
+
+CRegistrationPort::~CRegistrationPort()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/RequestHeader.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,75 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include "RequestHeader.h"
+
+const TDesC8& TUsbRequestHdr::Des()
+/**
+ * This function packs the TUsbRequestHdr class into a descriptor with the
+ * correct byte alignment for transmission on the USB bus.
+ *
+ * @return Correctly-aligned buffer. NB The buffer returned is a member of 
+ * this class and has the same lifetime.
+ */
+	{
+	iBuffer.SetLength(KUsbRequestHdrSize);
+
+	iBuffer[0] = iRequestType;
+	iBuffer[1] = iRequest;
+	iBuffer[2] = static_cast<TUint8>(iValue & 0x00ff);
+	iBuffer[3] = static_cast<TUint8>((iValue & 0xff00) >> 8);
+	iBuffer[4] = static_cast<TUint8>(iIndex & 0x00ff);
+	iBuffer[5] = static_cast<TUint8>((iIndex & 0xff00) >> 8);
+	iBuffer[6] = static_cast<TUint8>(iLength & 0x00ff);
+	iBuffer[7] = static_cast<TUint8>((iLength & 0xff00) >> 8);
+
+	return iBuffer;
+	}
+
+TInt TUsbRequestHdr::Decode(const TDesC8& aBuffer, TUsbRequestHdr& aTarget)
+/**
+ * This function unpacks into the TUsbRequestHdr class from a descriptor with 
+ * the alignment that would be introduced on the USB bus.
+ *
+ * @param aBuffer Input buffer
+ * @param aTarget Unpacked header.
+ * @return Error.
+ */
+	{
+	if (aBuffer.Length() < static_cast<TInt>(KUsbRequestHdrSize))
+		return KErrGeneral;
+
+	aTarget.iRequestType = aBuffer[0];
+	aTarget.iRequest = aBuffer[1];
+	aTarget.iValue	 = static_cast<TUint16>(aBuffer[2] + (aBuffer[3] << 8));
+	aTarget.iIndex	 = static_cast<TUint16>(aBuffer[4] + (aBuffer[5] << 8));
+	aTarget.iLength  = static_cast<TUint16>(aBuffer[6] + (aBuffer[7] << 8));
+	return KErrNone;
+	}
+
+TBool TUsbRequestHdr::IsDataResponseRequired() const
+/**
+ * This function determines whether data is required by the host in response 
+ * to a message header.
+ * @return TBool	Flag indicating whether a data response required.
+ */
+	{
+	return (iRequestType & 0x80) ? ETrue : EFalse;
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/acmserver.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,87 @@
+/*
+* Copyright (c) 2007-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:
+* ACM server.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <usb/usblogger.h>
+#include "acmserver.h"
+#include "acmsession.h"
+#include "acmserversecuritypolicy.h"
+#include "acmserverconsts.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CAcmServer* CAcmServer::NewL(MAcmController& aAcmController)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CAcmServer* self = new(ELeave) CAcmServer(aAcmController);
+	CleanupStack::PushL(self);
+	TInt err = self->Start(KAcmServerName);
+	// KErrAlreadyExists is a success case (c.f. transient server boilerplate
+	// code).
+	if ( err != KErrAlreadyExists )
+		{
+		LEAVEIFERRORL(err);
+		}
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CAcmServer::~CAcmServer()
+	{
+	LOG_FUNC
+	}
+
+CAcmServer::CAcmServer(MAcmController& aAcmController)
+ :	CPolicyServer(CActive::EPriorityStandard, KAcmServerPolicy),
+ 	iAcmController(aAcmController)
+ 	{
+	}
+
+CSession2* CAcmServer::NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const
+	{
+	LOG_FUNC
+
+	//Validate session as coming from UsbSvr
+	static _LIT_SECURITY_POLICY_S0(KSidPolicy, 0x101fe1db);
+	TBool auth = KSidPolicy.CheckPolicy(aMessage);
+	if(!auth)
+		{
+		LEAVEIFERRORL(KErrPermissionDenied);
+		}
+
+	// Version number check...
+	TVersion v(	KAcmSrvMajorVersionNumber,
+				KAcmSrvMinorVersionNumber,
+				KAcmSrvBuildNumber);
+
+	if ( !User::QueryVersionSupported(v, aVersion) )
+		{
+		LEAVEIFERRORL(KErrNotSupported);
+		}
+
+	CAcmSession* sess = CAcmSession::NewL(iAcmController);
+	LOGTEXT2(_L8("\tsess = 0x%08x"), sess);
+	return sess;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/acmsession.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,102 @@
+/*
+* 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 "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:
+* ACM session.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "acmserverconsts.h"
+#include "acmsession.h"
+#include "AcmPortFactory.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CAcmSession* CAcmSession::NewL(MAcmController& aAcmController)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CAcmSession* self = new(ELeave) CAcmSession(aAcmController);
+	return self;
+	}
+
+CAcmSession::CAcmSession(MAcmController& aAcmController)
+ :	iAcmController(aAcmController)
+	{
+	LOG_FUNC
+	}
+
+CAcmSession::~CAcmSession()
+	{
+	LOG_FUNC
+	}
+	
+void CAcmSession::CreateFunctionsL(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	RBuf acmControlIfcName, acmDataIfcName;
+
+	TInt size = aMessage.GetDesLengthL(2);
+	acmControlIfcName.CreateL(size);
+	acmControlIfcName.CleanupClosePushL();
+	aMessage.ReadL(2, acmControlIfcName);
+
+	size = aMessage.GetDesLengthL(3);
+	acmDataIfcName.CreateL(size);
+	acmDataIfcName.CleanupClosePushL();
+	aMessage.ReadL(3, acmDataIfcName);
+
+	LOGTEXT5(_L("\taNoAcms = %d, aProtocolNum = %d, Control Ifc Name = %S, Data Ifc Name = %S"),
+			aMessage.Int0(), aMessage.Int1(), &acmControlIfcName, &acmDataIfcName);
+
+	LEAVEIFERRORL(iAcmController.CreateFunctions(aMessage.Int0(), aMessage.Int1(), acmControlIfcName, acmDataIfcName));
+
+	CleanupStack::PopAndDestroy(2);
+	}
+
+void CAcmSession::ServiceL(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taMessage.Function() = %d"), aMessage.Function());
+
+	switch ( aMessage.Function() )
+		{
+	case EAcmCreateAcmFunctions:
+		{
+		TRAPD (err, CreateFunctionsL(aMessage));
+		aMessage.Complete(err);
+		break;
+		}
+
+	case EAcmDestroyAcmFunctions:
+		{
+		iAcmController.DestroyFunctions(aMessage.Int0());
+		aMessage.Complete(KErrNone);
+		break;
+		}
+		
+	default:
+		// Unknown function, panic the user
+		aMessage.Panic(KAcmSrvPanic, EAcmBadAcmMessage);
+		break;
+		}
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/linkstatenotifier.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,160 @@
+/*
+* 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 "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 <e32base.h>
+#include <d32usbc.h>
+#include <usb/usblogger.h>
+#include "AcmPanic.h"
+#include "linkstatenotifier.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "ECACM");
+#endif
+
+CLinkStateNotifier* CLinkStateNotifier::NewL(MLinkStateObserver& aParent, RDevUsbcClient& aUsb)
+	{
+	LOG_STATIC_FUNC_ENTRY
+	
+	CLinkStateNotifier* self = new (ELeave) CLinkStateNotifier(aParent, aUsb);
+	return self;
+	}
+
+
+CLinkStateNotifier::CLinkStateNotifier(MLinkStateObserver& aParent, RDevUsbcClient& aUsb)
+	 : CActive(EPriorityStandard),
+	   iParent(aParent), iUsb(aUsb)
+	{
+	LOG_FUNC
+	
+	CActiveScheduler::Add(this);
+	}
+
+
+
+/**
+CObexUsbHandler destructor.
+*/
+CLinkStateNotifier::~CLinkStateNotifier()
+	{
+	LOG_FUNC
+	Cancel();
+	}
+
+
+/**
+Standard active object error function.
+
+@return	KErrNone because currently nothing should cause this to be called.
+*/
+TInt CLinkStateNotifier::RunError(TInt /*aError*/)
+	{
+	return KErrNone;
+	}
+
+
+/**
+This function will be called upon a change in the state of the device
+(as set up in AcceptL).
+*/
+void CLinkStateNotifier::RunL()
+	{
+	LOGTEXT2(_L8("CObexUsbHandler::RunL called state=0x%X"), iUsbState);
+	
+	if (iStatus != KErrNone)
+		{
+		LOGTEXT2(_L8("CObexUsbHandler::RunL() - Error = %d"),iStatus.Int());
+		LinkDown();
+		iParent.MLSOStateChange(KDefaultMaxPacketTypeBulk);
+
+		return;
+		}
+
+	if (!(iUsbState & KUsbAlternateSetting))
+		{
+		TUsbcDeviceState deviceState = static_cast<TUsbcDeviceState>(iUsbState);
+
+		switch(deviceState)
+			{
+		case EUsbcDeviceStateUndefined:
+			LinkDown();
+			break;
+				
+		case EUsbcDeviceStateAttached:
+		case EUsbcDeviceStatePowered:
+		case EUsbcDeviceStateDefault:
+		case EUsbcDeviceStateAddress:
+		case EUsbcDeviceStateSuspended:
+			break;
+
+		case EUsbcDeviceStateConfigured:
+			LinkUp();
+			break;
+
+		default:
+			__ASSERT_DEBUG(false, _USB_PANIC(KAcmPanicCat, EPanicUnknownDeviceState));
+			break;
+			}
+		}
+
+	iParent.MLSOStateChange(iPacketSize || KDefaultMaxPacketTypeBulk);
+
+	// Await further notification of a state change.
+	iUsb.AlternateDeviceStatusNotify(iStatus, iUsbState);
+	SetActive();
+	}
+
+
+/**
+Standard active object cancellation function.
+*/
+void CLinkStateNotifier::DoCancel()
+	{
+	LOG_FUNC
+
+	iUsb.AlternateDeviceStatusNotifyCancel();
+	}
+
+
+
+/**
+Accept an incoming connection.
+*/
+void CLinkStateNotifier::Start()
+	{
+	LOG_FUNC
+	iUsb.AlternateDeviceStatusNotify(iStatus, iUsbState);
+	SetActive();
+	}
+
+
+void CLinkStateNotifier::LinkUp()
+	{
+	if (iUsb.CurrentlyUsingHighSpeed())
+		{
+		iPacketSize = KMaxPacketTypeBulkHS;
+		}
+	else
+		{
+		iPacketSize = KMaxPacketTypeBulkFS;
+		}
+	}
+
+
+void CLinkStateNotifier::LinkDown()
+	{
+	iPacketSize = 0;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,22 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "acm/bld.inf"
+#include "ms/bld.inf"
+#include "obex/bld.inf"
+#include "whcm/bld.inf"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/ms/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,18 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "classcontroller/group/bld.inf"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,22 @@
+/*
+* 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 "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:
+*
+*/
+
+PRJ_MMPFILES
+
+#if !(defined(WINS) || defined(WINSCW))	
+msclasscontroller.mmp	// Mass Storage Class Controller plugin
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/group/msclasscontroller.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,55 @@
+/*
+* 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 "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:
+* usbmassstorageclient.dll USB mass storage server client side API
+*
+*/
+
+/**
+ @file
+*/
+
+target			msclasscontroller.dll //Recommended unpaged
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+targettype		plugin
+
+
+uid			0x10009d8d 0x10204bbb
+
+
+userinclude		../inc
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+sourcepath		../src
+source			CUsbMsClassController.cpp
+source			CUsbMsClassImpCollection.cpp
+
+start resource usbms.rss
+targetpath /private/10204bbb
+header
+end
+
+start resource 10204bbb.rss
+target msclasscontroller.rsc
+end
+
+library			euser.lib
+LIBRARY			usbclasscontroller.lib
+LIBRARY			efsrv.lib
+LIBRARY			bafl.lib
+
+#include <usb/usblogger.mmh>
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/inc/CUsbMsClassController.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,84 @@
+/*
+* 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 "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:
+* Adheres to the UsbMan USB Class API and talks to mass storage file system
+*
+*/
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#ifndef __CUSBMSCLASSCONTROLLER_H__
+#define __CUSBMSCLASSCONTROLLER_H__
+
+#include <e32std.h>
+#include <cusbclasscontrollerplugin.h>
+#include <massstorage.h>
+
+_LIT(KUsbMsResource, "z:\\private\\101fe1db\\usbms.rsc");
+
+class MUsbClassControllerNotify;
+
+const TInt KMsStartupPriority = 3;
+
+	
+/**
+ The CUsbMsClassController class
+
+ Implements the USB Class Controller API 
+ */
+NONSHARABLE_CLASS(CUsbMsClassController) : public CUsbClassControllerPlugIn
+	{
+
+public: 
+	static CUsbMsClassController* NewL(MUsbClassControllerNotify& aOwner);
+	~CUsbMsClassController();
+
+private: 
+	// Functions derived from CActive.
+	virtual void RunL();
+	virtual void DoCancel();
+	virtual TInt RunError(TInt aError);
+
+private: 
+	// Functions derived from CUsbClassControllerBase
+	virtual void Start(TRequestStatus& aStatus);
+	virtual void Stop(TRequestStatus& aStatus);
+
+	virtual void GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const;
+
+private:
+	CUsbMsClassController(MUsbClassControllerNotify& aOwner);
+	void ConstructL();
+
+#ifdef _UNITTEST_DEBUG
+public:
+#else
+private:
+#endif
+
+    void ReadMassStorageConfigL();
+    void ConfigItem(const TPtrC& source, TDes& target, TInt maxLength);
+
+private:
+    RUsbMassStorage iUsbMs;
+#ifdef _UNITTEST_DEBUG
+public:
+#endif
+	TMassStorageConfig iMsConfig;
+	};
+
+#endif //__CUSBMSCLASSCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/inc/usbms.rh	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* 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 "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:
+* Resource header for usbman configuration.
+*
+*/
+
+/**
+ @file
+*/
+
+STRUCT USBMASSSTORAGE_CONFIG
+	{
+	LTEXT	vendorId;           // no more than 8 characters
+	LTEXT	productId;          // no more than 16 characters
+	LTEXT	productRev;        	// no more than 4 characters
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/src/10204bbb.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* 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 "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 <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x10204bbb;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x101fbf21;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x10204bbc;
+					version_no = 1;
+					display_name = "mass storage";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/src/CUsbMsClassController.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,305 @@
+/*
+* 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 "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:
+* Adheres to the UsbMan USB Class Controller API and talks to mass storage 
+* file server
+*
+*/
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#include <barsc.h> 
+#include <barsread.h>
+#include <usb_std.h>
+#include <cusbclasscontrollerplugin.h>
+#include <usbms.rsg>
+#include "CUsbMsClassController.h"
+#include <usb/usblogger.h>
+ 
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "MSCC");
+#endif
+
+// Panic category 
+#ifdef _DEBUG
+_LIT( KMsCcPanicCategory, "UsbMsCc" );
+#endif
+
+/**
+ Panic codes for the USB mass storage Class Controller.
+ */
+enum TMsCcPanic
+	{
+	//Class called while in an illegal state
+	EBadApiCall = 0,
+    EUnusedFunction = 1,
+	};
+
+/**
+ Constructs a CUsbMsClassController object
+ 
+ @param	aOwner	USB Device that owns and manages the class
+ @return	A new CUsbMsClassController object
+ */
+CUsbMsClassController* CUsbMsClassController::NewL(
+	MUsbClassControllerNotify& aOwner)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbMsClassController* r = new (ELeave) CUsbMsClassController(aOwner);
+	CleanupStack::PushL(r);
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+	}
+
+/**
+ Destructor
+ */
+CUsbMsClassController::~CUsbMsClassController()
+	{
+	Cancel();
+	}
+
+/**
+ Constructor.
+ 
+ @param	aOwner	USB Device that owns and manages the class
+ */
+CUsbMsClassController::CUsbMsClassController(
+	MUsbClassControllerNotify& aOwner)
+	: CUsbClassControllerPlugIn(aOwner, KMsStartupPriority)	
+	{
+	// Intentionally left blank
+	}
+
+/**
+ 2nd Phase Construction.
+ */
+void CUsbMsClassController::ConstructL()
+	{
+	LOG_FUNC
+
+	ReadMassStorageConfigL();
+	}
+
+/**
+ Called by UsbMan when it wants to start the mass storage class. 
+ 
+ @param aStatus The caller's request status, filled in with an error code
+ */
+void CUsbMsClassController::Start(TRequestStatus& aStatus)
+	{
+	LOG_FUNC
+	
+	// The service state should always be idle when this function is called 
+	// (guaranteed by CUsbSession).
+	__ASSERT_DEBUG( iState == EUsbServiceIdle, _USB_PANIC(KMsCcPanicCategory, EBadApiCall) );
+
+	TRequestStatus* reportStatus = &aStatus;
+
+	iState = EUsbServiceStarting;
+
+	// Connect to USB Mass Storage server
+	TInt err = iUsbMs.Connect();
+
+	if (err != KErrNone)
+		{
+		iState = EUsbServiceIdle;
+		User::RequestComplete(reportStatus, err);
+		LOGTEXT(_L8("Failed to connect to mass storage file server"));
+		return;
+		}
+
+	// Start mass storage device
+	err = iUsbMs.Start(iMsConfig);
+
+	if (err != KErrNone)
+		{
+		iState = EUsbServiceIdle;
+		
+		// Connection was created successfully in last step
+		// Get it closed since failed to start device.
+		iUsbMs.Close();
+		
+		User::RequestComplete(reportStatus, err);
+		LOGTEXT(_L8("Failed to start mass storage device"));
+		return;
+		}
+
+	iState = EUsbServiceStarted;
+
+	User::RequestComplete(reportStatus, KErrNone);
+	}
+
+/**
+ Called by UsbMan when it wants to stop the USB ACM class.
+ 
+ @param aStatus KErrNone on success or a system wide error code
+ */
+void CUsbMsClassController::Stop(TRequestStatus& aStatus)
+	{
+	LOG_FUNC
+	
+	// The service state should always be started when this function is called
+	// (guaranteed by CUsbSession)
+	__ASSERT_DEBUG( iState == EUsbServiceStarted, _USB_PANIC(KMsCcPanicCategory, EBadApiCall) );
+
+	TRequestStatus* reportStatus = &aStatus;
+	
+	TInt err = iUsbMs.Stop();
+	
+	if (err != KErrNone)
+		{
+		iState = EUsbServiceStarted;
+		User::RequestComplete(reportStatus, err);
+		LOGTEXT(_L8("Failed to stop mass storage device"));
+		return;
+		}	
+
+	iUsbMs.Close();
+
+	User::RequestComplete(reportStatus, KErrNone);
+	}
+
+/**
+ Gets information about the descriptor which this class provides. Never called
+ by usbMan.
+ 
+ @param aDescriptorInfo Descriptor info structure filled in by this function
+ */
+void CUsbMsClassController::GetDescriptorInfo(TUsbDescriptor& /*aDescriptorInfo*/) const
+	{
+	__ASSERT_DEBUG( EFalse, _USB_PANIC(KMsCcPanicCategory, EUnusedFunction));
+	}
+
+/**
+ Standard active object RunL. Never called because this class has no
+ asynchronous requests.
+ */
+void CUsbMsClassController::RunL()
+	{
+	__ASSERT_DEBUG( EFalse, _USB_PANIC(KMsCcPanicCategory, EUnusedFunction) );
+	}
+
+/**
+ Standard active object cancellation function. Never called because this
+ class has no asynchronous requests.
+ */
+void CUsbMsClassController::DoCancel()
+	{
+	__ASSERT_DEBUG( EFalse, _USB_PANIC(KMsCcPanicCategory, EUnusedFunction) );
+	}
+
+/**
+ Standard active object error function. Never called because this class has
+ no asynchronous requests, and hence its RunL is never called.
+ 
+ @param aError The error code (unused)
+ @return Always KErrNone to avoid an active scheduler panic
+ */
+TInt CUsbMsClassController::RunError(TInt /*aError*/)
+	{
+	__ASSERT_DEBUG( EFalse, _USB_PANIC(KMsCcPanicCategory, EUnusedFunction) );
+	return KErrNone;
+	}
+
+/**
+ Read mass storage configuration info from the resource file
+ */
+void CUsbMsClassController::ReadMassStorageConfigL()
+	{
+	LOG_FUNC
+
+	// Try to connect to file server
+	RFs fs;
+	LEAVEIFERRORL(fs.Connect());
+	CleanupClosePushL(fs);
+
+	RResourceFile resource;
+	TRAPD(err, resource.OpenL(fs, KUsbMsResource));
+	LOGTEXT2(_L8("Opened resource file with error %d"), err);
+
+	if (err != KErrNone)
+		{
+		LOGTEXT(_L8("Unable to open resource file"));
+		CleanupStack::PopAndDestroy(&fs);
+		return;
+		}
+
+	CleanupClosePushL(resource);
+
+	resource.ConfirmSignatureL(KUsbMsResourceVersion);
+
+	HBufC8* msConfigBuf = 0;
+	TRAPD(ret, msConfigBuf = resource.AllocReadL(USBMS_CONFIG));
+	if (ret != KErrNone)
+		{
+		LOGTEXT(_L8("Failed to open mass storage configuration file"));
+		CleanupStack::PopAndDestroy(2, &fs); 
+		return;
+		}
+	CleanupStack::PushL(msConfigBuf);
+	
+
+	// The format of the USB resource structure is:
+	
+	/* 	
+	 * 	STRUCT USBMASSSTORAGE_CONFIG
+	 *	{
+	 *	LTEXT	vendorId;           // no more than 8 characters
+	 *	LTEXT	productId;          // no more than 16 characters
+	 *	LTEXT	productRev;        	// no more than 4 characters
+	 *	};
+	 */
+	 
+	// Note that the resource must be read in this order!
+	
+	TResourceReader reader;
+	reader.SetBuffer(msConfigBuf);
+
+	TPtrC	vendorId		= reader.ReadTPtrC();
+	TPtrC	productId		= reader.ReadTPtrC();
+	TPtrC	productRev		= reader.ReadTPtrC();
+	
+	// populate iMsConfig, truncate if exceeding limit
+	ConfigItem(vendorId, iMsConfig.iVendorId, 8);
+	ConfigItem(productId, iMsConfig.iProductId, 16);
+	ConfigItem(productRev, iMsConfig.iProductRev, 4);
+	
+	// Debugging
+	LOGTEXT2(_L8("vendorId = %S\n"), 	&vendorId);
+	LOGTEXT2(_L8("productId = %S\n"), 	&productId);
+	LOGTEXT2(_L8("productRev = %S\n"), 	&productRev);
+		
+	CleanupStack::PopAndDestroy(3, &fs); // msConfigBuf, resource, fs		
+	}
+	
+/**
+ Utility. Copies the data from TPtr to TBuf and checks data length 
+ to make sure the source does not exceed the capacity of the target
+ */
+ void CUsbMsClassController::ConfigItem(const TPtrC& source, TDes& target, TInt maxLength)
+ 	{
+ 	if (source.Length() < maxLength)
+ 		{
+ 		maxLength = source.Length();
+ 		}
+ 		
+ 	target.Copy(source.Ptr(), maxLength);	 	
+ 	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/src/CUsbMsClassImpCollection.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,40 @@
+/*
+* 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 "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:
+* Defines the implementation collection for the mass storage class controller.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32base.h>
+#include <e32std.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include "CUsbMsClassController.h"
+
+// Define the private interface UIDs
+const TImplementationProxy UsbCCImplementationTable[] =
+    {
+	IMPLEMENTATION_PROXY_ENTRY(0x10204bbc, CUsbMsClassController::NewL),
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(UsbCCImplementationTable) / sizeof(TImplementationProxy);
+
+    return UsbCCImplementationTable;
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/src/usbms.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,39 @@
+/*
+* 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 "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:
+* Resource file for the USB mass storage configuration.
+*
+*/
+
+/**
+ @file
+*/
+
+NAME MSCF
+
+#include <badef.rh>
+#include "usbms.rh"
+
+RESOURCE BA_RSS_SIGNATURE
+	{
+	signature = 1;
+	}
+
+RESOURCE USBMASSSTORAGE_CONFIG usbms_config
+	{
+    vendorId    = "vendorId";      	// no more than 8 characters
+    productId   = "productId";      // no more than 16 characters
+    productRev  = "rev";    	    // no more than 4 characters
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/obex/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,18 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "classcontroller/group/bld.inf"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/obex/classcontroller/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,19 @@
+/*
+* 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 "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:
+*
+*/
+
+PRJ_TESTMMPFILES
+ObexClassController.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/obex/classcontroller/group/ObexClassController.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 1997-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:
+* ObexClassController.dll USB Class Controller Plugin, ref CC which loads/Starts/Stops whatever Obex implementation is desired
+*
+*/
+
+/**
+ @file
+*/
+
+
+target obexclasscontroller.dll //Recommended unpaged
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+targettype plugin
+
+// ECom Dll recognition UID followed by the unique dll UID 
+UID              	0x10009d8d 0x101fbf27
+VENDORID 0x70000001
+
+SOURCEPATH		../src
+SOURCE			CUsbObexClassImpCollection.cpp
+SOURCE			CUsbObexClassController.cpp
+
+USERINCLUDE         ../inc
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+start resource 101fbf27.rss
+target obexclasscontroller.rsc
+END
+
+LIBRARY			euser.lib 
+LIBRARY			usbclasscontroller.lib
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/obex/classcontroller/inc/CUsbObexClassController.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,81 @@
+/**
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class API and manages the class.
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBOBEXCLASSCONTROLLER_H__
+#define __CUSBOBEXCLASSCONTROLLER_H__
+
+#include <e32std.h>
+#include <cusbclasscontrollerplugin.h>
+#include <d32usbc.h>
+
+const TInt KObexClassPriority = 2;
+
+const TInt KObexDescriptorLength = 18;
+const TInt KObexMinNumEndpoints = 3;
+const TInt KObexClassNumber = 0x02;
+const TInt KObexNumInterfaces = 2;
+const TInt KObexSubClassNumber = 0x0b;
+const TInt KObexProtocolNumber = 0x0;
+const TInt KObexTotalEndpoints = 2;
+
+const TInt KObexDataClass = 0x0A;
+const TInt KObexDataSubClass = 0;
+const TInt KObexAlt0 = 0;
+const TInt KObexAlt1 = 1;
+const TInt KObexFunctionalDescriptorLength = 5;
+const TInt KObexInterfaceDescriptorLength = 9;
+
+_LIT(KUsbObexLddName, "eusbc");
+_LIT(KUsbObexIfc, "OBEX");
+
+NONSHARABLE_CLASS(CUsbObexClassController) : public CUsbClassControllerPlugIn
+	{
+public: // New functions.
+	static CUsbObexClassController* NewL(MUsbClassControllerNotify& aOwner);
+
+public: // Functions derived from CActive.
+	virtual void RunL();
+	virtual void DoCancel();
+	virtual TInt RunError(TInt aError);
+
+public: // Functions derived from CUsbClassControllerBase
+	virtual ~CUsbObexClassController();
+
+	virtual void Start(TRequestStatus& aStatus);
+	virtual void Stop(TRequestStatus& aStatus);
+
+	virtual void GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const;
+
+
+protected:
+	CUsbObexClassController(MUsbClassControllerNotify& aOwner);
+	TInt SetUpClassAndInterface();
+
+private:
+	RDevUsbcClient	iLdd;				// USB logical device drive			
+	RDevUsbcClient	iLdd2;
+	};
+
+#endif //__CUSBOBEXCLASSCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/obex/classcontroller/src/101fbf27.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x101fbf27;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x101fbf21;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x101fbf28;
+					version_no = 1;
+					display_name = "Obex";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/obex/classcontroller/src/CUsbObexClassController.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,394 @@
+/*
+* Copyright (c) 1997-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:
+* Implements part of UsbMan USB Class Framework.
+*
+*/
+
+/**
+ @file
+*/
+
+#include "CUsbObexClassController.h"
+#include <usb_std.h>
+#include <d32usbc.h>
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "OBEXCC");
+#endif
+
+
+// Panic category only used in debug builds
+#ifdef _DEBUG
+_LIT( KObexCcPanicCategory, "UsbObexCc" );
+#endif
+
+/**
+ * Panic codes for the USB OBEX Class Controller.
+ */
+enum TObexCCPanic
+	{
+	/** Asynchronous function called (not needed, as all requests complete synchronously) */
+	EUnusedFunction = 0,
+	/** Start() called while in an illegal state */
+	EBadApiCallStart = 1,
+	/** Stop() called while in an illegal state */
+	EBadApiCallStop = 2,
+	};
+
+const TInt KMaxPacketTypeBulk=64;
+
+/**
+ * Constructs a CUsbObexClassController object.
+ *
+ * @param aOwner USB Device that owns and manages the class
+ * @return A new CUsbObexClassController object
+ */
+CUsbObexClassController* CUsbObexClassController::NewL(
+	MUsbClassControllerNotify& aOwner)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbObexClassController* self =
+		new (ELeave) CUsbObexClassController(aOwner);
+	return self;
+	}
+
+/**
+ * Constructor.
+ *
+ * @param aOwner USB Device that owns and manages the class
+ */
+CUsbObexClassController::CUsbObexClassController(
+		MUsbClassControllerNotify& aOwner)
+	: CUsbClassControllerPlugIn(aOwner, KObexClassPriority)
+	{
+	iState = EUsbServiceIdle;
+	}
+
+/**
+ * Destructor.
+ */
+CUsbObexClassController::~CUsbObexClassController()
+	{
+	Cancel();
+	if (iState == EUsbServiceStarted) 
+		{
+		iLdd.ReleaseInterface(0);
+		iLdd.Close();
+		iLdd2.ReleaseInterface(1);
+		iLdd2.ReleaseInterface(0);
+		iLdd2.Close();
+		}
+	}
+
+/**
+ * SetupClassAndInterface.
+ *
+ * Sets the interface for use. This involves finding an "Interrupt IN" endpoint
+ * and if found configuring the interface.
+ */
+
+
+TInt CUsbObexClassController::SetUpClassAndInterface()
+	{
+	TUsbcInterfaceInfoBuf ifc;
+	
+	HBufC16* string = KUsbObexIfc().Alloc();
+	if (!string)
+		return KErrNoMemory;
+	
+	ifc().iString = string;
+	ifc().iClass.iClassNum = KObexClassNumber;		
+	ifc().iClass.iSubClassNum = KObexSubClassNumber;
+	ifc().iClass.iProtocolNum = KObexProtocolNumber;
+	ifc().iTotalEndpointsUsed = 0;
+	
+	// Indicate that this interface does not expect any control transfers 
+	// from EP0.
+	ifc().iFeatureWord |= KUsbcInterfaceInfo_NoEp0RequestsPlease;
+
+	TInt err = iLdd.SetInterface(0, ifc);
+	
+	// Get the interface number for later 
+	TBuf8<100> interfaceDescriptor;
+	iLdd.GetInterfaceDescriptor(0, interfaceDescriptor);
+	TUint8 OBEXIntNo = interfaceDescriptor.Ptr()[2];
+
+	delete string;
+
+	if (err != KErrNone) 
+		{ 
+		return err;
+		}
+
+	TBuf8<200> desc(0);
+
+	//Comms Class Header Functional Descriptor
+
+	desc.Append(KObexFunctionalDescriptorLength);
+	desc.Append(KUsbDescType_CS_Interface);
+	desc.Append(0);
+	desc.Append(0x10);
+	desc.Append(0x01);
+
+	// Obex Functional Descriptor
+
+	desc.Append(KObexFunctionalDescriptorLength);
+	desc.Append(KUsbDescType_CS_Interface);
+	desc.Append(0x15);
+	desc.Append(0x00);
+	desc.Append(0x01);
+
+	// Union Functional Descriptor
+	
+	desc.Append(KObexFunctionalDescriptorLength);
+	desc.Append(KUsbDescType_CS_Interface);	
+	desc.Append(0x06);								// descriptor type (Union)
+	desc.Append(OBEXIntNo);	
+	int dataInt = OBEXIntNo + 1;
+	desc.Append(dataInt);		
+
+	err= iLdd.SetCSInterfaceDescriptorBlock(0, desc);
+	if (err!= KErrNone)
+		{
+        return err;
+        }
+
+	err = iLdd2.Open(0);
+	if (err != KErrNone)
+		{
+        return err;
+        }
+
+	TUsbcInterfaceInfoBuf dataifc;
+
+	// Set data class interfaces
+    dataifc().iString = NULL;
+	dataifc().iClass.iClassNum = KObexDataClass;		
+	dataifc().iClass.iSubClassNum = KObexDataSubClass;
+	dataifc().iClass.iProtocolNum = 0;
+	dataifc().iTotalEndpointsUsed = 0;
+
+	// Indicate that this interface does not expect any control transfers 
+	// from EP0.
+	dataifc().iFeatureWord |= KUsbcInterfaceInfo_NoEp0RequestsPlease;
+	
+	err = iLdd2.SetInterface(0, dataifc);
+	if (err != KErrNone) 
+		{
+		iLdd2.Close();
+		return err;
+		}
+
+	TUsbDeviceCaps dCaps;
+	TInt ret = iLdd.DeviceCaps(dCaps);
+	if (ret != KErrNone) 
+		return ret;
+	
+	
+	TInt n = dCaps().iTotalEndpoints;
+	if (n < KObexMinNumEndpoints) 
+		return KErrGeneral;
+	
+	// Endpoints
+	TUsbcEndpointData data[KUsbcMaxEndpoints];
+	TPtr8 dataptr(REINTERPRET_CAST(TUint8*, data), sizeof(data), sizeof(data));
+	ret = iLdd.EndpointCaps(dataptr);
+	if (ret!= KErrNone) 
+		return ret;
+
+	// Set the active interface
+	
+    TUsbcInterfaceInfoBuf dataifc2;
+	TBool foundIn = EFalse;
+	TBool foundOut = EFalse;
+
+    for (TInt i = 0; !(foundIn && foundOut) && i < n; i++)
+        {
+        const TUsbcEndpointCaps* caps = &data[i].iCaps;
+        if (data[i].iInUse)
+            continue;
+
+		const TUint KBulkInFlags = KUsbEpTypeBulk | KUsbEpDirIn;
+		const TUint KBulkOutFlags = KUsbEpTypeBulk | KUsbEpDirOut;
+
+        if (!foundIn && (caps->iTypesAndDir & KBulkInFlags) == KBulkInFlags)
+            {
+            dataifc2().iEndpointData[0].iType  = KUsbEpTypeBulk;
+            dataifc2().iEndpointData[0].iDir   = KUsbEpDirIn; 	
+			TInt maxSize = caps->MaxPacketSize();
+			if (maxSize > KMaxPacketTypeBulk)
+				maxSize = KMaxPacketTypeBulk;
+			dataifc2().iEndpointData[0].iSize  = maxSize;
+			foundIn = ETrue;
+            }
+		else if (!foundOut && (caps->iTypesAndDir & KBulkOutFlags) == KBulkOutFlags)
+			{
+			dataifc2().iEndpointData[1].iType = KUsbEpTypeBulk;
+			dataifc2().iEndpointData[1].iDir = KUsbEpDirOut;
+			TInt maxSize = caps->MaxPacketSize();
+			if (maxSize > KMaxPacketTypeBulk)
+				maxSize = KMaxPacketTypeBulk;
+			dataifc2().iEndpointData[1].iSize  = maxSize;
+			foundOut = ETrue;
+			}
+		}
+		
+    if (!(foundIn && foundOut)) 
+		return KErrGeneral;
+	
+	dataifc2().iString = NULL;
+	dataifc2().iClass.iClassNum = KObexDataClass;		
+	dataifc2().iClass.iSubClassNum = KObexDataSubClass;
+	dataifc2().iClass.iProtocolNum = 0;
+	dataifc2().iTotalEndpointsUsed = KObexTotalEndpoints;
+	
+	// Indicate that this interface does not expect any control transfers 
+	// from EP0.
+	dataifc2().iFeatureWord |= KUsbcInterfaceInfo_NoEp0RequestsPlease;
+	
+	err = iLdd2.SetInterface(1, dataifc2);
+	if (err != KErrNone) 
+		{
+		iLdd2.ReleaseInterface(0);
+		iLdd2.Close();
+		return err;
+
+		}
+	return KErrNone;
+	}
+
+/**
+ * Called by UsbMan to start this class.
+ *
+ * @param aStatus Will be completed with success or failure.
+ */
+void CUsbObexClassController::Start(TRequestStatus& aStatus)
+	{	
+	LOG_FUNC
+
+	//Start() should never be called if started, starting or stopping (or in state EUsbServiceFatalError)
+	__ASSERT_DEBUG( iState == EUsbServiceIdle, _USB_PANIC(KObexCcPanicCategory, EBadApiCallStart) );
+	
+	TRequestStatus* reportStatus = &aStatus;
+	
+	iState = EUsbServiceStarting;
+
+	TInt err = User::LoadLogicalDevice(KUsbObexLddName);
+	if (err != KErrNone && err != KErrAlreadyExists) 
+		{
+		User::RequestComplete(reportStatus, err);
+		iState = EUsbServiceIdle;
+		return;      
+		} 
+		
+	err = iLdd.Open(0);
+	if(err != KErrNone)
+		{
+		iState = EUsbServiceIdle;
+		User::RequestComplete(reportStatus, err);
+
+		return;	
+		}
+
+	err = SetUpClassAndInterface();
+	if (err != KErrNone) 
+		{
+		iLdd.Close();
+		iState = EUsbServiceIdle;
+		User::RequestComplete(reportStatus, err);
+		
+		return;
+		}
+		
+	iState = EUsbServiceStarted;
+	User::RequestComplete(reportStatus, KErrNone);
+	}
+
+
+/**
+ * Called by UsbMan to stop this class.
+ *
+ * @param aStatus Will be completed with success or failure.
+ */
+void CUsbObexClassController::Stop(TRequestStatus& aStatus)
+	{
+	LOG_FUNC
+
+	//Stop() should never be called if stopping, idle or starting (or in state EUsbServiceFatalError)
+	__ASSERT_DEBUG( iState == EUsbServiceStarted, _USB_PANIC(KObexCcPanicCategory, EBadApiCallStop) );
+
+	TRequestStatus* ReportStatus = &aStatus;
+
+	iState = EUsbServiceStopping;
+
+	// We should probably check the return codes of these calls and report that
+	// we couldn't stop if they fail.
+	iLdd.ReleaseInterface(0);
+	iLdd.Close();
+	iLdd2.ReleaseInterface(1);
+	iLdd2.ReleaseInterface(0);
+	iLdd2.Close();
+
+	iState = EUsbServiceIdle;
+
+	User::RequestComplete(ReportStatus, KErrNone);
+	}
+
+
+/**
+ * Returns information about the interfaces supported by this class.
+ *
+ * @param aDescriptorInfo Will be filled in with interface information.
+ */
+void CUsbObexClassController::GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const
+	{
+	aDescriptorInfo.iNumInterfaces = KObexNumInterfaces;
+	aDescriptorInfo.iLength = KObexDescriptorLength;
+	}
+
+/**
+ * Standard active object RunL. 
+ *
+ * This is never called as this class does not have any asynchronous requests
+ */
+void CUsbObexClassController::RunL()
+	{
+	__ASSERT_DEBUG(EFalse, _USB_PANIC(KObexCcPanicCategory, EUnusedFunction));
+	}
+
+/**
+ * Standard active object cancellation function. 
+ *
+ * Will only be called when an asynchronous request is currently active.
+ */
+void CUsbObexClassController::DoCancel()
+	{
+	__ASSERT_DEBUG(EFalse, _USB_PANIC(KObexCcPanicCategory, EUnusedFunction));
+	}
+
+/**
+ * Standard active object error-handling function. 
+ *
+ * Should return KErrNone to avoid an active scheduler panic. This function
+ * should never be called as there is another mechanism for catching errors.
+ */
+
+TInt CUsbObexClassController::RunError(TInt /*aError*/)
+	{
+	__ASSERT_DEBUG(EFalse, _USB_PANIC(KObexCcPanicCategory, EUnusedFunction));
+	return KErrNone;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/obex/classcontroller/src/CUsbObexClassImpCollection.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 1997-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:
+* Defines the implementation collection for the USB Obex class controller.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32base.h>
+#include <e32std.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include "CUsbObexClassController.h"
+
+// Define the private interface UIDs
+const TImplementationProxy UsbCCImplementationTable[] =
+    {
+	IMPLEMENTATION_PROXY_ENTRY(0x101fbf28, CUsbObexClassController::NewL),
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(UsbCCImplementationTable) / sizeof(TImplementationProxy);
+
+    return UsbCCImplementationTable;
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/whcm/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,18 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "classcontroller/group/bld.inf"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/INC/CUsbWHCMClassController.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,86 @@
+/**
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class API and manages the class.
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBWHCMCLASSCONTROLLER_H__
+#define __CUSBWHCMCLASSCONTROLLER_H__
+
+#include <e32std.h>
+#include <cusbclasscontrollerplugin.h>
+#include <d32usbc.h>
+
+const TInt KWHCMPriority = 1;
+const TInt KWHCMSubClass = 0x08;
+const TInt KWHCMProtocol = 0;
+const TInt KWHCMFuncDescID = 0x11;
+
+/**
+ * A structure to hold most of the data for the descriptors in a WHCM header.
+ * The rest is filled out dynamically.
+ */
+static const TUint8 WHCMheader[] =
+	{
+	// Comms Class Header Functional Desctriptor
+	5, KUsbDescType_CS_Interface, 0, 0x10, 0x01,
+
+	// WHCM Functional Descriptor
+	5, KUsbDescType_CS_Interface, KWHCMFuncDescID, 0x00, 0x01,
+
+	// Union Functional Descriptor
+	4 /* length, updated later once subordinates are known */, KUsbDescType_CS_Interface, 0x06
+	// interface number and subordinates added later
+	};
+
+/**
+ * Class Controller for the WHCM union class.
+ */
+NONSHARABLE_CLASS(CUsbWHCMClassController) : public CUsbClassControllerPlugIn
+	{
+public: // New functions.
+	static CUsbWHCMClassController* NewL(
+		MUsbClassControllerNotify& aOwner);
+
+public: // Functions derived from CActive.
+	virtual void RunL();
+	virtual void DoCancel();
+	virtual TInt RunError(TInt aError);
+
+public: // Functions derived from CUsbClassControllerBase
+	virtual ~CUsbWHCMClassController();
+
+	virtual void Start(TRequestStatus& aStatus);
+	virtual void Stop(TRequestStatus& aStatus);
+
+	virtual void GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const;
+
+protected:
+	CUsbWHCMClassController(MUsbClassControllerNotify& aOwner);
+	void ConstructL();
+	void SetUpWHCMDescriptorL();
+
+private:
+	RDevUsbcClient	iLdd;				// USB logical device drive			
+	};
+
+#endif //__CUSBWHCMCLASSCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/SRC/101fbf23.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x101fbf23;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x101fbf21;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x101fbf24;
+					version_no = 1;
+					display_name = "WHCM";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/SRC/CUsbWHCMClassController.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,283 @@
+/*
+* Copyright (c) 1997-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:
+* Implements part of UsbMan USB Class Framework.
+*
+*/
+
+/**
+ @file
+*/
+
+#include "CUsbWHCMClassController.h"
+#include <usb_std.h>
+#include <cusbclasscontrolleriterator.h>
+#include <musbclasscontrollernotify.h>
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "WHCMCC");
+#endif
+
+_LIT(KUsbLDDName, "eusbc");
+
+_LIT( KWhcmCcPanicCategory, "UsbWhcmCc" );
+
+/**
+ * Panic codes for the USB WHCM Class Controller.
+ */
+enum TWhcmCcPanic
+	{
+	/** Start() called while in an illegal state */
+	EBadApiCallStart = 0,
+	/** Asynchronous function called (not needed, as all requests complete synchronously) */
+	EUnusedFunction = 1,
+	/** Stop() called while in an illegal state */
+	EBadApiCallStop = 2
+	};
+
+/**
+ * Constructs a CUsbWHCMClassController object.
+ *
+ * @param aOwner USB Device that owns and manages the class
+ * @return A new CUsbWHCMClassController object
+ */
+CUsbWHCMClassController* CUsbWHCMClassController::NewL(
+	MUsbClassControllerNotify& aOwner)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbWHCMClassController* self =
+		new (ELeave) CUsbWHCMClassController(aOwner);
+
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+/**
+ * Constructor.
+ *
+ * @param aOwner USB Device that owns and manages the class
+ */
+CUsbWHCMClassController::CUsbWHCMClassController(
+		MUsbClassControllerNotify& aOwner)
+	: CUsbClassControllerPlugIn(aOwner, KWHCMPriority)
+	{
+	iState = EUsbServiceIdle;
+	}
+
+/**
+ * Method to perform second phase construction.
+ */
+void CUsbWHCMClassController::ConstructL()
+	{
+	// Load the device driver
+	TInt err = User::LoadLogicalDevice(KUsbLDDName);
+	if (err != KErrNone && err != KErrAlreadyExists) 
+		{
+		LEAVEL(err);      
+		} 
+
+	LEAVEIFERRORL(iLdd.Open(0));
+	}
+
+/**
+ * Destructor.
+ */
+CUsbWHCMClassController::~CUsbWHCMClassController()
+	{
+	Cancel();
+
+	if (iState == EUsbServiceStarted)
+		{
+		// Must release all interfaces before closing the LDD to avoid a crash.
+		iLdd.ReleaseInterface(0);
+		}
+	iLdd.Close();
+	}
+
+/**
+ * Called by UsbMan to start this class.
+ *
+ * @param aStatus Will be completed with success or failure.
+ */
+void CUsbWHCMClassController::Start(TRequestStatus& aStatus)
+	{
+	LOG_FUNC
+		
+	//Start() should never be called if started, starting or stopping (or in state EUsbServiceFatalError)
+	__ASSERT_DEBUG( iState == EUsbServiceIdle, _USB_PANIC(KWhcmCcPanicCategory, EBadApiCallStart) );
+	
+	TRequestStatus* reportStatus = &aStatus;
+
+	iState = EUsbServiceStarting;
+
+	TRAPD(err, SetUpWHCMDescriptorL());
+
+	if (err != KErrNone) 
+		{
+		iState = EUsbServiceIdle;
+		User::RequestComplete(reportStatus, err);
+		return;
+		}
+	iState = EUsbServiceStarted;
+	User::RequestComplete(reportStatus, KErrNone);
+	}
+
+/**
+ * Called by UsbMan to stop this class.
+ *
+ * @param aStatus Will be completed with success or failure.
+ */
+void CUsbWHCMClassController::Stop(TRequestStatus& aStatus)
+	{
+	LOG_FUNC
+
+	//Stop() should never be called if stopping, idle or starting (or in state EUsbServiceFatalError)
+	__ASSERT_DEBUG( iState == EUsbServiceStarted, _USB_PANIC(KWhcmCcPanicCategory, EBadApiCallStop) );
+
+	TRequestStatus* reportStatus = &aStatus;
+
+	// Must release all interfaces before closing the LDD to avoid a crash.
+	iLdd.ReleaseInterface(0);
+
+	iState = EUsbServiceIdle;
+
+	aStatus = KRequestPending;
+
+	User::RequestComplete(reportStatus, KErrNone);
+	}
+
+/**
+ * Returns information about the interfaces supported by this class.
+ *
+ * @param aDescriptorInfo Will be filled in with interface information.
+ */
+void CUsbWHCMClassController::GetDescriptorInfo(
+	TUsbDescriptor& /*aDescriptorInfo*/) const
+	{
+	}
+
+/**
+ * Standard active object RunL.
+ */
+void CUsbWHCMClassController::RunL()
+	{
+	// This function should never be called.
+	_USB_PANIC(KWhcmCcPanicCategory, EUnusedFunction);
+	}
+
+/**
+ * Standard active object cancellation function. Will only be called when an
+ * asynchronous request is currently active.
+ */
+void CUsbWHCMClassController::DoCancel()
+	{
+	// This function should never be called.
+	_USB_PANIC(KWhcmCcPanicCategory, EUnusedFunction);
+	}
+
+/**
+ * Standard active object error-handling function. Should return KErrNone to
+ * avoid an active scheduler panic.
+ */
+TInt CUsbWHCMClassController::RunError(TInt /*aError*/)
+	{
+	// This function should never be called.
+	_USB_PANIC(KWhcmCcPanicCategory, EUnusedFunction);
+
+	return KErrNone;
+	}
+
+
+void CUsbWHCMClassController::SetUpWHCMDescriptorL()
+/**
+ * Setup the WHCM Class Descriptors.
+ */
+    {
+	// Set up and register the WHCM interface descriptor
+
+    TUsbcInterfaceInfoBuf ifc;
+	ifc().iString = NULL;
+	ifc().iClass.iClassNum = 0x02;
+	ifc().iClass.iSubClassNum =  KWHCMSubClass;
+	ifc().iClass.iProtocolNum = KWHCMProtocol;
+	ifc().iTotalEndpointsUsed = 0;
+
+	// Indicate that this interface does not expect any control transfers 
+	// from EP0.
+	ifc().iFeatureWord |= KUsbcInterfaceInfo_NoEp0RequestsPlease;
+
+	LEAVEIFERRORL(iLdd.SetInterface(0, ifc));
+
+	// Get the interface number from the LDD for later reference
+	TBuf8<100> interface_descriptor;
+	LEAVEIFERRORL(iLdd.GetInterfaceDescriptor(0, interface_descriptor));
+	
+		
+	TUint8 WHCM_int_no = interface_descriptor[2];
+
+	// Set up the class-specific interface block.
+	// This consists of:
+	//		Comms Class Header Functional Desctriptor
+	//		WHCM Functional Descriptor
+	//		Union Functional Descriptor
+	// Most of the data is copied from the static const structure in the header file.
+
+	TBuf8<200> desc;
+	desc.Copy(WHCMheader, sizeof(WHCMheader));
+
+	// Append the interface number to the Union Functional Descriptor
+	desc.Append( WHCM_int_no );
+
+    // In order to finish off the Union Functional Descriptor we need to fill
+	// out the Subordinate Class list.
+	// We can do this by iterating through the remaining class controllers in the
+	// owner's list to find all the the subordinate classes.
+
+	// Two assumptions are made here:
+	//		1) That all the remaining controller in the list (after this one)
+	//		   are subordinate classes of this WHCM class.
+	//		2) That their interface numbers will be assigned contiguously.
+
+	TInt if_number = WHCM_int_no + 1;	// for counting interface numbers
+	TUint8 union_len = 4;				// for holding the length of the union descriptor
+
+	// Iterate through the class controllers
+	CUsbClassControllerIterator *iterator = Owner().UccnGetClassControllerIteratorL();
+
+	iterator->Seek(this);
+
+	while(    (iterator->Next() != KErrNotFound)
+			&& (iterator->Current()->StartupPriority() >= StartupPriority()) )
+		{
+		// Found another class in the union. Add it to our list.
+		TUsbDescriptor desc_info;
+		iterator->Current()->GetDescriptorInfo(desc_info);
+		for (TInt i=0; i<desc_info.iNumInterfaces; i++)
+			{
+			desc.Append(if_number++);
+			union_len++;
+			}
+		}
+    delete iterator;
+	// We have added to the Union Functional Descriptor.
+	// So we need to insert the new length into it.
+	desc[10] = union_len;
+
+	// Register the whole class-specific interface block
+    LEAVEIFERRORL(iLdd.SetCSInterfaceDescriptorBlock(0, desc));	
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/SRC/CUsbWHCMClassImpCollection.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 1997-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:
+* Defines the ECom implementation collection for the USB WHCM class controller.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32base.h>
+#include <e32std.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include "CUsbWHCMClassController.h"
+
+// Define the private interface UIDs
+const TImplementationProxy UsbCCImplementationTable[] =
+    {
+	IMPLEMENTATION_PROXY_ENTRY(0x101fbf24, CUsbWHCMClassController::NewL),
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(UsbCCImplementationTable) / sizeof(TImplementationProxy);
+
+    return UsbCCImplementationTable;
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/group/WHCMClassController.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 1997-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:
+* WHCMClassController.dll USB Plugin, must be include in ROM if producing a WHCM device
+*
+*/
+
+/**
+ @file
+*/
+
+
+target whcmclasscontroller.dll //Recommended unpaged
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+targettype plugin
+
+// ECom Dll recognition UID followed by the unique dll UID 
+UID              	0x10009d8d 0x101fbf23
+VENDORID 0x70000001
+
+SOURCEPATH		../SRC
+SOURCE			CUsbWHCMClassImpCollection.cpp
+SOURCE			CUsbWHCMClassController.cpp
+
+USERINCLUDE		../INC
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+start resource 101fbf23.rss
+target whcmclasscontroller.rsc
+END
+
+LIBRARY			euser.lib 
+LIBRARY			usbclasscontroller.lib
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+/*
+* 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 "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:
+* OptionalClassControllers.inf
+* Builds class controllers which may be included
+* in a ROM at rombuild time but which are not required for
+* the emulator
+*
+*/
+
+
+PRJ_MMPFILES
+
+#if !(defined(WINS) || defined(WINSCW))	
+WHCMClassController.mmp	// WHCM Class Controller plugin
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/inf-files/symusb2k-XP.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,142 @@
+; 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:
+; Symbian USB Phone Setup File
+; 
+;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; LICENSEES - SEE END OF FILE FOR CONFIGURATION SECTION ;;
+;; =========   THE REST OF THIS FILE SHOULD NOT REQUIRE  ;;
+;;             MODIFICATION FOR STANDARD DISTRIBUTIONS   ;;
+;;                                                       ;;
+;; Comments with licensee instructions are preceeded by  ;;
+;; >>> so that they can be easily found and removed.     ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[Version]
+LayoutFile=layout.inf
+Signature=$WINDOWS NT$
+Class=Modem
+Provider=Symbian
+CLASSGUID={4D36E96D-E325-11CE-BFC1-08002BE10318}
+DriverVer =07/01/2001,5.1.2535.0
+
+[Manufacturer]
+Symbian=Models
+
+[ControlFlags]
+ExcludeFromSelect= *
+
+[DestinationDirs]
+FakeModemCopyFileSection=12
+DefaultDestDir=12
+
+[Models]
+%MODEL_NAME% = SymbianUSB, %MODEL_HARDWARE_ID%
+;>>> Note: we recommend that each .INF file supports just one model and that multiple models
+;>>>       are handled by multiple .INF files
+
+[SymbianUSB.NT]
+CopyFiles=FakeModemCopyFileSection
+AddReg = All, MfgAddReg, Modem1.AddReg, EXTERNAL
+
+[SymbianUSB.NT.Services]
+AddService=usbser, 0x00000000, LowerFilter_Service_Inst
+
+[SymbianUSB.NT.HW]
+AddReg=LowerFilterAddReg
+
+[LowerFilterAddReg]
+HKR,,"LowerFilters",0x00010000,"usbser"
+
+[LowerFilter_Service_Inst]
+DisplayName = %MODEL_NAME%
+ServiceType = 1
+StartType = 3
+ErrorControl = 0
+ServiceBinary = %12%\usbser.sys
+
+[FakeModemCopyFileSection]
+usbser.sys,,,0x20
+
+[All]
+HKR,,FriendlyDriver,,unimodem.vxd
+HKR,,DevLoader,,*vcomm
+
+HKR,,ConfigDialog,0,modemui.dll
+HKR,,EnumPropPages,0,modemui.dll,EnumPropPages
+HKR,,PortSubClass,1,02
+HKR, Init,      1,, "AT<cr>"
+HKR, Responses, "<cr><lf>OK<cr><lf>", 1, 00, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>ERROR<cr><lf>", 1, 03, 00, 00,00,00,00, 00,00,00,00
+
+[Modem1.AddReg]
+HKR,, DeviceType, 1, 01      ; External
+HKR,, DCB, 1, 1C,00,00,00, 00,c2,01,00, 15,20,00,00, 00,00, 0a,00, 0a,00, 08, 00, 00, 11, 13, 00, 00, 00
+HKR,, Properties, 1, 00,00,00,00, 32,00,00,00, ff,00,00,00, 00,00,00,00, 00,00,00,00, 30,00,00,00, 00,c2,01,00, 00,F4,01,00
+HKR, Init,      4,, "ATG1=2G11=2<cr>"
+
+[EXTERNAL]
+HKR,, DeviceType, 1, 01
+
+[MfgAddReg]
+HKR,, InactivityScale, 1, 3c,00,00,00
+HKR, Init,      2,, "AT&FX1E0&D2&C1<cr>"
+HKR, Init,      3,, "ATV1S0=0G44=0<cr>"
+HKR, Monitor, 	1,, "ATS0=0<cr>"
+HKR, Monitor, 	2,, "None"
+
+HKR, Hangup,    1,, "ATH<cr>"
+HKR, Answer,    1,, "ATA<cr>"
+HKR,, Reset,, "ATZ<cr>"
+HKR, Settings, Prefix,, "AT"
+HKR, Settings, Terminator,, "<cr>"
+HKR, Settings, DialPrefix,, "D"
+HKR, Settings, DialSuffix,, ""
+HKR, Settings, FlowControl_Off,, "\Q0"
+HKR, Settings, FlowControl_Hard,, "\Q3"
+HKR, Settings, FlowControl_Soft,, "\Q1"
+HKR, Settings, CallSetupFailTimer,, "S7=<#>"
+HKR, Settings, InactivityTimeout,, "C26=<#>"
+
+HKR, Responses, "<cr><lf>NO CARRIER<cr><lf>"     , 1, 04, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>NO DIALTONE<cr><lf>"   , 1, 05, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>BUSY<cr><lf>"          , 1, 06, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>NO ANSWER<cr><lf>"     , 1, 07, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>RING<cr><lf>"          , 1, 08, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>DELAYED<cr><lf>"       , 1, 1d, 00, 00,00,00,00, 00,00,00,00
+
+HKR, Responses, "<cr><lf>CONNECT<cr><lf>"       , 1, 02, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 9600<cr><lf>"  , 1, 02, 00, 80,25,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 19200<cr><lf>" , 1, 02, 00, 00,4b,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 38400<cr><lf>" , 1, 02, 00, 00,96,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000<cr><lf>" , 1, 02, 00, 00,fa,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 128000<cr><lf>", 1, 02, 00, 00,f4,01,00, 00,00,00,00
+HKR, Responses, "<cr><lf>ACON<cr><lf>"          , 1, 02, 00, 00,00,00,00, 00,00,00,00
+
+HKR, Responses, "0<cr>"  , 1, 00, 00, 00,00,00,00, 00,00,00,00 ; OK
+HKR, Responses, "2<cr>"  , 1, 08, 00, 00,00,00,00, 00,00,00,00 ; RING
+HKR, Responses, "3<cr>"  , 1, 04, 00, 00,00,00,00, 00,00,00,00 ; NO CARRIER
+HKR, Responses, "4<cr>"  , 1, 03, 00, 00,00,00,00, 00,00,00,00 ; ERROR
+HKR, Responses, "6<cr>"  , 1, 05, 00, 00,00,00,00, 00,00,00,00 ; for WHQL dummy
+HKR, Responses, "7<cr>"  , 1, 06, 00, 00,00,00,00, 00,00,00,00 ; NO ANSWER
+HKR, Responses, "8<cr>"  , 1, 07, 00, 00,00,00,00, 00,00,00,00 ; for WHQL dummy
+
+;>>>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;>>> Licensee Configuration Section ;;;
+;>>>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+[Strings]
+;>>> Name of one-and-only supported hardware model, and hardware signature of that model
+MODEL_NAME = "Lubbock"
+MODEL_HARDWARE_ID = "USB\VID_0E22&PID_000B"  ;; USB Vendor ID 0x0E22, Product ID 0x000B
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/inf-files/symusb_98_6.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,73 @@
+; Copyright (c) 2003-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:
+; Windows Device Setup File
+;
+; USB Modem installer for Windows 98, Part 1/2
+; This file is for the 'USB Composite Device' which is detected by
+; Windows 98. The modem installation takes places afterwards (see
+; symb_98_7.inf).
+;
+;
+
+
+[Version]
+Signature  = $WINDOWS NT$
+Class      = USB
+ClassGuid  = {36FC9E60-C465-11CF-8056-444553540000}
+Provider   = %String0%
+LayoutFile = layout.inf
+
+[DestinationDirs]
+Files.usbser   = 10, SYSTEM32\DRIVERS   ; 10 = %windir%
+Files.ccport   = 10, SYSTEM32\DRIVERS
+Files.wdmmdmld = 11                     ; 11 = %windir%\system (on Win98)
+
+[PreCopySection]
+HKR, , NoSetupUI, , 1
+
+[Manufacturer]
+%String1% = Models
+
+[Models]
+%String2% = SYMUSB, USB\VID_0E22&PID_000B
+
+[SYMUSB]
+CopyFiles = Files.usbser, Files.ccport, Files.wdmmdmld
+AddReg    = SYMUSB.AddReg
+
+[SYMUSB.AddReg]
+HKR, , DevLoader, , *ntkern
+HKR, , NTMPDriver, , "usbser.sys,ccport.sys"
+
+[SYMUSB.HW]
+AddReg = SYMUSBAddReg.HW
+
+[SYMUSBAddReg.HW]
+HKR, , ChildID, , USB\SYMBIAN
+
+[Files.usbser]
+usbser.sys
+
+[Files.ccport]
+ccport.sys
+
+[Files.wdmmdmld]
+wdmmdmld.vxd
+
+[Strings]
+String0 = "Symbian Ltd"
+String1 = "Symbian Ltd, London (UK)"
+String2 = "Lubbock USB Modem Test Driver"
+
+; --- eof ---
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/inf-files/symusb_98_7.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,45 @@
+; Copyright (c) 2003-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:
+; Windows Device Setup File
+;
+; USB Modem installer for Windows 98, Part 2/2
+; This file is given to Windows after the USB device is installed and
+; (immediately) a new (unknown) device gets detected. This will becoming
+; the modem.
+;
+
+[Version]
+Signature  = $WINDOWS NT$
+Class      = Modem
+ClassGuid  = {4D36E96D-E325-11CE-BFC1-08002BE10318}
+Provider   = %String0%
+LayoutFile = layout.inf
+
+[Manufacturer]
+%String1% = Models
+
+[Models]
+%String2% = SYMUSB, USB\SYMBIAN
+
+[SYMUSB]
+Include = symusb_98_9.inf
+Needs   = Main, Properties, PortDriver, External, Responses
+AddReg  = Main, Properties, PortDriver, External, Responses
+
+[Strings]
+String0 = "Symbian Ltd"
+String1 = "Symbian Ltd, London (UK)"
+String2 = "Lubbock USB Modem Test Driver"
+
+; --- eof ---
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/inf-files/symusb_98_9.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,160 @@
+; Copyright (c) 2003-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:
+; Windows Device Setup File
+;
+; USB Modem installer for Windows 98/2000
+; This file contains the modem registry keys. It is included by both the
+; Windows 98 and 2000 inf file. Since no device is actually installed, the
+; ClassGuid is set to all zeroes.
+;
+;
+
+[Version]
+Signature  = $WINDOWS NT$
+ClassGuid  = {00000000-0000-0000-0000-000000000000}
+Provider   = %String0%
+LayoutFile = layout.inf
+
+[Main]
+HKR,,FriendlyDriver,,unimodem.vxd
+HKR,,DevLoader,,*vcomm
+HKR,,PortSubClass,1,02
+HKR,,ConfigDialog,,modemui.dll
+HKR,,EnumPropPages,,modemui.dll,EnumPropPages
+HKR, Init,      1,, "AT<cr>"
+HKR, Monitor,   1,, "ATS0=0<cr>"
+HKR, Monitor,   2,, "None"
+HKR, Hangup,    1,, "ATH<cr>"
+HKR, Answer,    1,, "ATA<cr>"
+HKR,, Reset,, "ATZ<cr>"
+HKR, Settings, Prefix,, "AT"
+HKR, Settings, Terminator,, "<cr>"
+HKR, Settings, DialPrefix,, "D"
+HKR, Settings, DialSuffix,, ""
+HKR, Settings, FlowControl_Off,, "\Q0"
+HKR, Settings, FlowControl_Hard,, "\Q3"
+HKR, Settings, FlowControl_Soft,, "\Q1"
+HKR,, InactivityScale,1,0a,00,00,00
+HKR, Settings, InactivityTimeout,, "S30=<#>"
+
+[Properties]
+HKR,,Properties,1,00,00,00,00,00,00,00,00,FF,00,00,00,00,00,00,00,00,00,00,00,30,00,00,00,00,C2,01,00,00,FA,00,00
+
+[PortDriver]
+HKR, , PortDriver, , wdmmdmld.vxd
+HKR, , Contention, 0,
+
+[External]
+HKR, , DeviceType, 1, 01
+
+[Responses]
+; This selection of responses is by no means exhausting (probably not even
+; suitable for our device). But better to have this than nothing at all...
+; It was copied verbatim from mdmelsa5.inf from the ML ISDN 2 a/b project.
+;
+HKR, Responses, "0<cr>", 	1, 00, 00, 00,00,00,00, 00,00,00,00  ; OK
+HKR, Responses, "1<cr>",	1, 02, 00, 00,00,00,00, 00,00,00,00  ; CONNECT
+HKR, Responses, "2<cr>",	1, 08, 00, 00,00,00,00, 00,00,00,00  ; RING
+HKR, Responses, "3<cr>",	1, 04, 00, 00,00,00,00, 00,00,00,00  ; NO CARRIER
+HKR, Responses, "4<cr>",	1, 03, 00, 00,00,00,00, 00,00,00,00  ; ERROR
+HKR, Responses, "6<cr>",	1, 05, 00, 00,00,00,00, 00,00,00,00  ; NO DIALTONE
+HKR, Responses, "7<cr>",	1, 06, 00, 00,00,00,00, 00,00,00,00  ; BUSY
+
+HKR, Responses, "<cr><lf>CONNECT<cr><lf>",	1, 02, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>OK<cr><lf>",		1, 00, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>ERROR<cr><lf>",	1, 03, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>RING<cr><lf>",		1, 08, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>NO CARRIER<cr><lf>",	1, 04, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>NO DIALTONE<cr><lf>",	1, 05, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>BUSY<cr><lf>",		1, 06, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>NO ANSWER<cr><lf>",	1, 07, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECTING<cr><lf>",	1, 01, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CALL SENT<cr><lf>",	1, 01, 00, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>ALERTING<cr><lf>",	1, 01, 00, 00,00,00,00, 00,00,00,00
+
+HKR, Responses, "<cr><lf>CONNECT 38400<cr><lf>",	1, 02, 00, 00,96,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 48000<cr><lf>",	1, 02, 00, 80,BB,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 56000<cr><lf>",	1, 02, 00, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000<cr><lf>",	1, 02, 00, 00,FA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 56000/REL<cr><lf>",	1, 02, 02, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000/REL<cr><lf>",	1, 02, 02, 00,FA,00,00, 00,00,00,00
+
+; ISDN transparent no compression / no errorcorrection
+
+HKR, Responses, "<cr><lf>CONNECT 56000<cr><lf>",	1, 02, 00, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000<cr><lf>",	1, 02, 00, 00,FA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 112000<cr><lf>",	1, 02, 00, 08,B5,01,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 128000<cr><lf>",	1, 02, 00, 00,F4,01,00, 00,00,00,00
+
+; ISDN V110:  no compression / no errorcorrection
+
+HKR, Responses, "<cr><lf>CONNECT 1200/ISDN/V110<cr><lf>",	1, 02, 00, B0,04,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 2400/ISDN/V110<cr><lf>",	1, 02, 00, 60,09,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 4800/ISDN/V110<cr><lf>",	1, 02, 00, C0,12,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 9600/ISDN/V110<cr><lf>",	1, 02, 00, 80,25,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 19200/ISDN/V110<cr><lf>",	1, 02, 00, 00,4B,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 38400/ISDN/V110<cr><lf>",	1, 02, 00, 00,96,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 48000/ISDN/V110<cr><lf>",	1, 02, 00, 80,BB,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 56000/ISDN/V110<cr><lf>",	1, 02, 00, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000/ISDN/V110<cr><lf>",	1, 02, 00, 00,FA,00,00, 00,00,00,00
+
+; ISDN HDLC/V120/X75 errorcorrection / no compression
+
+HKR, Responses, "<cr><lf>CONNECT 56000/REL<cr><lf>",		1, 02, 02, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000/REL<cr><lf>",		1, 02, 02, 00,FA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 56000/REL-LAPB<cr><lf>",	1, 02, 02, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000/REL-LAPB<cr><lf>",	1, 02, 02, 00,FA,00,00, 00,00,00,00
+
+HKR, Responses, "<cr><lf>CONNECT 56000/ISDN/BTX<cr><lf>",	1, 02, 02, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000/ISDN/BTX<cr><lf>",	1, 02, 02, 00,FA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 56000/ISDN/HDLCP<cr><lf>",	1, 02, 00, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000/ISDN/HDLCP<cr><lf>",	1, 02, 00, 00,FA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 56000/ISDN/HDLC<cr><lf>",	1, 02, 00, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000/ISDN/HDLC<cr><lf>",	1, 02, 00, 00,FA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 56000/ISDN/V120<cr><lf>",	1, 02, 02, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000/ISDN/V120<cr><lf>",	1, 02, 02, 00,FA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 56000/ISDN/X75<cr><lf>",	1, 02, 02, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000/ISDN/X75<cr><lf>",	1, 02, 02, 00,FA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 112000/ISDN/X75<cr><lf>",	1, 02, 02, 80,B5,01,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 128000/ISDN/X75<cr><lf>",	1, 02, 02, 00,F4,01,00, 00,00,00,00
+
+; ISDN V120/X75 compression / errorcorrection
+
+HKR, Responses, "<cr><lf>CONNECT 56000/ISDN/V120/V42BIS<cr><lf>",	1, 02, 03, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000/ISDN/V120/V42BIS<cr><lf>",	1, 02, 03, 00,FA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 56000/ISDN/X75/V42BIS<cr><lf>",	1, 02, 03, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000/ISDN/X75/V42BIS<cr><lf>",	1, 02, 03, 00,FA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 112000/ISDN/X75/V42BIS<cr><lf>",	1, 02, 03, 80,B5,01,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 128000/ISDN/X75/V42BIS<cr><lf>",	1, 02, 03, 00,F4,01,00, 00,00,00,00
+
+HKR, Responses, "<cr><lf>CONNECT 56000/ISDN/X75/V42BIS/MLP<cr><lf>",	1, 02, 03, C0,DA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 64000/ISDN/X75/V42BIS/MLP<cr><lf>",	1, 02, 03, 00,FA,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 112000/ISDN/X75/V42BIS/MLP<cr><lf>",	1, 02, 03, 80,B5,01,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT 128000/ISDN/X75/V42BIS/MLP<cr><lf>",	1, 02, 03, 00,F4,01,00, 00,00,00,00
+
+; ISDN independent of transferrate: no compression / errrorcorrection
+
+HKR, Responses, "<cr><lf>CONNECT ISDN/V110<cr><lf>",	1, 02, 02, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT ISDN/V120<cr><lf>",	1, 02, 02, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT ISDN/X75<cr><lf>",	1, 02, 02, 00,00,00,00, 00,00,00,00
+
+; ISDN independent of transferrate: compression / errrorcorrection
+
+HKR, Responses, "<cr><lf>CONNECT ISDN/V120/V42BIS<cr><lf>",		1, 02, 03, 00,00,00,00, 00,00,00,00
+HKR, Responses, "<cr><lf>CONNECT ISDN/X75/V42BIS<cr><lf>",		1, 02, 03, 00,00,00,00, 00,00,00,00
+
+[Strings]
+String0 = "Symbian Ltd"
+
+; --- eof ---
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/device/inf-files/symusb_com.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,87 @@
+; 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 "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:
+; Windows Device Setup File
+;
+; Allows Lubbock to be installed as a COM port, instead of a Modem.
+; Tested with Windows 2000
+;
+; Instructions for use 
+;----------------------
+;
+; - Unplug the USB cable from the Lubbock (switching off USB Manager should work, but best to safe).
+; - From C:\WINNT\INF need to delete the *.inf and *.pnf files corresponding to the Lubbock drivers. 
+; - The *.inf files can be found by searching the INF directory for files containing "lubbock". 
+;   Each *.inf file should have a corresponding *.pnf file. (Note, it may be necessary to change 
+;   the WINNT folder options so hidden files and folders are shown).
+; - Run "regedt32" from Start | Run.
+; - In the HKEY_LOCAL_MACHINE window, navigate to SYSTEM\CurrentControlSet\Enum\USB
+; - Using the Permission menu option, add yourself to the permissions list for the USB folder.
+; - Open the USB folder and delete Vid_0e22&Pid_000b (deletion should be possible from regedt32,
+;   but it may be necessary to use regedit instead).
+; - Now plug in the Lubbock USB cable (and start USB Manager if it is not running).
+; - Windows should detect Lubbock as a completely new device. Point it at this file. 
+; - COM port should install
+;
+
+
+
+[Version] 
+Signature="$Windows NT$" 
+Class=Ports 
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} 
+
+Provider=%SYM% 
+LayoutFile=layout.inf 
+DriverVer=10/15/1999,5.0.2153.1 
+
+[Manufacturer] 
+%SYM%=SYM
+
+[SYM]
+%LUB%=Reader, USB\VID_0E22&PID_000B 
+
+[Reader_Install.NTx86] 
+;Windows2000 
+
+[DestinationDirs] 
+DefaultDestDir=12 
+Reader.NT.Copy=12 
+
+[Reader.NT] 
+CopyFiles=Reader.NT.Copy 
+AddReg=Reader.NT.AddReg 
+
+[Reader.NT.Copy] 
+usbser.sys 
+
+[Reader.NT.AddReg] 
+HKR,,DevLoader,,*ntkern 
+HKR,,NTMPDriver,,usbser.sys 
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" 
+
+[Reader.NT.Services] 
+AddService = usbser, 0x00000002, Service_Inst 
+
+[Service_Inst] 
+DisplayName = %Serial.SvcDesc% 
+ServiceType = 1 ; SERVICE_KERNEL_DRIVER 
+StartType = 3 ; SERVICE_DEMAND_START 
+ErrorControl = 1 ; SERVICE_ERROR_NORMAL 
+ServiceBinary = %12%\usbser.sys 
+LoadOrderGroup = Base 
+
+[Strings] 
+SYM = "Symbian Software Ltd." 
+LUB = "Lubbock USB serial connection" 
+Serial.SvcDesc = "USB Serial emulation driver"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 1999-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:
+* Build information for USB class support
+* USB Comms support
+*
+*/
+
+/**
+ @file
+*/
+
+#include "../logger/group/bld.inf"
+
+#if defined SYMBIAN_ENABLE_USB_OTG_HOST && !defined X86GCC
+#include "../host/bld.inf"
+#endif
+
+#include "../usbman/bld.inf"
+#include "../device/bld.inf"
+
+PRJ_EXPORTS
+usb.iby	/epoc32/rom/include/usb.iby
+Usbman.iby	/epoc32/rom/include/usbman.iby
+Usbmanbin.iby	/epoc32/rom/include/usbmanbin.iby
+Usbmanrsc.iby	/epoc32/rom/include/usbmanrsc.iby
+
+// ConfML Files
+../conf/usbmanager.confml                OS_LAYER_EXPORTS_CONFML(usbmanager.confml)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/group/RELEASE.TXT	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,4 @@
+Usbman E32 Universal Serial Bus Manager
+
+Version 1.0(001)
+================
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/group/Usbman.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 2003-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:
+* Universal Serial Bus Interface Manager
+*
+*/
+
+#ifndef __USBMAN_IBY__
+#define __USBMAN_IBY__
+
+REM *** The following iby files are always included, whether usb is supported
+REM *** by the device or not.
+
+#include <c32.iby>
+#include <ecom.iby>
+
+// Resources are in a separate file, for easier customisation
+#include <usbmanrsc.iby>
+#include <usbmanbin.iby>
+
+#endif // __USBMAN_IBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/group/Usbmanbin.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,170 @@
+
+
+/*
+* Copyright (c) 2003-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:
+* Universal Serial Bus Interface Manager Binaries
+*
+*/
+
+#ifndef __USBMANBIN_IBY__
+#define __USBMANBIN_IBY__
+
+// If __USB_DEBUG__ is defined pull in debug versions of the
+// USB DLLs and Plugins regardless of the ROM type
+#ifdef __USB_DEBUG__
+define USB_DIR UDEB
+#define USB_PLUGIN ECOM_PLUGIN_UDEB
+#else
+define USB_DIR BUILD_DIR
+#define USB_PLUGIN ECOM_PLUGIN
+#endif
+
+// *** Check we have been given a sensible set of buildrom options
+#if defined (__OBEX_OVER_USB__) && (defined (__TEST_USB_ZLP__) || defined (__USBMAN_DUMMYCC__))
+#error Defining both OBEX over USB _and_ Zero Length Packet testing or dummy class controllers does not make sense.
+#endif
+
+// *** USBMAN.DLL is the client side. It is always included in the ROM,
+// *** whether USB is supported by the device or not, so that client
+// *** applications can link against it regardless.
+file=ABI_DIR\USB_DIR\usbman.dll			usbman.dll
+
+// The main backup registration file. Plug-ins should use its own backup registration file in order to back its perfered data.
+data=ZPRIVATE\101fe1db\backup_registration.xml	private\101fe1db\backup_registration.xml
+
+// *** USB logger. This is not dependent on EUSBC as it is used by 
+// *** usbman.dll. It compiles down to next to nothing when __FLOG_ACTIVE is 
+// *** undefined, and we cannot remove it altogether because things link 
+// *** against it.
+file=ABI_DIR\USB_DIR\usblogger.dll		usblogger.dll
+
+#if defined(_DEBUG) || defined (__USB_DEBUG__)
+#include "commsdebugutility.iby"
+#endif
+
+// *** Now for things which should only be included if the device supports
+// *** USB, to save ROM space...
+#if defined(SYMBIAN_EXCLUDE_USB) || !defined(EUSBC)
+REM Feature USB is not included in this ROM (usbman.iby)
+#else
+
+#ifndef __OBEX_OVER_USB__
+  #ifndef __TEST_USB_ZLP__
+    #ifdef __EXAMPLE_OBEX_CC__
+      // *** OBEX Class Controller plugin. 
+      USB_PLUGIN(obexclasscontroller.dll,1027433a.rsc)
+      // *** All the files needed by Obex Class Controller
+      // *** The executable that the class controller links to
+      file=ABI_DIR\BUILD_DIR\classControllerServerSession.exe         sys\bin\classControllerServerSession.exe
+      // *** The dll that the class controller uses as a client 
+      file=ABI_DIR\BUILD_DIR\classControllerClientSession.dll         sys\bin\classControllerClientSession.dll
+    #endif //__EXAMPLE_OBEX_CC__	
+  #endif //__TEST_USB_ZLP__
+#endif //__OBEX_OVER_USB__
+
+// *** 'buildrom -D__USBMAN_DUMMYCC__' will use the dummy Class Controller
+// *** build of USBSVR for testing purposes.
+// *** Note: DummyCC never includes OTG code.
+#ifdef __USBMAN_DUMMYCC__
+#include <dummyccinifiles.iby>
+file=ABI_DIR\USB_DIR\t_usbman_dummycc.exe		usbsvr.exe
+#else
+//
+// Configuration of OTG or Client.
+//
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST)
+
+	#if defined(SYMBIAN_INCLUDE_USB_OTG_HOST)
+		REM Feature USB Host (and related OTG) is included in this ROM (usbman.iby)
+		file=ABI_DIR\USB_DIR\usbsvrotg.exe		usbsvr.exe
+		#include <fdf.iby>
+		REM Host Mass Storage binaries
+		#ifdef WITH_MASS_STORAGE
+			#include <usbhostmsmm.iby>
+			#include <msfdc.iby>
+		#endif
+	#else
+		REM Feature USB Host (and related OTG) is NOT included in this ROM (usbman.iby)
+		file=ABI_DIR\USB_DIR\usbsvr.exe			usbsvr.exe
+	#endif // SYMBIAN_INCLUDE_USB_OTG_HOST
+
+#else
+
+	REM SYMBIAN_ENABLE_USB_OTG_HOST is not defined - so we fall back to building in the 
+	REM non-OTG usbsvr.exe
+	file=ABI_DIR\USB_DIR\usbsvr.exe			usbsvr.exe
+
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST
+
+#endif
+
+file=ABI_DIR\USB_DIR\usbclasscontroller.dll		usbclasscontroller.dll
+file=ABI_DIR\USB_DIR\usbmanextensionplugin.dll		usbmanextensionplugin.dll
+
+// *** Abstract Control Model (serial emulation) Class Controller.
+#ifdef __ACM_REGPORT__
+USB_PLUGIN(t_regport_acmclasscontroller.dll,101fbf20.rsc)
+#else
+USB_PLUGIN(acmclasscontroller.dll,101fbf20.rsc)
+#endif
+
+#ifdef WITH_REFERENCE_USB_CHARGING_PLUGIN
+// *** Reference battery charging plug-in
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST) && defined (SYMBIAN_INCLUDE_USB_OTG_HOST)
+USB_PLUGIN(usbbatterychargingpluginotg.dll,usbbatterychargingpluginotg.rsc)
+#else
+USB_PLUGIN(usbbatterychargingplugin.dll,usbbatterychargingplugin.rsc)
+#endif
+#endif
+
+file=ABI_DIR\USB_DIR\acmserver.dll		acmserver.dll
+
+// *** WHCM Class Controller - used for OBEX over USB.
+USB_PLUGIN(whcmclasscontroller.dll,101fbf23.rsc)
+
+// *** Mass Storage Class Controller.
+USB_PLUGIN(msclasscontroller.dll,10204bbb.rsc)
+data=ZPRIVATE\10204bbb\usbms.rsc	PRIVATE\101fe1db\usbms.rsc
+#ifdef WITH_MASS_STORAGE_EXAMPLE_APP
+file=ABI_DIR\USB_DIR\usbmsexampleapp.exe		usbmsexampleapp.exe
+#endif
+
+// *** OBEX Class Controller. This is test code, used for descriptor checking
+// *** only.
+// USB_PLUGIN(Obexclasscontroller.dll,101fbf27.rsc)
+
+// *** Uncomment the following file and modify if the number or type of ACM 
+// *** Functions required is different from the default
+// data=ZPRIVATE\101fe1db\NumberOfAcmFunctions.ini	private\101fe1db\NumberOfAcmFunctions.ini
+
+#ifdef SYMBIAN_INCLUDE_USB_RNDIS
+// *** RNDIS Class Controller.
+
+#include <ether802.iby>
+
+USB_PLUGIN(rndisclasscontroller.dll, rndisclasscontroller.rsc)
+USB_PLUGIN(rndisproviders.dll, rndisproviders.rsc)
+
+// RNDIS IAP ID Backup registration file
+data=ZPRIVATE\101fe1db\backup_registration_rndis.xml  private\101fe1db\backup_registration_rndis.xml
+
+file=ABI_DIR\USB_DIR\rndispkt.drv        System\Libs\rndispkt.drv
+file=ABI_DIR\USB_DIR\rndismessages.dll	 System\Libs\rndismessages.dll
+file=ABI_DIR\USB_DIR\rndisagt.agt	 System\Libs\rndisagt.agt
+#endif  // SYMBIAN_INCLUDE_USB_RNDIS
+
+#endif // SYMBIAN_EXCLUDE_USB
+
+#endif // __USBMANBIN_IBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/group/Usbmanrsc.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,68 @@
+
+/*
+* Copyright (c) 2003-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:
+* Universal Serial Bus Interface Manager Resources
+*
+*/
+
+#ifndef __USBMANRSC_IBY__
+#define __USBMANRSC_IBY__
+
+
+// *** Only include resource files if device supports USB
+#if defined(SYMBIAN_EXCLUDE_USB) || !defined(EUSBC)
+REM Feature USB is not included in this ROM (usbman.iby)
+#else
+
+DEFINE __USBMAN_RSC_ZPATH__ ZPRIVATE\101fe1db
+DEFINE __USBMAN_RSC_PATH__  PRIVATE\101fe1db
+
+
+#ifdef __TEST_USB_ZLP__
+	// *** use the ZLP-configured resource file (PID and VID for the ACM CC are different)
+	data=__USBMAN_RSC_ZPATH__\usbmanzlp.rsc		__USBMAN_RSC_PATH__\usbman.rsc
+#else //__TEST_USB_ZLP__
+
+	#ifdef __EXAMPLE_OBEX_CC__
+		// *** 'buildrom -D__EXAMPLE_OBEX_CC__' will use example Obex class controller	
+		// *** The RSC file that was created when building the example source
+		data=__USBMAN_RSC_ZPATH__\obexusbman.rsc		__USBMAN_RSC_PATH__\usbman.rsc
+	#else //__EXAMPLE_OBEX_CC__
+		// *** This is the normal resource file..
+		#ifndef USB_EXCLUDE_DEFAULT_PERSONALITIES
+		  	#ifdef SYMBIAN_EXCLUDE_MTP
+		  		#ifdef SYMBIAN_INCLUDE_USB_RNDIS
+		  			// *** Normal resource file including RNDIS support but excluding MTP
+		  			data=__USBMAN_RSC_ZPATH__\usbmanrndis.rsc		__USBMAN_RSC_PATH__\usbman.rsc
+		  		#else
+		  			//	*** Normal resource file excluding MTP and RNDIS support
+		  			data=__USBMAN_RSC_ZPATH__\usbman.rsc		__USBMAN_RSC_PATH__\usbman.rsc
+		  		#endif // SYMBIAN_INCLUDE_USB_RNDIS
+			#else // SYMBIAN_EXCLUDE_MTP
+				#ifdef SYMBIAN_INCLUDE_USB_RNDIS
+					// *** Normal resource file including RNDIS and MTP support
+					data=__USBMAN_RSC_ZPATH__\usbmanmtprndis.rsc		__USBMAN_RSC_PATH__\usbman.rsc
+				#else
+					//	*** Normal resource file including MTP support but excluding RNDIS
+					data=__USBMAN_RSC_ZPATH__\usbmanmtp.rsc		__USBMAN_RSC_PATH__\usbman.rsc
+				#endif // SYMBIAN_INCLUDE_USB_RNDIS
+			#endif // SYMBIAN_EXCLUDE_MTP
+		#endif // USB_EXCLUDE_DEFAULT_PERSONALITIES
+	#endif //__EXAMPLE_OBEX_CC__	
+#endif //__TEST_USB_ZLP__
+
+#endif // SYMBIAN_EXCLUDE_USB
+
+#endif // __USBMANRSC_IBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/group/usb.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 2003-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:
+* Comms Server
+*
+*/
+
+#ifndef __USB_IBY__
+#define __USB_IBY__
+
+REM *** usbman.iby is always included whether USB is supported by the
+REM *** device or not.
+
+REM change to usbmanProto.iby for prototype builds
+#include <usbman.iby> // USB_DIR is defined in usbman.iby
+
+REM *** Now for things which should only be included if the device
+REM *** supports USB, to save ROM space...
+
+#if defined(SYMBIAN_EXCLUDE_USB) || !defined(EUSBC)
+REM Feature USB is not included in this ROM (usb.iby)
+#else
+
+file=ABI_DIR\USB_DIR\ecacm.csy	Ecacm.csy
+
+REM *** 'buildrom -D__TEST_USB_ZLP__' will use the ZLP version of the ini file.
+REM *** Note that this is a test configuration only.
+#ifndef __TEST_USB_ZLP__
+	data=ZSYSTEM\data\ecacm.ini	System\Data\ecacm.ini
+#else //__TEST_USB_ZLP__
+	data=ZSYSTEM\data\ecacm_for_usb_zlp_testing.ini	System\Data\ecacm.ini
+#endif //__TEST_USB_ZLP__
+
+#endif // SYMBIAN_EXCLUDE_USB
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/group/usb_manager.history.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<relnotes name="USB Manager">
+  <purpose>
+    USB class support providing control for USB device e.g. whether the USB CSY, Mass Storage Class or Obex over USB can be activated.
+  </purpose>
+
+	<defect number="PDEF135395" title="Reference USB Charging plug-in improvement" revision="057">
+    Now the reference USB Charging plug-in implements classic state machine design pattern.
+  </defect>
+  
+  <defect number="DEF125883" title="Charging plugin reports incorrect values of PnS properties after HNP " revision="056">
+    Charging plugin reference code updated.
+  </defect>
+
+  <defect number="DEF130692" title="Shortlink USB MS Example Application shares deficiency of Base MS App " revision="055">
+    We now record the filesystem type when dismounting and remount the same type filesystem.
+  </defect>
+
+  <defect number="INC130119" title="MSFDC open interface without load driver" revision="054">
+    We now load USBDI when the number of attached devices goes from 0 to 1 and unload it when the number goes from 1 to 0.
+  </defect>
+
+  <defect number="DEF129123" title="Memory Leak Introduced Into Usbman" revision="053">
+    Remove two instances of memory leak.
+  </defect>
+
+  <preq number="1577" title="USB Host Mass Storage" revision="052"/>
+  
+  <defect number="DEF128204" title="errors in IM tagging in shortlink" revision="051">
+    Correct the IM tagging.
+  </defect>
+
+  <defect number="DEF128203" title="protoype APIs in Shortlink" revision="050">
+    Changed prototype APIs to released.
+  </defect>
+
+  <defect number="DEF127048" title="Incorrrect platform security check in USB Manager " revision="049">
+    Changed it to from ECapabilityNetworkControl to ECapabilityCommDD.
+  </defect>
+
+  <defect number="DEF125713" title="Improve fix for DEF124986" revision="048">
+    Changed the CFdfServer::NewLC to return void as the pointer returned is never used, this fixes the coverity problem.
+  </defect>
+
+  <defect number="PDEF125932" title="AppCert- USB - Phone freezes after running Chapter9 tests in PCSuite USB persona" revision="047">
+    Remove Bus Stall Notifier from ECACM.
+  </defect>
+
+  <defect number="DEF124986" title="[Coverity]UNUSED_VALUE failure in RunFdfL" revision="046">
+    Improved construction of the usb Fdf Server.
+  </defect>
+
+  <defect number="DEF124985" title="[Coverity]CHECKED_RETURN failure in USB CIniFile" revision="045">
+    Improve error handling in usb ini file reader.
+  </defect>
+
+  <defect number="DEF121787" title="Changes required to match fix made in Base USB Peripheral driver" revision="044">
+    Add indication that no control transfers are expected on the WHCM and one of the ACM interfaces.
+  </defect>
+  
+  <defect number="PDEF122289" title="T_ACM DataStress_SizeVary_TestL hangs forever when writing" revision="043">
+    Creating a temporary buffer so IPCRead reads the right amount..
+  </defect>    
+  
+  <defect number="DEF119243" title="Checksource problems in usbman" revision="042">
+    fixed checksource problems.
+  </defect> 
+
+  <defect number="DEF118932" title="USB charging plugin fails to negotiate with Odd CurrentValue" revision="041">
+    Mask the value read from the repository with 0xFFFE to make sure it is an even value.
+  </defect> 
+
+  <defect number="PDEF119427" title="ACM does not report terminal disconnection" revision="040">
+    The data members iHostChangeSlc and iHostChangeCls are removed from CdcAcmClass.
+  </defect> 
+
+  <defect number="PDEF119090" title="CDC interface names are not configurable" revision="039">
+    Added the ability to read interface names from the existing NumberOfAcmFunctions.ini file, defaulting the names if they are absent
+    from the file or the file itself is absent.
+  </defect> 
+  
+  <defect number="PDEF118256" title="USB Logger Cannot Display 16 Bit Descriptors" revision="038">
+    Changed macros arguments forcing USB Logger to use 16 Bit Descriptors (it can display them)
+  </defect> 
+  
+  <preq number="1782" title="USB Host and on-the-go for pre-installed drivers" revision="037"/>
+  
+  <defect number="INC114331" title="USB Manager iby file split" revision="036">
+    Split usbman.iby into usbmanrsc.iby and usbmanbin.iby, with the original usbman.iby file including both.
+  </defect> 
+
+  <defect number="INC115129" title="Phone freeze when remove USB cable right after the connected note" revision="035">
+    Recoded CActiveDataAvailableNotifier::RunL to avoid an infinite loop when the LDD errors the request.
+  </defect> 
+
+  <defect number="DEF107610" title="USB Subsystem: 9.5/Future UsbSvr Capability tests failing" revision="034">
+    Fixed USB Charging Plugin so that it doesn't leave on startup when the properties it uses have been already defined.
+  </defect> 
+
+  <defect number="INC114558" title="Usbman crashes under IPC attack" revision="033">
+   Stopped USBSVR panicking when under IPC attack.
+  </defect> 
+
+  <defect number="PDEF114508" title="Klocwork issues in ser-comms_usb" revision="032">
+   wLength field is populated in CdcControlInterface.cpp. Propagated from INC114069
+  </defect> 
+
+  <defect number="PDEF112491" title="USB Subsystem: Address code-review comments on INC105375 fix" revision="031">
+   a deletion of commented out code
+  </defect> 
+   
+  <defect number="PDEF110695" title="USB Subsystem 9.5: propagation of pdef107569" revision="030">
+   Propagation of pdef107569 for new usb directory structure, see pdef107569 for all the defect details. Also include fix for DEF109361
+  </defect>  
+  
+  <defect number="PDEF112318" title="USB Subsystem: ACM classes have incorrect CDC version number" revision="029">
+   changing CDC version number
+  </defect>  
+    
+  <defect number="DEF110192" title="USB Sub: Prop of: Publish and subscribe access is missing from ACM configuration " revision="028">
+   - Added AcmConfig.h to allow inclusion of a set of constants for accessing various fields in the publish and subscribe data, and to allow access to the publish and subscribe key.
+   - Updated the publish and subscribe data whenever a function is created or destroyed. And data is created and deleted during construction and deletion appropriately.
+  </defect>  
+  
+  <defect number="DEF109279" title="USB Subsyste Propagation of: Higher ACM bandwidth priority needed for USB dialup" revision="027">
+   The following bandwidth priority is needed :EUsbcBandwidthOUTPlus2 | EUsbcBandwidthINPlus2
+   The bigger buffer size helps the USB side to recover from high speed downloads by writing bigger bursts to PDD.
+   By setting it to maximum it also allows configurability for products to dynamically adjust the amount of bursting
+  </defect>
+    
+  <defect number="DEF105916" title="USB subsystem: 9.5 New USB branch: clarify how NumberOfAcmFunctions.ini works" revision="026">
+   clarification on how the NumberOfAcmFunctions works
+  </defect>
+    
+  <defect number="DEF106781" title="USB Subsystem- 9.5 USB reorg - requires DEF106011 changes in new subsystem" revision="025"> 
+   corrected the IM tag placement and tagged it as publishedPartner 
+  </defect>
+  
+  <defect number="DEF107255" title="USB Subsystem 9.5: USB MTP driver PID clashes with Base app" revision="024">  
+   Future personalities should only use PIDs >= 0x1113 thus MTP should use a PID of 0x1114 or greater because 0x1113 is already used
+  </defect>
+    
+  <defect number="DEF108236" title="USB Subsystem 9.5: Ser_comms test T_ACM Random number generation broken" revision="023"> 
+   The random generator was made of an integer division so the result was always 0.
+   Now it is made up by using the modulo of the integer division of the random number with 1001 to get a range within the following boundaries: [0-1000]
+  </defect>  
+    
+  <defect number="DEF108237" title="USB Subsystem: Ser_comms test T_USB test suite not found" revision="022"> 
+   - Changed the script files for the correct test suite name - i.e. changed "usb" to "t_usb"and renaming the dll to t_usb.dll
+   - Changed the config files for the correct configuration values    
+  </defect>  
+    
+  <defect number="DEF109361" title="USB Sub: Prop of:ACM server incorrectly allows arbitrary ACM function crea/destr" revision="021"> 
+   - Downgraded capabilites of acmserver.dll to prevent it being loaded by inappropriate programs.
+   - Added an policy check to ecacm.scy to ensure the connections received originate from usbsvr.  
+  </defect> 
+    
+  <defect number="DEF110133" title="USB Subsystem: Propagation of Update usb ms example app" revision="020"> 
+   Added descriptions of device states and driver states into display and debug output to aid usability   
+  </defect>  
+    
+  <defect number="DEF110475" title="USB Subsystem: Logical error in USB logger leaveiferror" revision="019"> 
+   Corrected the logical comparison of the error passed  
+  </defect>
+    
+  <defect number="DEF110472" title="USB SubsysteM: Prop'n of RComm::Write() with bigger than default receive buffer." revision="018"> 
+    - Removed some check from CAcmWriter::Write to ensure buffer was big enough for request
+    - Updated CAcmWriter::ReadDataFromClient to read as much as was possible and update an internal counter to indicate how much data remains to be read
+    - Updated CAcmWriter::IssueWrite to write only as much data as was read.
+    - Updated CAcmWriter::WriteCompleted to reissue ReadDataFromClient and IssueWrite calls as long as the is data remaining to be read.
+    - modification of LARGE_WRITE_ENABLE macro to include 9.5 and above  
+  </defect>
+
+  <defect number="DEF110342" title="[System Build]:GT, ROM and CBR errors and warnings related to usb_manager in M04309v9.4" revision="017">
+    CBR .mrp file changed to include the inifile source directory
+  </defect>
+
+  <defect number="INC108692" title="USB OTG: Error note '!USBman KERN-EXEC 0' is displayed in Idle state after start" revision="016">
+    Only call SetInitialConfigurationL if we're NOT running on the emulator and we're not running test code
+  </defect>
+
+  <defect number="DEF104722" title="USB OTG New USB branch: documentation renaming needed" revision="015">
+    Remove mention of ser-comms in USB documentation
+  </defect>
+
+  <defect number="DEF104720" title="USB OTG New USB branch: usblogger improvements" revision="014">
+    - Add logging to Leaves
+    - Add logging to RMessage panics
+    - Adjust LeaveIfError to only leave if there is an error (ie. -ve).
+    - Tweak non-logging builds to ensure safe behaviour in the case of a binary muddle
+  </defect>
+
+  <defect number="DEF104719" title="USB OTG New USB branch: acm CC mmp files has unused LIBRARY directive" revision="013">
+    Make the ACM build vairants depend only on the libraries they actually require
+  </defect>
+
+  <defect number="DEF104717" title="USB OTG New USB branch: remove template class controller" revision="012">
+    Remove the template class controller
+  </defect>
+
+  <defect number="DEF104715" title="USB OTG New USB branch: multiple inifile implementations not needed" revision="011">
+    Standardise on a single inifile reader implementation
+  </defect>
+
+  <defect number="DEF107691" title="USB OTG: USB binaries have been assigned unnecessary capabilities" revision="010">
+    Remove the unnecessary capabilities WriteDeviceData and ReadDeviceData
+  </defect>
+
+  <preq number="1576" title="State change plug-in interface to USB Manager (for charging)" revision="009"/>
+
+  <defect number="DEF101319" title="Filename case check failures in source build and test" revision="008">
+    Corrected filenames to enable building of Symbian OS in Linux
+  </defect>
+
+  <defect number="PDEF103765" title="CUsbDevice::ResourceFileNameL uses hard-coded drive letter" revision="007">
+    Changing so the location of resource files stored on the system drive, is determined on runtime, rather than to be hardcoded as c:
+  </defect>
+
+  <defect number="DEF103560" title="Usbman changes required for MTP" revision="006">
+    - Added new .rss file (usbmanmtp.rss) which contains additional personality definition for the MTP personality
+    - Extended usbsvrbase.mmp to build the new .rss file as usbmanmtp.rsc
+    - Added more definitions to the usbman*.rls localisation files to cover the new MTP personality
+    - Amended usbman.iby to choose the usbman.rsc file in the final ROM depending on the presence or absence of the SYMBIAN_EXCLUDE_MTP macro at ROM build time.
+  </defect>
+
+  <defect number="PDEF101314" title="NotifyDataAvailable() is not supported by CAcmPort" revision="005">
+    Implementing NotifyDataAvailable() in CAcmPort
+  </defect>
+
+  <defect number="PDEF095763" title="ECACM returns KErrNoMemory when a Read with a large buffer is posted" revision="004">
+    ECACM (CSY) now allows larger read than its internal buffer
+  </defect>
+
+  <defect number="DEF098774" title="USBServer session count can trigger an assert (instead of counter going to -1)" revision="003">
+    2nd phase construction reorganised and altered to prevent potential USB server panics.
+  </defect>
+
+  <defect number="DEF099478" title="Cannot output USB debug traces over UART" revision="002">
+    Enabling USB debug traces over UART
+  </defect>
+
+  <defect number="PDEF100579" title="Symbian USB Manager WHCM class controller does not allow composite device creati" revision="001">
+    USB Manager WHCM class controller now allows composite device creation.
+  </defect>
+</relnotes>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/group/usb_manager.mrp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,46 @@
+# Copyright (c) 2003-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:
+# 
+#
+#
+
+component	usb_manager
+
+source	\sf\os\usb\usbmgmt\usbmgr\device
+source	\sf\os\usb\usbmgmt\usbmgr\group
+source	\sf\os\usb\usbmgmt\usbmgr\logger
+source	\sf\os\usb\usbmgmt\usbmgr\test
+source	\sf\os\usb\usbmgmt\usbmgr\inifile
+source	\sf\os\usb\usbmgmt\usbmgr\host
+source	\sf\os\usb\usbmgmt\usbmgr\usbman
+source	\sf\os\usb\usbmgmt\usbmgr\conf
+
+binary	\sf\os\usb\usbmgmt\usbmgr\group	all
+
+exports	\sf\os\usb\usbmgmt\usbmgr\group
+
+notes_source	\component_defs\release.src
+
+
+
+ipr E 
+ipr T \sf\os\usb\usbmgmt\usbmgr\test
+ipr T \sf\os\usb\usbmgmt\usbmgr\usbman\chargingplugin
+ipr T \sf\os\usb\usbmgmt\usbmgr\device\classdrivers\obex
+ipr T \sf\os\usb\usbmgmt\usbmgr\host\fdf\test
+ipr T \sf\os\usb\usbmgmt\usbmgr\host\fdf\reference
+ipr T \sf\os\usb\usbmgmt\usbmgr\host\functiondrivers\ms\msmm\referencepolicyplugin
+ipr T \sf\os\usb\usbmgmt\usbmgr\host\functiondrivers\ms\msmm\refppnotifier
+ipr T \sf\os\usb\usbmgmt\usbmgr\host\functiondrivers\ms\msmm\test
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,21 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+
+
+#include "fdf/production/bld.inf"
+#include "functiondrivers/ms/bld.inf"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "fdcbase/group/bld.inf"
+#include "server/group/bld.inf"
+#include "client/group/bld.inf"
+
+PRJ_EXPORTS
+fdf.iby				/epoc32/rom/include/fdf.iby
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/client/BWINS/usbhoststacku.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,17 @@
+EXPORTS
+	??0RUsbHostStack@@QAE@XZ @ 1 NONAME ; RUsbHostStack::RUsbHostStack(void)
+	?Connect@RUsbHostStack@@QAEHXZ @ 2 NONAME ; int RUsbHostStack::Connect(void)
+	?DisableDriverLoading@RUsbHostStack@@QAEXXZ @ 3 NONAME ; void RUsbHostStack::DisableDriverLoading(void)
+	?EnableDriverLoading@RUsbHostStack@@QAEHXZ @ 4 NONAME ; int RUsbHostStack::EnableDriverLoading(void)
+	?GetManufacturerStringDescriptor@RUsbHostStack@@QAEHIIAAV?$TBuf@$0IA@@@@Z @ 5 NONAME ; int RUsbHostStack::GetManufacturerStringDescriptor(unsigned int, unsigned int, class TBuf<128> &)
+	?GetProductStringDescriptor@RUsbHostStack@@QAEHIIAAV?$TBuf@$0IA@@@@Z @ 6 NONAME ; int RUsbHostStack::GetProductStringDescriptor(unsigned int, unsigned int, class TBuf<128> &)
+	?GetSupportedLanguages@RUsbHostStack@@QAEHIAAV?$RArray@I@@@Z @ 7 NONAME ; int RUsbHostStack::GetSupportedLanguages(unsigned int, class RArray<unsigned int> &)
+	?NotifyDeviceEvent@RUsbHostStack@@QAEXAAVTRequestStatus@@AAVTDeviceEventInformation@@@Z @ 8 NONAME ; void RUsbHostStack::NotifyDeviceEvent(class TRequestStatus &, class TDeviceEventInformation &)
+	?NotifyDeviceEventCancel@RUsbHostStack@@QAEXXZ @ 9 NONAME ; void RUsbHostStack::NotifyDeviceEventCancel(void)
+	?NotifyDevmonEvent@RUsbHostStack@@QAEXAAVTRequestStatus@@AAH@Z @ 10 NONAME ; void RUsbHostStack::NotifyDevmonEvent(class TRequestStatus &, int &)
+	?NotifyDevmonEventCancel@RUsbHostStack@@QAEXXZ @ 11 NONAME ; void RUsbHostStack::NotifyDevmonEventCancel(void)
+	?Version@RUsbHostStack@@QBE?AVTVersion@@XZ @ 12 NONAME ; class TVersion RUsbHostStack::Version(void) const
+	?__DbgAlloc@RUsbHostStack@@QAEHXZ @ 13 NONAME ; int RUsbHostStack::__DbgAlloc(void)
+	?__DbgFailNext@RUsbHostStack@@QAEHH@Z @ 14 NONAME ; int RUsbHostStack::__DbgFailNext(int)
+	?GetOtgDescriptor@RUsbHostStack@@QAEHIAAVTOtgDescriptor@@@Z @ 15 NONAME ; int RUsbHostStack::GetOtgDescriptor(unsigned int, class TOtgDescriptor &)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/client/EABI/usbhoststacku.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,18 @@
+EXPORTS
+	_ZN13RUsbHostStack10__DbgAllocEv @ 1 NONAME
+	_ZN13RUsbHostStack13__DbgFailNextEi @ 2 NONAME
+	_ZN13RUsbHostStack17NotifyDeviceEventER14TRequestStatusR23TDeviceEventInformation @ 3 NONAME
+	_ZN13RUsbHostStack17NotifyDevmonEventER14TRequestStatusRi @ 4 NONAME
+	_ZN13RUsbHostStack19EnableDriverLoadingEv @ 5 NONAME
+	_ZN13RUsbHostStack20DisableDriverLoadingEv @ 6 NONAME
+	_ZN13RUsbHostStack21GetSupportedLanguagesEjR6RArrayIjE @ 7 NONAME
+	_ZN13RUsbHostStack23NotifyDeviceEventCancelEv @ 8 NONAME
+	_ZN13RUsbHostStack23NotifyDevmonEventCancelEv @ 9 NONAME
+	_ZN13RUsbHostStack26GetProductStringDescriptorEjjR4TBufILi128EE @ 10 NONAME
+	_ZN13RUsbHostStack31GetManufacturerStringDescriptorEjjR4TBufILi128EE @ 11 NONAME
+	_ZN13RUsbHostStack7ConnectEv @ 12 NONAME
+	_ZN13RUsbHostStackC1Ev @ 13 NONAME
+	_ZN13RUsbHostStackC2Ev @ 14 NONAME
+	_ZNK13RUsbHostStack7VersionEv @ 15 NONAME
+	_ZN13RUsbHostStack16GetOtgDescriptorEjR14TOtgDescriptor @ 16 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/client/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#if !defined(WINS)
+
+PRJ_PLATFORMS
+ARMV5
+
+PRJ_MMPFILES
+usbhoststack.mmp // production version
+
+PRJ_EXPORTS
+../public/usbhosterrors.h		SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usbhosterrors.h)
+
+PRJ_TESTEXPORTS
+../public/usbhoststack.h		SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usbhost/internal/usbhoststack.h)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/client/group/usbhoststack.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2007-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:
+* DLL containing API presented by FDF to USBMAN.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "usbhoststack_base.mmp"
+
+// These are the caps of the only process (USBSVR) we ever validly run in.
+// Because component test asks an extra capability TrustedUI, so moved these 
+// capabilities out from usbhoststack_base.mmp to here.
+CAPABILITY		CommDD NetworkControl NetworkServices LocalServices ProtServ
+
+TARGET			usbhoststack.dll
+// UID2 = 0x1000008d for static interface DLLs.
+// UID3 = unique for FDF system
+UID 			0x1000008d 0x10282B48
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/client/group/usbhoststack_base.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2007-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:
+* Does not itself build an exe, but is used by other MMP files.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+TARGETTYPE		dll
+VENDORID		0x70000001
+
+SOURCEPATH		../src
+SOURCE			session.cpp
+
+USERINCLUDE		../../server/public
+USERINCLUDE		../public
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+DEFFILE			usbhoststack.def
+
+LIBRARY 		euser.lib
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/client/group/usbhoststack_over_dummyusbdi.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2007-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:
+* Special build of the API presented by FDF to USBMAN. This one uses 
+* a variant of the FDF which runs over the DummyUSBDI for test purposes.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "usbhoststack_base.mmp"
+
+// One more capability appended: TrustedUI for component test
+CAPABILITY		CommDD NetworkControl NetworkServices LocalServices ProtServ TrustedUI
+
+TARGET			usbhoststack_over_dummyusbdi.dll
+// UID2 = 0x1000008d for static interface DLLs.
+// UID3 = unique for FDF system
+UID 			0x1000008d 0x10282B50
+
+MACRO	__OVER_DUMMYUSBDI__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/client/group/usbhoststack_over_dummyusbdi_bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,24 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+PRJ_TESTMMPFILES
+usbhoststack_over_dummyusbdi.mmp // unit test version
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/client/public/usbhosterrors.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2007-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
+ @prototype
+*/
+
+#ifndef USBHOSTERROR_H
+#define USBHOSTERROR_H
+
+
+/** The device is unsupported- the FDF will not attempt to load drivers for
+it. */
+const TInt KErrUsbUnsupportedDevice				= -6620;
+
+/** Driver loading has not been enabled. */
+const TInt KErrUsbDriverLoadingDisabled			= -6621;
+
+/** The configuration descriptor's NumInterfaces is 0. */
+const TInt KErrUsbConfigurationHasNoInterfaces	= -6622;
+
+/** The configuration descriptor's NumInterfaces does not equal the actual
+number of (alternate 0) interface descriptors in the configuration bundle. */
+const TInt KErrUsbInterfaceCountMismatch			= -6623;
+
+/** A Function Driver was not found for at least one interface in the device's
+selected configuration. */
+const TInt KErrUsbFunctionDriverNotFound			= -6624;
+
+/** Two of the interfaces in the configuration bundle have the same interface
+numbers. */
+const TInt KErrUsbDuplicateInterfaceNumbers		= -6625;
+
+/** A Function Driver has found a problem with the device's descriptors. Such
+problems include (non-exhaustively) formatting or layout of Class-specific
+descriptors and alternate interface numbering. */
+const TInt KErrUsbBadDescriptor					= -6626;
+
+/** While FDF was busy trying to load FDs the current attached device has been
+detached by USBDI (physically unplugged or was draining too much current) */
+const TInt KErrUsbDeviceDetachedDuringDriverLoading			= -6627;
+
+/** During an attachment failure, FDF receives an error from USBDI
+If the error is not a known expected error then FDF will report it
+with the following error code -6628, as a KErrUsbAttachmentFailureGeneralError
+*/
+const TInt KErrUsbAttachmentFailureGeneralError			= -6628;
+
+/** If a Function Driver or Function Driver upgrade is installed or uninstalled then the FDF 
+receives notification of this from ECom and will update its list of Function Driver Proxies 
+accordingly. This may involve an allocation which therefore may fail however there is no point
+in the FDF propegating this failure (via a leave) back up the call stack as the originator is ECom.
+In the event that the FDF does encounter OOM then its list of proxy function drivers will be out of
+date, this error code indicates such a situation.
+*/
+const TInt KErrUsbUnableToUpdateFDProxyList				= -6629;
+
+#endif // USBHOSTERROR_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/client/public/usbhoststack.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,92 @@
+/*
+* Copyright (c) 2007-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
+ @prototype
+*/
+
+#ifndef USBHOSTSTACK_H
+#define USBHOSTSTACK_H
+
+#include <e32base.h>
+
+#include <usb/usbshared.h>
+#include <usbhosterrors.h>
+
+/**
+RUsbHostStack is the interface for USBMAN to use the FDF.
+*/
+NONSHARABLE_CLASS(RUsbHostStack) : public RSessionBase
+	{
+public:
+	IMPORT_C RUsbHostStack();
+	// No destructor needed.
+
+	IMPORT_C TInt Connect();
+	IMPORT_C TVersion Version() const;
+
+	/** Enable driver loading.
+	@return Error. */
+	IMPORT_C TInt EnableDriverLoading();
+
+	/** Disable driver loading. */
+	IMPORT_C void DisableDriverLoading(); // the client can't do anything with failure here.
+
+	/** Notification of device attach, driver loading, detach.
+	@param aStat Completion status.
+	@param aDeviceEventInformation On successful completion, information on
+	the device event.
+	*/
+	IMPORT_C void NotifyDeviceEvent(TRequestStatus& aStat, TDeviceEventInformation& aDeviceEventInformation);
+	IMPORT_C void NotifyDeviceEventCancel();
+
+	// Notification of non-device specific events and errors.
+	IMPORT_C void NotifyDevmonEvent(TRequestStatus& aStat, TInt& aEvent);
+	IMPORT_C void NotifyDevmonEventCancel();
+
+	// Support for getting string descriptors from devices.
+	// Note that the maximum length of a string descriptor is 253 bytes. This
+	// is 253/2 =~ 126 Unicode characters. TName is 0x80 (= 128) Unicode
+	// characters. So TName is just big enough without being excessive, or
+	// worth defining our own type or length.
+	IMPORT_C TInt GetSupportedLanguages(TUint aDeviceId, RArray<TUint>& aLangIds);
+	IMPORT_C TInt GetManufacturerStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString);
+	IMPORT_C TInt GetProductStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString);
+	
+	IMPORT_C TInt GetOtgDescriptor(TUint aDeviceId, TOtgDescriptor& aDescriptor);
+
+	// Support for server-side out-of-memory testing. In release, these just
+	// return KErrNone.
+
+	IMPORT_C TInt __DbgFailNext(TInt aCount);
+	IMPORT_C TInt __DbgAlloc();
+
+private: // utility
+	TInt DoConnect();
+	TInt CopyLangIdsToArray(RArray<TUint>& aLangIds, const TDesC8& aBuffer);
+
+private: // owned
+	// Device event notification data
+	TPckg<TDeviceEventInformation> iDeviceEventPckg;
+
+	// Devmon event notification data
+	TPckg<TInt> iDevmonEventPckg;
+	};
+
+#endif // USBHOSTSTACK_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/client/src/session.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,366 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include <e32base.h>
+#include <usb/usblogger.h>
+#include "usbhoststack.h"
+#include "fdfapi.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "usbhstcli");
+#endif
+
+/**
+Starts the server process.
+*/
+static TInt StartServer()
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	const TUidType serverUid(KNullUid, KNullUid, KUsbFdfUid);
+
+	//
+	// EPOC and EKA2 is easy, we just create a new server process. Simultaneous
+	// launching of two such processes should be detected when the second one
+	// attempts to create the server object, failing with KErrAlreadyExists.
+	//
+	RProcess server;
+	TInt err = server.Create(KUsbFdfImg, KNullDesC, serverUid);
+	LOGTEXT2(_L8("\terr = %d"), err);
+
+	if ( err != KErrNone )
+		{
+		return err;
+		}
+
+	TRequestStatus stat;
+	server.Rendezvous(stat);
+
+	if ( stat != KRequestPending )
+		{
+		LOGTEXT(_L8("\taborting startup"));
+		server.Kill(0); 	// abort startup
+		}
+	else
+		{
+		LOGTEXT(_L8("\tresuming"));
+		server.Resume();	// logon OK - start the server
+		}
+
+	User::WaitForRequest(stat); 	// wait for start or death
+
+	// we can't use the 'exit reason' if the server panicked as this
+	// is the panic 'reason' and may be '0' which cannot be distinguished
+	// from KErrNone
+	LOGTEXT2(_L8("\tstat.Int = %d"), stat.Int());
+	err = (server.ExitType() == EExitPanic) ? KErrServerTerminated : stat.Int();
+
+	server.Close();
+
+	LOGTEXT2(_L8("\terr = %d"), err);
+	return err;
+	}
+
+EXPORT_C RUsbHostStack::RUsbHostStack()
+	// these are all arbitrary initialisations
+ :	iDeviceEventPckg(TDeviceEventInformation()),
+	iDevmonEventPckg(0)
+	{
+	LOGTEXT(_L8("*** Search on '***USB HOST STACK' to find device events."));
+
+	LOG_LINE
+	LOG_FUNC
+	}
+
+EXPORT_C TVersion RUsbHostStack::Version() const
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return(TVersion(	KUsbFdfSrvMajorVersionNumber,
+						KUsbFdfSrvMinorVersionNumber,
+						KUsbFdfSrvBuildNumber
+					)
+			);
+	}
+
+EXPORT_C TInt RUsbHostStack::Connect()
+	{
+	LOG_LINE
+	LOG_FUNC;
+
+	TInt err = DoConnect();
+
+	LOGTEXT2(_L8("\terr = %d"), err);
+	return err;
+	}
+
+/**
+Connects the session, starting the server if necessary
+@return Error.
+*/
+TInt RUsbHostStack::DoConnect()
+	{
+	LOG_FUNC
+
+	TInt retry = 2;
+
+	FOREVER
+		{
+		// Use message slots from the global pool.
+		TInt err = CreateSession(KUsbFdfServerName, Version(), -1);
+		LOGTEXT2(_L8("\terr = %d"), err);
+
+		if ((err != KErrNotFound) && (err != KErrServerTerminated))
+			{
+			LOGTEXT(_L8("\treturning after CreateSession"));
+			return err;
+			}
+
+		if (--retry == 0)
+			{
+			LOGTEXT(_L8("\treturning after running out of retries"));
+			return err;
+			}
+
+		err = StartServer();
+		LOGTEXT2(_L8("\terr = %d"), err);
+
+		if ((err != KErrNone) && (err != KErrAlreadyExists))
+			{
+			LOGTEXT(_L8("\treturning after StartServer"));
+			return err;
+			}
+		}
+	}
+
+EXPORT_C TInt RUsbHostStack::EnableDriverLoading()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt ret = SendReceive(EUsbFdfSrvEnableDriverLoading);
+	LOGTEXT2(_L8("\tret = %d"), ret);
+	return ret;
+	}
+
+EXPORT_C void RUsbHostStack::DisableDriverLoading()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt ret = SendReceive(EUsbFdfSrvDisableDriverLoading);
+	LOGTEXT2(_L8("\tret = %d"), ret);
+	(void)ret;
+	}
+
+EXPORT_C void RUsbHostStack::NotifyDeviceEvent(TRequestStatus& aStat, TDeviceEventInformation& aDeviceEventInformation)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TIpcArgs args;
+	iDeviceEventPckg.Set((TUint8*)&aDeviceEventInformation, sizeof(TDeviceEventInformation), sizeof(TDeviceEventInformation));
+	args.Set(0, &iDeviceEventPckg);
+
+	SendReceive(EUsbFdfSrvNotifyDeviceEvent, args, aStat);
+	}
+
+EXPORT_C void RUsbHostStack::NotifyDeviceEventCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt ret = SendReceive(EUsbFdfSrvNotifyDeviceEventCancel);
+	LOGTEXT2(_L8("\tret = %d"), ret);
+	(void)ret;
+	}
+
+EXPORT_C void RUsbHostStack::NotifyDevmonEvent(TRequestStatus& aStat, TInt& aEvent)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TIpcArgs args;
+	iDevmonEventPckg.Set((TUint8*)&aEvent, sizeof(TInt), sizeof(TInt));
+	args.Set(0, &iDevmonEventPckg);
+
+	SendReceive(EUsbFdfSrvNotifyDevmonEvent, args, aStat);
+	}
+
+EXPORT_C void RUsbHostStack::NotifyDevmonEventCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt ret = SendReceive(EUsbFdfSrvNotifyDevmonEventCancel);
+	LOGTEXT2(_L8("\tret = %d"), ret);
+	(void)ret;
+	}
+
+EXPORT_C TInt RUsbHostStack::GetSupportedLanguages(TUint aDeviceId, RArray<TUint>& aLangIds)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	aLangIds.Reset();
+
+	TUint singleLangIdOrNumLangs = 0;
+	TPckg<TUint> singleLangIdOrNumLangsBuf(singleLangIdOrNumLangs);
+	TInt ret = SendReceive(EUsbFdfSrvGetSingleSupportedLanguageOrNumberOfSupportedLanguages, TIpcArgs(aDeviceId, &singleLangIdOrNumLangsBuf));
+	LOGTEXT2(_L8("\tsingleLangIdOrNumLangs = %d"), singleLangIdOrNumLangs);
+	switch ( ret )
+		{
+	case KErrNotFound:
+		LOGTEXT2(_L8("\tThere is no language available or the wrong device id %d was supplied"),aDeviceId);
+		ret = KErrNotFound;
+		break;
+
+	case KErrNone:
+		// The buffer is now either empty or contains the single supported language ID
+		ret = CopyLangIdsToArray(aLangIds, singleLangIdOrNumLangsBuf);
+		break;
+
+	case KErrTooBig:
+		{
+		// The buffer now contains the number of supported languages (not 0 or 1).
+		// Lang IDs are TUints.
+		RBuf8 buf;
+		ret = buf.Create(singleLangIdOrNumLangs * sizeof(TUint));
+		if ( ret == KErrNone )
+			{
+			ret = SendReceive(EUsbFdfSrvGetSupportedLanguages, TIpcArgs(aDeviceId, &buf));
+			if ( ret == KErrNone )
+				{
+				ret = CopyLangIdsToArray(aLangIds, buf);
+				}
+			buf.Close();
+			}
+		}
+		break;
+
+	default:
+		// Regular failure.
+		break;
+		}
+
+	LOGTEXT2(_L8("\tret = %d"), ret);
+	return ret;
+	}
+
+TInt RUsbHostStack::CopyLangIdsToArray(RArray<TUint>& aLangIds, const TDesC8& aBuffer)
+	{
+	LOG_FUNC
+
+	ASSERT(!(aBuffer.Size() % 4));
+	const TUint numLangs = aBuffer.Size() / 4;
+	LOGTEXT2(_L8("\tnumLangs = %d"), numLangs);
+
+	TInt ret = KErrNone;
+	const TUint* ptr = reinterpret_cast<const TUint*>(aBuffer.Ptr());
+	for ( TUint ii = 0 ; ii < numLangs ; ++ii )
+		{
+		ret = aLangIds.Append(*ptr++); // increments by sizeof(TUint)
+		if ( ret )
+			{
+			aLangIds.Reset();
+			break;
+			}
+		}
+
+	LOGTEXT2(_L8("\tret = %d"), ret);
+	return ret;
+	}
+
+EXPORT_C TInt RUsbHostStack::GetManufacturerStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt ret = SendReceive(EUsbFdfSrvGetManufacturerStringDescriptor, TIpcArgs(aDeviceId, aLangId, &aString));
+#ifdef __FLOG_ACTIVE
+	if ( !ret )
+		{
+		LOGTEXT2(_L("\taString = \"%S\""), &aString);
+		}
+#endif
+	LOGTEXT2(_L8("\tret = %d"), ret);
+	return ret;
+	}
+
+EXPORT_C TInt RUsbHostStack::GetProductStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt ret = SendReceive(EUsbFdfSrvGetProductStringDescriptor, TIpcArgs(aDeviceId, aLangId, &aString));
+#ifdef __FLOG_ACTIVE
+	if ( !ret )
+		{
+		LOGTEXT2(_L("\taString = \"%S\""), &aString);
+		}
+#endif
+	LOGTEXT2(_L8("\tret = %d"), ret);
+	return ret;
+	}
+
+EXPORT_C TInt RUsbHostStack::GetOtgDescriptor(TUint aDeviceId, TOtgDescriptor& aDescriptor)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TPckg<TOtgDescriptor> otgDescriptorPckg(aDescriptor);
+	
+	TIpcArgs args;
+	args.Set(0, aDeviceId);
+	args.Set(1, &otgDescriptorPckg);
+
+	TInt ret = SendReceive(EUsbFdfSrvGetOtgDescriptor, args);
+#ifdef __FLOG_ACTIVE
+	if ( !ret )
+		{
+		LOGTEXT2(_L("\taDescriptor.iDeviceId = %d"), aDescriptor.iDeviceId);
+		LOGTEXT2(_L("\taDescriptor.iAttributes = %d"), aDescriptor.iAttributes);
+		}
+#endif
+	LOGTEXT2(_L8("\tret = %d"), ret);
+	return ret;
+	}
+
+EXPORT_C TInt RUsbHostStack::__DbgFailNext(TInt aCount)
+	{
+#ifdef _DEBUG
+	return SendReceive(EUsbFdfSrvDbgFailNext, TIpcArgs(aCount));
+#else
+	(void)aCount;
+	return KErrNone;
+#endif
+	}
+
+EXPORT_C TInt RUsbHostStack::__DbgAlloc()
+	{
+#ifdef _DEBUG
+	return SendReceive(EUsbFdfSrvDbgAlloc);
+#else
+	return KErrNone;
+#endif
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdcbase/BWINS/fdcbaseu.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,12 @@
+EXPORTS
+	??0CFdcPlugin@@IAE@AAVMFdcPluginObserver@@@Z @ 1 NONAME ; CFdcPlugin::CFdcPlugin(class MFdcPluginObserver &)
+	??1CFdcPlugin@@MAE@XZ @ 2 NONAME ; CFdcPlugin::~CFdcPlugin(void)
+	?Extension_@CFdcPlugin@@MAEHIAAPAXPAX@Z @ 3 NONAME ; int CFdcPlugin::Extension_(unsigned int, void * &, void *)
+	?GetManufacturerStringDescriptor@MFdcPluginObserver@@QAEHIIAAV?$TBuf@$0IA@@@@Z @ 4 NONAME ; int MFdcPluginObserver::GetManufacturerStringDescriptor(unsigned int, unsigned int, class TBuf<128> &)
+	?GetProductStringDescriptor@MFdcPluginObserver@@QAEHIIAAV?$TBuf@$0IA@@@@Z @ 5 NONAME ; int MFdcPluginObserver::GetProductStringDescriptor(unsigned int, unsigned int, class TBuf<128> &)
+	?GetSupportedLanguagesL@MFdcPluginObserver@@QAEABV?$RArray@I@@I@Z @ 6 NONAME ; class RArray<unsigned int> const & MFdcPluginObserver::GetSupportedLanguagesL(unsigned int)
+	?NewL@CFdcPlugin@@CAPAV1@VTUid@@AAVMFdcPluginObserver@@@Z @ 7 NONAME ; class CFdcPlugin * CFdcPlugin::NewL(class TUid, class MFdcPluginObserver &)
+	?Observer@CFdcPlugin@@IAEAAVMFdcPluginObserver@@XZ @ 8 NONAME ; class MFdcPluginObserver & CFdcPlugin::Observer(void)
+	?TokenForInterface@MFdcPluginObserver@@QAEKE@Z @ 9 NONAME ; unsigned long MFdcPluginObserver::TokenForInterface(unsigned char)
+	?GetSerialNumberStringDescriptor@MFdcPluginObserver@@QAEHIIAAV?$TBuf@$0IA@@@@Z @ 10 NONAME ; int MFdcPluginObserver::GetSerialNumberStringDescriptor(unsigned int, unsigned int, class TBuf<128> &)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdcbase/EABI/fdcbaseu.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,16 @@
+EXPORTS
+	_ZN10CFdcPlugin10Extension_EjRPvS0_ @ 1 NONAME
+	_ZN10CFdcPlugin4NewLE4TUidR18MFdcPluginObserver @ 2 NONAME
+	_ZN10CFdcPlugin8ObserverEv @ 3 NONAME
+	_ZN10CFdcPluginC2ER18MFdcPluginObserver @ 4 NONAME
+	_ZN10CFdcPluginD0Ev @ 5 NONAME
+	_ZN10CFdcPluginD1Ev @ 6 NONAME
+	_ZN10CFdcPluginD2Ev @ 7 NONAME
+	_ZN18MFdcPluginObserver17TokenForInterfaceEh @ 8 NONAME
+	_ZN18MFdcPluginObserver22GetSupportedLanguagesLEj @ 9 NONAME
+	_ZN18MFdcPluginObserver26GetProductStringDescriptorEjjR4TBufILi128EE @ 10 NONAME
+	_ZN18MFdcPluginObserver31GetManufacturerStringDescriptorEjjR4TBufILi128EE @ 11 NONAME
+	_ZTI10CFdcPlugin @ 12 NONAME
+	_ZTV10CFdcPlugin @ 13 NONAME
+	_ZN18MFdcPluginObserver31GetSerialNumberStringDescriptorEjjR4TBufILi128EE @ 14 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdcbase/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#if !defined(WINS)
+
+PRJ_PLATFORMS
+ARMV5
+
+#include "fdcbase_base_bld.inf"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdcbase/group/fdcbase.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2007-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:
+* Base DLL for FDC plugins to the FDF.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+TARGET			fdcbase.dll
+TARGETTYPE		dll
+// UID2 = 0x1000008d for static interface DLLs.
+// UID3 = unique for FDF system
+UID 			0x1000008d 0x10282B48
+VENDORID		0x70000001
+
+SOURCEPATH		../src
+SOURCE			fdcplugin.cpp
+SOURCE			fdcpluginobserver.cpp
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY 		euser.lib
+LIBRARY 		ecom.lib
+
+#include <usb/usblogger.mmh>
+#include <usbhost/internal/fdfcaps.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdcbase/group/fdcbase_base_bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+PRJ_MMPFILES
+fdcbase.mmp
+
+PRJ_EXPORTS
+../public/fdcplugin.h					SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usbhost/internal/fdcplugin.h)
+../public/fdcplugin.hrh					/epoc32/include/usbhost/internal/fdcplugin.hrh
+../public/fdcinterface.h				SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usbhost/internal/fdcinterface.h)
+../public/fdcpluginobserver.h			SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usbhost/internal/fdcpluginobserver.h)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdcbase/group/fdcbase_over_dummyusbdi_bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,24 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+PRJ_TESTMMPFILES
+fdcbase.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdcbase/public/fdcinterface.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,158 @@
+/*
+* Copyright (c) 2007-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
+ @publishedPartner
+ @released
+*/
+
+#ifndef FDCINTERFACE_H
+#define FDCINTERFACE_H
+
+#include <e32base.h>
+
+class TUsbDeviceDescriptor;
+class TUsbConfigurationDescriptor;
+
+/** 
+The UID of this FDC interface. 
+If the FDC API ever has to change, a new UID and associated M class will be 
+created. New FDC implementations may implement the new API. Old (non-updated) 
+FDCs will still work because the FDF examines at run-time which interfaces are 
+supported by any particular FDC.
+*/
+const TInt KFdcInterfaceV1 = 0x10282B4C;
+
+/**
+Mixin for the FDC API.
+*/
+class MFdcInterfaceV1
+	{
+public:
+	/** 
+	Called when a device is attached.
+
+	The Function Driver Framework has determined that this Function Driver is 
+	the most suitable to drive at least one of the interfaces in the device's 
+	selected configuration.
+	
+  	Each call to this method represents an attempt by the Function Driver 
+	Framework to get the Function Driver Controller to take ownership of 
+	interfaces (exactly one Function) on the device.
+	
+	Not all the interfaces contained may be relevant to this Function Driver.
+	Some interfaces may be relevant to this Function Driver, but should *not* 
+	be claimed in this call, as described below.
+
+	The device's entire device descriptor and configuration descriptor are 
+	given. 
+
+	The Function Driver Framework provides a collection (aInterfaces) of 
+	interfaces which it is offering to the Function Driver Controller. The 
+	Function Driver Controller MUST take ownership of the first of these by 
+	calling MFdcPluginObserver::TokenForInterface (the Function Driver 
+	Controller was selected by the Function Driver Framework on the basis of 
+	its default_data field matching this particular interface). The Function 
+	Driver Controller MUST also take ownership of as many following interfaces 
+	as make up a single Function as defined by the relevant USB Class, again 
+	by calling MFdcPluginObserver::TokenForInterface for them.
+
+	The Function Driver Controller may examine interface descriptors for the 
+	interfaces it is being offered using the bInterfaceNumber items in 
+	aInterfaces, and the TUsbConfigurationDescriptor given 
+	(aConfigurationDescriptor).
+
+	Once exactly one Function has been claimed, the Function Driver Controller 
+	may return from this method. 
+	The Function Driver Framework does not make further attempts to load 
+	Function Drivers for the interfaces that have been claimed, whether an 
+	error is returned or not.
+	If an error is returned, then (a) the FDF will send a driver loading error 
+	to USBMAN, and (b) the FDC must not have opened ANY RUsbInterfaces as a 
+	result of this call to Mfi1NewFunction.
+	It is important for the Function Driver Controller to claim all the 
+	interfaces it should, even if it finds out early on that it won't be able 
+	to handle the Function for environmental or other reasons. 
+	The FDC may also return an error indicating that the Class-specific 
+	descriptors are incorrectly formatted.
+
+	The FD is not required to open RUsbInterface handles during 
+	Mfi1NewFunction. If it does, then it can pass any failure back as a return 
+	value to Mfi1NewFunction and this will be relayed to USBMAN as a driver 
+	loading error. If it does not, then the FD must itself take responsibility 
+	for relaying relevant failures to the user. (This is in aid of the 'no 
+	silent failures' requirement.)
+
+	This method may be called zero or more times for each device attached, 
+	depending on the interfaces present in the device's active configuration 
+	and on the other FDs present on the phone. If this function is called (and 
+	returns KErrNone) one or more times on a particular FDC, then 
+	Mfi1DeviceDetached will be called exactly once when the device is detached.
+	If on device attachment this function is called one or more times for a 
+	particular FDC, and each time the FDC returns an error, then no device 
+	detachment notification will be given to that FDC. Hence any RUsbInterface 
+	handles successfully opened in a call to this function should be cleaned 
+	up immediately if the function returns error.
+
+	@see MFdcPluginObserver::TokenForInterface.
+
+	@param aDeviceId This is the ID of the new device. This identifier is 
+	private between the Function Driver Framework and the Function Driver. Its 
+	significance is to identify a device when it is removed (see 
+	Mfi1DeviceDetached). It is not equivalent to the device address or to 
+	anything else.
+	
+	@param aInterfaces A collection of interface numbers (bInterfaceNumber) 
+	which are being offered to the Function Driver Controller. The Function 
+	Driver Controller uses items in this array in calls to 
+	MFdcPluginObserver::TokenForInterface. Ownership of the array is retained 
+	by the FDF.
+
+	@param aDeviceDescriptor The device descriptor of the device. Ownership is 
+	retained by the FDF.
+	
+	@param aConfigurationDescriptor The selected configuration descriptor of 
+	the device. Ownership is retained by the FDF.
+
+	@return Error. On return (ANY error code), the interfaces claimed in calls 
+	to MFdcPluginObserver::TokenForInterface are claimed by this FDC. If an 
+	error is returned, the FDC must cause no interface handles to be opened as 
+	a result of this call. The FDF will indicate a failure to load drivers to 
+	USBMAN.
+	*/
+	virtual TInt Mfi1NewFunction(TUint aDeviceId,
+		const TArray<TUint>& aInterfaces,
+		const TUsbDeviceDescriptor& aDeviceDescriptor,
+		const TUsbConfigurationDescriptor& aConfigurationDescriptor) = 0;
+	
+	/** 
+	Called when a device is detached.
+	The device is one of those which have previously been notified to the 
+	Function Driver in a Mfi1NewFunction call.
+	Any RUsbInterface handles which were opened as a result of the 
+	corresponding earlier Mfi1NewFunction call should be closed as they 
+	will be useless.
+
+	@param aDeviceId This serves to identify the device which has disappeared. 
+	This will be the device ID given in a previously completed 
+	Mfi1NewFunction call.
+	*/
+	virtual void Mfi1DeviceDetached(TUint aDeviceId) = 0;
+	};
+
+#endif // FDCINTERFACE_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdcbase/public/fdcplugin.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,95 @@
+/*
+* Copyright (c) 2007-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
+ @publishedPartner
+ @released
+*/
+
+#ifndef FDCPLUGIN_H
+#define FDCPLUGIN_H
+
+#include <e32base.h>
+
+class MFdcPluginObserver;
+
+/**
+Base class for FDC plugins.
+*/
+class CFdcPlugin : public CBase
+	{
+	// So we can make most of this class private- validly callable only by 
+	// CFdcProxy.
+	friend class CFdcProxy;
+
+private: // used by FDF to create and destroy FDC instances
+	/** 
+	Constructor.
+	@param aImplementationUid UID of implementation to create.
+	@param aObserver Handle back onto the FDF for the FDC to use.
+	@return Ownership of a new FDC plugin.
+	*/
+	IMPORT_C static CFdcPlugin* NewL(TUid aImplementationUid, MFdcPluginObserver& aObserver);
+
+	/**
+	Called by FDF to get a pointer to an object which implements the 
+	FDF API with UID aUid. This is a mechanism for allowing future change 
+	to the FDF API without breaking BC in existing (non-updated) FDF 
+	plugins.
+	*/
+	virtual TAny* GetInterface(TUid aUid) = 0;
+
+protected: // called by concrete FDF plugins
+	/** 
+	Constructor
+	*/
+	IMPORT_C CFdcPlugin(MFdcPluginObserver& aObserver);
+
+	/** Destructor. */
+	IMPORT_C ~CFdcPlugin();
+
+	/** 
+	Accessor for the interface to the FDF. 
+	@return Interface to the FDF.
+	*/
+	IMPORT_C MFdcPluginObserver& Observer();
+
+	/**
+	From CBase.
+	*/
+	IMPORT_C TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1);
+
+private: // owned
+	/**
+	UID set by ECOM when the instance is created. Used when the instance is 
+	destroyed.
+	*/
+	TUid iInstanceId;
+
+	/**
+	Interface for calls up to the FDF.
+	*/
+	MFdcPluginObserver& iObserver;
+
+	/** 
+	Pad for BC-friendly future change.
+	*/
+	TAny* iPad;
+	};
+
+#endif // FDCPLUGIN_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdcbase/public/fdcplugin.hrh	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 2007-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
+ @publishedPartner
+ @prototype
+*/
+
+#ifndef FDCPLUGIN_HRH
+#define FDCPLUGIN_HRH
+
+/**
+Definition of ECOM interface UID for Function Driver Controllers.
+*/
+#define KFdcEcomInterfaceUid 0x10281A86
+
+#endif // FDCPLUGIN_HRH
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdcbase/public/fdcpluginobserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,144 @@
+/*
+* Copyright (c) 2007-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
+ @publishedPartner
+ @released
+*/
+
+#ifndef FDCPLUGINOBSERVER_H
+#define FDCPLUGINOBSERVER_H
+
+#include <e32base.h>
+
+/**
+Interface for FDCs to call into the FDF.
+The public methods are non-virtual and exported, so that they can be added to
+without breaking BC for existing (non-rebuilt) FDCs.
+*/
+class MFdcPluginObserver
+	{
+	// So only a specific class internal to the FDF *can* derive from this M
+	// class.
+	friend class CFdcProxy;
+
+private:
+	inline MFdcPluginObserver() {}
+
+public:
+	/**
+	Retrieves the token for an interface and claims ownership of the
+	interface.
+
+	This method may only be called during execution of the FDC's
+	implementation of MFdcInterfaceV1::Mfi1NewFunction. If it is called at
+	any other time the FDC will be panicked.
+
+	If aInterface is not one of the interfaces listed in the array
+	'aInterfaces', passed to the FDC's implementation of
+	MFdcInterfaceV1::Mfi1NewFunction, then the FDC will be panicked.
+
+	In its implementation of MFdcInterfaceV1::Mfi1NewFunction, the FDC
+	is expected to make at least one call to TokenForInterface. If it does
+	not, it will be panicked.
+
+	The FDC is expected to make sufficient calls to TokenForInterface to claim
+	ownership of interfaces and to collect the tokens necessary to open
+	RUsbInterface handles on those interfaces.
+	The FDC must take a complete Function's worth of interfaces, and only a
+	single Function's worth of interfaces, depending on how the relevant USB
+	Class defines Functions.
+
+	WARNING:If the token is equal to 0 then the FDC should not make any attempt
+	to open any RUsbInterface handles with it because that means that the device has been
+	disconnected (cable removed or detached because was draining too much current)
+	thus will not being able to use the device
+
+	@param aInterface The interface number. This will come from aInterfaces as
+	passed in a call to MFdcInterfaceV1::Mfi1NewFunction.
+	@return The token for the interface
+	*/
+	IMPORT_C TUint32 TokenForInterface(TUint8 aInterface);
+
+	/**
+	Retrieves the language IDs supported by the given device (as expressed in
+	the device's string descriptor zero).
+	@param aDeviceId This is the device ID as given in
+	MFdcInterfaceV1::Mfi1NewFunction. If an invalid device ID is used then
+	the method will leave with KErrNotFound.
+	@return Non-ownership of an array of lang IDs.
+	*/
+	IMPORT_C const RArray<TUint>& GetSupportedLanguagesL(TUint aDeviceId);
+
+	/**
+	Retrieves the manufacturer string descriptor from the given device with
+	the given language ID.
+	@param aDeviceId This is the device ID as given in
+	MFdcInterfaceV1::Mfi1NewFunction.
+	@param aLangId The language ID of the desired string.
+	@param aString On return, the desired string.
+	@return Error.
+	*/
+	IMPORT_C TInt GetManufacturerStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString);
+
+	/**
+	Retrieves the product string descriptor from the given device with the
+	given language ID.
+	@param aDeviceId This is the device ID as given in
+	MFdcInterfaceV1::Mfi1NewFunction.
+	@param aLangId The language ID of the desired string.
+	@param aString On return, the desired string.
+	@return Error.
+	*/
+	IMPORT_C TInt GetProductStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString);
+
+	/**
+	Retrieves the serial number string descriptor from the given device with
+	the given language ID.
+	@param aDeviceId This is the device ID as given in
+	MFdcInterfaceV1::Mfi1NewFunction.
+	@param aLangId The language ID of the desired string.
+	@param aString On return, the desired string.
+	@return Error.
+	*/
+	IMPORT_C TInt GetSerialNumberStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString);
+
+private:
+	/**
+	@see TokenForInterface.
+	*/
+	virtual TUint32 MfpoTokenForInterface(TUint8 aInterface) = 0;
+	/**
+	@see GetSupportedLanguagesL.
+	*/
+	virtual const RArray<TUint>& MfpoGetSupportedLanguagesL(TUint aDeviceId) = 0;
+	/**
+	@see GetManufacturerStringDescriptor.
+	*/
+	virtual TInt MfpoGetManufacturerStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString) = 0;
+	/**
+	@see GetProductStringDescriptor.
+	*/
+	virtual TInt MfpoGetProductStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString) = 0;
+	/**
+	@see GetSerialNumberStringDescriptor.
+	*/
+	virtual TInt MfpoGetSerialNumberStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString) = 0;
+	};
+
+#endif // FDCPLUGINOBSERVER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdcbase/src/fdcplugin.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2007-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:
+* Implementation of FDC plugin.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <ecom/ecom.h>
+#include <usbhost/internal/fdcplugin.h>
+#include <usbhost/internal/fdcpluginobserver.h>
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdcplugin");
+#endif
+
+EXPORT_C CFdcPlugin::~CFdcPlugin()
+	{
+	LOG_FUNC
+
+	REComSession::DestroyedImplementation(iInstanceId);
+	}
+
+EXPORT_C CFdcPlugin::CFdcPlugin(MFdcPluginObserver& aObserver)
+:	iObserver(aObserver)
+	{
+	LOG_FUNC
+	}
+
+EXPORT_C CFdcPlugin* CFdcPlugin::NewL(TUid aImplementationUid, MFdcPluginObserver& aObserver)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	LOGTEXT2(_L8("\t\tFDC implementation UID: 0x%08x"), aImplementationUid);
+
+	CFdcPlugin* plugin = reinterpret_cast<CFdcPlugin*>(
+		REComSession::CreateImplementationL(
+			aImplementationUid, 
+			_FOFF(CFdcPlugin, iInstanceId),
+			&aObserver
+			)
+		);
+
+	LOGTEXT2(_L8("\tplugin = 0x%08x"), plugin);
+	return plugin;
+	}
+
+EXPORT_C MFdcPluginObserver& CFdcPlugin::Observer()
+	{
+	return iObserver;
+	}
+
+EXPORT_C TInt CFdcPlugin::Extension_(TUint aExtensionId, TAny*& a0, TAny* a1)
+	{
+	return CBase::Extension_(aExtensionId, a0, a1);
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdcbase/src/fdcpluginobserver.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include <usbhost/internal/fdcpluginobserver.h>
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdcplugin");
+#endif
+
+EXPORT_C TUint32 MFdcPluginObserver::TokenForInterface(TUint8 aInterface)
+	{
+	LOG_FUNC
+	
+	return MfpoTokenForInterface(aInterface);
+	}
+
+EXPORT_C const RArray<TUint>& MFdcPluginObserver::GetSupportedLanguagesL(TUint aDeviceId)
+	{
+	return MfpoGetSupportedLanguagesL(aDeviceId);
+	}
+
+EXPORT_C TInt MFdcPluginObserver::GetManufacturerStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
+	{
+	return MfpoGetManufacturerStringDescriptor(aDeviceId, aLangId, aString);
+	}
+
+EXPORT_C TInt MFdcPluginObserver::GetProductStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
+	{
+	return MfpoGetProductStringDescriptor(aDeviceId, aLangId, aString);
+	}
+
+EXPORT_C TInt MFdcPluginObserver::GetSerialNumberStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
+	{
+	return MfpoGetSerialNumberStringDescriptor(aDeviceId, aLangId, aString);
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/fdf.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef FDF_IBY
+#define FDF_IBY
+
+#include <ecom.iby>
+
+// USB_DIR is defined in usbman.iby (which should include this iby)
+
+file=ABI_DIR\USB_DIR\fdcbase.dll							fdcbase.dll
+file=ABI_DIR\USB_DIR\usbhoststack.dll						usbhoststack.dll
+file=ABI_DIR\USB_DIR\fdf.exe 								fdf.exe
+
+#endif // FDF_IBY
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#if !defined(WINS)
+
+PRJ_PLATFORMS
+ARMV5
+
+PRJ_MMPFILES
+fdf.mmp // production version
+
+PRJ_EXPORTS
+// Utility for everything running in the FDF's process.
+../public/fdfcaps.mmh					/epoc32/include/usbhost/internal/fdfcaps.mmh
+
+PRJ_TESTEXPORTS
+// Interface to the client side DLL.
+../public/fdfapi.h						SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usbhost/internal/fdfapi.h)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/group/fdf.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 2007-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:
+* 'Function Driver Framework'- part of the USB Host implementation. 
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "fdf_base.mmp"
+
+TARGET			fdf.exe
+// UID2 = 0x0 for plain exes
+// UID3 = unique for FDF system
+UID 			0x1000008c 0x10282B48
+
+LIBRARY			usbdescriptors.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/group/fdf_base.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2007-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:
+* Does not itself build an exe, but is used by other MMP files.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <usbhost/internal/fdfcaps.mmh>
+#include <usb/usblogger.mmh>
+
+TARGETTYPE		exe
+VENDORID		0x70000001
+
+SOURCEPATH		../src
+SOURCE			activewaitforbusevent.cpp
+SOURCE			activewaitforecomevent.cpp
+SOURCE			deviceproxy.cpp
+SOURCE			event.cpp
+SOURCE			eventqueue.cpp
+SOURCE			fdcproxy.cpp
+SOURCE			fdf.cpp
+SOURCE			fdfserver.cpp
+SOURCE			fdfsession.cpp
+SOURCE			main.cpp
+SOURCE			utils.cpp
+
+USERINCLUDE 	../inc
+USERINCLUDE 	../public
+USERINCLUDE		../../client/public
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN  
+
+NOEXPORTLIBRARY
+
+LIBRARY 		euser.lib
+LIBRARY			ecom.lib
+LIBRARY			fdcbase.lib
+
+#ifdef __FLOGGER_INCLUDED
+LIBRARY			efsrv.lib
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/group/fdf_over_dummyusbdi.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2007-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:
+* Special build of the 'Function Driver Framework' (part of the USB 
+* Host implementation) which runs over the DummyUSBDI for test purposes.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "fdf_base.mmp"
+
+TARGET			fdf_over_dummyusbdi.exe
+// UID2 = 0x0 for plain exes
+// UID3 = unique for 'FDF over DummyUSBDI' system
+UID 			0x1000008c 0x10282B50
+
+LIBRARY			dummyusbdi.lib
+LIBRARY			tfdf_usbdescriptors.lib
+
+MACRO	__OVER_DUMMYUSBDI__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/group/fdf_over_dummyusbdi_bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,24 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+PRJ_TESTMMPFILES
+fdf_over_dummyusbdi.mmp // unit test version
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/inc/activewaitforbusevent.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,61 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef ACTIVEWAITFORBUSEVENT_H
+#define ACTIVEWAITFORBUSEVENT_H
+
+#include <e32base.h>
+
+#ifdef __OVER_DUMMYUSBDI__
+#include <usbhost/dummyusbdi/d32usbdi_hubdriver.h>
+#else
+#include <d32usbdi_hubdriver.h>
+#endif
+
+NONSHARABLE_CLASS(MBusEventObserver)
+	{
+public:
+	virtual void MbeoBusEvent() = 0;
+	};
+
+NONSHARABLE_CLASS(CActiveWaitForBusEvent) : public CActive
+	{
+public:
+	static CActiveWaitForBusEvent* NewL(RUsbHubDriver& aHubDriver, 
+		RUsbHubDriver::TBusEvent& aBusEvent,
+		MBusEventObserver& aObserver);
+	~CActiveWaitForBusEvent();
+
+public:
+	void Wait();
+
+private:
+	CActiveWaitForBusEvent(RUsbHubDriver& aHubDriver, 
+		RUsbHubDriver::TBusEvent& aBusEvent,
+		MBusEventObserver& aObserver);
+
+private: // from CActive
+	void RunL();
+	void DoCancel();
+
+private: // unowned
+	RUsbHubDriver& iHubDriver;
+	RUsbHubDriver::TBusEvent& iBusEvent;
+	MBusEventObserver& iObserver;
+	};
+
+#endif // ACTIVEWAITFORBUSEVENT_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/inc/activewaitforecomevent.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,53 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef ACTIVEWAITFORECOMEVENT_H
+#define ACTIVEWAITFORECOMEVENT_H
+
+#include <e32base.h>
+#include <ecom/ecom.h>
+
+NONSHARABLE_CLASS(MEComEventObserver)
+	{
+public:
+	virtual void EComEventReceived() = 0;
+	};
+
+NONSHARABLE_CLASS(CActiveWaitForEComEvent) : public CActive
+	{
+public:
+	static CActiveWaitForEComEvent* NewL(MEComEventObserver& aObserver);
+	~CActiveWaitForEComEvent();
+
+public:
+	void Wait();
+
+private:
+	void ConstructL();
+	CActiveWaitForEComEvent(MEComEventObserver& aObserver);
+
+private: // from CActive
+	void RunL();
+	void DoCancel();
+	TInt RunError(TInt aError);	
+
+private: 
+	REComSession 		iEComSession;
+	MEComEventObserver& iObserver; 
+	};
+
+#endif // ACTIVEWAITFORECOMEVENT_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/inc/deviceproxy.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,149 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#ifndef DEVICEPROXY_H
+#define DEVICEPROXY_H
+
+#include <e32base.h>
+#include "usbhoststack.h"
+
+#ifdef __OVER_DUMMYUSBDI__
+#include <usbhost/dummyusbdi/d32usbdi_hubdriver.h>
+#else
+#include <d32usbdi_hubdriver.h>
+#endif
+
+class TDeviceEvent;
+class TOtgDescriptor;
+
+NONSHARABLE_CLASS(CDeviceProxy) : public CBase
+	{
+public:
+	/** Link between elements of this type in a TSglQue. */
+	TSglQueLink iLink;
+
+public:
+	static CDeviceProxy* NewL(RUsbHubDriver& aHubDriver, TUint aDeviceId);
+	~CDeviceProxy();
+
+public: // querying information from the device
+	TInt GetDeviceDescriptor(TUsbDeviceDescriptor& aDescriptor);
+	TInt GetConfigurationDescriptor(TUsbConfigurationDescriptor& aDescriptor) const;
+	const RArray<TUint>& GetSupportedLanguages() const;
+	void GetManufacturerStringDescriptorL(TUint32 aLangId, TName& aString) const;
+	void GetProductStringDescriptorL(TUint32 aLangId, TName& aString) const;
+	void GetSerialNumberStringDescriptorL(TUint32 aLangId, TName& aString) const;
+	
+	void GetOtgDescriptorL(TOtgDescriptor& aDescriptor) const;
+	void SetOtgDescriptorL(const TUsbOTGDescriptor& aDescriptor);
+
+public: // management
+	TInt GetTokenForInterface(TUint aIndex, TUint32& aToken) const;
+	TUint DeviceId() const;
+	void SetDriverLoadingEventData(TDriverLoadStatus aStatus, TInt aError = KErrNone);
+	TInt Suspend();
+
+	// These methods TAKE OWNERSHIP of the relevant objects.
+	TDeviceEvent* GetAttachmentEventObject();
+	TDeviceEvent* GetDriverLoadingEventObject();
+	TDeviceEvent* GetDetachmentEventObject();
+	inline void SetMultipleDriversFlag()
+	{
+		iMultipleDriversFound = ETrue;
+	}
+
+	inline TBool MultipleDriversFlag()
+	{
+		return iMultipleDriversFound;
+	}
+	inline void SetHasIADFlag()
+	{
+		iHasIAD = ETrue;
+	}
+	inline TBool HasIADFlag()
+	{
+		return iHasIAD;
+	}
+
+private:
+	CDeviceProxy(TUint aDeviceId);
+	void ConstructL(RUsbHubDriver& aHubDriver);
+
+private: // utility
+	void Log();
+	void ReadStringDescriptorsL();
+	void PopulateStringDescriptorsL(TUint8 aStringDescriptorIndex, RArray<TName>& aStringArray);
+	void GetStringDescriptorFromUsbdL(TUint32 aLangId, TName& aString, TUint8 aStringDescriptorIndex) const;
+	void GetStringDescriptorFromCacheL(TUint32 aLangId, TName& aString, const RArray<TName>& aStringArray) const;
+
+private: // owned
+	RUsbDevice iHandle;
+	const TUint iId;
+
+	TDeviceEvent* iAttachmentEvent;
+	TDeviceEvent* iDriverLoadingEvent;
+	TDeviceEvent* iDetachmentEvent;
+
+	// The design of string descriptor access in this class deserves some 
+	// explanation.
+	// In the simplest implementation of the FDF, we handle a device 
+	// attachment without getting or storing any string descriptors from the 
+	// device. If the FDF doesn't load any drivers for the device, it must 
+	// suspend the device to save power. If USBMAN, subsequent to this, 
+	// queries any string descriptors, the FDF will have to resume the device 
+	// first (string descriptors are not requested or cached by USBD). 
+	// Resuming a device is an asynchronous operation. We must therefore 
+	// either make querying a string descriptor asynchronous as far as USBMAN 
+	// is concerned (which would clearly make the relevant APIs much less 
+	// friendly) or find another way round. [For completeness: this 
+	// asynchronicity would rely on 
+	// RHubDriver::QueueDeviceStateChangeNotification.]
+	// Solution 1: if the FDF doesn't load drivers for the device, wait until 
+	// USBSVR has queried string descriptors from us before suspending the 
+	// device. Con: USBMAN only queries string descriptors when its client (in 
+	// licensee-land) does so. We can't make any assumptions about their doing 
+	// it in a timely manner or indeed at all. 
+	// Solution 2: use User::After to give the device time to resume 
+	// synchronously. Con: this is a major no-no in a production thread which 
+	// must remain responsive to user requests and lower-level events. 
+	// Mentioned only for completeness.
+	// Solution 3 (implemented): request and cache all supported string 
+	// descriptors at attachment time. String descriptors are typically small 
+	// (a dozen characters, say), we only support 3 of them (manufacturer, 
+	// product and serial number- not all of which may actually be supported 
+	// by a particular device) and there is usually only 1 language, if that. 
+	// Having cached the string descriptors, it is trivial to look them up 
+	// later when the client wants.
+	// These arrays are tied together, i.e. iManufacturerStrings[2] is the 
+	// manufacturer string in the language with ID iLangIds[2]. Note that this 
+	// may be KNullDesC if the device doesn't support the manufacturer string 
+	// descriptor, but there's still an entry in the array for it.
+	RArray<TUint> iLangIds;
+	RArray<TName> iManufacturerStrings;
+	RArray<TName> iProductStrings;
+	RArray<TName> iSerialNumberStrings;
+	TBool		  iHasIAD;
+	TBool         iMultipleDriversFound;
+	TOtgDescriptor* iOtgDescriptor; // Owned
+	};
+
+#endif // DEVICEPROXY_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/inc/event.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef EVENT_H
+#define EVENT_H
+
+#include <e32base.h>
+#include "usbhoststack.h"
+
+/**
+TEvent wraps up information about a single device-related event.
+*/
+NONSHARABLE_CLASS(TDeviceEvent)
+	{
+public:
+	TSglQueLink iLink;
+
+	TDeviceEvent();
+	~TDeviceEvent();
+
+	void Log() const;
+
+public:
+	TDeviceEventInformation iInfo;
+	};
+
+#endif // EVENT_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/inc/eventqueue.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,114 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef EVENTQUEUE_H
+#define EVENTQUEUE_H
+
+#include <e32base.h>
+#include "event.h"
+
+class CFdf;
+
+/**
+CEventQueue wraps all the events which are to be passed to USBMAN.
+These are of two kinds:
+1/ Devmon events. These are non-device-specific, and are sent to USBMAN
+through the NotifyDevmonEvent server API. We cannot drop any of these, so a
+count of each possible type is kept. When more than one such error is waiting
+to be given to USBMAN, they are given up in an arbitrary order.
+2/ Device events. These are device-specific, and indicate attachment, driver
+loading, or detachment. They are sent to USBMAN through the NotifyDeviceEvent
+server API. We keep a count of unsuccessful device attachments. These events
+are given up to USBMAN in the following order: unsuccessful attachments, then
+as they come in the queue. (For any one device, the queued events come in the
+order attachment, driver loading, detachment.)
+*/
+NONSHARABLE_CLASS(CEventQueue) : public CBase
+	{
+public:
+	static CEventQueue* NewL(CFdf& aFdf);
+	~CEventQueue();
+
+public:
+	// Called by CFdf when an attachment failure occurs.
+	void AttachmentFailure(TInt aError);
+
+	// Called by CFdf when a successful attachment, driver load or detachment
+	// occurs.
+	// NB aEvent is not const because we need to add it to a linked list
+	void AddDeviceEvent(TDeviceEvent& aEvent);
+
+	// Called by CFdf when a devmon event occurs.
+	void AddDevmonEvent(TInt aEvent);
+
+	// Called by CEventQueue (when an event is added, we poke the session to
+	// see if it's waiting for any new events) and by CFdfSession when the
+	// relevant notification (device or devmon) is placed.
+	TBool GetDeviceEvent(TDeviceEvent& aEvent);
+	TBool GetDevmonEvent(TInt& aEvent);
+
+private:
+	CEventQueue(CFdf& aFdf);
+
+private:
+	void Log();
+	void PokeSession();
+
+private: // unowned
+	CFdf& iFdf;
+
+private: // owned
+	TSglQue<TDeviceEvent> iDeviceEvents;
+
+	// These are used to index our array of the counts of different attachment
+	// failures.
+	enum
+		{
+		KSetAddrFailed					= 0,
+		KNoPower						= 1,
+		KBadPower						= 2,
+		KIOError						= 3,
+		KTimeout						= 4,
+		KStalled						= 5,
+		KNoMemory						= 6,
+		KConfigurationHasNoInterfaces	= 7,
+		KInterfaceCountMismatch			= 8,
+		KDuplicateInterfaceNumbers		= 9,
+		KBadHandle						= 10,
+		KAttachmentFailureGeneralError  = 11,
+		KNumberOfAttachmentFailureTypes	= 12,
+		};
+	TFixedArray<TUint, KNumberOfAttachmentFailureTypes> iAttachmentFailureCount;
+
+	// These are used to index our array of the counts of different devmon
+	// events.
+	enum
+		{
+		KUsbDeviceRejected			= 0,
+		KUsbDeviceFailed			= 1,
+		KUsbBadDevice				= 2,
+		KUsbBadHubPosition			= 3,
+		KUsbBadHub					= 4,
+		KUsbEventOverflow			= 5,
+		KUsbBadDeviceAttached       = 6,
+		KUsbBadDeviceDetached       = 7,
+		KNumberOfDevmonEventTypes	= 8,
+		};
+	TFixedArray<TUint, KNumberOfDevmonEventTypes> iDevmonEventCount;
+	};
+
+#endif // EVENTQUEUE_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/inc/fdcproxy.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,105 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#ifndef FDCPROXY_H
+#define FDCPROXY_H
+
+#include <e32base.h>
+#include <usbhost/internal/fdcpluginobserver.h>
+#include <usb/usblogger.h>
+
+class CFdcPlugin;
+class MFdcInterfaceV1;
+class CImplementationInformation;
+class TUsbDeviceDescriptor;
+class TUsbConfigurationDescriptor;
+class CFdf;
+
+/**
+CFdcProxy is a class internal to the FDF. 
+It is used to interface to CFdcPlugins, providing for 
+(a) re-use of CFdcPlugin objects for multiple devices, and 
+(b) easy finding of required CFdcPlugins by caching the data on which they 
+match USB interfaces. 
+*/
+NONSHARABLE_CLASS(CFdcProxy) : public CBase, public MFdcPluginObserver
+	{
+public:
+	/** Link between elements of this type in a TSglQue. */
+	TSglQueLink iLink;
+
+public:
+	static CFdcProxy* NewL(CFdf& aFdf, CImplementationInformation& aImplInfo);
+	~CFdcProxy();
+
+public:
+	const TDesC8& DefaultDataField() const;
+	TInt NewFunction(TUint aDeviceId,
+	const RArray<TUint>& aInterfaces,
+	const TUsbDeviceDescriptor& aDeviceDescriptor,
+	const TUsbConfigurationDescriptor& aConfigurationDescriptor);
+	void DeviceDetached(TUint aDeviceId);
+	TUid ImplUid() const;
+	TInt Version() const;
+	TInt DeviceCount() const;
+	void MarkForDeletion();
+	void UnmarkForDeletion();
+	TBool MarkedForDeletion() const;
+	TBool RomBased() const;
+
+private:
+	CFdcProxy(CFdf& aFdf);
+	void ConstructL(CImplementationInformation& aImplInfo);
+
+private: // from MFdcPluginObserver
+	TUint32 MfpoTokenForInterface(TUint8 aInterface);
+	const RArray<TUint>& MfpoGetSupportedLanguagesL(TUint aDeviceId);
+	TInt MfpoGetManufacturerStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString);
+	TInt MfpoGetProductStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString);
+	TInt MfpoGetSerialNumberStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString);
+
+private: // utilities
+	void Invariant() const;
+	void Log() const;
+	void NewFunctionL(TUint aDeviceId,
+	const RArray<TUint>& aInterfaces,
+	const TUsbDeviceDescriptor& aDeviceDescriptor,
+	const TUsbConfigurationDescriptor& aConfigurationDescriptor);
+	void CheckDeviceIdL(TUint aDeviceId) const;
+
+private: // unowned
+	CFdf& iFdf;
+	
+private: // owned
+	TUid				iImplementationUid;
+	TInt				iVersion;
+	RBuf8				iDefaultData;
+	RArray<TUint> 		iDeviceIds;
+	CFdcPlugin* 		iPlugin;
+	MFdcInterfaceV1*	iInterface;
+	TBool 				iInMfi1NewFunction;
+	TInt 				i0thInterface;
+	TBool				iMarkedForDeletion;
+	TBool				iRomBased;
+	};
+
+#endif // FDCPROXY_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/inc/fdf.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,184 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#ifndef FDF_H
+#define FDF_H
+
+#include <e32base.h>
+#include "activewaitforbusevent.h"
+#include "activewaitforecomevent.h"
+#include <ecom/ecom.h>
+#include "deviceproxy.h"
+#include "fdcproxy.h"
+
+class CFdfSession;
+class CEventQueue;
+
+NONSHARABLE_CLASS(CFdf) : public CBase, public MBusEventObserver, public MEComEventObserver
+	{
+private: // types used internally
+	struct TInterfaceInfo
+		{
+		// This odd NewL either: leaves safely, or passes ownership of the new
+		// TInterfaceInfo to aInterfaces.
+		static TInterfaceInfo* NewL(RPointerArray<TInterfaceInfo>& aInterfaces);
+
+		TUint8 iNumber;
+		TUint8 iClass;
+		TUint8 iSubclass;
+		TUint8 iProtocol;
+
+		TBool iClaimed;
+		};
+		
+		
+	enum TDeviceSearchKeys
+		{
+		EVendorProductDevice						= 0,
+		EVendorProduct								= 1,
+		EVendorDevicesubclassDeviceprotocol			= 2,
+		EVendorDevicesubclass						= 3,
+		EDeviceclassDevicesubclassDeviceprotocol 	= 4,
+		EDeviceclassDevicesubclass					= 5,
+		EMaxDeviceSearchKey							= 6
+		};		
+		
+		
+	enum TInterfaceSearchKeys
+		{
+		EVendorProductDeviceConfigurationvalueInterfacenumber	= 0,
+		EVendorProductConfigurationValueInterfacenumber			= 1,
+		EVendorInterfacesubclassInterfaceprotocol				= 2,
+		EVendorInterfacesubclass								= 3,
+		EInterfaceclassInterfacesubclassInterfaceprotocol		= 4,
+		EInterfaceclassInterfacesubclass						= 5,
+		EMaxInterfaceSearchKey									= 6,
+		};
+
+public:
+	static CFdf* NewL();
+	~CFdf();
+
+public: // called by CFdfSession
+	TBool GetDeviceEvent(TDeviceEvent& aEvent);
+	TBool GetDevmonEvent(TInt& aEvent);
+
+public: // called by CFdfServer
+	void SetSession(CFdfSession* aSession);
+
+public: // called by event queue
+	CFdfSession* Session();
+
+public: // invoked indirectly by USBMAN
+	void EnableDriverLoading();
+	void DisableDriverLoading();
+
+public: // called by CFdcProxy
+	TUint32 TokenForInterface(TUint8 aInterface); 
+	void GetSerialNumberStringDescriptorL(TUint aDeviceId, TUint32 aLangId, TName& aString) const;
+
+public: // called by CFdcProxy and CFdfSession
+	void GetManufacturerStringDescriptorL(TUint aDeviceId, TUint32 aLangId, TName& aString) const;
+	void GetProductStringDescriptorL(TUint aDeviceId, TUint32 aLangId, TName& aString) const;
+	const RArray<TUint>& GetSupportedLanguagesL(TUint aDeviceId) const;
+	void GetOtgDeviceDescriptorL(TInt aDeviceId, TOtgDescriptor& aDescriptor) const;
+	
+private:
+	CFdf();
+	void ConstructL();
+
+private: 
+	void MbeoBusEvent();		// from MBusEventObserver
+	void EComEventReceived();	// from MEComEventObserver
+	void HandleEComEventReceivedL();
+	
+private: // utility
+	void CreateFunctionDriverProxiesL();
+	CDeviceProxy* DeviceProxyL(TUint aDeviceId) const;
+	void TellFdcsOfDeviceDetachment(TUint aDeviceId);
+	void ParseL(TUsbGenericDescriptor& aDesc);
+
+	// Top-level handlers of MBusEventObserver events (calls to MbeoBusEvent)
+	void HandleDeviceAttachment(TUint aDeviceId);
+	void HandleDeviceDetachment(TUint aDeviceId);
+	void HandleDevmonEvent(TInt aEvent);
+
+	// Second-level handler of device attachment. Performs the first step:
+	// *actual* device attachment at the FDF level.
+	void HandleDeviceAttachmentL(TUint aDeviceId, CDeviceProxy*& aDevice);
+
+	// Second-level handler of device attachment. Performs the second step:
+	// driver loading.
+	void DoDriverLoading(CDeviceProxy& aDevice);
+	void DoDriverLoadingL(CDeviceProxy& aDevice);
+
+	// Utilities for driver loading.
+
+	void FindDriversForInterfacesUsingSpecificKeyL(CDeviceProxy& aDevice,
+													TInt& aCollectedErr,
+													TBool& aAnySuccess,			
+													RArray<TUint>& aInterfacesNumberArray, 
+													TInterfaceSearchKeys aKey);											
+
+	void FindDriverForInterfaceUsingSpecificKey(CDeviceProxy& aDevice,
+						TInt& aCollectedErr,
+						TBool& aAnySuccess,
+						RArray<TUint>& aInterfacesGivenToFdc,
+						const TDesC8& aSearchKey);
+	TBool SearchForADeviceFunctionDriverL(CDeviceProxy& aDevice, TBool& aAnySuccess, TInt& aCollectedErr);
+	void SearchForInterfaceFunctionDriversL(CDeviceProxy& aDevice, TBool& aAnySuccess, TInt& aCollectedErr);					
+	void FormatDeviceSearchKey(TDes8& aSearchKey, TDeviceSearchKeys aSearchKeys);
+	void FormatInterfaceSearchKey(TDes8& aSearchKey, TInterfaceSearchKeys aSearchKeys,  const TInterfaceInfo& aIfInfo);
+	TUint UnclaimedInterfaceCount() const;
+	void AppendInterfaceNumberToArrayL(CDeviceProxy& aDevice, RArray<TUint>& aArray, TUint aInterfaceNo) const;
+	void SetFailureStatus(TInt aUnclaimedInterfaces, TInt aInterfaceCount, TBool aAnySuccess, TBool aCollectedErr, CDeviceProxy& aDevice);
+	TBool FindMultipleFDs(const TDesC8& aSearchKey,TSglQueIter<CFdcProxy>& aFdcIter);
+	void  RebuildUnClaimedInterfacesArrayL(CDeviceProxy& aDevice, RArray<TUint>& aArray, TUint aOffset = 0);
+private: // unowned
+	CFdfSession* iSession;
+
+private: // owned
+	TUsbDeviceDescriptor 			iDD;
+	TUsbConfigurationDescriptor 	iCD;
+	TBool 							iDriverLoadingEnabled;
+	CEventQueue* 					iEventQueue;
+
+	TBool 							iDeviceDetachedTooEarly;
+
+	RImplInfoPtrArray 				iImplInfoArray;
+
+	// Our session on (and data from) the USBDI thunk.
+	RUsbHubDriver 					iHubDriver;
+	CActiveWaitForBusEvent* 		iActiveWaitForBusEvent;
+	CActiveWaitForEComEvent*		iActiveWaitForEComEvent;
+	RUsbHubDriver::TBusEvent 		iBusEvent;
+
+	// Our collections of attached devices and of Function Driver Controllers.
+	TSglQue<CDeviceProxy> 			iDevices;
+	TSglQue<CFdcProxy> 				iFunctionDrivers;
+
+	// Used while offering interfaces to FDCs.
+	RPointerArray<TInterfaceInfo>	iInterfaces; 	
+	CDeviceProxy* 					iCurrentDevice;	// iCurrentDevice is not owned by CFdf
+	};
+
+#endif // FDF_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/inc/fdfserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,61 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#ifndef FDFSERVER_H
+#define FDFSERVER_H
+
+#include <e32base.h>
+
+class CFdfSession;
+class CFdf;
+
+NONSHARABLE_CLASS(CFdfServer) : public CServer2
+	{
+public:
+	static void NewLC();
+	~CFdfServer();
+
+public: // called by session objects
+	void SessionClosed();
+
+private:
+	CFdfServer();
+	void ConstructL();
+	
+private: // from CPolicyServer
+	/**
+	Called by the base class to create a new session.
+	@param aVersion Version of client
+	@param aMessage Client's IPC message
+	@return A new session to be used for the client. If this could not be made, 
+	this function should leave.
+	*/
+	CSession2* NewSessionL(const TVersion &aVersion, const RMessage2& aMessage) const;
+
+private: // unowned
+	CFdfSession* iSession;
+
+private: // owned
+	CFdf* iFdf;
+	};
+
+#endif // FDFSERVER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/inc/fdfsession.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#ifndef FDFSESSION_H
+#define FDFSESSION_H
+
+#include <e32base.h>
+
+class CFdfServer;
+class CFdf;
+class TDeviceEvent;
+
+NONSHARABLE_CLASS(CFdfSession) : public CSession2
+	{
+public:
+	CFdfSession(CFdf& iFdf, CFdfServer& aServer);
+	~CFdfSession();
+
+public: // called by CFdfServer
+	void DeviceEvent(const TDeviceEvent& aEvent);
+	void DevmonEvent(TInt aEvent);
+
+public:
+	TBool NotifyDeviceEventOutstanding() const;
+	TBool NotifyDevmonEventOutstanding() const;
+
+private: // from CSession2
+	/**
+	Called when a message is received from the client.
+	@param aMessage Message received from the client.
+	*/
+	void ServiceL(const RMessage2& aMessage);
+
+private: // utility- IPC command handlers
+	void EnableDriverLoading(const RMessage2& aMessage);
+	void DisableDriverLoading(const RMessage2& aMessage);
+	void NotifyDeviceEvent(const RMessage2& aMessage);
+	void NotifyDeviceEventCancel(const RMessage2& aMessage);
+	void NotifyDevmonEvent(const RMessage2& aMessage);
+	void NotifyDevmonEventCancel(const RMessage2& aMessage);
+	void GetSingleSupportedLanguageOrNumberOfSupportedLanguages(const RMessage2& aMessage);
+	void GetSupportedLanguages(const RMessage2& aMessage);
+	void GetManufacturerStringDescriptor(const RMessage2& aMessage);
+	void GetProductStringDescriptor(const RMessage2& aMessage);
+	
+	void GetOtgDeviceDescriptor(const RMessage2& aMessage);
+
+private:
+	enum TStringType
+		{
+		EManufacturer,
+		EProduct,
+		};
+
+private: // utility
+	void CompleteClient(const RMessage2& aMessage, TInt aError);
+	void CompleteDeviceEventNotification(const TDeviceEvent& aEvent);
+	void CompleteDeviceEventNotificationL(const TDeviceEvent& aEvent);
+	void CompleteDevmonEventNotification(TInt aEvent);
+	void CompleteDevmonEventNotificationL(TInt aEvent);
+	void GetStringDescriptor(const RMessage2& aMessage, TStringType aStringType);
+	void GetStringDescriptorL(const RMessage2& aMessage, TStringType aStringType);
+	void GetSingleSupportedLanguageOrNumberOfSupportedLanguagesL(const RMessage2& aMessage);
+	void GetSupportedLanguagesL(const RMessage2& aMessage);
+
+private: // unowned
+	CFdf& iFdf;
+	CFdfServer& iServer;
+
+	RMessage2 iNotifyDeviceEventMsg;
+	RMessage2 iNotifyDevmonEventMsg;
+	};
+
+#endif // FDFSESSION_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/inc/utils.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,101 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <e32base.h>
+#include <ecom/ecom.h>
+#include <usb/usblogger.h>
+
+// In debug, using checking forms of CleanupStack::Pop. In release builds, 
+// use the non-checking form to save a little bit of ROM.
+#ifdef _DEBUG
+#define CLEANUPSTACK_POP1(a)		CleanupStack::Pop(a);
+#define CLEANUPSTACK_POP2(a, b) 	CleanupStack::Pop(a, b);
+#else
+#define CLEANUPSTACK_POP1(a)		CleanupStack::Pop();
+#define CLEANUPSTACK_POP2(a, b) 	CleanupStack::Pop(2);
+#endif // _DEBUG
+
+// What we want for internal programming errors in a server is a set of macros 
+// which, to save effort all round, use __LINE__ as the panic code, and a 
+// file-specific panic category. To make this non-standard pattern as helpful 
+// to users as possible, we append ' line#' to the category. That means we 
+// first have to check that the category is 10 characters long or less, so 
+// that the whole thing is legible to users when it appears on the screen.
+template <TBool> struct ASSERTION_FAILURE;
+TEMPLATE_SPECIALIZATION struct ASSERTION_FAILURE<ETrue>{};
+template <TInt> struct __assertion_test;
+#define COMPILE_ASSERT( B ) void __compile_assert(::__assertion_test<sizeof(::ASSERTION_FAILURE<(B)>)>)
+
+// We want a 10-character string (but allow for the NULL terminator).
+#define PANICCATEGORY(aaa) COMPILE_ASSERT(sizeof(L##aaa)/2 <= 11); _LIT(KPanicCat, aaa) 
+
+// A handy panic-self macro- the category is KPanicCat with " line#" appended; 
+// the code is the line number. 
+#define PANIC_LINENUM \
+	{ \
+	_LIT(KLnNo, " line#"); \
+	TBuf<KMaxExitCategoryName> cat = KPanicCat(); \
+	cat.Append(KLnNo()); \
+	_USB_PANIC(cat, __LINE__); \
+	}
+
+// A handy assertion macro that panics with a locally-defined panic category 
+// and the line number.
+#define ASSERT_ALWAYS(a) \
+	{ \
+	if ( !(a) ) \
+		{ \
+		PANIC_LINENUM; \
+		} \
+	}
+
+#ifdef _DEBUG
+#define ASSERT_DEBUG(a) ASSERT_ALWAYS(a)
+#define DEBUG_PANIC_LINENUM PANIC_LINENUM
+#else
+#define ASSERT_DEBUG(a)
+#define DEBUG_PANIC_LINENUM
+#endif // _DEBUG
+
+// Undefine the e32def.h-defined ASSERT macro to make sure no-one uses it 
+// under the mistaken impression that it's useful. Use our informative one 
+// above instead!
+#undef ASSERT
+
+/**
+Cleanup stack item to remove a given TUint from an RArray.
+*/
+struct TArrayRemove
+	{
+	TArrayRemove(RArray<TUint>& aDeviceIds, TUint aDeviceId);
+	~TArrayRemove();
+	
+	RArray<TUint>& iDeviceIds;
+	const TUint iDeviceId;
+	};
+void CleanupRemovePushL(TArrayRemove& aArrayRemove);
+void Remove(TAny* aArrayRemove);
+
+#endif // UTILS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/public/fdfapi.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,73 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#ifndef FDFAPI_H
+#define FDFAPI_H
+
+#include <e32base.h>
+
+#ifdef __OVER_DUMMYUSBDI__
+const TUint32 KUsbFdfTUint = 0x10282B50;
+_LIT(KUsbFdfImg, "fdf_over_dummyusbdi.exe");
+#else
+const TUint32 KUsbFdfTUint = 0x10282B48;
+_LIT(KUsbFdfImg, "fdf.exe");
+#endif
+
+const TUid KUsbFdfUid = {KUsbFdfTUint};
+
+_LIT(KUsbFdfServerName, "!FdfSrv");
+
+/** Version numbers. */
+const TInt8 KUsbFdfSrvMajorVersionNumber = 1;
+const TInt8 KUsbFdfSrvMinorVersionNumber = 1;
+const TInt16 KUsbFdfSrvBuildNumber = 0;
+
+/** IPC messages supported by the server. */
+enum
+	{
+	EUsbFdfSrvEnableDriverLoading										= 0,
+	EUsbFdfSrvDisableDriverLoading										= 1,
+	EUsbFdfSrvNotifyDeviceEvent											= 2,
+	EUsbFdfSrvNotifyDeviceEventCancel									= 3,
+	EUsbFdfSrvNotifyDevmonEvent											= 4,
+	EUsbFdfSrvNotifyDevmonEventCancel									= 5,
+	EUsbFdfSrvGetSingleSupportedLanguageOrNumberOfSupportedLanguages	= 6,
+	EUsbFdfSrvGetSupportedLanguages										= 7,
+	EUsbFdfSrvGetManufacturerStringDescriptor							= 8,
+	EUsbFdfSrvGetProductStringDescriptor								= 9,
+	EUsbFdfSrvGetOtgDescriptor                                          = 10,
+	EUsbFdfSrvDbgFailNext												= 11,
+	EUsbFdfSrvDbgAlloc													= 12,
+	};
+
+/** Panic codes which which the server panics an offending client. */
+enum
+	{
+	EBadIpc									= 0,
+	ENotifyDeviceEventAlreadyOutstanding	= 1,
+	ENotifyDevmonEventAlreadyOutstanding	= 2,
+	EBadNotifyDeviceEventData				= 3,
+	EBadNotifyDevmonEventData				= 4,
+	};
+
+#endif // FDFAPI_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/public/fdfcaps.mmh	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 2007-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:
+* This file is provided as a facility to FDC implementers.
+* It may be #included in mmp files to provide only those capabilities 
+* required to run in the FDF's process.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef FDFCAPS_MMH
+#define FDFCAPS_MMH
+
+CAPABILITY ProtServ CommDD
+
+#endif // FDFCAPS_MMH
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/src/activewaitforbusevent.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "activewaitforbusevent.h"
+#include <usb/usblogger.h>
+#include "utils.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdf      ");
+#endif
+
+
+CActiveWaitForBusEvent::CActiveWaitForBusEvent(RUsbHubDriver& aHubDriver,
+											   RUsbHubDriver::TBusEvent& aBusEvent,
+											   MBusEventObserver& aObserver)
+:	CActive(CActive::EPriorityStandard),
+	iHubDriver(aHubDriver),
+	iBusEvent(aBusEvent),
+	iObserver(aObserver)
+	{
+	LOG_FUNC
+
+	CActiveScheduler::Add(this);
+	}
+
+CActiveWaitForBusEvent::~CActiveWaitForBusEvent()
+	{
+	LOG_FUNC
+
+	Cancel();
+	}
+
+CActiveWaitForBusEvent* CActiveWaitForBusEvent::NewL(RUsbHubDriver& aHubDriver,
+													 RUsbHubDriver::TBusEvent& aBusEvent,
+													 MBusEventObserver& aObserver)
+	{
+	CActiveWaitForBusEvent* self = new(ELeave) CActiveWaitForBusEvent(aHubDriver, aBusEvent, aObserver);
+	return self;
+	}
+
+void CActiveWaitForBusEvent::Wait()
+	{
+	LOG_FUNC
+
+	iHubDriver.WaitForBusEvent(iBusEvent, iStatus);
+	SetActive();
+	}
+
+void CActiveWaitForBusEvent::RunL()
+	{
+	LOG_LINE
+	LOG_FUNC
+	LOGTEXT3(_L8("\tiStatus = %d , iBusEvent.iError=%d "), iStatus.Int(),iBusEvent.iError);
+
+	iObserver.MbeoBusEvent();
+	}
+
+void CActiveWaitForBusEvent::DoCancel()
+	{
+	LOG_FUNC
+
+	iHubDriver.CancelWaitForBusEvent();
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/src/activewaitforecomevent.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,92 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+
+#include "activewaitforecomevent.h"
+#include <usb/usblogger.h>
+#include "utils.h"
+
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdf      ");
+#endif
+
+#ifdef _DEBUG
+_LIT( KFdfEcomEventAOPanicCategory, "FdfEcomEventAO" );
+#endif
+
+CActiveWaitForEComEvent::CActiveWaitForEComEvent(MEComEventObserver& aObserver)
+:	CActive(CActive::EPriorityStandard),
+	iObserver(aObserver)
+	{
+	LOG_FUNC
+
+	CActiveScheduler::Add(this);
+	}
+
+CActiveWaitForEComEvent::~CActiveWaitForEComEvent()
+	{
+	LOG_FUNC
+	Cancel();
+	iEComSession.Close();
+	REComSession::FinalClose();
+	}
+
+CActiveWaitForEComEvent* CActiveWaitForEComEvent::NewL(MEComEventObserver& aObserver)
+	{
+	CActiveWaitForEComEvent* self = new(ELeave) CActiveWaitForEComEvent(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+void CActiveWaitForEComEvent::ConstructL()
+	{
+	iEComSession = REComSession::OpenL();
+	}
+
+void CActiveWaitForEComEvent::Wait()
+	{
+	LOG_FUNC
+	iEComSession.NotifyOnChange(iStatus);
+	SetActive();
+	}
+
+void CActiveWaitForEComEvent::RunL()
+	{
+	LOG_LINE
+	LOG_FUNC
+	iObserver.EComEventReceived();
+	Wait();
+	}
+
+void CActiveWaitForEComEvent::DoCancel()
+	{
+	LOG_FUNC
+	iEComSession.CancelNotifyOnChange(iStatus);
+	}
+
+TInt CActiveWaitForEComEvent::RunError(TInt aError)
+	{
+	LOG_LINE
+	LOG_FUNC
+	LOGTEXT2(_L8("ECOM change notification error = %d "), aError);
+	__ASSERT_DEBUG(EFalse, _USB_PANIC(KFdfEcomEventAOPanicCategory, aError));
+	return KErrNone;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/src/deviceproxy.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,444 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include "deviceproxy.h"
+#include <usb/usblogger.h>
+#include <usbhostdefs.h>
+#include "utils.h"
+#include "event.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdf      ");
+#endif
+
+#ifdef _DEBUG
+PANICCATEGORY("devproxy");
+#endif
+
+#ifdef __FLOG_ACTIVE
+#define LOG Log()
+#else
+#define LOG
+#endif
+
+CDeviceProxy* CDeviceProxy::NewL(RUsbHubDriver& aHubDriver, TUint aDeviceId)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CDeviceProxy* self = new(ELeave) CDeviceProxy(aDeviceId);
+	CleanupStack::PushL(self);
+	self->ConstructL(aHubDriver);
+	CLEANUPSTACK_POP1(self);
+	return self;
+	}
+
+CDeviceProxy::CDeviceProxy(TUint aDeviceId)
+:	iId(aDeviceId)
+	{
+	LOG_FUNC
+	}
+
+void CDeviceProxy::ConstructL(RUsbHubDriver& aHubDriver)
+	{
+	LOG_FUNC
+
+	LEAVEIFERRORL(iHandle.Open(aHubDriver, iId));
+
+	// Pre-allocate objects relating to this device for the event queue.
+	iAttachmentEvent = new(ELeave) TDeviceEvent;
+	iAttachmentEvent->iInfo.iEventType = EDeviceAttachment;
+	iAttachmentEvent->iInfo.iDeviceId = iId;
+
+	iDriverLoadingEvent = new(ELeave) TDeviceEvent;
+	iDriverLoadingEvent->iInfo.iEventType = EDriverLoad;
+	iDriverLoadingEvent->iInfo.iDeviceId = iId;
+
+	iDetachmentEvent = new(ELeave) TDeviceEvent;
+	iDetachmentEvent->iInfo.iEventType = EDeviceDetachment;
+	iDetachmentEvent->iInfo.iDeviceId = iId;
+	
+	ReadStringDescriptorsL();
+
+	LOG;
+	}
+
+void CDeviceProxy::ReadStringDescriptorsL()
+	{
+	LOG_FUNC
+
+	// wait 10 ms before reading any string descriptors
+	// to avoid IOP issues with some USB devices (e.g. PNY Attache)
+	User::After(10000);
+
+	// First read string descriptor 0 (supported languages).
+	// For each supported language, read the manufacturer, product and serial
+	// number string descriptors (as supported). (These are not cached in
+	// USBD.)
+	// To look up these string descriptors we need to get the device
+	// descriptor. The device descriptor *is* cached in USBD, so we don't
+	// remember our own copy, even though it is queried later by the CFdf.
+
+	// '0' is the index of the string descriptor which holds the supported
+	// language IDs.
+	TBuf8<256> stringBuf;
+	TUsbStringDescriptor* stringDesc = NULL;
+	ASSERT_DEBUG(iHandle.Handle());
+	LEAVEIFERRORL(iHandle.GetStringDescriptor(stringDesc, stringBuf, 0));
+	CleanupStack::PushL(*stringDesc);
+
+	// Copy the language IDs into our array.
+	TUint index = 0;
+	TInt16 langId = stringDesc->GetLangId(index);
+	while ( langId != KErrNotFound )
+		{
+		LOGTEXT2(_L8("\tsupported language: 0x%04x"), langId);
+		iLangIds.AppendL(langId); // stored as TUint
+		++index;
+		langId = stringDesc->GetLangId(index);
+		}
+
+	CleanupStack::PopAndDestroy(stringDesc);
+
+	// Get the actual strings for each supported language.
+	TUsbDeviceDescriptor deviceDescriptor;
+	ASSERT_DEBUG(iHandle.Handle());
+	LEAVEIFERRORL(iHandle.GetDeviceDescriptor(deviceDescriptor));
+	TUint8 manufacturerStringDescriptorIndex = deviceDescriptor.ManufacturerIndex();
+	TUint8 productStringDescriptorIndex = deviceDescriptor.ProductIndex();
+	TUint8 serialNumberStringDescriptorIndex = deviceDescriptor.SerialNumberIndex();
+	PopulateStringDescriptorsL(manufacturerStringDescriptorIndex, iManufacturerStrings);
+	PopulateStringDescriptorsL(productStringDescriptorIndex, iProductStrings);
+	PopulateStringDescriptorsL(serialNumberStringDescriptorIndex, iSerialNumberStrings);
+	ASSERT_DEBUG(iManufacturerStrings.Count() == iLangIds.Count());
+	ASSERT_DEBUG(iProductStrings.Count() == iLangIds.Count());
+	ASSERT_DEBUG(iSerialNumberStrings.Count() == iLangIds.Count());
+	}
+
+// Populates the given array with the supported language variants of the given
+// string. Can only leave with KErrNoMemory, which fails instantiation of the
+// CDeviceProxy. (It is legal for instance for manufacturer strings to be
+// supported but serial number strings to *not* be.)
+void CDeviceProxy::PopulateStringDescriptorsL(TUint8 aStringDescriptorIndex, RArray<TName>& aStringArray)
+	{
+	LOG_FUNC
+
+	const TUint langCount = iLangIds.Count();
+	for ( TUint ii = 0 ; ii < langCount ; ++ii )
+		{
+		TName string;
+		TRAPD(err, GetStringDescriptorFromUsbdL(iLangIds[ii], string, aStringDescriptorIndex));
+		if ( err == KErrNotFound)
+			{
+			// Make sure the string is blanked before storing it.
+			string = KNullDesC();
+			}
+		else
+			{
+			LEAVEIFERRORL(err);
+			}
+
+		LEAVEIFERRORL(aStringArray.Append(string));
+		}
+	}
+
+CDeviceProxy::~CDeviceProxy()
+	{
+	LOG_FUNC
+	LOG;
+
+	// In the design, the event objects should all have had ownership taken
+	// onto the event queue by now. The owner of the device proxy is required
+	// to take ownership of these objects before destroying the proxy.
+	// However, we might hit the destructor due to an out-of-memory failure
+	// during construction, so we can't assert this, and we still have to
+	// destroy the objects.
+	delete iAttachmentEvent;
+	delete iDriverLoadingEvent;
+	delete iDetachmentEvent;
+	delete iOtgDescriptor;
+
+	iLangIds.Reset();
+	iManufacturerStrings.Reset();
+	iProductStrings.Reset();
+	iSerialNumberStrings.Reset();
+
+	iHandle.Close();
+	}
+
+TInt CDeviceProxy::GetDeviceDescriptor(TUsbDeviceDescriptor& aDescriptor)
+	{
+	LOG_FUNC
+
+	ASSERT_DEBUG(iHandle.Handle());
+	TInt err = iHandle.GetDeviceDescriptor(aDescriptor);
+
+	LOGTEXT2(_L8("\terr = %d"), err);
+	return err;
+	}
+
+TInt CDeviceProxy::GetConfigurationDescriptor(TUsbConfigurationDescriptor& aDescriptor) const
+	{
+	LOG_FUNC
+
+	ASSERT_DEBUG(iHandle.Handle());
+	TInt err = const_cast<RUsbDevice&>(iHandle).GetConfigurationDescriptor(aDescriptor);
+
+	LOGTEXT2(_L8("\terr = %d"), err);
+	return err;
+	}
+
+TInt CDeviceProxy::GetTokenForInterface(TUint aIndex, TUint32& aToken) const
+	{
+	LOG_FUNC
+
+	ASSERT_DEBUG(iHandle.Handle());
+	// We shouldn't need to worry about whether the device is suspended or
+	// resumed before doing this. This function is only called if we find FDs
+	// for the device, in which case we wouldn't have suspended it in the
+	// first place.
+	TInt err = const_cast<RUsbDevice&>(iHandle).GetTokenForInterface(aIndex, aToken);
+
+	LOGTEXT2(_L8("\terr = %d"), err);
+	return err;
+	}
+
+const RArray<TUint>& CDeviceProxy::GetSupportedLanguages() const
+	{
+	LOG_FUNC
+
+	return iLangIds;
+	}
+
+void CDeviceProxy::GetManufacturerStringDescriptorL(TUint32 aLangId, TName& aString) const
+	{
+	LOG_FUNC
+
+	GetStringDescriptorFromCacheL(aLangId, aString, iManufacturerStrings);
+	}
+
+void CDeviceProxy::GetProductStringDescriptorL(TUint32 aLangId, TName& aString) const
+	{
+	LOG_FUNC
+
+	GetStringDescriptorFromCacheL(aLangId, aString, iProductStrings);
+	}
+
+void CDeviceProxy::GetSerialNumberStringDescriptorL(TUint32 aLangId, TName& aString) const
+	{
+	LOG_FUNC
+
+	GetStringDescriptorFromCacheL(aLangId, aString, iSerialNumberStrings);
+	}
+
+void CDeviceProxy::GetOtgDescriptorL(TOtgDescriptor& aDescriptor) const
+	{
+	LOG_FUNC
+	
+	if (iOtgDescriptor)
+		{
+		aDescriptor = *iOtgDescriptor;
+		}
+	else
+		{
+		LEAVEL(KErrNotSupported);
+		}
+	}
+
+void CDeviceProxy::SetOtgDescriptorL(const TUsbOTGDescriptor& aDescriptor)
+	{
+	if (iOtgDescriptor)
+		{
+		delete iOtgDescriptor;
+		iOtgDescriptor = NULL;
+		}
+	iOtgDescriptor = new (ELeave) TOtgDescriptor();
+
+	iOtgDescriptor->iDeviceId = iId;
+	iOtgDescriptor->iAttributes = aDescriptor.Attributes();
+	}
+
+// Used during instantiation to read supported strings.
+void CDeviceProxy::GetStringDescriptorFromUsbdL(TUint32 aLangId, TName& aString, TUint8 aStringDescriptorIndex) const
+	{
+	LOG_FUNC
+	LOGTEXT3(_L8("\taLangId = 0x%04x, aStringDescriptorIndex = %d"), aLangId, aStringDescriptorIndex);
+
+	// If the string is not defined by the device, leave.
+	if ( aStringDescriptorIndex == 0 )
+		{
+		LEAVEL(KErrNotFound);
+		}
+
+	TBuf8<255> stringBuf;
+	TUsbStringDescriptor* stringDesc = NULL;
+	ASSERT_DEBUG(iHandle.Handle());
+	LEAVEIFERRORL(const_cast<RUsbDevice&>(iHandle).GetStringDescriptor(stringDesc, stringBuf, aStringDescriptorIndex, aLangId));
+	stringDesc->StringData(aString);
+	stringDesc->DestroyTree();
+	delete stringDesc;
+	LOGTEXT2(_L("\taString = \"%S\""), &aString);
+	}
+
+// Called indirectly by users of this class to query a string descriptor.
+void CDeviceProxy::GetStringDescriptorFromCacheL(TUint32 aLangId, TName& aString, const RArray<TName>& aStringArray) const
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taLangId = 0x%04x"), aLangId);
+
+	// If the lang ID is not supported by the device, leave. At the same time
+	// find the index of the required string in the given string array.
+	const TUint langCount = iLangIds.Count();
+	TUint index = 0;
+	for ( index = 0 ; index < langCount ; ++index )
+		{
+		if ( iLangIds[index] == aLangId )
+			{
+			break;
+			}
+		}
+	if ( index == langCount )
+		{
+		LEAVEL(KErrNotFound);
+		}
+
+	aString = aStringArray[index];
+	LOGTEXT2(_L("\taString = \"%S\""), &aString);
+	}
+
+TInt CDeviceProxy::Suspend()
+	{
+	LOG_FUNC
+
+	ASSERT_DEBUG(iHandle.Handle());
+	TInt ret = iHandle.Suspend();
+
+	LOGTEXT2(_L8("\tret = %d"), ret);
+	return ret;
+	}
+
+TUint CDeviceProxy::DeviceId() const
+	{
+	return iId;
+	}
+
+void CDeviceProxy::SetDriverLoadingEventData(TDriverLoadStatus aStatus, TInt aError)
+	{
+	LOG_FUNC
+	LOGTEXT3(_L8("\taStatus = %d, aError = %d"), aStatus, aError);
+
+	ASSERT_DEBUG(iDriverLoadingEvent);
+	iDriverLoadingEvent->iInfo.iDriverLoadStatus = aStatus;
+	iDriverLoadingEvent->iInfo.iError = aError;
+
+	LOG;
+	}
+
+TDeviceEvent* CDeviceProxy::GetAttachmentEventObject()
+	{
+	LOG_FUNC
+	LOG;
+
+	ASSERT_DEBUG(iAttachmentEvent);
+	TDeviceEvent* const obj = iAttachmentEvent;
+	iAttachmentEvent = NULL;
+	LOGTEXT2(_L8("\tobj = 0x%08x"), obj);
+	return obj;
+	}
+
+TDeviceEvent* CDeviceProxy::GetDriverLoadingEventObject()
+	{
+	LOG_FUNC
+	LOG;
+
+	ASSERT_DEBUG(iDriverLoadingEvent);
+	TDeviceEvent* const obj = iDriverLoadingEvent;
+	iDriverLoadingEvent = NULL;
+	LOGTEXT2(_L8("\tobj = 0x%08x"), obj);
+	return obj;
+	}
+
+TDeviceEvent* CDeviceProxy::GetDetachmentEventObject()
+	{
+	LOG_FUNC
+	LOG;
+
+	ASSERT_DEBUG(iDetachmentEvent);
+	TDeviceEvent* const obj = iDetachmentEvent;
+	iDetachmentEvent = NULL;
+	LOGTEXT2(_L8("\tobj = 0x%08x"), obj);
+	return obj;
+	}
+
+#ifdef __FLOG_ACTIVE
+
+void CDeviceProxy::Log()
+	{
+	LOG_FUNC
+
+	LOGTEXT2(_L8("\tiId = %d"), iId);
+	LOGTEXT2(_L8("\tiHandle.Handle() = %d"), iHandle.Handle());
+	if ( iAttachmentEvent )
+		{
+		LOGTEXT(_L8("\tlogging iAttachmentEvent"));
+		iAttachmentEvent->Log();
+		}
+	if ( iDriverLoadingEvent )
+		{
+		LOGTEXT(_L8("\tlogging iDriverLoadingEvent"));
+		iDriverLoadingEvent->Log();
+		}
+	if ( iDetachmentEvent )
+		{
+		LOGTEXT(_L8("\tlogging iDetachmentEvent"));
+		iDetachmentEvent->Log();
+		}
+	const TUint langCount = iLangIds.Count();
+	const TUint manufacturerCount = iManufacturerStrings.Count();
+	const TUint productCount = iProductStrings.Count();
+	const TUint serialNumberCount = iSerialNumberStrings.Count();
+
+	// from the code below we can see that some protection have been added
+	// if(ii<manufacturerCount) etc...
+	// This has been done to protect in case there have been an incomplete construction etc..
+	// when logging the data
+
+	LOGTEXT2(_L8("\tlangCount = %d"), langCount);
+	for ( TUint ii = 0 ; ii < langCount ; ++ii )
+		{
+		LOGTEXT2(_L("\tlang ID 0x%04x:"), iLangIds[ii]);
+		if(ii<manufacturerCount)
+			{
+			LOGTEXT2(_L("\t\tmanufacturer string: \"%S\""), &iManufacturerStrings[ii]);
+			}
+		if(ii<productCount)
+			{
+			LOGTEXT2(_L("\t\tproduct string: \"%S\""), &iProductStrings[ii]);
+			}
+		if(ii<serialNumberCount)
+			{
+			LOGTEXT2(_L("\t\tserial number string: \"%S\""), &iSerialNumberStrings[ii]);
+			}
+
+		}
+	}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/src/event.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,65 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "event.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdf      ");
+#endif
+
+TDeviceEvent::TDeviceEvent()
+	{
+	LOG_FUNC
+	}
+
+TDeviceEvent::~TDeviceEvent()
+	{
+	LOG_FUNC
+	}
+
+#ifdef __FLOG_ACTIVE
+
+void TDeviceEvent::Log() const
+	{
+	LOGTEXT2(_L8("\tLogging event 0x%08x"), this);
+	LOGTEXT2(_L8("\t\tdevice ID = %d"), iInfo.iDeviceId);
+	LOGTEXT2(_L8("\t\tevent type = %d"), iInfo.iEventType);
+
+	switch ( iInfo.iEventType )
+		{
+	case EDeviceAttachment:
+		LOGTEXT2(_L8("\t\terror = %d"), iInfo.iError);
+		if ( !iInfo.iError )
+			{
+			LOGTEXT2(_L8("\t\tVID = 0x%04x"), iInfo.iVid);
+			LOGTEXT2(_L8("\t\tPID = 0x%04x"), iInfo.iPid);
+			}
+		break;
+
+	case EDriverLoad:
+		LOGTEXT2(_L8("\t\terror = %d"), iInfo.iError);
+		LOGTEXT2(_L8("\t\t\tdriver load status = %d"), iInfo.iDriverLoadStatus);
+		break;
+
+	case EDeviceDetachment: // No break deliberate.
+	default:
+		break;
+		}
+	}
+
+#endif // __FLOG_ACTIVE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/src/eventqueue.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,403 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "eventqueue.h"
+#include <usb/usblogger.h>
+#include "fdf.h"
+#include "fdfsession.h"
+#include "utils.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdf      ");
+#endif
+
+#ifdef __FLOG_ACTIVE
+#define LOG Log()
+#else
+#define LOG
+#endif
+
+#ifdef _DEBUG
+PANICCATEGORY("eventq");
+#endif
+
+class CFdfSession;
+
+CEventQueue* CEventQueue::NewL(CFdf& aFdf)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CEventQueue* self = new(ELeave) CEventQueue(aFdf);
+	return self;
+	}
+
+CEventQueue::CEventQueue(CFdf& aFdf)
+:	iFdf(aFdf),
+	iDeviceEvents(_FOFF(TDeviceEvent, iLink))
+	{
+	LOG_FUNC
+	}
+
+CEventQueue::~CEventQueue()
+	{
+	LOG_FUNC
+
+	// There will be things left on the queue at this time if USBMAN shuts us
+	// down without having picked up everything that was on the queue.
+	// This is valid behaviour and these events need destroying now.
+	TSglQueIter<TDeviceEvent> iter(iDeviceEvents);
+	iter.SetToFirst();
+	TDeviceEvent* event;
+	while ( ( event = iter++ ) != NULL )
+		{
+		delete event;
+		}
+	}
+
+// Increments the count of failed attachments.
+void CEventQueue::AttachmentFailure(TInt aError)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taError = %d"), aError);
+	LOG;
+
+	TUint index = 0;
+	switch ( aError )
+		{
+	case KErrUsbSetAddrFailed:
+		index = KSetAddrFailed;
+		break;
+	case KErrUsbNoPower:
+		index = KNoPower;
+		break;
+	case KErrBadPower:
+		index = KBadPower;
+		break;
+	case KErrUsbIOError:
+		index = KIOError;
+		break;
+	case KErrUsbTimeout:
+		index = KTimeout;
+		break;
+	case KErrUsbStalled:
+		index = KStalled;
+		break;
+	case KErrNoMemory:
+		index = KNoMemory;
+		break;
+	case KErrUsbConfigurationHasNoInterfaces:
+		index = KConfigurationHasNoInterfaces;
+		break;
+	case KErrUsbInterfaceCountMismatch:
+		index = KInterfaceCountMismatch;
+		break;
+	case KErrUsbDuplicateInterfaceNumbers:
+		index = KDuplicateInterfaceNumbers;
+		break;
+	case KErrBadHandle:
+		index = KBadHandle;
+		break;
+
+	default:
+		// we must deal with every error we are ever given
+		LOGTEXT2(_L8("\tFDF did not expect this error %d as a fail attachment"), aError);
+		index = KAttachmentFailureGeneralError;
+		break;
+		}
+	++(iAttachmentFailureCount[index]);
+
+	PokeSession();
+	LOG;
+	}
+
+// Called to add an event to the tail of the queue.
+// Takes ownership of aEvent.
+void CEventQueue::AddDeviceEvent(TDeviceEvent& aEvent)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\t&aEvent = 0x%08x"), &aEvent);
+	LOG;
+
+	iDeviceEvents.AddLast(aEvent);
+
+	PokeSession();
+	LOG;
+	}
+
+// Poke the session object (if it exists) to complete any outstanding event
+// notifications it has.
+// It only makes sense to call this function if there's some event to give up.
+void CEventQueue::PokeSession()
+	{
+	LOG_FUNC
+
+	// If the session exists, and has a notification outstanding, give them
+	// the head event.
+	CFdfSession* sess = iFdf.Session();
+	if ( sess )
+		{
+		if ( sess->NotifyDevmonEventOutstanding() )
+			{
+			TInt event;
+			if ( GetDevmonEvent(event) )
+				{
+				sess->DevmonEvent(event);
+				}
+			}
+		if ( sess->NotifyDeviceEventOutstanding() )
+			{
+			TDeviceEvent event;
+			if ( GetDeviceEvent(event) )
+				{
+				sess->DeviceEvent(event);
+				}
+			}
+		}
+	}
+
+// This is called to get a device event. Attachment failures are given up
+// before actual queued events.
+// If ETrue is returned, the queued event is destroyed and a copy is delivered
+// in aEvent.
+TBool CEventQueue::GetDeviceEvent(TDeviceEvent& aEvent)
+	{
+	LOG_FUNC
+	LOG;
+
+	TBool ret = EFalse;
+
+	// We need to see if any attachment failures have been collected by us. If
+	// there have, report exactly one of them to the client.
+	for ( TUint ii = 0 ; ii < KNumberOfAttachmentFailureTypes ; ++ii )
+		{
+		TUint& errorCount = iAttachmentFailureCount[ii];
+		if ( errorCount )
+			{
+			--errorCount;
+			switch ( ii )
+				{
+			case KSetAddrFailed:
+				aEvent.iInfo.iError = KErrUsbSetAddrFailed;
+				break;
+			case KNoPower:
+				aEvent.iInfo.iError = KErrUsbNoPower;
+				break;
+			case KBadPower:
+				aEvent.iInfo.iError = KErrBadPower;
+				break;
+			case KIOError:
+				aEvent.iInfo.iError = KErrUsbIOError;
+				break;
+			case KTimeout:
+				aEvent.iInfo.iError = KErrUsbTimeout;
+				break;
+			case KStalled:
+				aEvent.iInfo.iError = KErrUsbStalled;
+				break;
+			case KNoMemory:
+				aEvent.iInfo.iError = KErrNoMemory;
+				break;
+			case KConfigurationHasNoInterfaces:
+				aEvent.iInfo.iError = KErrUsbConfigurationHasNoInterfaces;
+				break;
+			case KInterfaceCountMismatch:
+				aEvent.iInfo.iError = KErrUsbInterfaceCountMismatch;
+				break;
+			case KDuplicateInterfaceNumbers:
+				aEvent.iInfo.iError = KErrUsbDuplicateInterfaceNumbers;
+				break;
+			case KBadHandle:
+				aEvent.iInfo.iError = KErrBadHandle;
+				break;
+			case KAttachmentFailureGeneralError:
+				aEvent.iInfo.iError = KErrUsbAttachmentFailureGeneralError;
+				break;
+
+			case KNumberOfAttachmentFailureTypes:
+			default:
+				// this switch should deal with every error type we store
+				ASSERT_DEBUG(0);
+
+				}
+
+			ret = ETrue;
+			aEvent.iInfo.iEventType = EDeviceAttachment;
+			LOGTEXT2(_L8("\treturning attachment failure event (code %d)"), aEvent.iInfo.iError);
+			// Only give the client one error at a time.
+			break;
+			}
+		}
+
+	if ( !ret && !iDeviceEvents.IsEmpty() )
+		{
+		TDeviceEvent* const event = iDeviceEvents.First();
+		LOGTEXT2(_L8("\tevent = 0x%08x"), event);
+		iDeviceEvents.Remove(*event);
+		(void)Mem::Copy(&aEvent, event, sizeof(TDeviceEvent));
+		delete event;
+		ret = ETrue;
+		}
+
+	LOG;
+	LOGTEXT2(_L8("\treturning %d"), ret);
+	return ret;
+	}
+
+TBool CEventQueue::GetDevmonEvent(TInt& aEvent)
+	{
+	LOG_FUNC
+	LOG;
+
+	TBool ret = EFalse;
+
+	for ( TUint ii = 0 ; ii < KNumberOfDevmonEventTypes ; ++ii )
+		{
+		TUint& eventCount = iDevmonEventCount[ii];
+		if ( eventCount )
+			{
+			--eventCount;
+			switch ( ii )
+				{
+
+			case KUsbDeviceRejected:
+				aEvent = KErrUsbDeviceRejected;
+				break;
+			case KUsbDeviceFailed:
+				aEvent = KErrUsbDeviceFailed;
+				break;
+			case KUsbBadDevice:
+				aEvent = KErrUsbBadDevice;
+				break;
+			case KUsbBadHubPosition:
+				aEvent = KErrUsbBadHubPosition;
+				break;
+			case KUsbBadHub:
+				aEvent = KErrUsbBadHub;
+				break;
+			case KUsbEventOverflow:
+				aEvent = KErrUsbEventOverflow;
+				break;
+			case KUsbBadDeviceAttached:
+			    aEvent = KErrUsbBadDeviceAttached;
+			    break;
+			case KUsbBadDeviceDetached:
+			    aEvent = KEventUsbBadDeviceDetached;
+			    break;
+			case KNumberOfDevmonEventTypes:
+			default:
+				LOGTEXT2(_L8("\tUnexpected devmon error, not handled properly %d"), ii);
+				ASSERT_DEBUG(0);
+				aEvent = KErrUsbDeviceRejected;
+				// this switch should deal with every error type we store
+				}
+
+			ret = ETrue;
+			// Only give the client one error at a time.
+			break;
+			}
+		}
+
+	LOG;
+	LOGTEXT2(_L8("\treturning %d"), ret);
+	return ret;
+	}
+
+void CEventQueue::AddDevmonEvent(TInt aEvent)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taEvent = %d"), aEvent);
+
+	// Increment the relevant count.
+	TInt index = 0;
+	switch ( aEvent )
+		{
+
+		case KErrUsbDeviceRejected:
+			index = KUsbDeviceRejected;
+			break;
+		case KErrUsbDeviceFailed:
+			index = KUsbDeviceFailed;
+			break;
+		case KErrUsbBadDevice:
+			index = KUsbBadDevice;
+			break;
+		case KErrUsbBadHubPosition:
+			index = KUsbBadHubPosition;
+			break;
+		case KErrUsbBadHub:
+			index = KUsbBadHub;
+			break;
+		case KErrUsbEventOverflow:
+			index = KUsbEventOverflow;
+			break;
+        case KErrUsbBadDeviceAttached:
+            index = KUsbBadDeviceAttached;
+            break;
+        case KEventUsbBadDeviceDetached:
+            index = KUsbBadDeviceDetached;
+            break;			
+
+		default:
+			LOGTEXT2(_L8("\tUnexpected devmon error, not handled properly %d"), aEvent);
+			ASSERT_DEBUG(0);
+			// this switch should deal with every type of event we ever receive from devmon
+			}
+
+	TUint& eventCount = iDevmonEventCount[index];
+	ASSERT_DEBUG(eventCount < KMaxTUint);
+	++eventCount;
+	PokeSession();
+	}
+
+#ifdef __FLOG_ACTIVE
+
+void CEventQueue::Log()
+	{
+	LOG_FUNC
+
+	for ( TUint ii = 0 ; ii < KNumberOfAttachmentFailureTypes ; ++ii )
+		{
+		const TInt& errorCount = iAttachmentFailureCount[ii];
+		if ( errorCount )
+			{
+			LOGTEXT3(_L8("\tNumber of attachment failures of type %d is %d"), ii, errorCount);
+			}
+		}
+
+	for ( TUint ii = 0 ; ii < KNumberOfDevmonEventTypes ; ++ii )
+		{
+		const TInt& eventCount = iDevmonEventCount[ii];
+		if ( eventCount )
+			{
+			LOGTEXT3(_L8("\tNumber of devmon events of type %d is %d"), ii, eventCount);
+			}
+		}
+
+	TUint pos = 0;
+	TSglQueIter<TDeviceEvent> iter(iDeviceEvents);
+	iter.SetToFirst();
+	TDeviceEvent* event;
+	while ( ( event = iter++ ) != NULL )
+		{
+		LOGTEXT2(_L8("\tLogging event at position %d"), pos);
+		event->Log();
+		++pos;
+		}
+	}
+
+#endif // __FLOG_ACTIVE
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/src/fdcproxy.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,497 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include "fdcproxy.h"
+#include <ecom/ecom.h>
+#include "utils.h"
+#include <usbhost/internal/fdcplugin.h>
+#include <usbhost/internal/fdcinterface.h>
+#include "fdf.h"
+#include "utils.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdf      ");
+#endif
+
+#ifdef __FLOG_ACTIVE
+#define LOG	Log()
+#else
+#define LOG
+#endif
+
+#ifdef _DEBUG
+#define INVARIANT Invariant()
+#else
+#define INVARIANT
+#endif
+
+PANICCATEGORY("fdcproxy");
+
+
+
+CFdcProxy* CFdcProxy::NewL(CFdf& aFdf, CImplementationInformation& aImplInfo)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CFdcProxy* self = new(ELeave) CFdcProxy(aFdf);
+	CleanupStack::PushL(self);
+	self->ConstructL(aImplInfo);
+#ifdef __FLOG_ACTIVE
+	self->INVARIANT;
+#endif
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+void CFdcProxy::ConstructL(CImplementationInformation& aImplInfo)
+	{
+	LOG_FUNC
+	
+	LOGTEXT2(_L8("\t\tFDC implementation UID: 0x%08x"), aImplInfo.ImplementationUid());
+	LOGTEXT2(_L("\t\tFDC display name: \"%S\""), &aImplInfo.DisplayName());
+	LOGTEXT2(_L8("\t\tFDC default_data: \"%S\""), &aImplInfo.DataType());
+	LOGTEXT2(_L8("\t\tFDC version: %d"), aImplInfo.Version());
+	LOGTEXT2(_L8("\t\tFDC disabled: %d"), aImplInfo.Disabled());
+	TDriveName drvName = aImplInfo.Drive().Name();
+ 	LOGTEXT2(_L8("\t\tFDC drive: %S"), &drvName);
+	LOGTEXT2(_L8("\t\tFDC rom only: %d"), aImplInfo.RomOnly());
+	LOGTEXT2(_L8("\t\tFDC rom based: %d"), aImplInfo.RomBased());
+	LOGTEXT2(_L8("\t\tFDC vendor ID: %08x"), (TUint32)aImplInfo.VendorId());
+		
+	// Before PREQ2080 a reference to the CImplementationInformation object was held. This is no longer
+	// possible because as soon as REComSession::ListImplementations() is called the reference will be
+	// invalid.		
+	iImplementationUid = aImplInfo.ImplementationUid();
+	iVersion = aImplInfo.Version();
+	iDefaultData.CreateL(aImplInfo.DataType());
+	iRomBased = aImplInfo.RomBased();
+	}
+
+CFdcProxy::CFdcProxy(CFdf& aFdf)
+:	iFdf(aFdf),
+	i0thInterface(-1) // -1 means unassigned
+	{
+	LOG_FUNC
+	}
+
+
+CFdcProxy::~CFdcProxy()
+	{
+	LOG_FUNC
+	INVARIANT;
+
+	// Only executed when the FDF is finally shutting down.
+	// By this time detachment of all devices should have been signalled to
+	// all FDCs and the FDC plugins should have been cleaned up.
+	// If is safe to assert this because iPlugin and iDeviceIds are not
+	// allocated on construction so this doesn't have to safe against partial
+	// construction.
+	ASSERT_DEBUG(!iPlugin);
+	ASSERT_DEBUG(iDeviceIds.Count() == 0);
+	iDeviceIds.Close();
+	iDefaultData.Close();
+
+	INVARIANT;
+	}
+
+
+TInt CFdcProxy::NewFunction(TUint aDeviceId,
+		const RArray<TUint>& aInterfaces,
+		const TUsbDeviceDescriptor& aDeviceDescriptor,
+		const TUsbConfigurationDescriptor& aConfigurationDescriptor)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taDeviceId = %d"), aDeviceId);
+	INVARIANT;
+
+	// Create a plugin object if required, call Mfi1NewFunction on it, and
+	// update our iDeviceIds.
+	TRAPD(err, NewFunctionL(aDeviceId, aInterfaces, aDeviceDescriptor, aConfigurationDescriptor));
+	INVARIANT;
+	LOGTEXT2(_L8("\terr = %d"), err);
+	return err;
+	}
+
+
+void CFdcProxy::NewFunctionL(TUint aDeviceId,
+		const RArray<TUint>& aInterfaces,
+		const TUsbDeviceDescriptor& aDeviceDescriptor,
+		const TUsbConfigurationDescriptor& aConfigurationDescriptor)
+	{
+	LOG_FUNC
+
+	// We may already have aDeviceId in our collection of device IDs, if the
+	// device is offering multiple Functions of the same type. In this case we
+	// don't want to add the device ID again.
+	// If we already know about this device, then we should definitely have
+	// already made iPlugin- this is checked in the invariant.
+	// However, if we don't know this device, we may still already have made
+	// iPlugin, to handle some other device. So we have to do some logic
+	// around creating the objects we need.
+
+	TBool alreadyKnowThisDevice = EFalse;
+	const TUint count = iDeviceIds.Count();
+	for ( TUint ii = 0 ; ii < count ; ++ii )
+		{
+		if ( iDeviceIds[ii] == aDeviceId )
+			{
+			alreadyKnowThisDevice = ETrue;
+			break;
+			}
+		}
+	LOGTEXT2(_L8("\talreadyKnowThisDevice = %d"), alreadyKnowThisDevice);
+
+	TArrayRemove arrayRemove(iDeviceIds, aDeviceId);
+	if ( !alreadyKnowThisDevice )
+		{
+		// We add the device ID to our array first because it's failable.
+		// Logically, it should be done *after* we call Mfi1NewFunction on the
+		// plugin, but we can't have the failable step of adding the device ID
+		// to the array after telling the FDC.
+		LEAVEIFERRORL(iDeviceIds.Append(aDeviceId));
+		// This cleanup item removes aDeviceId from iDeviceIds on a leave.
+		CleanupRemovePushL(arrayRemove);
+		}
+
+	TBool neededToMakePlugin = EFalse;
+	CFdcPlugin* plugin = iPlugin;
+	MFdcInterfaceV1* iface = iInterface;
+	if ( !plugin )
+		{
+		neededToMakePlugin = ETrue;
+		LOGTEXT2(_L8("\t\tFDC implementation UID: 0x%08x"), iImplementationUid);
+		plugin = CFdcPlugin::NewL(iImplementationUid, *this);
+		CleanupStack::PushL(plugin);
+		iface = reinterpret_cast<MFdcInterfaceV1*>(plugin->GetInterface(TUid::Uid(KFdcInterfaceV1)));
+		}
+	ASSERT_DEBUG(iface);
+	TInt err = KErrNone;
+
+	// Log the interfaces they're being offered.
+#ifdef __FLOG_ACTIVE
+	const TUint ifCount = aInterfaces.Count();
+	LOGTEXT2(_L8("\toffering %d interfaces:"), ifCount);
+	for ( TUint ii = 0 ; ii < ifCount ; ++ii )
+		{
+		LOGTEXT2(_L8("\t\tinterface %d"), aInterfaces[ii]);
+		}
+#endif
+
+	iInMfi1NewFunction = ETrue;
+	// Check that the FDC always claims the 0th interface.
+	ASSERT_DEBUG(i0thInterface == -1);
+	i0thInterface = aInterfaces[0];
+	err = iface->Mfi1NewFunction(   aDeviceId,
+									aInterfaces.Array(), // actually pass them a TArray for const access
+									aDeviceDescriptor,
+									aConfigurationDescriptor);
+	LOGTEXT2(_L8("\terr = %d"), err);
+	iInMfi1NewFunction = EFalse;
+	// The implementation of Mfi1NewFunction may not leave.
+//	ASSERT_ALWAYS(leave_err == KErrNone);
+	// This is set back to -1 when the FDC claims the 0th interface.
+	ASSERT_DEBUG(i0thInterface == -1);
+
+	// If this leaves, then:
+	// (a) aDeviceId will be removed from iDeviceIds (if we needed to add it).
+	// (b) the FDF will get the leave code.
+	// If this doesn't leave, then iPlugin, iInterface and iDeviceIds are
+	// populated OK and the FDF will get KErrNone.
+	LEAVEIFERRORL(err);
+
+	if ( neededToMakePlugin )
+		{
+		CLEANUPSTACK_POP1(plugin);
+		// Now everything failable has been done we can assign iPlugin and
+		// iInterface.
+		ASSERT_DEBUG(plugin);
+		ASSERT_DEBUG(iface);
+		iPlugin = plugin;
+		iInterface = iface;
+		}
+	if ( !alreadyKnowThisDevice )
+		{
+		CLEANUPSTACK_POP1(&arrayRemove);
+		}
+	}
+
+
+// Called by the FDF whenever a device is detached.
+// We check if the device is relevant to us. If it is, we signal its
+// detachment to the plugin.
+void CFdcProxy::DeviceDetached(TUint aDeviceId)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taDeviceId = %d"), aDeviceId);
+	INVARIANT;
+	
+	const TUint count = iDeviceIds.Count();
+	for ( TUint ii = 0 ; ii < count ; ++ii )
+		{
+		if ( iDeviceIds[ii] == aDeviceId )
+			{
+			LOGTEXT(_L8("\tmatching device id- calling Mfi1DeviceDetached!"));
+			ASSERT_DEBUG(iInterface);
+			iInterface->Mfi1DeviceDetached(aDeviceId);
+			// The implementation of Mfi1DeviceDetached may not leave.
+//			ASSERT_ALWAYS(err == KErrNone);
+			iDeviceIds.Remove(ii);
+			break;
+			}
+		}
+
+	LOGTEXT2(_L8("\tiDeviceIds.Count() = %d"), iDeviceIds.Count());
+	if ( iDeviceIds.Count() == 0 )
+		{
+		delete iPlugin;
+		iPlugin = NULL;
+		iInterface = NULL;
+		
+		// If an FDC was loaded and then unloaded and an upgrade of the FDC installed then when the FDC is
+		// loaded again ECom will load the original version and not the new version unless we do a FinalClose()
+		// to release cached handles
+#pragma message("ECom defect DEF122443 raised")		
+		REComSession::FinalClose(); 
+		}
+
+	INVARIANT;
+	}
+
+
+#ifdef _DEBUG
+void CFdcProxy::Invariant() const
+	{
+	// If the class invariant fails hopefully it will be clear why from
+	// inspection of this object dump.
+	LOG;
+
+	// Either these are all 0 or none of them are:
+	// iDeviceIds.Count, iPlugin, iInterface
+	
+	ASSERT_DEBUG(
+					(
+						iDeviceIds.Count() != 0 && iPlugin && iInterface
+					)
+				||
+					(
+						iDeviceIds.Count() == 0 && !iPlugin && !iInterface
+					)
+		);
+
+	// Each device ID appears only once in the device ID array.
+	const TUint count = iDeviceIds.Count();
+	for ( TUint ii = 0 ; ii < count ; ++ii )
+		{
+		for ( TUint jj = ii+1 ; jj < count ; ++jj )
+			{
+			ASSERT_DEBUG(iDeviceIds[ii] != iDeviceIds[jj]);
+			}
+		}
+	}
+
+
+void CFdcProxy::Log() const
+	{
+	LOGTEXT2(_L8("\tLogging CFdcProxy 0x%08x:"), this);
+	const TUint count = iDeviceIds.Count();
+	LOGTEXT2(_L8("\t\tiDeviceIds.Count() = %d"), count);
+	for ( TUint i = 0 ; i < count ; ++i )
+		{
+		LOGTEXT3(_L8("\t\t\tiDeviceIds[%d] = %d"), i, iDeviceIds[i]);
+		}
+	LOGTEXT2(_L8("\t\tiPlugin = 0x%08x"), iPlugin);
+	LOGTEXT2(_L8("\t\tiInterface = 0x%08x"), iInterface);
+	}
+#endif // _DEBUG
+
+
+const TDesC8& CFdcProxy::DefaultDataField() const
+	{
+	return iDefaultData;
+	}
+
+TUid CFdcProxy::ImplUid() const
+	{
+	return iImplementationUid;
+	}
+	
+TInt CFdcProxy::Version() const
+	{
+	return iVersion;
+	}	
+	
+	
+TInt CFdcProxy::DeviceCount() const
+	{
+	return iDeviceIds.Count();
+	}
+	
+	
+// If a FD has been uninstalled from the device then its proxy needs to be deleted from the proxy list
+// maintained by the FDF. However if the FD is in use by an attached peripheral it can't be deleted 
+// until that device is removed. Hence this function marks it for deletion upon device detachment.
+// This situation will also occur if a FD upgrade is installed onto the device and the original FD (the one that
+// is being upgraded) is in use.	
+void CFdcProxy::MarkForDeletion()
+	{
+	iMarkedForDeletion = ETrue;
+	}	
+	
+	
+	
+// If a FD is installed and a device attached which uses it, then if while the device is still attached that FD is 
+// uninstalled then the FD proxy is marked for deletion when the device detaches. However in the situation where the
+// FD is re-installed while the device still remains attached then the FD proxy should not be deleted when the device
+// eventually detaches. Hence this function is to undo the mark for deletion that was placed upon the proxy when the FD
+// was uninstalled.	
+void CFdcProxy::UnmarkForDeletion()
+	{
+	iMarkedForDeletion = EFalse;
+	}	
+	
+	
+TBool CFdcProxy::MarkedForDeletion() const
+	{
+	return iMarkedForDeletion;
+	}
+	
+	
+TBool CFdcProxy::RomBased() const
+	{
+	return iRomBased;
+	}	
+	
+	
+TUint32 CFdcProxy::MfpoTokenForInterface(TUint8 aInterface)
+	{
+	LOG_FUNC
+
+	// This function must only be called from an implementation of
+	// Mfi1NewInterface.
+	ASSERT_ALWAYS(iInMfi1NewFunction);
+	// Support our check that the FDC claims the 0th interface.
+	if ( aInterface == i0thInterface )
+		{
+		i0thInterface = -1;
+		}
+
+	return iFdf.TokenForInterface(aInterface);
+	}
+
+
+const RArray<TUint>& CFdcProxy::MfpoGetSupportedLanguagesL(TUint aDeviceId)
+	{
+	LOG_FUNC
+
+	CheckDeviceIdL(aDeviceId);
+
+	return iFdf.GetSupportedLanguagesL(aDeviceId);
+	}
+
+
+TInt CFdcProxy::MfpoGetManufacturerStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
+	{
+	LOG_FUNC
+
+	TRAPD(err,
+		CheckDeviceIdL(aDeviceId);
+		iFdf.GetManufacturerStringDescriptorL(aDeviceId, aLangId, aString)
+		);
+
+#ifdef __FLOG_ACTIVE
+	if ( !err )
+		{
+		LOGTEXT2(_L("\taString = \"%S\""), &aString);
+		}
+#endif
+	LOGTEXT2(_L8("\terr = %d"), err);
+	return err;
+	}
+
+
+TInt CFdcProxy::MfpoGetProductStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
+	{
+	LOG_FUNC
+
+	TRAPD(err,
+		CheckDeviceIdL(aDeviceId);
+		iFdf.GetProductStringDescriptorL(aDeviceId, aLangId, aString)
+		);
+
+#ifdef __FLOG_ACTIVE
+	if ( !err )
+		{
+		LOGTEXT2(_L("\taString = \"%S\""), &aString);
+		}
+#endif
+	LOGTEXT2(_L8("\terr = %d"), err);
+	return err;
+	}
+
+
+TInt CFdcProxy::MfpoGetSerialNumberStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
+	{
+	LOG_FUNC
+
+	TRAPD(err,
+		CheckDeviceIdL(aDeviceId);
+		iFdf.GetSerialNumberStringDescriptorL(aDeviceId, aLangId, aString)
+		);
+
+#ifdef __FLOG_ACTIVE
+	if ( !err )
+		{
+		LOGTEXT2(_L("\taString = \"%S\""), &aString);
+		}
+#endif
+	LOGTEXT2(_L8("\terr = %d"), err);
+	return err;
+	}
+
+/**
+Leaves with KErrNotFound if aDeviceId is not on our array of device IDs.
+Used to ensure that FDCs can only request strings etc from devices that are
+'their business'.
+*/
+void CFdcProxy::CheckDeviceIdL(TUint aDeviceId) const
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taDeviceId = %d"), aDeviceId);
+
+	TBool found = EFalse;
+	const TUint count = iDeviceIds.Count();
+	for ( TUint i = 0 ; i < count ; ++i )
+		{
+		if ( iDeviceIds[i] == aDeviceId )
+			{
+			found = ETrue;
+			break;
+			}
+		}
+	if ( !found )
+		{
+		LEAVEL(KErrNotFound);
+		}
+	}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/src/fdf.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,1450 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include "fdf.h"
+#include <usb/usblogger.h>
+#include "utils.h"
+#include <usbhost/internal/fdcplugin.hrh>
+#include "eventqueue.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdf      ");
+#endif
+
+_LIT(KDriverUsbhubLddFileName,"usbhubdriver");
+_LIT(KDriverUsbdiLddFileName,"usbdi");
+
+PANICCATEGORY("fdf");
+
+const TUint KVendorSpecificDeviceClassValue = 0xFF;
+const TUint KVendorSpecificInterfaceClassValue = 0xFF;
+const TUint KMaxSearchKeyLength = 64; 
+
+// Factory function for TInterfaceInfo objects.
+CFdf::TInterfaceInfo* CFdf::TInterfaceInfo::NewL(RPointerArray<CFdf::TInterfaceInfo>& aInterfaces)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	TInterfaceInfo* self = new(ELeave) TInterfaceInfo;
+	CleanupStack::PushL(self);
+	aInterfaces.AppendL(self);
+	CLEANUPSTACK_POP1(self);
+	return self;
+	}
+
+
+CFdf* CFdf::NewL()
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CFdf* self = new(ELeave) CFdf;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CLEANUPSTACK_POP1(self);
+	return self;
+	}
+
+CFdf::CFdf()
+:	iDevices(_FOFF(CDeviceProxy, iLink)),
+	iFunctionDrivers(_FOFF(CFdcProxy, iLink))
+	{
+	LOG_FUNC
+	}
+
+void CFdf::ConstructL()
+	{
+	LOG_FUNC
+
+#ifndef __OVER_DUMMYUSBDI__
+	// If we're using the DummyUSBDI we don't need the real USBDI.
+	TInt err = User::LoadLogicalDevice(KDriverUsbhubLddFileName);
+	if ( err != KErrAlreadyExists )
+		{
+		LEAVEIFERRORL(err);
+		}
+#endif // __OVER_DUMMYUSBDI__
+
+	LEAVEIFERRORL(iHubDriver.Open());
+
+#ifdef __OVER_DUMMYUSBDI__
+	LEAVEIFERRORL(iHubDriver.StartHost());
+#endif
+
+	iActiveWaitForBusEvent = CActiveWaitForBusEvent::NewL(iHubDriver, iBusEvent, *this);
+	iActiveWaitForBusEvent->Wait();	
+		
+	CreateFunctionDriverProxiesL();	
+	
+	iActiveWaitForEComEvent = CActiveWaitForEComEvent::NewL(*this);
+	iActiveWaitForEComEvent->Wait();
+	
+	iEventQueue = CEventQueue::NewL(*this);
+	}
+
+void CFdf::CreateFunctionDriverProxiesL()
+	{
+
+	LOG_FUNC
+	REComSession::ListImplementationsL(TUid::Uid(KFdcEcomInterfaceUid), iImplInfoArray);
+	const TUint count = iImplInfoArray.Count();
+	LOGTEXT2(_L8("\tiImplInfoArray.Count() upon FDF creation  = %d"), count);
+#ifdef __FLOG_ACTIVE
+	if ( count == 0 )
+		{
+		LOGTEXT(_L8("\tTHERE ARE NO FUNCTION DRIVERS PRESENT IN THE SYSTEM"));
+		}
+	else
+		{
+		for (TInt kk = 0; kk < count; ++kk)
+			LOGTEXT3(_L8("\t\tFDC implementation Index:%d UID: 0x%08x"), kk, iImplInfoArray[kk]->ImplementationUid());				
+		}
+#endif
+
+   	for ( TUint i = 0 ; i < count ; ++i )
+   		{
+   		CFdcProxy* proxy = CFdcProxy::NewL(*this, *iImplInfoArray[i]);
+   		
+   		// If this proxy is rom based then put it in the first place
+   		// this will save time when trying to load the FDC with the rule of 
+   		// ROM-based ones have higher priority than installed ones.
+   		if (proxy->RomBased())
+   			iFunctionDrivers.AddFirst(*proxy);
+   		else
+   			iFunctionDrivers.AddLast(*proxy);
+   		}
+	}
+
+CFdf::~CFdf()
+	{
+	LOG_FUNC
+
+	// Mimic the detachment of each attached device.
+	TSglQueIter<CDeviceProxy> deviceIter(iDevices);
+	deviceIter.SetToFirst();
+	CDeviceProxy* device;
+	while ( ( device = deviceIter++ ) != NULL )
+		{
+		const TUint deviceId = device->DeviceId();
+		LOGTEXT2(_L8("\tmimicking detachment of device with id %d"), device);
+		TellFdcsOfDeviceDetachment(deviceId);
+		iDevices.Remove(*device);
+		delete device;
+		}
+
+	// Destroy all the FDC proxies. They should each now have no 'attached
+	// devices' and no plugin instance.
+	TSglQueIter<CFdcProxy> fdcIter(iFunctionDrivers);
+	fdcIter.SetToFirst();
+	CFdcProxy* fdc;
+	while ( ( fdc = fdcIter++ ) != NULL )
+		{
+		iFunctionDrivers.Remove(*fdc);
+		delete fdc;
+		}
+
+	delete iActiveWaitForBusEvent;
+	
+	delete iActiveWaitForEComEvent;
+
+	if ( iHubDriver.Handle() )
+		{
+		iHubDriver.StopHost(); // NB this has no return value
+		}
+	iHubDriver.Close();
+
+#ifndef __OVER_DUMMYUSBDI__
+	//If we're using the DummyUSBDI the real USBDI isn't loaded.
+	TInt err = User::FreeLogicalDevice(KDriverUsbhubLddFileName);
+	LOGTEXT2(_L8("\tFreeLogicalDevice( usbhubdriver ) returned %d"), err);
+	
+	err = User::FreeLogicalDevice(KDriverUsbdiLddFileName);
+	LOGTEXT2(_L8("\tFreeLogicalDevice( usbdi ) returned %d"), err);
+#endif // __OVER_DUMMYUSBDI__
+	
+	delete iEventQueue;
+
+	// This is a worthwhile check to do at this point. If we ever don't clean
+	// up iInterfaces at the *right* time, then this will be easier to debug
+	// than a memory leak.
+	ASSERT_DEBUG(iInterfaces.Count() == 0);
+
+	iImplInfoArray.ResetAndDestroy();
+	REComSession::FinalClose();
+	}
+
+void CFdf::EnableDriverLoading()
+	{
+	LOG_FUNC
+
+	iDriverLoadingEnabled = ETrue;
+	}
+
+void CFdf::DisableDriverLoading()
+	{
+	LOG_FUNC
+
+	iDriverLoadingEnabled = EFalse;
+	}
+
+void CFdf::SetSession(CFdfSession* aSession)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taSession = 0x%08x"), aSession);
+
+	iSession = aSession;
+	}
+
+CFdfSession* CFdf::Session()
+	{
+	return iSession;
+	}
+
+TBool CFdf::GetDeviceEvent(TDeviceEvent& aEvent)
+	{
+	LOG_FUNC
+
+	ASSERT_DEBUG(iEventQueue);
+	return iEventQueue->GetDeviceEvent(aEvent);
+	}
+
+TBool CFdf::GetDevmonEvent(TInt& aEvent)
+	{
+	LOG_FUNC
+
+	ASSERT_DEBUG(iEventQueue);
+	return iEventQueue->GetDevmonEvent(aEvent);
+	}
+	
+	
+// An ECom plugin has been installed or removed
+void CFdf::EComEventReceived()
+	{
+	TRAPD(ret, HandleEComEventReceivedL());
+	if (ret != KErrNone)
+		HandleDevmonEvent(KErrUsbUnableToUpdateFDProxyList);
+	
+	}
+
+void CFdf::HandleEComEventReceivedL()
+	{
+	LOG_FUNC
+	
+	// There is no way to filter ecom notification to only receive ones we are interested in, also there is no way
+	// to query ecom as to what has changed. Hence there is no option but to call ListImplementations().
+	iImplInfoArray.ResetAndDestroy();		
+			
+	REComSession::ListImplementationsL(TUid::Uid(KFdcEcomInterfaceUid), iImplInfoArray);	
+	TUint implementationsCount = iImplInfoArray.Count();
+	LOGTEXT2(_L8("\tiImplInfoArray.Count() after ECom notification= %d"), implementationsCount);
+	
+#ifdef __FLOG_ACTIVE
+	if ( implementationsCount == 0 )
+		{
+		LOGTEXT(_L8("\tTHERE ARE NO FUNCTION DRIVERS PRESENT IN THE SYSTEM"));
+		}
+		
+	TSglQueIter<CFdcProxy> proxiesIterDebug(iFunctionDrivers);
+	CFdcProxy* fdcDebug = NULL;		
+	while ( ( fdcDebug = proxiesIterDebug++ ) != NULL )
+		{
+		TUid fdcUid = fdcDebug->ImplUid();
+		LOGTEXT2(_L8("\t\tOld FDC Proxy implementation UID: 0x%08x"), fdcUid.iUid);
+		TInt fdcVersion = fdcDebug->Version();
+		LOGTEXT2(_L8("\t\tFDC Proxy version UID: %d"), fdcVersion);
+		}		
+	LOGTEXT(_L8("\t\t------------------------------------------------------------------"));
+	for (TInt kk = 0; kk < implementationsCount; ++kk)
+		{
+		TUid fdcUid2 = iImplInfoArray[kk]->ImplementationUid();
+		LOGTEXT2(_L8("\t\tNew FDC Proxy implementation UID: 0x%08x"), fdcUid2.iUid);
+		TInt fdcVersion2 = iImplInfoArray[kk]->Version();
+		LOGTEXT2(_L8("\t\tFDC Proxy version UID: %d"), fdcVersion2);					
+		}
+#endif
+
+	// See if any relevant FDCs (or upgrades) have been installed or uninstalled:	
+	
+	// For each FD in the proxy list compare the uid and version with each FD returned by ECom looking
+	// for the removal, upgrade or downgrade of an existing FD 	
+	TSglQueIter<CFdcProxy> proxiesIter(iFunctionDrivers);
+	proxiesIter.SetToFirst();
+	CFdcProxy* fdc = NULL;	
+	while ( ( fdc = proxiesIter++ ) != NULL )
+		{
+		TBool fdcRemoved = ETrue;
+		for (TInt ii = 0; ii < implementationsCount; ++ii)
+			{
+			if (fdc->ImplUid() == iImplInfoArray[ii]->ImplementationUid())
+				{			
+				// We have found an upgrade, downgrade, or duplicate (a duplicate could occur in the situation
+				// where an FD has been installed, then a device attached, then the FD uninstalled and re-installed *while*
+				// the device is still attached (meaning the FD's proxy is still in the proxy list but will have been marked
+				// for deletion when the uninstallation was detected).
+				fdcRemoved = EFalse;
+				if (fdc->Version() != iImplInfoArray[ii]->Version())
+					{
+					// We've found an upgrade or a downgrade. Note that the upgrade FD proxy needs adding to the
+					// proxy list, however that isn't done here it is done later in the loop that is searching for
+					// new FDs. This is to prevent its possible duplicate addition [consider the situation where
+					// there is FDv1 and a device is attached, then while still attached FDv2 gets installed (while will
+					// result in FDv1 getting marked for deletion), then another device is attached which will use FDv2.
+					// Now if FDv3 is installed before any of the devices were detached there will be two proxies in the 
+					// proxy list with the same UID but differing version numbers. If FDv3 is added here it will therefore
+					// be added twice].
+					if (fdc->DeviceCount())
+						{
+						// The device using the FD is still attached
+						fdc->MarkForDeletion();
+						}
+					else
+						{
+						iFunctionDrivers.Remove(*fdc);
+						delete fdc;
+						}					
+					}		
+				else
+					{
+					// we've found an FD being installed which is still currently 
+					// active in the proxy list
+					fdc->UnmarkForDeletion();
+					}	
+				// Since we found the plugin with the same implementationUid
+				// we could simply bail out to stop the looping;
+				break;
+				}
+			}
+		if (fdcRemoved)
+			{ 
+			// An FDC has been uninstalled - if the FDC isn't in use remove it 
+			// otherwise mark it for deletion
+			if (fdc->DeviceCount())
+				fdc->MarkForDeletion();
+			else
+				{
+				iFunctionDrivers.Remove(*fdc); 
+				delete fdc;				
+				}			
+			}
+		}
+		
+		
+	// For each FD returned by ECom, search and compare with the FD proxy list 
+	// looking for new FDs
+	for (TInt ii = 0; ii < implementationsCount; ++ii)
+		{
+		TBool newFdcFound = ETrue;
+		proxiesIter.SetToFirst();
+		while ( ( fdc = proxiesIter++ ) != NULL )
+			{
+			if (fdc->ImplUid() == iImplInfoArray[ii]->ImplementationUid() && fdc->Version() == iImplInfoArray[ii]->Version())
+				{
+				// No need to create a new proxy if there is one with a matching UID and version.
+				newFdcFound = EFalse;
+				
+				// We break out this loop for efficiency.
+				break;
+				}
+			}	
+			
+		if (newFdcFound)
+			{ 
+			// A new or upgrade FDC has been installed onto the device
+			CFdcProxy* proxy = CFdcProxy::NewL(*this, *iImplInfoArray[ii]);
+
+			// If this proxy is rom based then put it in the first place
+	   		// this will save time when trying to load the FDC with the rule that 
+	   		// ROM-based ones have higher priority than installed ones.
+			if (proxy->RomBased())
+				iFunctionDrivers.AddFirst(*proxy);
+			else
+				iFunctionDrivers.AddLast(*proxy);			
+			}
+		}
+	}
+
+// A bus event has occurred.
+void CFdf::MbeoBusEvent()
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\tiBusEvent.iEventType = %d"), iBusEvent.iEventType);
+	LOGTEXT2(_L8("\tiBusEvent.iError = %d"), iBusEvent.iError);
+	LOGTEXT2(_L8("\tiBusEvent.iDeviceHandle = %d"), iBusEvent.iDeviceHandle);
+
+	switch ( iBusEvent.iEventType )
+		{
+		case RUsbHubDriver::TBusEvent::EDeviceAttached:
+			if ( !iBusEvent.iError )
+				{
+				// So far, a successful attachment.
+				HandleDeviceAttachment(iBusEvent.iDeviceHandle);
+				}
+			else
+				{
+				// It was an attachment failure. Simply tell the event queue.
+				ASSERT_DEBUG(iEventQueue);
+				iEventQueue->AttachmentFailure(iBusEvent.iError);
+				}
+			break;
+	
+		case RUsbHubDriver::TBusEvent::EDeviceRemoved:
+			// Device detachments are always 'KErrNone'. If the device was
+			// pseudo-detached due to an overcurrent condition (for instance) then
+			// the overcurrent condition is indicated through the devmon API (i.e.
+			// EDevMonEvent) and the detachment is still 'KErrNone'.
+			ASSERT_DEBUG(iBusEvent.iError == KErrNone);
+			HandleDeviceDetachment(iBusEvent.iDeviceHandle);
+			break;
+	
+		case RUsbHubDriver::TBusEvent::EDevMonEvent:
+			HandleDevmonEvent(iBusEvent.iError);
+			break;
+	
+		case RUsbHubDriver::TBusEvent::ENoEvent:
+		default:
+		break;
+		}
+
+	// Only re-post the notification when we've finished examining the
+	// TBusEvent from the previous completion. (Otherwise it might get
+	// overwritten.)
+	iActiveWaitForBusEvent->Wait();
+	}
+
+// This is the central handler for device attachment.
+// We deal with device attachments in two phases.
+// The first phase is confusingly called device attachment.
+// The second phase is driver loading.
+void CFdf::HandleDeviceAttachment(TUint aDeviceId)
+	{
+	LOG_FUNC
+	// This is filled in by HandleDeviceAttachmentL on success.
+	CDeviceProxy* device;
+	TRAPD(err, HandleDeviceAttachmentL(aDeviceId, device));
+	if ( err )
+		{
+		LOGTEXT2(_L8("\terr = %d"), err);
+		// There was an attachment failure, so we just increment the count of
+		// attachment failures.
+		ASSERT_DEBUG(iEventQueue);
+		iEventQueue->AttachmentFailure(err);
+		// If we failed the attachment phase, we can't try to load drivers for
+		// the device.
+
+		}
+	else
+		{
+		// This function always moves the 'driver loading' event from the
+		// device proxy created by HandleDeviceAttachmentL to the event queue.
+		// This event object is always populated with the correct status and
+		// error.
+		ASSERT_DEBUG(device);
+		DoDriverLoading(*device);
+		}
+
+	// Finally, clean up the collection of information on the device's
+	// interfaces which was populated (maybe only partly) in
+	// HandleDeviceAttachmentL.
+	iCurrentDevice = NULL;
+	iInterfaces.ResetAndDestroy();
+	}
+
+// This does the 'device attachment' phase of the new device attachment only.
+void CFdf::HandleDeviceAttachmentL(TUint aDeviceId, CDeviceProxy*& aDevice)
+	{
+	LOG_FUNC
+
+	// Create the device proxy
+	aDevice = CDeviceProxy::NewL(iHubDriver, aDeviceId);
+	CleanupStack::PushL(aDevice);
+	iCurrentDevice = aDevice;
+	// Get necessary descriptors (for this phase)
+	LEAVEIFERRORL(aDevice->GetDeviceDescriptor(iDD));
+	LOGTEXT2(_L8("\tiDD.USBBcd = 0x%04x"), iDD.USBBcd());
+	LOGTEXT2(_L8("\tiDD.DeviceClass = 0x%02x"), iDD.DeviceClass());
+	LOGTEXT2(_L8("\tiDD.DeviceSubClass = 0x%02x"), iDD.DeviceSubClass());
+	LOGTEXT2(_L8("\tiDD.DeviceProtocol = 0x%02x"), iDD.DeviceProtocol());
+	LOGTEXT2(_L8("\tiDD.MaxPacketSize0 = %d"), iDD.MaxPacketSize0());
+	LOGTEXT2(_L8("\tiDD.VendorId = 0x%04x"), iDD.VendorId());
+	LOGTEXT2(_L8("\tiDD.ProductId = 0x%04x"), iDD.ProductId());
+	LOGTEXT2(_L8("\tiDD.DeviceBcd = 0x%04x"), iDD.DeviceBcd());
+	LOGTEXT2(_L8("\tiDD.ManufacturerIndex = %d"), iDD.ManufacturerIndex());
+	LOGTEXT2(_L8("\tiDD.ProductIndex = %d"), iDD.ProductIndex());
+	LOGTEXT2(_L8("\tiDD.SerialNumberIndex = %d"), iDD.SerialNumberIndex());
+	LOGTEXT2(_L8("\tiDD.NumConfigurations = %d"), iDD.NumConfigurations());
+	LEAVEIFERRORL(aDevice->GetConfigurationDescriptor(iCD));
+	LOGTEXT2(_L8("\tiCD.TotalLength = %d"), iCD.TotalLength());
+	LOGTEXT2(_L8("\tiCD.NumInterfaces = %d"), iCD.NumInterfaces());
+	LOGTEXT2(_L8("\tiCD.ConfigurationValue = %d"), iCD.ConfigurationValue());
+	LOGTEXT2(_L8("\tiCD.ConfigurationIndex = %d"), iCD.ConfigurationIndex());
+	LOGTEXT2(_L8("\tiCD.Attributes = %d"), iCD.Attributes());
+	LOGTEXT2(_L8("\tiCD.MaxPower = %d"), iCD.MaxPower());
+
+	const TUint8 numberOfInterfaces = iCD.NumInterfaces();
+	LOGTEXT2(_L8("\tnumberOfInterfaces (field in config descriptor) = %d)"), numberOfInterfaces);
+	if ( numberOfInterfaces == 0 )
+		{
+		LEAVEL(KErrUsbConfigurationHasNoInterfaces);
+		}
+
+	// Walk the configuration bundle. Collect information on each interface
+	// (its number, class, subclass and protocol). This populates iInterfaces.
+	ASSERT_DEBUG(iInterfaces.Count() == 0);
+	ASSERT_ALWAYS(iCurrentDevice);
+	ParseL(iCD);
+
+	// Log iInterfaces.
+	const TUint interfaceCount = iInterfaces.Count();
+	LOGTEXT2(_L8("\tinterfaceCount (parsed from bundle) = %d"), interfaceCount);
+#ifdef __FLOG_ACTIVE
+	LOGTEXT(_L8("\tLogging iInterfaces:"));
+	for ( TUint ii = 0 ; ii < interfaceCount ; ++ii )
+		{
+		const TInterfaceInfo* ifInfo = iInterfaces[ii];
+		ASSERT_DEBUG(ifInfo);
+		LOGTEXT6(_L8("\t\tiInterfaces[%d]: number %d, interface class 0x%02x subclass 0x%02x protocol 0x%02x"),
+			ii,
+			ifInfo->iNumber,
+			ifInfo->iClass,
+			ifInfo->iSubclass,
+			ifInfo->iProtocol
+			);
+		}
+#endif
+
+	// Check that the config's NumInterfaces is the same as the actual number
+	// of interface descriptors we found. We rely on this later on.
+	if ( numberOfInterfaces != interfaceCount )
+		{
+		LEAVEL(KErrUsbInterfaceCountMismatch);
+		}
+
+	// Check that each interface number in iInterfaces is unique.
+	if ( interfaceCount > 1 )
+		{
+		for ( TUint ii = 0 ; ii < interfaceCount ; ++ii )
+			{
+			const TInterfaceInfo* lhs = iInterfaces[ii];
+			ASSERT_DEBUG(lhs);
+			for ( TUint jj = ii+1 ; jj < interfaceCount ; ++jj )
+				{
+				const TInterfaceInfo* rhs = iInterfaces[jj];
+				ASSERT_DEBUG(rhs);
+				if ( lhs->iNumber == rhs->iNumber )
+					{
+					LEAVEL(KErrUsbDuplicateInterfaceNumbers);
+					}
+				}
+			}
+		}
+
+#ifndef __OVER_DUMMYUSBDI__
+	// If we're using the DummyUSBDI we don't need the real USBDI.
+	// Load USBDI when attached devices goes from 0 to 1
+	if (iDevices.IsEmpty())
+		{
+		TInt err = User::LoadLogicalDevice(KDriverUsbdiLddFileName);
+		if ( err != KErrAlreadyExists )
+			{
+			LEAVEIFERRORL(err);
+			}
+		}
+#endif // __OVER_DUMMYUSBDI__
+	
+	// Now we know we've succeeded with a device attachment, remove the device
+	// proxy from the cleanup stack and put it on the TSglQue.
+	CLEANUPSTACK_POP1(aDevice);
+	iDevices.AddLast(*aDevice);
+	// Also put an event on the event queue.
+	TDeviceEvent* const attachmentEvent = aDevice->GetAttachmentEventObject();
+	ASSERT_DEBUG(attachmentEvent);
+	attachmentEvent->iInfo.iVid = iDD.VendorId();
+	attachmentEvent->iInfo.iPid = iDD.ProductId();
+	attachmentEvent->iInfo.iError = KErrNone;
+	ASSERT_DEBUG(iEventQueue);
+	iEventQueue->AddDeviceEvent(*attachmentEvent);
+	LOGTEXT2(_L8("***USB HOST STACK: SUCCESSFUL ATTACHMENT OF DEVICE (id %d)"), aDeviceId);
+	}
+
+void CFdf::DoDriverLoading(CDeviceProxy& aDevice)
+	{
+	LOG_FUNC
+
+	// Leaving or returning from DoDriverLoadingL is the trigger to put the
+	// 'driver loading' event object on the event queue. It must already have
+	// been populated correctly (the actual error code it left with doesn't
+	// feed into the driver loading event).
+	TRAP_IGNORE(DoDriverLoadingL(aDevice));
+	
+	TDeviceEvent* const driverLoadingEvent = aDevice.GetDriverLoadingEventObject();
+	ASSERT_DEBUG(driverLoadingEvent);
+	// The driver loading event object says whether driver loading succeeded
+	// (all interfaces were claimed without error), partly succeeded (not all
+	// interfaces were claimed without error), or failed (no interfaces were
+	// claimed without error). This information is intended for USBMAN so it
+	// can tell the user, but we also use it now to suspend the device if
+	// driver loading failed completely.
+	if ( driverLoadingEvent->iInfo.iDriverLoadStatus == EDriverLoadFailure )
+		{
+		// We can't do anything with error here. Suspending the device is for
+		// power-saving reasons and is not critical.
+		(void)aDevice.Suspend();
+		}
+	ASSERT_DEBUG(iEventQueue);
+	iEventQueue->AddDeviceEvent(*driverLoadingEvent);
+	}
+
+
+void CFdf::DoDriverLoadingL(CDeviceProxy& aDevice)
+	{
+	LOG_FUNC
+
+	// Check whether driver loading is enabled.
+	if ( !iDriverLoadingEnabled )
+		{
+		// Complete driver load failure scenario.
+		aDevice.SetDriverLoadingEventData(EDriverLoadFailure, KErrUsbDriverLoadingDisabled);
+		LEAVEL(KErrGeneral);
+	}
+
+
+	// Set this member up so that when the FDC calls TokenForInterface we call
+	// the right proxy object.
+
+	TInt collectedErr = KErrNone;
+	TBool anySuccess = EFalse;
+
+
+	// Now actually try to load the drivers.
+	// Device drivers are located based upon descriptor information from the USB device. The first search is
+	// based on information from the device descriptor and looks for a driver that matches the whole device; 
+	// the second search is based upon locating a driver for each interface within a configuration.
+	// The particular keys used in the driver search are defined in the Universal Serial Bus Common Class
+	// Specification version 1.0. They are represented by TDeviceSearchKeys and TInterfaceSearchKeys.						
+	//
+	// First perform a device search by iterating through the keys in TDeviceSearchKeys looking for a matching driver.
+	TBool functionDriverFound = SearchForADeviceFunctionDriverL(aDevice, anySuccess, collectedErr);
+	
+	// When do the parsing against the CD bundle, we already know if there is IAD(Interface Association Descriptor)
+	// in the new attached device. Once we finished the device level searching of FDC and we couldn't find any, we
+	// break down the loading process
+	if (aDevice.HasIADFlag() && !functionDriverFound)
+		{
+		aDevice.SetDriverLoadingEventData(EDriverLoadFailure, KErrUsbUnsupportedDevice);
+		LEAVEL(KErrGeneral);		
+		}
+	// If a device FD is found then it is supposed to claim all the interfaces, if it didn't then report
+	// a partial success but don't offer unclaimed interfaces to any other FD.
+	const TUint interfaceCount = iInterfaces.Count();
+
+
+	
+	// If no device driver was found then next perform an Interface search
+	if (!functionDriverFound)
+		SearchForInterfaceFunctionDriversL(aDevice, anySuccess, collectedErr);
+
+	// Now worry about the following:
+	// (a) are there any unclaimed interfaces remaining?
+	// (b) what's in collectedErr?
+	// Whether all interfaces were taken, some, or none, collectedErr may have
+	// an error in it or KErrNone. We use specific error codes in some cases.			
+	TUint unclaimedInterfaces = UnclaimedInterfaceCount();
+	LOGTEXT2(_L8("\tunclaimedInterfaces = %d"), unclaimedInterfaces);
+	LOGTEXT2(_L8("\tanySuccess = %d"), anySuccess);
+	LOGTEXT2(_L8("\tcollectedErr = %d"), collectedErr);
+	ASSERT_DEBUG(unclaimedInterfaces <= interfaceCount);
+
+	if(iDeviceDetachedTooEarly)
+		{
+		LOGTEXT(_L8("\tDevice has been detached too early!"));
+		iDeviceDetachedTooEarly = EFalse;
+		// the choice of having the status to be EDriverLoadPartialSuccess
+		// was not to clash with trying to suspend the device because
+		// of a total failure to load the FD.(because device is detached)
+		// even though that a FDC has been created
+		// see the :
+		// if ( driverLoadingEvent->iInfo.iDriverLoadStatus == EDriverLoadFailure )
+		// in function above => void CFdf::DoDriverLoadingL(etc...)
+		aDevice.SetDriverLoadingEventData(EDriverLoadPartialSuccess, KErrUsbDeviceDetachedDuringDriverLoading);
+		}
+	else
+		{
+		SetFailureStatus(unclaimedInterfaces, interfaceCount, anySuccess, collectedErr, aDevice);
+		}// iDeviceDetachedTooEarly
+
+	}
+
+// Recursive function, originally called with the configuration descriptor.
+// Builds up information on the interface descriptors in the configuration
+// bundle.
+void CFdf::ParseL(TUsbGenericDescriptor& aDesc)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\t&aDesc = 0x%08x"), &aDesc);
+	LOGTEXT2(_L8("\taDesc.ibDescriptorType = %d"), aDesc.ibDescriptorType);
+	LOGTEXT2(_L8("\taDesc.iFirstChild = 0x%08x"), aDesc.iFirstChild);
+	LOGTEXT2(_L8("\taDesc.iNextPeer = 0x%08x"), aDesc.iNextPeer);
+
+	if ( aDesc.ibDescriptorType == EInterface )
+		{
+		// Add interface information to collection, but only if it's alternate
+		// setting 0.
+		const TUsbInterfaceDescriptor& ifDesc = static_cast<TUsbInterfaceDescriptor&>(aDesc);
+		if ( ifDesc.AlternateSetting() == 0 ) // hard-coded '0' means the default (initial configuration) setting
+			{
+			LOGTEXT2(_L8("\tifDesc.InterfaceNumber = %d"), ifDesc.InterfaceNumber());
+			LOGTEXT2(_L8("\tifDesc.NumEndpoints = %d"), ifDesc.NumEndpoints());
+			LOGTEXT2(_L8("\tifDesc.InterfaceClass = 0x%02x"), ifDesc.InterfaceClass());
+			LOGTEXT2(_L8("\tifDesc.InterfaceSubClass = 0x%02x"), ifDesc.InterfaceSubClass());
+			LOGTEXT2(_L8("\tifDesc.InterfaceProtocol = 0x%02x"), ifDesc.InterfaceProtocol());
+			LOGTEXT2(_L8("\tifDesc.Interface = %d"), ifDesc.Interface());
+
+			TInterfaceInfo* ifInfo = TInterfaceInfo::NewL(iInterfaces);
+			ifInfo->iNumber = ifDesc.InterfaceNumber();
+			ifInfo->iClass = ifDesc.InterfaceClass();
+			ifInfo->iSubclass = ifDesc.InterfaceSubClass();
+			ifInfo->iProtocol = ifDesc.InterfaceProtocol();
+			ifInfo->iClaimed = EFalse;
+			}
+		}
+	else if (!iCurrentDevice->HasIADFlag() && aDesc.ibDescriptorType == EInterfaceAssociation)
+		{
+		// When found a Interface association descriptor, set this flag to ETrue,
+		// it is checked later after the device level driverloading.
+		iCurrentDevice->SetHasIADFlag();
+		}
+	else if (aDesc.ibDescriptorType == EOTG)
+		{
+		// OTG descriptor found
+		const TUsbOTGDescriptor& otgDesc = static_cast<TUsbOTGDescriptor&>(aDesc);
+
+		LOGTEXT2(_L8("\totgDesc.Attributes = %b"), otgDesc.Attributes());
+		LOGTEXT2(_L8("\totgDesc.HNPSupported = %d"), otgDesc.HNPSupported());
+		LOGTEXT2(_L8("\totgDesc.SRPSupported = %d"), otgDesc.SRPSupported());
+		
+		iCurrentDevice->SetOtgDescriptorL(otgDesc);
+		}
+
+	TUsbGenericDescriptor* const firstChild = aDesc.iFirstChild;
+	if ( firstChild )
+		{
+		ParseL(*firstChild);
+		}
+
+	TUsbGenericDescriptor* const nextPeer = aDesc.iNextPeer;
+	if ( nextPeer )
+		{
+		ParseL(*nextPeer);
+		}
+	}
+
+// Method that uses only one array to hold the unclaimed interface numbers.
+void CFdf::FindDriversForInterfacesUsingSpecificKeyL(CDeviceProxy& aDevice,
+													TInt& aCollectedErr,
+													TBool& aAnySuccess,			
+													RArray<TUint>& aInterfacesNumberArray, 
+													TInterfaceSearchKeys aKey)	
+	{
+	LOG_FUNC
+
+	const TUint interfaceCount = iInterfaces.Count();
+	for ( TUint ii = 0 ; ii < interfaceCount ; ++ii )
+		{
+		TInterfaceInfo* ifInfo = iInterfaces[ii];		
+		ASSERT_DEBUG(ifInfo);
+		
+		if ((ifInfo->iClaimed) ||
+			(aKey == EVendorInterfacesubclassInterfaceprotocol && ifInfo->iClass != KVendorSpecificInterfaceClassValue)||	
+			(aKey == EVendorInterfacesubclass && ifInfo->iClass != KVendorSpecificInterfaceClassValue) ||
+			(aKey == EInterfaceclassInterfacesubclassInterfaceprotocol && ifInfo->iClass == KVendorSpecificInterfaceClassValue) ||
+			(aKey == EInterfaceclassInterfacesubclass && ifInfo->iClass == KVendorSpecificInterfaceClassValue))
+			{
+			continue;
+			}
+		
+
+		TBuf8<KMaxSearchKeyLength> searchKey;
+		FormatInterfaceSearchKey(searchKey, aKey, *ifInfo);
+
+		LOGTEXT2(_L8("\tsearchKey = \"%S\""), &searchKey);
+		// RArray<TUint>* array = &aInterfacesNumberArray;
+
+		FindDriverForInterfaceUsingSpecificKey(aDevice, aCollectedErr, aAnySuccess, aInterfacesNumberArray, searchKey);
+
+		// Putting ii+1 as the starting offset is to remove the interface on which
+		// the searching have been done.		
+		RebuildUnClaimedInterfacesArrayL(aDevice, aInterfacesNumberArray, ii+1);
+		}
+	}
+
+
+
+// Called for one interface, to find a Function Driver on the basis of a
+
+// specific search key.
+void CFdf::FindDriverForInterfaceUsingSpecificKey(CDeviceProxy& aDevice,
+								   TInt& aCollectedErr,
+								   TBool& aAnySuccess,
+								   RArray<TUint>& aInterfacesGivenToFdc,
+								   const TDesC8& aSearchKey)
+	{
+
+	LOG_FUNC
+	LOGTEXT2(_L8("\taSearchKey = \"%S\""), &aSearchKey);
+
+	// Find an FDC matching this search key.
+	TSglQueIter<CFdcProxy> iter(iFunctionDrivers);
+	iter.SetToFirst();
+	CFdcProxy* fdc;
+
+	while ( ( fdc = iter++ ) != NULL )
+		{
+		LOGTEXT2(_L8("\tFDC's default_data field = \"%S\""), &fdc->DefaultDataField());
+#ifdef _DEBUG
+	// having these two together in the debug window is helpful for interactive debugging
+	TBuf8<KMaxSearchKeyLength > fd_key;
+	fd_key.Append(fdc->DefaultDataField().Ptr(), fdc->DefaultDataField().Length() > KMaxSearchKeyLength ? KMaxSearchKeyLength : fdc->DefaultDataField().Length());
+	TBuf8<KMaxSearchKeyLength > searchKey;
+	searchKey.Append(aSearchKey.Ptr(), aSearchKey.Length() > KMaxSearchKeyLength ? KMaxSearchKeyLength : aSearchKey.Length());
+	TInt version = fdc->Version();
+#endif // _DEBUG
+		if (aSearchKey.CompareF(fdc->DefaultDataField()) == 0 && !fdc->MarkedForDeletion())
+			{
+			// If there is more than one matching FD then if all of them are in RAM we simply choose the first one we find.
+			// (Similarly if they are all in ROM we choose the first one although this situation should not arise as a device
+			// manufacturer should not put two matching FDs into ROM).
+			// However if there are matching FDs in ROM and RAM then the one in ROM should be selected in preference to
+			// any in RAM. Hence at this point if the matching FD we have found is in RAM then we need to scan the list
+			// of FDs to see if there is also a matching one in ROM and if so we'll skip this iteration of the loop.
+			
+			// Edwin comment
+			// Put the searching key and the iterator as the parameter of 
+			// searching if more FDCs have the same default_data. The iterator
+			// helps to searching from the current FDC since this is the very first
+			// suitable FDC we found so fa.
+			if (!aDevice.MultipleDriversFlag() && FindMultipleFDs(aSearchKey, iter))
+				{
+				aDevice.SetMultipleDriversFlag();
+				}
+			
+			LOGTEXT2(_L8("\tfound matching FDC (0x%08x)"), fdc);
+#ifdef __FLOG_ACTIVE
+			const TUint count = aInterfacesGivenToFdc.Count();
+			LOGTEXT2(_L8("\tlogging aInterfacesGivenToFdc (interfaces being offered to the FDC): count = %d"), count);
+			for ( TUint ii = 0 ; ii < count ; ++ii )
+				{
+				LOGTEXT3(_L8("\t\tindex %d: interface number %d"), ii, aInterfacesGivenToFdc[ii]);
+				}
+#endif
+			TInt err = fdc->NewFunction(aDevice.DeviceId(), aInterfacesGivenToFdc, iDD, iCD);
+			LOGTEXT2(_L8("\tNewFunction returned %d"), err);
+			// To correctly determine whether the driver load for the whole
+			// configuration was a complete failure, a partial success or a
+			// complete success, we need to collect any non-KErrNone error
+			// from this, and whether any handovers worked at all.
+			if ( err == KErrNone )
+				{
+#ifdef __FLOG_ACTIVE
+				LOGTEXT3(_L8("***USB HOST STACK: THE FOLLOWING INTERFACES OF DEVICE %d WERE SUCCESSFULLY PASSED TO FUNCTION DRIVER WITH IMPL UID 0x%08x"),
+					aDevice.DeviceId(), fdc->ImplUid());
+				// We want to log each interface that's in
+				// aInterfacesGivenToFdc AND is marked claimed in iInterfaces.
+				for ( TUint ii = 0 ; ii < aInterfacesGivenToFdc.Count() ; ++ii )
+					{
+					const TUint ifNum = aInterfacesGivenToFdc[ii];
+					for ( TUint jj = 0 ; jj < iInterfaces.Count() ; ++jj )
+						{
+						const TInterfaceInfo* ifInfo = iInterfaces[jj];
+						ASSERT_DEBUG(ifInfo);
+						if (	ifNum == ifInfo->iNumber
+							&&	ifInfo->iClaimed
+							)
+							{
+							LOGTEXT2(_L8("***USB HOST STACK: bInterfaceNumber %d"), ifNum);
+							}
+						}
+					}
+#endif
+				aAnySuccess = ETrue;
+				}
+			else
+				{
+				aCollectedErr = err;
+				}
+			// We found a matching FDC for this interface- no need to look for more.
+			break;
+			}
+		}
+	}
+
+void CFdf::HandleDeviceDetachment(TUint aDeviceId)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taDeviceId = %d"), aDeviceId);
+
+
+#ifdef _DEBUG
+	TBool found = EFalse;
+#endif
+	// Find the relevant device proxy. If there isn't one, just drop the
+	// notification, assuming that the corresponding attachment failed at the
+	// FDF level.
+	TSglQueIter<CDeviceProxy> iter(iDevices);
+	iter.SetToFirst();
+	CDeviceProxy* device;
+	while ( ( device = iter++ ) != NULL )
+		{
+		if ( device->DeviceId() == aDeviceId )
+			{
+#ifdef _DEBUG
+			found = ETrue;
+#endif
+			LOGTEXT(_L8("\tfound matching device proxy"));
+
+			iDevices.Remove(*device);
+			// Before destroying the device proxy, take the detachment event
+			// stored in it for the event queue.
+			TDeviceEvent* const detachmentEvent = device->GetDetachmentEventObject();
+			ASSERT_DEBUG(detachmentEvent);
+			ASSERT_DEBUG(iEventQueue);
+			iEventQueue->AddDeviceEvent(*detachmentEvent);
+			LOGTEXT2(_L8("***USB HOST STACK: DETACHMENT OF DEVICE (id %d)"), aDeviceId);
+			delete device;
+
+			TellFdcsOfDeviceDetachment(aDeviceId);
+			
+#ifndef __OVER_DUMMYUSBDI__
+			// If we're using the DummyUSBDI the real USBDI isn't loaded.
+			// Unload USBDI when attached devices goes from 1 to 0
+			if (iDevices.IsEmpty())
+				{
+				TInt err = User::FreeLogicalDevice(KDriverUsbdiLddFileName);
+				LOGTEXT2(_L8("\tFreeLogicalDevice( usbdi ) returned %d"), err);
+				}
+#endif // __OVER_DUMMYUSBDI__
+			
+			break;
+			}
+		}
+
+#ifdef _DEBUG
+	if ( !found )
+		{
+		LOGTEXT(_L8("\tno matching device proxy found"));
+		}
+#endif
+	}
+
+void CFdf::HandleDevmonEvent(TInt aEvent)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taEvent = %d"), aEvent);
+
+	ASSERT_DEBUG(iEventQueue);
+	iEventQueue->AddDevmonEvent(aEvent);
+	}
+
+void CFdf::TellFdcsOfDeviceDetachment(TUint aDeviceId)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taDeviceId = %d"), aDeviceId);
+
+	TSglQueIter<CFdcProxy> iter(iFunctionDrivers);
+	iter.SetToFirst();
+	CFdcProxy* fdc;
+	while ( ( fdc = iter++ ) != NULL )
+		{
+		fdc->DeviceDetached(aDeviceId);
+		if (fdc->DeviceCount() == 0 && fdc->MarkedForDeletion())
+			{ // If the FDC was uninstalled while it was in use then it couldn't be deleted at that point so delete it now
+			iFunctionDrivers.Remove(*fdc);
+			delete fdc;
+			}
+		}			
+		
+	}
+
+TUint32 CFdf::TokenForInterface(TUint8 aInterface)
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taInterface = %d"), aInterface);
+	TUint32 token = 0;
+
+	// Check that the interface was in the array given to the FD and mark it
+	// as claimed.
+	TBool found = EFalse;
+	const TUint interfaceCount = iInterfaces.Count();
+	for ( TUint ii = 0 ; ii < interfaceCount ; ++ii )
+		{
+		TInterfaceInfo* ifInfo = iInterfaces[ii];
+		ASSERT_DEBUG(ifInfo);
+		if ( ifInfo->iNumber == aInterface )
+			{
+			found = ETrue;
+			// The FDC tried to claim an interface that was already claimed.
+			ASSERT_ALWAYS(!ifInfo->iClaimed);
+			ifInfo->iClaimed = ETrue;
+			break;
+			}
+		}
+	// Could not find interface in the interface array- the FDC tried to claim
+	// an interface it had not been offered.
+	ASSERT_ALWAYS(found);
+
+	ASSERT_DEBUG(iCurrentDevice);
+
+	// GetTokenForInterface will return error in the following cases:
+	// 1/ KErrBadHandle: invalid device handle (the CDeviceProxy asserts that
+	// the handle is valid) because the device has been detached while processing
+	// may be due to too much current or cable has been removed
+	// so FDF will still return a token of 0 and FDF will handle the proper
+	// device detachment when it will be able to process the detachment notification
+	//
+	// 2/ KErrNotFound: interface not found (if this happens, the FDC has
+	// misbehaved, and the correct thing to do is to panic)
+	// 3/ KErrInUse: we've already requested a token for that interface
+	// (ditto)
+	// 4/ KErrOverflow: when 0xFFFFFFFF tokens have been requested (this is a
+	// realistic built-in limitation of USBD)
+
+
+	TInt err = iCurrentDevice->GetTokenForInterface(aInterface, token);
+	switch(err)
+		{
+		case KErrBadHandle:
+			token = 0;
+			iDeviceDetachedTooEarly = ETrue;
+
+		case KErrNone: // Fall through and do nothing
+			break;
+
+		default:
+			LOGTEXT3(_L8("\tUnexpected error %d when requesting token for aInterface %d"),err,aInterface);
+			ASSERT_ALWAYS(0);
+			break;
+		}
+
+	LOGTEXT3(_L8("\tToken for interface %d is = %d"),aInterface, token);
+
+	return token;
+	}
+
+CDeviceProxy* CFdf::DeviceProxyL(TUint aDeviceId) const
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taDeviceId = %d"), aDeviceId);
+
+	TSglQueIter<CDeviceProxy> iter(const_cast<CFdf*>(this)->iDevices);
+	iter.SetToFirst();
+	CDeviceProxy* device = NULL;
+	while ( ( device = iter++ ) != NULL )
+		{
+		if ( device->DeviceId() == aDeviceId )
+			{
+			LOGTEXT2(_L8("\tdevice = 0x%08x"), device);
+			return device;
+			}
+		}
+	LEAVEL(KErrNotFound);
+	return NULL; // avoid warning
+	}
+
+const RArray<TUint>& CFdf::GetSupportedLanguagesL(TUint aDeviceId) const
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8("\taDeviceId = %d"), aDeviceId);
+
+	CDeviceProxy* deviceProxy = DeviceProxyL(aDeviceId);
+	return deviceProxy->GetSupportedLanguages();
+	}
+
+void CFdf::GetManufacturerStringDescriptorL(TUint aDeviceId, TUint32 aLangId, TName& aString) const
+	{
+	LOG_FUNC
+	LOGTEXT3(_L8("\taDeviceId = %d, aLangId = 0x%04x"), aDeviceId, aLangId);
+
+	CDeviceProxy* deviceProxy = DeviceProxyL(aDeviceId);
+	deviceProxy->GetManufacturerStringDescriptorL(aLangId, aString);
+	LOGTEXT2(_L("\taString = \"%S\""), &aString);
+	}
+
+void CFdf::GetProductStringDescriptorL(TUint aDeviceId, TUint32 aLangId, TName& aString) const
+	{
+	LOG_FUNC
+	LOGTEXT3(_L8("\taDeviceId = %d, aLangId = 0x%04x"), aDeviceId, aLangId);
+
+	CDeviceProxy* deviceProxy = DeviceProxyL(aDeviceId);
+	deviceProxy->GetProductStringDescriptorL(aLangId, aString);
+	LOGTEXT2(_L("\taString = \"%S\""), &aString);
+	}
+
+void CFdf::GetOtgDeviceDescriptorL(TInt aDeviceId, TOtgDescriptor& aDescriptor) const
+	{
+	LOG_FUNC
+	
+	DeviceProxyL(aDeviceId)->GetOtgDescriptorL(aDescriptor);
+	}
+
+void CFdf::GetSerialNumberStringDescriptorL(TUint aDeviceId, TUint32 aLangId, TName& aString) const
+	{
+	LOG_FUNC
+	LOGTEXT3(_L8("\taDeviceId = %d, aLangId = 0x%04x"), aDeviceId, aLangId);
+
+	CDeviceProxy* deviceProxy = DeviceProxyL(aDeviceId);
+	deviceProxy->GetSerialNumberStringDescriptorL(aLangId, aString);
+	LOGTEXT2(_L("\taString = \"%S\""), &aString);
+	}
+
+void CFdf::SearchForInterfaceFunctionDriversL(CDeviceProxy& aDevice, TBool& aAnySuccess, TInt& aCollectedErr)
+	{
+	RArray<TUint> interfacesNumberArray;	
+	CleanupClosePushL(interfacesNumberArray);
+
+
+	
+	for ( TUint ii = 0 ; ii < iInterfaces.Count() ; ++ii )
+		{
+		// At this point we have NOT done any interface level searching yet,
+		// and all interfaces should in the Unclaimed status,
+		// just simply put them all into the interfacesNumberArray.
+		TUint interfaceNumber = iInterfaces[ii]->iNumber; 
+		AppendInterfaceNumberToArrayL(aDevice, interfacesNumberArray, interfaceNumber);
+		}
+
+
+	for ( TUint key = EVendorProductDeviceConfigurationvalueInterfacenumber ; key < EMaxInterfaceSearchKey ; ++key )
+		{
+		// Searching for proper FDCs based on different criteria.
+		FindDriversForInterfacesUsingSpecificKeyL(aDevice,
+												aCollectedErr,
+												aAnySuccess,
+												interfacesNumberArray,
+												(TInterfaceSearchKeys) key);
+							
+		// If all the interfaces have been claimed by an FD then there is no point searching for other FDs							
+		if (UnclaimedInterfaceCount() == 0)
+			{
+			break;
+			}
+		else
+			{
+			// Put all the unclaimed interface numbers into the array again.
+			RebuildUnClaimedInterfacesArrayL(aDevice, interfacesNumberArray);
+			}
+		}
+	CleanupStack::PopAndDestroy(&interfacesNumberArray);				
+	}
+void  CFdf::RebuildUnClaimedInterfacesArrayL(CDeviceProxy& aDevice, RArray<TUint>& aArray, TUint aOffset)
+	{
+	aArray.Reset();
+	for ( TUint ii = aOffset ; ii < iInterfaces.Count() ; ++ii )
+		{
+			if (!iInterfaces[ii]->iClaimed)
+				{
+				TUint interfaceNumber = iInterfaces[ii]->iNumber; 
+				AppendInterfaceNumberToArrayL(aDevice, aArray, interfaceNumber);
+				}
+		}
+	}
+
+void CFdf::AppendInterfaceNumberToArrayL(CDeviceProxy& aDevice, RArray<TUint>& aArray, TUint aInterfaceNo) const
+	{
+	TInt err = aArray.Append(aInterfaceNo);
+	if ( err )
+		{
+		aDevice.SetDriverLoadingEventData(EDriverLoadFailure, err);
+		LEAVEL(err);
+		}
+	}
+	
+
+
+TBool CFdf::SearchForADeviceFunctionDriverL(CDeviceProxy& aDevice, TBool& aAnySuccess, TInt& aCollectedErr)
+	{			
+	
+	RArray<TUint> interfaces;
+	CleanupClosePushL(interfaces);
+	
+	for (TUint ii = 0; ii < iInterfaces.Count(); ++ii)
+		{
+		TUint interfaceNumber = iInterfaces[ii]->iNumber; 
+		AppendInterfaceNumberToArrayL(aDevice, interfaces, interfaceNumber);
+		}
+	
+	TBool foundFdc = EFalse;		
+	for (TUint key = EVendorProductDevice; key < EMaxDeviceSearchKey; ++key)
+		{		
+		
+		if (key == EVendorDevicesubclassDeviceprotocol && iDD.DeviceClass() != KVendorSpecificDeviceClassValue)
+			continue;
+		if (key == EVendorDevicesubclass && iDD.DeviceClass() != KVendorSpecificDeviceClassValue)
+			continue;
+		if (key == EDeviceclassDevicesubclassDeviceprotocol && iDD.DeviceClass() == KVendorSpecificDeviceClassValue)
+			continue;
+		if (key == EDeviceclassDevicesubclass && iDD.DeviceClass() == KVendorSpecificDeviceClassValue)
+			continue;			
+		
+		TBuf8<KMaxSearchKeyLength> searchKeyString;
+		FormatDeviceSearchKey(searchKeyString, (TDeviceSearchKeys)key);
+
+		// Find an FDC matching this search key.
+		TSglQueIter<CFdcProxy> iter(iFunctionDrivers);
+		iter.SetToFirst();
+		CFdcProxy* fdc;
+		while ( ( fdc = iter++ ) != NULL)
+			{
+			if (fdc->MarkedForDeletion())
+				continue;
+			LOGTEXT2(_L8("\tFDC's default_data field = \"%S\""), &fdc->DefaultDataField());
+#ifdef _DEBUG
+	// having these two together in the debug window is helpful for interactive debugging
+	TBuf8<KMaxSearchKeyLength> fd_key;
+	fd_key.Append(fdc->DefaultDataField().Ptr(), fdc->DefaultDataField().Length() > KMaxSearchKeyLength ? KMaxSearchKeyLength : fdc->DefaultDataField().Length());	
+	TBuf8<KMaxSearchKeyLength> search_key;
+	search_key.Append(searchKeyString.Ptr(), searchKeyString.Length() > KMaxSearchKeyLength ? KMaxSearchKeyLength : searchKeyString.Length());
+	TInt version = fdc->Version();
+#endif
+			if (searchKeyString.CompareF(fdc->DefaultDataField()) == 0)
+				{
+				
+				// If there is more than one matching FD then if all of them are in RAM we simply choose the first one we find.
+				// (Similarly if they are all in ROM we choose the first one although this situation should not arise as a device
+				// manufacturer should not put two matching FDs into ROM).
+				// However if there are matching FDs in ROM and RAM then the one in ROM should be selected in preference to
+				// any in RAM. Hence at this point if the matching FD we have found is in RAM then we need to scan the list
+				// of FDs to see if there is also a matching one in ROM and if so we'll skip this iteration of the loop.
+				//if (!fdc->RomBased() && FindMatchingRomBasedFD(searchKeyString))
+				//	continue;
+				if (FindMultipleFDs(searchKeyString, iter))
+					{
+					aDevice.SetMultipleDriversFlag();
+					}
+				
+				foundFdc = ETrue;
+				LOGTEXT2(_L8("\tfound matching FDC (0x%08x)"), fdc);
+				TInt err = fdc->NewFunction(aDevice.DeviceId(), interfaces, iDD, iCD);
+				LOGTEXT2(_L8("\tNewFunction returned %d"), err);
+				// To correctly determine whether the driver load for the whole
+				// configuration was a complete failure, a partial success or a
+				// complete success, we need to collect any non-KErrNone error
+				// from this, and whether any handovers worked at all.
+				if ( err == KErrNone )
+					{
+					aAnySuccess = ETrue;
+					}
+				else
+					{
+					aCollectedErr = err;
+					}
+				break; 	// We found a matching FDC so no need to look for more.
+				}
+			}
+		if (foundFdc)
+			break;
+		} // end of for
+	CleanupStack::PopAndDestroy(&interfaces);
+	return foundFdc;
+		
+	} // end of function
+
+
+
+
+//
+// Search the list of FDs looking for which matches with aSearchKey and is rom based and return true if found.
+//
+// added for Multiple FDs
+TBool CFdf::FindMultipleFDs(const TDesC8& aSearchKey,TSglQueIter<CFdcProxy>& aFdcIter)
+	{
+	CFdcProxy* fdc;
+	while ( ( fdc = aFdcIter++ ) != NULL)
+		{
+		if (!fdc->MarkedForDeletion() &&  (aSearchKey.CompareF(fdc->DefaultDataField()) == 0))
+			return ETrue;
+		}
+		
+	return EFalse;
+	}
+
+//
+// Format the string aSearchKey according to aSearchKeys to search for Device Functions drivers
+//
+void CFdf::FormatDeviceSearchKey(TDes8& aSearchKey, TDeviceSearchKeys aDeviceSearchKeys)
+	{
+	LOG_FUNC
+	switch (aDeviceSearchKeys)
+		{
+		case EVendorProductDevice:
+			{
+			_LIT8(KTemplateV_P_D, "V0x%04xP0x%04xD0x%04x");
+			aSearchKey.Format(KTemplateV_P_D(), iDD.VendorId(), iDD.ProductId(), iDD.DeviceBcd());
+			break;
+			}
+		case EVendorProduct:
+			{
+			_LIT8(KTemplateV_P, "V0x%04xP0x%04x");
+			aSearchKey.Format(KTemplateV_P(), iDD.VendorId(), iDD.ProductId());
+			break;
+			}
+		case EVendorDevicesubclassDeviceprotocol:
+			{
+			_LIT8(KTemplateV_DSC_DP, "V0x%04xDSC0x%02xDP0x%02x");
+			aSearchKey.Format(KTemplateV_DSC_DP(), iDD.VendorId(), iDD.DeviceSubClass(), iDD.DeviceProtocol());
+			break;
+			}
+		case EVendorDevicesubclass:
+			{
+			_LIT8(KTemplateV_DSC, "V0x%04xDSC0x%02x");
+			aSearchKey.Format(KTemplateV_DSC(), iDD.VendorId(), iDD.DeviceSubClass());
+			break;
+			}
+		case EDeviceclassDevicesubclassDeviceprotocol:
+			{
+			_LIT8(KTemplateDC_DSC_DP, "DC0x%02xDSC0x%02xDP0x%02x");
+			aSearchKey.Format(KTemplateDC_DSC_DP(), iDD.DeviceClass(), iDD.DeviceSubClass(), iDD.DeviceProtocol());
+			break;
+			}
+		case EDeviceclassDevicesubclass:
+			{
+			_LIT8(KTemplateDC_DSC, "DC0x%02xDSC0x%02x");
+			aSearchKey.Format(KTemplateDC_DSC(), iDD.DeviceClass(), iDD.DeviceSubClass());
+			break;
+			}
+		default:
+			{
+			ASSERT_DEBUG(EFalse);
+			}		
+		}
+		
+	LOGTEXT2(_L8("\taSearchKey = \"%S\""), &aSearchKey);		
+	}
+	
+	
+	
+	
+
+//
+// Format the string aSearchKey according to aSearchKeys to search for Interface Functions drivers
+//	
+void CFdf::FormatInterfaceSearchKey(TDes8& aSearchKey, TInterfaceSearchKeys aSearchKeys, const TInterfaceInfo& aIfInfo)
+	{
+	LOG_FUNC
+	switch (aSearchKeys)
+		{
+		case EVendorProductDeviceConfigurationvalueInterfacenumber:
+			{
+			_LIT8(KTemplateV_P_D_CV_IN, "V0x%04xP0x%04xD0x%04xCV0x%02xIN0x%02x");		
+			aSearchKey.Format(KTemplateV_P_D_CV_IN(), iDD.VendorId(), iDD.ProductId(), iDD.DeviceBcd(), iCD.ConfigurationValue(), aIfInfo.iNumber);
+			break;
+			}
+		case EVendorProductConfigurationValueInterfacenumber:
+			{
+			_LIT8(KTemplateV_P_CV_IN, "V0x%04xP0x%04xCV0x%02xIN0x%02x");
+			aSearchKey.Format(KTemplateV_P_CV_IN(), iDD.VendorId(), iDD.ProductId(), iCD.ConfigurationValue(), aIfInfo.iNumber);
+			break;
+			}
+		case EVendorInterfacesubclassInterfaceprotocol:
+			{
+			_LIT8(KTemplateV_ISC_IP, "V0x%04xISC0x%02xIP0x%02x");
+			aSearchKey.Format(KTemplateV_ISC_IP(), iDD.VendorId(), aIfInfo.iSubclass, aIfInfo.iProtocol);
+			break;
+			}
+		case EVendorInterfacesubclass:
+			{
+			_LIT8(KTemplateV_ISC, "V0x%04xISC0x%02x");
+			aSearchKey.Format(KTemplateV_ISC(), iDD.VendorId(), aIfInfo.iSubclass);
+			break;
+			}
+		case EInterfaceclassInterfacesubclassInterfaceprotocol:
+			{
+			_LIT8(KTemplateIC_ISC_IP, "IC0x%02xISC0x%02xIP0x%02x");
+			aSearchKey.Format(KTemplateIC_ISC_IP(), aIfInfo.iClass, aIfInfo.iSubclass, aIfInfo.iProtocol);
+			break;
+			}
+		case EInterfaceclassInterfacesubclass:
+			{
+			_LIT8(KTemplateIC_ISC, "IC0x%02xISC0x%02x");
+			aSearchKey.Format(KTemplateIC_ISC(), aIfInfo.iClass, aIfInfo.iSubclass);
+			break;
+			}
+		default:
+			{
+			ASSERT_DEBUG(EFalse);
+			}
+		}
+	LOGTEXT2(_L8("\taSearchKey = \"%S\""), &aSearchKey);		
+	}
+
+
+TUint CFdf::UnclaimedInterfaceCount() const
+	{
+	LOG_FUNC	
+	TUint unclaimedInterfaces = 0;
+	for ( TUint ii = 0 ; ii < iInterfaces.Count() ; ++ii )
+		{
+		TInterfaceInfo* ifInfo = iInterfaces[ii];
+		ASSERT_DEBUG(ifInfo);
+		if ( !ifInfo->iClaimed )
+			{
+			LOGTEXT2(_L8("\tunclaimed interface: ifInfo->iNumber = %d"), ifInfo->iNumber);
+			++unclaimedInterfaces;
+			}
+		}
+	LOGTEXT2(_L("\tunclaimedInterfaces = \"%d\""), unclaimedInterfaces);			
+	return unclaimedInterfaces;
+	}
+	
+	
+void CFdf::SetFailureStatus(TInt aUnclaimedInterfaces, TInt aInterfaceCount, TBool aAnySuccess, TBool aCollectedErr, CDeviceProxy& aDevice)
+	{
+	const TUint KMultipleDriverFound = aDevice.MultipleDriversFlag()?KMultipleDriversFound : 0;
+	
+	if (aUnclaimedInterfaces)
+		{
+		if(aUnclaimedInterfaces == aInterfaceCount)
+			{
+			// complete failure
+			aDevice.SetDriverLoadingEventData((TDriverLoadStatus)(EDriverLoadFailure|KMultipleDriverFound), KErrUsbFunctionDriverNotFound);
+			}
+		else
+			{// at that stage because we have unclaimed interfaces it means that
+			// depending on anySuccess we have a failure or a partial success
+			TDriverLoadStatus status = (aAnySuccess)? EDriverLoadPartialSuccess:EDriverLoadFailure;
+			aDevice.SetDriverLoadingEventData((TDriverLoadStatus)(status|KMultipleDriverFound), KErrUsbFunctionDriverNotFound);
+			}
+		}
+	else
+		{
+		if (aCollectedErr)
+			{
+			// There were no unclaimed interfaces, but an error was expressed.
+			// This is either a partial success or a complete failure scenario.
+			TDriverLoadStatus status = aAnySuccess ? EDriverLoadPartialSuccess : EDriverLoadFailure;
+			aDevice.SetDriverLoadingEventData((TDriverLoadStatus)(status|KMultipleDriverFound), aCollectedErr);
+			}
+		else
+			{
+			// There were no unclaimed interfaces, and no error reported.
+			aDevice.SetDriverLoadingEventData((TDriverLoadStatus)(EDriverLoadSuccess|KMultipleDriverFound));
+			}
+		}
+	}	
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/src/fdfserver.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,140 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include "fdfserver.h"
+#include "fdfsession.h"
+#include <usb/usblogger.h>
+#include "utils.h"
+#include "fdfapi.h"
+#include "fdf.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdf      ");
+#endif
+
+#ifdef _DEBUG
+PANICCATEGORY("fdfsrv");
+#endif
+
+void CFdfServer::NewLC()
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CFdfServer* self = new(ELeave) CFdfServer;
+	CleanupStack::PushL(self);
+	// StartL is where the kernel checks that there isn't already an instance
+	// of the same server running, so do it before ConstructL.
+	self->StartL(KUsbFdfServerName);
+	self->ConstructL();
+	}
+
+CFdfServer::~CFdfServer()
+	{
+	LOG_FUNC
+
+	delete iFdf;
+	}
+
+CFdfServer::CFdfServer()
+ :	CServer2(CActive::EPriorityHigh)
+	{
+	}
+
+void CFdfServer::ConstructL()
+	{
+	LOG_FUNC
+
+	iFdf = CFdf::NewL();
+	}
+
+CSession2* CFdfServer::NewSessionL(const TVersion& aVersion,
+	const RMessage2& aMessage) const
+	{
+	LOG_LINE
+	LOG_FUNC;
+	LOGTEXT4(_L8("\taVersion = (%d,%d,%d)"), aVersion.iMajor, aVersion.iMinor, aVersion.iBuild);
+	(void)aMessage;
+
+	// Check if we already have a session open.
+	if ( iSession )
+		{
+		LEAVEL(KErrInUse);
+		}
+
+	// In the production system, check the secure ID of the prospective
+	// client. It should be that of USBSVR.
+	// For unit testing, don't check the SID of the connecting client (it will
+	// not be USBSVR but the FDF Unit Test server).
+#ifndef __OVER_DUMMYUSBDI__
+
+#ifndef __TEST_FDF__
+	// NB When using t_fdf, this SID check needs disabling- t_fdf has yet
+	// another SID.
+	_LIT_SECURE_ID(KUsbsvrSecureId, 0x101fe1db);
+	// Contrary to what the sysdoc says on SecureId, we specifically *don't*
+	// use a _LIT_SECURITY_POLICY_S0 here. This is because (a) we emit our own
+	// diagnostic messages, and (b) we don't want configuring this security
+	// check OFF to allow any client to pass and thereby break our
+	// architecture.
+	TInt error = ( aMessage.SecureId() == KUsbsvrSecureId ) ? KErrNone : KErrPermissionDenied;
+	LEAVEIFERRORL(error);
+#endif // __TEST_FDF__
+
+#endif // __OVER_DUMMYUSBDI__
+
+	// Version number check...
+	TVersion v(KUsbFdfSrvMajorVersionNumber,
+		KUsbFdfSrvMinorVersionNumber,
+		KUsbFdfSrvBuildNumber);
+
+	if ( !User::QueryVersionSupported(v, aVersion) )
+		{
+		LEAVEL(KErrNotSupported);
+		}
+
+	CFdfServer* ncThis = const_cast<CFdfServer*>(this);
+	ncThis->iSession = new(ELeave) CFdfSession(*iFdf, *ncThis);
+	ASSERT_DEBUG(ncThis->iFdf);
+	ncThis->iFdf->SetSession(iSession);
+
+	LOGTEXT2(_L8("\tiSession = 0x%08x"), iSession);
+	return iSession;
+	}
+
+void CFdfServer::SessionClosed()
+	{
+	LOG_FUNC
+
+	ASSERT_DEBUG(iSession);
+	iSession = NULL;
+	iFdf->SetSession(NULL);
+
+	LOGTEXT(_L8("\tno remaining sessions- shutting down"));
+	// This returns control to the server boilerplate in main.cpp. This
+	// destroys all the objects, which includes signalling device detachment
+	// to any extant FDCs.
+	// The session object could perfectly well do this in its destructor but
+	// it's arguably more clear for the server to do it as it's the server
+	// that's created immediately before calling CActiveScheduler::Start in
+	// main.cpp.
+	CActiveScheduler::Stop();
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/src/fdfsession.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,479 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include "fdfsession.h"
+#include "fdfserver.h"
+#include <usb/usblogger.h>
+#include "utils.h"
+#include <ecom/ecom.h>
+#include "fdfapi.h"
+#include "fdf.h"
+#include "event.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdf      ");
+#endif
+
+#ifdef _DEBUG
+PANICCATEGORY("fdfsession");
+#endif
+
+CFdfSession::CFdfSession(CFdf& aFdf, CFdfServer& aServer)
+ :	iFdf(aFdf),
+	iServer(aServer)
+	{
+	LOG_FUNC
+	}
+
+CFdfSession::~CFdfSession()
+	{
+	LOG_LINE
+	LOG_FUNC;
+
+	iServer.SessionClosed();
+	}
+
+void CFdfSession::ServiceL(const RMessage2& aMessage)
+	{
+	LOG_LINE
+	LOG_FUNC;
+	LOGTEXT2(_L8("\taMessage.Function() = %d"), aMessage.Function());
+
+	// Switch on the IPC number and call a 'message handler'. Message handlers
+	// complete aMessage (either with Complete or Panic), or make a note of
+	// the message for later asynchronous completion.
+	// Message handlers should not leave- the server does not have an Error
+	// function.
+
+	switch ( aMessage.Function() )
+		{
+	case EUsbFdfSrvEnableDriverLoading:
+		EnableDriverLoading(aMessage);
+		// This is a sync API- check that the message has been completed.
+		// (NB We don't check the converse for async APIs because the message
+		// may have been panicked synchronously.)
+		ASSERT_DEBUG(aMessage.Handle() == 0);
+		break;
+
+	case EUsbFdfSrvDisableDriverLoading:
+		DisableDriverLoading(aMessage);
+		ASSERT_DEBUG(aMessage.Handle() == 0);
+		break;
+
+	case EUsbFdfSrvNotifyDeviceEvent:
+		NotifyDeviceEvent(aMessage);
+		break;
+
+	case EUsbFdfSrvNotifyDeviceEventCancel:
+		NotifyDeviceEventCancel(aMessage);
+		ASSERT_DEBUG(aMessage.Handle() == 0);
+		break;
+
+	case EUsbFdfSrvNotifyDevmonEvent:
+		NotifyDevmonEvent(aMessage);
+		break;
+
+	case EUsbFdfSrvNotifyDevmonEventCancel:
+		NotifyDevmonEventCancel(aMessage);
+		ASSERT_DEBUG(aMessage.Handle() == 0);
+		break;
+
+	case EUsbFdfSrvGetSingleSupportedLanguageOrNumberOfSupportedLanguages:
+		GetSingleSupportedLanguageOrNumberOfSupportedLanguages(aMessage);
+		ASSERT_DEBUG(aMessage.Handle() == 0);
+		break;
+
+	case EUsbFdfSrvGetSupportedLanguages:
+		GetSupportedLanguages(aMessage);
+		ASSERT_DEBUG(aMessage.Handle() == 0);
+		break;
+
+	case EUsbFdfSrvGetManufacturerStringDescriptor:
+		GetManufacturerStringDescriptor(aMessage);
+		ASSERT_DEBUG(aMessage.Handle() == 0);
+		break;
+
+	case EUsbFdfSrvGetProductStringDescriptor:
+		GetProductStringDescriptor(aMessage);
+		ASSERT_DEBUG(aMessage.Handle() == 0);
+		break;
+		
+	case EUsbFdfSrvGetOtgDescriptor:
+		GetOtgDeviceDescriptor(aMessage);
+		ASSERT_DEBUG(aMessage.Handle() == 0);
+		break;
+
+	// Heap failure testing APIs.
+	case EUsbFdfSrvDbgFailNext:
+#ifdef _DEBUG
+		{
+		LOGTEXT2(_L8("\tfail next (simulating failure after %d allocation(s))"), aMessage.Int0());
+		if ( aMessage.Int0() == 0 )
+			{
+			__UHEAP_RESET;
+			}
+		else
+			{
+			__UHEAP_FAILNEXT(aMessage.Int0());
+			}
+		}
+#endif // _DEBUG
+		CompleteClient(aMessage, KErrNone);
+		break;
+
+	case EUsbFdfSrvDbgAlloc:
+		{
+		TInt err = KErrNone;
+#ifdef _DEBUG
+		LOGTEXT(_L8("\tallocate on the heap"));
+		TInt* x = NULL;
+		TRAP(err, x = new(ELeave) TInt);
+		delete x;
+
+#endif // _DEBUG
+		CompleteClient(aMessage, err);
+		}
+		break;
+
+	default:
+		PANIC_MSG(aMessage, KUsbFdfServerName, EBadIpc);
+		break;
+		}
+	}
+
+void CFdfSession::CompleteClient(const RMessage2& aMessage, TInt aError)
+	{
+	LOGTEXT2(_L8("\tcompleting client message with %d"), aError);
+	aMessage.Complete(aError);
+	}
+
+void CFdfSession::EnableDriverLoading(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	iFdf.EnableDriverLoading();
+
+	CompleteClient(aMessage, KErrNone);
+	}
+
+void CFdfSession::DisableDriverLoading(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	iFdf.DisableDriverLoading();
+
+	CompleteClient(aMessage, KErrNone);
+	}
+
+TBool CFdfSession::NotifyDeviceEventOutstanding() const
+	{
+	const TBool ret = ( iNotifyDeviceEventMsg.Handle() != 0 );
+	LOGTEXT2(_L("CFdfSession::NotifyDeviceEventOutstanding returning %d"), ret);
+	return ret;
+	}
+
+void CFdfSession::NotifyDeviceEvent(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	if ( iNotifyDeviceEventMsg.Handle() )
+		{
+		PANIC_MSG(iNotifyDeviceEventMsg, KUsbFdfServerName, ENotifyDeviceEventAlreadyOutstanding);
+		}
+	else
+		{
+		iNotifyDeviceEventMsg = aMessage;
+		TDeviceEvent event;
+		if ( iFdf.GetDeviceEvent(event) )
+			{
+			CompleteDeviceEventNotification(event);
+			}
+		}
+	}
+
+void CFdfSession::NotifyDeviceEventCancel(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	if ( iNotifyDeviceEventMsg.Handle() )
+		{
+		CompleteClient(iNotifyDeviceEventMsg, KErrCancel);
+		}
+	CompleteClient(aMessage, KErrNone);
+	}
+
+void CFdfSession::DeviceEvent(const TDeviceEvent& aEvent)
+	{
+	LOG_FUNC
+
+	// This function should only be called if there is a request outstanding.
+	ASSERT_DEBUG(iNotifyDeviceEventMsg.Handle());
+
+	CompleteDeviceEventNotification(aEvent);
+	}
+
+void CFdfSession::CompleteDeviceEventNotification(const TDeviceEvent& aEvent)
+	{
+	LOG_FUNC
+
+	TRAPD(err, CompleteDeviceEventNotificationL(aEvent));
+	if ( err )
+		{
+		PANIC_MSG(iNotifyDeviceEventMsg, KUsbFdfServerName, EBadNotifyDeviceEventData);
+		}
+	}
+
+void CFdfSession::CompleteDeviceEventNotificationL(const TDeviceEvent& aEvent)
+	{
+	LOG_FUNC
+
+	// iNotifyDeviceEventMsg has one IPC arg: a TDeviceEventInformation
+
+	ASSERT_DEBUG(iNotifyDeviceEventMsg.Handle());
+
+	TPckg<TDeviceEventInformation> info(aEvent.iInfo);
+	iNotifyDeviceEventMsg.WriteL(0, info);
+
+	CompleteClient(iNotifyDeviceEventMsg, KErrNone);
+	}
+
+TBool CFdfSession::NotifyDevmonEventOutstanding() const
+	{
+	const TBool ret = ( iNotifyDevmonEventMsg.Handle() != 0 );
+	LOGTEXT2(_L("CFdfSession::NotifyDevmonEventOutstanding returning %d"), ret);
+	return ret;
+	}
+
+void CFdfSession::NotifyDevmonEvent(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	if ( iNotifyDevmonEventMsg.Handle() )
+		{
+		PANIC_MSG(iNotifyDevmonEventMsg, KUsbFdfServerName, ENotifyDevmonEventAlreadyOutstanding);
+		}
+	else
+		{
+		iNotifyDevmonEventMsg = aMessage;
+		TInt event;
+		if ( iFdf.GetDevmonEvent(event) )
+			{
+			CompleteDevmonEventNotification(event);
+			}
+		}
+	}
+
+void CFdfSession::NotifyDevmonEventCancel(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	if ( iNotifyDevmonEventMsg.Handle() )
+		{
+		CompleteClient(iNotifyDevmonEventMsg, KErrCancel);
+		}
+	CompleteClient(aMessage, KErrNone);
+	}
+
+void CFdfSession::DevmonEvent(TInt aError)
+	{
+	LOG_FUNC
+
+	// This function should only be called if there is a request outstanding.
+	ASSERT_DEBUG(iNotifyDevmonEventMsg.Handle());
+
+	CompleteDevmonEventNotification(aError);
+	}
+
+void CFdfSession::CompleteDevmonEventNotification(TInt aError)
+	{
+	LOG_FUNC
+
+	TRAPD(err, CompleteDevmonEventNotificationL(aError));
+	if ( err )
+		{
+		PANIC_MSG(iNotifyDevmonEventMsg, KUsbFdfServerName, EBadNotifyDevmonEventData);
+		}
+	}
+
+void CFdfSession::CompleteDevmonEventNotificationL(TInt aEvent)
+	{
+	LOG_FUNC
+
+	// iNotifyDevmonEventMsg has the following IPC args:
+	// 0- TInt& aError
+
+	ASSERT_DEBUG(iNotifyDevmonEventMsg.Handle());
+
+	TPckg<TInt> event(aEvent);
+	iNotifyDevmonEventMsg.WriteL(0, event);
+
+	CompleteClient(iNotifyDevmonEventMsg, KErrNone);
+	}
+
+void CFdfSession::GetSingleSupportedLanguageOrNumberOfSupportedLanguages(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	// To save IPC operations between client and server, we make use of the
+	// fact that the majority of devices only support a single language.
+	// The client is expected to have a buffer big enough to hold a single
+	// TUint.
+	// If the device supports 0 languages, the buffer is left empty and the
+	// request is completed with KErrNotFound.
+	// If the device supports 1 language, the language ID is put in the buffer
+	// and the request is completed with KErrNone.
+	// If the device supports more than 1 language, the number of languages is
+	// put in the buffer, and the request is completed with
+	// KErrTooBig. The client then allocates a buffer big enough to hold the
+	// supported languages and uses EUsbFdfSrvGetSupportedLanguages to get
+	// them all.
+	TRAPD(err, GetSingleSupportedLanguageOrNumberOfSupportedLanguagesL(aMessage));
+	CompleteClient(aMessage, err);
+	}
+
+void CFdfSession::GetSingleSupportedLanguageOrNumberOfSupportedLanguagesL(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	const TUint deviceId = aMessage.Int0();
+	LOGTEXT2(_L8("\tdeviceId = %d"), deviceId);
+	const RArray<TUint>& langIds = iFdf.GetSupportedLanguagesL(deviceId);
+	const TUint count = langIds.Count();
+	LOGTEXT2(_L8("\tcount = %d"), count);
+	switch ( count )
+		{
+	case 0:
+		// Nothing to write to the client's address space, complete with
+		LEAVEL(KErrNotFound);
+		break;
+
+	case 1:
+		{
+		// Write the single supported language to the client, complete with
+		// KErrNone (or error of course, if their buffer isn't big enough).
+		TPckg<TUint> buf(langIds[0]);
+		LEAVEIFERRORL(aMessage.Write(1, buf));
+		}
+		break;
+
+	default:
+		{
+		// Write the number of supported languages to the client, complete
+		// with KErrTooBig (or error if their buffer wasn't big enough). NB
+		// This is the point at which this mechanism depends on
+		// RMessagePtr2::WriteL itself not leaving with KErrTooBig!
+		TPckg<TUint> buf(count);
+		LEAVEIFERRORL(aMessage.Write(1, buf));
+		LEAVEL(KErrTooBig);
+		}
+		break;
+		}
+	}
+
+void CFdfSession::GetSupportedLanguages(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	TRAPD(err, GetSupportedLanguagesL(aMessage));
+	CompleteClient(aMessage, err);
+	}
+
+void CFdfSession::GetSupportedLanguagesL(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	const TUint deviceId = aMessage.Int0();
+	LOGTEXT2(_L8("\tdeviceId = %d"), deviceId);
+	const RArray<TUint>& langIds = iFdf.GetSupportedLanguagesL(deviceId);
+
+	const TUint count = langIds.Count();
+	LOGTEXT2(_L8("\tcount = %d"), count);
+	RBuf8 buf;
+	buf.CreateL(count * sizeof(TUint));
+	CleanupClosePushL(buf);
+	for ( TUint ii = 0 ; ii < count ; ++ii )
+		{
+		buf.Append((TUint8*)&(langIds[ii]), sizeof(TUint));
+		}
+
+	// Write back to the client.
+	LEAVEIFERRORL(aMessage.Write(1, buf));
+	CleanupStack::PopAndDestroy(&buf);
+	}
+
+void CFdfSession::GetManufacturerStringDescriptor(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	GetStringDescriptor(aMessage, EManufacturer);
+	}
+
+void CFdfSession::GetProductStringDescriptor(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	GetStringDescriptor(aMessage, EProduct);
+	}
+
+void CFdfSession::GetStringDescriptor(const RMessage2& aMessage, TStringType aStringType)
+	{
+	LOG_FUNC
+
+	TRAPD(err, GetStringDescriptorL(aMessage, aStringType));
+	CompleteClient(aMessage, err);
+	}
+
+void CFdfSession::GetStringDescriptorL(const RMessage2& aMessage, TStringType aStringType)
+	{
+	LOG_FUNC
+
+	ASSERT_DEBUG(aStringType == EManufacturer || aStringType == EProduct);
+
+	TName string;
+	const TUint deviceId = aMessage.Int0();
+	const TUint langId = aMessage.Int1();
+	if ( aStringType == EManufacturer )
+		{
+		iFdf.GetManufacturerStringDescriptorL(deviceId, langId, string);
+		}
+	else
+		{
+		iFdf.GetProductStringDescriptorL(deviceId, langId, string);
+		}
+	LOGTEXT2(_L("\tstring = \"%S\""), &string);
+	LEAVEIFERRORL(aMessage.Write(2, string));
+	}
+
+void CFdfSession::GetOtgDeviceDescriptor(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+	
+	TOtgDescriptor otgDesc;
+	const TUint deviceId = aMessage.Int0();
+	TRAPD(err, iFdf.GetOtgDeviceDescriptorL(deviceId, otgDesc));	
+	if (KErrNone == err)
+		{
+		TPckg<TOtgDescriptor> buf(otgDesc);
+		err = aMessage.Write(1, buf);
+		}
+	CompleteClient(aMessage, err);
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/src/main.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include <e32base.h>
+#include "fdfserver.h"
+#include <usb/usblogger.h>
+
+static void RunFdfL();
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdf      ");
+#endif
+
+GLDEF_C TInt E32Main()
+	{
+	LOGTEXT(_L8(">>E32Main"));
+
+	TInt ret = KErrNoMemory;
+
+	__UHEAP_MARK;
+
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+
+	if ( cleanup )
+		{
+		// Create the logger object
+#ifdef __FLOG_ACTIVE
+		(void)CUsbLog::Connect();
+#endif
+
+		TRAP(ret, RunFdfL());
+
+#ifdef __FLOG_ACTIVE
+		CUsbLog::Close();
+#endif
+
+		delete cleanup;
+		}
+
+	__UHEAP_MARKEND;
+
+	LOGTEXT2(_L8("<<E32Main ret = %d"), ret);
+	return ret;
+	}
+
+static void RunFdfL()
+	{
+	// Create and install the active scheduler.
+	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
+	CleanupStack::PushL(scheduler);
+	CActiveScheduler::Install(scheduler);
+
+	// Create the server
+	CFdfServer::NewLC();
+
+	// Initialisation complete, now signal the client
+	RProcess::Rendezvous(KErrNone);
+
+	// Ready to run. This only returns when the server is closing down.
+	CActiveScheduler::Start();
+
+	// Clean up the server and scheduler.
+	CleanupStack::PopAndDestroy(2, scheduler);
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/src/utils.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include "utils.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdf      ");
+#endif
+
+#ifdef __FLOG_ACTIVE
+#define LOG Log()
+#else
+#define LOG
+#endif
+
+//*****************************************************************************
+// Code relating to the cleanup stack item which 'Remove's a given TUint from 
+// an RArray.
+
+TArrayRemove::TArrayRemove(RArray<TUint>& aDeviceIds, TUint aDeviceId)
+ :	iDeviceIds(aDeviceIds), 
+	iDeviceId(aDeviceId) 
+	{
+	}
+
+TArrayRemove::~TArrayRemove()
+	{
+	}
+
+void Remove(TAny* aArrayRemove)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	TArrayRemove* arrayRemove = reinterpret_cast<TArrayRemove*>(aArrayRemove);
+
+	const TUint count = arrayRemove->iDeviceIds.Count();
+	for ( TUint ii = 0 ; ii < count ; ++ii )
+		{
+		if ( arrayRemove->iDeviceIds[ii] == arrayRemove->iDeviceId )
+			{
+			LOGTEXT(_L8("\tmatching device id"));
+			arrayRemove->iDeviceIds.Remove(ii);
+			break;
+			}
+		}
+	}
+
+void CleanupRemovePushL(TArrayRemove& aArrayRemove)
+	{
+	TCleanupItem item(Remove, &aArrayRemove);
+	CleanupStack::PushL(item);
+	}
+
+//*****************************************************************************
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/reference/reffdc/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 2007-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:
+* The reffdc is reference code for creators of FDC plugins to the FDF.
+* It is not part of the normal production or test build in order that it doesn't 
+* interfere with the unit tests.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+PRJ_PLATFORMS
+ARMV5
+
+PRJ_TESTMMPFILES
+reffdc.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/reference/reffdc/group/reffdc.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2007-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:
+* reffdc.dll Reference FDC plugin for FDF.
+* reffdc.rsc Resource file for ref FDC plugin.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+TARGET			reffdc.dll
+TARGETTYPE		PLUGIN
+// UID2 = 0x10009d8d for ECOM plugins.
+// UID3 = the 'DLL UID' (see resource file)
+UID 			0x10009d8d 0x10282B51
+VENDORID		0x70000001
+
+SOURCEPATH		..\src
+SOURCE			reffdc.cpp
+SOURCE			reffdcmain.cpp
+
+RESOURCE		reffdc.rss
+
+SYSTEMINCLUDE	\epoc32\include
+
+USERINCLUDE		..\inc
+
+LIBRARY 		euser.lib
+LIBRARY			fdcbase.lib
+
+NOEXPORTLIBRARY
+
+#include <usbhost/internal/fdfcaps.mmh>
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/reference/reffdc/inc/reffdc.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#ifndef REFFDC_H
+#define REFFDC_H
+
+#include <e32base.h>
+#include <usbhost/internal/fdcplugin.h>
+#include <usbhost/internal/fdcinterface.h>
+
+NONSHARABLE_CLASS(CRefFdc) : public CFdcPlugin, public MFdcInterfaceV1
+	{
+public:
+	static CRefFdc* NewL(MFdcPluginObserver& aObserver);
+	~CRefFdc();
+
+private:
+	CRefFdc(MFdcPluginObserver& aObserver);
+	void ConstructL();
+	
+private: // from CFdcPlugin
+	TAny* GetInterface(TUid aUid);
+
+private: // from MFdcInterfaceV1
+	TInt Mfi1NewFunction(TUint aDeviceId,
+		const TArray<TUint>& aInterfaces,
+		const TUsbDeviceDescriptor& aDeviceDescriptor,
+		const TUsbConfigurationDescriptor& aConfigurationDescriptor);
+	void Mfi1DeviceDetached(TUint aDeviceId);
+
+private: // utility
+	void NewFunctionL(TUint aDeviceId,
+		const TArray<TUint>& aInterfaces,
+		const TUsbDeviceDescriptor& aDeviceDescriptor,
+		const TUsbConfigurationDescriptor& aConfigurationDescriptor);
+	};
+
+#endif // REFFDC_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/reference/reffdc/src/reffdc.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,166 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include "reffdc.h"
+#include <usb/usblogger.h>
+#include <usbhost/internal/fdcpluginobserver.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "reffdc   ");
+#endif
+
+CRefFdc* CRefFdc::NewL(MFdcPluginObserver& aObserver)
+	{
+	LOG_LINE
+	LOG_STATIC_FUNC_ENTRY
+
+	CRefFdc* self = new(ELeave) CRefFdc(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CRefFdc::~CRefFdc()
+	{
+	LOG_LINE
+	LOG_FUNC
+	}
+
+CRefFdc::CRefFdc(MFdcPluginObserver& aObserver)
+:	CFdcPlugin(aObserver)
+	{
+	}
+
+void CRefFdc::ConstructL()
+	{
+	LOG_FUNC
+	}
+
+TInt CRefFdc::Mfi1NewFunction(TUint aDeviceId,
+		const TArray<TUint>& aInterfaces,
+		const TUsbDeviceDescriptor& aDeviceDescriptor,
+		const TUsbConfigurationDescriptor& aConfigurationDescriptor)
+	{
+	LOG_LINE
+	LOG_FUNC
+	LOGTEXT2(_L8("\t***** Ref FD offered chance to claim one function from device with ID %d"), aDeviceId);
+	(void)aDeviceId;
+
+	TRAPD(err, NewFunctionL(aDeviceId, aInterfaces, aDeviceDescriptor, aConfigurationDescriptor));
+
+	// If any error is returned, RUsbInterface (etc) handles opened from this 
+	// call must be closed.
+	LOGTEXT2(_L8("\terr = %d"), err);
+	return err;
+	}
+
+void CRefFdc::NewFunctionL(TUint aDeviceId,
+		const TArray<TUint>& aInterfaces,
+		const TUsbDeviceDescriptor& /*aDeviceDescriptor*/,
+		const TUsbConfigurationDescriptor& /*aConfigurationDescriptor*/)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	// We are obliged to claim the first interface because it has 
+	// interface class/subclass(/protocol) settings matching our default_data 
+	// field.
+	// We must take further interfaces until we have claimed a single complete 
+	// function. We must do this regardless of any error that occurs.
+	TUint32 token = Observer().TokenForInterface(aInterfaces[0]);
+	// The token may now be used to open a RUsbInterface handle.
+	(void)token;
+
+	// aDeviceDescriptor is accurate but currently useless. FDCs may not 
+	// 'reject' a device on any basis.
+
+	// aConfigurationDescriptor may be walked to find interface descriptors 
+	// matching interface numbers in aInterfaces.
+
+	// Illustrate how string descriptors may be obtained for 
+	// subsystem-specific purposes.
+	const RArray<TUint>& langIds = Observer().GetSupportedLanguagesL(aDeviceId);
+	const TUint langCount = langIds.Count();
+	LOGTEXT2(_L8("\tdevice supports %d language(s):"), langCount);
+	for ( TUint ii = 0 ; ii < langCount ; ++ii )
+		{
+		LOGTEXT2(_L8("\t\tlang code: 0x%04x"), langIds[ii]);
+		TName string;
+		TInt err = Observer().GetManufacturerStringDescriptor(aDeviceId, langIds[ii], string);
+		if ( !err )
+			{
+			LOGTEXT2(_L("\t\t\tmanufacturer string descriptor = \"%S\""), &string);
+			err = Observer().GetProductStringDescriptor(aDeviceId, langIds[ii], string);
+			if ( !err )
+				{
+				LOGTEXT2(_L("\t\t\tproduct string descriptor = \"%S\""), &string);
+				err = Observer().GetSerialNumberStringDescriptor(aDeviceId, langIds[ii], string);
+				if ( !err )
+					{
+					LOGTEXT2(_L("\t\t\tserial number string descriptor = \"%S\""), &string);
+					}
+				else
+					{
+					LOGTEXT2(_L("\t\t\tGetSerialNumberStringDescriptor returned %d"), err);
+					}
+				}
+			else
+				{
+				LOGTEXT2(_L("\t\t\tGetProductStringDescriptor returned %d"), err);
+				}
+			}
+		else
+			{
+			LOGTEXT2(_L("\t\t\tGetManufacturerStringDescriptor returned %d"), err);
+			}
+		}
+	}
+
+void CRefFdc::Mfi1DeviceDetached(TUint aDeviceId)
+	{
+	LOG_LINE
+	LOG_FUNC
+	LOGTEXT2(_L8("\t***** Ref FD notified of detachment of device with ID %d"), aDeviceId);
+	(void)aDeviceId;
+
+	// Any RUsbInterface (etc) handles opened as a result of any calls to 
+	// MfiNewFunction with this device ID should be closed.
+	}
+
+TAny* CRefFdc::GetInterface(TUid aUid)
+	{
+	LOG_LINE
+	LOG_FUNC;
+	LOGTEXT2(_L8("\taUid = 0x%08x"), aUid);
+
+	TAny* ret = NULL;
+	if ( aUid == TUid::Uid(KFdcInterfaceV1) )
+		{
+		ret = reinterpret_cast<TAny*>(
+			static_cast<MFdcInterfaceV1*>(this)
+			);
+		}
+
+	LOGTEXT2(_L8("\tret = [0x%08x]"), ret);
+	return ret;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/reference/reffdc/src/reffdc.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include <ecom/RegistryInfo.rh>
+#include <usbhost/internal/fdcplugin.hrh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x10282B51;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = KFdcEcomInterfaceUid;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x10282B52;
+					version_no = 1;
+					display_name = "REFERENCE FDC";
+					default_data = "reference field";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/reference/reffdc/src/reffdcmain.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include <ECom/ImplementationProxy.h>
+#include "reffdc.h"
+
+const TImplementationProxy ImplementationTable[] =
+	{
+	IMPLEMENTATION_PROXY_ENTRY(0x10282B52, CRefFdc::NewL),
+	};
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+	{
+	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+
+	return ImplementationTable;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/fdf_over_dummyusbdi/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 2007-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:
+* The production bld.inf for the FDF builds ARMV5 targets only.
+* This bld.inf builds, for WINSCW and ARMV5, variants of the FDF executables 
+* which run over the dummy USBDI.
+* The production build must have been done before building from this bld.inf. 
+* The dummy USBDI must also have been built.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "../../production/fdcbase/group/fdcbase_over_dummyusbdi_bld.inf"
+#include "../../production/server/group/fdf_over_dummyusbdi_bld.inf"
+#include "../../production/client/group/usbhoststack_over_dummyusbdi_bld.inf"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/t_fdf/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* Copyright (c) 2007-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:
+* NB To run t_fdf successfully, the secure ID check in CFdfServer must be 
+* disabled.
+*
+*/
+
+
+PRJ_PLATFORMS
+ARMV5
+
+PRJ_TESTMMPFILES
+t_fdf.mmp
+
+PRJ_TESTEXPORTS
+t_fdf.iby				/epoc32/rom/include/t_fdf.iby
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/t_fdf/FdfTest.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,391 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "fdftest.h"
+#include "testmanager.h"
+#include <usb/usblogger.h>
+#include <e32cmn.h>
+
+#include <d32usbdi_hubdriver.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdftest      ");
+#endif
+//--------------------------------
+
+CActiveNotifyDeviceEvent::CActiveNotifyDeviceEvent(RUsbHostStack& aUsbHostStack,
+												   MNotifyDeviceEventObserver& aObserver,
+												   TDeviceEventInformation& aDeviceEventInformation)
+:	CActive(CActive::EPriorityStandard),
+	iUsbHostStack(aUsbHostStack),
+	iObserver(aObserver),
+	iDeviceEventInformation(aDeviceEventInformation)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CActiveNotifyDeviceEvent::~CActiveNotifyDeviceEvent()
+	{
+	Cancel();
+	}
+
+CActiveNotifyDeviceEvent* CActiveNotifyDeviceEvent::NewL(RUsbHostStack& aUsbHostStack,
+														 MNotifyDeviceEventObserver& aObserver,
+														 TDeviceEventInformation& aDeviceEventInformation)
+	{
+	CActiveNotifyDeviceEvent* self = new(ELeave) CActiveNotifyDeviceEvent(aUsbHostStack,
+		aObserver,
+		aDeviceEventInformation);
+	return self;
+	}
+
+void CActiveNotifyDeviceEvent::Post()
+	{
+	iUsbHostStack.NotifyDeviceEvent(iStatus, iDeviceEventInformation);
+	SetActive();
+	}
+
+void CActiveNotifyDeviceEvent::RunL()
+	{
+	iObserver.MndeoDeviceEvent();
+
+	// We don't want to get into an infinite loop if the FDF dies.
+	if ( iStatus.Int() != KErrServerTerminated )
+		{
+		Post();
+		}
+	}
+
+void CActiveNotifyDeviceEvent::DoCancel()
+	{
+	iUsbHostStack.NotifyDeviceEventCancel();
+	}
+
+//--------------------------------
+
+CActiveNotifyDevmonEvent::CActiveNotifyDevmonEvent(RUsbHostStack& aUsbHostStack,
+												   MNotifyDevmonEventObserver& aObserver,
+												   TInt& aEvent)
+:	CActive(CActive::EPriorityStandard),
+	iUsbHostStack(aUsbHostStack),
+	iObserver(aObserver),
+	iEvent(aEvent)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CActiveNotifyDevmonEvent::~CActiveNotifyDevmonEvent()
+	{
+	Cancel();
+	}
+
+CActiveNotifyDevmonEvent* CActiveNotifyDevmonEvent::NewL(RUsbHostStack& aUsbHostStack,
+														 MNotifyDevmonEventObserver& aObserver,
+														 TInt& aEvent)
+	{
+	CActiveNotifyDevmonEvent* self = new(ELeave) CActiveNotifyDevmonEvent(aUsbHostStack,
+		aObserver,
+		aEvent);
+	return self;
+	}
+
+void CActiveNotifyDevmonEvent::Post()
+	{
+	iUsbHostStack.NotifyDevmonEvent(iStatus, iEvent);
+	SetActive();
+	}
+
+void CActiveNotifyDevmonEvent::RunL()
+	{
+	iObserver.MndeoDevmonEvent();
+
+	// We don't want to get into an infinite loop if the FDF dies.
+	if ( iStatus.Int() != KErrServerTerminated )
+		{
+		Post();
+		}
+	}
+
+void CActiveNotifyDevmonEvent::DoCancel()
+	{
+	iUsbHostStack.NotifyDevmonEventCancel();
+	}
+
+//--------------------------------
+
+CFdfTest::CFdfTest(MTestManager& aManager)
+ :	CTestBase(aManager)
+	{
+	}
+
+CTestBase* CFdfTest::NewL(MTestManager& aManager)
+	{
+	CFdfTest* self = new(ELeave) CFdfTest(aManager);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+void CFdfTest::ConstructL()
+	{
+	iNotifyDeviceEvent = CActiveNotifyDeviceEvent::NewL(iUsbHostStack,
+		*this,
+		iDeviceEventInformation);
+	iNotifyDevmonEvent = CActiveNotifyDevmonEvent::NewL(iUsbHostStack,
+		*this,
+		iDevmonEvent);
+	}
+
+CFdfTest::~CFdfTest()
+	{
+	iManager.Write(_L8("CFdfTest::~CFdfTest"));
+
+	delete iNotifyDeviceEvent;
+	delete iNotifyDevmonEvent;
+	iOtgDriver.Close();
+	iUsbHostStack.Close();
+	}
+
+void CFdfTest::ProcessKeyL(TKeyCode aKeyCode)
+	{
+	iManager.Write(_L8("CFdfTest::ProcessKeyL"));
+
+	switch ( aKeyCode )
+		{
+	case '0':
+		{
+		if ( iUsbHostStack.Handle() )
+			{
+			iManager.Write(_L8("\talready connected"));
+			}
+		else
+			{
+
+			iManager.Write(_L8("About to open LDD"));
+			_LIT(KUsbOtgLDDName,"otgdi");
+			TInt err = User::LoadLogicalDevice(KUsbOtgLDDName);
+			if ( (err != KErrNone) && (err != KErrAlreadyExists) )
+				{
+				iManager.Write(_L8("Error %d: Unable to load driver: %S"), err, &KUsbOtgLDDName);
+				LEAVEIFERRORL(err);
+				}
+
+			iManager.Write(_L8("About to open RUsbOtgDriver"));
+			err = iOtgDriver.Open();
+			if (err != KErrNone && err != KErrAlreadyExists)
+				{
+				iManager.Write(_L8("Error %d: Unable to open RUsbOtgDriver session"), err);
+				LEAVEIFERRORL(err);
+				}
+
+			iManager.Write(_L8("About to start OTG stacks"));
+			TInt iLastError = iOtgDriver.StartStacks();
+			if (iLastError != KErrNone)
+				{
+				iManager.Write(_L8("Error %d: Unable to open start OTG stacks"), iLastError);
+				LEAVEIFERRORL(err);
+				}
+
+			TInt errorBus = iOtgDriver.BusRequest();
+			iManager.Write(_L8("Error %d: iOtgDriver.BusRequest()"), errorBus);
+			if (errorBus == KErrNone)
+				{
+				iBusRequested = 1;
+				}
+
+
+			TInt error = iUsbHostStack.Connect();
+			iManager.Write(_L8("\terror = %d"), error);
+			if ( !error )
+				{
+				iManager.Write(_L8("\t Post() to wait for event "));
+				iNotifyDeviceEvent->Post();
+				iNotifyDevmonEvent->Post();
+				iManager.Write(_L8("\t After Post() to wait for event "));
+				}
+			}
+		}
+		break;
+
+	case '1':
+		{
+		TInt err = iUsbHostStack.EnableDriverLoading();
+		iManager.Write(_L8("\terr = %d"), err);
+		}
+		break;
+
+	case '2':
+		iUsbHostStack.DisableDriverLoading();
+		break;
+
+	case '3':
+		iNotifyDeviceEvent->Cancel();
+		iNotifyDevmonEvent->Cancel();
+		iUsbHostStack.Close();
+		break;
+	case '4':
+		if(iBusRequested)
+			{
+			iManager.Write(_L8("Call BusDrop()"));
+			TInt err = iOtgDriver.BusDrop();
+			iManager.Write(_L8("Call BusDrop() err = %d "),err);
+			}
+		else
+			{
+			iManager.Write(_L8("Cannot Call BusDrop() as the bus has not been Requested()"));
+			}
+		break;
+
+	default:
+		iManager.Write(_L8("Unknown selection"));
+		break;
+		}
+	}
+
+void CFdfTest::DisplayTestSpecificMenu()
+	{
+	iManager.Write(_L8("0 - RUsbHostStack::Connect"));
+	iManager.Write(_L8("1 - RUsbHostStack::EnableDriverLoading"));
+	iManager.Write(_L8("2 - RUsbHostStack::DisableDriverLoading"));
+	iManager.Write(_L8("3 - RUsbHostStack::Close"));
+	iManager.Write(_L8("4 - RUsbHostStack::StopBus"));
+
+	}
+
+void CFdfTest::MndeoDeviceEvent()
+	{
+	iManager.Write(_L8("CFdfTest::MndeoDeviceEvent"));
+	iManager.Write(KNullDesC8());
+	iManager.Write(_L8("CFdfTest::MndeoDeviceEvent"));
+
+	// Apologies for the squashed-up output this gives, but this text is no
+	// good if it scrolls off the top of the target board's screen.
+	iManager.Write(_L8("Raw data:"));
+	iManager.Write(_L8("device ID = %d, event type = %d, error = %d, driver load status = %d, vid = 0x%04x, pid = 0x%04x"),
+		iDeviceEventInformation.iDeviceId,
+		iDeviceEventInformation.iEventType,
+		iDeviceEventInformation.iError,
+		iDeviceEventInformation.iDriverLoadStatus,
+		iDeviceEventInformation.iVid,
+		iDeviceEventInformation.iPid);
+
+	iManager.Write(_L8("Interpretation:"));
+
+	_LIT8(KAttachment, "Attachment");
+	_LIT8(KDriverLoad, "Driver load");
+	_LIT8(KDetachment, "Detachment");
+	TFixedArray<const TDesC8*, 3> eventType;
+	eventType[EDeviceAttachment] = &KAttachment();
+	eventType[EDriverLoad] = &KDriverLoad();
+	eventType[EDeviceDetachment] = &KDetachment();
+
+	_LIT8(KSuccess, "Success");
+	_LIT8(KPartialSuccess, "Partial success");
+	_LIT8(KFailure, "Failure");
+	TFixedArray<const TDesC8*, 3> driverLoadStatus;
+	driverLoadStatus[EDriverLoadSuccess] = &KSuccess();
+	driverLoadStatus[EDriverLoadPartialSuccess] = &KPartialSuccess();
+	driverLoadStatus[EDriverLoadFailure] = &KFailure();
+
+	switch ( iDeviceEventInformation.iEventType )
+		{
+	case EDeviceAttachment:
+		{
+		iManager.Write(_L8("%S | device %d | error %d"),
+			eventType[iDeviceEventInformation.iEventType],
+			iDeviceEventInformation.iDeviceId,
+			iDeviceEventInformation.iError);
+		}
+		break;
+	case EDriverLoad:
+		iManager.Write(_L8("%S | device %d | %S | error %d"),
+			eventType[iDeviceEventInformation.iEventType],
+			iDeviceEventInformation.iDeviceId,
+			driverLoadStatus[iDeviceEventInformation.iDriverLoadStatus],
+			iDeviceEventInformation.iError);
+		break;
+	case EDeviceDetachment:
+		iManager.Write(_L8("%S | device %d"),
+			eventType[iDeviceEventInformation.iEventType],
+			iDeviceEventInformation.iDeviceId);
+		break;
+	default:
+		iManager.Write(_L8("INVALID iEventType"));
+		return;
+		}
+
+	if ( iDeviceEventInformation.iEventType == EDeviceAttachment && iDeviceEventInformation.iError == KErrNone )
+		{
+		iManager.Write(_L8("VID: 0x%04x, PID: 0x%04x"),
+			iDeviceEventInformation.iVid,
+			iDeviceEventInformation.iPid);
+
+		RArray<TUint> langIds;
+		TInt err = iUsbHostStack.GetSupportedLanguages(iDeviceEventInformation.iDeviceId, langIds);
+		if ( err == KErrNone )
+			{
+			const TUint count = langIds.Count();
+			iManager.Write(_L8("there is/are %d supported language(s)"), count);
+			for ( TUint ii = 0 ; ii < count ; ++ii )
+				{
+				iManager.Write(_L8("using langid %d (index %d)"), langIds[ii], ii);
+
+				TName string;
+
+				TInt err = iUsbHostStack.GetManufacturerStringDescriptor(iDeviceEventInformation.iDeviceId, langIds[ii], string);
+				if ( err == KErrNone )
+					{
+					TBuf8<256> buf;
+					buf.Copy(string);
+					iManager.Write(_L8("manufacturer string descriptor = \"%S\""), &buf);
+					}
+				else
+					{
+					iManager.Write(_L8("GetManufacturerStringDescriptor returned %d"), err);
+					}
+
+				err = iUsbHostStack.GetProductStringDescriptor(iDeviceEventInformation.iDeviceId, langIds[ii], string);
+				if ( err == KErrNone )
+					{
+					TBuf8<256> buf;
+					buf.Copy(string);
+					iManager.Write(_L8("product string descriptor = \"%S\""), &buf);
+					}
+				else
+					{
+					iManager.Write(_L8("GetProductStringDescriptor returned %d"), err);
+					}
+				}
+			}
+		else
+			{
+			iManager.Write(_L8("GetSupportedLanguages returned %d"), err);
+			}
+		langIds.Close();
+
+		}
+	}
+
+void CFdfTest::MndeoDevmonEvent()
+	{
+	iManager.Write(_L8("CFdfTest::MndeoDevmonEvent"));
+	iManager.Write(KNullDesC8());
+	iManager.Write(_L8("CFdfTest::MndeoDevmonEvent"));
+
+	iManager.Write(_L8("\tdevmon event: %d"), iDevmonEvent);
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/t_fdf/FdfTest.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,138 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef __FDFTEST_H__
+#define __FDFTEST_H__
+
+#include "testbase.h"
+#include "usbhoststack.h"
+#include <d32otgdi.h>
+#include <d32otgdi_errors.h>
+
+class RUsbOtgDriver;
+
+//--------------------------------
+
+NONSHARABLE_CLASS(MNotifyDeviceEventObserver)
+	{
+public:
+	virtual void MndeoDeviceEvent() = 0;
+	};
+
+NONSHARABLE_CLASS(CActiveNotifyDeviceEvent) : public CActive
+	{
+public:
+	static CActiveNotifyDeviceEvent* NewL(RUsbHostStack& aUsbHostStack,
+		MNotifyDeviceEventObserver& aObserver,
+		TDeviceEventInformation& aDeviceEventInformation);
+	~CActiveNotifyDeviceEvent();
+
+public:
+	void Post();
+
+private:
+	CActiveNotifyDeviceEvent(RUsbHostStack& aUsbHostStack,
+		MNotifyDeviceEventObserver& aObserver,
+		TDeviceEventInformation& aDeviceEventInformation);
+
+private: // from CActive
+	void RunL();
+	void DoCancel();
+
+private: // unowned
+	RUsbHostStack& iUsbHostStack;
+	MNotifyDeviceEventObserver& iObserver;
+	TDeviceEventInformation& iDeviceEventInformation;
+	};
+
+//--------------------------------
+
+NONSHARABLE_CLASS(MNotifyDevmonEventObserver)
+	{
+public:
+	virtual void MndeoDevmonEvent() = 0;
+	};
+
+NONSHARABLE_CLASS(CActiveNotifyDevmonEvent) : public CActive
+	{
+public:
+	static CActiveNotifyDevmonEvent* NewL(RUsbHostStack& aUsbHostStack,
+		MNotifyDevmonEventObserver& aObserver,
+		TInt& aError);
+	~CActiveNotifyDevmonEvent();
+
+public:
+	void Post();
+
+private:
+	CActiveNotifyDevmonEvent(RUsbHostStack& aUsbHostStack,
+		MNotifyDevmonEventObserver& aObserver,
+		TInt& aError);
+
+private: // from CActive
+	void RunL();
+	void DoCancel();
+
+private: // unowned
+	RUsbHostStack& iUsbHostStack;
+	MNotifyDevmonEventObserver& iObserver;
+	TInt& iEvent;
+	};
+
+//--------------------------------
+
+/**
+Test for Function Driver Framework.
+Acts very approximately as USBMAN in the USB Host architecture.
+*/
+class CFdfTest : public CTestBase,
+						public MNotifyDeviceEventObserver,
+						public MNotifyDevmonEventObserver
+	{
+public:
+	static CTestBase* NewL(MTestManager& aManager);
+	~CFdfTest();
+
+private:
+	CFdfTest(MTestManager& aManager);
+	void ConstructL();
+
+private: // from CTestBase
+	void ProcessKeyL(TKeyCode aKeyCode);
+	void DisplayTestSpecificMenu();
+
+private: // from MNotifyDeviceEventObserver
+	void MndeoDeviceEvent();
+
+private: // from MNotifyDevmonEventObserver
+	void MndeoDevmonEvent();
+
+private: // owned
+	// The handle we use when we're pretending to be USBMAN.
+	RUsbHostStack iUsbHostStack;
+
+	//needed because it starts usbdi
+	RUsbOtgDriver iOtgDriver;
+	TInt iBusRequested;
+	CActiveNotifyDeviceEvent* iNotifyDeviceEvent;
+	TDeviceEventInformation iDeviceEventInformation;
+
+	CActiveNotifyDevmonEvent* iNotifyDevmonEvent;
+	TInt iDevmonEvent;
+	};
+
+#endif // __FDFTEST_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/t_fdf/Tests.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef __TESTS_H__
+#define __TESTS_H__
+
+#include "FdfTest.h"
+
+class CTestBase;
+
+struct TTestDefinition
+	{
+	TTestDefinition(const TDesC8& aDescription, CTestBase* (*aFactoryL)(MTestManager&));
+
+	TBuf8<256> iDescription;
+	CTestBase* (*iFactoryL)(MTestManager&);
+	};
+
+TTestDefinition::TTestDefinition(const TDesC8& aDescription, CTestBase* (*aFactoryL)(MTestManager&))
+	{
+	iDescription = aDescription;
+	iFactoryL = aFactoryL;
+	}
+
+TTestDefinition gTestDefinitions[] = 
+	{
+		TTestDefinition(_L8("Test 1 (FDF test)"), CFdfTest::NewL),
+	};
+
+#endif // __TESTS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/t_fdf/activeconsole.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,317 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include <e32twin.h>
+#include <e32svr.h>
+#include "activeconsole.h"
+#include "testbase.h"
+#include "tests.h"
+
+CActiveConsole::CActiveConsole(CConsoleBase& aConsole)
+ :	CActive(CActive::EPriorityStandard),
+	iConsole(aConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CActiveConsole* CActiveConsole::NewLC(CConsoleBase& aConsole)
+	{
+	CActiveConsole* self = new(ELeave) CActiveConsole(aConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	self->DisplayMainMenu();
+	return self;
+	}
+
+void CActiveConsole::ConstructL()
+	{
+	// Launch of FDTest test.
+	iTest = gTestDefinitions[0].iFactoryL(*this);
+	}
+
+CActiveConsole::~CActiveConsole()
+	{
+	Cancel();
+
+	StopCurrentTest();
+	}
+
+void CActiveConsole::DoCancel()
+	{
+	iConsole.ReadCancel();
+	}
+
+void CActiveConsole::StopCurrentTest()
+	{
+	delete iTest;
+	iTest = NULL;
+	}
+
+void CActiveConsole::RunL()
+// Only process when we get a return, otherwise cache- i.e. support multi-character selections
+	{
+	DoActionKeyL(iConsole.KeyCode());
+
+	// Repost asynchronous request.
+	RequestCharacter();
+	}
+
+void CActiveConsole::DoActionKeyL(TKeyCode aKeyCode)
+	{
+	WriteNoReturn(_L8("%c"), aKeyCode);
+
+	// Examine the key that just came in.
+	switch ( TUint(aKeyCode) )
+		{
+	case EKeyEscape:
+		{
+		Write(_L8("Exiting"));
+		CActiveScheduler::Stop();
+		return;
+		}
+
+	case EKeyEnter:
+		// Tell the test about what's in the buffer so far, if anything.
+		Write(_L8("You entered \'%S\'"), &iInputBuffer);
+		switch ( iInputBuffer.Length() )
+			{
+		case 0:
+			// Don't pass anything on- nothing to pass on.
+			break;
+
+		case 1:
+			if ( 	iInputBuffer == _L8("S") 
+				||	iInputBuffer == _L8("s") 
+				)
+				{
+				StopCurrentTest();
+				}
+			else
+				{
+				// Tell the test via the old 'single character' interface.
+				// If there is a test, then let it process the key. If there isn't a 
+				// test, we process it to (possibly) create and run a new test object.
+				if ( iTest )
+					{
+					TRAPD(err, iTest->ProcessKeyL((TKeyCode)iInputBuffer[0]));
+					if ( err )
+						{
+						Write(_L8("CTestBase::ProcessKeyL left with %d"), err);
+						StopCurrentTest();
+						}
+					}
+				else
+					{
+					SelectTestL();
+					}
+				}
+			iInputBuffer = KNullDesC8();
+			break;
+		
+		default:
+			// Tell the test via the new 'multi character' interface.
+			// If there is a test, then let it process the key. If there isn't a 
+			// test, we process it to (possibly) create and run a new test object.
+			if ( iTest )
+				{
+				TRAPD(err, iTest->ProcessKeyL(iInputBuffer));
+				if ( err )
+					{
+					Write(_L8("CTestBase::ProcessKeyL left with %d"), err);
+					StopCurrentTest();
+					}
+				}
+			else
+				{
+				SelectTestL();
+				}
+			iInputBuffer = KNullDesC8();
+			break;
+			}
+		DisplayMainMenu();
+		break;
+
+	default:
+		iInputBuffer.Append(aKeyCode);
+		break;
+		}
+	}
+
+void CActiveConsole::RequestCharacter()
+	{
+	iConsole.Read(iStatus);
+	SetActive();
+	}
+
+void CActiveConsole::DisplayMainMenu()
+	{
+	Write(KNullDesC8);
+
+	// If there's a current test, display its step menu. Otherwise, display 
+	// all the available tests.
+	if ( iTest )
+		{
+		iTest->DisplayTestSpecificMenu();
+		Write(_L8("s - stop and close current test"));
+		}
+	else
+		{
+		const TUint numberOfTests = sizeof(gTestDefinitions) / sizeof(TTestDefinition);
+		for ( TUint ii = 0 ; ii < numberOfTests ; ii ++ )
+			{
+			Write(_L8("%d - %S"), ii, &gTestDefinitions[ii].iDescription);
+			}
+		}
+
+	Write(_L8("Escape - exit program"));
+	Write(KNullDesC8);
+ 	}
+
+void CActiveConsole::Write(TRefByValue<const TDesC8> aFmt, ...)
+	{
+	VA_LIST list;
+	VA_START(list, aFmt);
+
+	TBuf8<0x100> buf;
+	buf.AppendFormatList(aFmt, list);
+	TBuf<0x100> wideBuf;
+	wideBuf.Copy(buf);
+	iConsole.Write(wideBuf);
+	iConsole.Write(_L("\n"));
+
+	(void)RDebug::Print(wideBuf);
+	}
+
+void CActiveConsole::WriteNoReturn(TRefByValue<const TDesC8> aFmt, ...)
+	{
+	VA_LIST list;
+	VA_START(list, aFmt);
+
+	TBuf8<0x100> buf;
+	buf.AppendFormatList(aFmt, list);
+	TBuf<0x100> wideBuf;
+	wideBuf.Copy(buf);
+	iConsole.Write(wideBuf);
+
+	(void)RDebug::Print(wideBuf);
+	}
+
+TKeyCode CActiveConsole::Getch()
+	{
+	return iConsole.Getch();
+	}
+
+void CActiveConsole::SelectTestL()
+	{
+	StopCurrentTest();
+
+	// Pick a test out of the global array of tests.
+	const TUint numberOfTests = sizeof(gTestDefinitions) / sizeof (TTestDefinition);
+	TLex8 lex(iInputBuffer);
+	TUint index;
+	TInt err = lex.Val(index);
+
+	if (	err == KErrNone
+		&&	index < numberOfTests
+		)
+		{
+		iTest = gTestDefinitions[index].iFactoryL(*this);
+		}
+	else
+		{
+		Write(_L8("Unknown selection"));
+		}
+	}
+
+void CActiveConsole::TestFinished()
+/**
+ * Called by the test when it has finished. Results in the destruction of the 
+ * test.
+ */
+	{
+	StopCurrentTest();
+	}
+
+TInt CActiveConsole::RunError(TInt aError)
+/**
+ * Called by the Active Scheduler when a RunL in this active object leaves.
+ */
+	{
+	// This actually happens when a test object fails to construct properly.
+	Write(_L8("Error creating test object: %d"), aError);
+
+	iInputBuffer = KNullDesC8();
+	DisplayMainMenu();
+
+	// It's OK to carry on with the program itself, so repost asynchronous 
+	// request.
+	RequestCharacter();
+
+	return KErrNone;
+	}
+
+void CActiveConsole::GetNumberL(TUint& aNumber)
+	{
+	TBuf<12> addrAsText;
+	addrAsText.Zero();
+	if ( aNumber != 0 )
+		{
+		addrAsText.Format(_L("%d"), aNumber);
+		}
+	WriteNoReturn(_L8("Enter a number: "));
+	if ( addrAsText.Length() > 0 )
+		{
+		TBuf8<100> narrowBuf;
+		narrowBuf.Copy(addrAsText);
+		WriteNoReturn(narrowBuf);
+		}
+	TKeyCode code;
+	TBuf<1> character;
+	FOREVER
+		{
+		code = Getch();
+		character.SetLength(0);
+		character.Append(code);
+	
+		// If <CR> finish editing string
+		if (code == 0x0d)
+			break;
+		
+		// if <BS> remove last character
+		if ((code == 0x08)&&(addrAsText.Length() != 0))
+			{
+			WriteNoReturn(_L8("%S"),&character);
+			addrAsText.SetLength((addrAsText.Length()-1));
+			}
+		else
+			{
+			if (addrAsText.Length() < addrAsText.MaxLength())
+				{
+				WriteNoReturn(_L8("%S"),&character);
+				addrAsText.Append(code);
+				}
+			}
+		}
+	//now extract the new address from the string...
+	if( !addrAsText.Length() )
+		{
+		addrAsText.Append('0'); //null string causes TLex::Val to return an error
+		}
+	TLex lex(addrAsText);
+	TInt err = lex.Val(aNumber, EDecimal);
+	(void)User::LeaveIfError(err);
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/t_fdf/activeconsole.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include <e32base.h>
+#include <e32keys.h>
+#include "testmanager.h"
+
+class CTestBase;
+class CConsoleBase;
+
+class CActiveConsole : public CActive, public MTestManager
+/**
+ * Active Object console class. This is the means by which the user interacts 
+ * with the program.
+ */
+	{
+public:
+	static CActiveConsole* NewLC(CConsoleBase& aConsole);
+	~CActiveConsole();
+
+public:
+	void RequestCharacter();
+	TKeyCode Getch();
+
+private:
+	CActiveConsole(CConsoleBase& aConsole);
+	void ConstructL();
+
+private: // utility
+	void SelectTestL();
+	void StopCurrentTest();
+	void DisplayMainMenu();
+	void DoActionKeyL(TKeyCode aKey);
+
+private: // from MTestManager
+	void TestFinished();
+	void Write(TRefByValue<const TDesC8> aFmt, ...);
+	void WriteNoReturn(TRefByValue<const TDesC8> aFmt, ...);
+	void GetNumberL(TUint& aNumber);
+
+private: // from CActive
+	void RunL();
+	void DoCancel();
+	TInt RunError(TInt aError);
+
+private: // owned
+	CTestBase* iTest;
+	TBuf8<10> iInputBuffer;
+
+private: // unowned
+	CConsoleBase& iConsole;
+	};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/t_fdf/activetest.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <e32test.h>
+#include <e32twin.h>
+#include "activeconsole.h"
+
+LOCAL_C void ActiveTestL()
+	{
+	CConsoleBase* console = Console::NewL(_L("ACTIVETEST"), TSize(KConsFullScreen, KConsFullScreen));
+	CleanupStack::PushL(console);
+
+	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
+	CleanupStack::PushL(scheduler);
+	CActiveScheduler::Install(scheduler);
+
+	CActiveConsole* activeConsole = CActiveConsole::NewLC(*console);
+	activeConsole->RequestCharacter();
+	CActiveScheduler::Start();
+	// NB CActiveScheduler::Start only returns when someone somewhere has 
+	// called CActiveScheduler::Stop.
+
+	CleanupStack::PopAndDestroy(2); // activeConsole, scheduler
+
+	console->Printf(_L("\nPress any key"));
+	(void)console->Getch(); // get and ignore character
+	CleanupStack::PopAndDestroy(); // console
+	}
+
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	TRAPD(error, ActiveTestL());
+	__ASSERT_ALWAYS(!error, User::Panic(_L("E32Main"), error));
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return KErrNone;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/t_fdf/t_fdf.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef __TEST_FDF_IBY__
+#define __TEST_FDF_IBY__
+
+#include <ecom.iby>
+
+
+file=ABI_DIR/DEBUG_DIR/t_fdf.exe							t_fdf.exe
+
+
+
+#endif // __TEST_FDF_IBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/t_fdf/t_fdf.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+TARGET			t_fdf.exe
+TARGETTYPE		EXE
+// UID2 = 0x0 for plain exes
+// UID3 = 0
+UID 			0x0 0x101fe1db
+//0x101fe1db to pretend to be usbman
+
+
+// The same capabilities as USBSVR, which uses usbhoststack.lib.
+CAPABILITY		CommDD NetworkControl NetworkServices LocalServices ProtServ
+
+SOURCE			activetest.cpp
+SOURCE			activeconsole.cpp
+SOURCE			testbase.cpp
+SOURCE			FdfTest.cpp
+
+SYSTEMINCLUDE	\epoc32\include
+
+LIBRARY			EUSER.LIB
+LIBRARY			usbhoststack.lib
+
+//MACRO	__TEST_FDF__
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/t_fdf/testbase.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "testbase.h"
+#include "testmanager.h"
+
+CTestBase::CTestBase(MTestManager& aManager)
+ :	iManager(aManager)
+	{
+	}
+
+CTestBase::~CTestBase()
+	{
+	}
+
+void CTestBase::ProcessKeyL(TKeyCode /*aKeyCode*/)
+	{
+	}
+
+void CTestBase::ProcessKeyL(const TDesC8& /*aString*/)
+	{
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/t_fdf/testbase.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef __TESTBASE_H__
+#define __TESTBASE_H__
+
+#include <e32base.h>
+#include <e32keys.h>
+
+class MTestManager;
+
+#define LeaveIfErrorL(aError) \
+	{ \
+	if ( aError ) \
+		{ \
+		iManager.Write(_L8("LEAVE: line %d, code %d"), __LINE__, aError); \
+		User::Leave(aError); \
+		} \
+	} 
+
+class CTestBase : public CBase
+/**
+ * Abstract base class for tests.
+ */
+	{
+public:
+	CTestBase(MTestManager& aManager);
+	~CTestBase();
+
+public:
+	// Tests may implement either of these to pick up user selections. 
+	// Single-key entries require you to implement the TKeyCode overload; 
+	// multi-key selections require you to implement the descriptor overload.
+	virtual void ProcessKeyL(TKeyCode aKeyCode);
+	virtual void ProcessKeyL(const TDesC8& aString);
+
+	virtual void DisplayTestSpecificMenu() = 0;
+
+protected: // unowned
+	MTestManager& iManager;
+	};
+
+#endif // __TESTBASE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/test/t_fdf/testmanager.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef __TESTMANAGER_H__
+#define __TESTMANAGER_H__
+
+#include <e32std.h>
+#include <e32keys.h>
+
+class MTestManager
+	{
+public:
+	/**
+	Called when a test finishes.
+	*/
+	virtual void TestFinished() = 0;
+
+	/**
+	Called to display some text.
+	*/
+	virtual void Write(TRefByValue<const TDesC8> aFmt, ...) = 0;
+	virtual void WriteNoReturn(TRefByValue<const TDesC8> aFmt, ...) = 0;
+
+	/**
+	Read a user-inputted number.
+	aNumber should be initialised before calling.
+	*/
+	virtual void GetNumberL(TUint& aNumber) = 0;
+	};
+
+#endif // __TESTMANAGER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,20 @@
+/*
+* 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 "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 "msmm/group/bld.inf"
+#include "msfdc/group/bld.inf"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,34 @@
+/*
+* 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 "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
+*/
+
+PRJ_PLATFORMS
+ARMV5
+
+
+PRJ_MMPFILES
+
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST) && !defined(WINS) && !defined(X86GCC)
+msfdc.mmp
+#endif
+
+PRJ_EXPORTS
+msfdc.iby				/epoc32/rom/include/msfdc.iby
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/group/msfdc.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef __MSFDC_IBY__
+#define __MSFDC_IBY__
+
+#include <ecom.iby>
+#ifdef _DEBUG
+ECOM_PLUGIN_UDEB(msfdc.dll, msfdc.rsc)
+#else
+ECOM_PLUGIN(msfdc.dll, msfdc.rsc)
+#endif
+
+#endif // __MSFDC_IBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/group/msfdc.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,50 @@
+/*
+* 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 "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:
+* msfdc.dll Mass Storage FDC plugin for FDF.
+* msfdc.rsc Resource file for Mass Storage FDC plugin.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+TARGET			msfdc.dll
+TARGETTYPE		PLUGIN
+// UID2 = 0x10009d8d for ECOM plugins.
+// UID3 = the 'DLL UID' (see resource file)
+UID 			0x10009d8d 0x10285B0C
+
+SOURCEPATH		../src
+SOURCE			msfdc.cpp
+SOURCE			msfdcmain.cpp
+
+RESOURCE		msfdc.rss
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+USERINCLUDE		../inc
+USERINCLUDE		../../msmm/client/public
+USERINCLUDE		../../msmm/server/public
+
+LIBRARY 		euser.lib 
+
+LIBRARY			fdcbase.lib msmmsession.lib usbdescriptors.lib usbdi_utils.lib
+
+NOEXPORTLIBRARY
+
+#include <usbhost/internal/fdfcaps.mmh>
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/inc/msfdc.h	Tue Feb 02 02:02:59 2010 +0200
@@ -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 "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
+*/
+
+#ifndef MSFDC_H
+#define MSFDC_H
+
+#include <e32base.h>
+#include <usbhost/internal/fdcplugin.h>
+#include <usbhost/internal/fdcinterface.h>
+#include "msmmclient.h"
+
+/**
+  The CMsFdc class
+ 
+  Implements FDC that sends attach/disattach notifications to Mass
+  Storage Mount Manager.
+ */
+NONSHARABLE_CLASS(CMsFdc) : public CFdcPlugin, public MFdcInterfaceV1
+	{
+
+public:
+	static CMsFdc* NewL(MFdcPluginObserver& aObserver);
+	~CMsFdc();
+
+
+private:
+	CMsFdc(MFdcPluginObserver& aObserver);
+	void ConstructL();
+
+private: // from CFdcPlugin
+	TAny* GetInterface(TUid aUid);
+	TInt GetDefaultLanguageL(TUint aDeviceId, TUint& aDefaultLangId);
+
+private: // from MFdcInterfaceV1
+	TInt Mfi1NewFunction(TUint aDeviceId,
+		const TArray<TUint>& aInterfaces,
+		const TUsbDeviceDescriptor& aDeviceDescriptor,
+		const TUsbConfigurationDescriptor& aConfigurationDescriptor);
+	void Mfi1DeviceDetached(TUint aDeviceId);
+private:
+	RMsmmSession iMsmmSession;
+	};
+
+#endif // MSFDC_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/inc/utils.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,102 @@
+/*
+* 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 "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:
+* Utilities for server. (These depend on the logger.)
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <e32base.h>
+#include <ecom/ecom.h>
+#include <usb/usblogger.h>
+
+// In debug, using checking forms of CleanupStack::Pop. In release builds, 
+// use the non-checking form to save a little bit of ROM.
+#ifdef _DEBUG
+#define CLEANUPSTACK_POP1(a)		CleanupStack::Pop(a);
+#define CLEANUPSTACK_POP2(a, b) 	CleanupStack::Pop(a, b);
+#else
+#define CLEANUPSTACK_POP1(a)		CleanupStack::Pop();
+#define CLEANUPSTACK_POP2(a, b) 	CleanupStack::Pop(2);
+#endif // _DEBUG
+
+// What we want for internal programming errors in a server is a set of macros 
+// which, to save effort all round, use __LINE__ as the panic code, and a 
+// file-specific panic category. To make this non-standard pattern as helpful 
+// to users as possible, we append ' line#' to the category. That means we 
+// first have to check that the category is 10 characters long or less, so 
+// that the whole thing is legible to users when it appears on the screen.
+template <TBool> struct ASSERTION_FAILURE;
+TEMPLATE_SPECIALIZATION struct ASSERTION_FAILURE<ETrue>{};
+template <TInt> struct __assertion_test;
+#define COMPILE_ASSERT( B ) void __compile_assert(::__assertion_test<sizeof(::ASSERTION_FAILURE<(B)>)>)
+
+// We want a 10-character string (but allow for the NULL terminator).
+#define PANICCATEGORY(aaa) COMPILE_ASSERT(sizeof(L##aaa)/2 <= 11); _LIT(KPanicCat, aaa) 
+
+// A handy panic-self macro- the category is KPanicCat with " line#" appended; 
+// the code is the line number. 
+#define PANIC_LINENUM \
+	{ \
+	_LIT(KLnNo, " line#"); \
+	TBuf<KMaxExitCategoryName> cat = KPanicCat(); \
+	cat.Append(KLnNo()); \
+	_USB_PANIC(cat, __LINE__); \
+	}
+
+// A handy assertion macro that panics with a locally-defined panic category 
+// and the line number.
+#define ASSERT_ALWAYS(a) \
+	{ \
+	if ( !(a) ) \
+		{ \
+		PANIC_LINENUM; \
+		} \
+	}
+
+#ifdef _DEBUG
+#define ASSERT_DEBUG(a) ASSERT_ALWAYS(a)
+#define DEBUG_PANIC_LINENUM PANIC_LINENUM
+#else
+#define ASSERT_DEBUG(a)
+#define DEBUG_PANIC_LINENUM
+#endif // _DEBUG
+
+// Undefine the e32def.h-defined ASSERT macro to make sure no-one uses it 
+// under the mistaken impression that it's useful. Use our informative one 
+// above instead!
+#undef ASSERT
+
+/**
+Cleanup stack item to remove a given TUint from an RArray.
+*/
+struct TArrayRemove
+	{
+	TArrayRemove(RArray<TUint>& aDeviceIds, TUint aDeviceId);
+	~TArrayRemove();
+	
+	RArray<TUint>& iDeviceIds;
+	const TUint iDeviceId;
+	};
+void CleanupRemovePushL(TArrayRemove& aArrayRemove);
+void Remove(TAny* aArrayRemove);
+
+#endif // UTILS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/src/msfdc.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,299 @@
+/*
+* 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 "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
+*/
+
+#include "msfdc.h"
+#include "utils.h"
+#include <d32usbc.h>
+#include <usbhost/internal/fdcpluginobserver.h>
+#include <d32usbdi.h>
+#include <d32usbdescriptors.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "MsFdc");
+#endif
+/**
+  NewL function of CMsFdc, allocate the memory that needed for instantiating this object.
+ 
+  @param	aObserver   this is a pointer to the Observer object(FDF), MsFdc will get
+                       informations from FDF.
+  @return	A pointer to this CMsFdc object
+ */
+CMsFdc* CMsFdc::NewL(MFdcPluginObserver& aObserver)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CMsFdc* self = new(ELeave) CMsFdc(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	} 
+
+/**
+  Destructor of CMsFdc.
+ */
+CMsFdc::~CMsFdc()
+	{
+	LOG_FUNC
+	
+	iMsmmSession.Disconnect();
+	LOGTEXT(_L("Disconnected to MSMM OK"));
+#ifdef __FLOG_ACTIVE
+	CUsbLog::Close();
+#endif
+	}
+/**
+  Constructor of CMsFdc.
+ */
+CMsFdc::CMsFdc(MFdcPluginObserver& aObserver)
+:	CFdcPlugin(aObserver)
+	{
+	}
+/**
+  The Second phase construction of CMsFdc.
+ */
+void CMsFdc::ConstructL()
+	{
+
+#ifdef __FLOG_ACTIVE
+	CUsbLog::Connect();
+#endif
+	LOG_FUNC
+	
+	//Set up the connection with mount manager
+	TInt error = iMsmmSession.Connect();
+	if ( error )
+		{
+		LOGTEXT2(_L("Failed to connect to MSMM %d"),error);
+		User::Leave(error);
+		}
+	else
+		{
+		LOGTEXT(_L("Connected to MSMM OK"));
+		}
+	}
+/**
+  Get called when FDF is trying to load the driver for Mass Storage Device. 
+ 
+  @param	aDevice  	 				Device ID allocated by FDF for the newly inserted device
+  @param	aInterfaces					The interface array that contains interfaces to be claimed by this FDC
+                                       msfdc just claims the first one in this array.	
+  @param	aDeviceDescriptor			The device descriptor of the newly inserted device.
+  @param	aConfigurationDescriptor	The configuration descriptor of the newly inserted device.
+  @return	Any error that occurred or KErrNone
+ */
+TInt CMsFdc::Mfi1NewFunction(TUint aDeviceId,
+		const TArray<TUint>& aInterfaces,
+		const TUsbDeviceDescriptor& aDeviceDescriptor,
+		const TUsbConfigurationDescriptor& aConfigurationDescriptor)
+	{
+	LOG_FUNC // this is the evidence that the message got through.
+	LOGTEXT2(_L8("\t***** Mass Storage FD notified of device (ID %d) attachment!"), aDeviceId);
+	
+
+	// Mass Storage FDC only claims one interface.
+	LOGTEXT2(_L8("\t***** Mass Storage FD interface to request token is %d"), aInterfaces[0]);
+	TUint32 token = Observer().TokenForInterface(aInterfaces[0]);
+	LOGTEXT2(_L8("\t***** Mass Storage FD tokenInterface  %d"), token);
+	if (token == 0)
+		{
+		LOGTEXT(_L8("\t***** Mass Storage FDC device containing this function is removed."));
+		return KErrGeneral;
+		}
+
+	//Get the languages that is supported by this device.
+	TUint defaultlangid = 0;
+	TRAPD(error, GetDefaultLanguageL(aDeviceId, defaultlangid));
+
+	if (error)
+		{
+		LOGTEXT(_L8("\t***** Mass Storage FDC getting language array failed"));
+		return error;
+		}
+	
+	TUSBMSDeviceDescription* data = NULL;
+	TRAP(error, data = new (ELeave) TUSBMSDeviceDescription);
+	if (error)
+		{
+		LOGTEXT(_L8("\t***** Mass Storage FDC Memory allocation Failed"));		
+		return error;
+		}
+
+	//Get Serial number from string descriptor
+	error = Observer().GetSerialNumberStringDescriptor(aDeviceId, defaultlangid, 
+			data->iSerialNumber);
+	
+	if (error)
+		{
+		LOGTEXT(_L8("\t***** Mass Storage FDC getting Serial Number failed"));
+		delete data;
+		return error;
+		}
+	else
+		{
+		LOGTEXT2(_L("\t***** Mass Storage FDC Serial String is %S"), &data->iSerialNumber);
+		}
+	//Get Product string descriptor
+	error = Observer().GetProductStringDescriptor(aDeviceId, defaultlangid, data->iProductString);
+	
+
+	if (error)
+		{
+		LOGTEXT(_L8("\t***** Mass Storage FDC getting Product string failed"));
+		delete data;
+		return error;
+		}
+	else
+		{
+		LOGTEXT2(_L("\t***** Mass Storage FDC Product String is %S"), &data->iProductString);
+		}
+
+	//Get Manufacturer string descriptor
+	error = Observer().GetManufacturerStringDescriptor(aDeviceId, defaultlangid, 
+			data->iManufacturerString);
+	
+	if (error)
+		{
+		LOGTEXT(_L8("\t***** Mass Storage FDC getting Manufacturer string failed"));
+		delete data;
+		return error;
+		}
+	else
+		{
+		LOGTEXT2(_L("\t***** Mass Storage FDC Manufacturer String is %S"), 
+				&data->iManufacturerString);		
+		}	
+	
+	/************************Remote Wakeup Attribute acquiring***********************/
+	TUint8 attr = aConfigurationDescriptor.Attributes();
+
+	/************************Protocol ID & Transport ID******************************/
+	RUsbInterface interface_ep0;
+    TUsbInterfaceDescriptor ifDescriptor;
+    error = interface_ep0.Open(token);
+    if (error)
+    	{
+		LOGTEXT(_L8("\t***** Mass Storage FDC Open interface handle failed"));
+		delete data;
+		return error;
+    	}
+    else
+    	{
+		LOGTEXT(_L8("\t***** Mass Storage FDC Open interface handle OK"));
+    	}
+
+    error = interface_ep0.GetInterfaceDescriptor(ifDescriptor);
+    if (error)
+    	{
+		LOGTEXT(_L8("\t***** Mass Storage FDC get interface descriptor failed"));
+		interface_ep0.Close();
+		delete data;
+		return error;
+    	}
+    else
+    	{
+		LOGTEXT(_L8("\t***** Mass Storage FDC get interface descriptor OK"));
+    	}
+	
+	/*********************************************************************************/
+	
+	//Send informations to Mass Storage Mount Manager
+	
+	data->iConfigurationNumber   = aDeviceDescriptor.NumConfigurations();
+	data->iBcdDevice             = aDeviceDescriptor.DeviceBcd();
+	data->iDeviceId              = aDeviceId;
+	data->iProductId             = aDeviceDescriptor.ProductId();
+	data->iVendorId              = aDeviceDescriptor.VendorId();
+	
+	/*********************************************************************************/
+	data->iProtocolId  = ifDescriptor.InterfaceSubClass();
+	data->iTransportId = ifDescriptor.InterfaceProtocol();
+	
+	data->iRemoteWakeup = attr&0x20;  	// Bit 5 indicates the remote wakeup feature.
+	data->iIsOtgClient = 0;				// Put 0 into iIsOtgclient for now.
+	/*********************************************************************************/
+
+	//This OTG information may need to be changed when OTG descriptor becomes available.
+	data->iOtgInformation        = aDeviceDescriptor.DeviceBcd();
+	
+	error = iMsmmSession.AddFunction(*data, aInterfaces[0], token);
+	
+	interface_ep0.Close();
+	delete data;
+	return error;
+	}
+/**
+  Get called when FDF unload the function controller of the removed device.
+ 
+  @param	aDeviceId	The device ID that indicates that which device's been removed.
+ */
+void CMsFdc::Mfi1DeviceDetached(TUint aDeviceId)
+	{
+	LOG_FUNC // this is the evidence that the message got through.
+	LOGTEXT2(_L8("\t***** Mass Storage FD notified of device (ID %d) detachment!"), aDeviceId);
+	iMsmmSession.RemoveDevice(aDeviceId);
+
+	}
+
+/**
+  Convert the pointer of this CMsFdc object to a pointer to TAny
+ 
+  @param	aUid	A UID that indicate the interface that is needed..
+  @return	this pointer if aUid equals to the interface uid of CMsFdc or otherwise NULL.
+ */
+TAny* CMsFdc::GetInterface(TUid aUid)
+	{
+	LOG_LINE
+	LOG_FUNC;
+	LOGTEXT2(_L8("\taUid = 0x%08x"), aUid);
+
+	TAny* ret = NULL;
+	if ( aUid == TUid::Uid(KFdcInterfaceV1) )
+		{
+		ret = reinterpret_cast<TAny*>(
+			static_cast<MFdcInterfaceV1*>(this)
+			);
+		}
+
+	LOGTEXT2(_L8("\tret = [0x%08x]"), ret);
+	return ret;
+	}
+/**
+  Get the default language ID that is supported by this Mass Storage device.
+ 
+  @param	aDeviceId		Device ID allocated by FDF
+  @param	aDefaultLangId	The first Language ID that supported by this device.
+  @return	KErrNone is everything is alright or KErrNotFound if the SupportedLanguage of 
+  			the device are unavailable.
+ */
+TInt CMsFdc::GetDefaultLanguageL(TUint aDeviceId, TUint& aDefaultLangId)
+{
+	const RArray<TUint>& languagearray = Observer().GetSupportedLanguagesL(aDeviceId);
+	if (languagearray.Count() <= 0)
+		{
+		return KErrNotFound; 
+		}
+	aDefaultLangId = languagearray[0];
+	return KErrNone;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/src/msfdc.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+/*
+* 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 "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
+*/
+
+#include <ecom/registryinfo.rh>
+#include <usbhost/internal/fdcplugin.hrh>
+
+RESOURCE REGISTRY_INFO theInfo
+{
+dll_uid = 0x10285B0C;
+interfaces =
+	{
+	INTERFACE_INFO
+		{
+		interface_uid = KFdcEcomInterfaceUid;
+		implementations =
+			{
+			IMPLEMENTATION_INFO
+				{
+				implementation_uid = 0x10285B0D;
+				version_no = 1;
+				display_name = "Mass Storage FDC";	
+				default_data = "IC0x08ISC0x06IP0x50";
+				opaque_data = "";
+				}
+			};
+		}
+	};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msfdc/src/msfdcmain.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,44 @@
+/*
+* 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 "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
+*/
+
+#include <ecom/implementationproxy.h>
+#include "msfdc.h"
+
+const TImplementationProxy ImplementationTable[] =
+	{
+	IMPLEMENTATION_PROXY_ENTRY(0x10285B0D, CMsFdc::NewL),
+	};
+/**
+  A factory method that returns the number of implementation of an interfaces
+  and the implementation proxy entry, in the entry the pointer of the factory method 
+  that constructs a CMsFdc is also returned.
+ 
+  @param	aTableCount	A reference of TInt that holds the number of entries in the
+  			implementation proxy entry table.
+  @return	The implementation proxy entry table.
+ */
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+	{
+	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+
+	return ImplementationTable;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/bwins/msmmsession_over_dummycomponentu.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,9 @@
+EXPORTS
+	?Connect@RMsmmSession@@QAEHXZ @ 1 NONAME ; int RMsmmSession::Connect(void)
+	?Disconnect@RMsmmSession@@QAEHXZ @ 2 NONAME ; int RMsmmSession::Disconnect(void)
+	?RemoveDevice@RMsmmSession@@QAEHI@Z @ 3 NONAME ; int RMsmmSession::RemoveDevice(unsigned int)
+	?Version@RMsmmSession@@QBE?AVTVersion@@XZ @ 4 NONAME ; class TVersion RMsmmSession::Version(void) const
+	?__DbgAlloc@RMsmmSession@@QAEHXZ @ 5 NONAME ; int RMsmmSession::__DbgAlloc(void)
+	?__DbgFailNext@RMsmmSession@@QAEHH@Z @ 6 NONAME ; int RMsmmSession::__DbgFailNext(int)
+	?AddFunction@RMsmmSession@@QAEHABVTUSBMSDeviceDescription@@EK@Z @ 7 NONAME ; int RMsmmSession::AddFunction(class TUSBMSDeviceDescription const &, unsigned char, unsigned long)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/eabi/msmmsession_over_dummycomponentu.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,9 @@
+EXPORTS
+	_ZN12RMsmmSession10DisconnectEv @ 1 NONAME
+	_ZN12RMsmmSession10__DbgAllocEv @ 2 NONAME
+	_ZN12RMsmmSession11AddFunctionERK23TUSBMSDeviceDescriptionhm @ 3 NONAME
+	_ZN12RMsmmSession12RemoveDeviceEj @ 4 NONAME
+	_ZN12RMsmmSession13__DbgFailNextEi @ 5 NONAME
+	_ZN12RMsmmSession7ConnectEv @ 6 NONAME
+	_ZNK12RMsmmSession7VersionEv @ 7 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/eabi/msmmsessionu.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,9 @@
+EXPORTS
+	_ZN12RMsmmSession10DisconnectEv @ 1 NONAME
+	_ZN12RMsmmSession10__DbgAllocEv @ 2 NONAME
+	_ZN12RMsmmSession11AddFunctionERK23TUSBMSDeviceDescriptionhm @ 3 NONAME
+	_ZN12RMsmmSession12RemoveDeviceEj @ 4 NONAME
+	_ZN12RMsmmSession13__DbgFailNextEi @ 5 NONAME
+	_ZN12RMsmmSession7ConnectEv @ 6 NONAME
+	_ZNK12RMsmmSession7VersionEv @ 7 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,35 @@
+/*
+* 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 "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
+*/
+
+PRJ_PLATFORMS
+ARMV5 GCCXML
+
+PRJ_MMPFILES
+
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST) && !defined(WINS) && !defined(X86GCC)
+msmmclient.mmp
+#endif
+
+
+PRJ_TESTEXPORTS
+../public/msmmclient.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/hostms/msmmclient.h)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/group/msmmclient.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* 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 "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
+*/
+
+TARGET	msmmsession.dll
+TARGETTYPE	dll
+UID 0x1000008d 0x09A85D84
+
+#include "msmmclient_base.mmp"
+#include <usbhost/internal/fdfcaps.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/group/msmmclient_base.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+/*
+* 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 "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
+*/
+
+#include <usb/usblogger.mmh>
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY	euser.lib
+
+SOURCEPATH ../src
+
+SOURCE msmmclient.cpp
+
+USERINCLUDE ../../inc
+USERINCLUDE ../public
+USERINCLUDE ../../server/public
+
+VENDORID 0x70000001 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/group/msmmclient_over_dummycomponent.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* 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 "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
+*/
+
+
+TARGET		  msmmsession_over_dummycomponent.dll
+TARGETTYPE	  dll
+UID 0x1000008d 0x0F15665A
+
+#include "msmmclient_base.mmp"
+
+CAPABILITY ProtServ WriteDeviceData CommDD DiskAdmin NetworkControl
+
+MACRO	__OVER_DUMMYCOMPONENT__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/public/msmmclient.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,71 @@
+/*
+* 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 "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
+*/
+
+#ifndef MSMMCLIENT_H
+#define MSMMCLIENT_H
+
+#include <e32std.h>
+#include "msmm_pub_def.h"
+
+/**
+RMsmmSession is the interface for MFDC to use the MSMM.
+*/
+NONSHARABLE_CLASS(RMsmmSession) : public RSessionBase
+{
+public: 
+    //  RMsmmSession Implementaion
+    IMPORT_C TInt Connect();
+    IMPORT_C TInt Disconnect();
+    IMPORT_C TVersion Version() const;
+    
+    /** Add USB Mass Storage Function to the MSMM synchronously.
+    @param aDevice Usb Mass Storage device description.
+    @param aInterfaceNumber The Usb Mass Storage interface number.
+    @param aInterfaceToken The Usb Mass Storage interface token.
+    @return Error code of IPC. 
+    */
+    IMPORT_C TInt AddFunction(const TUSBMSDeviceDescription& aDevice,
+            TUint8 aInterfaceNumber,
+            TUint32 aInterfaceToken);
+
+    /** Remove USB Mass Storage device from the MSMM synchronously.
+    @param aDevice Usb Mass Storage device description.
+    @return Error code of IPC.
+    */
+    IMPORT_C TInt RemoveDevice(TUint aDevice);
+
+    // Support for server-side out-of-memory testing. In release, these just
+    // return KErrNone.
+    IMPORT_C TInt __DbgFailNext(TInt aCount);
+    IMPORT_C TInt __DbgAlloc();
+    
+    
+private:
+    // RMsmmSession data member
+    TPckgBuf<TUSBMSDeviceDescription> iDevicePkg;
+    TUint8 iInterfaceNumber;
+    TUint32 iInterfaceToken;
+};
+
+#endif // MSMMCLIENT_H
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/client/src/msmmclient.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,196 @@
+/*
+* 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 "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
+*/
+
+#include "msmmclient.h"
+#include <usb/usblogger.h>
+
+#include <e32cmn.h>
+
+#include "srvdef.h"
+ 
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmClient");
+#endif
+
+// Costants
+const TInt KConnectRetry = 0x2;
+
+//---------------------------------------------------------------------------
+//
+// NON-MEMBER FUNCTIONS
+
+static TInt StartServer()
+    {
+    LOG_STATIC_FUNC_ENTRY
+    
+    TInt ret = KErrNone;
+
+    // Create the server process
+    const TUidType serverUid(KNullUid, KNullUid, KMsmmServUid);
+    RProcess server;
+    _LIT(KNullCommand,"");
+    ret = server.Create(KMsmmServerBinaryName, KNullCommand, serverUid);
+
+    // Was server process created OK?
+    if (KErrNone != ret)
+        {
+        return ret;
+        }
+
+    // Set up Rendezvous so that server thread can signal correct startup
+    TRequestStatus serverDiedRequestStatus;
+    server.Rendezvous(serverDiedRequestStatus);
+
+    // Status flag should still be pending as we haven't 
+    // resumed the server yet!
+    if (serverDiedRequestStatus != KRequestPending)
+        {
+        server.Kill(0); // abort the startup here
+        }
+    else
+        {
+        server.Resume(); // start server
+        }
+
+    User::WaitForRequest(serverDiedRequestStatus);
+
+    // determine the reason for the server exit
+    TInt exitReason = (EExitPanic == server.ExitType()) ? 
+            KErrGeneral : serverDiedRequestStatus.Int();
+    server.Close();
+    return exitReason;
+    }
+
+//---------------------------------------------------------------------------
+// RMsmmSession
+//
+// Public member functions
+
+EXPORT_C TInt RMsmmSession::Connect()
+    {
+    LOG_FUNC
+    
+    TInt retry = KConnectRetry; // Attempt connect twice then give up
+    TInt ret(KErrNone);
+    FOREVER
+        {
+        ret = CreateSession(KMsmmServerName, Version(), KDefaultMessageSlots);
+        if ((KErrNotFound != ret) && (KErrServerTerminated != ret))
+            {
+            break;
+            }
+
+        if ((--retry) == 0)
+            {
+            break;
+            }
+
+        ret = StartServer();
+        if ((KErrNone != ret) && (KErrAlreadyExists != ret))
+            {
+            break;
+            }
+        }
+
+    if (KErrNone != ret)
+        {
+        LOGTEXT2(_L("Underlying error value = %d"), ret)
+        ret = KErrCouldNotConnect;
+        }
+    
+    return ret; 
+    }
+
+EXPORT_C TInt RMsmmSession::Disconnect()
+    {
+    LOG_FUNC
+    
+    Close();
+    return KErrNone;
+    }
+
+// Called to provide the version number of the server we require for this API
+EXPORT_C TVersion RMsmmSession::Version() const
+    {
+    LOG_FUNC
+    
+    return TVersion(KMsmmServMajorVersionNumber,
+                    KMsmmServMinorVersionNumber,
+                    KMsmmServBuildVersionNumber);
+    }
+
+EXPORT_C TInt RMsmmSession::AddFunction(
+        const TUSBMSDeviceDescription& aDevice,
+        TUint8 aInterfaceNumber, TUint32 aInterfaceToken)
+    {
+    LOG_FUNC
+    
+    TInt ret(KErrNone);
+    
+    TIpcArgs usbmsIpcArgs;
+    iDevicePkg = aDevice; // Package the device description
+    usbmsIpcArgs.Set(0, &iDevicePkg);
+    usbmsIpcArgs.Set(1, aInterfaceNumber);
+    usbmsIpcArgs.Set(2, aInterfaceToken);
+
+    ret = SendReceive(EHostMsmmServerAddFunction, usbmsIpcArgs);
+    
+    return ret;
+    }
+
+EXPORT_C TInt RMsmmSession::RemoveDevice(TUint aDevice)
+    {
+    LOG_FUNC
+    
+    TInt ret(KErrNone);
+
+    TIpcArgs usbmsIpcArgs(aDevice);
+
+    ret = SendReceive(EHostMsmmServerRemoveDevice, usbmsIpcArgs);
+    
+    return ret;
+    }
+
+EXPORT_C TInt RMsmmSession::__DbgFailNext(TInt aCount)
+    {
+    LOG_FUNC
+    
+#ifdef _DEBUG
+    return SendReceive(EHostMsmmServerDbgFailNext, TIpcArgs(aCount));
+#else
+    (void)aCount;
+    return KErrNone;
+#endif
+    }
+
+EXPORT_C TInt RMsmmSession::__DbgAlloc()
+    {
+    LOG_FUNC
+    
+#ifdef _DEBUG
+    return SendReceive(EHostMsmmServerDbgAlloc);
+#else
+    return KErrNone;
+#endif
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* 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 "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
+*/
+
+PRJ_PLATFORMS
+ARMV5 GCCXML
+
+#include "../server/group/bld.inf"
+#include "../client/group/bld.inf"
+#include "../referencepolicyplugin/group/bld.inf"
+#include "../refppnotifier/group/bld.inf"
+
+PRJ_EXPORTS
+usbhostmsmm.iby /epoc32/rom/include/usbhostmsmm.iby
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/group/msmm_over_dummycomponent_bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+/*
+* 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 "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
+*/
+
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_TESTMMPFILES
+../server/group/msmmserver_over_dummycomponent.mmp
+../client/group/msmmclient_over_dummycomponent.mmp
+../referencepolicyplugin/group/refpp_over_dummycomponent.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/group/usbhostmsmm.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,35 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef MSMM_IBY
+#define MSMM_IBY
+
+#include <ecom.iby>
+
+#ifndef SYMBIAN_EXCLUDE_MSMM_POLICY_PLUGIN
+#ifdef _DEBUG
+ECOM_PLUGIN_UDEB(referencepolicyplugin.dll, 10285c46.rsc)
+#else
+ECOM_PLUGIN(referencepolicyplugin.dll, 10285c46.rsc)
+#endif
+#endif //SYMBIAN_EXCLUDE_MSMM_POLICY_PLUGIN 
+
+file=ABI_DIR\USB_DIR\msmmsession.dll	        Sys\bin\msmmsession.dll
+file=ABI_DIR\USB_DIR\msmmserver.exe	         	Sys\bin\msmmserver.exe
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/inc/srvdef.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,72 @@
+/*
+* 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 "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
+*/
+
+#ifndef SRVDEF_H
+#define SRVDEF_H
+
+#include <e32base.h>
+
+// Constants
+
+// The MSMM server name
+_LIT(KMsmmServerName, "!MSMM Server");
+
+#ifdef __OVER_DUMMYCOMPONENT__
+_LIT(KMsmmServerBinaryName, "msmmserver_over_dummycomponent.exe");
+// server UID
+const TUid KMsmmServUid = {0x1028653F};
+#else
+/** The MSMM server binary executable file name */
+_LIT(KMsmmServerBinaryName, "msmmserver.exe");
+/** The MSMM server UID */
+const TUid KMsmmServUid = {0x10285c44};
+#endif
+
+#ifdef __OVER_DUMMYCOMPONENT__
+// Just the FDF process can start the MSMM server
+const TUint32 KFDFWSecureId = 0x10285c46; // SID for unit test project
+#else
+const TUint32 KFDFWSecureId = 0x10282B48;
+#endif
+
+/** The Msmm Version numbers */
+const TUint KMsmmServMajorVersionNumber = 1;
+const TUint KMsmmServMinorVersionNumber = 0;
+const TUint KMsmmServBuildVersionNumber = 1;
+
+/** IPC messages supported by the server. */
+enum TServMessage
+    {
+    EHostMsmmServerAddFunction = 0, // Add function request
+    EHostMsmmServerRemoveDevice = 2, // Remove device request
+    EHostMsmmServerDbgFailNext = 3,
+    EHostMsmmServerDbgAlloc = 4,
+    EHostMsmmServerEndMarker // Request end mark
+    };
+
+// Default number of message slots per session
+const TUint KDefaultMessageSlots = 1;
+
+// Max connection number
+const TInt KMaxClientCount = 1;
+
+#endif // #ifndef SRVDEF_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/inc/srvpanic.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,61 @@
+/*
+* 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 "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
+*/
+
+#ifndef SRVPANIC_H
+#define SRVPANIC_H
+
+#include <e32std.h>
+#include <e32cmn.h>
+
+// Constant
+
+// Category
+_LIT(KMsmmPanicServer, "MSMM Server");
+_LIT(KMsmmPanicClient, "MSMM Client");
+
+// Panic number
+enum TMsmmServerPanic
+    {
+    ENoPolicyPlugin = 0x01, // Missing policy plugin when starting server.
+    ENotSupported = 0x02,
+    EServerPanicMark
+    };
+
+enum TMsmmClientPanic
+    {
+    EBadRequest = 0x01,
+    EConnectionExist = 0x02, // Currently there is a connection to server.
+    ENoSupportedVersion = 0x03, // Server can not support this version.
+    EClientPanicMark
+    };
+
+inline void PanicServer(TMsmmServerPanic aPanic)
+    {
+    User::Panic(KMsmmPanicServer, aPanic);
+    }
+
+inline void PanicClient(const RMessage2& aMsg, TMsmmClientPanic aPanic)
+    {
+    aMsg.Panic(KMsmmPanicClient, aPanic);
+    }
+
+#endif /*SRVPANIC_H*/
Binary file usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/conf/usbmanager_10285c46.crml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/data/10285c46.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,52 @@
+/*
+* 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 "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:
+* Reference policy plugin implementation resource file
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <ecom/registryinfo.rh>
+#include <usb/hostms/policyplugin.hrh>
+#include "referenceplugin.hrh"
+
+RESOURCE REGISTRY_INFO theInfo
+    {
+    // UID for the DLL
+    dll_uid = 0x10285c46;
+    // Declare array of interface info
+    interfaces = 
+        {
+        INTERFACE_INFO
+            {
+            // UID of interface that is implemented
+            interface_uid = KUidMountPolicyInterface;
+            implementations = 
+                {
+                IMPLEMENTATION_INFO
+                    {
+                    implementation_uid = KUidMsmmPolicyPluginImp;
+                    version_no         = 1;
+                    display_name       = "Reference Policy Plugin";
+                    default_data       = "ReferencePolicy";
+                    opaque_data        = "";
+                    }
+                };
+            }
+        };
+    }
Binary file usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/data/10285c46.txt has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,39 @@
+/*
+* 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 "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
+*/
+
+PRJ_PLATFORMS
+ARMV5 GCCXML
+
+PRJ_EXPORTS
+// repositories exported for testing purposes
+../data/10285c46.txt /epoc32/release/winscw/udeb/z/private/10202be9/10285c46.txt
+../data/10285c46.txt /epoc32/data/z/private/10202be9/10285c46.txt
+
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST) && !defined(WINS) && !defined(X86GCC)
+
+// ConfML Files
+../conf/usbmanager_10285c46.crml	       OS_LAYER_EXPORTS_CRML(usbmanager_10285c46.crml)
+
+PRJ_MMPFILES
+
+referencepolicyplugin.mmp
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/group/referencepolicyplugin.mmh	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,48 @@
+/*
+* 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 "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
+*/
+
+TARGETTYPE	  PLUGIN
+UID 0x10009D8d 0x10285c46
+
+#include "../../server/public/hostmscaps.mmh"
+#include <usb/usblogger.mmh>
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+SOURCEPATH	  ../src
+SOURCE  proxy.cpp
+SOURCE	referencepolicyplugin.cpp
+SOURCE  refppnotificationman.cpp
+
+
+LIBRARY    euser.lib
+LIBRARY    ecom.lib
+LIBRARY    efsrv.lib
+LIBRARY    centralrepository.lib
+
+USERINCLUDE ../inc
+USERINCLUDE ../../inc
+SOURCEPATH ../data
+
+NOEXPORTLIBRARY
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/group/referencepolicyplugin.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* 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 "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
+*/
+
+TARGET		  referencepolicyplugin.dll
+
+#include <referencepolicyplugin.mmh>
+
+START RESOURCE 10285c46.rss
+	TARGET referencepolicyplugin.rsc
+END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/group/refpp_over_dummycomponent.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* 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 "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
+*/
+
+TARGET		  dummyreferencepolicyplugin.dll
+
+#include <referencepolicyplugin.mmh>
+
+START RESOURCE 10285c46.rss
+	TARGET dummyreferencepolicyplugin.rsc
+END
+
+MACRO   __OVER_DUMMYCOMPONENT__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/inc/referenceplugin.hrh	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* 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 "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
+*/
+
+#ifndef REFERENCELUGIN_HRH
+#define REFERENCELUGIN_HRH
+
+// UID3 for reference policy plugin dll
+#define KUidMsmmPolicyPluginImp 0x10285C4E
+
+#endif /*REFERENCELUGIN_HRH*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/inc/referencepolicyplugin.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,96 @@
+/*
+* 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 "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
+*/
+
+#ifndef REFERENCEPOLICYPLUGIN_H
+#define REFERENCEPOLICYPLUGIN_H
+
+#include <usb/hostms/msmmpolicypluginbase.h>
+#include <f32file.h>
+
+typedef RPointerArray<TPolicyMountRecord> RMountRecordArray;
+
+class CRepository;
+class CMsmmPolicyNotificationManager;
+
+NONSHARABLE_CLASS(CReferencePolicyPlugin) : 
+    public CMsmmPolicyPluginBase
+    {
+public:
+    virtual ~CReferencePolicyPlugin();
+    
+    static CReferencePolicyPlugin* NewL();
+
+    // CMsmmPolicyPluginBase implementation
+    void RetrieveDriveLetterL(TText& aDriveName, 
+            const TPolicyRequestData& aData, TRequestStatus& aStatus);
+    void CancelRetrieveDriveLetter();
+    void SaveLatestMountInfoL(const TPolicyMountRecord& aData, 
+            TRequestStatus& aStatus);
+    void CancelSaveLatestMountInfo();
+    void SendErrorNotificationL(const THostMsErrData& aErrData);
+    void GetSuspensionPolicy(TSuspensionPolicy& aPolicy);
+    
+protected:
+
+    // CActive implementation
+    void DoCancel();
+    void RunL();
+    
+private: // Constructor
+    CReferencePolicyPlugin();
+    void ConstructL();
+
+    void RetrieveDriveLetterL(TText& aDriveName, 
+            const TPolicyRequestData& aData);
+    void SaveLatestMountInfoL(const TPolicyMountRecord& aData);
+    
+    void Complete(TInt aError = KErrNone);
+    
+    // Prepare available drive name list buffer
+    void PrepareAvailableDriveList();
+    // Get available drive names by policy (Forbidden list will be removed)
+    void AvailableDriveListL();
+    // Filter F32 forbidden drive names from available list
+    void FilterFsForbiddenDriveListL(TDriveList& aAvailableNames);
+    // Called to filter the used drive letters
+    void FindFirstNotUsedDriveLetter(
+            const TDriveList& aAvailableNames,
+            TText& aDriveName);
+    // Retrieve history from CR
+    void RetrieveHistoryL();
+    // Remove all buffered history
+    void ClearHistory();
+    // Search in history array for a logic unit
+    TInt SearchHistoryByLogicUnit(const TPolicyRequestData& aLogicUnit) const;
+
+private:
+    CRepository* iRepository;    // Owned
+    TInt iMaxHistoryRecCount;
+    TDriveList iAvailableDrvList;  // Drive list available by policy
+    RMountRecordArray iHistory;  // Device history
+    TSuspensionPolicy iSuspensionPolicy; // Suspension policy
+    RFs iFs;
+    CMsmmPolicyNotificationManager* iNotificationMan;
+    TRequestStatus* iClientStatus; // No ownership
+    };
+
+#endif /*REFERENCEPOLICYPLUGIN_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/inc/refppnotificationman.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,60 @@
+/*
+* 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 "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
+*/
+
+#ifndef REFPPNOTIFICATIONMAN_H
+#define REFPPNOTIFICATIONMAN_H
+
+#include <e32base.h>
+#include <usb/hostms/msmm_policy_def.h>
+#include <usb/hostms/srverr.h>
+
+typedef RArray<THostMsErrorDataPckg> THostMsErrDataQueue;
+const TInt KMaxResponseStringLen = 16;
+
+NONSHARABLE_CLASS (CMsmmPolicyNotificationManager) : public CActive
+    {
+public:
+    ~CMsmmPolicyNotificationManager();
+    static CMsmmPolicyNotificationManager* NewL();
+    static CMsmmPolicyNotificationManager* NewLC();
+    
+public:
+    void SendErrorNotificationL(const THostMsErrData& aErrData);
+    
+    // CActive implementation
+    void RunL();
+    void DoCancel();
+    
+protected:
+    CMsmmPolicyNotificationManager();
+    void ConstructL();
+    
+private:
+    void SendNotification();
+        
+private:
+    THostMsErrDataQueue iErrorQueue;
+    TBuf8<16> iResponse;
+    RNotifier iNotifier;
+    };
+
+#endif /*REFPPNOTIFICATIONMAN_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/src/proxy.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -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 "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
+*/
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <ecom/implementationproxy.h>
+#include <usb/usblogger.h>
+
+#include "referencepolicyplugin.h"
+#include "referenceplugin.hrh"
+ 
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmRefPP");
+#endif
+
+// Provides a key value pair table, this is used to identify
+// the correct construction function for the requested interface.
+const TImplementationProxy ImplementationTable[] =
+    {
+	IMPLEMENTATION_PROXY_ENTRY(KUidMsmmPolicyPluginImp,
+	        CReferencePolicyPlugin::NewL)
+	};
+
+// Function used to return an instance of the proxy table.
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(
+        TInt& aTableCount)
+    {
+    LOGTEXT(_L(">>ImplementationGroupProxy()"));
+    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+    LOGTEXT(_L("<<ImplementationGroupProxy()"));
+    return ImplementationTable;
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/src/referencepolicyplugin.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,393 @@
+/*
+* 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 "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
+*/
+
+#include "referencepolicyplugin.h"
+#include <centralrepository.h>
+#include <e32std.h>
+#include <usb/usblogger.h>
+#include <usb/hostms/msmm_policy_def.h>
+#include "refppnotificationman.h"
+#include "srvpanic.h"
+ 
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmRefPP");
+#endif
+
+//  Global Variables
+const TUid KHostMsRepositoryUid = {0x10285c46};
+const TUint32 KPermittedRangeUid = 0x00010000;
+const TUint32 KForbiddenListUid = 0x00010001;
+const TUint32 KMaxHistoryCountUid = 0x00010002;
+const TUint32 KOTGCapableSuspendTimeUid = 0x00010003;
+const TUint32 KMediaPollingTimeUid = 0x00010004;
+const TUint32 KHistoryCountUid = 0x00010100;
+const TUint32 KFirstHistoryUid = 0x00010101;
+
+const TUint KHistoryGranularity = 0x8;
+const TUint KPermittedDrvRangeBufLen = 0x3;
+
+CReferencePolicyPlugin::~CReferencePolicyPlugin()
+    {
+    LOG_FUNC
+    Cancel();
+    ClearHistory(); // Remove all buffered history record.
+    delete iRepository;
+    delete iNotificationMan;
+    iFs.Close();
+    }
+
+CReferencePolicyPlugin* CReferencePolicyPlugin::NewL()
+    {
+    LOG_STATIC_FUNC_ENTRY
+    CReferencePolicyPlugin* self = new (ELeave) CReferencePolicyPlugin;
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    
+    return self;
+    }
+
+void CReferencePolicyPlugin::RetrieveDriveLetterL(TText& aDriveName,
+        const TPolicyRequestData& aData, TRequestStatus& aStatus)
+    {
+    LOG_FUNC
+    Cancel();
+    aStatus = KRequestPending;
+    iClientStatus = &aStatus;    
+
+    RetrieveDriveLetterL(aDriveName, aData);
+    // In a licensee owned policy plugin, it shall complete client 
+    // request in RunL() in general 
+    Complete(KErrNone);
+    }
+
+void CReferencePolicyPlugin::CancelRetrieveDriveLetter()
+    {
+    LOG_FUNC
+    Cancel();
+    }
+
+void CReferencePolicyPlugin::SaveLatestMountInfoL(
+        const TPolicyMountRecord& aData, TRequestStatus& aStatus)
+    {
+    LOG_FUNC    
+    Cancel();
+    aStatus = KRequestPending;
+    iClientStatus = &aStatus;
+
+    SaveLatestMountInfoL(aData);
+    // In a licensee owned policy plugin, it shall complete client 
+    // request in RunL() in general 
+    Complete(KErrNone);
+    }
+
+void CReferencePolicyPlugin::CancelSaveLatestMountInfo()
+    {
+    LOG_FUNC
+    Cancel();
+    }
+
+void CReferencePolicyPlugin::SendErrorNotificationL(
+        const THostMsErrData& aErrData)
+    {
+    LOG_FUNC
+    iNotificationMan->SendErrorNotificationL(aErrData);
+    }
+
+void CReferencePolicyPlugin::GetSuspensionPolicy(TSuspensionPolicy& aPolicy)
+    {
+    LOG_FUNC
+    aPolicy = iSuspensionPolicy;
+    }
+
+void CReferencePolicyPlugin::DoCancel()
+    {
+    LOG_FUNC
+    // No more work need to do in current implementation of reference
+    // policy plugin. 
+    // In a licensee owned policy plugin, it shall complete client 
+    // request here with KErrCancel.
+    }
+
+void CReferencePolicyPlugin::RunL()
+    {
+    LOG_FUNC
+    // No more work need to do in current implementation of reference
+    // policy plugin. 
+    // In a licensee owned policy plugin, it shall complete client 
+    // request here with a proper error code.
+    }
+
+CReferencePolicyPlugin::CReferencePolicyPlugin() :
+CMsmmPolicyPluginBase(),
+iHistory(KHistoryGranularity)
+    {
+    LOG_FUNC
+    CActiveScheduler::Add(this);
+    }
+
+void CReferencePolicyPlugin::ConstructL()
+    {
+    LOG_FUNC
+    iRepository = CRepository::NewL(KHostMsRepositoryUid);
+    User::LeaveIfError(iFs.Connect());
+    iNotificationMan = CMsmmPolicyNotificationManager::NewL();
+    RetrieveHistoryL();
+    AvailableDriveListL();
+    TInt value = 0;
+    User::LeaveIfError(iRepository->Get(
+            KOTGCapableSuspendTimeUid, value));
+    iSuspensionPolicy.iOtgSuspendTime = value;
+    User::LeaveIfError(iRepository->Get(
+            KMediaPollingTimeUid, value));
+    iSuspensionPolicy.iStatusPollingInterval = value;
+    }
+
+void CReferencePolicyPlugin::RetrieveDriveLetterL(TText& aDriveName,
+        const TPolicyRequestData& aData)
+    {
+    LOG_FUNC
+
+    TDriveList availableNames;
+    FilterFsForbiddenDriveListL(availableNames);
+
+    if (!availableNames.Length())
+        {
+        // Not any drive letter available
+        User::Leave(KErrNotFound);
+        }
+
+    // According to REQ8922, When a particular Logical Unit is mounted 
+    // for the first time, RefPP shall always try to allocate an 
+    // available and unused drive letter to it. Only if such a drive letter
+    // can not be found, RefPP shall use the first one in available name
+    // list;
+    
+    // Initialize aDriveName by the first available drive letter
+    aDriveName = availableNames[0];
+    // Find first such drive letter from available letter list. If it can
+    // be found, it will be used.
+    FindFirstNotUsedDriveLetter(availableNames, aDriveName);    
+    // Search history record
+    TInt historyIndex = SearchHistoryByLogicUnit(aData);
+    if (KErrNotFound != historyIndex)
+        {
+        // Find a match one in history
+        const TPolicyMountRecord& history = *iHistory[historyIndex];
+        TInt location = availableNames.Locate(TChar(history.iDriveName));
+        if (KErrNotFound != location)
+            {
+            // And it is available now. RefPP allocate it to the 
+            // LU currently mounted.
+            aDriveName = history.iDriveName;
+            }
+        }
+    }
+
+void CReferencePolicyPlugin::SaveLatestMountInfoL(
+        const TPolicyMountRecord& aData)
+    {
+    LOG_FUNC
+
+    if (iMaxHistoryRecCount == 0) // This policy disable history
+        {
+        return;
+        }
+    
+    TPolicyMountRecord* historyRecord = 
+            new (ELeave) TPolicyMountRecord(aData);
+    CleanupStack::PushL(historyRecord);
+    TInt historyIndex = SearchHistoryByLogicUnit(aData.iLogicUnit);
+    if (KErrNotFound == historyIndex)
+    	{
+        // No matched record exist
+		if (iHistory.Count() == iMaxHistoryRecCount)
+			{
+			// Remove the oldest entity
+			delete iHistory[0];
+			iHistory.Remove(0);
+			}
+    	}
+    else
+    	{
+    	// Remove the replaced entity
+    	delete iHistory[historyIndex];
+    	iHistory.Remove(historyIndex);
+    	}
+    iHistory.AppendL(historyRecord); // Push the new entity
+    CleanupStack::Pop(historyRecord);
+
+    TUint32 historyRecordUid = KFirstHistoryUid;
+    User::LeaveIfError(iRepository->Set(KHistoryCountUid, iHistory.Count()));
+    for (TInt index = 0; index < iHistory.Count(); index++)
+        {
+        TPckg<TPolicyMountRecord> historyPckg(*iHistory[index]);
+        User::LeaveIfError(iRepository->Set(historyRecordUid++, historyPckg));
+        }
+    }
+
+void CReferencePolicyPlugin::Complete(TInt aError)
+    {
+    LOG_FUNC
+    User::RequestComplete(iClientStatus, aError);
+    }
+
+void CReferencePolicyPlugin::PrepareAvailableDriveList()
+    {
+    LOG_FUNC
+    iAvailableDrvList.SetLength(KMaxDrives);
+    iAvailableDrvList.Fill(0, KMaxDrives);
+    }
+
+void CReferencePolicyPlugin::AvailableDriveListL()
+    {
+    LOG_FUNC
+    TBuf8<KPermittedDrvRangeBufLen> permittedRange;
+    TDriveList forbiddenList;
+
+    PrepareAvailableDriveList();
+
+    User::LeaveIfError(iRepository->Get(KPermittedRangeUid, permittedRange));
+    User::LeaveIfError(iRepository->Get(KForbiddenListUid, forbiddenList));
+
+    for (TInt index = 'A'; index <= 'Z'; index++ )
+        {
+        if ((index >= permittedRange[0]) && (index <= permittedRange[1]))
+            {
+            if (KErrNotFound == forbiddenList.Locate(TChar(index)))
+                {
+                // Permitted
+                iAvailableDrvList[index - 'A'] = 0x01;
+                }
+            }
+        }
+    }
+
+void CReferencePolicyPlugin::FilterFsForbiddenDriveListL(
+        TDriveList& aAvailableNames)
+    {
+    LOG_FUNC
+    TDriveList names;
+    names.SetLength(KMaxDrives);
+
+    TDriveList drives;
+    User::LeaveIfError(iFs.DriveList(drives));
+
+    TUint count(0);
+    for (TInt index = 0; index < KMaxDrives; index++ )
+        {
+        if ((drives[index] == 0x0) && (iAvailableDrvList[index]))
+            {
+            names[count++] = index+'A';
+            }
+        }
+    names.SetLength(count);
+    aAvailableNames = names;
+    }
+
+void CReferencePolicyPlugin::FindFirstNotUsedDriveLetter(
+        const TDriveList& aAvailableNames,
+        TText& aDriveName)
+    {
+    LOG_FUNC
+    TDriveList usedLetter;
+    TUint index = 0;
+    for (index = 0; index < iHistory.Count(); index++)
+        {
+        const TPolicyMountRecord& record = *iHistory[index];
+        usedLetter.Append(TChar(record.iDriveName));
+        }
+    for (index = 0; index < aAvailableNames.Length(); index++)
+        {
+        if (usedLetter.Locate(aAvailableNames[index]) == KErrNotFound)
+            {
+            aDriveName = aAvailableNames[index];
+            return; // A unused drive letter found out
+            }
+        }
+    }
+
+// Retrieve history from CR
+void CReferencePolicyPlugin::RetrieveHistoryL()
+    {
+    LOG_FUNC
+    // Read history record number from CR
+    TInt historyCount(0);
+    User::LeaveIfError(
+            iRepository->Get(KMaxHistoryCountUid, iMaxHistoryRecCount));
+    User::LeaveIfError(iRepository->Get(KHistoryCountUid, historyCount));
+
+    TUint32 historyRecordUid = KFirstHistoryUid;
+    if (historyCount)
+        {
+        TPolicyMountRecord historyRecord;
+        TPckg<TPolicyMountRecord> historyArray(historyRecord);        
+        for (TInt index = 0; index < historyCount; index++)
+            {
+            User::LeaveIfError(iRepository->Get(historyRecordUid++, 
+                    historyArray));
+            TPolicyMountRecord* record = new (ELeave) TPolicyMountRecord;
+            memcpy(record, &historyRecord, sizeof(TPolicyMountRecord));
+            CleanupStack::PushL(record);
+            iHistory.AppendL(record);
+            CleanupStack::Pop(record);
+            }
+        }
+    }
+
+// Remove all buffered history
+void CReferencePolicyPlugin::ClearHistory()
+    {
+    LOG_FUNC
+    iHistory.ResetAndDestroy();
+    iHistory.Close();
+    }
+
+// Search in history for a logic unit	
+TInt CReferencePolicyPlugin::SearchHistoryByLogicUnit(
+        const TPolicyRequestData& aLogicUnit) const
+    {
+    LOG_FUNC
+    TInt ret(KErrNotFound);
+    TUint count = iHistory.Count();
+    for (TUint index = 0; index < count; index ++)
+        {
+        const TPolicyMountRecord& record = *iHistory[index];
+        const TPolicyRequestData& logicalUnit = record.iLogicUnit;
+
+        if ((logicalUnit.iVendorId == aLogicUnit.iVendorId) &&
+                (logicalUnit.iProductId == aLogicUnit.iProductId) &&
+                (logicalUnit.iBcdDevice == aLogicUnit.iBcdDevice) &&
+                (logicalUnit.iConfigurationNumber == aLogicUnit.iConfigurationNumber) &&
+                (logicalUnit.iInterfaceNumber == aLogicUnit.iInterfaceNumber) &&
+                (logicalUnit.iSerialNumber == aLogicUnit.iSerialNumber) &&
+                (logicalUnit.iOtgInformation == aLogicUnit.iOtgInformation))
+            {
+            // Matched
+            return index;
+            }
+        }
+    // Can't find any matched records
+    return ret;
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/referencepolicyplugin/src/refppnotificationman.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,126 @@
+/*
+* 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 "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
+*/
+
+#include "refppnotificationman.h"
+#include <usb/usblogger.h>
+#include <usb/hostms/policypluginnotifier.hrh>
+#include "srvpanic.h"
+
+ 
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmRefPP");
+#endif
+
+#ifdef __OVER_DUMMYCOMPONENT__
+const TUid KMountPolicyNotifierUid = {0x1028653E};
+#else
+const TUid KMountPolicyNotifierUid = {KUidMountPolicyNotifier};
+#endif
+
+CMsmmPolicyNotificationManager::~CMsmmPolicyNotificationManager()
+    {
+    LOG_FUNC
+    Cancel();
+    iErrorQueue.Close();
+    iNotifier.Close();
+    }
+
+CMsmmPolicyNotificationManager* CMsmmPolicyNotificationManager::NewL()
+    {
+    LOG_STATIC_FUNC_ENTRY
+    CMsmmPolicyNotificationManager* self = 
+        CMsmmPolicyNotificationManager::NewLC();
+    CleanupStack::Pop(self);
+    
+    return self;
+    }
+
+CMsmmPolicyNotificationManager* CMsmmPolicyNotificationManager::NewLC()
+    {
+    LOG_STATIC_FUNC_ENTRY
+    CMsmmPolicyNotificationManager* self = 
+        new (ELeave) CMsmmPolicyNotificationManager();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    
+    return self;
+    }
+
+void CMsmmPolicyNotificationManager::SendErrorNotificationL(
+        const THostMsErrData& aErrData)
+    {
+    LOG_FUNC
+
+    // Print error notification data to log
+    LOGTEXT2(_L("Err:iError = %d"), aErrData.iError);
+    LOGTEXT2(_L("Err:iE32Error = %d"), aErrData.iE32Error);
+    LOGTEXT2(_L("Err:iDriveName = %d"), aErrData.iDriveName);
+    LOGTEXT2(_L("Err:iManufacturerString = %S"), &aErrData.iManufacturerString);
+    LOGTEXT2(_L("Err:iProductString = %S"), &aErrData.iProductString);
+    
+    THostMsErrorDataPckg errPckg = aErrData;
+    iErrorQueue.AppendL(errPckg);
+    if (!IsActive())
+    	{
+    	SendNotification();
+    	}
+    }
+
+void CMsmmPolicyNotificationManager::RunL()
+    {
+    LOG_FUNC
+    iErrorQueue.Remove(0);
+    if (iErrorQueue.Count() > 0)
+        {
+        SendNotification();
+        }
+    }
+
+void CMsmmPolicyNotificationManager::DoCancel()
+    {
+    LOG_FUNC
+    iErrorQueue.Reset();
+    iNotifier.CancelNotifier(KMountPolicyNotifierUid);
+    }
+
+CMsmmPolicyNotificationManager::CMsmmPolicyNotificationManager():
+CActive(EPriorityStandard)
+    {
+    LOG_FUNC
+    CActiveScheduler::Add(this);
+    }
+
+void CMsmmPolicyNotificationManager::ConstructL()
+    {
+    LOG_FUNC
+    User::LeaveIfError(iNotifier.Connect());
+    }
+
+void CMsmmPolicyNotificationManager::SendNotification()
+    {
+    LOG_FUNC
+    iNotifier.StartNotifierAndGetResponse(
+        iStatus, KMountPolicyNotifierUid, iErrorQueue[0], iResponse);
+    SetActive();
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* 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 "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
+*/
+
+PRJ_PLATFORMS
+ARMV5 GCCXML
+
+PRJ_TESTEXPORTS
+refppnotifier.iby  /epoc32/rom/include/refppnotifier.iby
+
+PRJ_TESTMMPFILES
+
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST) && !defined(WINS) && !defined(X86GCC)
+refppnotifier.mmp
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/group/refppnotifier.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,35 @@
+/*
+* 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 "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
+*/
+
+#ifndef __REFPPNOTIFIER_IBY__
+#define __REFPPNOTIFIER_IBY__
+
+#include <ecom.iby>
+#ifdef _DEBUG
+ECOM_PLUGIN_UDEB(refppnotifier.dll, refppnotifier.rsc)
+#else
+ECOM_PLUGIN(refppnotifier.dll, refppnotifier.rsc)
+#endif
+
+data=DATAZ_\resource\apps\dialog.rsc		"\resource\apps\dialog.rsc"
+
+#endif // __REFPPNOTIFIER_IBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/group/refppnotifier.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -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 "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
+*/
+ 
+TARGET		  	refppnotifier.dll
+TARGETTYPE	  	PLUGIN
+UID 			0x10009D8D 0x10285ddd
+
+CAPABILITY		ProtServ TrustedUI
+
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+SOURCEPATH	  ../src
+SOURCE  refppnotifier.cpp refppdialog.cpp
+
+RESOURCE		refppnotifier.rss
+
+START RESOURCE 	dialog.rss
+HEADER
+TARGETPATH 		/resource/apps
+END
+
+LIBRARY    euser.lib
+LIBRARY    ecom.lib
+LIBRARY    eikdlg.lib
+LIBRARY    eiksrv.lib
+LIBRARY    eikcoctl.lib
+LIBRARY    cone.lib
+LIBRARY    eikcdlg.lib 
+
+USERINCLUDE ../inc
+
+NOEXPORTLIBRARY
+
+VENDORID 0x70000001 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/inc/refppdialog.h	Tue Feb 02 02:02:59 2010 +0200
@@ -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 "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
+*/
+
+#ifndef CREFPPDIALOG_H
+#define CREFPPDIALOG_H
+
+// INCLUDES
+#include <techview/eikdialg.h>
+// CLASS DECLARATION
+
+/**
+  The CRefPPDialog class
+  This is a subclass derived from CEikDialog, it is used by notifier to display
+  the message of Errors from MS mount manager.
+ */
+class CRefPPDialog : public CEikDialog
+	{
+public:
+
+	~CRefPPDialog();
+	static CRefPPDialog* NewL(TBool* aDlgFlag);
+	static CRefPPDialog* NewLC(TBool* aDlgFlag);
+
+private:
+
+	CRefPPDialog(TBool* aDlgFlag);
+	void ConstructL();
+protected:
+	virtual TBool OkToExitL(TInt aButtonId);
+private:
+	TBool* iDlgFlagInOwner;
+
+	}; // class CRefPPDialog
+
+#endif // CREFPPDIALOG_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/inc/refppnotifier.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,67 @@
+/*
+* 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 "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
+*/
+
+#ifndef REFPPNOTIFIER_H
+#define REFPPNOTIFIER_H
+
+#include <techview/eikdialg.h>
+#include <eiknotapi.h>
+#include "refppdialog.h"
+
+/**
+  The CMsmmRefPolicyPluginNotifier class
+  This is a subclass derived from MEikSrvNotifierBase2, it is used as a ECOM
+  plug-in of notify service to provide the function of showing a dialog when 
+  error occured in MS mount manager.
+ */
+NONSHARABLE_CLASS (CMsmmRefPolicyPluginNotifier) : public MEikSrvNotifierBase2
+    {
+public:
+	~CMsmmRefPolicyPluginNotifier();
+	static CMsmmRefPolicyPluginNotifier* NewL();
+	static CMsmmRefPolicyPluginNotifier* NewLC();
+	
+public:
+    
+    // from MEikSrvNotifierBase2
+	void Release();
+	TNotifierInfo RegisterL();
+	TNotifierInfo Info() const;
+	TPtrC8 StartL(const TDesC8& aBuffer);
+	void StartL(const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage);
+	void Cancel();
+	TPtrC8 UpdateL(const TDesC8& aBuffer);
+	
+private:
+    CMsmmRefPolicyPluginNotifier();
+    void ConstructL();
+    
+private:
+    TNotifierInfo iInfo;
+    RMessagePtr2  iMessage;
+    CCoeEnv* iCoeEnv;
+    TInt iOffset;
+    TBool iDialogIsVisible;
+    CRefPPDialog* iDialogPtr;
+    };
+
+#endif /*REFPPNOTIFIER_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/inc/refppnotifier.hrh	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,35 @@
+/*
+* 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 "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
+*/
+
+#ifndef REFPPNOTIFIER_HRH
+#define REFPPNOTIFIER_HRH
+
+// Implementation UID for reference notifier of Policy plug-in
+#define KUidMsmmReferenceNotifierImp 0x10285DDE
+
+enum
+{
+	EReferencePPNotifierButton,			//ID of button on dialog
+	EReferencePPNotifierMsg			//ID of the label on dialog
+};
+
+#endif /*REFPPNOTIFIER_HRH*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/src/dialog.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,65 @@
+/*
+* 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 "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:
+* Reference policy plugin notifier implementation resource file
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <techview/eikon.rh>
+#include <techview/eikon.rsg>
+#include <techview/techviewctl.rh>
+#include <eikcoctl.rsg>
+#include "refppnotifier.hrh"
+NAME REFN
+
+RESOURCE RSS_SIGNATURE { }
+
+RESOURCE TBUF16 { buf=""; }
+
+RESOURCE DLG_BUTTONS r_dialog_buttons
+{
+buttons = 
+    {
+    DLG_BUTTON
+        {
+        id = EReferencePPNotifierButton;
+        button = CMBUT {txt = "OK";};
+        hotkey='1';
+        }
+    };
+}
+
+RESOURCE DIALOG r_notifier_dialog
+    {
+    title = "MSMM message";
+    buttons = r_dialog_buttons;
+    items = 
+        {
+        DLG_LINE
+            {
+            type = EEikCtLabel;
+            id = EReferencePPNotifierMsg;
+            control = LABEL
+                {
+                standard_font = EEikLabelFontAnnotation;
+                txt = "NULL";
+                };
+            }
+        };
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/src/refppdialog.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,87 @@
+/*
+* 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 "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
+*/
+
+#include "refppdialog.h"
+/**
+  Constructor 
+ */
+CRefPPDialog::CRefPPDialog(TBool* aDlgFlag):iDlgFlagInOwner(aDlgFlag)
+	{
+	}
+/**
+  Destructor
+ */
+CRefPPDialog::~CRefPPDialog()
+	{
+	}
+/**
+  This is a static method used by refppnotifier to initialize a CRefDialog object. 
+ 
+  @param	aDlgFlag  	 	The flag in the owner of this dialog. This flag is used
+                            to indicate if the dialog has been closed by the user
+                            by click the button on the dialog.
+  
+  @return	A pointer to the newly initialized object.
+ */
+CRefPPDialog* CRefPPDialog::NewLC(TBool* aDlgFlag)
+	{
+	CRefPPDialog* self = new (ELeave)CRefPPDialog(aDlgFlag);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+/**
+  This is a static method used by refppnotifier to initialize a CRefDialog object. 
+ 
+  @param	aDlgFlag  	 	The flag in the owner of this dialog. This flag is used
+                            to indicate if the dialog has been closed by the user
+                            by click the button on the dialog.
+  
+  @return	A pointer to the newly initialized object.
+ */
+CRefPPDialog* CRefPPDialog::NewL(TBool* aDlgFlag)
+	{
+	CRefPPDialog* self=CRefPPDialog::NewLC(aDlgFlag);
+	CleanupStack::Pop(self);
+	return self;
+	}
+/**
+  Method for the second phase construction. 
+ */
+void CRefPPDialog::ConstructL()
+	{
+	}
+/**
+  Get called when the dialog is closed by user closing the dialog. Must return ETrue to
+  allow the dialog to close.
+  
+  @param      aButtonId        the button pressed when OkToExitL() is called.
+  
+  @return     TBool            ETrue  to let the dialog close.
+                               EFalse to keep the dialog on screen.      
+  
+ */
+TBool CRefPPDialog::OkToExitL(TInt /*aButtonId*/)
+	{
+	*iDlgFlagInOwner = EFalse;
+	return ETrue;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/src/refppnotifier.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,268 @@
+/*
+* 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 "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
+*/
+
+#include "refppnotifier.h"
+#include <ecom/implementationproxy.h>
+#include "refppnotifier.hrh"
+#include <techview/eikinfo.h>
+#include <dialog.rsg>
+#include <techview/eiklabel.h>
+#include <usb/hostms/srverr.h>
+#include <usb/hostms/policypluginnotifier.hrh>
+const TUid KMsmmRefNotifierChannel = {0x10009D48}; //0x10208C14
+/**
+  Initialize and put the notifiers in this DLL into the array and return it.
+  
+  @return  CArrayPtr<MEikSrvNotifierBase2>*   The array contents the notifiers in this dll.      
+ */
+CArrayPtr<MEikSrvNotifierBase2>* NotifierArray()
+    {
+    CArrayPtrFlat<MEikSrvNotifierBase2>* subjects=NULL;
+    TRAPD(err, subjects = new(ELeave) CArrayPtrFlat<MEikSrvNotifierBase2>(1));
+    if( err == KErrNone )
+        {
+        TRAP(err, subjects->AppendL(CMsmmRefPolicyPluginNotifier::NewL()));
+        return(subjects);
+        }
+    else
+        {
+        return NULL;
+        }
+    }
+
+//Adding ECOM SUPPORT
+/**
+  Build up the table contains the implementation ID and the notifier array.
+ */
+const TImplementationProxy ImplementationTable[] =
+    {
+    IMPLEMENTATION_PROXY_ENTRY(KUidMsmmReferenceNotifierImp, NotifierArray)
+    };
+
+/**
+  Initialize and put the notifiers in this DLL into the array and return it.
+  @param  aTableCount    a TInt reference, when return it contains the entry number in the 
+                             array of ImplementationTable[].
+  @return     CArrayPtr<MEikSrvNotifierBase2>*   The table of implementations.      
+ */
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+    return ImplementationTable;
+    }
+
+// Member functions
+/**
+  Static method to initialize a CMsmmRefPolicyPluginNotifier object. This method may leave. 
+ 
+  @return     CMsmmRefPolicyPluginNotifier*   a pointer to an object of CMsmmRefPolicyPluginNotifier
+ */
+CMsmmRefPolicyPluginNotifier* CMsmmRefPolicyPluginNotifier::NewL()
+    {
+    CMsmmRefPolicyPluginNotifier* self = CMsmmRefPolicyPluginNotifier::NewLC();
+    CleanupStack::Pop(self);
+    return self;
+    }
+/**
+  Static method to initialize a CMsmmRefPolicyPluginNotifier object. This method may leave. 
+
+  @return     CMsmmRefPolicyPluginNotifier*   a pointer to an object of CMsmmRefPolicyPluginNotifier
+ */
+CMsmmRefPolicyPluginNotifier* CMsmmRefPolicyPluginNotifier::NewLC()
+    {
+    CMsmmRefPolicyPluginNotifier* self = new (ELeave) CMsmmRefPolicyPluginNotifier();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+/**
+  Constructor.
+ */
+CMsmmRefPolicyPluginNotifier::CMsmmRefPolicyPluginNotifier():iDialogIsVisible(EFalse),iDialogPtr(0)
+    {
+    iCoeEnv = CCoeEnv::Static();
+    }
+
+/**
+  Destructor.
+ */
+CMsmmRefPolicyPluginNotifier::~CMsmmRefPolicyPluginNotifier()
+    {
+    iCoeEnv->DeleteResourceFile(iOffset);    
+    if (iDialogIsVisible)
+    	{
+    	delete iDialogPtr;
+    	}
+    }
+
+/**
+  This method is called when client of this notifier disconnect from notify server.
+ */
+void CMsmmRefPolicyPluginNotifier::Release()
+    {
+    delete this;
+    }
+
+/**
+  This method is called when notify server starts and get all the plug-ins of notifiers.
+  By calling this method notify server knows the ID, channel and priority of this notifier.
+ */
+MEikSrvNotifierBase2::TNotifierInfo CMsmmRefPolicyPluginNotifier::RegisterL()
+    {
+    iInfo.iUid      = TUid::Uid(KUidMountPolicyNotifier);
+    iInfo.iChannel  = KMsmmRefNotifierChannel;
+    iInfo.iPriority = ENotifierPriorityLow;
+    return iInfo;
+    }
+
+/**
+  This method just returns the same TNotifierInfo as it is in RegisterL().
+ */
+MEikSrvNotifierBase2::TNotifierInfo CMsmmRefPolicyPluginNotifier::Info() const
+    {
+    return iInfo;
+    }
+
+/**
+  Starts the notifier.
+
+   This is called as a result of a client-side call to RNotifier::StartNotifier(), 
+   which the client uses to start a notifier from which it does not expect a response.
+
+   The function is synchronous, but it should be implemented so that it completes as 
+   soon as possible, allowing the notifier framework to enforce its priority mechanism.
+
+   It is not possible to to wait for a notifier to complete before returning from this
+   function unless the notifier is likely to finish implementing its functionality immediately.
+
+  @param   aBuffer    the message sent from client.
+
+  @return      TPtrC8     Defines an empty or null literal descriptor 
+                          for use with 8-bit descriptors
+ */
+TPtrC8 CMsmmRefPolicyPluginNotifier::StartL(const TDesC8& /*aBuffer*/)
+    {
+    return KNullDesC8();
+    }
+/**
+  Starts the notifier.
+
+  This is called as a result of a client-side call to the asynchronous function 
+  RNotifier::StartNotifierAndGetResponse(). This means that the client is waiting, 
+  asynchronously, for the notifier to tell the client that it has finished its work.
+
+  It is important to return from this function as soon as possible, and derived 
+  classes may find it useful to take a copy of the reply-slot number and the 
+  RMessage object.
+
+  The implementation of a derived class must make sure that Complete() is called 
+  on the RMessage object when the notifier is deactivated.
+
+  This function may be called multiple times if more than one client starts 
+  the notifier.
+
+  @param   aBuffer    Data that can be passed from the client-side. The format 
+                          and meaning of any data is implementation dependent. 
+                          
+              aReplySlot  Identifies which message argument to use for the reply. 
+                          This message argument will refer to a modifiable descriptor, 
+                          a TDes8 type, into which data can be returned. The format and 
+                          meaning of any returned data is implementation dependent.
+                          
+             aMessage     Encapsulates a client request. 
+*/
+void CMsmmRefPolicyPluginNotifier::StartL(const TDesC8& aBuffer, 
+                                          TInt /*aReplySlot*/, 
+                                          const RMessagePtr2& aMessage)
+    {
+    // extract the notifier request parameters
+    iMessage   = aMessage;
+
+    const TUint8* Buffer= aBuffer.Ptr();
+    const THostMsErrData* Data = reinterpret_cast<const THostMsErrData*>(Buffer);
+    
+    HBufC16* HeapBuf = HBufC16::NewL(aBuffer.Length());
+    CleanupStack::PushL(HeapBuf);
+    _LIT(KFormat1,"MSMMErr:%d SymbianErr:%d %S %S on Drive %c");
+    TPtr16 PtrBuf = HeapBuf->Des();
+    
+    PtrBuf.Format(KFormat1,Data->iError,Data->iE32Error,&Data->iProductString,&Data->iManufacturerString,Data->iDriveName);
+    
+    if (iDialogIsVisible && iDialogPtr)
+    	{
+    	delete iDialogPtr;
+	    }
+    iDialogPtr = CRefPPDialog::NewL(&iDialogIsVisible);
+    iDialogPtr->PrepareLC(R_NOTIFIER_DIALOG);
+    CEikLabel *pLabel = static_cast<CEikLabel *> (iDialogPtr->ControlOrNull(EReferencePPNotifierMsg));
+    pLabel->SetTextL(PtrBuf);
+    
+    iDialogPtr->RunLD();
+    iDialogIsVisible = ETrue;
+    
+    CleanupStack::Pop(HeapBuf);
+
+    // complete    
+    iMessage.Complete(KErrNone);
+    }
+
+/**
+  Cancels an active notifier.
+
+  This is called as a result of a client-side call to RNotifier::CancelNotifier().
+
+  An implementation should free any relevant resources and complete any outstanding 
+  messages, if relevant. 
+ */
+void CMsmmRefPolicyPluginNotifier::Cancel()
+    {
+    if (iDialogIsVisible && iDialogPtr)
+	    {
+    	delete iDialogPtr;
+	    iDialogPtr = NULL;
+	    }
+    }
+
+/**
+  Updates a currently active notifier with new data.This is called as a result 
+  of a client-side call to RNotifier::UpdateNotifier().
+ 
+  @param aBuffer   Data that can be passed from the client-side. The format 
+                       and meaning of any data is implementation dependent. 
+  
+  @return    KNullDesC8()  Defines an empty or null literal descriptor for use 
+                           with 8-bit descriptors.  
+ */
+TPtrC8 CMsmmRefPolicyPluginNotifier::UpdateL(const TDesC8& /*aBuffer*/)
+    {
+    return KNullDesC8();
+    }
+/**
+  Second phase construction.
+ */    
+void CMsmmRefPolicyPluginNotifier::ConstructL()
+    {
+    _LIT(KResFileName,"z:\\resource\\apps\\dialog.rsc");
+    iOffset=iCoeEnv->AddResourceFileL(KResFileName);
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/refppnotifier/src/refppnotifier.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -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 "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:
+* Reference policy plugin notifier implementation resource file
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <ecom/registryinfo.rh>
+#include <usb/hostms/policypluginnotifier.hrh>
+#include "refppnotifier.hrh"
+#include "uikon.hrh"
+
+RESOURCE REGISTRY_INFO theInfo
+    {
+    // UID for the DLL
+    dll_uid = 0x10285ddd;
+    // Declare array of interface info
+    interfaces = 
+        {
+        INTERFACE_INFO
+            {
+            // UID of interface that is implemented
+            interface_uid = KUikonUidPluginInterfaceNotifiers;
+            implementations = 
+                {
+                IMPLEMENTATION_INFO
+                    {
+                    implementation_uid = KUidMsmmReferenceNotifierImp;
+                    version_no         = 1;
+                    display_name       = "Reference notifier";
+                    default_data       = "Referencenotifier";
+                    opaque_data        = "";
+                    }
+                };
+            }
+        };
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* 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 "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
+*/
+
+PRJ_PLATFORMS
+ARMV5 GCCXML
+
+PRJ_MMPFILES
+
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST) && !defined(WINS) && !defined(X86GCC)
+msmmserver.mmp
+#endif
+
+PRJ_EXPORTS
+../public/msmm_policy_def.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/hostms/msmm_policy_def.h)
+../public/msmmpolicypluginbase.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/hostms/msmmpolicypluginbase.h)
+../public/msmmpolicypluginbase.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/hostms/msmmpolicypluginbase.inl)
+../public/policyplugin.hrh /epoc32/include/usb/hostms/policyplugin.hrh
+../public/policypluginnotifier.hrh /epoc32/include/usb/hostms/policypluginnotifier.hrh
+../public/srverr.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/hostms/srverr.h)
+
+PRJ_TESTEXPORTS
+../public/hostmscaps.mmh /epoc32/include/usb/hostms/hostmscaps.mmh
+../public/msmm_pub_def.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(msmm_pub_def.h)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/group/msmmserver.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* 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 "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
+*/
+
+TARGET		  msmmserver.exe
+TARGETTYPE	  exe
+UID    0 0x10285c44
+
+#include "msmmserver_base.mmp"
+LIBRARY usbhostmsclient.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/group/msmmserver_base.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,48 @@
+/*
+* 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 "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
+*/
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+#include "../public/hostmscaps.mmh"
+#include <usb/usblogger.mmh>
+
+LIBRARY    euser.lib
+LIBRARY    ecom.lib
+LIBRARY    efsrv.lib
+
+SOURCEPATH ../src
+SOURCE main.cpp 
+SOURCE msmmserver.cpp
+SOURCE msmmsession.cpp
+SOURCE eventqueue.cpp
+SOURCE eventhandler.cpp
+SOURCE msmmterminator.cpp
+SOURCE msmmengine.cpp
+SOURCE msmmnodebase.cpp
+SOURCE subcommandbase.cpp
+SOURCE subcommands.cpp
+
+USERINCLUDE ../inc
+USERINCLUDE ../public
+USERINCLUDE ../../inc
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/group/msmmserver_over_dummycomponent.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* 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 "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
+*/
+
+
+TARGET		  msmmserver_over_dummycomponent.exe
+TARGETTYPE	  exe
+UID			 0 0x1028653F
+
+LIBRARY		 dummymsc.lib
+#include "msmmserver_base.mmp"
+
+
+MACRO	__OVER_DUMMYCOMPONENT__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/eventhandler.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,131 @@
+/*
+* 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 "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
+*/
+
+#ifndef EVENTHANDLER_H
+#define EVENTHANDLER_H
+
+#include <e32base.h>
+#include <e32msgqueue.h>
+#include "msmm_internal_def.h"
+#include "subcommandbase.h"
+#include "handlerinterface.h"
+
+class MMsmmSrvProxy;
+class THostMsErrData;
+
+// USB MS sub-commands queue class
+// Intend to be used in event handler internally.
+NONSHARABLE_CLASS(RSubCommandQueue)
+    {
+public:
+    
+    inline TInt Count() const; 
+
+    // Push a sub-command into the queue and transfer the owership 
+    // to the queue
+    void PushL(TSubCommandBase* aCommand);
+    
+    // Pop the head entity from the queue and destroy it  
+    void Pop();
+    
+    // Insert a sub-command sequence after head entities    
+    void InsertAfterHeadL(TSubCommandBase* aCommand);
+    
+    // Execute the head sub-comment
+    void ExecuteHeadL();
+    
+    // Get a reference of head sub-command in queue
+    TSubCommandBase& Head();
+    
+    // Destory all entities and release the memory of queue
+    void Release();
+    
+private:
+    RPointerArray<TSubCommandBase> iQueue;
+    };
+
+NONSHARABLE_CLASS (CDeviceEventHandler) : 
+    public CActive, 
+    public MUsbMsEventHandler,
+    public MUsbMsSubCommandCreator
+    {
+public:
+    virtual ~CDeviceEventHandler();
+    static CDeviceEventHandler* NewL(MMsmmSrvProxy& aServer);
+    static CDeviceEventHandler* NewLC(MMsmmSrvProxy& aServer);
+
+    inline const TDeviceEvent& Event() const;
+
+    // From MUsbMsSubCommandCreator
+    void CreateSubCmdForRetrieveDriveLetterL(TInt aLogicalUnitCount);
+    void CreateSubCmdForMountingLogicalUnitL(TText aDrive, TInt aLuNumber);
+    void CreateSubCmdForSaveLatestMountInfoL(TText aDrive, TInt aLuNumber);
+    
+    // From MUsbMsEventHandler
+    void Start();
+    void Complete(TInt aError = KErrNone);
+    TRequestStatus& Status() const;
+
+    /** Send an event to handler and start to secure handler. 
+    * Intends to be used by CDeviceEventQueue class.
+    */
+    void HandleEventL(TRequestStatus& aStatus, const TDeviceEvent& aEvent);
+
+    /** Reset event handler to be ready for the next event
+     * 
+     */
+    void ResetHandler();
+    inline const THostMsErrData& ErrNotiData() const;
+    
+private:
+    // CActive implementation
+    void DoCancel();
+    void RunL();
+    TInt RunError(TInt aError);
+
+private:
+    CDeviceEventHandler(MMsmmSrvProxy& aServer);
+    void ConstructL();
+
+    // Create sub-commands based on a particular USB MS event
+    void CreateSubCmdForDeviceEventL();
+    void CreateSubCmdForAddingUsbMsFunctionL();
+    void CreateSubCmdForRemovingUsbMsDeviceL();
+
+    void ResetHandlerData();
+    void ResetHandlerError();
+    void CompleteClient(TInt aError = KErrNone);
+    
+private:
+    MMsmmSrvProxy& iServer;
+    TDeviceEvent iIncomingEvent;
+    RSubCommandQueue iSubCommandQueue;
+    TRequestStatus* iEvtQueueStatus; // No ownership
+
+    THostMsErrData* iErrNotiData; // Error notification - Owned
+    };
+
+#include "eventhandler.inl"
+
+#endif // EVENTHANDLER_H
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/eventhandler.inl	Tue Feb 02 02:02:59 2010 +0200
@@ -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 "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
+*/
+
+#ifndef EVENTHANDLER_INL
+#define EVENTHANDLER_INL
+
+inline TInt RSubCommandQueue::Count() const
+    {
+    return iQueue.Count();
+    }
+
+inline const TDeviceEvent& CDeviceEventHandler::Event() const
+    {
+    return iIncomingEvent;
+    }
+
+inline const THostMsErrData& CDeviceEventHandler::ErrNotiData() const
+    {
+    return *iErrNotiData;
+    }
+
+#endif /*EVENTHANDLER_INL*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/eventqueue.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,82 @@
+/*
+* 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 "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
+*/
+
+#ifndef EVENTMAN_H
+#define EVENTMAN_H
+
+#include <e32base.h>
+#include "msmm_internal_def.h"
+
+class MMsmmSrvProxy;
+class CDeviceEventHandler;
+
+NONSHARABLE_CLASS (CDeviceEventQueue) : public CActive
+    {
+public:
+    ~CDeviceEventQueue();
+    static CDeviceEventQueue* NewL(MMsmmSrvProxy& aServer);
+    static CDeviceEventQueue* NewLC(MMsmmSrvProxy& aServer);
+
+    /** Queue a device event 
+    * Intends to be used by CMsmmSession class
+    */
+    void PushL(const TDeviceEvent& aEvent);
+    
+    /** Finalize events in queue
+    * Intends to be used by CMsmmServer when last session has been closed.
+    * This function will remove all pending events of adding a interface
+    * from the queue. It also cancels adding events that currently is being
+    * handled in CDeviceEventHandler. 
+    */
+    void Finalize();
+
+    /** Return count of events in queue
+    */
+    inline TUint8 Count() const;
+    
+protected:
+    // Derived from CActive    
+    void DoCancel();
+    void RunL();
+    TInt RunError(TInt aError);
+
+private:
+    CDeviceEventQueue(MMsmmSrvProxy& aServer);
+    void ConstructL();
+
+    void AppendAndOptimizeL(const TDeviceEvent& aEvent);
+    void StartL();
+    
+    void SendEventL();
+    
+    inline TBool IsEventAvailable() const;
+    TDeviceEvent Pop();
+
+private:
+    MMsmmSrvProxy& iServer;
+    CDeviceEventHandler* iHandler; // Owned
+    RArray<TDeviceEvent> iEventArray;
+    };
+
+#include "eventqueue.inl"
+
+#endif /*EVENTMAN_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/eventqueue.inl	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/*
+* 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 "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
+*/
+
+#ifndef EVENTQUEUE_INL
+#define EVENTQUEUE_INL
+
+inline TUint8 CDeviceEventQueue::Count() const
+    {
+    return iEventArray.Count();
+    }
+
+inline TBool CDeviceEventQueue::IsEventAvailable() const
+    {
+    return (Count() > 0);
+    }
+    
+#endif /*EVENTQUEUE_INL*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/handlerinterface.h	Tue Feb 02 02:02:59 2010 +0200
@@ -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 "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
+*/
+
+#ifndef HANDLERINTERFACE_H
+#define HANDLERINTERFACE_H
+
+
+// USB MS sub-command creator class
+// Intend to be used by event handler and some sub-commands.
+class MUsbMsSubCommandCreator
+    {
+public:
+    // Interface to create new sub-cmmand method.
+    virtual void CreateSubCmdForRetrieveDriveLetterL(
+            TInt aLogicalUnitCount) = 0;
+    virtual void CreateSubCmdForMountingLogicalUnitL(
+            TText aDrive, TInt aLuNumber) = 0;
+    virtual void CreateSubCmdForSaveLatestMountInfoL(
+            TText aDrive, TInt aLuNumber) = 0;    
+    };
+
+// USB MS event handler interface class
+// Intend to be used by sub-command objects
+class MUsbMsEventHandler
+    {
+public:
+    // Activate the handler
+    virtual void Start() = 0;
+    // Complete current request. 
+    // Intend to be used by sync command to simulate async behavior.
+    virtual void Complete(TInt aError = KErrNone) = 0;
+    virtual TRequestStatus& Status() const = 0;
+    };
+
+#endif /*HANDLERINTERFACE_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmm_internal_def.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,76 @@
+/*
+* 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 "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
+*/
+
+#ifndef MSMM_INTERNAL_DEF_H
+#define MSMM_INTERNAL_DEF_H
+
+#include "msmm_pub_def.h"
+#include "msmmnodebase.h"
+
+// MSMM server internal device event type
+enum TDeviceEventType
+    {
+    EDeviceEventAddFunction = 1,
+    EDeviceEventRemoveDevice = 2,
+    EDeviceEventEndMark
+    };
+
+// MSMM server internal device event
+NONSHARABLE_CLASS(TDeviceEvent)
+    {
+public:
+    TDeviceEvent(TDeviceEventType aEvent = EDeviceEventEndMark, 
+            TUint aDeviceId = 0, TUint8 aInterfaceNumber = 0, 
+            TUint32 aInterfaceToken = 0):
+iEvent(aEvent),
+iDeviceId(aDeviceId),
+iInterfaceNumber(aInterfaceNumber),
+iInterfaceToken(aInterfaceToken)
+        {
+        }
+    
+public:
+    TDeviceEventType iEvent; // Event type
+    TUint iDeviceId; // Related device identifier
+    TUint8 iInterfaceNumber; // Related interface number
+    TUint32 iInterfaceToken; // Related interface token
+    };
+
+
+// Information needed by file system extension
+// They may changed before the final release available from base team 
+// frequently.
+
+// FAT file system name
+_LIT(KFATFSNAME, "FAT");
+
+// ELocal file system name
+_LIT(KELOCALFSNAME, "ELOCAL");
+
+// Proxy drive name
+_LIT(KPROXYDRIVENAME, "usbhostms");
+
+// File system extention name
+_LIT(KFSEXTNAME, "usbhostms.pxy");
+
+
+#endif /*MSMM_INTERNAL_DEF_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmmengine.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,111 @@
+/*
+* 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 "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
+*/
+
+#ifndef MSMMENGINE_H
+#define MSMMENGINE_H
+
+#include <e32base.h>
+class TUSBMSDeviceDescription;
+class TMsmmNodeBase;
+class TUsbMsInterface;
+class TUsbMsLogicalUnit;
+class TUsbMsDevice;
+
+NONSHARABLE_CLASS(CMsmmEngine) : public CBase
+    {
+public:
+    virtual ~CMsmmEngine();
+    static CMsmmEngine* NewL();
+    static CMsmmEngine* NewLC();
+
+public:
+
+    /**
+    Called to add a Usb MS device node
+    @param aDevice The device currently attched
+    */
+    void AddUsbMsDeviceL(const TUSBMSDeviceDescription& aDevice);
+        
+    /**
+    Called to add a Usb MS interface node
+    @param aDevice The device to which current interface belongs
+    @param aInterfaceNode Currently adding interface node
+    */
+    TUsbMsInterface* AddUsbMsInterfaceL(TInt aDeviceId, 
+            TUint8 aInterfaceNumber, TInt32 aInterface);
+    
+    /**
+    Called to add a Usb MS LU node
+    @param aDeviceId The device identifier of the device by which current 
+        logical unit supported
+    @param aInterfaceNumber The interface number value of the interface
+        to which current logical unit belongs
+    @param aLogicalUnitNumber Current LU number value
+    @param aDrive The drive on which current LU mounted
+    */
+    void AddUsbMsLogicalUnitL(TInt aDeviceId, TInt aInterfaceNumber, 
+            TInt aLogicalUnitNumber, TText aDrive);
+    
+    /**
+    Called to remove a Usb MS node
+    @param aNodeToBeRemoved The node to be removed
+    */
+    void RemoveUsbMsNode(TMsmmNodeBase* aNodeToBeRemoved);
+    
+    /**
+    Called to search a particular device in engine
+    @param aDeviceId The related device identifier of the device node
+    @return Pointer to the device node found out in the data engine
+    */
+    TUsbMsDevice* SearchDevice(TInt aDeviceId) const;
+        
+    /**
+    Called to search a particular device in engine. Intends to be used
+    when a parent device node is available.
+    @param aDevice The parent device node of the interface node 
+        currently searched 
+    @param aInterfaceNumber The related interface number value of the 
+        interface node
+    @return Pointer to the device node found out in the data engine
+    */
+    TUsbMsInterface* SearchInterface(TMsmmNodeBase* aDevice, 
+            TInt aInterfaceNumber) const;
+    
+protected:
+    CMsmmEngine();
+    void ConstructL();
+
+private:
+
+    // Called to add a new USB MS interface node into data engine.
+    TUsbMsInterface* AddUsbMsInterfaceNodeL(TUsbMsDevice* iParent,
+            TInt aInterfaceNumber, TInt aInterfaceToken);
+    
+    // Called to add a new USB MS logical unit node into data engine.
+    TUsbMsLogicalUnit* AddUsbMsLogicalUnitNodeL(TUsbMsInterface* iParent,
+            TInt aLogicalUnitNumber, TText aDrive);
+
+private:
+    TMsmmNodeBase* iDataEntrys; // Usb Ms device tree
+    };
+
+#endif /*MSMMENGINE_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmmnodebase.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,131 @@
+/*
+* 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 "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
+*/
+
+#ifndef MSMMNODEBASE_H
+#define MSMMNODEBASE_H
+
+#include <e32base.h>
+#include "msmm_pub_def.h"
+
+#ifdef __OVER_DUMMYCOMPONENT__
+#include <usb/hostms/dummycomponent/rusbhostmsdevice.h>
+#else
+#include <rusbhostmsdevice.h> // For RUsbHostMsDevice
+#endif
+
+class TMsmmNodeBase
+    {    
+public:
+	TMsmmNodeBase(TInt aIdentifier);
+    virtual ~TMsmmNodeBase();
+
+    void AddChild(TMsmmNodeBase* aChild);
+    TMsmmNodeBase* SearchInChildren(TInt aIdentifier);
+    
+private:
+    void DestroyNode();
+    
+private:
+    TInt    iIdentifier;
+    
+protected:
+    /**
+     A pointer to the next peer of this entry, or NULL.
+     */
+    TMsmmNodeBase* iNextPeer;
+
+    /**
+     A pointer to the first child of this entry, or NULL.
+     */
+    TMsmmNodeBase* iFirstChild;
+    
+    /**
+     A pointer to the last child of this entry, or NULL.
+     */
+    TMsmmNodeBase* iLastChild;
+
+    /**
+     A pointer to the parent to this entry, or NULL.
+     */
+    TMsmmNodeBase* iParent;
+    };
+
+class TUsbMsInterface;
+// The USB MS device node class
+NONSHARABLE_CLASS(TUsbMsDevice) : public TMsmmNodeBase
+    {
+public:
+    TUsbMsDevice(const TUSBMSDeviceDescription& aDevice);
+
+    inline TUsbMsInterface* FirstChild() const;
+    
+public:
+    TUSBMSDeviceDescription iDevice;
+    };
+
+class TUsbMsLogicalUnit;
+// The USB MS interface node class
+NONSHARABLE_CLASS(TUsbMsInterface) : public TMsmmNodeBase
+    {
+public:
+    TUsbMsInterface(TUint8 aInterfaceNumber, 
+            TUint32 aInterfaceToken);
+    ~TUsbMsInterface();
+
+    inline TUsbMsInterface* NextPeer() const;
+    inline TUsbMsLogicalUnit* FirstChild() const;
+    
+public:
+    TUint8 iInterfaceNumber;
+    TUint32 iInterfaceToken;
+    RUsbHostMsDevice iUsbMsDevice;
+    };
+
+// The USB MS logical unit node class
+NONSHARABLE_CLASS(TUsbMsLogicalUnit) : public TMsmmNodeBase
+    {
+public:
+    TUsbMsLogicalUnit(TUint8 aLogicalUnitNumber, 
+            TText aDrive);
+
+    inline TUsbMsLogicalUnit* NextPeer() const;
+    inline TUsbMsInterface* Parent() const;
+    
+public:
+    TUint8 iLogicalUnitNumber; // Logic Unit Number
+    TText iDrive;
+    };
+
+inline TUsbMsInterface* TUsbMsDevice::FirstChild() const
+    {return static_cast<TUsbMsInterface*>(iFirstChild);}
+
+inline TUsbMsLogicalUnit* TUsbMsInterface::FirstChild() const
+    {return static_cast<TUsbMsLogicalUnit*>(iFirstChild);}
+inline TUsbMsInterface* TUsbMsInterface::NextPeer() const
+    {return static_cast<TUsbMsInterface*>(iNextPeer);}
+
+inline TUsbMsLogicalUnit* TUsbMsLogicalUnit::NextPeer() const
+    {return static_cast<TUsbMsLogicalUnit*>(iNextPeer);}
+inline TUsbMsInterface* TUsbMsLogicalUnit::Parent() const
+    {return static_cast<TUsbMsInterface*>(iParent);}
+
+#endif /*MSMMNODEBASE_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmmserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,92 @@
+/*
+* 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 "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
+*/
+
+#ifndef MSMMSERVER_H
+#define MSMMSERVER_H
+
+//  Include Files
+#include <e32base.h> // for CPolicyServer
+#include <ecom/implementationinformation.h>
+
+// Project includes
+#include "srvdef.h"
+#include "srvpanic.h"
+#include "srvsec.h"
+
+// Forward declaration
+class CMsmmEngine;
+class CMsmmTerminator;
+class CDeviceEventQueue;
+class CMsmmPolicyPluginBase;
+
+// Server side resource container class
+// Intends to be used by any internal objects (such as sub-command objects) 
+// needs access to engine, policy plugin, MSC or RFs. 
+class MMsmmSrvProxy
+    {
+public:
+    virtual CMsmmEngine& Engine() const = 0;
+    virtual RFs& FileServerSession() const = 0;
+    virtual CMsmmPolicyPluginBase* PolicyPlugin() const = 0;
+    };
+
+// The MSMM server class 
+NONSHARABLE_CLASS (CMsmmServer) : public CPolicyServer, public MMsmmSrvProxy
+    {
+public: // Static
+    static TInt ThreadFunction();
+    static void ThreadFunctionL();
+        
+public:
+   
+    // Construction and destruction
+    static CMsmmServer* NewLC();
+    ~CMsmmServer();
+
+public:
+    // CMsmmServer API
+    virtual CSession2* NewSessionL(const TVersion& aVersion, 
+            const RMessage2& aMessage) const;
+    
+    TInt SessionNumber() const;
+    void AddSession();
+    void RemoveSession();
+
+    // From MMsmmSrvProxy
+    inline CMsmmEngine& Engine() const;
+    inline RFs& FileServerSession() const;
+    inline CMsmmPolicyPluginBase* PolicyPlugin() const;
+
+private: // CMsmmServer Construction
+    CMsmmServer(TInt aPriority);
+    void ConstructL();
+
+private: // Data members
+    TInt                iNumSessions;
+    CMsmmTerminator*    iTerminator; // Owned
+    CMsmmEngine*        iEngine; // Owned
+    RFs                 iFs;
+    CMsmmPolicyPluginBase*  iPolicyPlugin; // Owned
+    CDeviceEventQueue* iEventQueue; // Owned
+    };
+#include "msmmserver.inl" 
+#endif  // MSMMSERVER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmmserver.inl	Tue Feb 02 02:02:59 2010 +0200
@@ -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 "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
+*/
+
+#ifndef MSMMSERVER_INL
+#define MSMMSERVER_INL
+
+inline CMsmmEngine& CMsmmServer::Engine() const
+    {
+    return *iEngine;
+    }
+
+inline RFs& CMsmmServer::FileServerSession() const
+    {
+    return const_cast<RFs&>(iFs);
+    }
+
+inline CMsmmPolicyPluginBase* CMsmmServer::PolicyPlugin() const
+    {
+    return iPolicyPlugin;
+    }
+
+#endif /*MSMMSERVER_INL*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmmsession.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,65 @@
+/*
+* 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 "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
+*/
+
+#ifndef CMSMMSESSION_H
+#define CMSMMSESSION_H
+
+#include <e32base.h>
+#include <e32msgqueue.h>
+#include "msmm_internal_def.h"
+
+class CMsmmServer;
+class CMsmmEngine;
+class CDeviceEventQueue;
+class THostMsErrData;
+
+NONSHARABLE_CLASS(CMsmmSession) : public CSession2
+    {
+public: // Construction and Destruction
+    ~CMsmmSession();
+    static CMsmmSession* NewL(CMsmmServer& aServer, 
+            CDeviceEventQueue& anEventQueue);
+
+public: // CMsmmSession
+    void ServiceL (const RMessage2& aMessage);
+    void ServiceError(const RMessage2& aMessage, TInt aError);
+
+private:
+    CMsmmSession(CMsmmServer& aServer,
+            CDeviceEventQueue& anEventQueue);
+    void ConstructL();
+
+    void AddUsbMsInterfaceL(const RMessage2& aMessage);
+    void RemoveUsbMsDeviceL(const RMessage2& aMessage);
+
+private: // data members
+    CMsmmServer& iServer;
+    CMsmmEngine& iEngine;
+    CDeviceEventQueue& iEventQueue;
+    TPckgBuf<TUSBMSDeviceDescription> iDevicePkg;
+    THostMsErrData* iErrData; // The data nodes try, Owned
+    TInt iInterfaceNumber;
+    TInt32 iInterfaceToken;
+    TInt iDeviceID;
+    };
+
+#endif /*CMSMMSESSION_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/msmmterminator.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,49 @@
+/*
+* 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 "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
+*/
+
+#ifndef MSMMTERMINATOR_H
+#define MSMMTERMINATOR_H
+
+#include <e32base.h>
+
+class CDeviceEventQueue;
+
+NONSHARABLE_CLASS(CMsmmTerminator) : public CTimer
+    {
+public:
+    static CMsmmTerminator* NewL(const CDeviceEventQueue& anEventQueue);
+    
+    void Start();
+    
+protected:
+    void RunL();
+    
+private:
+    CMsmmTerminator(const CDeviceEventQueue& anEventQueue);
+    void ConstructL();
+    
+private:
+    const CDeviceEventQueue& iEventQueue;
+    };
+
+#endif /*MSMMTERMINATOR_H*/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/srvsec.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,55 @@
+/*
+* 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 "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
+*/
+
+#ifndef SRVSEC_H
+#define SRVSEC_H
+
+const TInt KMsmmServerRanges[] = 
+    {
+    EHostMsmmServerAddFunction,
+    EHostMsmmServerEndMarker
+    };
+const TUint KMsmmServerRangeCount = 
+    (sizeof(KMsmmServerRanges) / sizeof(KMsmmServerRanges[0])); 
+ 
+const TUint8 KMsmmServerElementsIndex[KMsmmServerRangeCount] = 
+    {
+    0,
+    CPolicyServer::ENotSupported
+    };
+
+const CPolicyServer::TPolicyElement KMsmmServerElements[] = 
+    {
+        {_INIT_SECURITY_POLICY_S1( KFDFWSecureId, ECapabilityCommDD ), 
+            CPolicyServer::EFailClient}
+    };
+
+const CPolicyServer::TPolicy KMsmmServerSecurityPolicy =
+    {
+    0,
+    KMsmmServerRangeCount,
+    KMsmmServerRanges,
+    KMsmmServerElementsIndex,
+    KMsmmServerElements,
+    };
+
+#endif /*SRVSEC_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/subcommandbase.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,84 @@
+/*
+* 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 "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
+*/
+
+#ifndef SUBCOMMANDBASE_H
+#define SUBCOMMANDBASE_H
+
+#include <e32const.h>
+#include <e32cmn.h>
+#include <usb/hostms/srverr.h>
+
+class TDeviceEvent;
+class MMsmmSrvProxy;
+class MUsbMsEventHandler;
+class MUsbMsSubCommandCreator;
+
+NONSHARABLE_CLASS(THostMsSubCommandParam)
+    {
+public:
+    MMsmmSrvProxy& iServer;
+    MUsbMsEventHandler& iHandler;
+    MUsbMsSubCommandCreator& iCreator;
+    TDeviceEvent& iEvent;
+    
+public:
+    THostMsSubCommandParam(MMsmmSrvProxy& aServer, 
+            MUsbMsEventHandler& aHandler, 
+            MUsbMsSubCommandCreator& aCreator, TDeviceEvent& aEvent);
+    };
+
+class TSubCommandBase
+    {    
+public:
+	TSubCommandBase(THostMsSubCommandParam& aParameter);
+
+	// Called to execute current sub-command.
+    void ExecuteL();
+    // Called to do the further operation when current sub-command 
+    // is done.
+    void AsyncCmdCompleteL();
+    // Called to cancel current pending sub-command
+    void CancelAsyncCmd();
+    // Called to generate command realted error notification data
+    virtual void HandleError(THostMsErrData& aData, TInt aError) = 0;
+    
+    inline TBool IsExecuted() const;
+    inline TBool IsKeyCommand() const;
+    
+protected:
+    virtual void DoExecuteL() = 0;
+    virtual void DoAsyncCmdCompleteL();
+    virtual void DoCancelAsyncCmd();
+    
+protected:
+    MMsmmSrvProxy& iServer;
+    MUsbMsEventHandler& iHandler;
+    MUsbMsSubCommandCreator& iCreator;
+    const TDeviceEvent& iEvent;
+    TBool iIsExecuted;
+    TBool iIsKeyCommand;
+    };
+
+inline TBool TSubCommandBase::IsExecuted() const {return iIsExecuted;};
+inline TBool TSubCommandBase::IsKeyCommand() const {return iIsKeyCommand;};
+
+#endif /*SUBCOMMANDBASE_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/inc/subcommands.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,193 @@
+/*
+* 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 "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
+*/
+
+#ifndef SUBCOMMANDS_H
+#define SUBCOMMANDS_H
+
+#include "subcommandbase.h"
+#include "usb/hostms/msmm_policy_def.h"
+#include "msmmnodebase.h"
+#ifdef __OVER_DUMMYCOMPONENT__
+#include <usb/hostms/dummycomponent/rusbhostmsdevice.h>
+#else
+#include <rusbhostmsdevice.h>
+#endif
+
+// TRegisterInterface class
+// Sub-command to regiest a USB MS function to RUsbHostMsDevice
+NONSHARABLE_CLASS(TRegisterInterface) : public TSubCommandBase
+    {
+public:
+    TRegisterInterface(THostMsSubCommandParam aParam);
+
+    // From TSubCommandBase
+    void HandleError(THostMsErrData& aData, TInt aError);
+    
+private:
+    // From TSubCommandBase
+    void DoExecuteL();
+    void DoAsyncCmdCompleteL();
+    void DoCancelAsyncCmd();
+
+private:
+    TUint32 iMaxLogicalUnit;
+    THostMassStorageConfig iMsConfig;
+    TUsbMsDevice* iDeviceNode; // Not owned
+    TUsbMsInterface* iInterfaceNode; // Not owned
+    };
+
+
+// TRetrieveDriveLetter class
+// Sub-command to retrieve a drive letter from policy plugin
+NONSHARABLE_CLASS(TRetrieveDriveLetter) : public TSubCommandBase
+    {
+public:
+    TRetrieveDriveLetter(THostMsSubCommandParam& aParameter, TInt aLuNumber);
+
+    // From TSubCommandBase
+    void HandleError(THostMsErrData& aData, TInt aError);
+    
+private:
+    // From TSubCommandBase
+    void DoExecuteL();
+    void DoAsyncCmdCompleteL();
+    void DoCancelAsyncCmd();
+
+private:
+    TPolicyRequestData iRequestData;
+    TInt iLuNumber;
+    TText iDrive;
+    };
+
+
+// TMountLogicalUnit class
+// Sub-command to mount a logical unit on a drive letter
+NONSHARABLE_CLASS(TMountLogicalUnit) : public TSubCommandBase
+    {
+public:
+
+    TMountLogicalUnit(THostMsSubCommandParam& aParameter,
+            TText aDrive, TInt aLuNumber);
+
+    // From TSubCommandBase
+    void HandleError(THostMsErrData& aData, TInt aError);
+    
+private:
+    // From TSubCommandBase
+    void DoExecuteL();
+    void DoAsyncCmdCompleteL();
+
+private:
+    TText iDrive;
+    TInt iLuNumber;
+    };
+
+// TSaveLatestMountInfo class
+// Sub-command to save a mounting record
+NONSHARABLE_CLASS(TSaveLatestMountInfo) : public TSubCommandBase
+    {
+public:
+    TSaveLatestMountInfo(THostMsSubCommandParam& aParameter,
+            TText aDrive, TInt aLuNumber);
+
+    // From TSubCommandBase
+    void HandleError(THostMsErrData& aData, TInt aError);
+    
+private:
+    // From TSubCommandBase
+    void DoExecuteL();
+    void DoAsyncCmdCompleteL();
+    void DoCancelAsyncCmd();
+
+private:
+    TPolicyMountRecord iRecord;
+    TText iDrive;
+    TInt iLuNumber;
+    };
+
+
+// TDeregisterInterface class
+// Sub-command to deregister a USB MS function from RUsbHostMsDevice
+NONSHARABLE_CLASS(TDeregisterInterface) : public TSubCommandBase
+    {
+public:
+    TDeregisterInterface(THostMsSubCommandParam& aParameter,
+            TUint8 aInterfaceNumber, TUint32 aInterfaceToken);
+
+    // From TSubCommandBase
+    void HandleError(THostMsErrData& aData, TInt aError);
+    
+private:
+    // From TSubCommandBase
+    void DoExecuteL();
+    
+private:
+    TUint8 iInterfaceNumber;
+    TUint32 iInterfaceToken;
+    THostMassStorageConfig iMsConfig;
+    TUsbMsDevice* iDeviceNode; // Not owned
+    TUsbMsInterface* iInterfaceNode; // Not owned
+    };
+
+
+// TDismountLogicalUnit class
+// Sub-command to dismount a logical unit
+class TUsbMsLogicalUnit;
+NONSHARABLE_CLASS (TDismountLogicalUnit) : public TSubCommandBase
+    {
+public:
+    TDismountLogicalUnit(THostMsSubCommandParam& aParameter,
+            const TUsbMsLogicalUnit& aLogicalUnit);
+
+    // From TSubCommandBase
+    void HandleError(THostMsErrData& aData, TInt aError);
+    
+private:
+    // From TSubCommandBase
+    void DoExecuteL();
+
+private:
+    const TUsbMsLogicalUnit& iLogicalUnit;
+    };
+
+
+// TRemoveUsbMsDeviceNode class
+// Sub-command to dismount a logical unit
+class TMsmmNodeBase;
+NONSHARABLE_CLASS(TRemoveUsbMsDeviceNode) : public TSubCommandBase
+    {
+public:
+    TRemoveUsbMsDeviceNode(THostMsSubCommandParam& aParameter,
+            TMsmmNodeBase* aNodeToBeRemoved);
+
+    // From TSubCommandBase
+    void HandleError(THostMsErrData& aData, TInt aError);
+    
+private:
+    // From TSubCommandBase
+    void DoExecuteL();
+    TMsmmNodeBase* iNodeToBeRemoved; // No ownership
+    };
+
+#endif /*SUBCOMMANDS_H*/
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/hostmscaps.mmh	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+/*
+* 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 "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:
+* This file is provided as a facility to policy plugin implementers.
+* It may be #included in mmp files to provide only those capabilities 
+* required to run in the msmm's process.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef HOSTMSCAPS_MMH
+#define HOSTMSCAPS_MMH
+
+CAPABILITY DiskAdmin NetworkControl ProtServ WriteDeviceData
+
+#endif // HOSTMMCAPS_MMH
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/msmm_policy_def.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,65 @@
+/*
+* 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 "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
+ @publishedPartner
+*/
+
+#ifndef MSMM_POLICY_DEF_H
+#define MSMM_POLICY_DEF_H
+
+/**
+TPolicyRequestData is used to identify a particular logical unit 
+to the Policy Plugin. Related device and interface information included.
+*/
+NONSHARABLE_CLASS(TPolicyRequestData)
+    {
+public:
+    TUint16 iBcdDevice; // Device Release Number
+    TUint8  iConfigurationNumber; // Number of Possible Configurations
+    TUint   iDeviceId; // Device identifier
+    TUint8  iInterfaceNumber; // Interface Number
+    TUint8  iLogicUnitNumber; // Logical Unit Number
+    TUint32 iOtgInformation; // Reserved for Otg Host information
+    TUint16 iProductId; // Product ID (Assigned by Manufacturer)
+    TUint16 iVendorId; // Vendor ID (Assigned by USB Org)
+    TName   iSerialNumber; // Serial Number String Descriptor
+    TName   iManufacturerString; // Manufacturer String Descriptor
+    TName   iProductString; // Product String Descriptor
+    };
+
+/**
+TPolicyMountRecord is used to record a particular mounting operation
+*/
+NONSHARABLE_CLASS(TPolicyMountRecord)
+    {
+public:
+    TText8  iDriveName; // Drive letter
+    TPolicyRequestData  iLogicUnit; // Mounted logical unit
+    };
+
+NONSHARABLE_CLASS(TSuspensionPolicy)
+    {
+public:
+    /** Time internval to check media status and finalisation */
+    TUint8  iStatusPollingInterval;
+    /** Time interval to delay suspending the interface after finalisation */
+    TUint8  iOtgSuspendTime; 
+    };
+
+#endif /*MSMM_POLICY_DEF_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/msmm_pub_def.h	Tue Feb 02 02:02:59 2010 +0200
@@ -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 "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
+*/
+
+#ifndef MSMM_PUB_DEF_H
+#define MSMM_PUB_DEF_H
+
+/**
+USB Mass Storage Device description structure
+Used to identifier a particular USB MS device when the MSFDC adds a 
+function or removes a device.
+*/
+NONSHARABLE_CLASS(TUSBMSDeviceDescription)
+    {
+public:
+    /** Device Release Number */
+    TUint16 iBcdDevice;
+    /** Number of Possible Configurations */
+    TUint8  iConfigurationNumber;
+    /** Device identifier */
+    TUint   iDeviceId;
+    /** Reservered for Otg Host information */
+    TUint32 iOtgInformation;
+    /** Product ID (Assigned by Manufacturer) */
+    TUint16 iProductId;
+    /** Vendor ID (Assigned by USB Org) */
+    TUint16 iVendorId;
+    /** Serial Number String Descriptor */
+    TName   iSerialNumber;
+    /** Manufacturer String Descriptor */
+    TName   iManufacturerString;
+    /** Product String Descriptor */
+    TName   iProductString;    
+    /** Protocol to be used by the MSC */
+    TUint8  iProtocolId;
+    /** Transport to be used by the MSC */
+    TUint8  iTransportId;
+    /** Device's capabilitiy for RemoteWakeup */
+    TUint8  iRemoteWakeup;
+    /** OTG capability of the device */
+    TUint8  iIsOtgClient; 
+    };
+
+#endif /*MSMM_PUB_DEF_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/msmmpolicypluginbase.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,107 @@
+/*
+* 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 "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
+ @publishedPartner
+ @released
+*/
+
+#ifndef MSMMPOLICYPLUGINBASE_H
+#define MSMMPOLICYPLUGINBASE_H
+
+// INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+#include <ecom/ecom.h>
+#include <usb/hostms/msmm_policy_def.h>
+#include <usb/hostms/srverr.h>
+
+// CLASS DECLARATION
+
+/**
+ CMsmmPolicyPluginBase
+*/
+class CMsmmPolicyPluginBase : public CActive
+    {
+public: // Constructors and destructor
+
+	virtual ~CMsmmPolicyPluginBase();
+	static CMsmmPolicyPluginBase* NewL();
+    
+public:
+    /** 
+     Called when the MSMM retrieves a drive letter to mount a logical unit on it.
+
+     @param aDriveName This is the drive name buffer for the new logical unit. 
+     The policy plugin uses it bring the drive name back.
+     @param aData The data used for retrieve a drive name. It includes number of
+     the new logical unit and the information of the USB mass storage function
+     and the device that current logical unit belongs to.
+     @param aStatus The reference of client request status object.
+     */
+    virtual void RetrieveDriveLetterL(TText& aDriveName, 
+            const TPolicyRequestData& aData, TRequestStatus& aStatus) = 0;
+    /** 
+     Called to cancel a outstanding drive letter retrieving request.
+     */
+    virtual void CancelRetrieveDriveLetter() = 0;
+
+    /** 
+     Called when the MSMM saves mount operation informaion to policy plugin.
+
+     @param aData This is the data that will be used to retrieve a drive letter
+     and perform a mounting operation before. It will be saved
+     @param aStatus The reference of client request status object. 
+     */
+    virtual void SaveLatestMountInfoL(const TPolicyMountRecord& aData, 
+            TRequestStatus& aStatus) = 0;
+    /** 
+     Called to cancel a outstanding saving mount information request.
+     */
+    virtual void CancelSaveLatestMountInfo() = 0;
+    
+    /** 
+     Called when the MSMM send a error notification to policy plugin.
+
+     @param aData This is the data that describles the error.
+     */
+    virtual void SendErrorNotificationL(const THostMsErrData& aErrData) = 0;
+    
+    /** 
+     Called when the MSMM need suspension policy passing to MSC interface.
+
+     @param aPolicy This is the buffer for suspension policy data.
+     */    
+    virtual void GetSuspensionPolicy(TSuspensionPolicy& aPolicy) = 0;
+    
+protected:
+    CMsmmPolicyPluginBase();
+    
+    // Derivde from CActive
+    virtual void DoCancel() = 0;
+    virtual void RunL() = 0;
+
+private:
+	TUid iDtor_ID_Key;
+    };
+
+#include "usb/hostms/msmmpolicypluginbase.inl"
+
+#endif // MSMMPOLICYPLUGINBASE_H
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/msmmpolicypluginbase.inl	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,56 @@
+/*
+* 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 "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
+ @publishedPartner
+ @released
+*/
+
+#include <usb/hostms/policyplugin.hrh>
+
+inline CMsmmPolicyPluginBase::~CMsmmPolicyPluginBase()
+	{
+	REComSession::DestroyedImplementation (iDtor_ID_Key);
+	}
+
+inline CMsmmPolicyPluginBase* CMsmmPolicyPluginBase::NewL()
+	{
+    RImplInfoPtrArray   pluginImpArray;
+    const TUid policyInterfaceUid = {KUidMountPolicyInterface};
+    REComSession::ListImplementationsL(policyInterfaceUid, pluginImpArray);
+    if (pluginImpArray.Count())
+        {
+        const TUid firstImplementationUid(
+                pluginImpArray[0]->ImplementationUid());
+        pluginImpArray.ResetAndDestroy();
+        
+        TAny* interface = REComSession::CreateImplementationL (
+                firstImplementationUid, 
+                _FOFF (CMsmmPolicyPluginBase, iDtor_ID_Key));
+
+        return reinterpret_cast <CMsmmPolicyPluginBase*> (interface);
+        }
+    return NULL;
+	}
+
+inline  CMsmmPolicyPluginBase::CMsmmPolicyPluginBase():
+CActive(EPriorityStandard)
+    {
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/policyplugin.hrh	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* 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 "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
+ @publishedPartner
+ @released
+*/
+
+#ifndef POLICYPLUGIN_HRH
+#define POLICYPLUGIN_HRH
+
+/**
+Definition of ECOM interface UID for Policy plug-in.
+*/
+#define KUidMountPolicyInterface 0x10285c45
+
+#endif // POLICYPLUGIN_HRH
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/policypluginnotifier.hrh	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* 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 "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
+ @publishedPartner
+ @released
+*/
+
+#ifndef POLICYPLUGINNOTIFIER_HRH
+#define POLICYPLUGINNOTIFIER_HRH
+
+/**
+Definition of USB Mass Storage mount policy plugin notifier UID.
+*/
+#define KUidMountPolicyNotifier 0x10285D58
+
+#endif /*POLICYPLUGINNOTIFIER_HRH*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/public/srverr.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,49 @@
+/*
+* 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 "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
+ @publishedPartner
+*/
+
+#ifndef SRVERR_H
+#define SRVERR_H
+
+enum THostMsErrCode
+    {
+    EHostMsErrGeneral = 0x1, // General error 
+    EHostMsErrNoDriveLetter = 0x2, // No drive letter available currently
+    EHostMsErrUnknownFileSystem = 0x3, // Unknown file system on currently 
+    // adding device
+    EHostMsErrInvalidParameter = 0x4, // Invalid request parameter
+    EHostMsErrOutOfMemory = 0x5, // Out of memory
+    EHostMsErrorEndMarker
+    };
+    
+NONSHARABLE_CLASS(THostMsErrData)
+    {
+public:
+    THostMsErrCode  iError; // Error code
+    TInt            iE32Error; // Symbian e32err code
+    TName           iManufacturerString;
+    TName           iProductString;
+    TText8          iDriveName; // Drive letter
+    };
+
+typedef TPckgBuf<THostMsErrData> THostMsErrorDataPckg;
+
+#endif /*SRVERR_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/eventhandler.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,388 @@
+/*
+* 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 "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
+*/
+
+#include "eventhandler.h"
+#include <usb/hostms/srverr.h>
+#include <usb/usblogger.h>
+#include "msmmserver.h"
+#include "msmmengine.h"
+#include "subcommands.h"
+#include "msmmnodebase.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmServer");
+#endif
+
+// Push a sub-command into the queue and transfer the owership 
+// to the queue
+void RSubCommandQueue::PushL(TSubCommandBase* aCommand)
+    {
+    LOG_FUNC
+    CleanupStack::PushL(aCommand);
+    iQueue.AppendL(aCommand);
+    CleanupStack::Pop(aCommand);
+    }
+
+// Pop the head entity from the queue and destroy it
+void RSubCommandQueue::Pop()
+    {
+    LOG_FUNC
+    if (iQueue.Count() == 0)
+        {
+        return;
+        }
+    
+    TSubCommandBase* command = iQueue[0];
+    iQueue.Remove(0);
+    delete command;
+    command = NULL;
+    }
+    
+// Insert a sub-command sequence after head entities
+void RSubCommandQueue::InsertAfterHeadL(TSubCommandBase* aCommand)
+    {
+    LOG_FUNC
+    if (!aCommand)
+        {
+        User::Leave(KErrArgument);
+        }
+    
+    iQueue.InsertL(aCommand, 1);
+    }
+    
+// Execute the head sub-comment
+void RSubCommandQueue::ExecuteHeadL()
+    {
+    LOG_FUNC
+    Head().ExecuteL();
+    }
+    
+// Get a reference of head sub-command in queue
+TSubCommandBase& RSubCommandQueue::Head()
+    {
+    LOG_FUNC
+    return *iQueue[0];
+    }
+    
+// Destory all entities and release the memory of queue
+void RSubCommandQueue::Release()
+    {
+    LOG_FUNC
+    iQueue.ResetAndDestroy();
+    }
+
+/*
+ *  Public member functions
+ */
+CDeviceEventHandler::~CDeviceEventHandler()
+    {
+    LOG_FUNC
+    Cancel();
+    delete iErrNotiData;
+    iSubCommandQueue.Release();
+    }
+
+CDeviceEventHandler* CDeviceEventHandler::NewL(MMsmmSrvProxy& aServer)
+    {
+    LOG_STATIC_FUNC_ENTRY
+    CDeviceEventHandler* self = CDeviceEventHandler::NewLC(aServer);
+    CleanupStack::Pop(self);
+    
+    return self;
+    }
+
+CDeviceEventHandler* CDeviceEventHandler::NewLC(MMsmmSrvProxy& aServer)
+    {
+    LOG_STATIC_FUNC_ENTRY
+    CDeviceEventHandler* self = 
+        new (ELeave) CDeviceEventHandler(aServer);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    
+    return self;
+    }
+
+void CDeviceEventHandler::CreateSubCmdForRetrieveDriveLetterL(
+        TInt aLogicalUnitCount)
+    {
+    LOG_FUNC
+    TRetrieveDriveLetter* command(NULL);
+    THostMsSubCommandParam parameter(iServer, *this, *this, iIncomingEvent);
+    for (TInt index = 0; index < aLogicalUnitCount; index++)
+        {
+        command = new (ELeave) TRetrieveDriveLetter(parameter, index);
+        iSubCommandQueue.PushL(command);
+        }
+    }
+
+void CDeviceEventHandler::CreateSubCmdForMountingLogicalUnitL(TText aDrive, 
+        TInt aLuNumber)
+    {
+    LOG_FUNC
+    THostMsSubCommandParam parameter(iServer, *this, *this, iIncomingEvent);
+    TMountLogicalUnit* command = new (ELeave) TMountLogicalUnit(
+            parameter, aDrive, aLuNumber);
+    iSubCommandQueue.InsertAfterHeadL(command);
+    }
+
+void CDeviceEventHandler::CreateSubCmdForSaveLatestMountInfoL(TText aDrive, 
+        TInt aLuNumber)
+    {
+    LOG_FUNC
+    THostMsSubCommandParam parameter(iServer, *this, *this, iIncomingEvent);
+    TSaveLatestMountInfo* command = 
+        new (ELeave) TSaveLatestMountInfo(parameter, aDrive, aLuNumber);
+    iSubCommandQueue.InsertAfterHeadL(command);
+    }
+
+void CDeviceEventHandler::Start()
+    {
+    LOG_FUNC
+    if (IsActive())
+        {
+        return;
+        }
+    iStatus = KRequestPending;
+    SetActive();
+    }
+
+void CDeviceEventHandler::Complete(TInt aError)
+    {
+    LOG_FUNC
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete(status, aError);
+    }
+
+TRequestStatus& CDeviceEventHandler::Status() const
+    {
+    LOG_FUNC
+    const TRequestStatus& status = iStatus;
+    return const_cast<TRequestStatus&>(status);
+    }
+
+void CDeviceEventHandler::HandleEventL(TRequestStatus& aStatus, 
+        const TDeviceEvent& aEvent)
+    {
+    LOG_FUNC
+    if (IsActive())
+        {
+        // An event is being handled. Currently handler is busy.
+        User::Leave(KErrInUse);
+        }
+    
+    // Copy incoming event
+    iIncomingEvent = aEvent;
+
+    // Create sub-commands and append them to queue
+    CreateSubCmdForDeviceEventL();
+    
+    aStatus = KRequestPending;
+    iEvtQueueStatus = &aStatus;
+    
+    // Start the handler to handle the incoming event
+    Start();
+    Complete();
+    }
+
+/*
+ * Protected member functions 
+ */
+
+void CDeviceEventHandler::DoCancel()
+    {
+    LOG_FUNC
+    // Complete client with KErrCancel
+    CompleteClient(KErrCancel);
+    
+    // Cancel current pending command
+    iSubCommandQueue.Head().CancelAsyncCmd();
+    }
+
+void CDeviceEventHandler::RunL( )
+    {
+    LOG_FUNC
+    
+    if (iSubCommandQueue.Count() == 0)
+        {
+        // Error occurs in lastest sub-command's DoExecuteL()
+        // Or current command has been cancelled.
+        return;
+        }
+    
+    if (iSubCommandQueue.Head().IsExecuted())
+        {
+        // Complete the current sub-command
+        iSubCommandQueue.Head().AsyncCmdCompleteL();
+        iSubCommandQueue.Pop();
+        }
+
+    // Move to the next sub-command
+    if (iSubCommandQueue.Count())
+        {
+        iSubCommandQueue.ExecuteHeadL();
+        }
+    else
+        {
+        // Run out of sub-commands. Current handling event achieved.
+        // Complete client
+        CompleteClient();
+        }
+    }
+
+TInt CDeviceEventHandler::RunError(TInt aError)
+    {
+    LOG_FUNC
+    // Retrieve sub-command related error notification data
+    iSubCommandQueue.Head().HandleError(*iErrNotiData, aError);
+        
+    // If current sub-command isn't a key one, the handler will continue to
+    // execute rest sub-command in the queue. But, if current sub-command
+    // is the last one in the queue, handler shall complete the client also. 
+    if (iSubCommandQueue.Head().IsKeyCommand() || 
+            (iSubCommandQueue.Count() == 1))
+        {
+        CompleteClient(aError);
+        }
+
+    //    CompleteClient(aError);
+    if (IsActive())
+        {
+        Complete(aError);
+        }
+    
+    if (iSubCommandQueue.Count())
+        {
+        iSubCommandQueue.Pop();
+        }
+    
+    return KErrNone;
+    }
+
+// Private member functions
+CDeviceEventHandler::CDeviceEventHandler(MMsmmSrvProxy& aServer):
+    CActive(EPriorityStandard),
+    iServer(aServer)
+    {
+    LOG_FUNC
+    CActiveScheduler::Add(this);
+    }
+
+void CDeviceEventHandler::ConstructL()
+    {
+    LOG_FUNC
+    iErrNotiData = new (ELeave) THostMsErrData;
+    ResetHandler();
+    }
+
+void CDeviceEventHandler::CreateSubCmdForDeviceEventL()
+    {
+    LOG_FUNC
+    switch (iIncomingEvent.iEvent)
+        {
+    case EDeviceEventAddFunction:
+        CreateSubCmdForAddingUsbMsFunctionL();
+        break;
+    case EDeviceEventRemoveDevice:
+        CreateSubCmdForRemovingUsbMsDeviceL();
+        break;
+        }
+    }
+
+void CDeviceEventHandler::CreateSubCmdForAddingUsbMsFunctionL()
+    {
+    LOG_FUNC
+    THostMsSubCommandParam parameter(iServer, *this, *this, iIncomingEvent);
+    TRegisterInterface* command = new (ELeave) TRegisterInterface(parameter);
+    iSubCommandQueue.PushL(command);
+    }
+
+void CDeviceEventHandler::CreateSubCmdForRemovingUsbMsDeviceL()
+    {
+    LOG_FUNC
+    CMsmmEngine& engine = iServer.Engine();
+    TUsbMsDevice* device = engine.SearchDevice(iIncomingEvent.iDeviceId);
+    if (!device)
+        {
+        User::Leave(KErrNotFound);
+        }
+    TUsbMsInterface* interface = device->FirstChild();
+    THostMsSubCommandParam parameter(iServer, *this, *this, iIncomingEvent);
+    while (interface)
+        {
+        TUsbMsLogicalUnit* logicalUnit = interface->FirstChild();
+        while (logicalUnit)
+            {
+            TDismountLogicalUnit* dismount = 
+                new (ELeave) TDismountLogicalUnit(parameter, *logicalUnit);
+            iSubCommandQueue.PushL(dismount);
+            logicalUnit = logicalUnit->NextPeer();
+            }
+        TDeregisterInterface* deregister = new (ELeave) TDeregisterInterface(
+                parameter, 
+                interface->iInterfaceNumber, interface->iInterfaceToken);
+        iSubCommandQueue.PushL(deregister);
+        interface = interface->NextPeer();
+        };
+    TRemoveUsbMsDeviceNode* removeNode = 
+        new (ELeave) TRemoveUsbMsDeviceNode(parameter, device);
+    iSubCommandQueue.PushL(removeNode);
+    }
+
+void CDeviceEventHandler::ResetHandler()
+    {
+    LOG_FUNC
+    ResetHandlerData();
+    ResetHandlerError();
+    }
+
+void CDeviceEventHandler::ResetHandlerData()
+    {
+    LOG_FUNC
+    // Reset event buffer
+    iIncomingEvent.iDeviceId = 0;
+    iIncomingEvent.iEvent = EDeviceEventEndMark;
+    iIncomingEvent.iInterfaceNumber = 0;
+    
+    // Destory sub-command queue
+    iSubCommandQueue.Release();
+    }
+
+void CDeviceEventHandler::ResetHandlerError()
+    {
+    LOG_FUNC
+    // Reset error notification data
+    iErrNotiData->iDriveName = 0x0;
+    iErrNotiData->iError = EHostMsErrorEndMarker;
+    iErrNotiData->iE32Error = KErrNone;
+    iErrNotiData->iManufacturerString.Zero();
+    }
+
+void CDeviceEventHandler::CompleteClient(TInt aError/* = KErrNone*/)
+    {
+    LOG_FUNC
+    if (iEvtQueueStatus)
+        {
+        User::RequestComplete(iEvtQueueStatus, aError);
+        }
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/eventqueue.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,240 @@
+/*
+* 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 "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
+*/
+
+#include "eventqueue.h"
+#include "eventhandler.h"
+#include "msmmserver.h"
+#include "msmmnodebase.h"
+#include "msmmengine.h"
+#include <usb/hostms/msmmpolicypluginbase.h>
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmServer");
+#endif
+
+// Public member functions
+CDeviceEventQueue::~CDeviceEventQueue( )
+    {
+    LOG_FUNC
+    Cancel();
+    delete iHandler;
+    iEventArray.Close();
+    }
+
+CDeviceEventQueue* CDeviceEventQueue::NewL(MMsmmSrvProxy& aServer)
+    {
+    LOG_STATIC_FUNC_ENTRY
+    CDeviceEventQueue* self = CDeviceEventQueue::NewLC(aServer);
+    CleanupStack::Pop(self);
+    
+    return self;
+    }
+CDeviceEventQueue* CDeviceEventQueue::NewLC(MMsmmSrvProxy& aServer)
+    {
+    LOG_STATIC_FUNC_ENTRY
+    CDeviceEventQueue* self = new (ELeave) CDeviceEventQueue(aServer);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    
+    return self;
+    }
+
+void CDeviceEventQueue::PushL(const TDeviceEvent& aEvent)
+    {
+    LOG_FUNC
+    
+    // Perform optimization for remove device event
+    AppendAndOptimizeL(aEvent);
+    
+    // Start handling first event in queue
+    StartL();
+    }
+
+void CDeviceEventQueue::Finalize()
+    {
+    TInt index(0);
+    while(index < iEventArray.Count())
+        {
+        if (EDeviceEventAddFunction == iEventArray[index].iEvent)
+            {
+            iEventArray.Remove(index);
+            }
+        else
+            {
+            index ++;
+            }
+        };
+    
+    if (EDeviceEventAddFunction == iHandler->Event().iEvent)
+        {
+        iHandler->Cancel();
+        }
+    }
+
+
+// Protected member functions
+void CDeviceEventQueue::DoCancel()
+    {
+    LOG_FUNC
+    iEventArray.Reset();
+    iHandler->Cancel();
+    }
+
+void CDeviceEventQueue::RunL()
+    {
+    LOG_FUNC
+    // Check the completion code from CDeviceEventHandler. If there
+    // is some error occured. We need issue error notification here.
+    TInt err = iStatus.Int();
+    if ((KErrNone != err) && (KErrCancel != err))
+        {
+        iServer.PolicyPlugin()->
+            SendErrorNotificationL(iHandler->ErrNotiData());
+        }
+    iHandler->ResetHandler();
+    if (IsEventAvailable())
+        {
+        SendEventL();
+        }
+    }
+
+TInt CDeviceEventQueue::RunError(TInt aError)
+    {
+    LOG_FUNC
+    THostMsErrData errData;
+    switch (aError)
+        {
+    case KErrNoMemory:
+        errData.iError = EHostMsErrOutOfMemory;
+        break;
+    case KErrArgument:
+        errData.iError = EHostMsErrInvalidParameter;
+        break;
+    default:
+        errData.iError = EHostMsErrGeneral;
+        }
+    errData.iE32Error = aError;
+    TUsbMsDevice* deviceNode = 
+        iServer.Engine().SearchDevice(iHandler->Event().iDeviceId);
+    if (deviceNode)
+        {
+        errData.iManufacturerString.Copy(deviceNode->iDevice.iManufacturerString);
+        errData.iProductString.Copy(deviceNode->iDevice.iProductString);
+        }
+    errData.iDriveName = 0x0;
+    TInt err(KErrNone);
+    TRAP(err, iServer.PolicyPlugin()->SendErrorNotificationL(errData));
+    return KErrNone;
+    }
+
+// Private member functions
+CDeviceEventQueue::CDeviceEventQueue(MMsmmSrvProxy& aServer):
+CActive(EPriorityStandard),
+iServer(aServer)
+    {
+    LOG_FUNC
+    CActiveScheduler::Add(this);
+    }
+
+void CDeviceEventQueue::ConstructL()
+    {
+    LOG_FUNC
+    iHandler = CDeviceEventHandler::NewL(iServer);
+    }
+
+void CDeviceEventQueue::AppendAndOptimizeL(const TDeviceEvent& aEvent)
+    {
+    LOG_FUNC
+    if (EDeviceEventRemoveDevice == aEvent.iEvent)
+        {
+        // Scan the event queue to discard all pending related adding 
+        // function events.
+        TInt index(0);
+        while(index < iEventArray.Count())
+            {
+        	if (aEvent.iDeviceId == iEventArray[index].iDeviceId)
+        	    {
+        	    iEventArray.Remove(index);
+        	    }
+        	else
+        	    {
+        	    index ++;
+        	    }
+            };
+        
+        switch (iHandler->Event().iEvent)
+            {
+        case EDeviceEventAddFunction:
+            // If a related adding interface event is being handled currently,
+            // CDeviceEventQueue shall cancel it first.
+            if (aEvent.iDeviceId == iHandler->Event().iDeviceId)
+                {
+                iHandler->Cancel();
+                }
+            break;
+        case EDeviceEventRemoveDevice:
+            if (aEvent.iDeviceId == iHandler->Event().iDeviceId && IsActive())
+                {
+                // Discard duplicated removing event.
+                return;
+                }
+            break;
+            }
+        }
+        iEventArray.AppendL(aEvent);
+    }
+
+void CDeviceEventQueue::StartL()
+    {
+    LOG_FUNC
+    if (IsActive())
+        {
+        return;
+        }
+
+    if (IsEventAvailable())
+        {
+        SendEventL();
+        }
+    }
+
+void CDeviceEventQueue::SendEventL()
+    {
+    LOG_FUNC     
+    // If the handler is available, sending oldest event to it
+    iHandler->HandleEventL(iStatus, Pop());
+        
+    // Activiate the manager again to wait for the handler 
+    // finish current event
+    SetActive();
+    }
+
+TDeviceEvent CDeviceEventQueue::Pop()
+    {
+    LOG_FUNC
+    TDeviceEvent event = iEventArray[0];
+    iEventArray.Remove(0);
+    return event;
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/main.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* 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 "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
+*/
+
+#include "msmmserver.h"
+
+// Server entry point
+
+TInt E32Main()
+    {
+    return CMsmmServer::ThreadFunction();
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmengine.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,170 @@
+/*
+* 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 "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
+*/
+
+#include "msmmengine.h"
+#include "msmmnodebase.h"
+
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmServer");
+#endif
+
+CMsmmEngine::~CMsmmEngine()
+    {
+    LOG_FUNC
+    if (iDataEntrys)
+        {
+        delete iDataEntrys;
+        }
+    }
+
+CMsmmEngine* CMsmmEngine::NewL()
+    {
+    LOG_STATIC_FUNC_ENTRY
+    CMsmmEngine* self = CMsmmEngine::NewLC();
+    CleanupStack::Pop(self);
+    
+    return self;
+    }
+
+CMsmmEngine* CMsmmEngine::NewLC()
+    {
+    LOG_STATIC_FUNC_ENTRY
+    CMsmmEngine* self = new (ELeave) CMsmmEngine();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    
+    return self;
+    }
+
+void CMsmmEngine::AddUsbMsDeviceL(const TUSBMSDeviceDescription& aDevice)
+    {
+    LOG_FUNC
+    TUsbMsDevice* device = SearchDevice(aDevice.iDeviceId);
+    if (!device)
+        {
+        device = new (ELeave) TUsbMsDevice(aDevice);
+        iDataEntrys->AddChild(device);
+        }
+    }
+
+TUsbMsInterface* CMsmmEngine::AddUsbMsInterfaceL(TInt aDeviceId, TUint8 aInterfaceNumber,
+        TInt32 aInterfaceToken)
+    {
+    LOG_FUNC
+    TUsbMsDevice* device = SearchDevice(aDeviceId);
+    if (!device)
+        {
+        User::Leave(KErrArgument);
+        }
+    TUsbMsInterface* interface = 
+        SearchInterface(device, aInterfaceNumber);
+    if (interface)
+        {
+        User::Leave(KErrAlreadyExists);
+        }
+    else
+        {
+        interface = AddUsbMsInterfaceNodeL(device, aInterfaceNumber, aInterfaceToken);
+        }
+    return interface;
+    }
+
+void CMsmmEngine::AddUsbMsLogicalUnitL(TInt aDeviceId,
+        TInt aInterfaceNumber, TInt aLogicalUnitNumber, TText aDrive)
+    {
+    LOG_FUNC
+    TUsbMsDevice* device = SearchDevice(aDeviceId);
+    if (!device)
+        {
+        User::Leave(KErrArgument); // A proper device node can't be found
+        }
+    
+    TUsbMsInterface* interface = SearchInterface(device, aInterfaceNumber);
+    if (interface)
+        {
+        AddUsbMsLogicalUnitNodeL(interface, aLogicalUnitNumber, aDrive);
+        }
+    else
+        {
+        User::Leave(KErrArgument); // A proper interface node can't be found
+        }
+    }
+
+void CMsmmEngine::RemoveUsbMsNode(TMsmmNodeBase* aNodeToBeRemoved)
+    {
+    LOG_FUNC
+    delete aNodeToBeRemoved;
+    }
+
+TUsbMsDevice* CMsmmEngine::SearchDevice(TInt aDeviceId) const
+    {
+    LOG_FUNC
+    return static_cast<TUsbMsDevice*>(
+            iDataEntrys->SearchInChildren(aDeviceId));
+    }
+
+TUsbMsInterface* CMsmmEngine::SearchInterface(TMsmmNodeBase* aDevice, 
+        TInt aInterfaceNumber) const
+    {
+    LOG_FUNC
+    return static_cast<TUsbMsInterface*>(
+            aDevice->SearchInChildren(aInterfaceNumber));
+    }
+
+CMsmmEngine::CMsmmEngine()
+    {
+    LOG_FUNC
+    }
+
+void CMsmmEngine::ConstructL()
+    {
+    LOG_FUNC
+    // Create the root of the whole node tree
+    iDataEntrys = new (ELeave) TMsmmNodeBase(0x0);
+    }
+
+TUsbMsInterface* CMsmmEngine::AddUsbMsInterfaceNodeL(TUsbMsDevice* iParent,
+        TInt aInterfaceNumber, TInt aInterfaceToken)
+    {
+    LOG_FUNC    
+    TUsbMsInterface* interface = new (ELeave) TUsbMsInterface(
+            aInterfaceNumber, aInterfaceToken);
+    iParent->AddChild(interface);
+    
+    return interface;
+    }
+
+TUsbMsLogicalUnit* CMsmmEngine::AddUsbMsLogicalUnitNodeL(
+        TUsbMsInterface* iParent, TInt aLogicalUnitNumber, 
+        TText aDrive)
+    {
+    LOG_FUNC
+    TUsbMsLogicalUnit* logicalUnit = new (ELeave) TUsbMsLogicalUnit(
+            aLogicalUnitNumber, aDrive);
+    iParent->AddChild(logicalUnit);
+    
+    return logicalUnit;
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmnodebase.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,184 @@
+/*
+* 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 "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
+*/
+
+#include "msmmnodebase.h"
+
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmServer");
+#endif
+
+TMsmmNodeBase::TMsmmNodeBase(TInt aIdentifier):
+iIdentifier(aIdentifier),
+iNextPeer(NULL),
+iFirstChild(NULL),
+iLastChild(NULL),
+iParent(NULL)
+    {
+    LOG_FUNC
+    }
+
+TMsmmNodeBase::~TMsmmNodeBase()
+    {
+    LOG_FUNC
+    // Remove current node from the parent node and destroy it.
+    DestroyNode(); 
+    }
+
+void TMsmmNodeBase::DestroyNode()
+    {
+    LOG_FUNC
+    TMsmmNodeBase* parentNode = iParent; 
+    TMsmmNodeBase* iterator(this);
+    TMsmmNodeBase* iteratorPrev(NULL);
+    TMsmmNodeBase* iteratorNext(NULL);
+    
+    if (parentNode)
+        {
+        // A parent node exists
+        iterator = parentNode->iFirstChild;
+        if (iterator)
+            {
+            // iteratorPrev equal NULL at beginning;
+            iteratorNext= iterator->iNextPeer;
+            }
+        // Go through each child node to find the node to be destroyed
+        while (iterator && (iterator != this))
+            {
+            iteratorPrev = iterator;
+            iterator = iteratorNext;
+            if(iteratorNext)
+                {
+                iteratorNext = iteratorNext->iNextPeer;
+                }
+            }
+        if (iterator)
+            {
+            // Matched node found
+            if (parentNode->iLastChild == iterator)
+                {
+                parentNode->iLastChild = iteratorPrev;
+                }
+            if (iteratorPrev)
+                {
+                iteratorPrev->iNextPeer = iteratorNext;
+                }
+            else
+                {
+                parentNode->iFirstChild = iteratorNext;
+                }
+            }
+        else
+            {
+            // No matched node
+            return;
+            }
+        }
+        
+    // Remove all children node
+    if (iFirstChild)
+        {
+        // Current node isn't a leaf node
+        iterator = iFirstChild;
+        iteratorNext= iterator->iNextPeer;
+        while (iterator)
+            {
+            delete iterator;
+            iterator = iteratorNext;
+            if (iteratorNext)
+                {
+                iteratorNext = iterator->iNextPeer;
+                }
+            }
+        }
+    }
+
+void TMsmmNodeBase::AddChild(TMsmmNodeBase* aChild)
+    {
+    LOG_FUNC
+    if (!iFirstChild)
+        {
+        iFirstChild = aChild;
+        }
+    else
+        {
+        iLastChild->iNextPeer = aChild;
+        }
+    iLastChild = aChild;
+    aChild->iParent = this;
+    }
+
+TMsmmNodeBase* TMsmmNodeBase::SearchInChildren(TInt aIdentifier)
+    {
+    LOG_FUNC
+    TMsmmNodeBase* iterator(iFirstChild);
+    
+    while (iterator)
+        {
+        if (iterator->iIdentifier == aIdentifier)
+            {
+            break;
+            }
+        iterator = iterator->iNextPeer;
+        }
+    
+    return iterator;
+    }
+
+// TUsbMsDevice
+// Function memeber
+TUsbMsDevice::TUsbMsDevice(const TUSBMSDeviceDescription& aDevice):
+TMsmmNodeBase(aDevice.iDeviceId),
+iDevice(aDevice)
+    {
+    LOG_FUNC
+    }
+
+// TUsbMsInterface
+// Function memeber
+TUsbMsInterface::TUsbMsInterface(TUint8 aInterfaceNumber, 
+        TUint32 aInterfaceToken):
+TMsmmNodeBase(aInterfaceNumber), 
+iInterfaceNumber(aInterfaceNumber),
+iInterfaceToken(aInterfaceToken)
+    {
+    LOG_FUNC
+    }
+
+TUsbMsInterface::~TUsbMsInterface()
+    {
+    LOG_FUNC
+    iUsbMsDevice.Close();
+    }
+
+// TUsbMsLogicalUnit
+// Function memeber
+TUsbMsLogicalUnit::TUsbMsLogicalUnit(TUint8 aLogicalUnitNumber, TText aDrive):
+TMsmmNodeBase(aLogicalUnitNumber),
+iLogicalUnitNumber(aLogicalUnitNumber),
+iDrive(aDrive)
+    {
+    LOG_FUNC
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmserver.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,230 @@
+/*
+* 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 "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
+*/
+
+#include "msmmserver.h"
+#include <usb/hostms/msmmpolicypluginbase.h>
+#include "msmm_internal_def.h"
+#include "msmmsession.h"
+#include "msmmengine.h"
+#include "eventqueue.h"
+#include "msmmterminator.h"
+
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmServer");
+#endif
+
+//  Static public functions
+TInt CMsmmServer::ThreadFunction()
+    {
+    TInt ret = KErrNone;
+    
+    __UHEAP_MARK;
+    // Create the cleanup stack
+    CTrapCleanup* cleanupStack = CTrapCleanup::New();
+    if (cleanupStack)
+        {
+#ifdef __FLOG_ACTIVE
+        (void)CUsbLog::Connect();
+#endif
+
+        TRAP(ret, ThreadFunctionL());
+
+#ifdef __FLOG_ACTIVE
+        CUsbLog::Close();
+#endif
+        
+        delete cleanupStack;
+        }
+    else
+        {
+        ret = KErrNoMemory;
+        }
+    __UHEAP_MARKEND;
+    
+    return ret;
+    }
+
+void CMsmmServer::ThreadFunctionL()
+    {
+    LOG_STATIC_FUNC_ENTRY
+    
+    TSecureId creatorSID = User::CreatorSecureId();
+    if (KFDFWSecureId != creatorSID)
+        {
+        // Only FDF process can be the creator of the MSMM server
+        User::Leave(KErrPermissionDenied);
+        }
+    
+    // Create and install the active scheduler
+    CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
+    CleanupStack::PushL(scheduler);
+    CActiveScheduler::Install(scheduler);
+
+    // Create the server and leave it on cleanup stack
+    CMsmmServer::NewLC();
+
+    // Signal the client that the server is up and running
+    RProcess::Rendezvous(KErrNone);
+    
+    RThread().SetPriority(EPriorityAbsoluteHigh);
+
+    // Start the active scheduler, the server will now service 
+    // request messages from clients.
+    CActiveScheduler::Start();
+
+    // Free the server and active scheduler.
+    CleanupStack::PopAndDestroy(2, scheduler);
+    }
+
+// Public functions
+// Construction and destruction
+CMsmmServer* CMsmmServer::NewLC()
+    {
+    LOG_STATIC_FUNC_ENTRY
+    CMsmmServer* self = new (ELeave) CMsmmServer(EPriorityHigh);
+    CleanupStack::PushL(self);
+    
+    // Create a server with unique server name
+    self->StartL(KMsmmServerName);
+    self->ConstructL();
+    
+    return self;
+    }
+
+CMsmmServer::~CMsmmServer()
+    {
+    LOG_FUNC
+    delete iPolicyPlugin;
+    delete iEventQueue;
+    delete iEngine;
+    delete iTerminator;
+    REComSession::FinalClose();
+
+#ifndef __OVER_DUMMYCOMPONENT__
+    iFs.RemoveProxyDrive(KPROXYDRIVENAME);
+    iFs.Close();
+#endif
+    }
+    
+    // CMsmmServer APIs
+CSession2* CMsmmServer::NewSessionL(const TVersion& aVersion, 
+        const RMessage2& aMessage) const
+    {
+    LOG_FUNC
+    
+    if (KMaxClientCount <= SessionNumber())
+        {
+        // There is a connection to MSMM server already.
+        // Currently design of MSMM allows only one activated client 
+        // at any time.
+        User::Leave(KErrInUse);
+        }
+    
+    // Check the client-side API version number against the server version 
+    // number.
+    TVersion serverVersion(KMsmmServMajorVersionNumber,
+        KMsmmServMinorVersionNumber, KMsmmServBuildVersionNumber);
+    
+    if (!User::QueryVersionSupported(serverVersion, aVersion))
+        {
+        // Server version incompatible with client-side API
+        PanicClient(aMessage, ENoSupportedVersion);
+        User::Leave(KErrNotSupported);
+        }
+
+    // Version number is OK - create the session
+    return CMsmmSession::NewL(*(const_cast<CMsmmServer*>(this)), *iEventQueue);
+    }
+
+TInt CMsmmServer::SessionNumber() const
+    {
+    LOG_FUNC
+    
+    return iNumSessions;
+    }
+
+void CMsmmServer::AddSession()
+    {
+    LOG_FUNC
+    
+    ++iNumSessions;
+    iTerminator->Cancel();
+    }
+
+void CMsmmServer::RemoveSession()
+    {
+    LOG_FUNC
+    
+    --iNumSessions;
+    if (iNumSessions == 0)
+        {
+        // Discard all pending adding interface events from queue
+        // and cancel event handler if a adding events is being 
+        // handled in it.
+        iEventQueue->Finalize();
+        iTerminator->Cancel();
+        iTerminator->Start();
+        }
+    }
+
+//  Private functions 
+// CMsmmServer Construction
+CMsmmServer::CMsmmServer(TInt aPriority)
+    :CPolicyServer(aPriority, KMsmmServerSecurityPolicy, EUnsharableSessions)
+    {
+    LOG_FUNC
+    //
+    }
+
+void CMsmmServer::ConstructL()
+    {
+    LOG_FUNC
+    
+    iEngine = CMsmmEngine::NewL();
+    iEventQueue = CDeviceEventQueue::NewL(*this);
+    iTerminator = CMsmmTerminator::NewL(*iEventQueue);
+    iPolicyPlugin = CMsmmPolicyPluginBase::NewL();
+    if (!iPolicyPlugin)
+        {
+        // Not any policy plugin implementation available
+        PanicServer(ENoPolicyPlugin);
+        }
+    
+    // Initalize RFs connection and add the ELOCAL file system to file server
+    User::LeaveIfError(iFs.Connect());
+
+#ifndef __OVER_DUMMYCOMPONENT__
+    TInt ret(KErrNone);
+    ret = iFs.AddProxyDrive(KFSEXTNAME);
+    if ((KErrNone != ret) && (KErrAlreadyExists !=  ret))
+        {
+        User::Leave(ret);
+        }
+#endif
+    
+    // Start automatic shutdown timer
+    iTerminator->Start();
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmsession.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,180 @@
+/*
+* 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 "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
+*/
+
+#include "msmmsession.h"
+#include "msmmserver.h"
+#include "msmmengine.h"
+#include "eventqueue.h"
+#include <usb/hostms/srverr.h>
+#include <usb/hostms/msmmpolicypluginbase.h>
+#include "msmmnodebase.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmServer");
+#endif
+
+CMsmmSession::~CMsmmSession()
+    {
+    LOG_FUNC
+    delete iErrData;
+    iServer.RemoveSession();
+    }
+
+CMsmmSession* CMsmmSession::NewL(CMsmmServer& aServer, 
+        CDeviceEventQueue& anEventQueue)
+    {
+    LOG_STATIC_FUNC_ENTRY
+    CMsmmSession* self = new(ELeave) CMsmmSession(aServer, anEventQueue);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+void CMsmmSession::ServiceL(const RMessage2& aMessage)
+    {
+    LOG_STATIC_FUNC_ENTRY
+    TInt ret(KErrNone);
+
+#ifdef _DEBUG
+    TInt* heapObj= NULL;
+#endif // _DEBUG
+        
+    switch (aMessage.Function())
+        {
+    case EHostMsmmServerAddFunction:
+        AddUsbMsInterfaceL(aMessage);
+        break;
+
+    case EHostMsmmServerRemoveDevice:
+        RemoveUsbMsDeviceL(aMessage);
+        break;
+
+        // Supporting for server side OOM testing  
+    case EHostMsmmServerDbgFailNext:
+        ret = KErrNone;
+#ifdef _DEBUG
+        if (aMessage.Int0() == 0 )
+            {
+            __UHEAP_RESET;
+            }
+        else
+            {
+            __UHEAP_FAILNEXT(aMessage.Int0());
+            }
+#endif // _DEBUG
+        break;
+
+    case EHostMsmmServerDbgAlloc:
+        ret = KErrNone;
+#ifdef _DEBUG
+        TRAP(ret, heapObj = new (ELeave) TInt);
+        delete heapObj;
+#endif // _DEBUG
+        break;
+
+    default:
+        // Unsupported function number - panic the client
+        PanicClient(aMessage, EBadRequest);
+        }
+        
+    // Complete the request
+    aMessage.Complete(ret);
+    }
+
+void CMsmmSession::ServiceError(const RMessage2 &aMessage, TInt aError)
+    {
+    LOG_FUNC
+    CMsmmPolicyPluginBase* plugin = iServer.PolicyPlugin();    
+    TUSBMSDeviceDescription& device = iDevicePkg();
+       
+    switch (aError)
+        {
+    case KErrNoMemory:
+        iErrData->iError = EHostMsErrOutOfMemory;
+        break;
+    case KErrArgument:
+        iErrData->iError = EHostMsErrInvalidParameter;
+        break;
+    case KErrNotFound:
+        iErrData->iError = EHostMsErrInvalidParameter;
+        break;
+    default:
+        iErrData->iError = EHostMsErrGeneral;
+        }
+    
+    iErrData->iE32Error = aError;
+    iErrData->iManufacturerString = device.iManufacturerString;
+    iErrData->iProductString = device.iProductString;
+    iErrData->iDriveName = 0x0;
+   
+    TInt err(KErrNone);
+    TRAP(err, plugin->SendErrorNotificationL(*iErrData));
+    aMessage.Complete(aError);
+    }
+
+CMsmmSession::CMsmmSession(CMsmmServer& aServer, 
+        CDeviceEventQueue& anEventQueue) :
+iServer(aServer),
+iEngine(aServer.Engine()),
+iEventQueue(anEventQueue)
+    {
+    LOG_FUNC
+    aServer.AddSession();
+    }
+
+void CMsmmSession::ConstructL()
+    {
+    LOG_FUNC
+    iErrData = new (ELeave) THostMsErrData;
+    }
+
+void CMsmmSession::AddUsbMsInterfaceL(const RMessage2& aMessage)
+    {
+    LOG_FUNC
+    aMessage.Read(0, iDevicePkg);
+    iInterfaceNumber = aMessage.Int1();
+    iInterfaceToken = static_cast<TInt32>(aMessage.Int2());
+    TUSBMSDeviceDescription& device = iDevicePkg();
+    
+    // Put currently adding USB MS function related device 
+    // information into engine
+    iEngine.AddUsbMsDeviceL(device);
+    
+    // Put device event into queue
+    TDeviceEvent event(EDeviceEventAddFunction, 
+            device.iDeviceId, iInterfaceNumber, iInterfaceToken);
+    iEventQueue.PushL(event);
+    }
+
+void CMsmmSession::RemoveUsbMsDeviceL(const RMessage2& aMessage)
+    {
+    LOG_FUNC
+    iDeviceID = aMessage.Int0();
+       
+    // Put device event into queue
+    TDeviceEvent event(EDeviceEventRemoveDevice, iDeviceID, 0, 0);
+    iEventQueue.PushL(event);
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmterminator.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,80 @@
+/*
+* 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 "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
+*/
+
+#include "msmmterminator.h"
+#include "eventqueue.h"
+
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmServer");
+#endif
+
+const TInt KShutdownDelay = 2000000; // approx 2 seconds
+const TInt KMsmmTerminatorPriority = CActive::EPriorityStandard;
+
+CMsmmTerminator* CMsmmTerminator::NewL(const CDeviceEventQueue& anEventQueue)
+    {
+    LOG_STATIC_FUNC_ENTRY
+    CMsmmTerminator* self = new (ELeave) CMsmmTerminator(anEventQueue);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+void CMsmmTerminator::Start()
+    {
+    LOG_FUNC
+    After(KShutdownDelay);
+    }
+
+void CMsmmTerminator::RunL()
+    {
+    LOG_FUNC
+    if (iEventQueue.Count())
+        {
+        // There are some events still in the event queue to 
+        // wait to be handled. Restart the shutdown timer.
+        Start();
+        }
+    else
+        {
+        CActiveScheduler::Stop();
+        }
+    }
+
+CMsmmTerminator::CMsmmTerminator(const CDeviceEventQueue& anEventQueue):
+CTimer(KMsmmTerminatorPriority),
+iEventQueue(anEventQueue)
+    {
+    LOG_FUNC
+    CActiveScheduler::Add(this);
+    }
+
+void CMsmmTerminator::ConstructL()
+    {
+    LOG_FUNC
+    CTimer::ConstructL();
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/subcommandbase.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,87 @@
+/*
+* 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 "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
+*/
+
+#include "subcommandbase.h"
+#include "msmm_internal_def.h"
+#include "msmmserver.h"
+#include "eventhandler.h"
+
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmServer");
+#endif
+
+THostMsSubCommandParam::THostMsSubCommandParam(MMsmmSrvProxy& aServer, 
+        MUsbMsEventHandler& aHandler, 
+        MUsbMsSubCommandCreator& aCreator, 
+        TDeviceEvent& aEvent) :
+    iServer(aServer),
+    iHandler(aHandler),
+    iCreator(aCreator),
+    iEvent(aEvent)
+    {
+    LOG_FUNC
+    }
+
+TSubCommandBase::TSubCommandBase(THostMsSubCommandParam& aParameter):
+iServer(aParameter.iServer),
+iHandler(aParameter.iHandler),
+iCreator(aParameter.iCreator),
+iEvent(aParameter.iEvent),
+iIsExecuted(EFalse),
+iIsKeyCommand(ETrue)
+    {
+    LOG_FUNC
+    }
+
+void TSubCommandBase::ExecuteL()
+    {
+    iIsExecuted = ETrue;
+    DoExecuteL();
+    }
+
+void TSubCommandBase::AsyncCmdCompleteL()
+    {
+    LOG_FUNC
+    DoAsyncCmdCompleteL();
+    }
+
+void TSubCommandBase::CancelAsyncCmd()
+    {
+    LOG_FUNC
+    DoCancelAsyncCmd();
+    }
+
+void TSubCommandBase::DoAsyncCmdCompleteL()
+    {
+    LOG_FUNC
+    // Empty implementation
+    }
+
+void TSubCommandBase::DoCancelAsyncCmd()
+    {
+    LOG_FUNC
+    // Empty implementation
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/subcommands.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,624 @@
+/*
+* 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 "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
+*/
+
+#include "subcommands.h"
+#include "msmmserver.h"
+#include "msmmengine.h"
+#include "msmmnodebase.h"
+#include "handlerinterface.h"
+#include "msmm_internal_def.h"
+#include <usb/hostms/msmmpolicypluginbase.h>
+#include <usb/hostms/srverr.h>
+
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "UsbHostMsmmServer");
+#endif
+
+/**
+ *  TRegisterInterface member functions
+ */
+TRegisterInterface::TRegisterInterface(THostMsSubCommandParam aParam):
+TSubCommandBase(aParam),
+iDeviceNode(NULL),
+iInterfaceNode(NULL)
+    {
+    LOG_FUNC
+    }
+
+void TRegisterInterface::DoExecuteL()
+    {
+    LOG_FUNC
+      
+    // Add new interface node into data engine
+    iInterfaceNode = iServer.Engine().AddUsbMsInterfaceL(iEvent.iDeviceId, 
+            iEvent.iInterfaceNumber, iEvent.iInterfaceToken);
+    
+    iDeviceNode = iServer.Engine().SearchDevice(iEvent.iDeviceId);
+    if (!iDeviceNode)
+        {
+        User::Leave(KErrArgument);
+        }
+    
+    TUSBMSDeviceDescription& device = iDeviceNode->iDevice;
+
+    iMsConfig.iInterfaceToken = iEvent.iInterfaceToken;
+    iMsConfig.iInterfaceNumber = iEvent.iInterfaceNumber;        
+    iMsConfig.iVendorId = device.iVendorId;
+    iMsConfig.iProductId = device.iProductId;
+    iMsConfig.iBcdDevice = device.iBcdDevice;
+    iMsConfig.iConfigurationNumber = device.iConfigurationNumber;        
+    iMsConfig.iSerialNumber.Copy(device.iSerialNumber);
+    iMsConfig.iProtocolId = device.iProtocolId;
+    iMsConfig.iTransportId = device.iTransportId;
+    iMsConfig.iRemoteWakeup = device.iRemoteWakeup;
+    iMsConfig.iIsOtgClient = device.iIsOtgClient;
+
+    LOGTEXT2(_L8("\t iMsConfig.iProtocolId %d"), iMsConfig.iProtocolId);
+    LOGTEXT2(_L8("\t iMsConfig.iTransportId %d"), iMsConfig.iTransportId);
+    LOGTEXT2(_L8("\t iMsConfig.iRemoteWakeup %d"), iMsConfig.iRemoteWakeup);
+    LOGTEXT2(_L8("\t iMsConfig.iIsOtgClient %d"), iMsConfig.iIsOtgClient);
+
+    TSuspensionPolicy suspensionPolicy;
+    iServer.PolicyPlugin()->GetSuspensionPolicy(suspensionPolicy);
+    iMsConfig.iOtgSuspendTime = suspensionPolicy.iOtgSuspendTime;
+    iMsConfig.iStatusPollingInterval = suspensionPolicy.iStatusPollingInterval;
+
+    LOGTEXT2(_L8("\t iMsConfig.iStatusPollingInterval %d"), iMsConfig.iStatusPollingInterval);
+    LOGTEXT2(_L8("\t iMsConfig.iOtgSuspendTime %d"), iMsConfig.iOtgSuspendTime);
+
+    iHandler.Start();
+    iInterfaceNode->iUsbMsDevice.Add(iMsConfig, iHandler.Status());
+    }
+
+void TRegisterInterface::HandleError(THostMsErrData& aData, TInt aError)
+    {
+    LOG_FUNC
+    
+    switch (aError)
+        {
+    case KErrNoMemory:
+        aData.iError = EHostMsErrOutOfMemory;
+        break;
+    case KErrAlreadyExists:
+    case KErrArgument:
+        aData.iError = EHostMsErrInvalidParameter;
+        break;
+    default:
+        aData.iError = EHostMsErrGeneral;
+        }
+    aData.iE32Error = aError;
+    if (iDeviceNode)
+        {
+        TUSBMSDeviceDescription& device = iDeviceNode->iDevice;
+        aData.iManufacturerString.Copy(device.iManufacturerString);
+        aData.iProductString.Copy(device.iProductString);
+        aData.iDriveName = 0x0;        
+        }
+    if (iInterfaceNode)
+        {
+        iServer.Engine().RemoveUsbMsNode(iInterfaceNode);
+        iInterfaceNode = NULL;
+        }
+    }
+
+void TRegisterInterface::DoAsyncCmdCompleteL()
+    {
+    LOG_FUNC
+    
+    User::LeaveIfError(iHandler.Status().Int());
+    if(iInterfaceNode)
+        {
+        User::LeaveIfError(
+                iInterfaceNode->iUsbMsDevice.GetNumLun(iMaxLogicalUnit));
+        }
+
+    LOGTEXT2(_L8("\tGetNumLun %d"), iMaxLogicalUnit);
+    
+    iCreator.CreateSubCmdForRetrieveDriveLetterL(iMaxLogicalUnit);
+    }
+
+void TRegisterInterface::DoCancelAsyncCmd()
+    {
+    LOG_FUNC
+
+    if(iInterfaceNode)
+        {
+        iInterfaceNode->iUsbMsDevice.Remove();
+        iServer.Engine().RemoveUsbMsNode(iInterfaceNode);
+        iInterfaceNode = NULL;
+        }
+    }
+
+/**
+ *  TRetrieveDriveLetter member functions
+ */
+
+TRetrieveDriveLetter::TRetrieveDriveLetter(
+        THostMsSubCommandParam& aParameter, TInt aLuNumber):
+TSubCommandBase(aParameter),
+iLuNumber(aLuNumber),
+iDrive(0)
+    {
+    LOG_FUNC
+    }
+
+void TRetrieveDriveLetter::DoExecuteL()
+    {
+    LOG_FUNC
+        
+    TUsbMsDevice* deviceEntry(NULL);
+    deviceEntry = iServer.Engine().SearchDevice(iEvent.iDeviceId);
+    if (!deviceEntry)
+        {
+        User::Leave(KErrArgument);
+        }
+    else
+        {
+        TUSBMSDeviceDescription& device = deviceEntry->iDevice;
+
+        iRequestData.iBcdDevice = device.iBcdDevice;
+        iRequestData.iConfigurationNumber = device.iConfigurationNumber;
+        iRequestData.iInterfaceNumber = iEvent.iInterfaceNumber;
+        iRequestData.iDeviceId = iEvent.iDeviceId;
+        iRequestData.iProductId = device.iProductId;
+        iRequestData.iVendorId = device.iVendorId;
+        iRequestData.iLogicUnitNumber = iLuNumber;
+        iRequestData.iOtgInformation = device.iOtgInformation;
+        iRequestData.iManufacturerString = device.iManufacturerString;
+        iRequestData.iProductString = device.iProductString;
+        iRequestData.iSerialNumber = device.iSerialNumber;
+
+        iHandler.Start();
+        TRequestStatus& status = iHandler.Status();
+        iServer.PolicyPlugin()->RetrieveDriveLetterL(
+                iDrive, iRequestData, status);
+        }
+    }
+
+void TRetrieveDriveLetter::HandleError(THostMsErrData& aData, TInt aError)
+    {
+    LOG_FUNC
+    
+    switch (aError)
+        {
+    case KErrArgument:
+        aData.iError = EHostMsErrInvalidParameter;
+        break;
+    case KErrNotFound:
+        aData.iError = EHostMsErrNoDriveLetter;
+        break;
+    case KErrNoMemory:
+        aData.iError = EHostMsErrOutOfMemory;
+        break;
+    default:
+        aData.iError = EHostMsErrGeneral;
+        }
+    aData.iE32Error = aError;
+    aData.iManufacturerString = iRequestData.iManufacturerString;
+    aData.iProductString = iRequestData.iProductString;
+    aData.iDriveName = iDrive;
+    }
+
+void TRetrieveDriveLetter::DoAsyncCmdCompleteL()
+    {
+    LOG_FUNC
+    
+    User::LeaveIfError(iHandler.Status().Int());
+    
+    iCreator.CreateSubCmdForMountingLogicalUnitL(iDrive, iLuNumber);
+    }
+
+void TRetrieveDriveLetter::DoCancelAsyncCmd()
+    {
+    LOG_FUNC
+    
+    iServer.PolicyPlugin()->CancelRetrieveDriveLetter();
+    }
+
+/**
+ *  TMountLogicalUnit member functions
+ */
+
+TMountLogicalUnit::TMountLogicalUnit(THostMsSubCommandParam& aParameter,
+        TText aDrive, TInt aLuNumber):
+TSubCommandBase(aParameter),
+iDrive(aDrive),
+iLuNumber(aLuNumber)
+    {
+    LOG_FUNC
+    
+    iIsKeyCommand = EFalse;
+    }
+
+void TMountLogicalUnit::DoExecuteL()
+    {
+    LOG_FUNC
+    TInt ret(KErrNone);
+    RFs& fs = iServer.FileServerSession();
+    
+    TInt driveNum;
+    User::LeaveIfError(fs.CharToDrive(iDrive, driveNum));
+    
+    TUsbMsDevice* device = NULL;
+    TUsbMsInterface* interface = NULL;
+    device = iServer.Engine().SearchDevice(iEvent.iDeviceId);
+    if (!device)
+        {
+        User::Leave(KErrArgument);
+        }
+    interface = iServer.Engine().SearchInterface(device, iEvent.iInterfaceNumber);
+    if (!interface)
+        {
+        User::Leave(KErrArgument);
+        }
+    
+    ret = interface->iUsbMsDevice.MountLun(iLuNumber, driveNum);
+    if ((KErrNone != ret) && (KErrAlreadyExists != ret)
+            && (KErrNotReady != ret))
+        {
+        User::Leave (ret);
+        }
+
+    iHandler.Start();
+    iHandler.Complete();
+    }
+
+void TMountLogicalUnit::HandleError(THostMsErrData& aData, TInt aError)
+    {
+    LOG_FUNC
+    
+    switch (aError)
+        {
+    case KErrNoMemory:
+        aData.iError = EHostMsErrOutOfMemory;
+        break;
+    case KErrArgument:
+        aData.iError = EHostMsErrInvalidParameter;
+        break;
+    case KErrCorrupt:
+        {
+        aData.iError = EHostMsErrUnknownFileSystem;
+
+        // Current implementation of USB Mass Storage extension will mount
+        // a logical unit successfully even the logical unit is in an 
+        // unsupported format like NTFS or CDFS. So we have to recode this 
+        // Logical unit down in the our data engine in order to dismount it
+        // in future when the interface which presents this logical unit is
+        // dettached. Reuse DoAsyncCmdCompleteL to do this.
+
+        // Check if the new drive mounted successfully.
+        RFs& fs = iServer.FileServerSession();
+        TInt driveNum;
+        User::LeaveIfError(fs.CharToDrive(iDrive, driveNum));
+        
+        TDriveList drives;
+        User::LeaveIfError(fs.DriveList(drives));
+        
+        if (drives[driveNum])
+            {
+            // Drive name mounted
+            DoAsyncCmdCompleteL();
+            
+            // Restart the handler
+            iHandler.Start();
+            }
+        }
+        break;
+    default:
+        aData.iError = EHostMsErrGeneral;
+        }
+    aData.iE32Error = aError;
+    TUsbMsDevice* deviceNode = iServer.Engine().SearchDevice(iEvent.iDeviceId);
+    if (deviceNode)
+        {
+        aData.iManufacturerString.Copy(deviceNode->iDevice.iManufacturerString);
+        aData.iProductString.Copy(deviceNode->iDevice.iProductString);
+        }
+    aData.iDriveName = iDrive;
+    }
+
+void TMountLogicalUnit::DoAsyncCmdCompleteL()
+    {
+    LOG_FUNC
+   
+    iServer.Engine().AddUsbMsLogicalUnitL(
+            iEvent.iDeviceId, iEvent.iInterfaceNumber, 
+            iLuNumber, iDrive);
+    iCreator.CreateSubCmdForSaveLatestMountInfoL(iDrive, iLuNumber);
+    }
+
+/**
+ *  TSaveLatestMountInfo member functions
+ */
+
+TSaveLatestMountInfo::TSaveLatestMountInfo(
+        THostMsSubCommandParam& aParameter,
+        TText aDrive, TInt aLuNumber):
+TSubCommandBase(aParameter),
+iDrive(aDrive),
+iLuNumber(aLuNumber)
+    {
+    LOG_FUNC
+    
+    iIsKeyCommand = EFalse;
+    }
+
+void TSaveLatestMountInfo::DoExecuteL()
+    {
+    LOG_FUNC
+        
+    TUsbMsDevice* deviceEntry(NULL);
+    deviceEntry = iServer.Engine().SearchDevice(iEvent.iDeviceId);
+    if (!deviceEntry)
+        {
+        User::Leave(KErrArgument);
+        }
+    else
+        {
+        TPolicyRequestData& request = iRecord.iLogicUnit;
+        TUSBMSDeviceDescription& device = deviceEntry->iDevice;
+
+        request.iBcdDevice = device.iBcdDevice;
+        request.iConfigurationNumber = device.iConfigurationNumber;
+        request.iInterfaceNumber = iEvent.iInterfaceNumber;
+        request.iDeviceId = iEvent.iDeviceId;
+        request.iProductId = device.iProductId;
+        request.iVendorId = device.iVendorId;
+        request.iLogicUnitNumber = iLuNumber;
+        request.iOtgInformation = device.iOtgInformation;
+        request.iManufacturerString = device.iManufacturerString;
+        request.iProductString = device.iProductString;
+        request.iSerialNumber = device.iSerialNumber;
+
+        iRecord.iDriveName = iDrive;
+
+        iHandler.Start();
+        TRequestStatus& status = iHandler.Status();
+        
+        iServer.PolicyPlugin()->SaveLatestMountInfoL(iRecord, status);
+        }
+    }
+
+void TSaveLatestMountInfo::DoAsyncCmdCompleteL()
+    {
+    LOG_FUNC    
+    User::LeaveIfError(iHandler.Status().Int());
+    }
+
+void TSaveLatestMountInfo::HandleError(THostMsErrData& aData, TInt aError)
+    {
+    LOG_FUNC
+        
+    switch (aError)
+        {
+    case KErrNoMemory:
+        aData.iError = EHostMsErrOutOfMemory;
+        break;
+    case KErrArgument:
+        aData.iError = EHostMsErrInvalidParameter;
+        break;
+    default:
+        aData.iError = EHostMsErrGeneral;
+        }
+    aData.iE32Error = aError;
+    aData.iManufacturerString = iRecord.iLogicUnit.iManufacturerString;
+    aData.iProductString = iRecord.iLogicUnit.iProductString;
+    aData.iDriveName = iDrive;
+    }
+
+void TSaveLatestMountInfo::DoCancelAsyncCmd()
+    {
+    LOG_FUNC
+    
+    iServer.PolicyPlugin()->CancelSaveLatestMountInfo();
+    }
+
+
+/**
+ *  TDeregisterInterface member functions
+ */
+
+TDeregisterInterface::TDeregisterInterface(
+        THostMsSubCommandParam& aParameter, 
+        TUint8 aInterfaceNumber, TUint32 aInterfaceToken):
+TSubCommandBase(aParameter),
+iInterfaceNumber(aInterfaceNumber),
+iInterfaceToken(aInterfaceToken),
+iDeviceNode(NULL),
+iInterfaceNode(NULL)
+    {
+    LOG_FUNC
+    }
+
+void TDeregisterInterface::DoExecuteL()
+    {
+    LOG_FUNC
+   
+    iDeviceNode = iServer.Engine().SearchDevice(iEvent.iDeviceId);
+    if (!iDeviceNode)
+        {
+        User::Leave(KErrArgument);
+        }
+
+    iInterfaceNode = iServer.Engine().SearchInterface(iDeviceNode, 
+            iInterfaceNumber);
+    if (!iInterfaceNode)
+        {
+        User::Leave(KErrArgument);
+        }
+ 
+    TUSBMSDeviceDescription& device = iDeviceNode->iDevice;
+
+    iMsConfig.iInterfaceToken = iInterfaceToken;
+    iMsConfig.iVendorId = device.iVendorId;
+    iMsConfig.iProductId = device.iVendorId;
+    iMsConfig.iBcdDevice = device.iBcdDevice;
+    iMsConfig.iConfigurationNumber = device.iConfigurationNumber;
+    iMsConfig.iInterfaceNumber = iInterfaceNumber;
+    iMsConfig.iSerialNumber.Copy(device.iSerialNumber);
+    iInterfaceNode->iUsbMsDevice.Remove();
+
+    // Activate the handler.
+    iHandler.Start();
+    // Simulate a async request be completed.
+    iHandler.Complete();
+    }
+
+void TDeregisterInterface::HandleError(THostMsErrData& aData, TInt aError)
+    {
+    LOG_FUNC
+     
+    switch (aError)
+        {
+    case KErrNoMemory:
+        aData.iError = EHostMsErrOutOfMemory;
+        break;
+    case KErrArgument:
+        aData.iError = EHostMsErrInvalidParameter;
+        break;
+    default:
+        aData.iError = EHostMsErrGeneral;
+        }
+    aData.iE32Error = aError;
+    if (iDeviceNode)
+        {
+        aData.iManufacturerString.Copy(iDeviceNode->iDevice.iManufacturerString);
+        aData.iProductString.Copy(iDeviceNode->iDevice.iProductString);
+        }
+    aData.iDriveName = 0;
+    }
+
+/**
+ *  TDismountLogicalUnit member functions
+ */
+
+TDismountLogicalUnit::TDismountLogicalUnit(
+        THostMsSubCommandParam& aParameter,
+        const TUsbMsLogicalUnit& aLogicalUnit):
+TSubCommandBase(aParameter),
+iLogicalUnit(aLogicalUnit)
+    {
+    LOG_FUNC
+    }
+
+void TDismountLogicalUnit::DoExecuteL()
+    {
+    LOG_FUNC
+    RFs& fs = iServer.FileServerSession();
+    TInt driveNum;
+    fs.CharToDrive(iLogicalUnit.iDrive, driveNum);
+
+    TUsbMsInterface* interface(NULL);
+    interface = iLogicalUnit.Parent();
+    if (!interface)
+        {
+        User::Leave(KErrArgument);
+        }
+    User::LeaveIfError(interface->iUsbMsDevice.DismountLun(driveNum));
+    
+    // Activate the handler.
+    iHandler.Start();
+    // Simulate a async request be completed.
+    iHandler.Complete();
+    }
+
+void TDismountLogicalUnit::HandleError(THostMsErrData& aData, TInt aError)
+    {
+    LOG_FUNC
+    
+    switch (aError)
+        {
+    case KErrNoMemory:
+        aData.iError = EHostMsErrOutOfMemory;
+        break;
+    case KErrArgument:
+        aData.iError = EHostMsErrInvalidParameter;
+        break;
+    default:
+        aData.iError = EHostMsErrGeneral;
+        }
+    aData.iE32Error = aError;
+    TUsbMsDevice* deviceNode = iServer.Engine().SearchDevice(iEvent.iDeviceId);
+    if (deviceNode)
+        {
+        aData.iManufacturerString.Copy(deviceNode->iDevice.iManufacturerString);
+        aData.iProductString.Copy(deviceNode->iDevice.iProductString);
+        }
+    aData.iDriveName = iLogicalUnit.iDrive;
+    }
+
+/**
+ *  TRemoveUsbMsDeviceNode member functions
+ */
+
+TRemoveUsbMsDeviceNode::TRemoveUsbMsDeviceNode(
+        THostMsSubCommandParam& aParameter,
+        TMsmmNodeBase* aNodeToBeRemoved):
+TSubCommandBase(aParameter),
+iNodeToBeRemoved(aNodeToBeRemoved)
+    {
+    LOG_FUNC
+    }
+
+void TRemoveUsbMsDeviceNode::DoExecuteL()
+    {
+    LOG_FUNC
+    if(iNodeToBeRemoved)
+        {
+        iServer.Engine().RemoveUsbMsNode(iNodeToBeRemoved);
+        iNodeToBeRemoved = NULL;
+        }
+    else
+        {
+        User::Leave(KErrArgument);
+        }
+    
+    // Activate the handler.
+    iHandler.Start();
+    // Simulate a async request be completed.
+    iHandler.Complete();
+    }
+
+void TRemoveUsbMsDeviceNode::HandleError(THostMsErrData& aData, TInt aError)
+    {
+    LOG_FUNC  
+    switch (aError)
+        {
+    case KErrArgument:
+        aData.iError = EHostMsErrInvalidParameter;
+        break;
+    default:
+        aData.iError = EHostMsErrGeneral;
+        }
+    aData.iE32Error = aError;
+    TUsbMsDevice* deviceNode = iServer.Engine().SearchDevice(iEvent.iDeviceId);
+    if (deviceNode)
+        {
+        aData.iManufacturerString.Copy(deviceNode->iDevice.iManufacturerString);
+        aData.iProductString.Copy(deviceNode->iDevice.iProductString);
+        }
+    aData.iDriveName = 0;
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/test/msmm_over_dummycomponent/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* 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 "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:
+* This bld.inf builds, for WINSCW and ARMV5, variants of the MSMM executables 
+* which run over the dummy MSC and dummy RFs.
+* The production build must have been done before building from this bld.inf. 
+* The dummy MSC and dummy RFs must also have been built.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+ @test
+*/
+
+#include "../../group/msmm_over_dummycomponent_bld.inf"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/inifile/inc/inifile.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,59 @@
+/*
+* 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:
+* Declares the class CIniFile for accessing ini file.
+*
+*/
+
+/**
+ @file
+*/
+
+#ifndef INIFILE_H__
+#define INIFILE_H__
+
+#include <e32base.h>
+
+class CIniFile : public CBase 
+	{
+public:
+	enum TIniPanic
+		{
+		ESectionNameTooBig,
+		EVarNameTooBig
+		};
+
+public:
+	static CIniFile* NewL(const TDesC& aName);
+	static CIniFile* NewL(const TDesC& aName, const TDesC& aPath);
+	virtual ~CIniFile();
+
+public:
+	TBool FindVar(const TDesC &aSection, const TDesC &aVarName, TPtrC &aResult);
+	TBool FindVar(const TDesC &aSection, const TDesC &aVarName, TInt &aResult);
+
+private:
+	CIniFile();
+	void ConstructL(const TDesC& aName, const TDesC& aPath);
+
+private: // utility
+	void Panic(TIniPanic aPanic);
+
+protected: // owned
+	HBufC* iName; // full name of ini file
+	HBufC* iToken;
+	TPtr iPtr;
+	};
+
+#endif // INIFILE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/inifile/src/inifile.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,237 @@
+/*
+* 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:
+* Defines the class CIniFile for accessing ini file.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <f32file.h>
+#include "inifile.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "IniFile");
+#endif
+
+
+const TUint KTokenSize = 32;
+_LIT(KDefaultIniFileDir,"\\");
+
+void CIniFile::Panic(TIniPanic aPanic)
+	{
+	_LIT(KIniData,"CIniFile");
+	_USB_PANIC(KIniData,aPanic);
+	}
+
+CIniFile::CIniFile() 
+ :	iPtr(NULL,0)
+	{
+	LOG_FUNC
+	}
+
+CIniFile::~CIniFile()
+	{
+	delete (TText*)iPtr.Ptr();
+	delete iToken;
+	delete iName;
+	}
+
+CIniFile* CIniFile::NewL(const TDesC& aName)
+/**
+ * Factory function for CIniFile.
+ *
+ * @param aName The name of the ini file to be used, e.g. "GPRSBTT.INI".
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CIniFile* self = new(ELeave) CIniFile;
+	CleanupStack::PushL(self);
+	self->ConstructL(aName, KDefaultIniFileDir);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CIniFile* CIniFile::NewL(const TDesC& aName, const TDesC& aPath)
+/**
+ * Factory function for CIniFile that allows the user to specify both filename
+ * and path
+ *
+ * @param aName The name of the ini file to be used, e.g. "GPRSBTT.INI".
+ * @param aPath The location of the file e.g. "\\system\\data\\".
+ */
+ {
+	LOG_STATIC_FUNC_ENTRY
+
+ 	CIniFile* self = new(ELeave) CIniFile;
+	CleanupStack::PushL(self);
+	self->ConstructL(aName, aPath);
+	CleanupStack::Pop(self);
+	return self;	 	
+ }
+ 
+void CIniFile::ConstructL(const TDesC& aName, const TDesC& aPath)
+/**
+ * Allocate a buffer and Read file's contents into iPtr
+ *
+ * @param aName is the name of the ini file to be used, e.g. "REFTSY.INI"
+ */
+	{
+    iToken = HBufC::NewL(KTokenSize+2);	// 2 extra chars for []
+
+	RFs fs;
+	LEAVEIFERRORL(fs.Connect());
+	CleanupClosePushL(fs);
+
+	TFindFile ff(fs);
+
+	LEAVEIFERRORL(ff.FindByDir(aName, aPath));
+
+	iName = ff.File().AllocL();
+	
+	RFile file;
+	TInt size;
+	LEAVEIFERRORL(file.Open(fs,*iName,EFileStreamText|EFileRead|EFileShareReadersOnly));
+	CleanupClosePushL(file);
+	
+	LEAVEIFERRORL(file.Size(size));
+
+
+	TText* data = REINTERPRET_CAST(TText*, User::AllocL(size));
+	iPtr.Set(data, size/sizeof(TText), size/sizeof(TText));
+	TPtr8 dest(REINTERPRET_CAST(TUint8*,data), 0, size);
+	LEAVEIFERRORL(file.Read(dest)); 
+
+	TUint8* ptr = REINTERPRET_CAST(TUint8*,data);
+
+	//
+	// This is orderred as FEFF assuming the processor is Little Endian
+	// The data in the file is FFFE.		PRR 28/9/98
+	//
+	if(size>= STATIC_CAST(TInt,sizeof(TText)) && iPtr[0]==0xFEFF)
+   		{
+		Mem::Copy(ptr, ptr+sizeof(TText), size-sizeof(TText));
+		iPtr.Set(data, size/sizeof(TText)-1, size/sizeof(TText)-1);
+		}
+	else if(size)
+		{
+		TText* newdata = REINTERPRET_CAST(TText*,
+			                              User::AllocL(size*sizeof(TText)));
+		iPtr.Set(newdata, size, size);
+		TInt i;
+		for(i=0 ; i<size ; ++i)
+			{
+			iPtr[i] = ptr[i];
+			}
+		delete data;
+		}
+
+	CleanupStack::PopAndDestroy(); // file
+	CleanupStack::PopAndDestroy(); // fs
+	}
+
+TBool CIniFile::FindVar(const TDesC &aSection,
+						const TDesC &aVarName,
+						TPtrC &aResult)
+//
+// Find a variable's value given a section name and a var name
+//
+	{
+	__ASSERT_DEBUG(aSection.Length()<=(TInt)KTokenSize,Panic(ESectionNameTooBig));
+	__ASSERT_DEBUG(aVarName.Length()<=(TInt)KTokenSize,Panic(EVarNameTooBig));
+
+	TPtr sectionToken = iToken->Des();
+	_LIT(KSectionTokenString,"[%S]");
+	sectionToken.Format(KSectionTokenString,&aSection);
+	TInt sectionStart = iPtr.Find(sectionToken);
+	TInt ret = ETrue;
+	if (sectionStart == KErrNotFound)
+		{
+		ret = EFalse;
+		}
+	else
+		{		
+		TPtrC section = iPtr.Mid(sectionStart);
+		TInt endBracket = section.Find(TPtrC(_S("]")));
+		if (endBracket == KErrNotFound)
+			{
+			ret = EFalse;
+			}
+		else
+			{
+			sectionStart += endBracket + 1;
+			section.Set(iPtr.Mid(sectionStart));
+			
+			TInt sectionEnd = section.Find(TPtrC(_S("[")));
+			if (sectionEnd == KErrNotFound)
+				{
+				sectionEnd = iPtr.Length() - sectionStart;
+				}
+			else
+				{
+				sectionEnd--;
+				}
+			section.Set(iPtr.Mid(sectionStart,sectionEnd));
+			TPtr varToken = iToken->Des();
+			_LIT(KVarTokenString,"%S=");
+			varToken.Format(KVarTokenString,&aVarName);
+			TInt pos = section.Find(varToken);
+			if (pos == KErrNotFound)
+				{
+				ret = EFalse;
+				}
+			else
+				{
+				// 'lex' points at the start of the data
+				TPtrC lex(section.Mid(pos));
+				TInt startpos = lex.Locate(TChar('='));
+				startpos++; // startpos points immediately after the =.
+				while ( TChar(lex[startpos]).IsSpace() )
+					{
+					startpos++; // skip to start of data
+					}
+				TInt endpos = lex.Locate(TChar('\n')); // assumes \n is after =.
+				if ( endpos == KErrNotFound ) // may not be \n on last line
+					{
+					endpos = section.Length()-1;
+					}
+				aResult.Set(lex.Mid(startpos).Ptr(),endpos-startpos-1);
+				}
+			}
+		}
+
+	return ret;
+	}
+
+TBool CIniFile::FindVar(const TDesC &aSection,const TDesC &aVarName,
+						TInt &aResult)
+	{
+	TInt ret = EFalse;
+	TPtrC ptr(NULL,0);
+	if (FindVar(aSection,aVarName,ptr))
+		{
+		TLex lex(ptr);
+		if (lex.Val(aResult)==KErrNone)
+			ret = ETrue;
+		}
+
+	return ret;
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/logger/BWINS/usbloggerU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,17 @@
+EXPORTS
+	??0TFunctionLogger@@QAE@ABVTDesC8@@0PAX@Z @ 1 NONAME ; TFunctionLogger::TFunctionLogger(class TDesC8 const &, class TDesC8 const &, void *)
+	??1TFunctionLogger@@QAE@XZ @ 2 NONAME ; TFunctionLogger::~TFunctionLogger(void)
+	?Close@CUsbLog@@SAXXZ @ 3 NONAME ; void CUsbLog::Close(void)
+	?Connect@CUsbLog@@SAHXZ @ 4 NONAME ; int CUsbLog::Connect(void)
+	?HexDump@CUsbLog@@SAXABVTDesC8@@PBG1PBEH@Z @ 5 NONAME ; void CUsbLog::HexDump(class TDesC8 const &, unsigned short const *, unsigned short const *, unsigned char const *, int)
+	?VerboseLeaveIfErrorL@@YAXABVTDesC8@@PADHH@Z @ 6 NONAME ; void VerboseLeaveIfErrorL(class TDesC8 const &, char *, int, int)
+	?VerbosePanic@@YAXABVTDesC8@@PADHHPAEABVTDesC16@@@Z @ 7 NONAME ; void VerbosePanic(class TDesC8 const &, char *, int, int, unsigned char *, class TDesC16 const &)
+	?Write@CUsbLog@@SAXABVTDesC8@@0@Z @ 8 NONAME ; void CUsbLog::Write(class TDesC8 const &, class TDesC8 const &)
+	?Write@CUsbLog@@SAXABVTDesC8@@ABVTDesC16@@@Z @ 9 NONAME ; void CUsbLog::Write(class TDesC8 const &, class TDesC16 const &)
+	?WriteFormat@CUsbLog@@SAXABVTDesC8@@V?$TRefByValue@$$CBVTDesC16@@@@AAY00PAC@Z @ 10 NONAME ; void CUsbLog::WriteFormat(class TDesC8 const &, class TRefByValue<class TDesC16 const >, signed char * [1] &)
+	?WriteFormat@CUsbLog@@SAXABVTDesC8@@V?$TRefByValue@$$CBVTDesC16@@@@ZZ @ 11 NONAME ; void CUsbLog::WriteFormat(class TDesC8 const &, class TRefByValue<class TDesC16 const >, ...)
+	?WriteFormat@CUsbLog@@SAXABVTDesC8@@V?$TRefByValue@$$CBVTDesC8@@@@AAY00PAC@Z @ 12 NONAME ; void CUsbLog::WriteFormat(class TDesC8 const &, class TRefByValue<class TDesC8 const >, signed char * [1] &)
+	?WriteFormat@CUsbLog@@SAXABVTDesC8@@V?$TRefByValue@$$CBVTDesC8@@@@ZZ @ 13 NONAME ; void CUsbLog::WriteFormat(class TDesC8 const &, class TRefByValue<class TDesC8 const >, ...)
+	?VerboseLeaveL@@YAXABVTDesC8@@PADHH@Z @ 14 NONAME ; void VerboseLeaveL(class TDesC8 const &, char *, int, int)
+	?VerboseMsgPanic@@YAXABVTDesC8@@PADHABVRMessage2@@ABVTDesC16@@H@Z @ 15 NONAME ; void VerboseMsgPanic(class TDesC8 const &, char *, int, class RMessage2 const &, class TDesC16 const &, int)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/logger/EABI/usbloggerU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,19 @@
+EXPORTS
+	_Z12VerbosePanicRK6TDesC8PciiPhRK7TDesC16 @ 1 NONAME
+	_Z20VerboseLeaveIfErrorLRK6TDesC8Pcii @ 2 NONAME
+	_ZN15TFunctionLoggerC1ERK6TDesC8S2_Pv @ 3 NONAME
+	_ZN15TFunctionLoggerC2ERK6TDesC8S2_Pv @ 4 NONAME
+	_ZN15TFunctionLoggerD1Ev @ 5 NONAME
+	_ZN15TFunctionLoggerD2Ev @ 6 NONAME
+	_ZN7CUsbLog11WriteFormatERK6TDesC811TRefByValueIK7TDesC16ERSt9__va_list @ 7 NONAME
+	_ZN7CUsbLog11WriteFormatERK6TDesC811TRefByValueIK7TDesC16Ez @ 8 NONAME
+	_ZN7CUsbLog11WriteFormatERK6TDesC811TRefByValueIS1_ERSt9__va_list @ 9 NONAME
+	_ZN7CUsbLog11WriteFormatERK6TDesC811TRefByValueIS1_Ez @ 10 NONAME
+	_ZN7CUsbLog5CloseEv @ 11 NONAME
+	_ZN7CUsbLog5WriteERK6TDesC8RK7TDesC16 @ 12 NONAME
+	_ZN7CUsbLog5WriteERK6TDesC8S2_ @ 13 NONAME
+	_ZN7CUsbLog7ConnectEv @ 14 NONAME
+	_ZN7CUsbLog7HexDumpERK6TDesC8PKtS4_PKhi @ 15 NONAME
+	_Z13VerboseLeaveLRK6TDesC8Pcii @ 16 NONAME
+	_Z15VerboseMsgPanicRK6TDesC8PciRK9RMessage2RK7TDesC16i @ 17 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/logger/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+/*
+* 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 "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
+*/
+
+PRJ_EXPORTS
+../public/usblogger.h				SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/usblogger.h)
+usblogger.mmh					/epoc32/include/usb/usblogger.mmh
+
+PRJ_MMPFILES
+usblogger.MMP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/logger/group/usblogger.MMP	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,44 @@
+/*
+* 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 "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:
+* Logging engine for USB.
+*
+*/
+
+/**
+ @file
+*/
+
+target usblogger.dll
+
+CAPABILITY All -Tcb
+TARGETTYPE	dll
+
+uid			0x1000008d 0x10281A7D
+
+// MACRO __USB_DEBUG_RDEBUG__
+// Define this macro to get output through the serial port (COM0) 
+
+SOURCEPATH 	../src
+SOURCE 		usblogger.cpp
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+library			euser.lib
+
+VENDORID 0x70000001
+
+#include <comms-infras/commsdebugutility.mmh>
+
+UNPAGED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/logger/group/usblogger.mmh	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,67 @@
+/*
+* 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 "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:
+* When checking this file into perforce, ensure that
+* LOGGING IS DISABLED FOR RELEASE BUILDS.
+* This file is not to be used outside Symbian.
+* It is largely a copy of commsdebugutility.mmh.
+* When the new logger comes in that provides the functionality we want 
+* (specifically, 'connected' logging using TLS), we can remove our own logger 
+* dll entirely, including this file. [We'll still possibly need a header with 
+* our nice function entry/exit, leave and panic macros though.]
+*
+*/
+
+// Uncomment next line to temporarily engage logging for release builds.
+//#define __FLOGGER_UREL
+// Comment next line to temporarily disengage logging for debug builds
+#define __FLOGGER_UDEB
+
+// Determine whether, and how, flogger is to be included
+#ifdef __FLOGGER_UREL
+	#ifdef __FLOGGER_UDEB
+	#define __FLOGGER_INCLUDED
+	MACRO __FLOG_UREL
+	#endif
+#endif
+#ifdef __FLOGGER_UREL
+	#ifndef __FLOGGER_UDEB
+	#define __FLOGGER_INCLUDED
+	MACRO __FLOG_UREL
+	MACRO __FLOG_NO_UDEB
+	#endif
+#endif
+#ifndef __FLOGGER_UREL
+	#ifndef __FLOGGER_UDEB
+	MACRO __FLOG_NO_UDEB
+	#endif
+#endif
+#ifndef __FLOGGER_UREL
+	#ifdef __FLOGGER_UDEB
+	#define __FLOGGER_INCLUDED
+	#define __FLOGGER_DEBUGGERLIBRARY
+	#endif
+#endif
+
+
+#ifdef __FLOGGER_INCLUDED
+	#ifndef __FLOGGER_SUPPRESS_LIBRARY
+		#ifdef __FLOGGER_DEBUGGERLIBRARY
+			DEBUGLIBRARY usblogger.lib
+		#else
+			LIBRARY usblogger.lib
+		#endif
+	#endif
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/logger/public/usblogger.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,183 @@
+/*
+* 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 "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
+ @internalTechnology
+*/
+
+
+#ifndef LOGGER_H
+#define LOGGER_H
+
+#include <e32base.h>
+
+// Control function entry and exit logging using a compile-time switch.
+#define __LOG_FUNCTIONS__
+
+class TFunctionLogger;
+
+#ifndef __COMMSDEBUGUTILITY_H__		// comms-infras/commsdebugutility.h not included
+#ifdef _DEBUG						// If this is a debug build...
+// Set flogging active.
+#define __FLOG_ACTIVE
+#endif
+#endif
+
+#ifdef __FLOG_ACTIVE
+#define IF_FLOGGING(a) a
+#else
+#define IF_FLOGGING(a)
+#endif
+
+_LIT8(KDefaultLogFile, "USB");
+
+#ifdef __FLOG_ACTIVE
+#define LEAVEIFERRORL(a)				VerboseLeaveIfErrorL(KLogComponent, __FILE__, __LINE__, a)
+#define LEAVEL(a)						VerboseLeaveL(KLogComponent, __FILE__, __LINE__, a)
+#define _USB_PANIC(CAT, CODE) 			VerbosePanic(KLogComponent, __FILE__, __LINE__, CODE, (TText8*)#CODE, CAT)
+#define PANIC_MSG(msg, cat, code)		VerboseMsgPanic(KLogComponent, __FILE__, __LINE__, msg, cat, code);
+#define FLOG(a)							CUsbLog::Write(KDefaultLogFile, a);
+#define FTRACE(a)						{a;}
+#define LOGTEXT(text)						CUsbLog::Write(KLogComponent, text);
+#define LOGTEXT2(text, a)					CUsbLog::WriteFormat(KLogComponent, text, a);
+#define LOGTEXT3(text, a, b)				CUsbLog::WriteFormat(KLogComponent, text, a, b);
+#define LOGTEXT4(text, a, b, c)				CUsbLog::WriteFormat(KLogComponent, text, a, b, c);
+#define LOGTEXT5(text, a, b, c, d)			CUsbLog::WriteFormat(KLogComponent, text, a, b, c, d);
+#define LOGTEXT6(text, a, b, c, d, e)		CUsbLog::WriteFormat(KLogComponent, text, a, b, c, d, e);
+#define LOGTEXT7(text, a, b, c, d, e, f)	CUsbLog::WriteFormat(KLogComponent, text, a, b, c, d, e, f);
+#define LOGHEXDESC(desc)				CUsbLog::HexDump(KLogComponent, 0, 0, desc.Ptr() , desc.Length());
+#define LOGHEXRAW(data, len)			CUsbLog::HexDump(KLogComponent, 0, 0, data, len);
+#else
+#define LEAVEIFERRORL(a)				static_cast<void>(User::LeaveIfError(a))
+#define LEAVEL(a)						User::Leave(a)
+#define _USB_PANIC(CAT, CODE) 			User::Panic(CAT, CODE)
+#define PANIC_MSG(msg, cat, code)		msg.Panic(cat, code);
+#define FLOG(a)
+#define FTRACE(a)
+#define LOGTEXT(text)
+#define LOGTEXT2(text, a)
+#define LOGTEXT3(text, a, b)
+#define LOGTEXT4(text, a, b, c)
+#define LOGTEXT5(text, a, b, c, d)			
+#define LOGTEXT6(text, a, b, c, d, e)		
+#define LOGTEXT7(text, a, b, c, d, e, f)
+#define LOGHEXDESC(desc)
+#define LOGHEXRAW(data, len)
+#endif // __FLOG_ACTIVE
+
+#define FORCED_LOG_FUNC					TFunctionLogger __instrument(KLogComponent, TPtrC8((TUint8*)__PRETTY_FUNCTION__), (TAny*)this);
+#define FORCED_LOG_STATIC_FUNC_ENTRY	TFunctionLogger __instrument(KLogComponent, TPtrC8((TUint8*)__PRETTY_FUNCTION__), (TAny*)NULL);
+
+#if ( defined __FLOG_ACTIVE && defined __LOG_FUNCTIONS__ )
+#define LOG_LINE						CUsbLog::Write(KLogComponent, KNullDesC8());
+#define LOG_FUNC						FORCED_LOG_FUNC
+#define LOG_STATIC_FUNC_ENTRY			FORCED_LOG_STATIC_FUNC_ENTRY
+#else
+#define LOG_LINE
+#define LOG_FUNC
+#define LOG_STATIC_FUNC_ENTRY
+#endif
+
+
+
+NONSHARABLE_CLASS(CUsbLog) : public CBase
+	{
+public:
+	IMPORT_C static TInt Connect();
+	IMPORT_C static void Close();
+	
+	IMPORT_C static void Write(const TDesC8& aCmpt, const TDesC8& aText);
+	IMPORT_C static void WriteFormat(const TDesC8& aCmpt, TRefByValue<const TDesC8> aFmt, ...);
+	IMPORT_C static void WriteFormat(const TDesC8& aCmpt, TRefByValue<const TDesC8> aFmt, VA_LIST& aList);
+	IMPORT_C static void Write(const TDesC8& aCmpt, const TDesC16& aText);
+	IMPORT_C static void WriteFormat(const TDesC8& aCmpt, TRefByValue<const TDesC16> aFmt, ...);
+	IMPORT_C static void WriteFormat(const TDesC8& aCmpt, TRefByValue<const TDesC16> aFmt, VA_LIST& aList);
+	IMPORT_C static void HexDump(const TDesC8& aCmpt, const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen);
+	};
+
+
+#ifndef NO_FPRINT
+inline void FPrint(const TRefByValue<const TDesC> IF_FLOGGING(aFmt), ...)
+	{
+#ifdef __FLOG_ACTIVE
+	VA_LIST list;
+	VA_START(list,aFmt);
+	CUsbLog::WriteFormat(KDefaultLogFile, aFmt, list);
+#endif
+	}
+#endif
+
+
+#ifndef NO_FHEX_PTR
+inline void FHex(const TUint8* IF_FLOGGING(aPtr), TInt IF_FLOGGING(aLen))
+	{
+#ifdef __FLOG_ACTIVE
+	CUsbLog::HexDump(KDefaultLogFile, 0, 0, aPtr, aLen);
+#endif
+	}
+#endif
+
+
+#ifndef NO_FHEX_DESC
+inline void FHex(const TDesC8& IF_FLOGGING(aDes))
+	{
+#ifdef __FLOG_ACTIVE
+	FHex(aDes.Ptr(), aDes.Length());
+#endif
+	}
+#endif
+
+
+IMPORT_C void VerboseLeaveIfErrorL(const TDesC8& aCpt, 
+						  char* aFile, 
+						  TInt aLine, 
+						  TInt aReason);
+						  
+IMPORT_C void VerboseLeaveL(const TDesC8& aCpt, 
+						  char* aFile, 
+						  TInt aLine, 
+						  TInt aReason);
+						  
+IMPORT_C void VerbosePanic(const TDesC8& aCpt, 
+				  char* aFile, 
+				  TInt aLine, 
+				  TInt aPanicCode, 
+				  TText8* aPanicName,
+				  const TDesC& aPanicCategory);
+
+IMPORT_C void VerboseMsgPanic(const TDesC8& aCpt, 
+								char* aFile, 
+								TInt  aLine,
+								const RMessage2& aMsg,
+								const TDesC& aCat, 
+								TInt  aPanicCode);
+
+
+NONSHARABLE_CLASS(TFunctionLogger)
+	{
+public:
+	IMPORT_C TFunctionLogger(const TDesC8& aCpt, const TDesC8& aString, TAny* aThis);
+	IMPORT_C ~TFunctionLogger();
+	
+private:
+	TPtrC8 iCpt;
+	TPtrC8 iString;
+	};
+
+#endif	// LOGGER_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/logger/src/usblogger.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,600 @@
+/*
+* 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 "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
+ @internalTechnology
+*/
+
+
+#include <e32base.h>
+#include <comms-infras/commsdebugutility.h>
+#include <usb/usblogger.h>
+
+
+#ifdef __USB_DEBUG_RDEBUG__
+#include <e32debug.h>
+const TInt KUSBLogBufferSize=255;
+class TUSBFlogOverflow8  : public TDes8Overflow
+     {
+public:
+     void Overflow(TDes8& /*aDes*/) { }
+     };
+
+class TUSBFlogOverflow16  : public TDes16Overflow
+     {
+public:
+     void Overflow(TDes16& /*aDes*/) { }
+     };
+void __CUsbLog_DoHexDump(const TDesC8& aCmpt, const TDesC8& aData, const TDesC8& aHeader, const TDesC8& aMargin);
+#endif //__USB_DEBUG_RDEBUG__
+
+
+
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KSubsystem, "USB");
+_LIT8(KLogCmpt, "logengine");
+#endif
+
+
+NONSHARABLE_CLASS(TLogData)
+	{
+	public:
+#ifdef __FLOG_ACTIVE
+		TLogData();
+
+		void SetLogTags(const TDesC8& aCmpt);
+
+		TInt iAccessCount;
+
+		RFileLogger iLogEngine;
+		TBuf8<KMaxTagLength> iCurrentComponent;
+#endif
+	};
+
+
+#ifdef __FLOG_ACTIVE
+TLogData::TLogData()
+	: iAccessCount(0), iCurrentComponent(KNullDesC8)
+	{}
+
+void TLogData::SetLogTags(const TDesC8& aCmpt)
+	{
+	if (aCmpt != iCurrentComponent)
+		{
+		iLogEngine.SetLogTags(KSubsystem, aCmpt.Left(KMaxTagLength));
+		iCurrentComponent = aCmpt.Left(KMaxTagLength);
+		}
+	}
+#endif
+
+#define GETLOG TLogData* __logger = static_cast<TLogData*>(Dll::Tls());
+
+
+
+EXPORT_C /*static*/ TInt CUsbLog::Connect()
+	{
+#ifdef __FLOG_ACTIVE
+	GETLOG;
+
+	if (!__logger)
+		{
+
+		CUsbLog::Write(KLogCmpt, _L8("Opening new logger connection"));
+		__logger = new TLogData();
+		if (!__logger)
+			{
+			CUsbLog::Write(KLogCmpt, _L8("Opening logger connection failed, no memory"));
+			return KErrNoMemory;
+			}
+
+		__logger->iLogEngine.Connect();
+		Dll::SetTls(__logger);
+		}
+
+	__logger->iAccessCount++;
+	CUsbLog::WriteFormat(KLogCmpt, _L8("Opening -- %d instances now open"), __logger->iAccessCount);
+
+	return KErrNone;
+#else
+	return KErrNotSupported;
+#endif
+	}
+
+
+EXPORT_C /*static*/ void CUsbLog::Close()
+	{
+#ifdef __FLOG_ACTIVE
+	GETLOG;
+
+	if (__logger)
+		{
+		TInt& count = __logger->iAccessCount;
+
+		if (count)
+			{
+			count--;
+			CUsbLog::WriteFormat(KLogCmpt, _L8("Closing -- %d instance(s) left open"), count);
+			if (!count)
+				{
+				__logger->iLogEngine.Close();
+				delete __logger;
+				Dll::SetTls(NULL);
+				CUsbLog::Write(KLogCmpt, _L8("Fully closed and deleted, now flogging statically."));
+				}
+			}
+		else
+			{
+			CUsbLog::Write(KLogCmpt, _L8("Not closing -- not opened"));
+			}
+		}
+#endif
+	}
+
+
+EXPORT_C /*static*/ void CUsbLog::Write(const TDesC8& IF_FLOGGING(aCmpt), const TDesC8& IF_FLOGGING(aText))
+	{
+#ifdef __FLOG_ACTIVE
+	GETLOG;
+
+#ifdef __USB_DEBUG_RDEBUG__
+		TBuf8<KUSBLogBufferSize> buf;
+		RThread thread;
+		buf.AppendFormat(_L8("%S\t%S\t%LX\t%S\r\n"), &KSubsystem(), &aCmpt, thread.Id().Id(), &aText);
+		RDebug::RawPrint(buf);
+#endif // __USB_DEBUG_RDEBUG
+
+	if (__logger)
+		{
+		__logger->SetLogTags(aCmpt);
+		__logger->iLogEngine.Write(aText);
+		}
+	else
+		{
+		RFileLogger::Write(KSubsystem, aCmpt, aText);
+		}
+#endif
+	}
+
+
+EXPORT_C /*static*/ void CUsbLog::WriteFormat(const TDesC8& IF_FLOGGING(aCmpt), TRefByValue<const TDesC8> IF_FLOGGING(aFmt), ...)
+	{
+#ifdef __FLOG_ACTIVE
+	VA_LIST list;
+	VA_START(list, aFmt);
+
+	GETLOG;
+
+#ifdef __USB_DEBUG_RDEBUG__
+		TUSBFlogOverflow8 objFlogBody8;
+		TBuf8<KUSBLogBufferSize> buf;
+		RThread thread;
+		buf.AppendFormat(_L8("%S\t%S\t%LX\t"), &KSubsystem(), &aCmpt, thread.Id().Id());
+		buf.AppendFormatList(aFmt, list, &objFlogBody8);
+		buf.Append(_L8("\r\n"));
+		RDebug::RawPrint(buf);
+#endif // __USB_DEBUG_RDEBUG
+
+	if (__logger)
+		{
+		__logger->SetLogTags(aCmpt);
+		__logger->iLogEngine.WriteFormat(aFmt, list);
+		}
+	else
+		{
+		RFileLogger::WriteFormat(KSubsystem, aCmpt, aFmt, list);
+		}
+#endif
+	}
+
+
+EXPORT_C /*static*/ void CUsbLog::WriteFormat(const TDesC8& IF_FLOGGING(aCmpt), TRefByValue<const TDesC8> IF_FLOGGING(aFmt), VA_LIST& IF_FLOGGING(aList))
+	{
+#ifdef __FLOG_ACTIVE
+	GETLOG;
+
+#ifdef __USB_DEBUG_RDEBUG__
+		TUSBFlogOverflow8 objFlogBody8;
+		TBuf8<KUSBLogBufferSize> buf;
+		RThread thread;
+		buf.AppendFormat(_L8("%S\t%S\t%LX\t"), &KSubsystem(), &aCmpt, thread.Id().Id());
+		buf.AppendFormatList(aFmt, aList, &objFlogBody8);
+		buf.Append(_L8("\r\n"));
+		RDebug::RawPrint(buf);
+#endif // __USB_DEBUG_RDEBUG
+
+	if (__logger)
+		{
+		__logger->SetLogTags(aCmpt);
+		__logger->iLogEngine.WriteFormat(aFmt, aList);
+		}
+	else
+		{
+		RFileLogger::WriteFormat(KSubsystem, aCmpt, aFmt, aList);
+		}
+#endif
+	}
+
+
+EXPORT_C /*static*/ void CUsbLog::Write(const TDesC8& IF_FLOGGING(aCmpt), const TDesC16& IF_FLOGGING(aText))
+	{
+#ifdef __FLOG_ACTIVE
+	GETLOG;
+
+#ifdef __USB_DEBUG_RDEBUG__
+		TBuf16<KUSBLogBufferSize> buf;
+		buf.AppendFormat(_L16("(TDesC16): %S\r\n"), &aText);
+		RDebug::RawPrint(buf);
+#endif // __USB_DEBUG_RDEBUG
+
+	if (__logger)
+		{
+		__logger->SetLogTags(aCmpt);
+		__logger->iLogEngine.Write(aText);
+		}
+	else
+		{
+		RFileLogger::WriteFormat(KSubsystem, aCmpt, aText);
+		}
+#endif
+	}
+
+
+EXPORT_C /*static*/ void CUsbLog::WriteFormat(const TDesC8& IF_FLOGGING(aCmpt), TRefByValue<const TDesC16> IF_FLOGGING(aFmt), ...)
+	{
+#ifdef __FLOG_ACTIVE
+	VA_LIST list;
+	VA_START(list, aFmt);
+
+	GETLOG;
+
+#ifdef __USB_DEBUG_RDEBUG__
+		TUSBFlogOverflow16 objFlogBody16;
+		TBuf16<KUSBLogBufferSize> wideBuf;
+		wideBuf.Append(_L16("(TDesC16): "));
+		wideBuf.AppendFormatList(aFmt, list, &objFlogBody16);
+		wideBuf.Append(_L16("\r\n"));
+		RDebug::RawPrint(wideBuf);
+#endif // __USB_DEBUG_RDEBUG
+
+	if (__logger)
+		{
+		__logger->SetLogTags(aCmpt);
+		__logger->iLogEngine.WriteFormat(aFmt, list);
+		}
+	else
+		{
+		RFileLogger::WriteFormat(KSubsystem, aCmpt, aFmt, list);
+		}
+#endif
+	}
+
+
+EXPORT_C /*static*/ void CUsbLog::WriteFormat(const TDesC8& IF_FLOGGING(aCmpt), TRefByValue<const TDesC16> IF_FLOGGING(aFmt), VA_LIST& IF_FLOGGING(aList))
+	{
+#ifdef __FLOG_ACTIVE
+	GETLOG;
+
+#ifdef __USB_DEBUG_RDEBUG__
+		TUSBFlogOverflow16 objFlogBody16;
+		TBuf16<KUSBLogBufferSize> wideBuf;
+		wideBuf.Append(_L16("(TDesC16): "));
+		wideBuf.AppendFormatList(aFmt, aList, &objFlogBody16);
+		wideBuf.Append(_L16("\r\n"));
+		RDebug::RawPrint(wideBuf);
+#endif // __USB_DEBUG_RDEBUG
+
+	if (__logger)
+		{
+		__logger->SetLogTags(aCmpt);
+		__logger->iLogEngine.WriteFormat(aFmt, aList);
+		}
+	else
+		{
+		RFileLogger::WriteFormat(KSubsystem, aCmpt, aFmt, aList);
+		}
+#endif
+	}
+
+
+EXPORT_C /*static*/ void CUsbLog::HexDump(const TDesC8& IF_FLOGGING(aCmpt), const TText* IF_FLOGGING(aHeader), const TText* IF_FLOGGING(aMargin), const TUint8* IF_FLOGGING(aPtr), TInt IF_FLOGGING(aLen))
+	{
+#ifdef __FLOG_ACTIVE
+	GETLOG;
+
+#ifdef __USB_DEBUG_RDEBUG__
+	__CUsbLog_DoHexDump(aCmpt, TPtrC8(aPtr, aLen), TPtrC8(NULL,0), TPtrC8(NULL,0));
+#endif // __USB_DEBUG_RDEBUG
+
+	if (__logger)
+		{
+		__logger->SetLogTags(aCmpt);
+		__logger->iLogEngine.HexDump(aHeader, aMargin, aPtr, aLen);
+		}
+	else
+		{
+		RFileLogger::HexDump(KSubsystem, aCmpt, TPtrC8(aPtr, aLen), KNullDesC8);
+		}
+#endif
+	}
+
+
+#ifdef __USB_DEBUG_RDEBUG__
+
+#define BLANK	_S("")
+const TInt KHexDumpWidth=16;			///< Number of bytes written per line when formatting as hex.
+const TInt KLowestPrintableCharacter = 32; ///< In Hex output, replace chars below space with a dot.
+const TInt KHighestPrintableCharacter = 126; ///< In Hex output, replace chars above 7-bits with a dot.
+
+_LIT8(KFirstFormatString8,"%04x : ");   ///< Format string used in Hexdump to format first part: header and byte numbers.
+_LIT8(KSecondFormatString8,"%02x ");      ///< Format string used in Hexdump to format mid part: each of the 16 bytes as hex
+_LIT8(KThirdFormatString8,"%c");          ///< Format string used in Hexdump to format the last part: each of the 16 bytes as characters
+_LIT8(KThreeSpaces8,"   ");               ///< Format string used in Hexdump to define padding between first and mid parts
+_LIT8(KTwoSpaces8," ");                   ///< Format string used in Hexdump to define padding between hex and char bytes.
+const TText8 KFullStopChar8='.';
+
+void __CUsbLog_DoHexDump(const TDesC8& aCmpt, const TDesC8& aData, const TDesC8& aHeader, const TDesC8& aMargin)
+	{
+#ifdef __FLOG_ACTIVE
+	HBufC8* marginStr = NULL;
+	TBuf8<KMaxHexDumpWidth> buf;
+	TInt aRemainingLen = aData.Length();
+	TInt aHeaderLen = aHeader.Length();
+	TUSBFlogOverflow8 objFlogBody8;
+
+	if (aData.Length()==0)		// nothing to do
+		{
+		return;
+		}
+
+
+	if (aHeaderLen > 0)
+		{
+
+		if (aMargin.Length() == 0)
+			{
+			marginStr = HBufC8::New(aHeader.Length());
+			if (marginStr == NULL)
+				{
+				return;		// abort if No memory
+				}
+			TPtr8 marginStrPtr(marginStr->Des());
+			marginStrPtr.AppendFill(' ',aHeader.Length());
+			}
+		else
+			{
+			marginStr = aMargin.Alloc();
+			}
+		}
+
+
+
+	TUint blockStartPos = 0;
+	while (aRemainingLen>0)
+		{
+		RThread thread;
+		buf.AppendFormat(_L8("%S\t%S\t%LX\t"), &KSubsystem(), &aCmpt, thread.Id().Id());
+		TInt blockLength = (aRemainingLen>KHexDumpWidth ? KHexDumpWidth : aRemainingLen);
+
+		// write the header/margin and print in hex which bytes we are about to write
+		if (blockStartPos == 0)
+			{
+			if (aHeaderLen > 0)
+				{
+				buf.Append(aHeader);
+				}
+			buf.AppendFormat(KFirstFormatString8,&objFlogBody8, blockStartPos);
+			}
+		else
+			{
+			if (marginStr)
+				{
+				buf.Append(*marginStr);
+				}
+			buf.AppendFormat(KFirstFormatString8,&objFlogBody8,blockStartPos);
+			}
+
+		TInt bytePos;
+		// write the bytes as hex
+		for (bytePos = 0; bytePos < blockLength; bytePos++)
+			{
+			buf.AppendFormat(KSecondFormatString8,aData[blockStartPos + bytePos]);
+			}
+		while (bytePos++ < KHexDumpWidth)
+			{
+			buf.Append(KThreeSpaces8);
+			}
+		buf.Append(KTwoSpaces8);
+		// print the bytes as characters, or full stops if outside printable range
+		for (bytePos = 0; bytePos < blockLength; bytePos++)
+			{
+			buf.AppendFormat(KThirdFormatString8,(aData[blockStartPos + bytePos] < KLowestPrintableCharacter || aData[blockStartPos + bytePos] > KHighestPrintableCharacter) ? KFullStopChar8 : aData[blockStartPos + bytePos]);
+			}
+
+		buf.Append(_L8("\r\n"));
+		RDebug::RawPrint(buf);
+
+		buf.SetLength(0);
+		aRemainingLen -= blockLength;
+		blockStartPos += blockLength;
+		}
+	delete marginStr;
+#endif // __FLOG_ACTIVE
+	}
+
+
+
+#endif // __USB_DEBUG_RDEBUG
+
+
+/**
+Leave (if error) verbosely- log name of file and line number just before
+leaving.
+@param aFile The file we're leaving from.
+@param aLine The line number we're leaving from.
+@param aReason The leave code.
+*/
+EXPORT_C void VerboseLeaveIfErrorL(const TDesC8& IF_FLOGGING(aCpt),
+						  char* IF_FLOGGING(aFile),
+						  TInt IF_FLOGGING(aLine),
+						  TInt aReason)
+	{
+	// only leave negative value
+	if ( aReason >= 0 )
+		{
+		return;
+		}
+
+#ifdef __FLOG_ACTIVE
+	_LIT8(KLeavePrefix, "LEAVE: ");
+
+	TPtrC8 fullFileName((const TUint8*)aFile);
+	TPtrC8 fileName(fullFileName.Ptr()+fullFileName.LocateReverse('\\')+1);
+
+	TBuf8<256> buf;
+	buf.Append(KLeavePrefix);
+	buf.AppendFormat(_L8("aReason = %d [file %S, line %d]"), aReason, &fileName,
+		aLine);
+	CUsbLog::Write(aCpt, buf);
+#endif
+
+	// finally
+	User::Leave(aReason);
+	}
+
+/**
+Leave verbosely- log name of file and line number just before
+leaving.
+@param aFile The file we're leaving from.
+@param aLine The line number we're leaving from.
+@param aReason The leave code.
+*/
+EXPORT_C void VerboseLeaveL(const TDesC8& IF_FLOGGING(aCpt),
+						  char* IF_FLOGGING(aFile),
+						  TInt IF_FLOGGING(aLine),
+						  TInt aReason)
+	{
+#ifdef __FLOG_ACTIVE
+	_LIT8(KLeavePrefix, "LEAVE: ");
+
+	TPtrC8 fullFileName((const TUint8*)aFile);
+	TPtrC8 fileName(fullFileName.Ptr()+fullFileName.LocateReverse('\\')+1);
+
+	TBuf8<256> buf;
+	buf.Append(KLeavePrefix);
+	buf.AppendFormat(_L8("aReason = %d [file %S, line %d]"), aReason, &fileName,
+		aLine);
+	CUsbLog::Write(aCpt, buf);
+#endif
+
+	// finally
+	User::Leave(aReason);
+	}
+
+/**
+Panic verbosely- log name of file and line number just before panicking.
+@param aFile The file that's panicking.
+@param aLine The line number that's panicking.
+@param aReason The panic code.
+@param aPanicName The text of the panic code.
+@param aPanicCategory The panic category.
+*/
+EXPORT_C void VerbosePanic(const TDesC8& IF_FLOGGING(aCpt),
+				  char* IF_FLOGGING(aFile),
+				  TInt IF_FLOGGING(aLine),
+				  TInt aPanicCode,
+				  TText8* IF_FLOGGING(aPanicName),
+				  const TDesC& aPanicCategory)
+	{
+#ifdef __FLOG_ACTIVE
+	_LIT8(KPanicPrefix, "PANIC: code ");
+
+	TPtrC8 fullFileName((const TUint8*)aFile);
+	TPtrC8 fileName(fullFileName.Ptr()+fullFileName.LocateReverse('\\')+1);
+
+	TBuf8<256> buf;
+	buf.Append(KPanicPrefix);
+	buf.AppendFormat(_L8("%d = %s [file %S, line %d]"),
+		aPanicCode,
+		aPanicName,
+		&fileName,
+		aLine);
+	CUsbLog::Write(aCpt, buf);
+#endif
+
+	// finally
+	User::Panic(aPanicCategory, aPanicCode);
+	}
+
+
+/**
+Panic the given message verbosely- log name of file and line number just
+before panicking.
+@param aMsg Message to panic.
+@param aFile The file that's panicking.
+@param aLine The line number that's panicking.
+@param aReason The panic code.
+@param aPanicName The text of the panic code.
+@param aPanicCategory The panic category.
+*/
+EXPORT_C void VerboseMsgPanic(const TDesC8& IF_FLOGGING(aCpt),
+								char* IF_FLOGGING(aFile),
+								TInt  IF_FLOGGING(aLine),
+								const RMessage2& aMsg,
+								const TDesC& aCat,
+								TInt  aPanicCode)
+	{
+#ifdef __FLOG_ACTIVE
+	_LIT8(KPanicPrefix, "PANICKING CLIENT: code ");
+
+	TPtrC8 fullFileName((const TUint8*)aFile);
+	TPtrC8 fileName(fullFileName.Ptr()+fullFileName.LocateReverse('\\')+1);
+
+	TBuf8<256> buf;
+	buf.Append(KPanicPrefix);
+	buf.AppendFormat(_L8("%d [file %S, line %d]"),
+		aPanicCode,
+		&fileName,
+		aLine);
+	CUsbLog::Write(aCpt, buf);
+#endif
+	// finally
+	aMsg.Panic(aCat, aPanicCode);
+	}
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KInstrumentIn, ">>%S this = [0x%08x]");
+_LIT8(KInstrumentOut, "<<%S");
+#endif
+
+EXPORT_C TFunctionLogger::TFunctionLogger(const TDesC8& IF_FLOGGING(aCpt), const TDesC8& IF_FLOGGING(aString), TAny* IF_FLOGGING(aThis))
+	{
+#ifdef __FLOG_ACTIVE
+	iCpt.Set(aCpt);
+	iString.Set(aString);
+	CUsbLog::WriteFormat(iCpt, KInstrumentIn, &iString, aThis);
+#endif
+	}
+
+EXPORT_C TFunctionLogger::~TFunctionLogger()
+	{
+#ifdef __FLOG_ACTIVE
+	CUsbLog::WriteFormat(iCpt, KInstrumentOut, &iString);
+#endif
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+/*
+* 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 "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:
+*
+*/
+
+PRJ_TESTEXPORTS
+
+// TEF ini file.
+..\testdata\UsbRomConfig.ini	\epoc32\winscw\c\testdata\usbromconfig\UsbRomConfig.ini
+
+// TEF scripts files.
+..\scripts\USB_ROMCONFIG_001.script		\epoc32\winscw\c\scripts\usbromconfig\USB_ROMCONFIG_001.script
+..\scripts\USB_ROMCONFIG_002.script		\epoc32\winscw\c\scripts\usbromconfig\USB_ROMCONFIG_002.script
+..\scripts\USB_ROMCONFIG_003.script		\epoc32\winscw\c\scripts\usbromconfig\USB_ROMCONFIG_003.script
+..\scripts\USB_ROMCONFIG_004.script		\epoc32\winscw\c\scripts\usbromconfig\USB_ROMCONFIG_004.script
+..\scripts\USB_INC_ROMCONFIG_001.script		\epoc32\winscw\c\scripts\usbromconfig\USB_INC_ROMCONFIG_001.script
+..\scripts\USB_INC_ROMCONFIG_002.script		\epoc32\winscw\c\scripts\usbromconfig\USB_INC_ROMCONFIG_002.script
+..\scripts\USB_INC_ROMCONFIG_003.script		\epoc32\winscw\c\scripts\usbromconfig\USB_INC_ROMCONFIG_003.script
+..\scripts\USB_INC_ROMCONFIG_004.script		\epoc32\winscw\c\scripts\usbromconfig\USB_INC_ROMCONFIG_004.script
+
+// Rom iby files.
+
+PRJ_TESTMMPFILES
+testserversymbianexcludeusb.mmp
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/group/testserversymbianexcludeusb.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,43 @@
+/*
+* 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 "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:
+* ObexTITest.mmp
+*
+*/
+
+TARGET		testserversymbianexcludeusb.exe
+TARGETTYPE	exe
+UID		0x1000008d 0x0F1F777D
+
+VENDORID	0x70000001
+CAPABILITY	All -TCB
+
+SOURCEPATH	../src
+SOURCE		testserversymbianexcludeusb.cpp
+SOURCE		cteststepusbromconfigbase.cpp
+SOURCE		cteststepusbromconfig001.cpp
+SOURCE		cteststepusbromconfig002.cpp
+SOURCE		cteststepusbromconfig003.cpp
+SOURCE		cteststepusbromconfig004.cpp
+
+USERINCLUDE	../inc
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY		euser.lib
+LIBRARY		c32.lib
+LIBRARY		testexecuteutils.lib 
+LIBRARY		testexecutelogclient.lib
+LIBRARY		esock.lib
+LIBRARY		usbman.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/inc/cteststepusbromconfig001.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef CTESTSTEPUSBROMCONFIG001_H
+#define CTESTSTEPUSBROMCONFIG001_H
+
+#include "cteststepusbromconfigbase.h"
+
+class CTestStepUsbRomConfig001 : public CTestStepUsbRomConfigBase
+	{
+public:
+	static CTestStepUsbRomConfig001* New(CTestServer& aParent);
+	~CTestStepUsbRomConfig001();
+	TVerdict doTestStepL();
+	
+private:
+	CTestStepUsbRomConfig001(CTestServer& aParent);
+	};
+
+_LIT(KTestName001, "USB_ROMCONFIG_001"); 
+#endif //  CTESTSTEPUSBROMCONFIG001_H
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/inc/cteststepusbromconfig002.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef CTESTSTEPUSBROMCONFIG002_H
+#define CTESTSTEPUSBROMCONFIG002_H
+
+#include "cteststepusbromconfigbase.h"
+
+class CTestStepUsbRomConfig002 : public CTestStepUsbRomConfigBase
+	{
+public:
+	static CTestStepUsbRomConfig002* New(CTestServer& aParent);
+	~CTestStepUsbRomConfig002();
+	TVerdict doTestStepL();
+	
+private:
+	CTestStepUsbRomConfig002(CTestServer& aParent);
+	};
+
+_LIT(KTestName002, "USB_ROMCONFIG_002"); 
+#endif //  CTESTSTEPUSBROMCONFIG002_H
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/inc/cteststepusbromconfig003.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef CTESTSTEPUSBROMCONFIG003_H
+#define CTESTSTEPUSBROMCONFIG003_H
+
+#include "cteststepusbromconfigbase.h"
+
+class CTestStepUsbRomConfig003 : public CTestStepUsbRomConfigBase
+	{
+public:
+	static CTestStepUsbRomConfig003* New(CTestServer& aParent);
+	~CTestStepUsbRomConfig003();
+	TVerdict doTestStepL();
+	
+private:
+	CTestStepUsbRomConfig003(CTestServer& aParent);
+	};
+
+_LIT(KTestName003, "USB_ROMCONFIG_003"); 
+#endif //  CTESTSTEPUSBROMCONFIG003_H
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/inc/cteststepusbromconfig004.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef CTESTSTEPUSBROMCONFIG004_H
+#define CTESTSTEPUSBROMCONFIG004_H
+
+#include "cteststepusbromconfigbase.h"
+
+class CTestStepUsbRomConfig004 : public CTestStepUsbRomConfigBase
+	{
+public:
+	static CTestStepUsbRomConfig004* New(CTestServer& aParent);
+	~CTestStepUsbRomConfig004();
+	TVerdict doTestStepL();
+	
+private:
+	CTestStepUsbRomConfig004(CTestServer& aParent);
+	};
+
+_LIT(KTestName004, "USB_ROMCONFIG_004"); 
+#endif //  CTESTSTEPUSBROMCONFIG004_H
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/inc/cteststepusbromconfigbase.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,48 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef CTESTSTEPUSBROMCONFIGBASE_H
+#define CTESTSTEPUSBROMCONFIGBASE_H
+
+#include <test/testexecutestepbase.h>
+#include <test/testexecuteserverbase.h>
+
+// constants used for logging
+_LIT(KErrNotFoundLit, "KErrNotFound");
+_LIT(KErrNoneLit, "KErrNone");
+_LIT(KErrBadNameLit, "KErrBadName");
+_LIT(KErrNotSupportedLit, "KErrNotSupported");
+
+class CTestStepUsbRomConfigBase : public CTestStep
+	{
+public:
+	~CTestStepUsbRomConfigBase();
+	TVerdict doTestStepL()=0;
+	TVerdict doTestStepPreambleL();
+
+protected:
+	CTestStepUsbRomConfigBase(CTestServer& aParent);
+	void CheckAndSetTestResult();
+	// ideally this should be const, but we need to get the value out of an ini file 
+	// and there's no easy way to do this inside the initialization list
+	TBool iUsbExcluded;	
+	const CTestServer& iParent;		
+	};
+
+#endif //  CTESTSTEPUSBROMCONFIGBASE_H
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/inc/testserversymbianexcludeusb.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,35 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef TESTSERVERSYMBIANEXCLUDEUSB_H
+#define TESTSERVERSYMBIANEXCLUDEUSB_H
+
+#include <test/testexecuteserverbase.h>
+
+/**
+Test Server for the USB tests for PREQ 581: Enable features to be ommitted from a ROM
+
+Nothing more than a wrapper to load the TestExecute steps 
+*/
+class CTestServerSymbianExcludeUsb : public CTestServer
+	{
+public:
+	static CTestServerSymbianExcludeUsb* NewL();
+	virtual CTestStep* CreateTestStep(const TDesC& aStepName);
+	};
+#endif      // TESTSERVERSYMBIANEXCLUDEUSB_H
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_CIT_P581_UsbExcluded.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+// Run all the USB_ROMCONFIG_* tests
+// Expects a ROM to be built without USB i.e. SYMBIAN_EXCLUDE_USB has been specified
+
+RUN_SCRIPT c:\scripts\usbromconfig\USB_ROMCONFIG_001.script
+
+RUN_SCRIPT c:\scripts\usbromconfig\USB_ROMCONFIG_002.script
+
+RUN_SCRIPT c:\scripts\usbromconfig\USB_ROMCONFIG_003.script
+
+RUN_SCRIPT c:\scripts\usbromconfig\USB_ROMCONFIG_004.script
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_CIT_P581_UsbIncluded.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+// Run all the USB_INC_ROMCONFIG_* tests
+// Expects a standard ROM to be built i.e. SYMBIAN_EXCLUDE_USB has NOT been specified
+
+RUN_SCRIPT c:\scripts\usbromconfig\USB_INC_ROMCONFIG_001.script
+
+RUN_SCRIPT c:\scripts\usbromconfig\USB_INC_ROMCONFIG_002.script
+
+RUN_SCRIPT c:\scripts\usbromconfig\USB_INC_ROMCONFIG_003.script
+
+RUN_SCRIPT c:\scripts\usbromconfig\USB_INC_ROMCONFIG_004.script
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_INC_ROMCONFIG_001.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+LOAD_SERVER TestServerSymbianExcludeUsb
+
+START_TESTCASE USB-INC-ROMCONFIG-001
+//! @SYMTestCaseID USB-INC-ROMCONFIG-001
+//! @SYMTestCaseDesc RUsb::Connect should succeed on a standard Techview ROM
+//! @SYMREQ 5414
+//! @SYMTestType CIT
+//! @SYMTestPriority 3
+//! @SYMTestStatus Implemented
+//! @SYMTestActions Call RUsb::Connect
+//! @SYMTestExpectedResults Returns KErrNone
+RUN_TEST_STEP 10 TestServerSymbianExcludeUsb USB_ROMCONFIG_001 c:\testdata\usbromconfig\UsbRomConfig.ini UsbIncluded
+END_TESTCASE USB-INC-ROMCONFIG-001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_INC_ROMCONFIG_002.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+LOAD_SERVER TestServerSymbianExcludeUsb
+
+START_TESTCASE USB-INC-ROMCONFIG-002
+//! @SYMTestCaseID USB-INC-ROMCONFIG-002
+//! @SYMTestCaseDesc User::LoadLogicalDevice("EUSBC") should succeed on a standard Techview ROM
+//! @SYMREQ 5414
+//! @SYMTestType CIT
+//! @SYMTestPriority 3
+//! @SYMTestStatus Implemented
+//! @SYMTestActions Call User::LoadLogicalDevice("EUSBC")
+//! @SYMTestExpectedResults Returns KErrNone (or KErrAlreadyExists)
+RUN_TEST_STEP 10 TestServerSymbianExcludeUsb USB_ROMCONFIG_002 c:\testdata\usbromconfig\UsbRomConfig.ini UsbIncluded
+END_TESTCASE USB-INC-ROMCONFIG-002
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_INC_ROMCONFIG_003.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+LOAD_SERVER TestServerSymbianExcludeUsb
+
+START_TESTCASE USB-INC-ROMCONFIG-003
+//! @SYMTestCaseID USB-INC-ROMCONFIG-003
+//! @SYMTestCaseDesc RCommServ::LoadCommModule should succeed for ACM csy on a standard Techview ROM
+//! @SYMREQ 5414
+//! @SYMTestType CIT
+//! @SYMTestPriority 3
+//! @SYMTestStatus Implemented
+//! @SYMTestActions Call RCommServ::LoadCommModule("ECACM")
+//! @SYMTestExpectedResults Returns KErrNone
+RUN_TEST_STEP 10 TestServerSymbianExcludeUsb USB_ROMCONFIG_003 c:\testdata\usbromconfig\UsbRomConfig.ini UsbIncluded
+END_TESTCASE USB-INC-ROMCONFIG-003
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_INC_ROMCONFIG_004.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+LOAD_SERVER TestServerSymbianExcludeUsb
+
+START_TESTCASE USB-INC-ROMCONFIG-004
+//! @SYMTestCaseID USB-INC-ROMCONFIG-004
+//! @SYMTestCaseDesc RDevUsbcClient::Open should succeed on a standard Techview ROM
+//! @SYMREQ 5414
+//! @SYMTestType CIT
+//! @SYMTestPriority 3
+//! @SYMTestStatus Implemented
+//! @SYMTestActions Call RDevUsbcClient::Open(0)
+//! @SYMTestExpectedResults Returns KErrNone
+RUN_TEST_STEP 10 TestServerSymbianExcludeUsb USB_ROMCONFIG_004 c:\testdata\usbromconfig\UsbRomConfig.ini UsbIncluded
+END_TESTCASE USB-INC-ROMCONFIG-004
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_ROMCONFIG_001.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+LOAD_SERVER TestServerSymbianExcludeUsb
+
+START_TESTCASE USB-ROMCONFIG-001
+//! @SYMTestCaseID USB-ROMCONFIG-001
+//! @SYMTestCaseDesc RUsb::Connect should fail on a SYMBIAN_EXCLUDE_USB ROM
+//! @SYMREQ 5414
+//! @SYMTestType CIT
+//! @SYMTestPriority 1
+//! @SYMTestStatus Implemented
+//! @SYMTestActions Call RUsb::Connect
+//! @SYMTestExpectedResults Returns KErrNotFound, as USB support has been removed from ROM
+RUN_TEST_STEP 10 TestServerSymbianExcludeUsb USB_ROMCONFIG_001 c:\testdata\usbromconfig\UsbRomConfig.ini UsbExcluded
+END_TESTCASE USB-ROMCONFIG-001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_ROMCONFIG_002.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+LOAD_SERVER TestServerSymbianExcludeUsb
+
+START_TESTCASE USB-ROMCONFIG-002
+//! @SYMTestCaseID USB-ROMCONFIG-002
+//! @SYMTestCaseDesc User::LoadLogicalDevice("EUSBC") should fail on a SYMBIAN_EXCLUDE_USB ROM
+//! @SYMREQ 5414
+//! @SYMTestType CIT
+//! @SYMTestPriority 1
+//! @SYMTestStatus Implemented
+//! @SYMTestActions Call User::LoadLogicalDevice("EUSBC")
+//! @SYMTestExpectedResults Returns KErrNotFound, as usb.ldd has been removed from ROM
+RUN_TEST_STEP 10 TestServerSymbianExcludeUsb USB_ROMCONFIG_002 c:\testdata\usbromconfig\UsbRomConfig.ini UsbExcluded
+END_TESTCASE USB-ROMCONFIG-002
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_ROMCONFIG_003.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+LOAD_SERVER TestServerSymbianExcludeUsb
+
+START_TESTCASE USB-ROMCONFIG-003
+//! @SYMTestCaseID USB-ROMCONFIG-003
+//! @SYMTestCaseDesc RCommServ::LoadCommModule should fail for ACM csy on a SYMBIAN_EXCLUDE_USB ROM
+//! @SYMREQ 5414
+//! @SYMTestType CIT
+//! @SYMTestPriority 1
+//! @SYMTestStatus Implemented
+//! @SYMTestActions Call RCommServ::LoadCommModule("ECACM")
+//! @SYMTestExpectedResults Returns KErrNotFound, as ecacm.csy has been removed from ROM
+RUN_TEST_STEP 10 TestServerSymbianExcludeUsb USB_ROMCONFIG_003 c:\testdata\usbromconfig\UsbRomConfig.ini UsbExcluded
+END_TESTCASE USB-ROMCONFIG-003
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/scripts/USB_ROMCONFIG_004.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+LOAD_SERVER TestServerSymbianExcludeUsb
+
+START_TESTCASE USB-ROMCONFIG-004
+//! @SYMTestCaseID USB-ROMCONFIG-004
+//! @SYMTestCaseDesc RDevUsbcClient::Open should fail on a SYMBIAN_EXCLUDE_USB ROM
+//! @SYMREQ 5414
+//! @SYMTestType CIT
+//! @SYMTestPriority 1
+//! @SYMTestStatus Implemented
+//! @SYMTestActions Call RDevUsbcClient::Open(0)
+//! @SYMTestExpectedResults Returns KErrNotFound, as USB not on ROM
+RUN_TEST_STEP 10 TestServerSymbianExcludeUsb USB_ROMCONFIG_004 c:\testdata\usbromconfig\UsbRomConfig.ini UsbExcluded
+END_TESTCASE USB-ROMCONFIG-004
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/src/cteststepusbromconfig001.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,70 @@
+/*
+* 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 "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 "cteststepusbromconfig001.h"
+#include <usbman.h>
+
+CTestStepUsbRomConfig001::~CTestStepUsbRomConfig001()
+	{
+    }
+	
+CTestStepUsbRomConfig001::CTestStepUsbRomConfig001(CTestServer& aParent) 
+	: CTestStepUsbRomConfigBase(aParent)
+	{
+	SetTestStepName(KTestName001);
+	}
+
+/**
+Static Constructor
+Note the lack of ELeave. This means that having insufficient memory will return NULL;
+*/
+CTestStepUsbRomConfig001* CTestStepUsbRomConfig001::New(CTestServer& aParent)
+	{
+	return new CTestStepUsbRomConfig001(aParent); 
+	}
+
+/**
+See USB_ROMCONFIG_001.script
+*/
+TVerdict CTestStepUsbRomConfig001::doTestStepL()
+	{
+	INFO_PRINTF1(\
+		_L("&gt;&gt;CTestStepUsbRomConfig001::doTestStepL()"));
+	
+	const TInt expectedError = ( iUsbExcluded ? KErrNotFound : KErrNone );
+	const TDesC* expectedErrorDesPtr = ( iUsbExcluded ? &KErrNotFoundLit : &KErrNoneLit );
+	RUsb usb;	
+	TInt err = usb.Connect();
+	if ( err!=expectedError )
+		{
+		INFO_PRINTF4(\
+			_L("Failed: Expected %S(%d) and got %d when calling RUsb::Connect()"),\
+			expectedErrorDesPtr, expectedError, err);
+		SetTestStepResult(EFail);
+		}
+	if ( usb.Handle() )	
+		{
+		usb.Close();
+		}
+	
+	INFO_PRINTF1(\
+		_L("&lt;&lt;CTestStepUsbRomConfig001::doTestStepL()"));
+	CheckAndSetTestResult();
+	return TestStepResult(); 
+	}
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/src/cteststepusbromconfig002.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,74 @@
+/*
+* 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 "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 "cteststepusbromconfig002.h"
+
+#ifndef __WINS__
+_LIT(KUsbLddName, "EUSBC");
+#else
+_LIT(KUsbLddName, "TESTUSBC");
+#endif
+
+CTestStepUsbRomConfig002::~CTestStepUsbRomConfig002()
+	{
+    }
+	
+CTestStepUsbRomConfig002::CTestStepUsbRomConfig002
+	(CTestServer& aParent) 
+	: CTestStepUsbRomConfigBase(aParent)
+	{
+	SetTestStepName(KTestName002);
+	}
+
+/**
+Static Constructor
+Note the lack of ELeave. This means that having insufficient memory will return NULL;
+*/
+CTestStepUsbRomConfig002* CTestStepUsbRomConfig002::New
+	(CTestServer& aParent)
+	{
+	return new CTestStepUsbRomConfig002(aParent); 
+	}
+
+/**
+See USB_ROMCONFIG_002.script
+*/
+TVerdict CTestStepUsbRomConfig002::doTestStepL()
+	{
+	INFO_PRINTF1(\
+		_L("&gt;&gt;CTestStepUsbRomConfig002::doTestStepL()"));
+	
+	const TInt expectedError = ( iUsbExcluded ? KErrNotFound : KErrNone );
+	const TDesC* expectedErrorDesPtr = ( iUsbExcluded ? &KErrNotFoundLit : &KErrNoneLit );
+	
+	TInt err = User::LoadLogicalDevice(KUsbLddName);
+	if ( (expectedError==KErrNone && err!=KErrNone && err!=KErrAlreadyExists) || 
+		(expectedError!=KErrNone && err!=expectedError) )
+		{
+		INFO_PRINTF5(\
+			_L("Failed: Expected %S(%d) and got %d when calling LoadLogicalDevice(%S)"),\
+			expectedErrorDesPtr, expectedError, err, &KUsbLddName);
+		SetTestStepResult(EFail);
+		}
+	
+	INFO_PRINTF1(\
+		_L("&lt;&lt;CTestStepUsbRomConfig002::doTestStepL()"));
+	CheckAndSetTestResult();
+	return TestStepResult(); 
+	}
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/src/cteststepusbromconfig003.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,72 @@
+/*
+* 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 "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 "cteststepusbromconfig003.h"
+#include <c32comm.h>
+#include <AcmInterface.h>
+
+CTestStepUsbRomConfig003::~CTestStepUsbRomConfig003()
+	{
+    }
+	
+CTestStepUsbRomConfig003::CTestStepUsbRomConfig003
+	(CTestServer& aParent) 
+	: CTestStepUsbRomConfigBase(aParent)
+	{
+	SetTestStepName(KTestName003);
+	}
+
+/**
+Static Constructor
+Note the lack of ELeave. This means that having insufficient memory will return NULL;
+*/
+CTestStepUsbRomConfig003* CTestStepUsbRomConfig003::New
+	(CTestServer& aParent)
+	{
+	return new CTestStepUsbRomConfig003(aParent); 
+	}
+	
+/**
+See USB_ROMCONFIG_003.script
+*/
+TVerdict CTestStepUsbRomConfig003::doTestStepL()
+	{
+	INFO_PRINTF1(\
+		_L("&gt;&gt;CTestStepUsbRomConfig003::doTestStepL()"));
+	
+	const TInt expectedError = ( iUsbExcluded ? KErrNotFound : KErrNone );
+	const TDesC* expectedErrorDesPtr = ( iUsbExcluded ? &KErrNotFoundLit : &KErrNoneLit );
+	
+	RCommServ commServ;
+	commServ.Connect();
+	TInt err = commServ.LoadCommModule(KAcmCsyName);
+	if ( err!=expectedError )
+		{
+		INFO_PRINTF5(\
+			_L("Failed: Expected %S(%d) and got %d when calling LoadCommModule(%S)"),\
+			expectedErrorDesPtr, expectedError, err, &KAcmCsyName);
+		SetTestStepResult(EFail);
+		}
+	commServ.Close();
+		
+	INFO_PRINTF1(\
+		_L("&lt;&lt;CTestStepUsbRomConfig003::doTestStepL()"));
+	CheckAndSetTestResult();
+	return TestStepResult(); 
+	}
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/src/cteststepusbromconfig004.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,73 @@
+/*
+* 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 "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 "cteststepusbromconfig004.h"
+#include <d32usbc.h>
+
+CTestStepUsbRomConfig004::~CTestStepUsbRomConfig004()
+	{
+    }
+	
+CTestStepUsbRomConfig004::CTestStepUsbRomConfig004
+	(CTestServer& aParent) 
+	: CTestStepUsbRomConfigBase(aParent)
+	{
+	SetTestStepName(KTestName004);
+	}
+
+/**
+Static Constructor
+Note the lack of ELeave. This means that having insufficient memory will return NULL;
+*/
+CTestStepUsbRomConfig004* CTestStepUsbRomConfig004::New
+	(CTestServer& aParent)
+	{
+	return new CTestStepUsbRomConfig004(aParent); 
+	}
+	
+/**
+See USB_ROMCONFIG_004.script
+*/
+TVerdict CTestStepUsbRomConfig004::doTestStepL()
+	{
+	INFO_PRINTF1(\
+		_L("&gt;&gt;CTestStepUsbRomConfig004::doTestStepL()"));
+	
+	const TInt expectedError = ( iUsbExcluded ? KErrNotFound : KErrNone );
+	const TDesC* expectedErrorDesPtr = ( iUsbExcluded ? &KErrNotFoundLit : &KErrNoneLit );
+	
+	RDevUsbcClient usbClient;
+	TInt err = usbClient.Open(0);
+	if ( err!=expectedError )
+		{
+		INFO_PRINTF4(\
+			_L("Failed: Expected %S(%d) and got %d when calling RDevUsbcClient::Open(0)"),\
+			expectedErrorDesPtr, expectedError, err);
+		SetTestStepResult(EFail);
+		}
+	if ( usbClient.Handle() )
+		{
+		usbClient.Close();
+		}
+		
+	INFO_PRINTF1(\
+		_L("&lt;&lt;CTestStepUsbRomConfig004::doTestStepL()"));
+	CheckAndSetTestResult();
+	return TestStepResult(); 
+	}
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/src/cteststepusbromconfigbase.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,66 @@
+/*
+* 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 "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 "cteststepusbromconfigbase.h"
+
+_LIT(KUsbExcludedKeyName, "UsbExcluded");
+
+CTestStepUsbRomConfigBase::~CTestStepUsbRomConfigBase()
+	{
+    }
+	
+/**
+Constructor sets the default test result to inconclusive
+Up to the test to either explicitly fail the test or to 
+explicitly pass
+*/
+CTestStepUsbRomConfigBase::CTestStepUsbRomConfigBase(CTestServer& aParent) 
+	: iParent(aParent)
+	{
+	SetTestStepResult(EInconclusive);
+	}
+
+/**
+The ROMConfig tests run in two configurations:
+ROM with component included
+ROM with component excluded
+By specifying the appropriate ini section, the test behaviour can be altered
+*/
+TVerdict CTestStepUsbRomConfigBase::doTestStepPreambleL()
+	{
+	if ( GetBoolFromConfig(ConfigSection(),KUsbExcludedKeyName, iUsbExcluded) )
+		{
+		return EPass;
+		}
+	return EFail;	
+	}
+	
+/**
+Should be called at the end of every test
+Checks if the default (EInconclusive) result is still set
+i.e. test has NOT set the result to EFail
+If still EInconclusive, then sets the result to EPass.
+*/	
+void CTestStepUsbRomConfigBase::CheckAndSetTestResult()	
+	{
+	if ( TestStepResult()==EInconclusive )
+		{
+		SetTestStepResult(EPass);
+		}
+	}
+	
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/src/testserversymbianexcludeusb.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,148 @@
+/*
+* 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 "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 "testserversymbianexcludeusb.h"
+#include <e32std.h>
+#include <rsshared.h>
+
+// Put all of the test step header files here...
+#include "cteststepusbromconfig001.h"
+#include "cteststepusbromconfig002.h"
+#include "cteststepusbromconfig003.h"
+#include "cteststepusbromconfig004.h"
+
+_LIT(KServerName,"TestServerSymbianExcludeUsb");
+
+TInt LoadDrivers()
+	{
+#ifdef __WINS__
+	#define KPDDName _L("ECDRV")
+	#define KLDDName _L("ECOMM")
+#else
+	#define KPDDName _L("EUART1")
+	#define KLDDName _L("ECOMM")	
+#endif	
+	TInt rerr = KErrNone;
+	
+	rerr = StartC32();
+	if ( rerr!=KErrNone && rerr!=KErrAlreadyExists )
+		{
+		return rerr;	
+		}
+
+	rerr = User::LoadPhysicalDevice(KPDDName);
+	if (rerr != KErrNone && rerr != KErrAlreadyExists)
+		{
+		return rerr;
+		}
+
+	rerr = User::LoadLogicalDevice(KLDDName);	
+	if (rerr != KErrNone && rerr != KErrAlreadyExists)
+		{
+		return rerr;
+		}
+	return KErrNone;	
+	}
+
+
+/**
+Called inside the MainL() function to create and start the test
+@return Instance of the test server
+*/
+CTestServerSymbianExcludeUsb* CTestServerSymbianExcludeUsb::NewL()
+
+	{
+	CTestServerSymbianExcludeUsb* server = new (ELeave) CTestServerSymbianExcludeUsb;
+	CleanupStack::PushL(server);
+	server->ConstructL(KServerName);
+	CleanupStack::Pop(server);
+	return server;
+	}
+
+LOCAL_C void MainL()
+	{
+	CActiveScheduler* sched = new (ELeave) CActiveScheduler;
+	CleanupStack::PushL(sched);
+	CActiveScheduler::Install(sched);
+
+	// this registers the server with the active scheduler and calls SetActive
+	CTestServerSymbianExcludeUsb* server = CTestServerSymbianExcludeUsb::NewL(); 
+
+	// signal to the client that we are ready by
+	// rendevousing process
+	RProcess::Rendezvous(KErrNone);
+	
+	// run the active scheduler
+	sched->Start();
+
+	// clean up
+	delete server;
+	CleanupStack::PopAndDestroy(sched);
+	}
+
+/**
+@return Standard Epoc error code on exit
+*/
+GLDEF_C TInt E32Main()
+	{	
+	TInt rerr = LoadDrivers();
+	if (rerr!=KErrNone)
+		{
+		return rerr;	
+		}
+	
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+
+	if (cleanup == NULL)
+		{
+		return KErrNoMemory;
+		}
+
+	TRAPD(err,MainL());
+
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return err;
+	} 
+
+/**
+Implementation of CTestServer pure virtual
+@return A CTestStep derived instance
+*/
+CTestStep* CTestServerSymbianExcludeUsb::CreateTestStep(const TDesC& aStepName)
+	{
+	if ( aStepName==KTestName001 )
+		{
+		return CTestStepUsbRomConfig001::New(*this);
+		}
+	if ( aStepName==KTestName002 )
+		{
+		return CTestStepUsbRomConfig002::New(*this);
+		}
+	if ( aStepName==KTestName003 )
+		{
+		return CTestStepUsbRomConfig003::New(*this);
+		}	
+	if ( aStepName==KTestName004 )
+		{
+		return CTestStepUsbRomConfig004::New(*this);
+		}				
+	return NULL;
+	}
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/testdata/UsbRomConfig.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,21 @@
+; Copyright (c) 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:
+;
+;
+[UsbIncluded]
+UsbExcluded = False
+
+[UsbExcluded]
+UsbExcluded = True
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/program files/common files/symbian/testSuite.dtd" [ ]>
+
+<testSuite>
+
+	<name>UsbRomConfigSuite</name>
+
+	<testItems>
+		<suite>UsbExcSuite</suite>
+		<suite>UsbIncSuite</suite>
+	</testItems>
+
+	<testExecuteServers>
+		<server>TestServerSymbianExcludeUsb</server>
+	</testExecuteServers>
+
+</testSuite>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/TestExecuteServers/TestServerSymbianExcludeUsb.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!DOCTYPE testExecuteServer SYSTEM "c:\program files\common files\symbian\testExecuteServer.dtd" [ ]>
+
+<testExecuteServer>
+
+	<name>TestServerSymbianExcludeUsb</name>
+
+	<mmpFile>testserversymbianexcludeusb.mmp</mmpFile>
+
+	<bldInfPath>group\bld.inf</bldInfPath>
+
+</testExecuteServer>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbExcSuite.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/program files/common files/symbian/testSuite.dtd" [ ]>
+
+<testSuite>
+
+	<name>UsbExcSuite</name>
+
+	<testItems>
+		<test>UsbRomConfig001</test>
+		<test>UsbRomConfig002</test>
+		<test>UsbRomConfig003</test>
+		<test>UsbRomConfig004</test>
+	</testItems>
+
+</testSuite>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbExcSuite/UsbRomConfig001.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!DOCTYPE testExecuteTest SYSTEM "c:\program files\common files\symbian\testExecuteTest.dtd" [ ]>
+
+<testExecuteTest>
+
+	<name>UsbRomConfig001</name>
+
+	<timeout>30</timeout>
+
+	<testScripts>
+		<script>
+			<hostPath>scripts\USB_ROMCONFIG_001.script</hostPath>
+			<devicePath>c:\scripts\usbromconfig\USB_ROMCONFIG_001.script</devicePath>
+		</script>
+	</testScripts>
+
+	<testServers>
+		<server>TestServerSymbianExcludeUsb</server>
+	</testServers>
+
+	<dependencies>
+		<data>
+			<hostPath>testdata\UsbRomConfig.ini</hostPath>
+			<devicePath>c:\testdata\usbromconfig\UsbRomConfig.ini</devicePath>
+		</data>
+	</dependencies>
+
+</testExecuteTest>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbExcSuite/UsbRomConfig002.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!DOCTYPE testExecuteTest SYSTEM "c:\program files\common files\symbian\testExecuteTest.dtd" [ ]>
+
+<testExecuteTest>
+
+	<name>UsbRomConfig002</name>
+
+	<timeout>30</timeout>
+
+	<testScripts>
+		<script>
+			<hostPath>scripts\USB_ROMCONFIG_002.script</hostPath>
+			<devicePath>c:\scripts\usbromconfig\USB_ROMCONFIG_002.script</devicePath>
+		</script>
+	</testScripts>
+
+	<testServers>
+		<server>TestServerSymbianExcludeUsb</server>
+	</testServers>
+
+	<dependencies>
+		<data>
+			<hostPath>testdata\UsbRomConfig.ini</hostPath>
+			<devicePath>c:\testdata\usbromconfig\UsbRomConfig.ini</devicePath>
+		</data>
+	</dependencies>
+
+</testExecuteTest>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbExcSuite/UsbRomConfig003.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!DOCTYPE testExecuteTest SYSTEM "c:\program files\common files\symbian\testExecuteTest.dtd" [ ]>
+
+<testExecuteTest>
+
+	<name>UsbRomConfig003</name>
+
+	<timeout>30</timeout>
+
+	<testScripts>
+		<script>
+			<hostPath>scripts\USB_ROMCONFIG_003.script</hostPath>
+			<devicePath>c:\scripts\usbromconfig\USB_ROMCONFIG_003.script</devicePath>
+		</script>
+	</testScripts>
+
+	<testServers>
+		<server>TestServerSymbianExcludeUsb</server>
+	</testServers>
+
+	<dependencies>
+		<data>
+			<hostPath>testdata\UsbRomConfig.ini</hostPath>
+			<devicePath>c:\testdata\usbromconfig\UsbRomConfig.ini</devicePath>
+		</data>
+	</dependencies>
+
+</testExecuteTest>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbExcSuite/UsbRomConfig004.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!DOCTYPE testExecuteTest SYSTEM "c:\program files\common files\symbian\testExecuteTest.dtd" [ ]>
+
+<testExecuteTest>
+
+	<name>UsbRomConfig004</name>
+
+	<timeout>30</timeout>
+
+	<testScripts>
+		<script>
+			<hostPath>scripts\USB_ROMCONFIG_004.script</hostPath>
+			<devicePath>c:\scripts\usbromconfig\USB_ROMCONFIG_004.script</devicePath>
+		</script>
+	</testScripts>
+
+	<testServers>
+		<server>TestServerSymbianExcludeUsb</server>
+	</testServers>
+
+	<dependencies>
+		<data>
+			<hostPath>testdata\UsbRomConfig.ini</hostPath>
+			<devicePath>c:\testdata\usbromconfig\UsbRomConfig.ini</devicePath>
+		</data>
+	</dependencies>
+
+</testExecuteTest>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbIncSuite.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/program files/common files/symbian/testSuite.dtd" [ ]>
+
+<testSuite>
+
+	<name>UsbIncSuite</name>
+
+	<testItems>
+		<test>UsbIncRomConfig001</test>
+		<test>UsbIncRomConfig002</test>
+		<test>UsbIncRomConfig003</test>
+		<test>UsbIncRomConfig004</test>
+	</testItems>
+
+</testSuite>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbIncSuite/UsbIncRomConfig001.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!DOCTYPE testExecuteTest SYSTEM "c:\program files\common files\symbian\testExecuteTest.dtd" [ ]>
+
+<testExecuteTest>
+
+	<name>UsbIncRomConfig001</name>
+
+	<timeout>30</timeout>
+
+	<testScripts>
+		<script>
+			<hostPath>scripts\USB_INC_ROMCONFIG_001.script</hostPath>
+			<devicePath>c:\scripts\usbromconfig\USB_INC_ROMCONFIG_001.script</devicePath>
+		</script>
+	</testScripts>
+
+	<testServers>
+		<server>TestServerSymbianExcludeUsb</server>
+	</testServers>
+
+	<dependencies>
+		<data>
+			<hostPath>testdata\UsbRomConfig.ini</hostPath>
+			<devicePath>c:\testdata\usbromconfig\UsbRomConfig.ini</devicePath>
+		</data>
+	</dependencies>
+
+</testExecuteTest>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbIncSuite/UsbIncRomConfig002.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!DOCTYPE testExecuteTest SYSTEM "c:\program files\common files\symbian\testExecuteTest.dtd" [ ]>
+
+<testExecuteTest>
+
+	<name>UsbIncRomConfig002</name>
+
+	<timeout>30</timeout>
+
+	<testScripts>
+		<script>
+			<hostPath>scripts\USB_INC_ROMCONFIG_002.script</hostPath>
+			<devicePath>c:\scripts\usbromconfig\USB_INC_ROMCONFIG_002.script</devicePath>
+		</script>
+	</testScripts>
+
+	<testServers>
+		<server>TestServerSymbianExcludeUsb</server>
+	</testServers>
+
+	<dependencies>
+		<data>
+			<hostPath>testdata\UsbRomConfig.ini</hostPath>
+			<devicePath>c:\testdata\usbromconfig\UsbRomConfig.ini</devicePath>
+		</data>
+	</dependencies>
+
+</testExecuteTest>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbIncSuite/UsbIncRomConfig003.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!DOCTYPE testExecuteTest SYSTEM "c:\program files\common files\symbian\testExecuteTest.dtd" [ ]>
+
+<testExecuteTest>
+
+	<name>UsbIncRomConfig003</name>
+
+	<timeout>30</timeout>
+
+	<testScripts>
+		<script>
+			<hostPath>scripts\USB_INC_ROMCONFIG_003.script</hostPath>
+			<devicePath>c:\scripts\usbromconfig\USB_INC_ROMCONFIG_003.script</devicePath>
+		</script>
+	</testScripts>
+
+	<testServers>
+		<server>TestServerSymbianExcludeUsb</server>
+	</testServers>
+
+	<dependencies>
+		<data>
+			<hostPath>testdata\UsbRomConfig.ini</hostPath>
+			<devicePath>c:\testdata\usbromconfig\UsbRomConfig.ini</devicePath>
+		</data>
+	</dependencies>
+
+</testExecuteTest>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/test/cit/ROMConfig/xml/UsbRomConfigSuite/UsbIncSuite/UsbIncRomConfig004.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!DOCTYPE testExecuteTest SYSTEM "c:\program files\common files\symbian\testExecuteTest.dtd" [ ]>
+
+<testExecuteTest>
+
+	<name>UsbIncRomConfig004</name>
+
+	<timeout>30</timeout>
+
+	<testScripts>
+		<script>
+			<hostPath>scripts\USB_INC_ROMCONFIG_004.script</hostPath>
+			<devicePath>c:\scripts\usbromconfig\USB_INC_ROMCONFIG_004.script</devicePath>
+		</script>
+	</testScripts>
+
+	<testServers>
+		<server>TestServerSymbianExcludeUsb</server>
+	</testServers>
+
+	<dependencies>
+		<data>
+			<hostPath>testdata\UsbRomConfig.ini</hostPath>
+			<devicePath>c:\testdata\usbromconfig\UsbRomConfig.ini</devicePath>
+		</data>
+	</dependencies>
+
+</testExecuteTest>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,21 @@
+/*
+* 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 "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 "extensionplugin/group/bld.inf"
+#include "server/group/bld.inf"
+#include "client/group/bld.inf"
+#include "chargingplugin/group/bld.inf"
Binary file usbmgmt/usbmgr/usbman/chargingplugin/conf/usbmanager_10208dd7.crml has changed
Binary file usbmgmt/usbmgr/usbman/chargingplugin/group/10208DD7.txt has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/group/UsbBatteryChargingPlugin.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* 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 "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:
+* usbbatterychargingplugin.dll UsbMan extension plugin for battery charging.
+* usbbatterychargingplugin.rsc Resource file for charging plugin.
+*
+*/
+
+/** @file
+@internalComponent
+@SYMPurpose usbbatterychargingplugin.dll UsbMan extension plugin for battery charging.
+@SYMPurpose usbbatterychargingplugin.rsc Resource file for charging plugin.
+*/
+
+TARGET			usbbatterychargingplugin.dll
+
+#include "UsbBatteryChargingPluginBase.mmp"
+
+SOURCEPATH      ../src
+SOURCE          vbuswatcher.cpp
+
+START RESOURCE 10208DD7.rss
+target usbbatterychargingplugin.rsc
+END
+
+//macro __USB_LOG_TO_RDEBUG__
+
+//macro __USB_LOGGING__
+
+//macro __CHARGING_PLUGIN_TEST_CODE__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/group/UsbBatteryChargingPluginBase.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,58 @@
+/*
+* 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 "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:
+* base mmp of UsbMan extension plugin for battery charging.
+* Resource file for charging plugin.
+*
+*/
+
+/** @file
+@internalComponent
+@SYMPurpose base mmp of UsbMan extension plugin for battery charging.
+@SYMPurpose Resource file for charging plugin.
+*/
+
+TARGETTYPE		PLUGIN
+// UID2 = 0x10009d8d for ECOM plugins.
+// UID3 = the 'DLL UID' (see resource file)
+UID 			0x10009d8d 0x10208DD7
+VENDORID		0x70000001
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+
+SOURCEPATH      ../src
+SOURCE          CUsbBatteryChargingPluginMain.cpp
+SOURCE          CUsbBatteryChargingPlugin.cpp
+SOURCE          chargingstates.cpp
+SOURCE          devicestatetimer.cpp
+SOURCE          reenumerator.cpp
+SOURCE          repositorynotifier.cpp
+
+
+USERINCLUDE		../inc
+USERINCLUDE		../public
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+// use this line for default implementation
+USERINCLUDE	../inc/default	
+
+LIBRARY 		euser.lib 
+LIBRARY 		usbmanextensionplugin.lib 
+LIBRARY			centralrepository.lib
+
+#include <usb/usblogger.mmh>
+
+
+//library	flogger.lib
+
+NOEXPORTLIBRARY
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/group/UsbBatteryChargingPluginotg.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,39 @@
+/*
+* 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 "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:
+* usbbatterychargingpluginotg.dll UsbMan extension plugin for battery charging.
+* usbbatterychargingplugin.rsc Resource file for charging plugin.
+*
+*/
+
+/** @file
+@internalComponent
+@SYMPurpose usbbatterychargingpluginotg.dll UsbMan extension plugin for battery charging.
+@SYMPurpose usbbatterychargingplugin.rsc Resource file for charging plugin.
+*/
+
+TARGET			usbbatterychargingpluginotg.dll
+
+#include "UsbBatteryChargingPluginBase.mmp"
+
+SOURCEPATH      ../src
+SOURCE          idpinwatcher.cpp
+SOURCE          vbuswatcher.cpp
+SOURCE          otgstatewatcher.cpp
+
+START RESOURCE 10208DD7.rss
+target usbbatterychargingpluginotg.rsc
+END
+
+MACRO            SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+PRJ_EXPORTS
+// repository files exported for testing purposes
+10208DD7.txt				/epoc32/data/z/private/10202be9/10208dd7.txt
+10208DD7.txt				/epoc32/release/winscw/udeb/z/private/10202be9/10208dd7.txt
+10208DD7.txt				/epoc32/release/winscw/urel/z/private/10202be9/10208dd7.txt
+
+// ConfML Files
+../conf/usbmanager_10208dd7.crml	       OS_LAYER_EXPORTS_CRML(usbmanager_10208dd7.crml)
+
+PRJ_MMPFILES
+    UsbBatteryChargingPlugin.mmp
+
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST) && !defined(WINS) && !defined(X86GCC)
+	UsbBatteryChargingPluginotg.mmp
+#endif
+
+PRJ_TESTEXPORTS
+// These files are exported so the battery charging TEST plugin can derive.
+../public/CUsbBatteryChargingPlugin.h   SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/charging/cusbbatterychargingplugin.h)
+../public/chargingstates.h              SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/charging/chargingstates.h)
+../public/devicestatetimer.h			SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(devicestatetimer.h)
+../public/repositorynotifier.h			SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(repositorynotifier.h)
+../public/motgobserver.h				SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(motgobserver.h)
+../public/usbbatterycharging.h			SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usbbatterycharging.h)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/inc/default/cusbbatterycharginglicenseehooks.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,68 @@
+/*
+* 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 "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
+*/
+
+#include <e32base.h>
+
+
+class CUsbBatteryChargingLicenseeHooks : public CBase
+	{
+public:
+	inline static CUsbBatteryChargingLicenseeHooks* NewL();
+	inline ~CUsbBatteryChargingLicenseeHooks();
+
+	inline void StartCharging(TUint aMilliAmps);
+	inline void StopCharging();
+private:
+	inline CUsbBatteryChargingLicenseeHooks();
+	inline void ConstructL();
+	};
+
+
+inline CUsbBatteryChargingLicenseeHooks* CUsbBatteryChargingLicenseeHooks::NewL()
+	{
+	CUsbBatteryChargingLicenseeHooks* self = new(ELeave) CUsbBatteryChargingLicenseeHooks;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+inline CUsbBatteryChargingLicenseeHooks::~CUsbBatteryChargingLicenseeHooks()
+	{
+	}
+
+inline void CUsbBatteryChargingLicenseeHooks::StartCharging(TUint /*aMilliAmps*/)
+	{
+	}
+
+inline void CUsbBatteryChargingLicenseeHooks::StopCharging()
+	{
+	}
+
+inline CUsbBatteryChargingLicenseeHooks::CUsbBatteryChargingLicenseeHooks()
+	{
+	}
+
+inline void CUsbBatteryChargingLicenseeHooks::ConstructL()
+	{
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/inc/idpinwatcher.h	Tue Feb 02 02:02:59 2010 +0200
@@ -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 "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
+*/
+
+#ifndef IDPINWATCHER_H
+#define IDPINWATCHER_H
+
+#include <e32def.h>
+#include <e32property.h> //Publish & Subscribe header
+#include <e32cmn.h>
+#include <e32base.h>
+#include "motgobserver.h"
+
+NONSHARABLE_CLASS(CIdPinWatcher) : public CActive
+	{
+public:
+	static CIdPinWatcher* NewL(MOtgPropertiesObserver* aObserver);
+	~CIdPinWatcher();
+
+	TInt IdPinValue() const;
+
+private:
+	CIdPinWatcher(MOtgPropertiesObserver* aObserver);
+	void ConstructL();
+	
+private:
+	void RunL();
+	void DoCancel();
+
+private:
+	MOtgPropertiesObserver* iObserver;
+	RProperty				iIdPinProp;
+	TInt					iIdPinValue;
+	};
+
+#endif //IDPINWATCHER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/inc/otgstatewatcher.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,55 @@
+/*
+* 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 "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
+*/
+
+#ifndef OTGSTATEWATCHER_H
+#define OTGSTATEWATCHER_H
+
+#include <e32def.h>
+#include <e32property.h> //Publish & Subscribe header
+#include <e32cmn.h>
+#include <e32base.h>
+#include <usbotgdefs.h>
+#include "motgobserver.h"
+
+NONSHARABLE_CLASS(COtgStateWatcher) : public CActive
+	{
+public:
+	static COtgStateWatcher* NewL(MOtgPropertiesObserver* aObserver);
+	~COtgStateWatcher();
+
+	TUsbOtgState OtgState() const;
+
+private:
+	COtgStateWatcher(MOtgPropertiesObserver* aObserver);
+	void ConstructL();
+	
+private:
+	void RunL();
+	void DoCancel();
+
+private:
+	MOtgPropertiesObserver* iObserver;
+	RProperty				iOtgStateProp;
+	TUsbOtgState			iOtgState;
+	};
+
+#endif //OTGSTATEWATCHER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/inc/reenumerator.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,50 @@
+/*
+* 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 "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
+*/
+
+#ifndef REENUMERATOR_H
+#define REENUMERATOR_H
+
+#include <e32base.h>
+
+#ifdef __CHARGING_PLUGIN_TEST_CODE__
+#include <dummyldd.h>
+#define __D32USBC_H__ // ensure that d32usbc is ignored
+#else
+#include <d32usbc.h>
+#endif
+
+class CUsbChargingReEnumerator : public CActive
+	{
+public:
+	static CUsbChargingReEnumerator* NewL(RDevUsbcClient& aLdd);
+	~CUsbChargingReEnumerator();
+	void ReEnumerate();
+private:
+	CUsbChargingReEnumerator(RDevUsbcClient& aLdd);
+	void RunL();
+	void DoCancel();
+
+private:
+	RDevUsbcClient& iLdd;
+	};
+
+#endif // REENUMERATOR_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/inc/vbuswatcher.h	Tue Feb 02 02:02:59 2010 +0200
@@ -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 "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
+*/
+
+#ifndef VBUSWATCHER_H
+#define VBUSWATCHER_H
+
+#include <e32def.h>
+#include <e32property.h> //Publish & Subscribe header
+#include <e32cmn.h>
+#include <e32base.h>
+#include "motgobserver.h"
+
+NONSHARABLE_CLASS(CVBusWatcher) : public CActive
+	{
+public:
+	static CVBusWatcher* NewL(MOtgPropertiesObserver* aObserver);
+	~CVBusWatcher();
+
+	TInt VBusState() const;
+
+private:
+	CVBusWatcher(MOtgPropertiesObserver* aObserver);
+	void ConstructL();
+	
+private:
+	void RunL();
+	void DoCancel();
+
+private:
+	MOtgPropertiesObserver*  iObserver;
+	RProperty				iVBusProp;
+	TInt					iVBusState;
+	};
+
+#endif //VBUSWATCHER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/public/CUsbBatteryChargingPlugin.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,242 @@
+/*
+* 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 "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
+*/
+
+#ifndef USBBATTERYCHARGINGPLUGIN_H
+#define USBBATTERYCHARGINGPLUGIN_H
+
+#include <e32base.h>
+
+#ifdef __CHARGING_PLUGIN_TEST_CODE__
+#include <dummyldd.h>
+#define __D32USBC_H__ // ensure that d32usbc is ignored
+#define private protected
+#else
+#include <d32usbc.h>
+#endif
+
+#include <cusbmanextensionplugin.h>
+#include "usbbatterycharging.h"
+#include <musbdevicenotify.h>
+#include "devicestatetimer.h"
+#include "repositorynotifier.h"
+#include "motgobserver.h"
+
+class CUsbChargingReEnumerator;
+class CUsbBatteryChargingLicenseeHooks;
+
+// For host OTG enabled charging plug-in
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+class CIdPinWatcher;
+class COtgStateWatcher;
+#endif
+
+class CVBusWatcher;
+
+enum TUsbBatteryChargingPanic
+    {
+    EUsbBatteryChargingPanicBadUserSetting = 0,
+    EUsbBatteryChargingPanicBadPluginState = 1,
+    EUsbBatteryChargingPanicUnexpectedPluginState = 2,
+    EUsbBatteryChargingPanicBadDeviceState = 3,
+    EUsbBatteryChargingPanicBadOtgState = 4,
+    EUsbBatteryChargingPanicBadVBusState = 5,
+    EUsbBatteryChargingPanicBadCharingCurrentNegotiation = 6
+    };
+
+// For host OTG enabled charging plug-in
+class MUsbBatteryChargingPluginInterface : public MUsbDeviceNotify,
+    public MUsbChargingRepositoryObserver,
+    public MUsbChargingDeviceStateTimerObserver, public MOtgPropertiesObserver
+    {
+public:  // from MUsbDeviceNotify
+    virtual void UsbServiceStateChange (TInt aLastError,
+        TUsbServiceState aOldState, TUsbServiceState aNewState) = 0;
+    virtual void UsbDeviceStateChange (TInt aLastError,
+        TUsbDeviceState aOldState, TUsbDeviceState aNewState) = 0;
+
+public: // from MUsbChargingRepositoryObserver
+    virtual void HandleRepositoryValueChangedL(const TUid& aRepository, TUint aId, TInt aVal) = 0;
+    
+public: // from MUsbChargingDeviceStateTimerObserver
+    virtual void DeviceStateTimeout() = 0;
+
+public: // from MOtgPropertiesObserver
+// For host OTG enabled charging plug-in
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV 
+    virtual void MpsoIdPinStateChanged(TInt aValue) = 0;
+    virtual void MpsoOtgStateChangedL(TUsbOtgState aNewState) = 0;
+#endif    
+    virtual void MpsoVBusStateChanged(TInt aNewState) = 0;
+    };
+
+class TUsbBatteryChargingPluginStateBase;
+class TUsbBatteryChargingPluginStateIdle;
+class TUsbBatteryChargingPluginStateIdleUserDisabled;
+class TUsbBatteryChargingPluginStateNoValidcurrent;
+class TUsbBatteryChargingPluginStateCurrentNegotiating;
+class TUsbBatteryChargingPluginStateCharging;
+class TUsbBatteryChargingPluginStateIdelNegotiated;
+class TUsbBatteryChargingPluginStateBEndedCableNotPresent;
+
+enum TUsbChargingPluginState
+    {
+    // The default first state of this plugin
+    EPluginStateIdle = 0,
+    
+    // Start to negotiate with A device about the charging current
+    // re-enumration is executed 
+    EPluginStateCurrentNegotiating,
+    
+    // Negotiation failed
+    EPluginStateNoValidCurrent,
+    
+    // The only that indicate charging is going on 
+    EPluginStateCharging,
+    
+    // charging is stopped for some reason, but negotiation is done already
+    EPluginStateIdleNegotiated,
+    
+    // User Disabled "charging from usb" functionality
+    EPluginStateUserDisabled,
+
+    // Deivce is connect with A end cable, so, no way to do a charging to itself 
+    EPluginStateBEndedCableNotPresent,
+        
+    // State counter
+    EPluginStateCount
+    };
+
+
+class CUsbBatteryChargingPlugin : public CUsbmanExtensionPlugin,
+    private MUsbBatteryChargingPluginInterface 
+    {
+    friend class TUsbBatteryChargingPluginStateBase;
+    friend class TUsbBatteryChargingPluginStateIdle;
+    friend class TUsbBatteryChargingPluginStateUserDisabled;
+    friend class TUsbBatteryChargingPluginStateNoValidCurrent;
+    friend class TUsbBatteryChargingPluginStateCurrentNegotiating;
+    friend class TUsbBatteryChargingPluginStateCharging;
+    friend class TUsbBatteryChargingPluginStateIdleNegotiated;
+    friend class TUsbBatteryChargingPluginStateBEndedCableNotPresent;
+    
+public:
+    static CUsbBatteryChargingPlugin* NewL(MUsbmanExtensionPluginObserver& aObserver);
+    ~CUsbBatteryChargingPlugin();
+
+private: // from CUsbmanExtensionPlugin
+    TAny* GetInterface(TUid aUid);
+    
+private:  // from MUsbBatteryChargingPluginInterface
+    // from MUsbDeviceNotify
+    void UsbServiceStateChange (TInt aLastError,
+        TUsbServiceState aOldState, TUsbServiceState aNewState);
+    void UsbDeviceStateChange (TInt aLastError,
+        TUsbDeviceState aOldState, TUsbDeviceState aNewState);
+
+    // from MUsbChargingRepositoryObserver
+    void HandleRepositoryValueChangedL(const TUid& aRepository, TUint aId, TInt aVal);
+    
+    // from MUsbChargingDeviceStateTimerObserver
+    void DeviceStateTimeout();
+
+// For host OTG enabled charging plug-in
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV 
+    // from MOtgPropertiesObserver
+    void MpsoIdPinStateChanged(TInt aValue);
+    void MpsoOtgStateChangedL(TUsbOtgState aNewState);
+#endif
+    
+    void MpsoVBusStateChanged(TInt aNewState);
+private:
+    CUsbBatteryChargingPlugin(MUsbmanExtensionPluginObserver& aObserver);
+    void ConstructL();
+    void Panic(TUsbBatteryChargingPanic aPanic);
+
+private:
+    void StartCharging(TUint aMilliAmps);
+    void StopCharging();
+    
+    void SetNegotiatedCurrent(TUint aMilliAmps);
+    void ReadCurrentRequestValuesL();
+    
+    void NegotiateChargingCurrent();
+    void NegotiateNextCurrentValueL();
+    void RequestCurrentL(TUint aMilliAmps);
+    
+    void ResetPlugin();
+            
+    void SetInitialConfigurationL();
+    
+    TBool IsUsbChargingPossible();
+    
+    void LogStateText(TUsbDeviceState aState);
+    void PushRecoverState(TUsbChargingPluginState aRecoverState);
+    TUsbChargingPluginState PopRecoverState();
+    
+    TUsbChargingPluginState SetState(TUsbChargingPluginState aState);
+    
+private: // owned
+    RDevUsbcClient& iLdd;
+       
+    // user allow usb charging function already?
+    TUsbBatteryChargingUserSetting iUserSetting;
+    
+    // More than one value will be tried by the negotiation process to 
+    // aquire a as larger current value as possible for charging
+    RArray<TInt> iCurrentValues;
+    
+    //value of requested current set to descriptor for negotiation
+    TInt iRequestedCurrentValue;
+    
+    //index of requested value
+    TInt iCurrentIndexRequested;
+    
+    //value of negotiated current
+    TInt iAvailableMilliAmps;   
+
+    CUsbChargingDeviceStateTimer*   iDeviceStateTimer;
+    CUsbChargingRepositoryNotifier* iRepositoryNotifier;
+    CUsbChargingReEnumerator*       iDeviceReEnumerator;
+
+    CUsbBatteryChargingLicenseeHooks* iLicenseeHooks;
+
+// For host OTG enabled charging plug-in
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV     
+    //Outer state watchers
+    COtgStateWatcher *iOtgStateWatcher;
+    CIdPinWatcher *iIdPinWatcher;
+    //Outer states
+    TInt iIdPinState;
+    TUsbOtgState iOtgState;
+#endif    
+    
+    TInt iVBusState;
+    CVBusWatcher *iVBusWatcher;
+    TUsbDeviceState iDeviceState;
+    
+    // Plug-in States
+    TUsbChargingPluginState iPluginState; // Current state machine status
+    TUsbChargingPluginState iPluginStateToRecovery; // The recover state when user enable USB Charging
+    TUsbBatteryChargingPluginStateBase* iCurrentState; // Owned
+    TUsbBatteryChargingPluginStateBase* iPluginStates[EPluginStateCount]; // State implementations
+    };
+
+#endif // USBBATTERYCHARGINGPLUGIN_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/public/chargingstates.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,140 @@
+/*
+* Copyright (c) 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
+*/
+#ifndef CHARGINGSTATES_H
+#define CHARGINGSTATES_H
+
+#include "CUsbBatteryChargingPlugin.h"
+
+class TUsbBatteryChargingPluginStateBase : public MUsbBatteryChargingPluginInterface
+    {
+    friend class CUsbBatteryChargingPlugin;
+    
+protected:  // from MUsbBatteryChargingPluginInterface
+    // from MUsbDeviceNotify
+    virtual void UsbServiceStateChange (TInt aLastError,
+        TUsbServiceState aOldState, TUsbServiceState aNewState);
+    virtual void UsbDeviceStateChange (TInt aLastError,
+        TUsbDeviceState aOldState, TUsbDeviceState aNewState);
+
+    // from MUsbChargingRepositoryObserver
+    virtual void HandleRepositoryValueChangedL (const TUid& aRepository,
+        TUint aId, TInt aVal);
+    
+    // from MUsbChargingDeviceStateTimerObserver
+    virtual void DeviceStateTimeout();
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV          // For host OTG enabled charging plug-in    
+    // from MOtgPropertiesObserver
+    virtual void MpsoIdPinStateChanged(TInt aValue);
+    virtual void MpsoOtgStateChangedL(TUsbOtgState aNewState);
+#endif
+    virtual void MpsoVBusStateChanged(TInt aNewState);
+    
+protected:
+    TUsbBatteryChargingPluginStateBase(CUsbBatteryChargingPlugin& aParentStateMachine);
+    
+protected:
+    CUsbBatteryChargingPlugin& iParent; // Charging state machine. Not Owned
+    };
+
+class TUsbBatteryChargingPluginStateIdle : public TUsbBatteryChargingPluginStateBase
+    {
+public:
+    TUsbBatteryChargingPluginStateIdle(
+            CUsbBatteryChargingPlugin& aParentStateMachine);
+    
+private:
+    void UsbDeviceStateChange(
+        TInt aLastError, TUsbDeviceState aOldState, TUsbDeviceState aNewState);
+    };
+
+class TUsbBatteryChargingPluginStateNoValidCurrent : public TUsbBatteryChargingPluginStateBase
+    {
+public:
+    TUsbBatteryChargingPluginStateNoValidCurrent(
+            CUsbBatteryChargingPlugin& aParentStateMachine);
+    };
+
+class TUsbBatteryChargingPluginStateCurrentNegotiating : public TUsbBatteryChargingPluginStateBase
+    {
+public:
+    TUsbBatteryChargingPluginStateCurrentNegotiating(
+            CUsbBatteryChargingPlugin& aParentStateMachine);
+    
+private:
+    void UsbDeviceStateChange(TInt aLastError, TUsbDeviceState aOldState, 
+            TUsbDeviceState aNewState);
+    void DeviceStateTimeout();
+    };
+
+class TUsbBatteryChargingPluginStateCharging : public TUsbBatteryChargingPluginStateBase
+    {
+public:
+    TUsbBatteryChargingPluginStateCharging(
+            CUsbBatteryChargingPlugin& aParentStateMachine);
+    
+private:
+    void UsbDeviceStateChange(TInt aLastError, TUsbDeviceState aOldState, 
+            TUsbDeviceState aNewState);
+    };
+
+class TUsbBatteryChargingPluginStateIdleNegotiated : public TUsbBatteryChargingPluginStateBase
+    {
+public:
+    TUsbBatteryChargingPluginStateIdleNegotiated(
+            CUsbBatteryChargingPlugin& aParentStateMachine);
+    
+private:
+    void UsbDeviceStateChange(TInt aLastError, TUsbDeviceState aOldState, 
+            TUsbDeviceState aNewState);
+    };
+
+class TUsbBatteryChargingPluginStateUserDisabled : public TUsbBatteryChargingPluginStateBase
+    {
+public:
+    TUsbBatteryChargingPluginStateUserDisabled(
+            CUsbBatteryChargingPlugin& aParentStateMachine);
+    
+private:
+    void UsbDeviceStateChange(TInt aLastError, TUsbDeviceState aOldState, 
+            TUsbDeviceState aNewState);
+    
+    // from MUsbChargingRepositoryObserver
+    void HandleRepositoryValueChangedL (const TUid& aRepository, 
+            TUint aId, TInt aVal);
+    
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV          // For host OTG enabled charging plug-in     
+    void MpsoIdPinStateChanged(TInt aValue);
+#endif
+    void MpsoVBusStateChanged(TInt aNewState);
+    };
+
+class TUsbBatteryChargingPluginStateBEndedCableNotPresent : public TUsbBatteryChargingPluginStateBase
+    {
+public:
+    TUsbBatteryChargingPluginStateBEndedCableNotPresent(
+            CUsbBatteryChargingPlugin& aParentStateMachine);
+    };
+
+#endif // CHARGINGSTATES_H
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/public/devicestatetimer.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,51 @@
+/*
+* 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 "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
+*/
+
+#ifndef DEVICESTATETIMER_H
+#define DEVICESTATETIMER_H
+
+#include <e32base.h>
+
+class MUsbChargingDeviceStateTimerObserver
+	{
+public:
+	virtual void DeviceStateTimeout() = 0;
+	};
+
+class CUsbChargingDeviceStateTimer : public CTimer
+	{
+public:
+	static CUsbChargingDeviceStateTimer* NewL(MUsbChargingDeviceStateTimerObserver& aObserver);
+	~CUsbChargingDeviceStateTimer();
+	void Start(TTimeIntervalMicroSeconds32 aTime);
+private:
+	void ConstructL();
+	CUsbChargingDeviceStateTimer(MUsbChargingDeviceStateTimerObserver& aObserver);
+	void RunL();
+	void DoCancel();
+
+private:
+	MUsbChargingDeviceStateTimerObserver& iObserver;
+	TTimeIntervalMicroSeconds32 iTime;
+	};
+
+#endif // DEVICESTATETIMER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/public/motgobserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,44 @@
+/*
+* 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 "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
+*/
+
+#ifndef MOTGOBSERVER_H
+#define MOTGOBSERVER_H
+
+#include <e32def.h>
+#include <e32property.h> //Publish & Subscribe header
+#include <e32cmn.h>
+#include <e32base.h>
+#include <usbotgdefs.h>
+
+//To observe ID-pin, VBus and OtgState properties via Publish and Subscribe
+NONSHARABLE_CLASS(MOtgPropertiesObserver)
+	{
+public:
+// For host OTG enabled charging plug-in
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV 
+	virtual void MpsoIdPinStateChanged(TInt aValue) = 0;
+	virtual void MpsoOtgStateChangedL(TUsbOtgState aNewState) = 0;
+#endif	
+	virtual void MpsoVBusStateChanged(TInt aNewState) = 0;
+	};
+
+
+#endif //MOTGOBSERVER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/public/repositorynotifier.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,57 @@
+/*
+* 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 "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
+*/
+
+#ifndef REPOSITORYNOTIFIER_H
+#define REPOSITORYNOTIFIER_H
+
+#include <e32base.h>
+
+class CRepository;
+
+class MUsbChargingRepositoryObserver
+	{
+public:
+	virtual void HandleRepositoryValueChangedL(const TUid& aRepository, TUint aId, TInt aVal) = 0;
+	};
+
+class CUsbChargingRepositoryNotifier : public CActive
+	{
+public:
+	~CUsbChargingRepositoryNotifier();
+	static CUsbChargingRepositoryNotifier* NewL(MUsbChargingRepositoryObserver& aObserver,const TUid& aRepository, TUint aId);
+	void Notify();
+protected:
+	CUsbChargingRepositoryNotifier(MUsbChargingRepositoryObserver& aObserver,const TUid& aRepository, TUint aId);
+	void RunL();
+	void ConstructL();
+private:
+	void DoCancel();
+	TInt RunError(TInt aError);
+
+protected:
+	MUsbChargingRepositoryObserver& iObserver;
+	CRepository*	iRepository;
+	TUid			iRepositoryUid;
+	TUint			iId;
+	};
+
+#endif // REPOSITORYNOTIFIER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/public/usbbatterycharging.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,51 @@
+/*
+* 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 "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
+*/
+
+#ifndef USBBATTERYCHARGING_H
+#define USBBATTERYCHARGING_H
+
+#include <e32base.h>
+
+// UID used for central respository
+const TUid KUsbBatteryChargingCentralRepositoryUid = {0x10208DD7};	// UID3 for usbbatterychargingplugin
+
+const TUid KPropertyUidUsbBatteryChargingCategory = {0x101fe1db};
+const TUint KPropertyUidUsbBatteryChargingAvailableCurrent = 1; // current negotiated
+const TUint KPropertyUidUsbBatteryChargingChargingCurrent = 2; // current for charging (i.e. depends on user setting)
+
+const TUint KUsbBatteryChargingKeyEnabledUserSetting = 1;
+const TUint KUsbBatteryChargingKeyNumberOfCurrentValues = 2;
+
+const TUint KUsbBatteryChargingCurrentValuesOffset = 0x1000;
+
+enum TUsbBatteryChargingUserSetting
+	{
+	EUsbBatteryChargingUserSettingDisabled = 0,
+	EUsbBatteryChargingUserSettingEnabled,
+	};
+
+enum TUsbIdPinState
+    {
+    EUsbBatteryChargingIdPinBRole = 0,
+    EUsbBatteryChargingIdPinARole,
+    };
+
+#endif // USBBATTERYCHARGING_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/src/10208DD7.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,46 @@
+/*
+* 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 "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
+*/
+
+#include <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x10208DD7;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x10208DD6;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x10208DD8;
+					version_no = 1;
+					display_name = "UsbBatteryChargingPlugin";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/src/CUsbBatteryChargingPlugin.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,664 @@
+/*
+* 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 "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
+*/
+
+#include "CUsbBatteryChargingPlugin.h"
+#include "chargingstates.h"
+#include <musbmanextensionpluginobserver.h>
+#include "cusbbatterycharginglicenseehooks.h"
+#include "reenumerator.h"
+#include <usb/usblogger.h>
+#include <e32property.h>
+#include <centralrepository.h>
+#include <usbotgdefs.h>
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV          // For host OTG enabled charging plug-in 
+#include "idpinwatcher.h"
+#include "otgstatewatcher.h"
+#endif
+
+#include "vbuswatcher.h"
+#include <e32debug.h> 
+#include <e32def.h>
+
+static const TInt KUsbBatteryChargingConfigurationDescriptorCurrentOffset = 8; // see bMaxPower in section 9.6.3 of USB Spec 2.0
+static const TInt KUsbBatteryChargingCurrentRequestTimeout = 3000000; // 3 seconds
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBCHARGE");
+#endif
+
+/**
+Factory function.
+@return Ownership of a new CUsbBatteryChargingPlugin.
+*/
+CUsbBatteryChargingPlugin* CUsbBatteryChargingPlugin::NewL(MUsbmanExtensionPluginObserver& aObserver)
+    {
+    CUsbBatteryChargingPlugin* self = new(ELeave) CUsbBatteryChargingPlugin(aObserver);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+/**
+Destructor.
+*/
+CUsbBatteryChargingPlugin::~CUsbBatteryChargingPlugin()
+    {
+    LOGTEXT(KNullDesC8);
+    LOGTEXT2(_L8(">>CUsbBatteryChargingPlugin::~CUsbBatteryChargingPlugin this = [0x%08x]"), this);
+    
+    iCurrentValues.Close();
+    delete iDeviceReEnumerator;
+    delete iDeviceStateTimer;
+    delete iRepositoryNotifier;
+    delete iLicenseeHooks;
+    
+// For host OTG enabled charging plug-in
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+    delete iIdPinWatcher;
+    delete iOtgStateWatcher;
+#endif
+    
+    delete iVBusWatcher;
+    for (TInt index = 0; index < EPluginStateCount; index ++)
+        {
+        delete iPluginStates[index];
+        iPluginStates[index] = NULL;
+        }
+    }
+
+/**
+Constructor.
+*/
+CUsbBatteryChargingPlugin::CUsbBatteryChargingPlugin(MUsbmanExtensionPluginObserver& aObserver)
+:    CUsbmanExtensionPlugin(aObserver) , iLdd(Observer().DevUsbcClient())
+    {
+    }
+
+/**
+2nd-phase construction.
+*/
+void CUsbBatteryChargingPlugin::ConstructL()
+    {
+    LOGTEXT(_L8(">>CUsbBatteryChargingPlugin::ConstructL"));
+   
+    // Create state objects
+    iPluginStates[EPluginStateIdle] = 
+        new (ELeave) TUsbBatteryChargingPluginStateIdle(*this);
+    iPluginStates[EPluginStateCurrentNegotiating] = 
+        new (ELeave) TUsbBatteryChargingPluginStateCurrentNegotiating(*this);
+    iPluginStates[EPluginStateCharging] = 
+        new (ELeave) TUsbBatteryChargingPluginStateCharging(*this);
+    iPluginStates[EPluginStateNoValidCurrent] = 
+        new (ELeave) TUsbBatteryChargingPluginStateNoValidCurrent(*this);
+    iPluginStates[EPluginStateIdleNegotiated] = 
+        new (ELeave) TUsbBatteryChargingPluginStateIdleNegotiated(*this);
+    iPluginStates[EPluginStateUserDisabled] = 
+        new (ELeave) TUsbBatteryChargingPluginStateUserDisabled(*this);
+    iPluginStates[EPluginStateBEndedCableNotPresent] = 
+        new (ELeave) TUsbBatteryChargingPluginStateBEndedCableNotPresent(*this);
+
+    // Set initial state to idle
+    SetState(EPluginStateIdle);
+    
+    TInt err = RProperty::Define(KPropertyUidUsbBatteryChargingCategory,
+                      KPropertyUidUsbBatteryChargingAvailableCurrent,
+                      RProperty::EInt,
+                      ECapabilityReadDeviceData,
+                      ECapabilityCommDD);
+
+    if(err == KErrNone || err == KErrAlreadyExists)
+        {
+
+        err = RProperty::Define(KPropertyUidUsbBatteryChargingCategory,
+                          KPropertyUidUsbBatteryChargingChargingCurrent,
+                          RProperty::EInt,
+                          ECapabilityReadDeviceData,
+                          ECapabilityCommDD);
+        }
+    else
+        {
+        LEAVEL(err);
+        }
+
+    if(err == KErrNone || err == KErrAlreadyExists)
+        {
+        err = RProperty::Set(KPropertyUidUsbBatteryChargingCategory,
+                                        KPropertyUidUsbBatteryChargingAvailableCurrent,
+                                        0);
+        }
+    else
+        {
+        static_cast<void> (RProperty::Delete (
+                KPropertyUidUsbBatteryChargingCategory,
+                KPropertyUidUsbBatteryChargingAvailableCurrent ));
+        LEAVEL(err);
+        }
+    
+    err = RProperty::Set(KPropertyUidUsbBatteryChargingCategory,
+                                        KPropertyUidUsbBatteryChargingChargingCurrent,
+                                        0);
+
+    if(err != KErrNone)
+        {
+        static_cast<void> (RProperty::Delete (
+                KPropertyUidUsbBatteryChargingCategory,
+                KPropertyUidUsbBatteryChargingAvailableCurrent ));
+        static_cast<void> (RProperty::Delete (
+                KPropertyUidUsbBatteryChargingCategory,
+                KPropertyUidUsbBatteryChargingChargingCurrent ));
+        LEAVEL(err);
+        }
+        
+    iRepositoryNotifier = CUsbChargingRepositoryNotifier::NewL (*this,
+            KUsbBatteryChargingCentralRepositoryUid,
+            KUsbBatteryChargingKeyEnabledUserSetting );
+    iDeviceStateTimer = CUsbChargingDeviceStateTimer::NewL(*this);
+
+    iDeviceReEnumerator = CUsbChargingReEnumerator::NewL(iLdd);
+
+    iPluginState = EPluginStateIdle;
+    iPluginStateToRecovery = EPluginStateIdle;
+    ReadCurrentRequestValuesL();
+    iVBusWatcher = CVBusWatcher::NewL(this);
+    iVBusState = iVBusWatcher->VBusState();
+    
+// For host OTG enabled charging plug-in
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+    iOtgStateWatcher = COtgStateWatcher::NewL(this);
+    iOtgState = iOtgStateWatcher->OtgState();
+    iIdPinWatcher = CIdPinWatcher::NewL(this);
+    TInt value = iIdPinWatcher->IdPinValue();
+    iIdPinState = iIdPinWatcher->IdPinValue();
+    if (iIdPinState == EUsbBatteryChargingIdPinBRole)
+#else
+    if (ETrue)
+#endif
+        {
+#if !defined(__WINS__) && !defined(__CHARGING_PLUGIN_TEST_CODE__)
+        SetInitialConfigurationL();
+#endif
+        }
+    else
+        {
+        iPluginState = EPluginStateBEndedCableNotPresent;
+        LOGTEXT2(_L8("PluginState => EPluginStateADevice(%d)"), iPluginState);
+        }
+
+    Observer().RegisterStateObserverL(*this);
+
+    iLicenseeHooks = CUsbBatteryChargingLicenseeHooks::NewL();
+    LOGTEXT(_L8("Created licensee specific hooks"));
+    
+    // Set initial recovery state to idle
+    PushRecoverState(EPluginStateIdle);
+    
+    LOGTEXT(_L8("<<CUsbBatteryChargingPlugin::ConstructL"));
+    }
+
+// For host OTG enabled charging plug-in
+TBool CUsbBatteryChargingPlugin::IsUsbChargingPossible()
+    {
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+    // VBus is off, so there is no way to do charging
+    if (0 == iVBusState)
+        {
+        return EFalse;
+        }
+    
+    // 'A' end cable connected. I'm the power supplier, with no way to charge myself :-) 
+    if (EUsbBatteryChargingIdPinARole == iIdPinState)
+        {
+        return EFalse;
+        }
+
+    // BHost charging is disabled
+    if (EUsbOtgStateBHost == iOtgState)
+        {
+        return EFalse;
+        }
+        
+    return ETrue;
+#else
+    return ETrue;
+#endif
+    }
+/**
+ Set first power to request
+*/
+void CUsbBatteryChargingPlugin::SetInitialConfigurationL()
+    {
+    LOGTEXT(_L8("Setting Initial Configuration"));
+    if (iCurrentValues.Count() > 0)
+        {
+        TInt configDescriptorSize = 0;
+        LEAVEIFERRORL(iLdd.GetConfigurationDescriptorSize(configDescriptorSize));
+        HBufC8* configDescriptor = HBufC8::NewLC(configDescriptorSize);
+        TPtr8 ptr(configDescriptor->Des());
+
+        LOGTEXT2(_L8("Getting Configuration Descriptor (size = %d)"),configDescriptorSize);
+        LEAVEIFERRORL(iLdd.GetConfigurationDescriptor(ptr));
+
+// For host OTG enabled charging plug-in
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+        // Get first power to put in configurator
+        LOGTEXT(_L8("Checking IdPin state:"));
+        if(iIdPinState == EUsbBatteryChargingIdPinBRole)
+#else
+        if (ETrue)
+#endif
+        	{
+            if (iCurrentValues.Count() > 0)
+                {
+                iCurrentIndexRequested = 0;
+                iRequestedCurrentValue = iCurrentValues[iCurrentIndexRequested];
+                LOGTEXT2(_L8("IdPin state is 0, current set to: %d"), iRequestedCurrentValue);
+                }
+            else
+                {
+                LOGTEXT(_L8("No vailable current found !"));
+                }
+            }
+        else
+            {
+            iRequestedCurrentValue = 0;
+            LOGTEXT(_L8("IdPin state is 1, current set to 0"));
+            }
+
+        TUint oldCurrentValue = ptr[KUsbBatteryChargingConfigurationDescriptorCurrentOffset] << 1;
+        ptr[KUsbBatteryChargingConfigurationDescriptorCurrentOffset] = (iRequestedCurrentValue >> 1);
+
+        LOGTEXT(_L8("Setting Updated Configuration Descriptor"));
+        LEAVEIFERRORL(iLdd.SetConfigurationDescriptor(ptr));
+
+        CleanupStack::PopAndDestroy(configDescriptor); 
+        }
+    }
+
+
+TAny* CUsbBatteryChargingPlugin::GetInterface(TUid aUid)
+    {
+    LOGTEXT(KNullDesC8);
+    LOGTEXT3(_L8(">>CUsbBatteryChargingPlugin::GetInterface this = [0x%08x], aUid = 0x%08x"), this, aUid);
+    (void)aUid;
+
+    TAny* ret = NULL;
+
+    LOGTEXT2(_L8("<<CUsbBatteryChargingPlugin::GetInterface ret = [0x%08x]"), ret);
+    return ret;
+    }
+
+void CUsbBatteryChargingPlugin::Panic(TUsbBatteryChargingPanic aPanic)
+    {
+    LOGTEXT2(_L8("*** CUsbBatteryChargingPlugin::Panic(%d) ***"),aPanic);
+    _LIT(KUsbChargingPanic,"USB Charging");
+    User::Panic(KUsbChargingPanic, aPanic);
+    }
+
+void CUsbBatteryChargingPlugin::UsbServiceStateChange(TInt /*aLastError*/, TUsbServiceState /*aOldState*/, TUsbServiceState /*aNewState*/)
+    {
+    // not used
+    }
+
+void CUsbBatteryChargingPlugin::PushRecoverState(TUsbChargingPluginState aRecoverState)
+    {
+    LOG_FUNC
+
+    if((aRecoverState == EPluginStateIdle)||
+       (aRecoverState == EPluginStateIdleNegotiated) ||
+       (aRecoverState == EPluginStateBEndedCableNotPresent) ||
+       (aRecoverState == EPluginStateNoValidCurrent))
+        {
+        iPluginStateToRecovery = aRecoverState;
+        }
+    }
+
+TUsbChargingPluginState CUsbBatteryChargingPlugin::PopRecoverState()
+    {
+    LOG_FUNC
+    
+    SetState(iPluginStateToRecovery);
+    
+    iPluginStateToRecovery = EPluginStateIdle;
+    
+    return iPluginStateToRecovery;
+    }
+
+TUsbChargingPluginState CUsbBatteryChargingPlugin::SetState(TUsbChargingPluginState aState)
+    {
+    LOG_FUNC
+
+    switch (aState)
+        {
+        case EPluginStateIdle:
+            {
+            ResetPlugin();
+            iCurrentState = iPluginStates[aState];
+            }
+            break;
+        case EPluginStateCurrentNegotiating:
+        case EPluginStateCharging:
+        case EPluginStateNoValidCurrent:
+        case EPluginStateIdleNegotiated:
+        case EPluginStateUserDisabled:
+        case EPluginStateBEndedCableNotPresent:
+            {
+            iPluginState = aState;
+            iCurrentState = iPluginStates[aState];
+            }
+            break;
+        default:
+            // Should never happen ...
+            iPluginState = EPluginStateIdle;
+            iCurrentState = iPluginStates[EPluginStateIdle];
+    
+            LOGTEXT2(_L8(">>CUsbBatteryChargingPlugin::SetState: Invalid new state: aState = %d"), aState);
+            
+            Panic(EUsbBatteryChargingPanicUnexpectedPluginState);
+        }
+    iPluginState = aState;
+    
+    LOGTEXT2(_L8(">>CUsbBatteryChargingPlugin::SetState, New state: aState = %d"), aState);
+    
+    return iPluginState;
+    }
+
+void CUsbBatteryChargingPlugin::NegotiateChargingCurrent()
+    {
+    LOG_FUNC
+
+    LOGTEXT2(_L8(">>CUsbBatteryChargingPlugin::StartNegotiation,  iDeviceState = %d"), iDeviceState);
+    TRAPD(result, NegotiateNextCurrentValueL());
+    if(result == KErrNone)
+        {
+        SetState(EPluginStateCurrentNegotiating);
+        }
+    else
+        {
+        LOGTEXT2(_L8("Negotiation call failed, iVBusState = 1: result = %d"), result);
+        }
+    }
+
+void CUsbBatteryChargingPlugin::UsbDeviceStateChange(TInt aLastError,
+        TUsbDeviceState aOldState, TUsbDeviceState aNewState)
+    {
+    LOG_FUNC
+    
+    iCurrentState->UsbDeviceStateChange(aLastError, aOldState, aNewState);
+    }
+
+void CUsbBatteryChargingPlugin::HandleRepositoryValueChangedL(const TUid& aRepository, TUint aId, TInt aVal)
+    {
+    LOG_FUNC    
+
+    iCurrentState->HandleRepositoryValueChangedL(aRepository, aId, aVal);
+    }
+
+void CUsbBatteryChargingPlugin::DeviceStateTimeout()
+    {
+    LOG_FUNC
+        
+    iCurrentState->DeviceStateTimeout();
+    }
+
+void CUsbBatteryChargingPlugin::NegotiateNextCurrentValueL()
+    {
+    LOG_FUNC
+
+    iDeviceStateTimer->Cancel();
+    TUint newCurrent = 0;
+
+    if ((iPluginState == EPluginStateIdle)  && iCurrentValues.Count() > 0)
+        {
+        // i.e. we haven't requested anything yet, and there are some current values to try
+        iCurrentIndexRequested  = 0;
+        newCurrent = iCurrentValues[iCurrentIndexRequested];        
+        }
+    else if (iPluginState == EPluginStateCurrentNegotiating && ( iCurrentIndexRequested + 1) < iCurrentValues.Count())
+        {
+        // there are more current values left to try
+        iCurrentIndexRequested++;
+        newCurrent = iCurrentValues[iCurrentIndexRequested];    
+        }
+    else if(iRequestedCurrentValue != 0)
+        {
+        // There isn't a 0ma round set from the Repository source -> 10208DD7.txt
+        // Just add it to make sure the device can be accepted by host    
+        newCurrent = 0;
+        }
+    else
+        {
+        // Warning 0001: If you go here, something wrong happend, check it.
+        __ASSERT_DEBUG(0,Panic(EUsbBatteryChargingPanicBadCharingCurrentNegotiation));
+        }
+    
+    RequestCurrentL(newCurrent);
+    iRequestedCurrentValue = newCurrent;
+    iPluginState = EPluginStateCurrentNegotiating;
+    }
+
+void CUsbBatteryChargingPlugin::ResetPlugin()
+    {
+    LOG_FUNC
+    
+    if((iPluginState != EPluginStateIdle))
+        {
+        iDeviceStateTimer->Cancel(); // doesn't matter if not running
+        iPluginState = EPluginStateIdle;
+        iPluginStateToRecovery = EPluginStateIdle;
+        LOGTEXT2(_L8("PluginState => EPluginStateIdle(%d)"),iPluginState);
+
+        iRequestedCurrentValue = 0;
+        iCurrentIndexRequested = 0;
+        iAvailableMilliAmps = 0;
+        SetNegotiatedCurrent(0);
+        TRAP_IGNORE(SetInitialConfigurationL());
+        }
+    }
+
+void CUsbBatteryChargingPlugin::RequestCurrentL(TUint aMilliAmps)
+    {
+    LOG_FUNC
+    
+    LOGTEXT2(_L8(">>CUsbBatteryChargingPlugin::RequestCurrent aMilliAmps = %d"), aMilliAmps);
+
+    if((EPluginStateCurrentNegotiating == iPluginState) && (iRequestedCurrentValue != aMilliAmps))
+        {
+        TInt configDescriptorSize = 0;
+        LEAVEIFERRORL(iLdd.GetConfigurationDescriptorSize(configDescriptorSize));
+        HBufC8* configDescriptor = HBufC8::NewLC(configDescriptorSize);
+        TPtr8 ptr(configDescriptor->Des());
+
+        LOGTEXT2(_L8("Getting Configuration Descriptor (size = %d)"),configDescriptorSize);
+        LEAVEIFERRORL(iLdd.GetConfigurationDescriptor(ptr));
+
+        // set bMaxPower field. One unit = 2mA, so need to halve aMilliAmps.
+        LOGTEXT3(_L8("Setting bMaxPower to %d mA ( = %d x 2mA units)"),aMilliAmps, (aMilliAmps >> 1));
+        TUint oldCurrentValue = ptr[KUsbBatteryChargingConfigurationDescriptorCurrentOffset] << 1;
+        LOGTEXT2(_L8("(old value was %d mA)"), oldCurrentValue);
+
+        //since the device will force reEnumeration if the value is odd
+        aMilliAmps = aMilliAmps & 0xFFFE;    
+    
+        // to negotiate a new current value, ReEnumerate is needed
+        LOGTEXT(_L8("Forcing ReEnumeration"));
+        ptr[KUsbBatteryChargingConfigurationDescriptorCurrentOffset] = (aMilliAmps >> 1);
+        LOGTEXT(_L8("Setting Updated Configuration Descriptor"));
+        LEAVEIFERRORL(iLdd.SetConfigurationDescriptor(ptr));
+        LOGTEXT(_L8("Triggering Re-enumeration"));
+        iDeviceReEnumerator->ReEnumerate();
+        
+        CleanupStack::PopAndDestroy(configDescriptor); // configDescriptor
+        }    
+    
+    // Always issue a timer as a watchdog to monitor the request progress
+    LOGTEXT2(_L8("Starting timer: %d"), User::NTickCount());
+    iDeviceStateTimer->Cancel();
+    iDeviceStateTimer->Start(TTimeIntervalMicroSeconds32(KUsbBatteryChargingCurrentRequestTimeout));
+    }
+
+void CUsbBatteryChargingPlugin::ReadCurrentRequestValuesL()
+    {
+    LOG_FUNC
+    
+    CRepository* repository = CRepository::NewLC(KUsbBatteryChargingCentralRepositoryUid);
+
+    TInt numberOfCurrents = 0;
+    repository->Get(KUsbBatteryChargingKeyNumberOfCurrentValues, numberOfCurrents);
+
+    TInt i = 0;
+    for (i=0; i<numberOfCurrents; i++)
+        {
+        TInt value;
+        repository->Get(KUsbBatteryChargingCurrentValuesOffset + i, value);
+        iCurrentValues.Append(static_cast<TUint>(value));
+        LOGTEXT3(_L8("CurrentValue %d = %dmA"),i,value);
+        }
+
+    CleanupStack::PopAndDestroy(repository);
+    }
+
+void CUsbBatteryChargingPlugin::StartCharging(TUint aMilliAmps)
+    {
+    LOG_FUNC
+    
+    LOGTEXT2(_L8(">>CUsbBatteryChargingPlugin::StartCharging aMilliAmps = %d"), aMilliAmps);
+    
+    // do licensee specific functionality (if any)
+    iLicenseeHooks->StartCharging(aMilliAmps);
+
+#ifdef __FLOG_ACTIVE
+    TInt err = RProperty::Set(KPropertyUidUsbBatteryChargingCategory,
+                KPropertyUidUsbBatteryChargingChargingCurrent,
+                            aMilliAmps);
+    LOGTEXT3(_L8("Set P&S current = %dmA - err = %d"),aMilliAmps,err);
+#else
+    (void)RProperty::Set(KPropertyUidUsbBatteryChargingCategory,
+                KPropertyUidUsbBatteryChargingChargingCurrent,
+                                aMilliAmps);
+#endif
+
+    SetState(EPluginStateCharging);
+    }
+
+void CUsbBatteryChargingPlugin::StopCharging()
+    {
+    LOG_FUNC
+    
+    // do licensee specific functionality (if any)
+    iLicenseeHooks->StopCharging();
+
+#ifdef __FLOG_ACTIVE
+    TInt err = RProperty::Set(KPropertyUidUsbBatteryChargingCategory,
+                                    KPropertyUidUsbBatteryChargingChargingCurrent,
+                                    0);
+    LOGTEXT2(_L8("Set P&S current = 0mA - err = %d"),err);
+#else
+    (void)RProperty::Set(KPropertyUidUsbBatteryChargingCategory,
+                                    KPropertyUidUsbBatteryChargingChargingCurrent,
+                                    0);
+#endif
+    }
+
+void CUsbBatteryChargingPlugin::SetNegotiatedCurrent(TUint aMilliAmps)
+    {
+    LOG_FUNC
+    
+    LOGTEXT2(_L8(">>CUsbBatteryChargingPlugin::SetNegotiatedCurrent aMilliAmps = %d"), aMilliAmps);
+
+    // Ignore errors - not much we can do if it fails
+#ifdef __FLOG_ACTIVE
+    TInt err = RProperty::Set(KPropertyUidUsbBatteryChargingCategory,
+                                    KPropertyUidUsbBatteryChargingAvailableCurrent,
+                                    aMilliAmps);
+    LOGTEXT3(_L8("Set P&S current = %dmA - err = %d"),aMilliAmps,err);
+#else
+    (void)RProperty::Set(KPropertyUidUsbBatteryChargingCategory,
+                                    KPropertyUidUsbBatteryChargingAvailableCurrent,
+                                    aMilliAmps);
+#endif
+    }
+
+
+#ifndef __FLOG_ACTIVE
+void CUsbBatteryChargingPlugin::LogStateText(TUsbDeviceState /*aState*/)
+    {
+    LOG_FUNC
+    }
+#else
+void CUsbBatteryChargingPlugin::LogStateText(TUsbDeviceState aState)
+    {
+    LOG_FUNC
+    
+    switch (aState)
+        {
+        case EUsbDeviceStateUndefined:
+            LOGTEXT(_L8(" ***** UNDEFINED *****"));
+            break;
+        case EUsbDeviceStateDefault:
+            LOGTEXT(_L8(" ***** DEFAULT *****"));
+            break;
+        case EUsbDeviceStateAttached:
+            LOGTEXT(_L8(" ***** ATTACHED *****"));
+            break;
+        case EUsbDeviceStatePowered:
+            LOGTEXT(_L8(" ***** POWERED *****"));
+            break;
+        case EUsbDeviceStateConfigured:
+            LOGTEXT(_L8(" ***** CONFIGURED *****"));
+            break;
+        case EUsbDeviceStateAddress:
+            LOGTEXT(_L8(" ***** ADDRESS *****"));
+            break;
+        case EUsbDeviceStateSuspended:
+            LOGTEXT(_L8(" ***** SUSPENDED *****"));
+            break;
+        default:
+            break;
+        }
+    }
+#endif
+
+void CUsbBatteryChargingPlugin::MpsoVBusStateChanged(TInt aNewState)
+    {
+    LOG_FUNC
+    
+    iCurrentState->MpsoVBusStateChanged(aNewState);
+    }
+
+
+// For host OTG enabled charging plug-in
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+void CUsbBatteryChargingPlugin::MpsoIdPinStateChanged(TInt aValue)
+    {
+    LOG_FUNC
+    
+    iCurrentState->MpsoIdPinStateChanged(aValue);
+    }
+
+void CUsbBatteryChargingPlugin::MpsoOtgStateChangedL(TUsbOtgState aNewState)
+    {
+    LOG_FUNC
+
+    iCurrentState->MpsoOtgStateChangedL(aNewState);
+    }
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/src/CUsbBatteryChargingPluginMain.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+/*
+* 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 "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
+*/
+
+#include <ecom/implementationproxy.h>
+#include "CUsbBatteryChargingPlugin.h"
+
+// Define the private interface UIDs
+const TImplementationProxy ImplementationTable[] =
+	{										
+	IMPLEMENTATION_PROXY_ENTRY(0x10208DD8, CUsbBatteryChargingPlugin::NewL),
+	};
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+	{
+	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+
+	return ImplementationTable;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/src/chargingstates.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,521 @@
+/*
+* Copyright (c) 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
+*/
+
+#include "chargingstates.h"
+#include <usb/usblogger.h>
+#include "reenumerator.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBCHARGEStates");
+#endif
+
+// Charging plugin base state
+
+// Empty virtual function implement to give a base of each state class. 
+// A concrete state class can overlap them according to actual demand.
+void TUsbBatteryChargingPluginStateBase::UsbServiceStateChange(TInt aLastError,
+    TUsbServiceState aOldState, TUsbServiceState aNewState)
+    {
+    LOG_FUNC
+    
+    (void)aLastError;
+    (void)aOldState;
+    (void)aNewState;
+    
+    // Not use
+    }
+
+void TUsbBatteryChargingPluginStateBase::UsbDeviceStateChange(TInt aLastError,
+    TUsbDeviceState aOldState, TUsbDeviceState aNewState)
+    {
+    LOG_FUNC
+    
+    (void)aLastError;
+    (void)aOldState;
+    (void)aNewState;
+    }
+
+void TUsbBatteryChargingPluginStateBase::HandleRepositoryValueChangedL(
+    const TUid& aRepository, TUint aId, TInt aVal)
+    {
+    LOG_FUNC
+    
+    LOGTEXT4(_L8(">>TUsbBatteryChargingPluginStateBase::HandleRepositoryValueChangedL aRepository = 0x%08x, aId = %d, aVal = %d"), aRepository, aId, aVal);
+    LOGTEXT3(_L8("Plugin State = %d, Device State = %d"), iParent.iPluginState, iParent.iDeviceState);
+    
+    if ((aRepository == KUsbBatteryChargingCentralRepositoryUid) &&
+            (aId == KUsbBatteryChargingKeyEnabledUserSetting))
+        {
+        iParent.iUserSetting = (TUsbBatteryChargingUserSetting)aVal;
+
+        if (iParent.iUserSetting == EUsbBatteryChargingUserSettingDisabled)
+            {
+            if(iParent.iPluginState == EPluginStateCharging)
+                {
+                iParent.StopCharging();
+                
+                // Push EPluginStateIdleNegotiated state to recover state
+                iParent.PushRecoverState(EPluginStateIdleNegotiated);
+                }
+            else
+                {
+                // Push current state to recover state
+                iParent.PushRecoverState(iParent.iPluginState);
+                }
+            
+            iParent.SetState(EPluginStateUserDisabled);
+            }
+        }
+    }
+    
+void TUsbBatteryChargingPluginStateBase::DeviceStateTimeout()
+    {
+    LOG_FUNC
+    LOGTEXT4(_L8("Time: %d Plugin State = %d, Device State = %d"), User::NTickCount(), iParent.iPluginState, iParent.iDeviceState);
+    
+    iParent.iDeviceReEnumerator->Cancel(); // cancel re-enumeration AO
+    
+    if(iParent.iUserSetting) // User allow charging already and not in negotiating process...
+        {
+        // Should not happen !!! Otherwise, something wrong!!!
+        iParent.SetState(EPluginStateIdle);
+        }
+    }
+
+// For host OTG enabled charging plug-in
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+void TUsbBatteryChargingPluginStateBase::MpsoIdPinStateChanged(TInt aValue)
+    {
+    LOG_FUNC
+    
+    LOGTEXT2(_L8("IdPinState changed => %d"), aValue);
+    
+    // Disable charging here when IdPin is present
+    // When IdPin disappears (i.e. the phone becomes B-Device), all necessary step are performed 
+    // in UsbDeviceStateChange() method
+
+    iParent.iIdPinState = aValue;
+    
+    // For all other states besides EPluginStateUserDisabled
+    switch(aValue)
+        {
+        case EUsbBatteryChargingIdPinARole:
+            if (iParent.iPluginState == EPluginStateCharging)
+                {
+                iParent.StopCharging();
+                }
+
+            TRAP_IGNORE(iParent.SetInitialConfigurationL());
+            iParent.SetState(EPluginStateBEndedCableNotPresent);
+            
+            return;
+
+        case EUsbBatteryChargingIdPinBRole:
+            iParent.SetState(EPluginStateIdle);
+            break;
+
+        default:
+            if (iParent.iPluginState == EPluginStateCharging)
+                {
+                iParent.StopCharging();
+                }     
+            iParent.SetState(EPluginStateIdle);
+            break;
+        }
+    }
+
+void TUsbBatteryChargingPluginStateBase::MpsoOtgStateChangedL(TUsbOtgState aNewState)
+    {
+    LOG_FUNC
+    
+    iParent.iOtgState = aNewState;
+    
+    // Not use currently
+    }
+#endif
+
+void TUsbBatteryChargingPluginStateBase::MpsoVBusStateChanged(TInt aNewState)
+    {
+    LOG_FUNC
+    
+    if (aNewState == iParent.iVBusState)
+        {
+        LOGTEXT2(_L8("Receive VBus State Change notification without any state change: aNewState = %d"), aNewState);
+        return;//should not happen??
+        }
+
+    LOGTEXT3(_L8("VBusState changed from %d to %d"), iParent.iVBusState, aNewState);
+    
+    iParent.iVBusState = aNewState;
+    if (aNewState == 0) // VBus drop down - we have disconnected from host
+        {
+        if (iParent.iPluginState == EPluginStateCharging)
+            {
+            iParent.StopCharging();
+            }
+        iParent.SetState(EPluginStateIdle);
+        }
+    
+    // The handling of VBus on will be down in DeviceStateChanged implicitly
+    }
+
+
+TUsbBatteryChargingPluginStateBase::TUsbBatteryChargingPluginStateBase (
+        CUsbBatteryChargingPlugin& aParentStateMachine ): 
+        iParent(aParentStateMachine)
+    {
+    LOG_FUNC
+    }
+
+        
+// Charging plugin idle state
+
+TUsbBatteryChargingPluginStateIdle::TUsbBatteryChargingPluginStateIdle (
+        CUsbBatteryChargingPlugin& aParentStateMachine ) :
+    TUsbBatteryChargingPluginStateBase(aParentStateMachine)
+    {
+    LOG_FUNC
+    };
+
+void TUsbBatteryChargingPluginStateIdle::UsbDeviceStateChange(
+        TInt aLastError, TUsbDeviceState aOldState, TUsbDeviceState aNewState)
+    {
+    LOG_FUNC
+
+    LOGTEXT4(_L8(">>TUsbBatteryChargingPluginStateIdle::UsbDeviceStateChange LastError = %d, aOldState = %d, aNewState = %d"), aLastError, aOldState, aNewState);
+    (void)aLastError;
+    (void)aOldState;
+    iParent.iDeviceState = aNewState;
+    iParent.LogStateText(aNewState);
+    
+    switch (iParent.iDeviceState)
+        {
+        case EUsbDeviceStateAddress:
+            {
+            if (iParent.iUserSetting)
+                {
+                if (iParent.IsUsbChargingPossible())
+                    {
+                    iParent.NegotiateChargingCurrent();
+                    }
+                }
+            else
+                {
+                iParent.SetState(EPluginStateUserDisabled);
+                }
+            }
+            break;
+        }
+    }
+    
+    
+// Charging plugin current negotiating state
+
+TUsbBatteryChargingPluginStateCurrentNegotiating::TUsbBatteryChargingPluginStateCurrentNegotiating (
+        CUsbBatteryChargingPlugin& aParentStateMachine ) :
+    TUsbBatteryChargingPluginStateBase(aParentStateMachine)
+    {
+    LOG_FUNC
+    };
+    
+void TUsbBatteryChargingPluginStateCurrentNegotiating::UsbDeviceStateChange(
+        TInt aLastError, TUsbDeviceState aOldState, TUsbDeviceState aNewState)
+    {
+    LOG_FUNC
+
+    LOGTEXT4(_L8(">>TUsbBatteryChargingPluginStateCurrentNegotiating::UsbDeviceStateChange LastError = %d, aOldState = %d, aNewState = %d"), aLastError, aOldState, aNewState);
+    (void)aLastError;
+    (void)aOldState;
+    iParent.iDeviceState = aNewState;
+    iParent.LogStateText(aNewState);
+    
+    switch(iParent.iDeviceState)
+        {
+        case EUsbDeviceStateConfigured:
+            if (iParent.IsUsbChargingPossible())
+                {
+                iParent.iDeviceStateTimer->Cancel();
+                
+                LOGTEXT2(_L8("iParent.iAvailableMilliAmps = %d"),iParent.iAvailableMilliAmps);
+                iParent.iAvailableMilliAmps = iParent.iRequestedCurrentValue;
+                
+                if(0 != iParent.iRequestedCurrentValue)
+                    {
+                    // A non-zero value was accepted by host, charging 
+                    // can be performed now.
+                    iParent.StartCharging(iParent.iAvailableMilliAmps);                     
+                    LOGTEXT2(_L8("PluginState => EPluginStateCharging(%d)"),iParent.iPluginState);
+                    iParent.SetNegotiatedCurrent(iParent.iAvailableMilliAmps);
+                    }
+                else
+                    {
+                    // Host can only accept 0 charging current
+                    // No way to do charging
+                    iParent.SetState(EPluginStateNoValidCurrent);
+                    LOGTEXT2(_L8("No more current value to try, iPluginState turned to %d"), iParent.iPluginState);
+                    }
+                }
+            
+            break;
+        
+        // If no configured received, there must be a timeout
+        // caught by the iDeviceStateTimer, and it will try next value or send state to  
+        // EPluginStateNoValidCurrent, so don't worry that we omit something important :-)
+            
+            
+        default:
+            break;
+        }
+    }
+
+void TUsbBatteryChargingPluginStateCurrentNegotiating::DeviceStateTimeout()
+    {
+    LOG_FUNC
+    LOGTEXT4(_L8("Time: %d Plugin State = %d, Device State = %d"), User::NTickCount(), iParent.iPluginState, iParent.iDeviceState);
+    
+    iParent.iDeviceReEnumerator->Cancel(); // cancel re-enumeration AO
+    
+    if(iParent.iRequestedCurrentValue != 0)
+        {
+        // If there are more value to try ...
+        iParent.NegotiateChargingCurrent();
+        }
+    else
+        {
+        // The Host doesn't accept 0ma power request?
+        // Assume it will never happens.
+        iParent.SetState(EPluginStateNoValidCurrent);
+        }
+    }
+
+
+// Charging plugin charing state
+
+    
+TUsbBatteryChargingPluginStateCharging::TUsbBatteryChargingPluginStateCharging (
+        CUsbBatteryChargingPlugin& aParentStateMachine ) :
+    TUsbBatteryChargingPluginStateBase(aParentStateMachine)
+    {
+    LOG_FUNC
+    }
+
+void TUsbBatteryChargingPluginStateCharging::UsbDeviceStateChange(
+        TInt aLastError, TUsbDeviceState aOldState, TUsbDeviceState aNewState)
+    {
+    LOG_FUNC
+
+    LOGTEXT4(_L8(">>TUsbBatteryChargingPluginStateCharging::UsbDeviceStateChange LastError = %d, aOldState = %d, aNewState = %d"), aLastError, aOldState, aNewState);
+    (void)aLastError;
+    (void)aOldState;
+    iParent.iDeviceState = aNewState;
+    iParent.LogStateText(aNewState);
+
+    switch(iParent.iDeviceState)
+        {
+        case EUsbDeviceStateConfigured:
+            break; // I think this can not happen at all but in case ...
+            
+        case EUsbDeviceStateAttached:
+        case EUsbDeviceStatePowered:
+        case EUsbDeviceStateDefault:
+        case EUsbDeviceStateAddress:
+        case EUsbDeviceStateSuspended:
+            {
+            // wait until configured
+            iParent.StopCharging();
+            iParent.SetState(EPluginStateIdleNegotiated);
+            }
+            break;
+                            
+        default:
+            break;
+        }
+    }
+
+// Charging plugin negotiated fail state
+    
+    
+TUsbBatteryChargingPluginStateNoValidCurrent::TUsbBatteryChargingPluginStateNoValidCurrent (
+        CUsbBatteryChargingPlugin& aParentStateMachine ) :
+    TUsbBatteryChargingPluginStateBase(aParentStateMachine)
+    {
+    LOG_FUNC
+    };
+
+    
+// Charging plugin idle negotiated state
+
+TUsbBatteryChargingPluginStateIdleNegotiated::TUsbBatteryChargingPluginStateIdleNegotiated (
+        CUsbBatteryChargingPlugin& aParentStateMachine ) :
+    TUsbBatteryChargingPluginStateBase(aParentStateMachine)
+    {
+    LOG_FUNC
+    };
+
+void TUsbBatteryChargingPluginStateIdleNegotiated::UsbDeviceStateChange(
+        TInt aLastError, TUsbDeviceState aOldState, TUsbDeviceState aNewState)
+    {
+    LOG_FUNC
+
+    LOGTEXT4(_L8(">>TUsbBatteryChargingPluginStateIdleNegotiated::UsbDeviceStateChange LastError = %d, aOldState = %d, aNewState = %d"), aLastError, aOldState, aNewState);
+    (void)aLastError;
+    (void)aOldState;
+    iParent.iDeviceState = aNewState;
+    iParent.LogStateText(aNewState);
+
+    switch(iParent.iDeviceState)
+        {
+        case EUsbDeviceStateConfigured:
+            {
+            // wait until configured
+            if (iParent.IsUsbChargingPossible())
+            	{
+                iParent.StartCharging(iParent.iAvailableMilliAmps);
+                }
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
+ 
+// Charging plugin user disabled state
+    
+TUsbBatteryChargingPluginStateUserDisabled::TUsbBatteryChargingPluginStateUserDisabled (
+        CUsbBatteryChargingPlugin& aParentStateMachine ) :
+    TUsbBatteryChargingPluginStateBase(aParentStateMachine)
+    {
+    LOG_FUNC
+    };
+
+
+void TUsbBatteryChargingPluginStateUserDisabled::UsbDeviceStateChange(
+        TInt aLastError, TUsbDeviceState aOldState, TUsbDeviceState aNewState)
+    {
+    LOG_FUNC
+
+    LOGTEXT4(_L8(">>TUsbBatteryChargingPluginStateUserDisabled::UsbDeviceStateChange LastError = %d, aOldState = %d, aNewState = %d"), aLastError, aOldState, aNewState);
+    (void)aLastError;
+    (void)aOldState;
+    iParent.iDeviceState = aNewState;
+    iParent.LogStateText(aNewState);
+    }
+
+void TUsbBatteryChargingPluginStateUserDisabled::HandleRepositoryValueChangedL(
+    const TUid& aRepository, TUint aId, TInt aVal)
+    {
+    LOG_FUNC
+    
+    LOGTEXT4(_L8(">>TUsbBatteryChargingPluginStateUserDisabled::HandleRepositoryValueChangedL aRepository = 0x%08x, aId = %d, aVal = %d"), aRepository, aId, aVal);
+    LOGTEXT3(_L8("Plugin State = %d, Device State = %d"), iParent.iPluginState, iParent.iDeviceState);
+    
+    if ((aRepository == KUsbBatteryChargingCentralRepositoryUid) &&
+            (aId == KUsbBatteryChargingKeyEnabledUserSetting))
+        {
+        iParent.iUserSetting = (TUsbBatteryChargingUserSetting)aVal;
+
+        if (iParent.iUserSetting == EUsbBatteryChargingUserSettingEnabled)
+            {
+            // EPluginStateUserDisabled must be the current state
+            iParent.PopRecoverState();
+            if ((iParent.iPluginState == EPluginStateIdleNegotiated)
+                    && (iParent.iDeviceState == EUsbDeviceStateConfigured))
+                {
+                iParent.StartCharging(iParent.iAvailableMilliAmps); // Go to charing state implicitly
+                }
+            LOGTEXT2(_L8("PluginState => %d"), iParent.iPluginState);
+            }
+        }
+    }
+
+// For host OTG enabled charging plug-in
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+void TUsbBatteryChargingPluginStateUserDisabled::MpsoIdPinStateChanged(TInt aValue)
+    {
+    LOG_FUNC
+    
+    LOGTEXT2(_L8("IdPinState changed => %d"), aValue);
+    
+    // Disable charging here when IdPin is present
+    // When IdPin disappears (i.e. the phone becomes B-Device), all necessary step are performed 
+    // in UsbDeviceStateChange() method
+
+    iParent.iIdPinState = aValue;
+    
+    switch(aValue)
+        {
+        case EUsbBatteryChargingIdPinARole:
+            TRAP_IGNORE(iParent.SetInitialConfigurationL());
+            iParent.PushRecoverState(EPluginStateBEndedCableNotPresent);
+            
+            return;
+
+        case EUsbBatteryChargingIdPinBRole:
+            iParent.PushRecoverState(EPluginStateIdle);
+            break;
+
+        default:     
+            iParent.SetState(EPluginStateIdle);
+            break;
+        }
+    }
+
+#endif     
+ 
+void TUsbBatteryChargingPluginStateUserDisabled::MpsoVBusStateChanged(TInt aNewState)
+    {
+    LOG_FUNC
+    
+    if (aNewState == iParent.iVBusState)
+        {
+        LOGTEXT2(_L8("Receive VBus State Change notification without any state change: aNewState = %d"), aNewState);
+        return;
+        }
+
+    LOGTEXT3(_L8("VBusState changed from %d to %d"), iParent.iVBusState, aNewState);
+    
+    iParent.iVBusState = aNewState;
+    if (aNewState == 0) // VBus drop down - we have disconnected from host
+        {
+        iParent.iRequestedCurrentValue = 0;
+        iParent.iCurrentIndexRequested = 0;
+        iParent.iAvailableMilliAmps = 0;
+        
+        iParent.iPluginStateToRecovery = EPluginStateIdle;
+        }
+    
+    // The handling of VBus on will be down in DeviceStateChanged implicitly
+    }
+
+
+// Charging plugin A-role state
+    
+TUsbBatteryChargingPluginStateBEndedCableNotPresent::TUsbBatteryChargingPluginStateBEndedCableNotPresent (
+        CUsbBatteryChargingPlugin& aParentStateMachine ) :
+    TUsbBatteryChargingPluginStateBase(aParentStateMachine)
+    {
+    LOG_FUNC
+    };
+    
+    
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/src/devicestatetimer.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,63 @@
+/*
+* 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 "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
+*/
+
+#include "devicestatetimer.h"
+
+CUsbChargingDeviceStateTimer* CUsbChargingDeviceStateTimer::NewL(MUsbChargingDeviceStateTimerObserver& aObserver)
+	{
+	CUsbChargingDeviceStateTimer* self = new(ELeave) CUsbChargingDeviceStateTimer(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CUsbChargingDeviceStateTimer::~CUsbChargingDeviceStateTimer()
+	{
+	Cancel();
+	}
+
+void CUsbChargingDeviceStateTimer::Start(TTimeIntervalMicroSeconds32 aTime)
+	{
+	After(aTime);
+	}
+
+void CUsbChargingDeviceStateTimer::ConstructL()
+	{
+	CTimer::ConstructL();
+	CActiveScheduler::Add(this);
+	}
+
+CUsbChargingDeviceStateTimer::CUsbChargingDeviceStateTimer(MUsbChargingDeviceStateTimerObserver& aObserver)
+: CTimer(EPriorityStandard), iObserver(aObserver)
+	{
+	}
+
+void CUsbChargingDeviceStateTimer::RunL()
+	{
+	iObserver.DeviceStateTimeout();
+	}
+
+void CUsbChargingDeviceStateTimer::DoCancel()
+	{
+	CTimer::DoCancel();
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/src/idpinwatcher.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,86 @@
+/*
+* 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 "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:
+* Talks directly to the USB Logical Device Driver (LDD) and 
+* watches any state changes
+*
+*/
+
+/**
+ @file
+*/
+
+#include "idpinwatcher.h"
+#include <usb/usbshared.h>
+
+CIdPinWatcher* CIdPinWatcher::NewL(MOtgPropertiesObserver* aObserver)
+	{
+	CIdPinWatcher* self = new(ELeave) CIdPinWatcher(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CIdPinWatcher::~CIdPinWatcher()
+	{
+	Cancel();
+	iIdPinProp.Close();
+	}
+
+CIdPinWatcher::CIdPinWatcher(MOtgPropertiesObserver* aObserver)
+	: CActive(EPriorityStandard)
+	, iObserver(aObserver), iIdPinValue(EFalse)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CIdPinWatcher::ConstructL()
+	{
+	User::LeaveIfError(iIdPinProp.Attach(KUidUsbManCategory, KUsbOtgIdPinPresentProperty));
+	iIdPinProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt err = iIdPinProp.Get(iIdPinValue);
+	if (KErrNone != err)
+		{
+		iIdPinValue = EFalse;
+		}
+	}
+
+void CIdPinWatcher::DoCancel()
+	{
+	iIdPinProp.Cancel();
+	}
+
+void CIdPinWatcher::RunL()
+	{
+	iIdPinProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt err = iIdPinProp.Get(iIdPinValue);
+	if (KErrNone == err)
+		{
+		iObserver->MpsoIdPinStateChanged(iIdPinValue);
+		}
+	else
+		{
+		iIdPinValue = EFalse;
+		}
+	}
+
+TInt CIdPinWatcher::IdPinValue() const
+	{
+	return iIdPinValue;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/src/otgstatewatcher.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,83 @@
+/*
+* 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 "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:
+* Talks directly to the USB Logical Device Driver (LDD) and 
+* watches any state changes
+*
+*/
+
+/**
+ @file
+*/
+
+#include "otgstatewatcher.h"
+
+COtgStateWatcher* COtgStateWatcher::NewL(MOtgPropertiesObserver* aObserver)
+	{
+	COtgStateWatcher* self = new(ELeave) COtgStateWatcher(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+COtgStateWatcher::~COtgStateWatcher()
+	{
+	Cancel();
+	iOtgStateProp.Close();
+	}
+
+COtgStateWatcher::COtgStateWatcher(MOtgPropertiesObserver* aObserver)
+	: CActive(EPriorityStandard)
+	, iObserver(aObserver)
+	, iOtgState(EUsbOtgStateReset)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void COtgStateWatcher::ConstructL()
+	{
+	User::LeaveIfError(iOtgStateProp.Attach(KUidUsbManCategory, KUsbOtgStateProperty));
+	iOtgStateProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt err = iOtgStateProp.Get((TInt&)iOtgState);
+	if (KErrNone != err)
+		{
+		iOtgState = EUsbOtgStateBPeripheral;
+		}
+	}
+
+void COtgStateWatcher::DoCancel()
+	{
+	iOtgStateProp.Cancel();
+	}
+
+void COtgStateWatcher::RunL()
+	{
+	iOtgStateProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt err = iOtgStateProp.Get((TInt&)iOtgState);
+	if (KErrNone != err)
+		{
+		iOtgState = EUsbOtgStateBPeripheral;
+		}
+	iObserver->MpsoOtgStateChangedL(iOtgState);
+	}
+
+TUsbOtgState COtgStateWatcher::OtgState() const
+	{
+	return iOtgState;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/src/reenumerator.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,59 @@
+/*
+* 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 "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
+*/
+
+#include "reenumerator.h"
+
+CUsbChargingReEnumerator* CUsbChargingReEnumerator::NewL(RDevUsbcClient& aLdd)
+	{
+	CUsbChargingReEnumerator* self = new (ELeave) CUsbChargingReEnumerator(aLdd);
+	return self;
+	}
+
+CUsbChargingReEnumerator::~CUsbChargingReEnumerator()
+	{
+	Cancel();
+	}
+
+void CUsbChargingReEnumerator::ReEnumerate()
+	{
+	if (IsActive())
+		{
+		Cancel();
+		}
+	iLdd.ReEnumerate(iStatus);
+	SetActive();
+	}
+
+CUsbChargingReEnumerator::CUsbChargingReEnumerator(RDevUsbcClient& aLdd)
+: CActive(EPriorityStandard), iLdd(aLdd)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUsbChargingReEnumerator::RunL()
+	{
+	}
+
+void CUsbChargingReEnumerator::DoCancel()
+	{
+	iLdd.ReEnumerateCancel();
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/src/repositorynotifier.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,91 @@
+/*
+* 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 "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
+*/
+
+#include "repositorynotifier.h"
+#include <centralrepository.h>
+
+CUsbChargingRepositoryNotifier::CUsbChargingRepositoryNotifier(MUsbChargingRepositoryObserver& aObserver,const TUid& aRepository, TUint aId)
+: CActive(EPriorityNormal), iObserver(aObserver), iRepositoryUid(aRepository), iId(aId)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUsbChargingRepositoryNotifier::ConstructL()
+	{
+	iRepository = CRepository::NewL(iRepositoryUid);
+	TInt state = KErrUnknown;
+	User::LeaveIfError(iRepository->Get(iId, state));
+	// Update observers with current value if valid
+	if(state >= KErrNone)
+		{
+		iObserver.HandleRepositoryValueChangedL(iRepositoryUid, iId, state);
+		}
+	Notify();
+	}
+
+void CUsbChargingRepositoryNotifier::DoCancel()
+	{
+	// If the call returns an error value, there's nothing meaninful we can do
+	// (void) it to avoid messages from Lint
+	(void) iRepository->NotifyCancel(iId);
+	}
+
+CUsbChargingRepositoryNotifier::~CUsbChargingRepositoryNotifier()
+	{
+	Cancel();
+	delete iRepository;
+	}
+
+void CUsbChargingRepositoryNotifier::Notify()
+	{
+	iStatus = KRequestPending;
+	TInt err = iRepository->NotifyRequest(iId, iStatus);
+	if(err == KErrNone)
+		{
+		SetActive();
+		}
+	}
+
+void CUsbChargingRepositoryNotifier::RunL()
+	{
+	TInt state;
+	TInt err = iRepository->Get(iId, state);
+	if(err ==KErrNone)
+		{
+		iObserver.HandleRepositoryValueChangedL(iRepositoryUid, iId, state);
+		}
+	Notify();
+	}
+
+TInt CUsbChargingRepositoryNotifier::RunError(TInt /*aError*/)
+	{
+	return KErrNone;
+	}
+
+CUsbChargingRepositoryNotifier* CUsbChargingRepositoryNotifier::NewL(MUsbChargingRepositoryObserver& aObserver,const TUid& aRepository, TUint aId)
+	{
+	CUsbChargingRepositoryNotifier* self = new (ELeave) CUsbChargingRepositoryNotifier(aObserver,aRepository,aId);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/chargingplugin/src/vbuswatcher.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,95 @@
+/*
+* 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 "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:
+* Talks directly to the USB Logical Device Driver (LDD) and 
+* watches any state changes
+*
+*/
+
+/**
+ @file
+*/
+
+#include "vbuswatcher.h"
+#include <usb/usbshared.h>
+
+CVBusWatcher* CVBusWatcher::NewL(MOtgPropertiesObserver* aObserver)
+	{
+	CVBusWatcher* self = new(ELeave) CVBusWatcher(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CVBusWatcher::~CVBusWatcher()
+	{
+	Cancel();
+	iVBusProp.Close();
+	}
+
+CVBusWatcher::CVBusWatcher(MOtgPropertiesObserver* aObserver)
+	: CActive(EPriorityStandard)
+	, iObserver(aObserver), iVBusState(EFalse)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CVBusWatcher::ConstructL()
+	{
+	User::LeaveIfError(iVBusProp.Attach(KUidUsbManCategory, KUsbOtgVBusPoweredProperty));
+	iVBusProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt err = iVBusProp.Get(iVBusState);
+	if (KErrNone != err)
+		{
+#ifndef __WINS__
+		iVBusState = EFalse;
+#else
+		iVBusState = ETrue;
+#endif
+		}
+	}
+
+void CVBusWatcher::DoCancel()
+	{
+	iVBusProp.Cancel();
+	}
+
+void CVBusWatcher::RunL()
+	{
+	iVBusProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt err = iVBusProp.Get(iVBusState);
+	if (KErrNone == err)
+		{
+		iObserver->MpsoVBusStateChanged(iVBusState);
+		}
+	else
+		{
+#ifndef __WINS__
+		iVBusState = EFalse;
+#else
+		iVBusState = ETrue;
+#endif
+		iObserver->MpsoVBusStateChanged(iVBusState);
+		}
+	}
+
+TInt CVBusWatcher::VBusState() const
+	{
+	return iVBusState;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/client/BWINS/USBMANU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,52 @@
+EXPORTS
+	??0RUsb@@QAE@XZ @ 1 NONAME ; public: __thiscall RUsb::RUsb(void)
+	??1RUsb@@QAE@XZ @ 2 NONAME ; public: __thiscall RUsb::~RUsb(void)
+	?panic@@YAXXZ @ 3 NONAME ; public: static int __cdecl UsbMan::Run(class UsbMan::TSignal &)
+	?Stop@RUsb@@QAEXXZ @ 4 NONAME ; public: void __thiscall RUsb::Stop(void)
+	?Version@RUsb@@QBE?AVTVersion@@XZ @ 5 NONAME ; public: class TVersion  __thiscall RUsb::Version(void)const 
+	?Connect@RUsb@@QAEHXZ @ 6 NONAME ; public: int __thiscall RUsb::Connect(void)
+	?Start@RUsb@@QAEXAAVTRequestStatus@@@Z @ 7 NONAME ; public: void __thiscall RUsb::Start(class TRequestStatus &)
+	?StateNotification@RUsb@@QAEXIAAW4TUsbDeviceState@@AAVTRequestStatus@@@Z @ 8 NONAME ; public: void __thiscall RUsb::StateNotification(unsigned int,enum TUsbDeviceState &,class TRequestStatus &)
+	?GetCurrentState@RUsb@@QAEHAAW4TUsbServiceState@@@Z @ 9 NONAME ; public: int __thiscall RUsb::GetCurrentState(enum TUsbServiceState &)
+	?StartCancel@RUsb@@QAEXXZ @ 10 NONAME ; public: void __thiscall RUsb::StartCancel(void)
+	?StateNotificationCancel@RUsb@@QAEXXZ @ 11 NONAME ; public: void __thiscall RUsb::StateNotificationCancel(void)
+	?GetDeviceState@RUsb@@QAEHAAW4TUsbDeviceState@@@Z @ 12 NONAME ; public: int __thiscall RUsb::GetDeviceState(enum TUsbDeviceState &)
+	?ServiceStateNotification@RUsb@@QAEXAAW4TUsbServiceState@@AAVTRequestStatus@@@Z @ 13 NONAME ; public: void __thiscall RUsb::ServiceStateNotification(enum TUsbServiceState &,class TRequestStatus &)
+	?ServiceStateNotificationCancel@RUsb@@QAEXXZ @ 14 NONAME ; public: void __thiscall RUsb::ServiceStateNotificationCancel(void)
+	?Stop@RUsb@@QAEXAAVTRequestStatus@@@Z @ 15 NONAME ; public: void __thiscall RUsb::Stop(class TRequestStatus &)
+	?StopCancel@RUsb@@QAEXXZ @ 16 NONAME ; public: void __thiscall RUsb::StopCancel(void)
+	?DeviceStateNotification@RUsb@@QAEXIAAW4TUsbDeviceState@@AAVTRequestStatus@@@Z @ 17 NONAME ; public: void __thiscall RUsb::DeviceStateNotification(unsigned int,enum TUsbDeviceState &,class TRequestStatus &)
+	?DeviceStateNotificationCancel@RUsb@@QAEXXZ @ 18 NONAME ; public: void __thiscall RUsb::DeviceStateNotificationCancel(void)
+	?GetServiceState@RUsb@@QAEHAAW4TUsbServiceState@@@Z @ 19 NONAME ; public: int __thiscall RUsb::GetServiceState(enum TUsbServiceState &)
+	?__DbgCheckHeap@RUsb@@QAEHH@Z @ 20 NONAME ; public: int __thiscall RUsb::__DbgCheckHeap(int)
+	?__DbgFailNext@RUsb@@QAEHH@Z @ 21 NONAME ; public: int __thiscall RUsb::__DbgFailNext(int)
+	?__DbgMarkEnd@RUsb@@QAEHH@Z @ 22 NONAME ; public: int __thiscall RUsb::__DbgMarkEnd(int)
+	?__DbgMarkHeap@RUsb@@QAEHXZ @ 23 NONAME ; public: int __thiscall RUsb::__DbgMarkHeap(void)
+	?CancelInterest@RUsb@@QAEHW4TUsbReqType@1@@Z @ 24 NONAME ; int RUsb::CancelInterest(enum RUsb::TUsbReqType)
+	?ClassSupported@RUsb@@QAEHHVTUid@@AAH@Z @ 25 NONAME ; int RUsb::ClassSupported(int, class TUid, int &)
+	?GetCurrentPersonalityId@RUsb@@QAEHAAH@Z @ 26 NONAME ; int RUsb::GetCurrentPersonalityId(int &)
+	?GetDescription@RUsb@@QAEHHAAPAVHBufC16@@@Z @ 27 NONAME ; int RUsb::GetDescription(int, class HBufC16 * &)
+	?GetPersonalityIds@RUsb@@QAEHAAV?$RArray@H@@@Z @ 28 NONAME ; int RUsb::GetPersonalityIds(class RArray<int> &)
+	?GetSupportedClasses@RUsb@@QAEHHAAV?$RArray@VTUid@@@@@Z @ 29 NONAME ; int RUsb::GetSupportedClasses(int, class RArray<class TUid> &)
+	?TryStart@RUsb@@QAEXHAAVTRequestStatus@@@Z @ 30 NONAME ; void RUsb::TryStart(int, class TRequestStatus &)
+	?TryStop@RUsb@@QAEXAAVTRequestStatus@@@Z @ 31 NONAME ; void RUsb::TryStop(class TRequestStatus &)
+	?BusDrop@RUsb@@QAEHXZ @ 32 NONAME ; int RUsb::BusDrop(void)
+	?BusRespondSrp@RUsb@@QAEHXZ @ 33 NONAME ; int RUsb::BusRespondSrp(void)
+	?BusRequest@RUsb@@QAEHXZ @ 34 NONAME ; int RUsb::BusRequest(void)
+	?DisableFunctionDriverLoading@RUsb@@QAEXXZ @ 35 NONAME ; void RUsb::DisableFunctionDriverLoading(void)
+	?EnableFunctionDriverLoading@RUsb@@QAEHXZ @ 36 NONAME ; int RUsb::EnableFunctionDriverLoading(void)
+	?GetManufacturerStringDescriptor@RUsb@@QAEHIIAAV?$TBuf@$0IA@@@@Z @ 37 NONAME ; int RUsb::GetManufacturerStringDescriptor(unsigned int, unsigned int, class TBuf<128> &)
+	?GetProductStringDescriptor@RUsb@@QAEHIIAAV?$TBuf@$0IA@@@@Z @ 38 NONAME ; int RUsb::GetProductStringDescriptor(unsigned int, unsigned int, class TBuf<128> &)
+	?GetSupportedLanguages@RUsb@@QAEHIAAV?$RArray@I@@@Z @ 39 NONAME ; int RUsb::GetSupportedLanguages(unsigned int, class RArray<unsigned int> &)
+	?HostEventNotification@RUsb@@QAEXAAVTRequestStatus@@AAVTDeviceEventInformation@@@Z @ 40 NONAME ; void RUsb::HostEventNotification(class TRequestStatus &, class TDeviceEventInformation &)
+	?HostEventNotificationCancel@RUsb@@QAEXXZ @ 41 NONAME ; void RUsb::HostEventNotificationCancel(void)
+	?MessageNotification@RUsb@@QAEXAAVTRequestStatus@@AAH@Z @ 42 NONAME ; void RUsb::MessageNotification(class TRequestStatus &, int &)
+	?MessageNotificationCancel@RUsb@@QAEXXZ @ 43 NONAME ; void RUsb::MessageNotificationCancel(void)
+	?SetCtlSessionMode@RUsb@@QAEHH@Z @ 44 NONAME ; int RUsb::SetCtlSessionMode(int)
+	?__DbgAlloc@RUsb@@QAEHXZ @ 45 NONAME ; int RUsb::__DbgAlloc(void)
+	?RequestSession@RUsb@@QAEHXZ @ 46 NONAME ; int RUsb::RequestSession(void)
+	?BusClearError@RUsb@@QAEHXZ @ 47 NONAME ; int RUsb::BusClearError(void)
+	?GetOtgDescriptor@RUsb@@QAEHIAAVTOtgDescriptor@@@Z @ 48 NONAME ; int RUsb::GetOtgDescriptor(unsigned int, class TOtgDescriptor &)
+	?GetDetailedDescription@RUsb@@QAEHHAAPAVHBufC16@@@Z @ 49 NONAME ; int RUsb::GetDetailedDescription(int, class HBufC16 * &)
+	?GetPersonalityProperty@RUsb@@QAEHHAAK@Z @ 50 NONAME ; int RUsb::GetPersonalityProperty(int, unsigned long &)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/client/BWINS/usbman_over_dummyusbdiu.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,52 @@
+EXPORTS
+	??0RUsb@@QAE@XZ @ 1 NONAME ; RUsb::RUsb(void)
+	??1RUsb@@QAE@XZ @ 2 NONAME ; RUsb::~RUsb(void)
+	?BusDrop@RUsb@@QAEHXZ @ 3 NONAME ; int RUsb::BusDrop(void)
+	?BusRespondSrp@RUsb@@QAEHXZ @ 4 NONAME ; int RUsb::BusRespondSrp(void)
+	?BusRequest@RUsb@@QAEHXZ @ 5 NONAME ; int RUsb::BusRequest(void)
+	?CancelInterest@RUsb@@QAEHW4TUsbReqType@1@@Z @ 6 NONAME ; int RUsb::CancelInterest(enum RUsb::TUsbReqType)
+	?ClassSupported@RUsb@@QAEHHVTUid@@AAH@Z @ 7 NONAME ; int RUsb::ClassSupported(int, class TUid, int &)
+	?Connect@RUsb@@QAEHXZ @ 8 NONAME ; int RUsb::Connect(void)
+	?DeviceStateNotification@RUsb@@QAEXIAAW4TUsbDeviceState@@AAVTRequestStatus@@@Z @ 9 NONAME ; void RUsb::DeviceStateNotification(unsigned int, enum TUsbDeviceState &, class TRequestStatus &)
+	?DeviceStateNotificationCancel@RUsb@@QAEXXZ @ 10 NONAME ; void RUsb::DeviceStateNotificationCancel(void)
+	?DisableFunctionDriverLoading@RUsb@@QAEXXZ @ 11 NONAME ; void RUsb::DisableFunctionDriverLoading(void)
+	?EnableFunctionDriverLoading@RUsb@@QAEHXZ @ 12 NONAME ; int RUsb::EnableFunctionDriverLoading(void)
+	?GetCurrentPersonalityId@RUsb@@QAEHAAH@Z @ 13 NONAME ; int RUsb::GetCurrentPersonalityId(int &)
+	?GetCurrentState@RUsb@@QAEHAAW4TUsbServiceState@@@Z @ 14 NONAME ; int RUsb::GetCurrentState(enum TUsbServiceState &)
+	?GetDescription@RUsb@@QAEHHAAPAVHBufC16@@@Z @ 15 NONAME ; int RUsb::GetDescription(int, class HBufC16 * &)
+	?GetDeviceState@RUsb@@QAEHAAW4TUsbDeviceState@@@Z @ 16 NONAME ; int RUsb::GetDeviceState(enum TUsbDeviceState &)
+	?GetManufacturerStringDescriptor@RUsb@@QAEHIIAAV?$TBuf@$0IA@@@@Z @ 17 NONAME ; int RUsb::GetManufacturerStringDescriptor(unsigned int, unsigned int, class TBuf<128> &)
+	?GetPersonalityIds@RUsb@@QAEHAAV?$RArray@H@@@Z @ 18 NONAME ; int RUsb::GetPersonalityIds(class RArray<int> &)
+	?GetProductStringDescriptor@RUsb@@QAEHIIAAV?$TBuf@$0IA@@@@Z @ 19 NONAME ; int RUsb::GetProductStringDescriptor(unsigned int, unsigned int, class TBuf<128> &)
+	?GetServiceState@RUsb@@QAEHAAW4TUsbServiceState@@@Z @ 20 NONAME ; int RUsb::GetServiceState(enum TUsbServiceState &)
+	?GetSupportedClasses@RUsb@@QAEHHAAV?$RArray@VTUid@@@@@Z @ 21 NONAME ; int RUsb::GetSupportedClasses(int, class RArray<class TUid> &)
+	?GetSupportedLanguages@RUsb@@QAEHIAAV?$RArray@I@@@Z @ 22 NONAME ; int RUsb::GetSupportedLanguages(unsigned int, class RArray<unsigned int> &)
+	?HostEventNotification@RUsb@@QAEXAAVTRequestStatus@@AAVTDeviceEventInformation@@@Z @ 23 NONAME ; void RUsb::HostEventNotification(class TRequestStatus &, class TDeviceEventInformation &)
+	?HostEventNotificationCancel@RUsb@@QAEXXZ @ 24 NONAME ; void RUsb::HostEventNotificationCancel(void)
+	?MessageNotification@RUsb@@QAEXAAVTRequestStatus@@AAH@Z @ 25 NONAME ; void RUsb::MessageNotification(class TRequestStatus &, int &)
+	?MessageNotificationCancel@RUsb@@QAEXXZ @ 26 NONAME ; void RUsb::MessageNotificationCancel(void)
+	?ServiceStateNotification@RUsb@@QAEXAAW4TUsbServiceState@@AAVTRequestStatus@@@Z @ 27 NONAME ; void RUsb::ServiceStateNotification(enum TUsbServiceState &, class TRequestStatus &)
+	?ServiceStateNotificationCancel@RUsb@@QAEXXZ @ 28 NONAME ; void RUsb::ServiceStateNotificationCancel(void)
+	?SetCtlSessionMode@RUsb@@QAEHH@Z @ 29 NONAME ; int RUsb::SetCtlSessionMode(int)
+	?Start@RUsb@@QAEXAAVTRequestStatus@@@Z @ 30 NONAME ; void RUsb::Start(class TRequestStatus &)
+	?StartCancel@RUsb@@QAEXXZ @ 31 NONAME ; void RUsb::StartCancel(void)
+	?StateNotification@RUsb@@QAEXIAAW4TUsbDeviceState@@AAVTRequestStatus@@@Z @ 32 NONAME ; void RUsb::StateNotification(unsigned int, enum TUsbDeviceState &, class TRequestStatus &)
+	?StateNotificationCancel@RUsb@@QAEXXZ @ 33 NONAME ; void RUsb::StateNotificationCancel(void)
+	?Stop@RUsb@@QAEXAAVTRequestStatus@@@Z @ 34 NONAME ; void RUsb::Stop(class TRequestStatus &)
+	?Stop@RUsb@@QAEXXZ @ 35 NONAME ; void RUsb::Stop(void)
+	?StopCancel@RUsb@@QAEXXZ @ 36 NONAME ; void RUsb::StopCancel(void)
+	?TryStart@RUsb@@QAEXHAAVTRequestStatus@@@Z @ 37 NONAME ; void RUsb::TryStart(int, class TRequestStatus &)
+	?TryStop@RUsb@@QAEXAAVTRequestStatus@@@Z @ 38 NONAME ; void RUsb::TryStop(class TRequestStatus &)
+	?Version@RUsb@@QBE?AVTVersion@@XZ @ 39 NONAME ; class TVersion RUsb::Version(void) const
+	?__DbgAlloc@RUsb@@QAEHXZ @ 40 NONAME ; int RUsb::__DbgAlloc(void)
+	?__DbgCheckHeap@RUsb@@QAEHH@Z @ 41 NONAME ; int RUsb::__DbgCheckHeap(int)
+	?__DbgFailNext@RUsb@@QAEHH@Z @ 42 NONAME ; int RUsb::__DbgFailNext(int)
+	?__DbgMarkEnd@RUsb@@QAEHH@Z @ 43 NONAME ; int RUsb::__DbgMarkEnd(int)
+	?__DbgMarkHeap@RUsb@@QAEHXZ @ 44 NONAME ; int RUsb::__DbgMarkHeap(void)
+	?panic@@YAXXZ @ 45 NONAME ; void panic(void)
+	?RequestSession@RUsb@@QAEHXZ @ 46 NONAME ; int RUsb::RequestSession(void)
+	?BusClearError@RUsb@@QAEHXZ @ 47 NONAME ; int RUsb::BusClearError(void)
+	?GetOtgDescriptor@RUsb@@QAEHIAAVTOtgDescriptor@@@Z @ 48 NONAME ; int RUsb::GetOtgDescriptor(unsigned int, class TOtgDescriptor &)
+	?GetDetailedDescription@RUsb@@QAEHHAAPAVHBufC16@@@Z @ 49 NONAME ; int RUsb::GetDetailedDescription(int, class HBufC16 * &)
+	?GetPersonalityProperty@RUsb@@QAEHHAAK@Z @ 50 NONAME ; int RUsb::GetPersonalityProperty(int, unsigned long &)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/client/EABI/usbmanU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,54 @@
+EXPORTS
+	_Z5panicv @ 1 NONAME
+	_ZN4RUsb10StopCancelEv @ 2 NONAME
+	_ZN4RUsb11StartCancelEv @ 3 NONAME
+	_ZN4RUsb12__DbgMarkEndEi @ 4 NONAME
+	_ZN4RUsb13__DbgFailNextEi @ 5 NONAME
+	_ZN4RUsb13__DbgMarkHeapEv @ 6 NONAME
+	_ZN4RUsb14GetDeviceStateER15TUsbDeviceState @ 7 NONAME
+	_ZN4RUsb14__DbgCheckHeapEi @ 8 NONAME
+	_ZN4RUsb15GetCurrentStateER16TUsbServiceState @ 9 NONAME
+	_ZN4RUsb15GetServiceStateER16TUsbServiceState @ 10 NONAME
+	_ZN4RUsb17StateNotificationEjR15TUsbDeviceStateR14TRequestStatus @ 11 NONAME
+	_ZN4RUsb23DeviceStateNotificationEjR15TUsbDeviceStateR14TRequestStatus @ 12 NONAME
+	_ZN4RUsb23StateNotificationCancelEv @ 13 NONAME
+	_ZN4RUsb24ServiceStateNotificationER16TUsbServiceStateR14TRequestStatus @ 14 NONAME
+	_ZN4RUsb29DeviceStateNotificationCancelEv @ 15 NONAME
+	_ZN4RUsb30ServiceStateNotificationCancelEv @ 16 NONAME
+	_ZN4RUsb4StopER14TRequestStatus @ 17 NONAME
+	_ZN4RUsb4StopEv @ 18 NONAME
+	_ZN4RUsb5StartER14TRequestStatus @ 19 NONAME
+	_ZN4RUsb7ConnectEv @ 20 NONAME
+	_ZN4RUsbC1Ev @ 21 NONAME
+	_ZN4RUsbC2Ev @ 22 NONAME
+	_ZN4RUsbD1Ev @ 23 NONAME
+	_ZN4RUsbD2Ev @ 24 NONAME
+	_ZNK4RUsb7VersionEv @ 25 NONAME
+	_ZN4RUsb14CancelInterestENS_11TUsbReqTypeE @ 26 NONAME
+	_ZN4RUsb14ClassSupportedEi4TUidRi @ 27 NONAME
+	_ZN4RUsb14GetDescriptionEiRP7HBufC16 @ 28 NONAME
+	_ZN4RUsb17GetPersonalityIdsER6RArrayIiE @ 29 NONAME
+	_ZN4RUsb19GetSupportedClassesEiR6RArrayI4TUidE @ 30 NONAME
+	_ZN4RUsb23GetCurrentPersonalityIdERi @ 31 NONAME
+	_ZN4RUsb7TryStopER14TRequestStatus @ 32 NONAME
+	_ZN4RUsb8TryStartEiR14TRequestStatus @ 33 NONAME
+	_ZN4RUsb13BusRespondSrpEv @ 34 NONAME
+	_ZN4RUsb10BusRequestEv @ 35 NONAME
+	_ZN4RUsb17SetCtlSessionModeEi @ 36 NONAME
+	_ZN4RUsb19MessageNotificationER14TRequestStatusRi @ 37 NONAME
+	_ZN4RUsb21GetSupportedLanguagesEjR6RArrayIjE @ 38 NONAME
+	_ZN4RUsb21HostEventNotificationER14TRequestStatusR23TDeviceEventInformation @ 39 NONAME
+	_ZN4RUsb25MessageNotificationCancelEv @ 40 NONAME
+	_ZN4RUsb26GetProductStringDescriptorEjjR4TBufILi128EE @ 41 NONAME
+	_ZN4RUsb27EnableFunctionDriverLoadingEv @ 42 NONAME
+	_ZN4RUsb27HostEventNotificationCancelEv @ 43 NONAME
+	_ZN4RUsb28DisableFunctionDriverLoadingEv @ 44 NONAME
+	_ZN4RUsb31GetManufacturerStringDescriptorEjjR4TBufILi128EE @ 45 NONAME
+	_ZN4RUsb7BusDropEv @ 46 NONAME
+	_ZN4RUsb10__DbgAllocEv @ 47 NONAME
+	_ZN4RUsb14RequestSessionEv @ 48 NONAME
+	_ZN4RUsb13BusClearErrorEv @ 49 NONAME
+	_ZN4RUsb16GetOtgDescriptorEjR14TOtgDescriptor @ 50 NONAME
+	_ZN4RUsb22GetDetailedDescriptionEiRP7HBufC16 @ 51 NONAME
+	_ZN4RUsb22GetPersonalityPropertyEiRm @ 52 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/client/SRC/RUsb.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,790 @@
+/*
+* Copyright (c) 2003-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:
+*
+*/
+
+#include <e32uid.h>
+#include <usbman.h>
+#include <usb.h>
+#include <e32base.h>
+#include "rusb.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBMAN");
+#endif
+
+#ifdef __USBMAN_NO_PROCESSES__
+#include <e32math.h>
+#endif
+
+
+static TInt StartServer()
+//
+// Start the server process or thread
+//
+	{
+	const TUidType serverUid(KNullUid, KNullUid, KUsbmanSvrUid);
+
+#ifdef __USBMAN_NO_PROCESSES__
+	//
+	// In EKA1 WINS the server is a DLL, the exported entrypoint returns a TInt
+	// which represents the real entry-point for the server thread
+	//
+	RLibrary lib;
+	TInt err = lib.Load(KUsbmanImg, serverUid);
+	
+	if (err != KErrNone)
+		{
+		return err;
+		}
+
+	TLibraryFunction ordinal1 = lib.Lookup(1);
+	TThreadFunction serverFunc = reinterpret_cast<TThreadFunction>(ordinal1());
+
+	//
+	// To deal with the unique thread (+semaphore!) naming in EPOC, and that we may
+	// be trying to restart a server that has just exited we attempt to create a
+	// unique thread name for the server.
+	// This uses Math::Random() to generate a 32-bit random number for the name
+	//
+	TName name(KUsbServerName);
+	name.AppendNum(Math::Random(),EHex);
+	
+	RThread server;
+	err = server.Create (
+		name,
+		serverFunc,
+		KUsbmanStackSize,
+		NULL,
+		&lib,
+		NULL,
+		KUsbmanMinHeapSize,
+		KUsbmanMaxHeapSize,
+		EOwnerProcess
+	);
+
+	lib.Close();	// if successful, server thread has handle to library now
+#else
+	//
+	// EPOC and EKA2 is easy, we just create a new server process. Simultaneous
+	// launching of two such processes should be detected when the second one
+	// attempts to create the server object, failing with KErrAlreadyExists.
+	//
+	RProcess server;
+	TInt err = server.Create(KUsbmanImg, KNullDesC, serverUid);
+#endif //__USBMAN_NO_PROCESSES__
+	
+	if (err != KErrNone)
+		{
+		return err;
+		}
+
+	TRequestStatus stat;
+	server.Rendezvous(stat);
+	
+	if (stat!=KRequestPending)
+		server.Kill(0);		// abort startup
+	else
+		server.Resume();	// logon OK - start the server
+
+	User::WaitForRequest(stat);		// wait for start or death
+
+	// we can't use the 'exit reason' if the server panicked as this
+	// is the panic 'reason' and may be '0' which cannot be distinguished
+	// from KErrNone
+	err = (server.ExitType() == EExitPanic) ? KErrServerTerminated : stat.Int();
+
+	server.Close();
+	
+	LOGTEXT2(_L8("USB server started successfully: err = %d\n"),err);
+
+	return err;
+	}
+
+
+
+
+EXPORT_C RUsb::RUsb() 
+	: iDeviceStatePkg(0), iServiceStatePkg(0), iMessagePkg(0), 
+	  iHostPkg(TDeviceEventInformation())
+	{
+	LOG_LINE
+	LOG_FUNC
+	}
+
+EXPORT_C RUsb::~RUsb()
+	{
+	LOG_LINE
+	LOG_FUNC
+	}
+
+EXPORT_C TVersion RUsb::Version() const
+	{
+	return(TVersion(KUsbSrvMajorVersionNumber,KUsbSrvMinorVersionNumber,KUsbSrvBuildVersionNumber));
+	}
+
+EXPORT_C TInt RUsb::Connect()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt retry = 2;
+	
+	FOREVER
+		{
+		// Create the session to UsbSrv with 10 asynchronous message slots
+		TInt err = CreateSession(KUsbServerName, Version(), 10);
+
+		if ((err != KErrNotFound) && (err != KErrServerTerminated))
+			{
+			return err;
+			}
+
+		if (--retry == 0)
+			{
+			return err;
+			}
+
+		err = StartServer();
+
+		if ((err != KErrNone) && (err != KErrAlreadyExists))
+			{
+			return err;
+			}
+		}
+	}
+
+EXPORT_C void RUsb::Start(TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbStart, aStatus);
+	}
+
+EXPORT_C void RUsb::StartCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbStartCancel);
+	}
+
+EXPORT_C void RUsb::Stop()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbStop);
+	}
+
+EXPORT_C void RUsb::Stop(TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbStop, aStatus);
+	}
+
+EXPORT_C void RUsb::StopCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbStopCancel);
+	}
+
+EXPORT_C TInt RUsb::GetServiceState(TUsbServiceState& aState)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TPckg<TUint32> pkg(aState);
+	TInt ret=SendReceive(EUsbGetCurrentState, TIpcArgs(&pkg));
+	aState=(TUsbServiceState)pkg();
+	return ret;
+	}
+
+EXPORT_C TInt RUsb::GetCurrentState(TUsbServiceState& aState)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return GetServiceState(aState);
+	}
+
+EXPORT_C void RUsb::ServiceStateNotification(TUsbServiceState& aState,
+	TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	iServiceStatePkg.Set((TUint8*)&aState, sizeof(TUint32), sizeof(TUint32));
+
+	SendReceive(EUsbRegisterServiceObserver, TIpcArgs(&iServiceStatePkg), aStatus);
+	}
+
+EXPORT_C void RUsb::ServiceStateNotificationCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbCancelServiceObserver);
+	}
+
+EXPORT_C TInt RUsb::GetDeviceState(TUsbDeviceState& aState)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TPckg<TUint32> pkg(aState);
+	TInt ret=SendReceive(EUsbGetCurrentDeviceState, TIpcArgs(&pkg));
+	aState=(TUsbDeviceState)pkg();
+	return ret;
+	}
+
+EXPORT_C void RUsb::DeviceStateNotification(TUint aEventMask, TUsbDeviceState& aState,
+											TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	iDeviceStatePkg.Set((TUint8*)&aState, sizeof(TUint32), sizeof(TUint32));
+
+	SendReceive(EUsbRegisterObserver, TIpcArgs(aEventMask, &iDeviceStatePkg), aStatus);
+	}
+
+EXPORT_C void RUsb::DeviceStateNotificationCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbCancelObserver);
+	}
+
+EXPORT_C void RUsb::StateNotification(TUint aEventMask, TUsbDeviceState& aState, TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	DeviceStateNotification(aEventMask, aState, aStatus);
+	}
+
+EXPORT_C void RUsb::StateNotificationCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	DeviceStateNotificationCancel();
+	}
+	
+EXPORT_C void RUsb::TryStart(TInt aPersonalityId, TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TIpcArgs ipcArgs(aPersonalityId);
+	SendReceive(EUsbTryStart, ipcArgs, aStatus);
+	}
+
+EXPORT_C void RUsb::TryStop(TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbTryStop, aStatus);
+	}
+	
+EXPORT_C TInt RUsb::CancelInterest(TUsbReqType aMessageId)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt messageId;
+	switch (aMessageId)
+		{
+	case EStart:
+		messageId = EUsbStart;
+		break;
+	case EStop:
+		messageId = EUsbStop;
+		break;
+	case ETryStart:
+		messageId = EUsbTryStart;
+		break;
+	case ETryStop:
+		messageId = EUsbTryStop;
+		break;
+	default:
+		return KErrNotSupported;
+		}
+		
+	TIpcArgs ipcArgs(messageId);
+	return SendReceive(EUsbCancelInterest, ipcArgs);
+	}
+
+EXPORT_C TInt RUsb::GetDescription(TInt aPersonalityId, HBufC*& aLocalizedPersonalityDescriptor)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+	// caller is responsible for freeing up memory allocatd for aLocalizedPersonalityDescriptor
+	TRAP(ret, aLocalizedPersonalityDescriptor = HBufC::NewL(KUsbStringDescStringMaxSize));
+	if (ret == KErrNone)
+		{
+		TPtr ptr = aLocalizedPersonalityDescriptor->Des();
+		TIpcArgs ipcArgs(0, &ptr);
+		ipcArgs.Set(0, aPersonalityId);
+		ret = SendReceive(EUsbGetDescription, ipcArgs);
+		}
+	else
+		{
+		// just in case caller tries to free the memory before checking the return code
+		aLocalizedPersonalityDescriptor = NULL;
+		}
+
+	return ret;	
+	}
+	
+EXPORT_C TInt RUsb::GetCurrentPersonalityId(TInt& aPersonalityId)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TPckg<TInt> pkg0(aPersonalityId);
+	TInt ret = SendReceive(EUsbGetCurrentPersonalityId, TIpcArgs(&pkg0));
+	aPersonalityId = static_cast<TInt>(pkg0());
+	return ret;	
+	}
+
+EXPORT_C TInt RUsb::GetSupportedClasses(TInt aPersonalityId, RArray<TUid>& aClassUids)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+	HBufC8* buf = NULL;
+	// +1 for the actual count of personality ids
+	TRAP(ret, buf = HBufC8::NewL((KUsbMaxSupportedClasses + 1)*sizeof (TInt32)));
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+
+	TPtr8 ptr8 = buf->Des();
+	ret = SendReceive(EUsbGetSupportedClasses, TIpcArgs(aPersonalityId, &ptr8));
+		
+	if (ret == KErrNone)
+		{
+		const TInt32* recvedIds = reinterpret_cast<const TInt32*>(buf->Ptr());
+		if (!recvedIds)
+			{
+			delete buf;
+			return KErrCorrupt;
+			}
+			
+		TInt arraySize = *recvedIds++;
+		// Copy received supported class ids to aClassUids
+		for (TInt i = 0; i < arraySize; i++)
+			{
+			if (recvedIds)
+				{
+				ret = aClassUids.Append(TUid::Uid(*recvedIds++));
+				if(ret!=KErrNone)
+					{
+					//Remove all the ids appended so far (assume the last append failed, because
+					//the only reason to fail is if the array couldn't grow to accommodate another
+					//element).
+					//It would be easier to just reset the array, but we never specified that
+					//aClassUids should be an empty array, nor did we specify that this method
+					//might empty the array. To maintain exisiting behaviour we should return
+					//aClassUids to the state it was in when this method was called.
+					TInt last = aClassUids.Count() - 1;
+					while(i>0)
+						{
+						aClassUids.Remove(last);
+						i--;
+						last--;
+						}	
+					break;
+					}
+				}
+			else
+				{
+				ret = KErrCorrupt;
+				break;
+				}
+			}
+		}
+		
+	delete buf;
+	return ret;
+	}
+	
+EXPORT_C TInt RUsb::ClassSupported(TInt aPersonalityId, TUid aClassUid, TBool& aSupported)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TPckg<TInt32>  	pkg2(aSupported);
+	TIpcArgs ipcArgs(aPersonalityId, aClassUid.iUid, &pkg2);
+	
+	TInt ret = SendReceive(EUsbClassSupported, ipcArgs);
+	
+	if (ret == KErrNone)
+		{
+		aSupported = static_cast<TBool>(pkg2());		
+		}
+		
+	return ret;
+	}
+	
+EXPORT_C TInt RUsb::GetPersonalityIds(RArray<TInt>& aPersonalityIds)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+	HBufC8* buf = NULL;
+	// +1 for the actual count of personality ids
+	TRAP(ret, buf = HBufC8::NewL((KUsbMaxSupportedPersonalities + 1)*sizeof (TInt)));
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+
+	TPtr8 ptr8 = buf->Des();
+	ret = SendReceive(EUsbGetPersonalityIds, TIpcArgs(&ptr8));
+		
+	if (ret == KErrNone)
+		{
+		const TInt* recvedIds = reinterpret_cast<const TInt*>(buf->Ptr());
+		if (!recvedIds)
+			{
+			delete buf;
+			return KErrCorrupt;
+			}
+			
+		TInt arraySize = *recvedIds++;
+		// Copy received personality ids to aPersonalityIds
+		for (TInt i = 0; i < arraySize; i++)
+			{
+			if (recvedIds)
+				{		
+				ret = aPersonalityIds.Append(*recvedIds++);
+				
+				if(ret!=KErrNone)
+					{
+					//Remove all the ids appended so far (assume the last append failed, because
+					//the only reason to fail is if the array couldn't grow to accommodate another
+					//element).
+					//It would be easier to just reset the array, but we never specified that
+					//aPersonalityIds should be an empty array, nor did we specify that this method
+					//might empty the array. To maintain exisiting behaviour we should return
+					//aPersonalityIds to the state it was in when this method was called.
+					TInt last = aPersonalityIds.Count() - 1;
+					while(i>0)
+						{
+						aPersonalityIds.Remove(last);
+						i--;
+						last--;
+						}	
+					break;
+					}
+				}
+			else
+				{
+				ret = KErrCorrupt;
+				break;
+				}
+			}
+		}
+		
+	delete buf;
+	return ret;
+	}
+	
+EXPORT_C TInt RUsb::__DbgMarkHeap()
+	{
+#ifdef _DEBUG
+    return SendReceive(EUsbDbgMarkHeap);
+#else
+    return KErrNone;
+#endif
+	}
+
+EXPORT_C TInt RUsb::__DbgCheckHeap(TInt aCount)
+	{
+#ifdef _DEBUG
+    return SendReceive(EUsbDbgCheckHeap, TIpcArgs(aCount));
+#else
+	(void)aCount; // not used for Release builds
+    return KErrNone;
+#endif
+	}
+
+EXPORT_C TInt RUsb::__DbgMarkEnd(TInt aCount)
+	{
+#ifdef _DEBUG
+    return SendReceive(EUsbDbgMarkEnd, TIpcArgs(aCount));
+#else
+	(void)aCount; // not used for Release builds
+    return KErrNone;
+#endif
+	}
+
+EXPORT_C TInt RUsb::__DbgFailNext(TInt aCount)
+	{
+#ifdef _DEBUG
+    return SendReceive(EUsbDbgFailNext, TIpcArgs(aCount));
+#else
+	(void)aCount; // not used for Release builds
+    return KErrNone;
+#endif
+	}
+
+EXPORT_C TInt RUsb::__DbgAlloc()
+	{
+#ifdef _DEBUG
+    return SendReceive(EUsbDbgAlloc);
+#else
+    return KErrNone;
+#endif
+	}
+
+EXPORT_C void panic()
+	{
+	_USB_PANIC(KUsbCliPncCat, EUsbPanicRemovedExport);
+	}
+
+EXPORT_C TInt RUsb::SetCtlSessionMode(TBool aValue)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TPckg<TBool> pkg(aValue);
+	return SendReceive(EUsbSetCtlSessionMode, TIpcArgs(&pkg));
+	}
+
+EXPORT_C TInt RUsb::BusRequest()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbBusRequest);
+	}
+
+EXPORT_C TInt RUsb::BusRespondSrp()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbBusRespondSrp);
+	}
+
+EXPORT_C TInt RUsb::BusClearError()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbBusClearError);
+	}
+
+
+EXPORT_C TInt RUsb::BusDrop()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbBusDrop);
+	}
+
+EXPORT_C void RUsb::MessageNotification(TRequestStatus& aStatus, TInt& aMessage)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	iMessagePkg.Set((TUint8*)&aMessage, sizeof(TInt), sizeof(TInt));
+
+	SendReceive(EUsbRegisterMessageObserver, TIpcArgs(&iMessagePkg), aStatus);
+	}
+
+EXPORT_C void RUsb::MessageNotificationCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbCancelMessageObserver);
+	}
+
+EXPORT_C void RUsb::HostEventNotification(TRequestStatus& aStatus,
+										  TDeviceEventInformation& aDeviceInformation)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	iHostPkg.Set((TUint8*)&aDeviceInformation, sizeof(TDeviceEventInformation), sizeof(TDeviceEventInformation));
+
+	SendReceive(EUsbRegisterHostObserver, TIpcArgs(&iHostPkg), aStatus);
+	}
+	
+EXPORT_C void RUsb::HostEventNotificationCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbCancelHostObserver);
+	}
+
+EXPORT_C TInt RUsb::EnableFunctionDriverLoading()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbEnableFunctionDriverLoading);
+	}
+
+EXPORT_C void RUsb::DisableFunctionDriverLoading()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbDisableFunctionDriverLoading);
+	}
+
+EXPORT_C TInt RUsb::GetSupportedLanguages(TUint aDeviceId, RArray<TUint>& aLangIds)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	aLangIds.Reset();
+
+	TInt ret = KErrNone;
+	HBufC8* buf = NULL;
+	// +1 for the actual count of language ids
+	TRAP(ret, buf = HBufC8::NewL((KUsbMaxSupportedLanguageIds + 1)*sizeof (TUint)));
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+
+	TPtr8 ptr8 = buf->Des();
+	ret = SendReceive(EUsbGetSupportedLanguages, TIpcArgs(aDeviceId, &ptr8));
+		
+	if (ret == KErrNone)
+		{
+		const TUint* recvedIds = reinterpret_cast<const TUint*>(buf->Ptr());
+		if (!recvedIds)
+			{
+			delete buf;
+			return KErrCorrupt;
+			}
+			
+		TInt arraySize = *recvedIds++;
+		// Copy received language ids to aLangIds
+		for (TInt i = 0; i < arraySize; i++)
+			{
+			ret = aLangIds.Append(*recvedIds++); // increments by sizeof(TUint)
+			if ( ret )
+				{
+				aLangIds.Reset();
+				break;
+				}
+			}
+		}
+		
+	delete buf;	
+	return ret;
+	}
+	
+EXPORT_C TInt RUsb::GetManufacturerStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbGetManufacturerStringDescriptor, TIpcArgs(aDeviceId, aLangId, &aString));
+	}
+
+EXPORT_C TInt RUsb::GetProductStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbGetProductStringDescriptor, TIpcArgs(aDeviceId, aLangId, &aString));
+	}
+
+EXPORT_C TInt RUsb::GetOtgDescriptor(TUint aDeviceId, TOtgDescriptor& aDescriptor)
+	{
+	LOG_LINE
+	LOG_FUNC
+		
+	TPckg<TOtgDescriptor> otgDescPkg(aDescriptor);
+	
+	TIpcArgs args;
+	args.Set(0, aDeviceId);
+	args.Set(1, &otgDescPkg);
+
+	return SendReceive(EUsbGetOtgDescriptor, args);
+	}
+
+
+EXPORT_C TInt RUsb::RequestSession()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbRequestSession);
+	}
+
+EXPORT_C TInt RUsb::GetDetailedDescription(TInt aPersonalityId, HBufC*& aLocalizedPersonalityDescriptor)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+ 	TInt ret = KErrNone;
+	// caller is responsible for freeing up memory allocated for aLocalizedPersonalityDescriptor
+	TRAP(ret, aLocalizedPersonalityDescriptor = HBufC::NewL(KUsbStringDescStringMaxSize));
+	if (ret == KErrNone)
+		{
+		TPtr ptr = aLocalizedPersonalityDescriptor->Des();
+		TIpcArgs ipcArgs(0, &ptr);
+		ipcArgs.Set(0, aPersonalityId);
+		ret = SendReceive(EUsbGetDetailedDescription, ipcArgs);
+		}
+	else
+		{
+		// just in case caller tries to free the memory before checking the return code
+		aLocalizedPersonalityDescriptor = NULL;
+		}
+
+	return ret; 
+	}
+
+EXPORT_C TInt RUsb::GetPersonalityProperty(TInt aPersonalityId, TUint32& aProperty)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TPckg<TUint32> pkg(aProperty);
+	TInt ret = SendReceive(EUsbGetPersonalityProperty, TIpcArgs(aPersonalityId, &pkg));
+	if (ret == KErrNone)
+		{
+		aProperty = static_cast<TUint32>(pkg());
+		}
+	return ret;	
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/client/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* 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 "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:
+*
+*/
+
+PRJ_EXPORTS
+../public/usbman.h			SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usbman.h)
+../public/usbstates.h			SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usbstates.h)
+
+PRJ_MMPFILES
+Usbman.mmp
+
+#if defined(WINS)
+PRJ_TESTMMPFILES
+Usbman_over_dummyusbdi.mmp
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/client/group/Usbman.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 1997-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:
+* usbman.dll USB Client side RUsb Class
+*
+*/
+
+/**
+ @file
+*/
+
+target			usbman.dll
+CAPABILITY All -Tcb
+targettype		dll
+
+//
+// We have a laggard, ill-defined UID3 which must be kept
+// for old platforms for BC.  For newer platforms, we use
+// KUidUsbmanClient = 0x101FE1DA
+//
+ uid			0x1000008d 0x101fe1da
+
+sourcepath		../SRC
+source			RUsb.cpp
+
+userinclude		../../server/public
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+library			euser.lib
+
+#include <usb/usblogger.mmh>
+
+VENDORID 0x70000001
+
+UNPAGED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/client/group/Usbman_over_dummyusbdi.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 1997-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:
+* usbman.mmp
+* usbman.dll USB Client side RUsb Class
+*
+*/
+
+/**
+ @file
+*/
+
+MACRO	__OVER_DUMMYUSBDI__
+
+target			usbman_over_dummyusbdi.dll
+CAPABILITY All -Tcb
+targettype		dll
+
+//
+// We have a laggard, ill-defined UID3 which must be kept
+// for old platforms for BC.  For newer platforms, we use
+// KUidUsbmanClient = 0x101FE1DA
+//
+uid			0x1000008d 0x101fe1da
+
+sourcepath		../SRC
+source			RUsb.cpp
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+userinclude		../../server/public
+
+library			euser.lib
+
+#include <usb/usblogger.mmh>
+
+VENDORID 0x70000001
+
+UNPAGED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/client/public/usbman.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,707 @@
+/*
+* Copyright (c) 1997-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:
+* RUsb Client side header
+* Implements the Symbian OS USB Management API RUsb
+*
+*/
+
+/**
+ @file
+*/
+
+#ifndef __USBMAN_H__
+#define __USBMAN_H__
+
+#include <e32std.h>
+#include <usberrors.h>
+#include <usbstates.h>
+#include <usb/usbshared.h>
+
+// The propery of a personality is a bitmap, and bit 0 is used to identify
+// whether a personality is hidden.
+const TUint32 KUsbPersonalityPropertyHidden = 0x00000001;
+
+NONSHARABLE_CLASS(RUsb) : public RSessionBase
+/**
+The RUsb class implements the Symbian OS USB Management API RUsb
+
+@publishedPartner
+@released
+*/
+	{
+public:
+
+	// Request types, the interest of which can be cancelled by clients
+	enum TUsbReqType
+		{
+		EStart,
+		EStop,
+		ETryStart,
+		ETryStop
+		};
+		
+	/**
+	Constructor
+
+	
+	@since	7.0
+
+	@publishedPartner
+	@released
+	 */
+	IMPORT_C RUsb();
+
+	/**
+	Destructor
+
+	
+	@since	7.0
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C ~RUsb();
+
+	/**
+	Extract the version of the server providing the RUsb API
+
+	
+	@since	7.0
+
+	@return	Version of the server
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TVersion Version() const;
+
+	/**
+	Connect the Handle to the Server
+	Must be called before all other methods except Version()
+
+	
+	@since	7.0
+
+	@return	KErrNone if successful, otherwise the error that occurred
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt Connect();
+
+	/**
+	Start the device's USB service. Should not be called if the USB services
+	have already been started
+	Note: Asynchonous Version, outcome returned when the status is completed
+	
+	
+	@since	7.0
+	@param	aStatus		Status to complete once the start operation has completed
+	@capability NetworkControl
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C void Start(TRequestStatus& aStatus);
+
+	/**
+	Cancels the pending start operation of the device's USB service.
+
+	
+	@since	7.0
+	@capability NetworkControl
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C void StartCancel();
+
+	/**
+	Stops the device's USB service. Should not be called if the USB services
+	have not been started. This is the synchronous variant of this function.
+	This function is deprecated- use the asynchronous version.
+	
+	
+	@since	7.0
+	@capability NetworkControl
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C void Stop();
+
+	/**
+	Stops the device's USB service. Should not be called if the USB services
+	have not been started. This is the asynchronous variant of this function.
+	
+	
+	@since	7.0s
+	@param	aStatus		Status to complete once the stop operation has completed
+	@capability NetworkControl
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C void Stop(TRequestStatus& aStatus);
+
+	/**
+	Cancels the pending stop operation of the device's USB service.
+
+	
+	@since	7.0s
+	@capability NetworkControl
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C void StopCancel();
+
+	/**
+	Get the current state of the device's USB service.
+
+	
+	@since	7.0s
+	@param	aState	Set by the method to the current state of the USB service
+
+	@return	KErrNone if successful, otherwise the error that occurred
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt GetServiceState(TUsbServiceState& aState);
+
+	/**
+	Request to be notified of a change in service state of the USB device. The
+	request only completes when the service state changes.
+
+	
+	@since	7.0s
+	@param	aState		State variable to be written to upon completion of the request
+	@param	aStatus		Status to complete when required state change occurs
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C void ServiceStateNotification(
+		TUsbServiceState& aState,
+		TRequestStatus& aStatus
+	);
+
+	/**
+	Cancel the outstanding service state notification request.
+
+	
+	@since 7.0s
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C void ServiceStateNotificationCancel();
+
+	/**
+	Gets the current device state (eg. powered, configured...).
+
+	
+	@since	7.0s
+	@param	aState	Set by the method to the current state of the USB device
+	@return	KErrNone if successful, otherwise the error that occurred
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt GetDeviceState(TUsbDeviceState& aState);
+
+	/**
+	Request to be notified of a change in state of the USB device.
+
+	
+	@since	7.0s
+	@param	aStateMask	State mask of the states the client is interested in	
+	@param	aState		State variable to be written to upon completion of the request
+	@param	aStatus		Status to complete when required state change occurs
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C void DeviceStateNotification(
+		TUint aStateMask,
+		TUsbDeviceState& aState,
+		TRequestStatus& aStatus
+	);
+
+	/**
+	Cancel the outstanding device state notification request.
+
+	
+	@since 7.0s
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C void DeviceStateNotificationCancel();
+	
+	/**
+	Try to start the device's USB service. It starts the current personality
+	only if the service is in the idle state. Calling this API while the server
+	is in any other states has no any effect on the service state.
+	 
+	Note: Asynchonous version, outcome returned when the status is completed
+	
+	@param aPersonalityId 	a personality id
+	@param aStatus			Status to complete once the start operation has completed.
+							It may be one of the following:	
+								KErrNotSupported
+								KErrAccessDenied
+								KErrServerBusy
+								KErrAbort
+								KErrNone
+	@capability NetworkControl
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C void TryStart(TInt aPersonalityId, TRequestStatus& aStatus);
+
+	/**
+	Try to stop the device's USB service. It stops the service only if the serice
+	is in the started state. Calling this API while the server is in the other states 
+	has no any effect on the service state.
+
+	Note: Asynchonous version, outcome returned when the status is completed
+	
+	@param	aStatus		Status to complete once the stop operation has completed.
+						It may be one of the following:
+								KErrNotSupported
+								KErrAccessDenied
+								KErrServerBusy
+								KErrNone
+	@capability NetworkControl
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C void TryStop(TRequestStatus& aStatus);
+
+	/**
+	Cancels the interest of the pending operation of the device's USB service, 
+	either starting or stopping. The pending request will run to the completion.
+	The caller of this function receives a status of KErrCancel.
+	
+	@param  aMessageId	a message id to identify the request to be cancelled
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt CancelInterest(TUsbReqType aMessageId);
+
+	/**
+	Gets the textual description of the personality identified by the aPersonalityId.
+	Caller is repsonsible for freeing up memories allocated to 
+	aLocalizedPersonalityDescriptor.
+
+	@param	aPersonalityId a personality id
+	@param  aLocalizedPersonalityDescriptor a localize text string
+	@return	KErrNone if successful, otherwise the error that occurred
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt GetDescription(TInt aPersonalityId, HBufC*& aLocalizedPersonalityDescriptor);
+
+	/**
+	Gets the current personality id of the device's USb service
+	
+	@param	aPersonalityId set to the current personality of USB device
+	@return	KErrNone if successful, otherwise the error that occurred
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt GetCurrentPersonalityId(TInt& aPersonalityId);
+	
+	/**
+	Gets supported classes by the given personality identified by the aPersonalityId
+
+	@param aPersonalityId a personality id 
+	@param aClassUids an array of class uids
+	@return	KErrNone if successful, otherwise the error that occurred
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt GetSupportedClasses(TInt aPersonalityId, RArray<TUid>& aClassUids);
+
+	/** 
+	Queries the USB manager to determine if a given class is supported
+	
+	@param aPersonalityId a personality id
+	@param aClassUid a class uid
+	@param aSupported set upon return
+	@return	KErrNone if successful, otherwise the error that occurred
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt ClassSupported(TInt aPersonalityId, TUid aClassUid, TBool& aSupported);
+	
+	/**
+	Gets all supported personality ids of the device's USB service.
+
+	@param	aPersonalityIds populated with all supported personality ids of the USB device
+	@return	KErrNone if successful, otherwise the error that occurred
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt GetPersonalityIds(RArray<TInt>& aPersonalityIds);
+
+	/**
+	Marks the start of heap cell checking for the USB Manager. This function is only defined
+	in debug builds.
+
+	@return	KErrNone if successful, otherwise the error that occurred
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt __DbgMarkHeap();
+
+	/**
+	Checks that the number of allocated cells on the USB Manager's heap is correct. The USB
+	Manager will be panicked if it is not. This function is only defined in debug builds.
+	
+	@param	aCount	The expected number of heap cells allocated
+	@return	KErrNone if successful, otherwise the error that occurred
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt __DbgCheckHeap(TInt aCount);
+
+	/**
+	Marks the end of heap cell checking for the USB Manager. Checks that the number of heap
+	cells allocated since the last __DbgMarkHeap() is aCount; the most common value to pass
+	here is zero. This function is only defined in debug builds.
+
+	@param	aCount	The expected number of heap cells allocated
+	@return	KErrNone if successful, otherwise the error that occurred
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt __DbgMarkEnd(TInt aCount);
+
+	/**
+	Simulates memory allocation failure in the USB Manager. This function is only defined in
+	debug builds.
+
+	@param	aCount	The number of allocations after which memory allocation should fail
+	@return	KErrNone if successful, otherwise the error that occurred
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt __DbgFailNext(TInt aCount);
+	
+	/**
+	Functions below this point are deprecated and should not be used.
+	*/
+
+	/**
+	Get the current state of the device's USB service. This function is deprecated and has been
+	replaced by the GetServiceState function from version 7.0s onwards.
+
+	
+	@since	7.0
+	@param	aState	Set by the method to the current state of the USB service
+
+	@return	KErrNone if successful, otherwise the error that occurred
+
+	@publishedPartner
+	@deprecated
+	*/
+	IMPORT_C TInt GetCurrentState(TUsbServiceState& aState);
+
+	/**
+	Request to be notified of a change in state of the USB device. This function is deprecated
+	and has been replaced by the DeviceStateNotification function from version 7.0s onwards.
+
+	
+	@since	7.0
+	@param	aStateMask	State mask of the states the client is interested in	
+	@param	aState		State variable to be written to upon completion of the request
+	@param	aStatus		Status to complete when required state change occurs
+
+	@publishedPartner
+	@deprecated
+	*/
+	IMPORT_C void StateNotification(
+		TUint aStateMask,
+		TUsbDeviceState& aState,
+		TRequestStatus& aStatus
+	);
+
+	/**
+	Cancel the outstanding device state notification request. This function is deprecated and
+	has been replaced by the DeviceStateNotificationCancel function from version 7.0s onwards.
+
+	
+	@since 7.0
+
+	@publishedPartner
+	@deprecated
+	*/
+	IMPORT_C void StateNotificationCancel();
+
+	/**
+	* Set or reset the mode in which current RUsb session operates.
+	* Recent implementation assumes that there is the one and only application
+	* which controls USBMAN, all other clients act as listeners to notification 
+	* requests. Only application which was previously granted 'control' mode is 
+	* allowed to reset it at later stage. Any calls from other applications will
+	* generate an error.
+	*
+	* @param	aValue		True to inform USBMAN that Application wants to 'control' 
+	*						USBMAN
+	*						False otherwise
+	*
+	* @capability NetworkControl
+	* @return	KErrNone		 if successful
+	*			KErrAccessDenied otherwise
+	*/
+	IMPORT_C TInt SetCtlSessionMode(TBool aValue);
+
+	/**
+	* Cable watcher wants to assert Bus_request.
+	* If ID-Pin is present this is an A-Device and this will result in an attempt 
+	* to raise VBus. Second attempt to raise VBus causes KErrUsbOtgVbusAlreadyRaised
+	* error.
+	* If ID-Pin is absent this is a B-Device and this will result in an attempt to 
+	* use SRP. Recently does nothing
+	* 
+	* When BusRequest() returns an error, VBus remains low until the errors are cleared by
+	* BusDrop() or BusClearErr() calls 
+	* 
+	* @capability NetworkControl
+	* @return KErrNone if successful, otherwise an error code returned by OTGDI
+	*/
+	IMPORT_C TInt BusRequest();
+
+	/**
+	* Cable watcher wants to assert Bus_request after SRP.
+	* If ID-Pin is present this is an A-Device and this will result in an attempt 
+	* to raise VBus
+	* 
+	* @capability NetworkControl
+	* @return KErrNone if successful, otherwise an error code returned by OTGDI
+	*/
+	IMPORT_C TInt BusRespondSrp();
+
+	/**
+	* Cable watcher wants to clear the Bus Error after A_VBUS_ERR
+	* Only works if ID-Pin is present (this is an A-Device) and there
+	* has already been a bus erorr.
+	* This will not result in any attempt to raise or drop VBus
+	* 
+	* @capability NetworkControl
+	* @return KErrNone if successful, otherwise an error code returned by OTGDI
+	*/
+	IMPORT_C TInt BusClearError();
+
+	/**
+	* Cable watcher wants to drop VBus.
+	* If ID-Pin is present this is an A-Device and this will result in stopping VBus 
+	* power-up
+	* 
+	* @capability NetworkControl
+	* @return KErrNone if successful, otherwise an error code returned by OTGDI
+	*/
+	IMPORT_C TInt BusDrop();
+	
+	/**
+	* Register for Messages notifications
+	* The request only completes when the new message arrives.
+	* Calling this function the first time initializes Messages queue
+	* 
+	*
+	* @param	aMessage	UI Message variable to be written to upon completion 
+	* 						of the request
+	* @param	aStatus		Status to complete when required state change occurs
+	*			KErrNone	- if successful
+	*			KErrInUse	- if there is another outstanding nofitication request 
+	* 						  for the same session
+	*			otherwise an error code returned by OTGDI or Host
+	*/
+	IMPORT_C void MessageNotification(TRequestStatus& aStatus, TInt& aMessage);
+
+	/**
+	* Cancel the outstanding Messages notification request.
+	*/
+	IMPORT_C void MessageNotificationCancel();
+
+	/**
+	* Register for Host Device Event notifications.
+	* The request only completes when the host event occurs.
+	* Calling this function the first time initializes Host Events queue
+	*
+	* @param	aStatus		Status to complete when required event occurs
+	* 
+	*			KErrNone	- if successful
+	*			KErrInUse	- if there is another outstanding nofitication 
+	*						  request for the same session
+	*			otherwise an error code returned by FDF
+	* @param	aDeviceInformation	device info to be written to upon completion 
+	*								of the request
+	*/
+	IMPORT_C void HostEventNotification(TRequestStatus& aStatus,
+										TDeviceEventInformation& aDeviceInformation);
+	/**
+	* Cancel the outstanding FDF Device Event notification request.
+	*/
+	IMPORT_C void HostEventNotificationCancel();
+
+	/**
+	* Enable Function Driver Loading.
+	*
+	* @capability NetworkControl
+	* @return	KErrNone		 - if successful
+	*			KErrNotSupported - if FDF is not included in current configuration
+	*			otherwise an error code returned by FDF
+	*/
+	IMPORT_C TInt EnableFunctionDriverLoading();
+
+	/**
+	* Disable Function Driver Loading.
+	*
+	* @capability NetworkControl
+	*/
+	IMPORT_C void DisableFunctionDriverLoading();
+
+	/**
+	* Get Supported Languages from USB Device
+	*
+	* @param	aDeviceId	DeviceID of given device
+	* @param	aLangIds	an array of language IDs supported by given device.
+	*						These language IDs are supplied by USB-IF and are 
+	*						different from standard Symbian TLanguage enumeration
+	*
+	* @return	KErrNone		 - if successful
+	*			otherwise an error code returned by FDF
+	*/
+	IMPORT_C TInt GetSupportedLanguages(TUint aDeviceId, RArray<TUint>& aLangIds);
+
+	/**
+	* Get Manufacturer Descriptor
+	*
+	* @param	aDeviceId	DeviceID of given device
+	* @param	aLangId		required language ID which is supplied by USB-IF and is 
+	*						different from standard Symbian TLanguage enumeration
+	* @param	aString		manufacturer descriptor value at output
+	*
+	* @return	KErrNone		 - if successful
+	*			otherwise an error code returned by FDF
+	*/
+	IMPORT_C TInt GetManufacturerStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString);
+
+	/**
+	* Get Product Descriptor
+	*
+	* @param	aDeviceId	DeviceID of given device
+	* @param	aLangId		required language ID which is supplied by USB-IF and is 
+	*						different from standard Symbian TLanguage enumeration
+	* @param	aString		product descriptor value at output
+	*
+	* @return	KErrNone		 - if successful
+	*			otherwise an error code returned by FDF
+	*/
+	IMPORT_C TInt GetProductStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString);
+		
+	/**
+	* Retrieve Otg Descriptor for device which has given device Id.
+	* Currently TOtgDescriptor has following fields:
+	*  - HNP supported
+	*  - SRP supported
+	* An OTG device should support them both. 
+	*
+	* @param	aDeviceId	DeviceID of given device
+	* @param	aDescriptor OTG descriptor value at output
+	*
+	* @return	KErrNone		 - if successful
+	*			otherwise an error code returned by FDF
+	*/
+	IMPORT_C TInt GetOtgDescriptor(TUint aDeviceId, TOtgDescriptor& aDescriptor);
+	
+	/**
+	Simulates memory allocation in the USB Manager. This function is only defined in
+	debug builds.
+
+	@return	KErrNone if successful, otherwise the error that occurred
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt __DbgAlloc();
+	
+	/**
+	Informs USB Manager that the client would like to initialte USB session.
+	On A-Device, it results in sending a notification to 'controller' application
+	On B-Device, it may trigger either SRP or HNP sequence depending on the state of VBus 
+
+	@return	KErrNone if successful, otherwise the error that occurred
+
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt RequestSession();
+	
+
+	/**
+	Gets the property of the personality identified by the aPersonalityId.
+
+	@param  aPersonalityId a personality id
+	@return the personality property
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt GetPersonalityProperty(TInt aPersonalityId, TUint32& aProperty);
+
+	/**
+	Gets the detailed textual description of the personality identified by the aPersonalityId.
+	Caller is repsonsible for freeing up memories allocated to 
+	aLocalizedPersonalityDescriptor.
+
+	@param  aPersonalityId a personality id
+	@param  aLocalizedPersonalityDescriptor a localize text string
+	@return KErrNone if successful, otherwise the error that occurred
+	@publishedPartner
+	@released
+	*/
+	IMPORT_C TInt GetDetailedDescription(TInt aPersonalityId, HBufC*& aLocalizedPersonalityDescriptor);
+	
+private:
+	/** 
+	Used to register device state notifications.
+	*/
+	TPckg<TUint32> iDeviceStatePkg;
+
+	/** 
+	Used to register service state notifications.
+	*/
+	TPckg<TUint32> iServiceStatePkg;
+
+	/**
+	Used to register OTG/Host message notifications.
+	*/
+	TPckg<TUint32> iMessagePkg;
+
+	/**
+	Used to register Host state notifications.
+	*/
+	TPckg<TDeviceEventInformation> iHostPkg;
+	};
+
+#endif //__USBMAN_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/client/public/usbstates.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,97 @@
+/*
+* Copyright (c) 2003-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:
+* State enumerations for the RUsb Client side header
+*
+*/
+
+/**
+ @file
+*/
+
+#ifndef __USBSTATES_H__
+#define __USBSTATES_H__
+
+#include <e32def.h>
+
+/** TUsbServiceState
+
+	Enumeration of all the USB service states.
+
+	@publishedPartner
+	@released
+*/
+enum TUsbServiceState
+	{
+	/** EUsbServiceIdle 
+		The service is not started.
+	*/
+	EUsbServiceIdle        = 0x01,
+	
+	/** EUsbServiceStarting */
+	EUsbServiceStarting    = 0x02,
+	
+	/** EUsbServiceStarted */
+	EUsbServiceStarted     = 0x04,
+	
+	/** EUsbServiceStopping */
+	EUsbServiceStopping    = 0x08,
+
+	/** EUsbServiceFatalError */
+	EUsbServiceFatalError  = 0x10
+	};
+
+/** TUsbDeviceState
+
+	Enumeration of all of the states of the USB device.
+	The states reported are dependent on the hardware.
+
+	*** If this changes update KUsbDeviceStates below ***
+
+	@publishedPartner
+	@released
+*/
+enum TUsbDeviceState
+	{
+	/** EUsbDeviceStateUndefined */
+	EUsbDeviceStateUndefined  = 0x00,
+
+	/** EUsbDeviceStateDefault */
+	EUsbDeviceStateDefault    = 0x01,
+
+	/** EUsbDeviceStateAttached */
+	EUsbDeviceStateAttached   = 0x02,
+
+	/** EUsbDeviceStatePowered */
+	EUsbDeviceStatePowered    = 0x04,
+
+	/** EUsbDeviceStateConfigured */
+	EUsbDeviceStateConfigured = 0x08,
+
+	/** EUsbDeviceStateAddress */
+	EUsbDeviceStateAddress    = 0x10,
+
+	/** EUsbDeviceStateSuspended */
+	EUsbDeviceStateSuspended  = 0x20
+	};
+
+/**
+Number of different USB Device States
+
+@publishedPartner
+*/
+const TInt KUsbDeviceStates = 7;
+
+
+#endif //__USBSTATES_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/extensionplugin/BWINS/usbmanextensionpluginu.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,8 @@
+EXPORTS
+	??0CUsbmanExtensionPlugin@@IAE@AAVMUsbmanExtensionPluginObserver@@@Z @ 1 NONAME ; CUsbmanExtensionPlugin::CUsbmanExtensionPlugin(class MUsbmanExtensionPluginObserver &)
+	??1CUsbmanExtensionPlugin@@UAE@XZ @ 2 NONAME ; CUsbmanExtensionPlugin::~CUsbmanExtensionPlugin(void)
+	?DevUsbcClient@MUsbmanExtensionPluginObserver@@QAEAAVRDevUsbcClient@@XZ @ 3 NONAME ; class RDevUsbcClient & MUsbmanExtensionPluginObserver::DevUsbcClient(void)
+	?NewL@CUsbmanExtensionPlugin@@SAPAV1@VTUid@@AAVMUsbmanExtensionPluginObserver@@@Z @ 4 NONAME ; class CUsbmanExtensionPlugin * CUsbmanExtensionPlugin::NewL(class TUid, class MUsbmanExtensionPluginObserver &)
+	?Observer@CUsbmanExtensionPlugin@@IAEAAVMUsbmanExtensionPluginObserver@@XZ @ 5 NONAME ; class MUsbmanExtensionPluginObserver & CUsbmanExtensionPlugin::Observer(void)
+	?RegisterStateObserverL@MUsbmanExtensionPluginObserver@@QAEXAAVMUsbDeviceNotify@@@Z @ 6 NONAME ; void MUsbmanExtensionPluginObserver::RegisterStateObserverL(class MUsbDeviceNotify &)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/extensionplugin/EABI/usbmanextensionpluginu.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,12 @@
+EXPORTS
+	_ZN22CUsbmanExtensionPlugin4NewLE4TUidR30MUsbmanExtensionPluginObserver @ 1 NONAME
+	_ZN22CUsbmanExtensionPlugin8ObserverEv @ 2 NONAME
+	_ZN22CUsbmanExtensionPluginC2ER30MUsbmanExtensionPluginObserver @ 3 NONAME
+	_ZN22CUsbmanExtensionPluginD0Ev @ 4 NONAME
+	_ZN22CUsbmanExtensionPluginD1Ev @ 5 NONAME
+	_ZN22CUsbmanExtensionPluginD2Ev @ 6 NONAME
+	_ZN30MUsbmanExtensionPluginObserver13DevUsbcClientEv @ 7 NONAME
+	_ZN30MUsbmanExtensionPluginObserver22RegisterStateObserverLER16MUsbDeviceNotify @ 8 NONAME
+	_ZTI22CUsbmanExtensionPlugin @ 9 NONAME ; #<TI>#
+	_ZTV22CUsbmanExtensionPlugin @ 10 NONAME ; #<VT>#
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/extensionplugin/group/UsbManExtensionPlugin.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* 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 "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:
+* usbmanextensionplugin.dll Base DLL for UsbMan extension plugins
+* Plugins to UsbMan.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+TARGET			usbmanextensionplugin.dll
+TARGETTYPE		dll
+// UID2 = 0x1000008d for static interface DLLs.
+// UID3 = unique for UsbMan system
+UID 			0x1000008d 0x101f9067
+VENDORID		0x70000001
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+
+SOURCEPATH		../src
+SOURCE			CUsbManExtensionPlugin.cpp
+SOURCE			MUsbManExtensionPluginObserver.cpp
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY 		euser.lib
+LIBRARY 		ecom.lib
+
+//macro __USB_LOG_TO_RDEBUG__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/extensionplugin/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+PRJ_EXPORTS
+../public/CUsbManExtensionPlugin.h				SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(cusbmanextensionplugin.h)
+../public/MUsbManExtensionPluginObserver.h		SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(musbmanextensionpluginobserver.h)
+
+PRJ_MMPFILES
+UsbManExtensionPlugin.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/extensionplugin/public/CUsbManExtensionPlugin.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,87 @@
+/*
+* 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 "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:
+* Abstract base class for usbman extension plugins.
+*
+*/
+
+/**
+ @file
+ @publishedPartner
+ @released
+*/
+
+#ifndef USBMANEXTENSIONPLUGIN_H
+#define USBMANEXTENSIONPLUGIN_H
+
+#include <e32base.h>
+#include <d32usbc.h>
+
+class MUsbmanExtensionPluginObserver;
+class MUsbDeviceNotify;
+
+/**
+The UID of the Usbman Extension Plugin interface.
+*/
+const TInt KUsbmanExtensionPluginInterfaceUid = 0x10208DD6;
+
+class CUsbmanExtensionPlugin : public CBase
+	{
+public:
+	/** 
+	Constructor.
+	@param aImplementationUid The UID of the implementation.
+	@param aObserver The observer of the plugin.
+	*/
+	IMPORT_C static CUsbmanExtensionPlugin* NewL(const TUid aImplementationUid, 
+		MUsbmanExtensionPluginObserver& aObserver);
+
+	/** Destructor. */
+	IMPORT_C ~CUsbmanExtensionPlugin();
+
+public:
+	/**
+	Called by Usbman server to get a pointer to an object which implements the 
+	ExtensionPlugin interface with UID aUid. This is a mechanism for allowing future 
+	change to the plugin API without breaking BC in existing (non-updated) 
+	plugins.
+	*/
+	virtual TAny* GetInterface(TUid aUid) = 0;
+
+protected:
+	/** 
+	Constructor.
+	@param aObserver The observer of the plugin.
+	*/
+	IMPORT_C CUsbmanExtensionPlugin(MUsbmanExtensionPluginObserver& aObserver);
+
+protected:
+	/**
+	Accessor for the observer.
+	@return The observer.
+	*/
+	IMPORT_C MUsbmanExtensionPluginObserver& Observer();
+
+private: // owned
+	/**
+	UID set by ECOM when the instance is created. Used when the instance is 
+	destroyed.
+	*/
+	TUid iInstanceId;
+
+private: // unowned
+	MUsbmanExtensionPluginObserver& iObserver;
+	};
+
+#endif // USBMANEXTENSIONPLUGIN_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/extensionplugin/public/MUsbManExtensionPluginObserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,61 @@
+/*
+* 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 "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:
+* Interface presented by Usbman down to the concrete Usbman Extension Plugins.
+*
+*/
+
+/**
+ @file
+ @publishedPartner
+ @released
+*/
+
+#ifndef USBMANEXTENSIONPLUGINOBSERVER_H
+#define USBMANEXTENSIONPLUGINOBSERVER_H
+
+#include <e32base.h>
+#include <d32usbc.h>
+
+class MUsbDeviceNotify;
+
+class MUsbmanExtensionPluginObserver
+	{
+
+public:
+	/**
+	Called by the plugin to get a RDevUsbcClient handle from its owner
+	@return RDevUsbcClient handle
+	*/
+	IMPORT_C RDevUsbcClient& DevUsbcClient();
+
+	/**
+	Called by the plugin to register for device/service state changes from its owner
+	@param aObserver The observer to register for state changes
+	*/
+	IMPORT_C void RegisterStateObserverL(MUsbDeviceNotify& aObserver);
+
+private:
+	/**
+	@see DevUsbcClient.
+	*/
+	virtual RDevUsbcClient& MuepoDoDevUsbcClient() = 0;
+
+	/**
+	@see RegisterStateObserverL.
+	*/
+	virtual void MuepoDoRegisterStateObserverL(MUsbDeviceNotify& aObserver) = 0;
+	};
+
+#endif // USBMANEXTENSIONPLUGINOBSERVER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/extensionplugin/src/CUsbManExtensionPlugin.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,52 @@
+/*
+* 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 "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:
+* Implementation of Usbman extension plugin.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "cusbmanextensionplugin.h"
+#include "musbmanextensionpluginobserver.h"
+#include <ecom/ecom.h>
+
+EXPORT_C CUsbmanExtensionPlugin::~CUsbmanExtensionPlugin()
+	{
+	REComSession::DestroyedImplementation(iInstanceId);
+	}
+
+EXPORT_C CUsbmanExtensionPlugin::CUsbmanExtensionPlugin(MUsbmanExtensionPluginObserver& aObserver)
+:	iObserver(aObserver)
+	{
+	}
+
+EXPORT_C CUsbmanExtensionPlugin* CUsbmanExtensionPlugin::NewL(const TUid aImplementationUid, MUsbmanExtensionPluginObserver& aObserver)
+	{
+	return reinterpret_cast<CUsbmanExtensionPlugin*>(
+		REComSession::CreateImplementationL(
+			aImplementationUid, 
+			_FOFF(CUsbmanExtensionPlugin, iInstanceId),
+			(TAny*)&aObserver)
+		);
+	}
+
+EXPORT_C MUsbmanExtensionPluginObserver& CUsbmanExtensionPlugin::Observer()
+	{
+	return iObserver;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/extensionplugin/src/MUsbManExtensionPluginObserver.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/*
+* 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 "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:
+* Implementation of interface presented by Usbman down to the concrete Usbman Extension Plugins.
+*
+*/
+
+/**
+ @file
+ @publishedPartner
+ @released
+*/
+
+#include "musbmanextensionpluginobserver.h"
+
+EXPORT_C RDevUsbcClient& MUsbmanExtensionPluginObserver::DevUsbcClient()
+	{
+	return MuepoDoDevUsbcClient();
+	}
+
+EXPORT_C void MUsbmanExtensionPluginObserver::RegisterStateObserverL(MUsbDeviceNotify& aObserver)
+	{
+	MuepoDoRegisterStateObserverL(aObserver);
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/CPersonality.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,89 @@
+/**
+* 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 "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:
+* Implements a utility class which holds the information about a USB descriptor
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CPERSONALITY_H__
+#define __CPERSONALITY_H__
+
+#include <e32std.h>
+#include "CUsbDevice.h"
+
+NONSHARABLE_CLASS(CPersonality) : public CBase
+	{
+public:
+	static CPersonality* NewL();
+	~CPersonality();
+
+	TInt PersonalityId() const;
+	const RArray<TUid>& SupportedClasses() const;
+	TInt ClassSupported(TUid aClassId) const;
+	const CUsbDevice::TUsbDeviceDescriptor& DeviceDescriptor() const; 	
+	CUsbDevice::TUsbDeviceDescriptor& DeviceDescriptor(); 	
+	const TDesC* Manufacturer() const;
+	const TDesC* Product() const;
+	const TDesC* Description() const;
+	TInt AddSupportedClasses(TUid aClassId);
+	void SetId(TInt aId);
+	void SetManufacturer(const TDesC* aManufacturer);
+	void SetProduct(const TDesC* aProduct);
+	void SetDescription(const TDesC* aDescription);
+	static TInt Compare(const TUid&  aFirst, const TUid& aSecond);
+
+	const TDesC* DetailedDescription() const;
+	void SetDetailedDescription(const TDesC* aDetailedDescription);
+
+	TUint32 Property() const;
+	void SetProperty(TUint32 aProperty);
+	
+	TInt Version() const;
+	void SetVersion(TInt version);
+    
+private:
+	CPersonality();
+	void ConstructL();
+
+private:
+	// personality id
+	TInt								iId;
+	// USB class ids
+	RArray<TUid>						iClassUids;
+	// textual description of manufacturer
+	HBufC*								iManufacturer;
+	// textual description of product	
+	HBufC*								iProduct;
+	// textual description of personality
+	HBufC*								iDescription;
+	// USB device descriptor struct	
+	CUsbDevice::TUsbDeviceDescriptor 	iDeviceDescriptor;
+	// detailed textual description of personality
+	HBufC*                              	iDetailedDescription;
+    
+	TInt                                	iVersion;
+	TUint32								iProperty;
+	};
+
+#include "CPersonality.inl"
+	
+#endif // __CPERSONALITY_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/CPersonality.inl	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,120 @@
+/**
+* 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 "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:
+* Implements a utitility class which holds the information about a USB device personality
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CPERSONALITY_INL__
+#define __CPERSONALITY_INL__
+
+/**
+ * @internalComponent
+ * @return personality id
+ */ 
+inline TInt CPersonality::PersonalityId() const
+	{
+	return iId;
+	}
+	
+/**
+ * @internalComponent
+ * @return supported class uids
+ */
+inline const RArray<TUid>& CPersonality::SupportedClasses() const
+	{
+	return iClassUids;
+	}
+	
+/**
+ * @internalComponent
+ * @return a const reference to device descriptor
+ */
+inline const CUsbDevice::TUsbDeviceDescriptor& CPersonality::DeviceDescriptor() const 	
+	{
+	return iDeviceDescriptor;
+	}
+
+/**
+ * @internalComponent
+ * @return a const reference to device descriptor
+ */
+inline CUsbDevice::TUsbDeviceDescriptor& CPersonality::DeviceDescriptor() 	
+	{
+	return iDeviceDescriptor;
+	}
+
+/**
+ * @internalComponent
+ * @return a const pointer to manufacturer string
+ */
+inline const TDesC* CPersonality::Manufacturer() const
+	{
+	return iManufacturer;
+	}
+	
+/** 
+ * @internalComponent 
+ * @return a const pointer to product string
+ */
+inline const TDesC* CPersonality::Product() const
+	{
+	return iProduct;
+	}
+	
+/**
+ * @internalComponent
+ * @return a const pointer to description string
+ */
+inline const TDesC* CPersonality::Description() const
+	{
+	return iDescription;
+	}
+
+/**
+ * @internalComponent
+ * @return a const pointer to detailed description string
+ */
+inline const TDesC* CPersonality::DetailedDescription() const
+	{
+	return iDetailedDescription;
+	}
+
+
+/**
+ * @internalComponent
+ * @return version
+ */ 
+inline TInt CPersonality::Version() const
+	{
+	return iVersion;
+	}
+
+/**
+ * @internalComponent
+ * @return the property information
+ */
+inline TUint32 CPersonality::Property() const
+	{
+	return iProperty;
+	}
+#endif // __PERSONALITY_INL__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/CUsbDevice.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,177 @@
+/**
+* Copyright (c) 1997-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:
+* Implements the main object of Usbman that manages all the USB Classes
+* and the USB Logical Device (via CUsbDeviceStateWatcher).
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBDEVICE_H__
+#define __CUSBDEVICE_H__
+
+#include <usbstates.h>
+#include <musbclasscontrollernotify.h>
+#include <ecom/ecom.h>
+#include <d32usbc.h>
+#include <e32std.h>
+#include <usb/usblogger.h>
+#include <musbmanextensionpluginobserver.h>
+
+class CUsbDeviceStateWatcher;
+class CUsbClassControllerBase;
+class CUsbServer;
+class MUsbDeviceNotify;
+class CPersonality;
+class CUsbmanExtensionPlugin;
+
+const TUid KUidUsbPlugIns = {0x101fbf21};
+
+/**
+ * The CUsbDevice class
+ *
+ * Implements the main object of Usbman that manages all the USB Classes
+ * and the USB Logical Device (via CUsbDeviceStateWatcher).
+ * It owns one instance of CUsbDeviceStateWatcher and an instance of each USB 
+ * Class Controller (CUsbClassControllerBase derived).
+ * It also owns an instance of RDevUsbcClient, a handle on the logical device
+ * driver for USB for Symbian OS.
+ * It implements the MUsbClassControllerNotify mixin so all Usb Class
+ * Controllers can notify it of any changes in their state.
+ *
+ * CUsbDevice is an active object which starts and stops Usb Class Controllers
+ * asynchronously, one by one. Its RunL function will be called after each
+ * start/stop.
+ */
+NONSHARABLE_CLASS(CUsbDevice) : public CActive, public MUsbClassControllerNotify, public MUsbmanExtensionPluginObserver
+	{
+public:
+	class TUsbDeviceDescriptor
+		{
+	public:
+		TUint8	iLength;
+		TUint8  iDescriptorType;
+		TUint16	iBcdUsb;
+		TUint8  iDeviceClass;
+		TUint8  iDeviceSubClass;
+		TUint8  iDeviceProtocol;
+		TUint8  iMaxPacketSize;
+		TUint16 iIdVendor;
+		TUint16	iIdProduct;
+		TUint16	iBcdDevice;
+		TUint8  iManufacturer;
+		TUint8  iProduct;
+		TUint8  iSerialNumber;
+		TUint8  iNumConfigurations;
+		};
+
+public:
+	static CUsbDevice* NewL(CUsbServer& aUsbServer);
+	virtual ~CUsbDevice();
+
+ 	void EnumerateClassControllersL();
+	void AddClassControllerL(CUsbClassControllerBase* aClassController, TLinearOrder<CUsbClassControllerBase> order);
+
+	void RegisterObserverL(MUsbDeviceNotify& aObserver);
+	void DeRegisterObserver(MUsbDeviceNotify& aObserver);
+
+	void StartL();
+	void Stop();
+
+	inline TInt LastError() const;
+	inline RDevUsbcClient& UsbBus();
+	inline TUsbDeviceState DeviceState() const;
+	inline TUsbServiceState ServiceState() const;
+	inline TBool isPersonalityCfged() const;
+	
+	void SetServiceState(TUsbServiceState aState);
+	void SetDeviceState(TUsbcDeviceState aState);
+
+	void BusEnumerationCompleted();
+	void BusEnumerationFailed(TInt aError);
+	
+	void TryStartL(TInt aPersonalityId);
+	TInt CurrentPersonalityId() const;
+	const RPointerArray<CPersonality>& Personalities() const;
+	const CPersonality* GetPersonality(TInt aPersonalityId) const;
+	void ValidatePersonalitiesL();
+	void ReadPersonalitiesL();
+	void SetDefaultPersonalityL();
+	void LoadFallbackClassControllersL();
+	
+public: // From CActive
+	void RunL();
+	void DoCancel();
+	TInt RunError(TInt aError);
+
+public: // Inherited from MUsbClassControllerNotify
+	CUsbClassControllerIterator* UccnGetClassControllerIteratorL();
+	void UccnError(TInt aError);
+
+public: // from MUsbmanExtensionPluginObserver
+	RDevUsbcClient& MuepoDoDevUsbcClient();
+	void MuepoDoRegisterStateObserverL(MUsbDeviceNotify& aObserver);
+
+protected:
+	CUsbDevice(CUsbServer& aUsbServer);
+	void ConstructL();
+	void StartCurrentClassController();
+	void StopCurrentClassController();
+
+private:
+	void SetDeviceDescriptorL();
+	void SetUsbDeviceSettingsL(TUsbDeviceDescriptor& aDeviceDescriptor);
+	void SetUsbDeviceSettingsDefaultsL(TUsbDeviceDescriptor& aDeviceDescriptor);
+	void SelectClassControllersL();
+	void SetCurrentPersonalityL(TInt aPersonalityId);
+	void SetUsbDeviceSettingsFromPersonalityL(CUsbDevice::TUsbDeviceDescriptor& aDeviceDescriptor);
+	void ResourceFileNameL(TFileName& aFileName);
+	void CreateClassControllersL(const RArray<TUid>& aClassUids);
+	void ConvertUidsL(const TDesC& aStr, RArray<TUint>& aUidArray);
+	TInt PowerUpAndConnect();	
+#ifdef __FLOG_ACTIVE
+	void PrintDescriptor(CUsbDevice::TUsbDeviceDescriptor& aDeviceDescriptor);
+#endif
+	void InstantiateExtensionPluginsL();
+private:
+	RPointerArray<CUsbClassControllerBase> iSupportedClasses;
+	RPointerArray<MUsbDeviceNotify> iObservers;
+	RPointerArray<CUsbmanExtensionPlugin> iExtensionPlugins;
+	TUsbDeviceState  iDeviceState;
+	TUsbServiceState iServiceState;
+	TInt iLastError;
+	RDevUsbcClient iLdd;
+	CUsbDeviceStateWatcher* iDeviceStateWatcher;
+	CUsbServer& iUsbServer;
+	CUsbClassControllerIterator* iUsbClassControllerIterator;
+	const CPersonality* iCurrentPersonality;
+	RPointerArray<CPersonality> iSupportedPersonalities;
+	RArray<TUid> iSupportedClassUids;
+	TBool iPersonalityCfged;
+	TBool iUdcSupportsCableDetectWhenUnpowered;
+	HBufC16* iDefaultSerialNumber;
+	
+	REComSession* iEcom;	//	Not to be deleted, only closed!
+	};
+
+#include "CUsbDevice.inl"
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/CUsbDevice.inl	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,101 @@
+/**
+* Copyright (c) 1997-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:
+* Implements the main object of UsbMan that manages all the USB Classes
+* and the USB Logical Device (via CUSBDeviceHandler and CUSBStateWatcher).
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBDEVICE_INL__
+#define __CUSBDEVICE_INL__
+
+
+/**
+ * The CUsbDevice::LastError method
+ *
+ * Fetch the last error that occurred
+ *
+ * @internalComponent
+ *
+ * @return	Last error that occurred, KErrNone if no error
+ */
+inline TInt CUsbDevice::LastError() const
+	{
+	return iLastError;
+	}
+
+
+/**
+ * The CUsbDevice::UsbBus method
+ *
+ * Fetch a reference to the USB Logical Device Device
+ *
+ * @internalComponent
+ *
+ * @return	A reference to the USB Logical Device Device
+ */
+inline RDevUsbcClient& CUsbDevice::UsbBus()
+	{
+	return iLdd;
+	}
+
+
+/**
+ * The CUsbDevice::DeviceState method
+ *
+ * Fetch the device's current state
+ *
+ * @internalComponent
+ *
+ * @return	Device's current state
+ */
+inline TUsbDeviceState CUsbDevice::DeviceState() const
+	{
+	return iDeviceState;
+	}
+
+/**
+ * The CUsbDevice::ServiceState method
+ *
+ * Fetch the device's current state
+ *
+ * @internalComponent
+ *
+ * @return	Device's current service state
+ */
+inline TUsbServiceState CUsbDevice::ServiceState() const
+	{
+	return iServiceState;
+	}
+
+/**
+ * Checks if personalities are configured for the device
+ *
+ * @internalComponent 
+ * @return ETrue or EFalse
+ */
+ 
+inline TBool CUsbDevice::isPersonalityCfged() const
+	{
+	return iPersonalityCfged;
+	}
+	
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/CUsbDeviceStateWatcher.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,67 @@
+/**
+* Copyright (c) 1997-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:
+* Talks directly to the USB Logical Device Driver (LDD) and 
+* watches any state changes
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBDEVICESTATEWATCHER_H__
+#define __CUSBDEVICESTATEWATCHER_H__
+
+#include <e32def.h>
+
+class CUsbDevice;
+class RDevUsbcClient;
+
+/**
+ * The CUsbDeviceStateWatcher class
+ *
+ * Talks directly to the USB Logical Device Driver (LDD) and 
+ * watches any state changes
+ */
+NONSHARABLE_CLASS(CUsbDeviceStateWatcher) : public CActive
+	{
+public:
+	static CUsbDeviceStateWatcher* NewL(CUsbDevice& aOwner, RDevUsbcClient& aLdd);
+	virtual ~CUsbDeviceStateWatcher();
+
+	inline CUsbDevice& Owner() const;
+
+	// From CActive
+	virtual void RunL();
+	virtual void DoCancel();
+
+	virtual void Start();
+
+protected:
+	CUsbDeviceStateWatcher(CUsbDevice& aOwner, RDevUsbcClient& aLdd);
+
+private:
+	CUsbDevice& iOwner;
+	RDevUsbcClient& iLdd;
+	TUint iState;
+	};
+
+#include "CUsbDeviceStateWatcher.inl"
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/CUsbDeviceStateWatcher.inl	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,45 @@
+/**
+* Copyright (c) 1997-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:
+* Talks directly to the USB Logical Device Driver (LDD) and 
+* watches any state changes
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBDEVICESTATEWATCHER_INL__
+#define __CUSBDEVICESTATEWATCHER_INL__
+
+
+/**
+ * The CUsbDeviceStateWatcher::Owner method
+ *
+ * Fetch the device that owns this state watcher
+ *
+ * @internalComponent
+ *
+ * @return	The device that owns this state watcher
+ */
+inline CUsbDevice& CUsbDeviceStateWatcher::Owner() const
+	{
+	return iOwner;
+	}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/CUsbDummyClassController.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,123 @@
+/**
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class Controller API.
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef CUSBDUMMYCLASSCONTROLLER_H__
+#define CUSBDUMMYCLASSCONTROLLER_H__
+
+#include <cusbclasscontrollerbase.h>
+
+class CIniFile;
+
+NONSHARABLE_CLASS(CUsbDummyClassController) : public CUsbClassControllerBase
+/**
+ * A test utility which, depending on the contents of c:\\dummy.ini, displays 
+ * different start up and shutdown behaviour.
+ * The USB manager can instantiate a number of instances of this class 
+ * controller. Each one reads its behaviour from a section of dummy.ini. The 
+ * options are, for each of startup and shutdown: (a) synchronous or 
+ * asynchronous, (b) completing after a variable amount of time, or 
+ * immediately, or never, and (c) completing with a given error code.
+ * NB This class controller is a dummy- it does not communicate with a class 
+ * implementation. It registers no USB interfaces.
+ * Note that for each of startup and shutdown, Type, Time and Error *must* be 
+ * filled in, even if one or more are irrelevant. They are applied in the 
+ * following order: Type, Time, Error. That is, if Type is 'never', the CC 
+ * never completes, but it does this asynchronously, i.e. without blocking the 
+ * CC's (=USBMAN's) thread. If Time is '0', it completes after a synchronous 
+ * or asynchronous wait for 0 microseconds (as determined by the Type). 
+ * Note that the ini file is re-read whenever Start or Stop is requested. 
+ * Otherwise, a CC which is set to not Stop would stop us being able to Stop, 
+ * ever, or shut down USBMAN, which would make wrapping up the test framework 
+ * impossible.
+ * Note that we inherit the TUsbServiceState iState member of 
+ * CUsbClassControllerBase. We only use this to mark whether we're currently 
+ * starting or stopping, or doing nothing. Requests from the device may come 
+ * in at any point- the only proviso is that we are always Cancelled before 
+ * another Start or Stop comes in first (this is enforced by us through 
+ * iReportStatus). It happens that it's useless to assert our iState in Start 
+ * and Stop.
+ */
+	{
+public:
+	static CUsbDummyClassController* NewL(MUsbClassControllerNotify& aOwner, TUint aIndex);
+	static CUsbDummyClassController* NewL(MUsbClassControllerNotify& aOwner, TUint aIndex, TInt aPriority);
+	~CUsbDummyClassController();
+
+private:
+	CUsbDummyClassController(MUsbClassControllerNotify& aOwner, TUint aIndex);
+	CUsbDummyClassController(MUsbClassControllerNotify& aOwner,TUint aIndex, TInt aPriority);
+	void ConstructL();
+
+private: // from CActive
+	void RunL();
+	void DoCancel();
+	TInt RunError(TInt aError);
+
+private: // from CUsbClassControllerBase
+	void Start(TRequestStatus& aStatus);
+	void Stop(TRequestStatus& aStatus);
+	void GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const;
+
+private:
+	enum TSynchronicity 
+		{
+		EUndefined = 0,
+		ESynchronous,
+		EAsynchronous,
+		ENever,
+		};
+	
+	NONSHARABLE_STRUCT( TBehaviour )
+	/** 
+	 * Defines the behaviour for a startup or a shutdown.
+	 */
+		{
+		TSynchronicity iSynchronicity;
+		TTimeIntervalMicroSeconds32 iDelay;
+		TInt iErrorCode;
+		};
+
+private: // utility
+	void GetConfig();
+	void GetBehaviour(CIniFile& aInifile, 
+		const TDesC& aSection, 
+		TBehaviour& aBehaviour);
+	void DoGetConfigL();
+
+private: // unowned
+	TRequestStatus* iReportStatus;
+
+private: // owned
+	RTimer iTimer;
+	// The index of this instance (USBMAN may have more than one, and this is 
+	// used to get the required behaviour for this instance from the ini 
+	// file).	
+	const TUint iIndex;
+
+	TBehaviour iStartupBehaviour;
+	TBehaviour iShutdownBehaviour;
+	};
+
+#endif // CUSBDUMMYCLASSCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/CUsbOtg.h	Tue Feb 02 02:02:59 2010 +0200
@@ -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 "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:
+* Implements the main object of Usbman that manages all the OTG-related activity
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBOTG_H__
+#define __CUSBOTG_H__
+
+#include <d32otgdi.h>
+#include <d32otgdi_errors.h>
+#include <e32std.h>
+#include <usb/usblogger.h>
+
+#include "musbinternalobservers.h"
+class CUsbServer;
+class CUsbOtgWatcher;
+class CUsbOtgIdPinWatcher;
+class CUsbOtgVbusWatcher;
+class CUsbOtgStateWatcher;
+class CUsbOtgEventWatcher;
+class CUsbOtgConnectionIdleWatcher;
+class MUsbOtgHostNotifyObserver;
+class RUsbOtgDriver;
+class CRequestSessionWatcher;
+
+
+/**
+ * The CUsbOtg class
+ *
+ * Implements the main object of Usbman that manages all OTG related functionality
+ * It owns one instance of CUsbOtgStateWatcher.
+ * It also owns an instance of RUsbOtgDriver, a handle on the logical device
+ * driver for USB OTG for Symbian OS.
+ *
+ * CUsbOtg is an active object which starts and stops internal CUsbOtgStateWatcher
+ * in order to monitor ID-Pin and VBus state. Its RunL function will be called when
+ * one of RUsbOtgDriver::TOtgEvent occurs.
+ */
+NONSHARABLE_CLASS(CUsbOtg) : public CBase, public MUsbOtgObserver
+	{
+public:
+	static CUsbOtg* NewL();
+	virtual ~CUsbOtg();
+
+	void RegisterObserverL(MUsbOtgHostNotifyObserver& aObserver);
+	void DeRegisterObserver(MUsbOtgHostNotifyObserver& aObserver);
+
+	void StartL();
+	void Stop();
+	
+	TInt BusRequest();
+	TInt BusRespondSrp();
+	
+	TInt BusClearError();
+
+	TInt BusDrop();
+
+	void NotifyOtgEvent();
+	
+public:
+	// From MUsbMessageObserver
+	virtual void NotifyMessage(TInt aMessage);
+	
+protected:
+	CUsbOtg();
+	void ConstructL();
+	TInt TranslateOtgEvent();
+
+private:
+	RPointerArray<MUsbOtgHostNotifyObserver> iObservers;
+	TInt iLastError;
+	RUsbOtgDriver iOtgDriver;
+	RUsbOtgDriver::TOtgEvent iOtgEvent;
+	CUsbOtgWatcher* iOtgWatcher;
+	CUsbOtgIdPinWatcher* iIdPinWatcher;
+	CUsbOtgVbusWatcher* iVbusWatcher;
+	CUsbOtgStateWatcher* iOtgStateWatcher;
+	CUsbOtgEventWatcher* iOtgEventWatcher;
+    CUsbOtgConnectionIdleWatcher* iOtgConnectionIdleWatcher;
+	TUint iOtgMessage;
+	CRequestSessionWatcher *iRequestSessionWatcher;
+	RCriticalSection iCriticalSection;
+	};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/CUsbScheduler.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,57 @@
+/**
+* Copyright (c) 1997-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:
+* Implements an Active Scheduler for the server to use
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBSCHEDULER_H__
+#define __CUSBSCHEDULER_H__
+
+#include <e32base.h>
+
+class CUsbServer;
+
+/**
+ * The CUsbScheduler class
+ *
+ * Implements an Active Scheduler for the server to use. This is necessary
+ * in order to provide an Error() function which does something useful instead
+ * of panicking.
+ */
+NONSHARABLE_CLASS(CUsbScheduler) : public CActiveScheduler
+	{
+public:
+	static CUsbScheduler* NewL();
+	~CUsbScheduler();
+
+	void SetServer(CUsbServer& aServer);
+
+private:
+	inline CUsbScheduler() {};
+	// from CActiveScheduler
+	void Error(TInt aError) const;
+
+public:
+	CUsbServer* iServer;
+	};
+
+#endif //__CUSBSCHEDULER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/CUsbServer.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,101 @@
+/**
+* Copyright (c) 1997-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:
+* Implements a Symbian OS server that exposes the RUsb API
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBSERVER_H__
+#define __CUSBSERVER_H__
+
+
+_LIT(KUsbSvrPncCat, "CUsbServer");
+
+enum TUsbPanicServer
+	{
+	EICSInvalidCount 			= 0x00,
+	EDCSInvalidCount 			= 0x10,
+	ELSTNSNotIdle 				= 0x20,
+	ENullPersonalityPointer 	= 0x30,
+	EMaxClassUidsBufTooSmall	= 0x40
+	};
+
+//
+// Forward declarations
+//
+class CUsbDevice;
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+class CUsbOtg;
+class CUsbHost;
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+/**
+ * The CUsbServer class
+ *
+ * Implements a Symbian OS server that exposes the RUsb API
+ */
+ NONSHARABLE_CLASS(CUsbServer) : public CPolicyServer
+	{
+public:
+	static CUsbServer* NewLC();
+	virtual ~CUsbServer();
+
+	virtual CSession2* NewSessionL(const TVersion &aVersion, const RMessage2& aMessage) const;
+	void Error(TInt aError);
+
+	inline CUsbDevice& Device() const;
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	inline CUsbOtg& Otg() const;
+	inline CUsbHost& Host() const;
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+	void IncrementSessionCount();
+	void DecrementSessionCount();
+	inline TInt SessionCount() const;
+	void LaunchShutdownTimerIfNoSessions();
+
+protected:
+	CUsbServer();
+	void ConstructL();
+	
+private:
+	CUsbDevice* iUsbDevice;
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	CUsbOtg* iUsbOtg;
+	CUsbHost* iUsbHost;
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+	TInt iSessionCount;
+	enum {KShutdownDelay = 2 * 1000 * 1000};	// 2 seconds
+	class CShutdownTimer : public CTimer
+		{
+	public:
+		CShutdownTimer();
+		void ConstructL();
+		virtual void RunL();
+		};
+	CShutdownTimer* iShutdownTimer;
+	};
+
+#include "CUsbServer.inl"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/CUsbServer.inl	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,81 @@
+/**
+* Copyright (c) 1997-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:
+* Implements a Symbian OS server that exposes the RUsb API
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBSERVER_INL__
+#define __CUSBSERVER_INL__
+
+
+/**
+ * The CUsbServer::Device method
+ *
+ * Fetch the device that the server owns
+ *
+ * @internalComponent
+ *
+ * @return	The server's device
+ */
+inline CUsbDevice& CUsbServer::Device() const
+	{
+	return *iUsbDevice;
+	}
+
+inline TInt CUsbServer::SessionCount() const
+	{
+	return iSessionCount;
+	}
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+/**
+ * The CUsbServer::Otg method
+ *
+ * Fetch the CUsbOtg object that the server owns
+ *
+ * @internalComponent
+ *
+ * @return	The OTG object
+ */
+inline CUsbOtg& CUsbServer::Otg() const
+	{
+	return *iUsbOtg;
+	}
+
+/**
+ * The CUsbServer::Host method
+ *
+ * Fetch the CUsbHost object that the server owns
+ *
+ * @internalComponent
+ *
+ * @return	The HOST object
+ */
+inline CUsbHost& CUsbServer::Host() const
+	{
+	return *iUsbHost;
+	}
+
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/CUsbSession.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,191 @@
+/**
+* Copyright (c) 1997-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:
+* Implements a Session of a Symbian OS server for the RUsb API
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBSESSION_H__
+#define __CUSBSESSION_H__
+
+#include <e32std.h>
+#include "MUsbDeviceNotify.h"
+#include <usb/usbshared.h>
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+#include "musbotghostnotifyobserver.h"
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+// device event queue size is number of device states + 1
+// (+1 so we can distinguish full & empty!)
+// (any state can only appear in the queue once)
+const TInt KDeviceStatesQueueSize = KUsbDeviceStates + 1;
+const TInt KOtgHostMessageQueueSize = KDeviceStatesQueueSize * 2;
+
+//
+// Forward declarations
+//
+class CUsbServer;
+
+/**
+ * The CUsbSession class
+ *
+ * Implements a Session of a Symbian OS server for the RUsb API
+ */
+NONSHARABLE_CLASS(CUsbSession) : public CSession2
+							   , public MUsbDeviceNotify
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+							   , public MUsbOtgHostNotifyObserver
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	{
+public:
+	static CUsbSession* NewL(CUsbServer* aServer);
+	virtual ~CUsbSession();
+
+	// CSession2
+	virtual void ServiceL(const RMessage2& aMessage);
+	virtual void CreateL();
+
+	// MUsbDeviceNotify
+	virtual void UsbDeviceStateChange(TInt aLastError, TUsbDeviceState aOldState, TUsbDeviceState aNewState);
+	virtual void UsbServiceStateChange(TInt aLastError, TUsbServiceState aOldState, TUsbServiceState aNewState);
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	// MUsbOtgHostNotifyObserver
+	virtual void UsbOtgHostMessage(TInt aMessage);
+	virtual void UsbHostEvent(TDeviceEventInformation& aDevInfo);
+
+	TInt DoRequestSession();
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+protected:
+	CUsbSession(CUsbServer* aServer);
+
+	void DispatchMessageL(const RMessage2& aMessage);
+	TInt StartDeviceL(const RMessage2& aMessage, TBool& aComplete);
+	TInt StopDeviceL(const RMessage2& aMessage, TBool& aComplete);
+	TInt StartCancel(const RMessage2& aMessage, TBool& aComplete);
+	TInt StopCancel(const RMessage2& aMessage, TBool& aComplete);
+	TInt RegisterDeviceObserver(const RMessage2& aMessage, TBool& aComplete);
+	TInt RegisterServiceObserver(const RMessage2& aMessage, TBool& aComplete);
+	TInt GetCurrentServiceState(const RMessage2& aMessage);
+	TInt GetCurrentDeviceState(const RMessage2& aMessage);
+	TInt DeRegisterServiceObserver();
+	TInt DeRegisterDeviceObserver();
+	TInt TryStartDeviceL(const RMessage2& aMessage, TBool& aComplete);
+	TInt TryStopDeviceL(const RMessage2& aMessage, TBool& aComplete);
+	TInt CancelInterest(const RMessage2& aMessage);
+	TInt GetCurrentPersonalityId(const RMessage2& aMessage);
+	TInt GetSupportedClasses(const RMessage2& aMessage);
+	TInt GetPersonalityIds(const RMessage2& aMessage);
+	TInt GetDescription(const RMessage2& aMessage);
+	TInt GetDetailedDescription(const RMessage2& aMessage);         
+	TInt ClassSupported(const RMessage2& aMessage);
+	TInt GetPersonalityProperty(const RMessage2& aMessage);         
+
+	void UsbDeviceDequeueEvent();
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	// Common functions
+	TInt SetCtlSessionMode(const RMessage2& aMessage);
+	TInt RegisterMsgObserver(const RMessage2& aMessage, TBool& aComplete);
+	TInt DeRegisterMsgObserver();
+
+	// OTG
+	TInt BusRequest();
+	TInt BusRespondSrp();
+
+	TInt BusClearError();
+
+	TInt BusDrop();
+
+	// HOST
+	TInt EnableFunctionDriverLoading();
+	TInt DisableFunctionDriverLoading();
+	TInt GetSupportedLanguages(const RMessage2& aMessage);
+	TInt GetManufacturerStringDescriptor(const RMessage2& aMessage);
+	TInt GetProductStringDescriptor(const RMessage2& aMessage);
+	TInt GetOtgDescriptor(const RMessage2& aMessage);
+
+	TInt RegisterHostObserver(const RMessage2& aMessage, TBool& aComplete);
+	TInt DeRegisterHostObserver();
+	TInt RequestSession();
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+private:
+	void HandleServiceStateChangeWhileStarting(TInt aLastError,
+		TUsbServiceState aNewState);
+	void HandleServiceStateChangeWhileStopping(TInt aLastError,
+		TUsbServiceState aNewState);
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	void UsbMsgDequeue();
+
+	void UsbHostEventDequeue();
+	TInt GetSupportedLanguagesL(const RMessage2& aMessage);
+
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+private:
+	CUsbServer* iUsbServer;
+
+	RMessage2 iStartMessage;
+	RMessage2 iStopMessage;
+	RMessage2 iCancelMessage;
+	RMessage2 iServiceObserverMessage;
+	RMessage2 iDeviceObserverMessage;
+
+	TBool iStartOutstanding;
+	TBool iStopOutstanding;
+	TBool iCancelOutstanding;
+	TBool iDeviceObserverOutstanding;
+	TBool iServiceObserverOutstanding;
+	TBool iPersonalityCfged;
+
+ 	TFixedArray<TUsbDeviceState, KDeviceStatesQueueSize> iDeviceStateQueue;
+ 	TUsbDeviceState iNotifiedDevState;
+ 	TBool iObserverQueueEvents;
+ 	TInt iDevStateQueueHead;
+ 	TInt iDevStateQueueTail;
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+ 	static CUsbSession* iCtlSession;
+ 	TBool iSessionCtlMode;
+
+	RMessage2 iMsgObserverMessage;
+	TBool iMsgObserverOutstanding;
+	TFixedArray<TInt, KOtgHostMessageQueueSize> iMsgQueue;
+ 	TBool iMsgObserverQueueEvents;
+ 	TInt iMsgQueueHead;
+ 	TInt iMsgQueueTail;
+ 	TInt iNotifiedMsg;
+
+	RMessage2 iHostEventObserverMessage;
+	TBool iHostEventObserverOutstanding;
+	TFixedArray<TDeviceEventInformation, KDeviceStatesQueueSize> iHostStateQueue;
+ 	TBool iHostEventObserverQueueEvents;
+ 	TInt iHostEventQueueHead;
+ 	TInt iHostEventQueueTail;
+ 	TDeviceEventInformation iNotifiedHostState;
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	};
+
+#endif //__CUSBSESSION_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/UsbSettings.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,65 @@
+/**
+* Copyright (c) 1997-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:
+* Defines USB settings
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __USBSETTINGS_H__
+#define __USBSETTINGS_H__
+
+#include <e32std.h>
+
+//	These definitions are used as the second level of defaults
+//	and overlay the initial settings that are put in place by
+//	the construction in the PDD (file pa_usbc.cpp)
+//
+//	********************************************************
+//	* These values are *not* to be changed by the licensee *
+//	********************************************************
+//
+
+const TUint16	KUsbDefaultBcdUsb				= 0x0000;
+const TUint8	KUsbDefaultDeviceClass			= 0x02;
+const TUint8	KUsbDefaultDeviceSubClass		= 0x00;
+const TUint8	KUsbDefaultDeviceProtocol		= 0x00;
+const TUint16	KUsbDefaultVendorId				= 0x0e22;
+const TUint16	KUsbDefaultProductId			= 0x000b;
+const TUint16	KUsbDefaultBcdDevice			= 0x0000;
+
+_LIT(KUsbDefaultManufacturer, "Symbian Ltd.");
+_LIT(KUsbDefaultProduct, "Symbian OS");
+_LIT(KUsbDefaultSerialNumber, "0123456789");
+_LIT(KUsbDefaultConfig, "First and Last and Always");
+
+const TInt KUsbManagerResourceVersion = 0;
+const TInt KUsbManagerResourceVersionNew = 1;
+
+enum TUsbManagerResourceVersion
+	{
+	EUsbManagerResourceVersionOne = 1,
+	EUsbManagerResourceVersionTwo = 2,
+	EUsbManagerResourceVersionThree = 3
+	};
+
+_LIT(KUsbManagerResource, "z:\\private\\101fe1db\\usbman.rsc");
+
+#endif // __USBSETTINGS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/UsbUtils.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#ifndef __USBUTILS_H__
+#define __USBUTILS_H__
+
+#include <e32std.h>
+#include <ecom/ecom.h>
+
+//Used to push a pointer array on to the cleanup stack
+//ensuring that it will be reset and destroyed when popped
+void CleanupResetAndDestroyPushL(RImplInfoPtrArray& aArray);
+ 	
+#endif //__USBUTILS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/UsbmanServerSecurityPolicy.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,132 @@
+/*
+* 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 "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:
+* USBMAN Server Security Policy definitions for Platform security.
+*
+*/
+
+/**
+ @file 
+ @internalComponent
+*/
+ 
+#if !defined(__USBMANSERVERSECURITYPOLICY_H__)
+#define __USBMANSERVERSECURITYPOLICY_H__
+
+#include <usb/usbshared.h>
+#include "rusb.h"
+
+/** Usbman Server Security Policy Definition */
+const TUint KUsbmanServerRangeCount = 13;
+
+const TInt KUsbmanServerRanges[KUsbmanServerRangeCount] = 
+	{
+	EUsbStart,                 			/** NetworkControl 		*/
+	EUsbRegisterObserver,       		/** none 				*/
+	EUsbStartCancel,            		/** NetworkControl 		*/
+	EUsbCancelObserver,        			/** none 				*/
+	EUsbStopCancel,            			/** NetworkControl 		*/
+	EUsbGetCurrentDeviceState, 			/** none 				*/
+	EUsbTryStart,              			/** NetworkControl 		*/
+	EUsbCancelInterest,        			/** none 				*/
+	EUsbSetCtlSessionMode,	   			/** NetworkControl 		*/
+	EUsbRegisterMessageObserver, 		/** none 				*/
+	EUsbEnableFunctionDriverLoading,	/** NetworkControl 		*/
+	EUsbGetSupportedLanguages, 			/** none 				*/
+	EUsbGetPersonalityProperty + 1	 				/** fail (to KMaxTInt) 	*/
+	};
+
+/** Index numbers into KUsbmanServerElements[] */
+const TInt KPolicyNetworkControl = 0;
+const TInt KPolicyPass = 1;
+
+/**Mapping IPCs to policy element */
+const TUint8 KUsbmanServerElementsIndex[KUsbmanServerRangeCount] = 
+	{
+	KPolicyNetworkControl, 	/** EUsbStart */
+				 			/** EUsbStop  */
+
+	KPolicyPass, 		 	/** EUsbRegisterObserver */
+				 			/** EUsbGetCurrentState */
+
+	KPolicyNetworkControl, 	/** EUsbStartCancel */
+
+	KPolicyPass,		 	/** EUsbCancelObserver */
+
+	KPolicyNetworkControl, 	/** EUsbStopCancel */
+	KPolicyPass, 		 	/** EUsbGetCurrentDeviceState */
+				 			/** EUsbRegisterServiceObserver */
+		                 	/** EUsbCancelServiceObserver */
+		           	 		/** EUsbDbgMarkHeap */
+				 			/** EUsbDbgCheckHeap */
+				 			/** EUsbDbgMarkEnd */
+				 			/** EUsbDbgFailNext */
+
+	KPolicyNetworkControl,	/** EUsbTryStart */
+				 			/** EUsbTryStop */
+
+	KPolicyPass,		 	/** EUsbCancelInterest */
+					 		/** EUsbGetCurrentPersonalityId */
+					 		/** EUsbGetSupportedClasses */
+					 		/** EUsbGetPersonalityIds */
+					 		/** EUsbGetDescription */
+					 		/** EUsbClassSupported */
+
+	KPolicyNetworkControl,	/** EUsbSetCtlSessionMode */
+							/** EUsbBusRequest */
+				 			/** EUsbBusRespondSrp */
+
+				 			/** EUsbBusClearError */
+
+				 			/** EUsbBusDrop */
+
+	KPolicyPass,		 	/** EUsbRegisterMessageObserver */
+					 		/** EUsbCancelMessageObserver */
+					 		/** EUsbRegisterHostObserver */
+					 		/** EUsbCancelHostObserver */
+
+	KPolicyNetworkControl,	/** EUsbEnableFunctionDriverLoading */
+				 			/** EUsbDisableFunctionDriverLoading */
+
+	KPolicyPass,		 	/** EUsbGetSupportedLanguages */
+					 		/** EUsbGetManufacturerStringDescriptor */
+					 		/** EUsbGetProductStringDescriptor */
+                            /** EUsbGetOtgDescriptor */
+				 			/** EUsbDbgAlloc */
+							/** EUsbRequestSession */
+                            /** EUsbGetDetailedDescription */
+							/** EUsbGetPersonalityProperty */
+
+	CPolicyServer::ENotSupported, /** EUsbGetPersonalityProperty + 1 to KMaxTInt */
+
+	};
+
+/** Individual policy elements */
+const CPolicyServer::TPolicyElement KUsbmanServerElements[] = 
+	{
+		/** the EFailClient means that the if the check fails the CheckFailed method with return KErrPermissionDenied */
+  		{ _INIT_SECURITY_POLICY_C1(ECapabilityNetworkControl), CPolicyServer::EFailClient },
+  		{ _INIT_SECURITY_POLICY_PASS },
+	};
+
+/** Main policy */
+const CPolicyServer::TPolicy KUsbmanServerPolicy = 
+	{
+	CPolicyServer::EAlwaysPass, /** Specifies all connect attempts should pass */
+	KUsbmanServerRangeCount,
+	KUsbmanServerRanges,
+	KUsbmanServerElementsIndex,
+	KUsbmanServerElements,
+	};
+#endif //__USBMANSERVERSECURITYPOLICY_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/cusbhost.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,76 @@
+/*
+* 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 "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
+ @released
+*/
+
+#ifndef CUSBHOST_H
+#define CUSBHOST_H
+
+#include "usbhoststack.h"
+#include "musbotghostnotifyobserver.h"
+#include "musbinternalobservers.h"
+#include "cusbhostwatcher.h"
+
+NONSHARABLE_CLASS(CUsbHost) : public CBase, public MUsbHostObserver
+	{
+public:
+	static CUsbHost* NewL();
+	virtual ~CUsbHost();
+
+private:
+	CUsbHost();
+	void ConstructL();
+
+private:
+	static CUsbHost* iInstance;
+	
+public:
+	void StartL();
+	void Stop();
+	void RegisterObserverL(MUsbOtgHostNotifyObserver& aObserver);
+	void DeregisterObserver(MUsbOtgHostNotifyObserver& aObserver);
+	TInt GetProductStringDescriptor(TUint aDeviceId,TUint aLangId,TName& aString);
+	TInt GetSupportedLanguages(TUint aDeviceId,RArray<TUint>& aLangIds);
+	TInt GetManufacturerStringDescriptor(TUint aDeviceId,TUint aLangId,TName& aString);
+	TInt GetOtgDescriptor(TUint aDeviceId, TOtgDescriptor& otgDescriptor);
+	TInt EnableDriverLoading();
+	void DisableDriverLoading();
+
+public:
+	// MUsbHostObserver
+	virtual void NotifyHostEvent(TUint aWatcherId);
+
+private:
+
+	void UpdateNumOfObservers();
+
+private:
+	TBool iHasBeenStarted;
+
+	CActiveUsbHostWatcher* iUsbHostWatcher[2];
+	TDeviceEventInformation iHostEventInfo;
+	TInt iHostMessage;
+	RUsbHostStack iUsbHostStack;
+	RPointerArray<MUsbOtgHostNotifyObserver> iObservers;
+	TUint iNumOfObservers;
+	};
+
+#endif //CUSBHOST_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/cusbhostwatcher.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,111 @@
+/*
+* 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 "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
+ @released
+*/
+
+
+#ifndef CUSBHOSTWATCHER_H
+#define CUSBHOSTWATCHER_H
+
+#include "usbhoststack.h"
+#include <usb/usbshared.h>
+
+enum TUsbHostMonitor
+	{
+	EHostEventMonitor 	= 0,
+	EHostMessageMonitor = 1,
+	ENumMonitor			= 2,
+	};	
+
+const TUint KHostEventMonitor = EHostEventMonitor;
+const TUint KHostMessageMonitor = EHostMessageMonitor;
+
+class MUsbHostObserver;
+
+class CActiveUsbHostWatcher : public CActive
+	{
+public:
+
+	CActiveUsbHostWatcher(RUsbHostStack& aUsbHostStack, 
+						  MUsbHostObserver& aOwner,
+						  TUint aWatcherId);
+	virtual ~CActiveUsbHostWatcher();
+
+public:
+	virtual void Post() = 0;
+
+protected: // from CActive
+	virtual void RunL();
+	virtual void DoCancel() = 0;
+
+protected: // unowned
+	RUsbHostStack& iUsbHostStack;
+	MUsbHostObserver& iOwner;
+	TUint iWatcherId;
+	};
+
+
+class CActiveUsbHostEventWatcher: public CActiveUsbHostWatcher
+	{
+public:
+	static CActiveUsbHostEventWatcher* NewL(RUsbHostStack& aUsbHostStack, 
+											MUsbHostObserver& aOwner,
+											TDeviceEventInformation& aDeviceEventInfo);
+	virtual ~CActiveUsbHostEventWatcher();
+private:
+	CActiveUsbHostEventWatcher(RUsbHostStack& aUsbHostStack, 
+							   MUsbHostObserver& aOwner,
+							   TDeviceEventInformation& aHostEventInfo);
+
+private: // from CActive
+	virtual void DoCancel();
+public:
+	// from CActiveUsbHostWatcher
+	virtual void Post();
+
+private:
+	TDeviceEventInformation& iHostEventInfo;
+};
+
+
+class CActiveUsbHostMessageWatcher: public CActiveUsbHostWatcher
+	{
+public:
+	static CActiveUsbHostMessageWatcher* NewL(RUsbHostStack& aUsbHostStack, 
+											  MUsbHostObserver& aOwner,
+											  TInt& aHostMessage);
+	virtual ~CActiveUsbHostMessageWatcher();
+private:
+	CActiveUsbHostMessageWatcher(RUsbHostStack& aUsbHostStack, 
+								 MUsbHostObserver& aOwner,
+								 TInt& aHostMessage);
+
+private: // from CActive
+	virtual void DoCancel();
+public:
+	// from CActiveUsbHostWatcher
+	virtual void Post();
+	
+private:
+	TInt& iHostMessage;
+	};
+
+#endif //CUSBHOSTWATCHER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/cusbotgwatcher.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,247 @@
+/**
+* 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 "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
+ @released
+*/
+
+#ifndef __CUSBOTGWATCHER_H__
+#define __CUSBOTGWATCHER_H__
+
+#include <e32def.h>
+#include <d32otgdi.h>
+#include <e32property.h> //Publish & Subscribe header
+
+class MUsbOtgObserver;
+class RUsbOtgDriver;
+class CUsbOtg;
+
+/**
+ * The CUsbOtgIdPinWatcher class
+ *
+ * Talks directly to the USB OTG Logical Device Driver (LDD) and 
+ * watches ID-Pin changes.
+ * Publishes TInt property as ID-Pin status
+ */
+class CUsbOtgBaseWatcher : public CActive
+	{
+public:
+	CUsbOtgBaseWatcher(RUsbOtgDriver& aLdd);
+	virtual ~CUsbOtgBaseWatcher();
+
+	// From CActive
+	virtual void RunL() = 0;
+	virtual void DoCancel() = 0;
+	
+	virtual void Start();
+
+protected:
+	virtual void Post() = 0;
+
+protected:
+	RUsbOtgDriver& iLdd;
+	};
+
+/**
+ * The CUsbOtgIdPinWatcher class
+ *
+ * Talks directly to the USB OTG Logical Device Driver (LDD) and 
+ * watches ID-Pin changes.
+ * Publishes TInt property as ID-Pin status
+ */
+NONSHARABLE_CLASS(CUsbOtgIdPinWatcher) : public CUsbOtgBaseWatcher
+	{
+public:
+	static CUsbOtgIdPinWatcher* NewL(RUsbOtgDriver& aLdd);
+	virtual ~CUsbOtgIdPinWatcher();
+
+	// From CActive
+	virtual void RunL();
+	virtual void DoCancel();
+	
+protected:
+	CUsbOtgIdPinWatcher(RUsbOtgDriver& aLdd);
+	void ConstructL();
+	virtual void Post();
+
+private:
+	RUsbOtgDriver::TOtgIdPin iOtgIdPin;
+	};
+
+/**
+ * The CUsbOtgVBusWatcher class
+ *
+ * Talks directly to the USB OTG Logical Device Driver (LDD) and 
+ * watches ID-Pin changes.
+ * Publishes TInt property as ID-Pin status
+ */
+NONSHARABLE_CLASS(CUsbOtgVbusWatcher) : public CUsbOtgBaseWatcher
+	{
+public:
+	static CUsbOtgVbusWatcher* NewL(RUsbOtgDriver& aLdd);
+	virtual ~CUsbOtgVbusWatcher();
+
+	// From CActive
+	virtual void RunL();
+	virtual void DoCancel();
+	
+protected:
+	CUsbOtgVbusWatcher(RUsbOtgDriver& aLdd);
+	void ConstructL();
+	virtual void Post();
+
+private:
+	RUsbOtgDriver::TOtgVbus iOtgVbus;
+	};	
+
+/**
+ * The CUsbOtgVBusWatcher class
+ *
+ * Talks directly to the USB OTG Logical Device Driver (LDD) and 
+ * watches ID-Pin changes.
+ * Publishes TInt property as ID-Pin status
+ */
+NONSHARABLE_CLASS(CUsbOtgStateWatcher) : public CUsbOtgBaseWatcher
+	{
+	public:
+		static CUsbOtgStateWatcher* NewL(RUsbOtgDriver& aLdd);
+		virtual ~CUsbOtgStateWatcher();
+
+		// From CActive
+		virtual void RunL();
+		virtual void DoCancel();
+		
+	protected:
+		CUsbOtgStateWatcher(RUsbOtgDriver& aLdd);
+		void ConstructL();
+		virtual void Post();
+
+	private:
+		RUsbOtgDriver::TOtgState iOtgState;
+	};
+
+/**
+ * The CUsbOtgEventWatcher class
+ *
+ * Talks directly to the USB OTG Logical Device Driver (LDD) and 
+ * watches ID-Pin changes.
+ * Publishes TInt property as ID-Pin status
+ */
+NONSHARABLE_CLASS(CUsbOtgEventWatcher) : public CUsbOtgBaseWatcher
+	{
+	public:
+		static CUsbOtgEventWatcher* NewL(CUsbOtg& aOwner, RUsbOtgDriver& aLdd, 
+										 RUsbOtgDriver::TOtgEvent& aOtgEvent);
+		virtual ~CUsbOtgEventWatcher();
+
+		// From CActive
+		virtual void RunL();
+		virtual void DoCancel();
+		
+	protected:
+		CUsbOtgEventWatcher(CUsbOtg& aOwner, RUsbOtgDriver& aLdd, RUsbOtgDriver::TOtgEvent& aOtgEvent);
+		void ConstructL();
+		virtual void Post();
+		
+	private:
+		void LogEventText(RUsbOtgDriver::TOtgEvent /*aState*/);
+
+	private:
+		CUsbOtg& iOwner;
+		RUsbOtgDriver::TOtgEvent& iOtgEvent;
+	};	
+	
+/**
+ * The CUsbOtgConnectionIdleWatcher class
+ *
+ * Talks directly to the USB OTG Logical Device Driver (LDD) and 
+ * watches Connection Idle changes.
+ * Publishes TInt property as Connection Idle status
+ */
+NONSHARABLE_CLASS(CUsbOtgConnectionIdleWatcher) : public CUsbOtgBaseWatcher
+	{
+public:
+	static CUsbOtgConnectionIdleWatcher* NewL(RUsbOtgDriver& aLdd);
+	virtual ~CUsbOtgConnectionIdleWatcher();
+
+	// From CActive
+	virtual void RunL();
+	virtual void DoCancel();
+	
+protected:
+	CUsbOtgConnectionIdleWatcher(RUsbOtgDriver& aLdd);
+	void ConstructL();
+	virtual void Post();
+
+private:
+	RUsbOtgDriver::TOtgConnection iConnectionIdle;
+	};
+
+
+/**
+ * The CUsbOtgWatcher class
+ *
+ * Talks directly to the USB OTG Logical Device Driver (LDD) and 
+ * watches any messages/errors which occur
+ */
+NONSHARABLE_CLASS(CUsbOtgWatcher) : public CActive
+	{
+public:
+	static CUsbOtgWatcher* NewL(MUsbOtgObserver& aOwner, RUsbOtgDriver& aLdd, TUint& aOtgMessage);
+	virtual ~CUsbOtgWatcher();
+
+	// From CActive
+	virtual void RunL();
+	virtual void DoCancel();
+
+	virtual void Start();
+
+protected:
+	CUsbOtgWatcher(MUsbOtgObserver& aOwner, RUsbOtgDriver& aLdd, TUint& aOtgMessage);
+	void Post();
+
+private:
+	MUsbOtgObserver& iOwner;
+	RUsbOtgDriver& iLdd;
+	TUint& iOtgMessage;
+	};
+
+NONSHARABLE_CLASS(CRequestSessionWatcher) : public CActive
+	{
+public:
+	static CRequestSessionWatcher* NewL(MUsbOtgObserver& aOwner);
+	~CRequestSessionWatcher();
+
+private:
+	CRequestSessionWatcher(MUsbOtgObserver& aOwner);
+	void ConstructL();
+	
+	// From CActive
+	virtual void RunL();
+	virtual void DoCancel();
+
+private:
+	RProperty iProp;
+	MUsbOtgObserver& iOwner;
+	};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/musbinternalobservers.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,57 @@
+/*
+* 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 "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
+ @released
+*/
+
+#ifndef USBINTERNALOBSERVERS_H
+#define USBINTERNALOBSERVERS_H
+
+/**
+ * The MUsbMessageObserver class
+ *
+ * The mixin used by the USB Otg/Host watcher objects to notify their
+ * owners of any messages that occur
+ *
+ * @internalComponent
+ * @released
+ */
+class MUsbOtgObserver
+	{
+public:
+	virtual void NotifyMessage(TInt aMessage = 0) = 0;
+	};
+
+/**
+ * The MUsbHostObserver class
+ *
+ * The mixin used by the USB Host watcher objects to notify their
+ * owners of any Host events that occur
+ *
+ * @internalComponent
+ * @released
+ */
+class MUsbHostObserver
+	{
+public:
+	virtual void NotifyHostEvent(TUint aWatcherId) = 0;
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/INC/musbotghostnotifyobserver.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,57 @@
+/*
+* 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 "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:
+* The mixin used by the USB OTG/Host objects to notify all of
+* it's observers of any messages and state changes that occur
+*
+*/
+
+/**
+ @file
+*/
+
+#ifndef __MUSBOTGHOSTNOTIFYOBSERVER_H__
+#define __MUSBOTGHOSTNOTIFYOBSERVER_H__
+
+#include <usb/usbshared.h>
+
+/**
+ * The MUsbOtgHostNotifyObserver class
+ *
+ * The mixin used by the USB Otg/Host objects to notify all of
+ * it's observers of any messages and state changes that occur
+ *
+ * @internalTechnology
+ * @released
+ */
+class MUsbOtgHostNotifyObserver
+	{
+public:
+	/**
+	 * Called when the USB OTG/Host components reports
+	 * new message arrival
+	 *
+	 * @param aMessage The last message code detected
+	 */
+	virtual void UsbOtgHostMessage(TInt aMessage) = 0;
+
+	/**
+	 * Called when the USB Host state has changed
+	 *
+	 * @param aDevInfo The last device info 
+	 */
+	virtual void UsbHostEvent(TDeviceEventInformation& aDevInfo) = 0;
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/CPersonality.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,166 @@
+/*
+* 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 "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:
+* Implements a utility class which holds information about a USB personality
+*
+*/
+
+/**
+ @file
+ @internalAll
+*/
+
+#include "CPersonality.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBSVR");
+#endif
+
+/**
+ * Factory method. Constructs a CPersonality object. 
+ *
+ * @return a pointer to CPersonality object.
+ */
+CPersonality* CPersonality::NewL()
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CPersonality* self = new(ELeave) CPersonality;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/**
+ * Allocates max amount of memory for each of 3 strings
+ */	
+void CPersonality::ConstructL()
+	{
+	LOG_FUNC
+
+	iManufacturer 	= HBufC::NewLC(KUsbStringDescStringMaxSize);
+	CleanupStack::Pop();
+	iProduct	 	= HBufC::NewLC(KUsbStringDescStringMaxSize);
+	CleanupStack::Pop();
+	iDescription	= HBufC::NewLC(KUsbStringDescStringMaxSize);
+	CleanupStack::Pop();
+	iDetailedDescription    = HBufC::NewLC(KUsbStringDescStringMaxSize);
+	CleanupStack::Pop();
+	}
+	
+/**
+ * standard constructor
+ */
+CPersonality::CPersonality()
+	{
+	}
+
+/**
+ * destructor
+ */
+CPersonality::~CPersonality()
+	{
+	LOG_FUNC
+
+	iClassUids.Close();
+	delete iManufacturer;
+	delete iProduct;
+	delete iDescription;
+	delete iDetailedDescription;
+	}
+
+/**
+ * @return the index of the first match or KErrNotFound
+ */
+TInt CPersonality::ClassSupported(TUid aClassUid) const
+	{
+	TIdentityRelation<TUid> relation(CPersonality::Compare);
+	return iClassUids.Find(aClassUid, relation);
+	}
+
+/**
+ * @return KErrNone or system wide error code
+ */	
+TInt CPersonality::AddSupportedClasses(TUid aClassUid)
+	{
+	return iClassUids.Append(aClassUid);
+	}
+
+/**
+ * Sets personality id
+ */
+void CPersonality::SetId(TInt aId)
+	{
+	iId = aId;
+	}
+
+/**
+ * Sets manufacturer textual description
+ */	
+void CPersonality::SetManufacturer(const TDesC* aManufacturer)
+	{
+	iManufacturer->Des().Copy(*aManufacturer);
+	}
+
+/**
+ * Sets product textual description
+ */	
+void CPersonality::SetProduct(const TDesC* aProduct)
+	{
+	iProduct->Des().Copy(*aProduct);
+	}
+
+/**
+ * Sets personality textual description
+ */
+void CPersonality::SetDescription(const TDesC* aDescription)
+	{
+	iDescription->Des().Copy((*aDescription).Left(KUsbStringDescStringMaxSize-1));
+	}
+
+/**
+ * Compares if two class uids are equal
+ *
+ * @return 1 if they are equal or 0 otherwise
+ */
+TInt CPersonality::Compare(const TUid&  aFirst, const TUid& aSecond)
+	{
+	return aFirst == aSecond;
+	};
+
+/**
+ * Sets detailed personality textual description
+ */
+void CPersonality::SetDetailedDescription(const TDesC* aDetailedDescription)
+	{
+	iDetailedDescription->Des().Copy((*aDetailedDescription).Left(KUsbStringDescStringMaxSize-1));
+	}
+
+/**
+ * Sets version
+ */
+void CPersonality::SetVersion(TInt aVersion)
+	{
+	iVersion = aVersion;
+	}
+
+/**
+ * Sets property
+ */
+void CPersonality::SetProperty(TUint32 aProperty)
+	{
+	iProperty = aProperty;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/CUsbDevice.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,1555 @@
+/*
+* Copyright (c) 1997-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:
+* Implements the main object of Usbman that manages all the USB Classes
+* and the USB Logical Device (via CUsbDeviceStateWatcher).
+*
+*/
+
+/**
+ @file
+*/
+
+#include "CUsbDevice.h"
+#include "CUsbDeviceStateWatcher.h"
+#include <cusbclasscontrolleriterator.h>
+#include "MUsbDeviceNotify.h"
+#include "UsbSettings.h"
+#include "CUsbServer.h"
+#include <cusbclasscontrollerbase.h>
+#include <cusbclasscontrollerplugin.h>
+#include "UsbUtils.h"
+#include <cusbmanextensionplugin.h>
+
+#ifdef USE_DUMMY_CLASS_CONTROLLER
+#include "CUsbDummyClassController.h"
+#endif
+
+#include <bafl/sysutil.h>
+#include <usb/usblogger.h>
+#include <e32svr.h>
+#include <e32base.h>
+#include <e32std.h>
+#include <usbman.rsg>
+#include <f32file.h>
+#include <barsc.h>
+#include <barsread.h>
+#include <bautils.h>
+#include <e32property.h> //Publish & Subscribe header
+#include "CPersonality.h"
+
+_LIT(KUsbLDDName, "eusbc"); //Name used in call to User::LoadLogicalDevice
+_LIT(KUsbLDDFreeName, "Usbc"); //Name used in call to User::FreeLogicalDevice
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBSVR");
+#endif
+
+// Panic category only used in debug builds
+#ifdef _DEBUG
+_LIT(KUsbDevicePanicCategory, "UsbDevice");
+#endif
+
+/**
+ * Panic codes for the USB Device Class
+ */
+enum TUsbDevicePanic
+	{
+	/** Class called while in an illegal state */
+	EBadAsynchronousCall = 0,
+	EConfigurationError,
+	EResourceFileNotFound,
+	/** ConvertUidsL called with an array that is not empty */
+	EUidArrayNotEmpty,
+	};
+
+
+CUsbDevice* CUsbDevice::NewL(CUsbServer& aUsbServer)
+/**
+ * Constructs a CUsbDevice object.
+ *
+ * @return	A new CUsbDevice object
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbDevice* r = new (ELeave) CUsbDevice(aUsbServer);
+	CleanupStack::PushL(r);
+	r->ConstructL();
+	CleanupStack::Pop(r);
+	return r;
+	}
+
+
+CUsbDevice::~CUsbDevice()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	// Cancel any outstanding asynchronous operation.
+	Cancel();
+	
+	delete iUsbClassControllerIterator;
+	iSupportedClasses.ResetAndDestroy();
+	iSupportedPersonalities.ResetAndDestroy();
+	iSupportedClassUids.Close();
+
+	iExtensionPlugins.ResetAndDestroy();
+
+	if(iEcom)
+		iEcom->Close();
+	REComSession::FinalClose();
+
+	// Free any memory allocated to the list of observers. Note that
+	// we don't want to call ResetAndDestroy, because we don't own
+	// the observers themselves.
+	iObservers.Reset();
+
+#ifndef __WINS__
+	LOGTEXT2(_L8("about to delete device state watcher @ %08x"), (TUint32) iDeviceStateWatcher);
+	delete iDeviceStateWatcher;
+	LOGTEXT(_L8("deleted device state watcher"));
+
+	iLdd.Close();
+
+	LOGTEXT(_L8("Freeing logical device"));
+	TInt err = User::FreeLogicalDevice(KUsbLDDFreeName);
+	//Putting the LOGTEXT2 inside the if statement prevents a compiler
+	//warning about err being unused in UREL builds.
+	if(err)
+		{
+		LOGTEXT2(_L8("     User::FreeLogicalDevice returned %d"),err);
+		}
+#endif	
+
+	delete iDefaultSerialNumber;
+	}
+
+
+CUsbDevice::CUsbDevice(CUsbServer& aUsbServer)
+	: CActive(EPriorityStandard)
+	, iDeviceState(EUsbDeviceStateUndefined)
+	, iServiceState(EUsbServiceIdle)
+	, iUsbServer(aUsbServer)
+	, iPersonalityCfged(EFalse)
+/**
+ * Constructor.
+ */
+	{
+	CActiveScheduler::Add(this);
+	}
+
+
+void CUsbDevice::ConstructL()
+/**
+ * Performs 2nd phase construction of the USB device.
+ */
+	{
+	LOG_FUNC
+	
+	iEcom = &(REComSession::OpenL());
+
+	iUsbClassControllerIterator = new(ELeave) CUsbClassControllerIterator(iSupportedClasses);
+
+#ifndef __WINS__
+	LOGTEXT(_L8("About to load LDD"));
+	TInt err = User::LoadLogicalDevice(KUsbLDDName);
+
+	if (err != KErrNone && err != KErrAlreadyExists)
+		{
+		LEAVEL(err);
+		}
+
+	LOGTEXT(_L8("About to open LDD"));
+	LEAVEIFERRORL(iLdd.Open(0));
+	LOGTEXT(_L8("LDD opened"));
+	
+	// hide bus from host while interfaces are being set up
+	iLdd.DeviceDisconnectFromHost();
+
+	// Does the USC support cable detection while powered off? If no, then 
+	// call PowerUpUdc when RUsb::Start finishes, as is obvious. If yes, we 
+	// delay calling PowerUpUdc until both the service state is 'started' and 
+	// the device state is not undefined. This is to save power in the UDC 
+	// when there's no point it being powered.
+	TUsbDeviceCaps devCapsBuf;
+	LEAVEIFERRORL(iLdd.DeviceCaps(devCapsBuf));
+	if ( devCapsBuf().iFeatureWord1 & KUsbDevCapsFeatureWord1_CableDetectWithoutPower )
+		{
+		LOGTEXT(_L8("\tUDC supports cable detect when unpowered"));
+		iUdcSupportsCableDetectWhenUnpowered = ETrue;
+		}
+	else
+		{
+		LOGTEXT(_L8("\tUDC does not support cable detect when unpowered"));
+		}
+
+	TUsbcDeviceState deviceState;
+	LEAVEIFERRORL(iLdd.DeviceStatus(deviceState));
+	SetDeviceState(deviceState);
+	LOGTEXT(_L8("Got device state"));
+
+	iDeviceStateWatcher = CUsbDeviceStateWatcher::NewL(*this, iLdd);
+	iDeviceStateWatcher->Start();
+
+	// Get hold of the default serial number in the driver
+	// This is so it can be put back in place when a device that sets a
+	// different serial number (through the P&S key) is stopped
+	iDefaultSerialNumber = HBufC16::NewL(KUsbStringDescStringMaxSize);
+	TPtr16 serNum = iDefaultSerialNumber->Des();
+	err = iLdd.GetSerialNumberStringDescriptor(serNum);
+	if (err == KErrNotFound)
+		{
+		delete iDefaultSerialNumber;
+		iDefaultSerialNumber = NULL;
+		LOGTEXT(_L8("No default serial number"));
+		}
+	else
+		{
+		LEAVEIFERRORL(err);
+#ifdef __FLOG_ACTIVE
+		TBuf8<KUsbStringDescStringMaxSize> narrowString;
+		narrowString.Copy(serNum);
+		LOGTEXT2(_L8("Got default serial number %S"), &narrowString);
+#endif //__FLOG_ACTIVE		
+		}
+
+	LOGTEXT(_L8("UsbDevice::ConstructL() finished"));
+#endif
+	
+#ifndef __OVER_DUMMYUSBDI__
+	InstantiateExtensionPluginsL();
+#endif
+	}
+
+void CUsbDevice::InstantiateExtensionPluginsL()
+	{
+	LOGTEXT(_L8(">>CUsbDevice::InstantiateExtensionPluginsL"));
+	const TUid KUidExtensionPluginInterface = TUid::Uid(KUsbmanExtensionPluginInterfaceUid);
+	RImplInfoPtrArray implementations;
+	const TEComResolverParams noResolverParams;
+	REComSession::ListImplementationsL(KUidExtensionPluginInterface, noResolverParams, KRomOnlyResolverUid, implementations);
+	CleanupResetAndDestroyPushL(implementations);
+	LOGTEXT2(_L8("Number of implementations of extension plugin interface: %d"), implementations.Count());
+
+	for (TInt i=0; i<implementations.Count(); i++)
+		{
+		CUsbmanExtensionPlugin* plugin = CUsbmanExtensionPlugin::NewL(implementations[i]->ImplementationUid(), *this);
+		CleanupStack::PushL(plugin);
+		iExtensionPlugins.AppendL(plugin); // transfer ownership to iExtensionPlugins
+		CleanupStack::Pop(plugin);
+		LOGTEXT2(_L8("Added extension plugin with UID 0x%08x"),
+			implementations[i]->ImplementationUid());
+		}
+
+	CleanupStack::PopAndDestroy(&implementations);
+
+	LOGTEXT(_L8("<<CUsbDevice::InstantiateExtensionPluginsL"));
+	}
+
+
+	
+   	
+void CUsbDevice::EnumerateClassControllersL()
+/**
+ * Loads all USB class controllers at startup.
+ *
+ */
+	{
+	LOG_FUNC
+	
+#ifdef USE_DUMMY_CLASS_CONTROLLER
+	//create a TLinearOrder to supply the comparison function, Compare(), to be used  
+	//to determine the order to add class controllers
+	TLinearOrder<CUsbClassControllerBase> order(CUsbClassControllerBase::Compare);
+	
+	// For GT171 automated tests, create three instances of the dummy class 
+	// controller, which will read their behaviour from an ini file. Do not 
+	// make any other class controllers.
+	for ( TUint ii = 0 ; ii < 3 ; ii++ )
+		{
+		AddClassControllerL(CUsbDummyClassController::NewL(*this, ii), order);	
+		}
+	    
+	LEAVEIFERRORL(iUsbClassControllerIterator->First());
+	    
+#else
+
+	// Add a class controller statically.
+	// The next line shows how to add a class controller, CUsbExampleClassController,
+	// statically
+
+	// AddClassControllerL(CUsbExampleClassController::NewL(*this),order);
+	
+	// Load class controller plug-ins
+
+	RImplInfoPtrArray implementations;
+
+	const TEComResolverParams noResolverParams;
+	REComSession::ListImplementationsL(KUidUsbPlugIns, noResolverParams, KRomOnlyResolverUid, implementations);
+  	CleanupResetAndDestroyPushL(implementations);
+  	
+	LOGTEXT2(_L8("Number of implementations to load  %d"), implementations.Count());
+	
+	for (TInt i=0; i<implementations.Count(); i++)
+		{
+		LOGTEXT2(_L8("Adding class controller with UID %x"),
+			implementations[i]->ImplementationUid());
+		const TUid uid = implementations[i]->ImplementationUid();
+		LEAVEIFERRORL(iSupportedClassUids.Append(uid));
+		}	
+			
+	CleanupStack::PopAndDestroy(&implementations);
+	
+#endif // USE_DUMMY_CLASS_CONTROLLER
+	}
+
+void CUsbDevice::AddClassControllerL(CUsbClassControllerBase* aClassController, 
+									TLinearOrder<CUsbClassControllerBase> aOrder)
+/**
+ * Adds a USB class controller to the device. The controller will now be
+ * managed by this device. Note that the class controller, aClassController, is now
+ * owned by this function and can be destroyed by it.  Calling functions do not need to 
+ * destroy the class controller. 
+ *
+ * @param	aClassController	Class to be managed
+ * @param   aOrder              Specifies order CUsbClassControllerBase objects are to be
+ *                              added
+ */
+	{
+	LOG_FUNC
+	
+	
+	TInt rc = KErrNone;	
+	
+	if(isPersonalityCfged()) // do not take into account priorities
+		{
+		rc = iSupportedClasses.Append(aClassController);	
+		}
+	else
+		{
+		rc = iSupportedClasses.InsertInOrderAllowRepeats(
+		aClassController, aOrder);
+		} 
+		
+	if (rc != KErrNone) 
+		{
+		// Avoid memory leak by deleting class controller if the append fails.
+		delete aClassController;
+		LEAVEL(rc);
+		}
+	}
+
+void CUsbDevice::RegisterObserverL(MUsbDeviceNotify& aObserver)
+/**
+ * Register an observer of the device.
+ * Presently, the device supports watching state.
+ *
+ * @param	aObserver	New Observer of the device
+ */
+	{
+	LOG_FUNC
+
+	LEAVEIFERRORL(iObservers.Append(&aObserver));
+	}
+
+
+void CUsbDevice::DeRegisterObserver(MUsbDeviceNotify& aObserver)
+/**
+ * De-registers an existing device observer.
+ *
+ * @param	aObserver	The existing device observer to be de-registered
+ */
+	{
+	LOG_FUNC
+
+	TInt index = iObservers.Find(&aObserver);
+
+	if (index >= 0)
+		iObservers.Remove(index);
+	}
+
+
+void CUsbDevice::StartL()
+/**
+ * Start the USB Device and all its associated USB classes.
+ * Reports errors and state changes via observer interface.
+ */
+	{
+	LOG_FUNC
+
+	Cancel();
+	SetServiceState(EUsbServiceStarting);
+
+	TRAPD(err, SetDeviceDescriptorL());
+	if ( err != KErrNone )
+		{
+		SetServiceState(EUsbServiceIdle);
+		LEAVEL(err);		
+		}
+
+	iLastError = KErrNone;
+	StartCurrentClassController();
+	}
+
+void CUsbDevice::Stop()
+/**
+ * Stop the USB device and all its associated USB classes.
+ */
+	{
+	LOG_FUNC
+
+	Cancel();
+	SetServiceState(EUsbServiceStopping);
+	
+	iLastError = KErrNone;
+	StopCurrentClassController();
+	}
+
+void CUsbDevice::SetServiceState(TUsbServiceState aState)
+/**
+ * Change the device's state and report the change to the observers.
+ *
+ * @param	aState	New state that the device is moving to
+ */
+	{
+	LOGTEXT3(_L8("Calling: CUsbDevice::SetServiceState [iServiceState=%d,aState=%d]"),
+		iServiceState, aState);
+
+	if (iServiceState != aState)
+		{
+		// Change state straight away in case any of the clients check it
+		TUsbServiceState oldState = iServiceState;
+		iServiceState = aState;
+		TUint length = iObservers.Count();
+
+		for (TUint i = 0; i < length; i++)
+			{
+			iObservers[i]->UsbServiceStateChange(LastError(), oldState,
+				iServiceState);
+			}
+
+		if (iServiceState == EUsbServiceIdle)
+			iUsbServer.LaunchShutdownTimerIfNoSessions();
+		}
+	LOGTEXT(_L8("Exiting: CUsbDevice::SetServiceState"));
+	}
+
+void CUsbDevice::SetDeviceState(TUsbcDeviceState aState)
+/**
+ * The CUsbDevice::SetDeviceState method
+ *
+ * Change the device's state and report the change to the observers
+ *
+ * @internalComponent
+ * @param	aState	New state that the device is moving to
+ */
+	{
+	LOG_FUNC
+	LOGTEXT3(_L8("\taState = %d, iDeviceState = %d"), aState, iDeviceState);
+
+	TUsbDeviceState state;
+	switch (aState)
+		{
+	case EUsbcDeviceStateUndefined:
+		state = EUsbDeviceStateUndefined;
+		break;
+	case EUsbcDeviceStateAttached:
+		state = EUsbDeviceStateAttached;
+		break;
+	case EUsbcDeviceStatePowered:
+		state = EUsbDeviceStatePowered;
+		break;
+	case EUsbcDeviceStateDefault:
+		state = EUsbDeviceStateDefault;
+		break;
+	case EUsbcDeviceStateAddress:
+		state = EUsbDeviceStateAddress;
+		break;
+	case EUsbcDeviceStateConfigured:
+		state = EUsbDeviceStateConfigured;
+		break;
+	case EUsbcDeviceStateSuspended:
+		state = EUsbDeviceStateSuspended;
+		break;
+	default:
+		return;
+		}
+
+	if (iDeviceState != state)
+		{
+#ifndef __WINS__
+		if (iDeviceState == EUsbDeviceStateUndefined &&
+			iUdcSupportsCableDetectWhenUnpowered &&
+			iServiceState == EUsbServiceStarted)
+			{
+			// We just changed state away from undefined. Hence the cable must
+			// now be attached (if it wasn't before). If the UDC supports
+			// cable detection when unpowered, NOW is the right time to power
+			// it up (so long as usbman is fully started).
+			(void)PowerUpAndConnect(); // We don't care about any errors here.
+			}
+#endif // __WINS__
+		// Change state straight away in case any of the clients check it
+		TUsbDeviceState oldState = iDeviceState;
+		iDeviceState = state;
+		TUint length = iObservers.Count();
+
+		for (TUint i = 0; i < length; i++)
+			{
+			iObservers[i]->UsbDeviceStateChange(LastError(), oldState, iDeviceState);
+			}
+		}
+	}
+
+/**
+ * Callback called by CDeviceHandler when the USB bus has sucessfully
+ * completed a ReEnumeration (restarted all services).
+ */
+void CUsbDevice::BusEnumerationCompleted()
+	{
+	LOG_FUNC
+
+	// Has the start been cancelled?
+	if (iServiceState == EUsbServiceStarting)
+		{
+		SetServiceState(EUsbServiceStarted);
+		}
+	else
+		{
+		LOGTEXT(_L8("    Start has been cancelled!"));
+		}
+	}
+
+void CUsbDevice::BusEnumerationFailed(TInt aError)
+/**
+ * Callback called by CDeviceHandler when the USB bus has
+ * completed an ReEnumeration (Restarted all services) with errors
+ *
+ * @param	aError	Error that has occurred during Re-enumeration
+ */
+	{
+	LOGTEXT2(_L8("CUsbDevice::BusEnumerationFailed [aError=%d]"), aError);
+	iLastError = aError;
+
+	if (iServiceState == EUsbServiceStarting)
+		{
+		SetServiceState(EUsbServiceStopping);
+		StopCurrentClassController();
+		}
+	else
+		{
+		LOGTEXT(_L8("    Start has been cancelled!"));
+		}
+	}
+
+
+void CUsbDevice::StartCurrentClassController()
+/**
+ * Called numerous times to start all the USB classes.
+ */
+	{
+	LOG_FUNC
+
+	iUsbClassControllerIterator->Current()->Start(iStatus);
+	SetActive();
+	}
+
+void CUsbDevice::StopCurrentClassController()
+/**
+ * Called numerous times to stop all the USB classes.
+ */
+	{
+	LOG_FUNC
+
+	iUsbClassControllerIterator->Current()->Stop(iStatus);
+	SetActive();
+	}
+
+/**
+Utility function to power up the UDC and connect the
+device to the host.
+*/
+TInt CUsbDevice::PowerUpAndConnect()
+	{
+	LOG_FUNC
+	LOGTEXT(_L8("\tPowering up UDC..."));
+	TInt res = iLdd.PowerUpUdc();
+	LOGTEXT2(_L8("\tPowerUpUdc res = %d"), res);
+	res = iLdd.DeviceConnectToHost();
+	LOGTEXT2(_L8("\tDeviceConnectToHost res = %d"), res);
+	return res;
+	}
+
+void CUsbDevice::RunL()
+/**
+ * Called when starting or stopping a USB class has completed, successfully or
+ * otherwise. Continues with the process of starting or stopping until all
+ * classes have been completed.
+ */
+	{
+	LOGTEXT2(_L8(">>CUsbDevice::RunL [iStatus=%d]"), iStatus.Int());
+
+	LEAVEIFERRORL(iStatus.Int());
+
+	switch (iServiceState)
+		{
+	case EUsbServiceStarting:
+		if (iUsbClassControllerIterator->Next() == KErrNotFound)
+			{
+#ifndef __WINS__
+			if (!iUdcSupportsCableDetectWhenUnpowered || iDeviceState != EUsbDeviceStateUndefined)
+				{
+				// We've finished starting the classes. We can just power up the UDC
+				// now: there's no need to re-enumerate, because we soft disconnected
+				// earlier. This will also do a soft connect.
+				LOGTEXT(_L8("Finished starting classes: powering up UDC"));
+
+				// It isn't an error if this call fails. This will happen, for example,
+				// in the case where there are no USB classes defined.
+				(void)PowerUpAndConnect();
+				}
+#endif
+			// If we're not running on target, we can just go to "started".
+			SetServiceState(EUsbServiceStarted);
+			}
+		else
+			{
+			StartCurrentClassController();
+			}
+		break;
+
+	case EUsbServiceStopping:
+		if (iUsbClassControllerIterator->Previous() == KErrNotFound)
+			{
+			// if stopping classes, hide the USB interface from the host
+#ifndef __WINS__
+			iLdd.DeviceDisconnectFromHost();
+
+			// Restore the default serial number 
+			if (iDefaultSerialNumber)
+				{
+				TInt res = iLdd.SetSerialNumberStringDescriptor(*iDefaultSerialNumber);
+				LOGTEXT2(_L8("Restore default serial number res = %d"), res);
+				}
+			else
+				{
+				TInt res = iLdd.RemoveSerialNumberStringDescriptor();
+				LOGTEXT2(_L8("Remove serial number res = %d"), res);
+				}
+				
+#endif			
+			SetServiceState(EUsbServiceIdle);
+			}
+		else
+			{
+			StopCurrentClassController();
+			}
+		break;
+
+	default:
+		__ASSERT_DEBUG( EFalse, _USB_PANIC(KUsbDevicePanicCategory, EBadAsynchronousCall) );
+		break;
+		}
+	LOGTEXT(_L8("<<CUsbDevice::RunL"));
+	}
+
+void CUsbDevice::DoCancel()
+/**
+ * Standard active object cancellation function. If we're starting or stopping
+ * a USB class, cancels it. If we're not, then we shouldn't be active and hence
+ * this function being called is a programming error.
+ */
+	{
+	LOG_FUNC
+
+	switch (iServiceState)
+		{
+	case EUsbServiceStarting:
+	case EUsbServiceStopping:
+		iUsbClassControllerIterator->Current()->Cancel();
+		break;
+
+	default:
+		__ASSERT_DEBUG( EFalse, _USB_PANIC(KUsbDevicePanicCategory, EBadAsynchronousCall) );
+		break;
+		}
+	}
+
+TInt CUsbDevice::RunError(TInt aError)
+/**
+ * Standard active object RunError function. Handles errors which occur when
+ * starting and stopping the USB class objects.
+ *
+ * @param aError The error which occurred
+ * @return Always KErrNone, to avoid an active scheduler panic
+ */
+	{
+	LOGTEXT2(_L8("CUsbDevice::RunError [aError=%d]"), aError);
+
+	iLastError = aError;
+
+	switch (iServiceState)
+		{
+	case EUsbServiceStarting:
+	case EUsbServiceStarted:
+		// An error has happened while we're either started or starting, so
+		// we have to stop all the classes which were successfully started.
+		if ((iUsbClassControllerIterator->Current()->State() ==
+				EUsbServiceIdle) &&
+			(iUsbClassControllerIterator->Previous() == KErrNotFound))
+			{
+			SetServiceState(EUsbServiceIdle);
+			}
+		else
+			{
+			SetServiceState(EUsbServiceStopping);
+			StopCurrentClassController();
+			}
+		break;
+
+	case EUsbServiceStopping:
+		// Argh, we've got problems. Let's stop as many classes as we can.
+		if (iUsbClassControllerIterator->Previous() == KErrNotFound)
+			SetServiceState(EUsbServiceIdle);
+		else
+			StopCurrentClassController();
+		break;
+
+	default:
+		__ASSERT_DEBUG( EFalse, _USB_PANIC(KUsbDevicePanicCategory, EBadAsynchronousCall) );
+		break;
+		}
+
+	return KErrNone;
+	}
+
+CUsbClassControllerIterator* CUsbDevice::UccnGetClassControllerIteratorL()
+/**
+ * Function used by USB classes to get an iterator over the set of classes
+ * owned by this device. Note that the caller takes ownership of the iterator
+ * which this function returns.
+ *
+ * @return A new iterator
+ */
+	{
+	LOG_FUNC
+
+	return new (ELeave) CUsbClassControllerIterator(iSupportedClasses);
+	}
+
+void CUsbDevice::UccnError(TInt aError)
+/**
+ * Function called by USB classes to notify the device of a fatal error. In
+ * this situation, we should just stop all the classes we can.
+ *
+ * @param aError The error that's occurred
+ */
+	{
+	LOG_FUNC
+
+	RunError(aError);
+	}
+
+
+#ifdef __FLOG_ACTIVE
+void CUsbDevice::PrintDescriptor(CUsbDevice::TUsbDeviceDescriptor& aDeviceDescriptor)
+	{
+	LOGTEXT2(_L8("\tiLength is %d"), aDeviceDescriptor.iLength);
+	LOGTEXT2(_L8("\tiDescriptorType is %d"), aDeviceDescriptor.iDescriptorType);
+	LOGTEXT2(_L8("\tBcdUsb is: 0x%04x"), aDeviceDescriptor.iBcdUsb);
+	LOGTEXT2(_L8("\tDeviceClass is: 0x%02x"), aDeviceDescriptor.iDeviceClass);
+	LOGTEXT2(_L8("\tDeviceSubClass is: 0x%02x"), aDeviceDescriptor.iDeviceSubClass);
+	LOGTEXT2(_L8("\tDeviceProtocol is: 0x%02x"), aDeviceDescriptor.iDeviceProtocol);
+	LOGTEXT2(_L8("\tiMaxPacketSize is: 0x%02x"), aDeviceDescriptor.iMaxPacketSize);
+	
+	LOGTEXT2(_L8("\tVendorId is: 0x%04x"), aDeviceDescriptor.iIdVendor);
+	LOGTEXT2(_L8("\tProductId is: 0x%04x"), aDeviceDescriptor.iIdProduct);
+	LOGTEXT2(_L8("\tBcdDevice is: 0x%04x"), aDeviceDescriptor.iBcdDevice);
+
+	LOGTEXT2(_L8("\tiManufacturer is: 0x%04x"), aDeviceDescriptor.iManufacturer);
+	LOGTEXT2(_L8("\tiSerialNumber is: 0x%04x"), aDeviceDescriptor.iSerialNumber);
+	LOGTEXT2(_L8("\tiNumConfigurations is: 0x%04x"), aDeviceDescriptor.iNumConfigurations);
+	}
+#endif
+//
+void CUsbDevice::SetDeviceDescriptorL()
+/**
+ * Modifies the USB device descriptor.
+ */
+	{
+	LOG_FUNC
+
+#ifndef __WINS__
+
+	TInt desSize = 0;
+	iLdd.GetDeviceDescriptorSize(desSize);
+	LOGTEXT2(_L8("UDeviceDescriptorSize = %d"), desSize);
+	HBufC8* deviceBuf = HBufC8::NewLC(desSize);
+	TPtr8   devicePtr = deviceBuf->Des();
+	devicePtr.SetLength(0);
+
+	TInt ret = iLdd.GetDeviceDescriptor(devicePtr);
+
+	if (ret != KErrNone)
+		{
+		LOGTEXT2(_L8("Unable to fetch device descriptor. Error: %d"), ret);
+		LEAVEL(ret);
+		}
+
+	TUsbDeviceDescriptor* deviceDescriptor = reinterpret_cast<TUsbDeviceDescriptor*>(
+		const_cast<TUint8*>(devicePtr.Ptr()));
+
+
+#else
+
+	// Create an empty descriptor to allow the settings
+	// to be read in from the resource file
+	TUsbDeviceDescriptor descriptor;
+	TUsbDeviceDescriptor* deviceDescriptor = &descriptor;
+	
+#endif // __WINS__
+
+	if (iPersonalityCfged)
+		{
+		SetUsbDeviceSettingsFromPersonalityL(*deviceDescriptor);		
+		}
+	else
+		{
+	SetUsbDeviceSettingsL(*deviceDescriptor);
+		}
+	
+#ifndef __WINS__
+	ret = iLdd.SetDeviceDescriptor(devicePtr);
+
+	if (ret != KErrNone)
+		{
+		LOGTEXT2(_L8("Unable to set device descriptor. Error: %d"), ret);
+		LEAVEL(ret);
+		}
+
+	CleanupStack::PopAndDestroy(deviceBuf);
+
+#endif // __WINS__
+	}
+
+void CUsbDevice::SetUsbDeviceSettingsDefaultsL(CUsbDevice::TUsbDeviceDescriptor& aDeviceDescriptor)
+/**
+ * Set the device settings defaults, as per the non-resource
+ * version of the USB manager
+ *
+ * @param aDeviceDescriptor The device descriptor for the USB device
+ */
+	{
+	aDeviceDescriptor.iDeviceClass		= KUsbDefaultDeviceClass;
+	aDeviceDescriptor.iDeviceSubClass	= KUsbDefaultDeviceSubClass;
+	aDeviceDescriptor.iDeviceProtocol	= KUsbDefaultDeviceProtocol;
+	aDeviceDescriptor.iIdVendor			= KUsbDefaultVendorId;
+	aDeviceDescriptor.iIdProduct		= KUsbDefaultProductId;
+	}
+
+void CUsbDevice::SetUsbDeviceSettingsL(CUsbDevice::TUsbDeviceDescriptor& aDeviceDescriptor)
+/**
+ * Configure the USB device, reading in the settings from a
+ * resource file where possible.
+ *
+ * @param aDeviceDescriptor The device descriptor for the USB device
+ */
+	{
+	LOG_FUNC
+
+	// First, use the default values
+	LOGTEXT(_L8("Setting default values for the configuration"));
+	SetUsbDeviceSettingsDefaultsL(aDeviceDescriptor);
+
+	// Now try to get the configuration from the resource file
+	RFs fs;
+	LEAVEIFERRORL(fs.Connect());
+	CleanupClosePushL(fs);
+
+	RResourceFile resource;
+	TRAPD(err, resource.OpenL(fs, KUsbManagerResource));
+	LOGTEXT2(_L8("Opened resource file with error %d"), err);
+
+	if (err != KErrNone)
+		{
+		LOGTEXT(_L8("Unable to open resource file: using default settings"));
+		CleanupStack::PopAndDestroy(&fs);
+		return;
+		}
+
+	CleanupClosePushL(resource);
+
+	resource.ConfirmSignatureL(KUsbManagerResourceVersion);
+
+	HBufC8* id = resource.AllocReadLC(USB_CONFIG);
+
+	// The format of the USB resource structure is:
+	//
+	//	STRUCT usb_configuration
+	//		{
+	//		WORD	vendorId		= 0x0e22;
+	//		WORD	productId		= 0x000b;
+	//		WORD	bcdDevice		= 0x0000;
+	//		LTEXT	manufacturer	= "Symbian Ltd.";
+	//		LTEXT	product			= "Symbian OS";
+	//		}
+	//
+	// Note that the resource must be read in this order!
+	
+	TResourceReader reader;
+	reader.SetBuffer(id);
+
+	aDeviceDescriptor.iIdVendor = static_cast<TUint16>(reader.ReadUint16());
+	aDeviceDescriptor.iIdProduct = static_cast<TUint16>(reader.ReadUint16());
+	aDeviceDescriptor.iBcdDevice = static_cast<TUint16>(reader.ReadUint16());
+
+	// Try to read device and manufacturer name from new SysUtil API
+	TPtrC16 sysUtilModelName;
+	TPtrC16 sysUtilManuName;
+	
+	// This method returns ownership.
+	CDeviceTypeInformation* deviceInfo = SysUtil::GetDeviceTypeInfoL();
+	CleanupStack::PushL(deviceInfo);
+	TInt gotSysUtilModelName = deviceInfo->GetModelName(sysUtilModelName);
+	TInt gotSysUtilManuName = deviceInfo->GetManufacturerName(sysUtilManuName);
+	
+	TPtrC manufacturerString = reader.ReadTPtrC();
+	TPtrC productString = reader.ReadTPtrC();
+	
+	// If we succesfully read the manufacturer or device name from SysUtil API
+	// then set these results, otherwise use the values defined in resource file
+#ifndef __WINS__
+	if (gotSysUtilManuName == KErrNone)
+		{
+		LEAVEIFERRORL(iLdd.SetManufacturerStringDescriptor(sysUtilManuName));
+		}
+	else
+		{
+		LEAVEIFERRORL(iLdd.SetManufacturerStringDescriptor(manufacturerString));
+		}
+
+	if (gotSysUtilModelName == KErrNone)
+		{
+		LEAVEIFERRORL(iLdd.SetProductStringDescriptor(sysUtilModelName));
+		}
+	else
+		{
+		LEAVEIFERRORL(iLdd.SetProductStringDescriptor(productString));
+		}
+#endif // __WINS__
+
+#ifdef __FLOG_ACTIVE
+	PrintDescriptor(aDeviceDescriptor);	
+	TBuf8<KUsbStringDescStringMaxSize> narrowString;
+	narrowString.Copy(manufacturerString);
+	LOGTEXT2(_L8("Manufacturer is: '%S'"), &narrowString);
+	narrowString.Copy(productString);
+	LOGTEXT2(_L8("Product is: '%S'"), &narrowString);
+#endif // __FLOG_ACTIVE
+
+#ifndef __WINS__	
+	//Read the published serial number. The key is the UID KUidUsbmanServer = 0x101FE1DB
+	TBuf16<KUsbStringDescStringMaxSize> serNum;
+	TInt r = RProperty::Get(KUidSystemCategory,0x101FE1DB,serNum);
+	if(r==KErrNone)
+		{
+#ifdef __FLOG_ACTIVE
+		TBuf8<KUsbStringDescStringMaxSize> narrowString;
+		narrowString.Copy(serNum);
+		LOGTEXT2(_L8("Setting published SerialNumber: %S"), &narrowString);
+#endif // __FLOG_ACTIVE
+		//USB spec doesn't give any constraints on what constitutes a valid serial number.
+		//As long as it is a string descriptor it is valid.
+		LEAVEIFERRORL(iLdd.SetSerialNumberStringDescriptor(serNum));	
+		}
+#ifdef __FLOG_ACTIVE
+	else
+		{
+		LOGTEXT(_L8("SerialNumber has not been published"));	
+		}
+#endif // __FLOG_ACTIVE
+#endif // __WINS__
+
+
+	CleanupStack::PopAndDestroy(4, &fs); //  deviceInfo, id, resource, fs
+	}
+
+void CUsbDevice::SetUsbDeviceSettingsFromPersonalityL(CUsbDevice::TUsbDeviceDescriptor& aDeviceDescriptor)
+/**
+ * Configure the USB device from the current personality.
+ *
+ * @param aDeviceDescriptor The device descriptor for the USB device
+ */
+	{
+	LOG_FUNC
+
+	// First, use the default values
+	LOGTEXT(_L8("Setting default values for the configuration"));
+	SetUsbDeviceSettingsDefaultsL(aDeviceDescriptor);
+
+	// Now try to get the configuration from the current personality
+	const CUsbDevice::TUsbDeviceDescriptor& deviceDes = iCurrentPersonality->DeviceDescriptor();
+	aDeviceDescriptor.iDeviceClass			= deviceDes.iDeviceClass;
+	aDeviceDescriptor.iDeviceSubClass		= deviceDes.iDeviceSubClass;
+	aDeviceDescriptor.iDeviceProtocol		= deviceDes.iDeviceProtocol;
+	aDeviceDescriptor.iIdVendor				= deviceDes.iIdVendor;
+	aDeviceDescriptor.iIdProduct			= deviceDes.iIdProduct;
+	aDeviceDescriptor.iBcdDevice			= deviceDes.iBcdDevice;
+	aDeviceDescriptor.iSerialNumber			= deviceDes.iSerialNumber;
+	aDeviceDescriptor.iNumConfigurations	= deviceDes.iNumConfigurations;
+
+#ifndef __WINS__
+	LEAVEIFERRORL(iLdd.SetManufacturerStringDescriptor(*(iCurrentPersonality->Manufacturer())));
+	LEAVEIFERRORL(iLdd.SetProductStringDescriptor(*(iCurrentPersonality->Product())));
+
+	//Read the published serial number. The key is the UID KUidUsbmanServer = 0x101FE1DB
+	TBuf16<KUsbStringDescStringMaxSize> serNum;
+	TInt r = RProperty::Get(KUidSystemCategory,0x101FE1DB,serNum);
+	if(r==KErrNone)
+		{
+#ifdef __FLOG_ACTIVE
+		TBuf8<KUsbStringDescStringMaxSize> narrowString;
+		narrowString.Copy(serNum);
+		LOGTEXT2(_L8("Setting published SerialNumber: %S"), &narrowString);
+#endif // __FLOG_ACTIVE
+		//USB spec doesn't give any constraints on what constitutes a valid serial number.
+		//As long as it is a string descriptor it is valid.
+		LEAVEIFERRORL(iLdd.SetSerialNumberStringDescriptor(serNum));	
+		}
+#ifdef __FLOG_ACTIVE
+	else
+		{
+		LOGTEXT(_L8("SerialNumber has not been published"));	
+		}
+#endif // __FLOG_ACTIVE
+#endif // __WINS__
+
+
+#ifdef __FLOG_ACTIVE
+	PrintDescriptor(aDeviceDescriptor);		
+
+#ifndef __WINS__
+	TBuf16<KUsbStringDescStringMaxSize> wideString;
+	TBuf8<KUsbStringDescStringMaxSize> narrowString;
+
+	LEAVEIFERRORL(iLdd.GetConfigurationStringDescriptor(wideString));
+	narrowString.Copy(wideString);
+	LOGTEXT2(_L8("Configuration is: '%S'"), &narrowString);
+#endif // __WINS__
+
+#endif // __FLOG_ACTIVE
+	}
+	
+void CUsbDevice::TryStartL(TInt aPersonalityId)
+/**
+ * Start all USB classes associated with the personality identified
+ * by aPersonalityId. Reports errors and state changes via observer 
+ * interface.
+ *
+ * @param aPersonalityId a personality id
+ */
+	{
+	LOG_FUNC
+	SetCurrentPersonalityL(aPersonalityId);
+	
+	SelectClassControllersL();
+	SetServiceState(EUsbServiceStarting);
+
+	TRAPD(err, SetDeviceDescriptorL());
+	if ( err != KErrNone )
+		{
+		SetServiceState(EUsbServiceIdle);
+		LEAVEL(err);		
+		}
+
+	iLastError = KErrNone;
+	StartCurrentClassController();
+ 	}
+ 	
+TInt CUsbDevice::CurrentPersonalityId() const
+/**
+ * @return the current personality id
+ */
+ 	{
+	LOG_FUNC
+ 	return iCurrentPersonality->PersonalityId();
+ 	}
+ 	
+const RPointerArray<CPersonality>& CUsbDevice::Personalities() const
+/**
+ * @return a const reference to RPointerArray<CPersonality>
+ */
+ 	{
+	LOG_FUNC
+ 	return iSupportedPersonalities;
+ 	} 
+ 	
+const CPersonality* CUsbDevice::GetPersonality(TInt aPersonalityId) const
+/**
+ * Obtains a handle to the CPersonality object whose id is aPersonalityId
+ *
+ * @param aPeraonalityId a personality id
+ * @return a const pointer to the CPersonality object whose id is aPersonalityId if found
+ * or 0 otherwise.
+ */
+	{
+	LOG_FUNC
+	
+	TInt count = iSupportedPersonalities.Count();
+	for (TInt i = 0; i < count; i++)
+		{
+		if (iSupportedPersonalities[i]->PersonalityId() == aPersonalityId)
+			{
+			return iSupportedPersonalities[i];
+			}
+		}
+	
+	return 0;
+	}
+	
+void CUsbDevice::SetCurrentPersonalityL(TInt aPersonalityId)
+/**
+ * Sets the current personality to the personality with id aPersonalityId
+ */
+ 	{
+	LOG_FUNC
+	const CPersonality* personality = GetPersonality(aPersonalityId);
+	if (!personality)
+		{
+		LOGTEXT(_L8("Personality id not found"));
+		LEAVEL(KErrNotFound);
+		}
+		
+	iCurrentPersonality = personality;
+ 	}
+	
+void CUsbDevice::ValidatePersonalitiesL()
+/**
+ * Verifies all class controllers associated with each personality are loaded.
+ * Leave if validation fails.
+ */
+	{
+	LOG_FUNC
+
+	TInt personalityCount = iSupportedPersonalities.Count();
+	for (TInt i = 0; i < personalityCount; i++)
+		{
+		const RArray<TUid>& classUids = iSupportedPersonalities[i]->SupportedClasses();
+		TInt uidCount = classUids.Count();
+		for (TInt j = 0; j < uidCount; j++)	
+			{
+			TInt ccCount = iSupportedClassUids.Count();
+			TInt k;
+			for (k = 0; k < ccCount; k++)
+				{
+				if (iSupportedClassUids[k] == classUids[j])
+					{
+					break;
+					}
+				}
+			if (k == ccCount)
+				{
+				LOGTEXT(_L8("personality validation failed"));
+				LEAVEL(KErrAbort);
+				}					
+			}	
+		}
+	}
+/**
+Converts text string with UIDs to array of Uint
+
+If there is an error during the conversion, this function will not clean-up,
+so there may still be UIDs allocated in the RArray.
+
+@param aStr Reference to a string containing one or more UIDs in hex
+@param aUIDs On return array of UIDs parsed from the input string
+@panic EUidArrayNotEmpty if the RArray passed in is not empty
+*/
+void CUsbDevice::ConvertUidsL(const TDesC& aStr, RArray<TUint>& aUidArray)	
+	{
+	// Function assumes that aUIDs is empty
+	__ASSERT_DEBUG( aUidArray.Count() == 0, _USB_PANIC(KUsbDevicePanicCategory, EUidArrayNotEmpty) );
+
+	TLex input(aStr);
+
+	// Scan through string to find UIDs
+	// Need to do this at least once, as no UID in the string is an error
+	do 
+		{
+		// Find first hex digit
+		while (!(input.Eos() || input.Peek().IsHexDigit()))
+			{
+			input.Inc();	
+			}
+
+		// Convert and add to array
+		TUint val;
+		LEAVEIFERRORL(input.Val(val,EHex));
+		aUidArray.AppendL(val);
+		}
+	while (!input.Eos());	
+	}
+
+void CUsbDevice::ReadPersonalitiesL()
+/**
+ * Reads configured personalities from the resource file
+ */
+	{
+	LOG_FUNC
+	iPersonalityCfged = EFalse;
+	// Now try to connect to file server
+	RFs fs;
+	LEAVEIFERRORL(fs.Connect());
+	CleanupClosePushL(fs);
+
+	TFileName resourceFileName;
+	ResourceFileNameL(resourceFileName);
+	RResourceFile resource;
+	TRAPD(err, resource.OpenL(fs, resourceFileName));
+	LOGTEXT2(_L8("Opened resource file with error %d"), err);
+
+	if (err != KErrNone)
+		{
+		LOGTEXT(_L8("Unable to open resource file"));
+		CleanupStack::PopAndDestroy(&fs);
+		return;
+		}
+
+	CleanupClosePushL(resource);
+
+	TInt resourceVersion = resource.SignatureL();
+	LOGTEXT2(_L8("Resource file signature is %d"), resourceVersion);
+	// Check for the version is valid(EUsbManagerResourceVersionOne, EUsbManagerResourceVersionTwo
+	// or EUsbManagerResourceVersionThree).
+	if(resourceVersion > EUsbManagerResourceVersionThree)
+		{
+		LOGTEXT2(_L8("Version of resource file is valid (>%d)"), EUsbManagerResourceVersionThree);
+		User::LeaveIfError(KErrNotSupported);
+		}
+	
+	resource.ConfirmSignatureL(resourceVersion);
+
+	HBufC8* personalityBuf = 0;
+	TRAPD(ret, personalityBuf = resource.AllocReadL(DEVICE_PERSONALITIES));
+	// If personalities resource is not found, swallow the error and return
+	// as no specified personalities is a valid configuration
+	if (ret == KErrNotFound)
+		{
+		LOGTEXT(_L8("Personalities are not configured"));
+		CleanupStack::PopAndDestroy(2, &fs); 
+		return;
+		}
+	// Otherwise leave noisily if the AllocRead fails
+	LEAVEIFERRORL(ret);
+	CleanupStack::PushL(personalityBuf);
+
+	// The format of the USB resource structure is:
+	//
+	// 	STRUCT PERSONALITY
+	//		{
+	// 		WORD	bcdDeviceClass;
+	// 		WORD	bcdDeviceSubClass;
+	//		WORD 	protocol;
+	//		WORD	numConfigurations;
+	//		WORD 	vendorId;
+	//		WORD 	productId;
+	//		WORD 	bcdDevice;
+	//		LTEXT 	manufacturer;
+	//		LTEXT 	product;
+	//		WORD 	id;					// personality id
+	//		LTEXT	class_uids;	
+	//		LTEXT 	description;		// personality description
+	//     	LTEXT   detailedDescription;  //detailed description. This is in version 2
+	//		LONG 	Property;
+	//		}
+	//
+	// Note that the resource must be read in this order!
+	
+	TResourceReader reader;
+	reader.SetBuffer(personalityBuf);
+
+	TUint16 personalityCount 	= static_cast<TUint16>(reader.ReadUint16());
+	
+	// Read the manufacturer and device name (product) here from SysUtil class
+	TPtrC16 sysUtilModelName;
+	TPtrC16 sysUtilManuName;
+
+	// This method returns ownership.
+	CDeviceTypeInformation* deviceInfo = SysUtil::GetDeviceTypeInfoL();
+	CleanupStack::PushL(deviceInfo);
+	TInt gotSysUtilModelName = deviceInfo->GetModelName(sysUtilModelName);
+	TInt gotSysUtilManuName = deviceInfo->GetManufacturerName(sysUtilManuName);
+	
+	for (TInt idx = 0; idx < personalityCount; idx++)
+		{
+		// read a personality 
+		TUint8 	bDeviceClass 		= static_cast<TUint8>(reader.ReadUint8());
+		TUint8 	bDeviceSubClass 	= static_cast<TUint8>(reader.ReadUint8());
+		TUint8 	protocol 			= static_cast<TUint8>(reader.ReadUint8());
+		TUint8 	numConfigurations	= static_cast<TUint8>(reader.ReadUint8());
+		TUint16 vendorId			= static_cast<TUint16>(reader.ReadUint16());
+		TUint16 productId			= static_cast<TUint16>(reader.ReadUint16());
+		TUint16 bcdDevice			= static_cast<TUint16>(reader.ReadUint16());
+		TPtrC	manufacturer		= reader.ReadTPtrC();
+		TPtrC	product				= reader.ReadTPtrC();
+		TUint16 id					= static_cast<TUint16>(reader.ReadUint16());
+		TPtrC	uidsStr				= reader.ReadTPtrC();
+		TPtrC 	description			= reader.ReadTPtrC();
+		
+		RArray<TUint> uids;
+		CleanupClosePushL(uids);
+		ConvertUidsL(uidsStr, uids);
+		// creates a CPersonality object
+		CPersonality* personality = CPersonality::NewL();
+		CleanupStack::PushL(personality);
+
+		personality->SetVersion(resourceVersion);
+		
+		// populates personality object
+		personality->SetId(id);
+		        
+		for (TInt uidIdx = 0; uidIdx < uids.Count(); uidIdx++)
+			{
+			LEAVEIFERRORL(personality->AddSupportedClasses(TUid::Uid(uids[uidIdx])));
+			}
+		
+		// gets a handle to iDeviceDescriptor of personality
+		CUsbDevice::TUsbDeviceDescriptor& dvceDes = personality->DeviceDescriptor();
+		if (gotSysUtilManuName == KErrNone)
+			{
+			personality->SetManufacturer(&sysUtilManuName);
+			}
+		else
+			{
+			personality->SetManufacturer(&manufacturer);
+			}
+			
+		if (gotSysUtilModelName == KErrNone)
+			{
+			personality->SetProduct(&sysUtilModelName);
+			}
+		else
+			{
+			personality->SetProduct(&product);
+			}
+			
+		personality->SetDescription(&description);
+		dvceDes.iDeviceClass = bDeviceClass;
+		dvceDes.iDeviceSubClass = bDeviceSubClass;
+		dvceDes.iDeviceProtocol = protocol;
+		dvceDes.iIdVendor = vendorId;
+		dvceDes.iIdProduct= productId;
+		dvceDes.iBcdDevice = bcdDevice;
+		dvceDes.iNumConfigurations = numConfigurations;
+		
+		//detailedDescription is only supported after EUsbManagerResourceVersionTwo
+		if(resourceVersion >= EUsbManagerResourceVersionTwo)
+			{
+			TPtrC   detailedDescription = reader.ReadTPtrC();        
+			personality->SetDetailedDescription(&detailedDescription);
+#ifdef __FLOG_ACTIVE
+			TBuf8<KUsbDescMaxSize_String> narrowLongBuf;
+			narrowLongBuf.Copy(detailedDescription);
+			LOGTEXT2(_L8("detailed description = '%S'"),        &narrowLongBuf);            
+#endif // __FLOG_ACTIVE
+			}
+
+		//Property is only supported after EUsbManagerResourceVersionThree
+		if(resourceVersion >= EUsbManagerResourceVersionThree)
+			{
+			TUint32 property			= static_cast<TUint32>(reader.ReadUint32());
+			personality->SetProperty(property);
+#ifdef __FLOG_ACTIVE
+		LOGTEXT2(_L8("property = %d\n"), 			property);
+#endif // __FLOG_ACTIVE
+			}
+		
+		// Append personality to iSupportedPersonalities
+		iSupportedPersonalities.AppendL(personality);
+		// Now pop off personality
+		CleanupStack::Pop(personality);
+#ifdef __FLOG_ACTIVE
+		// Debugging
+		LOGTEXT2(_L8("personalityCount = %d\n"), 	personalityCount);
+		LOGTEXT2(_L8("bDeviceClass = %d\n"), 		bDeviceClass);
+		LOGTEXT2(_L8("bDeviceSubClass = %d\n"), 	bDeviceSubClass);
+		LOGTEXT2(_L8("protocol = %d\n"), 			protocol);
+		LOGTEXT2(_L8("numConfigurations = %d\n"), 	numConfigurations);
+		LOGTEXT2(_L8("vendorId = %d\n"), 			vendorId);
+		LOGTEXT2(_L8("productId = %d\n"), 			productId);
+		LOGTEXT2(_L8("bcdDevice = %d\n"), 			bcdDevice);
+		TBuf8<KMaxName> narrowBuf;
+		narrowBuf.Copy(manufacturer);
+		LOGTEXT2(_L8("manufacturer = '%S'"), 		&narrowBuf);
+		narrowBuf.Copy(product);
+		LOGTEXT2(_L8("product = '%S'"), 			&narrowBuf);
+		LOGTEXT2(_L8("id = %d\n"), 					id);
+		LOGTEXT(_L8("ClassUids{"));
+		for (TInt k = 0; k < uids.Count(); k++)
+			{
+			LOGTEXT2(_L8("%d"), uids[k]);
+			}
+		LOGTEXT(_L8("}"));
+		narrowBuf.Copy(description);
+		LOGTEXT2(_L8("description = '%S'"), 		&narrowBuf);
+#endif // __FLOG_ACTIVE
+		CleanupStack::PopAndDestroy(&uids);	// close uid array		
+		}
+		
+	CleanupStack::PopAndDestroy(4, &fs); // deviceInfo, personalityBuf, resource, fs
+	iPersonalityCfged = ETrue;	
+	}
+	
+void CUsbDevice::SelectClassControllersL()
+/**
+ * Selects class controllers for the current personality
+ */
+	{
+	LOG_FUNC
+
+	CreateClassControllersL(iCurrentPersonality->SupportedClasses());
+	}
+#ifdef USE_DUMMY_CLASS_CONTROLLER	
+void CUsbDevice::CreateClassControllersL(const RArray<TUid>& /* aClassUids*/)
+#else 
+void CUsbDevice::CreateClassControllersL(const RArray<TUid>& aClassUids)
+#endif
+/**
+ * Creates a class controller object for each class uid
+ *
+ * @param aClassUids an array of class uids
+ */
+ 	{
+	LOG_FUNC
+
+#ifndef USE_DUMMY_CLASS_CONTROLLER
+
+	//create a TLinearOrder to supply the comparison function, Compare(), to be used  
+	//to determine the order to add class controllers
+	TLinearOrder<CUsbClassControllerBase> order(CUsbClassControllerBase::Compare);
+
+	TInt count = aClassUids.Count();
+	
+	// destroy any class controller objects in iSupportedClasses and reset it for reuse
+	iSupportedClasses.ResetAndDestroy();
+	LOGTEXT2(_L8("aClassUids.Count() = %d\n"), 	count);
+	for (TInt i = 0; i < count; i++)
+		{ 
+		CUsbClassControllerPlugIn* plugIn = CUsbClassControllerPlugIn::NewL(aClassUids[i], *this);
+		AddClassControllerL(reinterpret_cast<CUsbClassControllerBase*>(plugIn), order);
+		} 
+#endif // USE_DUMMY_CLASS_CONTROLLER	
+
+	LEAVEIFERRORL(iUsbClassControllerIterator->First());
+ 	}
+
+void CUsbDevice::SetDefaultPersonalityL()
+/**
+ * Sets default personality. Used for Start request.
+ */
+	{
+	LOG_FUNC
+
+	TInt smallestId = iSupportedPersonalities[0]->PersonalityId();
+ 	TInt count = iSupportedPersonalities.Count();
+ 	
+ 	for (TInt i = 1; i < count; i++)
+ 		{
+ 		if(iSupportedPersonalities[i]->PersonalityId() < smallestId)
+ 			{
+ 			smallestId = iSupportedPersonalities[i]->PersonalityId();
+ 			}
+ 		}
+
+	SetCurrentPersonalityL(smallestId);
+	SelectClassControllersL();
+	}
+
+void CUsbDevice::LoadFallbackClassControllersL()
+/**
+ * Load class controllers for fallback situation:
+ * no personalities are configured.
+ * This method inserts all class controllers to 
+ * the list from which they will be either all started
+ * or stopped
+ */
+ 	{
+	LOG_FUNC
+ 	SetDeviceDescriptorL();
+	CreateClassControllersL(iSupportedClassUids);
+ 	}
+ 	
+void CUsbDevice::ResourceFileNameL(TFileName& aFileName)
+/**
+ * Gets resource file name
+ *
+ * @param aFileName Descriptor to populate with resource file name
+ */
+ 	{
+	LOG_FUNC
+
+	RFs fs;
+	LEAVEIFERRORL(fs.Connect());
+	CleanupClosePushL(fs);
+
+#ifdef __WINS__
+	// If we are running in the emulator then read the resource file from system drive.
+	// This makes testing with different resource files easier.
+	_LIT(KPrivatePath, ":\\Private\\101fe1db\\");
+	aFileName.Append(RFs::GetSystemDriveChar()); //get the name of system drive
+	aFileName.Append(KPrivatePath);
+#else
+ 	const TDriveNumber KResourceDrive = EDriveZ;
+
+	TDriveUnit driveUnit(KResourceDrive);
+	TDriveName drive=driveUnit.Name();
+	aFileName.Insert(0, drive);
+	// append private path
+	TPath privatePath;
+	fs.PrivatePath(privatePath);
+	aFileName.Append(privatePath);		
+#endif //WINS
+
+	// Find the nearest match of resource file for the chosen locale
+	aFileName.Append(_L("usbman.rsc"));
+	BaflUtils::NearestLanguageFile(fs, aFileName); // if a match is not found, usbman.rsc will be used
+
+	CleanupStack::PopAndDestroy(&fs);	// fs no longer needed
+ 	}
+
+RDevUsbcClient& CUsbDevice::MuepoDoDevUsbcClient()
+/**
+ * Inherited from MUsbmanExtensionPluginObserver - Function used by plugins to
+ * retrieve our handle to the LDD
+ *
+ * @return The LDD handle
+ */
+	{
+	return iLdd;
+	}
+
+void CUsbDevice::MuepoDoRegisterStateObserverL(MUsbDeviceNotify& aObserver)
+/**
+ * Inherited from MUsbmanExtensionPluginObserver - Function used by plugins to
+ * register themselves for notifications of device/service state changes.
+ *
+ * @param aObserver New Observer of the device
+ */
+	{
+	LOGTEXT2(_L8("CUsbDevice::MuepoDoRegisterStateObserverL aObserver = 0x%08x"),&aObserver);
+	RegisterObserverL(aObserver);
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/CUsbDeviceStateWatcher.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,122 @@
+/*
+* Copyright (c) 1997-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:
+* Talks directly to the USB Logical Device Driver (LDD) and 
+* watches any state changes
+*
+*/
+
+/**
+ @file
+*/
+
+#include <usb/usblogger.h>
+#include "CUsbScheduler.h"
+#include "CUsbDeviceStateWatcher.h"
+#include "CUsbDevice.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBSVR");
+#endif
+
+/**
+ * The CUsbDeviceStateWatcher::NewL method
+ *
+ * Constructs a new CUsbDeviceStateWatcher object
+ *
+ * @internalComponent
+ * @param	aOwner	The device that owns the state watcher
+ * @param	aLdd	A reference to the USB Logical Device Driver
+ *
+ * @return	A new CUsbDeviceStateWatcher object
+ */
+CUsbDeviceStateWatcher* CUsbDeviceStateWatcher::NewL(CUsbDevice& aOwner, RDevUsbcClient& aLdd)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbDeviceStateWatcher* r = new (ELeave) CUsbDeviceStateWatcher(aOwner, aLdd);
+	return r;
+	}
+
+
+/**
+ * The CUsbDeviceStateWatcher::~CUsbDeviceStateWatcher method
+ *
+ * Destructor
+ *
+ * @internalComponent
+ */
+CUsbDeviceStateWatcher::~CUsbDeviceStateWatcher()
+	{
+	LOGTEXT2(_L8(">CUsbDeviceStateWatcher::~CUsbDeviceStateWatcher (0x%08x)"), (TUint32) this);
+	Cancel();
+	}
+
+
+/**
+ * The CUsbDeviceStateWatcher::CUsbDeviceStateWatcher method
+ *
+ * Constructor
+ *
+ * @param	aOwner	The device that owns the state watcher
+ * @param	aLdd	A reference to the USB Logical Device Driver
+ */
+CUsbDeviceStateWatcher::CUsbDeviceStateWatcher(CUsbDevice& aOwner, RDevUsbcClient& aLdd)
+	: CActive(CActive::EPriorityStandard), iOwner(aOwner), iLdd(aLdd)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+/**
+ * Called when the USB device changes its state.
+ */
+void CUsbDeviceStateWatcher::RunL()
+	{
+	if (iStatus.Int() != KErrNone)
+		{
+		LOGTEXT2(_L8("CUsbDeviceStateWatcher::RunL() - Error = %d"), iStatus.Int());
+		return;
+		}
+
+	LOGTEXT2(_L8("CUsbDeviceStateWatcher::RunL() - State Changed to %d"), iState);
+
+	if (!(iState & KUsbAlternateSetting))
+		iOwner.SetDeviceState((TUsbcDeviceState) iState);
+
+	LOGTEXT(_L8("CUsbDeviceStateWatcher::RunL() - About to call DeviceStatusNotify"));
+	iLdd.AlternateDeviceStatusNotify(iStatus, iState);
+	SetActive();
+	LOGTEXT(_L8("CUsbDeviceStateWatcher::RunL() - Called DeviceStatusNotify"));
+	}
+
+
+/**
+ * Automatically called when the state watcher is cancelled.
+ */
+void CUsbDeviceStateWatcher::DoCancel()
+	{
+	LOG_FUNC
+	iLdd.AlternateDeviceStatusNotifyCancel();
+	}
+
+
+/**
+ * Instructs the state watcher to start watching.
+ */
+void CUsbDeviceStateWatcher::Start()
+	{
+	LOG_FUNC
+	iLdd.AlternateDeviceStatusNotify(iStatus, iState);
+	SetActive();
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/CUsbDummyClassController.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,502 @@
+/*
+* Copyright (c) 1997-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:
+* Implements part of UsbMan USB Class Framework.
+*
+*/
+
+/**
+ @file
+*/
+
+#include "CUsbDummyClassController.h"
+#include <usb_std.h>
+#include "inifile.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBSVR");
+#endif
+
+_LIT(KDummyControllerPanic, "UsbDummyCC"); // must be <=16 chars
+// Panic codes
+enum
+	{
+	// Bad value for the iSynchronicity member.
+	EDummyPanicBadSynchronicity = 0,
+	
+	// Used for environment errors we do not handle.
+	EDummyPanicUnhandledError = 1,
+	
+	// Used for bad iStatus and other state errors.
+	EDummyPanicBadState = 2,
+	
+	// Error reading ini file.
+	EDummyPanicBadIniFile = 3,
+	
+	// We already have our async request active.
+	EDummyPanicAlreadyActive = 4,
+	
+	// We already have a request outstanding from the device class. 
+	EDummyPanicOutstandingRequestFromDevice = 5,
+	
+	// Attempt to call Start() when in illegal state
+	EDummyPanicBadApiCallStart = 6,
+	
+	// Attempt to call Stop() when in illegal state
+	EDummyPanicBadApiCallStop = 7,
+	};
+
+const TInt KDummyClassPriority = 1;
+
+// Keys for reading the ini file.
+_LIT(KStartup, "Startup");
+_LIT(KShutdown, "Shutdown");
+_LIT(KType, "Type");
+_LIT(KTime, "Time");
+_LIT(KError, "Error");
+_LIT(KSync, "sync");
+_LIT(KAsync, "async");
+_LIT(KNever, "never");
+
+CUsbDummyClassController* CUsbDummyClassController::NewL(
+		MUsbClassControllerNotify& aOwner,
+		TUint aIndex)
+/**
+ * Constructs a CUsbDummyClassController object.
+ *
+ * @param aOwner USB Device that owns and manages the class
+ * @param aIndex The index number of the instance
+ * @return Ownership of a new CUsbDummyClassController object
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbDummyClassController* self = new(ELeave) CUsbDummyClassController(aOwner, aIndex);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+CUsbDummyClassController* CUsbDummyClassController::NewL(
+	MUsbClassControllerNotify& aOwner, 
+	TUint aIndex, TInt aPriority)
+/**
+ * Constructs a CUsbDummyClassController object.
+ *
+ * @param aOwner USB Device that owns and manages the class
+ * @param aIndex The index number of the instance
+ * @param aPriority The startup priority of the instance
+ * @return Ownership of a new CUsbDummyClassController object
+ */
+ 	{
+	LOG_STATIC_FUNC_ENTRY
+
+ 	CUsbDummyClassController* self = new(ELeave) CUsbDummyClassController(aOwner, aIndex, aPriority);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+ 	}
+ 
+CUsbDummyClassController::CUsbDummyClassController(
+		MUsbClassControllerNotify& aOwner,
+		TUint aIndex)
+/**
+ * Constructor.
+ *
+ * @param aOwner USB Device that owns and manages the class
+ * @param aIndex The index number of the instance
+ */
+ :	CUsbClassControllerBase(aOwner, KDummyClassPriority),
+	iIndex(aIndex)
+	{
+	iState = EUsbServiceIdle; // needs explicit initialisation as non-zero
+	}
+
+CUsbDummyClassController::CUsbDummyClassController(
+		MUsbClassControllerNotify& aOwner,
+		TUint aIndex, TInt aPriority)
+		
+/**
+ * Constructor.
+ *
+ * @param aOwner USB Device that owns and manages the class
+ * @param aIndex The index number of the instance
+ * @param aPriority a startup priority for the class controller
+ */		
+ : 	CUsbClassControllerBase(aOwner, aPriority),
+ 	iIndex(aIndex)
+ 	{
+ 	iState = EUsbServiceIdle; // needs explicit initialisation as non-zero
+ 	}
+		
+void CUsbDummyClassController::ConstructL()
+/**
+ * Method to perform second phase construction.
+ */
+	{
+	LEAVEIFERRORL(iTimer.CreateLocal());
+	}
+
+CUsbDummyClassController::~CUsbDummyClassController()
+/**
+ * Destructor.
+ */
+	{
+	Cancel();
+
+	iTimer.Close();
+	}
+	
+void CUsbDummyClassController::GetBehaviour(CIniFile& aIniFile, 
+											const TDesC& aSection, 
+											TBehaviour& aBehaviour)
+/**
+ * Reads information from the ini file, from a given section, to the given 
+ * behaviour structure.
+ *
+ * @param aIniFile The ini file to read from.
+ * @param aSection The section to reads from.
+ * @param aBehaviour The behaviour struct to read to.
+ */
+	{
+	LOG_FUNC
+#ifdef __FLOG_ACTIVE
+	TBuf8<KMaxName> buf;
+	buf.Copy(aSection);
+	LOGTEXT2(_L8("\taSection = %S"), &buf);
+#endif // __FLOG_ACTIVE
+
+	TPtrC temp;
+	if ( !aIniFile.FindVar(aSection, KType(), temp) )
+		{
+		LOGTEXT2(_L8("\tPANICKING: can't find Type item in section %S"), &aSection);
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicBadIniFile);
+		}
+	if ( temp == KSync )
+		{
+		aBehaviour.iSynchronicity = ESynchronous;
+		}
+	else if ( temp == KAsync )
+		{
+		aBehaviour.iSynchronicity = EAsynchronous;
+		}
+	else if ( temp == KNever )
+		{
+		aBehaviour.iSynchronicity = ENever;
+		}
+	else
+		{
+		LOGTEXT3(_L8("\tPANICKING: bad Type value (%S) in section %S"), &temp, &aSection);
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicBadIniFile);
+		}
+	TInt delay;
+	if ( !aIniFile.FindVar(aSection, KTime(), delay) )
+		{
+		LOGTEXT2(_L8("\tPANICKING: can't find Time item in section %S"), &aSection);
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicBadIniFile);
+		}
+	aBehaviour.iDelay = delay;
+	if ( !aIniFile.FindVar(aSection, KError(), aBehaviour.iErrorCode) )
+		{
+		LOGTEXT2(_L8("\tPANICKING: can't find Error item in section %S"), &aSection);
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicBadIniFile);
+		}
+	}
+
+void CUsbDummyClassController::DoGetConfigL()
+/**
+ * Reads the config from the ini file.
+ */
+	{
+	LOG_FUNC
+
+	CIniFile* iniFile = CIniFile::NewL(_L("dummy.ini"));
+	CleanupStack::PushL(iniFile);
+	TName section;
+
+	// Read startup behaviour
+	section.Format(_L("%S.%d"), &KStartup(), iIndex);
+	GetBehaviour(*iniFile, section, iStartupBehaviour);
+	// Read shutdown behaviour
+	section.Format(_L("%S.%d"), &KShutdown(), iIndex);
+	GetBehaviour(*iniFile, section, iShutdownBehaviour);
+
+	CleanupStack::PopAndDestroy(iniFile);
+	}
+
+void CUsbDummyClassController::GetConfig()
+/**
+ * Reads the config from the ini file.
+ * Note that this is assumed to succeed. Any failure will break the test and 
+ * it's much cleaner to panic out of the test entirely rather than leave it to 
+ * the user to figure out what's gone wrong.
+ */
+	{
+	LOG_FUNC
+
+	// Always use dummy.ini. The entity setting up the test is responsible for 
+	// copying the correct file to c:\\dummy.ini. The first found 
+	// by FindByDir will be used. TODO: enforce c:\\.
+	TRAPD(err, DoGetConfigL());
+	if ( err != KErrNone )
+		{
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicUnhandledError);
+		}
+	
+	LOGTEXT2(_L8("\tLogging dummy class controller behaviour for instance %d"), iIndex);
+	LOGTEXT2(_L8("\tiStartupBehaviour.iSynchronicity = %d"), iStartupBehaviour.iSynchronicity);
+	LOGTEXT2(_L8("\tiStartupBehaviour.iDelay = %d"), iStartupBehaviour.iDelay.Int());
+	LOGTEXT2(_L8("\tiStartupBehaviour.iErrorCode = %d"), iStartupBehaviour.iErrorCode);
+	LOGTEXT2(_L8("\tiShutdownBehaviour.iSynchronicity = %d"), iShutdownBehaviour.iSynchronicity);
+	LOGTEXT2(_L8("\tiShutdownBehaviour.iDelay = %d"), iShutdownBehaviour.iDelay.Int());
+	LOGTEXT2(_L8("\tiShutdownBehaviour.iErrorCode = %d"), iShutdownBehaviour.iErrorCode);
+	}
+
+void CUsbDummyClassController::Start(TRequestStatus& aStatus)
+/**
+ * Called by UsbMan to start this class.
+ *
+ * @param aStatus Will be completed with success or failure.
+ */
+	{
+	LOG_FUNC
+	
+	//Start() should only be called if the CC is idle or started		
+	__ASSERT_DEBUG((iState == EUsbServiceIdle || iState == EUsbServiceStarted), 
+							_USB_PANIC(KDummyControllerPanic, EDummyPanicBadApiCallStart) );
+
+	// Get config from ini file. Note that can't be done once in ConstructL 
+	// because then, in the case of a CC which doesn't Stop, we'd never be 
+	// able to shut down USBMAN!
+	GetConfig();
+
+	// NB We enforce that the device doesn't re-post requests on us.
+	__ASSERT_DEBUG(!iReportStatus, 
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicOutstandingRequestFromDevice));
+	aStatus = KRequestPending;
+	iReportStatus = &aStatus;
+	
+	iState = EUsbServiceStarting;
+
+	switch ( iStartupBehaviour.iSynchronicity )
+		{
+	case ESynchronous:
+		User::After(iStartupBehaviour.iDelay);
+		iState = EUsbServiceStarted;
+		User::RequestComplete(iReportStatus, iStartupBehaviour.iErrorCode);
+		iReportStatus = NULL;
+		break;
+
+	case EAsynchronous:
+		iTimer.After(iStatus, iStartupBehaviour.iDelay);
+		__ASSERT_DEBUG(!IsActive(), _USB_PANIC(KDummyControllerPanic, EDummyPanicAlreadyActive));		
+		SetActive();
+		break;
+
+	case ENever:
+		// Don't do anything and never complete
+		break;
+
+	default:
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicBadSynchronicity);
+		break;
+		}
+	}
+
+void CUsbDummyClassController::Stop(TRequestStatus& aStatus)
+/**
+ * Called by UsbMan to stop this class.
+ *
+ * @param aStatus Will be completed with success or failure.
+ */
+	{
+	LOG_FUNC
+		
+	//Stop() should only be called if the CC is Started or Idle
+	__ASSERT_DEBUG((iState == EUsbServiceStarted || iState == EUsbServiceIdle), 
+				_USB_PANIC(KDummyControllerPanic, EDummyPanicBadApiCallStop));
+	
+	// Get config from ini file. Note that can't be done once in ConstructL 
+	// because then, in the case of a CC which doesn't Stop, we'd never be 
+	// able to shutdown USBMAN!
+	GetConfig();
+
+	// NB We enforce that the device doesn't re-post requests on us.
+	__ASSERT_DEBUG(!iReportStatus, 
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicOutstandingRequestFromDevice));
+	aStatus = KRequestPending;
+	iReportStatus = &aStatus;
+
+	iState = EUsbServiceStopping;
+
+	switch ( iShutdownBehaviour.iSynchronicity )
+		{
+	case ESynchronous:
+		User::After(iShutdownBehaviour.iDelay);
+		iState = EUsbServiceIdle;
+		User::RequestComplete(iReportStatus, iShutdownBehaviour.iErrorCode);
+		iReportStatus = NULL;
+		break;
+
+	case EAsynchronous:
+		iTimer.After(iStatus, iShutdownBehaviour.iDelay);
+    	__ASSERT_DEBUG(!IsActive(), _USB_PANIC(KDummyControllerPanic, EDummyPanicAlreadyActive));		
+		SetActive();
+		break;
+
+	case ENever:
+		// Don't do anything and never complete
+		break;
+
+	default:
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicBadSynchronicity);
+		break;
+		}
+	}
+
+void CUsbDummyClassController::GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const
+/**
+ * Returns information about the interfaces supported by this class.
+ *
+ * @param aDescriptorInfo Will be filled in with interface information.
+ */
+	{
+	aDescriptorInfo.iNumInterfaces = 0;
+	aDescriptorInfo.iLength = 0;
+	}
+
+void CUsbDummyClassController::RunL()
+/**
+ * Standard active object RunL. 
+ */
+	{
+	LOGTEXT3(_L8(">>CUsbDummyClassController::RunL [iStatus=%d,iState=%d]"),
+			iStatus.Int(), iState);
+
+	if ( iStatus != KErrNone )
+		{
+		// Panic runtime errors from the timer. We can't ignore them, and 
+		// there's no point trying to code round them. This is part of the 
+		// test framework and if it's failing we want to alert the user 
+		// without faffing around. (It invalidates the test.)
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicUnhandledError);
+		}								  
+
+	__ASSERT_DEBUG(iReportStatus, 
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicBadState));
+
+	switch ( iState )
+		{
+	case EUsbServiceStarting:
+		// Completion of asynchronous startup...
+		__ASSERT_DEBUG(iStartupBehaviour.iSynchronicity == EAsynchronous, 
+			_USB_PANIC(KDummyControllerPanic, EDummyPanicBadSynchronicity));
+		iState = EUsbServiceStarted;
+		User::RequestComplete(iReportStatus, iStartupBehaviour.iErrorCode);
+		iReportStatus = NULL;
+		break;
+
+	case EUsbServiceStopping:
+		// Completion of asynchronous shutdown...
+		__ASSERT_DEBUG(iShutdownBehaviour.iSynchronicity == EAsynchronous, 
+			_USB_PANIC(KDummyControllerPanic, EDummyPanicBadSynchronicity));
+		iState = EUsbServiceIdle;
+		User::RequestComplete(iReportStatus, iShutdownBehaviour.iErrorCode);
+		iReportStatus = NULL;
+		break;
+
+	case EUsbServiceIdle:
+	case EUsbServiceStarted:
+	default:
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicBadState);
+		break;
+		}
+
+	LOGTEXT(_L8("<<CUsbDummyClassController::RunL"));
+	}
+
+void CUsbDummyClassController::DoCancel()
+/**
+ * Standard active object cancellation function. 
+ */
+	{
+	LOG_FUNC
+
+	// Note that CActive::Cancel does not call DoCancel unless we are active. 
+	// Therefore we are at this point active. Therefore, we should have 
+	// iReportStatus pointing to something. This is true whether we are in 
+	// our destructor or being cancelled by the device. It is also true that 
+	// (for us to be active at all) our synchronicity should be set to async 
+	// and the timer must have been CreateLocal'd successfully.
+
+	// Cancel may be called in one of the following situations: 
+	// 1/ In our destructor. 
+	// 2/ The device wants to cancel us in the middle of a Start before 
+	// issuing a Stop (or vice versa). Note that the device may cancel us in 
+	// the middle of a Start, then immediately issue another Start.
+	
+	// Cancel our own asynchronous operation.
+	__ASSERT_DEBUG(iTimer.Handle(), 
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicBadState));
+	iTimer.Cancel();
+
+	// Update our iState. If we're starting, then roll back to idle. If we're 
+	// stopping, role back to started. Nothing else is legal.
+	switch ( iState )
+		{
+	case EUsbServiceStarting:
+		__ASSERT_DEBUG(iStartupBehaviour.iSynchronicity == EAsynchronous, 
+			_USB_PANIC(KDummyControllerPanic, EDummyPanicBadSynchronicity));
+		iState = EUsbServiceIdle;
+		break;
+
+	case EUsbServiceStopping:
+		__ASSERT_DEBUG(iShutdownBehaviour.iSynchronicity == EAsynchronous, 
+			_USB_PANIC(KDummyControllerPanic, EDummyPanicBadSynchronicity));
+		iState = EUsbServiceStarted;
+		break;
+
+	case EUsbServiceIdle:
+	case EUsbServiceStarted:
+	default:
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicBadState);
+		break;
+		}
+
+	// Complete the client's request.	
+	__ASSERT_DEBUG(iReportStatus, 
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicBadState));
+	User::RequestComplete(iReportStatus, KErrCancel); 
+	iReportStatus = NULL;
+	}
+
+TInt CUsbDummyClassController::RunError(TInt /*aError*/)
+/**
+ * Standard active object error-handling function. 
+ *
+ * Should return KErrNone to avoid an active scheduler panic. This function
+ * should never be called as there is another mechanism for catching errors.
+ */
+	{
+	__ASSERT_DEBUG(EFalse, 
+		_USB_PANIC(KDummyControllerPanic, EDummyPanicBadState));
+	return KErrNone;
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/CUsbOtg.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,374 @@
+/*
+* 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 "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:
+* Implements the object of Usbman that manages all the USB OTG
+* activity (via CUsbOtgWatcher).
+*
+*/
+
+/**
+ @file
+*/
+
+#include "CUsbOtg.h"
+#include "cusbotgwatcher.h"
+#include "CUsbDevice.h"
+#include "musbotghostnotifyobserver.h"
+#include "CUsbServer.h"
+#include <e32property.h> //Publish & Subscribe header
+#include "usberrors.h"
+
+//Name used in call to User::LoadLogicalDevice/User::FreeLogicalDevice
+_LIT(KUsbOtgLDDName,"otgdi");
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBSVR-OTG");
+#endif
+
+
+CUsbOtg* CUsbOtg::NewL()
+/**
+ * Constructs a CUsbOtg object.
+ *
+ * @return	A new CUsbOtg object
+ */
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbOtg* self = new (ELeave) CUsbOtg();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+CUsbOtg::~CUsbOtg()
+/**
+ * Destructor.
+ */
+	{
+	LOG_FUNC
+
+	// Cancel any outstanding asynchronous operation.
+	Stop();
+	
+	// Free any memory allocated to the list of observers. Note that
+	// we don't want to call ResetAndDestroy, because we don't own
+	// the observers themselves.
+	iObservers.Reset();
+	
+	LOGTEXT2(_L8("about to stop Id-Pin watcher @ %08x"), (TUint32) iIdPinWatcher);
+	if (iIdPinWatcher)
+		{
+		iIdPinWatcher->Cancel();
+		delete iIdPinWatcher;
+		iIdPinWatcher = NULL;
+		LOGTEXT(_L8("deleted Id-Pin watcher"));
+		}
+	LOGTEXT2(_L8("about to stop Vbus watcher @ %08x"), (TUint32) iVbusWatcher);
+	if (iVbusWatcher)
+		{
+		iVbusWatcher->Cancel();
+		delete iVbusWatcher;
+		iVbusWatcher = NULL;
+		LOGTEXT(_L8("deleted Vbus watcher"));
+		}
+	LOGTEXT2(_L8("about to stop OTG State watcher @ %08x"), (TUint32) iVbusWatcher);
+	if (iOtgStateWatcher)
+		{
+		iOtgStateWatcher->Cancel();
+		delete iOtgStateWatcher;
+		iOtgStateWatcher = NULL;
+		LOGTEXT(_L8("deleted OTG State watcher"));
+		}
+	LOGTEXT2(_L8("about to stop OTG Event watcher @ %08x"), (TUint32) iVbusWatcher);
+	if (iOtgEventWatcher)
+		{
+		iOtgEventWatcher->Cancel();
+		delete iOtgEventWatcher;
+		iOtgEventWatcher = NULL;
+		LOGTEXT(_L8("deleted OTG Event watcher"));
+		}
+	
+	if (iRequestSessionWatcher)
+		{
+		delete iRequestSessionWatcher;
+		LOGTEXT(_L8("deleted Session Request watcher"));
+		}
+
+	LOGTEXT2(_L8("about to stop Connection Idle watcher @ %08x"), (TUint32)iOtgConnectionIdleWatcher);
+	if (iOtgConnectionIdleWatcher)
+		{
+		iOtgConnectionIdleWatcher->Cancel();
+		delete iOtgConnectionIdleWatcher;
+		iOtgConnectionIdleWatcher= NULL;
+		LOGTEXT(_L8("deleted Connection Idle watcher"));
+		}
+
+	// Unload OTGDI components if it was ever started
+	if ( iOtgDriver.Handle() )
+		{
+		LOGTEXT(_L8("Stopping stacks"));
+		iOtgDriver.StopStacks();
+		iOtgDriver.Close();
+		}
+	else
+		{
+		LOGTEXT(_L8("No OTG Driver session was opened, nothing to do"));
+		}
+
+	LOGTEXT(_L8("Freeing logical device"));
+	TInt err = User::FreeLogicalDevice(KUsbOtgLDDName);
+	//Putting the LOGTEXT2 inside the if statement prevents a compiler
+	//warning about err being unused in UREL builds.
+	if(err)
+		{
+		LOGTEXT2(_L8("     User::FreeLogicalDevice returned %d"),err);
+		}
+	
+	iCriticalSection.Close();
+	}
+
+
+CUsbOtg::CUsbOtg()
+/**
+ * Constructor.
+ */
+	{
+	LOG_FUNC
+	}
+
+
+void CUsbOtg::ConstructL()
+/**
+ * Performs 2nd phase construction of the OTG object.
+ */
+	{
+	LOG_FUNC
+	
+	LOGTEXT(_L8("About to open LDD"));
+	iLastError = User::LoadLogicalDevice(KUsbOtgLDDName);
+	if ( (iLastError != KErrNone) && (iLastError != KErrAlreadyExists) )
+		{
+		LOGTEXT3(_L8("Error %d: Unable to load driver: %S"), iLastError, &KUsbOtgLDDName);
+		LEAVEIFERRORL(iLastError);
+		}
+
+	LOGTEXT(_L8("About to open RUsbOtgDriver"));
+	iLastError = iOtgDriver.Open();
+	if ( (iLastError != KErrNone) && (iLastError != KErrAlreadyExists) )
+		{
+		LOGTEXT2(_L8("Error %d: Unable to open RUsbOtgDriver session"), iLastError);
+		LEAVEIFERRORL(iLastError);
+		}
+
+
+	LOGTEXT(_L8("About to start OTG stacks"));
+	iLastError = iOtgDriver.StartStacks();
+	if (iLastError != KErrNone)
+		{
+		LOGTEXT2(_L8("Error %d: Unable to open start OTG stacks"), iLastError);
+		LEAVEIFERRORL(iLastError);
+		}
+
+	// Request Otg notifications
+	iIdPinWatcher = CUsbOtgIdPinWatcher::NewL(iOtgDriver);
+	iIdPinWatcher->Start();
+
+	iVbusWatcher = CUsbOtgVbusWatcher::NewL(iOtgDriver);
+	iVbusWatcher->Start();
+
+	iOtgStateWatcher = CUsbOtgStateWatcher::NewL(iOtgDriver);
+	iOtgStateWatcher->Start();
+	
+	iOtgEventWatcher = CUsbOtgEventWatcher::NewL(*this, iOtgDriver, iOtgEvent);
+	iOtgEventWatcher->Start();
+	
+    iOtgConnectionIdleWatcher = CUsbOtgConnectionIdleWatcher::NewL(iOtgDriver);
+    iOtgConnectionIdleWatcher->Start();
+
+	iRequestSessionWatcher = CRequestSessionWatcher::NewL(*this);
+	
+	iCriticalSection.CreateLocal(EOwnerProcess);
+	
+	LOGTEXT(_L8("UsbOtg::ConstructL() finished"));
+	}
+	
+void CUsbOtg::NotifyMessage(TInt aMessage)
+/**
+ * The CUsbOtg::NotifyMessage method
+ *
+ * Reports the OTG message to the observers
+ *
+ * @internalComponent
+ */
+	{
+	iCriticalSection.Wait();
+
+	TInt msg = aMessage == 0 ? iOtgMessage : aMessage;
+	TUint length = iObservers.Count();
+	for (TUint i = 0; i < length; i++)
+		{
+		iObservers[i]->UsbOtgHostMessage(msg);
+		}
+
+	iCriticalSection.Signal();
+	}
+
+TInt CUsbOtg::TranslateOtgEvent()
+/**
+ * The CUsbOtg::TranslateOtgEvent method
+ *
+ * Attempts to translate the OTG event into OTG message
+ *
+ * @internalComponent
+ */
+	{
+	TInt otgEvent = KErrBadName;
+	switch (iOtgEvent)
+	{
+	case RUsbOtgDriver::EEventHnpDisabled:
+		otgEvent = KUsbMessageHnpDisabled;
+		break;
+	case RUsbOtgDriver::EEventHnpEnabled:
+		otgEvent = KUsbMessageHnpEnabled;
+		break;
+	case RUsbOtgDriver::EEventSrpReceived:
+		otgEvent = KUsbMessageSrpReceived;
+		break;
+	case RUsbOtgDriver::EEventSrpInitiated:
+		otgEvent = KUsbMessageSrpInitiated;
+		break;
+	case RUsbOtgDriver::EEventVbusRaised:
+		otgEvent = KUsbMessageVbusRaised;
+		break;
+	case RUsbOtgDriver::EEventVbusDropped:
+		otgEvent = KUsbMessageVbusDropped;
+		break;
+	}
+
+	return otgEvent;
+	}
+
+void CUsbOtg::NotifyOtgEvent()
+/**
+ * The CUsbOtg::NotifyOtgEvent method
+ *
+ * Reports the OTG message translated from OTG Event to the observers
+ *
+ * @internalComponent
+ */
+	{
+	TUint length = iObservers.Count();
+	TInt otgEvent = TranslateOtgEvent();
+	if ( otgEvent == KErrBadName )
+		{
+		LOGTEXT2(_L8("CUsbOtg::NotifyOtgEvent(): OTG event %d was reported, but not propagated"), (TInt) iOtgEvent);
+		return;
+		}
+
+	for (TUint i = 0; i < length; i++)
+		{
+		iObservers[i]->UsbOtgHostMessage(otgEvent);
+		}
+	}
+
+void CUsbOtg::RegisterObserverL(MUsbOtgHostNotifyObserver& aObserver)
+/**
+ * Register an observer of the OTG events.
+ * Presently, the device supports watching state.
+ *
+ * @param	aObserver	New Observer of the OTG events
+ */
+	{
+	LOG_FUNC
+
+	LEAVEIFERRORL(iObservers.Append(&aObserver));
+	}
+
+
+void CUsbOtg::DeRegisterObserver(MUsbOtgHostNotifyObserver& aObserver)
+/**
+ * De-registers an existing OTG events observer.
+ *
+ * @param	aObserver	The existing OTG events observer to be de-registered
+ */
+	{
+	LOG_FUNC
+
+	TInt index = iObservers.Find(&aObserver);
+
+	if (index >= 0 && index < iObservers.Count())
+		{
+		iObservers.Remove(index);
+		}
+	}
+
+
+void CUsbOtg::StartL()
+/**
+ * Start the USB OTG events watcher
+ * Reports errors and OTG events via observer interface.
+ */
+	{
+	LOG_FUNC
+
+	iOtgWatcher = CUsbOtgWatcher::NewL(*this, iOtgDriver, iOtgMessage);
+	iOtgWatcher->Start();
+	}
+
+void CUsbOtg::Stop()
+/**
+ * Stop the USB OTG events watcher
+ */
+	{
+	LOG_FUNC
+
+	LOGTEXT2(_L8("about to stop OTG watcher @ %08x"), (TUint32) iOtgWatcher);
+	
+	if (iOtgWatcher)
+		{
+		iOtgWatcher->Cancel();
+		delete iOtgWatcher;
+		iOtgWatcher = NULL;
+		LOGTEXT(_L8("deleted OTG watcher"));
+		}
+	
+	iLastError = KErrNone;
+	}
+
+TInt CUsbOtg::BusRequest()
+	{
+	LOG_FUNC
+	return iOtgDriver.BusRequest();
+	}
+	
+TInt CUsbOtg::BusRespondSrp()
+	{
+	LOG_FUNC
+	return iOtgDriver.BusRespondSrp();
+	}
+
+TInt CUsbOtg::BusClearError()
+	{
+	LOG_FUNC
+	return iOtgDriver.BusClearError();
+	}
+
+TInt CUsbOtg::BusDrop()
+	{
+	LOG_FUNC
+	return iOtgDriver.BusDrop();
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/CUsbScheduler.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,90 @@
+/*
+* Copyright (c) 1997-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
+*/
+
+#include <usb/usblogger.h>
+#include "CUsbScheduler.h"
+#include "CUsbServer.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBSVR");
+#endif
+
+/**
+ * The CUsbScheduler::NewL method
+ *
+ * Creates a new Active scheduler
+ *
+ * @internalComponent
+ */
+CUsbScheduler* CUsbScheduler::NewL()
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbScheduler* self = new(ELeave) CUsbScheduler;
+	return self;
+	}
+
+/**
+ * The CUsbScheduler::~CUsbScheduler method
+ *
+ * Destructor
+ *
+ * @internalComponent
+ */
+CUsbScheduler::~CUsbScheduler()
+	{
+	// Note that though we store a pointer to the server,
+	// we do not own it (it is owned by the cleanup stack)
+	// and our pointer is only used to error the server
+	// if we have been given a reference to it.
+	}
+
+/**
+ * The CUsbScheduler::SetServer method
+ *
+ * Give us a reference to the server
+ *
+ * @internalComponent
+ * @param	aServer	A reference to the server
+ */
+void CUsbScheduler::SetServer(CUsbServer& aServer)
+	{
+	iServer = &aServer;	
+	}
+
+/**
+ * The CUsbScheduler::Error method
+ *
+ * Inform the server that an error has occurred
+ *
+ * @internalComponent
+ * @param	aError	Error that has occurred
+ */
+void CUsbScheduler::Error(TInt aError) const
+	{
+	LOGTEXT2(_L8("CUsbScheduler::Error aError=%d"), aError);
+
+	if (iServer)
+		{
+		iServer->Error(aError);
+		}
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/CUsbServer.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,333 @@
+/*
+* Copyright (c) 1997-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:
+* Implements a Symbian OS server that exposes the RUsb API
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32svr.h>
+#include "UsbSettings.h"
+#include "CUsbServer.h"
+#include "CUsbSession.h"
+#include "CUsbDevice.h"
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+#include "CUsbOtg.h"
+#include "cusbhost.h"
+#include <e32property.h> //Publish & Subscribe header
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+#include <usb/usblogger.h>
+#include "UsbmanServerSecurityPolicy.h"
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBSVR");
+#endif
+
+/**
+ * The CUsbServer::NewL method
+ *
+ * Constructs a Usb Server
+ *
+ * @internalComponent
+ *
+ * @return	A new Usb Server object
+ */
+CUsbServer* CUsbServer::NewLC()
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbServer* self = new(ELeave) CUsbServer;
+	CleanupStack::PushL(self);
+	self->StartL(KUsbServerName);
+	self->ConstructL();
+	return self;
+	}
+
+
+/**
+ * The CUsbServer::~CUsbServer method
+ *
+ * Destructor
+ *
+ * @internalComponent
+ */
+CUsbServer::~CUsbServer()
+	{
+	LOG_FUNC
+
+	delete iShutdownTimer;
+	delete iUsbDevice;
+	
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	delete iUsbHost;
+	
+#ifndef __OVER_DUMMYUSBDI__
+	// Check that this is A-Device
+	LOGTEXT(_L8("Checking Id-Pin state..."));
+	TInt value = 0;
+	TInt err = RProperty::Get(KUidUsbManCategory, KUsbOtgIdPinPresentProperty,value);
+	if (err == 0 && value == 1)
+		{
+		// Ensure VBus is dropped when Usb server exits
+		LOGTEXT(_L8("Checking VBus state..."));
+		err = RProperty::Get(KUidUsbManCategory, KUsbOtgVBusPoweredProperty,value);
+		if ( err == KErrNone && value != 0 )
+			{
+			if ( iUsbOtg )
+				{
+				err = iUsbOtg->BusDrop();
+				LOGTEXT2(_L8("BusDrop() returned err = %d"),err);
+				LOGTEXT(_L8("USBMAN will wait until VBus is actually dropped"));
+				// Wait 1 second for Hub driver to perform VBus drop
+				RTimer timer;
+				err = timer.CreateLocal();
+				if ( err == KErrNone )
+					{
+					TRequestStatus tstatus;
+					timer.After(tstatus, 1000000);
+					User::WaitForRequest(tstatus);
+					timer.Close();
+					}
+				else
+					{
+					LOGTEXT2(_L8("Failed to create local timer: err = %d"),err);
+					}
+				}
+			else
+				{
+				LOGTEXT(_L8("Unexpected: OTG object is NULL"));
+				}
+			}
+		else
+			{
+			LOGTEXT3(_L8("VBus is already dropped or an error occured: err = %d, value =%d"),err,value);
+			}
+		}
+	else
+		{
+		LOGTEXT3(_L8("No Id-Pin is found or an error occured: err = %d, value = %d"), err, value);
+		}
+	
+	delete iUsbOtg;
+#endif
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+#ifdef __FLOG_ACTIVE
+	CUsbLog::Close();
+#endif
+	}
+
+
+/**
+ * The CUsbServer::CUsbServer method
+ *
+ * Constructor
+ *
+ * @internalComponent
+ */
+CUsbServer::CUsbServer()
+     : CPolicyServer(EPriorityHigh,KUsbmanServerPolicy)
+	{
+	}
+
+/**
+ * The CUsbServer::ConstructL method
+ *
+ * 2nd Phase Construction
+ *
+ * @internalComponent
+ */
+void CUsbServer::ConstructL()
+	{
+#ifdef __FLOG_ACTIVE
+	// Set the logger up so that everything in this thread that logs using it 
+	// will do so 'connectedly' (i.e. quickly). If this fails, we don't care- 
+	// logging will still work, just 'statically' (i.e. slowly).
+	static_cast<void>(CUsbLog::Connect());
+#endif
+
+	iShutdownTimer = new(ELeave) CShutdownTimer;
+	iShutdownTimer->ConstructL(); 
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+#ifndef __OVER_DUMMYUSBDI__
+	iUsbOtg = CUsbOtg::NewL();
+	iUsbOtg->StartL();
+#endif
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+	iUsbDevice = CUsbDevice::NewL(*this);
+	LOGTEXT(_L8("About to load USB classes"));
+	iUsbDevice->EnumerateClassControllersL();
+
+#ifndef USE_DUMMY_CLASS_CONTROLLER	
+	iUsbDevice->ReadPersonalitiesL();
+	if (iUsbDevice->isPersonalityCfged())
+		{
+#ifndef __OVER_DUMMYUSBDI__
+		iUsbDevice->ValidatePersonalitiesL();
+#endif
+		iUsbDevice->SetDefaultPersonalityL();		
+		}
+	else  
+		{
+		LOGTEXT(_L8("Personalities unconfigured, so using fallback CCs"));
+		iUsbDevice->LoadFallbackClassControllersL();
+		}
+#else // USE_DUMMY_CLASS_CONTROLLER
+	LOGTEXT(_L8("Using Dummy Class Controller, so using fallback CCs"));
+	iUsbDevice->LoadFallbackClassControllersL();
+#endif // USE_DUMMY_CLASS_CONTROLLER		
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	iUsbHost = CUsbHost::NewL();
+	//moved to CUsbSession:StartDeviceL() and similar: iUsbHost->StartL();
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+	LOGTEXT(_L8("CUsbServer constructed"));
+	}
+
+
+/**
+ * The CUsbServer::NewSessionL method
+ *
+ * Create a new client on this server
+ *
+ * @internalComponent
+ * @param	&aVersion	Vesion of client
+ * @param  	&aMessage 	Client's IPC message
+ *
+ * @return	A new USB session to be used for the client
+ */
+CSession2* CUsbServer::NewSessionL(const TVersion &aVersion, const RMessage2& aMessage) const
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	(void)aMessage;//Remove compiler warning
+	
+	TVersion v(KUsbSrvMajorVersionNumber,KUsbSrvMinorVersionNumber,KUsbSrvBuildVersionNumber);
+
+	LOGTEXT(_L8("CUsbServer::NewSessionL - creating new session..."));
+	if (!User::QueryVersionSupported(v, aVersion))
+		{
+		LEAVEL(KErrNotSupported);
+		}
+
+	CUsbServer* ncThis = const_cast<CUsbServer*>(this);
+	
+	CUsbSession* sess = CUsbSession::NewL(ncThis);
+		
+	return sess;
+	}
+
+
+/**
+ * Inform the client there has been an error.
+ *
+ * @param	aError	The error that has occurred
+ */
+void CUsbServer::Error(TInt aError)
+	{
+	LOGTEXT2(_L8("CUsbServer::Error [aError=%d]"), aError);
+
+	Message().Complete(aError);
+	ReStart();
+	}
+
+/**
+ * Increment the open session count (iSessionCount) by one.
+ * 
+ * @post	the number of open sessions is incremented by one
+ */
+void CUsbServer::IncrementSessionCount()
+	{
+	LOGTEXT2(_L8(">CUsbServer::IncrementSessionCount %d"), iSessionCount);
+	__ASSERT_DEBUG(iSessionCount >= 0, _USB_PANIC(KUsbSvrPncCat, EICSInvalidCount));
+	
+	++iSessionCount;
+	iShutdownTimer->Cancel();
+
+	LOGTEXT(_L8("<CUsbServer::IncrementSessionCount"));
+	}
+
+/**
+ * Decrement the open session count (iSessionCount) by one.
+ * 
+ * @post		the number of open sessions is decremented by one
+ */
+void CUsbServer::DecrementSessionCount()
+	{
+	LOGTEXT3(_L8("CUsbServer::DecrementSessionCount %d, %d"), iSessionCount, Device().ServiceState());
+	__ASSERT_DEBUG(iSessionCount > 0, _USB_PANIC(KUsbSvrPncCat, EDCSInvalidCount));
+	
+	--iSessionCount;
+	
+	if (iSessionCount == 0 && Device().ServiceState() == EUsbServiceIdle)
+		{
+		iShutdownTimer->After(KShutdownDelay);
+		}
+	}
+
+/**
+ * If there are no sessions then launch the shutdown timer.  This function
+ * is provided for the case where the sole session stops the classes but dies
+ * before they are completely stopped.  The server must then be shut down
+ * from CUsbDevice::SetServiceState().
+ *
+ * @pre		the services have been stopped.
+ * @see		CUsbDevice::SetServiceStateIdle
+ */
+void CUsbServer::LaunchShutdownTimerIfNoSessions()
+	{
+	LOGTEXT(_L8("CUsbServer::LaunchShutdownTimerIfNoSessions"));
+	__ASSERT_DEBUG(Device().ServiceState() == EUsbServiceIdle, _USB_PANIC(KUsbSvrPncCat, ELSTNSNotIdle));
+
+	if (iSessionCount == 0)
+		iShutdownTimer->After(KShutdownDelay);
+	}
+
+/**
+ * Initialize this shutdown timer as a normal-priority
+ * (EPriorityStandard) active object.
+ */
+CUsbServer::CShutdownTimer::CShutdownTimer()
+:	CTimer(EPriorityStandard)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+/**
+ * Forwarding function call's CTimer's ConstructL() to initialize the RTimer.
+ */
+void CUsbServer::CShutdownTimer::ConstructL()
+	{
+	CTimer::ConstructL();
+	}
+
+/**
+ * Server shutdown callback.  This stops the active scheduler,
+ * and so closes down the server.
+ */
+void CUsbServer::CShutdownTimer::RunL()
+	{
+	CActiveScheduler::Stop();
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/CUsbSession.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,2108 @@
+/*
+* Copyright (c) 1997-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:
+* Implements a Session of a Symbian OS server for the RUsb API
+*
+*/
+
+/**
+ @file
+*/
+
+#include <usb/usblogger.h>
+#include "CUsbSession.h"
+#include "CUsbDevice.h"
+#include "CUsbServer.h"
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+#include "CUsbOtg.h"
+#include "cusbhost.h"
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+#include <usbstates.h>
+#include <usberrors.h>
+
+#include <usb/usbshared.h>
+#include "CPersonality.h"
+#include "rusb.h"
+#include "UsbSettings.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBSVR");
+#endif
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+CUsbSession* CUsbSession::iCtlSession = NULL;
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+/**
+ * Construct a Symbian OS session object.
+ *
+ * @internalComponent
+ * @param	aServer		Service the session will be a member of
+ *
+ * @return	A new CUsbSession object
+ */
+CUsbSession* CUsbSession::NewL(CUsbServer* aServer)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	//this class has moved away from standard NewL() semantics
+	//and now uses the virtual CSession2::CreateL() function
+	//[instead of ConstructL()] which is called by CServer2
+	//and finalises the construction of the session
+	return (new (ELeave) CUsbSession(aServer));
+	}
+
+
+/**
+ * Constructor.
+ *
+ * @internalComponent
+ * @param	aServer	Service the session will be a member of
+ */
+CUsbSession::CUsbSession(CUsbServer* aServer)
+	: iUsbServer(aServer)
+	{
+	LOG_FUNC
+
+	iUsbServer->IncrementSessionCount();
+	}
+
+
+/**
+ * Destructor.
+ */
+CUsbSession::~CUsbSession()
+	{
+	LOG_FUNC
+
+	LOGTEXT2(_L8("About to Device().DeRegisterObserver(%08x"),this);
+	iUsbServer->Device().DeRegisterObserver(*this);
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+#ifndef __OVER_DUMMYUSBDI__
+	LOGTEXT2(_L8("About to Otg().DeRegisterObserver(%08x"),this);
+	iUsbServer->Otg().DeRegisterObserver(*this);
+#endif
+
+	LOGTEXT2(_L8("About to Host().DeRegisterObserver(%08x"),this);
+	iUsbServer->Host().DeregisterObserver(*this);
+
+	if ( iCtlSession && (iCtlSession == this) )
+		{
+		iCtlSession = NULL;
+		}
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+	LOGTEXT(_L8("About to iUsbServer->DecrementSessionCount()"));
+	iUsbServer->DecrementSessionCount();
+	}
+
+
+/**
+ * Called when a message is received from the client.
+ *
+ * @param	aMessage	Message received from the client
+ */
+void CUsbSession::ServiceL(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	DispatchMessageL(aMessage);
+	}
+
+/**
+ * Handles 2nd Phase Construction.  Implementation of the virtual method defined in CSession2 and called from
+ * CServer2::DoConnectL() which executes when the client makes a connection request through CServer2::Connect().  If
+ * a Leave occurs at any point the CUsbSession object is cleaned up in CServer2::DoConnect().
+ */
+void CUsbSession::CreateL()
+	{
+	LOG_FUNC
+
+	// This code originally existed in the typical non-virtual ConstructL() method.
+	// However it was moved to this method for minor optimisation reasons [three less
+	// function calls and several lines less code in the NewL() method].
+
+	iPersonalityCfged = iUsbServer->Device().isPersonalityCfged();
+
+    LOGTEXT(_L8("Registering Device Observer\n"));
+	iUsbServer->Device().RegisterObserverL(*this);
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+#ifndef __OVER_DUMMYUSBDI__
+	LOGTEXT(_L8("Registering OTG Observer\n"));
+	iUsbServer->Otg().RegisterObserverL(*this);
+#endif
+
+	LOGTEXT(_L8("Registering HOST Observer\n"));
+	iUsbServer->Host().RegisterObserverL(*this);
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	}
+
+/**
+ * Called by CUsbDevice when the service state changes.
+ * CUsbSession is an observer of the device.
+ *
+ * @param	aLastError	The last error happened
+ * @param	aOldState	The device's service state just before it changed
+ * @param	aNewState	The device's new and current service state
+ */
+void CUsbSession::UsbServiceStateChange(TInt aLastError, TUsbServiceState aOldState,
+										TUsbServiceState aNewState)
+	{
+	LOG_FUNC
+	LOGTEXT3(_L8("    aOldState=0x%X, aNewState=0x%X"), aOldState, aNewState);
+	(void) aOldState; // a-void build warning in UREL
+
+	// Note that it's possible to have both a start and a stop outstanding!
+
+	if (iStartOutstanding)
+		{
+		HandleServiceStateChangeWhileStarting(aLastError, aNewState);
+		}
+
+	if (iStopOutstanding)
+		{
+		HandleServiceStateChangeWhileStopping(aLastError, aNewState);
+		}
+
+	// Check whether we have an observer of the service state.
+
+	if (iServiceObserverOutstanding)
+		{
+		TPckg<TUint32> pckg(aNewState);
+		iServiceObserverOutstanding = EFalse;
+		const TInt err = iServiceObserverMessage.Write(0, pckg);
+		iServiceObserverMessage.Complete(err);
+		}
+	}
+
+/**
+ * Handles a state change while a start request is currently outstanding.
+ *
+ * @param aLastError The last error happened
+ * @param aNewState The state we've moved to
+ */
+void CUsbSession::HandleServiceStateChangeWhileStarting(TInt aLastError,
+												 TUsbServiceState aNewState)
+	{
+	LOG_FUNC
+
+	switch (aNewState)
+		{
+	case EUsbServiceStarted:
+		LOGTEXT(_L8("    Completing Start successfully"));
+
+		// If the user has tried to cancel the start, they're too late!
+		if (iCancelOutstanding)
+			{
+			LOGTEXT(_L8("    Completing cancel request with KErrNone"));
+			iCancelOutstanding = EFalse;
+			iCancelMessage.Complete(KErrNone);
+			}
+
+		iStartMessage.Complete(KErrNone);
+		iStartOutstanding = EFalse;
+		break;
+
+	case EUsbServiceIdle:
+		LOGTEXT2(_L8("    Completing Start with error=%d"), aLastError);
+
+		// If there hasn't actually been an error, but we're in an unexpected
+		// state now, that means that this client cancelled the request, or
+		// another client stopped the service.
+		if (aLastError == KErrNone)
+			{
+			// If there's a cancel outstanding, then that message succeeded, but
+			// the start message should be completed with KErrCancel.
+			if (iCancelOutstanding)
+				{
+				LOGTEXT(_L8("    Completing original message with KErrCancel"));
+				iCancelOutstanding = EFalse;
+				iCancelMessage.Complete(KErrNone);
+				iStartMessage.Complete(KErrCancel);
+				}
+			else
+				{
+				iStartMessage.Complete(KErrUsbServiceStopped);
+				}
+			}
+		else
+			{
+			// There's been some kind of error, so complete the original message
+			// with the right error code.
+			if (iCancelOutstanding)
+				{
+				iCancelOutstanding = EFalse;
+				iCancelMessage.Complete(KErrNone);
+				}
+			iStartMessage.Complete(aLastError);
+			}
+
+		iStartOutstanding = EFalse;
+		break;
+
+	default:
+		break;
+		}
+	}
+
+/**
+ * Handles a state change while a stop request is currently outstanding.
+ *
+ * @param aLastError The last error happened
+ * @param aNewState The state we've moved to
+ */
+void CUsbSession::HandleServiceStateChangeWhileStopping(TInt aLastError,
+												 TUsbServiceState aNewState)
+	{
+	LOG_FUNC
+
+	switch (aNewState)
+		{
+	case EUsbServiceStarted:
+		LOGTEXT2(_L8("    Completing Stop with error=%d"), aLastError);
+
+		// If there hasn't actually been an error, but we're in an unexpected
+		// state now, that means that this client cancelled the request, or
+		// another client has started the service.
+		if (aLastError == KErrNone)
+			{
+			// If there's a cancel outstanding, then that message succeeded, but
+			// the stop message should be completed with KErrCancel.
+			if (iCancelOutstanding)
+				{
+				LOGTEXT(_L8("    Completing original message with KErrCancel"));
+				iCancelOutstanding = EFalse;
+				iCancelMessage.Complete(KErrNone);
+				iStopMessage.Complete(KErrCancel);
+				}
+			else
+				{
+				iStopMessage.Complete(KErrUsbServiceStarted);
+				}
+			}
+		else
+			{
+			// There's been some kind of error, so complete the original message
+			// with the right error code.
+			if (iCancelOutstanding)
+				{
+				iCancelOutstanding = EFalse;
+				iCancelMessage.Complete(KErrNone);
+				}
+			iStopMessage.Complete(aLastError);
+			}
+
+		iStopOutstanding = EFalse;
+		break;
+
+	case EUsbServiceIdle:
+		LOGTEXT(_L8("    Completing Stop with KErrNone"));
+
+		// If the user has tried to cancel the stop, they're too late!
+		if (iCancelOutstanding)
+			{
+			LOGTEXT(_L8("    Completing cancel request with KErrNone"));
+			iCancelOutstanding = EFalse;
+			iCancelMessage.Complete(KErrNone);
+			}
+
+		iStopMessage.Complete(KErrNone);
+		iStopOutstanding = EFalse;
+		break;
+
+	default:
+		break;
+		}
+	}
+
+/**
+ * Called by CUsbDevice when it state change. CUsbSession is an observer of
+ * the device. If the client has an Observer outstanding then complete it,
+ * otherwise put it in a circular queue.
+ *
+ * @internalComponent
+ * @param	aLastError	The last error happened
+ * @param	aOldState	The device's state just before it changed
+ * @param	aNewState	The device's new and current state
+ */
+void CUsbSession::UsbDeviceStateChange(TInt /*aLastError*/, TUsbDeviceState /*aOldState*/,
+									   TUsbDeviceState aNewState)
+	{
+	LOG_FUNC
+
+	// can we bypass the queue?
+ 	if ((iDeviceObserverOutstanding) && (iDevStateQueueHead == iDevStateQueueTail))
+		{
+		if ((iDeviceObserverMessage.Int0() & aNewState) ||
+			(aNewState == EUsbDeviceStateUndefined))
+			{
+			TPckg<TUint32> pckg(aNewState);
+
+			iNotifiedDevState = aNewState;
+
+			iDeviceObserverOutstanding = EFalse;
+			const TInt err = iDeviceObserverMessage.Write(1, pckg);
+			iDeviceObserverMessage.Complete(err);
+			}
+		}
+	else if (iObserverQueueEvents)
+		{
+		TBool addToQueue = ETrue;
+
+ 		// Search queue for similar event, truncate event queue if found
+ 		if (aNewState == EUsbDeviceStateUndefined)
+ 			{
+ 			// erase Event queue, just want this event - not interested in how we got here
+ 			iDevStateQueueTail = iDevStateQueueHead;
+
+ 			// if this is also the event mostly recently notified then don't bother to queue it
+ 			if(aNewState == iNotifiedDevState)
+ 				addToQueue = EFalse;
+ 			}
+ 		else
+ 			{
+ 			TInt queuePtr = iDevStateQueueTail;
+
+ 			// search forward from tail to head
+ 			while (queuePtr != iDevStateQueueHead)
+ 				{
+ 				if (aNewState == iDeviceStateQueue[queuePtr])
+ 					{
+ 					// Event is already queued; discard the duplicate and in-between events
+ 					LOGTEXT3(_L8("--- collapsing queue head (%d, %d)"),
+						iDevStateQueueHead,
+						(queuePtr + 1) % KDeviceStatesQueueSize);
+
+ 					// queue head moved to position following the match
+ 					iDevStateQueueHead = (queuePtr + 1) % KDeviceStatesQueueSize;
+ 					addToQueue = EFalse;
+ 					break;
+ 					}
+
+ 				// work our way through queue
+ 				queuePtr = (queuePtr + 1) % KDeviceStatesQueueSize;
+ 				}
+ 			}
+
+ 		// still want to add to queue?
+ 		if (addToQueue)
+ 			{
+ 			// add event to head of queue
+ 			iDeviceStateQueue[iDevStateQueueHead] = aNewState;
+ 			iDevStateQueueHead = (iDevStateQueueHead + 1) % KDeviceStatesQueueSize;
+ 			LOGTEXT3(_L8("+++ addqueue (%d, %d)"), iDevStateQueueHead,
+				iDevStateQueueTail);
+ 			}
+
+ 		// UsbDeviceDequeueEvent() will read from queue when RegisterObserver()
+		// is next called.
+		}
+	}
+
+/**
+ * Dequeues an event and completes the observer's request with it.
+ */
+void CUsbSession::UsbDeviceDequeueEvent()
+ 	{
+	LOG_FUNC
+
+ 	// Work our way through the queue, until we reach the end
+ 	// OR we find an event the current observer wants.
+ 	while ((iDeviceObserverOutstanding) && (iDevStateQueueHead != iDevStateQueueTail))
+ 		{
+ 		// inform the observer of state changes they are interested in AND
+ 		// if the cable is pulled out (EUsbDeviceStateUndefined)
+ 		TUsbDeviceState newState = iDeviceStateQueue[iDevStateQueueTail];
+
+ 		// advance tail towards the head
+ 		iDevStateQueueTail = (iDevStateQueueTail + 1) % KDeviceStatesQueueSize;
+
+ 		// is this state one the Observer wants?
+ 		if ((iDeviceObserverMessage.Int0() & newState) ||
+			(newState == EUsbDeviceStateUndefined))
+ 			{
+ 			TPckg<TUint32> pckg(newState);
+
+ 			iNotifiedDevState = newState;
+
+ 			LOGTEXT3(_L8(">>> dequeued event #%d (0x%x)"), iDevStateQueueTail, newState);
+
+  			iDeviceObserverOutstanding = EFalse;
+			const TInt err = iDeviceObserverMessage.Write(1, pckg);
+ 			iDeviceObserverMessage.Complete(err);
+ 			break;
+   			}
+   		}
+   	}
+
+/**
+ * Handles the request (in the form of a the message) received from the client
+ *
+ * @internalComponent
+ * @param	aMessage	The received message
+ */
+void CUsbSession::DispatchMessageL(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	TBool complete = ETrue;
+	TInt ret = KErrNone;
+
+	LOGTEXT2(_L8("CUsbSession::DispatchMessageL(): func# %d"), aMessage.Function());
+
+	switch (aMessage.Function())
+		{
+	case EUsbStart:
+		ret = StartDeviceL(aMessage, complete);
+		break;
+	case EUsbStop:
+		ret = StopDeviceL(aMessage, complete);
+		break;
+	case EUsbGetCurrentState:
+		ret = GetCurrentServiceState(aMessage);
+		break;
+	case EUsbGetCurrentDeviceState:
+		ret = GetCurrentDeviceState(aMessage);
+		break;
+	case EUsbRegisterServiceObserver:
+		ret = RegisterServiceObserver(aMessage, complete);
+		break;
+	case EUsbRegisterObserver:
+		ret = RegisterDeviceObserver(aMessage, complete);
+		break;
+	case EUsbStartCancel:
+		ret = StartCancel(aMessage, complete);
+		break;
+	case EUsbStopCancel:
+		ret = StopCancel(aMessage, complete);
+		break;
+	case EUsbCancelServiceObserver:
+		ret = DeRegisterServiceObserver();
+		break;
+	case EUsbCancelObserver:
+		ret = DeRegisterDeviceObserver();
+		break;
+	case EUsbTryStart:
+		ret = TryStartDeviceL(aMessage, complete);
+		break;
+	case EUsbTryStop:
+		ret = TryStopDeviceL(aMessage, complete);
+		break;
+	case EUsbCancelInterest:
+		ret = CancelInterest(aMessage);
+		break;
+	case EUsbGetCurrentPersonalityId:
+		ret = GetCurrentPersonalityId(aMessage);
+		break;
+	case EUsbGetSupportedClasses:
+		ret = GetSupportedClasses(aMessage);
+		break;
+	case EUsbGetPersonalityIds:
+		ret = GetPersonalityIds(aMessage);
+		break;
+	case EUsbGetDescription:
+		ret = GetDescription(aMessage);
+		break;
+	case EUsbGetDetailedDescription:
+		ret = GetDetailedDescription(aMessage);
+		break;
+	case EUsbGetPersonalityProperty:
+		ret = GetPersonalityProperty(aMessage);
+		break;
+	case EUsbClassSupported:
+		ret = ClassSupported(aMessage);
+		break;
+
+#ifdef _DEBUG
+	// Heap failure debug APIs.
+
+	case EUsbDbgMarkHeap:
+		LOGTEXT(_L8("Marking heap"));
+		__UHEAP_MARK;
+		break;
+	case EUsbDbgCheckHeap:
+		LOGTEXT2(_L8("Checking heap (expecting %d cells)"), aMessage.Int0());
+		__UHEAP_CHECK(aMessage.Int0());
+		break;
+	case EUsbDbgMarkEnd:
+		LOGTEXT2(_L8("End of marking heap (expecting %d cells)"), aMessage.Int0());
+		__UHEAP_MARKENDC(aMessage.Int0());
+		break;
+	case EUsbDbgFailNext:
+		{
+		LOGTEXT2(_L8("Simulating failure after %d allocation(s)"), aMessage.Int0());
+		if (aMessage.Int0() == 0)
+			__UHEAP_RESET;
+		else
+			__UHEAP_FAILNEXT(aMessage.Int0());
+		}
+		break;
+	case EUsbDbgAlloc:
+		{
+		ret = KErrNone;
+#ifdef _DEBUG
+		LOGTEXT(_L8("\tallocate on the heap"));
+		TInt* x = NULL;
+		TRAP(ret, x = new(ELeave) TInt);
+		delete x;
+#endif // _DEBUG
+		}
+		break;
+
+#endif
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	case EUsbSetCtlSessionMode:
+		ret = SetCtlSessionMode(aMessage);
+		break;
+	case EUsbRegisterMessageObserver:
+		ret = RegisterMsgObserver(aMessage, complete);
+		break;
+	case EUsbCancelMessageObserver:
+		ret = DeRegisterMsgObserver();
+		break;
+#ifndef __OVER_DUMMYUSBDI__
+	case EUsbBusRequest:
+		ret = BusRequest();
+		break;
+	case EUsbBusRespondSrp:
+		ret = BusRespondSrp();
+		break;
+	case EUsbBusClearError:
+		ret = BusClearError();
+		break;
+	case EUsbBusDrop:
+		ret = BusDrop();
+		break;
+#else
+	case EUsbBusRequest:
+	case EUsbBusRespondSrp:
+	case EUsbBusClearError:
+	case EUsbBusDrop:
+		ret = KErrNone;
+		break;
+#endif
+	case EUsbRegisterHostObserver:
+		ret = RegisterHostObserver(aMessage, complete);
+		break;
+	case EUsbCancelHostObserver:
+		ret = DeRegisterHostObserver();
+		break;
+	case EUsbEnableFunctionDriverLoading:
+		ret = EnableFunctionDriverLoading();
+		break;
+	case EUsbDisableFunctionDriverLoading:
+		ret = DisableFunctionDriverLoading();
+		break;
+	case EUsbGetSupportedLanguages:
+		ret = GetSupportedLanguages(aMessage);
+		break;
+	case EUsbGetManufacturerStringDescriptor:
+		ret = GetManufacturerStringDescriptor(aMessage);
+		break;
+	case EUsbGetProductStringDescriptor:
+		ret = GetProductStringDescriptor(aMessage);
+		break;
+	case EUsbGetOtgDescriptor:
+		ret = GetOtgDescriptor(aMessage);
+		break;
+	case EUsbRequestSession:
+		ret = RequestSession();
+		break;
+#else // !SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	case EUsbSetCtlSessionMode:
+	case EUsbRegisterMessageObserver:
+	case EUsbCancelMessageObserver:
+	case EUsbBusRequest:
+	case EUsbBusRespondSrp:
+	case EUsbBusClearError:
+	case EUsbBusDrop:
+	case EUsbRegisterHostObserver:
+	case EUsbCancelHostObserver:
+	case EUsbEnableFunctionDriverLoading:
+	case EUsbDisableFunctionDriverLoading:
+	case EUsbGetSupportedLanguages:
+	case EUsbGetManufacturerStringDescriptor:
+	case EUsbGetProductStringDescriptor:
+	case EUsbGetOtgDescriptor:
+	case EUsbRequestSession:
+		ret = KErrNotSupported;
+		break;
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+	default:
+		LOGTEXT2(_L8("Illegal IPC argument(%d) - Panicking Client..."), aMessage.Function());
+		aMessage.Panic(KUsbCliPncCat, EUsbPanicIllegalIPC);
+		complete = EFalse;
+		break;
+		}
+
+	if (complete)
+		aMessage.Complete(ret);
+	}
+
+
+/**
+ * Client request to start the device.
+ *
+ * @param	aMessage	Message received from the client
+ * @param	aComplete	Whether the request is complete or not
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::StartDeviceL(const RMessage2& aMessage, TBool& aComplete)
+	{
+	LOG_FUNC
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	// Only 'control' session is allowed to start USB support
+	if ( !iSessionCtlMode )
+		{
+		return KErrAccessDenied;
+		}
+#endif
+
+	if (iStartOutstanding)
+		return KErrInUse;
+
+#ifndef __OVER_DUMMYUSBDI__
+
+	// If the service is idle or stopping, then we just need to start it.
+	// If it's starting (ie. by another client), then we need to perform nothing
+	// but wait for the start to complete.
+	// If it's already started, we just return immediately.
+	TUsbServiceState state = iUsbServer->Device().ServiceState();
+
+	if ((state == EUsbServiceIdle) || (state == EUsbServiceStopping))
+		{
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+		iUsbServer->Host().StartL();
+#endif
+		iUsbServer->Device().StartL();
+
+		aComplete = EFalse;
+		iStartMessage = aMessage;
+		iStartOutstanding = ETrue;
+		}
+	else if (state == EUsbServiceStarting)
+		{
+		aComplete = EFalse;
+		iStartMessage = aMessage;
+		iStartOutstanding = ETrue;
+		}
+
+	return KErrNone;
+
+#else
+	// pretend that the server is in Started state
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	iUsbServer->Host().StartL();
+#endif
+	iStartOutstanding = EFalse;
+	aMessage.IsNull();
+	aComplete = ETrue;
+	return KErrNone;
+
+#endif
+	}
+
+/**
+ * Client request to stop the device.
+ *
+ * @param	aMessage	Message received from the client
+ * @param	aComplete	Whether the request is complete or not
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::StopDeviceL(const RMessage2& aMessage, TBool& aComplete)
+    {
+	LOG_FUNC
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	// Only 'control' session is allowed to stop USB support
+	if ( !iSessionCtlMode )
+		{
+		return KErrAccessDenied;
+		}
+#endif
+
+	if (iStopOutstanding)
+		{
+		return KErrInUse;
+		}
+
+#ifndef __OVER_DUMMYUSBDI__
+
+	// Only do anything if the service isn't currently idle. If it is, we just
+	// need to complete the user's request immediately.
+	if (iUsbServer->Device().ServiceState() != EUsbServiceIdle)
+		{
+		iUsbServer->Device().Stop();
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+		iUsbServer->Host().Stop();
+#endif
+
+		aComplete = EFalse;
+		iStopMessage = aMessage;
+		iStopOutstanding = ETrue;
+		}
+
+	return KErrNone;
+
+#else
+	// pretend that the server is in Started state
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	iUsbServer->Host().Stop();
+#endif
+	aComplete = ETrue;
+	aMessage.IsNull();
+	iStopOutstanding = EFalse;
+	return KErrNone;
+
+#endif
+    }
+
+/**
+ * Cancel the pending start operation. Note that this can just be implemented
+ * as a synchronous stop, if the start operation is pending. However, we have to
+ * retain the cancel message, so we can complete it when the stop completes.
+ *
+ * @param aMessage The message from the client
+ * @param aComplete Whether the message is complete or not
+ * @return Always KErrNone
+ */
+TInt CUsbSession::StartCancel(const RMessage2& aMessage, TBool& aComplete)
+	{
+	LOG_FUNC
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	// Only 'control' session is allowed to cancel outstaning start request
+	if ( !iSessionCtlMode )
+		{
+		return KErrAccessDenied;
+		}
+#endif
+
+	if (!iStartOutstanding)
+		return KErrNone;
+
+	aComplete = EFalse;
+	iCancelMessage = aMessage;
+	iCancelOutstanding = ETrue;
+
+	if (iUsbServer->Device().ServiceState() != EUsbServiceIdle)
+		{
+		iUsbServer->Device().Stop();
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+		iUsbServer->Host().Stop();
+#endif
+		}
+
+	return KErrNone;
+	}
+
+/**
+ * Cancel the pending stop operation. Note that this can just be implemented as
+ * a synchronous start, if the stop operation is pending. However, we have to
+ * retain the cancel message, so we can complete it when the start completes.
+ *
+ * @param aMessage The message from the client
+ * @param aComplete Whether the message is complete or not
+ * @return KErrNone on success, otherwise standard error codes
+ */
+TInt CUsbSession::StopCancel(const RMessage2& aMessage, TBool& aComplete)
+	{
+	LOG_FUNC
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	// Only 'control' session is allowed to cancel outstaning stop request
+	if ( !iSessionCtlMode )
+		{
+		return KErrAccessDenied;
+		}
+#endif
+
+	if (!iStopOutstanding)
+		{
+		return KErrNone;
+		}
+
+	aComplete = EFalse;
+	iCancelMessage = aMessage;
+	iCancelOutstanding = ETrue;
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	TRAPD(errHost,iUsbServer->Host().StartL());
+	if (errHost != KErrNone)
+		return errHost;
+#endif
+	TRAPD(err, iUsbServer->Device().StartL());
+	return err;
+	}
+
+/**
+ * Client request to observe the device (for state changes).
+ * Asks the device to register the session as an observer.
+ * Assures initialisation/dequeueing of Event queue.
+ *
+ * @param	aMessage	Message received from the client
+ * @param	aComplete	set to true to complete the request
+ *
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::RegisterDeviceObserver(const RMessage2& aMessage, TBool& aComplete)
+	{
+	LOG_FUNC
+
+	if (iDeviceObserverOutstanding)
+		{
+		return KErrInUse;
+		}
+
+	iDeviceObserverMessage = aMessage;
+	iDeviceObserverOutstanding = ETrue;
+	aComplete = EFalse;
+
+ 	if (iObserverQueueEvents == EFalse)
+	 	{
+ 		// This is the first observer after c'tor or DeregisterObserver(),
+ 		// so zap the device event queue.
+ 		LOGTEXT(_L8("    Reset Device Event Queue"));
+ 		iDevStateQueueHead = 0;
+ 		iDevStateQueueTail = 0;
+ 		iObserverQueueEvents = ETrue;
+	 	}
+ 	else if (iDevStateQueueHead != iDevStateQueueTail)
+	 	{
+ 		// event(s) queued, we can de-queue one now
+ 		UsbDeviceDequeueEvent();
+	 	}
+
+	return KErrNone;
+	}
+
+/**
+ * Client request to observe the service (for state changes)
+ * Asks the device to register the session as an observer
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @param	aComplete	set to true to complete the request
+ *
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::RegisterServiceObserver(const RMessage2& aMessage, TBool& aComplete)
+	{
+	LOG_FUNC
+
+	if (iServiceObserverOutstanding)
+		{
+		return KErrInUse;
+		}
+
+	iServiceObserverMessage = aMessage;
+	iServiceObserverOutstanding = ETrue;
+	aComplete = EFalse;
+	return KErrNone;
+	}
+
+
+/**
+ * Client request to fetch the current service state of the device
+ * Asks the device for its current service state
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ *
+ * @return	Any errors that occurred or KErrNone
+ */
+TInt CUsbSession::GetCurrentServiceState(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	TUsbServiceState state = iUsbServer->Device().ServiceState();
+	LOGTEXT2(_L8("\tstate = %d"), state);
+	TPckg<TUint32> pckg(state);
+	return aMessage.Write(0, pckg);
+	}
+
+/**
+ * Client request to fetch the current device state of the device
+ * Asks the device for its current device state
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ *
+ * @return	Any errors that occurred or KErrNone
+ */
+TInt CUsbSession::GetCurrentDeviceState(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	TUsbDeviceState state = iUsbServer->Device().DeviceState();
+	LOGTEXT2(_L8("\tstate = %d"), state);
+	TPckg<TUint32> pckg(state);
+	return aMessage.Write(0, pckg);
+	}
+
+
+/**
+ * Deregister the client as an observer of device state changes. Note that we don't
+ * deregister ourselves as an observer, because we need to be notified when the
+ * device state changes, so we can complete Start and Stop requests.
+ *
+ * @return Always KErrNone
+ */
+TInt CUsbSession::DeRegisterDeviceObserver()
+	{
+	LOG_FUNC
+
+	if (!iDeviceObserverOutstanding)
+		{
+		return KErrNone;
+		}
+
+	iDeviceObserverOutstanding = EFalse;
+	iDeviceObserverMessage.Complete(KErrCancel);
+
+	// client doesn't need events queuing any more
+ 	iObserverQueueEvents = EFalse;
+
+	return KErrNone;
+	}
+
+/**
+ * Deregister the client as an observer of service state changes. Note that we don't
+ * deregister ourselves as an observer, because we need to be notified when the
+ * service state changes, so we can complete Start and Stop requests.
+ *
+ * @return Always KErrNone
+ */
+TInt CUsbSession::DeRegisterServiceObserver()
+	{
+	LOG_FUNC
+
+	if (!iServiceObserverOutstanding)
+		{
+		return KErrNone;
+		}
+
+	iServiceObserverOutstanding = EFalse;
+	iServiceObserverMessage.Complete(KErrCancel);
+	return KErrNone;
+	}
+
+/**
+ * Try starting the USB device.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @param	aComplete	set to true to complete the request
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::TryStartDeviceL(const RMessage2& aMessage, TBool& aComplete)
+	{
+	LOG_FUNC
+
+#ifndef __OVER_DUMMYUSBDI__
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	// Only 'control' session is allowed to start USB support
+	if ( !iSessionCtlMode )
+		{
+		return KErrAccessDenied;
+		}
+#endif
+
+	if (!iPersonalityCfged)
+	{
+	return KErrNotSupported;
+	}
+
+	if (iStartOutstanding || iStopOutstanding)
+		{
+		return KErrServerBusy;
+		}
+
+	// Obtains the curent service state
+	TUsbServiceState state = iUsbServer->Device().ServiceState();
+
+
+	// USB Peripheral Stack Starting sequence:
+	// if the server is in the idle state
+	//		start it;
+	// if the server is in the started state
+	//		return KErrNone immediately;
+	// if the server is in the stopping state
+	//		return KErrServerBusy immediately;
+ 	// if the server is in the starting state
+	// (was already called by this very session in OTG/Host configuration and/or
+	//  by another session for Client Only configuration)
+	// 		if requested personality is not equal to the current one
+	//			return KErrAbort;
+	//		else
+ 	//			mark this request as outstanding and let the caller to wait
+	//			for start operation to complete;
+	if (state == EUsbServiceIdle)
+		{
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+		iUsbServer->Host().StartL();
+#endif
+		iUsbServer->Device().TryStartL(aMessage.Int0());
+		aComplete = EFalse;
+		iStartMessage = aMessage;
+		iStartOutstanding = ETrue;
+		}
+	else if (state == EUsbServiceStarting || state == EUsbServiceStarted)
+		{
+		if (aMessage.Int0() != iUsbServer->Device().CurrentPersonalityId())
+			{
+			return KErrAbort;
+			}
+
+		if (state == EUsbServiceStarting)
+			{
+			aComplete = EFalse;
+			iStartMessage = aMessage;
+			iStartOutstanding = ETrue;
+			}
+		}
+	else if (state == EUsbServiceStopping)
+		{
+		return KErrServerBusy;
+		}
+
+	return KErrNone;
+
+#else
+	// pretend that the server is in Started state
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	iUsbServer->Host().StartL();
+#endif
+	iStartOutstanding = EFalse;
+	aMessage.IsNull();
+	aComplete = ETrue;
+	return KErrNone;
+#endif
+	}
+
+/**
+ * Try stopping the USB device.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @param	aComplete	Whether the request is complete or not
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::TryStopDeviceL(const RMessage2& aMessage, TBool& aComplete)
+	{
+	LOG_FUNC
+
+#ifndef __OVER_DUMMYUSBDI__
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	// Only 'control' session is allowed to stop USB support
+	if ( !iSessionCtlMode )
+		{
+		return KErrAccessDenied;
+		}
+#endif
+
+	if (!iPersonalityCfged)
+		{
+		return KErrNotSupported;
+		}
+
+	if (iStartOutstanding || iStopOutstanding)
+		{
+		return KErrServerBusy;
+		}
+
+	// Obtains the curent service state
+	TUsbServiceState state = iUsbServer->Device().ServiceState();
+
+	// USB Peripheral Stack Stopping sequence:
+	// if the server is in the started state
+	//		stop it;
+	// if the server is in the starting state
+	//		return KErrServerBusy immediately;
+	// if the server is in the idle state
+	//		return KErrNone immediately;
+	// if the server is in the stopping state (must by another client)
+ 	//			mark this request as outstanding and let the caller to wait
+	//			for stop operation to complete;
+	if (state == EUsbServiceStarted)
+		{
+		iUsbServer->Device().Stop();
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+		iUsbServer->Host().Stop();
+#endif
+
+		aComplete = EFalse;
+		iStopMessage = aMessage;
+		iStopOutstanding = ETrue;
+		}
+	else if (state == EUsbServiceStarting)
+		{
+		return KErrServerBusy;
+		}
+	else if (state == EUsbServiceStopping)
+		{
+		aComplete = EFalse;
+		iStopMessage = aMessage;
+		iStopOutstanding = ETrue;
+		}
+
+	return KErrNone;
+
+#else
+	// pretend that the server is in Started state
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+	iUsbServer->Host().Stop();
+#endif
+	aMessage.IsNull();
+	aComplete = ETrue;
+	iStopOutstanding = EFalse;
+	return KErrNone;
+#endif
+	}
+
+/**
+ * Cancels the interest to the outstanding request. The acutal request itself
+ * is not cancelled.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @return	KErrCancel
+ */
+TInt CUsbSession::CancelInterest(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	if (!iPersonalityCfged)
+		{
+		return KErrNotSupported;
+		}
+
+	TUsbMessages toBeCancelledMsg = static_cast<TUsbMessages>(aMessage.Int0());
+	if (toBeCancelledMsg == EUsbStart || toBeCancelledMsg == EUsbTryStart)
+		{
+		if (iStartOutstanding)
+			{
+			iStartMessage.Complete(KErrNone);
+			iStartOutstanding = EFalse;
+			}
+		}
+	else if (toBeCancelledMsg == EUsbStop || toBeCancelledMsg == EUsbTryStop)
+		{
+		if (iStopOutstanding)
+			{
+			iStopMessage.Complete(KErrNone);
+			iStopOutstanding = EFalse;
+			}
+		}
+
+	return KErrCancel;
+	}
+
+/**
+ * Gets the current personality id.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::GetCurrentPersonalityId(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	if (!iPersonalityCfged)
+		{
+		return KErrNotSupported;
+		}
+
+	TInt currentPersonalityId = iUsbServer->Device().CurrentPersonalityId();
+	LOGTEXT2(_L8("\tcurrentPersonalityId = %d"), currentPersonalityId);
+	TPckgC<TInt> pckg(currentPersonalityId);
+	return aMessage.Write(0, pckg);
+	}
+
+/**
+ * Gets supported classes.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @return	KerrTooBig if supported class > KUsbMaxSupportedClasses;
+ *          KErrNotSupported if personality is not configured
+ * 			return code from RMessage2.Write()
+ */
+TInt CUsbSession::GetSupportedClasses(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	if (!iPersonalityCfged)
+		{
+		return KErrNotSupported;
+		}
+
+	// +1 for the size of actual class uid count
+	TInt32 classUids[KUsbMaxSupportedClasses + 1];
+	classUids[0] = 0;	// initializes class uids count to zero
+	// Gets all class uids for the given personality
+	const RPointerArray<CPersonality>&  personalities = iUsbServer->Device().Personalities();
+	TInt personalityCount = personalities.Count();
+	for (TInt i = 0; i < personalityCount; i++)
+		{
+		__ASSERT_ALWAYS(personalities[i] != NULL, _USB_PANIC(KUsbSvrPncCat, ENullPersonalityPointer));
+		if (aMessage.Int0() == personalities[i]->PersonalityId())
+			{
+			classUids[0] = personalities[i]->SupportedClasses().Count();
+			for (TInt j = 1; j <= classUids[0]; j++)
+				{
+				if (j < KUsbMaxSupportedClasses + 1)
+					{
+					classUids[j] = personalities[i]->SupportedClasses()[j - 1].iUid;
+					LOGTEXT3(_L8("\tclassUids[%d] = %d"), j, classUids[j]);
+					}
+				else
+					{
+					return KErrTooBig;
+					}
+				}
+			break;
+			}
+		}
+
+	if (classUids[0] == 0)
+		{
+		// No supported classes are found
+		return KErrNotSupported;
+		}
+
+	TInt ret;
+	HBufC8* buf = NULL;
+	TRAP(ret, buf = HBufC8::NewL((classUids[0] + 1)*sizeof(TInt32)));
+	if (ret == KErrNone)
+		{
+		TPtr8 ptr8 = buf->Des();
+		ptr8.Copy(reinterpret_cast<TUint8*>(classUids), (classUids[0] + 1)*sizeof(TInt32));
+		ret = aMessage.Write(1, ptr8);
+		}
+
+	delete buf;
+	return ret;
+	}
+
+/**
+ * Gets all personality ids.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::GetPersonalityIds(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	if (!iPersonalityCfged)
+		{
+		return KErrNotSupported;
+		}
+
+	// +1 for the size of actual personality id count
+	TInt personalityIds[KUsbMaxSupportedPersonalities + 1];
+
+	const RPointerArray<CPersonality>&  personalities = iUsbServer->Device().Personalities();
+	TInt personalityCount = personalities.Count();
+	for (TInt i = 0; i < personalityCount; ++i)
+		{
+		__ASSERT_ALWAYS(personalities[i] != NULL, _USB_PANIC(KUsbSvrPncCat, ENullPersonalityPointer));
+		personalityIds[i + 1] = personalities[i]->PersonalityId();
+		}
+	personalityIds[0] = personalityCount;
+
+	TInt ret;
+	HBufC8* buf = NULL;
+	TRAP(ret, buf = HBufC8::NewL((personalityCount + 1)*sizeof(TInt)));
+	if (ret == KErrNone)
+		{
+		TPtr8 ptr8 = buf->Des();
+		ptr8.Copy(reinterpret_cast<TUint8*>(personalityIds), (personalityCount + 1)*sizeof(TInt));
+		ret = aMessage.Write(0, ptr8);
+		}
+
+	delete buf;
+	return ret;
+	}
+
+/**
+ * Gets personality description
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::GetDescription(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	if (!iPersonalityCfged)
+		{
+		return KErrNotSupported;
+		}
+
+	TInt personalityId = aMessage.Int0();
+	const CPersonality* personality = iUsbServer->Device().GetPersonality(personalityId);
+	if (personality)
+		{
+		return aMessage.Write(1, *(personality->Description()));
+		}
+
+	// We should never reach here
+	return KErrNotSupported;
+	}
+
+/**
+ * Gets personality detailed description
+ *
+ * @internalComponent
+ * @param   aMessage    Message received from the client
+ * @return  Any error that occurred or KErrNone
+ */
+TInt CUsbSession::GetDetailedDescription(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+ 	if (!iPersonalityCfged)
+		{
+		return KErrNotSupported;
+		}
+
+	TInt personalityId = aMessage.Int0();
+	const CPersonality* personality = iUsbServer->Device().GetPersonality(personalityId);
+    	if (personality)
+        	{
+        	if(personality->Version() < EUsbManagerResourceVersionTwo)
+            		{
+            		return KErrNotFound;
+            		}
+		return aMessage.Write(1, *(personality->DetailedDescription()));
+		}
+
+	// We should never reach here
+	return KErrNotSupported;
+	}
+
+/**
+ * Gets personality property
+ *
+ * @internalComponent
+ * @param   aMessage    Message received from the client
+ * @return  Any error that occurred or KErrNone
+ */
+TInt CUsbSession::GetPersonalityProperty(const RMessage2& aMessage)
+	{
+		LOG_FUNC
+
+		if (!iPersonalityCfged)
+			{
+			return KErrNotSupported;
+			}
+
+		TInt personalityId = aMessage.Int0();
+		const CPersonality* personality = iUsbServer->Device().GetPersonality(personalityId);
+		if (personality)
+			{
+			if(personality->Version() < EUsbManagerResourceVersionThree)
+				{
+				return KErrNotFound;
+				}
+			TPckg<TUint32> pckg(personality->Property());
+			return aMessage.Write(1, pckg);
+			}
+
+		return KErrNotSupported;
+	}
+
+/**
+ * Checks if a given class is supported by a personality.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::ClassSupported(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	if (!iPersonalityCfged)
+		{
+		return KErrNotSupported;
+		}
+
+	TBool isSupported = EFalse;
+	TInt personalityId = aMessage.Int0();
+	TUid classUid = TUid::Uid(aMessage.Int1());
+	const CPersonality* personality = iUsbServer->Device().GetPersonality(personalityId);
+	if (personality)
+		{
+		isSupported = (personality->ClassSupported(classUid) != KErrNotFound);
+		TPckg<TBool> pkg2(isSupported);
+		return aMessage.Write(2, pkg2);
+		}
+
+	// We should never reach here
+	return KErrNotSupported;
+	}
+
+#ifdef SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+/**
+ * Sets or resets the control mode flag for this session.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::SetCtlSessionMode(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+
+	TBool value = (TBool)aMessage.Int0();
+	LOGTEXT2(_L8("\tSetting = %d"), static_cast<TInt>(value));
+
+	// Verify if this is the same session which set the value before
+	if ( iCtlSession && (iCtlSession != this) )
+		{
+		ret = KErrAccessDenied;
+		}
+	else
+		{
+		iSessionCtlMode = value;
+
+		// Set control session pointer if the flag is set
+		if ( iSessionCtlMode )
+			{
+			iCtlSession = this;
+			}
+		else
+			{
+			iCtlSession = NULL;
+			}
+		}
+
+	return ret;
+	}
+
+/**
+ * Asserts a request to drive VBus.
+ *
+ * @internalComponent
+ * @return	If control mode flag is not set returns KErrAccessDenied
+ * 			An error code for all other cases
+ */
+TInt CUsbSession::BusRequest()
+	{
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+	if ( iSessionCtlMode )
+		{
+		ret = iUsbServer->Otg().BusRequest();
+		}
+	else
+		{
+		ret = KErrAccessDenied;
+		}
+
+	return ret;
+	}
+
+/**
+ * Asserts a request to raise VBUS but assumes this is after B-Device
+ * has used SRP to make a request to become session Host, so may be able
+ * to take some short cuts when enumerating the B-Device.
+ *
+ * @internalComponent
+ * @return	If control mode flag is not set returns KErrAccessDenied
+ * 			Any error that occurred or KErrNone for all other cases
+ */
+TInt CUsbSession::BusRespondSrp()
+	{
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+	if ( iSessionCtlMode )
+		{
+		ret = iUsbServer->Otg().BusRespondSrp();
+		}
+	else
+		{
+		ret = KErrAccessDenied;
+		}
+
+	return ret;
+	}
+
+/**
+ * Clears a possible VBUS error condition (VBUS inexplicably low after
+ * having been driven)
+ *
+ * @internalComponent
+ * @return	If control mode flag is not set returns KErrAccessDenied
+ * 			Any error that occurred or KErrNone for all other cases
+ */
+TInt CUsbSession::BusClearError()
+	{
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+	if ( iSessionCtlMode )
+		{
+		ret = iUsbServer->Otg().BusClearError();
+		}
+	else
+		{
+		ret = KErrAccessDenied;
+		}
+
+	return ret;
+	}
+
+/**
+ * Drops VBus.
+ *
+ * @internalComponent
+ * @return	If control mode flag is not set returns KErrAccessDenied
+ * 			Any error that occurred or KErrNone for all other cases
+ */
+TInt CUsbSession::BusDrop()
+	{
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+	if ( iSessionCtlMode )
+		{
+		ret = iUsbServer->Otg().BusDrop();
+		}
+	else
+		{
+		ret = KErrAccessDenied;
+		}
+
+	return ret;
+	}
+
+/**
+ * Enables loading of Function Drivers.
+ *
+ * @internalComponent
+ * @return	If control mode flag is not set returns KErrAccessDenied
+ * 			Any error that occurred or KErrNone for all other cases
+ */
+TInt CUsbSession::EnableFunctionDriverLoading()
+	{
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+	if ( iSessionCtlMode )
+		{
+		ret = iUsbServer->Host().EnableDriverLoading();
+		}
+	else
+		{
+		ret = KErrAccessDenied;
+		}
+
+	return ret;
+	}
+
+/**
+ * Disables loading of Function Drivers.
+ *
+ * @internalComponent
+ * @return	If control mode flag is not set returns KErrAccessDenied
+ * 			KErrNone for all other cases
+ */
+TInt CUsbSession::DisableFunctionDriverLoading()
+	{
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+	if ( iSessionCtlMode )
+		{
+		iUsbServer->Host().DisableDriverLoading();
+		}
+	else
+		{
+		ret = KErrAccessDenied;
+		}
+
+	return ret;
+	}
+
+/**
+ * Requests an array of language identifiers supported by connected device.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::GetSupportedLanguages(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+	TRAPD(err, GetSupportedLanguagesL(aMessage));
+	return err;
+	}
+
+/**
+ * Requests an array of language identifiers supported by connected device.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::GetSupportedLanguagesL(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+
+	const TUint deviceId = aMessage.Int0();
+	LOGTEXT2(_L8("\tdeviceId = %d"), deviceId);
+
+	RArray<TUint> langIds;
+	CleanupClosePushL(langIds);
+	TInt ret = iUsbServer->Host().GetSupportedLanguages(deviceId,langIds);
+
+	if (ret == KErrNone)
+		{
+		const TUint count = langIds.Count();
+		LOGTEXT2(_L8("\tcount = %d"), count);
+
+		// Set error code if there is no languages or there are too many
+		if ( count == 0 )
+			{
+			ret = KErrNotSupported;
+			}
+		else if ( count > KUsbMaxSupportedLanguageIds )
+			{
+			ret = KErrTooBig;
+			}
+
+		if ( ret == KErrNone )
+			{
+			// Create a buffer to keep an array size and all received language Ids
+			RBuf8 buf;
+			buf.CreateL((count + 1) * sizeof(TUint));
+			CleanupClosePushL(buf);
+
+			// Save the length of the array
+			buf.Append((TUint8*)&count, sizeof(TUint));
+
+			// Save all received language Ids
+			for ( TUint ii = 0 ; ii < count; ++ii )
+				{
+				buf.Append((TUint8*)&(langIds[ii]), sizeof(TUint));
+				LOGTEXT3(_L8("Append langID[%d] = %d"),ii,langIds[ii]);
+				}
+
+			// Write back to the client.
+			ret = aMessage.Write(1, buf);
+			CleanupStack::PopAndDestroy(&buf);
+			}
+		}
+
+	CleanupStack::PopAndDestroy();
+
+	return ret;
+	}
+
+/**
+ * Requests a manufacturer string descriptor of connected device.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::GetManufacturerStringDescriptor(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	const TUint deviceId = aMessage.Int0();
+	const TUint langId = aMessage.Int1();
+	LOGTEXT3(_L8("\tdeviceId = %d, langId = %d"), deviceId, langId);
+
+	TName string;
+	TInt ret = iUsbServer->Host().GetManufacturerStringDescriptor(deviceId,langId,string);
+	if (ret == KErrNone)
+		{
+		LOGTEXT2(_L("\tstring = \"%S\""), &string);
+		ret = aMessage.Write(2, string);
+		}
+
+	return ret;
+	}
+
+/**
+ * Requests a product string descriptor of connected device.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::GetProductStringDescriptor(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	const TUint deviceId = aMessage.Int0();
+	const TUint langId = aMessage.Int1();
+	LOGTEXT3(_L8("\tdeviceId = %d, langId = %d"), deviceId, langId);
+
+	TName string;
+	TInt ret = iUsbServer->Host().GetProductStringDescriptor(deviceId,langId,string);
+	if (ret == KErrNone)
+		{
+		LOGTEXT2(_L("\tstring = \"%S\""), &string);
+		ret = aMessage.Write(2, string);
+		}
+
+	return ret;
+	}
+
+/**
+ * Requests a OTG descriptor of connected device.
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::GetOtgDescriptor(const RMessage2& aMessage)
+	{
+	LOG_FUNC
+
+	const TUint deviceId = aMessage.Int0();
+	LOGTEXT2(_L8("\tdeviceId = %d"), deviceId);
+
+    TOtgDescriptor otgDescriptor;
+	TInt ret = iUsbServer->Host().GetOtgDescriptor(deviceId, otgDescriptor);
+	if (ret == KErrNone)
+		{
+		TPckg<TOtgDescriptor> buf(otgDescriptor);
+		ret = aMessage.Write(1, buf);
+		}
+
+	return ret;
+	}
+
+/**
+ * Client request to observe the host (for state changes).
+ * Asks the host to register the session as an observer.
+ * Assures initialisation/dequeueing of Event queue.
+ * No events are queued until the first observer is registered
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @param	aComplete	set to true to complete the request
+ *
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::RegisterHostObserver(const RMessage2& aMessage, TBool& aComplete)
+	{
+	LOG_FUNC
+
+	if (iHostEventObserverOutstanding)
+		{
+		return KErrInUse;
+		}
+
+	iHostEventObserverMessage = aMessage;
+	iHostEventObserverOutstanding = ETrue;
+	aComplete = EFalse;
+
+ 	if (iHostEventObserverQueueEvents == EFalse)
+	 	{
+ 		// This is the first observer after c'tor or DeregisterObserver(),
+ 		// so zap the device event queue.
+ 		LOGTEXT(_L8("    Reset OTG Host State Queue"));
+ 		iHostEventQueueHead = 0;
+ 		iHostEventQueueTail = 0;
+ 		iHostEventObserverQueueEvents = ETrue;
+	 	}
+ 	else if (iHostEventQueueHead != iHostEventQueueTail)
+	 	{
+ 		// event(s) queued, we can de-queue one now
+ 		UsbHostEventDequeue();
+	 	}
+
+	return KErrNone;
+	}
+
+/**
+ * Deregister the client as an observer of host state changes.
+ *
+ * @internalComponent
+ * @return Always KErrNone
+ */
+TInt CUsbSession::DeRegisterHostObserver()
+	{
+	LOG_FUNC
+
+
+	if (!iHostEventObserverOutstanding)
+		{
+		return KErrNone;
+		}
+
+	iHostEventObserverOutstanding = EFalse;
+	iHostEventObserverMessage.Complete(KErrCancel);
+
+	// client doesn't need events queuing any more
+ 	iHostEventObserverQueueEvents = EFalse;
+
+	return KErrNone;
+	}
+
+/**
+ * Client request to observe both OTG and HOST (for events and errors).
+ * Asks HOST and OTGDI components to register the session as an observer.
+ * Assures initialisation/dequeueing of Event queue.
+ * No events are queued until the first observer is registered
+ *
+ * @internalComponent
+ * @param	aMessage	Message received from the client
+ * @param	aComplete	set to true to complete the request
+ *
+ * @return	Any error that occurred or KErrNone
+ */
+TInt CUsbSession::RegisterMsgObserver(const RMessage2& aMessage, TBool& aComplete)
+	{
+	LOG_FUNC
+
+	if (iMsgObserverOutstanding)
+		{
+		return KErrInUse;
+		}
+
+	iMsgObserverMessage = aMessage;
+	iMsgObserverOutstanding = ETrue;
+	aComplete = EFalse;
+
+ 	if (iMsgObserverQueueEvents == EFalse)
+	 	{
+ 		// This is the first observer after c'tor or DeregisterObserver(),
+ 		// so zap the device event queue.
+ 		LOGTEXT(_L8("    Reset OTG Message Queue"));
+ 		iMsgQueueHead = 0;
+ 		iMsgQueueTail = 0;
+ 		iMsgObserverQueueEvents = ETrue;
+	 	}
+ 	else if (iMsgQueueHead != iMsgQueueTail)
+	 	{
+ 		// event(s) queued, we can de-queue one now
+ 		UsbMsgDequeue();
+	 	}
+
+	return KErrNone;
+	}
+
+/**
+ * Deregister the client as an observer of OTG/HOST events and errors.
+ *
+ * @internalComponent
+ * @return Always KErrNone
+ */
+TInt CUsbSession::DeRegisterMsgObserver()
+	{
+	LOG_FUNC
+
+	if (!iMsgObserverOutstanding)
+		{
+		return KErrNone;
+		}
+
+	iMsgObserverOutstanding = EFalse;
+	iMsgObserverMessage.Complete(KErrCancel);
+
+	// client doesn't need events queuing any more
+ 	iMsgObserverQueueEvents = EFalse;
+
+	return KErrNone;
+	}
+
+
+
+/**
+ * Called by CUsbOtg or CUsbHost when the USB OTG/HOST message has arrived
+ *
+ * @internalComponent
+ * @param aMessage The new OTG Message
+ */
+void CUsbSession::UsbOtgHostMessage(TInt aMessage)
+	{
+	LOG_FUNC
+
+	// can we bypass the queue?
+ 	if ((iMsgObserverOutstanding) && (iMsgQueueHead == iMsgQueueTail))
+		{
+		TPckg<TInt> pckg(aMessage);
+
+		iNotifiedMsg = aMessage;
+
+		iMsgObserverOutstanding = EFalse;
+		const TInt err = iMsgObserverMessage.Write(0, pckg);
+		iMsgObserverMessage.Complete(err);
+		}
+	else if (iMsgObserverQueueEvents)
+		{
+		// add event to head of queue
+		iMsgQueue[iMsgQueueHead] = aMessage;
+		iMsgQueueHead = (iMsgQueueHead + 1) % KOtgHostMessageQueueSize;
+		LOGTEXT3(_L8("+++ CUsbSession::UsbOtgMessage() addqueue (%d, %d)"), iMsgQueueHead,
+			iMsgQueueTail);
+
+ 		// UsbMsgDequeueEvent() will read from queue when RegisterMsgObserver()
+		// is next called.
+		}
+	}
+
+/**
+ * Called by CUsbHost when it state change. CUsbSession is an observer of
+ * the device. If the client has an Observer outstanding then complete it,
+ * otherwise put it in a circular queue.
+ *
+ * @internalComponent
+ * @param	aDevInfo	The information about the device being attached or detached
+ * 						along with the status of Function Driver loading
+ */
+void CUsbSession::UsbHostEvent(TDeviceEventInformation& aDevInfo)
+	{
+	LOG_FUNC
+
+	// can we bypass the queue?
+ 	if ((iHostEventObserverOutstanding) && (iHostEventQueueHead == iHostEventQueueTail))
+		{
+		iNotifiedHostState = aDevInfo;
+		iHostEventObserverOutstanding = EFalse;
+
+		LOGTEXT(_L8("CUsbSession::UsbHostEvent() detected outstanding request"));
+
+		TPckg<TDeviceEventInformation> info(aDevInfo);
+		const TInt err = iHostEventObserverMessage.Write(0, info);
+		iHostEventObserverMessage.Complete(err);
+		LOGTEXT2(_L8("CUsbSession::UsbHostEvent() detects outstanding request: request is compeleted with %d"), err);
+		}
+	else if (iHostEventObserverQueueEvents)
+		{
+		// add dev info to head of queue
+		iHostStateQueue[iHostEventQueueHead] = aDevInfo;
+		iHostEventQueueHead = (iHostEventQueueHead + 1) % KDeviceStatesQueueSize;
+		LOGTEXT3(_L8("+++ CUsbSession::UsbHostEvent() addqueue (%d, %d)"), iHostEventQueueHead,
+			iHostEventQueueTail);
+
+ 		// UsbHostStateDequeueEvent() will read from queue when RegisterHostObserver()
+		// is next called.
+		}
+	}
+
+/**
+ * Dequeues an event and completes the observer's request with it.
+ */
+void CUsbSession::UsbMsgDequeue()
+ 	{
+	LOG_FUNC
+
+	// Work our way through the queue, until we reach the end
+ 	// OR we find an event the current observer wants.
+ 	if ((iMsgObserverOutstanding) && (iMsgQueueHead != iMsgQueueTail))
+ 		{
+ 		TInt newMsg = iMsgQueue[iMsgQueueTail];
+
+ 		// advance tail towards the head
+ 		iMsgQueueTail = (iMsgQueueTail + 1) % KOtgHostMessageQueueSize;
+
+ 		TPckg<TUint32> pckg(newMsg);
+ 		iNotifiedMsg = newMsg;
+
+ 		LOGTEXT3(_L8(">>> dequeued event #%d (0x%x)"), iMsgQueueTail, newMsg);
+
+		iMsgObserverOutstanding = EFalse;
+		const TInt err = iMsgObserverMessage.Write(0, pckg);
+		iMsgObserverMessage.Complete(err);
+   		}
+  	}
+
+/**
+ * Dequeues an event and completes the observer's request with it.
+ */
+void CUsbSession::UsbHostEventDequeue()
+ 	{
+	LOG_FUNC
+
+	// Work our way through the queue, until we reach the end
+ 	// OR we find an event the current observer wants.
+ 	if ((iHostEventObserverOutstanding) && (iHostEventQueueHead != iHostEventQueueTail))
+ 		{
+ 		// inform the observer of state changes they are interested in AND
+ 		// if the cable is pulled out (EUsbDeviceStateUndefined)
+ 		TDeviceEventInformation newDevInfo = iHostStateQueue[iHostEventQueueTail];
+		iNotifiedHostState = newDevInfo;
+
+ 		// advance tail towards the head
+ 		iHostEventQueueTail = (iHostEventQueueTail + 1) % KDeviceStatesQueueSize;
+
+		LOGTEXT3(_L8(">>> CUsbSession::UsbHostStateDequeueEvent() dequeued event #%d (0x%x)"), iHostEventQueueTail, newDevInfo.iEventType);
+
+		TPckg<TDeviceEventInformation> info(newDevInfo);
+		iHostEventObserverOutstanding = EFalse;
+		const TInt err = iHostEventObserverMessage.Write(0, info);
+		iHostEventObserverMessage.Complete(err);
+
+		LOGTEXT2(_L8("CUsbSession::UsbHostStateDequeueEvent() detects outstanding request: request is compeleted with %d"), err);
+   		}
+   	}
+
+TInt CUsbSession::RequestSession()
+	{
+	return DoRequestSession();
+	}
+
+TInt CUsbSession::DoRequestSession()
+	{
+	if ( iCtlSession )
+		{
+		if ( iCtlSession == this )
+			{
+	 		if (iMsgObserverQueueEvents)
+	 			{
+	 			UsbOtgHostMessage(KUsbMessageRequestSession);
+	 			return KErrNone;
+	 			}
+		 	else
+		 		{
+		 		return KErrNotFound;
+		 		}
+			}
+		else
+			{
+			return iCtlSession->DoRequestSession();
+			}
+		}
+ 	return KErrNotFound;
+	}
+
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/UsbSvr.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,127 @@
+/*
+* Copyright (c) 2003-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:
+*
+*/
+
+#include <e32base.h>
+#include <usb/usbshared.h>
+#include "CUsbScheduler.h"
+#include "CUsbServer.h"
+#include <usb/usblogger.h>
+#include "rusb.h"
+
+static void RunServerL();
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBSVR");
+#endif
+
+
+GLDEF_C TInt E32Main()
+/**
+ * Entry-point for the USB Manager server.
+ *
+ * @return The result of UsbMan::Run
+ */
+	{
+	__UHEAP_MARK;
+
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+
+	TInt ret = KErrNoMemory;
+
+	if (cleanup)
+		{
+		TRAP(ret, RunServerL());
+		delete cleanup;
+		}
+
+	__UHEAP_MARKEND;
+
+	return ret;
+	}
+
+static void RunServerL()
+//
+// Perform all server initialisation, in particular creation of the
+// scheduler and server and then run the scheduler
+//
+	{
+	// naming the server thread after the server helps to debug panics
+	LEAVEIFERRORL(User::RenameThread(KUsbServerName));
+	//
+	// create and install the active scheduler we need
+	CUsbScheduler* scheduler = CUsbScheduler::NewL();
+	CleanupStack::PushL(scheduler);
+	CUsbScheduler::Install(scheduler);
+	//
+	// create the server (leave it on the cleanup stack)
+	CUsbServer* server = CUsbServer::NewLC();
+	scheduler->SetServer(*server);
+	//
+	// Initialisation complete, now signal the client
+#ifdef __USBMAN_NO_PROCESSES__
+	RThread::Rendezvous(KErrNone);
+#else
+	RProcess::Rendezvous(KErrNone);
+#endif
+
+	//
+	// Ready to run
+	CActiveScheduler::Start();
+
+	//
+	// Cleanup the server and scheduler
+	CleanupStack::PopAndDestroy(2, scheduler);
+	}
+
+#ifdef __USBMAN_NO_PROCESSES__
+
+// The server binary is an "EPOCEXE" target type
+// Thus the server parameter passing and startup code for WINS and EPOC are
+// significantly different.
+//
+// In EKA1 WINS, the EPOCEXE target is a DLL with an entry point called WinsMain,
+// taking no parameters and returning TInt. This is not really valid as a thread
+// function which takes a TAny* parameter which we need.
+//
+// So the DLL entry-point WinsMain() is used to return a TInt representing the
+// real thread function within the DLL. This is good as long as
+// sizeof(TInt)>=sizeof(TThreadFunction).
+//
+
+static TInt ThreadFunction(TAny* /*aPtr*/)
+//
+// WINS thread entry-point function.
+//
+	{
+	return E32Main();
+	}
+
+IMPORT_C TInt WinsMain();
+EXPORT_C TInt WinsMain()
+//
+// WINS DLL entry-point. Just return the real thread function 
+// cast to TInt
+//
+	{
+	return reinterpret_cast<TInt>(&ThreadFunction);
+	}
+
+
+#endif
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/UsbUtils.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+#include <e32std.h>
+#include <e32base.h>
+#include "UsbUtils.h"
+
+void ResetAndDestroy(TAny* aPtr)
+/**
+ *Function passed in as a parameter to TCleanupItem constructor to 
+ *reset and destroy the received aPtr.
+ *
+ *aPtr object
+ *
+ *@param aPtr a pointer to the object that is to be cleaned up
+ */
+	{
+	reinterpret_cast<RImplInfoPtrArray*>(aPtr)->ResetAndDestroy();
+	}
+
+void CleanupResetAndDestroyPushL(RImplInfoPtrArray& aArray)
+/**
+ *Function that creates a clean up item for the received, aArray and
+ *specifies the cleanup function, ResetAndDestroy. When the item is 
+ *removed from the cleanup stack the function, ResetAndDestroy will be
+ *called on aArray
+ *
+ *@param aArray the array to be pushed onto the cleanup stack
+ */
+   	{  	    
+	TCleanupItem item(ResetAndDestroy, &aArray);
+   	CleanupStack::PushL(item);
+   	}
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/cusbhost.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,248 @@
+/*
+* 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 "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 "cusbhost.h"
+#include <usb/usblogger.h>
+
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "usbhost");
+#endif
+
+CUsbHost* CUsbHost::iInstance = 0;
+
+CUsbHost* CUsbHost::NewL()
+	{
+	if(iInstance == 0)
+		{
+		iInstance = new (ELeave) CUsbHost();		
+		CleanupStack::PushL(iInstance);		
+		iInstance->ConstructL();		
+		CleanupStack::Pop(iInstance);
+		}	
+	return iInstance;
+	}
+
+CUsbHost::~CUsbHost()
+	{
+	LOG_FUNC
+
+	Stop();
+
+	TInt i =0;
+	for(i=0;i<ENumMonitor;i++)
+		{
+		delete iUsbHostWatcher[i];
+		iUsbHostWatcher[i] = NULL;
+		}
+	iObservers.Close();
+	iInstance = 0;
+	}
+
+CUsbHost::CUsbHost()
+	{
+	LOG_FUNC
+	}
+
+void CUsbHost::ConstructL()
+	{
+	LOG_FUNC
+
+	iUsbHostWatcher[EHostEventMonitor] = 
+			CActiveUsbHostEventWatcher::NewL(iUsbHostStack,*this,iHostEventInfo);
+	iUsbHostWatcher[EHostMessageMonitor] = 
+			CActiveUsbHostMessageWatcher::NewL(iUsbHostStack,*this,iHostMessage);
+	}
+void CUsbHost::StartL()
+	{
+	LOG_FUNC
+
+	if(!iHasBeenStarted)
+		{
+
+		LEAVEIFERRORL(iUsbHostStack.Connect());
+
+		for(TInt i=0;i<ENumMonitor;i++)
+			{
+			iUsbHostWatcher[i]->Post();
+			}
+		iHasBeenStarted = ETrue;
+		}
+	}
+
+void CUsbHost::Stop()
+	{
+	LOG_FUNC
+
+	TInt i=0;
+	for(i=0;i<ENumMonitor;i++)
+		{
+		if (iUsbHostWatcher[i])
+			{
+			iUsbHostWatcher[i]->Cancel();
+			}
+		}
+
+	iUsbHostStack.Close();
+
+	iHasBeenStarted = EFalse;
+	}
+
+void CUsbHost::RegisterObserverL(MUsbOtgHostNotifyObserver& aObserver)
+	{
+	LOG_FUNC
+
+	iObservers.AppendL(&aObserver);
+	UpdateNumOfObservers();
+	}
+
+void CUsbHost::DeregisterObserver(MUsbOtgHostNotifyObserver& aObserver)
+	{
+	LOG_FUNC
+	TInt index = iObservers.Find(&aObserver);
+	if(index == KErrNotFound)
+		{
+		LOGTEXT(_L8("\t Cannot remove observer, not found"));
+		}
+	else
+		{
+		iObservers.Remove(index);
+		}
+
+	UpdateNumOfObservers();
+	}
+
+TInt CUsbHost::GetSupportedLanguages(TUint aDeviceId,RArray<TUint>& aLangIds)
+	{
+	LOG_FUNC
+	TInt err = KErrNone;
+	if ( iUsbHostStack.Handle() )
+		{
+		err = iUsbHostStack.GetSupportedLanguages(aDeviceId,aLangIds);
+		}
+	else
+		{
+		err = KErrBadHandle;
+		}
+	return err;
+	}
+
+TInt CUsbHost::GetManufacturerStringDescriptor(TUint aDeviceId,TUint aLangId,TName& aString)
+	{
+	LOG_FUNC
+	TInt err = KErrNone;
+	if ( iUsbHostStack.Handle() )
+		{
+		err = iUsbHostStack.GetManufacturerStringDescriptor(aDeviceId,aLangId,aString);
+		}
+	else
+		{
+		err = KErrBadHandle;
+		}
+	return err;
+	}
+
+TInt CUsbHost::GetProductStringDescriptor(TUint aDeviceId,TUint aLangId,TName& aString)
+	{
+	LOG_FUNC
+	TInt err = KErrNone;
+	if ( iUsbHostStack.Handle() )
+		{
+		err = iUsbHostStack.GetProductStringDescriptor(aDeviceId,aLangId,aString);
+		}
+	else
+		{
+		err = KErrBadHandle;
+		}
+	return err;
+	}
+
+TInt CUsbHost::GetOtgDescriptor(TUint aDeviceId, TOtgDescriptor& otgDescriptor)
+	{
+	LOG_FUNC
+	
+	TInt err(KErrNone);
+	
+	if (iUsbHostStack.Handle())
+		{
+		err = iUsbHostStack.GetOtgDescriptor(aDeviceId, otgDescriptor);
+		}
+	else
+		{
+		err = KErrBadHandle;
+		}
+	
+	return err;
+	}
+
+void CUsbHost::NotifyHostEvent(TUint aWatcherId)
+	{
+	LOG_FUNC
+	if(aWatcherId == EHostEventMonitor)
+		{
+
+		LOGTEXT2(_L8("\t Device id %d"),iHostEventInfo.iDeviceId);
+		LOGTEXT2(_L8("\t iEventType  %d"),iHostEventInfo.iEventType);
+		LOGTEXT2(_L8("\t TDriverLoadStatus %d"),iHostEventInfo.iDriverLoadStatus);
+		LOGTEXT2(_L8("\t VID %d"),iHostEventInfo.iVid);
+		LOGTEXT2(_L8("\t PID %d"),iHostEventInfo.iPid);
+
+		for(TUint i=0;i<iNumOfObservers;i++)
+			{
+			iObservers[i]->UsbHostEvent(iHostEventInfo);
+			}
+		}
+	else
+		{
+		LOGTEXT2(_L8("\t Host Message %d"),iHostMessage);
+
+		for(TUint i=0;i<iNumOfObservers;i++)
+			{
+			iObservers[i]->UsbOtgHostMessage(iHostMessage);
+			}
+		}
+	}
+
+void CUsbHost::UpdateNumOfObservers()
+	{
+	LOG_FUNC
+	iNumOfObservers = iObservers.Count();
+	}
+
+TInt CUsbHost::EnableDriverLoading()
+	{
+	LOG_FUNC
+	TInt err = KErrNone;
+	if ( iUsbHostStack.Handle() )
+		{
+		err = iUsbHostStack.EnableDriverLoading();
+		}
+	else
+		{
+		err = KErrBadHandle;
+		}
+	return err;
+	}
+
+void CUsbHost::DisableDriverLoading()
+	{
+	LOG_FUNC
+	if ( iUsbHostStack.Handle() )
+		{
+		iUsbHostStack.DisableDriverLoading();
+		}
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/cusbhostwatcher.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,155 @@
+/*
+* 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 "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 "cusbhostwatcher.h"
+#include <usb/usblogger.h>
+#include "cusbhost.h"
+
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "hoststatewatcher");
+#endif
+
+/*
+ * 	Base class for USB Host watchers
+ */
+CActiveUsbHostWatcher::CActiveUsbHostWatcher(RUsbHostStack& aUsbHostStack, 
+											 MUsbHostObserver& aOwner,
+											 TUint aWatcherId):
+	CActive(CActive::EPriorityStandard),
+	iUsbHostStack(aUsbHostStack),
+	iOwner(aOwner),
+	iWatcherId(aWatcherId)
+	{
+	LOG_FUNC
+	CActiveScheduler::Add(this);
+	}
+
+CActiveUsbHostWatcher::~CActiveUsbHostWatcher()
+	{
+	LOG_FUNC
+	Cancel();
+	}
+
+void CActiveUsbHostWatcher::RunL()
+	{
+	LOG_FUNC
+
+	ASSERT(iStatus.Int() == KErrNone);
+	iOwner.NotifyHostEvent(iWatcherId);
+	Post();
+	}
+
+
+
+/*
+ * 	Monitors host events (attach/load/detach)
+ */
+CActiveUsbHostEventWatcher* CActiveUsbHostEventWatcher::NewL(
+												RUsbHostStack& aUsbHostStack, 
+												MUsbHostObserver& aOwner,
+												TDeviceEventInformation& aHostEventInfo)
+	{
+	CActiveUsbHostEventWatcher* self = new (ELeave) CActiveUsbHostEventWatcher(aUsbHostStack,aOwner,aHostEventInfo);
+	return self;
+	}
+
+
+CActiveUsbHostEventWatcher::CActiveUsbHostEventWatcher(
+									RUsbHostStack& aUsbHostStack,
+									MUsbHostObserver& aOwner,
+									TDeviceEventInformation& aHostEventInfo)
+									:CActiveUsbHostWatcher(aUsbHostStack,
+														   aOwner,
+														   KHostEventMonitor)
+														 , iHostEventInfo(aHostEventInfo)
+
+	{
+	LOG_FUNC
+	}
+
+CActiveUsbHostEventWatcher::~CActiveUsbHostEventWatcher()
+	{
+	LOG_FUNC
+	Cancel();
+	}
+
+void CActiveUsbHostEventWatcher::Post()
+	{
+	LOG_FUNC
+
+	iUsbHostStack.NotifyDeviceEvent(iStatus, iHostEventInfo);
+	SetActive();
+	}
+
+void CActiveUsbHostEventWatcher::DoCancel()
+	{
+	LOG_FUNC
+
+	iUsbHostStack.NotifyDeviceEventCancel();
+	}
+
+
+/*
+ * 	Monitors device monitor events
+ */
+
+CActiveUsbHostMessageWatcher* CActiveUsbHostMessageWatcher::NewL(
+		RUsbHostStack& aUsbHostStack, 
+		MUsbHostObserver& aOwner,
+		TInt& aHostMessage)
+	{
+	CActiveUsbHostMessageWatcher* self = new (ELeave)CActiveUsbHostMessageWatcher(aUsbHostStack,aOwner,aHostMessage);
+	return self;
+	}
+
+CActiveUsbHostMessageWatcher::~CActiveUsbHostMessageWatcher()
+	{
+	LOG_FUNC
+
+	Cancel();
+	}
+
+CActiveUsbHostMessageWatcher::CActiveUsbHostMessageWatcher(
+										RUsbHostStack& aUsbHostStack,
+										MUsbHostObserver& aOwner,
+										TInt& aHostMessage)
+										:CActiveUsbHostWatcher(aUsbHostStack,
+															   aOwner,
+															   KHostMessageMonitor)
+										, iHostMessage(aHostMessage)
+	{
+	LOG_FUNC
+	}
+
+void CActiveUsbHostMessageWatcher::Post()
+	{
+	LOG_FUNC
+	
+	iUsbHostStack.NotifyDevmonEvent(iStatus, iHostMessage);
+	SetActive();
+	}
+
+
+void CActiveUsbHostMessageWatcher::DoCancel()
+	{
+	LOG_FUNC
+	
+	iUsbHostStack.NotifyDevmonEventCancel();
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/cusbotgwatcher.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,927 @@
+/*
+* 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 "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:
+* Talks directly to the USB Logical Device Driver (LDD) and 
+* watches any state changes
+*
+*/
+
+/**
+ @file
+*/
+
+#include <usb/usblogger.h>
+#include "CUsbScheduler.h"
+#include "cusbotgwatcher.h"
+#include "CUsbOtg.h"
+#include <usb/usbshared.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBSVR-OTGWATCHER");
+#endif
+
+static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
+static _LIT_SECURITY_POLICY_S1(KNetworkControlPolicy,KUsbmanSvrSid,ECapabilityNetworkControl);
+static _LIT_SECURITY_POLICY_C1(KRequestSessionPolicy,ECapabilityCommDD);
+
+//-----------------------------------------------------------------------------
+//------------------------------ Helper watchers ------------------------------ 
+//-----------------------------------------------------------------------------
+//--------------------- Base class for all helper watchers -------------------- 
+/**
+ * The CUsbOtgBaseWatcher::CUsbOtgBaseWatcher method
+ *
+ * Constructor
+ *
+ * @param	aOwner	The device that owns the state watcher
+ * @param	aLdd	A reference to the USB Logical Device Driver
+ */
+CUsbOtgBaseWatcher::CUsbOtgBaseWatcher(RUsbOtgDriver& aLdd)
+	: CActive(CActive::EPriorityStandard), iLdd(aLdd)
+	{
+	LOG_FUNC
+	CActiveScheduler::Add(this);
+	}
+
+/**
+ * The CUsbOtgBaseWatcher::~CUsbOtgBaseWatcher method
+ *
+ * Destructor
+ *
+ * @internalComponent
+ */
+CUsbOtgBaseWatcher::~CUsbOtgBaseWatcher()
+	{
+	LOG_FUNC
+	Cancel();
+	}
+
+/**
+ * Instructs the state watcher to start watching.
+ */
+void CUsbOtgBaseWatcher::Start()
+	{
+	LOG_FUNC
+	Post();
+	}
+
+//---------------------------- Id-Pin watcher class --------------------------- 
+/**
+ * The CUsbOtgIdPinWatcher::NewL method
+ *
+ * Constructs a new CUsbOtgWatcher object
+ *
+ * @internalComponent
+ * @param	aLdd	A reference to the USB Logical Device Driver
+ *
+ * @return	A new CUsbOtgWatcher object
+ */
+CUsbOtgIdPinWatcher* CUsbOtgIdPinWatcher::NewL(RUsbOtgDriver& aLdd)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbOtgIdPinWatcher* self = new (ELeave) CUsbOtgIdPinWatcher(aLdd);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+/**
+ * The CUsbOtgIdPinWatcher::~CUsbOtgIdPinWatcher method
+ *
+ * Destructor
+ *
+ * @internalComponent
+ */
+CUsbOtgIdPinWatcher::~CUsbOtgIdPinWatcher()
+	{
+	LOG_FUNC
+	Cancel();
+	RProperty::Delete(KUsbOtgIdPinPresentProperty);
+	}
+
+void CUsbOtgIdPinWatcher::ConstructL()
+/**
+ * Performs 2nd phase construction of the OTG object.
+ */
+	{
+	LOG_FUNC
+
+	TInt err = RProperty::Define(KUsbOtgIdPinPresentProperty, RProperty::EInt, KAllowAllPolicy, KNetworkControlPolicy);
+	if ( err != KErrNone && err != KErrAlreadyExists )
+	    {
+	    User::LeaveIfError(err);
+	    }
+	err = RProperty::Set(KUidUsbManCategory,KUsbOtgIdPinPresentProperty,EFalse);
+	if ( err != KErrNone )
+	    {
+	    User::LeaveIfError(err);
+	    }
+	}
+
+/**
+ * The CUsbOtgIdPinWatcher::CUsbOtgIdPinWatcher method
+ *
+ * Constructor
+ *
+ * @param	aLdd	A reference to the USB Logical Device Driver
+ */
+
+CUsbOtgIdPinWatcher::CUsbOtgIdPinWatcher(RUsbOtgDriver& aLdd)
+	: CUsbOtgBaseWatcher(aLdd)
+	{
+	LOG_FUNC
+	}
+
+/**
+ * Called when the ID-Pin status change is reported
+ */
+void CUsbOtgIdPinWatcher::RunL()
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8(">>CUsbOtgIdPinWatcher::RunL [iStatus=%d]"), iStatus.Int());
+
+	LEAVEIFERRORL(iStatus.Int());
+	
+	Post();
+
+	LOGTEXT(_L8("<<CUsbOtgIdPinWatcher::RunL"));
+	}
+
+
+/**
+ * Automatically called when the ID-Pin watcher is cancelled.
+ */
+void CUsbOtgIdPinWatcher::DoCancel()
+	{
+	LOG_FUNC
+	iLdd.CancelOtgIdPinNotification();
+	}
+
+/**
+ * Sets state watcher in active state
+ */
+void CUsbOtgIdPinWatcher::Post()
+	{
+	LOG_FUNC
+
+	LOGTEXT(_L8("CUsbOtgIdPinWatcher::Post() - About to call QueueOtgIdPinNotification"));
+	iLdd.QueueOtgIdPinNotification(iOtgIdPin, iStatus);
+	switch (iOtgIdPin)
+		{
+		case RUsbOtgDriver::EIdPinAPlug:
+			if (RProperty::Set(KUidUsbManCategory,KUsbOtgIdPinPresentProperty,ETrue) != KErrNone)
+				{
+				LOGTEXT2(_L8(">>CUsbOtgIdPinWatcher::Post [iOtgIdPin=%d] - failed to set the property value"), iOtgIdPin);
+				}
+			else
+				{
+				LOGTEXT2(_L8(">>CUsbOtgIdPinWatcher::Post [iOtgIdPin=%d] - property is set to 1"), iOtgIdPin);
+				}
+			break;
+		case RUsbOtgDriver::EIdPinBPlug:
+		case RUsbOtgDriver::EIdPinUnknown:
+			if (RProperty::Set(KUidUsbManCategory,KUsbOtgIdPinPresentProperty,EFalse) != KErrNone)
+				{
+				LOGTEXT2(_L8(">>CUsbOtgIdPinWatcher::Post [iOtgIdPin=%d] - failed to set the property value"), iOtgIdPin);
+				}
+			else
+				{
+				LOGTEXT2(_L8(">>CUsbOtgIdPinWatcher::Post [iOtgIdPin=%d] - property is set to 0"), iOtgIdPin);
+				}
+			break;
+		default:
+			LOGTEXT2(_L8(">>CUsbOtgIdPinWatcher::Post [iOtgIdPin=%d] is unrecognized, re-request QueueOtgIdPinNotification"), iOtgIdPin);
+			break;
+		}
+	SetActive();
+	}
+
+//----------------------------- VBus watcher class ---------------------------- 
+/**
+ * The CUsbOtgVbusWatcher::NewL method
+ *
+ * Constructs a new CUsbOtgVbusWatcher object
+ *
+ * @internalComponent
+ * @param	aLdd	A reference to the USB OTG Logical Device Driver
+ *
+ * @return	A new CUsbOtgVbusWatcher object
+ */
+CUsbOtgVbusWatcher* CUsbOtgVbusWatcher::NewL(RUsbOtgDriver& aLdd)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbOtgVbusWatcher* self = new (ELeave) CUsbOtgVbusWatcher(aLdd);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+/**
+ * The CUsbOtgVbusWatcher::~CUsbOtgVbusWatcher method
+ *
+ * Destructor
+ *
+ * @internalComponent
+ */
+CUsbOtgVbusWatcher::~CUsbOtgVbusWatcher()
+	{
+	LOG_FUNC
+	Cancel();
+
+	RProperty::Delete(KUsbOtgVBusPoweredProperty);
+	}
+
+void CUsbOtgVbusWatcher::ConstructL()
+/**
+ * Performs 2nd phase construction of the OTG object.
+ */
+	{
+	LOG_FUNC
+
+	TInt err = RProperty::Define(KUsbOtgVBusPoweredProperty, RProperty::EInt, KAllowAllPolicy, KNetworkControlPolicy);
+	if ( err != KErrNone && err != KErrAlreadyExists )
+	    {
+	    User::LeaveIfError(err);
+	    }
+	err = RProperty::Set(KUidUsbManCategory,KUsbOtgVBusPoweredProperty,EFalse);
+	if ( err != KErrNone )
+	    {
+	    User::LeaveIfError(err);
+	    }
+	}
+
+/**
+ * The CUsbOtgVbusWatcher::CUsbOtgVbusWatcher method
+ *
+ * Constructor
+ *
+ * @param	aLdd	A reference to the USB OTG Logical Device Driver
+ */
+CUsbOtgVbusWatcher::CUsbOtgVbusWatcher(RUsbOtgDriver& aLdd)
+	: CUsbOtgBaseWatcher(aLdd)
+	{
+	LOG_FUNC
+	}
+
+/**
+ * Called when the Vbus status is changed
+ */
+void CUsbOtgVbusWatcher::RunL()
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8(">>CUsbOtgVbusWatcher::RunL [iStatus=%d]"), iStatus.Int());
+
+	LEAVEIFERRORL(iStatus.Int());
+
+	Post();
+
+	LOGTEXT(_L8("<<CUsbOtgVbusWatcher::RunL"));
+	}
+
+
+/**
+ * Automatically called when the VBus status watcher is cancelled.
+ */
+void CUsbOtgVbusWatcher::DoCancel()
+	{
+	LOG_FUNC
+	iLdd.CancelOtgVbusNotification();
+	}
+
+/**
+ * Sets state watcher in active state
+ */
+void CUsbOtgVbusWatcher::Post()
+	{
+	LOG_FUNC
+
+	LOGTEXT(_L8("CUsbOtgVbusWatcher::Post() - About to call QueueOtgVbusNotification"));
+	iLdd.QueueOtgVbusNotification(iOtgVbus, iStatus);
+	switch (iOtgVbus)
+		{
+		case RUsbOtgDriver::EVbusHigh:
+			if (RProperty::Set(KUidUsbManCategory,KUsbOtgVBusPoweredProperty,ETrue) != KErrNone)
+				{
+				LOGTEXT2(_L8(">>CUsbOtgVbusWatcher::Post [iOtgVbus=%d](EVbusHigh) - failed to set the property value"), iOtgVbus);
+				}
+			else
+				{
+				LOGTEXT2(_L8(">>CUsbOtgVbusWatcher::Post [iOtgVbus=%d](EVbusHigh) - property is set to ETrue"), iOtgVbus);
+				}
+			break;
+		case RUsbOtgDriver::EVbusLow:
+		case RUsbOtgDriver::EVbusUnknown:
+			if (RProperty::Set(KUidUsbManCategory,KUsbOtgVBusPoweredProperty,EFalse) != KErrNone)
+				{
+				LOGTEXT2(_L8(">>CUsbOtgVbusWatcher::Post [iOtgVbus=%d](1 - EVbusLow, 2 - EVbusUnknown) - failed to set the property value"), iOtgVbus);
+				}
+			else
+				{
+				LOGTEXT2(_L8(">>CUsbOtgVbusWatcher::Post [iOtgVbus=%d](1 - EVbusLow, 2 - EVbusUnknown) - property is set to EFalse"), iOtgVbus);
+				}
+			break;
+		default:
+			LOGTEXT2(_L8(">>CUsbOtgVbusWatcher::RunL [iOtgVbus=%d] is unrecognized, re-request QueueOtgVbusNotification"), iOtgVbus);
+			break;
+		}
+	SetActive();
+	}
+
+
+//-------------------------- OTG State watcher class -------------------------- 
+/**
+ * The CUsbOtgStateWatcher::NewL method
+ *
+ * Constructs a new CUsbOtgWatcher object
+ *
+ * @internalComponent
+ * @param	aLdd	A reference to the USB Logical Device Driver
+ *
+ * @return	A new CUsbOtgWatcher object
+ */
+CUsbOtgStateWatcher* CUsbOtgStateWatcher::NewL(RUsbOtgDriver& aLdd)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbOtgStateWatcher* self = new (ELeave) CUsbOtgStateWatcher(aLdd);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+/**
+ * The CUsbOtgStateWatcher::~CUsbOtgStateWatcher method
+ *
+ * Destructor
+ *
+ * @internalComponent
+ */
+CUsbOtgStateWatcher::~CUsbOtgStateWatcher()
+	{
+	LOG_FUNC
+	Cancel();
+	RProperty::Delete(KUsbOtgStateProperty);
+	}
+
+void CUsbOtgStateWatcher::ConstructL()
+/**
+ * Performs 2nd phase construction of the OTG object.
+ */
+	{
+	LOG_FUNC
+
+	TInt err = RProperty::Define(KUsbOtgStateProperty, RProperty::EInt, KAllowAllPolicy, KNetworkControlPolicy);
+	if ( err != KErrNone && err != KErrAlreadyExists )
+	    {
+	    User::LeaveIfError(err);
+	    }
+	err = RProperty::Set(KUidUsbManCategory,KUsbOtgStateProperty,RUsbOtgDriver::EStateReset);
+	if ( err != KErrNone )
+	    {
+	    User::LeaveIfError(err);
+	    }
+	}
+
+/**
+ * The CUsbOtgIdPinWatcher::CUsbOtgIdPinWatcher method
+ *
+ * Constructor
+ *
+ * @param	aLdd	A reference to the USB Logical Device Driver
+ */
+
+CUsbOtgStateWatcher::CUsbOtgStateWatcher(RUsbOtgDriver& aLdd)
+	: CUsbOtgBaseWatcher(aLdd)
+	{
+	LOG_FUNC
+	iOtgState = RUsbOtgDriver::EStateReset;
+	}
+
+/**
+ * Called when the OTG State change is reported
+ */
+void CUsbOtgStateWatcher::RunL()
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8(">>CUsbOtgStateWatcher::RunL [iStatus=%d]"), iStatus.Int());
+
+	LEAVEIFERRORL(iStatus.Int());
+
+	Post();
+
+	LOGTEXT(_L8("<<CUsbOtgStateWatcher::RunL"));
+	}
+
+
+/**
+ * Automatically called when the OTG State watcher is cancelled.
+ */
+void CUsbOtgStateWatcher::DoCancel()
+	{
+	LOG_FUNC
+	iLdd.CancelOtgStateNotification();
+	}
+
+/**
+ * Sets state watcher in active state
+ */
+void CUsbOtgStateWatcher::Post()
+	{
+	LOG_FUNC
+
+	LOGTEXT(_L8("CUsbOtgStateWatcher::Post() - About to call QueueOtgStateNotification"));	
+	iLdd.QueueOtgStateNotification(iOtgState, iStatus);
+	LOGTEXT3(_L8(">>CUsbOtgStateWatcher::RunL [iStatus=%d], iOtgState = %d"), iStatus.Int(), iOtgState);
+	if (RProperty::Set(KUidUsbManCategory,KUsbOtgStateProperty,(TInt)iOtgState) != KErrNone)
+	{
+		LOGTEXT3(_L8(">>CUsbOtgStateWatcher::RunL [iStatus=%d], iOtgState = %d - failed to set the property"), iStatus.Int(), iOtgState);
+	}
+
+	SetActive();
+	}
+
+//-------------------------- OTG Events watcher class ------------------------- 
+/**
+ * The CUsbOtgEventWatcher::NewL method
+ *
+ * Constructs a new CUsbOtgEventWatcher object
+ *
+ * @internalComponent
+ * @param	aOwner		The CUsbOtg that owns the state watcher
+ * @param	aLdd		A reference to the USB Logical Device Driver
+ * @param	aOtgEvent	A reference to the OTG Event
+ *
+ * @return	A new CUsbOtgEventWatcher object
+ */
+CUsbOtgEventWatcher* CUsbOtgEventWatcher::NewL(CUsbOtg& aOwner, RUsbOtgDriver& aLdd,
+											   RUsbOtgDriver::TOtgEvent& aOtgEvent)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbOtgEventWatcher* self = new (ELeave) CUsbOtgEventWatcher(aOwner, aLdd, aOtgEvent);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+/**
+ * The CUsbOtgEventWatcher::~CUsbOtgEventWatcher method
+ *
+ * Destructor
+ *
+ * @internalComponent
+ */
+CUsbOtgEventWatcher::~CUsbOtgEventWatcher()
+	{
+	LOG_FUNC
+	Cancel();
+	}
+
+void CUsbOtgEventWatcher::ConstructL()
+/**
+ * Performs 2nd phase construction of the OTG object.
+ */
+	{
+	LOG_FUNC
+	}
+
+/**
+ * The CUsbOtgEventWatcher::CUsbOtgEventWatcher method
+ *
+ * Constructor
+ *
+ * @param	aOwner		A reference to the CUsbOtg object that owns the state watcher
+ * @param	aLdd		A reference to the USB Logical Device Driver
+ * @param	aOtgEvent	A reference to the OTG Event
+ */
+CUsbOtgEventWatcher::CUsbOtgEventWatcher(CUsbOtg& aOwner, RUsbOtgDriver& aLdd, 
+										 RUsbOtgDriver::TOtgEvent& aOtgEvent)
+	: CUsbOtgBaseWatcher(aLdd), iOwner(aOwner), iOtgEvent(aOtgEvent)
+	{
+	LOG_FUNC
+	}
+
+/**
+ * Called when the OTG Event is reported
+ */
+void CUsbOtgEventWatcher::RunL()
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8(">>CUsbOtgEventWatcher::RunL [iStatus=%d]"), iStatus.Int());
+
+	LEAVEIFERRORL(iStatus.Int());
+	LOGTEXT2(_L8("CUsbOtgEventWatcher::RunL() - Otg Event reported: %d"), (TInt)iOtgEvent);
+	if (  ( iOtgEvent == RUsbOtgDriver::EEventHnpDisabled )
+	    ||( iOtgEvent == RUsbOtgDriver::EEventHnpEnabled )
+	    ||( iOtgEvent == RUsbOtgDriver::EEventSrpInitiated )
+	    ||( iOtgEvent == RUsbOtgDriver::EEventSrpReceived )
+	    ||( iOtgEvent == RUsbOtgDriver::EEventVbusRaised )
+	    ||( iOtgEvent == RUsbOtgDriver::EEventVbusDropped )
+	   )
+		{
+		iOwner.NotifyOtgEvent();
+		LOGTEXT2(_L8("CUsbOtgEventWatcher::RunL() - The owner is notified about Otg Event = %d"), (TInt)iOtgEvent);
+		}
+	Post();
+	LOGTEXT(_L8("<<CUsbOtgEventWatcher::RunL"));
+	}
+
+#ifndef __FLOG_ACTIVE
+void CUsbOtgEventWatcher::LogEventText(RUsbOtgDriver::TOtgEvent /*aState*/)
+	{
+	}
+#else
+void CUsbOtgEventWatcher::LogEventText(RUsbOtgDriver::TOtgEvent aEvent)
+	{
+	switch (aEvent)
+		{
+		case RUsbOtgDriver::EEventAPlugInserted:
+			LOGTEXT(_L8(" ***** A-Plug Inserted *****"));
+			break;
+		case RUsbOtgDriver::EEventAPlugRemoved:
+			LOGTEXT(_L8(" ***** A-Plug Removed *****"));
+			break;
+		case RUsbOtgDriver::EEventVbusRaised:
+			LOGTEXT(_L8(" ***** VBus Raised *****"));
+			break;
+		case RUsbOtgDriver::EEventVbusDropped:
+			LOGTEXT(_L8(" ***** VBus Dropped *****"));
+			break;
+		case RUsbOtgDriver::EEventSrpInitiated:
+			LOGTEXT(_L8(" ***** SRP Initiated *****"));
+			break;
+		case RUsbOtgDriver::EEventSrpReceived:
+			LOGTEXT(_L8(" ***** SRP Received *****"));
+			break;
+		case RUsbOtgDriver::EEventHnpEnabled:
+			LOGTEXT(_L8(" ***** HNP Enabled *****"));
+			break;
+		case RUsbOtgDriver::EEventHnpDisabled:
+			LOGTEXT(_L8(" ***** HNP Disabled *****"));
+			break;
+		case RUsbOtgDriver::EEventRoleChangedToHost:
+			LOGTEXT(_L8(" ***** Role Changed to Host *****"));
+			break;
+		case RUsbOtgDriver::EEventRoleChangedToDevice:
+			LOGTEXT(_L8(" ***** Role Changed to Device *****"));
+			break;
+		case RUsbOtgDriver::EEventRoleChangedToIdle:
+			LOGTEXT(_L8(" ***** Role Changed to Idle *****"));
+			break;
+		default:
+			break;
+		}
+	}
+#endif
+
+/**
+ * Automatically called when the OTG Event watcher is cancelled.
+ */
+void CUsbOtgEventWatcher::DoCancel()
+	{
+	LOG_FUNC
+	iLdd.CancelOtgEventRequest();
+	}
+
+/**
+ * Sets state watcher in active state
+ */
+void CUsbOtgEventWatcher::Post()
+	{
+	LOG_FUNC
+
+	LOGTEXT(_L8("CUsbOtgEventWatcher::Post() - About to call QueueOtgEventRequest"));	
+	iLdd.QueueOtgEventRequest(iOtgEvent, iStatus);
+	SetActive();
+	}
+
+
+//-----------------------------------------------------------------------------
+//----------------- OTG watcher class to monitor OTG Messages ----------------- 
+//-----------------------------------------------------------------------------
+/**
+ * The CUsbOtgWatcher::NewL method
+ *
+ * Constructs a new CUsbOtgWatcher object
+ *
+ * @internalComponent
+ * @param	aOwner	A reference to the object that owns the state watcher
+ * @param	aLdd	A reference to the USB Logical Device Driver
+ *
+ * @return	A new CUsbOtgWatcher object
+ */
+CUsbOtgWatcher* CUsbOtgWatcher::NewL(MUsbOtgObserver& aOwner, RUsbOtgDriver& aLdd, TUint& aOtgMessage)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbOtgWatcher* r = new (ELeave) CUsbOtgWatcher(aOwner, aLdd, aOtgMessage);
+	return r;
+	}
+
+
+/**
+ * The CUsbOtgWatcher::~CUsbOtgWatcher method
+ *
+ * Destructor
+ *
+ * @internalComponent
+ */
+CUsbOtgWatcher::~CUsbOtgWatcher()
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8(">CUsbOtgWatcher::~CUsbOtgWatcher (0x%08x)"), (TUint32) this);
+	Cancel();
+	}
+
+
+/**
+ * The CUsbOtgWatcher::CUsbOtgWatcher method
+ *
+ * Constructor
+ *
+ * @param	aOwner	The device that owns the state watcher
+ * @param	aLdd	A reference to the USB Logical Device Driver
+ */
+CUsbOtgWatcher::CUsbOtgWatcher(MUsbOtgObserver& aOwner, RUsbOtgDriver& aLdd, TUint& aOtgMessage)
+	: CActive(CActive::EPriorityStandard), iOwner(aOwner), iLdd(aLdd), iOtgMessage(aOtgMessage)
+	{
+	LOG_FUNC
+	CActiveScheduler::Add(this);
+	}
+
+/**
+ * Called when the OTG component changes its state.
+ */
+void CUsbOtgWatcher::RunL()
+	{
+	LOG_FUNC
+	if (iStatus.Int() != KErrNone)
+		{
+		LOGTEXT2(_L8("CUsbOtgWatcher::RunL() - Error = %d"), iStatus.Int());
+		return;
+		}
+
+	LOGTEXT2(_L8("CUsbOtgWatcher::RunL() - Otg Message reported: %d"), iOtgMessage);
+	iOwner.NotifyMessage();
+
+	Post();
+	}
+
+
+/**
+ * Automatically called when the state watcher is cancelled.
+ */
+void CUsbOtgWatcher::DoCancel()
+	{
+	LOG_FUNC
+	iLdd.CancelOtgMessageRequest();
+	}
+
+
+/**
+ * Instructs the state watcher to start watching.
+ */
+void CUsbOtgWatcher::Start()
+	{
+	LOG_FUNC
+	Post();
+	}
+
+/**
+ * Sets state watcher in active state
+ */
+void CUsbOtgWatcher::Post()
+	{
+	LOG_FUNC
+
+	LOGTEXT(_L8("CUsbOtgWatcher::Post() - About to call QueueOtgMessageRequest"));
+	iLdd.QueueOtgMessageRequest((RUsbOtgDriver::TOtgMessage&)iOtgMessage, iStatus);
+	SetActive();
+	}
+
+
+
+
+//-----------------------------------------------------------------------------
+//------ A watcher class to monitor the P&S property for VBus marshalling ----- 
+//-----------------------------------------------------------------------------
+
+CRequestSessionWatcher* CRequestSessionWatcher::NewL(MUsbOtgObserver& aOwner)
+	{
+	CRequestSessionWatcher* self = new(ELeave) CRequestSessionWatcher(aOwner);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CRequestSessionWatcher::~CRequestSessionWatcher()
+	{
+	Cancel();
+	iProp.Close();
+	}
+
+void CRequestSessionWatcher::ConstructL()
+/**
+ * Performs 2nd phase construction of the OTG object.
+ */
+	{
+	LOG_FUNC
+
+	TInt err = RProperty::Define(KUsbRequestSessionProperty, RProperty::EInt, KAllowAllPolicy, KRequestSessionPolicy);
+	if ( err != KErrNone && err != KErrAlreadyExists )
+	    {
+	    User::LeaveIfError(err);
+	    }
+	err = RProperty::Set(KUidUsbManCategory,KUsbRequestSessionProperty,0);
+	if ( err != KErrNone )
+	    {
+	    User::LeaveIfError(err);
+	    }
+	User::LeaveIfError(iProp.Attach(KUidUsbManCategory, KUsbRequestSessionProperty));
+	iProp.Subscribe(iStatus);
+	SetActive();
+	}
+
+CRequestSessionWatcher::CRequestSessionWatcher(MUsbOtgObserver& aOwner)
+	: CActive(CActive::EPriorityStandard), iOwner(aOwner)
+	{
+	LOG_FUNC
+	CActiveScheduler::Add(this);
+	}
+
+/**
+ * Called when the OTG Event is reported
+ */
+void CRequestSessionWatcher::RunL()
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8(">>CRequestSessionWatcher::RunL [iStatus=%d]"), iStatus.Int());
+	RDebug::Printf(">>CRequestSessionWatcher::RunL [iStatus=%d]", iStatus.Int());
+	
+	iProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iProp.Get(val));
+	RDebug::Printf(">>value=%d", val);
+
+	iOwner.NotifyMessage(KUsbMessageRequestSession);
+	
+	LOGTEXT(_L8("<<CRequestSessionWatcher::RunL"));
+	}
+
+
+/**
+ * Automatically called when the OTG Event watcher is cancelled.
+ */
+void CRequestSessionWatcher::DoCancel()
+	{
+	LOG_FUNC
+	iProp.Cancel();
+	}
+
+//---------------------------- Connection Idle watcher class --------------------------- 
+/**
+ * The CUsbOtgConnectionIdleWatcher::NewL method
+ *
+ * Constructs a new CUsbOtgWatcher object
+ *
+ * @internalComponent
+ * @param	aLdd	A reference to the USB Logical Device Driver
+ *
+ * @return	A new CUsbOtgWatcher object
+ */
+CUsbOtgConnectionIdleWatcher* CUsbOtgConnectionIdleWatcher::NewL(RUsbOtgDriver& aLdd)
+	{
+	LOG_STATIC_FUNC_ENTRY
+
+	CUsbOtgConnectionIdleWatcher* self = new (ELeave) CUsbOtgConnectionIdleWatcher(aLdd);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+/**
+ * The CUsbOtgConnectionIdleWatcher::~CUsbOtgConnectionIdleWatcher method
+ *
+ * Destructor
+ *
+ * @internalComponent
+ */
+CUsbOtgConnectionIdleWatcher::~CUsbOtgConnectionIdleWatcher()
+	{
+	LOG_FUNC
+	Cancel();
+	RProperty::Delete(KUsbOtgConnectionIdleProperty);
+	}
+
+/**
+ * Performs 2nd phase construction of the OTG object.
+ */
+void CUsbOtgConnectionIdleWatcher::ConstructL()
+	{
+	LOG_FUNC
+
+	TInt err = RProperty::Define(KUsbOtgConnectionIdleProperty, RProperty::EInt, KAllowAllPolicy, KNetworkControlPolicy);
+	if ( err != KErrNone && err != KErrAlreadyExists )
+	    {
+	    User::LeaveIfError(err);
+	    }
+	err = RProperty::Set(KUidUsbManCategory,KUsbOtgConnectionIdleProperty,ETrue);
+	if ( err != KErrNone )
+	    {
+	    User::LeaveIfError(err);
+	    }
+	}
+
+/**
+ * The CUsbOtgConnectionIdleWatcher::CUsbOtgConnectionIdleWatcher method
+ *
+ * Constructor
+ *
+ * @param	aLdd	A reference to the USB Logical Device Driver
+ */
+
+CUsbOtgConnectionIdleWatcher::CUsbOtgConnectionIdleWatcher(RUsbOtgDriver& aLdd)
+	: CUsbOtgBaseWatcher(aLdd)
+	{
+	LOG_FUNC
+	}
+
+/**
+ * Called when the Connection Idle status change is reported
+ */
+void CUsbOtgConnectionIdleWatcher::RunL()
+	{
+	LOG_FUNC
+	LOGTEXT2(_L8(">>CUsbOtgConnectionIdleWatcher::RunL [iStatus=%d]"), iStatus.Int());
+
+	LEAVEIFERRORL(iStatus.Int());
+	
+	Post();
+
+	LOGTEXT(_L8("<<CUsbOtgConnectionIdleWatcher::RunL"));
+	}
+
+
+/**
+ * Automatically called when the Connection Idle watcher is cancelled.
+ */
+void CUsbOtgConnectionIdleWatcher::DoCancel()
+	{
+	LOG_FUNC
+	iLdd.CancelOtgConnectionNotification();
+	}
+
+/**
+ * Sets state watcher in active state
+ */
+void CUsbOtgConnectionIdleWatcher::Post()
+	{
+	LOG_FUNC
+
+	LOGTEXT(_L8("CUsbOtgConnectionIdleWatcher::Post() - About to call QueueOtgIdPinNotification"));
+	iLdd.QueueOtgConnectionNotification(iConnectionIdle, iStatus);
+	switch (iConnectionIdle)
+		{
+		case RUsbOtgDriver::EConnectionIdle:
+		case RUsbOtgDriver::EConnectionUnknown:
+			RProperty::Set(KUidUsbManCategory,KUsbOtgConnectionIdleProperty,ETrue);
+			LOGTEXT2(_L8(">>CUsbOtgConnectionIdleWatcher::Post [iConnectionIdle=%d] - property is set to 1"), iConnectionIdle);
+			break;
+		case RUsbOtgDriver::EConnectionBusy:
+			RProperty::Set(KUidUsbManCategory,KUsbOtgConnectionIdleProperty,EFalse);
+			LOGTEXT2(_L8(">>CUsbOtgConnectionIdleWatcher::Post [iConnectionIdle=%d] - property is set to 0"), iConnectionIdle);
+			break;
+		default:
+			LOGTEXT2(_L8(">>CUsbOtgConnectionIdleWatcher::Post [iConnectionIdle=%d] is unrecognized, re-request QueueOtgIdPinNotification"), iConnectionIdle);
+			break;
+		}
+	SetActive();
+	}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/usbman.rls	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* 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 "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
+* This file serves a template for the purpose of localization. The
+* content of this file shall be properly filled with unicode pertaining
+* to the configured language.
+* localized strings, US english
+*
+*/
+
+// personality one
+rls_string per_manufacturer1	"localized manufacturer"
+rls_string per_product1		"localized product description"
+rls_string per_description1	"localized personality description"
+rls_string per_detailedDescription1	"localized personality detailed description"
+
+// personality two
+rls_string per_manufacturer2	"localized manufacturer"
+rls_string per_product2		"localized product description"
+rls_string per_description2	"localized personality description"
+rls_string per_detailedDescription2	"localized personality detailed description"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/usbman.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,112 @@
+/*
+* 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 "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:
+* Resource file for usbman configuration.
+*
+*/
+
+/**
+ @file
+*/
+
+NAME USBM
+
+#include <badef.rh>
+#include "usbman.rh"
+
+#ifdef LANGUAGE_01 			// UK English  
+ 	#include "usbman_01.rls"	
+#elif LANGUAGE_02 	 		// French  
+ 	#include "usbman_02.rls"	
+#elif defined LANGUAGE_03  		// German
+ 	#include "usbman_03.rls"
+#elif defined LANGUAGE_10  		// US English
+ 	#include "usbman_10.rls"
+#else					// default to UK English strings in usbman.rsc
+ 	#include "usbman_01.rls"	
+#endif      
+
+RESOURCE BA_RSS_SIGNATURE
+	{
+	signature = 3;
+	}
+
+RESOURCE usb_configuration usb_config
+	{
+	}
+	
+		
+RESOURCE PERSONALITY_ARRAY device_personalities
+	{
+	personalities = 
+		{
+		PERSONALITY
+			{
+			bDeviceClass = 02;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x000b;
+			bcdDevice = 0;
+			manufacturer = per_manufacturer1;
+			product = per_product1;
+			id = 1;					
+			class_uids = "101FBF22";    			
+			description = per_description1;
+			detailedDescription = per_detailedDescription1;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 1;
+			bDeviceSubClass = 2;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x000c;
+			bcdDevice = 2;
+			manufacturer= per_manufacturer2;
+			product = per_product2;
+			id = 2;					
+			class_uids = "101fbf24";			
+			description = per_description2;
+			detailedDescription = per_detailedDescription2;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 0;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x1113;
+			bcdDevice = 0;
+			manufacturer = per_manufacturer3;
+			product = per_product3;
+			id = 3;					
+			class_uids = "10204bbc";			
+			description = per_description3;
+			detailedDescription = per_detailedDescription3;
+			property = 0x00000000;
+			}
+
+		// The productId's value of personalities to be implemented in the
+		// future should be > 0x1115, to avoid conflict with IDs used by
+		// other drivers or applications
+
+		};
+	}
+			
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/usbman_01.rls	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,50 @@
+/*
+* 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 "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
+* Resource file for testing and example mass storage application
+* localized strings for UK English. A place holder only. The actual
+* strings however may not be UK English at all.
+*
+*/
+
+// personality one
+rls_string per_manufacturer1 	"Symbian"
+rls_string per_product1		"Symbian OS ACM"
+rls_string per_description1 	"Serial Emulation"
+rls_string per_detailedDescription1    	"Serial Emulation(detail)"
+
+// personality two
+rls_string per_manufacturer2 	"Symbian"
+rls_string per_product2		"Symbian OS WHCM"
+rls_string per_description2 	"Obex over USB"
+rls_string per_detailedDescription2    	"Obex over USB(detail)"
+
+// personality three
+rls_string per_manufacturer3 	"Symbian"
+rls_string per_product3		"Symbian OS MSCC"
+rls_string per_description3 	"USB Mass Storage"
+rls_string per_detailedDescription3    	"USB Mass Storage(detail)"
+
+// personality four
+rls_string per_manufacturer4 	"Symbian"
+rls_string per_product4		"Symbian OS MTP"
+rls_string per_description4 	"MTP over USB"
+rls_string per_detailedDescription4    	"MTP over USB(detail)"
+
+// personality five
+rls_string per_manufacturer5 	"Symbian"
+rls_string per_product5		"Symbian OS RNDIS"
+rls_string per_description5 	"IP over USB - RNDIS"
+rls_string per_detailedDescription5    	"IP over USB - RNDIS(detail)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/usbman_02.rls	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,54 @@
+/*
+* 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 "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
+* This file serves a template for the purpose of localization. The
+* content of this file shall be properly filled with unicode pertaining
+* to the configured language.
+* localized strings for French. A place holder only. you know the 
+* following strings are not French
+*
+*/
+
+
+// personality one
+rls_string per_manufacturer1 	"Symbian"
+rls_string per_product1		"Symbian OS ACM"
+rls_string per_description1 	"Serial Emulation"
+rls_string per_detailedDescription1    	"Serial Emulation(detail)"
+
+// personality two
+rls_string per_manufacturer2 	"Symbian"
+rls_string per_product2		"Symbian OS WHCM"
+rls_string per_description2 	"Obex over USB"
+rls_string per_detailedDescription2     	"Obex over USB(detail)"
+
+// personality three
+rls_string per_manufacturer3 	"Symbian"
+rls_string per_product3		"Symbian OS MSCC"
+rls_string per_description3 	"USB Mass Storage"
+rls_string per_detailedDescription3   	"USB Mass Storage(detail)"
+
+// personality four
+rls_string per_manufacturer4 	"Symbian"
+rls_string per_product4		"Symbian OS MTP"
+rls_string per_description4 	"MTP over USB"
+rls_string per_detailedDescription4    	"MTP over USB(detail)"
+
+// personality five
+rls_string per_manufacturer5 	"Symbian"
+rls_string per_product5		"Symbian OS RNDIS"
+rls_string per_description5 	"IP over USB - RNDIS"
+rls_string per_detailedDescription5    	"IP over USB - RNDIS(detail)"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/usbman_03.rls	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,54 @@
+/*
+* 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 "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
+* This file serves a template for the purpose of localization. The
+* content of this file shall be properly filled with unicode pertaining
+* to the configured language.
+* localized strings for German. A place holder only. you know the 
+* following strings are not German
+*
+*/
+
+
+// personality one
+// personality one
+rls_string per_manufacturer1 	"Symbian"
+rls_string per_product1		"Symbian OS ACM"
+rls_string per_description1 	"Serial Emulation"
+rls_string per_detailedDescription1    	"Serial Emulation(detail)"
+
+// personality two
+rls_string per_manufacturer2 	"Symbian"
+rls_string per_product2		"Symbian OS WHCM"
+rls_string per_description2 	"Obex over USB"
+rls_string per_detailedDescription2     	"Obex over USB(detail)"
+
+// personality three
+rls_string per_manufacturer3 	"Symbian"
+rls_string per_product3		"Symbian OS MSCC"
+rls_string per_description3 	"USB Mass Storage"
+rls_string per_detailedDescription3    	"USB Mass Storage(detail)"
+
+// personality four
+rls_string per_manufacturer4 	"Symbian"
+rls_string per_product4		"Symbian OS MTP"
+rls_string per_description4 	"MTP over USB"
+rls_string per_detailedDescription4    	"MTP over USB(detail)"
+
+// personality five
+rls_string per_manufacturer5 	"Symbian"
+rls_string per_product5		"Symbian OS RNDIS"
+rls_string per_description5 	"IP over USB - RNDIS"
+rls_string per_detailedDescription5    	"IP over USB - RNDIS(detail)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/usbman_10.rls	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,52 @@
+/*
+* 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 "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
+* This file serves a template for the purpose of localization. The
+* content of this file shall be properly filled with unicode pertaining
+* to the configured language.
+* localized strings, US english
+*
+*/
+
+
+// personality one
+rls_string per_manufacturer1 	"Symbian"
+rls_string per_product1		"Symbian OS ACM"
+rls_string per_description1 	"Serial Emulation"
+rls_string per_detailedDescription1    	"Serial Emulation(detail)"
+
+// personality two
+rls_string per_manufacturer2 	"Symbian"
+rls_string per_product2		"Symbian OS WHCM"
+rls_string per_description2 	"Obex over USB"
+rls_string per_detailedDescription2     	"Obex over USB(detail)"
+
+// personality three
+rls_string per_manufacturer3 	"Symbian"
+rls_string per_product3		"Symbian OS MSCC"
+rls_string per_description3 	"USB Mass Storage"
+rls_string per_detailedDescription3    	"USB Mass Storage(detail)"
+
+// personality four
+rls_string per_manufacturer4 	"Symbian"
+rls_string per_product4		"Symbian OS MTP"
+rls_string per_description4 	"MTP over USB"
+rls_string per_detailedDescription4    	"MTP over USB(detail)"
+
+// personality five
+rls_string per_manufacturer5 	"Symbian"
+rls_string per_product5		"Symbian OS RNDIS"
+rls_string per_description5 	"IP over USB - RNDIS"
+rls_string per_detailedDescription5   	"IP over USB - RNDIS(detail)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/usbmanlubbockobex.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,108 @@
+/*
+* 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 "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:
+* Resource file for usbman configuration.
+*
+*/
+
+/**
+ @file
+*/
+
+NAME USBM
+
+#include <badef.rh>
+#include "usbman.rh"
+#ifdef LANGUAGE_01 			// UK English  
+ 	#include "usbman_01.rls"	
+#elif LANGUAGE_02 	 		// French  
+ 	#include "usbman_02.rls"	
+#elif defined LANGUAGE_03  		// German
+ 	#include "usbman_03.rls"
+#elif defined LANGUAGE_10  		// US English
+ 	#include "usbman_10.rls"
+#else					// default to UK English strings in usbman.rsc
+ 	#include "usbman_01.rls"	
+#endif      
+
+RESOURCE BA_RSS_SIGNATURE
+	{
+	signature = 3;
+	}
+
+RESOURCE usb_configuration usb_config
+	{
+	}
+	
+		
+RESOURCE PERSONALITY_ARRAY device_personalities
+	{
+	personalities = 
+		{
+		PERSONALITY
+			{
+			bDeviceClass = 02;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x000b;
+			bcdDevice = 0;
+			manufacturer = per_manufacturer1;
+			product = per_product1;
+			id = 1;					
+			class_uids = "101FBF22";    			
+			description = per_description1;
+            		detailedDescription = per_detailedDescription1;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 1;
+			bDeviceSubClass = 2;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x000d;             // instead of 0x000c
+			bcdDevice = 2;
+			manufacturer= per_manufacturer2;
+			product = per_product2;
+			id = 2;					
+			class_uids = "101fbf24";			
+			description = per_description2;
+            		detailedDescription = per_detailedDescription2;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 0;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x1111;
+			bcdDevice = 0;
+			manufacturer = per_manufacturer3;
+			product = per_product3;
+			id = 3;					
+			class_uids = "10204bbc";			
+			description = per_description3;
+            		detailedDescription = per_detailedDescription3;
+			property = 0x00000000;
+			}
+
+		};
+	}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/usbmanmtp.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,129 @@
+/*
+* 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 "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:
+* Resource file for usbman configuration.
+*
+*/
+
+/**
+ @file
+*/
+
+NAME USBM
+
+#include <badef.rh>
+#include "usbman.rh"
+
+#ifdef LANGUAGE_01 			// UK English  
+ 	#include "usbman_01.rls"	
+#elif LANGUAGE_02 	 		// French  
+ 	#include "usbman_02.rls"	
+#elif defined LANGUAGE_03  		// German
+ 	#include "usbman_03.rls"
+#elif defined LANGUAGE_10  		// US English
+ 	#include "usbman_10.rls"
+#else					// default to UK English strings in usbman.rsc
+ 	#include "usbman_01.rls"	
+#endif      
+
+RESOURCE BA_RSS_SIGNATURE
+	{
+	signature = 3;
+	}
+
+RESOURCE usb_configuration usb_config
+	{
+	}
+	
+		
+RESOURCE PERSONALITY_ARRAY device_personalities
+	{
+	personalities = 
+		{
+		PERSONALITY
+			{
+			bDeviceClass = 02;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x000b;
+			bcdDevice = 0;
+			manufacturer = per_manufacturer1;
+			product = per_product1;
+			id = 1;					
+			class_uids = "101FBF22";    			
+			description = per_description1;
+			detailedDescription = per_detailedDescription1;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 1;
+			bDeviceSubClass = 2;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x000c;
+			bcdDevice = 2;
+			manufacturer= per_manufacturer2;
+			product = per_product2;
+			id = 2;					
+			class_uids = "101fbf24";			
+			description = per_description2;
+			detailedDescription = per_detailedDescription2;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 0;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x1113;
+			bcdDevice = 0;
+			manufacturer = per_manufacturer3;
+			product = per_product3;
+			id = 3;					
+			class_uids = "10204bbc";			
+			description = per_description3;
+			detailedDescription = per_detailedDescription3;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 0x00;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x1114;
+			bcdDevice = 0x0100;
+			manufacturer = per_manufacturer4;
+			product = per_product4;
+			id = 4;					
+			class_uids = "102827B3";			
+			description = per_description4;
+			detailedDescription = per_detailedDescription4;
+			property = 0x00000000;
+			}
+
+		// The productId's value of personalities to be implemented in the
+		// future should be > 0x1115, to avoid conflict with IDs used by
+		// other drivers or applications
+
+		};
+	}
+			
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/usbmanmtprndis.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,146 @@
+/*
+* 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 "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:
+* Resource file for usbman configuration.
+*
+*/
+
+/** 
+@file
+ */
+
+NAME USBM
+
+#include <badef.rh>
+#include "usbman.rh"
+
+#ifdef LANGUAGE_01 			// UK English  
+ 	#include "usbman_01.rls"	
+#elif LANGUAGE_02 	 		// French  
+ 	#include "usbman_02.rls"	
+#elif defined LANGUAGE_03  		// German
+ 	#include "usbman_03.rls"
+#elif defined LANGUAGE_10  		// US English
+ 	#include "usbman_10.rls"
+#else					// default to UK English strings in usbman.rsc
+ 	#include "usbman_01.rls"	
+#endif      
+
+RESOURCE BA_RSS_SIGNATURE
+	{
+	signature = 3;
+	}
+
+RESOURCE usb_configuration usb_config
+	{
+	}
+	
+		
+RESOURCE PERSONALITY_ARRAY device_personalities
+	{
+	personalities = 
+		{
+		PERSONALITY
+			{
+			bDeviceClass = 02;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x000b;
+			bcdDevice = 0;
+			manufacturer = per_manufacturer1;
+			product = per_product1;
+			id = 1;					
+			class_uids = "101FBF22";    			
+			description = per_description1;
+			detailedDescription = per_detailedDescription1;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 1;
+			bDeviceSubClass = 2;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x000c;
+			bcdDevice = 2;
+			manufacturer= per_manufacturer2;
+			product = per_product2;
+			id = 2;					
+			class_uids = "101fbf24";			
+			description = per_description2;
+			detailedDescription = per_detailedDescription2;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 0;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x1113;
+			bcdDevice = 0;
+			manufacturer = per_manufacturer3;
+			product = per_product3;
+			id = 3;					
+			class_uids = "10204bbc";			
+			description = per_description3;
+			detailedDescription = per_detailedDescription3;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 0x00;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x1114;
+			bcdDevice = 0x0100;
+			manufacturer = per_manufacturer4;
+			product = per_product4;
+			id = 4;					
+			class_uids = "102827B3";			
+			description = per_description4;
+			detailedDescription = per_detailedDescription4;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 0x02;
+			bDeviceSubClass = 0x00;
+			protocol = 0x00;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x1115;
+			bcdDevice = 0x0100;
+			manufacturer = per_manufacturer5;
+			product =  per_product5;
+			id = 5;					
+			class_uids = "20013d2f";			
+			description = per_description5;
+			detailedDescription = per_detailedDescription5;
+			property = 0x00000000;
+			}			
+
+		// The productId's value of personalities to be implemented in the
+		// future should be > 0x1115, to avoid conflict with IDs used by
+		// other drivers or applications
+
+		};
+	}
+			
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/SRC/usbmanrndis.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,129 @@
+/*
+* 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 "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:
+* Resource file for usbman configuration.
+*
+*/
+
+/** 
+@file
+ */
+
+NAME USBM
+
+#include <badef.rh>
+#include "usbman.rh"
+
+#ifdef LANGUAGE_01 			// UK English  
+ 	#include "usbman_01.rls"	
+#elif LANGUAGE_02 	 		// French  
+ 	#include "usbman_02.rls"	
+#elif defined LANGUAGE_03  		// German
+ 	#include "usbman_03.rls"
+#elif defined LANGUAGE_10  		// US English
+ 	#include "usbman_10.rls"
+#else					// default to UK English strings in usbman.rsc
+ 	#include "usbman_01.rls"	
+#endif      
+
+RESOURCE BA_RSS_SIGNATURE
+	{
+	signature = 3;
+	}
+
+RESOURCE usb_configuration usb_config
+	{
+	}
+	
+		
+RESOURCE PERSONALITY_ARRAY device_personalities
+	{
+	personalities = 
+		{
+		PERSONALITY
+			{
+			bDeviceClass = 02;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x000b;
+			bcdDevice = 0;
+			manufacturer = per_manufacturer1;
+			product = per_product1;
+			id = 1;					
+			class_uids = "101FBF22";    			
+			description = per_description1;
+			detailedDescription = per_detailedDescription1;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 1;
+			bDeviceSubClass = 2;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x000c;
+			bcdDevice = 2;
+			manufacturer= per_manufacturer2;
+			product = per_product2;
+			id = 2;					
+			class_uids = "101fbf24";			
+			description = per_description2;
+			detailedDescription = per_detailedDescription2;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 0;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x1113;
+			bcdDevice = 0;
+			manufacturer = per_manufacturer3;
+			product = per_product3;
+			id = 3;					
+			class_uids = "10204bbc";			
+			description = per_description3;
+			detailedDescription = per_detailedDescription3;
+			property = 0x00000000;
+			},
+		PERSONALITY
+			{
+			bDeviceClass = 0x02;
+			bDeviceSubClass = 0x00;
+			protocol = 0x00;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x1115;
+			bcdDevice = 0x0100;
+			manufacturer = per_manufacturer5;
+			product =  per_product5;
+			id = 4;					
+			class_uids = "20013d2f";			
+			description = per_description5;
+			detailedDescription = per_detailedDescription5;
+			property = 0x00000000;
+			}
+
+		// The productId's value of personalities to be implemented in the
+		// future should be > 0x1115, to avoid conflict with IDs used by
+		// other drivers or applications
+
+		};
+	}
+			
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/AsyncStart.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,46 @@
+; Copyright (c) 2003-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:
+; Ini file for USBMAN dummy class controller.
+; Specifies behaviour for up to three instances of the dummy class 
+; controller. Instance 0 Starts asynchronously in 1s.
+; 
+;
+
+[Startup.0]
+Type= async
+Time= 1000000
+Error= 0
+[Shutdown.0]
+Type= sync
+Time= 0
+Error= 0
+
+[Startup.1]
+Type= sync
+Time= 0
+Error= 0
+[Shutdown.1]
+Type= sync
+Time= 0
+Error= 0
+
+[Startup.2]
+Type= sync
+Time= 0
+Error= 0
+[Shutdown.2]
+Type= sync
+Time= 0
+Error= 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/AsyncStop.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,46 @@
+; Copyright (c) 2003-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:
+; Ini file for USBMAN dummy class controller.
+; Specifies behaviour for up to three instances of the dummy class 
+; controller. Instance 0 Stops asynchronously in 1s.
+; 
+;
+
+[Startup.0]
+Type= sync
+Time= 0
+Error= 0
+[Shutdown.0]
+Type= async
+Time= 1000000
+Error= 0
+
+[Startup.1]
+Type= sync
+Time= 0
+Error= 0
+[Shutdown.1]
+Type= sync
+Time= 0
+Error= 0
+
+[Startup.2]
+Type= sync
+Time= 0
+Error= 0
+[Shutdown.2]
+Type= sync
+Time= 0
+Error= 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/BadStart0CI.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+; Copyright (c) 2003-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:
+; Ini file for USBMAN dummy class controller.
+; Specifies behaviour for up to three instances of the dummy class 
+; controller. Instance 0 completes Start with KErrServerTerminated 
+; (mimics a Class Implementation panicking).
+; 
+;
+
+[Startup.0]
+Type= async
+Time= 0
+Error= -15
+[Shutdown.0]
+Type= async
+Time= 0
+Error= 0
+
+[Startup.1]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.1]
+Type= async
+Time= 0
+Error= 0
+
+[Startup.2]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.2]
+Type= async
+Time= 0
+Error= 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/BadStart1CI.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+; Copyright (c) 2003-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:
+; Ini file for USBMAN dummy class controller.
+; Specifies behaviour for up to three instances of the dummy class 
+; controller. Instance 1 completes Start with KErrServerTerminated 
+; (mimics a Class Implementation panicking).
+; 
+;
+
+[Startup.0]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.0]
+Type= async
+Time= 0
+Error= 0
+
+[Startup.1]
+Type= async
+Time= 0
+Error= -15
+[Shutdown.1]
+Type= async
+Time= 0
+Error= 0
+
+[Startup.2]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.2]
+Type= async
+Time= 0
+Error= 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/BadStart2CI.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+; Copyright (c) 2003-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:
+; Ini file for USBMAN dummy class controller.
+; Specifies behaviour for up to three instances of the dummy class 
+; controller. Instance 2 completes Start with KErrServerTerminated 
+; (mimics a Class Implementation panicking).
+; 
+;
+
+[Startup.0]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.0]
+Type= async
+Time= 0
+Error= 0
+
+[Startup.1]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.1]
+Type= async
+Time= 0
+Error= 0
+
+[Startup.2]
+Type= async
+Time= 0
+Error= -15
+[Shutdown.2]
+Type= async
+Time= 0
+Error= 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/BadStop0CI.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+; Copyright (c) 2003-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:
+; Ini file for USBMAN dummy class controller.
+; Specifies behaviour for up to three instances of the dummy class 
+; controller. Instance 0 completes Stop with KErrServerTerminated 
+; (mimics a Class Implementation panicking).
+; 
+;
+
+[Startup.0]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.0]
+Type= async
+Time= 0
+Error= -15
+
+[Startup.1]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.1]
+Type= async
+Time= 0
+Error= 0
+
+[Startup.2]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.2]
+Type= async
+Time= 0
+Error= 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/BadStop1CI.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+; Copyright (c) 2003-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:
+; Ini file for USBMAN dummy class controller.
+; Specifies behaviour for up to three instances of the dummy class 
+; controller. Instance 1 completes Stop with KErrServerTerminated 
+; (mimics a Class Implementation panicking).
+; 
+;
+
+[Startup.0]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.0]
+Type= async
+Time= 0
+Error= 0
+
+[Startup.1]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.1]
+Type= async
+Time= 0
+Error= -15
+
+[Startup.2]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.2]
+Type= async
+Time= 0
+Error= 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/BadStop2CI.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+; Copyright (c) 2003-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:
+; Ini file for USBMAN dummy class controller.
+; Specifies behaviour for up to three instances of the dummy class 
+; controller. Instance 2 completes Stop with KErrServerTerminated 
+; (mimics a Class Implementation panicking).
+; 
+;
+
+[Startup.0]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.0]
+Type= async
+Time= 0
+Error= 0
+
+[Startup.1]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.1]
+Type= async
+Time= 0
+Error= 0
+
+[Startup.2]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.2]
+Type= async
+Time= 0
+Error= -15
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/SyncStart.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,46 @@
+; Copyright (c) 2003-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:
+; Ini file for USBMAN dummy class controller.
+; Specifies behaviour for up to three instances of the dummy class 
+; controller. Instance 0 Starts synchronously in 1s.
+; 
+;
+
+[Startup.0]
+Type= sync
+Time= 1000000
+Error= 0
+[Shutdown.0]
+Type= sync
+Time= 0
+Error= 0
+
+[Startup.1]
+Type= sync
+Time= 0
+Error= 0
+[Shutdown.1]
+Type= sync
+Time= 0
+Error= 0
+
+[Startup.2]
+Type= sync
+Time= 0
+Error= 0
+[Shutdown.2]
+Type= sync
+Time= 0
+Error= 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/SyncStop.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,46 @@
+; Copyright (c) 2003-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:
+; Ini file for USBMAN dummy class controller.
+; Specifies behaviour for up to three instances of the dummy class 
+; controller. Instance 0 Stops synchronously in 1s.
+; 
+;
+
+[Startup.0]
+Type= sync
+Time= 0
+Error= 0
+[Shutdown.0]
+Type= sync
+Time= 1000000
+Error= 0
+
+[Startup.1]
+Type= sync
+Time= 0
+Error= 0
+[Shutdown.1]
+Type= sync
+Time= 0
+Error= 0
+
+[Startup.2]
+Type= sync
+Time= 0
+Error= 0
+[Shutdown.2]
+Type= sync
+Time= 0
+Error= 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/demo_mcci_usbman.rh	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+/*
+* 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 "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:
+* Resource header for usbman configuration.
+* this file can be renamed usbman.rh and pasted to ser-comms\usb\usbman\inc
+*
+*/
+
+STRUCT usb_configuration
+	{
+	WORD	vendorId		= 0x040E;	//values matching demo mcci inf files on PC
+	WORD	productId		= 0xF10F;	// use those to have the symbian device using mcci drivers
+	WORD	bcdDevice		= 0x0000;
+	LTEXT	manufacturer	= "Symbian Ltd.";
+	LTEXT	product			= "Symbian OS";
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/nice.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,46 @@
+; Copyright (c) 2003-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:
+; Ini file for USBMAN dummy class controller.
+; Allows up to three instances of the dummy class controller to start up 
+; and shut down with no error, asynchronously, with no extra delay.
+; 
+;
+
+[Startup.0]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.0]
+Type= async
+Time= 0
+Error= 0
+
+[Startup.1]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.1]
+Type= async
+Time= 0
+Error= 0
+
+[Startup.2]
+Type= async
+Time= 0
+Error= 0
+[Shutdown.2]
+Type= async
+Time= 0
+Error= 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/data/test.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,46 @@
+; Copyright (c) 2003-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:
+; Ini file for USBMAN dummy class controller.
+; Specifies behaviour for up to three instances of the dummy class 
+; controller. Each instance Starts and Stops asynchronously with no 
+; error, taking 1s in each case.
+; 
+;
+
+[Startup.0]
+Type= async
+Time= 1000000
+Error= 0
+[Shutdown.0]
+Type= async
+Time= 1000000
+Error= 0
+
+[Startup.1]
+Type= async
+Time= 1000000
+Error= 0
+[Shutdown.1]
+Type= async
+Time= 1000000
+Error= 0
+
+[Startup.2]
+Type= async
+Time= 1000000
+Error= 0
+[Shutdown.2]
+Type= async
+Time= 1000000
+Error= 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2003-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:
+*
+*/
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+../public/Usb_std.h						SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb_std.h)
+../public/MUsbDeviceNotify.h			SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(musbdevicenotify.h)
+../public/usbman.rh						/epoc32/include/usbman.rh
+../public/usberrors.h					SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usberrors.h)
+../public/UsbClassUids.h				SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usbclassuids.h)
+../public/usbshared.h					SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/usbshared.h)
+../public/usbotgdefs.h					SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usbotgdefs.h)
+../public/usbhostdefs.h					SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usbhostdefs.h)
+./backup_registration.xml  			/epoc32/data/z/private/101fe1db/backup_registration.xml
+
+PRJ_TESTEXPORTS
+
+// IBY and INI files for Dummy Class Controller Tests (t_usbman_dummycc)
+dummyCCinifiles.iby    /epoc32/rom/include/dummyccinifiles.iby
+../data/BadStart0CI.ini		/epoc32/data/z/private/101fe1db/data/badstart0ci.ini
+../data/BadStart1CI.ini		/epoc32/data/z/private/101fe1db/data/badstart1ci.ini
+../data/BadStart2CI.ini		/epoc32/data/z/private/101fe1db/data/badstart2ci.ini
+../data/BadStop0CI.ini		/epoc32/data/z/private/101fe1db/data/badstop0ci.ini
+../data/BadStop1CI.ini		/epoc32/data/z/private/101fe1db/data/badstop1ci.ini
+../data/BadStop2CI.ini		/epoc32/data/z/private/101fe1db/data/badstop2ci.ini
+../data/nice.ini			/epoc32/data/z/private/101fe1db/data/nice.ini
+../data/test.ini			/epoc32/data/z/private/101fe1db/data/test.ini
+../data/SyncStart.ini		/epoc32/data/z/private/101fe1db/data/syncstart.ini
+../data/SyncStop.ini		/epoc32/data/z/private/101fe1db/data/syncstop.ini
+../data/AsyncStart.ini		/epoc32/data/z/private/101fe1db/data/asyncstart.ini
+../data/AsyncStop.ini		/epoc32/data/z/private/101fe1db/data/asyncstop.ini
+
+../public/rusb.h						SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/rusb.h)
+../public/UsbmanInternalConstants.h		SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/usbmaninternalconstants.h)
+
+PRJ_MMPFILES
+
+Usbsvr.mmp
+
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST) && !defined(WINS) && !defined(X86GCC)
+usbsvrotg.mmp
+#endif
+
+PRJ_TESTMMPFILES
+
+// Special USBSVR with no class controllers except 3 instances of the dummy 
+// class controller, for GT171 tests.
+t_Usbman_dummyCC.mmp
+
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST)
+
+// exe built from usbsvrotg_dummyusbdi.mmp (below) has dependency on usbhoststack_over_dummyusbdi.lib
+#include "../../../host/fdf/production/client/group/usbhoststack_over_dummyusbdi_bld.inf"
+
+// Special USBSVR with no OTGDI part and over DUMMY USBDI
+usbsvrotg_dummyusbdi.mmp
+
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/group/Usbsvr.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2003-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:
+* usbsvr.exe USB server
+*
+*/
+
+/**
+ @file
+*/
+
+target usbsvr.exe
+
+#include "usbsvrbase.mmp"
+//
+// End of file
+
+UNPAGED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/group/backup_registration.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,23 @@
+<?xml version="1.0" standalone="yes"?>
+<!--
+ 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:
+
+-->
+
+<!-- The main backup registration file-->
+<backup_registration> 
+	<passive_backup>
+	</passive_backup>
+</backup_registration> 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/group/dummyCCinifiles.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 2003-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:
+* Ini files which determine dummy class controller behaviour.
+*
+*/
+
+#ifndef __DUMMYCCINIFILES_IBY__
+#define __DUMMYCCINIFILES_IBY__
+
+
+data=ZPRIVATE\101fe1db\data\BadStart0CI.ini    	private\101fe1db\data\BadStart0CI.ini
+data=ZPRIVATE\101fe1db\data\BadStart1CI.ini    	private\101fe1db\data\BadStart1CI.ini
+data=ZPRIVATE\101fe1db\data\BadStart2CI.ini    	private\101fe1db\data\BadStart2CI.ini
+data=ZPRIVATE\101fe1db\data\BadStop0CI.ini    	private\101fe1db\data\BadStop0CI.ini
+data=ZPRIVATE\101fe1db\data\BadStop1CI.ini    	private\101fe1db\data\BadStop1CI.ini
+data=ZPRIVATE\101fe1db\data\BadStop2CI.ini    	private\101fe1db\data\BadStop2CI.ini
+data=ZPRIVATE\101fe1db\data\nice.ini    		private\101fe1db\data\nice.ini
+data=ZPRIVATE\101fe1db\data\test.ini    		private\101fe1db\data\test.ini
+data=ZPRIVATE\101fe1db\data\SyncStart.ini  		private\101fe1db\data\SyncStart.ini
+data=ZPRIVATE\101fe1db\data\SyncStop.ini   		private\101fe1db\data\SyncStop.ini
+data=ZPRIVATE\101fe1db\data\AsyncStart.ini 		private\101fe1db\data\AsyncStart.ini
+data=ZPRIVATE\101fe1db\data\AsyncStop.ini    	private\101fe1db\data\AsyncStop.ini
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/group/t_Usbman_dummyCC.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+/*
+* Copyright (c) 1997-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:
+* This is the mmp file for a special build of USBSVR, including only three 
+* instances of the dummy class controller, and no other class controllers. It 
+* is used for GT171 automated tests.
+*
+*/
+
+target t_usbman_dummycc.exe
+
+#include "usbsvrbase.mmp"
+
+userinclude		../../../inifile/inc
+
+sourcepath		../SRC
+source			CUsbDummyClassController.cpp
+
+sourcepath		../../../inifile/src
+source			inifile.cpp
+
+// This is the crucial difference between this and usbsvr.mmp.
+MACRO USE_DUMMY_CLASS_CONTROLLER
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/group/usbsvrbase.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,85 @@
+/*
+* 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 "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:
+* Core MMP file for usbsvr and test variants.
+*
+*/
+
+/**
+ @file
+*/
+
+
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+
+targettype exe
+
+uid 0x0 0x101fe1db
+VENDORID 0x70000001
+
+sourcepath		../SRC
+source			UsbSvr.cpp
+source			CUsbServer.cpp
+source			CUsbSession.cpp
+source			CUsbScheduler.cpp
+source			CUsbDevice.cpp
+source			CUsbDeviceStateWatcher.cpp
+source			UsbUtils.cpp
+source			CPersonality.cpp
+
+userinclude		../INC
+userinclude		../public
+userinclude		../../../host/fdf/production/client/public
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+lang			sc 01 02 03 10	// UK English, French, German, US English
+
+START RESOURCE usbman.rss
+TARGETPATH /private/101fe1db
+HEADER
+END
+
+#ifdef SYMBIAN_USB_RNDIS
+START RESOURCE usbmanrndis.rss
+TARGETPATH /private/101fe1db
+HEADER
+END
+#endif
+
+START RESOURCE usbmanmtp.rss
+TARGETPATH /private/101fe1db
+HEADER
+END
+
+#ifdef SYMBIAN_USB_RNDIS
+START RESOURCE usbmanmtprndis.rss
+TARGETPATH /private/101fe1db
+HEADER
+END
+#endif
+	
+START RESOURCE usbmanlubbockobex.rss
+TARGETPATH /private/101fe1db
+HEADER
+END
+
+library			euser.lib
+library			usbclasscontroller.lib
+library			ecom.lib
+library			efsrv.lib
+library			bafl.lib
+library			usbmanextensionplugin.lib
+library			sysutil.lib
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/group/usbsvrotg.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+/*
+* 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 "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:
+* usbsvr.exe USB server with USB Host and OTG support
+*
+*/
+
+/**
+ @file
+*/
+
+#include "usbsvrbase.mmp"
+
+MACRO SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+
+target usbsvrotg.exe
+
+sourcepath		../SRC
+source			CUsbOtg.cpp
+source			cusbotgwatcher.cpp
+source			cusbhost.cpp
+source			cusbhostwatcher.cpp
+
+library			usbhoststack.lib
+
+UNPAGED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/group/usbsvrotg_dummyusbdi.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,45 @@
+/*
+* 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 "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:
+* usbsvrotg.mmp
+* usbsvr.exe USB server with USB Host and OTG support
+*
+*/
+
+/**
+ @file
+*/
+
+#include "usbsvrbase.mmp"
+
+MACRO SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+MACRO	__OVER_DUMMYUSBDI__
+// This is the crucial difference between this and usbsvr.mmp.
+//MACRO USE_DUMMY_CLASS_CONTROLLER
+
+//SID 0x10282B50
+
+target usbsvr_over_dummyusbdi.exe
+
+sourcepath		../SRC
+source			CUsbOtg.cpp
+source			cusbotgwatcher.cpp
+source			cusbhost.cpp
+source			cusbhostwatcher.cpp
+//source			CUsbDummyClassController.cpp
+//source			INIFILE.CPP
+
+library			usbhoststack_over_dummyusbdi.lib
+
+UNPAGED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/public/MUsbDeviceNotify.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 1997-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
+ *
+ * The mixin used by the USB Device object to notify all of
+ * it's observers of any state changes that occur
+ *
+ * Copyright (c) 1997-2007 Symbian Ltd.  All rights reserved.
+ */
+
+#ifndef __MUSBDEVICENOTIFY_H__
+#define __MUSBDEVICENOTIFY_H__
+
+#include <usbstates.h>
+
+/**
+ * The MUsbDeviceNotify class
+ *
+ * The mixin used by the USB Device object to notify all of
+ * it's observers of any state changes that occur
+
+  @publishedPartner
+  @released
+ */
+class MUsbDeviceNotify
+	{
+public:
+	/**
+	 * Called when the USB service state has changed
+	 *
+	 * @param aLastError The last error code detected
+	 * @param aOldState The previous service state
+	 * @param aNewState The new service state
+	 */
+	virtual void UsbServiceStateChange(TInt aLastError, TUsbServiceState aOldState, TUsbServiceState aNewState) = 0;
+
+	/**
+	 * Called when the USB device state has changed
+	 *
+	 * @param aLastError The last error code detected
+	 * @param aOldState The previous device state
+	 * @param aNewState The new device state
+	 */
+	virtual void UsbDeviceStateChange(TInt aLastError, TUsbDeviceState aOldState, TUsbDeviceState aNewState) = 0;
+	};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/public/UsbClassUids.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,44 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef USBCLASSUIDS_H
+#define USBCLASSUIDS_H
+
+
+/**
+UID of the Serial Emulation plugin
+@publishedPartner
+@released
+*/
+const TUid KECACMUid={0x101FBF22};
+
+/**
+UID of the Obex over USB plugin
+@publishedPartner
+@released
+*/
+const TUid KWHCMUid={0x101fbf24};
+
+/**
+UID of the Mass Storage plugin
+@publishedPartner
+@released
+*/
+const TUid KUSBMSUid={0x10204bbc};
+
+
+#endif // USBCLASSUIDS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/public/Usb_std.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 1997-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
+ @publishedPartner
+*/
+
+#ifndef __USB_STD_H__
+#define __USB_STD_H__
+
+#include <e32def.h>
+
+NONSHARABLE_CLASS(TUsbDescriptor)
+/** Used by Class Controllers to express information about their descriptors.
+
+  @publishedPartner
+  @released
+  */
+	{
+public:
+	/**
+	Number of interfaces this class controller is responsible for.
+	*/
+	TInt iNumInterfaces;
+
+	/**
+	Total length of interfaces this class controller is responsible for.
+	*/
+	TInt iLength;
+	};
+
+#endif // __USB_STD_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/public/UsbmanInternalConstants.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 1997-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:
+* Defines usbmanager constants needed by cpp's executing in the usb 
+* manager process
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+ 
+#ifndef __USBMANINTERNALCONSTANTS_H__
+#define __USBMANINTERNALCONSTANTS_H__
+ 
+_LIT(KUsbManPrivatePath,"\\private\\101fe1db\\");
+_LIT(KUsbManResourcePath,"\\resource\\");
+
+#endif //__USBMANINTERNALCONSTANTS_H__
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/public/rusb.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,117 @@
+/*
+* Copyright (c) 2003-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:
+* Definitions required for RUsb
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef __RUSB_H__
+#define __RUSB_H__
+
+#include <e32std.h>
+#include <usb/usbshared.h>
+
+const TInt KUsbSrvMajorVersionNumber = 1;
+const TInt KUsbSrvMinorVersionNumber = 1;
+const TInt KUsbSrvBuildVersionNumber = 0;
+
+const TInt KUsbMaxSupportedClasses = 64;		// Max number of supported USB classes by a personality
+
+const TInt KUsbMaxSupportedPersonalities = 64;	// Max number of supported personalities
+
+_LIT(KUsbServerName, "!usbman");
+
+enum TUsbMessages
+	{
+	EUsbStart,
+	EUsbStop,
+	EUsbRegisterObserver,
+	EUsbGetCurrentState,
+	EUsbStartCancel,
+	EUsbCancelObserver,
+	EUsbStopCancel,
+	EUsbGetCurrentDeviceState,
+	EUsbRegisterServiceObserver,
+	EUsbCancelServiceObserver,
+	EUsbDbgMarkHeap,
+	EUsbDbgCheckHeap,
+	EUsbDbgMarkEnd,
+	EUsbDbgFailNext,
+	EUsbTryStart,
+	EUsbTryStop,
+	EUsbCancelInterest,
+	EUsbGetCurrentPersonalityId,
+	EUsbGetSupportedClasses,
+	EUsbGetPersonalityIds,
+	EUsbGetDescription,
+	EUsbClassSupported,
+
+	
+	EUsbSetCtlSessionMode,
+	EUsbBusRequest,
+	EUsbBusRespondSrp,
+	EUsbBusClearError,
+
+	EUsbBusDrop,
+	EUsbRegisterMessageObserver,
+	EUsbCancelMessageObserver,
+	EUsbRegisterHostObserver,
+	EUsbCancelHostObserver,
+	EUsbEnableFunctionDriverLoading,
+	EUsbDisableFunctionDriverLoading,
+	EUsbGetSupportedLanguages,
+	EUsbGetManufacturerStringDescriptor,
+	EUsbGetProductStringDescriptor,
+	EUsbGetOtgDescriptor,
+	EUsbDbgAlloc,
+	EUsbRequestSession,
+	EUsbGetDetailedDescription,
+	EUsbGetPersonalityProperty
+	};
+
+_LIT(KUsbCliPncCat, "UsbMan-Client");
+
+enum TUsbPanicClient
+	{
+	EUsbCreateFailure,
+	EUsbPanicIllegalIPC,
+	EUsbPanicRemovedExport
+	};
+
+const TUid KUsbmanSvrUid = {0x101fe1db};
+
+#ifdef __USBMAN_NO_PROCESSES__
+
+const TUint KUsbmanStackSize = 0x3000;			//  12KB
+const TUint KUsbmanMinHeapSize = 0x1000;		//   4KB
+const TUint KUsbmanMaxHeapSize = 0x40000;		// 256KB
+
+_LIT(KUsbmanImg, "usbsvr");
+
+#else
+
+#ifndef __OVER_DUMMYUSBDI__
+_LIT(KUsbmanImg, "z:\\system\\programs\\usbsvr.exe");
+#else
+_LIT(KUsbmanImg, "z:\\system\\programs\\usbsvr_over_dummyusbdi.exe");
+#endif
+
+#endif //__USBMAN_NO_PROCESSES__
+
+#endif //__RUSB_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/public/usberrors.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2003-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:
+*
+*/
+
+#ifndef __USBERRORS_H__
+#define __USBERRORS_H__
+
+#include <e32def.h>
+
+/** @file
+ Errors used by the USB Manager.
+*/
+
+/** KErrUsbBase
+	
+	Not used as an error. 'Base' value for USB Manager errors. 
+	Numerical value: -6600.
+
+	@publishedPartner 
+	@released 
+*/
+const TInt KErrUsbBase				= (-6600);
+
+/** KErrUsbServiceStopped
+	
+	Used to complete an RUsb::Start request when the service ends up Idle 
+	because another client did an RUsb::Stop. 
+	Numerical value: -6601
+	
+	@publishedPartner 
+	@released 
+*/
+const TInt KErrUsbServiceStopped	= (KErrUsbBase-1); // -6601
+
+/** KErrUsbServiceStarted
+
+	Used to complete an RUsb::Stop request when the service ends up Started 
+	because another client did an RUsb::Start. 
+	Numerical value: -6602
+
+	@publishedPartner 
+	@released 
+*/
+const TInt KErrUsbServiceStarted	= (KErrUsbBase-2); // -6602
+
+#endif //__USBERRORS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/public/usbhostdefs.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,142 @@
+/*
+* 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 "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:
+* Shared HOST definitions
+*
+*/
+
+/**
+ @file
+ @publishedPartner
+*/
+
+#ifndef __USBHOSTDEFS_H__
+#define __USBHOSTDEFS_H__
+
+#include <e32std.h>
+
+/** An event in the attachment-detachment lifecycle of a USB device. */
+enum TUsbHostStackEventType
+	{
+	/** A device attachment has occurred. */
+	EDeviceAttachment	= 0,
+	
+	/** An attempt to load Function Driver(s) has occurred. */
+	EDriverLoad			= 1,
+	
+	/** A device detachment has occurred. */
+	EDeviceDetachment	= 2,
+	};
+
+/** For a 'driver loading' event, whether the attempt to load drivers was 
+successful, partially successful, or unsuccessful. */
+const TUint KMultipleDriversFound = 0x00000004;
+
+enum TDriverLoadStatus
+	{
+	/** Driver loading was successful for all the device's interfaces. */
+	EDriverLoadSuccess			= 0,
+	
+	/** Driver loading was successful for one or more of the device's 
+	interfaces, but not for all of them. */
+	EDriverLoadPartialSuccess	= 1,
+	
+	/** Driver loading was successful for none of the device's interfaces. */
+	EDriverLoadFailure			= 2,
+	
+	/** Driver loading was successful for all the device's interfaces, with multiple drivers found */
+	EDriverLoadSuccessMultipleDriversFound			= EDriverLoadSuccess|KMultipleDriversFound,
+	
+	/** Driver loading was successful for one or more of the device's 
+	interfaces, but not for all of them, with multiple drivers found. */
+	EDriverLoadPartialSuccessMultipleDriversFound	= EDriverLoadPartialSuccess|KMultipleDriversFound,
+	
+	/** Driver loading was successful for none of the device's interfaces, with multiple drivers found. */
+	EDriverLoadFailureMultipleDriversFound           = EDriverLoadFailure|KMultipleDriversFound
+	};
+
+NONSHARABLE_CLASS(TDeviceEventInformation)
+	{
+public:
+	inline TDeviceEventInformation()
+		// These initialisations are arbitrary
+		:	iDeviceId(0),
+			iEventType(EDeviceAttachment),
+			iError(KErrNone),
+			iDriverLoadStatus(EDriverLoadSuccess),
+			iVid(0),
+			iPid(0)
+		{}
+
+	// Always relevant- the ID of the device the event relates to.
+	TUint iDeviceId;
+
+	// Always relevant- the type of event that has occurred.
+	TUsbHostStackEventType iEventType;
+
+	// Relevant to attachment and driver load events.
+	TInt iError;
+
+	// Relevant to driver load events only.
+	TDriverLoadStatus iDriverLoadStatus;
+
+	// Relevant to attachments with iError KErrNone.
+	TUint16 iVid;
+
+	// Relevant to attachments with iError KErrNone.
+	TUint16 iPid;
+	};
+	
+const TInt KUsbMaxSupportedLanguageIds = 127;	// Max number of supported USB Language Ids
+
+
+enum TUsbOtgAttributes
+	{	
+	/** Device supported SRP protocol */
+	EUsbOtgSRPSupported = 0x01,
+	
+	/** Device supported HNP protocol */
+	EUsbOtgHNPSupported = 0x02,	
+	
+	EUsbOtgAttributeCount,
+	};
+
+NONSHARABLE_CLASS(TOtgDescriptor)
+	{
+public:
+	inline TOtgDescriptor()
+		:	iDeviceId(0),
+		    iAttributes(0),
+		    iReserved1(0),
+		    iReserved2(0),
+		    iReserved3(0)
+		{}
+
+	// The ID of the device the OTG descriptor relates to.
+	TUint iDeviceId;
+    
+	// The OTG attributes - currently only D0 and D1 are used for SRP and HNP.
+	TUint8 iAttributes;
+	
+	// Reserved
+	TInt iReserved1;
+	
+	// Reserved
+	TInt iReserved2;
+
+	// Reserved
+	TInt iReserved3;
+	};
+
+#endif //__USBHOSTDEFS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/public/usbman.rh	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,133 @@
+/*
+* Copyright (c) 2003-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:
+* Resource header for usbman configuration.
+*
+*/
+
+/**
+ @file
+ @publishedPartner
+ @released
+*/
+
+STRUCT usb_configuration
+	{
+	/** 
+		vendorId is the 16-bit number that is assigned by USB-ORG.
+	 */
+	WORD	vendorId		= 0x0e22;
+
+	/** 
+		productId is a 16-bit number that is assigned by the licensee to 
+		uniquely identify this particular type of device.
+	 */
+	WORD	productId		= 0x000b;
+
+	/** 
+		bcdDevice may be optionally used during enumeration, this depends on 
+		the licensee's policy regarding device upgrades (new versions of a 
+		device may require to use new host driver files)
+	 */
+	WORD	bcdDevice		= 0x0000;
+
+	/** 
+		manufacturerString is displayed on the Windows screen during first 
+		enumeration of the device, and should identify the same company that 
+		owns the USB vendorId given above
+	 */
+	LTEXT	manufacturer	= "Symbian Ltd.";
+
+	/** 
+		productString is displayed on the Windows screen during first 
+		enumeration of the device, and should identify the same device that is 
+		implied by the productId given above
+	 */
+	LTEXT	product			= "Symbian OS";
+	}
+
+STRUCT PERSONALITY
+	{
+	/** 	Class code (assigned by the USB-IF). If this field is set to zero, each interface within 
+		a configuration specifies its own class information and the various interfaces operate independently. 
+
+		If this field is set to a value between 1 and FEH, the device supports different class
+		specifications on different interfaces and the interfaces may not operate independently.
+		This value identifies the class definition used for the aggregate interfaces.
+
+		If this field is set to FFH, the device class is vendor-specific. */
+	BYTE	bDeviceClass;
+
+	/** 	Subclass code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass field.
+		If the bDeviceClass field is set to zero, this field must also be set to zero.
+		If the bDeviceClass field is not set to FFH, all values are reserved for assignment by the USB-IF. */
+	BYTE	bDeviceSubClass;
+
+	/**	Protocol code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass and the
+		bDeviceSubClass fields. If a device supports class-specific protocols on a device basis as opposed to an 
+		interface basis, this code identifies the protocols that the device uses as defined by the specification of the device class.
+		If this field is set to zero, the device does not use class-specific protocols on a device basis. However, it may use 
+		classspecific protocols on an interface basis.
+		If this field is set to FFH, the device uses a vendor-specific protocol on a device basis. */
+	BYTE 	protocol;
+
+	/**	Number of possible configurations */
+	BYTE	numConfigurations;
+
+	/** vendorId is the 16-bit number that is assigned by USB-ORG. */
+	WORD 	vendorId;
+
+	/** productId is a 16-bit number that is assigned by the licensee to 
+	uniquely identify this particular personality as type of device . */
+	WORD 	productId;
+
+	/** 	bcdDevice may be optionally used during enumeration, this depends on 
+		the licensee's policy regarding device upgrades */
+	WORD 	bcdDevice;
+
+	/** 	manufacturerString is displayed on the Windows screen during first 
+		enumeration of the device, and should identify the same company that 
+		owns the USB vendorId given above */
+	LTEXT 	manufacturer;
+	
+	/** 	productString is displayed on the Windows screen during first 
+		enumeration of the device, and should identify the same device that is 
+		implied by the productId given above */
+	LTEXT 	product;
+
+	/**	personality id - UID which identified this personality */
+	WORD 	id;					 
+	
+	/**	list of Class Controllers UIDs associated with this personality.
+		UIDs shoud be provided as list of hexadecimal numbers separated by space or comma.
+		Note Do not provide leading 0x or any trailing characters!
+		Example "1Abc3422, 12345678  FE43bc33"
+		Incorrect example "1abc3422, 0x12345678," */
+	LTEXT	class_uids;			
+	
+	/** 	free text description of this personality. */
+	LTEXT 	description;
+
+	/**     free text detailed description of this personality. */
+	LTEXT   detailedDescription;
+
+	/**	personality property - the property of this personality */
+	LONG 	property;					 
+
+	}
+	
+STRUCT PERSONALITY_ARRAY
+	{
+	STRUCT	personalities[];	// STRUCT PERSONALITY
+	}	 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/public/usbotgdefs.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,101 @@
+/*
+* 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 "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:
+* Shared OTG definitions
+*
+*/
+
+/**
+ @file
+ @publishedPartner
+ @released
+*/
+
+#ifndef __USBOTGDEFS_H__
+#define __USBOTGDEFS_H__
+
+#include <e32std.h>
+	
+const TUint32 KUsbmanSvrSid = {0x101fe1db};
+const TUid KUidUsbManCategory = {0x101fe1db};
+const TUint KUsbOtgIdPinPresentProperty = 3; 	// Id-Pin present
+const TUint KUsbOtgVBusPoweredProperty = 4;  	// VBus powered up
+const TUint KUsbOtgStateProperty = 5;  			// OTG State
+const TUint KUsbRequestSessionProperty = 6;  	// Request VBus
+const TUint KUsbOtgConnectionIdleProperty = 7;  // Connection Idle
+
+/**
+	OTG State, supplied in a form that will enable use as an array
+	index (note also how this is used below in the bit-mask form)
+*/
+enum TUsbOtgState
+	{
+	/**
+	Single case of non-stable state, used only during
+	startup
+	*/
+	EUsbOtgStateReset = 0x01,
+
+	/**
+	'A'-connection states (names are derived from OTG-Supplement
+	Figure 6-2 On-The-Go A-Device State Diagram)
+	*/
+	EUsbOtgStateAIdle = 0x02,
+	EUsbOtgStateAHost = 0x04,
+	EUsbOtgStateAPeripheral = 0x08,
+	EUsbOtgStateAVbusError = 0x10,
+
+	/**
+	'B'-connection states (names are derived from OTG-Supplement
+	Figure 6-3 On-The-Go B-Device State Diagram)
+	*/
+	EUsbOtgStateBIdle = 0x20,
+	EUsbOtgStateBPeripheral = 0x40,
+	EUsbOtgStateBHost = 0x80,
+	};
+
+/**
+	OTG Events, supplied in a form that can be used to create a mask
+	that can specify a watcher's events of interest.
+*/
+enum TUsbOtgEvent
+	{
+	/**
+	OTG events related to plug insertion or removal
+	*/
+	EUsbOtgEventAPlugInserted 		= 0x01,
+	EUsbOtgEventAPlugRemoved  		= 0x02,
+
+	/**
+	OTG events relating to changes visible on the bus
+	*/
+	EUsbOtgEventVbusRaised			= 0x04,
+	EUsbOtgEventVbusDropped			= 0x08,
+
+	EUsbOtgEventSrpInitiated		= 0x10,
+
+	EUsbOtgEventSrpReceived			= 0x20,
+	EUsbOtgEventHnpEnabled			= 0x40,
+	EUsbOtgEventHnpDisabled			= 0x80,
+
+	/**
+	OTG events related to changes in the current role the device
+	is performing (independant of the orientation of the connection)
+	*/
+	EUsbOtgEventRoleChangedToHost	= 0x100,
+	EUsbOtgEventRoleChangedToDevice	= 0x200,
+	EUsbOtgEventRoleChangedToIdle	= 0x400
+	};
+
+#endif //__USBOTGDEFS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/usbman/server/public/usbshared.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,106 @@
+/*
+* Copyright (c) 2003-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:
+* Shared client/server definitions
+*
+*/
+
+/**
+ @file
+ @publishedPartner
+*/
+
+#ifndef __USBSHARED_H__
+#define __USBSHARED_H__
+
+#include <e32std.h>
+#include <usbhostdefs.h>
+#include <usbotgdefs.h>
+	
+/** KUsbMessageBase
+	
+	Not used as a message value. 'Base' value for USB OTG/Host related messages which are NOT errors. 
+	Numerical value: 6600.
+
+	@publishedPartner 
+	@released 
+*/
+const TInt KUsbMessageBase	= 6600;
+	
+
+/** KUsbMessageSrpInitiated
+
+	Used to inform the observer about SRP request 
+
+	@publishedPartner 
+	@released 
+*/
+const TInt KUsbMessageSrpInitiated	= (KUsbMessageBase+1);
+
+/** KUsbMessageSrpReceived
+
+	Used to inform the observer about SRP request 
+
+	@publishedPartner 
+	@released 
+*/
+const TInt KUsbMessageSrpReceived	= (KUsbMessageBase+2);
+
+/** KUsbMessageHnpDisabled
+
+	Used to inform the observer about HNP status after RESET
+
+	@publishedPartner 
+	@released 
+*/
+const TInt KUsbMessageHnpDisabled	= (KUsbMessageBase+3);
+
+/** KUsbMessageHnpEnabled
+
+	Used to inform the observer about HNP status
+
+	@publishedPartner 
+	@released 
+*/
+const TInt KUsbMessageHnpEnabled	= (KUsbMessageBase+4);
+
+/** KUsbMessageVbusRaised
+
+	Used to inform the observer about VBUS going up
+
+	@publishedPartner 
+	@released 
+*/
+const TInt KUsbMessageVbusRaised	= (KUsbMessageBase+5);
+
+/** KUsbMessageVbusDropped
+
+	Used to inform the observer about VBUS going down
+
+	@publishedPartner 
+	@released 
+*/
+const TInt KUsbMessageVbusDropped	= (KUsbMessageBase+6);
+
+/** KUsbMessageRequestSession
+
+	Used to inform the observer about USB session request  
+
+	@publishedPartner 
+	@released
+*/
+const TInt KUsbMessageRequestSession = (KUsbMessageBase+7);
+
+	
+#endif //__USBSHARED_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerClientSession/BWINS/classControllerClientSessionU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,5 @@
+EXPORTS
+	?Connect@RClassControllerClient@@QAEHXZ @ 1 NONAME ; int RClassControllerClient::Connect(void)
+	?StartService@RClassControllerClient@@QAEHXZ @ 2 NONAME ; int RClassControllerClient::StartService(void)
+	?StopService@RClassControllerClient@@QAEHXZ @ 3 NONAME ; int RClassControllerClient::StopService(void)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerClientSession/EABI/classControllerClientSessionU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,5 @@
+EXPORTS
+	_ZN22RClassControllerClient11StopServiceEv @ 1 NONAME
+	_ZN22RClassControllerClient12StartServiceEv @ 2 NONAME
+	_ZN22RClassControllerClient7ConnectEv @ 3 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerClientSession/group/ClassControllerClientSession.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,44 @@
+/*
+* 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 "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:
+* clientSession.dll Client side code for Class controller to use to Start/Stop a Process
+*
+*/
+
+/**
+ @file
+*/
+
+
+TARGET classcontrollerclientsession.dll
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+TARGETTYPE dll
+//CAPABILITY All -Tcb
+
+// unique dll UID 
+UID             0x1028180b
+VENDORID 		0x70000001
+
+SOURCEPATH		../src
+SOURCE			classControllerClientSession.cpp
+
+USERINCLUDE		../inc
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+LIBRARY			euser.lib 
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerClientSession/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,24 @@
+/*
+* 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 "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:
+*
+*/
+
+
+
+PRJ_TESTMMPFILES
+ClassControllerClientSession.mmp
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerClientSession/inc/classControllerClientSession.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* 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 "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:
+*
+*/
+
+
+#ifndef CLASSCONTROLLERCLIENTSESSION_H
+#define CLASSCONTROLLERCLIENTSESSION_H
+
+#include <e32base.h>
+
+/**
+ * RClassControllerClient is a RSessionBase derived class.
+ * It serves as the Client side of a Client and Server
+ * configuration. Implementation of this class occurs within
+ * the Obex Class Controller, it's member functions
+ * cause messages to be sent to the server side code implemented in an 
+ * executable process that start an Obex server.
+ *
+ */
+
+class RClassControllerClient : public RSessionBase
+	{
+	public:
+		IMPORT_C TInt Connect();
+		IMPORT_C TInt StartService();
+		IMPORT_C TInt StopService();
+	};
+#endif // CLASSCONTROLLERCLIENTSESSION_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerClientSession/src/classControllerClientSession.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,124 @@
+/*
+* 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 "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 "../../public/clientServerShared.h"
+#include "classControllerClientSession.h"
+
+
+/**
+ * Function used by RClassControllerClient::Connect member function.
+ * It exists to create a new process which contains the server side code.
+ *
+ * @return Value of error code created
+ */
+static TInt StartServer()
+	{
+	const TUidType serverUid(KNullUid, KNullUid, KObexCCUid);
+	RProcess server;
+	TInt err = server.Create(KServerExe, KNullDesC, serverUid);
+	if ( err != KErrNone )
+		{
+		return err;
+		}
+
+	TRequestStatus stat;
+	server.Rendezvous(stat);
+
+	if ( stat != KRequestPending )
+		{
+		server.Kill(0); 	// abort startup
+		}
+	else
+		{
+		server.Resume();	// logon OK - start the server
+		}
+
+	User::WaitForRequest(stat); 	// wait for start or death
+
+	// we can't use the 'exit reason' if the server paniced as this
+	// is the panic 'reason' and may be '0' which cannot be distinguished
+	// from KErrNone
+	err = (server.ExitType() == EExitPanic) ? KErrServerTerminated : stat.Int();
+	
+	server.Close();
+
+	return err;
+	}
+
+
+
+/**
+ * Function that creates a session with the server and then returns the appropriate error code.
+ * Then calls StartServer to start the process with the server side code.
+ * 
+ * @return Value of error code produced
+ */
+
+EXPORT_C TInt RClassControllerClient::Connect()
+	{
+	TInt retry = 2;
+
+	FOREVER
+		{
+		//Create Session, With server name from shared header 
+		//And lowest version number of the server with which this client is compatible. 
+		//Number of message slots available, -1 for meessages from global free pool
+
+		TInt err = CreateSession(KServerName, TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber), KMessageSlots);
+
+		if ((err != KErrNotFound) && (err != KErrServerTerminated))
+			{
+			return err;
+			}
+
+		if (--retry == 0)
+			{
+			return err;
+			}
+
+		err = StartServer();
+
+		if ((err != KErrNone) && (err != KErrAlreadyExists))
+			{
+			return err;
+			}
+		}
+	}
+
+/**
+ * Function that sends a message to the server to initiate the start
+ * of an Obex Service. On completion, TRequestStatus contains error code.
+ *
+ * @return Value of TRequestStatus 
+ */
+EXPORT_C TInt RClassControllerClient::StartService()
+	{
+	return (SendReceive(EStartClassContServer));
+	}
+
+/**
+ * Function that sends a message to the server to initiate the stop
+ * of an Obex Service. On completion, TRequestStatus contains error code.
+ *
+ * @return Value of TRequestStatus 
+ */
+EXPORT_C TInt RClassControllerClient::StopService()
+	{
+	return (SendReceive(EStopClassContServer));
+	}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/group/Bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,21 @@
+/*
+* 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 "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:
+*
+*/
+
+
+PRJ_TESTMMPFILES
+classControllerServerSession.mmp
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/group/classControllerServerSession.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* 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 "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:
+*
+*/
+
+
+
+TARGET        classcontrollerserversession.exe
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+TARGETTYPE    exe
+UID           0x0  0x10281916
+VENDORID 0x70000001
+
+SOURCEPATH    ../src
+SOURCE      main.cpp 
+SOURCE		classContServer.cpp 
+SOURCE		classContServerSession.cpp
+SOURCE		obexInitiator.cpp
+
+
+USERINCLUDE   ../inc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY		euser.lib 
+LIBRARY		esock.lib 
+LIBRARY		obex.lib
+LIBRARY		c32.lib
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/inc/classContServer.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,79 @@
+/*
+* 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 "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
+*/
+
+#ifndef CLASSCONTSERVER_H
+#define CLASSCONTSERVER_H
+
+#include <e32base.h>
+
+
+_LIT(KServerPanicCategory, "ServServer");
+_LIT(KClientPanicCategory, "Client");
+
+_LIT_SECURE_ID(KUsbSvrSecureId,0x101fe1db);
+
+enum TServServerPanic
+	{
+	EServServerPanicIllegal = 0
+	};
+
+enum TClientPanic
+	{
+	EClientPanicBadMessage = 0
+	};
+
+class CServerTimer;
+
+/**
+ * CClassContServer is a CServer2 derived class, it resides on the server side
+ * of the Client and Server configuration and implements a new Session to deal with requests 
+ * from the client side.
+ *
+ */
+
+NONSHARABLE_CLASS(CClassContServer) : public CServer2
+	{
+	public:
+		static CClassContServer* NewLC();
+		~CClassContServer();
+		void SessionRemoved();
+		void StartShutdownTimer();
+		void CancelShutdownTimer();
+		static TInt ShutdownTimerFired(TAny*);
+
+	
+	private:
+		CClassContServer();
+		CSession2* NewSessionL(const TVersion &aVersion, const RMessage2& aMessage) const;
+		void ConstructL();
+
+	private:
+		CSession2* iSession;
+		CPeriodic* iShutdownTimer;
+		static const TUint KShutdownDelay = 5 * 1000 * 1000;
+		static const TUint KShutdownInterval = 0;
+	};
+
+
+
+
+#endif // CLASSCONTSERVER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/inc/classContServerSession.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,69 @@
+/*
+* 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 "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
+*/
+
+#ifndef CLASSCONTSERVERSESSION_H
+#define CLASSCONTSERVERSESSION_H
+
+#include <e32base.h>
+#include <obex.h>
+#include <obexserver.h>
+#include "obexInitiator.h"
+
+class CClassContServer;
+
+
+
+/**
+ * CClassContServerSession is a CSession2 derived class.
+ * This class is implemented on the server side of a Client
+ * and Server configuration, it has member functions that exist
+ * to process requests from the client. 
+ *
+ */
+NONSHARABLE_CLASS(CClassContServerSession) : public CSession2
+	{
+	public:
+		static CClassContServerSession* NewL(CClassContServer& aServer);
+		~CClassContServerSession();
+
+	private:
+		CClassContServerSession(CClassContServer& aServer);
+		void ConstructL();
+		
+		// from CSession2
+		void ServiceL(const RMessage2& aMessage);
+	
+		void ForwardMessageL(const RMessage2& aMessage);
+		void StartServiceL();
+		void StopService();
+		
+		CClassContServer& iServer;
+		CObexInitiator* iObexInitiator;
+		TBool iBadMessage;
+	};
+
+
+#endif //CLASSCONTSERVERSESSION_H
+
+
+
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/inc/obexInitiator.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,68 @@
+/*
+* 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 "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:
+*
+*/
+
+
+
+#ifndef OBEXINITIATOR_H
+#define OBEXINITIATOR_H
+	
+_LIT(KObexDescription, "Obex Server Interface");
+_LIT(KConsoleName, "Obex Server");
+/**
+ * CObexInitiator implements the MObexServerNotify interface. 
+ * It has implementations of virtual functions from the MObexServerNotify
+ * It also allows for an CObexServer to be created, started and stopped.
+ * This class is implemented in the CSession2 derived class, this class can be extended
+ * to make a greater use of the CObexServer class.
+ *
+ */
+NONSHARABLE_CLASS(CObexInitiator) : public CBase, private MObexServerNotify
+	{
+	
+	public:
+		static CObexInitiator* NewL();
+		~CObexInitiator();
+		void StartObexServerL();
+		void StopObexServer();
+
+	private:
+		void ConstructL();
+		CObexInitiator();
+		// These are the MObexServerNotify functions
+		virtual void ErrorIndication (TInt aError);
+		virtual void TransportUpIndication ();
+		virtual void TransportDownIndication ();
+		virtual TInt ObexConnectIndication  (const TObexConnectInfo& aRemoteInfo, const TDesC8& aInfo);
+		virtual void ObexDisconnectIndication (const TDesC8& aInfo);
+		virtual CObexBufObject* PutRequestIndication ();
+		virtual TInt PutPacketIndication ();
+		virtual TInt PutCompleteIndication ();
+		virtual CObexBufObject* GetRequestIndication (CObexBaseObject *aRequestedObject);
+		virtual TInt GetPacketIndication ();
+		virtual TInt GetCompleteIndication ();
+		virtual TInt SetPathIndication (const CObex::TSetPathInfo& aPathInfo, const TDesC8& aInfo);
+		virtual void AbortIndication ();
+	
+	private:
+		CObexServer* iObexServer;
+		CConsoleBase* iConsole;
+	
+	
+	};
+	
+	
+#endif // OBEXINITIATOR_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/src/classContServer.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,121 @@
+/*
+* 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 "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 <e32debug.h>
+
+#include "../../public/clientServerShared.h"
+#include "classContServer.h"
+#include "classContServerSession.h"
+
+/**
+ * Creates a new instance of CClassContServer, a CServer2
+ * derived class.
+ */
+CClassContServer* CClassContServer::NewLC()
+	{
+	CClassContServer* s = new(ELeave) CClassContServer;
+	CleanupStack::PushL(s);
+	s->ConstructL();
+	s->StartL(KServerName);
+	return s;	
+	}
+/**
+ * Destructor
+ */
+CClassContServer::~CClassContServer()
+	{
+	delete iShutdownTimer;
+	}
+
+/**
+ * Constructor
+ */	
+CClassContServer::CClassContServer() : CServer2(EPriorityStandard)
+	{
+	}
+
+
+/**
+ * 2nd phase construction. This exists to create a new timer and start a 5 second 
+ * timing period.
+ */	
+void CClassContServer::ConstructL()
+	{
+	iShutdownTimer = CPeriodic::NewL(CActive::EPriorityStandard);
+	StartShutdownTimer();	
+	}
+
+
+/**
+ * This function is called by the session object when a session has been terminated.
+ * It creates a new timer of 5 seconds, this time the 5 seconds will run to 
+ * completion and the timers RunL function will be called, stopping the active scheduler.
+ */	
+
+void CClassContServer::SessionRemoved()
+	{
+	iSession = NULL;
+	StartShutdownTimer();
+	}
+
+
+/**
+ * Function to instansiate a new CSession2 object, function leaves if a session
+ * already exists. After a session has been created the CServerTimer object
+ * gets cancelled.
+ */	
+CSession2* CClassContServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& aMessage) const
+	{
+	// before we continue check the secure ID of the send of aMessage
+	if (aMessage.SecureId() != KUsbSvrSecureId)
+		User::Leave(KErrPermissionDenied);
+
+	CClassContServer* ncthis = const_cast<CClassContServer*>(this);
+	// Only allow one session
+	if (iSession)
+		User::Leave(KErrAlreadyExists);	
+	ncthis->iSession = CClassContServerSession::NewL(*ncthis);
+	ncthis->CancelShutdownTimer();
+	return iSession;
+	}
+
+
+
+	
+void CClassContServer::StartShutdownTimer()
+	{
+	if ( !iShutdownTimer->IsActive() )
+		{
+		// Start the timer, delay events for 5 seconds, subsequent
+		// firings will not occur.
+		iShutdownTimer->Start(KShutdownDelay, KShutdownInterval, 
+								TCallBack(CClassContServer::ShutdownTimerFired, this));
+		}	
+	}
+	
+void CClassContServer::CancelShutdownTimer()
+	{
+	iShutdownTimer->Cancel();
+	}
+	
+TInt CClassContServer::ShutdownTimerFired(TAny* /*aThis*/)
+	{
+	CActiveScheduler::Stop();
+	return KErrNone;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/src/classContServerSession.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,135 @@
+/*
+* 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 "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 <e32def.h>
+#include <e32debug.h> 
+#include <obexserver.h>
+#include <obex.h>
+
+#include "../../public/clientServerShared.h"
+#include "classContServer.h"
+#include "classContServerSession.h"
+#include "obexInitiator.h"
+
+
+
+/**
+ * Creates a new CSession2 derived object
+ */
+CClassContServerSession* CClassContServerSession::NewL(CClassContServer& aServer)
+	{
+	CClassContServerSession* s = new(ELeave) CClassContServerSession(aServer);
+	CleanupStack::PushL(s);
+	s->ConstructL();
+	CleanupStack::Pop();
+	return s;
+	}
+
+	
+/**
+ * Desctructor, delete the CObexInitiator object and set to NULL
+ * to avaiod dereferencing freed memory
+ */	
+CClassContServerSession::~CClassContServerSession()
+	{
+
+	delete iObexInitiator;
+	iObexInitiator = NULL;
+	// tell server im gonna die
+	iServer.SessionRemoved();
+	}
+
+	
+/**
+ * Constructor, CServer2 object is passed
+ */
+CClassContServerSession::CClassContServerSession(CClassContServer& aServer) :
+	iServer(aServer)
+	{	
+	}
+
+
+/**
+ * 2nd phase constructor, new CObexIntiiator object is created under a Trap harness
+ * this allows for RMessage2 to complete with the appropriate error code before leaving.
+ */	
+void CClassContServerSession::ConstructL()
+	{
+	iObexInitiator = CObexInitiator::NewL(); // Create new CObexServer object
+	}
+
+
+/**
+ * This is the function that deals with an incoming request from 
+ * the client and then routes to the necessary function call.
+ */
+void CClassContServerSession::ServiceL(const RMessage2& aMessage)
+	{
+	TRAPD(err, ForwardMessageL(aMessage));
+	if (!iBadMessage)
+		aMessage.Complete(err);
+	}
+
+/**
+ * This is the function that maps the message from the client to
+ * the appropriate call onto the OBEX server.
+ */
+void CClassContServerSession::ForwardMessageL(const RMessage2& aMessage)
+	{
+	switch(aMessage.Function())
+		{
+		case EStartClassContServer:
+			StartServiceL();
+			break;
+		case EStopClassContServer:
+			StopService();
+			break;
+		default:
+			iBadMessage = ETrue;
+			aMessage.Panic(KClientPanicCategory, EClientPanicBadMessage);
+			break;
+		}
+	}
+
+/**
+ * This is the function that is called by the server when the client has
+ * requested to start the Obex Server, CObexInitiator::StartObexServerL 
+ * is responsible for calling CObexServer::Start, implementing an Obex Server.		
+ */	
+void CClassContServerSession::StartServiceL()
+	{
+	iObexInitiator->StartObexServerL(); // Call Start on the Obex Server
+	}
+
+
+/**
+ * This is the function called by the server when the client has requested
+ * to stop the Obex server, CObexInitiator::StopObexServer is esponsible
+ * for calling CObexServer::Stop.
+ *
+ */
+void CClassContServerSession::StopService()
+	{
+	iObexInitiator->StopObexServer(); //Stop the Obex server
+	}
+
+
+
+
+    
+  
+  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/src/main.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,72 @@
+/*
+* 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 "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 <e32base.h>
+#include <e32debug.h>
+
+#include "../../public/clientServerShared.h"
+#include "classContServer.h"
+
+static void RunServerL();
+
+
+/**
+ *This is the code entry point, calls run server function
+ */
+GLDEF_C TInt E32Main()
+	{
+
+	TInt ret = KErrNoMemory;
+
+	__UHEAP_MARK;
+
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	
+	if ( cleanup )
+		{
+		TRAP(ret, RunServerL());
+		delete cleanup;
+		}
+		
+	__UHEAP_MARKEND;
+	
+	return ret;
+	
+	}
+
+/**
+ * Function to initialise a CServer2 derived class and connect to
+ * the client.
+ */
+static void RunServerL()
+	{
+	static_cast<void>(User::RenameThread(KServerName));
+
+	// Create and install the active scheduler.
+	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
+	CleanupStack::PushL(scheduler);
+	CActiveScheduler::Install(scheduler);
+
+	(void)CClassContServer::NewLC();
+
+	// Initialisation complete, now signal the client
+	RProcess::Rendezvous(KErrNone);
+	// Ready to run. This only returns when the server is closing down.
+	CActiveScheduler::Start();
+	// Clean up the server and scheduler.
+	CleanupStack::PopAndDestroy(2, scheduler);
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ClassControllerServerSession/src/obexInitiator.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,162 @@
+/*
+* 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 "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 <e32cons.h>
+#include <obex.h>
+#include <obexserver.h>
+
+#include "obexInitiator.h"
+
+/**
+ * Creates a new object of type CObexInitiator
+ */
+CObexInitiator* CObexInitiator::NewL()
+	{
+	CObexInitiator* obexInit = new(ELeave) CObexInitiator();
+	CleanupStack::PushL(obexInit);
+	obexInit->ConstructL();
+	CleanupStack::Pop(obexInit);
+	return obexInit;
+	}
+/**
+ * Desctructor
+ */	
+CObexInitiator::~CObexInitiator()
+	{
+	delete iObexServer;
+	iObexServer = NULL;
+	__DEBUG_ONLY(delete iConsole);
+	}
+
+/**
+ * Constructor
+ */	
+CObexInitiator::CObexInitiator() 
+	{
+	}
+	
+/**
+ * 2nd phase constructor, this creates a new CObexServer
+ * with protocol information for USB Obex.
+ */
+void CObexInitiator::ConstructL()
+	{
+	TObexUsbProtocolInfo info;
+	info.iTransport = KObexUsbProtocol;
+	info.iInterfaceStringDescriptor = KObexDescription;
+	iObexServer = CObexServer::NewL(info);
+	__DEBUG_ONLY(iConsole = Console::NewL(KConsoleName, TSize(KConsFullScreen,KConsFullScreen));
+	iConsole->Printf(_L("A New Obex Server has been Created!\n")););
+	}	
+
+
+/**
+ * Start the Obex Server by calling CObexServer::Start
+ * Current instance that implements MObexServerNotify 
+ * is passed to the CObexServer.
+ */
+void CObexInitiator::StartObexServerL()
+	{
+	TInt err = iObexServer->Start(this);
+	User::LeaveIfError(err);
+	__DEBUG_ONLY(iConsole->Printf(_L("Obex Server Started!\n\n")););
+	}
+
+
+/**
+ * Stop the Obex Server and delete the CObexServer member.
+ * Set to NULL to avoid de referencing freed memory
+ */	
+void CObexInitiator::StopObexServer()
+	{
+	iObexServer->Stop();
+	}
+	
+	
+//Start of the MServerNotify virtual functions
+
+void CObexInitiator::ErrorIndication (TInt /*aError*/)
+    {
+    __DEBUG_ONLY(iConsole->Printf(_L("An OBEX Protocol error has occured!\n")););
+    }
+
+void CObexInitiator::TransportUpIndication ()
+    {
+    __DEBUG_ONLY(iConsole->Printf(_L("Transport Up\n")););
+    }
+
+void CObexInitiator::TransportDownIndication ()
+    {
+    __DEBUG_ONLY(iConsole->Printf(_L("Transport Down\n")););
+    }
+
+TInt CObexInitiator::ObexConnectIndication(const TObexConnectInfo& /*aRemoteInfo*/, const TDesC8& /*aInfo*/)
+    {
+    __DEBUG_ONLY(iConsole->Printf(_L("OBEX connection has been made with client\n")););
+	return KErrNone;
+    }
+
+void CObexInitiator::ObexDisconnectIndication (const TDesC8& /*aInfo*/)
+    {
+    __DEBUG_ONLY(iConsole->Printf(_L("OBEX has been disconnected with client\n")););
+    }
+
+CObexBufObject* CObexInitiator::PutRequestIndication ()
+    {
+    __DEBUG_ONLY(iConsole->Printf(_L("A Put is being made\n")););
+	return NULL;
+	}
+
+TInt CObexInitiator::PutPacketIndication ()
+    {
+	return KErrNone;
+    }
+
+TInt CObexInitiator::PutCompleteIndication ()
+    {
+    __DEBUG_ONLY(iConsole->Printf(_L("Put has completed\n")););
+	return KErrNone;
+    }
+
+
+CObexBufObject* CObexInitiator::GetRequestIndication (CObexBaseObject* /*aRequiredObject*/)
+    {
+    __DEBUG_ONLY(iConsole->Printf(_L("Client has made a Get request\n")););
+	return NULL;
+	}
+
+TInt CObexInitiator::GetPacketIndication ()
+    {
+    return KErrNone;
+    }
+
+TInt CObexInitiator::GetCompleteIndication ()
+    {
+    __DEBUG_ONLY(iConsole->Printf(_L("Get has completed\n")););
+  	return KErrNone;
+    }
+
+TInt CObexInitiator::SetPathIndication (const CObex::TSetPathInfo& /*aPathInfo*/, const TDesC8& /*aInfo*/)
+    {
+	return KErrNone;
+    }
+
+void CObexInitiator::AbortIndication ()
+    {
+    __DEBUG_ONLY(iConsole->Printf(_L("Operation aborted\n")););
+    }
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/group/CUsbObexClassController.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,57 @@
+/*
+* 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 "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
+*/
+
+
+target obexclasscontroller.dll
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+
+targettype plugin
+
+// ECom Dll recognition UID followed by the unique dll UID 
+UID              	0x10009d8d 0x1027433a
+VENDORID 0x70000001
+
+SOURCEPATH		../src
+SOURCE			CUsbObexClassImpCollection.cpp
+SOURCE			CUsbObexClassController.cpp
+
+
+USERINCLUDE		../inc
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+start resource 1027433a.rss
+target obexclasscontroller.rsc
+END
+
+START RESOURCE obexusbman.rss
+TARGETPATH /private/101fe1db
+HEADER
+END
+
+LIBRARY			classcontrollerclientsession.lib
+LIBRARY			euser.lib 
+LIBRARY			usbclasscontroller.lib
+LIBRARY			efsrv.lib
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,22 @@
+/*
+* 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 "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:
+*
+*/
+
+
+
+
+PRJ_TESTMMPFILES
+CUsbObexClassController.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/inc/CUsbObexClassController.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,60 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef __OBEXCLASSCONTROLLER_H__
+#define __OBEXCLASSCONTROLLER_H__
+
+#include <e32std.h>
+#include <cusbclasscontrollerplugin.h>
+#include "../../ClassControllerClientSession/inc/classControllerClientSession.h"
+
+class MUsbClassControllerNotify;
+
+const TInt KObexStartupPriority = 2;
+
+//Constants used in GetDescriptorInfo function
+const TInt KNumObexInterfaces = 2;
+const TInt KObexDescriptorLength = 18;
+
+NONSHARABLE_CLASS(CUsbObexClassController) : public CUsbClassControllerPlugIn
+	{
+
+	public:
+		static CUsbObexClassController* NewL(MUsbClassControllerNotify& aOwner);
+
+		virtual ~CUsbObexClassController();
+	 	// Functions derived from CActive.
+		virtual void RunL();
+		virtual void DoCancel();
+		virtual TInt RunError(TInt aError);
+
+		// Functions derived from CUsbClassControllerBase
+		virtual void Start(TRequestStatus& aStatus);
+		virtual void Stop(TRequestStatus& aStatus);
+
+		virtual void GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const;
+
+	protected:
+		CUsbObexClassController(MUsbClassControllerNotify& aOwner);
+		void ConstructL();
+
+	private:
+		RClassControllerClient iClassContClient;
+
+	};
+
+#endif //__OBEXCLASSCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/src/1027433a.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* 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 "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 <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x1027433a;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x101fbf21;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x10274339;
+					version_no = 1;
+					display_name = "ObexClassController";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/src/CUsbObexClassController.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,214 @@
+/*
+* 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 "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:
+* Implements part of the UsbMan USB Class Framework
+*
+*/
+
+/**
+ @file
+*/
+ 
+#include <e32debug.h>
+#include <e32std.h>
+#include <usb_std.h>
+#include "../../public/clientServerShared.h"
+#include "../../ClassControllerClientSession/inc/classControllerClientSession.h"
+#include "CUsbObexClassController.h"
+
+
+// Panic category only used in debug builds
+#ifdef _DEBUG
+_LIT( KObexCcPanicCategory, "UsbObexCc" );
+#endif
+
+/**
+ * Panic codes for the USB OBEX Class Controller.
+ */
+enum TObexCCPanic
+	{
+	/** Asynchronous function called (not needed, as all requests complete synchronously) */
+	EUnusedFunction = 0,
+	/** Start() called while in an illegal state */
+	EBadApiCallStart = 1,
+	/** Stop() called while in an illegal state */
+	EBadApiCallStop = 2,
+	};
+
+
+/**
+ * Constructs a CUsbObexClassController object
+ *
+ * @param	aOwner	USB Device that owns and manages the class
+ *
+ * @return	A new CUsbObexClassController object
+ */
+ 
+CUsbObexClassController* CUsbObexClassController::NewL(
+	MUsbClassControllerNotify& aOwner)
+	{
+	CUsbObexClassController* r = new (ELeave) CUsbObexClassController(aOwner);
+	CleanupStack::PushL(r);
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+	}
+
+/**
+ * Destructor
+ */
+CUsbObexClassController::~CUsbObexClassController()
+	{
+	iClassContClient.Close();
+	}
+
+
+
+/**
+ * Constructor.
+ *
+ * @param	aOwner	USB Device that owns and manages the class
+ */
+CUsbObexClassController::CUsbObexClassController(
+	MUsbClassControllerNotify& aOwner)
+	: CUsbClassControllerPlugIn(aOwner, KObexStartupPriority)
+	{
+	}
+
+
+
+/**
+ * 2nd Phase Construction.
+ */
+void CUsbObexClassController::ConstructL()
+	{
+	}
+
+
+
+/**
+ * Called by UsbMan when it wants to start the USB Obex class. 
+ * Data member from RSessionBase implements a Start call on the
+ * Obex Server process.
+ * 
+ * @param aStatus The caller's request status, filled in with an error code
+ */
+void CUsbObexClassController::Start(TRequestStatus& aStatus)
+	{
+	//Start() should never be called if started, starting or stopping (or in state EUsbServiceFatalError)
+	__ASSERT_DEBUG( iState == EUsbServiceIdle, User::Panic(KObexCcPanicCategory, EBadApiCallStart) );
+
+	TRequestStatus* status = &aStatus;
+	TInt err;
+	iState = EUsbServiceStarting;
+
+	err = iClassContClient.Connect(); // Connect to the Server Session
+	if (err != KErrNone)
+		{
+		iState = EUsbServiceFatalError;
+		User::RequestComplete(status, err);
+		}
+	else
+		{
+		err = iClassContClient.StartService(); // Call function to implement Obex Server
+		if (err != KErrNone)
+			{
+			iState = EUsbServiceFatalError;
+			User::RequestComplete(status, err);
+			}
+		else
+			{
+			iState = EUsbServiceStarted;
+			User::RequestComplete(status,KErrNone);
+			}
+		}
+
+	}
+
+/**
+ * Called by UsbMan when it wants to stop the USB Obex class.
+ * Data member from RSessionBase implements a Stop call on
+ * the Obex Server process.
+ *
+ * @param aStatus The caller's request status: always set to KErrNone
+ */
+void CUsbObexClassController::Stop(TRequestStatus& aStatus)
+	{
+	
+	//Stop() should never be called if stopping, idle or starting (or in state EUsbServiceFatalError)
+	__ASSERT_DEBUG( iState == EUsbServiceStarted, User::Panic(KObexCcPanicCategory, EBadApiCallStop) );
+	
+	TRequestStatus* status = &aStatus;
+	TInt err;
+	iState = EUsbServiceStopping;
+
+	err = iClassContClient.StopService();
+	if (err != KErrNone)
+		{
+		iState = EUsbServiceFatalError;
+		User::RequestComplete(status, err);
+		}
+	else
+		{	
+		iState = EUsbServiceIdle;
+		User::RequestComplete(status, KErrNone);
+		}
+			
+	}
+
+/**
+ * Gets information about the descriptor which this class provides.
+ *
+ * @param aDescriptorInfo Descriptor info structure filled in by this function
+ */
+void CUsbObexClassController::GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const
+	{
+	aDescriptorInfo.iNumInterfaces = KNumObexInterfaces;
+	aDescriptorInfo.iLength = KObexDescriptorLength;
+	}
+
+
+
+/**
+ * Standard active object RunL. Never called because this class has no
+ * asynchronous requests. As it is never called, function causes a panic.
+ */
+void CUsbObexClassController::RunL()
+	{
+	__ASSERT_DEBUG(EFalse, User::Panic(KObexCcPanicCategory, EUnusedFunction));
+	}
+
+/**
+ * Standard active object cancellation function. Never called because this
+ * class has no asynchronous requests. As it is never called, function causes a panic.
+ */
+void CUsbObexClassController::DoCancel()
+	{
+	__ASSERT_DEBUG(EFalse, User::Panic(KObexCcPanicCategory, EUnusedFunction));
+	}
+
+
+/**
+ * Standard active object error-handling function. 
+ *
+ * Should return KErrNone to avoid an active scheduler panic. This function
+ * should never be called as there is another mechanism for catching errors.
+ */
+TInt CUsbObexClassController::RunError(TInt /*aError*/)
+	{	
+	__ASSERT_DEBUG(EFalse, User::Panic(KObexCcPanicCategory, EUnusedFunction));
+	return KErrNone;
+	}
+	
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/src/CUsbObexClassImpCollection.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* 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 "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:
+* Defines the implementation collection for the Obex class controller.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32base.h>
+#include <e32std.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include "CUsbObexClassController.h"
+
+
+// Define the private interface UIDs
+const TImplementationProxy UsbCCImplementationTable[] =
+    {
+	IMPLEMENTATION_PROXY_ENTRY(0x10274339, CUsbObexClassController::NewL),
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(UsbCCImplementationTable) / sizeof(TImplementationProxy);
+
+    return UsbCCImplementationTable;
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/ObexClassController/src/obexusbman.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,72 @@
+/*
+* 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 "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:
+* Resource file for usbman configuration.
+* This file is needed when implementing Obex over USB.
+* This file needs to be placed in usbman\src\ and a new build needs 
+* to be made.
+*
+*/
+
+/**
+ @file
+*/
+
+NAME USBM
+
+#include <badef.rh>
+#include "usbman.rh"
+
+#ifdef LANGUAGE_01 			// UK English  
+ 	#include "usbman_01.rls"	
+#elif LANGUAGE_02 	 		// French  
+ 	#include "usbman_02.rls"	
+#elif defined LANGUAGE_03  		// German
+ 	#include "usbman_03.rls"
+#elif defined LANGUAGE_10  		// US English
+ 	#include "usbman_10.rls"
+#endif      
+
+RESOURCE BA_RSS_SIGNATURE
+	{
+	signature = 1;
+	}
+
+RESOURCE usb_configuration usb_config
+	{
+	}
+	
+		
+RESOURCE PERSONALITY_ARRAY device_personalities
+	{
+	personalities = 
+		{
+		PERSONALITY
+			{
+			bDeviceClass = 02;
+			bDeviceSubClass = 0;
+			protocol = 0;
+			numConfigurations = 1;
+			vendorId = 0x0e22;
+			productId = 0x000c;
+			bcdDevice = 0;
+			manufacturer = per_manufacturer1;
+			product = per_product1;
+			id = 1;					
+			class_uids = "101fbf24, 10274339";    			
+			description = per_description1;
+			}
+		};
+	}
+			
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,22 @@
+/*
+* 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 "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 "ClassControllerClientSession/group/bld.inf"
+#include "ClassControllerServerSession/group/bld.inf"
+#include "ObexClassController/group/bld.inf"
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/ObexUsbClassController/public/clientServerShared.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,49 @@
+/*
+* 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 "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:
+* This is the Shared header needed for implementing the Obex Class Controller
+* configuration.
+*
+*/
+
+#include <e32base.h>
+// server name
+
+_LIT(KServerName,"ObexServer");
+
+// Server location
+
+_LIT(KServerExe,"z:\\sys\\bin\\classControllerServerSession.exe");
+
+const TUint32 KObexCCUidTUint = 0x10281916;
+const TUid KObexCCUid = {KObexCCUidTUint};
+
+
+// A version must be specifyed when creating a session with the server
+
+const TUint KMajorVersionNumber=1;
+const TUint KMinorVersionNumber=0;
+const TUint KBuildVersionNumber=0;
+const TInt KMessageSlots=-1;
+
+/**
+ * Declaration of function
+ */
+IMPORT_C TInt StartThread(RThread& aServerThread);
+
+enum TServRqst
+	{
+	EStartClassContServer,
+	EStopClassContServer
+	};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,20 @@
+/*
+* 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 "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 "ObexUsbClassController/bld.inf"
+#include "test/group/bld.inf"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/group/Bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 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:
+*
+*/
+// BLD.INF
+//
+PRJ_TESTMMPFILES
+
+simpleObexApp.mmp
+
+
+PRJ_TESTEXPORTS
+
+simpleObexApp.IBY 		/epoc32/rom/include/simpleobexapp.iby
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/group/simpleObexApp.IBY	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,22 @@
+/*
+* 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 "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=ABI_DIR\BUILD_DIR\simpleObexApp.exe	         Sys\bin\simpleObexApp.exe
+
+data=E:\personal\SimpleObexApplication\Contactsbak.vcf			private\00000000\Contactsbak.vcf
+data=E:\personal\SimpleObexApplication\Contactsbak2.vcf			private\00000000\Contactsbak2.vcf
+data=E:\personal\SimpleObexApplication\Contactsbak3.vcf			private\00000000\Contactsbak3.vcf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/group/simpleObexApp.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,55 @@
+/*
+* 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 "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:
+*
+*/
+
+
+
+TARGET        simpleobexapp.exe
+TARGETTYPE    exe
+UID           0
+VENDORID 	  0x70000001
+
+SOURCEPATH    ../src
+SOURCE        simpleObexApp.cpp
+SOURCE		  simpleObexClient.cpp
+SOURCE		  simpleObexServer.cpp
+
+USERINCLUDE   ../inc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY		euser.lib 
+LIBRARY		efsrv.lib // Library for RFile and RFs
+LIBRARY		esock.lib 
+LIBRARY		obex.lib 
+LIBRARY		bafl.lib // Library for file handling service
+LIBRARY 	c32.lib // Library for serial comms
+// ONLY FOR IRDA:
+LIBRARY		irda.lib 
+// ONLY FOR BLUETOOTH:
+LIBRARY		bluetooth.lib 
+LIBRARY		btmanclient.lib 
+LIBRARY		sdpdatabase.lib 
+LIBRARY		sdpagent.lib 
+// Only for USB:
+LIBRARY		usbman.lib 
+
+// At least one of these two must be uncommented:
+MACRO TRANSPORT_BLUETOOTH  // Comment this out if OBEX is not to be used over Bluetooth
+MACRO TRANSPORT_IRDA // Comment this out if OBEX is not to be used over IrDA
+
+CAPABILITY All -Tcb 
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/inc/Contactsbak.vcf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,7 @@
+BEGIN:VCARD
+VERSION:2.1
+REV:20020312T103257Z
+UID:1000118a25d0b113-e079ae8022476c-158
+ADR;WORK:;;3 Ely Road;Milton;Cambridgeshire;CB4 6AA;UK
+ORG:Symbian Cambridge;
+END:VCARD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/inc/Contactsbak2.vcf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,7 @@
+BEGIN:VCARD
+VERSION:2.1
+REV:20020312T103555Z
+UID:1000118a25d0b113-e079ae8b82cce4-159
+ADR;WORK:;;2-6 Boundary Row;Southwark;London;SE1 8HP;UK
+ORG:Symbian International Headquarters;
+END:VCARD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/inc/Contactsbak3.vcf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,7 @@
+BEGIN:VCARD
+VERSION:2.1
+REV:20020312T103832Z
+UID:1000118a25d0b113-e079ae94deab2d-160
+ADR;WORK:;;Soft Center;Ronneby;;SE-372 25;Sweden
+ORG:Symbian Ronneby;
+END:VCARD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/inc/obexAppConstants.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,73 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef OBEXAPPCONSTANTS_H
+#define OBEXAPPCONSTANTS_H
+
+/**
+ * This file defines the constants that are used in the simpleObexApp
+ * program.
+ */
+
+/* 
+ Casira address for OBEX over Bluetooth
+ This value needs to be changed
+ to the address that your OBEX server will listen on
+ */
+const TBTDevAddr devAddr(MAKE_TINT64(0x0002, 0x5b019a36));	
+/* The UUID for FTP in SDP. */
+const TUUID ftpUuid(0x1106);
+
+/* This defines the size to expand the buffer by when additional space is required */
+const TUint KBufExpandSize=8;
+const TUint KServerBufExpandSize=500;
+
+/* Service name attribute is offset with the language base value */
+const TUint KSdpAttrIdServiceName=KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName;
+
+/* This value is used as when a port is found it will be between 0 - 30 */
+const TUint8 KNotAPort = 0xFF;
+const TUint KNoPort = 0;
+
+/* Obex test port value */
+static const TUint8 KObexTestPort = 17;
+/* RFCOMM protocol UUID, not in btsdp.h at time of writing */ 
+static const TInt KRfcommUuid = 0x0003;
+/* Obex Protocol UUID, not in btsdp.h at time of writing */
+static const TInt KObexProtocolUuid = 0x0003;
+
+
+/* String Literals used in application */
+_LIT(KObjectType,"text/x-vcard");
+_LIT(KClientInterfaceDescriptor,"Client Interface");
+_LIT(KServerInterfaceDescriptor,"Server Interface");
+_LIT8(KIrdaTransportAttrName, "IrDA:TinyTP:LsapSel");
+_LIT(KFilePath1,"Z:\\private\\00000000\\Contactsbak.vcf");
+_LIT(KFilePath2,"Z:\\private\\00000000\\Contactsbak2.vcf");
+_LIT(KFilePath3,"Z:\\private\\00000000\\Contactsbak3.vcf");
+_LIT(KFilename1,"Contacts.vcf");
+_LIT(KFilename2,"Contacts2.vcf");
+_LIT(KFilename3,"Contacts3.vcf");
+_LIT(KAlreadyActive,"\r\nError: Client handler already active\r\n");
+_LIT8(KIrdaClassName, "OBEX");
+_LIT8(KLocalInfoAppend," EikIrOBEXFile ");
+_LIT(KAuthPassword,"password");
+_LIT8(KServerDesC,"File transfer server");
+
+#define EPOCIDENT _L8("EPOC32 ER5")
+
+#endif // OBEXAPPCONSTANTS_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/inc/simpleObexApp.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,105 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef SIMPLEOBEXAPP_H
+#define SIMPLEOBEXAPP_H
+
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <obex.h>
+#include <btsdp.h>
+#include <d32usbc.h>
+
+
+
+#ifdef __WINS__
+_LIT(KWinsPddName,"ecdrv");
+_LIT(KWinsLddName,"ecomm");
+#endif //__WINS__
+
+
+_LIT(KEusbc,"EUSBC");
+
+
+enum Mode
+	{
+	E_Inactive,
+	E_Server,
+	E_Server_File,
+	E_Client,
+	E_Client_Connect_Menu,
+	E_Client_Setup_Menu,
+	E_SdpQuery
+
+	};
+
+enum TTransport
+	{
+	EBluetooth,
+	EIrda,
+	EUsb,
+	EWin32Usb
+	};
+
+
+
+class CObexClientHandler;
+class CObexServerHandler;
+
+
+
+
+/**
+ * CActiveConsole is a CActive derived class, it is used to provide
+ * a means for the user to interact with the OBEX application. It provides
+ * a test shell menu for the user to select options from, it is also responsible for 
+ * initialising user selected processes.
+ */
+
+class CActiveConsole : public CActive
+	{
+	public:
+		static CActiveConsole* NewLC(CConsoleBase* aConsole);
+		~CActiveConsole();
+
+		void DoCancel();
+		void RunL();
+		void RequestCharacter();
+		void ProcessKeyPressL(TChar aChar);
+		void DoUsbInitialisationL();
+		
+		CConsoleBase* Console();
+	private:
+		void ConstructL();
+		CActiveConsole(CConsoleBase* aConsole);
+
+	public:
+		// Data members defined by this class
+		CConsoleBase*    iConsole;					// A console for reading from
+		CObexClientHandler*  iObexClientHandler;	// Client wrapper for CObexClient
+		CObexServerHandler*  iObexServerHandler;	// Client wrapper for CObexServer
+		TUint iMode;
+		TTransport iTransport;
+		RDevUsbcClient iUsbDriver;
+
+	};
+	
+
+	
+
+#endif // SIMPLEOBEXAPP_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/inc/simpleObexAppConstants.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,72 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef SIMPLEOBEXAPPCONSTANTS_H
+#define SIMPLEOBEXAPPCONSTANTS_H
+
+/**
+ * This file defines the constants that are used in the simpleObexApp
+ * program.
+ */
+
+/* 
+ Casira address for OBEX over Bluetooth
+ This value needs to be changed
+ to the address that your OBEX server will listen on
+ */
+TBTDevAddr devAddr(MAKE_TINT64(0x0002, 0x5b019a36));	
+/* The UUID for FTP in SDP. */
+TUUID ftpUuid(0x1106);
+
+/* This defines the size to expand the buffer by when additional space is required */
+const TUint KBufExpandSize=8;
+const TUint KServerBufExpandSize=500;
+
+/* Service name attribute is offset with the language base value */
+const TUint KSdpAttrIdServiceName=KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName;
+
+/* This value is used as when a port is found it will be between 0 - 30 */
+const TUint8 KNotAPort = 0xFF;
+const TUint KNoPort = 0;
+/* Obex test port value */
+static const TUint8 KObexTestPort = 17;
+/* RFCOMM protocol UUID, not in btsdp.h at time of writing */ 
+static const TInt KRfcommUuid = 0x0003;
+/* Obex Protocol UUID, not in btsdp.h at time of writing */
+static const TInt KObexProtocolUuid = 0x0003;
+
+
+/* String Literals used in application */
+_LIT(KObjectType,"text/x-vcard");
+_LIT(KClientInterfaceDescriptor,"Client Interface");
+_LIT(KServerInterfaceDescriptor,"Server Interface");
+_LIT8(KIrdaTransportAttrName, "IrDA:TinyTP:LsapSel");
+_LIT8(KIrdaClassName, "OBEX");
+_LIT8(KLocalInfoAppend," EikIrOBEXFile ");
+_LIT(KFilePath1,"Z:\\private\\00000000\\Contactsbak.vcf");
+_LIT(KFilePath2,"Z:\\private\\00000000\\Contactsbak2.vcf");
+_LIT(KFilePath3,"Z:\\private\\00000000\\Contactsbak3.vcf");
+_LIT(KFilename1,"Contacts.vcf");
+_LIT(KFilename2,"Contacts2.vcf");
+_LIT(KFilename3,"Contacts3.vcf");
+_LIT(KAlreadyActive,"\r\nError: Client handler already active\r\n");
+_LIT(KAuthPassword,"password");
+_LIT8(KServerDesC,"File transfer server");
+
+#define EPOCIDENT _L8("EPOC32 ER5")
+
+#endif // SIMPLEOBEXAPPCONSTANTS_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/inc/simpleObexClient.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,143 @@
+/*
+* 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 "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:
+*
+*/
+
+
+#ifndef SIMPLEOBEXCLIENT_H
+#define SIMPLEOBEXCLIENT_H
+
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <obex.h>
+#include <btsdp.h>
+#include "simpleObexApp.h"
+
+
+
+class CRFCOMMServiceFinder;
+	
+
+/**
+ * MRFCOMMServiceSeeker is a mixin class that contains a virtual function,
+ * SearchResult, that is overridden by the SearchResult funtion in the
+ * CObexClientHandler class. 
+ *
+ */
+class MRFCOMMServiceSeeker
+	{
+	public:
+		virtual void SearchResult(TInt aError, TUint8 aPort)=0;	// user implemented
+	};
+	
+
+
+/**
+ * CObexClientHandler is a wrapper class that is responsible for dealing
+ * with an OBEX client. It implements MRFCOMMServiceSeeker to deal with
+ * Bluetooth searches on other OBEX devices.
+ *
+ */
+class CObexClientHandler : public CActive, public MRFCOMMServiceSeeker
+	{
+	public:
+		static CObexClientHandler* NewL(CActiveConsole* aParent, TTransport aTransport);
+		~CObexClientHandler();
+		
+		void SetMode(TUint mode);
+		void Connect();
+		void Disconnect();
+		void GetByNameL();
+		void Put(TDes& filename);
+		void SetName(TDes& aName);
+		void SearchResult(TInt aError, TUint8 aPort);
+
+		void ConnectWithAuthenticationL();
+
+	private:
+		void ConstructL(TTransport aTransport);
+		CObexClientHandler(CActiveConsole* aParent);
+		void RunL ();
+		void DoCancel ();
+		TInt SetUpObjectFromFile (TDes& filename);
+		void DisplayObjectInformation();
+
+	public:
+		TBuf<64> iObexName;
+		TBuf<64> iFilename1;
+		TBuf<64> iFilename2;
+		TBuf<64> iFilename3;
+		TBuf<32> iSessionPath;	
+		TBuf<16> iChallengePassword;
+		TBuf<16> iResponsePassword;
+		TBuf<32> iGetType;
+	private:
+		enum TSendState
+			{
+			EIdle,
+			EConnecting,
+			EConnected,
+			EPutting,
+			EGetting,
+			EDisconnecting
+			};
+
+		CActiveConsole* iParent;
+		CObexClient* iClient;
+		CObexFileObject* iFileObject;
+		CObexBufObject* iObject;
+		CBufFlat* iObjectBuffer;
+		TSendState iState;
+		CObexNullObject* iTargetHeaderObject;
+		CRFCOMMServiceFinder* iSdpServiceFinder;
+		TBTDevAddr iDevAddr;
+
+	};
+	
+
+/**
+ * CRFCOMMServiceFinder is the clas that is responsible for searching the SDP
+ * records of a specified device (by address) to see if OBEX FTP is supported
+ *
+ */	
+class CRFCOMMServiceFinder : public CBase, public MSdpAgentNotifier
+	{
+	public:
+		static CRFCOMMServiceFinder* NewL(	const TUUID& aServiceClass,const TBTDevAddr& aDevAddr,MRFCOMMServiceSeeker& aSeeker);
+		~CRFCOMMServiceFinder();
+
+		void FindPortL();	//Starts the search
+
+		
+		// MSdpAgentNotifier functions
+		void NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount);
+		void AttributeRequestResult(TSdpServRecordHandle,TSdpAttributeID,CSdpAttrValue*) {User::Panic(_L("RFCOMMSEEK"), 0);} // Not using this API form
+		void AttributeRequestComplete(TSdpServRecordHandle aHandle, TInt aError);
+
+	private:
+		CRFCOMMServiceFinder(MRFCOMMServiceSeeker& aSeeker);
+		void ConstructL(const TBTDevAddr& aDevAddr, const TUUID& aServiceClass);
+
+	private:
+		CSdpAgent* iAgent;
+		CSdpSearchPattern* iPattern;
+		TBool iFoundRFCOMMUUID;
+		TUint8 iPort;
+		MRFCOMMServiceSeeker& iSeeker;//initialised from aSeeker in the constructor
+		CActiveConsole* iParent;
+	};
+	
+#endif // SIMPLEOBEXCLIENT_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/inc/simpleObexServer.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,95 @@
+/*
+* 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 "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:
+*
+*/
+
+
+#ifndef SIMPLEOBEXSERVER_H
+#define SIMPLEOBEXSERVER_H
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <obex.h>
+#include <btsdp.h>
+#include "simpleObexApp.h"
+
+
+/**
+ * CObexServerHandler is a wrapper class that is responsible for setting up 
+ * and managing an OBEX Server. It implements MObexServerNotify as an interface 
+ * as is required to start an OBEX server.
+ *
+ */
+	
+class CObexServerHandler : public CBase, private MObexServerNotify
+	{
+	public:
+		static CObexServerHandler* NewL(CActiveConsole* aParent, TTransport aTransport);
+		
+		void Stop();
+		~CObexServerHandler();
+
+		void EnableAuthenticationL();
+		void DisableAuthentication();
+	
+	private:
+		CObexServerHandler(CActiveConsole* aParent);
+		void ConstructL(TTransport aTransport);
+
+		// Implementation of MObexServerNotify interface
+		virtual void ErrorIndication (TInt aError);
+		virtual void TransportUpIndication ();
+		virtual void TransportDownIndication ();
+		virtual TInt ObexConnectIndication  (const TObexConnectInfo& aRemoteInfo, const TDesC8& aInfo);
+		virtual void ObexDisconnectIndication (const TDesC8& aInfo);
+		virtual CObexBufObject* PutRequestIndication ();
+		virtual TInt PutPacketIndication ();
+		virtual TInt PutCompleteIndication ();
+		virtual CObexBufObject* GetRequestIndication (CObexBaseObject *aRequestedObject);
+		virtual TInt GetPacketIndication ();
+		virtual TInt GetCompleteIndication ();
+		virtual TInt SetPathIndication (const CObex::TSetPathInfo& aPathInfo, const TDesC8& aInfo);
+		virtual void AbortIndication ();
+
+		void SetUpGetObjectL(CObexBaseObject *aRequestedObject);
+
+	public:
+		TBuf<16> iChallengePassword;
+		TBuf<16> iResponsePassword;
+		TBool iAcceptPuts;
+
+
+	private:
+		CActiveConsole* iParent;
+		CObexServer*  iServer;
+		CObexBufObject*  iObject;
+		CBufFlat *iBuf;
+		TTransport iTransportLayer;
+		TBuf<32> iSessionPath;	
+		
+		RSdp iSdp;
+		RSdpDatabase iSdpdb;
+		CSdpAttrValueDES* iProtDescList;
+	
+		TBool iBuffering;
+		TBool iUseRFile;
+		RFs iFs;
+		RFile iFile;
+		TBool iIsAuthenticationEnabled;
+
+	};
+	
+	
+#endif // SIMPLEOBEXSEVER_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/src/simpleObexApp.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,509 @@
+/*
+* 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 "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 <e32base.h>
+#include <c32comm.h>
+
+#include <usbman.h>
+
+#include "simpleObexApp.h"
+#include "simpleObexClient.h"
+#include "simpleObexServer.h"
+
+
+// Define Physical Device Driver and Logical Device Driver
+// for device.
+
+
+
+/**
+ * Constructor.
+ */
+CActiveConsole::CActiveConsole(CConsoleBase* aConsole) 
+	: CActive(CActive::EPriorityStandard),
+	  iConsole(aConsole),
+	iMode(E_Inactive)
+
+	{
+	}
+
+/**
+ * NewLC function, calls 2nd phase constructor.
+ */
+CActiveConsole* CActiveConsole::NewLC(CConsoleBase* aConsole)
+    {
+    CActiveConsole* self = new (ELeave) CActiveConsole(aConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+    return self;
+    }
+
+
+/**
+ * 2nd phase construction.
+ */
+void CActiveConsole::ConstructL ()
+    { 
+      
+    CActiveScheduler::Add(this);// Add to active scheduler
+
+    }
+
+
+
+/**
+ * Destructor.
+ */
+CActiveConsole::~CActiveConsole()
+	{
+	// Make sure we're cancelled
+	Cancel();
+
+	// safe to delete NULL
+	
+    if(iObexClientHandler)
+		delete iObexClientHandler;
+    if(iObexServerHandler)
+		delete iObexServerHandler;
+ 
+	}
+
+/**
+ * RequestCharacter function, this is responsible for diplasying a menu to the user.
+ */
+void CActiveConsole::RequestCharacter()
+    {
+    
+		if (iMode == E_Inactive) 
+		{	
+			// Initial menu
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|~~~~~~~~~~~~~~~~~OBEX~~~~~~~~~~~~~~~~~|\n"));
+			iConsole->Printf(_L("---------------------------------------\n"));
+			iConsole->Printf(_L("|-----------Bluetooth options----------|\n"));
+			iConsole->Printf(_L("---------------------------------------\n"));
+			iConsole->Printf(_L("| 1 - Start Obex Server over Bluetooth |\n"));
+			iConsole->Printf(_L("| 2 - Start Obex Client over Bluetooth |\n"));
+			iConsole->Printf(_L("---------------------------------------\n"));
+			iConsole->Printf(_L("|-------------IrDA options-------------|\n"));
+			iConsole->Printf(_L("---------------------------------------\n"));
+			iConsole->Printf(_L("|   3 - Start Obex Server over IrDA    |\n"));
+			iConsole->Printf(_L("|   4 - Start Obex Client over IrDA    |\n"));
+			iConsole->Printf(_L("---------------------------------------\n"));
+			iConsole->Printf(_L("|--------------USB options-------------| \n"));
+			iConsole->Printf(_L("---------------------------------------\n"));
+			iConsole->Printf(_L("|    5 - Start Obex Server over USB    |\n"));
+			iConsole->Printf(_L("|    6 - Start Obex Client over USB    |\n"));
+			iConsole->Printf(_L("---------------------------------------\n"));
+		
+		}
+		
+		if (iMode == E_Server)
+			{
+			// Menu displayed when Start server is called
+			iConsole->Printf(_L("\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|~~~~~~~~~OBEX_SERVER_OPTIONS~~~~~~~~~~|\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|   S - Stop and kill the Obex Server  |\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|      1 - Enable authentication       |\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|      2 - Disable authentication      |\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			}
+		
+		
+		
+		if (iMode == E_Client)
+			{
+			// Menu displayed when start client is started
+			iConsole->Printf(_L("\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|~~~~~~~~~OBEX_CONNECT_OPTIONS~~~~~~~~~|\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|        1  -  OBEX connect menu       |\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|         2  -  Disconnect Obex        |\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|    3  -  Obex Put obj 1 : %S |\n"), &(iObexClientHandler->iFilename1));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|    4  -  Obex Put obj 2 : %S |\n"), &(iObexClientHandler->iFilename2));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|    5  -  Obex Put obj 3 : %S |\n"), &(iObexClientHandler->iFilename3));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|       6  -  Obex Get by name         |\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			}
+		
+		
+		
+		if (iMode == E_Client_Connect_Menu )
+			{
+			// Obex connect menu
+			iConsole->Printf(_L("\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|~~~~~~~~~~~OBEX_CONNECT_MENU~~~~~~~~~~|\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|       0  -  IrObex Disconnect        |\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|         1  -  IrObex Connect         |\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|   2  -  Connect with Authentication  |\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			iConsole->Printf(_L("|     s  -  Back to Client Menu        |\n"));
+			iConsole->Printf(_L("----------------------------------------\n"));
+			}
+		
+		
+		iConsole->Printf(_L("press Escape to quit\r\n\r\n"));
+    	iConsole->Read(iStatus); 
+    	SetActive();
+    	
+    }
+
+
+/**
+ * The active object DoCancel function
+ */
+void  CActiveConsole::DoCancel()
+    {
+    iConsole->ReadCancel();
+    }
+    
+ 
+
+/**
+ * The active object RunL function. It is responsible for routing the users
+ * selection by calling the ProcessKeyPressL function.
+ */
+void  CActiveConsole::RunL()
+    {
+    TUint oldMode = iMode;
+	TRAPD(err,ProcessKeyPressL(TChar(iConsole->KeyCode())));
+	if(err != KErrNone)
+		{
+		iConsole->Printf(_L("Failed. Error: %d\r\n"),err);
+		// Put the test mode back again
+		iMode = oldMode;
+		RequestCharacter();
+		}	
+    }
+
+
+/**
+ * This function is called after the user has made a selection.
+ */
+void CActiveConsole::ProcessKeyPressL(TChar aChar)
+    {
+    
+    if (aChar == EKeyEscape)
+		{
+		CActiveScheduler::Stop();
+		return;
+		}
+		
+	else if (iMode == E_Inactive)
+		{
+		switch(aChar)
+			{
+			case '1':
+				//Obex Server over Bluetooth
+				iMode = E_Server;
+				iTransport = EBluetooth;
+				iObexServerHandler = CObexServerHandler::NewL(this, EBluetooth);
+				break;
+			
+			case '2':
+				//Obex Client over Bluetooth
+				iMode = E_SdpQuery;
+				iTransport = EBluetooth;
+				iObexClientHandler = CObexClientHandler::NewL(this, EBluetooth);
+				break;
+			
+			case '3':
+			
+				//Obex server over IrDA
+				iMode = E_Server;
+				iTransport = EIrda;
+				iObexServerHandler = CObexServerHandler::NewL(this, EIrda);
+				break;
+			
+			case '4':
+				//Obex client over IrDA
+				iMode = E_Client;
+				iTransport = EIrda;
+				iObexClientHandler = CObexClientHandler::NewL(this, EIrda);
+				break;
+			
+			case '5':
+				{
+				// Obex server over USB.
+				iMode = E_Server;
+				
+				#ifdef __WINS__
+					// If starting usb on PC emulator side
+					iTransport = EWin32Usb;
+					iObexServerHandler = CObexServerHandler::NewL(this, EWin32Usb);
+				#else
+					// This is where the Class controller code provided is implemented	
+					RUsb usb;
+					TRequestStatus status;
+					TInt obexPersonality = 1;
+					User::LeaveIfError(usb.Connect());
+					// Start the OBEX personality that will
+					// start up an OBEX server.
+					usb.TryStop(status);
+					User::WaitForRequest(status);
+					usb.TryStart(obexPersonality, status);
+					User::WaitForRequest(status);
+	
+				#endif
+				}
+				break;
+			case '6':
+				{
+				iMode = E_Client;
+				
+				#ifdef __WINS__
+					// If starting client on PC emulator
+					iTransport = EWin32Usb;
+					iObexClientHandler = CObexClientHandler::NewL(this, EWin32Usb);
+				#else
+					iTransport = EUsb;
+					DoUsbInitialisationL();
+					iObexClientHandler = CObexClientHandler::NewL(this, EUsb);
+					User::LeaveIfError(iUsbDriver.DeviceConnectToHost());// Plugin driver
+					iUsbDriver.Close();
+				#endif
+				}
+			default:
+				break; 
+			
+			}
+		
+		}
+	
+	else if (iMode == E_Client_Connect_Menu )
+		{
+		switch (aChar)
+			{
+			case '0':
+				// Disconnect Obex connection
+				iObexClientHandler->Disconnect();
+				break;
+		
+			case '1':
+				// Start Obex connection
+				iObexClientHandler->Connect();
+				break;
+		
+			case '2':
+			// Start Obex connection with authentication
+			iObexClientHandler->ConnectWithAuthenticationL();		
+			
+			default:
+				iMode = E_Client;
+				break;
+			}
+		}
+		
+	else if (iMode == E_Server)
+		{
+		switch(aChar)
+			{
+			case 's':
+				// Stop the Obex server
+				iObexServerHandler->Stop();
+				break;
+			
+			case '1':
+				// Force authenication
+				iObexServerHandler->EnableAuthenticationL();
+				break;
+			
+			case '2':
+				// Stop the need to authenicate
+				iObexServerHandler->DisableAuthentication();
+			
+			default:
+				break;
+		
+			}
+		
+		
+		}
+		
+	else if (iMode == E_Client)
+		{
+		switch(aChar)
+			{
+		
+			case '1':
+				iMode = E_Client_Connect_Menu;				
+				break;
+			
+			case '2':
+				// Disconnect client and server link
+				iObexClientHandler->Disconnect();
+				break;
+			
+			case '3':
+				// Put iFilename1 object
+				iObexClientHandler->Put(iObexClientHandler->iFilename1);
+				break;
+			
+			case '4':
+				// Put iFilename2 object
+				iObexClientHandler->Put(iObexClientHandler->iFilename2);
+				break;
+			
+			case '5':
+				// Put iFilename3 object
+				iObexClientHandler->Put(iObexClientHandler->iFilename3);
+				break;
+			
+			case '6':
+				// Call get by name on active object
+				iObexClientHandler->GetByNameL();
+			default:
+				break;
+			
+			}
+		}
+	
+	else 
+		{
+		CActiveScheduler::Stop();
+		return;
+		}
+	// Dislpay next menu
+	RequestCharacter ();
+	return;
+    
+    }
+
+
+/**
+ * Function used in creating a new active console.
+ */
+CConsoleBase* CActiveConsole::Console()
+	{
+	return iConsole;
+	}
+
+
+void CActiveConsole::DoUsbInitialisationL()
+	{
+	// Before creating an Obex client or server some initialisation
+	// is needed. 
+		
+	// Load the USB device driver
+	User::LeaveIfError(User::LoadLogicalDevice(KEusbc));
+		
+	// Now connect to USBmanager		
+	RUsb usb;
+	User::LeaveIfError(usb.Connect());
+	iConsole->Printf(_L("Connected to USB\n"));
+	// Before starting the WHCM USB personality foe OBEX
+	// we need to stop the current personality.
+	TRequestStatus status;
+	usb.TryStop(status);
+	User::WaitForRequest(status);
+	User::LeaveIfError(status.Int());
+	// Now we want to start the WHCM personality
+	const TUint KWhcmPersonality=2;
+	usb.TryStart(KWhcmPersonality, status);
+	User::WaitForRequest(status);
+			
+	iConsole->Printf(_L("Starting USB returned %d\n"), status.Int());
+	User::LeaveIfError(status.Int());
+	// We are now finished with Usb manager so close. 
+	usb.Close();
+		
+	// We now need to open a channel to a client driver
+	User::LeaveIfError(iUsbDriver.Open(0));
+	// Unplug driver to allow for a new CObexClient to be created.
+	User::LeaveIfError(iUsbDriver.DeviceDisconnectFromHost());
+
+	}
+
+/**
+ * This is the function called by the entry point code.
+ * It exists to perform initialisation
+ *
+ */
+void RunAppL(void)
+	{
+
+	CActiveScheduler *myScheduler = new (ELeave) CActiveScheduler();
+	CleanupStack::PushL(myScheduler);
+	CActiveScheduler::Install(myScheduler); 
+
+	CConsoleBase* aConsole = 	
+	Console::NewL(_L("Obex Program"),TSize(KConsFullScreen, KConsFullScreen));
+	
+	// Load Device drivers
+	
+	TInt err;
+	// Start C32 now
+	aConsole->Printf(_L("Loading C32...\n"));
+	err=StartC32();
+	if (err!=KErrNone && err!=KErrAlreadyExists)
+		aConsole->Printf(_L("	Failed %d\n"), err);
+	else
+		aConsole->Printf(_L("	Sucess\n"));
+	// If running on PC emulator
+	
+	// Load drivers for using Serial communication
+	#ifdef __WINS__
+		TInt load =	User::LoadLogicalDevice(KWinsLddName);
+		aConsole->Printf(_L("Load LDD : %d\n"), load);
+		load =	User::LoadPhysicalDevice(KWinsPddName);
+		aConsole->Printf(_L("Load PDD : %d\n"), load);
+	#endif //__WINS__
+
+
+
+	CleanupStack::PushL(aConsole);
+	CActiveConsole* my_console = CActiveConsole::NewLC(aConsole);// New active console
+	my_console->RequestCharacter();
+	CActiveScheduler::Start();
+	CleanupStack::PopAndDestroy(3); 
+	
+	}
+
+
+
+
+/**
+ * The E32main function is the main entry point for the
+ * code.
+ */
+
+TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
+	TRAPD(error,RunAppL()); // more initialization, then do example
+	__ASSERT_ALWAYS(!error,User::Panic(_L("Simple OBEX Application"),error));
+	delete cleanup; // destroy clean-up stack
+	__UHEAP_MARKEND;
+
+	return 0; // and return
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/src/simpleObexClient.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,585 @@
+/*
+* 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 "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 <e32base.h>
+
+#include <bautils.h>
+#include <obexconstants.h>
+#include "simpleObexClient.h"
+#include "simpleObexApp.h"
+#include "obexAppConstants.h"
+
+
+
+/**
+ * Constructor, ownership of Console is passed.
+ */
+CObexClientHandler::CObexClientHandler(CActiveConsole* aParent)
+    : CActive(CActive::EPriorityStandard),
+      iParent(aParent)
+    {
+    iClient    = NULL;
+    iObject    = NULL;
+    iState     = EIdle;
+    }
+
+
+/**
+ * NewL function.
+ */
+CObexClientHandler* CObexClientHandler::NewL(CActiveConsole* aParent, TTransport aTransport)
+    {
+    CObexClientHandler* self = new (ELeave) CObexClientHandler(aParent);
+
+    CleanupStack::PushL (self);
+    self->ConstructL(aTransport);
+    CActiveScheduler::Add (self);
+    CleanupStack::Pop ();
+    return (self);
+    }
+
+
+/**
+ * 2nd phase constructor. Responsible for determining which
+ * transport has been selected and to create a new OBEX Client.
+ */
+void CObexClientHandler::ConstructL(TTransport aTransport)
+    {
+	
+	// Construct client if bluetooth selected
+	if (aTransport == EBluetooth)
+		{
+		iDevAddr = devAddr;  // take the Bluetooth address
+
+		//start the SDP Query
+		delete iSdpServiceFinder;
+		iSdpServiceFinder=0;
+		iSdpServiceFinder = CRFCOMMServiceFinder::NewL(ftpUuid, iDevAddr, *this);
+		// Start search process
+		iSdpServiceFinder->FindPortL();
+		iParent->Console()->Printf(_L("\nSearching for SDP service....\n"));
+		}
+	else if (aTransport == EIrda)
+		{
+		// Create transport info
+		TObexIrProtocolInfo transportInfo;
+		//assigning the unique name for the irda transport
+		transportInfo.iTransport = KObexIrTTPProtocol; 
+		//assigning irda specific attributes
+		transportInfo.iClassName      = KIrdaClassName;					
+		transportInfo.iAttributeName = KIrdaTransportAttrName;
+		
+  		iClient = CObexClient::NewL (transportInfo);	//create the obex client
+		iParent->iMode = E_Client;
+		}
+	else if (aTransport == EUsb)
+		{
+		// Create transport info
+		TObexUsbProtocolInfo aInfo;
+		aInfo.iTransport = KObexUsbProtocol;
+		aInfo.iInterfaceStringDescriptor = KClientInterfaceDescriptor;
+
+	    iClient = CObexClient::NewL (aInfo);// Create the CObexClient
+		}
+	else if (aTransport == EWin32Usb)
+		{
+		// Ensure win32usb Obex transport plugin exists
+		// Create transport info
+		TObexUsbProtocolInfo aInfo;
+		aInfo.iTransport = KObexWin32UsbProtocol;
+		aInfo.iInterfaceStringDescriptor = KClientInterfaceDescriptor;
+
+	    iClient = CObexClient::NewL (aInfo);
+		}
+	else
+		{
+		User::Invariant();
+		}
+
+	// Setup Obex objects
+	iFileObject = CObexFileObject::NewL();
+	iObjectBuffer = CBufFlat::NewL(KBufExpandSize);
+    iObject = CObexBufObject::NewL(iObjectBuffer);
+    iObexName = KNullDesC;
+	iGetType = KObjectType;
+	
+	// Create file session and create a new private path on drive C
+	RFs fileSession;
+	fileSession.Connect();
+	
+	fileSession.CreatePrivatePath(EDriveC);
+	fileSession.SetSessionToPrivate(EDriveC);	
+	fileSession.SessionPath(iSessionPath);
+	
+	// Copy the files from oby file ro the newly created path
+	BaflUtils::CopyFile(fileSession, KFilePath1, KFilename1,0);
+	BaflUtils::CopyFile(fileSession, KFilePath2, KFilename2,0);
+	BaflUtils::CopyFile(fileSession, KFilePath3, KFilename3,0);
+ 
+	fileSession.Close();
+	
+	// Assign file names
+	iFilename1 = KFilename1; 
+	iFilename2 = KFilename2;
+	iFilename3 = KFilename3;
+
+	
+    }
+
+
+/**
+ * Destructor.
+ */
+CObexClientHandler::~CObexClientHandler()
+    {
+    // do cleanup
+    Cancel();
+    delete iObject;
+	delete iFileObject;
+    delete iClient;
+	delete iObjectBuffer;
+	delete iTargetHeaderObject;
+	delete iSdpServiceFinder;
+    }
+    
+/**
+ * This function is called when the SDP search finishes.
+ * If search was successful then the OBEX port number is
+ * taken an used in starting the OBEX client.
+ * If unsuccessful, go back to the initial menu.
+ */
+void CObexClientHandler::SearchResult(TInt aError, TUint8 aPort)
+	{
+	// Service not supported?
+	if (aError != KErrNone)
+		{
+		iParent->Console()->Printf(_L("\r\n Could not find SDP service in remote device : error %d \r\n"),aError);	
+		iParent->iMode = E_Inactive;
+		iParent->Cancel();
+		}
+	
+	
+	// Set protocol info for bluetooth
+		
+	TObexBluetoothProtocolInfo aInfo;
+	aInfo.iAddr.SetBTAddr(iDevAddr);
+	aInfo.iAddr.SetPort(aPort); 
+	aInfo.iTransport = KObexRfcommProtocol;
+	//now create the obex client...
+	TRAPD(error,iClient = CObexClient::NewL (aInfo));
+	if (error)
+		{
+		iParent->Console()->Printf(_L("\r\n Could not create client! : error %d \r\n"),error);
+		iParent->iMode = E_Inactive;
+		iParent->Cancel();
+		}
+		
+	iParent->Console()->Printf(_L("\nSDP search complete OK!\n"));
+	iParent->iMode = E_Client;
+	
+	iParent->RequestCharacter();
+
+	}
+
+
+
+/**
+ * This function performs the actual connection of client to server.
+ */
+
+void CObexClientHandler::Connect()
+    {
+    if(IsActive())
+		{
+		iParent->Console()->Printf(KAlreadyActive);
+		return;
+		}
+   
+    TObexConnectInfo iLocalInfo = iClient->LocalInfo();
+    iLocalInfo.iWho = KNullDesC8;
+    iLocalInfo.iWho = EPOCIDENT;  
+    iLocalInfo.iWho.Append(KLocalInfoAppend);
+	// Connect to Obex client
+    iClient->Connect(iStatus);
+    SetActive();
+    iState = EConnecting;
+    }
+
+    
+/**
+ * This fucntion performs the disconnection from OBEX client and server
+ */    
+void CObexClientHandler::Disconnect()
+    {
+    if(IsActive())
+		{
+		iParent->Console()->Printf(KAlreadyActive);
+		return;
+		} 
+    // Disconnect from Obex client
+	iClient->Disconnect(iStatus);
+    SetActive();
+    iState = EDisconnecting;
+    }
+
+
+/**
+ * This function is called when an OBEX get is requested by name.
+ * It takes the current name of the OBEX object, replaces it with
+ * a user defined name. it then performs a Get on this object name. 
+ */
+void CObexClientHandler::GetByNameL()
+    {
+    if(IsActive())
+		{
+		iParent->Console()->Printf(KAlreadyActive);
+		return;
+		}
+	
+    iObject->Reset ();
+    // Call SetName passing current name
+    // This will set a newly selected name from the user
+	SetName(iObexName);
+	// Set the name
+    iObject->SetNameL (iObexName);
+    // Call get with required object
+    iClient->Get(*iObject, iStatus);
+    SetActive();
+    iState = EGetting;
+    }
+
+
+
+/**
+ * This function is a wrapper for the CObexClient::Put function.
+ * It is responsible for setting up a new Obex object from a specified file.
+ * It then performs the Put operation.
+ */    
+void CObexClientHandler::Put(TDes& aFilename)
+    {
+    if(IsActive())
+		{
+		iParent->Console()->Printf(KAlreadyActive);
+		return;
+		}
+		
+	// Setup the object from file
+	TInt err = SetUpObjectFromFile (aFilename);
+	// Advise user if unsuccessful
+	if( err != KErrNone)
+		{
+		iParent->Console()->Printf(_L("\r\n Couldnt set up object : error %d \r\n"),err);
+		Disconnect();
+		return;
+		}
+	// Call the put	
+	iClient->Put(*iFileObject,iStatus);
+	SetActive();
+	iState = EPutting;
+	}
+
+
+/**
+ * This function is responsible for initiating a 
+ * client/server connection with authentication.
+ * The password is set in source.
+ */
+void CObexClientHandler::ConnectWithAuthenticationL()
+	{
+    if(IsActive())
+		{
+		iParent->Console()->Printf(KAlreadyActive);
+		return;
+		}
+	// Set generic password
+    iChallengePassword = KAuthPassword;
+    // Connect client to server sending password
+    iClient->ConnectL(iChallengePassword, iStatus);
+    // Active the active object
+    SetActive();
+    iState = EConnecting;
+	}
+	
+/**
+ * This function is called from within the GetByName function.
+ * It takes in the current object name and changes it to a user
+ * defined alternative.
+ */
+void CObexClientHandler::SetName(TDes& aName)
+    {
+	TBuf<64> oldName;
+	oldName = aName;
+
+	TKeyCode aCode;
+	TBuf<1> aChar;
+	iParent->Console()->Printf(_L("\nEnter a name: %S"),&aName);
+	FOREVER
+		{
+		aCode = iParent->Console()->Getch();
+		aChar.SetLength(0);
+		aChar.Append(aCode);
+
+		iParent->Console()->Printf(_L("%S"),&aChar);
+	
+		// If <CR> finish editing string
+		if (aCode ==  EStdKeyDelete)
+			break;
+		
+		// if <BS> remove last character
+		if ((aCode == EStdKeyHome)&&(aName.Length() != 0))
+			aName.SetLength((aName.Length()-1));
+		else
+			aName.Append(aCode);
+		}
+	iParent->Console()->Printf(_L("\n"));
+
+
+    }
+
+
+
+/**
+ * This is the active object RunL function.
+ * When the function is called the currently selected mode of operation
+ * is examined and then dealt with accordingly.
+ * It displays the active object iStatus current state to the user.
+ */
+void CObexClientHandler::RunL ()
+    {
+    if (iStatus != KErrNone)
+		{// Handle error
+		}
+
+    TBuf<80> filename;
+    switch (iState)
+		{
+		// If we were connecting, and iStatus has completed then we want to change iState to EConnected
+		case EConnecting:
+			iParent->Console()->Printf(_L("\r\nConnect completed with error code: %d\r\n\r\n"),iStatus.Int());
+			iState = EConnected;
+			break;
+		// If we were performing a put and the iStatus has completed change iState to EConnected
+		case EPutting:
+			iState = EConnected;
+			iParent->Console()->Printf(_L("\r\nPut completed with error code: %d\r\n\r\n"),iStatus.Int());
+			break;
+		// If we were performing a get and the iStatus has completed change iState to EConnected
+		// Also we want to write the received object to file
+		case EGetting:
+			iState = EConnected;
+			iParent->Console()->Printf(_L("\r\nGet completed with error code: %d\r\n\r\n"),iStatus.Int());
+			DisplayObjectInformation();
+			filename = iSessionPath;
+			filename.Append(iObject->Name());		
+			// Write objects data to file, test if the file already exists as well
+			if (iObject->WriteToFile(filename) == KErrAlreadyExists)
+				{
+				iParent->Console()->Printf(_L("\r\nWrite failed, File Already Exists\n"));
+				}
+			iObject->Reset ();
+			break;
+		// If we wanted to disconnect and iStatus has completed, then go back to original state 
+		case EDisconnecting:
+			iParent->Console()->Printf(_L("\r\nDisconnect completed with error code: %d\r\n\r\n"),iStatus.Int());
+			iState = EIdle;
+		
+		default:
+			iParent->Console()->Printf(_L("\r\nTest Code is in an incorrect state: %d\r\n\r\n"),iState);
+			break;
+		}
+   
+    }
+
+/**
+ * This is the active object DoCancel function.
+ */
+void CObexClientHandler::DoCancel()
+    {
+    delete iClient;
+    iClient = NULL;
+    }
+    
+    
+/**
+ * DisplayObjectInformation prints information of the received object.
+ */    
+void CObexClientHandler::DisplayObjectInformation()
+    {
+    // Display Contents of CBufFlat data on current console
+	iParent->Console()->Printf(_L("Size of received object = %d\n"),iObjectBuffer->Size());
+	TDateTime dt = iObject->Time().DateTime();
+	iParent->Console()->Printf(_L("\r\nTimestamp: %d/%d/%d, %d:%d:%d\r\n\r\n"),
+				   dt.Day(), dt.Month()+1, dt.Year(), dt.Hour(), dt.Minute(), dt.Second());
+
+    TBuf8<1024> tempBuffer;
+	iObjectBuffer->Read(0, tempBuffer, tempBuffer.MaxSize() < iObjectBuffer->Size() ? tempBuffer.MaxSize() : iObjectBuffer->Size());
+	// Printf fails with Descriptor bigger than X hundred bytes so write byte at a time
+	for(TInt count = 0; count < tempBuffer.Size(); count++) 
+		{
+		iParent->Console()->Printf(_L("%C"),tempBuffer[count]);
+		}
+    }
+
+
+
+/**
+ * This function is called when a Put operation has started.
+ * It takes a filename and then attempts to setup an OBEX object
+ * from that file. Returns the appropriate error code, if the  
+ * file didn't exist then this function creates a new file of
+ * the same name. 
+ */
+TInt CObexClientHandler::SetUpObjectFromFile(TDes& aFilename)
+    {
+    // Try to create CObexFileObject with filename 
+	TRAPD (err, iFileObject->InitFromFileL (aFilename));
+	if (err != KErrNone)
+		{
+		RFs fs;
+		RFile f;
+		err = fs.Connect();
+		if (err== KErrNone)
+			{
+			err = fs.CreatePrivatePath(EDriveC);
+		 	}
+		 
+		if (err== KErrNone || err == KErrAlreadyExists )
+			{
+			err = fs.SetSessionToPrivate(EDriveC);
+			}
+			
+		if (err == KErrNone)
+			{
+			// File didn't exist so create a file of same name in it place	
+			err = f.Create (fs, aFilename, EFileShareExclusive | EFileWrite);
+			}
+			
+		if (err != KErrNone)
+			{
+			iParent->Console()->Printf(_L("\r\nError reading '%s'.\r\nI tried to create this file for you, but failed to do that too. Sorry.\r\n\r\n"), aFilename.PtrZ ());			
+			}
+		else
+			{
+			f.Write (_L8("Test file for sending from EPOC\r\n\r\nLooks like obex is sending OK!!\r\n"));
+			f.Close ();
+			iParent->Console()->Printf(_L("\r\nFile '%s' did not exist, so I've created one.\r\nPlease try again.\r\n\r\n"), aFilename.PtrZ ());	
+			}
+		fs.Close ();
+		
+		}
+	
+	return (err);
+
+    }
+
+
+    
+/**
+ * NewL function for CRFCOMMServiceFinder 
+ */
+
+CRFCOMMServiceFinder* CRFCOMMServiceFinder::NewL(	const TUUID& aServiceClass,
+							const TBTDevAddr& aDevAddr,
+							MRFCOMMServiceSeeker& aSeeker)
+	{
+	CRFCOMMServiceFinder* self= new (ELeave) CRFCOMMServiceFinder(aSeeker);
+	CleanupStack::PushL(self);
+	self->ConstructL(aDevAddr, aServiceClass);
+	CleanupStack::Pop();
+	return (self);
+	}
+
+/**
+ * Destructor.
+ */
+CRFCOMMServiceFinder::~CRFCOMMServiceFinder()
+	{
+	delete iPattern;
+	delete iAgent;
+	}
+
+/**
+ * Constructor.
+ */	
+CRFCOMMServiceFinder::CRFCOMMServiceFinder(MRFCOMMServiceSeeker& aSeeker)
+: iSeeker(aSeeker)
+	{
+	}
+
+/**
+ * 2nd phase constructor. Sets the seach pattern for SDP with the UUID supplied.
+ * Then Creates a new SDP agent with the device address supplied.
+ */
+void CRFCOMMServiceFinder::ConstructL(const TBTDevAddr& aDevAddr, const TUUID& aServiceClass)
+	{
+	iPattern=CSdpSearchPattern::NewL();
+	iPattern->AddL(aServiceClass);
+	iAgent=CSdpAgent::NewL(*this, aDevAddr);
+	// Filter out classes that arent FTP
+	iAgent->SetRecordFilterL(*iPattern);
+	}
+
+/**
+ * This function is responsible for calling the SDP agent NextRecordRequestL
+ * function, this gets the next service record that the device has registered
+ * in the SDP database.
+ */
+void CRFCOMMServiceFinder::FindPortL()
+	{
+	iPort=KNotAPort;	//0xFF will never be returned from a query, 
+			//because RFCOMM server channels only
+			//go up to 30.
+	
+	iAgent->NextRecordRequestL();
+	}
+
+
+/**
+ * This function is from the MSdpAgentNotify interface and is called when there
+ * are no more SDP records registered in the database. It calls SearchResult implemented 
+ * by this class.
+ */
+void CRFCOMMServiceFinder::NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt /*aTotalRecordsCount*/) 
+	{
+	if(aError)
+		iSeeker.SearchResult(aError,KNoPort);	
+	else
+		{
+		//We have the record, kick off the attribute request
+		TRAPD(err,iAgent->AttributeRequestL(aHandle,KSdpAttrIdProtocolDescriptorList )); 
+		if(err)
+			iSeeker.SearchResult(err,KNoPort);
+		}
+	}
+
+
+	
+/**
+ * This function comes from the MSdpAgentNotifer interface, It is called when
+ * the attribute request process has finished.
+ */
+void CRFCOMMServiceFinder::AttributeRequestComplete(TSdpServRecordHandle /*aHandle*/, TInt aError)
+	{
+	if(aError!=KErrNone || iPort==KNotAPort)
+		iSeeker.SearchResult(aError?aError:KErrNotFound,KNoPort);
+	else
+		iSeeker.SearchResult(KErrNone, iPort);
+	}
+
+ 
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/src/simpleObexServer.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,484 @@
+/*
+* 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 "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 <e32base.h>
+#include <obexconstants.h>
+
+#include "simpleObexServer.h"
+#include "simpleObexApp.h"
+#include "obexAppConstants.h"
+
+
+/**
+ * Constructor.
+ */
+CObexServerHandler::CObexServerHandler(CActiveConsole* aParent)
+:iAcceptPuts(ETrue)
+    {
+	iParent = aParent;
+    iServer    = NULL;
+    iObject    = NULL;
+    }
+
+
+
+/**
+ * NewL function
+ */
+CObexServerHandler* CObexServerHandler::NewL(CActiveConsole* aParent, TTransport aTransport)
+    {
+    CObexServerHandler* self = new (ELeave) CObexServerHandler(aParent);
+
+    CleanupStack::PushL(self);
+    self->ConstructL(aTransport);
+    CleanupStack::Pop();
+    return (self);
+    }
+
+
+/**
+ * 2nd phase constructor. This function performs the initial steps needed in 
+ * creating a new CObexServer object. It then creates the CObexServer object for the specified
+ * transport.
+ *
+ */
+void CObexServerHandler::ConstructL(TTransport aTransport)
+    {
+	iTransportLayer = aTransport;
+	if (aTransport == EBluetooth)
+		{
+		// Start bluetooth socket and set security
+		RSocketServ socketServ;
+		socketServ.Connect();
+		RSocket listen;
+		TInt test = listen.Open(socketServ, KRFCOMMDesC);
+
+		if (test == KErrNone)
+			{
+			iParent->Console()->Printf(_L("Socket Open ... Success\n"));	
+			}
+
+		TBTSockAddr addr;
+		// Auto bind to RFComm port
+		addr.SetPort(KRfcommPassiveAutoBind);
+		
+		TBTServiceSecurity serviceSecurity;
+			
+		serviceSecurity.SetUid(KUidServiceSDP);
+		serviceSecurity.SetAuthentication(EFalse);
+		serviceSecurity.SetEncryption(EFalse);
+		serviceSecurity.SetAuthorisation(EFalse);
+		serviceSecurity.SetDenied(EFalse);
+		addr.SetSecurity(serviceSecurity);
+			
+		TInt error;	
+		// Set bluetooth protocol info
+		TObexBluetoothProtocolInfo info;
+		info.iAddr.SetPort(KObexTestPort);
+		info.iTransport = KRFCOMMDesC;
+		TRAP(error,iServer  = CObexServer::NewL(info));
+		if (error)
+			{
+			iParent->Console()->Printf(_L("\r\n Could not create obex server! : error %d \r\n"),error);
+			iParent->iMode = E_Inactive;
+			iParent->iMode = E_Server;
+			iParent->Cancel(); // cancel request for key
+			}
+		// Add services to the Service discovery database
+			
+		User::LeaveIfError(iSdp.Connect());
+		User::LeaveIfError(iSdpdb.Open(iSdp));
+		
+		TSdpServRecordHandle ftphandle;
+
+		iSdpdb.CreateServiceRecordL(ftpUuid, ftphandle);
+		iSdpdb.UpdateAttributeL(ftphandle, KSdpAttrIdServiceName, KServerDesC);
+				
+		iProtDescList = CSdpAttrValueDES::NewDESL(0);
+
+			iProtDescList
+			->StartListL()
+				->BuildDESL()
+				->StartListL()
+					->BuildUUIDL(KL2CAPUUID) 
+				->EndListL()
+				->BuildDESL()
+				->StartListL()
+					->BuildUUIDL(KRfcommUuid) 
+						->BuildUintL(TSdpIntBuf<TInt8>(KObexTestPort))
+				->EndListL()
+				->BuildDESL()
+				->StartListL()
+					->BuildUUIDL(KObexProtocolUuid) 
+				->EndListL()
+			->EndListL();
+		// Update attribute
+		iSdpdb.UpdateAttributeL(ftphandle, KProtocolDescriptorListUUID, *iProtDescList); // put into both records
+		delete iProtDescList;
+			
+		User::LeaveIfError(listen.Bind(addr)); 
+			
+		TInt queueSize=2;
+		User::LeaveIfError(listen.Listen(queueSize));
+	
+		iParent->Console()->Printf(_L("\n.....Now Listening.....\n"));
+		
+		}
+
+	else if (aTransport == EIrda)
+		{
+		
+		//creating the transport info
+		TObexIrProtocolInfo transportInfo;
+		transportInfo.iAddr.SetPort(KAutoBindLSAP);//default obex server for now
+		transportInfo.iTransport = KObexIrTTPProtocol; 
+		transportInfo.iClassName      = KIrdaClassName;					
+		transportInfo.iAttributeName = KIrdaTransportAttrName;
+
+  		iServer = CObexServer::NewL (transportInfo);
+		
+		}
+	
+    else if (aTransport == EWin32Usb)
+		{
+		// Create transport info
+		TObexUsbProtocolInfo aInfo;
+		aInfo.iTransport = KObexWin32UsbProtocol;
+        aInfo.iInterfaceStringDescriptor = KServerInterfaceDescriptor;
+		iServer = CObexServer::NewL (aInfo);
+		
+		}
+   
+   // Now that the transport has been selected and Obex Server started
+   // We need to do some initialisation with Obex Objects so that we are 
+   // prepared to deal with Put/Get requests from the client
+    
+    iObject  = CObexBufObject::NewL (NULL);
+
+    iBuf = CBufFlat::NewL(KServerBufExpandSize);
+  	
+	iBuf->ResizeL(KServerBufExpandSize);// Resize the buffer
+
+	iObject = CObexBufObject::NewL(NULL);
+	iObject->SetDataBufL(iBuf);
+	//Create the RFile to be used
+	User::LeaveIfError(iFs.Connect());
+	User::LeaveIfError(iFs.CreatePrivatePath(EDriveC));
+	User::LeaveIfError(iFs.SetSessionToPrivate(EDriveC));
+	User::LeaveIfError(iFs.SessionPath( iSessionPath ));
+	// Start the server
+	User::LeaveIfError(iServer->Start (this)); 
+    
+    }
+
+
+
+
+/**
+ * This function stops the OBEX server
+ */
+void CObexServerHandler::Stop()
+    {
+	if (iServer)
+		{
+		iServer->Stop();
+		}
+    }
+
+
+/**
+ * Destructor.
+ */
+CObexServerHandler::~CObexServerHandler ()
+    {
+    Stop();
+	
+	iSdpdb.Close();
+	iSdp.Close();
+
+	delete iObject;
+    delete iBuf;
+    delete iServer;
+    }
+
+/**
+ * This function enables authentication on the OBEX server.
+ * The password is defined in source.
+ */
+void CObexServerHandler::EnableAuthenticationL()
+	{
+	iChallengePassword = KAuthPassword;
+	iServer->SetChallengeL(iChallengePassword);
+	iIsAuthenticationEnabled = ETrue;
+	}
+
+/**
+ * This function disables authentication on the server.
+ */
+void CObexServerHandler::DisableAuthentication()
+	{
+	iServer->ResetChallenge();
+	iIsAuthenticationEnabled = EFalse;
+	}
+
+
+
+
+
+// MObexServerNotify interface functions
+
+/**
+ * Called if an OBEX protocol error occurs.
+ */
+void CObexServerHandler::ErrorIndication (TInt aError)
+    {
+    iParent->Console()->Printf(_L("Obex Server error %d"), aError);
+    }
+
+/**
+ * Called when the underlying transport connection is made from a remote client to the server.
+ */
+void CObexServerHandler::TransportUpIndication ()
+    {
+    iParent->Console()->Printf(_L("\nTransport started\n"));
+    }
+
+/**
+ * Called when the transport connection is dropped (by either party).
+ */
+void CObexServerHandler::TransportDownIndication ()
+    {
+    iParent->Console()->Printf(_L("\nTransport down\n"));
+    }
+
+/**
+ * Called when an OBEX connection is made from a remote client.
+ */
+TInt CObexServerHandler::ObexConnectIndication(const TObexConnectInfo& aRemoteInfo, const TDesC8& /*aInfo*/)
+    {
+    
+    iParent->Console()->Printf(_L("\r\nCObexServerHandler::ObexConnectIndication"));
+	iParent->Console()->Printf(_L("\r\nConnected to machine with OBEX version %d.%d\r\n"), 
+		     aRemoteInfo.VersionMajor (), aRemoteInfo.VersionMinor ());
+
+     return (KErrNone);
+    
+    }
+
+/**
+ * Called on a (graceful) OBEX disconnection by the client.
+ */
+void CObexServerHandler::ObexDisconnectIndication (const TDesC8& /*aInfo*/)
+    {
+    iParent->Console()->Printf(_L("\r\nObex Disconnected\r\n\r\n"));
+    }
+
+
+/**
+ * Called on receipt of the first packet of a (valid) put request.
+ */
+CObexBufObject* CObexServerHandler::PutRequestIndication ()
+    {
+    iParent->Console()->Printf(_L("Receiving object...\r\n"));
+    iObject->Reset ();
+
+	if ( iAcceptPuts)
+		return (iObject);
+	else
+		return (NULL);
+    }
+
+/**
+ * Called on receipt of every packet of an OBEX PUT operation.
+ */
+TInt CObexServerHandler::PutPacketIndication ()
+    {
+    
+    TUint length = iObject->Length();
+
+	TUint received = iObject->BytesReceived();
+	TUint8 percent = 0;
+    if (length > 0)
+		{
+		percent = TUint8((100 * received) / length);
+		iParent->Console()->Printf(_L("\r%d %%      "), percent);
+		}
+    else
+		{
+		iParent->Console()->Printf(_L("\r%d      "), iObject->BytesReceived ());
+		}
+    return (KErrNone);
+    
+    }
+
+/**
+ * Called after the final put packet has been successfully received and parsed.
+ */
+TInt CObexServerHandler::PutCompleteIndication ()
+    {
+    TPtrC name=iObject->Name();
+	TBuf<100> type;
+	type.Copy(iObject->Type());
+	iParent->Console()->Printf(_L("\r\nSuccessfully received '%S'\r\nType[%d]: '%S'\r\n"), &name, type.Length(), &type);
+
+	TInt err = KErrNone;
+	TBuf<80> filename(iSessionPath);
+	filename.Append(iObject->Name());
+	err = iObject->WriteToFile(filename);
+    if (err == KErrAlreadyExists)
+    	{
+       	iParent->Console()->Printf(_L("\r\nWrite failed, File Already Exists\n"));
+        }
+    
+	iObject->Reset ();
+    return (err);
+    }
+
+
+/**
+ * Called when a full get request has been received from the client.
+ */
+CObexBufObject* CObexServerHandler::GetRequestIndication (CObexBaseObject* aRequiredObject)
+    {
+
+	TRAPD(err,SetUpGetObjectL(aRequiredObject));
+	if (err != KErrNone)
+		{
+		iParent->Console()->Printf(_L("\nSetUpGetObjectL() returned %d.\n"), err);
+		return NULL;
+		}
+		
+	return (iObject);
+	
+	}
+	
+	
+/**
+ * Called for every packet of get reply sent by the server back to the client.
+ */
+TInt CObexServerHandler::GetPacketIndication ()
+    {
+    if (iObject->Length () > 0)
+		iParent->Console()->Printf(_L("\r%d %%      "), 
+			 100 * iObject->BytesSent () / iObject->Length ());
+    else
+		iParent->Console()->Printf(_L("\r%d Bytes      "), iObject->BytesSent ());
+    return (KErrNone);
+    }
+
+/**
+ * Called when the final packet of the object has been returned to the client.
+ */
+TInt CObexServerHandler::GetCompleteIndication ()
+    {
+    iParent->Console()->Printf(_L("Obex Get Complete\r\n"));
+    iObject->Reset ();
+	return (KErrNone);
+    }
+    
+    
+    
+/**
+ * Called when an OBEX SETPATH command is received by the server.
+ *
+ */
+TInt CObexServerHandler::SetPathIndication (const CObex::TSetPathInfo& aPathInfo, const TDesC8& /*aInfo*/)
+    {
+    iParent->Console()->Printf(_L("Obex SetPath request:\r\n"));
+    iParent->Console()->Printf(_L("   --- Flags = '%d' - Constants = '%d' - "), aPathInfo.iFlags, aPathInfo.iConstants);
+    
+    if (aPathInfo.iNamePresent)
+		iParent->Console()->Printf(_L("Name = %S\r\n"), &aPathInfo.iName);
+	else
+		iParent->Console()->Printf(_L("> No Name Present <\r\n"));
+	
+	iParent->Console()->Printf(_L("\nReturning success...!\n"));
+	return (KErrNone);
+    
+    }
+
+/**
+ * Called when an abort packet is received from the client.
+ */
+void CObexServerHandler::AbortIndication ()
+    {
+    iParent->Console()->Printf(_L("Obex Operation aborted\r\n"));
+    if(iObject)
+		{
+		// Determine if we have recieved any amount of the object
+		// Return without notifing user if we haven't.
+		if(!iObject->BytesReceived())
+		    return;
+		iParent->Console()->Printf(_L("\r\nWe have received part of an Obex object\r\n\r\n"));
+
+		iObject->Reset();
+		}
+	}
+
+
+/**
+ * This is the function that sets up an object ready for a Get.
+ * It takes as a parameter the requested object and then examines it's
+ * name and if a filename matches then the object it setup from that file.
+ */
+void CObexServerHandler::SetUpGetObjectL(CObexBaseObject *aRequestedObject)
+	{
+	// Get the name of the requested object
+	TBuf<200> name (aRequestedObject->Name ());
+	if(name.Length())
+		{
+		iParent->Console()->Printf(_L("Obex Get Request for name '%s'\r\n"), name.PtrZ ());
+		}
+
+	else
+		{
+		iParent->Console()->Printf(_L("Obex Get Request unknown details\r\n"));
+		User::Leave(KErrNotSupported);
+		}
+	iObject->Reset();
+
+	RFs fs;
+	RFile f;
+	// Attempt to open the specified file
+	if ((fs.Connect () != KErrNone) || 
+		(f.Open (fs, name, EFileShareReadersOnly | EFileRead) != KErrNone))
+		{
+		iParent->Console()->Printf(_L("\r\nError reading '%S'."), &name);
+		User::Leave(KErrNotFound);
+		}
+	// We can now proceed in setting up the object using the file retrieved
+	
+	TInt size = 0;
+	// Set size of file
+	User::LeaveIfError(f.Size (size));
+	// Resize buffer object
+	iBuf->ResizeL(size);
+	// Get a pointer to represent the data
+	TInt bufStart=0;
+	TPtr8 data (iBuf->Ptr(bufStart));
+	// Read data from file,
+	f.Read (data);
+	if (iBuf->Size() < size)
+		User::Leave(KErrGeneral);
+	// Set name of the object
+	iObject->SetNameL(name);
+	// Set length
+	iObject->SetLengthL(size);
+	TTime time;
+	if (f.Modified(time) == KErrNone)
+		iObject->SetTimeL(time);
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/BWINS/T_usbU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,3 @@
+EXPORTS
+	?NewTestSuiteUsb@@YAPAVCTestSuiteUsb@@XZ @ 1 NONAME ; class CTestSuiteUsb * NewTestSuiteUsb(void)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/EABI/T_usbU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,25 @@
+EXPORTS
+	_Z15NewTestSuiteUsbv @ 1 NONAME
+	_ZTI13CTestOpenPort @ 2 NONAME ; #<TI>#
+	_ZTI17CTestCheckSignals @ 3 NONAME ; #<TI>#
+	_ZTI21CTestSetSignalsToMark @ 4 NONAME ; #<TI>#
+	_ZTI22CTestNotifyStateChange @ 5 NONAME ; #<TI>#
+	_ZTI22CTestSetSignalsToSpace @ 6 NONAME ; #<TI>#
+	_ZTI23CTestWaitForReadFailure @ 7 NONAME ; #<TI>#
+	_ZTI23CTestWaitForStateChange @ 8 NONAME ; #<TI>#
+	_ZTI24CTestWaitForConfigChange @ 9 NONAME ; #<TI>#
+	_ZTI24CTestWaitForWriteFailure @ 10 NONAME ; #<TI>#
+	_ZTI28CTestUsbManNotifyStateChange @ 11 NONAME ; #<TI>#
+	_ZTI29CTestUsbManWaitForStateChange @ 12 NONAME ; #<TI>#
+	_ZTV13CTestOpenPort @ 13 NONAME ; #<VT>#
+	_ZTV17CTestCheckSignals @ 14 NONAME ; #<VT>#
+	_ZTV21CTestSetSignalsToMark @ 15 NONAME ; #<VT>#
+	_ZTV22CTestNotifyStateChange @ 16 NONAME ; #<VT>#
+	_ZTV22CTestSetSignalsToSpace @ 17 NONAME ; #<VT>#
+	_ZTV23CTestWaitForReadFailure @ 18 NONAME ; #<VT>#
+	_ZTV23CTestWaitForStateChange @ 19 NONAME ; #<VT>#
+	_ZTV24CTestWaitForConfigChange @ 20 NONAME ; #<VT>#
+	_ZTV24CTestWaitForWriteFailure @ 21 NONAME ; #<VT>#
+	_ZTV28CTestUsbManNotifyStateChange @ 22 NONAME ; #<VT>#
+	_ZTV29CTestUsbManWaitForStateChange @ 23 NONAME ; #<VT>#
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/group/T_usb.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2007-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:
+* using relative paths for sourcepath and user includes
+*
+*/
+
+TARGET        t_usb.dll
+TARGETTYPE    dll
+UID           0
+VENDORID 0x70000001
+
+CAPABILITY	ALL -TCB
+
+SOURCEPATH    	../src
+SOURCE   	UsbSuite.cpp
+SOURCE  	UsbStep.cpp
+SOURCE  	UsbTest1.cpp
+SOURCE  	UsbTest2.cpp
+SOURCE  	UsbManTest1.cpp
+
+USERINCLUDE   	../inc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+LIBRARY       euser.lib usbman.lib c32.lib 		// EPOC stuff
+LIBRARY	      integrationtestutils.lib 			// Test utils stuff
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 2007-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:
+* Integration test system build for T_usb 
+*
+*/
+
+PRJ_TESTEXPORTS
+
+../scripts/t_usb.script		/epoc32/winscw/c/t_usb.script
+../scripts/t_usb1.script	/epoc32/winscw/c/t_usb1.script
+../scripts/t_usb2.script	/epoc32/winscw/c/t_usb2.script
+../scripts/t_usb3.script	/epoc32/winscw/c/t_usb3.script
+../scripts/t_usb4.script	/epoc32/winscw/c/t_usb4.script
+../scripts/t_usb5.script	/epoc32/winscw/c/t_usb5.script
+../scripts/t_usb6.script	/epoc32/winscw/c/t_usb6.script
+../scripts/t_usb7.script	/epoc32/winscw/c/t_usb7.script
+../scripts/t_usb3.ini		/epoc32/winscw/c/t_usb3.ini
+
+../scripts/t_usbman1.script	/epoc32/winscw/c/t_usbman1.script
+../scripts/t_usbman1.ini	/epoc32/winscw/c/t_usbman1.ini
+../scripts/t_usbman2.ini	/epoc32/winscw/c/t_usbman2.ini
+
+PRJ_TESTMMPFILES
+T_usb.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/inc/UsbManTest1.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,49 @@
+/*
+* 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:
+* This is the header file for Usbman test section 1
+*
+*/
+
+#ifndef __USBMANTEST1_H__
+#define __USBMANTEST1_H__
+
+///////////////////////////////////////////////
+// Test 1.1
+class CTestUsbManNotifyStateChange : public CTestStepUsb
+{
+public:
+	CTestUsbManNotifyStateChange();
+	virtual ~CTestUsbManNotifyStateChange();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.2
+class CTestUsbManWaitForStateChange : public CTestStepUsb
+{
+public:
+	CTestUsbManWaitForStateChange();
+	virtual ~CTestUsbManWaitForStateChange();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/inc/UsbStep.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,44 @@
+/*
+* 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:
+* This contains CTestStepUsb which is the base class for all 
+* the Usb test step cases
+*
+*/
+
+#ifndef __USBSTEP_H__
+#define __USBSTEP_H__
+
+#include <networking/teststep.h>
+#include <usbman.h>
+
+class CTestSuite;
+class CTestSuiteUsb;
+NONSHARABLE_CLASS(CTestStepUsb) : public CTestStep
+{
+public:
+	CTestStepUsb();
+	virtual ~CTestStepUsb();
+
+	// pointer to suite which owns this test 
+	CTestSuiteUsb* iUsbSuite;
+
+protected:
+	void OpenCommServerL();
+	TInt OpenLdd();
+};
+
+
+
+#endif /* __USBSTEP_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/inc/UsbSuite.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,73 @@
+/*
+* Copyright (c) 2007-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:
+* This contains CTestSuiteUsb 
+* This is the container class for all the Usb test steps
+*
+*/
+
+
+#ifndef __USBSUITE_H__
+#define __USBSUITE_H__
+
+#include <networking/testsuite.h>
+#include <c32comm.h>
+#include <d32usbc.h>
+
+#define CSY_NAME _L("ECACM")
+#define PORT_NAME _L("ACM::0")
+
+NONSHARABLE_CLASS(CTestSuiteUsb) : public CTestSuite
+{
+public:
+	void InitialiseL( );
+	virtual ~CTestSuiteUsb();
+	
+	void AddTestStepL(CTestStepUsb* aTestStep);
+
+	// Override of test system getversion method  
+	TPtrC GetVersion();
+
+	void CloseAll();
+
+public:
+	RUsb			iUsb;
+	RCommServ		iCommServer;
+	RComm			iCommPort;
+	RDevUsbcClient  iLdd;
+
+	TBool			iPortOpen;
+	TBool			iCommServerOpen;
+	TBool			iUsbOpen;
+	TBool			iLddOpen;
+
+	TRequestStatus	iStartStatus;
+	TRequestStatus	iReadStatus;
+	TRequestStatus	iWriteStatus;
+	TRequestStatus	iNotifySignalChangeStatus;
+	TRequestStatus	iNotifyConfigChangeStatus;
+	TRequestStatus  iNotifyBreakStatus;
+	TRequestStatus  iNotifyStateStatus;
+
+	TUint				  iSignals;
+	TCommNotificationPckg iConfig;
+	TUint				  iUsbState;
+
+	TUsbDeviceState		  iUsbManState;
+
+	TBuf8<1024>     iReadBuffer;
+	TBuf8<1024>     iWriteBuffer;
+};
+
+#endif /* __USBSUITE_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/inc/UsbTest1.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,339 @@
+/*
+* 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:
+* This is the header file for Usb test section 1
+*
+*/
+
+#ifndef __USBTEST1_H__
+#define __USBTEST1_H__
+
+
+///////////////////////////////////////////////
+// Test 1.1
+NONSHARABLE_CLASS(CTestStartUsb) : public CTestStepUsb
+{
+public:
+	CTestStartUsb();
+	virtual ~CTestStartUsb();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+
+///////////////////////////////////////////////
+// Test 1.2
+NONSHARABLE_CLASS(CTestWaitForUsb) : public CTestStepUsb
+{
+public:
+	CTestWaitForUsb();
+	virtual ~CTestWaitForUsb();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+
+///////////////////////////////////////////////
+// Test 1.3
+NONSHARABLE_CLASS(CTestStartCsy) : public CTestStepUsb
+{
+public:
+	CTestStartCsy();
+	virtual ~CTestStartCsy();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+
+///////////////////////////////////////////////
+// Test 1.4
+NONSHARABLE_CLASS(CTestOpenDTEPort) : public CTestStepUsb
+{
+public:
+	CTestOpenDTEPort();
+	~CTestOpenDTEPort();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+
+///////////////////////////////////////////////
+// Test 1.5
+NONSHARABLE_CLASS(CTestOpenDCEPort) : public CTestStepUsb
+{
+public:
+	CTestOpenDCEPort();
+	virtual ~CTestOpenDCEPort();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.6
+NONSHARABLE_CLASS(CTestPostRead) : public CTestStepUsb
+{
+public:
+	CTestPostRead();
+	virtual ~CTestPostRead();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.7
+NONSHARABLE_CLASS(CTestPostWrite) : public CTestStepUsb
+{
+public:
+	CTestPostWrite();
+	virtual ~CTestPostWrite();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.8
+NONSHARABLE_CLASS(CTestCancelRead) : public CTestStepUsb
+{
+public:
+	CTestCancelRead();
+	virtual ~CTestCancelRead();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.9
+NONSHARABLE_CLASS(CTestCancelWrite) : public CTestStepUsb
+{
+public:
+	CTestCancelWrite();
+	virtual ~CTestCancelWrite();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.10
+NONSHARABLE_CLASS(CTestWaitForRead) : public CTestStepUsb
+{
+public:
+	CTestWaitForRead();
+	virtual ~CTestWaitForRead();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.11
+NONSHARABLE_CLASS(CTestWaitForWrite) : public CTestStepUsb
+{
+public:
+	CTestWaitForWrite();
+	virtual ~CTestWaitForWrite();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.12
+NONSHARABLE_CLASS(CTestPostReadOneOrMore) : public CTestStepUsb
+{
+public:
+	CTestPostReadOneOrMore();
+	virtual ~CTestPostReadOneOrMore();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.13
+NONSHARABLE_CLASS(CTestClosePort) : public CTestStepUsb
+{
+public:
+	CTestClosePort();
+	virtual ~CTestClosePort();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.14
+NONSHARABLE_CLASS(CTestCloseCommServer) : public CTestStepUsb
+{
+public:
+	CTestCloseCommServer();
+	virtual ~CTestCloseCommServer();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.15
+NONSHARABLE_CLASS(CTestCloseUsbServer) : public CTestStepUsb
+{
+public:
+	CTestCloseUsbServer();
+	virtual ~CTestCloseUsbServer();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.16
+NONSHARABLE_CLASS(CTestStopUsb) : public CTestStepUsb
+{
+public:
+	CTestStopUsb();
+	virtual ~CTestStopUsb();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.17
+NONSHARABLE_CLASS(CTestNotifySignalChange) : public CTestStepUsb
+{
+public:
+	CTestNotifySignalChange();
+	virtual ~CTestNotifySignalChange();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.18
+NONSHARABLE_CLASS(CTestWaitForSignalChange) : public CTestStepUsb
+{
+public:
+	CTestWaitForSignalChange();
+	virtual ~CTestWaitForSignalChange();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.19
+NONSHARABLE_CLASS(CTestWaitForReadCancel) : public CTestStepUsb
+{
+public:
+	CTestWaitForReadCancel();
+	virtual ~CTestWaitForReadCancel();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.20
+NONSHARABLE_CLASS(CTestPostReadThenCancel) : public CTestStepUsb
+{
+public:
+	CTestPostReadThenCancel();
+	virtual ~CTestPostReadThenCancel();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.21
+NONSHARABLE_CLASS(CTestNotifyConfigChange) : public CTestStepUsb
+{
+public:
+	CTestNotifyConfigChange();
+	virtual ~CTestNotifyConfigChange();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.23
+NONSHARABLE_CLASS(CTestNotifyBreak) : public CTestStepUsb
+{
+public:
+	CTestNotifyBreak();
+	virtual ~CTestNotifyBreak();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.24
+NONSHARABLE_CLASS(CTestWaitForBreak) : public CTestStepUsb
+{
+public:
+	CTestWaitForBreak();
+	virtual ~CTestWaitForBreak();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 1.25
+NONSHARABLE_CLASS(CTestCloseAll) : public CTestStepUsb
+{
+public:
+	CTestCloseAll();
+	virtual ~CTestCloseAll();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+#endif /* __USBTEST1_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/inc/UsbTest2.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,139 @@
+/*
+* 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:
+* This is the header file for Usb test section 2
+*
+*/
+
+#ifndef __USBTEST2_H__
+#define __USBTEST2_H__
+
+///////////////////////////////////////////////
+// Test 2.1
+class CTestSetSignalsToMark : public CTestStepUsb
+{
+public:
+	CTestSetSignalsToMark();
+	virtual ~CTestSetSignalsToMark();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 2.2
+class CTestSetSignalsToSpace : public CTestStepUsb
+{
+public:
+	CTestSetSignalsToSpace();
+	virtual ~CTestSetSignalsToSpace();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 2.3
+class CTestCheckSignals : public CTestStepUsb
+{
+public:
+	CTestCheckSignals();
+	virtual ~CTestCheckSignals();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 2.4
+class CTestWaitForReadFailure : public CTestStepUsb
+{
+public:
+	CTestWaitForReadFailure();
+	virtual ~CTestWaitForReadFailure();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 2.5
+class CTestWaitForWriteFailure : public CTestStepUsb
+{
+public:
+	CTestWaitForWriteFailure();
+	virtual ~CTestWaitForWriteFailure();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 2.6
+class CTestOpenPort : public CTestStepUsb
+{
+public:
+	CTestOpenPort();
+	virtual ~CTestOpenPort();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 2.7
+class CTestWaitForConfigChange : public CTestStepUsb
+{
+public:
+	CTestWaitForConfigChange();
+	virtual ~CTestWaitForConfigChange();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 2.8
+class CTestNotifyStateChange : public CTestStepUsb
+{
+public:
+	CTestNotifyStateChange();
+	virtual ~CTestNotifyStateChange();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+///////////////////////////////////////////////
+// Test 2.9
+class CTestWaitForStateChange : public CTestStepUsb
+{
+public:
+	CTestWaitForStateChange();
+	virtual ~CTestWaitForStateChange();
+
+	virtual enum TVerdict doTestStepL( void );
+
+private:
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usb.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+// Copyright (c) 2007-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:
+// t_usb tests. 
+// 
+//
+
+LOAD_SUITE t_usb.dll
+
+// Start and stop Usb services
+
+
+PRINT Please remove USB cable
+PAUSE
+
+// Request the USB services are started
+RUN_TEST_STEP -1, t_usb, StartUsb
+
+PRINT Please insert USB cable
+PAUSE
+
+// Wait for the bus to re-enumerate
+RUN_TEST_STEP -1, t_usb, WaitForUsb
+
+// Stop the USB services
+RUN_TEST_STEP -1, t_usb, StopUsb
+
+TEST_COMPLETE
+
+UNLOAD
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usb1.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,104 @@
+// Copyright (c) 2007-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:
+// t_usb tests. 
+// Test Steps available
+// "StartUsb"			- Initiate Start of USB services
+// "WaitForUsb"			- Wait for the bus to re-enumerate
+// "StartCSY"			- Ask C32 to load the ACM CSY
+// "OpenDTE"			- Open the ACM comm port as a DTE
+// "OpenDCE"			- Open the ACM comm port as a DCE
+// "Read"			- Post a Read to the comm port
+// "Write"			- Post a Write to the comm port
+// "CancelRead"			- Cancel a pending Read
+// "CancelWrite" 		- Cancel a pending Write
+// "WaitForRead"		- Wait for a Read operation to complete
+// "WaitForWrite"		- Wait for a Write operation to complete
+// "ReadOneOrMore"		- Post a ReadOneOrMore to the comm port
+// "ClosePort"			- Close the ACM port
+// "CloseCommServer"		- Close the handle to C32
+// "CloseUsb"			- Close the handle to the USB server
+// "CloseAll"			- Close all handles (port, C32 and USB server)
+// "StopUsb"			- Stop USB services
+// "NotifySignalChange"		- Post a notify request for when signals change
+// "WaitForReadCancel"		- Wait for a read operation to be cancelled completely
+// "ReadThenCancel"		- Post a read and then cancel it immediately
+// "NotifyConfigChange"		- Post a notify request for when the config changes
+// "WaitForConfigChange"	- Wait for the configuration to change
+// "NotifyBreak"		- Post a notify request for when a break occurs
+// "WaitForBreak"		- Wait for a break to occur 
+// "SetSignalsToMarkC"		- Set the signals to mark (Requires a configuration file)
+// "SetSignalsToSpaceC"		- Set the signals to space (Requires a configuration file) 
+// "CheckSignalsC"		- Check the signals match (Requires a configuration file)
+// "WaitForReadFailureC"	- Wait for read failure (Requires a configuration file)
+// "WaitForWriteFailureC"	- Wait for write failure (Requires a configuration file)
+// "OpenPortC"			- Open the ACM port configurable for role, mode and return value
+// "WaitForSignalChangeC"	- Wait for the signals to change
+// 
+//
+
+LOAD_SUITE t_usb.dll
+
+////////////////////////////////////////
+// Test 1 - Start and Stop Usb services
+////////////////////////////////////////
+
+PRINT Please remove USB cable
+PAUSE
+
+// Request the USB services are started
+RUN_TEST_STEP -1, t_usb, StartUsb
+
+PRINT Please insert USB cable
+PAUSE
+
+// Wait for the bus to re-enumerate
+RUN_TEST_STEP -1, t_usb, WaitForUsb
+
+// Stop the USB services
+RUN_TEST_STEP -1, t_usb, StopUsb
+
+// Close all handles
+RUN_TEST_STEP -1, t_usb, CloseAll
+
+TEST_COMPLETE 1
+
+////////////////////////////////////////
+// Test 2 - Open a comm port as DTE
+////////////////////////////////////////
+
+PRINT Please remove USB cable
+PAUSE
+
+// Request the USB services are started
+RUN_TEST_STEP -1, t_usb, StartUsb
+
+PRINT Please insert USB cable
+PAUSE
+
+// Wait for the bus to re-enumerate
+RUN_TEST_STEP -1, t_usb, WaitForUsb
+
+// Open the ACM comm port as DTE
+RUN_TEST_STEP -1, t_usb, OpenDTE
+
+// Close the port
+RUN_TEST_STEP -1, t_usb, ClosePort
+
+// Close the rest of the handles
+RUN_TEST_STEP -1, t_usb, CloseAll
+
+TEST_COMPLETE 2
+
+UNLOAD
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usb2.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,87 @@
+// Copyright (c) 2007-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:
+// t_usb2.scripts
+// t_usb tests. 
+// Test Steps available
+// "StartUsb"			- Initiate Start of USB services
+// "WaitForUsb"			- Wait for the bus to re-enumerate
+// "StartCSY"			- Ask C32 to load the ACM CSY
+// "OpenDTE"			- Open the ACM comm port as a DTE
+// "OpenDCE"			- Open the ACM comm port as a DCE
+// "Read"			- Post a Read to the comm port
+// "Write"			- Post a Write to the comm port
+// "CancelRead"			- Cancel a pending Read
+// "CancelWrite" 		- Cancel a pending Write
+// "WaitForRead"		- Wait for a Read operation to complete
+// "WaitForWrite"		- Wait for a Write operation to complete
+// "ReadOneOrMore"		- Post a ReadOneOrMore to the comm port
+// "ClosePort"			- Close the ACM port
+// "CloseCommServer"		- Close the handle to C32
+// "CloseUsb"			- Close the handle to the USB server
+// "CloseAll"			- Close all handles (port, C32 and USB server)
+// "StopUsb"			- Stop USB services
+// "NotifySignalChange"		- Post a notify request for when signals change
+// "WaitForReadCancel"		- Wait for a read operation to be cancelled completely
+// "ReadThenCancel"		- Post a read and then cancel it immediately
+// "NotifyConfigChange"		- Post a notify request for when the config changes
+// "WaitForConfigChange"	- Wait for the configuration to change
+// "NotifyBreak"		- Post a notify request for when a break occurs
+// "WaitForBreak"		- Wait for a break to occur 
+// "SetSignalsToMarkC"		- Set the signals to mark (Requires a configuration file)
+// "SetSignalsToSpaceC"		- Set the signals to space (Requires a configuration file) 
+// "CheckSignalsC"		- Check the signals match (Requires a configuration file)
+// "WaitForReadFailureC"	- Wait for read failure (Requires a configuration file)
+// "WaitForWriteFailureC"	- Wait for write failure (Requires a configuration file)
+// "OpenPortC"			- Open the ACM port configurable for role, mode and return value
+// "WaitForSignalChangeC"	- Wait for the signals to change
+// 
+//
+
+LOAD_SUITE t_usb.dll
+
+////////////////////////////////////////
+// Test 2 - Register for Config Change
+////////////////////////////////////////
+
+PRINT Please remove USB cable
+PAUSE
+
+// Request the USB services are started
+RUN_TEST_STEP -1, t_usb, StartUsb
+
+PRINT Please insert USB cable
+PAUSE
+
+// Wait for the bus to re-enumerate
+RUN_TEST_STEP -1, t_usb, WaitForUsb
+
+// Open the ACM comm port as DTE
+RUN_TEST_STEP -1, t_usb, OpenDTE
+
+// Register for Config Change
+RUN_TEST_STEP -1, t_usb, NotifyConfigChange
+
+// Register for Config Change
+RUN_TEST_STEP -1, t_usb, WaitForConfigChangeC, e:\t_usb3.ini
+
+// Close the port
+RUN_TEST_STEP -1, t_usb, ClosePort
+
+// Close the rest of the handles
+RUN_TEST_STEP -1, t_usb, CloseAll
+
+TEST_COMPLETE 2
+
+UNLOAD
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usb3.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,44 @@
+; Copyright (c) 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:
+; 
+;
+[Signal]
+Mark= 0
+Space= 0
+CheckValue= 0
+CheckValueMask= 0
+
+[Config]
+Rate= 14
+StopBits= 0
+DataBits= 3
+Parity= 0
+
+[Write]
+FailureValue= -3
+
+[Read]
+FailureValue= -6702
+
+[Port]
+OpenMode= 0
+OpenRole= 0
+OpenReturnValue= 0
+
+[State]
+Target= 6
+
+[UsbManState]
+StateMask= 40
+ExpectedState= 8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usb3.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,88 @@
+// Copyright (c) 2007-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:
+// t_usb tests. 
+// Test Steps available
+// "StartUsb"				- Initiate Start of USB services
+// "WaitForUsb"				- Wait for the bus to re-enumerate
+// "StartCSY"				- Ask C32 to load the ACM CSY
+// "OpenDTE"				- Open the ACM comm port as a DTE
+// "OpenDCE"				- Open the ACM comm port as a DCE
+// "Read"				- Post a Read to the comm port
+// "Write"				- Post a Write to the comm port
+// "CancelRead"				- Cancel a pending Read
+// "CancelWrite" 			- Cancel a pending Write
+// "WaitForRead"			- Wait for a Read operation to complete
+// "WaitForWrite"			- Wait for a Write operation to complete
+// "ReadOneOrMore"			- Post a ReadOneOrMore to the comm port
+// "ClosePort"				- Close the ACM port
+// "CloseCommServer"			- Close the handle to C32
+// "CloseUsb"				- Close the handle to the USB server
+// "CloseAll"				- Close all handles (port, C32 and USB server)
+// "StopUsb"				- Stop USB services
+// "NotifySignalChange"			- Post a notify request for when signals change
+// "WaitForSignalChange"		- Wait for the signals to change
+// "WaitForReadCancel"			- Wait for a read operation to be cancelled completely
+// "ReadThenCancel"			- Post a read and then cancel it immediately
+// "NotifyConfigChange"			- Post a notify request for when the config changes
+// "NotifyBreak"			- Post a notify request for when a break occurs
+// "WaitForBreak"			- Wait for a break to occur 
+// "SetSignalsToMarkC"			- Set the signals to mark (Requires a configuration file)
+// "SetSignalsToSpaceC"			- Set the signals to space (Requires a configuration file) 
+// "CheckSignalsC"			- Check the signals match (Requires a configuration file)
+// "WaitForReadFailureC"		- Wait for read failure (Requires a configuration file)
+// "WaitForWriteFailureC"		- Wait for write failure (Requires a configuration file)
+// "OpenPortC"				- Open the ACM port configurable for role, mode and return value
+// "WaitForConfigChangeC"		- Wait for the configuration to change
+// 
+//
+
+LOAD_SUITE t_usb.dll
+
+////////////////////////////////////////
+// Test 3 - Check read fails gracefully
+// when the cable is unplugged
+////////////////////////////////////////
+
+PRINT Please remove USB cable
+PAUSE
+
+// Request the USB services are started
+RUN_TEST_STEP -1, t_usb, StartUsb
+
+PRINT Please insert USB cable
+
+// Wait for the bus to re-enumerate
+RUN_TEST_STEP -1, t_usb, WaitForUsb
+
+// Open the ACM comm port as DTE
+RUN_TEST_STEP -1, t_usb, OpenDTE
+
+// Post a read
+RUN_TEST_STEP -1, t_usb, Read
+
+PRINT Please remove USB cable
+
+// Check the read fails gracefully
+RUN_TEST_STEP -1, t_usb, WaitForReadFailureC, e:\t_usb3.ini
+
+// Close the port
+RUN_TEST_STEP -1, t_usb, ClosePort
+
+// Close the rest of the handles
+RUN_TEST_STEP -1, t_usb, CloseAll
+
+TEST_COMPLETE 3
+
+UNLOAD
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usb4.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,85 @@
+// Copyright (c) 2007-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:
+// t_usb tests. 
+// Test Steps available
+// "StartUsb"				- Initiate Start of USB services
+// "WaitForUsb"				- Wait for the bus to re-enumerate
+// "StartCSY"				- Ask C32 to load the ACM CSY
+// "OpenDTE"				- Open the ACM comm port as a DTE
+// "OpenDCE"				- Open the ACM comm port as a DCE
+// "Read"				- Post a Read to the comm port
+// "Write"				- Post a Write to the comm port
+// "CancelRead"				- Cancel a pending Read
+// "CancelWrite" 			- Cancel a pending Write
+// "WaitForRead"			- Wait for a Read operation to complete
+// "WaitForWrite"			- Wait for a Write operation to complete
+// "ReadOneOrMore"			- Post a ReadOneOrMore to the comm port
+// "ClosePort"				- Close the ACM port
+// "CloseCommServer"			- Close the handle to C32
+// "CloseUsb"				- Close the handle to the USB server
+// "CloseAll"				- Close all handles (port, C32 and USB server)
+// "StopUsb"				- Stop USB services
+// "NotifySignalChange"			- Post a notify request for when signals change
+// "WaitForSignalChange"		- Wait for the signals to change
+// "WaitForReadCancel"			- Wait for a read operation to be cancelled completely
+// "ReadThenCancel"			- Post a read and then cancel it immediately
+// "NotifyConfigChange"			- Post a notify request for when the config changes
+// "WaitForConfigChange"		- Wait for the configuration to change
+// "NotifyBreak"			- Post a notify request for when a break occurs
+// "WaitForBreak"			- Wait for a break to occur 
+// "SetSignalsToMarkC"			- Set the signals to mark (Requires a configuration file)
+// "SetSignalsToSpaceC"			- Set the signals to space (Requires a configuration file) 
+// "CheckSignalsC"			- Check the signals match (Requires a configuration file)
+// "WaitForReadFailureC"		- Wait for read failure (Requires a configuration file)
+// "WaitForWriteFailureC"		- Wait for write failure (Requires a configuration file)
+// "OpenPortC"				- Open the ACM port configurable for role, mode and return value
+// 
+//
+
+LOAD_SUITE t_usb.dll
+
+////////////////////////////////////////
+// Test 4 - Check read cancel completes
+// correctly
+////////////////////////////////////////
+
+PRINT Please remove USB cable
+PAUSE
+
+// Request the USB services are started
+RUN_TEST_STEP -1, t_usb, StartUsb
+
+PRINT Please insert USB cable
+PAUSE
+
+// Wait for the bus to re-enumerate
+RUN_TEST_STEP -1, t_usb, WaitForUsb
+
+// Open the ACM comm port as DTE
+RUN_TEST_STEP -1, t_usb, OpenDTE
+
+// Post a read then cancel it immediately
+// and wait for completion of the read
+RUN_TEST_STEP -1, t_usb, ReadThenCancel
+
+// Close the port
+RUN_TEST_STEP -1, t_usb, ClosePort
+
+// Close the rest of the handles
+RUN_TEST_STEP -1, t_usb, CloseAll
+
+TEST_COMPLETE 4
+
+UNLOAD
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usb5.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,89 @@
+// Copyright (c) 2007-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:
+// t_usb tests. 
+// Test Steps available
+// "StartUsb"				- Initiate Start of USB services
+// "WaitForUsb"				- Wait for the bus to re-enumerate
+// "StartCSY"				- Ask C32 to load the ACM CSY
+// "OpenDTE"				- Open the ACM comm port as a DTE
+// "OpenDCE"				- Open the ACM comm port as a DCE
+// "Read"				- Post a Read to the comm port
+// "Write"				- Post a Write to the comm port
+// "CancelRead"				- Cancel a pending Read
+// "CancelWrite" 			- Cancel a pending Write
+// "WaitForRead"			- Wait for a Read operation to complete
+// "WaitForWrite"			- Wait for a Write operation to complete
+// "ReadOneOrMore"			- Post a ReadOneOrMore to the comm port
+// "ClosePort"				- Close the ACM port
+// "CloseCommServer"			- Close the handle to C32
+// "CloseUsb"				- Close the handle to the USB server
+// "CloseAll"				- Close all handles (port, C32 and USB server)
+// "StopUsb"				- Stop USB services
+// "NotifySignalChange"			- Post a notify request for when signals change
+// "WaitForSignalChange"		- Wait for the signals to change
+// "WaitForReadCancel"			- Wait for a read operation to be cancelled completely
+// "ReadThenCancel"			- Post a read and then cancel it immediately
+// "NotifyConfigChange"			- Post a notify request for when the config changes
+// "WaitForConfigChange"		- Wait for the configuration to change
+// "NotifyBreak"			- Post a notify request for when a break occurs
+// "WaitForBreak"			- Wait for a break to occur 
+// "SetSignalsToMarkC"			- Set the signals to mark (Requires a configuration file)
+// "SetSignalsToSpaceC"			- Set the signals to space (Requires a configuration file) 
+// "CheckSignalsC"			- Check the signals match (Requires a configuration file)
+// "WaitForReadFailureC"		- Wait for read failure (Requires a configuration file)
+// "WaitForWriteFailureC"		- Wait for write failure (Requires a configuration file)
+// "OpenPortC"				- Open the ACM port configurable for role, mode and return value
+// 
+//
+
+LOAD_SUITE t_usb.dll
+
+////////////////////////////////////////////
+// Test 5 - Check SignalChange Notification
+////////////////////////////////////////////
+
+PRINT Please remove USB cable
+PAUSE
+
+// Request the USB services are started
+RUN_TEST_STEP -1, t_usb, StartUsb
+
+PRINT Please insert USB cable
+PAUSE
+
+// Wait for the bus to re-enumerate
+RUN_TEST_STEP -1, t_usb, WaitForUsb
+
+// Open the ACM comm port as DTE
+RUN_TEST_STEP -1, t_usb, OpenDTE
+
+// Post a notification request for signal change
+RUN_TEST_STEP -1, t_usb, NotifySignalChange
+
+PRINT Please change signals on the host
+PAUSE
+
+// Wait for signal change notification
+RUN_TEST_STEP -1, t_usb, WaitForSignalChange
+
+// Close the port
+RUN_TEST_STEP -1, t_usb, ClosePort
+
+// Close the rest of the handles
+RUN_TEST_STEP -1, t_usb, CloseAll
+
+TEST_COMPLETE 5
+
+UNLOAD
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usb6.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,93 @@
+// Copyright (c) 2007-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:
+// t_usb tests. 
+// Test Steps available
+// "StartUsb"				- Initiate Start of USB services
+// "WaitForUsb"				- Wait for the bus to re-enumerate
+// "StartCSY"				- Ask C32 to load the ACM CSY
+// "OpenDTE"				- Open the ACM comm port as a DTE
+// "OpenDCE"				- Open the ACM comm port as a DCE
+// "Read"				- Post a Read to the comm port
+// "Write"				- Post a Write to the comm port
+// "CancelRead"				- Cancel a pending Read
+// "CancelWrite" 			- Cancel a pending Write
+// "WaitForRead"			- Wait for a Read operation to complete
+// "WaitForWrite"			- Wait for a Write operation to complete
+// "ReadOneOrMore"			- Post a ReadOneOrMore to the comm port
+// "ClosePort"				- Close the ACM port
+// "CloseCommServer"			- Close the handle to C32
+// "CloseUsb"				- Close the handle to the USB server
+// "CloseAll"				- Close all handles (port, C32 and USB server)
+// "StopUsb"				- Stop USB services
+// "NotifySignalChange"			- Post a notify request for when signals change
+// "WaitForSignalChange"		- Wait for the signals to change
+// "WaitForReadCancel"			- Wait for a read operation to be cancelled completely
+// "ReadThenCancel"			- Post a read and then cancel it immediately
+// "NotifyConfigChange"			- Post a notify request for when the config changes
+// "WaitForConfigChange"		- Wait for the configuration to change
+// "NotifyBreak"			- Post a notify request for when a break occurs
+// "WaitForBreak"			- Wait for a break to occur 
+// "SetSignalsToMarkC"			- Set the signals to mark (Requires a configuration file)
+// "SetSignalsToSpaceC"			- Set the signals to space (Requires a configuration file) 
+// "CheckSignalsC"			- Check the signals match (Requires a configuration file)
+// "WaitForReadFailureC"		- Wait for read failure (Requires a configuration file)
+// "WaitForWriteFailureC"		- Wait for write failure (Requires a configuration file)
+// "OpenPortC"				- Open the ACM port configurable for role, mode and return value
+// 
+//
+
+LOAD_SUITE t_usb.dll
+
+////////////////////////////////////////////
+// Test 6 - Post a Read, cancel it and repost
+// another read and check that it completes
+////////////////////////////////////////////
+
+PRINT Please remove USB cable
+PAUSE
+
+// Request the USB services are started
+RUN_TEST_STEP -1, t_usb, StartUsb
+
+PRINT Please insert USB cable
+PAUSE
+
+// Wait for the bus to re-enumerate
+RUN_TEST_STEP -1, t_usb, WaitForUsb
+
+// Open the ACM comm port as DTE
+RUN_TEST_STEP -1, t_usb, OpenDTE
+
+// Post a read then cancel it
+RUN_TEST_STEP -1, t_usb, ReadThenCancel
+
+// Post another read 
+RUN_TEST_STEP -1, t_usb, Read
+
+PRINT Please luanch hyperterm and type some data
+PAUSE
+
+// Wait for read to complete
+RUN_TEST_STEP -1, t_usb, WaitForRead
+
+// Close the port
+RUN_TEST_STEP -1, t_usb, ClosePort
+
+// Close the rest of the handles
+RUN_TEST_STEP -1, t_usb, CloseAll
+
+TEST_COMPLETE 6
+
+UNLOAD
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usb7.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,86 @@
+// Copyright (c) 2007-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:
+// t_usb tests. 
+// Test Steps available
+// "StartUsb"				- Initiate Start of USB services
+// "WaitForUsb"				- Wait for the bus to re-enumerate
+// "StartCSY"				- Ask C32 to load the ACM CSY
+// "OpenDTE"				- Open the ACM comm port as a DTE
+// "OpenDCE"				- Open the ACM comm port as a DCE
+// "Read"				- Post a Read to the comm port
+// "Write"				- Post a Write to the comm port
+// "CancelRead"				- Cancel a pending Read
+// "CancelWrite" 			- Cancel a pending Write
+// "WaitForRead"			- Wait for a Read operation to complete
+// "WaitForWrite"			- Wait for a Write operation to complete
+// "ReadOneOrMore"			- Post a ReadOneOrMore to the comm port
+// "ClosePort"				- Close the ACM port
+// "CloseCommServer"			- Close the handle to C32
+// "CloseUsb"				- Close the handle to the USB server
+// "CloseAll"				- Close all handles (port, C32 and USB server)
+// "StopUsb"				- Stop USB services
+// "NotifySignalChange"			- Post a notify request for when signals change
+// "WaitForSignalChange"		- Wait for the signals to change
+// "WaitForReadCancel"			- Wait for a read operation to be cancelled completely
+// "ReadThenCancel"			- Post a read and then cancel it immediately
+// "NotifyConfigChange"			- Post a notify request for when the config changes
+// "NotifyBreak"			- Post a notify request for when a break occurs
+// "WaitForBreak"			- Wait for a break to occur 
+// "SetSignalsToMarkC"			- Set the signals to mark (Requires a configuration file)
+// "SetSignalsToSpaceC"			- Set the signals to space (Requires a configuration file) 
+// "CheckSignalsC"			- Check the signals match (Requires a configuration file)
+// "WaitForReadFailureC"		- Wait for read failure (Requires a configuration file)
+// "WaitForWriteFailureC"		- Wait for write failure (Requires a configuration file)
+// "OpenPortC"				- Open the ACM port configurable for role, mode and return value
+// "WaitForConfigChangeC"		- Wait for the configuration to change
+// "NotifyStateChange"			- Post a notify request for when the LDD state changes
+// "WaitForStateChangeC"		- Wait for the LDD to change state (Requires a configuration file)
+// 
+//
+
+LOAD_SUITE t_usb.dll
+
+////////////////////////////////////////
+// Test 7 - Check the LDD state changes
+// when the cable is unplugged
+////////////////////////////////////////
+
+PRINT Please remove USB cable
+PAUSE
+
+// Request the USB services are started
+RUN_TEST_STEP -1, t_usb, StartUsb
+
+PRINT Please insert USB cable
+PAUSE
+
+// Wait for the bus to re-enumerate
+RUN_TEST_STEP -1, t_usb, WaitForUsb
+
+// Post a request for state notification
+RUN_TEST_STEP -1, t_usb, NotifyStateChange
+
+PRINT Please remove USB cable
+PAUSE
+
+// Check that the LDD's state changes
+RUN_TEST_STEP -1, t_usb, WaitForStateChangeC, e:\t_usb3.ini
+
+// Close all of the handles
+RUN_TEST_STEP -1, t_usb, CloseAll
+
+TEST_COMPLETE 7
+
+UNLOAD
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usb_sample.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+; Copyright (c) 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:
+; 
+;
+[Signal]
+Mark= 0
+Space= 0
+CheckValue= 0
+CheckValueMask= 0
+
+[Config]
+Rate= 0
+StopBits= 0
+DataBits= 0
+Parity= 0
+
+[Write]
+FailureValue= -2
+
+[Read]
+FailureValue= -2
+
+[Port]
+OpenMode= 0
+OpenRole= 0
+OpenReturnValue= 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usbman1.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,18 @@
+; Copyright (c) 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:
+; 
+;
+[UsbManState]
+StateMask= 40
+ExpectedState= 32
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usbman1.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,92 @@
+// Copyright (c) 2007-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:
+// T_Usb tests. 
+// Test Steps available
+// "StartUsb"				- Initiate Start of USB services
+// "WaitForUsb"				- Wait for the bus to re-enumerate
+// "StartCSY"				- Ask C32 to load the ACM CSY
+// "OpenDTE"				- Open the ACM comm port as a DTE
+// "OpenDCE"				- Open the ACM comm port as a DCE
+// "Read"				- Post a Read to the comm port
+// "Write"				- Post a Write to the comm port
+// "CancelRead"				- Cancel a pending Read
+// "CancelWrite" 			- Cancel a pending Write
+// "WaitForRead"			- Wait for a Read operation to complete
+// "WaitForWrite"			- Wait for a Write operation to complete
+// "ReadOneOrMore"			- Post a ReadOneOrMore to the comm port
+// "ClosePort"				- Close the ACM port
+// "CloseCommServer"			- Close the handle to C32
+// "CloseUsb"				- Close the handle to the USB server
+// "CloseAll"				- Close all handles (port, C32 and USB server)
+// "StopUsb"				- Stop USB services
+// "NotifySignalChange"			- Post a notify request for when signals change
+// "WaitForSignalChange"		- Wait for the signals to change
+// "WaitForReadCancel"			- Wait for a read operation to be cancelled completely
+// "ReadThenCancel"			- Post a read and then cancel it immediately
+// "NotifyConfigChange"			- Post a notify request for when the config changes
+// "WaitForConfigChange"		- Wait for the configuration to change
+// "NotifyBreak"			- Post a notify request for when a break occurs
+// "WaitForBreak"			- Wait for a break to occur 
+// "SetSignalsToMarkC"			- Set the signals to mark (Requires a configuration file)
+// "SetSignalsToSpaceC"			- Set the signals to space (Requires a configuration file) 
+// "CheckSignalsC"			- Check the signals match (Requires a configuration file)
+// "WaitForReadFailureC"		- Wait for read failure (Requires a configuration file)
+// "WaitForWriteFailureC"		- Wait for write failure (Requires a configuration file)
+// "OpenPortC"				- Open the ACM port configurable for role, mode and return value
+// "UMNotifyStateChangeC"		- Post a notify for state change (via RUsb)
+// "UMWaitForStateChgeC"		- Wait for a state change to happen (via RUsb)
+// 
+//
+
+LOAD_SUITE t_usb.dll
+
+////////////////////////////////////////////
+// Test 1 - Check that state notification
+// via RUsb works (configured state)
+////////////////////////////////////////////
+
+PRINT Please remove USB cable
+PAUSE
+
+// Request the USB services are started
+RUN_TEST_STEP -1, t_usb, StartUsb
+
+// Request a notification when the state changes
+RUN_TEST_STEP -1, t_usb, UMNotifyStateChangeC, e:\t_usbman1.ini
+
+PRINT Please insert USB cable
+PAUSE
+
+// Wait for the bus to re-enumerate
+RUN_TEST_STEP -1, t_usb, WaitForUsb
+
+// Wait for the state to change to configured
+RUN_TEST_STEP -1, t_usb, UMWaitForStateChgeC, e:\t_usbman1.ini
+
+// Request a notification when the state changes
+RUN_TEST_STEP -1, t_usb, UMNotifyStateChangeC, e:\t_usbman2.ini
+
+PRINT Please remove the USB cable
+PAUSE
+
+// Wait for the state to change to suspended
+RUN_TEST_STEP -1, t_usb, UMWaitForStateChgeC, e:\t_usbman2.ini
+
+// Close the rest of the handles
+RUN_TEST_STEP -1, t_usb, CloseAll
+
+TEST_COMPLETE 1
+
+UNLOAD
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/scripts/t_usbman2.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,18 @@
+; Copyright (c) 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:
+; 
+;
+[UsbManState]
+StateMask= 40
+ExpectedState= 8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/src/UsbManTest1.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,87 @@
+/*
+* Copyright (c) 2007-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:
+* This contains UsbMan Test Section 1
+*
+*/
+
+// EPOC includes
+#include <e32base.h>
+
+// Usb Test system includes
+#include <networking/log.h>
+#include "UsbStep.h"
+#include "UsbSuite.h"
+#include "UsbManTest1.h"
+
+
+_LIT(KUsbmanStateSection,   "UsbManState");
+_LIT(KUsbmanStateMask,      "StateMask");
+_LIT(KUsbmanExpectedState,  "ExpectedState");
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.1
+CTestUsbManNotifyStateChange::CTestUsbManNotifyStateChange()
+	{
+	// store the name of this test case
+	iTestStepName = _L("UMNotifyStateChangeC");
+	}
+
+// Test 1.1 Destructor
+CTestUsbManNotifyStateChange::~CTestUsbManNotifyStateChange()
+	{	
+	}
+
+// Test 1.1 Main Code
+enum TVerdict CTestUsbManNotifyStateChange::doTestStepL()
+	{
+	TUint32 stateMask;
+
+	TESTL(GetIntFromConfig(KUsbmanStateSection, KUsbmanStateMask, (TInt&) stateMask));
+
+	Log(_L("CTestUsbManNotifyStateChange::doTestStepL() - Posting notification request"));
+	iUsbSuite->iUsb.StateNotification(stateMask, iUsbSuite->iUsbManState, iUsbSuite->iNotifyStateStatus);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.2
+CTestUsbManWaitForStateChange::CTestUsbManWaitForStateChange()
+	{
+	// store the name of this test case
+	iTestStepName = _L("UMWaitForStateChgeC");
+	}
+
+// Test 1.1 Destructor
+CTestUsbManWaitForStateChange::~CTestUsbManWaitForStateChange()
+	{	
+	}
+
+// Test 1.1 Main Code
+enum TVerdict CTestUsbManWaitForStateChange::doTestStepL()
+	{
+	TUsbDeviceState expectedState;
+
+	TESTL(GetIntFromConfig(KUsbmanStateSection, KUsbmanExpectedState, (TInt&) expectedState));
+
+	User::WaitForRequest(iUsbSuite->iNotifyStateStatus);
+	Log(_L("CTestUsbManWaitForStateChange::doTestStepL() - State in the config file is %d"), expectedState);
+	Log(_L("CTestUsbManWaitForStateChange::doTestStepL() - State changed to %d"), iUsbSuite->iUsbManState);
+
+	TESTL(expectedState == iUsbSuite->iUsbManState);
+	return iTestStepResult;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/src/UsbStep.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,105 @@
+/*
+* Copyright (c) 2007-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:
+* This contains CTestStepUsb which is the base class for all the Usb Test Steps
+*
+*/
+
+// EPOC includes
+#include <e32base.h>
+#include <c32comm.h>
+
+// Test system includes
+#include <networking/log.h>
+#include "UsbStep.h"
+#include "UsbSuite.h"
+
+_LIT(KUsbLddName, "eusbc");
+
+/**
+ * The CTestStepUsb::CTestStepUsb method
+ *
+ *
+ *
+ * @internalComponent
+ *
+ * @return	
+ */
+CTestStepUsb::CTestStepUsb()
+	: iUsbSuite(0)
+	{
+	}
+
+
+/**
+ * The CTestStepUsb::~CTestStepUsb method
+ *
+ *
+ *
+ * @internalComponent
+ *
+ * @return	
+ */
+CTestStepUsb::~CTestStepUsb()
+	{ 
+	}	
+
+void CTestStepUsb::OpenCommServerL()
+	{
+	if (!iUsbSuite->iCommServerOpen)
+		{
+		TInt err = iUsbSuite->iCommServer.Connect();
+		TESTL(err == KErrNone || err == KErrAlreadyExists);
+		iUsbSuite->iCommServerOpen = ETrue;
+
+		Log(_L("CTestStepUsb::doTestStepL() - Connected to C32"));
+
+		err = iUsbSuite->iCommServer.LoadCommModule(CSY_NAME);
+		TESTL(err == KErrNone || err == KErrAlreadyExists);
+
+		Log(_L("CTestStepUsb::doTestStepL() = Loaded ACM CSY"));
+		}
+	else
+		{
+		TEST(ETrue);
+		}
+	}
+
+TInt CTestStepUsb::OpenLdd()
+	{
+	if (iUsbSuite->iLddOpen)
+		{
+		return KErrNone;
+		}
+
+	TInt err = User::LoadLogicalDevice(KUsbLddName);
+
+	if (err != KErrNone && err != KErrAlreadyExists)
+		{
+		Log(_L("CTestStepUsb::OpenLdd() - Unable to load LDD! Error = %d"), err);
+		return err;
+		}
+
+	err = iUsbSuite->iLdd.Open(0);
+	if (err != KErrNone)
+		{
+		Log(_L("CTestStepUsb::OpenLdd() - Unable to Open LDD! Error = %d"), err);
+		return err;
+		}
+
+	iUsbSuite->iLddOpen = ETrue;
+	iUsbSuite->iLdd.SetDeviceControl();
+	iUsbSuite->iLdd.ReleaseDeviceControl();
+	return KErrNone;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/src/UsbSuite.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,155 @@
+/*
+* Copyright (c) 2007-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:
+* This main DLL entry point for the T_Usb.dll
+*
+*/
+
+
+
+// EPOC includes
+#include <e32base.h>
+#include <c32comm.h>
+
+// Usb Test system includes
+#include <networking/log.h>
+#include "UsbStep.h"
+#include "UsbSuite.h"
+
+// Test case includes
+#include "UsbTest1.h"
+#include "UsbTest2.h"
+#include "UsbManTest1.h"
+
+
+
+EXPORT_C CTestSuiteUsb* NewTestSuiteUsb( void ) 
+    {
+	CTestSuiteUsb* ts = 0;
+	TRAPD(err,ts = new (ELeave) CTestSuiteUsb);
+	if (err == KErrNone)
+		return ts;
+	return 0;
+    }
+
+// destructor
+CTestSuiteUsb::~CTestSuiteUsb()
+	{
+	}
+
+// Add a test step into the suite
+void CTestSuiteUsb::AddTestStepL(CTestStepUsb* aTestStep)
+{
+	// test steps contain a pointer back to the suite which owns them
+	aTestStep->iUsbSuite = this; 
+
+	// add the step using the base class method
+	CTestSuite::AddTestStepL(aTestStep);
+}
+
+
+// second phase constructor for Usb test suite
+// this creates all the Usb test steps and
+// stores them inside CTestSuiteUsb
+void CTestSuiteUsb::InitialiseL( void )
+{
+	iPortOpen		= EFalse;
+	iCommServerOpen = EFalse;
+	iUsbOpen		= EFalse;
+
+	TInt ret = StartC32();
+	if ( KErrNone != ret && KErrAlreadyExists != ret )
+		{
+		User::Leave( ret );
+		}
+	
+	// store the name of this test suite
+	OverrideSuiteName(_L("Usb"));
+
+	// Add Test steps
+	AddTestStepL(new (ELeave) CTestStartUsb);
+	AddTestStepL(new (ELeave) CTestWaitForUsb);
+	AddTestStepL(new (ELeave) CTestStartCsy);
+	AddTestStepL(new (ELeave) CTestOpenDTEPort);
+	AddTestStepL(new (ELeave) CTestOpenDCEPort);
+	AddTestStepL(new (ELeave) CTestPostRead);
+	AddTestStepL(new (ELeave) CTestPostWrite);
+	AddTestStepL(new (ELeave) CTestCancelRead);
+	AddTestStepL(new (ELeave) CTestCancelWrite);
+	AddTestStepL(new (ELeave) CTestWaitForRead);
+	AddTestStepL(new (ELeave) CTestWaitForWrite);
+	AddTestStepL(new (ELeave) CTestPostReadOneOrMore);
+	AddTestStepL(new (ELeave) CTestClosePort);
+	AddTestStepL(new (ELeave) CTestCloseCommServer);
+	AddTestStepL(new (ELeave) CTestCloseUsbServer);
+	AddTestStepL(new (ELeave) CTestStopUsb);
+	AddTestStepL(new (ELeave) CTestNotifySignalChange);
+	AddTestStepL(new (ELeave) CTestWaitForSignalChange);
+	AddTestStepL(new (ELeave) CTestWaitForReadCancel);
+	AddTestStepL(new (ELeave) CTestPostReadThenCancel);
+	AddTestStepL(new (ELeave) CTestNotifyConfigChange);
+	AddTestStepL(new (ELeave) CTestNotifyBreak);
+	AddTestStepL(new (ELeave) CTestWaitForBreak);
+	AddTestStepL(new (ELeave) CTestCloseAll);
+
+	// Test steps that require a configuration file
+	AddTestStepL(new (ELeave) CTestSetSignalsToMark);
+	AddTestStepL(new (ELeave) CTestSetSignalsToSpace);
+	AddTestStepL(new (ELeave) CTestCheckSignals);
+	AddTestStepL(new (ELeave) CTestWaitForReadFailure);
+	AddTestStepL(new (ELeave) CTestWaitForWriteFailure);
+	AddTestStepL(new (ELeave) CTestOpenPort);
+	AddTestStepL(new (ELeave) CTestWaitForConfigChange);
+	AddTestStepL(new (ELeave) CTestNotifyStateChange);
+	AddTestStepL(new (ELeave) CTestWaitForStateChange);
+
+	// UsbMan tests
+	AddTestStepL(new (ELeave) CTestUsbManWaitForStateChange);
+	AddTestStepL(new (ELeave) CTestUsbManNotifyStateChange);
+}
+
+
+// make a version string available for test system 
+_LIT(KTxtVersion,"1.001");
+TPtrC CTestSuiteUsb::GetVersion( void )
+	{
+	return KTxtVersion();
+	}
+
+void CTestSuiteUsb::CloseAll()
+	{
+	if (iPortOpen)
+		{
+		iCommPort.Close();
+		iPortOpen = EFalse;
+		}
+
+	if (iCommServerOpen)
+		{
+		iCommServer.Close();
+		iCommServerOpen = EFalse;
+		}
+
+	if (iUsbOpen)
+		{
+		iUsb.Close();
+		iUsbOpen = EFalse;
+		}
+
+	if (iLddOpen)
+		{
+		iLdd.Close();
+		iLddOpen = EFalse;
+		}
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/src/UsbTest1.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,617 @@
+/*
+* Copyright (c) 2007-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:
+* This contains Usb Test Section 1
+*
+*/
+
+// EPOC includes
+#include <e32base.h>
+
+// Usb Test system includes
+#include <networking/log.h>
+#include "UsbStep.h"
+#include "UsbSuite.h"
+#include "UsbTest1.h"
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.1
+CTestStartUsb::CTestStartUsb()
+	{
+	// store the name of this test case
+	iTestStepName = _L("StartUsb");
+	}
+
+// Test 1.1 Destructor
+CTestStartUsb::~CTestStartUsb()
+	{	
+	}
+
+// Test 1.1 Main Code
+enum TVerdict CTestStartUsb::doTestStepL()
+	{
+	if (!iUsbSuite->iUsbOpen)
+		{
+		TESTL(iUsbSuite->iUsb.Connect() == KErrNone);
+		iUsbSuite->iUsbOpen = ETrue;
+		}
+
+	iUsbSuite->iUsb.Start(iUsbSuite->iStartStatus);
+	Log(_L("CTestStartUsb::doTestStepL() - Requested USB service start"));
+	return iTestStepResult;
+	}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.2
+CTestWaitForUsb::CTestWaitForUsb()
+	{
+	// store the name of this test case
+	iTestStepName = _L("WaitForUsb");
+	}
+
+// Test 1.2 Destructor
+CTestWaitForUsb::~CTestWaitForUsb()
+	{
+	}
+
+// Test 1.2	Main Code
+enum TVerdict CTestWaitForUsb::doTestStepL()
+	{
+	User::WaitForRequest(iUsbSuite->iStartStatus);
+	Log(_L("CTestWaitForUsb::doTestStepL() - Usb Start returned %d"), iUsbSuite->iStartStatus.Int());
+	TESTL(iUsbSuite->iStartStatus.Int() == KErrNone);
+	return iTestStepResult;
+	}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.3
+CTestStartCsy::CTestStartCsy()
+	{
+	// store the name of this test case
+	iTestStepName = _L("StartCSY");
+	}
+
+// destructor
+CTestStartCsy::~CTestStartCsy()
+	{	
+	}
+
+// Test 1.3	Main Code
+enum TVerdict CTestStartCsy::doTestStepL()
+	{
+	OpenCommServerL();
+	return iTestStepResult;
+	}	
+
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.4
+CTestOpenDTEPort::CTestOpenDTEPort()
+	{
+	// store the name of this test case
+	iTestStepName = _L("OpenDTE");
+	}
+
+// Test 1.4 Destructor
+CTestOpenDTEPort::~CTestOpenDTEPort()
+	{	
+	}
+
+// Test 1.4	Main Code
+enum TVerdict CTestOpenDTEPort::doTestStepL()
+	{
+	OpenCommServerL();
+
+	if (!iUsbSuite->iPortOpen)
+		{
+		TInt err = iUsbSuite->iCommPort.Open(iUsbSuite->iCommServer, PORT_NAME, ECommExclusive, ECommRoleDTE);
+		TESTL(err == KErrNone);
+		iUsbSuite->iPortOpen = ETrue;
+		Log(_L("CTestOpenDTEPort::doTestStepL() - Opened ACM comm port, role DTE"));
+		}
+	else
+		{
+		TEST(ETrue);
+		}
+
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.5
+CTestOpenDCEPort::CTestOpenDCEPort()
+	{
+	// store the name of this test case
+	iTestStepName = _L("OpenDCE");
+	}
+
+// Test 1.5 Destructor
+CTestOpenDCEPort::~CTestOpenDCEPort()
+	{
+	}
+
+// Test 1.5 Main Code
+enum TVerdict CTestOpenDCEPort::doTestStepL()
+	{
+	OpenCommServerL();
+
+	if (!iUsbSuite->iPortOpen)
+		{
+		TInt err = iUsbSuite->iCommPort.Open(iUsbSuite->iCommServer, PORT_NAME, ECommExclusive, ECommRoleDCE);
+		TESTL(err == KErrNone);
+		iUsbSuite->iPortOpen = ETrue;
+
+		Log(_L("CTestOpenDCEPort::doTestStepL() - Opened ACM comm port, role DCE"));
+		}
+	else
+		{
+		TEST(ETrue);
+		}
+
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.6
+CTestPostRead::CTestPostRead()
+	{
+	// store the name of this test case
+	iTestStepName = _L("Read");
+	}
+
+// Test 1.6 Destructor
+CTestPostRead::~CTestPostRead()
+	{
+	}
+
+// Test 1.6 Main Code
+enum TVerdict CTestPostRead::doTestStepL()
+	{
+	iUsbSuite->iCommPort.Read(iUsbSuite->iReadStatus, iUsbSuite->iReadBuffer);
+	Log(_L("CTestPostRead::doTestStepL() - Read posted on ACM comm port"));
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.7
+CTestPostWrite::CTestPostWrite()
+	{
+	// store the name of this test case
+	iTestStepName = _L("Write");
+	}
+
+// Test 1.7 Destructor
+CTestPostWrite::~CTestPostWrite()
+	{
+	}
+
+// Test 1.7 Main Code
+enum TVerdict CTestPostWrite::doTestStepL()
+	{
+	iUsbSuite->iWriteBuffer.SetLength(24);
+	iUsbSuite->iWriteBuffer.Copy(_L("Hello There!"));
+	iUsbSuite->iCommPort.Write(iUsbSuite->iWriteStatus, iUsbSuite->iWriteBuffer);
+	Log(_L("CTestPostWrite::doTestStepL() - Write posted on ACM comm port"));
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.8
+CTestCancelRead::CTestCancelRead()
+	{
+	// store the name of this test case
+	iTestStepName = _L("CancelRead");
+	}
+
+// Test 1.8 Destructor
+CTestCancelRead::~CTestCancelRead()
+	{
+	}
+
+// Test 1.8 Main Code
+enum TVerdict CTestCancelRead::doTestStepL()
+	{
+	iUsbSuite->iCommPort.ReadCancel();
+	Log(_L("CTestCancelRead::doTestStepL() - Read Cancelled"));
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.9
+CTestCancelWrite::CTestCancelWrite()
+	{
+	// store the name of this test case
+	iTestStepName = _L("CancelWrite");
+	}
+
+// Test 1.9 Destructor
+CTestCancelWrite::~CTestCancelWrite()
+	{
+	}
+
+// Test 1.9 Main Code
+enum TVerdict CTestCancelWrite::doTestStepL()
+	{
+	iUsbSuite->iCommPort.WriteCancel();
+	Log(_L("CTestCancelWrite::doTestStepL() - Write Cancelled"));
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.10
+CTestWaitForRead::CTestWaitForRead()
+	{
+	// store the name of this test case
+	iTestStepName = _L("WaitForRead");
+	}
+
+// Test 1.10 Destructor
+CTestWaitForRead::~CTestWaitForRead()
+	{
+	}
+
+// Test 1.10 Main Code
+enum TVerdict CTestWaitForRead::doTestStepL()
+	{
+	User::WaitForRequest(iUsbSuite->iReadStatus);
+	Log(_L("CTestWaitForRead::doTestStepL() - Read request returned %d"), iUsbSuite->iReadStatus.Int());
+	TESTL(iUsbSuite->iReadStatus.Int() == KErrNone);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.11
+CTestWaitForWrite::CTestWaitForWrite()
+	{
+	// store the name of this test case
+	iTestStepName = _L("WaitForWrite");
+	}
+
+// Test 1.11 Destructor
+CTestWaitForWrite::~CTestWaitForWrite()
+	{
+	}
+
+// Test 1.11 Main Code
+enum TVerdict CTestWaitForWrite::doTestStepL()
+	{
+	User::WaitForRequest(iUsbSuite->iWriteStatus);
+	Log(_L("CTestWaitForWrite::doTestStepL() - Write request returned %d"), iUsbSuite->iWriteStatus.Int());
+	TESTL(iUsbSuite->iWriteStatus.Int() == KErrNone);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.12
+CTestPostReadOneOrMore::CTestPostReadOneOrMore()
+	{
+	// store the name of this test case
+	iTestStepName = _L("ReadOneOrMore");
+	}
+
+// Test 1.12 Destructor
+CTestPostReadOneOrMore::~CTestPostReadOneOrMore()
+	{
+	}
+
+// Test 1.12 Main Code
+enum TVerdict CTestPostReadOneOrMore::doTestStepL()
+	{
+	iUsbSuite->iCommPort.ReadOneOrMore(iUsbSuite->iReadStatus, iUsbSuite->iReadBuffer);
+	Log(_L("CTestPostReadOneOrMore::doTestStepL() - Read posted on ACM comm port"));
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.13
+CTestClosePort::CTestClosePort()
+	{
+	// store the name of this test case
+	iTestStepName = _L("ClosePort");
+	}
+
+// Test 1.13 Destructor
+CTestClosePort::~CTestClosePort()
+	{
+	}
+
+// Test 1.13 Main Code
+enum TVerdict CTestClosePort::doTestStepL()
+	{
+	iUsbSuite->iCommPort.Close();
+	iUsbSuite->iPortOpen = EFalse;
+	Log(_L("CTestClosePort::doTestStepL() - ACM comm port closed"));
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.14
+CTestCloseCommServer::CTestCloseCommServer()
+	{
+	// store the name of this test case
+	iTestStepName = _L("CloseCommServer");
+	}
+
+// Test 1.14 Destructor
+CTestCloseCommServer::~CTestCloseCommServer()
+	{
+	}
+
+// Test 1.14 Main Code
+enum TVerdict CTestCloseCommServer::doTestStepL()
+	{
+	iUsbSuite->iCommServer.Close();
+	iUsbSuite->iCommServerOpen = EFalse;
+	Log(_L("CTestCloseCommServer::doTestStepL() - Comm Server handle closed"));
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.15
+CTestCloseUsbServer::CTestCloseUsbServer()
+	{
+	// store the name of this test case
+	iTestStepName = _L("CloseUsb");
+	}
+
+// Test 1.15 Destructor
+CTestCloseUsbServer::~CTestCloseUsbServer()
+	{
+	}
+
+// Test 1.15 Main Code
+enum TVerdict CTestCloseUsbServer::doTestStepL()
+	{
+	iUsbSuite->iUsb.Close();
+	iUsbSuite->iUsbOpen = EFalse;
+	Log(_L("CTestCloseUsbServer::doTestStepL() - Usb Server handle closed"));
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.16
+CTestStopUsb::CTestStopUsb()
+	{
+	// store the name of this test case
+	iTestStepName = _L("StopUsb");
+	}
+
+// Test 1.16 Destructor
+CTestStopUsb::~CTestStopUsb()
+	{
+	}
+
+// Test 1.16 Main Code
+enum TVerdict CTestStopUsb::doTestStepL()
+	{
+	iUsbSuite->iUsb.Stop();
+	Log(_L("CTestCloseUsbServer::doTestStepL() - Usb Services stopped"));
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.17
+CTestNotifySignalChange::CTestNotifySignalChange()
+	{
+	// store the name of this test case
+	iTestStepName = _L("NotifySignalChange");
+	}
+
+// Test 1.17 Destructor
+CTestNotifySignalChange::~CTestNotifySignalChange()
+	{
+	}
+
+// Test 1.17 Main Code
+enum TVerdict CTestNotifySignalChange::doTestStepL()
+	{
+	iUsbSuite->iCommPort.NotifySignalChange(iUsbSuite->iNotifySignalChangeStatus, iUsbSuite->iSignals);
+	Log(_L("CTestNotifySignalChange::doTestStepL() - Posted signal change notification request"));
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.18
+CTestWaitForSignalChange::CTestWaitForSignalChange()
+	{
+	// store the name of this test case
+	iTestStepName = _L("WaitForSignalChange");
+	}
+
+// Test 1.18 Destructor
+CTestWaitForSignalChange::~CTestWaitForSignalChange()
+	{
+	}
+
+// Test 1.18 Main Code
+enum TVerdict CTestWaitForSignalChange::doTestStepL()
+	{
+	Log(_L("CTestWaitForSignalChange::doTestStepL() - Waiting for signal change"));
+	User::WaitForRequest(iUsbSuite->iNotifySignalChangeStatus);
+	Log(_L("CTestNotifySignalChange::doTestStepL() - Signal status completed with %d"), iUsbSuite->iNotifySignalChangeStatus.Int());
+	TESTL(iUsbSuite->iNotifySignalChangeStatus.Int() == KErrNone);
+	Log(_L("CTestNotifySignalChange::doTestStepL() - Signal = %d"), iUsbSuite->iSignals);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.19
+CTestWaitForReadCancel::CTestWaitForReadCancel()
+	{
+	// store the name of this test case
+	iTestStepName = _L("WaitForReadCancel");
+	}
+
+// Test 1.19 Destructor
+CTestWaitForReadCancel::~CTestWaitForReadCancel()
+	{
+	}
+
+// Test 1.19 Main Code
+enum TVerdict CTestWaitForReadCancel::doTestStepL()
+	{
+	Log(_L("CTestWaitForReadCancel::doTestStepL() - Waiting for read status to be cancelled"));
+	User::WaitForRequest(iUsbSuite->iReadStatus);
+	Log(_L("CTestWaitForReadCancel::doTestStepL() - Signal status completed with %d"), iUsbSuite->iReadStatus.Int());
+	TESTL(iUsbSuite->iReadStatus.Int() == KErrCancel);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.20
+CTestPostReadThenCancel::CTestPostReadThenCancel()
+	{
+	// store the name of this test case
+	iTestStepName = _L("ReadThenCancel");
+	}
+
+// Test 1.20 Destructor
+CTestPostReadThenCancel::~CTestPostReadThenCancel()
+	{
+	}
+
+// Test 1.20 Main Code
+enum TVerdict CTestPostReadThenCancel::doTestStepL()
+	{
+	iUsbSuite->iCommPort.Read(iUsbSuite->iReadStatus, iUsbSuite->iReadBuffer);
+	Log(_L("CTestPostReadThenCancel::doTestStepL() - Read posted on ACM comm port"));
+	iUsbSuite->iCommPort.ReadCancel();
+	Log(_L("CTestPostReadThenCancel::doTestStepL() - Cancelling read"));
+	User::WaitForRequest(iUsbSuite->iReadStatus);
+	Log(_L("CTestPostReadThenCancel::doTestStepL() - Read status completed with %d"), iUsbSuite->iReadStatus.Int());
+	TESTL(iUsbSuite->iReadStatus.Int() == KErrCancel);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.21
+CTestNotifyConfigChange::CTestNotifyConfigChange()
+	{
+	// store the name of this test case
+	iTestStepName = _L("NotifyConfigChange");
+	}
+
+// Test 1.21 Destructor
+CTestNotifyConfigChange::~CTestNotifyConfigChange()
+	{
+	}
+
+// Test 1.21 Main Code
+enum TVerdict CTestNotifyConfigChange::doTestStepL()
+	{
+	iUsbSuite->iCommPort.NotifyConfigChange(iUsbSuite->iNotifyConfigChangeStatus, iUsbSuite->iConfig);
+	Log(_L("CTestNotifyConfigChange::doTestStepL() - Posted config change notification request"));
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.23
+CTestNotifyBreak::CTestNotifyBreak()
+	{
+	// store the name of this test case
+	iTestStepName = _L("NotifyBreak");
+	}
+
+// Test 1.23 Destructor
+CTestNotifyBreak::~CTestNotifyBreak()
+	{
+	}
+
+// Test 1.23 Main Code
+enum TVerdict CTestNotifyBreak::doTestStepL()
+	{
+	iUsbSuite->iCommPort.NotifyBreak(iUsbSuite->iNotifyBreakStatus);
+	Log(_L("CTestNotifyBreak::doTestStepL() - Posted break notification request"));
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.24
+CTestWaitForBreak::CTestWaitForBreak()
+	{
+	// store the name of this test case
+	iTestStepName = _L("WaitForBreak");
+	}
+
+// Test 1.24 Destructor
+CTestWaitForBreak::~CTestWaitForBreak()
+	{
+	}
+
+// Test 1.24 Main Code
+enum TVerdict CTestWaitForBreak::doTestStepL()
+	{
+	Log(_L("CTestWaitForBreak::doTestStepL() - Waiting for break"));
+	User::WaitForRequest(iUsbSuite->iNotifyBreakStatus);
+	Log(_L("CTestWaitForBreak::doTestStepL() - Break status completed with %d"), iUsbSuite->iNotifyBreakStatus.Int());
+	TESTL(iUsbSuite->iNotifyBreakStatus.Int() == KErrNone);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 1.25
+CTestCloseAll::CTestCloseAll()
+	{
+	// store the name of this test case
+	iTestStepName = _L("CloseAll");
+	}
+
+// Test 1.25 Destructor
+CTestCloseAll::~CTestCloseAll()
+	{
+	}
+
+// Test 1.25 Main Code
+enum TVerdict CTestCloseAll::doTestStepL()
+	{
+	iUsbSuite->CloseAll();
+	TESTL(ETrue);
+	return iTestStepResult;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/T_usb/src/UsbTest2.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,353 @@
+/*
+* Copyright (c) 2001-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:
+* This contains Usb Test Section 2
+*
+*/
+
+// EPOC includes
+#include <e32base.h>
+
+// Usb Test system includes
+#include <networking/log.h>
+#include "UsbStep.h"
+#include "UsbSuite.h"
+#include "UsbTest2.h"
+
+_LIT(KSignalSection,        "Signal");
+_LIT(KSignalMark,           "Mark");
+_LIT(KSignalSpace,          "Space");
+_LIT(KSignalCheckValue,     "CheckValue");
+_LIT(KSignalCheckValueMask, "CheckValueMask");
+
+_LIT(KConfigSection,		"Config");
+_LIT(KConfigRate,			"Rate");
+_LIT(KConfigStopBits,		"StopBits");
+_LIT(KConfigDataBits,		"DataBits");
+_LIT(KConfigParity,			"Parity");
+
+_LIT(KWriteSection,			"Write");
+_LIT(KWriteFailureValue,	"FailureValue");
+
+_LIT(KReadSection,			"Read");
+_LIT(KReadFailureValue,		"FailureValue");
+
+_LIT(KPortSection,			"Port");
+_LIT(KPortOpenMode,			"OpenMode");
+_LIT(KPortOpenRole,			"OpenRole");
+_LIT(KPortOpenReturnValue,	"OpenReturnValue");
+
+_LIT(KStateSection,			"State");
+_LIT(KStateTarget,			"Target");
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 2.1
+CTestSetSignalsToMark::CTestSetSignalsToMark()
+	{
+	// store the name of this test case
+	iTestStepName = _L("SetSignalsToMarkC");
+	}
+
+// Test 2.1 Destructor
+CTestSetSignalsToMark::~CTestSetSignalsToMark()
+	{	
+	}
+
+// Test 2.1 Main Code
+enum TVerdict CTestSetSignalsToMark::doTestStepL()
+	{
+	TUint mask;
+	TESTL(GetIntFromConfig(KSignalSection, KSignalMark, (TInt&) mask));
+	iUsbSuite->iCommPort.SetSignalsToMark(mask);
+	Log(_L("CTestSetSignalsToMark::doTestStepL() - Signal to mark set to 0x%x"), mask);
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 2.2
+CTestSetSignalsToSpace::CTestSetSignalsToSpace()
+	{
+	// store the name of this test case
+	iTestStepName = _L("SetSignalsToSpaceC");
+	}
+
+// Test 2.2 Destructor
+CTestSetSignalsToSpace::~CTestSetSignalsToSpace()
+	{	
+	}
+
+// Test 2.2 Main Code
+enum TVerdict CTestSetSignalsToSpace::doTestStepL()
+	{
+	TUint mask;
+	TESTL(GetIntFromConfig(KSignalSection, KSignalSpace, (TInt&) mask));
+	iUsbSuite->iCommPort.SetSignalsToSpace(mask);
+	Log(_L("CTestSetSignalsToSpace::doTestStepL() - Signal to space set to 0x%x"), mask);
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 2.3
+CTestCheckSignals::CTestCheckSignals()
+	{
+	// store the name of this test case
+	iTestStepName = _L("CheckSignalsC");
+	}
+
+// Test 2.3 Destructor
+CTestCheckSignals::~CTestCheckSignals()
+	{	
+	}
+
+// Test 2.3 Main Code
+enum TVerdict CTestCheckSignals::doTestStepL()
+	{
+	TUint checkValue;
+	TUint checkValueMask;
+	TUint currentValue;
+
+	TESTL(GetIntFromConfig(KSignalSection, KSignalCheckValue, (TInt&) checkValue));
+
+	if (GetIntFromConfig(KSignalSection, KSignalCheckValueMask, (TInt&) checkValueMask))
+		currentValue = iUsbSuite->iCommPort.Signals(checkValueMask);
+	else
+		currentValue = iUsbSuite->iCommPort.Signals();
+
+	Log(_L("CTestCheckSignals::doTestStepL() - Current signals set to 0x%x with mask 0x%x"), currentValue, checkValueMask);
+	TEST(currentValue == checkValue);
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 2.4
+CTestWaitForReadFailure::CTestWaitForReadFailure()
+	{
+	// store the name of this test case
+	iTestStepName = _L("WaitForReadFailureC");
+	}
+
+// Test 2.4 Destructor
+CTestWaitForReadFailure::~CTestWaitForReadFailure()
+	{	
+	}
+
+// Test 2.4 Main Code
+enum TVerdict CTestWaitForReadFailure::doTestStepL()
+	{
+	TInt failureValue;
+
+	TESTL(GetIntFromConfig(KReadSection, KReadFailureValue, failureValue));
+
+	Log(_L("CTestWaitForReadFailure::doTestStepL() - Waiting for read status to be complete with error"));
+	User::WaitForRequest(iUsbSuite->iReadStatus);
+	Log(_L("CTestWaitForReadFailure::doTestStepL() - Read status completed with %d"), iUsbSuite->iReadStatus.Int());
+	TEST(iUsbSuite->iReadStatus.Int() == failureValue);
+
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 2.5
+CTestWaitForWriteFailure::CTestWaitForWriteFailure()
+	{
+	// store the name of this test case
+	iTestStepName = _L("WaitForWriteFailureC");
+	}
+
+// Test 2.5 Destructor
+CTestWaitForWriteFailure::~CTestWaitForWriteFailure()
+	{	
+	}
+
+// Test 2.5 Main Code
+enum TVerdict CTestWaitForWriteFailure::doTestStepL()
+	{
+	TInt failureValue;
+
+	TESTL(GetIntFromConfig(KWriteSection, KWriteFailureValue, failureValue));
+
+	Log(_L("CTestWaitForWriteFailure::doTestStepL() - Waiting for write status to be complete with error"));
+	User::WaitForRequest(iUsbSuite->iWriteStatus);
+	Log(_L("CTestWaitForWriteFailure::doTestStepL() - Read status completed with %d"), iUsbSuite->iWriteStatus.Int());
+	TEST(iUsbSuite->iWriteStatus.Int() == failureValue);
+
+	return iTestStepResult;
+	}
+ 
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 2.6
+CTestOpenPort::CTestOpenPort()
+	{
+	// store the name of this test case
+	iTestStepName = _L("OpenPortC");
+	}
+
+// Test 2.6 Destructor
+CTestOpenPort::~CTestOpenPort()
+	{	
+	}
+
+// Test 2.6 Main Code
+enum TVerdict CTestOpenPort::doTestStepL()
+	{
+	TCommAccess openMode;
+	TCommRole role;
+	TInt returnValue;
+
+	TESTL(GetIntFromConfig(KPortSection, KPortOpenMode, (TInt&) openMode));
+	TESTL(GetIntFromConfig(KPortSection, KPortOpenRole, (TInt&) role));
+	TESTL(GetIntFromConfig(KPortSection, KPortOpenReturnValue, returnValue));
+
+	OpenCommServerL();
+
+	if (!iUsbSuite->iPortOpen)
+		{
+		Log(_L("CTestOpenPort::doTestStepL() - Attempting to open ACM comm port with mode %d and role %d"), openMode, role);
+		TInt err = iUsbSuite->iCommPort.Open(iUsbSuite->iCommServer, PORT_NAME, openMode, role);
+
+		if (err == KErrNone)
+			{
+			iUsbSuite->iPortOpen = ETrue;
+			Log(_L("CTestOpenPort::doTestStepL() - Opened ACM comm port, mode %d, role %d"), openMode, role);
+			}
+		TESTL(err == returnValue);
+		}
+	else
+		{
+		TEST(ETrue);
+		}
+
+	return iTestStepResult;
+	}
+ 
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 2.7
+CTestWaitForConfigChange::CTestWaitForConfigChange()
+	{
+	// store the name of this test case
+	iTestStepName = _L("WaitForConfigChangeC");
+	}
+
+// Test 2.7 Destructor
+CTestWaitForConfigChange::~CTestWaitForConfigChange()
+	{
+	}
+
+// Test 2.7 Main Code
+enum TVerdict CTestWaitForConfigChange::doTestStepL()
+	{
+	TCommConfigV01 config;
+
+	TESTL(GetIntFromConfig(KConfigSection, KConfigRate,     (TInt&) config.iRate));
+	TESTL(GetIntFromConfig(KConfigSection, KConfigStopBits, (TInt&) config.iStopBits));
+	TESTL(GetIntFromConfig(KConfigSection, KConfigDataBits, (TInt&) config.iDataBits));
+	TESTL(GetIntFromConfig(KConfigSection, KConfigParity,   (TInt&) config.iParity));
+
+	Log(_L("CTestWaitForConfigChange::doTestStepL() - Waiting for config change"));
+	User::WaitForRequest(iUsbSuite->iNotifyConfigChangeStatus);
+	Log(_L("CTestWaitForConfigChange::doTestStepL() - Config status completed with %d"), iUsbSuite->iNotifyConfigChangeStatus.Int());
+	TESTL(iUsbSuite->iNotifyConfigChangeStatus.Int() == KErrNone);
+
+	Log(_L("iRate=%d iStopBits=%d iDataBits=%d iParity=%d"), iUsbSuite->iConfig().iRate, iUsbSuite->iConfig().iStopBits, iUsbSuite->iConfig().iDataBits, iUsbSuite->iConfig().iParity);
+
+	TESTL(iUsbSuite->iConfig().iRate     == config.iRate);
+	TESTL(iUsbSuite->iConfig().iStopBits == config.iStopBits);
+	TESTL(iUsbSuite->iConfig().iDataBits == config.iDataBits);
+	TESTL(iUsbSuite->iConfig().iParity   == config.iParity);
+
+	return iTestStepResult;
+	}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 2.8
+CTestNotifyStateChange::CTestNotifyStateChange()
+	{
+	// store the name of this test case
+	iTestStepName = _L("NotifyStateChange");
+	}
+
+// Test 2.8 Destructor
+CTestNotifyStateChange::~CTestNotifyStateChange()
+	{	
+	}
+
+// Test 2.8 Main Code
+enum TVerdict CTestNotifyStateChange::doTestStepL()
+	{
+	TESTL(OpenLdd() == KErrNone);
+	iUsbSuite->iLdd.AlternateDeviceStatusNotify(iUsbSuite->iNotifyStateStatus, iUsbSuite->iUsbState);
+	TEST(ETrue);
+	return iTestStepResult;
+	}
+ 
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// Test 2.9
+CTestWaitForStateChange::CTestWaitForStateChange()
+	{
+	// store the name of this test case
+	iTestStepName = _L("WaitForStateChangeC");
+	}
+
+// Test 2.9 Destructor
+CTestWaitForStateChange::~CTestWaitForStateChange()
+	{
+	}
+
+// Test 2.9 Main Code
+enum TVerdict CTestWaitForStateChange::doTestStepL()
+	{
+	Log(_L("CTestWaitForConfigChange::doTestStepL() - Waiting for state change..."));
+	User::WaitForRequest(iUsbSuite->iNotifyStateStatus);
+
+	if (iUsbSuite->iNotifyStateStatus.Int() != KErrNone)
+		{
+		Log(_L("CTestWaitForConfigChange::doTestStepL() - Error = %d"), iUsbSuite->iNotifyStateStatus.Int());
+		TESTL(EFalse);
+		return iTestStepResult;
+		}
+
+	TUint targetState;
+
+	TESTL(GetIntFromConfig(KStateSection, KStateTarget, (TInt&) targetState));
+
+	if (!(iUsbSuite->iUsbState & KUsbAlternateSetting))
+		{
+		Log(_L("CTestWaitForStateChange::doTestStepL() - State Changed to %d"), iUsbSuite->iUsbState);
+		TESTL(iUsbSuite->iUsbState == targetState);
+		}
+	else
+		{
+		// Repost notify as state hasn't changed yet
+		Log(_L("CTestWaitForStateChange::doTestStepL() - State hasn't changed, reposting notify"));
+		iUsbSuite->iLdd.AlternateDeviceStatusNotify(iUsbSuite->iNotifyStateStatus, iUsbSuite->iUsbState);
+		doTestStepL();
+		return iTestStepResult;
+		}
+
+	return iTestStepResult;
+	}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/makerom.pl	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,53 @@
+#!/usr/bin/perl -w
+# 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 "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:
+#
+
+prebuildrom();
+open ROMCONF, $ARGV[0] or die "Cannot open $ARGV[0]";
+while (<ROMCONF>) {
+	($name, $type, $flags, $obylist) = split /,/,;
+	buildrom($name, $flags, $type, $obylist);
+}
+close ROMCONF;
+
+sub prebuildrom {
+	# Rebuild start.rsc to start stauto on startup
+	unlink("\\epoc32\\data\\z\\System\\PROGRAMS\\start.rsc");
+	system("attrib -r \\techview\\toolkit\\startup\\group\\start.rss");
+	system("xcopy start.rss \\techview\\toolkit\\startup\\group\\start.rss /S/C/Y");
+	system("attrib +r \\techview\\toolkit\\startup\\group\\start.rss");
+	system("metabld start.mbc");
+}
+
+sub buildrom {
+	my($name, $flags, $type, $obylist) = @_;
+
+	chdir("\\epoc32\\rom");
+	# Delete Existing Files
+	unlink("$name.dir");
+	unlink("$name.img");
+	unlink("$name.log");
+	unlink("$name.oby");
+	unlink("$name.symbol");
+	unlink("rombuild.txt");
+	unlink("$name.zip");
+	unlink("tmp1.oby");
+
+	#Build and zip the rom
+	system("buildrom.cmd $flags $type $obylist -o$name.img");
+	print "Zipping the rom\n";
+	system("zip -q -m -9 $name.zip $name.img");
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/processLogs.pl	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,161 @@
+# 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 "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:
+#
+
+$suite = "";
+$verbose = 1;
+
+$numtests = $ARGV[0];
+
+open TESTS, $ARGV[1] or die "Cannot open $ARGV[1]";
+%config = (tdlogs => "", logdir => "", mainlog => "");
+CONFIG: while (<TESTS>) {
+	last CONFIG if /\[tests\]/i;
+	next CONFIG if /^\n/;
+	chomp;
+	($var, $value) = split /=/, $_;
+	if (exists $config{$var}) {
+		$config{$var} = $value;
+	}
+}
+close TESTS;
+
+@rundirs = &find_rundirs;
+@sorted = sort {
+	$a =~ /RunNo([0-9]+)/;
+	$l = $1;
+	$b =~ /RunNo([0-9]+)/;
+	$r = $1;
+	$r <=> $l;
+	} @rundirs;
+
+open MAIN, ">".$config{"mainlog"} or die "Can't open ".$config{"mainlog"}.": $!";
+print MAIN <<EOT;
+<html>
+<head>
+<title>$suite Log</title></head>
+<style type="text/css">
+.pass { color: green; }
+.fail { color: red; }
+</style>
+<body>
+EOT
+print "Number of test dirs to process: $numtests\n";
+my @dirlist;
+for ($i = 0; $i < $numtests; $i++) {
+	$dirlist[$i] = $sorted[$i];
+}
+@dirlist = reverse @dirlist;
+for ($i = 0; $i < $numtests; $i++) {
+	&process_dir($dirlist[$i], "");
+}
+print MAIN "</body></html>";
+close MAIN;
+
+sub find_rundirs {
+	my @rundirs;
+	opendir(RESDIR, $config{"tdlogs"}) or die "Can't open ".$config{"tdlogs"}.": $!\n";
+	my @dirs = grep { /^[^.]/ } readdir(RESDIR);
+	close RESDIR;
+	my $highest = 0;
+	my $highDir = "";
+	for my $dir (@dirs) {
+		opendir(SUBDIR, $config{"tdlogs"}."\\$dir") or die "Can't open ".$config{"tdlogs"}."\\$dir: $!\n";
+		@subdirs = grep { /[^.]/ } readdir(SUBDIR);
+		for my $subdir (@subdirs) {
+			push @rundirs, $config{"tdlogs"}."\\$dir\\$subdir";
+#			print "Found ".$config{"tdlogs"}."\\$dir\\$subdir\n"
+			#$subdir =~ /RunNo([0-9]+)/;
+			#if ($1 > $highest) {
+			#	$highest = $1;
+			#	$highDir = $config{"tdlogs"}."\\$dir\\$subdir";
+			#}
+		}
+		close SUBDIR;
+	}
+	#return $highDir;
+	return @rundirs;
+}
+
+sub process_dir {
+	my ($tdlogdir, $currdir) = @_;
+	print "Processing $tdlogdir$currdir\n" if $verbose;
+	chdir("$tdlogdir$currdir");
+	#Find all log files that match the ones retrieved from the board and process them.
+	while (<*.htm>) {
+		/(.*)\.htm/;
+		my $htmlog = $_;
+		my $txtlog = "";
+		print "Looking for ".$config{"logdir"}."\\$suite$currdir\\$1.txt\n" if $verbose;
+		if (-e $config{"logdir"}."\\$suite$currdir\\$1.txt") {
+			print "found $1.txt\n" if $verbose;
+			$txtlog = $config{"logdir"}."\\$suite$currdir\\$1.txt";
+		}
+		&process_logs($1, $txtlog, $htmlog);
+	}
+
+	#Process subdirectories
+	opendir(DIR, "$tdlogdir$currdir") or die "Can't open $tdlogdir$currdir: $!\n";
+	my @dirs = grep { /^[^.]/ } readdir(DIR);
+	close DIR;
+	for my $dir (@dirs) {
+		if (-d "$tdlogdir$currdir\\$dir") {
+			&process_dir($tdlogdir, "$currdir\\$dir");
+		}
+	}
+}
+
+sub process_logs {
+	my ($name, $txtlog, $htmlog) = @_;
+	print MAIN "<b>$name Log</b><br/><br/>";
+	my $fail = 0;
+	$fail += &process_txt_log($txtlog) unless $txtlog eq "";
+	$fail += &process_htm_log($htmlog);
+	if ($fail > 0) {
+		print MAIN "<b>$name: </b><span class=\"fail\"><b>$fail step(s) failed</b></span><br/>";
+	} else {
+		print MAIN "<b>$name: </b><span class=\"pass\"><b>All steps passed</b></span><br/>";
+	}
+}
+
+sub process_txt_log {
+	open LOG, $_[0] or die "Can't open".$_[0].": $!\n";
+	my $fail = 0;
+	while (<LOG>) {
+		print MAIN "Command $_ : ";
+		$_ = <LOG>;
+		print MAIN "<span class=\"pass\">PASS" if /pass/i;
+		do { print MAIN "<span class=\"fail\">FAIL"; $fail++ } if /fail/i;
+		print MAIN "</span><br/>";
+	}
+	close LOG;
+	return $fail;
+}
+
+sub process_htm_log {
+	open LOG, $_[0] or die "Can't open".$_[0].": $!\n";
+	print MAIN "<pre>\n";
+	my $fail = 0;
+	LINE: while (<LOG>) {
+		next LINE if /<\/?html>/;
+		if (/(FAIL|ABORT|PANIC|INCONCLUSIVE|UNKNOWN|UNEXECUTED) = ([0-9]+)/) {
+			$fail += $2; 
+		}		
+		print MAIN;
+	}
+	print MAIN "</pre>\n";
+	return $fail;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/rom.armv5.81b.config	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,3 @@
+t_usbmanager_armv5_81b$rom,lubbock,-D_SERIAL_DOWNLOAD -DSTATAUTO -DRVCT -D_EABI=armv5 -DPLATSEC,techview_StatAPI t_usbmanager
+t_usbmanagercomp4_armv5_81b$rom,lubbock,-D_SERIAL_DOWNLOAD -DSTATAUTO -DRVCT -D_EABI=armv5 -DPLATSEC,techview_StatAPI t_usbmanagercomponent_4
+t_usbmanagercomp5_armv5_81b$rom,lubbock,-D_SERIAL_DOWNLOAD -DSTATAUTO -DRVCT -D_EABI=armv5 -DPLATSEC,techview_StatAPI t_usbmanagercomponent_5
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/rom.armv5.90.config	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,3 @@
+t_usbmanager_armv5_90$rom,lubbock,-D_SERIAL_DOWNLOAD -DSTATAUTO -DRVCT -D_EABI=armv5 -DPLATSEC,techview_StatAPI t_usbmanager
+t_usbmanagercomp4_armv5_90$rom,lubbock,-D_SERIAL_DOWNLOAD -DSTATAUTO -DRVCT -D_EABI=armv5 -DPLATSEC,techview_StatAPI t_usbmanagercomponent_4
+t_usbmanagercomp5_armv5_90$rom,lubbock,-D_SERIAL_DOWNLOAD -DSTATAUTO -DRVCT -D_EABI=armv5 -DPLATSEC,techview_StatAPI t_usbmanagercomponent_5
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/rom.thumb.81a.config	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,3 @@
+t_usbmanager_thumb_81a$rom,lubbock,-D_SERIAL_DOWNLOAD -DSTATAUTO -DRVCT -D_EABI=thumb -DPLATSEC,techview_StatAPI t_usbmanager
+t_usbmanagercomp4_thumb_81a$rom,lubbock,-D_SERIAL_DOWNLOAD -DSTATAUTO -DRVCT -D_EABI=thumb -DPLATSEC,techview_StatAPI t_usbmanagercomponent_4
+t_usbmanagercomp5_thumb_81a$rom,lubbock,-D_SERIAL_DOWNLOAD -DSTATAUTO -DRVCT -D_EABI=thumb -DPLATSEC,techview_StatAPI t_usbmanagercomponent_5
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/runcmd.pl	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,40 @@
+# 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 "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:
+# runcmd log expected-result command
+# 
+#
+
+use File::Basename;
+use File::Path;
+
+($#ARGV >= 3) or die "Usage: runcmd log expected-result command";
+
+($log, $expected, @command) = @ARGV;
+
+$cmd = "";
+for my $c (@command) {$cmd = $cmd.$c." "};
+
+print "Executing: ".$cmd."\n";
+$ret = system($cmd) >> 8;
+
+mkpath(dirname($log));
+open LOG, ">>".$log;
+print LOG "$cmd\n";
+if ($ret == $expected) {
+	print LOG "PASS\n";
+}
+else {
+	print LOG "FAIL\n";
+}
+close LOG;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/runtests.pl	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,78 @@
+#!/usr/bin/perl -w
+# 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 "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:
+#
+
+use File::Path;
+use Cwd;
+
+#read config file
+open TESTS, $ARGV[0] or die "Cannot open $ARGV[0]";
+%config = (testdriver => "", logdir => "", romdir => "");
+CONFIG: while (<TESTS>) {
+	last CONFIG if /\[tests\]/i;
+	next CONFIG if /^\n/;
+	chomp;
+	($var, $value) = split /=/, $_;
+	if (exists $config{$var}) {
+		$config{$var} = $value;
+	}
+}
+#Save location of test list start
+$testspos = tell TESTS;
+
+print "td = ".$config{"testdriver"}."\n";
+print "logdir = ".$config{"logdir"}."\n";
+print "romdir = ".$config{"romdir"}."\n";
+
+#delete old logs
+print "deleting ".$config{"logdir"}."\n";
+rmtree($config{"logdir"});
+
+$cwd = getcwd;
+chdir($config{"testdriver"});
+
+#Build tests
+print "Building tests\n";
+while(<TESTS>) {
+	($suite, $plat, $rel) = split /,/, $_;
+	print "testdriver.exe build -p $plat -b $rel -s $suite\n";
+	system("testdriver.exe build -p $plat -b $rel -s $suite");
+}
+#return to the beggining for later processing
+seek TESTS, $testspos, 0;
+
+#Run tests
+$numtests = 0;
+while(<TESTS>) {
+	($suite, $plat, $rel, $rom) = split /,/, $_;
+
+	#Turn board on
+	system("hardwareswitch off");
+	sleep(5);
+	system("hardwareswitch on");
+	sleep(5);
+
+	#Transfer rom to board
+	system("\\epoc32\\release\\tools\\rel\\trgtest.exe 1 $config{'romdir'}\\$rom");
+	#I know, another hardcoded delay... but how is the script supposed to know when
+	#the board has finished booting?
+	sleep(200);
+	system("testdriver.exe run -p $plat -b $rel -s $suite -t serial2");
+	$numtests++
+}
+
+#Compile the log files
+chdir($cwd);
+system("perl \\build\\processLogs.pl $numtests $ARGV[0]");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/start.mbc	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,9 @@
+SECTION_COMMANDS
+bldmake bldfiles
+abld clean
+abld reallyclean
+abld build thumb
+abld build armv5
+
+SECTION_DIRS
+\techview\toolkit\startup\group
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/start.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,119 @@
+// Copyright (c) 1997-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:
+//
+
+#include <techview/eikon.rh>
+#include "start.hrh"
+
+STRUCT STUBPARAMS
+	{
+	LTEXT splash_exe = "";	// No translation
+	LLINK apps_list_id;
+	LLINK exe_list_id;
+	}
+
+STRUCT STARTUP_ITEM
+	{
+	LONG uid = 0;
+	LTEXT path ="";	// No translation
+	LTEXT winspath ="";			// Only used with ECmdLnArgExecutableType on WINS
+	LTEXT args =""; // Command line arguments, Only used with ECmdLnArgExecutableType
+	LONG stackSize = 0;			// Only used with ECmdLnArgExecutableType on WINS (0=default)
+	LONG minHeapSize = 0;		// Only used with ECmdLnArgExecutableType on WINS (0=default)
+	LONG maxHeapSize = 0x400000;// Only used with ECmdLnArgExecutableType on WINS
+	WORD monitored = 0;
+	WORD semaphore = 0;
+	WORD viewless = 0; // 1 would start this app in viewless mode
+	WORD boot_type = EBothBootType;
+	}
+
+STRUCT STARTUP_EXTRAS_ITEM
+	{
+	LONG uid = 0;
+	LTEXT path ="";	// No translation
+	LTEXT winspath ="";			// Only used with ECmdLnArgExecutableType on WINS
+	LTEXT args =""; // Command line arguments, Only used with ECmdLnArgExecutableType
+	LONG stackSize = 0;			// Only used with ECmdLnArgExecutableType on WINS (0=default)
+	LONG minHeapSize = 0;		// Only used with ECmdLnArgExecutableType on WINS (0=default)
+	LONG maxHeapSize = 0x400000;// Only used with ECmdLnArgExecutableType on WINS
+	WORD monitored = 0;
+	WORD viewless = 0; // 1 would start this app in viewless mode
+	WORD boot_type = EBothBootType;
+	}
+
+RESOURCE STUBPARAMS r_app_start_params
+	{
+	splash_exe = "Z:\\SYSTEM\\PROGRAMS\\SPLASH";	// No translation of path
+	apps_list_id = r_startup_list;
+	exe_list_id = r_start_extras_list; 
+	}
+
+RESOURCE ARRAY r_startup_list //Needed before the splashscreen is removed
+	{
+	items=
+		{
+		STARTUP_ITEM
+			{
+			path = "Z:\\System\\Libs\\InstRec";	// No translation of path
+			boot_type = EExecutableType;
+			},
+		STARTUP_ITEM
+			{ // Shell
+			uid = 0x10003A5D;	// No translation of uid
+			monitored = 1;
+			semaphore = 1;
+			boot_type = EApplicationType;
+			},
+		STARTUP_ITEM
+			{
+			path = "Z:\\System\\Libs\\watcher";	// No translation of path
+			boot_type = EExecutableType;
+			}
+		};
+	}
+
+RESOURCE ARRAY r_start_extras_list
+	{
+	items=
+		{
+		STARTUP_EXTRAS_ITEM
+			{
+			path = "Z:\\System\\Programs\\statauto";
+			boot_type = EExecutableType;
+			},
+		STARTUP_EXTRAS_ITEM
+			{
+			path = "Z:\\System\\Programs\\DefaultFileInit";	// No translation of path
+			boot_type = EExecutableType;
+ 			},
+		STARTUP_EXTRAS_ITEM
+			{
+			path = "SystemAMS";
+			winspath = "JavaAMS";
+			boot_type = ECmdLnArgExecutableType;
+			args="-boot";
+			}	
+/*		
+#ifndef __MINI_BUILD__
+		,STARTUP_EXTRAS_ITEM
+			{	// IR default listener (Beamer)
+			uid = 0x10005fd5;	// No translation of uid
+			monitored = 1;
+			viewless = 1;
+			boot_type = EApplicationType;
+			}
+#endif
+This is left as an example how applications are added in startup list of extra applications.
+*/		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests.armv5.81b.config	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,10 @@
+testdriver=h:\testdriver\bin
+tdlogs=h:\testdriver\results
+logdir=h:\build\logs
+romdir=h:\epoc32\rom
+mainlog=h:\build\armv5.81b.logs.html
+
+[tests]
+usbmanagertest.singlerom,armv5,urel,t_usbmanager_armv5_81b$rom.zip
+usbmanagertest.individualrom.t_usbmancomponent_4,armv5,urel,t_usbmanagercomp4_armv5_81b$rom$rom.zip
+usbmanagertest.individualrom.t_usbmancomponent_5,armv5,urel,t_usbmanagercomp5_armv5_81b$rom.zip
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests.armv5.90.config	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,10 @@
+testdriver=h:\testdriver\bin
+tdlogs=h:\testdriver\results
+logdir=h:\build\logs
+romdir=h:\epoc32\rom
+mainlog=h:\build\armv5.90.logs.html
+
+[tests]
+usbmanagertest.singlerom,armv5,urel,t_usbmanager_armv5_90$rom.zip
+usbmanagertest.individualrom.t_usbmancomponent_4,armv5,urel,t_usbmanagercomp4_armv5_90$rom$rom.zip
+usbmanagertest.individualrom.t_usbmancomponent_5,armv5,urel,t_usbmanagercomp5_armv5_90$rom.zip
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests.thumb.81a.config	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,10 @@
+testdriver=h:\testdriver\bin
+tdlogs=h:\testdriver\results
+logdir=h:\build\logs
+romdir=h:\epoc32\rom
+mainlog=h:\build\thumb.81a.logs.html
+
+[tests]
+usbmanagertest.singlerom,thumb,urel,t_usbmanager_thumb_81a$rom.zip
+usbmanagertest.individualrom.t_usbmancomponent_4,thumb,urel,t_usbmanagercomp4_thumb_81a$rom$rom.zip
+usbmanagertest.individualrom.t_usbmancomponent_5,thumb,urel,t_usbmanagercomp5_thumb_81a$rom.zip
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/testSuite.dtd" [ ]>
+
+<testSuite>
+	<name>UsbManagerTest</name>
+	
+	<testItems>
+		<suite>SingleRom</suite>
+		<suite>IndividualRom</suite>
+	</testItems>
+	
+</testSuite>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/IndividualRom.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/testSuite.dtd" [ ]>
+
+<testSuite>
+	<name>IndividualRom</name>
+	
+	<testItems>
+<!--		<test>t_usbmancomponent_2</test>
+		<test>t_usbmancomponent_3</test>
+-->
+		<test>t_usbmancomponent_4</test>
+		<test>t_usbmancomponent_5</test>
+	</testItems>
+	
+</testSuite>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/IndividualRom/t_usbmancomponent_4.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/CommandLineTest.dtd" [ ]>
+
+<CommandLineTest>
+	<name>t_usbmancomponent_4</name>
+
+	<commandLine>testexecute.exe z:\testdata\scripts\t_usbmancomponent_4.script</commandLine>
+	<logfile>c:\logs\testexecute\t_usbmancomponent_4.htm</logfile>
+	<timeout>300</timeout>
+</CommandLineTest>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/IndividualRom/t_usbmancomponent_5.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/CommandLineTest.dtd" [ ]>
+
+<CommandLineTest>
+	<name>t_usbmancomponent_5</name>
+
+	<commandLine>testexecute.exe z:\testdata\scripts\t_usbmancomponent_5.script</commandLine>
+	<logfile>c:\logs\testexecute\t_usbmancomponent_5.htm</logfile>
+	<timeout>300</timeout>
+</CommandLineTest>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/testSuite.dtd" [ ]>
+
+<testSuite>
+	<name>SingleRom</name>
+	
+	<testItems>
+		<suite>component</suite>
+		<suite>Integration</suite>
+		<suite>Integration_Connected</suite>
+	</testItems>
+	
+</testSuite>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Component.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/testSuite.dtd" [ ]>
+
+<testSuite>
+	<name>Component</name>
+	
+	<testItems>
+		<test>t_usbmancomponent_1</test>
+	</testItems>
+	
+</testSuite>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Component/t_usbmancomponent_1.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/CommandLineTest.dtd" [ ]>
+
+<CommandLineTest>
+	<name>t_usbmancomponent_1</name>
+
+	<commandLine>testexecute.exe z:\testdata\scripts\t_usbmancomponent_1.script</commandLine>
+	<logfile>c:\logs\testexecute\t_usbmancomponent_1.htm</logfile>
+	<timeout>300</timeout>
+</CommandLineTest>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/testSuite.dtd" [ ]>
+
+<testSuite>
+	<name>Integration</name>
+	
+	<testItems>
+		<test>t_usbmanintegration</test>
+	</testItems>
+	
+</testSuite>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration/t_usbmanintegration.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/CommandLineTest.dtd" [ ]>
+
+<CommandLineTest>
+	<name>t_usbmanintegration</name>
+
+	<commandLine>testexecute.exe z:\testdata\scripts\t_usbmanintegration.script</commandLine>
+	<logfile>c:\logs\testexecute\t_usbmanintegration.htm</logfile>
+	<timeout>1200</timeout>
+</CommandLineTest>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/testSuite.dtd" [ ]>
+
+<testSuite>
+	<name>Integration_Connected</name>
+	
+	<testItems>
+		<test>t_usbmanconnected_1</test>
+		<test>t_usbmanconnected_2</test>
+		<test>t_usbmanconnected_3</test>
+		<test>t_usbmanconnected_4</test>
+		<test>t_usbmanconnected_5</test>
+		<test>t_usbmanconnected_6</test>
+	</testItems>
+	
+</testSuite>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected/t_usbmanconnected_1.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/CommandLineTest.dtd" [ ]>
+
+<CommandLineTest>
+	<name>t_usbmanconnected_1</name>
+
+	<afterTestRun cmd='perl h:\build\runcmd.pl h:\build\logs\UsbManagerTest\SingleRom\Integration_Connected\t_usbmanconnected_1\t_usbmanconnected_1.txt 0 h:\usbcheck 1 2 2 2 2 1 \"localized manufacturer\" \"localized product description\"'/>
+
+	<commandLine>testexecute.exe z:\testdata\scripts\t_usbmanconnected_1.script</commandLine>
+	<logfile>c:\logs\testexecute\t_usbmanconnected_1.htm</logfile>
+	<timeout>100</timeout>
+</CommandLineTest>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected/t_usbmanconnected_2.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/CommandLineTest.dtd" [ ]>
+
+<CommandLineTest>
+	<name>t_usbmanconnected_2</name>
+
+	<afterTestRun cmd='perl h:\build\runcmd.pl h:\build\logs\UsbManagerTest\SingleRom\Integration_Connected\t_usbmanconnected_2\t_usbmanconnected_2.txt 1 h:\usbcheck 1 2 2 2 2 1 \"localized manufacturer\" \"localized product description\"'/>
+
+	<commandLine>testexecute.exe z:\testdata\scripts\t_usbmanconnected_2.script</commandLine>
+	<logfile>c:\logs\testexecute\t_usbmanconnected_2.htm</logfile>
+	<timeout>100</timeout>
+</CommandLineTest>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected/t_usbmanconnected_3.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/CommandLineTest.dtd" [ ]>
+
+<CommandLineTest>
+	<name>t_usbmanconnected_3</name>
+
+	<afterTestRun cmd='perl h:\build\runcmd.pl h:\build\logs\UsbManagerTest\SingleRom\Integration_Connected\t_usbmanconnected_3\t_usbmanconnected_3.txt 0 h:\usbcheck 1 2 2 2 2 1 \"localized manufacturer\" \"localized product description\"'/>
+
+	<commandLine>testexecute.exe z:\testdata\scripts\t_usbmanconnected_3.script</commandLine>
+	<logfile>c:\logs\testexecute\t_usbmanconnected_3.htm</logfile>
+	<timeout>100</timeout>
+</CommandLineTest>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected/t_usbmanconnected_4.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/CommandLineTest.dtd" [ ]>
+
+<CommandLineTest>
+	<name>t_usbmanconnected_4</name>
+
+	<afterTestRun cmd='perl h:\build\runcmd.pl h:\build\logs\UsbManagerTest\SingleRom\Integration_Connected\t_usbmanconnected_4\t_usbmanconnected_4.txt 0 h:\usbcheck 2 0 3618 11 0 1 \"localized manufacturer\" \"localized product description\"'/>
+
+	<commandLine>testexecute.exe z:\testdata\scripts\t_usbmanconnected_4.script</commandLine>
+	<logfile>c:\logs\testexecute\t_usbmanconnected_4.htm</logfile>
+	<timeout>100</timeout>
+</CommandLineTest>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected/t_usbmanconnected_5.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/CommandLineTest.dtd" [ ]>
+
+<CommandLineTest>
+	<name>t_usbmanconnected_5</name>
+
+	<afterTestRun cmd='perl h:\build\runcmd.pl h:\build\logs\UsbManagerTest\SingleRom\Integration_Connected\t_usbmanconnected_5\t_usbmanconnected_5.txt 1 h:\usbcheck 1 2 2 2 2 1 \"localized manufacturer\" \"localized product description\"'/>
+
+	<commandLine>testexecute.exe z:\testdata\scripts\t_usbmanconnected_5.script</commandLine>
+	<logfile>c:\logs\testexecute\t_usbmanconnected_5.htm</logfile>
+	<timeout>100</timeout>
+</CommandLineTest>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/automation/tests/UsbManagerTest/SingleRom/Integration_Connected/t_usbmanconnected_6.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!DOCTYPE testSuite SYSTEM "file:///c:/testdriver/xml/CommandLineTest.dtd" [ ]>
+
+<CommandLineTest>
+	<name>t_usbmanconnected_6</name>
+
+	<afterTestRun cmd='perl h:\build\runcmd.pl h:\build\logs\UsbManagerTest\SingleRom\Integration_Connected\t_usbmanconnected_6\t_usbmanconnected_6.txt 0 h:\usbcheck 1 2 2 2 2 1 \"localized manufacturer\" \"localized product description\"'/>
+
+	<commandLine>testexecute.exe z:\testdata\scripts\t_usbmanconnected_6.script</commandLine>
+	<logfile>c:\logs\testexecute\t_usbmanconnected_6.htm</logfile>
+	<timeout>100</timeout>
+</CommandLineTest>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/csy/t_ecacm/group/T_csyaccess.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 2001-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:
+*
+*/
+
+
+TARGET			t_csyaccess.exe
+TARGETTYPE		exe
+UID				0
+VENDORID 0x70000001
+CAPABILITY		All -TCB
+
+SOURCEPATH		../src
+SOURCE			t_csyaccess.cpp
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+LIBRARY			euser.lib 
+LIBRARY			usbman.lib 
+LIBRARY			c32.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/csy/t_ecacm/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* 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 "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:
+* BLD.INF for T_CsyAccess
+* BLD.INF for T_CsyAccess
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+T_csyaccess.mmp
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/csy/t_ecacm/src/t_csyaccess.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,849 @@
+/*
+* Copyright (c) 2001-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:
+* Contains sanity tests for various things.
+*
+*/
+
+#include <e32base.h>
+#include <c32comm.h>
+#include <usbman.h>
+#include <acminterface.h>
+#include <e32test.h>
+
+#ifndef __WINS__
+_LIT(KCommDriverName, "EUSBC");
+//_LIT(KCommDeviceName, "USBC");
+#else
+_LIT(KCommPhysDriverName, "ECDRV");
+_LIT(KCommPhysDeviceName, "Comm.Wins");
+_LIT(KCommDriverName, "ECOMM");
+//_LIT(KCommDeviceName, "Comm");
+#endif
+
+LOCAL_D RTest gTest(_L("T_CSYACCESS"));
+  
+enum TInitReturnValue 
+	{
+	ENotFinished,
+	EFinished
+	};
+
+TInitReturnValue C32_FailAcmOpen(TUint aCount);
+TInitReturnValue C32_SucceedAcmOpen(TUint aCount);
+TInitReturnValue USBMAN_SucceedAcmOpen(TUint aCount);
+
+TUint gInitSafetyTimeout = 100000;
+TUint gBetweenTestDelay = 1000000;
+
+TInt _1();
+TInt _2();
+TInt _3();
+TInt _4();
+TInt _5();
+TInt Oom(TInitReturnValue fn(TUint n));
+TInt Regression_DEF23333();
+TInt RunOneTest(TInt aKey);
+void RunAll();
+
+#define TEST(AAA)	{ if ( !(AAA) ) { return __LINE__; } }
+
+TInt _1()
+/**
+ * Checks: 
+ *	1/ can't open ACM port when USBMAN isn't started.
+ *	2/ can open ACM port when USBMAN is started.
+ *	3/ then stop USBMAN and check Read and Write complete with error.
+ *	4/ then close the port and check that opening ACM port returns error.
+ *	5/ then restarts USBMAN and checks the ACM port can be opened then shuts 
+ *		it all down.
+ *	6/ then start USBMAN, open ACM port, issue a Read request, close USBMAN, 
+ *		and check the Read is completed with an error.
+ */
+	{
+	gTest.Printf(_L("\nRunning test 1"));
+
+	CActiveScheduler* sch = new(ELeave) CActiveScheduler;
+	CActiveScheduler::Install(sch);
+
+	TName portName(KAcmSerialName);
+	portName.AppendFormat(_L("::%d"), KAcmLowUnit);
+
+	// Try to access serial/USB when the registration hasn't been done
+	RCommServ sess;
+	TEST(sess.Connect() == KErrNone);
+	RComm port;
+	TEST(sess.LoadCommModule(KAcmCsyName) == KErrNone);
+	TInt err = port.Open(sess, portName, ECommExclusive); // should fail
+	TEST(err == KErrAccessDenied);
+
+	// Start USB services
+	RUsb usb;
+	TEST(usb.Connect() == KErrNone);
+	TRequestStatus stat;
+	usb.Start(stat);
+	User::WaitForRequest(stat);
+	TEST(stat.Int() == KErrNone);
+
+	// Try to access serial/USB when the registration HAS been done
+	TEST(port.Open(sess, portName, ECommExclusive) == KErrNone); // should work
+
+	// Deregister and check further RComm calls
+	usb.Stop();
+	usb.Close();
+	TBuf8<10> buf;
+	port.Read(stat, buf);
+	User::WaitForRequest(stat);
+	TEST(stat.Int() == KErrAccessDenied);
+	port.Write(stat, _L8("stuff"));
+	User::WaitForRequest(stat);
+	TEST(stat.Int() == KErrAccessDenied);
+	port.Close();
+	err = port.Open(sess, portName, ECommExclusive); // should fail
+	TEST(err == KErrAccessDenied);
+
+	// Check can open again after restarting service
+	TEST(usb.Connect() == KErrNone);
+	usb.Start(stat);
+	User::WaitForRequest(stat);
+	TEST(stat.Int() == KErrNone);
+	err = port.Open(sess, portName, ECommExclusive); // should work
+	TEST(err == KErrNone);
+	port.Close();
+	usb.Stop();
+	usb.Close();
+  
+	// Check completion of an outstanding RComm request when usbman pulls the 
+	// rug out.
+	TEST(usb.Connect() == KErrNone);
+	usb.Start(stat);
+	User::WaitForRequest(stat);
+	TEST(stat.Int() == KErrNone);
+	err = port.Open(sess, portName, ECommExclusive); // should work
+	TEST(err == KErrNone);
+
+	// Hacky pause to wait for device to enumerate.
+	User::After(1000000);
+
+	port.Read(stat, buf);
+	usb.Stop();
+	User::WaitForRequest(stat);
+	TEST(stat.Int() == KErrAccessDenied);
+  
+	// Clean up
+	port.Close(); 
+	TEST(sess.UnloadCommModule(KAcmSerialName) == KErrNone);
+	sess.Close();
+
+	usb.Close();
+
+	delete sch;
+
+	return KErrNone;
+	}
+
+TInt _2()
+/**
+ * Checks: 
+ *	simple open/close of registration port
+ */
+	{
+	gTest.Printf(_L("\nRunning test 2"));
+
+	CActiveScheduler* sch = new(ELeave) CActiveScheduler;
+	CActiveScheduler::Install(sch);
+
+	TName portName(KAcmSerialName);
+	portName.AppendFormat(_L("::%d"), 666);
+
+	RCommServ sess;
+	TEST(sess.Connect() == KErrNone);
+	RComm port;
+	TEST(sess.LoadCommModule(KAcmCsyName) == KErrNone);
+	TEST(port.Open(sess, portName, ECommExclusive) == KErrNone); 
+	port.Close();
+	TEST(sess.UnloadCommModule(KAcmSerialName) == KErrNone);
+	sess.Close();
+
+	delete sch;
+
+	return KErrNone;
+	}
+
+TInt _3()
+/**
+ * Checks: 
+ *	simple open/close of registration port with open/close of ACM port inside 
+ *	that.
+ */
+	{
+	gTest.Printf(_L("\nRunning test 3"));
+
+	CActiveScheduler* sch = new(ELeave) CActiveScheduler;
+	CActiveScheduler::Install(sch);
+
+	TName portName(KAcmSerialName);
+	portName.AppendFormat(_L("::%d"), 666);
+
+	RCommServ sess;
+	TEST(sess.Connect() == KErrNone);
+	RComm port;
+	TEST(sess.LoadCommModule(KAcmCsyName) == KErrNone);
+	TEST(port.Open(sess, portName, ECommExclusive) == KErrNone); 
+
+	TName acmPortName(KAcmSerialName);
+	acmPortName.AppendFormat(_L("::%d"), KAcmLowUnit);
+	RComm acmPort;
+	TEST(acmPort.Open(sess, acmPortName, ECommExclusive) == KErrNone); 
+	acmPort.Close();
+
+	port.Close();
+	TEST(sess.UnloadCommModule(KAcmSerialName) == KErrNone);
+	sess.Close();
+
+	delete sch;
+
+	return KErrNone;
+	}
+
+TInt _4()
+/**
+ * Checks: 
+ *	opens registration port (NB actually starts USB- just opening reg port 
+ *		doesn't instantiate the LDD, which we need to get the Read test to 
+ *		work. Otherwise the read comes back immediately with KErrGeneral.)
+ *	opens ACM port
+ *	check ACM APIs active
+ *	closes registration port (NB stop & close USB)
+ *	checks ACM APIs inactive
+ *	closes ACM port.
+ */
+	{
+	gTest.Printf(_L("\nRunning test 4"));
+
+	CActiveScheduler* sch = new(ELeave) CActiveScheduler;
+	CActiveScheduler::Install(sch);
+
+	// Start USB services
+	RUsb usb;
+	TEST(usb.Connect() == KErrNone);
+	TRequestStatus stat;
+	usb.Start(stat);
+	User::WaitForRequest(stat);
+	TEST(stat.Int() == KErrNone);	  
+
+	RCommServ sess;
+	TEST(sess.Connect() == KErrNone);
+
+	TName acmPortName(KAcmSerialName);
+	acmPortName.AppendFormat(_L("::%d"), KAcmLowUnit); 
+	RComm acmPort;
+	TEST(acmPort.Open(sess, acmPortName, ECommExclusive) == KErrNone); 
+
+	// Hacky pause to wait for device to enumerate.
+	User::After(1000000);
+
+	TRequestStatus readStat;
+	TRequestStatus timerStat;
+	TBuf8<10> buf;
+	acmPort.Read(readStat, buf);
+	RTimer timer;
+	TEST(timer.CreateLocal() == KErrNone);
+	timer.After(timerStat, 1000000); 
+	User::WaitForRequest(readStat, timerStat);
+	TEST(readStat == KRequestPending);
+	TEST(timerStat == KErrNone);
+	acmPort.ReadCancel();
+	User::WaitForRequest(readStat);
+	TEST(readStat == KErrCancel);
+	timer.Close();
+
+	usb.Stop();
+	usb.Close();
+
+	acmPort.Read(readStat, buf);
+	User::WaitForRequest(readStat);
+	TEST(readStat == KErrAccessDenied);
+
+	acmPort.Close();
+
+	sess.Close();
+
+	delete sch;
+
+	return KErrNone;
+	}
+
+TInt _5()
+/**
+ * Checks: 
+ *	opens registration port
+ *	opens ACM port
+ *	check ACM APIs active
+ *	closes registration port
+ *	checks ACM APIs inactive
+ *	opens registration port
+ *	checks ACM APIs active
+ *	closes ACM port
+ *	closes registration port
+ */
+	{
+	gTest.Printf(_L("\nRunning test 5"));
+
+	CActiveScheduler* sch = new(ELeave) CActiveScheduler;
+	CActiveScheduler::Install(sch);
+
+	// Start USB services
+	RUsb usb;
+	TEST(usb.Connect() == KErrNone);
+	TRequestStatus stat;
+	usb.Start(stat);
+	User::WaitForRequest(stat);
+	TEST(stat.Int() == KErrNone);	  
+
+	RCommServ sess;
+	TEST(sess.Connect() == KErrNone);
+
+	TName acmPortName(KAcmSerialName);
+	acmPortName.AppendFormat(_L("::%d"), KAcmLowUnit);
+	RComm acmPort;
+	TEST(acmPort.Open(sess, acmPortName, ECommExclusive) == KErrNone); 
+
+	// Hacky pause to wait for device to enumerate.
+	User::After(1000000);  
+
+	TRequestStatus readStat;
+	TRequestStatus timerStat;
+	TBuf8<10> buf;
+	acmPort.Read(readStat, buf);
+	RTimer timer;
+	TEST(timer.CreateLocal() == KErrNone);
+	timer.After(timerStat, 1000000); 
+	User::WaitForRequest(readStat, timerStat);
+	TEST(readStat == KRequestPending);
+	TEST(timerStat == KErrNone);
+	acmPort.ReadCancel();
+	User::WaitForRequest(readStat);
+	TEST(readStat == KErrCancel);
+	timer.Close();
+
+	usb.Stop();
+
+	acmPort.Read(readStat, buf);
+	User::WaitForRequest(readStat);
+	TEST(readStat == KErrAccessDenied);
+
+	usb.Start(stat);
+	User::WaitForRequest(stat);
+	TEST(stat.Int() == KErrNone);	  
+
+	// Hacky pause to wait for device to enumerate.
+	User::After(1000000);
+
+	acmPort.Read(readStat, buf);
+	TEST(timer.CreateLocal() == KErrNone);
+	timer.After(timerStat, 1000000);
+	User::WaitForRequest(readStat, timerStat);
+	TEST(readStat == KRequestPending);
+	TEST(timerStat == KErrNone);
+	acmPort.ReadCancel();
+	User::WaitForRequest(readStat);
+	TEST(readStat == KErrCancel);
+	timer.Close();
+		
+	acmPort.Close();
+
+	usb.Stop();
+	usb.Close();
+	sess.Close();
+
+	delete sch;
+
+	return KErrNone;
+	}
+
+TInitReturnValue C32_FailAcmOpen(TUint aCount)
+/**
+ * One iteration of loading ECACM.CSY and trying to open the ACM port. Will 
+ * fail due to the access control (USB isn't started). Heap failures in C32's 
+ * heap.
+ */
+	{
+	RCommServ serv;
+	TInt err = serv.Connect();
+	if ( !err )
+		{
+		gTest.Printf(_L("\tconnected to server\n"));
+		serv.__DbgMarkHeap();
+		serv.__DbgFailNext(aCount);
+
+		err = serv.LoadCommModule(KAcmCsyName);
+		if ( !err )
+			{
+			gTest.Printf(_L("\tloaded comm module\n"));
+			RComm comm;
+			TName name(KAcmSerialName);
+			name.AppendFormat(_L("::%d"), KAcmLowUnit); 
+			err = comm.Open(serv, name, ECommExclusive);
+			if ( err == KErrAccessDenied ) 
+				{
+				gTest.Printf(_L("\tsuccessful result from RComm::Open\n"));
+				err = KErrNone;
+				}
+			}
+		serv.UnloadCommModule(KAcmSerialName);
+		User::After(gInitSafetyTimeout);
+		serv.__DbgMarkEnd(0);
+		serv.Close();
+		User::After(gInitSafetyTimeout);
+
+		if ( !err )
+			{
+			// Test for if the test has finished. If aCount has become so big 
+			// as to skip over all the allocs in the above use case, the next 
+			// API call which causes alloc will fail with KErrNoMemory. 
+			if ( serv.Connect() == KErrNoMemory )
+				{
+				serv.Close();
+				User::After(gInitSafetyTimeout);
+				return EFinished;
+				}
+			}
+		}
+
+	serv.Close();
+	User::After(gInitSafetyTimeout);
+
+	return ENotFinished;
+	}
+
+TInitReturnValue C32_SucceedAcmOpen(TUint aCount)
+/**
+ * One iteration of starting USB, loading ECACM.CSY, trying to open the ACM 
+ * port and changing the ACM port's buffer sizes. Heap failures in C32's heap.
+ */
+	{
+	RUsb usb;
+	TInt err = usb.Connect();
+	gTest.Printf(_L("\tRUsb::Connect = %d\n"), err);
+	if ( !err )
+		{
+		RCommServ serv;
+		err = serv.Connect();
+		gTest.Printf(_L("\tRCommServ::Connect = %d\n"), err);
+
+		if ( !err )
+			{
+			serv.__DbgMarkHeap();
+			serv.__DbgFailNext(aCount);
+
+			TRequestStatus stat;
+			usb.Start(stat);
+			User::WaitForRequest(stat);
+			err = stat.Int();
+			gTest.Printf(_L("\tRUsb::Start = %d\n"), err);
+			if ( !err )
+				{
+				err = serv.LoadCommModule(KAcmCsyName);
+				gTest.Printf(_L("\tRCommServ::LoadCommModule = %d\n"), err);
+				if ( !err )
+					{
+					RComm comm;
+					TName name(KAcmSerialName);
+					name.AppendFormat(_L("::%d"), KAcmLowUnit);
+					err = comm.Open(serv, name, ECommExclusive);
+					gTest.Printf(_L("\tRComm::Open = %d\n"), err);
+					if ( !err ) 
+						{
+						gTest.Printf(_L("\tsuccessful result from RComm::Open\n"));
+						
+	/*					TCommServerConfigV01 serverConfig;
+						TCommServerConfig serverConfigBuf(serverConfig);
+						comm.Mode(serverConfigBuf);
+
+						const TUint KBufSize = 0x1000;
+						serverConfig.iBufSize = KBufSize;
+
+						err = comm.SetMode(serverConfig);
+						if ( !err )
+							{
+							gTest.Printf(_L("\tsuccessful result from RComm::SetMode\n"));
+							// End of use case.
+							}
+  */
+						comm.Close();			
+						}
+					}
+				serv.UnloadCommModule(KAcmSerialName);
+				
+				usb.Stop();
+				User::After(gInitSafetyTimeout);
+
+				serv.__DbgMarkEnd(0);
+				}
+			serv.Close();
+			User::After(gInitSafetyTimeout);
+			}
+		
+		usb.Close();
+		User::After(gInitSafetyTimeout);
+
+		if ( !err )
+			{
+			// Test for if the test has finished. If aCount has become so big 
+			// as to skip over all the allocs in the above use case, the next 
+			// API call which causes alloc will fail with KErrNoMemory. 
+			if ( serv.Connect() == KErrNoMemory )
+				{
+				serv.Close();
+				User::After(gInitSafetyTimeout);
+				return EFinished;
+				}
+			}
+		}
+
+	return ENotFinished;
+	}
+
+TInitReturnValue USBMAN_SucceedAcmOpen(TUint aCount)
+/**
+ * One iteration of doing RUsb::Start/Stop. Heap failures in USBMAN's heap.
+ */
+	{
+	RUsb usb;
+	TInt err = usb.Connect();
+	if ( !err )
+		{
+		gTest.Printf(_L("\tconnected to USBMAN\n"));
+
+		err = usb.__DbgMarkHeap();
+		if ( !err )
+			{
+			err = usb.__DbgFailNext(aCount);
+			if ( !err )
+				{
+				TRequestStatus stat;
+				usb.Start(stat);
+				User::WaitForRequest(stat);
+				err = stat.Int();
+				gTest.Printf(_L("\tRUsb::Start completed with %d\n"), err);
+				if ( !err )
+					{
+					usb.Stop(stat);
+					User::WaitForRequest(stat);
+					err = stat.Int();
+					gTest.Printf(_L("\tRUsb::Stop completed with %d\n"), err);
+					}
+				}
+			else
+				{
+				gTest.Printf(_L("\tRUsb::__DbgFailNext completed with %d\n"), err);
+				User::Panic(_L("t_csyaccess"), 1);
+				}
+			}
+		else
+			{
+			gTest.Printf(_L("\tRUsb::__DbgMarkHeap completed with %d\n"), err);
+			User::Panic(_L("t_csyaccess"), 1);
+			}
+		}
+	else
+		{
+		gTest.Printf(_L("\tRUsb::Connect completed with %d\n"), err);
+		User::Panic(_L("t_csyaccess"), 1);
+		}
+
+	usb.__DbgMarkEnd(0);
+	usb.Close();
+	
+	if ( !err )
+		{
+		// Test for if the test has finished. If aCount has become so big 
+		// as to skip over all the allocs in the above use case, the next 
+		// API call which causes alloc will fail with KErrNoMemory. 
+		if ( usb.Connect() == KErrNoMemory )
+			{
+			usb.Close();
+			User::After(gInitSafetyTimeout);
+			return EFinished;
+			}
+		}
+  
+	User::After(gInitSafetyTimeout);
+
+	return ENotFinished;
+	}
+
+TInt Oom(TInitReturnValue fn(TUint n))
+/**
+ * Wrapper for OOM iterations.
+ *
+ * @param fn Function pointer taking a TUint (the iteration) and returning a 
+ * TInitReturnValue indicating whether the test has completed or not.
+ * @return KErrNone.
+ */
+	{
+	gTest.Printf(_L("\n"));
+
+	for ( TInt n = 1 ; ; n++ )
+		{
+		gTest.Printf(_L("Failing alloc %d\n"),n);
+	
+		if ( fn(n) == EFinished )
+			return KErrNone;
+		}
+	}
+
+TInt Regression_DEF23333()
+/**
+ * Regression test for defect DEF23333.
+ * Buffer size member of Tx class (CAcmWriter) isn't changed when SetBufSize 
+ * is used.
+ */
+	{
+	gTest.Printf(_L("\nRunning test Regression_DEF23333"));
+
+	CActiveScheduler* sch = new(ELeave) CActiveScheduler;
+	CActiveScheduler::Install(sch);
+
+	RUsb usb;
+	TEST(usb.Connect() == KErrNone);
+	TRequestStatus stat;
+	usb.Start(stat);
+	User::WaitForRequest(stat);
+	TEST(stat == KErrNone);
+
+	TName portName(KAcmSerialName);
+	portName.AppendFormat(_L("::%d"), KAcmLowUnit);
+
+	RCommServ sess;
+	TEST(sess.Connect() == KErrNone);
+	RComm acmPort;
+	TEST(sess.LoadCommModule(KAcmCsyName) == KErrNone);
+	TEST(acmPort.Open(sess, portName, ECommExclusive) == KErrNone);
+
+	// Hacky pause to wait for device to enumerate.
+	User::After(1000000);
+	
+	// This seems to be needed to keep the LDD happy.
+	gTest.Printf(_L("\nAttach a HyperTerminal session (emulated serial over USB) and hit a key"));
+	gTest.Getch();
+	
+	TInt len = acmPort.ReceiveBufferLength();
+	TEST(len > 10); 
+	// Check we can Write amounts of data less than the default starting 
+	// buffer size.
+	HBufC8* data = HBufC8::NewL(len + 20);
+	TPtr8 ptr = data->Des();
+	ptr.SetLength(len - 1);
+	acmPort.Write(stat, *data);
+	User::WaitForRequest(stat);
+	TEST(stat == KErrNone);
+	// Check writing an amount bigger than this fails.
+	ptr.SetLength(len + 1);
+	acmPort.Write(stat, *data);
+	User::WaitForRequest(stat);
+	TEST(stat == KErrNoMemory);	
+	// Resize the buffer.
+	const TInt newLength = 10;
+	acmPort.SetReceiveBufferLength(newLength);
+	TEST(acmPort.ReceiveBufferLength() == newLength);
+	// Check writing an amount smaller than the new buffer.
+	ptr.SetLength(newLength - 1);
+	acmPort.Write(stat, *data);
+	User::WaitForRequest(stat);
+	TEST(stat == KErrNone);
+	// Check writing an amount larger than the new size fails.
+	ptr.SetLength(newLength + 1);
+	acmPort.Write(stat, *data);
+	User::WaitForRequest(stat);
+	TEST(stat == KErrNoMemory);	
+	
+	delete data;
+	acmPort.Close();
+	TEST(sess.UnloadCommModule(KAcmSerialName) == KErrNone);
+	sess.Close();
+	usb.Stop(stat);
+	User::WaitForRequest(stat);
+	TEST(stat == KErrNone);
+	usb.Close();
+	
+	delete sch;
+
+	// This seems to be needed to keep the LDD happy.
+	gTest.Printf(_L("\nDisconnect the HyperTerminal session and hit a key"));
+	gTest.Getch();
+
+	return KErrNone;
+	}
+
+void PrintTestInstructions()
+	{
+	gTest.Printf(_L("\nThese tests should be run with USB OFF,"));
+	gTest.Printf(_L("\ni.e. RUsb has not been Started, or, if"));
+	gTest.Printf(_L("\nit has, it should be Stopped again."));
+	gTest.Printf(_L("\nAlso, there should be no open subsessions"));
+	gTest.Printf(_L("\non the ECACM.CSY."));
+	gTest.Printf(_L("\nIn a Techview ROM, it will be necessary"));
+	gTest.Printf(_L("\nto remove the watchers so that nothing"));
+	gTest.Printf(_L("\ninterferes with C32's heap (for the OOM"));
+	gTest.Printf(_L("\ntests in C32's heap)."));
+	gTest.Printf(_L("\nNothing else should be using USBMAN or"));
+	gTest.Printf(_L("\nECACM during the test."));
+	}
+
+void PrintTestIds()
+	{
+	gTest.Printf(_L("\n1/"));
+	gTest.Printf(_L("\n2/"));
+	gTest.Printf(_L("\n3/"));
+	gTest.Printf(_L("\n4/"));
+	gTest.Printf(_L("\n5/"));
+	gTest.Printf(_L("\n6/ OOM1 (in C32)- failure opening ACM port"));
+	gTest.Printf(_L("\n7/ OOM2 (in C32)- success opening ACM port"));
+	gTest.Printf(_L("\n8/ OOM3 (in USBMAN)- RUsb::Start"));
+	gTest.Printf(_L("\n9/ Regression_DEF23333"));
+	gTest.Printf(_L("\n! to run all"));
+	gTest.Printf(_L("\nEsc to exit"));
+	}
+
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
+												  	
+	gTest.Title();
+	gTest.Start(_L("Starting E32Main"));
+
+	gTest.Next(_L("loading LDD"));
+	TInt r = User::LoadLogicalDevice(KCommDriverName);
+	gTest(r == KErrNone || r == KErrAlreadyExists);
+
+#ifdef __WINS__
+	gTest.Next(_L("loading PDD"));
+	r = User::LoadPhysicalDevice(KCommPhysDriverName);
+	gTest(r == KErrNone || r == KErrAlreadyExists);
+#endif
+
+	gTest.Next(_L("starting C32"));
+	r = StartC32();
+	gTest(r == KErrNone || r == KErrAlreadyExists);
+
+	PrintTestInstructions();
+
+	PrintTestIds();
+
+	TInt key = gTest.Getch();
+
+	while ( key != EKeyEscape )
+		{
+		TInt error = KErrNone;
+
+		RCommServ sess;
+		sess.Connect();
+		sess.__DbgMarkHeap();
+
+		switch (key )
+			{
+		case '!':
+			RunAll();
+			break;
+		default:
+			error = RunOneTest(key);
+			break;
+			}
+
+		User::After(gInitSafetyTimeout);
+
+		sess.__DbgCheckHeap(0);
+		sess.Close();
+
+		User::After(gBetweenTestDelay);
+
+		gTest.Printf(_L("\nTest completed with error %d"), error);
+
+		PrintTestIds();
+
+		key = gTest.Getch();
+		}
+
+	gTest.End();
+	gTest.Close();
+
+	delete cleanup; // destroy clean-up stack
+	__UHEAP_MARKEND;
+	return KErrNone;
+	}
+
+TInt RunOneTest(TInt aKey)
+	{
+	TInt error = KErrNone;
+
+	switch ( aKey )
+		{
+	case '1':
+		error = _1();
+		break;
+	case '2':
+		error = _2();
+		break;
+	case '3':
+		error = _3();
+		break;
+	case '4':
+		error = _4();
+		break;
+	case '5':
+		error = _5();
+		break;
+	case '6':
+		error = Oom(C32_FailAcmOpen);
+		break;
+	case '7':
+		error = Oom(C32_SucceedAcmOpen);
+		break;
+	case '8':
+		error = Oom(USBMAN_SucceedAcmOpen);
+		break;
+	case '9':
+		error = Regression_DEF23333();
+		break;
+	default:
+		gTest.Printf(_L("\nKey not recognised"));
+		break;
+		}
+
+	return error;
+	}
+		
+void RunAll()
+	{
+	RCommServ sess;
+	sess.Connect();
+
+	for ( TInt ii = 0 ; ii < 9 ; ii++ ) // TODO: keep 9 up-to-date with number of tests.
+		{
+		sess.__DbgMarkHeap();
+		gTest.Printf(_L("\nTest completed with error %d"), RunOneTest('1'+ii));
+		sess.__DbgCheckHeap(0);
+		User::After(gBetweenTestDelay);
+		}
+
+	sess.Close();
+
+	User::After(gBetweenTestDelay);
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,56 @@
+/*
+* Copyright (c) 1999-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:
+* Build information for USB class support testing
+* USB Comms support testing
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTMMPFILES
+#include "../t_usbmanager_suite/group/bld.inf"
+#include "../T_usb/group/bld.inf"
+#include "../usbmsapp/bld.inf"
+#include "../startusb/group/bld.inf"
+#include "../startusb2/group/bld.inf"
+#include "../stopusb/group/bld.inf"
+#include "../showcaps/group/bld.inf"
+#include "../t_acm_wins/group/bld.inf"
+#include "../t_termusb/group/bld.inf"
+#include "../t_termusb2/group/bld.inf"
+#include "../t_usbmodem/group/bld.inf"
+#include "../t_acm/group/bld.inf"
+#include "../t_multi_acm/group/bld.inf"
+#include "../t_catc/group/bld.inf"
+#include "../t_usbman/group/bld.inf"
+#include "../t_whcm_cc/group/bld.inf"
+#include "../t_acm_cc/group/bld.inf"
+#include "../t_acm_spec/group/bld.inf"
+#include "../t_usb_cable_detect/group/bld.inf"
+#include "../csy/t_ecacm/group/bld.inf"
+#include "../ObexClassController/bld.inf"
+#include "../t_charging_emu/group/bld.inf"
+
+#include "../usbtestconsole/bld.inf"
+
+// Uncomment this to build the 'headless' acm for 
+// performance testing at the RDevUsbcClient level.
+// #include "../t_headlessecacm/group/bld.inf"
+
+PRJ_TESTEXPORTS
+tacmcsy.oby	/epoc32/rom/include/tacmcsy.oby
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/group/tacmcsy.oby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 2003-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:
+*
+*/
+
+
+REM Need to check C32 is present
+#include <c32.iby>
+
+REM USBMAN and ECACM.CSY
+#include <usbman.iby>
+#include <usb.iby>
+
+REM Start/Stop test apps
+#include <startusb.iby>
+#include <stopusb.iby>
+
+REM Higher level tests
+#include <t_termusb.iby>
+#include <t_usbmodem.iby>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/group/usb_test.history.xml	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<relnotes name="USB Manager">
+  <purpose>
+    Test applications for USB.
+  </purpose>
+
+  <defect number="DEF125802" title="USB Test Source Type Re-classification " revision="006">
+    mrp now matches distribution policy files for Win32 USB Host files
+  </defect>
+
+  <defect number="PDEF122279" title="t_acm Several tests fail or hang due to changed behaviour of ACM" revision="005">
+    t_acm tests corrected,
+  </defect>
+
+  <defect number="DEF108115" title="T_usb3 fails" revision="004">
+    Modified the t_usb3.ini with expected read failure value i.e. KErrUsbInterfaceNotReady = -6702
+  </defect>
+
+  <defect number="PDEF118797" title="Correct CheckSource failures in \usb\usb_test\  files" revision="003">
+    Files corrected.
+  </defect>
+
+  <defect number="PDEF119091" title="Tag scan errors in usb\usb_test" revision="002">
+    Changed upper case to lower case
+  </defect>
+
+  <preq number="1576" title="State change plug-in interface to USB Manager (for charging)" revision="001"/>
+</relnotes>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/group/usb_test.mrp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+# Copyright (c) 2003-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:
+# 
+#
+#
+
+component	usb_test
+
+source	\sf\os\usb\usbmgmt\usbmgrtest
+
+notes_source	\component_defs\release.src
+
+
+
+ipr T 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/showcaps/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* 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 "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:
+* BLD.INF for showcaps
+* BLD.INF for showcaps
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+showcaps.mmp
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/showcaps/group/showcaps.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 1997-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:
+* T_TERMUSB.MMP
+*
+*/
+
+TARGET         showcaps.exe
+TARGETTYPE     EXE
+SOURCEPATH    ../src
+SOURCE         showcaps.cpp
+LIBRARY        euser.lib c32.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/showcaps/src/showcaps.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,110 @@
+/*
+* Copyright (c) 1997-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:
+* SER-COMMS\USB\TESTSRC\SHOWCAPS.CPP
+*
+*/
+
+#include <c32comm.h>
+#include <e32test.h>
+
+#ifndef __WINS__
+_LIT(KCommDriverName, "EUSBC");
+_LIT(KCommDeviceName, "USBC");
+_LIT(KCommModuleCsyName, "ECACM");
+_LIT(KCommModulePortNameAndNumber, "ACM::0");
+_LIT(KCommModulePortName, "ACM");
+#else
+_LIT(KCommPhysDriverName, "ECDRV");
+_LIT(KCommPhysDeviceName, "Comm.Wins");
+_LIT(KCommDriverName, "ECOMM");
+_LIT(KCommDeviceName, "Comm");
+_LIT(KCommModuleCsyName, "ECUART");
+_LIT(KCommModulePortNameAndNumber, "COMM::0");
+_LIT(KCommModulePortName, "COMM");
+#endif
+
+LOCAL_D RCommServ CommServ;
+LOCAL_D RComm CommPort;
+LOCAL_D RTest test(_L("SHOWCAPS"));
+
+TInt E32Main()
+/**
+ * Loads the USB serial driver and prints its capabilities.
+ */
+	{
+	TInt r;
+
+	test.Title();
+	test.Start(_L("Starting E32Main"));
+
+ 	__UHEAP_MARK;
+
+	test.Next(_L("loading LDD"));
+	r = User::LoadLogicalDevice(KCommDriverName);
+	test(r == KErrNone || r == KErrAlreadyExists);
+
+#ifdef __WINS__
+	test.Next(_L("loading PDD"));
+	r = User::LoadPhysicalDevice(KCommPhysDriverName);
+	test(r == KErrNone || r == KErrAlreadyExists);
+#endif
+
+	test.Next(_L("starting C32"));
+	r = StartC32();
+	test(r == KErrNone || r == KErrAlreadyExists);
+
+	test.Next(_L("connecting to comms server"));
+	test(CommServ.Connect() == KErrNone);
+
+	test.Next(_L("loading CommPort module"));
+	r = CommServ.LoadCommModule(KCommModuleCsyName);
+	test(r == KErrNone || r == KErrAlreadyExists);
+
+	test.Next(_L("opening CommPort port"));
+	test(CommPort.Open(CommServ, KCommModulePortNameAndNumber, ECommExclusive) == KErrNone);
+
+	test.Next(_L("getting caps"));
+	TCommCaps2 cc2;
+	CommPort.Caps(cc2);
+	test.Printf(_L("TCommCapsV01"));
+	test.Printf(_L("iRate\t0x%x\n"), cc2().iRate);
+	test.Printf(_L("iDataBits\t0x%x\n"), cc2().iDataBits);
+	test.Printf(_L("iStopBits\t0x%x\n"), cc2().iStopBits);
+	test.Printf(_L("iParity\t0x%x\n"), cc2().iParity);
+	test.Printf(_L("iHandshake\t0x%x\n"), cc2().iHandshake);
+	test.Printf(_L("iSignals\t0x%x\n"), cc2().iSignals);
+	test.Printf(_L("iFifo\t%d\n"), cc2().iFifo);
+	test.Printf(_L("iSIR\t%d\n"), cc2().iSIR);
+	test.Printf(_L("TCommCapsV02"));
+	test.Printf(_L("iNotificationCaps\t0x%x\n"), cc2().iNotificationCaps);
+	test.Printf(_L("iRoleCaps\t0x%x\n"), cc2().iRoleCaps);
+	test.Printf(_L("iFlowControlCaps\t0x%x\n"), cc2().iFlowControlCaps);
+
+	CommPort.Close();
+	test(CommServ.UnloadCommModule(KCommModulePortName) == KErrNone);
+	CommServ.Close();
+#ifdef __WINS__
+	test(User::FreePhysicalDevice(KCommPhysDeviceName) == KErrNone);
+#endif
+	test(User::FreeLogicalDevice(KCommDeviceName) == KErrNone);
+
+	__UHEAP_MARKEND;
+
+	test.End();
+	test.Close();
+
+
+	return KErrNone;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/startusb/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* 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 "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:
+* BLD.INF for startusb
+* BLD.INF for startusb
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+startusb.iby    /epoc32/rom/include/startusb.iby
+
+PRJ_TESTMMPFILES
+startusb.mmp
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/startusb/group/startusb.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 2003-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:
+* Test program for serial port
+*
+*/
+
+#ifndef __STARTUSB_IBY__
+#define __STARTUSB_IBY__
+
+file=ABI_DIR\DEBUG_DIR\startusb.exe    System\Programs\startusb.exe
+file=ABI_DIR\DEBUG_DIR\startusb2.exe    System\Programs\startusb2.exe
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/startusb/group/startusb.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+TARGET         startusb.exe
+TARGETTYPE     EXE
+SOURCEPATH    ../src
+SOURCE         startusb.cpp
+LIBRARY        euser.lib efsrv.lib c32.lib usbman.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/startusb/src/startusb.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,118 @@
+/*
+* Copyright (c) 1997-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:
+*
+* Startusb.cpp
+*
+*/ 
+
+
+#include <e32test.h>
+#include <e32twin.h>
+#include <c32comm.h>
+#include <d32comm.h>
+#include <f32file.h>
+#include <hal.h>
+#include <usbman.h>
+
+static TInt MainL()
+	{
+	RDebug::Print(_L("Main() - Starting!"));
+
+	RFs theFs;
+
+	TInt r = theFs.Connect();
+	if (r != KErrNone)
+		{
+		RDebug::Print(_L("Main() - Failed to connect to the fs. Error = %d"), r);
+		return r;
+		}
+
+	RDebug::Print(_L("Main() - Connected to file server"));
+
+	r = StartC32();
+	if (r!=KErrNone && r !=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("Main() - Failed to start C32. Error = %d"), r);
+		return r;
+		}
+
+	RDebug::Print(_L("E32Main: Started c32"));
+
+	RUsb usb;
+	TInt err = usb.Connect();
+	if (err != KErrNone)
+		{
+		RDebug::Print(_L("MainL() - Unable to Connect to USB server"));
+		theFs.Close();
+		return err;
+		}
+	RDebug::Print(_L("MainL() - Connected to USB server"));
+
+	TUsbServiceState state;
+
+	err = usb.GetCurrentState(state);
+	if (err != KErrNone)
+		{
+		RDebug::Print(_L("MainL() - Failed to fetch service state from usbman, error %d"), err);
+		}
+	else
+		{
+		RDebug::Print(_L("MainL() - Usb service state = 0x%x"), state);
+		}
+
+	TRequestStatus status;
+	usb.Start(status);
+	User::WaitForRequest(status);
+
+	if (status.Int() != KErrNone)
+		{
+		RDebug::Print(_L("MainL() - Unable to start USB services. Error %d"), status.Int());
+		theFs.Close();
+		return status.Int();
+		}
+
+	err = usb.GetCurrentState(state);
+	if (err != KErrNone)
+		{
+		RDebug::Print(_L("MainL() - Failed to fetch service state from usbman, error %d"), err);
+		}
+	else
+		{
+		RDebug::Print(_L("MainL() - Usb service state = 0x%x"), state);
+		}
+
+	RDebug::Print(_L("MainL() - Started USB services"));
+	usb.Close();
+	theFs.Close();
+	RDebug::Print(_L("MainL() - Exiting normally"));
+	return KErrNone;
+	}
+
+GLDEF_C TInt E32Main()
+    {
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	if(cleanup == NULL)
+		{
+		return KErrNoMemory;
+		}
+	TRAPD(err,err=MainL());
+
+	if (err != KErrNone)
+		User::Panic(_L("StartUsb::E32Main - Panic"), err);
+
+	delete cleanup;
+	return err;
+    }
+///////////////////////
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/startusb2/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+/*
+* 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 "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:
+* BLD.INF for startusb2
+* BLD.INF for startusb2
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+startusb2.mmp
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/startusb2/group/startusb2.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 1997-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:
+* STARTUSB.MMP
+*
+*/
+
+TARGET         startusb2.exe
+TARGETTYPE     EXE
+SOURCEPATH    ../src
+SOURCE         startusb2.cpp
+LIBRARY        euser.lib efsrv.lib c32.lib usbman.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/startusb2/src/startusb2.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,98 @@
+/*
+* Copyright (c) 2003-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:
+*
+*/
+
+#include <e32test.h>
+#include <e32twin.h>
+#include <c32comm.h>
+#include <d32comm.h>
+#include <f32file.h>
+#include <hal.h>
+#include <usbman.h>
+
+static TInt MainL()
+	{
+	RDebug::Print(_L("Main() - Starting!"));
+
+	RFs theFs;
+
+	TInt r = theFs.Connect();
+	if (r != KErrNone)
+		{
+		RDebug::Print(_L("Main() - Failed to connect to the fs. Error = %d"), r);
+		return r;
+		}
+
+	RDebug::Print(_L("Main() - Connected to file server"));
+
+	r = StartC32();
+	if (r!=KErrNone && r !=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("Main() - Failed to start C32. Error = %d"), r);
+		return r;
+		}
+
+	RDebug::Print(_L("E32Main: Started c32"));
+
+	RUsb usb;
+	TInt err = usb.Connect();
+	if (err != KErrNone)
+		{
+		RDebug::Print(_L("MainL() - Unable to Connect to USB server"));
+		theFs.Close();
+		return err;
+		}
+	RDebug::Print(_L("MainL() - Connected to USB server"));
+
+	TUsbServiceState state;
+
+	err = usb.GetCurrentState(state);
+	if (err != KErrNone)
+		{
+		RDebug::Print(_L("MainL() - Failed to fetch service state from usbman, error %d"), err);
+		}
+	else
+		{
+		RDebug::Print(_L("MainL() - Usb service state = 0x%x"), state);
+		}
+
+	TRequestStatus status;
+	usb.Start(status);
+	User::WaitForRequest(status);
+
+	RDebug::Print(_L("Start completed with status %d"), status.Int());
+
+	theFs.Close();
+	RDebug::Print(_L("MainL() - Exiting normally"));
+	return KErrNone;
+	}
+
+GLDEF_C TInt E32Main()
+    {
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	if(cleanup == NULL)
+		{
+		return KErrNoMemory;
+		}
+	TRAPD(err,err=MainL());
+
+	if (err != KErrNone)
+		User::Panic(_L("StartUsb::E32Main - Panic"), err);
+
+	delete cleanup;
+	return err;
+    }
+///////////////////////
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/stopusb/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+/*
+* 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 "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:
+* BLD.INF for stopusb
+* BLD.INF for stopusb
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+stopusb.iby    /epoc32/rom/include/stopusb.iby
+
+
+PRJ_TESTMMPFILES
+stopusb.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/stopusb/group/stopusb.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2003-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:
+* Test program for serial port
+*
+*/
+
+#ifndef __STOPUSB_IBY__
+#define __STOPUSB_IBY__
+
+file=ABI_DIR\DEBUG_DIR\stopusb.exe    System\Programs\stopusb.exe
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/stopusb/group/stopusb.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+TARGET         stopusb.exe
+TARGETTYPE     EXE
+SOURCEPATH    ../src
+SOURCE         stopusb.cpp
+LIBRARY        euser.lib usbman.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/stopusb/src/stopusb.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2003-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:
+*
+*/
+
+#include <e32base.h>
+#include <usbman.h>
+
+static void MainL()
+	{
+	RUsb usb;
+	User::LeaveIfError(usb.Connect());
+	usb.Stop();
+	usb.Close();
+	}
+
+GLDEF_C TInt E32Main()
+    {
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	if(cleanup == NULL)
+		{
+		return KErrNoMemory;
+		}
+	TRAPD(err,MainL());
+
+	if (err != KErrNone)
+		User::Panic(_L("StopUsb::E32Main - Panic"), err);
+
+	delete cleanup;
+	return KErrNone;
+    }
+///////////////////////
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* 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 "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:
+* BLD.INF for t_acm
+* BLD.INF for t_acm
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+t_acm.iby	/epoc32/rom/include/t_acm.iby
+
+PRJ_TESTMMPFILES
+t_acm.mmp
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm/group/t_acm.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,26 @@
+/*
+* 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 "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:
+* Test program for USB ACM ports
+*
+*/
+
+#ifndef __T_ACM_IBY__
+#define __T_ACM_IBY__
+
+file=ABI_DIR\DEBUG_DIR\t_acm.exe    t_acm.exe
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm/group/t_acm.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+TARGET		t_acm.exe
+CAPABILITY All -Tcb
+TARGETTYPE	EXE
+UID		0
+VENDORID 0x70000001
+SOURCEPATH    ../src
+SOURCE		t_acm.cpp
+LIBRARY		euser.lib c32.lib usbman.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm/src/t_acm.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,1880 @@
+/*
+* 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:
+* This program executes all the tests in the ACM CSY Test Specification v 0.1
+* and is to be used in conjunction with the host-side application. (t_acm_wins)
+*
+*/
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <e32math.h>
+#include <c32comm.h>
+#include <usbman.h>
+#include <e32debug.h>
+
+LOCAL_D CConsoleBase* console;
+
+RCommServ TheCommServ;
+RUsb TheUsb;
+
+TCommConfig TheConfigBuf;
+TCommConfigV01& TheConfig = TheConfigBuf();
+
+const TInt KReceiveBufferLength = 4096;
+const TInt KMaxAcmPortNameLength = 8;
+//_LIT(KUsbCsyName, "ECACM");
+_LIT(KUsbPortName, "ACM::0");
+_LIT(KUsbPortNameAcm1, "ACM::1");
+
+_LIT(KUsbLddName, "EUSBC");
+
+#define _printf console->Printf
+#define _getch console->Getch
+#define LEAVE(_x) VerboseLeaveL(_x, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+#define LEAVEIFERROR(_x) VerboseLeaveIfErrorL(_x, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+#define CHECK(_x) if (! (_x)) VerboseLeaveL(KErrGeneral, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+
+// A define for stack-based buffers
+#define MAX_BUFFER_SIZE 1024
+
+// A bigger buffer on the heap
+#define MAX_HEAP_BUFFER_SIZE	(1024*8)
+TBuf8<MAX_HEAP_BUFFER_SIZE> readBigBuf;
+
+// A timer for use by several of the tests
+RTimer timer;
+
+//The random seed
+TInt64 seed = 100;
+
+void VerboseLeaveL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode)
+/**
+ * For bombing out usefully.
+ */
+	{
+	TInt filenameOffset = aFileName.LocateReverse('\\') + 1;
+	if (filenameOffset < 0) filenameOffset = 1;
+	TPtrC8 shortFileName = aFileName.Mid(filenameOffset);
+	TBuf<64> fName, code;
+	fName.Copy(shortFileName.Left(64));
+	code.Copy(aCode.Left(64));
+	_printf(_L("\nERROR (%d) on line %d of file %S\n"), aError, aLineNum, &fName);
+	_printf(_L("Code: %S\n\n"), &code);
+	_printf(_L("[ press any key ]"));
+	_getch();
+	User::Leave(aError);
+	}
+
+void VerboseLeaveIfErrorL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode)
+/**
+ * For bombing out usefully if there's an error.
+ */
+	{
+	if (aError)
+		VerboseLeaveL(aError, aLineNum, aFileName, aCode);
+	}
+
+void ReadString(TDes& aDes)
+/**
+ * Reads user input into the start of the descriptor aDes.
+ */
+	{
+	TChar inputKey;
+	TInt count = 0;
+
+	aDes.Zero();
+	for (;;)
+		{
+		inputKey = (TInt) _getch();
+
+		if ((TInt)inputKey == EKeyEnter)
+			break;
+
+		if(inputKey == EKeyBackspace)
+			{
+			if (count > 0)
+				{
+				_printf(_L("%C"), (TUint) inputKey);
+				aDes.Delete(--count,1);
+				}
+			}
+		else if(inputKey.IsPrint())
+			{
+			_printf(_L("%C"), (TUint) inputKey);
+			aDes.Append(inputKey);
+			count++;
+			}
+		}
+	}
+
+void FillBuffer(TDes8 &aDes)
+/**
+ * Fills a given buffer with incrementing numbers.
+ */
+{
+	 aDes.Zero();
+	 for (TInt i=0; i<aDes.MaxSize(); i++)
+	 {
+		  aDes.Append(i);
+	 }
+}
+
+bool CheckBuffer(TDes8 &aDes, TInt size)
+/**
+ * Checks that a given buffer contains incrementing numbers.
+ */
+{
+	 for (TInt i=0; i<size; i++)
+	 {
+		  if (aDes[i] != i)
+			   return FALSE;
+	 }
+
+	 return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ *  loopback From a Port input by the user to abother port-
+ *  ACM::1 KUsbPortNameAcm1 to ACM::0 KUsbPortName by default
+ */
+
+void ReadLoopbackFromPortAToPortBTestL()
+	{
+
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm portIN;
+	RComm portOut;
+
+	_printf(_L("Enter the packet size:"));
+	TBufC<8> buf;
+	TPtr ptr (buf.Des());
+	ReadString(ptr);
+
+	TLex input(buf);
+
+	TInt pktlen = 0;
+	while ((input.Peek()).IsDigit()) {
+		pktlen = 10*pktlen + (input.Get()) - '0';
+	}
+
+	// Get port names
+	_printf(_L("\nEnter acm port name as loopback INPUT: (ex ACM::1):"));
+	TBufC<KMaxAcmPortNameLength> portINName;
+	TPtr portINNamePtr (portINName.Des());
+	ReadString(portINNamePtr);
+	if ( portINNamePtr.Length() == 0 )
+		{
+		portINName= KUsbPortNameAcm1;
+		}
+
+	_printf(_L("\nEnter acm port name as loopback OUTPUT: (ex ACM::0):"));
+	TBufC<KMaxAcmPortNameLength> portOutName;
+	TPtr portOutNamePtr (portOutName.Des());
+	ReadString(portOutNamePtr);
+	if ( portOutNamePtr.Length() == 0 )
+		{
+		portOutName = KUsbPortName;
+		}
+
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This test listens for data on the ACM port: "));
+	_printf(portINName);
+	_printf(_L("\nwrites anything it receives on the ACM port: "));
+	_printf(portOutName);
+	_printf(_L("\nPress any key to quit.\n"));
+	_printf(_L("----------------------------------------\n\n"));
+
+	LEAVEIFERROR(portIN.Open(TheCommServ, portINName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(portIN);
+
+	LEAVEIFERROR(portOut.Open(TheCommServ, portOutName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(portOut);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	portIN.SetConfig(TheConfigBuf);
+	portIN.SetReceiveBufferLength(KReceiveBufferLength);
+	portOut.SetConfig(TheConfigBuf);
+	portOut.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("loopback received data\n"));
+
+	console->Read(consoleStatus);
+
+	FOREVER
+		{
+		portIN.Read(status, readBigBuf, pktlen);
+
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			portIN.ReadCancel();
+			break;
+			}
+
+		portOut.Write(status, readBigBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			portOut.WriteCancel();
+			break;
+			}
+		}
+
+	portOut.WriteCancel();
+
+	_printf(_L("\nTest complete\n"));
+
+	CleanupStack::PopAndDestroy(2); // portA	, portOut
+
+	}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ *  Original loopback test - uses Read().
+ */
+
+void ReadLoopbackTestL()
+	{
+
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm port;
+
+	_printf(_L("Enter the packet size:"));
+	TBufC<8> buf;
+	TPtr ptr (buf.Des());
+	ReadString(ptr);
+
+	TLex input(buf);
+
+	TInt pktlen = 0;
+	while ((input.Peek()).IsDigit()) {
+		pktlen = 10*pktlen + (input.Get()) - '0';
+	}
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This test listens for data on the ACM\n"));
+	_printf(_L("port and echoes anything it receives\n"));
+	_printf(_L("back to the PC. Press any key to quit.\n"));
+	_printf(_L("----------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Echoing received data\n"));
+
+	console->Read(consoleStatus);
+
+	FOREVER
+		{
+		port.Read(status, readBigBuf, pktlen);
+
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.ReadCancel();
+			break;
+			}
+		port.Write(status, readBigBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.WriteCancel();
+			break;
+			}
+		}
+
+	_printf(_L("\nTest complete\n"));
+
+	CleanupStack::PopAndDestroy(); // port
+
+	}
+
+/**
+ * Original loopback test - uses ReadOneOrMore().
+ */
+
+void LoopbackTestL()
+	{
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm port;
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This test listens for data on the ACM\n"));
+	_printf(_L("port and echoes anything it receives\n"));
+	_printf(_L("back to the PC. Press any key to quit.\n"));
+	_printf(_L("----------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Echoing received data\n"));
+
+	TBuf8<256> readBuf;
+
+	console->Read(consoleStatus);
+
+	FOREVER
+		{
+		port.ReadOneOrMore(status, readBuf);
+
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.ReadCancel();
+			break;
+			}
+		port.Write(status, readBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.WriteCancel();
+			break;
+			}
+		}
+
+	_printf(_L("\nTest complete\n"));
+
+	CleanupStack::PopAndDestroy(); // port
+	}
+
+/**
+ * NotifydataAvailable test.
+ */
+
+void NotifyDataAvailableTestL()
+	{
+	TRequestStatus status;
+	TRequestStatus stat2;
+	RComm port;
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This test listens for data on the ACM\n"));
+	_printf(_L("port and echoes anything it receives\n"));
+	_printf(_L("back to the PC. Press any key to quit.\n"));
+	_printf(_L("----------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Echoing received data\n"));
+
+	TBuf8<256> readBuf;
+
+	_printf(_L("*********************************\n"));
+	_printf(_L("test NotifyDataAvailable\n"));
+	TRequestStatus stat;
+	TRequestStatus status2;
+
+	_printf(_L("test NotifyDataAvailable, nominal test\n"));
+
+	port.NotifyDataAvailable(status);
+
+	User::WaitForRequest(status);	// wait until the data is available
+
+	LEAVEIFERROR(status.Int());
+
+	TBuf8<30> receive;
+	port.ReadOneOrMore(status,receive);
+	User::WaitForRequest(status);
+
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("test NotifyDataAvailable, nominal test succeeded\n"));
+
+
+	//=========== Test the KErrInUse that should be returned when a notification of data available is posted at the same
+	// time as a Read - or visa versa  ============== //
+	_printf(_L("test NotifyDataAvailable, KErrInUse mode\n"));
+
+	TBuf8<10> buf;
+	port.ReadOneOrMore(status,buf);
+	port.NotifyDataAvailable(status2);
+	User::WaitForRequest(status2);
+	if (status2.Int() != KErrInUse)
+		{
+		LEAVE(status2.Int());
+		}
+	LEAVEIFERROR(port.ReadCancel());
+
+	User::WaitForRequest(status);
+	if (status.Int() != KErrCancel)
+		{
+		LEAVE(status.Int());
+		}
+	// 2nd case
+	port.NotifyDataAvailable(status);
+	port.ReadOneOrMore(status2,buf);
+	User::WaitForRequest(status2);
+	if (status2.Int() != KErrInUse)
+		{
+		LEAVE(status2.Int());
+		}
+
+	// cancel
+	LEAVEIFERROR(port.NotifyDataAvailableCancel());
+
+	User::WaitForRequest(status);
+
+	if (status.Int() != KErrCancel)
+		{
+		LEAVE(status.Int());
+		}
+	_printf(_L("test NotifyDataAvailable, KErrInUse test succeeded\n"));
+
+
+	// ====== test NotifyDataAvailable, testing canceling
+
+	_printf(_L("test NotifyDataAvailable, testing canceling\n"));
+	port.NotifyDataAvailable(stat);
+	User::WaitForRequest(stat);
+
+	LEAVEIFERROR(stat.Int());
+
+	port.ResetBuffers();
+	// testing canceling
+	stat2=KErrNone;
+	port.NotifyDataAvailable(stat2);
+	LEAVEIFERROR(port.NotifyDataAvailableCancel());
+	User::WaitForRequest(stat2); //
+	if (stat2.Int() != KErrCancel)
+		{
+		LEAVE(stat2.Int());
+		}
+	stat2=KErrNone;
+	port.NotifyDataAvailable(stat2);
+    LEAVEIFERROR(port.NotifyDataAvailableCancel());
+
+	User::WaitForRequest(stat2); //
+	if (stat2.Int() != KErrCancel)
+		{
+		LEAVE(stat2.Int());
+		}
+
+	_printf(_L("test NotifyDataAvailable, testing canceling succeeded\n"));
+
+	User::After(20000000);
+
+	_printf(_L("\nTest complete\n"));
+
+	CleanupStack::PopAndDestroy(); // port
+	}
+
+void ReadWithTerminatorsLoopbackTestL()
+	{
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm port;
+
+	// Get terminator characters
+	_printf(_L("Enter the terminator characters (up to %d):"), KConfigMaxTerminators);
+	TBufC<KConfigMaxTerminators> termbuf;
+	TPtr termptr (termbuf.Des());
+	ReadString(termptr);
+	TText8 terminators[KConfigMaxTerminators];
+	if ( termptr.Length() == 0 )
+		{
+		_printf(_L("\nno terminators given- not running test"));
+		return;
+		}
+	TUint termCount = 0;
+	TUint ii;
+	for ( ii = 0 ; ii < (TUint)termptr.Length() ; ii++ )
+		{
+		termCount++;
+		terminators[ii] = (TText8)termptr[ii];
+		}
+
+	_printf(_L("\nEnter the packet size:"));
+	TBufC<8> buf;
+	TPtr ptr (buf.Des());
+	ReadString(ptr);
+
+	TLex input(buf);
+
+	TInt pktlen = 0;
+	while ((input.Peek()).IsDigit()) {
+		pktlen = 10*pktlen + (input.Get()) - '0';
+	}
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This test listens for data on the ACM\n"));
+	_printf(_L("port and echoes anything it receives\n"));
+	_printf(_L("back to the PC. Press any key to quit.\n"));
+	_printf(_L("----------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	// Set the config, including terminator characters.
+	TCommConfig configBuf;
+	TCommConfigV01& config = configBuf();
+	port.Config(configBuf);
+	config.iTerminatorCount = termCount;
+	for ( ii = 0 ; ii < termCount ; ii++ )
+		{
+		config.iTerminator[ii] = terminators[ii];
+		}
+	LEAVEIFERROR(port.SetConfig(configBuf));
+
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Echoing received data\n"));
+
+	console->Read(consoleStatus);
+
+	TBuf8<256> readBuf;
+
+	FOREVER
+		{
+		port.Read(status, readBuf, pktlen);
+
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.ReadCancel();
+			break;
+			}
+
+		port.Write(status, readBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.WriteCancel();
+			break;
+			}
+		}
+
+	_printf(_L("\nTest complete\n"));
+
+	CleanupStack::PopAndDestroy(); // port
+	}
+
+/////////////////////////////////////////////////////////////////////////////////
+
+void DataStress_SizeVary_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+	TInt i;
+
+	_printf(_L("\n----------------------------------\n"));
+	_printf(_L("This test performs varying size read\n"));
+	_printf(_L("and writes to and from the host.\n"));
+	_printf(_L("------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf;
+
+	_printf(_L("Reading data.\nLengths:"));
+	for (i = 1; i<MAX_BUFFER_SIZE; i*=2)
+		{
+		_printf(_L(" %d"), i);
+
+		port.Read(status, readBuf, i);
+		User::WaitForRequest(status);
+
+		if (status != KErrNone)
+			{
+			LEAVE(status.Int());
+			}
+
+		CheckBuffer(readBuf, i);
+		}
+
+	_printf(_L(" done.\nReadOneOrMore()-ing data.\n"));
+	TUint totalExpectedTransfer = 0;
+	for (i = 1; i<MAX_BUFFER_SIZE; i*=2)
+		{
+		totalExpectedTransfer += i;
+		}
+	TUint totalTransfer = 0;
+	while ( totalTransfer < totalExpectedTransfer )
+		{
+		port.ReadOneOrMore(status, readBuf);
+		User::WaitForRequest(status);
+
+		if (status != KErrNone)
+			{
+				_printf(_L("Read error"));
+				LEAVE(status.Int());
+			}
+		else
+			{
+				totalTransfer += readBuf.Length();
+			}
+		}
+
+	_printf(_L("\n Writing\n"));
+
+	for (i = 1; i<MAX_BUFFER_SIZE; i*=2)
+		{
+
+		FillBuffer(readBuf);
+
+		port.Write(status, readBuf, i);
+
+		User::WaitForRequest(status);
+
+		if (status != KErrNone)
+			{
+			_printf(_L("write error\n"));
+			LEAVE(status.Int());
+			}
+
+		_printf(_L(" %d"), i);
+		}
+
+	_printf(_L(" done.\nTest complete\n"));
+	 CleanupStack::PopAndDestroy(); //port
+}
+
+
+void DataStress_RateVary_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+	TInt i;
+
+	_printf(_L("\n----------------------------------\n"));
+	_printf(_L("This test performs varying speed read\n"));
+	_printf(_L("and writes to and from the host.\n"));
+	_printf(_L("------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf;
+
+	_printf(_L("Reading data.\nLengths:"));
+	for (i = 1; i<100; i++)
+		{
+		_printf(_L(" %d"), i);
+		port.Read(status, readBuf);
+		User::WaitForRequest(status);
+
+		if (status != KErrNone)
+			{
+			_printf(_L("Error reading"));
+			LEAVE(status.Int());
+			}
+
+		CheckBuffer(readBuf, readBuf.MaxSize());
+		}
+
+
+	_printf(_L("done.\nReadOneOrMore()-ing data.\n "));
+	int totalTransferSize = 19*MAX_BUFFER_SIZE;
+	int totalTransfer = 0;
+	while (totalTransfer < totalTransferSize) {
+		port.ReadOneOrMore(status, readBuf);
+		User::WaitForRequest(status);
+
+		if (status != KErrNone)
+			{
+			LEAVE(status.Int());
+			}
+		else
+			{
+			totalTransfer += readBuf.Length();
+			}
+	}
+
+	_printf(_L(" Writing data\n"));
+
+	FillBuffer(readBuf);
+
+	for (i = 1; i< 100; i++)
+		{
+		_printf(_L(" %d "), i);
+		port.Write(status, readBuf, MAX_BUFFER_SIZE);
+		User::WaitForRequest(status);
+
+		if (status != KErrNone)
+			{
+			_printf(_L("Write failed\n"));
+			LEAVE(status.Int());
+			}
+
+		// Wait for random time
+		timer.After(status, (Math::Rand(seed) % 1001));//1001 to get a value within [0-1000]
+		User::WaitForRequest(status);
+		}
+
+	_printf(_L(" done.\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+
+void TimeOut_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+	TInt timeout;
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf;
+
+	_printf(_L("\n---------------------------\n"));
+	_printf(_L("This test exercises the read\n"));
+	_printf(_L("and write timeouts.\n"));
+	_printf(_L("-----------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Reading data\nTimeouts (ms):"));
+	for (timeout = 10; timeout<100; timeout+=10)
+		{
+		 // Clean buffers
+		 port.ResetBuffers();
+
+		_printf(_L(" %d"), timeout);
+		port.Read(status, timeout, readBuf, MAX_BUFFER_SIZE);
+		User::WaitForRequest(status);
+
+		if (status != KErrTimedOut)
+		    {
+				LEAVE(status.Int());
+			}
+		}
+
+	TBuf8<MAX_BUFFER_SIZE> writeBuf;
+	writeBuf = _L8("some data");
+	_printf(_L(" done.\nWriting data\nTimeouts (ms):"));
+	for (timeout = 10; timeout<100; timeout+=10)
+		{
+		 // Clean buffers
+		 port.ResetBuffers();
+
+		_printf(_L(" %d"), timeout);
+		port.Write(status, timeout, writeBuf);
+		User::WaitForRequest(status);
+
+		if (status != KErrTimedOut && status != KErrNone ) // NB Writes complete very quickly.
+		    {
+				LEAVE(status.Int());
+			}
+		}
+
+	_printf(_L(" done.\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void CancelTx_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+	TInt timeout;
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf;
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This tests the read/write cancel feature\n"));
+	_printf(_L("------------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Reading data\n"));
+	for (timeout = 10; timeout<100; timeout++)
+		{
+		port.Read(status, readBuf);
+
+		// Wait before cancelling
+		timer.After(status, timeout);
+		User::WaitForRequest(status);
+
+		port.ReadCancel();
+		User::WaitForRequest(status);
+
+		if ( (status != KErrNone) && (status !=KErrCancel) )
+			{
+			LEAVE(status.Int());
+			}
+		}
+
+	_printf(_L("Writing data\n"));
+	for (timeout = 10; timeout<100; timeout++)
+		{
+//		FillBuffer(readBuf);
+
+		port.Write(status, readBuf);
+
+		// Wait before cancelling
+		timer.After(status, timeout);
+		User::WaitForRequest(status);
+
+		port.WriteCancel();
+		User::WaitForRequest(status);
+
+		if ( (status != KErrNone) && (status !=KErrCancel) )
+			{
+			LEAVE(status.Int());
+			}
+		}
+
+	_printf(_L("\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void InterruptTx_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf;
+
+	_printf(_L("\n--------------------------------\n"));
+	_printf(_L("This tests the read/write cancel\n"));
+	_printf(_L("when the USB cable is pulled\n"));
+	_printf(_L("----------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Reading data\n"));
+	port.Read(status, readBuf);
+
+	_printf(_L("Pull cable now\n"));
+	User::WaitForRequest(status);
+	_printf(_L("Received error code: %d\n"),status.Int());
+	_printf(_L("Expect -29(KErrCommsLineFail) or range -6702 to -6712 (USB driver errors)\n\n"));
+
+	_printf(_L("Plug in cable and press any key\n"));
+	_getch();
+	User::After(1000000);
+
+	_printf(_L("Pull cable now\n"));
+	_printf(_L("Writing data...\n"));
+	do
+	{
+		 port.Write(status, readBuf);
+		 User::WaitForRequest(status);
+
+	} while (status == KErrNone);
+
+	_printf(_L("Received error code: %d\n"),status.Int());
+	_printf(_L("Expect -29(KErrCommsLineFail) or range -6702 to -6712 (USB driver errors)\n\n"));
+
+	_printf(_L("Plug in cable and press any key- test is now finished\n"));
+	_getch();
+
+	_printf(_L("\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void Shutdown_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf;
+
+	_printf(_L("\n-----------------------------------\n"));
+	_printf(_L("This tests the USB Manager shutdown\n"));
+	_printf(_L("during reads and writes.\n"));
+	_printf(_L("-------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Reading data\n"));
+	port.Read(status, readBuf);
+
+	_printf(_L("Shutting down USB Manager.\n"));
+	TheUsb.Stop();
+
+	_printf(_L("shutdown complete.\nWaiting for read to terminate."));
+	User::WaitForRequest(status);
+
+	if (status != KErrAccessDenied)
+		{
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("Read complete.\nRestarting USB Manager\n"));
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	// Hacky pause to wait for device to enumerate.
+	User::After(1000000);
+	_printf(_L("Writing data\n"));
+
+	port.Write(status, readBuf);
+
+	_printf(_L("Shutting down USB Manager\n"));
+	TheUsb.Stop();
+
+	_printf(_L("shutdown complete.\nWaiting for write to terminate."));
+	if ( status == KErrNone )
+		{
+		// The Write already completed. This part of the test didn't work
+		// (i.e. it didn't actually test 'shutting down the USB Manager
+		// causes Write completion'), but there's not much we can do about it.
+		}
+	else
+		{
+		// If the Write is still outstanding at this point, it should
+		// eventually complete with access denied.
+		User::WaitForRequest(status);
+		if (status != KErrAccessDenied)
+			{
+			LEAVE(status.Int());
+			}
+		}
+
+	_printf(_L("Write complete.\nRestarting USB Manager\n"));
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void BufferOverrun_TestL()
+/**
+ * Test updated from that in the ACM unit test specification to
+ * read/write messages bigger than the receive and transmit buffers.
+ * Changed as previous test was no longer valid.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+
+	_printf(_L("\n--------------------------------\n"));
+	_printf(_L("This tests read/writes which are\n"));
+	_printf(_L("bigger than the buffer length.\n"));
+	_printf(_L("----------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+
+	_printf(_L("Reading data.\nBuffer length: %d"), MAX_HEAP_BUFFER_SIZE);
+
+	port.SetReceiveBufferLength(128);
+
+	port.Read(status, readBigBuf);
+
+	User::WaitForRequest(status);
+
+	if (status != KErrNone)
+		{
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("done.\nWriting data\nBuffer length: %d"), MAX_HEAP_BUFFER_SIZE);
+	FillBuffer(readBigBuf);
+
+	port.SetReceiveBufferLength(128);
+
+	port.Write(status, readBigBuf);
+	User::WaitForRequest(status);
+
+	 if (status != KErrNone)
+		 {
+		  LEAVE(status.Int());
+		 }
+
+	_printf(_L(" done.\nTest complete\n"));
+	_printf(_L("[ press any key ]"));
+	_getch();
+
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void Break_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+
+	_printf(_L("\n--------------------------------\n"));
+	_printf(_L("This tests break and break cancel.\n"));
+	_printf(_L("----------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	// Check that NotifyBreak is not completed at any point (should only be
+	// completed by host-driven breaks).
+	TRequestStatus notifyBreakStat;
+	port.NotifyBreak(notifyBreakStat);
+
+	_printf(_L("Breaking\n"));
+	port.Break(status, 10);
+
+	User::WaitForRequest(status);
+
+	if (status != KErrNone)
+	{
+		LEAVE(status.Int());
+	}
+
+	_printf(_L("Press any key to cancel a break.\n"));
+	_getch();
+
+	_printf(_L("Cancelling the break.\n"));
+	port.Break(status, 1000000);
+	port.BreakCancel();
+	User::WaitForRequest(status);
+	if (status != KErrCancel)
+	{
+		LEAVE(status.Int());
+	}
+
+	User::After(1000000);
+	if ( notifyBreakStat != KRequestPending )
+		{
+		LEAVE(notifyBreakStat.Int());
+		}
+	port.NotifyBreakCancel();
+	User::WaitForRequest(notifyBreakStat);
+	if ( notifyBreakStat != KErrCancel )
+		{
+		LEAVE(notifyBreakStat.Int());
+		}
+
+	_printf(_L("\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+
+void SignalChange_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status, statusTimer;
+	RComm port;
+
+	_printf(_L("\n---------------------------------------\n"));
+	_printf(_L("This tests signal change notifications.\n"));
+	_printf(_L("---------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	TUint signals = 0;
+	signals |= KSignalDTR;
+
+	port.NotifySignalChange(status, signals);
+	User::WaitForRequest(status);
+
+	if (status != KErrNone)
+		{
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("Notified\n"));
+
+	port.NotifySignalChange(status, signals);
+
+	// Wait
+	timer.After(statusTimer, 10);
+	User::WaitForRequest(statusTimer);
+
+	_printf(_L("Cancelling request for signal notifications\n"));
+
+	port.NotifySignalChangeCancel();
+	User::WaitForRequest(status);
+
+	if (status != KErrCancel)
+		{
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("\nRequest cancelled.\n Test complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void FlowControl_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status, statusTimer;
+	RComm port;
+
+	_printf(_L("\n-------------------------------------------\n"));
+	_printf(_L("This tests flow control change notifications.\n"));
+	_printf(_L("---------------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	TFlowControl signals;
+	port.NotifyFlowControlChange(status, signals);
+	User::WaitForRequest(status);
+
+	if (status != KErrNotSupported)
+		{
+		LEAVE(status.Int());
+		}
+
+	port.NotifyFlowControlChange(status, signals);
+
+	// Wait
+	timer.After(statusTimer, 10);
+	User::WaitForRequest(statusTimer);
+
+	port.NotifyFlowControlChangeCancel();
+	User::WaitForRequest(status);
+	if (status != KErrNotSupported)
+		{
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void ConfigChange_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status, statusTimer;
+	RComm port;
+
+	_printf(_L("\n-------------------------------------\n"));
+	_printf(_L("This tests config change notifications.\n"));
+	_printf(_L("---------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	TBuf8<64> signals;
+	port.NotifyConfigChange(status, signals);
+	User::WaitForRequest(status);
+
+	if (status != KErrNone)
+		{
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("Notified, waiting for a while before the next test\n"));
+
+	// Wait
+	timer.After(statusTimer, 10);
+	User::WaitForRequest(statusTimer);
+
+	_printf(_L("Cancelling request for config change notifications\n"));
+
+	port.NotifyConfigChange(status, signals);
+	_printf(_L("Cancelling request for config change notifications\n"));
+	port.NotifyConfigChangeCancel();
+	User::WaitForRequest(status);
+
+	if (status != KErrCancel)
+		{
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("\nRequest cancelled.\n Test complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+
+
+void SecondClient_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ * Updated to use a second RCommServ and to read/read in series.
+ * Tests that two clients can read/write on a single serial comms server.
+ * Note that it is invalid to have 2 reads/writes outstanding on a
+ * serial comms server. It would return a KErrInUse.
+ */
+{
+	RCommServ TheCommServ2;
+	RComm port1, port2;
+	TRequestStatus status1, status2;
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf1;
+	TBuf8<MAX_BUFFER_SIZE> readBuf2;
+
+	_printf(_L("\n---------------------------------------\n"));
+	_printf(_L("This tests that we can have a second\n"));
+	_printf(_L("client with non-exclusive access.\n"));
+	_printf(_L("---------------------------------------\n\n"));
+
+	// TheCommServ is already connected in mainL
+	_printf(_L("Connected to C32\n"));
+	LEAVEIFERROR(TheCommServ2.Connect());
+	CleanupClosePushL(TheCommServ2);
+	_printf(_L("Connected to second C32\n"));
+
+	LEAVEIFERROR(port1.Open(TheCommServ, KUsbPortName, ECommShared, ECommRoleDCE));
+	CleanupClosePushL(port1);
+	LEAVEIFERROR(port2.Open(TheCommServ2, KUsbPortName, ECommShared, ECommRoleDCE));
+	CleanupClosePushL(port2);
+
+	port1.SetConfig(TheConfigBuf);
+	port1.SetReceiveBufferLength(256);
+	port2.SetConfig(TheConfigBuf);
+	port2.SetReceiveBufferLength(256);
+
+	_printf(_L("Read()-ing data\n"));
+	port1.Read(status1, readBuf1);
+	_printf(_L("First data read\n"));
+
+	User::WaitForAnyRequest();
+	if ( status1 != KErrNone )
+		{
+		LEAVE(status1.Int());
+		}
+	_printf(_L("status of first read: %d\n"), status1.Int());
+
+	port2.Read(status2, readBuf2);
+	_printf(_L("Second data read\n"));
+
+	User::WaitForAnyRequest();
+	if ( status2 != KErrNone )
+		{
+		LEAVE(status2.Int());
+		}
+	_printf(_L("status of second read: %d\n"), status2.Int());
+
+	_printf(_L("Reading complete\n"), status1.Int());
+
+	TBuf8<256> readBuf;
+
+	_printf(_L("Write()-ing data\n"));
+	FillBuffer(readBuf);
+
+	// Test Writes
+	port1.Write(status1, readBuf, 256);
+	User::WaitForAnyRequest();
+	if ( status1 != KErrNone )
+		{
+		LEAVE(status1.Int());
+		}
+	_printf(_L("status of first write : %d\n"), status1.Int());
+
+	port2.Write(status2, readBuf, 256);
+	User::WaitForAnyRequest();
+	if ( status2 != KErrNone )
+		{
+		LEAVE(status2.Int());
+		}
+	_printf(_L("status of second write : %d\n"), status1.Int(), status2.Int());
+
+	_printf(_L("\nTest complete\n"));
+	_printf(_L("[ press any key ]"));
+	_getch();
+
+	CleanupStack::PopAndDestroy(); // port
+	CleanupStack::PopAndDestroy(); // the other port
+	CleanupStack::PopAndDestroy(); // TheCommServ2 
+}
+
+
+// ******************************************************************
+// The following are placholders for the ACMRq tests.
+// These tests need no support on the platform end, as yet.
+// The functions are left here incase someday support is needed.
+// ******************************************************************
+
+void ACMRq_EncapCommand_TestL()
+{
+	 // Not needed to support this here
+}
+
+void ACMRq_Break_TestL()
+{
+	 // TODO: can we check for break status here ?
+}
+
+void ACMRq_SetFeature_TestL()
+{
+	 // TODO: Test doesn't make sense.
+}
+
+void ACMRq_ClearFeature_TestL()
+{
+	 // TODO: Test doesn't make sense.
+}
+
+void ACMRq_SetCoding_TestL()
+{
+	 // TODO: Can we check the line codeing here ?
+}
+
+void ACMRq_CtrlState_TestL()
+{
+	 // TODO: Test doesn't make sense.
+}
+
+void ACMRq_EncapResp_TestL()
+{
+	 // Not needed to support this here.
+}
+
+void ACMRq_CommsFeature_TestL()
+{
+	 // Not needed to support this here.
+}
+
+void ACMRq_GetCoding_TestL()
+{
+	 // Not needed to support this here.
+}
+
+
+void ACMNtf_SendState_TestL()
+{
+	 // TODO: SendSerialState() ???
+}
+
+void ACMNtf_Status_TestL()
+{
+	 // TODO: SendNetworkConnection() ???
+}
+
+void ACMNtf_RespAvail_TestL()
+{
+	 // Test not supported.
+}
+
+void AcmLoopback_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+	{
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm port;
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This test listens for data on the ACM\n"));
+	_printf(_L("port and echoes anything it receives\n"));
+	_printf(_L("back to the PC. Press any key to quit.\n"));
+	_printf(_L("----------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Echoing received data\n"));
+
+	TBuf8<1024> readBuf;
+
+	console->Read(consoleStatus);
+
+	FOREVER
+		{
+		port.ReadOneOrMore(status, readBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.ReadCancel();
+			break;
+			}
+
+		port.Write(status, readBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.WriteCancel();
+			break;
+			}
+
+		_printf(_L("."));
+		}
+
+	_printf(_L("\nTest complete\n"));
+
+	CleanupStack::PopAndDestroy(); // port
+	}
+
+void SetHandshakingL()
+/**
+ * This function allows the user to select a new handshaking mode.
+ */
+	{
+	RComm port;
+
+	TCommCaps capsBuf;
+	TCommCapsV01& caps = capsBuf();
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.Caps(capsBuf);
+	_printf(_L("\nPort handshaking capabilities: 0x%X\n"), caps.iHandshake);
+	_printf(_L("Current handshaking options: 0x%X\n"), TheConfig.iHandshake);
+
+	_printf(_L("\nHandshaking options:\n"));
+	_printf(_L("1. No handshaking\n"));
+	_printf(_L("2. Toggle Xon/Xoff\n"));
+	_printf(_L("3. Toggle obey CTS\n"));
+	_printf(_L("4. Toggle obey DSR / free RTS\n"));
+	_printf(_L("5. Toggle write buffered complete\n"));
+
+	TInt key = (TInt) _getch();
+
+	switch (key)
+		{
+	case '1':
+		TheConfig.iHandshake = 0;
+		break;
+	case '2':
+		TheConfig.iHandshake ^= KConfigObeyXoff;
+		TheConfig.iHandshake ^= KConfigSendXoff;
+		break;
+	case '3':
+		TheConfig.iHandshake ^= KConfigObeyCTS;
+		break;
+	case '4':
+		TheConfig.iHandshake ^= KConfigObeyDSR;
+		TheConfig.iHandshake ^= KConfigFreeRTS;
+		break;
+	case '5':
+		TheConfig.iHandshake ^= KConfigWriteBufferedComplete;
+		break;
+	default:
+		break;
+		}
+
+	LEAVEIFERROR(port.SetConfig(TheConfigBuf));
+
+	_printf(_L("Handshaking options now: 0x%X\n"), TheConfig.iHandshake);
+
+	CleanupStack::PopAndDestroy();
+	}
+
+void RestartUsbL()
+/**
+ * This function stops and restarts usb manager.
+ */
+	{
+	TheUsb.Stop();
+
+	TRequestStatus status;
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("Restarted USB.\n"));
+	}
+
+void mainL()
+/**
+ * This function controls test execution as directed by the user.
+ */
+	{
+		 char ch;
+		 TInt menu = 1;
+
+	TInt ret = User::LoadLogicalDevice(KUsbLddName);
+	if ((ret != KErrNone) && (ret != KErrAlreadyExists))
+		LEAVE(ret);
+
+	_printf(_L("Loaded USB LDD\n"));
+
+	ret = StartC32();
+	if ((ret != KErrNone) && (ret != KErrAlreadyExists))
+		LEAVE(ret);
+
+	_printf(_L("Started C32\n"));
+
+	LEAVEIFERROR(TheUsb.Connect());
+
+	_printf(_L("Connected to USB Manager\n"));
+
+	TRequestStatus status;
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("Started USB\n"));
+
+
+
+	LEAVEIFERROR(TheCommServ.Connect());
+
+	_printf(_L("Connected to C32\n"));
+
+	RComm port;
+
+	// The port's configuration seems to be junk at the beginning, so we set it to known values.
+
+	TheConfig.iRate = EBps115200;
+	TheConfig.iDataBits = EData8;
+	TheConfig.iStopBits = EStop1;
+	TheConfig.iParity = EParityNone;
+	TheConfig.iHandshake = 0;
+	TheConfig.iTerminatorCount = 0;
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+	_printf(_L("----------------------------------------\n"));
+	_printf(_L("Initial port config:\n"));
+	_printf(_L("  Rate: %d bps\n"), TheConfig.iRate);
+	_printf(_L("  Data bits: %d. Parity type: %d. Stop bits: %d\n"),
+		TheConfig.iStopBits, TheConfig.iParity, TheConfig.iStopBits);
+	_printf(_L("  Handshaking options: 0x%X\n"), TheConfig.iHandshake);
+	_printf(_L("----------------------------------------\n\n"));
+
+	CleanupStack::PopAndDestroy(); // port
+
+	TBool noExit = ETrue;
+	while (noExit)
+		{
+			 switch(menu)
+			 {
+			 case 1:
+				  _printf(_L("\nAvailable tests:\n\n"));
+				  _printf(_L("1. ReadOneOrMore loopback test\n"));
+				  _printf(_L("2. Read loopback test\n"));
+				  _printf(_L("3. Set handshaking\n"));
+				  _printf(_L("4. Restart USB\n"));
+				  _printf(_L("5. Test specification menu\n"));
+				  _printf(_L("6. Read with terminators loopback test\n"));
+  				  _printf(_L("7. Read loopback from ACM0->ACM1 test\n"));
+  				  _printf(_L("8. NotifyDataAvailable test\n"));
+				  _printf(_L("\nSelection (x to exit): "));
+
+				  ch = (char) _getch();
+				  _printf(_L("\n"));
+				  switch (ch)
+				  {
+				  case '1': LoopbackTestL(); break;
+				  case '2': ReadLoopbackTestL(); break;
+				  case '3': SetHandshakingL(); break;
+				  case '4': RestartUsbL(); break;
+				  case '5': menu = 2; break;
+				  case '6': ReadWithTerminatorsLoopbackTestL(); break;
+				  case '7': ReadLoopbackFromPortAToPortBTestL(); break;
+				  case '8': NotifyDataAvailableTestL(); break;
+				  case 'x':
+				  case 'X': noExit = EFalse; break;
+				  default:  _printf(_L("\nInvalid key\n")); break;
+				  }
+				  break;
+			 case 2:
+				  _printf(_L("\nAvailable tests:\n\n"));
+				  _printf(_L("1. Data stress, size varies (test 2.1.1)\n"));
+				  _printf(_L("2. Data stress, rate varies (test 2.1.2)\n"));
+				  _printf(_L("3. Timeout (test 2.2)\n"));
+				  _printf(_L("4. Cancel Transfer (test 2.3)\n"));
+				  _printf(_L("5. Interrupt Transfer (test 2.4)\n"));
+				  _printf(_L("6. Shutdown (test 2.5)\n"));
+				  _printf(_L("7. Buffer overrun (test 2.6)\n"));
+				  _printf(_L("8. Break (test 2.7)\n"));
+				  _printf(_L("9. Event notification, signal change (test 2.8.1)\n"));
+				  _printf(_L("a. Event notification, flow control (test 2.8.2)\n"));
+				  _printf(_L("b. Event notification, config change (test 2.8.3)\n"));
+				  _printf(_L("c. Second client (test 2.9)\n"));
+/*				  _printf(_L("d. ACM request, encapsulated command (test 2.10.1)\n"));
+				  _printf(_L("e. ACM request, break (test 2.10.2)\n"));
+				  _printf(_L("f. ACM request, setting feature (test 2.10.3)\n"));
+				  _printf(_L("g. ACM request, clearing feature (test 2.10.4)\n"));
+				  _printf(_L("h. ACM request, setting line coding (test 2.10.5)\n"));
+				  _printf(_L("i. ACM request, control line state (test 2.10.6)\n"));
+				  _printf(_L("j. ACM request, encapsualted response (test 2.10.7)\n"));
+				  _printf(_L("k. ACM request, comms feature (test 2.10.8)\n"));
+				  _printf(_L("l. ACM request, getting line coding (test 2.10.9)\n"));
+				  _printf(_L("m. ACM Notifications, send serial state (test 2.11.1)\n"));
+				  _printf(_L("n. ACM Notifications, network status (test 2.11.2)\n"));
+				  _printf(_L("o. ACM Notifications, response available (test 2.11.3)\n"));
+*/				  _printf(_L("p. Loopback test (test 2.12)\n"));
+				  _printf(_L("q. Main menu\n"));
+
+				  ch = (char) _getch();
+				  _printf(_L("\n"));
+				  switch (ch)
+				  {
+				  case '1': DataStress_SizeVary_TestL();	break;
+				  case '2': DataStress_RateVary_TestL();	break;
+				  case '3': TimeOut_TestL();	break;
+				  case '4': CancelTx_TestL();	break;
+				  case '5': InterruptTx_TestL();	break;
+				  case '6': Shutdown_TestL();	break;
+				  case '7': BufferOverrun_TestL();	break;
+				  case '8': Break_TestL();	break;
+				  case '9': SignalChange_TestL();	break;
+				  case 'A':
+				  case 'a': FlowControl_TestL();	break;
+				  case 'B':
+				  case 'b': ConfigChange_TestL();	break;
+				  case 'C':
+				  case 'c': SecondClient_TestL();	break;
+				  case 'D':
+				  case 'd': ACMRq_EncapCommand_TestL();	break;
+				  case 'E':
+				  case 'e': ACMRq_Break_TestL();	break;
+				  case 'F':
+				  case 'f': ACMRq_SetFeature_TestL();	break;
+				  case 'G':
+				  case 'g': ACMRq_ClearFeature_TestL();	break;
+				  case 'H':
+				  case 'h': ACMRq_SetCoding_TestL();	break;
+				  case 'I':
+				  case 'i': ACMRq_CtrlState_TestL();	break;
+				  case 'J':
+				  case 'j': ACMRq_EncapResp_TestL();	break;
+				  case 'K':
+				  case 'k': ACMRq_CommsFeature_TestL();	break;
+				  case 'L':
+				  case 'l': ACMRq_GetCoding_TestL();	break;
+				  case 'M':
+				  case 'm': ACMNtf_SendState_TestL();	break;
+				  case 'N':
+				  case 'n': ACMNtf_Status_TestL();	break;
+				  case 'O':
+				  case 'o': ACMNtf_RespAvail_TestL();	break;
+				  case 'P':
+				  case 'p': AcmLoopback_TestL(); break;
+				  case 'q':
+				  case 'Q': menu = 1; break;
+				  default:
+					   _printf(_L("\nInvalid key\n"));
+					   break;
+				  }
+				  break;
+			 default:
+				  LEAVE(-1);
+			 }
+		}
+	TheCommServ.Close();
+	TheUsb.Close();
+	}
+
+void consoleMainL()
+/**
+ * Create a console and run mainL().
+ */
+	{
+	console=Console::NewL(_L("T_ACM"),TSize(KConsFullScreen,KConsFullScreen));
+	CleanupStack::PushL(console);
+	mainL();
+	_printf(_L("[ press any key ]"));
+	_getch();
+	CleanupStack::PopAndDestroy();
+	}
+
+GLDEF_C TInt E32Main()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanupStack=CTrapCleanup::New();
+
+	// create the timer for use during some of the tests
+	timer.CreateLocal();
+
+	TRAP_IGNORE(consoleMainL());
+	delete cleanupStack;
+	__UHEAP_MARKEND;
+	return 0;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_cc/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* 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 "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:
+* BLD.INF for t_acm_cc
+* BLD.INF for t_acm_cc
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+t_acm_cc.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_cc/group/t_acm_cc.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+TARGET         t_acm_cc.exe
+TARGETTYPE     EXE
+SOURCEPATH    ../src
+SOURCE         t_acm_cc.cpp
+LIBRARY        euser.lib efsrv.lib c32.lib usbman.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_cc/src/t_acm_cc.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,586 @@
+/*
+* Copyright (c) 1997-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:
+* 
+* Runs tests upon USB Manager's ACM Class Controller.
+* Relies on the fact that the USB Manager is actually configured to start an ACM class controller.
+* Tests are numbered as in v0.2 of the USB Manager Test Specification.
+*
+* t_ACM_cc.cpp
+*
+*/
+
+#include <e32test.h>
+#include <e32twin.h>
+#include <c32comm.h>
+#include <d32comm.h>
+#include <f32file.h>
+#include <hal.h>
+#include <usbman.h>
+
+// A test object for test io
+LOCAL_D RTest test(_L("T_ACM_CC"));
+
+// A pointer to an instance of the USB Manager
+RUsb *usbman;
+
+// An instance of the fileserver
+RFs theFs;
+
+// A timer for waiting around
+RTimer timer;
+
+// Some wait times for use with the timer (in microseconds)
+// May need to tinker with these to get them right
+#define CANCEL_START_REQ_DELAY 2
+#define CANCEL_STOP_REQ_DELAY 2
+
+// A set of states for the startup and shutdown sequence
+enum TestState
+{
+	 EStart = 0,
+	 EFsConnected,
+	 EC32Started,
+	 EUSBManCreated,
+	 EUSBManConnected,
+	 EPrimaryRegistered,
+	 EUSBManStarted
+};
+TestState current_test_state;
+
+/**
+ * Function to run through the common startup of a test.
+ */
+TInt CommonStart()
+{
+	 TInt r;
+
+	test.Printf(_L("CommonStart()\n"));
+
+	 // Loop until the primary client is registered.
+     // Do not proceed to start the USB Manager, as that is test specific.
+	 while(current_test_state != EPrimaryRegistered)
+	 {
+		  switch(current_test_state)
+		  {
+		  case EStart:
+			   // Connect to the fileserver
+			   r = theFs.Connect();
+			   if (r != KErrNone)
+			   {
+					test.Printf(_L("   Failed to connect to the fs. Error = %d\n"), r);
+					return r;
+			   }
+			   test.Printf(_L("   Connected to file server.\n"));
+			   current_test_state = EFsConnected;
+			   break;
+		  case EFsConnected:
+			   // Start C32
+			   r = StartC32();
+			   if (r!=KErrNone && r !=KErrAlreadyExists)
+			   {
+					test.Printf(_L("   Failed to start C32. Error = %d\n"), r);
+					return r;
+			   }
+			   test.Printf(_L("   Started C32.\n"));
+			   current_test_state = EC32Started;
+			   break;
+		  case EC32Started:
+			   // Create an instance of the USB Manager
+			  usbman = new RUsb;
+			   if (!usbman)
+			   {
+					test.Printf(_L("   Failed to instantiate USB Manager.\n"));
+					return KErrGeneral;
+			   }
+			   test.Printf(_L("   Instantiated USB Manager.\n"));
+			   current_test_state = EUSBManCreated;
+			   break;
+		  case EUSBManCreated:
+			   // Connect to the USB Manager
+			   r = usbman->Connect();
+			   if (r != KErrNone)
+			   {
+					test.Printf(_L("   Failed to connect to USB Manager. Error = %d\n"), r);
+					return r;
+			   }
+			   test.Printf(_L("   Connected to USB Manager.\n"));
+			   current_test_state = EUSBManConnected;
+			   break;
+		  case EUSBManConnected:
+			   // Register as primary client.
+			   // *** Obsolete ***
+			   /*
+			   r = usbman->RegisterAsPrimarySession();
+			   if (r != KErrNone)
+			   {
+					test.Printf(_L("    Failed to register as primary client. Error = %d\n"), r);
+					return r;
+			   }
+			   test.Printf(_L("    Registered as primary client.\n"));
+			   */
+			   current_test_state = EPrimaryRegistered;
+			   break;
+		  default:
+			   break;
+		  }
+	 }
+
+	 test.Printf(_L("CommonStart() done\n"));
+
+	 return KErrNone;
+}
+
+/**
+ * Function to run through the common shutdown of a test.
+ * Shuts down only what is needed, based upon the value of current_test_state,
+ * so it can be used to clean up after aborted starts.
+ */
+TInt CommonCleanup()
+{
+	 TRequestStatus status;
+
+	 while(current_test_state != EStart)
+	 {
+		  switch(current_test_state)
+		  {
+		  case EUSBManStarted:
+			   // Stop the USB Manager
+			   usbman->Stop(status);
+			   User::WaitForRequest(status);
+			   current_test_state = EPrimaryRegistered;
+			   break;
+		  case EPrimaryRegistered:
+			   // *** Obsolete ***
+			   // usbman->DeregisterAsPrimarySession();
+			   current_test_state = EUSBManConnected;
+			   break;
+		  case EUSBManConnected:
+			   // Don't need to disconnect.
+			   current_test_state = EUSBManCreated;
+			   break;
+		  case EUSBManCreated:
+			   delete usbman;
+			   current_test_state = EC32Started;
+			   break;
+		  case EC32Started:
+			   // Don't need to stop C32
+			   current_test_state = EFsConnected;
+			   break;
+		  case EFsConnected:
+			   theFs.Close();
+			   current_test_state = EStart;
+			   break;
+		  default:
+			   break;
+		  }
+	 }
+	 return KErrNone;
+}
+
+/**
+ * Checks that the USB service state is as expected.
+ */
+TInt CheckServiceState(TUsbServiceState state)
+{
+	TUsbServiceState aState;
+	TInt r = usbman->GetServiceState(aState);
+	if (r != KErrNone)
+		{
+		test.Printf(_L("Failed to get service state. Error = %d\n"), r);
+		return r;
+		}
+	if (aState != state)
+		{
+		test.Printf(_L("Service state check failed. State expected: %d. State is: %d (type TUsbServiceState).\n"), state, aState);
+		return KErrGeneral;
+		}
+	test.Printf(_L("Service state ok\n"));
+
+	return KErrNone;
+}
+
+/**
+ * Executes test B1 (as detailed in the USB Manager Test Specification).
+ */
+static TInt RunTest_B1()
+	{
+	TInt r;
+
+	test.Next(_L("Test B1.\n"));
+
+	// Perform common startup
+	current_test_state = EStart;
+	r = CommonStart();
+	if (r != KErrNone)
+		 return r;
+
+	// Start the USB Manager
+	TRequestStatus status;
+	test.Printf(_L("Starting.\n"));
+	usbman->Start(status);
+	test.Printf(_L("Waiting for request.\n"));
+	User::WaitForRequest(status);
+
+	test.Printf(_L("... done. Status: %d.\n"), status.Int());
+
+	current_test_state = EUSBManStarted;
+	return KErrNone;
+	}
+
+/**
+ * Executes test B2 (as detailed in the USB Manager Test Specification).
+ * No longer a relevant test.
+ */
+/*static TInt RunTest_B2()
+	{
+	TInt r;
+
+	test.Next(_L("Test B2.\n"));
+
+	// Perform common startup
+	current_test_state = EStart;
+	r = CommonStart();
+	if (r != KErrNone)
+		 return r;
+
+	// Start the USB Manager
+	TRequestStatus status;
+	test.Printf(_L("Starting.\n"));
+	usbman->Start(status);
+
+	// Wait for specific time (has to be less than the time to process a start request)
+	timer.After(status, CANCEL_START_REQ_DELAY);
+	User::WaitForRequest(status);
+
+	// Cancel the start request
+	test.Printf(_L("Cancelling.\n"));
+	usbman->StartCancel();
+
+	// Check service status
+	test.Printf(_L("Checking service status.\n"));
+	r = CheckServiceState(EUsbServiceIdle);
+	if ( r != KErrNone)
+		 return r;
+
+	return KErrNone;
+	}
+*/
+/**
+ * Executes test B3 (as detailed in the USB Manager Test Specification).
+ */
+static TInt RunTest_B3()
+	{
+	TInt r;
+
+	test.Next(_L("Test B3.\n"));
+
+	// Perform common startup
+	current_test_state = EStart;
+	r = CommonStart();
+	if (r != KErrNone)
+		 return r;
+
+	// Start the USB Manager
+	TRequestStatus status;
+	usbman->Start(status);
+	User::WaitForRequest(status);
+	test.Printf(_L("Start completed with status %d\n"), status.Int());
+	current_test_state = EUSBManStarted;
+
+	// Stop the USB Manager
+	usbman->Stop(status);
+	User::WaitForRequest(status);
+	test.Printf(_L("Stop completed with status %d\n"), status.Int());
+	current_test_state = EPrimaryRegistered;
+
+	// Check service status
+	r = CheckServiceState(EUsbServiceIdle);
+	if ( r != KErrNone)
+		 return r;
+
+	return KErrNone;
+	}
+
+/**
+ * Executes test B4 (as detailed in the USB Manager Test Specification).
+ * No longer a relevant test.
+ */
+/*static TInt RunTest_B4()
+	{
+	TInt r;
+
+	test.Next(_L("Test B4.\n"));
+
+	// Perform common startup
+	current_test_state = EStart;
+	r = CommonStart();
+	if (r != KErrNone)
+		 return r;
+
+	// Start the USB Manager
+	TRequestStatus status, timerStatus;
+	usbman->Start(status);
+	User::WaitForRequest(status);
+	test.Printf(_L("Start completed with status %d\n"), status.Int());
+	current_test_state = EUSBManStarted;
+
+	// Stop the USB Manager
+	usbman->Stop(status);
+
+	// Wait for specific time (has to be less than the time to process a start request)
+	timer.After(timerStatus, CANCEL_STOP_REQ_DELAY);
+	User::WaitForRequest(status, timerStatus);
+
+	// Cancel the stop request
+	usbman->StopCancel();
+
+	// Check service status
+	r = CheckServiceState(EUsbServiceStarted);
+	if ( r != KErrNone)
+		 return r;
+
+	return KErrNone;
+	}
+*/
+/**
+ * Executes test B5 (as detailed in the USB Manager Test Specification).
+ */
+static TInt RunTest_B5()
+	{
+	TInt r, i;
+	TRequestStatus status, timerStatus;
+
+	test.Next(_L("Test B5.\n"));
+
+	// Perform common startup
+	current_test_state = EStart;
+	r = CommonStart();
+	if (r != KErrNone)
+		 return r;
+
+	// Loop to stress-test the start-stop process
+	test.Printf(_L("Looping for start-stop ...\n"));
+	for (i=0; i<10; i++)
+	{
+		 test.Printf(_L("%d "), i);
+
+		 // Start the USB Manager
+		 usbman->Start(status);
+		 User::WaitForRequest(status);
+		 current_test_state = EUSBManStarted;
+
+		 // Stop the USB Manager
+		 usbman->Stop(status);
+		 User::WaitForRequest(status);
+		 current_test_state = EPrimaryRegistered;
+	}
+
+	test.Printf(_L("\nFinished looping.\n"));
+	
+	// Check service status
+	r = CheckServiceState(EUsbServiceIdle);
+	if ( r != KErrNone)
+		 return r;
+
+	test.Printf(_L("Serve state ok.\n"));
+
+	// Loop to stress-test the start cancel process
+	test.Printf(_L("Looping for start-cancel ...\n"));
+	for (i=0; i<10; i++)
+	{
+		 test.Printf(_L("%d "), i);
+
+		 // Start the USB Manager
+		 usbman->Start(status);
+
+		 // Wait for specific time (has to be less than the time to process a start request)
+		 timer.After(timerStatus, CANCEL_START_REQ_DELAY);
+		 User::WaitForRequest(timerStatus);
+
+		 // Cancel the start request
+		 usbman->StartCancel();
+	}
+
+	test.Printf(_L("\nFinished looping.\n"));
+
+	// Check service status
+	r = CheckServiceState(EUsbServiceIdle);
+	if ( r != KErrNone)
+		 return r;
+
+	// Start the USB Manager
+	test.Printf(_L("Restarting.\n"));
+	usbman->Start(status);
+	test.Printf(_L("Waiting for restart.\n"));
+	User::WaitForRequest(status);
+	test.Printf(_L("Start completed with status %d\n"), status.Int());
+	current_test_state = EUSBManStarted;
+
+	// Loop to stress-test the stop cancel process
+	test.Printf(_L("Looping for stop-cancel ...\n"));
+	for (i=0; i<10; i++)
+	{
+		 test.Printf(_L("%d "), i);
+
+		 // Stop the USB Manager
+		 usbman->Stop(status);
+
+		 // Wait for specific time (has to be less than the time to process a start request)
+		 timer.After(timerStatus, CANCEL_STOP_REQ_DELAY);
+		 User::WaitForRequest(timerStatus);
+
+		 // Cancel the start request
+		 usbman->StopCancel();
+	}
+
+	test.Printf(_L("\nFinished looping.\n"));
+
+	// Check service status
+	r = CheckServiceState(EUsbServiceStarted);
+	if ( r != KErrNone)
+		 return r;
+
+	return KErrNone;
+	}
+
+/**
+ * Executes test B6 (as detailed in the USB Manager Test Specification).
+ */
+static TInt RunTest_B6()
+	{
+	TInt r;
+
+	test.Next(_L("Test B6.\n"));
+
+	// Perform common startup
+	current_test_state = EStart;
+	r = CommonStart();
+	if (r != KErrNone)
+		 return r;
+
+	// Start the USB Manager
+	TRequestStatus status;
+	usbman->Start(status);
+	User::WaitForRequest(status);
+	test.Printf(_L("Start completed with status %d\n"), status.Int());
+	current_test_state = EUSBManStarted;
+
+	// TODO: Force an ACM failure
+
+	// Check service status
+	r = CheckServiceState(EUsbServiceIdle);
+	if ( r != KErrNone)
+		 return r;
+	
+	return KErrNone;
+	}
+
+/**
+ * Main test function.
+ *
+ * Runs all the tests in order.
+ */
+void mainL()
+    {
+	TInt err;
+
+	// Run all the tests
+
+	err=RunTest_B1();
+	if (err != KErrNone)
+	{
+		test.Printf(_L("Test B1 failed, code: %d\n\n"), err);
+	}
+	else
+		test.Printf(_L("Test B1 passed.\n\n"));
+	CommonCleanup();
+
+/*	Depreciated test.
+	err=RunTest_B2();
+	if (err != KErrNone)
+	{
+		test.Printf(_L("Test B2 failed, code: %d\n\n"), err);
+	}
+	else
+		test.Printf(_L("Test B2 passed.\n\n"));
+	CommonCleanup();
+*/
+	err=RunTest_B3();
+	if (err != KErrNone)
+	{
+		test.Printf(_L("Test B3 failed, code: %d\n\n"), err);
+	}
+	else
+		test.Printf(_L("Test B3 passed.\n\n"));
+	CommonCleanup();
+
+/*	Depreciated test.
+	err=RunTest_B4();
+	if (err != KErrNone)
+	{
+		test.Printf(_L("Test B4 failed, code: %d\n\n"), err);
+	}
+	else
+		test.Printf(_L("Test B4 passed.\n\n"));
+	CommonCleanup();
+*/
+	err=RunTest_B5();
+	if (err != KErrNone)
+	{
+		test.Printf(_L("Test B5 failed, code: %d\n\n"), err);
+	}
+	else
+		test.Printf(_L("Test B5 passed.\n\n"));
+	CommonCleanup();
+
+	err=RunTest_B6();
+	if (err != KErrNone)
+	{
+		test.Printf(_L("Test B6 failed, code: %d\n\n"), err);
+	}
+	else
+		test.Printf(_L("Test B6 passed.\n\n"));
+	CommonCleanup();
+
+	// Tests finished
+    }
+
+/**
+ * Entry point.
+ *
+ * Creates a cleanup stack and a timer then calls consoleMainL.
+ */
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanupStack=CTrapCleanup::New();
+
+	test.Title();
+	test.Start(_L("Starting E32Main"));
+
+	// create the timer for use during some of the tests
+	timer.CreateLocal();
+
+	TRAP_IGNORE(mainL());
+
+	test.Printf(_L("\n[Finished. Press any key.]\n"));
+	test.Getch();
+	test.End();
+	test.Close();
+
+	delete cleanupStack;
+	__UHEAP_MARKEND;
+	return 0;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_pub_sub/data/numberofacmfunctions.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+; numberofacmfunctions.ini
+; Copyright (c) 2007 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:
+;
+;
+
+[ACM_CONF]
+NumberOfAcmFunctions= 3
+
+[ACM 1]
+ProtocolNum= 1     //0x01 - code taken from USBCDC 1.1 Table 17- Hayes compatible modem
+
+
+[ACM 2]
+ProtocolNum= 255  //0xFF - Vendor-specific
+
+
+[ACM 3]
+ProtocolNum= 127  //0x7F - Random code
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_pub_sub/group/Bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+PRJ_TESTEXPORTS
+t_acm_pub_sub.iby             		/epoc32/rom/include/t_acm_pub_sub.iby
+
+../data/NumberofAcmFunctions.ini 	z:/private/101fe1db/NumberOfAcmFunctions.ini
+
+
+PRJ_TESTMMPFILES
+
+t_acm_pub_sub.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_pub_sub/group/t_acm_pub_sub.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 2007-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:
+* BLD.INF
+*
+*/
+
+#ifndef __ACM_PUB_SUB_IBY__
+#define __ACM_PUB_SUB_IBY__
+
+file=ABI_DIR\BUILD_DIR\t_acm_pub_sub.exe	                     		Sys\Bin\t_acm_pub_sub.exe
+
+data=EPOCROOT##epoc32\data\z\private\101fe1db\NumberOfAcmFunctions.ini		private\101fe1db\NumberOfAcmFunctions.ini
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_pub_sub/group/t_acm_pub_sub.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2007-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:
+* using relative paths for sourcepath and user includes
+*
+*/
+
+TARGET        t_acm_pub_sub.exe
+CAPABILITY 	NetworkControl LocalServices NetworkServices CommDD ProtServ ReadDeviceData WriteDeviceData
+TARGETTYPE    exe
+UID           0
+
+SOURCEPATH    ..\src
+SOURCE        t_acm_pub_sub.cpp
+
+USERINCLUDE   ..\inc
+SYSTEMINCLUDE \Epoc32\include
+SYSTEMINCLUDE \Epoc32\include\usb
+SYSTEMINCLUDE \Epoc32\include\test
+
+LIBRARY       EUSER.LIB EFSRV.LIB c32.lib usbman.lib acmserver.lib
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_pub_sub/inc/CommonFramework.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2000-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:
+*
+*/
+
+
+#ifndef __CommonFramework_H
+#define __CommonFramework_H
+
+#include <e32base.h>
+#include <e32cons.h>
+
+_LIT(KTxtEPOC32EX,"EXAMPLES");
+_LIT(KTxtExampleCode,"Symbian OS Example Code");
+_LIT(KFormatFailed,"failed: leave code=%d");
+_LIT(KTxtOK,"ok");
+_LIT(KTxtPressAnyKey," [press any key]");
+
+// public
+LOCAL_D CConsoleBase* console; // write all your messages to this
+LOCAL_C void doExampleL(CConsoleBase*); // code this function for the real example
+
+// private
+LOCAL_C void callExampleL(); // initialize with cleanup stack, then do example
+
+GLDEF_C TInt E32Main() // main function called by E32
+    {
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
+	TRAPD(error,callExampleL()); // more initialization, then do example
+	__ASSERT_ALWAYS(!error,User::Panic(KTxtEPOC32EX,error));
+	delete cleanup; // destroy clean-up stack
+	__UHEAP_MARKEND;
+	return 0; // and return
+    }
+
+LOCAL_C void callExampleL() // initialize and call example code under cleanup stack
+    {
+	console=Console::NewL(KTxtExampleCode,TSize(KConsFullScreen,KConsFullScreen));
+	CleanupStack::PushL(console);
+	
+	TRAPD(error,doExampleL(console)); // perform example function
+		
+	if (error)
+		console->Printf(KFormatFailed, error);
+	else
+		console->Printf(KTxtOK);
+	
+	console->Printf(KTxtPressAnyKey);
+	console->Getch(); // get and ignore character
+	CleanupStack::PopAndDestroy(); // close console
+    }
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_pub_sub/src/t_acm_pub_sub.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,359 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include <hal.h>
+#include <usbman.h>
+#include <e32test.h>
+#include <e32twin.h>
+#include <e32def.h>
+#include <c32comm.h>
+#include <d32comm.h>
+#include <f32file.h>
+#include <e32cons.h>
+#include <acmserver.h>
+#include <AcmInterface.h>
+#include <UsbClassUids.h>
+#include <CUsbClassControllerPlugIn.h>
+#include "CommonFramework.h"
+#include <usb/acmconfig.h>
+
+#include <e32std.h>
+#include <test/testexecutelog.h>
+#include <test/testexecutelogger.h>
+
+#ifndef __WINS__
+_LIT(KCommDriverName, "EUSBC");
+#endif
+
+RFs gFs;
+RUsb usb;
+CConsoleBase* tCon;
+TPtrC16 KTestResult;
+
+/**
+ * Quick cleanup before exit
+ */
+static void Cleanup()
+	{
+	if(usb.Handle())
+		{
+		usb.Close();
+		}
+	gFs.Close();
+	tCon = NULL;
+	}
+
+/**
+ * Handy function for outputting the buffers length values whilst debugging.
+ * @param CConsoleBase* a console for output of information and getting user input
+ * @param RBuf& the buffer you want to check
+ */
+void PrintBuf(CConsoleBase* aCon, RBuf8& aBuf)
+	{
+	aCon->Printf(_L("aBuf.Length(): %d\t aBuf.MaxLength() %d.\n"), aBuf.Length(), aBuf.MaxLength());
+	aCon->Getch();			
+	}
+
+/**
+ * LoadDrivers
+ * Attempts to load drivers for Usb. This only works on the device, the emulator will fail to load
+ * correct drivers, so this is skipped for WINS builds
+ */
+static TInt LoadDrivers(CConsoleBase*  aCon)
+	{
+	TInt err = KErrNone;
+	aCon->Printf(_L("loading LDD\n")); //leave this line outside of preprocessor if to avoid compiler warning.
+#ifndef __WINS__
+	err = User::LoadLogicalDevice(KCommDriverName);
+	if(err != KErrNone && err != KErrAlreadyExists)
+		return err;
+#endif
+	return err == KErrAlreadyExists ? KErrNone : err;
+	}
+
+/**
+ * Attached a supplied RProperty to the AcmConfig published data
+ * @param RProperty& aProp the RProperty to be attached to the published data
+ * @return KErrNone on success or standard Symbian error code on failure
+ */
+void AttachPropertyL(RProperty& aProp)
+	{
+	User::LeaveIfError(aProp.Attach(KUidSystemCategory, KAcmKey));
+	}
+
+/**
+ * Returns the number of acm functions currently available
+ * @param RProperty aProp, a connected RProperty connected to the P&S data
+ * @return TInt the number of functions currently available or a standard
+ * Symbian error code.
+ */
+TInt GetCount(RProperty aProp)
+	{
+	TPckgBuf<TPublishedAcmConfigs> configBuf;
+	TInt ret = aProp.Get(configBuf);
+	if(ret == KErrNone)
+		 {
+		 ret = configBuf().iAcmCount;
+		 }	 		 		 		 		 		 		 
+	return ret;
+	}
+
+/**
+ * Checks the function count against the expected value.
+ * @param RProperty aProp, a connected RProperty connected to the P&S data
+ * @param TInt8 aExpected the number of functions to test against.
+ * @return KErrNone if count is expected. KErrGeneral if count differs
+ * from the expected value. Otherwise standard Symbian error code  
+ */
+TInt CheckFunctionCount(RProperty aProp, TInt8 aExpected)
+	{
+	TInt ret = GetCount(aProp);
+  	if(aExpected >=0) //check the expected count
+  		{
+  		if(ret != aExpected)
+  			{
+  			KTestResult.Set(_L("Check function count failed. "));
+  			ret = KErrGeneral;
+  			}
+  		else
+  			{
+  			ret = KErrNone;	
+  			}
+  		}
+  	else //we are checking for an error code 
+  		{
+  		if(ret == aExpected)
+  			ret = KErrNone; //else return the error code
+  		}
+	return ret;
+	}
+	
+	
+//DisplayProperties is not strictly required by this test case but is 
+//left in as it shows how to access all the AcmConfig properties in one
+//convenient place.
+/**
+ * Displays a list of available acm fucntions with protocol numbers
+ * @param RProperty aProp, a connected RProperty connected to the P&S data
+ * @param CConsoleBase* aCon, console where output will be directed.
+ */
+void DisplayProperties(RProperty aProp, CConsoleBase* aCon)
+	{
+	TInt err;
+	TPckgBuf<TPublishedAcmConfigs> configBuf;
+	err = aProp.Get(configBuf);
+	if(err != KErrNone)
+		{
+		aCon->Printf(_L("ERROR: Failed to get the published data as a buffer, code: %d\n\n"), err);
+		}
+	//purely to prove it can be done, create a TPublishedAcmConfig from the configBuf and use
+	//it to display	the properties of the functions
+	TPublishedAcmConfigs configs = configBuf();
+	
+	
+	TInt version = configs.iAcmConfigVersion;
+	TInt funcCount = configs.iAcmCount;
+	
+	aCon->Printf(_L("AcmConfig Version: %d\n"), version);
+	for(int i=0;i<funcCount;i++)	
+		{
+		aCon->Printf(_L("Func Num: %d\tProtocol: %d\n"), i, configs.iAcmConfig[i].iProtocol);
+		}
+	aCon->Printf(_L("Done\n"));	
+	}
+
+/**
+ * Checks the properties of an Acm function are as expected
+ * @param RProperty aProp the attached RProperty to be checked.
+ * @param TInt aFuncNum the function to check
+ * @param TInt aVersion the version of the config info being used. This is the same for all functions
+ * @param TInt aProtocol the expected protocol of this function
+ * @return TInt ret. Expected KErrNone or standard Symbian error code.
+ */
+TInt CheckProperties(RProperty aProp, TInt aFuncNum, TInt aVersion, TUint8 aProtocol)
+	{
+	TInt ret = KErrNone;
+	TPckgBuf<TPublishedAcmConfigs> configBuf;
+	TInt err = aProp.Get(configBuf);
+	if(err != KErrNone)
+		{
+		KTestResult.Set(_L("Check properties failed to retrieve the P&S data"));
+		ret = KErrGeneral;
+		}
+	else
+		{
+		//Check the version number
+		if(configBuf().iAcmConfigVersion != aVersion)
+			{
+			KTestResult.Set(_L("Check properties version check failed."));
+			ret = KErrGeneral;
+			}
+		else
+			{
+    		if(configBuf().iAcmConfig[aFuncNum].iProtocol != aProtocol)
+				{
+				KTestResult.Set(_L("Check properties protocol check failed."));
+				ret = KErrGeneral;
+				}
+			}
+		}
+	return ret;
+	}
+
+/**
+ * Build a new test ROM configuration where the ACM class controller has 
+ * an .ini file which creates multiple ACMs, with different protocols. 
+ * Again, check that the P&S key is appropriately set before TryStart(), 
+ * while started, and after TryStop()
+ */	
+TInt TestCase1L()
+	{
+	RArray<TInt> availablePersonalities;
+	TRequestStatus status;
+	RProperty prop;
+	TInt err = KErrNone;
+		
+	err = usb.Connect();
+	if(err)
+		{
+		KTestResult.Set(_L("RUsb::Connect failed."));
+		return err;
+		}
+		
+	//check to see if the P&S data exists already
+	//It should do as usbman should have been started during system startup, 
+	//but no functions should exist until RUsb::Start | RUsb::TryStart calls
+	//are made.
+	AttachPropertyL(prop);
+	err = CheckFunctionCount(prop, 0);
+	if(err)
+		{
+		KTestResult.Set(_L("Expected 0 function to exist at this time."));
+		return GetCount(prop); //Error return the number of functions found
+		}
+	
+	err = usb.GetPersonalityIds(availablePersonalities);
+	if(err) //couldn't retrieve the personalities. 
+		{
+		KTestResult.Set(_L("Failed to retrieve the supported personalities for this device."));
+		return err;
+		}
+	if(availablePersonalities.Count() == 0) //no personalities 
+		{
+		KTestResult.Set(_L("GetPersonalities returned 0 supported personalities."));
+		return KErrGeneral;
+		}
+	usb.TryStart(availablePersonalities[0], status); //personality 0 should be the default personality
+	User::WaitForRequest(status);
+	if(status.Int())
+		{
+		KTestResult.Set(_L("RUsb::TryStart failed."));
+		return status.Int(); //USB failed to start the personality
+		}
+	
+	//now that usb has started we should be able to check the P&S data.
+	//Our NumberOfAcmFunctions.ini defines 3 functions so we should 
+	//have three funtions now
+	DisplayProperties(prop, tCon);
+	err = CheckFunctionCount(prop, 3);
+	if(err)
+		{
+		KTestResult.Set(_L("Incorrect number of functions found."));
+		return GetCount(prop);//Error return the number of functions found
+		}
+	
+	//We've gotten here so presumably all is going well, so check the version and 
+	//protcol numbers on the functions created.
+	//NumberOfAcmFunctions.ini defines functions with protocols 1, 255 & 127. 
+	TInt version = 1; //simply for clarity
+	
+	if(err)
+		{
+		KTestResult.Set(_L("Failed to attach property for CheckProperties."));
+		return err;
+		}
+	
+	err = CheckProperties(prop, 0, version, 1);
+	if(err)
+		{
+		KTestResult.Set(_L("Properties check failed for function 1."));
+		return err;
+		}
+	
+	err = CheckProperties(prop, 1, version, 255);
+	if(err)
+		{
+		KTestResult.Set(_L("Properties check failed for function 2."));
+		return err;
+		}
+	
+	err = CheckProperties(prop, 2, version, 127);
+	if(err)
+		{
+		KTestResult.Set(_L("Properties check failed for function 3."));
+		return err;
+		}
+	
+	//Assuming we're still here everything is correct, so shutdown Usbman and check 
+	//the P&S data is destroyed 
+	usb.TryStop(status);
+	User::WaitForRequest(status);
+	if(status.Int())
+		{
+		KTestResult.Set(_L("RUsb::TryStop failed."));
+		return status.Int();
+		}
+	
+	//Check to see if the P&S data was destroyed
+	err = CheckFunctionCount(prop, 0);
+	if(err)
+		{
+		KTestResult.Set(_L("P&S data was not destroyed by stopping usb."));
+		return GetCount(prop); //Error return the number of functions found
+		}
+		
+	//We got here so "All is well!"
+	KTestResult.Set(_L("Test Passed."));
+	return KErrNone;
+	}
+
+void doExampleL(CConsoleBase *aCon)
+    {
+ 
+	TInt err;
+	tCon = aCon;  
+	err = LoadDrivers(aCon);
+    if(err != KErrNone)
+    {
+    	aCon->Printf(_L("Failed to load device drivers\n"));
+    	Cleanup();
+    }
+    
+    //Connect to the file server
+    gFs.Connect();
+    TInt result = KErrNone;
+    TRAPD(error, result = TestCase1L());
+    if(error)
+    	{
+    	KTestResult.Set(_L("TestCase1L Leave occurred."));
+    	result = error;
+    	}
+	aCon->Printf(_L("TestCase 1 results: %S Result: %d\n"), &KTestResult, result);
+	Cleanup();
+	}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_spec/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* 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 "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:
+* BLD.INF for t_acm_spec
+* BLD.INF for t_acm_spec
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+t_acm_spec.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_spec/group/t_acm_spec.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+TARGET		t_acm_spec.exe
+TARGETTYPE	EXE
+UID		0
+VENDORID 0x70000001
+SOURCEPATH    ../src
+SOURCE		t_acm_spec.cpp
+LIBRARY		euser.lib c32.lib usbman.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_spec/src/t_acm_spec.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,1291 @@
+/*
+* 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:
+* t_acm.cpp
+* This program executes all the tests in the ACM CSY Test Specification v 0.1
+* and is to be used in conjunction with the host-side application.
+*
+*/
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <e32math.h>
+#include <badesca.h>
+#include <c32comm.h>
+#include <usbman.h>
+
+LOCAL_D CConsoleBase* console;
+
+RCommServ TheCommServ;
+RUsb TheUsb;
+
+TCommConfig TheConfigBuf;
+TCommConfigV01& TheConfig = TheConfigBuf();
+
+const TInt KReceiveBufferLength = 8192;
+
+//_LIT(KUsbCsyName, "ECACM");
+_LIT(KUsbPortName, "ACM::0");
+_LIT(KUsbLddName, "EUSBC");
+
+#define _printf console->Printf
+#define _getch console->Getch
+#define LEAVE(_x) VerboseLeaveL(_x, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+#define LEAVEIFERROR(_x) VerboseLeaveIfErrorL(_x, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+#define CHECK(_x) if (! (_x)) VerboseLeaveL(KErrGeneral, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+
+// A define for stack-based buffers
+#define MAX_BUFFER_SIZE 1024
+
+// A bigger buffer on the heap
+#define MAX_HEAP_BUFFER_SIZE	1024*8
+TBuf8<MAX_HEAP_BUFFER_SIZE> readBigBuf;
+
+// A timer for use by several of the tests
+RTimer timer;
+
+//The random seed
+TInt64 seed = 100;
+
+void VerboseLeaveL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode)
+/**
+ * For bombing out usefully.
+ */
+	{
+	TInt filenameOffset = aFileName.LocateReverse('\\') + 1;
+	if (filenameOffset < 0) filenameOffset = 1;
+	TPtrC8 shortFileName = aFileName.Mid(filenameOffset);
+	TBuf<64> fName, code;
+	fName.Copy(shortFileName.Left(64));
+	code.Copy(aCode.Left(64));
+	_printf(_L("\nERROR (%d) on line %d of file %S\n"), aError, aLineNum, &fName);
+	_printf(_L("Code: %S\n\n"), &code);
+	_printf(_L("[ press any key ]"));
+	_getch();
+	User::Leave(aError);
+	}
+
+void VerboseLeaveIfErrorL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode)
+/**
+ * For bombing out usefully if there's an error.
+ */
+	{
+	if (aError)
+		VerboseLeaveL(aError, aLineNum, aFileName, aCode);
+	}
+
+void ReadString(TDes& aDes)
+/**
+ * Reads user input into the start of the descriptor aDes.
+ */
+	{
+	TChar inputKey;
+	TInt count = 0;
+
+	aDes.Zero();
+	for (;;)
+		{
+		inputKey = (TInt) _getch();
+
+		if ((TInt)inputKey == EKeyEnter)
+			break;
+
+		if(inputKey == EKeyBackspace)
+			{
+			if (count > 0)
+				{
+				_printf(_L("%C"), (TUint) inputKey);
+				aDes.Delete(--count,1);
+				}
+			}
+		else if(inputKey.IsPrint())
+			{
+			_printf(_L("%C"), (TUint) inputKey);
+			aDes.Append(inputKey);
+			count++;
+			}
+		}
+	}
+
+void FillBuffer(TDes8 &aDes)
+/**
+ * Fills a given buffer with incrementing numbers.
+ */
+{
+	 aDes.Zero();
+	 for (TInt i=0; i<aDes.MaxSize(); i++)
+	 {
+		aDes.Append(i);
+	 }
+}
+
+bool CheckBuffer(TDes8 &aDes, TInt size)
+/**
+ * Checks that a given buffer contains incrementing numbers.
+ */
+{
+	 for (TInt i=0; i<size; i++)
+	 {
+		  if (aDes[i] != i)
+			   return FALSE;
+	 }
+
+	 return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void DataStress_SizeVary_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+	TInt i;
+
+	_printf(_L("\n----------------------------------\n"));
+	_printf(_L("This test performs varying size read\n"));
+	_printf(_L("and writes to and from the host.\n"));
+	_printf(_L("------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf;
+
+	_printf(_L("Reading data.\nLengths:"));
+	for (i = 1; i<MAX_BUFFER_SIZE; i*=2)
+		{
+		_printf(_L(" %d"), i);
+
+		port.Read(status, readBuf, i);
+		User::WaitForRequest(status);
+
+		if (status != KErrNone)
+			{
+			LEAVE(status.Int());
+			}
+
+		CheckBuffer(readBuf, i);
+		}
+
+	_printf(_L(" done.\nReadOneOrMore()-ing data.\n"));
+	for (i = 1; i<MAX_BUFFER_SIZE; i*=2)
+		{
+		int transferSize = 0;
+		while (transferSize != i)
+			{
+			port.ReadOneOrMore(status, readBuf);
+			User::WaitForRequest(status);
+
+			if (status != KErrNone)
+				{
+					_printf(_L("Read error"));
+					LEAVE(status.Int());
+				}
+			else
+				{
+					transferSize += readBuf.Length();
+				}
+
+			}
+			_printf(_L(" %d "), transferSize);
+		}
+
+	_printf(_L(" done.\nWriting data "));
+
+	FillBuffer(readBuf);
+
+	for (i = 1; i<MAX_BUFFER_SIZE; i*=2)
+		{
+
+		port.Write(status, readBuf, i);
+
+		User::WaitForRequest(status);
+
+		if (status != KErrNone)
+			{
+			_printf(_L("write error\n"));
+			LEAVE(status.Int());
+			}
+
+		_printf(_L(" %d"), i);
+		}
+
+	_printf(_L(" done.\nTest complete\n"));
+	 CleanupStack::PopAndDestroy(); //port
+}
+
+void DataStress_RateVary_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+	TInt i;
+
+	_printf(_L("\n----------------------------------\n"));
+	_printf(_L("This test performs varying speed read\n"));
+	_printf(_L("and writes to and from the host.\n"));
+	_printf(_L("------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf;
+
+	_printf(_L("Reading data.\nLengths:"));
+	for (i = 1; i<100; i++)
+		{
+		_printf(_L(" %d"), i);
+		port.Read(status, readBuf);
+		User::WaitForRequest(status);
+
+		if (status != KErrNone)
+			{
+			_printf(_L("Error reading"));
+			LEAVE(status.Int());
+			}
+
+		CheckBuffer(readBuf, readBuf.MaxSize());
+		}
+
+
+	_printf(_L("done.\nReadOneOrMore()-ing data.\n Lengths: "));
+	for (i = 1; i< 20; i++)
+		{
+		int transferSize = 0;
+		while (transferSize != MAX_BUFFER_SIZE) {
+			port.ReadOneOrMore(status, readBuf);
+			User::WaitForRequest(status);
+
+			if (status != KErrNone)
+				{
+				LEAVE(status.Int());
+				}
+			else
+				{
+				transferSize += readBuf.Length();
+				}
+		}
+		_printf(_L(" %d "), i);
+	}
+
+	_printf(_L(" done.\nWriting data\nLengths:"));
+	FillBuffer(readBuf);
+	for (i = 1; i< 100; i++)
+		{
+		_printf(_L(" %d "), i);
+		port.Write(status, readBuf, 1024);
+		User::WaitForRequest(status);
+
+		if (status != KErrNone)
+			{
+			_printf(_L("Write failed"));
+			LEAVE(status.Int());
+			}
+
+		// Wait for random time
+		timer.After(status, (Math::Rand(seed) % 1001));//1001 to get a value within [0-1000]
+		User::WaitForRequest(status);
+		}
+
+	_printf(_L(" done.\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void TimeOut_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+	TInt timeout;
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf;
+
+	_printf(_L("\n---------------------------\n"));
+	_printf(_L("This test exercises the read\n"));
+	_printf(_L("and write timeouts.\n"));
+	_printf(_L("-----------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Reading data\nTimeouts (ms):"));
+	for (timeout = 10; timeout<100; timeout+=10)
+		{
+		 // Clean buffers
+		 port.ResetBuffers();
+
+		_printf(_L(" %d"), timeout);
+		port.Read(status, timeout, readBuf, MAX_BUFFER_SIZE);
+		User::WaitForRequest(status);
+
+		if (status != KErrTimedOut)
+		    {
+				LEAVE(status.Int());
+			}
+		}
+
+	_printf(_L(" done.\nWriting data\nTimeouts (ms):"));
+	for (timeout = 10; timeout<100; timeout+=10)
+		{
+		 // Clean buffers
+		 port.ResetBuffers();
+
+		_printf(_L(" %d"), timeout);
+		port.Write(status, timeout, readBuf, MAX_BUFFER_SIZE);
+		User::WaitForRequest(status);
+
+		if (status != KErrTimedOut)
+		    {
+				LEAVE(status.Int());
+			}
+		}
+
+	_printf(_L(" done.\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void CancelTx_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+	TInt timeout;
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf;
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This tests the read/write cancel feature\n"));
+	_printf(_L("------------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Reading data\n"));
+	for (timeout = 10; timeout<100; timeout++)
+		{
+		port.Read(status, readBuf);
+
+		// Wait before cancelling
+		timer.After(status, timeout);
+		User::WaitForRequest(status);
+
+		port.ReadCancel();
+		User::WaitForRequest(status);
+
+		if ( (status != KErrNone) && (status !=KErrCancel) )
+			{
+			LEAVE(status.Int());
+			}
+		}
+
+	_printf(_L("Writing data\n"));
+	for (timeout = 10; timeout<100; timeout++)
+		{
+//		FillBuffer(readBuf);
+
+		port.Write(status, readBuf);
+
+		// Wait before cancelling
+		timer.After(status, timeout);
+		User::WaitForRequest(status);
+
+		port.WriteCancel();
+		User::WaitForRequest(status);
+
+		if ( (status != KErrNone) && (status !=KErrCancel) )
+			{
+			LEAVE(status.Int());
+			}
+		}
+
+	_printf(_L("\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void InterruptTx_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf;
+
+	_printf(_L("\n--------------------------------\n"));
+	_printf(_L("This tests the read/write cancel\n"));
+	_printf(_L("when the USB cable is pulled\n"));
+	_printf(_L("----------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Reading data\n"));
+	port.Read(status, readBuf);
+
+	_printf(_L("Pull cable now\n"));
+	User::WaitForRequest(status);
+	_printf(_L("Received error code: %d\n"),status.Int());
+	_printf(_L("Expect -29(KErrCommsLineFail) or range -6702 to -6712 (USB driver errors)\n\n"));
+
+	_printf(_L("Plug in cable and press any key\n"));
+	_getch();
+
+	_printf(_L("Writing data\n"));
+	_printf(_L("Pull cable now\n"));
+
+	do
+	{
+		 port.Write(status, readBuf);
+		 User::WaitForRequest(status);
+
+	} while (status == KErrNone);
+
+	_printf(_L("Received error code: %d\n"),status.Int());
+	_printf(_L("Expect -29(KErrCommsLineFail) or range -6702 to -6712 (USB driver errors)\n\n"));
+
+	_printf(_L("\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void Shutdown_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf;
+
+	_printf(_L("\n-----------------------------------\n"));
+	_printf(_L("This tests the USB Manager shutdown\n"));
+	_printf(_L("during reads and writes.\n"));
+	_printf(_L("-------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Reading data\n"));
+	port.Read(status, readBuf);
+
+	_printf(_L("Shutting down USB Manager.\n"));
+	TheUsb.Stop();
+
+	_printf(_L("Shutdown complete.\nWaiting for read to terminate."));
+	User::WaitForRequest(status);
+
+	if (status != KErrNone)	// Error code ? TODO
+		{
+		//LEAVE(status.Int());
+		_printf(_L("Read failed\n"));
+		}
+
+	_printf(_L("Read complete.\nRestarting USB Manager\n"));
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("Writing data\n"));
+
+	port.Write(status, readBuf);
+
+	_printf(_L("Shutting down USB Manager\n"));
+	TheUsb.Stop();
+
+	_printf(_L("shutdown complete.\nWaiting for write to terminate."));
+	User::WaitForRequest(status);
+
+	if (status != KErrNone)	// Error code ? TODO
+	    {
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("Write complete.\nRestarting USB Manager\n"));
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void BufferOverrun_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+	TInt i;
+
+	_printf(_L("\n--------------------------------\n"));
+	_printf(_L("This test read/writes which are\n"));
+	_printf(_L("bigger than the buffer length.\n"));
+	_printf(_L("----------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+
+	_printf(_L("Reading data.\nBuffer lengths:"));
+	for (i=128; i<=8*1024; i+=128)
+	{
+		port.SetReceiveBufferLength(i);
+
+		_printf(_L(" %d"), i);
+		port.Read(status, readBigBuf);
+
+		User::WaitForRequest(status);
+
+		if (status != KErrNone)
+		{
+			LEAVE(status.Int());
+		}
+	}
+
+	_printf(_L("done.\nWriting data\nBuffer lengths:"));
+	for (i=128; i<=8*1024; i+=128)
+	{
+		port.SetReceiveBufferLength(i);
+
+		FillBuffer(readBigBuf);
+		_printf(_L(" %d"), i);
+		port.Write(status, readBigBuf);
+		User::WaitForRequest(status);
+
+		 if (status != KErrNone)
+		 {
+			  LEAVE(status.Int());
+		 }
+	}
+
+	_printf(_L(" done.\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void Break_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status;
+	RComm port;
+
+	_printf(_L("\n--------------------------------\n"));
+	_printf(_L("This tests break and break cancel.\n"));
+	_printf(_L("----------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Breaking\n"));
+	port.Break(status, 10);
+
+	User::WaitForRequest(status);
+
+	if (status != KErrNone)
+	{
+		LEAVE(status.Int());
+	}
+
+	_printf(_L("Press and key to cancel the break.\n"));
+	_getch();
+
+	_printf(_L("Cancelling the break.\n"));
+	port.BreakCancel();
+
+	_printf(_L("\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void SignalChange_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status, statusTimer;
+	RComm port;
+
+	_printf(_L("\n---------------------------------------\n"));
+	_printf(_L("This tests signal change notifications.\n"));
+	_printf(_L("---------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	TUint signals = 0;
+	signals |= KSignalDTR;
+
+	port.NotifySignalChange(status, signals);
+	User::WaitForRequest(status);
+
+	if (status != KErrNone)
+		{
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("Notified\n"));
+
+	port.NotifySignalChange(status, signals);
+
+	// Wait
+	timer.After(statusTimer, 10);
+	User::WaitForRequest(statusTimer);
+
+	_printf(_L("Cancelling request for signal notifications\n"));
+
+	port.NotifySignalChangeCancel();
+	User::WaitForRequest(status);
+
+	if (status != KErrCancel)
+		{
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("\nRequest cancelled.\n Test complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void FlowControl_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status, statusTimer;
+	RComm port;
+
+	_printf(_L("\n-------------------------------------------\n"));
+	_printf(_L("This tests flow control change notifications.\n"));
+	_printf(_L("---------------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	TFlowControl signals;
+	port.NotifyFlowControlChange(status, signals);
+	User::WaitForRequest(status);
+
+	if (status != KErrNotSupported)
+		{
+		LEAVE(status.Int());
+		}
+
+	port.NotifyFlowControlChange(status, signals);
+
+	// Wait
+	timer.After(statusTimer, 10);
+	User::WaitForRequest(statusTimer);
+
+	port.NotifyFlowControlChangeCancel();
+	User::WaitForRequest(status);
+	if (status != KErrNotSupported)
+		{
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void ConfigChange_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	TRequestStatus status, statusTimer;
+	RComm port;
+
+	_printf(_L("\n-------------------------------------\n"));
+	_printf(_L("This tests config change notifications.\n"));
+	_printf(_L("---------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	TBuf8<64> signals;
+	port.NotifyConfigChange(status, signals);
+	User::WaitForRequest(status);
+
+	if (status != KErrNone)
+		{
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("Notified"));
+
+	port.NotifyConfigChange(status, signals);
+
+	// Wait
+	timer.After(statusTimer, 10);
+	User::WaitForRequest(statusTimer);
+
+	_printf(_L("Cancelling request for config change notifications"));
+
+	port.NotifyConfigChangeCancel();
+	User::WaitForRequest(status);
+
+	if (status != KErrCancel)
+		{
+		LEAVE(status.Int());
+		}
+
+	_printf(_L("\nRequest cancelled.\n Test complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+void SecondClient_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+{
+	RComm port1, port2;
+	TRequestStatus status1, status2, consoleStatus;
+
+	TBuf8<MAX_BUFFER_SIZE> readBuf1;
+	TBuf8<MAX_BUFFER_SIZE> readBuf2;
+
+	_printf(_L("\n---------------------------------------\n"));
+	_printf(_L("This tests that we can have a second\n"));
+	_printf(_L("client with non-exclusive access.\n"));
+	_printf(_L("---------------------------------------\n\n"));
+
+	LEAVEIFERROR(TheCommServ.Connect());
+	_printf(_L("Connected to C32\n"));
+
+	LEAVEIFERROR(port1.Open(TheCommServ, KUsbPortName, ECommShared, ECommRoleDCE));
+	CleanupClosePushL(port1);
+	LEAVEIFERROR(port2.Open(TheCommServ, KUsbPortName, ECommShared, ECommRoleDCE));
+	CleanupClosePushL(port2);
+
+	port1.SetConfig(TheConfigBuf);
+	port1.SetReceiveBufferLength(256);
+	port2.SetConfig(TheConfigBuf);
+	port2.SetReceiveBufferLength(256);
+
+	port1.SetReceiveBufferLength(256);
+	port2.SetReceiveBufferLength(256);
+
+	console->Read(consoleStatus);
+
+	_printf(_L("Read()-ing data\n"));
+	port1.Read(status1, readBuf1);
+	port2.Read(status2, readBuf2);
+
+	do
+	{
+		 User::WaitForAnyRequest();
+		 if ( (status1 != KRequestPending) && (status1 != KErrNone) )
+		 {
+			  LEAVE(status1.Int());
+		 }
+		 if ( (status2 != KRequestPending) && (status2 != KErrNone) )
+		 {
+			  LEAVE(status2.Int());
+		 }
+	}
+	while ( (status1 == KRequestPending) || (status2 == KRequestPending) );
+
+	TBuf8<256> readBuf;
+
+	_printf(_L("Write()-ing data\n"));
+	FillBuffer(readBuf);
+
+	port2.Write(status2, readBuf, 256);
+	User::WaitForRequest(status2);
+
+	if (status2 == KErrNone)
+		{
+		LEAVE(status2.Int());
+		}
+
+	_printf(_L("\nTest complete\n"));
+	CleanupStack::PopAndDestroy(); // port
+}
+
+
+// ******************************************************************
+// The following are placholders for the ACMRq tests.
+// These tests need no support on the platform end, as yet.
+// The functions are left here incase someday support is needed.
+// ******************************************************************
+
+void ACMRq_EncapCommand_TestL()
+{
+	 // Not needed to support this here
+}
+
+void ACMRq_Break_TestL()
+{
+	 // TODO: can we check for break status here ?
+}
+
+void ACMRq_SetFeature_TestL()
+{
+	 // TODO: Test doesn't make sense.
+}
+
+void ACMRq_ClearFeature_TestL()
+{
+	 // TODO: Test doesn't make sense.
+}
+
+void ACMRq_SetCoding_TestL()
+{
+	 // TODO: Can we check the line codeing here ?
+}
+
+void ACMRq_CtrlState_TestL()
+{
+	 // TODO: Test doesn't make sense.
+}
+
+void ACMRq_EncapResp_TestL()
+{
+	 // Not needed to support this here.
+}
+
+void ACMRq_CommsFeature_TestL()
+{
+	 // Not needed to support this here.
+}
+
+void ACMRq_GetCoding_TestL()
+{
+	 // Not needed to support this here.
+}
+
+
+void ACMNtf_SendState_TestL()
+{
+	 // TODO: SendSerialState() ???
+}
+
+void ACMNtf_Status_TestL()
+{
+	 // TODO: SendNetworkConnection() ???
+}
+
+void ACMNtf_RespAvail_TestL()
+{
+	 // Test not supported.
+}
+
+void Loopback_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+	{
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm port;
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This test listens for data on the ACM\n"));
+	_printf(_L("port and echoes anything it receives\n"));
+	_printf(_L("back to the PC. Press any key to quit.\n"));
+	_printf(_L("----------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Echoing received data\n"));
+
+	TBuf8<1024> readBuf;
+
+	console->Read(consoleStatus);
+
+	while (1)
+		{
+		port.ReadOneOrMore(status, readBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.ReadCancel();
+			break;
+			}
+
+//		_printf(_L("Read %d bytes\n"), readBuf.Length());
+
+		port.Write(status, readBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.WriteCancel();
+			break;
+			}
+
+		_printf(_L("."));
+		}
+
+	_printf(_L("\nTest complete\n"));
+
+	CleanupStack::PopAndDestroy(); // port
+	}
+
+void SetHandshakingL()
+/**
+ * This function allows the user to select a new handshaking mode.
+ */
+	{
+	RComm port;
+
+	TCommCaps capsBuf;
+	TCommCapsV01& caps = capsBuf();
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.Caps(capsBuf);
+	_printf(_L("\nPort handshaking capabilities: 0x%X\n"), caps.iHandshake);
+	_printf(_L("Current handshaking options: 0x%X\n"), TheConfig.iHandshake);
+
+	_printf(_L("\nHandshaking options:\n"));
+	_printf(_L("1. No handshaking\n"));
+	_printf(_L("2. Toggle Xon/Xoff\n"));
+	_printf(_L("3. Toggle obey CTS\n"));
+	_printf(_L("4. Toggle obey DSR / free RTS\n"));
+	_printf(_L("5. Toggle write buffered complete\n"));
+
+	TInt key = (TInt) _getch();
+
+	switch (key)
+		{
+	case '1':
+		TheConfig.iHandshake = 0;
+		break;
+	case '2':
+		TheConfig.iHandshake ^= KConfigObeyXoff;
+		TheConfig.iHandshake ^= KConfigSendXoff;
+		break;
+	case '3':
+		TheConfig.iHandshake ^= KConfigObeyCTS;
+		break;
+	case '4':
+		TheConfig.iHandshake ^= KConfigObeyDSR;
+		TheConfig.iHandshake ^= KConfigFreeRTS;
+		break;
+	case '5':
+		TheConfig.iHandshake ^= KConfigWriteBufferedComplete;
+		break;
+	default:
+		break;
+		}
+
+	LEAVEIFERROR(port.SetConfig(TheConfigBuf));
+
+	_printf(_L("Handshaking options now: 0x%X\n"), TheConfig.iHandshake);
+
+	CleanupStack::PopAndDestroy();
+	}
+
+void RestartUsbL()
+/**
+ * This function stops and restarts usb manager.
+ */
+	{
+	TheUsb.Stop();
+
+	TRequestStatus status;
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("Restarted USB.\n"));
+	}
+
+void mainL()
+/**
+ * This function controls test execution as directed by the user.
+ */
+	{
+		 char ch;
+		 TInt menu = 1;
+
+	TInt ret = User::LoadLogicalDevice(KUsbLddName);
+	if ((ret != KErrNone) && (ret != KErrAlreadyExists))
+		LEAVE(ret);
+
+	_printf(_L("Loaded USB LDD\n"));
+
+	ret = StartC32();
+	if ((ret != KErrNone) && (ret != KErrAlreadyExists))
+		LEAVE(ret);
+
+	_printf(_L("Started C32\n"));
+
+	LEAVEIFERROR(TheUsb.Connect());
+
+	_printf(_L("Connected to USB Manager\n"));
+
+	TRequestStatus status;
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("Started USB\n"));
+
+	LEAVEIFERROR(TheCommServ.Connect());
+
+	_printf(_L("Connected to C32\n"));
+
+	RComm port;
+
+	// The port's configuration seems to be junk at the beginning, so we set it to known values.
+
+	TheConfig.iRate = EBps115200;
+	TheConfig.iDataBits = EData8;
+	TheConfig.iStopBits = EStop1;
+	TheConfig.iParity = EParityNone;
+	TheConfig.iHandshake = 0;
+	TheConfig.iTerminatorCount = 0;
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+
+//	_printf(_L("----------------------------------------\n"));
+//	_printf(_L("Initial port config:\n"));
+//	_printf(_L("  Rate: %d bps\n"), TheConfig.iRate);
+//	_printf(_L("  Data bits: %d. Parity type: %d. Stop bits: %d\n"),
+//		TheConfig.iStopBits, TheConfig.iParity, TheConfig.iStopBits);
+//	_printf(_L("  Handshaking options: 0x%X\n"), TheConfig.iHandshake);
+//	_printf(_L("----------------------------------------\n\n"));
+
+	CleanupStack::PopAndDestroy(); // port
+
+	TBool noExit = ETrue;
+	while (noExit)
+		{
+			 switch(menu)
+			 {
+			 case 1:
+				  _printf(_L("\nAvailable tests:\n\n"));
+				  _printf(_L("1. Loopback test\n"));
+				  _printf(_L("2. Set handshaking\n"));
+				  _printf(_L("3. Restart USB\n"));
+				  _printf(_L("4. Test specification menu\n"));
+				  _printf(_L("\nSelection (x to exit): "));
+
+				  ch = (char) _getch();
+				  _printf(_L("\n"));
+				  switch (ch)
+				  {
+				  case '1': Loopback_TestL(); break;
+				  case '2': SetHandshakingL(); break;
+				  case '3': RestartUsbL(); break;
+				  case '4': menu = 2; break;
+				  case 'x':
+				  case 'X': noExit = EFalse; break;
+				  default:  _printf(_L("\nInvalid key\n")); break;
+				  }
+				  break;
+			 case 2:
+				  _printf(_L("\nAvailable tests:\n\n"));
+				  _printf(_L("1. Data stress, size varies (test 2.1.1)\n"));
+				  _printf(_L("2. Data stress, rate varies (test 2.1.2)\n"));
+				  _printf(_L("3. Timeout (test 2.2)\n"));
+				  _printf(_L("4. Cancel Transfer (test 2.3)\n"));
+				  _printf(_L("5. Interrupt Transfer (test 2.4)\n"));
+				  _printf(_L("6. Shutdown (test 2.5)\n"));
+				  _printf(_L("7. Buffer overrun (test 2.6)\n"));
+				  _printf(_L("8. Break (test 2.7)\n"));
+				  _printf(_L("9. Event notification, signal change (test 2.8.1)\n"));
+				  _printf(_L("a. Event notification, flow control (test 2.8.2)\n"));
+				  _printf(_L("b. Event notification, config change (test 2.8.3)\n"));
+				  _printf(_L("c. Second client (test 2.9)\n"));
+/*				  _printf(_L("d. ACM request, encapsulated command (test 2.10.1)\n"));
+				  _printf(_L("e. ACM request, break (test 2.10.2)\n"));
+				  _printf(_L("f. ACM request, setting feature (test 2.10.3)\n"));
+				  _printf(_L("g. ACM request, clearing feature (test 2.10.4)\n"));
+				  _printf(_L("h. ACM request, setting line coding (test 2.10.5)\n"));
+				  _printf(_L("i. ACM request, control line state (test 2.10.6)\n"));
+				  _printf(_L("j. ACM request, encapsualted response (test 2.10.7)\n"));
+				  _printf(_L("k. ACM request, comms feature (test 2.10.8)\n"));
+				  _printf(_L("l. ACM request, getting line coding (test 2.10.9)\n"));
+				  _printf(_L("m. ACM Notifications, send serial state (test 2.11.1)\n"));
+				  _printf(_L("n. ACM Notifications, network status (test 2.11.2)\n"));
+				  _printf(_L("o. ACM Notifications, response available (test 2.11.3)\n"));
+*/				  _printf(_L("p. Loopback test (test 2.12)\n"));
+				  _printf(_L("q. Main menu\n"));
+
+				  ch = (char) _getch();
+				  _printf(_L("\n"));
+				  switch (ch)
+				  {
+				  case '1': DataStress_SizeVary_TestL();	break;
+				  case '2': DataStress_RateVary_TestL();	break;
+				  case '3': TimeOut_TestL();	break;
+				  case '4': CancelTx_TestL();	break;
+				  case '5': InterruptTx_TestL();	break;
+				  case '6': Shutdown_TestL();	break;
+				  case '7': BufferOverrun_TestL();	break;
+				  case '8': Break_TestL();	break;
+				  case '9': SignalChange_TestL();	break;
+				  case 'A':
+				  case 'a': FlowControl_TestL();	break;
+				  case 'B':
+				  case 'b': ConfigChange_TestL();	break;
+				  case 'C':
+				  case 'c': SecondClient_TestL();	break;
+				  case 'D':
+				  case 'd': ACMRq_EncapCommand_TestL();	break;
+				  case 'E':
+				  case 'e': ACMRq_Break_TestL();	break;
+				  case 'F':
+				  case 'f': ACMRq_SetFeature_TestL();	break;
+				  case 'G':
+				  case 'g': ACMRq_ClearFeature_TestL();	break;
+				  case 'H':
+				  case 'h': ACMRq_SetCoding_TestL();	break;
+				  case 'I':
+				  case 'i': ACMRq_CtrlState_TestL();	break;
+				  case 'J':
+				  case 'j': ACMRq_EncapResp_TestL();	break;
+				  case 'K':
+				  case 'k': ACMRq_CommsFeature_TestL();	break;
+				  case 'L':
+				  case 'l': ACMRq_GetCoding_TestL();	break;
+				  case 'M':
+				  case 'm': ACMNtf_SendState_TestL();	break;
+				  case 'N':
+				  case 'n': ACMNtf_Status_TestL();	break;
+				  case 'O':
+				  case 'o': ACMNtf_RespAvail_TestL();	break;
+				  case 'P':
+				  case 'p': Loopback_TestL(); break;
+				  case 'q':
+				  case 'Q': menu = 1; break;
+				  default:
+					   _printf(_L("\nInvalid key\n"));
+					   break;
+				  }
+				  break;
+			 default:
+				  LEAVE(-1);
+			 }
+		}
+	TheCommServ.Close();
+	TheUsb.Close();
+	}
+
+void consoleMainL()
+/**
+ * Create a console and run mainL().
+ */
+	{
+	console=Console::NewL(_L("T_ACM"),TSize(KConsFullScreen,KConsFullScreen));
+	CleanupStack::PushL(console);
+	mainL();
+	_printf(_L("[ press any key ]"));
+	_getch();
+	CleanupStack::PopAndDestroy();
+	}
+
+GLDEF_C TInt E32Main()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanupStack=CTrapCleanup::New();
+
+	// create the timer for use during some of the tests
+	timer.CreateLocal();
+
+	TRAP_IGNORE(consoleMainL());
+	delete cleanupStack;
+	__UHEAP_MARKEND;
+	return 0;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_wins/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 1999-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:
+* Build information for ACM CSY host test project
+* Build information for ACM CSY host test project
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_PLATFORMS
+WINSCW
+// WINS
+
+PRJ_TESTMMPFILES
+#ifdef WINSCW
+	t_acm_wins.mmp
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_wins/group/t_acm_wins.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 1997-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:
+* T_ACM.MMP
+*
+*/
+
+TARGET		t_acm_wins.exe
+TARGETTYPE	EXE
+SOURCEPATH	../src
+SOURCE		t_acm_wins.cpp
+LIBRARY		euser.lib efsrv.lib c32.lib ws32.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+START WINS
+	win32_library 	user32.lib
+END
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_acm_wins/src/t_acm_wins.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,920 @@
+/*
+* 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:
+* This program executes all the tests in the ACM CSY Test Specification v 0.1
+* on the host, and is to be used in conjunction with the device-side application (t_acm).
+*
+*/
+
+// Includes ////////////////////////////////////////////////////////////////////
+
+/* Symbian OS includes */
+#include <e32base.h>
+#include <e32cons.h>
+#include <e32math.h>
+
+#define WIN32_LEAN_AND_MEAN
+
+/* Windows i/o for serial device */
+#include <windows.h>
+#include <wchar.h>
+
+// Defines and enumerations /////////////////////////////////////////////////////
+
+#define _printf console->Printf
+#define _getch console->Getch
+#define LEAVE(_x) VerboseLeaveL(_x, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+#define LEAVEIFERROR(_x) VerboseLeaveIfErrorL(_x, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+#define CHECK(_x) if (! (_x)) VerboseLeaveL(KErrGeneral, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+
+#define MAX_BUFFER_SIZE 1024
+
+// Flow control constants
+enum	FlowControl_Modes {KFLOW_NONE, KFLOW_RTSCTS, KFLOW_DTRDSR};
+
+// Global Variables /////////////////////////////////////////////////////////////
+
+HANDLE	hSerial;	// An MS Windows handle for the serial port
+DCB		OldDcb;		// for storing the original serial device context
+DCB		newDcb;
+
+// For holding our new serial port parameteres
+struct SerialParameters
+	{
+	char			*comport;					// which port
+	unsigned long	pktsize, pktcount, maxwait;	// packet config
+	unsigned long	baud, bits, stop;			// serial parameters
+	unsigned char	parity;
+	enum	FlowControl_Modes	flowcontrol;	// flow control handshaking
+} SerialParams;
+
+LOCAL_D CConsoleBase* console;	// A Symbian command console
+
+_LIT(KPortName, "COM3");		// Windows serial port name
+
+RTimer timer;	// A timer for use by several of the tests
+
+// Some buffers allocated on the heap for functions with large
+// stack usage so we don't get a __chkstk error.
+char writeBufbig[MAX_BUFFER_SIZE];
+char readBufbig[MAX_BUFFER_SIZE];
+
+// Functions //////////////////////////////////////////////////////////////////
+
+void VerboseLeaveL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode)
+/**
+ * For bombing out usefully.
+ */
+	{
+	TInt filenameOffset = aFileName.LocateReverse('\\') + 1;
+	if (filenameOffset < 0) filenameOffset = 1;
+	TPtrC8 shortFileName = aFileName.Mid(filenameOffset);
+	TBuf<64> fName, code;
+	fName.Copy(shortFileName.Left(64));
+	code.Copy(aCode.Left(64));
+	_printf(_L("ERROR (%d) on line %d of file %S\n"), aError, aLineNum, &fName);
+	_printf(_L("Code: %S\n\n"), &code);
+	_printf(_L("[ press any key ]"));
+	_getch();
+	User::Leave(aError);
+	}
+
+void VerboseLeaveIfErrorL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode)
+/**
+ * For bombing out usefully if there's an error.
+ */
+	{
+	if (aError) 
+		VerboseLeaveL(aError, aLineNum, aFileName, aCode);
+	}
+
+void SetWindowsSerialParams()
+/**
+ * Set up the new serial parameters with which to run the tests.
+ */
+{
+	// parameter 1 is port name
+	// read in COM port name (this parameter must be specified!)
+	SerialParams.comport = new char[10];
+	strcpy(SerialParams.comport, "COM3");
+
+	// default packet size
+	SerialParams.pktsize = 1024;
+
+	// default no of packets
+	SerialParams.pktcount = 1;
+
+	// default wait for data return
+	SerialParams.maxwait = 30;
+
+	// default flow control
+	SerialParams.flowcontrol = KFLOW_RTSCTS;
+
+	// default data rate
+	// baud rate 0 (port's default) standard rates 300 -> 115200
+	SerialParams.baud = 0;
+
+	// default bits per char
+	SerialParams.bits = 8;
+
+	// default parity
+	SerialParams.parity = 'N';
+
+	// default 9 is stop bits
+	SerialParams.stop = 1;
+}
+
+static int	InitializePort()
+/**
+ * Store the old state of the serial port and set it up for our tests.
+ */
+{
+	DCB				dcb;
+	COMMTIMEOUTS	CommsTimeouts;
+
+	// Setup comms device receive & transmit buffers
+	if(SetupComm(hSerial, 16384, 16384) == 0)
+	{
+		LEAVE(-1);
+	}
+
+	// Purge all characters from the output and input buffers
+	// and terminate any pending read or write operations 
+	if(PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR) == 0)
+	{
+		LEAVE(-1);
+	}
+
+	dcb.DCBlength = sizeof(DCB);
+	if(GetCommState(hSerial, &dcb) == 0)
+	{
+		// not a serial device
+		LEAVE(-1);
+	}
+
+    memcpy(&OldDcb, &dcb, sizeof(DCB));
+
+	// General initialization for both transmitted and received bytes
+	// using port's default baud rate etc..., so read it
+	SerialParams.baud = dcb.BaudRate;		// Get baud rate 
+	SerialParams.bits = dcb.ByteSize;		// Get number of bits 
+	if(dcb.StopBits == 2)					// Get number of stop bits to be used
+		SerialParams.stop = 2;
+	else
+		SerialParams.stop = 1;
+
+	// Get parity scheme
+	if((dcb.fParity == FALSE) || (dcb.Parity == 0))
+	{
+		SerialParams.parity = 'N';
+	}
+	else
+	{
+		switch(dcb.Parity)
+		{
+		case 1:	SerialParams.parity = 'O'; break;
+		case 2:	SerialParams.parity = 'E'; break;
+		case 3:	SerialParams.parity = 'M'; break;
+		case 4:	SerialParams.parity = 'S'; break;
+		default:	SerialParams.parity = 'N'; break;  // shouldn't happen
+		}
+	}
+	dcb.fBinary = TRUE;				// Set binary mode 
+
+	// Setup hardware flow control
+	if(SerialParams.flowcontrol == KFLOW_RTSCTS)
+	{
+		dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;	// Specify the type of RTS flow control
+		dcb.fOutxCtsFlow = 1;						// Specify whether the CTS signal is monitored
+
+		dcb.fDtrControl = DTR_CONTROL_ENABLE;	// Specify the type of DTR flow control
+		dcb.fOutxDsrFlow = 0;					// Specify whether the DSR signal is monitored
+	}
+	else if(SerialParams.flowcontrol == KFLOW_DTRDSR)
+	{
+		dcb.fRtsControl = RTS_CONTROL_ENABLE;	// Specify the type of RTS flow control
+		dcb.fOutxCtsFlow = 0;						// Specify whether the CTS signal is monitored
+
+		dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;// Specify the type of DTR flow control
+		dcb.fOutxDsrFlow = 1;					// Specify whether the DSR signal is monitored
+	}
+	else // KFLOW_NONE
+	{
+		dcb.fRtsControl = RTS_CONTROL_ENABLE;	// Specify the type of RTS flow control
+		dcb.fOutxCtsFlow = 0;					// Specify whether the CTS signal is monitored
+
+		dcb.fDtrControl = DTR_CONTROL_ENABLE;	// Specify the type of DTR flow control
+		dcb.fOutxDsrFlow = 0;					// Specify whether the DSR signal is monitored
+	}
+
+	dcb.fInX = dcb.fOutX = 0;
+	dcb.fDsrSensitivity = 0;
+	dcb.fErrorChar = 0;
+	dcb.fNull = 0;
+	dcb.fAbortOnError = 1;
+
+	// Configure the communications device according 
+	// to the specifications in the device-control block
+	// The function reinitializes all hardware and control settings, 
+	// but does not empty output or input queues
+	if(SetCommState(hSerial, &dcb) == 0)
+	{
+		LEAVE(-1);
+	}
+
+	// Set timeout parameters for comms device
+	/* A value of MAXDWORD, combined with zero values for both the 
+	 * ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, 
+	 * specifies that the read operation is to return immediately with 
+	 * the characters that have already been received, even if no characters 
+	 * have been received.
+	 */
+
+	CommsTimeouts.ReadIntervalTimeout = 0xFFFFFFFF;
+	CommsTimeouts.ReadTotalTimeoutMultiplier = 0;
+	CommsTimeouts.ReadTotalTimeoutConstant = 1000;
+
+	// CBR_9600 is approximately 1byte/ms. For our purposes be generous 
+	// & allow double the expected time per character
+	if(SerialParams.maxwait > 1)
+	{
+		CommsTimeouts.WriteTotalTimeoutMultiplier = 0;
+		CommsTimeouts.WriteTotalTimeoutConstant = (SerialParams.maxwait - 1) * 1000;
+	}
+	else
+	{
+		CommsTimeouts.WriteTotalTimeoutMultiplier = 2*CBR_9600/dcb.BaudRate;
+		CommsTimeouts.WriteTotalTimeoutConstant = 1000;
+	}
+
+	if(0 == SetCommTimeouts(hSerial, &CommsTimeouts))
+	{
+		LEAVE(-1);
+	}
+
+	if(0 == SetCommMask(hSerial, EV_RXCHAR | EV_ERR /* | EV_TXEMPTY */))
+	{
+		LEAVE(-1);
+	}
+
+	return 0;
+}
+
+void OpenComPort()
+/**
+ * Create a Windows com port for our serial device.
+ */
+{
+	hSerial = INVALID_HANDLE_VALUE;
+	wchar_t  *fullname = new wchar_t[50];
+    
+	// Open comms device
+	wcscpy(fullname, L"\\\\.\\com3");
+	hSerial = CreateFile(fullname,
+						 GENERIC_READ | GENERIC_WRITE,
+						 0,                    // exclusive access
+						 NULL,                 // no security attrs
+						 OPEN_EXISTING,
+						 FILE_ATTRIBUTE_NORMAL,
+						 NULL ) ;
+
+	// return if handle for comms device is invalid
+	if (hSerial == INVALID_HANDLE_VALUE)
+	{
+		delete[] fullname;
+		LEAVE(GetLastError());
+	}
+	else 
+	{
+		if(InitializePort())
+		{
+			// Close comms device and event handles for overlapped read and write
+			CloseHandle(hSerial);
+			hSerial = INVALID_HANDLE_VALUE;
+		}
+	}
+	delete[] fullname;
+}
+
+void FillBuffer(char *buffer, int size)
+/**
+ * Fills the buffer with incrementing data
+ */
+	{
+	for (TInt i=0; i<size; i++)
+		{
+		// Need the & 0xff to remove the truncation warning
+		buffer[i] = (char)((i%256) & 0xff);
+		}
+	}
+
+bool CheckBuffer(char *buffer, int size)
+/**
+ * Checks the buffer is filled with incrementing data
+ */
+	{
+	for (TInt i=0; i<size; i++)
+		{
+		if (buffer[i] != i%256)
+		return FALSE;
+		}
+
+	return TRUE;
+	}
+
+void ReadData(char *RxBuffer, int size)
+/**
+ * Read the given amount of data into a buffer from the serial port.
+ */
+{
+	unsigned long Count;
+	long total = 0;
+
+	while (total < size) {
+	  if(ReadFile(hSerial, RxBuffer, size, &Count, NULL) == 0)
+	  {
+		_printf(_L("ReadFile() returned error code: %d.\n"), GetLastError());
+	  }
+	  else
+	  {
+		total += Count;
+	  }
+	}
+
+}
+
+void WriteData(char *TxBuffer, int size)
+/**
+ * Write the given data over the serial port.
+ */
+{
+	unsigned long TxCount;
+
+	if(WriteFile(hSerial, TxBuffer, size, &TxCount, NULL) == 0)
+	{
+		_printf(_L("WriteFile() returned error code: %d.\n"), GetLastError());
+	}
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+void DataStress_SizeVary_TestL()
+/**
+ * Perform a single test.
+ */
+	{
+	_printf(_L("\n----------------------------------\n"));
+	_printf(_L("This test performs varying size read\n"));
+	_printf(_L("and writes to and from the device.\n"));
+	_printf(_L("------------------------------------\n\n"));
+
+	// Purge all characters from the output and input buffers
+	// and terminate any pending read or write operations 
+	if(PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR) == 0)
+		{
+		CloseHandle(hSerial);
+		LEAVE(-1);
+		}
+
+	_printf(_L("Writing data\n"));
+	for (int i = 1; i<MAX_BUFFER_SIZE; i*=2)
+		{
+		FillBuffer(writeBufbig, i);
+		WriteData(writeBufbig, i);
+		}
+
+	_printf(_L("Writing more data\n"));
+	for (int i = 1; i<MAX_BUFFER_SIZE; i*=2)
+		{	
+		FillBuffer(writeBufbig, i);
+		WriteData(writeBufbig, i);
+		}
+
+	_printf(_L("Reading data\n"));
+	for (int i = 1; i<MAX_BUFFER_SIZE; i*=2)
+		{
+		memset(readBufbig, 0, MAX_BUFFER_SIZE);
+		ReadData(readBufbig, i);
+		_printf(_L("%d "), i);
+		}
+
+	_printf(_L("\nTest complete.\n"));
+	}
+
+
+void DataStress_RateVary_TestL()
+/**
+ * Perform a single test.
+ */
+{
+	TInt i;
+
+	_printf(_L("\n----------------------------------\n"));
+	_printf(_L("This test performs varying speed read\n"));
+	_printf(_L("and writes to and from the host.\n"));
+	_printf(_L("Press any key to quit.\n"));
+	_printf(_L("------------------------------------\n\n"));
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	_printf(_L("Writing data\n"));
+	for (i = 1; i<100; i++)
+		{
+		FillBuffer(writeBufbig, MAX_BUFFER_SIZE);
+		WriteData(writeBufbig, MAX_BUFFER_SIZE);
+		}
+
+	_printf(_L("Writing more data\n"));
+	for (i = 1; i<20; i++)
+		{
+		FillBuffer(writeBufbig, MAX_BUFFER_SIZE);
+		WriteData(writeBufbig, MAX_BUFFER_SIZE);
+		}
+
+	_printf(_L("Reading data\n"));
+	for (i = 1; i<100; i++)
+		{
+		memset(readBufbig, 0, MAX_BUFFER_SIZE);
+		ReadData(readBufbig, MAX_BUFFER_SIZE);
+		CheckBuffer(readBufbig, MAX_BUFFER_SIZE);
+
+		}
+
+	_printf(_L("\nTest complete\n"));
+}
+
+void TimeOut_TestL()
+/**
+ * Perform a single test.
+ */
+{
+	_printf(_L("\n---------------------------\n"));
+	_printf(_L("This test exercises the read\n"));
+	_printf(_L("and write timeouts on the device.\n"));
+	_printf(_L("Press any key to quit.\n"));
+	_printf(_L("-----------------------------\n\n"));
+
+
+	_printf(_L("In this test the host sits around while the device times out.\n"));
+	_printf(_L("Press a key when finished.\n"));
+	_getch();
+
+	_printf(_L("\nTest complete\n"));
+}
+
+void CancelTx_TestL()
+/**
+ * Perform a single test.
+ */
+{
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This tests the read/write cancel feature\n"));
+	_printf(_L("Press any key to quit.\n"));
+	_printf(_L("------------------------------------------\n\n"));
+
+	_printf(_L("In this test the host sits around while the device cancels.\n"));
+	_printf(_L("Press a key when finished.\n"));
+	_getch();
+
+	_printf(_L("\nTest complete\n"));
+}
+
+void InterruptTx_TestL()
+/**
+ * Perform a single test.
+ */
+{
+	_printf(_L("\n--------------------------------\n"));
+	_printf(_L("This tests the read/write cancel\n"));
+	_printf(_L("when the USB cable is pulled\n"));
+	_printf(_L("----------------------------------\n\n"));
+
+	// Close the handle. If we don't do this before the device operator starts 
+	// pulling the cable out and plugging it in again then we'll never be able 
+	// to open it again afterwards. (This is also seen in HyperTerminal- 
+	// solution: reboot HyperTerminal.)
+	CloseHandle(hSerial);
+
+	// The device will attempt to read, then the cable will be pulled.
+	_printf(_L("Press any key when the device reports\n"));
+	_printf(_L("that the test is complete.\n"));
+	_getch();
+
+	// restart the serial device
+	OpenComPort();
+
+	_printf(_L("\nTest complete\n"));
+}
+
+void Shutdown_TestL()
+/**
+ * Perform a single test.
+ */
+{
+	_printf(_L("\n-----------------------------------\n"));
+	_printf(_L("This tests the USB Manager shutdown\n"));
+	_printf(_L("during reads and writes.\n"));
+	_printf(_L("Press any key to quit.\n"));
+	_printf(_L("-------------------------------------\n\n"));
+
+	_printf(_L("In this test the host sits around while\n"));
+	_printf(_L(" the device shuts down the USB manager.\n"));
+	_printf(_L("Press a key when finished.\n"));
+	_getch();
+
+	_printf(_L("\nTest complete\n"));
+}
+
+void BufferOverrun_TestL()
+/**
+ * Test updated from that in the ACM unit test specification to
+ * read/write messages bigger than the receive and transmit buffers.
+ * Changed as previous test was no longer valid.
+ */
+{
+	#define MAX_BIG_BUFFER_SIZE	(1024*8)
+	char bigBuf[MAX_BIG_BUFFER_SIZE];
+
+	_printf(_L("\n--------------------------------\n"));
+	_printf(_L("This tests read/writes which are\n"));
+	_printf(_L("bigger than the buffer length.\n"));
+	_printf(_L("----------------------------------\n\n"));
+
+	_printf(_L("Writing data.\nBuffer length: %d"), MAX_BIG_BUFFER_SIZE);
+	FillBuffer(bigBuf, MAX_BIG_BUFFER_SIZE);
+	WriteData(bigBuf, MAX_BIG_BUFFER_SIZE);
+
+	_printf(_L("done.\nReading data\nBuffer length: %d"), MAX_BIG_BUFFER_SIZE);
+	ReadData(bigBuf, MAX_BIG_BUFFER_SIZE);
+
+	_printf(_L(" done.\nTest complete\n"));
+}
+
+void Break_TestL()
+/**
+ * Perform a single test.
+ */
+{
+	_printf(_L("\n--------------------------------\n"));
+	_printf(_L("This tests break and break cancel.\n"));
+	_printf(_L("----------------------------------\n\n"));
+
+	_printf(_L("In this test the host sits around while\n"));
+	_printf(_L("the device issues some breaks.\n"));
+	_printf(_L("Press a key when finished.\n"));
+	_getch();
+
+	// TODO: should also do host-requested breaks. And NotifyBreaks.
+	_printf(_L("\nTest complete\n"));
+}
+
+void SignalChange_TestL()
+/**
+ * Perform a single test.
+ */
+{
+	_printf(_L("\n---------------------------------------\n"));
+	_printf(_L("This tests signal change notifications.\n"));
+	_printf(_L("---------------------------------------\n\n"));
+
+
+	_printf(_L("Press any key to send a signal change.\n"));
+	_getch();
+
+	newDcb.DCBlength = sizeof(DCB);
+    memcpy(&OldDcb, &newDcb, sizeof(DCB));
+
+	newDcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
+	
+	(void) SetCommState(hSerial, &newDcb);
+
+	_printf(_L("\nTest complete\n"));
+}
+
+void FlowControl_TestL()
+/**
+ * Perform a single test.
+ */
+{
+	_printf(_L("\n-------------------------------------------\n"));
+	_printf(_L("This tests flow control change notifications.\n"));
+	_printf(_L("---------------------------------------------\n\n"));
+
+	_printf(_L("Host side does nothing in this test. Press any key.\n"));
+	_getch();
+
+	_printf(_L("\nTest complete\n"));
+}
+
+void ConfigChange_TestL()
+/**
+ * Perform a single test.
+ */
+{
+	DCB		dcb;
+
+	_printf(_L("\n------------------------------- -----\n"));
+	_printf(_L("This tests config change notifications.\n"));
+	_printf(_L("---------------------------------------\n\n"));
+
+	
+	_printf(_L("Press any key to send a new configuration.\n"));
+	_getch();
+
+	dcb.DCBlength = sizeof(DCB);
+    memcpy(&OldDcb, &dcb, sizeof(DCB));
+	dcb.BaudRate=38400;
+
+	(void) SetCommState(hSerial, &dcb);
+	
+	_printf(_L("\nTest complete\n"));
+}
+
+
+void SecondClient_TestL()
+/**
+ * Perform a single test.
+ */
+{
+	_printf(_L("\n---------------------------------------\n"));
+	_printf(_L("This tests that we can have a second\n"));
+	_printf(_L("client with non-exclusive access.\n"));
+	_printf(_L("Press any key to quit.\n"));
+	_printf(_L("---------------------------------------\n\n"));
+
+	_printf(_L("Writing data\n"));
+	FillBuffer(writeBufbig, MAX_BUFFER_SIZE);
+	WriteData(writeBufbig, MAX_BUFFER_SIZE);
+	WriteData(writeBufbig, MAX_BUFFER_SIZE);
+
+	_printf(_L("Reading data\n"));
+	memset(readBufbig, 0, 256);
+	ReadData(readBufbig, 256);
+	CheckBuffer(readBufbig, 256);
+
+	_printf(_L("\nTest complete\n"));
+}
+
+
+// ******************************************************************
+// The following are placholders for the ACMRq tests.
+// These tests need no support on the platform end, as yet.
+// The functions are left here incase someday some support is needed.
+// ******************************************************************
+
+void ACMRq_EncapCommand_TestL()
+{
+	 // Not needed to support this here
+}
+
+void ACMRq_Break_TestL()
+{
+	 // TODO: can we check for break status here ?
+}
+
+void ACMRq_SetFeature_TestL()
+{
+	 // TODO: Test doesn't make sense.
+}
+
+void ACMRq_ClearFeature_TestL()
+{
+	 // TODO: Test doesn't make sense.
+}
+
+void ACMRq_SetCoding_TestL()
+{
+	 // TODO: Can we check the line codeing here ?
+}
+
+void ACMRq_CtrlState_TestL()
+{
+	 // TODO: Test doesn't make sense.
+}
+
+void ACMRq_EncapResp_TestL()
+{
+	 // Not needed to support this here.
+}
+
+void ACMRq_CommsFeature_TestL()
+{
+	 // Not needed to support this here.
+}
+
+void ACMRq_GetCoding_TestL()
+{
+	 // Not needed to support this here.
+}
+
+
+void ACMNtf_SendState_TestL()
+{
+	 // TODO: SendSerialState() ???
+}
+
+void ACMNtf_Status_TestL()
+{
+	 // TODO: SendNetworkConnection() ???
+}
+
+void ACMNtf_RespAvail_TestL()
+{
+	 // Test not supported.
+}
+
+void Loopback_TestL()
+/**
+ * Perform a single test.
+ */
+	{
+	_printf(_L("\n---------------------------------------------\n"));
+	_printf(_L("This test writes data out of the USB ACM port\n"));
+	_printf(_L("and check that it is correctly echoed back.\n"));
+	_printf(_L("---------------------------------------------\n\n"));
+
+	// Purge all characters from the output and input buffers
+	// and terminate any pending read or write operations 
+	if(PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR) == 0)
+		{
+		LEAVE(GetLastError());
+		}
+
+	for (char i=0; i<100; i++)
+		{
+		memset(readBufbig, 0, MAX_BUFFER_SIZE);	// clear the read buffer
+		memset(writeBufbig, i, MAX_BUFFER_SIZE);	// fill the write buffer with known data
+		_printf(_L("%d: "), (TInt)i);
+		WriteData(writeBufbig, 64);
+		//FlushFileBuffers(hSerial);
+		ReadData(readBufbig, 64);
+		for (int j=0; j<64; j++)
+			{
+			if (readBufbig[j] != i)
+				{
+				_printf(_L("Buffer contents error.\n"));
+				for (int k=0; k<64; k++)
+					{
+					_printf(_L("%d "), readBufbig[k]);
+					}
+				_printf(_L("\n"));
+				return;
+				}
+			}
+		}
+	}
+
+void mainL()
+/**
+ * This function controls test execution as directed by the user.
+ */
+	{
+	TRequestStatus status;
+
+	memset(&SerialParams, 0, sizeof(struct SerialParameters));
+	SetWindowsSerialParams();
+
+	OpenComPort();
+
+	_printf(_L("Opened com port. [press any key]")); _getch();
+
+	TBool noExit = ETrue;
+	while (noExit)
+		{
+			_printf(_L("\nAvailable tests:\n\n"));
+			_printf(_L("1. Data stress, size varies (test 2.1.1)\n"));
+			_printf(_L("2. Data stress, rate varies (test 2.1.2)\n"));
+			_printf(_L("3. Timeout (test 2.2)\n"));
+			_printf(_L("4. Cancel Transfer (test 2.3)\n"));
+			_printf(_L("5. Interrupt Transfer (test 2.4)\n"));
+			_printf(_L("6. Shutdown (test 2.5)\n"));
+			_printf(_L("7. Buffer overrun (test 2.6)\n"));
+			_printf(_L("8. Break (test 2.7)\n"));
+			_printf(_L("9. Event notification, signal change (test 2.8.1)\n"));
+			_printf(_L("a. Event notification, flow control (test 2.8.2)\n"));
+			_printf(_L("b. Event notification, config change (test 2.8.3)\n"));
+			_printf(_L("c. Second client (test 2.9)\n"));
+/*			_printf(_L("d. ACM request, encapsulated command (test 2.10.1)\n"));
+			_printf(_L("e. ACM request, break (test 2.10.2)\n"));
+			_printf(_L("f. ACM request, setting feature (test 2.10.3)\n"));
+			_printf(_L("g. ACM request, clearing feature (test 2.10.4)\n"));
+			_printf(_L("h. ACM request, setting line coding (test 2.10.5)\n"));
+			_printf(_L("i. ACM request, control line state (test 2.10.6)\n"));
+			_printf(_L("j. ACM request, encapsualted response (test 2.10.7)\n"));
+			_printf(_L("k. ACM request, comms feature (test 2.10.8)\n"));
+			_printf(_L("l. ACM request, getting line coding (test 2.10.9)\n"));
+			_printf(_L("m. ACM Notifications, send serial state (test 2.11.1)\n"));
+			_printf(_L("n. ACM Notifications, network status (test 2.11.2)\n"));
+			_printf(_L("o. ACM Notifications, response available (test 2.11.3)\n"));
+*/			_printf(_L("p. Loopback test (test 2.12)\n"));
+			_printf(_L("\n"));
+			_printf(_L("\nSelection (x to exit): "));
+
+			char ch = (char) _getch();
+			_printf(_L("\n"));
+			switch (ch)
+				{
+			case '1': DataStress_SizeVary_TestL();	break;
+			case '2': DataStress_RateVary_TestL();	break;
+			case '3': TimeOut_TestL();	break;
+			case '4': CancelTx_TestL();	break;
+			case '5': InterruptTx_TestL();	break;
+			case '6': Shutdown_TestL();	break;
+			case '7': BufferOverrun_TestL();	break;
+			case '8': Break_TestL();	break;
+			case '9': SignalChange_TestL();	break;
+			case 'A':
+			case 'a': FlowControl_TestL();	break;
+			case 'B':
+			case 'b': ConfigChange_TestL();	break;
+			case 'C':
+			case 'c': SecondClient_TestL();	break;
+			case 'D':
+			case 'd': ACMRq_EncapCommand_TestL();	break;
+			case 'E':
+			case 'e': ACMRq_Break_TestL();	break;
+			case 'F':
+			case 'f': ACMRq_SetFeature_TestL();	break;
+			case 'G':
+			case 'g': ACMRq_ClearFeature_TestL();	break;
+			case 'H':
+			case 'h': ACMRq_SetCoding_TestL();	break;
+			case 'I':
+			case 'i': ACMRq_CtrlState_TestL();	break;
+			case 'J':
+			case 'j': ACMRq_EncapResp_TestL();	break;
+			case 'K':
+			case 'k': ACMRq_CommsFeature_TestL();	break;
+			case 'L':
+			case 'l': ACMRq_GetCoding_TestL();	break;
+			case 'M':
+			case 'm': ACMNtf_SendState_TestL();	break;
+			case 'N':
+			case 'n': ACMNtf_Status_TestL();	break;
+			case 'O':
+			case 'o': ACMNtf_RespAvail_TestL();	break;
+			case 'P':
+			case 'p': Loopback_TestL(); break;
+			case 'x':
+			case 'X':
+				noExit = EFalse;
+				break;
+			default:
+				_printf(_L("\nInvalid key\n"));
+				break;
+				}
+
+			if (noExit)
+				{
+				_printf(_L("Test Complete. Press a key.\n"));
+				_getch();
+				}
+		}
+
+		(void) SetCommState(hSerial, &OldDcb);
+		CloseHandle(hSerial);
+		delete[] SerialParams.comport;
+	}
+
+void consoleMainL()
+/**
+ * Create a console and run mainL().
+ */
+	{
+	console=Console::NewL(_L("T_ACM"),TSize(KConsFullScreen,KConsFullScreen));
+	CleanupStack::PushL(console);
+	mainL();
+	CleanupStack::PopAndDestroy();
+	}
+
+GLDEF_C TInt E32Main()
+/**
+ * Standard Symbian entry point. Sets stuff up and deals with the cleanup stack.
+ */
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanupStack=CTrapCleanup::New();
+
+	// create the timer for use during some of the tests
+	timer.CreateLocal();
+
+	TRAP_IGNORE(consoleMainL());
+	delete cleanupStack;
+	timer.Close();
+	__UHEAP_MARKEND;
+	return 0;
+	}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_catc/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* 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 "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:
+* BLD.INF for t_catc
+* BLD.INF for t_catc
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+t_catc.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_catc/group/t_catc.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 1997-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:
+* T_ACM.MMP
+*
+*/
+
+TARGET		t_catc.exe
+TARGETTYPE	EXE
+UID		0
+VENDORID 0x70000001
+SOURCEPATH    ../src
+SOURCE		t_catc.cpp
+LIBRARY		euser.lib c32.lib usbman.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_catc/src/t_catc.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,723 @@
+/*
+* Copyright (c) 2003-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:
+* TODO: This is used for non-loopback (i.e. bulk IN and OUT) performance 
+* testing. It has been modified (see TODO: speed enhancement! marks) from the 
+* vanilla version in the team directory (Camfiler01\softeng\Departmental\Pan
+* \Team\USB\Useful Stuff\t_catc\t_catc.cpp) to make it faster
+*
+*/
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <e32std.h>
+#include <badesca.h>
+#include <c32comm.h>
+#include <usbman.h>
+
+////////////////////////////////////////////////////////////////////////////////
+
+LOCAL_D CConsoleBase* console;
+
+RCommServ TheCommServ;
+RUsb TheUsb;
+
+TCommConfig TheConfigBuf;
+TCommConfigV01& TheConfig = TheConfigBuf();
+
+const TInt KReceiveBufferLength = 65536/*16384*/; // TODO: speed enhancement!
+//const TInt KMaxBufferSize = 8192; // TODO: speed enhancement!
+const TUint KChunkSize = 65536;
+
+////////////////////////////////////////////////////////////////////////////////
+
+//_LIT(KUsbCsyName, "ECACM");
+_LIT(KUsbPortName, "ACM::0");
+_LIT(KUsbLddName, "EUSBC");
+
+////////////////////////////////////////////////////////////////////////////////
+
+#define _printf console->Printf
+#define _getch  console->Getch
+
+////////////////////////////////////////////////////////////////////////////////
+
+TInt bReadCall = ETrue ;
+TInt bUseZLP   = EFalse ;
+TInt bUseTerm  = EFalse ;
+
+////////////////////////////////////////////////////////////////////////////////
+
+#define PARM(_c,_x)			_c, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x)
+
+#define LEAVE(_x)			VerboseLeaveL(PARM(_x,_x))
+#define LEAVEIFERROR(_x)	VerboseLeaveIfErrorL(PARM(_x,_x))
+
+#define CHECK(_x)			if(! (_x) )										\
+								{											\
+								VerboseLeaveL(PARM(KErrGeneral,_x));		\
+								}
+
+void VerboseLeaveL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode)
+	{
+	TInt filenameOffset = aFileName.LocateReverse('\\') + 1;
+	if (filenameOffset < 0) filenameOffset = 1;
+	TPtrC8 shortFileName = aFileName.Mid(filenameOffset);
+	TBuf<64> fName, code;
+	fName.Copy(shortFileName.Left(64));
+	code.Copy(aCode.Left(64));
+	_printf(_L("ERROR (%d) on line %d of file %S\n"), aError, aLineNum, &fName);
+	_printf(_L("Code: %S\n\n"), &code);
+	_printf(_L("[ press any key ]"));
+	_getch();
+	User::Leave(aError);
+	}
+
+void VerboseLeaveIfErrorL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode)
+	{
+	if (aError)
+		{
+		VerboseLeaveL(aError, aLineNum, aFileName, aCode);
+		}
+	}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void ReadString(TDes& aDes)
+/**
+ * Reads user input into the start of the descriptor aDes.
+ */
+	{
+	TChar inputKey;
+	TInt count = 0;
+
+	aDes.Zero();
+	for (;;)
+		{
+		inputKey = (TInt) _getch();
+
+		if ((TInt)inputKey == EKeyEnter)
+			{
+			break;
+			}
+
+		if(inputKey == EKeyBackspace)
+			{
+			if (count > 0)
+				{
+				_printf(_L("%C"), (TUint) inputKey);
+				aDes.Delete(--count,1);
+				}
+			}
+		else if(inputKey.IsPrint())
+			{
+			_printf(_L("%C"), (TUint) inputKey);
+			aDes.Append(inputKey);
+			count++;
+			}
+		}
+	}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void Bulk_OUT_TestL()
+	{
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm port;
+
+//	static TBuf8<1024> OUT_Buf; // TODO: speed enhancement!
+	static TBuf8<KChunkSize> OUT_Buf;
+
+	_printf(_L("\n"));
+	_printf(_L("+-----------------------------------------+\n"));
+	_printf(_L("|+---------------------------------------+|\n"));
+	_printf(_L("|| This test listens for data on the ACM ||\n"));
+	_printf(_L("|| (Bulk OUT) data port   .              ||\n"));
+	_printf(_L("||                                       ||\n"));
+	_printf(_L("|| Once running, Press any key to quit.  ||\n"));
+	_printf(_L("|+---------------------------------------+|\n"));
+	_printf(_L("+------------------------------------[rjf]+\n"));
+	_printf(_L("\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	// prime the console for the abandon-ship
+
+	console->Read(consoleStatus);
+	
+	TInt uReadCount = 0 ;
+	//TInt uThermoBar = 0 ; // TODO: speed enhancement! (remove ThermoBar fnality)
+
+	_printf(_L("\tWatch :  "));
+
+	TInt uAvgCount = 0 ;
+	TInt uNumReads = 0 ;
+	TInt uNumRooms = 0 ;
+
+	while (1)
+		{
+		// setup read to collect a single block by whatever method
+		// has been selected.
+
+		if( bReadCall )
+			{
+			port.Read(status, OUT_Buf, KChunkSize); // TODO: speed enhancement!
+
+			uNumReads++ ;
+			}
+		else
+			{
+			port.ReadOneOrMore(status, OUT_Buf);
+
+			uNumRooms++ ;
+			}
+
+		// either the read is complete, or user request to stop the test
+
+		User::WaitForRequest(status,consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			// still waiting for keypress, so it must have been the read
+			// that completed, check if it worked OK
+
+			if (status != KErrNone)
+				{
+				console->ReadCancel();
+
+				LEAVE(status.Int());
+				}
+
+			// reassure watcher that there is something happening...
+
+			if( uAvgCount == 0 )
+				{
+				uAvgCount = OUT_Buf.Length() ;
+				}
+			else
+				{
+				uAvgCount = ( ( 9 * uAvgCount ) + OUT_Buf.Length() ) / 10 ;
+				}
+
+			uReadCount += OUT_Buf.Length() ;
+
+/*			if( uReadCount >= 1024 )
+				{
+				// uThermoBar runs from 0..63
+
+				uThermoBar = ( uThermoBar + 1 ) & 0x3F ;
+
+				if( uThermoBar < 32 )
+					{
+					_printf(_L("*"));
+					}
+				else
+					{
+					_printf(_L("\b \b"));
+					}
+
+				uReadCount -= 1024 ;
+				}
+				*/
+			}
+		else
+			{
+			// user must have wanted to stop, shut down the reader
+
+			_printf(_L("\n"));
+			_printf(_L("\n"));
+			_printf(_L("\nReads=%d, Rooms=%d, Average Count=%d"),uNumReads,uNumRooms,uAvgCount);
+			_printf(_L("\n"));
+
+			_printf(_L("\n\n\tCancelling Read()"));
+
+			port.ReadCancel();
+
+			_printf(_L("\n\n\tRead() Cancelled"));
+
+			break;
+			}
+		}
+
+	_printf(_L("\n"));
+	_printf(_L("\tBulk OUT says bye..."));
+	_printf(_L("\n"));
+
+	CleanupStack::PopAndDestroy(); // port	
+	}
+
+/////////////////////////////////////////////////////////////////////////////////
+
+void Bulk_IN_TestL()
+	{
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm port;
+
+//#define uInBufSize 4096 // TODO: speed enhancement! reduce number of IPC calls
+#define uInBufSize 65536
+
+	static TBuf8<uInBufSize> IN_Buf;
+	static TBuf8<uInBufSize> ZLP_Buf;
+
+	_printf(_L("\n"));
+	_printf(_L("+-------------------------------------+\n"));
+	_printf(_L("|+-----------------------------------+|\n"));
+	_printf(_L("|| This test writes data on the ACM  ||\n"));
+	_printf(_L("|| (Bulk IN) data port               ||\n"));
+	_printf(_L("||                                   ||\n"));
+	_printf(_L("|| On running, Press any key to quit ||\n"));
+	_printf(_L("|+-----------------------------------+|\n"));
+	_printf(_L("+--------------------------------[rjf]+\n"));
+	_printf(_L("\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	// set up the ZLP and set a default pattern into the buffer
+
+	ZLP_Buf.SetLength(0) ;
+
+	IN_Buf.SetLength( uInBufSize ) ;
+
+	int j = 0 ;
+
+	for( int i = 0 ; i < uInBufSize ; i++ )
+		{
+		if( ( i % 64 ) == 0 )
+			{
+			j++;
+			}
+
+		switch( i % 64 )
+			{
+		case 0 :
+			IN_Buf[i] = 0xFF ;
+			break ;
+		case 1 :
+			IN_Buf[i] = j / 256 ;
+			break ;
+		case 2 :
+			IN_Buf[i] = j % 256 ;
+			break ;
+		case 3 :
+			IN_Buf[i] = 0xFF ;
+			break ;
+		default:
+			IN_Buf[i] = i ;
+			break ;
+			}
+		}
+
+	// prime the console for the abandon-ship
+
+	console->Read(consoleStatus);
+
+	TInt bDoneBlock = EFalse ;
+
+	TInt bNeedZLP = bUseZLP && ((IN_Buf.Length()%64)==0);
+
+	TInt uWriteCount = 0 ;
+//	TInt uThermoBar = 0 ; // TODO: speed enhancement!
+
+	_printf(_L("\tWatch :  "));
+
+	while (1)
+		{
+		// setup write to send a single block, this is either the
+		// block in the buffer, or else may be a ZLP which is sent
+		// on every other pass, provided the size of the block is
+		// exactly N*64
+
+		if( bDoneBlock && bNeedZLP )
+		{
+			port.Write(status, ZLP_Buf);
+
+			bDoneBlock = EFalse;
+		}
+		else
+		{
+			port.Write(status, IN_Buf);
+
+			uWriteCount += IN_Buf.Length() ;
+
+			bDoneBlock = ETrue;
+		}
+
+		// either the write is complete, or user request to stop the test
+
+		User::WaitForRequest(status,consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				console->ReadCancel();
+
+				LEAVE(status.Int());
+				}
+
+			// reassure watcher that there is something happening...
+
+/*			while( uWriteCount >= 1024 )
+				{
+				// uThermoBar runs from 0..63
+
+				uThermoBar = ( uThermoBar + 1 ) & 0x3F ;
+
+				if( uThermoBar < 32 )
+					{
+					_printf(_L("*"));
+					}
+				else
+					{
+					_printf(_L("\b \b"));
+					}
+  
+				uWriteCount -= 1024 ;
+				}
+				*/
+			}
+		else
+			{
+			_printf(_L("\n\n\tCancelling Write()"));
+
+			port.WriteCancel();
+
+			_printf(_L("\n\n\tWrite() Cancelled"));
+
+			break;
+			}
+		}
+
+	_printf(_L("\n"));
+	_printf(_L("\tBulk IN says bye..."));
+	_printf(_L("\n"));
+
+	CleanupStack::PopAndDestroy(); // port	
+	}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void SetHandshakingL()
+	{
+	RComm port;
+
+	TCommCaps capsBuf;
+	TCommCapsV01& caps = capsBuf();
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.Caps(capsBuf);
+
+	_printf(_L("\nPort handshaking capabilities: 0x%08X\n"), caps.iHandshake);
+	_printf(_L("\nCurrent handshaking options:   0x%08X\n"), TheConfig.iHandshake);
+
+	_printf(_L("\n"));
+
+#define HS(b) _printf(_L("\tTheConfig.%s = %s\n"), #b, ((TheConfig.iHandshake & b) == b) ? "Set" : "Clear" ) ;
+
+	HS(KConfigObeyXoff);
+	HS(KConfigSendXoff);
+	HS(KConfigObeyCTS);
+	HS(KConfigObeyDSR);
+	HS(KConfigFreeRTS);
+	HS(KConfigWriteBufferedComplete);
+
+	_printf(_L("\n\n"));
+	_printf(_L("Handshaking options:\n\n"));
+	_printf(_L("1. No handshaking\n"));
+	_printf(_L("2. Toggle Xon/Xoff\n"));
+	_printf(_L("3. Toggle obey CTS\n"));
+	_printf(_L("4. Toggle obey DSR / free RTS\n"));
+	_printf(_L("5. Toggle write buffered complete\n"));
+
+	TKeyCode key = console->Getch();
+
+	switch (key)
+		{
+	case '1':
+		TheConfig.iHandshake = 0;
+		break;
+	case '2':
+		TheConfig.iHandshake ^= KConfigObeyXoff;
+		TheConfig.iHandshake ^= KConfigSendXoff;
+		break;
+	case '3':
+		TheConfig.iHandshake ^= KConfigObeyCTS;
+		break;
+	case '4':
+		TheConfig.iHandshake ^= KConfigObeyDSR;
+		TheConfig.iHandshake ^= KConfigFreeRTS;
+		break;
+	case '5':
+		TheConfig.iHandshake ^= KConfigWriteBufferedComplete;
+		break;
+	default:
+		break;
+		}
+
+	LEAVEIFERROR(port.SetConfig(TheConfigBuf));
+
+	_printf(_L("Handshaking options now: 0x%X\n"), TheConfig.iHandshake);
+
+	CleanupStack::PopAndDestroy();
+	}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void RestartUsbL()
+	{
+	TheUsb.Stop();
+
+	TRequestStatus status;
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("Restarted USB.\n"));
+	}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/*void ThermoBar()
+	{
+	TUint uCol = 0 ;
+
+	TTime		now;
+
+	TDateTime	WasDT;
+	TDateTime	NowDT;
+
+	now.HomeTime(); 
+	WasDT = now.DateTime();
+
+	for( TUint line = 0 ; line < 30 ; )
+		{
+		for( TUint dotO = 0 ; dotO < 1000 ; dotO++ )
+			{
+			for( TUint dotI = 0 ; dotI < 1000 ; dotI++ )
+				{
+				;
+				}
+			}
+
+		_printf(_L("*"));
+
+		now.HomeTime(); 
+		NowDT = now.DateTime();
+
+		if( ( ++uCol >= 79 ) || ( WasDT.Second() != NowDT.Second() ) )
+			{
+			_printf(_L("\n"));
+
+			uCol = 0 ;
+
+			line++ ;
+
+			WasDT = now.DateTime() ;
+			}
+		}
+	}
+*/
+////////////////////////////////////////////////////////////////////////////////
+
+void ToggleTermL()
+	{
+	bUseTerm = ( bUseTerm == EFalse ) ;
+
+	if( bUseTerm )
+		{
+		TheConfig.iTerminatorCount = 1 ;
+
+		TheConfig.iTerminator[0] = 0x7E ;
+		}
+	else
+		{
+		TheConfig.iTerminatorCount = 0 ;
+		}
+	}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void mainL()
+	{
+	_printf(_L("\n"));
+	_printf(_L("+--------------------------------+\n"));
+	_printf(_L("|+------------------------------+|\n"));
+	_printf(_L("|| T_CATC : V1.00 : 25-Feb-2003 ||\n"));
+	_printf(_L("|+------------------------------+|\n"));
+	_printf(_L("+---------------------------[rjf]+\n"));
+	_printf(_L("\n"));
+
+	TInt ret = User::LoadLogicalDevice(KUsbLddName);
+	if ((ret != KErrNone) && (ret != KErrAlreadyExists))
+		LEAVE(ret);
+
+	_printf(_L("Loaded USB LDD\n"));
+
+	ret = StartC32();
+	if ((ret != KErrNone) && (ret != KErrAlreadyExists))
+		LEAVE(ret);
+
+	_printf(_L("Started C32\n"));
+
+	LEAVEIFERROR(TheUsb.Connect());
+
+	_printf(_L("Connected to USB Manager\n"));
+
+	_printf(_L("\n"));
+	_printf(_L("+-------------------------------------+\n"));
+	_printf(_L("|+-----------------------------------+|\n"));
+	_printf(_L("|| Please connect the USB cable now! ||\n"));
+	_printf(_L("|+-----------------------------------+|\n"));
+	_printf(_L("+--------------------------------[rjf]+\n"));
+	_printf(_L("\n"));
+
+	TRequestStatus status;
+
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("Started USB\n"));
+
+	LEAVEIFERROR(TheCommServ.Connect());
+
+	_printf(_L("Connected to C32\n"));
+
+	RComm port;
+
+	// The port's configuration seems to be junk at the beginning, so we set it to known values.
+
+	TheConfig.iRate = EBps115200;
+	TheConfig.iDataBits = EData8;
+	TheConfig.iStopBits = EStop1;
+	TheConfig.iParity = EParityNone;
+	TheConfig.iHandshake = 0;
+	TheConfig.iTerminatorCount = 0;
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+
+	CleanupStack::PopAndDestroy(); // port
+
+	TBool exit = EFalse;
+
+#define SHOW(h,l,t,f)						\
+	{										\
+		_printf(_L("\n  "));				\
+		_printf(_L(h));						\
+		_printf(_L("\t"));					\
+											\
+		if( l )								\
+		{									\
+			_printf(_L(t));					\
+		}									\
+		else								\
+		{									\
+			_printf(_L(f));					\
+		}									\
+											\
+		_printf(_L("\n"));					\
+	}
+
+	while (!exit)
+		{
+		_printf(_L("\n"));
+		_printf(_L("Current Settings:\n"));
+		_printf(_L("\n"));
+		SHOW("OUT Method", bReadCall,"Read()","ReadOneOrMore()");
+		SHOW("ZLP Method", bUseZLP,  "Active","Suppressed"     );
+		SHOW("Term Method",bUseTerm, "Active","Suppressed"     );
+		_printf(_L("\n"));
+		_printf(_L("Available tests:    \n"));
+		_printf(_L("\n"));
+		_printf(_L("1. Bulk OUT test    \n"));
+		_printf(_L("2. Bulk IN  test    \n"));
+		_printf(_L("3. Set handshaking  \n"));
+		_printf(_L("4. Restart USB      \n"));
+//		_printf(_L("5. Run ThermoBar    \n"));
+		_printf(_L("6. Swap Read Method \n"));
+		_printf(_L("7. Swap ZLP Method  \n"));
+		_printf(_L("8. Swap Term Method \n"));
+		_printf(_L("\n"));
+		_printf(_L("Select (q to quit): "));
+
+		char ch = (char) _getch();
+		_printf(_L("\n"));
+
+		switch (ch)
+			{
+		case '1': Bulk_OUT_TestL();							break;
+		case '2': Bulk_IN_TestL();							break;
+		case '3': SetHandshakingL();						break;
+		case '4': RestartUsbL();							break;
+//		case '5': ThermoBar();								break;
+		case '6': bReadCall = ( bReadCall == EFalse ) ;		break;
+		case '7': bUseZLP   = ( bUseZLP == EFalse ) ;		break;
+		case '8': ToggleTermL() ;							break;
+
+		case 'q':
+		case 'Q':
+			exit = ETrue;
+			break;
+
+		default:
+			_printf(_L("\nInvalid key\n"));
+			break;
+			}
+		}
+
+	TheCommServ.Close();
+	TheUsb.Close();
+	}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void consoleMainL()
+	{
+	console=Console::NewL(_L("T_ACM"),TSize(KConsFullScreen,KConsFullScreen));
+	CleanupStack::PushL(console);
+	mainL();
+	_printf(_L("[ press any key ]"));
+	_getch();
+	CleanupStack::PopAndDestroy();
+	}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanupStack=CTrapCleanup::New();
+	TRAP_IGNORE(consoleMainL());
+	delete cleanupStack;
+	__UHEAP_MARKEND;
+	return 0;
+	}
+
+////////////////////////////////////////////////////////////////////////////////
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_arm/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,22 @@
+/*
+* 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 "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:
+*
+*/
+
+PRJ_TESTEXPORTS
+t_usbchargingarm.iby       \epoc32\rom\include\t_usbchargingarm.iby
+
+PRJ_TESTMMPFILES
+t_usbchargingarm.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_arm/group/t_usbchargingarm.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+#ifndef __T_USBCHARGINGARM_IBY__
+#define __T_USBCHARGINGARM_IBY__
+
+// t_usbchargingarm.iby
+// USB Charging active test to be run on the ARM boards
+
+// *** Test executable
+file=ABI_DIR\UDEB\tusbchargingarm.exe    System\Programs\tusbchargingarm.exe
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_arm/group/t_usbchargingarm.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,54 @@
+/*
+* 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 "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:
+*
+*/
+
+TARGETTYPE		exe
+// UID2 = 0x0 for plain exes
+// UID3 = 0
+UID 			0x0 0
+
+TARGET			tusbchargingarm.exe        
+
+CAPABILITY		ALL -Tcb
+
+SOURCEPATH              ../src
+SOURCE			activetest.CPP
+SOURCE			activeconsole.CPP
+SOURCE			testbase.CPP
+
+// -- Add specific test files here.
+SOURCE			usbchargingarmtest.cpp
+// -- End
+
+USERINCLUDE             ../inc
+USERINCLUDE             ../../../usbmgr/usbman/chargingplugin/public
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY			euser.lib
+LIBRARY			usbman.lib
+LIBRARY			c32.lib
+LIBRARY 		btextnotifiers.lib
+LIBRARY			bluetooth.lib
+LIBRARY			esock.lib
+LIBRARY			efsrv.lib
+LIBRARY			btdevice.lib
+LIBRARY			btmanclient.lib
+LIBRARY			gavdp.lib
+LIBRARY			bluetoothav.lib
+// -- Add specific libraries here
+LIBRARY			centralrepository.lib
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_arm/inc/Tests.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,48 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef __TESTS_H__
+#define __TESTS_H__
+
+// -- Add specific test header files here.
+#include "usbchargingarmtest.h"
+// -- End
+
+class CTestBase;
+
+struct TTestDefinition
+	{
+	TTestDefinition(const TDesC8& aDescription, CTestBase* (*aFactoryL)(MTestManager&));
+
+	TBuf8<256> iDescription;
+	CTestBase* (*iFactoryL)(MTestManager&);
+	};
+
+TTestDefinition::TTestDefinition(const TDesC8& aDescription, CTestBase* (*aFactoryL)(MTestManager&))
+	{
+	iDescription = aDescription;
+	iFactoryL = aFactoryL;
+	}
+
+TTestDefinition gTestDefinitions[] = 
+	{
+// -- Add information about specific tests here
+		TTestDefinition(_L8("Test 1 (USBChargingARMTest)"), CUsbChargingArmTest::NewL),
+// -- End
+	};
+
+#endif // __TESTS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_arm/inc/activeconsole.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,66 @@
+/*
+* 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 "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 <e32base.h>
+#include <e32keys.h>
+#include "testmanager.h"
+
+class CTestBase;
+class CConsoleBase;
+
+class CActiveConsole : public CActive, public MTestManager
+/**
+ * Active Object console class. This is the means by which the user interacts 
+ * with the program.
+ */
+	{
+public:
+	static CActiveConsole* NewLC(CConsoleBase& aConsole);
+	~CActiveConsole();
+
+public:
+	void RequestCharacter();
+	TKeyCode Getch();
+
+private:
+	CActiveConsole(CConsoleBase& aConsole);
+	void ConstructL();
+
+private: // utility
+	void SelectTestL();
+	void StopCurrentTest();
+	void DisplayMainMenu();
+	void DoActionKeyL(TKeyCode aKey);
+
+private: // from MTestManager
+	void TestFinished();
+	void Write(TRefByValue<const TDesC8> aFmt, ...);
+	void WriteNoReturn(TRefByValue<const TDesC8> aFmt, ...);
+	void GetNumberL(TUint& aNumber);
+
+private: // from CActive
+	void RunL();
+	void DoCancel();
+	TInt RunError(TInt aError);
+
+private: // owned
+	CTestBase* iTest;
+	TBuf8<10> iInputBuffer;
+
+private: // unowned
+	CConsoleBase& iConsole;
+	};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_arm/inc/testbase.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,57 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef __TESTBASE_H__
+#define __TESTBASE_H__
+
+#include <e32base.h>
+#include <e32keys.h>
+
+class MTestManager;
+
+#define LeaveIfErrorL(aError) \
+	{ \
+	if ( aError ) \
+		{ \
+		iManager.Write(_L8("LEAVE: line %d, code %d"), __LINE__, aError); \
+		User::Leave(aError); \
+		} \
+	} 
+
+class CTestBase : public CBase
+/**
+ * Abstract base class for tests.
+ */
+	{
+public:
+	CTestBase(MTestManager& aManager);
+	~CTestBase();
+
+public:
+	// Tests may implement either of these to pick up user selections. 
+	// Single-key entries require you to implement the TKeyCode overload; 
+	// multi-key selections require you to implement the descriptor overload.
+	virtual void ProcessKeyL(TKeyCode aKeyCode);
+	virtual void ProcessKeyL(const TDesC8& aString);
+
+	virtual void DisplayTestSpecificMenu() = 0;
+
+protected: // unowned
+	MTestManager& iManager;
+	};
+
+#endif // __TESTBASE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_arm/inc/testmanager.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,45 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef __TESTMANAGER_H__
+#define __TESTMANAGER_H__
+
+#include <e32std.h>
+#include <e32keys.h>
+
+class MTestManager
+	{
+public:
+	/**
+	Called when a test finishes.
+	*/
+	virtual void TestFinished() = 0;
+
+	/**
+	Called to display some text.
+	*/
+	virtual void Write(TRefByValue<const TDesC8> aFmt, ...) = 0;
+	virtual void WriteNoReturn(TRefByValue<const TDesC8> aFmt, ...) = 0;
+
+	/**
+	Read a user-inputted number.
+	aNumber should be initialised before calling.
+	*/
+	virtual void GetNumberL(TUint& aNumber) = 0;
+	};
+
+#endif // __TESTMANAGER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_arm/inc/usbchargingarmtest.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,49 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef __USBCHARGINGARM_H__
+#define __USBCHARGINGARM_H__
+
+#include "testbase.h"
+#include <e32property.h>
+#include <usbman.h>
+#include <centralrepository.h>
+
+/**
+*/
+class CUsbChargingArmTest : public CTestBase 
+	{
+public:
+	static CTestBase* NewL(MTestManager& aManager);
+	~CUsbChargingArmTest();
+
+private:
+	CUsbChargingArmTest(MTestManager& aManager);
+	void ConstructL();
+
+private: // from CTestBase
+	void ProcessKeyL(TKeyCode aKeyCode);
+	void DisplayTestSpecificMenu();
+
+private: // owned
+	CRepository*	iRepository;
+	TUid		iRepositoryUid;
+	TUint		iId;
+	RUsb iUsbMan;
+	};
+
+#endif // __USBCHARGINGARM_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_arm/src/activeconsole.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,317 @@
+/*
+* 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 "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 <e32twin.h>
+#include <e32svr.h>
+#include "activeconsole.h"
+#include "testbase.h"
+#include "tests.h"
+
+CActiveConsole::CActiveConsole(CConsoleBase& aConsole)
+ :	CActive(CActive::EPriorityStandard),
+	iConsole(aConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CActiveConsole* CActiveConsole::NewLC(CConsoleBase& aConsole)
+	{
+	CActiveConsole* self = new(ELeave) CActiveConsole(aConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	self->DisplayMainMenu();
+	return self;
+	}
+
+void CActiveConsole::ConstructL()
+	{
+	// Launch of FDTest test.
+	iTest = gTestDefinitions[0].iFactoryL(*this);
+	}
+
+CActiveConsole::~CActiveConsole()
+	{
+	Cancel();
+
+	StopCurrentTest();
+	}
+
+void CActiveConsole::DoCancel()
+	{
+	iConsole.ReadCancel();
+	}
+
+void CActiveConsole::StopCurrentTest()
+	{
+	delete iTest;
+	iTest = NULL;
+	}
+
+void CActiveConsole::RunL()
+// Only process when we get a return, otherwise cache- i.e. support multi-character selections
+	{
+	DoActionKeyL(iConsole.KeyCode());
+
+	// Repost asynchronous request.
+	RequestCharacter();
+	}
+
+void CActiveConsole::DoActionKeyL(TKeyCode aKeyCode)
+	{
+	WriteNoReturn(_L8("%c"), aKeyCode);
+
+	// Examine the key that just came in.
+	switch ( TUint(aKeyCode) )
+		{
+	case EKeyEscape:
+		{
+		Write(_L8("Exiting"));
+		CActiveScheduler::Stop();
+		return;
+		}
+
+	case EKeyEnter:
+		// Tell the test about what's in the buffer so far, if anything.
+		Write(_L8("You entered \'%S\'"), &iInputBuffer);
+		switch ( iInputBuffer.Length() )
+			{
+		case 0:
+			// Don't pass anything on- nothing to pass on.
+			break;
+
+		case 1:
+			if ( 	iInputBuffer == _L8("S") 
+				||	iInputBuffer == _L8("s") 
+				)
+				{
+				StopCurrentTest();
+				}
+			else
+				{
+				// Tell the test via the old 'single character' interface.
+				// If there is a test, then let it process the key. If there isn't a 
+				// test, we process it to (possibly) create and run a new test object.
+				if ( iTest )
+					{
+					TRAPD(err, iTest->ProcessKeyL((TKeyCode)iInputBuffer[0]));
+					if ( err )
+						{
+						Write(_L8("CTestBase::ProcessKeyL left with %d"), err);
+						StopCurrentTest();
+						}
+					}
+				else
+					{
+					SelectTestL();
+					}
+				}
+			iInputBuffer = KNullDesC8();
+			break;
+		
+		default:
+			// Tell the test via the new 'multi character' interface.
+			// If there is a test, then let it process the key. If there isn't a 
+			// test, we process it to (possibly) create and run a new test object.
+			if ( iTest )
+				{
+				TRAPD(err, iTest->ProcessKeyL(iInputBuffer));
+				if ( err )
+					{
+					Write(_L8("CTestBase::ProcessKeyL left with %d"), err);
+					StopCurrentTest();
+					}
+				}
+			else
+				{
+				SelectTestL();
+				}
+			iInputBuffer = KNullDesC8();
+			break;
+			}
+		DisplayMainMenu();
+		break;
+
+	default:
+		iInputBuffer.Append(aKeyCode);
+		break;
+		}
+	}
+
+void CActiveConsole::RequestCharacter()
+	{
+	iConsole.Read(iStatus);
+	SetActive();
+	}
+
+void CActiveConsole::DisplayMainMenu()
+	{
+	Write(KNullDesC8);
+
+	// If there's a current test, display its step menu. Otherwise, display 
+	// all the available tests.
+	if ( iTest )
+		{
+		iTest->DisplayTestSpecificMenu();
+		Write(_L8("s - stop and close current test"));
+		}
+	else
+		{
+		const TUint numberOfTests = sizeof(gTestDefinitions) / sizeof(TTestDefinition);
+		for ( TUint ii = 0 ; ii < numberOfTests ; ii ++ )
+			{
+			Write(_L8("%d - %S"), ii, &gTestDefinitions[ii].iDescription);
+			}
+		}
+
+	Write(_L8("Escape - exit program"));
+	Write(KNullDesC8);
+ 	}
+
+void CActiveConsole::Write(TRefByValue<const TDesC8> aFmt, ...)
+	{
+	VA_LIST list;
+	VA_START(list, aFmt);
+
+	TBuf8<0x100> buf;
+	buf.AppendFormatList(aFmt, list);
+	TBuf<0x100> wideBuf;
+	wideBuf.Copy(buf);
+	iConsole.Write(wideBuf);
+	iConsole.Write(_L("\n"));
+
+	RDebug::Print(wideBuf);
+	}
+
+void CActiveConsole::WriteNoReturn(TRefByValue<const TDesC8> aFmt, ...)
+	{
+	VA_LIST list;
+	VA_START(list, aFmt);
+
+	TBuf8<0x100> buf;
+	buf.AppendFormatList(aFmt, list);
+	TBuf<0x100> wideBuf;
+	wideBuf.Copy(buf);
+	iConsole.Write(wideBuf);
+
+	RDebug::Print(wideBuf);
+	}
+
+TKeyCode CActiveConsole::Getch()
+	{
+	return iConsole.Getch();
+	}
+
+void CActiveConsole::SelectTestL()
+	{
+	StopCurrentTest();
+
+	// Pick a test out of the global array of tests.
+	const TUint numberOfTests = sizeof(gTestDefinitions) / sizeof (TTestDefinition);
+	TLex8 lex(iInputBuffer);
+	TUint index;
+	TInt err = lex.Val(index);
+
+	if (	err == KErrNone
+		&&	index < numberOfTests
+		)
+		{
+		iTest = gTestDefinitions[index].iFactoryL(*this);
+		}
+	else
+		{
+		Write(_L8("Unknown selection"));
+		}
+	}
+
+void CActiveConsole::TestFinished()
+/**
+ * Called by the test when it has finished. Results in the destruction of the 
+ * test.
+ */
+	{
+	StopCurrentTest();
+	}
+
+TInt CActiveConsole::RunError(TInt aError)
+/**
+ * Called by the Active Scheduler when a RunL in this active object leaves.
+ */
+	{
+	// This actually happens when a test object fails to construct properly.
+	Write(_L8("Error creating test object: %d"), aError);
+
+	iInputBuffer = KNullDesC8();
+	DisplayMainMenu();
+
+	// It's OK to carry on with the program itself, so repost asynchronous 
+	// request.
+	RequestCharacter();
+
+	return KErrNone;
+	}
+
+void CActiveConsole::GetNumberL(TUint& aNumber)
+	{
+	TBuf<12> addrAsText;
+	addrAsText.Zero();
+	if ( aNumber != 0 )
+		{
+		addrAsText.Format(_L("%d"), aNumber);
+		}
+	WriteNoReturn(_L8("Enter a number: "));
+	if ( addrAsText.Length() > 0 )
+		{
+		TBuf8<100> narrowBuf;
+		narrowBuf.Copy(addrAsText);
+		WriteNoReturn(narrowBuf);
+		}
+	TKeyCode code;
+	TBuf<1> character;
+	FOREVER
+		{
+		code = Getch();
+		character.SetLength(0);
+		character.Append(code);
+	
+		// If <CR> finish editing string
+		if (code == 0x0d)
+			break;
+		
+		// if <BS> remove last character
+		if ((code == 0x08)&&(addrAsText.Length() != 0))
+			{
+			WriteNoReturn(_L8("%S"),&character);
+			addrAsText.SetLength((addrAsText.Length()-1));
+			}
+		else
+			{
+			if (addrAsText.Length() < addrAsText.MaxLength())
+				{
+				WriteNoReturn(_L8("%S"),&character);
+				addrAsText.Append(code);
+				}
+			}
+		}
+	//now extract the new address from the string...
+	if( !addrAsText.Length() )
+		{
+		addrAsText.Append('0'); //null string causes TLex::Val to return an error
+		}
+	TLex lex(addrAsText);
+	TInt err = lex.Val(aNumber, EDecimal);
+	User::LeaveIfError(err);
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_arm/src/activetest.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,55 @@
+/*
+* 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 "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 <e32base.h>
+#include <e32cons.h>
+#include <e32test.h>
+#include <e32twin.h>
+#include "activeconsole.h"
+
+LOCAL_C void ActiveTestL()
+    {
+	CConsoleBase* console = Console::NewL(_L("ACTIVETEST"), TSize(KConsFullScreen, KConsFullScreen));
+	CleanupStack::PushL(console);
+
+	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
+	CleanupStack::PushL(scheduler);
+	CActiveScheduler::Install(scheduler);
+
+	CActiveConsole* activeConsole = CActiveConsole::NewLC(*console);
+	activeConsole->RequestCharacter();
+	CActiveScheduler::Start();
+	// NB CActiveScheduler::Start only returns when someone somewhere has 
+	// called CActiveScheduler::Stop.
+
+	CleanupStack::PopAndDestroy(2); // activeConsole, scheduler
+
+	console->Printf(_L("\nPress any key"));
+	console->Getch(); // get and ignore character
+	CleanupStack::PopAndDestroy(); // console
+	}
+
+GLDEF_C TInt E32Main()
+    {
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	TRAPD(error, ActiveTestL());
+	__ASSERT_ALWAYS(!error, User::Panic(_L("E32Main"), error));
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return KErrNone;
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_arm/src/testbase.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/*
+* 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 "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 "testbase.h"
+#include "testmanager.h"
+
+CTestBase::CTestBase(MTestManager& aManager)
+ :	iManager(aManager)
+	{
+	}
+
+CTestBase::~CTestBase()
+	{
+	}
+
+void CTestBase::ProcessKeyL(TKeyCode /*aKeyCode*/)
+	{
+	}
+
+void CTestBase::ProcessKeyL(const TDesC8& /*aString*/)
+	{
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_arm/src/usbchargingarmtest.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,151 @@
+/*
+* 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 "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 "usbchargingarmtest.h"
+#include <usb/usblogger.h>
+#include <e32cmn.h>
+#include "usbbatterycharging.h"
+#include "testmanager.h"
+
+CUsbChargingArmTest::CUsbChargingArmTest(MTestManager& aManager)
+ :	CTestBase(aManager)
+	{
+	}
+
+CTestBase* CUsbChargingArmTest::NewL(MTestManager& aManager)
+	{
+	CUsbChargingArmTest* self = new(ELeave) CUsbChargingArmTest(aManager);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+void CUsbChargingArmTest::ConstructL()
+	{
+
+	// -- Insert initialization code here
+	iRepository = CRepository::NewL(KUsbBatteryChargingCentralRepositoryUid);
+	iId = KUsbBatteryChargingKeyEnabledUserSetting;
+
+	}
+
+CUsbChargingArmTest::~CUsbChargingArmTest()
+	{
+	iManager.Write(_L8("CUsbChargingArmTest::~CUsbChargingArmTest"));
+
+	// -- Insert cleanup code here
+	delete iRepository;
+	}
+
+void CUsbChargingArmTest::ProcessKeyL(TKeyCode aKeyCode)
+	{
+	iManager.Write(_L8("CUsbChargingArmTest::ProcessKeyL"));
+
+	switch ( aKeyCode )
+		{
+	case '0':
+		{
+		iManager.Write(_L8("About to connect to USBMan"));
+		TInt res = iUsbMan.Connect();
+		if(res != KErrNone)
+			{
+			iManager.Write(_L8("Connection to USBMan failed"));
+			}
+		else
+			{
+			iManager.Write(_L8("Now connected to USBMan"));
+			}
+		}
+		break;
+
+	case '1':
+		{
+		iManager.Write(_L8("About to start USBMan"));
+		TRequestStatus requestStatus;
+		iUsbMan.Start(requestStatus);
+		User::WaitForRequest(requestStatus);
+		if(requestStatus.Int() == KErrNone)
+			{
+			iManager.Write(_L8("USBMan Started OK"));
+			}
+		else
+			{
+			iManager.Write(_L8("Failed to start USBMan"));
+			}
+		}
+		break;
+	case '2':
+		{
+		iManager.Write(_L8("About to stop USBMan"));
+		TRequestStatus requestStatus;
+		iUsbMan.Stop(requestStatus);
+		User::WaitForRequest(requestStatus);
+		if(requestStatus.Int() == KErrNone)
+			{
+			iManager.Write(_L8("USBMan Stopped OK"));
+			}
+		else
+			{
+			iManager.Write(_L8("Failed to stop USBMan"));
+			}
+		}
+		break;
+	case '3':
+		{
+		TInt state = KErrUnknown;
+		iRepository->Get(iId, state);
+		iManager.Write(_L8("CenRep Enable setting is: <%d>"), state);
+		}
+		break;
+	case '4':
+		{
+		TInt state = KErrUnknown;
+		iRepository->Get(iId, state);
+		iManager.Write(_L8("CenRep Enable setting is: <%d>"), state);
+		if(state == EUsbBatteryChargingUserSettingDisabled)
+			{
+			iRepository->Set(iId, EUsbBatteryChargingUserSettingEnabled);
+			}
+		else
+			{
+			iRepository->Set(iId, EUsbBatteryChargingUserSettingDisabled);
+			}
+		
+		iRepository->Get(iId, state);
+		iManager.Write(_L8("CenRep Enable setting is now: <%d>"), state);
+		}
+		break;
+
+
+	default:
+		iManager.Write(_L8("Unknown selection"));
+		break;
+		}
+	}
+
+void CUsbChargingArmTest::DisplayTestSpecificMenu()
+	{
+	iManager.Write(_L8("0 - RUsb::Connect"));
+	iManager.Write(_L8("1 - RUsb::Start"));
+	iManager.Write(_L8("2 - RUsb::Stop"));
+	iManager.Write(_L8("3 - CenRep Enable setting read"));
+	iManager.Write(_L8("4 - CenRep Enable setting toggle"));
+
+	// -- Add test titles here
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 1999-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:
+*
+*/
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_TESTEXPORTS
+../inc/dummyldd.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(dummyldd.h)
+../inc/CUsbBatteryChargingTestPlugin.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(usb/chargingtest/CUsbBatteryChargingTestPlugin.h)
+../src/t_charging.txt /epoc32/winscw/c/system/data/t_charging.txt
+../src/t_charging.txt /epoc32/data/z/system/data/t_charging.txt
+
+
+t_usbcharging.iby       /epoc32/rom/include/t_usbcharging.iby
+
+PRJ_TESTMMPFILES
+
+	tbatterycharging.mmp
+	tbatterychargingrepositorywriter.mmp
+	TestPlugin.mmp
+	TestPluginotg.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/group/TestPlugin.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,66 @@
+/*
+* 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 "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:
+* usbbatterychargingtestplugin.dll UsbMan extension plugin for battery charging, with test function.
+* usbbatterychargingtestplugin.rsc Resource file for charging plugin.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+TARGET			usbbatterychargingtestplugin.dll
+TARGETTYPE		PLUGIN
+// UID2 = 0x10009d8d for ECOM plugins.
+// UID3 = the 'DLL UID' (see resource file)
+UID 			0x10009d8d 0x1020DEA7
+VENDORID		0x70000001
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+
+SOURCEPATH      ../../../usbmgr/usbman/chargingplugin/src
+SOURCE			CUsbBatteryChargingPlugin.cpp
+SOURCE          chargingstates.cpp
+SOURCE			repositorynotifier.cpp
+SOURCE			reenumerator.cpp
+SOURCE			devicestatetimer.cpp
+SOURCE			vbuswatcher.cpp
+SOURCEPATH      ../src
+SOURCE			CUsbBatteryChargingTestPlugin.cpp
+
+START RESOURCE 1020DEA7.rss
+target usbbatterychargingtestplugin.rsc
+END
+
+USERINCLUDE		../inc ../../../usbmgr/usbman/chargingplugin/inc
+USERINCLUDE		../../../usbmgr/usbman/chargingplugin/inc/default
+USERINCLUDE		../../../usbmgr/usbman/chargingplugin/public
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY 		euser.lib 
+LIBRARY 		usbmanextensionplugin.lib 
+LIBRARY			centralrepository.lib
+
+#include <usb/usblogger.mmh>
+
+library	flogger.lib
+
+NOEXPORTLIBRARY
+
+//macro __USB_LOG_TO_RDEBUG__
+
+//macro __USB_LOGGING__
+
+macro __CHARGING_PLUGIN_TEST_CODE__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/group/TestPluginotg.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,70 @@
+/*
+* 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 "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:
+* usbbatterychargingtestplugin.dll UsbMan extension plugin for battery charging, with test function.
+* usbbatterychargingtestplugin.rsc Resource file for charging plugin.
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+TARGET			usbbatterychargingtestpluginotg.dll
+TARGETTYPE		PLUGIN
+// UID2 = 0x10009d8d for ECOM plugins.
+// UID3 = the 'DLL UID' (see resource file)
+UID 			0x10009d8d 0x1020DEA7
+VENDORID		0x70000001
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+
+SOURCEPATH      ../../../usbmgr/usbman/chargingplugin/src
+SOURCE			CUsbBatteryChargingPlugin.cpp
+SOURCE          chargingstates.cpp
+SOURCE			repositorynotifier.cpp
+SOURCE			reenumerator.cpp
+SOURCE			devicestatetimer.cpp
+SOURCE			vbuswatcher.cpp
+
+SOURCE			idpinwatcher.cpp
+SOURCE			otgstatewatcher.cpp
+SOURCEPATH      ../src
+SOURCE			CUsbBatteryChargingTestPlugin.cpp
+
+START RESOURCE 1020DEA7.rss
+target usbbatterychargingtestpluginotg.rsc
+END
+
+USERINCLUDE		../inc ../../../usbmgr/usbman/chargingplugin/inc
+USERINCLUDE		../../../usbmgr/usbman/chargingplugin/inc/default
+USERINCLUDE		../../../usbmgr/usbman/chargingplugin/public
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY 		euser.lib 
+LIBRARY 		usbmanextensionplugin.lib 
+LIBRARY			centralrepository.lib
+
+#include <usb/usblogger.mmh>
+
+library	flogger.lib
+
+NOEXPORTLIBRARY
+
+//macro __USB_LOG_TO_RDEBUG__
+
+//macro __USB_LOGGING__
+
+macro SYMBIAN_ENABLE_USB_OTG_HOST_PRIV
+macro __CHARGING_PLUGIN_TEST_CODE__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/group/t_usbcharging.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef __T_USBCHARGING_IBY__
+#define __T_USBCHARGING_IBY__
+
+// *** Manual Test executable
+file=ABI_DIR\USB_DIR\tbatterycharging.exe    System\Programs\tbatterycharging.exe
+file=ABI_DIR\USB_DIR\tbatterychargingrepositorywriter.exe    System\Programs\tbatterychargingrepositorywriter.exe
+
+// *** file needed for the manual test when built in ROM
+data=EPOCROOT##Epoc32\data\z\system\data\t_charging.txt	"system\data\t_charging.txt"
+
+
+// *** Test plug-in
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST) && defined (SYMBIAN_INCLUDE_USB_OTG_HOST)
+USB_PLUGIN(usbbatterychargingtestpluginotg.dll,usbbatterychargingtestpluginotg.rsc)
+#else
+USB_PLUGIN(usbbatterychargingtestplugin.dll,usbbatterychargingtestplugin.rsc)
+#endif
+data=EPOCROOT##epoc32\data\z\private\10202be9\10208DD7.txt private\10202be9\10208DD7.txt
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/group/tbatterycharging.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,48 @@
+/*
+* 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 "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:
+*
+*/
+
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ 
+targettype exe
+
+
+target tbatterycharging.exe
+
+uid 0x0 0x101fe1db 
+
+VENDORID 0x70000001
+
+
+sourcepath		../src
+source			tbatterycharging.cpp
+source			../../../usbmgr/usbman/server/SRC/UsbUtils.cpp
+
+
+userinclude		../inc ../../../usbmgr/usbman/chargingplugin/inc
+userinclude		../../../usbmgr/usbman/server/INC
+userinclude		../../../usbmgr/usbman/chargingplugin/public
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+lang			sc 01 02 03 10	// UK English, French, German, US English
+
+library			euser.lib 
+library			ecom.lib
+library			efsrv.lib
+library			bafl.lib
+library			usbmanextensionplugin.lib
+//LIBRARY			centralrepository.lib
+
+macro __CHARGING_PLUGIN_TEST_CODE__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/group/tbatterychargingrepositorywriter.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,49 @@
+/*
+* 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 "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:
+*
+*/
+
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ ReadDeviceData WriteDeviceData
+
+targettype exe
+
+
+target tbatterychargingrepositorywriter.exe
+
+uid 0x0 0x102834EB
+VENDORID 0x70000001
+
+sourcepath		../src
+source			activepropertysubscribercharging.cpp
+source			tpropertybatterycharging.cpp
+
+source			../../../usbmgr/usbman/server/SRC/UsbUtils.cpp
+
+userinclude		../inc ../../../usbmgr/usbman/chargingplugin/inc
+userinclude		../../../usbmgr/usbman/server/INC
+userinclude		../../../usbmgr/usbman/chargingplugin/public
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+lang			sc 01 02 03 10	// UK English, French, German, US English
+
+library			euser.lib 
+
+//library			ecom.lib
+//library			efsrv.lib
+//library			bafl.lib
+//library			usbmanextensionplugin.lib
+LIBRARY			centralrepository.lib
+
+macro __CHARGING_PLUGIN_TEST_CODE__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/inc/CUsbBatteryChargingTestPlugin.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,67 @@
+/*
+* 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 "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
+*/
+
+#ifndef USBBATTERYCHARGINGTESTPLUGIN_H
+#define USBBATTERYCHARGINGTESTPLUGIN_H
+
+#include <e32base.h>
+#include <dummyldd.h>
+#define __D32USBC_H__ // ensure that d32usbc is ignored
+
+#define private protected
+
+#include <usb/charging/cusbbatterychargingplugin.h>
+
+
+// define extension of the plugin, which includes an API to query the plugin state, etc.
+
+class TPluginTestInfo
+	{
+public:
+	TUint iAvailableMilliAmps;
+	TInt iPluginState;
+	TUsbDeviceState iDeviceState;
+	TUsbBatteryChargingUserSetting iUserSetting;
+	TInt iCurrentIndexRequested;
+	TUint iRequestedCurrentValue;
+	};
+
+class MUsbBatteryChargingTestPluginInterface2
+	{
+public:
+	virtual void GetPluginInfo(TPluginTestInfo& aInfo) = 0;
+	};
+
+const TUid KUidUsbBatteryChargingTestPluginInterface2 = {0x1020DEA6};
+
+class CUsbBatteryChargingTestPlugin :	public CUsbBatteryChargingPlugin,
+										public MUsbBatteryChargingTestPluginInterface2
+	{
+public:
+	static CUsbBatteryChargingTestPlugin* NewL(MUsbmanExtensionPluginObserver& aObserver);
+	CUsbBatteryChargingTestPlugin(MUsbmanExtensionPluginObserver& aObserver);
+	void GetPluginInfo(TPluginTestInfo& aInfo);
+	TAny* GetInterface(TUid aUid);
+	};
+
+
+#endif // USBBATTERYCHARGINGTESTPLUGIN_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/inc/activepropertysubscribercharging.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,101 @@
+/*
+* 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 "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
+ @prototype
+*/
+
+#ifndef ACTIVEPROPERTYSUBSCRIBERCHARGING_H
+#define ACTIVEPROPERTYSUBSCRIBERCHARGING_H
+
+#include <e32base.h>
+#include <e32property.h>
+
+
+NONSHARABLE_CLASS(MPropertyWriteRepositoryObserver)
+	{
+public:
+	virtual void MpsoPropertyWriteChanged(const TInt aValue) = 0;
+	};
+
+
+NONSHARABLE_CLASS(CActivePropertyWriteRepository) : public CActive
+	{
+public:
+	static CActivePropertyWriteRepository* NewL(MPropertyWriteRepositoryObserver& aObserver);
+	~CActivePropertyWriteRepository();
+
+public:
+	void Request();
+
+private:
+	CActivePropertyWriteRepository(MPropertyWriteRepositoryObserver& aObserver);
+	void ConstructL();
+
+private: // from CActive
+	void RunL();
+	void DoCancel();
+
+private: // utility
+	void HandleCompletionL(TInt aError);
+
+private: // unowned
+	MPropertyWriteRepositoryObserver& iObserver;
+
+private: // owned
+	RProperty iPropertyWriteToRepository;	
+	
+	};
+	
+NONSHARABLE_CLASS(MPropertyReadBatteryChargingCurrentObserver)
+	{
+public:
+	virtual void MpsoPropertyReadChanged() = 0;
+	};
+
+
+NONSHARABLE_CLASS(CActivePropertyReadChargingCurrent) : public CActive
+	{
+public:
+	static CActivePropertyReadChargingCurrent* NewL(MPropertyReadBatteryChargingCurrentObserver& aObserver);
+	~CActivePropertyReadChargingCurrent();
+
+public:
+	void Request();
+
+private:
+	CActivePropertyReadChargingCurrent(MPropertyReadBatteryChargingCurrentObserver& aObserver);
+	void ConstructL();
+
+private: // from CActive
+	void RunL();
+	void DoCancel();
+
+private: // utility
+	void HandleCompletionL(TInt aError);
+
+private: // unowned
+	MPropertyReadBatteryChargingCurrentObserver& iObserver;
+
+private: // owned
+	RProperty iPropertyReadChargingCurrent;	
+	
+	};
+
+#endif // ACTIVEPROPERTYSUBSCRIBERCHARGING_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/inc/dummyldd.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef __DUMMY_LDD_H__
+#define __DUMMY_LDD_H__
+
+static const TInt KDummyConfigDescSize = 9;
+
+/******
+ * NOTE: This dummy implementation of RDevUsbcClient is actually a C-class!!!!!!
+ */
+class RDevUsbcClient
+	{
+public:
+	// functions needed by charging plugin
+	inline TInt GetConfigurationDescriptor(TDes8& aConfigurationDescriptor);
+	inline TInt SetConfigurationDescriptor(const TDesC8& aConfigurationDescriptor);
+	inline TInt GetConfigurationDescriptorSize(TInt& aSize);
+	inline void ReEnumerate(TRequestStatus& aStatus);
+	inline void ReEnumerateCancel();
+
+	// used to initialise config desc.
+	inline void Initialise();
+private:
+	TBuf8<KDummyConfigDescSize> iConfigDesc;
+	};
+
+inline TInt RDevUsbcClient::GetConfigurationDescriptor(TDes8& aConfigurationDescriptor)
+	{
+	// 8th byte is bMaxPower
+	aConfigurationDescriptor.Copy(iConfigDesc);//[8] = iConfigDesc[8];
+	return KErrNone;
+	}
+
+inline TInt RDevUsbcClient::SetConfigurationDescriptor(const TDesC8& aConfigurationDescriptor)
+	{
+	// 8th byte is bMaxPower
+	iConfigDesc[8] = aConfigurationDescriptor[8];
+	return KErrNone;
+	}
+
+inline TInt RDevUsbcClient::GetConfigurationDescriptorSize(TInt& aSize)
+	{
+	aSize = KDummyConfigDescSize;
+	return KErrNone;
+	}
+
+inline void RDevUsbcClient::ReEnumerate(TRequestStatus& aStatus)
+	{
+	// just complete "synchronously". The plugin takes no notice of when this completes
+	// so we don't need to fake it ever failing
+	TRequestStatus* status = &aStatus;
+	User::RequestComplete(status, KErrNone);
+	}
+
+inline void RDevUsbcClient::ReEnumerateCancel()
+	{
+	// nothing to do, as ReEnumerate always completes "synchronously".
+	}
+
+inline void RDevUsbcClient::Initialise()
+	{
+	iConfigDesc.FillZ(KDummyConfigDescSize);
+	// 8th byte is bMaxPower
+	iConfigDesc[8] = 0;
+	}
+
+#endif // __DUMMY_LDD_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/inc/tbatterycharging.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,144 @@
+/**
+* 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 "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:
+* Usb Battery Charging test code
+* 
+*
+*/
+
+
+
+#ifndef __CDUMMYUSBDEVICE_H__
+#define __CDUMMYUSBDEVICE_H__
+
+#include <usb/chargingtest/cusbbatterychargingtestplugin.h>
+#include <usbstates.h>
+#include <ecom/ecom.h>
+#include <e32std.h>
+#include "musbmanextensionpluginobserver.h"
+#include "cusbmanextensionplugin.h"
+#include <e32test.h>
+#include <e32property.h> //Publish & Subscribe header
+
+class MUsbDeviceNotify;
+
+_LIT(KUsbChargingTestPanic, "UsbChargingTestPanic");
+enum TUsbChargingTestPanic
+	{
+	EUsbChargingTestPanicIncorrectPlugin = 0,
+	EUsbChargingTestPanicBadInputData	 = 1,
+	EUsbChargingTestPanicBadCommand		 = 2,
+	EUsbChargingTestPanicBadAsyncOp		 = 3,
+	EUsbChargingTestPanicBadCheck		 = 4,
+	};
+
+enum TUsbChargingTestCommand
+	{
+	EUsbChargingTestCommandNone		    = 0, // "none"
+	EUsbChargingTestCommandDeviceState  = 1, // "devicestate"
+	EUsbChargingTestCommandUserSetting  = 2, // "usersetting"
+	};
+
+enum TUsbChargingTestCheck
+	{
+	EUsbChargingTestCheckNone			= 0, // "none"
+	EUsbChargingTestCheckPluginState	= 1, // "pluginstate"
+	EUsbChargingTestCheckMilliAmps		= 2, // "milliamps" - requested current
+	EUsbChargingTestCheckCharging		= 3, // "charging" - available current
+	};
+
+enum TUsbChargingTestAsyncOp
+	{
+	EUsbChargingTestAsyncOpNone			= 0, // "none"
+	EUsbChargingTestAsyncOpDelay		= 1, // "delay" - microseconds
+	};
+
+class CDummyUsbDevice : public CActive, public MUsbmanExtensionPluginObserver
+	{
+public:
+	static CDummyUsbDevice* NewL();
+	virtual ~CDummyUsbDevice();
+
+	void RegisterObserverL(MUsbDeviceNotify& aObserver);
+	void DeRegisterObserver(MUsbDeviceNotify& aObserver);
+	
+	void DefinePropertyL(const TInt32 aCategory, TUint aKey,RProperty::TType eType);
+	TInt GetChargingCurrentFromProperty(TInt &aCurrent);
+	TInt WriteToRepositoryProperty(TInt iCommandValue);
+	
+	TInt StartPropertyBatteryCharging();
+
+	void DoTestsL();
+
+public: // From CActive
+	void RunL();
+	void DoCancel();
+	TInt RunError(TInt aError);
+
+protected:
+	CDummyUsbDevice();
+	void ConstructL();
+
+private:
+	void InstantiateExtensionPluginsL();
+	void UpdatePluginInfo();
+	void OpenFileL();
+	TInt GetNextLine();
+	void InterpretLine();
+	TInt GetCommand(const TDesC8& aDes);
+	TInt GetAsyncOp(const TDesC8& aDes);
+	TInt GetCheck(const TDesC8& aDes);
+	void DoCommand();
+	void DoAsyncOp();
+	void DoCheck();
+
+private: // from MUsbmanExtensionPluginObserver
+	RDevUsbcClient& MuepoDoDevUsbcClient();
+	void MuepoDoRegisterStateObserverL(MUsbDeviceNotify& aObserver);
+
+private:
+	RPointerArray<MUsbDeviceNotify> iObservers;
+	RPointerArray<CUsbmanExtensionPlugin> iExtensionPlugins;
+	// we know there'll only be one plugin, so keep a single pointer to it...
+	CUsbmanExtensionPlugin* iPlugin;
+	TUsbDeviceState  iDeviceState;
+	RDevUsbcClient iDummyLdd;
+	REComSession* iEcom;	//	Not to be deleted, only closed!
+
+	TPluginTestInfo iInfo;
+
+	RTest iTest;
+	RTimer iTimer;
+	//CRepository* iRepository;
+
+	TPtr8 iPtr; // data file
+	TPtr8 iLine; // current line
+	TInt  iLineNumber;
+	TInt iFileOffset;
+	TText8* iText;
+
+	TInt	iCommand;
+	TInt					iCommandValue;
+	TInt	iAsyncOp;
+	TInt					iAsyncOpValue;
+	TInt	iCheck;
+	TInt					iCheckValue;
+	
+	RProperty iPropertyWriteToRepositoryAck;
+	RProperty iPropertyReadChargingCurrentAck;
+	RProperty iProperty;
+	};
+
+#endif // __CDUMMYUSBDEVICE_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/inc/tbatterychargingdefinitions.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,49 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef TBATTERYCHARGINGDEFINITIONS_H
+#define TBATTERYCHARGINGDEFINITIONS_H
+
+#include <e32base.h>
+
+
+const TUint32 KBatteryChargingTUint = 0x102834EB;
+_LIT(KBattChargingImg, "tbatterychargingrepositorywriter.exe");
+
+const TUid KBatteryChargingTUid = {KBatteryChargingTUint};
+
+
+const TUint KBattChargWriteRepositoryUid = 0x101fe1db;
+const TUint KBattChargReadPropertyCurrentUid = 0x101fe1db;
+
+
+typedef struct TDataFromPropBattChargToTBatteryCharging
+	{
+	TInt iCurrent;
+	TInt iError;
+	}TDataFromPropBattChargToTBatteryCharging;
+
+const TUint KPropBattChargNumOfData	=2;
+
+const TUint KBattChargWriteRepositoryKey	= 0x102834EE;
+const TUint KBattChargWriteRepositoryAckKey	= 0x102834EF;
+
+const TUint KBattChargReadCurrentChargingKey	= 0x102834F0;
+const TUint KBattChargReadCurrentChargingAckKey	= 0x102834F1;
+
+
+#endif //TBATTERYCHARGINGDEFINITIONS_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/inc/tpropertybatterycharging.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,64 @@
+/**
+* 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 "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:
+* Usb Battery Charging test code to write to the Repository
+* 
+*
+*/
+
+
+
+#include <e32base.h>
+#include "activepropertysubscribercharging.h"
+
+class CRepository;
+class CActivePropertySubscriber;
+
+
+NONSHARABLE_CLASS(CPropertyBatteryCharging) : public CBase
+											 ,public MPropertyWriteRepositoryObserver
+											 ,public MPropertyReadBatteryChargingCurrentObserver
+	{
+public:
+	static CPropertyBatteryCharging* NewL();
+	~CPropertyBatteryCharging();
+
+private:
+	CPropertyBatteryCharging();
+	void ConstructL();
+	void DefinePropertiesL();
+	
+	void DefinePropertyL(const TInt32 aCategory, TUint aKey,RProperty::TType eType);
+
+private:
+	// from MPropertyWriteRepositoryObserver
+	void MpsoPropertyWriteChanged(const TInt aValue);
+	
+	// from MPropertyReadBatteryChargingCurrentObserver
+	void MpsoPropertyReadChanged();
+	
+	
+	
+
+private: // owned
+	CActivePropertyWriteRepository* iActiveWriteRepository;
+	CActivePropertyReadChargingCurrent* iActiveReadChargingCurrent;
+	CRepository* iRepository;
+	
+	//RProperty iPropertyWrittenToRepositoryAck;
+	//RProperty iPropertyReadChargingCurrentAck;
+	RProperty iProperty; // only one protected needed ?
+	
+	
+	};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/src/1020DEA7.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,46 @@
+/*
+* 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 "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
+*/
+
+#include <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x1020DEA7;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x10208DD6;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x1020DEA8;
+					version_no = 1;
+					display_name = "UsbBatteryChargingTestPlugin";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/src/CUsbBatteryChargingTestPlugin.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2007-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
+*/
+
+#include <ecom/implementationproxy.h>
+
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBCHARGE TEST");
+#endif
+
+#include <dummyldd.h>
+#define __D32USBC_H__ // ensure that d32usbc is ignored, and dummyldd used instead
+#include "CUsbBatteryChargingTestPlugin.h"
+
+// Define the private interface UIDs
+const TImplementationProxy ImplementationTable[] =
+	{										
+	IMPLEMENTATION_PROXY_ENTRY(0x1020DEA8, CUsbBatteryChargingTestPlugin::NewL),
+	};
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+	{
+	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+
+	return ImplementationTable;
+	}
+
+CUsbBatteryChargingTestPlugin* CUsbBatteryChargingTestPlugin::NewL(MUsbmanExtensionPluginObserver& aObserver)
+	{
+	LOGTEXT(_L8("NewL Test plug-n"));
+
+	CUsbBatteryChargingTestPlugin* self = new(ELeave) CUsbBatteryChargingTestPlugin(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CUsbBatteryChargingTestPlugin::CUsbBatteryChargingTestPlugin(MUsbmanExtensionPluginObserver& aObserver)
+: CUsbBatteryChargingPlugin(aObserver) {}
+
+void CUsbBatteryChargingTestPlugin::GetPluginInfo(TPluginTestInfo& aInfo)
+	{
+	aInfo.iPluginState = iPluginState;
+	aInfo.iAvailableMilliAmps = iAvailableMilliAmps;
+	aInfo.iDeviceState = iDeviceState;
+	aInfo.iUserSetting = iUserSetting;
+	aInfo.iCurrentIndexRequested = iCurrentIndexRequested;
+	aInfo.iRequestedCurrentValue = iRequestedCurrentValue;
+	}
+
+TAny* CUsbBatteryChargingTestPlugin::GetInterface(TUid aUid)
+	{
+	TAny* ret = NULL;
+	if (aUid == KUidUsbBatteryChargingTestPluginInterface2)
+		{
+		ret = reinterpret_cast<TAny*>(
+			static_cast<MUsbBatteryChargingTestPluginInterface2*>(this)
+			);
+		}
+	return ret;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/src/activepropertysubscribercharging.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,142 @@
+/*
+* 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 "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
+ @prototype
+*/
+
+#include "activepropertysubscribercharging.h"
+#include"tbatterychargingdefinitions.h"
+
+CActivePropertyWriteRepository::CActivePropertyWriteRepository(MPropertyWriteRepositoryObserver& aObserver)
+:	CActive(CActive::EPriorityStandard),
+	iObserver(aObserver)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CActivePropertyWriteRepository::~CActivePropertyWriteRepository()
+	{
+	
+	Cancel();
+	iPropertyWriteToRepository.Close();
+	}
+
+CActivePropertyWriteRepository* CActivePropertyWriteRepository::NewL(MPropertyWriteRepositoryObserver& aObserver)
+	{
+	
+	CActivePropertyWriteRepository* self = new(ELeave) CActivePropertyWriteRepository(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+void CActivePropertyWriteRepository::ConstructL()
+	{
+	// Assumes the property has already been defined by the driving test code.
+	User::LeaveIfError(iPropertyWriteToRepository.Attach(TUid::Uid(KBattChargWriteRepositoryUid), KBattChargWriteRepositoryKey));
+	}
+
+void CActivePropertyWriteRepository::Request()
+	{
+	iPropertyWriteToRepository.Subscribe(iStatus);
+	SetActive();
+	}
+
+void CActivePropertyWriteRepository::RunL()
+	{
+	
+	if ( iStatus.Int() == KErrNone )
+		{
+		TInt value;
+		TInt err = iPropertyWriteToRepository.Get(value);
+		ASSERT(!err);
+		iObserver.MpsoPropertyWriteChanged(value);
+		}
+
+	Request();
+	}
+
+void CActivePropertyWriteRepository::DoCancel()
+	{
+	
+	iPropertyWriteToRepository.Cancel();
+	}
+
+
+// this is to read the property for current charging
+CActivePropertyReadChargingCurrent::CActivePropertyReadChargingCurrent(MPropertyReadBatteryChargingCurrentObserver& aObserver)
+:	CActive(CActive::EPriorityStandard),
+	iObserver(aObserver)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CActivePropertyReadChargingCurrent::~CActivePropertyReadChargingCurrent()
+	{
+	
+	Cancel();
+	iPropertyReadChargingCurrent.Close();
+	}
+
+CActivePropertyReadChargingCurrent* CActivePropertyReadChargingCurrent::NewL(MPropertyReadBatteryChargingCurrentObserver& aObserver)
+	{
+	
+	CActivePropertyReadChargingCurrent* self = new(ELeave) CActivePropertyReadChargingCurrent(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+void CActivePropertyReadChargingCurrent::ConstructL()
+	{
+	// Assumes the property has already been defined by the driving test code.
+	User::LeaveIfError(iPropertyReadChargingCurrent.Attach(TUid::Uid(KBattChargReadPropertyCurrentUid), KBattChargReadCurrentChargingKey));
+	}
+
+void CActivePropertyReadChargingCurrent::Request()
+	{
+	iPropertyReadChargingCurrent.Subscribe(iStatus);
+	SetActive();
+	}
+
+void CActivePropertyReadChargingCurrent::RunL()
+	{
+	
+	if ( iStatus.Int() == KErrNone )
+		{
+		//not interested in the value of the property but just by the fact that it was triggered
+		iObserver.MpsoPropertyReadChanged();
+		}
+
+	Request();
+	}
+
+void CActivePropertyReadChargingCurrent::DoCancel()
+	{
+	
+	iPropertyReadChargingCurrent.Cancel();
+	}
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/src/t_charging.txt	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,171 @@
+# Copyright (c) 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:
+#
+#
+// command.......	asyncOp......		check........
+
+
+** start undefined, with user setting on...
+
+devicestate 0		none 0			none 0
+usersetting 1		none 1000000		pluginstate 0
+
+// test initial negotiation...
+
+devicestate 2		none 0			pluginstate 0
+devicestate 4		none 0			pluginstate 0
+devicestate 32		none 0			pluginstate 0
+devicestate 1		none 0			pluginstate 0
+devicestate 16		none 0			pluginstate 1
+none 0			none 0			milliamps 500
+none 0			none 0			charging 0
+devicestate 4		none 0			pluginstate 1
+devicestate 1		none 0			pluginstate 1
+devicestate 32		none 0			pluginstate 1
+devicestate 1		none 0			pluginstate 1
+devicestate 16		none 0			pluginstate 1
+devicestate 8		none 0			pluginstate 3
+none 0			none 0			charging 500
+
+** toggle suspend mode and user setting...
+
+devicestate 32		none 0			pluginstate 4
+none 0			none 0			charging 0
+devicestate 8		none 0			pluginstate 3
+none 0			none 0			charging 500
+devicestate 32		none 0			pluginstate 4
+none 0			none 0			charging 0
+devicestate 8		none 0			pluginstate 3
+none 0			none 0			charging 500
+usersetting 0		delay 100000		pluginstate 5
+none 0			none 0			charging 0
+devicestate 32		none 0			pluginstate 5
+none 0			none 0			charging 0
+devicestate 8		none 0			pluginstate 5
+none 0			none 0			charging 0
+devicestate 32		none 0			pluginstate 5
+usersetting 1		delay 100000		pluginstate 4
+none 0			none 0			charging 0
+devicestate 8		none 0			pluginstate 3
+none 0			none 0			charging 500
+devicestate 32		none 0			pluginstate 4
+usersetting 0		delay 100000		pluginstate 5
+none 0			none 0			charging 0
+
+** re-enumerate..
+
+devicestate 32		none 0			pluginstate 5
+devicestate 0		none 0			pluginstate 0
+devicestate 2		none 0			pluginstate 7
+devicestate 4		none 0			pluginstate 7
+devicestate 1		none 0			pluginstate 7
+devicestate 16		none 0			pluginstate 7
+none 0			none 0			milliamps 500
+none 0			none 0			charging 0
+
+** configure... (but UI is disabled)
+
+devicestate 16		none 0			pluginstate 7
+devicestate 8		none 0			pluginstate 7
+none 0			none 0			charging 0
+
+usersetting 1		delay 100000		pluginstate 7
+none 0			none 0			charging 0
+
+** now try failing to enumerate until current is lowered to 100mA
+
+devicestate 32		none 0			pluginstate 7
+none 0			none 0			charging 0
+devicestate 0		none 0			pluginstate 0
+devicestate 2		none 0			pluginstate 0
+devicestate 4		none 0			pluginstate 0
+devicestate 1		none 0			pluginstate 0
+devicestate 16		none 0			pluginstate 1
+none 0			none 0			milliamps 500
+none 0			none 0			charging 0
+
+none 0			delay 3500000		pluginstate 1
+none 0			none 0			milliamps 100
+none 0			none 0			charging 0
+
+devicestate 4		delay 1500000		pluginstate 1
+devicestate 1		none 0			pluginstate 1
+devicestate 32		none 0			pluginstate 1
+devicestate 1		none 0			pluginstate 1
+devicestate 16		none 0			pluginstate 1
+devicestate 8		none 0			pluginstate 3
+none 0			none 0			charging 100
+
+devicestate 32		none 0			pluginstate 4
+none 0			none 0			charging 0
+devicestate 8		none 0			pluginstate 3
+none 0			none 0			charging 100
+usersetting 0		delay 100000		pluginstate 5
+none 0			none 0			charging 0
+usersetting 1		delay 100000		pluginstate 3
+none 0			none 0			charging 100
+
+** now try failing to enumerate until current is lowered to 0mA
+
+devicestate 32		none 0			pluginstate 4
+none 0			none 0			charging 0
+devicestate 2		none 0			pluginstate 0
+devicestate 4		none 0			pluginstate 0
+devicestate 1		none 0			pluginstate 0
+devicestate 16		none 0			pluginstate 1
+none 0			none 0			milliamps 500
+none 0			none 0			charging 0
+
+none 0			delay 3500000		pluginstate 1
+none 0			none 0			milliamps 100
+none 0			none 0			charging 0
+
+devicestate 16		none 0			pluginstate 1
+none 0			delay 3500000		pluginstate 2
+none 0			none 0			milliamps 0
+none 0			none 0			charging 0
+
+** so become configured with no current...
+
+devicestate 4		delay 1500000		pluginstate 2
+devicestate 1		none 0			pluginstate 2
+devicestate 32		none 0			pluginstate 2
+devicestate 1		none 0			pluginstate 2
+devicestate 16		none 0			pluginstate 2
+devicestate 8		none 0			pluginstate 6
+none 0			none 0			charging 0
+
+devicestate 32		none 0			pluginstate 6
+none 0			none 0			charging 0
+devicestate 8		none 0			pluginstate 6
+none 0			none 0			charging 0
+devicestate 32		none 0			pluginstate 6
+none 0			none 0			charging 0
+devicestate 8		none 0			pluginstate 6
+none 0			none 0			charging 0
+usersetting 0		delay 100000		pluginstate 6
+none 0			none 0			charging 0
+usersetting 1		delay 100000		pluginstate 6
+none 0			none 0			charging 0
+
+** and disconnect...
+
+devicestate 32		none 0			pluginstate 6
+devicestate 0		none 0			pluginstate 0
+devicestate 2		none 0			pluginstate 0
+devicestate 4		none 0			pluginstate 0
+devicestate 1		none 0			pluginstate 0
+devicestate 16		none 0			pluginstate 1
+none 0			none 0			milliamps 500
+none 0			none 0			charging 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/src/tbatterycharging.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,573 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "tbatterycharging.h"
+#include "musbdevicenotify.h"
+
+#include <e32svr.h>
+#include <e32base.h>
+#include <e32std.h>
+#include <usbman.rsg>
+#include <f32file.h>
+#include <barsc.h>
+#include <barsread.h>
+#include <bautils.h>
+#include "UsbUtils.h"
+
+
+#include"tbatterychargingdefinitions.h"
+
+
+LOCAL_C void ConsoleMainL();
+
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
+	
+	TRAPD(error, ConsoleMainL() );
+	
+	__ASSERT_ALWAYS(!error,User::Panic(_L("UsbChargingTest"), error));
+	delete cleanup; // destroy clean-up stack
+	__UHEAP_MARKEND;
+	return KErrNone;
+	}
+
+void ConsoleMainL()
+	{
+    CActiveScheduler* myScheduler = new(ELeave) CActiveScheduler;
+    CleanupStack::PushL(myScheduler);
+    CActiveScheduler::Install(myScheduler);	
+    
+	CDummyUsbDevice* device = CDummyUsbDevice::NewL();
+	CleanupStack::PushL(device);
+	device->DoTestsL();
+	CActiveScheduler::Start();
+
+	CleanupStack::PopAndDestroy(2, myScheduler);
+	}
+
+CDummyUsbDevice* CDummyUsbDevice::NewL()
+/**
+ * Constructs a CDummyUsbDevice object.
+ *
+ * @return	A new CDummyUsbDevice object
+ */
+	{
+	CDummyUsbDevice* r = new (ELeave) CDummyUsbDevice();
+	CleanupStack::PushL(r);
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+	}
+
+CDummyUsbDevice::~CDummyUsbDevice()
+/**
+ * Destructor.
+ */
+	{
+	// Cancel any outstanding asynchronous operation.
+	Cancel();
+	iTimer.Close();
+	//delete iRepository;
+	iExtensionPlugins.ResetAndDestroy();
+
+	if(iEcom)
+		iEcom->Close();
+	REComSession::FinalClose();
+
+	// Free any memory allocated to the list of observers. Note that
+	// we don't want to call ResetAndDestroy, because we don't own
+	// the observers themselves.
+	iObservers.Reset();
+	delete iText;
+	iTest.Close();
+	
+	iProperty.Close();
+	iPropertyWriteToRepositoryAck.Close();
+	iPropertyReadChargingCurrentAck.Close();
+
+	}
+
+CDummyUsbDevice::CDummyUsbDevice()
+	: CActive(EPriorityStandard), iTest(_L("Usb Charging Plugin Test")), iPtr(0,200), iLine(0,200)
+/**
+ * Constructor.
+ */
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CDummyUsbDevice::ConstructL()
+/**
+ * Performs 2nd phase construction of the USB device.
+ */
+	{
+	iEcom = &(REComSession::OpenL());
+
+	InstantiateExtensionPluginsL();
+
+	if (iExtensionPlugins.Count() != 1)
+		{
+		User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicIncorrectPlugin);
+		}
+
+	iPlugin = iExtensionPlugins[0];
+
+	iDummyLdd.Initialise();
+	//iRepository = CRepository::NewL(KUsbBatteryChargingCentralRepositoryUid);
+	User::LeaveIfError(iTimer.CreateLocal());
+	
+	DefinePropertyL(KBattChargWriteRepositoryUid, KBattChargWriteRepositoryKey,RProperty::EInt);
+	DefinePropertyL(KBattChargReadPropertyCurrentUid,KBattChargReadCurrentChargingKey,RProperty::EInt);
+	
+	User::LeaveIfError(iPropertyWriteToRepositoryAck.Attach(TUid::Uid(KBattChargWriteRepositoryUid), KBattChargWriteRepositoryAckKey));
+	User::LeaveIfError(iPropertyReadChargingCurrentAck.Attach(TUid::Uid(KBattChargReadPropertyCurrentUid), KBattChargReadCurrentChargingAckKey));
+	
+	User::LeaveIfError(StartPropertyBatteryCharging());
+
+	}
+	
+void CDummyUsbDevice::DefinePropertyL(const TInt32 aCategory, TUint aKey,RProperty::TType eType)
+	{
+	
+	_LIT_SECURITY_POLICY_PASS(KAlwaysPass);
+
+	TInt err = iProperty.Define(TUid::Uid(aCategory),
+									aKey,
+									eType,
+									KAlwaysPass,
+									KAlwaysPass
+									);
+	if ( err != KErrAlreadyExists )
+		{
+		User::LeaveIfError(err);
+		}
+	}
+
+
+	
+void CDummyUsbDevice::InstantiateExtensionPluginsL()
+	{
+	const TUid KUidExtensionPluginInterface = TUid::Uid(KUsbmanExtensionPluginInterfaceUid);
+	RImplInfoPtrArray implementations;
+	const TEComResolverParams noResolverParams;
+	REComSession::ListImplementationsL(KUidExtensionPluginInterface, noResolverParams, KRomOnlyResolverUid, implementations);
+	CleanupResetAndDestroyPushL(implementations);
+
+	for (TInt i=0; i<implementations.Count(); i++)
+		{
+		const TUid KTestPluginUid = {0x1020DEA8};
+		if (implementations[i]->ImplementationUid() == KTestPluginUid)
+			{
+			CUsbmanExtensionPlugin* plugin = CUsbmanExtensionPlugin::NewL(implementations[i]->ImplementationUid(), *this);
+			CleanupStack::PushL(plugin);
+			// there will most likely be two plugins - the standard one, and the test one (which
+			// is an extension of the standard one, to include the interface 
+			// MUsbBatteryChargingTestPluginInterface2. So check, and only keep the test one:
+			MUsbBatteryChargingTestPluginInterface2* pluginIf
+				= reinterpret_cast<MUsbBatteryChargingTestPluginInterface2*>(
+					plugin->GetInterface(KUidUsbBatteryChargingTestPluginInterface2));
+			
+			if (pluginIf)
+				{
+				iExtensionPlugins.AppendL(plugin); // transfer ownership to iExtensionPlugins
+				CleanupStack::Pop(plugin);
+				}
+			else
+				{ // destroy it - it's the standard plugin.
+				CleanupStack::PopAndDestroy(plugin);
+				iObservers.Remove(iObservers.Count() - 1);
+				}
+			}
+		}
+	CleanupStack::PopAndDestroy(&implementations);
+	}
+
+void CDummyUsbDevice::RegisterObserverL(MUsbDeviceNotify& aObserver)
+/**
+ * Register an observer of the device.
+ * Presently, the device supports watching state.
+ *
+ * @param	aObserver	New Observer of the device
+ */
+	{
+	User::LeaveIfError(iObservers.Append(&aObserver));
+	}
+
+
+void CDummyUsbDevice::DeRegisterObserver(MUsbDeviceNotify& aObserver)
+/**
+ * De-registers an existing device observer.
+ *
+ * @param	aObserver	The existing device observer to be de-registered
+ */
+	{
+	TInt index = iObservers.Find(&aObserver);
+
+	if (index >= 0)
+		iObservers.Remove(index);
+	}
+
+void CDummyUsbDevice::RunL()
+	{
+	DoCheck();
+	if (GetNextLine() < 0)
+		{
+		iTest.End();
+		iTest.Getch();
+		CActiveScheduler::Stop();
+		}
+	else
+		{
+		iLineNumber++;
+		iTest.Next(_L(""));
+		InterpretLine();
+		DoCommand();
+		DoAsyncOp();	
+		}
+	}
+
+void CDummyUsbDevice::DoCancel()
+	{
+	iTimer.Cancel();
+	}
+
+TInt CDummyUsbDevice::RunError(TInt /*aError*/)
+	{
+
+	return KErrNone;
+	}
+
+RDevUsbcClient& CDummyUsbDevice::MuepoDoDevUsbcClient()
+/**
+ * Inherited from MUsbmanExtensionPluginObserver - Function used by plugins to
+ * retrieve our handle to the LDD
+ *
+ * @return The LDD handle
+ */
+	{
+	return iDummyLdd;
+	}
+
+void CDummyUsbDevice::MuepoDoRegisterStateObserverL(MUsbDeviceNotify& aObserver)
+/**
+ * Inherited from MUsbmanExtensionPluginObserver - Function used by plugins to
+ * register themselves for notifications of device/service state changes.
+ *
+ * @param aObserver New Observer of the device
+ */
+	{
+	RegisterObserverL(aObserver);
+	}
+
+void CDummyUsbDevice::UpdatePluginInfo()
+	{
+	// we can assume our plugin does support this interface....
+	reinterpret_cast<MUsbBatteryChargingTestPluginInterface2*>(iPlugin->GetInterface(KUidUsbBatteryChargingTestPluginInterface2))->GetPluginInfo(iInfo);
+	}
+
+void CDummyUsbDevice::DoTestsL()
+	{
+	iTest.SetLogged(ETrue);
+	iTest.Title();
+	OpenFileL();
+	TInt length = GetNextLine();
+	if (length <= 0)
+		{
+		User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadInputData);
+		}
+	iLineNumber = 1;
+	iTest.Start(_L("test"));
+	InterpretLine();
+	DoCommand();
+	DoAsyncOp();
+	}
+
+void CDummyUsbDevice::InterpretLine()
+	{
+	TLex8 lex(iLine);
+	lex.SkipCharacters();
+	iCommand = GetCommand(iLine.Left(lex.Offset()));
+	lex.SkipSpace();
+	lex.Val(iCommandValue);
+	lex.SkipSpace();
+	TInt pos = lex.Offset();
+	lex.SkipCharacters();
+	iAsyncOp = GetAsyncOp(iLine.Mid(pos,lex.Offset()-pos));
+	lex.SkipSpace();
+	lex.Val(iAsyncOpValue);
+	lex.SkipSpace();
+	pos = lex.Offset();
+	lex.SkipCharacters();
+	iCheck = GetCheck(iLine.Mid(pos,lex.Offset()-pos));
+	lex.SkipSpace();
+	lex.Val(iCheckValue);
+	}
+
+void CDummyUsbDevice::OpenFileL()
+	{
+	RFs fs;
+	User::LeaveIfError(fs.Connect());
+	CleanupClosePushL(fs);
+
+	TFindFile ff(fs);
+	User::LeaveIfError(ff.FindByDir(_L("\\system\\data\\t_charging.txt"),KNullDesC));
+	
+	RFile file;
+	TInt size;
+	User::LeaveIfError(file.Open(fs,ff.File(),EFileStreamText|EFileRead|EFileShareReadersOnly));
+	CleanupClosePushL(file);
+	
+	User::LeaveIfError(file.Size(size));
+
+	iText = REINTERPRET_CAST(TText8*, User::AllocL(size));
+	iPtr.Set(iText, size/sizeof(TText8), size/sizeof(TText8));
+	TPtr8 dest(REINTERPRET_CAST(TUint8*,iText), 0, size);
+	User::LeaveIfError(file.Read(dest)); 
+
+	CleanupStack::PopAndDestroy(); // file
+	CleanupStack::PopAndDestroy(); // fs
+	}
+
+TInt CDummyUsbDevice::GetNextLine()
+	{
+	TInt newLineOffset = (iPtr.Mid(iFileOffset)).Locate(13);//Find(_L("\r\n"));
+	if (newLineOffset < 0)
+		{
+		return newLineOffset;
+		}
+	if (newLineOffset == 0)
+		{
+		iFileOffset += 2;
+		return GetNextLine();
+		}
+	iLine.Set(iPtr.MidTPtr(iFileOffset, newLineOffset));
+	iFileOffset += (newLineOffset + 2);
+	if (iLine.Find(_L8("//")) == 0) // i.e. line begins with "//"
+		{
+		return GetNextLine();
+		}
+	if (iLine.Find(_L8("**")) == 0) // line begins with **, so display it
+		{
+		TBuf<100> buf; // max length 100 for test messages
+		buf.Copy(iLine);
+		iTest.Printf(_L("\n%S\n\n"),&buf);
+		return GetNextLine();
+		};
+	return newLineOffset;
+	}
+
+TInt CDummyUsbDevice::GetCommand(const TDesC8& aDes)
+	{
+	if (aDes.MatchF(_L8("none")) != KErrNotFound)
+		return EUsbChargingTestCommandNone;
+	if (aDes.MatchF(_L8("devicestate")) != KErrNotFound)
+		return EUsbChargingTestCommandDeviceState;
+	if (aDes.MatchF(_L8("usersetting")) != KErrNotFound)
+		return EUsbChargingTestCommandUserSetting;
+	User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadInputData);
+	return -1;
+	}
+
+TInt CDummyUsbDevice::GetAsyncOp(const TDesC8& aDes)
+	{
+	if (aDes.MatchF(_L8("none")) != KErrNotFound)
+		return EUsbChargingTestAsyncOpNone;
+	if (aDes.MatchF(_L8("delay")) != KErrNotFound)
+		return EUsbChargingTestAsyncOpDelay;
+	User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadInputData);
+	return -1;
+	}
+
+TInt CDummyUsbDevice::GetCheck(const TDesC8& aDes)
+	{
+	if (aDes.MatchF(_L8("none")) != KErrNotFound)
+		return EUsbChargingTestCheckNone;
+	if (aDes.MatchF(_L8("pluginstate")) != KErrNotFound)
+		return EUsbChargingTestCheckPluginState;
+	if (aDes.MatchF(_L8("milliamps")) != KErrNotFound)
+		return EUsbChargingTestCheckMilliAmps;
+	if (aDes.MatchF(_L8("charging")) != KErrNotFound)
+		return EUsbChargingTestCheckCharging;
+	User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadInputData);
+	return -1;
+	}
+
+void CDummyUsbDevice::DoCommand()
+	{
+	switch (iCommand)
+		{
+		case EUsbChargingTestCommandNone:
+			{
+			// do nothing	
+			}
+			break;
+		case EUsbChargingTestCommandDeviceState:
+			{
+			iObservers[0]->UsbDeviceStateChange(KErrNone, iDeviceState, TUsbDeviceState(iCommandValue));
+			iDeviceState = TUsbDeviceState(iCommandValue);
+			}
+			break;
+		case EUsbChargingTestCommandUserSetting:
+			{
+			TInt err = WriteToRepositoryProperty(iCommandValue);
+			
+			//TInt err = iRepository->Set(KUsbBatteryChargingKeyEnabledUserSetting, iCommandValue);
+			iTest(err == KErrNone);
+			}
+			break;
+		default:
+			User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadCommand);
+		}
+	}
+
+void CDummyUsbDevice::DoAsyncOp()
+	{
+	switch (iAsyncOp)
+		{
+		case EUsbChargingTestAsyncOpNone:
+			{
+			SetActive();
+			TRequestStatus* status = &iStatus;
+			User::RequestComplete(status, KErrNone);
+			}
+			break;
+		case EUsbChargingTestAsyncOpDelay:
+			{
+			iTimer.After(iStatus, TTimeIntervalMicroSeconds32(iAsyncOpValue));
+			SetActive();
+			}
+			break;
+		default:
+			User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadAsyncOp);
+		}
+	}
+
+void CDummyUsbDevice::DoCheck()
+	{
+	UpdatePluginInfo();
+	switch (iCheck)
+		{
+		case EUsbChargingTestCheckNone:
+			{
+			// do nothing
+			}
+			break;
+		case EUsbChargingTestCheckPluginState:
+			{
+			iTest(iInfo.iPluginState == iCheckValue);
+			}
+			break;
+		case EUsbChargingTestCheckMilliAmps:
+			{
+			iTest(iInfo.iRequestedCurrentValue == iCheckValue);
+			}
+			break;
+		case EUsbChargingTestCheckCharging:
+			{
+			TInt current;			
+			TInt err = GetChargingCurrentFromProperty(current);
+			
+			//TInt err = RProperty::Get(KPropertyUidUsbBatteryChargingCategory,
+			//	KPropertyUidUsbBatteryChargingChargingCurrent, current);
+			iTest(err == KErrNone);
+			iTest(current == iCheckValue);
+			}
+			break;
+		default:
+			User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadCheck);
+		}
+	}
+	
+TInt CDummyUsbDevice::GetChargingCurrentFromProperty(TInt &aCurrent)
+	{
+	
+	TRequestStatus stat;
+	iPropertyReadChargingCurrentAck.Subscribe(stat);
+	
+	TInt err = iProperty.Set(TUid::Uid(KBattChargReadPropertyCurrentUid),
+								KBattChargReadCurrentChargingKey,
+								1);
+	ASSERT(!err);	
+	User::WaitForRequest(stat);
+	
+	TBufC8<50> value;
+	TPtr8 myPtr(value.Des());
+	TInt error = iPropertyReadChargingCurrentAck.Get(myPtr);
+	ASSERT(!error);
+	
+	TDataFromPropBattChargToTBatteryCharging received;
+	TPckg<TDataFromPropBattChargToTBatteryCharging>tmp(received);
+	tmp.Copy(value);
+	aCurrent = received.iCurrent;
+	return received.iError;
+	
+	}
+
+TInt CDummyUsbDevice::WriteToRepositoryProperty(TInt iCommandValue)
+	{
+	TRequestStatus stat;
+	iPropertyWriteToRepositoryAck.Subscribe(stat);
+		
+	TInt err = iProperty.Set(TUid::Uid(KBattChargWriteRepositoryUid),
+									KBattChargWriteRepositoryKey,
+									iCommandValue);
+	ASSERT(!err);	
+	User::WaitForRequest(stat);
+	TInt value;
+	err = iPropertyWriteToRepositoryAck.Get(value);
+	ASSERT(!err);
+	return value;
+	}
+	
+TInt CDummyUsbDevice::StartPropertyBatteryCharging()
+	{
+	const TUidType serverUid(KNullUid, KNullUid, KBatteryChargingTUid);
+	RProcess server;
+	TInt err = server.Create(KBattChargingImg, KNullDesC, serverUid);
+	if ( err != KErrNone )
+		{
+		return err;
+		}
+	TRequestStatus stat;
+	server.Rendezvous(stat);
+	
+	if ( stat != KRequestPending )
+		{		
+		server.Kill(0); 	// abort startup
+		}
+	else
+		{		
+		server.Resume();	// logon OK - start the server
+		}
+	
+	User::WaitForRequest(stat); 	// wait for start or death
+	
+	// we can't use the 'exit reason' if the server panicked as this
+	// is the panic 'reason' and may be '0' which cannot be distinguished
+	// from KErrNone
+	
+	err = (server.ExitType() == EExitPanic) ? KErrServerTerminated : stat.Int();
+	
+	server.Close();	
+	
+	return err;
+	
+	}
+	
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/src/tpropertybatterycharging.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,163 @@
+/*
+* 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 "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 "tpropertybatterycharging.h"
+
+#include <e32property.h> //Publish & Subscribe header
+
+#include <centralrepository.h>
+#include "usbbatterycharging.h"
+#include"tbatterychargingdefinitions.h"
+
+
+LOCAL_C void ConsoleMainL();
+
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
+	
+	TRAPD(error, ConsoleMainL() );
+	
+	__ASSERT_ALWAYS(!error,User::Panic(_L("TPropertyBatteryCharging"), error));
+	delete cleanup; // destroy clean-up stack
+	__UHEAP_MARKEND;
+	return KErrNone;
+	}
+
+void ConsoleMainL()
+	{
+    CActiveScheduler* myScheduler = new(ELeave) CActiveScheduler;
+    CleanupStack::PushL(myScheduler);
+    CActiveScheduler::Install(myScheduler);	
+    
+	CPropertyBatteryCharging* propertyBatCharg = CPropertyBatteryCharging::NewL();
+	CleanupStack::PushL(propertyBatCharg);
+	
+	RProcess::Rendezvous(KErrNone);
+	
+	CActiveScheduler::Start();
+
+	CleanupStack::PopAndDestroy(2, myScheduler);
+	}
+
+CPropertyBatteryCharging* CPropertyBatteryCharging::NewL()
+/**
+ * Constructs a CDummyUsbDevice object.
+ *
+ * @return	A new CDummyUsbDevice object
+ */
+	{
+	CPropertyBatteryCharging* r = new (ELeave) CPropertyBatteryCharging();
+	CleanupStack::PushL(r);
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+	}
+
+CPropertyBatteryCharging::~CPropertyBatteryCharging()
+/**
+ * Destructor.
+ */
+	{
+	
+	delete iActiveWriteRepository;
+	delete iActiveReadChargingCurrent;
+	delete iRepository;
+	iProperty.Close();
+	
+	}
+
+CPropertyBatteryCharging::CPropertyBatteryCharging() 
+/**
+ * Constructor.
+ */
+	{
+	
+	}
+
+void CPropertyBatteryCharging::ConstructL()
+/**
+ * Performs 2nd phase construction of the USB device.
+ */
+	{	
+	
+	iActiveWriteRepository = CActivePropertyWriteRepository::NewL(*this);
+	iActiveReadChargingCurrent = CActivePropertyReadChargingCurrent::NewL(*this);	
+		
+	iRepository = CRepository::NewL(KUsbBatteryChargingCentralRepositoryUid);
+	
+	DefinePropertyL(KBattChargWriteRepositoryUid, KBattChargWriteRepositoryAckKey,RProperty::EInt);
+	DefinePropertyL(KBattChargReadPropertyCurrentUid,KBattChargReadCurrentChargingAckKey,RProperty::EByteArray);
+	
+	iActiveWriteRepository->Request();
+	iActiveReadChargingCurrent->Request();
+	
+	}
+	
+void CPropertyBatteryCharging::DefinePropertyL(const TInt32 aCategory, TUint aKey,RProperty::TType eType)
+	{
+	
+
+	_LIT_SECURITY_POLICY_PASS(KAlwaysPass);
+
+	TInt err = iProperty.Define(TUid::Uid(aCategory),
+									aKey,
+									eType,
+									KAlwaysPass,
+									KAlwaysPass
+									);
+	if ( err != KErrAlreadyExists )
+		{
+		User::LeaveIfError(err);
+		}
+	}
+
+	
+void CPropertyBatteryCharging::MpsoPropertyReadChanged()
+	{
+		
+	TInt current;
+	TInt err = RProperty::Get(KPropertyUidUsbBatteryChargingCategory,
+				KPropertyUidUsbBatteryChargingChargingCurrent, current);
+		
+	TDataFromPropBattChargToTBatteryCharging toSend;
+	toSend.iCurrent=current;
+	toSend.iError=err;
+		
+	TPckgBuf<TDataFromPropBattChargToTBatteryCharging> tmp(toSend);
+	
+	err = iProperty.Set(TUid::Uid(KBattChargReadPropertyCurrentUid),
+									KBattChargReadCurrentChargingAckKey,
+									tmp);
+	ASSERT(!err);	
+					
+	}
+	
+void CPropertyBatteryCharging::MpsoPropertyWriteChanged(const TInt aValue)
+	{
+	TInt err = iRepository->Set(KUsbBatteryChargingKeyEnabledUserSetting, aValue);
+	
+	TInt error = iProperty.Set(TUid::Uid(KBattChargWriteRepositoryUid),
+						KBattChargWriteRepositoryAckKey,
+						err);
+	ASSERT(!error);	
+	
+	}
+	
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_headlessecacm/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* 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 "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:
+* BLD.INF for t_headlessecacm
+* BLD.INF for t_headlessecacm
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+t_headlessecacm.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_headlessecacm/group/t_headlessecacm.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 1997-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:
+* HEADLESSECACM.MMP
+* Top-level project file for ECACM.CSY. 
+* This version of the CSY is used for doing performance testing at the 
+* RDevUsbcClient level. When some data comes in, it is immediately written 
+* back to the host. If you have something like serial.exe running on the 
+* host, you will get a loopback which can be used for gathering data transfer 
+* rate information.
+* Main usage: 
+* 1/ run t_acm on the Lubbock, select ReadOneOrMore
+* 2/ run serial.exe on the PC with a packet size of your choosing
+* or:
+* 1/ run t_acm on the Lubbock, select Read, and give a packet size of N
+* 2/ run serial.exe on the PC with a packet size of N
+*
+*/
+
+/**
+ @file
+*/
+
+TARGET			ecacm.csy
+CAPABILITY CommDD PowerMgmt ReadDeviceData WriteDeviceData TrustedUI ProtServ NetworkControl NetworkServices LocalServices ReadUserData WriteUserData
+TARGETTYPE		dll
+UID 			0x10005054
+NOEXPORTLIBRARY
+VENDORID 0x70000001
+
+SOURCEPATH		../../../usbmgr/usb/csy/src
+SOURCE			AcmPort.cpp
+SOURCE			AcmPortFactory.cpp 
+SOURCE			AcmReader.cpp
+SOURCE			AcmWriter.cpp
+SOURCE			ActiveBusStallNotifier.cpp 
+SOURCE			ActiveReader.cpp 
+SOURCE			ActiveReadOneOrMoreReader.cpp
+SOURCE			ActiveWriter.cpp
+SOURCE			BreakController.cpp
+SOURCE			CdcAcmClass.cpp 
+SOURCE			CdcInterfaceBase.cpp		
+SOURCE			CdcControlInterface.cpp 	
+SOURCE			CdcControlInterfaceReader.cpp 
+SOURCE			CdcDataInterface.cpp		
+SOURCE			ClassDescriptor.cpp 
+SOURCE			DllMain.cpp 
+SOURCE			IniFile.cpp
+SOURCE			RegistrationPort.cpp 
+SOURCE			RequestHeader.cpp 
+SOURCE			acmserver.cpp
+SOURCE			acmsession.cpp
+
+USERINCLUDE 	../../../usbmgr/usb/csy/inc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY 		euser.lib 
+LIBRARY 		c32.lib
+LIBRARY			efsrv.lib
+
+#ifdef WINS
+DEFFILE			..\..\..\usbmgr\usb\csy\bmarm\ecacm.def
+#else
+DEFFILE			..\..\..\usbmgr\usb\csy\bwins\ecacm.def
+#endif
+
+// Define this macro to build a 'headless' ACM, which, when you do a Read or 
+// ReadOneOrMore, Writes the data back to the LDD. This is used for 
+// performance testing at the level of RDevUsbcClient.
+MACRO __HEADLESS_ACM_TEST_CODE__
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_multi_acm/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* 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 "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:
+* BLD.INF for t_multi_acm
+* BLD.INF for t_multi_acm
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+t_multi_acm.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_multi_acm/group/t_multi_acm.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+TARGET		t_multiacm.exe
+TARGETTYPE	EXE
+UID		0
+SOURCEPATH    ../src
+SOURCE          t_multiple_acm.cpp
+LIBRARY		euser.lib c32.lib usbman.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_multi_acm/src/t_multiple_acm.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,792 @@
+/*
+* 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:
+* This program executes all the tests in the ACM CSY Test Specification v 0.1
+* and is to be used in conjunction with the host-side application.
+*
+*/
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <e32math.h>
+#include <c32comm.h>
+#include <usbman.h>
+
+LOCAL_D CConsoleBase* console;
+
+RCommServ TheCommServ;
+
+
+TCommConfig TheConfigBuf;
+TCommConfigV01& TheConfig = TheConfigBuf();
+
+const TInt KReceiveBufferLength = 4096;
+const TInt KMaxAcmPortNameLength = 8;
+//_LIT(KUsbCsyName, "ECACM");
+_LIT(KUsbPortName, "ACM::0");
+_LIT(KUsbPortNameAcm1, "ACM::1");
+
+_LIT(KUsbLddName, "EUSBC");
+
+#define _printf console->Printf
+#define _getch console->Getch
+#define LEAVE(_x) VerboseLeaveL(_x, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+#define LEAVEIFERROR(_x) VerboseLeaveIfErrorL(_x, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+#define CHECK(_x) if (! (_x)) VerboseLeaveL(KErrGeneral, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+
+// A define for stack-based buffers
+#define MAX_BUFFER_SIZE 1024
+
+// A bigger buffer on the heap
+#define MAX_HEAP_BUFFER_SIZE	1024*8
+TBuf8<MAX_HEAP_BUFFER_SIZE> readBigBuf;
+
+// A timer for use by several of the tests
+RTimer timer;
+
+void VerboseLeaveL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode)
+/**
+ * For bombing out usefully.
+ */
+	{
+	TInt filenameOffset = aFileName.LocateReverse('\\') + 1;
+	if (filenameOffset < 0) filenameOffset = 1;
+	TPtrC8 shortFileName = aFileName.Mid(filenameOffset);
+	TBuf<64> fName, code;
+	fName.Copy(shortFileName.Left(64));
+	code.Copy(aCode.Left(64));
+	_printf(_L("\nERROR (%d) on line %d of file %S\n"), aError, aLineNum, &fName);
+	_printf(_L("Code: %S\n\n"), &code);
+	_printf(_L("[ press any key ]"));
+	_getch();
+	User::Leave(aError);
+	}
+
+void VerboseLeaveIfErrorL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode)
+/**
+ * For bombing out usefully if there's an error.
+ */
+	{
+	if (aError) 
+		VerboseLeaveL(aError, aLineNum, aFileName, aCode);
+	}
+
+void ReadString(TDes& aDes)
+/**
+ * Reads user input into the start of the descriptor aDes.
+ */
+	{
+	TChar inputKey;
+	TInt count = 0;
+
+	aDes.Zero();
+	for (;;)
+		{
+		inputKey = (TInt) _getch();
+
+		if ((TInt)inputKey == EKeyEnter)
+			break;
+
+		if(inputKey == EKeyBackspace)
+			{
+			if (count > 0)
+				{
+				_printf(_L("%C"), (TUint) inputKey);
+				aDes.Delete(--count,1);
+				}
+			}
+		else if(inputKey.IsPrint())
+			{
+			_printf(_L("%C"), (TUint) inputKey);
+			aDes.Append(inputKey);
+			count++;
+			}
+		}
+	}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ *  loopback From a Port input by the user to abother port- 
+ *  ACM::1 KUsbPortNameAcm1 to ACM::0 KUsbPortName by default
+ */
+
+void ReadLoopbackFromPortAToPortBTestL()
+	{
+
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm portIN;
+	RComm portOut;
+
+	_printf(_L("Enter the packet size:"));
+	TBufC<8> buf;
+	TPtr ptr (buf.Des());
+	ReadString(ptr);
+
+	TLex input(buf);
+
+	TInt pktlen = 0;
+	while ((input.Peek()).IsDigit()) {
+		pktlen = 10*pktlen + (input.Get()) - '0';
+	}
+
+	// Get port names
+	_printf(_L("\nEnter acm port name as loopback INPUT: (ex ACM::1):"));
+	TBufC<KMaxAcmPortNameLength> portINName;
+	TPtr portINNamePtr (portINName.Des());
+	ReadString(portINNamePtr);
+	if ( portINNamePtr.Length() == 0 )
+		{
+		portINName= KUsbPortNameAcm1;
+		}
+
+	_printf(_L("\nEnter acm port name as loopback OUTPUT: (ex ACM::0):"));
+	TBufC<KMaxAcmPortNameLength> portOutName;
+	TPtr portOutNamePtr (portOutName.Des());
+	ReadString(portOutNamePtr);
+	if ( portOutNamePtr.Length() == 0 )
+		{
+		portOutName = KUsbPortName;
+		}
+
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This test listens for data on the ACM port: "));
+	_printf(portINName);
+	_printf(_L("\nwrites anything it receives on the ACM port: "));
+	_printf(portOutName);
+	_printf(_L("\nPress any key to quit.\n"));
+	_printf(_L("----------------------------------------\n\n"));
+
+	LEAVEIFERROR(portIN.Open(TheCommServ, portINName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(portIN);
+
+	LEAVEIFERROR(portOut.Open(TheCommServ, portOutName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(portOut);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	portIN.SetConfig(TheConfigBuf);
+	portIN.SetReceiveBufferLength(KReceiveBufferLength);
+	portOut.SetConfig(TheConfigBuf);
+	portOut.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("loopback received data\n"));
+
+	console->Read(consoleStatus);
+	
+	FOREVER
+		{
+		portIN.Read(status, readBigBuf, pktlen);
+
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			portIN.ReadCancel();
+			break;
+			}
+
+		portOut.Write(status, readBigBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			portOut.WriteCancel();
+			break;
+			}
+		}
+
+	portOut.WriteCancel();
+
+	_printf(_L("\nTest complete\n"));
+
+	CleanupStack::PopAndDestroy(2); // portA	, portOut
+	
+	}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ *  Original loopback test - uses Read().
+ */
+
+void ReadLoopbackTestL()
+	{
+
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm port;
+	RComm port2;
+
+	_printf(_L("Enter the packet size:"));
+	TBufC<8> buf;
+	TPtr ptr (buf.Des());
+	ReadString(ptr);
+
+	TLex input(buf);
+
+	TInt pktlen = 0;
+	while ((input.Peek()).IsDigit()) {
+		pktlen = 10*pktlen + (input.Get()) - '0';
+	}
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This test listens for data on the ACM\n"));
+	_printf(_L("port and echoes anything it receives\n"));
+	_printf(_L("back to the PC. Press any key to quit.\n"));
+	_printf(_L("----------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	LEAVEIFERROR(port2.Open(TheCommServ, _L("ACM::1"), ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port2);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+	port2.SetConfig(TheConfigBuf);
+	port2.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Echoing received data\n"));
+
+
+
+
+
+	console->Read(consoleStatus);
+	
+	FOREVER
+		{
+		port.Read(status, readBigBuf, pktlen);
+
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.ReadCancel();
+			break;
+			}
+
+		port.Write(status, readBigBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.WriteCancel();
+			break;
+			}
+		}
+
+
+	console->Read(consoleStatus);
+	
+	FOREVER
+		{
+		port2.Read(status, readBigBuf, pktlen);
+
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port2.ReadCancel();
+			break;
+			}
+
+		port2.Write(status, readBigBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port2.WriteCancel();
+			break;
+			}
+		}
+
+
+	_printf(_L("\nTest complete\n"));
+
+	CleanupStack::PopAndDestroy(2); // port	, port2
+	
+	}
+
+/**
+ * Original loopback test - uses ReadOneOrMore().
+ */
+
+void LoopbackTestL()
+	{
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm port;
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This test listens for data on the ACM\n"));
+	_printf(_L("port and echoes anything it receives\n"));
+	_printf(_L("back to the PC. Press any key to quit.\n"));
+	_printf(_L("----------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Echoing received data\n"));
+
+	TBuf8<256> readBuf;
+
+	console->Read(consoleStatus);
+
+	FOREVER
+		{
+		port.ReadOneOrMore(status, readBuf);
+		
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.ReadCancel();
+			break;
+			}
+
+		port.Write(status, readBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.WriteCancel();
+			break;
+			}
+		}
+
+	_printf(_L("\nTest complete\n"));
+
+	CleanupStack::PopAndDestroy(); // port
+	}
+
+void ReadWithTerminatorsLoopbackTestL()
+	{
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm port;
+
+	// Get terminator characters
+	_printf(_L("Enter the terminator characters (up to %d):"), KConfigMaxTerminators);
+	TBufC<KConfigMaxTerminators> termbuf;
+	TPtr termptr (termbuf.Des());
+	ReadString(termptr);
+	TText8 terminators[KConfigMaxTerminators]; 
+	if ( termptr.Length() == 0 )
+		{
+		_printf(_L("\nno terminators given- not running test"));
+		return;
+		}
+	TUint termCount = 0;
+	TUint ii;
+	for ( ii = 0 ; ii < (TUint)termptr.Length() ; ii++ )
+		{
+		termCount++;
+		terminators[ii] = (TText8)termptr[ii];
+		}
+	
+	_printf(_L("\nEnter the packet size:"));
+	TBufC<8> buf;
+	TPtr ptr (buf.Des());
+	ReadString(ptr);
+
+	TLex input(buf);
+
+	TInt pktlen = 0;
+	while ((input.Peek()).IsDigit()) {
+		pktlen = 10*pktlen + (input.Get()) - '0';
+	}
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This test listens for data on the ACM\n"));
+	_printf(_L("port and echoes anything it receives\n"));
+	_printf(_L("back to the PC. Press any key to quit.\n"));
+	_printf(_L("----------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	// Set the config, including terminator characters.
+	TCommConfig configBuf;
+	TCommConfigV01& config = configBuf();
+	port.Config(configBuf);
+	config.iTerminatorCount = termCount;
+	for ( ii = 0 ; ii < termCount ; ii++ )
+		{
+		config.iTerminator[ii] = terminators[ii];
+		}
+	LEAVEIFERROR(port.SetConfig(configBuf));
+
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Echoing received data\n"));
+
+	console->Read(consoleStatus);
+
+	TBuf8<256> readBuf;
+
+	FOREVER
+		{
+		port.Read(status, readBuf, pktlen);
+
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.ReadCancel();
+			break;
+			}
+
+		port.Write(status, readBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.WriteCancel();
+			break;
+			}
+		}
+
+	_printf(_L("\nTest complete\n"));
+
+	CleanupStack::PopAndDestroy(); // port	
+	}
+
+
+
+void AcmLoopback_TestL()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+	{
+	TRequestStatus consoleStatus;
+	TRequestStatus status;
+	RComm port;
+
+	_printf(_L("\n----------------------------------------\n"));
+	_printf(_L("This test listens for data on the ACM\n"));
+	_printf(_L("port and echoes anything it receives\n"));
+	_printf(_L("back to the PC. Press any key to quit.\n"));
+	_printf(_L("----------------------------------------\n\n"));
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	_printf(_L("Setting handshaking & receive buffer length\n"));
+
+	port.SetConfig(TheConfigBuf);
+	port.SetReceiveBufferLength(KReceiveBufferLength);
+
+	_printf(_L("Echoing received data\n"));
+
+	TBuf8<1024> readBuf;
+
+	console->Read(consoleStatus);
+
+	FOREVER
+		{
+		port.ReadOneOrMore(status, readBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.ReadCancel();
+			break;
+			}
+
+		port.Write(status, readBuf);
+		User::WaitForRequest(status, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (status != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(status.Int());
+				}
+			}
+		else
+			{
+			port.WriteCancel();
+			break;
+			}
+
+		_printf(_L("."));
+		}
+
+	_printf(_L("\nTest complete\n"));
+
+	CleanupStack::PopAndDestroy(); // port
+	}
+
+void SetHandshakingL()
+/**
+ * This function allows the user to select a new handshaking mode.
+ */
+	{
+	RComm port;
+
+	TCommCaps capsBuf;
+	TCommCapsV01& caps = capsBuf();
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.Caps(capsBuf);
+	_printf(_L("\nPort handshaking capabilities: 0x%X\n"), caps.iHandshake);
+	_printf(_L("Current handshaking options: 0x%X\n"), TheConfig.iHandshake);
+
+	_printf(_L("\nHandshaking options:\n"));
+	_printf(_L("1. No handshaking\n"));
+	_printf(_L("2. Toggle Xon/Xoff\n"));
+	_printf(_L("3. Toggle obey CTS\n"));
+	_printf(_L("4. Toggle obey DSR / free RTS\n"));
+	_printf(_L("5. Toggle write buffered complete\n"));
+
+	TInt key = (TInt) _getch();
+
+	switch (key)
+		{
+	case '1':
+		TheConfig.iHandshake = 0;
+		break;
+	case '2':
+		TheConfig.iHandshake ^= KConfigObeyXoff;
+		TheConfig.iHandshake ^= KConfigSendXoff;
+		break;
+	case '3':
+		TheConfig.iHandshake ^= KConfigObeyCTS;
+		break;
+	case '4':
+		TheConfig.iHandshake ^= KConfigObeyDSR;
+		TheConfig.iHandshake ^= KConfigFreeRTS;
+		break;
+	case '5':
+		TheConfig.iHandshake ^= KConfigWriteBufferedComplete;
+		break;
+	default:
+		break;
+		}
+
+	LEAVEIFERROR(port.SetConfig(TheConfigBuf));
+
+	_printf(_L("Handshaking options now: 0x%X\n"), TheConfig.iHandshake);
+
+	CleanupStack::PopAndDestroy();
+	}
+
+
+void mainL()
+/**
+ * This function controls test execution as directed by the user.
+ */
+	{
+		 char ch;
+
+	TInt ret = User::LoadLogicalDevice(KUsbLddName);
+	if ((ret != KErrNone) && (ret != KErrAlreadyExists))
+		LEAVE(ret);
+
+	_printf(_L("Loaded USB LDD\n"));
+
+	LEAVEIFERROR(TheCommServ.Connect());
+	_printf(_L("Connected to C32\n"));
+
+	RComm port;
+
+	// The port's configuration seems to be junk at the beginning, so we set it to known values.
+
+	TheConfig.iRate = EBps115200;
+	TheConfig.iDataBits = EData8;
+	TheConfig.iStopBits = EStop1;
+	TheConfig.iParity = EParityNone;
+	TheConfig.iHandshake = 0;
+	TheConfig.iTerminatorCount = 0;
+
+	LEAVEIFERROR(port.Open(TheCommServ, KUsbPortNameAcm1, ECommExclusive, ECommRoleDCE));
+	CleanupClosePushL(port);
+
+	port.SetConfig(TheConfigBuf);
+	_printf(_L("----------------------------------------\n"));
+	_printf(_L("Initial port config:\n"));
+	_printf(_L("  Rate: %d bps\n"), TheConfig.iRate);
+	_printf(_L("  Data bits: %d. Parity type: %d. Stop bits: %d\n"),
+		TheConfig.iStopBits, TheConfig.iParity, TheConfig.iStopBits);
+	_printf(_L("  Handshaking options: 0x%X\n"), TheConfig.iHandshake);
+	_printf(_L("----------------------------------------\n\n"));
+
+	CleanupStack::PopAndDestroy(); // port
+
+
+	TBool noExit = ETrue;
+	while (noExit)
+		{
+		_printf(_L("\nAvailable tests:\n\n"));
+		  _printf(_L("1. Read loopback from ACM0->ACM1 test\n"));
+		_printf(_L("\nSelection (x to exit): "));
+
+		ch = (char) _getch();
+		_printf(_L("\n"));
+		switch (ch)
+		{
+		case '1': ReadLoopbackFromPortAToPortBTestL(); break;
+		case 'x':
+		case 'X': noExit = EFalse; break;
+		default:  _printf(_L("\nInvalid key\n")); break;
+			 }
+		}
+	TheCommServ.Close();
+	}
+
+void consoleMainL()
+/**
+ * Create a console and run mainL().
+ */
+	{
+	console=Console::NewL(_L("T_ACM"),TSize(KConsFullScreen,KConsFullScreen));
+	CleanupStack::PushL(console);
+	mainL();
+	_printf(_L("[ press any key ]"));
+	_getch();
+	CleanupStack::PopAndDestroy();
+	}
+
+GLDEF_C TInt E32Main()
+/**
+ * Runs the test as specified in the ACM unit test specification.
+ */
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanupStack=CTrapCleanup::New();
+
+	// create the timer for use during some of the tests
+	timer.CreateLocal();
+
+	TRAP_IGNORE(consoleMainL());
+	delete cleanupStack;
+	__UHEAP_MARKEND;
+	return 0;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_termusb/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* 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 "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:
+* BLD.INF for t_termusb
+* BLD.INF for t_termusb
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+t_termusb.iby    /epoc32/rom/include/t_termusb.iby
+
+PRJ_TESTMMPFILES
+t_termusb.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_termusb/group/t_termusb.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* Copyright (c) 2003-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:
+* Test program for serial port
+*
+*/
+
+#ifndef __T_TERMUSB_IBY__
+#define __T_TERMUSB_IBY__
+
+#include <c32.iby>
+
+file=ABI_DIR\DEBUG_DIR\t_termusb.exe    System\Programs\t_termusb.exe
+file=ABI_DIR\DEBUG_DIR\t_termusb2.exe    System\Programs\t_termusb2.exe
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_termusb/group/t_termusb.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+TARGET         t_termusb.exe
+TARGETTYPE     EXE
+SOURCEPATH    ../src
+SOURCE         t_termusb.cpp
+LIBRARY        	euser.lib
+LIBRARY         efsrv.lib 
+LIBRARY         c32.lib 
+LIBRARY         usbman.lib
+LIBRARY         econs.lib
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_termusb/src/t_termusb.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,865 @@
+/*
+* Copyright (c) 1995-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:
+* T_TERM.CPP
+* Dumb terminal
+*
+*/
+
+#define VERBOSE
+#define _PC_CARD_SERIAL
+
+#include <e32test.h>
+#include <e32twin.h>
+#include <c32comm.h>
+#include <d32comm.h>
+#include <f32file.h>
+#include <hal.h>
+#include <usbman.h>
+
+#include <flogger.h>
+
+void StartLoader();
+
+const TPtrC KCaptureFileName=_L("C:\\CAPTURE.TXT");
+const TPtrC KUploadFileName=_L("C:\\UPLOAD.TXT");
+RFs TheFs;
+RFile TheCaptureFile;
+RFile TheUploadFile;
+
+TBuf8<1024> ch;
+TBuf8<1024> chw;
+TBuf<1024>	buf;
+TCommConfig TheConfigBuf;
+TCommConfigV01 &TheConfig=TheConfigBuf();
+TInt TheLastError=KErrNone;
+
+const TInt KMaxDumpLength=0x100;
+
+enum TTermPanic
+	{
+	EStraySignal,
+	ELoadPhysicalDeviceErr,
+	ELoadLogicalDeviceErr,
+	EOpenErr,
+	EConnectFsErr,
+	ECaptureFileOpen,
+	EOpenUploadFile,
+	};
+
+enum TRxMode
+	{
+	ENormal=0,
+	ELoopBack=1,
+	ECountChars=2,
+	ERxOff=3,
+	ECapture=128,
+	};
+
+struct SSettings
+	{
+	TBool iNotFinished;
+	TBool iLocalEcho;
+	TInt iAddLF;
+	TBool iDump;
+	TInt iDumpRepeat;
+	TBuf8<KMaxDumpLength> iDumpData;
+	TRxMode iRxMode;
+	TInt iCharCount;
+	TInt iMaxInOne;
+	TInt iInfraRed;
+	TBool iWaitAfterWrite;
+	// Fifo
+	// Brk
+	};
+
+LOCAL_D SSettings TheSettings;
+LOCAL_D RUsb TheUsbServer;
+LOCAL_D RCommServ TheCommServer;
+LOCAL_D RComm TheCommPort;
+LOCAL_D RConsole TheWindow;
+
+LOCAL_C TInt CommWriteSync(RComm &aComm, const TDesC8 &aData)
+	{
+	TRequestStatus stat;
+	aComm.Write(stat, aData);
+	User::WaitForRequest(stat);
+	return stat.Int();
+	}
+
+LOCAL_C TInt WaitAfterWrite(RComm& aComm)
+	{
+	TRequestStatus s;
+	TBuf8<1> b;
+	aComm.Write(s,b);
+	User::WaitForRequest(s);
+	return s.Int();
+	}
+
+LOCAL_C TInt RateToInt(TBps aRate)
+//
+//
+//
+	{
+
+	switch (aRate)
+		{
+	case EBps115200:	return 115200;
+    case EBps57600:	return 57600;
+    case EBps38400:	return 38400;
+    case EBps19200:	return 19200;
+    case EBps9600:	return 9600;
+	case EBps7200:	return 7200;
+    case EBps4800:	return 4800;
+	case EBps3600:	return 3600;
+    case EBps2400:	return 2400;
+	case EBps2000:	return 2000;
+	case EBps1800:	return 1800;
+    case EBps1200:	return 1200;
+    case EBps600:	return 600;
+    case EBps300:	return 300;
+    case EBps150:	return 150;
+	case EBps134:	return 134;
+    case EBps110:	return 110;
+	case EBps75:	return 75;
+	case EBps50:	return 50;
+	default:	return -1;
+		}
+	}
+
+LOCAL_C TBps IntToRate(TInt aVal)
+//
+//
+//
+	{
+
+	if (aVal>=115200) return EBps115200;
+	if (aVal>=57600) return EBps57600;
+	if (aVal>=38400) return EBps38400;
+	if (aVal>=19200) return EBps19200;
+	if (aVal>=9600) return EBps9600;
+	if (aVal>=7200) return EBps7200;
+	if (aVal>=4800) return EBps4800;
+	if (aVal>=3600) return EBps3600;
+	if (aVal>=2400) return EBps2400;
+	if (aVal>=2000) return EBps2000;
+	if (aVal>=1800) return EBps1800;
+	if (aVal>=1200) return EBps1200;
+	if (aVal>=600) return EBps600;
+	if (aVal>=300) return EBps300;
+	if (aVal>=150) return EBps150;
+	if (aVal>=134) return EBps134;
+	if (aVal>=110) return EBps110;
+	if (aVal>=75) return EBps75;
+	if (aVal>=50) return EBps50;
+	return EBps50;
+	}
+
+LOCAL_C void ConfigString(TDes &aBuf, const TCommConfigV01 &aConfig, const SSettings &aSettings)
+//
+//	Construct a Configuaration string
+//
+	{
+
+	// Config
+	aBuf.Format(_L(" %d "), RateToInt(aConfig.iRate));
+	switch (aConfig.iParity)
+		{
+	case EParityEven: aBuf.Append(_L("E")); break;
+	case EParityOdd: aBuf.Append(_L("O")); break;
+	case EParityNone: aBuf.Append(_L("N")); break;
+    default: break;
+		}
+	switch (aConfig.iDataBits)
+		{
+	case EData5: aBuf.Append(_L("5")); break;
+	case EData6: aBuf.Append(_L("6")); break;
+	case EData7: aBuf.Append(_L("7")); break;
+	case EData8: aBuf.Append(_L("8")); break;
+    default: break;
+		}
+	if (aConfig.iStopBits==EStop1)
+		aBuf.Append(_L("1 "));
+	else
+		aBuf.Append(_L("2 "));
+
+	aBuf.Append(_L("Use:"));
+	if (aConfig.iHandshake==0)
+		aBuf.Append(_L("NoControl "));
+	if (aConfig.iHandshake&(KConfigObeyXoff|KConfigSendXoff))
+		aBuf.Append(_L("XonXoff "));
+	if (aConfig.iHandshake&KConfigObeyCTS)
+		aBuf.Append(_L("CTS/RTS "));
+	if (aConfig.iHandshake&KConfigObeyDSR)
+		aBuf.Append(_L("DSR/DTR "));
+	if (aConfig.iHandshake&KConfigWriteBufferedComplete)
+		aBuf.Append(_L("Early "));
+	//|KConfigObeyDCD|KConfigFailDCD|))
+
+
+//	if (aConfig.iBreak==TEiger::EBreakOn)
+//		aBuf.Append(_L("Brk "));
+	if (aConfig.iFifo==EFifoEnable)
+		aBuf.Append(_L("Fifo "));
+	
+	// Settings
+	if (aSettings.iLocalEcho)
+		aBuf.Append(_L("LocalEcho "));
+	if (aSettings.iAddLF)
+		aBuf.Append(_L("AddLF "));
+	// rx mode
+	if ((aSettings.iRxMode&~ECapture)==ELoopBack)
+		aBuf.Append(_L("LpBk"));
+	else if ((aSettings.iRxMode&~ECapture)==ECountChars)
+		aBuf.Append(_L("CtCh"));
+	//else if (aSettings.iRxMode==ERxOff)
+		//{
+		//aBuf.Append(_L("NoRx"));
+		//}
+	aBuf.Append(_L(" "));
+	aBuf.AppendNum((TInt)(RThread().Priority()));
+	if (aSettings.iInfraRed==1)
+		aBuf.Append(_L("IR1"));
+	else if (aSettings.iInfraRed==2)
+		aBuf.Append(_L("IR2"));
+	if (aSettings.iWaitAfterWrite)
+		aBuf.Append(_L("Wait"));
+
+	aBuf.Append(_L("Last Err: "));
+	if (TheLastError==KErrNone)
+		aBuf.Append(_L("None "));
+	else if (TheLastError==KErrCommsLineFail)
+		aBuf.Append(_L("LineFail "));
+	else if (TheLastError==KErrCommsFrame)
+		aBuf.Append(_L("Frame "));
+	else if (TheLastError==KErrCommsOverrun)
+		aBuf.Append(_L("Overrun "));
+	else if (TheLastError==KErrCommsParity)
+		aBuf.Append(_L("Parity "));
+	else if (TheLastError==KErrAbort)
+		aBuf.Append(_L("Abort "));
+	else if (TheLastError==KErrBadPower)
+		aBuf.Append(_L("BadPower "));
+	else if (TheLastError==KErrNotReady)
+		aBuf.Append(_L("NotReady "));
+	else
+		aBuf.AppendNum(TheLastError);
+	}
+
+LOCAL_C void GetRate(TBps &aRate, const TDesC &aDes)
+//
+//	Set Baud rate
+//
+	{
+
+	TInt32 i;
+	if (TLex(aDes).Val(i)==KErrNone)
+		aRate=IntToRate(i);
+	}
+
+LOCAL_C void GetParity(TParity &aParity, const TDesC &aDes)
+//
+//
+//
+	{
+
+	if (aDes.FindF(_L("O"))>=0)
+		aParity=EParityOdd;
+  	if (aDes.FindF(_L("E"))>=0)
+		aParity=EParityEven;
+	if (aDes.FindF(_L("N"))>=0)
+		aParity=EParityNone;
+	}
+
+LOCAL_C void GetHandshake(TUint &aHandshake, const TDesC &aDes)
+//
+//
+//
+	{
+
+	if (aDes.FindF(_L("N"))>=0)
+		aHandshake=0;
+	if (aDes.FindF(_L("X"))>=0)
+		aHandshake=KConfigObeyXoff|KConfigSendXoff;
+	if (aDes.FindF(_L("C"))>=0)
+		aHandshake=KConfigObeyCTS;
+	if (aDes.FindF(_L("D"))>=0)
+		aHandshake=KConfigObeyDSR|KConfigFreeRTS;
+	if (aDes.FindF(_L("E"))>=0)
+		aHandshake|=KConfigWriteBufferedComplete;
+	}
+
+LOCAL_C void GetStopBit(TStopBits &aStop, const TDesC &aDes)
+	{
+
+	TInt32 in;
+	if (TLex(aDes).Val(in)==KErrNone)
+		{
+		if (in==1)
+			aStop=EStop1;
+		if (in==2)
+			aStop=EStop2;
+		}
+	else
+		{
+		if (aStop==EStop1)
+			aStop=EStop2;
+		else
+			aStop=EStop1;
+		}
+	}
+
+LOCAL_C void GetLength(TDataBits &aData, const TDesC &aDes)
+	{
+
+	TInt32 in;
+	if (TLex(aDes).Val(in)==KErrNone)
+		{
+		switch (in)
+			{
+		case 5: aData=EData5; break;
+		case 6: aData=EData6; break;
+		case 7: aData=EData7; break;
+		case 8: aData=EData8; break;
+		default: break;
+			}
+		}
+	}
+
+LOCAL_C void GetInfraRedMode(TInt &aInfraRed, const TDesC &aDes)
+	{
+
+	if (aDes.FindF(_L("0"))>=0)
+		aInfraRed=0;
+	else if (aDes.FindF(_L("1"))>=0)
+		aInfraRed=1;
+	else if (aDes.FindF(_L("2"))>=0)
+		aInfraRed=2;
+	}
+
+LOCAL_C void GetWaitMode(TBool &aWait, const TDesC &aDes)
+	{
+
+	if (aDes.FindF(_L("0"))>=0)
+		aWait=EFalse;
+	else if (aDes.FindF(_L("1"))>=0)
+		aWait=ETrue;
+	}
+
+/*LOCAL_C void GetBreak(const TDesC &aDes)
+	{
+
+	if (aDes==_L(""))
+		{
+		if (data.iBreak==TEiger::EBreakOn)
+			data.iBreak=TEiger::EBreakOff;
+		else
+			data.iBreak=TEiger::EBreakOn;
+		}
+	if (aDes.FindF(_L("N"))>=0)
+		data.iBreak=TEiger::EBreakOn;
+	if (aDes.FindF(_L("F"))>=0)
+		data.iBreak=TEiger::EBreakOff;
+	SetConfig();
+	}
+*/
+LOCAL_C void GetFifo(TUint& aFifo, const TDesC &aDes)
+	{
+
+	if (aDes==_L(""))
+		{
+		if (aFifo==EFifoEnable)
+			aFifo=EFifoDisable;
+		else
+			aFifo=EFifoEnable;
+		}
+	if (aDes.FindF(_L("N"))>=0)
+		aFifo=EFifoEnable;
+	if (aDes.FindF(_L("F"))>=0)
+		aFifo=EFifoDisable;
+	}
+
+LOCAL_C void GetEcho(TBool &aEcho, const TDesC &aDes)
+	{
+
+	if (aDes==_L(""))
+		{
+		if (aEcho)
+			aEcho=EFalse;
+		else
+			aEcho=ETrue;
+		}
+	if (aDes.FindF(_L("N"))>=0)
+		aEcho=ETrue;
+	if (aDes.FindF(_L("F"))>=0)
+		aEcho=EFalse;
+	}
+
+LOCAL_C void GetRxMode(TRxMode &aMode, const TDesC &aDes)
+	{
+
+	if (aDes.FindF(_L("O"))>=0)
+		aMode=ERxOff;
+	if (aDes.FindF(_L("N"))>=0)
+		aMode=ENormal;
+	if (aDes.FindF(_L("L"))>=0)
+		aMode=ELoopBack;
+	if (aDes.FindF(_L("C"))>=0)
+		aMode=ECountChars;
+	if (aDes.FindF(_L("S"))>=0)
+		{
+		aMode=TRxMode(TInt(aMode)|ECapture);
+		TInt r=TheCaptureFile.Create(TheFs,KCaptureFileName,EFileWrite);
+		if (r!=KErrNone)
+			User::Panic(_L("T_TERM CAP"),r);
+		}
+	if (aDes.FindF(_L("Z"))>=0)
+		{
+		aMode=TRxMode(TInt(aMode)&~ECapture);
+		TheCaptureFile.Close();
+		}
+	if (aDes.FindF(_L("0"))>=0)
+		RThread().SetPriority(EPriorityNormal);
+	if (aDes.FindF(_L("1"))>=0)
+		RThread().SetPriority(EPriorityAbsoluteHigh);
+	}
+
+LOCAL_C void GetDump(SSettings &aSettings, const TDesC &aDes)
+	{
+	
+	TInt32 in;
+	if (TLex(aDes).Val(in)==KErrNone)
+		{
+		aSettings.iDump=ETrue;
+		aSettings.iDumpRepeat=in;
+		return;
+		}
+	if (aDes.Length()!=0)
+		{
+		TBuf8<16> b=_L8("0123456789ABCDEF");
+		aSettings.iDumpData.Zero();
+		TInt i;
+		for (i=0; i<16; i++)
+			aSettings.iDumpData+=b;
+		return;
+		}
+	RConsole dialog;
+	TInt r=dialog.Init(_L("Type data to dump to comm.  Escape to finish"),TSize(KConsFullScreen,KConsFullScreen));
+	r=dialog.Control(_L("+Maximize +NewLine"));
+	aSettings.iDumpData=_L8("");
+	TConsoleKey k;
+	do 
+		{
+		dialog.Read(k);
+		if (k.Code()==EKeyEscape)
+			break;
+		TText a=(TText)k.Code();
+		TPtrC s(&a,1);
+		dialog.Write(s);
+		aSettings.iDumpData.Append(k.Code());
+		//if (a=='\r')
+		//	dialog.Write(_L("\n"));
+		} while (aSettings.iDumpData.Length()<KMaxDumpLength);
+
+	dialog.Destroy();
+	dialog.Close();
+	}
+
+
+
+LOCAL_C void CommandWindow(TCommConfigV01 &aConfig, SSettings &aSettings)
+//
+//	Display some words of wisdom and get a command from the user
+//
+	{
+
+	TBuf<32> b;
+	b.Num(aSettings.iCharCount);
+	b+=_L(" ");
+	b.AppendNum(aSettings.iMaxInOne);
+	b+=_L("\n");
+	RConsole dialog;
+	TInt r=dialog.Init(_L("."),TSize(KConsFullScreen,KConsFullScreen));
+	r=dialog.Control(_L("+Maximize +NewLine"));
+	dialog.Write(_L("B<n> Set Bps to n               P[Odd|Even|None] Set Parity\n"));
+	dialog.Write(_L("S[1|2] Set/Toggle stop bits     L<n> Set Data Length (5<=n<=8)\n"));
+	dialog.Write(_L("K[On|Off] Set/Toggle BRK        F[On|Off] Set/Toggle Fifo\n"));
+	dialog.Write(_L("H[None|X|CtsRts|DsrDtr] Handshaking\n"));
+	dialog.Write(_L("D[<n>] Set data or Dump data n times\n"));
+ 	dialog.Write(_L("J Toggle Add Line Feed          E Toggle local Echo\n"));
+	dialog.Write(_L("U [NLCO] Set Rx Mode to Normal, Loopback, Count, Off \n"));
+	dialog.Write(b);
+	dialog.Write(_L("Q Quit\n"));
+	dialog.Write(_L("\n:"));
+
+	//	Get a command
+	TBuf<0x80> des=_L("");
+	TConsoleKey k;
+	dialog.Read(k);
+	while ((k.Code()!='\r') && (k.Code()!=EKeyEscape))
+		{
+		TText a=(TText)k.Code();
+		TPtrC s(&a,1);
+		dialog.Write(s);
+		des.Append(k.Code());
+		dialog.Read(k);
+		}
+
+	if (k.Code()!=EKeyEscape && des.Length()>0)
+		{
+		des.UpperCase();
+		TBuf<0x80> right(des.Right(des.Length()-1));
+		if (des[0]=='B')
+			GetRate(aConfig.iRate, right);
+		if (des[0]=='P')
+			GetParity(aConfig.iParity, right);
+		if (des[0]=='S')
+			GetStopBit(aConfig.iStopBits, right);
+		if (des[0]=='L')
+			GetLength(aConfig.iDataBits, right);
+//		if (des[0]=='K')
+//			GetBreak(aSettings.iBreak, right);
+		if (des[0]=='F')
+			GetFifo(aConfig.iFifo, right);
+		if (des[0]=='I')
+			GetInfraRedMode(aSettings.iInfraRed, right);
+		if (aSettings.iInfraRed==1)
+			{
+			aConfig.iSIREnable=ESIREnable;
+			aConfig.iSIRSettings=KConfigSIRPulseWidthMinimum;
+			}
+		else if (aSettings.iInfraRed==2)
+			{
+			aConfig.iSIREnable=ESIREnable;
+			aConfig.iSIRSettings=KConfigSIRPulseWidthMaximum;
+			}
+		else
+			{
+			aConfig.iSIREnable=ESIRDisable;
+			aConfig.iSIRSettings=0;
+			}
+		if (des[0]=='H')
+			GetHandshake(aConfig.iHandshake, right);
+		if (des[0]=='E')
+			GetEcho(aSettings.iLocalEcho, right);
+		if (des[0]=='D')
+			GetDump(aSettings, right);
+		if (des[0]=='J')
+			aSettings.iAddLF=!aSettings.iAddLF;
+		if (des[0]=='U')
+			{
+			GetRxMode(aSettings.iRxMode, right);
+			aSettings.iCharCount=0;
+			aSettings.iMaxInOne=0;
+			}
+		if (des[0]=='Q')
+			aSettings.iNotFinished=EFalse;
+		if (des[0]=='W')
+			GetWaitMode(aSettings.iWaitAfterWrite, right);
+		}
+
+	dialog.Destroy();
+	dialog.Close();
+	}
+
+// The following decl is a hack for the Eiger build.
+// Without it T_TERM.EXE has no .data or .bss section.  This means the data offset
+// field in the file header is zero.  When the kernel comes to copy the data sections
+// from rom into ram it reads the data size field (which is the size of all data
+// sections) from the header and tries to copy data from 0x00000000 (the data offset),
+// causing a data abort.
+TInt dummy=10;	 
+#if defined (__WINS__)
+#define PDD_NAME _L("ECDRV")
+#define LDD_NAME _L("ECOMM")
+#else
+#define PDD_NAME _L("EUARTn")
+#define LDD_NAME _L("EUSBC")
+#endif
+
+#define CSY_NAME _L("ECACM")
+#define PORT_NAME _L("ACM::0")
+
+LOCAL_C void ProcessError(TInt anError)
+	{
+	TBuf<80> buf;
+	if (anError!=KErrNone)
+		{
+		TheLastError=anError;
+		ConfigString(buf, TheConfig, TheSettings);
+		TheWindow.SetTitle(buf);
+		}
+	}
+
+LOCAL_C void HandleRx(TRequestStatus& aStatus, TBool aFinish)
+	{
+	chw.Copy(ch);
+	switch(TheSettings.iRxMode & ~ECapture)
+		{
+		case ENormal:
+			{
+			buf.Copy(chw);
+			TheWindow.Write(buf);
+			break;
+			}
+		case ELoopBack:
+			{
+			ProcessError(CommWriteSync(TheCommPort,chw));
+			if (TheSettings.iWaitAfterWrite)
+				ProcessError(WaitAfterWrite(TheCommPort));
+			break;
+			}
+		case ECountChars:
+			{
+			TInt l=chw.Length();
+			TheSettings.iCharCount+=l;
+			if (l>TheSettings.iMaxInOne)
+				TheSettings.iMaxInOne=l;
+			break;
+			}
+		}
+	if (TheSettings.iRxMode & ECapture)
+		TheCaptureFile.Write(chw);
+	if (TheSettings.iRxMode!=ERxOff)
+		{
+		if ((TheSettings.iRxMode & ~ECapture)==ELoopBack && !aFinish)
+			TheCommPort.Read(aStatus, ch);
+		else
+			TheCommPort.ReadOneOrMore(aStatus, ch);
+		}
+	}
+
+GLDEF_C TInt E32Main()
+//
+// Term
+//
+    {
+	// Open the window asap
+	TheWindow.Init(_L("TERM"),TSize(KConsFullScreen,KConsFullScreen));
+	RDebug::Print(_L("E32Main: Initialised Window!"));
+
+    // Initialisation
+	TBuf <0x100> cmd;
+	User::CommandLine(cmd);
+
+	// Load Device Drivers
+	TInt r;
+
+	TheWindow.Write(_L("Starting\r\n"));
+	r=User::LoadLogicalDevice(LDD_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+    	TConsoleKey keystroke;
+		TBuf<32> outBuf;
+		outBuf.AppendFormat(_L("Failed 0x%X\n\r"),r);
+		TheWindow.Write(outBuf);
+		TheWindow.Read(keystroke);
+		User::Panic(_L("T_TERM"), ELoadLogicalDeviceErr);
+		}
+
+	TheWindow.Write(_L("Loaded LDD\r\n"));
+
+	r=TheFs.Connect();
+	if (r!=KErrNone)
+		User::Panic(_L("T_TERM"), EConnectFsErr);
+
+	TheWindow.Write(_L("Connected to file server\r\n"));
+
+	TheSettings.iNotFinished=ETrue;
+	TheSettings.iLocalEcho=ETrue;
+	TheSettings.iAddLF=FALSE;
+	TheSettings.iDump=EFalse;
+	TheSettings.iDumpRepeat=1;
+	TheSettings.iDumpData=_L8("Some Text\r");
+	TheSettings.iRxMode=ENormal;
+	TheSettings.iCharCount=0;
+	TheSettings.iMaxInOne=0;
+	TheSettings.iInfraRed=0;
+	TheSettings.iWaitAfterWrite=EFalse;
+	
+	r = StartC32();
+	if (r!=KErrNone && r !=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed to start C32. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+
+	TheWindow.Write(_L("Started c32\r\n"));
+
+	// Comms Config
+	r = TheUsbServer.Connect();
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to connect to UsbMan Server. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+
+	TheWindow.Write(_L("Connected to UsbMan Server\r\n"));
+
+	TRequestStatus status;
+	TheUsbServer.Start(status);
+	User::WaitForRequest(status);
+
+	if (status.Int() != KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Unable to start USB services. Error %d"), status.Int());
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+
+	TheWindow.Write(_L("Started USB services\r\n"));
+
+	r = TheCommServer.Connect();
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to Connect to C32. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+
+	TheWindow.Write(_L("Connected to C32 Server\r\n"));
+
+	r = TheCommServer.LoadCommModule(CSY_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed to load USB CSY. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+
+	TheWindow.Write(_L("Loaded USB CSY\r\n"));
+
+	r = TheCommPort.Open(TheCommServer, PORT_NAME,ECommExclusive); // Comm port
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to Open USB Comm Port. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+
+	TheWindow.Write(_L("Opened USB Comm Port\r\n"));
+
+	TheCommPort.Config(TheConfigBuf);	// get config
+	TheConfig.iHandshake=0; //KConfigObeyXoff|KConfigSendXoff;
+	TheCommPort.SetConfig(TheConfigBuf);
+	TheCommPort.SetReceiveBufferLength(8192);
+
+	//	Set up a console window
+	TheWindow.Control(_L("+Maximize +Newline"));
+	TheWindow.Write(_L("Startup complete\r\n\nType '*' for commands\r\n"));
+	TBuf<0x80> buf;
+	ConfigString(buf, TheConfig, TheSettings);
+	TheWindow.SetTitle(buf);
+
+	TConsoleKey k;
+	TRequestStatus readStat, keyStat;
+
+	// main loop
+	TheWindow.Read(k, keyStat);
+	TheCommPort.ReadOneOrMore(readStat, ch);
+	do
+		{
+		User::WaitForRequest(readStat, keyStat);
+		if (keyStat!=KRequestPending)
+			{
+			TUint32 c=k.Code();
+			switch(c)
+    			{
+    			case '\x3':
+    				{
+    				TheCommPort.ReadCancel();
+    				HandleRx(readStat,ETrue);
+    				}
+    				break;
+                case '*':
+		    		{
+		    		CommandWindow(TheConfig, TheSettings);
+		    		TheCommPort.ReadCancel();
+		    		TheCommPort.SetConfig(TheConfigBuf);
+		    		if (TheSettings.iRxMode!=ERxOff)
+		    			TheCommPort.ReadOneOrMore(readStat, ch);
+		    		ConfigString(buf, TheConfig, TheSettings);
+		    		TheWindow.SetTitle(buf);
+		    		}
+		    		break;
+		    	case '\x15':
+		    		{
+		    		TInt r=TheUploadFile.Open(TheFs,KUploadFileName,EFileRead);
+		    		if (r!=KErrNone)
+		    			User::Panic(_L("T_TERM"),EOpenUploadFile);
+		    		TBuf8<0x100> buf;
+		    		do	{
+		    			TheUploadFile.Read(buf);
+		    			ProcessError(CommWriteSync(TheCommPort,buf));
+		    			if (TheSettings.iWaitAfterWrite)
+		    				ProcessError(WaitAfterWrite(TheCommPort));
+		    			} while(buf.Length()!=0);
+		    		TheUploadFile.Close();
+		    		}
+		    		break;
+		    	default:
+		    		if (c<256)
+		    			{
+		    			TText8 a8=(TText8)c;
+		    			TText a=(TText)c;
+		    			TPtrC8 s8(&a8,1);
+		    			TPtrC s(&a,1);
+		    			ProcessError(CommWriteSync(TheCommPort, s8));
+		    			if (TheSettings.iWaitAfterWrite)
+		    				ProcessError(WaitAfterWrite(TheCommPort));
+		    			if (TheSettings.iLocalEcho)
+		    				{
+		    				TheWindow.Write(s);
+		    				if (c=='\r' && TheSettings.iAddLF) TheWindow.Write(_L("\n"));
+		    				}
+		    			}
+		    		break;
+		    	}
+			TheWindow.Read(k, keyStat);
+			}
+		else if (readStat!=KRequestPending)
+			{
+			ProcessError(readStat.Int());
+			if (readStat!=KErrAbort && readStat!=KErrBadPower && readStat!=KErrNotReady)
+				HandleRx(readStat,EFalse);
+			else
+				{
+				if (TheSettings.iRxMode!=ERxOff)
+					TheCommPort.ReadOneOrMore(readStat, ch);
+				}
+			}
+		else
+			{
+			User::Panic(_L("T_TERM"), EStraySignal);
+			}
+
+		if (TheSettings.iDump)
+			{
+			TheSettings.iDump=EFalse;
+			TInt i;
+			for (i=0; i<TheSettings.iDumpRepeat; i++)
+				{
+				ProcessError(CommWriteSync(TheCommPort, TheSettings.iDumpData));
+				if (TheSettings.iWaitAfterWrite)
+					ProcessError(WaitAfterWrite(TheCommPort));
+				}
+			}
+		} while(TheSettings.iNotFinished);
+
+	TheWindow.Destroy();
+	TheWindow.Close();
+	TheCommPort.Close();
+	TheCommServer.Close();
+	TheUsbServer.Stop();
+	TheUsbServer.Close();
+
+	return(KErrNone);
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_termusb2/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* 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 "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:
+* BLD.INF for t_termusb2
+* BLD.INF for t_termusb2
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+t_termusb2.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_termusb2/group/t_termusb2.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+TARGET         t_termusb2.exe
+TARGETTYPE     EXE
+SOURCEPATH    ../src
+SOURCE         t_termusb2.cpp
+LIBRARY        	euser.lib
+LIBRARY         efsrv.lib 
+LIBRARY         c32.lib 
+LIBRARY         usbman.lib
+LIBRARY         econs.lib
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_termusb2/src/t_termusb2.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,881 @@
+/*
+* Copyright (c) 1995-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:
+* T_TERM.CPP
+* Dumb terminal
+*
+*/
+
+#define VERBOSE
+#define _PC_CARD_SERIAL
+
+#include <e32test.h>
+#include <e32twin.h>
+#include <c32comm.h>
+#include <d32comm.h>
+#include <f32file.h>
+#include <hal.h>
+#include <usbman.h>
+
+void StartLoader();
+
+const TPtrC KCaptureFileName=_L("C:\\CAPTURE.TXT");
+const TPtrC KUploadFileName=_L("C:\\UPLOAD.TXT");
+RFs TheFs;
+RFile TheCaptureFile;
+RFile TheUploadFile;
+
+TBuf8<1024> ch;
+TBuf8<1024> chw;
+TBuf<1024>	buf;
+TCommConfig TheConfigBuf;
+TCommConfigV01 &TheConfig=TheConfigBuf();
+TInt TheLastError=KErrNone;
+
+const TInt KMaxDumpLength=0x100;
+
+enum TTermPanic
+	{
+	EStraySignal,
+	ELoadPhysicalDeviceErr,
+	ELoadLogicalDeviceErr,
+	EOpenErr,
+	EConnectFsErr,
+	ECaptureFileOpen,
+	EOpenUploadFile,
+	};
+
+enum TRxMode
+	{
+	ENormal=0,
+	ELoopBack=1,
+	ECountChars=2,
+	ERxOff=3,
+	ECapture=128,
+	};
+
+struct SSettings
+	{
+	TBool iNotFinished;
+	TBool iLocalEcho;
+	TInt iAddLF;
+	TBool iDump;
+	TInt iDumpRepeat;
+	TBuf8<KMaxDumpLength> iDumpData;
+	TRxMode iRxMode;
+	TInt iCharCount;
+	TInt iMaxInOne;
+	TInt iInfraRed;
+	TBool iWaitAfterWrite;
+	// Fifo
+	// Brk
+	};
+
+LOCAL_D SSettings TheSettings;
+LOCAL_D RUsb TheUsbServer;
+LOCAL_D RCommServ TheCommServer;
+LOCAL_D RComm TheCommPort;
+LOCAL_D RConsole TheWindow;
+
+LOCAL_C TInt CommWriteSync(RComm &aComm, const TDesC8 &aData)
+	{
+	TRequestStatus stat;
+	aComm.Write(stat, aData);
+	User::WaitForRequest(stat);
+	return stat.Int();
+	}
+
+LOCAL_C TInt WaitAfterWrite(RComm& aComm)
+	{
+	TRequestStatus s;
+	TBuf8<1> b;
+	aComm.Write(s,b);
+	User::WaitForRequest(s);
+	return s.Int();
+	}
+
+LOCAL_C TInt RateToInt(TBps aRate)
+//
+//
+//
+	{
+
+	switch (aRate)
+		{
+	case EBps115200:	return 115200;
+    case EBps57600:	return 57600;
+    case EBps38400:	return 38400;
+    case EBps19200:	return 19200;
+    case EBps9600:	return 9600;
+	case EBps7200:	return 7200;
+    case EBps4800:	return 4800;
+	case EBps3600:	return 3600;
+    case EBps2400:	return 2400;
+	case EBps2000:	return 2000;
+	case EBps1800:	return 1800;
+    case EBps1200:	return 1200;
+    case EBps600:	return 600;
+    case EBps300:	return 300;
+    case EBps150:	return 150;
+	case EBps134:	return 134;
+    case EBps110:	return 110;
+	case EBps75:	return 75;
+	case EBps50:	return 50;
+	default:	return -1;
+		}
+	}
+
+LOCAL_C TBps IntToRate(TInt aVal)
+//
+//
+//
+	{
+
+	if (aVal>=115200) return EBps115200;
+	if (aVal>=57600) return EBps57600;
+	if (aVal>=38400) return EBps38400;
+	if (aVal>=19200) return EBps19200;
+	if (aVal>=9600) return EBps9600;
+	if (aVal>=7200) return EBps7200;
+	if (aVal>=4800) return EBps4800;
+	if (aVal>=3600) return EBps3600;
+	if (aVal>=2400) return EBps2400;
+	if (aVal>=2000) return EBps2000;
+	if (aVal>=1800) return EBps1800;
+	if (aVal>=1200) return EBps1200;
+	if (aVal>=600) return EBps600;
+	if (aVal>=300) return EBps300;
+	if (aVal>=150) return EBps150;
+	if (aVal>=134) return EBps134;
+	if (aVal>=110) return EBps110;
+	if (aVal>=75) return EBps75;
+	if (aVal>=50) return EBps50;
+	return EBps50;
+	}
+
+LOCAL_C void ConfigString(TDes &aBuf, const TCommConfigV01 &aConfig, const SSettings &aSettings)
+//
+//	Construct a Configuaration string
+//
+	{
+
+	// Config
+	aBuf.Format(_L(" %d "), RateToInt(aConfig.iRate));
+	switch (aConfig.iParity)
+		{
+	case EParityEven: aBuf.Append(_L("E")); break;
+	case EParityOdd: aBuf.Append(_L("O")); break;
+	case EParityNone: aBuf.Append(_L("N")); break;
+    default: break;
+		}
+	switch (aConfig.iDataBits)
+		{
+	case EData5: aBuf.Append(_L("5")); break;
+	case EData6: aBuf.Append(_L("6")); break;
+	case EData7: aBuf.Append(_L("7")); break;
+	case EData8: aBuf.Append(_L("8")); break;
+    default: break;
+		}
+	if (aConfig.iStopBits==EStop1)
+		aBuf.Append(_L("1 "));
+	else
+		aBuf.Append(_L("2 "));
+
+	aBuf.Append(_L("Use:"));
+	if (aConfig.iHandshake==0)
+		aBuf.Append(_L("NoControl "));
+	if (aConfig.iHandshake&(KConfigObeyXoff|KConfigSendXoff))
+		aBuf.Append(_L("XonXoff "));
+	if (aConfig.iHandshake&KConfigObeyCTS)
+		aBuf.Append(_L("CTS/RTS "));
+	if (aConfig.iHandshake&KConfigObeyDSR)
+		aBuf.Append(_L("DSR/DTR "));
+	if (aConfig.iHandshake&KConfigWriteBufferedComplete)
+		aBuf.Append(_L("Early "));
+	//|KConfigObeyDCD|KConfigFailDCD|))
+
+
+//	if (aConfig.iBreak==TEiger::EBreakOn)
+//		aBuf.Append(_L("Brk "));
+	if (aConfig.iFifo==EFifoEnable)
+		aBuf.Append(_L("Fifo "));
+	
+	// Settings
+	if (aSettings.iLocalEcho)
+		aBuf.Append(_L("LocalEcho "));
+	if (aSettings.iAddLF)
+		aBuf.Append(_L("AddLF "));
+	// rx mode
+	if ((aSettings.iRxMode&~ECapture)==ELoopBack)
+		aBuf.Append(_L("LpBk"));
+	else if ((aSettings.iRxMode&~ECapture)==ECountChars)
+		aBuf.Append(_L("CtCh"));
+	//else if (aSettings.iRxMode==ERxOff)
+		//{
+		//aBuf.Append(_L("NoRx"));
+		//}
+	aBuf.Append(_L(" "));
+	aBuf.AppendNum((TInt)(RThread().Priority()));
+	if (aSettings.iInfraRed==1)
+		aBuf.Append(_L("IR1"));
+	else if (aSettings.iInfraRed==2)
+		aBuf.Append(_L("IR2"));
+	if (aSettings.iWaitAfterWrite)
+		aBuf.Append(_L("Wait"));
+
+	aBuf.Append(_L("Last Err: "));
+	if (TheLastError==KErrNone)
+		aBuf.Append(_L("None "));
+	else if (TheLastError==KErrCommsLineFail)
+		aBuf.Append(_L("LineFail "));
+	else if (TheLastError==KErrCommsFrame)
+		aBuf.Append(_L("Frame "));
+	else if (TheLastError==KErrCommsOverrun)
+		aBuf.Append(_L("Overrun "));
+	else if (TheLastError==KErrCommsParity)
+		aBuf.Append(_L("Parity "));
+	else if (TheLastError==KErrAbort)
+		aBuf.Append(_L("Abort "));
+	else if (TheLastError==KErrBadPower)
+		aBuf.Append(_L("BadPower "));
+	else if (TheLastError==KErrNotReady)
+		aBuf.Append(_L("NotReady "));
+	else
+		aBuf.AppendNum(TheLastError);
+	}
+
+LOCAL_C void GetRate(TBps &aRate, const TDesC &aDes)
+//
+//	Set Baud rate
+//
+	{
+
+	TInt32 i;
+	if (TLex(aDes).Val(i)==KErrNone)
+		aRate=IntToRate(i);
+	}
+
+LOCAL_C void GetParity(TParity &aParity, const TDesC &aDes)
+//
+//
+//
+	{
+
+	if (aDes.FindF(_L("O"))>=0)
+		aParity=EParityOdd;
+  	if (aDes.FindF(_L("E"))>=0)
+		aParity=EParityEven;
+	if (aDes.FindF(_L("N"))>=0)
+		aParity=EParityNone;
+	}
+
+LOCAL_C void GetHandshake(TUint &aHandshake, const TDesC &aDes)
+//
+//
+//
+	{
+
+	if (aDes.FindF(_L("N"))>=0)
+		aHandshake=0;
+	if (aDes.FindF(_L("X"))>=0)
+		aHandshake=KConfigObeyXoff|KConfigSendXoff;
+	if (aDes.FindF(_L("C"))>=0)
+		aHandshake=KConfigObeyCTS;
+	if (aDes.FindF(_L("D"))>=0)
+		aHandshake=KConfigObeyDSR|KConfigFreeRTS;
+	if (aDes.FindF(_L("E"))>=0)
+		aHandshake|=KConfigWriteBufferedComplete;
+	}
+
+LOCAL_C void GetStopBit(TStopBits &aStop, const TDesC &aDes)
+	{
+
+	TInt32 in;
+	if (TLex(aDes).Val(in)==KErrNone)
+		{
+		if (in==1)
+			aStop=EStop1;
+		if (in==2)
+			aStop=EStop2;
+		}
+	else
+		{
+		if (aStop==EStop1)
+			aStop=EStop2;
+		else
+			aStop=EStop1;
+		}
+	}
+
+LOCAL_C void GetLength(TDataBits &aData, const TDesC &aDes)
+	{
+
+	TInt32 in;
+	if (TLex(aDes).Val(in)==KErrNone)
+		{
+		switch (in)
+			{
+		case 5: aData=EData5; break;
+		case 6: aData=EData6; break;
+		case 7: aData=EData7; break;
+		case 8: aData=EData8; break;
+		default: break;
+			}
+		}
+	}
+
+LOCAL_C void GetInfraRedMode(TInt &aInfraRed, const TDesC &aDes)
+	{
+
+	if (aDes.FindF(_L("0"))>=0)
+		aInfraRed=0;
+	else if (aDes.FindF(_L("1"))>=0)
+		aInfraRed=1;
+	else if (aDes.FindF(_L("2"))>=0)
+		aInfraRed=2;
+	}
+
+LOCAL_C void GetWaitMode(TBool &aWait, const TDesC &aDes)
+	{
+
+	if (aDes.FindF(_L("0"))>=0)
+		aWait=EFalse;
+	else if (aDes.FindF(_L("1"))>=0)
+		aWait=ETrue;
+	}
+
+/*LOCAL_C void GetBreak(const TDesC &aDes)
+	{
+
+	if (aDes==_L(""))
+		{
+		if (data.iBreak==TEiger::EBreakOn)
+			data.iBreak=TEiger::EBreakOff;
+		else
+			data.iBreak=TEiger::EBreakOn;
+		}
+	if (aDes.FindF(_L("N"))>=0)
+		data.iBreak=TEiger::EBreakOn;
+	if (aDes.FindF(_L("F"))>=0)
+		data.iBreak=TEiger::EBreakOff;
+	SetConfig();
+	}
+*/
+LOCAL_C void GetFifo(TUint& aFifo, const TDesC &aDes)
+	{
+
+	if (aDes==_L(""))
+		{
+		if (aFifo==EFifoEnable)
+			aFifo=EFifoDisable;
+		else
+			aFifo=EFifoEnable;
+		}
+	if (aDes.FindF(_L("N"))>=0)
+		aFifo=EFifoEnable;
+	if (aDes.FindF(_L("F"))>=0)
+		aFifo=EFifoDisable;
+	}
+
+LOCAL_C void GetEcho(TBool &aEcho, const TDesC &aDes)
+	{
+
+	if (aDes==_L(""))
+		{
+		if (aEcho)
+			aEcho=EFalse;
+		else
+			aEcho=ETrue;
+		}
+	if (aDes.FindF(_L("N"))>=0)
+		aEcho=ETrue;
+	if (aDes.FindF(_L("F"))>=0)
+		aEcho=EFalse;
+	}
+
+LOCAL_C void GetRxMode(TRxMode &aMode, const TDesC &aDes)
+	{
+
+	if (aDes.FindF(_L("O"))>=0)
+		aMode=ERxOff;
+	if (aDes.FindF(_L("N"))>=0)
+		aMode=ENormal;
+	if (aDes.FindF(_L("L"))>=0)
+		aMode=ELoopBack;
+	if (aDes.FindF(_L("C"))>=0)
+		aMode=ECountChars;
+	if (aDes.FindF(_L("S"))>=0)
+		{
+		aMode=TRxMode(TInt(aMode)|ECapture);
+		TInt r=TheCaptureFile.Create(TheFs,KCaptureFileName,EFileWrite);
+		if (r!=KErrNone)
+			User::Panic(_L("T_TERM CAP"),r);
+		}
+	if (aDes.FindF(_L("Z"))>=0)
+		{
+		aMode=TRxMode(TInt(aMode)&~ECapture);
+		TheCaptureFile.Close();
+		}
+	if (aDes.FindF(_L("0"))>=0)
+		RThread().SetPriority(EPriorityNormal);
+	if (aDes.FindF(_L("1"))>=0)
+		RThread().SetPriority(EPriorityAbsoluteHigh);
+	}
+
+LOCAL_C void GetDump(SSettings &aSettings, const TDesC &aDes)
+	{
+	
+	TInt32 in;
+	if (TLex(aDes).Val(in)==KErrNone)
+		{
+		aSettings.iDump=ETrue;
+		aSettings.iDumpRepeat=in;
+		return;
+		}
+	if (aDes.Length()!=0)
+		{
+		TBuf8<16> b=_L8("0123456789ABCDEF");
+		aSettings.iDumpData.Zero();
+		TInt i;
+		for (i=0; i<16; i++)
+			aSettings.iDumpData+=b;
+		return;
+		}
+	RConsole dialog;
+	TInt r=dialog.Init(_L("Type data to dump to comm.  Escape to finish"),TSize(KConsFullScreen,KConsFullScreen));
+	r=dialog.Control(_L("+Maximize +NewLine"));
+	aSettings.iDumpData=_L8("");
+	TConsoleKey k;
+	do 
+		{
+		dialog.Read(k);
+		if (k.Code()==EKeyEscape)
+			break;
+		TText a=(TText)k.Code();
+		TPtrC s(&a,1);
+		dialog.Write(s);
+		aSettings.iDumpData.Append(k.Code());
+		//if (a=='\r')
+		//	dialog.Write(_L("\n"));
+		} while (aSettings.iDumpData.Length()<KMaxDumpLength);
+
+	dialog.Destroy();
+	dialog.Close();
+	}
+
+
+
+LOCAL_C void CommandWindow(TCommConfigV01 &aConfig, SSettings &aSettings)
+//
+//	Display some words of wisdom and get a command from the user
+//
+	{
+
+	TBuf<32> b;
+	b.Num(aSettings.iCharCount);
+	b+=_L(" ");
+	b.AppendNum(aSettings.iMaxInOne);
+	b+=_L("\n");
+	RConsole dialog;
+	TInt r=dialog.Init(_L("."),TSize(KConsFullScreen,KConsFullScreen));
+	r=dialog.Control(_L("+Maximize +NewLine"));
+	dialog.Write(_L("B<n> Set Bps to n               P[Odd|Even|None] Set Parity\n"));
+	dialog.Write(_L("S[1|2] Set/Toggle stop bits     L<n> Set Data Length (5<=n<=8)\n"));
+	dialog.Write(_L("K[On|Off] Set/Toggle BRK        F[On|Off] Set/Toggle Fifo\n"));
+	dialog.Write(_L("H[None|X|CtsRts|DsrDtr] Handshaking\n"));
+	dialog.Write(_L("D[<n>] Set data or Dump data n times\n"));
+ 	dialog.Write(_L("J Toggle Add Line Feed          E Toggle local Echo\n"));
+	dialog.Write(_L("U [NLCO] Set Rx Mode to Normal, Loopback, Count, Off \n"));
+	dialog.Write(b);
+	dialog.Write(_L("Q Quit\n"));
+	dialog.Write(_L("\n:"));
+
+	//	Get a command
+	TBuf<0x80> des=_L("");
+	TConsoleKey k;
+	dialog.Read(k);
+	while ((k.Code()!='\r') && (k.Code()!=EKeyEscape))
+		{
+		TText a=(TText)k.Code();
+		TPtrC s(&a,1);
+		dialog.Write(s);
+		des.Append(k.Code());
+		dialog.Read(k);
+		}
+
+	if (k.Code()!=EKeyEscape && des.Length()>0)
+		{
+		des.UpperCase();
+		TBuf<0x80> right(des.Right(des.Length()-1));
+		if (des[0]=='B')
+			GetRate(aConfig.iRate, right);
+		if (des[0]=='P')
+			GetParity(aConfig.iParity, right);
+		if (des[0]=='S')
+			GetStopBit(aConfig.iStopBits, right);
+		if (des[0]=='L')
+			GetLength(aConfig.iDataBits, right);
+//		if (des[0]=='K')
+//			GetBreak(aSettings.iBreak, right);
+		if (des[0]=='F')
+			GetFifo(aConfig.iFifo, right);
+		if (des[0]=='I')
+			GetInfraRedMode(aSettings.iInfraRed, right);
+		if (aSettings.iInfraRed==1)
+			{
+			aConfig.iSIREnable=ESIREnable;
+			aConfig.iSIRSettings=KConfigSIRPulseWidthMinimum;
+			}
+		else if (aSettings.iInfraRed==2)
+			{
+			aConfig.iSIREnable=ESIREnable;
+			aConfig.iSIRSettings=KConfigSIRPulseWidthMaximum;
+			}
+		else
+			{
+			aConfig.iSIREnable=ESIRDisable;
+			aConfig.iSIRSettings=0;
+			}
+		if (des[0]=='H')
+			GetHandshake(aConfig.iHandshake, right);
+		if (des[0]=='E')
+			GetEcho(aSettings.iLocalEcho, right);
+		if (des[0]=='D')
+			GetDump(aSettings, right);
+		if (des[0]=='J')
+			aSettings.iAddLF=!aSettings.iAddLF;
+		if (des[0]=='U')
+			{
+			GetRxMode(aSettings.iRxMode, right);
+			aSettings.iCharCount=0;
+			aSettings.iMaxInOne=0;
+			}
+		if (des[0]=='Q')
+			aSettings.iNotFinished=EFalse;
+		if (des[0]=='W')
+			GetWaitMode(aSettings.iWaitAfterWrite, right);
+		}
+
+	dialog.Destroy();
+	dialog.Close();
+	}
+
+// The following decl is a hack for the Eiger build.
+// Without it T_TERM.EXE has no .data or .bss section.  This means the data offset
+// field in the file header is zero.  When the kernel comes to copy the data sections
+// from rom into ram it reads the data size field (which is the size of all data
+// sections) from the header and tries to copy data from 0x00000000 (the data offset),
+// causing a data abort.
+TInt dummy=10;	 
+#if defined (__WINS__)
+#define PDD_NAME _L("ECDRV")
+#define LDD_NAME _L("ECOMM")
+#else
+#define PDD_NAME _L("EUARTn")
+#define LDD_NAME _L("EUSBC")
+#endif
+
+#define CSY_NAME _L("ECACM")
+#define PORT_NAME _L("ACM::0")
+
+LOCAL_C void ProcessError(TInt anError)
+	{
+	TBuf<80> buf;
+	if (anError!=KErrNone)
+		{
+		TheLastError=anError;
+		ConfigString(buf, TheConfig, TheSettings);
+		TheWindow.SetTitle(buf);
+		}
+	}
+
+LOCAL_C void HandleRx(TRequestStatus& aStatus, TBool aFinish)
+	{
+	chw.Copy(ch);
+	switch(TheSettings.iRxMode & ~ECapture)
+		{
+		case ENormal:
+			{
+			buf.Copy(chw);
+			TheWindow.Write(buf);
+			break;
+			}
+		case ELoopBack:
+			{
+			ProcessError(CommWriteSync(TheCommPort,chw));
+			if (TheSettings.iWaitAfterWrite)
+				ProcessError(WaitAfterWrite(TheCommPort));
+			break;
+			}
+		case ECountChars:
+			{
+			TInt l=chw.Length();
+			TheSettings.iCharCount+=l;
+			if (l>TheSettings.iMaxInOne)
+				TheSettings.iMaxInOne=l;
+			break;
+			}
+		}
+	if (TheSettings.iRxMode & ECapture)
+		TheCaptureFile.Write(chw);
+	if (TheSettings.iRxMode!=ERxOff)
+		{
+		if ((TheSettings.iRxMode & ~ECapture)==ELoopBack && !aFinish)
+			TheCommPort.Read(aStatus, ch);
+		else
+			TheCommPort.Read(aStatus, ch);
+		}
+	}
+
+GLDEF_C TInt E32Main()
+//
+// Term
+//
+    {
+	RDebug::Print(_L("E32Main: Starting!"));
+
+	// Open the window asap
+	TheWindow.Init(_L("TERM"),TSize(KConsFullScreen,KConsFullScreen));
+
+	RDebug::Print(_L("E32Main: Initialised Window!"));
+
+	// Initialisation
+
+/*	
+	// I don't belive this section of code is being used anymore and
+	// has been replaced with PORT_NAME.
+	// I'm not sure so I've left it here ...
+	
+	TBuf <0x100> cmd;
+	User::CommandLine(cmd);
+	TInt port=0;
+	if ((cmd.Length()>0) && (cmd[0]>='1' && cmd[0]<='4'))
+		port=(TInt)(cmd[0]-'0');
+*/
+	// Load Device Drivers
+	TInt r;
+
+#if defined (VERBOSE)
+	TheWindow.Write(_L("Load LDD "));
+	TConsoleKey keystroke;
+#endif
+	r=User::LoadLogicalDevice(LDD_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+#if defined (VERBOSE)
+		TBuf<32> outBuf;
+		outBuf.AppendFormat(_L("Failed 0x%X\n\r"),r);
+		TheWindow.Write(outBuf);
+		TheWindow.Read(keystroke);
+#endif
+		User::Panic(_L("T_TERM"), ELoadLogicalDeviceErr);
+		}
+
+	RDebug::Print(_L("E32Main: Loaded Logical Device Driver"));
+
+	r=TheFs.Connect();
+	if (r!=KErrNone)
+		User::Panic(_L("T_TERM"), EConnectFsErr);
+
+	RDebug::Print(_L("E32Main: Connected to file server"));
+
+	TheSettings.iNotFinished=ETrue;
+	TheSettings.iLocalEcho=ETrue;
+	TheSettings.iAddLF=FALSE;
+	TheSettings.iDump=EFalse;
+	TheSettings.iDumpRepeat=1;
+	TheSettings.iDumpData=_L8("Some Text\r");
+	TheSettings.iRxMode=ENormal;
+	TheSettings.iCharCount=0;
+	TheSettings.iMaxInOne=0;
+	TheSettings.iInfraRed=0;
+	TheSettings.iWaitAfterWrite=EFalse;
+	
+	r = StartC32();
+	if (r!=KErrNone && r !=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed to start C32. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+
+	RDebug::Print(_L("E32Main: Started c32"));
+
+	// Comms Config
+	r = TheUsbServer.Connect();
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to connect to UsbMan Server. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+
+	RDebug::Print(_L("E32Main: Connected to UsbMan Server"));
+
+	TRequestStatus status;
+	TheUsbServer.Start(status);
+	User::WaitForRequest(status);
+
+	if (status.Int() != KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Unable to start USB services. Error %d"), status.Int());
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+
+	RDebug::Print(_L("E32Main: Started USB services"));
+
+	r = TheCommServer.Connect();
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to Connect to C32. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+
+	RDebug::Print(_L("E32Main: Connected to C32 Server"));
+
+	r = TheCommServer.LoadCommModule(CSY_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed to load USB CSY. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+
+	RDebug::Print(_L("E32Main: Loaded USB CSY"));
+
+	r = TheCommPort.Open(TheCommServer, PORT_NAME,ECommExclusive); // Comm port
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to Open USB Comm Port. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+
+	RDebug::Print(_L("E32Main: Open USB Comm Port"));
+
+	TheCommPort.Config(TheConfigBuf);	// get config
+	TheConfig.iHandshake=0; //KConfigObeyXoff|KConfigSendXoff;
+	TheConfig.iTerminator[0] = 'Z';
+	TheConfig.iTerminatorCount = 1;
+	TheCommPort.SetConfig(TheConfigBuf);
+	TheCommPort.SetReceiveBufferLength(8192);
+
+	//	Set up a console window
+	TheWindow.Control(_L("+Maximize +Newline"));
+	TheWindow.Write(_L("\r\nType '*' for commands\n"));
+	TBuf<0x80> buf;
+	ConfigString(buf, TheConfig, TheSettings);
+	TheWindow.SetTitle(buf);
+
+	TConsoleKey k;
+	TRequestStatus readStat, keyStat;
+
+	// main loop
+	TheWindow.Read(k, keyStat);
+	TheCommPort.Read(readStat, ch);
+	do
+		{
+		User::WaitForRequest(readStat, keyStat);
+		if (keyStat!=KRequestPending)
+			{
+			TUint32 c=k.Code();
+            switch(c)
+                {
+                case '\x3':
+    				{
+    				TheCommPort.ReadCancel();
+    				HandleRx(readStat,ETrue);
+    				}
+                    break;
+                case '*':
+    				{
+    				CommandWindow(TheConfig, TheSettings);
+    				TheCommPort.ReadCancel();
+    				TheCommPort.SetConfig(TheConfigBuf);
+    				if (TheSettings.iRxMode!=ERxOff)
+    					TheCommPort.Read(readStat, ch);
+    				ConfigString(buf, TheConfig, TheSettings);
+    				TheWindow.SetTitle(buf);
+    				}
+                    break;
+                case '\x15':
+    				{
+    				TInt r=TheUploadFile.Open(TheFs,KUploadFileName,EFileRead);
+    				if (r!=KErrNone)
+    					User::Panic(_L("T_TERM"),EOpenUploadFile);
+    				TBuf8<0x100> buf;
+    				do	{
+    					TheUploadFile.Read(buf);
+    					ProcessError(CommWriteSync(TheCommPort,buf));
+    					if (TheSettings.iWaitAfterWrite)
+    						ProcessError(WaitAfterWrite(TheCommPort));
+    					} while(buf.Length()!=0);
+    				TheUploadFile.Close();
+    				}
+                    break;
+                default:
+        			if (c<256)
+        				{
+     		    		TText8 a8=(TText8)c;
+    		    		TText a=(TText)c;
+    		    		TPtrC8 s8(&a8,1);
+    		    		TPtrC s(&a,1);
+    		    		ProcessError(CommWriteSync(TheCommPort, s8));
+			         	if (TheSettings.iWaitAfterWrite)
+			    	    	ProcessError(WaitAfterWrite(TheCommPort));
+			    	    if (TheSettings.iLocalEcho)
+			    		    {
+			    		    TheWindow.Write(s);
+			    		    if (c=='\r' && TheSettings.iAddLF) TheWindow.Write(_L("\n"));
+			    		    }
+				        }
+                    break;
+                }
+			TheWindow.Read(k, keyStat);
+			}
+		else if (readStat!=KRequestPending)
+			{
+			ProcessError(readStat.Int());
+			if (readStat!=KErrAbort && readStat!=KErrBadPower && readStat!=KErrNotReady)
+				HandleRx(readStat,EFalse);
+			else
+				{
+				if (TheSettings.iRxMode!=ERxOff)
+					TheCommPort.Read(readStat, ch);
+				}
+			}
+		else
+			{
+			User::Panic(_L("T_TERM"), EStraySignal);
+			}
+
+		if (TheSettings.iDump)
+			{
+			TheSettings.iDump=EFalse;
+			TInt i;
+			for (i=0; i<TheSettings.iDumpRepeat; i++)
+				{
+				ProcessError(CommWriteSync(TheCommPort, TheSettings.iDumpData));
+				if (TheSettings.iWaitAfterWrite)
+					ProcessError(WaitAfterWrite(TheCommPort));
+				}
+			}
+		} while(TheSettings.iNotFinished);
+
+	TheWindow.Destroy();
+	TheWindow.Close();
+	TheCommPort.Close();
+	TheCommServer.Close();
+	TheUsbServer.Stop();
+	TheUsbServer.Close();
+
+	return(KErrNone);
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usb_cable_detect/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* 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 "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:
+* BLD.INF for t_usb_cable_detect
+* BLD.INF for t_usb_cable_detect
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+t_usb_cable_detect.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usb_cable_detect/group/t_usb_cable_detect.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2003-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:
+*
+*/
+
+TARGET		t_usb_cable_detect.exe
+TARGETTYPE	EXE
+UID		0
+VENDORID 0x70000001
+SOURCEPATH    ../src
+SOURCE		t_usb_cable_detect.cpp
+LIBRARY		euser.lib c32.lib usbman.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usb_cable_detect/src/t_usb_cable_detect.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,311 @@
+/*
+* Copyright (c) 2003-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:
+* This is a simple program which demonstrates how to start USB services when
+* the cable is plugged in, and stop them when it's unplugged. A couple of
+* caveats:
+* 1. This mechanism will only work on certain hardware platforms (eg. Lubbock).
+* 2. The USB Manager will be loaded for the lifetime of this program.
+*
+*/
+
+#include <e32base.h>
+#include <e32math.h>
+#include <e32cons.h>
+#include <badesca.h>
+#include <c32comm.h>
+#include <usbman.h>
+
+// The name of the logical device driver to load.
+_LIT(KUsbLddName, "EUSBC");
+
+// An argument which, when passed to this program, means "don't run another
+// instance of yourself in the background".
+_LIT(KForkFlag, "f");
+
+class CUsbCableDetector : public CActive
+/**
+ * This class provides a USB cable detection service. It monitors the state of
+ * the USB cable and starts and stops USB services appropriately.
+ */
+	{
+public:
+	enum TReqState
+		{
+		EIdle = 0,
+		ENotifyDeviceStateChange,
+		EStart,
+		EStop
+		};
+
+	static CUsbCableDetector* NewL();
+	static CUsbCableDetector* NewLC();
+	virtual ~CUsbCableDetector();
+
+	void CheckAndMonitorCableL();
+	void MonitorCable();
+	void RunL();
+
+protected:
+	CUsbCableDetector();
+	void ConstructL();
+
+	void DoCancel();
+	TInt RunError(TInt aError);
+
+private:
+	RUsb iUsbMan;
+	TUsbDeviceState iDeviceState;
+	TReqState iReqState;
+	};
+
+
+CUsbCableDetector::CUsbCableDetector()
+	: CActive(EPriorityStandard)
+/**
+ * Constructor. Performs standard active object setup.
+ */
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CUsbCableDetector* CUsbCableDetector::NewLC()
+/**
+ * Factory function which leaves the new object on the cleanup stack.
+ *
+ * @return a new CUsbCableDetector which is still on the cleanup stack
+ */
+	{
+	CUsbCableDetector* self = new (ELeave) CUsbCableDetector;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+
+	return self;
+	}
+
+CUsbCableDetector* CUsbCableDetector::NewL()
+/**
+ * Factory function.
+ *
+ * @return a new CUsbCableDetector
+ */
+	{
+	CUsbCableDetector* self = CUsbCableDetector::NewLC();
+	CleanupStack::Pop(self);
+
+	return self;
+	}
+
+void CUsbCableDetector::ConstructL()
+/**
+ * Connects to the USB Manager and gets the current device state.
+ */
+	{
+	User::LeaveIfError(iUsbMan.Connect());
+	User::LeaveIfError(iUsbMan.GetDeviceState(iDeviceState));
+	}
+
+CUsbCableDetector::~CUsbCableDetector()
+/**
+ * Destructor. Cleans up all resources.
+ */
+	{
+	Cancel();
+	iUsbMan.Close();
+	}
+
+void CUsbCableDetector::CheckAndMonitorCableL()
+/**
+ * Checks that the current USB service state is consistent with the state of
+ * the cable. If the cable is unplugged and USB services are started, we want
+ * to stop them. If the cable is plugged in and USB services are stopped, we
+ * want to stop them. In any other situation, we just want to go on monitoring.
+ */
+	{
+	TUsbServiceState serviceState;
+	User::LeaveIfError(iUsbMan.GetServiceState(serviceState));
+
+//	RDebug::Print(_L("Service state: %d. Device state: %d"), serviceState, iDeviceState);
+
+	if ((serviceState != EUsbServiceIdle) &&
+		(iDeviceState == EUsbDeviceStateUndefined))
+		{
+		iReqState = EStop;
+		iUsbMan.Stop(iStatus);
+		SetActive();
+		}
+	else if ((serviceState != EUsbServiceStarted) &&
+		(iDeviceState != EUsbDeviceStateUndefined))
+		{
+		iReqState = EStart;
+		iUsbMan.Start(iStatus);
+		SetActive();
+		}
+	else
+		{
+		MonitorCable();
+		}
+	}
+
+void CUsbCableDetector::MonitorCable()
+/**
+ * Requests a notification from the USB Manager when the device state changes.
+ */
+	{
+	iReqState = ENotifyDeviceStateChange;
+	iUsbMan.DeviceStateNotification(KMaxTInt, iDeviceState, iStatus);
+	SetActive();
+	}
+
+void CUsbCableDetector::RunL()
+/**
+ * An asynchronous request has completed. The way we handle this depends on our
+ * current state.
+ */
+	{
+	User::LeaveIfError(iStatus.Int());
+
+	switch (iReqState)
+		{
+	case ENotifyDeviceStateChange:
+		CheckAndMonitorCableL();
+		break;
+
+	case EStart:
+	case EStop:
+		MonitorCable();
+		break;
+
+	default:
+		break;
+		}
+	}
+
+void CUsbCableDetector::DoCancel()
+/**
+ * Cancels the current asynchronous request.
+ */
+	{
+	switch (iReqState)
+		{
+	case ENotifyDeviceStateChange:
+		iUsbMan.DeviceStateNotificationCancel();
+		break;
+
+	case EStart:
+		iUsbMan.StartCancel();
+		break;
+
+	case EStop:
+		iUsbMan.StopCancel();
+		break;
+
+	default:
+		break;
+		}
+	}
+
+TInt CUsbCableDetector::RunError(TInt /*aError*/)
+/**
+ * Error handler. Stops the active scheduler, which will cause this program to
+ * terminate.
+ *
+ * @param aError Unused
+ * @return Always KErrNone to avoid a panic
+ */
+	{
+	CActiveScheduler::Stop();
+	return KErrNone;
+	}
+
+
+void UsbCableDetectL()
+/**
+ * Starts USB cable detection. This function will never return unless an error
+ * occurs.
+ */
+	{
+	TInt ret;
+
+	// Load the USB logical device driver.
+	ret = User::LoadLogicalDevice(KUsbLddName);
+	if ((ret != KErrNone) && (ret != KErrAlreadyExists))
+		User::Leave(ret);
+
+	// Start the C32 process (in which the USB Manager currently lives).
+	ret = StartC32();
+	if ((ret != KErrNone) && (ret != KErrAlreadyExists))
+		User::Leave(ret);
+
+	// Create an active scheduler for the cable detector object.
+	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
+	CleanupStack::PushL(scheduler);
+
+	CActiveScheduler::Install(scheduler);
+
+	// Prepare to start monitoring cable state.
+	CUsbCableDetector* cableDetector = CUsbCableDetector::NewLC();
+	cableDetector->CheckAndMonitorCableL();
+
+	// Action!
+	CActiveScheduler::Start();
+
+	// Clean everything up. We'll only get here if an error occurred.
+	CleanupStack::PopAndDestroy(2); // scheduler, cableDetector
+	}
+
+void mainL()
+/**
+ * Main function. If run without any arguments, creates another instance of
+ * this process with an argument which signifies that it should start cable
+ * detection. This allows the program to be fired off from the command-line.
+ */
+	{
+	RProcess thisProcess;
+
+	// Create a buffer big enough for the command-line arguments.
+	HBufC* commandLine = HBufC::NewLC(User::CommandLineLength());
+	TPtr commandLinePtr = commandLine->Des();
+	
+	// Get the command-line arguments.
+	User::CommandLine(commandLinePtr);
+
+	if (commandLinePtr == KForkFlag)
+		{
+		UsbCableDetectL();
+		}
+	else
+		{
+		thisProcess.Create(thisProcess.FileName(), KForkFlag);
+		thisProcess.Resume();
+		}
+
+	CleanupStack::PopAndDestroy(commandLine);
+	}
+
+GLDEF_C TInt E32Main()
+/**
+ * Symbian OS entry point. Creates a cleanup stack and runs the rest of the
+ * program.
+ *
+ * @return Always 0
+ */
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanupStack=CTrapCleanup::New();
+	TRAP_IGNORE(mainL());
+	delete cleanupStack;
+	__UHEAP_MARKEND;
+	return 0;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbman/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* 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 "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:
+* BLD.INF for t_usbman
+* BLD.INF for t_usbman
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+t_usbman.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbman/group/t_usbman.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+TARGET		t_usbman.exe
+TARGETTYPE	EXE
+UID		0
+VENDORID 0x70000001
+SOURCEPATH    ../src
+SOURCE		t_usbman.cpp
+LIBRARY		euser.lib c32.lib usbman.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+CAPABILITY	All -Tcb
+
+// Define this macro to test the Hurricane version of USB Manager
+//MACRO		HURRICANE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbman/src/t_usbman.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,1164 @@
+/*
+* 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:
+* This test program provides menu-driven functional tests for the USB Manager which exercise
+* every exported API it provides. Note that, to use this program with Hurricane USB, the macro
+* HURRICANE should be defined in the t_usbman.mmp file.
+* WARNING: Some of these tests rely on the 'dummy class controller' build of 
+* USBMAN. This is produced with t_usbman_dummycc.mmp, and it includes three 
+* instances of the dummy class controller (mainly used for GT171 automated 
+* tests). To get this to operate correctly a suitable ini file must be copied 
+* to c:\dummy.ini, for instance usbman\data\test.ini, which provides delayed 
+* asynchronous Start and Stop behaviour for each of the dummy CC instances.
+*
+*/
+
+#include <e32base.h>
+#include <e32math.h>
+#include <e32cons.h>
+#include <badesca.h>
+#include <c32comm.h>
+#include <usbman.h>
+#include <e32property.h> //Publish & Subscribe header, required for setting serial number
+#include "usb.h"
+
+LOCAL_D CConsoleBase* console;
+
+RTimer TheTimer;
+RCommServ TheCommServ;
+RUsb TheUsb;
+RUsb TheSecondUsbSession;
+TBool ThePrimaryClient;
+
+//_LIT(KUsbCsyName, "ECACM");
+//_LIT(KUsbPortName, "ACM::0");
+_LIT(KUsbLddName, "EUSBC");
+
+// These are used in the startup stress test.
+TInt64 TheRandomSeed = 0;
+const TInt KMaxCancelTime = 2000000;
+const TInt KMaxStopTime = 10000000;
+
+#define _printf console->Printf
+#define _getch console->Getch
+#define LEAVE(_x) VerboseLeaveL(_x, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+#define LEAVEIFERROR(_x) VerboseLeaveIfErrorL(_x, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+#define CHECK(_x) if (! (_x)) VerboseLeaveL(KErrGeneral, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x))
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper functions below this point
+////////////////////////////////////////////////////////////////////////////////
+
+void VerboseLeaveL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode)
+	{
+	TInt filenameOffset = aFileName.LocateReverse('\\') + 1;
+	if (filenameOffset < 0) filenameOffset = 1;
+	TPtrC8 shortFileName = aFileName.Mid(filenameOffset);
+	TBuf<64> fName, code;
+	fName.Copy(shortFileName.Left(64));
+	code.Copy(aCode.Left(64));
+	_printf(_L("ERROR (%d) on line %d of file %S\n"), aError, aLineNum, &fName);
+	_printf(_L("Code: %S\n\n"), &code);
+	_printf(_L("[ press any key ]"));
+	_getch();
+	User::Leave(aError);
+	}
+
+void VerboseLeaveIfErrorL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode)
+	{
+	if (aError) 
+		VerboseLeaveL(aError, aLineNum, aFileName, aCode);
+	}
+
+void ReadString(TDes& aDes)
+/**
+ * Reads user input into the start of the descriptor aDes.
+ */
+	{
+	TChar inputKey;
+	TInt count = 0;
+
+	aDes.Zero();
+	for (;;)
+		{
+		inputKey = (TInt) _getch();
+
+		if ((TInt)inputKey == EKeyEnter)
+			break;
+
+		if(inputKey == EKeyBackspace)
+			{
+			if (count > 0)
+				{
+ 				_printf(_L("%C"), (TUint) inputKey);
+				aDes.Delete(--count,1);
+				}
+			}
+		else if(inputKey.IsPrint())
+			{
+			_printf(_L("%C"), (TUint) inputKey);
+			aDes.Append(inputKey);
+			count++;
+			}
+		}
+	}
+
+
+void PrintUsbServiceState(TUsbServiceState aServiceState)
+	{
+	switch (aServiceState)
+		{
+	case EUsbServiceIdle: _printf(_L("USB service is idle.\n")); break;
+	case EUsbServiceStarting: _printf(_L("USB service is starting.\n")); break;
+	case EUsbServiceStarted: _printf(_L("USB service is started.\n")); break;
+	case EUsbServiceStopping: _printf(_L("USB service is stopping.\n")); break;
+#ifndef HURRICANE
+	case EUsbServiceFatalError: _printf(_L("USB service has a fatal error.\n")); break;
+#endif // HURRICANE
+	default:
+		_printf(_L("ERROR: unknown service state!\n"));
+		break;
+		}
+	}
+
+void PrintUsbDeviceState(TUsbDeviceState aDeviceState)
+	{
+	switch (aDeviceState)
+		{
+	case EUsbDeviceStateUndefined:
+		_printf(_L("USB device state is undefined.\n"));
+		break;
+	case EUsbDeviceStateDefault:
+		_printf(_L("USB device state is default.\n"));
+		break;
+	case EUsbDeviceStateAttached:
+		_printf(_L("USB device state is attached.\n"));
+		break;
+	case EUsbDeviceStatePowered:
+		_printf(_L("USB device state is powered.\n"));
+		break;
+	case EUsbDeviceStateConfigured:
+		_printf(_L("USB device state is configured.\n"));
+		break;
+	case EUsbDeviceStateAddress:
+		_printf(_L("USB device state is address.\n"));
+		break;
+	case EUsbDeviceStateSuspended:
+		_printf(_L("USB device state is suspended.\n"));
+		break;
+	default:
+		_printf(_L("ERROR: unknown device state!\n"));
+		break;
+		}
+	}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test cases below this point
+////////////////////////////////////////////////////////////////////////////////
+
+void OpenUsbL()
+	{
+	LEAVEIFERROR(TheUsb.Connect());
+	}
+
+void CloseUsbL()
+	{
+	TheUsb.Close();
+	}
+
+// USB test cases 3.1.1, 3.1.2 and 3.1.4, startup from primary and non-primary sessions.
+void StartUsbL()
+	{
+	TRequestStatus status;
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("Started USB.\n"));
+	}
+
+// USB test cases 3.2 and (part of) 3.4, startup cancellation.
+void CancelStartingUsbL(TBool aCancelByStopping)
+	{
+	TRequestStatus cancelStatus;
+	TRequestStatus timerStatus;
+	TInt cancelTime = 0;
+
+	while (cancelTime < (100 * 1000000))
+		{
+		_printf(_L("Cancelling after %d microseconds\n"), cancelTime);
+
+		TheTimer.After(timerStatus, cancelTime);
+		TheUsb.Start(cancelStatus);
+
+		User::WaitForRequest(cancelStatus, timerStatus);
+
+		// If the request has finished before the timer completed,
+		// cancel the timer and check the request status for errors.
+		if (timerStatus == KRequestPending)
+			{
+			TheTimer.Cancel();
+			User::WaitForRequest(timerStatus);
+			LEAVEIFERROR(cancelStatus.Int());
+			break;
+			}
+
+		// The timer should never complete with an error.
+		LEAVEIFERROR(timerStatus.Int());
+		
+		// Cancel the start. The option of cancelling by stopping is only available
+		// from version 7.0s, because in Hurricane a stop while starting is
+		// actually implemented as a cancel.
+
+#ifndef HURRICANE
+		if (aCancelByStopping)
+			{
+			TRequestStatus stopStatus;
+			TheUsb.Stop(stopStatus);
+			User::WaitForRequest(stopStatus);
+			LEAVEIFERROR(stopStatus.Int());
+			}
+		else
+#endif // HURRICANE
+			{
+			TheUsb.StartCancel();
+			}
+
+		User::WaitForRequest(cancelStatus);
+
+		// If the start actually completed, just return.
+		if (cancelStatus == KErrNone)
+			break;
+
+#ifndef HURRICANE
+		// If we're cancelling by stopping, then getting this error code is
+		// expected.
+		if (cancelStatus == KErrUsbServiceStopped)
+			{
+			cancelTime += 50000;
+			continue;
+			}
+#endif // HURRICANE
+
+		if (cancelStatus != KErrCancel)
+			LEAVE(cancelStatus.Int());
+
+		cancelTime += 50000;
+		}
+
+	TUsbServiceState serviceState;
+	LEAVEIFERROR(TheUsb.GetCurrentState(serviceState));
+	PrintUsbServiceState(serviceState);
+	}
+
+// Part of USB test case 3.4, stopping class controllers.
+void StopUsbSynchronousL()
+	{
+	TheUsb.Stop();
+	_printf(_L("Stopped USB.\n"));
+	}
+
+#ifndef HURRICANE
+
+// Part of USB test case 3.4, stopping class controllers.
+void StopUsbAsynchronousL()
+	{
+	TRequestStatus status;
+
+	TheUsb.Stop(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("Stopped USB.\n"));
+	}
+
+void CancelStoppingUsbL(TBool aCancelByStarting)
+	{
+	TRequestStatus cancelStatus;
+	TRequestStatus timerStatus;
+	TInt cancelTime = 0;
+
+	while (cancelTime < (100 * 1000000))
+		{
+		_printf(_L("Cancelling after %d microseconds\n"), cancelTime);
+
+		TheTimer.After(timerStatus, cancelTime);
+		TheUsb.Stop(cancelStatus);
+
+		User::WaitForRequest(cancelStatus, timerStatus);
+
+		// If the request has finished before the timer completed,
+		// cancel the timer and check the request status for errors.
+		if (timerStatus == KRequestPending)
+			{
+			TheTimer.Cancel();
+			User::WaitForRequest(timerStatus);
+			LEAVEIFERROR(cancelStatus.Int());
+			break;
+			}
+
+		// The timer should never complete with an error.
+		LEAVEIFERROR(timerStatus.Int());
+
+#ifndef HURRICANE 
+		if (aCancelByStarting) 
+			{ 
+			TRequestStatus startStatus; 
+			TheUsb.Start(startStatus); 
+			User::WaitForRequest(startStatus); 
+			LEAVEIFERROR(startStatus.Int()); 
+			} 
+		else 
+#endif // HURRICANE 
+			{ 
+			TheUsb.StopCancel(); 
+			}
+
+		User::WaitForRequest(cancelStatus);
+
+		// If the stop actually completed, just return.
+		if (cancelStatus == KErrNone)
+			break;
+
+#ifndef HURRICANE 
+		// If we're cancelling by starting, then getting this 
+		// error code is expected. 
+	    if (cancelStatus == KErrUsbServiceStarted) 
+			{ 
+			cancelTime += 50000; 
+			continue; 
+			} 
+#endif // HURRICANE 
+	 
+		if (cancelStatus != KErrCancel)
+			LEAVE(cancelStatus.Int());
+
+		cancelTime += 50000;
+		}
+
+	TUsbServiceState serviceState;
+	LEAVEIFERROR(TheUsb.GetCurrentState(serviceState));
+	PrintUsbServiceState(serviceState);
+	}
+
+#endif // HURRICANE
+
+void RestartUsbL()
+	{
+	TheUsb.Stop();
+
+	TRequestStatus status;
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	_printf(_L("\nRestarted USB.\n"));
+	}
+
+// USB test case 3.6, stress testing of startup and shutdown.
+void StartupStressTestL()
+	{
+	TRequestStatus cancelStatus;
+	TRequestStatus timerStatus;
+	TInt cancelTime = Math::Rand(TheRandomSeed) % KMaxCancelTime;
+	TInt stopTime;
+
+	for (TInt i = 0; i < 100; i++)
+		{
+		_printf(_L("Cancelling after %d microseconds\n"), cancelTime);
+
+		TheTimer.After(timerStatus, cancelTime);
+		TheUsb.Start(cancelStatus);
+
+		User::WaitForRequest(cancelStatus, timerStatus);
+
+		// If the request has finished before the timer completed,
+		// cancel the timer and check the request status for errors.
+		if (timerStatus == KRequestPending)
+			{
+			TheTimer.Cancel();
+			LEAVEIFERROR(cancelStatus.Int());
+			}
+		else
+			{
+			// The timer should never complete with an error.
+			LEAVEIFERROR(timerStatus.Int());
+
+			// Cancel the start.
+			TheUsb.StartCancel();
+			User::WaitForRequest(cancelStatus);
+			}
+
+		// If the start actually completed, then try stopping.
+		if (cancelStatus == KErrNone)
+			{
+			stopTime = Math::Rand(TheRandomSeed) % KMaxStopTime;
+			_printf(_L("Stopping after %d microseconds\n"), stopTime);
+			User::After(stopTime);
+			TheUsb.Stop();
+			}
+		else if (cancelStatus != KErrCancel)
+			{
+			LEAVE(cancelStatus.Int());
+			}
+
+		cancelTime = Math::Rand(TheRandomSeed) % KMaxCancelTime;
+		}
+
+	_printf(_L("USB is now stopped\n"));
+	}
+
+// USB test case 3.3, monitoring the state of the USB.
+void MonitorUsbDeviceStateL()
+	{
+	TRequestStatus consoleStatus;
+	TRequestStatus notifyStatus;
+	TUsbServiceState serviceState;
+	TUsbDeviceState deviceState;
+
+	LEAVEIFERROR(TheUsb.GetCurrentState(serviceState));
+
+	_printf(_L("\n"));
+
+	PrintUsbServiceState(serviceState);
+
+#ifndef HURRICANE
+	LEAVEIFERROR(TheUsb.GetDeviceState(deviceState));
+	PrintUsbDeviceState(deviceState);
+#endif // HURRICANE
+
+	_printf(_L("\nMonitoring the state of USB - press any key to stop\n\n"));
+
+	console->Read(consoleStatus);
+
+	while (consoleStatus == KRequestPending)
+		{
+		TheUsb.StateNotification(0xFFFFFFFF, deviceState, notifyStatus);
+		User::WaitForRequest(notifyStatus, consoleStatus);
+
+		if (consoleStatus == KRequestPending)
+			{
+			if (notifyStatus != KErrNone)
+				{
+				// need to cancel the read to avoid a CBase-77 panic!
+				console->ReadCancel();
+				LEAVE(notifyStatus.Int());
+				}
+			}
+		else
+			{
+			// The user's pressed a key.
+			TheUsb.StateNotificationCancel();
+			User::WaitForRequest(notifyStatus);
+			break;
+			}
+
+		PrintUsbDeviceState(deviceState);
+		}
+
+	_printf(_L("\nTest complete\n"));
+	}
+
+// Concurrency test case (3.9.1 in test spec). One client starts USB and then another
+// one stops it.
+void StartAThenStopBL()
+	{
+	LEAVEIFERROR(TheSecondUsbSession.Connect());
+
+	TRequestStatus status;
+	TUsbServiceState serviceState;
+
+	// Start on client 1.
+	TheUsb.Start(status);
+	User::WaitForRequest(status);
+	LEAVEIFERROR(status.Int());
+
+	// Get status on both sessions.
+
+	LEAVEIFERROR(TheUsb.GetCurrentState(serviceState));
+	_printf(_L("\nSession 1: "));
+	PrintUsbServiceState(serviceState);
+
+	LEAVEIFERROR(TheSecondUsbSession.GetCurrentState(serviceState));
+	_printf(_L("Session 2: "));
+	PrintUsbServiceState(serviceState);
+
+	// Stop on client 2.
+	TheSecondUsbSession.Stop();
+
+	// Get status on both sessions.
+
+	LEAVEIFERROR(TheUsb.GetCurrentState(serviceState));
+	_printf(_L("Session 1: "));
+	PrintUsbServiceState(serviceState);
+
+	LEAVEIFERROR(TheSecondUsbSession.GetCurrentState(serviceState));
+	_printf(_L("Session 2: "));
+	PrintUsbServiceState(serviceState);
+
+	TheSecondUsbSession.Close();
+	}
+
+// Concurrency test case (3.9.2 in test spec). One client stops USB while it's being
+// started by another one.
+void StopBWhileAStartingL()
+	{
+	LEAVEIFERROR(TheSecondUsbSession.Connect());
+
+	TRequestStatus status;
+	TUsbServiceState serviceState;
+
+	// Start on client 1.
+	TheUsb.Start(status);
+
+	// Stop on client 2.
+	TheSecondUsbSession.Stop();
+
+	// Wait for start request to complete.
+	User::WaitForRequest(status);
+	if (status.Int() != KErrUsbServiceStopped)
+		LEAVEIFERROR(status.Int());
+
+	// Get status on both sessions.
+
+	LEAVEIFERROR(TheUsb.GetCurrentState(serviceState));
+	_printf(_L("\nSession 1: "));
+	PrintUsbServiceState(serviceState);
+
+	LEAVEIFERROR(TheSecondUsbSession.GetCurrentState(serviceState));
+	_printf(_L("Session 2: "));
+	PrintUsbServiceState(serviceState);
+
+	TheSecondUsbSession.Close();
+	}
+
+// Concurrency test case (3.9.5 in test spec). One client starts USB while it's being
+// started by another one.
+void StartBWhileAStartingL()
+	{
+	LEAVEIFERROR(TheSecondUsbSession.Connect());
+
+	TRequestStatus status1;
+	TRequestStatus status2;
+	TUsbServiceState serviceState;
+
+	// Start on client 1.
+	TheUsb.Start(status1);
+
+	// Start on client 2.
+	TheSecondUsbSession.Start(status2);
+
+	// Wait for first request to complete.
+	User::WaitForRequest(status1);
+	LEAVEIFERROR(status1.Int());
+
+	// Wait for second request to complete.
+	User::WaitForRequest(status2);
+	LEAVEIFERROR(status2.Int());
+
+	// Get status on both sessions.
+
+	LEAVEIFERROR(TheUsb.GetCurrentState(serviceState));
+	_printf(_L("\nSession 1: "));
+	PrintUsbServiceState(serviceState);
+
+	LEAVEIFERROR(TheSecondUsbSession.GetCurrentState(serviceState));
+	_printf(_L("Session 2: "));
+	PrintUsbServiceState(serviceState);
+
+	TheSecondUsbSession.Close();
+	}
+
+#ifndef HURRICANE
+
+// Concurrency test case (3.9.3 in test spec). One client starts USB while it's being
+// stopped by another one.
+void StartBWhileAStoppingL()
+	{
+	LEAVEIFERROR(TheSecondUsbSession.Connect());
+
+	TRequestStatus status1;
+	TRequestStatus status2;
+	TUsbServiceState serviceState;
+
+	// Stop on client 1.
+	TheUsb.Stop(status1);
+
+	// Start on client 2.
+	TheSecondUsbSession.Start(status2);
+
+	// Wait for first request to complete.
+	User::WaitForRequest(status1);
+	if (status1.Int() != KErrUsbServiceStarted)
+		LEAVEIFERROR(status1.Int());
+
+	// Wait for second request to complete.
+	User::WaitForRequest(status2);
+	LEAVEIFERROR(status2.Int());
+
+	// Get status on both sessions.
+
+	LEAVEIFERROR(TheUsb.GetCurrentState(serviceState));
+	_printf(_L("\nSession 1: "));
+	PrintUsbServiceState(serviceState);
+
+	LEAVEIFERROR(TheSecondUsbSession.GetCurrentState(serviceState));
+	_printf(_L("Session 2: "));
+	PrintUsbServiceState(serviceState);
+
+	TheSecondUsbSession.Close();
+	}
+
+// Concurrency test case (3.9.4 in test spec). One client stops USB while it's being
+// stopped by another one.
+void StopBWhileAStoppingL()
+	{
+	LEAVEIFERROR(TheSecondUsbSession.Connect());
+
+	TRequestStatus status1;
+	TRequestStatus status2;
+	TUsbServiceState serviceState;
+
+	// Stop on client 1.
+	TheUsb.Stop(status1);
+
+	// Stop on client 2.
+	TheSecondUsbSession.Stop(status2);
+
+	// Wait for first request to complete.
+	User::WaitForRequest(status1);
+	LEAVEIFERROR(status1.Int());
+
+	// Wait for second request to complete.
+	User::WaitForRequest(status2);
+	LEAVEIFERROR(status2.Int());
+
+	// Get status on both sessions.
+
+	LEAVEIFERROR(TheUsb.GetCurrentState(serviceState));
+	_printf(_L("\nSession 1: "));
+	PrintUsbServiceState(serviceState);
+
+	LEAVEIFERROR(TheSecondUsbSession.GetCurrentState(serviceState));
+	_printf(_L("Session 2: "));
+	PrintUsbServiceState(serviceState);
+
+	TheSecondUsbSession.Close();
+	}
+/*
+void RegisterAsPrimaryClientL()
+	{
+	LEAVEIFERROR(TheUsb.RegisterAsPrimarySession());
+	ThePrimaryClient = ETrue;
+	}
+
+void DeregisterAsPrimaryClientL()
+	{
+	LEAVEIFERROR(TheUsb.DeregisterAsPrimarySession());
+	ThePrimaryClient = EFalse;
+	}
+*/
+void DbgCheckHeapL()
+	{
+	_printf(_L("Expected number of allocated heap cells: "));
+
+	TBuf<20> numBuf;
+	ReadString(numBuf);
+
+	TLex lex(numBuf);
+	TInt expected;
+	
+	if (lex.Val(expected) != KErrNone)
+		expected = 0;
+
+	LEAVEIFERROR(TheUsb.__DbgCheckHeap(expected));
+	}
+
+void DbgMarkEndL()
+	{
+	_printf(_L("Expected number of allocated heap cells: "));
+
+	TBuf<20> numBuf;
+	ReadString(numBuf);
+
+	TLex lex(numBuf);
+	TInt expected;
+	
+	if (lex.Val(expected) != KErrNone)
+		expected = 0;
+
+	LEAVEIFERROR(TheUsb.__DbgMarkEnd(expected));
+	}
+
+void DbgFailNextL()
+	{
+	_printf(_L("Number of allocation which will fail: "));
+
+	TBuf<20> numBuf;
+	ReadString(numBuf);
+
+	TLex lex(numBuf);
+	TInt allocNumber;
+	
+	if (lex.Val(allocNumber) != KErrNone)
+		allocNumber = 1;
+
+	LEAVEIFERROR(TheUsb.__DbgFailNext(allocNumber));
+	}
+
+#endif // HURRICANE
+
+void SetUsbSerialNumberL()
+	{
+	//Get a number from user
+	TBuf16<KUsbStringDescStringMaxSize> serNum;
+	
+	_printf(_L("\nEnter new USB serial number:\n"));
+	ReadString(serNum);
+	if(serNum.Length()==0)
+		{
+		TInt r = RProperty::Delete(KUidSystemCategory,0x101FE1DB);
+		if(r!=KErrNotFound && r!=KErrNone)
+			{
+			User::Leave(r);
+			}
+		_printf(_L("Serial number un-published. Restart USB for change to take effect.\ne.g. Option 1 -> 1 (calls RUsb::Start)\n"));		
+		}
+	else
+		{
+		_printf(_L("\nSetting serial number to %S\n"),&serNum);	
+		//Publish the number. It will be read by CUsbDevice::SetUsbDeviceSettingsL
+		//The key used is the UID KUidUsbmanServer = 0x101FE1DB
+		//The size of the serial number value published is KUsbStringDescStringMaxSize. The
+		//USB spec doesn't give a specific max size for the serial number, it just says it is
+		//a string descriptor, hence it can have size KUsbStringDescStringMaxSize (252 characters).
+		TInt r = RProperty::Define(KUidSystemCategory,0x101FE1DB,RProperty::EText,KUsbStringDescStringMaxSize);
+		if(r!=KErrAlreadyExists && r!=KErrNone)
+			{
+			User::Leave(r);
+			}
+		r = RProperty::Set(KUidSystemCategory,0x101FE1DB,serNum);
+		User::LeaveIfError(r);
+
+		_printf(_L("Serial number published. Restart USB for change to take effect.\ne.g. Option 1 -> 1 (calls RUsb::Start)\n"));		
+		}
+	}
+
+////////////////////////////////////////////////////////////////////////////////
+// Menus etc. below this point
+////////////////////////////////////////////////////////////////////////////////
+
+TBool SelectStartingTestL(TChar aChar)
+	{
+	TBool result = ETrue;
+	
+	switch (aChar)
+		{
+	case '1': StartUsbL(); break;
+	case '2': CancelStartingUsbL(EFalse); break;
+	case '3': CancelStartingUsbL(ETrue); break;
+	case '4': StartupStressTestL(); break;
+	case 'q':
+	case 'Q':
+		result = EFalse;
+//		break; // commented out as it's unreachable
+	default:
+		_printf(_L("\nInvalid key\n"));
+		break;
+		}
+	return result;
+	}
+
+void StartingTestsL()
+	{
+	_printf(_L("\nStarting tests\n"));
+	_printf(_L("--------------\n"));
+	_printf(_L("Available tests:\n\n"));
+	_printf(_L("1. Start USB\n"));
+	_printf(_L("2. Cancel starting USB\n"));
+	_printf(_L("3. Stop USB while it's starting\n"));
+	_printf(_L("4. Startup stress test\n"));
+	_printf(_L("\nSelection (q for main menu): "));
+
+	TChar ch = (TChar) _getch();
+	_printf(_L("\n"));
+
+	TRAP_IGNORE(SelectStartingTestL(ch));
+	}
+
+TBool SelectStoppingTestL(TChar aChar)
+	{
+	TBool result = ETrue;
+	
+	switch (aChar)
+		{
+	case '1': StopUsbSynchronousL(); break;
+#ifndef HURRICANE
+	case '2': StopUsbAsynchronousL(); break;
+    case '3': CancelStoppingUsbL(EFalse); break; 
+    case '4': CancelStoppingUsbL(ETrue); break; 
+#endif // HURRICANE
+	case 'q':
+	case 'Q':
+		result = EFalse;
+//		break; // commented out as it's unreachable
+	default:
+		_printf(_L("\nInvalid key\n"));
+		break;
+		}
+	return result;
+	}
+
+void StoppingTestsL()
+	{
+	_printf(_L("\nStopping tests\n"));
+	_printf(_L("--------------\n"));
+	_printf(_L("Available tests:\n\n"));
+	_printf(_L("1. Stop USB synchronously\n"));
+#ifndef HURRICANE
+	_printf(_L("2. Stop USB asynchronously\n"));
+	_printf(_L("3. Cancel stopping USB\n"));
+	_printf(_L("4. Start USB whilst stopping\n"));
+#endif // HURRICANE
+	_printf(_L("\nSelection (q for main menu): "));
+
+	TChar ch = (TChar) _getch();
+	_printf(_L("\n"));
+
+	TRAP_IGNORE(SelectStoppingTestL(ch));
+	}
+
+TBool SelectConcurrencyTestL(TChar aChar)
+	{
+	TBool result = ETrue;
+	
+	switch (aChar)
+		{
+	case '1': StartAThenStopBL(); break;
+	case '2': StopBWhileAStartingL(); break;
+	case '3': StartBWhileAStartingL(); break;
+#ifndef HURRICANE
+	case '4': StartBWhileAStoppingL(); break;
+	case '5': StopBWhileAStoppingL(); break;
+#endif // HURRICANE
+	case 'q':
+	case 'Q':
+		result = EFalse;
+//		break; // commented out as it's unreachable
+	default:
+		_printf(_L("\nInvalid key\n"));
+		break;
+		}
+	return result;
+	}
+
+void ConcurrencyTestsL()
+	{
+	_printf(_L("\nConcurrency tests\n"));
+	_printf(_L("-----------------\n"));
+	_printf(_L("Available tests:\n\n"));
+	_printf(_L("1. Client A starts, then client B stops\n"));
+	_printf(_L("2. Client B stops while client A is starting\n"));
+	_printf(_L("3. Client B starts while client A is starting\n"));
+#ifndef HURRICANE
+	_printf(_L("4. Client B starts while client A is stopping\n"));
+	_printf(_L("5. Client B stops while client A is stopping\n"));
+#endif // HURRICANE
+	_printf(_L("\nSelection (q for main menu): "));
+
+	TChar ch = (TChar) _getch();
+	_printf(_L("\n"));
+
+	TRAP_IGNORE(SelectConcurrencyTestL(ch));
+	}
+
+void SanityTestL()
+/**
+ * Call each API. Just a quick way of sanity-checking the API.
+ */
+	{
+	_printf(_L("\nQuick sanity check of all APIs\n"));
+	
+	RUsb usb;
+	LEAVEIFERROR(usb.Connect());
+	usb.Version();
+	
+	TUsbDeviceState deviceState;
+	TRequestStatus deviceStateNotStat;
+	usb.StateNotification(0xFFFF, deviceState, deviceStateNotStat);
+	usb.StateNotificationCancel();
+	User::WaitForRequest(deviceStateNotStat);
+	if ( deviceStateNotStat != KErrCancel )
+		{
+		LEAVEIFERROR(__LINE__);
+		}
+
+	usb.Stop(); // get it into a known state
+
+	TUsbServiceState serviceState;
+	LEAVEIFERROR(usb.GetServiceState(serviceState));
+	if ( serviceState != EUsbServiceIdle )
+		{
+		LEAVEIFERROR(__LINE__);
+		}
+	TRequestStatus serviceStateNotStat;
+	usb.ServiceStateNotification(serviceState, serviceStateNotStat);
+	// Start & Stop & Cancels
+	TRequestStatus startStat;
+	usb.Start(startStat);
+	User::WaitForRequest(startStat);
+	LEAVEIFERROR(startStat.Int());
+	User::WaitForRequest(serviceStateNotStat);
+	LEAVEIFERROR(serviceStateNotStat.Int());
+	if ( serviceState != EUsbServiceStarting )
+		{
+		LEAVEIFERROR(__LINE__);
+		}
+	LEAVEIFERROR(usb.GetServiceState(serviceState));
+	if ( serviceState != EUsbServiceStarted )
+		{
+		LEAVEIFERROR(__LINE__);
+		}
+	usb.Stop();
+	usb.StartCancel();
+	usb.StopCancel();
+	TRequestStatus stopStat;
+	usb.Stop(stopStat);
+	User::WaitForRequest(stopStat);
+	LEAVEIFERROR(stopStat.Int());
+
+	// Service state
+	LEAVEIFERROR(usb.GetServiceState(serviceState));
+	if ( serviceState != EUsbServiceIdle )
+		{
+		LEAVEIFERROR(__LINE__);
+		}
+	LEAVEIFERROR(usb.GetCurrentState(serviceState));
+	if ( serviceState != EUsbServiceIdle )
+		{
+		LEAVEIFERROR(__LINE__);
+		}
+	usb.ServiceStateNotification(serviceState, serviceStateNotStat);
+	usb.ServiceStateNotificationCancel();
+	User::WaitForRequest(serviceStateNotStat);
+	if ( serviceStateNotStat != KErrCancel )
+		{
+		LEAVEIFERROR(__LINE__);
+		}
+	User::After(1000000);
+	// Device state
+	LEAVEIFERROR(usb.GetDeviceState(deviceState));		// need default for Cedar below
+	if ( deviceState != EUsbDeviceStateUndefined && deviceState != EUsbDeviceStateDefault )
+		{
+		LEAVEIFERROR(__LINE__);
+		}
+	usb.DeviceStateNotification(0xFFFF, deviceState, deviceStateNotStat);
+	usb.DeviceStateNotificationCancel();
+	User::WaitForRequest(deviceStateNotStat);
+	if ( deviceStateNotStat != KErrCancel )
+		{
+		LEAVEIFERROR(__LINE__);
+		}
+	usb.DeviceStateNotification(EUsbDeviceStateDefault, deviceState, deviceStateNotStat);
+	usb.Start(startStat);
+	User::WaitForRequest(startStat);
+	LEAVEIFERROR(startStat.Int());
+	User::WaitForRequest(deviceStateNotStat);
+	LEAVEIFERROR(deviceStateNotStat.Int());		  // need undefined for Cedar below
+	if ( deviceState != EUsbDeviceStateDefault && deviceState != EUsbDeviceStateUndefined )
+		{
+		LEAVEIFERROR(__LINE__);
+		}
+	User::After(1000000);
+	LEAVEIFERROR(usb.GetDeviceState(deviceState));	// need default & undefined & configured for Cedar below
+	if ( deviceState != EUsbDeviceStateSuspended && deviceState != EUsbDeviceStateDefault && deviceState != EUsbDeviceStateUndefined && deviceState != EUsbDeviceStateConfigured)
+		{
+		LEAVEIFERROR(__LINE__);
+		}
+	// Heap marking
+	LEAVEIFERROR(usb.__DbgMarkHeap());
+	LEAVEIFERROR(usb.__DbgCheckHeap(0));
+	LEAVEIFERROR(usb.__DbgMarkEnd(0));
+	// NB __DbgFailNext is not checked
+	usb.Stop();
+	usb.Close();
+	}
+
+#ifndef HURRICANE
+
+TBool SelectMemoryTestL(TChar aChar)
+	{
+	TBool result = ETrue;
+			
+	switch (aChar)
+		{
+	case '1': LEAVEIFERROR(TheUsb.__DbgMarkHeap()); break;
+	case '2': DbgCheckHeapL(); break;
+	case '3': DbgMarkEndL(); break;
+	case '4': DbgFailNextL(); break;
+	case 'q':
+	case 'Q':
+		result = EFalse;
+//		break; // commented out as it's unreachable
+	default:
+		_printf(_L("\nInvalid key\n"));
+		break;
+		}
+	return result;
+	}
+
+void MemoryTestsL()
+	{
+	_printf(_L("\nMemory tests\n"));
+	_printf(_L("------------\n"));
+	_printf(_L("Available tests:\n\n"));
+	_printf(_L("1. Mark heap\n"));
+	_printf(_L("2. Check heap\n"));
+	_printf(_L("3. End marking heap\n"));
+	_printf(_L("4. Simulate allocation failure\n"));
+	_printf(_L("\nSelection (q for main menu): "));
+
+	TChar ch = (TChar) _getch();
+	_printf(_L("\n"));
+
+	TRAP_IGNORE(SelectMemoryTestL(ch));
+	}
+
+#endif // HURRICANE
+
+TBool SelectTestL(TChar aChar)
+	{
+	TBool result = ETrue;
+			
+	switch (aChar)
+		{
+	case '1': StartingTestsL(); break;
+	case '2': StoppingTestsL(); break;
+	case '3': MonitorUsbDeviceStateL(); break;
+	case '4': ConcurrencyTestsL(); break;
+	case '5': SetUsbSerialNumberL(); break;
+	case 's': case 'S': SanityTestL(); break;
+#ifndef HURRICANE
+/*	case 'r': RegisterAsPrimaryClientL(); break;
+	case 'd': DeregisterAsPrimaryClientL(); break;
+*/	case 'm': MemoryTestsL(); break;
+#endif // HURRICANE
+	case 'c': case 'C': CloseUsbL(); break;
+	case 'o': case 'O': OpenUsbL(); break;
+	case 'q':
+	case 'Q':
+		result = EFalse;
+//		break; // commented out as it's unreachable
+	default:
+		_printf(_L("\nInvalid key\n"));
+		break;
+		}
+	return result;
+	}
+
+void mainL()
+	{
+	// Create the global timer. This is used throughout the code for timing services.
+	TheTimer.CreateLocal();
+
+	TInt ret;
+
+#ifndef __WINS__
+	ret = User::LoadLogicalDevice(KUsbLddName);
+	if ((ret != KErrNone) && (ret != KErrAlreadyExists))
+		LEAVE(ret);
+
+	_printf(_L("Loaded USB LDD\n"));
+#endif
+
+	ret = StartC32();
+	if ((ret != KErrNone) && (ret != KErrAlreadyExists))
+		LEAVE(ret);
+
+	_printf(_L("Started C32\n"));
+
+	OpenUsbL();
+
+	TUsbServiceState serviceState;
+
+	TBool noExit = ETrue;
+	while (noExit)
+		{
+		_printf(_L("\nMain menu\n"));
+		_printf(_L("---------\n"));
+		_printf(_L("Available tests:\n\n"));
+		_printf(_L("1. Starting tests\n"));
+		_printf(_L("2. Stopping tests\n"));
+		_printf(_L("3. Monitor USB device state\n"));
+		_printf(_L("4. Concurrency tests\n"));
+		_printf(_L("5. Publish Serial Number\n"));
+		_printf(_L("S. Sanity test- quickly calls all APIs to make sure they don't panic\n"));
+#ifndef HURRICANE
+/*		_printf(_L("R. Register as primary client\n"));
+		_printf(_L("D. Deregister as primary client\n"));
+*/		_printf(_L("M. Memory tests\n"));
+#endif // HURRICANE
+		_printf(_L("C. Close connection to USB Manager\n"));
+		_printf(_L("O. Connect to USB Manager\n"));
+
+		if (TheUsb.Handle())
+			{
+			_printf(_L("\nConnected to USB "));
+			if (ThePrimaryClient)
+				_printf(_L("as the primary client.\n"));
+			else
+				_printf(_L("as a non-primary client.\n"));
+
+			ret = TheUsb.GetCurrentState(serviceState);
+			if (ret == KErrNone)
+				PrintUsbServiceState(serviceState);
+			else
+				_printf(_L("Couldn't get USB service state (error %d).\n"), ret);
+			}
+		else
+			{
+			_printf(_L("\nNot connected to USB.\n"));
+			}
+
+		_printf(_L("\nSelection (q to quit): "));
+
+		TChar ch = (TChar) _getch();
+		_printf(_L("\n"));
+
+		TRAP_IGNORE(noExit = SelectTestL(ch));
+		}
+
+	TheCommServ.Close();
+	TheUsb.Close();
+	}
+
+void consoleMainL()
+	{
+	console=Console::NewL(_L("T_USBMAN"),TSize(KConsFullScreen,KConsFullScreen));
+	CleanupStack::PushL(console);
+	mainL();
+	_printf(_L("[ press any key ]"));
+	_getch();
+	CleanupStack::PopAndDestroy();
+	}
+
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanupStack=CTrapCleanup::New();
+	TRAP_IGNORE(consoleMainL());
+	delete cleanupStack;
+	__UHEAP_MARKEND;
+	return 0;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/EABI/stub1ccU.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,3 @@
+EXPORTS
+	_Z24ImplementationGroupProxyRi @ 1 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* 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 "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:
+*
+*/
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_TESTEXPORTS
+#ifndef WINS
+Stub1CC.iby			/epoc32/rom/include/stub1cc.iby
+stub1cc.ini			z:/testdata/config/stub1cc.ini
+#endif
+
+PRJ_TESTMMPFILES
+#ifndef WINS
+Stub1CC.mmp
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/group/Stub1CC.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+#ifndef __STUB1CC_IBY__
+#define __STUB1CC_IBY__
+
+
+// Universal Serial Bus Stub1 Class Controller
+
+#include <ecom.iby>
+
+ECOM_PLUGIN(stub1cc.dll,10203284.rsc)
+data=\epoc32\data\z\testdata\config\stub1cc.ini testdata\config\stub1cc.ini
+
+#endif // __STUBCC_IBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/group/Stub1CC.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 1997-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:
+* ACMClassController.MMP
+*
+*/
+
+/**
+ @file
+*/
+
+target stub1cc.dll
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+targettype plugin
+DEFFILE stub1cc.def
+
+// ECom Dll recognition UID followed by the unique dll UID 
+UID              	0x10009d8d 0x10203284
+VENDORID 0x70000001
+
+SOURCEPATH		../src
+SOURCE			Stub1CCImpCollection.cpp
+SOURCE			Stub1CC.cpp
+
+USERINCLUDE		../inc
+USERINCLUDE		../../../../usbmgr/usbman/server/public
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+start resource 10203284.rss
+target stub1cc.rsc
+END
+
+LIBRARY			euser.lib 
+LIBRARY			usbclasscontroller.lib
+LIBRARY 		esock.lib
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/group/stub1cc.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,20 @@
+; Copyright (c) 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:
+; 
+;
+[0x10203285]
+StopDelay= 3000
+StartDelay= 3000
+FailToStart= 0
+FailToStop= 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/inc/Stub1CC.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,120 @@
+/**
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class API and talks to C32
+* to manage the stub1.CSY that is used to provide a virtual
+* serial port service to clients
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUsbstub1CLASSCONTROLLER_H__
+#define __CUsbstub1CLASSCONTROLLER_H__
+
+#include <e32std.h>
+#include <cusbclasscontrollerplugin.h>
+#include <d32usbc.h>
+
+class MUsbClassControllerNotify;
+
+const TInt Kstub1StartupPriority = 4;
+
+const TInt Kstub1CCDefaultDelay = 500; //0.5 sec default delay for start and stop
+
+const TInt Kstub1NumberOfInterfacesPerstub1Function = 2; // data and control interfaces
+
+// The name of the ini file specifying the number of functions required different from default
+/*
+_LIT(Kstub1FunctionsIniFileName, "NumberOfstub1Functions.ini");
+_LIT(Kstub1ConfigSection,"stub1_CONF");
+_LIT(KNumberOfstub1FunctionsKeyWord,"NumberOfstub1Functions");
+*/
+// Lengths of the various bits of the  descriptor. Taken from the USB
+// WMCDC specification, v1.0.
+const TInt Kstub1InterfaceDescriptorLength = 3;
+const TInt Kstub1CcHeaderDescriptorLength = 5;
+const TInt Kstub1FunctionalDescriptorLength = 4;
+const TInt Kstub1CcUfdDescriptorLength = 5;
+const TInt Kstub1NotificationEndpointDescriptorLength = 7;
+const TInt Kstub1DataClassInterfaceDescriptorLength = 3;
+const TInt Kstub1DataClassHeaderDescriptorLength = 5;
+const TInt Kstub1DataClassEndpointInDescriptorLength = 7;
+const TInt Kstub1DataClassEndpointOutDescriptorLength = 7;
+
+const TInt Kstub1DescriptorLength =
+	Kstub1InterfaceDescriptorLength +
+	Kstub1CcHeaderDescriptorLength +
+	Kstub1FunctionalDescriptorLength +
+	Kstub1CcUfdDescriptorLength +
+	Kstub1NotificationEndpointDescriptorLength +
+	Kstub1DataClassInterfaceDescriptorLength +
+	Kstub1DataClassHeaderDescriptorLength +
+	Kstub1DataClassEndpointInDescriptorLength +
+	Kstub1DataClassEndpointOutDescriptorLength;
+	
+/**
+ * The CUsbstub1ClassController class
+ *
+ * Implements the USB Class Controller API and manages the stub1.CSY
+ */
+NONSHARABLE_CLASS(CUsbstub1ClassController) : public CUsbClassControllerPlugIn
+	{
+
+public: // New functions.
+	static CUsbstub1ClassController* NewL(MUsbClassControllerNotify& aOwner);
+
+public: // Functions derived from CBase.
+	virtual ~CUsbstub1ClassController();
+
+public: // Functions derived from CActive.
+	virtual void RunL();
+	virtual void DoCancel();
+	virtual TInt RunError(TInt aError);
+
+public: // Functions derived from CUsbClassControllerBase
+	virtual void Start(TRequestStatus& aStatus);
+	virtual void Stop(TRequestStatus& aStatus);
+
+	virtual void GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const;
+
+protected:
+	CUsbstub1ClassController(MUsbClassControllerNotify& aOwner);
+	void ConstructL();
+
+
+
+private:
+	TInt SetUpInterface();
+
+	// delays in microseconds
+	TInt iStartDelay;
+	TInt iStopDelay;
+	
+	TBool iFailToStart;
+	TBool iFailToStop;
+	
+	RTimer iTimer;
+	TRequestStatus* iReportStatus;
+	RDevUsbcClient  iLdd;
+	
+	
+	};
+
+#endif //__CUsbstub1CLASSCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/src/10203284.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* 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 "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 <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x10203284;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x101fbf21;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x10203285;
+					version_no = 1;
+					display_name = "Stub1CC";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/src/Stub1CC.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,397 @@
+/*
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class Controller API and talks to C32
+* to manage the stub1.CSY that is used to provide a virtual
+* serial port service to clients
+*
+*/
+
+/**
+ @file
+*/
+
+#include "Stub1CC.h"
+#include <usb_std.h>
+#include <es_ini.h>
+#include <d32usbc.h>
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "STUB1CC");
+#endif
+
+
+#include "usbmaninternalconstants.h"
+ 
+
+// Panic category 
+_LIT( Kstub1CcPanicCategory, "Usbstub1Cc" );
+
+
+
+/**
+ * Panic codes for the USB stub1 Class Controller.
+ */
+enum Tstub1CcPanic
+	{
+	/** Class called while in an illegal state */
+	EBadApiCall = 0,
+	/** Asynchronous function called (not needed, as all requests complete synchronously) */
+	EUnusedFunction = 1,
+	/** Error reading ini file. */
+	EPanicBadIniFile = 2,		
+	/** Bad value for the iNumberOfstub1Functions member.*/
+	EPanicBadNumberOfstub1Functions = 3,
+	
+	EPanicUnexpectedStatus,
+	EPanicUnexpectedState
+
+	};
+_LIT16(KIfcName, "SubCC 1 Interface");
+const TInt KMaxPacketTypeInterrupt = 64;	
+const TInt KPollInterval  = 128; 
+
+
+
+/**
+ * Constructs a CUsbstub1ClassController object
+ *
+ * @param	aOwner	USB Device that owns and manages the class
+ *
+ * @return	A new CUsbstub1ClassController object
+ */
+CUsbstub1ClassController* CUsbstub1ClassController::NewL(
+	MUsbClassControllerNotify& aOwner)
+	{
+	CUsbstub1ClassController* r = new (ELeave) CUsbstub1ClassController(aOwner);
+	CleanupStack::PushL(r);
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+	}
+
+/**
+ * Destructor
+ */
+CUsbstub1ClassController::~CUsbstub1ClassController()
+	{
+	Cancel();
+
+	iTimer.Close();
+
+#ifndef __WINS__	
+	iLdd.Close();
+#endif
+	}
+
+
+
+/**
+ * Constructor.
+ *
+ * @param	aOwner	USB Device that owns and manages the class
+ */
+CUsbstub1ClassController::CUsbstub1ClassController(
+	MUsbClassControllerNotify& aOwner)
+	: CUsbClassControllerPlugIn(aOwner, Kstub1StartupPriority),
+	iStartDelay(Kstub1CCDefaultDelay),
+	iStopDelay(Kstub1CCDefaultDelay),
+	iFailToStart(EFalse),
+	iFailToStop(EFalse)	
+
+	{
+	iTimer.CreateLocal();
+	}
+
+
+
+/**
+ * 2nd Phase Construction.
+ */
+void CUsbstub1ClassController::ConstructL()
+	{
+	//read INI file
+	TInt ret;
+	CESockIniData* ini = 0;
+	_LIT(KIniFile, "c:\\testdata\\config\\stub1cc.ini");
+	TRAP(ret, ini=CESockIniData::NewL(KIniFile));	
+	if(ret!=KErrNone)		
+		return;	
+
+	CleanupStack::PushL(ini);
+	
+	TInt val;
+	if ((ini->FindVar(_L("0x10203285"),_L("StartDelay"), val)))
+		{
+		iStartDelay = val;
+		}
+	if ((ini->FindVar(_L("0x10203285"),_L("StopDelay"), val)))
+		{
+		iStopDelay = val;
+		}
+	if ((ini->FindVar(_L("0x10203285"),_L("FailToStart"), val)) && val!=0)
+		{
+		iFailToStart = ETrue;
+		}
+	if ((ini->FindVar(_L("0x10203285"),_L("FailToStop"), val)) && val!=0 )
+		{
+		iFailToStop = ETrue;
+		}	
+	CleanupStack::PopAndDestroy(ini);					
+	}
+
+/**
+ * Called by UsbMan when it wants to start the USB stub1 class. This always
+ * completes immediately.
+ *
+ * @param aStatus The caller's request status, filled in with an error code
+ */
+void CUsbstub1ClassController::Start(TRequestStatus& aStatus)
+	{
+	LOG_FUNC
+
+	aStatus = KRequestPending;
+	iReportStatus = &aStatus;
+	//If we are already started then just complete the request.
+	if (iState == EUsbServiceStarted)
+		{
+		User::RequestComplete(iReportStatus, KErrNone);
+		return;
+		}
+
+	if (iFailToStart)
+		{
+		User::RequestComplete(iReportStatus, KErrGeneral);
+		return;
+		}
+	
+	iState = EUsbServiceStarting;
+#ifndef __WINS__	
+	TInt ret = iLdd.Open(0);
+	LOGTEXT2(_L8("Open LDD, ret=%d"), ret);
+	ret = SetUpInterface();
+	LOGTEXT2(_L8("SetUpInterface(), ret=%d"), ret);
+#endif	
+	iTimer.After(iStatus, iStartDelay*1000);  //convert from usec to msec
+	SetActive();
+	}
+
+/**
+ * Called by UsbMan when it wants to stop the USB stub1 class.
+ *
+ * @param aStatus The caller's request status: always set to KErrNone
+ */
+void CUsbstub1ClassController::Stop(TRequestStatus& aStatus)
+	{
+	LOG_FUNC
+	
+	aStatus = KRequestPending;
+	iReportStatus = &aStatus;
+	//If we are already idle then just complete the request.
+	if (iState == EUsbServiceIdle)
+		{
+		User::RequestComplete(iReportStatus, KErrNone);
+		return;
+		}
+
+	if (iFailToStop)
+		{
+		User::RequestComplete(iReportStatus, KErrGeneral);
+		return;
+		}
+
+	iState = EUsbServiceStopping;
+
+#ifndef __WINS__	
+	iLdd.Close();
+#endif
+	
+	iTimer.After(iStatus, iStopDelay*1000);  //convert from usec to msec
+	SetActive();
+	}
+
+/**
+ * Gets information about the descriptor which this class provides.
+ *
+ * @param aDescriptorInfo Descriptor info structure filled in by this function
+ */
+void CUsbstub1ClassController::GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const
+	{
+	LOG_FUNC
+
+	aDescriptorInfo.iLength = Kstub1DescriptorLength;
+	aDescriptorInfo.iNumInterfaces = Kstub1NumberOfInterfacesPerstub1Function;
+	}
+
+
+/**
+ * Standard active object RunL. 
+ */
+void CUsbstub1ClassController::RunL()
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG( iStatus == KErrNone, _USB_PANIC(Kstub1CcPanicCategory, EPanicUnexpectedStatus) );
+	switch (iState)
+		{
+		case EUsbServiceStarting:
+			iState = EUsbServiceStarted;
+			break;
+		case EUsbServiceStopping:
+			iState = EUsbServiceIdle;
+			break;
+		default:	
+			_USB_PANIC(Kstub1CcPanicCategory, EPanicUnexpectedState);
+		}
+	*iReportStatus = KErrNone;	
+	User::RequestComplete(iReportStatus, iStatus.Int());	
+	}
+
+/**
+ * Standard active object cancellation function. Never called because this
+ * class has no asynchronous requests.
+ */
+void CUsbstub1ClassController::DoCancel()
+	{
+
+	if (IsActive())
+		{
+		iTimer.Cancel();	
+		}
+	switch (iState)
+	{
+		case EUsbServiceStarting:
+			iState = EUsbServiceIdle;
+			break;
+		case EUsbServiceStopping:
+			iState = EUsbServiceStarted;
+			break;
+		default:	
+			_USB_PANIC(Kstub1CcPanicCategory, EPanicUnexpectedState);
+	}
+	*iReportStatus = KErrNone;		
+	User::RequestComplete(iReportStatus, KErrCancel);	
+	}
+
+/**
+ * Standard active object error function. Never called because this class has
+ * no asynchronous requests, and hence its RunL is never called.
+ *
+ * @param aError The error code (unused)
+ * @return Always KErrNone to avoid an active scheduler panic
+ */
+TInt CUsbstub1ClassController::RunError(TInt /*aError*/)
+	{
+	__ASSERT_DEBUG( EFalse, _USB_PANIC(Kstub1CcPanicCategory, EUnusedFunction) );
+	return KErrNone;
+	}
+	
+TInt CUsbstub1ClassController::SetUpInterface()
+/**
+ * Set up the interface for use. This involves finding a "Interrupt IN" 
+ * endpoint and, if found, configuring the interface.
+ */
+	{
+	LOGTEXT(_L8(">>CCdcControlInterface::SetUpInterface"));
+
+	TUsbDeviceCaps dCaps;
+	TInt ret = iLdd.DeviceCaps(dCaps);
+	LOGTEXT(_L8("\tchecking result of DeviceCaps"));
+	if ( ret )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), ret);
+		return ret;
+		}
+
+	const TUint KRequiredNumberOfEndpoints = 1; // in addition to endpoint 0.
+
+	const TUint totalEndpoints = static_cast<TUint>(dCaps().iTotalEndpoints);
+	LOGTEXT2(_L8("\tiTotalEndpoints = %d"), totalEndpoints);
+	if ( totalEndpoints < KRequiredNumberOfEndpoints )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), 
+			KErrGeneral);
+		return KErrGeneral;
+		}
+	
+	// Endpoints
+	TUsbcEndpointData data[KUsbcMaxEndpoints];
+	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
+	ret = iLdd.EndpointCaps(dataptr);
+	LOGTEXT(_L8("\tchecking result of EndpointCaps"));
+	if ( ret )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), ret);
+		return ret;
+		}
+
+	// Set the active interface
+	TUsbcInterfaceInfoBuf ifc;
+	TBool epFound = EFalse;
+	for ( TUint i = 0 ; i < totalEndpoints ; i++ )
+		{
+		const TUsbcEndpointCaps* caps = &data[i].iCaps;
+		__ASSERT_DEBUG(caps,_USB_PANIC(Kstub1CcPanicCategory, EPanicUnexpectedStatus));
+
+		if (data[i].iInUse)
+			{
+			continue;
+			}
+
+		if ((caps->iTypesAndDir & (KUsbEpTypeInterrupt | KUsbEpDirIn)) == 
+			(KUsbEpTypeInterrupt | KUsbEpDirIn))
+			{
+			// EEndpoint1 is interrupt endpoint
+			ifc().iEndpointData[0].iType  = KUsbEpTypeInterrupt;
+			ifc().iEndpointData[0].iDir   = KUsbEpDirIn; 
+
+			//get the max packet size it can potentially support
+			//it's possible that it can support Isoch (1023) which is greater
+			//than max for Int at 64
+			TInt maxSize = Min(caps->MaxPacketSize(), KMaxPacketTypeInterrupt);
+			
+			ifc().iEndpointData[0].iSize  = maxSize;
+
+			ifc().iEndpointData[0].iInterval = KPollInterval; 
+			epFound = ETrue;
+			break;
+			}
+		}
+	LOGTEXT(_L8("\tchecking epFound"));
+	if ( !epFound )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), 
+			KErrGeneral);
+		return KErrGeneral;
+		}
+
+	TName ifcName(KIfcName);
+	ifc().iString = &ifcName;
+	ifc().iTotalEndpointsUsed = KRequiredNumberOfEndpoints;
+	// Codes taken from USBCDC 1.1.
+	ifc().iClass.iClassNum	  = 0x02; // Table 15- Communication Interface Class
+	ifc().iClass.iSubClassNum = 0x02; // Table 16- Abstract Control Model
+	ifc().iClass.iProtocolNum = 0x01; // Table 17- Hayes compatible
+
+	LOGTEXT(_L8("\tabout to call SetInterface"));
+	// Zero effectively indicates that alternate interfaces are not used.
+	ret = iLdd.SetInterface(0, ifc);
+
+	LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), ret);
+	return ret;
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub1CC/src/Stub1CCImpCollection.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 1997-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:
+* Defines the implementation collection for the ACM class controller.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32base.h>
+#include <e32std.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include "Stub1CC.h"
+
+// Define the private interface UIDs
+const TImplementationProxy UsbCCImplementationTable[] =
+    {
+	IMPLEMENTATION_PROXY_ENTRY(0x10203285, CUsbstub1ClassController::NewL),
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(UsbCCImplementationTable) / sizeof(TImplementationProxy);
+
+    return UsbCCImplementationTable;
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/EABI/stub2ccU.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,3 @@
+EXPORTS
+	_Z24ImplementationGroupProxyRi @ 1 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* 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 "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:
+*
+*/
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_TESTEXPORTS
+#ifndef WINS
+Stub2CC.iby			/epoc32/rom/include/stub2cc.iby
+stub2cc.ini			z:/testdata/config/stub2cc.ini
+#endif
+
+PRJ_TESTMMPFILES
+#ifndef WINS
+Stub2CC.mmp
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/group/Stub2CC.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+#ifndef __STUB2CC_IBY__
+#define __STUB2CC_IBY__
+
+
+// Universal Serial Bus Stub2 Class Controller
+
+#include <ecom.iby>
+
+ECOM_PLUGIN(stub2cc.dll,10203286.rsc)
+data=\epoc32\data\z\testdata\config\stub2cc.ini testdata\config\stub2cc.ini
+
+#endif // __STUBCC_IBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/group/Stub2CC.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 1997-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:
+* ACMClassController.MMP
+*
+*/
+
+/**
+ @file
+*/
+
+target stub2cc.dll
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+targettype plugin
+
+// ECom Dll recognition UID followed by the unique dll UID 
+UID              	0x10009d8d 0x10203286
+VENDORID 0x70000001
+DEFFILE stub2cc.def
+
+SOURCEPATH		../src
+SOURCE			Stub2CCImpCollection.cpp
+SOURCE			Stub2CC.cpp
+
+USERINCLUDE		../inc
+USERINCLUDE		../../../../usbmgr/usbman/server/public
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+start resource 10203286.rss
+target stub2cc.rsc
+END
+
+LIBRARY			euser.lib
+LIBRARY			usbclasscontroller.lib
+LIBRARY 		esock.lib
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/group/stub2cc.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,20 @@
+; Copyright (c) 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:
+; 
+;
+[0x10203287]
+StopDelay= 3000
+StartDelay= 3000
+FailToStart= 0
+FailToStop= 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/inc/Stub2CC.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,122 @@
+/**
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class API and talks to C32
+* to manage the stub2.CSY that is used to provide a virtual
+* serial port service to clients
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBstub2CLASSCONTROLLER_H__
+#define __CUSBstub2CLASSCONTROLLER_H__
+
+#include <e32std.h>
+#include <cusbclasscontrollerplugin.h>
+#include <d32usbc.h>
+
+class MUsbClassControllerNotify;
+
+const TInt Kstub2StartupPriority = 3;
+
+const TInt Kstub2CCDefaultDelay = 500; //0.5 sec default delay for start and stop
+
+const TInt Kstub2NumberOfInterfacesPerstub2Function = 2; // data and control interfaces
+
+// The name of the ini file specifying the number of functions required different from default
+/*
+_LIT(Kstub2FunctionsIniFileName, "NumberOfstub2Functions.ini");
+_LIT(Kstub2ConfigSection,"stub2_CONF");
+_LIT(KNumberOfstub2FunctionsKeyWord,"NumberOfstub2Functions");
+*/
+// Lengths of the various bits of the  descriptor. Taken from the USB
+// WMCDC specification, v1.0.
+const TInt Kstub2InterfaceDescriptorLength = 3;
+const TInt Kstub2CcHeaderDescriptorLength = 5;
+const TInt Kstub2FunctionalDescriptorLength = 4;
+const TInt Kstub2CcUfdDescriptorLength = 5;
+const TInt Kstub2NotificationEndpointDescriptorLength = 7;
+const TInt Kstub2DataClassInterfaceDescriptorLength = 3;
+const TInt Kstub2DataClassHeaderDescriptorLength = 5;
+const TInt Kstub2DataClassEndpointInDescriptorLength = 7;
+const TInt Kstub2DataClassEndpointOutDescriptorLength = 7;
+
+const TInt Kstub2DescriptorLength =
+	Kstub2InterfaceDescriptorLength +
+	Kstub2CcHeaderDescriptorLength +
+	Kstub2FunctionalDescriptorLength +
+	Kstub2CcUfdDescriptorLength +
+	Kstub2NotificationEndpointDescriptorLength +
+	Kstub2DataClassInterfaceDescriptorLength +
+	Kstub2DataClassHeaderDescriptorLength +
+	Kstub2DataClassEndpointInDescriptorLength +
+	Kstub2DataClassEndpointOutDescriptorLength;
+	
+/**
+ * The CUsbstub2ClassController class
+ *
+ * Implements the USB Class Controller API and manages the stub2.CSY
+ */
+NONSHARABLE_CLASS(CUsbstub2ClassController) : public CUsbClassControllerPlugIn
+	{
+
+public: // New functions.
+	static CUsbstub2ClassController* NewL(MUsbClassControllerNotify& aOwner);
+
+public: // Functions derived from CBase.
+	virtual ~CUsbstub2ClassController();
+
+public: // Functions derived from CActive.
+	virtual void RunL();
+	virtual void DoCancel();
+	virtual TInt RunError(TInt aError);
+
+public: // Functions derived from CUsbClassControllerBase
+	virtual void Start(TRequestStatus& aStatus);
+	virtual void Stop(TRequestStatus& aStatus);
+
+	virtual void GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const;
+
+protected:
+	CUsbstub2ClassController(MUsbClassControllerNotify& aOwner);
+	void ConstructL();
+
+
+
+private:
+	TInt SetUpInterface();
+
+
+	// delays in microseconds
+	TInt iStartDelay;
+	TInt iStopDelay;
+	
+	TBool iFailToStart;
+	TBool iFailToStop;
+	
+	RTimer iTimer;
+	TRequestStatus* iReportStatus;
+	RDevUsbcClient  iLdd;
+
+	
+	
+	};
+
+#endif //__CUSBstub2CLASSCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/src/10203286.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+
+/*
+* 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 "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 <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x10203286;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x101fbf21;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x10203287;
+					version_no = 1;
+					display_name = "Stub2CC";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/src/Stub2CC.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,400 @@
+/*
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class Controller API and talks to C32
+* to manage the stub2.CSY that is used to provide a virtual
+* serial port service to clients
+*
+*/
+
+/**
+ @file
+*/
+
+#include "Stub2CC.h"
+#include <usb_std.h>
+#include <es_ini.h>
+#include <d32usbc.h>
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "STUB2CC");
+#endif
+
+
+#include "usbmaninternalconstants.h"
+ 
+
+// Panic category 
+_LIT( Kstub2CcPanicCategory, "Usbstub2Cc" );
+
+
+/**
+ * Panic codes for the USB stub2 Class Controller.
+ */
+enum Tstub2CcPanic
+	{
+	/** Class called while in an illegal state */
+	EBadApiCall = 0,
+	/** Asynchronous function called (not needed, as all requests complete synchronously) */
+	EUnusedFunction = 1,
+	/** Error reading ini file. */
+	EPanicBadIniFile = 2,		
+	/** Bad value for the iNumberOfstub2Functions member.*/
+	EPanicBadNumberOfstub2Functions = 3,
+	
+	EPanicUnexpectedStatus,
+	EPanicUnexpectedState
+
+	};
+
+_LIT16(KIfcName, "SubCC 1 Interface");
+const TInt KMaxPacketTypeInterrupt = 64;	
+const TInt KPollInterval  = 128; 
+
+
+
+/**
+ * Constructs a CUsbstub2ClassController object
+ *
+ * @param	aOwner	USB Device that owns and manages the class
+ *
+ * @return	A new CUsbstub2ClassController object
+ */
+CUsbstub2ClassController* CUsbstub2ClassController::NewL(
+	MUsbClassControllerNotify& aOwner)
+	{
+	CUsbstub2ClassController* r = new (ELeave) CUsbstub2ClassController(aOwner);
+	CleanupStack::PushL(r);
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+	}
+
+/**
+ * Destructor
+ */
+CUsbstub2ClassController::~CUsbstub2ClassController()
+	{
+	Cancel();
+
+	iTimer.Close();
+	
+#ifndef __WINS__	
+	iLdd.Close();
+#endif
+
+	}
+
+
+
+/**
+ * Constructor.
+ *
+ * @param	aOwner	USB Device that owns and manages the class
+ */
+CUsbstub2ClassController::CUsbstub2ClassController(
+	MUsbClassControllerNotify& aOwner)
+	: CUsbClassControllerPlugIn(aOwner, Kstub2StartupPriority),
+	iStartDelay(Kstub2CCDefaultDelay),
+	iStopDelay(Kstub2CCDefaultDelay),
+	iFailToStart(EFalse),
+	iFailToStop(EFalse)	
+
+	{
+	iTimer.CreateLocal();
+	}
+
+
+
+/**
+ * 2nd Phase Construction.
+ */
+void CUsbstub2ClassController::ConstructL()
+	{
+	//read INI file
+	TInt ret;
+	CESockIniData* ini = 0;
+	_LIT(KIniFile, "c:\\testdata\\config\\stub2cc.ini");
+	TRAP(ret, ini=CESockIniData::NewL(KIniFile));	
+	if(ret!=KErrNone)		
+		return;	
+
+	CleanupStack::PushL(ini);
+	
+	TInt val;
+	if ((ini->FindVar(_L("0x10203287"),_L("StartDelay"), val)))
+		{
+		iStartDelay = val;
+		}
+	if ((ini->FindVar(_L("0x10203287"),_L("StopDelay"), val)))
+		{
+		iStopDelay = val;
+		}
+	if ((ini->FindVar(_L("0x10203287"),_L("FailToStart"), val)) && val!=0)
+		{
+		iFailToStart = ETrue;
+		}
+	if ((ini->FindVar(_L("0x10203287"),_L("FailToStop"), val)) && val!=0 )
+		{
+		iFailToStop = ETrue;
+		}
+	CleanupStack::PopAndDestroy(ini);						
+	}
+
+/**
+ * Called by UsbMan when it wants to start the USB stub2 class. This always
+ * completes immediately.
+ *
+ * @param aStatus The caller's request status, filled in with an error code
+ */
+void CUsbstub2ClassController::Start(TRequestStatus& aStatus)
+	{
+	LOG_FUNC
+
+	aStatus = KRequestPending;
+	iReportStatus = &aStatus;
+	//If we are already started then just complete the request.
+	if (iState == EUsbServiceStarted)
+		{
+		User::RequestComplete(iReportStatus, KErrNone);
+		return;
+		}
+
+	if (iFailToStart)
+		{
+		User::RequestComplete(iReportStatus, KErrGeneral);
+		return;
+		}
+	
+	iState = EUsbServiceStarting;
+#ifndef __WINS__	
+	TInt ret = iLdd.Open(0);
+	LOGTEXT2(_L8("Open LDD, ret=%d"), ret);
+	ret = SetUpInterface();
+	LOGTEXT2(_L8("SetUpInterface(), ret=%d"), ret);
+#endif	
+
+
+	iTimer.After(iStatus, iStartDelay*1000);  //convert from usec to msec
+	SetActive();
+	}
+
+/**
+ * Called by UsbMan when it wants to stop the USB stub2 class.
+ *
+ * @param aStatus The caller's request status: always set to KErrNone
+ */
+void CUsbstub2ClassController::Stop(TRequestStatus& aStatus)
+	{
+	LOG_FUNC
+
+	aStatus = KRequestPending;
+	iReportStatus = &aStatus;
+	//If we are already idle then just complete the request.
+	if (iState == EUsbServiceIdle)
+		{
+		User::RequestComplete(iReportStatus, KErrNone);
+		return;
+		}
+
+	if (iFailToStop)
+		{
+		User::RequestComplete(iReportStatus, KErrGeneral);
+		return;
+		}
+
+	iState = EUsbServiceStopping;
+	
+#ifndef __WINS__	
+	iLdd.Close();
+#endif
+
+	iTimer.After(iStatus, iStopDelay*1000);  //convert from usec to msec
+	SetActive();
+	}
+
+/**
+ * Gets information about the descriptor which this class provides.
+ *
+ * @param aDescriptorInfo Descriptor info structure filled in by this function
+ */
+void CUsbstub2ClassController::GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const
+	{
+	LOG_FUNC
+
+	aDescriptorInfo.iLength = Kstub2DescriptorLength;
+	aDescriptorInfo.iNumInterfaces = Kstub2NumberOfInterfacesPerstub2Function;
+	}
+
+
+/**
+ * Standard active object RunL. 
+ */
+void CUsbstub2ClassController::RunL()
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG( iStatus == KErrNone, _USB_PANIC(Kstub2CcPanicCategory, EPanicUnexpectedStatus) );
+	switch (iState)
+		{
+		case EUsbServiceStarting:
+			iState = EUsbServiceStarted;
+			break;
+		case EUsbServiceStopping:
+			iState = EUsbServiceIdle;
+			break;
+		default:	
+			_USB_PANIC(Kstub2CcPanicCategory, EPanicUnexpectedState);
+		}
+	*iReportStatus = KErrNone;	
+	User::RequestComplete(iReportStatus, iStatus.Int());	
+	}
+
+/**
+ * Standard active object cancellation function. Never called because this
+ * class has no asynchronous requests.
+ */
+void CUsbstub2ClassController::DoCancel()
+	{
+
+	if (IsActive())
+		{
+		iTimer.Cancel();	
+		}
+	switch (iState)
+	{
+		case EUsbServiceStarting:
+			iState = EUsbServiceIdle;
+			break;
+		case EUsbServiceStopping:
+			iState = EUsbServiceStarted;
+			break;
+		default:	
+			_USB_PANIC(Kstub2CcPanicCategory, EPanicUnexpectedState);
+	}
+	*iReportStatus = KErrNone;		
+	User::RequestComplete(iReportStatus, KErrCancel);	
+	}
+
+/**
+ * Standard active object error function. Never called because this class has
+ * no asynchronous requests, and hence its RunL is never called.
+ *
+ * @param aError The error code (unused)
+ * @return Always KErrNone to avoid an active scheduler panic
+ */
+TInt CUsbstub2ClassController::RunError(TInt /*aError*/)
+	{
+	__ASSERT_DEBUG( EFalse, _USB_PANIC(Kstub2CcPanicCategory, EUnusedFunction) );
+	return KErrNone;
+	}
+
+TInt CUsbstub2ClassController::SetUpInterface()
+/**
+ * Set up the interface for use. This involves finding a "Interrupt IN" 
+ * endpoint and, if found, configuring the interface.
+ */
+	{
+	LOGTEXT(_L8(">>CCdcControlInterface::SetUpInterface"));
+
+	TUsbDeviceCaps dCaps;
+	TInt ret = iLdd.DeviceCaps(dCaps);
+	LOGTEXT(_L8("\tchecking result of DeviceCaps"));
+	if ( ret )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), ret);
+		return ret;
+		}
+
+	const TUint KRequiredNumberOfEndpoints = 1; // in addition to endpoint 0.
+
+	const TUint totalEndpoints = static_cast<TUint>(dCaps().iTotalEndpoints);
+	LOGTEXT2(_L8("\tiTotalEndpoints = %d"), totalEndpoints);
+	if ( totalEndpoints < KRequiredNumberOfEndpoints )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), 
+			KErrGeneral);
+		return KErrGeneral;
+		}
+	
+	// Endpoints
+	TUsbcEndpointData data[KUsbcMaxEndpoints];
+	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
+	ret = iLdd.EndpointCaps(dataptr);
+	LOGTEXT(_L8("\tchecking result of EndpointCaps"));
+	if ( ret )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), ret);
+		return ret;
+		}
+
+	// Set the active interface
+	TUsbcInterfaceInfoBuf ifc;
+	TBool epFound = EFalse;
+	for ( TUint i = 0 ; i < totalEndpoints ; i++ )
+		{
+		const TUsbcEndpointCaps* caps = &data[i].iCaps;
+		__ASSERT_DEBUG(caps,_USB_PANIC(Kstub2CcPanicCategory, EPanicUnexpectedStatus));
+
+		if (data[i].iInUse)
+			{
+			continue;
+			}
+
+		if ((caps->iTypesAndDir & (KUsbEpTypeInterrupt | KUsbEpDirIn)) == 
+			(KUsbEpTypeInterrupt | KUsbEpDirIn))
+			{
+			// EEndpoint1 is interrupt endpoint
+			ifc().iEndpointData[0].iType  = KUsbEpTypeInterrupt;
+			ifc().iEndpointData[0].iDir   = KUsbEpDirIn; 
+
+			//get the max packet size it can potentially support
+			//it's possible that it can support Isoch (1023) which is greater
+			//than max for Int at 64
+			TInt maxSize = Min(caps->MaxPacketSize(), KMaxPacketTypeInterrupt);
+			
+			ifc().iEndpointData[0].iSize  = maxSize;
+
+			ifc().iEndpointData[0].iInterval = KPollInterval; 
+			epFound = ETrue;
+			break;
+			}
+		}
+	LOGTEXT(_L8("\tchecking epFound"));
+	if ( !epFound )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), 
+			KErrGeneral);
+		return KErrGeneral;
+		}
+
+	TName ifcName(KIfcName);
+	ifc().iString = &ifcName;
+	ifc().iTotalEndpointsUsed = KRequiredNumberOfEndpoints;
+	// Codes taken from USBCDC 1.1.
+	ifc().iClass.iClassNum	  = 0x02; // Table 15- Communication Interface Class
+	ifc().iClass.iSubClassNum = 0x02; // Table 16- Abstract Control Model
+	ifc().iClass.iProtocolNum = 0x01; // Table 17- Hayes compatible
+
+	LOGTEXT(_L8("\tabout to call SetInterface"));
+	// Zero effectively indicates that alternate interfaces are not used.
+	ret = iLdd.SetInterface(0, ifc);
+
+	LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), ret);
+	return ret;
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub2CC/src/Stub2CCImpCollection.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 1997-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:
+* Defines the implementation collection for the ACM class controller.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32base.h>
+#include <e32std.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include "Stub2CC.h"
+
+// Define the private interface UIDs
+const TImplementationProxy UsbCCImplementationTable[] =
+    {
+	IMPLEMENTATION_PROXY_ENTRY(0x10203287, CUsbstub2ClassController::NewL),
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(UsbCCImplementationTable) / sizeof(TImplementationProxy);
+
+    return UsbCCImplementationTable;
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/EABI/stub3ccU.def	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,3 @@
+EXPORTS
+	_Z24ImplementationGroupProxyRi @ 1 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* 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 "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:
+*
+*/
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_TESTEXPORTS
+#ifndef WINS
+Stub3CC.iby			/epoc32/rom/include/stub3cc.iby
+stub3cc.ini			z:/testdata/config/stub3cc.ini
+#endif
+
+PRJ_TESTMMPFILES
+#ifndef WINS
+Stub3CC.mmp
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/group/Stub3CC.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+#ifndef __STUB3CC_IBY__
+#define __STUB3CC_IBY__
+
+
+// Universal Serial Bus Stub3 Class Controller
+
+#include <ecom.iby>
+
+ECOM_PLUGIN(stub3cc.dll,10203288.rsc)
+data=\epoc32\data\z\testdata\config\stub3cc.ini testdata\config\stub3cc.ini
+
+#endif // __STUBCC_IBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/group/Stub3CC.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 1997-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:
+* ACMClassController.MMP
+*
+*/
+
+/**
+ @file
+*/
+
+target stub3cc.dll
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+targettype plugin
+
+// ECom Dll recognition UID followed by the unique dll UID 
+UID              	0x10009d8d 0x10203288
+VENDORID 0x70000001
+DEFFILE stub3cc.def
+
+SOURCEPATH		../src
+SOURCE			Stub3CCImpCollection.cpp
+SOURCE			Stub3CC.cpp
+
+USERINCLUDE		../inc
+USERINCLUDE		../../../../usbmgr/usbman/server/public
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+start resource 10203288.rss
+target stub3cc.rsc
+END
+
+LIBRARY			euser.lib 
+LIBRARY			usbclasscontroller.lib
+LIBRARY 		esock.lib
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/group/stub3cc.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,20 @@
+; Copyright (c) 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:
+; 
+;
+[0x10203289]
+StopDelay= 3000
+StartDelay= 3000
+FailToStart= 0
+FailToStop= 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/inc/Stub3CC.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,122 @@
+/**
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class API and talks to C32
+* to manage the stub3.CSY that is used to provide a virtual
+* serial port service to clients
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBstub3CLASSCONTROLLER_H__
+#define __CUSBstub3CLASSCONTROLLER_H__
+
+#include <e32std.h>
+#include <cusbclasscontrollerplugin.h>
+#include <d32usbc.h>
+
+class MUsbClassControllerNotify;
+
+const TInt Kstub3StartupPriority = 2;
+
+const TInt Kstub3CCDefaultDelay = 500; //0.5 sec default delay for start and stop
+
+const TInt Kstub3NumberOfInterfacesPerstub3Function = 2; // data and control interfaces
+
+// The name of the ini file specifying the number of functions required different from default
+/*
+_LIT(Kstub3FunctionsIniFileName, "NumberOfstub3Functions.ini");
+_LIT(Kstub3ConfigSection,"stub3_CONF");
+_LIT(KNumberOfstub3FunctionsKeyWord,"NumberOfstub3Functions");
+*/
+// Lengths of the various bits of the  descriptor. Taken from the USB
+// WMCDC specification, v1.0.
+const TInt Kstub3InterfaceDescriptorLength = 3;
+const TInt Kstub3CcHeaderDescriptorLength = 5;
+const TInt Kstub3FunctionalDescriptorLength = 4;
+const TInt Kstub3CcUfdDescriptorLength = 5;
+const TInt Kstub3NotificationEndpointDescriptorLength = 7;
+const TInt Kstub3DataClassInterfaceDescriptorLength = 3;
+const TInt Kstub3DataClassHeaderDescriptorLength = 5;
+const TInt Kstub3DataClassEndpointInDescriptorLength = 7;
+const TInt Kstub3DataClassEndpointOutDescriptorLength = 7;
+
+const TInt Kstub3DescriptorLength =
+	Kstub3InterfaceDescriptorLength +
+	Kstub3CcHeaderDescriptorLength +
+	Kstub3FunctionalDescriptorLength +
+	Kstub3CcUfdDescriptorLength +
+	Kstub3NotificationEndpointDescriptorLength +
+	Kstub3DataClassInterfaceDescriptorLength +
+	Kstub3DataClassHeaderDescriptorLength +
+	Kstub3DataClassEndpointInDescriptorLength +
+	Kstub3DataClassEndpointOutDescriptorLength;
+	
+/**
+ * The CUsbstub3ClassController class
+ *
+ * Implements the USB Class Controller API and manages the stub3.CSY
+ */
+NONSHARABLE_CLASS(CUsbstub3ClassController) : public CUsbClassControllerPlugIn
+	{
+
+public: // New functions.
+	static CUsbstub3ClassController* NewL(MUsbClassControllerNotify& aOwner);
+
+public: // Functions derived from CBase.
+	virtual ~CUsbstub3ClassController();
+
+public: // Functions derived from CActive.
+	virtual void RunL();
+	virtual void DoCancel();
+	virtual TInt RunError(TInt aError);
+
+public: // Functions derived from CUsbClassControllerBase
+	virtual void Start(TRequestStatus& aStatus);
+	virtual void Stop(TRequestStatus& aStatus);
+
+	virtual void GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const;
+
+protected:
+	CUsbstub3ClassController(MUsbClassControllerNotify& aOwner);
+	void ConstructL();
+
+
+
+private:
+	TInt SetUpInterface();
+
+
+	// delays in microseconds
+	TInt iStartDelay;
+	TInt iStopDelay;
+	
+	TBool iFailToStart;
+	TBool iFailToStop;
+	
+	RTimer iTimer;
+	TRequestStatus* iReportStatus;
+	RDevUsbcClient  iLdd;
+
+	
+	
+	};
+
+#endif //__CUSBstub3CLASSCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/src/10203288.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* 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 "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 <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x10203288;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x101fbf21;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x10203289;
+					version_no = 1;
+					display_name = "Stub3CC";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/src/Stub3CC.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,403 @@
+/*
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class Controller API and talks to C32
+* to manage the stub3.CSY that is used to provide a virtual
+* serial port service to clients
+*
+*/
+
+/**
+ @file
+*/
+
+#include "Stub3CC.h"
+#include <usb_std.h>
+#include <es_ini.h>
+#include <d32usbc.h>
+#include <usb/usblogger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "STUB3CC");
+#endif
+
+
+#include "usbmaninternalconstants.h"
+ 
+
+// Panic category 
+_LIT( Kstub3CcPanicCategory, "Usbstub3Cc" );
+
+
+/**
+ * Panic codes for the USB stub3 Class Controller.
+ */
+enum Tstub3CcPanic
+	{
+	/** Class called while in an illegal state */
+	EBadApiCall = 0,
+	/** Asynchronous function called (not needed, as all requests complete synchronously) */
+	EUnusedFunction = 1,
+	/** Error reading ini file. */
+	EPanicBadIniFile = 2,		
+	/** Bad value for the iNumberOfstub3Functions member.*/
+	EPanicBadNumberOfstub3Functions = 3,
+	
+	EPanicUnexpectedStatus,
+	EPanicUnexpectedState
+
+	};
+	
+_LIT16(KIfcName, "SubCC 1 Interface");
+const TInt KMaxPacketTypeInterrupt = 64;	
+const TInt KPollInterval  = 128; 
+
+
+
+
+/**
+ * Constructs a CUsbstub3ClassController object
+ *
+ * @param	aOwner	USB Device that owns and manages the class
+ *
+ * @return	A new CUsbstub3ClassController object
+ */
+CUsbstub3ClassController* CUsbstub3ClassController::NewL(
+	MUsbClassControllerNotify& aOwner)
+	{
+	CUsbstub3ClassController* r = new (ELeave) CUsbstub3ClassController(aOwner);
+	CleanupStack::PushL(r);
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+	}
+
+/**
+ * Destructor
+ */
+CUsbstub3ClassController::~CUsbstub3ClassController()
+	{
+	Cancel();
+
+	iTimer.Close();
+
+#ifndef __WINS__	
+	iLdd.Close();
+#endif
+
+	}
+
+
+
+/**
+ * Constructor.
+ *
+ * @param	aOwner	USB Device that owns and manages the class
+ */
+CUsbstub3ClassController::CUsbstub3ClassController(
+	MUsbClassControllerNotify& aOwner)
+	: CUsbClassControllerPlugIn(aOwner, Kstub3StartupPriority),
+	iStartDelay(Kstub3CCDefaultDelay),
+	iStopDelay(Kstub3CCDefaultDelay),
+	iFailToStart(EFalse),
+	iFailToStop(EFalse)	
+
+	{
+	iTimer.CreateLocal();
+	}
+
+
+
+/**
+ * 2nd Phase Construction.
+ */
+void CUsbstub3ClassController::ConstructL()
+	{
+	//read INI file
+	TInt ret;
+	CESockIniData* ini = 0;
+	_LIT(KIniFile, "c:\\testdata\\config\\stub3cc.ini");
+	TRAP(ret, ini=CESockIniData::NewL(KIniFile));	
+	if(ret!=KErrNone)		
+		return;	
+
+	CleanupStack::PushL(ini);
+	
+	TInt val;
+	if ((ini->FindVar(_L("0x10203289"),_L("StartDelay"), val)))
+		{
+		iStartDelay = val;
+		}
+	if ((ini->FindVar(_L("0x10203289"),_L("StopDelay"), val)))
+		{
+		iStopDelay = val;
+		}
+	if ((ini->FindVar(_L("0x10203289"),_L("FailToStart"), val)) && val!=0)
+		{
+		iFailToStart = ETrue;
+		}
+	if ((ini->FindVar(_L("0x10203289"),_L("FailToStop"), val)) && val!=0 )
+		{
+		iFailToStop = ETrue;
+		}
+	CleanupStack::PopAndDestroy(ini);						
+	}
+
+/**
+ * Called by UsbMan when it wants to start the USB stub3 class. This always
+ * completes immediately.
+ *
+ * @param aStatus The caller's request status, filled in with an error code
+ */
+void CUsbstub3ClassController::Start(TRequestStatus& aStatus)
+	{
+	LOG_FUNC
+
+	aStatus = KRequestPending;
+	iReportStatus = &aStatus;
+	//If we are already started then just complete the request.
+	if (iState == EUsbServiceStarted)
+		{
+		User::RequestComplete(iReportStatus, KErrNone);
+		return;
+		}
+
+	if (iFailToStart)
+		{
+		User::RequestComplete(iReportStatus, KErrGeneral);
+		return;
+		}
+	
+	iState = EUsbServiceStarting;
+	
+#ifndef __WINS__	
+	TInt ret = iLdd.Open(0);
+	LOGTEXT2(_L8("Open LDD, ret=%d"), ret);
+	ret = SetUpInterface();
+	LOGTEXT2(_L8("SetUpInterface(), ret=%d"), ret);
+#endif	
+
+
+	iTimer.After(iStatus, iStartDelay*1000);  //convert from usec to msec
+	SetActive();
+	}
+
+/**
+ * Called by UsbMan when it wants to stop the USB stub3 class.
+ *
+ * @param aStatus The caller's request status: always set to KErrNone
+ */
+void CUsbstub3ClassController::Stop(TRequestStatus& aStatus)
+	{
+	LOG_FUNC
+
+	aStatus = KRequestPending;
+	iReportStatus = &aStatus;
+	//If we are already idle then just complete the request.
+	if (iState == EUsbServiceIdle)
+		{
+		User::RequestComplete(iReportStatus, KErrNone);
+		return;
+		}
+
+	if (iFailToStop)
+		{
+		User::RequestComplete(iReportStatus, KErrGeneral);
+		return;
+		}
+
+	iState = EUsbServiceStopping;
+
+#ifndef __WINS__	
+	iLdd.Close();
+#endif
+
+	
+	iTimer.After(iStatus, iStopDelay*1000);  //convert from usec to msec
+	SetActive();
+	}
+
+/**
+ * Gets information about the descriptor which this class provides.
+ *
+ * @param aDescriptorInfo Descriptor info structure filled in by this function
+ */
+void CUsbstub3ClassController::GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const
+	{
+	LOG_FUNC
+
+	aDescriptorInfo.iLength = Kstub3DescriptorLength;
+	aDescriptorInfo.iNumInterfaces = Kstub3NumberOfInterfacesPerstub3Function;
+	}
+
+
+/**
+ * Standard active object RunL. 
+ */
+void CUsbstub3ClassController::RunL()
+	{
+	LOG_FUNC
+
+	__ASSERT_DEBUG( iStatus == KErrNone, _USB_PANIC(Kstub3CcPanicCategory, EPanicUnexpectedStatus) );
+	switch (iState)
+		{
+		case EUsbServiceStarting:
+			iState = EUsbServiceStarted;
+			break;
+		case EUsbServiceStopping:
+			iState = EUsbServiceIdle;
+			break;
+		default:	
+			_USB_PANIC(Kstub3CcPanicCategory, EPanicUnexpectedState);
+		}
+	*iReportStatus = KErrNone;	
+	User::RequestComplete(iReportStatus, iStatus.Int());	
+	}
+
+/**
+ * Standard active object cancellation function. Never called because this
+ * class has no asynchronous requests.
+ */
+void CUsbstub3ClassController::DoCancel()
+	{
+
+	if (IsActive())
+		{
+		iTimer.Cancel();	
+		}
+	switch (iState)
+	{
+		case EUsbServiceStarting:
+			iState = EUsbServiceIdle;
+			break;
+		case EUsbServiceStopping:
+			iState = EUsbServiceStarted;
+			break;
+		default:	
+			_USB_PANIC(Kstub3CcPanicCategory, EPanicUnexpectedState);
+	}
+	*iReportStatus = KErrNone;		
+	User::RequestComplete(iReportStatus, KErrCancel);	
+	}
+
+/**
+ * Standard active object error function. Never called because this class has
+ * no asynchronous requests, and hence its RunL is never called.
+ *
+ * @param aError The error code (unused)
+ * @return Always KErrNone to avoid an active scheduler panic
+ */
+TInt CUsbstub3ClassController::RunError(TInt /*aError*/)
+	{
+	__ASSERT_DEBUG( EFalse, _USB_PANIC(Kstub3CcPanicCategory, EUnusedFunction) );
+	return KErrNone;
+	}
+
+TInt CUsbstub3ClassController::SetUpInterface()
+/**
+ * Set up the interface for use. This involves finding a "Interrupt IN" 
+ * endpoint and, if found, configuring the interface.
+ */
+	{
+	LOG_FUNC
+
+	TUsbDeviceCaps dCaps;
+	TInt ret = iLdd.DeviceCaps(dCaps);
+	LOGTEXT(_L8("\tchecking result of DeviceCaps"));
+	if ( ret )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), ret);
+		return ret;
+		}
+
+	const TUint KRequiredNumberOfEndpoints = 1; // in addition to endpoint 0.
+
+	const TUint totalEndpoints = static_cast<TUint>(dCaps().iTotalEndpoints);
+	LOGTEXT2(_L8("\tiTotalEndpoints = %d"), totalEndpoints);
+	if ( totalEndpoints < KRequiredNumberOfEndpoints )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), 
+			KErrGeneral);
+		return KErrGeneral;
+		}
+	
+	// Endpoints
+	TUsbcEndpointData data[KUsbcMaxEndpoints];
+	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
+	ret = iLdd.EndpointCaps(dataptr);
+	LOGTEXT(_L8("\tchecking result of EndpointCaps"));
+	if ( ret )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), ret);
+		return ret;
+		}
+
+	// Set the active interface
+	TUsbcInterfaceInfoBuf ifc;
+	TBool epFound = EFalse;
+	for ( TUint i = 0 ; i < totalEndpoints ; i++ )
+		{
+		const TUsbcEndpointCaps* caps = &data[i].iCaps;
+		__ASSERT_DEBUG(caps,_USB_PANIC(Kstub3CcPanicCategory, EPanicUnexpectedStatus));
+
+		if (data[i].iInUse)
+			{
+			continue;
+			}
+
+		if ((caps->iTypesAndDir & (KUsbEpTypeInterrupt | KUsbEpDirIn)) == 
+			(KUsbEpTypeInterrupt | KUsbEpDirIn))
+			{
+			// EEndpoint1 is interrupt endpoint
+			ifc().iEndpointData[0].iType  = KUsbEpTypeInterrupt;
+			ifc().iEndpointData[0].iDir   = KUsbEpDirIn; 
+
+			//get the max packet size it can potentially support
+			//it's possible that it can support Isoch (1023) which is greater
+			//than max for Int at 64
+			TInt maxSize = Min(caps->MaxPacketSize(), KMaxPacketTypeInterrupt);
+			
+			ifc().iEndpointData[0].iSize  = maxSize;
+
+			ifc().iEndpointData[0].iInterval = KPollInterval; 
+			epFound = ETrue;
+			break;
+			}
+		}
+	LOGTEXT(_L8("\tchecking epFound"));
+	if ( !epFound )
+		{
+		LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), 
+			KErrGeneral);
+		return KErrGeneral;
+		}
+
+	TName ifcName(KIfcName);
+	ifc().iString = &ifcName;
+	ifc().iTotalEndpointsUsed = KRequiredNumberOfEndpoints;
+	// Codes taken from USBCDC 1.1.
+	ifc().iClass.iClassNum	  = 0x02; // Table 15- Communication Interface Class
+	ifc().iClass.iSubClassNum = 0x02; // Table 16- Abstract Control Model
+	ifc().iClass.iProtocolNum = 0x01; // Table 17- Hayes compatible
+
+	LOGTEXT(_L8("\tabout to call SetInterface"));
+	// Zero effectively indicates that alternate interfaces are not used.
+	ret = iLdd.SetInterface(0, ifc);
+
+	LOGTEXT2(_L8("<<CCdcControlInterface::SetUpInterface ret=%d"), ret);
+	return ret;
+	}
+
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/src/Stub3CCImpCollection.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 1997-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:
+* Defines the implementation collection for the ACM class controller.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32base.h>
+#include <e32std.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include "Stub3CC.h"
+
+// Define the private interface UIDs
+const TImplementationProxy UsbCCImplementationTable[] =
+    {
+	IMPLEMENTATION_PROXY_ENTRY(0x10203289, CUsbstub3ClassController::NewL),
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(UsbCCImplementationTable) / sizeof(TImplementationProxy);
+
+    return UsbCCImplementationTable;
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 1999-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:
+*
+*/
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_TESTEXPORTS
+
+t_UsbManager.oby						/epoc32/rom/include/t_usbmanager.oby
+t_UsbManagerComponent_4.oby				/epoc32/rom/include/t_usbmanagercomponent_4.oby
+t_UsbManagerComponent_5.oby				/epoc32/rom/include/t_usbmanagercomponent_5.oby
+
+../scripts/t_usbmancomponent_1.script	z:/testdata/scripts/t_usbmancomponent_1.script
+../scripts/t_usbmancomponent_4.script	z:/testdata/scripts/t_usbmancomponent_4.script
+../scripts/t_usbmancomponent_5.script	z:/testdata/scripts/t_usbmancomponent_5.script
+../scripts/t_usbmscccomponent.script	z:/testdata/scripts/t_usbmscccomponent.script
+
+
+../scripts/t_usbmanintegration.script	z:/testdata/scripts/t_usbmanintegration.script
+../scripts/t_usbmanconnected_1.script	z:/testdata/scripts/t_usbmanconnected_1.script
+../scripts/t_usbmanconnected_2.script	z:/testdata/scripts/t_usbmanconnected_2.script
+../scripts/t_usbmanconnected_3.script	z:/testdata/scripts/t_usbmanconnected_3.script
+../scripts/t_usbmanconnected_4.script	z:/testdata/scripts/t_usbmanconnected_4.script
+../scripts/t_usbmanconnected_5.script	z:/testdata/scripts/t_usbmanconnected_5.script
+../scripts/t_usbmanconnected_6.script	z:/testdata/scripts/t_usbmanconnected_6.script
+../testdata/t_usbmanintegration.ini		z:/testdata/config/t_usbmanintegration.ini
+../testdata/t_usbmancomponent.ini		z:/testdata/config/t_usbmancomponent.ini
+../testdata/stub1cctest.ini				z:/testdata/config/stub1cctest.ini
+
+
+PRJ_TESTMMPFILES
+T_UsbManager.mmp  
+t_usbms_cable_detect.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/group/T_UsbManager.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,44 @@
+/*
+* 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:
+* SampleServer.mmp
+* Using relative paths for sourcepath and user includes
+*
+*/
+
+TARGET      t_usbmanagerserver.exe
+CAPABILITY NetworkControl CommDD
+TARGETTYPE  exe
+UID             0x1000007A 0x10203283
+
+SOURCEPATH  ../src
+SOURCE		T_UsbManagerServer.cpp
+SOURCE		CUsbTestStepBase.cpp
+SOURCE		CCancelStartInterest.cpp
+SOURCE		CCancelStopInterest.cpp
+SOURCE		CStartPersonality.cpp
+SOURCE		CStopPersonality.cpp
+SOURCE		CStartNewPersonality.cpp
+SOURCE		CSimCablePulling.cpp
+SOURCE		CStartStopPersonality.cpp
+SOURCE		CUsbComponentTest.cpp
+SOURCE		CUsbMsComponentTest.cpp
+
+USERINCLUDE   ../inc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY    	euser.lib efsrv.lib
+LIBRARY		testexecuteutils.lib
+LIBRARY		testexecutelogclient.lib
+LIBRARY		usbman.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/group/t_UsbManager.oby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+/*
+* 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:
+*
+*/
+
+#ifndef __T_USBMANGER_OBY__
+#define __T_USBMANGER_OBY__
+
+#include <testexecute.iby>
+#include <stub1cc.iby>
+#include <stub2cc.iby>
+#include <stub3cc.iby>
+#include <te_msclasscontroller.iby>
+
+file=ABI_DIR\BUILD_DIR\T_UsbManagerServer.exe		System\bin\T_UsbManagerServer.exe
+extension[VARID]=ABI_DIR\BUILD_DIR\testusbc.ldd	\system\libs\testusbc.ldd
+file=ABI_DIR\BUILD_DIR\msfs.fsy				System\libs\msfs.fsy
+
+data=ZSYSTEM\..\testdata\config\T_usbmanintegration.ini testdata\config\T_usbmanintegration.ini
+data=ZSYSTEM\..\testdata\config\T_usbmancomponent.ini testdata\config\T_usbmancomponent.ini
+data=ZSYSTEM\..\testdata\config\stub1cctest.ini testdata\config\stub1cctest.ini
+
+data=ZSYSTEM\..\testdata\scripts\t_usbmancomponent_1.script testdata\scripts\t_usbmancomponent_1.script
+data=ZSYSTEM\..\testdata\scripts\t_usbmanintegration.script testdata\scripts\t_usbmanintegration.script
+data=ZSYSTEM\..\testdata\scripts\t_usbmanconnected_1.script testdata\scripts\t_usbmanconnected_1.script
+data=ZSYSTEM\..\testdata\scripts\t_usbmanconnected_2.script testdata\scripts\t_usbmanconnected_2.script
+data=ZSYSTEM\..\testdata\scripts\t_usbmanconnected_3.script testdata\scripts\t_usbmanconnected_3.script
+data=ZSYSTEM\..\testdata\scripts\t_usbmanconnected_4.script testdata\scripts\t_usbmanconnected_4.script
+data=ZSYSTEM\..\testdata\scripts\t_usbmanconnected_5.script testdata\scripts\t_usbmanconnected_5.script
+data=ZSYSTEM\..\testdata\scripts\t_usbmanconnected_6.script testdata\scripts\t_usbmanconnected_6.script
+data=ZSYSTEM\..\testdata\scripts\t_usbmscccomponent.script  testdata\scripts\t_usbmscccomponent.script
+
+data=ZPRIVATE\101fe1db\USBMAN.R01 private\101fe1db\usbman.r01
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/group/t_UsbManagerComponent_4.oby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,35 @@
+/*
+* 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:
+*
+*/
+
+#ifndef __T_USBMANGER_OBY__
+#define __T_USBMANGER_OBY__
+
+#include <testexecute.iby>
+#include <stub1cc.iby>
+#include <stub2cc.iby>
+//this is the case 4 for stub3cc missing
+//#include <stub3cc.iby>	
+
+file=ABI_DIR\BUILD_DIR\T_UsbManagerServer.exe		System\bin\T_UsbManagerServer.exe
+
+data=ZSYSTEM\..\testdata\config\T_usbmancomponent.ini testdata\config\T_usbmancomponent.ini
+data=ZSYSTEM\..\testdata\scripts\t_usbmancomponent_4.script testdata\scripts\t_usbmancomponent_4.script
+
+
+data=ZPRIVATE\101fe1db\USBMAN.R01 private\101fe1db\usbman.r01
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/group/t_UsbManagerComponent_5.oby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+/*
+* 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:
+*
+*/
+
+#ifndef __T_USBMANGER_OBY__
+#define __T_USBMANGER_OBY__
+
+#include <testexecute.iby>
+#include <stub1cc.iby>
+#include <stub2cc.iby>
+#include <stub3cc.iby>
+
+file=ABI_DIR\BUILD_DIR\T_UsbManagerServer.exe		System\bin\T_UsbManagerServer.exe
+
+data=ZSYSTEM\..\testdata\config\T_usbmancomponent.ini testdata\config\T_usbmancomponent.ini
+data=ZSYSTEM\..\testdata\scripts\t_usbmancomponent_5.script testdata\scripts\t_usbmancomponent_5.script
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/group/t_usbms_cable_detect.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 2003-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:
+* T_USB_CABLE_DETECT.MMP
+*
+*/
+
+TARGET		t_usbms_cable_detect.exe
+TARGETTYPE	EXE
+UID		0
+VENDORID 0x70000001
+SOURCEPATH	../src
+SOURCE		t_usbms_cable_detect.cpp
+
+LIBRARY		euser.lib
+#ifndef WINS
+LIBRARY		efsrv.lib usbman.lib
+#endif
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CCancelStartInterest.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/**
+* 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 "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
+*/
+#if (!defined __CCANCELSTARTINTEREST_H__)
+#define __CCANCELSTARTINTEREST_H__
+#include <test/testexecutestepbase.h>
+#include "CUsbTestStepBase.h"
+
+_LIT(KCancelStartInterest,"CancelStartInterest");
+NONSHARABLE_CLASS(CCancelStartInterest) : public CUsbTestStepBase 
+	{
+public:
+	CCancelStartInterest();
+	virtual TVerdict doTestStepL();
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CCancelStopInterest.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/**
+* 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 "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
+*/
+#if (!defined __CCANCELSTOPINTEREST_H__)
+#define __CCANCELSTOPINTEREST_H__
+#include <test/testexecutestepbase.h>
+#include "CUsbTestStepBase.h"
+
+_LIT(KCancelStopInterest,"CancelStopInterest");
+NONSHARABLE_CLASS(CCancelStopInterest) : public CUsbTestStepBase 
+	{
+public:
+	CCancelStopInterest();
+	virtual TVerdict doTestStepL();
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CSimCablePulling.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/**
+* 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 "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
+*/
+#if (!defined __CSIMCABLEPULLING_H__)
+#define __CSIMCABLEPULLING_H__
+#include <test/testexecutestepbase.h>
+#include "CUsbTestStepBase.h"
+
+_LIT(KSimCablePulling,"SimCablePulling");
+NONSHARABLE_CLASS(CSimCablePulling) : public CUsbTestStepBase 
+	{
+public:
+	CSimCablePulling();
+	virtual TVerdict doTestStepL();
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CStartNewPersonality.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/**
+* 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 "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
+*/
+#if (!defined __CSTARTNEWPERSONALITY_H__)
+#define __CSTARTNEWPERSONALITY_H__
+#include <test/testexecutestepbase.h>
+#include "CUsbTestStepBase.h"
+
+_LIT(KStartNewPersonality,"StartNewPersonality");
+NONSHARABLE_CLASS(CStartNewPersonality) : public CUsbTestStepBase 
+	{
+public:
+	CStartNewPersonality();
+	virtual TVerdict doTestStepL();
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CStartPersonality.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/**
+* 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 "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
+*/
+#if (!defined __CSTARTPERSONALITY_H__)
+#define __CSTARTPERSONALITY_H__
+#include <test/testexecutestepbase.h>
+#include "CUsbTestStepBase.h"
+
+_LIT(KStartPersonality,"StartPersonality");
+NONSHARABLE_CLASS(CStartPersonality) : public CUsbTestStepBase 
+	{
+public:
+	CStartPersonality();
+	virtual TVerdict doTestStepL();
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CStartStopPersonality.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,49 @@
+/**
+* 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 "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
+*/
+#if (!defined __CSTARTSTOPPERSONALITY_H__)
+#define __CSTARTSTOPPERSONALITY_H__
+#include <test/testexecutestepbase.h>
+#include "CUsbTestStepBase.h"
+	
+_LIT(KStartStopPersonality1,"StartStopPersonality1");
+NONSHARABLE_CLASS(CStartStopPersonality1) : public CUsbTestStepBase 
+	{
+public:
+	CStartStopPersonality1();
+	virtual TVerdict doTestStepL();
+protected:
+	TInt TryStart(RUsb aSess1, RUsb aSess2, RUsb aSess3, TInt aRet1, TInt aRet2, TInt aRet3, TInt aPersonality1, TInt aPersonality2, TUsbServiceState aState);
+	TInt TryStop(RUsb aSess1, RUsb aSess2, RUsb aSess3, TInt aRet1, TInt aRet2, TInt aRet3);
+	};
+
+_LIT(KStartStopPersonality2,"StartStopPersonality2");
+NONSHARABLE_CLASS(CStartStopPersonality2) : public CUsbTestStepBase 
+	{
+public:
+	CStartStopPersonality2();
+	virtual TVerdict doTestStepL();
+protected:
+	TInt CheckReturnCodes(TRequestStatus& aStat1, TRequestStatus& aStat2, TInt aRet1, TInt aRet2);
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CStopPersonality.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,36 @@
+/**
+* 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 "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 
+*/
+#if (!defined __CSTOPPERSONALITY_H__)
+#define __CSTOPPERSONALITY_H__
+#include <test/testexecutestepbase.h>
+#include "CUsbTestStepBase.h"
+
+_LIT(KStopPersonality,"StopPersonality");
+NONSHARABLE_CLASS(CStopPersonality) : public CUsbTestStepBase 
+	{
+public:
+	CStopPersonality();
+	virtual TVerdict doTestStepL();
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CUsbComponentTest.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,115 @@
+/**
+* Copyright (c) 1997-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 
+*/
+
+#include <test/testexecutestepbase.h>
+#include <usbman.h>
+#include "T_UsbManagerServer.h"
+#include "CUsbTestStepBase.h"
+
+NONSHARABLE_CLASS(CUsbComponentTest) :public CUsbTestStepBase
+{
+public:
+	virtual TVerdict CompareUsbPersonalityL();
+	
+};
+
+_LIT(KUsbLoadPersonalityNormal,"CUsbLoadPersonalityNormal");
+NONSHARABLE_CLASS(CUsbLoadPersonalityNormal) : public CUsbComponentTest
+	{
+public:
+	CUsbLoadPersonalityNormal();
+	virtual TVerdict doTestStepL();
+	};
+
+_LIT(KUsbLoadPersonalityAbNormal,"CUsbLoadPersonalityAbNormal");
+NONSHARABLE_CLASS(CUsbLoadPersonalityAbNormal) : public CUsbComponentTest
+	{
+public:
+	CUsbLoadPersonalityAbNormal();
+	virtual TVerdict doTestStepL();
+	};
+	
+_LIT(KUsbLoadPersonalityMissing,"CUsbLoadPersonalityMissing");
+NONSHARABLE_CLASS(CUsbLoadPersonalityMissing) : public CUsbComponentTest
+	{
+public:
+	CUsbLoadPersonalityMissing();
+	virtual TVerdict doTestStepL();
+	};
+	
+_LIT(KUsbTestOOM,"CUsbTestOOM");
+NONSHARABLE_CLASS(CUsbTestOOM) : public CUsbComponentTest
+	{
+public:
+	CUsbTestOOM();
+	virtual TVerdict doTestStepL();
+	};
+
+_LIT(KUsbSwitchPersonalityNormal,"CUsbSwitchPersonalityNormal");
+NONSHARABLE_CLASS(CUsbSwitchPersonalityNormal) : public CUsbComponentTest
+	{
+public:
+	CUsbSwitchPersonalityNormal();
+	virtual TVerdict doTestStepL();
+	};
+
+_LIT(KUsbSwitchPersonalityAbNormal,"CUsbSwitchPersonalityAbNormal");
+NONSHARABLE_CLASS(CUsbSwitchPersonalityAbNormal) : public CUsbComponentTest
+	{
+public:
+	CUsbSwitchPersonalityAbNormal();
+	virtual TVerdict doTestStepL();
+	};
+	
+_LIT(KUsbStartStopPersonality1,"CUsbStartStopPersonality1");
+NONSHARABLE_CLASS(CUsbStartStopPersonality1) : public CUsbComponentTest
+	{
+public:
+	CUsbStartStopPersonality1();
+	virtual TVerdict doTestStepL();
+	};
+
+_LIT(KUsbStartStopPersonality2,"CUsbStartStopPersonality2");
+NONSHARABLE_CLASS(CUsbStartStopPersonality2) : public CUsbComponentTest
+	{
+public:
+	CUsbStartStopPersonality2();
+	virtual TVerdict doTestStepL();
+	};
+	
+_LIT(KUsbStartStopPersonality3,"CUsbStartStopPersonality3");
+NONSHARABLE_CLASS(CUsbStartStopPersonality3) : public CUsbComponentTest
+	{
+public:
+	CUsbStartStopPersonality3();
+	virtual TVerdict doTestStepL();
+	};
+
+_LIT(KMemAllocationFailure,"CMemAllocationFailure");
+NONSHARABLE_CLASS(CMemAllocationFailure) : public CUsbComponentTest
+	{
+public:
+	CMemAllocationFailure();
+	virtual TVerdict doTestStepL();
+	};
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CUsbMsComponentTest.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,51 @@
+/**
+* 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 "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 
+*/
+
+#include <test/testexecutestepbase.h>
+#include <usbman.h>
+#include "T_UsbManagerServer.h"
+#include "CUsbTestStepBase.h"
+
+NONSHARABLE_CLASS(CUsbMsComponentTest) :public CUsbTestStepBase
+{
+public:
+	virtual TVerdict CompareUsbPersonalityL();
+	
+};
+
+_LIT(KUsbMsccGetPersonality,"CUsbMsccGetPersonality");
+NONSHARABLE_CLASS(CUsbMsccGetPersonality) : public CUsbMsComponentTest
+	{
+public:
+	CUsbMsccGetPersonality();
+	virtual TVerdict doTestStepL();
+	};
+
+_LIT(KUsbMsccStartStop,"CUsbMsccStartStop");
+NONSHARABLE_CLASS(CUsbMsccStartStop) : public CUsbMsComponentTest
+	{
+public:
+	CUsbMsccStartStop();
+	virtual TVerdict doTestStepL();
+	};
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/CUsbTestStepBase.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,49 @@
+/**
+* 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 "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
+*/
+#if (!defined __CUSBTESTSTEPBASE_H__)
+#define __CUSBTESTSTEPBASE_H__
+#include <test/testexecutestepbase.h>
+#include <usbman.h>
+#include "T_UsbManagerServer.h"
+
+NONSHARABLE_CLASS(CUsbTestStepBase) : public CTestStep
+	{
+public:
+	CUsbTestStepBase();
+	virtual TVerdict doTestStepPreambleL();
+	virtual TVerdict doTestStepPostambleL();
+protected:
+	RUsb iUsb;
+	TBool iDoNotConnect;
+	TBool iConnected;
+	TBool iStopService;
+
+protected:
+	TInt CheckState(RUsb sess, TUsbServiceState aState);
+	TInt SetIdle(RUsb sess);
+	TInt SetStarted(RUsb sess);
+	TInt SetStarting(RUsb sess);
+	TInt SetStopping(RUsb sess);
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/inc/T_UsbManagerServer.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,38 @@
+/**
+* Copyright (c) 1997-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 
+*/
+// __EDIT_ME__ Create your own class definition based on this
+#if (!defined __USB_MANAGER_SERVER_H__)
+#define __USB_MANAGER_SERVER_H__
+#include <test/testexecuteserverbase.h>
+
+NONSHARABLE_CLASS(CUsbManagerServer) : public CTestServer
+	{
+public:
+	static CUsbManagerServer* NewL();
+	virtual CTestStep* CreateTestStep(const TDesC& aStepName);
+	RFs& Fs(){return iFs;};
+
+private:
+	RFs iFs;
+	};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmancomponent_1.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,163 @@
+// Copyright (c) 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:
+// USBSRV   Component tests
+
+LOAD_SUITE T_UsbManagerServer
+
+RUN_UTILS MkDir C:\testdata\
+RUN_UTILS MkDir C:\testdata\config\
+RUN_UTILS CopyFile Z:\testdata\config\stub2cc.ini C:\testdata\config\stub2cc.ini
+RUN_UTILS MakeReadWrite C:\testdata\config\stub2cc.ini
+RUN_UTILS MkDir c:\private\
+RUN_UTILS MkDir c:\private\101fe1db\
+RUN_UTILS CopyFile Z:\private\101fe1db\usbman.r01 c:\private\101fe1db\usbman.r01
+RUN_UTILS MakeReadWrite c:\private\101fe1db\usbman.r01
+// Delay 3 seconds for RUN_UTILS to complete
+DELAY 3000
+
+//! @SYMTestCaseID T_LoadPersonalitiesListNormal
+//! @SYMTestType CT
+//! @SYMTestCaseDesc Test Normal Case for startup USB Server and loading of personality list
+//! @SYMFssID USB/DynamicClassChange/1
+//! @SYMFssID USB/DynamicClassChange/1.3.1
+//! @SYMFssID USB/DynamicClassChange/1.1.1
+//! @SYMFssID USB/DynamicClassChange/1.2.2
+//! @SYMFssID USB/DynamicClassChange/1.2.3
+//! @SYMFssID USB/DynamicClassChange/1.2.3.1
+//! @SYMFssID USB/DynamicClassChange/1.2.5
+//! @SYMTestActions Create a new session with CUsbServer. It's cause creation of new 
+//! CUsbDevice object wich read personality list from resource file and validate them.
+//! @SYMTestExpectedResults The personality IDs requested from CUsbDevice should be equal to expected. 
+//! Each personality should have expected textual description and UID list of supported CCs  
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+START_TESTCASE T_LoadPersonalitiesListNormal
+RUN_TEST_STEP 100 T_UsbManagerServer CUsbLoadPersonalityNormal z:\testdata\config\t_usbmancomponent.ini UsbLoadPersonalityNormal
+END_TESTCASE T_LoadPersonalitiesListNormal
+
+//! @SYMTestCaseID T_LoadPersonalitiesListOOM
+//! @SYMTestType CT
+//! @SYMTestCaseDesc Test startup USB Server and loading of personality list in OOM conditions
+//! @SYMFssID USB/DynamicClassChange/1
+//! @SYMFssID USB/DynamicClassChange/1.3.1
+//! @SYMFssID USB/DynamicClassChange/1.1.1
+//! @SYMFssID USB/DynamicClassChange/1.2.3
+//! @SYMFssID USB/DynamicClassChange/1.2.5
+//! @SYMTestActions Try to create a new session with CUsbServer in OOM conditions. It's cause creation of new 
+//! CUsbDevice object which read personality list from recourse file and validate them.
+//! @SYMTestExpectedResults Until OOM condition is present RUsb::Conect() method  should fail with KErrNoMemory. 
+//! After removing OOM conditions the personality IDs requested from CUsbDevice should equal to expected. 
+//! Each personality should have expected textual description and list of supported CCs 
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+START_TESTCASE T_LoadPersonalitiesListOOM
+RUN_TEST_STEP 100 T_UsbManagerServer CUsbTestOOM z:\testdata\config\t_usbmancomponent.ini UsbTestOOM 
+END_TESTCASE T_LoadPersonalitiesListOOM 
+
+//! @SYMTestCaseID T_SwitchPersonalityNormal
+//! @SYMTestType CT
+//! @SYMTestCaseDesc Test personality switching
+//! @SYMFssID USB/DynamicClassChange/1
+//! @SYMFssID USB/DynamicClassChange/1.2.1
+//! @SYMFssID USB/DynamicClassChange/1.2.4
+//! @SYMFssID USB/DynamicClassChange/1.2.5
+//! @SYMTestActions Create a new session with CUsbServer. Compare ID, PID, VID, CC UIDs and description of current personality with expected data. Switch personality and check parameters again.
+//! @SYMTestExpectedResults All gotten parameters should match with expected data. 
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+START_TESTCASE T_SwitchPersonalityNormal
+RUN_TEST_STEP 100 T_UsbManagerServer CUsbSwitchPersonalityNormal z:\testdata\config\t_usbmancomponent.ini UsbSwitchPersonalityNormal 
+END_TESTCASE T_SwitchPersonalityNormal  
+
+//! @SYMTestCaseID T_StartStopPersonality1
+//! @SYMTestType CT
+//! @SYMTestCaseDesc Test start/stop personality with normal CCs and then with failed to start CC
+//! @SYMFssID USB/DynamicClassChange/1
+//! @SYMFssID USB/DynamicClassChange/1.3.3
+//! @SYMFssID USB/DynamicClassChange/1.4.2
+//! @SYMTestActions Create a new session with USB server, Issue TryStart request, try to change personality then TryStop. Switch to personality wich has "failure" stub CC.
+//! Try to start this personality
+//! @SYMTestExpectedResults The first TryStart request should be completed successfully.
+//! The attempt to switch personality should fail. The second TryStart request should return error code signaling about problem with starting CC.
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+START_TESTCASE T_StartStopPersonality1
+RUN_UTILS DeleteFile C:\testdata\config\stub1cc.ini
+RUN_UTILS CopyFile Z:\testdata\config\stub1cctest.ini C:\testdata\config\stub1cc.ini
+RUN_UTILS MakeReadWrite C:\testdata\config\stub1cc.ini
+DELAY 1000
+RUN_TEST_STEP 100 T_UsbManagerServer CUsbStartStopPersonality1 z:\testdata\config\t_usbmancomponent.ini UsbStartStopPersonality1
+RUN_UTILS DeleteFile C:\testdata\config\stub1cc.ini
+DELAY 1000
+END_TESTCASE T_StartStopPersonality1
+
+//! @SYMTestCaseID T_StartStopPersonality2
+//! @SYMTestType CT
+//! @SYMTestCaseDesc Test start/stop personality at different USB server's states using TryStart/TryStop methods
+//! @SYMFssID USB/DynamicClassChange/1
+//! @SYMFssID USB/DynamicClassChange/1.3.3
+//! @SYMFssID USB/DynamicClassChange/1.4.2
+//! @SYMTestActions Create a new session with USB server, Issue TryStart and TryStop requests at all possible server's states.
+//! @SYMTestExpectedResults The requests should be succeeded or failed according to the "State Transition Diagram" chapter from 
+//! the "USB Design Document for PREQ 543"
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+START_TESTCASE T_StartStopPersonality2
+RUN_TEST_STEP 100 T_UsbManagerServer CUsbStartStopPersonality2 z:\testdata\config\t_usbmancomponent.ini UsbStartStopPersonality2 
+END_TESTCASE T_StartStopPersonality2 
+
+//! @SYMTestCaseID T_StartStopPersonality3
+//! @SYMTestType CT
+//! @SYMTestCaseDesc Test start/stop personality at different USB server's states using Start/Stop methods
+//! @SYMFssID USB/DynamicClassChange/1
+//! @SYMFssID USB/DynamicClassChange/1.3.2
+//! @SYMFssID USB/DynamicClassChange/1.4.1
+//! @SYMTestActions Create a new session with USB server, Issue Start and Stop requests at all possible server's states and check state of the USB server.
+//! @SYMTestExpectedResults The requests should be succeeded, a finale state of USB manager after each request should be as requested. 
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+START_TESTCASE T_StartStopPersonality3
+RUN_TEST_STEP 100 T_UsbManagerServer CUsbStartStopPersonality3 z:\testdata\config\t_usbmancomponent.ini UsbStartStopPersonality3 
+END_TESTCASE T_StartStopPersonality3  
+
+
+//! @SYMTestCaseID T_SwitchPersonalityAbNormal
+//! @SYMTestType CT
+//! @SYMTestCaseDesc Test personality switching
+//! @SYMFssID USB/DynamicClassChange/1
+//! @SYMFssID USB/DynamicClassChange/1.2.1
+//! @SYMFssID USB/DynamicClassChange/1.2.4
+//! @SYMFssID USB/DynamicClassChange/1.2.5
+//! @SYMTestActions Create a new session with CUsbServer. Compare ID, PID, VID, CC UIDs and description of current personality with expected data. Switch personality and check parameters again.
+//! @SYMTestExpectedResults All gotten parameters should match with expected data. 
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+START_TESTCASE T_SwitchPersonalityAbNormal
+RUN_TEST_STEP 100 T_UsbManagerServer CUsbSwitchPersonalityAbNormal z:\testdata\config\t_usbmancomponent.ini UsbSwitchPersonalityAbNormal 
+END_TESTCASE T_SwitchPersonalityAbNormal  
+
+
+//! @SYMTestCaseID T_MemoryAllocationFailure
+//! @SYMTestType CT
+//! @SYMTestCaseDesc Test handling of memory allocation failure
+//! @SYMFssID USB/DynamicClassChange/1
+//! @SYMFssID USB/DynamicClassChange/1.3.1
+//! @SYMTestActions Create a session with  CUsbServer. Call __UHEAP_FAILNEXT(1) and then call APIs
+//! that requirement memory allocation. 
+//! @SYMTestExpectedResults all calls should return KErrNoMemory
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+START_TESTCASE T_MemoryAllocationFailure
+RUN_TEST_STEP 100 T_UsbManagerServer CMemAllocationFailure
+END_TESTCASE T_MemoryAllocationFailure
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmancomponent_4.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,45 @@
+// Copyright (c) 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:
+//
+
+
+//USBSRV
+//Component tests
+LOAD_SUITE T_UsbManagerServer
+
+RUN_UTILS MkDir C:\testdata\
+RUN_UTILS MkDir C:\testdata\config\
+RUN_UTILS CopyFile Z:\testdata\config\stub1cc.ini C:\testdata\config\stub1cc.ini
+RUN_UTILS CopyFile Z:\testdata\config\stub2cc.ini C:\testdata\config\stub2cc.ini
+RUN_UTILS CopyFile Z:\testdata\config\stub3cc.ini C:\testdata\config\stub3cc.ini
+RUN_UTILS MkDir c:\private\
+RUN_UTILS MkDir c:\private\101fe1db\
+RUN_UTILS CopyFile Z:\private\101fe1db\usbman.r01 c:\private\101fe1db\usbman.r01
+// Delay 3 seconds for RUN_UTILS to complete
+DELAY 3000
+
+//! @SYMTestCaseID T_LoadPersonalitiesMissingCC
+//! @SYMTestType CT
+//! @SYMTestCaseDesc Test startup USB Server and loading of personality list when one of CC from this list isn't present.
+//! @SYMFssID USB/DynamicClassChange/1
+//! @SYMFssID USB/DynamicClassChange/1.3.1
+//! @SYMTestActions Create a new session with CUsbServer. It's cause creation of new 
+//! CUsbDevice object which read personality list and then validate these personalities .
+//! @SYMTestExpectedResults RUsb::Conect() method should fail with expected errcode due to failure of personality validation
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+START_TESTCASE T_LoadPersonalitiesMissingCC
+RUN_TEST_STEP 100 T_UsbManagerServer CUsbLoadPersonalityAbNormal
+END_TESTCASE T_LoadPersonalitiesMissingCC
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmancomponent_5.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,47 @@
+// Copyright (c) 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:
+//
+
+//USBSRV
+//Component tests
+LOAD_SUITE T_UsbManagerServer
+
+RUN_UTILS MkDir C:\testdata\
+RUN_UTILS MkDir C:\testdata\config\
+RUN_UTILS CopyFile Z:\testdata\config\stub1cc.ini C:\testdata\config\stub1cc.ini
+RUN_UTILS CopyFile Z:\testdata\config\stub2cc.ini C:\testdata\config\stub2cc.ini
+RUN_UTILS CopyFile Z:\testdata\config\stub3cc.ini C:\testdata\config\stub3cc.ini
+RUN_UTILS MkDir c:\private\
+RUN_UTILS MkDir c:\private\101fe1db\
+// remove resource file if it remain here from previous tests
+RUN_UTILS MakeReadWrite c:\private\101fe1db\usbman.r01
+RUN_UTILS run_utils delete c:\private\101fe1db\*.*
+
+// Delay 3 seconds for RUN_UTILS to complete
+DELAY 3000
+
+//! @SYMTestCaseID T_LoadPersonalitiesmissingFile
+//! @SYMTestType CT
+//! @SYMTestCaseDesc Test startup USB Server and loading of personality list from missing r01 file.
+//! @SYMFssID USB/DynamicClassChange/1
+//! @SYMFssID USB/DynamicClassChange/1.3.1
+//! @SYMTestActions Create a session with  CUsbServer. It's cause creation of new 
+//! CUsbDevice object which try to read personality list from default RSC file when missing r01 file.
+//! @SYMTestExpectedResults RUsb::Conect() and start() method  should successful with RSC file
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+START_TESTCASE T_LoadPersonalitiesmissingFile
+RUN_TEST_STEP 100 T_UsbManagerServer CUsbLoadPersonalityMissing z:\testdata\config\t_usbmancomponent.ini UsbLoadPersonalityMissing
+END_TESTCASE T_LoadPersonalitiesmissingFile
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanconnected_1.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,32 @@
+// Copyright (c) 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:
+//
+
+// Integration tests which demand USB connection with host PC
+
+LOAD_SUITE T_UsbManagerServer
+
+//! @SYMTestCaseID T_StartPersonalityIC1
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Test start current personality 
+//! @SYMFssID USB/DynamicClassChange/1.3.3
+//! @SYMFssID USB/DynamicClassChange/1.4.2
+//! @SYMTestActions Create  session with USB server, Issue TryStart request for current personality wait for completion. Close session
+//! @SYMTestExpectedResults The request should be succeeded then software on Host PC can check if this personality is visible from the host side
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+
+START_TESTCASE T_StartPersonalityIC1
+RUN_TEST_STEP -1 T_UsbManagerServer StartPersonality
+END_TESTCASE T_StartPersonalityIC1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanconnected_2.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+// Copyright (c) 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:
+//
+
+LOAD_SUITE T_UsbManagerServer
+
+//! @SYMTestCaseID T_StopPersonalityIC1
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Test stop current personality 
+//! @SYMFssID USB/DynamicClassChange/1.3.3
+//! @SYMFssID USB/DynamicClassChange/1.4.2
+//! @SYMTestActions Create session with USB server, Issue TryStop request for current personality wait for completion
+//! @SYMTestExpectedResults The request should be succeeded then software on Host PC can check if this personality now unavailable from the host side
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+
+START_TESTCASE T_StopPersonalityIC1
+RUN_TEST_STEP -1 T_UsbManagerServer StopPersonality
+END_TESTCASE T_StopPersonalityIC1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanconnected_3.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+// Copyright (c) 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:
+//
+
+LOAD_SUITE T_UsbManagerServer
+
+//! @SYMTestCaseID T_StartNewPersonalityIC1
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Test start new personality 
+//! @SYMFssID USB/DynamicClassChange/1.3.3
+//! @SYMFssID USB/DynamicClassChange/1.4.2
+//! @SYMTestActions Create  session with USB server, check server status if it's running - stop it. Switch to personality defined in INI file. Issue TryStart requests and wait for completion. Close session
+//! @SYMTestExpectedResults The requests should be succeeded, then software on Host PC can check if new personality is visible from the host side
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+
+START_TESTCASE T_StartNewPersonalityIC1
+RUN_TEST_STEP -1 T_UsbManagerServer StartNewPersonality z:\testdata\config\t_usbmanintegration.ini T_StartNewPersonality1
+END_TESTCASE T_StartNewPersonalityIC1
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanconnected_4.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+// Copyright (c) 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:
+//
+
+LOAD_SUITE T_UsbManagerServer
+
+//! @SYMTestCaseID T_StartNewPersonalityIC2
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Test start new personality 
+//! @SYMFssID USB/DynamicClassChange/1.3.3
+//! @SYMFssID USB/DynamicClassChange/1.4.2
+//! @SYMTestActions Create  session with USB server, check server status if it's running - stop it. Switch to personality defined in INI file. Issue TryStart requests and wait for completion. Close session
+//! @SYMTestExpectedResults The requests should be succeeded, then software on Host PC can check if new personality is visible from the host side
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+
+START_TESTCASE T_StartNewPersonalityIC2
+RUN_TEST_STEP -1 T_UsbManagerServer StartNewPersonality z:\testdata\config\t_usbmanintegration.ini T_StartNewPersonality2
+END_TESTCASE T_StartNewPersonalityIC2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanconnected_5.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+// Copyright (c) 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:
+//
+
+LOAD_SUITE T_UsbManagerServer
+
+//! @SYMTestCaseID T_CablePulling1
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Test cable pulling during personality switching 
+//! @SYMFssID USB/DynamicClassChange/1.3.3
+//! @SYMTestActions Create session with USB server. Start personality defined at INI file and then simulate cable pull-of.
+//! After defined period of time simulate cable pull-on. Wait time is shorter than stub cc start time.
+//! @SYMTestExpectedResults The host PC should read personality data (PID,VID etc) correctly
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+
+START_TESTCASE T_CablePulling1
+RUN_TEST_STEP -1 T_UsbManagerServer SimCablePulling z:\testdata\config\t_usbmanintegration.ini T_CablePulling1
+END_TESTCASE T_CablePulling1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanconnected_6.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+// Copyright (c) 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:
+//
+
+LOAD_SUITE T_UsbManagerServer
+
+//! @SYMTestCaseID T_CablePulling2
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Test cable pulling during personality switching 
+//! @SYMFssID USB/DynamicClassChange/1.3.3
+//! @SYMTestActions Create session with USB server. Start personality defined at INI file and then simulate cable pull-of.
+//! After defined period of time simulate cable pull-on. Wait time is longer than stub cc start time.
+//! @SYMTestExpectedResults The host PC should read personality data (PID,VID etc) correctly
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+
+START_TESTCASE T_CablePulling2
+RUN_TEST_STEP -1 T_UsbManagerServer SimCablePulling z:\testdata\config\t_usbmanintegration.ini T_CablePulling2
+END_TESTCASE T_CablePulling2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmanintegration.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,89 @@
+// Copyright (c) 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:
+//
+
+//Integration tests wich can be run on emulator.
+
+LOAD_SUITE T_UsbManagerServer
+
+RUN_UTILS MkDir C:\testdata\
+RUN_UTILS MkDir C:\testdata\config\
+RUN_UTILS CopyFile Z:\testdata\config\stub1cc.ini C:\testdata\config\stub1cc.ini
+RUN_UTILS CopyFile Z:\testdata\config\stub2cc.ini C:\testdata\config\stub2cc.ini
+RUN_UTILS CopyFile Z:\testdata\config\stub3cc.ini C:\testdata\config\stub3cc.ini
+RUN_UTILS MkDir c:\private\
+RUN_UTILS MkDir c:\private\101fe1db\
+RUN_UTILS CopyFile Z:\private\101fe1db\usbman.r01 c:\private\101fe1db\usbman.r01
+// Delay 3 seconds for RUN_UTILS to complete
+DELAY 3000
+
+//! @SYMTestCaseID T_CancelInterest1
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Test CancelInterest request
+//! @SYMFssID USB/DynamicClassChange/1.5.1
+//! @SYMTestActions Create session with USB server, Issue TryStart request and then immediatly CancelInterest. Check the state of the USB server until it started.
+//! Repeat previous step for Start request
+//! @SYMTestExpectedResults The outstanding request should be completed immediately after CancelInterest, but USB server should continue to transition to "Start" state.
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+
+START_TESTCASE T_CancelInterest1
+RUN_TEST_STEP 90 T_UsbManagerServer CancelStartInterest z:\testdata\config\t_usbmanintegration.ini T_CancelInterest
+END_TESTCASE T_CancelInterest1
+
+//! @SYMTestCaseID T_CancelInterest2
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Test CancelInterest request
+//! @SYMFssID USB/DynamicClassChange/1.5.1
+//! @SYMTestActions Create session with USB server, Issue TryStart wait for completion,
+//! then issue TryStop request and immediately CancelInterest. Check the state of the USB server until it stopped.
+//! Repeat previous step for Stop request
+//! @SYMTestExpectedResults The outstanding request should be completed immediately after CancelInterest, but USB server should continue to transition to "Stop" state.
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+
+START_TESTCASE T_CancelInterest2
+RUN_TEST_STEP 90 T_UsbManagerServer CancelStopInterest z:\testdata\config\t_usbmanintegration.ini T_CancelInterest
+END_TESTCASE T_CancelInterest2
+
+//! @SYMTestCaseID T_StartStopPersonalityI1
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Test start/stop personality at different USB server's states
+//! @SYMFssID USB/DynamicClassChange/1.3.3
+//! @SYMFssID USB/DynamicClassChange/1.4.2
+//! @SYMTestActions Create 3 sessions with USB server, Issue TryStart and TryStop requests simultanestly from 3 clients  at all possible server's states.
+//! @SYMTestExpectedResults The requests should be succeeded or failed according to the "State Transition Diagram" chapter from 
+//! the "USB Design Document for PREQ 543"
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+
+START_TESTCASE T_StartStopPersonalityI1
+RUN_TEST_STEP 90 T_UsbManagerServer StartStopPersonality1 z:\testdata\config\t_usbmanintegration.ini T_StartStopPersonality
+END_TESTCASE T_StartStopPersonalityI1
+
+//! @SYMTestCaseID T_StartStopPersonalityI2
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Test start/stop personality at different USB server's states
+//! @SYMFssID USB/DynamicClassChange/1.3.3
+//! @SYMFssID USB/DynamicClassChange/1.4.2
+//! @SYMTestActions Create 2 sessions with USB server, Issue TryStart and TryStop requests from one client and start/stop request from another simultaneously at all possible server's states.
+//! @SYMTestExpectedResults The requests should be succeeded or failed according to the "State Transition Diagram" chapter from 
+//! the "USB Design Document for PREQ 543"
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+
+START_TESTCASE T_StartStopPersonalityI2
+RUN_TEST_STEP 300 T_UsbManagerServer StartStopPersonality2 z:\testdata\config\t_usbmanintegration.ini T_StartStopPersonality
+END_TESTCASE T_StartStopPersonalityI2
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/scripts/t_usbmscccomponent.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,51 @@
+// Copyright (c) 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:
+//
+
+// USB mass storage class controller
+// Component tests
+
+LOAD_SUITE T_UsbManagerServer
+
+RUN_UTILS MkDir C:\testdata\
+RUN_UTILS MkDir C:\testdata\config\
+
+RUN_UTILS MkDir c:\private\
+RUN_UTILS MkDir c:\private\101fe1db\
+RUN_UTILS CopyFile Z:\private\101fe1db\usbman.r01 c:\private\101fe1db\usbman.r01
+RUN_UTILS MakeReadWrite c:\private\101fe1db\usbman.r01
+
+// Delay 3 seconds for RUN_UTILS to complete
+DELAY 1000
+
+//! @SYMTestCaseID T_UsbMsccStartStop
+//! @SYMTestType CT
+//! @SYMTestCaseDesc Test Normal Case for startup USB Server and loading of personality list
+//! @SYMFssID USB/DynamicClassChange/1
+//! @SYMFssID USB/DynamicClassChange/1.3.1
+//! @SYMFssID USB/DynamicClassChange/1.1.1
+//! @SYMFssID USB/DynamicClassChange/1.2.2
+//! @SYMFssID USB/DynamicClassChange/1.2.3
+//! @SYMFssID USB/DynamicClassChange/1.2.3.1
+//! @SYMFssID USB/DynamicClassChange/1.2.5
+//! @SYMTestActions Create a new session with CUsbServer. It's cause creation of new 
+//! CUsbDevice object wich read personality list from resource file and validate them.
+//! @SYMTestExpectedResults The personality IDs requested from CUsbDevice should be equal to expected. 
+//! Each personality should have expected textual description and UID list of supported CCs  
+//! @SYMTestPriority Low
+//! @SYMTestStatus Defined
+START_TESTCASE T_UsbMsccStartStop
+RUN_TEST_STEP 100 T_UsbManagerServer CUsbMsccStartStop
+END_TESTCASE T_UsbMsccStartStop
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CCancelStartInterest.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,116 @@
+/*
+* 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 "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
+*/
+#include <test/testexecutelog.h>
+#include "CUsbTestStepBase.h"
+#include "CCancelStartInterest.h"
+
+CCancelStartInterest::CCancelStartInterest()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KCancelStartInterest);
+	}
+
+TVerdict CCancelStartInterest::doTestStepL()
+	{
+	SetTestStepResult(EFail);
+	TInt err;
+	err = SetIdle(iUsb);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("Can't stop USB service: %s"), err);
+		return TestStepResult();
+		}
+		
+	//Read personality from ini file
+	TInt personality;
+	_LIT(KPersonality, "personality"); 
+	if (!GetIntFromConfig(ConfigSection(), KPersonality, personality))
+		{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		return TestStepResult();
+		}
+	//Read timeout from ini file
+	TInt timeout;
+	_LIT(KTimeout, "timeout"); 
+	if (!GetIntFromConfig(ConfigSection(), KTimeout, timeout))
+		{
+		INFO_PRINTF1(_L("Can't get timeout from config file"));
+		return TestStepResult();
+		}
+	
+	//TryStart and then cancel interest.
+	TRequestStatus status;
+	iUsb.TryStart(personality, status);
+	iUsb.CancelInterest(RUsb::ETryStart);
+	User::WaitForRequest(status);
+	if (status != KErrNone)
+		{
+		INFO_PRINTF2(_L("Bad error code after CancelInterest(EUsbTryStart): %d"), status.Int());
+		return TestStepResult();
+		}
+	//Make sure state is still starting
+	TUsbServiceState state;
+	err = iUsb.GetServiceState(state);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("GetServiceState returned error code %d"), err);
+		return TestStepResult();
+		}
+	else if (state != EUsbServiceStarting)
+		{
+		INFO_PRINTF2(_L("Bad service state after CancelInterest(EUsbTryStart): %d"), state);
+		return TestStepResult();
+		}
+	
+	
+	//The Usb service should start even after CancelInterest.
+	//The timeout value from the config file is used so that we don't wait forever.
+	for (;;)
+		{
+		err = iUsb.GetServiceState(state);
+		if (err != KErrNone)
+			{
+			INFO_PRINTF2(_L("GetServiceState returned error code %d"), err);
+			break;
+			}
+		else if (state == EUsbServiceStarted)
+			{
+			SetTestStepResult(EPass);
+			break;
+			}
+		else if (state == EUsbServiceFatalError)
+			{
+			INFO_PRINTF1(_L("Service state is EUsbServiceFatalError"));
+			break;
+			}
+		else if (timeout == 0)
+			{
+			INFO_PRINTF1(_L("Timeout waiting for service to start"));
+			break;
+			}
+		User::After(1000000);
+		timeout--;
+		}
+
+	return TestStepResult();
+	}
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CCancelStopInterest.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,125 @@
+/*
+* 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 "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
+*/
+#include <test/testexecutelog.h>
+#include "CUsbTestStepBase.h"
+#include "CCancelStopInterest.h"
+
+CCancelStopInterest::CCancelStopInterest()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KCancelStopInterest);
+	}
+
+TVerdict CCancelStopInterest::doTestStepL()
+	{
+	SetTestStepResult(EFail);
+	TInt err;
+	err = SetIdle(iUsb);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("Can't stop USB service: %s"), err);
+		return TestStepResult();
+		}
+	
+	//Read personality from ini file
+	TInt personality;
+	_LIT(KPersonality, "personality"); 
+	if (!GetIntFromConfig(ConfigSection(), KPersonality, personality))
+		{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		return TestStepResult();
+		}
+	//Read timeout from ini file
+	TInt timeout;
+	_LIT(KTimeout, "timeout"); 
+	if (!GetIntFromConfig(ConfigSection(), KTimeout, timeout))
+		{
+		INFO_PRINTF1(_L("Can't get timeout from config file"));
+		return TestStepResult();
+		}
+	
+	//TryStart and wait for service to start
+	TRequestStatus status;
+	iUsb.TryStart(personality, status);
+	User::WaitForRequest(status);
+	
+	if (status != KErrNone)
+		{
+		INFO_PRINTF2(_L("TryStart finished with error code %d"), status.Int());
+		return TestStepResult();
+		}
+		
+	//TryStop and immidiately CancelInterest
+	iUsb.TryStop(status);
+	iUsb.CancelInterest(RUsb::ETryStop);
+	User::WaitForRequest(status);
+	if (status != KErrNone)
+		{
+		INFO_PRINTF2(_L("Bad error code after CancelInterest(EUsbTryStop): %d"), status.Int());
+		return TestStepResult();
+		}
+	//Make sure state is still stopping
+	TUsbServiceState state;
+	err = iUsb.GetServiceState(state);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("GetServiceState returned error code %d"), err);
+		return TestStepResult();
+		}
+	else if (state != EUsbServiceStopping)
+		{
+		INFO_PRINTF2(_L("Bad service state after CancelInterest(EUsbTryStop): %d"), state);
+		return TestStepResult();
+		}
+	
+	//The Usb service should stop even after CancelInterest.
+	//The timeout value from the config file is used so that we don't wait forever.
+	for (;;)
+		{
+		err = iUsb.GetServiceState(state);
+		if (err != KErrNone)
+			{
+			INFO_PRINTF2(_L("GetServiceState returned error code %d"), err);
+			break;
+			}
+		else if (state == EUsbServiceIdle)
+			{
+			SetTestStepResult(EPass);
+			break;
+			}
+		else if (state == EUsbServiceFatalError)
+			{
+			INFO_PRINTF1(_L("Service state is EUsbServiceFatalError"));
+			break;
+			}
+		else if (timeout == 0)
+			{
+			INFO_PRINTF1(_L("Timeout waiting for service to start"));
+			break;
+			}
+		User::After(1000000);
+		timeout--;
+		}
+
+	return TestStepResult();
+	}
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CSimCablePulling.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,115 @@
+/*
+* 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 "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
+*/
+#include <test/testexecutelog.h>
+#include <d32usbc.h>
+#include "CUsbTestStepBase.h"
+#include "CSimCablePulling.h"
+
+CSimCablePulling::CSimCablePulling()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KSimCablePulling);
+	//We need the service to continue running after the test so that usbcheck
+	//can find the device connected to the PC.
+	iStopService = EFalse;
+	}
+
+/*
+ This test simulates pulling and plugging of the usb cable while the service is starting.
+ The device is actually connected to a host PC which checks the correct personality is loaded
+ when the cable is plugged back in.
+*/
+TVerdict CSimCablePulling::doTestStepL()
+	{
+	SetTestStepResult(EFail);
+	//Read personality from ini file
+	TInt personality;
+	_LIT(KPersonality, "personality"); 
+	if (!GetIntFromConfig(ConfigSection(), KPersonality, personality))
+		{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		return TestStepResult();
+		}
+	//Read waiting time from ini file
+	TInt wait;
+	_LIT(KWait, "wait"); 
+	if (!GetIntFromConfig(ConfigSection(), KWait, wait))
+		{
+		INFO_PRINTF1(_L("Can't get waiting time from config file"));
+		return TestStepResult();
+		}
+		
+	TUsbServiceState state;
+	TInt err;
+	err = SetIdle(iUsb);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("Unable to stop USB service: %d"), err);
+		return TestStepResult();
+		}
+		
+	//TryStart with new personality
+	TRequestStatus status;
+	iUsb.TryStart(personality, status);
+	
+	//Simulate cable pull, wait for specified amount of time and then simulate cable plug-in
+	RDevUsbcClient client;
+	client.Open(1);
+	err = client.DeviceDisconnectFromHost();
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("DeviceDisconnectFromHost returned error code: %d"), err);
+		return TestStepResult();
+		}
+	User::After(wait*1000000);
+	err = client.DeviceConnectToHost();
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("DeviceConnectToHost returned error code: %d"), err);
+		return TestStepResult();
+		}
+	client.Close();
+	
+
+	//Check TryStart result
+	User::WaitForRequest(status);
+	if (status != KErrNone)
+		{
+		INFO_PRINTF2(_L("Unable to start USB service: %d"), status.Int());
+		return TestStepResult();
+		}
+	err = iUsb.GetServiceState(state);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("GetServiceState returned error code %d"), err);
+		return TestStepResult();
+		}
+	if (state != EUsbServiceStarted)
+		{
+		INFO_PRINTF2(_L("USB service is in the wrong state: %d"), state);
+		return TestStepResult();
+		}
+	
+	SetTestStepResult(EPass);
+	return TestStepResult();
+	}
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CStartNewPersonality.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,80 @@
+/*
+* 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 "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
+*/
+#include <test/testexecutelog.h>
+#include "CUsbTestStepBase.h"
+#include "CStartNewPersonality.h"
+
+CStartNewPersonality::CStartNewPersonality()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KStartNewPersonality);
+	//We need the service to continue running after the test so that usbcheck
+	//can find the device connected to the PC.
+	iStopService = EFalse;
+	}
+
+TVerdict CStartNewPersonality::doTestStepL()
+	{
+	SetTestStepResult(EFail);
+	//Read personality from ini file
+	TInt personality;
+	_LIT(KPersonality, "personality"); 
+	if (!GetIntFromConfig(ConfigSection(), KPersonality, personality))
+		{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		return TestStepResult();
+		}
+		
+	TInt err;
+	err = SetIdle(iUsb);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("Unable to stop USB service: %d"), err);
+		return TestStepResult();
+		}
+	
+	//TryStart with new personality
+	TUsbServiceState state;
+	TRequestStatus status;
+	iUsb.TryStart(personality, status);
+	User::WaitForRequest(status);
+	if (status != KErrNone)
+		{
+		INFO_PRINTF2(_L("Unable to start USB service: %d"), status.Int());
+		return TestStepResult();
+		}
+	err = iUsb.GetServiceState(state);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("GetServiceState returned error code %d"), err);
+		return TestStepResult();
+		}
+	if (state != EUsbServiceStarted)
+		{
+		INFO_PRINTF2(_L("USB service is in the wrong state: %d"), state);
+		return TestStepResult();
+		}
+		
+	SetTestStepResult(EPass);
+	return TestStepResult();
+	}
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CStartPersonality.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,65 @@
+/*
+* 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 "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
+*/
+#include <test/testexecutelog.h>
+#include "CUsbTestStepBase.h"
+#include "CStartPersonality.h"
+
+CStartPersonality::CStartPersonality()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KStartPersonality);
+	//We need the service to continue running after the test so that usbcheck
+	//can find the device connected to the PC.
+	iStopService = EFalse;
+	}
+
+TVerdict CStartPersonality::doTestStepL()
+	{
+	SetTestStepResult(EFail);
+	TRequestStatus status;
+	iUsb.Start(status);
+	User::WaitForRequest(status);
+	if (status != KErrNone)
+		{
+		INFO_PRINTF2(_L("Unable to start USB service: %d"), status.Int());
+		return TestStepResult();
+		}
+
+	TUsbServiceState aState;
+	TInt err;
+	err = iUsb.GetServiceState(aState);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("Error getting USB service state: %d"), status.Int());
+		return TestStepResult();
+		}
+
+	if (EUsbServiceStarted != aState)
+		{
+		INFO_PRINTF2(_L("USB service is in wrong state: %d"), aState);
+		return TestStepResult();
+		}
+
+	SetTestStepResult(EPass);
+	return TestStepResult();
+	}
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CStartStopPersonality.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,738 @@
+/*
+* 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 "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
+*/
+#include <test/testexecutelog.h>
+#include "CUsbTestStepBase.h"
+#include "CStartStopPersonality.h"
+	
+//////////////////////////////////
+//    CStartStopPersonality1    //
+//////////////////////////////////
+
+CStartStopPersonality1::CStartStopPersonality1()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KStartStopPersonality1);
+	iDoNotConnect = ETrue;
+	}
+
+/*
+ This test case uses 3 sessions to the USB manager to call TryStart and TryStop in
+ different states of the server.
+ For TryStart the first 2 sessions use the same personality id and the third one uses
+ a different personality id.
+*/
+TVerdict CStartStopPersonality1::doTestStepL()
+	{
+	SetTestStepResult(EFail);
+	
+	//Read personality from ini file
+	TInt personality1 = 0;
+	TInt personality2 = 0;
+	_LIT(KPersonality1, "personality1"); 
+	if (!GetIntFromConfig(ConfigSection(), KPersonality1, personality1))
+		{
+		INFO_PRINTF1(_L("Can't get personality1 id from config file"));
+		return TestStepResult();
+		}
+	_LIT(KPersonality2, "personality2"); 
+	if (!GetIntFromConfig(ConfigSection(), KPersonality2, personality1))
+		{
+		INFO_PRINTF1(_L("Can't get personality2 id from config file"));
+		return TestStepResult();
+		}
+	
+	//Open sessions;
+	RUsb sess1, sess2, sess3;
+
+	TInt res;
+	res = sess1.Connect();
+	if (res != KErrNone)
+		{
+		INFO_PRINTF2(_L("Error connecting session 1 to USB service: %d"), res);
+		return TestStepResult();
+		}
+	res = sess2.Connect();
+	if (res != KErrNone)
+		{
+		INFO_PRINTF2(_L("Error connecting session 2 to USB service: %d"), res);
+		return TestStepResult();
+		}
+	res = sess3.Connect();
+	if (res != KErrNone)
+		{
+		INFO_PRINTF2(_L("Error connecting session 3 to USB service: %d"), res);
+		return TestStepResult();
+		}
+
+	//Initial State: Idle
+	//Function: TryStart
+	INFO_PRINTF1(_L("Initial State: Idle, Function: TryStart"));
+	SetIdle(sess1);
+	if (CheckState(sess1, EUsbServiceIdle) != KErrNone)
+		{
+		INFO_PRINTF1(_L("Trying again"));
+		SetIdle(sess1);
+		if (CheckState(sess1, EUsbServiceIdle) != KErrNone)
+			{
+			return TestStepResult();
+			}
+		}
+	if (TryStart(sess1, sess2, sess3, KErrNone, KErrNone, KErrAbort, personality1, personality2, EUsbServiceStarted) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Idle
+	//Function: TryStop
+	INFO_PRINTF1(_L("Initial State: Idle, Function: TryStop"));
+	SetIdle(sess1);
+	if (CheckState(sess1, EUsbServiceIdle) != KErrNone)
+		{
+		INFO_PRINTF1(_L("Trying again"));
+		SetIdle(sess1);
+		if (CheckState(sess1, EUsbServiceIdle) != KErrNone)
+			{
+			return TestStepResult();
+			}
+		}
+	if (TryStop(sess1, sess2, sess3, KErrNone, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Starting
+	//Function: TryStart
+	INFO_PRINTF1(_L("Initial State: Starting, Function: TryStart"));
+	SetStarting(sess1);
+	if (CheckState(sess1, EUsbServiceStarting) != KErrNone)
+		{
+		INFO_PRINTF1(_L("Trying again"));
+		SetStarting(sess1);
+		if (CheckState(sess1, EUsbServiceStarting) != KErrNone)
+			{
+			return TestStepResult();
+			}
+		}
+	if (TryStart(sess1, sess2, sess3, KErrNone, KErrNone, KErrAbort, personality1, personality2, EUsbServiceStarted) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Starting
+	//Function: TryStop
+	INFO_PRINTF1(_L("Initial State: Starting, Function: TryStop"));
+	SetStarting(sess1);
+	if (CheckState(sess1, EUsbServiceStarting) != KErrNone)
+		{
+		INFO_PRINTF1(_L("Trying again"));
+		SetStarting(sess1);
+		if (CheckState(sess1, EUsbServiceStarting) != KErrNone)
+			{
+			return TestStepResult();
+			}
+		}
+	if (TryStop(sess1, sess2, sess3, KErrServerBusy, KErrServerBusy, KErrServerBusy) != KErrNone)
+		{
+		return TestStepResult();
+		}
+
+	//Initial State: Stopping
+	//Function: TryStart
+	INFO_PRINTF1(_L("Initial State: Stopping, Function: TryStart"));
+	SetStopping(sess1);
+	if (CheckState(sess1, EUsbServiceStopping) != KErrNone)
+		{
+		INFO_PRINTF1(_L("Trying again"));
+		SetStopping(sess1);
+		if (CheckState(sess1, EUsbServiceStopping) != KErrNone)
+			{
+			return TestStepResult();
+			}
+		}
+	if (TryStart(sess1, sess2, sess3, KErrServerBusy, KErrServerBusy, KErrServerBusy, personality1, personality2, EUsbServiceStopping) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Stopping
+	//Function: TryStop
+	INFO_PRINTF1(_L("Initial State: Stopping, Function: TryStop"));
+	SetStopping(sess1);
+	if (CheckState(sess1, EUsbServiceStopping) != KErrNone)
+		{
+		INFO_PRINTF1(_L("Trying again"));
+		SetStopping(sess1);
+		if (CheckState(sess1, EUsbServiceStopping) != KErrNone)
+			{
+			return TestStepResult();
+			}
+		}
+	if (TryStop(sess1, sess2, sess3, KErrNone, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Started
+	//Function: TryStart
+	//Assumes that the personality we are trying to start in sessions 1 and 2
+	//is the same as the current personality.
+	INFO_PRINTF1(_L("Initial State: Started, Function: TryStart"));
+	SetStarted(sess1);
+	if (CheckState(sess1, EUsbServiceStarted) != KErrNone)
+		{
+		INFO_PRINTF1(_L("Trying again"));
+		SetStarted(sess1);
+		if (CheckState(sess1, EUsbServiceStarted) != KErrNone)
+			{
+			return TestStepResult();
+			}
+		}
+	if (TryStart(sess1, sess2, sess3, KErrNone, KErrNone, KErrAbort, personality1, personality2, EUsbServiceStarted) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Started
+	//Function: TryStop
+	INFO_PRINTF1(_L("Initial State: Started, Function: TryStop"));
+	SetStarted(sess1);
+	if (CheckState(sess1, EUsbServiceStarted) != KErrNone)
+		{
+		INFO_PRINTF1(_L("Trying again"));
+		SetStarted(sess1);
+		if (CheckState(sess1, EUsbServiceStarted) != KErrNone)
+			{
+			return TestStepResult();
+			}
+		}
+	if (TryStop(sess1, sess2, sess3, KErrNone, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	
+	sess1.Close();
+	sess2.Close();
+	sess3.Close();
+	
+	SetTestStepResult(EPass);
+	return TestStepResult();
+	}
+
+TInt CStartStopPersonality1::TryStart(RUsb aSess1, RUsb aSess2, RUsb aSess3, TInt aRet1, TInt aRet2, TInt aRet3, TInt aPersonality1, TInt aPersonality2, TUsbServiceState aState)
+	{
+	TRequestStatus stat1, stat2, stat3;
+	aSess1.TryStart(aPersonality1, stat1);
+	aSess2.TryStart(aPersonality1, stat2);
+	aSess3.TryStart(aPersonality2, stat3);
+	User::WaitForRequest(stat1);
+	User::WaitForRequest(stat2);
+	User::WaitForRequest(stat3);
+	if (stat1 != aRet1)
+		{
+		INFO_PRINTF2(_L("Session 1 TryStart returned unexpected error code: %d"), stat1.Int());
+		return KErrGeneral;
+		}
+	if (stat2 != aRet2)
+		{
+		INFO_PRINTF2(_L("Session 2 TryStart returned unexpected error code: %d"), stat2.Int());
+		return KErrGeneral;
+		}
+	if (stat3 != aRet3)
+		{
+		INFO_PRINTF2(_L("Session 3 TryStart returned unexpected error code: %d"), stat3.Int());
+		return KErrGeneral;
+		}
+	
+	//Make sure the correct personality is loaded and the server is in the expected state
+	TInt err;
+	TInt currPersonality;
+	err = aSess1.GetCurrentPersonalityId(currPersonality);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("Unable to get current personality id: %d"), err);
+		return KErrGeneral;
+		}
+	else if (currPersonality != aPersonality1)
+		{
+		INFO_PRINTF3(_L("Current personality id does not match expected value: %d != %d"), currPersonality, aPersonality1);
+		return KErrGeneral;
+		}
+	
+	return CheckState(aSess1, aState);
+	}
+
+TInt CStartStopPersonality1::TryStop(RUsb aSess1, RUsb aSess2, RUsb aSess3, TInt aRet1, TInt aRet2, TInt aRet3)
+	{
+	TRequestStatus stat1, stat2, stat3;
+	aSess1.TryStop(stat1);
+	aSess2.TryStop(stat2);
+	aSess3.TryStop(stat3);
+	User::WaitForRequest(stat1);
+	User::WaitForRequest(stat2);
+	User::WaitForRequest(stat3);
+	if (stat1 != aRet1)
+		{
+		INFO_PRINTF2(_L("Session 1 TryStop returned unexpected error code: %d"), stat1.Int());
+		return KErrGeneral;
+		}
+	if (stat2 != aRet2)
+		{
+		INFO_PRINTF2(_L("Session 2 TryStop returned unexpected error code: %d"), stat2.Int());
+		return KErrGeneral;
+		}
+	if (stat3 != aRet3)
+		{
+		INFO_PRINTF2(_L("Session 3 TryStop returned unexpected error code: %d"), stat3.Int());
+		return KErrGeneral;
+		}
+	return KErrNone;
+	}
+
+//////////////////////////////////
+//    CStartStopPersonality2    //
+//////////////////////////////////
+
+CStartStopPersonality2::CStartStopPersonality2()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KStartStopPersonality2);
+	iDoNotConnect = ETrue;
+	}
+
+TVerdict CStartStopPersonality2::doTestStepL()
+	{
+	SetTestStepResult(EFail);
+	
+	//Read personality from ini file
+	TInt personality;
+	_LIT(KPersonality, "personality1"); 
+	if (!GetIntFromConfig(ConfigSection(), KPersonality, personality))
+		{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		return TestStepResult();
+		}
+	
+	//Open sessions;
+	RUsb sess1, sess2;
+
+	TInt res;
+	res = sess1.Connect();
+	if (res != KErrNone)
+		{
+		INFO_PRINTF2(_L("Error connecting session 1 to USB service: %d"), res);
+		return TestStepResult();
+		}
+	res = sess2.Connect();
+	if (res != KErrNone)
+		{
+		INFO_PRINTF2(_L("Error connecting session 2 to USB service: %d"), res);
+		return TestStepResult();
+		}
+	
+	TRequestStatus stat1, stat2;
+	
+	//Initial State: Idle
+	//Functions: TryStart/Start
+	INFO_PRINTF1(_L("Initial State: Idle, Functions: TryStart/Start"));
+	SetIdle(sess1);
+	if (CheckState(sess1, EUsbServiceIdle) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	sess1.TryStart(personality, stat1);
+	sess2.Start(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Idle
+	//Functions: Start/TryStart
+	INFO_PRINTF1(_L("Initial State: Idle, Functions: Start/TryStart"));
+	SetIdle(sess1);
+	sess1.Start(stat1);
+	sess2.TryStart(personality, stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Idle
+	//Functions: TryStart/Stop
+	INFO_PRINTF1(_L("Initial State: Idle, Functions: TryStart/Stop"));
+	SetIdle(sess1);
+	sess1.TryStart(personality, stat1);
+	sess2.Stop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrUsbServiceStopped, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Idle
+	//Functions: Stop/TryStart
+	INFO_PRINTF1(_L("Initial State: Idle, Functions: Stop/TryStart"));
+	SetIdle(sess1);
+	sess1.Stop(stat1);
+	sess2.TryStart(personality, stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Idle
+	//Functions: TryStop/Start
+	INFO_PRINTF1(_L("Initial State: Idle, Functions: TryStop/Start"));
+	SetIdle(sess1);
+	sess1.TryStop(stat1);
+	sess2.Start(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Idle
+	//Functions: Start/TryStop
+	INFO_PRINTF1(_L("Initial State: Idle, Functions: Start/Stop"));
+	SetIdle(sess1);
+	sess1.Start(stat1);
+	sess2.TryStop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrServerBusy) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Idle
+	//Functions: TryStop/Stop
+	INFO_PRINTF1(_L("Initial State: Idle, Functions: TryStop/Stop"));
+	SetIdle(sess1);
+	sess1.TryStop(stat1);
+	sess2.Stop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Idle
+	//Functions: Stop/TryStop
+	INFO_PRINTF1(_L("Initial State: Idle, Functions: Stop/TryStop"));
+	SetIdle(sess1);
+	sess1.Stop(stat1);
+	sess2.TryStop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Starting
+	//Functions: TryStart/Start
+	INFO_PRINTF1(_L("Initial State: Starting, Functions: TryStart/Start"));
+	SetIdle(sess1);
+	sess1.TryStart(personality, stat1);
+	sess2.Start(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Starting
+	//Functions: Start/TryStart
+	INFO_PRINTF1(_L("Initial State: Starting, Functions: Start/TryStart"));
+	SetStarting(sess1);
+	sess1.Start(stat1);
+	sess2.TryStart(personality, stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Starting
+	//Functions: TryStart/Stop
+	INFO_PRINTF1(_L("Initial State: Starting, Functions: TryStart/Stop"));
+	SetStarting(sess1);
+	sess1.TryStart(personality, stat1);
+	sess2.Stop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrUsbServiceStopped, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Starting
+	//Functions: Stop/TryStart
+	INFO_PRINTF1(_L("Initial State: Starting, Functions: Stop/TryStart"));
+	SetStarting(sess1);
+	sess1.Stop(stat1);
+	sess2.TryStart(personality, stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrServerBusy) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Starting
+	//Functions: TryStop/Start
+	INFO_PRINTF1(_L("Initial State: Starting, Functions: TryStop/Start"));
+	SetStarting(sess1);
+	sess1.TryStop(stat1);
+	sess2.Start(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrServerBusy, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Starting
+	//Functions: Start/TryStop
+	INFO_PRINTF1(_L("Initial State: Starting, Functions: Start/TryStop"));
+	SetStarting(sess1);
+	sess1.Start(stat1);
+	sess2.TryStop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrServerBusy) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Starting
+	//Functions: TryStop/Stop
+	INFO_PRINTF1(_L("Initial State: Starting, Functions: TryStop/Stop"));
+	SetStarting(sess1);
+	sess1.TryStop(stat1);
+	sess2.Stop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrServerBusy, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Starting
+	//Functions: Stop/TryStop
+	INFO_PRINTF1(_L("Initial State: Starting, Functions: Stop/TryStop"));
+	SetStarting(sess1);
+	sess1.Stop(stat1);
+	sess2.TryStop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Stopping
+	//Functions: TryStart/Start
+	INFO_PRINTF1(_L("Initial State: Stopping, Functions: TryStart/Start"));
+	SetStopping(sess1);
+	sess1.TryStart(personality, stat1);
+	sess2.Start(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrServerBusy, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Stopping
+	//Functions: Start/TryStart
+	INFO_PRINTF1(_L("Initial State: Stopping, Functions: Start/TryStart"));
+	SetStopping(sess1);
+	sess1.Start(stat1);
+	sess2.TryStart(personality, stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Stopping
+	//Functions: TryStart/Stop
+	INFO_PRINTF1(_L("Initial State: Stopping, Functions: TryStart/Stop"));
+	SetStopping(sess1);
+	sess1.TryStart(personality, stat1);
+	sess2.Stop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrServerBusy, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Stopping
+	//Functions: Stop/TryStart
+	INFO_PRINTF1(_L("Initial State: Stopping, Functions: Stop/TryStart"));
+	SetStopping(sess1);
+	sess1.Stop(stat1);
+	sess2.TryStart(personality, stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrServerBusy) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Stopping
+	//Functions: TryStop/Start
+	INFO_PRINTF1(_L("Initial State: Stopping, Functions: TryStop/Start"));
+	SetStopping(sess1);
+	sess1.TryStop(stat1);
+	sess2.Start(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrUsbServiceStarted, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Stopping
+	//Functions: Start/TryStop
+	INFO_PRINTF1(_L("Initial State: Stopping, Functions: Start/TryStop"));
+	SetStopping(sess1);
+	sess1.Start(stat1);
+	sess2.TryStop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrServerBusy) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Stopping
+	//Functions: TryStop/Stop
+	INFO_PRINTF1(_L("Initial State: Stopping, Functions: TryStop/Stop"));
+	SetStopping(sess1);
+	sess1.TryStop(stat1);
+	sess2.Stop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Stopping
+	//Functions: Stop/TryStop
+	INFO_PRINTF1(_L("Initial State: Stopping, Functions: Stop/TryStop"));
+	SetStopping(sess1);
+	sess1.Stop(stat1);
+	sess2.TryStop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Started
+	//Functions: TryStart/Start
+	INFO_PRINTF1(_L("Initial State: Started, Functions: TryStart/Start"));
+	SetIdle(sess1);
+	sess1.TryStart(personality, stat1);
+	sess2.Start(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Started
+	//Functions: Start/TryStart
+	//Assumes that the personality we are trying to start in sessions 1 and 2
+	//is the same as the current personality.
+	INFO_PRINTF1(_L("Initial State: Started, Functions: Start/TryStart"));
+	SetStarted(sess1);
+	sess1.Start(stat1);
+	sess2.TryStart(personality, stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Started
+	//Functions: TryStart/Stop
+	//Assumes that the personality we are trying to start in session 1
+	//is the same as the current personality.
+	INFO_PRINTF1(_L("Initial State: Started, Functions: TryStart/Stop"));
+	SetStarted(sess1);
+	sess1.TryStart(personality, stat1);
+	sess2.Stop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Started
+	//Functions: Stop/TryStart
+	INFO_PRINTF1(_L("Initial State: Started, Functions: Stop/TryStart"));
+	SetStarted(sess1);
+	sess1.Stop(stat1);
+	sess2.TryStart(personality, stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrServerBusy) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Started
+	//Functions: TryStop/Start
+	INFO_PRINTF1(_L("Initial State: Started, Functions: TryStop/Start"));
+	SetStarted(sess1);
+	sess1.TryStop(stat1);
+	sess2.Start(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrUsbServiceStarted, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Started
+	//Functions: Start/TryStop
+	INFO_PRINTF1(_L("Initial State: Started, Functions: Start/TryStop"));
+	SetStarted(sess1);
+	sess1.Start(stat1);
+	sess2.TryStop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Started
+	//Functions: TryStop/Stop
+	INFO_PRINTF1(_L("Initial State: Started, Functions: TryStop/Stop"));
+	SetStarted(sess1);
+	sess1.TryStop(stat1);
+	sess2.Stop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	//Initial State: Started
+	//Functions: Stop/TryStop
+	INFO_PRINTF1(_L("Initial State: Started, Functions: Stop/TryStop"));
+	SetStarted(sess1);
+	sess1.Stop(stat1);
+	sess2.TryStop(stat2);
+	if (CheckReturnCodes(stat1, stat2, KErrNone, KErrNone) != KErrNone)
+		{
+		return TestStepResult();
+		}
+	
+	sess1.Close();
+	sess2.Close();
+	
+	SetTestStepResult(EPass);
+	return TestStepResult();
+	}
+
+TInt CStartStopPersonality2::CheckReturnCodes(TRequestStatus& aStat1, TRequestStatus& aStat2, TInt aRet1, TInt aRet2)
+	{
+	User::WaitForRequest(aStat1);
+	User::WaitForRequest(aStat2);
+	if (aStat1 != aRet1)
+		{
+		INFO_PRINTF2(_L("Session 1 returned unexpected error code: %d"), aStat1.Int());
+		return KErrGeneral;
+		}
+	if (aStat2 != aRet2)
+		{
+		INFO_PRINTF2(_L("Session 2 returned unexpected error code: %d"), aStat2.Int());
+		return KErrGeneral;
+		}
+	return KErrNone;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CStopPersonality.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,65 @@
+/*
+* 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 "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
+*/
+#include <test/testexecutelog.h>
+#include "CUsbTestStepBase.h"
+#include "CStopPersonality.h"
+
+CStopPersonality::CStopPersonality()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KStopPersonality);
+	//We need the service to continue running after the test so that usbcheck
+	//can find the device connected to the PC.
+	iStopService = EFalse;
+	}
+
+TVerdict CStopPersonality::doTestStepL()
+	{
+	SetTestStepResult(EFail);
+	TRequestStatus status;
+	iUsb.Stop(status);
+	User::WaitForRequest(status);
+	if (status != KErrNone)
+		{
+		INFO_PRINTF2(_L("Unable to stop USB service: %d"), status.Int());
+		return TestStepResult();
+		}
+
+	TUsbServiceState aState;
+	TInt err;
+	err = iUsb.GetServiceState(aState);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("Error getting USB service state: %d"), status.Int());
+		return TestStepResult();
+		}
+
+	if (EUsbServiceIdle != aState)
+		{
+		INFO_PRINTF2(_L("USB service is in wrong state: %d"), aState);
+		return TestStepResult();
+		}
+
+	SetTestStepResult(EPass);
+	return TestStepResult();
+	}
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CUsbComponentTest.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,899 @@
+/*
+* 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 "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:
+* Example CTestStep derived implementation
+*
+*/
+
+/**
+ @file 
+*/
+#include <test/testexecutelog.h>
+#include "CUsbComponentTest.h"
+
+
+/**
+ Compare personalities of USB from device with expected result in
+ ini file. The compared fields are: personal IDs, Description
+ and Class control IDs.
+ */
+TVerdict CUsbComponentTest::CompareUsbPersonalityL()
+
+{
+		
+	//Get Personality IDs from usb server
+	TInt checkStatus;
+	RArray<TInt> idArray;
+	checkStatus = iUsb.GetPersonalityIds(idArray);
+	TEST(checkStatus==KErrNone);
+	
+	
+	TInt expectedPersonalityID;
+	TInt classID;
+	HBufC* descriptor; 	
+	TPtrC theString;
+	RArray<TUid> uidArray;	
+	TBool isClassSupported;
+	TBuf<16> getStringName;
+	TInt expectedPersonalityCount;
+	TInt expectedClassCount;
+	
+	
+	//get total personality counts
+	if(!GetIntFromConfig(ConfigSection(), _L("personalityCount"),expectedPersonalityCount))
+	{
+		INFO_PRINTF1(_L("Can't get personality count from config file"));
+		SetTestStepResult(EFail);
+	}
+	TEST(idArray.Count()==expectedPersonalityCount);
+	
+	for (TInt i = 0; i<idArray.Count(); i++)
+	{
+			_LIT(KIntFormat, "Id%d");
+			getStringName.Format(KIntFormat,i+1);
+			if(!GetIntFromConfig(ConfigSection(), getStringName,expectedPersonalityID))
+			{
+				INFO_PRINTF1(_L("Can't get personality id from config file"));
+				SetTestStepResult(EFail);
+			}
+			
+			_LIT(KStringFormat, "Description%d");
+			getStringName.Format(KStringFormat,i+1);
+			if(!GetStringFromConfig(ConfigSection(), getStringName,theString))
+			{
+				INFO_PRINTF1(_L("Can't get Description from config file"));
+				SetTestStepResult(EFail);
+			}
+			
+			
+			//compare ID with expected result.	
+			TEST(expectedPersonalityID == idArray[i]);
+			
+			//compare descriptions with expected result
+			checkStatus = iUsb.GetDescription(expectedPersonalityID,descriptor);
+			TEST(checkStatus==KErrNone);	
+			TEST (descriptor->Compare(theString) == 0);	
+			delete descriptor;
+		
+			//compare CC ids with expected result.check class supported
+			uidArray.Reset();
+			checkStatus = iUsb.GetSupportedClasses(expectedPersonalityID,uidArray);
+			TEST(checkStatus==KErrNone);
+			
+			_LIT(KCountFormat, "classCount%d");
+			getStringName.Format(KCountFormat,i+1);
+			if(!GetIntFromConfig(ConfigSection(), getStringName,expectedClassCount))
+			{
+				INFO_PRINTF1(_L("Can't get class count from config file"));
+				SetTestStepResult(EFail);	
+			}
+			TEST(expectedClassCount==uidArray.Count());	
+			
+			for(TInt j = 0; j<uidArray.Count();j++)
+			{
+				//get expected class ID from ini file
+				_LIT(KClassFormat, "classID%d%d");
+				getStringName.Format(KClassFormat,i+1, j+1);
+				if(!GetHexFromConfig(ConfigSection(), getStringName, classID))
+				{
+					INFO_PRINTF1(_L("Can't get class id from config file"));
+					SetTestStepResult(EFail);	
+				}
+				
+				//check class supported and actual class id match expected Id
+				TEST(uidArray[j] ==TUid::Uid(classID));									
+				checkStatus = iUsb.ClassSupported(expectedPersonalityID,TUid::Uid(classID),isClassSupported);
+				TEST(checkStatus==KErrNone);	
+				TEST(isClassSupported);
+				
+			}
+			
+	}
+	
+	idArray.Close();
+	uidArray.Close();
+
+	return TestStepResult();
+}
+
+CUsbLoadPersonalityNormal::CUsbLoadPersonalityNormal()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KUsbLoadPersonalityNormal);
+	}
+
+
+/**
+ @return - TVerdict code
+ Override of base class pure virtual
+ Demonstrates USB device read personality list from resource file 
+ and validate them when RUsb connect to USB server
+ */
+TVerdict CUsbLoadPersonalityNormal::doTestStepL()
+	{
+	return CompareUsbPersonalityL();
+	}	
+
+/**
+ * Constructor
+ */
+CUsbLoadPersonalityAbNormal::CUsbLoadPersonalityAbNormal()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KUsbLoadPersonalityAbNormal);
+	//Skip connection to USB server during preamble
+	iDoNotConnect = ETrue;
+	}
+
+/**
+ @return - TVerdict code
+ Override of base class pure virtual
+ Demonstrates Loading ersonalities from CC missed
+ when RUsb try to connect to USB server and should fail
+ */
+TVerdict CUsbLoadPersonalityAbNormal::doTestStepL()
+	{
+		
+	TInt res = iUsb.Connect();
+	TEST(res==KErrAbort);
+	return TestStepResult();
+	}	
+
+
+/**
+ * Constructor
+ */
+CUsbLoadPersonalityMissing::CUsbLoadPersonalityMissing()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KUsbLoadPersonalityMissing);
+	
+	}
+
+/**
+ @return - TVerdict code
+ Override of base class pure virtual
+ Demonstrates Loading personalities from missing file
+ when RUsb try to connect to USB server and startshould successful 
+ */
+TVerdict CUsbLoadPersonalityMissing::doTestStepL()
+	{
+		TRequestStatus status;
+		TUsbServiceState currentState;	
+		
+		iUsb.Start(status );
+		User::WaitForRequest(status);
+		TEST(status==KErrNone);
+		TEST(iUsb.GetServiceState(currentState)==KErrNone);
+		TEST(EUsbServiceStarted==currentState);
+		
+		iUsb.Stop(status );
+		User::WaitForRequest(status);
+		TEST(status==KErrNone);
+		TEST(iUsb.GetServiceState(currentState)==KErrNone);
+		TEST(EUsbServiceIdle==currentState);
+		
+		TInt expectedPersonalityID;
+		if(!GetIntFromConfig(ConfigSection(), _L("Id"), expectedPersonalityID))
+		{
+			INFO_PRINTF1(_L("Can't get personality id from config file"));
+			SetTestStepResult(EFail);	
+		}
+		
+		iUsb.TryStart(expectedPersonalityID,status);
+		User::WaitForRequest(status);
+		TEST(status==KErrNotSupported);
+		HBufC* descriptor; 
+		status = iUsb.GetDescription(expectedPersonalityID,descriptor);
+		TEST(status==KErrNotSupported);
+		delete descriptor;
+	
+		//Try to get suported class with bad personality ID, it will fail
+		RArray<TUid> uidArray;
+		status = iUsb.GetSupportedClasses(expectedPersonalityID,uidArray);
+		TEST(status==KErrNotSupported);
+		
+		return TestStepResult();
+	
+	}		
+	/**
+ * Constructor
+ */
+CUsbTestOOM::CUsbTestOOM()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KUsbTestOOM);
+	}
+
+/**
+ @return - TVerdict code
+ Override of base class pure virtual
+ Demonstrates Loading personalities with OOM condition
+ when RUsb connect to USB server
+ */
+TVerdict CUsbTestOOM::doTestStepL()
+	{
+	
+ 	//Frist time RUsb should connect to USB server successfully
+	TVerdict result = CompareUsbPersonalityL();
+	//set oom, RUsb whould fail connect to USB Server.
+	RUsb aUsb;
+	TInt count = 1;
+	TInt res;
+	for(;;)
+	{
+		iUsb.__DbgFailNext(count);
+		res = aUsb.Connect();
+		if (res!=KErrNoMemory) 
+			break;
+		count++;
+	}
+	
+	TEST(res == KErrNone);
+	iUsb.__DbgFailNext(0);
+	aUsb.Close();
+	iUsb.Close();
+	// remove oom RUsb should connect to USB server successfully again.
+	res = iUsb.Connect();
+	TEST(res == KErrNone);
+	result = CompareUsbPersonalityL();
+	return result;
+
+	}	
+
+/**
+ * Constructor
+ */
+CUsbSwitchPersonalityNormal::CUsbSwitchPersonalityNormal()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KUsbSwitchPersonalityNormal);
+	}
+
+/**
+ @return - TVerdict code
+ Override of base class pure virtual
+ Demonstrates switching different personality from current one
+ when RUsb connect to USB server
+ */
+TVerdict CUsbSwitchPersonalityNormal::doTestStepL()
+	{
+
+	TRequestStatus status;	
+	
+	//When USB server is started, a defaul personality is set. 
+	//Compare personal IDs
+	TInt deviceCurrentID ,expectedPersonalityID;
+	TInt checkStatus = iUsb.GetCurrentPersonalityId(deviceCurrentID);
+	TEST(checkStatus==KErrNone);	
+	
+	if(!GetIntFromConfig(ConfigSection(), _L("Id2"), expectedPersonalityID))
+	{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		SetTestStepResult(EFail);	
+	}
+	TEST(deviceCurrentID==expectedPersonalityID);
+	
+	//compare descriptions
+	TPtrC theString;
+	HBufC* descriptor; 
+	checkStatus = iUsb.GetDescription(deviceCurrentID,descriptor);
+	TEST(checkStatus==KErrNone);
+	
+	if(!GetStringFromConfig(ConfigSection(), _L("Description2"), theString))
+	{
+		INFO_PRINTF1(_L("Can't get Description from config file"));
+		SetTestStepResult(EFail);
+	}
+	TEST(descriptor->Compare(theString) == 0);			
+	delete descriptor;
+			
+	//compare CC ids
+	RArray<TUid> uidArray;
+	TInt classID;
+	checkStatus = iUsb.GetSupportedClasses(deviceCurrentID,uidArray);
+	TBuf<16> getStringName;
+	
+	TInt expectedClassCount;
+	if(!GetIntFromConfig(ConfigSection(), _L("classCount2"),expectedClassCount))
+	{
+		INFO_PRINTF1(_L("Can't get class count from config file"));
+		SetTestStepResult(EFail);
+	}
+	TEST(expectedClassCount==uidArray.Count());	
+						
+	for(TInt j = 0; j<uidArray.Count();j++)
+	{
+		//get expected class ID from ini file
+		_LIT(KClassFormat, "classID2%d");
+		getStringName.Format(KClassFormat,j+1);
+		if(!GetHexFromConfig(ConfigSection(), getStringName, classID))
+		{
+			INFO_PRINTF1(_L("Can't get class id from config file"));
+			SetTestStepResult(EFail);
+		}
+		TEST(uidArray[j] ==TUid::Uid(classID));	
+	}
+	
+	
+	//check whether usb service state is in idle before switch	
+	TUsbServiceState currentState;	
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceIdle==currentState);
+	
+	//Switch another personality
+	if(!GetIntFromConfig(ConfigSection(),_L("Id1"),expectedPersonalityID))
+	{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		SetTestStepResult(EFail);
+	}
+	iUsb.TryStart(expectedPersonalityID,status);
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	
+	//Compare personal ID
+	checkStatus = iUsb.GetCurrentPersonalityId(deviceCurrentID);
+	TEST(checkStatus==KErrNone);	
+	TEST(deviceCurrentID==expectedPersonalityID);
+	
+	//compare descriptions
+	checkStatus = iUsb.GetDescription(deviceCurrentID,descriptor);
+	TEST(checkStatus==KErrNone);
+	if(!GetStringFromConfig(ConfigSection(), _L("Description1"), theString))
+	{
+		INFO_PRINTF1(_L("Can't get description from config file"));
+		SetTestStepResult(EFail);
+	}
+	TEST(descriptor->Compare(theString) == 0);
+	delete descriptor;			
+			
+	//compare CC ids
+	uidArray.Reset();
+	checkStatus = iUsb.GetSupportedClasses(deviceCurrentID,uidArray);
+
+	if(!GetIntFromConfig(ConfigSection(), _L("classCount1"),expectedClassCount))
+	{
+		INFO_PRINTF1(_L("Can't get class count from config file"));
+		SetTestStepResult(EFail);
+	}
+	TEST(expectedClassCount==uidArray.Count());	
+	
+	for(TInt k = 0; k<uidArray.Count();k++)
+	{
+		_LIT(KClassFormat2, "classID1%d");
+		getStringName.Format(KClassFormat2,k+1);
+		if(!GetHexFromConfig(ConfigSection(), getStringName, classID))
+		{
+			INFO_PRINTF1(_L("Can't get class id from config file"));
+			SetTestStepResult(EFail);
+		}
+//		TUid temp = uidArray[k]; 
+		TEST(uidArray[k] ==TUid::Uid(classID));
+	}
+	
+	//try stop service
+	iUsb.TryStop(status);
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceIdle==currentState);
+		
+	// do clean job
+	uidArray.Close();
+	return TestStepResult();
+
+	}	
+
+/**
+ * Constructor
+ */
+CUsbSwitchPersonalityAbNormal::CUsbSwitchPersonalityAbNormal()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KUsbSwitchPersonalityAbNormal);
+	}
+
+/**
+ @return - TVerdict code
+ Override of base class pure virtual
+ Demonstrates switching different personality from current one to abnormal one
+ when RUsb connect to USB server
+ */
+TVerdict CUsbSwitchPersonalityAbNormal::doTestStepL()
+	{
+	
+	TRequestStatus status;
+	TInt expectedPersonalityID;
+		
+	//trystart personality
+	if(!GetIntFromConfig(ConfigSection(),_L("goodId1"),expectedPersonalityID))
+	{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		SetTestStepResult(EFail);
+	}
+	iUsb.TryStart(expectedPersonalityID,status);
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	TUsbServiceState currentState;
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarted==currentState);
+	
+	//trystart different personality when in started, it will fail
+	if(!GetIntFromConfig(ConfigSection(),_L("goodId2"),expectedPersonalityID))
+	{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		SetTestStepResult(EFail);
+	}
+	iUsb.TryStart(expectedPersonalityID,status);
+	User::WaitForRequest(status);
+	TEST(status==KErrAbort);
+	
+	//try to get description with bad personality, it will fail
+	if(!GetIntFromConfig(ConfigSection(),_L("badId"),expectedPersonalityID))
+	{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		SetTestStepResult(EFail);
+	}
+	HBufC* descriptor; 
+	status = iUsb.GetDescription(expectedPersonalityID,descriptor);
+	TEST(status==KErrNotSupported);
+	delete descriptor;
+	
+	//Try to get suported class with bad personality ID, it will fail
+	RArray<TUid> uidArray;
+	status = iUsb.GetSupportedClasses(expectedPersonalityID,uidArray);
+	TEST(status==KErrNotSupported);
+	
+	//trystart a bad personality ID, it will fail
+	iUsb.TryStop(status);
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceIdle==currentState);
+	
+	
+	iUsb.TryStart(expectedPersonalityID,status);
+	User::WaitForRequest(status);
+	TEST(status==KErrNotFound);
+	
+	uidArray.Close();
+	return TestStepResult();
+		
+	}
+/**
+ Constructor
+ */
+CUsbStartStopPersonality1::CUsbStartStopPersonality1()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KUsbStartStopPersonality1);
+	}
+
+/**
+ @return - TVerdict code
+ Override of base class pure virtual
+ Demonstrates switching personality with CC fail to start from current one
+ when RUsb connect to USB server
+ */
+TVerdict CUsbStartStopPersonality1::doTestStepL()
+	{
+	
+	TInt deviceCurrentID ;
+	TRequestStatus status;
+	TUsbServiceState currentState;	
+	
+	//First time set personalty successfully
+	if(!GetIntFromConfig(ConfigSection(),_L("IdGood"),deviceCurrentID))
+	{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		SetTestStepResult(EFail);
+	}
+	iUsb.TryStart(deviceCurrentID,status );
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarted==currentState); 
+	
+	// Stop service, service state should be idle
+	iUsb.TryStop(status );
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);	
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceIdle==currentState); 
+	
+	//Second time set personalty with a CC fail to start, switch will fail
+	if(!GetIntFromConfig(ConfigSection(),_L("IdFail"),deviceCurrentID))
+	{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		SetTestStepResult(EFail);
+	}
+	iUsb.TryStart(deviceCurrentID,status );
+	User::WaitForRequest(status);
+	TEST(status==KErrGeneral);
+	
+	return TestStepResult();
+	}	
+
+/**
+ * Constructor
+ */
+CUsbStartStopPersonality2::CUsbStartStopPersonality2()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KUsbStartStopPersonality2);
+	}
+
+/**
+ @return - TVerdict code
+ Override of base class pure virtual
+ Demonstrates TryStart/TryStop personality at different USB server's state
+ when RUsb connect to USB server
+ */
+TVerdict CUsbStartStopPersonality2::doTestStepL()
+	{
+	
+	TInt deviceCurrentID ;
+	TRequestStatus status;
+	TRequestStatus status2;
+	TUsbServiceState currentState;
+	
+	
+	// call tryStart when server's state is in idle.
+	// the server state is started
+	if(!GetIntFromConfig(ConfigSection(),_L("IdGood"),deviceCurrentID))
+	{
+		INFO_PRINTF1(_L("Can't get personality id from config file"));
+		SetTestStepResult(EFail);
+	}
+	iUsb.TryStart(deviceCurrentID,status );
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarted==currentState); 
+	
+	// call tryStart when server's state is in started.
+	// the server state is started
+	iUsb.TryStart(deviceCurrentID,status );
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarted==currentState); 
+	
+	//call trystart when server's state is in stoping,
+	//it has no effect, server state finally is in idle.
+	TBool startCompleteFirst = EFalse;	
+	iUsb.TryStop(status );
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStopping ==currentState);
+	iUsb.TryStart(deviceCurrentID,status2 );	
+
+	
+	//The Usb service should stop.
+	User::WaitForRequest(status, status2);
+	if(status == KRequestPending)
+	{
+		TEST(status2==KErrServerBusy);
+		User::WaitForRequest(status);
+		startCompleteFirst = ETrue;	
+	}
+	else 
+	{
+		User::WaitForRequest(status2);
+		SetTestStepResult(EFail);
+	}
+	if (startCompleteFirst)
+	{
+		TEST(iUsb.GetServiceState(currentState)==KErrNone);
+		TEST(EUsbServiceIdle ==currentState);
+	}
+	
+	//call trystart when server's state is in starting,
+	//it has no effect, server state finally is in started.
+	TBool secondStartCompleteFirst = EFalse;	
+	iUsb.TryStart(deviceCurrentID,status );
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarting ==currentState);
+	iUsb.TryStart(deviceCurrentID,status2 );	
+	
+	//The Usb service should start.
+	User::WaitForRequest(status, status2);
+	if(status == KRequestPending)
+	{
+		TEST(status2==KErrServerBusy);
+		User::WaitForRequest(status);
+		secondStartCompleteFirst = ETrue;	
+	}
+	else 
+	{
+		User::WaitForRequest(status2);
+		SetTestStepResult(EFail);
+	}
+	if (secondStartCompleteFirst)
+	{
+		TEST(iUsb.GetServiceState(currentState)==KErrNone);
+		TEST(EUsbServiceStarted ==currentState);
+	}
+	
+	
+	
+	//call trystop when server's state is started
+	//server state finally is in idle.
+	iUsb.TryStop(status );
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceIdle==currentState); 
+	
+	//call trystop when server's state is idle
+	//server state finally is in idle.
+	iUsb.TryStop(status );
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceIdle==currentState); 
+	
+	//call trystop when server's state is in staring,
+	//it has no effect, server's state finally is in started	
+	
+	iUsb.TryStart(deviceCurrentID,status );
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarting ==currentState);	
+	iUsb.TryStop(status2 );
+
+	TBool stopCompleteFirst = EFalse;
+	User::WaitForRequest(status, status2);
+	
+	if(status == KRequestPending)
+	{
+		TEST(status2==KErrServerBusy);
+		User::WaitForRequest(status);
+		stopCompleteFirst = ETrue;	
+	}
+	else 
+	{
+		User::WaitForRequest(status2);
+		SetTestStepResult(EFail);
+	}
+	if (stopCompleteFirst)
+	{
+		TEST(iUsb.GetServiceState(currentState)==KErrNone);
+		TEST(EUsbServiceStarted ==currentState);
+	}
+	
+	//call trystop when server's state is in stoping,
+	//it has no effect, server's state finally is in idle	
+	
+	iUsb.TryStop(status );
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStopping ==currentState);	
+	iUsb.TryStop(status2 );
+
+	TBool secondStopCompleteFirst = EFalse;
+	User::WaitForRequest(status, status2);
+	
+	if(status == KRequestPending)
+	{
+		TEST(status2==KErrServerBusy);
+		User::WaitForRequest(status);
+		secondStopCompleteFirst = ETrue;	
+	}
+	else 
+	{
+		User::WaitForRequest(status2);
+		SetTestStepResult(EFail);
+	}
+	if (secondStopCompleteFirst)
+	{
+		TEST(iUsb.GetServiceState(currentState)==KErrNone);
+		TEST(EUsbServiceIdle ==currentState);
+	}
+	
+	return TestStepResult();
+	}	
+
+
+/**
+ * Constructor
+ */
+
+CUsbStartStopPersonality3::CUsbStartStopPersonality3()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KUsbStartStopPersonality3);
+	}
+
+/**
+ @return - TVerdict code
+ Override of base class pure virtual
+ Demonstrates start/stop personality at different USB server's state
+ when RUsb connect to USB server
+ */
+TVerdict CUsbStartStopPersonality3::doTestStepL()
+	{
+
+	TRequestStatus status;
+	TRequestStatus status2;
+	TUsbServiceState currentState;	
+	
+	
+	//call start, when server's state is idle
+	//State is started
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceIdle==currentState); 
+	iUsb.Start(status );
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarted==currentState); 
+	
+	//call started when server's state is started, 
+	//State is started
+	
+	iUsb.Start(status );
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarted==currentState); 
+	
+	//call started when server's state is starting, 
+	//State is started
+	iUsb.Stop(status );
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	
+	iUsb.Start(status );
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarting ==currentState);
+	iUsb.Start(status2 );	
+	User::WaitForRequest(status);
+	User::WaitForRequest(status2);	
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarted ==currentState);
+	
+	//call start when server's state is in stopping,
+	//it will starting sevice and finally state is in started
+	iUsb.Stop(status );
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStopping ==currentState);
+	iUsb.Start(status2 );
+
+	User::WaitForRequest(status);
+	User::WaitForRequest(status2);
+	
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarted ==currentState);
+	
+	//call stop when server's state is started, 
+	//the state is idle
+	iUsb.Stop(status );
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceIdle==currentState); 
+	
+	//call stop when server's state is idle, 
+	//the state is idle
+	iUsb.Stop(status );
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceIdle==currentState);
+	
+	//call stop when server's state is in staring,
+	//finally state is in idle
+	
+	iUsb.Start(status );
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarting ==currentState);
+	iUsb.Stop(status2 );	
+
+	User::WaitForRequest(status);
+	User::WaitForRequest(status2);	
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceIdle ==currentState);
+	
+	//call stop when server's state is in stoping,
+	//finally state is in idle
+	
+	iUsb.Start(status );
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	iUsb.Stop(status );
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStopping ==currentState);
+	iUsb.Stop(status2 );	
+
+	User::WaitForRequest(status);
+	User::WaitForRequest(status2);	
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceIdle ==currentState);
+	
+	
+	return TestStepResult();
+	}	
+
+/**
+ * Constructor
+ */
+CMemAllocationFailure::CMemAllocationFailure()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KMemAllocationFailure);
+	}
+
+/**
+ @return - TVerdict code
+ Override of base class pure virtual
+ Test memory allocation failure scenario
+ */
+TVerdict CMemAllocationFailure::doTestStepL()
+	{
+#ifdef _DEBUG
+	TInt personalityId = 2;	// dummy, not used
+
+	__UHEAP_FAILNEXT(1);
+	HBufC* hbuf;		
+	TEST(iUsb.GetDescription(personalityId, hbuf)==KErrNoMemory);
+	__UHEAP_RESET;
+	
+	__UHEAP_FAILNEXT(1);
+	RArray<TInt> personalityIds;		
+	TEST(iUsb.GetPersonalityIds(personalityIds)==KErrNoMemory);
+	personalityIds.Close();
+	__UHEAP_RESET;
+
+	__UHEAP_FAILNEXT(1);
+	RArray<TUid>uids;		
+	TEST(iUsb.GetSupportedClasses(personalityId, uids)==KErrNoMemory);
+	uids.Close();
+	
+	__UHEAP_RESET;
+#else
+	SetTestStepResult(EPass);
+#endif
+
+	return TestStepResult();
+	}	
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CUsbMsComponentTest.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,130 @@
+/*
+* 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 "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:
+* Example CTestStep derived implementation
+*
+*/
+
+/**
+ @file 
+*/
+#include <test/testexecutelog.h>
+#include "CUsbMsComponentTest.h"
+
+
+/**
+ Compare personalities of USB from device with expected result in
+ ini file. The compared fields are: personal IDs, Description
+ and Class control IDs.
+ */
+TVerdict CUsbMsComponentTest::CompareUsbPersonalityL()
+	{
+		
+	//Get Personality IDs from usb server
+	TInt checkStatus;
+	RArray<TInt> idArray;
+	checkStatus = iUsb.GetPersonalityIds(idArray);
+	TEST(checkStatus==KErrNone);
+	
+	// from mmp file
+	TInt expectedPersonalityID = 0x10204bbc;
+		
+	//compare ID with expected result.	
+	TEST(expectedPersonalityID == idArray[0]);		
+	
+	idArray.Close();
+
+	return TestStepResult();
+	}
+
+CUsbMsccGetPersonality::CUsbMsccGetPersonality()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KUsbMsccGetPersonality);
+	}
+
+
+/**
+ @return - TVerdict code
+ Override of base class pure virtual
+ Demonstrates USB device read personality list from resource file 
+ and validate them when RUsb connect to USB server
+ */
+TVerdict CUsbMsccGetPersonality::doTestStepL()
+	{
+	return CompareUsbPersonalityL();
+	}	
+
+
+/**
+ * Constructor
+ */
+CUsbMsccStartStop::CUsbMsccStartStop()
+
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(KUsbMsccStartStop);
+	}
+
+/**
+ @return - TVerdict code
+ Override of base class pure virtual
+ Demonstrates TryStart/TryStop personality at different USB server's state
+ when RUsb connect to USB server
+ */
+TVerdict CUsbMsccStartStop::doTestStepL()
+	{
+	// hard coded
+	TInt deviceCurrentID = 114;
+	TRequestStatus status;
+	TUsbServiceState currentState;
+	
+	RFs fs;
+	// Connect to the server
+    TEST(KErrNone == fs.Connect());
+
+    // Add MS file system
+	_LIT(KMsFs, "MSFS.FSY");
+	TEST(KErrNone == fs.AddFileSystem(KMsFs));
+
+	// Load the logical device
+	_LIT(KDriverFileName,"TESTUSBC.LDD");
+	TInt ret = User::LoadLogicalDevice(KDriverFileName);
+	TEST(KErrNone == ret || KErrAlreadyExists == ret);
+	
+	// call tryStart when server is in the idle state.
+	// the server state should become started
+		
+	iUsb.TryStart(deviceCurrentID,status);
+	User::WaitForRequest(status);
+	TEST(status==KErrNone);
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceStarted==currentState); 
+	
+	// call tryStop when server is in the started state,
+	// the server state should become idle
+	iUsb.TryStop(status );
+	User::WaitForRequest(status);
+	TEST(status == KErrNone);
+	TEST(iUsb.GetServiceState(currentState)==KErrNone);
+	TEST(EUsbServiceIdle ==currentState);
+	
+	fs.Close();
+	
+	User::FreeLogicalDevice(_L("usbc"));
+		
+	return TestStepResult();
+	}	
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/CUsbTestStepBase.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,223 @@
+/*
+* 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 "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
+*/
+#include <test/testexecutelog.h>
+#include "CUsbTestStepBase.h"
+
+CUsbTestStepBase::CUsbTestStepBase():
+	iDoNotConnect(EFalse),
+	iConnected(EFalse),
+	iStopService(ETrue)
+	{
+	}
+
+TVerdict CUsbTestStepBase::doTestStepPreambleL()
+/**
+ * @return - TVerdict code
+ * Override of base class virtual
+ */
+	{
+	__UHEAP_MARK;
+	SetTestStepResult(EPass);
+	
+	if (!iDoNotConnect)
+		{
+		TInt res = iUsb.Connect();
+		if (res != KErrNone)
+			{
+			INFO_PRINTF2(_L("Error connecting to USB service: %d"), res);
+			SetTestStepResult(EFail);
+			return TestStepResult();
+			}
+		iConnected = ETrue;
+		}
+	return TestStepResult();
+	}
+
+TVerdict CUsbTestStepBase::doTestStepPostambleL()
+/**
+ * @return - TVerdict code
+ * Override of base class virtual
+ */
+	{
+	if (iStopService && iConnected)
+		{
+		TRequestStatus status;
+		iUsb.Stop(status);
+		User::WaitForRequest(status);
+		}
+	if (iConnected)
+		{
+		iUsb.Close();
+		}
+	__UHEAP_MARKEND;
+	return TestStepResult();
+	}
+
+TInt CUsbTestStepBase::CheckState(RUsb sess, TUsbServiceState aState)
+	{
+	TUsbServiceState currState;
+	TInt err;
+	err = sess.GetServiceState(currState);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("GetServiceState returned error code %d"), err);
+		return err;
+		}
+	if (currState != aState)
+		{
+		INFO_PRINTF3(_L("GetServiceState returned unexpected state %d, expected was: %d"), currState, aState);
+		return KErrGeneral;
+		}
+	return KErrNone;
+	}
+
+TInt CUsbTestStepBase::SetIdle(RUsb sess)
+	{
+	TRequestStatus status;
+	TUsbServiceState currState;
+	TInt err;
+	err = sess.GetServiceState(currState);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("GetServiceState returned error code %d"), err);
+		return err;
+		}
+	if (currState == EUsbServiceIdle)
+		{
+		return KErrNone;
+		}
+	
+	sess.Stop(status);
+	User::WaitForRequest(status);
+	if (status != KErrNone)
+		{
+		INFO_PRINTF2(_L("Unable to stop service: %d"), status.Int());
+		return status.Int();
+		}
+	return KErrNone;
+	}
+
+TInt CUsbTestStepBase::SetStarted(RUsb sess)
+	{
+	TRequestStatus status;
+	TUsbServiceState currState;
+	TInt err;
+	err = sess.GetServiceState(currState);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("GetServiceState returned error code %d"), err);
+		return err;
+		}
+	if (currState == EUsbServiceStarted)
+		{
+		return KErrNone;
+		}
+	
+	sess.Start(status);
+	User::WaitForRequest(status);
+	if (status != KErrNone)
+		{
+		INFO_PRINTF2(_L("Unable to start service: %d"), status.Int());
+		return status.Int();
+		}
+	return KErrNone;
+	}
+
+TInt CUsbTestStepBase::SetStarting(RUsb sess)
+	{
+	TRequestStatus status;
+	TUsbServiceState currState;
+	TInt err;
+	err = sess.GetServiceState(currState);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("GetServiceState returned error code %d"), err);
+		return err;
+		}
+	if (currState == EUsbServiceStarting)
+		{
+		return KErrNone;
+		}
+	
+	if (currState == EUsbServiceStarted)
+		{
+		sess.Stop(status);
+		User::WaitForRequest(status);
+		if (status != KErrNone)
+			{
+			INFO_PRINTF2(_L("Unable to stop service: %d"), status.Int());
+			return status.Int();
+			}
+		if (CheckState(sess, EUsbServiceIdle) != KErrNone)
+			{
+				INFO_PRINTF1(_L("Can't set state to EUsbServiceIdle"));
+				return KErrGeneral;
+			}
+		}
+	
+	//Start and don't wait for request, otherwise the state will be "started"
+	sess.Start(status);
+	sess.CancelInterest(RUsb::EStart);
+	User::WaitForRequest(status);
+	
+	return KErrNone;
+	}
+	
+TInt CUsbTestStepBase::SetStopping(RUsb sess)
+	{
+	TRequestStatus status;
+	TUsbServiceState currState;
+	TInt err;
+	err = sess.GetServiceState(currState);
+	if (err != KErrNone)
+		{
+		INFO_PRINTF2(_L("GetServiceState returned error code %d"), err);
+		return err;
+		}
+	if (currState == EUsbServiceStopping)
+		{
+		return KErrNone;
+		}
+	
+	if (currState == EUsbServiceIdle)
+		{
+		sess.Start(status);
+		User::WaitForRequest(status);
+		if (status != KErrNone)
+			{
+			INFO_PRINTF2(_L("Unable to start service: %d"), status.Int());
+			return status.Int();
+			}
+		if (CheckState(sess, EUsbServiceStarted) != KErrNone)
+			{
+			INFO_PRINTF1(_L("Can't set state to EUsbServiceStarted"));
+			return KErrGeneral;
+			}
+		}
+	
+	//Stop and don't wait for request, otherwise the state will be "idle"
+	sess.Stop(status);
+	sess.CancelInterest(RUsb::EStop);
+	User::WaitForRequest(status);
+	
+	return KErrNone;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/T_UsbManagerServer.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,179 @@
+/*
+* Copyright (c) 1997-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:
+* Example file/test code to demonstrate how to develop a TestExecute Server
+* Developers should take this project as a template and substitute their own
+* code at the __EDIT_ME__ tags
+* for (WINS && !EKA2) versions will be xxxServer.Dll and require a thread to be started
+* in the process of the client. The client initialises the server by calling the
+* one and only ordinal.
+*
+*/
+
+/**
+ @file 
+*/
+#include "T_UsbManagerServer.h"
+#include "CCancelStartInterest.h"
+#include "CCancelStopInterest.h"
+#include "CStartPersonality.h"
+#include "CStopPersonality.h"
+#include "CStartNewPersonality.h"
+#include "CSimCablePulling.h"
+#include "CStartStopPersonality.h"
+#include "CUsbComponentTest.h"
+#include "CUsbMsComponentTest.h"
+
+
+_LIT(KServerName,"T_UsbManagerServer");
+
+CUsbManagerServer* CUsbManagerServer::NewL()
+/**
+ * @return - Instance of the test server
+ * Called inside the MainL() function to create and start the
+ * CTestServer derived server.
+ */
+	{
+
+	CUsbManagerServer * server = new (ELeave) CUsbManagerServer();
+	CleanupStack::PushL(server);
+	
+	// Either use a StartL or ConstructL, the latter will permit
+	// Server Logging.
+
+	server->StartL(KServerName); 
+	//server-> ConstructL(KServerName);
+	CleanupStack::Pop(server);
+	return server;
+	}
+
+// EKA2 much simpler
+// Just an E32Main and a MainL()
+LOCAL_C void MainL()
+/**
+ * Much simpler, uses the new Rendezvous() call to sync with the client
+ */
+	{
+	// Leave the hooks in for platform security
+#if (defined __DATA_CAGING__)
+	RProcess().DataCaging(RProcess::EDataCagingOn);
+	RProcess().SecureApi(RProcess::ESecureApiOn);
+#endif
+	CActiveScheduler* sched=NULL;
+	sched=new(ELeave) CActiveScheduler;
+	CActiveScheduler::Install(sched);
+
+	CUsbManagerServer* server = NULL;
+	// Create the CTestServer derived server
+
+	TRAPD(err,server = CUsbManagerServer::NewL());
+	if(!err)
+		{
+		// Sync with the client and enter the active scheduler
+		RProcess::Rendezvous(KErrNone);
+		sched->Start();
+		}
+	delete server;
+	delete sched;
+	}
+
+// Only a DLL on emulator for typhoon and earlier
+
+GLDEF_C TInt E32Main()
+/**
+ * @return - Standard Epoc error code on exit
+ */
+	{
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	if(cleanup == NULL)
+		{
+		return KErrNoMemory;
+		}
+	TRAP_IGNORE(MainL());
+	delete cleanup;
+	return KErrNone;
+    }
+
+// Create a thread in the calling process
+// Emulator typhoon and earlier
+
+
+CTestStep* CUsbManagerServer::CreateTestStep(const TDesC& aStepName)
+/**
+ * @return - A CTestStep derived instance
+ * Implementation of CTestServer pure virtual
+ */
+	{
+	CTestStep* testStep = NULL;
+	// __EDIT_ME__ - Create your own test steps here
+	// This server creates just one step but create as many as you want
+	// They are created "just in time" when the worker thread is created
+
+
+	if(aStepName == KCancelStartInterest)
+		testStep = new CCancelStartInterest();
+	if(aStepName == KCancelStopInterest)
+		testStep = new CCancelStopInterest();
+	if(aStepName == KStartPersonality)
+		testStep = new CStartPersonality();
+	if(aStepName == KStopPersonality)
+		testStep = new CStopPersonality();
+	if(aStepName == KStartNewPersonality)
+		testStep = new CStartNewPersonality();
+	if(aStepName == KSimCablePulling)
+		testStep = new CSimCablePulling();
+	if(aStepName == KStartStopPersonality1)
+		testStep = new CStartStopPersonality1();
+	if(aStepName == KStartStopPersonality2)
+		testStep = new CStartStopPersonality2();
+	
+	if(aStepName == KUsbLoadPersonalityNormal)
+		testStep = new CUsbLoadPersonalityNormal();
+	
+	if(aStepName == KUsbLoadPersonalityAbNormal)
+		testStep = new CUsbLoadPersonalityAbNormal();
+	
+	if(aStepName == KUsbLoadPersonalityMissing)
+		testStep = new CUsbLoadPersonalityMissing();
+	
+	if(aStepName == KUsbTestOOM)
+		testStep = new CUsbTestOOM();
+	
+	if(aStepName == KUsbSwitchPersonalityNormal)
+		testStep = new CUsbSwitchPersonalityNormal();
+	
+	if(aStepName == KUsbSwitchPersonalityAbNormal)
+		testStep = new CUsbSwitchPersonalityAbNormal();
+	
+	if(aStepName == KUsbStartStopPersonality1)
+		testStep = new CUsbStartStopPersonality1();
+	
+	if(aStepName == KUsbStartStopPersonality2)
+		testStep = new CUsbStartStopPersonality2();
+	
+	if(aStepName == KUsbStartStopPersonality3)
+		testStep = new CUsbStartStopPersonality3();
+	
+	if(aStepName == KMemAllocationFailure)
+		testStep = new CMemAllocationFailure();
+	
+	if(aStepName == KUsbMsccGetPersonality)
+		testStep = new CUsbMsccGetPersonality();
+	
+	if(aStepName == KUsbMsccStartStop)
+		testStep = new CUsbMsccStartStop();
+		
+	return testStep;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/src/t_usbms_cable_detect.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,506 @@
+/*
+* 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 "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:
+* Part of Base Test - F32 Test Suite
+* SYMTestCaseID Cable_plug_unplug
+* SYMTestCaseDesc Test mass storage system behavior on USB cable 
+* plug-in/plug-out (automated integration test)
+* To run the test, invoke
+* t_usbms_cable_detect X
+* where X is the appropriate mass storage drive letter.
+* Notes: 
+* - This test does not work on the emulator due to LDD requirements.
+* - The USB cable must be connected to a host.
+* Test sequence:
+* - (USB/MS intialisation)
+* - Wait for DriveStatus = Connecting
+* - Dismount FAT, Mount MSFS
+* - Wait for DriveStatus = Connected
+* - Simulate cable disconnection
+* - Wait for USB Status != Configured
+* - Dismount MSFS, Mount FAT
+* - Wait for DriveStatus = Disconnected
+* - Simulate cable re-connection
+* - Wait for DriveStatus = Connecting
+* - Dismount FAT, Mount MSFS
+* - Wait for DriveStatus = Connected
+* - Simulate cable disconnection
+* - Wait for USB Status != Configured
+* - Dismount MSFS, Mount FAT
+* - (USB/MS shutdown)
+* This test program includes a 3 minute timeout to ensure that 
+* it does not hang in case of failure.
+*
+*/
+
+/**
+ @file
+ @publishedPartner
+*/
+
+// This test code is based on usbmsapp and shares its class declarations.
+#include "../../../usbmsapp/usbmsapp.h"
+
+#include <e32std.h>
+#include <e32svr.h>
+#include <f32file.h>
+#include <usbman.h>
+#include <e32test.h>
+#include <d32usbc.h>
+#include <usbmsshared.h>
+
+
+_LIT(KTxtApp,"USBMSCABLEDETECT");
+LOCAL_D RTest test(_L("USBMSCABLE"));
+
+#ifndef __WINS__
+
+_LIT(KMsFsy, "MSFS.FSY");
+_LIT(KMsFs, "MassStorageFileSystem");
+_LIT(KOk,"OK");
+_LIT(KError,"Error");
+
+LOCAL_D RFs fs;
+LOCAL_D RDevUsbcClient ldd;
+LOCAL_D TDriveNumber selectedDriveNumber = EDriveA;
+LOCAL_D TInt selectedDriveIndex = -1;
+LOCAL_D TFileName gOldFileSysName;
+
+LOCAL_C void MountMsFs(RUsb& aUsb, TInt driveNumber)
+	{
+	test.Printf(_L("MountMsFs driveNumber=%d\n"), driveNumber); 
+
+	TInt error = fs.FileSystemName(gOldFileSysName, driveNumber);
+	test(error==KErrNone);
+
+    error = fs.DismountFileSystem(gOldFileSysName, driveNumber);
+   	test.Printf(_L("%S Dismount %c: %S (%d)\n"), &gOldFileSysName,
+	   		'A' + driveNumber, (error?&KError:&KOk), error);
+	
+	error = fs.MountFileSystem(KMsFs, driveNumber);
+	test.Printf(_L("MSFS Mount %c:   %S (%d)"), 
+		'A' + driveNumber, (error?&KError:&KOk), error);
+		
+	if(error!=KErrNone)
+		{
+		test.Printf(_L("Failed to mount Mass Storage (%d), shutting down.\n"), error); 
+		TRequestStatus status;
+		aUsb.TryStop(status);
+		User::WaitForRequest(status);
+		test(false);
+		}
+	}
+
+LOCAL_C void UnmountMsFs(RUsb& aUsb, TInt driveNumber)
+	{
+	test.Printf(_L("UnmountMsFs driveNumber=%d\n"), driveNumber); 
+
+	TInt error = fs.DismountFileSystem(KMsFs, driveNumber);
+	test.Printf(_L("MSFS Dismount:%S (%d)\n"), (error?&KError:&KOk), error);
+	if(error!=KErrNone)
+		{
+		test.Printf(_L("Failed to dismount Mass Storage (%d), shutting down.\n"), error); 
+		TRequestStatus status;
+		aUsb.TryStop(status);
+		User::WaitForRequest(status);
+		test(false);
+		}
+
+	error = fs.MountFileSystem(gOldFileSysName, driveNumber);
+   	test.Printf(_L("%S Mount:    %S (%d)\n"), 
+   				&gOldFileSysName, (error?&KError:&KOk), error);
+	}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// CPropertyWatch
+// An active object that tracks changes to the KUsbMsDriveState properties
+//
+//////////////////////////////////////////////////////////////////////////////
+
+CPropertyWatch* CPropertyWatch::NewLC(TUsbMsDriveState_Subkey aSubkey, PropertyHandlers::THandler aHandler)
+	{
+	CPropertyWatch* me=new(ELeave) CPropertyWatch(aHandler);
+	CleanupStack::PushL(me);
+	me->ConstructL(aSubkey);
+	return me;
+	}
+
+CPropertyWatch::CPropertyWatch(PropertyHandlers::THandler aHandler)
+	: CActive(CActive::EPriorityStandard), iHandler(aHandler)
+	{}
+
+void CPropertyWatch::ConstructL(TUsbMsDriveState_Subkey aSubkey)
+	{
+	User::LeaveIfError(iProperty.Attach(KUsbMsDriveState_Category, aSubkey));
+	CActiveScheduler::Add(this);
+	// initial subscription and process current property value
+	RunL();
+	}
+
+CPropertyWatch::~CPropertyWatch()
+	{
+	Cancel();
+	iProperty.Close();
+	}
+
+void CPropertyWatch::DoCancel()
+	{
+	iProperty.Cancel();
+	}
+
+void CPropertyWatch::RunL()
+	{
+	iHandler(iProperty);
+
+	iProperty.Subscribe(iStatus);
+	SetActive();
+	}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// CUsbWatch
+//
+//////////////////////////////////////////////////////////////////////////////
+
+CUsbWatch* CUsbWatch::NewLC(RUsb& aUsb)
+	{
+	CUsbWatch* me=new(ELeave) CUsbWatch(aUsb);
+	CleanupStack::PushL(me);
+	me->ConstructL();
+	return me;
+	}
+
+CUsbWatch::CUsbWatch(RUsb& aUsb)
+	: 
+	CActive(CActive::EPriorityStandard), 
+	iUsb(aUsb),
+	iUsbDeviceState(EUsbDeviceStateUndefined)
+	{}
+
+void CUsbWatch::ConstructL()
+	{
+	CActiveScheduler::Add(this);
+	RunL();
+	}
+
+CUsbWatch::~CUsbWatch()
+	{
+	Cancel();
+	}
+
+void CUsbWatch::DoCancel()
+	{
+	iUsb.DeviceStateNotificationCancel();
+	}
+
+static TBool IsDriveConnected(TInt driveStatusIndex)
+	{
+	TInt driveStatus = PropertyHandlers::allDrivesStatus[2*driveStatusIndex+1];
+	return driveStatus == EUsbMsDriveState_Connected 
+		|| driveStatus >= EUsbMsDriveState_Active;
+	}
+
+void CUsbWatch::RunL()
+	{
+	static TBool done = EFalse;
+	
+	test.Printf(_L("CUsbWatch DeviceStateNotification: status=%d state=%d\n"), 
+						iStatus.Int(), iUsbDeviceState);
+	
+	if(iUsbDeviceState != EUsbDeviceStateConfigured)
+		{
+		// note this may be called before selectedDriveIndex is initialised
+		if(selectedDriveIndex!=-1 && IsDriveConnected(selectedDriveIndex))
+			{
+			test.Printf(_L("CUsbWatch calling UnmountMsFs\n"));
+			UnmountMsFs(iUsb, selectedDriveNumber);	
+
+			// stop only the second time we get here
+			if(done) CActiveScheduler::Stop();
+			done = ETrue;
+			}
+		}
+	else
+		{
+		if(selectedDriveIndex!=-1 && !IsDriveConnected(selectedDriveIndex))
+			{
+			test.Printf(_L("CUsbWatch calling MountMsFs\n"));
+			MountMsFs(iUsb, selectedDriveNumber);	
+			}
+		}
+	const TUint stateMask = 0xFF;
+	iUsb.DeviceStateNotification(stateMask, iUsbDeviceState, iStatus);
+	SetActive();
+	}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// PropertyHandlers (declared in usbmsapp.h)
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// Unused members
+TUsbMsBytesTransferred PropertyHandlers::iKBytesRead;
+TUsbMsBytesTransferred PropertyHandlers::iKBytesWritten;
+void PropertyHandlers::Read(RProperty& ) {}
+void PropertyHandlers::Written(RProperty& ) {}
+void PropertyHandlers::Transferred(RProperty& , TUsbMsBytesTransferred& ) {}
+
+
+TUsbMsDrivesStatus PropertyHandlers::allDrivesStatus;
+	
+void PropertyHandlers::DriveStatus(RProperty& aProperty)
+	{
+	static TBool hasBeenConnected = EFalse;
+	static TInt lastSelectedDriveStatus = -1;
+		
+	TInt err = aProperty.Get(allDrivesStatus);
+	if(err == KErrNone)
+		{
+		for(TInt i=0; i<allDrivesStatus.Length()/2; i++)
+			{
+			TInt driveNumber = allDrivesStatus[2*i];
+			TInt driveStatus = allDrivesStatus[2*i+1];
+			TUint16 driveLetter = static_cast<TUint16>(driveNumber-EDriveA+'A');
+			test.Printf(_L("PropertyHandlers::DriveStatus: drive %c: = %d\n"), 
+						driveLetter, driveStatus);
+			
+			if(driveNumber == selectedDriveNumber)
+				{
+				selectedDriveIndex = i;
+				
+				if(driveStatus != lastSelectedDriveStatus)
+				switch(driveStatus)
+					{
+					case EUsbMsDriveState_Connecting:
+						test.Printf(_L("EUsbMsDriveState_Connecting: don't care\n"));
+						break;
+					case EUsbMsDriveState_Disconnecting:
+						test.Printf(_L("EUsbMsDriveState_Disconnecting: don't care\n"));
+						break;
+					case EUsbMsDriveState_Disconnected:
+						if(hasBeenConnected)
+							{
+							test.Printf(_L("EUsbMsDriveState_Disconnected: connecting cable (DeviceConnectToHost)\n"));
+							test(KErrNone == ldd.DeviceConnectToHost());
+							}
+						break;
+					case EUsbMsDriveState_Connected:
+					case EUsbMsDriveState_Active:
+					case EUsbMsDriveState_Locked:
+						hasBeenConnected = ETrue;
+						test.Printf(_L("DriveStatus: disconnecting cable (DeviceDisconnectFromHost)\n"));
+						test(KErrNone == ldd.DeviceDisconnectFromHost());
+						break;
+					default:
+						test.Printf(_L("DriveStatus: Error or media removed\n"));
+						test(false);
+					}
+					
+				lastSelectedDriveStatus = driveStatus;
+
+				break; // found the drive
+				}
+			}
+		}
+	else
+		{
+		test.Printf(_L("DriveStatus error=%d\n"), err);
+		test(false);
+		}
+	}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Timeout, to ensure test doesn't hang
+//
+//////////////////////////////////////////////////////////////////////////////
+class CTimeout : public CTimer
+	{
+public:
+	static CTimeout* NewLC()
+		{
+		CTimeout* self = new (ELeave) CTimeout;
+		CleanupStack::PushL(self);
+		self->ConstructL();
+		return self;
+		}
+protected:
+	void ConstructL()
+		{
+		CTimer::ConstructL();
+		CActiveScheduler::Add(this);
+		After(180*1000*1000);
+		}
+	CTimeout() : CTimer(0) 
+		{
+		}
+	void RunL() 
+		{
+		test.Printf(_L("Test did not complete within timeout period.\n"));
+		test(false);
+		}
+	void DoCancel() 
+		{
+		}
+	};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Application entry point
+//
+//////////////////////////////////////////////////////////////////////////////
+LOCAL_C void RunAppL()
+	{
+    TInt error = KErrUnknown;
+	TRequestStatus status;
+
+	// Command line: the massstorage drive letter
+	TBuf<0x40> cmdLine;
+	User::CommandLine(cmdLine);
+	
+	cmdLine.UpperCase();
+	if(cmdLine.Length() != 1 
+		|| cmdLine[0] < 'A'
+		|| cmdLine[0] > 'Z')
+		{
+		test.Printf(_L("You must specify a drive [A-Z|a-z] on the command line\n"));
+		test(false);
+		}
+		
+	selectedDriveNumber = (TDriveNumber)(cmdLine[0] - 'A');
+	test.Printf(_L("Selected drive: %S\n"), &cmdLine);
+
+	CActiveScheduler* sched = new(ELeave) CActiveScheduler;
+	CleanupStack::PushL(sched);
+	CActiveScheduler::Install(sched);
+
+	// Ensure test cannot hang
+	CTimeout::NewLC();
+
+	test(KErrNone==fs.Connect());
+	CleanupClosePushL(fs);
+
+	// Add MS file system
+	error = fs.AddFileSystem(KMsFsy);
+	if(error != KErrNone && error != KErrAlreadyExists)
+		{
+		test.Printf(_L("AddFileSystem failed, err=%d\n"), error);
+		User::Leave(error);
+		}
+   	test.Printf(_L("MSFS file system: Added OK\n"));
+
+	RUsb usb;
+	error = usb.Connect();
+	User::LeaveIfError(error);
+	CleanupClosePushL(usb);
+	
+    // Find the personality that supports the massstorage UID
+	TInt personalityId=-1;
+	RArray<TInt> personalityIds;
+	usb.GetPersonalityIds(personalityIds);
+	for (TInt i=0; i < personalityIds.Count(); i++)
+	    {
+    	TBool supported=EFalse;
+        usb.ClassSupported(personalityIds[i], KUsbMsClassControllerUID, supported);
+
+        HBufC* localizedPersonalityDescriptor;
+        usb.GetDescription(personalityIds[i],localizedPersonalityDescriptor);
+        test.Printf(_L("USB Class Controller id=%d - '%S'\n"), 
+        	personalityIds[i], localizedPersonalityDescriptor);
+
+        if(supported)
+        	{
+        	personalityId = personalityIds[i];	
+        	}
+        delete localizedPersonalityDescriptor;
+		}
+	personalityIds.Close();
+
+	if(personalityId != -1)
+		{
+		usb.TryStart(personalityId, status);
+		User::WaitForRequest(status);
+		test(KErrNone == status.Int());
+		
+		TUsbServiceState currentState;
+		test(KErrNone == usb.GetServiceState(currentState));
+		if(EUsbServiceStarted != currentState)
+			{
+			test.Printf(_L("USB Service did not start\n"));
+			test(false);
+			}
+		test.Printf(_L("USB Service Started, personality id=%d\n"), personalityId);
+		}
+	else
+		{
+		test.Printf(_L("USB: USBMS personality 10204bbc not found\n"));
+		test(false);
+		}
+
+	error = ldd.Open(0);
+    test(KErrNone == error);	
+	CleanupClosePushL(ldd);
+
+	CPropertyWatch::NewLC(EUsbMsDriveState_DriveStatus, PropertyHandlers::DriveStatus);
+	CUsbWatch::NewLC(usb);
+		
+	CActiveScheduler::Start();
+
+	usb.TryStop(status);
+	User::WaitForRequest(status);
+	test.Printf(_L("USB TryStop returned %d\n"), status.Int());
+
+	error = fs.RemoveFileSystem(KMsFs);
+	test.Printf(_L("RemoveFileSystem returned %d\n"), error);
+
+	CleanupStack::PopAndDestroy();	// CUsbWatch
+	CleanupStack::PopAndDestroy();	// CPropertyWatch
+	CleanupStack::PopAndDestroy(&ldd);
+	CleanupStack::PopAndDestroy(&usb);
+	CleanupStack::PopAndDestroy(&fs);
+	CleanupStack::PopAndDestroy();	// CTimeout
+	CleanupStack::PopAndDestroy(sched);
+	}
+#endif //__WINS__
+
+
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup=CTrapCleanup::New();
+	
+	test.Start(KTxtApp);
+
+#ifdef __WINS__
+	test.Printf(_L("This test cannot be run on WINS.\n"));
+#else
+	
+	TRAPD(error, RunAppL());
+	if (error) 
+		{
+		test.Printf(_L("Leave occurred; code=%d\n"), error);
+		test(false);
+		}
+	
+#endif //__WINS__
+
+	test.End();	// output success/fail
+	test.Close();
+	
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return 0;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/testdata/stub1cctest.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,20 @@
+; Copyright (c) 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:
+; 
+;
+[0x10203285]
+StopDelay= 500
+StartDelay= 1000
+FailToStart= 1
+FailToStop= 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/testdata/t_usbmancomponent.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,91 @@
+; Copyright (c) 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:
+; 
+;
+[UsbLoadPersonalityNormal]
+personalityCount=3;
+Id1=113
+classCount1=3;
+classID11=10203285;
+classID12=10203287;
+classID13=10203289;
+Description1=localized personality description
+Id2=2
+classCount2=2;
+classID21=10203287;
+classID22=10203289;
+Description2=localized personality description
+Id3=114
+classCount3=1;
+classID31=10204bbc;
+Description3=USB Mass Storage
+
+[UsbTestOOM]
+personalityCount=3;
+Id1=113
+classCount1=3;
+classID11=10203285;
+classID12=10203287;
+classID13=10203289;
+Description1=localized personality description
+Id2=2
+classCount2=2;
+classID21=10203287;
+classID22=10203289;
+Description2=localized personality description
+Id3=114
+classCount3=1;
+classID31=10204bbc;
+Description3=USB Mass Storage
+
+[UsbSwitchPersonalityNormal]
+Id1=113
+classCount1=3;
+classID11=10203285;
+classID12=10203287;
+classID13=10203289;
+Description1=localized personality description
+Id2=2
+classCount2=2;
+classID21=10203287;
+classID22=10203289;
+Description2=localized personality description
+
+[UsbSwitchPersonalityAbNormal]
+goodId1=113
+goodId2=2
+badId=50
+
+[UsbStartStopPersonality1]
+IdFail=113
+classCount1=3;
+classID11=10203285;
+classID12=10203287;
+classID13=10203289;
+Description1=localized personality description
+IdGood=2
+classCount2=2;
+classID21=10203287;
+classID22=10203289;
+Description2=localized personality description
+
+[UsbStartStopPersonality2]
+IdGood=113
+
+
+[UsbStartStopPersonality3]
+timeout= 60
+
+[UsbLoadPersonalityMissing]
+Id=113
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/testdata/t_usbmanintegration.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+; Copyright (c) 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:
+; 
+;
+[T_CancelInterest]
+personality= 2
+timeout= 60
+
+[T_StartStopPersonality]
+personality1= 2
+personality2= 113
+
+[T_StartNewPersonality1]
+personality= 2
+
+[T_StartNewPersonality2]
+personality= 113
+
+[T_CablePulling1]
+personality= 2
+wait= 1
+
+[T_CablePulling2]
+personality= 2
+wait= 5
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/T_UsbManager/testdata/usbman1.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,100 @@
+/*
+* Copyright (c) 2003-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:
+* Resource file for usbman configuration.
+*
+*/
+
+/**
+ @file
+*/
+
+NAME USBM
+
+#include <badef.rh>
+#include "usbman.rh"
+#ifdef LANGUAGE_01 				// UK English  
+ 	#include "usbman_01.rls"	
+#elif LANGUAGE_02 	 				// French  
+ 	#include "usbman_02.rls"	
+#elif defined LANGUAGE_03  		// German
+ 	#include "usbman_03.rls"
+#elif defined LANGUAGE_10  		// US English
+ 	#include "usbman_10.rls"
+#endif      
+
+RESOURCE BA_RSS_SIGNATURE
+	{
+	signature = 0;
+	}
+
+RESOURCE usb_configuration usb_config
+	{
+	}
+
+RESOURCE CLASS_UIDS uids_one
+	{
+	uids = {0x10203285, 0x10203287, 0x10203289};
+	}
+	
+RESOURCE CLASS_UIDS uids_two
+	{
+	uids = {0x10203287, 0x10203289};
+	}
+	
+RESOURCE PERSONALITY_ARRAY device_personalities
+	{
+	personalities = 
+		{
+		PERSONALITY
+			{
+ 			descriptorType = 100;
+			bcdUSB = 101;
+			bcdDeviceClass = 102;
+			bcdDeviceSubClass = 103;
+			protocol = 104;
+			maxPacketSize = 105;
+			numConfigurations = 107;
+			vendorId = 108;
+			productId =109;
+			bcdDevice = 110;
+			manufacturer = per_manufacturer1;
+			product = per_product1;
+			id = 113;					
+			class_uids = uids_one;			
+			description = per_description1;
+			},
+		PERSONALITY
+			{
+ 			descriptorType = 2;
+			bcdUSB = 2;
+			bcdDeviceClass = 2;
+			bcdDeviceSubClass = 2;
+			protocol = 2;
+			maxPacketSize = 256;
+			numConfigurations = 1;
+			vendorId = 2;
+			productId = 2;
+			bcdDevice = 2;
+			manufacturer= per_manufacturer2;
+			product = per_product2;
+			id = 2;					
+			class_uids = uids_two;			
+			description = per_description2;
+			}
+		};
+	}
+					
+			
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* 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 "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:
+* BLD.INF for the t_usbmanager suite
+* BLD.INF for the t_usbmanager suite
+*
+*/
+
+/**
+ @file
+*/
+
+#include "../T_UsbManager/group/bld.inf"
+#include "../mscc/group/bld.inf"
+#include "../Stub1CC/group/bld.inf"
+#include "../Stub2CC/group/bld.inf"
+#include "../Stub3CC/group/bld.inf"
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* 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 "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:
+*
+*/
+
+PRJ_PLATFORMS
+DEFAULT
+
+
+PRJ_TESTEXPORTS
+../scripts/te_msclasscontroller.script	z:/testdata/scripts/te_msclasscontroller.script
+../scripts/te_msclasscontroller.ini		z:/testdata/scripts/te_msclasscontroller.ini
+te_msclasscontroller.iby				/epoc32/rom/include/te_msclasscontroller.iby
+
+PRJ_TESTMMPFILES
+te_msclasscontroller.mmp
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/group/te_msclasscontroller.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef __TE_MSCLASSCONTROLLER_IBY__
+#define __TE_MSCLASSCONTROLLER_IBY__
+
+file=ABI_DIR\BUILD_DIR\te_msclasscontroller.exe		System\bin\te_msclasscontroller.exe
+
+data=ZSYSTEM\..\testdata\scripts\te_msclasscontroller.script testdata\scripts\te_msclasscontroller.script
+data=ZSYSTEM\..\testdata\scripts\te_msclasscontroller.ini testdata\scripts\te_msclasscontroller.ini
+
+data=ZSYSTEM\data\USBMS.RSC system\data\USBMS.RSC
+
+#endif
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/group/te_msclasscontroller.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,54 @@
+/*
+* 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 "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:
+* USB mass storage plugin testexecute server
+*
+*/
+
+/**
+ @file
+*/
+
+
+TARGET			te_msclasscontroller.exe
+TARGETTYPE		exe
+UID			0x1000007A 0x101F7774
+
+// For unit testing private methods
+MACRO		_UNITTEST_DEBUG
+
+SOURCEPATH	../src
+SOURCE		CUsbMsTestStep.cpp
+SOURCE		CUsbMsTestServer.cpp
+
+START RESOURCE usbms.rss
+target te_msclasscontroller.rsc
+END
+
+SOURCEPATH	../../../../usbmgr/device/classdrivers/ms/classcontroller/src
+source		CUsbMsClassController.cpp
+
+
+USERINCLUDE	../inc
+USERINCLUDE	../../../../usbmgr/device/classdrivers/ms/classcontroller/inc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY     	euser.lib
+LIBRARY		testexecuteutils.lib
+LIBRARY		efsrv.lib
+LIBRARY		testexecutelogclient.lib
+LIBRARY		bafl.lib 
+LIBRARY		usbclasscontroller.lib
+
+#include <usb/usblogger.mmh>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/inc/CUsbMsTestServer.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,28 @@
+/*
+* 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 "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:
+*
+*/
+
+#if (!defined __CUSBMSTESTSERVER_H__)
+#define __CUSBMSTESTSERVER_H__
+#include <test/testexecuteserverbase.h>
+		
+class CUsbMsTestServer : public CTestServer
+	{
+public:
+	static CUsbMsTestServer* NewL();
+	virtual CTestStep* CreateTestStep(const TDesC& aStepName);
+	};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/inc/CUsbMsTestStep.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* 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 "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:
+*
+*/
+ 
+#if (!defined __CUSBMSTESTSTEP_H__)
+#define __CUSBMSTESTSTEP_H__
+
+#include <e32std.h>
+#include <test/testexecuteserverbase.h>
+#include "CUsbMsClassController.h"
+
+_LIT(KConfigItemTest, "CConfigItemTest");
+NONSHARABLE_CLASS(CConfigItemTest) : public CTestStep
+	{
+public:
+	inline CConfigItemTest(){SetTestStepName(KConfigItemTest);};
+	virtual TVerdict doTestStepL(void);
+	};
+
+_LIT(KReadMsConfigTest, "CReadMsConfigTest");
+NONSHARABLE_CLASS(CReadMsConfigTest) : public CTestStep
+	{
+public:
+	inline CReadMsConfigTest(){SetTestStepName(KReadMsConfigTest);};
+	virtual TVerdict doTestStepL(void);
+	};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/scripts/te_msclasscontroller.ini	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,35 @@
+; Copyright (c) 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:
+; 
+;
+[ConfigItemShorter]
+origString=short
+expectedString=short
+stringLength = 8;
+
+[ConfigItemLonger]
+origString=longerThanSix
+expectedString=longer
+stringLength = 6;
+
+[ConfigItemEqual]
+origString=equalTo8
+expectedString=equalTo8
+stringLength = 8;
+
+[MsConfig]
+vendorId = vendorId
+productId = productIdIsTooLo
+productRev = rev
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/scripts/te_msclasscontroller.script	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,23 @@
+/*
+* 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 "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:
+*
+*/
+
+LOAD_SUITE te_msclasscontroller
+
+RUN_TEST_STEP 1000 te_msclasscontroller CConfigItemTest z:\testdata\scripts\te_msclasscontroller.ini ConfigItemShorter
+RUN_TEST_STEP 100 te_msclasscontroller CConfigItemTest z:\testdata\scripts\te_msclasscontroller.ini ConfigItemLonger
+RUN_TEST_STEP 100 te_msclasscontroller CConfigItemTest z:\testdata\scripts\te_msclasscontroller.ini ConfigItemEqual
+RUN_TEST_STEP 100 te_msclasscontroller CReadMsConfigTest z:\testdata\scripts\te_msclasscontroller.ini MsConfig
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/src/CUsbMsTestServer.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,110 @@
+/*
+* 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 "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:
+* for (WINS && !EKA2) versions will be xxxServer.Dll and require a thread to be started
+* in the process of the client. The client initialises the server by calling the
+* one and only ordinal.
+*
+*/
+
+/**
+ @internalTechnology 
+*/
+#include "CUsbMsTestServer.h"
+#include "CUsbMsTestStep.h"
+
+_LIT(KServerName, "te_msclasscontroller");
+
+CUsbMsTestServer* CUsbMsTestServer::NewL()
+/**
+ * @return - Instance of the test server
+ * Called inside the MainL() function to create and start the
+ * CTestServer derived server.
+ */
+	{
+	CUsbMsTestServer * server = new (ELeave) CUsbMsTestServer();
+	CleanupStack::PushL(server);
+	// CServer base class call
+	server->StartL(KServerName);
+	CleanupStack::Pop(server);
+	return server;
+	}
+	
+// EKA2 much simpler
+// Just an E32Main and a MainL()
+LOCAL_C void MainL()
+/**
+ * Much simpler, uses the new Rendezvous() call to sync with the client
+ */
+	{
+	// Leave the hooks in for platform security
+#if (defined __DATA_CAGING__)
+	RProcess().DataCaging(RProcess::EDataCagingOn);
+	RProcess().SecureApi(RProcess::ESecureApiOn);
+#endif
+	
+	CActiveScheduler* sched=NULL;
+	sched=new(ELeave) CActiveScheduler;
+	CActiveScheduler::Install(sched);
+	CUsbMsTestServer* server = NULL;
+	// Create the CTestServer derived server
+	TRAPD(err,server = CUsbMsTestServer::NewL());
+	if(!err)
+		{
+		// Sync with the client and enter the active scheduler
+		RProcess::Rendezvous(KErrNone);
+		sched->Start();
+		}
+	delete server;
+	delete sched;
+	}
+
+GLDEF_C TInt E32Main()
+/**
+ * @return - Standard Epoc error code on exit
+ */
+	{
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	if(cleanup == NULL)
+		{
+		return KErrNoMemory;
+		}
+	TRAP_IGNORE(MainL());
+	delete cleanup;
+	return KErrNone;
+    }
+
+// Create a thread in the calling process
+// Emulator typhoon and earlier
+
+CTestStep* CUsbMsTestServer::CreateTestStep(const TDesC& aStepName)
+/**
+ * @return - A CTestStep derived instance
+ * Implementation of CTestServer pure virtual
+ */
+	{
+	CTestStep* testStep = NULL;
+
+	if (aStepName == KConfigItemTest)
+		{
+		testStep = new CConfigItemTest();
+		}
+	else if (aStepName == KReadMsConfigTest)
+		{
+		testStep = new CReadMsConfigTest();
+		}	
+
+	return testStep;
+	}
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/src/CUsbMsTestStep.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,104 @@
+/*
+* 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 "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 <e32std.h>
+#include <cusbclasscontrolleriterator.h>
+#include "CUsbMsTestStep.h"
+#include <musbclasscontrollernotify.h>
+
+class TNotify : public MUsbClassControllerNotify
+	{
+	CUsbClassControllerIterator* UccnGetClassControllerIteratorL(){return 0;}			
+	void UccnError(TInt /*Error*/){}
+	} owner;
+	
+TVerdict CConfigItemTest::doTestStepL()
+	{
+	INFO_PRINTF1(_L("CConfigItemTest::doTestStepL"));
+	SetTestStepResult(EPass);
+
+	TPtrC origString;
+	TPtrC expectedString;
+	TInt stringLength;
+	if(	!GetStringFromConfig(ConfigSection(), _L("origString"), origString) ||
+	   	!GetStringFromConfig(ConfigSection(), _L("expectedString"), expectedString) ||
+	   	!GetIntFromConfig(ConfigSection(), _L("stringLength"), stringLength))
+		{
+		INFO_PRINTF1(_L("Failed to get init data"));
+		SetTestStepResult(EFail);
+		return TestStepResult();
+		}
+
+	// Create an active scheduler
+	CActiveScheduler* sched = new(ELeave) CActiveScheduler;
+	CleanupStack::PushL(sched);
+	CActiveScheduler::Install(sched);
+
+	CUsbMsClassController* controller = CUsbMsClassController::NewL(owner);
+	
+	CleanupStack::PopAndDestroy(sched);
+	
+	TBuf<64> copiedString;
+	controller->ConfigItem(origString, copiedString, stringLength);
+	delete controller;
+
+	TEST(copiedString.Compare(expectedString) == 0);
+
+	return TestStepResult();
+	}
+
+TVerdict CReadMsConfigTest::doTestStepL()
+	{
+	INFO_PRINTF1(_L("CReadMsConfigTest::doTestStepL"));
+	SetTestStepResult(EPass);
+	
+	TPtrC vendorId;
+	TPtrC productId;
+	TPtrC productRev;
+	
+	if(	!GetStringFromConfig(ConfigSection(), _L("vendorId"), vendorId) ||
+	   	!GetStringFromConfig(ConfigSection(), _L("productId"), productId) ||
+	   	!GetStringFromConfig(ConfigSection(), _L("productRev"), productRev))
+		{
+		INFO_PRINTF1(_L("Failed to get init data"));
+		SetTestStepResult(EFail);
+		return TestStepResult();
+		}
+	
+	// Create an active scheduler
+	CActiveScheduler* sched = new(ELeave) CActiveScheduler;
+	CleanupStack::PushL(sched);
+	CActiveScheduler::Install(sched);
+	
+	CUsbMsClassController* controller = CUsbMsClassController::NewL(owner);
+	CleanupStack::PushL(controller);
+	
+	controller->ReadMassStorageConfigL();
+	
+	// Do comparison
+	TEST(controller->iMsConfig.iVendorId.Compare(vendorId) == 0 &&
+		controller->iMsConfig.iProductId.Compare(productId) == 0  &&
+		controller->iMsConfig.iProductRev.Compare(productRev) == 0);
+
+		
+	// controller and sched
+	CleanupStack::PopAndDestroy(2);
+	
+	return TestStepResult();
+	}
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/mscc/src/usbms.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,39 @@
+/*
+* 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 "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:
+* Resource file for the USB mass storage configuration.
+*
+*/
+
+/**
+ @file
+*/
+
+NAME MSCF
+
+#include <badef.rh>
+#include "usbms.rh"
+
+RESOURCE BA_RSS_SIGNATURE
+	{
+	signature = 1;
+	}
+
+RESOURCE USBMASSSTORAGE_CONFIG usbms_config
+	{
+    vendorId    = "vendorId";      			// = max char length (8)
+    productId   = "productIdIsTooLong";  	// > max char length (16)
+    productRev  = "rev";    	    		// < max char length (4)
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmodem/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* 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 "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:
+* BLD.INF for t_usbmodem
+* BLD.INF for t_usbmodem
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+t_usbmodem.iby	/epoc32/rom/include/t_usbmodem.iby
+
+PRJ_TESTMMPFILES
+t_usbmodem.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmodem/group/t_usbmodem.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 2003-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:
+* Test program for serial port
+*
+*/
+
+#ifndef __T_USBMODEM_IBY__
+#define __T_USBMODEM_IBY__
+
+#include <c32.iby>
+
+file=ABI_DIR\DEBUG_DIR\t_usbmodem.exe    System\Programs\t_usbmodem.exe
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmodem/group/t_usbmodem.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+TARGET         t_usbmodem.exe
+TARGETTYPE     EXE
+SOURCEPATH    ../src
+SOURCE         t_usbmodem.cpp
+LIBRARY        euser.lib c32.lib usbman.lib
+LIBRARY         econs.lib
+
+USERINCLUDE    ../inc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmodem/inc/t_usbmodem.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,264 @@
+/*
+* Copyright (c) 2003-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:
+*
+*/
+
+#include <e32test.h>
+#include <e32twin.h>
+#include <c32comm.h>
+#include <d32comm.h>
+#include <usbman.h>
+
+TCommNotificationPckg TheSerialConfigBuf;
+TCommNotificationPckg TheUsbConfigBuf;
+
+TCommNotificationV01 &TheSerialConfig=TheSerialConfigBuf();
+TCommNotificationV01 &TheUsbConfig=TheUsbConfigBuf();
+TInt TheLastError=KErrNone;
+
+static const TInt KMaxBufSize = 4096;
+const TInt KMaxDumpLength=0x100;
+
+enum TTermPanic
+	{
+	EStraySignal,
+	ELoadPhysicalDeviceErr,
+	ELoadLogicalDeviceErr,
+	EOpenErr,
+	EConnectFsErr,
+	ECaptureFileOpen,
+	EOpenUploadFile,
+	};
+
+enum TRxMode
+	{
+	ENormal=0,
+	ELoopBack=1,
+	ECountChars=2,
+	ERxOff=3,
+	ECapture=128,
+	};
+
+NONSHARABLE_STRUCT(SSettings)
+	{
+	TBool iNotFinished;
+	TBool iLocalEcho;
+	TInt iAddLF;
+	TBool iDump;
+	TInt iDumpRepeat;
+	TBuf8<KMaxDumpLength> iDumpData;
+	TRxMode iRxMode;
+	TInt iCharCount;
+	TInt iMaxInOne;
+	TInt iInfraRed;
+	TBool iWaitAfterWrite;
+	// Fifo
+	// Brk
+	};
+
+LOCAL_D SSettings TheSettings;
+LOCAL_D RUsb TheUsbServer;
+LOCAL_D RCommServ TheCommServer;
+LOCAL_D RComm TheUsbPort;
+LOCAL_D RComm TheSerialPort;
+LOCAL_D RConsole TheWindow;
+
+
+#define USBCSY_NAME _L("ECACM")
+#define USBPORT_NAME _L("ACM::0")
+#define SERIALCSY_NAME _L("ECUART")
+#define SERIALPORT_NAME _L("COMM::0")		// second comm port
+
+#define SERIALPDD_NAME _L("EUART1")
+#define SERIALLDD_NAME _L("ECOMM")
+#define USBLDD_NAME _L("EUSBC")
+
+class CDuplex;
+//Base class for simplex transfer activity
+class MTransferNotifier
+	{
+public:
+	virtual void NotifyRead(TInt aErr,TInt aSize, TDes8& aBuf)=0;
+	virtual void NotifyWrite(TInt aErr)=0;
+	};
+
+class CSimplex: public CActive
+	{
+public:
+	void SetTotalAmount(TUint aTotalAmount){iTotalAmount = aTotalAmount;}
+	virtual ~CSimplex(){Cancel();}
+protected:
+	CSimplex(CDuplex& aDuplex):
+		CActive(CActive::EPriorityStandard),iDuplex(aDuplex){}
+	
+protected:
+	TBuf8<KMaxBufSize> iBuffer;
+	CDuplex& iDuplex;
+	TInt iTotalAmount;
+	};
+
+class CSimplexRead: public CSimplex
+	{
+public:
+	static CSimplexRead* NewL(CDuplex& aDuplex);
+	virtual ~CSimplexRead(){}
+	void SetPort(RComm* aPort){iCommPort = aPort;}
+	void StartL();
+protected:
+	CSimplexRead(CDuplex& aDuplex):
+		CSimplex(aDuplex){}
+	virtual void DoCancel(void);
+	void ConstructL();
+	virtual void RunL();
+private:
+	TBuf8<KMaxBufSize> iBuffer;
+	TBool iPortType;
+	RComm* iCommPort;
+	};
+
+class CSimplexWrite: public CSimplex
+	{
+public:
+	static CSimplexWrite* NewL(CDuplex& aDuplex);
+	virtual ~CSimplexWrite(){}
+	void SetPort(RComm* aPort){iCommPort = aPort;}
+	void StartL(TDes8& abuf);
+protected:
+	CSimplexWrite(CDuplex& aDuplex):
+		CSimplex(aDuplex){}
+	virtual void DoCancel(void);
+	void ConstructL();
+	virtual void RunL();
+private:
+	TBool iPortType;
+	RComm* iCommPort;
+	};
+
+class CDuplex : public MTransferNotifier, CBase
+	{
+public:
+	// Construction
+	static CDuplex* NewL();
+	// Destruction
+	void StartL();
+	void Cancel();
+	void NotifyRead(TInt aErr,TInt aSize, TDes8& aBuf);
+	void NotifyWrite(TInt aErr);
+	void SetTxPort(RComm* aPort){iSimplexWrite->SetPort(aPort);}
+	void SetRxPort(RComm* aPort){iSimplexRead->SetPort(aPort);}
+	void SetTotalAmount(TInt aTotalAmount){iSimplexWrite->SetTotalAmount(aTotalAmount);
+											iSimplexRead->SetTotalAmount(aTotalAmount);}
+	virtual ~CDuplex();
+protected:
+	// Construction
+	CDuplex(){};
+	void ConstructL();
+private:
+	CSimplexRead* iSimplexRead;
+	CSimplexWrite* iSimplexWrite;
+	};
+
+class CConfigChangeNotifier: public CActive
+	{
+public:
+	static CConfigChangeNotifier* NewL();
+	~CConfigChangeNotifier(){};
+
+	// Issue request
+	void StartL();
+private:
+	CConfigChangeNotifier();
+	virtual void DoCancel();
+	virtual void RunL();
+	};
+
+class CSignalChangeNotifier: public CActive
+	{
+public:
+	static CSignalChangeNotifier* NewL(TBool aIsusbPort);
+	~CSignalChangeNotifier(){};
+
+	// Issue request
+	void StartL();
+private:
+	CSignalChangeNotifier(TBool aIsusbPort);
+	virtual void DoCancel();
+	virtual void RunL();
+	const TBool iIsUsbPort;
+	TUint iInSignals;
+	};
+
+class CFControlChangeNotifier: public CActive
+	{
+public:
+	static CFControlChangeNotifier* NewL();
+	~CFControlChangeNotifier(){};
+
+	// Issue request
+	void StartL();
+private:
+	CFControlChangeNotifier();
+	virtual void DoCancel();
+	virtual void RunL();
+	TFlowControl iFlowControl;
+	};
+
+
+class CActiveConsole : public CActive
+//-----------------------------------
+	{
+public:
+	// Construction
+	static CActiveConsole* NewLC();
+	static CActiveConsole* NewL();
+	void ConstructL();
+
+	// Destruction
+	~CActiveConsole();
+
+	// Issue request
+	void WaitForKeyPress();
+
+private:
+	// Construction
+	CActiveConsole();
+
+	// Cancel request.
+	// Defined as pure virtual by CActive;
+	// implementation provided by this class.
+	virtual void DoCancel();
+
+	// Service completed request.
+	// Defined as pure virtual by CActive;
+	// implementation provided by this class,
+	virtual void RunL();
+
+	void Start();
+	void ProcessKeyPressL();
+
+private:
+	TBool iIsRunning;
+	TConsoleKey iKeypress;
+	TRequestStatus iBreakRequest;
+	// Data members defined by this class
+	CDuplex*	iUsbToSerial;
+	CDuplex*	iSerialToUsb;
+	CSignalChangeNotifier*	iUsbSignalChangeNotifier;
+	CSignalChangeNotifier*	iSerialSignalChangeNotifier;
+	CFControlChangeNotifier* 		iUsbFControlNotifier;
+	CConfigChangeNotifier*	iUsbConfigChangeNotifier;
+	};
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmodem/src/t_usbmodem.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,966 @@
+/*
+* Copyright (c) 2003-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:
+* This test is used to pipe data to and from the USB ACM comm port to
+* a real comm port connected to a modem.
+*
+*/
+
+#include "t_usbmodem.h"
+#include <e32debug.h>
+
+//
+//--- class CSimplexRead ----------------------------------------------------
+//
+CSimplexRead* CSimplexRead::NewL(CDuplex& aDuplex)
+	{
+	CSimplexRead* self = new (ELeave) CSimplexRead(aDuplex);
+	self->ConstructL();
+	CActiveScheduler::Add(self);
+	return (self);	
+	}
+
+void CSimplexRead::ConstructL()
+	{
+	// Not much to do yet
+	}
+
+void CSimplexRead::StartL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexRead::StartL\n"));
+#endif
+	if(IsActive())
+		{
+		RDebug::Print(_L(": CSimplexRead::StartL Warning - Already active\n"));
+		return;
+		}
+	//iBuffer.SetMax();	
+	iCommPort->ReadOneOrMore(iStatus, iBuffer);
+	SetActive();
+	}
+
+void CSimplexRead::RunL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexRead::RunL - iStatus:%d iBuffer.Length:%d TotalAmount Left:%d\n"),iStatus.Int(),iBuffer.Length(),iTotalAmount);
+#endif
+	//RDebug::Print(_L(">%S<\n"),&iBuffer);
+	//Notify Duplex object
+	iDuplex.NotifyRead(iStatus.Int(),iBuffer.Length(), iBuffer);
+	}
+
+void CSimplexRead::DoCancel(void)
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexRead::DoCancel\n"));
+#endif
+	if(iCommPort)
+		iCommPort->ReadCancel();
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexRead::DoCancel done\n"));
+#endif
+	}
+
+//
+//--- class CSimplexWrite ----------------------------------------------------
+//
+CSimplexWrite* CSimplexWrite::NewL(CDuplex& aDuplex)
+	{
+	CSimplexWrite* self = new (ELeave) CSimplexWrite(aDuplex);
+	self->ConstructL();
+	CActiveScheduler::Add(self);
+	return (self);	
+	}
+
+void CSimplexWrite::ConstructL()
+	{
+	// Not much to do yet
+	}
+
+void CSimplexWrite::StartL(TDes8& aBuf)
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexWrite::StartL - About to write l=%d\n"),aBuf.Length());
+#endif
+	if(IsActive())
+		{
+		RDebug::Print(_L(": CSimplexWrite::StartL Warning - Already active\n"));
+		return;
+		}
+
+	iCommPort->Write(iStatus, aBuf);
+	SetActive();
+	}
+
+void CSimplexWrite::RunL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexWrite::RunL - iStatus:%d"),iStatus.Int());
+#endif
+	//Notify Duplex object
+	iDuplex.NotifyWrite(iStatus.Int());
+	}
+
+void CSimplexWrite::DoCancel(void)
+	{
+	if(iCommPort)
+		iCommPort->WriteCancel();
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexWrite:: Comm port write Canceled\n"));
+#endif
+	}
+
+//
+// --- class CDuplex ---------------------------------------------------------
+//
+CDuplex* CDuplex::NewL()
+	{
+	CDuplex* self = new (ELeave) CDuplex();
+	self->ConstructL();
+	return (self);	
+	}
+
+void CDuplex::ConstructL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CDuplex::ConstructL\n"));
+#endif
+	//Create reader and writer
+	iSimplexRead = CSimplexRead::NewL(*this);
+	iSimplexWrite = CSimplexWrite::NewL(*this);
+	}
+
+void CDuplex::StartL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CDuplex::StartL\n"));
+#endif
+	iSimplexRead->StartL();
+	}
+
+void CDuplex::Cancel()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CDuplex::Cancel\n"));
+#endif
+	if(iSimplexRead)
+		iSimplexRead->Cancel(); 
+	if(iSimplexWrite)
+		iSimplexWrite->Cancel();
+	}
+
+#ifdef _DEBUG
+	void CDuplex::NotifyRead(TInt aErr,TInt aSize, TDes8& aBuf)
+#endif
+
+#ifndef _DEBUG
+	void CDuplex::NotifyRead(TInt aErr,TInt /*aSize*/, TDes8& aBuf)
+#endif
+	{
+	TInt ignoreErr;
+
+	// Check if error
+	switch(aErr)
+		{
+		case KErrNone:
+			// Start the write
+#ifdef _DEBUG
+			RDebug::Print(_L(": CDuplex::NotifyRead err:%d recvd:%d\n"), aErr, aSize);
+#endif
+			TRAP(ignoreErr, iSimplexWrite->StartL(aBuf));
+			break;
+		default:
+#ifdef _DEBUG
+			RDebug::Print(_L(": CDuplex::NotifyRead error:%d\n"), aErr);
+#endif
+			Cancel();
+			break;
+		}
+#ifdef _DEBUG
+	RDebug::Print(_L(": CDuplex::NotifyRead Done \n"), aErr, aSize);
+#endif
+	return;
+	}
+
+void CDuplex::NotifyWrite(TInt aErr)
+	{
+	TInt ignoreErr;
+
+	// Check if error
+	switch(aErr)
+		{
+		case KErrNone:
+			//Not much right now, just trigger another read
+#ifdef _DEBUG
+			RDebug::Print(_L(": CDuplex::NotifyWrite err:%d \n"), aErr);
+#endif
+			TRAP(ignoreErr, iSimplexRead->StartL());
+			break;
+		default:
+#ifdef _DEBUG
+			RDebug::Print(_L(": CDuplex::NotifyWrite error:%d\n"), aErr);
+#endif
+			Cancel();
+			break;
+		}
+#ifdef _DEBUG
+	RDebug::Print(_L(": CDuplex::NotifyWrite Done \n"), aErr);
+#endif
+
+	return;
+	}
+
+CDuplex::~CDuplex()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": Deleting CDuplex\n"));
+#endif
+	Cancel();
+	delete iSimplexRead;
+	delete iSimplexWrite;
+	}
+
+//
+//----- class CConfigChangeNotifier -----------------------------------------
+//
+CConfigChangeNotifier::CConfigChangeNotifier()
+	:CActive(CActive::EPriorityStandard)
+	{
+	}
+
+CConfigChangeNotifier* CConfigChangeNotifier::NewL()
+	{
+	CConfigChangeNotifier* self = new (ELeave) CConfigChangeNotifier();
+	CActiveScheduler::Add(self);				// Add to active scheduler
+	return self;
+	}
+	
+void CConfigChangeNotifier::DoCancel()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CConfigChangeNotifier::DoCancel"));
+#endif
+	TheUsbPort.NotifyConfigChangeCancel();
+	}
+
+void CConfigChangeNotifier::StartL()
+	{
+	if (IsActive())
+		{
+		RDebug::Print(_L(": Config chabge Notifier Already active"));
+		return;
+		}
+	TheUsbPort.NotifyConfigChange(iStatus, TheUsbConfigBuf);
+	SetActive();
+	}
+
+void CConfigChangeNotifier::RunL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": Config Change Notifier activated"));
+#endif
+	// Set the serial port config
+	TCommConfig aConfig;
+	TheUsbPort.Config(aConfig);
+	TheSerialPort.SetConfig(aConfig);
+	StartL();
+	}
+
+//
+//----- class CSignalChageNotifier -----------------------------------------
+//
+CSignalChangeNotifier::CSignalChangeNotifier(TBool aIsUsbPort)
+	:CActive(CActive::EPriorityStandard),
+	iIsUsbPort(aIsUsbPort)
+	{
+	}
+
+CSignalChangeNotifier* CSignalChangeNotifier::NewL(TBool aIsUsbPort)
+	{
+	CSignalChangeNotifier* self = new (ELeave) CSignalChangeNotifier(aIsUsbPort);
+	CActiveScheduler::Add(self);				// Add to active scheduler
+	return self;
+	}
+	
+void CSignalChangeNotifier::DoCancel()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSignalChangeNotifier::DoCancel"));
+#endif
+	if (iIsUsbPort)
+		TheUsbPort.NotifySignalChangeCancel();
+	else 
+		TheSerialPort.NotifySignalChangeCancel();
+	}
+
+void CSignalChangeNotifier::StartL()
+	{
+	if (IsActive())
+		{
+		RDebug::Print(_L(": Signal Notifier Already active"));
+		return;
+		}
+	else if (iIsUsbPort)
+		{
+		RDebug::Print(_L(": Starting Signal Notifier for USB"));
+		TheUsbPort.NotifySignalChange(iStatus, iInSignals, KSignalDCEInputs | KSignalDCEOutputs | KSignalBreak);
+		}
+	else 
+		{
+		RDebug::Print(_L(": Starting Signal Notifier for serial port"));
+		TheSerialPort.NotifySignalChange(iStatus, iInSignals, KSignalDTEInputs);
+		}
+
+	SetActive();
+	}
+
+void CSignalChangeNotifier::RunL()
+	{
+	// if this object is for USB,
+	if (iIsUsbPort)
+		{
+#ifdef _DEBUG
+		RDebug::Print(_L(": Signal Change Notifier activated for USB - %x"), iInSignals);
+#endif
+		if ( iInSignals & KRTSChanged )
+			{
+			if ( iInSignals & KSignalRTS )
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": Serial RTS on"));
+#endif
+				TheSerialPort.SetSignals( KSignalRTS, 0 );
+				//TheUsbPort.SetSignals( KSignalCTS, 0 );
+				}
+			else
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": Serial RTS off"));
+#endif
+				TheSerialPort.SetSignals( 0, KSignalRTS );
+				//TheUsbPort.SetSignals( 0, KSignalCTS );
+				}
+			}
+	
+		if ( iInSignals & KDTRChanged )
+			{
+			if ( iInSignals & KSignalDTR )
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": Serial DTR on"));
+#endif
+				TheSerialPort.SetSignals( KSignalDTR, 0 );
+				//TheUsbPort.SetSignals( KSignalDSR, 0 );
+				}
+			else
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": Serial DTR off"));
+#endif
+				TheSerialPort.SetSignals( 0, KSignalDTR );
+				//TheUsbPort.SetSignals( 0, KSignalDSR );
+				}
+			}
+
+		}
+	else 
+		{
+#ifdef _DEBUG
+		RDebug::Print(_L(": Signal Change Notifier activated for Serial port - %x"), iInSignals);
+#endif
+		if ( iInSignals & KCTSChanged )
+			{
+			if ( iInSignals & KSignalCTS )
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB CTS on"));
+#endif
+				TheUsbPort.SetSignals( KSignalCTS, 0 );
+				}
+			else
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB CTS off"));
+#endif
+				TheUsbPort.SetSignals( 0, KSignalCTS );
+				}
+			}
+		if ( iInSignals & KDSRChanged )
+			{
+			if ( iInSignals & KSignalDSR )
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB DSR on"));
+#endif
+				TheUsbPort.SetSignals( KSignalDSR, 0 );
+				}
+			else
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB DSR off"));
+#endif
+				TheUsbPort.SetSignals( 0, KSignalDSR );
+				}
+			}
+
+		if ( iInSignals & KDCDChanged )
+			{
+				if ( iInSignals & KSignalDCD )
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB DCD on"));
+#endif
+				TheUsbPort.SetSignals( KSignalDCD, 0 );
+				}
+			else
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB DCD off"));
+#endif
+				TheUsbPort.SetSignals( 0, KSignalDCD );
+				}
+			}
+
+		if ( iInSignals & KRNGChanged )
+			{
+			if ( iInSignals & KSignalRNG )
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB RNG on"));
+#endif
+				TheUsbPort.SetSignals( KSignalRNG, 0 );
+				}
+			else
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB RNG off"));
+#endif
+				TheUsbPort.SetSignals( 0, KSignalRNG );
+				}
+			}
+		}
+	StartL();
+	}
+
+//
+//----- class CFControlChangeNotifier -----------------------------------------
+//
+CFControlChangeNotifier::CFControlChangeNotifier()
+	:CActive(CActive::EPriorityStandard)
+	{
+	}
+
+CFControlChangeNotifier* CFControlChangeNotifier::NewL()
+	{
+	CFControlChangeNotifier* self = new (ELeave) CFControlChangeNotifier();
+	CActiveScheduler::Add(self);				// Add to active scheduler
+	return self;
+	}
+	
+void CFControlChangeNotifier::DoCancel()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CFControlChangeNotifier::DoCancel()"));
+#endif
+	TheUsbPort.NotifyFlowControlChangeCancel();
+	}
+
+void CFControlChangeNotifier::StartL()
+	{
+	if (IsActive())
+		{
+		RDebug::Print(_L(": FlowControl Notifier Already active"));
+		return;
+		}
+	TheUsbPort.NotifyFlowControlChange(iStatus, iFlowControl);
+	SetActive();
+	}
+
+void CFControlChangeNotifier::RunL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": FlowControl Notifier activated"));
+#endif
+	StartL();
+	}
+
+//
+// --- class CActiveConsole -------------------------------------------------
+//
+
+CActiveConsole::CActiveConsole()
+	: CActive(CActive::EPriorityStandard),
+	iIsRunning(EFalse)
+	{}
+
+
+CActiveConsole* CActiveConsole::NewLC()
+	{
+	CActiveConsole* self = new (ELeave) CActiveConsole();
+	self->ConstructL();
+	return self;
+	}
+
+
+CActiveConsole* CActiveConsole::NewL()
+	{
+	CActiveConsole* self = NewLC();
+	return self;
+	}
+
+CActiveConsole::~CActiveConsole()
+	{
+	delete iUsbToSerial;
+	delete iSerialToUsb;
+	}
+
+void CActiveConsole::DoCancel()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CActiveConsole::DoCancel()"));
+#endif
+	iUsbConfigChangeNotifier->Cancel();
+	iSerialSignalChangeNotifier->Cancel();
+	iUsbSignalChangeNotifier->Cancel();
+	//iUsbFControlNotifier->Cancel();
+	
+	iUsbToSerial->Cancel();
+	iSerialToUsb->Cancel();
+	
+	iIsRunning = EFalse;
+	}
+
+void CActiveConsole::RunL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CActiveConsole::RunL()"));
+#endif
+	ProcessKeyPressL();
+	WaitForKeyPress();
+	}
+
+void CActiveConsole::ConstructL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CActiveConsole::ConstructL()"));
+#endif
+	CActiveScheduler::Add(this);				// Add to active scheduler
+
+	// Create 2 reader writer AOs/ threads
+	// 1 for reading from USb and writing to serial
+	iUsbToSerial = CDuplex::NewL();
+	iUsbToSerial->SetRxPort(&TheUsbPort);
+	iUsbToSerial->SetTxPort(&TheSerialPort);
+	
+	// 1 for reading from Serial and writing to Usb
+	iSerialToUsb = CDuplex::NewL();
+	iSerialToUsb->SetRxPort(&TheSerialPort);
+	iSerialToUsb->SetTxPort(&TheUsbPort);
+
+	iSerialSignalChangeNotifier = CSignalChangeNotifier::NewL(EFalse);
+	iUsbSignalChangeNotifier = CSignalChangeNotifier::NewL(ETrue);
+//	iUsbFControlNotifier = CFControlChangeNotifier::NewL();
+	iUsbConfigChangeNotifier = CConfigChangeNotifier::NewL();
+	}
+
+void CActiveConsole::Start()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CActiveConsole::Start()"));
+#endif
+	if (iIsRunning)
+		{
+		TheWindow.Write(_L(": Invalid Key pressed, already running\n"));
+		return;
+		}
+	iIsRunning = ETrue;
+	TInt ignoreErr;
+	TRAP(ignoreErr, iUsbConfigChangeNotifier->StartL());
+	TRAP(ignoreErr, iSerialSignalChangeNotifier->StartL());
+	TRAP(ignoreErr, iUsbSignalChangeNotifier->StartL());
+//	iUsbFControlNotifier->StartL();
+	
+	TRAP(ignoreErr, iUsbToSerial->StartL());
+	TRAP(ignoreErr, iSerialToUsb->StartL());
+#ifdef _DEBUG
+	RDebug::Print(_L(": CActiveConsole::Start() done"));
+#endif
+	}
+
+void CActiveConsole::WaitForKeyPress()
+	{
+	if (IsActive())
+		{
+		RDebug::Print(_L(": ActiveConsole -- Already Running\n"));
+		return;
+		}
+		
+	TheWindow.Write(_L("Press Escape to STOP\n"));
+	TheWindow.Write(_L("Press Enter to EXIT\n"));
+	if (!iIsRunning)
+		{
+		TheWindow.Write(_L("Press Spacebar to START test\n"));
+		}
+	else
+		{
+		TheWindow.Write(_L("1 DTR on	A DTR off\n"));
+		TheWindow.Write(_L("2 RTS on	B RTS off\n"));
+		TheWindow.Write(_L("3 DSR on	C DSR off\n"));
+		TheWindow.Write(_L("4 CTS on	D CTS off\n"));
+		TheWindow.Write(_L("5 DCD on	E DCD off\n"));
+		TheWindow.Write(_L("6 RNG on	F RNG off\n"));
+		TheWindow.Write(_L("7 BRK on	G BRK off\n"));
+		}
+	TheWindow.Write(_L("\n"));
+	TheWindow.Write(_L("\n"));
+	TheWindow.Read(iKeypress, iStatus);
+	SetActive();
+	}
+
+void CActiveConsole::ProcessKeyPressL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CActiveConsole::ProcessKeyPressL()"));
+#endif
+	switch (iKeypress.Code())
+		{
+		case EKeyEscape:
+			RDebug::Print(_L(": Stopping CactiveConsole"));
+			DoCancel();
+			break;
+		case EKeySpace:
+			RDebug::Print(_L(": Starting"));
+			Start();
+			break;
+		case EKeyEnter:
+			RDebug::Print(_L(": Exiting"));
+			DoCancel();
+
+			RDebug::Print(_L(": Closing ports and servers"));
+	
+			TheUsbPort.Close();
+			TheSerialPort.Close();
+			TheUsbServer.Close();
+			TheCommServer.Close();
+
+			CActiveScheduler::Stop();
+			break;
+		case '1':
+			TheUsbPort.SetSignals ( KSignalDTR, 0 );
+			break;
+		case '2':
+			TheUsbPort.SetSignals ( KSignalRTS, 0 );
+			break;
+		case '3':
+			TheUsbPort.SetSignals ( KSignalDSR, 0 );
+			break;
+		case '4':
+			TheUsbPort.SetSignals ( KSignalCTS, 0 );
+			break;
+		case '5':
+			TheUsbPort.SetSignals ( KSignalDCD, 0 );
+			break;
+		case '6':
+			TheUsbPort.SetSignals ( KSignalRNG, 0 );
+			break;
+		case '7':
+			TheUsbPort.Break ( iBreakRequest, 1000 );
+			break;
+		case 'A':
+			TheUsbPort.SetSignals ( 0, KSignalDTR );
+			break;
+		case 'B':
+			TheUsbPort.SetSignals ( 0, KSignalRTS );
+			break;
+		case 'C':
+			TheUsbPort.SetSignals ( 0, KSignalDSR );
+			break;
+		case 'D':
+			TheUsbPort.SetSignals ( 0, KSignalCTS );
+			break;
+		case 'E':
+			TheUsbPort.SetSignals ( 0, KSignalDCD );
+			break;
+		case 'F':
+			TheUsbPort.SetSignals ( 0, KSignalRNG );
+			break;
+		default:
+			TheWindow.Write(_L(": Invalid Key pressed\n"));
+		}
+	}
+
+/*
+LOCAL_C TInt RateToInt(TBps aRate)
+	{
+	switch (aRate)
+		{
+	case EBps115200:	return 115200;
+    case EBps57600:	return 57600;
+    case EBps38400:	return 38400;
+    case EBps19200:	return 19200;
+    case EBps9600:	return 9600;
+	case EBps7200:	return 7200;
+    case EBps4800:	return 4800;
+	case EBps3600:	return 3600;
+    case EBps2400:	return 2400;
+	case EBps2000:	return 2000;
+	case EBps1800:	return 1800;
+    case EBps1200:	return 1200;
+    case EBps600:	return 600;
+    case EBps300:	return 300;
+    case EBps150:	return 150;
+	case EBps134:	return 134;
+    case EBps110:	return 110;
+	case EBps75:	return 75;
+	case EBps50:	return 50;
+	default:	return -1;
+		}
+	}
+
+LOCAL_C void ConfigString(TDes &aBuf, const TCommNotificationV01 &aConfig)
+	{
+	// Config
+	aBuf.Format(_L(" %d "), RateToInt(aConfig.iRate));
+	switch (aConfig.iParity)
+		{
+	case EParityEven: aBuf.Append(_L("E")); break;
+	case EParityOdd: aBuf.Append(_L("O")); break;
+	case EParityNone: aBuf.Append(_L("N")); break;
+    default: break;
+		}
+	switch (aConfig.iDataBits)
+		{
+	case EData5: aBuf.Append(_L("5")); break;
+	case EData6: aBuf.Append(_L("6")); break;
+	case EData7: aBuf.Append(_L("7")); break;
+	case EData8: aBuf.Append(_L("8")); break;
+    default: break;
+		}
+	if (aConfig.iStopBits==EStop1)
+		aBuf.Append(_L("1 "));
+	else
+		aBuf.Append(_L("2 "));
+
+	aBuf.Append(_L("Use:"));
+	if (aConfig.iHandshake==0)
+		aBuf.Append(_L("NoControl "));
+	if (aConfig.iHandshake&(KConfigObeyXoff|KConfigSendXoff))
+		aBuf.Append(_L("XonXoff "));
+	if (aConfig.iHandshake&KConfigObeyCTS)
+		aBuf.Append(_L("CTS/RTS "));
+	if (aConfig.iHandshake&KConfigObeyDSR)
+		aBuf.Append(_L("DSR/DTR "));
+	if (aConfig.iHandshake&KConfigWriteBufferedComplete)
+		aBuf.Append(_L("Early "));
+	//|KConfigObeyDCD|KConfigFailDCD|))
+
+//	if (aConfig.iBreak==TEiger::EBreakOn)
+//		aBuf.Append(_L("Brk "));
+//	if (aConfig.iFifo==EFifoEnable)
+//		aBuf.Append(_L("Fifo "));
+	}
+	
+LOCAL_C void PrintCaps()
+	{
+	TCommCaps2 caps;
+	TheUsbPort.Caps(caps);
+	TUint notifycaps = caps().iNotificationCaps;
+	RDebug::Print(_L("Capabilities:\n"));
+	if (notifycaps&KNotifySignalsChangeSupported)
+		RDebug::Print(_L("Notify Signals Change supported\n"));
+	if (notifycaps&KNotifyRateChangeSupported)
+		RDebug::Print(_L("Notify Rate Change supported\n"));
+	if (notifycaps&KNotifyDataFormatChangeSupported)
+		RDebug::Print(_L("Notify Data Format Change supported\n"));
+	if (notifycaps&KNotifyHandshakeChangeSupported)
+		RDebug::Print(_L("Notify Handshake Change supported\n"));
+	if (notifycaps&KNotifyBreakSupported)
+		RDebug::Print(_L("Notify Break supported\n"));
+	if (notifycaps&KNotifyFlowControlChangeSupported)
+		RDebug::Print(_L("Notify Flow Control Change supported\n"));
+	if (notifycaps&KNotifyDataAvailableSupported)
+		RDebug::Print(_L("Notify Data Available supported\n"));
+	if (notifycaps&KNotifyOutputEmptySupported)
+		RDebug::Print(_L("Notify Output Empty supported\n"));
+	RDebug::Print(_L("\n"));
+	if ((caps().iRoleCaps)&KCapsRoleSwitchSupported)
+		RDebug::Print(_L("Role switching is supported\n"));
+	RDebug::Print(_L("\n"));
+	if ((caps().iFlowControlCaps)&KCapsFlowControlStatusSupported)
+		RDebug::Print(_L("Retrieve flow control status is supported\n"));
+	}
+*/
+LOCAL_C void DoInitL()
+	{
+	// Do the necessary initialisation of the C32, 2 comm ports, USB stuff.
+	// Load Device Drivers
+	TInt r;
+
+	RDebug::Print(_L("E32Main: Load USB LDD \n"));
+	r=User::LoadLogicalDevice(USBLDD_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed 0x%X\n\r"),r);
+		User::Panic(_L("T_TERM"), ELoadLogicalDeviceErr);
+		}
+
+	RDebug::Print(_L("E32Main: Load Serial PDD \n "));
+	r=User::LoadPhysicalDevice(SERIALPDD_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed 0x%X\n\r"),r);
+		User::Panic(_L("T_TERM"), ELoadLogicalDeviceErr);
+		}
+
+	RDebug::Print(_L("E32Main: Load SERIAL LDD \n"));
+	r=User::LoadLogicalDevice(SERIALLDD_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed 0x%X\n\r"),r);
+		User::Panic(_L("T_TERM"), ELoadLogicalDeviceErr);
+		}
+	RDebug::Print(_L("E32Main: Loaded Device Drivers\n"));
+	
+	r = StartC32();
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed to start C32. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Started c32"));
+
+	r = TheUsbServer.Connect();
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to connect to UsbMan Server. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Connected to UsbMan Server"));
+
+	TRequestStatus startStatus;
+	TheUsbServer.Start(startStatus);
+	User::WaitForRequest(startStatus);
+	if (startStatus != KErrNone && startStatus != KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed to Start USB services. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Started USB services"));
+
+	// Comms Config
+	r = TheCommServer.Connect();
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to Connect to C32. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Connected to C32 Server"));
+
+	r = TheCommServer.LoadCommModule(USBCSY_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed to load USB CSY. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Loaded USB CSY"));
+
+	r = TheCommServer.LoadCommModule(SERIALCSY_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed to load serial CSY. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Loaded Serial CSY"));
+
+	r = TheUsbPort.Open(TheCommServer, USBPORT_NAME,ECommExclusive,ECommRoleDCE); // Comm port
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to Open USB Comm Port. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Opened USB Comm Port"));
+
+
+	r = TheSerialPort.Open(TheCommServer, SERIALPORT_NAME,ECommExclusive,ECommRoleDTE); // Comm port
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to Open Serial Comm Port. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Opened Serial Comm Port"));
+
+	// Print the caps
+	//PrintCaps();
+
+	RDebug::Print(_L("E32Main: Reading Serial Comm Port config"));
+	TheSerialPort.Config(TheSerialConfigBuf);	// get config
+	RDebug::Print(_L("E32Main: Reading Usb Comm Port config"));
+	TheUsbPort.Config(TheUsbConfigBuf);	// get config
+
+	TBuf<80> buf;
+	buf.FillZ();
+	//ConfigString(buf, TheUsbConfig);
+	RDebug::Print(_L("E32Main: Old USB Port Settings"));
+	RDebug::Print(buf);
+	RDebug::Print(_L(""));
+	buf.FillZ();
+	//ConfigString(buf, TheSerialConfig);
+	RDebug::Print(_L("E32Main: Old Serial Port Settings"));
+	RDebug::Print(buf);
+	RDebug::Print(_L(""));
+
+	TCommConfig serialConfig;
+	TheSerialPort.Config(serialConfig);	// get config
+	serialConfig().iHandshake = 0;
+	serialConfig().iRate = EBps1152000;
+	TheSerialPort.SetConfig(serialConfig);
+
+	RDebug::Print(_L(""));	}
+
+/// Main function
+//
+GLDEF_C TInt E32Main()
+	{
+	RDebug::Print(_L("E32Main: Starting!"));
+	// Construct the active scheduler
+	CActiveScheduler* myScheduler = new (ELeave) CActiveScheduler();
+
+	// Install as the active scheduler
+	CActiveScheduler::Install(myScheduler);
+
+	// Create objects and console handler
+	// Open the window asap
+	TheWindow.Init(_L("TERM"),TSize(KConsFullScreen,KConsFullScreen));
+
+	TheWindow.Control(_L("+Maximize +Newline"));
+	RDebug::Print(_L("E32Main: Initialised Window!"));
+
+	DoInitL();
+	
+	// Does the construction, 
+	CActiveConsole* myActiveConsole = CActiveConsole::NewL();
+
+    // Call request function to start the test
+	myActiveConsole->WaitForKeyPress();	
+	// Start active scheduler
+	CActiveScheduler::Start();
+
+	// Suspend thread for 2 secs
+	User::After(2000000);
+
+	delete myActiveConsole;
+	return KErrNone;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_whcm_cc/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* 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 "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:
+* BLD.INF for t_whcm_cc
+* BLD.INF for t_whcm_cc
+*
+*/
+
+/**
+ @file
+*/
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+t_whcm_cc.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_whcm_cc/group/t_whcm_cc.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+
+TARGET         t_whcm_cc.exe
+TARGETTYPE     EXE
+SOURCEPATH    ../src
+SOURCE         t_whcm_cc.cpp
+LIBRARY        euser.lib efsrv.lib c32.lib usbman.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+VENDORID 0x70000001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_whcm_cc/src/t_whcm_cc.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,434 @@
+/*
+* Copyright (c) 1997-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:
+* Runs tests upon USB Manager's WHCM Class Controller.
+* Relies on the fact that the USB Manager is actually configured to start a WHCM class controller.
+* Tests are numbered as in v0.2 of the USB Manager Test Specification.
+*
+*/
+// t_WHCM_cc.cpp
+
+#include <e32test.h>
+#include <e32twin.h>
+#include <c32comm.h>
+#include <d32comm.h>
+#include <f32file.h>
+#include <hal.h>
+#include <usbman.h>
+
+// A test object for test io
+LOCAL_D RTest test(_L("T_ACM_CC"));
+
+// A pointer to an instance of the USB Manager
+RUsb *usbman;
+
+// An instance of the fileserver
+RFs theFs;
+
+// A timer for waiting around
+RTimer timer;
+
+// Some wait times for use with the timer (in microseconds)
+// May need to tinker with these to get them right
+#define CANCEL_START_REQ_DELAY 10
+#define CANCEL_STOP_REQ_DELAY 10
+
+// A set of states for the startup and shutdown sequence
+enum TestState
+{
+	 EStart = 0,
+	 EFsConnected,
+	 EC32Started,
+	 EUSBManCreated,
+	 EUSBManConnected,
+	 EPrimaryRegistered,
+	 EUSBManStarted
+};
+TestState current_test_state;
+
+/**
+ * Function to run through the common startup of a test.
+ */
+TInt CommonStart()
+{
+	 TInt r;
+
+	test.Printf(_L("CommonStart()\n"));
+
+	 // Loop until the primary client is registered.
+     // Do not proceed to start the USB Manager, as that is test specific.
+	 while(current_test_state != EPrimaryRegistered)
+	 {
+		  switch(current_test_state)
+		  {
+		  case EStart:
+			   // Connect to the fileserver
+			   r = theFs.Connect();
+			   if (r != KErrNone)
+			   {
+					test.Printf(_L("   Failed to connect to the fs. Error = %d\n"), r);
+					return r;
+			   }
+			   test.Printf(_L("   Connected to file server.\n"));
+			   current_test_state = EFsConnected;
+			   break;
+		  case EFsConnected:
+			   // Start C32
+			   r = StartC32();
+			   if (r!=KErrNone && r !=KErrAlreadyExists)
+			   {
+					test.Printf(_L("   Failed to start C32. Error = %d\n"), r);
+					return r;
+			   }
+			   test.Printf(_L("   Started C32.\n"));
+			   current_test_state = EC32Started;
+			   break;
+		  case EC32Started:
+			   // Create an instance of the USB Manager
+			  usbman = new RUsb;
+			   if (!usbman)
+			   {
+					test.Printf(_L("   Failed to instantiate USB Manager.\n"));
+					return KErrGeneral;
+			   }
+			   test.Printf(_L("   Instantiated USB Manager.\n"));
+			   current_test_state = EUSBManCreated;
+			   break;
+		  case EUSBManCreated:
+			   // Connect to the USB Manager
+			   r = usbman->Connect();
+			   if (r != KErrNone)
+			   {
+					test.Printf(_L("   Failed to connect to USB Manager. Error = %d\n"), r);
+					return r;
+			   }
+			   test.Printf(_L("   Connected to USB Manager.\n"));
+			   current_test_state = EUSBManConnected;
+			   break;
+		  case EUSBManConnected:
+			   // Register as primary client.
+			   // *** Obsolete ***
+			   /*
+			   r = usbman->RegisterAsPrimarySession();
+			   if (r != KErrNone)
+			   {
+					test.Printf(_L("    Failed to register as primary client. Error = %d\n"), r);
+					return r;
+			   }
+			   test.Printf(_L("    Registered as primary client.\n"));
+			   */
+			   current_test_state = EPrimaryRegistered;
+			   break;
+		  default:
+			   break;
+		  }
+	 }
+
+	 test.Printf(_L("CommonStart() done\n"));
+
+	 return KErrNone;
+}
+
+/**
+ * Function to run through the common shutdown of a test.
+ * Shuts down only what is needed, based upon the value of current_test_state,
+ * so it can be used to clean up after aborted starts.
+ */
+TInt CommonCleanup()
+{
+	 TRequestStatus status;
+
+	 while(current_test_state != EStart)
+	 {
+		  switch(current_test_state)
+		  {
+		  case EUSBManStarted:
+			   // Stop the USB Manager
+			   usbman->Stop(status);
+			   User::WaitForRequest(status);
+			   current_test_state = EPrimaryRegistered;
+			   break;
+		  case EPrimaryRegistered:
+			   // *** Obsolete ***
+			   // usbman->DeregisterAsPrimarySession();
+			   current_test_state = EUSBManConnected;
+			   break;
+		  case EUSBManConnected:
+			   // Don't need to disconnect.
+			   current_test_state = EUSBManCreated;
+			   break;
+		  case EUSBManCreated:
+			   delete usbman;
+			   current_test_state = EC32Started;
+			   break;
+		  case EC32Started:
+			   // Don't need to stop C32
+			   current_test_state = EFsConnected;
+			   break;
+		  case EFsConnected:
+			   theFs.Close();
+			   current_test_state = EStart;
+			   break;
+		  default:
+			   break;
+		  }
+	 }
+	 return KErrNone;
+}
+
+/**
+ * Checks that the USB service state is as expected.
+ */
+TInt CheckServiceState(TUsbServiceState state)
+{
+	TUsbServiceState aState;
+	TInt r = usbman->GetServiceState(aState);
+	if (r != KErrNone)
+		{
+		test.Printf(_L("Failed to get service state. Error = %d\n"), r);
+		return r;
+		}
+	if (aState != state)
+		{
+		test.Printf(_L("Service state check failed. State expected: %d. State is: %d (type TUsbServiceState).\n"), state, aState);
+		return KErrGeneral;
+		}
+	test.Printf(_L("Service state ok\n"));
+
+	return KErrNone;
+}
+
+/**
+ * Executes test A1 (as detailed in the USB Manager Test Specification).
+ */
+static TInt RunTest_A1()
+	{
+	TInt r;
+
+	test.Next(_L("Test A1.\n"));
+
+	// Perform common startup
+	current_test_state = EStart;
+	r = CommonStart();
+	if (r != KErrNone)
+		 return r;
+
+	// Start the USB Manager
+	TRequestStatus status;
+	test.Printf(_L("Starting.\n"));
+	usbman->Start(status);
+	test.Printf(_L("Waiting for request.\n"));
+	User::WaitForRequest(status);
+
+	test.Printf(_L("... done. Status: %d.\n"), status.Int());
+
+	current_test_state = EUSBManStarted;
+	return KErrNone;
+	}
+
+
+/**
+ * Executes test A2 (as detailed in the USB Manager Test Specification).
+ * No longer a relevant test.
+ */
+/*static TInt RunTest_A2()
+	{
+	TInt r;
+
+	test.Next(_L("Test A2.\n"));
+
+	// Perform common startup
+	current_test_state = EStart;
+	r = CommonStart();
+	if (r != KErrNone)
+		 return r;
+
+	// Start the USB Manager
+	TRequestStatus status;
+	test.Printf(_L("Starting.\n"));
+	usbman->Start(status);
+
+	// Wait for specific time (has to be less than the time to process a start request)
+	timer.After(status, CANCEL_START_REQ_DELAY);
+	User::WaitForRequest(status);
+
+	// Cancel the start request
+	test.Printf(_L("Cancelling.\n"));
+	usbman->StartCancel();
+
+	// Check service status
+	test.Printf(_L("Checking service status.\n"));
+	r = CheckServiceState(EUsbServiceIdle);
+	if ( r != KErrNone)
+		 return r;
+
+	return KErrNone;
+	}
+*/
+/**
+ * Executes test A3 (as detailed in the USB Manager Test Specification).
+ */
+static TInt RunTest_A3()
+	{
+	TInt r;
+
+	test.Next(_L("Test A3.\n"));
+
+	// Perform common startup
+	current_test_state = EStart;
+	r = CommonStart();
+	if (r != KErrNone)
+		 return r;
+
+	// Start the USB Manager
+	TRequestStatus status;
+	usbman->Start(status);
+	User::WaitForRequest(status);
+	test.Printf(_L("Start completed with status %d\n"), status.Int());
+	current_test_state = EUSBManStarted;
+
+	// Stop the USB Manager
+	usbman->Stop(status);
+	User::WaitForRequest(status);
+	test.Printf(_L("Stop completed with status %d\n"), status.Int());
+	current_test_state = EPrimaryRegistered;
+
+	// Check service status
+	r = CheckServiceState(EUsbServiceIdle);
+	if ( r != KErrNone)
+		 return r;
+
+	return KErrNone;
+	}
+
+/**
+ * Executes test A4 (as detailed in the USB Manager Test Specification).
+ * No longer a relevant test.
+ */
+/*static TInt RunTest_A4()
+	{
+	TInt r;
+
+	test.Next(_L("Test A4.\n"));
+
+	// Perform common startup
+	current_test_state = EStart;
+	r = CommonStart();
+	if (r != KErrNone)
+		 return r;
+
+	// Start the USB Manager
+	TRequestStatus status, timerStatus;
+	usbman->Start(status);
+	User::WaitForRequest(status);
+	test.Printf(_L("Start completed with status %d\n"), status.Int());
+	current_test_state = EUSBManStarted;
+
+	// Stop the USB Manager
+	usbman->Stop(status);
+
+	// Wait for specific time (has to be less than the time to process a start request)
+	timer.After(timerStatus, CANCEL_STOP_REQ_DELAY);
+	User::WaitForRequest(status, timerStatus);
+
+	// Cancel the stop request
+	usbman->StopCancel();
+
+	// Check service status
+	r = CheckServiceState(EUsbServiceStarted);
+	if ( r != KErrNone)
+		 return r;
+
+	return KErrNone;
+	}
+*/
+/**
+ * Main function.
+ *
+ * Runs all the tests in order.
+ */
+void mainL()
+    {
+	TInt err;
+
+	// Run all the tests
+
+	err=RunTest_A1();
+	if (err != KErrNone)
+	{
+		test.Printf(_L("Test A1 failed, code: %d\n\n"), err);
+	}
+	else
+		test.Printf(_L("Test A1 passed.\n\n"));
+	CommonCleanup();
+
+/*	Depreciated test.
+	err=RunTest_A2();
+	if (err != KErrNone)
+	{
+		test.Printf(_L("Test A2 failed, code: %d\n\n"), err);
+	}
+	else
+		test.Printf(_L("Test A2 passed.\n\n"));
+	CommonCleanup();
+*/
+	err=RunTest_A3();
+	if (err != KErrNone)
+	{
+		test.Printf(_L("Test A3 failed, code: %d\n\n"), err);
+	}
+	else
+		test.Printf(_L("Test A3 passed.\n\n"));
+	CommonCleanup();
+
+/*	Depreciated test.
+	err=RunTest_A4();
+	if (err != KErrNone)
+	{
+		test.Printf(_L("Test A4 failed, code: %d\n\n"), err);
+	}
+	else
+		test.Printf(_L("Test A4 passed.\n\n"));
+	CommonCleanup();
+*/
+	// Tests finished
+    }
+
+/**
+ * Entry point.
+ *
+ * Creates a cleanup stack and a timer then calls consoleMainL.
+ */
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanupStack=CTrapCleanup::New();
+
+	test.Title();
+	test.Start(_L("Starting E32Main"));
+
+	// create the timer for use during some of the tests
+	timer.CreateLocal();
+
+	TRAP_IGNORE(mainL());
+
+	test.Printf(_L("\n[Finished. Press any key.]\n"));
+	test.Getch();
+	test.End();
+	test.Close();
+
+	delete cleanupStack;
+	__UHEAP_MARKEND;
+	return 0;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/controlappbinder/controlappbinder.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,350 @@
+/*
+* 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 "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 <e32cons.h>
+#include <e32debug.h>
+
+#include "e32svr.h"
+#include <e32keys.h>
+
+#include <e32property.h> 
+
+#include "controlappbinder.h"
+
+
+
+#define LOG(A,B) RDebug::Print(_L("UsbControlAppBinder: " L##A),B)
+
+#define PNT(A)	 RDebug::Print(_L("UsbControlAppBinder: " L##A))
+
+#define PANIC Panic(__LINE__)
+
+void Panic(TInt aLine)
+	{
+	RDebug::Printf("UsbControlAppBinder: PANIC line=%d", aLine);
+	User::Panic(_L("UsbControlAppBinder"), aLine);
+	}
+
+
+void RunAppL()
+	{
+	CUsbControlAppBinderConsole* binderapp = CUsbControlAppBinderConsole::NewLC();
+	binderapp->Start();
+	CleanupStack::PopAndDestroy(binderapp);
+	}
+
+
+TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	CActiveScheduler* activeScheduler = new CActiveScheduler;
+	TInt err = KErrNoMemory;
+	if(cleanup && activeScheduler)
+		{
+		CActiveScheduler::Install(activeScheduler);
+		PNT("*** UsbControlAppBinder E32Main ***\n");
+		TRAP(err, RunAppL());
+		}
+	delete activeScheduler;
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return err;
+	}
+
+
+
+CUsbControlAppBinderConsole* CUsbControlAppBinderConsole::NewLC()
+	{
+	CUsbControlAppBinderConsole* self = new(ELeave) CUsbControlAppBinderConsole;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	PNT("Constructed USB Control App Binder\n");
+	return self;
+	}
+	
+CUsbControlAppBinderConsole::~CUsbControlAppBinderConsole()
+	{
+	PNT("Closing USB Control App Binder\n");
+	delete iKeys;
+	delete iConsole;
+	}
+
+CUsbControlAppBinderConsole::CUsbControlAppBinderConsole()
+	{
+	}
+
+void CUsbControlAppBinderConsole::ConstructL()
+	{
+	iConsole = Console::NewL(KUsbControlAppBinderTitle, TSize(KBinderWindowWidth, KBinderWindowDepth));
+
+	Move((KScreenWidth-KBinderWindowWidth-2)/2,1);
+	
+	// After everything else, enable interactivity.
+	iKeys = CUsbControlAppBinderKeys::NewL(*this);
+
+	Draw();
+	}
+
+void CUsbControlAppBinderConsole::Move(TInt aX, TInt aY)
+	{
+	TRawEvent event;
+
+	event.Set(TRawEvent::EKeyDown, EStdKeyLeftShift);
+	UserSvr::AddEvent(event);
+
+	if (aX)
+		{
+		if ( aX > 0 )
+			{
+			// Move to the right...
+			for(TInt i=aX; i; i--)
+				{
+				event.Set(TRawEvent::EKeyDown, EStdKeyRightArrow);
+				UserSvr::AddEvent(event);
+				event.Set(TRawEvent::EKeyUp, EStdKeyRightArrow);
+				UserSvr::AddEvent(event);
+				}
+			}
+		else
+			{
+			// Move to the Left...
+			for(TInt i=aX; i; i++)
+				{
+				event.Set(TRawEvent::EKeyDown, EStdKeyLeftArrow);
+				UserSvr::AddEvent(event);
+				event.Set(TRawEvent::EKeyUp, EStdKeyLeftArrow);
+				UserSvr::AddEvent(event);
+				}
+			}
+		}
+	
+	if (aY)
+		{
+		if ( aY > 0 )
+			{
+			// Move downwards...
+			for(TInt i=aY; i; i--)
+				{
+				event.Set(TRawEvent::EKeyDown, EStdKeyDownArrow);
+				UserSvr::AddEvent(event);
+				event.Set(TRawEvent::EKeyUp, EStdKeyDownArrow);
+				UserSvr::AddEvent(event);
+				}
+			}
+		else
+			{
+			// Move upwards...
+			for(TInt i=aY; i; i++)
+				{
+				event.Set(TRawEvent::EKeyDown, EStdKeyUpArrow);
+				UserSvr::AddEvent(event);
+				event.Set(TRawEvent::EKeyUp, EStdKeyUpArrow);
+				UserSvr::AddEvent(event);
+				}
+			}
+		}
+
+	event.Set(TRawEvent::EKeyUp, EStdKeyLeftShift);
+	UserSvr::AddEvent(event);
+	}
+
+void CUsbControlAppBinderConsole::Start()
+	{
+	// Get everything running
+	CActiveScheduler::Start();
+	}
+	
+void CUsbControlAppBinderConsole::Stop() const
+	{
+	CActiveScheduler::Stop();
+	}
+
+void CUsbControlAppBinderConsole::Draw()
+	{
+	iConsole->ClearScreen();
+	
+	iConsole->Printf
+	(	_L(	 "\r\n"
+			L"'A'\r\n"
+			L"\r\n"
+			L"\r\n"
+			L"\r\n"
+			L"'C'\r\n"
+			L"\r\n"
+			L"\r\n"
+			L"\r\n"
+			L"'V'\r\n"
+			L"\r\n"
+			L"\r\n"
+			L"\r\n"
+			L"'*'\r\n"
+			L"\r\n"
+			L"\r\n"
+			L"\r\n"
+			L"'Q'\r\n"
+		  )
+	);
+	}
+
+void CUsbControlAppBinderConsole::StartAwareApp()
+	{
+	PNT("Start Aware Program\n");
+	RProcess iAwareApp;
+	TInt err = iAwareApp.Create(_L("testusbawareapp.exe"), KNullDesC);
+	
+	if (err != KErrNone)
+		{
+		LOG("Failed to create Aware program, err=%d",err);
+		iAwareApp.Close();
+		}
+	else
+		{
+		iAwareApp.Resume();
+		}
+	}
+
+void CUsbControlAppBinderConsole::StartControlApp()
+	{
+	PNT("Start Control Program\n");
+	RProcess iControlApp;
+	TInt err = iControlApp.Create(_L("exampleusbcontrolapp.exe"), KNullDesC);
+	
+	if (err != KErrNone)
+		{
+		LOG("Failed to create Control program, err=%d",err);
+		iControlApp.Close();
+		}
+	else
+		{
+		iControlApp.Resume();
+		}
+	}
+
+void CUsbControlAppBinderConsole::StartViewerApp()
+	{
+	PNT("Start Viewer Program\n");
+	RProcess iViewerApp;
+	TInt err = iViewerApp.Create(_L("usbviewer.exe"), KNullDesC);
+	
+	if (err != KErrNone)
+		{
+		LOG("Failed to create Viewer program, err=%d",err);
+		iViewerApp.Close();
+		}
+	else
+		{
+		iViewerApp.Resume();
+		}
+	}
+
+
+
+CUsbControlAppBinderKeys* CUsbControlAppBinderKeys::NewL(CUsbControlAppBinderConsole& aUsbControlAppBinderConsole)
+	{
+	CUsbControlAppBinderKeys* self = new(ELeave) CUsbControlAppBinderKeys(aUsbControlAppBinderConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CUsbControlAppBinderKeys::~CUsbControlAppBinderKeys()
+	{
+	Cancel();
+	}
+
+CUsbControlAppBinderKeys::CUsbControlAppBinderKeys(CUsbControlAppBinderConsole& aUsbControlAppBinderConsole)
+	: CActive(EPriorityStandard)
+	, iUsbControlAppBinderConsole(aUsbControlAppBinderConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUsbControlAppBinderKeys::ConstructL()
+	{
+	TInt err = RProperty::Define(KUidUsbControlAppCategory, KUsbControlAppShutdownKey, RProperty::EInt);	
+	LOG("CUsbControlAppBinderKeys::ConstructL()   RProperty::Define()   err=%d", err);
+	if(err)
+		{
+		PNT("CUsbControlAppBinderKeys::ConstructL()   RProperty::Define()	Property probably already defined\n");
+		}
+	err = RProperty::Set(KUidUsbControlAppCategory, KUsbControlAppShutdownKey, 0);
+	LOG("CUsbControlAppBinderKeys::ConstructL()   RProperty::Set()   err=%d", err);	
+	User::LeaveIfError(err);	
+	// Allow keyboard input
+	iUsbControlAppBinderConsole.iConsole->Read(iStatus);
+	SetActive();
+	}
+
+#define SECONDS(t) (t*1000000)
+
+void CUsbControlAppBinderKeys::RunL()
+	{
+	User::LeaveIfError(iStatus.Int());
+	
+	TKeyCode theKey = iUsbControlAppBinderConsole.iConsole->KeyCode();
+	
+	switch(theKey)
+		{
+		case 'a': case 'A':
+			iUsbControlAppBinderConsole.StartAwareApp();
+			break;
+
+		case 'c': case 'C':
+			iUsbControlAppBinderConsole.StartControlApp();
+			break;
+
+		case 'v': case 'V':
+			iUsbControlAppBinderConsole.StartViewerApp();
+			break;
+
+		case '*':
+			PNT("Start Everything\n");
+			iUsbControlAppBinderConsole.StartControlApp();
+			User::After(SECONDS(4));
+			iUsbControlAppBinderConsole.StartViewerApp();
+			User::After(SECONDS(4));
+			iUsbControlAppBinderConsole.StartAwareApp();
+			break;
+			
+		case 'q': case 'Q':
+			{
+			TInt err = RProperty::Set(KUidUsbControlAppCategory, KUsbControlAppShutdownKey, 1);
+			LOG("CUsbAwareAppKeys::RunL()   RProperty::Set()   err=%d", err);
+			User::LeaveIfError(err);
+			iUsbControlAppBinderConsole.Stop();
+			return;
+			}
+
+		default:
+			LOG("Unexpected Key [%c]",theKey);
+			break;
+		}
+	
+	iUsbControlAppBinderConsole.iConsole->Read(iStatus);
+	SetActive();
+	}
+
+void CUsbControlAppBinderKeys::DoCancel()
+	{
+	iUsbControlAppBinderConsole.iConsole->ReadCancel();
+	}
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/controlappbinder/controlappbinder.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,91 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef CONTROL_APP_BINDER_H
+#define CONTROL_APP_BINDER_H
+
+#include <e32cmn.h>
+#include <e32base.h>
+
+#include "usbcontrolappshared.h"
+
+
+_LIT(KUsbControlAppBinderTitle, "BIND");
+
+class CUsbControlAppBinderKeys;
+
+NONSHARABLE_CLASS(CUsbControlAppBinderConsole) : public CBase
+	{
+friend class CUsbControlAppBinderKeys;
+
+public:
+	static CUsbControlAppBinderConsole* NewLC();
+	~CUsbControlAppBinderConsole();
+
+public:
+	void Start();     
+	void Stop() const; 
+
+private:
+	CUsbControlAppBinderConsole();
+	void ConstructL();
+	void Move(TInt aX, TInt aY);
+	void Draw();
+
+	void StartAwareApp();
+	void StartControlApp();
+	void StartViewerApp();
+	
+private:
+	CConsoleBase* 				iConsole;	
+	CUsbControlAppBinderKeys*	iKeys;
+
+	// Handles for the individual components to run in parallel
+	
+	static RProcess iAwareApp;
+	static RProcess iControlApp;
+	static RProcess iViewerApp;
+	
+private:
+	// Run on the far right-hand side of the H4 screen, which (for
+	// the TextShell program) is 24 rows, 40 columns - each allows
+	// 2 row/column for borders
+	static const TInt KBinderWindowDepth = (KScreenDepth - 3);
+	static const TInt KBinderWindowWidth = (KScreenWidth - (KViewerNumCharactersOnLine + 4));
+	};
+
+
+
+NONSHARABLE_CLASS(CUsbControlAppBinderKeys) : public CActive
+	{
+public:
+	static CUsbControlAppBinderKeys* NewL(CUsbControlAppBinderConsole& aUsbControlAppBinderConsole);
+	~CUsbControlAppBinderKeys();
+	
+private:
+	CUsbControlAppBinderKeys(CUsbControlAppBinderConsole& aUsbControlAppBinderConsole);
+	void ConstructL();
+	void DoCancel();
+	void RunL();
+	
+private:
+	CUsbControlAppBinderConsole&	iUsbControlAppBinderConsole;
+	};
+
+
+#endif // CONTROL_APP_BINDER_H
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/controlappbinder/controlappbinder.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,33 @@
+/*
+* 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 "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:
+*
+*/
+
+
+target		controlappbinder.exe
+targettype	exe
+UID		0x100039CE 0x10285EE9
+VENDORID	0x70000001
+
+capability	SwEvent
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+userinclude	../shared
+
+sourcepath	../controlappbinder
+source		controlappbinder.cpp
+
+library		euser.lib
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/exampleusbcontrolapp/exampleusbcontrolapp.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,1555 @@
+/*
+* 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 "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 "exampleusbcontrolapp.h"
+
+#include <e32cons.h>
+#include <e32debug.h>
+// For Message Watcher
+#include <d32otgdi_errors.h>
+#include <d32usbdi_errors.h>
+#include <usb/usbshared.h>
+
+
+#define LOG(A,B)	RDebug::Print(_L("UsbControlApp: " L##A),B)
+#define PNT(A)		RDebug::Print(_L("UsbControlApp: " L##A))
+#define BLN(A)		RDebug::Print(_L("" L##A))
+#define PANIC		Panic(__LINE__)
+
+
+#ifdef __USB_DEBUG__
+#define DBG_PANIC	Panic(__LINE__)
+#else
+#define DBG_PANIC
+#endif
+
+
+void Panic(TInt aLine)
+	{
+	RDebug::Printf("UsbControlApp: PANIC line=%d", aLine);
+	User::Panic(_L("USBCONTROLAPP"), aLine);
+	}
+
+void RunAppL()
+	{
+	CUsbControlAppEngine* engine = CUsbControlAppEngine::NewLC();
+	engine->Start();
+	CleanupStack::PopAndDestroy(engine);
+	}
+
+TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	CActiveScheduler* activeScheduler = new CActiveScheduler;
+	TInt err = KErrNoMemory;
+	if(cleanup && activeScheduler)
+		{
+		CActiveScheduler::Install(activeScheduler);
+		PNT("*** UsbControlApp E32Main ***\n");
+		TRAP(err, RunAppL());
+		}
+	delete activeScheduler;
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return err;
+	}
+
+
+CShutdownMonitor* CShutdownMonitor::NewL(MShutdownInterface& aControlAppEngine)
+	{
+	CShutdownMonitor* self = new(ELeave) CShutdownMonitor(aControlAppEngine);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CShutdownMonitor::CShutdownMonitor(MShutdownInterface& aControlAppEngine)
+	: CActive(EPriorityLow) // Low so all notifications that want to be serviced will be done first
+	, iParentControlAppEngine(aControlAppEngine)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CShutdownMonitor::ConstructL()
+	{
+	// Monitor the KUsbControlAppShutdownKey property to tell us when to shut down
+	TInt err = iShutdownProp.Attach(KUidUsbControlAppCategory, KUsbControlAppShutdownKey);
+	LOG("CShutdownMonitor::ConstructL	 iShutdownProp.Attach() => %d", err);
+	User::LeaveIfError(err);
+	iShutdownProp.Subscribe(iStatus);
+	SetActive();
+	TInt val;
+	// Make sure the cuurent value is 0 - shut down when this changes to 1
+	err = iShutdownProp.Get(val);
+	LOG("CShutdownMonitor::ConstructL()	 iShutdownProp.Get(val)		val => %d", val);
+	LOG("CShutdownMonitor::ConstructL()	 iShutdownProp.Get(val)		err => %d", err);
+	User::LeaveIfError(err);
+	__ASSERT_ALWAYS(val==0, PANIC);
+	}
+
+CShutdownMonitor::~CShutdownMonitor()
+	{
+	iShutdownProp.Close();
+	}
+
+void CShutdownMonitor::RunL()
+	{
+	// Request to shut everything down made in USB Aware App
+	TInt val;
+	TInt err = iShutdownProp.Get(val);
+	LOG("CShutdownMonitor::RunL	 iShutdownProp.Get(val) err => %d", err);
+	LOG("CShutdownMonitor::RunL	 iShutdownProp.Get(val) val => %d", val);
+	Cancel(); // Not interested in any more notifications
+	iParentControlAppEngine.Stop(); // Stopping Active Scheduler will results in the destructor getting called
+	}
+
+void CShutdownMonitor::DoCancel()
+	{
+	iShutdownProp.Cancel();
+	}
+
+
+CUsbControlAppEngine* CUsbControlAppEngine::NewLC()
+	{
+	CUsbControlAppEngine* self = new(ELeave) CUsbControlAppEngine();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	PNT("\nConstructed Control App\n");
+	return self;
+	}
+
+CUsbControlAppEngine::~CUsbControlAppEngine()
+	{
+	PNT("\nClosing Control App\n");
+	iViewerMsgQ.Close();
+	delete iShutdownMonitor;
+	delete iStateMachine;
+	delete iMessageWatcher;
+	delete iConnIdleWatcher;
+	delete iVBusWatcher;
+	delete iIdPinWatcher;
+	iUsb.Close();
+	}
+
+CUsbControlAppEngine::CUsbControlAppEngine()
+	{
+	}
+
+void CUsbControlAppEngine::ConstructL()
+	{
+	// Start session to USBMAN
+	TInt err = iUsb.Connect();
+	LOG("CUsbControlAppEngine::ConstructL()   iUsb.Connect()   err=%d", err);
+	User::LeaveIfError(err);
+	// Set this as the single controller of USBMAN
+	err = iUsb.SetCtlSessionMode(ETrue);
+	LOG("CUsbControlAppEngine::ConstructL()   iUsb.SetCtlSessionMode(ETrue)   err=%d", err);
+	User::LeaveIfError(err);
+	iStateMachine	= CControlAppStateMachine::NewL(*this);
+	// Create Watcher Active Objects to monitor events
+	iIdPinWatcher	= CIdPinWatcher::NewL(*this);
+	iVBusWatcher	= CVBusWatcher::NewL(*this);
+	iConnIdleWatcher= CConnectionIdleWatcher::NewL(*this);
+	iMessageWatcher	= CMessageWatcher::NewL(*this);
+
+	iShutdownMonitor = CShutdownMonitor::NewL(*this);
+	// Create message queue between exampleusbcontrolapp.exe & usbviewer.exe for showing user messages
+	err = iViewerMsgQ.CreateGlobal(KControlAppViewerMsgQName, KControlAppViewerMsgQSlots);
+	LOG("CUsbControlAppEngine::ConstructL()	 iViewerMsgQ.CreateGlobal		err => %d", err);
+	User::LeaveIfError(err);
+	// Stop USB services if they are started so system can start from a known state
+	err = StopUsbServices();
+	LOG("CUsbControlAppEngine::ConstructL()   StopUsbServices()		err=%d", err);
+	User::LeaveIfError(err);
+	// Last thing - allow State Machine to find a main state by sending it a StartUp event
+	iStateMachine->StartUp();
+	}
+
+void CUsbControlAppEngine::Start()
+	{
+	CActiveScheduler::Start(); // Get everything running
+	}
+	
+void CUsbControlAppEngine::Stop() const
+	{
+	CActiveScheduler::Stop();
+	}
+
+// Called by State Machine
+TInt CUsbControlAppEngine::StopUsbServices()
+	{
+	TRequestStatus status;
+	iUsb.TryStop(status);
+	User::WaitForRequest(status);
+	LOG("CUsbControlAppEngine::StopUsbServices()   status.Int()=%d", status.Int());
+	return status.Int();
+	}
+
+TInt CUsbControlAppEngine::StartUsbServices()
+	{
+	const TInt KACMPersonality = 1;
+	TRequestStatus status;
+	iUsb.TryStart(KACMPersonality, status);
+	User::WaitForRequest(status);
+	LOG("CUsbControlAppEngine::StartUsbServices()   status.Int()=%d", status.Int());
+	return status.Int();
+	}
+
+TInt CUsbControlAppEngine::EnableFunctionDriverLoading()
+	{
+	TInt err = iUsb.EnableFunctionDriverLoading();
+	LOG("CUsbControlAppEngine::EnableFunctionDriverLoading()   err=%d", err);
+	return err;
+	}
+
+void CUsbControlAppEngine::DisableFunctionDriverLoading()
+	{
+	PNT("CUsbControlAppEngine::DisableFunctionDriverLoading()\n");
+	iUsb.DisableFunctionDriverLoading();
+	}
+
+TInt CUsbControlAppEngine::BusRequest()
+	{
+	TInt err = iUsb.BusRequest();
+	LOG("CUsbControlAppEngine::BusRequest()   err=%d", err);
+	return err;
+	}
+
+TInt CUsbControlAppEngine::BusDrop()
+	{
+	TInt err = iUsb.BusDrop();
+	LOG("CUsbControlAppEngine::BusDrop()   err=%d", err);
+	return err;
+	}
+
+TInt CUsbControlAppEngine::BusRespondSrp()
+	{
+	TInt err = iUsb.BusRespondSrp();
+	LOG("CUsbControlAppEngine::BusRespondSrp()   err=%d", err);
+	return err;
+	}
+
+TInt CUsbControlAppEngine::ClearVBusError()
+	{
+	TInt err = iUsb.BusClearError();
+	LOG("CUsbControlAppEngine::ClearVBusError()   err=%d", err);
+	return err;
+	}
+
+// Must divide the user message to be displayed into segments that will fit on the usbviewer.exe window.
+// Because the viewer.exe displays Events in a downward scrolling list with the latest entry at the top,
+// the user message segments must be sent in reverse order.
+void CUsbControlAppEngine::DisplayUserMessage(const TDesC& aUserMsg)
+	{
+	LOG("CUsbControlAppEngine::DisplayUserMessage(\"%S\")\n", &aUserMsg);
+	TInt msgLength = aUserMsg.Length();
+	TInt lastBitLength = msgLength % KEventLineMsgNumCharacters;
+	LOG("CUsbControlAppEngine::DisplayUserMessage	 lastBitLength => %d", lastBitLength);
+	if (lastBitLength) // show the 'last bit' segment of the message which is not divisible by KEventLineMsgNumCharacters
+		{
+		TBuf<KEventLineNumCharacters> buf(KPrefix);
+		TPtrC text = aUserMsg.Right(lastBitLength);
+		buf.Append(text);
+		LOG("CUsbControlAppEngine::DisplayUserMessage	 iViewerMsgQ.Send(buf) buf => %S", &buf);
+		TInt err = iViewerMsgQ.Send(buf);
+		LOG("CUsbControlAppEngine::DisplayUserMessage	 iViewerMsgQ.Send(buf) err => %d", err);
+		}
+	msgLength -= lastBitLength;
+	while (msgLength > 0) // show the segments of the message which are exactly divisible by KEventLineMsgNumCharacters
+		{
+		// TBuf of length KEventLineNumCharacters = KPrefix of length 2 + Mid bit of length KEventLineMsgNumCharacters
+		TBuf<KEventLineNumCharacters> buf(KPrefix);
+		TPtrC text = aUserMsg.Mid(msgLength-KEventLineMsgNumCharacters, KEventLineMsgNumCharacters);
+		buf.Append(text);
+		LOG("CUsbControlAppEngine::DisplayUserMessage	 iViewerMsgQ.Send(buf) buf => %S", &buf);
+		TInt err = iViewerMsgQ.Send(buf);
+		LOG("CUsbControlAppEngine::DisplayUserMessage	 iViewerMsgQ.Send(buf) err => %d", err);		
+		msgLength -= KEventLineMsgNumCharacters;
+		}
+	}
+
+// Called by Watchers. Will forward as event to State Machine.
+void CUsbControlAppEngine::SetIdPin(TInt aIdPin)
+	{
+	PNT("CUsbControlAppEngine::SetIdPin()\n");
+	iIdPin = aIdPin;
+	__ASSERT_ALWAYS(iStateMachine, PANIC);
+	aIdPin ? iStateMachine->IdPinPresent() : iStateMachine->IdPinAbsent();
+	}
+
+void CUsbControlAppEngine::SetVBus(TInt aVBus)
+	{
+	PNT("CUsbControlAppEngine::SetVBus()\n");
+	iVBus = aVBus;
+	__ASSERT_ALWAYS(iStateMachine, PANIC);
+	aVBus ? iStateMachine->VBusRise() : iStateMachine->VBusDrop();
+	}
+
+void CUsbControlAppEngine::SetConnectionIdle(TInt aConnIdle)
+	{
+	PNT("CUsbControlAppEngine::SetConnectionIdle()\n");
+	iConnIdle = aConnIdle;
+	__ASSERT_ALWAYS(iStateMachine, PANIC);
+	aConnIdle ? iStateMachine->ConnectionIdle() : iStateMachine->ConnectionActive();
+	}
+
+void CUsbControlAppEngine::MessageReceived(CMessageWatcher::TMessageWatcherNotifications aMessageNotification)
+	{
+	switch(aMessageNotification)
+		{
+	case CMessageWatcher::EUsbMessageRequestSession :
+		PNT("CUsbControlAppEngine::MessageReceived()	EUsbMessageRequestSession\n");
+		iStateMachine->RequestSessionCalled();
+		break;
+	case CMessageWatcher::EUsbMessageSrpReceived :
+		PNT("CUsbControlAppEngine::MessageReceived()	EUsbMessageSrpReceived\n");
+		iStateMachine->SrpDetected();
+		break;
+	case CMessageWatcher::EErrUsbOtgSrpTimeout :
+		PNT("CUsbControlAppEngine::MessageReceived()	EErrUsbOtgSrpTimeout\n");
+		iStateMachine->SrpTimeout();
+		break;
+	case CMessageWatcher::EErrUsbOtgVbusError :
+		PNT("CUsbControlAppEngine::MessageReceived()	EErrUsbOtgVbusError\n");
+		iStateMachine->VBusError();
+		break;
+	default:
+		PANIC;
+		}
+	}
+
+RUsb& CUsbControlAppEngine::Usb()
+	{
+	return iUsb;
+	}
+
+TInt CUsbControlAppEngine::GetIdPin()
+	{
+	return iIdPin;
+	}
+
+TInt CUsbControlAppEngine::GetVBus()
+	{
+	return iVBus;
+	}
+
+
+CControlAppStateMachine* CControlAppStateMachine::NewL(MControlAppEngineInterface& aControlAppEngine)
+	{
+	CControlAppStateMachine* self = new(ELeave) CControlAppStateMachine(aControlAppEngine);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	PNT("CControlAppStateMachine::NewL\n");
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CControlAppStateMachine::~CControlAppStateMachine()
+	{
+	delete iStateAServicesStopped;
+	delete iStateAServicesStarted;
+	delete iStateBServicesStarted;
+	delete iStateBServicesStopped;
+	delete iStateInitial;
+	delete iInactivityTimer;
+	}
+
+CControlAppStateMachine::CControlAppStateMachine(MControlAppEngineInterface& aControlAppEngine)
+	: iParentControlAppEngine(aControlAppEngine)
+	, iTriggerSrp(EFalse)
+	{
+	}
+
+void CControlAppStateMachine::ConstructL()
+	{
+	iInactivityTimer		= CInactivityTimer::NewL(*this);
+	iStateInitial			= new(ELeave) CControlAppStateInitial(*this);
+	iStateBServicesStopped	= new(ELeave) CControlAppStateBServicesStopped(*this);
+	iStateBServicesStarted	= new(ELeave) CControlAppStateBServicesStarted(*this);
+	iStateAServicesStarted	= new(ELeave) CControlAppStateAServicesStarted(*this);
+	iStateAServicesStopped	= new(ELeave) CControlAppStateAServicesStopped(*this);
+	SetState(EStateInitial);
+	}
+
+void CControlAppStateMachine::SetState(TControlAppState aState)
+	{
+	TPtrC StateString(NULL, 0);
+	//               123456789
+	_LIT(KInitial,	" Initial ");
+	_LIT(KBStopped, "B-Stopped");
+	_LIT(KBStarted, "B-Started");
+	_LIT(KAStopped, "A-Stopped");
+	_LIT(KAStarted, "A-Started");
+	switch(aState)
+		{
+	case EStateInitial :			
+		StateString.Set(KInitial);		
+		iCurrentState = iStateInitial;		
+		break;
+	case EStateBServicesStopped :	
+		StateString.Set(KBStopped);		
+		iCurrentState = iStateBServicesStopped;		
+		break;
+	case EStateBServicesStarted :	
+		StateString.Set(KBStarted);		
+		iCurrentState = iStateBServicesStarted;		
+		break;
+	case EStateAServicesStopped :	
+		StateString.Set(KAStopped);		
+		iCurrentState = iStateAServicesStopped;		
+		break;
+	case EStateAServicesStarted :	
+		StateString.Set(KAStarted);		
+		iCurrentState = iStateAServicesStarted;	
+		break;
+	default :	PANIC;
+		}
+	//                                         (123456789)  ***
+	BLN("");
+	PNT("******************************************************");
+	LOG("***  CControlAppStateMachine::SetState(%S)  ***", &StateString);
+	PNT("******************************************************");
+	BLN("");
+	}
+
+// State Machine's publicly visible interface...
+//		Initial
+void CControlAppStateMachine::StartUp()
+	{
+	PNT("CControlAppStateMachine::StartUp() - event will be forwarded to current state\n");
+	__ASSERT_ALWAYS(iCurrentState, PANIC);
+	// Could implement global USB enabled/disabled policy here by allowing/preventing event reaching current state
+	iCurrentState->StartUp();
+	}
+
+//		B-Stopped, B-Started
+void CControlAppStateMachine::IdPinPresent()
+	{
+	PNT("CControlAppStateMachine::IdPinPresent() - event will be forwarded to current state\n");
+	__ASSERT_ALWAYS(iCurrentState, PANIC);
+	// Could implement global USB enabled/disabled policy here by allowing/preventing event reaching current state
+	iCurrentState->IdPinPresent(); 
+	}
+	
+//		B-Stopped, A-Started
+void CControlAppStateMachine::VBusRise()
+	{
+	PNT("CControlAppStateMachine::VBusRise() - event will be forwarded to current state\n");
+	__ASSERT_ALWAYS(iCurrentState, PANIC);
+	// Could implement global USB enabled/disabled policy here by allowing/preventing event reaching current state		
+	iCurrentState->VBusRise();
+	}
+
+//		B-Started, A-Started
+void CControlAppStateMachine::VBusDrop()
+	{
+	PNT("CControlAppStateMachine::VBusDrop() - event will be forwarded to current state\n");
+	__ASSERT_ALWAYS(iCurrentState, PANIC);
+	// Could implement global USB enabled/disabled policy here by allowing/preventing event reaching current state
+	iCurrentState->VBusDrop();
+	}
+
+//		A-Started, A-Stopped
+void CControlAppStateMachine::IdPinAbsent()
+	{
+	PNT("CControlAppStateMachine::IdPinAbsent() - event will be forwarded to current state\n");
+	__ASSERT_ALWAYS(iCurrentState, PANIC);
+	// Could implement global USB enabled/disabled policy here by allowing/preventing event reaching current state
+	iCurrentState->IdPinAbsent();
+	}
+
+//		A-Started
+void CControlAppStateMachine::ConnectionIdle()
+	{
+	PNT("CControlAppStateMachine::ConnectionIdle() - event will be forwarded to current state\n");
+	__ASSERT_ALWAYS(iCurrentState, PANIC);
+	// Could implement global USB enabled/disabled policy here by allowing/preventing event reaching current state
+	iCurrentState->ConnectionIdle();
+	}
+
+//		A-Started
+void CControlAppStateMachine::ConnectionActive()
+	{
+	PNT("CControlAppStateMachine::ConnectionActive() - event will be forwarded to current state\n");
+	__ASSERT_ALWAYS(iCurrentState, PANIC);
+	// Could implement global USB enabled/disabled policy here by allowing/preventing event reaching current state
+	iCurrentState->ConnectionActive();
+	}
+
+//		B-Stopped, A-Stopped, B-Started, A-Started
+void CControlAppStateMachine::RequestSessionCalled()
+	{
+	PNT("CControlAppStateMachine::RequestSessionCalled() - event will be forwarded to current state\n");
+	__ASSERT_ALWAYS(iCurrentState, PANIC);
+	// Could implement global USB enabled/disabled policy here by allowing/preventing event reaching current state
+	iCurrentState->RequestSessionCalled();
+	}
+
+//		B-Started
+void CControlAppStateMachine::SrpTimeout()
+	{
+	PNT("CControlAppStateMachine::SrpTimeout() - event will be forwarded to current state\n");
+	__ASSERT_ALWAYS(iCurrentState, PANIC);
+	// Could implement global USB enabled/disabled policy here by allowing/preventing event reaching current state
+	iCurrentState->SrpTimeout();
+	}
+
+//		A-Stopped
+void CControlAppStateMachine::SrpDetected()
+	{
+	PNT("CControlAppStateMachine::SrpDetected() - event will be forwarded to current state\n");
+	__ASSERT_ALWAYS(iCurrentState, PANIC);
+	// Could implement global USB enabled/disabled policy here by allowing/preventing event reaching current state
+	iCurrentState->SrpDetected();
+	}
+
+//		A-Started, A-Stopped
+void CControlAppStateMachine::VBusError()
+	{
+	PNT("CControlAppStateMachine::VBusError() - event will be forwarded to current state\n");
+	__ASSERT_ALWAYS(iCurrentState, PANIC);
+	// Could implement global USB enabled/disabled policy here by allowing/preventing event reaching current state
+	iCurrentState->VBusError();
+	}
+
+void CControlAppStateMachine::ResetInactivityTimer()
+	{
+	PNT("CControlAppStateMachine::ResetInactivityTimer()\n");
+	iInactivityTimer->Reset();
+	}
+
+void CControlAppStateMachine::CancelInactivityTimer()
+	{
+	PNT("CControlAppStateMachine::CancelInactivityTimer()\n");
+	iInactivityTimer->Cancel();
+	}
+
+void CControlAppStateMachine::InactivityTimerExpired()
+	{
+	PNT("CControlAppStateMachine::InactivityTimerExpired()\n");
+	iCurrentState->InactivityTimerExpired();
+	}
+
+
+CControlAppStateMachine::CInactivityTimer* CControlAppStateMachine::CInactivityTimer::NewL(CControlAppStateMachine& aParentStateMachine)
+	{
+	PNT("CControlAppStateMachine::CInactivityTimer::NewL()\n");
+	CControlAppStateMachine::CInactivityTimer* self = new(ELeave) CControlAppStateMachine::CInactivityTimer(aParentStateMachine);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CControlAppStateMachine::CInactivityTimer::~CInactivityTimer()
+	{
+	PNT("CControlAppStateMachine::CInactivityTimer::~CInactivityTimer()\n");
+	Cancel();
+	iTimer.Close();
+	}
+
+CControlAppStateMachine::CInactivityTimer::CInactivityTimer(CControlAppStateMachine& aParentStateMachine)
+	: CActive(EPriorityStandard)
+	, iParentStateMachine(aParentStateMachine)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CControlAppStateMachine::CInactivityTimer::ConstructL()
+	{
+	PNT("CControlAppStateMachine::CInactivityTimer::ConstructL\n");
+	TInt err = iTimer.CreateLocal();
+	LOG("CInactivityTimer::ConstructL	iTimer.CreateLocal() => %d",err);
+	User::LeaveIfError(err);
+	}
+
+void CControlAppStateMachine::CInactivityTimer::Reset()
+	{
+	PNT("CControlAppStateMachine::CInactivityTimer::Reset()\n");
+	if (IsActive())
+		{
+		PNT("CControlAppStateMachine::CInactivityTimer::Reset() - IsActive() so Cancel() before setting RTimer\n");
+		Cancel(); // Reset
+		}
+	iTimer.After(iStatus, KInactivityTimerPeriod); // 10 sec
+	SetActive();
+	}
+	
+void CControlAppStateMachine::CInactivityTimer::RunL()
+	{
+	PNT("CControlAppStateMachine::CInactivityTimer::RunL() - calling iParentState.InactivityTimerExpired()\n");
+	iParentStateMachine.InactivityTimerExpired();
+	}
+
+void CControlAppStateMachine::CInactivityTimer::DoCancel()
+	{
+	PNT("CControlAppStateMachine::CInactivityTimer::DoCancel()\n");
+	iTimer.Cancel();
+	}
+
+
+// Base state...
+CControlAppStateMachine::CControlAppStateBase::CControlAppStateBase(CControlAppStateMachine& aParentStateMachine)
+	: iParentStateMachine(aParentStateMachine)
+	{
+	}
+
+void CControlAppStateMachine::CControlAppStateBase::StartUp()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::StartUp() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+
+void CControlAppStateMachine::CControlAppStateBase::IdPinPresent()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::IdPinPresent() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+	
+void CControlAppStateMachine::CControlAppStateBase::VBusRise()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::VBusRise() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+
+void CControlAppStateMachine::CControlAppStateBase::VBusDrop()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::VBusDrop() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+
+void CControlAppStateMachine::CControlAppStateBase::IdPinAbsent()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::IdPinAbsent() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+
+void CControlAppStateMachine::CControlAppStateBase::ConnectionIdle()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::ConnectionIdle() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+
+void CControlAppStateMachine::CControlAppStateBase::ConnectionActive()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::ConnectionActive() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+
+void CControlAppStateMachine::CControlAppStateBase::InactivityTimerExpired()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::InactivityTimerExpired() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+
+void CControlAppStateMachine::CControlAppStateBase::RequestSessionCalled()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::RequestSessionCalled() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+
+void CControlAppStateMachine::CControlAppStateBase::SrpTriggered()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::SrpTriggered() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+
+void CControlAppStateMachine::CControlAppStateBase::SrpTimeout()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::SrpTimeout() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+
+void CControlAppStateMachine::CControlAppStateBase::SrpDetected()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::SrpDetected() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+
+void CControlAppStateMachine::CControlAppStateBase::VBusError()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBase::VBusError() - ERROR: unexpected event in current state\n");
+	DBG_PANIC;
+	}
+
+
+// Initial state...
+CControlAppStateMachine::CControlAppStateInitial::CControlAppStateInitial(CControlAppStateMachine& aParentStateMachine)
+	: CControlAppStateBase(aParentStateMachine)
+	{
+	}
+
+void CControlAppStateMachine::CControlAppStateInitial::VBusRise()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateInitial::VBusRise() - no action: wait for StartUp event\n");
+	}
+
+void CControlAppStateMachine::CControlAppStateInitial::VBusDrop()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateInitial::VBusDrop() - no action: wait for StartUp event\n");
+	}
+
+void CControlAppStateMachine::CControlAppStateInitial::IdPinPresent()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateInitial::IdPinPresent() - no action: wait for StartUp event\n");
+	}
+
+void CControlAppStateMachine::CControlAppStateInitial::IdPinAbsent()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateInitial::IdPinAbsent() - no action: wait for StartUp event\n");
+	}
+
+void CControlAppStateMachine::CControlAppStateInitial::ConnectionIdle()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateInitial::ConnectionIdle() - no action: wait for StartUp event\n");
+	}
+
+void CControlAppStateMachine::CControlAppStateInitial::ConnectionActive()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateInitial::ConnectionActive() - no action: wait for StartUp event\n");
+	}
+
+void CControlAppStateMachine::CControlAppStateInitial::StartUp()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()\n");
+	// Determine state to move to from the Initial
+	if (iParentStateMachine.iParentControlAppEngine.GetIdPin())
+		{
+		PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	Id Pin detected\n");
+		TInt err = iParentStateMachine.iParentControlAppEngine.StartUsbServices();
+		if (!err) // Started USB services
+			{
+			PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	Started USB services\n");
+			iParentStateMachine.SetState(EStateAServicesStarted);
+			err = iParentStateMachine.iParentControlAppEngine.EnableFunctionDriverLoading();
+			if (!err) // Started USB services & enabled FD loading
+				{
+				PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	Enabled FD loading\n");
+				}
+			else // Started USB services & couldn't enable FD loading
+				{
+				PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	Couldn't enable FD loading\n");
+				_LIT(KMsgCouldntEnableFdLoading,	"Error: Couldn't enable driver loading - can't function as host");
+				iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntEnableFdLoading);
+				}
+			// Regardless of whether enabling FD loading succeeded or not do BusRequest() to power VBus
+			err = iParentStateMachine.iParentControlAppEngine.BusRequest(); 
+			if (!err)
+				{
+				PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	BusRequest() successful\n");
+				}
+			else
+				{
+				PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	BusRequest() failed\n");
+				// This error only indicates whether USBMAN server got the request without any problem.
+				// VBus could still fail to go up but this is only likely if there is a Bus Error - this is 
+				// handled in a separate event though.
+				_LIT(KMsgCouldntPowerUsbDevice,	"Error: Couldn't power USB device - press 'R' to try again");
+				iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntPowerUsbDevice);
+				// CControlAppStateAServicesStarted::VBusRise() ensures Inactivity Timer is activated when the BusRequest()
+				// is successful, but when it fails we must ensure USB services will be eventually stopped:
+				iParentStateMachine.ResetInactivityTimer();
+				}
+			}
+		else // Couldn't start USB services
+			{
+			PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	Couldn't start USB services\n");
+			_LIT(KMsgCouldntStartUsb,	"Error: Couldn't start USB services");
+			iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntStartUsb);
+			iParentStateMachine.SetState(EStateAServicesStopped); // Since Id Pin is present
+			}
+		} // if (iParentStateMachine.iParentControlAppEngine.GetIdPin())
+	else // i.e. no Id Pin
+		{
+		if (iParentStateMachine.iParentControlAppEngine.GetVBus())
+			{
+			PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	Id Pin Absent & VBus detected\n");
+			TInt err = iParentStateMachine.iParentControlAppEngine.StartUsbServices();
+			if (!err) // Started USB services
+				{
+				PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	Started USB services\n");
+				iParentStateMachine.SetState(EStateBServicesStarted);
+				err = iParentStateMachine.iParentControlAppEngine.EnableFunctionDriverLoading();
+				if (!err) // Started USB services & enabled FD loading
+					{
+					PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	Enabled FD loading\n");
+					}
+				else // Started USB services & couldn't enable FD loading
+					{
+					PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	couldn't enable FD loading\n");
+					_LIT(KMsgCouldntEnableFdLoading,	"Error: Couldn't enable driver loading - can't function as host");
+					iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntEnableFdLoading);
+					}
+				}
+			else // Couldn't start USB services
+				{
+				PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	Couldn't start USB services\n");
+				iParentStateMachine.SetState(EStateBServicesStopped); // even though VBus
+				_LIT(KMsgCouldntStartUsb,	"Error: Couldn't start USB services");
+				iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntStartUsb);
+				}
+			} // if (iParentStateMachine.iParentControlAppEngine.GetVBus())
+		else  // if (iParentStateMachine.iParentControlAppEngine.GetVBus())
+			{
+			PNT("CControlAppStateMachine::CControlAppStateInitial::StartUp()	Id Pin Absent & VBus not detected\n");
+			iParentStateMachine.SetState(EStateBServicesStopped);
+			}
+		} // else i.e. no Id Pin
+	}
+
+
+// BServicesStopped state...
+CControlAppStateMachine::CControlAppStateBServicesStopped::CControlAppStateBServicesStopped(CControlAppStateMachine& aParentStateMachine)
+	: CControlAppStateBase(aParentStateMachine)
+	{
+	}
+
+// Power detected on VBus
+// Try to move to B-Started
+void CControlAppStateMachine::CControlAppStateBServicesStopped::VBusRise()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::VBusRise()	VBus detected\n");
+	TInt err = iParentStateMachine.iParentControlAppEngine.StartUsbServices();
+	if (!err) // Started USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::VBusRise()	Started USB services\n");
+		iParentStateMachine.SetState(EStateBServicesStarted);
+		err = iParentStateMachine.iParentControlAppEngine.EnableFunctionDriverLoading();
+		if (!err) // Started USB services & enabled FD loading
+			{
+			PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::VBusRise()	Enabled FD loading\n");
+			}
+		else // Started USB services & couldn't enable FD loading
+			{
+			PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::VBusRise()	couldn't enable FD loading\n");
+			_LIT(KMsgCouldntEnableFdLoading,	"Error: Couldn't enable driver loading - can't function as host");
+			iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntEnableFdLoading);
+			}
+		}
+	else // Couldn't start USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::VBusRise()	Couldn't start USB services\n");
+		_LIT(KMsgCouldntStartUsb,	"Error: Couldn't start USB services");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntStartUsb);
+		}
+	}
+
+// Id Pin detected
+// Try to move to A-Started
+void CControlAppStateMachine::CControlAppStateBServicesStopped::IdPinPresent()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::IdPinPresent()\n");
+	TInt err = iParentStateMachine.iParentControlAppEngine.StartUsbServices();
+	if (!err) // Started USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::IdPinPresent()	Started USB services\n");
+		iParentStateMachine.SetState(EStateAServicesStarted);
+		err = iParentStateMachine.iParentControlAppEngine.EnableFunctionDriverLoading();
+		if (!err) // Started USB services & enabled FD loading
+			{
+			PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::IdPinPresent()	Enabled FD loading\n");
+			}
+		else // Started USB services & couldn't enable FD loading
+			{
+			PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::IdPinPresent()	Couldn't enable FD loading\n");
+			_LIT(KMsgCouldntEnableFdLoading,	"Error: Couldn't enable driver loading - can't function as host");
+			iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntEnableFdLoading);
+			}
+		// Regardless of whether enabling FD loading succeeded or not, attempt to power VBus
+		err = iParentStateMachine.iParentControlAppEngine.BusRequest(); 
+		if (!err)
+			{
+			PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::IdPinPresent()	BusRequest() successful\n");
+			}
+		else
+			{
+			PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::IdPinPresent()	BusRequest() failed\n");
+			// This error only indicates whether USBMAN server got the request without any problem.
+			// VBus could still fail to go up but this is only likely if there is a Bus Error - this is 
+			// handled in a separate event though.
+			_LIT(KMsgCouldntPowerUsbDevice,	"Error: Couldn't power USB device - press 'R' to try again");
+			iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntPowerUsbDevice);
+			// CControlAppStateAServicesStarted::VBusRise() ensures Inactivity Timer is activated when the BusRequest()
+			// is successful, but when it fails we must ensure USB services will be eventually stopped:
+			iParentStateMachine.ResetInactivityTimer();
+			}
+		}
+	else // Couldn't start USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::IdPinPresent()	Couldn't start USB services\n");
+		iParentStateMachine.SetState(EStateAServicesStopped); // Since Id Pin is present
+		_LIT(KMsgCouldntStartUsb,	"Error: Couldn't start USB services");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntStartUsb);
+		}
+	}
+
+// RUsb::RequestSession() called from USB Aware App
+// Try to move to B-Started and trigger SRP
+void CControlAppStateMachine::CControlAppStateBServicesStopped::RequestSessionCalled()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::RequestSessionCalled()\n");
+	TInt err = iParentStateMachine.iParentControlAppEngine.StartUsbServices();
+	if (!err) // Started USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::RequestSessionCalled()	Started USB services\n");
+		iParentStateMachine.SetState(EStateBServicesStarted); // Do this before SrpTriggered()
+		err = iParentStateMachine.iParentControlAppEngine.EnableFunctionDriverLoading();
+		if (!err) // Started USB services & enabled FD loading
+			{
+			PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::RequestSessionCalled()	Enabled FD loading\n");	
+			iParentStateMachine.iCurrentState->SrpTriggered(); // Internally generated event in B-Started state
+			}
+		else // Started USB services & couldn't enable FD loading
+			{
+			PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::RequestSessionCalled()	Couldn't enable FD loading\n");
+			_LIT(KMsgCouldntEnableFdLoading,	"Error: Couldn't enable driver loading - can't function as host");
+			iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntEnableFdLoading);
+			// No point doing SRP since wont be able to enumerate peripheral
+			}
+		}
+	else // Couldn't start USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::RequestSessionCalled()	Couldn't start USB services\n");
+		_LIT(KMsgCouldntStartUsb,	"Error: Couldn't start USB services");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntStartUsb);
+		}
+	}
+
+void CControlAppStateMachine::CControlAppStateBServicesStopped::VBusDrop()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::VBusDrop()	no action: this A-Device dropped VBus before moving into this state\n");
+	DBG_PANIC;
+	}
+
+
+// BServicesStarted state...
+CControlAppStateMachine::CControlAppStateBServicesStarted::CControlAppStateBServicesStarted(CControlAppStateMachine& aParentStateMachine)
+	: CControlAppStateBase(aParentStateMachine)
+	{
+	}
+
+// VBus not being powered any more by remote device
+// Try to stop USB services and move to B-Stopped
+void CControlAppStateMachine::CControlAppStateBServicesStarted::VBusDrop()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::VBusDrop()\n");
+	TInt err = iParentStateMachine.iParentControlAppEngine.StopUsbServices();
+	if (!err) // Stopped USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::VBusDrop()	Stopped USB services\n");
+		iParentStateMachine.SetState(EStateBServicesStopped);
+		}
+	else // Couldn't stop USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::VBusDrop()	Couldn't stop USB services\n");
+		// Stay in current state B-Started.
+		// VBus probably dropped as a result of B-Plug being withdrawn (or remote A-Device powering down VBus).
+		// If A-Plug inserted, will move to A-Started from this state. (If VBus is re-powered, in the correct state too).
+		_LIT(KMsgCouldntStopUsb,	"Error: Couldn't stop USB services");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntStopUsb);
+		}
+	}
+
+// We've come from B-Stopped to trigger an SRP
+// If SRP times out (notification from USBMAN will be another separate event received) we'll return to B-Stopped.
+// If SRP successful, VBus will be powered and we can stay in the current state.
+void CControlAppStateMachine::CControlAppStateBServicesStarted::SrpTriggered()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::SrpTriggered()\n");
+	TInt err = iParentStateMachine.iParentControlAppEngine.BusRequest(); // SRP
+	// If no err, we don't have to do anything
+	if (!err)
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::SrpTriggered()	BusRequest for SRP successful\n");
+		}
+	else // Was problem doing SRP - won't get SRP timeout event - go back to B-Stopped now
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::SrpTriggered()	BusRequest for SRP failed\n");
+		_LIT(KMsgFailedBecomingHost,	"Error: Failed to become Host");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgFailedBecomingHost);
+		err = iParentStateMachine.iParentControlAppEngine.StopUsbServices();
+		if (!err) // Cleaned up by stopping USB services
+			{
+			PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::SrpTriggered()	Stopped USB services\n");
+			iParentStateMachine.SetState(EStateBServicesStopped);
+			}
+		else
+			{
+			PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::SrpTriggered()	Couldn't stop USB services\n");
+			_LIT(KMsgCouldntStopUsb,	"Error: Couldn't stop USB services");
+			iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntStopUsb);
+			// Stay in current state B-Started.
+			// Can re-try SRP by doing RequestSession() -> BusRequest() in this state.
+			// No event received if B-Plug is withdrawn.
+			// If A-Plug inserted, will move to A-Started from this state.
+			}
+		}
+	}
+
+// Message notification from USBMAN that SRP requested earlier has timed out.
+// Try to move to B-Stopped
+void CControlAppStateMachine::CControlAppStateBServicesStarted::SrpTimeout()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::SrpTimeout()\n");
+	TInt err = iParentStateMachine.iParentControlAppEngine.StopUsbServices();
+	if (!err) // Stopped USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::SrpTimeout()	Stopped USB services\n");
+		iParentStateMachine.SetState(EStateBServicesStopped);
+		}
+	else // Couldn't stop USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::SrpTimeout()	Couldn't stop USB services\n");
+		_LIT(KMsgCouldntStopUsb,	"Error: Couldn't stop USB services");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntStopUsb);
+		// Stay in current state B-Started. 
+		// Can re-try SRP by doing RequestSession() -> BusRequest() in this state.
+		// No event received if B-Plug is withdrawn.
+		// If A-Plug inserted, will move to A-Started from this state.
+		}
+	}
+
+// Will see when SRP successful
+void CControlAppStateMachine::CControlAppStateBServicesStarted::VBusRise()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::VBusRise()\n");
+	}
+
+// Time taken to notice the drop in VBus by which time the Id Pin has been inserted.
+// Cater for the IdPinPresent event in this state therefore.
+// Try to power VBus and move to A-Started state
+void CControlAppStateMachine::CControlAppStateBServicesStarted::IdPinPresent()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::IdPinPresent()\n");
+	iParentStateMachine.SetState(EStateAServicesStarted); // Since Id Pin present and USB services still started.
+	// USB services already started but may have failed to enable FD loading previously so try again (calling twice does no harm)
+	TInt err = iParentStateMachine.iParentControlAppEngine.EnableFunctionDriverLoading();
+	if (!err)
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::IdPinPresent()	Enabled FD loading\n");	
+		}
+	else 
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::IdPinPresent()	Couldn't enable FD loading\n");
+		_LIT(KMsgCouldntEnableFdLoading,	"Error: Couldn't enable driver loading - can't function as host");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntEnableFdLoading);
+		}
+	err = iParentStateMachine.iParentControlAppEngine.BusRequest();
+	if (!err) // Powered VBus
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::IdPinPresent()	Powered VBus\n");
+		}
+	else // Couldn't power VBus
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::IdPinPresent()	Couldn't power VBus\n");
+		// RequestSession() in A-Started will have the effect of powering VBus
+		_LIT(KMsgCouldntPowerUsbDevice,	"Error: Couldn't power USB device - press 'R' to try again");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntPowerUsbDevice);
+		// CControlAppStateAServicesStarted::VBusRise() ensures Inactivity Timer is activated when the BusRequest()
+		// is successful, but when it fails we must ensure USB services will be eventually stopped:
+		iParentStateMachine.ResetInactivityTimer();
+		}
+	}
+
+// Let underlying OTG deal with what this means in this state
+void CControlAppStateMachine::CControlAppStateBServicesStarted::RequestSessionCalled()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateBServicesStarted::RequestSessionCalled()\n");
+	(void) iParentStateMachine.iParentControlAppEngine.BusRequest(); // Not interested in error code
+	}
+
+
+// AServicesStarted state...
+CControlAppStateMachine::CControlAppStateAServicesStarted::CControlAppStateAServicesStarted(CControlAppStateMachine& aParentStateMachine)
+	: CControlAppStateBase(aParentStateMachine)
+	{
+	}
+
+// A-Plug has been removed
+// Try to move to B-Stopped state
+void CControlAppStateMachine::CControlAppStateAServicesStarted::IdPinAbsent()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::IdPinAbsent()\n");
+	// BusDrop() not needed as VBus unpowered at a lower level if Id Pin not present
+	TInt err = iParentStateMachine.iParentControlAppEngine.StopUsbServices();
+	if (!err) // Stopped USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::IdPinAbsent()	Stopped USB services	(BusDrop unnecessary here)\n");
+		iParentStateMachine.SetState(EStateBServicesStopped);
+		}
+	else // Couldn't stop USB services started & Id Pin absent - go to B-Started
+		{
+		PNT("CControlAppStateMachine::CControlAppStateBServicesStopped::IdPinAbsent()	Couldn't stop USB services\n");
+		// Move to B-Started since no Id Pin but USB services still started.
+		iParentStateMachine.SetState(EStateBServicesStarted);
+		_LIT(KMsgCouldntStopUsb,	"Error: Couldn't stop USB services");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntStopUsb);
+		}
+	}
+
+// Remote B-Device sent SRP
+// It is possible for VBus to be down in A-Started state so SRP could arrive
+void CControlAppStateMachine::CControlAppStateAServicesStarted::SrpDetected()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::SrpDetected()\n");
+	TInt err = iParentStateMachine.iParentControlAppEngine.BusRespondSrp();
+	if (!err)
+		{
+		PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::SrpDetected()	BusRespondSrp() succeeded\n");
+		}
+	else
+		{
+		PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::SrpDetected()	BusRespondSrp() error\n");
+		_LIT(KMsgCouldntPowerUsbDevice,	"Error: Couldn't power USB device");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntPowerUsbDevice);
+		}
+	}
+
+void CControlAppStateMachine::CControlAppStateAServicesStarted::VBusRise()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::VBusRise() - start Inactivity Timer...\n");
+	iParentStateMachine.ResetInactivityTimer();
+	}
+
+void CControlAppStateMachine::CControlAppStateAServicesStarted::ConnectionIdle()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::ConnectionIdle()\n");
+	iParentStateMachine.ResetInactivityTimer();
+	}
+
+void CControlAppStateMachine::CControlAppStateAServicesStarted::ConnectionActive()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::ConnectionActive()\n");
+	iParentStateMachine.CancelInactivityTimer();
+	}
+
+void CControlAppStateMachine::CControlAppStateAServicesStarted::InactivityTimerExpired()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::InactivityTimerExpired()\n");
+	TInt err = iParentStateMachine.iParentControlAppEngine.BusDrop();
+	if (!err)
+		{
+		PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::InactivityTimerExpired()	Dropped VBus\n");
+		err = iParentStateMachine.iParentControlAppEngine.StopUsbServices();
+		if (!err) // Stopped USB services
+			{
+			PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::InactivityTimerExpired()	Stopped USB services\n");
+			iParentStateMachine.SetState(EStateAServicesStopped);
+			}
+		else // Couldn't stop USB services started & Id Pin present - stay in A-Started
+			{
+			PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::InactivityTimerExpired()	Couldn't stop USB services\n");
+			_LIT(KMsgCouldntStopUsb,	"Error: Couldn't stop USB services");
+			iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntStopUsb);
+			}
+		}
+	else
+		{
+		PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::InactivityTimerExpired()	Can't drop VBus\n");
+		_LIT(KMsgCouldntDropVBus,	"Error: Couldn't drop VBus to save power. Unplug device.");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntDropVBus);
+		}
+	}
+
+// Let underlying OTG deal with what this means in this state
+void CControlAppStateMachine::CControlAppStateAServicesStarted::RequestSessionCalled()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::RequestSessionCalled()\n");
+	(void) iParentStateMachine.iParentControlAppEngine.BusRequest(); // Not interested in error code
+	}
+
+void CControlAppStateMachine::CControlAppStateAServicesStarted::VBusError()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateAServicesStarted::VBusError()\n");
+	iParentStateMachine.CancelInactivityTimer(); // To prevent a BusDrop being done - VBus is already down.
+	(void) iParentStateMachine.iParentControlAppEngine.ClearVBusError(); // Not interested in error code
+	// A call to RequestSession() will be necessary to raise VBus again
+	_LIT(KMsgVBusError,	"Error: Couldn't power USB device - please unplug");
+	iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgVBusError);	
+	}
+
+
+// AServicesStopped state...
+CControlAppStateMachine::CControlAppStateAServicesStopped::CControlAppStateAServicesStopped(CControlAppStateMachine& aParentStateMachine)
+	: CControlAppStateBase(aParentStateMachine)
+	{
+	}
+
+// A-Plug been removed
+// Try to move to B-Stopped
+void CControlAppStateMachine::CControlAppStateAServicesStopped::IdPinAbsent()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::IdPinAbsent()\n");
+	iParentStateMachine.SetState(EStateBServicesStopped);
+	}
+
+// Remote B-Device sent SRP
+// Try to move to A-Started
+void CControlAppStateMachine::CControlAppStateAServicesStopped::SrpDetected()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::SrpDetected()\n");
+	TInt err = iParentStateMachine.iParentControlAppEngine.StartUsbServices();
+	if (!err) // Started USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::SrpDetected()	Started USB services\n");
+		iParentStateMachine.SetState(EStateAServicesStarted);
+		// Need to enable FD loading for when the roles revert back to their defaults
+		// for after the role swap that follows the BusRespondSRP()
+		err = iParentStateMachine.iParentControlAppEngine.EnableFunctionDriverLoading();
+		if (!err) // Started USB services & enabled FD loading
+			{
+			PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::SrpDetected()	Enabled FD loading\n");
+			}
+		else // Started USB services & couldn't enable FD loading
+			{
+			PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::SrpDetected()	Couldn't enable FD loading\n");
+			_LIT(KMsgCouldntEnableFdLoading,	"Error: Couldn't enable driver loading - can't function as host");
+			iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntEnableFdLoading);
+			}
+		// Regardless of whether FD loading succeeded
+		err = iParentStateMachine.iParentControlAppEngine.BusRespondSrp();
+		if (!err)
+			{
+			PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::SrpDetected()	BusRespondSrp() succeeded\n");
+			}
+		else
+			{
+			PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::SrpDetected()	BusRespondSrp() error\n");
+			// In A-Started, if no activity for a while (which will be the case if BusRespondSRP() failed = VBus unpowered)
+			// Inactivity Timer will expire and send the system back to A-Stopped.
+			_LIT(KMsgCouldntPowerUsbDevice,	"Error: Couldn't power USB device");
+			iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntPowerUsbDevice);
+			}
+		}
+	else // Couldn't start USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::SrpDetected()	Couldn't start USB services\n");
+		_LIT(KMsgCouldntStartUsb,	"Error: Couldn't start USB services");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntStartUsb);
+		}
+	}
+
+// Local USB Aware App would like to use USB services
+// Try to move to A-Started
+void CControlAppStateMachine::CControlAppStateAServicesStopped::RequestSessionCalled()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::RequestSessionCalled()\n");
+	TInt err = iParentStateMachine.iParentControlAppEngine.StartUsbServices();
+	if (!err) // Started USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::RequestSessionCalled()	Started USB services\n");
+		iParentStateMachine.SetState(EStateAServicesStarted);
+		// In A-Started, if no activity for a while, which will be the case if 
+		// EnableFunctionDriverLoading() fails (= no host activity) or BusRequest() fails (= no VBus)
+		// Inactivity Timer will expire soon and send the system back to A-Stopped.
+		err = iParentStateMachine.iParentControlAppEngine.EnableFunctionDriverLoading();
+		if (!err) // Started USB services & enabled FD loading
+			{
+			PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::RequestSessionCalled()	Enabled FD loading\n");
+			}
+		else // Started USB services & couldn't enable FD loading
+			{
+			PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::RequestSessionCalled()	Couldn't enable FD loading\n");
+			_LIT(KMsgCouldntEnableFdLoading,	"Error: Couldn't enable driver loading - can't function as host");
+			iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntEnableFdLoading);
+			}
+		// Regardless of whether enabling FD loading succeeded
+		err = iParentStateMachine.iParentControlAppEngine.BusRequest();
+		if (!err)
+			{
+			PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::RequestSessionCalled()	BusRequest() succeeded\n");
+			}
+		else
+			{
+			PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::RequestSessionCalled()	BusRequest() error\n");
+			_LIT(KMsgCouldntPowerUsbDevice,	"Error: Couldn't power USB device");
+			iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntPowerUsbDevice);
+			// CControlAppStateAServicesStarted::VBusRise() ensures Inactivity Timer is activated when the BusRequest()
+			// is successful, but when it fails we must ensure USB services will be eventually stopped:
+			iParentStateMachine.ResetInactivityTimer();
+			}
+		}
+	else // Couldn't start USB services
+		{
+		PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::RequestSessionCalled()	Couldn't start USB services\n");
+		_LIT(KMsgCouldntStartUsb,	"Error: Couldn't start USB services");
+		iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgCouldntStartUsb);
+		}
+	}
+
+void CControlAppStateMachine::CControlAppStateAServicesStopped::VBusError()
+	{
+	PNT("CControlAppStateMachine::CControlAppStateAServicesStopped::VBusError()\n");
+	(void) iParentStateMachine.iParentControlAppEngine.ClearVBusError(); // Not interested in error code
+	// A call to RequestSession() will be necessary to raise VBus again
+	_LIT(KMsgVBusError,	"Error: Couldn't power USB device - please unplug");
+	iParentStateMachine.iParentControlAppEngine.DisplayUserMessage(KMsgVBusError);
+	}
+
+
+CIdPinWatcher* CIdPinWatcher::NewL(MControlAppEngineWatcherInterface& aControlAppEngine)
+	{
+	CIdPinWatcher* self = new(ELeave) CIdPinWatcher(aControlAppEngine);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CIdPinWatcher::~CIdPinWatcher()
+	{
+	Cancel();
+	iIdPinProp.Close();
+	}
+
+CIdPinWatcher::CIdPinWatcher(MControlAppEngineWatcherInterface& aControlAppEngine)
+	: CActive(EPriorityStandard)
+	, iParentControlAppEngine(aControlAppEngine)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CIdPinWatcher::ConstructL()
+	{
+	TInt err = iIdPinProp.Attach(KUidUsbManCategory, KUsbOtgIdPinPresentProperty);
+	LOG("CIdPinWatcher::ConstructL iIdPinProp.Attach(KUidUsbManCategory, KUsbOtgIdPinPresentProperty) => %d",err);
+	User::LeaveIfError(err);
+
+	SubscribeForNotification();
+
+	// Get the current value and update the Engine
+	TInt val;
+	err = iIdPinProp.Get(val);
+	LOG("CIdPinWatcher::ConstructL iIdPinProp.Get(val) => %d",err);
+	User::LeaveIfError(err);
+	iParentControlAppEngine.SetIdPin(val);
+	}
+
+void CIdPinWatcher::SubscribeForNotification()
+	{
+	iIdPinProp.Subscribe(iStatus);
+	SetActive();
+	}
+	
+void CIdPinWatcher::RunL()
+	{
+	SubscribeForNotification();
+	// Get newly changed value
+	TInt val;
+	User::LeaveIfError(iIdPinProp.Get(val));
+	// Update value in Engine
+	iParentControlAppEngine.SetIdPin(val);
+	}
+
+void CIdPinWatcher::DoCancel()
+	{
+	iIdPinProp.Cancel();
+	}
+
+
+	
+CVBusWatcher* CVBusWatcher::NewL(MControlAppEngineWatcherInterface& aControlAppEngine)
+	{
+	CVBusWatcher* self = new(ELeave) CVBusWatcher(aControlAppEngine);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CVBusWatcher::~CVBusWatcher()
+	{
+	Cancel();
+	iVBusProp.Close();
+	}
+
+CVBusWatcher::CVBusWatcher(MControlAppEngineWatcherInterface& aControlAppEngine)
+	: CActive(EPriorityStandard)
+	, iParentControlAppEngine(aControlAppEngine)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CVBusWatcher::ConstructL()
+	{
+	TInt err = iVBusProp.Attach(KUidUsbManCategory, KUsbOtgVBusPoweredProperty);
+	LOG("CVBusWatcher::ConstructL iVBusProp.Attach(KUidUsbManCategory, KUsbOtgVBusPoweredProperty) => %d",err);
+	User::LeaveIfError(err);
+
+	SubscribeForNotification();
+
+	// Get the current value and update the Engine
+	TInt val;
+	err = iVBusProp.Get(val);
+	LOG("CVBusWatcher::ConstructL iVBusProp.Get(val) => %d",err);
+	User::LeaveIfError(err);
+	iParentControlAppEngine.SetVBus(val);
+	}
+
+void CVBusWatcher::SubscribeForNotification()
+	{
+	iVBusProp.Subscribe(iStatus);
+	SetActive();
+	}
+
+void CVBusWatcher::RunL()
+	{
+	SubscribeForNotification();
+	// Get newly changed value
+	TInt val;
+	User::LeaveIfError(iVBusProp.Get(val));
+	// Update value in Engine
+	iParentControlAppEngine.SetVBus(val);
+	}
+
+void CVBusWatcher::DoCancel()
+	{
+	iVBusProp.Cancel();
+	}
+
+
+
+CConnectionIdleWatcher* CConnectionIdleWatcher::NewL(MControlAppEngineWatcherInterface& aControlAppEngine)
+	{
+	CConnectionIdleWatcher* self = new(ELeave) CConnectionIdleWatcher(aControlAppEngine);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CConnectionIdleWatcher::~CConnectionIdleWatcher()
+	{
+	Cancel();
+	iConnIdleProp.Close();
+	}
+
+CConnectionIdleWatcher::CConnectionIdleWatcher(MControlAppEngineWatcherInterface& aControlAppEngine)
+	: CActive(EPriorityStandard)
+	, iParentControlAppEngine(aControlAppEngine)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CConnectionIdleWatcher::ConstructL()
+	{
+	TInt err = iConnIdleProp.Attach(KUidUsbManCategory, KUsbOtgConnectionIdleProperty);
+	LOG("CConnectionIdleWatcher::ConstructL iIdPinProp.Attach(KUidUsbManCategory, KUsbOtgConnectionIdleProperty) => %d",err);
+	User::LeaveIfError(err);
+
+	SubscribeForNotification();
+
+	// Get the current value and update the Engine
+	TInt val;
+	err = iConnIdleProp.Get(val);
+	LOG("CConnectionIdleWatcher::ConstructL iConnIdleProp.Get(val) => %d",err);
+	User::LeaveIfError(err);
+	iParentControlAppEngine.SetConnectionIdle(val);
+	}
+
+void CConnectionIdleWatcher::SubscribeForNotification()
+	{
+	iConnIdleProp.Subscribe(iStatus);
+	SetActive();
+	}
+	
+void CConnectionIdleWatcher::RunL()
+	{
+	SubscribeForNotification();
+	// Get newly changed value
+	TInt val;
+	User::LeaveIfError(iConnIdleProp.Get(val));
+	// Update value in Engine
+	iParentControlAppEngine.SetConnectionIdle(val);
+	}
+
+void CConnectionIdleWatcher::DoCancel()
+	{
+	iConnIdleProp.Cancel();
+	}
+
+
+	
+CMessageWatcher* CMessageWatcher::NewL(MControlAppEngineWatcherInterface& aControlAppEngine)
+	{
+	CMessageWatcher* self = new(ELeave) CMessageWatcher(aControlAppEngine);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CMessageWatcher::~CMessageWatcher()
+	{
+	Cancel();
+	}
+
+CMessageWatcher::CMessageWatcher(MControlAppEngineWatcherInterface& aControlAppEngine)
+	: CActive(EPriorityStandard)
+	, iParentControlAppEngine(aControlAppEngine)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CMessageWatcher::ConstructL()
+	{
+	iParentControlAppEngine.Usb().MessageNotification(iStatus, iMessage);
+	SetActive();
+	}
+
+void CMessageWatcher::DoCancel()
+	{
+	iParentControlAppEngine.Usb().MessageNotificationCancel();
+	}
+
+void CMessageWatcher::RunL()
+	{
+	TInt err = iStatus.Int();
+	if (err)
+		{
+		LOG("CMessageWatcher::RunL()	iStatus.Int()=%d", err);
+		}
+	else
+		{
+		switch(iMessage)
+			{
+			case KErrUsbOtgVbusError:			       	
+				iParentControlAppEngine.MessageReceived(EErrUsbOtgVbusError);
+				break;	
+			case KErrUsbOtgSrpTimeout:			       	
+				iParentControlAppEngine.MessageReceived(EErrUsbOtgSrpTimeout);
+				break;
+			case KUsbMessageSrpReceived:				
+				iParentControlAppEngine.MessageReceived(EUsbMessageSrpReceived);
+				break;
+			case KUsbMessageRequestSession:				
+				iParentControlAppEngine.MessageReceived(EUsbMessageRequestSession);
+				break;
+			default: // The State Machine is not interested in any other messages
+				break;
+			}
+
+		LOG("CMessageWatcher::RunL()	msg = %d", iMessage);
+		} // else
+
+	iParentControlAppEngine.Usb().MessageNotification(iStatus, iMessage);
+	SetActive();
+	}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/exampleusbcontrolapp/exampleusbcontrolapp.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,418 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef EXAMPLEUSBCONTROLAPP_H
+#define EXAMPLEUSBCONTROLAPP_H
+
+#include <e32cmn.h>
+#include <e32base.h>
+#include <usbman.h>
+#include <e32property.h>
+#include "e32msgqueue.h"
+
+#include "usbcontrolappshared.h"
+
+
+class MControlAppEngineWatcherInterface;
+static const TInt KInactivityTimerPeriod = 10000000; // 10 sec
+
+
+NONSHARABLE_CLASS(CIdPinWatcher) : public CActive
+	{
+public:
+	static CIdPinWatcher* NewL(MControlAppEngineWatcherInterface& aControlAppEngine);
+	~CIdPinWatcher();
+
+private:
+	CIdPinWatcher(MControlAppEngineWatcherInterface& aControlAppEngine);
+	void ConstructL();
+	void SubscribeForNotification();
+	void DoCancel();
+	void RunL();
+
+private:
+	MControlAppEngineWatcherInterface&	iParentControlAppEngine;
+	RProperty							iIdPinProp;
+	};
+
+
+NONSHARABLE_CLASS(CVBusWatcher) : public CActive
+	{
+public:
+	static CVBusWatcher* NewL(MControlAppEngineWatcherInterface& aControlAppEngine);
+	~CVBusWatcher();
+
+private:
+	CVBusWatcher(MControlAppEngineWatcherInterface& aControlAppEngine);
+	void ConstructL();
+	void SubscribeForNotification();
+	void DoCancel();
+	void RunL();
+
+private:
+	MControlAppEngineWatcherInterface&	iParentControlAppEngine;
+	RProperty							iVBusProp;
+	};
+	
+
+NONSHARABLE_CLASS(CConnectionIdleWatcher) : public CActive
+	{
+public:
+	static CConnectionIdleWatcher* NewL(MControlAppEngineWatcherInterface& aControlAppEngine);
+	~CConnectionIdleWatcher();
+
+private:
+	CConnectionIdleWatcher(MControlAppEngineWatcherInterface& aControlAppEngine);
+	void ConstructL();
+	void SubscribeForNotification();
+	void DoCancel();
+	void RunL();
+
+private:
+	MControlAppEngineWatcherInterface&	iParentControlAppEngine;
+	RProperty							iConnIdleProp;
+	};
+
+
+NONSHARABLE_CLASS(CMessageWatcher) : public CActive
+	{
+public:
+	static CMessageWatcher* NewL(MControlAppEngineWatcherInterface& aControlAppEngine);
+	~CMessageWatcher();
+
+private:
+	CMessageWatcher(MControlAppEngineWatcherInterface& aControlAppEngine);
+	void ConstructL();
+
+	void DoCancel();
+	void RunL();
+
+public:
+	enum TMessageWatcherNotifications
+		{
+		EUsbMessageRequestSession,
+		EUsbMessageSrpReceived,
+		EErrUsbOtgSrpTimeout,
+		EErrUsbOtgVbusError
+		};
+
+private:
+	MControlAppEngineWatcherInterface&	iParentControlAppEngine;
+	TInt								iMessage;
+	};
+
+
+NONSHARABLE_CLASS(MControlAppStateMachineInterface)
+	{
+public: // All the events that the state machine can receive from outside:
+	//		Initial
+	virtual void StartUp()					= 0;
+	//		B-Stopped, B-Started
+	virtual void IdPinPresent()				= 0;
+	//		B-Stopped, A-Started
+	virtual void VBusRise()					= 0;
+	//		B-Started, A-Started
+	virtual void VBusDrop()					= 0;
+	//		A-Started, A-Stopped
+	virtual void IdPinAbsent()				= 0;
+	//		A-Started
+	virtual void ConnectionIdle()			= 0;
+	//		A-Started
+	virtual void ConnectionActive()			= 0;
+	//		B-Stopped, A-Stopped, B-Started, A-Started
+	virtual void RequestSessionCalled()		= 0;
+	//		B-Started
+	virtual void SrpTimeout()				= 0;
+	//		A-Stopped, A-Started
+	virtual void SrpDetected()				= 0;
+	//		A-Started, A-Stopped
+	virtual void VBusError()				= 0;
+	};
+
+class MControlAppEngineInterface;
+
+NONSHARABLE_CLASS(CControlAppStateMachine) : public CBase, public MControlAppStateMachineInterface
+	{
+// States are friend classes so that they can call private methods of the state machine.
+// We don't want those private methods visible outside the state machine.
+friend class CControlAppStateInitial;
+friend class CControlAppStateBServicesStopped;
+friend class CControlAppStateBServicesStarted;
+friend class CControlAppStateAServicesStarted;
+friend class CControlAppStateAServicesStopped;
+friend class CInactivityTimer;
+
+public:
+	static CControlAppStateMachine* NewL(MControlAppEngineInterface& aControlAppEngine);
+	~CControlAppStateMachine();
+private:
+	CControlAppStateMachine(MControlAppEngineInterface& aControlAppEngine);
+	void ConstructL();
+
+public: // From MControlAppStateMachineInterface, all the events that the state machine can receive from outside:
+	void StartUp();
+	void IdPinPresent();
+	void VBusRise();
+	void VBusDrop();
+	void IdPinAbsent();
+	void ConnectionIdle();
+	void ConnectionActive();
+	void RequestSessionCalled();
+	void SrpTimeout();
+	void SrpDetected();
+	void VBusError();
+
+private:
+	enum TControlAppState
+		{
+		EStateInitial,
+		EStateBServicesStopped,
+		EStateBServicesStarted,
+		EStateAServicesStopped,
+		EStateAServicesStarted
+		};
+	void SetState(TControlAppState aState);
+
+	void ResetInactivityTimer();
+	void CancelInactivityTimer();
+	void InactivityTimerExpired();
+
+
+	NONSHARABLE_CLASS(CInactivityTimer) : public CActive
+		{
+	public:
+		static CInactivityTimer* NewL(CControlAppStateMachine& aParentStateMachine);
+		~CInactivityTimer();
+		void Reset(); // Sets and resets timer. 
+		// Timer cancelled by calling CActive::Cancel()
+	private:
+		CInactivityTimer(CControlAppStateMachine& aParentStateMachine);
+		void ConstructL();		
+		void DoCancel();
+		void RunL();
+	private:
+		CControlAppStateMachine&	iParentStateMachine;
+		RTimer						iTimer;
+		};
+
+// Base State
+	NONSHARABLE_CLASS(CControlAppStateBase) : public CBase, public MControlAppStateMachineInterface
+		{
+	public:
+		CControlAppStateBase(CControlAppStateMachine& aParentStateMachine);
+		virtual void StartUp();
+		virtual void IdPinPresent();	
+		virtual void VBusRise();
+		virtual void VBusDrop();
+		virtual void IdPinAbsent();
+		virtual void ConnectionIdle();
+		virtual void ConnectionActive();
+		virtual void InactivityTimerExpired();	// Internally generated event
+		virtual void RequestSessionCalled();
+		virtual void SrpTriggered();			// Internally generated event
+		virtual void SrpTimeout();
+		virtual void SrpDetected();
+		virtual void VBusError();
+	protected:
+		CControlAppStateMachine& iParentStateMachine;
+		};
+
+// Initial State
+	NONSHARABLE_CLASS(CControlAppStateInitial) : public CControlAppStateBase
+		{
+	public:
+		CControlAppStateInitial(CControlAppStateMachine& aParentStateMachine);
+		// No action on these events which will come from Watchers when they are created.
+		// The Watchers will update the Engine with these values however and the 
+		// State Machine can act on those values on receiving the StartUp event.
+		void VBusRise();
+		void VBusDrop();
+		void IdPinPresent();
+		void IdPinAbsent();
+		void ConnectionIdle();
+		void ConnectionActive();
+		// Act on this events only:
+		void StartUp();
+		};
+
+// B-ServicesStopped State
+	NONSHARABLE_CLASS(CControlAppStateBServicesStopped) : public CControlAppStateBase
+		{
+	public:
+		CControlAppStateBServicesStopped(CControlAppStateMachine& aParentStateMachine);
+		void VBusRise();
+		void IdPinPresent();
+		void RequestSessionCalled();
+		void VBusDrop();
+		};
+
+// B-ServicesStarted State
+	NONSHARABLE_CLASS(CControlAppStateBServicesStarted) : public CControlAppStateBase
+		{
+	public:
+		CControlAppStateBServicesStarted(CControlAppStateMachine& aParentStateMachine);
+		void VBusDrop();	
+		void SrpTriggered(); // Internally generated event
+		void SrpTimeout();
+		void VBusRise(); // called when SRP has been successful
+		void IdPinPresent();
+		void RequestSessionCalled();
+		};
+
+// A-ServicesStarted State
+	NONSHARABLE_CLASS(CControlAppStateAServicesStarted) : public CControlAppStateBase
+		{
+	public:
+		CControlAppStateAServicesStarted(CControlAppStateMachine& aParentStateMachine);
+		void IdPinAbsent();
+		void SrpDetected();
+		void VBusRise();
+		void ConnectionIdle();
+		void ConnectionActive();
+		void InactivityTimerExpired(); // Internally generated event
+		void RequestSessionCalled();
+		void VBusError();
+		};
+
+// A-ServicesStopped State
+	NONSHARABLE_CLASS(CControlAppStateAServicesStopped) : public CControlAppStateBase
+		{
+	public:
+		CControlAppStateAServicesStopped(CControlAppStateMachine& aParentStateMachine);
+		void IdPinAbsent();
+		void SrpDetected();
+		void RequestSessionCalled();
+		void VBusError();
+		};
+
+private:
+	CControlAppStateBase*				iCurrentState;
+	CControlAppStateInitial*			iStateInitial;
+	CInactivityTimer*					iInactivityTimer;
+	CControlAppStateBServicesStopped*	iStateBServicesStopped;
+	CControlAppStateBServicesStarted*	iStateBServicesStarted;
+	CControlAppStateAServicesStarted*	iStateAServicesStarted;
+	CControlAppStateAServicesStopped*	iStateAServicesStopped;
+
+private:
+	MControlAppEngineInterface&			iParentControlAppEngine;
+	TBool								iTriggerSrp;
+	};
+
+
+NONSHARABLE_CLASS(MShutdownInterface)
+	{
+public:
+	virtual void Stop() const = 0;
+	};
+
+
+class CUsbControlAppEngine;
+
+NONSHARABLE_CLASS(CShutdownMonitor) : public CActive
+	{
+public:
+	static CShutdownMonitor* NewL(MShutdownInterface& aControlAppEngine);
+	~CShutdownMonitor();
+private:
+	CShutdownMonitor(MShutdownInterface& aControlAppEngine);
+	void ConstructL();
+	// From CActive
+	void DoCancel();
+	void RunL();
+private:
+	RProperty				iShutdownProp;
+	MShutdownInterface&		iParentControlAppEngine;
+	};
+
+
+NONSHARABLE_CLASS(MControlAppEngineInterface)
+	{
+public: // All the services the Engine provides that the State Machine calls on:
+	virtual TInt GetIdPin()									= 0;
+	virtual TInt GetVBus()									= 0;
+	virtual TInt StopUsbServices()							= 0;
+	virtual TInt StartUsbServices()							= 0;
+	virtual TInt EnableFunctionDriverLoading()				= 0;
+	virtual void DisableFunctionDriverLoading()				= 0;
+	virtual TInt BusRequest()								= 0;
+	virtual TInt BusDrop()									= 0;
+	virtual TInt BusRespondSrp()							= 0;
+	virtual TInt ClearVBusError()							= 0;
+	virtual void DisplayUserMessage(const TDesC& aUserMsg)	= 0;
+	};
+
+NONSHARABLE_CLASS(MControlAppEngineWatcherInterface)
+	{
+public: // All the methods the Engine provides that the Watcher classes can call:
+	virtual void SetIdPin(TInt aIdPin)				= 0;
+	virtual void SetVBus(TInt aVBus)				= 0;
+	virtual void SetConnectionIdle(TInt aConnIdle)	= 0;
+	virtual void MessageReceived(CMessageWatcher::TMessageWatcherNotifications aMessageNotification) = 0;
+	virtual RUsb& Usb()								= 0;
+	};
+
+NONSHARABLE_CLASS(CUsbControlAppEngine) : public CBase, public MControlAppEngineInterface, public MControlAppEngineWatcherInterface, public MShutdownInterface
+	{
+public:
+	static CUsbControlAppEngine* NewLC();
+	~CUsbControlAppEngine();
+	// Start/stop Active Scheduler
+	void Start();     
+	void Stop() const;
+	// From MControlAppEngineWatcherInterface, Watcher callbacks
+	void SetIdPin(TInt aIdPin);
+	void SetVBus(TInt aVBus);
+	void SetConnectionIdle(TInt aConnIdle);
+	void MessageReceived(CMessageWatcher::TMessageWatcherNotifications aMessageNotification);
+	RUsb& Usb();
+	// Getters
+	TInt GetIdPin();
+	TInt GetVBus();
+	// From MControlAppEngineInterface, called by State Machine
+	TInt StopUsbServices();
+	TInt StartUsbServices();
+	TInt EnableFunctionDriverLoading();
+	void DisableFunctionDriverLoading();
+	TInt BusRequest();
+	TInt BusDrop();
+	TInt BusRespondSrp();
+	TInt ClearVBusError();
+	void DisplayUserMessage(const TDesC& aUserMsg);
+
+private:
+	CUsbControlAppEngine();
+	void ConstructL();
+
+private: 
+	// Watcher related
+	CIdPinWatcher* 			iIdPinWatcher;
+	CVBusWatcher* 			iVBusWatcher;
+	CConnectionIdleWatcher* iConnIdleWatcher;
+	CMessageWatcher*		iMessageWatcher;
+	TInt					iIdPin;
+	TInt					iVBus;
+	TInt					iConnIdle;
+	// Resources
+	CControlAppStateMachine*	iStateMachine;
+	CShutdownMonitor*			iShutdownMonitor;
+	RUsb						iUsb;
+	//    RMsgQueue between exampleusbcontrolapp.exe & usbviewer.exe for displaying user messages
+	RMsgQueue<TBuf<KViewerNumCharactersOnLine> >	iViewerMsgQ; 
+	}; // CUsbControlAppEngine
+
+#endif // EXAMPLEUSBCONTROLAPP_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/exampleusbcontrolapp/exampleusbcontrolapp.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,34 @@
+/*
+* 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 "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:
+*
+*/
+
+
+target		exampleusbcontrolapp.exe
+targettype	exe
+UID		0x100039CE 0x10285EE7
+VENDORID	0x70000001
+
+capability	NetworkControl
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+userinclude	../shared
+
+sourcepath	../exampleusbcontrolapp
+source		exampleusbcontrolapp.cpp
+
+library		euser.lib
+library		usbman.lib
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/group/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* 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 "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:
+*
+*/
+
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST)
+
+PRJ_TESTEXPORTS
+usbcontrolapp.oby		/epoc32/rom/include/usbcontrolapp.oby
+
+PRJ_TESTMMPFILES
+../testusbawareapp/testusbawareapp.mmp
+../exampleusbcontrolapp/exampleusbcontrolapp.mmp
+../usbviewer/usbviewer.mmp
+../controlappbinder/controlappbinder.mmp
+
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/group/usbcontrolapp.oby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,35 @@
+
+
+/*
+* 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 "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:
+*
+*/
+
+
+#ifndef __USBCONTROLAPP_OBY__
+#define __USBCONTROLAPP_OBY__
+
+#ifdef __USB_DEBUG__
+define USB_DIR UDEB
+#else
+define USB_DIR BUILD_DIR
+#endif
+
+file=ABI_DIR\USB_DIR\testusbawareapp.exe	sys\bin\testusbawareapp.exe
+file=ABI_DIR\USB_DIR\exampleusbcontrolapp.exe	sys\bin\exampleusbcontrolapp.exe
+file=ABI_DIR\USB_DIR\usbviewer.exe		sys\bin\usbviewer.exe
+file=ABI_DIR\USB_DIR\controlappbinder.exe	sys\bin\usbcapp.exe
+
+#endif // __USBCONTROLAPP_OBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/shared/usbcontrolappshared.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,38 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef USBCONTROLAPPSHARED_H
+#define USBCONTROLAPPSHARED_H
+
+// P&S Shutdown property
+static const TInt32 KUidUsbControlAppCategoryValue=0x10285EE9;
+static const TUid	KUidUsbControlAppCategory={KUidUsbControlAppCategoryValue};
+static const TUint	KUsbControlAppShutdownKey=0x10285EE6;
+
+// Standard H4 TextShell screen size
+const TInt KScreenWidth = 40;
+const TInt KScreenDepth = 24;
+
+// Message Queue between Control App and Viewer
+_LIT(KControlAppViewerMsgQName, "ControlAppViewerMsgQ");
+const TInt KControlAppViewerMsgQSlots	= 5;
+const TInt KViewerNumCharactersOnLine	= 32;
+const TInt KEventLineNumCharacters		= KViewerNumCharactersOnLine-1; // Chars that can go into an Event for display 
+_LIT(KPrefix, "!:"); // All user messages shown with prefix "!:"
+const TInt KEventLineMsgNumCharacters	= KEventLineNumCharacters - 2; // -2 for "!:" prefix
+
+#endif // USBCONTROLAPPSHARED_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/testusbawareapp/testusbawareapp.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,300 @@
+/*
+* 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 "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 "testusbawareapp.h"
+
+#include <e32cons.h>
+#include <e32debug.h>
+#include "e32svr.h"
+#include <e32keys.h>
+
+#include "usbcontrolappshared.h"
+#include "e32property.h" 
+
+#define LOG(A,B) RDebug::Print(_L("UsbAwareApp: " L##A),B)
+#define PNT(A)	 RDebug::Print(_L("UsbAwareApp: " L##A))
+#define PANIC Panic(__LINE__)
+
+void Panic(TInt aLine)
+	{
+	RDebug::Printf("UsbAwareApp: PANIC line=%d", aLine);
+	User::Panic(_L("USBAWAREAPP"), aLine);
+	}
+
+void RunAppL()
+	{
+	CUsbAwareAppConsole* awareapp = CUsbAwareAppConsole::NewLC();
+	awareapp->Start();
+	CleanupStack::PopAndDestroy(awareapp);
+	}
+
+TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	CActiveScheduler* activeScheduler = new CActiveScheduler;
+	TInt err = KErrNoMemory;
+	if(cleanup && activeScheduler)
+		{
+		CActiveScheduler::Install(activeScheduler);
+		PNT("*** UsbAwareApp E32Main ***\n");
+		TRAP(err, RunAppL());
+		}
+	delete activeScheduler;
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return err;
+	}
+
+
+
+CUsbAwareAppConsole* CUsbAwareAppConsole::NewLC()
+	{
+	CUsbAwareAppConsole* self = new(ELeave) CUsbAwareAppConsole;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	PNT("\nConstructed Aware App\n");
+	return self;
+	}
+	
+CUsbAwareAppConsole::~CUsbAwareAppConsole()
+	{
+	PNT("\nClosing Aware App\n");
+	delete iKeys;
+	delete iShutdownMonitor;
+	delete iConsole;
+	}
+
+CUsbAwareAppConsole::CUsbAwareAppConsole()
+	{
+	}
+
+void CUsbAwareAppConsole::ConstructL()
+	{
+	iConsole = Console::NewL(KUsbAwareAppTitle, TSize(KViewerNumCharactersOnLine, KNumLinesInWindow));
+	Move(-3, 9);
+	iShutdownMonitor = CShutdownMonitor::NewL(*this);
+	// After everything else, enable interactivity.
+	iKeys = CUsbAwareAppKeys::NewL(*this);
+	Draw();
+	}
+
+void CUsbAwareAppConsole::Move(TInt aX, TInt aY)
+	{
+	TRawEvent event;
+
+	event.Set(TRawEvent::EKeyDown, EStdKeyLeftShift);
+	UserSvr::AddEvent(event);
+
+	if (aX)
+		{
+		if ( aX > 0 )
+			{
+			// Move to the right...
+			for(TInt i=aX; i; i--)
+				{
+				event.Set(TRawEvent::EKeyDown, EStdKeyRightArrow);
+				UserSvr::AddEvent(event);
+				event.Set(TRawEvent::EKeyUp, EStdKeyRightArrow);
+				UserSvr::AddEvent(event);
+				}
+			}
+		else
+			{
+			// Move to the Left...
+			for(TInt i=aX; i; i++)
+				{
+				event.Set(TRawEvent::EKeyDown, EStdKeyLeftArrow);
+				UserSvr::AddEvent(event);
+				event.Set(TRawEvent::EKeyUp, EStdKeyLeftArrow);
+				UserSvr::AddEvent(event);
+				}
+			}
+		}
+	
+	if (aY)
+		{
+		if ( aY > 0 )
+			{
+			// Move downwards...
+			for(TInt i=aY; i; i--)
+				{
+				event.Set(TRawEvent::EKeyDown, EStdKeyDownArrow);
+				UserSvr::AddEvent(event);
+				event.Set(TRawEvent::EKeyUp, EStdKeyDownArrow);
+				UserSvr::AddEvent(event);
+				}
+			}
+		else
+			{
+			// Move upwards...
+			for(TInt i=aY; i; i++)
+				{
+				event.Set(TRawEvent::EKeyDown, EStdKeyUpArrow);
+				UserSvr::AddEvent(event);
+				event.Set(TRawEvent::EKeyUp, EStdKeyUpArrow);
+				UserSvr::AddEvent(event);
+				}
+			}
+		}
+
+	event.Set(TRawEvent::EKeyUp, EStdKeyLeftShift);
+	UserSvr::AddEvent(event);
+	}
+
+void CUsbAwareAppConsole::Start()
+	{
+	// Get everything running
+	CActiveScheduler::Start();
+	}
+	
+void CUsbAwareAppConsole::Stop() const
+	{
+	CActiveScheduler::Stop();
+	}
+
+void CUsbAwareAppConsole::Draw()
+	{
+	iConsole->ClearScreen();
+	
+	iConsole->Printf(_L(
+//          1         2         3         4         5 \r\n
+// 12345678901234567890123456789012345678901234567890123
+  "Test USB Aware App:           \r\n"
+ L"\r\n"
+ L"Press 'R' to RequestSession   \r\n"
+	)
+	);
+
+	}
+
+
+
+CUsbAwareAppKeys* CUsbAwareAppKeys::NewL(CUsbAwareAppConsole& aUsbAwareAppConsole)
+	{
+	CUsbAwareAppKeys* self = new(ELeave) CUsbAwareAppKeys(aUsbAwareAppConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CUsbAwareAppKeys::~CUsbAwareAppKeys()
+	{
+	iUsb.Close();
+	Cancel();
+	}
+
+CUsbAwareAppKeys::CUsbAwareAppKeys(CUsbAwareAppConsole& aUsbAwareAppConsole)
+	: CActive(EPriorityStandard)
+	, iUsbAwareAppConsole(aUsbAwareAppConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUsbAwareAppKeys::ConstructL()
+	{
+	// Connect USB session
+	TInt err = iUsb.Connect();
+	LOG("CUsbAwareAppKeys::ConstructL()   iUsb.Connect()   err=%d", err);
+	User::LeaveIfError(err);
+	// Allow keyboard input
+	iUsbAwareAppConsole.iConsole->Read(iStatus);
+	SetActive();
+	}
+
+void CUsbAwareAppKeys::RunL()
+	{
+	if (!IsActive())
+		{
+		User::LeaveIfError(iStatus.Int());
+		
+		switch(iUsbAwareAppConsole.iConsole->KeyCode())
+			{
+		case 'r': case 'R':
+			{
+			TInt err = iUsb.RequestSession();
+			LOG("CUsbAwareAppKeys::RunL()   RequestSession()	err=%d", err);
+			}
+			break;
+			} // switch
+		iUsbAwareAppConsole.iConsole->Read(iStatus);
+		SetActive();
+		}
+	}
+
+void CUsbAwareAppKeys::DoCancel()
+	{
+	iUsbAwareAppConsole.iConsole->ReadCancel();
+	}
+
+
+
+
+CShutdownMonitor* CShutdownMonitor::NewL(MShutdownInterface& aUsbAwareAppConsole)
+	{
+	CShutdownMonitor* self = new(ELeave) CShutdownMonitor(aUsbAwareAppConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CShutdownMonitor::CShutdownMonitor(MShutdownInterface& aUsbAwareAppConsole)
+	: CActive(EPriorityLow) // Low so all notifications that want to be serviced will be done first
+	, iUsbAwareAppConsole(aUsbAwareAppConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CShutdownMonitor::ConstructL()
+	{
+	// Monitor the KUsbControlAppShutdownKey property to tell us when to shut down
+	TInt err = iShutdownProp.Attach(KUidUsbControlAppCategory, KUsbControlAppShutdownKey);
+	LOG("CShutdownMonitor::ConstructL	 iShutdownProp.Attach() => %d", err);
+	User::LeaveIfError(err);
+	iShutdownProp.Subscribe(iStatus);
+	SetActive();
+	TInt val;
+	// Make sure the cuurent value is 0 - shut down when this changes to 1
+	err = iShutdownProp.Get(val);
+	LOG("CShutdownMonitor::ConstructL()	 iShutdownProp.Get(val)		val => %d", val);
+	LOG("CShutdownMonitor::ConstructL()	 iShutdownProp.Get(val)		err => %d", err);
+	User::LeaveIfError(err);
+	__ASSERT_ALWAYS(val==0, PANIC);
+	}
+
+CShutdownMonitor::~CShutdownMonitor()
+	{
+	iShutdownProp.Close();
+	}
+
+void CShutdownMonitor::RunL()
+	{
+	// Request to shut everything down made in USB Aware App
+	TInt val;
+	TInt err = iShutdownProp.Get(val);
+	LOG("CShutdownMonitor::RunL	 iShutdownProp.Get(val) err => %d", err);
+	LOG("CShutdownMonitor::RunL	 iShutdownProp.Get(val) val => %d", val);
+	Cancel(); // Not interested in any more notifications
+	iUsbAwareAppConsole.Stop(); // Stopping Active Scheduler will results in the destructor getting called
+	}
+
+void CShutdownMonitor::DoCancel()
+	{
+	iShutdownProp.Cancel();
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/testusbawareapp/testusbawareapp.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,99 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef TESTUSBAWAREAPP_H
+#define TESTUSBAWAREAPP_H
+
+#include <e32cmn.h>
+#include <e32base.h>
+#include <usbman.h>
+#include <e32property.h>
+
+_LIT(KUsbAwareAppTitle, "USB Aware App");
+
+class CUsbAwareAppKeys;
+class CShutdownMonitor;
+
+NONSHARABLE_CLASS(MShutdownInterface)
+	{
+public:
+	virtual void Stop() const = 0;
+	};
+
+NONSHARABLE_CLASS(CUsbAwareAppConsole) : public CBase, public MShutdownInterface
+	{
+friend class CUsbAwareAppKeys;
+
+public:
+	static CUsbAwareAppConsole* NewLC();
+	~CUsbAwareAppConsole();
+
+public:
+	void Start();     
+	void Stop() const; 
+
+private:
+	CUsbAwareAppConsole();
+	void ConstructL();
+	void Move(TInt aX, TInt aY);
+	void Draw();
+
+private:
+	CConsoleBase*		iConsole;
+	CUsbAwareAppKeys*	iKeys;
+	CShutdownMonitor*	iShutdownMonitor;
+
+private:
+	static const TInt KNumLinesInWindow		= 5;
+	};
+
+
+NONSHARABLE_CLASS(CUsbAwareAppKeys) : public CActive
+	{
+public:
+	static CUsbAwareAppKeys* NewL(CUsbAwareAppConsole& aUsbAwareAppConsole);
+	~CUsbAwareAppKeys();
+	
+private:
+	CUsbAwareAppKeys(CUsbAwareAppConsole& aUsbAwareAppConsole);
+	void ConstructL();
+	void DoCancel();
+	void RunL();
+	
+private:
+	CUsbAwareAppConsole&	iUsbAwareAppConsole;
+	RUsb					iUsb;
+	};
+
+
+NONSHARABLE_CLASS(CShutdownMonitor) : public CActive
+	{
+public:
+	static CShutdownMonitor* NewL(MShutdownInterface& aUsbAwareAppConsole);
+	~CShutdownMonitor();
+private:
+	CShutdownMonitor(MShutdownInterface& aUsbAwareAppConsole);
+	void ConstructL();
+	// From CActive
+	void DoCancel();
+	void RunL();
+private:
+	RProperty				iShutdownProp;
+	MShutdownInterface&		iUsbAwareAppConsole;
+	};
+
+#endif // TESTUSBAWAREAPP_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/testusbawareapp/testusbawareapp.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,34 @@
+/*
+* 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 "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:
+*
+*/
+
+
+target		testusbawareapp.exe
+targettype	exe
+UID		0x100039CE 0x10285EE5
+VENDORID	0x70000001
+
+capability	CommDD SwEvent
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+userinclude	../shared
+
+sourcepath	../testusbawareapp
+source		testusbawareapp.cpp
+
+library		euser.lib
+library		usbman.lib
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/usbviewer/usbviewer.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,1553 @@
+/*
+* 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 "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 "usbviewer.h"
+
+#include <e32cons.h>
+#include <e32debug.h>
+
+#include <d32otgdi_errors.h>
+#include <d32usbdi_errors.h>
+#include <usb/usbshared.h>
+// For moving windows using scancode events
+#include "e32event.h"
+#include "e32svr.h" 
+
+
+#define PANIC Panic(__LINE__)
+#define LOG(A,B) RDebug::Print(_L("UsbViewer: " L##A),B)
+#define PNT(A)	 RDebug::Print(_L("UsbViewer: " L##A))
+
+void Panic(TInt aLine)
+	{
+	RDebug::Printf("UsbViewer: PANIC line=%d", aLine);
+	User::Panic(_L("USBVIEWER"), aLine);
+	}
+
+void RunViewerL()
+	{
+	CUsbViewer* viewer = CUsbViewer::NewLC();
+	viewer->Start();
+	CleanupStack::PopAndDestroy(viewer);
+	}
+
+TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	CActiveScheduler* activeScheduler = new CActiveScheduler;
+	TInt err = KErrNoMemory;
+	if(cleanup && activeScheduler)
+		{
+		CActiveScheduler::Install(activeScheduler);
+		PNT("*** UsbViewer E32Main ***\n");
+		TRAP(err, RunViewerL());
+		}
+	delete activeScheduler;
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return err;
+	}
+
+
+XUsbViewerEvent::~XUsbViewerEvent()
+	{
+	iLink.Deque();
+	iEvent.Close();
+	}
+	
+	
+
+CUsbViewer* CUsbViewer::NewLC()
+	{
+	PNT("CUsbViewer::NewLC");
+	CUsbViewer* self = new(ELeave) CUsbViewer;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	PNT("CUsbViewer::NewLC - Constructed Viewer");
+	return self;
+	}
+	
+CUsbViewer::~CUsbViewer()
+	{
+	PNT("CUsbViewer::~CUsbViewer");
+
+	delete iShutdownMonitor;
+
+	delete iMessageWatcher;
+	delete iHostEventWatcher;
+	delete iOtgStateWatcher;
+	delete iConnIdleWatcher;
+	delete iVBusWatcher;
+	delete iIdPinWatcher;
+	delete iDeviceStateWatcher;
+	delete iServiceStateWatcher;
+
+	delete iUserMsgQWatcher;
+	iUserMsgQ.Close();
+
+	TDblQueIter<XUsbViewerEvent> iter(iEventList);
+	XUsbViewerEvent* event = NULL;
+	while((event = iter++) != NULL)
+		{
+		delete event;
+		} 
+
+	Cancel();
+
+	PNT("Closing USB Session");
+	iUsb.Close();
+	delete iConsole;
+	}
+
+CUsbViewer::CUsbViewer()
+	: CActive(EPriorityLow) // Low so all notifications that want to be serviced will be done first
+	, iAutoSrpResponse(EFalse)
+	, iDeviceType(ENoDevice)
+	, iEventList(_FOFF(XUsbViewerEvent, iLink))
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUsbViewer::ConstructL()
+	{
+	PNT("CUsbViewer::ConstructL");
+	iConsole = Console::NewL(KUsbViewerTitle, TSize(KViewerNumCharactersOnLine, KNumLinesInWindow));
+	Move(-3, -3);
+	User::LeaveIfError(iUsb.Connect());
+	
+	for(TInt i=0; i<KNumEventsInWindow; ++i)
+		{
+        XUsbViewerEvent* nullEvent = new(ELeave) XUsbViewerEvent;
+		iEventList.AddFirst(*nullEvent);
+		}
+
+	// Open message queue to display user messages
+	User::LeaveIfError(iUserMsgQ.OpenGlobal(KControlAppViewerMsgQName));
+	iUserMsgQWatcher = CUserMsgQWatcher::NewL(*this);
+
+	iServiceStateWatcher = CServiceStateWatcher::NewL(*this);
+	iDeviceStateWatcher = CDeviceStateWatcher::NewL(*this);
+	iIdPinWatcher = CIdPinWatcher::NewL(*this);
+	iVBusWatcher = CVBusWatcher::NewL(*this);
+	iConnIdleWatcher = CConnectionIdleWatcher::NewL(*this);
+	iOtgStateWatcher = COtgStateWatcher::NewL(*this);
+	iHostEventWatcher = CHostEventWatcher::NewL(*this);
+	iMessageWatcher = CMessageWatcher::NewL(*this);
+	SetDriverLoading(EUnknown);
+	SetDeviceType(ENoDevice);
+
+	iShutdownMonitor = CShutdownMonitor::NewL(*this);
+	}
+
+void CUsbViewer::Move(TInt aX, TInt aY)
+	{
+	TRawEvent event;
+
+	event.Set(TRawEvent::EKeyDown, EStdKeyLeftShift);
+	UserSvr::AddEvent(event);
+
+	if (aX)
+		{
+		if ( aX > 0 )
+			{
+			// Move to the right...
+			for(TInt i=aX; i; i--)
+				{
+				event.Set(TRawEvent::EKeyDown, EStdKeyRightArrow);
+				UserSvr::AddEvent(event);
+				event.Set(TRawEvent::EKeyUp, EStdKeyRightArrow);
+				UserSvr::AddEvent(event);
+				}
+			}
+		else
+			{
+			// Move to the Left...
+			for(TInt i=aX; i; i++)
+				{
+				event.Set(TRawEvent::EKeyDown, EStdKeyLeftArrow);
+				UserSvr::AddEvent(event);
+				event.Set(TRawEvent::EKeyUp, EStdKeyLeftArrow);
+				UserSvr::AddEvent(event);
+				}
+			}
+		}
+	
+	if (aY)
+		{
+		if ( aY > 0 )
+			{
+			// Move downwards...
+			for(TInt i=aY; i; i--)
+				{
+				event.Set(TRawEvent::EKeyDown, EStdKeyDownArrow);
+				UserSvr::AddEvent(event);
+				event.Set(TRawEvent::EKeyUp, EStdKeyDownArrow);
+				UserSvr::AddEvent(event);
+				}
+			}
+		else
+			{
+			// Move upwards...
+			for(TInt i=aY; i; i++)
+				{
+				event.Set(TRawEvent::EKeyDown, EStdKeyUpArrow);
+				UserSvr::AddEvent(event);
+				event.Set(TRawEvent::EKeyUp, EStdKeyUpArrow);
+				UserSvr::AddEvent(event);
+				}
+			}
+		}
+
+	event.Set(TRawEvent::EKeyUp, EStdKeyLeftShift);
+	UserSvr::AddEvent(event);
+	}
+
+void CUsbViewer::Start()
+	{
+	// Get everything running
+	CActiveScheduler::Start();
+	}
+	
+void CUsbViewer::Stop() const
+	{
+	CActiveScheduler::Stop();
+	}
+
+void CUsbViewer::DoCancel()
+	{
+	// Don't need to do anything as the AO is completed straight away.
+	}
+
+void CUsbViewer::RunL()
+	{
+	__ASSERT_ALWAYS(iStatus.Int() == KErrNone, PANIC);
+	Draw();
+	}
+
+void CUsbViewer::ScheduleDraw()
+	{
+	PNT("CUsbViewer::ScheduleDraw");
+	if(!IsActive())
+		{
+		SetActive();
+		TRequestStatus* status = &iStatus;
+		User::RequestComplete(status, KErrNone);
+
+		TSize size = iConsole->ScreenSize();
+		iConsole->SetCursorPosAbs(TPoint(size.iWidth-1, 0));
+		iConsole->Write(_L("*"));
+		}
+	}
+	
+RUsb& CUsbViewer::Usb()
+	{
+	return iUsb;
+	}
+
+RMsgQueue<TBuf<KViewerNumCharactersOnLine> >& CUsbViewer::UserMsgQ()
+	{
+	return iUserMsgQ;
+	}
+	
+void CUsbViewer::SetServiceState(TUsbServiceState aServiceState)
+	{
+	switch(aServiceState)
+		{
+    case EUsbServiceIdle:
+    	iServStatus =
+    		//  12345678901
+			_L("Idle       ");
+    	break;
+
+	case EUsbServiceStarting:
+    	iServStatus =
+    		//  12345678901
+			_L("Starting   ");
+		break;
+
+	case EUsbServiceStarted:
+	    iServStatus =
+    		//  12345678901
+			_L("Started    ");
+		break;
+
+	case EUsbServiceStopping:
+    	iServStatus =
+    		//  12345678901
+			_L("Stopping   ");
+		break;
+
+	case EUsbServiceFatalError:
+    	iServStatus =
+    		//  12345678901
+			_L("Error      ");
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	LOG("Service State => %S", &iServStatus);
+	ScheduleDraw();
+	}
+	
+void CUsbViewer::SetDeviceState(TUsbDeviceState aDeviceState)
+	{
+	switch(aDeviceState)
+		{
+	case EUsbDeviceStateUndefined:
+		iDevStatus =
+    		//  12345678901
+			_L("Undefined  ");
+		break;
+
+	case EUsbDeviceStateDefault:
+		iDevStatus =
+    		//  12345678901
+			_L("Default    ");
+		break;
+
+	case EUsbDeviceStateAttached:
+		iDevStatus =
+    		//  12345678901
+			_L("Attached   ");
+		break;
+
+	case EUsbDeviceStatePowered:
+		iDevStatus =
+    		//  12345678901
+			_L("Powered    ");
+		break;
+
+	case EUsbDeviceStateConfigured:
+		iDevStatus =
+    		//  12345678901
+			_L("Configured ");
+		break;
+
+	case EUsbDeviceStateAddress:
+		iDevStatus =
+    		//  12345678901
+			_L("Address    ");
+		break;
+
+	case EUsbDeviceStateSuspended:
+		iDevStatus =
+    		//  12345678901
+			_L("Suspended  ");
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	LOG("Device State => %S", &iDevStatus);
+	ScheduleDraw();
+	}
+	
+void CUsbViewer::SetIdPin(TInt aIdPin)
+	{
+	switch(aIdPin)
+		{
+	case 0:
+		iIdPin =
+    		//  12345
+			_L("-    ");
+		break;
+
+	case 1:
+		iIdPin =
+    		//  12345
+			_L("+    ");
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	LOG("Id Pin => %S", &iIdPin);
+	ScheduleDraw();
+	}
+	
+void CUsbViewer::SetVBus(TInt aVBus)
+	{
+	switch(aVBus)
+		{
+	case 0:
+		iVBus =
+    		//  12345
+			_L("-    ");
+		break;
+
+	case 1:
+		iVBus =
+    		//  12345
+			_L("+    ");
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	LOG("VBus => %S", &iVBus);
+	ScheduleDraw();
+	}
+
+void CUsbViewer::SetConnectionIdle(TInt aConnIdle)
+	{
+	switch(aConnIdle)
+		{
+	case 0:
+		iConnIdle =
+    		//  12345
+			_L("-    ");
+		break;
+
+	case 1:
+		iConnIdle =
+    		//  12345
+			_L("+    ");
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	LOG("Connection Idle => %S", &iConnIdle);
+	ScheduleDraw();
+	}
+
+void CUsbViewer::SetOtgState(TInt aOtgState)
+	{
+	switch(aOtgState)
+		{
+	case 0x01:
+		iOtgState =
+    		//  123456789012
+			_L("Reset       ");
+		break;
+
+	case 0x02:
+		iOtgState =
+    		//  123456789012
+			_L("A-Idle      ");
+		break;
+
+	case 0x04:
+		iOtgState =
+    		//  123456789012
+			_L("A-Host      ");
+		break;
+
+	case 0x08:
+		iOtgState =
+    		//  1234567890123
+			_L("A-Peripheral");
+		break;
+
+	case 0x10:
+		iOtgState =
+    		//  123456789012
+			_L("A-Vbus Error");
+		break;
+
+	case 0x20:
+		iOtgState =
+    		//  123456789012
+			_L("B-Idle      ");
+		break;
+
+	case 0x40:
+		iOtgState =
+    		//  1234567890123
+			_L("B-Peripheral");
+		break;
+
+	case 0x80:
+		iOtgState =
+    		//  1234567890123
+			_L("B-Host      ");
+		break;
+		
+	default:
+		iOtgState =
+    		//  1234567890123
+			_L("Don't Panic!");
+		break;
+		}
+	LOG("OTG State => %S", &iOtgState);
+	ScheduleDraw();
+	}
+
+void CUsbViewer::SetDriverLoading(TFdfDriverLoadingState aDriverLoading)
+	{
+	switch(aDriverLoading)
+		{
+	case EUnknown:
+		iDriverLoading =
+			//  123
+			_L("???");
+		break;
+	case EDisabled:
+		iDriverLoading =
+			//  123
+			_L("Off");
+		break;
+	case EEnabled:
+		iDriverLoading =
+			//  123
+			_L("On ");
+		break;
+	default:
+		PANIC;
+		break;
+		}
+	LOG("Driver Loading => %S", &iDriverLoading);
+	ScheduleDraw();
+	}
+	
+void CUsbViewer::SetAttachedDevices(TUint aAttachedDevices)
+	{
+	if(aAttachedDevices > 999)
+		{
+		iAttachedDevices =
+			//  123
+			_L("xxx");
+		}
+	else
+		{
+		iAttachedDevices.NumFixedWidthUC(aAttachedDevices, EDecimal, 3);
+		}
+	LOG("Attached Devices => %S", &iAttachedDevices);
+	ScheduleDraw();
+	}
+
+void CUsbViewer::SetDeviceType(TDeviceType aDeviceType)
+	{
+	iDeviceType = aDeviceType;
+
+	switch ( aDeviceType )
+		{
+	case ENoDevice:
+		iAttachedDevice =
+			//  12345
+			_L("     ");
+		break;
+	case EGenericDevice:
+		iAttachedDevice =
+			//  12345
+			_L("<   >");
+		break;
+	case ELogitechHeadset:
+		iAttachedDevice =
+			//  12345
+			_L("<<A>>");
+		break;
+		}
+	LOG("Audio Device => [%S]", &iAttachedDevice);
+	ScheduleDraw();
+	}
+
+void CUsbViewer::NotifyEvent(XUsbViewerEvent* aEvent)
+	{
+	LOG("CUsbViewer::NotifyEvent	event length = %d", aEvent->iEvent.Length());
+	__ASSERT_ALWAYS(aEvent, PANIC);
+	__ASSERT_ALWAYS(aEvent->iEvent.Length() <= KViewerNumCharactersOnLine, PANIC);
+
+	iEventList.AddFirst(*aEvent);
+	delete iEventList.Last();
+
+	LOG("Event => %S", &(aEvent->iEvent));
+	ScheduleDraw();
+	}
+
+void CUsbViewer::Draw()
+	{
+	PNT("CUsbViewer::Draw");
+	iConsole->ClearScreen();
+
+	iConsole->Printf(_L(
+//          1         2         3  
+// 12345678901234567890123456789012
+//               
+//        12345         12345678901
+  "IdPin: %S" L"SrvSt : %S\n"      
+//        12345         12345678901
+ L"VBus : %S" L"DevSt : %S\n"
+//        123           123
+ L"DLoad: %S  " L"# Devs: %S\n"   
+//        12345         1234
+ L"Dev  : %S" L"        \n"
+//        12345        1234567890123
+ L"C.Idl: %S" L"OTG  : %S \n"   
+	),
+	&iIdPin,			&iServStatus, 
+	&iVBus,				&iDevStatus, 
+	&iDriverLoading,	&iAttachedDevices,
+	&iAttachedDevice,	
+	&iConnIdle,			&iOtgState
+	);
+
+	// Events...
+	TDblQueIter<XUsbViewerEvent> iter(iEventList);
+	XUsbViewerEvent* event = NULL;
+	while((event = iter++) != NULL)
+		{
+		iConsole->Printf(_L("\n"));
+		iConsole->Printf(event->iEvent.Left(KViewerNumCharactersOnLine));
+		}
+	}
+	
+
+
+CShutdownMonitor* CShutdownMonitor::NewL(MShutdownInterface& aParentUsbViewer)
+	{
+	CShutdownMonitor* self = new(ELeave) CShutdownMonitor(aParentUsbViewer);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CShutdownMonitor::CShutdownMonitor(MShutdownInterface& aParentUsbViewer)
+	: CActive(EPriorityLow) // Low so all notifications that want to be serviced will be done first
+	, iParentUsbViewer(aParentUsbViewer)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CShutdownMonitor::ConstructL()
+	{
+	// Monitor the KUsbControlAppShutdownKey property to tell us when to shut down
+	TInt err = iShutdownProp.Attach(KUidUsbControlAppCategory, KUsbControlAppShutdownKey);
+	LOG("CShutdownMonitor::ConstructL	 iShutdownProp.Attach() => %d", err);
+	User::LeaveIfError(err);
+	iShutdownProp.Subscribe(iStatus);
+	SetActive();
+	TInt val;
+	// Make sure the cuurent value is 0 - shut down when this changes to 1
+	err = iShutdownProp.Get(val);
+	LOG("CShutdownMonitor::ConstructL()	 iShutdownProp.Get(val)		val => %d", val);
+	LOG("CShutdownMonitor::ConstructL()	 iShutdownProp.Get(val)		err => %d", err);
+	User::LeaveIfError(err);
+	__ASSERT_ALWAYS(val==0, PANIC);
+	}
+
+CShutdownMonitor::~CShutdownMonitor()
+	{
+	iShutdownProp.Close();
+	}
+
+void CShutdownMonitor::RunL()
+	{
+	// Request to shut everything down made in USB Aware App
+	TInt val;
+	TInt err = iShutdownProp.Get(val);
+	LOG("CShutdownMonitor::RunL	 iShutdownProp.Get(val) err => %d", err);
+	LOG("CShutdownMonitor::RunL	 iShutdownProp.Get(val) val => %d", val);
+	Cancel(); // Not interested in any more notifications
+	iParentUsbViewer.Stop(); // Stopping Active Scheduler will results in the destructor getting called
+	}
+
+void CShutdownMonitor::DoCancel()
+	{
+	iShutdownProp.Cancel();
+	}
+	
+
+
+CEventNotifier::CEventNotifier(TInt aPriority)
+	: CActive(aPriority)
+	{
+	}
+
+XUsbViewerEvent* CEventNotifier::NewViewerEventL()
+	{
+	XUsbViewerEvent* event = new(ELeave) XUsbViewerEvent;
+	CleanupStack::PushL(event);
+	User::LeaveIfError(event->iEvent.Create(KViewerNumCharactersOnLine));
+	CleanupStack::Pop();
+	return event;
+	}
+
+void CEventNotifier::RunL()
+	{
+	DoRunL(NewViewerEventL());
+	}
+
+
+
+
+CServiceStateWatcher* CServiceStateWatcher::NewL(CUsbViewer& aUsbViewer)
+	{
+	CServiceStateWatcher* self = new(ELeave) CServiceStateWatcher(aUsbViewer);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CServiceStateWatcher::~CServiceStateWatcher()
+	{
+	Cancel();
+	}
+
+CServiceStateWatcher::CServiceStateWatcher(CUsbViewer& aUsbViewer)
+	: CEventNotifier(EPriorityStandard)
+	, iUsbViewer(aUsbViewer)
+	, iServiceState(EUsbServiceIdle)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CServiceStateWatcher::ConstructL()
+	{
+	iUsbViewer.Usb().ServiceStateNotification(iServiceState, iStatus);
+	SetActive();
+
+	TUsbServiceState serviceState;
+	User::LeaveIfError(iUsbViewer.Usb().GetServiceState(serviceState));
+	iUsbViewer.SetServiceState(serviceState);
+	}
+
+void CServiceStateWatcher::DoCancel()
+	{
+	iUsbViewer.Usb().ServiceStateNotificationCancel();
+	}
+
+void CServiceStateWatcher::DoRunL(XUsbViewerEvent* aEvent)
+	{
+	iUsbViewer.SetServiceState(iServiceState);
+	TPtrC res(NULL, 0);
+	_LIT(KIdle,     "Idle");
+	_LIT(KStarting, "Starting");
+	_LIT(KStarted,  "Started");
+	_LIT(KStopping, "Stopping");
+	_LIT(KError,    "Error");
+	switch(iServiceState)
+		{
+	case EUsbServiceIdle:
+		res.Set(KIdle);
+		break;
+	case EUsbServiceStarting:
+		res.Set(KStarting);
+		break;
+	case EUsbServiceStarted:
+		res.Set(KStarted);
+		break;
+	case EUsbServiceStopping:
+		res.Set(KStopping);
+		break;
+	case EUsbServiceFatalError:
+		res.Set(KError);
+		break;
+	default:
+		PANIC;
+		break;
+		}
+		
+	iUsbViewer.Usb().ServiceStateNotification(iServiceState, iStatus);
+	SetActive();
+//                                  16              8 1 -> 25
+	aEvent->iEvent.AppendFormat(_L("D:ServiceState [%S]"), &res);
+	iUsbViewer.NotifyEvent(aEvent);
+
+	// RunL call may have been delayed: ensure viewer has the very latest information
+	TUsbServiceState serviceState;
+	User::LeaveIfError(iUsbViewer.Usb().GetServiceState(serviceState));
+
+	iUsbViewer.SetServiceState(serviceState);
+	}
+
+	
+CDeviceStateWatcher* CDeviceStateWatcher::NewL(CUsbViewer& aUsbViewer)
+	{
+	CDeviceStateWatcher* self = new(ELeave) CDeviceStateWatcher(aUsbViewer);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CDeviceStateWatcher::~CDeviceStateWatcher()
+	{
+	Cancel();
+	}
+
+CDeviceStateWatcher::CDeviceStateWatcher(CUsbViewer& aUsbViewer)
+	: CEventNotifier(EPriorityStandard)
+	, iUsbViewer(aUsbViewer)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CDeviceStateWatcher::ConstructL()
+	{
+	iUsbViewer.Usb().DeviceStateNotification(0xffffffff, iDeviceState, iStatus);
+	SetActive();
+
+	TUsbDeviceState deviceState;
+	User::LeaveIfError(iUsbViewer.Usb().GetDeviceState(deviceState));
+	iUsbViewer.SetDeviceState(deviceState);
+	}
+
+void CDeviceStateWatcher::DoCancel()
+	{
+	iUsbViewer.Usb().DeviceStateNotificationCancel();
+	}
+
+void CDeviceStateWatcher::DoRunL(XUsbViewerEvent* aEvent)
+	{
+	iUsbViewer.SetDeviceState(iDeviceState);
+	TPtrC res(NULL, 0);
+	_LIT(KUndefined,  "Undefined");
+    _LIT(KDefault,    "Default");
+    _LIT(KAttached,   "Attached");
+    _LIT(KPowered,    "Powered");
+    _LIT(KConfigured, "Configured");
+    _LIT(KAddress,    "Address");
+    _LIT(KSuspended,  "Suspended");
+	switch(iDeviceState)
+		{
+	case EUsbDeviceStateUndefined:
+		res.Set(KUndefined);
+		break;
+	case EUsbDeviceStateDefault:
+		res.Set(KDefault);
+		break;
+	case EUsbDeviceStateAttached:
+		res.Set(KAttached);
+		break;
+	case EUsbDeviceStatePowered:
+		res.Set(KPowered);
+		break;
+	case EUsbDeviceStateConfigured:
+		res.Set(KConfigured);
+		break;
+	case EUsbDeviceStateAddress:
+		res.Set(KAddress);
+		break;
+	case EUsbDeviceStateSuspended:
+		res.Set(KSuspended);
+		break;
+	default:
+		PANIC;
+		break;
+		}
+
+    iUsbViewer.Usb().DeviceStateNotification(0xffffffff, iDeviceState, iStatus);
+	SetActive();
+//                                  15            10 1 -> 26
+	aEvent->iEvent.AppendFormat(_L("D:DeviceState [%S]"), &res);
+	iUsbViewer.NotifyEvent(aEvent);
+
+	// RunL call may have been delayed: ensure viewer has the very latest information
+	TUsbDeviceState deviceState;
+	User::LeaveIfError(iUsbViewer.Usb().GetDeviceState(deviceState));
+
+	iUsbViewer.SetDeviceState(deviceState);
+	}
+	
+	
+CIdPinWatcher* CIdPinWatcher::NewL(CUsbViewer& aUsbViewer)
+	{
+	CIdPinWatcher* self = new(ELeave) CIdPinWatcher(aUsbViewer);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CIdPinWatcher::~CIdPinWatcher()
+	{
+	Cancel();
+	iIdPinProp.Close();
+	}
+
+CIdPinWatcher::CIdPinWatcher(CUsbViewer& aUsbViewer)
+	: CEventNotifier(EPriorityStandard)
+	, iUsbViewer(aUsbViewer)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CIdPinWatcher::ConstructL()
+	{
+	User::LeaveIfError(iIdPinProp.Attach(KUidUsbManCategory, KUsbOtgIdPinPresentProperty));
+	iIdPinProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	TInt err = iIdPinProp.Get(val);
+	LOG("CIdPinWatcher::ConstructL iIdPinProp.Get(val) => %d",err);
+	User::LeaveIfError(err);
+	iUsbViewer.SetIdPin(val);
+	}
+
+void CIdPinWatcher::DoCancel()
+	{
+	iIdPinProp.Cancel();
+	}
+
+void CIdPinWatcher::DoRunL(XUsbViewerEvent* aEvent)
+	{
+	CleanupStack::PushL(aEvent);
+
+	iIdPinProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iIdPinProp.Get(val));
+
+	TPtrC res(NULL, 0);
+	_LIT(KIdPinInserted, "Inserted");
+	_LIT(KIdPinRemoved,  "Removed");
+	switch(val)
+		{
+	case 0:
+		res.Set(KIdPinRemoved);
+		break;
+
+	case 1:
+		res.Set(KIdPinInserted);
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	CleanupStack::Pop();
+//                                  9        8 1 -> 18
+	aEvent->iEvent.AppendFormat(_L("O:IdPin [%S]"), &res);
+	iUsbViewer.SetIdPin(val);
+	iUsbViewer.NotifyEvent(aEvent);
+	}
+	
+	
+CVBusWatcher* CVBusWatcher::NewL(CUsbViewer& aUsbViewer)
+	{
+	CVBusWatcher* self = new(ELeave) CVBusWatcher(aUsbViewer);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CVBusWatcher::~CVBusWatcher()
+	{
+	Cancel();
+	iVBusProp.Close();
+	}
+
+CVBusWatcher::CVBusWatcher(CUsbViewer& aUsbViewer)
+	: CEventNotifier(EPriorityStandard)
+	, iUsbViewer(aUsbViewer)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CVBusWatcher::ConstructL()
+	{
+	User::LeaveIfError(iVBusProp.Attach(KUidUsbManCategory, KUsbOtgVBusPoweredProperty));
+	iVBusProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iVBusProp.Get(val));
+	iUsbViewer.SetVBus(val);
+	}
+
+void CVBusWatcher::DoCancel()
+	{
+	iVBusProp.Cancel();
+	}
+
+void CVBusWatcher::DoRunL(XUsbViewerEvent* aEvent)
+	{
+	CleanupStack::PushL(aEvent);
+
+	iVBusProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iVBusProp.Get(val));
+
+	TPtrC res(NULL, 0);
+	_LIT(KVBusRaised,  "Raised");
+	_LIT(KVBusDropped, "Dropped");
+	switch(val)
+		{
+	case 0:
+		res.Set(KVBusDropped);
+		break;
+
+	case 1:
+		res.Set(KVBusRaised);
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	CleanupStack::Pop();
+//									8       7 1 -> 16
+	aEvent->iEvent.AppendFormat(_L("O:VBus [%S]"), &res);
+	iUsbViewer.SetVBus(val);
+	iUsbViewer.NotifyEvent(aEvent);
+	}
+
+
+CConnectionIdleWatcher* CConnectionIdleWatcher::NewL(CUsbViewer& aUsbViewer)
+	{
+	CConnectionIdleWatcher* self = new(ELeave) CConnectionIdleWatcher(aUsbViewer);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CConnectionIdleWatcher::~CConnectionIdleWatcher()
+	{
+	Cancel();
+	iConnIdleProp.Close();
+	}
+
+CConnectionIdleWatcher::CConnectionIdleWatcher(CUsbViewer& aUsbViewer)
+	: CEventNotifier(EPriorityStandard)
+	, iUsbViewer(aUsbViewer)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CConnectionIdleWatcher::ConstructL()
+	{
+	User::LeaveIfError(iConnIdleProp.Attach(KUidUsbManCategory, KUsbOtgConnectionIdleProperty));
+	iConnIdleProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	TInt err = iConnIdleProp.Get(val);
+	LOG("CConnectionIdleWatcher::ConstructL iConnIdleProp.Get(val) => %d",err);
+	User::LeaveIfError(err);
+	iUsbViewer.SetConnectionIdle(val);
+	}
+
+void CConnectionIdleWatcher::DoCancel()
+	{
+	iConnIdleProp.Cancel();
+	}
+
+void CConnectionIdleWatcher::DoRunL(XUsbViewerEvent* aEvent)
+	{
+	CleanupStack::PushL(aEvent);
+
+	iConnIdleProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iConnIdleProp.Get(val));
+
+	TPtrC res(NULL, 0);
+	_LIT(KConnIdle,		"Idle");
+	_LIT(KConnActive,	"Active");
+	switch(val)
+		{
+	case 0:
+		res.Set(KConnActive);
+		break;
+
+	case 1:
+		res.Set(KConnIdle);
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	CleanupStack::Pop();
+//                                  12          6 1 -> 19
+	aEvent->iEvent.AppendFormat(_L("O:ConnIdle [%S]"), &res);
+	iUsbViewer.SetConnectionIdle(val);
+	iUsbViewer.NotifyEvent(aEvent);
+	}
+
+	
+COtgStateWatcher* COtgStateWatcher::NewL(CUsbViewer& aUsbViewer)
+	{
+	COtgStateWatcher* self = new(ELeave) COtgStateWatcher(aUsbViewer);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+COtgStateWatcher::~COtgStateWatcher()
+	{
+	Cancel();
+	iOtgStateProp.Close();
+	}
+
+COtgStateWatcher::COtgStateWatcher(CUsbViewer& aUsbViewer)
+	: CEventNotifier(EPriorityStandard)
+	, iUsbViewer(aUsbViewer)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void COtgStateWatcher::ConstructL()
+	{
+	User::LeaveIfError(iOtgStateProp.Attach(KUidUsbManCategory, KUsbOtgStateProperty));
+	iOtgStateProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iOtgStateProp.Get(val));
+	iUsbViewer.SetOtgState(val);
+	}
+
+void COtgStateWatcher::DoCancel()
+	{
+	iOtgStateProp.Cancel();
+	}
+
+void COtgStateWatcher::DoRunL(XUsbViewerEvent* aEvent)
+	{
+	CleanupStack::PushL(aEvent);
+
+	iOtgStateProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iOtgStateProp.Get(val));
+
+	TPtrC res(NULL, 0);
+	
+	_LIT(KReset, 		"Reset"			);
+
+	_LIT(KAIdle, 		"A-Idle"		);
+	_LIT(KAHost, 		"A-Host"		);
+	_LIT(KAPeripheral, 	"A-Peripheral"	);
+	_LIT(KABusError, 	"A-Bus Error"	);
+	
+	_LIT(KBIdle, 		"B-Idle"		);
+	_LIT(KBPeripheral, 	"B-Peripheral"	);
+	_LIT(KBHost, 		"B-Host"		);
+	
+	_LIT(KUnknown, 		"Unknown"		);
+
+	switch(val)
+		{
+	case EUsbOtgStateReset:
+		res.Set(KReset);
+		break;
+
+	case EUsbOtgStateAIdle:
+		res.Set(KAIdle);
+		break;
+
+	case EUsbOtgStateAHost:
+		res.Set(KAHost);
+		break;
+
+	case EUsbOtgStateAPeripheral:
+		res.Set(KAPeripheral);
+		break;
+
+	case EUsbOtgStateAVbusError:
+		res.Set(KABusError);
+		break;
+
+	case EUsbOtgStateBIdle:
+		res.Set(KBIdle);
+		break;
+
+	case EUsbOtgStateBPeripheral:
+		res.Set(KBPeripheral);
+		break;
+		
+	case EUsbOtgStateBHost:
+		res.Set(KBHost);
+		break;
+
+	default:
+		res.Set(KUnknown);
+		break;
+		}
+	CleanupStack::Pop();
+
+//                                  12         12 1 -> 25
+	aEvent->iEvent.AppendFormat(_L("O:OtgState [%S]"), &res);
+	iUsbViewer.SetOtgState(val);
+	iUsbViewer.NotifyEvent(aEvent);
+	}
+
+CHostEventWatcher* CHostEventWatcher::NewL(CUsbViewer& aUsbViewer)
+	{
+	CHostEventWatcher* self = new(ELeave) CHostEventWatcher(aUsbViewer);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CHostEventWatcher::~CHostEventWatcher()
+	{
+	Cancel();
+	}
+
+CHostEventWatcher::CHostEventWatcher(CUsbViewer& aUsbViewer)
+	: CEventNotifier(EPriorityStandard)
+	, iUsbViewer(aUsbViewer)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CHostEventWatcher::ConstructL()
+	{
+	iUsbViewer.Usb().HostEventNotification(iStatus, iDeviceInfo);
+	SetActive();
+	iUsbViewer.SetAttachedDevices(0);
+	}
+
+void CHostEventWatcher::DoCancel()
+	{
+	iUsbViewer.Usb().HostEventNotificationCancel();
+	}
+
+void CHostEventWatcher::DoRunL(XUsbViewerEvent* aEvent)
+	{
+	CleanupStack::PushL(aEvent);
+
+	switch(iDeviceInfo.iEventType)
+		{
+	case EDeviceAttachment:
+			{
+			if(iDeviceInfo.iError == KErrNone)
+				{
+				User::LeaveIfError(iAttachedDevices.Append(iDeviceInfo.iDeviceId));
+				}
+//										    5    8    6     4    1 4   1 -> 29
+			aEvent->iEvent.AppendFormat(_L("H:At[%.08x] V,P[%.04x,%.04x]"), iDeviceInfo.iDeviceId, iDeviceInfo.iVid, iDeviceInfo.iPid);
+			
+			if (  (iDeviceInfo.iVid == 0x046D)
+			    &&(iDeviceInfo.iPid == 0x0A02)
+			   )
+				{
+				iUsbViewer.SetDeviceType(CUsbViewer::ELogitechHeadset);
+				}
+			else
+				{
+				iUsbViewer.SetDeviceType(CUsbViewer::EGenericDevice);
+				}
+			}
+		break;
+
+	case EDriverLoad:
+			{
+			TPtrC res(NULL, 0);
+			_LIT(KDriverLoadSuccess, "Success");
+			_LIT(KDriverLoadPartialSuccess, "Warning");
+			_LIT(KDriverLoadFailure, "Failure");
+			switch(iDeviceInfo.iDriverLoadStatus)
+				{
+			case EDriverLoadSuccess:
+				res.Set(KDriverLoadSuccess);
+				break;
+			case EDriverLoadPartialSuccess:
+				res.Set(KDriverLoadPartialSuccess);
+				break;
+			case EDriverLoadFailure:
+				res.Set(KDriverLoadFailure);
+				break;
+			default:
+				PANIC;
+				break;
+				}
+//                                          7      8    6     3   5    1  1 -> 31
+			aEvent->iEvent.AppendFormat(_L("H:Load[%.08x] Err[%.3d] St[%1S]"), iDeviceInfo.iDeviceId, iDeviceInfo.iError, &res);
+			}
+		break;
+
+	case EDeviceDetachment:
+			{
+//											10        8	   1 -> 19
+			aEvent->iEvent.AppendFormat(_L("H:Detach [%.08x]"), iDeviceInfo.iDeviceId);
+			TInt ix = iAttachedDevices.Find(iDeviceInfo.iDeviceId);
+			if(ix == KErrNotFound)
+				{
+				// This is probably caused by starting a new instance of the test console.
+				break;
+				}
+			iAttachedDevices.Remove(ix);
+			iUsbViewer.SetDeviceType(CUsbViewer::ENoDevice);
+			}
+		break;
+	default:
+		PANIC;
+		break;
+		}
+	CleanupStack::Pop();
+	iUsbViewer.SetAttachedDevices(iAttachedDevices.Count());
+	iUsbViewer.NotifyEvent(aEvent);
+	iUsbViewer.Usb().HostEventNotification(iStatus, iDeviceInfo);
+	SetActive();
+	}
+	
+	
+CMessageWatcher* CMessageWatcher::NewL(CUsbViewer& aUsbViewer)
+	{
+	CMessageWatcher* self = new(ELeave) CMessageWatcher(aUsbViewer);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CMessageWatcher::~CMessageWatcher()
+	{
+	Cancel();
+	}
+
+CMessageWatcher::CMessageWatcher(CUsbViewer& aUsbViewer)
+	: CEventNotifier(EPriorityStandard)
+	, iUsbViewer(aUsbViewer)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CMessageWatcher::ConstructL()
+	{
+	iUsbViewer.Usb().MessageNotification(iStatus, iMessage);
+	SetActive();
+	}
+
+void CMessageWatcher::DoCancel()
+	{
+	iUsbViewer.Usb().MessageNotificationCancel();
+	}
+
+void CMessageWatcher::DoRunL(XUsbViewerEvent* aEvent)
+	{
+	TInt err = iStatus.Int();
+	
+	if (err)
+		{
+		aEvent->iEvent.AppendFormat(_L("O:Err! [%d] [%d]"), iMessage, err); // 32 chars max
+		}
+	else
+		{
+		TPtrC text(NULL, 0);
+
+		// OTGDI
+		_LIT(KMessOtgdiEventQueueOverflow,			"O:Event Queue Overflow"			);
+		_LIT(KMessOtgdiStateQueueOverflow,			"O:State Queue Overflow"			);
+		_LIT(KMessOtgdiMessageQueueOverflow,		"O:Message Queue Overflow"			);
+		_LIT(KMessOtgdiBadState,					"O:Bad State"						);
+		_LIT(KMessOtgdiStackNotStarted,				"O:Stack Not Started"				);
+		_LIT(KMessOtgdiVbusAlreadyRaised,			"O:VBUS Already Raised"				);
+		_LIT(KMessOtgdiSrpForbidden,				"O:SRP Forbidden"					);
+		_LIT(KMessOtgdiBusControlProblem,			"O:Bus Control Problem"				);
+		_LIT(KMessOtgdiVbusError,					"O:VBUS Error"						);
+		_LIT(KMessOtgdiSrpTimeout,					"O:SRP Timeout"						);
+		_LIT(KMessOtgdiSrpActive,					"O:SRP Already Active"				);
+		_LIT(KMessOtgdiSrpNotPermitted,				"O:SRP Not Permitted"				);
+		_LIT(KMessOtgdiHnpNotPermitted,				"O:HNP Not Permitted"				);
+		_LIT(KMessOtgdiHnpNotEnabled,				"O:HNP Not Enabled"					);
+		_LIT(KMessOtgdiHnpNotSuspended,				"O:HNP Not Suspended"				);
+		_LIT(KMessOtgdiVbusPowerUpNotPermitted,		"O:VBUS Power Up Not Permitted"		);
+		_LIT(KMessOtgdiVbusPowerDownNotPermitted,	"O:VBUS Power Down Not Permitted"	);
+		_LIT(KMessOtgdiVbusClearErrorNotPermitted,	"O:VBUS Clear Error Not Permitted"	);
+
+		// USBDI - Main
+
+		_LIT(KMessUsbdiRequestsPending,				"U:Requests Pending"				);		
+		_LIT(KMessUsbdiBadAddress,					"U:Bad Address"						);
+		_LIT(KMessUsbdiNoAddress,					"U:No Address"						);
+		_LIT(KMessUsbdiSetAddrFailed,				"U:Set Address Failed"				);
+		_LIT(KMessUsbdiNoPower,						"U:No Power"						);
+		_LIT(KMessUsbdiTooDeep,						"U:Too Deep"						);
+		_LIT(KMessUsbdiIOError,						"U:IO Error"						);
+		_LIT(KMessUsbdiNotConfigured,				"U:Not Configured"					);
+		_LIT(KMessUsbdiTimeout,						"U:Timeout"							);
+		_LIT(KMessUsbdiStalled,						"U:Stalled"							);
+		_LIT(KMessUsbdiTestFailure,					"U:Test Failure"					);
+		_LIT(KMessUsbdiBadState,					"U:Bad State"						);
+		_LIT(KMessUsbdiDeviceSuspended,				"U:Device Suspended"				);
+
+		// USBDI - Descriptors
+
+		_LIT(KMessUsbdiBadDescriptorTopology,		"U:Bad Descriptor Topology"			);
+
+		// USBDI - DevMon
+
+		_LIT(KMessUsbdiDeviceRejected,				"U:Device Rejected"					);
+		_LIT(KMessUsbdiDeviceFailed,				"U:Device failed"					);
+		_LIT(KMessUsbdiBadDevice,					"U:Bad Device"						);
+		_LIT(KMessUsbdiBadHubPosition,				"U:Bad Hub Position"				);
+		_LIT(KMessUsbdiBadHub,						"U:Bad Hub"							);
+		_LIT(KMessUsbdiEventOverflow,				"U:Event Overflow"					);
+		
+		// USBMAN
+		
+		_LIT(KMessUsbmanSrpInitiated,				"M:SRP Initiated"					);
+		_LIT(KMessUsbmanSrpReceived,				"M:SRP Received"					);
+		_LIT(KMessUsbmanHnpDisabled,				"M:HNP Disabled"					);
+		_LIT(KMessUsbmanHnpEnabled,					"M:HNP Enabled"						);
+		_LIT(KMessUsbmanVbusRaised,					"M:VBUS Raised"						);
+		_LIT(KMessUsbmanVbusDropped,				"M:VBUS Dropped"					);
+		_LIT(KMessUsbmanRequestSession,				"M:Request Session"					);
+
+		_LIT(KMessUnknown, 							"*:Unknown"							);
+
+		switch(iMessage)
+			{
+			// OTGDI
+
+			case KErrUsbOtgEventQueueOverflow:			text.Set(KMessOtgdiEventQueueOverflow);			break;
+			case KErrUsbOtgStateQueueOverflow:	       	text.Set(KMessOtgdiStateQueueOverflow);			break;
+			case KErrUsbOtgMessageQueueOverflow:		text.Set(KMessOtgdiMessageQueueOverflow)	;	break;
+			case KErrUsbOtgBadState:					text.Set(KMessOtgdiBadState);					break;		
+			case KErrUsbOtgStackNotStarted:				text.Set(KMessOtgdiStackNotStarted);			break;	
+			case KErrUsbOtgVbusAlreadyRaised:	       	text.Set(KMessOtgdiVbusAlreadyRaised);			break;
+			case KErrUsbOtgSrpForbidden:				text.Set(KMessOtgdiSrpForbidden);				break;	
+			case KErrUsbOtgBusControlProblem:	       	text.Set(KMessOtgdiBusControlProblem);			break;
+			case KErrUsbOtgVbusError:			       	text.Set(KMessOtgdiVbusError);					break;		
+			case KErrUsbOtgSrpTimeout:			       	text.Set(KMessOtgdiSrpTimeout);					break;		
+			case KErrUsbOtgSrpActive:			       	text.Set(KMessOtgdiSrpActive);					break;		
+			case KErrUsbOtgSrpNotPermitted:				text.Set(KMessOtgdiSrpNotPermitted);			break;
+			case KErrUsbOtgHnpNotPermitted:				text.Set(KMessOtgdiHnpNotPermitted);			break;
+			case KErrUsbOtgHnpNotEnabled:				text.Set(KMessOtgdiHnpNotEnabled);				break;
+			case KErrUsbOtgHnpNotSuspended:				text.Set(KMessOtgdiHnpNotSuspended);			break;
+			case KErrUsbOtgVbusPowerUpNotPermitted:  	text.Set(KMessOtgdiVbusPowerUpNotPermitted);	break;
+			case KErrUsbOtgVbusPowerDownNotPermitted:	text.Set(KMessOtgdiVbusPowerDownNotPermitted);	break;
+			case KErrUsbOtgVbusClearErrorNotPermitted:	text.Set(KMessOtgdiVbusClearErrorNotPermitted);	break;
+
+			// USBDI - Main
+
+			case KErrUsbRequestsPending:				text.Set(KMessUsbdiRequestsPending);			break;		
+			case KErrUsbBadAddress:						text.Set(KMessUsbdiBadAddress); 				break;			
+			case KErrUsbNoAddress:						text.Set(KMessUsbdiNoAddress); 					break;			
+			case KErrUsbSetAddrFailed:					text.Set(KMessUsbdiSetAddrFailed); 				break;		
+			case KErrUsbNoPower:						text.Set(KMessUsbdiNoPower); 					break;				
+			case KErrUsbTooDeep:						text.Set(KMessUsbdiTooDeep); 					break;				
+			case KErrUsbIOError:						text.Set(KMessUsbdiIOError); 					break;				
+			case KErrUsbNotConfigured:					text.Set(KMessUsbdiNotConfigured); 				break;		
+			case KErrUsbTimeout:						text.Set(KMessUsbdiTimeout); 					break;				
+			case KErrUsbStalled:						text.Set(KMessUsbdiStalled); 					break;				
+			case KErrUsbTestFailure:					text.Set(KMessUsbdiTestFailure); 				break;			
+			case KErrUsbBadState:						text.Set(KMessUsbdiBadState); 					break;			
+			case KErrUsbDeviceSuspended:				text.Set(KMessUsbdiDeviceSuspended); 			break;		
+																									
+			// USBDI - Descriptors																	
+			
+			case KErrUsbBadDescriptorTopology:			text.Set(KMessUsbdiBadDescriptorTopology); 		break;
+
+			// USBDI - DevMon
+			
+			case KErrUsbDeviceRejected:					text.Set(KMessUsbdiDeviceRejected); 			break;		
+			case KErrUsbDeviceFailed:					text.Set(KMessUsbdiDeviceFailed); 				break;		
+			case KErrUsbBadDevice:						text.Set(KMessUsbdiBadDevice); 					break;			
+			case KErrUsbBadHubPosition:					text.Set(KMessUsbdiBadHubPosition); 			break;		
+			case KErrUsbBadHub:							text.Set(KMessUsbdiBadHub); 					break;				
+			case KErrUsbEventOverflow:					text.Set(KMessUsbdiEventOverflow); 				break;		
+																										
+			// USBMAN																					
+																										
+			case KUsbMessageSrpInitiated:				text.Set(KMessUsbmanSrpInitiated);				break;
+			case KUsbMessageSrpReceived:				text.Set(KMessUsbmanSrpReceived);				break;
+			case KUsbMessageHnpDisabled:				text.Set(KMessUsbmanHnpDisabled);				break;
+			case KUsbMessageHnpEnabled:					text.Set(KMessUsbmanHnpEnabled);				break;
+			case KUsbMessageVbusRaised:					text.Set(KMessUsbmanVbusRaised);				break;
+			case KUsbMessageVbusDropped:				text.Set(KMessUsbmanVbusDropped);				break;
+			case KUsbMessageRequestSession:				text.Set(KMessUsbmanRequestSession);			break;
+																										
+			default:									text.Set(KMessUnknown);							break;
+			} // switch(iMessage)																							
+
+		// The message number can be positive (USBMAN) or negative (OTGDI/USBDI)
+		
+		LOG("CMessageWatcher::DoRunL iMessage = [%d]",iMessage);
+		LOG("CMessageWatcher::DoRunL text     = [%S]",&text);
+
+		if ( iMessage > 0 )
+			{
+			//								4   1 4   3   19  1 -> 32
+			aEvent->iEvent.AppendFormat(_L("Msg[+%4.4d] [%.19S]"), iMessage, &text); // 32 chars max
+			}
+		else
+			{
+			//								4   1 4   3   19  1 -> 32
+			aEvent->iEvent.AppendFormat(_L("Msg[-%4.4d] [%.19S]"), -iMessage, &text); // 32 chars max
+			}
+		} // else
+
+	iUsbViewer.Usb().MessageNotification(iStatus, iMessage);
+	SetActive();
+	iUsbViewer.NotifyEvent(aEvent);
+	}
+
+
+
+
+CUserMsgQWatcher* CUserMsgQWatcher::NewL(CUsbViewer& aUsbViewer)
+	{
+	CUserMsgQWatcher* self = new(ELeave) CUserMsgQWatcher(aUsbViewer);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CUserMsgQWatcher::~CUserMsgQWatcher()
+	{
+	Cancel();
+	}
+
+CUserMsgQWatcher::CUserMsgQWatcher(CUsbViewer& aUsbViewer)
+	: CEventNotifier(EPriorityStandard)
+	, iUsbViewer(aUsbViewer)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUserMsgQWatcher::ConstructL()
+	{
+	iUsbViewer.UserMsgQ().NotifyDataAvailable(iStatus);
+	SetActive();
+	}
+
+void CUserMsgQWatcher::DoCancel()
+	{
+	iUsbViewer.UserMsgQ().CancelDataAvailable();
+	}
+
+void CUserMsgQWatcher::DoRunL(XUsbViewerEvent* aEvent)
+	{
+	CleanupStack::PushL(aEvent);
+
+	User::LeaveIfError(iUsbViewer.UserMsgQ().Receive(iUserMsgLine));
+	LOG("CUserMsgQWatcher::DoRunL		iUsbViewer.UserMsgQ().Receive => %S", &iUserMsgLine);
+	CleanupStack::Pop();
+
+	aEvent->iEvent.AppendFormat(_L("%S"), &iUserMsgLine);
+	iUsbViewer.NotifyEvent(aEvent);
+
+	iUsbViewer.UserMsgQ().NotifyDataAvailable(iStatus); // Re-subscribe
+	SetActive();
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/usbviewer/usbviewer.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,355 @@
+/*
+* 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 "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:
+*
+*/
+
+#ifndef USBVIEWER_H
+#define USBVIEWER_H
+
+#include <e32cmn.h>
+#include <e32base.h>
+#include <usbman.h>
+#include <e32property.h>
+#include "e32msgqueue.h"
+
+#include "usbcontrolappshared.h"
+
+class CConsoleBase;
+
+class CUserMsgQWatcher;
+class CServiceStateWatcher;
+class CDeviceStateWatcher;
+class CIdPinWatcher;
+class CVBusWatcher;
+class CConnectionIdleWatcher;
+class CHostEventWatcher;
+class CMessageWatcher;
+class COtgStateWatcher;
+
+class CShutdownMonitor;
+
+_LIT(KUsbViewerTitle, "USB Viewer");
+
+
+NONSHARABLE_STRUCT(XUsbViewerEvent)
+	{
+	~XUsbViewerEvent();
+	TDblQueLink	iLink;
+	RBuf		iEvent;
+	};
+
+
+NONSHARABLE_CLASS(MShutdownInterface)
+	{
+public:
+	virtual void Stop() const = 0;
+	};
+
+
+NONSHARABLE_CLASS(CUsbViewer) : public CActive, public MShutdownInterface
+	{
+public:
+	static CUsbViewer* NewLC();
+	~CUsbViewer();
+
+public:
+	void Start();
+	void Stop() const;
+	
+	RUsb& Usb();
+	RMsgQueue<TBuf<KViewerNumCharactersOnLine> >& UserMsgQ();	
+
+public:
+	enum TFdfDriverLoadingState
+		{
+		EUnknown,
+		EDisabled,
+		EEnabled
+		};
+	
+	enum TDeviceType
+		{
+		ENoDevice,
+		EGenericDevice,
+		ELogitechHeadset
+		};
+
+public: // Callbacks
+	void SetServiceState(TUsbServiceState aServiceState);
+	void SetDeviceState(TUsbDeviceState aDeviceState);
+	void SetIdPin(TInt aIdPin);
+	void SetVBus(TInt aVBus);
+	void SetConnectionIdle(TInt aConnIdle);
+	void SetOtgState(TInt aOtgState);
+	void SetDriverLoading(TFdfDriverLoadingState aDriverLoading);
+	void SetAttachedDevices(TUint aAttachedDevices);
+	void SetDeviceType(TDeviceType aDeviceType);
+
+	void NotifyEvent(XUsbViewerEvent* aEvent);
+
+private:
+	CUsbViewer();
+	void ConstructL();
+	void Move(TInt aX, TInt aY);
+	void Draw();
+
+	void DoCancel();
+	void RunL();
+	void ScheduleDraw();
+	
+	TBool		iAutoSrpResponse;
+	TDeviceType iDeviceType;
+	
+private:
+	CConsoleBase*		iConsole;
+	RUsb				iUsb;
+	CShutdownMonitor*	iShutdownMonitor;
+	
+private:
+	CUserMsgQWatcher*		iUserMsgQWatcher;
+	CServiceStateWatcher*	iServiceStateWatcher;
+	CDeviceStateWatcher*	iDeviceStateWatcher;
+	CIdPinWatcher*			iIdPinWatcher;
+	CVBusWatcher*			iVBusWatcher;
+	CConnectionIdleWatcher*	iConnIdleWatcher;
+	COtgStateWatcher*		iOtgStateWatcher;
+	CHostEventWatcher*		iHostEventWatcher;
+	CMessageWatcher*		iMessageWatcher;
+
+private: // Display variables
+	TVersion	iVersion;
+	TBuf<11>	iServStatus; // Needs Trailing Space
+	TBuf<11>	iDevStatus; // Needs Trailing Space
+	TBuf<5>		iIdPin; // Needs Trailing Space
+	TBuf<5>		iVBus;  // Needs Trailing Space
+	TBuf<5>		iConnIdle; // Needs Trailing Space
+	TBuf<3>		iDriverLoading;
+	TBuf<3>		iAttachedDevices;
+	TBuf<14>	iOtgState;  // Needs Trailing Space
+	TBuf<5>		iAttachedDevice;
+
+private:
+	static const TInt KNumEventsInWindow = 7;
+	// H4 screen can have 22 lines of text on it at once
+	static const TInt KNumLinesInWindow = 14;
+	
+private: // Event list
+	TDblQue<XUsbViewerEvent>						iEventList;
+	// RMsgQueue between exampleusbcontrolapp.exe & usbviewer.exe for displaying user messages
+	RMsgQueue<TBuf<KViewerNumCharactersOnLine> >	iUserMsgQ;
+	};
+	
+
+NONSHARABLE_CLASS(CShutdownMonitor) : public CActive
+	{
+public:
+	static CShutdownMonitor* NewL(MShutdownInterface& aParentUsbViewer);
+	~CShutdownMonitor();
+private:
+	CShutdownMonitor(MShutdownInterface& aParentUsbViewer);
+	void ConstructL();
+	// From CActive
+	void DoCancel();
+	void RunL();
+private:
+	RProperty				iShutdownProp;
+	MShutdownInterface&		iParentUsbViewer;
+	};
+
+	
+NONSHARABLE_CLASS(CEventNotifier) : public CActive
+	{
+protected:
+	CEventNotifier(TInt aPriority);
+	XUsbViewerEvent* NewViewerEventL();
+	virtual void DoRunL(XUsbViewerEvent* aEvent) = 0;
+private:
+	void RunL();
+	};
+	
+	
+NONSHARABLE_CLASS(CServiceStateWatcher) : public CEventNotifier
+	{
+public:
+	static CServiceStateWatcher* NewL(CUsbViewer& aUsb);
+	~CServiceStateWatcher();
+
+private:
+	CServiceStateWatcher(CUsbViewer& aUsb);
+	void ConstructL();
+
+	void DoCancel();
+	void DoRunL(XUsbViewerEvent* aEvent);
+
+private:
+	CUsbViewer&	iUsbViewer;
+	TUsbServiceState	iServiceState;
+	};
+
+
+NONSHARABLE_CLASS(CDeviceStateWatcher) : public CEventNotifier
+	{
+public:
+	static CDeviceStateWatcher* NewL(CUsbViewer& aUsb);
+	~CDeviceStateWatcher();
+
+private:
+	CDeviceStateWatcher(CUsbViewer& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbViewerEvent* aEvent);
+
+private:
+	CUsbViewer&	iUsbViewer;
+	TUsbDeviceState		iDeviceState;
+	};
+
+
+NONSHARABLE_CLASS(CIdPinWatcher) : public CEventNotifier
+	{
+public:
+	static CIdPinWatcher* NewL(CUsbViewer& aUsb);
+	~CIdPinWatcher();
+
+private:
+	CIdPinWatcher(CUsbViewer& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbViewerEvent* aEvent);
+
+private:
+	CUsbViewer&	iUsbViewer;
+	RProperty			iIdPinProp;
+	};
+
+
+NONSHARABLE_CLASS(CVBusWatcher) : public CEventNotifier
+	{
+public:
+	static CVBusWatcher* NewL(CUsbViewer& aUsb);
+	~CVBusWatcher();
+
+private:
+	CVBusWatcher(CUsbViewer& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbViewerEvent* aEvent);
+
+private:
+	CUsbViewer&		iUsbViewer;
+	RProperty		iVBusProp;
+	};
+
+
+NONSHARABLE_CLASS(CConnectionIdleWatcher) : public CEventNotifier
+	{
+public:
+	static CConnectionIdleWatcher* NewL(CUsbViewer& aUsb);
+	~CConnectionIdleWatcher();
+
+private:
+	CConnectionIdleWatcher(CUsbViewer& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbViewerEvent* aEvent);
+
+private:
+	CUsbViewer&		iUsbViewer;
+	RProperty		iConnIdleProp;
+	};
+
+	
+NONSHARABLE_CLASS(COtgStateWatcher) : public CEventNotifier
+	{
+public:
+	static COtgStateWatcher* NewL(CUsbViewer& aUsb);
+	~COtgStateWatcher();
+
+private:
+	COtgStateWatcher(CUsbViewer& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbViewerEvent* aEvent);
+
+private:
+	CUsbViewer&		iUsbViewer;
+	RProperty		iOtgStateProp;
+	};
+	
+	
+NONSHARABLE_CLASS(CHostEventWatcher) : public CEventNotifier
+	{
+public:
+	static CHostEventWatcher* NewL(CUsbViewer& aUsb);
+	~CHostEventWatcher();
+
+private:
+	CHostEventWatcher(CUsbViewer& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbViewerEvent* aEvent);
+
+private:
+	CUsbViewer&				iUsbViewer;
+	TDeviceEventInformation	iDeviceInfo;
+	RArray<TUint>			iAttachedDevices;
+	};
+	
+
+NONSHARABLE_CLASS(CMessageWatcher) : public CEventNotifier
+	{
+public:
+	static CMessageWatcher* NewL(CUsbViewer& aUsb);
+	~CMessageWatcher();
+
+private:
+	CMessageWatcher(CUsbViewer& aUsb);
+	void ConstructL();
+
+	void DoCancel();
+	void DoRunL(XUsbViewerEvent* aEvent);
+
+private:
+	CUsbViewer&	iUsbViewer;
+	TInt		iMessage;
+	};
+
+
+NONSHARABLE_CLASS(CUserMsgQWatcher) : public CEventNotifier
+	{
+public:
+	static CUserMsgQWatcher* NewL(CUsbViewer& aUsb);
+	~CUserMsgQWatcher();
+
+private:
+	CUserMsgQWatcher(CUsbViewer& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbViewerEvent* aEvent);
+
+private:
+	CUsbViewer&							iUsbViewer;
+	TBuf<KViewerNumCharactersOnLine>	iUserMsgLine;
+	};
+	
+
+#endif // USBVIEWER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbcontrolapp/usbviewer/usbviewer.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,34 @@
+/*
+* 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 "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:
+*
+*/
+
+
+target		usbviewer.exe
+targettype	exe
+UID		0x100039CE 0x10285EE8
+VENDORID	0x70000001
+
+capability	SwEvent
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+userinclude	../shared
+
+sourcepath	../usbviewer
+source		usbviewer.cpp
+
+library		euser.lib
+library		usbman.lib
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,37 @@
+/*
+* Copyright (c) 1999-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:
+* Build information for USB Mass Storage sample application
+*
+*/
+
+/**
+ @file
+*/
+
+
+#include "usbms_stub/group/bld.inf"
+
+PRJ_EXPORTS
+
+PRJ_TESTEXPORTS
+
+./usbms.iby /epoc32/rom/include/usbms.iby
+./usbms.oby /epoc32/rom/include/usbms.oby
+
+PRJ_MMPFILES
+
+PRJ_TESTMMPFILES
+
+usbmsapp.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms.iby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+#ifndef __USBMS_IBY__
+#define __USBMS_IBY__
+
+#include <usbman.iby>
+
+file=ABI_DIR\DEBUG_DIR\usbms_stub1cc.dll			System\libs\Plugins\stub1cc.dll
+file=ABI_DIR\DEBUG_DIR\usbms_stub2cc.dll			System\libs\Plugins\stub2cc.dll
+file=ABI_DIR\DEBUG_DIR\usbms_stub3cc.dll			System\libs\Plugins\stub3cc.dll
+
+#ifdef USBMS90
+data=ZRESOURCE\Plugins\stub1cc.RSC 		SYSTEM\LIBS\Plugins\10203284.RSC
+data=ZRESOURCE\Plugins\stub2cc.RSC 		SYSTEM\LIBS\Plugins\10203286.RSC
+data=ZRESOURCE\Plugins\stub3cc.RSC 		SYSTEM\LIBS\Plugins\10203288.RSC
+data=ZRESOURCE\Plugins\msclasscontroller.RSC 		SYSTEM\LIBS\Plugins\10204BBB.RSC
+#else
+// 8.1a, 8.1b
+data=ZSYSTEM\Libs\Plugins\10203284.RSC 		SYSTEM\LIBS\Plugins\10203284.RSC
+data=ZSYSTEM\Libs\Plugins\10203286.RSC 		SYSTEM\LIBS\Plugins\10203286.RSC
+data=ZSYSTEM\Libs\Plugins\10203288.RSC 		SYSTEM\LIBS\Plugins\10203288.RSC
+data=ZSYSTEM\Libs\Plugins\10204BBB.RSC 		SYSTEM\LIBS\Plugins\10204BBB.RSC
+#endif
+
+file=ABI_DIR\DEBUG_DIR\msfs.fsy			System\libs\msfs.fsy
+file=ABI_DIR\DEBUG_DIR\usbmsexampleapp.exe		System\Programs\usbmsexampleapp.exe
+file=ABI_DIR\DEBUG_DIR\msclasscontroller.dll	System\libs\Plugins\msclasscontroller.dll
+
+file=ABI_DIR\DEBUG_DIR\t_usbms_cable_detect.exe System\Programs\t_usbms_cable_detect.exe
+
+data=ZPRIVATE\101fe1db\USBMAN.R01 		Private\101fe1db\USBMAN.R01
+data=ZPRIVATE\101fe1db\USBMAN.R02 		Private\101fe1db\USBMAN.R02
+data=ZPRIVATE\101fe1db\USBMAN.R03 		Private\101fe1db\USBMAN.R03
+data=ZPRIVATE\101fe1db\USBMAN.R10 		Private\101fe1db\USBMAN.R10
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms.oby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,156 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+#ifndef __USBMS_OBY__
+#define __USBMS_OBY__
+
+// This OBY File is used to build CDMA Test ROM Images.
+
+// Building a ROM Image generates a number of files.  Thus it is better to run this
+// from a separate directory.  To build a CDMA test ROM enter the following:
+//
+//   Building for Assabet
+//      1) buildrom assabet CDMAtest.oby 
+//      2) buildrom -D_DEBUG assabet CDMAtest.oby 
+//      3) buildrom -DTEXT_ONLY_ROM assabet CDMAtest.oby 
+//      4) buildrom -DTEXT_ONLY_ROM -D_DEBUG assabet CDMAtest.oby 
+//
+//   Building for Lubbock - CF Card loader
+//      1) buildrom lubbock CDMAtest.oby 
+//      2) buildrom -D_DEBUG lubbock CDMAtest.oby 
+//      3) buildrom -DTEXT_ONLY_ROM lubbock CDMAtest.oby 
+//      4) buildrom -DTEXT_ONLY_ROM -D_DEBUG lubbock CDMAtest.oby 
+//
+//   Building for Lubbock - Ethernet TFTP loader
+//      1) Create a rom using the above then rombuild --no-header (Output *.oby file from the above) 
+//
+// _DEBUG results in debug ROMS and TEXT_ONLY_ROM generates text only ROMS.  The above 
+// shows all combinations.
+
+define ROMDATE	##TODAY##
+
+#define __TCPIP_IBY__ // used to avoid including the old IP4 TCPIP.IBY via PLP.IBY
+#define NO_METROTRK_APP // don't want metrotrk application
+#define EXCLUDE_JAVA
+#define EXCLUDE_APPINST
+#define HAS_ETHERNET	// include etherDrv, ether802, DHCP
+#define __INCLUDE_SW_KEYSTORE__ // Put sw implementation of keystore into v8.0a ROM
+
+#include <header.iby>				/* ROM header definitions */
+#include <base.iby>					/* The lowest-level of the operating system */
+
+#include <debug.iby>
+
+kerneltrace 0x80000000
+
+		file=ABI_DIR\DEBUG_DIR\EDISP.DLL				System\Libs\EDISP.DLL
+
+file=ABI_DIR\DEBUG_DIR\ECONS.DLL					System\Libs\ECONS.DLL	
+
+file=ABI_DIR\DEBUG_DIR\EWSRV.EXE					System\Libs\EWSRV.EXE	fixed
+
+file=ABI_DIR\DEBUG_DIR\ESHELL.EXE					System\Libs\ESHELL.EXE heapmin=0x8000
+
+////////////////////////////////////////// Full Text Support
+
+file=ABI_DIR\DEBUG_DIR\form.DLL					System\Libs\form.dll
+file=ABI_DIR\DEBUG_DIR\tagma.DLL				System\Libs\tagma.DLL
+
+file=ABI_DIR\BUILD_DIR\ws32.dll					System\Libs\Ws32.dll
+
+file=ABI_DIR\BUILD_DIR\VIEWCLI.DLL				System\Libs\VIEWCLI.DLL
+file=ABI_DIR\BUILD_DIR\VIEWSRV.DLL				System\Libs\VIEWSRV.DLL
+file=ABI_DIR\BUILD_DIR\UIKLAF.DLL				System\Libs\UIKLAF.DLL
+file=ABI_DIR\BUILD_DIR\EXPARSER.DLL				System\Libs\EXPARSER.DLL
+file=ABI_DIR\BUILD_DIR\Eikcore.DLL				System\Libs\Eikcore.dll
+file=ABI_DIR\BUILD_DIR\EIKSRVC.DLL				System\Libs\EIKSRVC.DLL
+file=ABI_DIR\BUILD_DIR\Sysamob.exe				System\Libs\Sysamob.exe
+
+/* extras */
+#include "mmfsounddev.iby"
+#include "ezlib.iby"
+#include <centralrepository.iby>
+#include <http.iby>
+
+	#include <crypto.iby>
+
+#include <c32.iby>			/* standard Sockets components */
+#include <irda.iby>			/* standard Sockets components */
+#include <bluetooth.iby>	/* standard Sockets components */
+#include <gdi.iby>			/* standard Graphics components */
+#include <fntstore.iby>		/* standard Graphics components */
+#include <fbserv.iby>		/* standard Graphics components */
+#include <bitgdi.iby>		/* standard Graphics components */
+
+#include <apparc.iby>		/* Application architecture DLLs */
+#include <emime.iby>		/* Mime recognition */
+
+#include <fepbase.iby>		/* Front end processor base classes */
+
+#include <mmf.iby> 			/* Multimedia Framework */
+
+#include <sysagent.iby>		/* System Agent client and server */
+
+#include <network.iby>		/* Networking Components */
+
+#include <wapmessage.iby>       	/* Wap Stack Components  */
+
+// ============== Telephony Core Components =============
+#include <etel.iby>
+#include <smsstack.iby>
+#include <etelmm.iby>
+#include <etelpckt.iby>
+#include <mmtsy.iby>
+#include <phbksync.iby>
+#include <etelsat.iby>
+#include <sysawatcher.iby>
+
+#include <ecom.iby>
+
+/* Store */
+#include "Store.iby"
+
+/* Etext */
+#include "EText.iby"
+
+/* Clock */
+file=ABI_DIR\BUILD_DIR\clock.dll				System\Libs\Clock.dll
+
+/* Print */
+file=ABI_DIR\BUILD_DIR\print.dll				System\Libs\Print.dll
+
+/* Pwrcli */
+#include "PwrCli.iby"
+
+/* Bafl */
+#include "Bafl.iby"
+
+/* Cone */
+file=ABI_DIR\DEBUG_DIR\cone.dll					System\Libs\Cone.dll
+
+/* NumberConversion */
+#include "NumberConversion.iby"
+
+/* EGUL */
+file=ABI_DIR\DEBUG_DIR\egul.dll					System\Libs\Egul.dll
+
+/* Dial */
+file=ABI_DIR\BUILD_DIR\dial.dll					System\Libs\Dial.dll
+
+#include "usbms.iby"
+
+#endif //__USBMS_OBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/BWINS/usbms_stub1ccU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,3 @@
+EXPORTS
+	?ImplementationGroupProxy@@YAPBUTImplementationProxy@@AAH@Z @ 1 NONAME ; struct TImplementationProxy const * ImplementationGroupProxy(int &)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/BWINS/usbms_stub2ccU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,3 @@
+EXPORTS
+	?ImplementationGroupProxy@@YAPBUTImplementationProxy@@AAH@Z @ 1 NONAME ; struct TImplementationProxy const * ImplementationGroupProxy(int &)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/BWINS/usbms_stub3ccU.DEF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,3 @@
+EXPORTS
+	?ImplementationGroupProxy@@YAPBUTImplementationProxy@@AAH@Z @ 1 NONAME ; struct TImplementationProxy const * ImplementationGroupProxy(int &)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/group/BLD.INF	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,30 @@
+/*
+* 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 "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:
+*
+*/
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_TESTEXPORTS
+
+PRJ_TESTMMPFILES
+#ifdef WINS
+usbms_stub1cc.mmp
+usbms_stub2cc.mmp
+usbms_stub3cc.mmp
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/group/usbms_stub1cc.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 1997-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
+*/
+
+#define USB_LOG_TO_FILE__
+
+target usbms_stub1cc.dll
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+targettype dll
+
+// ECom Dll recognition UID followed by the unique dll UID 
+UID              	0x10009d8d 0x10203284
+VENDORID 0x70000001
+DEFFILE usbms_stub1cc.DEF
+
+SOURCEPATH		../src
+SOURCE			Stub1CCImpCollection.cpp
+SOURCE			usbms_stub.cpp
+
+USERINCLUDE		../inc
+USERINCLUDE		../../../../usbmgr/usbman/server/public
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+#ifdef USB_LOG_TO_FILE__
+MACRO __USB_LOG_TO_FILE__
+#endif												
+
+#ifdef USB_LOG_TO_RDEBUG__
+MACRO __USB_LOG_TO_RDEBUG__
+#endif
+
+
+
+start resource 10203284.rss
+target usbms_stub1cc.rsc
+END
+
+LIBRARY			euser.lib 
+LIBRARY			usbclasscontroller.lib
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/group/usbms_stub2cc.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 1997-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
+*/
+
+#define USB_LOG_TO_FILE__
+
+target usbms_stub2cc.dll
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+targettype dll
+
+// ECom Dll recognition UID followed by the unique dll UID 
+UID              	0x10009d8d 0x10203286
+VENDORID 0x70000001
+DEFFILE usbms_stub2cc.DEF
+
+SOURCEPATH		../src
+SOURCE			Stub2CCImpCollection.cpp
+SOURCE			usbms_stub.cpp
+
+USERINCLUDE		../inc
+USERINCLUDE		../../../../usbmgr/usbman/server/public
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+#ifdef USB_LOG_TO_FILE__
+MACRO __USB_LOG_TO_FILE__
+#endif												
+
+#ifdef USB_LOG_TO_RDEBUG__
+MACRO __USB_LOG_TO_RDEBUG__
+#endif
+
+
+
+start resource 10203286.rss
+target stub2cc.rsc
+END
+
+LIBRARY			euser.lib
+LIBRARY			usbclasscontroller.lib
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/group/usbms_stub3cc.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 1997-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
+*/
+
+#define USB_LOG_TO_FILE__
+
+target usbms_stub3cc.dll
+CAPABILITY CommDD NetworkControl NetworkServices LocalServices ProtServ
+targettype dll
+
+// ECom Dll recognition UID followed by the unique dll UID 
+UID              	0x10009d8d 0x10203288
+VENDORID 0x70000001
+DEFFILE usbms_stub3cc.DEF
+
+SOURCEPATH		../src
+SOURCE			Stub3CCImpCollection.cpp
+SOURCE			usbms_stub.cpp
+
+USERINCLUDE		../inc
+USERINCLUDE		../../../../usbmgr/usbman/server/public
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+#ifdef USB_LOG_TO_FILE__
+MACRO __USB_LOG_TO_FILE__
+#endif												
+
+#ifdef USB_LOG_TO_RDEBUG__
+MACRO __USB_LOG_TO_RDEBUG__
+#endif
+
+
+
+start resource 10203288.rss
+target stub3cc.rsc
+END
+
+LIBRARY			euser.lib 
+LIBRARY			usbclasscontroller.lib
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/inc/usbms_stub.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,122 @@
+/**
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class API and talks to C32
+* to manage the stub3.CSY that is used to provide a virtual
+* serial port service to clients
+* 
+*
+*/
+
+
+
+/**
+ @file
+*/
+
+#ifndef __CUSBstub3CLASSCONTROLLER_H__
+#define __CUSBstub3CLASSCONTROLLER_H__
+
+#include <e32std.h>
+#include <cusbclasscontrollerplugin.h>
+#include <d32usbc.h>
+
+class MUsbClassControllerNotify;
+
+const TInt Kstub3StartupPriority = 2;
+
+const TInt Kstub3CCDefaultDelay = 500; //0.5 sec default delay for start and stop
+
+const TInt Kstub3NumberOfInterfacesPerstub3Function = 2; // data and control interfaces
+
+// The name of the ini file specifying the number of functions required different from default
+/*
+_LIT(Kstub3FunctionsIniFileName, "NumberOfstub3Functions.ini");
+_LIT(Kstub3ConfigSection,"stub3_CONF");
+_LIT(KNumberOfstub3FunctionsKeyWord,"NumberOfstub3Functions");
+*/
+// Lengths of the various bits of the  descriptor. Taken from the USB
+// WMCDC specification, v1.0.
+const TInt Kstub3InterfaceDescriptorLength = 3;
+const TInt Kstub3CcHeaderDescriptorLength = 5;
+const TInt Kstub3FunctionalDescriptorLength = 4;
+const TInt Kstub3CcUfdDescriptorLength = 5;
+const TInt Kstub3NotificationEndpointDescriptorLength = 7;
+const TInt Kstub3DataClassInterfaceDescriptorLength = 3;
+const TInt Kstub3DataClassHeaderDescriptorLength = 5;
+const TInt Kstub3DataClassEndpointInDescriptorLength = 7;
+const TInt Kstub3DataClassEndpointOutDescriptorLength = 7;
+
+const TInt Kstub3DescriptorLength =
+	Kstub3InterfaceDescriptorLength +
+	Kstub3CcHeaderDescriptorLength +
+	Kstub3FunctionalDescriptorLength +
+	Kstub3CcUfdDescriptorLength +
+	Kstub3NotificationEndpointDescriptorLength +
+	Kstub3DataClassInterfaceDescriptorLength +
+	Kstub3DataClassHeaderDescriptorLength +
+	Kstub3DataClassEndpointInDescriptorLength +
+	Kstub3DataClassEndpointOutDescriptorLength;
+	
+/**
+ * The CUsbstub3ClassController class
+ *
+ * Implements the USB Class Controller API and manages the stub3.CSY
+ */
+NONSHARABLE_CLASS(CUsbstub3ClassController) : public CUsbClassControllerPlugIn
+	{
+
+public: // New functions.
+	static CUsbstub3ClassController* NewL(MUsbClassControllerNotify& aOwner);
+
+public: // Functions derived from CBase.
+	virtual ~CUsbstub3ClassController();
+
+public: // Functions derived from CActive.
+	virtual void RunL();
+	virtual void DoCancel();
+	virtual TInt RunError(TInt aError);
+
+public: // Functions derived from CUsbClassControllerBase
+	virtual void Start(TRequestStatus& aStatus);
+	virtual void Stop(TRequestStatus& aStatus);
+
+	virtual void GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const;
+
+protected:
+	CUsbstub3ClassController(MUsbClassControllerNotify& aOwner);
+	void ConstructL();
+
+
+
+private:
+	TInt SetUpInterface();
+
+
+	// delays in microseconds
+	TInt iStartDelay;
+	TInt iStopDelay;
+	
+	TBool iFailToStart;
+	TBool iFailToStop;
+	
+	RTimer iTimer;
+	TRequestStatus* iReportStatus;
+	RDevUsbcClient  iLdd;
+
+	
+	
+	};
+
+#endif //__CUSBstub3CLASSCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/10203284.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* 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 "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 <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x10203284;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x101fbf21;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x10203285;
+					version_no = 1;
+					display_name = "Stub1CC";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/10203286.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* 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 "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 <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x10203286;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x101fbf21;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x10203287;
+					version_no = 1;
+					display_name = "Stub2CC";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/10203288.rss	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,41 @@
+/*
+* 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 "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 <ecom/registryinfo.rh>
+
+RESOURCE REGISTRY_INFO theInfo
+	{
+	dll_uid = 0x10203288;
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			interface_uid = 0x101fbf21;
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x10203289;
+					version_no = 1;
+					display_name = "Stub3CC";
+					default_data = "";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/Stub1CCImpCollection.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 1997-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:
+* Defines the implementation collection for the ACM class controller.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32base.h>
+#include <e32std.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include "usbms_stub.h"
+
+// Define the private interface UIDs
+const TImplementationProxy UsbCCImplementationTable[] =
+    {
+	IMPLEMENTATION_PROXY_ENTRY(0x10203285, CUsbstub3ClassController::NewL),
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(UsbCCImplementationTable) / sizeof(TImplementationProxy);
+
+    return UsbCCImplementationTable;
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/Stub2CCImpCollection.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 1997-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:
+* Defines the implementation collection for the ACM class controller.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32base.h>
+#include <e32std.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include "usbms_stub.h"
+
+// Define the private interface UIDs
+const TImplementationProxy UsbCCImplementationTable[] =
+    {
+	IMPLEMENTATION_PROXY_ENTRY(0x10203287, CUsbstub3ClassController::NewL),
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(UsbCCImplementationTable) / sizeof(TImplementationProxy);
+
+    return UsbCCImplementationTable;
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/Stub3CCImpCollection.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 1997-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:
+* Defines the implementation collection for the ACM class controller.
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32base.h>
+#include <e32std.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include "usbms_stub.h"
+
+// Define the private interface UIDs
+const TImplementationProxy UsbCCImplementationTable[] =
+    {
+	IMPLEMENTATION_PROXY_ENTRY(0x10203289, CUsbstub3ClassController::NewL),
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(UsbCCImplementationTable) / sizeof(TImplementationProxy);
+
+    return UsbCCImplementationTable;
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbms_stub/src/usbms_stub.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,263 @@
+/*
+* Copyright (c) 1997-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:
+* Adheres to the UsbMan USB Class Controller API and talks to C32
+* to manage the stub3.CSY that is used to provide a virtual
+* serial port service to clients
+*
+*/
+
+/**
+ @file
+*/
+
+#include "usbms_stub.h"
+#include <usb_std.h>
+#include <es_ini.h>
+#include <d32usbc.h>
+
+#include "UsbmanInternalConstants.h"
+
+#define _USB_PANIC(CAT, CODE)	User::Panic(CAT, CODE) 
+
+// Panic category 
+_LIT( Kstub3CcPanicCategory, "UsbstubCc" );
+
+
+/**
+ * Panic codes for the USB stub3 Class Controller.
+ */
+enum Tstub3CcPanic
+	{
+	/** Class called while in an illegal state */
+	EBadApiCall = 0,
+	/** Asynchronous function called (not needed, as all requests complete synchronously) */
+	EUnusedFunction = 1,
+	/** Error reading ini file. */
+	EPanicBadIniFile = 2,		
+	/** Bad value for the iNumberOfstub3Functions member.*/
+	EPanicBadNumberOfstub3Functions = 3,
+	
+	EPanicUnexpectedStatus,
+	EPanicUnexpectedState
+
+	};
+	
+
+/**
+ * Constructs a CUsbstub3ClassController object
+ *
+ * @param	aOwner	USB Device that owns and manages the class
+ *
+ * @return	A new CUsbstub3ClassController object
+ */
+CUsbstub3ClassController* CUsbstub3ClassController::NewL(
+	MUsbClassControllerNotify& aOwner)
+	{
+	CUsbstub3ClassController* r = new (ELeave) CUsbstub3ClassController(aOwner);
+	CleanupStack::PushL(r);
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+	}
+
+/**
+ * Destructor
+ */
+CUsbstub3ClassController::~CUsbstub3ClassController()
+	{
+	Cancel();
+
+	iTimer.Close();
+
+#ifndef __WINS__	
+//	iLdd.Close();
+#endif
+
+	}
+
+
+
+/**
+ * Constructor.
+ *
+ * @param	aOwner	USB Device that owns and manages the class
+ */
+CUsbstub3ClassController::CUsbstub3ClassController(
+	MUsbClassControllerNotify& aOwner)
+	: CUsbClassControllerPlugIn(aOwner, Kstub3StartupPriority),
+	iStartDelay(Kstub3CCDefaultDelay),
+	iStopDelay(Kstub3CCDefaultDelay),
+	iFailToStart(EFalse),
+	iFailToStop(EFalse)	
+
+	{
+	iTimer.CreateLocal();
+	}
+
+
+
+/**
+ * 2nd Phase Construction.
+ */
+void CUsbstub3ClassController::ConstructL()
+	{
+	}
+
+/**
+ * Called by UsbMan when it wants to start the USB stub3 class. This always
+ * completes immediately.
+ *
+ * @param aStatus The caller's request status, filled in with an error code
+ */
+void CUsbstub3ClassController::Start(TRequestStatus& aStatus)
+	{
+
+	aStatus = KRequestPending;
+	iReportStatus = &aStatus;
+	//If we are already started then just complete the request.
+	if (iState == EUsbServiceStarted)
+		{
+		User::RequestComplete(iReportStatus, KErrNone);
+		return;
+		}
+
+	if (iFailToStart)
+		{
+		User::RequestComplete(iReportStatus, KErrGeneral);
+		return;
+		}
+	
+	iState = EUsbServiceStarting;
+
+	iTimer.After(iStatus, iStartDelay*1000);  //convert from usec to msec
+	SetActive();
+	}
+
+/**
+ * Called by UsbMan when it wants to stop the USB stub3 class.
+ *
+ * @param aStatus The caller's request status: always set to KErrNone
+ */
+void CUsbstub3ClassController::Stop(TRequestStatus& aStatus)
+	{
+
+	aStatus = KRequestPending;
+	iReportStatus = &aStatus;
+	//If we are already idle then just complete the request.
+	if (iState == EUsbServiceIdle)
+		{
+		User::RequestComplete(iReportStatus, KErrNone);
+		return;
+		}
+
+	if (iFailToStop)
+		{
+		User::RequestComplete(iReportStatus, KErrGeneral);
+		return;
+		}
+
+	iState = EUsbServiceStopping;
+
+	
+	iTimer.After(iStatus, iStopDelay*1000);  //convert from usec to msec
+	SetActive();
+	}
+
+/**
+ * Gets information about the descriptor which this class provides.
+ *
+ * @param aDescriptorInfo Descriptor info structure filled in by this function
+ */
+void CUsbstub3ClassController::GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const
+	{
+
+	aDescriptorInfo.iLength = Kstub3DescriptorLength;
+	aDescriptorInfo.iNumInterfaces = Kstub3NumberOfInterfacesPerstub3Function;
+	}
+
+
+/**
+ * Standard active object RunL. 
+ */
+void CUsbstub3ClassController::RunL()
+	{
+
+	__ASSERT_DEBUG( iStatus == KErrNone, _USB_PANIC(Kstub3CcPanicCategory, EPanicUnexpectedStatus) );
+	switch (iState)
+		{
+		case EUsbServiceStarting:
+			iState = EUsbServiceStarted;
+			break;
+		case EUsbServiceStopping:
+			iState = EUsbServiceIdle;
+			break;
+		default:	
+			_USB_PANIC(Kstub3CcPanicCategory, EPanicUnexpectedState);
+		}
+	*iReportStatus = KErrNone;	
+	User::RequestComplete(iReportStatus, iStatus.Int());	
+	}
+
+/**
+ * Standard active object cancellation function. Never called because this
+ * class has no asynchronous requests.
+ */
+void CUsbstub3ClassController::DoCancel()
+	{
+
+	if (IsActive())
+		{
+		iTimer.Cancel();	
+		}
+	switch (iState)
+	{
+		case EUsbServiceStarting:
+			iState = EUsbServiceIdle;
+			break;
+		case EUsbServiceStopping:
+			iState = EUsbServiceStarted;
+			break;
+		default:	
+			_USB_PANIC(Kstub3CcPanicCategory, EPanicUnexpectedState);
+	}
+	*iReportStatus = KErrNone;		
+	User::RequestComplete(iReportStatus, KErrCancel);	
+	}
+
+/**
+ * Standard active object error function. Never called because this class has
+ * no asynchronous requests, and hence its RunL is never called.
+ *
+ * @param aError The error code (unused)
+ * @return Always KErrNone to avoid an active scheduler panic
+ */
+TInt CUsbstub3ClassController::RunError(TInt /*aError*/)
+	{
+	__ASSERT_DEBUG( EFalse, _USB_PANIC(Kstub3CcPanicCategory, EUnusedFunction) );
+	return KErrNone;
+	}
+
+TInt CUsbstub3ClassController::SetUpInterface()
+/**
+ * Set up the interface for use. This involves finding a "Interrupt IN" 
+ * endpoint and, if found, configuring the interface.
+ */
+	{
+return 0;
+	}
+
+	
+//
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbmsapp.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,968 @@
+/*
+* 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 "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:
+* USB Mass Storage Sample Application
+*
+*/
+
+/**
+ @file
+ @publishedPartner
+*/
+
+#include "usbmsapp.h"
+
+#include <e32std.h>
+#include <e32svr.h>
+#include <e32cons.h>
+#include <f32file.h>
+#include <usbman.h>
+
+#include <d32usbc.h>
+
+#include <usbmsshared.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+_LIT(KTxtApp,"USBMSEXAMPLEAPP");
+_LIT(KMsFsy, "MSFS.FSY");
+_LIT(KMsFs, "MassStorageFileSystem");
+_LIT(KOk,"OK");
+_LIT(KError,"Error");
+_LIT(KBytesTransferredFmt, "%c:%d/%d ");
+_LIT(KErrFmt, "Property not found (%d)\r");
+_LIT8(KDefPwd,"123");
+
+//Mass Storage Device States xRef cedar/generic/base/f32/smassstorage/inc/usbmsshared.h
+_LIT(KUsbMsDriveStateDisconnected, "Disconnected");
+_LIT(KUsbMsDriveStateConnecting, "Connecting");
+_LIT(KUsbMsDriveStateConnected, "Connected");
+_LIT(KUsbMsDriveStateDisconnecting, "Disconnecting");
+_LIT(KUsbMsDriveStateActive, "Active");
+_LIT(KUsbMsDriveStateLocked, "Locked");
+_LIT(KUsbMsDriveStateMediaNotPresent, "Media Not Present");
+_LIT(KUsbMsDriveStateRemoved, "Removed");
+_LIT(KUsbMsDriveStateError, "Error");
+_LIT(KUsbMsDriveStateUnkown, "Unkown");
+
+//Usb Device States
+_LIT(KEUsbDeviceStateUndefined,"Undefined");
+_LIT(KEUsbDeviceStateDefault,"Default");
+_LIT(KEUsbDeviceStateAttached,"Attached");
+_LIT(KEUsbDeviceStatePowered,"Powered");
+_LIT(KEUsbDeviceStateConfigured,"Configured");
+_LIT(KEUsbDeviceStateAddress,"Address");
+_LIT(KEUsbDeviceStateSuspended ,"Suspended");
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+Console shared by main routine and active objects.
+*/
+LOCAL_D CConsoleBase* console = NULL;
+
+/**
+File system resource shared by main routine and active objects.
+*/
+LOCAL_D RFs fs;
+
+/**
+Currently selected drive, index into PropertyHandlers' objects.
+*/
+LOCAL_D TInt selectedDriveIndex = 0;
+
+/**
+Command line text buffer, sufficiently large so that it will
+hold any reasonable input.
+*/
+LOCAL_D TBuf<0x40> mountList;
+
+static TFixedArray<TBool, KMaxDrives>                   msfsMountedList;  ///< 'true' entry corresponds to the drive with mounted MSFS.FSY
+static TFixedArray<CFileSystemDescriptor*, KMaxDrives>  unmountedFsList;  ///< every non-NULL entry corresponds to the unmounted original FS for the drive
+
+/**
+*/
+LOCAL_D TMediaPassword  password(KDefPwd);
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+Move cursor to row 'row', column 0.
+Erase 'count' rows starting with 'row'.
+*/
+LOCAL_C void Clear(int row, int count=1)
+	{
+	_LIT(KBlank,"                                        ");
+	for(TInt i=0; i<count; i++)
+		{
+		console->SetPos(0,row+i);
+		console->Printf(KBlank);
+		}
+	console->SetPos(0,row);
+	}
+
+/**
+Display the user's drive selection.
+*/
+LOCAL_C void ShowDriveSelection()
+	{
+	Clear(15);
+	if(PropertyHandlers::allDrivesStatus.Length()/2 > selectedDriveIndex)
+		{
+		console->Printf(_L("Selected Drive: %c"),
+					'A' + PropertyHandlers::allDrivesStatus[selectedDriveIndex*2]);
+		}
+	else
+		{
+		console->Printf(_L("Selected Drive: (none)"));
+		}
+	}
+
+//-----------------------------------------------------------------------------
+/**
+    Tries to restore the original FS on the drive using the FS descriptor provided
+    @return standard error code.
+*/
+LOCAL_C TInt DoRestoreFS(RFs& aFs, TInt aDrive, CFileSystemDescriptor* apFsDesc)
+    {
+    TInt nRes;
+    RDebug::Print(_L("# DoRestoreFS drv:%d\n"), aDrive);
+    //-- 1. check that there is no FS installed   
+    TBuf<128>   fsName;
+    nRes = aFs.FileSystemName(fsName, aDrive);
+    if(nRes == KErrNone)
+        {//-- probably no file system installed at all
+        RDebug::Print(_L("# This drive already has FS intalled:%S \n"), &fsName);
+        return KErrAlreadyExists;
+        }
+        
+    TPtrC ptrN  (apFsDesc->FsName());
+    TPtrC ptrExt(apFsDesc->PrimaryExtName());
+    RDebug::Print(_L("# Mounting FS:%S, Prim ext:%S, synch:%d\n"), &ptrN, &ptrExt, apFsDesc->DriveIsSynch());
+
+    if(ptrExt.Length() >0)
+        {//-- there is a primary extension to be mounted
+        nRes = aFs.AddExtension(ptrExt);
+        if(nRes != KErrNone && nRes != KErrAlreadyExists)
+            {
+            return nRes;
+            }
+
+        nRes = aFs.MountFileSystem(ptrN, ptrExt, aDrive, apFsDesc->DriveIsSynch());
+        }
+    else
+        {
+        nRes = aFs.MountFileSystem(ptrN, aDrive, apFsDesc->DriveIsSynch());
+        }
+
+    if(nRes != KErrNone)
+        {
+        RDebug::Print(_L("# Mount failed! code:%d\n"),nRes);    
+        }
+
+    return nRes;
+    }
+
+
+//-----------------------------------------------------------------------------
+/**
+    Dismounts the originally mounted FS and optional primary extension from the drive and stores 
+    this information in the FS descriptor
+
+    @return on success returns a pointer to the instantinated FS descriptor
+*/
+LOCAL_C CFileSystemDescriptor* DoDismountOrginalFS(RFs& aFs, TInt aDrive)
+    {
+    TInt        nRes;
+    TBuf<128>   fsName;
+    TBuf<128>   primaryExtName;
+    TBool       bDrvSync = EFalse;
+
+    RDebug::Print(_L("# DoDismountOrginalFS drv:%d\n"), aDrive);
+
+    //-- 1. get file system name
+    nRes = aFs.FileSystemName(fsName, aDrive);
+    if(nRes != KErrNone)
+        {//-- probably no file system installed at all
+        return NULL;
+        }
+
+    //-- 2. find out if the drive sync/async
+    TPckgBuf<TBool> drvSyncBuf;
+    nRes = aFs.QueryVolumeInfoExt(aDrive, EIsDriveSync, drvSyncBuf);
+    if(nRes == KErrNone)
+        {
+        bDrvSync = drvSyncBuf();
+        }
+
+    //-- 3. find out primary extension name if it is present; we will need to add it againt when mounting the FS
+    //-- other extensions (non-primary) are not supported yet
+    nRes = aFs.ExtensionName(primaryExtName, aDrive, 0);
+    if(nRes != KErrNone)
+        {   
+        primaryExtName.SetLength(0);
+        }
+
+    //-- 3.1 check if the drive has non-primary extensions, fail in this case, because this FS can't be mounted back normally
+    nRes = aFs.ExtensionName(primaryExtName, aDrive, 1);
+    if(nRes == KErrNone)
+        {   
+        RDebug::Print(_L("Non-primary extensions are not supported!\n"));
+        return NULL;
+        }
+
+    RDebug::Print(_L("# DoDismountOrginalFS FS:%S, Prim ext:%S, synch:%d\n"), &fsName, &primaryExtName, bDrvSync);
+
+    //-- create FS descriptor and dismount the FS
+    CFileSystemDescriptor* pFsDesc = NULL; 
+    
+    TRAP(nRes, pFsDesc = CFileSystemDescriptor::NewL(fsName, primaryExtName, bDrvSync));
+    if(nRes != KErrNone)
+        return NULL; //-- OOM ?
+
+    nRes = aFs.DismountFileSystem(fsName, aDrive);
+    if(nRes != KErrNone)
+        {
+        delete pFsDesc;
+        pFsDesc = NULL;
+        RDebug::Print(_L("# DoDismountOrginalFS Dismounting Err:%d\n"), nRes);
+        }
+    
+    return pFsDesc;
+}
+
+/**
+Unmount FAT and mount MSFS.
+@param driveNumber
+*/
+LOCAL_C void MountMsFs(TInt driveNumber)
+	{
+	TInt x = console->WhereX();
+	TInt y = console->WhereY();
+	Clear(11,2);
+	RDebug::Print(_L("UsbMsExampleApp::MountMsFs driveNumber=%d\n"), driveNumber);
+
+	//-- 1. try dismounting the original FS
+    CFileSystemDescriptor* fsDesc = DoDismountOrginalFS(fs, driveNumber);
+    unmountedFsList[driveNumber] = fsDesc; 
+  
+    if(fsDesc)
+        {
+        TPtrC ptrN(fsDesc->FsName());
+        RDebug::Print(_L("drv:%d FS:%S Dismounted OK"),driveNumber, &ptrN);
+	   	console->Printf(_L("%S Dismount %c: %S\n"), &ptrN, 'A' + driveNumber, &KOk);
+        }
+    else
+        {
+        RDebug::Print(_L("drv:%d Dismount FS Failed!"),driveNumber);
+        }
+
+    //-- 2. try to mount the "MSFS"
+    TInt error;
+    error = fs.MountFileSystem(KMsFs, driveNumber);
+	RDebug::Print(_L("MSFS Mount:   %S (%d)"), (error?&KError:&KOk), error);
+
+	if (!error)
+		msfsMountedList[driveNumber] = ETrue;
+
+	// restore console position
+	console->Printf(_L("MSFS Mount %c:   %S (%d)"), 'A' + driveNumber, (error?&KError:&KOk), error);
+	console->SetPos(x,y);
+	}
+
+/**
+Unmount MSFS and mount FAT.
+@param driveNumber
+*/
+LOCAL_C TInt RestoreMount(TInt driveNumber)
+	{
+	TInt err = KErrNone;
+	TInt x = console->WhereX();
+	TInt y = console->WhereY();
+	Clear(11,2);
+
+    //-- 1. try dismounting the "MSFS"
+	if (msfsMountedList[driveNumber])
+		{
+		err = fs.DismountFileSystem(KMsFs, driveNumber);
+		RDebug::Print(_L("MSFS Dismount:%S (%d)"), (err?&KError:&KOk), err);
+		if (err)
+			return err;
+
+		msfsMountedList[driveNumber] = EFalse;
+		console->Printf(_L("MSFS Dismount:%S (%d)\n"), (err?&KError:&KOk), err);
+        }
+
+    //-- 2. try to mount the original FS back
+    CFileSystemDescriptor* fsDesc = unmountedFsList[driveNumber];
+    if(fsDesc)
+        {
+        err = DoRestoreFS(fs, driveNumber, fsDesc);
+
+        TPtrC ptrN(fsDesc->FsName());
+        RDebug::Print(_L("%S Mount:    %S (%d)"), &ptrN, (err?&KError:&KOk), err);      
+        delete fsDesc;
+        unmountedFsList[driveNumber] = NULL;
+       	console->Printf(_L("FAT Mount:    %S (%d)"), (err?&KError:&KOk), err);
+        }
+   
+    // restore console position
+	console->SetPos(x,y);
+	return err;
+	}
+
+/**
+Return a string description of the Drive Status
+@param DriveStatus
+@return a descriptor containing the description of the Drive Status
+ */
+LOCAL_C const TDesC& DriveStatusDescription(TInt & aDriveStatus)
+  {
+ 	switch(aDriveStatus)
+		{
+		case EUsbMsDriveState_Disconnected:
+			return KUsbMsDriveStateDisconnected;
+
+		case EUsbMsDriveState_Connecting:
+			return KUsbMsDriveStateConnecting;
+
+		case EUsbMsDriveState_Connected:
+			return KUsbMsDriveStateConnected;
+
+		case EUsbMsDriveState_Disconnecting:
+			return KUsbMsDriveStateDisconnecting;
+
+		case EUsbMsDriveState_Active:
+			return KUsbMsDriveStateActive;
+
+		case EUsbMsDriveState_Locked:
+			return KUsbMsDriveStateLocked;
+
+		case EUsbMsDriveState_MediaNotPresent:
+			return KUsbMsDriveStateMediaNotPresent;
+
+		case EUsbMsDriveState_Removed:
+			return KUsbMsDriveStateRemoved;
+
+		case EUsbMsDriveState_Error:
+			return KUsbMsDriveStateError;
+
+		default :
+			return KUsbMsDriveStateUnkown;
+
+		}
+  }
+
+/**
+Return a string description of the Usb Device State
+@param aUsbState Usb Device State
+@return the descriptor containing the device state description
+ */
+LOCAL_C const TDesC& UsbStateDescription(TUsbDeviceState& aUsbState)
+  {
+	switch(aUsbState)
+		{
+		case EUsbDeviceStateDefault:
+			return KEUsbDeviceStateDefault;
+
+		case EUsbDeviceStateAttached:
+			return KEUsbDeviceStateAttached;
+
+		case EUsbDeviceStatePowered:
+			return KEUsbDeviceStatePowered;
+
+		case EUsbDeviceStateConfigured:
+			return KEUsbDeviceStateConfigured;
+
+		case EUsbDeviceStateAddress:
+			return KEUsbDeviceStateAddress;
+
+ 		case  EUsbDeviceStateSuspended:
+			return KEUsbDeviceStateSuspended;
+
+		case EUsbDeviceStateUndefined:
+		default :
+			return KEUsbDeviceStateUndefined;
+		}
+
+  }
+
+//////////////////////////////////////////////////////////////////////////////
+
+CPropertyWatch* CPropertyWatch::NewLC(TUsbMsDriveState_Subkey aSubkey, PropertyHandlers::THandler aHandler)
+	{
+	CPropertyWatch* me=new(ELeave) CPropertyWatch(aHandler);
+	CleanupStack::PushL(me);
+	me->ConstructL(aSubkey);
+	return me;
+	}
+
+CPropertyWatch::CPropertyWatch(PropertyHandlers::THandler aHandler)
+	: CActive(0), iHandler(aHandler)
+	{}
+
+void CPropertyWatch::ConstructL(TUsbMsDriveState_Subkey aSubkey)
+	{
+	User::LeaveIfError(iProperty.Attach(KUsbMsDriveState_Category, aSubkey));
+	CActiveScheduler::Add(this);
+	// initial subscription and process current property value
+	RunL();
+	}
+
+CPropertyWatch::~CPropertyWatch()
+	{
+	Cancel();
+	iProperty.Close();
+	}
+
+void CPropertyWatch::DoCancel()
+	{
+	iProperty.Cancel();
+	}
+
+void CPropertyWatch::RunL()
+	{
+	// resubscribe before processing new value to prevent missing updates
+	iProperty.Subscribe(iStatus);
+	SetActive();
+
+	iHandler(iProperty);
+	}
+
+//////////////////////////////////////////////////////////////////////////////
+
+CUsbWatch* CUsbWatch::NewLC(RUsb& aUsb)
+	{
+	CUsbWatch* me=new(ELeave) CUsbWatch(aUsb);
+	CleanupStack::PushL(me);
+	me->ConstructL();
+	return me;
+	}
+
+CUsbWatch::CUsbWatch(RUsb& aUsb)
+	:
+	CActive(0),
+	iUsb(aUsb),
+	iUsbDeviceState(EUsbDeviceStateUndefined),
+	iIsConfigured(EFalse)
+	{}
+
+void CUsbWatch::ConstructL()
+	{
+	CActiveScheduler::Add(this);
+	RunL();
+	}
+
+CUsbWatch::~CUsbWatch()
+	{
+	Cancel();
+	}
+
+void CUsbWatch::DoCancel()
+	{
+	iUsb.DeviceStateNotificationCancel();
+	}
+
+static TBool IsDriveConnected(TInt driveStatusIndex)
+	{
+	TInt driveStatus = PropertyHandlers::allDrivesStatus[2*driveStatusIndex+1];
+	return driveStatus == EUsbMsDriveState_Connected
+		|| driveStatus >= EUsbMsDriveState_Active;
+	}
+
+static TChar DriveNumberToLetter(TInt driveNumber)
+	{
+	TChar driveLetter = '?';
+	fs.DriveToChar(driveNumber, driveLetter);
+	return driveLetter;
+	}
+
+static TBool IsDriveInMountList(TUint driveLetter)
+	{
+	TUint16 driveLetter16 = static_cast<TUint16>(driveLetter);
+	return(!mountList.Length() || KErrNotFound != mountList.Find(&driveLetter16, 1));
+	}
+
+void CUsbWatch::RunL()
+	{
+	RDebug::Print(_L("CUsbWatch DeviceStateNotification: iUsbDeviceState=%d %s"), iUsbDeviceState, &UsbStateDescription(iUsbDeviceState));
+
+	// If the cable is disconnected, unmount all the connected drives.
+	if(iIsConfigured && (iUsbDeviceState == EUsbDeviceStateUndefined))
+		{
+		for(TInt i=0; i<PropertyHandlers::allDrivesStatus.Length()/2; i++)
+			{
+			if(IsDriveConnected(i))
+				{
+				RDebug::Print(_L("CUsbWatch calling UnmountMsFs"));
+				RestoreMount(PropertyHandlers::allDrivesStatus[2*i]);
+				}
+			}
+
+		iIsConfigured = EFalse;
+		}
+
+  	if(iUsbDeviceState == EUsbDeviceStateConfigured)
+  		{
+  		iIsConfigured = ETrue;
+  		}
+
+	const TUint stateMask = 0xFF;
+	iUsb.DeviceStateNotification(stateMask, iUsbDeviceState, iStatus);
+	SetActive();
+	}
+
+//////////////////////////////////////////////////////////////////////////////
+
+TUsbMsDrivesStatus PropertyHandlers::allDrivesStatus;
+TUsbMsBytesTransferred PropertyHandlers::iKBytesRead;
+TUsbMsBytesTransferred PropertyHandlers::iKBytesWritten;
+
+/**
+Handle a publish event for the Bytes Read property.
+*/
+void PropertyHandlers::Read(RProperty& aProperty)
+	{
+	Transferred(aProperty, iKBytesRead);
+	}
+
+/**
+Handle a publish event for the Bytes Written property.
+*/
+void PropertyHandlers::Written(RProperty& aProperty)
+	{
+	Transferred(aProperty, iKBytesWritten);
+	}
+
+/**
+Helper function for Read and Written
+*/
+void PropertyHandlers::Transferred(RProperty& aProperty, TUsbMsBytesTransferred& aReadOrWritten)
+	{
+	console->SetPos(0,1);
+	console->Printf(_L("KB R/W:  "));
+	TInt err = aProperty.Get(aReadOrWritten);
+	if(err == KErrNone)
+		{
+		for(TInt i=0; i<allDrivesStatus.Length()/2; i++)
+			{
+			console->Printf(KBytesTransferredFmt,
+				static_cast<char>(DriveNumberToLetter(allDrivesStatus[2*i])), iKBytesRead[i], iKBytesWritten[i]);
+			}
+		}
+	else
+		{
+		console->Printf(KErrFmt, err);
+		}
+	}
+
+/**
+Handle a publish event for the Drive Status property.
+*/
+void PropertyHandlers::DriveStatus(RProperty& aProperty)
+	{
+	RDebug::Print(_L(">> PropertyHandlers::DriveStatus"));
+	TInt err = aProperty.Get(allDrivesStatus);
+	console->SetPos(0,0);
+	if(err == KErrNone)
+		{
+		TInt numDrives = allDrivesStatus.Length()/2;
+		console->Printf(_L("Status:  "));
+		for(TInt i=0; i<numDrives; i++)
+			{
+			TInt driveNumber = allDrivesStatus[2*i];
+			TInt driveStatus = allDrivesStatus[2*i+1];
+			TChar driveLetter = DriveNumberToLetter(driveNumber);
+
+
+			RDebug::Print(_L("PropertyHandlers::DriveStatus: drive %c: = %d %S"),
+						static_cast<char>(driveLetter), driveStatus, &DriveStatusDescription(driveStatus));
+			console->Printf(_L("%c:%d %S          "), static_cast<char>(driveLetter), driveStatus, &DriveStatusDescription(driveStatus));
+
+			if(IsDriveInMountList(driveLetter))
+				{
+				if(driveStatus == EUsbMsDriveState_Connecting)
+					{
+					MountMsFs(driveNumber);
+					}
+				else if(driveStatus == EUsbMsDriveState_Disconnected)
+					{
+					RestoreMount(driveNumber);
+					}
+				else
+					{
+					RDebug::Print(_L("PropertyHandlers::DriveStatus: nothing to do"));
+					}
+				}
+			else
+				{
+				RDebug::Print(_L("PropertyHandlers::DriveStatus: %c: is not in mountList\n"),
+				(TUint) driveLetter);
+				}
+			}
+		}
+	else
+		{
+		console->Printf(KErrFmt, err);
+		}
+
+	RDebug::Print(_L("<< PropertyHandlers::DriveStatus"));
+	}
+
+//////////////////////////////////////////////////////////////////////////////
+
+CMessageKeyProcessor::CMessageKeyProcessor(CConsoleBase* aConsole)
+	: CActive(CActive::EPriorityUserInput), iConsole(aConsole)
+	{
+	}
+
+CMessageKeyProcessor* CMessageKeyProcessor::NewLC(CConsoleBase* aConsole
+												 )
+	{
+	CMessageKeyProcessor* self=new (ELeave) CMessageKeyProcessor(aConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+CMessageKeyProcessor* CMessageKeyProcessor::NewL(CConsoleBase* aConsole
+												)
+	{
+	CMessageKeyProcessor* self = NewLC(aConsole);
+	CleanupStack::Pop();
+	return self;
+	}
+
+void CMessageKeyProcessor::ConstructL()
+	{
+	// Add to active scheduler
+	CActiveScheduler::Add(this);
+	RequestCharacter();
+	}
+
+
+CMessageKeyProcessor::~CMessageKeyProcessor()
+	{
+	// Make sure we're cancelled
+	Cancel();
+	}
+
+void  CMessageKeyProcessor::DoCancel()
+	{
+	iConsole->ReadCancel();
+	}
+
+void  CMessageKeyProcessor::RunL()
+	{
+	  // Handle completed request
+	ProcessKeyPress(TChar(iConsole->KeyCode()));
+	}
+
+void CMessageKeyProcessor::RequestCharacter()
+	{
+	  // A request is issued to the CConsoleBase to accept a
+	  // character from the keyboard.
+	iConsole->Read(iStatus);
+	SetActive();
+	}
+
+void CMessageKeyProcessor::ProcessKeyPress(TChar aChar)
+	{
+	TInt error = KErrNone;
+
+	aChar.UpperCase();
+	switch(aChar)
+		{
+		case 'Q':
+		case EKeyEscape:
+			for(TInt j=0; j<KMaxDrives; j++)
+				{
+				error = RestoreMount(j);
+				if (error)
+					{
+					// Mount is busy/locked and can not be restored.
+					break;
+					}
+				}
+			CActiveScheduler::Stop();
+			return;
+
+		case 'D':
+			if(++selectedDriveIndex >= PropertyHandlers::allDrivesStatus.Length()/2)
+				{
+				selectedDriveIndex = 0;
+				}
+			ShowDriveSelection();
+			break;
+
+		case 'M':
+			if(PropertyHandlers::allDrivesStatus.Length())
+				{
+				MountMsFs(PropertyHandlers::allDrivesStatus[selectedDriveIndex*2]);
+				}
+			break;
+
+		case 'U':
+			if(PropertyHandlers::allDrivesStatus.Length())
+				{
+				RestoreMount(PropertyHandlers::allDrivesStatus[selectedDriveIndex*2]);
+				}
+			break;
+
+		case 'L':
+			{
+			_LIT(KEmpty, "");
+			TMediaPassword nul;
+			nul.Copy(KEmpty);
+			error = fs.LockDrive(PropertyHandlers::allDrivesStatus[selectedDriveIndex*2],
+				nul, password, ETrue);
+			console->SetPos(0,9);
+			console->Printf(_L("LockDrive %S (%d)"), (error?&KError:&KOk), error);
+			break;
+			}
+
+		case 'N':
+			error = fs.UnlockDrive(PropertyHandlers::allDrivesStatus[selectedDriveIndex*2],
+				password, ETrue);
+			Clear(9);
+			console->Printf(_L("UnlockDrive %S (%d)"), (error?&KError:&KOk), error);
+			break;
+
+		case 'C':
+			error = fs.ClearPassword(PropertyHandlers::allDrivesStatus[selectedDriveIndex*2],
+				password);
+			Clear(9);
+			console->Printf(_L("ClearPassword %S (%d)"), (error?&KError:&KOk), error);
+			break;
+		}
+	RequestCharacter();
+	}
+
+
+//-----------------------------------------------------------------------------
+
+CFileSystemDescriptor::~CFileSystemDescriptor()
+    {
+    iFsName.Close();
+    iPrimaryExtName.Close();
+    }
+
+//-----------------------------------------------------------------------------
+CFileSystemDescriptor* CFileSystemDescriptor::NewL(const TDesC& aFsName, const TDesC& aPrimaryExtName, TBool aDrvSynch)
+    {
+    CFileSystemDescriptor* pSelf = new (ELeave) CFileSystemDescriptor;
+
+    CleanupStack::PushL(pSelf);
+    
+    pSelf->iFsName.CreateMaxL(aFsName.Length());
+    pSelf->iFsName.Copy(aFsName);
+    
+    pSelf->iPrimaryExtName.CreateMaxL(aPrimaryExtName.Length());
+    pSelf->iPrimaryExtName.Copy(aPrimaryExtName);
+
+    pSelf->iDriveSynch = aDrvSynch;
+
+    CleanupStack::Pop();
+
+    return pSelf;
+    }
+
+
+
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+Initialize mass storage. Enter Active Scheduler. Shutdown mass storage.
+*/
+LOCAL_C void RunAppL()
+	{
+    TInt error = KErrUnknown;
+	TRequestStatus status;
+
+	PropertyHandlers::allDrivesStatus.Fill(0);
+
+	RDebug::Print(_L("USBMSEXAMPLEAPP: Creating console\n"));
+	console = Console::NewL(KTxtApp,TSize(KConsFullScreen,KConsFullScreen));
+	CleanupStack::PushL(console);
+
+	console->SetPos(0,2);
+	console->Printf(_L("========================================"));
+
+	RDebug::Print(_L("USBMSEXAMPLEAPP: Getting CommandLine\n"));
+	// Command line: list of drive letters to auto-mount (all if not specified)
+	User::CommandLine(mountList);
+	mountList.UpperCase();
+
+	RDebug::Print(_L("USBMSEXAMPLEAPP: Creating CActiveScheduler\n"));
+	CActiveScheduler* sched = new(ELeave) CActiveScheduler;
+	CleanupStack::PushL(sched);
+	CActiveScheduler::Install(sched);
+
+	RDebug::Print(_L("USBMSEXAMPLEAPP: Connecting to file system\n"));
+	User::LeaveIfError(fs.Connect());
+	CleanupClosePushL(fs);
+
+	_LIT(KMountAllDefault,"(all)");
+	console->SetPos(0,3);
+	console->Printf(_L("Drives to auto-mount: %S"),
+		(mountList.Length() ? &mountList : &KMountAllDefault));
+
+#if defined(__WINS__)
+	_LIT(KDriverFileName,"TESTUSBC.LDD");
+	error = User::LoadLogicalDevice(KDriverFileName);
+	console->SetPos(0,4);
+	console->Printf(_L("Load %S: %S (%d)"),
+				&KDriverFileName, (error?&KError:&KOk), error);
+#endif
+
+	console->SetPos(0,5);
+	RDebug::Print(_L("USBMSEXAMPLEAPP: Add MS file system\n"));
+	// Add MS file system
+	error = fs.AddFileSystem(KMsFsy);
+	console->Printf(_L("Add MS File System: %S (%d)"),
+				(error?&KError:&KOk), error);
+
+	RUsb usb;
+	error = usb.Connect();
+	User::LeaveIfError(error);
+	CleanupClosePushL(usb);
+
+	console->SetPos(0,6);
+	RDebug::Print(_L("USBMSEXAMPLEAPP: Find the class controller\n"));
+
+    // Find the personality that supports the massstorage uid
+	TInt personalityId=-1;
+	RArray<TInt> personalityIds;
+	usb.GetPersonalityIds(personalityIds);
+	for (TInt i=0; i < personalityIds.Count(); i++)
+	    {
+    	TBool supported=EFalse;
+        User::LeaveIfError(usb.ClassSupported(personalityIds[i], KUsbMsClassControllerUID, supported));
+
+        HBufC* localizedPersonalityDescriptor;
+        User::LeaveIfError(usb.GetDescription(personalityIds[i],localizedPersonalityDescriptor));
+        console->Printf(_L("USB Personality id=%d - '%S' %s\n"),
+        	personalityIds[i], localizedPersonalityDescriptor,
+        	supported?_S("*"):_S(""));
+
+        if(supported)
+        	{
+        	personalityId = personalityIds[i];
+        	}
+        delete localizedPersonalityDescriptor;
+		}
+	personalityIds.Close();
+
+	if(personalityId != -1)
+		{
+		RDebug::Print(_L("USBMSEXAMPLEAPP: Start USB\n"));
+		usb.TryStart(personalityId, status);
+		User::WaitForRequest(status);
+		if(status.Int() != KErrNone)
+			{
+			console->Printf(_L("USB Service failed to start (%d)"), status.Int());
+			}
+		else
+			{
+			TUsbServiceState currentState;
+			User::LeaveIfError(usb.GetServiceState(currentState));
+			if(EUsbServiceStarted != currentState)
+				{
+				console->Printf(_L("USB Service failed to enter EUsbServiceStarted"));
+				User::Leave(KErrUnknown);
+				}
+			console->Printf(_L("USB Service Started, personality id=%d"), personalityId);
+			}
+		}
+	else
+		{
+		console->Printf(_L("USBMS class controller not found"));
+		}
+
+    console->SetPos(0,14);
+    TBuf16<8> lpwd;
+    lpwd.Copy(password);
+    console->Printf(_L("Password: %S"), &lpwd);
+
+    RDebug::Print(_L("USBMSEXAMPLEAPP: Create active objects\n"));
+
+	CMessageKeyProcessor::NewLC(console);
+	CPropertyWatch::NewLC(EUsbMsDriveState_KBytesRead, PropertyHandlers::Read);
+	CPropertyWatch::NewLC(EUsbMsDriveState_KBytesWritten, PropertyHandlers::Written);
+	CPropertyWatch::NewLC(EUsbMsDriveState_DriveStatus, PropertyHandlers::DriveStatus);
+	CUsbWatch::NewLC(usb);
+
+	ShowDriveSelection();
+
+	console->SetPos(0,16);
+	_LIT(KMsgTitleB,"Menu: q=quit d=chg drv m=mount u=unmount\n      l=lock n=unlock c=clr pwd");
+	console->Printf(KMsgTitleB);
+
+	RDebug::Print(_L("USBMSEXAMPLEAPP: Start CActiveScheduler\n"));
+	CActiveScheduler::Start();
+
+	RDebug::Print(_L("Shutting down. Unmounting all mounted drives\n"));
+
+	for(TInt j=0; j<PropertyHandlers::allDrivesStatus.Length()/2; j++)
+		{
+		if(IsDriveConnected(j))
+			{
+			RestoreMount(PropertyHandlers::allDrivesStatus[2*j]);
+			}
+		}
+
+	usb.TryStop(status);
+	User::WaitForRequest(status);
+	RDebug::Print(_L("USB TryStop returned %d\n"), status.Int());
+
+	error = fs.RemoveFileSystem(KMsFs);
+	RDebug::Print(_L("RemoveFileSystem returned %d\n"), error);
+
+#if defined(__WINS__)
+	error = User::FreeLogicalDevice(KDriverFileName);
+	RDebug::Print(_L("FreeLogicalDevice returned %d\n"), error);
+#endif
+
+	CleanupStack::PopAndDestroy();	// CUsbWatch
+	CleanupStack::PopAndDestroy();	// CPropertyWatch
+	CleanupStack::PopAndDestroy();	// CPropertyWatch
+	CleanupStack::PopAndDestroy();	// CPropertyWatch
+	CleanupStack::PopAndDestroy();	// CMessageKeyProcessor
+	CleanupStack::PopAndDestroy(&usb);
+	CleanupStack::PopAndDestroy(&fs);
+	CleanupStack::PopAndDestroy(sched);
+	CleanupStack::PopAndDestroy(console);
+	}
+
+
+/**
+Application entry point.
+*/
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup=CTrapCleanup::New();
+
+	TRAPD(error,RunAppL());
+	__ASSERT_ALWAYS(!error, User::Panic(KTxtApp, error));
+
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return 0;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbmsapp.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,145 @@
+/*
+* 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 "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 <e32base.h>
+#include <e32property.h>		// RProperty
+#include <usbman.h>
+
+#include "usbmsshared.h"		// TUsbMsBytesTransferred
+
+/**
+    Class describing a file system mounted on the drive.
+    It has a limitation: full list of possible FS extensions is not supported, only the primary one.
+*/
+NONSHARABLE_CLASS(CFileSystemDescriptor) : public CBase
+    {
+ public:
+    ~CFileSystemDescriptor();    
+    static CFileSystemDescriptor* NewL(const TDesC& aFsName, const TDesC& aPrimaryExtName, TBool aDrvSynch);
+
+    TPtrC FsName() const            {return iFsName;}
+    TPtrC PrimaryExtName() const    {return iPrimaryExtName;}
+    TBool DriveIsSynch() const      {return iDriveSynch;}
+
+
+ private:
+    CFileSystemDescriptor() {}
+ 
+ private:   
+    RBuf    iFsName;        ///< file system name
+    RBuf    iPrimaryExtName;///< name of the primary extension if present. Empty otherwise
+    TBool   iDriveSynch;    ///< ETrue if the drive is synchronous
+    };
+
+
+    
+/**
+A set of static objects that hold the latest properties published by Mass Storage,
+and a set of corresponding static functions that process the publish events. 
+The functions are passed by pointer to, and invoked by, CPropertyWatch instances.
+*/
+NONSHARABLE_CLASS(PropertyHandlers) {
+public:
+	/** The prototype for all public property handler functions */
+	typedef void(*THandler)(RProperty&);
+
+public:
+	static void Read(RProperty& aProperty);
+	static void Written(RProperty& aProperty);
+	static void DriveStatus(RProperty& aProperty);
+private:
+	static void Transferred(RProperty& aProperty, TUsbMsBytesTransferred& aReadOrWritten);
+
+public:
+	static TBuf8<16> allDrivesStatus;
+	static TUsbMsBytesTransferred iKBytesRead;
+	static TUsbMsBytesTransferred iKBytesWritten;
+	};
+
+/**
+An active object that subscribes to a specified Mass Storage property and
+calls a provided handler each time the property is published.
+*/
+NONSHARABLE_CLASS(CPropertyWatch) : public CActive
+	{
+public:
+	static CPropertyWatch* NewLC(TUsbMsDriveState_Subkey aSubkey, PropertyHandlers::THandler aHandler);
+private:
+	CPropertyWatch(PropertyHandlers::THandler aHandler);
+	void ConstructL(TUsbMsDriveState_Subkey aSubkey);
+	~CPropertyWatch();
+	void RunL();
+	void DoCancel();
+	
+	RProperty iProperty;
+	PropertyHandlers::THandler iHandler;
+	};
+
+/**
+An active object that handles changes to the KUsbMsDriveState properties.
+*/
+NONSHARABLE_CLASS(CUsbWatch) : public CActive
+	{
+public:
+	static CUsbWatch* NewLC(RUsb& aUsb);
+private:
+	CUsbWatch(RUsb& aUsb);
+	void ConstructL();
+	~CUsbWatch();
+	void RunL();
+	void DoCancel();
+
+private:
+	RUsb& iUsb;
+	TUsbDeviceState iUsbDeviceState;
+	TBool iIsConfigured;
+	};
+
+/**
+An active object for handling user menu selections.
+*/
+NONSHARABLE_CLASS(CMessageKeyProcessor) : public CActive
+	{
+public:
+	static CMessageKeyProcessor* NewLC(CConsoleBase* aConsole);
+	static CMessageKeyProcessor* NewL(CConsoleBase* aConsole);
+	~CMessageKeyProcessor();
+
+public:
+	  // Issue request
+	void RequestCharacter();
+	  // Cancel request.
+	  // Defined as pure virtual by CActive;
+	  // implementation provided by this class.
+	void DoCancel();
+	  // Service completed request.
+	  // Defined as pure virtual by CActive;
+	  // implementation provided by this class,
+	void RunL();
+	  // Called from RunL() to handle the completed request
+	void ProcessKeyPress(TChar aChar); 
+
+private:
+	CMessageKeyProcessor(CConsoleBase* aConsole);
+	void ConstructL();
+
+private:
+	CConsoleBase* iConsole; // A console for reading from
+	};
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbmsapp/usbmsapp.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,25 @@
+/*
+* 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 "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:
+*
+*/
+
+TARGET         	usbmsexampleapp.exe
+TARGETTYPE     	EXE
+SOURCEPATH		.
+SOURCE 	       	usbmsapp.cpp
+	
+LIBRARY			efsrv.lib euser.lib usbman.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+CAPABILITY 	All -Tcb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbtestconsole/bld.inf	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,26 @@
+/*
+* 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 "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:
+*
+*/
+
+#if defined(SYMBIAN_ENABLE_USB_OTG_HOST)
+
+PRJ_TESTEXPORTS
+usbtestconsole.oby /epoc32/rom/include/usbtestconsole.oby
+
+PRJ_TESTMMPFILES
+usbtestconsole
+
+#endif // SYMBIAN_ENABLE_USB_OTG_HOST
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbtestconsole/usbtestconsole.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,2192 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#include "usbtestconsole.h"
+
+#include <e32cons.h>
+#include <e32debug.h>
+
+#include <d32otgdi_errors.h>
+#include <d32usbdi_errors.h>
+#include <d32usbdi.h>
+
+#include <usb/usbshared.h>
+
+static TBool verbose = EFalse;
+
+const TUint KTimerAWaitBConnect = 30*1000000;  
+
+#define PANIC Panic(__LINE__)
+
+#define LOG(A,B) if (verbose) RDebug::Print(_L("UsbTestConsole: " L##A),B)
+
+#define PNT(A)	 if (verbose) RDebug::Print(_L("UsbTestConsole: " L##A))
+
+void Panic(TInt aLine)
+	{
+	if (verbose) RDebug::Printf("UsbTestConsole: PANIC line=%d", aLine);
+	User::Panic(_L("USBTESTCONSOLE"), aLine);
+	}
+
+_LIT(KArgVerbose, "VERBOSE");
+
+void RunConsoleL()
+	{
+	TInt cmdLineLength(User::CommandLineLength());
+	HBufC* cmdLine = HBufC::NewMaxLC(cmdLineLength);
+	TPtr cmdLinePtr = cmdLine->Des();
+	User::CommandLine(cmdLinePtr);
+
+	TLex args(*cmdLine);
+	args.SkipSpace(); // args are separated by spaces
+	
+	// first arg is the exe name, skip it
+	TPtrC cmdToken = args.NextToken();
+	HBufC* tc = HBufC::NewLC(80);
+	*tc = cmdToken;
+	
+	while (tc->Length())
+		{
+		TInt pos = tc->FindF(KArgVerbose);
+		
+		if ( pos != KErrNotFound )
+			{ 
+			verbose = ETrue;
+			}
+		
+		// next parameter
+		*tc = args.NextToken();
+		}
+	CleanupStack::PopAndDestroy(tc);
+	CleanupStack::PopAndDestroy(cmdLine);
+
+	CUsbTestConsole* console = CUsbTestConsole::NewLC();
+	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;
+	}
+
+XUsbTestConsoleEvent::~XUsbTestConsoleEvent()
+	{
+	iLink.Deque();
+	iEvent.Close();
+	}
+	
+	
+	
+	
+CUsbTestConsoleKeys* CUsbTestConsoleKeys::NewL(CUsbTestConsole& aTestConsole)
+	{
+	CUsbTestConsoleKeys* self = new(ELeave) CUsbTestConsoleKeys(aTestConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CUsbTestConsoleKeys::~CUsbTestConsoleKeys()
+	{
+	Cancel();
+
+	TDblQueIter<CUsbTestConsoleTextEntryBase> iter(iEntryConsoles);
+	CUsbTestConsoleTextEntryBase* event = NULL;
+	while((event = iter++) != NULL)
+		{
+		delete event;
+		}
+		
+	delete iUsbManStarter;
+	delete iUsbManStoper;
+	delete iUsbManTryStarter;
+	delete iUsbManTryStoper;
+	}
+
+CUsbTestConsoleKeys::CUsbTestConsoleKeys(CUsbTestConsole& aTestConsole)
+	: CActive(EPriorityStandard)
+	, iTestConsole(aTestConsole)
+	, iEntryConsoles(_FOFF(CUsbTestConsoleTextEntryBase, iLink))
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUsbTestConsoleKeys::ConstructL()
+	{
+	iTestConsole.iConsole->Read(iStatus);
+	SetActive();
+	}
+
+void CUsbTestConsoleKeys::DoCancel()
+	{
+	iTestConsole.iConsole->ReadCancel();
+	}
+
+void CUsbTestConsoleKeys::RunL()
+	{
+	User::LeaveIfError(iStatus.Int());
+	
+	switch(iTestConsole.iConsole->KeyCode())
+		{
+	case '[':
+		{
+		RUsb sess;
+		TInt err = sess.Connect();
+		sess.Close();
+		
+		User::After(4000000);
+		
+		err = sess.Connect(); 
+
+		XUsbTestConsoleEvent* event = NewConsoleEventL();
+		event->iEvent.AppendFormat(_L("T:USBMAN Test Err[%d]"), err);
+		iTestConsole.NotifyEvent(event);
+		
+		sess.Close();
+		}
+		break;
+	case 'm':
+		{
+		TInt val = 1;
+		TInt err = RProperty::Set(KUidUsbManCategory,KUsbRequestSessionProperty,val);
+		XUsbTestConsoleEvent* event = NewConsoleEventL();
+		event->iEvent.AppendFormat(_L("T:USBMAN VBus marshalling - err=[%d]"),err);
+		iTestConsole.NotifyEvent(event);
+		}
+		break;
+	case 'H': case 'h': case '?': 
+
+		iTestConsole.ScheduleDraw('H');
+		break;
+
+	case 'q': case 'Q':
+		iTestConsole.Stop();
+		return;
+		
+	case 's':
+		// Toggle Start
+		if(!iUsbManStarter)
+			{
+			CUsbManStarter::NewL(iUsbManStarter, iTestConsole);
+			}
+		else
+			{
+			iUsbManStarter->DestroyL();
+			}
+		break;
+		
+	case 'S':
+		// Toggle Stop
+		if(!iUsbManStoper)
+			{
+			// Because we cannot tell query the actual state of Function Driver loading
+			// when we shutdown we also automatically disable loading.
+			iTestConsole.Usb().DisableFunctionDriverLoading();
+			iFunctionDriverLoading = EFalse;
+			iTestConsole.SetDriverLoading(CUsbTestConsole::EDisabled);
+
+			CUsbManStoper::NewL(iUsbManStoper, iTestConsole);
+			}
+		else
+			{
+			iUsbManStoper->DestroyL();
+			}
+		break;
+		
+	case 't':
+		// Toggle TryStart
+		if(!iUsbManTryStarter)
+			{
+			CUsbManTryStarter::NewL(iUsbManTryStarter, iTestConsole, iPersonalityId);
+			}
+		else
+			{
+			iUsbManTryStarter->DestroyL();
+			}
+		break;
+
+	case 'T':
+		// Toggle TryStop
+		if(!iUsbManTryStoper)
+			{
+			// Because we cannot tell query the actual state of Function Driver loading
+			// when we shutdown we also automatically disable loading.
+			iTestConsole.Usb().DisableFunctionDriverLoading();
+			iFunctionDriverLoading = EFalse;
+			iTestConsole.SetDriverLoading(CUsbTestConsole::EDisabled);
+
+			CUsbManTryStoper::NewL(iUsbManTryStoper, iTestConsole);
+			}
+		else
+			{
+			iUsbManTryStoper->DestroyL();
+			}
+		break;
+		
+	case 'p': case 'P':
+		// Enter personality id
+			{
+			CUsbTestConsoleTextEntryBase* entry = CUsbTestConsoleTextEntry<TInt>::NewL(iPersonalityId, _L("Personality Id"));
+			iEntryConsoles.AddLast(*entry);
+			}
+		break;
+		
+	case 'c': case 'C':
+		// Toggle Control Session
+			{
+			iControlSession = !iControlSession;
+			TInt err = iTestConsole.Usb().SetCtlSessionMode(iControlSession);
+			if(err != KErrNone)
+				{
+				iControlSession = !iControlSession;
+				}
+			else
+				{
+				iTestConsole.SetControlSession(iControlSession);
+				if(!iControlSession)
+					{
+					// This is set to unknown because as soon as we relinquish the controlling session
+					// someone else could be altering the state.
+					iFunctionDriverLoading = EFalse;
+                    iTestConsole.SetDriverLoading(CUsbTestConsole::EUnknown);
+					}
+				}
+			XUsbTestConsoleEvent* event = NewConsoleEventL();
+			event->iEvent.AppendFormat(_L("G:SetControlSession:Err[%d]"), err);
+			iTestConsole.NotifyEvent(event);
+			}
+		break;
+
+	case 'b':
+		// Bus Request
+			{
+			TInt err = iTestConsole.Usb().BusRequest();
+			XUsbTestConsoleEvent* event = NewConsoleEventL();
+			event->iEvent.AppendFormat(_L("G:BusRequest:Err[%d]"), err);
+			iTestConsole.NotifyEvent(event);
+			}
+		break;
+
+	case 'r':
+	    // Respond to SRP
+			{
+			TInt err = iTestConsole.Usb().BusRespondSrp();
+			XUsbTestConsoleEvent* event = NewConsoleEventL();
+			event->iEvent.AppendFormat(_L("G:BusRespondSrp:Err[%d]"), err);
+			iTestConsole.NotifyEvent(event);
+			}
+			break;
+
+	case 'R':
+		// Auto-respond to SRP
+			{
+			iTestConsole.SetAutoSrpResponseState( !iTestConsole.GetAutoSrpResponseState() );
+			XUsbTestConsoleEvent* event = NewConsoleEventL();
+			event->iEvent.AppendFormat(_L("G:Auto-Respond to SRP (%d)"), iTestConsole.GetAutoSrpResponseState());
+			iTestConsole.NotifyEvent(event);
+			}
+			break;
+			
+	case 'x': case 'X':
+	    // Clear Bus Error State
+			{
+			TInt err = iTestConsole.Usb().BusClearError();
+			XUsbTestConsoleEvent* event = NewConsoleEventL();
+			event->iEvent.AppendFormat(_L("G:BusClearError:Err[%d]"), err);
+			iTestConsole.NotifyEvent(event);
+			}
+			break;
+
+	case 'B':
+		// Bus Drop
+			{
+			TInt err = iTestConsole.Usb().BusDrop();
+			XUsbTestConsoleEvent* event = NewConsoleEventL();
+			event->iEvent.AppendFormat(_L("G:BusDrop:Err[%d]"), err);
+			iTestConsole.NotifyEvent(event);
+			}
+		break;
+		
+	case 'e': case 'E':
+			{
+			TBool functionDriverLoading = !iFunctionDriverLoading;
+			CUsbTestConsole::TFdfDriverLoadingState state = functionDriverLoading ? CUsbTestConsole::EEnabled : CUsbTestConsole::EDisabled;
+			TInt err = KErrNone;
+			if(functionDriverLoading)
+				{
+				err = iTestConsole.Usb().EnableFunctionDriverLoading();
+				}
+			else
+				{
+				iTestConsole.Usb().DisableFunctionDriverLoading();
+				}
+
+			if(err == KErrNone)
+				{
+				iFunctionDriverLoading = functionDriverLoading;
+				iTestConsole.SetDriverLoading(state);
+				}
+			XUsbTestConsoleEvent* event = NewConsoleEventL();
+			event->iEvent.AppendFormat(_L("H:FunctionDriverLoading[%d] Err[%d]"), functionDriverLoading, err);
+			iTestConsole.NotifyEvent(event);
+			}
+		break;
+
+		case 'A': case 'a': 
+			{
+			XUsbTestConsoleEvent* event = NewConsoleEventL();
+			switch( iTestConsole.iDeviceType )
+				{
+				case CUsbTestConsole::ELogitechHeadset:
+					{
+												// 12345678901234567890123456789012345678901234567890123
+					event->iEvent.AppendFormat(_L("G:Audio will play OK on this Logitech headset"));
+					}
+					break;
+				case CUsbTestConsole::EGenericDevice:
+					{
+												// 12345678901234567890123456789012345678901234567890123
+					event->iEvent.AppendFormat(_L("G:Audio on this device is not supported"));
+					}
+					break;
+				case CUsbTestConsole::ENoDevice:
+					{
+												// 12345678901234567890123456789012345678901234567890123
+					event->iEvent.AppendFormat(_L("G:There is no device connected!"));
+					}
+					break;
+				}
+			iTestConsole.NotifyEvent(event);
+			}
+		break;
+		
+	case 'v': case 'V':
+		{
+		TBool oldVerbose = verbose;
+		
+		verbose = ETrue;
+		
+		if (oldVerbose)
+			{
+			PNT("Switching Logging Off");
+			}
+		else
+			{
+			PNT("Switching Logging On");
+			}
+		
+		verbose = !oldVerbose;
+
+		break;
+		}
+		
+	default:
+		// Unrecognised key
+		XUsbTestConsoleEvent* event = NewConsoleEventL();
+		event->iEvent.AppendFormat(_L("G:Unknown:Key[%c]"), iTestConsole.iConsole->KeyCode());
+		iTestConsole.NotifyEvent(event);
+		break;
+		}
+	iTestConsole.iConsole->Read(iStatus);
+	SetActive();
+	}
+	
+XUsbTestConsoleEvent* CUsbTestConsoleKeys::NewConsoleEventL()
+	{
+	XUsbTestConsoleEvent* event = new(ELeave) XUsbTestConsoleEvent;
+	CleanupStack::PushL(event);
+	User::LeaveIfError(event->iEvent.Create(CUsbTestConsole::KNumCharactersOnLine-1));
+	CleanupStack::Pop();
+	return event;
+	}
+	
+
+
+CUsbTestConsole* CUsbTestConsole::NewLC()
+	{
+	CUsbTestConsole* self = new(ELeave) CUsbTestConsole;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+	
+CUsbTestConsole::~CUsbTestConsole()
+	{
+	PNT("Closing Console");
+
+	delete iKeys;
+
+	TDblQueIter<XUsbTestConsoleEvent> iter(iEventList);
+	XUsbTestConsoleEvent* event = NULL;
+	while((event = iter++) != NULL)
+		{
+		delete event;
+		}
+
+	delete iMessageWatcher;
+	delete iHostEventWatcher;
+	delete iOtgStateWatcher;
+	delete iVBusWatcher;
+	delete iIdPinWatcher;
+	delete iDeviceStateWatcher;
+	delete iServiceStateWatcher;
+	delete iTimer;  
+
+	Cancel();
+
+	PNT("Closing USB Session");
+
+	iUsb.Close();
+	
+	delete iConsole;
+	}
+
+CUsbTestConsole::CUsbTestConsole()
+	: CActive(EPriorityLow) // Low so all notifications that want to be serviced will be done first
+	, iHelp(EFalse)
+	, iAutoSrpResponse(EFalse)
+	, iDeviceType(ENoDevice)
+	, iEventList(_FOFF(XUsbTestConsoleEvent, iLink))
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUsbTestConsole::ConstructL()
+	{
+	iConsole = Console::NewL(KUsbTestConsoleTitle, TSize(-1,-1));
+	User::LeaveIfError(iUsb.Connect());
+	
+	for(TInt i=0; i<KNumEventsOnScreen; ++i)
+		{
+        XUsbTestConsoleEvent* nullEvent = new(ELeave) XUsbTestConsoleEvent;
+		iEventList.AddFirst(*nullEvent);
+		}
+
+	iServiceStateWatcher = CServiceStateWatcher::NewL(*this);
+	iDeviceStateWatcher = CDeviceStateWatcher::NewL(*this);
+	iIdPinWatcher = CIdPinWatcher::NewL(*this);
+	iVBusWatcher = CVBusWatcher::NewL(*this);
+    iConnectionIdleWatcher = CConnectionIdleWatcher::NewL(*this);
+	iOtgStateWatcher = COtgStateWatcher::NewL(*this);
+	iHostEventWatcher = CHostEventWatcher::NewL(*this);
+	iMessageWatcher = CMessageWatcher::NewL(*this);
+	iTimer = CUsbTestTimer::NewL(*this);  
+	SetDriverLoading(EUnknown);
+	SetDeviceType(ENoDevice);
+	SetAutoSrpResponseState(EFalse);
+
+	// After everything else, enable interactivity.
+	iKeys = CUsbTestConsoleKeys::NewL(*this);
+	}
+CUsbTestTimer* CUsbTestConsole::Timer() const
+	{
+	return iTimer;
+	}
+
+
+void CUsbTestConsole::StartL()
+	{
+	// Get everything running
+	CActiveScheduler::Start();
+	}
+	
+void CUsbTestConsole::Stop() const
+	{
+	CActiveScheduler::Stop();
+	}
+
+void CUsbTestConsole::DoCancel()
+	{
+	// Don't need to do anything as the AO is completed straight away.
+	}
+
+void CUsbTestConsole::RunL()
+	{
+	__ASSERT_ALWAYS(iStatus.Int() == KErrNone, PANIC);
+	Draw();
+	}
+
+void CUsbTestConsole::ScheduleDraw(TUint aKey)
+	{
+	if(!IsActive())
+		{
+		iHelp = (aKey=='H') ? !iHelp : EFalse;
+		SetActive();
+		TRequestStatus* status = &iStatus;
+		User::RequestComplete(status, KErrNone);
+
+		TSize size = iConsole->ScreenSize();
+		iConsole->SetCursorPosAbs(TPoint(size.iWidth-1, 0));
+		iConsole->Write(_L("*"));
+		}
+	}
+	
+RUsb& CUsbTestConsole::Usb()
+	{
+	return iUsb;
+	}
+	
+void CUsbTestConsole::SetServiceState(TUsbServiceState aServiceState)
+	{
+	switch(aServiceState)
+		{
+    case EUsbServiceIdle:
+    	iServStatus =
+    		//  12345678901
+			_L("Idle       ");
+    	break;
+
+	case EUsbServiceStarting:
+    	iServStatus =
+    		//  12345678901
+			_L("Starting   ");
+		break;
+
+	case EUsbServiceStarted:
+	    iServStatus =
+    		//  12345678901
+			_L("Started    ");
+		break;
+
+	case EUsbServiceStopping:
+    	iServStatus =
+    		//  12345678901
+			_L("Stopping   ");
+		break;
+
+	case EUsbServiceFatalError:
+    	iServStatus =
+    		//  12345678901
+			_L("Error      ");
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	LOG("Service State => %S", &iServStatus);
+	ScheduleDraw('E');
+	}
+	
+void CUsbTestConsole::SetDeviceState(TUsbDeviceState aDeviceState)
+	{
+	switch(aDeviceState)
+		{
+	case EUsbDeviceStateUndefined:
+		iDevStatus =
+    		//  12345678901
+			_L("Undefined  ");
+		break;
+
+	case EUsbDeviceStateDefault:
+		iDevStatus =
+    		//  12345678901
+			_L("Default    ");
+		break;
+
+	case EUsbDeviceStateAttached:
+		iDevStatus =
+    		//  12345678901
+			_L("Attached   ");
+		break;
+
+	case EUsbDeviceStatePowered:
+		iDevStatus =
+    		//  12345678901
+			_L("Powered    ");
+		break;
+
+	case EUsbDeviceStateConfigured:
+		iDevStatus =
+    		//  12345678901
+			_L("Configured ");
+		break;
+
+	case EUsbDeviceStateAddress:
+		iDevStatus =
+    		//  12345678901
+			_L("Address    ");
+		break;
+
+	case EUsbDeviceStateSuspended:
+		iDevStatus =
+    		//  12345678901
+			_L("Suspended  ");
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	LOG("Device State => %S", &iDevStatus);
+	ScheduleDraw('E');
+	}
+	
+void CUsbTestConsole::SetConnectionIdle(TInt aConnectionIdle)
+	{
+	switch(aConnectionIdle)
+		{
+	case 0:
+		iConnectionIdle =
+    		//  12345
+			_L("Busy ");
+		break;
+
+	case 1:
+		iConnectionIdle =
+    		//  12345
+			_L("Idle ");
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	LOG("ConnectionIdle => %S", &iConnectionIdle);
+	ScheduleDraw('E');
+	}
+
+void CUsbTestConsole::SetIdPin(TInt aIdPin)
+	{
+	switch(aIdPin)
+		{
+    case 0:
+        iIdPin =
+    		//  12345
+			_L("-    ");
+		break;
+
+	case 1:
+		iIdPin =
+    		//  12345
+			_L("+    ");
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	LOG("Id Pin => %S", &iIdPin);
+	ScheduleDraw('E');
+	}
+	
+void CUsbTestConsole::SetVBus(TInt aVBus)
+	{
+	switch(aVBus)
+		{
+	case 0:
+		iVBus =
+    		//  12345
+			_L("-    ");
+		break;
+
+	case 1:
+		iVBus =
+    		//  12345
+			_L("+    ");
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	LOG("VBus => %S", &iVBus);
+	ScheduleDraw('E');
+	}
+
+void CUsbTestConsole::SetOtgState(TInt aOtgState)
+	{
+	switch(aOtgState)
+		{
+	case 0x01:
+		iOtgState =
+    		//  123456789012
+			_L("Reset       ");
+		break;
+
+	case 0x02:
+		iOtgState =
+    		//  123456789012
+			_L("A-Idle      ");
+		break;
+
+	case 0x04:
+		iOtgState =
+    		//  123456789012
+			_L("A-Host      ");
+		break;
+
+	case 0x08:
+		iOtgState =
+    		//  1234567890123
+			_L("A-Peripheral");
+		break;
+
+	case 0x10:
+		iOtgState =
+    		//  123456789012
+			_L("A-Vbus Error");
+		break;
+
+	case 0x20:
+		iOtgState =
+    		//  123456789012
+			_L("B-Idle      ");
+		break;
+
+	case 0x40:
+		iOtgState =
+    		//  1234567890123
+			_L("B-Peripheral");
+		break;
+
+	case 0x80:
+		iOtgState =
+    		//  1234567890123
+			_L("B-Host      ");
+		break;
+		
+	default:
+		iOtgState =
+    		//  1234567890123
+			_L("Don't Panic!");
+		break;
+		}
+	LOG("OTG State => %S", &iOtgState);
+	ScheduleDraw('E');
+	}
+
+void CUsbTestConsole::SetDriverLoading(TFdfDriverLoadingState aDriverLoading)
+	{
+	switch(aDriverLoading)
+		{
+	case EUnknown:
+		iDriverLoading =
+			//  123
+			_L("???");
+		break;
+	case EDisabled:
+		iDriverLoading =
+			//  123
+			_L("Off");
+		break;
+	case EEnabled:
+		iDriverLoading =
+			//  123
+			_L("On ");
+		break;
+	default:
+		PANIC;
+		break;
+		}
+	LOG("Driver Loading => %S", &iDriverLoading);
+	ScheduleDraw('E');
+	}
+	
+void CUsbTestConsole::SetAttachedDevices(TUint aAttachedDevices)
+	{
+	if(aAttachedDevices > 999)
+		{
+		iAttachedDevices =
+			//  123
+			_L("xxx");
+		}
+	else
+		{
+		iAttachedDevices.NumFixedWidthUC(aAttachedDevices, EDecimal, 3);
+		}
+	LOG("Attached Devices => %S", &iAttachedDevices);
+	ScheduleDraw('E');
+	}
+	
+void CUsbTestConsole::SetControlSession(TBool aControl)
+	{
+	if(aControl)
+		{
+		iControlSession =
+			//  1234567
+			_L("Control");
+		}
+	else
+		{
+		iControlSession =
+			//  1234567
+			_L("       ");
+		}
+	LOG("Control Session => [%d]", aControl);
+	ScheduleDraw('E');
+	}
+
+void CUsbTestConsole::SetDeviceType(TDeviceType aDeviceType)
+	{
+	iDeviceType = aDeviceType;
+
+	switch ( aDeviceType )
+		{
+	case ENoDevice:
+		iAttachedDevice =
+			//  12345
+			_L("     ");
+		break;
+	case EGenericDevice:
+		iAttachedDevice =
+			//  12345
+			_L("<   >");
+		break;
+	case ELogitechHeadset:
+		iAttachedDevice =
+			//  12345
+			_L("<<A>>");
+		break;
+		}
+	LOG("Audio Device => [%S]", &iAttachedDevice);
+	ScheduleDraw('E');
+	}
+	
+TBool CUsbTestConsole::GetAutoSrpResponseState()
+	{
+	return iAutoSrpResponse;
+	}
+	
+void CUsbTestConsole::SetAutoSrpResponseState(TBool aAutoSrpResponse)
+	{
+	iAutoSrpResponse = aAutoSrpResponse;
+	
+	if ( aAutoSrpResponse )
+		{
+		iSrpState = _L("Auto");
+		}
+	else
+		{
+		iSrpState = _L("    ");
+		}
+	}
+
+void CUsbTestConsole::NotifyEvent(XUsbTestConsoleEvent* aEvent)
+	{
+	__ASSERT_ALWAYS(aEvent, PANIC);
+	__ASSERT_ALWAYS(aEvent->iEvent.Length() <= KNumCharactersOnLine, PANIC);
+
+	iEventList.AddFirst(*aEvent);
+	delete iEventList.Last();
+	LOG("Event => %S", &(aEvent->iEvent));
+	ScheduleDraw('E');
+	}
+
+void CUsbTestConsole::Draw()
+	{
+	iConsole->ClearScreen();
+	
+	// First line is the server version number (and session state)
+	TVersionName versionName = iVersion.Name();
+	iConsole->Printf(_L(
+//          1         2         3         4         5
+// 12345678901234567890123456789012345678901234567890123
+  "Server Version: %S   %S\n"
+	),
+	&versionName, &iControlSession
+	);
+
+	// Print "dash board"
+	iConsole->Printf(_L(
+//          1         2         3         4         5
+// 12345678901234567890123456789012345678901234567890123
+  "Device              OTG          Host          "L"%S\n"
+//          12345678901        12345                123
+ L"Service: %S"      L"Id Pin: %S"L"Driver Loading: %S\n"
+ L"Device:  %S"      L"V. Bus: %S"L"Attached Devs:  %S\n"
+ //           1234567890123           12345
+ L"OTG State: %S "        L"Device: %S " L"SRP: %S\n"
+	),
+	&iConnectionIdle,
+    &iServStatus, &iIdPin, &iDriverLoading,
+	&iDevStatus, &iVBus, &iAttachedDevices,
+	&iOtgState, &iAttachedDevice, &iSrpState
+	);
+
+	if (iHelp)
+		{
+		//                     12345678901234567890123456789012345678901234567890123
+		iConsole->Printf(_L("\nHelp:Available Command Selections"));
+		iConsole->Printf(_L("\n"));
+		iConsole->Printf(_L("\n '?'/'h'/'H' = Help (show these menu commands)"));
+		iConsole->Printf(_L("\n 'v'/'V' = Toggle 'verbose' logging"));
+		iConsole->Printf(_L("\n 'q'/'Q' = Quit application"));
+		iConsole->Printf(_L("\n 'c'/'C' = Toggle control session"));
+		iConsole->Printf(_L("\n 's' = Start()           'S' = Stop()"));
+		iConsole->Printf(_L("\n 't' = TryStart()        'T' = TryStop()"));
+		iConsole->Printf(_L("\n 'p'/'P' = Enter personality number (for TryStart())"));
+		iConsole->Printf(_L("\n 'e'/'E' = Toggle 'enable driver loading'"));
+		iConsole->Printf(_L("\n 'b' = BusRequest()      'B' = BusDrop()"));
+		iConsole->Printf(_L("\n 'r' = Respond (positively) to SRP"));
+		iConsole->Printf(_L("\n 'R' = Toggle SRP Auto-Response"));
+		iConsole->Printf(_L("\n 'x'/'X' = Clear Bus Error (A_VBUS_ERR)"));
+		iConsole->Printf(_L("\n 'a'/'A' = Check audio capability"));
+		iConsole->Printf(_L("\n '[' = Perform USBMAN test"));
+		}
+	else
+		{
+		// Events...
+		TDblQueIter<XUsbTestConsoleEvent> iter(iEventList);
+		XUsbTestConsoleEvent* event = NULL;
+		while((event = iter++) != NULL)
+			{
+			iConsole->Printf(_L("\n"));
+			iConsole->Printf(event->iEvent.Left(KNumCharactersOnLine-1));
+			}
+		}
+	}
+	
+	
+
+CUsbTestConsoleTextEntryBase::CUsbTestConsoleTextEntryBase()
+	: CActive(EPriorityNormal)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CUsbTestConsoleTextEntryBase::~CUsbTestConsoleTextEntryBase()
+	{
+	Cancel();
+	iLink.Deque();
+	delete iEntryConsole;
+	iChars.Close();
+	}
+
+void CUsbTestConsoleTextEntryBase::ConstructL(const TDesC& aEntryField)
+	{
+	User::LeaveIfError(iChars.Create(KMaxNumOfChars));
+	iEntryConsole = Console::NewL(_L("UsbTestConsole Entry Console"), TSize(-1,-1));
+	iEntryConsole->Printf(aEntryField);
+	iEntryConsole->Printf(_L(": "));
+	iEntryConsole->Read(iStatus);
+	SetActive();
+	}
+
+void CUsbTestConsoleTextEntryBase::DoCancel()
+	{
+	iEntryConsole->ReadCancel();
+	}
+
+void CUsbTestConsoleTextEntryBase::RunL()
+	{
+	TKeyCode code = iEntryConsole->KeyCode();
+	switch(code)
+		{
+		case EKeyEnter:
+				{
+				TRAPD(err, ConvertAndSetL());
+				if(err == KErrNone)
+					{
+					delete this;
+					return;
+					}
+				}
+			break;
+		case EKeyEscape:
+			delete this;
+			return;
+		case EKeyBackspace:
+			if(iChars.Length() > 0)
+				{
+				iEntryConsole->SetCursorPosRel(TPoint(-1, 0));
+				iEntryConsole->ClearToEndOfLine();
+				iChars.SetLength(iChars.Length()-1);
+				}
+			break;
+		default:
+			iChars.Append(code);
+			iEntryConsole->Printf(_L("%c"), code);
+			break;
+		}
+	iEntryConsole->Read(iStatus);
+	SetActive();
+	}
+
+
+template<typename T>
+CUsbTestConsoleTextEntry<T>* CUsbTestConsoleTextEntry<T>::NewL(T& aValue, const TDesC& aEntryField)
+	{
+	CUsbTestConsoleTextEntry<T>* self = new(ELeave) CUsbTestConsoleTextEntry<T>(aValue);
+	CleanupStack::PushL(self);
+	self->ConstructL(aEntryField);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+template<typename T>
+CUsbTestConsoleTextEntry<T>::~CUsbTestConsoleTextEntry()
+	{
+	}
+
+template<typename T>
+CUsbTestConsoleTextEntry<T>::CUsbTestConsoleTextEntry(T& aValue)
+	: CUsbTestConsoleTextEntryBase()
+	, iValue(aValue)
+	{
+	}
+
+template<>
+void CUsbTestConsoleTextEntry<TUint>::ConvertAndSetL()
+	{
+	TLex lex(iChars);
+	
+	lex.SkipSpaceAndMark();
+
+	TBool hex = ETrue;
+	if (lex.Get() != '0' || lex.Get() != 'x')
+		{
+		lex.UnGetToMark();
+		hex = EFalse;
+		}
+		
+	TUint val;
+	TRadix rad = hex ? EHex : EDecimal;
+	User::LeaveIfError(lex.Val(val, rad));
+	
+	iValue = val;
+	}
+	
+template<>
+void CUsbTestConsoleTextEntry<TInt>::ConvertAndSetL()
+	{
+	TLex lex(iChars);
+	
+	lex.SkipSpaceAndMark();
+
+	TUint val;
+	User::LeaveIfError(lex.Val(val, EDecimal));
+	
+	iValue = val;
+	}
+
+
+
+
+
+
+
+
+	
+
+
+CEventNotifier::CEventNotifier(TInt aPriority)
+	: CActive(aPriority)
+	{
+	}
+
+XUsbTestConsoleEvent* CEventNotifier::NewConsoleEventL()
+	{
+	XUsbTestConsoleEvent* event = new(ELeave) XUsbTestConsoleEvent;
+	CleanupStack::PushL(event);
+	User::LeaveIfError(event->iEvent.Create(CUsbTestConsole::KNumCharactersOnLine-1));
+	CleanupStack::Pop();
+	return event;
+	}
+
+void CEventNotifier::RunL()
+	{
+	DoRunL(NewConsoleEventL());
+	}
+
+
+CServiceStateWatcher* CServiceStateWatcher::NewL(CUsbTestConsole& aTestConsole)
+	{
+	CServiceStateWatcher* self = new(ELeave) CServiceStateWatcher(aTestConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+CServiceStateWatcher::~CServiceStateWatcher()
+	{
+	Cancel();
+	}
+
+CServiceStateWatcher::CServiceStateWatcher(CUsbTestConsole& aTestConsole)
+	: CEventNotifier(EPriorityStandard)
+	, iTestConsole(aTestConsole)
+	, iServiceState(EUsbServiceIdle)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CServiceStateWatcher::ConstructL()
+	{
+	iTestConsole.Usb().ServiceStateNotification(iServiceState, iStatus);
+	SetActive();
+
+	TUsbServiceState serviceState;
+	User::LeaveIfError(iTestConsole.Usb().GetServiceState(serviceState));
+	iTestConsole.SetServiceState(serviceState);
+	}
+
+void CServiceStateWatcher::DoCancel()
+	{
+	iTestConsole.Usb().ServiceStateNotificationCancel();
+	}
+
+void CServiceStateWatcher::DoRunL(XUsbTestConsoleEvent* aEvent)
+	{
+	iTestConsole.SetServiceState(iServiceState);
+	TPtrC res(NULL, 0);
+	_LIT(KIdle, "Idle");
+	_LIT(KStarting, "Starting");
+	_LIT(KStarted, "Started");
+	_LIT(KStopping, "Stopping");
+	_LIT(KError, "Error");
+	switch(iServiceState)
+		{
+	case EUsbServiceIdle:
+		res.Set(KIdle);
+		break;
+	case EUsbServiceStarting:
+		res.Set(KStarting);
+		break;
+	case EUsbServiceStarted:
+		res.Set(KStarted);
+		break;
+	case EUsbServiceStopping:
+		res.Set(KStopping);
+		break;
+	case EUsbServiceFatalError:
+		res.Set(KError);
+		break;
+	default:
+		PANIC;
+		break;
+		}
+		
+	iTestConsole.Usb().ServiceStateNotification(iServiceState, iStatus);
+	SetActive();
+
+	aEvent->iEvent.AppendFormat(_L("D:ServiceState [%S]"), &res);
+	iTestConsole.NotifyEvent(aEvent);
+
+	// Seems like there can be race conditions
+	TUsbServiceState serviceState;
+	User::LeaveIfError(iTestConsole.Usb().GetServiceState(serviceState));
+
+	iTestConsole.SetServiceState(serviceState);
+	}
+
+	
+CDeviceStateWatcher* CDeviceStateWatcher::NewL(CUsbTestConsole& aTestConsole)
+	{
+	CDeviceStateWatcher* self = new(ELeave) CDeviceStateWatcher(aTestConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+CDeviceStateWatcher::~CDeviceStateWatcher()
+	{
+	Cancel();
+	}
+
+CDeviceStateWatcher::CDeviceStateWatcher(CUsbTestConsole& aTestConsole)
+	: CEventNotifier(EPriorityStandard)
+	, iTestConsole(aTestConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CDeviceStateWatcher::ConstructL()
+	{
+	iTestConsole.Usb().DeviceStateNotification(0xffffffff, iDeviceState, iStatus);
+	SetActive();
+
+	TUsbDeviceState deviceState;
+	User::LeaveIfError(iTestConsole.Usb().GetDeviceState(deviceState));
+	iTestConsole.SetDeviceState(deviceState);
+	}
+
+void CDeviceStateWatcher::DoCancel()
+	{
+	iTestConsole.Usb().DeviceStateNotificationCancel();
+	}
+
+void CDeviceStateWatcher::DoRunL(XUsbTestConsoleEvent* aEvent)
+	{
+	iTestConsole.SetDeviceState(iDeviceState);
+	TPtrC res(NULL, 0);
+	_LIT(KUndefined, "Undefined");
+    _LIT(KDefault, "Default");
+    _LIT(KAttached, "Attached");
+    _LIT(KPowered, "Powered");
+    _LIT(KConfigured, "Configured");
+    _LIT(KAddress, "Address");
+    _LIT(KSuspended, "Suspended");
+	switch(iDeviceState)
+		{
+	case EUsbDeviceStateUndefined:
+		res.Set(KUndefined);
+		break;
+	case EUsbDeviceStateDefault:
+		res.Set(KDefault);
+		break;
+	case EUsbDeviceStateAttached:
+		res.Set(KAttached);
+		break;
+	case EUsbDeviceStatePowered:
+		res.Set(KPowered);
+		break;
+	case EUsbDeviceStateConfigured:
+		res.Set(KConfigured);
+		break;
+	case EUsbDeviceStateAddress:
+		res.Set(KAddress);
+		break;
+	case EUsbDeviceStateSuspended:
+		res.Set(KSuspended);
+		break;
+	default:
+		PANIC;
+		break;
+		}
+
+    iTestConsole.Usb().DeviceStateNotification(0xffffffff, iDeviceState, iStatus);
+	SetActive();
+
+	aEvent->iEvent.AppendFormat(_L("D:DeviceState [%S]"), &res);
+	iTestConsole.NotifyEvent(aEvent);
+
+	// Seems like there can be race conditions
+	TUsbDeviceState deviceState;
+	User::LeaveIfError(iTestConsole.Usb().GetDeviceState(deviceState));
+
+	iTestConsole.SetDeviceState(deviceState);
+	}
+	
+CConnectionIdleWatcher* CConnectionIdleWatcher::NewL(CUsbTestConsole& aTestConsole)
+	{
+	CConnectionIdleWatcher * self = new(ELeave) CConnectionIdleWatcher (aTestConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+CConnectionIdleWatcher::~CConnectionIdleWatcher()
+	{
+	Cancel();
+	iConnectionIdleProp.Close();
+	}
+
+CConnectionIdleWatcher::CConnectionIdleWatcher(CUsbTestConsole& aTestConsole)
+	: CEventNotifier(EPriorityStandard)
+	, iTestConsole(aTestConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CConnectionIdleWatcher::ConstructL()
+	{
+	User::LeaveIfError(iConnectionIdleProp.Attach(KUidUsbManCategory, KUsbOtgConnectionIdleProperty));
+	iConnectionIdleProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	TInt err = iConnectionIdleProp.Get(val);
+	LOG("CConnectionIdleWatcher::ConstructL iConnectionIdleProp.Get(val) => val=%d", val);
+	User::LeaveIfError(err);
+	iTestConsole.SetConnectionIdle(val);
+	}
+
+void CConnectionIdleWatcher::DoCancel()
+	{
+	iConnectionIdleProp.Cancel();
+	}
+
+void CConnectionIdleWatcher::DoRunL(XUsbTestConsoleEvent* aEvent)
+	{
+	CleanupStack::PushL(aEvent);
+
+	iConnectionIdleProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iConnectionIdleProp.Get(val));
+
+	TPtrC res(NULL, 0);
+	_LIT(KConnectionIdle, "Idle");
+	_LIT(KConnectionBusy, "Busy");
+	switch(val)
+		{
+	case 0:
+		res.Set(KConnectionBusy);
+		break;
+
+	case 1:
+		res.Set(KConnectionIdle);
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	CleanupStack::Pop();
+
+	aEvent->iEvent.AppendFormat(_L("O:ConnectionIdle [%S]"), &res);
+	iTestConsole.SetConnectionIdle(val);
+	iTestConsole.NotifyEvent(aEvent);
+	}
+	
+	
+CIdPinWatcher* CIdPinWatcher::NewL(CUsbTestConsole& aTestConsole)
+	{
+	CIdPinWatcher* self = new(ELeave) CIdPinWatcher(aTestConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+CIdPinWatcher::~CIdPinWatcher()
+	{
+	Cancel();
+	iIdPinProp.Close();
+	}
+
+CIdPinWatcher::CIdPinWatcher(CUsbTestConsole& aTestConsole)
+	: CEventNotifier(EPriorityStandard)
+	, iTestConsole(aTestConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CIdPinWatcher::ConstructL()
+	{
+	User::LeaveIfError(iIdPinProp.Attach(KUidUsbManCategory, KUsbOtgIdPinPresentProperty));
+	iIdPinProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	TInt err = iIdPinProp.Get(val);
+	LOG("CIdPinWatcher::ConstructL iIdPinProp.Get(val) => %d",err);
+	User::LeaveIfError(err);
+	iTestConsole.SetIdPin(val);
+	}
+
+void CIdPinWatcher::DoCancel()
+	{
+	iIdPinProp.Cancel();
+	}
+
+void CIdPinWatcher::DoRunL(XUsbTestConsoleEvent* aEvent)
+	{
+	CleanupStack::PushL(aEvent);
+
+	iIdPinProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iIdPinProp.Get(val));
+
+	TPtrC res(NULL, 0);
+	_LIT(KIdPinInserted, "Inserted");
+	_LIT(KIdPinRemoved, "Removed");
+	switch(val)
+		{
+	case 0:
+		res.Set(KIdPinRemoved);
+		break;
+
+	case 1:
+		res.Set(KIdPinInserted);
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	CleanupStack::Pop();
+
+	aEvent->iEvent.AppendFormat(_L("O:IdPin [%S]"), &res);
+	iTestConsole.SetIdPin(val);
+	iTestConsole.NotifyEvent(aEvent);
+	}
+	
+	
+CVBusWatcher* CVBusWatcher::NewL(CUsbTestConsole& aTestConsole)
+	{
+	CVBusWatcher* self = new(ELeave) CVBusWatcher(aTestConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+CVBusWatcher::~CVBusWatcher()
+	{
+	Cancel();
+	iVBusProp.Close();
+	}
+
+CVBusWatcher::CVBusWatcher(CUsbTestConsole& aTestConsole)
+	: CEventNotifier(EPriorityStandard)
+	, iTestConsole(aTestConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CVBusWatcher::ConstructL()
+	{
+	User::LeaveIfError(iVBusProp.Attach(KUidUsbManCategory, KUsbOtgVBusPoweredProperty));
+	iVBusProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iVBusProp.Get(val));
+	iTestConsole.SetVBus(val);
+	}
+
+void CVBusWatcher::DoCancel()
+	{
+	iVBusProp.Cancel();
+	}
+
+void CVBusWatcher::DoRunL(XUsbTestConsoleEvent* aEvent)
+	{
+	CleanupStack::PushL(aEvent);
+
+	iVBusProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iVBusProp.Get(val));
+
+	TPtrC res(NULL, 0);
+	_LIT(KVBusRaised, "Raised");
+	_LIT(KVBusDropped, "Dropped");
+	switch(val)
+		{
+	case 0:
+		{
+		if ( iTestConsole.GetAutoSrpResponseState() ) 
+			{
+			(iTestConsole.Timer())->Cancel();
+			}
+		res.Set(KVBusDropped);
+		break;
+		}
+	case 1:
+		res.Set(KVBusRaised);
+		break;
+
+	default:
+		PANIC;
+		break;
+		}
+	CleanupStack::Pop();
+
+	aEvent->iEvent.AppendFormat(_L("O:VBus [%S]"), &res);
+	iTestConsole.SetVBus(val);
+	iTestConsole.NotifyEvent(aEvent);
+	}
+	
+COtgStateWatcher* COtgStateWatcher::NewL(CUsbTestConsole& aTestConsole)
+	{
+	COtgStateWatcher* self = new(ELeave) COtgStateWatcher(aTestConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+COtgStateWatcher::~COtgStateWatcher()
+	{
+	Cancel();
+	iOtgStateProp.Close();
+	}
+
+COtgStateWatcher::COtgStateWatcher(CUsbTestConsole& aTestConsole)
+	: CEventNotifier(EPriorityStandard)
+	, iTestConsole(aTestConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void COtgStateWatcher::ConstructL()
+	{
+	User::LeaveIfError(iOtgStateProp.Attach(KUidUsbManCategory, KUsbOtgStateProperty));
+	iOtgStateProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iOtgStateProp.Get(val));
+	iTestConsole.SetOtgState(val);
+	}
+
+void COtgStateWatcher::DoCancel()
+	{
+	iOtgStateProp.Cancel();
+	}
+
+void COtgStateWatcher::DoRunL(XUsbTestConsoleEvent* aEvent)
+	{
+	CleanupStack::PushL(aEvent);
+
+	iOtgStateProp.Subscribe(iStatus);
+	SetActive();
+
+	TInt val;
+	User::LeaveIfError(iOtgStateProp.Get(val));
+
+	TPtrC res(NULL, 0);
+	
+	_LIT(KReset, 		"Reset"			);
+
+	_LIT(KAIdle, 		"A-Idle"		);
+	_LIT(KAHost, 		"A-Host"		);
+	_LIT(KAPeripheral, 	"A-Peripheral"	);
+	_LIT(KABusError, 	"A-Bus Error"	);
+	
+	_LIT(KBIdle, 		"B-Idle"		);
+	_LIT(KBPeripheral, 	"B-Peripheral"	);
+	_LIT(KBHost, 		"B-Host"		);
+	
+	_LIT(KUnknown, 		"Unknown"		);
+
+	switch(val)
+		{
+	case EUsbOtgStateReset:
+		res.Set(KReset);
+		break;
+
+	case EUsbOtgStateAIdle:
+		res.Set(KAIdle);
+		break;
+
+	case EUsbOtgStateAHost:
+		if ( iTestConsole.GetAutoSrpResponseState() ) 
+			{
+			(iTestConsole.Timer())->Cancel();
+			}
+		res.Set(KAHost);
+		break;
+
+	case EUsbOtgStateAPeripheral:
+		res.Set(KAPeripheral);
+		break;
+
+	case EUsbOtgStateAVbusError:
+		res.Set(KABusError);
+		break;
+
+	case EUsbOtgStateBIdle:
+		res.Set(KBIdle);
+		break;
+
+	case EUsbOtgStateBPeripheral:
+		res.Set(KBPeripheral);
+		break;
+		
+	case EUsbOtgStateBHost:
+		res.Set(KBHost);
+		break;
+
+	default:
+		res.Set(KUnknown);
+		break;
+		}
+	CleanupStack::Pop();
+
+	aEvent->iEvent.AppendFormat(_L("O:OtgState [%S]"), &res);
+	iTestConsole.SetOtgState(val);
+	iTestConsole.NotifyEvent(aEvent);
+	}
+
+CHostEventWatcher* CHostEventWatcher::NewL(CUsbTestConsole& aTestConsole)
+	{
+	CHostEventWatcher* self = new(ELeave) CHostEventWatcher(aTestConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CHostEventWatcher::~CHostEventWatcher()
+	{
+	Cancel();
+	}
+
+CHostEventWatcher::CHostEventWatcher(CUsbTestConsole& aTestConsole)
+	: CEventNotifier(EPriorityStandard)
+	, iTestConsole(aTestConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CHostEventWatcher::ConstructL()
+	{
+	iTestConsole.Usb().HostEventNotification(iStatus, iDeviceInfo);
+	SetActive();
+	iTestConsole.SetAttachedDevices(0);
+	}
+
+void CHostEventWatcher::DoCancel()
+	{
+	iTestConsole.Usb().HostEventNotificationCancel();
+	}
+
+void CHostEventWatcher::DoRunL(XUsbTestConsoleEvent* aEvent)
+	{
+	CleanupStack::PushL(aEvent);
+
+	switch(iDeviceInfo.iEventType)
+		{
+	case EDeviceAttachment:
+			{
+			if(iDeviceInfo.iError == KErrNone)
+				{
+				User::LeaveIfError(iAttachedDevices.Append(iDeviceInfo.iDeviceId));
+				}
+			aEvent->iEvent.AppendFormat(_L("H:Attach[%08x] Err[%d] VidPid[%04x,%04x]"), iDeviceInfo.iDeviceId, iDeviceInfo.iError, iDeviceInfo.iVid, iDeviceInfo.iPid);
+			
+			if (  (iDeviceInfo.iVid == 0x046D)
+			    &&(iDeviceInfo.iPid == 0x0A02)
+			   )
+				{
+				iTestConsole.SetDeviceType(CUsbTestConsole::ELogitechHeadset);
+				}
+			else
+				{
+				iTestConsole.SetDeviceType(CUsbTestConsole::EGenericDevice);
+				}
+			}
+		break;
+
+	case EDriverLoad:
+			{
+			TPtrC res(NULL, 0);
+			_LIT(KDriverLoadSuccess, "Success");
+			_LIT(KDriverLoadPartialSuccess, "Warning");
+			_LIT(KDriverLoadFailure, "Failure");
+			switch(iDeviceInfo.iDriverLoadStatus)
+				{
+			case EDriverLoadSuccess:
+				res.Set(KDriverLoadSuccess);
+				break;
+			case EDriverLoadPartialSuccess:
+				res.Set(KDriverLoadPartialSuccess);
+				break;
+			case EDriverLoadFailure:
+				res.Set(KDriverLoadFailure);
+				break;
+			default:
+				PANIC;
+				break;
+				}
+			aEvent->iEvent.AppendFormat(_L("H:Load[%08x] Err[%d] Status[%S]"), iDeviceInfo.iDeviceId, iDeviceInfo.iError, &res);
+			}
+		break;
+
+	case EDeviceDetachment:
+			{
+			aEvent->iEvent.AppendFormat(_L("H:Detach [%08x]"), iDeviceInfo.iDeviceId);
+			TInt ix = iAttachedDevices.Find(iDeviceInfo.iDeviceId);
+			if(ix == KErrNotFound)
+				{
+				// This is probably caused by starting a new instance of the test console.
+				break;
+				}
+			iAttachedDevices.Remove(ix);
+			iTestConsole.SetDeviceType(CUsbTestConsole::ENoDevice);
+			}
+		break;
+	default:
+		PANIC;
+		break;
+		}
+	CleanupStack::Pop();
+	iTestConsole.SetAttachedDevices(iAttachedDevices.Count());
+	iTestConsole.NotifyEvent(aEvent);
+	iTestConsole.Usb().HostEventNotification(iStatus, iDeviceInfo);
+	SetActive();
+	}
+	
+	
+CMessageWatcher* CMessageWatcher::NewL(CUsbTestConsole& aTestConsole)
+	{
+	CMessageWatcher* self = new(ELeave) CMessageWatcher(aTestConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+CMessageWatcher::~CMessageWatcher()
+	{
+	Cancel();
+	}
+
+CMessageWatcher::CMessageWatcher(CUsbTestConsole& aTestConsole)
+	: CEventNotifier(EPriorityStandard)
+	, iTestConsole(aTestConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CMessageWatcher::ConstructL()
+	{
+	iTestConsole.Usb().MessageNotification(iStatus, iMessage);
+	SetActive();
+	}
+
+void CMessageWatcher::DoCancel()
+	{
+	iTestConsole.Usb().MessageNotificationCancel();
+	}
+
+void CMessageWatcher::DoRunL(XUsbTestConsoleEvent* aEvent)
+	{
+	TInt err = iStatus.Int();
+	
+	if (err)
+		{
+		aEvent->iEvent.AppendFormat(_L("O:Message[%d] Err[%d]"), iMessage, err);
+		}
+	else
+		{
+		TPtrC text(NULL, 0);
+
+		// OTGDI
+		_LIT(KMessOtgdiEventQueueOverflow,			"O:Event Queue Overflow"			);
+		_LIT(KMessOtgdiStateQueueOverflow,			"O:State Queue Overflow"			);
+		_LIT(KMessOtgdiMessageQueueOverflow,		"O:Message Queue Overflow"			);
+		_LIT(KMessOtgdiBadState,					"O:Bad State"						);
+		_LIT(KMessOtgdiStackNotStarted,				"O:Stack Not Started"				);
+		_LIT(KMessOtgdiVbusAlreadyRaised,			"O:VBUS Already Raised"				);
+		_LIT(KMessOtgdiSrpForbidden,				"O:SRP Forbidden"					);
+		_LIT(KMessOtgdiBusControlProblem,			"O:Bus Control Problem"				);
+		_LIT(KMessOtgdiVbusPowerUpError,			"O:VBUS Power Up Error"				);		
+		_LIT(KMessOtgdiHnpEnableProblem,			"O:HNP Enable Problem"				);		
+		_LIT(KMessOtgdiPeriphNotSupported,			"O:Peripheral Not Supported"		);		
+		_LIT(KMessOtgdiVbusError,					"O:VBUS Error"						);
+		_LIT(KMessOtgdiSrpTimeout,					"O:SRP Timeout"						);
+		_LIT(KMessOtgdiSrpActive,					"O:SRP Already Active"				);
+		_LIT(KMessOtgdiSrpNotPermitted,				"O:SRP Not Permitted"				);
+		_LIT(KMessOtgdiHnpNotPermitted,				"O:HNP Not Permitted"				);
+		_LIT(KMessOtgdiHnpNotEnabled,				"O:HNP Not Enabled"					);
+		_LIT(KMessOtgdiHnpNotSuspended,				"O:HNP Not Suspended"				);
+		_LIT(KMessOtgdiVbusPowerUpNotPermitted,		"O:VBUS Power Up Not Permitted"		);
+		_LIT(KMessOtgdiVbusPowerDownNotPermitted,	"O:VBUS Power Down Not Permitted"	);
+		_LIT(KMessOtgdiVbusClearErrorNotPermitted,	"O:VBUS Clear Error Not Permitted"	);
+		_LIT(KMessOtgdiHnpNotResponding,			"O:HNP Not Responding"				);
+		_LIT(KMessOtgdiHnpBusDrop,					"O:VBUS Drop During HNP!"			);
+
+		// USBDI - Main
+
+		_LIT(KMessUsbdiRequestsPending,				"U:Requests Pending"				);		
+		_LIT(KMessUsbdiBadAddress,					"U:Bad Address"						);
+		_LIT(KMessUsbdiNoAddress,					"U:No Address"						);
+		_LIT(KMessUsbdiSetAddrFailed,				"U:Set Address Failed"				);
+		_LIT(KMessUsbdiNoPower,						"U:No Power"						);
+		_LIT(KMessUsbdiTooDeep,						"U:Too Deep"						);
+		_LIT(KMessUsbdiIOError,						"U:IO Error"						);
+		_LIT(KMessUsbdiNotConfigured,				"U:Not Configured"					);
+		_LIT(KMessUsbdiTimeout,						"U:Timeout"							);
+		_LIT(KMessUsbdiStalled,						"U:Stalled"							);
+		_LIT(KMessUsbdiTestFailure,					"U:Test Failure"					);
+		_LIT(KMessUsbdiBadState,					"U:Bad State"						);
+		_LIT(KMessUsbdiDeviceSuspended,				"U:Device Suspended"				);
+
+		// USBDI - Descriptors
+
+		_LIT(KMessUsbdiBadDescriptorTopology,		"U:Bad Descriptor Topology"			);
+
+		// USBDI - DevMon
+
+		_LIT(KMessUsbdiDeviceRejected,				"U:Device Rejected"					);
+		_LIT(KMessUsbdiDeviceFailed,				"U:Device failed"					);
+		_LIT(KMessUsbdiBadDevice,					"U:Bad Device"						);
+		_LIT(KMessUsbdiBadHubPosition,				"U:Bad Hub Position"				);
+		_LIT(KMessUsbdiBadHub,						"U:Bad Hub"							);
+		_LIT(KMessUsbdiEventOverflow,				"U:Event Overflow"					);
+		
+		// USBMAN
+		
+		_LIT(KMessUsbmanSrpInitiated,				"M:SRP Initiated"					);
+		_LIT(KMessUsbmanSrpReceived,				"M:SRP Received"					);
+		_LIT(KMessUsbmanHnpDisabled,				"M:HNP Disabled"					);
+		_LIT(KMessUsbmanHnpEnabled,					"M:HNP Enabled"						);
+		_LIT(KMessUsbmanVbusRaised,					"M:VBUS Raised"						);
+		_LIT(KMessUsbmanVbusDropped,				"M:VBUS Dropped"					);
+		_LIT(KMessUsbmanRequestSession,				"M:Request Session"					);
+
+		_LIT(KMessUnknown, 							"*:Unknown"							);
+
+		switch(iMessage)
+			{
+			// OTGDI
+
+			case KErrUsbOtgEventQueueOverflow:			text.Set(KMessOtgdiEventQueueOverflow);			break;
+			case KErrUsbOtgStateQueueOverflow:	       	text.Set(KMessOtgdiStateQueueOverflow);			break;
+			case KErrUsbOtgMessageQueueOverflow:		text.Set(KMessOtgdiMessageQueueOverflow);		break;
+			case KErrUsbOtgBadState:					text.Set(KMessOtgdiBadState);					break;		
+			case KErrUsbOtgStackNotStarted:				text.Set(KMessOtgdiStackNotStarted);			break;	
+			case KErrUsbOtgVbusAlreadyRaised:	       	text.Set(KMessOtgdiVbusAlreadyRaised);			break;
+			case KErrUsbOtgSrpForbidden:				text.Set(KMessOtgdiSrpForbidden);				break;	
+			case KErrUsbOtgBusControlProblem:	       	text.Set(KMessOtgdiBusControlProblem);			break;
+			case KErrUsbOtgVbusPowerUpError:			text.Set(KMessOtgdiVbusPowerUpError);			break;		
+			case KErrUsbOtgHnpEnableProblem:			text.Set(KMessOtgdiHnpEnableProblem);			break;		
+			case KErrUsbOtgPeriphNotSupported:			text.Set(KMessOtgdiPeriphNotSupported);			break;		
+			case KErrUsbOtgVbusError:			       	text.Set(KMessOtgdiVbusError);					break;		
+			case KErrUsbOtgSrpTimeout:			       	text.Set(KMessOtgdiSrpTimeout);					break;		
+			case KErrUsbOtgSrpActive:			       	text.Set(KMessOtgdiSrpActive);					break;		
+			case KErrUsbOtgSrpNotPermitted:				text.Set(KMessOtgdiSrpNotPermitted);			break;
+			case KErrUsbOtgHnpNotPermitted:				text.Set(KMessOtgdiHnpNotPermitted);			break;
+			case KErrUsbOtgHnpNotEnabled:				text.Set(KMessOtgdiHnpNotEnabled);				break;
+			case KErrUsbOtgHnpNotSuspended:				text.Set(KMessOtgdiHnpNotSuspended);			break;
+			case KErrUsbOtgVbusPowerUpNotPermitted:  	text.Set(KMessOtgdiVbusPowerUpNotPermitted);	break;
+			case KErrUsbOtgVbusPowerDownNotPermitted:	text.Set(KMessOtgdiVbusPowerDownNotPermitted);	break;
+			case KErrUsbOtgVbusClearErrorNotPermitted:	text.Set(KMessOtgdiVbusClearErrorNotPermitted);	break;
+			case KErrUsbOtgHnpNotResponding:			text.Set(KMessOtgdiHnpNotResponding);			break;
+			case KErrUsbOtgHnpBusDrop:					text.Set(KMessOtgdiHnpBusDrop);					break;
+
+			// USBDI - Main
+
+			case KErrUsbRequestsPending:				text.Set(KMessUsbdiRequestsPending);			break;		
+			case KErrUsbBadAddress:						text.Set(KMessUsbdiBadAddress); 				break;			
+			case KErrUsbNoAddress:						text.Set(KMessUsbdiNoAddress); 					break;			
+			case KErrUsbSetAddrFailed:					text.Set(KMessUsbdiSetAddrFailed); 				break;		
+			case KErrUsbNoPower:						text.Set(KMessUsbdiNoPower); 					break;				
+			case KErrUsbTooDeep:						text.Set(KMessUsbdiTooDeep); 					break;				
+			case KErrUsbIOError:						text.Set(KMessUsbdiIOError); 					break;				
+			case KErrUsbNotConfigured:					text.Set(KMessUsbdiNotConfigured); 				break;		
+			case KErrUsbTimeout:						text.Set(KMessUsbdiTimeout); 					break;				
+			case KErrUsbStalled:						text.Set(KMessUsbdiStalled); 					break;				
+			case KErrUsbTestFailure:					text.Set(KMessUsbdiTestFailure); 				break;			
+			case KErrUsbBadState:						text.Set(KMessUsbdiBadState); 					break;			
+			case KErrUsbDeviceSuspended:				text.Set(KMessUsbdiDeviceSuspended); 			break;		
+																									
+			// USBDI - Descriptors																	
+			
+			case KErrUsbBadDescriptorTopology:			text.Set(KMessUsbdiBadDescriptorTopology); 		break;
+
+			// USBDI - DevMon
+			
+			case KErrUsbDeviceRejected:					text.Set(KMessUsbdiDeviceRejected); 			break;		
+			case KErrUsbDeviceFailed:					text.Set(KMessUsbdiDeviceFailed); 				break;		
+			case KErrUsbBadDevice:						text.Set(KMessUsbdiBadDevice); 					break;			
+			case KErrUsbBadHubPosition:					text.Set(KMessUsbdiBadHubPosition); 			break;		
+			case KErrUsbBadHub:							text.Set(KMessUsbdiBadHub); 					break;				
+			case KErrUsbEventOverflow:					text.Set(KMessUsbdiEventOverflow); 				break;		
+																										
+			// USBMAN																					
+																										
+			case KUsbMessageSrpInitiated:				text.Set(KMessUsbmanSrpInitiated);				break;
+			case KUsbMessageSrpReceived:				text.Set(KMessUsbmanSrpReceived);				break;
+			case KUsbMessageHnpDisabled:				text.Set(KMessUsbmanHnpDisabled);				break;
+			case KUsbMessageHnpEnabled:					text.Set(KMessUsbmanHnpEnabled);				break;
+			case KUsbMessageVbusRaised:					text.Set(KMessUsbmanVbusRaised);				break;
+			case KUsbMessageVbusDropped:				text.Set(KMessUsbmanVbusDropped);				break;
+			case KUsbMessageRequestSession:				text.Set(KMessUsbmanRequestSession);			break;
+																										
+			default:									text.Set(KMessUnknown);							break;
+			}																							
+
+		aEvent->iEvent.AppendFormat(_L("O:Message[%d] [%S]"), iMessage, &text);
+		
+		if (   ( iMessage == KUsbMessageSrpReceived )
+		    && ( iTestConsole.GetAutoSrpResponseState() )
+		   )
+			{
+			iTestConsole.Usb().BusRespondSrp();
+			iTestConsole.Timer()->Start(KTimerAWaitBConnect);
+			}
+		else if ( iMessage == KUsbMessageRequestSession )
+			{
+			iTestConsole.Usb().BusRequest();
+			} 
+		}
+
+	iTestConsole.Usb().MessageNotification(iStatus, iMessage);
+	SetActive();
+	
+	iTestConsole.NotifyEvent(aEvent);
+	}
+
+
+	
+void CUsbManStarter::NewL(CUsbManStarter*& aSelf, CUsbTestConsole& aTestConsole)
+	{
+	aSelf = NULL;
+	CUsbManStarter* self = new(ELeave) CUsbManStarter(aSelf, aTestConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	aSelf = self;
+	}
+
+CUsbManStarter::~CUsbManStarter()
+	{
+	Cancel();
+	iSelf = NULL;
+	}
+
+CUsbManStarter::CUsbManStarter(CUsbManStarter*& aSelf, CUsbTestConsole& aTestConsole)
+	: CEventNotifier(EPriorityStandard)
+	, iSelf(aSelf)
+	, iTestConsole(aTestConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUsbManStarter::ConstructL()
+	{
+	iTestConsole.Usb().Start(iStatus);
+	SetActive();
+	}
+
+void CUsbManStarter::DoCancel()
+	{
+	iTestConsole.Usb().StartCancel();
+	}
+
+void CUsbManStarter::DoRunL(XUsbTestConsoleEvent* aEvent)
+	{
+	aEvent->iEvent.AppendFormat(_L("G:Start:Err[%d]"), iStatus.Int());
+	iTestConsole.NotifyEvent(aEvent);
+	delete this;
+	}
+
+void CUsbManStarter::DestroyL()
+	{
+	XUsbTestConsoleEvent* event = NewConsoleEventL();
+	event->iEvent.Append(_L("G:StartCancel"));
+	iTestConsole.NotifyEvent(event);
+	delete this;
+	}
+	
+	
+void CUsbManStoper::NewL(CUsbManStoper*& aSelf, CUsbTestConsole& aTestConsole)
+	{
+	aSelf = NULL;
+	CUsbManStoper* self = new(ELeave) CUsbManStoper(aSelf, aTestConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	aSelf = self;
+	}
+
+CUsbManStoper::~CUsbManStoper()
+	{
+	Cancel();
+	iSelf = NULL;
+	}
+
+CUsbManStoper::CUsbManStoper(CUsbManStoper*& aSelf, CUsbTestConsole& aTestConsole)
+	: CEventNotifier(EPriorityStandard)
+	, iSelf(aSelf)
+	, iTestConsole(aTestConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUsbManStoper::ConstructL()
+	{
+	iTestConsole.Usb().Stop(iStatus);
+	SetActive();
+	}
+
+void CUsbManStoper::DoCancel()
+	{
+	iTestConsole.Usb().StopCancel();
+	}
+
+void CUsbManStoper::DoRunL(XUsbTestConsoleEvent* aEvent)
+	{
+	aEvent->iEvent.AppendFormat(_L("G:Stop:Err[%d]"), iStatus.Int());
+	iTestConsole.NotifyEvent(aEvent);
+	delete this;
+	}
+
+void CUsbManStoper::DestroyL()
+	{
+	XUsbTestConsoleEvent* event = NewConsoleEventL();
+	event->iEvent.Append(_L("G:StopCancel"));
+	iTestConsole.NotifyEvent(event);
+	delete this;
+	}
+	
+	
+	
+void CUsbManTryStarter::NewL(CUsbManTryStarter*& aSelf, CUsbTestConsole& aTestConsole, TInt aPersonalityId)
+	{
+	aSelf = NULL;
+	CUsbManTryStarter* self = new(ELeave) CUsbManTryStarter(aSelf, aTestConsole, aPersonalityId);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	aSelf = self;
+	}
+
+CUsbManTryStarter::~CUsbManTryStarter()
+	{
+	Cancel();
+	iSelf = NULL;
+	}
+
+CUsbManTryStarter::CUsbManTryStarter(CUsbManTryStarter*& aSelf, CUsbTestConsole& aTestConsole, TInt aPersonalityId)
+	: CEventNotifier(EPriorityStandard)
+	, iSelf(aSelf)
+	, iTestConsole(aTestConsole)
+	, iPersonalityId(aPersonalityId)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUsbManTryStarter::ConstructL()
+	{
+	iTestConsole.Usb().TryStart(iPersonalityId, iStatus);
+	SetActive();
+	}
+
+void CUsbManTryStarter::DoCancel()
+	{
+	iTestConsole.Usb().StartCancel();
+	}
+
+void CUsbManTryStarter::DoRunL(XUsbTestConsoleEvent* aEvent)
+	{
+	aEvent->iEvent.AppendFormat(_L("G:TryStart:Err[%d]"), iStatus.Int());
+	iTestConsole.NotifyEvent(aEvent);
+	delete this;
+	}
+
+void CUsbManTryStarter::DestroyL()
+	{
+	XUsbTestConsoleEvent* event = NewConsoleEventL();
+	event->iEvent.Append(_L("G:StartCancel"));
+	iTestConsole.NotifyEvent(event);
+	delete this;
+	}
+	
+	
+void CUsbManTryStoper::NewL(CUsbManTryStoper*& aSelf, CUsbTestConsole& aTestConsole)
+	{
+	aSelf = NULL;
+	CUsbManTryStoper* self = new(ELeave) CUsbManTryStoper(aSelf, aTestConsole);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	aSelf = self;
+	}
+
+CUsbManTryStoper::~CUsbManTryStoper()
+	{
+	Cancel();
+	iSelf = NULL;
+	}
+
+CUsbManTryStoper::CUsbManTryStoper(CUsbManTryStoper*& aSelf, CUsbTestConsole& aTestConsole)
+	: CEventNotifier(EPriorityStandard)
+	, iSelf(aSelf)
+	, iTestConsole(aTestConsole)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CUsbManTryStoper::ConstructL()
+	{
+	iTestConsole.Usb().TryStop(iStatus);
+	SetActive();
+	}
+
+void CUsbManTryStoper::DoCancel()
+	{
+	iTestConsole.Usb().StopCancel();
+	}
+
+void CUsbManTryStoper::DoRunL(XUsbTestConsoleEvent* aEvent)
+	{
+	aEvent->iEvent.AppendFormat(_L("G:TryStop:Err[%d]"), iStatus.Int());
+	iTestConsole.NotifyEvent(aEvent);
+	delete this;
+	}
+
+void CUsbManTryStoper::DestroyL()
+	{
+	XUsbTestConsoleEvent* event = NewConsoleEventL();
+	event->iEvent.Append(_L("G:StopCancel"));
+	iTestConsole.NotifyEvent(event);
+	delete this;
+	}
+
+CUsbTestTimer* CUsbTestTimer::NewL(CUsbTestConsole& aUsb)
+	{
+	CUsbTestTimer* self = new(ELeave) CUsbTestTimer(aUsb);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CUsbTestTimer::~CUsbTestTimer()
+	{
+	Cancel();
+	}
+
+void CUsbTestTimer::ConstructL()
+	{
+	CTimer::ConstructL();
+	CActiveScheduler::Add(this);
+	}
+
+CUsbTestTimer::CUsbTestTimer(CUsbTestConsole& aUsb)
+: CTimer(EPriorityStandard)
+, iTestConsole(aUsb)
+	{	
+	}
+
+void CUsbTestTimer::Start(TTimeIntervalMicroSeconds32 aTime)
+	{
+	After(aTime);
+	}
+
+void CUsbTestTimer::RunL()
+	{
+		XUsbTestConsoleEvent* event = new(ELeave) XUsbTestConsoleEvent;
+		CleanupStack::PushL(event);
+		User::LeaveIfError(event->iEvent.Create(CUsbTestConsole::KNumCharactersOnLine-1));
+		CleanupStack::Pop();
+		
+		TPtrC res(NULL, 0);
+		_LIT(KErrMsg, "Device Not Responding");
+		
+		res.Set(KErrMsg);
+		event->iEvent.AppendFormat(_L("T:Timer Message [%S]"), &res);
+		iTestConsole.NotifyEvent(event);
+	}
+
+void CUsbTestTimer::DoCancel()
+	{
+	CTimer::DoCancel();
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbtestconsole/usbtestconsole.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,499 @@
+/*
+* Copyright (c) 2007-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:
+*
+*/
+
+#ifndef USBTESTCONSOLE_H
+#define USBTESTCONSOLE_H
+
+#include <e32cmn.h>
+#include <e32base.h>
+#include <usbman.h>
+#include <e32property.h>
+
+class CConsoleBase;
+
+class CUsbTestConsoleKeys;
+
+class CServiceStateWatcher;
+class CDeviceStateWatcher;
+class CConnectionIdleWatcher;
+class CIdPinWatcher;
+class CVBusWatcher;
+class CHostEventWatcher;
+class CMessageWatcher;
+class COtgStateWatcher;
+
+class CUsbManStarter;
+class CUsbManStoper;
+class CUsbManTryStarter;
+class CUsbManTryStoper;
+class CUsbTestTimer;   
+
+_LIT(KUsbTestConsoleTitle, "USB Test Console");
+
+
+NONSHARABLE_STRUCT(XUsbTestConsoleEvent)
+	{
+	~XUsbTestConsoleEvent();
+	TDblQueLink	iLink;
+	RBuf		iEvent;
+	};
+
+
+NONSHARABLE_CLASS(CUsbTestConsole) : public CActive
+	{
+friend class CUsbTestConsoleKeys;
+
+public:
+	static CUsbTestConsole* NewLC();
+	~CUsbTestConsole();
+
+public:
+	void StartL();
+	void Stop() const;
+	
+	RUsb& Usb();
+	CUsbTestTimer* Timer() const;  
+
+public:
+	enum TFdfDriverLoadingState
+		{
+		EUnknown,
+		EDisabled,
+		EEnabled
+		};
+	
+	enum TDeviceType
+		{
+		ENoDevice,
+		EGenericDevice,
+		ELogitechHeadset
+		};
+
+public: // Callbacks
+	void SetServiceState(TUsbServiceState aServiceState);
+	void SetDeviceState(TUsbDeviceState aDeviceState);
+	void SetIdPin(TInt aIdPin);
+    void SetConnectionIdle(TInt aConnectionIdle);
+	void SetVBus(TInt aVBus);
+	void SetOtgState(TInt aOtgState);
+	void SetDriverLoading(TFdfDriverLoadingState aDriverLoading);
+	void SetAttachedDevices(TUint aAttachedDevices);
+	void SetControlSession(TBool aControl);
+	void SetDeviceType(TDeviceType aDeviceType);
+
+	void NotifyEvent(XUsbTestConsoleEvent* aEvent);
+	
+	TBool GetAutoSrpResponseState();
+	void  SetAutoSrpResponseState(TBool aAutoSrpResponse);
+
+private:
+	CUsbTestConsole();
+	void ConstructL();
+	void Draw();
+
+	void DoCancel();
+	void RunL();
+	void ScheduleDraw(TUint aKey);
+	
+	TBool 		iHelp;
+	TBool		iAutoSrpResponse;
+	TDeviceType iDeviceType;
+	
+private:
+	CConsoleBase* iConsole;
+	RUsb iUsb;
+	
+	CUsbTestConsoleKeys* iKeys;
+	
+private:
+	CServiceStateWatcher*	iServiceStateWatcher;
+	CDeviceStateWatcher*	iDeviceStateWatcher;
+	CIdPinWatcher*			iIdPinWatcher;
+    CConnectionIdleWatcher* iConnectionIdleWatcher;
+	CVBusWatcher*			iVBusWatcher;
+	COtgStateWatcher*		iOtgStateWatcher;
+	CHostEventWatcher*		iHostEventWatcher;
+	CMessageWatcher*		iMessageWatcher;
+	CUsbTestTimer*          iTimer;  
+
+private: // Display variables
+	TVersion	iVersion;
+	TBuf<9>		iControlSession;
+	TBuf<11>	iServStatus; // Needs Trailing Space
+	TBuf<11>	iDevStatus; // Needs Trailing Space
+	TBuf<5>		iIdPin; // Needs Trailing Space
+    TBuf<5>     iConnectionIdle; // Needs Trailing Space
+	TBuf<5>		iVBus;  // Needs Trailing Space
+	TBuf<3>		iDriverLoading;
+	TBuf<3>		iAttachedDevices;
+	TBuf<14>	iOtgState;  // Needs Trailing Space
+	TBuf<5>		iAttachedDevice;
+	TBuf<5>		iSrpState;
+
+public:
+	// H4 screen can have 22 lines of text on it at once
+	// H4 screen can have 53 characters per line.
+	static const TInt KNumCharactersOnLine = 53;
+
+private:
+	static const TInt KNumEventsOnScreen = 15;
+	
+private: // Event list
+	TDblQue<XUsbTestConsoleEvent>	iEventList;
+	};
+	
+	
+NONSHARABLE_CLASS(CUsbTestConsoleTextEntryBase) : public CActive
+	{
+public:
+	~CUsbTestConsoleTextEntryBase();
+
+protected:
+	CUsbTestConsoleTextEntryBase();
+	void ConstructL(const TDesC& aEntryField);
+
+private:
+	void DoCancel();
+	void RunL();
+
+	virtual void ConvertAndSetL() = 0;
+
+private:
+	static const TInt KMaxNumOfChars = 255;
+	CConsoleBase*	iEntryConsole;
+protected:
+	RBuf			iChars;
+public:
+	TDblQueLink		iLink;
+	};
+
+NONSHARABLE_CLASS(CUsbTestConsoleKeys) : public CActive
+	{
+public:
+	static CUsbTestConsoleKeys* NewL(CUsbTestConsole& aUsb);
+	~CUsbTestConsoleKeys();
+	
+private:
+	CUsbTestConsoleKeys(CUsbTestConsole& aUsb);
+	void ConstructL();
+	void DoCancel();
+	void RunL();
+	XUsbTestConsoleEvent* NewConsoleEventL();
+	
+private:
+	CUsbTestConsole&	iTestConsole;
+	
+private: // Async Utilities
+	CUsbManStarter*			iUsbManStarter;
+	CUsbManStoper*			iUsbManStoper;
+	CUsbManTryStarter*		iUsbManTryStarter;
+	CUsbManTryStoper*		iUsbManTryStoper;
+
+private:
+	TDblQue<CUsbTestConsoleTextEntryBase>	iEntryConsoles;
+
+private: // configured variables
+	TInt	iPersonalityId;
+	TBool	iControlSession;
+	TBool	iFunctionDriverLoading;
+	};
+
+	
+template<typename T>
+NONSHARABLE_CLASS(CUsbTestConsoleTextEntry) : public CUsbTestConsoleTextEntryBase
+	{
+public:
+	static CUsbTestConsoleTextEntry* NewL(T& aValue, const TDesC& aEntryField);
+	~CUsbTestConsoleTextEntry();
+	
+private:
+	CUsbTestConsoleTextEntry(T& aValue);
+	void ConvertAndSetL();
+
+private:
+    T&						iValue;
+	};
+
+
+	
+NONSHARABLE_CLASS(CEventNotifier) : public CActive
+	{
+protected:
+	CEventNotifier(TInt aPriority);
+	XUsbTestConsoleEvent* NewConsoleEventL();
+	virtual void DoRunL(XUsbTestConsoleEvent* aEvent) = 0;
+private:
+	void RunL();
+	};
+	
+
+	
+NONSHARABLE_CLASS(CServiceStateWatcher) : public CEventNotifier
+	{
+public:
+	static CServiceStateWatcher* NewL(CUsbTestConsole& aUsb);
+	~CServiceStateWatcher();
+
+private:
+	CServiceStateWatcher(CUsbTestConsole& aUsb);
+	void ConstructL();
+
+	void DoCancel();
+	void DoRunL(XUsbTestConsoleEvent* aEvent);
+
+private:
+	CUsbTestConsole&	iTestConsole;
+	TUsbServiceState	iServiceState;
+	};
+
+
+NONSHARABLE_CLASS(CDeviceStateWatcher) : public CEventNotifier
+	{
+public:
+	static CDeviceStateWatcher* NewL(CUsbTestConsole& aUsb);
+	~CDeviceStateWatcher();
+
+private:
+	CDeviceStateWatcher(CUsbTestConsole& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbTestConsoleEvent* aEvent);
+
+private:
+	CUsbTestConsole&	iTestConsole;
+	TUsbDeviceState		iDeviceState;
+	};
+
+
+NONSHARABLE_CLASS(CIdPinWatcher) : public CEventNotifier
+	{
+public:
+	static CIdPinWatcher* NewL(CUsbTestConsole& aUsb);
+	~CIdPinWatcher();
+
+private:
+	CIdPinWatcher(CUsbTestConsole& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbTestConsoleEvent* aEvent);
+
+private:
+	CUsbTestConsole&	iTestConsole;
+	RProperty			iIdPinProp;
+	};
+
+NONSHARABLE_CLASS(CConnectionIdleWatcher) : public CEventNotifier
+	{
+public:
+	static CConnectionIdleWatcher* NewL(CUsbTestConsole& aUsb);
+	~CConnectionIdleWatcher();
+
+private:
+	CConnectionIdleWatcher(CUsbTestConsole& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbTestConsoleEvent* aEvent);
+
+private:
+	CUsbTestConsole&	iTestConsole;
+	RProperty			iConnectionIdleProp;
+	};
+
+
+NONSHARABLE_CLASS(CVBusWatcher) : public CEventNotifier
+	{
+public:
+	static CVBusWatcher* NewL(CUsbTestConsole& aUsb);
+	~CVBusWatcher();
+
+private:
+	CVBusWatcher(CUsbTestConsole& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbTestConsoleEvent* aEvent);
+
+private:
+	CUsbTestConsole&	iTestConsole;
+	RProperty			iVBusProp;
+	};
+	
+NONSHARABLE_CLASS(COtgStateWatcher) : public CEventNotifier
+	{
+public:
+	static COtgStateWatcher* NewL(CUsbTestConsole& aUsb);
+	~COtgStateWatcher();
+
+private:
+	COtgStateWatcher(CUsbTestConsole& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbTestConsoleEvent* aEvent);
+
+private:
+	CUsbTestConsole&	iTestConsole;
+	RProperty			iOtgStateProp;
+	};
+	
+	
+NONSHARABLE_CLASS(CHostEventWatcher) : public CEventNotifier
+	{
+public:
+	static CHostEventWatcher* NewL(CUsbTestConsole& aUsb);
+	~CHostEventWatcher();
+
+private:
+	CHostEventWatcher(CUsbTestConsole& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbTestConsoleEvent* aEvent);
+
+private:
+	CUsbTestConsole&		iTestConsole;
+	TDeviceEventInformation	iDeviceInfo;
+	RArray<TUint>			iAttachedDevices;
+	};
+	
+
+NONSHARABLE_CLASS(CMessageWatcher) : public CEventNotifier
+	{
+public:
+	static CMessageWatcher* NewL(CUsbTestConsole& aUsb);
+	~CMessageWatcher();
+
+private:
+	CMessageWatcher(CUsbTestConsole& aUsb);
+	void ConstructL();
+
+	void DoCancel();
+	void DoRunL(XUsbTestConsoleEvent* aEvent);
+
+private:
+	CUsbTestConsole&	iTestConsole;
+	TInt				iMessage;
+	};
+
+
+
+
+
+
+
+NONSHARABLE_CLASS(CUsbManStarter) : public CEventNotifier
+	{
+public:
+	static void NewL(CUsbManStarter*& aSelf, CUsbTestConsole& aUsb);
+	void DestroyL();
+	~CUsbManStarter();
+	
+private:
+	CUsbManStarter(CUsbManStarter*& aSelf, CUsbTestConsole& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbTestConsoleEvent* aEvent);
+	
+private:
+	CUsbManStarter*& 	iSelf;
+	CUsbTestConsole&	iTestConsole;
+	};
+	
+	
+NONSHARABLE_CLASS(CUsbManStoper) : public CEventNotifier
+	{
+public:
+	static void NewL(CUsbManStoper*& aSelf, CUsbTestConsole& aUsb);
+	void DestroyL();
+	~CUsbManStoper();
+	
+private:
+	CUsbManStoper(CUsbManStoper*& aSelf, CUsbTestConsole& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbTestConsoleEvent* aEvent);
+	
+private:
+	CUsbManStoper*& 	iSelf;
+	CUsbTestConsole&	iTestConsole;
+	};
+	
+	
+	
+NONSHARABLE_CLASS(CUsbManTryStarter) : public CEventNotifier
+	{
+public:
+	static void NewL(CUsbManTryStarter*& aSelf, CUsbTestConsole& aUsb, TInt aPersonalityId);
+	void DestroyL();
+	~CUsbManTryStarter();
+	
+private:
+	CUsbManTryStarter(CUsbManTryStarter*& aSelf, CUsbTestConsole& aUsb, TInt aPersonalityId);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbTestConsoleEvent* aEvent);
+	
+private:
+	CUsbManTryStarter*& 	iSelf;
+	CUsbTestConsole&	iTestConsole;
+	TInt				iPersonalityId;
+	};
+	
+	
+NONSHARABLE_CLASS(CUsbManTryStoper) : public CEventNotifier
+	{
+public:
+	static void NewL(CUsbManTryStoper*& aSelf, CUsbTestConsole& aUsb);
+	void DestroyL();
+	~CUsbManTryStoper();
+	
+private:
+	CUsbManTryStoper(CUsbManTryStoper*& aSelf, CUsbTestConsole& aUsb);
+	void ConstructL();
+	
+	void DoCancel();
+	void DoRunL(XUsbTestConsoleEvent* aEvent);
+	
+private:
+	CUsbManTryStoper*& 	iSelf;
+	CUsbTestConsole&	iTestConsole;
+	};
+
+NONSHARABLE_CLASS(CUsbTestTimer) : public CTimer
+	{
+public:
+	static CUsbTestTimer* NewL(CUsbTestConsole& aUsb);
+	~CUsbTestTimer();
+	void Start(TTimeIntervalMicroSeconds32 aTime);
+		
+private:
+	CUsbTestTimer(CUsbTestConsole& aUsb);
+	void ConstructL();
+	void DoCancel();
+	void RunL();
+	
+private:
+	TTimeIntervalMicroSeconds32 iTime;
+	CUsbTestConsole&	iTestConsole;
+	};
+#endif // USBTESTCONSOLE_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbtestconsole/usbtestconsole.mmp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,31 @@
+/*
+* 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 "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:
+*
+*/
+
+
+target usbtestconsole.exe
+targettype exe
+
+capability All -Tcb
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+sourcepath .
+source usbtestconsole.cpp
+
+library euser.lib
+library usbman.lib
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/usbtestconsole/usbtestconsole.oby	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,18 @@
+/*
+* 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 "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= ABI_DIR\BUILD_DIR\usbtestconsole.exe sys\bin\usbtestconsole.exe
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/winapp/test.bat	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,27 @@
+REM Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+REM All rights reserved.
+REM This component and the accompanying materials are made available
+REM under the terms of "Eclipse Public License v1.0"
+REM which accompanies this distribution, and is available
+REM at the URL "http://www.eclipse.org/legal/epl-v10.html".
+REM 
+REM Initial Contributors:
+REM Nokia Corporation - initial contribution.
+REM 
+REM Contributors:
+REM 
+REM Description:
+REM 
+REM 
+
+usbcheck 0 0 1060 8444 293 0 "SMSC" "USB 2 Flash Media Device" >log.txt
+if ERRORLEVEL 1 goto bad
+echo !!!!
+goto end
+
+:bad
+
+echo ???
+
+:end
+
Binary file usbmgmt/usbmgrtest/winapp/usbcheck.exe has changed