blob: 4b82d67c705e62777aed4710dba128cbfbf218b3 [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 James50fb3552015-10-28 20:27:23 -050050 //TODO: have to tune flash twice
51 sleep(1);
Norman Jamesd5b5e622015-10-28 20:53:28 -050052 update(f,obj_path);
Norman James18998182015-10-11 21:54:53 -050053 }
54 return TRUE;
55}
Norman James068efb32015-10-06 16:52:28 -050056
Norman James18998182015-10-11 21:54:53 -050057static gboolean
58on_lock (SharedResource *lock,
59 GDBusMethodInvocation *invocation,
60 gchar* name,
61 gpointer user_data)
62{
Norman Jamesa3e47c42015-10-18 14:43:10 -050063 gboolean locked = shared_resource_get_lock(lock);
64 if (locked)
65 {
66 const gchar* name = shared_resource_get_name(lock);
67 printf("ERROR: BIOS Flash is already locked: %s\n",name);
68 }
69 else
70 {
71 printf("Locking BIOS Flash: %s\n",name);
72 shared_resource_set_lock(lock,true);
73 shared_resource_set_name(lock,name);
74 }
Norman James18998182015-10-11 21:54:53 -050075 shared_resource_complete_lock(lock,invocation);
76 return TRUE;
77}
78static gboolean
79on_is_locked (SharedResource *lock,
80 GDBusMethodInvocation *invocation,
81 gpointer user_data)
82{
83 gboolean locked = shared_resource_get_lock(lock);
84 const gchar* name = shared_resource_get_name(lock);
85 shared_resource_complete_is_locked(lock,invocation,locked,name);
86 return TRUE;
87}
88
89
90static gboolean
91on_unlock (SharedResource *lock,
92 GDBusMethodInvocation *invocation,
93 gpointer user_data)
94{
95 printf("Unlocking BIOS Flash\n");
96 shared_resource_set_lock(lock,false);
97 shared_resource_set_name(lock,"");
98 shared_resource_complete_unlock(lock,invocation);
Norman James65a295a2015-09-26 22:21:10 -050099 return TRUE;
Norman James471ab592015-08-30 22:29:40 -0500100}
101
102static gboolean
Norman Jamesf066e872015-10-07 15:29:51 -0500103on_update_via_tftp (Flash *flash,
104 GDBusMethodInvocation *invocation,
105 gchar* url,
106 gchar* write_file,
107 gpointer user_data)
108{
Norman James18998182015-10-11 21:54:53 -0500109 SharedResource *lock = object_get_shared_resource((Object*)user_data);
110 gboolean locked = shared_resource_get_lock(lock);
Norman Jamesf066e872015-10-07 15:29:51 -0500111 flash_complete_update_via_tftp(flash,invocation);
Norman James18998182015-10-11 21:54:53 -0500112 if (locked)
113 {
114 const gchar* name = shared_resource_get_name(lock);
115 printf("BIOS Flash is locked: %s\n",name);
116 }
117 else
118 {
119 printf("Flashing BIOS from TFTP: %s,%s\n",url,write_file);
Norman James18998182015-10-11 21:54:53 -0500120 flash_set_filename(flash,write_file);
121 flash_emit_download(flash,url,write_file);
Norman James166acf42015-10-22 07:11:51 -0500122 flash_set_status(flash,"Downloading");
Norman James18998182015-10-11 21:54:53 -0500123 }
Norman Jamesf066e872015-10-07 15:29:51 -0500124 return TRUE;
125}
126
127static gboolean
Norman James166acf42015-10-22 07:11:51 -0500128on_error (Flash *flash,
129 GDBusMethodInvocation *invocation,
130 gchar* error_msg,
131 gpointer user_data)
132{
133 int rc = 0;
134 SharedResource *lock = object_get_shared_resource((Object*)user_data);
135 gboolean locked = shared_resource_get_lock(lock);
136 flash_set_status(flash, error_msg);
137 flash_complete_error(flash,invocation);
138 printf("ERROR: %s. Clearing locks\n",error_msg);
139 shared_resource_set_lock(lock,false);
140 shared_resource_set_name(lock,"");
141
142 return TRUE;
143}
144static gboolean
145on_done (Flash *flash,
146 GDBusMethodInvocation *invocation,
147 gpointer user_data)
148{
149 int rc = 0;
150 SharedResource *lock = object_get_shared_resource((Object*)user_data);
151 gboolean locked = shared_resource_get_lock(lock);
152 flash_set_status(flash, "Flash Done");
153 flash_complete_done(flash,invocation);
154 printf("Flash Done. Clearing locks\n");
155 shared_resource_set_lock(lock,false);
156 shared_resource_set_name(lock,"");
157
158 return TRUE;
159}
160
161
162static gboolean
Norman Jamesf066e872015-10-07 15:29:51 -0500163on_update (Flash *flash,
Norman Jamese2765102015-08-19 22:00:55 -0500164 GDBusMethodInvocation *invocation,
165 gchar* write_file,
166 gpointer user_data)
167{
Norman James18998182015-10-11 21:54:53 -0500168 int rc = 0;
169 SharedResource *lock = object_get_shared_resource((Object*)user_data);
170 gboolean locked = shared_resource_get_lock(lock);
Norman James166acf42015-10-22 07:11:51 -0500171 flash_set_status(flash,"Flashing");
Norman Jamesf066e872015-10-07 15:29:51 -0500172 flash_complete_update(flash,invocation);
Norman James18998182015-10-11 21:54:53 -0500173 if (locked)
174 {
175 const gchar* name = shared_resource_get_name(lock);
176 printf("BIOS Flash is locked: %s\n",name);
177 }
178 else
179 {
180 printf("Flashing BIOS from: %s\n",write_file);
Norman James166acf42015-10-22 07:11:51 -0500181 flash_set_status(flash, "Flashing");
Norman James18998182015-10-11 21:54:53 -0500182 shared_resource_set_lock(lock,true);
183 shared_resource_set_name(lock,dbus_object_path);
184 flash_set_filename(flash,write_file);
Norman James166acf42015-10-22 07:11:51 -0500185 const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data);
186 rc = update(flash,obj_path);
Norman James18998182015-10-11 21:54:53 -0500187 if (!rc)
188 {
189 shared_resource_set_lock(lock,false);
190 shared_resource_set_name(lock,"");
191 }
192 }
Norman James068efb32015-10-06 16:52:28 -0500193 return TRUE;
Norman Jamese2765102015-08-19 22:00:55 -0500194}
Norman James18998182015-10-11 21:54:53 -0500195static void
196on_flash_progress (GDBusConnection* connection,
197 const gchar* sender_name,
198 const gchar* object_path,
199 const gchar* interface_name,
200 const gchar* signal_name,
201 GVariant* parameters,
202 gpointer user_data)
203{
204 Flash *flash = object_get_flash((Object*)user_data);
205 SharedResource *lock = object_get_shared_resource((Object*)user_data);
206 GVariantIter *iter = g_variant_iter_new(parameters);
207 GVariant* v_filename = g_variant_iter_next_value(iter);
208 GVariant* v_progress = g_variant_iter_next_value(iter);
Norman Jamesf066e872015-10-07 15:29:51 -0500209
Norman James18998182015-10-11 21:54:53 -0500210 uint8_t progress = g_variant_get_byte(v_progress);
Norman James166acf42015-10-22 07:11:51 -0500211
212 gchar *s;
213 s = g_strdup_printf ("Flashing: %d%%",progress);
214 flash_set_status(flash,s);
215 g_free(s);
Norman James18998182015-10-11 21:54:53 -0500216}
217
218static void
219on_flash_done (GDBusConnection* connection,
220 const gchar* sender_name,
221 const gchar* object_path,
222 const gchar* interface_name,
223 const gchar* signal_name,
224 GVariant* parameters,
225 gpointer user_data)
226{
227 Flash *flash = object_get_flash((Object*)user_data);
228 SharedResource *lock = object_get_shared_resource((Object*)user_data);
229 printf("Flash succeeded; unlocking flash\n");
230 shared_resource_set_lock(lock,false);
231 shared_resource_set_name(lock,"");
Norman James166acf42015-10-22 07:11:51 -0500232 flash_set_status(flash,"Flash Done");
Norman James18998182015-10-11 21:54:53 -0500233}
234
235static void
236on_flash_error (GDBusConnection* connection,
237 const gchar* sender_name,
238 const gchar* object_path,
239 const gchar* interface_name,
240 const gchar* signal_name,
241 GVariant* parameters,
242 gpointer user_data)
243{
244 Flash *flash = object_get_flash((Object*)user_data);
245 SharedResource *lock = object_get_shared_resource((Object*)user_data);
246 printf("Flash Error; unlocking flash\n");
247 shared_resource_set_lock(lock,false);
248 shared_resource_set_name(lock,"");
249}
250
251static void
252on_download_error (GDBusConnection* connection,
253 const gchar* sender_name,
254 const gchar* object_path,
255 const gchar* interface_name,
256 const gchar* signal_name,
257 GVariant* parameters,
258 gpointer user_data)
259{
260 Flash *flash = object_get_flash((Object*)user_data);
261 SharedResource *lock = object_get_shared_resource((Object*)user_data);
262 printf("ERROR: FlashBios: Download error; clearing flash lock\n");
263 shared_resource_set_lock(lock,false);
264 shared_resource_set_name(lock,"");
Norman Jamesf066e872015-10-07 15:29:51 -0500265}
266
Norman Jamese2765102015-08-19 22:00:55 -0500267static void
268on_bus_acquired (GDBusConnection *connection,
269 const gchar *name,
270 gpointer user_data)
271{
Norman James10ff6a32015-08-27 14:24:17 -0500272 ObjectSkeleton *object;
Norman James10ff6a32015-08-27 14:24:17 -0500273 cmdline *cmd = user_data;
Norman James10ff6a32015-08-27 14:24:17 -0500274 manager = g_dbus_object_manager_server_new (dbus_object_path);
275 int i=0;
Norman James166acf42015-10-22 07:11:51 -0500276
277 //TODO: don't use fixed buffer
278 char flasher_path[512];
279 memset(flasher_path, '\0', sizeof(flasher_path));
280 bool found = false;
281 gchar *flasher_file;
282 int c = strlen(cmd->argv[0]);
283 while(c>0)
284 {
285 if (cmd->argv[0][c] == '/')
286 {
287 strncpy(flasher_path,cmd->argv[0],c);
288 flasher_file = g_strdup_printf ("%s/%s",flasher_path,FLASHER_BIN);
289 break;
290 }
291 c--;
292 }
293
Norman James15aaa802015-10-28 06:54:48 -0500294 const char* inst[] = {"bios","bmc","bmc_ramdisk","bmc_kernel"};
295 for (i=0;i<4;i++)
Norman James10ff6a32015-08-27 14:24:17 -0500296 {
Norman James166acf42015-10-22 07:11:51 -0500297 gchar* s;
298 s = g_strdup_printf ("%s/%s",dbus_object_path,inst[i]);
Norman James10ff6a32015-08-27 14:24:17 -0500299 object = object_skeleton_new (s);
300 g_free (s);
Norman Jamese2765102015-08-19 22:00:55 -0500301
Norman James10ff6a32015-08-27 14:24:17 -0500302 Flash* flash = flash_skeleton_new ();
303 object_skeleton_set_flash (object, flash);
304 g_object_unref (flash);
Norman Jamese2765102015-08-19 22:00:55 -0500305
Norman James18998182015-10-11 21:54:53 -0500306 SharedResource* lock = shared_resource_skeleton_new ();
307 object_skeleton_set_shared_resource (object, lock);
308 g_object_unref (lock);
309
310 shared_resource_set_lock(lock,false);
311 shared_resource_set_name(lock,"");
312
Norman James166acf42015-10-22 07:11:51 -0500313 flash_set_flasher_path(flash,flasher_file);
314 flash_set_flasher_name(flash,FLASHER_BIN);
315 flash_set_flasher_instance(flash,inst[i]);
316 //g_free (s);
Norman James18998182015-10-11 21:54:53 -0500317
318
Norman James10ff6a32015-08-27 14:24:17 -0500319 //define method callbacks here
Norman James18998182015-10-11 21:54:53 -0500320 g_signal_connect (lock,
321 "handle-lock",
322 G_CALLBACK (on_lock),
323 NULL); /* user_data */
324 g_signal_connect (lock,
325 "handle-unlock",
326 G_CALLBACK (on_unlock),
327 NULL); /* user_data */
328 g_signal_connect (lock,
329 "handle-is-locked",
330 G_CALLBACK (on_is_locked),
331 NULL); /* user_data */
332
Norman James10ff6a32015-08-27 14:24:17 -0500333 g_signal_connect (flash,
Norman James8c6d8382015-10-06 07:47:16 -0500334 "handle-update",
335 G_CALLBACK (on_update),
Norman James18998182015-10-11 21:54:53 -0500336 object); /* user_data */
Norman James166acf42015-10-22 07:11:51 -0500337
338 g_signal_connect (flash,
339 "handle-error",
340 G_CALLBACK (on_error),
341 object); /* user_data */
342
343 g_signal_connect (flash,
344 "handle-done",
345 G_CALLBACK (on_done),
346 object); /* user_data */
347
Norman Jamesf066e872015-10-07 15:29:51 -0500348 g_signal_connect (flash,
349 "handle-update-via-tftp",
350 G_CALLBACK (on_update_via_tftp),
Norman James18998182015-10-11 21:54:53 -0500351 object); /* user_data */
Norman Jamesf066e872015-10-07 15:29:51 -0500352
Norman James471ab592015-08-30 22:29:40 -0500353 g_signal_connect (flash,
354 "handle-init",
355 G_CALLBACK (on_init),
Norman James166acf42015-10-22 07:11:51 -0500356 object); /* user_data */
Norman James471ab592015-08-30 22:29:40 -0500357
Norman James166acf42015-10-22 07:11:51 -0500358 s = g_strdup_printf ("/org/openbmc/control/%s",inst[i]);
Norman James18998182015-10-11 21:54:53 -0500359 g_dbus_connection_signal_subscribe(connection,
360 NULL,
361 "org.openbmc.FlashControl",
362 "Progress",
363 s,
364 NULL,
365 G_DBUS_SIGNAL_FLAGS_NONE,
366 (GDBusSignalCallback) on_flash_progress,
367 object,
368 NULL );
369
370 g_free (s);
Norman Jamesf066e872015-10-07 15:29:51 -0500371
Norman James471ab592015-08-30 22:29:40 -0500372
Norman James18998182015-10-11 21:54:53 -0500373 flash_set_filename(flash,"");
Norman James10ff6a32015-08-27 14:24:17 -0500374 /* Export the object (@manager takes its own reference to @object) */
375 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
376 g_object_unref (object);
377 }
Norman James166acf42015-10-22 07:11:51 -0500378 g_free(flasher_file);
Norman James10ff6a32015-08-27 14:24:17 -0500379 /* Export all objects */
380 g_dbus_object_manager_server_set_connection (manager, connection);
Norman Jamese2765102015-08-19 22:00:55 -0500381}
382
383static void
384on_name_acquired (GDBusConnection *connection,
385 const gchar *name,
386 gpointer user_data)
387{
Norman James362a80f2015-09-14 14:04:39 -0500388// g_print ("Acquired the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500389}
390
391static void
392on_name_lost (GDBusConnection *connection,
393 const gchar *name,
394 gpointer user_data)
395{
Norman James362a80f2015-09-14 14:04:39 -0500396 //g_print ("Lost the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500397}
398
399gint
400main (gint argc, gchar *argv[])
401{
402 GMainLoop *loop;
Norman James952b38d2015-08-27 21:30:06 -0500403 cmdline cmd;
404 cmd.argc = argc;
405 cmd.argv = argv;
Norman Jamese2765102015-08-19 22:00:55 -0500406 guint id;
Norman Jamese2765102015-08-19 22:00:55 -0500407 loop = g_main_loop_new (NULL, FALSE);
408
Norman James5e792e32015-10-07 17:36:17 -0500409 id = g_bus_own_name (DBUS_TYPE,
Norman James26072c02015-08-25 07:14:29 -0500410 dbus_name,
Norman Jamese2765102015-08-19 22:00:55 -0500411 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
412 G_BUS_NAME_OWNER_FLAGS_REPLACE,
413 on_bus_acquired,
414 on_name_acquired,
415 on_name_lost,
Norman James952b38d2015-08-27 21:30:06 -0500416 &cmd,
Norman Jamese2765102015-08-19 22:00:55 -0500417 NULL);
418
419 g_main_loop_run (loop);
420
421 g_bus_unown_name (id);
422 g_main_loop_unref (loop);
423 return 0;
424}