blob: d171bf5622e9b21026ab5779cf592d2a90c8b31a [file] [log] [blame]
Chris Austenac4604a2015-10-13 12:43:27 -05001#include "sensorhandler.h"
2#include "ipmid-api.h"
3#include <stdio.h>
4#include <string.h>
5#include <stdint.h>
Chris Austen10ccc0f2015-12-10 18:27:04 -06006#include <systemd/sd-bus.h>
Chris Austenac4604a2015-10-13 12:43:27 -05007
Chris Austen8a45e7c2015-10-15 00:31:46 -05008extern int updateSensorRecordFromSSRAESC(const void *);
Chris Austen0012e9b2015-10-22 01:37:46 -05009extern int find_interface_property_fru_type(dbus_interface_t *interface, const char *property_name, char *property_value) ;
10extern int find_openbmc_path(const char *type, const uint8_t num, dbus_interface_t *interface) ;
Chris Austenac4604a2015-10-13 12:43:27 -050011
12void register_netfn_sen_functions() __attribute__((constructor));
13
Chris Austen0012e9b2015-10-22 01:37:46 -050014struct sensorTypemap_t {
15 uint8_t number;
Chris Austend7cf0e42015-11-07 14:27:12 -060016 uint8_t typecode;
Chris Austen0012e9b2015-10-22 01:37:46 -050017 char dbusname[32];
18} ;
19
20
21sensorTypemap_t g_SensorTypeMap[] = {
22
Chris Austend7cf0e42015-11-07 14:27:12 -060023 {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"},
Chris Austen800ba712015-12-03 15:31:00 -060033 {0x12, 0x6F, "SYSTEM_EVENT"},
34 {0xC7, 0x03, "SYSTEM"},
35 {0xC7, 0x03, "MAIN_PLANAR"},
Chris Austen10ccc0f2015-12-10 18:27:04 -060036 {0xC2, 0x6F, "PowerCap"},
Chris Austend7cf0e42015-11-07 14:27:12 -060037 {0xFF, 0x00, ""},
Chris Austen0012e9b2015-10-22 01:37:46 -050038};
39
40
Chris Austenac4604a2015-10-13 12:43:27 -050041struct sensor_data_t {
42 uint8_t sennum;
43} __attribute__ ((packed)) ;
44
Chris Austen10ccc0f2015-12-10 18:27:04 -060045struct sensorreadingresp_t {
46 uint8_t value;
47 uint8_t operation;
48 uint8_t indication[2];
49} __attribute__ ((packed)) ;
Chris Austenac4604a2015-10-13 12:43:27 -050050
Chris Austen0012e9b2015-10-22 01:37:46 -050051uint8_t dbus_to_sensor_type(char *p) {
Chris Austenac4604a2015-10-13 12:43:27 -050052
Chris Austen0012e9b2015-10-22 01:37:46 -050053 sensorTypemap_t *s = g_SensorTypeMap;
54 char r=0;
Chris Austenac4604a2015-10-13 12:43:27 -050055
Chris Austen0012e9b2015-10-22 01:37:46 -050056 while (s->number != 0xFF) {
57 if (!strcmp(s->dbusname,p)) {
58 r = s->number;
59 break;
Chris Austenac4604a2015-10-13 12:43:27 -050060 }
Chris Austen0012e9b2015-10-22 01:37:46 -050061 s++;
Chris Austenac4604a2015-10-13 12:43:27 -050062 }
63
Chris Austend7cf0e42015-11-07 14:27:12 -060064
Chris Austen0012e9b2015-10-22 01:37:46 -050065 if (s->number == 0xFF)
66 printf("Failed to find Sensor Type %s\n", p);
Chris Austenac4604a2015-10-13 12:43:27 -050067
Chris Austen0012e9b2015-10-22 01:37:46 -050068 return r;
Chris Austenac4604a2015-10-13 12:43:27 -050069}
70
Chris Austen0012e9b2015-10-22 01:37:46 -050071
72uint8_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
86uint8_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
Chris Austend7cf0e42015-11-07 14:27:12 -060099 if (a.interface[0] == 0) { return 0;}
Chris Austen0012e9b2015-10-22 01:37:46 -0500100
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
Chris Austen10ccc0f2015-12-10 18:27:04 -0600114
115
116
117
Chris Austen0012e9b2015-10-22 01:37:46 -0500118ipmi_ret_t ipmi_sen_get_sensor_type(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
119 ipmi_request_t request, ipmi_response_t response,
Chris Austenac4604a2015-10-13 12:43:27 -0500120 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
Chris Austen0012e9b2015-10-22 01:37:46 -0500131 buf[0] = find_sensor(reqptr->sennum);
132
133 // HACK UNTIL Dbus gets updated or we find a better way
134 if (buf[0] == 0) {
Chris Austen800ba712015-12-03 15:31:00 -0600135 rc = IPMI_CC_SENSOR_INVALID;
Chris Austen0012e9b2015-10-22 01:37:46 -0500136 }
137
Chris Austenac4604a2015-10-13 12:43:27 -0500138
139 *data_len = sizeof(buf);
140 memcpy(response, &buf, *data_len);
141
Chris Austenac4604a2015-10-13 12:43:27 -0500142 return rc;
143}
144
145
146
Chris Austen0012e9b2015-10-22 01:37:46 -0500147ipmi_ret_t ipmi_sen_set_sensor(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
148 ipmi_request_t request, ipmi_response_t response,
Chris Austenac4604a2015-10-13 12:43:27 -0500149 ipmi_data_len_t data_len, ipmi_context_t context)
150{
Chris Austenac4604a2015-10-13 12:43:27 -0500151 sensor_data_t *reqptr = (sensor_data_t*)request;
152 ipmi_ret_t rc = IPMI_CC_OK;
Chris Austenac4604a2015-10-13 12:43:27 -0500153
Chris Austen0012e9b2015-10-22 01:37:46 -0500154 printf("IPMI SET_SENSOR [0x%02x]\n",reqptr->sennum);
Chris Austenac4604a2015-10-13 12:43:27 -0500155
Chris Austen8a45e7c2015-10-15 00:31:46 -0500156 updateSensorRecordFromSSRAESC(reqptr);
157
Chris Austenac4604a2015-10-13 12:43:27 -0500158 *data_len=0;
159
Chris Austenac4604a2015-10-13 12:43:27 -0500160 return rc;
161}
162
Chris Austen10ccc0f2015-12-10 18:27:04 -0600163
164ipmi_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 uint8_t reading;
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 type = find_sensor(reqptr->sennum);
184
185 fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n", a.bus, a.path, a.interface);
186
187 *data_len=0;
188
189 switch(type) {
190 case 0xC3:
191 case 0xC2:
192 r = sd_bus_get_property(bus,a.bus, a.path, a.interface, "value", NULL, &reply, "y");
193 if (r < 0) {
194 fprintf(stderr, "Failed to call sd_bus_get_property:%d, %s\n", r, strerror(-r));
195 fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n",
196 a.bus, a.path, a.interface);
197 break;
198 }
199
200 r = sd_bus_message_read(reply, "y", &reading);
201 if (r < 0) {
202 fprintf(stderr, "Failed to read byte: %s\n", strerror(-r));
203 break;
204 }
205
206 printf("Contents of a 0x%02x is 0x%02x\n", type, reading);
207
208 rc = IPMI_CC_OK;
209 *data_len=sizeof(sensorreadingresp_t);
210
211 resp->value = reading;
212 resp->operation = 0;
213 resp->indication[0] = 0;
214 resp->indication[1] = 0;
215 break;
216
217 default:
218 *data_len=0;
219 rc = IPMI_CC_SENSOR_INVALID;
220 break;
221 }
222
223
224 sd_bus_message_unref(reply);
225
226 return rc;
227}
228
Chris Austen0012e9b2015-10-22 01:37:46 -0500229ipmi_ret_t ipmi_sen_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
230 ipmi_request_t request, ipmi_response_t response,
Chris Austenac4604a2015-10-13 12:43:27 -0500231 ipmi_data_len_t data_len, ipmi_context_t context)
232{
233 ipmi_ret_t rc = IPMI_CC_OK;
234
235 printf("IPMI S/E Wildcard Netfn:[0x%X], Cmd:[0x%X]\n",netfn,cmd);
236 *data_len = 0;
237
238 return rc;
239}
240
241
242void register_netfn_sen_functions()
243{
244 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_WILDCARD);
245 ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_WILDCARD, NULL, ipmi_sen_wildcard);
246
247 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE);
248 ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE, NULL, ipmi_sen_get_sensor_type);
249
250 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_SET_SENSOR);
251 ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_SET_SENSOR, NULL, ipmi_sen_set_sensor);
Chris Austen8a45e7c2015-10-15 00:31:46 -0500252
Chris Austen10ccc0f2015-12-10 18:27:04 -0600253 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_READING);
254 ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_READING, NULL, ipmi_sen_get_sensor_reading);
255
Chris Austenac4604a2015-10-13 12:43:27 -0500256 return;
257}