VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/serial/loopback.py@ 92489

Last change on this file since 92489 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.4 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: loopback.py 82968 2020-02-04 10:35:17Z vboxsync $
3
4"""
5VirtualBox Validation Kit - Serial loopback module.
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2018-2020 Oracle Corporation
11
12This file is part of VirtualBox Open Source Edition (OSE), as
13available from http://www.virtualbox.org. This file is free software;
14you can redistribute it and/or modify it under the terms of the GNU
15General Public License (GPL) as published by the Free Software
16Foundation, in version 2 as it comes in the "COPYING" file of the
17VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19
20The contents of this file may alternatively be used under the terms
21of the Common Development and Distribution License Version 1.0
22(CDDL) only, as it comes in the "COPYING.CDDL" file of the
23VirtualBox OSE distribution, in which case the provisions of the
24CDDL are applicable instead of those of the GPL.
25
26You may elect to license modified versions of this file under the
27terms and conditions of either the GPL or the CDDL or both.
28"""
29__version__ = "$Revision: 82968 $"
30
31# Standard Python imports.
32#import os;
33import socket;
34import threading;
35
36
37g_ksLoopbackTcpServ = 'TcpServ';
38g_ksLoopbackTcpClient = 'TcpClient';
39g_ksLoopbackNamedPipeServ = 'NamedPipeServ';
40g_ksLoopbackNamedPipeClient = 'NamedPipeClient';
41
42class SerialLoopbackTcpServ(object):
43 """
44 Handler for a server TCP style connection.
45 """
46 def __init__(self, sLocation, iTimeout):
47 sHost, sPort = sLocation.split(':');
48 self.oConn = None;
49 self.oSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
50 self.oSock.settimeout(iTimeout);
51 self.oSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
52 self.oSock.bind((sHost, int(sPort)));
53 self.oSock.listen(1);
54 self.iTimeout = iTimeout;
55
56 def __del__(self):
57 if self.oConn is not None:
58 self.oConn.close();
59 if self.oSock is not None:
60 self.oSock.close();
61 self.oSock = None;
62
63 def shutdown(self):
64 if self.oConn is not None:
65 self.oConn.close();
66 self.oConn = None;
67 self.oSock.close();
68 self.oSock = None;
69
70 def pumpIo(self):
71 """
72 Main I/O pumping routine.
73 """
74 try:
75 if self.oConn is None:
76 oConn, _ = self.oSock.accept();
77 self.oConn = oConn;
78 else:
79 abData = self.oConn.recv(1024); # pylint: disable=no-member
80 if abData is not None:
81 self.oConn.send(abData); # pylint: disable=no-member
82 except:
83 pass;
84
85class SerialLoopbackTcpClient(object):
86 """
87 Handler for a client TCP style connection.
88 """
89 def __init__(self, sLocation, iTimeout):
90 sHost, sPort = sLocation.split(':');
91 self.oConn = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
92 self.oConn.connect((sHost, int(sPort)));
93 self.oConn.settimeout(iTimeout);
94 self.iTimeout = iTimeout;
95
96 def __del__(self):
97 if self.oConn is not None:
98 self.oConn.close();
99
100 def shutdown(self):
101 if self.oConn is not None:
102 self.oConn.close();
103 self.oConn = None;
104
105 def pumpIo(self):
106 """
107 Main I/O pumping routine.
108 """
109 try:
110 abData = self.oConn.recv(1024);
111 if abData is not None:
112 self.oConn.send(abData);
113 except:
114 pass;
115
116class SerialLoopbackNamedPipeServ(object):
117 """
118 Handler for a named pipe server style connection.
119 """
120 def __init__(self, sLocation, iTimeout):
121 self.oConn = None;
122 self.oSock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM); # pylint: disable=no-member
123 self.oSock.settimeout(iTimeout);
124 self.oSock.bind(sLocation);
125 self.oSock.listen(1);
126 self.iTimeout = iTimeout;
127
128 def __del__(self):
129 if self.oConn is not None:
130 self.oConn.close();
131 if self.oSock is not None:
132 self.oSock.close();
133 self.oSock = None;
134
135 def shutdown(self):
136 if self.oConn is not None:
137 self.oConn.close();
138 self.oConn = None;
139 self.oSock.close();
140 self.oSock = None;
141
142 def pumpIo(self):
143 """
144 Main I/O pumping routine.
145 """
146 try:
147 if self.oConn is None:
148 oConn, _ = self.oSock.accept();
149 self.oConn = oConn;
150 else:
151 abData = self.oConn.recv(1024); # pylint: disable=no-member
152 if abData is not None:
153 self.oConn.send(abData); # pylint: disable=no-member
154 except:
155 pass;
156
157class SerialLoopbackNamedPipeClient(object):
158 """
159 Handler for a named pipe client style connection.
160 """
161 def __init__(self, sLocation, iTimeout):
162 self.oConn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM); # pylint: disable=no-member
163 self.oConn.connect(sLocation);
164 self.oConn.settimeout(iTimeout);
165 self.iTimeout = iTimeout;
166
167 def __del__(self):
168 if self.oConn is not None:
169 self.oConn.close();
170
171 def shutdown(self):
172 if self.oConn is not None:
173 self.oConn.close();
174 self.oConn = None;
175
176 def pumpIo(self):
177 """
178 Main I/O pumping routine.
179 """
180 try:
181 abData = self.oConn.recv(1024);
182 if abData is not None:
183 self.oConn.send(abData);
184 except:
185 pass;
186
187class SerialLoopback(object):
188 """
189 Serial port loopback module working with TCP and named pipes.
190 """
191
192 def __init__(self, sType, sLocation):
193 self.fShutdown = False;
194 self.sType = sType;
195 self.sLocation = sLocation;
196 self.oLock = threading.Lock();
197 self.oThread = threading.Thread(target=self.threadWorker, args=(), name=('SerLoopback'));
198
199 if sType == g_ksLoopbackTcpServ:
200 self.oIoPumper = SerialLoopbackTcpServ(sLocation, 0.5);
201 self.oThread.start();
202 elif sType == g_ksLoopbackNamedPipeServ:
203 self.oIoPumper = SerialLoopbackNamedPipeServ(sLocation, 0.5); # pylint: disable=redefined-variable-type
204 self.oThread.start();
205
206 def connect(self):
207 """
208 Connects to the server for a client type version.
209 """
210 fRc = True;
211 try:
212 if self.sType == g_ksLoopbackTcpClient:
213 self.oIoPumper = SerialLoopbackTcpClient(self.sLocation, 0.5);
214 elif self.sType == g_ksLoopbackNamedPipeClient:
215 self.oIoPumper = SerialLoopbackNamedPipeClient(self.sLocation, 0.5); # pylint: disable=redefined-variable-type
216 except:
217 fRc = False;
218 else:
219 self.oThread.start();
220 return fRc;
221
222 def shutdown(self):
223 """
224 Shutdown any connection and wait for it to become idle.
225 """
226 self.oLock.acquire();
227 self.fShutdown = True;
228 self.oLock.release();
229 self.oIoPumper.shutdown();
230
231 def isShutdown(self):
232 """
233 Returns whether the I/O pumping thread should shut down.
234 """
235 self.oLock.acquire();
236 fShutdown = self.fShutdown;
237 self.oLock.release();
238
239 return fShutdown;
240
241 def threadWorker(self):
242 """
243 The threaded worker.
244 """
245 while not self.isShutdown():
246 self.oIoPumper.pumpIo();
247
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