1*3d30708fSChicago Duan #pragma once 2*3d30708fSChicago Duan 3*3d30708fSChicago Duan #include "async_resp.hpp" 4*3d30708fSChicago Duan #include "dbus_singleton.hpp" 5*3d30708fSChicago Duan #include "dbus_utility.hpp" 6*3d30708fSChicago Duan #include "error_messages.hpp" 7*3d30708fSChicago Duan #include "event_service_manager.hpp" 8*3d30708fSChicago Duan #include "http_request.hpp" 9*3d30708fSChicago Duan #include "http_response.hpp" 10*3d30708fSChicago Duan #include "logging.hpp" 11*3d30708fSChicago Duan #include "utils/dbus_utils.hpp" 12*3d30708fSChicago Duan 13*3d30708fSChicago Duan #include <boost/system/error_code.hpp> 14*3d30708fSChicago Duan #include <boost/url/format.hpp> 15*3d30708fSChicago Duan #include <sdbusplus/unpack_properties.hpp> 16*3d30708fSChicago Duan 17*3d30708fSChicago Duan #include <memory> 18*3d30708fSChicago Duan #include <string> 19*3d30708fSChicago Duan #include <string_view> 20*3d30708fSChicago Duan 21*3d30708fSChicago Duan namespace redfish 22*3d30708fSChicago Duan { 23*3d30708fSChicago Duan 24*3d30708fSChicago Duan inline void afterGetSnmpTrapClientdata( 25*3d30708fSChicago Duan const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 26*3d30708fSChicago Duan const boost::system::error_code& ec, 27*3d30708fSChicago Duan const dbus::utility::DBusPropertiesMap& propertiesList) 28*3d30708fSChicago Duan { 29*3d30708fSChicago Duan if (ec) 30*3d30708fSChicago Duan { 31*3d30708fSChicago Duan BMCWEB_LOG_ERROR << "D-Bus response error on GetSubTree " << ec; 32*3d30708fSChicago Duan messages::internalError(asyncResp->res); 33*3d30708fSChicago Duan return; 34*3d30708fSChicago Duan } 35*3d30708fSChicago Duan 36*3d30708fSChicago Duan std::string address; 37*3d30708fSChicago Duan uint16_t port = 0; 38*3d30708fSChicago Duan 39*3d30708fSChicago Duan bool success = sdbusplus::unpackPropertiesNoThrow( 40*3d30708fSChicago Duan dbus_utils::UnpackErrorPrinter(), propertiesList, "Address", address, 41*3d30708fSChicago Duan "Port", port); 42*3d30708fSChicago Duan 43*3d30708fSChicago Duan if (!success) 44*3d30708fSChicago Duan { 45*3d30708fSChicago Duan messages::internalError(asyncResp->res); 46*3d30708fSChicago Duan return; 47*3d30708fSChicago Duan } 48*3d30708fSChicago Duan 49*3d30708fSChicago Duan asyncResp->res.jsonValue["Destination"] = 50*3d30708fSChicago Duan boost::urls::format("snmp://{}:{}", address, port); 51*3d30708fSChicago Duan } 52*3d30708fSChicago Duan 53*3d30708fSChicago Duan inline void 54*3d30708fSChicago Duan getSnmpTrapClientdata(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 55*3d30708fSChicago Duan const std::string& id, const std::string& objectPath) 56*3d30708fSChicago Duan { 57*3d30708fSChicago Duan asyncResp->res.jsonValue["@odata.type"] = 58*3d30708fSChicago Duan "#EventDestination.v1_8_0.EventDestination"; 59*3d30708fSChicago Duan asyncResp->res.jsonValue["Protocol"] = "SNMPv2c"; 60*3d30708fSChicago Duan asyncResp->res.jsonValue["@odata.id"] = 61*3d30708fSChicago Duan boost::urls::format("/redfish/v1/EventService/Subscriptions/{}", id); 62*3d30708fSChicago Duan 63*3d30708fSChicago Duan asyncResp->res.jsonValue["Id"] = id; 64*3d30708fSChicago Duan asyncResp->res.jsonValue["Name"] = "Event Destination"; 65*3d30708fSChicago Duan 66*3d30708fSChicago Duan asyncResp->res.jsonValue["SubscriptionType"] = "SNMPTrap"; 67*3d30708fSChicago Duan asyncResp->res.jsonValue["EventFormatType"] = "Event"; 68*3d30708fSChicago Duan 69*3d30708fSChicago Duan std::shared_ptr<Subscription> subValue = 70*3d30708fSChicago Duan EventServiceManager::getInstance().getSubscription(id); 71*3d30708fSChicago Duan if (subValue != nullptr) 72*3d30708fSChicago Duan { 73*3d30708fSChicago Duan asyncResp->res.jsonValue["Context"] = subValue->customText; 74*3d30708fSChicago Duan } 75*3d30708fSChicago Duan else 76*3d30708fSChicago Duan { 77*3d30708fSChicago Duan asyncResp->res.jsonValue["Context"] = ""; 78*3d30708fSChicago Duan } 79*3d30708fSChicago Duan 80*3d30708fSChicago Duan sdbusplus::asio::getAllProperties( 81*3d30708fSChicago Duan *crow::connections::systemBus, "xyz.openbmc_project.Network.SNMP", 82*3d30708fSChicago Duan objectPath, "xyz.openbmc_project.Network.Client", 83*3d30708fSChicago Duan [asyncResp](const boost::system::error_code& ec, 84*3d30708fSChicago Duan const dbus::utility::DBusPropertiesMap& properties) { 85*3d30708fSChicago Duan afterGetSnmpTrapClientdata(asyncResp, ec, properties); 86*3d30708fSChicago Duan }); 87*3d30708fSChicago Duan } 88*3d30708fSChicago Duan 89*3d30708fSChicago Duan inline void 90*3d30708fSChicago Duan getSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 91*3d30708fSChicago Duan const std::string& id) 92*3d30708fSChicago Duan { 93*3d30708fSChicago Duan crow::connections::systemBus->async_method_call( 94*3d30708fSChicago Duan [asyncResp, id](const boost::system::error_code& ec, 95*3d30708fSChicago Duan dbus::utility::ManagedObjectType& resp) { 96*3d30708fSChicago Duan if (ec) 97*3d30708fSChicago Duan { 98*3d30708fSChicago Duan BMCWEB_LOG_ERROR << "D-Bus response error on GetManagedObjects " 99*3d30708fSChicago Duan << ec; 100*3d30708fSChicago Duan messages::internalError(asyncResp->res); 101*3d30708fSChicago Duan return; 102*3d30708fSChicago Duan } 103*3d30708fSChicago Duan 104*3d30708fSChicago Duan for (const auto& objpath : resp) 105*3d30708fSChicago Duan { 106*3d30708fSChicago Duan sdbusplus::message::object_path path(objpath.first); 107*3d30708fSChicago Duan const std::string snmpId = path.filename(); 108*3d30708fSChicago Duan if (snmpId.empty()) 109*3d30708fSChicago Duan { 110*3d30708fSChicago Duan BMCWEB_LOG_ERROR << "The SNMP client ID is wrong"; 111*3d30708fSChicago Duan messages::internalError(asyncResp->res); 112*3d30708fSChicago Duan return; 113*3d30708fSChicago Duan } 114*3d30708fSChicago Duan const std::string subscriptionId = "snmp" + snmpId; 115*3d30708fSChicago Duan if (id != subscriptionId) 116*3d30708fSChicago Duan { 117*3d30708fSChicago Duan continue; 118*3d30708fSChicago Duan } 119*3d30708fSChicago Duan 120*3d30708fSChicago Duan getSnmpTrapClientdata(asyncResp, id, objpath.first); 121*3d30708fSChicago Duan return; 122*3d30708fSChicago Duan } 123*3d30708fSChicago Duan 124*3d30708fSChicago Duan messages::resourceNotFound(asyncResp->res, "Subscriptions", id); 125*3d30708fSChicago Duan EventServiceManager::getInstance().deleteSubscription(id); 126*3d30708fSChicago Duan }, 127*3d30708fSChicago Duan "xyz.openbmc_project.Network.SNMP", 128*3d30708fSChicago Duan "/xyz/openbmc_project/network/snmp/manager", 129*3d30708fSChicago Duan "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 130*3d30708fSChicago Duan } 131*3d30708fSChicago Duan 132*3d30708fSChicago Duan inline void 133*3d30708fSChicago Duan afterSnmpClientCreate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 134*3d30708fSChicago Duan const boost::system::error_code& ec, 135*3d30708fSChicago Duan const std::string& dbusSNMPid) 136*3d30708fSChicago Duan { 137*3d30708fSChicago Duan if (ec) 138*3d30708fSChicago Duan { 139*3d30708fSChicago Duan if (ec.value() != EBADR) 140*3d30708fSChicago Duan { 141*3d30708fSChicago Duan // SNMP not installed 142*3d30708fSChicago Duan messages::propertyValueOutOfRange(asyncResp->res, "SNMPv2c", 143*3d30708fSChicago Duan "Protocol"); 144*3d30708fSChicago Duan return; 145*3d30708fSChicago Duan } 146*3d30708fSChicago Duan messages::internalError(asyncResp->res); 147*3d30708fSChicago Duan return; 148*3d30708fSChicago Duan } 149*3d30708fSChicago Duan 150*3d30708fSChicago Duan sdbusplus::message::object_path path(dbusSNMPid); 151*3d30708fSChicago Duan const std::string snmpId = path.filename(); 152*3d30708fSChicago Duan if (snmpId.empty()) 153*3d30708fSChicago Duan { 154*3d30708fSChicago Duan messages::internalError(asyncResp->res); 155*3d30708fSChicago Duan return; 156*3d30708fSChicago Duan } 157*3d30708fSChicago Duan 158*3d30708fSChicago Duan std::string subscriptionId = "snmp" + snmpId; 159*3d30708fSChicago Duan 160*3d30708fSChicago Duan boost::urls::url uri = boost::urls::format( 161*3d30708fSChicago Duan "/redfish/v1/EventService/Subscriptions/{}", subscriptionId); 162*3d30708fSChicago Duan asyncResp->res.addHeader("Location", uri.buffer()); 163*3d30708fSChicago Duan messages::created(asyncResp->res); 164*3d30708fSChicago Duan } 165*3d30708fSChicago Duan 166*3d30708fSChicago Duan inline void 167*3d30708fSChicago Duan addSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 168*3d30708fSChicago Duan const std::string& host, uint16_t snmpTrapPort) 169*3d30708fSChicago Duan { 170*3d30708fSChicago Duan crow::connections::systemBus->async_method_call( 171*3d30708fSChicago Duan [asyncResp](const boost::system::error_code& ec, 172*3d30708fSChicago Duan const std::string& dbusSNMPid) { 173*3d30708fSChicago Duan afterSnmpClientCreate(asyncResp, ec, dbusSNMPid); 174*3d30708fSChicago Duan }, 175*3d30708fSChicago Duan "xyz.openbmc_project.Network.SNMP", 176*3d30708fSChicago Duan "/xyz/openbmc_project/network/snmp/manager", 177*3d30708fSChicago Duan "xyz.openbmc_project.Network.Client.Create", "Client", host, 178*3d30708fSChicago Duan snmpTrapPort); 179*3d30708fSChicago Duan } 180*3d30708fSChicago Duan 181*3d30708fSChicago Duan inline void 182*3d30708fSChicago Duan getSnmpSubscriptionList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 183*3d30708fSChicago Duan const std::string& snmpId, 184*3d30708fSChicago Duan nlohmann::json& memberArray) 185*3d30708fSChicago Duan { 186*3d30708fSChicago Duan const std::string subscriptionId = "snmp" + snmpId; 187*3d30708fSChicago Duan 188*3d30708fSChicago Duan nlohmann::json::object_t member; 189*3d30708fSChicago Duan member["@odata.id"] = boost::urls::format( 190*3d30708fSChicago Duan "/redfish/v1/EventService/Subscriptions/{}", subscriptionId); 191*3d30708fSChicago Duan memberArray.push_back(std::move(member)); 192*3d30708fSChicago Duan 193*3d30708fSChicago Duan asyncResp->res.jsonValue["Members@odata.count"] = memberArray.size(); 194*3d30708fSChicago Duan } 195*3d30708fSChicago Duan 196*3d30708fSChicago Duan inline void 197*3d30708fSChicago Duan deleteSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 198*3d30708fSChicago Duan const std::string& param) 199*3d30708fSChicago Duan { 200*3d30708fSChicago Duan std::string_view snmpTrapId = param; 201*3d30708fSChicago Duan 202*3d30708fSChicago Duan // Erase "snmp" in the request to find the corresponding 203*3d30708fSChicago Duan // dbus snmp client id. For example, the snmpid in the 204*3d30708fSChicago Duan // request is "snmp1", which will be "1" after being erased. 205*3d30708fSChicago Duan snmpTrapId.remove_prefix(4); 206*3d30708fSChicago Duan 207*3d30708fSChicago Duan sdbusplus::message::object_path snmpPath = 208*3d30708fSChicago Duan sdbusplus::message::object_path( 209*3d30708fSChicago Duan "/xyz/openbmc_project/network/snmp/manager") / 210*3d30708fSChicago Duan std::string(snmpTrapId); 211*3d30708fSChicago Duan 212*3d30708fSChicago Duan crow::connections::systemBus->async_method_call( 213*3d30708fSChicago Duan [asyncResp, param](const boost::system::error_code& ec) { 214*3d30708fSChicago Duan if (ec) 215*3d30708fSChicago Duan { 216*3d30708fSChicago Duan // The snmp trap id is incorrect 217*3d30708fSChicago Duan if (ec.value() == EBADR) 218*3d30708fSChicago Duan { 219*3d30708fSChicago Duan messages::resourceNotFound(asyncResp->res, "Subscription", 220*3d30708fSChicago Duan param); 221*3d30708fSChicago Duan return; 222*3d30708fSChicago Duan } 223*3d30708fSChicago Duan messages::internalError(asyncResp->res); 224*3d30708fSChicago Duan return; 225*3d30708fSChicago Duan } 226*3d30708fSChicago Duan messages::success(asyncResp->res); 227*3d30708fSChicago Duan }, 228*3d30708fSChicago Duan "xyz.openbmc_project.Network.SNMP", static_cast<std::string>(snmpPath), 229*3d30708fSChicago Duan "xyz.openbmc_project.Object.Delete", "Delete"); 230*3d30708fSChicago Duan } 231*3d30708fSChicago Duan 232*3d30708fSChicago Duan } // namespace redfish 233