Commit d1e1bd56 authored by Roland Singer's avatar Roland Singer

* implemented config readout and match function

* added support to define multiple device rules in configs
* added priority support to configs
* sorting configs after priority
* redesigned base mhwd structure
parent 2dd1e13a
......@@ -3,5 +3,4 @@ project(mhwd)
add_definitions(-Wall)
include_directories(vita-1.0)
add_subdirectory(libmhwd)
include_directories (.)
include_directories(. vita)
set( HEADERS
mhwd.h
hwd.h
const.h
device.h
config.h
vita/config.hpp
vita/string.hpp
)
set( SOURCES
mhwd.cpp
device.cpp
hwd.cpp
device.cpp
config.cpp
vita/config.cpp
vita/string.cpp
)
set( LIBS hd)
......
/*
* mhwd - Manjaro Hardware Detection
*
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
mhwd::Config::Config(string path)
{
priority = 0;
freedriver = true;
Config::path = path;
readConfig(path);
}
bool mhwd::Config::operator==(const mhwd::Config& compare) {
return (path == compare.path);
}
// Private
bool mhwd::Config::readConfig(const Vita::string path) {
if (IDs.empty())
addNewIDsGroup();
ifstream file(path.c_str(), ios::in);
if (!file.is_open())
return false;
Vita::string line, key, value;
vector<Vita::string> parts;
while (!file.eof()) {
getline(file, line);
size_t pos = line.find_first_of('#');
if (pos != string::npos)
line.erase(pos);
if (line.trim().empty())
continue;
parts = line.explode("=");
key = parts.front().trim().toLower();
value = parts.back().trim("\"").trim();
if (key == "include") {
readConfig(value);
}
else if (key == "name") {
name = value;
}
else if (key == "info") {
info = value;
}
else if (key == "priority") {
priority = value.convert<int>();
}
else if (key == "freedriver") {
value = value.toLower();
if (value == "false")
freedriver = false;
else if (value == "true")
freedriver = true;
}
else if (key == "classids") {
if (!IDs.back().classIDs.empty())
addNewIDsGroup();
IDs.back().classIDs = getIDs(value);
}
else if (key == "vendorids") {
if (!IDs.back().vendorIDs.empty())
addNewIDsGroup();
IDs.back().vendorIDs = getIDs(value);
}
else if (key == "deviceids") {
if (!IDs.back().deviceIDs.empty())
addNewIDsGroup();
IDs.back().deviceIDs = getIDs(value);
}
}
file.close();
// Append * to all empty vectors
for (vector<IDsGroup>::iterator iterator = IDs.begin(); iterator != IDs.end(); iterator++) {
if ((*iterator).classIDs.empty())
(*iterator).classIDs.push_back("*");
if ((*iterator).vendorIDs.empty())
(*iterator).vendorIDs.push_back("*");
if ((*iterator).deviceIDs.empty())
(*iterator).deviceIDs.push_back("*");
}
return true;
}
vector<string> mhwd::Config::getIDs(Vita::string str) {
vector<Vita::string> work = str.toLower().explode(" ");
vector<string> final;
for (vector<Vita::string>::const_iterator iterator = work.begin(); iterator != work.end(); iterator++) {
if (*iterator != "")
final.push_back(*iterator);
}
return final;
}
void mhwd::Config::addNewIDsGroup() {
IDsGroup group;
IDs.push_back(group);
}
/*
* mhwd - Manjaro Hardware Detection
*
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "string.hpp"
using namespace std;
namespace mhwd {
class Config
{
public:
Config(string path);
bool operator==(const Config& compare);
string getName() { return name; }
string getInfo() { return info; }
bool getIsFreeDriver() { return freedriver; }
int getPriority() { return priority; }
struct IDsGroup {
vector<string> classIDs, vendorIDs, deviceIDs;
};
vector<IDsGroup> getIDsGroups() { return IDs; }
private:
string path, name, info;
vector<IDsGroup> IDs;
bool freedriver;
int priority;
bool readConfig(const Vita::string path);
vector<string> getIDs(Vita::string str);
inline void addNewIDsGroup();
};
}
#endif // CONFIG_H
......@@ -17,48 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mhwd.h"
vector<mhwd::Device*> mhwd::getDevices(HW hw) {
vector<Device*> devices;
hd_data_t *hd_data;
hd_t *hd;
hd_data = (hd_data_t*)calloc(1, sizeof *hd_data);
hd = hd_list(hd_data, (hw_item)hw, 1, NULL);
for(; hd; hd = hd->next) {
Device::TYPE type = Device::TYPE_PCI;
if (hw == HW_USB)
type = Device::TYPE_USB;
devices.push_back(new Device(hd, type));
}
hd_free_hd_list(hd);
hd_free_hd_data(hd_data);
free(hd_data);
return devices;
}
void mhwd::printDetails(HW hw) {
hd_data_t *hd_data;
hd_t *hd;
hd_data = (hd_data_t*)calloc(1, sizeof *hd_data);
hd = hd_list(hd_data, (hw_item)hw, 1, NULL);
for(; hd; hd = hd->next) {
hd_dump_entry(hd_data, hd, stdout);
}
hd_free_hd_list(hd);
hd_free_hd_data(hd_data);
free(hd_data);
}
#define MHWD_CONFIG_END "mhwd"
#define MHWD_USB_CONFIG_DIR "/var/lib/mhwd/usb"
#define MHWD_PCI_CONFIG_DIR "/var/lib/mhwd/pci"
......@@ -24,9 +24,9 @@
mhwd::Device::Device(hd_t *hd, TYPE type) {
Device::type = type;
ClassID = from_Hex(hd->base_class.id, 2) + from_Hex(hd->sub_class.id, 2);
VendorID = from_Hex(hd->vendor.id, 4);
DeviceID = from_Hex(hd->device.id, 4);
ClassID = from_Hex(hd->base_class.id, 2) + from_Hex(hd->sub_class.id, 2).toLower();
VendorID = from_Hex(hd->vendor.id, 4).toLower();
DeviceID = from_Hex(hd->device.id, 4).toLower();
ClassName = from_CharArray(hd->base_class.name);
VendorName = from_CharArray(hd->vendor.name);
DeviceName = from_CharArray(hd->device.name);
......@@ -39,7 +39,25 @@ mhwd::Device::Device(hd_t *hd, TYPE type) {
string mhwd::Device::from_Hex(uint16_t hexnum, int fill) {
void mhwd::Device::addConfig(mhwd::Config& config) {
for (vector<mhwd::Config>::const_iterator iterator = configs.begin(); iterator != configs.end(); iterator++) {
if (config == *iterator)
return;
}
for (vector<mhwd::Config>::iterator iterator = configs.begin(); iterator != configs.end(); iterator++) {
if (config.getPriority() > (*iterator).getPriority()) {
configs.insert(iterator, config);
return;
}
}
configs.push_back(config);
}
Vita::string mhwd::Device::from_Hex(uint16_t hexnum, int fill) {
stringstream stream;
stream << hex << setfill('0') << setw(fill) << hexnum;
return stream.str();
......@@ -47,9 +65,10 @@ string mhwd::Device::from_Hex(uint16_t hexnum, int fill) {
string mhwd::Device::from_CharArray(char* c) {
Vita::string mhwd::Device::from_CharArray(char* c) {
if (c == NULL)
return "";
return string(c);
}
......@@ -27,13 +27,17 @@
#include <vector>
#include <hd.h>
#include "string.hpp"
#include "config.h"
using namespace std;
namespace mhwd {
class Device
{
public:
friend class hwd;
enum TYPE { TYPE_PCI, TYPE_USB };
Device(hd_t *hd, TYPE type);
......@@ -45,13 +49,16 @@ namespace mhwd {
string getClassID() { return ClassID; }
string getDeviceID() { return DeviceID; }
string getVendorID() { return VendorID; }
vector<mhwd::Config> getConfigs() { return configs; }
private:
private:
string ClassName, DeviceName, VendorName, ClassID, DeviceID, VendorID;
TYPE type;
vector<mhwd::Config> configs;
string from_Hex(uint16_t hexnum, int fill = 4);
string from_CharArray(char* c);
void addConfig(Config& config);
Vita::string from_Hex(uint16_t hexnum, int fill = 4);
Vita::string from_CharArray(char* c);
};
}
......
/*
* mhwd - Manjaro Hardware Detection
*
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "hwd.h"
// Static variables
vector<mhwd::Device*> mhwd::hwd::USBDevices, mhwd::hwd::PCIDevices;
// Static methods
vector<mhwd::Device*> mhwd::hwd::getUSBDevices() {
if (USBDevices.empty())
update();
return USBDevices;
}
vector<mhwd::Device*> mhwd::hwd::getPCIDevices() {
if (PCIDevices.empty())
update();
return PCIDevices;
}
void mhwd::hwd::update() {
PCIDevices.clear();
USBDevices.clear();
PCIDevices = getDevices(Device::TYPE_PCI);
USBDevices = getDevices(Device::TYPE_USB);
}
void mhwd::hwd::printUSBDetails() {
printDetails(hw_usb);
}
void mhwd::hwd::printPCIDetails() {
printDetails(hw_pci);
}
// Private
vector<mhwd::Device*> mhwd::hwd::getDevices(Device::TYPE type) {
vector<Device*> devices;
hd_data_t *hd_data;
hd_t *hd;
hw_item hw;
string configDir;
if (type == Device::TYPE_USB) {
hw = hw_usb;
configDir = MHWD_USB_CONFIG_DIR;
}
else {
hw = hw_pci;
configDir = MHWD_PCI_CONFIG_DIR;
}
hd_data = (hd_data_t*)calloc(1, sizeof *hd_data);
hd = hd_list(hd_data, hw, 1, NULL);
for(; hd; hd = hd->next) {
devices.push_back(new Device(hd, type));
}
setMatchingConfigs(&devices, configDir);
hd_free_hd_list(hd);
hd_free_hd_data(hd_data);
free(hd_data);
return devices;
}
void mhwd::hwd::setMatchingConfigs(vector<mhwd::Device*>* devices, const string configDir) {
struct dirent *dir;
DIR *d = opendir(configDir.c_str());
if (!d)
return;
while ((dir = readdir(d)) != NULL)
{
Vita::string filename = Vita::string(dir->d_name);
Vita::string filepath = configDir + "/" + filename;
if(filename == "." || filename == ".." || filename == "")
continue;
struct stat filestatus;
lstat(filepath.c_str(), &filestatus);
if (S_ISREG(filestatus.st_mode) && filename.explode(".").back() == MHWD_CONFIG_END)
setMatchingConfig(devices, filepath);
else if (S_ISDIR(filestatus.st_mode))
setMatchingConfigs(devices, filepath);
}
closedir(d);
}
void mhwd::hwd::setMatchingConfig(vector<mhwd::Device*>* devices, const string configPath) {
mhwd::Config config(configPath);
vector<mhwd::Device*> foundDevices;
vector<mhwd::Config::IDsGroup> IDsGroups = config.getIDsGroups();
for (vector<mhwd::Config::IDsGroup>::const_iterator i_idsgroup = IDsGroups.begin(); i_idsgroup != IDsGroups.end(); i_idsgroup++) {
bool foundDevice = false;
// Check all devices
for (vector<mhwd::Device*>::iterator i_device = devices->begin(); i_device != devices->end(); i_device++) {
bool found = false;
// Check class ids
for (vector<string>::const_iterator iterator = (*i_idsgroup).classIDs.begin(); iterator != (*i_idsgroup).classIDs.end(); iterator++) {
if (*iterator == "*" || *iterator == (*i_device)->ClassID) {
found = true;
break;
}
}
if (!found)
continue;
// Check vendor ids
found = false;
for (vector<string>::const_iterator iterator = (*i_idsgroup).vendorIDs.begin(); iterator != (*i_idsgroup).vendorIDs.end(); iterator++) {
if (*iterator == "*" || *iterator == (*i_device)->VendorID) {
found = true;
break;
}
}
if (!found)
continue;
// Check device ids
found = false;
for (vector<string>::const_iterator iterator = (*i_idsgroup).deviceIDs.begin(); iterator != (*i_idsgroup).deviceIDs.end(); iterator++) {
if (*iterator == "*" || *iterator == (*i_device)->DeviceID) {
found = true;
break;
}
}
if (!found)
continue;
foundDevices.push_back((*i_device));
foundDevice = true;
}
if (!foundDevice)
return;
}
// Set config to all matching devices
for (vector<mhwd::Device*>::iterator iterator = foundDevices.begin(); iterator != foundDevices.end(); iterator++) {
(*iterator)->addConfig(config);
}
}
void mhwd::hwd::printDetails(hw_item hw) {
hd_data_t *hd_data;
hd_t *hd;
hd_data = (hd_data_t*)calloc(1, sizeof *hd_data);
hd = hd_list(hd_data, hw, 1, NULL);
for(; hd; hd = hd->next) {
hd_dump_entry(hd_data, hd, stdout);
}
hd_free_hd_list(hd);
hd_free_hd_data(hd_data);
free(hd_data);
}
/*
* mhwd - Manjaro Hardware Detection
*
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the