blob: 0190fdf89fa3ea17436609c0047e2561ecd1f2c9 [file] [log] [blame]
Norman James26072c02015-08-25 07:14:29 -05001#include <stdint.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <fcntl.h>
6#include <unistd.h>
7#include <sys/stat.h>
8#include <sys/mman.h>
Norman James362a80f2015-09-14 14:04:39 -05009#include "interfaces/openbmc_intf.h"
Norman James10ff6a32015-08-27 14:24:17 -050010#include "openbmc.h"
11#include "gpio.h"
Norman Jamese2765102015-08-19 22:00:55 -050012
13/* ---------------------------------------------------------------------------------------------------- */
Norman James362a80f2015-09-14 14:04:39 -050014static const gchar* dbus_object_path = "/org/openbmc/control";
Norman James26072c02015-08-25 07:14:29 -050015static const gchar* dbus_name = "org.openbmc.control.Power";
16
Norman James3f97c5d2015-08-26 17:44:14 -050017GPIO power_pin = (GPIO){ "POWER_PIN" };
18GPIO pgood = (GPIO){ "PGOOD" };
Norman Jamese2765102015-08-19 22:00:55 -050019
20static GDBusObjectManagerServer *manager = NULL;
Norman Jamese2765102015-08-19 22:00:55 -050021
Norman James362a80f2015-09-14 14:04:39 -050022guint tmp_pgood = 0;
23guint last_pgood = 0;
24
Norman Jamesce46e3e2015-08-30 22:25:55 -050025static gboolean poll_pgood(gpointer user_data)
26{
27 ControlPower *control_power = object_get_control_power((Object*)user_data);
28 Control* control = object_get_control((Object*)user_data);
29 EventLog* event_log = object_get_event_log((Object*)user_data);
30 control_emit_heartbeat(control,dbus_name);
31
Norman James362a80f2015-09-14 14:04:39 -050032 //For simulation, remove
33 if (tmp_pgood!=last_pgood) {
34 if (tmp_pgood == 1) {
35 control_emit_goto_system_state(control,"POWERED_ON");
36 } else {
37 control_emit_goto_system_state(control,"POWERED_OFF");
Norman Jamesce46e3e2015-08-30 22:25:55 -050038 }
Norman James362a80f2015-09-14 14:04:39 -050039 }
40
41 last_pgood = tmp_pgood;
42 uint8_t gpio = gpio_read(&pgood);
43 //if changed, set property and emit signal
44 if (gpio != control_power_get_pgood(control_power))
45 {
46 control_power_set_pgood(control_power,gpio);
47 if (gpio==0)
48 {
49 control_power_emit_power_lost(control_power);
50 control_emit_goto_system_state(control,"POWERED_OFF");
51 }
52 else
53 {
54 control_power_emit_power_good(control_power);
55 control_emit_goto_system_state(control,"POWERED_ON");
56 }
57 }
Norman Jamesce46e3e2015-08-30 22:25:55 -050058 return TRUE;
59}
60
61
62
Norman Jamese2765102015-08-19 22:00:55 -050063static gboolean
Norman James3f97c5d2015-08-26 17:44:14 -050064on_set_power_state (ControlPower *pwr,
Norman Jamese2765102015-08-19 22:00:55 -050065 GDBusMethodInvocation *invocation,
66 guint state,
67 gpointer user_data)
68{
Norman James362a80f2015-09-14 14:04:39 -050069 Control* control = object_get_control((Object*)user_data);
Norman James3f97c5d2015-08-26 17:44:14 -050070 if (state > 1)
71 {
72 g_dbus_method_invocation_return_dbus_error (invocation,
73 "org.openbmc.ControlPower.Error.Failed",
74 "Invalid power state");
75 return TRUE;
76 }
Norman James9e6acf92015-09-08 07:00:04 -050077 // return from method call
78 control_power_complete_set_power_state(pwr,invocation);
Norman James3f97c5d2015-08-26 17:44:14 -050079 if (state == control_power_get_state(pwr))
80 {
Norman James9e6acf92015-09-08 07:00:04 -050081 g_print("Power already at requested state: %d\n",state);
Norman James3f97c5d2015-08-26 17:44:14 -050082 }
Norman James9e6acf92015-09-08 07:00:04 -050083 else
84 {
85 g_print("Set power state: %d\n",state);
Norman James362a80f2015-09-14 14:04:39 -050086 //temporary until real hardware works
87 tmp_pgood = state;
Norman James9e6acf92015-09-08 07:00:04 -050088 gpio_open(&power_pin);
89 gpio_write(&power_pin,!state);
90 gpio_close(&power_pin);
91 control_power_set_state(pwr,state);
Norman James362a80f2015-09-14 14:04:39 -050092 if (state == 1)
93 {
94 control_emit_goto_system_state(control,"POWERING_ON");
95 }
96 else
97 {
98 control_emit_goto_system_state(control,"POWERING_OFF");
99 }
Norman James9e6acf92015-09-08 07:00:04 -0500100 }
101 return TRUE;
102}
Norman Jamese2765102015-08-19 22:00:55 -0500103
Norman James9e6acf92015-09-08 07:00:04 -0500104static gboolean
105on_init (Control *control,
106 GDBusMethodInvocation *invocation,
107 gpointer user_data)
108{
109 guint poll_interval = control_get_poll_interval(control);
110 g_timeout_add(poll_interval, poll_pgood, user_data);
111 control_complete_init(control,invocation);
Norman James3f97c5d2015-08-26 17:44:14 -0500112 return TRUE;
Norman Jamese2765102015-08-19 22:00:55 -0500113}
114
115static gboolean
Norman James3f97c5d2015-08-26 17:44:14 -0500116on_get_power_state (ControlPower *pwr,
Norman Jamese2765102015-08-19 22:00:55 -0500117 GDBusMethodInvocation *invocation,
118 gpointer user_data)
119{
Norman James3f97c5d2015-08-26 17:44:14 -0500120 guint pgood = control_power_get_pgood(pwr);
121 control_power_complete_get_power_state(pwr,invocation,pgood);
122 return TRUE;
Norman Jamese2765102015-08-19 22:00:55 -0500123}
124
125static void
126on_bus_acquired (GDBusConnection *connection,
127 const gchar *name,
128 gpointer user_data)
129{
Norman James3f97c5d2015-08-26 17:44:14 -0500130 ObjectSkeleton *object;
Norman James362a80f2015-09-14 14:04:39 -0500131 //g_print ("Acquired a message bus connection: %s\n",name);
Norman James10ff6a32015-08-27 14:24:17 -0500132 cmdline *cmd = user_data;
133 if (cmd->argc < 2)
134 {
135 g_print("No objects created. Put object name(s) on command line\n");
136 return;
137 }
138 manager = g_dbus_object_manager_server_new (dbus_object_path);
139 int i=0;
140 for (i=1;i<cmd->argc;i++)
141 {
142 gchar *s;
143 s = g_strdup_printf ("%s/%s",dbus_object_path,cmd->argv[i]);
Norman James362a80f2015-09-14 14:04:39 -0500144 g_print("%s\n",s);
Norman James10ff6a32015-08-27 14:24:17 -0500145 object = object_skeleton_new (s);
146 g_free (s);
Norman Jamese2765102015-08-19 22:00:55 -0500147
Norman James10ff6a32015-08-27 14:24:17 -0500148 ControlPower* control_power = control_power_skeleton_new ();
149 object_skeleton_set_control_power (object, control_power);
150 g_object_unref (control_power);
Norman Jamese2765102015-08-19 22:00:55 -0500151
Norman Jamesce46e3e2015-08-30 22:25:55 -0500152 Control* control = control_skeleton_new ();
153 object_skeleton_set_control (object, control);
154 g_object_unref (control);
155
156 EventLog* event_log = event_log_skeleton_new ();
157 object_skeleton_set_event_log (object, event_log);
158 g_object_unref (event_log);
159
Norman James10ff6a32015-08-27 14:24:17 -0500160 //define method callbacks here
161 g_signal_connect (control_power,
162 "handle-set-power-state",
163 G_CALLBACK (on_set_power_state),
Norman James362a80f2015-09-14 14:04:39 -0500164 object); /* user_data */
Norman Jamese2765102015-08-19 22:00:55 -0500165
Norman James10ff6a32015-08-27 14:24:17 -0500166 g_signal_connect (control_power,
167 "handle-get-power-state",
168 G_CALLBACK (on_get_power_state),
169 NULL); /* user_data */
Norman Jamese2765102015-08-19 22:00:55 -0500170
Norman James9e6acf92015-09-08 07:00:04 -0500171 g_signal_connect (control,
172 "handle-init",
173 G_CALLBACK (on_init),
174 object); /* user_data */
175
176
Norman Jamesce46e3e2015-08-30 22:25:55 -0500177
Norman James10ff6a32015-08-27 14:24:17 -0500178 /* Export the object (@manager takes its own reference to @object) */
179 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
180 g_object_unref (object);
181 }
Norman James3f97c5d2015-08-26 17:44:14 -0500182 /* Export all objects */
183 g_dbus_object_manager_server_set_connection (manager, connection);
184
185 // get gpio device paths
186 gpio_init(connection,&power_pin);
187 gpio_init(connection,&pgood);
188 gpio_open(&pgood);
Norman Jamese2765102015-08-19 22:00:55 -0500189}
190
191static void
192on_name_acquired (GDBusConnection *connection,
193 const gchar *name,
194 gpointer user_data)
195{
Norman James362a80f2015-09-14 14:04:39 -0500196 //g_print ("Acquired the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500197}
198
199static void
200on_name_lost (GDBusConnection *connection,
201 const gchar *name,
202 gpointer user_data)
203{
Norman James362a80f2015-09-14 14:04:39 -0500204 //g_print ("Lost the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500205}
206
Norman Jamese2765102015-08-19 22:00:55 -0500207
Norman James3f97c5d2015-08-26 17:44:14 -0500208
209
210/*----------------------------------------------------------------*/
211/* Main Event Loop */
212
Norman Jamese2765102015-08-19 22:00:55 -0500213gint
214main (gint argc, gchar *argv[])
215{
216 GMainLoop *loop;
Norman James90caa3c2015-08-27 21:28:48 -0500217 cmdline cmd;
218 cmd.argc = argc;
219 cmd.argv = argv;
Norman Jamese2765102015-08-19 22:00:55 -0500220
221 guint id;
Norman Jamese2765102015-08-19 22:00:55 -0500222 loop = g_main_loop_new (NULL, FALSE);
223
224 id = g_bus_own_name (G_BUS_TYPE_SESSION,
Norman James26072c02015-08-25 07:14:29 -0500225 dbus_name,
Norman Jamese2765102015-08-19 22:00:55 -0500226 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
227 G_BUS_NAME_OWNER_FLAGS_REPLACE,
228 on_bus_acquired,
229 on_name_acquired,
230 on_name_lost,
Norman James90caa3c2015-08-27 21:28:48 -0500231 &cmd,
Norman Jamese2765102015-08-19 22:00:55 -0500232 NULL);
233
Norman Jamesce46e3e2015-08-30 22:25:55 -0500234 g_main_loop_run (loop);
Norman Jamese2765102015-08-19 22:00:55 -0500235
236 g_bus_unown_name (id);
237 g_main_loop_unref (loop);
238 return 0;
239}