xref: /openbmc/hiomapd/mboxctl.c (revision a804a73c)
14fe996c2SAndrew Jeffery // SPDX-License-Identifier: Apache-2.0
24fe996c2SAndrew Jeffery // Copyright (C) 2018 IBM Corp.
3939bd388SAndrew Jeffery #include "config.h"
4ddf0edbfSSuraj Jitindar Singh 
5fbf74549SAndrew Jeffery #include <errno.h>
6ddf0edbfSSuraj Jitindar Singh #include <getopt.h>
75320f6e0SAndrew Jeffery #include <limits.h>
8ddf0edbfSSuraj Jitindar Singh #include <stdbool.h>
9ddf0edbfSSuraj Jitindar Singh #include <stdio.h>
10ddf0edbfSSuraj Jitindar Singh #include <stdlib.h>
11fbf74549SAndrew Jeffery #include <string.h>
12ddf0edbfSSuraj Jitindar Singh #include <systemd/sd-bus.h>
13ddf0edbfSSuraj Jitindar Singh 
14ddf0edbfSSuraj Jitindar Singh #include "dbus.h"
15ddf0edbfSSuraj Jitindar Singh 
16ddf0edbfSSuraj Jitindar Singh #define USAGE \
17ddf0edbfSSuraj Jitindar Singh "\nUsage: %s [--silent | -s] <command> [args]\n\n" \
18ddf0edbfSSuraj Jitindar Singh "\t\t--silent\t\t- no output on the command line\n\n" \
19ddf0edbfSSuraj Jitindar Singh "\tCommands: (num args)\n" \
20ddf0edbfSSuraj Jitindar Singh "\t\t--ping\t\t\t- ping the daemon (0)\n" \
21ddf0edbfSSuraj Jitindar Singh "\t\t--daemon-state\t\t- check state of the daemon (0)\n" \
22ddf0edbfSSuraj Jitindar Singh "\t\t--lpc-state\t\t- check the state of the lpc mapping (0)\n" \
23ddf0edbfSSuraj Jitindar Singh "\t\t--kill\t\t\t- stop the daemon [no flush] (0)\n" \
24ddf0edbfSSuraj Jitindar Singh "\t\t--reset\t\t\t- hard reset the daemon state (0)\n" \
25ddf0edbfSSuraj Jitindar Singh "\t\t--point-to-flash\t- point the lpc mapping back to flash (0)\n" \
26ddf0edbfSSuraj Jitindar Singh "\t\t--suspend\t\t- suspend the daemon to inhibit flash accesses (0)\n" \
27ddf0edbfSSuraj Jitindar Singh "\t\t--resume\t\t- resume the daemon (1)\n" \
28ddf0edbfSSuraj Jitindar Singh "\t\t\targ[0]: < \"clean\" | \"modified\" >\n" \
295320f6e0SAndrew Jeffery "\t\t--clear-cache\t- tell the daemon to discard any caches (0)\n" \
305320f6e0SAndrew Jeffery "\t\t--backend <vpnor|mtd[:PATH]|file:PATH>\n"
31ddf0edbfSSuraj Jitindar Singh 
328d65bb44SSuraj Jitindar Singh #define NAME		"Mailbox Control"
33ddf0edbfSSuraj Jitindar Singh 
34ddf0edbfSSuraj Jitindar Singh static bool silent;
35ddf0edbfSSuraj Jitindar Singh 
36ddf0edbfSSuraj Jitindar Singh #define MSG_OUT(...)	do { if (!silent) { \
37ddf0edbfSSuraj Jitindar Singh 				fprintf(stdout, __VA_ARGS__); } \
38ddf0edbfSSuraj Jitindar Singh 			} while (0)
39ddf0edbfSSuraj Jitindar Singh #define MSG_ERR(...)	do { if (!silent) { \
40ddf0edbfSSuraj Jitindar Singh 				fprintf(stderr, __VA_ARGS__); } \
41ddf0edbfSSuraj Jitindar Singh 			} while (0)
42ddf0edbfSSuraj Jitindar Singh 
43ddf0edbfSSuraj Jitindar Singh struct mboxctl_context {
44ddf0edbfSSuraj Jitindar Singh 	sd_bus *bus;
45ddf0edbfSSuraj Jitindar Singh };
46ddf0edbfSSuraj Jitindar Singh 
usage(char * name)47ddf0edbfSSuraj Jitindar Singh static void usage(char *name)
48ddf0edbfSSuraj Jitindar Singh {
49ddf0edbfSSuraj Jitindar Singh 	MSG_OUT(USAGE, name);
50ddf0edbfSSuraj Jitindar Singh 	exit(0);
51ddf0edbfSSuraj Jitindar Singh }
52ddf0edbfSSuraj Jitindar Singh 
init_mboxctl_dbus(struct mboxctl_context * context)53ddf0edbfSSuraj Jitindar Singh static int init_mboxctl_dbus(struct mboxctl_context *context)
54ddf0edbfSSuraj Jitindar Singh {
55ddf0edbfSSuraj Jitindar Singh 	int rc;
56ddf0edbfSSuraj Jitindar Singh 
57ddf0edbfSSuraj Jitindar Singh 	rc = sd_bus_default_system(&context->bus);
58ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
59ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to connect to the system bus: %s\n",
60ddf0edbfSSuraj Jitindar Singh 			strerror(-rc));
61ddf0edbfSSuraj Jitindar Singh 	}
62ddf0edbfSSuraj Jitindar Singh 
63ddf0edbfSSuraj Jitindar Singh 	return rc;
64ddf0edbfSSuraj Jitindar Singh }
65ddf0edbfSSuraj Jitindar Singh 
mboxctl_directive(struct mboxctl_context * context,const char * cmd)66fbf74549SAndrew Jeffery static int mboxctl_directive(struct mboxctl_context *context, const char *cmd)
67fbf74549SAndrew Jeffery {
68fbf74549SAndrew Jeffery 	sd_bus_error error = SD_BUS_ERROR_NULL;
69fbf74549SAndrew Jeffery 	sd_bus_message *m = NULL;
70fbf74549SAndrew Jeffery 	int rc;
71fbf74549SAndrew Jeffery 
72fbf74549SAndrew Jeffery 	rc = sd_bus_message_new_method_call(context->bus, &m,
73fbf74549SAndrew Jeffery 					    MBOX_DBUS_NAME,
74fbf74549SAndrew Jeffery 					    MBOX_DBUS_OBJECT,
75fbf74549SAndrew Jeffery 					    MBOX_DBUS_CONTROL_IFACE,
76fbf74549SAndrew Jeffery 					    cmd);
77fbf74549SAndrew Jeffery 	if (rc < 0) {
78fbf74549SAndrew Jeffery 		MSG_ERR("Failed to init method call: %s\n",
79fbf74549SAndrew Jeffery 			strerror(-rc));
80fbf74549SAndrew Jeffery 		goto out;
81fbf74549SAndrew Jeffery 	}
82fbf74549SAndrew Jeffery 
83fbf74549SAndrew Jeffery 	rc = sd_bus_call(context->bus, m, 0, &error, NULL);
84fbf74549SAndrew Jeffery 	if (rc < 0) {
85fbf74549SAndrew Jeffery 		MSG_ERR("Failed to post message: %s\n", strerror(-rc));
86fbf74549SAndrew Jeffery 	}
87fbf74549SAndrew Jeffery 
88fbf74549SAndrew Jeffery out:
89fbf74549SAndrew Jeffery 	sd_bus_error_free(&error);
90fbf74549SAndrew Jeffery 	sd_bus_message_unref(m);
91fbf74549SAndrew Jeffery 
92fbf74549SAndrew Jeffery 	return rc < 0 ? rc : 0;
93fbf74549SAndrew Jeffery }
94fbf74549SAndrew Jeffery 
mboxctl_getter(struct mboxctl_context * context,const char * property,uint8_t * resp)95*a804a73cSAndrew Jeffery static int mboxctl_getter(struct mboxctl_context *context,
96*a804a73cSAndrew Jeffery 			  const char *property, uint8_t *resp)
97ddf0edbfSSuraj Jitindar Singh {
98ddf0edbfSSuraj Jitindar Singh 	sd_bus_error error = SD_BUS_ERROR_NULL;
99ddf0edbfSSuraj Jitindar Singh 
100*a804a73cSAndrew Jeffery 	return sd_bus_get_property_trivial(context->bus, MBOX_DBUS_NAME,
101fbf74549SAndrew Jeffery 					   MBOX_DBUS_OBJECT,
102fbf74549SAndrew Jeffery 					   MBOX_DBUS_CONTROL_IFACE,
103*a804a73cSAndrew Jeffery 					   property, &error, 'y', resp);
104fbf74549SAndrew Jeffery }
105fbf74549SAndrew Jeffery 
handle_cmd_ping(struct mboxctl_context * context)106fbf74549SAndrew Jeffery static int handle_cmd_ping(struct mboxctl_context *context)
107fbf74549SAndrew Jeffery {
108fbf74549SAndrew Jeffery 	int rc;
109fbf74549SAndrew Jeffery 
110fbf74549SAndrew Jeffery 	rc = mboxctl_directive(context, "Ping");
111fbf74549SAndrew Jeffery 	MSG_OUT("Ping: %s\n", rc ? strerror(-rc) : "Success");
112fbf74549SAndrew Jeffery 
113fbf74549SAndrew Jeffery 	return rc;
114fbf74549SAndrew Jeffery }
115fbf74549SAndrew Jeffery 
handle_cmd_daemon_state(struct mboxctl_context * context)116fbf74549SAndrew Jeffery static int handle_cmd_daemon_state(struct mboxctl_context *context)
117fbf74549SAndrew Jeffery {
118fbf74549SAndrew Jeffery 	uint8_t resp;
119fbf74549SAndrew Jeffery 	int rc;
120fbf74549SAndrew Jeffery 
121*a804a73cSAndrew Jeffery 	rc = mboxctl_getter(context, "DaemonState", &resp);
122fbf74549SAndrew Jeffery 	if (rc < 0)
123fbf74549SAndrew Jeffery 		return rc;
124fbf74549SAndrew Jeffery 
125fbf74549SAndrew Jeffery 	MSG_OUT("Daemon State: %s\n", resp == DAEMON_STATE_ACTIVE ?
126fbf74549SAndrew Jeffery 				      "Active" : "Suspended");
127fbf74549SAndrew Jeffery 	return 0;
128fbf74549SAndrew Jeffery }
129fbf74549SAndrew Jeffery 
handle_cmd_lpc_state(struct mboxctl_context * context)130fbf74549SAndrew Jeffery static int handle_cmd_lpc_state(struct mboxctl_context *context)
131fbf74549SAndrew Jeffery {
132fbf74549SAndrew Jeffery 	uint8_t resp;
133fbf74549SAndrew Jeffery 	int rc;
134fbf74549SAndrew Jeffery 
135*a804a73cSAndrew Jeffery 	rc = mboxctl_getter(context, "LpcState", &resp);
136fbf74549SAndrew Jeffery 	if (rc < 0)
137fbf74549SAndrew Jeffery 		return rc;
138fbf74549SAndrew Jeffery 
139fbf74549SAndrew Jeffery 	MSG_OUT("LPC Bus Maps: %s\n", resp == LPC_STATE_MEM ?
140fbf74549SAndrew Jeffery 				      "BMC Memory" :
141fbf74549SAndrew Jeffery 				      (resp == LPC_STATE_FLASH ?
142fbf74549SAndrew Jeffery 				       "Flash Device" :
143fbf74549SAndrew Jeffery 				       "Invalid System State"));
144fbf74549SAndrew Jeffery 
145fbf74549SAndrew Jeffery 	return 0;
146fbf74549SAndrew Jeffery }
147fbf74549SAndrew Jeffery 
handle_cmd_kill(struct mboxctl_context * context)148fbf74549SAndrew Jeffery static int handle_cmd_kill(struct mboxctl_context *context)
149fbf74549SAndrew Jeffery {
150fbf74549SAndrew Jeffery 	int rc;
151fbf74549SAndrew Jeffery 
152fbf74549SAndrew Jeffery 	rc = mboxctl_directive(context, "Kill");
153fbf74549SAndrew Jeffery 	MSG_OUT("Kill: %s\n", rc ? strerror(-rc) : "Success");
154fbf74549SAndrew Jeffery 
155fbf74549SAndrew Jeffery 	return rc;
156fbf74549SAndrew Jeffery }
157fbf74549SAndrew Jeffery 
handle_cmd_reset(struct mboxctl_context * context)158fbf74549SAndrew Jeffery static int handle_cmd_reset(struct mboxctl_context *context)
159fbf74549SAndrew Jeffery {
160fbf74549SAndrew Jeffery 	int rc;
161fbf74549SAndrew Jeffery 
162fbf74549SAndrew Jeffery 	rc = mboxctl_directive(context, "Reset");
163fbf74549SAndrew Jeffery 	MSG_OUT("Reset: %s\n", rc ? strerror(-rc) : "Success");
164fbf74549SAndrew Jeffery 
165fbf74549SAndrew Jeffery 	return rc;
166fbf74549SAndrew Jeffery }
167fbf74549SAndrew Jeffery 
handle_cmd_suspend(struct mboxctl_context * context)168fbf74549SAndrew Jeffery static int handle_cmd_suspend(struct mboxctl_context *context)
169fbf74549SAndrew Jeffery {
170fbf74549SAndrew Jeffery 	int rc;
171fbf74549SAndrew Jeffery 
172fbf74549SAndrew Jeffery 	rc = mboxctl_directive(context, "Suspend");
173fbf74549SAndrew Jeffery 	MSG_OUT("Suspend: %s\n", rc ? strerror(-rc) : "Success");
174fbf74549SAndrew Jeffery 
175fbf74549SAndrew Jeffery 	return rc;
176fbf74549SAndrew Jeffery }
177fbf74549SAndrew Jeffery 
handle_cmd_resume(struct mboxctl_context * context,char * sarg)178fbf74549SAndrew Jeffery static int handle_cmd_resume(struct mboxctl_context *context, char *sarg)
179fbf74549SAndrew Jeffery {
180fbf74549SAndrew Jeffery 	sd_bus_error error = SD_BUS_ERROR_NULL;
181fbf74549SAndrew Jeffery 	sd_bus_message *m = NULL, *n = NULL;
182fbf74549SAndrew Jeffery 	uint8_t arg;
183fbf74549SAndrew Jeffery 	int rc;
184fbf74549SAndrew Jeffery 
185fbf74549SAndrew Jeffery 	if (!sarg) {
186fbf74549SAndrew Jeffery 		MSG_ERR("Resume command takes an argument\n");
187fbf74549SAndrew Jeffery 		return -EINVAL;
188fbf74549SAndrew Jeffery 	}
189fbf74549SAndrew Jeffery 
190fbf74549SAndrew Jeffery 	rc = sd_bus_message_new_method_call(context->bus, &m,
191fbf74549SAndrew Jeffery 					    MBOX_DBUS_NAME,
192fbf74549SAndrew Jeffery 					    MBOX_DBUS_OBJECT,
193fbf74549SAndrew Jeffery 					    MBOX_DBUS_CONTROL_IFACE,
194fbf74549SAndrew Jeffery 					    "Resume");
195ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
196ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to init method call: %s\n",
197ddf0edbfSSuraj Jitindar Singh 			strerror(-rc));
198ddf0edbfSSuraj Jitindar Singh 		goto out;
199ddf0edbfSSuraj Jitindar Singh 	}
200ddf0edbfSSuraj Jitindar Singh 
201fbf74549SAndrew Jeffery 	if (!strncmp(sarg, "clean", strlen("clean"))) {
202fbf74549SAndrew Jeffery 		arg = RESUME_NOT_MODIFIED;
203fbf74549SAndrew Jeffery 	} else if (!strncmp(sarg, "modified", strlen("modified"))) {
204fbf74549SAndrew Jeffery 		arg = RESUME_FLASH_MODIFIED;
205fbf74549SAndrew Jeffery 	} else {
206fbf74549SAndrew Jeffery 		MSG_ERR("Resume command takes argument < \"clean\" | "
207fbf74549SAndrew Jeffery 			"\"modified\" >\n");
208fbf74549SAndrew Jeffery 		rc = -EINVAL;
209ddf0edbfSSuraj Jitindar Singh 		goto out;
210ddf0edbfSSuraj Jitindar Singh 	}
211ddf0edbfSSuraj Jitindar Singh 
2126c4d8ba3SAndrew Jeffery 	rc = sd_bus_message_append(m, "b", arg);
213ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
214ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to add args to message: %s\n",
215ddf0edbfSSuraj Jitindar Singh 			strerror(-rc));
216ddf0edbfSSuraj Jitindar Singh 		goto out;
217ddf0edbfSSuraj Jitindar Singh 	}
218ddf0edbfSSuraj Jitindar Singh 
219ddf0edbfSSuraj Jitindar Singh 	rc = sd_bus_call(context->bus, m, 0, &error, &n);
220ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
221ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to post message: %s\n", strerror(-rc));
222ddf0edbfSSuraj Jitindar Singh 		goto out;
223ddf0edbfSSuraj Jitindar Singh 	}
224ddf0edbfSSuraj Jitindar Singh 
225fbf74549SAndrew Jeffery 	MSG_OUT("Resume: %s\n", rc < 0 ? strerror(-rc) : "Success");
226ddf0edbfSSuraj Jitindar Singh 
227ddf0edbfSSuraj Jitindar Singh out:
228ddf0edbfSSuraj Jitindar Singh 	sd_bus_error_free(&error);
229ddf0edbfSSuraj Jitindar Singh 	sd_bus_message_unref(m);
230ddf0edbfSSuraj Jitindar Singh 	sd_bus_message_unref(n);
231ddf0edbfSSuraj Jitindar Singh 
232fbf74549SAndrew Jeffery 	return rc < 0 ? rc : 0;
233ddf0edbfSSuraj Jitindar Singh }
234ddf0edbfSSuraj Jitindar Singh 
handle_cmd_modified(struct mboxctl_context * context)235ddf0edbfSSuraj Jitindar Singh static int handle_cmd_modified(struct mboxctl_context *context)
236ddf0edbfSSuraj Jitindar Singh {
237ddf0edbfSSuraj Jitindar Singh 	int rc;
238ddf0edbfSSuraj Jitindar Singh 
239fbf74549SAndrew Jeffery 	rc = mboxctl_directive(context, "MarkFlashModified");
240fbf74549SAndrew Jeffery 	MSG_OUT("Clear Cache: %s\n", rc ? strerror(-rc) : "Success");
241ddf0edbfSSuraj Jitindar Singh 
242ddf0edbfSSuraj Jitindar Singh 	return rc;
243ddf0edbfSSuraj Jitindar Singh }
244ddf0edbfSSuraj Jitindar Singh 
handle_cmd_backend(struct mboxctl_context * context,char * sarg)2455320f6e0SAndrew Jeffery static int handle_cmd_backend(struct mboxctl_context *context, char *sarg)
2465320f6e0SAndrew Jeffery {
2475320f6e0SAndrew Jeffery 	sd_bus_error error = SD_BUS_ERROR_NULL;
2485320f6e0SAndrew Jeffery 	sd_bus_message *m = NULL, *n = NULL;
2495320f6e0SAndrew Jeffery 	char *delim = NULL;
2505320f6e0SAndrew Jeffery 	char *strv[2];
2515320f6e0SAndrew Jeffery 	int rc;
2525320f6e0SAndrew Jeffery 
2535320f6e0SAndrew Jeffery 	if (!sarg) {
2545320f6e0SAndrew Jeffery 		MSG_ERR("Backend command takes an argument\n");
2555320f6e0SAndrew Jeffery 		return -EINVAL;
2565320f6e0SAndrew Jeffery 	}
2575320f6e0SAndrew Jeffery 
2585320f6e0SAndrew Jeffery 	rc = sd_bus_message_new_method_call(context->bus, &m,
2595320f6e0SAndrew Jeffery 					    MBOX_DBUS_NAME,
2605320f6e0SAndrew Jeffery 					    MBOX_DBUS_OBJECT,
2615320f6e0SAndrew Jeffery 					    MBOX_DBUS_CONTROL_IFACE,
2625320f6e0SAndrew Jeffery 					    "SetBackend");
2635320f6e0SAndrew Jeffery 	if (rc < 0) {
2645320f6e0SAndrew Jeffery 		MSG_ERR("Failed to init method call: %s\n",
2655320f6e0SAndrew Jeffery 			strerror(-rc));
2665320f6e0SAndrew Jeffery 		goto out;
2675320f6e0SAndrew Jeffery 	}
2685320f6e0SAndrew Jeffery 
2695320f6e0SAndrew Jeffery 	if (!strncmp(sarg, "vpnor", strlen("vpnor"))) {
2705320f6e0SAndrew Jeffery 		if (strchr(sarg, ':')) {
2715320f6e0SAndrew Jeffery 			MSG_ERR("Path parameter not supported for vpnor\n");
2725320f6e0SAndrew Jeffery 			rc = -EINVAL;
2735320f6e0SAndrew Jeffery 			goto out;
2745320f6e0SAndrew Jeffery 		}
2755320f6e0SAndrew Jeffery 
2765320f6e0SAndrew Jeffery 		rc = sd_bus_message_append(m, "s", "vpnor");
2775320f6e0SAndrew Jeffery 		if (rc < 0)
2785320f6e0SAndrew Jeffery 			goto out;
2795320f6e0SAndrew Jeffery 	} else if (!strncmp(sarg, "mtd", strlen("mtd"))) {
2805320f6e0SAndrew Jeffery 		rc = sd_bus_message_append(m, "s", "mtd");
2815320f6e0SAndrew Jeffery 		if (rc < 0)
2825320f6e0SAndrew Jeffery 			goto out;
2835320f6e0SAndrew Jeffery 	} else if (!strncmp(sarg, "file", strlen("file"))) {
2845320f6e0SAndrew Jeffery 		rc = sd_bus_message_append(m, "s", "file");
2855320f6e0SAndrew Jeffery 		if (rc < 0)
2865320f6e0SAndrew Jeffery 			goto out;
2875320f6e0SAndrew Jeffery 	} else {
2885320f6e0SAndrew Jeffery 		rc = -EINVAL;
2895320f6e0SAndrew Jeffery 		goto out;
2905320f6e0SAndrew Jeffery 	}
2915320f6e0SAndrew Jeffery 
2925320f6e0SAndrew Jeffery 	delim = strchr(sarg, ':');
2935320f6e0SAndrew Jeffery 	if (delim) {
2945320f6e0SAndrew Jeffery 		char *path;
2955320f6e0SAndrew Jeffery 
2965320f6e0SAndrew Jeffery 		path = realpath(delim + 1, NULL);
2975320f6e0SAndrew Jeffery 		if (!path) {
2985320f6e0SAndrew Jeffery 			MSG_ERR("Failed to resolve path: %s\n",
2995320f6e0SAndrew Jeffery 					strerror(errno));
3005320f6e0SAndrew Jeffery 			rc = -errno;
3015320f6e0SAndrew Jeffery 			goto out;
3025320f6e0SAndrew Jeffery 		}
3035320f6e0SAndrew Jeffery 
3045320f6e0SAndrew Jeffery 		strv[0] = path;
3055320f6e0SAndrew Jeffery 		strv[1] = NULL;
3065320f6e0SAndrew Jeffery 
3075320f6e0SAndrew Jeffery 		rc = sd_bus_message_append_strv(m, &strv[0]);
3085320f6e0SAndrew Jeffery 		free(path);
3095320f6e0SAndrew Jeffery 		if (rc < 0)
3105320f6e0SAndrew Jeffery 			goto out;
3115320f6e0SAndrew Jeffery 	} else {
3125320f6e0SAndrew Jeffery 		strv[0] = NULL;
3135320f6e0SAndrew Jeffery 		strv[1] = NULL;
3145320f6e0SAndrew Jeffery 		rc = sd_bus_message_append_strv(m, &strv[0]);
3155320f6e0SAndrew Jeffery 		if (rc < 0)
3165320f6e0SAndrew Jeffery 			goto out;
3175320f6e0SAndrew Jeffery 	}
3185320f6e0SAndrew Jeffery 
3195320f6e0SAndrew Jeffery 	rc = sd_bus_call(context->bus, m, 0, &error, &n);
3205320f6e0SAndrew Jeffery 	if (rc < 0) {
3215320f6e0SAndrew Jeffery 		MSG_ERR("Failed to post message: %s\n", strerror(-rc));
3225320f6e0SAndrew Jeffery 		goto out;
3235320f6e0SAndrew Jeffery 	}
3245320f6e0SAndrew Jeffery 
3255320f6e0SAndrew Jeffery 	MSG_OUT("SetBackend: %s\n", rc < 0 ? strerror(-rc) : "Success");
3265320f6e0SAndrew Jeffery 
3275320f6e0SAndrew Jeffery out:
3285320f6e0SAndrew Jeffery 	sd_bus_error_free(&error);
3295320f6e0SAndrew Jeffery 	sd_bus_message_unref(m);
3305320f6e0SAndrew Jeffery 
3315320f6e0SAndrew Jeffery 	return rc < 0 ? rc : 0;
3325320f6e0SAndrew Jeffery }
3335320f6e0SAndrew Jeffery 
parse_cmdline(struct mboxctl_context * context,int argc,char ** argv)334ddf0edbfSSuraj Jitindar Singh static int parse_cmdline(struct mboxctl_context *context, int argc, char **argv)
335ddf0edbfSSuraj Jitindar Singh {
336ddf0edbfSSuraj Jitindar Singh 	int opt, rc = -1;
337ddf0edbfSSuraj Jitindar Singh 
338ddf0edbfSSuraj Jitindar Singh 	static const struct option long_options[] = {
339ddf0edbfSSuraj Jitindar Singh 		{ "silent",		no_argument,		0, 's' },
340ddf0edbfSSuraj Jitindar Singh 		{ "ping",		no_argument,		0, 'p' },
341ddf0edbfSSuraj Jitindar Singh 		{ "daemon-state",	no_argument,		0, 'd' },
342ddf0edbfSSuraj Jitindar Singh 		{ "lpc-state",		no_argument,		0, 'l' },
343ddf0edbfSSuraj Jitindar Singh 		{ "kill",		no_argument,		0, 'k' },
344ddf0edbfSSuraj Jitindar Singh 		{ "reset",		no_argument,		0, 'r' },
345ddf0edbfSSuraj Jitindar Singh 		{ "point-to-flash",	no_argument,		0, 'f' },
346ddf0edbfSSuraj Jitindar Singh 		{ "suspend",		no_argument,		0, 'u' },
347ddf0edbfSSuraj Jitindar Singh 		{ "resume",		required_argument,	0, 'e' },
348ddf0edbfSSuraj Jitindar Singh 		{ "clear-cache",	no_argument,		0, 'c' },
3495320f6e0SAndrew Jeffery 		{ "backend",		required_argument,	0, 'b' },
350ddf0edbfSSuraj Jitindar Singh 		{ "version",		no_argument,		0, 'v' },
351ddf0edbfSSuraj Jitindar Singh 		{ "help",		no_argument,		0, 'h' },
352ddf0edbfSSuraj Jitindar Singh 		{ 0,			0,			0, 0   }
353ddf0edbfSSuraj Jitindar Singh 	};
354ddf0edbfSSuraj Jitindar Singh 
355ddf0edbfSSuraj Jitindar Singh 	if (argc <= 1) {
356ddf0edbfSSuraj Jitindar Singh 		usage(argv[0]);
357fbf74549SAndrew Jeffery 		return -EINVAL;
358ddf0edbfSSuraj Jitindar Singh 	}
359ddf0edbfSSuraj Jitindar Singh 
360ddf0edbfSSuraj Jitindar Singh 	while ((opt = getopt_long(argc, argv, "spdlkrfue:cvh", long_options,
361ddf0edbfSSuraj Jitindar Singh 				  NULL)) != -1) {
362ddf0edbfSSuraj Jitindar Singh 		switch (opt) {
363ddf0edbfSSuraj Jitindar Singh 		case 's':
364ddf0edbfSSuraj Jitindar Singh 			silent = true;
365ddf0edbfSSuraj Jitindar Singh 			continue;
366ddf0edbfSSuraj Jitindar Singh 		case 'p':
367ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_ping(context);
368ddf0edbfSSuraj Jitindar Singh 			break;
369ddf0edbfSSuraj Jitindar Singh 		case 'd':
370ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_daemon_state(context);
371ddf0edbfSSuraj Jitindar Singh 			break;
372ddf0edbfSSuraj Jitindar Singh 		case 'l':
373ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_lpc_state(context);
374ddf0edbfSSuraj Jitindar Singh 			break;
375ddf0edbfSSuraj Jitindar Singh 		case 'k':
376ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_kill(context);
377ddf0edbfSSuraj Jitindar Singh 			break;
378ddf0edbfSSuraj Jitindar Singh 		case 'r': /* These are the same for now (reset may change) */
379ddf0edbfSSuraj Jitindar Singh 		case 'f':
380ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_reset(context);
381ddf0edbfSSuraj Jitindar Singh 			break;
382ddf0edbfSSuraj Jitindar Singh 		case 'u':
383ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_suspend(context);
384ddf0edbfSSuraj Jitindar Singh 			break;
385ddf0edbfSSuraj Jitindar Singh 		case 'e':
386ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_resume(context, optarg);
387ddf0edbfSSuraj Jitindar Singh 			break;
388ddf0edbfSSuraj Jitindar Singh 		case 'c':
389ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_modified(context);
390ddf0edbfSSuraj Jitindar Singh 			break;
3915320f6e0SAndrew Jeffery 		case 'b':
3925320f6e0SAndrew Jeffery 			rc = handle_cmd_backend(context, optarg);
3935320f6e0SAndrew Jeffery 			break;
394ddf0edbfSSuraj Jitindar Singh 		case 'v':
3958d65bb44SSuraj Jitindar Singh 			MSG_OUT("%s V%s\n", NAME, PACKAGE_VERSION);
396ddf0edbfSSuraj Jitindar Singh 			rc = 0;
397ddf0edbfSSuraj Jitindar Singh 			break;
398ddf0edbfSSuraj Jitindar Singh 		case 'h':
399ddf0edbfSSuraj Jitindar Singh 			usage(argv[0]);
400ddf0edbfSSuraj Jitindar Singh 			rc = 0;
401ddf0edbfSSuraj Jitindar Singh 			break;
402ddf0edbfSSuraj Jitindar Singh 		default:
403ddf0edbfSSuraj Jitindar Singh 			usage(argv[0]);
404fbf74549SAndrew Jeffery 			rc = -EINVAL;
405ddf0edbfSSuraj Jitindar Singh 			break;
406ddf0edbfSSuraj Jitindar Singh 		}
407ddf0edbfSSuraj Jitindar Singh 	}
408ddf0edbfSSuraj Jitindar Singh 
409ddf0edbfSSuraj Jitindar Singh 	return rc;
410ddf0edbfSSuraj Jitindar Singh }
411ddf0edbfSSuraj Jitindar Singh 
main(int argc,char ** argv)412ddf0edbfSSuraj Jitindar Singh int main(int argc, char **argv)
413ddf0edbfSSuraj Jitindar Singh {
414ddf0edbfSSuraj Jitindar Singh 	struct mboxctl_context context;
415ddf0edbfSSuraj Jitindar Singh 	int rc;
416ddf0edbfSSuraj Jitindar Singh 
417ddf0edbfSSuraj Jitindar Singh 	silent = false;
418ddf0edbfSSuraj Jitindar Singh 
419ddf0edbfSSuraj Jitindar Singh 	rc = init_mboxctl_dbus(&context);
420ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
421ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to init dbus\n");
422ddf0edbfSSuraj Jitindar Singh 		return rc;
423ddf0edbfSSuraj Jitindar Singh 	}
424ddf0edbfSSuraj Jitindar Singh 
425ddf0edbfSSuraj Jitindar Singh 	rc = parse_cmdline(&context, argc, argv);
426ddf0edbfSSuraj Jitindar Singh 
427ddf0edbfSSuraj Jitindar Singh 	return rc;
428ddf0edbfSSuraj Jitindar Singh }
429