blob: ea8099d0a15b41e8d18ae86ad3ad6558892c28c3 [file] [log] [blame]
Chris Austenac4604a2015-10-13 12:43:27 -05001#include "sensorhandler.h"
Patrick Williams37af7332016-09-02 21:21:42 -05002#include "host-ipmid/ipmid-api.h"
Chris Austenac4604a2015-10-13 12:43:27 -05003#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;
Adriana Kobylak93125982016-03-01 12:48:10 -0600176 int reading = 0;
Chris Austen10ccc0f2015-12-10 18:27:04 -0600177
178
179 printf("IPMI GET_SENSOR_READING [0x%02x]\n",reqptr->sennum);
180
181 r = find_openbmc_path("SENSOR", reqptr->sennum, &a);
182
Nan Li36deb762016-05-12 10:23:41 +0800183 if (r < 0) {
184 fprintf(stderr, "Failed to find Sensor 0x%02x\n", reqptr->sennum);
185 return IPMI_CC_SENSOR_INVALID;
186 }
187
Chris Austen10ccc0f2015-12-10 18:27:04 -0600188 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:
Adriana Kobylak93125982016-03-01 12:48:10 -0600197 r = sd_bus_get_property(bus,a.bus, a.path, a.interface, "value", NULL, &reply, "i");
Chris Austen10ccc0f2015-12-10 18:27:04 -0600198 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
Adriana Kobylak93125982016-03-01 12:48:10 -0600205 r = sd_bus_message_read(reply, "i", &reading);
Chris Austen10ccc0f2015-12-10 18:27:04 -0600206 if (r < 0) {
Adriana Kobylak93125982016-03-01 12:48:10 -0600207 fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r));
Chris Austen10ccc0f2015-12-10 18:27:04 -0600208 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
Adriana Kobylak93125982016-03-01 12:48:10 -0600216 resp->value = (uint8_t)reading;
Chris Austen10ccc0f2015-12-10 18:27:04 -0600217 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
vishwa1eaea4f2016-02-26 11:57:40 -0600229 reply = sd_bus_message_unref(reply);
Chris Austen10ccc0f2015-12-10 18:27:04 -0600230
231 return rc;
232}
233
Chris Austen0012e9b2015-10-22 01:37:46 -0500234ipmi_ret_t ipmi_sen_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
235 ipmi_request_t request, ipmi_response_t response,
Chris Austenac4604a2015-10-13 12:43:27 -0500236 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
247void 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);
Chris Austen8a45e7c2015-10-15 00:31:46 -0500257
Chris Austen10ccc0f2015-12-10 18:27:04 -0600258 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
Chris Austenac4604a2015-10-13 12:43:27 -0500261 return;
262}