Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add logSystemInfo parameter and USB VID/PID lookup #331

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34,088 changes: 34,088 additions & 0 deletions data-files/vid_pid.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions docs/general_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ These flags control whether various information is written to the output databas
|`logPlayerActions` |`bool` | Enable/disable for logging player position, aim , and actions to database (per frame) |
|`logTrialResponse` |`bool` | Enable/disable for logging trial responses to database (per trial) |
|`logUsers` |`bool` | Enable/disable for logging users to database (per session) |
|`logSystemInfo` |`bool` | Enable/disable for logging system (hardware) information to database (per session) |
|`logOnChange` |`bool` | Enable/disable for logging values to the `Player_Action` and `Target_Trajectory` tables only when changes occur |
|`logToSingleDb` |`bool` | Enable/disable for logging to a unified output database file (named using the experiment description and user ID) |
|`sessionParametersToLog` |`Array<String>`| A list of other config parameters (by name) that are logged on a per-session basis to the `Sessions` table |
Expand All @@ -664,6 +665,7 @@ These flags control whether various information is written to the output databas
"logPlayerActions" = true, // Log player actions (view direction, position, state, event, target)
"logTrialResponse" = true, // Log trial results to the Trials table
"logUsers" = true, // Log the users to the Users table
"logSystemInfo" = true, // Log the system information (USB VID/PID)
"logOnChange" = false, // Log every frame (do not log only on change)
"logToSingleDb" = true, // Log all sessions affiliated with a given experiment to the same database file
"sessionParametersToLog" = ["frameRate", "frameDelay"], // Log the frame rate and frame delay to the Sessions table
Expand Down
2 changes: 2 additions & 0 deletions source/FpsConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ void LoggerConfig::load(FPSciAnyTableReader reader, int settingsVersion) {
reader.getIfPresent("logPlayerActions", logPlayerActions);
reader.getIfPresent("logTrialResponse", logTrialResponse);
reader.getIfPresent("logUsers", logUsers);
reader.getIfPresent("logSystemInfo", logSystemInfo);
reader.getIfPresent("logOnChange", logOnChange);
reader.getIfPresent("sessionParametersToLog", sessParamsToLog);
reader.getIfPresent("logToSingleDb", logToSingleDb);
Expand All @@ -550,6 +551,7 @@ Any LoggerConfig::addToAny(Any a, bool forceAll) const {
if (forceAll || def.logPlayerActions != logPlayerActions) a["logPlayerActions"] = logPlayerActions;
if (forceAll || def.logTrialResponse != logTrialResponse) a["logTrialResponse"] = logTrialResponse;
if (forceAll || def.logUsers != logUsers) a["logUsers"] = logUsers;
if (forceAll || def.logSystemInfo != logSystemInfo) a["logSystemInfo"] = logSystemInfo;
if (forceAll || def.logOnChange != logOnChange) a["logOnChange"] = logOnChange;
if (forceAll || def.sessParamsToLog != sessParamsToLog) a["sessionParametersToLog"] = sessParamsToLog;
if (forceAll || def.logToSingleDb != logToSingleDb) a["logToSingleDb"] = logToSingleDb;
Expand Down
4 changes: 2 additions & 2 deletions source/FpsConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ class LoggerConfig {
bool logTrialResponse = true; ///< Log trial response in table?
bool logUsers = true; ///< Log user information in table?
bool logOnChange = false; ///< Only log to Player_Action/Target_Trajectory table when the player/target position/orientation changes

bool logToSingleDb = true; ///< Log all results to a single db file?
bool logToSingleDb = true; ///< Log all results to a single db file?
bool logSystemInfo = true; ///< Log system information to the results database

// Session parameter logging
Array<String> sessParamsToLog = { "frameRate", "frameDelay" }; ///< Parameter names to log to the Sessions table of the DB
Expand Down
29 changes: 29 additions & 0 deletions source/Logger.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "Logger.h"
#include "SystemInfo.h"
#include "Session.h"
#include "FPSciApp.h"

Expand Down Expand Up @@ -62,6 +63,7 @@ void FPSciLogger::initResultsFile(const String& filename,
createFrameInfoTable();
createQuestionsTable();
createUsersTable();
createSystemInfoTable();
}

// Add the session info to the sessions table
Expand Down Expand Up @@ -422,6 +424,33 @@ void FPSciLogger::logUserConfig(const UserConfig& user, const String& sessId, co
m_users.append(row);
}

void FPSciLogger::createSystemInfoTable() {
const Columns systemInfoColumns = {
{"time", "text"},
{"session_id", "text"},
{"parameter", "text"},
{"value", "text"}
};
createTableInDB(m_db, "System_Info", systemInfoColumns);
}

void FPSciLogger::logSystemInfo(const String& sessID, const SystemInfo& info) {
String time = genUniqueTimestamp(); // Produce a single unique timestamp for this entry
Any::AnyTable infoTable = info.toAny().table();
Array<RowEntry> rows;
// Iterate through entries writing to log
for (String paramName : infoTable.getKeys()) {
Array<String> row = {
"'" + time + "'",
"'" + sessID + "'",
"'" + paramName + "'",
"'" + infoTable[paramName].unparse() + "'"
};
rows.append(row);
}
insertRowsIntoDB(m_db, "System_Info", rows);
}

void FPSciLogger::loggerThreadEntry()
{
std::unique_lock<std::mutex> lk(m_queueMutex);
Expand Down
3 changes: 3 additions & 0 deletions source/Logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ using Columns = Array<Array<String>>;
struct TargetLocation;
struct PlayerAction;
struct FrameInfo;
class SystemInfo;

template<typename ItemType> static size_t queueBytes(Array<ItemType>& queue)
{
Expand Down Expand Up @@ -111,6 +112,7 @@ class FPSciLogger : public ReferenceCountedObject {
void createFrameInfoTable();
void createQuestionsTable();
void createUsersTable();
void createSystemInfoTable();

// Functions that assume the schema from above
//void insertSession(sessionInfo);
Expand Down Expand Up @@ -142,6 +144,7 @@ class FPSciLogger : public ReferenceCountedObject {

void logUserConfig(const UserConfig& userConfig, const String& sessId, const Vector2& sessTurnScale);
void logTargetTypes(const Array<shared_ptr<TargetConfig>>& targets);
void logSystemInfo(const String& sessID, const SystemInfo& info);

/** Wakes up the logging thread and flushes even if the buffer limit is not reached yet. */
void flush(bool blockUntilDone);
Expand Down
5 changes: 5 additions & 0 deletions source/Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ void Session::onInit(String filename, String description) {
m_config, description);
logger->logTargetTypes(m_app->experimentConfig.getSessionTargets(m_config->id)); // Log target info at start of session
logger->logUserConfig(user, m_config->id, m_config->player.turnScale); // Log user info at start of session
if (m_config->logger.logSystemInfo) {
// Log the system info (per session) if requested
SystemInfo info = SystemInfo::get();
logger->logSystemInfo(m_config->id, info);
}
m_dbFilename = filename;
}

Expand Down
90 changes: 89 additions & 1 deletion source/SystemInfo.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "SystemInfo.h"
#include <setupapi.h>
#include <devguid.h>

SystemInfo SystemInfo::get(void) {
SystemInfo info;
Expand Down Expand Up @@ -71,9 +73,88 @@ SystemInfo SystemInfo::get(void) {
info.displayXSize = GetDeviceCaps(hdc, HORZSIZE);
info.displayYSize = GetDeviceCaps(hdc, VERTSIZE);

// Get USB info
Array<String> VIDs; Array<String> PIDs;
int usbCount = getUSBInfo(VIDs, PIDs);

Any::AnyTable lookup;
bool haveVIDPIDLookup = loadVIDPIDTable("vid_pid.json", lookup);
for (int i = 0; i < usbCount; i++) {
// Add each VID/PID pair to the info structure
String devString = format("VID = %s, PID = %s", VIDs[i], PIDs[i]);
if (haveVIDPIDLookup) {
String vendor = "Unknown vendor";
String product = "Unknown product";
if (lookup.containsKey(VIDs[i])) {
vendor = lookup[VIDs[i]]["vendor"];
if (lookup[VIDs[i]]["pids"].containsKey(PIDs[i])) {
product = lookup[VIDs[i]]["pids"][PIDs[i]];
}
}
devString += format(" (%s %s)", vendor.c_str(), product.c_str());
}
info.usbDevices.append(devString);
}

return info;
}

int SystemInfo::getUSBInfo(Array<String>& VIDs, Array<String>& PIDs) {
HDEVINFO deviceInfoSet;
GUID* guidDev = (GUID*)&GUID_DEVCLASS_USB;
deviceInfoSet = SetupDiGetClassDevs(guidDev, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE);
int memberIndex = 0;
int validCount = 0;

while (true) {
// Initialize storage
SP_DEVINFO_DATA deviceInfoData;
ZeroMemory(&deviceInfoData, sizeof(SP_DEVINFO_DATA));
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
// Get device info (one at a time)
if (!SetupDiEnumDeviceInfo(deviceInfoSet, memberIndex, &deviceInfoData)) {
if (GetLastError() == ERROR_NO_MORE_ITEMS) {
break; // Exit the while loop once all devices have been found
}
}
memberIndex++;

// Storage for VID/PID string
TCHAR buffer[4000];
DWORD nSize = 0;
SetupDiGetDeviceInstanceId(deviceInfoSet, &deviceInfoData, buffer, sizeof(buffer), &nSize);
buffer[nSize] = '\0'; // Add string null terminator

// Convert to G3D::String
String vidpidStr = String(buffer);

// Validate the VID/PID string to make sure it is a USB device w/ VID and PID present
if (!vidpidStr.rfind("USB", 0) == 0) continue; // Skip non-USB devices
if (vidpidStr.rfind("VID") == std::string::npos) continue; // Skip USB devices without VID present

// Extract VID and PID substrings
String vid = vidpidStr.substr(8, 4);
String pid = vidpidStr.substr(17, 4);
VIDs.append(vid);
PIDs.append(pid);
validCount++;
}
if (deviceInfoSet) {
SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
return validCount;
}

bool SystemInfo::loadVIDPIDTable(const String& filename, Any::AnyTable& table) {
if (!FileSystem::exists(System::findDataFile(filename, false))) {
return false;
}
Any raw;
raw.load(System::findDataFile(filename));
table = raw.table();
return true;
}

Any SystemInfo::toAny(const bool forceAll) const {
Any a(Any::TABLE);
a["hostname"] = hostName;
Expand All @@ -87,11 +168,18 @@ Any SystemInfo::toAny(const bool forceAll) const {
a["DisplayResYpx"] = displayYRes;
a["DisplaySizeXmm"] = displayXSize;
a["DisplaySizeYmm"] = displayYSize;
a["USBDevices"] = usbDevices;
return a;
}

void SystemInfo::printToLog() {
// Print system info to log
logPrintf("\n-------------------\nSystem Info:\n-------------------\n\tHostname: %s\n\tUsername: %s\n\tProcessor: %s\n\tCore Count: %d\n\tMemory: %dMB\n\tGPU: %s\n\tDisplay: %s\n\tDisplay Resolution: %d x %d (px)\n\tDisplay Size: %d x %d (mm)\n\n",
logPrintf("\n-------------------\nSystem Info:\n-------------------\n\tHostname: %s\n\tUsername: %s\n\tProcessor: %s\n\tCore Count: %d\n\tMemory: %dMB\n\tGPU: %s\n\tDisplay: %s\n\tDisplay Resolution: %d x %d (px)\n\tDisplay Size: %d x %d (mm)\n",
hostName, userName, cpuName, coreCount, memCapacityMB, gpuName, displayName, displayXRes, displayYRes, displayXSize, displayYSize);
// Print USB devices to the log
logPrintf("\tUSB Devices:\n");
for (String devString : usbDevices) {
logPrintf("\t\t%s\n", devString);
}
logPrintf("\n");
}
5 changes: 5 additions & 0 deletions source/SystemInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ class SystemInfo {
int displayYRes; ///< The vertical size of the display in pixels
int displayXSize; ///< The horizontal size of the display in mm
int displayYSize; ///< The vertical size of the display in mm
Array<String> usbDevices; ///< Array of USB devices (VID, PID, and interpreted names)

static SystemInfo get(void); // Get the system info using (windows) calls

Any toAny(const bool forceAll = true) const;
void printToLog();

protected:
static int getUSBInfo(Array<String>& VIDs, Array<String>& PIDs);
static bool loadVIDPIDTable(const String& filename, Any::AnyTable& table);
};
4 changes: 2 additions & 2 deletions vs/FPSci.test.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
<Link>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;sqlite3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;sqlite3.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
Expand Down Expand Up @@ -146,7 +146,7 @@
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;sqlite3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;sqlite3.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
Expand Down
4 changes: 2 additions & 2 deletions vs/FirstPersonScience.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;sqlite3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;sqlite3.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
Expand Down Expand Up @@ -151,7 +151,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;sqlite3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;sqlite3.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
Expand Down