HID event-input debugging
Adding more debugEvents-enabled log output to HDI input
This commit is contained in:
parent
96cce67040
commit
6366dea197
3 changed files with 104 additions and 30 deletions
12
3rdparty/hidapi/hidparser/hidparse.c
vendored
12
3rdparty/hidapi/hidparser/hidparse.c
vendored
|
@ -184,8 +184,8 @@ int hid_parse_reportdesc(uint8_t* rdesc_buf, uint32_t rdesc_size, hid_item** ite
|
||||||
uint8_t type = (pfx >> 2) & 0x3; /* bits 3-2 */
|
uint8_t type = (pfx >> 2) & 0x3; /* bits 3-2 */
|
||||||
uint8_t tag = pfx >> 4;
|
uint8_t tag = pfx >> 4;
|
||||||
|
|
||||||
// fprintf(stderr, "short item: size=%d, bytes=%d, type = %d, tag=%d\n",
|
// fprintf(stderr, "short item: size=%d, bytes=%d, type = %d, tag=%d\n",
|
||||||
// size, bytes, type, tag);
|
// size, bytes, type, tag);
|
||||||
|
|
||||||
/* If it's a main item */
|
/* If it's a main item */
|
||||||
if (type == 0)
|
if (type == 0)
|
||||||
|
@ -194,7 +194,7 @@ int hid_parse_reportdesc(uint8_t* rdesc_buf, uint32_t rdesc_size, hid_item** ite
|
||||||
{
|
{
|
||||||
case HID_COLLECTION_ITEM:
|
case HID_COLLECTION_ITEM:
|
||||||
{
|
{
|
||||||
//fprintf(stderr, "opening collection\n");
|
// fprintf(stderr, "opening collection\n");
|
||||||
uint8_t flags = read_uint(size, p);
|
uint8_t flags = read_uint(size, p);
|
||||||
hid_item* col = build_collection(flags);
|
hid_item* col = build_collection(flags);
|
||||||
if (!current_collection) {
|
if (!current_collection) {
|
||||||
|
@ -212,7 +212,7 @@ int hid_parse_reportdesc(uint8_t* rdesc_buf, uint32_t rdesc_size, hid_item** ite
|
||||||
}
|
}
|
||||||
|
|
||||||
case HID_END_COLLECTION_ITEM:
|
case HID_END_COLLECTION_ITEM:
|
||||||
//fprintf(stderr, "closing collection\n");
|
// fprintf(stderr, "closing collection\n");
|
||||||
assert(current_collection);
|
assert(current_collection);
|
||||||
current_collection = current_collection->parent;
|
current_collection = current_collection->parent;
|
||||||
break;
|
break;
|
||||||
|
@ -226,6 +226,8 @@ int hid_parse_reportdesc(uint8_t* rdesc_buf, uint32_t rdesc_size, hid_item** ite
|
||||||
|
|
||||||
for (i=0; i<report_count; ++i) {
|
for (i=0; i<report_count; ++i) {
|
||||||
hid_item* item = build_item(tag, flags, ¤t_state);
|
hid_item* item = build_item(tag, flags, ¤t_state);
|
||||||
|
// fprintf(stderr, "adding: %d report:%d bits:%d\n", item->type,
|
||||||
|
// item->report_id, item->report_size);
|
||||||
append_item(current_collection, item);
|
append_item(current_collection, item);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -270,10 +272,12 @@ int hid_parse_reportdesc(uint8_t* rdesc_buf, uint32_t rdesc_size, hid_item** ite
|
||||||
|
|
||||||
case HID_REPORT_SIZE_ITEM:
|
case HID_REPORT_SIZE_ITEM:
|
||||||
current_state.report_size = read_uint(size, p);
|
current_state.report_size = read_uint(size, p);
|
||||||
|
//fprintf(stderr, "item size is:%d\n", current_state.report_size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HID_REPORT_COUNT_ITEM:
|
case HID_REPORT_COUNT_ITEM:
|
||||||
report_count = read_uint(size, p);
|
report_count = read_uint(size, p);
|
||||||
|
//fprintf(stderr, "item count is:%d\n", report_count);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HID_POP_ITEM:
|
case HID_POP_ITEM:
|
||||||
|
|
|
@ -507,11 +507,14 @@ bool FGReportSetting::Test()
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* hexTable = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
|
||||||
std::string FGReportSetting::reportBytes(const std::string& moduleName) const
|
std::string FGReportSetting::reportBytes(const std::string& moduleName) const
|
||||||
{
|
{
|
||||||
FGNasalSys *nas = (FGNasalSys *)globals->get_subsystem("nasal");
|
FGNasalSys *nas = globals->get_subsystem<FGNasalSys>();
|
||||||
if (!nas) {
|
if (!nas) {
|
||||||
return std::string();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
naRef module = nas->getModule(moduleName.c_str());
|
naRef module = nas->getModule(moduleName.c_str());
|
||||||
|
@ -526,13 +529,38 @@ std::string FGReportSetting::reportBytes(const std::string& moduleName) const
|
||||||
}
|
}
|
||||||
|
|
||||||
naRef result = nas->call(func, 0, 0, naNil());
|
naRef result = nas->call(func, 0, 0, naNil());
|
||||||
if (!naIsString(result)) {
|
if (naIsString(result)) {
|
||||||
return std::string();
|
size_t len = naStr_len(result);
|
||||||
|
char* bytes = naStr_data(result);
|
||||||
|
return std::string(bytes, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t len = naStr_len(result);
|
if (naIsVector(result)) {
|
||||||
char* bytes = naStr_data(result);
|
int len = naVec_size(result);
|
||||||
return std::string(bytes, len);
|
std::string s;
|
||||||
|
for (int b=0; b < len; ++b) {
|
||||||
|
int num = naNumValue(naVec_get(result, b)).num;
|
||||||
|
s.push_back(static_cast<char>(num));
|
||||||
|
}
|
||||||
|
|
||||||
|
// can't access FGInputDevice here to check debugEvents flag
|
||||||
|
#if 0
|
||||||
|
std::ostringstream byteString;
|
||||||
|
|
||||||
|
for (int i=0; i<s.size(); ++i) {
|
||||||
|
uint8_t uc = static_cast<uint8_t>(s[i]);
|
||||||
|
byteString << hexTable[uc >> 4];
|
||||||
|
byteString << hexTable[uc & 0x0f];
|
||||||
|
byteString << " ";
|
||||||
|
}
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "report bytes: (" << s.size() << ") " << byteString.str());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
SG_LOG(SG_INPUT, SG_DEV_WARN, "bad return data from report setting");
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGReportSetting::valueChanged(SGPropertyNode * node)
|
void FGReportSetting::valueChanged(SGPropertyNode * node)
|
||||||
|
|
|
@ -34,6 +34,9 @@
|
||||||
#include <simgear/misc/strutils.hxx>
|
#include <simgear/misc/strutils.hxx>
|
||||||
#include <simgear/io/lowlevel.hxx>
|
#include <simgear/io/lowlevel.hxx>
|
||||||
|
|
||||||
|
//#define HID_INPUT_DEBUG 1
|
||||||
|
|
||||||
|
const char* hexTable = "0123456789ABCDEF";
|
||||||
|
|
||||||
namespace HID
|
namespace HID
|
||||||
{
|
{
|
||||||
|
@ -102,6 +105,10 @@ namespace HID
|
||||||
AD_CharacterReport = 0x2B,
|
AD_CharacterReport = 0x2B,
|
||||||
AD_DisplayData = 0x2C,
|
AD_DisplayData = 0x2C,
|
||||||
AD_DisplayStatus = 0x2D,
|
AD_DisplayStatus = 0x2D,
|
||||||
|
AD_Rows = 0x35,
|
||||||
|
AD_Columns = 0x36,
|
||||||
|
AD_7SegmentDirectMap = 0x43,
|
||||||
|
AD_14SegmentDirectMap = 0x45,
|
||||||
AD_DisplayBrightness = 0x46,
|
AD_DisplayBrightness = 0x46,
|
||||||
AD_DisplayContrast = 0x47
|
AD_DisplayContrast = 0x47
|
||||||
};
|
};
|
||||||
|
@ -153,7 +160,9 @@ namespace HID
|
||||||
case AD_AlphanumericDisplay: return "alphanumeric";
|
case AD_AlphanumericDisplay: return "alphanumeric";
|
||||||
case AD_CharacterReport: return "character-report";
|
case AD_CharacterReport: return "character-report";
|
||||||
case AD_DisplayData: return "display-data";
|
case AD_DisplayData: return "display-data";
|
||||||
case AD_DisplayBrightness: return "display-brightness";
|
case AD_DisplayBrightness: return "display-brightness";
|
||||||
|
case AD_7SegmentDirectMap: return "seven-segment-direct";
|
||||||
|
case AD_14SegmentDirectMap: return "fourteen-segment-direct";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
SG_LOG(SG_INPUT, SG_WARN, "Unhandled HID alphanumeric usage:" << usage);
|
SG_LOG(SG_INPUT, SG_WARN, "Unhandled HID alphanumeric usage:" << usage);
|
||||||
|
@ -331,6 +340,10 @@ FGHIDDevice::FGHIDDevice(hid_device_info *devInfo, FGHIDEventInput *)
|
||||||
if ((serial != nullptr) && std::wcslen(serial) > 0) {
|
if ((serial != nullptr) && std::wcslen(serial) > 0) {
|
||||||
SetSerialNumber(simgear::strutils::convertWStringToUtf8(serial));
|
SetSerialNumber(simgear::strutils::convertWStringToUtf8(serial));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HID_INPUT_DEBUG)
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "HID device:" << GetName() << " at path " << _hidPath);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
FGHIDDevice::~FGHIDDevice()
|
FGHIDDevice::~FGHIDDevice()
|
||||||
|
@ -350,10 +363,30 @@ bool FGHIDDevice::Open()
|
||||||
|
|
||||||
unsigned char reportDescriptor[1024];
|
unsigned char reportDescriptor[1024];
|
||||||
int descriptorSize = hid_get_descriptor(_device, reportDescriptor, 1024);
|
int descriptorSize = hid_get_descriptor(_device, reportDescriptor, 1024);
|
||||||
|
if (descriptorSize <= 0) {
|
||||||
|
SG_LOG(SG_INPUT, SG_WARN, "HID: " << GetUniqueName() << " failed to read HID descriptor");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(HID_INPUT_DEBUG)
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "\nHID: descriptor for:" << GetUniqueName());
|
||||||
|
{
|
||||||
|
std::ostringstream byteString;
|
||||||
|
|
||||||
|
for (int i=0; i<descriptorSize; ++i) {
|
||||||
|
byteString << hexTable[reportDescriptor[i] >> 4];
|
||||||
|
byteString << hexTable[reportDescriptor[i] & 0x0f];
|
||||||
|
byteString << " ";
|
||||||
|
}
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "\tbytes: " << byteString.str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
hid_item* rootItem = nullptr;
|
hid_item* rootItem = nullptr;
|
||||||
hid_parse_reportdesc(reportDescriptor, descriptorSize, &rootItem);
|
hid_parse_reportdesc(reportDescriptor, descriptorSize, &rootItem);
|
||||||
|
#if defined(HID_INPUT_DEBUG)
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "\nHID: scan for:" << GetUniqueName());
|
||||||
|
#endif
|
||||||
scanCollection(rootItem);
|
scanCollection(rootItem);
|
||||||
|
|
||||||
hid_free_reportdesc(rootItem);
|
hid_free_reportdesc(rootItem);
|
||||||
|
@ -366,7 +399,10 @@ bool FGHIDDevice::Open()
|
||||||
}
|
}
|
||||||
|
|
||||||
FGInputEvent_ptr event = v.second;
|
FGInputEvent_ptr event = v.second;
|
||||||
// SG_LOG(SG_INPUT, SG_INFO, "found item for event:" << v.first);
|
if (debugEvents) {
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "found item for event:" << v.first);
|
||||||
|
}
|
||||||
|
|
||||||
reportItem.second->event = event;
|
reportItem.second->event = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,12 +516,13 @@ void FGHIDDevice::scanItem(hid_item* item)
|
||||||
auto report = getReport(ty, item->report_id, true /* create */);
|
auto report = getReport(ty, item->report_id, true /* create */);
|
||||||
uint32_t bitOffset = report->currentBitSize();
|
uint32_t bitOffset = report->currentBitSize();
|
||||||
|
|
||||||
// SG_LOG(SG_INPUT, SG_INFO, "adding item:" << name);
|
if (debugEvents) {
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, GetUniqueName() << ": add:" << name << ", bits: " << bitOffset << ":" << (int) item->report_size
|
||||||
|
<< ", report=" << (int) item->report_id);
|
||||||
|
}
|
||||||
|
|
||||||
Item* itemObject = new Item{name, bitOffset, item->report_size};
|
Item* itemObject = new Item{name, bitOffset, item->report_size};
|
||||||
itemObject->isRelative = hid_parse_is_relative(item);
|
itemObject->isRelative = hid_parse_is_relative(item);
|
||||||
|
|
||||||
// SG_LOG(SG_INPUT, SG_INFO, "\t logical min-max:" << item->logical_min << " / " << item->logical_max);
|
|
||||||
|
|
||||||
itemObject->doSignExtend = (item->logical_min < 0) || (item->logical_max < 0);
|
itemObject->doSignExtend = (item->logical_min < 0) || (item->logical_max < 0);
|
||||||
report->items.push_back(itemObject);
|
report->items.push_back(itemObject);
|
||||||
}
|
}
|
||||||
|
@ -574,17 +611,19 @@ void FGHIDDevice::processInputReport(Report* report, unsigned char* data,
|
||||||
size_t length,
|
size_t length,
|
||||||
double dt, int keyModifiers)
|
double dt, int keyModifiers)
|
||||||
{
|
{
|
||||||
//SG_LOG(SG_INPUT, SG_INFO, "Report " << report->number);
|
if (debugEvents) {
|
||||||
#if 0
|
SG_LOG(SG_INPUT, SG_INFO, "Report " << (int) report->number << length);
|
||||||
{
|
{
|
||||||
std::ostringstream byteString;
|
std::ostringstream byteString;
|
||||||
byteString << std::hex;
|
|
||||||
for (int i=0; i<length; ++i) {
|
for (int i=0; i<length; ++i) {
|
||||||
byteString << (int) data[i] << " ";
|
byteString << hexTable[data[i] >> 4];
|
||||||
|
byteString << hexTable[data[i] & 0x0f];
|
||||||
|
byteString << " ";
|
||||||
|
}
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "\tbytes: " << byteString.str());
|
||||||
}
|
}
|
||||||
SG_LOG(SG_INPUT, SG_INFO, "\tbytes: " << byteString.str());
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
for (auto item : report->items) {
|
for (auto item : report->items) {
|
||||||
int value = extractBits(data, length, item->bitOffset, item->bitSize);
|
int value = extractBits(data, length, item->bitOffset, item->bitSize);
|
||||||
|
@ -608,7 +647,9 @@ void FGHIDDevice::processInputReport(Report* report, unsigned char* data,
|
||||||
if (!item->event)
|
if (!item->event)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SG_LOG(SG_INPUT, SG_INFO, "\titem:" << item->name << " = " << value);
|
if (debugEvents) {
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "\titem:" << item->name << " = " << value);
|
||||||
|
}
|
||||||
|
|
||||||
HIDEventData event{item, value, dt, keyModifiers};
|
HIDEventData event{item, value, dt, keyModifiers};
|
||||||
HandleEvent(event);
|
HandleEvent(event);
|
||||||
|
@ -759,8 +800,9 @@ void FGHIDEventInput::update(double dt)
|
||||||
|
|
||||||
void FGHIDEventInput::FGHIDEventInputPrivate::evaluateDevice(hid_device_info* deviceInfo)
|
void FGHIDEventInput::FGHIDEventInputPrivate::evaluateDevice(hid_device_info* deviceInfo)
|
||||||
{
|
{
|
||||||
SG_LOG(SG_INPUT, SG_DEBUG, "HID device:" << deviceInfo->product_string << " from " << deviceInfo->manufacturer_string);
|
#if defined(HID_INPUT_DEBUG)
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "HID device:" << deviceInfo->product_string << " from " << deviceInfo->manufacturer_string);
|
||||||
|
#endif
|
||||||
// allocate an input device, and add to the base class to see if we have
|
// allocate an input device, and add to the base class to see if we have
|
||||||
// a config
|
// a config
|
||||||
p->AddDevice(new FGHIDDevice(deviceInfo, p));
|
p->AddDevice(new FGHIDDevice(deviceInfo, p));
|
||||||
|
|
Loading…
Reference in a new issue