summaryrefslogtreecommitdiffstats
path: root/src/VBox/Main/src-server/darwin/USBProxyBackendDarwin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Main/src-server/darwin/USBProxyBackendDarwin.cpp')
-rw-r--r--src/VBox/Main/src-server/darwin/USBProxyBackendDarwin.cpp195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/VBox/Main/src-server/darwin/USBProxyBackendDarwin.cpp b/src/VBox/Main/src-server/darwin/USBProxyBackendDarwin.cpp
new file mode 100644
index 00000000..d232f5ce
--- /dev/null
+++ b/src/VBox/Main/src-server/darwin/USBProxyBackendDarwin.cpp
@@ -0,0 +1,195 @@
+/* $Id: USBProxyBackendDarwin.cpp $ */
+/** @file
+ * VirtualBox USB Proxy Service (in VBoxSVC), Darwin Specialization.
+ */
+
+/*
+ * Copyright (C) 2005-2022 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#define LOG_GROUP LOG_GROUP_MAIN_USBPROXYBACKEND
+#include "USBProxyBackend.h"
+#include "LoggingNew.h"
+#include "iokit.h"
+
+#include <VBox/usb.h>
+#include <VBox/usblib.h>
+#include <iprt/errcore.h>
+
+#include <iprt/string.h>
+#include <iprt/alloc.h>
+#include <iprt/assert.h>
+#include <iprt/file.h>
+#include <iprt/errcore.h>
+#include <iprt/asm.h>
+
+
+/**
+ * Initialize data members.
+ */
+USBProxyBackendDarwin::USBProxyBackendDarwin()
+ : USBProxyBackend(), mServiceRunLoopRef(NULL), mNotifyOpaque(NULL), mWaitABitNextTime(false)
+{
+}
+
+USBProxyBackendDarwin::~USBProxyBackendDarwin()
+{
+}
+
+/**
+ * Initializes the object (called right after construction).
+ *
+ * @returns VBox status code.
+ */
+int USBProxyBackendDarwin::init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
+ const com::Utf8Str &strAddress, bool fLoadingSettings)
+{
+ USBProxyBackend::init(pUsbProxyService, strId, strAddress, fLoadingSettings);
+
+ unconst(m_strBackend) = Utf8Str("host");
+
+ /*
+ * Start the poller thread.
+ */
+ start();
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Stop all service threads and free the device chain.
+ */
+void USBProxyBackendDarwin::uninit()
+{
+ LogFlowThisFunc(("\n"));
+
+ /*
+ * Stop the service.
+ */
+ if (isActive())
+ stop();
+
+ USBProxyBackend::uninit();
+}
+
+
+int USBProxyBackendDarwin::captureDevice(HostUSBDevice *aDevice)
+{
+ /*
+ * Check preconditions.
+ */
+ AssertReturn(aDevice, VERR_GENERAL_FAILURE);
+ AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
+
+ AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
+ LogFlowThisFunc(("aDevice=%s\n", aDevice->i_getName().c_str()));
+
+ Assert(aDevice->i_getUnistate() == kHostUSBDeviceState_Capturing);
+
+ devLock.release();
+ interruptWait();
+ return VINF_SUCCESS;
+}
+
+
+int USBProxyBackendDarwin::releaseDevice(HostUSBDevice *aDevice)
+{
+ /*
+ * Check preconditions.
+ */
+ AssertReturn(aDevice, VERR_GENERAL_FAILURE);
+ AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
+
+ AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
+ LogFlowThisFunc(("aDevice=%s\n", aDevice->i_getName().c_str()));
+
+ Assert(aDevice->i_getUnistate() == kHostUSBDeviceState_ReleasingToHost);
+
+ devLock.release();
+ interruptWait();
+ return VINF_SUCCESS;
+}
+
+
+bool USBProxyBackendDarwin::isFakeUpdateRequired()
+{
+ return true;
+}
+
+
+int USBProxyBackendDarwin::wait(RTMSINTERVAL aMillies)
+{
+ SInt32 rc = CFRunLoopRunInMode(CFSTR(VBOX_IOKIT_MODE_STRING),
+ mWaitABitNextTime && aMillies >= 1000
+ ? 1.0 /* seconds */
+ : aMillies >= 5000 /* Temporary measure to poll for status changes (MSD). */
+ ? 5.0 /* seconds */
+ : aMillies / 1000.0,
+ true);
+ mWaitABitNextTime = rc != kCFRunLoopRunTimedOut;
+
+ return VINF_SUCCESS;
+}
+
+
+int USBProxyBackendDarwin::interruptWait(void)
+{
+ if (mServiceRunLoopRef)
+ CFRunLoopStop(mServiceRunLoopRef);
+ return 0;
+}
+
+
+PUSBDEVICE USBProxyBackendDarwin::getDevices(void)
+{
+ /* call iokit.cpp */
+ return DarwinGetUSBDevices();
+}
+
+
+void USBProxyBackendDarwin::serviceThreadInit(void)
+{
+ mServiceRunLoopRef = CFRunLoopGetCurrent();
+ mNotifyOpaque = DarwinSubscribeUSBNotifications();
+}
+
+
+void USBProxyBackendDarwin::serviceThreadTerm(void)
+{
+ DarwinUnsubscribeUSBNotifications(mNotifyOpaque);
+ mServiceRunLoopRef = NULL;
+}
+
+
+/**
+ * Wrapper called from iokit.cpp.
+ *
+ * @param pCur The USB device to free.
+ */
+void DarwinFreeUSBDeviceFromIOKit(PUSBDEVICE pCur)
+{
+ USBProxyBackend::freeDevice(pCur);
+}
+