mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2025-12-23 23:37:48 -05:00
Add functions to get serial port path from USB VID/PID for both Windows and Linux
This commit is contained in:
@@ -1,20 +1,8 @@
|
||||
#include "HuePlusController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_HuePlus.h"
|
||||
#include "find_usb_serial_port.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
@@ -29,60 +17,13 @@ void DetectHuePlusControllers(std::vector<RGBController*> &rgb_controllers)
|
||||
HuePlusController* new_hueplus;
|
||||
RGBController_HuePlus* new_controller;
|
||||
|
||||
//Get file path in executable directory
|
||||
std::ifstream infile;
|
||||
char filename[2048];
|
||||
char arg1[64];
|
||||
|
||||
#ifdef WIN32
|
||||
GetModuleFileName(NULL, filename, 2048);
|
||||
strcpy(filename, std::string(filename).substr(0, std::string(filename).find_last_of("\\/")).c_str());
|
||||
#else
|
||||
snprintf(arg1, 64, "/proc/%d/exe", getpid());
|
||||
readlink(arg1, filename, 1024);
|
||||
strcpy(filename, std::string(filename).substr(0, std::string(filename).find_last_of("\\/")).c_str());
|
||||
#endif
|
||||
|
||||
strcat(filename, "/settings.txt");
|
||||
|
||||
//Open settings file
|
||||
infile.open(filename);
|
||||
|
||||
if (infile.good())
|
||||
std::string portname = find_usb_serial_port(0x04D8, 0x00DF);
|
||||
if( portname != "" )
|
||||
{
|
||||
for (std::string line; std::getline(infile, line); )
|
||||
{
|
||||
if (line == "")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((line[0] != ';') && (line[0] != '#') && (line[0] != '/'))
|
||||
{
|
||||
char * argument;
|
||||
char * value;
|
||||
new_hueplus = new HuePlusController();
|
||||
new_hueplus->Initialize((char *)portname.c_str());
|
||||
|
||||
value = (char *)line.c_str();
|
||||
|
||||
argument = strtok_s(value, "=", &value);
|
||||
|
||||
//Strip off new line characters if present
|
||||
argument = strtok(argument, "\r\n");
|
||||
value = strtok(value, "\r\n");
|
||||
|
||||
if(argument)
|
||||
{
|
||||
if (strcmp(argument, "hueplus") == 0)
|
||||
{
|
||||
new_hueplus = new HuePlusController();
|
||||
new_hueplus->Initialize(value);
|
||||
|
||||
new_controller = new RGBController_HuePlus(new_hueplus);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
new_controller = new RGBController_HuePlus(new_hueplus);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
|
||||
} /* DetectHuePlusControllers() */
|
||||
|
||||
@@ -85,6 +85,7 @@ HEADERS += \
|
||||
net_port/net_port.h \
|
||||
qt/OpenRGBDialog2.h \
|
||||
qt/OpenRGBSystemInfoPage.h \
|
||||
serial_port/find_usb_serial_port.h \
|
||||
serial_port/serial_port.h \
|
||||
Controllers/AMDWraithPrismController/AMDWraithPrismController.h \
|
||||
Controllers/AuraController/AuraController.h \
|
||||
@@ -133,6 +134,7 @@ win32:SOURCES += \
|
||||
i2c_smbus/i2c_smbus_i801.cpp \
|
||||
i2c_smbus/i2c_smbus_nct6775.cpp \
|
||||
i2c_smbus/i2c_smbus_piix4.cpp \
|
||||
serial_port/find_usb_serial_port_win.cpp \
|
||||
wmi/wmi.cpp \
|
||||
RGBController/AorusGPUDetect.cpp \
|
||||
RGBController/RGBController_AorusGPU.cpp \
|
||||
@@ -176,5 +178,6 @@ unix:LIBS += \
|
||||
|
||||
unix:SOURCES += \
|
||||
i2c_smbus/i2c_smbus_linux.cpp \
|
||||
serial_port/find_usb_serial_port_linux.cpp \
|
||||
RGBController/OpenRazerDetect.cpp \
|
||||
RGBController/RGBController_OpenRazer.cpp \
|
||||
|
||||
10
serial_port/find_usb_serial_port.h
Normal file
10
serial_port/find_usb_serial_port.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
std::string find_usb_serial_port(unsigned short vid, unsigned short pid);
|
||||
116
serial_port/find_usb_serial_port_linux.cpp
Normal file
116
serial_port/find_usb_serial_port_linux.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "find_usb_serial_port.h"
|
||||
|
||||
/*---------------------------------------------------------------------*\
|
||||
| |
|
||||
| find_usb_serial_port |
|
||||
| |
|
||||
| This function returns the name of the first USB serial port matching|
|
||||
| the given USB product and vendor ID. |
|
||||
| |
|
||||
| vid: Vendor ID code |
|
||||
| pid: Product ID code |
|
||||
| |
|
||||
| returns: std::string containing port name "COMx" or "/dev/ttyX" |
|
||||
| |
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
std::string find_usb_serial_port(unsigned short vid, unsigned short pid)
|
||||
{
|
||||
std::string ret_string = "";
|
||||
DIR* dir;
|
||||
char symlink_path[1024] = {0};
|
||||
struct dirent* ent;
|
||||
char vid_pid[10] = {0}; //Store VID/PID
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Open /sys/class/tty |
|
||||
\*-----------------------------------------------------------------*/
|
||||
dir = opendir("/sys/class/tty");
|
||||
|
||||
if(dir == NULL)
|
||||
{
|
||||
closedir(dir);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Loop through all symlinks in /sys/class/tty directory to find |
|
||||
| paths with "usb" in them. These links should have the USB device |
|
||||
| index which can be used to find the VID/PID |
|
||||
\*-----------------------------------------------------------------*/
|
||||
ent = readdir(dir);
|
||||
|
||||
while(ent != NULL)
|
||||
{
|
||||
if(ent->d_type == DT_LNK)
|
||||
{
|
||||
char tty_path[1024];
|
||||
strcpy(tty_path, "/sys/class/tty/");
|
||||
strcat(tty_path, ent->d_name);
|
||||
|
||||
readlink(tty_path, symlink_path, 1024);
|
||||
|
||||
char * usb_string = strstr(symlink_path, "usb");
|
||||
|
||||
if(usb_string != NULL)
|
||||
{
|
||||
char * usb_dev = strstr(usb_string, "/");
|
||||
usb_dev++;
|
||||
usb_dev = strtok(usb_dev, "/");
|
||||
|
||||
char usb_path[1024];
|
||||
|
||||
strcpy(usb_path, "/sys/bus/usb/devices/");
|
||||
strcat(usb_path, usb_dev);
|
||||
|
||||
char vendor_path[1024];
|
||||
char product_path[1024];
|
||||
|
||||
strcpy(vendor_path, usb_path);
|
||||
strcat(vendor_path, "/idVendor");
|
||||
|
||||
strcpy(product_path, usb_path);
|
||||
strcat(product_path, "/idProduct");
|
||||
|
||||
std::ifstream vendor_file;
|
||||
std::ifstream product_file;
|
||||
std::string vendor_string;
|
||||
std::string product_string;
|
||||
|
||||
vendor_file.open(vendor_path);
|
||||
product_file.open(product_path);
|
||||
|
||||
std::getline(vendor_file, vendor_string);
|
||||
std::getline(product_file, product_string);
|
||||
|
||||
snprintf(vid_pid, 10, "%04x", vid);
|
||||
|
||||
if((strcmp(vid_pid, vendor_string.c_str()) == 0)
|
||||
{
|
||||
snprintf(vid_pid, 10, "%04x", pid);
|
||||
if(strcmp(vid_pid, product_string.c_str()) == 0)
|
||||
{
|
||||
char* port_string = NULL;
|
||||
for(int i = strlen(tty_path); i > 0; i--)
|
||||
{
|
||||
if(tty_path[i] == '/')
|
||||
{
|
||||
port_string = &tty_path[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret_string.append("/dev/");
|
||||
ret_string.append(port_string);
|
||||
|
||||
return ret_string;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ent = readdir(dir);
|
||||
}
|
||||
|
||||
return ret_string;
|
||||
|
||||
} /* find_usb_serial_port() */
|
||||
118
serial_port/find_usb_serial_port_win.cpp
Normal file
118
serial_port/find_usb_serial_port_win.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
#include "find_usb_serial_port.h"
|
||||
|
||||
#include <initguid.h>
|
||||
#include <windows.h>
|
||||
#include <Setupapi.h>
|
||||
|
||||
//Buffer length
|
||||
#define BUFF_LEN 20
|
||||
|
||||
#pragma comment (lib, "Setupapi.lib")
|
||||
#pragma comment(lib, "advapi32")
|
||||
|
||||
/*---------------------------------------------------------------------*\
|
||||
| |
|
||||
| find_usb_serial_port |
|
||||
| |
|
||||
| This function returns the name of the first USB serial port matching|
|
||||
| the given USB product and vendor ID. |
|
||||
| |
|
||||
| vid: Vendor ID code |
|
||||
| pid: Product ID code |
|
||||
| |
|
||||
| returns: std::string containing port name "COMx" or "/dev/ttyX" |
|
||||
| |
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
std::string find_usb_serial_port(unsigned short vid, unsigned short pid)
|
||||
{
|
||||
std::string ret_str = "";
|
||||
HDEVINFO DeviceInfoSet;
|
||||
DWORD DeviceIndex = 0;
|
||||
SP_DEVINFO_DATA DeviceInfoData;
|
||||
const char * DevEnum = "USB";
|
||||
char ExpectedDeviceId[80] = {0}; //Store hardware id
|
||||
char vid_pid[10] = {0}; //Store VID/PID
|
||||
BYTE szBuffer[1024] = {0};
|
||||
DEVPROPTYPE ulPropertyType;
|
||||
DWORD dwSize = 0;
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Create device hardware id |
|
||||
| "vid_ABCD&pid_CDEF" |
|
||||
\*-----------------------------------------------------------------*/
|
||||
strcpy(ExpectedDeviceId, "vid_");
|
||||
snprintf(vid_pid, 10, "%04X", vid);
|
||||
strcat(ExpectedDeviceId, vid_pid);
|
||||
strcat(ExpectedDeviceId, "&pid_");
|
||||
snprintf(vid_pid, 10, "%04X", pid);
|
||||
strcat(ExpectedDeviceId, vid_pid);
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| SetupDiGetClassDevs returns a handle to a device information set |
|
||||
\*-----------------------------------------------------------------*/
|
||||
DeviceInfoSet = SetupDiGetClassDevs( NULL, DevEnum, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
|
||||
|
||||
if (DeviceInfoSet == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Set up Device Info Data |
|
||||
\*-----------------------------------------------------------------*/
|
||||
memset(&DeviceInfoData, 0, sizeof(SP_DEVINFO_DATA));
|
||||
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Receive information about an enumerated device |
|
||||
\*-----------------------------------------------------------------*/
|
||||
while (SetupDiEnumDeviceInfo( DeviceInfoSet, DeviceIndex, &DeviceInfoData))
|
||||
{
|
||||
DeviceIndex++;
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Retrieves a specified Plug and Play device property |
|
||||
\*-------------------------------------------------------------*/
|
||||
if (SetupDiGetDeviceRegistryProperty (DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, &ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize))
|
||||
{
|
||||
HKEY hDeviceRegistryKey;
|
||||
|
||||
hDeviceRegistryKey = SetupDiOpenDevRegKey(DeviceInfoSet, &DeviceInfoData,DICS_FLAG_GLOBAL, 0,DIREG_DEV, KEY_READ);
|
||||
if (hDeviceRegistryKey == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
char pszPortName[BUFF_LEN];
|
||||
DWORD dwSize = sizeof(pszPortName);
|
||||
DWORD dwType = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read in the name of the port |
|
||||
\*-----------------------------------------------------*/
|
||||
if( (RegQueryValueEx(hDeviceRegistryKey,"PortName", NULL, &dwType, (LPBYTE) pszPortName, &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ))
|
||||
{
|
||||
if(strncmp(pszPortName, "COM", 3) == 0)
|
||||
{
|
||||
ret_str.append(pszPortName);
|
||||
return ret_str;
|
||||
}
|
||||
}
|
||||
|
||||
// Close the key now that we are finished with it
|
||||
RegCloseKey(hDeviceRegistryKey);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (DeviceInfoSet)
|
||||
{
|
||||
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
|
||||
}
|
||||
|
||||
return ret_str;
|
||||
|
||||
} /* find_usb_serial_port() */
|
||||
Reference in New Issue
Block a user