summaryrefslogtreecommitdiff
path: root/SDL_Core/src/components/transport_manager/src/usb/libusb/usb_connection.cc
diff options
context:
space:
mode:
Diffstat (limited to 'SDL_Core/src/components/transport_manager/src/usb/libusb/usb_connection.cc')
-rw-r--r--SDL_Core/src/components/transport_manager/src/usb/libusb/usb_connection.cc313
1 files changed, 0 insertions, 313 deletions
diff --git a/SDL_Core/src/components/transport_manager/src/usb/libusb/usb_connection.cc b/SDL_Core/src/components/transport_manager/src/usb/libusb/usb_connection.cc
deleted file mode 100644
index 00c792de8..000000000
--- a/SDL_Core/src/components/transport_manager/src/usb/libusb/usb_connection.cc
+++ /dev/null
@@ -1,313 +0,0 @@
-/**
- * \file usb_connection.cc
- * \brief UsbConnection 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 <iomanip>
-
-#include <libusb/libusb.h>
-
-#include "transport_manager/usb/libusb/usb_connection.h"
-#include "transport_manager/transport_adapter/transport_adapter_impl.h"
-
-namespace transport_manager {
-namespace transport_adapter {
-
-UsbConnection::UsbConnection(const DeviceUID& device_uid,
- const ApplicationHandle& app_handle,
- TransportAdapterController* controller,
- const UsbHandlerSptr& usb_handler,
- PlatformUsbDevice* device)
- : device_uid_(device_uid),
- app_handle_(app_handle),
- controller_(controller),
- usb_handler_(usb_handler),
- libusb_device_(device->GetLibusbDevice()),
- device_handle_(device->GetLibusbHandle()),
- in_endpoint_(0),
- in_endpoint_max_packet_size_(0),
- out_endpoint_(0),
- out_endpoint_max_packet_size_(0),
- in_buffer_(0),
- in_transfer_(0),
- out_transfer_(0),
- out_messages_(),
- current_out_message_(),
- out_messages_mutex_(),
- bytes_sent_(0),
- disconnecting_(false),
- waiting_in_transfer_cancel_(false),
- waiting_out_transfer_cancel_(false) {
- pthread_mutex_init(&out_messages_mutex_, 0);
-}
-
-UsbConnection::~UsbConnection() {
- Finalise();
- if (in_transfer_) {
- libusb_free_transfer(in_transfer_);
- }
- if (in_buffer_) {
- delete[] in_buffer_;
- }
- pthread_mutex_destroy(&out_messages_mutex_);
-}
-
-void InTransferCallback(libusb_transfer* transfer) {
- static_cast<UsbConnection*>(transfer->user_data)->OnInTransfer(transfer);
-}
-
-void OutTransferCallback(libusb_transfer* transfer) {
- static_cast<UsbConnection*>(transfer->user_data)->OnOutTransfer(transfer);
-}
-
-bool UsbConnection::PostInTransfer() {
- libusb_fill_bulk_transfer(in_transfer_, device_handle_, in_endpoint_,
- in_buffer_, in_endpoint_max_packet_size_,
- InTransferCallback, this, 0);
- const int libusb_ret = libusb_submit_transfer(in_transfer_);
- if (LIBUSB_SUCCESS != libusb_ret) {
- LOG4CXX_ERROR(logger_, "libusb_submit_transfer failed: "
- << libusb_error_name(libusb_ret));
- return false;
- }
- return true;
-}
-
-void UsbConnection::OnInTransfer(libusb_transfer* transfer) {
- if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
- if (logger_->isTraceEnabled()) {
- std::ostringstream hexdata;
- for (int i = 0; i < transfer->actual_length; ++i) {
- hexdata << " " << std::hex << std::setw(2) << std::setfill('0')
- << (int)transfer->buffer[i];
- }
- LOG4CXX_TRACE(logger_, "USB incoming transfer, size:"
- << transfer->actual_length
- << ", data:" << hexdata.str());
- }
- RawMessageSptr data(new protocol_handler::RawMessage(
- 0, 0, in_buffer_, transfer->actual_length));
- controller_->DataReceiveDone(device_uid_, app_handle_, data);
- } else {
- LOG4CXX_ERROR(logger_, "USB transfer failed: " << transfer->status);
- controller_->DataReceiveFailed(device_uid_, app_handle_,
- DataReceiveError());
- }
- if (disconnecting_) {
- waiting_in_transfer_cancel_ = false;
- } else {
- if (!PostInTransfer()) {
- controller_->ConnectionAborted(device_uid_, app_handle_,
- CommunicationError());
- Disconnect();
- }
- }
-}
-
-void UsbConnection::PopOutMessage() {
- bytes_sent_ = 0;
- if (out_messages_.empty()) {
- current_out_message_.reset();
- } else {
- current_out_message_ = out_messages_.front();
- out_messages_.pop_front();
- PostOutTransfer();
- }
-}
-
-bool UsbConnection::PostOutTransfer() {
- out_transfer_ = libusb_alloc_transfer(0);
- if (0 == out_transfer_) {
- LOG4CXX_ERROR(logger_, "libusb_alloc_transfer failed");
- return false;
- }
- libusb_fill_bulk_transfer(out_transfer_, device_handle_, out_endpoint_,
- current_out_message_->data() + bytes_sent_,
- current_out_message_->data_size() - bytes_sent_,
- OutTransferCallback, this, 0);
- const int libusb_ret = libusb_submit_transfer(out_transfer_);
- if (LIBUSB_SUCCESS != libusb_ret) {
- LOG4CXX_ERROR(logger_, "libusb_submit_transfer failed: "
- << libusb_error_name(libusb_ret));
- controller_->ConnectionAborted(device_uid_, app_handle_,
- CommunicationError());
- Disconnect();
- return false;
- }
- return true;
-}
-
-void UsbConnection::OnOutTransfer(libusb_transfer* transfer) {
- pthread_mutex_lock(&out_messages_mutex_);
- if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
- bytes_sent_ += transfer->actual_length;
- if (bytes_sent_ == current_out_message_->data_size()) {
- LOG4CXX_INFO(logger_, "USB out transfer, data sent: "
- << current_out_message_.get());
- controller_->DataSendDone(device_uid_, app_handle_, current_out_message_);
- PopOutMessage();
- }
- } else {
- LOG4CXX_ERROR(logger_, "USB transfer failed: " << transfer->status);
- controller_->DataSendFailed(device_uid_, app_handle_, current_out_message_,
- DataSendError());
- PopOutMessage();
- }
- libusb_free_transfer(transfer);
- out_transfer_ = 0;
- pthread_mutex_unlock(&out_messages_mutex_);
- waiting_out_transfer_cancel_ = false;
-}
-
-TransportAdapter::Error UsbConnection::SendData(RawMessageSptr message) {
- if (disconnecting_) {
- return TransportAdapter::BAD_STATE;
- }
- pthread_mutex_lock(&out_messages_mutex_);
- if (current_out_message_.valid()) {
- out_messages_.push_back(message);
- } else {
- current_out_message_ = message;
- if (!PostOutTransfer()) {
- controller_->DataSendFailed(device_uid_, app_handle_, message,
- DataSendError());
- }
- }
- pthread_mutex_unlock(&out_messages_mutex_);
- return TransportAdapter::OK;
-}
-
-void UsbConnection::Finalise() {
- LOG4CXX_INFO(logger_, "Finalise USB connection " << device_uid_);
- pthread_mutex_lock(&out_messages_mutex_);
- disconnecting_ = true;
- if (out_transfer_) {
- waiting_out_transfer_cancel_ = true;
- if (LIBUSB_SUCCESS != libusb_cancel_transfer(out_transfer_)) {
- waiting_out_transfer_cancel_ = false;
- }
- }
- if (in_transfer_) {
- waiting_in_transfer_cancel_ = true;
- if (LIBUSB_SUCCESS != libusb_cancel_transfer(in_transfer_)) {
- waiting_in_transfer_cancel_ = false;
- }
- }
- for (std::list<RawMessageSptr>::iterator it = out_messages_.begin();
- it != out_messages_.end(); it = out_messages_.erase(it)) {
- controller_->DataSendFailed(device_uid_, app_handle_, *it, DataSendError());
- }
- pthread_mutex_unlock(&out_messages_mutex_);
-
- while (waiting_in_transfer_cancel_ || waiting_out_transfer_cancel_) {
- pthread_yield();
- }
-}
-
-TransportAdapter::Error UsbConnection::Disconnect() {
- Finalise();
- LOG4CXX_INFO(logger_, "USB disconnect done " << device_uid_);
- controller_->DisconnectDone(device_uid_, app_handle_);
- return TransportAdapter::OK;
-}
-
-bool UsbConnection::Init() {
- if (!FindEndpoints()) {
- return false;
- }
-
- in_buffer_ = new unsigned char[in_endpoint_max_packet_size_];
- if (0 == in_buffer_) {
- LOG4CXX_ERROR(logger_, "in buffer allocation failed (size "
- << in_endpoint_max_packet_size_ << ")");
- return false;
- }
-
- in_transfer_ = libusb_alloc_transfer(0);
- if (0 == in_transfer_) {
- LOG4CXX_ERROR(logger_, "libusb_alloc_transfer failed");
- return false;
- }
-
- controller_->ConnectDone(device_uid_, app_handle_);
- if (!PostInTransfer()) {
- controller_->ConnectionAborted(device_uid_, app_handle_,
- CommunicationError());
- return true;
- }
-
- return true;
-}
-
-bool UsbConnection::FindEndpoints() {
- struct libusb_config_descriptor* config;
- const int libusb_ret =
- libusb_get_active_config_descriptor(libusb_device_, &config);
- if (LIBUSB_SUCCESS != libusb_ret) {
- LOG4CXX_ERROR(logger_, "libusb_get_active_config_descriptor failed: "
- << libusb_error_name(libusb_ret));
- return false;
- }
-
- bool find_in_endpoint = true;
- bool find_out_endpoint = true;
-
- for (int i = 0; i < config->bNumInterfaces; ++i) {
- const libusb_interface& interface = config->interface[i];
- for (int i = 0; i < interface.num_altsetting; ++i) {
- const libusb_interface_descriptor& iface_desc = interface.altsetting[i];
- for (int i = 0; i < iface_desc.bNumEndpoints; ++i) {
- const libusb_endpoint_descriptor& endpoint_desc =
- iface_desc.endpoint[i];
-
- const uint8_t endpoint_dir =
- endpoint_desc.bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK;
- if (find_in_endpoint && endpoint_dir == LIBUSB_ENDPOINT_IN) {
- in_endpoint_ = endpoint_desc.bEndpointAddress;
- in_endpoint_max_packet_size_ = endpoint_desc.wMaxPacketSize;
- find_in_endpoint = false;
- } else if (find_out_endpoint && endpoint_dir == LIBUSB_ENDPOINT_OUT) {
- out_endpoint_ = endpoint_desc.bEndpointAddress;
- out_endpoint_max_packet_size_ = endpoint_desc.wMaxPacketSize;
- find_out_endpoint = false;
- }
- }
- }
- }
- libusb_free_config_descriptor(config);
-
- return !(find_in_endpoint || find_out_endpoint);
-}
-
-} // namespace transport_adapter
-} // namespace transport_manager