VirtualBox

source: vbox/trunk/src/VBox/Main/darwin/USBProxyServiceDarwin.cpp@ 33060

Last change on this file since 33060 was 31892, checked in by vboxsync, 14 years ago

OSE header fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1/* $Id: USBProxyServiceDarwin.cpp 31892 2010-08-24 08:00:51Z vboxsync $ */
2/** @file
3 * VirtualBox USB Proxy Service (in VBoxSVC), Darwin Specialization.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include "USBProxyService.h"
23#include "Logging.h"
24#include "iokit.h"
25
26#include <VBox/usb.h>
27#include <VBox/usblib.h>
28#include <VBox/err.h>
29
30#include <iprt/string.h>
31#include <iprt/alloc.h>
32#include <iprt/assert.h>
33#include <iprt/file.h>
34#include <iprt/err.h>
35#include <iprt/asm.h>
36
37
38/**
39 * Initialize data members.
40 */
41USBProxyServiceDarwin::USBProxyServiceDarwin (Host *aHost)
42 : USBProxyService (aHost), mServiceRunLoopRef (NULL), mNotifyOpaque (NULL), mWaitABitNextTime (false), mUSBLibInitialized (false)
43{
44 LogFlowThisFunc(("aHost=%p\n", aHost));
45}
46
47
48/**
49 * Initializes the object (called right after construction).
50 *
51 * @returns S_OK on success and non-fatal failures, some COM error otherwise.
52 */
53HRESULT USBProxyServiceDarwin::init(void)
54{
55 /*
56 * Call the superclass method first.
57 */
58 HRESULT hrc = USBProxyService::init();
59 AssertComRCReturn(hrc, hrc);
60
61#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
62 /*
63 * Initialize the USB library.
64 */
65 int rc = USBLibInit();
66 if (RT_FAILURE(rc))
67 {
68 mLastError = rc;
69 return S_OK;
70 }
71 mUSBLibInitialized = true;
72#endif
73
74 /*
75 * Start the poller thread.
76 */
77 start();
78 return S_OK;
79}
80
81
82/**
83 * Stop all service threads and free the device chain.
84 */
85USBProxyServiceDarwin::~USBProxyServiceDarwin()
86{
87 LogFlowThisFunc(("\n"));
88
89 /*
90 * Stop the service.
91 */
92 if (isActive())
93 stop();
94
95#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
96 /*
97 * Terminate the USB library - it'll
98 */
99 if (mUSBLibInitialized)
100 {
101 USBLibTerm();
102 mUSBLibInitialized = false;
103 }
104#endif
105}
106
107
108#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
109void *USBProxyServiceDarwin::insertFilter (PCUSBFILTER aFilter)
110{
111 return USBLibAddFilter (aFilter);
112}
113
114
115void USBProxyServiceDarwin::removeFilter (void *aId)
116{
117 USBLibRemoveFilter (aId);
118}
119#endif /* VBOX_WITH_NEW_USB_CODE_ON_DARWIN */
120
121
122int USBProxyServiceDarwin::captureDevice(HostUSBDevice *aDevice)
123{
124 /*
125 * Check preconditions.
126 */
127 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
128 LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
129 AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
130 Assert(aDevice->getUnistate() == kHostUSBDeviceState_Capturing);
131
132#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
133 /*
134 * Fake it.
135 */
136 ASMAtomicWriteBool(&mFakeAsync, true);
137 interruptWait();
138 return VINF_SUCCESS;
139
140#else
141 /*
142 * Create a one-shot capture filter for the device (don't
143 * match on port) and trigger a re-enumeration of it.
144 */
145 USBFILTER Filter;
146 USBFilterInit(&Filter, USBFILTERTYPE_ONESHOT_CAPTURE);
147 initFilterFromDevice(&Filter, aDevice);
148
149 void *pvId = USBLibAddFilter(&Filter);
150 if (!pvId)
151 return VERR_GENERAL_FAILURE;
152
153 int rc = DarwinReEnumerateUSBDevice(aDevice->mUsb);
154 if (RT_SUCCESS(rc))
155 aDevice->mOneShotId = pvId;
156 else
157 {
158 USBLibRemoveFilter(pvId);
159 pvId = NULL;
160 }
161 LogFlowThisFunc(("returns %Rrc pvId=%p\n", rc, pvId));
162 return rc;
163#endif
164}
165
166
167void USBProxyServiceDarwin::captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess)
168{
169#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
170 /*
171 * Remove the one-shot filter if necessary.
172 */
173 LogFlowThisFunc(("aDevice=%s aSuccess=%RTbool mOneShotId=%p\n", aDevice->getName().c_str(), aSuccess, aDevice->mOneShotId));
174 if (!aSuccess && aDevice->mOneShotId)
175 USBLibRemoveFilter(aDevice->mOneShotId);
176 aDevice->mOneShotId = NULL;
177#endif
178}
179
180
181int USBProxyServiceDarwin::releaseDevice(HostUSBDevice *aDevice)
182{
183 /*
184 * Check preconditions.
185 */
186 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
187 LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
188 AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
189 Assert(aDevice->getUnistate() == kHostUSBDeviceState_ReleasingToHost);
190
191#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
192 /*
193 * Fake it.
194 */
195 ASMAtomicWriteBool(&mFakeAsync, true);
196 interruptWait();
197 return VINF_SUCCESS;
198
199#else
200 /*
201 * Create a one-shot ignore filter for the device
202 * and trigger a re-enumeration of it.
203 */
204 USBFILTER Filter;
205 USBFilterInit(&Filter, USBFILTERTYPE_ONESHOT_IGNORE);
206 initFilterFromDevice(&Filter, aDevice);
207 Log(("USBFILTERIDX_PORT=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_PORT)));
208 Log(("USBFILTERIDX_BUS=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_BUS)));
209
210 void *pvId = USBLibAddFilter(&Filter);
211 if (!pvId)
212 return VERR_GENERAL_FAILURE;
213
214 int rc = DarwinReEnumerateUSBDevice(aDevice->mUsb);
215 if (RT_SUCCESS(rc))
216 aDevice->mOneShotId = pvId;
217 else
218 {
219 USBLibRemoveFilter(pvId);
220 pvId = NULL;
221 }
222 LogFlowThisFunc(("returns %Rrc pvId=%p\n", rc, pvId));
223 return rc;
224#endif
225}
226
227
228void USBProxyServiceDarwin::releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess)
229{
230#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
231 /*
232 * Remove the one-shot filter if necessary.
233 */
234 LogFlowThisFunc(("aDevice=%s aSuccess=%RTbool mOneShotId=%p\n", aDevice->getName().c_str(), aSuccess, aDevice->mOneShotId));
235 if (!aSuccess && aDevice->mOneShotId)
236 USBLibRemoveFilter(aDevice->mOneShotId);
237 aDevice->mOneShotId = NULL;
238#endif
239}
240
241
242void USBProxyServiceDarwin::detachingDevice(HostUSBDevice *aDevice)
243{
244#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
245 aDevice->setLogicalReconnect (HostUSBDevice::kDetachingPendingDetach);
246#else
247 NOREF(aDevice);
248#endif
249}
250
251
252bool USBProxyServiceDarwin::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine)
253{
254#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
255 /* We're faking async state stuff. */
256 return updateDeviceStateFake(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
257#else
258 /* Nothing special here so far, so fall back on parent */
259 return USBProxyService::updateDeviceState(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
260#endif
261}
262
263
264int USBProxyServiceDarwin::wait(RTMSINTERVAL aMillies)
265{
266#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
267 if ( mFakeAsync
268 && ASMAtomicXchgBool(&mFakeAsync, false))
269 return VINF_SUCCESS;
270#endif
271
272 SInt32 rc = CFRunLoopRunInMode(CFSTR (VBOX_IOKIT_MODE_STRING),
273 mWaitABitNextTime && aMillies >= 1000
274 ? 1.0 /* seconds */
275 : aMillies >= 5000 /* Temporary measure to poll for status changes (MSD). */
276 ? 5.0 /* seconds */
277 : aMillies / 1000.0,
278 true);
279 mWaitABitNextTime = rc != kCFRunLoopRunTimedOut;
280
281 return VINF_SUCCESS;
282}
283
284
285int USBProxyServiceDarwin::interruptWait (void)
286{
287 if (mServiceRunLoopRef)
288 CFRunLoopStop (mServiceRunLoopRef);
289 return 0;
290}
291
292
293PUSBDEVICE USBProxyServiceDarwin::getDevices (void)
294{
295 /* call iokit.cpp */
296 return DarwinGetUSBDevices();
297}
298
299
300void USBProxyServiceDarwin::serviceThreadInit (void)
301{
302 mServiceRunLoopRef = CFRunLoopGetCurrent();
303 mNotifyOpaque = DarwinSubscribeUSBNotifications();
304}
305
306
307void USBProxyServiceDarwin::serviceThreadTerm (void)
308{
309 DarwinUnsubscribeUSBNotifications (mNotifyOpaque);
310 mServiceRunLoopRef = NULL;
311}
312
313
314/**
315 * Wrapper called from iokit.cpp.
316 *
317 * @param pCur The USB device to free.
318 */
319void DarwinFreeUSBDeviceFromIOKit (PUSBDEVICE pCur)
320{
321 USBProxyService::freeDevice (pCur);
322}
323
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