diff options
Diffstat (limited to 'SDL_Core/src/components/transport_manager/src/usb/libusb/usb_handler.cc')
-rw-r--r-- | SDL_Core/src/components/transport_manager/src/usb/libusb/usb_handler.cc | 418 |
1 files changed, 0 insertions, 418 deletions
diff --git a/SDL_Core/src/components/transport_manager/src/usb/libusb/usb_handler.cc b/SDL_Core/src/components/transport_manager/src/usb/libusb/usb_handler.cc deleted file mode 100644 index 88c4ee1da..000000000 --- a/SDL_Core/src/components/transport_manager/src/usb/libusb/usb_handler.cc +++ /dev/null @@ -1,418 +0,0 @@ -/** - * \file usb_handler.cc - * \brief UsbHandler class source file. - * - * Copyright (c) 2013, Ford Motor Company - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Ford Motor Company nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <cstring> -#include <cstdlib> - -#include "transport_manager/usb/common.h" -#include "transport_manager/transport_adapter/transport_adapter_impl.h" - -namespace transport_manager { -namespace transport_adapter { - -class UsbHandler::ControlTransferSequenceState { - public: - ControlTransferSequenceState(class UsbHandler* usb_handler, - UsbControlTransferSequence* sequence, - PlatformUsbDevice* device); - ~ControlTransferSequenceState(); - void Finish(); - bool Finished() const { return finished_; } - UsbControlTransfer* CurrentTransfer(); - UsbControlTransfer* Next(); - UsbHandler* usb_handler() const { return usb_handler_; } - PlatformUsbDevice* device() const { return device_; } - - private: - UsbHandler* usb_handler_; - PlatformUsbDevice* device_; - bool finished_; - UsbControlTransferSequence* sequence_; - UsbControlTransferSequence::Transfers::const_iterator current_transfer_; -}; - -UsbHandler::UsbHandler() - : shutdown_requested_(false), - thread_(), - usb_device_listeners_(), - devices_(), - transfer_sequences_(), - device_handles_to_close_(), - libusb_context_(NULL), - arrived_callback_handle_(), - left_callback_handle_() {} - -UsbHandler::~UsbHandler() { - shutdown_requested_ = true; - if (libusb_context_ != 0) { - libusb_hotplug_deregister_callback(libusb_context_, - arrived_callback_handle_); - libusb_hotplug_deregister_callback(libusb_context_, left_callback_handle_); - } - pthread_join(thread_, 0); - LOG4CXX_INFO(logger_, "UsbHandler thread finished"); - if (libusb_context_) { - libusb_exit(libusb_context_); - libusb_context_ = 0; - } -} - -void UsbHandler::DeviceArrived(libusb_device* device_libusb) { - const uint8_t bus_number = libusb_get_bus_number(device_libusb); - const uint8_t device_address = libusb_get_device_address(device_libusb); - libusb_device_descriptor descriptor; - int libusb_ret = libusb_get_device_descriptor(device_libusb, &descriptor); - if (LIBUSB_SUCCESS != libusb_ret) { - LOG4CXX_ERROR(logger_, - "libusb_get_device_descriptor failed: " << libusb_ret); - return; - } - - libusb_device_handle* device_handle_libusb; - libusb_ret = libusb_open(device_libusb, &device_handle_libusb); - if (libusb_ret != LIBUSB_SUCCESS) { - LOG4CXX_ERROR(logger_, - "libusb_open failed: " << libusb_error_name(libusb_ret)); - return; - } - - int configuration; - libusb_ret = libusb_get_configuration(device_handle_libusb, &configuration); - if (LIBUSB_SUCCESS != libusb_ret) { - LOG4CXX_INFO( - logger_, - "libusb_get_configuration failed: " << libusb_error_name(libusb_ret)); - return; - } - - if (configuration != kUsbConfiguration) { - libusb_ret = libusb_set_configuration(device_handle_libusb, kUsbConfiguration); - if (LIBUSB_SUCCESS != libusb_ret) { - LOG4CXX_INFO( - logger_, - "libusb_set_configuration failed: " << libusb_error_name(libusb_ret)); - return; - } - } - - libusb_ret = libusb_claim_interface(device_handle_libusb, 0); - if (LIBUSB_SUCCESS != libusb_ret) { - LOG4CXX_INFO(logger_, "libusb_claim_interface failed: " - << libusb_error_name(libusb_ret)); - CloseDeviceHandle(device_handle_libusb); - return; - } - - PlatformUsbDevice* device(new PlatformUsbDevice(bus_number, device_address, - descriptor, device_libusb, - device_handle_libusb)); - devices_.push_back(device); - - for (std::list<UsbDeviceListener*>::iterator it = - usb_device_listeners_.begin(); - it != usb_device_listeners_.end(); ++it) { - (*it)->OnDeviceArrived(device); - } -} - -void UsbHandler::DeviceLeft(libusb_device* device_libusb) { - PlatformUsbDevice* device = NULL; - for (Devices::iterator it = devices_.begin(); it != devices_.end(); ++it) { - if ((*it)->GetLibusbDevice() == device_libusb) { - device = *it; - break; - } - } - if (NULL == device) { - return; - } - - for (std::list<UsbDeviceListener*>::iterator it = - usb_device_listeners_.begin(); - it != usb_device_listeners_.end(); ++it) { - (*it)->OnDeviceLeft(device); - } - - for (Devices::iterator it = devices_.begin(); it != devices_.end(); ++it) { - if ((*it)->GetLibusbDevice() == device_libusb) { - devices_.erase(it); - break; - } - } - - if (device->GetLibusbHandle()) { - libusb_release_interface(device->GetLibusbHandle(), 0); - CloseDeviceHandle(device->GetLibusbHandle()); - } - delete device; -} - -void UsbHandler::StartControlTransferSequence( - UsbControlTransferSequence* sequence, PlatformUsbDevice* device) { - TransferSequences::iterator it = transfer_sequences_.insert( - transfer_sequences_.end(), - new ControlTransferSequenceState(this, sequence, device)); - SubmitControlTransfer(*it); -} - -void UsbHandler::CloseDeviceHandle(libusb_device_handle* device_handle) { - device_handles_to_close_.push_back(device_handle); -} - -void* UsbHandlerThread(void* data) { - static_cast<UsbHandler*>(data)->Thread(); - return 0; -} - -int ArrivedCallback(libusb_context* context, libusb_device* device, - libusb_hotplug_event event, void* data) { - LOG4CXX_INFO(logger_, "libusb device arrived (bus number " - << static_cast<int>(libusb_get_bus_number(device)) - << ", device address " - << static_cast<int>( - libusb_get_device_address(device)) << ")"); - UsbHandler* usb_handler = static_cast<UsbHandler*>(data); - usb_handler->DeviceArrived(device); - return 0; -} - -int LeftCallback(libusb_context* context, libusb_device* device, - libusb_hotplug_event event, void* data) { - LOG4CXX_INFO(logger_, "libusb device left (bus number " - << static_cast<int>(libusb_get_bus_number(device)) - << ", device address " - << static_cast<int>( - libusb_get_device_address(device)) << ")"); - UsbHandler* usb_handler = static_cast<UsbHandler*>(data); - usb_handler->DeviceLeft(device); - return 0; -} - -TransportAdapter::Error UsbHandler::Init() { - int libusb_ret = libusb_init(&libusb_context_); - - if (LIBUSB_SUCCESS != libusb_ret) { - LOG4CXX_ERROR(logger_, "libusb_init failed: " << libusb_ret); - return TransportAdapter::FAIL; - } - - if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { - LOG4CXX_ERROR(logger_, "LIBUSB_CAP_HAS_HOTPLUG not supported"); - return TransportAdapter::FAIL; - } - - libusb_ret = libusb_hotplug_register_callback( - libusb_context_, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, - LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY, - LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, ArrivedCallback, this, - &arrived_callback_handle_); - - if (LIBUSB_SUCCESS != libusb_ret) { - LOG4CXX_ERROR(logger_, - "libusb_hotplug_register_callback failed: " << libusb_ret); - return TransportAdapter::FAIL; - } - - libusb_ret = libusb_hotplug_register_callback( - libusb_context_, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, - static_cast<libusb_hotplug_flag>(0), LIBUSB_HOTPLUG_MATCH_ANY, - LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LeftCallback, this, - &left_callback_handle_); - - if (LIBUSB_SUCCESS != libusb_ret) { - LOG4CXX_ERROR(logger_, - "libusb_hotplug_register_callback failed: " << libusb_ret); - return TransportAdapter::FAIL; - } - - const int thread_start_error = - pthread_create(&thread_, 0, &UsbHandlerThread, this); - if (0 == thread_start_error) { - LOG4CXX_INFO(logger_, "UsbHandler thread started"); - return TransportAdapter::OK; - } else { - LOG4CXX_ERROR(logger_, "USB device scanner thread start failed, error code " - << thread_start_error); - return TransportAdapter::FAIL; - } -} - -void UsbHandler::Thread() { - int completed = 0; - while (!shutdown_requested_) { - libusb_handle_events_completed(libusb_context_, &completed); - - for (TransferSequences::iterator it = transfer_sequences_.begin(); - it != transfer_sequences_.end();) { - ControlTransferSequenceState* sequence_state = *it; - if (sequence_state->Finished()) { - delete *it; - it = transfer_sequences_.erase(it); - } else { - ++it; - } - } - - for (std::list<libusb_device_handle*>::iterator it = - device_handles_to_close_.begin(); - it != device_handles_to_close_.end(); - it = device_handles_to_close_.erase(it)) { - libusb_close(*it); - } - } -} - -void UsbTransferSequenceCallback(libusb_transfer* transfer) { - UsbHandler::ControlTransferSequenceState* sequence_state = - static_cast<UsbHandler::ControlTransferSequenceState*>(transfer->user_data); - sequence_state->usb_handler()->ControlTransferCallback(transfer); -} - -void UsbHandler::SubmitControlTransfer( - ControlTransferSequenceState* sequence_state) { - UsbControlTransfer* transfer = sequence_state->CurrentTransfer(); - if (NULL == transfer) return; - - libusb_transfer* libusb_transfer = libusb_alloc_transfer(0); - if (0 == libusb_transfer) { - LOG4CXX_ERROR(logger_, "libusb_alloc_transfer failed"); - sequence_state->Finish(); - return; - } - - assert(transfer->Type() == UsbControlTransfer::VENDOR); - const libusb_request_type request_type = LIBUSB_REQUEST_TYPE_VENDOR; - - libusb_endpoint_direction endpoint_direction; - if (transfer->Direction() == UsbControlTransfer::IN) { - endpoint_direction = LIBUSB_ENDPOINT_IN; - } else if (transfer->Direction() == UsbControlTransfer::OUT) { - endpoint_direction = LIBUSB_ENDPOINT_OUT; - } else { - assert(0); - } - const uint8_t request = transfer->Request(); - const uint16_t value = transfer->Value(); - const uint16_t index = transfer->Index(); - const uint16_t length = transfer->Length(); - - unsigned char* buffer = - static_cast<unsigned char*>(malloc(length + LIBUSB_CONTROL_SETUP_SIZE)); - if (NULL == buffer) { - LOG4CXX_ERROR(logger_, "buffer allocation failed"); - libusb_free_transfer(libusb_transfer); - sequence_state->Finish(); - return; - } - - libusb_fill_control_setup(buffer, request_type | endpoint_direction, request, - value, index, length); - - if (0 != length && endpoint_direction == LIBUSB_ENDPOINT_OUT) { - const char* data = static_cast<UsbControlOutTransfer*>(transfer)->Data(); - memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, length); - } - libusb_fill_control_transfer( - libusb_transfer, sequence_state->device()->GetLibusbHandle(), buffer, - UsbTransferSequenceCallback, sequence_state, 0); - libusb_transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER; - - const int libusb_ret = libusb_submit_transfer(libusb_transfer); - if (LIBUSB_SUCCESS != libusb_ret) { - LOG4CXX_ERROR(logger_, "libusb_submit_transfer failed: " - << libusb_error_name(libusb_ret)); - libusb_free_transfer(libusb_transfer); - sequence_state->Finish(); - } -} - -void UsbHandler::ControlTransferCallback(libusb_transfer* transfer) { - ControlTransferSequenceState* sequence_state = - static_cast<ControlTransferSequenceState*>(transfer->user_data); - if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { - LOG4CXX_INFO(logger_, "USB control transfer completed"); - UsbControlTransfer* current_transfer = sequence_state->CurrentTransfer(); - bool submit_next = true; - if (current_transfer && - current_transfer->Direction() == UsbControlTransfer::IN) { - submit_next = - static_cast<UsbControlInTransfer*>(current_transfer) - ->OnCompleted(libusb_control_transfer_get_data(transfer)); - } - - sequence_state->Next(); - if (submit_next && !sequence_state->Finished()) { - SubmitControlTransfer(sequence_state); - } else { - sequence_state->Finish(); - } - } else { - LOG4CXX_ERROR(logger_, "USB control transfer failed: " << transfer->status); - sequence_state->Finish(); - } - libusb_free_transfer(transfer); -} - -UsbHandler::ControlTransferSequenceState::ControlTransferSequenceState( - UsbHandler* usb_handler, UsbControlTransferSequence* sequence, - PlatformUsbDevice* device) - : usb_handler_(usb_handler), - device_(device), - finished_(false), - sequence_(sequence), - current_transfer_(sequence->transfers().begin()) {} - -UsbHandler::ControlTransferSequenceState::~ControlTransferSequenceState() { - delete sequence_; -} - -UsbControlTransfer* UsbHandler::ControlTransferSequenceState::Next() { - if (finished_) return NULL; - if (++current_transfer_ == sequence_->transfers().end()) { - Finish(); - return NULL; - } else { - return *current_transfer_; - } -} - -UsbControlTransfer* UsbHandler::ControlTransferSequenceState::CurrentTransfer() { - return finished_ ? NULL : *current_transfer_; -} - -void UsbHandler::ControlTransferSequenceState::Finish() { finished_ = true; } - -} // namespace -} // namespace |