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