VirtualBox

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

Last change on this file since 60548 was 60488, checked in by vboxsync, 9 years ago

ValidationKit/usb: Fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: usbgadget.py 60488 2016-04-14 10:33:11Z 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: 60488 $"
31
32import time;
33
34# Validation Kit imports.
35import testdriver.txsclient as txsclient;
36import testdriver.reporter as reporter;
37from common import utils;
38
39## @name USB gadget type string constants.
40## @{
41g_ksGadgetTypeInvalid = 'Invalid';
42g_ksGadgetTypeBeaglebone = 'BeagleBone';
43g_ksGadgetTypeODroidXu3 = 'ODroidXu3';
44g_ksGadgetTypeDummyHcd = 'DummyHcd';
45## @}
46
47## @name USB gadget configurations.
48## @{
49g_kdGadgetCfgs = {
50 g_ksGadgetTypeBeaglebone: ('musb-hdrc.0.auto'),
51 g_ksGadgetTypeODroidXu3: ('12400000.dwc3'),
52 g_ksGadgetTypeDummyHcd: ('dummy_udc.0')
53};
54## @}
55
56## @name USB gadget imeprsonation string constants.
57## @{
58g_ksGadgetImpersonationInvalid = 'Invalid';
59g_ksGadgetImpersonationTest = 'Test';
60g_ksGadgetImpersonationMsd = 'Msd';
61g_ksGadgetImpersonationWebcam = 'Webcam';
62g_ksGadgetImpersonationEther = 'Ether';
63## @}
64
65class UsbGadget(object):
66 """
67 USB Gadget control class using the TesteXecService to talk to the external
68 board behaving like a USB device.
69 The board needs to run an embedded Linux system with the TXS service running.
70 """
71
72 def __init__(self):
73 self.oTxsSession = None;
74 self.sImpersonation = g_ksGadgetImpersonationInvalid;
75 self.sGadgetType = g_ksGadgetTypeInvalid;
76
77 def _sudoExecuteSync(self, asArgs):
78 """
79 Executes a sudo child process synchronously.
80 Returns a tuple [True, 0] if the process executed successfully
81 and returned 0, otherwise [False, rc] is returned.
82 """
83 reporter.log('Executing [sudo]: %s' % (asArgs, ));
84 reporter.flushall();
85 iRc = 0;
86 try:
87 iRc = utils.sudoProcessCall(asArgs, shell = False, close_fds = False);
88 except:
89 reporter.errorXcpt();
90 return (False, 0);
91 reporter.log('Exit code [sudo]: %s (%s)' % (iRc, asArgs));
92 return (iRc is 0, iRc);
93
94 def _execLocallyOrThroughTxs(self, sExec, asArgs):
95 """
96 Executes the given program locally or through TXS based on the
97 current config.
98 """
99 fRc = False;
100
101 if self.oTxsSession is not None:
102 fRc = self.oTxsSession.syncExecEx(sExec, (sExec,) + asArgs);
103 else:
104 fRc, _ = self._sudoExecuteSync([sExec, ] + list(asArgs));
105 return fRc;
106
107 def _loadModule(self, sModule):
108 """
109 Loads the given module on the USB gadget.
110 Returns True on success.
111 Returns False otherwise.
112 """
113 return self._execLocallyOrThroughTxs('/usr/bin/modprobe', (sModule, ));
114
115 def _unloadModule(self, sModule):
116 """
117 Unloads the given module on the USB gadget.
118 Returns True on success.
119 Returns False otherwise.
120 """
121 return self._execLocallyOrThroughTxs('/usr/bin/rmmod', (sModule, ));
122
123 def _clearImpersonation(self):
124 """
125 Removes the current impersonation of the gadget.
126 """
127 if self.sImpersonation == g_ksGadgetImpersonationInvalid:
128 self._unloadModule('g_zero');
129 self._unloadModule('g_mass_storage');
130 self._unloadModule('g_webcam');
131 self._unloadModule('g_ether');
132 return True;
133 elif self.sImpersonation == g_ksGadgetImpersonationTest:
134 return self._unloadModule('g_zero');
135 elif self.sImpersonation == g_ksGadgetImpersonationMsd:
136 return self._unloadModule('g_mass_storage');
137 elif self.sImpersonation == g_ksGadgetImpersonationWebcam:
138 return self._unloadModule('g_webcam');
139 elif self.sImpersonation == g_ksGadgetImpersonationEther:
140 return self._unloadModule('g_ether');
141 else:
142 reporter.log('Invalid impersonation');
143
144 return False;
145
146 def _doSoftConnect(self, sAction):
147 """
148 Does a softconnect/-disconnect based on the given action.
149 """
150 sUdcFile = g_kdGadgetCfgs.get(self.sGadgetType);
151 sPath = '/sys/class/udc/' + sUdcFile + '/soft_connect';
152
153 return self._execLocallyOrThroughTxs('/usr/bin/sh', ('-c', 'echo ' + sAction + ' > ' + sPath));
154
155 def _prepareGadget(self):
156 """
157 Prepares the gadget for use in testing.
158 """
159 fRc = True;
160 if self.sGadgetType is g_ksGadgetTypeDummyHcd:
161 fRc = self._loadModule('dummy_hcd');
162 return fRc;
163
164 def _cleanupGadget(self):
165 """
166 Cleans up the gadget to the default state.
167 """
168 fRc = True;
169 if self.sGadgetType is g_ksGadgetTypeDummyHcd:
170 fRc = self._unloadModule('dummy_hcd');
171 return fRc;
172
173 def disconnectUsb(self):
174 """
175 Disconnects the USB gadget from the host. (USB connection not network
176 connection used for control)
177 """
178 return self._doSoftConnect('disconnect');
179
180 def connectUsb(self):
181 """
182 Connect the USB gadget to the host.
183 """
184 return self._doSoftConnect('connect');
185
186 def impersonate(self, sImpersonation):
187 """
188 Impersonate a given device.
189 """
190
191 # Clear any previous impersonation
192 self._clearImpersonation();
193 self.sImpersonation = sImpersonation;
194
195 fRc = False;
196 if sImpersonation == g_ksGadgetImpersonationTest:
197 fRc = self._loadModule('g_zero');
198 elif sImpersonation == g_ksGadgetImpersonationMsd:
199 # @todo: Not complete
200 fRc = self._loadModule('g_mass_storage');
201 elif sImpersonation == g_ksGadgetImpersonationWebcam:
202 # @todo: Not complete
203 fRc = self._loadModule('g_webcam');
204 elif sImpersonation == g_ksGadgetImpersonationEther:
205 fRc = self._loadModule('g_ether');
206 else:
207 reporter.log('Invalid impersonation');
208
209 if fRc and self.sGadgetType is g_ksGadgetTypeDummyHcd and self.oTxsSession is not None:
210 time.sleep(2); # Fudge
211 # For the dummy HCD over USB/IP case we have to bind the device to the USB/IP server
212 self._execLocallyOrThroughTxs('/usr/bin/sh', ('-c', '/usr/bin/usbip bind -b 3-1'));
213
214 return fRc;
215
216 def connectTo(self, cMsTimeout, sGadgetType, fUseTxs, sHostname, uPort = None):
217 """
218 Connects to the specified target device.
219 Returns True on Success.
220 Returns False otherwise.
221 """
222 fRc = True;
223
224 if fUseTxs:
225 if uPort is None:
226 self.oTxsSession = txsclient.openTcpSession(cMsTimeout, sHostname);
227 else:
228 self.oTxsSession = txsclient.openTcpSession(cMsTimeout, sHostname, uPort = uPort);
229 if self.oTxsSession is None:
230 return False;
231
232 fDone = self.oTxsSession.waitForTask(30*1000);
233 print 'connect: waitForTask -> %s, result %s' % (fDone, self.oTxsSession.getResult());
234 if fDone is True and self.oTxsSession.isSuccess():
235 fRc = True;
236 else:
237 fRc = False;
238
239 if fRc is True:
240 self.sGadgetType = sGadgetType;
241 else:
242 self.sGadgetType = g_ksGadgetTypeInvalid;
243
244 if fRc:
245 fRc = self._prepareGadget();
246
247 return fRc;
248
249 def disconnectFrom(self):
250 """
251 Disconnects from the target device.
252 """
253 fRc = True;
254
255 if self.sGadgetType is not g_ksGadgetTypeInvalid:
256 self._clearImpersonation();
257 self._cleanupGadget();
258 if self.oTxsSession is not None:
259 fRc = self.oTxsSession.syncDisconnect();
260
261 return fRc;
Note: See TracBrowser for help on using the repository browser.

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