From e5caefb53e16c8cd8aa03d4d1e5cc19afc70774a Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 17 Mar 2018 01:17:40 +0100 Subject: [PATCH] Implementation of connected device enumerator --- include/f1x/aasdk/Error/Error.hpp | 2 + include/f1x/aasdk/Error/ErrorCode.hpp | 41 +++--- .../USB/ConnectedAccessoriesEnumerator.hpp | 58 ++++++++ .../USB/IConnectedAccessoriesEnumerator.hpp | 44 ++++++ include/f1x/aasdk/USB/USBHub.hpp | 1 - src/Error/Error.cpp | 10 ++ src/USB/ConnectedAccessoriesEnumerator.cpp | 134 ++++++++++++++++++ 7 files changed, 268 insertions(+), 22 deletions(-) create mode 100644 include/f1x/aasdk/USB/ConnectedAccessoriesEnumerator.hpp create mode 100644 include/f1x/aasdk/USB/IConnectedAccessoriesEnumerator.hpp create mode 100644 src/USB/ConnectedAccessoriesEnumerator.cpp diff --git a/include/f1x/aasdk/Error/Error.hpp b/include/f1x/aasdk/Error/Error.hpp index f9537b8..22275a6 100644 --- a/include/f1x/aasdk/Error/Error.hpp +++ b/include/f1x/aasdk/Error/Error.hpp @@ -41,6 +41,8 @@ public: bool operator!() const; bool operator==(const Error& other) const; + bool operator==(const ErrorCode& code) const; + bool operator!=(const ErrorCode& code) const; private: ErrorCode code_; diff --git a/include/f1x/aasdk/Error/ErrorCode.hpp b/include/f1x/aasdk/Error/ErrorCode.hpp index 75c5896..046118c 100644 --- a/include/f1x/aasdk/Error/ErrorCode.hpp +++ b/include/f1x/aasdk/Error/ErrorCode.hpp @@ -43,27 +43,26 @@ enum class ErrorCode DATA_SINK_COMMIT_OVERFLOW = 11, DATA_SINK_CONSUME_UNDERFLOW = 12, USB_AOAP_PROTOCOL_VERSION = 13, - USB_EMPTY_DEVICE_LIST = 14, - USB_AOAP_DEVICE_NOT_FOUND = 15, - SSL_READ_CERTIFICATE = 16, - SSL_READ_PRIVATE_KEY = 17, - SSL_METHOD = 18, - SSL_CONTEXT_CREATION = 19, - SSL_USE_CERTIFICATE = 20, - SSL_USE_PRIVATE_KEY = 21, - SSL_HANDLER_CREATION = 22, - SSL_READ_BIO_CREATION = 23, - SSL_WRITE_BIO_CREATION = 24, - SSL_HANDSHAKE = 25, - SSL_WRITE = 26, - SSL_READ = 27, - SSL_BIO_READ = 28, - SSL_BIO_WRITE = 29, - MESSENGER_INTERTWINED_CHANNELS = 30, - OPERATION_ABORTED = 31, - OPERATION_IN_PROGRESS = 32, - PARSE_PAYLOAD = 33, - TCP_TRANSFER = 34 + USB_AOAP_DEVICE_NOT_FOUND = 14, + SSL_READ_CERTIFICATE = 15, + SSL_READ_PRIVATE_KEY = 16, + SSL_METHOD = 17, + SSL_CONTEXT_CREATION = 18, + SSL_USE_CERTIFICATE = 19, + SSL_USE_PRIVATE_KEY = 20, + SSL_HANDLER_CREATION = 21, + SSL_READ_BIO_CREATION = 22, + SSL_WRITE_BIO_CREATION = 23, + SSL_HANDSHAKE = 24, + SSL_WRITE = 25, + SSL_READ = 26, + SSL_BIO_READ = 27, + SSL_BIO_WRITE = 28, + MESSENGER_INTERTWINED_CHANNELS = 29, + OPERATION_ABORTED = 30, + OPERATION_IN_PROGRESS = 31, + PARSE_PAYLOAD = 32, + TCP_TRANSFER = 33 }; } diff --git a/include/f1x/aasdk/USB/ConnectedAccessoriesEnumerator.hpp b/include/f1x/aasdk/USB/ConnectedAccessoriesEnumerator.hpp new file mode 100644 index 0000000..1a93f1c --- /dev/null +++ b/include/f1x/aasdk/USB/ConnectedAccessoriesEnumerator.hpp @@ -0,0 +1,58 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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; either version 3 of the License, or +* (at your option) any later version. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class ConnectedAccessoriesEnumerator: public IConnectedAccessoriesEnumerator, public std::enable_shared_from_this +{ +public: + ConnectedAccessoriesEnumerator(IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, IAccessoryModeQueryChainFactory& queryChainFactory); + + void enumerate(Promise::Pointer promise) override; + void cancel() override; + +private: + using std::enable_shared_from_this::shared_from_this; + void queryNextDevice(); + DeviceHandle getNextDeviceHandle(); + void reset(); + + IUSBWrapper& usbWrapper_; + boost::asio::io_service::strand strand_; + IAccessoryModeQueryChainFactory& queryChainFactory_; + IAccessoryModeQueryChain::Pointer queryChain_; + Promise::Pointer promise_; + DeviceListHandle deviceListHandle_; + DeviceList::iterator actualDeviceIter_; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/IConnectedAccessoriesEnumerator.hpp b/include/f1x/aasdk/USB/IConnectedAccessoriesEnumerator.hpp new file mode 100644 index 0000000..f0a5fc9 --- /dev/null +++ b/include/f1x/aasdk/USB/IConnectedAccessoriesEnumerator.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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; either version 3 of the License, or +* (at your option) any later version. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class IConnectedAccessoriesEnumerator +{ +public: + typedef std::shared_ptr Pointer; + typedef io::Promise Promise; + + virtual ~IConnectedAccessoriesEnumerator() = default; + virtual void enumerate(Promise::Pointer promise) = 0; + virtual void cancel() = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/USBHub.hpp b/include/f1x/aasdk/USB/USBHub.hpp index 1eaafed..ca05e84 100644 --- a/include/f1x/aasdk/USB/USBHub.hpp +++ b/include/f1x/aasdk/USB/USBHub.hpp @@ -19,7 +19,6 @@ #pragma once #include -#include #include #include #include diff --git a/src/Error/Error.cpp b/src/Error/Error.cpp index bbaa33e..b28c1db 100644 --- a/src/Error/Error.cpp +++ b/src/Error/Error.cpp @@ -65,6 +65,16 @@ bool Error::operator==(const Error& other) const return code_ == other.code_ && nativeCode_ == other.nativeCode_; } +bool Error::operator==(const ErrorCode& code) const +{ + return code_ == code; +} + +bool Error::operator!=(const ErrorCode& code) const +{ + return !operator==(code); +} + } } } diff --git a/src/USB/ConnectedAccessoriesEnumerator.cpp b/src/USB/ConnectedAccessoriesEnumerator.cpp new file mode 100644 index 0000000..75758fa --- /dev/null +++ b/src/USB/ConnectedAccessoriesEnumerator.cpp @@ -0,0 +1,134 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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; either version 3 of the License, or +* (at your option) any later version. + +* aasdk 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 aasdk. If not, see . +*/ + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +ConnectedAccessoriesEnumerator::ConnectedAccessoriesEnumerator(IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, IAccessoryModeQueryChainFactory& queryChainFactory) + : usbWrapper_(usbWrapper) + , strand_(ioService) + , queryChainFactory_(queryChainFactory) +{ + +} + +void ConnectedAccessoriesEnumerator::enumerate(Promise::Pointer promise) +{ + strand_.dispatch([this, self = this->shared_from_this(), promise = std::move(promise)]() mutable { + if(promise_ != nullptr) + { + promise->reject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS)); + } + else + { + promise_ = std::move(promise); + + auto result = usbWrapper_.getDeviceList(deviceListHandle_); + + if(result < 0) + { + promise_->reject(error::Error(error::ErrorCode::USB_LIST_DEVICES)); + } + else if(deviceListHandle_->empty()) + { + promise_->resolve(false); + } + else + { + actualDeviceIter_ = deviceListHandle_->begin(); + this->queryNextDevice(); + } + } + }); +} + +void ConnectedAccessoriesEnumerator::cancel() +{ + strand_.dispatch([this, self = this->shared_from_this()]() mutable { + if(queryChain_ != nullptr) + { + queryChain_->cancel(); + queryChain_.reset(); + } + }); +} + +void ConnectedAccessoriesEnumerator::queryNextDevice() +{ + auto deviceHandle = this->getNextDeviceHandle(); + + if(deviceHandle != nullptr) + { + queryChain_ = queryChainFactory_.create(); + auto queryChainPromise = IAccessoryModeQueryChain::Promise::defer(strand_); + + queryChainPromise->then([this, self = this->shared_from_this()](DeviceHandle) mutable { + promise_->resolve(true); + this->reset(); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + if(e != error::ErrorCode::OPERATION_ABORTED) + { + this->queryNextDevice(); + } + }); + + queryChain_->start(std::move(deviceHandle), std::move(queryChainPromise)); + } + else if(actualDeviceIter_ == deviceListHandle_->end()) + { + promise_->resolve(false); + this->reset(); + } +} + +DeviceHandle ConnectedAccessoriesEnumerator::getNextDeviceHandle() +{ + DeviceHandle handle; + + while(actualDeviceIter_ != deviceListHandle_->end()) + { + auto openResult = usbWrapper_.open(*actualDeviceIter_, handle); + ++actualDeviceIter_; + + if(openResult == 0) + { + break; + } + } + + return handle; +} + +void ConnectedAccessoriesEnumerator::reset() +{ + queryChain_.reset(); + deviceListHandle_.reset(); + actualDeviceIter_ = DeviceList::iterator(); + promise_.reset(); +} + +} +} +}