1d700e76aSTom #include <mapper.h>
21fabf229SEmily Shaffer #include <math.h>
398a23840SMatthew Barth #include <stdio.h>
498a23840SMatthew Barth #include <string.h>
5be703f71STom Joseph #include <bitset>
6bbef71c2SEmily Shaffer #include <xyz/openbmc_project/Sensor/Value/server.hpp>
798a23840SMatthew Barth #include <systemd/sd-bus.h>
8be703f71STom Joseph #include "host-ipmid/ipmid-api.h"
9be703f71STom Joseph #include <phosphor-logging/log.hpp>
10d700e76aSTom #include "ipmid.hpp"
11be703f71STom Joseph #include "sensorhandler.h"
12be703f71STom Joseph #include "types.hpp"
13be703f71STom Joseph #include "utils.hpp"
1498a23840SMatthew Barth 
1598a23840SMatthew Barth extern int updateSensorRecordFromSSRAESC(const void *);
16d700e76aSTom extern sd_bus *bus;
17be703f71STom Joseph extern const ipmi::sensor::IdInfoMap sensors;
18be703f71STom Joseph using namespace phosphor::logging;
1998a23840SMatthew Barth 
2098a23840SMatthew Barth void register_netfn_sen_functions()   __attribute__((constructor));
2198a23840SMatthew Barth 
2298a23840SMatthew Barth struct sensorTypemap_t {
2398a23840SMatthew Barth     uint8_t number;
2498a23840SMatthew Barth     uint8_t typecode;
2598a23840SMatthew Barth     char dbusname[32];
2698a23840SMatthew Barth } ;
2798a23840SMatthew Barth 
2898a23840SMatthew Barth sensorTypemap_t g_SensorTypeMap[] = {
2998a23840SMatthew Barth 
3098a23840SMatthew Barth     {0x01, 0x6F, "Temp"},
3198a23840SMatthew Barth     {0x0C, 0x6F, "DIMM"},
3298a23840SMatthew Barth     {0x0C, 0x6F, "MEMORY_BUFFER"},
3398a23840SMatthew Barth     {0x07, 0x6F, "PROC"},
3498a23840SMatthew Barth     {0x07, 0x6F, "CORE"},
3598a23840SMatthew Barth     {0x07, 0x6F, "CPU"},
3698a23840SMatthew Barth     {0x0F, 0x6F, "BootProgress"},
3798a23840SMatthew Barth     {0xe9, 0x09, "OccStatus"},  // E9 is an internal mapping to handle sensor type code os 0x09
3898a23840SMatthew Barth     {0xC3, 0x6F, "BootCount"},
3998a23840SMatthew Barth     {0x1F, 0x6F, "OperatingSystemStatus"},
4098a23840SMatthew Barth     {0x12, 0x6F, "SYSTEM_EVENT"},
4198a23840SMatthew Barth     {0xC7, 0x03, "SYSTEM"},
4298a23840SMatthew Barth     {0xC7, 0x03, "MAIN_PLANAR"},
4398a23840SMatthew Barth     {0xC2, 0x6F, "PowerCap"},
4407248298SDhruvaraj S     {0xD8, 0x03, "PowerSupplyRedundancy"},
450661beb1SJayanth Othayoth     {0xDA, 0x03, "TurboAllowed"},
46d5b2ac0eSJayanth Othayoth     {0xB4, 0x6F, "PowerSupplyDerating"},
4798a23840SMatthew Barth     {0xFF, 0x00, ""},
4898a23840SMatthew Barth };
4998a23840SMatthew Barth 
5098a23840SMatthew Barth 
5198a23840SMatthew Barth struct sensor_data_t {
5298a23840SMatthew Barth     uint8_t sennum;
5398a23840SMatthew Barth }  __attribute__ ((packed)) ;
5498a23840SMatthew Barth 
5598a23840SMatthew Barth struct sensorreadingresp_t {
5698a23840SMatthew Barth     uint8_t value;
5798a23840SMatthew Barth     uint8_t operation;
5898a23840SMatthew Barth     uint8_t indication[2];
5998a23840SMatthew Barth }  __attribute__ ((packed)) ;
6098a23840SMatthew Barth 
61d700e76aSTom // Use a lookup table to find the interface name of a specific sensor
62d700e76aSTom // This will be used until an alternative is found.  this is the first
63d700e76aSTom // step for mapping IPMI
64d700e76aSTom int find_interface_property_fru_type(dbus_interface_t *interface, const char *property_name, char *property_value) {
65d700e76aSTom 
66d700e76aSTom     char  *str1;
67d700e76aSTom     sd_bus_error error = SD_BUS_ERROR_NULL;
68d700e76aSTom     sd_bus_message *reply = NULL, *m=NULL;
69d700e76aSTom 
70d700e76aSTom 
71d700e76aSTom     int r;
72d700e76aSTom 
73d700e76aSTom     r = sd_bus_message_new_method_call(bus,&m,interface->bus,interface->path,"org.freedesktop.DBus.Properties","Get");
74d700e76aSTom     if (r < 0) {
75d700e76aSTom         fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
76d700e76aSTom         fprintf(stderr,"Bus: %s Path: %s Interface: %s \n",
77d700e76aSTom                 interface->bus, interface->path, interface->interface);
78d700e76aSTom         goto final;
79d700e76aSTom     }
80d700e76aSTom 
81d700e76aSTom     r = sd_bus_message_append(m, "ss", "org.openbmc.InventoryItem", property_name);
82d700e76aSTom     if (r < 0) {
83d700e76aSTom         fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
84d700e76aSTom         fprintf(stderr,"Bus: %s Path: %s Interface: %s \n",
85d700e76aSTom                 interface->bus, interface->path, interface->interface);
86d700e76aSTom         goto final;
87d700e76aSTom     }
88d700e76aSTom 
89d700e76aSTom     r = sd_bus_call(bus, m, 0, &error, &reply);
90d700e76aSTom     if (r < 0) {
91d700e76aSTom         fprintf(stderr, "Failed to call the method: %s", strerror(-r));
92d700e76aSTom         goto final;
93d700e76aSTom     }
94d700e76aSTom 
95d700e76aSTom     r = sd_bus_message_read(reply, "v",  "s", &str1) ;
96d700e76aSTom     if (r < 0) {
97d700e76aSTom         fprintf(stderr, "Failed to get a response: %s", strerror(-r));
98d700e76aSTom         goto final;
99d700e76aSTom     }
100d700e76aSTom 
101d700e76aSTom     strcpy(property_value, str1);
102d700e76aSTom 
103d700e76aSTom final:
104d700e76aSTom 
105d700e76aSTom     sd_bus_error_free(&error);
106d700e76aSTom     m = sd_bus_message_unref(m);
107d700e76aSTom     reply = sd_bus_message_unref(reply);
108d700e76aSTom 
109d700e76aSTom     return r;
110d700e76aSTom }
111d700e76aSTom 
1122ae09b9aSEmily Shaffer int get_bus_for_path(const char *path, char **busname) {
1132ae09b9aSEmily Shaffer     return mapper_get_service(bus, path, busname);
1142ae09b9aSEmily Shaffer }
115d700e76aSTom 
1162ae09b9aSEmily Shaffer int legacy_dbus_openbmc_path(const char *type, const uint8_t num, dbus_interface_t *interface) {
117d700e76aSTom     char  *busname = NULL;
118d700e76aSTom     const char  *iface = "org.openbmc.managers.System";
119d700e76aSTom     const char  *objname = "/org/openbmc/managers/System";
120d700e76aSTom     char  *str1 = NULL, *str2, *str3;
121d700e76aSTom     sd_bus_error error = SD_BUS_ERROR_NULL;
122d700e76aSTom     sd_bus_message *reply = NULL;
123d700e76aSTom 
124d700e76aSTom 
125d700e76aSTom     int r;
1262ae09b9aSEmily Shaffer     r = get_bus_for_path(objname, &busname);
127d700e76aSTom     if (r < 0) {
128819ddd42SBrad Bishop         fprintf(stderr, "Failed to get %s busname: %s\n",
129819ddd42SBrad Bishop                 objname, strerror(-r));
130d700e76aSTom         goto final;
131d700e76aSTom     }
132d700e76aSTom 
133d700e76aSTom     r = sd_bus_call_method(bus,busname,objname,iface, "getObjectFromByteId",
134d700e76aSTom                            &error, &reply, "sy", type, num);
135d700e76aSTom     if (r < 0) {
136d700e76aSTom         fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
137d700e76aSTom         goto final;
138d700e76aSTom     }
139d700e76aSTom 
140d700e76aSTom     r = sd_bus_message_read(reply, "(ss)", &str2, &str3);
141d700e76aSTom     if (r < 0) {
142d700e76aSTom         fprintf(stderr, "Failed to get a response: %s", strerror(-r));
143d700e76aSTom         goto final;
144d700e76aSTom     }
145d700e76aSTom 
1462ae09b9aSEmily Shaffer     r = get_bus_for_path(str2, &str1);
147d700e76aSTom     if (r < 0) {
148819ddd42SBrad Bishop         fprintf(stderr, "Failed to get %s busname: %s\n",
149819ddd42SBrad Bishop                 str2, strerror(-r));
150d700e76aSTom         goto final;
151d700e76aSTom     }
152d700e76aSTom 
153d700e76aSTom     strncpy(interface->bus, str1, MAX_DBUS_PATH);
154d700e76aSTom     strncpy(interface->path, str2, MAX_DBUS_PATH);
155d700e76aSTom     strncpy(interface->interface, str3, MAX_DBUS_PATH);
156d700e76aSTom 
157d700e76aSTom     interface->sensornumber = num;
1587117441cSEmily Shaffer     // Make sure we know that the type hasn't been set, as newer codebase will
1597117441cSEmily Shaffer     // set it automatically from the YAML at this step.
1607117441cSEmily Shaffer     interface->sensortype = 0;
161d700e76aSTom 
162d700e76aSTom final:
163d700e76aSTom 
164d700e76aSTom     sd_bus_error_free(&error);
165d700e76aSTom     reply = sd_bus_message_unref(reply);
166d700e76aSTom     free(busname);
167d700e76aSTom     free(str1);
168d700e76aSTom 
169d700e76aSTom     return r;
170d700e76aSTom }
171d700e76aSTom 
1722ae09b9aSEmily Shaffer // Use a lookup table to find the interface name of a specific sensor
1732ae09b9aSEmily Shaffer // This will be used until an alternative is found.  this is the first
1742ae09b9aSEmily Shaffer // step for mapping IPMI
1752ae09b9aSEmily Shaffer int find_openbmc_path(uint8_t num, dbus_interface_t *interface) {
1762ae09b9aSEmily Shaffer     int rc;
1772ae09b9aSEmily Shaffer 
1782ae09b9aSEmily Shaffer     // When the sensor map does not contain the sensor requested,
1792ae09b9aSEmily Shaffer     // fall back to the legacy DBus lookup (deprecated)
1802ae09b9aSEmily Shaffer     const auto& sensor_it = sensors.find(num);
1812ae09b9aSEmily Shaffer     if (sensor_it == sensors.end())
1822ae09b9aSEmily Shaffer     {
1832ae09b9aSEmily Shaffer         return legacy_dbus_openbmc_path("SENSOR", num, interface);
1842ae09b9aSEmily Shaffer     }
1852ae09b9aSEmily Shaffer 
1862ae09b9aSEmily Shaffer     const auto& info = sensor_it->second;
1872ae09b9aSEmily Shaffer 
1888451edf5SPatrick Williams     char* busname = nullptr;
1892ae09b9aSEmily Shaffer     rc = get_bus_for_path(info.sensorPath.c_str(), &busname);
1902ae09b9aSEmily Shaffer     if (rc < 0) {
1912ae09b9aSEmily Shaffer         fprintf(stderr, "Failed to get %s busname: %s\n",
1922ae09b9aSEmily Shaffer                 info.sensorPath.c_str(),
1932ae09b9aSEmily Shaffer                 busname);
1942ae09b9aSEmily Shaffer         goto final;
1952ae09b9aSEmily Shaffer     }
1962ae09b9aSEmily Shaffer 
1972ae09b9aSEmily Shaffer     interface->sensortype = info.sensorType;
1982ae09b9aSEmily Shaffer     strcpy(interface->bus, busname);
1992ae09b9aSEmily Shaffer     strcpy(interface->path, info.sensorPath.c_str());
2002ae09b9aSEmily Shaffer     // Take the interface name from the beginning of the DbusInterfaceMap. This
2012ae09b9aSEmily Shaffer     // works for the Value interface but may not suffice for more complex
2022ae09b9aSEmily Shaffer     // sensors.
2032ae09b9aSEmily Shaffer     // tracked https://github.com/openbmc/phosphor-host-ipmid/issues/103
2042ae09b9aSEmily Shaffer     strcpy(interface->interface, info.sensorInterfaces.begin()->first.c_str());
2052ae09b9aSEmily Shaffer     interface->sensornumber = num;
2062ae09b9aSEmily Shaffer 
2072ae09b9aSEmily Shaffer final:
2082ae09b9aSEmily Shaffer     free(busname);
2092ae09b9aSEmily Shaffer     return rc;
2102ae09b9aSEmily Shaffer }
2112ae09b9aSEmily Shaffer 
212d700e76aSTom 
213d700e76aSTom /////////////////////////////////////////////////////////////////////
214d700e76aSTom //
215d700e76aSTom // Routines used by ipmi commands wanting to interact on the dbus
216d700e76aSTom //
217d700e76aSTom /////////////////////////////////////////////////////////////////////
218d700e76aSTom int set_sensor_dbus_state_s(uint8_t number, const char *method, const char *value) {
219d700e76aSTom 
220d700e76aSTom 
221d700e76aSTom     dbus_interface_t a;
222d700e76aSTom     int r;
223d700e76aSTom     sd_bus_error error = SD_BUS_ERROR_NULL;
224d700e76aSTom     sd_bus_message *m=NULL;
225d700e76aSTom 
226d700e76aSTom     fprintf(ipmidbus, "Attempting to set a dbus Variant Sensor 0x%02x via %s with a value of %s\n",
227d700e76aSTom         number, method, value);
228d700e76aSTom 
2292ae09b9aSEmily Shaffer     r = find_openbmc_path(number, &a);
230d700e76aSTom 
231d700e76aSTom     if (r < 0) {
232d700e76aSTom         fprintf(stderr, "Failed to find Sensor 0x%02x\n", number);
233d700e76aSTom         return 0;
234d700e76aSTom     }
235d700e76aSTom 
236d700e76aSTom     r = sd_bus_message_new_method_call(bus,&m,a.bus,a.path,a.interface,method);
237d700e76aSTom     if (r < 0) {
238d700e76aSTom         fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
239d700e76aSTom         goto final;
240d700e76aSTom     }
241d700e76aSTom 
242d700e76aSTom     r = sd_bus_message_append(m, "v", "s", value);
243d700e76aSTom     if (r < 0) {
244d700e76aSTom         fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
245d700e76aSTom         goto final;
246d700e76aSTom     }
247d700e76aSTom 
248d700e76aSTom 
249d700e76aSTom     r = sd_bus_call(bus, m, 0, &error, NULL);
250d700e76aSTom     if (r < 0) {
251d700e76aSTom         fprintf(stderr, "Failed to call the method: %s", strerror(-r));
252d700e76aSTom     }
253d700e76aSTom 
254d700e76aSTom final:
255d700e76aSTom     sd_bus_error_free(&error);
256d700e76aSTom     m = sd_bus_message_unref(m);
257d700e76aSTom 
258d700e76aSTom     return 0;
259d700e76aSTom }
260d700e76aSTom int set_sensor_dbus_state_y(uint8_t number, const char *method, const uint8_t value) {
261d700e76aSTom 
262d700e76aSTom 
263d700e76aSTom     dbus_interface_t a;
264d700e76aSTom     int r;
265d700e76aSTom     sd_bus_error error = SD_BUS_ERROR_NULL;
266d700e76aSTom     sd_bus_message *m=NULL;
267d700e76aSTom 
268d700e76aSTom     fprintf(ipmidbus, "Attempting to set a dbus Variant Sensor 0x%02x via %s with a value of 0x%02x\n",
269d700e76aSTom         number, method, value);
270d700e76aSTom 
2712ae09b9aSEmily Shaffer     r = find_openbmc_path(number, &a);
272d700e76aSTom 
273d700e76aSTom     if (r < 0) {
274d700e76aSTom         fprintf(stderr, "Failed to find Sensor 0x%02x\n", number);
275d700e76aSTom         return 0;
276d700e76aSTom     }
277d700e76aSTom 
278d700e76aSTom     r = sd_bus_message_new_method_call(bus,&m,a.bus,a.path,a.interface,method);
279d700e76aSTom     if (r < 0) {
280d700e76aSTom         fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
281d700e76aSTom         goto final;
282d700e76aSTom     }
283d700e76aSTom 
284d700e76aSTom     r = sd_bus_message_append(m, "v", "i", value);
285d700e76aSTom     if (r < 0) {
286d700e76aSTom         fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
287d700e76aSTom         goto final;
288d700e76aSTom     }
289d700e76aSTom 
290d700e76aSTom 
291d700e76aSTom     r = sd_bus_call(bus, m, 0, &error, NULL);
292d700e76aSTom     if (r < 0) {
293d700e76aSTom         fprintf(stderr, "12 Failed to call the method: %s", strerror(-r));
294d700e76aSTom     }
295d700e76aSTom 
296d700e76aSTom final:
297d700e76aSTom     sd_bus_error_free(&error);
298d700e76aSTom     m = sd_bus_message_unref(m);
299d700e76aSTom 
300d700e76aSTom     return 0;
301d700e76aSTom }
302d700e76aSTom 
30398a23840SMatthew Barth uint8_t dbus_to_sensor_type(char *p) {
30498a23840SMatthew Barth 
30598a23840SMatthew Barth     sensorTypemap_t *s = g_SensorTypeMap;
30698a23840SMatthew Barth     char r=0;
30798a23840SMatthew Barth 
30898a23840SMatthew Barth     while (s->number != 0xFF) {
30998a23840SMatthew Barth         if (!strcmp(s->dbusname,p)) {
31098a23840SMatthew Barth             r = s->number;
31198a23840SMatthew Barth              break;
31298a23840SMatthew Barth         }
31398a23840SMatthew Barth         s++;
31498a23840SMatthew Barth     }
31598a23840SMatthew Barth 
31698a23840SMatthew Barth 
31798a23840SMatthew Barth     if (s->number == 0xFF)
31898a23840SMatthew Barth         printf("Failed to find Sensor Type %s\n", p);
31998a23840SMatthew Barth 
32098a23840SMatthew Barth     return r;
32198a23840SMatthew Barth }
32298a23840SMatthew Barth 
32398a23840SMatthew Barth 
32498a23840SMatthew Barth uint8_t dbus_to_sensor_type_from_dbus(dbus_interface_t *a) {
32598a23840SMatthew Barth     char fru_type_name[64];
32698a23840SMatthew Barth     int r= 0;
32798a23840SMatthew Barth 
32898a23840SMatthew Barth     r = find_interface_property_fru_type(a, "fru_type", fru_type_name);
32998a23840SMatthew Barth     if (r<0) {
33098a23840SMatthew Barth         fprintf(stderr, "Failed to get a fru type: %s", strerror(-r));
33198a23840SMatthew Barth         return -1;
33298a23840SMatthew Barth     } else {
33398a23840SMatthew Barth         return dbus_to_sensor_type(fru_type_name);
33498a23840SMatthew Barth     }
33598a23840SMatthew Barth }
33698a23840SMatthew Barth 
337391f3303SEmily Shaffer uint8_t get_type_from_interface(dbus_interface_t dbus_if) {
33898a23840SMatthew Barth 
33998a23840SMatthew Barth     char *p;
34056003453SBrad Bishop     uint8_t type;
34198a23840SMatthew Barth 
34298a23840SMatthew Barth     // This is where sensors that do not exist in dbus but do
34398a23840SMatthew Barth     // exist in the host code stop.  This should indicate it
34498a23840SMatthew Barth     // is not a supported sensor
345391f3303SEmily Shaffer     if (dbus_if.interface[0] == 0) { return 0;}
34698a23840SMatthew Barth 
3477117441cSEmily Shaffer     // Fetch type from interface itself.
3487117441cSEmily Shaffer     if (dbus_if.sensortype != 0)
3497117441cSEmily Shaffer     {
3507117441cSEmily Shaffer         type = dbus_if.sensortype;
3517117441cSEmily Shaffer     }
3527117441cSEmily Shaffer     // Legacy codebase does not populate type during initial handling:
3537117441cSEmily Shaffer     else if (strstr(dbus_if.interface, "InventoryItem")) {
35498a23840SMatthew Barth         // InventoryItems are real frus.  So need to get the
35598a23840SMatthew Barth         // fru_type property
356391f3303SEmily Shaffer         type = dbus_to_sensor_type_from_dbus(&dbus_if);
35798a23840SMatthew Barth     } else {
35898a23840SMatthew Barth         // Non InventoryItems
359391f3303SEmily Shaffer         p = strrchr (dbus_if.path, '/');
36056003453SBrad Bishop         type = dbus_to_sensor_type(p+1);
36198a23840SMatthew Barth     }
36298a23840SMatthew Barth 
36356003453SBrad Bishop     return type;
36498a23840SMatthew Barth  }
36598a23840SMatthew Barth 
366391f3303SEmily Shaffer // Replaces find_sensor
367391f3303SEmily Shaffer uint8_t find_type_for_sensor_number(uint8_t num) {
368391f3303SEmily Shaffer     int r;
369391f3303SEmily Shaffer     dbus_interface_t dbus_if;
3702ae09b9aSEmily Shaffer     r = find_openbmc_path(num, &dbus_if);
371391f3303SEmily Shaffer     if (r < 0) {
372391f3303SEmily Shaffer         fprintf(stderr, "Could not find sensor %d\n", num);
373391f3303SEmily Shaffer         return r;
374391f3303SEmily Shaffer     }
375391f3303SEmily Shaffer     return get_type_from_interface(dbus_if);
376391f3303SEmily Shaffer }
377391f3303SEmily Shaffer 
37898a23840SMatthew Barth 
37998a23840SMatthew Barth 
38098a23840SMatthew Barth 
38198a23840SMatthew Barth 
38298a23840SMatthew Barth ipmi_ret_t ipmi_sen_get_sensor_type(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
38398a23840SMatthew Barth                              ipmi_request_t request, ipmi_response_t response,
38498a23840SMatthew Barth                              ipmi_data_len_t data_len, ipmi_context_t context)
38598a23840SMatthew Barth {
38698a23840SMatthew Barth     sensor_data_t *reqptr = (sensor_data_t*)request;
38798a23840SMatthew Barth     ipmi_ret_t rc = IPMI_CC_OK;
38898a23840SMatthew Barth 
38998a23840SMatthew Barth     printf("IPMI GET_SENSOR_TYPE [0x%02X]\n",reqptr->sennum);
39098a23840SMatthew Barth 
39198a23840SMatthew Barth     // TODO Not sure what the System-event-sensor is suppose to return
39298a23840SMatthew Barth     // need to ask Hostboot team
39398a23840SMatthew Barth     unsigned char buf[] = {0x00,0x6F};
39498a23840SMatthew Barth 
395391f3303SEmily Shaffer     buf[0] = find_type_for_sensor_number(reqptr->sennum);
39698a23840SMatthew Barth 
39798a23840SMatthew Barth     // HACK UNTIL Dbus gets updated or we find a better way
39898a23840SMatthew Barth     if (buf[0] == 0) {
39998a23840SMatthew Barth         rc = IPMI_CC_SENSOR_INVALID;
40098a23840SMatthew Barth     }
40198a23840SMatthew Barth 
40298a23840SMatthew Barth 
40398a23840SMatthew Barth     *data_len = sizeof(buf);
40498a23840SMatthew Barth     memcpy(response, &buf, *data_len);
40598a23840SMatthew Barth 
40698a23840SMatthew Barth     return rc;
40798a23840SMatthew Barth }
40898a23840SMatthew Barth 
409be703f71STom Joseph ipmi_ret_t setSensorReading(void *request)
410be703f71STom Joseph {
411*e0af7209SDhruvaraj Subhashchandran     SetSensorReadingReq cmdData =
412*e0af7209SDhruvaraj Subhashchandran             *(static_cast<SetSensorReadingReq *>(request));
413be703f71STom Joseph 
414be703f71STom Joseph     // Check if the Sensor Number is present
415*e0af7209SDhruvaraj Subhashchandran     const auto iter = sensors.find(cmdData.number);
416be703f71STom Joseph     if (iter == sensors.end())
417be703f71STom Joseph     {
418be703f71STom Joseph         return IPMI_CC_SENSOR_INVALID;
419be703f71STom Joseph     }
420be703f71STom Joseph 
421*e0af7209SDhruvaraj Subhashchandran     return iter->second.updateFunc(cmdData, iter->second);
422be703f71STom Joseph }
42398a23840SMatthew Barth 
42498a23840SMatthew Barth ipmi_ret_t ipmi_sen_set_sensor(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
42598a23840SMatthew Barth                              ipmi_request_t request, ipmi_response_t response,
42698a23840SMatthew Barth                              ipmi_data_len_t data_len, ipmi_context_t context)
42798a23840SMatthew Barth {
42898a23840SMatthew Barth     sensor_data_t *reqptr = (sensor_data_t*)request;
42998a23840SMatthew Barth 
43098a23840SMatthew Barth     printf("IPMI SET_SENSOR [0x%02x]\n",reqptr->sennum);
43198a23840SMatthew Barth 
432be703f71STom Joseph     /*
433be703f71STom Joseph      * This would support the Set Sensor Reading command for the presence
434be703f71STom Joseph      * and functional state of Processor, Core & DIMM. For the remaining
435be703f71STom Joseph      * sensors the existing support is invoked.
436be703f71STom Joseph      */
437be703f71STom Joseph     auto ipmiRC = setSensorReading(request);
438be703f71STom Joseph 
439be703f71STom Joseph     if(ipmiRC == IPMI_CC_SENSOR_INVALID)
440be703f71STom Joseph     {
44198a23840SMatthew Barth         updateSensorRecordFromSSRAESC(reqptr);
442be703f71STom Joseph         ipmiRC = IPMI_CC_OK;
443be703f71STom Joseph     }
44498a23840SMatthew Barth 
44598a23840SMatthew Barth     *data_len=0;
446be703f71STom Joseph     return ipmiRC;
44798a23840SMatthew Barth }
44898a23840SMatthew Barth 
44998a23840SMatthew Barth 
45098a23840SMatthew Barth ipmi_ret_t ipmi_sen_get_sensor_reading(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
45198a23840SMatthew Barth                              ipmi_request_t request, ipmi_response_t response,
45298a23840SMatthew Barth                              ipmi_data_len_t data_len, ipmi_context_t context)
45398a23840SMatthew Barth {
45498a23840SMatthew Barth     sensor_data_t *reqptr = (sensor_data_t*)request;
45598a23840SMatthew Barth     ipmi_ret_t rc = IPMI_CC_SENSOR_INVALID;
45698a23840SMatthew Barth     uint8_t type;
45798a23840SMatthew Barth     sensorreadingresp_t *resp = (sensorreadingresp_t*) response;
45898a23840SMatthew Barth     int r;
45998a23840SMatthew Barth     dbus_interface_t a;
46098a23840SMatthew Barth     sd_bus *bus = ipmid_get_sd_bus_connection();
46198a23840SMatthew Barth     sd_bus_message *reply = NULL;
46298a23840SMatthew Barth     int reading = 0;
46398a23840SMatthew Barth 
46498a23840SMatthew Barth 
46598a23840SMatthew Barth     printf("IPMI GET_SENSOR_READING [0x%02x]\n",reqptr->sennum);
46698a23840SMatthew Barth 
4672ae09b9aSEmily Shaffer     r = find_openbmc_path(reqptr->sennum, &a);
46898a23840SMatthew Barth 
46998a23840SMatthew Barth     if (r < 0) {
47098a23840SMatthew Barth         fprintf(stderr, "Failed to find Sensor 0x%02x\n", reqptr->sennum);
47198a23840SMatthew Barth         return IPMI_CC_SENSOR_INVALID;
47298a23840SMatthew Barth     }
47398a23840SMatthew Barth 
474391f3303SEmily Shaffer     type = get_type_from_interface(a);
47556003453SBrad Bishop     if(type == 0) {
47656003453SBrad Bishop         fprintf(stderr, "Failed to find Sensor 0x%02x\n", reqptr->sennum);
47756003453SBrad Bishop         return IPMI_CC_SENSOR_INVALID;
47856003453SBrad Bishop     }
47998a23840SMatthew Barth 
48098a23840SMatthew Barth     fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n", a.bus, a.path, a.interface);
48198a23840SMatthew Barth 
48298a23840SMatthew Barth     *data_len=0;
48398a23840SMatthew Barth 
48410f4959aSEmily Shaffer     int64_t raw_value;
4851fabf229SEmily Shaffer     ipmi::sensor::Info sensor;
4861fabf229SEmily Shaffer 
48798a23840SMatthew Barth     switch(type) {
48898a23840SMatthew Barth         case 0xC3:
48998a23840SMatthew Barth         case 0xC2:
49098a23840SMatthew Barth             r = sd_bus_get_property(bus,a.bus, a.path, a.interface, "value", NULL, &reply, "i");
49198a23840SMatthew Barth             if (r < 0) {
49298a23840SMatthew Barth                 fprintf(stderr, "Failed to call sd_bus_get_property:%d,  %s\n", r, strerror(-r));
49398a23840SMatthew Barth                 fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n",
49498a23840SMatthew Barth                         a.bus, a.path, a.interface);
49598a23840SMatthew Barth                 break;
49698a23840SMatthew Barth             }
49798a23840SMatthew Barth 
49898a23840SMatthew Barth             r = sd_bus_message_read(reply, "i", &reading);
49998a23840SMatthew Barth             if (r < 0) {
50098a23840SMatthew Barth                 fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r));
50198a23840SMatthew Barth                 break;
50298a23840SMatthew Barth             }
50398a23840SMatthew Barth 
50498a23840SMatthew Barth             printf("Contents of a 0x%02x is 0x%02x\n", type, reading);
50598a23840SMatthew Barth 
50698a23840SMatthew Barth             rc = IPMI_CC_OK;
50798a23840SMatthew Barth             *data_len=sizeof(sensorreadingresp_t);
50898a23840SMatthew Barth 
50998a23840SMatthew Barth             resp->value         = (uint8_t)reading;
51098a23840SMatthew Barth             resp->operation     = 0;
51198a23840SMatthew Barth             resp->indication[0] = 0;
51298a23840SMatthew Barth             resp->indication[1] = 0;
51398a23840SMatthew Barth             break;
51498a23840SMatthew Barth 
5151fabf229SEmily Shaffer         case IPMI_SENSOR_TEMP:
5161fabf229SEmily Shaffer         case IPMI_SENSOR_VOLTAGE:
5171fabf229SEmily Shaffer         case IPMI_SENSOR_CURRENT:
5181fabf229SEmily Shaffer         case IPMI_SENSOR_FAN:
5191fabf229SEmily Shaffer             // Get reading for /xyz/openbmc_project/Sensor/Value.interface
52010f4959aSEmily Shaffer             if(sensors.find(reqptr->sennum) == sensors.end())
52110f4959aSEmily Shaffer             {
52210f4959aSEmily Shaffer                 fprintf(stderr, "Failed to find config entry for Sensor 0x%02x\n",
52310f4959aSEmily Shaffer                         reqptr->sennum);
52410f4959aSEmily Shaffer                 return IPMI_CC_SENSOR_INVALID;
52510f4959aSEmily Shaffer             }
52610f4959aSEmily Shaffer 
52710f4959aSEmily Shaffer             sensor = sensors.at(reqptr->sennum);
5281fabf229SEmily Shaffer 
5291fabf229SEmily Shaffer             // Get value
5301fabf229SEmily Shaffer             r = sd_bus_get_property_trivial(bus,
5311fabf229SEmily Shaffer                                             a.bus,
5321fabf229SEmily Shaffer                                             a.path,
5331fabf229SEmily Shaffer                                             a.interface,
5341fabf229SEmily Shaffer                                             "Value",
5351fabf229SEmily Shaffer                                             NULL,
5361fabf229SEmily Shaffer                                             'x',
5371fabf229SEmily Shaffer                                             &raw_value);
5381fabf229SEmily Shaffer             if (r < 0) {
5391fabf229SEmily Shaffer                 fprintf(stderr,
5401fabf229SEmily Shaffer                         "Failed to call sd_bus_get_property:%d,  %s, 'value'\n",
5411fabf229SEmily Shaffer                         r,
5421fabf229SEmily Shaffer                         strerror(-r));
5431fabf229SEmily Shaffer                 fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n",
5441fabf229SEmily Shaffer                         a.bus, a.path, a.interface);
5451fabf229SEmily Shaffer                 break;
5461fabf229SEmily Shaffer             }
5471fabf229SEmily Shaffer 
54810f4959aSEmily Shaffer             // Prevent div0
54910f4959aSEmily Shaffer             if (sensor.coefficientM == 0) {
55010f4959aSEmily Shaffer                 sensor.coefficientM = 1;
55110f4959aSEmily Shaffer             };
5521fabf229SEmily Shaffer 
55310f4959aSEmily Shaffer             resp->value = static_cast<uint8_t>(
55410f4959aSEmily Shaffer                     (raw_value - sensor.scaledOffset) / sensor.coefficientM);
555bbef71c2SEmily Shaffer             resp->operation = 1<<6; // scanning enabled
556bbef71c2SEmily Shaffer             resp->indication[0] = 0; // not a threshold sensor. ignore
5571fabf229SEmily Shaffer             resp->indication[1] = 0;
5581fabf229SEmily Shaffer             rc = IPMI_CC_OK;
5591fabf229SEmily Shaffer             *data_len=sizeof(sensorreadingresp_t);
5601fabf229SEmily Shaffer             break;
5611fabf229SEmily Shaffer 
56298a23840SMatthew Barth         default:
56398a23840SMatthew Barth             *data_len=0;
56498a23840SMatthew Barth             rc = IPMI_CC_SENSOR_INVALID;
56598a23840SMatthew Barth             break;
56698a23840SMatthew Barth     }
56798a23840SMatthew Barth 
56898a23840SMatthew Barth 
56998a23840SMatthew Barth     reply = sd_bus_message_unref(reply);
57098a23840SMatthew Barth 
57198a23840SMatthew Barth     return rc;
57298a23840SMatthew Barth }
57398a23840SMatthew Barth 
57498a23840SMatthew Barth ipmi_ret_t ipmi_sen_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
57598a23840SMatthew Barth                              ipmi_request_t request, ipmi_response_t response,
57698a23840SMatthew Barth                              ipmi_data_len_t data_len, ipmi_context_t context)
57798a23840SMatthew Barth {
57870aa8d96SNan Li     ipmi_ret_t rc = IPMI_CC_INVALID;
57998a23840SMatthew Barth 
58098a23840SMatthew Barth     printf("IPMI S/E Wildcard Netfn:[0x%X], Cmd:[0x%X]\n",netfn,cmd);
58198a23840SMatthew Barth     *data_len = 0;
58298a23840SMatthew Barth 
58398a23840SMatthew Barth     return rc;
58498a23840SMatthew Barth }
58598a23840SMatthew Barth 
586d06e0e7eSEmily Shaffer ipmi_ret_t ipmi_sen_get_sdr_info(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
587d06e0e7eSEmily Shaffer                                  ipmi_request_t request,
588d06e0e7eSEmily Shaffer                                  ipmi_response_t response,
589d06e0e7eSEmily Shaffer                                  ipmi_data_len_t data_len,
590d06e0e7eSEmily Shaffer                                  ipmi_context_t context)
591d06e0e7eSEmily Shaffer {
592d06e0e7eSEmily Shaffer     auto resp = static_cast<get_sdr_info::GetSdrInfoResp*>(response);
593d06e0e7eSEmily Shaffer     if (request == nullptr ||
594d06e0e7eSEmily Shaffer         get_sdr_info::request::get_count(request) == false)
595d06e0e7eSEmily Shaffer     {
596d06e0e7eSEmily Shaffer         // Get Sensor Count
597d06e0e7eSEmily Shaffer         resp->count = sensors.size();
598d06e0e7eSEmily Shaffer     }
599d06e0e7eSEmily Shaffer     else
600d06e0e7eSEmily Shaffer     {
601d06e0e7eSEmily Shaffer         resp->count = 1;
602d06e0e7eSEmily Shaffer     }
603d06e0e7eSEmily Shaffer 
604d06e0e7eSEmily Shaffer     // Multiple LUNs not supported.
605d06e0e7eSEmily Shaffer     namespace response = get_sdr_info::response;
606d06e0e7eSEmily Shaffer     response::set_lun_present(0, &(resp->luns_and_dynamic_population));
607d06e0e7eSEmily Shaffer     response::set_lun_not_present(1, &(resp->luns_and_dynamic_population));
608d06e0e7eSEmily Shaffer     response::set_lun_not_present(2, &(resp->luns_and_dynamic_population));
609d06e0e7eSEmily Shaffer     response::set_lun_not_present(3, &(resp->luns_and_dynamic_population));
610d06e0e7eSEmily Shaffer     response::set_static_population(&(resp->luns_and_dynamic_population));
611d06e0e7eSEmily Shaffer 
612d06e0e7eSEmily Shaffer     *data_len = SDR_INFO_RESP_SIZE;
613d06e0e7eSEmily Shaffer 
614d06e0e7eSEmily Shaffer     return IPMI_CC_OK;
615d06e0e7eSEmily Shaffer }
616d06e0e7eSEmily Shaffer 
617a344afc0SEmily Shaffer ipmi_ret_t ipmi_sen_reserve_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
618a344afc0SEmily Shaffer                                 ipmi_request_t request,
619a344afc0SEmily Shaffer                                 ipmi_response_t response,
620a344afc0SEmily Shaffer                                 ipmi_data_len_t data_len,
621a344afc0SEmily Shaffer                                 ipmi_context_t context)
622a344afc0SEmily Shaffer {
623a344afc0SEmily Shaffer     // A constant reservation ID is okay until we implement add/remove SDR.
624a344afc0SEmily Shaffer     const uint16_t reservation_id = 1;
625a344afc0SEmily Shaffer     *(uint16_t*)response = reservation_id;
626a344afc0SEmily Shaffer 
627a344afc0SEmily Shaffer     printf("Created new IPMI SDR reservation ID %d\n", *(uint16_t*)response);
628a344afc0SEmily Shaffer     return IPMI_CC_OK;
629a344afc0SEmily Shaffer }
63098a23840SMatthew Barth 
631bbef71c2SEmily Shaffer ipmi_ret_t populate_record_from_dbus(get_sdr::SensorDataFullRecordBody *body,
632bbef71c2SEmily Shaffer                                      const ipmi::sensor::Info *info,
633bbef71c2SEmily Shaffer                                      ipmi_data_len_t data_len)
634bbef71c2SEmily Shaffer {
635bbef71c2SEmily Shaffer     /* Functional sensor case */
636bbef71c2SEmily Shaffer     if (info->sensorInterfaces.begin()->first ==
637bbef71c2SEmily Shaffer             "xyz.openbmc_project.Sensor.Value")
638bbef71c2SEmily Shaffer     {
639bbef71c2SEmily Shaffer         // Get bus
640bbef71c2SEmily Shaffer         sd_bus *bus = ipmid_get_sd_bus_connection();
641bbef71c2SEmily Shaffer         dbus_interface_t iface;
642bbef71c2SEmily Shaffer 
643bbef71c2SEmily Shaffer         if (0 > find_openbmc_path(body->entity_id, &iface))
644bbef71c2SEmily Shaffer             return IPMI_CC_SENSOR_INVALID;
645bbef71c2SEmily Shaffer 
646bbef71c2SEmily Shaffer         body->sensor_units_1 = 0; // unsigned, no rate, no modifier, not a %
647bbef71c2SEmily Shaffer 
648bbef71c2SEmily Shaffer         /* Unit info */
649bbef71c2SEmily Shaffer         char *raw_cstr;
650bbef71c2SEmily Shaffer         if (0 > sd_bus_get_property_string(bus, iface.bus, iface.path,
651bbef71c2SEmily Shaffer                                             iface.interface, "Unit", NULL,
652bbef71c2SEmily Shaffer                                             &raw_cstr)) {
653bbef71c2SEmily Shaffer             fprintf(stderr, "Expected to find Unit interface in bus %s, path %s, but it was missing.\n",
654bbef71c2SEmily Shaffer                     iface.bus, iface.path);
655bbef71c2SEmily Shaffer             return IPMI_CC_SENSOR_INVALID;
656bbef71c2SEmily Shaffer         }
657bbef71c2SEmily Shaffer 
658bbef71c2SEmily Shaffer         std::string raw_str(raw_cstr);
659bbef71c2SEmily Shaffer         namespace server = sdbusplus::xyz::openbmc_project::Sensor::server;
660bbef71c2SEmily Shaffer         server::Value::Unit unit =
661bbef71c2SEmily Shaffer             server::Value::convertUnitFromString(raw_str);
662bbef71c2SEmily Shaffer 
663bbef71c2SEmily Shaffer         // Unit strings defined in
664bbef71c2SEmily Shaffer         // phosphor-dbus-interfaces/xyz/openbmc_project/Sensor/Value.interface.yaml
665bbef71c2SEmily Shaffer         switch (unit)
666bbef71c2SEmily Shaffer         {
667bbef71c2SEmily Shaffer             case server::Value::Unit::DegreesC:
668bbef71c2SEmily Shaffer                 body->sensor_units_2_base = get_sdr::SENSOR_UNIT_DEGREES_C;
669bbef71c2SEmily Shaffer                 break;
670bbef71c2SEmily Shaffer             case server::Value::Unit::RPMS:
671bbef71c2SEmily Shaffer                 body->sensor_units_2_base = get_sdr::SENSOR_UNIT_REVOLUTIONS; // revolutions
672bbef71c2SEmily Shaffer                 get_sdr::body::set_rate_unit(0b100, body); // per minute
673bbef71c2SEmily Shaffer                 break;
674bbef71c2SEmily Shaffer             case server::Value::Unit::Volts:
675bbef71c2SEmily Shaffer                 body->sensor_units_2_base = get_sdr::SENSOR_UNIT_VOLTS;
676bbef71c2SEmily Shaffer                 break;
677bbef71c2SEmily Shaffer             case server::Value::Unit::Meters:
678bbef71c2SEmily Shaffer                 body->sensor_units_2_base = get_sdr::SENSOR_UNIT_METERS;
679bbef71c2SEmily Shaffer                 break;
680bbef71c2SEmily Shaffer             case server::Value::Unit::Amperes:
681bbef71c2SEmily Shaffer                 body->sensor_units_2_base = get_sdr::SENSOR_UNIT_AMPERES;
682bbef71c2SEmily Shaffer                 break;
683bbef71c2SEmily Shaffer             case server::Value::Unit::Joules:
684bbef71c2SEmily Shaffer                 body->sensor_units_2_base = get_sdr::SENSOR_UNIT_JOULES;
685bbef71c2SEmily Shaffer                 break;
686bbef71c2SEmily Shaffer             default:
687bbef71c2SEmily Shaffer                 fprintf(stderr, "Unknown value unit type: = %s\n", raw_cstr);
688bbef71c2SEmily Shaffer         }
689bbef71c2SEmily Shaffer 
690bbef71c2SEmily Shaffer         free(raw_cstr);
691bbef71c2SEmily Shaffer 
692bbef71c2SEmily Shaffer         /* Modifiers to reading info */
69310f4959aSEmily Shaffer         // Get scale
69410f4959aSEmily Shaffer         int64_t scale;
69510f4959aSEmily Shaffer         if (0 > sd_bus_get_property_trivial(bus,
69610f4959aSEmily Shaffer                                         iface.bus,
69710f4959aSEmily Shaffer                                         iface.path,
69810f4959aSEmily Shaffer                                         iface.interface,
69910f4959aSEmily Shaffer                                         "Scale",
70010f4959aSEmily Shaffer                                         NULL,
70110f4959aSEmily Shaffer                                         'x',
70210f4959aSEmily Shaffer                                         &scale)) {
70310f4959aSEmily Shaffer             fprintf(stderr, "Expected to find Scale interface in bus %s, path %s, but it was missing.\n",
70410f4959aSEmily Shaffer                     iface.bus, iface.path);
70510f4959aSEmily Shaffer             return IPMI_CC_SENSOR_INVALID;
70610f4959aSEmily Shaffer         }
70710f4959aSEmily Shaffer 
70810f4959aSEmily Shaffer         get_sdr::body::set_b(info->coefficientB, body);
70910f4959aSEmily Shaffer         get_sdr::body::set_m(info->coefficientM, body);
71010f4959aSEmily Shaffer         get_sdr::body::set_b_exp(info->exponentB, body);
71110f4959aSEmily Shaffer         get_sdr::body::set_r_exp(scale, body);
712bbef71c2SEmily Shaffer 
713bbef71c2SEmily Shaffer         /* ID string */
714bbef71c2SEmily Shaffer         std::string id_string = info->sensorPath.substr(
715bbef71c2SEmily Shaffer             info->sensorPath.find_last_of('/')+1, info->sensorPath.length());
716bbef71c2SEmily Shaffer         get_sdr::body::set_id_type(0b00, body); // 00 = unicode
717bbef71c2SEmily Shaffer         if (id_string.length() > FULL_RECORD_ID_STR_MAX_LENGTH)
718bbef71c2SEmily Shaffer         {
719bbef71c2SEmily Shaffer             get_sdr::body::set_id_strlen(FULL_RECORD_ID_STR_MAX_LENGTH, body);
720bbef71c2SEmily Shaffer         }
721bbef71c2SEmily Shaffer         else
722bbef71c2SEmily Shaffer         {
723bbef71c2SEmily Shaffer             get_sdr::body::set_id_strlen(id_string.length(), body);
724bbef71c2SEmily Shaffer         }
725bbef71c2SEmily Shaffer         strncpy(body->id_string, id_string.c_str(),
726bbef71c2SEmily Shaffer                 get_sdr::body::get_id_strlen(body));
727bbef71c2SEmily Shaffer     }
728bbef71c2SEmily Shaffer 
729bbef71c2SEmily Shaffer     return IPMI_CC_OK;
730bbef71c2SEmily Shaffer };
731bbef71c2SEmily Shaffer 
732bbef71c2SEmily Shaffer ipmi_ret_t ipmi_sen_get_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
733bbef71c2SEmily Shaffer                             ipmi_request_t request, ipmi_response_t response,
734bbef71c2SEmily Shaffer                             ipmi_data_len_t data_len, ipmi_context_t context)
735bbef71c2SEmily Shaffer {
736bbef71c2SEmily Shaffer     ipmi_ret_t ret = IPMI_CC_OK;
737bbef71c2SEmily Shaffer     get_sdr::GetSdrReq *req = (get_sdr::GetSdrReq*)request;
738bbef71c2SEmily Shaffer     get_sdr::GetSdrResp *resp = (get_sdr::GetSdrResp*)response;
739bbef71c2SEmily Shaffer     get_sdr::SensorDataFullRecord record = {0};
740bbef71c2SEmily Shaffer     if (req != NULL)
741bbef71c2SEmily Shaffer     {
742bbef71c2SEmily Shaffer         // Note: we use an iterator so we can provide the next ID at the end of
743bbef71c2SEmily Shaffer         // the call.
744bbef71c2SEmily Shaffer         auto sensor = sensors.begin();
745bbef71c2SEmily Shaffer 
746bbef71c2SEmily Shaffer         // At the beginning of a scan, the host side will send us id=0.
747bbef71c2SEmily Shaffer         if (get_sdr::request::get_record_id(req) != 0)
748bbef71c2SEmily Shaffer         {
749bbef71c2SEmily Shaffer             sensor = sensors.find(get_sdr::request::get_record_id(req));
750bbef71c2SEmily Shaffer             if(sensor == sensors.end()) {
751bbef71c2SEmily Shaffer                 return IPMI_CC_SENSOR_INVALID;
752bbef71c2SEmily Shaffer             }
753bbef71c2SEmily Shaffer         }
754bbef71c2SEmily Shaffer 
755bbef71c2SEmily Shaffer         uint8_t sensor_id = sensor->first;
756bbef71c2SEmily Shaffer 
757bbef71c2SEmily Shaffer         /* Header */
758bbef71c2SEmily Shaffer         get_sdr::header::set_record_id(sensor_id, &(record.header));
759bbef71c2SEmily Shaffer         record.header.sdr_version = 0x51; // Based on IPMI Spec v2.0 rev 1.1
760bbef71c2SEmily Shaffer         record.header.record_type = get_sdr::SENSOR_DATA_FULL_RECORD;
761bbef71c2SEmily Shaffer         record.header.record_length = sizeof(get_sdr::SensorDataFullRecord);
762bbef71c2SEmily Shaffer 
763bbef71c2SEmily Shaffer         /* Key */
764bbef71c2SEmily Shaffer         record.key.sensor_number = sensor_id;
765bbef71c2SEmily Shaffer 
766bbef71c2SEmily Shaffer         /* Body */
767bbef71c2SEmily Shaffer         record.body.entity_id = sensor_id;
768bbef71c2SEmily Shaffer         record.body.sensor_type = sensor->second.sensorType;
769bbef71c2SEmily Shaffer         record.body.event_reading_type = sensor->second.sensorReadingType;
770bbef71c2SEmily Shaffer 
771bbef71c2SEmily Shaffer         // Set the type-specific details given the DBus interface
772bbef71c2SEmily Shaffer         ret = populate_record_from_dbus(&(record.body), &(sensor->second),
773bbef71c2SEmily Shaffer                                         data_len);
774bbef71c2SEmily Shaffer 
775bbef71c2SEmily Shaffer         if (++sensor == sensors.end())
776bbef71c2SEmily Shaffer         {
777bbef71c2SEmily Shaffer             get_sdr::response::set_next_record_id(0xFFFF, resp); // last record
778bbef71c2SEmily Shaffer         }
779bbef71c2SEmily Shaffer         else
780bbef71c2SEmily Shaffer         {
781bbef71c2SEmily Shaffer             get_sdr::response::set_next_record_id(sensor->first, resp);
782bbef71c2SEmily Shaffer         }
783bbef71c2SEmily Shaffer 
784bbef71c2SEmily Shaffer         *data_len = sizeof(get_sdr::GetSdrResp) - req->offset;
785bbef71c2SEmily Shaffer         memcpy(resp->record_data, (char*)&record + req->offset,
786bbef71c2SEmily Shaffer                sizeof(get_sdr::SensorDataFullRecord) - req->offset);
787bbef71c2SEmily Shaffer     }
788bbef71c2SEmily Shaffer 
789bbef71c2SEmily Shaffer     return ret;
790bbef71c2SEmily Shaffer }
791bbef71c2SEmily Shaffer 
792bbef71c2SEmily Shaffer 
79398a23840SMatthew Barth void register_netfn_sen_functions()
79498a23840SMatthew Barth {
7950573237fSTom     // <Wildcard Command>
796a344afc0SEmily Shaffer     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
797a344afc0SEmily Shaffer            NETFUN_SENSOR, IPMI_CMD_WILDCARD);
798a344afc0SEmily Shaffer     ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_WILDCARD,
799a344afc0SEmily Shaffer                            nullptr, ipmi_sen_wildcard,
8000573237fSTom                            PRIVILEGE_USER);
80198a23840SMatthew Barth 
8020573237fSTom     // <Get Sensor Type>
803a344afc0SEmily Shaffer     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
804a344afc0SEmily Shaffer            NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE);
805a344afc0SEmily Shaffer     ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE,
806a344afc0SEmily Shaffer                            nullptr, ipmi_sen_get_sensor_type,
8070573237fSTom                            PRIVILEGE_USER);
80898a23840SMatthew Barth 
8090573237fSTom     // <Set Sensor Reading and Event Status>
810a344afc0SEmily Shaffer     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
811a344afc0SEmily Shaffer            NETFUN_SENSOR, IPMI_CMD_SET_SENSOR);
812a344afc0SEmily Shaffer     ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_SET_SENSOR,
813a344afc0SEmily Shaffer                            nullptr, ipmi_sen_set_sensor,
8140573237fSTom                            PRIVILEGE_OPERATOR);
81598a23840SMatthew Barth 
8160573237fSTom     // <Get Sensor Reading>
817a344afc0SEmily Shaffer     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
818a344afc0SEmily Shaffer            NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_READING);
819a344afc0SEmily Shaffer     ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_READING,
820a344afc0SEmily Shaffer                            nullptr, ipmi_sen_get_sensor_reading,
821a344afc0SEmily Shaffer                            PRIVILEGE_USER);
822a344afc0SEmily Shaffer 
823a344afc0SEmily Shaffer     // <Reserve SDR>
824a344afc0SEmily Shaffer     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
825a344afc0SEmily Shaffer            NETFUN_SENSOR, IPMI_CMD_RESERVE_SDR_REPO);
826a344afc0SEmily Shaffer     ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_RESERVE_SDR_REPO,
827a344afc0SEmily Shaffer                            nullptr, ipmi_sen_reserve_sdr,
828a344afc0SEmily Shaffer                            PRIVILEGE_USER);
82998a23840SMatthew Barth 
830d06e0e7eSEmily Shaffer     // <Get SDR Info>
831a344afc0SEmily Shaffer     printf("Registering NetFn:[0x%X], Cmd:[0x%x]\n",
832a344afc0SEmily Shaffer            NETFUN_SENSOR, IPMI_CMD_GET_SDR_INFO);
833a344afc0SEmily Shaffer     ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SDR_INFO,
834a344afc0SEmily Shaffer                            nullptr, ipmi_sen_get_sdr_info,
835a344afc0SEmily Shaffer                            PRIVILEGE_USER);
836bbef71c2SEmily Shaffer 
837bbef71c2SEmily Shaffer     // <Get SDR>
838bbef71c2SEmily Shaffer     printf("Registering NetFn:[0x%X], Cmd:[0x%x]\n",
839bbef71c2SEmily Shaffer            NETFUN_SENSOR, IPMI_CMD_GET_SDR);
840bbef71c2SEmily Shaffer     ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SDR,
841bbef71c2SEmily Shaffer                            nullptr, ipmi_sen_get_sdr,
842bbef71c2SEmily Shaffer                            PRIVILEGE_USER);
843bbef71c2SEmily Shaffer 
84498a23840SMatthew Barth     return;
84598a23840SMatthew Barth }
846