Monitor all HID++ reports on wireless device 1
Again, many things were done in this commit such as implementing an I/O queue, a mutex_queue, and implementing the hidpp::Report class. I'm expecting commits to be like this until I can get a clean codebase for the backend.
This commit is contained in:
parent
1de722b935
commit
6b895b3015
|
@ -12,11 +12,13 @@ add_executable(logid
|
|||
logid.cpp
|
||||
util.cpp
|
||||
DeviceMonitor.cpp
|
||||
backend/Error.cpp
|
||||
backend/raw/DeviceMonitor.cpp
|
||||
backend/raw/RawDevice.cpp
|
||||
backend/hidpp/Device.cpp
|
||||
backend/hidpp/Report.cpp
|
||||
backend/dj/Report.cpp)
|
||||
backend/dj/Report.cpp
|
||||
util/mutex_queue.h)
|
||||
|
||||
set_target_properties(logid PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
|
|
|
@ -102,9 +102,29 @@ void DeviceMonitor::stopAndDeleteDevice (const std::string &path, HIDPP::DeviceI
|
|||
void DeviceMonitor::addDevice(std::string path)
|
||||
{
|
||||
try {
|
||||
backend::hidpp::Device device(path, hidpp::DeviceIndex::DefaultDevice);
|
||||
|
||||
backend::hidpp::Device device(path, hidpp::DeviceIndex::WirelessDevice1);
|
||||
log_printf(DEBUG, "Detected HID++ device at %s", path.c_str());
|
||||
|
||||
backend::hidpp::EventHandler eventHandler;
|
||||
eventHandler.condition = [device](backend::hidpp::Report& report)->bool
|
||||
{
|
||||
return true;
|
||||
};
|
||||
eventHandler.callback = [device](backend::hidpp::Report& report)->void
|
||||
{
|
||||
log_printf(DEBUG, "Event on %s:%d", device.devicePath().c_str(),
|
||||
device.deviceIndex());
|
||||
for(auto& i : report.rawReport())
|
||||
printf("%02x ", i);
|
||||
printf("\n");
|
||||
};
|
||||
|
||||
device.addEventHandler("MONITOR_ALL", eventHandler);
|
||||
|
||||
std::thread([](backend::hidpp::Device device) { device.listen(); }, device).detach();
|
||||
|
||||
/* This is a temporary solution to avoid std::bad_function_call */
|
||||
while(true) {}
|
||||
}
|
||||
catch(backend::hidpp::Device::InvalidDevice &e)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace logid
|
|||
private:
|
||||
std::mutex devices_mutex;
|
||||
std::map<std::string, std::map<backend::hidpp::DeviceIndex, ConnectedDevice>> devices;
|
||||
backend::hidpp::EventHandler eventHandler;
|
||||
};
|
||||
|
||||
extern DeviceMonitor* finder;
|
||||
|
|
6
src/logid/backend/Error.cpp
Normal file
6
src/logid/backend/Error.cpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include "Error.h"
|
||||
|
||||
const char *logid::backend::TimeoutError::what() noexcept
|
||||
{
|
||||
return "Device timed out";
|
||||
}
|
16
src/logid/backend/Error.h
Normal file
16
src/logid/backend/Error.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef LOGID_BACKEND_ERROR_H
|
||||
#define LOGID_BACKEND_ERROR_H
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace logid {
|
||||
namespace backend {
|
||||
class TimeoutError: public std::exception
|
||||
{
|
||||
public:
|
||||
TimeoutError() = default;
|
||||
virtual const char* what() noexcept;
|
||||
};
|
||||
}}
|
||||
|
||||
#endif //LOGID_BACKEND_ERROR_H
|
15
src/logid/backend/defs.h
Normal file
15
src/logid/backend/defs.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef LOGID_BACKEND_DEFS_H
|
||||
#define LOGID_BACKEND_DEFS_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace logid::backend
|
||||
{
|
||||
struct RawEventHandler
|
||||
{
|
||||
std::function<bool(std::vector<uint8_t>& )> condition;
|
||||
std::function<void(std::vector<uint8_t>& )> callback;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //LOGID_BACKEND_DEFS_H
|
|
@ -1,3 +1,4 @@
|
|||
#include <assert.h>
|
||||
#include "Device.h"
|
||||
#include "Report.h"
|
||||
|
||||
|
@ -21,10 +22,67 @@ Device::InvalidDevice::Reason Device::InvalidDevice::code() const noexcept
|
|||
}
|
||||
|
||||
/// TODO: Initialize a single RawDevice for each path.
|
||||
Device::Device(std::string path, DeviceIndex index):
|
||||
Device::Device(const std::string& path, DeviceIndex index):
|
||||
raw_device (std::make_shared<raw::RawDevice>(path)), path (path), index (index)
|
||||
{
|
||||
supported_reports = getSupportedReports(raw_device->reportDescriptor());
|
||||
if(!supported_reports)
|
||||
throw InvalidDevice(InvalidDevice::NoHIDPPReport);
|
||||
}
|
||||
|
||||
// Pass all HID++ events with device index to this device.
|
||||
RawEventHandler rawEventHandler;
|
||||
rawEventHandler.condition = [index](std::vector<uint8_t>& report)->bool
|
||||
{
|
||||
return (report[Offset::Type] == Report::Short ||
|
||||
report[Offset::Type] == Report::Long) && (report[Offset::DeviceIndex] == index);
|
||||
};
|
||||
rawEventHandler.callback = [this](std::vector<uint8_t>& report)->void
|
||||
{
|
||||
Report _report(report);
|
||||
this->handleEvent(_report);
|
||||
};
|
||||
|
||||
raw_device->addEventHandler("DEV_" + std::to_string(index), rawEventHandler);
|
||||
}
|
||||
|
||||
void Device::addEventHandler(const std::string& nickname, EventHandler& handler)
|
||||
{
|
||||
auto it = event_handlers.find(nickname);
|
||||
assert(it == event_handlers.end());
|
||||
|
||||
event_handlers.emplace(nickname, handler);
|
||||
}
|
||||
|
||||
void Device::removeEventHandler(const std::string& nickname)
|
||||
{
|
||||
event_handlers.erase(nickname);
|
||||
}
|
||||
|
||||
void Device::handleEvent(Report& report)
|
||||
{
|
||||
for(auto& handler : event_handlers)
|
||||
if(handler.second.condition(report))
|
||||
handler.second.callback(report);
|
||||
}
|
||||
|
||||
Report Device::sendReport(Report& report)
|
||||
{
|
||||
switch(report.type())
|
||||
{
|
||||
case Report::Short:
|
||||
if(!(supported_reports & HIDPP_REPORT_SHORT_SUPPORTED))
|
||||
report.setType(Report::Long);
|
||||
break;
|
||||
case Report::Long:
|
||||
/* Report can be truncated, but that isn't a good idea. */
|
||||
assert(supported_reports & HIDPP_REPORT_LONG_SUPPORTED);
|
||||
}
|
||||
|
||||
auto raw_response = raw_device->sendReport(report.rawReport());
|
||||
return Report(raw_response);
|
||||
}
|
||||
|
||||
void Device::listen()
|
||||
{
|
||||
raw_device->listen();
|
||||
}
|
||||
|
|
|
@ -3,22 +3,21 @@
|
|||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include "../raw/RawDevice.h"
|
||||
#include "Report.h"
|
||||
#include "defs.h"
|
||||
|
||||
namespace logid::backend::hidpp
|
||||
namespace logid {
|
||||
namespace backend {
|
||||
namespace hidpp
|
||||
{
|
||||
enum DeviceIndex: uint8_t
|
||||
struct EventHandler
|
||||
{
|
||||
DefaultDevice = 0,
|
||||
WirelessDevice1 = 1,
|
||||
WirelessDevice2 = 2,
|
||||
WirelessDevice3 = 3,
|
||||
WirelessDevice4 = 4,
|
||||
WirelessDevice5 = 5,
|
||||
WirelessDevice6 = 6,
|
||||
CordedDevice = 0xff
|
||||
std::function<bool(Report&)> condition;
|
||||
std::function<void(Report&)> callback;
|
||||
};
|
||||
|
||||
class Device
|
||||
{
|
||||
public:
|
||||
|
@ -35,17 +34,30 @@ namespace logid::backend::hidpp
|
|||
virtual Reason code() const noexcept;
|
||||
private:
|
||||
Reason _reason;
|
||||
|
||||
};
|
||||
Device(std::string path, DeviceIndex index);
|
||||
|
||||
Device(const std::string& path, DeviceIndex index);
|
||||
|
||||
std::string devicePath() const { return path; }
|
||||
DeviceIndex deviceIndex() const { return index; }
|
||||
|
||||
void listen(); // Runs asynchronously
|
||||
void stopListening();
|
||||
|
||||
void addEventHandler(const std::string& nickname, EventHandler& handler);
|
||||
void removeEventHandler(const std::string& nickname);
|
||||
|
||||
Report sendReport(Report& report);
|
||||
|
||||
void handleEvent(Report& report);
|
||||
private:
|
||||
std::shared_ptr<logid::backend::raw::RawDevice> raw_device;
|
||||
std::shared_ptr<raw::RawDevice> raw_device;
|
||||
std::string path;
|
||||
DeviceIndex index;
|
||||
uint8_t supported_reports;
|
||||
|
||||
std::map<std::string, EventHandler> event_handlers;
|
||||
};
|
||||
}
|
||||
} } }
|
||||
|
||||
#endif //LOGID_HIDPP_DEVICE_H
|
|
@ -1,5 +1,6 @@
|
|||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include "Report.h"
|
||||
|
||||
using namespace logid::backend::hidpp;
|
||||
|
@ -80,4 +81,80 @@ uint8_t hidpp::getSupportedReports(std::vector<uint8_t>&& rdesc)
|
|||
ret |= HIDPP_REPORT_LONG_SUPPORTED;
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
const char *Report::InvalidReportID::what() const noexcept
|
||||
{
|
||||
return "Invalid report ID";
|
||||
}
|
||||
|
||||
const char *Report::InvalidReportLength::what() const noexcept
|
||||
{
|
||||
return "Invalid report length";
|
||||
}
|
||||
|
||||
Report::Report(Report::Type type, DeviceIndex device_index,
|
||||
uint8_t feature_index, uint8_t function, uint8_t sw_id)
|
||||
{
|
||||
assert(!(function & functionMask));
|
||||
assert(!(sw_id & swIdMask));
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case Short:
|
||||
_data.resize(HeaderLength + ShortParamLength);
|
||||
break;
|
||||
case Long:
|
||||
_data.resize(HeaderLength + LongParamLength);
|
||||
break;
|
||||
default:
|
||||
throw InvalidReportID();
|
||||
}
|
||||
|
||||
_data[Offset::Type] = type;
|
||||
_data[Offset::DeviceIndex] = device_index;
|
||||
_data[Offset::Feature] = feature_index;
|
||||
_data[Offset::Function] = (function & functionMask) << 4 | (sw_id & swIdMask);
|
||||
}
|
||||
|
||||
Report::Report(const std::vector<uint8_t>& data)
|
||||
{
|
||||
_data = data;
|
||||
|
||||
switch(_data[Offset::Type])
|
||||
{
|
||||
case Short:
|
||||
_data.resize(HeaderLength + ShortParamLength);
|
||||
break;
|
||||
case Long:
|
||||
_data.resize(HeaderLength + LongParamLength);
|
||||
break;
|
||||
default:
|
||||
throw InvalidReportID();
|
||||
}
|
||||
}
|
||||
|
||||
void Report::setType(Report::Type type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case Short:
|
||||
_data.resize(HeaderLength + ShortParamLength);
|
||||
break;
|
||||
case Long:
|
||||
_data.resize(HeaderLength + LongParamLength);
|
||||
break;
|
||||
default:
|
||||
throw InvalidReportID();
|
||||
}
|
||||
|
||||
_data[Offset::Type] = type;
|
||||
}
|
||||
|
||||
void Report::setParams(const std::vector<uint8_t>& _params)
|
||||
{
|
||||
assert(_params.size() <= _data.size()-HeaderLength);
|
||||
|
||||
for(std::size_t i = 0; i < _params.size(); i++)
|
||||
_data[Offset::Parameters + i] = _params[i];
|
||||
}
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
|
||||
#include <cstdint>
|
||||
#include "../raw/RawDevice.h"
|
||||
#include "Device.h"
|
||||
|
||||
#define LOGID_HIDPP_SW_ID 0x0f
|
||||
#include "defs.h"
|
||||
|
||||
/* Some devices only support a subset of these reports */
|
||||
#define HIDPP_REPORT_SHORT_SUPPORTED 1U
|
||||
|
@ -15,6 +13,16 @@
|
|||
namespace logid::backend::hidpp
|
||||
{
|
||||
uint8_t getSupportedReports(std::vector<uint8_t>&& rdesc);
|
||||
|
||||
namespace Offset
|
||||
{
|
||||
static constexpr uint8_t Type = 0;
|
||||
static constexpr uint8_t DeviceIndex = 1;
|
||||
static constexpr uint8_t Feature = 2;
|
||||
static constexpr uint8_t Function = 3;
|
||||
static constexpr uint8_t Parameters = 4;
|
||||
}
|
||||
|
||||
class Report
|
||||
{
|
||||
public:
|
||||
|
@ -24,30 +32,43 @@ namespace logid::backend::hidpp
|
|||
Long = 0x11
|
||||
};
|
||||
|
||||
class InvalidReportID: std::exception
|
||||
class InvalidReportID: public std::exception
|
||||
{
|
||||
InvalidReportID();
|
||||
public:
|
||||
InvalidReportID() = default;
|
||||
virtual const char* what() const noexcept;
|
||||
};
|
||||
|
||||
class InvalidReportLength: std::exception
|
||||
class InvalidReportLength: public std::exception
|
||||
{
|
||||
InvalidReportLength();
|
||||
public:
|
||||
InvalidReportLength() = default;;
|
||||
virtual const char* what() const noexcept;
|
||||
};
|
||||
|
||||
static constexpr std::size_t MaxDataLength = 32;
|
||||
static constexpr std::size_t MaxDataLength = 20;
|
||||
static constexpr uint8_t swIdMask = 0x0f;
|
||||
static constexpr uint8_t functionMask = 0x0f;
|
||||
|
||||
Report(uint8_t report_id, const uint8_t* data, std::size_t length);
|
||||
Report(std::vector<uint8_t> data);
|
||||
Report(Type type, DeviceIndex device_index,
|
||||
uint8_t feature_index,
|
||||
uint8_t function,
|
||||
uint8_t sw_id);
|
||||
explicit Report(const std::vector<uint8_t>& data);
|
||||
|
||||
Type type() const;
|
||||
Type type() const { return static_cast<Type>(_data[Offset::Type]); };
|
||||
void setType(Report::Type type);
|
||||
|
||||
logid::backend::hidpp::DeviceIndex deviceIndex();
|
||||
std::vector<uint8_t>::const_iterator paramBegin() const { return _data.begin() + Offset::Parameters; }
|
||||
std::vector<uint8_t>::const_iterator paramEnd() const { return _data.end(); }
|
||||
void setParams(const std::vector<uint8_t>& _params);
|
||||
|
||||
logid::backend::hidpp::DeviceIndex deviceIndex()
|
||||
{
|
||||
return static_cast<DeviceIndex>(_data[Offset::DeviceIndex]);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> rawReport () const { return _data; }
|
||||
|
||||
private:
|
||||
static constexpr std::size_t HeaderLength = 4;
|
||||
std::vector<uint8_t> _data;
|
||||
|
|
24
src/logid/backend/hidpp/defs.h
Normal file
24
src/logid/backend/hidpp/defs.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef LOGID_HIDPP_DEFS_H
|
||||
#define LOGID_HIDPP_DEFS_H
|
||||
|
||||
#define LOGID_HIDPP_SOFTWARE_ID 1
|
||||
|
||||
namespace logid::backend::hidpp
|
||||
{
|
||||
enum DeviceIndex: uint8_t
|
||||
{
|
||||
DefaultDevice = 0,
|
||||
WirelessDevice1 = 1,
|
||||
WirelessDevice2 = 2,
|
||||
WirelessDevice3 = 3,
|
||||
WirelessDevice4 = 4,
|
||||
WirelessDevice5 = 5,
|
||||
WirelessDevice6 = 6,
|
||||
CordedDevice = 0xff
|
||||
};
|
||||
|
||||
static constexpr std::size_t ShortParamLength = 3;
|
||||
static constexpr std::size_t LongParamLength = 16;
|
||||
}
|
||||
|
||||
#endif //LOGID_HIDPP_DEFS_H
|
|
@ -1,9 +1,11 @@
|
|||
#include "RawDevice.h"
|
||||
#include "../Error.h"
|
||||
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
#define MAX_DATA_LENGTH 32
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
@ -76,29 +78,43 @@ RawDevice::~RawDevice()
|
|||
}
|
||||
}
|
||||
|
||||
void RawDevice::sendReport(std::vector<uint8_t> report)
|
||||
std::vector<uint8_t> RawDevice::sendReport(const std::vector<uint8_t>& report)
|
||||
{
|
||||
_sendReport(std::move(report));
|
||||
std::packaged_task<std::vector<uint8_t>()> task(
|
||||
[=]() {
|
||||
_sendReport(report);
|
||||
std::vector<uint8_t> response;
|
||||
_readReport(response, MAX_DATA_LENGTH);
|
||||
return response;
|
||||
});
|
||||
|
||||
/* If the listener will stop, handle I/O manually.
|
||||
* Otherwise, push to queue and wait for result. */
|
||||
if(continue_listen)
|
||||
{
|
||||
auto f = task.get_future();
|
||||
write_queue.push(&task);
|
||||
return f.get();
|
||||
}
|
||||
else
|
||||
return task.get_future().get();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> RawDevice::readReport(std::size_t maxDataLength)
|
||||
{
|
||||
return _readReport(maxDataLength);
|
||||
}
|
||||
|
||||
void RawDevice::_sendReport(std::vector<uint8_t> report)
|
||||
int RawDevice::_sendReport(const std::vector<uint8_t>& report)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(dev_io);
|
||||
int ret = ::write(fd, report.data(), report.size());
|
||||
if(ret == -1)
|
||||
throw std::system_error(errno, std::system_category(), "_sendReport write failed");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> RawDevice::_readReport(std::size_t maxDataLength)
|
||||
int RawDevice::_readReport(std::vector<uint8_t>& report, std::size_t maxDataLength)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(dev_io);
|
||||
int ret;
|
||||
std::vector<uint8_t> report(maxDataLength);
|
||||
report.resize(maxDataLength);
|
||||
|
||||
timeval timeout = { duration_cast<milliseconds>(HIDPP_IO_TIMEOUT).count(),
|
||||
duration_cast<microseconds>(HIDPP_IO_TIMEOUT).count() };
|
||||
|
@ -133,7 +149,10 @@ std::vector<uint8_t> RawDevice::_readReport(std::size_t maxDataLength)
|
|||
throw std::system_error(errno, std::system_category(), "_readReport read pipe failed");
|
||||
}
|
||||
|
||||
return report;
|
||||
if(0 == ret)
|
||||
throw backend::TimeoutError();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void RawDevice::interruptRead()
|
||||
|
@ -144,4 +163,62 @@ void RawDevice::interruptRead()
|
|||
|
||||
// Ensure I/O has halted
|
||||
std::lock_guard<std::mutex> lock(dev_io);
|
||||
}
|
||||
}
|
||||
|
||||
void RawDevice::listen()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(listening);
|
||||
|
||||
continue_listen = true;
|
||||
while(continue_listen)
|
||||
{
|
||||
while(!write_queue.empty())
|
||||
{
|
||||
auto task = write_queue.front();
|
||||
(*task)();
|
||||
write_queue.pop();
|
||||
}
|
||||
std::vector<uint8_t> report;
|
||||
_readReport(report, MAX_DATA_LENGTH);
|
||||
std::thread([this](std::vector<uint8_t> report) {
|
||||
this->handleEvent(report);
|
||||
}, report).detach();
|
||||
}
|
||||
|
||||
continue_listen = false;
|
||||
}
|
||||
|
||||
void RawDevice::stopListener()
|
||||
{
|
||||
continue_listen = false;
|
||||
interruptRead();
|
||||
}
|
||||
|
||||
void RawDevice::addEventHandler(const std::string &nickname, RawEventHandler &handler)
|
||||
{
|
||||
auto it = event_handlers.find(nickname);
|
||||
assert(it == event_handlers.end());
|
||||
event_handlers.emplace(nickname, handler);
|
||||
}
|
||||
|
||||
void RawDevice::removeEventHandler(const std::string &nickname)
|
||||
{
|
||||
event_handlers.erase(nickname);
|
||||
}
|
||||
|
||||
void RawDevice::handleEvent(std::vector<uint8_t> &report)
|
||||
{
|
||||
for(auto& handler : event_handlers)
|
||||
if(handler.second.condition(report))
|
||||
handler.second.callback(report);
|
||||
}
|
||||
|
||||
bool RawDevice::isListening()
|
||||
{
|
||||
bool ret = listening.try_lock();
|
||||
|
||||
if(ret)
|
||||
listening.unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -4,10 +4,18 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
#include <future>
|
||||
|
||||
#include "../defs.h"
|
||||
#include "../../util/mutex_queue.h"
|
||||
|
||||
#define HIDPP_IO_TIMEOUT std::chrono::seconds(2)
|
||||
|
||||
namespace logid::backend::raw
|
||||
namespace logid {
|
||||
namespace backend {
|
||||
namespace raw
|
||||
{
|
||||
class RawDevice
|
||||
{
|
||||
|
@ -18,12 +26,18 @@ namespace logid::backend::raw
|
|||
std::vector<uint8_t> reportDescriptor() const { return rdesc; }
|
||||
|
||||
/// TODO: Process reports in a queue.
|
||||
void sendReport(std::vector<uint8_t> report);
|
||||
std::vector<uint8_t> readReport(std::size_t maxDataLength);
|
||||
|
||||
std::vector<uint8_t> sendReport(const std::vector<uint8_t>& report);
|
||||
void interruptRead();
|
||||
|
||||
void listen();
|
||||
void stopListener();
|
||||
bool isListening();
|
||||
|
||||
void addEventHandler(const std::string& nickname, RawEventHandler& handler);
|
||||
void removeEventHandler(const std::string& nickname);
|
||||
|
||||
private:
|
||||
std::mutex dev_io;
|
||||
std::mutex dev_io, listening;
|
||||
std::string path;
|
||||
int fd;
|
||||
int dev_pipe[2];
|
||||
|
@ -32,10 +46,17 @@ namespace logid::backend::raw
|
|||
std::string name;
|
||||
std::vector<uint8_t> rdesc;
|
||||
|
||||
std::atomic<bool> continue_listen;
|
||||
|
||||
std::map<std::string, backend::RawEventHandler> event_handlers;
|
||||
void handleEvent(std::vector<uint8_t>& report);
|
||||
|
||||
/* These will only be used internally and processed with a queue */
|
||||
void _sendReport(std::vector<uint8_t> report);
|
||||
std::vector<uint8_t> _readReport(std::size_t maxDataLength);
|
||||
int _sendReport(const std::vector<uint8_t>& report);
|
||||
int _readReport(std::vector<uint8_t>& report, std::size_t maxDataLength);
|
||||
|
||||
mutex_queue<std::packaged_task<std::vector<uint8_t>()>*> write_queue;
|
||||
};
|
||||
}
|
||||
}}}
|
||||
|
||||
#endif //LOGID_BACKEND_RAWDEVICE_H
|
37
src/logid/util/mutex_queue.h
Normal file
37
src/logid/util/mutex_queue.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef MUTEX_QUEUE_H
|
||||
#define MUTEX_QUEUE_H
|
||||
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
|
||||
template<typename data>
|
||||
class mutex_queue
|
||||
{
|
||||
public:
|
||||
mutex_queue<data>() = default;
|
||||
bool empty()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
return _queue.empty();
|
||||
}
|
||||
data& front()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
return _queue.front();
|
||||
}
|
||||
void push(const data& _data)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
_queue.push(_data);
|
||||
}
|
||||
void pop()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
_queue.pop();
|
||||
}
|
||||
private:
|
||||
std::queue<data> _queue;
|
||||
std::mutex _mutex;
|
||||
};
|
||||
|
||||
#endif //MUTEX_QUEUE_H
|
Loading…
Reference in New Issue
Block a user