198a23840SMatthew Barth #include "sensorhandler.h" 2*37af7331SPatrick Williams #include "host-ipmid/ipmid-api.h" 398a23840SMatthew Barth #include <stdio.h> 498a23840SMatthew Barth #include <string.h> 598a23840SMatthew Barth #include <stdint.h> 698a23840SMatthew Barth #include <systemd/sd-bus.h> 798a23840SMatthew Barth 898a23840SMatthew Barth extern int updateSensorRecordFromSSRAESC(const void *); 998a23840SMatthew Barth extern int find_interface_property_fru_type(dbus_interface_t *interface, const char *property_name, char *property_value) ; 1098a23840SMatthew Barth extern int find_openbmc_path(const char *type, const uint8_t num, dbus_interface_t *interface) ; 1198a23840SMatthew Barth 1298a23840SMatthew Barth void register_netfn_sen_functions() __attribute__((constructor)); 1398a23840SMatthew Barth 1498a23840SMatthew Barth struct sensorTypemap_t { 1598a23840SMatthew Barth uint8_t number; 1698a23840SMatthew Barth uint8_t typecode; 1798a23840SMatthew Barth char dbusname[32]; 1898a23840SMatthew Barth } ; 1998a23840SMatthew Barth 2098a23840SMatthew Barth 2198a23840SMatthew Barth sensorTypemap_t g_SensorTypeMap[] = { 2298a23840SMatthew Barth 2398a23840SMatthew Barth {0x01, 0x6F, "Temp"}, 2498a23840SMatthew Barth {0x0C, 0x6F, "DIMM"}, 2598a23840SMatthew Barth {0x0C, 0x6F, "MEMORY_BUFFER"}, 2698a23840SMatthew Barth {0x07, 0x6F, "PROC"}, 2798a23840SMatthew Barth {0x07, 0x6F, "CORE"}, 2898a23840SMatthew Barth {0x07, 0x6F, "CPU"}, 2998a23840SMatthew Barth {0x0F, 0x6F, "BootProgress"}, 3098a23840SMatthew Barth {0xe9, 0x09, "OccStatus"}, // E9 is an internal mapping to handle sensor type code os 0x09 3198a23840SMatthew Barth {0xC3, 0x6F, "BootCount"}, 3298a23840SMatthew Barth {0x1F, 0x6F, "OperatingSystemStatus"}, 3398a23840SMatthew Barth {0x12, 0x6F, "SYSTEM_EVENT"}, 3498a23840SMatthew Barth {0xC7, 0x03, "SYSTEM"}, 3598a23840SMatthew Barth {0xC7, 0x03, "MAIN_PLANAR"}, 3698a23840SMatthew Barth {0xC2, 0x6F, "PowerCap"}, 3798a23840SMatthew Barth {0xFF, 0x00, ""}, 3898a23840SMatthew Barth }; 3998a23840SMatthew Barth 4098a23840SMatthew Barth 4198a23840SMatthew Barth struct sensor_data_t { 4298a23840SMatthew Barth uint8_t sennum; 4398a23840SMatthew Barth } __attribute__ ((packed)) ; 4498a23840SMatthew Barth 4598a23840SMatthew Barth struct sensorreadingresp_t { 4698a23840SMatthew Barth uint8_t value; 4798a23840SMatthew Barth uint8_t operation; 4898a23840SMatthew Barth uint8_t indication[2]; 4998a23840SMatthew Barth } __attribute__ ((packed)) ; 5098a23840SMatthew Barth 5198a23840SMatthew Barth uint8_t dbus_to_sensor_type(char *p) { 5298a23840SMatthew Barth 5398a23840SMatthew Barth sensorTypemap_t *s = g_SensorTypeMap; 5498a23840SMatthew Barth char r=0; 5598a23840SMatthew Barth 5698a23840SMatthew Barth while (s->number != 0xFF) { 5798a23840SMatthew Barth if (!strcmp(s->dbusname,p)) { 5898a23840SMatthew Barth r = s->number; 5998a23840SMatthew Barth break; 6098a23840SMatthew Barth } 6198a23840SMatthew Barth s++; 6298a23840SMatthew Barth } 6398a23840SMatthew Barth 6498a23840SMatthew Barth 6598a23840SMatthew Barth if (s->number == 0xFF) 6698a23840SMatthew Barth printf("Failed to find Sensor Type %s\n", p); 6798a23840SMatthew Barth 6898a23840SMatthew Barth return r; 6998a23840SMatthew Barth } 7098a23840SMatthew Barth 7198a23840SMatthew Barth 7298a23840SMatthew Barth uint8_t dbus_to_sensor_type_from_dbus(dbus_interface_t *a) { 7398a23840SMatthew Barth char fru_type_name[64]; 7498a23840SMatthew Barth int r= 0; 7598a23840SMatthew Barth 7698a23840SMatthew Barth r = find_interface_property_fru_type(a, "fru_type", fru_type_name); 7798a23840SMatthew Barth if (r<0) { 7898a23840SMatthew Barth fprintf(stderr, "Failed to get a fru type: %s", strerror(-r)); 7998a23840SMatthew Barth return -1; 8098a23840SMatthew Barth } else { 8198a23840SMatthew Barth return dbus_to_sensor_type(fru_type_name); 8298a23840SMatthew Barth } 8398a23840SMatthew Barth } 8498a23840SMatthew Barth 8598a23840SMatthew Barth 8698a23840SMatthew Barth uint8_t find_sensor(uint8_t sensor_number) { 8798a23840SMatthew Barth 8898a23840SMatthew Barth dbus_interface_t a; 8998a23840SMatthew Barth char *p; 9098a23840SMatthew Barth char r; 9198a23840SMatthew Barth 9298a23840SMatthew Barth r = find_openbmc_path("SENSOR", sensor_number, &a); 9398a23840SMatthew Barth 9498a23840SMatthew Barth if (r < 0) { return 0; } 9598a23840SMatthew Barth 9698a23840SMatthew Barth // This is where sensors that do not exist in dbus but do 9798a23840SMatthew Barth // exist in the host code stop. This should indicate it 9898a23840SMatthew Barth // is not a supported sensor 9998a23840SMatthew Barth if (a.interface[0] == 0) { return 0;} 10098a23840SMatthew Barth 10198a23840SMatthew Barth if (strstr(a.interface, "InventoryItem")) { 10298a23840SMatthew Barth // InventoryItems are real frus. So need to get the 10398a23840SMatthew Barth // fru_type property 10498a23840SMatthew Barth r = dbus_to_sensor_type_from_dbus(&a); 10598a23840SMatthew Barth } else { 10698a23840SMatthew Barth // Non InventoryItems 10798a23840SMatthew Barth p = strrchr (a.path, '/'); 10898a23840SMatthew Barth r = dbus_to_sensor_type(p+1); 10998a23840SMatthew Barth } 11098a23840SMatthew Barth 11198a23840SMatthew Barth return r; 11298a23840SMatthew Barth } 11398a23840SMatthew Barth 11498a23840SMatthew Barth 11598a23840SMatthew Barth 11698a23840SMatthew Barth 11798a23840SMatthew Barth 11898a23840SMatthew Barth ipmi_ret_t ipmi_sen_get_sensor_type(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 11998a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 12098a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 12198a23840SMatthew Barth { 12298a23840SMatthew Barth sensor_data_t *reqptr = (sensor_data_t*)request; 12398a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_OK; 12498a23840SMatthew Barth 12598a23840SMatthew Barth printf("IPMI GET_SENSOR_TYPE [0x%02X]\n",reqptr->sennum); 12698a23840SMatthew Barth 12798a23840SMatthew Barth // TODO Not sure what the System-event-sensor is suppose to return 12898a23840SMatthew Barth // need to ask Hostboot team 12998a23840SMatthew Barth unsigned char buf[] = {0x00,0x6F}; 13098a23840SMatthew Barth 13198a23840SMatthew Barth buf[0] = find_sensor(reqptr->sennum); 13298a23840SMatthew Barth 13398a23840SMatthew Barth // HACK UNTIL Dbus gets updated or we find a better way 13498a23840SMatthew Barth if (buf[0] == 0) { 13598a23840SMatthew Barth rc = IPMI_CC_SENSOR_INVALID; 13698a23840SMatthew Barth } 13798a23840SMatthew Barth 13898a23840SMatthew Barth 13998a23840SMatthew Barth *data_len = sizeof(buf); 14098a23840SMatthew Barth memcpy(response, &buf, *data_len); 14198a23840SMatthew Barth 14298a23840SMatthew Barth return rc; 14398a23840SMatthew Barth } 14498a23840SMatthew Barth 14598a23840SMatthew Barth 14698a23840SMatthew Barth 14798a23840SMatthew Barth ipmi_ret_t ipmi_sen_set_sensor(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 14898a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 14998a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 15098a23840SMatthew Barth { 15198a23840SMatthew Barth sensor_data_t *reqptr = (sensor_data_t*)request; 15298a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_OK; 15398a23840SMatthew Barth 15498a23840SMatthew Barth printf("IPMI SET_SENSOR [0x%02x]\n",reqptr->sennum); 15598a23840SMatthew Barth 15698a23840SMatthew Barth updateSensorRecordFromSSRAESC(reqptr); 15798a23840SMatthew Barth 15898a23840SMatthew Barth *data_len=0; 15998a23840SMatthew Barth 16098a23840SMatthew Barth return rc; 16198a23840SMatthew Barth } 16298a23840SMatthew Barth 16398a23840SMatthew Barth 16498a23840SMatthew Barth ipmi_ret_t ipmi_sen_get_sensor_reading(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 16598a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 16698a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 16798a23840SMatthew Barth { 16898a23840SMatthew Barth sensor_data_t *reqptr = (sensor_data_t*)request; 16998a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_SENSOR_INVALID; 17098a23840SMatthew Barth uint8_t type; 17198a23840SMatthew Barth sensorreadingresp_t *resp = (sensorreadingresp_t*) response; 17298a23840SMatthew Barth int r; 17398a23840SMatthew Barth dbus_interface_t a; 17498a23840SMatthew Barth sd_bus *bus = ipmid_get_sd_bus_connection(); 17598a23840SMatthew Barth sd_bus_message *reply = NULL; 17698a23840SMatthew Barth int reading = 0; 17798a23840SMatthew Barth 17898a23840SMatthew Barth 17998a23840SMatthew Barth printf("IPMI GET_SENSOR_READING [0x%02x]\n",reqptr->sennum); 18098a23840SMatthew Barth 18198a23840SMatthew Barth r = find_openbmc_path("SENSOR", reqptr->sennum, &a); 18298a23840SMatthew Barth 18398a23840SMatthew Barth if (r < 0) { 18498a23840SMatthew Barth fprintf(stderr, "Failed to find Sensor 0x%02x\n", reqptr->sennum); 18598a23840SMatthew Barth return IPMI_CC_SENSOR_INVALID; 18698a23840SMatthew Barth } 18798a23840SMatthew Barth 18898a23840SMatthew Barth type = find_sensor(reqptr->sennum); 18998a23840SMatthew Barth 19098a23840SMatthew Barth fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n", a.bus, a.path, a.interface); 19198a23840SMatthew Barth 19298a23840SMatthew Barth *data_len=0; 19398a23840SMatthew Barth 19498a23840SMatthew Barth switch(type) { 19598a23840SMatthew Barth case 0xC3: 19698a23840SMatthew Barth case 0xC2: 19798a23840SMatthew Barth r = sd_bus_get_property(bus,a.bus, a.path, a.interface, "value", NULL, &reply, "i"); 19898a23840SMatthew Barth if (r < 0) { 19998a23840SMatthew Barth fprintf(stderr, "Failed to call sd_bus_get_property:%d, %s\n", r, strerror(-r)); 20098a23840SMatthew Barth fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n", 20198a23840SMatthew Barth a.bus, a.path, a.interface); 20298a23840SMatthew Barth break; 20398a23840SMatthew Barth } 20498a23840SMatthew Barth 20598a23840SMatthew Barth r = sd_bus_message_read(reply, "i", &reading); 20698a23840SMatthew Barth if (r < 0) { 20798a23840SMatthew Barth fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r)); 20898a23840SMatthew Barth break; 20998a23840SMatthew Barth } 21098a23840SMatthew Barth 21198a23840SMatthew Barth printf("Contents of a 0x%02x is 0x%02x\n", type, reading); 21298a23840SMatthew Barth 21398a23840SMatthew Barth rc = IPMI_CC_OK; 21498a23840SMatthew Barth *data_len=sizeof(sensorreadingresp_t); 21598a23840SMatthew Barth 21698a23840SMatthew Barth resp->value = (uint8_t)reading; 21798a23840SMatthew Barth resp->operation = 0; 21898a23840SMatthew Barth resp->indication[0] = 0; 21998a23840SMatthew Barth resp->indication[1] = 0; 22098a23840SMatthew Barth break; 22198a23840SMatthew Barth 22298a23840SMatthew Barth default: 22398a23840SMatthew Barth *data_len=0; 22498a23840SMatthew Barth rc = IPMI_CC_SENSOR_INVALID; 22598a23840SMatthew Barth break; 22698a23840SMatthew Barth } 22798a23840SMatthew Barth 22898a23840SMatthew Barth 22998a23840SMatthew Barth reply = sd_bus_message_unref(reply); 23098a23840SMatthew Barth 23198a23840SMatthew Barth return rc; 23298a23840SMatthew Barth } 23398a23840SMatthew Barth 23498a23840SMatthew Barth ipmi_ret_t ipmi_sen_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 23598a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 23698a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 23798a23840SMatthew Barth { 23898a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_OK; 23998a23840SMatthew Barth 24098a23840SMatthew Barth printf("IPMI S/E Wildcard Netfn:[0x%X], Cmd:[0x%X]\n",netfn,cmd); 24198a23840SMatthew Barth *data_len = 0; 24298a23840SMatthew Barth 24398a23840SMatthew Barth return rc; 24498a23840SMatthew Barth } 24598a23840SMatthew Barth 24698a23840SMatthew Barth 24798a23840SMatthew Barth void register_netfn_sen_functions() 24898a23840SMatthew Barth { 24998a23840SMatthew Barth printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_WILDCARD); 25098a23840SMatthew Barth ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_WILDCARD, NULL, ipmi_sen_wildcard); 25198a23840SMatthew Barth 25298a23840SMatthew Barth printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE); 25398a23840SMatthew Barth ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE, NULL, ipmi_sen_get_sensor_type); 25498a23840SMatthew Barth 25598a23840SMatthew Barth printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_SET_SENSOR); 25698a23840SMatthew Barth ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_SET_SENSOR, NULL, ipmi_sen_set_sensor); 25798a23840SMatthew Barth 25898a23840SMatthew Barth printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_READING); 25998a23840SMatthew Barth ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_READING, NULL, ipmi_sen_get_sensor_reading); 26098a23840SMatthew Barth 26198a23840SMatthew Barth return; 26298a23840SMatthew Barth } 263