diff --git a/chatpad/SConstruct b/chatpad/SConstruct index d293270..b1486f8 100644 --- a/chatpad/SConstruct +++ b/chatpad/SConstruct @@ -1,10 +1,13 @@ -env = Environment(CXXFLAGS=["-Werror", "-Wall"], LIBS=["usb", "boost_thread"]) +env = Environment(CXXFLAGS=["-Werror", "-Wall", "-g", "-O0"], LIBS=["usb", "boost_thread"]) env.Program("chatpad", ["chatpad.cpp"]) -env = Environment(CXXFLAGS=["-Werror", "-Wall"], LIBS=["usb-1.0", "boost_thread"]) +env = Environment(CXXFLAGS=["-Werror", "-Wall", "-g", "-O0"], LIBS=["usb-1.0", "boost_thread"]) env.Program("chatpad2", ["chatpad2.cpp"]) -env = Environment(CXXFLAGS=["-Werror", "-Wall"], LIBS=["usb-1.0", "boost_thread"]) +env = Environment(CXXFLAGS=["-Werror", "-Wall", "-g", "-O0"], LIBS=["usb-1.0", "boost_thread"]) +env.Program("chatpad3", ["chatpad3.cpp"]) + +env = Environment(CXXFLAGS=["-Werror", "-Wall", "-g", "-O0"], LIBS=["usb-1.0", "boost_thread"]) env.Program("reset", ["reset.cpp"]) # EOF # diff --git a/chatpad/chatpad2.cpp b/chatpad/chatpad2.cpp index 44a3ad9..0807e31 100644 --- a/chatpad/chatpad2.cpp +++ b/chatpad/chatpad2.cpp @@ -15,12 +15,15 @@ private: uint8_t old_buttons; uint8_t old_dpad; + bool m_running; + public: Main() : m_ctx(0), m_handle(0), old_buttons(0), - old_dpad(0) + old_dpad(0), + m_running(false) {} ~Main() @@ -42,6 +45,8 @@ public: { m_handle = libusb_open_device_with_vid_pid(m_ctx, 0x045e, 0x028e); + set_configuration(); + std::cout << "handle: " << m_handle << std::endl; if (!m_handle) { @@ -53,6 +58,39 @@ public: err = libusb_claim_interface(m_handle, 0); std::cout << "Claim: " << err << std::endl; + + m_running = true; + } + + void set_configuration() + { + old_buttons = 0; + old_dpad = 0; + + if (m_running) + { + libusb_release_interface(m_handle, 0); + libusb_release_interface(m_handle, 2); + } + + int ret = libusb_set_configuration(m_handle, 1); + + switch(ret) + { + case 0: + std::cout << "set_configuration(): success" << std::endl; + break; + + default: + std::cout << "set_configuration(): " << ret << std::endl; + break; + } + + if (m_running) + { + libusb_claim_interface(m_handle, 0); + libusb_claim_interface(m_handle, 2); + } } void reset() @@ -60,9 +98,13 @@ public: std::cout << "reset()" << std::endl; libusb_reset_device(m_handle); libusb_close(m_handle); + libusb_exit(m_ctx); m_handle = 0; - sleep(1); - init_device_handle(); + m_ctx = 0; + old_buttons = 0; + old_dpad = 0; + + execl("./chatpad2", "./chatpad2", NULL); } void ctrl_msg(uint8_t value) @@ -153,6 +195,9 @@ public: { callback(data.get()); } + + // if (endpoint == 6) + // std::cout << "Clear Halt: " << libusb_clear_halt(m_handle, endpoint) << std::endl; } break; @@ -172,6 +217,10 @@ public: std::cout << "read_thread: no device" << std::endl; break; + case LIBUSB_ERROR_OTHER: // happens on reset + std::cout << "read_thread: other error" << std::endl; + break; + default: std::cout << "read_thread: unknown: " << ret << std::endl; break; @@ -194,21 +243,26 @@ public: switch(dpad) { case 0x04: // left + ctrl_msg(0x08); break; case 0x08: // right + ctrl_msg(0x09); break; case 0x01: // up + ctrl_msg(0x0a); break; case 0x02: // down + ctrl_msg(0x0b); break; case 0x20: // back break; case 0x10: // start + set_configuration(); break; case 0x40: // left stick @@ -245,7 +299,7 @@ public: break; case 0x04: // guide - ctrl_msg(0x17); + reset(); break; } } diff --git a/chatpad/chatpad3.cpp b/chatpad/chatpad3.cpp new file mode 100644 index 0000000..244a079 --- /dev/null +++ b/chatpad/chatpad3.cpp @@ -0,0 +1,201 @@ +#include <boost/thread.hpp> +#include <boost/format.hpp> +#include <boost/function.hpp> +#include <boost/scoped_array.hpp> +#include <libusb-1.0/libusb.h> +#include <iostream> +#include <stdexcept> +#include <stdlib.h> + +class Main +{ +private: + libusb_context* m_ctx; + libusb_device_handle* m_handle; + +public: + Main() : + m_ctx(0), + m_handle(0) + {} + + ~Main() + { + } + + void init_libusb() + { + if (libusb_init(&m_ctx) != 0) + { + throw std::runtime_error("Libusb went wrong"); + } + + std::cout << "Debug to max" << std::endl; + libusb_set_debug(m_ctx, 3); + } + + void init_device_handle() + { + m_handle = libusb_open_device_with_vid_pid(m_ctx, 0x045e, 0x028e); + + std::cout << "handle: " << m_handle << std::endl; + if (!m_handle) + { + throw std::runtime_error("Couldn't find controller"); + } + + int err = libusb_claim_interface(m_handle, 2); + std::cout << "Claim: " << err << std::endl; + + err = libusb_claim_interface(m_handle, 0); + std::cout << "Claim: " << err << std::endl; + } + + void ctrl_msg(uint8_t value) + { + int ret = libusb_control_transfer(m_handle, + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_INTERFACE, + LIBUSB_REQUEST_GET_STATUS, + value, 0x02, NULL, 0, 0); + std::cout << "ctrl_msg: " << ret << boost::format(" %02x") % int(value) << std::endl; + } + + static void callback_wrap(libusb_transfer* transfer) + { + static_cast<Main*>(transfer->user_data)->callback(transfer); + } + + void callback(libusb_transfer* transfer) + { + if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { + std::cout << "data transfer not completed: " << transfer->status << std::endl; + } + + unsigned char* data = transfer->buffer; + std::cout << "callback(" << transfer->actual_length << "): "; + for(int i = 0; i < transfer->actual_length; ++i) + { + std::cout << boost::format("0x%02x ") % int(data[i]); + } + std::cout << std::endl; + + // done with the transfer, so clean it up + // libusb_free_transfer(transfer); + + // request more data + request_controller_data(LIBUSB_ENDPOINT_ADDRESS_MASK & transfer->endpoint); + } + + static void control_callback_wrap(libusb_transfer* transfer) + { + static_cast<Main*>(transfer->user_data)->control_callback(transfer); + } + + void control_callback(libusb_transfer* transfer) + { + + } + + void request_controller_data(int endpoint) + { + libusb_transfer* transfer = libusb_alloc_transfer(0); + if (!transfer) + { + std::cout << "Couldn't alloc transfer" << std::endl; + } + + unsigned char* buffer = static_cast<unsigned char*>(malloc(8+32)); + + libusb_fill_interrupt_transfer(transfer, + m_handle, + endpoint | LIBUSB_ENDPOINT_IN, + buffer, // buffer + 8+32, // length, + &Main::callback_wrap, + this, // userdata + 0 // timeout + ); + + transfer->flags = + LIBUSB_TRANSFER_FREE_BUFFER | + LIBUSB_TRANSFER_FREE_TRANSFER; + + int ret = libusb_submit_transfer(transfer); + if (ret != 0) + { + std::cout << "Error with libusb_submit_transfer: " << ret << std::endl; + } + } + + void request_control(unsigned char value) + { + libusb_transfer* transfer = libusb_alloc_transfer(0); + if (!transfer) + { + std::cout << "Couldn't alloc transfer" << std::endl; + } + + unsigned char* buffer = static_cast<unsigned char*>(malloc(LIBUSB_CONTROL_SETUP_SIZE)); + libusb_fill_control_transfer(transfer, m_handle, buffer, + &Main::control_callback_wrap, + this, + 0); + + libusb_fill_control_setup(buffer, + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_INTERFACE, + LIBUSB_REQUEST_GET_STATUS, + value, + 2, + 0); + + transfer->flags = + LIBUSB_TRANSFER_FREE_BUFFER | + LIBUSB_TRANSFER_FREE_TRANSFER; + + int ret = libusb_submit_transfer(transfer); + if (ret != 0) + { + std::cout << "Error with libusb_submit_transfer: " << ret << std::endl; + } + } + + void main_loop() + { + request_controller_data(1); + request_controller_data(6); + request_control(0x1f); + request_control(0x1b); + while(true) + { + std::cout << "Handle events: " << libusb_handle_events(m_ctx) << std::endl; + } + } + + void run() + { + init_libusb(); + init_device_handle(); + + main_loop(); + + libusb_close(m_handle); + libusb_exit(m_ctx); + } +}; + +int main() +{ + try + { + Main app; + app.run(); + } + catch(const std::exception& err) + { + std::cout << "Error: " << err.what() << std::endl; + } + + return 0; +} + +/* EOF */