VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostUsbIp.cpp@ 86185

Last change on this file since 86185 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: 8.4 KB
Line 
1/* $Id: UsbTestServiceGadgetHostUsbIp.cpp 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * UsbTestServ - Remote USB test configuration and execution server, USB gadget host interface
4 * for USB/IP.
5 */
6
7/*
8 * Copyright (C) 2016-2020 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * The contents of this file may alternatively be used under the terms
19 * of the Common Development and Distribution License Version 1.0
20 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
21 * VirtualBox OSE distribution, in which case the provisions of the
22 * CDDL are applicable instead of those of the GPL.
23 *
24 * You may elect to license modified versions of this file under the
25 * terms and conditions of either the GPL or the CDDL or both.
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#include <iprt/asm.h>
33#include <iprt/ctype.h>
34#include <iprt/err.h>
35#include <iprt/env.h>
36#include <iprt/mem.h>
37#include <iprt/process.h>
38#include <iprt/string.h>
39#include <iprt/thread.h>
40#include <iprt/time.h>
41
42#include "UsbTestServiceGadgetHostInternal.h"
43#include "UsbTestServicePlatform.h"
44
45
46/*********************************************************************************************************************************
47* Constants And Macros, Structures and Typedefs *
48*********************************************************************************************************************************/
49
50/**
51 * Internal UTS gadget host instance data.
52 */
53typedef struct UTSGADGETHOSTTYPEINT
54{
55 /** Handle to the USB/IP daemon process. */
56 RTPROCESS hProcUsbIp;
57} UTSGADGETHOSTTYPEINT;
58
59/** Default port of the USB/IP server. */
60#define UTS_GADGET_HOST_USBIP_PORT_DEF 3240
61
62
63/*********************************************************************************************************************************
64* Internal Functions *
65*********************************************************************************************************************************/
66
67
68/**
69 * Worker for binding/unbinding the given gadget from the USB/IP server.
70 *
71 * @returns IPRT status code.
72 * @param pThis The gadget host instance.
73 * @param hGadget The gadget handle.
74 * @param fBind Flag whether to do a bind or unbind.
75 */
76static int usbGadgetHostUsbIpBindUnbind(PUTSGADGETHOSTTYPEINT pThis, UTSGADGET hGadget, bool fBind)
77{
78 RT_NOREF1(pThis);
79 uint32_t uBusId, uDevId;
80 char aszBus[32];
81
82 uBusId = utsGadgetGetBusId(hGadget);
83 uDevId = utsGadgetGetDevId(hGadget);
84
85 /* Create the busid argument string. */
86 size_t cbRet = RTStrPrintf(&aszBus[0], RT_ELEMENTS(aszBus), "%u-%u", uBusId, uDevId);
87 if (cbRet == RT_ELEMENTS(aszBus))
88 return VERR_BUFFER_OVERFLOW;
89
90 /* Bind to the USB/IP server. */
91 RTPROCESS hProcUsbIp = NIL_RTPROCESS;
92 const char *apszArgv[5];
93
94 apszArgv[0] = "usbip";
95 apszArgv[1] = fBind ? "bind" : "unbind";
96 apszArgv[2] = "-b";
97 apszArgv[3] = &aszBus[0];
98 apszArgv[4] = NULL;
99
100 int rc = RTProcCreate("usbip", apszArgv, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &hProcUsbIp);
101 if (RT_SUCCESS(rc))
102 {
103 RTPROCSTATUS ProcSts;
104 rc = RTProcWait(hProcUsbIp, RTPROCWAIT_FLAGS_BLOCK, &ProcSts);
105 if (RT_SUCCESS(rc))
106 {
107 /* Evaluate the process status. */
108 if ( ProcSts.enmReason != RTPROCEXITREASON_NORMAL
109 || ProcSts.iStatus != 0)
110 rc = VERR_UNRESOLVED_ERROR; /** @todo Log and give finer grained status code. */
111 }
112 }
113
114 return rc;
115}
116
117/**
118 * @interface_method_impl{UTSGADGETHOSTIF,pfnInit}
119 */
120static DECLCALLBACK(int) utsGadgetHostUsbIpInit(PUTSGADGETHOSTTYPEINT pIf, PCUTSGADGETCFGITEM paCfg)
121{
122 int rc = VINF_SUCCESS;
123 uint16_t uPort = 0;
124
125 pIf->hProcUsbIp = NIL_RTPROCESS;
126
127 rc = utsGadgetCfgQueryU16Def(paCfg, "UsbIp/Port", &uPort, UTS_GADGET_HOST_USBIP_PORT_DEF);
128 if (RT_SUCCESS(rc))
129 {
130 /* Make sure the kernel drivers are loaded. */
131 rc = utsPlatformModuleLoad("usbip-core", NULL, 0);
132 if (RT_SUCCESS(rc))
133 {
134 rc = utsPlatformModuleLoad("usbip-host", NULL, 0);
135 if (RT_SUCCESS(rc))
136 {
137 char aszPort[10];
138 char aszPidFile[64];
139 const char *apszArgv[6];
140
141 RTStrPrintf(aszPort, RT_ELEMENTS(aszPort), "%u", uPort);
142 RTStrPrintf(aszPidFile, RT_ELEMENTS(aszPidFile), "/var/run/usbipd-%u.pid", uPort);
143 /* Start the USB/IP server process. */
144 apszArgv[0] = "usbipd";
145 apszArgv[1] = "--tcp-port";
146 apszArgv[2] = aszPort;
147 apszArgv[3] = "--pid";
148 apszArgv[4] = aszPidFile;
149 apszArgv[5] = NULL;
150 rc = RTProcCreate("usbipd", apszArgv, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &pIf->hProcUsbIp);
151 if (RT_SUCCESS(rc))
152 {
153 /* Wait for a bit to make sure the server started up successfully. */
154 uint64_t tsStart = RTTimeMilliTS();
155 do
156 {
157 RTPROCSTATUS ProcSts;
158 rc = RTProcWait(pIf->hProcUsbIp, RTPROCWAIT_FLAGS_NOBLOCK, &ProcSts);
159 if (rc != VERR_PROCESS_RUNNING)
160 {
161 rc = VERR_INVALID_HANDLE;
162 break;
163 }
164 RTThreadSleep(1);
165 rc = VINF_SUCCESS;
166 } while (RTTimeMilliTS() - tsStart < 2 * 1000); /* 2 seconds. */
167 }
168 }
169 }
170 }
171
172 return rc;
173}
174
175
176/**
177 * @interface_method_impl{UTSGADGETHOSTIF,pfnTerm}
178 */
179static DECLCALLBACK(void) utsGadgetHostUsbIpTerm(PUTSGADGETHOSTTYPEINT pIf)
180{
181 /* Kill the process and wait for it to terminate. */
182 RTProcTerminate(pIf->hProcUsbIp);
183
184 RTPROCSTATUS ProcSts;
185 RTProcWait(pIf->hProcUsbIp, RTPROCWAIT_FLAGS_BLOCK, &ProcSts);
186}
187
188
189/**
190 * @interface_method_impl{UTSGADGETHOSTIF,pfnGadgetAdd}
191 */
192static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetAdd(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
193{
194 /* Nothing to do so far. */
195 RT_NOREF2(pIf, hGadget);
196 return VINF_SUCCESS;
197}
198
199
200/**
201 * @interface_method_impl{UTSGADGETHOSTIF,pfnGadgetRemove}
202 */
203static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetRemove(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
204{
205 /* Nothing to do so far. */
206 RT_NOREF2(pIf, hGadget);
207 return VINF_SUCCESS;
208}
209
210
211/**
212 * @interface_method_impl{UTSGADGETHOSTIF,pfnGadgetConnect}
213 */
214static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetConnect(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
215{
216 return usbGadgetHostUsbIpBindUnbind(pIf, hGadget, true /* fBind */);
217}
218
219
220/**
221 * @interface_method_impl{UTSGADGETHOSTIF,pfnGadgetDisconnect}
222 */
223static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetDisconnect(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
224{
225 return usbGadgetHostUsbIpBindUnbind(pIf, hGadget, false /* fBind */);
226}
227
228
229
230/**
231 * The gadget host interface callback table.
232 */
233const UTSGADGETHOSTIF g_UtsGadgetHostIfUsbIp =
234{
235 /** enmType */
236 UTSGADGETHOSTTYPE_USBIP,
237 /** pszDesc */
238 "UTS USB/IP gadget host",
239 /** cbIf */
240 sizeof(UTSGADGETHOSTTYPEINT),
241 /** pfnInit */
242 utsGadgetHostUsbIpInit,
243 /** pfnTerm */
244 utsGadgetHostUsbIpTerm,
245 /** pfnGadgetAdd */
246 utsGadgetHostUsbIpGadgetAdd,
247 /** pfnGadgetRemove */
248 utsGadgetHostUsbIpGadgetRemove,
249 /** pfnGadgetConnect */
250 utsGadgetHostUsbIpGadgetConnect,
251 /** pfnGadgetDisconnect */
252 utsGadgetHostUsbIpGadgetDisconnect
253};
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