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> 10*18e99992SDhruvaraj Subhashchandran #include <phosphor-logging/elog-errors.hpp> 11d700e76aSTom #include "ipmid.hpp" 12be703f71STom Joseph #include "sensorhandler.h" 13be703f71STom Joseph #include "types.hpp" 14be703f71STom Joseph #include "utils.hpp" 15*18e99992SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Common/error.hpp" 16*18e99992SDhruvaraj Subhashchandran 1798a23840SMatthew Barth 1898a23840SMatthew Barth extern int updateSensorRecordFromSSRAESC(const void *); 19d700e76aSTom extern sd_bus *bus; 20be703f71STom Joseph extern const ipmi::sensor::IdInfoMap sensors; 21be703f71STom Joseph using namespace phosphor::logging; 22*18e99992SDhruvaraj Subhashchandran using InternalFailure = 23*18e99992SDhruvaraj Subhashchandran sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 2498a23840SMatthew Barth 2598a23840SMatthew Barth void register_netfn_sen_functions() __attribute__((constructor)); 2698a23840SMatthew Barth 2798a23840SMatthew Barth struct sensorTypemap_t { 2898a23840SMatthew Barth uint8_t number; 2998a23840SMatthew Barth uint8_t typecode; 3098a23840SMatthew Barth char dbusname[32]; 3198a23840SMatthew Barth } ; 3298a23840SMatthew Barth 3398a23840SMatthew Barth sensorTypemap_t g_SensorTypeMap[] = { 3498a23840SMatthew Barth 3598a23840SMatthew Barth {0x01, 0x6F, "Temp"}, 3698a23840SMatthew Barth {0x0C, 0x6F, "DIMM"}, 3798a23840SMatthew Barth {0x0C, 0x6F, "MEMORY_BUFFER"}, 3898a23840SMatthew Barth {0x07, 0x6F, "PROC"}, 3998a23840SMatthew Barth {0x07, 0x6F, "CORE"}, 4098a23840SMatthew Barth {0x07, 0x6F, "CPU"}, 4198a23840SMatthew Barth {0x0F, 0x6F, "BootProgress"}, 4298a23840SMatthew Barth {0xe9, 0x09, "OccStatus"}, // E9 is an internal mapping to handle sensor type code os 0x09 4398a23840SMatthew Barth {0xC3, 0x6F, "BootCount"}, 4498a23840SMatthew Barth {0x1F, 0x6F, "OperatingSystemStatus"}, 4598a23840SMatthew Barth {0x12, 0x6F, "SYSTEM_EVENT"}, 4698a23840SMatthew Barth {0xC7, 0x03, "SYSTEM"}, 4798a23840SMatthew Barth {0xC7, 0x03, "MAIN_PLANAR"}, 4898a23840SMatthew Barth {0xC2, 0x6F, "PowerCap"}, 4907248298SDhruvaraj S {0xD8, 0x03, "PowerSupplyRedundancy"}, 500661beb1SJayanth Othayoth {0xDA, 0x03, "TurboAllowed"}, 51d5b2ac0eSJayanth Othayoth {0xB4, 0x6F, "PowerSupplyDerating"}, 5298a23840SMatthew Barth {0xFF, 0x00, ""}, 5398a23840SMatthew Barth }; 5498a23840SMatthew Barth 5598a23840SMatthew Barth 5698a23840SMatthew Barth struct sensor_data_t { 5798a23840SMatthew Barth uint8_t sennum; 5898a23840SMatthew Barth } __attribute__ ((packed)) ; 5998a23840SMatthew Barth 6098a23840SMatthew Barth struct sensorreadingresp_t { 6198a23840SMatthew Barth uint8_t value; 6298a23840SMatthew Barth uint8_t operation; 6398a23840SMatthew Barth uint8_t indication[2]; 6498a23840SMatthew Barth } __attribute__ ((packed)) ; 6598a23840SMatthew Barth 66d700e76aSTom // Use a lookup table to find the interface name of a specific sensor 67d700e76aSTom // This will be used until an alternative is found. this is the first 68d700e76aSTom // step for mapping IPMI 69d700e76aSTom int find_interface_property_fru_type(dbus_interface_t *interface, const char *property_name, char *property_value) { 70d700e76aSTom 71d700e76aSTom char *str1; 72d700e76aSTom sd_bus_error error = SD_BUS_ERROR_NULL; 73d700e76aSTom sd_bus_message *reply = NULL, *m=NULL; 74d700e76aSTom 75d700e76aSTom 76d700e76aSTom int r; 77d700e76aSTom 78d700e76aSTom r = sd_bus_message_new_method_call(bus,&m,interface->bus,interface->path,"org.freedesktop.DBus.Properties","Get"); 79d700e76aSTom if (r < 0) { 80d700e76aSTom fprintf(stderr, "Failed to create a method call: %s", strerror(-r)); 81d700e76aSTom fprintf(stderr,"Bus: %s Path: %s Interface: %s \n", 82d700e76aSTom interface->bus, interface->path, interface->interface); 83d700e76aSTom goto final; 84d700e76aSTom } 85d700e76aSTom 86d700e76aSTom r = sd_bus_message_append(m, "ss", "org.openbmc.InventoryItem", property_name); 87d700e76aSTom if (r < 0) { 88d700e76aSTom fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r)); 89d700e76aSTom fprintf(stderr,"Bus: %s Path: %s Interface: %s \n", 90d700e76aSTom interface->bus, interface->path, interface->interface); 91d700e76aSTom goto final; 92d700e76aSTom } 93d700e76aSTom 94d700e76aSTom r = sd_bus_call(bus, m, 0, &error, &reply); 95d700e76aSTom if (r < 0) { 96d700e76aSTom fprintf(stderr, "Failed to call the method: %s", strerror(-r)); 97d700e76aSTom goto final; 98d700e76aSTom } 99d700e76aSTom 100d700e76aSTom r = sd_bus_message_read(reply, "v", "s", &str1) ; 101d700e76aSTom if (r < 0) { 102d700e76aSTom fprintf(stderr, "Failed to get a response: %s", strerror(-r)); 103d700e76aSTom goto final; 104d700e76aSTom } 105d700e76aSTom 106d700e76aSTom strcpy(property_value, str1); 107d700e76aSTom 108d700e76aSTom final: 109d700e76aSTom 110d700e76aSTom sd_bus_error_free(&error); 111d700e76aSTom m = sd_bus_message_unref(m); 112d700e76aSTom reply = sd_bus_message_unref(reply); 113d700e76aSTom 114d700e76aSTom return r; 115d700e76aSTom } 116d700e76aSTom 1172ae09b9aSEmily Shaffer int get_bus_for_path(const char *path, char **busname) { 1182ae09b9aSEmily Shaffer return mapper_get_service(bus, path, busname); 1192ae09b9aSEmily Shaffer } 120d700e76aSTom 1212ae09b9aSEmily Shaffer int legacy_dbus_openbmc_path(const char *type, const uint8_t num, dbus_interface_t *interface) { 122d700e76aSTom char *busname = NULL; 123d700e76aSTom const char *iface = "org.openbmc.managers.System"; 124d700e76aSTom const char *objname = "/org/openbmc/managers/System"; 125d700e76aSTom char *str1 = NULL, *str2, *str3; 126d700e76aSTom sd_bus_error error = SD_BUS_ERROR_NULL; 127d700e76aSTom sd_bus_message *reply = NULL; 128d700e76aSTom 129d700e76aSTom 130d700e76aSTom int r; 1312ae09b9aSEmily Shaffer r = get_bus_for_path(objname, &busname); 132d700e76aSTom if (r < 0) { 133819ddd42SBrad Bishop fprintf(stderr, "Failed to get %s busname: %s\n", 134819ddd42SBrad Bishop objname, strerror(-r)); 135d700e76aSTom goto final; 136d700e76aSTom } 137d700e76aSTom 138d700e76aSTom r = sd_bus_call_method(bus,busname,objname,iface, "getObjectFromByteId", 139d700e76aSTom &error, &reply, "sy", type, num); 140d700e76aSTom if (r < 0) { 141d700e76aSTom fprintf(stderr, "Failed to create a method call: %s", strerror(-r)); 142d700e76aSTom goto final; 143d700e76aSTom } 144d700e76aSTom 145d700e76aSTom r = sd_bus_message_read(reply, "(ss)", &str2, &str3); 146d700e76aSTom if (r < 0) { 147d700e76aSTom fprintf(stderr, "Failed to get a response: %s", strerror(-r)); 148d700e76aSTom goto final; 149d700e76aSTom } 150d700e76aSTom 1512ae09b9aSEmily Shaffer r = get_bus_for_path(str2, &str1); 152d700e76aSTom if (r < 0) { 153819ddd42SBrad Bishop fprintf(stderr, "Failed to get %s busname: %s\n", 154819ddd42SBrad Bishop str2, strerror(-r)); 155d700e76aSTom goto final; 156d700e76aSTom } 157d700e76aSTom 158d700e76aSTom strncpy(interface->bus, str1, MAX_DBUS_PATH); 159d700e76aSTom strncpy(interface->path, str2, MAX_DBUS_PATH); 160d700e76aSTom strncpy(interface->interface, str3, MAX_DBUS_PATH); 161d700e76aSTom 162d700e76aSTom interface->sensornumber = num; 1637117441cSEmily Shaffer // Make sure we know that the type hasn't been set, as newer codebase will 1647117441cSEmily Shaffer // set it automatically from the YAML at this step. 1657117441cSEmily Shaffer interface->sensortype = 0; 166d700e76aSTom 167d700e76aSTom final: 168d700e76aSTom 169d700e76aSTom sd_bus_error_free(&error); 170d700e76aSTom reply = sd_bus_message_unref(reply); 171d700e76aSTom free(busname); 172d700e76aSTom free(str1); 173d700e76aSTom 174d700e76aSTom return r; 175d700e76aSTom } 176d700e76aSTom 1772ae09b9aSEmily Shaffer // Use a lookup table to find the interface name of a specific sensor 1782ae09b9aSEmily Shaffer // This will be used until an alternative is found. this is the first 1792ae09b9aSEmily Shaffer // step for mapping IPMI 1802ae09b9aSEmily Shaffer int find_openbmc_path(uint8_t num, dbus_interface_t *interface) { 1812ae09b9aSEmily Shaffer int rc; 1822ae09b9aSEmily Shaffer 1832ae09b9aSEmily Shaffer // When the sensor map does not contain the sensor requested, 1842ae09b9aSEmily Shaffer // fall back to the legacy DBus lookup (deprecated) 1852ae09b9aSEmily Shaffer const auto& sensor_it = sensors.find(num); 1862ae09b9aSEmily Shaffer if (sensor_it == sensors.end()) 1872ae09b9aSEmily Shaffer { 1882ae09b9aSEmily Shaffer return legacy_dbus_openbmc_path("SENSOR", num, interface); 1892ae09b9aSEmily Shaffer } 1902ae09b9aSEmily Shaffer 1912ae09b9aSEmily Shaffer const auto& info = sensor_it->second; 1922ae09b9aSEmily Shaffer 1938451edf5SPatrick Williams char* busname = nullptr; 1942ae09b9aSEmily Shaffer rc = get_bus_for_path(info.sensorPath.c_str(), &busname); 1952ae09b9aSEmily Shaffer if (rc < 0) { 1962ae09b9aSEmily Shaffer fprintf(stderr, "Failed to get %s busname: %s\n", 1972ae09b9aSEmily Shaffer info.sensorPath.c_str(), 1982ae09b9aSEmily Shaffer busname); 1992ae09b9aSEmily Shaffer goto final; 2002ae09b9aSEmily Shaffer } 2012ae09b9aSEmily Shaffer 2022ae09b9aSEmily Shaffer interface->sensortype = info.sensorType; 2032ae09b9aSEmily Shaffer strcpy(interface->bus, busname); 2042ae09b9aSEmily Shaffer strcpy(interface->path, info.sensorPath.c_str()); 2052ae09b9aSEmily Shaffer // Take the interface name from the beginning of the DbusInterfaceMap. This 2062ae09b9aSEmily Shaffer // works for the Value interface but may not suffice for more complex 2072ae09b9aSEmily Shaffer // sensors. 2082ae09b9aSEmily Shaffer // tracked https://github.com/openbmc/phosphor-host-ipmid/issues/103 2092ae09b9aSEmily Shaffer strcpy(interface->interface, info.sensorInterfaces.begin()->first.c_str()); 2102ae09b9aSEmily Shaffer interface->sensornumber = num; 2112ae09b9aSEmily Shaffer 2122ae09b9aSEmily Shaffer final: 2132ae09b9aSEmily Shaffer free(busname); 2142ae09b9aSEmily Shaffer return rc; 2152ae09b9aSEmily Shaffer } 2162ae09b9aSEmily Shaffer 217d700e76aSTom 218d700e76aSTom ///////////////////////////////////////////////////////////////////// 219d700e76aSTom // 220d700e76aSTom // Routines used by ipmi commands wanting to interact on the dbus 221d700e76aSTom // 222d700e76aSTom ///////////////////////////////////////////////////////////////////// 223d700e76aSTom int set_sensor_dbus_state_s(uint8_t number, const char *method, const char *value) { 224d700e76aSTom 225d700e76aSTom 226d700e76aSTom dbus_interface_t a; 227d700e76aSTom int r; 228d700e76aSTom sd_bus_error error = SD_BUS_ERROR_NULL; 229d700e76aSTom sd_bus_message *m=NULL; 230d700e76aSTom 231d700e76aSTom fprintf(ipmidbus, "Attempting to set a dbus Variant Sensor 0x%02x via %s with a value of %s\n", 232d700e76aSTom number, method, value); 233d700e76aSTom 2342ae09b9aSEmily Shaffer r = find_openbmc_path(number, &a); 235d700e76aSTom 236d700e76aSTom if (r < 0) { 237d700e76aSTom fprintf(stderr, "Failed to find Sensor 0x%02x\n", number); 238d700e76aSTom return 0; 239d700e76aSTom } 240d700e76aSTom 241d700e76aSTom r = sd_bus_message_new_method_call(bus,&m,a.bus,a.path,a.interface,method); 242d700e76aSTom if (r < 0) { 243d700e76aSTom fprintf(stderr, "Failed to create a method call: %s", strerror(-r)); 244d700e76aSTom goto final; 245d700e76aSTom } 246d700e76aSTom 247d700e76aSTom r = sd_bus_message_append(m, "v", "s", value); 248d700e76aSTom if (r < 0) { 249d700e76aSTom fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r)); 250d700e76aSTom goto final; 251d700e76aSTom } 252d700e76aSTom 253d700e76aSTom 254d700e76aSTom r = sd_bus_call(bus, m, 0, &error, NULL); 255d700e76aSTom if (r < 0) { 256d700e76aSTom fprintf(stderr, "Failed to call the method: %s", strerror(-r)); 257d700e76aSTom } 258d700e76aSTom 259d700e76aSTom final: 260d700e76aSTom sd_bus_error_free(&error); 261d700e76aSTom m = sd_bus_message_unref(m); 262d700e76aSTom 263d700e76aSTom return 0; 264d700e76aSTom } 265d700e76aSTom int set_sensor_dbus_state_y(uint8_t number, const char *method, const uint8_t value) { 266d700e76aSTom 267d700e76aSTom 268d700e76aSTom dbus_interface_t a; 269d700e76aSTom int r; 270d700e76aSTom sd_bus_error error = SD_BUS_ERROR_NULL; 271d700e76aSTom sd_bus_message *m=NULL; 272d700e76aSTom 273d700e76aSTom fprintf(ipmidbus, "Attempting to set a dbus Variant Sensor 0x%02x via %s with a value of 0x%02x\n", 274d700e76aSTom number, method, value); 275d700e76aSTom 2762ae09b9aSEmily Shaffer r = find_openbmc_path(number, &a); 277d700e76aSTom 278d700e76aSTom if (r < 0) { 279d700e76aSTom fprintf(stderr, "Failed to find Sensor 0x%02x\n", number); 280d700e76aSTom return 0; 281d700e76aSTom } 282d700e76aSTom 283d700e76aSTom r = sd_bus_message_new_method_call(bus,&m,a.bus,a.path,a.interface,method); 284d700e76aSTom if (r < 0) { 285d700e76aSTom fprintf(stderr, "Failed to create a method call: %s", strerror(-r)); 286d700e76aSTom goto final; 287d700e76aSTom } 288d700e76aSTom 289d700e76aSTom r = sd_bus_message_append(m, "v", "i", value); 290d700e76aSTom if (r < 0) { 291d700e76aSTom fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r)); 292d700e76aSTom goto final; 293d700e76aSTom } 294d700e76aSTom 295d700e76aSTom 296d700e76aSTom r = sd_bus_call(bus, m, 0, &error, NULL); 297d700e76aSTom if (r < 0) { 298d700e76aSTom fprintf(stderr, "12 Failed to call the method: %s", strerror(-r)); 299d700e76aSTom } 300d700e76aSTom 301d700e76aSTom final: 302d700e76aSTom sd_bus_error_free(&error); 303d700e76aSTom m = sd_bus_message_unref(m); 304d700e76aSTom 305d700e76aSTom return 0; 306d700e76aSTom } 307d700e76aSTom 30898a23840SMatthew Barth uint8_t dbus_to_sensor_type(char *p) { 30998a23840SMatthew Barth 31098a23840SMatthew Barth sensorTypemap_t *s = g_SensorTypeMap; 31198a23840SMatthew Barth char r=0; 31298a23840SMatthew Barth 31398a23840SMatthew Barth while (s->number != 0xFF) { 31498a23840SMatthew Barth if (!strcmp(s->dbusname,p)) { 31598a23840SMatthew Barth r = s->number; 31698a23840SMatthew Barth break; 31798a23840SMatthew Barth } 31898a23840SMatthew Barth s++; 31998a23840SMatthew Barth } 32098a23840SMatthew Barth 32198a23840SMatthew Barth 32298a23840SMatthew Barth if (s->number == 0xFF) 32398a23840SMatthew Barth printf("Failed to find Sensor Type %s\n", p); 32498a23840SMatthew Barth 32598a23840SMatthew Barth return r; 32698a23840SMatthew Barth } 32798a23840SMatthew Barth 32898a23840SMatthew Barth 32998a23840SMatthew Barth uint8_t dbus_to_sensor_type_from_dbus(dbus_interface_t *a) { 33098a23840SMatthew Barth char fru_type_name[64]; 33198a23840SMatthew Barth int r= 0; 33298a23840SMatthew Barth 33398a23840SMatthew Barth r = find_interface_property_fru_type(a, "fru_type", fru_type_name); 33498a23840SMatthew Barth if (r<0) { 33598a23840SMatthew Barth fprintf(stderr, "Failed to get a fru type: %s", strerror(-r)); 33698a23840SMatthew Barth return -1; 33798a23840SMatthew Barth } else { 33898a23840SMatthew Barth return dbus_to_sensor_type(fru_type_name); 33998a23840SMatthew Barth } 34098a23840SMatthew Barth } 34198a23840SMatthew Barth 342391f3303SEmily Shaffer uint8_t get_type_from_interface(dbus_interface_t dbus_if) { 34398a23840SMatthew Barth 34498a23840SMatthew Barth char *p; 34556003453SBrad Bishop uint8_t type; 34698a23840SMatthew Barth 34798a23840SMatthew Barth // This is where sensors that do not exist in dbus but do 34898a23840SMatthew Barth // exist in the host code stop. This should indicate it 34998a23840SMatthew Barth // is not a supported sensor 350391f3303SEmily Shaffer if (dbus_if.interface[0] == 0) { return 0;} 35198a23840SMatthew Barth 3527117441cSEmily Shaffer // Fetch type from interface itself. 3537117441cSEmily Shaffer if (dbus_if.sensortype != 0) 3547117441cSEmily Shaffer { 3557117441cSEmily Shaffer type = dbus_if.sensortype; 3567117441cSEmily Shaffer } 3577117441cSEmily Shaffer // Legacy codebase does not populate type during initial handling: 3587117441cSEmily Shaffer else if (strstr(dbus_if.interface, "InventoryItem")) { 35998a23840SMatthew Barth // InventoryItems are real frus. So need to get the 36098a23840SMatthew Barth // fru_type property 361391f3303SEmily Shaffer type = dbus_to_sensor_type_from_dbus(&dbus_if); 36298a23840SMatthew Barth } else { 36398a23840SMatthew Barth // Non InventoryItems 364391f3303SEmily Shaffer p = strrchr (dbus_if.path, '/'); 36556003453SBrad Bishop type = dbus_to_sensor_type(p+1); 36698a23840SMatthew Barth } 36798a23840SMatthew Barth 36856003453SBrad Bishop return type; 36998a23840SMatthew Barth } 37098a23840SMatthew Barth 371391f3303SEmily Shaffer // Replaces find_sensor 372391f3303SEmily Shaffer uint8_t find_type_for_sensor_number(uint8_t num) { 373391f3303SEmily Shaffer int r; 374391f3303SEmily Shaffer dbus_interface_t dbus_if; 3752ae09b9aSEmily Shaffer r = find_openbmc_path(num, &dbus_if); 376391f3303SEmily Shaffer if (r < 0) { 377391f3303SEmily Shaffer fprintf(stderr, "Could not find sensor %d\n", num); 378391f3303SEmily Shaffer return r; 379391f3303SEmily Shaffer } 380391f3303SEmily Shaffer return get_type_from_interface(dbus_if); 381391f3303SEmily Shaffer } 382391f3303SEmily Shaffer 38398a23840SMatthew Barth 38498a23840SMatthew Barth 38598a23840SMatthew Barth 38698a23840SMatthew Barth 38798a23840SMatthew Barth ipmi_ret_t ipmi_sen_get_sensor_type(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 38898a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 38998a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 39098a23840SMatthew Barth { 39198a23840SMatthew Barth sensor_data_t *reqptr = (sensor_data_t*)request; 39298a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_OK; 39398a23840SMatthew Barth 39498a23840SMatthew Barth printf("IPMI GET_SENSOR_TYPE [0x%02X]\n",reqptr->sennum); 39598a23840SMatthew Barth 39698a23840SMatthew Barth // TODO Not sure what the System-event-sensor is suppose to return 39798a23840SMatthew Barth // need to ask Hostboot team 39898a23840SMatthew Barth unsigned char buf[] = {0x00,0x6F}; 39998a23840SMatthew Barth 400391f3303SEmily Shaffer buf[0] = find_type_for_sensor_number(reqptr->sennum); 40198a23840SMatthew Barth 40298a23840SMatthew Barth // HACK UNTIL Dbus gets updated or we find a better way 40398a23840SMatthew Barth if (buf[0] == 0) { 40498a23840SMatthew Barth rc = IPMI_CC_SENSOR_INVALID; 40598a23840SMatthew Barth } 40698a23840SMatthew Barth 40798a23840SMatthew Barth 40898a23840SMatthew Barth *data_len = sizeof(buf); 40998a23840SMatthew Barth memcpy(response, &buf, *data_len); 41098a23840SMatthew Barth 41198a23840SMatthew Barth return rc; 41298a23840SMatthew Barth } 41398a23840SMatthew Barth 414be703f71STom Joseph ipmi_ret_t setSensorReading(void *request) 415be703f71STom Joseph { 416e0af7209SDhruvaraj Subhashchandran SetSensorReadingReq cmdData = 417e0af7209SDhruvaraj Subhashchandran *(static_cast<SetSensorReadingReq *>(request)); 418be703f71STom Joseph 419be703f71STom Joseph // Check if the Sensor Number is present 420e0af7209SDhruvaraj Subhashchandran const auto iter = sensors.find(cmdData.number); 421be703f71STom Joseph if (iter == sensors.end()) 422be703f71STom Joseph { 423be703f71STom Joseph return IPMI_CC_SENSOR_INVALID; 424be703f71STom Joseph } 425be703f71STom Joseph 426*18e99992SDhruvaraj Subhashchandran try 427*18e99992SDhruvaraj Subhashchandran { 428e0af7209SDhruvaraj Subhashchandran return iter->second.updateFunc(cmdData, iter->second); 429be703f71STom Joseph } 430*18e99992SDhruvaraj Subhashchandran catch (InternalFailure& e) 431*18e99992SDhruvaraj Subhashchandran { 432*18e99992SDhruvaraj Subhashchandran log<level::ERR>("Set sensor failed", 433*18e99992SDhruvaraj Subhashchandran entry("SENSOR_NUM=%d", cmdData.number)); 434*18e99992SDhruvaraj Subhashchandran commit<InternalFailure>(); 435*18e99992SDhruvaraj Subhashchandran } 436*18e99992SDhruvaraj Subhashchandran 437*18e99992SDhruvaraj Subhashchandran return IPMI_CC_UNSPECIFIED_ERROR; 438*18e99992SDhruvaraj Subhashchandran } 43998a23840SMatthew Barth 44098a23840SMatthew Barth ipmi_ret_t ipmi_sen_set_sensor(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 44198a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 44298a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 44398a23840SMatthew Barth { 44498a23840SMatthew Barth sensor_data_t *reqptr = (sensor_data_t*)request; 44598a23840SMatthew Barth 44698a23840SMatthew Barth printf("IPMI SET_SENSOR [0x%02x]\n",reqptr->sennum); 44798a23840SMatthew Barth 448be703f71STom Joseph /* 449be703f71STom Joseph * This would support the Set Sensor Reading command for the presence 450be703f71STom Joseph * and functional state of Processor, Core & DIMM. For the remaining 451be703f71STom Joseph * sensors the existing support is invoked. 452be703f71STom Joseph */ 453be703f71STom Joseph auto ipmiRC = setSensorReading(request); 454be703f71STom Joseph 455be703f71STom Joseph if(ipmiRC == IPMI_CC_SENSOR_INVALID) 456be703f71STom Joseph { 45798a23840SMatthew Barth updateSensorRecordFromSSRAESC(reqptr); 458be703f71STom Joseph ipmiRC = IPMI_CC_OK; 459be703f71STom Joseph } 46098a23840SMatthew Barth 46198a23840SMatthew Barth *data_len=0; 462be703f71STom Joseph return ipmiRC; 46398a23840SMatthew Barth } 46498a23840SMatthew Barth 46598a23840SMatthew Barth 46698a23840SMatthew Barth ipmi_ret_t ipmi_sen_get_sensor_reading(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 46798a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 46898a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 46998a23840SMatthew Barth { 47098a23840SMatthew Barth sensor_data_t *reqptr = (sensor_data_t*)request; 47198a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_SENSOR_INVALID; 47298a23840SMatthew Barth uint8_t type; 47398a23840SMatthew Barth sensorreadingresp_t *resp = (sensorreadingresp_t*) response; 47498a23840SMatthew Barth int r; 47598a23840SMatthew Barth dbus_interface_t a; 47698a23840SMatthew Barth sd_bus *bus = ipmid_get_sd_bus_connection(); 47798a23840SMatthew Barth sd_bus_message *reply = NULL; 47898a23840SMatthew Barth int reading = 0; 47998a23840SMatthew Barth 48098a23840SMatthew Barth 48198a23840SMatthew Barth printf("IPMI GET_SENSOR_READING [0x%02x]\n",reqptr->sennum); 48298a23840SMatthew Barth 4832ae09b9aSEmily Shaffer r = find_openbmc_path(reqptr->sennum, &a); 48498a23840SMatthew Barth 48598a23840SMatthew Barth if (r < 0) { 48698a23840SMatthew Barth fprintf(stderr, "Failed to find Sensor 0x%02x\n", reqptr->sennum); 48798a23840SMatthew Barth return IPMI_CC_SENSOR_INVALID; 48898a23840SMatthew Barth } 48998a23840SMatthew Barth 490391f3303SEmily Shaffer type = get_type_from_interface(a); 49156003453SBrad Bishop if(type == 0) { 49256003453SBrad Bishop fprintf(stderr, "Failed to find Sensor 0x%02x\n", reqptr->sennum); 49356003453SBrad Bishop return IPMI_CC_SENSOR_INVALID; 49456003453SBrad Bishop } 49598a23840SMatthew Barth 49698a23840SMatthew Barth fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n", a.bus, a.path, a.interface); 49798a23840SMatthew Barth 49898a23840SMatthew Barth *data_len=0; 49998a23840SMatthew Barth 50010f4959aSEmily Shaffer int64_t raw_value; 5011fabf229SEmily Shaffer ipmi::sensor::Info sensor; 5021fabf229SEmily Shaffer 50398a23840SMatthew Barth switch(type) { 50498a23840SMatthew Barth case 0xC3: 50598a23840SMatthew Barth case 0xC2: 50698a23840SMatthew Barth r = sd_bus_get_property(bus,a.bus, a.path, a.interface, "value", NULL, &reply, "i"); 50798a23840SMatthew Barth if (r < 0) { 50898a23840SMatthew Barth fprintf(stderr, "Failed to call sd_bus_get_property:%d, %s\n", r, strerror(-r)); 50998a23840SMatthew Barth fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n", 51098a23840SMatthew Barth a.bus, a.path, a.interface); 51198a23840SMatthew Barth break; 51298a23840SMatthew Barth } 51398a23840SMatthew Barth 51498a23840SMatthew Barth r = sd_bus_message_read(reply, "i", &reading); 51598a23840SMatthew Barth if (r < 0) { 51698a23840SMatthew Barth fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r)); 51798a23840SMatthew Barth break; 51898a23840SMatthew Barth } 51998a23840SMatthew Barth 52098a23840SMatthew Barth printf("Contents of a 0x%02x is 0x%02x\n", type, reading); 52198a23840SMatthew Barth 52298a23840SMatthew Barth rc = IPMI_CC_OK; 52398a23840SMatthew Barth *data_len=sizeof(sensorreadingresp_t); 52498a23840SMatthew Barth 52598a23840SMatthew Barth resp->value = (uint8_t)reading; 52698a23840SMatthew Barth resp->operation = 0; 52798a23840SMatthew Barth resp->indication[0] = 0; 52898a23840SMatthew Barth resp->indication[1] = 0; 52998a23840SMatthew Barth break; 53098a23840SMatthew Barth 5311fabf229SEmily Shaffer case IPMI_SENSOR_TEMP: 5321fabf229SEmily Shaffer case IPMI_SENSOR_VOLTAGE: 5331fabf229SEmily Shaffer case IPMI_SENSOR_CURRENT: 5341fabf229SEmily Shaffer case IPMI_SENSOR_FAN: 5351fabf229SEmily Shaffer // Get reading for /xyz/openbmc_project/Sensor/Value.interface 53610f4959aSEmily Shaffer if(sensors.find(reqptr->sennum) == sensors.end()) 53710f4959aSEmily Shaffer { 53810f4959aSEmily Shaffer fprintf(stderr, "Failed to find config entry for Sensor 0x%02x\n", 53910f4959aSEmily Shaffer reqptr->sennum); 54010f4959aSEmily Shaffer return IPMI_CC_SENSOR_INVALID; 54110f4959aSEmily Shaffer } 54210f4959aSEmily Shaffer 54310f4959aSEmily Shaffer sensor = sensors.at(reqptr->sennum); 5441fabf229SEmily Shaffer 5451fabf229SEmily Shaffer // Get value 5461fabf229SEmily Shaffer r = sd_bus_get_property_trivial(bus, 5471fabf229SEmily Shaffer a.bus, 5481fabf229SEmily Shaffer a.path, 5491fabf229SEmily Shaffer a.interface, 5501fabf229SEmily Shaffer "Value", 5511fabf229SEmily Shaffer NULL, 5521fabf229SEmily Shaffer 'x', 5531fabf229SEmily Shaffer &raw_value); 5541fabf229SEmily Shaffer if (r < 0) { 5551fabf229SEmily Shaffer fprintf(stderr, 5561fabf229SEmily Shaffer "Failed to call sd_bus_get_property:%d, %s, 'value'\n", 5571fabf229SEmily Shaffer r, 5581fabf229SEmily Shaffer strerror(-r)); 5591fabf229SEmily Shaffer fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n", 5601fabf229SEmily Shaffer a.bus, a.path, a.interface); 5611fabf229SEmily Shaffer break; 5621fabf229SEmily Shaffer } 5631fabf229SEmily Shaffer 56410f4959aSEmily Shaffer // Prevent div0 56510f4959aSEmily Shaffer if (sensor.coefficientM == 0) { 56610f4959aSEmily Shaffer sensor.coefficientM = 1; 56710f4959aSEmily Shaffer }; 5681fabf229SEmily Shaffer 56910f4959aSEmily Shaffer resp->value = static_cast<uint8_t>( 57010f4959aSEmily Shaffer (raw_value - sensor.scaledOffset) / sensor.coefficientM); 571bbef71c2SEmily Shaffer resp->operation = 1<<6; // scanning enabled 572bbef71c2SEmily Shaffer resp->indication[0] = 0; // not a threshold sensor. ignore 5731fabf229SEmily Shaffer resp->indication[1] = 0; 5741fabf229SEmily Shaffer rc = IPMI_CC_OK; 5751fabf229SEmily Shaffer *data_len=sizeof(sensorreadingresp_t); 5761fabf229SEmily Shaffer break; 5771fabf229SEmily Shaffer 57898a23840SMatthew Barth default: 57998a23840SMatthew Barth *data_len=0; 58098a23840SMatthew Barth rc = IPMI_CC_SENSOR_INVALID; 58198a23840SMatthew Barth break; 58298a23840SMatthew Barth } 58398a23840SMatthew Barth 58498a23840SMatthew Barth 58598a23840SMatthew Barth reply = sd_bus_message_unref(reply); 58698a23840SMatthew Barth 58798a23840SMatthew Barth return rc; 58898a23840SMatthew Barth } 58998a23840SMatthew Barth 59098a23840SMatthew Barth ipmi_ret_t ipmi_sen_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 59198a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 59298a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 59398a23840SMatthew Barth { 59470aa8d96SNan Li ipmi_ret_t rc = IPMI_CC_INVALID; 59598a23840SMatthew Barth 59698a23840SMatthew Barth printf("IPMI S/E Wildcard Netfn:[0x%X], Cmd:[0x%X]\n",netfn,cmd); 59798a23840SMatthew Barth *data_len = 0; 59898a23840SMatthew Barth 59998a23840SMatthew Barth return rc; 60098a23840SMatthew Barth } 60198a23840SMatthew Barth 602d06e0e7eSEmily Shaffer ipmi_ret_t ipmi_sen_get_sdr_info(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 603d06e0e7eSEmily Shaffer ipmi_request_t request, 604d06e0e7eSEmily Shaffer ipmi_response_t response, 605d06e0e7eSEmily Shaffer ipmi_data_len_t data_len, 606d06e0e7eSEmily Shaffer ipmi_context_t context) 607d06e0e7eSEmily Shaffer { 608d06e0e7eSEmily Shaffer auto resp = static_cast<get_sdr_info::GetSdrInfoResp*>(response); 609d06e0e7eSEmily Shaffer if (request == nullptr || 610d06e0e7eSEmily Shaffer get_sdr_info::request::get_count(request) == false) 611d06e0e7eSEmily Shaffer { 612d06e0e7eSEmily Shaffer // Get Sensor Count 613d06e0e7eSEmily Shaffer resp->count = sensors.size(); 614d06e0e7eSEmily Shaffer } 615d06e0e7eSEmily Shaffer else 616d06e0e7eSEmily Shaffer { 617d06e0e7eSEmily Shaffer resp->count = 1; 618d06e0e7eSEmily Shaffer } 619d06e0e7eSEmily Shaffer 620d06e0e7eSEmily Shaffer // Multiple LUNs not supported. 621d06e0e7eSEmily Shaffer namespace response = get_sdr_info::response; 622d06e0e7eSEmily Shaffer response::set_lun_present(0, &(resp->luns_and_dynamic_population)); 623d06e0e7eSEmily Shaffer response::set_lun_not_present(1, &(resp->luns_and_dynamic_population)); 624d06e0e7eSEmily Shaffer response::set_lun_not_present(2, &(resp->luns_and_dynamic_population)); 625d06e0e7eSEmily Shaffer response::set_lun_not_present(3, &(resp->luns_and_dynamic_population)); 626d06e0e7eSEmily Shaffer response::set_static_population(&(resp->luns_and_dynamic_population)); 627d06e0e7eSEmily Shaffer 628d06e0e7eSEmily Shaffer *data_len = SDR_INFO_RESP_SIZE; 629d06e0e7eSEmily Shaffer 630d06e0e7eSEmily Shaffer return IPMI_CC_OK; 631d06e0e7eSEmily Shaffer } 632d06e0e7eSEmily Shaffer 633a344afc0SEmily Shaffer ipmi_ret_t ipmi_sen_reserve_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 634a344afc0SEmily Shaffer ipmi_request_t request, 635a344afc0SEmily Shaffer ipmi_response_t response, 636a344afc0SEmily Shaffer ipmi_data_len_t data_len, 637a344afc0SEmily Shaffer ipmi_context_t context) 638a344afc0SEmily Shaffer { 639a344afc0SEmily Shaffer // A constant reservation ID is okay until we implement add/remove SDR. 640a344afc0SEmily Shaffer const uint16_t reservation_id = 1; 641a344afc0SEmily Shaffer *(uint16_t*)response = reservation_id; 642a344afc0SEmily Shaffer 643a344afc0SEmily Shaffer printf("Created new IPMI SDR reservation ID %d\n", *(uint16_t*)response); 644a344afc0SEmily Shaffer return IPMI_CC_OK; 645a344afc0SEmily Shaffer } 64698a23840SMatthew Barth 647bbef71c2SEmily Shaffer ipmi_ret_t populate_record_from_dbus(get_sdr::SensorDataFullRecordBody *body, 648bbef71c2SEmily Shaffer const ipmi::sensor::Info *info, 649bbef71c2SEmily Shaffer ipmi_data_len_t data_len) 650bbef71c2SEmily Shaffer { 651bbef71c2SEmily Shaffer /* Functional sensor case */ 652bbef71c2SEmily Shaffer if (info->sensorInterfaces.begin()->first == 653bbef71c2SEmily Shaffer "xyz.openbmc_project.Sensor.Value") 654bbef71c2SEmily Shaffer { 655bbef71c2SEmily Shaffer // Get bus 656bbef71c2SEmily Shaffer sd_bus *bus = ipmid_get_sd_bus_connection(); 657bbef71c2SEmily Shaffer dbus_interface_t iface; 658bbef71c2SEmily Shaffer 659bbef71c2SEmily Shaffer if (0 > find_openbmc_path(body->entity_id, &iface)) 660bbef71c2SEmily Shaffer return IPMI_CC_SENSOR_INVALID; 661bbef71c2SEmily Shaffer 662bbef71c2SEmily Shaffer body->sensor_units_1 = 0; // unsigned, no rate, no modifier, not a % 663bbef71c2SEmily Shaffer 664bbef71c2SEmily Shaffer /* Unit info */ 665bbef71c2SEmily Shaffer char *raw_cstr; 666bbef71c2SEmily Shaffer if (0 > sd_bus_get_property_string(bus, iface.bus, iface.path, 667bbef71c2SEmily Shaffer iface.interface, "Unit", NULL, 668bbef71c2SEmily Shaffer &raw_cstr)) { 669bbef71c2SEmily Shaffer fprintf(stderr, "Expected to find Unit interface in bus %s, path %s, but it was missing.\n", 670bbef71c2SEmily Shaffer iface.bus, iface.path); 671bbef71c2SEmily Shaffer return IPMI_CC_SENSOR_INVALID; 672bbef71c2SEmily Shaffer } 673bbef71c2SEmily Shaffer 674bbef71c2SEmily Shaffer std::string raw_str(raw_cstr); 675bbef71c2SEmily Shaffer namespace server = sdbusplus::xyz::openbmc_project::Sensor::server; 676bbef71c2SEmily Shaffer server::Value::Unit unit = 677bbef71c2SEmily Shaffer server::Value::convertUnitFromString(raw_str); 678bbef71c2SEmily Shaffer 679bbef71c2SEmily Shaffer // Unit strings defined in 680bbef71c2SEmily Shaffer // phosphor-dbus-interfaces/xyz/openbmc_project/Sensor/Value.interface.yaml 681bbef71c2SEmily Shaffer switch (unit) 682bbef71c2SEmily Shaffer { 683bbef71c2SEmily Shaffer case server::Value::Unit::DegreesC: 684bbef71c2SEmily Shaffer body->sensor_units_2_base = get_sdr::SENSOR_UNIT_DEGREES_C; 685bbef71c2SEmily Shaffer break; 686bbef71c2SEmily Shaffer case server::Value::Unit::RPMS: 687bbef71c2SEmily Shaffer body->sensor_units_2_base = get_sdr::SENSOR_UNIT_REVOLUTIONS; // revolutions 688bbef71c2SEmily Shaffer get_sdr::body::set_rate_unit(0b100, body); // per minute 689bbef71c2SEmily Shaffer break; 690bbef71c2SEmily Shaffer case server::Value::Unit::Volts: 691bbef71c2SEmily Shaffer body->sensor_units_2_base = get_sdr::SENSOR_UNIT_VOLTS; 692bbef71c2SEmily Shaffer break; 693bbef71c2SEmily Shaffer case server::Value::Unit::Meters: 694bbef71c2SEmily Shaffer body->sensor_units_2_base = get_sdr::SENSOR_UNIT_METERS; 695bbef71c2SEmily Shaffer break; 696bbef71c2SEmily Shaffer case server::Value::Unit::Amperes: 697bbef71c2SEmily Shaffer body->sensor_units_2_base = get_sdr::SENSOR_UNIT_AMPERES; 698bbef71c2SEmily Shaffer break; 699bbef71c2SEmily Shaffer case server::Value::Unit::Joules: 700bbef71c2SEmily Shaffer body->sensor_units_2_base = get_sdr::SENSOR_UNIT_JOULES; 701bbef71c2SEmily Shaffer break; 702bbef71c2SEmily Shaffer default: 703bbef71c2SEmily Shaffer fprintf(stderr, "Unknown value unit type: = %s\n", raw_cstr); 704bbef71c2SEmily Shaffer } 705bbef71c2SEmily Shaffer 706bbef71c2SEmily Shaffer free(raw_cstr); 707bbef71c2SEmily Shaffer 708bbef71c2SEmily Shaffer /* Modifiers to reading info */ 70910f4959aSEmily Shaffer // Get scale 71010f4959aSEmily Shaffer int64_t scale; 71110f4959aSEmily Shaffer if (0 > sd_bus_get_property_trivial(bus, 71210f4959aSEmily Shaffer iface.bus, 71310f4959aSEmily Shaffer iface.path, 71410f4959aSEmily Shaffer iface.interface, 71510f4959aSEmily Shaffer "Scale", 71610f4959aSEmily Shaffer NULL, 71710f4959aSEmily Shaffer 'x', 71810f4959aSEmily Shaffer &scale)) { 71910f4959aSEmily Shaffer fprintf(stderr, "Expected to find Scale interface in bus %s, path %s, but it was missing.\n", 72010f4959aSEmily Shaffer iface.bus, iface.path); 72110f4959aSEmily Shaffer return IPMI_CC_SENSOR_INVALID; 72210f4959aSEmily Shaffer } 72310f4959aSEmily Shaffer 72410f4959aSEmily Shaffer get_sdr::body::set_b(info->coefficientB, body); 72510f4959aSEmily Shaffer get_sdr::body::set_m(info->coefficientM, body); 72610f4959aSEmily Shaffer get_sdr::body::set_b_exp(info->exponentB, body); 72710f4959aSEmily Shaffer get_sdr::body::set_r_exp(scale, body); 728bbef71c2SEmily Shaffer 729bbef71c2SEmily Shaffer /* ID string */ 730bbef71c2SEmily Shaffer std::string id_string = info->sensorPath.substr( 731bbef71c2SEmily Shaffer info->sensorPath.find_last_of('/')+1, info->sensorPath.length()); 732bbef71c2SEmily Shaffer get_sdr::body::set_id_type(0b00, body); // 00 = unicode 733bbef71c2SEmily Shaffer if (id_string.length() > FULL_RECORD_ID_STR_MAX_LENGTH) 734bbef71c2SEmily Shaffer { 735bbef71c2SEmily Shaffer get_sdr::body::set_id_strlen(FULL_RECORD_ID_STR_MAX_LENGTH, body); 736bbef71c2SEmily Shaffer } 737bbef71c2SEmily Shaffer else 738bbef71c2SEmily Shaffer { 739bbef71c2SEmily Shaffer get_sdr::body::set_id_strlen(id_string.length(), body); 740bbef71c2SEmily Shaffer } 741bbef71c2SEmily Shaffer strncpy(body->id_string, id_string.c_str(), 742bbef71c2SEmily Shaffer get_sdr::body::get_id_strlen(body)); 743bbef71c2SEmily Shaffer } 744bbef71c2SEmily Shaffer 745bbef71c2SEmily Shaffer return IPMI_CC_OK; 746bbef71c2SEmily Shaffer }; 747bbef71c2SEmily Shaffer 748bbef71c2SEmily Shaffer ipmi_ret_t ipmi_sen_get_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 749bbef71c2SEmily Shaffer ipmi_request_t request, ipmi_response_t response, 750bbef71c2SEmily Shaffer ipmi_data_len_t data_len, ipmi_context_t context) 751bbef71c2SEmily Shaffer { 752bbef71c2SEmily Shaffer ipmi_ret_t ret = IPMI_CC_OK; 753bbef71c2SEmily Shaffer get_sdr::GetSdrReq *req = (get_sdr::GetSdrReq*)request; 754bbef71c2SEmily Shaffer get_sdr::GetSdrResp *resp = (get_sdr::GetSdrResp*)response; 755bbef71c2SEmily Shaffer get_sdr::SensorDataFullRecord record = {0}; 756bbef71c2SEmily Shaffer if (req != NULL) 757bbef71c2SEmily Shaffer { 758bbef71c2SEmily Shaffer // Note: we use an iterator so we can provide the next ID at the end of 759bbef71c2SEmily Shaffer // the call. 760bbef71c2SEmily Shaffer auto sensor = sensors.begin(); 761bbef71c2SEmily Shaffer 762bbef71c2SEmily Shaffer // At the beginning of a scan, the host side will send us id=0. 763bbef71c2SEmily Shaffer if (get_sdr::request::get_record_id(req) != 0) 764bbef71c2SEmily Shaffer { 765bbef71c2SEmily Shaffer sensor = sensors.find(get_sdr::request::get_record_id(req)); 766bbef71c2SEmily Shaffer if(sensor == sensors.end()) { 767bbef71c2SEmily Shaffer return IPMI_CC_SENSOR_INVALID; 768bbef71c2SEmily Shaffer } 769bbef71c2SEmily Shaffer } 770bbef71c2SEmily Shaffer 771bbef71c2SEmily Shaffer uint8_t sensor_id = sensor->first; 772bbef71c2SEmily Shaffer 773bbef71c2SEmily Shaffer /* Header */ 774bbef71c2SEmily Shaffer get_sdr::header::set_record_id(sensor_id, &(record.header)); 775bbef71c2SEmily Shaffer record.header.sdr_version = 0x51; // Based on IPMI Spec v2.0 rev 1.1 776bbef71c2SEmily Shaffer record.header.record_type = get_sdr::SENSOR_DATA_FULL_RECORD; 777bbef71c2SEmily Shaffer record.header.record_length = sizeof(get_sdr::SensorDataFullRecord); 778bbef71c2SEmily Shaffer 779bbef71c2SEmily Shaffer /* Key */ 780bbef71c2SEmily Shaffer record.key.sensor_number = sensor_id; 781bbef71c2SEmily Shaffer 782bbef71c2SEmily Shaffer /* Body */ 783bbef71c2SEmily Shaffer record.body.entity_id = sensor_id; 784bbef71c2SEmily Shaffer record.body.sensor_type = sensor->second.sensorType; 785bbef71c2SEmily Shaffer record.body.event_reading_type = sensor->second.sensorReadingType; 786bbef71c2SEmily Shaffer 787bbef71c2SEmily Shaffer // Set the type-specific details given the DBus interface 788bbef71c2SEmily Shaffer ret = populate_record_from_dbus(&(record.body), &(sensor->second), 789bbef71c2SEmily Shaffer data_len); 790bbef71c2SEmily Shaffer 791bbef71c2SEmily Shaffer if (++sensor == sensors.end()) 792bbef71c2SEmily Shaffer { 793bbef71c2SEmily Shaffer get_sdr::response::set_next_record_id(0xFFFF, resp); // last record 794bbef71c2SEmily Shaffer } 795bbef71c2SEmily Shaffer else 796bbef71c2SEmily Shaffer { 797bbef71c2SEmily Shaffer get_sdr::response::set_next_record_id(sensor->first, resp); 798bbef71c2SEmily Shaffer } 799bbef71c2SEmily Shaffer 800bbef71c2SEmily Shaffer *data_len = sizeof(get_sdr::GetSdrResp) - req->offset; 801bbef71c2SEmily Shaffer memcpy(resp->record_data, (char*)&record + req->offset, 802bbef71c2SEmily Shaffer sizeof(get_sdr::SensorDataFullRecord) - req->offset); 803bbef71c2SEmily Shaffer } 804bbef71c2SEmily Shaffer 805bbef71c2SEmily Shaffer return ret; 806bbef71c2SEmily Shaffer } 807bbef71c2SEmily Shaffer 808bbef71c2SEmily Shaffer 80998a23840SMatthew Barth void register_netfn_sen_functions() 81098a23840SMatthew Barth { 8110573237fSTom // <Wildcard Command> 812a344afc0SEmily Shaffer printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", 813a344afc0SEmily Shaffer NETFUN_SENSOR, IPMI_CMD_WILDCARD); 814a344afc0SEmily Shaffer ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_WILDCARD, 815a344afc0SEmily Shaffer nullptr, ipmi_sen_wildcard, 8160573237fSTom PRIVILEGE_USER); 81798a23840SMatthew Barth 8180573237fSTom // <Get Sensor Type> 819a344afc0SEmily Shaffer printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", 820a344afc0SEmily Shaffer NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE); 821a344afc0SEmily Shaffer ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE, 822a344afc0SEmily Shaffer nullptr, ipmi_sen_get_sensor_type, 8230573237fSTom PRIVILEGE_USER); 82498a23840SMatthew Barth 8250573237fSTom // <Set Sensor Reading and Event Status> 826a344afc0SEmily Shaffer printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", 827a344afc0SEmily Shaffer NETFUN_SENSOR, IPMI_CMD_SET_SENSOR); 828a344afc0SEmily Shaffer ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_SET_SENSOR, 829a344afc0SEmily Shaffer nullptr, ipmi_sen_set_sensor, 8300573237fSTom PRIVILEGE_OPERATOR); 83198a23840SMatthew Barth 8320573237fSTom // <Get Sensor Reading> 833a344afc0SEmily Shaffer printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", 834a344afc0SEmily Shaffer NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_READING); 835a344afc0SEmily Shaffer ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_READING, 836a344afc0SEmily Shaffer nullptr, ipmi_sen_get_sensor_reading, 837a344afc0SEmily Shaffer PRIVILEGE_USER); 838a344afc0SEmily Shaffer 839a344afc0SEmily Shaffer // <Reserve SDR> 840a344afc0SEmily Shaffer printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", 841a344afc0SEmily Shaffer NETFUN_SENSOR, IPMI_CMD_RESERVE_SDR_REPO); 842a344afc0SEmily Shaffer ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_RESERVE_SDR_REPO, 843a344afc0SEmily Shaffer nullptr, ipmi_sen_reserve_sdr, 844a344afc0SEmily Shaffer PRIVILEGE_USER); 84598a23840SMatthew Barth 846d06e0e7eSEmily Shaffer // <Get SDR Info> 847a344afc0SEmily Shaffer printf("Registering NetFn:[0x%X], Cmd:[0x%x]\n", 848a344afc0SEmily Shaffer NETFUN_SENSOR, IPMI_CMD_GET_SDR_INFO); 849a344afc0SEmily Shaffer ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SDR_INFO, 850a344afc0SEmily Shaffer nullptr, ipmi_sen_get_sdr_info, 851a344afc0SEmily Shaffer PRIVILEGE_USER); 852bbef71c2SEmily Shaffer 853bbef71c2SEmily Shaffer // <Get SDR> 854bbef71c2SEmily Shaffer printf("Registering NetFn:[0x%X], Cmd:[0x%x]\n", 855bbef71c2SEmily Shaffer NETFUN_SENSOR, IPMI_CMD_GET_SDR); 856bbef71c2SEmily Shaffer ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SDR, 857bbef71c2SEmily Shaffer nullptr, ipmi_sen_get_sdr, 858bbef71c2SEmily Shaffer PRIVILEGE_USER); 859bbef71c2SEmily Shaffer 86098a23840SMatthew Barth return; 86198a23840SMatthew Barth } 862