add hashes for nodes for persistent identification

This commit is contained in:
Jussi Kuokkanen 2020-05-06 20:40:48 +03:00
parent 40d740fd6b
commit d445e3d7d8
8 changed files with 105 additions and 20 deletions

10
src/include/Crypto.hpp Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include <string>
namespace TuxClocker::Crypto {
std::string sha256(std::string s);
std::string md5(std::string s);
};

View File

@ -77,8 +77,8 @@ using DeviceInterface = std::variant<Assignable, DynamicReadable>;
struct DeviceNode {
std::string name;
std::optional<DeviceInterface> interface;
std::string hash;
};
};
};

32
src/lib/Crypto.cpp Normal file
View File

@ -0,0 +1,32 @@
#include <Crypto.hpp>
#include <openssl/md5.h>
#include <openssl/sha.h>
namespace TuxClocker::Crypto {
std::string sha256(std::string s) {
auto d = SHA256(reinterpret_cast<const unsigned char*>(s.c_str()), s.size(), 0);
char out[(SHA256_DIGEST_LENGTH * 2) + 1];
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
sprintf(out + (i * 2), "%02x", d[i]);
out[SHA256_DIGEST_LENGTH * 2] = '\0';
return std::string(out);
}
std::string md5(std::string s) {
unsigned char data[MD5_DIGEST_LENGTH];
MD5(reinterpret_cast<const unsigned char*>(s.c_str()), s.size(), data);
char out[(MD5_DIGEST_LENGTH * 2) + 1];
for (int i = 0; i < MD5_DIGEST_LENGTH; i++)
sprintf(out + (i * 2), "%02x", data[i]);
out[MD5_DIGEST_LENGTH * 2] = '\0';
return std::string(out);
}
};

View File

@ -1,3 +1,4 @@
#include <Crypto.hpp>
#include <Device.hpp>
#include <Plugin.hpp>
@ -10,6 +11,7 @@
#include <nvml.h>
using namespace TuxClocker;
using namespace TuxClocker::Crypto;
using namespace TuxClocker::Device;
using namespace TuxClocker::Plugin;
using namespace mpark::patterns;
@ -34,6 +36,18 @@ struct UnspecializedReadable {
std::function<std::variant<ReadError, ReadableValue>(T)> func;
std::optional<std::string> unit;
std::string nodeName;
// One time function for getting a hash
std::function<std::string(T)> hash;
static std::vector<DeviceNode> toDeviceNodes(
std::vector<UnspecializedReadable<T>> rawNodes, T data, std::string uuid) {
std::vector<DeviceNode> retval;
for (const auto &rawNode : rawNodes) {
}
return retval;
}
};
template <typename T>
@ -43,10 +57,11 @@ struct UnspecializedAssignable {
std::function<std::optional<AssignmentError>(T, AssignableInfo, AssignmentArgument)> func;
std::optional<std::string> unit;
std::string nodeName;
std::function<std::string(std::string, T)> hash;
static std::vector<DeviceNode> toDeviceNodes(
std::vector<UnspecializedAssignable<T>> rawNodes,
T devData) {
T devData, std::string uuid) {
std::vector<DeviceNode> retval;
for (auto &rawNode : rawNodes) {
if_let(pattern(some(arg)) = rawNode.assignableInfo(devData)) = [&](auto info) {
@ -55,7 +70,8 @@ struct UnspecializedAssignable {
}, info);
auto node = DeviceNode {
.name = rawNode.nodeName,
.interface = assignable
.interface = assignable,
.hash = rawNode.hash(uuid, devData)
};
retval.push_back(node);
};
@ -259,7 +275,10 @@ NvidiaPlugin::NvidiaPlugin() : m_dpy() {
return retval;
},
"W",
"Power Limit"
"Power Limit",
[](std::string uuid, nvmlDevice_t) {
return md5(uuid + "Power Limit");
}
}
};
@ -297,7 +316,10 @@ NvidiaPlugin::NvidiaPlugin() : m_dpy() {
return retval;
},
"MHz",
"Memory Clock Offset"
"Memory Clock Offset",
[](std::string uuid, NVClockInfo) {
return md5(uuid + "Memory Clock Offset");
}
}
};
@ -335,7 +357,10 @@ NvidiaPlugin::NvidiaPlugin() : m_dpy() {
return ret;
},
std::nullopt,
"Fan Mode"
"Fan Mode",
[](std::string uuid, uint) {
return md5(uuid + "Fan Mode");
}
}
};
@ -448,7 +473,7 @@ NvidiaPlugin::NvidiaPlugin() : m_dpy() {
gpuRoot.appendChild(specNode);
for (auto &node : UnspecializedAssignable<nvmlDevice_t>::toDeviceNodes(
rawNVMLAssignables, dev))
rawNVMLAssignables, dev, nvOpt.uuid))
gpuRoot.appendChild(node);
};
@ -472,11 +497,11 @@ NvidiaPlugin::NvidiaPlugin() : m_dpy() {
auto clockInfo = NVClockInfo{nvctrlPerfModes(index), index};
for (auto &node : UnspecializedAssignable<NVClockInfo>::toDeviceNodes(
rawNVCTRLClockAssignables, clockInfo))
rawNVCTRLClockAssignables, clockInfo, nvOpt.uuid))
gpuRoot.appendChild(node);
for (auto &node : UnspecializedAssignable<uint>::toDeviceNodes(
rawNVCTRLAssignables, index))
rawNVCTRLAssignables, index, nvOpt.uuid))
gpuRoot.appendChild(node);
};

View File

@ -34,5 +34,6 @@ if all_nvidia_linux_libs
include_directories : [incdir, patterns_inc, fplus_inc],
dependencies : [nvidia_linux_libs, boost_dep],
install_dir : get_option('libdir') / 'tuxclocker' / 'plugins',
install : true)
install : true,
link_with : libtuxclocker)
endif

View File

@ -16,14 +16,14 @@ public:
/* Returns a raw pointer since smart pointers caused some scope issues.
* TODO: try to use smart pointers instead? */
static std::optional<QDBusAbstractAdaptor*> adaptor(QObject *obj,
DeviceInterface iface) {
DeviceInterface iface, DeviceNode devNode) {
std::optional<QDBusAbstractAdaptor*> retval = std::nullopt;
match(iface)
(pattern(as<DynamicReadable>(arg)) = [&](auto dr) {
retval = new DynamicReadableAdaptor(obj, dr);
},
pattern(as<Assignable>(arg)) = [&](auto a) {
retval = new AssignableAdaptor(obj, a);
retval = new AssignableAdaptor(obj, a, devNode);
},
pattern(_) = []{});
return retval;

View File

@ -63,8 +63,8 @@ Q_DECLARE_METATYPE(TCDBus::Result<int>)
class AssignableAdaptor : public QDBusAbstractAdaptor {
public:
explicit AssignableAdaptor(QObject *obj, Assignable a) : QDBusAbstractAdaptor(obj),
m_assignable(a) {
explicit AssignableAdaptor(QObject *obj, Assignable a, DeviceNode devNode) :
QDBusAbstractAdaptor(obj), m_assignable(a), m_devNode(devNode) {
qDBusRegisterMetaType<TCDBus::Range>();
qDBusRegisterMetaType<TCDBus::Enumeration>();
qDBusRegisterMetaType<QVector<TCDBus::Enumeration>>();
@ -99,6 +99,7 @@ public:
m_dbusAssignableInfo = QDBusVariant(a_info);
}
QDBusVariant assignableInfo_() {return m_dbusAssignableInfo;}
QString hash_() {return QString::fromStdString(m_devNode.hash);}
public Q_SLOTS:
TCDBus::Result<int> assign(QDBusVariant arg_) {
auto v = arg_.variant();
@ -132,8 +133,10 @@ private:
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.tuxclocker.Assignable")
Q_PROPERTY(QDBusVariant assignableInfo READ assignableInfo_)
Q_PROPERTY(QString hash READ hash_)
Assignable m_assignable;
DeviceNode m_devNode;
QDBusVariant m_dbusAssignableInfo;
};
@ -155,7 +158,6 @@ public:
childIndices.append(i);
TCDBus::FlatTreeNode<TCDBus::DeviceNode> fn{f_node.value, childIndices};
qDebug("Hello");
m_flatTree.append(fn);
}
}

View File

@ -28,21 +28,36 @@ int main(int argc, char **argv) {
TreeNode<TCDBus::DeviceNode> dbusRootNode;
std::function<void(TreeNode<DeviceNode>, QString, TreeNode<TCDBus::DeviceNode>*)> traverse;
traverse = [&traverse, &connection, &adaptors, &root, &dbusRootNode](
traverse = [&traverse, &connection, &adaptors, &root](
TreeNode<DeviceNode> node,
QString parentPath, TreeNode<TCDBus::DeviceNode> *dbusNode) {
auto obj = new QObject(&root); // Is destroyed when root goes out of scope
// Remove whitespaces to make valid object paths
auto objName = QString::fromStdString(node.value().name).replace(" ", "");
auto thisPath = parentPath + objName;
QString ifaceName;
if_let(pattern(some(arg)) = node.value().interface) = [&](auto iface) {
if_let(pattern(some(arg)) = AdaptorFactory::adaptor(obj, iface)) = [&](auto adaptor) {
if_let(pattern(some(arg)) =
AdaptorFactory::adaptor(obj, iface, node.value())) = [&](auto adaptor) {
adaptors.append(adaptor);
connection.registerObject(thisPath, obj);
// TODO: don't hardcode interface name
// Maybe create an intermediate class that contains the interface name to avoid this
// For some reason this throws a bad_cast when using 'as' with pointer type
match(*adaptor)
(pattern(as<AssignableAdaptor>(_)) = [&] {
ifaceName = "org.tuxclocker.Assignable";
},
pattern(as<DynamicReadableAdaptor>(_)) = [&] {
ifaceName = "org.tuxclocker.DynamicReadable";
},
pattern(_) = [] {});
};
};
auto thisDBusNode = new TreeNode<TCDBus::DeviceNode>{{thisPath, "org.tuxclocker"}};
dbusNode->appendChild(*thisDBusNode);
auto thisDBusNode = TreeNode<TCDBus::DeviceNode>{{thisPath, ifaceName}};
dbusNode->appendChild(thisDBusNode);
qDebug() << thisPath;
for (const auto &child : node.children())
traverse(child, thisPath + "/", &dbusNode->childrenPtr()->back());