1db5975dbSChris Austen #define _GNU_SOURCE
2935beda9SChris Austen #include <stdio.h>
3935beda9SChris Austen #include <stdlib.h>
4935beda9SChris Austen #include <errno.h>
5935beda9SChris Austen #include <stddef.h>
6935beda9SChris Austen #include <systemd/sd-bus.h>
7*acdc2a90SMatthew Barth #include "message.hpp"
8935beda9SChris Austen #include "event_messaged_sdbus.h"
9935beda9SChris Austen #include <syslog.h>
10935beda9SChris Austen
11935beda9SChris Austen /*****************************************************************************/
12935beda9SChris Austen /* This set of functions are responsible for interactions with events over */
13935beda9SChris Austen /* dbus. Logs come in a couple of different ways... */
14935beda9SChris Austen /* 1) From the calls from acceptHostMessage, acceptTestMessage */
15935beda9SChris Austen /* 2) At startup and logs that exist alreafy are re-added */
16935beda9SChris Austen /* */
17935beda9SChris Austen /* event_record_t when loaded contain all strings and data stream for a log */
18935beda9SChris Austen /* */
19935beda9SChris Austen /* Functions naming convention */
20935beda9SChris Austen /* prop_x : callable dbus properties. */
21935beda9SChris Austen /* method_x : callable dbus functions. */
22935beda9SChris Austen /* */
23935beda9SChris Austen /*****************************************************************************/
24db5975dbSChris Austen const char *event_path = "/org/openbmc/records/events";
25935beda9SChris Austen
26935beda9SChris Austen sd_bus *bus = NULL;
27935beda9SChris Austen sd_bus_slot *slot = NULL;
28935beda9SChris Austen
29935beda9SChris Austen event_record_t *gCachedRec = NULL;
30935beda9SChris Austen
31935beda9SChris Austen typedef struct messageEntry_t {
32935beda9SChris Austen
33935beda9SChris Austen size_t logid;
34935beda9SChris Austen sd_bus_slot *messageslot;
35935beda9SChris Austen sd_bus_slot *deleteslot;
36db5975dbSChris Austen sd_bus_slot *associationslot;
37935beda9SChris Austen event_manager *em;
38935beda9SChris Austen
39935beda9SChris Austen } messageEntry_t;
40935beda9SChris Austen
41eac13554SChris Austen static int remove_log_from_dbus(messageEntry_t *node);
42935beda9SChris Austen
message_entry_close(messageEntry_t * m)438890b946SChris Austen static void message_entry_close(messageEntry_t *m)
448890b946SChris Austen {
45935beda9SChris Austen free(m);
46935beda9SChris Austen return;
47935beda9SChris Austen }
48935beda9SChris Austen
message_entry_new(messageEntry_t ** m,uint16_t logid,event_manager * em)498890b946SChris Austen static void message_entry_new(messageEntry_t **m, uint16_t logid, event_manager *em)
508890b946SChris Austen {
51935beda9SChris Austen *m = malloc(sizeof(messageEntry_t));
52935beda9SChris Austen (*m)->logid = logid;
53935beda9SChris Austen (*m)->em = em;
54935beda9SChris Austen return;
55935beda9SChris Austen }
56935beda9SChris Austen
57935beda9SChris Austen // After calling this function the gCachedRec will be set
message_record_open(event_manager * em,uint16_t logid)588890b946SChris Austen static event_record_t* message_record_open(event_manager *em, uint16_t logid)
598890b946SChris Austen {
60935beda9SChris Austen
61935beda9SChris Austen int r = 0;
62935beda9SChris Austen event_record_t *rec;
63935beda9SChris Austen
64935beda9SChris Austen // A simple caching technique because each
65935beda9SChris Austen // property needs to extract data from the
66935beda9SChris Austen // same data blob.
67935beda9SChris Austen if (gCachedRec == NULL) {
68935beda9SChris Austen if (message_load_log(em, logid, &rec)) {
69935beda9SChris Austen gCachedRec = rec;
70935beda9SChris Austen return gCachedRec;
71935beda9SChris Austen } else
72935beda9SChris Austen return NULL;
73935beda9SChris Austen }
74935beda9SChris Austen
75935beda9SChris Austen if (logid == gCachedRec->logid) {
76935beda9SChris Austen r = 1;
77935beda9SChris Austen
78935beda9SChris Austen } else {
79935beda9SChris Austen message_free_log(em, gCachedRec);
80935beda9SChris Austen gCachedRec = NULL;
81935beda9SChris Austen
82935beda9SChris Austen r = message_load_log(em, logid, &rec);
83935beda9SChris Austen if (r)
84935beda9SChris Austen gCachedRec = rec;
85935beda9SChris Austen }
86935beda9SChris Austen
87935beda9SChris Austen return (r ? gCachedRec : NULL);
88935beda9SChris Austen }
89935beda9SChris Austen
prop_message_assoc(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)90db5975dbSChris Austen static int prop_message_assoc(sd_bus *bus,
91db5975dbSChris Austen const char *path,
92db5975dbSChris Austen const char *interface,
93db5975dbSChris Austen const char *property,
94db5975dbSChris Austen sd_bus_message *reply,
95db5975dbSChris Austen void *userdata,
96db5975dbSChris Austen sd_bus_error *error)
97db5975dbSChris Austen {
98db5975dbSChris Austen int r=0;
99db5975dbSChris Austen messageEntry_t *m = (messageEntry_t*) userdata;
100db5975dbSChris Austen event_record_t *rec;
101db5975dbSChris Austen char *p;
10269c3d209SMatthew Barth char *token;
103db5975dbSChris Austen
104db5975dbSChris Austen rec = message_record_open(m->em, m->logid);
105db5975dbSChris Austen if (!rec) {
10669c3d209SMatthew Barth fprintf(stderr,"Warning missing event log for %zx\n", m->logid);
107db5975dbSChris Austen sd_bus_error_set(error,
108db5975dbSChris Austen SD_BUS_ERROR_FILE_NOT_FOUND,
109db5975dbSChris Austen "Could not find log file");
110db5975dbSChris Austen return -1;
111db5975dbSChris Austen }
112db5975dbSChris Austen
113db5975dbSChris Austen /* strtok manipulates a string. It turns out that message_record_open */
114db5975dbSChris Austen /* implements a caching mechcanism which means the oiginal string is */
115db5975dbSChris Austen /* To avoid that, I will make a copy and mess with that */
116db5975dbSChris Austen p = strdup(rec->association);
117db5975dbSChris Austen
118db5975dbSChris Austen if (!p) {
119db5975dbSChris Austen /* no association string == no associations */
120db5975dbSChris Austen sd_bus_error_set(error,
121db5975dbSChris Austen SD_BUS_ERROR_NO_MEMORY,
122db5975dbSChris Austen "Not enough memory for association");
123db5975dbSChris Austen return -1;
124db5975dbSChris Austen }
125db5975dbSChris Austen
126db5975dbSChris Austen token = strtok(p, " ");
127db5975dbSChris Austen
128db5975dbSChris Austen if (token) {
129db5975dbSChris Austen
130db5975dbSChris Austen r = sd_bus_message_open_container(reply, 'a', "(sss)");
131db5975dbSChris Austen if (r < 0) {
132db5975dbSChris Austen fprintf(stderr,"Error opening container %s to reply %s\n", token, strerror(-r));
133db5975dbSChris Austen }
134db5975dbSChris Austen
135db5975dbSChris Austen while(token) {
136db5975dbSChris Austen r = sd_bus_message_append(reply, "(sss)", "fru", "event", token);
137db5975dbSChris Austen if (r < 0) {
138db5975dbSChris Austen fprintf(stderr,"Error adding properties for %s to reply %s\n", token, strerror(-r));
139db5975dbSChris Austen }
140db5975dbSChris Austen
141db5975dbSChris Austen token = strtok(NULL, " ");
142db5975dbSChris Austen }
143db5975dbSChris Austen
144db5975dbSChris Austen r = sd_bus_message_close_container(reply);
145db5975dbSChris Austen }
146db5975dbSChris Austen
147db5975dbSChris Austen free(p);
148db5975dbSChris Austen
149db5975dbSChris Austen return r;
150db5975dbSChris Austen }
151935beda9SChris Austen
152935beda9SChris Austen
prop_message(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)153935beda9SChris Austen static int prop_message(sd_bus *bus,
154935beda9SChris Austen const char *path,
155935beda9SChris Austen const char *interface,
156935beda9SChris Austen const char *property,
157935beda9SChris Austen sd_bus_message *reply,
158935beda9SChris Austen void *userdata,
1598890b946SChris Austen sd_bus_error *error)
1608890b946SChris Austen {
161935beda9SChris Austen int r=0;
162935beda9SChris Austen messageEntry_t *m = (messageEntry_t*) userdata;
163935beda9SChris Austen char *p;
164935beda9SChris Austen struct tm *tm_info;
165db5975dbSChris Austen char buffer[36];
166935beda9SChris Austen event_record_t *rec;
167935beda9SChris Austen
168935beda9SChris Austen rec = message_record_open(m->em, m->logid);
169935beda9SChris Austen if (!rec) {
17069c3d209SMatthew Barth fprintf(stderr,"Warning missing event log for %zx\n", m->logid);
1718890b946SChris Austen sd_bus_error_set(error,
1728890b946SChris Austen SD_BUS_ERROR_FILE_NOT_FOUND,
1738890b946SChris Austen "Could not find log file");
174935beda9SChris Austen return -1;
175935beda9SChris Austen }
176935beda9SChris Austen
1778890b946SChris Austen if (!strncmp("message", property, 7)) {
178935beda9SChris Austen p = rec->message;
1798890b946SChris Austen } else if (!strncmp("severity", property, 8)) {
180935beda9SChris Austen p = rec->severity;
1818890b946SChris Austen } else if (!strncmp("reported_by", property, 11)) {
182935beda9SChris Austen p = rec->reportedby;
1838890b946SChris Austen } else if (!strncmp("time", property, 4)) {
184935beda9SChris Austen tm_info = localtime(&rec->timestamp);
185935beda9SChris Austen strftime(buffer, 26, "%Y:%m:%d %H:%M:%S", tm_info);
186935beda9SChris Austen p = buffer;
1878890b946SChris Austen } else {
188935beda9SChris Austen p = "";
1898890b946SChris Austen }
190935beda9SChris Austen
191935beda9SChris Austen r = sd_bus_message_append(reply, "s", p);
192935beda9SChris Austen if (r < 0) {
1938890b946SChris Austen fprintf(stderr,"Error adding property to reply %s\n", strerror(-r));
194935beda9SChris Austen }
195935beda9SChris Austen
196935beda9SChris Austen return r;
197935beda9SChris Austen }
198935beda9SChris Austen
199935beda9SChris Austen
prop_message_dd(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)200935beda9SChris Austen static int prop_message_dd(sd_bus *bus,
201935beda9SChris Austen const char *path,
202935beda9SChris Austen const char *interface,
203935beda9SChris Austen const char *property,
204935beda9SChris Austen sd_bus_message *reply,
205935beda9SChris Austen void *userdata,
2068890b946SChris Austen sd_bus_error *error)
2078890b946SChris Austen {
208935beda9SChris Austen
209935beda9SChris Austen event_record_t *rec;
210935beda9SChris Austen messageEntry_t *m = (messageEntry_t*) userdata;
211935beda9SChris Austen
212935beda9SChris Austen
213935beda9SChris Austen rec = message_record_open(m->em, m->logid);
214935beda9SChris Austen
215935beda9SChris Austen if (!rec) {
2168890b946SChris Austen sd_bus_error_set(error,
2178890b946SChris Austen SD_BUS_ERROR_FILE_NOT_FOUND,
2188890b946SChris Austen "Could not find log file");
2198890b946SChris Austen
220935beda9SChris Austen return -1;
221935beda9SChris Austen }
222935beda9SChris Austen return sd_bus_message_append_array(reply, 'y', rec->p, rec->n);
223935beda9SChris Austen }
224935beda9SChris Austen
225935beda9SChris Austen /////////////////////////////////////////////////////////////
226935beda9SChris Austen // Receives an array of bytes as an esel error log
227935beda9SChris Austen // returns the messageid in 2 byte format
228935beda9SChris Austen //
229935beda9SChris Austen // S1 - Message - Simple sentence about the fail
230935beda9SChris Austen // S2 - Severity - How bad of a problem is this
231935beda9SChris Austen // S3 - Association - sensor path
232935beda9SChris Austen // ay - Detailed data - developer debug information
233935beda9SChris Austen //
234935beda9SChris Austen /////////////////////////////////////////////////////////////
accept_message(sd_bus_message * m,void * userdata,sd_bus_error * ret_error,char * reportedby)2354dad2391SYi Li static int accept_message(sd_bus_message *m,
236935beda9SChris Austen void *userdata,
2374dad2391SYi Li sd_bus_error *ret_error,
2384dad2391SYi Li char *reportedby)
2398890b946SChris Austen {
240db5975dbSChris Austen char *message, *severity, *association;
241935beda9SChris Austen size_t n = 4;
242935beda9SChris Austen uint8_t *p;
243935beda9SChris Austen int r;
244935beda9SChris Austen uint16_t logid;
245935beda9SChris Austen event_record_t rec;
246935beda9SChris Austen event_manager *em = (event_manager *) userdata;
247935beda9SChris Austen
248935beda9SChris Austen r = sd_bus_message_read(m, "sss", &message, &severity, &association);
249935beda9SChris Austen if (r < 0) {
2508890b946SChris Austen fprintf(stderr, "Error parsing strings: %s\n", strerror(-r));
251935beda9SChris Austen return r;
252935beda9SChris Austen }
253935beda9SChris Austen
254935beda9SChris Austen r = sd_bus_message_read_array(m, 'y', (const void **)&p, &n);
255935beda9SChris Austen if (r < 0) {
2568890b946SChris Austen fprintf(stderr, "Error parsing debug data: %s\n", strerror(-r));
257935beda9SChris Austen return r;
258935beda9SChris Austen }
259935beda9SChris Austen
260935beda9SChris Austen rec.message = (char*) message;
261935beda9SChris Austen rec.severity = (char*) severity;
262935beda9SChris Austen rec.association = (char*) association;
2634dad2391SYi Li rec.reportedby = reportedby;
264935beda9SChris Austen rec.p = (uint8_t*) p;
265935beda9SChris Austen rec.n = n;
266935beda9SChris Austen
267db5975dbSChris Austen syslog(LOG_NOTICE, "%s %s (%s)", rec.severity, rec.message, rec.association);
268935beda9SChris Austen
269935beda9SChris Austen logid = message_create_new_log_event(em, &rec);
270935beda9SChris Austen
271935beda9SChris Austen if (logid)
272db5975dbSChris Austen r = send_log_to_dbus(em, logid, rec.association);
273935beda9SChris Austen
274935beda9SChris Austen return sd_bus_reply_method_return(m, "q", logid);
275935beda9SChris Austen }
276935beda9SChris Austen
method_accept_host_message(sd_bus_message * m,void * userdata,sd_bus_error * ret_error)2774dad2391SYi Li static int method_accept_host_message(sd_bus_message *m,
2784dad2391SYi Li void *userdata,
2794dad2391SYi Li sd_bus_error *ret_error)
2804dad2391SYi Li {
2814dad2391SYi Li return accept_message(m, userdata, ret_error, "Host");
2824dad2391SYi Li }
283935beda9SChris Austen
method_accept_bmc_message(sd_bus_message * m,void * userdata,sd_bus_error * ret_error)2844dad2391SYi Li static int method_accept_bmc_message(sd_bus_message *m,
2854dad2391SYi Li void *userdata,
2864dad2391SYi Li sd_bus_error *ret_error)
2874dad2391SYi Li {
2884dad2391SYi Li return accept_message(m, userdata, ret_error, "BMC");
2894dad2391SYi Li }
method_accept_test_message(sd_bus_message * m,void * userdata,sd_bus_error * ret_error)290935beda9SChris Austen static int method_accept_test_message(sd_bus_message *m,
291935beda9SChris Austen void *userdata,
2928890b946SChris Austen sd_bus_error *ret_error)
2938890b946SChris Austen {
294935beda9SChris Austen // Random debug data including, ascii, null, >signed int, max
295935beda9SChris Austen uint8_t p[] = {0x30, 0x00, 0x13, 0x7F, 0x88, 0xFF};
296935beda9SChris Austen uint16_t logid;
297935beda9SChris Austen event_record_t rec;
298935beda9SChris Austen event_manager *em = (event_manager *) userdata;
299935beda9SChris Austen
300935beda9SChris Austen rec.message = (char*) "A Test event log just happened";
301935beda9SChris Austen rec.severity = (char*) "Info";
302935beda9SChris Austen rec.association = (char*) "/org/openbmc/inventory/system/chassis/motherboard/dimm3 " \
303935beda9SChris Austen "/org/openbmc/inventory/system/chassis/motherboard/dimm2";
304935beda9SChris Austen rec.reportedby = (char*) "Test";
305935beda9SChris Austen rec.p = (uint8_t*) p;
306935beda9SChris Austen rec.n = 6;
307935beda9SChris Austen
308935beda9SChris Austen
309db5975dbSChris Austen syslog(LOG_NOTICE, "%s %s (%s)", rec.severity, rec.message, rec.association);
310935beda9SChris Austen logid = message_create_new_log_event(em, &rec);
311db5975dbSChris Austen
312db5975dbSChris Austen if (logid)
313db5975dbSChris Austen send_log_to_dbus(em, logid, rec.association);
314935beda9SChris Austen
315935beda9SChris Austen return sd_bus_reply_method_return(m, "q", logid);
316935beda9SChris Austen }
317935beda9SChris Austen
finish_delete_log(sd_bus_message * m,void * userdata,sd_bus_error * ret_error)3188890b946SChris Austen static int finish_delete_log(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
3198890b946SChris Austen {
320eac13554SChris Austen return 0;
321eac13554SChris Austen }
322935beda9SChris Austen
method_clearall(sd_bus_message * m,void * userdata,sd_bus_error * ret_error)3238890b946SChris Austen static int method_clearall(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
3248890b946SChris Austen {
325eac13554SChris Austen event_manager *em = (event_manager *) userdata;
326eac13554SChris Austen uint16_t logid;
327eac13554SChris Austen char buffer[32];
328eac13554SChris Austen int r;
329935beda9SChris Austen
330eac13554SChris Austen message_refresh_events(em);
331eac13554SChris Austen
33269c3d209SMatthew Barth while ((logid = message_next_event(em))) {
3338890b946SChris Austen snprintf(buffer, sizeof(buffer),
334db5975dbSChris Austen "%s/%d", event_path, logid);
335eac13554SChris Austen
336eac13554SChris Austen r = sd_bus_call_method_async(bus,
337eac13554SChris Austen NULL,
338eac13554SChris Austen "org.openbmc.records.events",
339eac13554SChris Austen buffer,
340eac13554SChris Austen "org.openbmc.Object.Delete",
341eac13554SChris Austen "delete",
342eac13554SChris Austen finish_delete_log,
343eac13554SChris Austen NULL,
344eac13554SChris Austen NULL);
345eac13554SChris Austen if (r < 0) {
3468890b946SChris Austen fprintf(stderr,
3478890b946SChris Austen "sd_bus_call_method_async Failed : %s\n",
3488890b946SChris Austen strerror(-r));
349eac13554SChris Austen return -1;
350eac13554SChris Austen }
351935beda9SChris Austen }
352935beda9SChris Austen
353935beda9SChris Austen return sd_bus_reply_method_return(m, "q", 0);
354935beda9SChris Austen }
355935beda9SChris Austen
356935beda9SChris Austen
method_deletelog(sd_bus_message * m,void * userdata,sd_bus_error * ret_error)3578890b946SChris Austen static int method_deletelog(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
3588890b946SChris Austen {
359eac13554SChris Austen messageEntry_t *p = (messageEntry_t *) userdata;
360935beda9SChris Austen
361935beda9SChris Austen message_delete_log(p->em, p->logid);
362eac13554SChris Austen remove_log_from_dbus(p);
363935beda9SChris Austen return sd_bus_reply_method_return(m, "q", 0);
364935beda9SChris Austen }
365935beda9SChris Austen
366935beda9SChris Austen
367935beda9SChris Austen
368935beda9SChris Austen static const sd_bus_vtable recordlog_vtable[] = {
369935beda9SChris Austen SD_BUS_VTABLE_START(0),
370935beda9SChris Austen SD_BUS_METHOD("acceptHostMessage", "sssay", "q", method_accept_host_message, SD_BUS_VTABLE_UNPRIVILEGED),
3714dad2391SYi Li SD_BUS_METHOD("acceptBMCMessage", "sssay", "q", method_accept_bmc_message, SD_BUS_VTABLE_UNPRIVILEGED),
372935beda9SChris Austen SD_BUS_METHOD("acceptTestMessage", NULL, "q", method_accept_test_message, SD_BUS_VTABLE_UNPRIVILEGED),
373935beda9SChris Austen SD_BUS_METHOD("clear", NULL, "q", method_clearall, SD_BUS_VTABLE_UNPRIVILEGED),
374935beda9SChris Austen SD_BUS_VTABLE_END
375935beda9SChris Austen };
376935beda9SChris Austen
377935beda9SChris Austen static const sd_bus_vtable log_vtable[] = {
378935beda9SChris Austen SD_BUS_VTABLE_START(0),
379935beda9SChris Austen SD_BUS_PROPERTY("message", "s", prop_message, 0, SD_BUS_VTABLE_PROPERTY_CONST),
380935beda9SChris Austen SD_BUS_PROPERTY("severity", "s", prop_message, 0, SD_BUS_VTABLE_PROPERTY_CONST),
381935beda9SChris Austen SD_BUS_PROPERTY("reported_by", "s", prop_message, 0, SD_BUS_VTABLE_PROPERTY_CONST),
382935beda9SChris Austen SD_BUS_PROPERTY("time", "s", prop_message, 0, SD_BUS_VTABLE_PROPERTY_CONST),
383935beda9SChris Austen SD_BUS_PROPERTY("debug_data", "ay", prop_message_dd ,0, SD_BUS_VTABLE_PROPERTY_CONST),
384935beda9SChris Austen SD_BUS_VTABLE_END
385935beda9SChris Austen };
386935beda9SChris Austen
387935beda9SChris Austen
388935beda9SChris Austen static const sd_bus_vtable recordlog_delete_vtable[] = {
389935beda9SChris Austen SD_BUS_VTABLE_START(0),
390935beda9SChris Austen SD_BUS_METHOD("delete", NULL, "q", method_deletelog, SD_BUS_VTABLE_UNPRIVILEGED),
391935beda9SChris Austen SD_BUS_VTABLE_END
392935beda9SChris Austen };
393935beda9SChris Austen
394db5975dbSChris Austen static const sd_bus_vtable recordlog_association_vtable[] = {
395db5975dbSChris Austen SD_BUS_VTABLE_START(0),
396db5975dbSChris Austen SD_BUS_PROPERTY("associations", "a(sss)", prop_message_assoc, 0, SD_BUS_VTABLE_PROPERTY_CONST),
397db5975dbSChris Austen SD_BUS_VTABLE_END
398db5975dbSChris Austen };
399db5975dbSChris Austen
remove_log_from_dbus(messageEntry_t * p)4008890b946SChris Austen static int remove_log_from_dbus(messageEntry_t *p)
4018890b946SChris Austen {
402935beda9SChris Austen int r;
403935beda9SChris Austen char buffer[32];
404935beda9SChris Austen
40569c3d209SMatthew Barth snprintf(buffer, sizeof(buffer), "%s/%zu", event_path, p->logid);
406935beda9SChris Austen
407935beda9SChris Austen printf("Attempting to delete %s\n", buffer);
408935beda9SChris Austen
409935beda9SChris Austen r = sd_bus_emit_object_removed(bus, buffer);
410935beda9SChris Austen if (r < 0) {
411935beda9SChris Austen fprintf(stderr, "Failed to emit the delete signal %s\n", strerror(-r));
412935beda9SChris Austen return -1;
413935beda9SChris Austen }
414935beda9SChris Austen sd_bus_slot_unref(p->messageslot);
415935beda9SChris Austen sd_bus_slot_unref(p->deleteslot);
416935beda9SChris Austen
417db5975dbSChris Austen if (p->associationslot)
418db5975dbSChris Austen sd_bus_slot_unref(p->associationslot);
419db5975dbSChris Austen
420935beda9SChris Austen message_entry_close(p);
421935beda9SChris Austen
422935beda9SChris Austen return 0;
423935beda9SChris Austen }
424935beda9SChris Austen
send_log_to_dbus(event_manager * em,const uint16_t logid,const char * association)425db5975dbSChris Austen int send_log_to_dbus(event_manager *em, const uint16_t logid, const char *association)
4268890b946SChris Austen {
427935beda9SChris Austen char loglocation[64];
428935beda9SChris Austen int r;
429935beda9SChris Austen messageEntry_t *m;
430935beda9SChris Austen
431db5975dbSChris Austen snprintf(loglocation, sizeof(loglocation), "%s/%d", event_path, logid);
432935beda9SChris Austen
433935beda9SChris Austen message_entry_new(&m, logid, em);
434935beda9SChris Austen
435935beda9SChris Austen r = sd_bus_add_object_vtable(bus,
436935beda9SChris Austen &m->messageslot,
437935beda9SChris Austen loglocation,
438935beda9SChris Austen "org.openbmc.record",
439935beda9SChris Austen log_vtable,
440935beda9SChris Austen m);
441935beda9SChris Austen if (r < 0) {
4428890b946SChris Austen fprintf(stderr, "Failed to acquire service name: %s %s\n",
4438890b946SChris Austen loglocation, strerror(-r));
444935beda9SChris Austen message_entry_close(m);
445935beda9SChris Austen return 0;
446935beda9SChris Austen }
447935beda9SChris Austen
448935beda9SChris Austen r = sd_bus_add_object_vtable(bus,
449935beda9SChris Austen &m->deleteslot,
450935beda9SChris Austen loglocation,
451935beda9SChris Austen "org.openbmc.Object.Delete",
452935beda9SChris Austen recordlog_delete_vtable,
453eac13554SChris Austen m);
454935beda9SChris Austen
455db5975dbSChris Austen if (r < 0) {
456db5975dbSChris Austen fprintf(stderr, "Failed to add delete object for: %s, %s\n",
457db5975dbSChris Austen loglocation, strerror(-r));
458db5975dbSChris Austen message_entry_close(m);
459db5975dbSChris Austen return 0;
460db5975dbSChris Austen }
461db5975dbSChris Austen
462db5975dbSChris Austen m->associationslot = NULL;
463db5975dbSChris Austen if (strlen(association) > 0) {
464db5975dbSChris Austen r = sd_bus_add_object_vtable(bus,
465db5975dbSChris Austen &m->associationslot,
466db5975dbSChris Austen loglocation,
467db5975dbSChris Austen "org.openbmc.Associations",
468db5975dbSChris Austen recordlog_association_vtable,
469db5975dbSChris Austen m);
470db5975dbSChris Austen if (r < 0) {
471db5975dbSChris Austen fprintf(stderr, "Failed to add association object for: %s %s\n",
472db5975dbSChris Austen loglocation, strerror(-r));
473db5975dbSChris Austen message_entry_close(m);
474db5975dbSChris Austen return 0;
475db5975dbSChris Austen }
476db5975dbSChris Austen }
477935beda9SChris Austen
478935beda9SChris Austen r = sd_bus_emit_object_added(bus, loglocation);
479935beda9SChris Austen if (r < 0) {
480935beda9SChris Austen fprintf(stderr, "Failed to emit signal %s\n", strerror(-r));
481db5975dbSChris Austen message_entry_close(m);
482935beda9SChris Austen return 0;
483935beda9SChris Austen }
484935beda9SChris Austen
485935beda9SChris Austen return logid;
486935beda9SChris Austen }
487935beda9SChris Austen
488935beda9SChris Austen
start_event_monitor(void)4898890b946SChris Austen int start_event_monitor(void)
4908890b946SChris Austen {
491935beda9SChris Austen int r;
492935beda9SChris Austen
493935beda9SChris Austen for (;;) {
494935beda9SChris Austen
495935beda9SChris Austen r = sd_bus_process(bus, NULL);
496935beda9SChris Austen if (r < 0) {
4978890b946SChris Austen fprintf(stderr, "Error bus process: %s\n", strerror(-r));
498935beda9SChris Austen break;
499935beda9SChris Austen }
500935beda9SChris Austen
501935beda9SChris Austen if (r > 0)
502935beda9SChris Austen continue;
503935beda9SChris Austen
504935beda9SChris Austen r = sd_bus_wait(bus, (uint64_t) -1);
505935beda9SChris Austen if (r < 0) {
5068890b946SChris Austen fprintf(stderr, "Error in sd_bus_wait: %s\n", strerror(-r));
507935beda9SChris Austen break;
508935beda9SChris Austen }
509935beda9SChris Austen }
510935beda9SChris Austen
511935beda9SChris Austen return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
512935beda9SChris Austen }
513935beda9SChris Austen
514935beda9SChris Austen
515935beda9SChris Austen /* Only thing we are doing in this function is to get a connection on the dbus */
build_bus(event_manager * em)5168890b946SChris Austen int build_bus(event_manager *em)
5178890b946SChris Austen {
518935beda9SChris Austen
519935beda9SChris Austen int r = 0;
520935beda9SChris Austen
521935beda9SChris Austen /* Connect to the system bus */
522935beda9SChris Austen r = sd_bus_open_system(&bus);
523935beda9SChris Austen if (r < 0) {
5248890b946SChris Austen fprintf(stderr, "Error connecting to system bus: %s\n", strerror(-r));
525935beda9SChris Austen goto finish;
526935beda9SChris Austen }
527935beda9SChris Austen
528935beda9SChris Austen /* Install the object */
529935beda9SChris Austen r = sd_bus_add_object_vtable(bus,
530935beda9SChris Austen &slot,
5318890b946SChris Austen "/org/openbmc/records/events",
5328890b946SChris Austen "org.openbmc.recordlog",
533935beda9SChris Austen recordlog_vtable,
534935beda9SChris Austen em);
535935beda9SChris Austen if (r < 0) {
5368890b946SChris Austen fprintf(stderr, "Error adding vtable: %s\n", strerror(-r));
537935beda9SChris Austen goto finish;
538935beda9SChris Austen }
539935beda9SChris Austen
540935beda9SChris Austen r = sd_bus_request_name(bus, "org.openbmc.records.events", 0);
541935beda9SChris Austen if (r < 0) {
5428890b946SChris Austen fprintf(stderr, "Error requesting name: %s\n", strerror(-r));
543935beda9SChris Austen }
544935beda9SChris Austen
545935beda9SChris Austen /* You want to add an object manager to support deleting stuff */
546935beda9SChris Austen /* without it, dbus can show interfaces that no longer exist */
547db5975dbSChris Austen r = sd_bus_add_object_manager(bus, NULL, event_path);
548935beda9SChris Austen if (r < 0) {
549935beda9SChris Austen fprintf(stderr, "Object Manager failure %s\n", strerror(-r));
550935beda9SChris Austen }
551935beda9SChris Austen
552935beda9SChris Austen
553935beda9SChris Austen finish:
554935beda9SChris Austen return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
555935beda9SChris Austen }
556935beda9SChris Austen
cleanup_event_monitor(void)5578890b946SChris Austen void cleanup_event_monitor(void)
5588890b946SChris Austen {
559935beda9SChris Austen sd_bus_slot_unref(slot);
560935beda9SChris Austen sd_bus_unref(bus);
561935beda9SChris Austen }
562