VirtualBox

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

Last change on this file since 62736 was 62471, checked in by vboxsync, 9 years ago

Misc: scm

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1/* $Id: UsbTestServiceGadgetHostUsbIp.cpp 62471 2016-07-22 18:04:30Z 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 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
33#include <iprt/asm.h>
34#include <iprt/cdefs.h>
35#include <iprt/ctype.h>
36#include <iprt/env.h>
37#include <iprt/mem.h>
38#include <iprt/process.h>
39#include <iprt/string.h>
40#include <iprt/thread.h>
41#include <iprt/time.h>
42#include <iprt/types.h>
43
44#include "UsbTestServiceGadgetHostInternal.h"
45#include "UsbTestServicePlatform.h"
46
47
48/*********************************************************************************************************************************
49* Constants And Macros, Structures and Typedefs *
50*********************************************************************************************************************************/
51
52/**
53 * Internal UTS gadget host instance data.
54 */
55typedef struct UTSGADGETHOSTTYPEINT
56{
57 /** Handle to the USB/IP daemon process. */
58 RTPROCESS hProcUsbIp;
59} UTSGADGETHOSTTYPEINT;
60
61/** Default port of the USB/IP server. */
62#define UTS_GADGET_HOST_USBIP_PORT_DEF 3240
63
64
65/*********************************************************************************************************************************
66* Internal Functions *
67*********************************************************************************************************************************/
68
69
70/**
71 * Worker for binding/unbinding the given gadget from the USB/IP server.
72 *
73 * @returns IPRT status code.
74 * @param pThis The gadget host instance.
75 * @param hGadget The gadget handle.
76 * @param fBind Flag whether to do a bind or unbind.
77 */
78static int usbGadgetHostUsbIpBindUnbind(PUTSGADGETHOSTTYPEINT pThis, UTSGADGET hGadget, bool fBind)
79{
80 uint32_t uBusId, uDevId;
81 char aszBus[32];
82
83 uBusId = utsGadgetGetBusId(hGadget);
84 uDevId = utsGadgetGetDevId(hGadget);
85
86 /* Create the busid argument string. */
87 size_t cbRet = RTStrPrintf(&aszBus[0], RT_ELEMENTS(aszBus), "%u-%u", uBusId, uDevId);
88 if (cbRet == RT_ELEMENTS(aszBus))
89 return VERR_BUFFER_OVERFLOW;
90
91 /* Bind to the USB/IP server. */
92 RTPROCESS hProcUsbIp = NIL_RTPROCESS;
93 const char *apszArgv[5];
94
95 apszArgv[0] = "usbip";
96 apszArgv[1] = fBind ? "bind" : "unbind";
97 apszArgv[2] = "-b";
98 apszArgv[3] = &aszBus[0];
99 apszArgv[4] = NULL;
100
101 int rc = RTProcCreate("usbip", apszArgv, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &hProcUsbIp);
102 if (RT_SUCCESS(rc))
103 {
104 RTPROCSTATUS ProcSts;
105 rc = RTProcWait(hProcUsbIp, RTPROCWAIT_FLAGS_BLOCK, &ProcSts);
106 if (RT_SUCCESS(rc))
107 {
108 /* Evaluate the process status. */
109 if ( ProcSts.enmReason != RTPROCEXITREASON_NORMAL
110 || ProcSts.iStatus != 0)
111 rc = VERR_UNRESOLVED_ERROR; /** @todo: Log and give finer grained status code. */
112 }
113 }
114
115 return rc;
116}
117
118/**
119 * @interface_method_impl{UTSGADGETHOSTIF,pfnInit}
120 */
121static DECLCALLBACK(int) utsGadgetHostUsbIpInit(PUTSGADGETHOSTTYPEINT pIf, PCUTSGADGETCFGITEM paCfg)
122{
123 int rc = VINF_SUCCESS;
124 uint16_t uPort = 0;
125
126 pIf->hProcUsbIp = NIL_RTPROCESS;
127
128 rc = utsGadgetCfgQueryU16Def(paCfg, "UsbIp/Port", &uPort, UTS_GADGET_HOST_USBIP_PORT_DEF);
129 if (RT_SUCCESS(rc))
130 {
131 /* Make sure the kernel drivers are loaded. */
132 rc = utsPlatformModuleLoad("usbip-core", NULL, 0);
133 if (RT_SUCCESS(rc))
134 {
135 rc = utsPlatformModuleLoad("usbip-host", NULL, 0);
136 if (RT_SUCCESS(rc))
137 {
138 char aszPort[10];
139 char aszPidFile[64];
140 const char *apszArgv[6];
141
142 RTStrPrintf(aszPort, RT_ELEMENTS(aszPort), "%u", uPort);
143 RTStrPrintf(aszPidFile, RT_ELEMENTS(aszPidFile), "/var/run/usbipd-%u.pid", uPort);
144 /* Start the USB/IP server process. */
145 apszArgv[0] = "usbipd";
146 apszArgv[1] = "--tcp-port";
147 apszArgv[2] = aszPort;
148 apszArgv[3] = "--pid";
149 apszArgv[4] = aszPidFile;
150 apszArgv[5] = NULL;
151 rc = RTProcCreate("usbipd", apszArgv, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &pIf->hProcUsbIp);
152 if (RT_SUCCESS(rc))
153 {
154 /* Wait for a bit to make sure the server started up successfully. */
155 uint64_t tsStart = RTTimeMilliTS();
156 do
157 {
158 RTPROCSTATUS ProcSts;
159 rc = RTProcWait(pIf->hProcUsbIp, RTPROCWAIT_FLAGS_NOBLOCK, &ProcSts);
160 if (rc != VERR_PROCESS_RUNNING)
161 {
162 rc = VERR_INVALID_HANDLE;
163 break;
164 }
165 RTThreadSleep(1);
166 rc = VINF_SUCCESS;
167 } while (RTTimeMilliTS() - tsStart < 2 * 1000); /* 2 seconds. */
168 }
169 }
170 }
171 }
172
173 return rc;
174}
175
176
177/**
178 * @interface_method_impl{UTSGADGETHOSTIF,pfnTerm}
179 */
180static DECLCALLBACK(void) utsGadgetHostUsbIpTerm(PUTSGADGETHOSTTYPEINT pIf)
181{
182 /* Kill the process and wait for it to terminate. */
183 RTProcTerminate(pIf->hProcUsbIp);
184
185 RTPROCSTATUS ProcSts;
186 RTProcWait(pIf->hProcUsbIp, RTPROCWAIT_FLAGS_BLOCK, &ProcSts);
187}
188
189
190/**
191 * @interface_method_impl{UTSGADGETHOSTIF,pfnGadgetAdd}
192 */
193static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetAdd(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
194{
195 /* Nothing to do so far. */
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 return VINF_SUCCESS;
207}
208
209
210/**
211 * @interface_method_impl{UTSGADGETHOSTIF,pfnGadgetConnect}
212 */
213static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetConnect(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
214{
215 return usbGadgetHostUsbIpBindUnbind(pIf, hGadget, true /* fBind */);
216}
217
218
219/**
220 * @interface_method_impl{UTSGADGETHOSTIF,pfnGadgetDisconnect}
221 */
222static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetDisconnect(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
223{
224 return usbGadgetHostUsbIpBindUnbind(pIf, hGadget, false /* fBind */);
225}
226
227
228
229/**
230 * The gadget host interface callback table.
231 */
232const UTSGADGETHOSTIF g_UtsGadgetHostIfUsbIp =
233{
234 /** enmType */
235 UTSGADGETHOSTTYPE_USBIP,
236 /** pszDesc */
237 "UTS USB/IP gadget host",
238 /** cbIf */
239 sizeof(UTSGADGETHOSTTYPEINT),
240 /** pfnInit */
241 utsGadgetHostUsbIpInit,
242 /** pfnTerm */
243 utsGadgetHostUsbIpTerm,
244 /** pfnGadgetAdd */
245 utsGadgetHostUsbIpGadgetAdd,
246 /** pfnGadgetRemove */
247 utsGadgetHostUsbIpGadgetRemove,
248 /** pfnGadgetConnect */
249 utsGadgetHostUsbIpGadgetConnect,
250 /** pfnGadgetDisconnect */
251 utsGadgetHostUsbIpGadgetDisconnect
252};
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