xref: /openbmc/phosphor-mboxd/mboxctl.c (revision 4fe996c2e7f157d521b5c8732e8b80e03bd25ff0)
1*4fe996c2SAndrew Jeffery // SPDX-License-Identifier: Apache-2.0
2*4fe996c2SAndrew Jeffery // Copyright (C) 2018 IBM Corp.
3ddf0edbfSSuraj Jitindar Singh 
4ddf0edbfSSuraj Jitindar Singh #define _GNU_SOURCE
5ddf0edbfSSuraj Jitindar Singh #include <assert.h>
6ddf0edbfSSuraj Jitindar Singh #include <errno.h>
7ddf0edbfSSuraj Jitindar Singh #include <fcntl.h>
8ddf0edbfSSuraj Jitindar Singh #include <getopt.h>
9ddf0edbfSSuraj Jitindar Singh #include <limits.h>
10ddf0edbfSSuraj Jitindar Singh #include <poll.h>
11ddf0edbfSSuraj Jitindar Singh #include <stdbool.h>
12ddf0edbfSSuraj Jitindar Singh #include <stdint.h>
13ddf0edbfSSuraj Jitindar Singh #include <stdio.h>
14ddf0edbfSSuraj Jitindar Singh #include <stdlib.h>
15ddf0edbfSSuraj Jitindar Singh #include <string.h>
16ddf0edbfSSuraj Jitindar Singh #include <syslog.h>
17ddf0edbfSSuraj Jitindar Singh #include <signal.h>
18ddf0edbfSSuraj Jitindar Singh #include <sys/ioctl.h>
19ddf0edbfSSuraj Jitindar Singh #include <sys/mman.h>
20ddf0edbfSSuraj Jitindar Singh #include <sys/stat.h>
21ddf0edbfSSuraj Jitindar Singh #include <sys/timerfd.h>
22ddf0edbfSSuraj Jitindar Singh #include <sys/types.h>
23ddf0edbfSSuraj Jitindar Singh #include <time.h>
24ddf0edbfSSuraj Jitindar Singh #include <unistd.h>
25ddf0edbfSSuraj Jitindar Singh #include <inttypes.h>
26ddf0edbfSSuraj Jitindar Singh 
27ddf0edbfSSuraj Jitindar Singh #include <systemd/sd-bus.h>
28ddf0edbfSSuraj Jitindar Singh 
298d65bb44SSuraj Jitindar Singh #include "config.h"
30ddf0edbfSSuraj Jitindar Singh #include "dbus.h"
31ddf0edbfSSuraj Jitindar Singh 
32ddf0edbfSSuraj Jitindar Singh #define USAGE \
33ddf0edbfSSuraj Jitindar Singh "\nUsage: %s [--silent | -s] <command> [args]\n\n" \
34ddf0edbfSSuraj Jitindar Singh "\t\t--silent\t\t- no output on the command line\n\n" \
35ddf0edbfSSuraj Jitindar Singh "\tCommands: (num args)\n" \
36ddf0edbfSSuraj Jitindar Singh "\t\t--ping\t\t\t- ping the daemon (0)\n" \
37ddf0edbfSSuraj Jitindar Singh "\t\t--daemon-state\t\t- check state of the daemon (0)\n" \
38ddf0edbfSSuraj Jitindar Singh "\t\t--lpc-state\t\t- check the state of the lpc mapping (0)\n" \
39ddf0edbfSSuraj Jitindar Singh "\t\t--kill\t\t\t- stop the daemon [no flush] (0)\n" \
40ddf0edbfSSuraj Jitindar Singh "\t\t--reset\t\t\t- hard reset the daemon state (0)\n" \
41ddf0edbfSSuraj Jitindar Singh "\t\t--point-to-flash\t- point the lpc mapping back to flash (0)\n" \
42ddf0edbfSSuraj Jitindar Singh "\t\t--suspend\t\t- suspend the daemon to inhibit flash accesses (0)\n" \
43ddf0edbfSSuraj Jitindar Singh "\t\t--resume\t\t- resume the daemon (1)\n" \
44ddf0edbfSSuraj Jitindar Singh "\t\t\targ[0]: < \"clean\" | \"modified\" >\n" \
45ddf0edbfSSuraj Jitindar Singh "\t\t--clear-cache\t- tell the daemon to discard any caches (0)\n"
46ddf0edbfSSuraj Jitindar Singh 
478d65bb44SSuraj Jitindar Singh #define NAME		"Mailbox Control"
48ddf0edbfSSuraj Jitindar Singh 
49ddf0edbfSSuraj Jitindar Singh static bool silent;
50ddf0edbfSSuraj Jitindar Singh 
51ddf0edbfSSuraj Jitindar Singh #define MSG_OUT(...)	do { if (!silent) { \
52ddf0edbfSSuraj Jitindar Singh 				fprintf(stdout, __VA_ARGS__); } \
53ddf0edbfSSuraj Jitindar Singh 			} while (0)
54ddf0edbfSSuraj Jitindar Singh #define MSG_ERR(...)	do { if (!silent) { \
55ddf0edbfSSuraj Jitindar Singh 				fprintf(stderr, __VA_ARGS__); } \
56ddf0edbfSSuraj Jitindar Singh 			} while (0)
57ddf0edbfSSuraj Jitindar Singh 
58ddf0edbfSSuraj Jitindar Singh struct mboxctl_context {
59ddf0edbfSSuraj Jitindar Singh 	sd_bus *bus;
60ddf0edbfSSuraj Jitindar Singh };
61ddf0edbfSSuraj Jitindar Singh 
usage(char * name)62ddf0edbfSSuraj Jitindar Singh static void usage(char *name)
63ddf0edbfSSuraj Jitindar Singh {
64ddf0edbfSSuraj Jitindar Singh 	MSG_OUT(USAGE, name);
65ddf0edbfSSuraj Jitindar Singh 	exit(0);
66ddf0edbfSSuraj Jitindar Singh }
67ddf0edbfSSuraj Jitindar Singh 
68ddf0edbfSSuraj Jitindar Singh static const char *dbus_err_str[] = {
69ddf0edbfSSuraj Jitindar Singh 	"Success",
70ddf0edbfSSuraj Jitindar Singh 	"Failed - Internal Error",
71ddf0edbfSSuraj Jitindar Singh 	"Failed - Invalid Command or Request",
72ddf0edbfSSuraj Jitindar Singh 	"Failed - Request Rejected by Daemon",
73ddf0edbfSSuraj Jitindar Singh 	"Failed - BMC Hardware Error",
74ddf0edbfSSuraj Jitindar Singh 	"Failed - Insufficient Memory for Allocation Request"
75ddf0edbfSSuraj Jitindar Singh };
76ddf0edbfSSuraj Jitindar Singh 
init_mboxctl_dbus(struct mboxctl_context * context)77ddf0edbfSSuraj Jitindar Singh static int init_mboxctl_dbus(struct mboxctl_context *context)
78ddf0edbfSSuraj Jitindar Singh {
79ddf0edbfSSuraj Jitindar Singh 	int rc;
80ddf0edbfSSuraj Jitindar Singh 
81ddf0edbfSSuraj Jitindar Singh 	rc = sd_bus_default_system(&context->bus);
82ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
83ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to connect to the system bus: %s\n",
84ddf0edbfSSuraj Jitindar Singh 			strerror(-rc));
85ddf0edbfSSuraj Jitindar Singh 	}
86ddf0edbfSSuraj Jitindar Singh 
87ddf0edbfSSuraj Jitindar Singh 	return rc;
88ddf0edbfSSuraj Jitindar Singh }
89ddf0edbfSSuraj Jitindar Singh 
send_dbus_msg(struct mboxctl_context * context,struct mbox_dbus_msg * msg,struct mbox_dbus_msg * resp)90ddf0edbfSSuraj Jitindar Singh static int send_dbus_msg(struct mboxctl_context *context,
91ddf0edbfSSuraj Jitindar Singh 			 struct mbox_dbus_msg *msg,
92ddf0edbfSSuraj Jitindar Singh 			 struct mbox_dbus_msg *resp)
93ddf0edbfSSuraj Jitindar Singh {
94ddf0edbfSSuraj Jitindar Singh 	sd_bus_error error = SD_BUS_ERROR_NULL;
95ddf0edbfSSuraj Jitindar Singh 	sd_bus_message *m = NULL, *n = NULL;
96ddf0edbfSSuraj Jitindar Singh 	uint8_t *buf;
97ddf0edbfSSuraj Jitindar Singh 	size_t sz;
98ddf0edbfSSuraj Jitindar Singh 	int rc;
99ddf0edbfSSuraj Jitindar Singh 
100ddf0edbfSSuraj Jitindar Singh 	/* Generate the bus message */
101ddf0edbfSSuraj Jitindar Singh 	rc = sd_bus_message_new_method_call(context->bus, &m, DBUS_NAME,
102ddf0edbfSSuraj Jitindar Singh 					    DOBJ_NAME, DBUS_NAME, "cmd");
103ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
104ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to init method call: %s\n",
105ddf0edbfSSuraj Jitindar Singh 			strerror(-rc));
106ddf0edbfSSuraj Jitindar Singh 		rc = -E_DBUS_INTERNAL;
107ddf0edbfSSuraj Jitindar Singh 		goto out;
108ddf0edbfSSuraj Jitindar Singh 	}
109ddf0edbfSSuraj Jitindar Singh 
110ddf0edbfSSuraj Jitindar Singh 	/* Add the command */
111ddf0edbfSSuraj Jitindar Singh 	rc = sd_bus_message_append(m, "y", msg->cmd);
112ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
113ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to add cmd to message: %s\n",
114ddf0edbfSSuraj Jitindar Singh 			strerror(-rc));
115ddf0edbfSSuraj Jitindar Singh 		rc = -E_DBUS_INTERNAL;
116ddf0edbfSSuraj Jitindar Singh 		goto out;
117ddf0edbfSSuraj Jitindar Singh 	}
118ddf0edbfSSuraj Jitindar Singh 
119ddf0edbfSSuraj Jitindar Singh 	/* Add the args */
120ddf0edbfSSuraj Jitindar Singh 	rc = sd_bus_message_append_array(m, 'y', msg->args, msg->num_args);
121ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
122ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to add args to message: %s\n",
123ddf0edbfSSuraj Jitindar Singh 			strerror(-rc));
124ddf0edbfSSuraj Jitindar Singh 		rc = -E_DBUS_INTERNAL;
125ddf0edbfSSuraj Jitindar Singh 		goto out;
126ddf0edbfSSuraj Jitindar Singh 	}
127ddf0edbfSSuraj Jitindar Singh 
128ddf0edbfSSuraj Jitindar Singh 	/* Send the message */
129ddf0edbfSSuraj Jitindar Singh 	rc = sd_bus_call(context->bus, m, 0, &error, &n);
130ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
131ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to post message: %s\n", strerror(-rc));
132ddf0edbfSSuraj Jitindar Singh 		rc = -E_DBUS_INTERNAL;
133ddf0edbfSSuraj Jitindar Singh 		goto out;
134ddf0edbfSSuraj Jitindar Singh 	}
135ddf0edbfSSuraj Jitindar Singh 
136ddf0edbfSSuraj Jitindar Singh 	/* Read response code */
137ddf0edbfSSuraj Jitindar Singh 	rc = sd_bus_message_read(n, "y", &resp->cmd);
138ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
139ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to read response code: %s\n",
140ddf0edbfSSuraj Jitindar Singh 			strerror(-rc));
141ddf0edbfSSuraj Jitindar Singh 		rc = -E_DBUS_INTERNAL;
142ddf0edbfSSuraj Jitindar Singh 		goto out;
143ddf0edbfSSuraj Jitindar Singh 	}
144ddf0edbfSSuraj Jitindar Singh 
145ddf0edbfSSuraj Jitindar Singh 	/* Read response args */
146ddf0edbfSSuraj Jitindar Singh 	rc = sd_bus_message_read_array(n, 'y', (const void **) &buf, &sz);
147ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
148ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to read response args: %s\n",
149ddf0edbfSSuraj Jitindar Singh 			strerror(-rc));
150ddf0edbfSSuraj Jitindar Singh 		rc = -E_DBUS_INTERNAL;
151ddf0edbfSSuraj Jitindar Singh 		goto out;
152ddf0edbfSSuraj Jitindar Singh 	}
153ddf0edbfSSuraj Jitindar Singh 
154ddf0edbfSSuraj Jitindar Singh 	if (sz < resp->num_args) {
155ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Command returned insufficient response args\n");
156ddf0edbfSSuraj Jitindar Singh 		rc = -E_DBUS_INTERNAL;
157ddf0edbfSSuraj Jitindar Singh 		goto out;
158ddf0edbfSSuraj Jitindar Singh 	}
159ddf0edbfSSuraj Jitindar Singh 
160ddf0edbfSSuraj Jitindar Singh 	memcpy(resp->args, buf, resp->num_args);
161ddf0edbfSSuraj Jitindar Singh 	rc = 0;
162ddf0edbfSSuraj Jitindar Singh 
163ddf0edbfSSuraj Jitindar Singh out:
164ddf0edbfSSuraj Jitindar Singh 	sd_bus_error_free(&error);
165ddf0edbfSSuraj Jitindar Singh 	sd_bus_message_unref(m);
166ddf0edbfSSuraj Jitindar Singh 	sd_bus_message_unref(n);
167ddf0edbfSSuraj Jitindar Singh 
168ddf0edbfSSuraj Jitindar Singh 	return rc;
169ddf0edbfSSuraj Jitindar Singh }
170ddf0edbfSSuraj Jitindar Singh 
handle_cmd_ping(struct mboxctl_context * context)171ddf0edbfSSuraj Jitindar Singh static int handle_cmd_ping(struct mboxctl_context *context)
172ddf0edbfSSuraj Jitindar Singh {
173ddf0edbfSSuraj Jitindar Singh 	struct mbox_dbus_msg msg = { 0 }, resp = { 0 };
174ddf0edbfSSuraj Jitindar Singh 	int rc;
175ddf0edbfSSuraj Jitindar Singh 
176ddf0edbfSSuraj Jitindar Singh 	msg.cmd = DBUS_C_PING;
177ddf0edbfSSuraj Jitindar Singh 
178ddf0edbfSSuraj Jitindar Singh 	rc = send_dbus_msg(context, &msg, &resp);
179ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
180ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to send ping command\n");
181ddf0edbfSSuraj Jitindar Singh 		return rc;
182ddf0edbfSSuraj Jitindar Singh 	}
183ddf0edbfSSuraj Jitindar Singh 
184ddf0edbfSSuraj Jitindar Singh 	rc = -resp.cmd;
185ddf0edbfSSuraj Jitindar Singh 	MSG_OUT("Ping: %s\n", dbus_err_str[-rc]);
186ddf0edbfSSuraj Jitindar Singh 
187ddf0edbfSSuraj Jitindar Singh 	return rc;
188ddf0edbfSSuraj Jitindar Singh }
189ddf0edbfSSuraj Jitindar Singh 
handle_cmd_daemon_state(struct mboxctl_context * context)190ddf0edbfSSuraj Jitindar Singh static int handle_cmd_daemon_state(struct mboxctl_context *context)
191ddf0edbfSSuraj Jitindar Singh {
192ddf0edbfSSuraj Jitindar Singh 	struct mbox_dbus_msg msg = { 0 }, resp = { 0 };
193ddf0edbfSSuraj Jitindar Singh 	int rc;
194ddf0edbfSSuraj Jitindar Singh 
195ddf0edbfSSuraj Jitindar Singh 	msg.cmd = DBUS_C_DAEMON_STATE;
196ddf0edbfSSuraj Jitindar Singh 	resp.num_args = DAEMON_STATE_NUM_ARGS;
197ddf0edbfSSuraj Jitindar Singh 	resp.args = calloc(resp.num_args, sizeof(*resp.args));
198ddf0edbfSSuraj Jitindar Singh 	if (!resp.args) {
199ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Memory allocation failed\n");
200ddf0edbfSSuraj Jitindar Singh 		return -E_DBUS_NO_MEM;
201ddf0edbfSSuraj Jitindar Singh 	}
202ddf0edbfSSuraj Jitindar Singh 
203ddf0edbfSSuraj Jitindar Singh 	rc = send_dbus_msg(context, &msg, &resp);
204ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
205ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to send daemon state command\n");
206ddf0edbfSSuraj Jitindar Singh 		goto out;
207ddf0edbfSSuraj Jitindar Singh 	}
208ddf0edbfSSuraj Jitindar Singh 
209ddf0edbfSSuraj Jitindar Singh 	rc = -resp.cmd;
210ddf0edbfSSuraj Jitindar Singh 	if (resp.cmd != DBUS_SUCCESS) {
211ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Daemon state command failed\n");
212ddf0edbfSSuraj Jitindar Singh 		goto out;
213ddf0edbfSSuraj Jitindar Singh 	}
214ddf0edbfSSuraj Jitindar Singh 
215ddf0edbfSSuraj Jitindar Singh 	MSG_OUT("Daemon State: %s\n", resp.args[0] == DAEMON_STATE_ACTIVE ?
216ddf0edbfSSuraj Jitindar Singh 				      "Active" : "Suspended");
217ddf0edbfSSuraj Jitindar Singh 
218ddf0edbfSSuraj Jitindar Singh out:
219ddf0edbfSSuraj Jitindar Singh 	free(resp.args);
220ddf0edbfSSuraj Jitindar Singh 	return rc;
221ddf0edbfSSuraj Jitindar Singh }
222ddf0edbfSSuraj Jitindar Singh 
handle_cmd_lpc_state(struct mboxctl_context * context)223ddf0edbfSSuraj Jitindar Singh static int handle_cmd_lpc_state(struct mboxctl_context *context)
224ddf0edbfSSuraj Jitindar Singh {
225ddf0edbfSSuraj Jitindar Singh 	struct mbox_dbus_msg msg = { 0 }, resp = { 0 };
226ddf0edbfSSuraj Jitindar Singh 	int rc;
227ddf0edbfSSuraj Jitindar Singh 
228ddf0edbfSSuraj Jitindar Singh 	msg.cmd = DBUS_C_LPC_STATE;
229ddf0edbfSSuraj Jitindar Singh 	resp.num_args = LPC_STATE_NUM_ARGS;
230ddf0edbfSSuraj Jitindar Singh 	resp.args = calloc(resp.num_args, sizeof(*resp.args));
231ddf0edbfSSuraj Jitindar Singh 	if (!resp.args) {
232ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Memory allocation failed\n");
233ddf0edbfSSuraj Jitindar Singh 		return -E_DBUS_NO_MEM;
234ddf0edbfSSuraj Jitindar Singh 	}
235ddf0edbfSSuraj Jitindar Singh 
236ddf0edbfSSuraj Jitindar Singh 	rc = send_dbus_msg(context, &msg, &resp);
237ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
238ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to send lpc state command\n");
239ddf0edbfSSuraj Jitindar Singh 		goto out;
240ddf0edbfSSuraj Jitindar Singh 	}
241ddf0edbfSSuraj Jitindar Singh 
242ddf0edbfSSuraj Jitindar Singh 	rc = -resp.cmd;
243ddf0edbfSSuraj Jitindar Singh 	if (resp.cmd != DBUS_SUCCESS) {
244ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("LPC state command failed\n");
245ddf0edbfSSuraj Jitindar Singh 		goto out;
246ddf0edbfSSuraj Jitindar Singh 	}
247ddf0edbfSSuraj Jitindar Singh 
248ddf0edbfSSuraj Jitindar Singh 	MSG_OUT("LPC Bus Maps: %s\n", resp.args[0] == LPC_STATE_MEM ?
249ddf0edbfSSuraj Jitindar Singh 				      "BMC Memory" :
250ddf0edbfSSuraj Jitindar Singh 				      (resp.args[0] == LPC_STATE_FLASH ?
251ddf0edbfSSuraj Jitindar Singh 				       "Flash Device" :
252ddf0edbfSSuraj Jitindar Singh 				       "Invalid System State"));
253ddf0edbfSSuraj Jitindar Singh 
254ddf0edbfSSuraj Jitindar Singh out:
255ddf0edbfSSuraj Jitindar Singh 	free(resp.args);
256ddf0edbfSSuraj Jitindar Singh 	return rc;
257ddf0edbfSSuraj Jitindar Singh }
258ddf0edbfSSuraj Jitindar Singh 
handle_cmd_kill(struct mboxctl_context * context)259ddf0edbfSSuraj Jitindar Singh static int handle_cmd_kill(struct mboxctl_context *context)
260ddf0edbfSSuraj Jitindar Singh {
261ddf0edbfSSuraj Jitindar Singh 	struct mbox_dbus_msg msg = { 0 }, resp = { 0 };
262ddf0edbfSSuraj Jitindar Singh 	int rc;
263ddf0edbfSSuraj Jitindar Singh 
264ddf0edbfSSuraj Jitindar Singh 	msg.cmd = DBUS_C_KILL;
265ddf0edbfSSuraj Jitindar Singh 
266ddf0edbfSSuraj Jitindar Singh 	rc = send_dbus_msg(context, &msg, &resp);
267ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
268ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to send kill command\n");
269ddf0edbfSSuraj Jitindar Singh 		return rc;
270ddf0edbfSSuraj Jitindar Singh 	}
271ddf0edbfSSuraj Jitindar Singh 
272ddf0edbfSSuraj Jitindar Singh 	rc = -resp.cmd;
273ddf0edbfSSuraj Jitindar Singh 	MSG_OUT("Kill: %s\n", dbus_err_str[-rc]);
274ddf0edbfSSuraj Jitindar Singh 
275ddf0edbfSSuraj Jitindar Singh 	return rc;
276ddf0edbfSSuraj Jitindar Singh }
277ddf0edbfSSuraj Jitindar Singh 
handle_cmd_reset(struct mboxctl_context * context)278ddf0edbfSSuraj Jitindar Singh static int handle_cmd_reset(struct mboxctl_context *context)
279ddf0edbfSSuraj Jitindar Singh {
280ddf0edbfSSuraj Jitindar Singh 	struct mbox_dbus_msg msg = { 0 }, resp = { 0 };
281ddf0edbfSSuraj Jitindar Singh 	int rc;
282ddf0edbfSSuraj Jitindar Singh 
283ddf0edbfSSuraj Jitindar Singh 	msg.cmd = DBUS_C_RESET;
284ddf0edbfSSuraj Jitindar Singh 
285ddf0edbfSSuraj Jitindar Singh 	rc = send_dbus_msg(context, &msg, &resp);
286ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
287ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to send reset command\n");
288ddf0edbfSSuraj Jitindar Singh 		return rc;
289ddf0edbfSSuraj Jitindar Singh 	}
290ddf0edbfSSuraj Jitindar Singh 
291ddf0edbfSSuraj Jitindar Singh 	rc = -resp.cmd;
292ddf0edbfSSuraj Jitindar Singh 	MSG_OUT("Reset: %s\n", dbus_err_str[-rc]);
293ddf0edbfSSuraj Jitindar Singh 
294ddf0edbfSSuraj Jitindar Singh 	return rc;
295ddf0edbfSSuraj Jitindar Singh }
296ddf0edbfSSuraj Jitindar Singh 
handle_cmd_suspend(struct mboxctl_context * context)297ddf0edbfSSuraj Jitindar Singh static int handle_cmd_suspend(struct mboxctl_context *context)
298ddf0edbfSSuraj Jitindar Singh {
299ddf0edbfSSuraj Jitindar Singh 	struct mbox_dbus_msg msg = { 0 }, resp = { 0 };
300ddf0edbfSSuraj Jitindar Singh 	int rc;
301ddf0edbfSSuraj Jitindar Singh 
302ddf0edbfSSuraj Jitindar Singh 	msg.cmd = DBUS_C_SUSPEND;
303ddf0edbfSSuraj Jitindar Singh 
304ddf0edbfSSuraj Jitindar Singh 	rc = send_dbus_msg(context, &msg, &resp);
305ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
306ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to send suspend command\n");
307ddf0edbfSSuraj Jitindar Singh 		return rc;
308ddf0edbfSSuraj Jitindar Singh 	}
309ddf0edbfSSuraj Jitindar Singh 
310ddf0edbfSSuraj Jitindar Singh 	rc = -resp.cmd;
311ddf0edbfSSuraj Jitindar Singh 	MSG_OUT("Suspend: %s\n", dbus_err_str[-rc]);
312ddf0edbfSSuraj Jitindar Singh 
313ddf0edbfSSuraj Jitindar Singh 	return rc;
314ddf0edbfSSuraj Jitindar Singh }
315ddf0edbfSSuraj Jitindar Singh 
handle_cmd_resume(struct mboxctl_context * context,char * arg)316ddf0edbfSSuraj Jitindar Singh static int handle_cmd_resume(struct mboxctl_context *context, char *arg)
317ddf0edbfSSuraj Jitindar Singh {
318ddf0edbfSSuraj Jitindar Singh 	struct mbox_dbus_msg msg = { 0 }, resp = { 0 };
319ddf0edbfSSuraj Jitindar Singh 	int rc;
320ddf0edbfSSuraj Jitindar Singh 
321ddf0edbfSSuraj Jitindar Singh 	if (!arg) {
322ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Resume command takes an argument\n");
323ddf0edbfSSuraj Jitindar Singh 		return -E_DBUS_INVAL;
324ddf0edbfSSuraj Jitindar Singh 	}
325ddf0edbfSSuraj Jitindar Singh 
326ddf0edbfSSuraj Jitindar Singh 	msg.cmd = DBUS_C_RESUME;
327ddf0edbfSSuraj Jitindar Singh 	msg.num_args = RESUME_NUM_ARGS;
328ddf0edbfSSuraj Jitindar Singh 	msg.args = calloc(msg.num_args, sizeof(*msg.args));
329ddf0edbfSSuraj Jitindar Singh 	if (!msg.args) {
330ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Memory allocation failed\n");
331ddf0edbfSSuraj Jitindar Singh 		return -E_DBUS_NO_MEM;
332ddf0edbfSSuraj Jitindar Singh 	}
333ddf0edbfSSuraj Jitindar Singh 
334ddf0edbfSSuraj Jitindar Singh 	if (!strncmp(arg, "clean", strlen("clean"))) {
335ddf0edbfSSuraj Jitindar Singh 		msg.args[0] = RESUME_NOT_MODIFIED;
336ddf0edbfSSuraj Jitindar Singh 	} else if (!strncmp(arg, "modified", strlen("modified"))) {
337ddf0edbfSSuraj Jitindar Singh 		msg.args[0] = RESUME_FLASH_MODIFIED;
338ddf0edbfSSuraj Jitindar Singh 	} else {
339ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Resume command takes argument < \"clean\" | "
340ddf0edbfSSuraj Jitindar Singh 			"\"modified\" >\n");
341ddf0edbfSSuraj Jitindar Singh 		rc = -E_DBUS_INVAL;
342ddf0edbfSSuraj Jitindar Singh 		goto out;
343ddf0edbfSSuraj Jitindar Singh 	}
344ddf0edbfSSuraj Jitindar Singh 
345ddf0edbfSSuraj Jitindar Singh 	rc = send_dbus_msg(context, &msg, &resp);
346ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
347ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to send resume command\n");
348ddf0edbfSSuraj Jitindar Singh 		goto out;
349ddf0edbfSSuraj Jitindar Singh 	}
350ddf0edbfSSuraj Jitindar Singh 
351ddf0edbfSSuraj Jitindar Singh 	rc = -resp.cmd;
352ddf0edbfSSuraj Jitindar Singh 	MSG_OUT("Resume: %s\n", dbus_err_str[-rc]);
353ddf0edbfSSuraj Jitindar Singh 
354ddf0edbfSSuraj Jitindar Singh out:
355ddf0edbfSSuraj Jitindar Singh 	free(msg.args);
356ddf0edbfSSuraj Jitindar Singh 	return rc;
357ddf0edbfSSuraj Jitindar Singh }
358ddf0edbfSSuraj Jitindar Singh 
handle_cmd_modified(struct mboxctl_context * context)359ddf0edbfSSuraj Jitindar Singh static int handle_cmd_modified(struct mboxctl_context *context)
360ddf0edbfSSuraj Jitindar Singh {
361ddf0edbfSSuraj Jitindar Singh 	struct mbox_dbus_msg msg = { 0 }, resp = { 0 };
362ddf0edbfSSuraj Jitindar Singh 	int rc;
363ddf0edbfSSuraj Jitindar Singh 
364ddf0edbfSSuraj Jitindar Singh 	msg.cmd = DBUS_C_MODIFIED;
365ddf0edbfSSuraj Jitindar Singh 
366ddf0edbfSSuraj Jitindar Singh 	rc = send_dbus_msg(context, &msg, &resp);
367ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
368ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to send flash modified command\n");
369ddf0edbfSSuraj Jitindar Singh 		return rc;
370ddf0edbfSSuraj Jitindar Singh 	}
371ddf0edbfSSuraj Jitindar Singh 
372ddf0edbfSSuraj Jitindar Singh 	rc = -resp.cmd;
373ddf0edbfSSuraj Jitindar Singh 	MSG_OUT("Clear Cache: %s\n", dbus_err_str[-rc]);
374ddf0edbfSSuraj Jitindar Singh 
375ddf0edbfSSuraj Jitindar Singh 	return rc;
376ddf0edbfSSuraj Jitindar Singh }
377ddf0edbfSSuraj Jitindar Singh 
parse_cmdline(struct mboxctl_context * context,int argc,char ** argv)378ddf0edbfSSuraj Jitindar Singh static int parse_cmdline(struct mboxctl_context *context, int argc, char **argv)
379ddf0edbfSSuraj Jitindar Singh {
380ddf0edbfSSuraj Jitindar Singh 	int opt, rc = -1;
381ddf0edbfSSuraj Jitindar Singh 
382ddf0edbfSSuraj Jitindar Singh 	static const struct option long_options[] = {
383ddf0edbfSSuraj Jitindar Singh 		{ "silent",		no_argument,		0, 's' },
384ddf0edbfSSuraj Jitindar Singh 		{ "ping",		no_argument,		0, 'p' },
385ddf0edbfSSuraj Jitindar Singh 		{ "daemon-state",	no_argument,		0, 'd' },
386ddf0edbfSSuraj Jitindar Singh 		{ "lpc-state",		no_argument,		0, 'l' },
387ddf0edbfSSuraj Jitindar Singh 		{ "kill",		no_argument,		0, 'k' },
388ddf0edbfSSuraj Jitindar Singh 		{ "reset",		no_argument,		0, 'r' },
389ddf0edbfSSuraj Jitindar Singh 		{ "point-to-flash",	no_argument,		0, 'f' },
390ddf0edbfSSuraj Jitindar Singh 		{ "suspend",		no_argument,		0, 'u' },
391ddf0edbfSSuraj Jitindar Singh 		{ "resume",		required_argument,	0, 'e' },
392ddf0edbfSSuraj Jitindar Singh 		{ "clear-cache",	no_argument,		0, 'c' },
393ddf0edbfSSuraj Jitindar Singh 		{ "version",		no_argument,		0, 'v' },
394ddf0edbfSSuraj Jitindar Singh 		{ "help",		no_argument,		0, 'h' },
395ddf0edbfSSuraj Jitindar Singh 		{ 0,			0,			0, 0   }
396ddf0edbfSSuraj Jitindar Singh 	};
397ddf0edbfSSuraj Jitindar Singh 
398ddf0edbfSSuraj Jitindar Singh 	if (argc <= 1) {
399ddf0edbfSSuraj Jitindar Singh 		usage(argv[0]);
400ddf0edbfSSuraj Jitindar Singh 		return -E_DBUS_INVAL;
401ddf0edbfSSuraj Jitindar Singh 	}
402ddf0edbfSSuraj Jitindar Singh 
403ddf0edbfSSuraj Jitindar Singh 	while ((opt = getopt_long(argc, argv, "spdlkrfue:cvh", long_options,
404ddf0edbfSSuraj Jitindar Singh 				  NULL)) != -1) {
405ddf0edbfSSuraj Jitindar Singh 		switch (opt) {
406ddf0edbfSSuraj Jitindar Singh 		case 's':
407ddf0edbfSSuraj Jitindar Singh 			silent = true;
408ddf0edbfSSuraj Jitindar Singh 			continue;
409ddf0edbfSSuraj Jitindar Singh 		case 'p':
410ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_ping(context);
411ddf0edbfSSuraj Jitindar Singh 			break;
412ddf0edbfSSuraj Jitindar Singh 		case 'd':
413ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_daemon_state(context);
414ddf0edbfSSuraj Jitindar Singh 			break;
415ddf0edbfSSuraj Jitindar Singh 		case 'l':
416ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_lpc_state(context);
417ddf0edbfSSuraj Jitindar Singh 			break;
418ddf0edbfSSuraj Jitindar Singh 		case 'k':
419ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_kill(context);
420ddf0edbfSSuraj Jitindar Singh 			break;
421ddf0edbfSSuraj Jitindar Singh 		case 'r': /* These are the same for now (reset may change) */
422ddf0edbfSSuraj Jitindar Singh 		case 'f':
423ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_reset(context);
424ddf0edbfSSuraj Jitindar Singh 			break;
425ddf0edbfSSuraj Jitindar Singh 		case 'u':
426ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_suspend(context);
427ddf0edbfSSuraj Jitindar Singh 			break;
428ddf0edbfSSuraj Jitindar Singh 		case 'e':
429ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_resume(context, optarg);
430ddf0edbfSSuraj Jitindar Singh 			break;
431ddf0edbfSSuraj Jitindar Singh 		case 'c':
432ddf0edbfSSuraj Jitindar Singh 			rc = handle_cmd_modified(context);
433ddf0edbfSSuraj Jitindar Singh 			break;
434ddf0edbfSSuraj Jitindar Singh 		case 'v':
4358d65bb44SSuraj Jitindar Singh 			MSG_OUT("%s V%s\n", NAME, PACKAGE_VERSION);
436ddf0edbfSSuraj Jitindar Singh 			rc = 0;
437ddf0edbfSSuraj Jitindar Singh 			break;
438ddf0edbfSSuraj Jitindar Singh 		case 'h':
439ddf0edbfSSuraj Jitindar Singh 			usage(argv[0]);
440ddf0edbfSSuraj Jitindar Singh 			rc = 0;
441ddf0edbfSSuraj Jitindar Singh 			break;
442ddf0edbfSSuraj Jitindar Singh 		default:
443ddf0edbfSSuraj Jitindar Singh 			usage(argv[0]);
444ddf0edbfSSuraj Jitindar Singh 			rc = -E_DBUS_INVAL;
445ddf0edbfSSuraj Jitindar Singh 			break;
446ddf0edbfSSuraj Jitindar Singh 		}
447ddf0edbfSSuraj Jitindar Singh 	}
448ddf0edbfSSuraj Jitindar Singh 
449ddf0edbfSSuraj Jitindar Singh 	return rc;
450ddf0edbfSSuraj Jitindar Singh }
451ddf0edbfSSuraj Jitindar Singh 
main(int argc,char ** argv)452ddf0edbfSSuraj Jitindar Singh int main(int argc, char **argv)
453ddf0edbfSSuraj Jitindar Singh {
454ddf0edbfSSuraj Jitindar Singh 	struct mboxctl_context context;
455ddf0edbfSSuraj Jitindar Singh 	int rc;
456ddf0edbfSSuraj Jitindar Singh 
457ddf0edbfSSuraj Jitindar Singh 	silent = false;
458ddf0edbfSSuraj Jitindar Singh 
459ddf0edbfSSuraj Jitindar Singh 	rc = init_mboxctl_dbus(&context);
460ddf0edbfSSuraj Jitindar Singh 	if (rc < 0) {
461ddf0edbfSSuraj Jitindar Singh 		MSG_ERR("Failed to init dbus\n");
462ddf0edbfSSuraj Jitindar Singh 		return rc;
463ddf0edbfSSuraj Jitindar Singh 	}
464ddf0edbfSSuraj Jitindar Singh 
465ddf0edbfSSuraj Jitindar Singh 	rc = parse_cmdline(&context, argc, argv);
466ddf0edbfSSuraj Jitindar Singh 
467ddf0edbfSSuraj Jitindar Singh 	return rc;
468ddf0edbfSSuraj Jitindar Singh }
469