blob: ebc71aafedda073a5270d8abaa6b7ae49c9e4190 [file] [log] [blame]
Norman James18998182015-10-11 21:54:53 -05001#include <stdio.h>
2#include <stdbool.h>
3#include <string.h>
Norman James362a80f2015-09-14 14:04:39 -05004#include "interfaces/openbmc_intf.h"
Norman James10ff6a32015-08-27 14:24:17 -05005#include "openbmc.h"
Norman Jamese2765102015-08-19 22:00:55 -05006
7/* ---------------------------------------------------------------------------------------------------- */
Norman James362a80f2015-09-14 14:04:39 -05008static const gchar* dbus_object_path = "/org/openbmc/flash";
Norman James8c6d8382015-10-06 07:47:16 -05009static const gchar* dbus_name = "org.openbmc.flash.Bios";
Norman James18998182015-10-11 21:54:53 -050010static const gchar* FLASHER_BIN = "flasher.exe";
11static const gchar* DLOAD_BUS = "org.openbmc.managers.Download";
12static const gchar* DLOAD_OBJ = "/org/openbmc/managers/Download";
Norman Jamese2765102015-08-19 22:00:55 -050013
14static GDBusObjectManagerServer *manager = NULL;
Norman Jamese2765102015-08-19 22:00:55 -050015
Norman James18998182015-10-11 21:54:53 -050016int update(Flash* flash)
Norman Jamesf066e872015-10-07 15:29:51 -050017{
Norman James18998182015-10-11 21:54:53 -050018 pid_t pid;
19 int status=-1;
20 pid = fork();
21 if (pid == 0)
22 {
23 const gchar* path = flash_get_flasher_path(flash);
24 const gchar* name = flash_get_flasher_name(flash);
25 const gchar* inst = flash_get_flasher_instance(flash);
26 const gchar* filename = flash_get_filename(flash);
Norman James18998182015-10-11 21:54:53 -050027 status = execl(path, name, inst, filename, NULL);
Norman Jamesa3e47c42015-10-18 14:43:10 -050028 return status;
Norman Jamesf066e872015-10-07 15:29:51 -050029 }
Norman Jamesa3e47c42015-10-18 14:43:10 -050030 return 0;
Norman Jamesf066e872015-10-07 15:29:51 -050031}
32
Norman Jamese2765102015-08-19 22:00:55 -050033static gboolean
Norman James471ab592015-08-30 22:29:40 -050034on_init (Flash *f,
35 GDBusMethodInvocation *invocation,
36 gpointer user_data)
37{
Norman James65a295a2015-09-26 22:21:10 -050038 flash_complete_init(f,invocation);
Norman James068efb32015-10-06 16:52:28 -050039
Norman James18998182015-10-11 21:54:53 -050040 //tune flash
41 flash_set_filename(f,"");
42 int rc = update(f);
43 if (rc==-1)
44 {
45 printf("ERROR FlashControl_0: Unable to init\n");
46 }
47 return TRUE;
48}
Norman James068efb32015-10-06 16:52:28 -050049
Norman James18998182015-10-11 21:54:53 -050050static gboolean
51on_lock (SharedResource *lock,
52 GDBusMethodInvocation *invocation,
53 gchar* name,
54 gpointer user_data)
55{
Norman Jamesa3e47c42015-10-18 14:43:10 -050056 gboolean locked = shared_resource_get_lock(lock);
57 if (locked)
58 {
59 const gchar* name = shared_resource_get_name(lock);
60 printf("ERROR: BIOS Flash is already locked: %s\n",name);
61 }
62 else
63 {
64 printf("Locking BIOS Flash: %s\n",name);
65 shared_resource_set_lock(lock,true);
66 shared_resource_set_name(lock,name);
67 }
Norman James18998182015-10-11 21:54:53 -050068 shared_resource_complete_lock(lock,invocation);
69 return TRUE;
70}
71static gboolean
72on_is_locked (SharedResource *lock,
73 GDBusMethodInvocation *invocation,
74 gpointer user_data)
75{
76 gboolean locked = shared_resource_get_lock(lock);
77 const gchar* name = shared_resource_get_name(lock);
78 shared_resource_complete_is_locked(lock,invocation,locked,name);
79 return TRUE;
80}
81
82
83static gboolean
84on_unlock (SharedResource *lock,
85 GDBusMethodInvocation *invocation,
86 gpointer user_data)
87{
88 printf("Unlocking BIOS Flash\n");
89 shared_resource_set_lock(lock,false);
90 shared_resource_set_name(lock,"");
91 shared_resource_complete_unlock(lock,invocation);
Norman James65a295a2015-09-26 22:21:10 -050092 return TRUE;
Norman James471ab592015-08-30 22:29:40 -050093}
94
95static gboolean
Norman Jamesf066e872015-10-07 15:29:51 -050096on_update_via_tftp (Flash *flash,
97 GDBusMethodInvocation *invocation,
98 gchar* url,
99 gchar* write_file,
100 gpointer user_data)
101{
Norman James18998182015-10-11 21:54:53 -0500102 SharedResource *lock = object_get_shared_resource((Object*)user_data);
103 gboolean locked = shared_resource_get_lock(lock);
Norman Jamesf066e872015-10-07 15:29:51 -0500104 flash_complete_update_via_tftp(flash,invocation);
Norman James18998182015-10-11 21:54:53 -0500105 if (locked)
106 {
107 const gchar* name = shared_resource_get_name(lock);
108 printf("BIOS Flash is locked: %s\n",name);
109 }
110 else
111 {
112 printf("Flashing BIOS from TFTP: %s,%s\n",url,write_file);
113 shared_resource_set_lock(lock,true);
114 shared_resource_set_name(lock,dbus_object_path);
115 flash_set_filename(flash,write_file);
116 flash_emit_download(flash,url,write_file);
117 }
Norman Jamesf066e872015-10-07 15:29:51 -0500118 return TRUE;
119}
120
121static gboolean
122on_update (Flash *flash,
Norman Jamese2765102015-08-19 22:00:55 -0500123 GDBusMethodInvocation *invocation,
124 gchar* write_file,
125 gpointer user_data)
126{
Norman James18998182015-10-11 21:54:53 -0500127 int rc = 0;
128 SharedResource *lock = object_get_shared_resource((Object*)user_data);
129 gboolean locked = shared_resource_get_lock(lock);
Norman Jamesf066e872015-10-07 15:29:51 -0500130 flash_complete_update(flash,invocation);
Norman James18998182015-10-11 21:54:53 -0500131 if (locked)
132 {
133 const gchar* name = shared_resource_get_name(lock);
134 printf("BIOS Flash is locked: %s\n",name);
135 }
136 else
137 {
138 printf("Flashing BIOS from: %s\n",write_file);
139 shared_resource_set_lock(lock,true);
140 shared_resource_set_name(lock,dbus_object_path);
141 flash_set_filename(flash,write_file);
142 rc = update(flash);
143 if (!rc)
144 {
145 shared_resource_set_lock(lock,false);
146 shared_resource_set_name(lock,"");
147 }
148 }
Norman James068efb32015-10-06 16:52:28 -0500149 return TRUE;
Norman Jamese2765102015-08-19 22:00:55 -0500150}
151
Norman Jamesf066e872015-10-07 15:29:51 -0500152static void
153on_download_complete (GDBusConnection* connection,
154 const gchar* sender_name,
155 const gchar* object_path,
156 const gchar* interface_name,
157 const gchar* signal_name,
158 GVariant* parameters,
159 gpointer user_data)
160{
161 Flash *flash = object_get_flash((Object*)user_data);
Norman James18998182015-10-11 21:54:53 -0500162 SharedResource *lock = object_get_shared_resource((Object*)user_data);
163
Norman Jamesf066e872015-10-07 15:29:51 -0500164 GVariantIter *iter = g_variant_iter_new(parameters);
Norman James18998182015-10-11 21:54:53 -0500165 GVariant* v_fullname = g_variant_iter_next_value(iter);
Norman Jamesf066e872015-10-07 15:29:51 -0500166 gsize size;
Norman James18998182015-10-11 21:54:53 -0500167 const gchar* fullname = g_variant_get_string(v_fullname,&size);
168 int rc;
169 flash_set_filename(flash,fullname);
170 rc = update(flash);
171 if (!rc)
172 {
173 shared_resource_set_lock(lock,false);
174 shared_resource_set_name(lock,"");
175 }
176}
177
178static void
179on_flash_progress (GDBusConnection* connection,
180 const gchar* sender_name,
181 const gchar* object_path,
182 const gchar* interface_name,
183 const gchar* signal_name,
184 GVariant* parameters,
185 gpointer user_data)
186{
187 Flash *flash = object_get_flash((Object*)user_data);
188 SharedResource *lock = object_get_shared_resource((Object*)user_data);
189 GVariantIter *iter = g_variant_iter_new(parameters);
190 GVariant* v_filename = g_variant_iter_next_value(iter);
191 GVariant* v_progress = g_variant_iter_next_value(iter);
Norman Jamesf066e872015-10-07 15:29:51 -0500192
Norman James18998182015-10-11 21:54:53 -0500193 uint8_t progress = g_variant_get_byte(v_progress);
194 printf("Progress: %d\n",progress);
195}
196
197static void
198on_flash_done (GDBusConnection* connection,
199 const gchar* sender_name,
200 const gchar* object_path,
201 const gchar* interface_name,
202 const gchar* signal_name,
203 GVariant* parameters,
204 gpointer user_data)
205{
206 Flash *flash = object_get_flash((Object*)user_data);
207 SharedResource *lock = object_get_shared_resource((Object*)user_data);
208 printf("Flash succeeded; unlocking flash\n");
209 shared_resource_set_lock(lock,false);
210 shared_resource_set_name(lock,"");
211}
212
213static void
214on_flash_error (GDBusConnection* connection,
215 const gchar* sender_name,
216 const gchar* object_path,
217 const gchar* interface_name,
218 const gchar* signal_name,
219 GVariant* parameters,
220 gpointer user_data)
221{
222 Flash *flash = object_get_flash((Object*)user_data);
223 SharedResource *lock = object_get_shared_resource((Object*)user_data);
224 printf("Flash Error; unlocking flash\n");
225 shared_resource_set_lock(lock,false);
226 shared_resource_set_name(lock,"");
227}
228
229static void
230on_download_error (GDBusConnection* connection,
231 const gchar* sender_name,
232 const gchar* object_path,
233 const gchar* interface_name,
234 const gchar* signal_name,
235 GVariant* parameters,
236 gpointer user_data)
237{
238 Flash *flash = object_get_flash((Object*)user_data);
239 SharedResource *lock = object_get_shared_resource((Object*)user_data);
240 printf("ERROR: FlashBios: Download error; clearing flash lock\n");
241 shared_resource_set_lock(lock,false);
242 shared_resource_set_name(lock,"");
Norman Jamesf066e872015-10-07 15:29:51 -0500243}
244
Norman Jamese2765102015-08-19 22:00:55 -0500245static void
246on_bus_acquired (GDBusConnection *connection,
247 const gchar *name,
248 gpointer user_data)
249{
Norman James10ff6a32015-08-27 14:24:17 -0500250 ObjectSkeleton *object;
Norman James10ff6a32015-08-27 14:24:17 -0500251 cmdline *cmd = user_data;
252 if (cmd->argc < 2)
253 {
254 g_print("No objects created. Put object name(s) on command line\n");
255 return;
256 }
257 manager = g_dbus_object_manager_server_new (dbus_object_path);
258 int i=0;
259 for (i=1;i<cmd->argc;i++)
260 {
261 gchar *s;
262 s = g_strdup_printf ("%s/%s",dbus_object_path,cmd->argv[i]);
263 object = object_skeleton_new (s);
264 g_free (s);
Norman Jamese2765102015-08-19 22:00:55 -0500265
Norman James10ff6a32015-08-27 14:24:17 -0500266 Flash* flash = flash_skeleton_new ();
267 object_skeleton_set_flash (object, flash);
268 g_object_unref (flash);
Norman Jamese2765102015-08-19 22:00:55 -0500269
Norman James18998182015-10-11 21:54:53 -0500270 SharedResource* lock = shared_resource_skeleton_new ();
271 object_skeleton_set_shared_resource (object, lock);
272 g_object_unref (lock);
273
274 shared_resource_set_lock(lock,false);
275 shared_resource_set_name(lock,"");
276
277 int c = strlen(cmd->argv[0]);
278
279 //TODO: don't use fixed buffer
280 char buf[512];
281 memset(buf, '\0', sizeof(buf));
282 bool found = false;
283 while(c>0)
284 {
285 if (cmd->argv[0][c] == '/')
286 {
287 strncpy(buf,cmd->argv[0],c);
288 s = g_strdup_printf ("%s/%s",buf,FLASHER_BIN);
289 break;
290 }
291 c--;
292 }
293 if (c==0)
294 {
295 printf("ERROR FlashBios: Invalid Path = %s\n",cmd->argv[0]);
296 }
297 else
298 {
299 flash_set_flasher_path(flash,s);
300 flash_set_flasher_name(flash,FLASHER_BIN);
301 flash_set_flasher_instance(flash,cmd->argv[i]);
302 }
303 g_free (s);
304
305
Norman James10ff6a32015-08-27 14:24:17 -0500306 //define method callbacks here
Norman James18998182015-10-11 21:54:53 -0500307 g_signal_connect (lock,
308 "handle-lock",
309 G_CALLBACK (on_lock),
310 NULL); /* user_data */
311 g_signal_connect (lock,
312 "handle-unlock",
313 G_CALLBACK (on_unlock),
314 NULL); /* user_data */
315 g_signal_connect (lock,
316 "handle-is-locked",
317 G_CALLBACK (on_is_locked),
318 NULL); /* user_data */
319
Norman James10ff6a32015-08-27 14:24:17 -0500320 g_signal_connect (flash,
Norman James8c6d8382015-10-06 07:47:16 -0500321 "handle-update",
322 G_CALLBACK (on_update),
Norman James18998182015-10-11 21:54:53 -0500323 object); /* user_data */
Norman Jamesf066e872015-10-07 15:29:51 -0500324 g_signal_connect (flash,
325 "handle-update-via-tftp",
326 G_CALLBACK (on_update_via_tftp),
Norman James18998182015-10-11 21:54:53 -0500327 object); /* user_data */
Norman Jamesf066e872015-10-07 15:29:51 -0500328
Norman James471ab592015-08-30 22:29:40 -0500329 g_signal_connect (flash,
330 "handle-init",
331 G_CALLBACK (on_init),
332 NULL); /* user_data */
333
Norman Jamesf066e872015-10-07 15:29:51 -0500334 g_dbus_connection_signal_subscribe(connection,
Norman James18998182015-10-11 21:54:53 -0500335 DLOAD_BUS, DLOAD_BUS, "DownloadComplete",
336 DLOAD_OBJ,NULL,G_DBUS_SIGNAL_FLAGS_NONE,
Norman Jamesf066e872015-10-07 15:29:51 -0500337 (GDBusSignalCallback) on_download_complete,
338 object,
339 NULL );
Norman James18998182015-10-11 21:54:53 -0500340 g_dbus_connection_signal_subscribe(connection,
341 DLOAD_BUS, DLOAD_BUS, "DownloadError",
342 DLOAD_OBJ,NULL,G_DBUS_SIGNAL_FLAGS_NONE,
343 (GDBusSignalCallback) on_download_error,
344 object,
345 NULL );
346
347 s = g_strdup_printf ("/org/openbmc/control/%s",cmd->argv[i]);
348 g_dbus_connection_signal_subscribe(connection,
349 NULL,
350 "org.openbmc.FlashControl",
351 "Done",
352 s,
353 NULL,
354 G_DBUS_SIGNAL_FLAGS_NONE,
355 (GDBusSignalCallback) on_flash_done,
356 object,
357 NULL );
358 g_free(s);
Norman Jamesa3e47c42015-10-18 14:43:10 -0500359 s = g_strdup_printf ("/org/openbmc/control/%s",cmd->argv[i]);
Norman James18998182015-10-11 21:54:53 -0500360 g_dbus_connection_signal_subscribe(connection,
361 NULL,
362 "org.openbmc.FlashControl",
363 "Error",
364 s,
365 NULL,
366 G_DBUS_SIGNAL_FLAGS_NONE,
367 (GDBusSignalCallback) on_flash_error,
368 object,
369 NULL );
370
371 g_free(s);
372 s = g_strdup_printf ("/org/openbmc/control/%s",cmd->argv[i]);
373 g_dbus_connection_signal_subscribe(connection,
374 NULL,
375 "org.openbmc.FlashControl",
376 "Progress",
377 s,
378 NULL,
379 G_DBUS_SIGNAL_FLAGS_NONE,
380 (GDBusSignalCallback) on_flash_progress,
381 object,
382 NULL );
383
384 g_free (s);
Norman Jamesf066e872015-10-07 15:29:51 -0500385
Norman James471ab592015-08-30 22:29:40 -0500386
Norman James18998182015-10-11 21:54:53 -0500387 flash_set_filename(flash,"");
Norman James10ff6a32015-08-27 14:24:17 -0500388 /* Export the object (@manager takes its own reference to @object) */
389 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
390 g_object_unref (object);
391 }
Norman Jamese2765102015-08-19 22:00:55 -0500392
Norman James10ff6a32015-08-27 14:24:17 -0500393 /* Export all objects */
394 g_dbus_object_manager_server_set_connection (manager, connection);
Norman Jamese2765102015-08-19 22:00:55 -0500395}
396
397static void
398on_name_acquired (GDBusConnection *connection,
399 const gchar *name,
400 gpointer user_data)
401{
Norman James362a80f2015-09-14 14:04:39 -0500402// g_print ("Acquired the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500403}
404
405static void
406on_name_lost (GDBusConnection *connection,
407 const gchar *name,
408 gpointer user_data)
409{
Norman James362a80f2015-09-14 14:04:39 -0500410 //g_print ("Lost the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500411}
412
413gint
414main (gint argc, gchar *argv[])
415{
416 GMainLoop *loop;
Norman James952b38d2015-08-27 21:30:06 -0500417 cmdline cmd;
418 cmd.argc = argc;
419 cmd.argv = argv;
Norman Jamese2765102015-08-19 22:00:55 -0500420 guint id;
Norman Jamese2765102015-08-19 22:00:55 -0500421 loop = g_main_loop_new (NULL, FALSE);
422
Norman James5e792e32015-10-07 17:36:17 -0500423 id = g_bus_own_name (DBUS_TYPE,
Norman James26072c02015-08-25 07:14:29 -0500424 dbus_name,
Norman Jamese2765102015-08-19 22:00:55 -0500425 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
426 G_BUS_NAME_OWNER_FLAGS_REPLACE,
427 on_bus_acquired,
428 on_name_acquired,
429 on_name_lost,
Norman James952b38d2015-08-27 21:30:06 -0500430 &cmd,
Norman Jamese2765102015-08-19 22:00:55 -0500431 NULL);
432
433 g_main_loop_run (loop);
434
435 g_bus_unown_name (id);
436 g_main_loop_unref (loop);
437 return 0;
438}