Cleaned up debugging output, fixed bugs on shutdown and fixed reconnection issues in daemon
This commit is contained in:
parent
3ca7573177
commit
dbd033030a
12 changed files with 66 additions and 167 deletions
4
TODO
4
TODO
|
@ -73,6 +73,10 @@ Checklist
|
|||
|
||||
* check that uinput gets its timeout/update calls (send_rel_event)
|
||||
|
||||
* cleanup a lot of the log_trace() and other temporary debug output
|
||||
|
||||
* check that repeated wireless controller connects and disconnects work
|
||||
|
||||
|
||||
Stuff to do before 0.7.4 release:
|
||||
=================================
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
0.7.4
|
||||
0.8.0
|
|
@ -37,7 +37,6 @@ Controller::~Controller()
|
|||
void
|
||||
Controller::submit_msg(const XboxGenericMsg& msg)
|
||||
{
|
||||
log_trace();
|
||||
if (m_msg_cb)
|
||||
{
|
||||
m_msg_cb(msg);
|
||||
|
|
|
@ -33,8 +33,6 @@ ControllerThread::ControllerThread(ControllerPtr controller, const Options& opts
|
|||
m_processor(),
|
||||
m_controller(controller),
|
||||
m_oldrealmsg(),
|
||||
m_child_exec(opts.exec),
|
||||
m_pid(-1),
|
||||
m_timeout(opts.timeout),
|
||||
m_timeout_id(),
|
||||
m_timer(g_timer_new())
|
||||
|
@ -66,8 +64,6 @@ ControllerThread::on_message(const XboxGenericMsg& msg)
|
|||
{
|
||||
m_oldrealmsg = msg;
|
||||
|
||||
log_trace();
|
||||
|
||||
int msec_delta = static_cast<int>(g_timer_elapsed(m_timer, NULL) * 1000.0f);
|
||||
g_timer_reset(m_timer);
|
||||
|
||||
|
|
|
@ -42,9 +42,6 @@ private:
|
|||
|
||||
XboxGenericMsg m_oldrealmsg; /// last data read from the device
|
||||
|
||||
std::vector<std::string> m_child_exec;
|
||||
pid_t m_pid;
|
||||
|
||||
int m_timeout;
|
||||
guint m_timeout_id;
|
||||
GTimer* m_timer;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
USBController::USBController(libusb_device* dev) :
|
||||
m_dev(dev),
|
||||
m_handle(0),
|
||||
m_read_transfer(),
|
||||
m_usbpath(),
|
||||
m_usbid(),
|
||||
m_name()
|
||||
|
@ -77,6 +78,12 @@ USBController::USBController(libusb_device* dev) :
|
|||
|
||||
USBController::~USBController()
|
||||
{
|
||||
usb_cancel_read();
|
||||
if (m_read_transfer)
|
||||
{
|
||||
libusb_free_transfer(m_read_transfer);
|
||||
}
|
||||
|
||||
//libusb_release_interface(m_handle, 0);
|
||||
libusb_close(m_handle);
|
||||
}
|
||||
|
@ -102,33 +109,38 @@ USBController::get_name() const
|
|||
void
|
||||
USBController::usb_submit_read(int endpoint, int len)
|
||||
{
|
||||
log_debug("ep: " << endpoint << " len: " << len);
|
||||
assert(!m_read_transfer);
|
||||
|
||||
libusb_transfer* transfer = libusb_alloc_transfer(0);
|
||||
//log_debug("ep: " << endpoint << " len: " << len);
|
||||
|
||||
m_read_transfer = libusb_alloc_transfer(0);
|
||||
|
||||
uint8_t* data = static_cast<uint8_t*>(malloc(sizeof(uint8_t) * len));
|
||||
//FIXME: transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER;
|
||||
libusb_fill_interrupt_transfer(transfer, m_handle,
|
||||
m_read_transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER;
|
||||
libusb_fill_interrupt_transfer(m_read_transfer, m_handle,
|
||||
endpoint | LIBUSB_ENDPOINT_IN,
|
||||
data, len,
|
||||
&USBController::on_read_data_wrap, this,
|
||||
0); // timeout
|
||||
int ret;
|
||||
ret = libusb_submit_transfer(transfer);
|
||||
log_debug("libusb_submit_transfer: " << usb_strerror(ret));
|
||||
ret = libusb_submit_transfer(m_read_transfer);
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
raise_exception(std::runtime_error, "libusb_submit_transfer(): " << usb_strerror(ret));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
USBController::usb_cancel_read()
|
||||
{
|
||||
assert(!"implement me");
|
||||
assert(m_read_transfer);
|
||||
libusb_cancel_transfer(m_read_transfer);
|
||||
m_read_transfer = 0;
|
||||
}
|
||||
|
||||
void
|
||||
USBController::on_read_data(libusb_transfer *transfer)
|
||||
{
|
||||
log_trace();
|
||||
|
||||
assert(transfer);
|
||||
|
||||
// process data
|
||||
|
|
|
@ -31,6 +31,8 @@ protected:
|
|||
libusb_device* m_dev;
|
||||
libusb_device_handle* m_handle;
|
||||
|
||||
libusb_transfer* m_read_transfer;
|
||||
|
||||
std::string m_usbpath;
|
||||
std::string m_usbid;
|
||||
std::string m_name;
|
||||
|
|
|
@ -24,10 +24,8 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "log.hpp"
|
||||
#include "usb_helper.hpp"
|
||||
|
||||
// GUSBSource
|
||||
|
||||
// documentation at: http://library.gnome.org/devel/glib/2.28/
|
||||
USBGSource::USBGSource() :
|
||||
m_source_funcs(),
|
||||
m_source(),
|
||||
|
@ -54,7 +52,6 @@ USBGSource::USBGSource() :
|
|||
const libusb_pollfd** fds = libusb_get_pollfds(NULL);
|
||||
for(const libusb_pollfd** i = fds; *i != NULL; ++i)
|
||||
{
|
||||
log_debug("adding pollfd: " << (*i)->fd);
|
||||
on_usb_pollfd_added((*i)->fd, (*i)->events);
|
||||
}
|
||||
free(fds);
|
||||
|
@ -68,6 +65,8 @@ USBGSource::USBGSource() :
|
|||
|
||||
USBGSource::~USBGSource()
|
||||
{
|
||||
// get rid of the callbacks as they will be triggered by libusb_exit()
|
||||
libusb_set_pollfd_notifiers(NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -80,7 +79,6 @@ USBGSource::attach(GMainContext* context)
|
|||
void
|
||||
USBGSource::on_usb_pollfd_added(int fd, short events)
|
||||
{
|
||||
log_debug(fd << " " << events);
|
||||
GPollFD* gfd = new GPollFD;
|
||||
|
||||
gfd->fd = fd;
|
||||
|
@ -95,8 +93,6 @@ USBGSource::on_usb_pollfd_added(int fd, short events)
|
|||
void
|
||||
USBGSource::on_usb_pollfd_removed(int fd)
|
||||
{
|
||||
log_debug(fd);
|
||||
|
||||
// find the GPollFD that matched the given \a fd
|
||||
std::list<GPollFD*>::iterator it = m_pollfds.end();
|
||||
for(std::list<GPollFD*>::iterator i = m_pollfds.begin(); i != m_pollfds.end(); ++i)
|
||||
|
@ -119,41 +115,43 @@ USBGSource::on_usb_pollfd_removed(int fd)
|
|||
gboolean
|
||||
USBGSource::on_source_prepare(GSource* source, gint* timeout)
|
||||
{
|
||||
log_trace();
|
||||
|
||||
struct timeval tv;
|
||||
int ret = libusb_get_next_timeout(NULL, &tv);
|
||||
|
||||
log_debug("libusb_get_next_timeout(): " << ret);
|
||||
|
||||
if (ret == LIBUSB_SUCCESS)
|
||||
if (ret == 0) // no timeouts
|
||||
{
|
||||
// no timeout
|
||||
*timeout = -1;
|
||||
}
|
||||
else if (ret == 1) // timeout was returned
|
||||
{
|
||||
*timeout = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
// convert tv
|
||||
log_error("libusb_get_next_timeout() failed: " << usb_strerror(ret));
|
||||
*timeout = -1;
|
||||
}
|
||||
|
||||
// FALSE means the source isn't yet ready
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
USBGSource::on_source_check(GSource* source)
|
||||
{
|
||||
log_trace();
|
||||
|
||||
USBGSource* usb_source = reinterpret_cast<GUSBSource*>(source)->usb_source;
|
||||
log_debug("Number of PollFD: " << usb_source->m_pollfds.size());
|
||||
//log_debug("Number of PollFD: " << usb_source->m_pollfds.size());
|
||||
for(std::list<GPollFD*>::iterator i = usb_source->m_pollfds.begin(); i != usb_source->m_pollfds.end(); ++i)
|
||||
{
|
||||
log_debug("GSource GPollFD: " << (*i)->fd);
|
||||
log_debug("REvents: G_IO_OUT: " << ((*i)->revents & G_IO_OUT));
|
||||
log_debug(" G_IO_IN: " << ((*i)->revents & G_IO_IN));
|
||||
log_debug(" G_IO_PRI: " << ((*i)->revents & G_IO_PRI));
|
||||
log_debug(" G_IO_HUP: " << ((*i)->revents & G_IO_HUP));
|
||||
log_debug(" G_IO_ERR: " << ((*i)->revents & G_IO_ERR));
|
||||
if (false)
|
||||
{
|
||||
log_debug("GSource GPollFD: " << (*i)->fd);
|
||||
log_debug("REvents: G_IO_OUT: " << ((*i)->revents & G_IO_OUT));
|
||||
log_debug(" G_IO_IN: " << ((*i)->revents & G_IO_IN));
|
||||
log_debug(" G_IO_PRI: " << ((*i)->revents & G_IO_PRI));
|
||||
log_debug(" G_IO_HUP: " << ((*i)->revents & G_IO_HUP));
|
||||
log_debug(" G_IO_ERR: " << ((*i)->revents & G_IO_ERR));
|
||||
}
|
||||
|
||||
if ((*i)->revents)
|
||||
{
|
||||
|
@ -167,16 +165,13 @@ USBGSource::on_source_check(GSource* source)
|
|||
gboolean
|
||||
USBGSource::on_source_dispatch(GSource* source, GSourceFunc callback, gpointer userdata)
|
||||
{
|
||||
log_trace();
|
||||
return callback(userdata);
|
||||
}
|
||||
|
||||
gboolean
|
||||
USBGSource::on_source()
|
||||
{
|
||||
log_debug("libusb_handle_events()");
|
||||
libusb_handle_events(NULL);
|
||||
log_debug("libusb_handle_events() done");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
** Xbox360 USB Gamepad Userspace Driver
|
||||
** Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "wakeup_pipe.hpp"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdexcept>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "raise_exception.hpp"
|
||||
|
||||
WakeupPipe::WakeupPipe()
|
||||
{
|
||||
int ret = pipe(m_pipefd);
|
||||
if (ret < 0)
|
||||
{
|
||||
raise_exception(std::runtime_error, "pipe() failed: " << strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
WakeupPipe::get_read_fd() const
|
||||
{
|
||||
return m_pipefd[0];
|
||||
}
|
||||
|
||||
int
|
||||
WakeupPipe::get_write_fd() const
|
||||
{
|
||||
return m_pipefd[1];
|
||||
}
|
||||
|
||||
void
|
||||
WakeupPipe::send_wakeup()
|
||||
{
|
||||
char buf[1] = {0};
|
||||
ssize_t ret = write(get_write_fd(), buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
{
|
||||
raise_exception(std::runtime_error, "write() to pipe failed: " << strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
** Xbox360 USB Gamepad Userspace Driver
|
||||
** Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_XBOXDRV_WAKEUP_PIPE_HPP
|
||||
#define HEADER_XBOXDRV_WAKEUP_PIPE_HPP
|
||||
|
||||
class WakeupPipe
|
||||
{
|
||||
private:
|
||||
int m_pipefd[2];
|
||||
|
||||
public:
|
||||
WakeupPipe();
|
||||
|
||||
int get_read_fd() const;
|
||||
int get_write_fd() const;
|
||||
|
||||
void send_wakeup();
|
||||
|
||||
private:
|
||||
WakeupPipe(const WakeupPipe&);
|
||||
WakeupPipe& operator=(const WakeupPipe&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
|
@ -115,9 +115,14 @@ XboxdrvDaemon::~XboxdrvDaemon()
|
|||
assert(s_current);
|
||||
s_current = 0;
|
||||
|
||||
m_inactive_controllers.clear();
|
||||
|
||||
for(ControllerSlots::iterator i = m_controller_slots.begin(); i != m_controller_slots.end(); ++i)
|
||||
{
|
||||
(*i)->disconnect();
|
||||
if ((*i)->is_connected())
|
||||
{
|
||||
(*i)->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
udev_monitor_unref(m_monitor);
|
||||
|
@ -134,9 +139,10 @@ XboxdrvDaemon::cleanup_threads()
|
|||
if ((*i)->is_connected())
|
||||
{
|
||||
count += 1;
|
||||
// FIXME: we kill the thread in try_disconnect() but on_disconnect() needs it
|
||||
on_disconnect(*i);
|
||||
(*i)->disconnect();
|
||||
|
||||
// disconnect slot and put the controller back into the inactive group
|
||||
m_inactive_controllers.push_back((*i)->disconnect());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -490,12 +496,6 @@ XboxdrvDaemon::on_udev_data(GIOChannel* channel, GIOCondition condition)
|
|||
return true;
|
||||
}
|
||||
|
||||
gboolean
|
||||
XboxdrvDaemon::on_udev_data_wrap(GIOChannel* channel, GIOCondition condition, gpointer data)
|
||||
{
|
||||
return static_cast<XboxdrvDaemon*>(data)->on_udev_data(channel, condition);
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::check_thread_status()
|
||||
{
|
||||
|
@ -811,20 +811,10 @@ XboxdrvDaemon::on_disconnect(ControllerSlotPtr slot)
|
|||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
XboxdrvDaemon::on_wakeup_wrap(gpointer data)
|
||||
{
|
||||
log_info("wrapper called");
|
||||
return static_cast<XboxdrvDaemon*>(data)->on_wakeup();
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::wakeup()
|
||||
{
|
||||
log_info("received wakeup call");
|
||||
g_idle_add(&XboxdrvDaemon::on_wakeup_wrap, this);
|
||||
g_main_context_wakeup(NULL);
|
||||
log_info("idle_add called");
|
||||
}
|
||||
|
||||
std::string
|
||||
|
|
|
@ -96,12 +96,18 @@ private:
|
|||
|
||||
void wakeup();
|
||||
|
||||
private:
|
||||
bool on_wakeup();
|
||||
bool on_udev_data(GIOChannel* channel, GIOCondition condition);
|
||||
|
||||
private:
|
||||
static gboolean on_udev_data_wrap(GIOChannel* channel, GIOCondition condition, gpointer data);
|
||||
static gboolean on_wakeup_wrap(gpointer data);
|
||||
static gboolean on_wakeup_wrap(gpointer data) {
|
||||
return static_cast<XboxdrvDaemon*>(data)->on_wakeup();
|
||||
}
|
||||
|
||||
static gboolean on_udev_data_wrap(GIOChannel* channel, GIOCondition condition, gpointer data) {
|
||||
return static_cast<XboxdrvDaemon*>(data)->on_udev_data(channel, condition);
|
||||
}
|
||||
|
||||
private:
|
||||
XboxdrvDaemon(const XboxdrvDaemon&);
|
||||
|
|
Loading…
Reference in a new issue