From dc88807020644f12924d1f61229d7414f150d2bc Mon Sep 17 00:00:00 2001
From: Ingo Ruhnke <grumbel@gmx.de>
Date: Wed, 24 Nov 2010 07:02:29 +0100
Subject: [PATCH] Some more chatpad  related tools

---
 chatpad/SConstruct   |   6 +
 chatpad/chatpad.py   |  24 ++++
 chatpad/chatpad2.cpp |   4 +-
 chatpad/chatpad4.cpp | 259 +++++++++++++++++++++++++++++++++++++++++++
 chatpad/usbreset.cpp |  32 ++++++
 5 files changed, 323 insertions(+), 2 deletions(-)
 create mode 100755 chatpad/chatpad.py
 create mode 100644 chatpad/chatpad4.cpp
 create mode 100644 chatpad/usbreset.cpp

diff --git a/chatpad/SConstruct b/chatpad/SConstruct
index b1486f8..e74a6b7 100644
--- a/chatpad/SConstruct
+++ b/chatpad/SConstruct
@@ -10,5 +10,11 @@ env.Program("chatpad3", ["chatpad3.cpp"])
 env = Environment(CXXFLAGS=["-Werror", "-Wall", "-g", "-O0"], LIBS=["usb-1.0", "boost_thread"])
 env.Program("reset", ["reset.cpp"])
 
+env = Environment(CXXFLAGS=["-Werror", "-Wall", "-g", "-O0"], LIBS=["usb-1.0", "boost_thread"])
+env.Program("chatpad4", ["chatpad4.cpp"])
+
+env = Environment(CXXFLAGS=["-Werror", "-Wall", "-g", "-O0"], LIBS=["usb-1.0", "boost_thread"])
+env.Program("usbreset", ["usbreset.cpp"])
+
 # EOF #
 
diff --git a/chatpad/chatpad.py b/chatpad/chatpad.py
new file mode 100755
index 0000000..caaca7f
--- /dev/null
+++ b/chatpad/chatpad.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+import usb
+import sys
+import time
+ 
+# find our device
+dev = usb.core.find(idVendor=0x045e, idProduct=0x028e)
+ 
+# was it found?
+if dev is None:
+    raise ValueError('Device not found')
+
+dev.set_configuration()
+
+print dev
+print dir(dev)
+
+while True:
+    # Get data from brequest 0x32
+    # ret = dev.ctrl_transfer(0xC0, 0x32, 0x0, 0x0, 10)
+    pass
+
+# EOF #
diff --git a/chatpad/chatpad2.cpp b/chatpad/chatpad2.cpp
index 52a6095..4917791 100644
--- a/chatpad/chatpad2.cpp
+++ b/chatpad/chatpad2.cpp
@@ -291,11 +291,11 @@ public:
         break;
 
       case 0x01: // lb
-        ctrl_msg(0x05);
+        ctrl_msg(0x08);
         break;
 
       case 0x02: // rb
-        ctrl_msg(0x06);
+        ctrl_msg(0x09);
         break;
 
       case 0x04: // guide
diff --git a/chatpad/chatpad4.cpp b/chatpad/chatpad4.cpp
new file mode 100644
index 0000000..d109428
--- /dev/null
+++ b/chatpad/chatpad4.cpp
@@ -0,0 +1,259 @@
+#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>
+
+class Main
+{
+private:
+  libusb_context*       m_ctx;
+  libusb_device_handle* m_handle;
+
+  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),
+    m_running(false)
+  {}
+
+  ~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 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 init_device_handle()
+  {
+    m_handle = libusb_open_device_with_vid_pid(m_ctx, 0x045e, 0x028e);
+
+    set_configuration();
+
+    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;
+
+    m_running = true;
+  }
+
+  void usb_send(uint8_t  reqtype, 
+                uint8_t  request, 
+                uint16_t value,
+                uint16_t index,
+                uint16_t length,
+                unsigned char* data,
+                unsigned int timeout)
+  {
+    usleep(100000);
+
+    std::cout << "send: " 
+              << boost::format("%02x %02x %04x %04x %04x") % int(reqtype) % int(request) % int(value) % int(index) % int(length)
+              << " { ";
+    for(int i = 0; i < length; ++i)
+    {
+      std::cout << boost::format("%02x ") % int(data[i]);
+    }
+    std::cout << " }" << std::endl;
+
+    int ret;
+    ret = libusb_control_transfer(m_handle, 
+                                  reqtype,
+                                  request,
+                                  value,
+                                  index,
+                                  data,
+                                  length,
+                                  0       // timeout
+      );
+
+    if (ret < 0)
+    {
+      std::cout << "ctrl_msg: " << ret << '"' << strerror(-ret) << '"' << std::endl;
+    }
+    std::cout << std::endl;
+  }
+
+  void usb_receive(uint8_t  reqtype, 
+                   uint8_t  request, 
+                   uint16_t value,
+                   uint16_t index,
+                   uint16_t length,
+                   unsigned int timeout)
+  {
+    usleep(100000);
+
+    std::cout << "recv: " 
+              << boost::format("%02x %02x %04x %04x %04x") % int(reqtype) % int(request) % int(value) % int(index) % int(length)
+              << " { ";
+
+    unsigned char buf[1024] = { 0 };
+    int ret;
+    ret = libusb_control_transfer(m_handle, 
+                                  reqtype,
+                                  request,
+                                  value,
+                                  index,
+                                  buf,
+                                  length,
+                                  0       // timeout
+      );
+
+    if (ret < 0)
+    {
+      std::cout << "ctrl_msg: " << ret << '"' << strerror(-ret) << '"' << std::endl;
+    }
+    else
+    {
+      for(int i = 0; i < ret; ++i)
+      {
+        std::cout << boost::format("%02x ") % int(buf[i]);
+      }
+      std::cout << " }" << std::endl;
+    }
+
+    std::cout << std::endl;
+  }
+
+  void run()
+  {
+    init_libusb();
+    init_device_handle();
+
+    if (true)
+    {
+      // my controller (seems constant):
+      // 49 4b 00 00 17 b7 e8 06 39 02 ca 90 55 21 01 33 00 00 80 02 5e 04 8e 02 03 00 01 01 29
+      // usb logs:
+      // 49 4b 00 00 17 e7 d9 1d 50 02 20 85 55 21 01 33 00 00 80 02 5e 04 8e 02 03 00 01 01 c5
+      //                ^^^^^^^^^^^    ^^^^^                                                 ^^
+      usb_receive(0xC1, 0x81, 0x5B17, 0x0103, 0x001D, 0);
+
+      {
+        unsigned char data[] = { 
+          0x09, 0x40, 0x00, 0x00, 0x1C, 0xDC, 0xA6, 0xB3,
+          0xEF, 0x84, 0x3A, 0x2C, 0x8C, 0xB6, 0x57, 0xCC,
+          0x09, 0xC7, 0x5E, 0x2F, 0x1B, 0x64, 0x58, 0x19,
+          0xC6, 0x48, 0xED, 0x45, 0x37, 0xB7, 0xB5, 0x61,
+          0xAA, 0x4C
+        };
+        usb_send(0x41, 0x82, 0x0003, 0x0103, 0x0022, data, 0);
+      }
+
+      // gives 00 00 or 01 00 or 02 00 
+      usb_receive(0xC1, 0x86, 0x0000, 0x0103, 0x0002, 0);
+
+      // gives 00 00 or 01 00 or 02 00 
+      usb_receive(0xC1, 0x86, 0x0000, 0x0103, 0x0002, 0);
+
+      usb_receive(0xC1, 0x83, 0x5C28, 0x0103, 0x002E, 0);
+
+      {
+        unsigned char data[] = { 
+        };
+
+        usb_send(0x41, 0x84, 0x0003, 0x0103, 0x0000, data, 0);
+      }
+
+      {
+        unsigned char data[] = { 
+          0x09, 0x41, 0x00, 0x00, 0x10, 0xBB, 0x4D, 0x42,
+          0xA3, 0x40, 0x63, 0x24, 0x26, 0xD8, 0x10, 0x06,
+          0x54, 0x47, 0xB2, 0x2F, 0xF7, 0x81
+        };
+
+        usb_send(0x41, 0x87, 0x0003, 0x0103, 0x0016, data, 0);
+      }
+    }
+
+    usb_receive(0xC1, 0x86, 0x0000, 0x0103, 0x0002, 0); 
+    usb_receive(0xC1, 0x86, 0x0000, 0x0103, 0x0002, 0);
+    usb_receive(0xC1, 0x83, 0x5C10, 0x0103, 0x0016, 0);
+    usb_receive(0xC0, 0x01, 0x0000, 0x0000, 0x0004, 0);
+
+    usb_send(0x40, 0xa9, 0xa30c, 0x4423, 0x0000, NULL, 0);
+    usb_send(0x40, 0xa9, 0x2344, 0x7f23, 0x0000, NULL, 0);
+    usb_send(0x40, 0xa9, 0x5839, 0x6832, 0x0000, NULL, 0);
+
+    usb_receive(0xC0, 0xA1, 0x0000, 0xE416, 0x0002, 0);
+    {
+      unsigned char data[] = { 0x01, 0x02 };
+      usb_send(0x40, 0xA1, 0x0000, 0xE416, 0x0002, data, 0);
+    }
+
+    libusb_close(m_handle);
+    libusb_exit(m_ctx);
+  }
+};
+
+int main(int argc, char* argv[])
+{
+  try 
+  {
+    Main app;
+    app.run();
+  }
+  catch(const std::exception& err)
+  {
+    std::cout << "Error: " << err.what() << std::endl;
+  }
+
+  return 0;
+}
+
+/* EOF */
diff --git a/chatpad/usbreset.cpp b/chatpad/usbreset.cpp
new file mode 100644
index 0000000..ceb7edc
--- /dev/null
+++ b/chatpad/usbreset.cpp
@@ -0,0 +1,32 @@
+#include <libusb-1.0/libusb.h>
+#include <iostream>
+#include <stdexcept>
+
+int main()
+{
+  libusb_context*       ctx;
+  libusb_device_handle* handle;
+
+  if (libusb_init(&ctx) != 0)
+  {
+    throw std::runtime_error("Libusb went wrong");
+  }
+  else
+  {
+    libusb_set_debug(ctx, 3);
+
+    handle = libusb_open_device_with_vid_pid(ctx, 0x045e, 0x028e);
+
+    int ret = libusb_reset_device(handle);
+
+    std::cout << "ret: " << ret << std::endl;
+
+    libusb_close(handle);
+
+    libusb_exit(ctx);
+
+    return 0;
+  }
+}
+
+/* EOF */