blob: 94e037cd61bf22e76f2e1272ca9d0062d7fc501f [file] [log] [blame]
Chris Austen41a4b312015-10-25 03:45:42 -05001#include <stdint.h>
2#include <cstdlib>
3#include <cstring>
4#include <fstream>
5#include <iostream>
6#include <algorithm>
7#include <vector>
8#include <memory>
9#include <systemd/sd-bus.h>
10
11#include "ipmid.H"
12#include "storagehandler.h"
13#include "sensorhandler.h"
14
15using namespace std;
16
17extern int find_openbmc_path(const char *, const uint8_t , dbus_interface_t *);
18
19
20//////////////////////////
21struct esel_section_headers_t {
22 uint8_t sectionid[2];
23 uint8_t sectionlength[2];
24 uint8_t version;
25 uint8_t subsectiontype;
26 uint8_t compid;
27};
28
29struct severity_values_t {
30 uint8_t type;
31 const char *description;
32};
33
34
35const std::vector<severity_values_t> g_sev_desc = {
36 {0x10, "recoverable error"},
37 {0x20, "predictive error"},
38 {0x40, "unrecoverable error"},
39 {0x50, "critical error"},
40 {0x60, "error from a diagnostic test"},
41 {0x70, "recovered symptom "},
42 {0xFF, "Unknown"},
43};
44
45const char* sev_lookup(uint8_t n) {
46 auto i = std::find_if(std::begin(g_sev_desc), std::end(g_sev_desc),
47 [n](auto p){ return p.type == n || p.type == 0xFF; });
48 return i->description;
49}
50
51
52
53
54int find_sensor_type_string(uint8_t sensor_number, char **s) {
55
56 dbus_interface_t a;
57 const char *p;
58 char r;
59
60 r = find_openbmc_path("SENSOR", sensor_number, &a);
61
62 if ((r < 0) || (a.bus[0] == 0)) {
63 // Just make a generic message for errors that
64 // occur on sensors that dont exist
65 asprintf(s, "Unknown Sensor (0x%02x)", sensor_number);
66 } else {
67
68 if ((p = strrchr (a.path, '/')) == NULL) {
69 p = "/Unknown Sensor";
70 }
71
72 asprintf(s, "%s", p+1);
73 }
74
75 return 0;
76}
77
78
79size_t getfilestream(const char *fn, uint8_t **buffer) {
80
81 FILE *fp;
82 size_t size = 0;
83
84 if ((fp = fopen(fn, "rb")) != NULL) {
85
86 fseek(fp, 0, SEEK_END);
87 size = ftell(fp);
88 fseek(fp, 0, SEEK_SET);
89
90 size = 0x100;
91
92 *buffer = new uint8_t [size];
93
94 fread(*buffer, 1, size, fp);
95 fclose(fp);
96 }
97
98 return size;
99}
100
101
102const char *create_esel_severity(const uint8_t *buffer) {
103
104 uint8_t severity;
105 // Dive in to the IBM log to find the severity
106 severity = (0xF0 & buffer[0x4A]);
107
108 return sev_lookup(severity);
109}
110
111int create_esel_association(const uint8_t *buffer, char **m) {
112
113 ipmi_add_sel_request_t *p;
114 dbus_interface_t dbusint;
115 uint8_t sensor;
116
117 p = ( ipmi_add_sel_request_t *) buffer;
118
119 sensor = p->sensornumber;
120
121 find_openbmc_path("SENSOR", sensor, &dbusint);
122
123 if (strlen(dbusint.path) < 1) {
124 printf("Sensor not found\n");
125 snprintf(dbusint.path, sizeof(dbusint.path), "0x%x", sensor);
126 }
127
128 asprintf(m, "%s", dbusint.path);
129
130 return 0;
131}
132
133
134
135int create_esel_description(const uint8_t *buffer, const char *sev, char **message) {
136
137
138 ipmi_add_sel_request_t *p;
139 int r;
140 char *m;
141
142 p = ( ipmi_add_sel_request_t *) buffer;
143
144 find_sensor_type_string(p->sensornumber,&m);
145
146 asprintf(message, "A %s has experienced a %s", m, sev );
147
148 free(m);
149
150 return 0;
151}
152
153
154int send_esel_to_dbus(const char *desc, const char *sev, const char *details, uint8_t *debug, size_t debuglen) {
155
156 sd_bus *mbus = NULL;
157 sd_bus_error error = SD_BUS_ERROR_NULL;
158 sd_bus_message *reply = NULL, *m=NULL;
159 uint16_t *pty;
160 int r;
161
162
163
164 /* Connect to system bus */
165 r = sd_bus_open_system(&mbus);
166 if (r < 0) {
167 fprintf(stderr, "Failed to connect to system bus: %s\n",
168 strerror(-r));
169 goto finish;
170 }
171 r = sd_bus_message_new_method_call(mbus,&m,
172 "org.openbmc.records.events",
173 "/org/openbmc/records/events",
174 "org.openbmc.recordlog",
175 "acceptHostMessage");
176 if (r < 0) {
177 fprintf(stderr, "Failed to add the method object: %s\n", strerror(-r));
178 return -1;
179 }
180
181 r = sd_bus_message_append(m, "sss", desc, sev, details);
182 if (r < 0) {
183 fprintf(stderr, "Failed add the message strings : %s\n", strerror(-r));
184 return -1;
185 }
186
187 r = sd_bus_message_append_array(m, 'y', debug, debuglen);
188 if (r < 0) {
189 fprintf(stderr, "Failed to add the raw array of bytes: %s\n", strerror(-r));
190 return -1;
191 }
192
193 // Call the IPMI responder on the bus so the message can be sent to the CEC
194 r = sd_bus_call(mbus, m, 0, &error, &reply);
195 if (r < 0) {
196 fprintf(stderr, "Failed to call the method: %s", strerror(-r));
197 return -1;
198 }
199
200 r = sd_bus_message_read(reply, "q", &pty);
201 if (r < 0) {
Chris Austen7cc33322015-11-11 00:20:22 -0600202 fprintf(stderr, "Failed to get a rc from the method: %s\n", strerror(-r));
203 } else {
204 r = *pty;
Chris Austen41a4b312015-10-25 03:45:42 -0500205 }
206
207finish:
208 sd_bus_error_free(&error);
209 sd_bus_message_unref(m);
210 sd_bus_message_unref(reply);
211 sd_bus_unref(mbus);
212
213 return r;
214
215}
216
217
218void send_esel(uint16_t recordid) {
219 char *desc, *assoc, *ascii;
220 const char *sev;
221 uint8_t *buffer = NULL;
Chris Austen7cc33322015-11-11 00:20:22 -0600222 char *path, *pathsent;
Chris Austen41a4b312015-10-25 03:45:42 -0500223 size_t sz;
Chris Austen7cc33322015-11-11 00:20:22 -0600224 int r;
Chris Austen41a4b312015-10-25 03:45:42 -0500225
226 uint8_t hack[] = {0x30, 0x32, 0x34};
227
228 asprintf(&path,"%s%04x", "/tmp/esel", recordid);
229
230 sz = getfilestream(path, &buffer);
231
232 if (sz == 0) {
233 printf("Error file does not exist %d\n",__LINE__);
234 free(path);
235 return;
236 }
237
238
239 sev = create_esel_severity(buffer);
240
241 create_esel_association(buffer, &assoc);
242
243 create_esel_description(buffer, sev, &desc);
244
245
246 // TODO until ISSUE https://github.com/openbmc/rest-dbus/issues/2
247 // I cant send extended ascii chars. So 0,2,4 for now...
Chris Austen7cc33322015-11-11 00:20:22 -0600248 r = send_esel_to_dbus(desc, sev, assoc, hack, 3);
Chris Austen41a4b312015-10-25 03:45:42 -0500249
Chris Austen7cc33322015-11-11 00:20:22 -0600250 asprintf(&pathsent,"%s_%d", path, r);
251
252
253 rename(path, pathsent);
Chris Austen41a4b312015-10-25 03:45:42 -0500254
255 free(path);
Chris Austen7cc33322015-11-11 00:20:22 -0600256 free(pathsent);
Chris Austen41a4b312015-10-25 03:45:42 -0500257 free(assoc);
258 free(desc);
259
260 delete[] buffer;
261
Chris Austen7cc33322015-11-11 00:20:22 -0600262
Chris Austen41a4b312015-10-25 03:45:42 -0500263 return;
264}