From 6366dea197e4d4e28d9479470df0def974a51482 Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 4 Oct 2018 12:16:15 +0100 Subject: [PATCH] HID event-input debugging Adding more debugEvents-enabled log output to HDI input --- 3rdparty/hidapi/hidparser/hidparse.c | 12 +++-- src/Input/FGEventInput.cxx | 42 ++++++++++++--- src/Input/FGHIDEventInput.cxx | 80 +++++++++++++++++++++------- 3 files changed, 104 insertions(+), 30 deletions(-) diff --git a/3rdparty/hidapi/hidparser/hidparse.c b/3rdparty/hidapi/hidparser/hidparse.c index 494c5e1eb..496651fae 100644 --- a/3rdparty/hidapi/hidparser/hidparse.c +++ b/3rdparty/hidapi/hidparser/hidparse.c @@ -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 tag = pfx >> 4; - // fprintf(stderr, "short item: size=%d, bytes=%d, type = %d, tag=%d\n", - // size, bytes, type, tag); + // fprintf(stderr, "short item: size=%d, bytes=%d, type = %d, tag=%d\n", + // size, bytes, type, tag); /* If it's a main item */ 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: { - //fprintf(stderr, "opening collection\n"); + // fprintf(stderr, "opening collection\n"); uint8_t flags = read_uint(size, p); hid_item* col = build_collection(flags); 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: - //fprintf(stderr, "closing collection\n"); + // fprintf(stderr, "closing collection\n"); assert(current_collection); current_collection = current_collection->parent; break; @@ -226,6 +226,8 @@ int hid_parse_reportdesc(uint8_t* rdesc_buf, uint32_t rdesc_size, hid_item** ite for (i=0; itype, + // item->report_id, item->report_size); append_item(current_collection, item); } 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: current_state.report_size = read_uint(size, p); + //fprintf(stderr, "item size is:%d\n", current_state.report_size); break; case HID_REPORT_COUNT_ITEM: report_count = read_uint(size, p); + //fprintf(stderr, "item count is:%d\n", report_count); break; case HID_POP_ITEM: diff --git a/src/Input/FGEventInput.cxx b/src/Input/FGEventInput.cxx index 9281ad6b1..3ca566903 100644 --- a/src/Input/FGEventInput.cxx +++ b/src/Input/FGEventInput.cxx @@ -507,11 +507,14 @@ bool FGReportSetting::Test() return d; } +static const char* hexTable = "0123456789ABCDEF"; + + std::string FGReportSetting::reportBytes(const std::string& moduleName) const { - FGNasalSys *nas = (FGNasalSys *)globals->get_subsystem("nasal"); + FGNasalSys *nas = globals->get_subsystem(); if (!nas) { - return std::string(); + return {}; } 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()); - if (!naIsString(result)) { - return std::string(); + if (naIsString(result)) { + size_t len = naStr_len(result); + char* bytes = naStr_data(result); + return std::string(bytes, len); } - size_t len = naStr_len(result); - char* bytes = naStr_data(result); - return std::string(bytes, len); + if (naIsVector(result)) { + int len = naVec_size(result); + std::string s; + for (int b=0; b < len; ++b) { + int num = naNumValue(naVec_get(result, b)).num; + s.push_back(static_cast(num)); + } + + // can't access FGInputDevice here to check debugEvents flag +#if 0 + std::ostringstream byteString; + + for (int i=0; i(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) diff --git a/src/Input/FGHIDEventInput.cxx b/src/Input/FGHIDEventInput.cxx index 4375e2675..21617f119 100644 --- a/src/Input/FGHIDEventInput.cxx +++ b/src/Input/FGHIDEventInput.cxx @@ -34,6 +34,9 @@ #include #include +//#define HID_INPUT_DEBUG 1 + +const char* hexTable = "0123456789ABCDEF"; namespace HID { @@ -102,6 +105,10 @@ namespace HID AD_CharacterReport = 0x2B, AD_DisplayData = 0x2C, AD_DisplayStatus = 0x2D, + AD_Rows = 0x35, + AD_Columns = 0x36, + AD_7SegmentDirectMap = 0x43, + AD_14SegmentDirectMap = 0x45, AD_DisplayBrightness = 0x46, AD_DisplayContrast = 0x47 }; @@ -153,7 +160,9 @@ namespace HID case AD_AlphanumericDisplay: return "alphanumeric"; case AD_CharacterReport: return "character-report"; 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: 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) { 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() @@ -350,10 +363,30 @@ bool FGHIDDevice::Open() unsigned char 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> 4]; + byteString << hexTable[reportDescriptor[i] & 0x0f]; + byteString << " "; + } + SG_LOG(SG_INPUT, SG_INFO, "\tbytes: " << byteString.str()); + } +#endif hid_item* rootItem = nullptr; hid_parse_reportdesc(reportDescriptor, descriptorSize, &rootItem); - +#if defined(HID_INPUT_DEBUG) + SG_LOG(SG_INPUT, SG_INFO, "\nHID: scan for:" << GetUniqueName()); +#endif scanCollection(rootItem); hid_free_reportdesc(rootItem); @@ -366,7 +399,10 @@ bool FGHIDDevice::Open() } 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; } @@ -480,12 +516,13 @@ void FGHIDDevice::scanItem(hid_item* item) auto report = getReport(ty, item->report_id, true /* create */); 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}; 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); report->items.push_back(itemObject); } @@ -574,17 +611,19 @@ void FGHIDDevice::processInputReport(Report* report, unsigned char* data, size_t length, double dt, int keyModifiers) { - //SG_LOG(SG_INPUT, SG_INFO, "Report " << report->number); -#if 0 - { - std::ostringstream byteString; - byteString << std::hex; - for (int i=0; inumber << length); + { + std::ostringstream byteString; + + for (int i=0; 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) { int value = extractBits(data, length, item->bitOffset, item->bitSize); @@ -608,7 +647,9 @@ void FGHIDDevice::processInputReport(Report* report, unsigned char* data, if (!item->event) 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}; HandleEvent(event); @@ -759,8 +800,9 @@ void FGHIDEventInput::update(double dt) 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 // a config p->AddDevice(new FGHIDDevice(deviceInfo, p));