blob: 738ba8658ec8cc682bc8775e517ffec79d31e72a [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 Jamescfc2b442015-10-31 17:31:46 -05006#include "object_mapper.h"
Norman Jamese2765102015-08-19 22:00:55 -05007
8/* ---------------------------------------------------------------------------------------------------- */
Norman James166acf42015-10-22 07:11:51 -05009static const gchar* dbus_object_path = "/org/openbmc/control/flash";
10static const gchar* dbus_name = "org.openbmc.control.Flash";
Norman James18998182015-10-11 21:54:53 -050011static const gchar* FLASHER_BIN = "flasher.exe";
12static const gchar* DLOAD_BUS = "org.openbmc.managers.Download";
13static const gchar* DLOAD_OBJ = "/org/openbmc/managers/Download";
Norman Jamese2765102015-08-19 22:00:55 -050014
15static GDBusObjectManagerServer *manager = NULL;
Norman Jamese2765102015-08-19 22:00:55 -050016
Norman James166acf42015-10-22 07:11:51 -050017int update(Flash* flash, const char* obj_path)
Norman Jamesf066e872015-10-07 15:29:51 -050018{
Norman James18998182015-10-11 21:54:53 -050019 pid_t pid;
20 int status=-1;
21 pid = fork();
22 if (pid == 0)
23 {
24 const gchar* path = flash_get_flasher_path(flash);
25 const gchar* name = flash_get_flasher_name(flash);
26 const gchar* inst = flash_get_flasher_instance(flash);
27 const gchar* filename = flash_get_filename(flash);
Norman James166acf42015-10-22 07:11:51 -050028 status = execl(path, name, inst, filename, obj_path, NULL);
Norman Jamesa3e47c42015-10-18 14:43:10 -050029 return status;
Norman Jamesf066e872015-10-07 15:29:51 -050030 }
Norman Jamesa3e47c42015-10-18 14:43:10 -050031 return 0;
Norman Jamesf066e872015-10-07 15:29:51 -050032}
33
Norman Jamese2765102015-08-19 22:00:55 -050034static gboolean
Norman James471ab592015-08-30 22:29:40 -050035on_init (Flash *f,
36 GDBusMethodInvocation *invocation,
37 gpointer user_data)
38{
Norman James65a295a2015-09-26 22:21:10 -050039 flash_complete_init(f,invocation);
Norman James068efb32015-10-06 16:52:28 -050040
Norman James18998182015-10-11 21:54:53 -050041 //tune flash
Norman James166acf42015-10-22 07:11:51 -050042 if (strcmp(flash_get_flasher_instance(f),"bios") == 0)
Norman James18998182015-10-11 21:54:53 -050043 {
Norman James166acf42015-10-22 07:11:51 -050044 flash_set_filename(f,"");
45 const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data);
46 int rc = update(f,obj_path);
47 if (rc==-1)
48 {
49 printf("ERROR FlashControl: Unable to init\n");
50 }
Norman James50fb3552015-10-28 20:27:23 -050051 //TODO: have to tune flash twice
52 sleep(1);
Norman Jamesd5b5e622015-10-28 20:53:28 -050053 update(f,obj_path);
Norman James18998182015-10-11 21:54:53 -050054 }
55 return TRUE;
56}
Norman James068efb32015-10-06 16:52:28 -050057
Norman James18998182015-10-11 21:54:53 -050058static gboolean
59on_lock (SharedResource *lock,
60 GDBusMethodInvocation *invocation,
61 gchar* name,
62 gpointer user_data)
63{
Norman Jamesa3e47c42015-10-18 14:43:10 -050064 gboolean locked = shared_resource_get_lock(lock);
65 if (locked)
66 {
67 const gchar* name = shared_resource_get_name(lock);
68 printf("ERROR: BIOS Flash is already locked: %s\n",name);
69 }
70 else
71 {
72 printf("Locking BIOS Flash: %s\n",name);
73 shared_resource_set_lock(lock,true);
74 shared_resource_set_name(lock,name);
75 }
Norman James18998182015-10-11 21:54:53 -050076 shared_resource_complete_lock(lock,invocation);
77 return TRUE;
78}
79static gboolean
80on_is_locked (SharedResource *lock,
81 GDBusMethodInvocation *invocation,
82 gpointer user_data)
83{
84 gboolean locked = shared_resource_get_lock(lock);
85 const gchar* name = shared_resource_get_name(lock);
86 shared_resource_complete_is_locked(lock,invocation,locked,name);
87 return TRUE;
88}
89
90
91static gboolean
92on_unlock (SharedResource *lock,
93 GDBusMethodInvocation *invocation,
94 gpointer user_data)
95{
96 printf("Unlocking BIOS Flash\n");
97 shared_resource_set_lock(lock,false);
98 shared_resource_set_name(lock,"");
99 shared_resource_complete_unlock(lock,invocation);
Norman James65a295a2015-09-26 22:21:10 -0500100 return TRUE;
Norman James471ab592015-08-30 22:29:40 -0500101}
102
103static gboolean
Norman Jamesf066e872015-10-07 15:29:51 -0500104on_update_via_tftp (Flash *flash,
105 GDBusMethodInvocation *invocation,
106 gchar* url,
107 gchar* write_file,
108 gpointer user_data)
109{
Norman James18998182015-10-11 21:54:53 -0500110 SharedResource *lock = object_get_shared_resource((Object*)user_data);
111 gboolean locked = shared_resource_get_lock(lock);
Norman Jamesf066e872015-10-07 15:29:51 -0500112 flash_complete_update_via_tftp(flash,invocation);
Norman James18998182015-10-11 21:54:53 -0500113 if (locked)
114 {
115 const gchar* name = shared_resource_get_name(lock);
116 printf("BIOS Flash is locked: %s\n",name);
117 }
118 else
119 {
120 printf("Flashing BIOS from TFTP: %s,%s\n",url,write_file);
Norman James18998182015-10-11 21:54:53 -0500121 flash_set_filename(flash,write_file);
122 flash_emit_download(flash,url,write_file);
Norman James166acf42015-10-22 07:11:51 -0500123 flash_set_status(flash,"Downloading");
Norman James18998182015-10-11 21:54:53 -0500124 }
Norman Jamesf066e872015-10-07 15:29:51 -0500125 return TRUE;
126}
127
128static gboolean
Norman James166acf42015-10-22 07:11:51 -0500129on_error (Flash *flash,
130 GDBusMethodInvocation *invocation,
131 gchar* error_msg,
132 gpointer user_data)
133{
134 int rc = 0;
135 SharedResource *lock = object_get_shared_resource((Object*)user_data);
136 gboolean locked = shared_resource_get_lock(lock);
137 flash_set_status(flash, error_msg);
138 flash_complete_error(flash,invocation);
139 printf("ERROR: %s. Clearing locks\n",error_msg);
140 shared_resource_set_lock(lock,false);
141 shared_resource_set_name(lock,"");
142
143 return TRUE;
144}
145static gboolean
146on_done (Flash *flash,
147 GDBusMethodInvocation *invocation,
148 gpointer user_data)
149{
150 int rc = 0;
151 SharedResource *lock = object_get_shared_resource((Object*)user_data);
152 gboolean locked = shared_resource_get_lock(lock);
153 flash_set_status(flash, "Flash Done");
154 flash_complete_done(flash,invocation);
155 printf("Flash Done. Clearing locks\n");
156 shared_resource_set_lock(lock,false);
157 shared_resource_set_name(lock,"");
158
159 return TRUE;
160}
161
162
163static gboolean
Norman Jamesf066e872015-10-07 15:29:51 -0500164on_update (Flash *flash,
Norman Jamese2765102015-08-19 22:00:55 -0500165 GDBusMethodInvocation *invocation,
166 gchar* write_file,
167 gpointer user_data)
168{
Norman James18998182015-10-11 21:54:53 -0500169 int rc = 0;
170 SharedResource *lock = object_get_shared_resource((Object*)user_data);
171 gboolean locked = shared_resource_get_lock(lock);
Norman James166acf42015-10-22 07:11:51 -0500172 flash_set_status(flash,"Flashing");
Norman Jamesf066e872015-10-07 15:29:51 -0500173 flash_complete_update(flash,invocation);
Norman James18998182015-10-11 21:54:53 -0500174 if (locked)
175 {
176 const gchar* name = shared_resource_get_name(lock);
177 printf("BIOS Flash is locked: %s\n",name);
178 }
179 else
180 {
181 printf("Flashing BIOS from: %s\n",write_file);
Norman James166acf42015-10-22 07:11:51 -0500182 flash_set_status(flash, "Flashing");
Norman James18998182015-10-11 21:54:53 -0500183 shared_resource_set_lock(lock,true);
184 shared_resource_set_name(lock,dbus_object_path);
185 flash_set_filename(flash,write_file);
Norman James166acf42015-10-22 07:11:51 -0500186 const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data);
187 rc = update(flash,obj_path);
Norman James18998182015-10-11 21:54:53 -0500188 if (!rc)
189 {
190 shared_resource_set_lock(lock,false);
191 shared_resource_set_name(lock,"");
192 }
193 }
Norman James068efb32015-10-06 16:52:28 -0500194 return TRUE;
Norman Jamese2765102015-08-19 22:00:55 -0500195}
Norman James18998182015-10-11 21:54:53 -0500196static void
197on_flash_progress (GDBusConnection* connection,
198 const gchar* sender_name,
199 const gchar* object_path,
200 const gchar* interface_name,
201 const gchar* signal_name,
202 GVariant* parameters,
203 gpointer user_data)
204{
205 Flash *flash = object_get_flash((Object*)user_data);
206 SharedResource *lock = object_get_shared_resource((Object*)user_data);
207 GVariantIter *iter = g_variant_iter_new(parameters);
208 GVariant* v_filename = g_variant_iter_next_value(iter);
209 GVariant* v_progress = g_variant_iter_next_value(iter);
Norman Jamesf066e872015-10-07 15:29:51 -0500210
Norman James18998182015-10-11 21:54:53 -0500211 uint8_t progress = g_variant_get_byte(v_progress);
Norman James166acf42015-10-22 07:11:51 -0500212
213 gchar *s;
214 s = g_strdup_printf ("Flashing: %d%%",progress);
215 flash_set_status(flash,s);
216 g_free(s);
Norman James18998182015-10-11 21:54:53 -0500217}
218
219static void
220on_flash_done (GDBusConnection* connection,
221 const gchar* sender_name,
222 const gchar* object_path,
223 const gchar* interface_name,
224 const gchar* signal_name,
225 GVariant* parameters,
226 gpointer user_data)
227{
228 Flash *flash = object_get_flash((Object*)user_data);
229 SharedResource *lock = object_get_shared_resource((Object*)user_data);
230 printf("Flash succeeded; unlocking flash\n");
231 shared_resource_set_lock(lock,false);
232 shared_resource_set_name(lock,"");
Norman James166acf42015-10-22 07:11:51 -0500233 flash_set_status(flash,"Flash Done");
Norman James18998182015-10-11 21:54:53 -0500234}
235
236static void
237on_flash_error (GDBusConnection* connection,
238 const gchar* sender_name,
239 const gchar* object_path,
240 const gchar* interface_name,
241 const gchar* signal_name,
242 GVariant* parameters,
243 gpointer user_data)
244{
245 Flash *flash = object_get_flash((Object*)user_data);
246 SharedResource *lock = object_get_shared_resource((Object*)user_data);
247 printf("Flash Error; unlocking flash\n");
248 shared_resource_set_lock(lock,false);
249 shared_resource_set_name(lock,"");
250}
251
252static void
253on_download_error (GDBusConnection* connection,
254 const gchar* sender_name,
255 const gchar* object_path,
256 const gchar* interface_name,
257 const gchar* signal_name,
258 GVariant* parameters,
259 gpointer user_data)
260{
261 Flash *flash = object_get_flash((Object*)user_data);
262 SharedResource *lock = object_get_shared_resource((Object*)user_data);
263 printf("ERROR: FlashBios: Download error; clearing flash lock\n");
264 shared_resource_set_lock(lock,false);
265 shared_resource_set_name(lock,"");
Norman Jamesf066e872015-10-07 15:29:51 -0500266}
267
Norman Jamese2765102015-08-19 22:00:55 -0500268static void
269on_bus_acquired (GDBusConnection *connection,
270 const gchar *name,
271 gpointer user_data)
272{
Norman James10ff6a32015-08-27 14:24:17 -0500273 ObjectSkeleton *object;
Norman James10ff6a32015-08-27 14:24:17 -0500274 cmdline *cmd = user_data;
Norman James10ff6a32015-08-27 14:24:17 -0500275 manager = g_dbus_object_manager_server_new (dbus_object_path);
276 int i=0;
Norman James166acf42015-10-22 07:11:51 -0500277
278 //TODO: don't use fixed buffer
279 char flasher_path[512];
280 memset(flasher_path, '\0', sizeof(flasher_path));
281 bool found = false;
282 gchar *flasher_file;
283 int c = strlen(cmd->argv[0]);
284 while(c>0)
285 {
286 if (cmd->argv[0][c] == '/')
287 {
288 strncpy(flasher_path,cmd->argv[0],c);
289 flasher_file = g_strdup_printf ("%s/%s",flasher_path,FLASHER_BIN);
290 break;
291 }
292 c--;
293 }
294
Norman James15aaa802015-10-28 06:54:48 -0500295 const char* inst[] = {"bios","bmc","bmc_ramdisk","bmc_kernel"};
296 for (i=0;i<4;i++)
Norman James10ff6a32015-08-27 14:24:17 -0500297 {
Norman James166acf42015-10-22 07:11:51 -0500298 gchar* s;
299 s = g_strdup_printf ("%s/%s",dbus_object_path,inst[i]);
Norman James10ff6a32015-08-27 14:24:17 -0500300 object = object_skeleton_new (s);
301 g_free (s);
Norman Jamese2765102015-08-19 22:00:55 -0500302
Norman James10ff6a32015-08-27 14:24:17 -0500303 Flash* flash = flash_skeleton_new ();
304 object_skeleton_set_flash (object, flash);
305 g_object_unref (flash);
Norman Jamese2765102015-08-19 22:00:55 -0500306
Norman James18998182015-10-11 21:54:53 -0500307 SharedResource* lock = shared_resource_skeleton_new ();
308 object_skeleton_set_shared_resource (object, lock);
309 g_object_unref (lock);
310
Norman Jamescfc2b442015-10-31 17:31:46 -0500311 ObjectMapper* mapper = object_mapper_skeleton_new ();
312 object_skeleton_set_object_mapper (object, mapper);
313 g_object_unref (mapper);
314
Norman James18998182015-10-11 21:54:53 -0500315 shared_resource_set_lock(lock,false);
316 shared_resource_set_name(lock,"");
317
Norman James166acf42015-10-22 07:11:51 -0500318 flash_set_flasher_path(flash,flasher_file);
319 flash_set_flasher_name(flash,FLASHER_BIN);
320 flash_set_flasher_instance(flash,inst[i]);
321 //g_free (s);
Norman James18998182015-10-11 21:54:53 -0500322
323
Norman James10ff6a32015-08-27 14:24:17 -0500324 //define method callbacks here
Norman James18998182015-10-11 21:54:53 -0500325 g_signal_connect (lock,
326 "handle-lock",
327 G_CALLBACK (on_lock),
328 NULL); /* user_data */
329 g_signal_connect (lock,
330 "handle-unlock",
331 G_CALLBACK (on_unlock),
332 NULL); /* user_data */
333 g_signal_connect (lock,
334 "handle-is-locked",
335 G_CALLBACK (on_is_locked),
336 NULL); /* user_data */
337
Norman James10ff6a32015-08-27 14:24:17 -0500338 g_signal_connect (flash,
Norman James8c6d8382015-10-06 07:47:16 -0500339 "handle-update",
340 G_CALLBACK (on_update),
Norman James18998182015-10-11 21:54:53 -0500341 object); /* user_data */
Norman James166acf42015-10-22 07:11:51 -0500342
343 g_signal_connect (flash,
344 "handle-error",
345 G_CALLBACK (on_error),
346 object); /* user_data */
347
348 g_signal_connect (flash,
349 "handle-done",
350 G_CALLBACK (on_done),
351 object); /* user_data */
352
Norman Jamesf066e872015-10-07 15:29:51 -0500353 g_signal_connect (flash,
354 "handle-update-via-tftp",
355 G_CALLBACK (on_update_via_tftp),
Norman James18998182015-10-11 21:54:53 -0500356 object); /* user_data */
Norman Jamesf066e872015-10-07 15:29:51 -0500357
Norman James471ab592015-08-30 22:29:40 -0500358 g_signal_connect (flash,
359 "handle-init",
360 G_CALLBACK (on_init),
Norman James166acf42015-10-22 07:11:51 -0500361 object); /* user_data */
Norman James471ab592015-08-30 22:29:40 -0500362
Norman James166acf42015-10-22 07:11:51 -0500363 s = g_strdup_printf ("/org/openbmc/control/%s",inst[i]);
Norman James18998182015-10-11 21:54:53 -0500364 g_dbus_connection_signal_subscribe(connection,
365 NULL,
366 "org.openbmc.FlashControl",
367 "Progress",
368 s,
369 NULL,
370 G_DBUS_SIGNAL_FLAGS_NONE,
371 (GDBusSignalCallback) on_flash_progress,
372 object,
373 NULL );
374
375 g_free (s);
Norman Jamesf066e872015-10-07 15:29:51 -0500376
Norman James471ab592015-08-30 22:29:40 -0500377
Norman James18998182015-10-11 21:54:53 -0500378 flash_set_filename(flash,"");
Norman James10ff6a32015-08-27 14:24:17 -0500379 /* Export the object (@manager takes its own reference to @object) */
380 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
381 g_object_unref (object);
382 }
Norman James166acf42015-10-22 07:11:51 -0500383 g_free(flasher_file);
Norman James10ff6a32015-08-27 14:24:17 -0500384 /* Export all objects */
385 g_dbus_object_manager_server_set_connection (manager, connection);
Norman Jamescfc2b442015-10-31 17:31:46 -0500386 emit_object_added((GDBusObjectManager*)manager);
Norman Jamese2765102015-08-19 22:00:55 -0500387}
388
389static void
390on_name_acquired (GDBusConnection *connection,
391 const gchar *name,
392 gpointer user_data)
393{
Norman James362a80f2015-09-14 14:04:39 -0500394// g_print ("Acquired the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500395}
396
397static void
398on_name_lost (GDBusConnection *connection,
399 const gchar *name,
400 gpointer user_data)
401{
Norman James362a80f2015-09-14 14:04:39 -0500402 //g_print ("Lost the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500403}
404
405gint
406main (gint argc, gchar *argv[])
407{
408 GMainLoop *loop;
Norman James952b38d2015-08-27 21:30:06 -0500409 cmdline cmd;
410 cmd.argc = argc;
411 cmd.argv = argv;
Norman Jamese2765102015-08-19 22:00:55 -0500412 guint id;
Norman Jamese2765102015-08-19 22:00:55 -0500413 loop = g_main_loop_new (NULL, FALSE);
414
Norman James5e792e32015-10-07 17:36:17 -0500415 id = g_bus_own_name (DBUS_TYPE,
Norman James26072c02015-08-25 07:14:29 -0500416 dbus_name,
Norman Jamese2765102015-08-19 22:00:55 -0500417 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
418 G_BUS_NAME_OWNER_FLAGS_REPLACE,
419 on_bus_acquired,
420 on_name_acquired,
421 on_name_lost,
Norman James952b38d2015-08-27 21:30:06 -0500422 &cmd,
Norman Jamese2765102015-08-19 22:00:55 -0500423 NULL);
424
425 g_main_loop_run (loop);
426
427 g_bus_unown_name (id);
428 g_main_loop_unref (loop);
429 return 0;
430}