blob: 9d15a49f20b34eda19667ff17d16c8033fe0d90c [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>
Sergey Solomineb9b8142016-08-23 09:07:28 -050010#include <mapper.h>
Chris Austen41a4b312015-10-25 03:45:42 -050011#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;
Nan Lidfe6e422016-05-13 21:46:26 +080083 int r;
Chris Austen41a4b312015-10-25 03:45:42 -050084
85 if ((fp = fopen(fn, "rb")) != NULL) {
86
Nan Lidfe6e422016-05-13 21:46:26 +080087 r = fseek(fp, 0, SEEK_END);
88 if (r) {
89 fprintf(stderr,"Fseek failed\n");
90 goto fclose_fp;
91 }
92
Chris Austen41a4b312015-10-25 03:45:42 -050093 size = ftell(fp);
Nan Lidfe6e422016-05-13 21:46:26 +080094 if (size == -1L) {
95 fprintf(stderr,"Ftell failed for %s\n", strerror(errno));
96 size = 0;
97 goto fclose_fp;
98 }
99
100 r = fseek(fp, 0, SEEK_SET);
101 if (r) {
102 fprintf(stderr,"Fseek failed\n");
103 size = 0;
104 goto fclose_fp;
105 }
Chris Austen41a4b312015-10-25 03:45:42 -0500106
Chris Austen41a4b312015-10-25 03:45:42 -0500107 *buffer = new uint8_t [size];
108
Nan Lidfe6e422016-05-13 21:46:26 +0800109 r = fread(*buffer, 1, size, fp);
110 if ( r != size) {
111 size = 0;
112 fprintf(stderr,"Fread failed\n");
113 }
114
115fclose_fp:
Chris Austen41a4b312015-10-25 03:45:42 -0500116 fclose(fp);
117 }
118
119 return size;
120}
121
122
123const char *create_esel_severity(const uint8_t *buffer) {
124
125 uint8_t severity;
126 // Dive in to the IBM log to find the severity
127 severity = (0xF0 & buffer[0x4A]);
128
129 return sev_lookup(severity);
130}
131
132int create_esel_association(const uint8_t *buffer, char **m) {
133
134 ipmi_add_sel_request_t *p;
135 dbus_interface_t dbusint;
136 uint8_t sensor;
137
138 p = ( ipmi_add_sel_request_t *) buffer;
139
140 sensor = p->sensornumber;
141
142 find_openbmc_path("SENSOR", sensor, &dbusint);
143
Chris Austen6dc2e912016-02-20 01:00:06 -0600144 // Simply no associations if the sensor can not be found
Chris Austen41a4b312015-10-25 03:45:42 -0500145 if (strlen(dbusint.path) < 1) {
Chris Austen6dc2e912016-02-20 01:00:06 -0600146 printf("Sensor 0x%x not found\n", sensor);
147 memset(dbusint.path,0,sizeof(dbusint.path));
Chris Austen41a4b312015-10-25 03:45:42 -0500148 }
149
150 asprintf(m, "%s", dbusint.path);
151
152 return 0;
153}
154
155
156
157int create_esel_description(const uint8_t *buffer, const char *sev, char **message) {
158
159
160 ipmi_add_sel_request_t *p;
Chris Austen41a4b312015-10-25 03:45:42 -0500161 char *m;
162
163 p = ( ipmi_add_sel_request_t *) buffer;
164
165 find_sensor_type_string(p->sensornumber,&m);
166
167 asprintf(message, "A %s has experienced a %s", m, sev );
168
169 free(m);
170
171 return 0;
172}
173
174
175int send_esel_to_dbus(const char *desc, const char *sev, const char *details, uint8_t *debug, size_t debuglen) {
176
177 sd_bus *mbus = NULL;
178 sd_bus_error error = SD_BUS_ERROR_NULL;
179 sd_bus_message *reply = NULL, *m=NULL;
Chris Austen169395e2015-12-02 20:56:15 -0600180 uint16_t x;
Chris Austen41a4b312015-10-25 03:45:42 -0500181 int r;
Sergey Solomineb9b8142016-08-23 09:07:28 -0500182 const char *object_name = "/org/openbmc/records/events";
183 char *bus_name = NULL;
Chris Austen41a4b312015-10-25 03:45:42 -0500184
Chris Austen30195fa2015-11-13 14:39:19 -0600185 mbus = ipmid_get_sd_bus_connection();
Sergey Solomineb9b8142016-08-23 09:07:28 -0500186 r = mapper_get_service(mbus, object_name, &bus_name);
187 if (r < 0) {
188 fprintf(stderr, "Failed to get connection, return value: %s.\n", strerror(-r));
189 goto finish;
190 }
Chris Austen41a4b312015-10-25 03:45:42 -0500191 r = sd_bus_message_new_method_call(mbus,&m,
Sergey Solomineb9b8142016-08-23 09:07:28 -0500192 bus_name,
193 object_name,
Chris Austen41a4b312015-10-25 03:45:42 -0500194 "org.openbmc.recordlog",
195 "acceptHostMessage");
196 if (r < 0) {
197 fprintf(stderr, "Failed to add the method object: %s\n", strerror(-r));
Chris Austen169395e2015-12-02 20:56:15 -0600198 goto finish;
Chris Austen41a4b312015-10-25 03:45:42 -0500199 }
200
201 r = sd_bus_message_append(m, "sss", desc, sev, details);
202 if (r < 0) {
203 fprintf(stderr, "Failed add the message strings : %s\n", strerror(-r));
Chris Austen169395e2015-12-02 20:56:15 -0600204 goto finish;
Chris Austen41a4b312015-10-25 03:45:42 -0500205 }
206
207 r = sd_bus_message_append_array(m, 'y', debug, debuglen);
208 if (r < 0) {
209 fprintf(stderr, "Failed to add the raw array of bytes: %s\n", strerror(-r));
Chris Austen169395e2015-12-02 20:56:15 -0600210 goto finish;
Chris Austen41a4b312015-10-25 03:45:42 -0500211 }
Chris Austen41a4b312015-10-25 03:45:42 -0500212 // Call the IPMI responder on the bus so the message can be sent to the CEC
213 r = sd_bus_call(mbus, m, 0, &error, &reply);
214 if (r < 0) {
Chris Austen169395e2015-12-02 20:56:15 -0600215 fprintf(stderr, "Failed to call the method: %s %s\n", __FUNCTION__, strerror(-r));
216 goto finish;
Chris Austen41a4b312015-10-25 03:45:42 -0500217 }
Chris Austen169395e2015-12-02 20:56:15 -0600218 r = sd_bus_message_read(reply, "q", &x);
Chris Austen41a4b312015-10-25 03:45:42 -0500219 if (r < 0) {
Chris Austen7cc33322015-11-11 00:20:22 -0600220 fprintf(stderr, "Failed to get a rc from the method: %s\n", strerror(-r));
Chris Austen41a4b312015-10-25 03:45:42 -0500221 }
222
Chris Austen169395e2015-12-02 20:56:15 -0600223finish:
Chris Austen41a4b312015-10-25 03:45:42 -0500224 sd_bus_error_free(&error);
vishwa1eaea4f2016-02-26 11:57:40 -0600225 m = sd_bus_message_unref(m);
226 reply = sd_bus_message_unref(reply);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500227 free (bus_name);
Chris Austen41a4b312015-10-25 03:45:42 -0500228 return r;
Chris Austen41a4b312015-10-25 03:45:42 -0500229}
230
231
232void send_esel(uint16_t recordid) {
Joel Stanleyf19539e2015-11-25 17:24:05 +1030233 char *desc, *assoc;
Chris Austen41a4b312015-10-25 03:45:42 -0500234 const char *sev;
235 uint8_t *buffer = NULL;
Chris Austen6dc2e912016-02-20 01:00:06 -0600236 const char *path = "/tmp/esel";
Chris Austen41a4b312015-10-25 03:45:42 -0500237 size_t sz;
Nan Lidfe6e422016-05-13 21:46:26 +0800238 int r;
Chris Austen41a4b312015-10-25 03:45:42 -0500239
Chris Austen41a4b312015-10-25 03:45:42 -0500240 sz = getfilestream(path, &buffer);
Chris Austen41a4b312015-10-25 03:45:42 -0500241 if (sz == 0) {
242 printf("Error file does not exist %d\n",__LINE__);
Chris Austen41a4b312015-10-25 03:45:42 -0500243 return;
244 }
245
Chris Austen41a4b312015-10-25 03:45:42 -0500246 sev = create_esel_severity(buffer);
Chris Austen41a4b312015-10-25 03:45:42 -0500247 create_esel_association(buffer, &assoc);
Chris Austen41a4b312015-10-25 03:45:42 -0500248 create_esel_description(buffer, sev, &desc);
249
Nan Lidfe6e422016-05-13 21:46:26 +0800250 r = send_esel_to_dbus(desc, sev, assoc, buffer, sz);
251 if (r < 0) {
252 fprintf(stderr, "Failed to send esel to dbus\n");
253 }
Chris Austen41a4b312015-10-25 03:45:42 -0500254
Chris Austen41a4b312015-10-25 03:45:42 -0500255 free(assoc);
256 free(desc);
Chris Austen41a4b312015-10-25 03:45:42 -0500257 delete[] buffer;
258
Chris Austen41a4b312015-10-25 03:45:42 -0500259 return;
260}