blob: 17582d4688ece1862df9a89a639bee82167da0e0 [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 James166acf42015-10-22 07:11:51 -05008static const gchar* dbus_object_path = "/org/openbmc/control/flash";
9static const gchar* dbus_name = "org.openbmc.control.Flash";
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 James166acf42015-10-22 07:11:51 -050016int update(Flash* flash, const char* obj_path)
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 James166acf42015-10-22 07:11:51 -050027 status = execl(path, name, inst, filename, obj_path, 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
Norman James166acf42015-10-22 07:11:51 -050041 if (strcmp(flash_get_flasher_instance(f),"bios") == 0)
Norman James18998182015-10-11 21:54:53 -050042 {
Norman James166acf42015-10-22 07:11:51 -050043 flash_set_filename(f,"");
44 const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data);
45 int rc = update(f,obj_path);
46 if (rc==-1)
47 {
48 printf("ERROR FlashControl: Unable to init\n");
49 }
Norman James18998182015-10-11 21:54:53 -050050 }
51 return TRUE;
52}
Norman James068efb32015-10-06 16:52:28 -050053
Norman James18998182015-10-11 21:54:53 -050054static gboolean
55on_lock (SharedResource *lock,
56 GDBusMethodInvocation *invocation,
57 gchar* name,
58 gpointer user_data)
59{
Norman Jamesa3e47c42015-10-18 14:43:10 -050060 gboolean locked = shared_resource_get_lock(lock);
61 if (locked)
62 {
63 const gchar* name = shared_resource_get_name(lock);
64 printf("ERROR: BIOS Flash is already locked: %s\n",name);
65 }
66 else
67 {
68 printf("Locking BIOS Flash: %s\n",name);
69 shared_resource_set_lock(lock,true);
70 shared_resource_set_name(lock,name);
71 }
Norman James18998182015-10-11 21:54:53 -050072 shared_resource_complete_lock(lock,invocation);
73 return TRUE;
74}
75static gboolean
76on_is_locked (SharedResource *lock,
77 GDBusMethodInvocation *invocation,
78 gpointer user_data)
79{
80 gboolean locked = shared_resource_get_lock(lock);
81 const gchar* name = shared_resource_get_name(lock);
82 shared_resource_complete_is_locked(lock,invocation,locked,name);
83 return TRUE;
84}
85
86
87static gboolean
88on_unlock (SharedResource *lock,
89 GDBusMethodInvocation *invocation,
90 gpointer user_data)
91{
92 printf("Unlocking BIOS Flash\n");
93 shared_resource_set_lock(lock,false);
94 shared_resource_set_name(lock,"");
95 shared_resource_complete_unlock(lock,invocation);
Norman James65a295a2015-09-26 22:21:10 -050096 return TRUE;
Norman James471ab592015-08-30 22:29:40 -050097}
98
99static gboolean
Norman Jamesf066e872015-10-07 15:29:51 -0500100on_update_via_tftp (Flash *flash,
101 GDBusMethodInvocation *invocation,
102 gchar* url,
103 gchar* write_file,
104 gpointer user_data)
105{
Norman James18998182015-10-11 21:54:53 -0500106 SharedResource *lock = object_get_shared_resource((Object*)user_data);
107 gboolean locked = shared_resource_get_lock(lock);
Norman Jamesf066e872015-10-07 15:29:51 -0500108 flash_complete_update_via_tftp(flash,invocation);
Norman James18998182015-10-11 21:54:53 -0500109 if (locked)
110 {
111 const gchar* name = shared_resource_get_name(lock);
112 printf("BIOS Flash is locked: %s\n",name);
113 }
114 else
115 {
116 printf("Flashing BIOS from TFTP: %s,%s\n",url,write_file);
Norman James18998182015-10-11 21:54:53 -0500117 flash_set_filename(flash,write_file);
118 flash_emit_download(flash,url,write_file);
Norman James166acf42015-10-22 07:11:51 -0500119 flash_set_status(flash,"Downloading");
Norman James18998182015-10-11 21:54:53 -0500120 }
Norman Jamesf066e872015-10-07 15:29:51 -0500121 return TRUE;
122}
123
124static gboolean
Norman James166acf42015-10-22 07:11:51 -0500125on_error (Flash *flash,
126 GDBusMethodInvocation *invocation,
127 gchar* error_msg,
128 gpointer user_data)
129{
130 int rc = 0;
131 SharedResource *lock = object_get_shared_resource((Object*)user_data);
132 gboolean locked = shared_resource_get_lock(lock);
133 flash_set_status(flash, error_msg);
134 flash_complete_error(flash,invocation);
135 printf("ERROR: %s. Clearing locks\n",error_msg);
136 shared_resource_set_lock(lock,false);
137 shared_resource_set_name(lock,"");
138
139 return TRUE;
140}
141static gboolean
142on_done (Flash *flash,
143 GDBusMethodInvocation *invocation,
144 gpointer user_data)
145{
146 int rc = 0;
147 SharedResource *lock = object_get_shared_resource((Object*)user_data);
148 gboolean locked = shared_resource_get_lock(lock);
149 flash_set_status(flash, "Flash Done");
150 flash_complete_done(flash,invocation);
151 printf("Flash Done. Clearing locks\n");
152 shared_resource_set_lock(lock,false);
153 shared_resource_set_name(lock,"");
154
155 return TRUE;
156}
157
158
159static gboolean
Norman Jamesf066e872015-10-07 15:29:51 -0500160on_update (Flash *flash,
Norman Jamese2765102015-08-19 22:00:55 -0500161 GDBusMethodInvocation *invocation,
162 gchar* write_file,
163 gpointer user_data)
164{
Norman James18998182015-10-11 21:54:53 -0500165 int rc = 0;
166 SharedResource *lock = object_get_shared_resource((Object*)user_data);
167 gboolean locked = shared_resource_get_lock(lock);
Norman James166acf42015-10-22 07:11:51 -0500168 flash_set_status(flash,"Flashing");
Norman Jamesf066e872015-10-07 15:29:51 -0500169 flash_complete_update(flash,invocation);
Norman James18998182015-10-11 21:54:53 -0500170 if (locked)
171 {
172 const gchar* name = shared_resource_get_name(lock);
173 printf("BIOS Flash is locked: %s\n",name);
174 }
175 else
176 {
177 printf("Flashing BIOS from: %s\n",write_file);
Norman James166acf42015-10-22 07:11:51 -0500178 flash_set_status(flash, "Flashing");
Norman James18998182015-10-11 21:54:53 -0500179 shared_resource_set_lock(lock,true);
180 shared_resource_set_name(lock,dbus_object_path);
181 flash_set_filename(flash,write_file);
Norman James166acf42015-10-22 07:11:51 -0500182 const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data);
183 rc = update(flash,obj_path);
Norman James18998182015-10-11 21:54:53 -0500184 if (!rc)
185 {
186 shared_resource_set_lock(lock,false);
187 shared_resource_set_name(lock,"");
188 }
189 }
Norman James068efb32015-10-06 16:52:28 -0500190 return TRUE;
Norman Jamese2765102015-08-19 22:00:55 -0500191}
Norman James18998182015-10-11 21:54:53 -0500192static void
193on_flash_progress (GDBusConnection* connection,
194 const gchar* sender_name,
195 const gchar* object_path,
196 const gchar* interface_name,
197 const gchar* signal_name,
198 GVariant* parameters,
199 gpointer user_data)
200{
201 Flash *flash = object_get_flash((Object*)user_data);
202 SharedResource *lock = object_get_shared_resource((Object*)user_data);
203 GVariantIter *iter = g_variant_iter_new(parameters);
204 GVariant* v_filename = g_variant_iter_next_value(iter);
205 GVariant* v_progress = g_variant_iter_next_value(iter);
Norman Jamesf066e872015-10-07 15:29:51 -0500206
Norman James18998182015-10-11 21:54:53 -0500207 uint8_t progress = g_variant_get_byte(v_progress);
Norman James166acf42015-10-22 07:11:51 -0500208
209 gchar *s;
210 s = g_strdup_printf ("Flashing: %d%%",progress);
211 flash_set_status(flash,s);
212 g_free(s);
Norman James18998182015-10-11 21:54:53 -0500213}
214
215static void
216on_flash_done (GDBusConnection* connection,
217 const gchar* sender_name,
218 const gchar* object_path,
219 const gchar* interface_name,
220 const gchar* signal_name,
221 GVariant* parameters,
222 gpointer user_data)
223{
224 Flash *flash = object_get_flash((Object*)user_data);
225 SharedResource *lock = object_get_shared_resource((Object*)user_data);
226 printf("Flash succeeded; unlocking flash\n");
227 shared_resource_set_lock(lock,false);
228 shared_resource_set_name(lock,"");
Norman James166acf42015-10-22 07:11:51 -0500229 flash_set_status(flash,"Flash Done");
Norman James18998182015-10-11 21:54:53 -0500230}
231
232static void
233on_flash_error (GDBusConnection* connection,
234 const gchar* sender_name,
235 const gchar* object_path,
236 const gchar* interface_name,
237 const gchar* signal_name,
238 GVariant* parameters,
239 gpointer user_data)
240{
241 Flash *flash = object_get_flash((Object*)user_data);
242 SharedResource *lock = object_get_shared_resource((Object*)user_data);
243 printf("Flash Error; unlocking flash\n");
244 shared_resource_set_lock(lock,false);
245 shared_resource_set_name(lock,"");
246}
247
248static void
249on_download_error (GDBusConnection* connection,
250 const gchar* sender_name,
251 const gchar* object_path,
252 const gchar* interface_name,
253 const gchar* signal_name,
254 GVariant* parameters,
255 gpointer user_data)
256{
257 Flash *flash = object_get_flash((Object*)user_data);
258 SharedResource *lock = object_get_shared_resource((Object*)user_data);
259 printf("ERROR: FlashBios: Download error; clearing flash lock\n");
260 shared_resource_set_lock(lock,false);
261 shared_resource_set_name(lock,"");
Norman Jamesf066e872015-10-07 15:29:51 -0500262}
263
Norman Jamese2765102015-08-19 22:00:55 -0500264static void
265on_bus_acquired (GDBusConnection *connection,
266 const gchar *name,
267 gpointer user_data)
268{
Norman James10ff6a32015-08-27 14:24:17 -0500269 ObjectSkeleton *object;
Norman James10ff6a32015-08-27 14:24:17 -0500270 cmdline *cmd = user_data;
Norman James10ff6a32015-08-27 14:24:17 -0500271 manager = g_dbus_object_manager_server_new (dbus_object_path);
272 int i=0;
Norman James166acf42015-10-22 07:11:51 -0500273
274 //TODO: don't use fixed buffer
275 char flasher_path[512];
276 memset(flasher_path, '\0', sizeof(flasher_path));
277 bool found = false;
278 gchar *flasher_file;
279 int c = strlen(cmd->argv[0]);
280 while(c>0)
281 {
282 if (cmd->argv[0][c] == '/')
283 {
284 strncpy(flasher_path,cmd->argv[0],c);
285 flasher_file = g_strdup_printf ("%s/%s",flasher_path,FLASHER_BIN);
286 break;
287 }
288 c--;
289 }
290
Norman James15aaa802015-10-28 06:54:48 -0500291 const char* inst[] = {"bios","bmc","bmc_ramdisk","bmc_kernel"};
292 for (i=0;i<4;i++)
Norman James10ff6a32015-08-27 14:24:17 -0500293 {
Norman James166acf42015-10-22 07:11:51 -0500294 gchar* s;
295 s = g_strdup_printf ("%s/%s",dbus_object_path,inst[i]);
Norman James10ff6a32015-08-27 14:24:17 -0500296 object = object_skeleton_new (s);
297 g_free (s);
Norman Jamese2765102015-08-19 22:00:55 -0500298
Norman James10ff6a32015-08-27 14:24:17 -0500299 Flash* flash = flash_skeleton_new ();
300 object_skeleton_set_flash (object, flash);
301 g_object_unref (flash);
Norman Jamese2765102015-08-19 22:00:55 -0500302
Norman James18998182015-10-11 21:54:53 -0500303 SharedResource* lock = shared_resource_skeleton_new ();
304 object_skeleton_set_shared_resource (object, lock);
305 g_object_unref (lock);
306
307 shared_resource_set_lock(lock,false);
308 shared_resource_set_name(lock,"");
309
Norman James166acf42015-10-22 07:11:51 -0500310 flash_set_flasher_path(flash,flasher_file);
311 flash_set_flasher_name(flash,FLASHER_BIN);
312 flash_set_flasher_instance(flash,inst[i]);
313 //g_free (s);
Norman James18998182015-10-11 21:54:53 -0500314
315
Norman James10ff6a32015-08-27 14:24:17 -0500316 //define method callbacks here
Norman James18998182015-10-11 21:54:53 -0500317 g_signal_connect (lock,
318 "handle-lock",
319 G_CALLBACK (on_lock),
320 NULL); /* user_data */
321 g_signal_connect (lock,
322 "handle-unlock",
323 G_CALLBACK (on_unlock),
324 NULL); /* user_data */
325 g_signal_connect (lock,
326 "handle-is-locked",
327 G_CALLBACK (on_is_locked),
328 NULL); /* user_data */
329
Norman James10ff6a32015-08-27 14:24:17 -0500330 g_signal_connect (flash,
Norman James8c6d8382015-10-06 07:47:16 -0500331 "handle-update",
332 G_CALLBACK (on_update),
Norman James18998182015-10-11 21:54:53 -0500333 object); /* user_data */
Norman James166acf42015-10-22 07:11:51 -0500334
335 g_signal_connect (flash,
336 "handle-error",
337 G_CALLBACK (on_error),
338 object); /* user_data */
339
340 g_signal_connect (flash,
341 "handle-done",
342 G_CALLBACK (on_done),
343 object); /* user_data */
344
Norman Jamesf066e872015-10-07 15:29:51 -0500345 g_signal_connect (flash,
346 "handle-update-via-tftp",
347 G_CALLBACK (on_update_via_tftp),
Norman James18998182015-10-11 21:54:53 -0500348 object); /* user_data */
Norman Jamesf066e872015-10-07 15:29:51 -0500349
Norman James471ab592015-08-30 22:29:40 -0500350 g_signal_connect (flash,
351 "handle-init",
352 G_CALLBACK (on_init),
Norman James166acf42015-10-22 07:11:51 -0500353 object); /* user_data */
Norman James471ab592015-08-30 22:29:40 -0500354
Norman James166acf42015-10-22 07:11:51 -0500355 s = g_strdup_printf ("/org/openbmc/control/%s",inst[i]);
Norman James18998182015-10-11 21:54:53 -0500356 g_dbus_connection_signal_subscribe(connection,
357 NULL,
358 "org.openbmc.FlashControl",
359 "Progress",
360 s,
361 NULL,
362 G_DBUS_SIGNAL_FLAGS_NONE,
363 (GDBusSignalCallback) on_flash_progress,
364 object,
365 NULL );
366
367 g_free (s);
Norman Jamesf066e872015-10-07 15:29:51 -0500368
Norman James471ab592015-08-30 22:29:40 -0500369
Norman James18998182015-10-11 21:54:53 -0500370 flash_set_filename(flash,"");
Norman James10ff6a32015-08-27 14:24:17 -0500371 /* Export the object (@manager takes its own reference to @object) */
372 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
373 g_object_unref (object);
374 }
Norman James166acf42015-10-22 07:11:51 -0500375 g_free(flasher_file);
Norman James10ff6a32015-08-27 14:24:17 -0500376 /* Export all objects */
377 g_dbus_object_manager_server_set_connection (manager, connection);
Norman Jamese2765102015-08-19 22:00:55 -0500378}
379
380static void
381on_name_acquired (GDBusConnection *connection,
382 const gchar *name,
383 gpointer user_data)
384{
Norman James362a80f2015-09-14 14:04:39 -0500385// g_print ("Acquired the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500386}
387
388static void
389on_name_lost (GDBusConnection *connection,
390 const gchar *name,
391 gpointer user_data)
392{
Norman James362a80f2015-09-14 14:04:39 -0500393 //g_print ("Lost the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500394}
395
396gint
397main (gint argc, gchar *argv[])
398{
399 GMainLoop *loop;
Norman James952b38d2015-08-27 21:30:06 -0500400 cmdline cmd;
401 cmd.argc = argc;
402 cmd.argv = argv;
Norman Jamese2765102015-08-19 22:00:55 -0500403 guint id;
Norman Jamese2765102015-08-19 22:00:55 -0500404 loop = g_main_loop_new (NULL, FALSE);
405
Norman James5e792e32015-10-07 17:36:17 -0500406 id = g_bus_own_name (DBUS_TYPE,
Norman James26072c02015-08-25 07:14:29 -0500407 dbus_name,
Norman Jamese2765102015-08-19 22:00:55 -0500408 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
409 G_BUS_NAME_OWNER_FLAGS_REPLACE,
410 on_bus_acquired,
411 on_name_acquired,
412 on_name_lost,
Norman James952b38d2015-08-27 21:30:06 -0500413 &cmd,
Norman Jamese2765102015-08-19 22:00:55 -0500414 NULL);
415
416 g_main_loop_run (loop);
417
418 g_bus_unown_name (id);
419 g_main_loop_unref (loop);
420 return 0;
421}