VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/usb/usbgadget.py@ 60002

Last change on this file since 60002 was 59884, checked in by vboxsync, 9 years ago

ValidationKit/usb: Add a new gadget type using the dummy_hcd module to use gadgets on the machine executing the test

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: usbgadget.py 59884 2016-03-01 11:27:30Z vboxsync $
3# pylint: disable=C0302
4
5"""
6VirtualBox USB gadget control class
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2014-2016 Oracle Corporation
12
13This file is part of VirtualBox Open Source Edition (OSE), as
14available from http://www.virtualbox.org. This file is free software;
15you can redistribute it and/or modify it under the terms of the GNU
16General Public License (GPL) as published by the Free Software
17Foundation, in version 2 as it comes in the "COPYING" file of the
18VirtualBox OSE distribution. VirtualBox OSE is distributed in the
19hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20
21The contents of this file may alternatively be used under the terms
22of the Common Development and Distribution License Version 1.0
23(CDDL) only, as it comes in the "COPYING.CDDL" file of the
24VirtualBox OSE distribution, in which case the provisions of the
25CDDL are applicable instead of those of the GPL.
26
27You may elect to license modified versions of this file under the
28terms and conditions of either the GPL or the CDDL or both.
29"""
30__version__ = "$Revision: 59884 $"
31
32
33# Validation Kit imports.
34import testdriver.txsclient as txsclient;
35import testdriver.reporter as reporter;
36from common import utils;
37
38## @name USB gadget type string constants.
39## @{
40g_ksGadgetTypeInvalid = 'Invalid';
41g_ksGadgetTypeBeaglebone = 'BeagleBone';
42g_ksGadgetTypeODroidXu3 = 'ODroidXu3';
43g_ksGadgetTypeDummyHcd = 'DummyHcd';
44## @}
45
46## @name USB gadget configurations.
47## @{
48g_kdGadgetCfgs = {
49 g_ksGadgetTypeBeaglebone: ('musb-hdrc.0.auto'),
50 g_ksGadgetTypeODroidXu3: ('12400000.dwc3'),
51 g_ksGadgetTypeDummyHcd: ('dummy_udc.0')
52};
53## @}
54
55## @name USB gadget imeprsonation string constants.
56## @{
57g_ksGadgetImpersonationInvalid = 'Invalid';
58g_ksGadgetImpersonationTest = 'Test';
59g_ksGadgetImpersonationMsd = 'Msd';
60g_ksGadgetImpersonationWebcam = 'Webcam';
61g_ksGadgetImpersonationEther = 'Ether';
62## @}
63
64class UsbGadget(object):
65 """
66 USB Gadget control class using the TesteXecService to talk to the external
67 board behaving like a USB device.
68 The board needs to run an embedded Linux system with the TXS service running.
69 """
70
71 def __init__(self):
72 self.oTxsSession = None;
73 self.sImpersonation = g_ksGadgetImpersonationInvalid;
74 self.sGadgetType = g_ksGadgetTypeInvalid;
75
76 def _sudoExecuteSync(self, asArgs):
77 """
78 Executes a sudo child process synchronously.
79 Returns a tuple [True, 0] if the process executed successfully
80 and returned 0, otherwise [False, rc] is returned.
81 """
82 reporter.log('Executing [sudo]: %s' % (asArgs, ));
83 reporter.flushall();
84 iRc = 0;
85 try:
86 iRc = utils.sudoProcessCall(asArgs, shell = False, close_fds = False);
87 except:
88 reporter.errorXcpt();
89 return (False, 0);
90 reporter.log('Exit code [sudo]: %s (%s)' % (iRc, asArgs));
91 return (iRc is 0, iRc);
92
93 def _execLocallyOrThroughTxs(self, sExec, asArgs):
94 """
95 Executes the given program locally or through TXS based on the
96 current config.
97 """
98 fRc = False;
99
100 if self.oTxsSession is not None:
101 fRc = self.oTxsSession.syncExecEx(sExec, (sExec,) + asArgs);
102 else:
103 fRc, _ = self._sudoExecuteSync([sExec, ] + list(asArgs));
104 return fRc;
105
106 def _loadModule(self, sModule):
107 """
108 Loads the given module on the USB gadget.
109 Returns True on success.
110 Returns False otherwise.
111 """
112 return self._execLocallyOrThroughTxs('/usr/bin/modprobe', (sModule, ));
113
114 def _unloadModule(self, sModule):
115 """
116 Unloads the given module on the USB gadget.
117 Returns True on success.
118 Returns False otherwise.
119 """
120 return self._execLocallyOrThroughTxs('/usr/bin/rmmod', (sModule, ));
121
122 def _clearImpersonation(self):
123 """
124 Removes the current impersonation of the gadget.
125 """
126 if self.sImpersonation == g_ksGadgetImpersonationInvalid:
127 self._unloadModule('g_zero');
128 self._unloadModule('g_mass_storage');
129 self._unloadModule('g_webcam');
130 self._unloadModule('g_ether');
131 return True;
132 elif self.sImpersonation == g_ksGadgetImpersonationTest:
133 return self._unloadModule('g_zero');
134 elif self.sImpersonation == g_ksGadgetImpersonationMsd:
135 return self._unloadModule('g_mass_storage');
136 elif self.sImpersonation == g_ksGadgetImpersonationWebcam:
137 return self._unloadModule('g_webcam');
138 elif self.sImpersonation == g_ksGadgetImpersonationEther:
139 return self._unloadModule('g_ether');
140 else:
141 reporter.log('Invalid impersonation');
142
143 return False;
144
145 def _doSoftConnect(self, sAction):
146 """
147 Does a softconnect/-disconnect based on the given action.
148 """
149 sUdcFile = g_kdGadgetCfgs.get(self.sGadgetType);
150 sPath = '/sys/class/udc/' + sUdcFile + '/soft_connect';
151
152 return self._execLocallyOrThroughTxs('/usr/bin/sh', ('-c', 'echo' + sAction + ' > ' + sPath));
153
154 def _prepareGadget(self):
155 """
156 Prepares the gadget for use in testing.
157 """
158 fRc = True;
159 if self.sGadgetType is g_ksGadgetTypeDummyHcd:
160 fRc = self._loadModule('dummy_hcd');
161 return fRc;
162
163 def _cleanupGadget(self):
164 """
165 Cleans up the gadget to the default state.
166 """
167 fRc = True;
168 if self.sGadgetType is g_ksGadgetTypeDummyHcd:
169 fRc = self._unloadModule('dummy_hcd');
170 return fRc;
171
172 def disconnectUsb(self):
173 """
174 Disconnects the USB gadget from the host. (USB connection not network
175 connection used for control)
176 """
177 return self._doSoftConnect('disconnect');
178
179 def connectUsb(self):
180 """
181 Connect the USB gadget to the host.
182 """
183 return self._doSoftConnect('connect');
184
185 def impersonate(self, sImpersonation):
186 """
187 Impersonate a given device.
188 """
189
190 # Clear any previous impersonation
191 self._clearImpersonation();
192 self.sImpersonation = sImpersonation;
193
194 if sImpersonation == g_ksGadgetImpersonationInvalid:
195 return False;
196 elif sImpersonation == g_ksGadgetImpersonationTest:
197 return self._loadModule('g_zero');
198 elif sImpersonation == g_ksGadgetImpersonationMsd:
199 # @todo: Not complete
200 return self._loadModule('g_mass_storage');
201 elif sImpersonation == g_ksGadgetImpersonationWebcam:
202 # @todo: Not complete
203 return self._loadModule('g_webcam');
204 elif sImpersonation == g_ksGadgetImpersonationEther:
205 return self._loadModule('g_ether');
206 else:
207 reporter.log('Invalid impersonation');
208
209 return False;
210
211 def connectTo(self, cMsTimeout, sGadgetType, fUseTxs, sHostname, uPort = None):
212 """
213 Connects to the specified target device.
214 Returns True on Success.
215 Returns False otherwise.
216 """
217 fRc = True;
218
219 if fUseTxs:
220 if uPort is None:
221 self.oTxsSession = txsclient.openTcpSession(cMsTimeout, sHostname);
222 else:
223 self.oTxsSession = txsclient.openTcpSession(cMsTimeout, sHostname, uPort = uPort);
224 if self.oTxsSession is None:
225 return False;
226
227 fDone = self.oTxsSession.waitForTask(30*1000);
228 print 'connect: waitForTask -> %s, result %s' % (fDone, self.oTxsSession.getResult());
229 if fDone is True and self.oTxsSession.isSuccess():
230 fRc = True;
231 else:
232 fRc = False;
233
234 if fRc is True:
235 self.sGadgetType = sGadgetType;
236 else:
237 self.sGadgetType = g_ksGadgetTypeInvalid;
238
239 if fRc:
240 fRc = self._prepareGadget();
241
242 return fRc;
243
244 def disconnectFrom(self):
245 """
246 Disconnects from the target device.
247 """
248 fRc = True;
249
250 if self.sGadgetType is not g_ksGadgetTypeInvalid:
251 self._clearImpersonation();
252 self._cleanupGadget();
253 if self.oTxsSession is not None:
254 fRc = self.oTxsSession.syncDisconnect();
255
256 return fRc;
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette