xref: /openbmc/phosphor-event/event_messaged_sdbus.c (revision acdc2a909e7464111b259fb94509dcf8dab7c626)
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