diff options
| author | Ed Tanous <ed.tanous@intel.com> | 2017-05-11 10:27:23 -0700 |
|---|---|---|
| committer | Ed Tanous <ed.tanous@intel.com> | 2017-05-11 10:27:23 -0700 |
| commit | cc5a37f7362e8aabb8f21705c8583d2ff19a641d (patch) | |
| tree | 5608eb4c28bc22aa221aa503916946fa5b79d827 /src | |
| parent | e2fc45a1cd7645e50754d93ce52ec8935e723007 (diff) | |
| download | bmcweb-cc5a37f7362e8aabb8f21705c8583d2ff19a641d.tar.gz bmcweb-cc5a37f7362e8aabb8f21705c8583d2ff19a641d.zip | |
incremental
Diffstat (limited to 'src')
| -rw-r--r-- | src/dbus_main.cpp | 455 | ||||
| -rw-r--r-- | src/test_resources/blns (renamed from src/test_resources/blns.txt) | 0 | ||||
| -rw-r--r-- | src/webserver_main.cpp | 197 |
3 files changed, 652 insertions, 0 deletions
diff --git a/src/dbus_main.cpp b/src/dbus_main.cpp new file mode 100644 index 0000000..6cee92e --- /dev/null +++ b/src/dbus_main.cpp @@ -0,0 +1,455 @@ +#define DBUS_API_SUBJECT_TO_CHANGE +#include <dbus/dbus.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <iostream> +#include <string> +#include <vector> +#include <boost/iostreams/stream.hpp> +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/xml_parser.hpp> + +/** + * Connect to the DBUS bus and send a broadcast signal + */ +void sendsignal(char* sigvalue) { + DBusMessage* msg; + DBusMessageIter args; + DBusConnection* conn; + DBusError err; + int ret; + dbus_uint32_t serial = 0; + + printf("Sending signal with value %s\n", sigvalue); + + // initialise the error value + dbus_error_init(&err); + + // connect to the DBUS system bus, and check for errors + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) { + exit(1); + } + + // register our name on the bus, and check for errors + ret = dbus_bus_request_name(conn, "test.signal.source", + DBUS_NAME_FLAG_REPLACE_EXISTING, &err); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { + exit(1); + } + + // create a signal & check for errors + msg = dbus_message_new_signal( + "/test/signal/Object", // object name of the signal + "test.signal.Type", // interface name of the signal + "Test"); // name of the signal + if (NULL == msg) { + fprintf(stderr, "Message Null\n"); + exit(1); + } + + // append arguments onto signal + dbus_message_iter_init_append(msg, &args); + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) { + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + + // send the message and flush the connection + if (!dbus_connection_send(conn, msg, &serial)) { + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + dbus_connection_flush(conn); + + printf("Signal Sent\n"); + + // free the message and close the connection + dbus_message_unref(msg); + dbus_connection_close(conn); +} + +/** + * Call a method on a remote object + */ +void query(const char* param) { + DBusMessage* msg; + DBusMessageIter args; + DBusConnection* conn; + DBusError err; + DBusPendingCall* pending; + int ret; + bool stat; + dbus_uint32_t level; + + printf("Calling remote method with %s\n", param); + + // initialiset the errors + dbus_error_init(&err); + + // connect to the system bus and check for errors + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) { + exit(1); + } + /* + // request our name on the bus + ret = dbus_bus_request_name(conn, "test.method.caller", + DBUS_NAME_FLAG_REPLACE_EXISTING , &err); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { + exit(1); + } + */ + + // create a new method call and check for errors + msg = dbus_message_new_method_call( + "org.freedesktop.Avahi", // target for the method call + "/", // object to call on + "org.freedesktop.Avahi.Server", // interface to call on + "GetHostName"); // method name + if (NULL == msg) { + fprintf(stderr, "Message Null\n"); + exit(1); + } + + // append arguments + /* + dbus_message_iter_init_append(msg, &args); + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, ¶m)) { + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + */ + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, + -1)) { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + if (NULL == pending) { + fprintf(stderr, "Pending Call Null\n"); + exit(1); + } + dbus_connection_flush(conn); + + printf("Request Sent\n"); + + // free message + dbus_message_unref(msg); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) { + fprintf(stderr, "Reply Null\n"); + exit(1); + } + // free the pending message handle + dbus_pending_call_unref(pending); + + // read the parameters + char* str = NULL; + if (!dbus_message_iter_init(msg, &args)) + fprintf(stderr, "Message has no arguments!\n"); + else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) + fprintf(stderr, "Argument is not boolean!\n"); + else + dbus_message_iter_get_basic(&args, &str); + + printf("Got Reply: %s\n", str); + + // free reply and close connection + dbus_message_unref(msg); + dbus_connection_close(conn); +} + +void list_names() { + DBusError err; + + int ret; + bool stat; + dbus_uint32_t level; + + // initialiset the errors + dbus_error_init(&err); + + // connect to the system bus and check for errors + DBusConnection* conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) { + exit(1); + } + + // create a new method call and check for errors + DBusMessage* msg = dbus_message_new_method_call( + "org.freedesktop.DBus", // target for the method call + "/", // object to call on + "org.freedesktop.DBus", // interface to call on + "ListNames"); // method name + if (NULL == msg) { + fprintf(stderr, "Message Null\n"); + exit(1); + } + + DBusPendingCall* pending; + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, + -1)) { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + if (NULL == pending) { + fprintf(stderr, "Pending Call Null\n"); + exit(1); + } + dbus_connection_flush(conn); + + // free message + dbus_message_unref(msg); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) { + fprintf(stderr, "Reply Null\n"); + exit(1); + } + // free the pending message handle + dbus_pending_call_unref(pending); + + // read the parameters + DBusMessageIter args; + DBusMessageIter strings; + char* paths = NULL; + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "Message has no arguments!\n"); + } + std::vector<std::string> names; + do { + dbus_message_iter_recurse(&args, &strings); + do { + dbus_message_iter_get_basic(&strings, &paths); + names.emplace_back(paths); + } while (dbus_message_iter_next(&strings)); + } while (dbus_message_iter_next(&args)); + + // free reply and close connection + dbus_message_unref(msg); + dbus_connection_close(conn); +} + +std::vector<std::string> read_dbus_xml_names(std::string& xml_data) { + std::vector<std::string> values; + // populate tree structure pt + using boost::property_tree::ptree; + ptree pt; + boost::iostreams::stream<boost::iostreams::array_source> stream( + xml_data.c_str(), xml_data.size()); + read_xml(stream, pt); + + // traverse node to find other nodes + for (const auto& interface : pt.get_child("node")) { + if (interface.first == "node") { + auto t = interface.second.get<std::string>("<xmlattr>", "default"); + for (const auto& subnode : interface.second.get_child("<xmlattr>")) { + if (subnode.first == "name") { + auto t = subnode.second.get("", "unknown"); + values.emplace_back(std::move(t)); + } + } + } + } + return values; +} + +using sensor_values=std::vector<std::pair<std::string, int32_t>>; + +sensor_values read_sensor_values() { + sensor_values values; + DBusError err; + + int ret; + bool stat; + dbus_uint32_t level; + + // initialiset the errors + dbus_error_init(&err); + + // connect to the system bus and check for errors + DBusConnection* conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) { + exit(1); + } + + // create a new method call and check for errors + DBusMessage* msg = dbus_message_new_method_call( + "org.openbmc.Sensors", // target for the method call + "/org/openbmc/sensors/tach", // object to call on + "org.freedesktop.DBus.Introspectable", // interface to call on + "Introspect"); // method name + if (NULL == msg) { + fprintf(stderr, "Message Null\n"); + exit(1); + } + + DBusPendingCall* pending; + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, + -1)) { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + if (NULL == pending) { + fprintf(stderr, "Pending Call Null\n"); + exit(1); + } + dbus_connection_flush(conn); + + // free message + dbus_message_unref(msg); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) { + fprintf(stderr, "Reply Null\n"); + exit(1); + } + // free the pending message handle + dbus_pending_call_unref(pending); + + // read the parameters + DBusMessageIter args; + char* xml_struct = NULL; + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "Message has no arguments!\n"); + } + + // read the arguments + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "Message has no arguments!\n"); + } else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "Argument is not string!\n"); + } else { + dbus_message_iter_get_basic(&args, &xml_struct); + } + std::vector<std::string> methods; + if (xml_struct != NULL) { + std::string xml_data(xml_struct); + methods = read_dbus_xml_names(xml_data); + } + + fprintf(stdout, "Found %ld sensors \n", methods.size()); + + for (auto& method : methods) { + // TODO(Ed) make sure sensor exposes SensorValue interface + // create a new method call and check for errors + DBusMessage* msg = dbus_message_new_method_call( + "org.openbmc.Sensors", // target for the method call + ("/org/openbmc/sensors/tach/" + method).c_str(), // object to call on + "org.openbmc.SensorValue", // interface to call on + "getValue"); // method name + if (NULL == msg) { + fprintf(stderr, "Message Null\n"); + exit(1); + } + + DBusPendingCall* pending; + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, + -1)) { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + if (NULL == pending) { + fprintf(stderr, "Pending Call Null\n"); + exit(1); + } + dbus_connection_flush(conn); + + // free message + dbus_message_unref(msg); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) { + fprintf(stderr, "Reply Null\n"); + exit(1); + } + // free the pending message handle + dbus_pending_call_unref(pending); + + // read the parameters + DBusMessageIter args; + int32_t value; + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "Message has no arguments!\n"); + } + + // read the arguments + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "Message has no arguments!\n"); + } else if (DBUS_TYPE_VARIANT != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "Argument is not string!\n"); + } else { + DBusMessageIter sub; + dbus_message_iter_recurse(&args, &sub); + auto type = dbus_message_iter_get_arg_type(&sub); + if (DBUS_TYPE_INT32 != type) { + fprintf(stderr, "Variant subType is not int32 it is %d\n", type); + } else { + dbus_message_iter_get_basic(&sub, &value); + values.emplace_back(method.c_str(), value); + } + } + } + + // free reply and close connection + dbus_message_unref(msg); + return values; +} + + +int main(int argc, char** argv) { + auto values = read_sensor_values(); + + for (auto value: values){ + std::cout << value.first << ": " << value.second << "\n"; + } + + return 0; +}
\ No newline at end of file diff --git a/src/test_resources/blns.txt b/src/test_resources/blns index cdbac02..cdbac02 100644 --- a/src/test_resources/blns.txt +++ b/src/test_resources/blns diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp index 2ec7e37..82b83a7 100644 --- a/src/webserver_main.cpp +++ b/src/webserver_main.cpp @@ -31,11 +31,196 @@ #include <boost/asio.hpp> #include <boost/endian/arithmetic.hpp> +#include <dbus/dbus.h> +#include <boost/iostreams/stream.hpp> +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/xml_parser.hpp> + #include <iostream> #include <memory> #include <string> #include <unordered_set> +using sensor_values = std::vector<std::pair<std::string, int32_t>>; + +std::vector<std::string> read_dbus_xml_names(std::string& xml_data) { + std::vector<std::string> values; + // populate tree structure pt + using boost::property_tree::ptree; + ptree pt; + boost::iostreams::stream<boost::iostreams::array_source> stream( + xml_data.c_str(), xml_data.size()); + read_xml(stream, pt); + + // traverse node to find other nodes + for (const auto& interface : pt.get_child("node")) { + if (interface.first == "node") { + auto t = interface.second.get<std::string>("<xmlattr>", "default"); + for (const auto& subnode : interface.second.get_child("<xmlattr>")) { + if (subnode.first == "name") { + auto t = subnode.second.get("", "unknown"); + values.emplace_back(std::move(t)); + } + } + } + } + return values; +} + +sensor_values read_sensor_values() { + sensor_values values; + DBusError err; + + int ret; + bool stat; + dbus_uint32_t level; + + // initialiset the errors + dbus_error_init(&err); + + // connect to the system bus and check for errors + DBusConnection* conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) { + exit(1); + } + + // create a new method call and check for errors + DBusMessage* msg = dbus_message_new_method_call( + "org.openbmc.Sensors", // target for the method call + "/org/openbmc/sensors/tach", // object to call on + "org.freedesktop.DBus.Introspectable", // interface to call on + "Introspect"); // method name + if (NULL == msg) { + fprintf(stderr, "Message Null\n"); + exit(1); + } + + DBusPendingCall* pending; + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, + -1)) { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + if (NULL == pending) { + fprintf(stderr, "Pending Call Null\n"); + exit(1); + } + dbus_connection_flush(conn); + + // free message + dbus_message_unref(msg); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) { + fprintf(stderr, "Reply Null\n"); + exit(1); + } + // free the pending message handle + dbus_pending_call_unref(pending); + + // read the parameters + DBusMessageIter args; + char* xml_struct = NULL; + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "Message has no arguments!\n"); + } + + // read the arguments + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "Message has no arguments!\n"); + } else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "Argument is not string!\n"); + } else { + dbus_message_iter_get_basic(&args, &xml_struct); + } + std::vector<std::string> methods; + if (xml_struct != NULL) { + std::string xml_data(xml_struct); + methods = read_dbus_xml_names(xml_data); + } + + fprintf(stdout, "Found %ld sensors \n", methods.size()); + + for (auto& method : methods) { + // TODO(Ed) make sure sensor exposes SensorValue interface + // create a new method call and check for errors + DBusMessage* msg = dbus_message_new_method_call( + "org.openbmc.Sensors", // target for the method call + ("/org/openbmc/sensors/tach/" + method).c_str(), // object to call on + "org.openbmc.SensorValue", // interface to call on + "getValue"); // method name + if (NULL == msg) { + fprintf(stderr, "Message Null\n"); + exit(1); + } + + DBusPendingCall* pending; + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, + -1)) { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + if (NULL == pending) { + fprintf(stderr, "Pending Call Null\n"); + exit(1); + } + dbus_connection_flush(conn); + + // free message + dbus_message_unref(msg); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) { + fprintf(stderr, "Reply Null\n"); + exit(1); + } + // free the pending message handle + dbus_pending_call_unref(pending); + + // read the parameters + DBusMessageIter args; + int32_t value; + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "Message has no arguments!\n"); + } + + // read the arguments + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "Message has no arguments!\n"); + } else if (DBUS_TYPE_VARIANT != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "Argument is not string!\n"); + } else { + DBusMessageIter sub; + dbus_message_iter_recurse(&args, &sub); + auto type = dbus_message_iter_get_arg_type(&sub); + if (DBUS_TYPE_INT32 != type) { + fprintf(stderr, "Variant subType is not int32 it is %d\n", type); + } else { + dbus_message_iter_get_basic(&sub, &value); + values.emplace_back(method.c_str(), value); + } + } + } + + // free reply and close connection + dbus_message_unref(msg); + return values; +} + int main(int argc, char** argv) { auto worker(g3::LogWorker::createLogWorker()); std::string logger_name("bmcweb"); @@ -114,6 +299,18 @@ int main(int argc, char** argv) { conn.send_binary(str); }); + + CROW_ROUTE(app, "/sensortest") + ([]() { + crow::json::wvalue j; + auto values = read_sensor_values(); + for (auto& pair : values) { + j[pair.first] = pair.second; + } + + return j; + }); + auto ssl_context = ensuressl::get_ssl_context(ssl_pem_file); app.port(18080) //.ssl(std::move(ssl_context)) |

