13d30708fSChicago Duan #pragma once
23d30708fSChicago Duan
33d30708fSChicago Duan #include "async_resp.hpp"
43d30708fSChicago Duan #include "dbus_singleton.hpp"
53d30708fSChicago Duan #include "dbus_utility.hpp"
63d30708fSChicago Duan #include "error_messages.hpp"
73d30708fSChicago Duan #include "event_service_manager.hpp"
83d30708fSChicago Duan #include "http_request.hpp"
93d30708fSChicago Duan #include "http_response.hpp"
103d30708fSChicago Duan #include "logging.hpp"
113d30708fSChicago Duan #include "utils/dbus_utils.hpp"
123d30708fSChicago Duan
133d30708fSChicago Duan #include <boost/system/error_code.hpp>
143d30708fSChicago Duan #include <boost/url/format.hpp>
153d30708fSChicago Duan #include <sdbusplus/unpack_properties.hpp>
163d30708fSChicago Duan
173d30708fSChicago Duan #include <memory>
183d30708fSChicago Duan #include <string>
193d30708fSChicago Duan #include <string_view>
203d30708fSChicago Duan
213d30708fSChicago Duan namespace redfish
223d30708fSChicago Duan {
233d30708fSChicago Duan
afterGetSnmpTrapClientdata(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const boost::system::error_code & ec,const dbus::utility::DBusPropertiesMap & propertiesList)243d30708fSChicago Duan inline void afterGetSnmpTrapClientdata(
253d30708fSChicago Duan const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
263d30708fSChicago Duan const boost::system::error_code& ec,
273d30708fSChicago Duan const dbus::utility::DBusPropertiesMap& propertiesList)
283d30708fSChicago Duan {
293d30708fSChicago Duan if (ec)
303d30708fSChicago Duan {
3162598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus response error on GetSubTree {}", ec);
323d30708fSChicago Duan messages::internalError(asyncResp->res);
333d30708fSChicago Duan return;
343d30708fSChicago Duan }
353d30708fSChicago Duan
363d30708fSChicago Duan std::string address;
373d30708fSChicago Duan uint16_t port = 0;
383d30708fSChicago Duan
393d30708fSChicago Duan bool success = sdbusplus::unpackPropertiesNoThrow(
403d30708fSChicago Duan dbus_utils::UnpackErrorPrinter(), propertiesList, "Address", address,
413d30708fSChicago Duan "Port", port);
423d30708fSChicago Duan
433d30708fSChicago Duan if (!success)
443d30708fSChicago Duan {
453d30708fSChicago Duan messages::internalError(asyncResp->res);
463d30708fSChicago Duan return;
473d30708fSChicago Duan }
483d30708fSChicago Duan
493d30708fSChicago Duan asyncResp->res.jsonValue["Destination"] =
503d30708fSChicago Duan boost::urls::format("snmp://{}:{}", address, port);
513d30708fSChicago Duan }
523d30708fSChicago Duan
533d30708fSChicago Duan inline void
getSnmpTrapClientdata(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & id,const std::string & objectPath)543d30708fSChicago Duan getSnmpTrapClientdata(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
553d30708fSChicago Duan const std::string& id, const std::string& objectPath)
563d30708fSChicago Duan {
573d30708fSChicago Duan asyncResp->res.jsonValue["@odata.type"] =
583d30708fSChicago Duan "#EventDestination.v1_8_0.EventDestination";
593d30708fSChicago Duan asyncResp->res.jsonValue["Protocol"] = "SNMPv2c";
603d30708fSChicago Duan asyncResp->res.jsonValue["@odata.id"] =
613d30708fSChicago Duan boost::urls::format("/redfish/v1/EventService/Subscriptions/{}", id);
623d30708fSChicago Duan
633d30708fSChicago Duan asyncResp->res.jsonValue["Id"] = id;
643d30708fSChicago Duan asyncResp->res.jsonValue["Name"] = "Event Destination";
653d30708fSChicago Duan
663d30708fSChicago Duan asyncResp->res.jsonValue["SubscriptionType"] = "SNMPTrap";
673d30708fSChicago Duan asyncResp->res.jsonValue["EventFormatType"] = "Event";
683d30708fSChicago Duan
693d30708fSChicago Duan std::shared_ptr<Subscription> subValue =
703d30708fSChicago Duan EventServiceManager::getInstance().getSubscription(id);
713d30708fSChicago Duan if (subValue != nullptr)
723d30708fSChicago Duan {
733d30708fSChicago Duan asyncResp->res.jsonValue["Context"] = subValue->customText;
743d30708fSChicago Duan }
753d30708fSChicago Duan else
763d30708fSChicago Duan {
773d30708fSChicago Duan asyncResp->res.jsonValue["Context"] = "";
783d30708fSChicago Duan }
793d30708fSChicago Duan
803d30708fSChicago Duan sdbusplus::asio::getAllProperties(
813d30708fSChicago Duan *crow::connections::systemBus, "xyz.openbmc_project.Network.SNMP",
823d30708fSChicago Duan objectPath, "xyz.openbmc_project.Network.Client",
833d30708fSChicago Duan [asyncResp](const boost::system::error_code& ec,
843d30708fSChicago Duan const dbus::utility::DBusPropertiesMap& properties) {
853d30708fSChicago Duan afterGetSnmpTrapClientdata(asyncResp, ec, properties);
863d30708fSChicago Duan });
873d30708fSChicago Duan }
883d30708fSChicago Duan
893d30708fSChicago Duan inline void
getSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & id)903d30708fSChicago Duan getSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
913d30708fSChicago Duan const std::string& id)
923d30708fSChicago Duan {
933d30708fSChicago Duan crow::connections::systemBus->async_method_call(
943d30708fSChicago Duan [asyncResp, id](const boost::system::error_code& ec,
953d30708fSChicago Duan dbus::utility::ManagedObjectType& resp) {
963d30708fSChicago Duan if (ec)
973d30708fSChicago Duan {
9862598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}",
9962598e31SEd Tanous ec);
1003d30708fSChicago Duan messages::internalError(asyncResp->res);
1013d30708fSChicago Duan return;
1023d30708fSChicago Duan }
1033d30708fSChicago Duan
1043d30708fSChicago Duan for (const auto& objpath : resp)
1053d30708fSChicago Duan {
1063d30708fSChicago Duan sdbusplus::message::object_path path(objpath.first);
1073d30708fSChicago Duan const std::string snmpId = path.filename();
1083d30708fSChicago Duan if (snmpId.empty())
1093d30708fSChicago Duan {
11062598e31SEd Tanous BMCWEB_LOG_ERROR("The SNMP client ID is wrong");
1113d30708fSChicago Duan messages::internalError(asyncResp->res);
1123d30708fSChicago Duan return;
1133d30708fSChicago Duan }
1143d30708fSChicago Duan const std::string subscriptionId = "snmp" + snmpId;
1153d30708fSChicago Duan if (id != subscriptionId)
1163d30708fSChicago Duan {
1173d30708fSChicago Duan continue;
1183d30708fSChicago Duan }
1193d30708fSChicago Duan
1203d30708fSChicago Duan getSnmpTrapClientdata(asyncResp, id, objpath.first);
1213d30708fSChicago Duan return;
1223d30708fSChicago Duan }
1233d30708fSChicago Duan
1243d30708fSChicago Duan messages::resourceNotFound(asyncResp->res, "Subscriptions", id);
1253d30708fSChicago Duan EventServiceManager::getInstance().deleteSubscription(id);
1263d30708fSChicago Duan },
1273d30708fSChicago Duan "xyz.openbmc_project.Network.SNMP",
1283d30708fSChicago Duan "/xyz/openbmc_project/network/snmp/manager",
1293d30708fSChicago Duan "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
1303d30708fSChicago Duan }
1313d30708fSChicago Duan
afterSnmpClientCreate(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const boost::system::error_code & ec,const sdbusplus::message_t & msg,const std::string & host,const std::string & dbusSNMPid)132*63509dd5SRavi Teja inline void afterSnmpClientCreate(
133*63509dd5SRavi Teja const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
134*63509dd5SRavi Teja const boost::system::error_code& ec, const sdbusplus::message_t& msg,
135*63509dd5SRavi Teja const std::string& host, const std::string& dbusSNMPid)
1363d30708fSChicago Duan {
1373d30708fSChicago Duan if (ec)
1383d30708fSChicago Duan {
139*63509dd5SRavi Teja const sd_bus_error* dbusError = msg.get_error();
140*63509dd5SRavi Teja if (dbusError != nullptr)
141*63509dd5SRavi Teja {
142*63509dd5SRavi Teja if (std::string_view(
143*63509dd5SRavi Teja "xyz.openbmc_project.Common.Error.InvalidArgument") ==
144*63509dd5SRavi Teja dbusError->name)
145*63509dd5SRavi Teja {
146*63509dd5SRavi Teja messages::propertyValueIncorrect(asyncResp->res, "Destination",
147*63509dd5SRavi Teja host);
148*63509dd5SRavi Teja return;
149*63509dd5SRavi Teja }
1503d30708fSChicago Duan if (ec.value() != EBADR)
1513d30708fSChicago Duan {
1523d30708fSChicago Duan // SNMP not installed
1533d30708fSChicago Duan messages::propertyValueOutOfRange(asyncResp->res, "SNMPv2c",
1543d30708fSChicago Duan "Protocol");
1553d30708fSChicago Duan return;
1563d30708fSChicago Duan }
157*63509dd5SRavi Teja }
1583d30708fSChicago Duan messages::internalError(asyncResp->res);
1593d30708fSChicago Duan return;
1603d30708fSChicago Duan }
1613d30708fSChicago Duan sdbusplus::message::object_path path(dbusSNMPid);
1623d30708fSChicago Duan const std::string snmpId = path.filename();
1633d30708fSChicago Duan if (snmpId.empty())
1643d30708fSChicago Duan {
1653d30708fSChicago Duan messages::internalError(asyncResp->res);
1663d30708fSChicago Duan return;
1673d30708fSChicago Duan }
1683d30708fSChicago Duan
1693d30708fSChicago Duan std::string subscriptionId = "snmp" + snmpId;
1703d30708fSChicago Duan
1713d30708fSChicago Duan boost::urls::url uri = boost::urls::format(
1723d30708fSChicago Duan "/redfish/v1/EventService/Subscriptions/{}", subscriptionId);
1733d30708fSChicago Duan asyncResp->res.addHeader("Location", uri.buffer());
1743d30708fSChicago Duan messages::created(asyncResp->res);
1753d30708fSChicago Duan }
1763d30708fSChicago Duan
1773d30708fSChicago Duan inline void
addSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & host,uint16_t snmpTrapPort)1783d30708fSChicago Duan addSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1793d30708fSChicago Duan const std::string& host, uint16_t snmpTrapPort)
1803d30708fSChicago Duan {
1813d30708fSChicago Duan crow::connections::systemBus->async_method_call(
182*63509dd5SRavi Teja [asyncResp, host](const boost::system::error_code& ec,
183*63509dd5SRavi Teja const sdbusplus::message_t& msg,
1843d30708fSChicago Duan const std::string& dbusSNMPid) {
185*63509dd5SRavi Teja afterSnmpClientCreate(asyncResp, ec, msg, host, dbusSNMPid);
1863d30708fSChicago Duan },
1873d30708fSChicago Duan "xyz.openbmc_project.Network.SNMP",
1883d30708fSChicago Duan "/xyz/openbmc_project/network/snmp/manager",
1893d30708fSChicago Duan "xyz.openbmc_project.Network.Client.Create", "Client", host,
1903d30708fSChicago Duan snmpTrapPort);
1913d30708fSChicago Duan }
1923d30708fSChicago Duan
1933d30708fSChicago Duan inline void
getSnmpSubscriptionList(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & snmpId,nlohmann::json & memberArray)1943d30708fSChicago Duan getSnmpSubscriptionList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1953d30708fSChicago Duan const std::string& snmpId,
1963d30708fSChicago Duan nlohmann::json& memberArray)
1973d30708fSChicago Duan {
1983d30708fSChicago Duan const std::string subscriptionId = "snmp" + snmpId;
1993d30708fSChicago Duan
2003d30708fSChicago Duan nlohmann::json::object_t member;
2013d30708fSChicago Duan member["@odata.id"] = boost::urls::format(
2023d30708fSChicago Duan "/redfish/v1/EventService/Subscriptions/{}", subscriptionId);
2033d30708fSChicago Duan memberArray.push_back(std::move(member));
2043d30708fSChicago Duan
2053d30708fSChicago Duan asyncResp->res.jsonValue["Members@odata.count"] = memberArray.size();
2063d30708fSChicago Duan }
2073d30708fSChicago Duan
2083d30708fSChicago Duan inline void
deleteSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & param)2093d30708fSChicago Duan deleteSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2103d30708fSChicago Duan const std::string& param)
2113d30708fSChicago Duan {
2123d30708fSChicago Duan std::string_view snmpTrapId = param;
2133d30708fSChicago Duan
2143d30708fSChicago Duan // Erase "snmp" in the request to find the corresponding
2153d30708fSChicago Duan // dbus snmp client id. For example, the snmpid in the
2163d30708fSChicago Duan // request is "snmp1", which will be "1" after being erased.
2173d30708fSChicago Duan snmpTrapId.remove_prefix(4);
2183d30708fSChicago Duan
2193d30708fSChicago Duan sdbusplus::message::object_path snmpPath =
2203d30708fSChicago Duan sdbusplus::message::object_path(
2213d30708fSChicago Duan "/xyz/openbmc_project/network/snmp/manager") /
2223d30708fSChicago Duan std::string(snmpTrapId);
2233d30708fSChicago Duan
2243d30708fSChicago Duan crow::connections::systemBus->async_method_call(
2253d30708fSChicago Duan [asyncResp, param](const boost::system::error_code& ec) {
2263d30708fSChicago Duan if (ec)
2273d30708fSChicago Duan {
2283d30708fSChicago Duan // The snmp trap id is incorrect
2293d30708fSChicago Duan if (ec.value() == EBADR)
2303d30708fSChicago Duan {
2313d30708fSChicago Duan messages::resourceNotFound(asyncResp->res, "Subscription",
2323d30708fSChicago Duan param);
2333d30708fSChicago Duan return;
2343d30708fSChicago Duan }
2353d30708fSChicago Duan messages::internalError(asyncResp->res);
2363d30708fSChicago Duan return;
2373d30708fSChicago Duan }
2383d30708fSChicago Duan messages::success(asyncResp->res);
2393d30708fSChicago Duan },
2403d30708fSChicago Duan "xyz.openbmc_project.Network.SNMP", static_cast<std::string>(snmpPath),
2413d30708fSChicago Duan "xyz.openbmc_project.Object.Delete", "Delete");
2423d30708fSChicago Duan }
2433d30708fSChicago Duan
2443d30708fSChicago Duan } // namespace redfish
245