blob: f0374f3f7613454e011d12a78a95e18fb4c6151b [file] [log] [blame]
Vernon Mauery9e801a22018-10-12 13:20:49 -07001#include "provider_registration.hpp"
2
3#include "command_table.hpp"
4#include "main.hpp"
5
Tom485038e2016-12-02 13:44:45 +05306#include <dirent.h>
7#include <dlfcn.h>
Vernon Mauery9e801a22018-10-12 13:20:49 -07008#include <host-ipmid/ipmid-api.h>
Tom485038e2016-12-02 13:44:45 +05309#include <stdlib.h>
10#include <string.h>
11
12#include <iostream>
13
Tom485038e2016-12-02 13:44:45 +053014namespace provider
15{
16
17int handler_select(const struct dirent* entry)
18{
19 // Check for versioned libraries .so.*
20 if (strstr(entry->d_name, PROVIDER_SONAME_EXTN))
21 {
22 return 1;
23 }
24 else
25 {
26 return 0;
27 }
28}
29
30void registerCallbackHandlers(const char* providerLibPath)
31{
32 if (providerLibPath == NULL)
33 {
34 std::cerr << "Path not provided for registering IPMI provider libraries"
35 << "\n";
36 return;
37 }
38
39 struct dirent** handlerList = nullptr;
40 std::string handlerPath(providerLibPath);
41
Vernon Mauery9e801a22018-10-12 13:20:49 -070042 auto numLibs =
43 scandir(providerLibPath, &handlerList, handler_select, alphasort);
Tom485038e2016-12-02 13:44:45 +053044 if (numLibs < 0)
45 {
46 return;
47 }
48
49 // dlopen each IPMI provider shared library
50 while (numLibs--)
51 {
52 handlerPath = providerLibPath;
53 handlerPath += handlerList[numLibs]->d_name;
Tom485038e2016-12-02 13:44:45 +053054
55 auto lib_handler = dlopen(handlerPath.c_str(), RTLD_NOW);
56
57 if (lib_handler == NULL)
58 {
59 std::cerr << "Error opening " << handlerPath << dlerror() << "\n";
60 }
61 free(handlerList[numLibs]);
62 }
63
64 free(handlerList);
65}
66
67} // namespace provider
68
69/*
70 * @brief Method that gets called from IPMI provider shared libraries to get
71 * the command handlers registered.
72 *
73 * When the IPMI provider shared library is loaded, the dynamic loader program
74 * looks for special section(.ctors on ELF) which contains references to the
75 * functions marked with the constructor attributes. This function is invoked
76 * in such manner.
77 *
78 * @param[in] netfn - Network Function code
79 * @param[in] cmd - Command
80 * @param[in] context - User specific data
81 * @param[in] handler - The callback routine for the command
Tom Joseph935606c2017-01-27 10:53:33 +053082 * @param[in] priv - IPMI Command Privilege
Tom485038e2016-12-02 13:44:45 +053083 */
84void ipmi_register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Vernon Mauery9e801a22018-10-12 13:20:49 -070085 ipmi_context_t context, ipmid_callback_t handler,
86 ipmi_cmd_privilege_t priv)
Tom485038e2016-12-02 13:44:45 +053087{
88 uint16_t netFn = netfn << 10;
89
90 // The payload type of IPMI commands provided by the shared libraries
91 // is IPMI
Vernon Mauery9e801a22018-10-12 13:20:49 -070092 command::CommandID command = {
93 ((static_cast<uint32_t>(message::PayloadType::IPMI)) << 16) | netFn |
94 cmd};
Tom485038e2016-12-02 13:44:45 +053095
Vernon Mauery9e801a22018-10-12 13:20:49 -070096 std::get<command::Table&>(singletonPool)
97 .registerCommand(command, std::make_unique<command::ProviderIpmidEntry>(
98 command, handler,
99 static_cast<session::Privilege>(priv)));
Tom485038e2016-12-02 13:44:45 +0530100}