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