1*98a23840SMatthew Barth #include "sensorhandler.h" 2*98a23840SMatthew Barth #include "ipmid-api.h" 3*98a23840SMatthew Barth #include <stdio.h> 4*98a23840SMatthew Barth #include <string.h> 5*98a23840SMatthew Barth #include <stdint.h> 6*98a23840SMatthew Barth #include <systemd/sd-bus.h> 7*98a23840SMatthew Barth 8*98a23840SMatthew Barth extern int updateSensorRecordFromSSRAESC(const void *); 9*98a23840SMatthew Barth extern int find_interface_property_fru_type(dbus_interface_t *interface, const char *property_name, char *property_value) ; 10*98a23840SMatthew Barth extern int find_openbmc_path(const char *type, const uint8_t num, dbus_interface_t *interface) ; 11*98a23840SMatthew Barth 12*98a23840SMatthew Barth void register_netfn_sen_functions() __attribute__((constructor)); 13*98a23840SMatthew Barth 14*98a23840SMatthew Barth struct sensorTypemap_t { 15*98a23840SMatthew Barth uint8_t number; 16*98a23840SMatthew Barth uint8_t typecode; 17*98a23840SMatthew Barth char dbusname[32]; 18*98a23840SMatthew Barth } ; 19*98a23840SMatthew Barth 20*98a23840SMatthew Barth 21*98a23840SMatthew Barth sensorTypemap_t g_SensorTypeMap[] = { 22*98a23840SMatthew Barth 23*98a23840SMatthew Barth {0x01, 0x6F, "Temp"}, 24*98a23840SMatthew Barth {0x0C, 0x6F, "DIMM"}, 25*98a23840SMatthew Barth {0x0C, 0x6F, "MEMORY_BUFFER"}, 26*98a23840SMatthew Barth {0x07, 0x6F, "PROC"}, 27*98a23840SMatthew Barth {0x07, 0x6F, "CORE"}, 28*98a23840SMatthew Barth {0x07, 0x6F, "CPU"}, 29*98a23840SMatthew Barth {0x0F, 0x6F, "BootProgress"}, 30*98a23840SMatthew Barth {0xe9, 0x09, "OccStatus"}, // E9 is an internal mapping to handle sensor type code os 0x09 31*98a23840SMatthew Barth {0xC3, 0x6F, "BootCount"}, 32*98a23840SMatthew Barth {0x1F, 0x6F, "OperatingSystemStatus"}, 33*98a23840SMatthew Barth {0x12, 0x6F, "SYSTEM_EVENT"}, 34*98a23840SMatthew Barth {0xC7, 0x03, "SYSTEM"}, 35*98a23840SMatthew Barth {0xC7, 0x03, "MAIN_PLANAR"}, 36*98a23840SMatthew Barth {0xC2, 0x6F, "PowerCap"}, 37*98a23840SMatthew Barth {0xFF, 0x00, ""}, 38*98a23840SMatthew Barth }; 39*98a23840SMatthew Barth 40*98a23840SMatthew Barth 41*98a23840SMatthew Barth struct sensor_data_t { 42*98a23840SMatthew Barth uint8_t sennum; 43*98a23840SMatthew Barth } __attribute__ ((packed)) ; 44*98a23840SMatthew Barth 45*98a23840SMatthew Barth struct sensorreadingresp_t { 46*98a23840SMatthew Barth uint8_t value; 47*98a23840SMatthew Barth uint8_t operation; 48*98a23840SMatthew Barth uint8_t indication[2]; 49*98a23840SMatthew Barth } __attribute__ ((packed)) ; 50*98a23840SMatthew Barth 51*98a23840SMatthew Barth uint8_t dbus_to_sensor_type(char *p) { 52*98a23840SMatthew Barth 53*98a23840SMatthew Barth sensorTypemap_t *s = g_SensorTypeMap; 54*98a23840SMatthew Barth char r=0; 55*98a23840SMatthew Barth 56*98a23840SMatthew Barth while (s->number != 0xFF) { 57*98a23840SMatthew Barth if (!strcmp(s->dbusname,p)) { 58*98a23840SMatthew Barth r = s->number; 59*98a23840SMatthew Barth break; 60*98a23840SMatthew Barth } 61*98a23840SMatthew Barth s++; 62*98a23840SMatthew Barth } 63*98a23840SMatthew Barth 64*98a23840SMatthew Barth 65*98a23840SMatthew Barth if (s->number == 0xFF) 66*98a23840SMatthew Barth printf("Failed to find Sensor Type %s\n", p); 67*98a23840SMatthew Barth 68*98a23840SMatthew Barth return r; 69*98a23840SMatthew Barth } 70*98a23840SMatthew Barth 71*98a23840SMatthew Barth 72*98a23840SMatthew Barth uint8_t dbus_to_sensor_type_from_dbus(dbus_interface_t *a) { 73*98a23840SMatthew Barth char fru_type_name[64]; 74*98a23840SMatthew Barth int r= 0; 75*98a23840SMatthew Barth 76*98a23840SMatthew Barth r = find_interface_property_fru_type(a, "fru_type", fru_type_name); 77*98a23840SMatthew Barth if (r<0) { 78*98a23840SMatthew Barth fprintf(stderr, "Failed to get a fru type: %s", strerror(-r)); 79*98a23840SMatthew Barth return -1; 80*98a23840SMatthew Barth } else { 81*98a23840SMatthew Barth return dbus_to_sensor_type(fru_type_name); 82*98a23840SMatthew Barth } 83*98a23840SMatthew Barth } 84*98a23840SMatthew Barth 85*98a23840SMatthew Barth 86*98a23840SMatthew Barth uint8_t find_sensor(uint8_t sensor_number) { 87*98a23840SMatthew Barth 88*98a23840SMatthew Barth dbus_interface_t a; 89*98a23840SMatthew Barth char *p; 90*98a23840SMatthew Barth char r; 91*98a23840SMatthew Barth 92*98a23840SMatthew Barth r = find_openbmc_path("SENSOR", sensor_number, &a); 93*98a23840SMatthew Barth 94*98a23840SMatthew Barth if (r < 0) { return 0; } 95*98a23840SMatthew Barth 96*98a23840SMatthew Barth // This is where sensors that do not exist in dbus but do 97*98a23840SMatthew Barth // exist in the host code stop. This should indicate it 98*98a23840SMatthew Barth // is not a supported sensor 99*98a23840SMatthew Barth if (a.interface[0] == 0) { return 0;} 100*98a23840SMatthew Barth 101*98a23840SMatthew Barth if (strstr(a.interface, "InventoryItem")) { 102*98a23840SMatthew Barth // InventoryItems are real frus. So need to get the 103*98a23840SMatthew Barth // fru_type property 104*98a23840SMatthew Barth r = dbus_to_sensor_type_from_dbus(&a); 105*98a23840SMatthew Barth } else { 106*98a23840SMatthew Barth // Non InventoryItems 107*98a23840SMatthew Barth p = strrchr (a.path, '/'); 108*98a23840SMatthew Barth r = dbus_to_sensor_type(p+1); 109*98a23840SMatthew Barth } 110*98a23840SMatthew Barth 111*98a23840SMatthew Barth return r; 112*98a23840SMatthew Barth } 113*98a23840SMatthew Barth 114*98a23840SMatthew Barth 115*98a23840SMatthew Barth 116*98a23840SMatthew Barth 117*98a23840SMatthew Barth 118*98a23840SMatthew Barth ipmi_ret_t ipmi_sen_get_sensor_type(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 119*98a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 120*98a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 121*98a23840SMatthew Barth { 122*98a23840SMatthew Barth sensor_data_t *reqptr = (sensor_data_t*)request; 123*98a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_OK; 124*98a23840SMatthew Barth 125*98a23840SMatthew Barth printf("IPMI GET_SENSOR_TYPE [0x%02X]\n",reqptr->sennum); 126*98a23840SMatthew Barth 127*98a23840SMatthew Barth // TODO Not sure what the System-event-sensor is suppose to return 128*98a23840SMatthew Barth // need to ask Hostboot team 129*98a23840SMatthew Barth unsigned char buf[] = {0x00,0x6F}; 130*98a23840SMatthew Barth 131*98a23840SMatthew Barth buf[0] = find_sensor(reqptr->sennum); 132*98a23840SMatthew Barth 133*98a23840SMatthew Barth // HACK UNTIL Dbus gets updated or we find a better way 134*98a23840SMatthew Barth if (buf[0] == 0) { 135*98a23840SMatthew Barth rc = IPMI_CC_SENSOR_INVALID; 136*98a23840SMatthew Barth } 137*98a23840SMatthew Barth 138*98a23840SMatthew Barth 139*98a23840SMatthew Barth *data_len = sizeof(buf); 140*98a23840SMatthew Barth memcpy(response, &buf, *data_len); 141*98a23840SMatthew Barth 142*98a23840SMatthew Barth return rc; 143*98a23840SMatthew Barth } 144*98a23840SMatthew Barth 145*98a23840SMatthew Barth 146*98a23840SMatthew Barth 147*98a23840SMatthew Barth ipmi_ret_t ipmi_sen_set_sensor(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 148*98a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 149*98a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 150*98a23840SMatthew Barth { 151*98a23840SMatthew Barth sensor_data_t *reqptr = (sensor_data_t*)request; 152*98a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_OK; 153*98a23840SMatthew Barth 154*98a23840SMatthew Barth printf("IPMI SET_SENSOR [0x%02x]\n",reqptr->sennum); 155*98a23840SMatthew Barth 156*98a23840SMatthew Barth updateSensorRecordFromSSRAESC(reqptr); 157*98a23840SMatthew Barth 158*98a23840SMatthew Barth *data_len=0; 159*98a23840SMatthew Barth 160*98a23840SMatthew Barth return rc; 161*98a23840SMatthew Barth } 162*98a23840SMatthew Barth 163*98a23840SMatthew Barth 164*98a23840SMatthew Barth ipmi_ret_t ipmi_sen_get_sensor_reading(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 165*98a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 166*98a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 167*98a23840SMatthew Barth { 168*98a23840SMatthew Barth sensor_data_t *reqptr = (sensor_data_t*)request; 169*98a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_SENSOR_INVALID; 170*98a23840SMatthew Barth uint8_t type; 171*98a23840SMatthew Barth sensorreadingresp_t *resp = (sensorreadingresp_t*) response; 172*98a23840SMatthew Barth int r; 173*98a23840SMatthew Barth dbus_interface_t a; 174*98a23840SMatthew Barth sd_bus *bus = ipmid_get_sd_bus_connection(); 175*98a23840SMatthew Barth sd_bus_message *reply = NULL; 176*98a23840SMatthew Barth int reading = 0; 177*98a23840SMatthew Barth 178*98a23840SMatthew Barth 179*98a23840SMatthew Barth printf("IPMI GET_SENSOR_READING [0x%02x]\n",reqptr->sennum); 180*98a23840SMatthew Barth 181*98a23840SMatthew Barth r = find_openbmc_path("SENSOR", reqptr->sennum, &a); 182*98a23840SMatthew Barth 183*98a23840SMatthew Barth if (r < 0) { 184*98a23840SMatthew Barth fprintf(stderr, "Failed to find Sensor 0x%02x\n", reqptr->sennum); 185*98a23840SMatthew Barth return IPMI_CC_SENSOR_INVALID; 186*98a23840SMatthew Barth } 187*98a23840SMatthew Barth 188*98a23840SMatthew Barth type = find_sensor(reqptr->sennum); 189*98a23840SMatthew Barth 190*98a23840SMatthew Barth fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n", a.bus, a.path, a.interface); 191*98a23840SMatthew Barth 192*98a23840SMatthew Barth *data_len=0; 193*98a23840SMatthew Barth 194*98a23840SMatthew Barth switch(type) { 195*98a23840SMatthew Barth case 0xC3: 196*98a23840SMatthew Barth case 0xC2: 197*98a23840SMatthew Barth r = sd_bus_get_property(bus,a.bus, a.path, a.interface, "value", NULL, &reply, "i"); 198*98a23840SMatthew Barth if (r < 0) { 199*98a23840SMatthew Barth fprintf(stderr, "Failed to call sd_bus_get_property:%d, %s\n", r, strerror(-r)); 200*98a23840SMatthew Barth fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n", 201*98a23840SMatthew Barth a.bus, a.path, a.interface); 202*98a23840SMatthew Barth break; 203*98a23840SMatthew Barth } 204*98a23840SMatthew Barth 205*98a23840SMatthew Barth r = sd_bus_message_read(reply, "i", &reading); 206*98a23840SMatthew Barth if (r < 0) { 207*98a23840SMatthew Barth fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r)); 208*98a23840SMatthew Barth break; 209*98a23840SMatthew Barth } 210*98a23840SMatthew Barth 211*98a23840SMatthew Barth printf("Contents of a 0x%02x is 0x%02x\n", type, reading); 212*98a23840SMatthew Barth 213*98a23840SMatthew Barth rc = IPMI_CC_OK; 214*98a23840SMatthew Barth *data_len=sizeof(sensorreadingresp_t); 215*98a23840SMatthew Barth 216*98a23840SMatthew Barth resp->value = (uint8_t)reading; 217*98a23840SMatthew Barth resp->operation = 0; 218*98a23840SMatthew Barth resp->indication[0] = 0; 219*98a23840SMatthew Barth resp->indication[1] = 0; 220*98a23840SMatthew Barth break; 221*98a23840SMatthew Barth 222*98a23840SMatthew Barth default: 223*98a23840SMatthew Barth *data_len=0; 224*98a23840SMatthew Barth rc = IPMI_CC_SENSOR_INVALID; 225*98a23840SMatthew Barth break; 226*98a23840SMatthew Barth } 227*98a23840SMatthew Barth 228*98a23840SMatthew Barth 229*98a23840SMatthew Barth reply = sd_bus_message_unref(reply); 230*98a23840SMatthew Barth 231*98a23840SMatthew Barth return rc; 232*98a23840SMatthew Barth } 233*98a23840SMatthew Barth 234*98a23840SMatthew Barth ipmi_ret_t ipmi_sen_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 235*98a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 236*98a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 237*98a23840SMatthew Barth { 238*98a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_OK; 239*98a23840SMatthew Barth 240*98a23840SMatthew Barth printf("IPMI S/E Wildcard Netfn:[0x%X], Cmd:[0x%X]\n",netfn,cmd); 241*98a23840SMatthew Barth *data_len = 0; 242*98a23840SMatthew Barth 243*98a23840SMatthew Barth return rc; 244*98a23840SMatthew Barth } 245*98a23840SMatthew Barth 246*98a23840SMatthew Barth 247*98a23840SMatthew Barth void register_netfn_sen_functions() 248*98a23840SMatthew Barth { 249*98a23840SMatthew Barth printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_WILDCARD); 250*98a23840SMatthew Barth ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_WILDCARD, NULL, ipmi_sen_wildcard); 251*98a23840SMatthew Barth 252*98a23840SMatthew Barth printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE); 253*98a23840SMatthew Barth ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE, NULL, ipmi_sen_get_sensor_type); 254*98a23840SMatthew Barth 255*98a23840SMatthew Barth printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_SET_SENSOR); 256*98a23840SMatthew Barth ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_SET_SENSOR, NULL, ipmi_sen_set_sensor); 257*98a23840SMatthew Barth 258*98a23840SMatthew Barth printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_READING); 259*98a23840SMatthew Barth ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_READING, NULL, ipmi_sen_get_sensor_reading); 260*98a23840SMatthew Barth 261*98a23840SMatthew Barth return; 262*98a23840SMatthew Barth } 263