blob: d9ad04deb2fcd5796f9c42543700428cfc428084 [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 printf(" >>>>>>>>>> %s\n",flash_get_flasher_instance(f));
42 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 James18998182015-10-11 21:54:53 -050051 }
52 return TRUE;
53}
Norman James068efb32015-10-06 16:52:28 -050054
Norman James18998182015-10-11 21:54:53 -050055static gboolean
56on_lock (SharedResource *lock,
57 GDBusMethodInvocation *invocation,
58 gchar* name,
59 gpointer user_data)
60{
Norman Jamesa3e47c42015-10-18 14:43:10 -050061 gboolean locked = shared_resource_get_lock(lock);
62 if (locked)
63 {
64 const gchar* name = shared_resource_get_name(lock);
65 printf("ERROR: BIOS Flash is already locked: %s\n",name);
66 }
67 else
68 {
69 printf("Locking BIOS Flash: %s\n",name);
70 shared_resource_set_lock(lock,true);
71 shared_resource_set_name(lock,name);
72 }
Norman James18998182015-10-11 21:54:53 -050073 shared_resource_complete_lock(lock,invocation);
74 return TRUE;
75}
76static gboolean
77on_is_locked (SharedResource *lock,
78 GDBusMethodInvocation *invocation,
79 gpointer user_data)
80{
81 gboolean locked = shared_resource_get_lock(lock);
82 const gchar* name = shared_resource_get_name(lock);
83 shared_resource_complete_is_locked(lock,invocation,locked,name);
84 return TRUE;
85}
86
87
88static gboolean
89on_unlock (SharedResource *lock,
90 GDBusMethodInvocation *invocation,
91 gpointer user_data)
92{
93 printf("Unlocking BIOS Flash\n");
94 shared_resource_set_lock(lock,false);
95 shared_resource_set_name(lock,"");
96 shared_resource_complete_unlock(lock,invocation);
Norman James65a295a2015-09-26 22:21:10 -050097 return TRUE;
Norman James471ab592015-08-30 22:29:40 -050098}
99
100static gboolean
Norman Jamesf066e872015-10-07 15:29:51 -0500101on_update_via_tftp (Flash *flash,
102 GDBusMethodInvocation *invocation,
103 gchar* url,
104 gchar* write_file,
105 gpointer user_data)
106{
Norman James18998182015-10-11 21:54:53 -0500107 SharedResource *lock = object_get_shared_resource((Object*)user_data);
108 gboolean locked = shared_resource_get_lock(lock);
Norman Jamesf066e872015-10-07 15:29:51 -0500109 flash_complete_update_via_tftp(flash,invocation);
Norman James18998182015-10-11 21:54:53 -0500110 if (locked)
111 {
112 const gchar* name = shared_resource_get_name(lock);
113 printf("BIOS Flash is locked: %s\n",name);
114 }
115 else
116 {
117 printf("Flashing BIOS from TFTP: %s,%s\n",url,write_file);
Norman James18998182015-10-11 21:54:53 -0500118 flash_set_filename(flash,write_file);
119 flash_emit_download(flash,url,write_file);
Norman James166acf42015-10-22 07:11:51 -0500120 flash_set_status(flash,"Downloading");
Norman James18998182015-10-11 21:54:53 -0500121 }
Norman Jamesf066e872015-10-07 15:29:51 -0500122 return TRUE;
123}
124
125static gboolean
Norman James166acf42015-10-22 07:11:51 -0500126on_error (Flash *flash,
127 GDBusMethodInvocation *invocation,
128 gchar* error_msg,
129 gpointer user_data)
130{
131 int rc = 0;
132 SharedResource *lock = object_get_shared_resource((Object*)user_data);
133 gboolean locked = shared_resource_get_lock(lock);
134 flash_set_status(flash, error_msg);
135 flash_complete_error(flash,invocation);
136 printf("ERROR: %s. Clearing locks\n",error_msg);
137 shared_resource_set_lock(lock,false);
138 shared_resource_set_name(lock,"");
139
140 return TRUE;
141}
142static gboolean
143on_done (Flash *flash,
144 GDBusMethodInvocation *invocation,
145 gpointer user_data)
146{
147 int rc = 0;
148 SharedResource *lock = object_get_shared_resource((Object*)user_data);
149 gboolean locked = shared_resource_get_lock(lock);
150 flash_set_status(flash, "Flash Done");
151 flash_complete_done(flash,invocation);
152 printf("Flash Done. Clearing locks\n");
153 shared_resource_set_lock(lock,false);
154 shared_resource_set_name(lock,"");
155
156 return TRUE;
157}
158
159
160static gboolean
Norman Jamesf066e872015-10-07 15:29:51 -0500161on_update (Flash *flash,
Norman Jamese2765102015-08-19 22:00:55 -0500162 GDBusMethodInvocation *invocation,
163 gchar* write_file,
164 gpointer user_data)
165{
Norman James18998182015-10-11 21:54:53 -0500166 int rc = 0;
167 SharedResource *lock = object_get_shared_resource((Object*)user_data);
168 gboolean locked = shared_resource_get_lock(lock);
Norman James166acf42015-10-22 07:11:51 -0500169 flash_set_status(flash,"Flashing");
Norman Jamesf066e872015-10-07 15:29:51 -0500170 flash_complete_update(flash,invocation);
Norman James18998182015-10-11 21:54:53 -0500171 if (locked)
172 {
173 const gchar* name = shared_resource_get_name(lock);
174 printf("BIOS Flash is locked: %s\n",name);
175 }
176 else
177 {
178 printf("Flashing BIOS from: %s\n",write_file);
Norman James166acf42015-10-22 07:11:51 -0500179 flash_set_status(flash, "Flashing");
Norman James18998182015-10-11 21:54:53 -0500180 shared_resource_set_lock(lock,true);
181 shared_resource_set_name(lock,dbus_object_path);
182 flash_set_filename(flash,write_file);
Norman James166acf42015-10-22 07:11:51 -0500183 const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data);
184 rc = update(flash,obj_path);
Norman James18998182015-10-11 21:54:53 -0500185 if (!rc)
186 {
187 shared_resource_set_lock(lock,false);
188 shared_resource_set_name(lock,"");
189 }
190 }
Norman James068efb32015-10-06 16:52:28 -0500191 return TRUE;
Norman Jamese2765102015-08-19 22:00:55 -0500192}
Norman James18998182015-10-11 21:54:53 -0500193static void
194on_flash_progress (GDBusConnection* connection,
195 const gchar* sender_name,
196 const gchar* object_path,
197 const gchar* interface_name,
198 const gchar* signal_name,
199 GVariant* parameters,
200 gpointer user_data)
201{
202 Flash *flash = object_get_flash((Object*)user_data);
203 SharedResource *lock = object_get_shared_resource((Object*)user_data);
204 GVariantIter *iter = g_variant_iter_new(parameters);
205 GVariant* v_filename = g_variant_iter_next_value(iter);
206 GVariant* v_progress = g_variant_iter_next_value(iter);
Norman Jamesf066e872015-10-07 15:29:51 -0500207
Norman James18998182015-10-11 21:54:53 -0500208 uint8_t progress = g_variant_get_byte(v_progress);
Norman James166acf42015-10-22 07:11:51 -0500209
210 gchar *s;
211 s = g_strdup_printf ("Flashing: %d%%",progress);
212 flash_set_status(flash,s);
213 g_free(s);
Norman James18998182015-10-11 21:54:53 -0500214}
215
216static void
217on_flash_done (GDBusConnection* connection,
218 const gchar* sender_name,
219 const gchar* object_path,
220 const gchar* interface_name,
221 const gchar* signal_name,
222 GVariant* parameters,
223 gpointer user_data)
224{
225 Flash *flash = object_get_flash((Object*)user_data);
226 SharedResource *lock = object_get_shared_resource((Object*)user_data);
227 printf("Flash succeeded; unlocking flash\n");
228 shared_resource_set_lock(lock,false);
229 shared_resource_set_name(lock,"");
Norman James166acf42015-10-22 07:11:51 -0500230 flash_set_status(flash,"Flash Done");
Norman James18998182015-10-11 21:54:53 -0500231}
232
233static void
234on_flash_error (GDBusConnection* connection,
235 const gchar* sender_name,
236 const gchar* object_path,
237 const gchar* interface_name,
238 const gchar* signal_name,
239 GVariant* parameters,
240 gpointer user_data)
241{
242 Flash *flash = object_get_flash((Object*)user_data);
243 SharedResource *lock = object_get_shared_resource((Object*)user_data);
244 printf("Flash Error; unlocking flash\n");
245 shared_resource_set_lock(lock,false);
246 shared_resource_set_name(lock,"");
247}
248
249static void
250on_download_error (GDBusConnection* connection,
251 const gchar* sender_name,
252 const gchar* object_path,
253 const gchar* interface_name,
254 const gchar* signal_name,
255 GVariant* parameters,
256 gpointer user_data)
257{
258 Flash *flash = object_get_flash((Object*)user_data);
259 SharedResource *lock = object_get_shared_resource((Object*)user_data);
260 printf("ERROR: FlashBios: Download error; clearing flash lock\n");
261 shared_resource_set_lock(lock,false);
262 shared_resource_set_name(lock,"");
Norman Jamesf066e872015-10-07 15:29:51 -0500263}
264
Norman Jamese2765102015-08-19 22:00:55 -0500265static void
266on_bus_acquired (GDBusConnection *connection,
267 const gchar *name,
268 gpointer user_data)
269{
Norman James10ff6a32015-08-27 14:24:17 -0500270 ObjectSkeleton *object;
Norman James10ff6a32015-08-27 14:24:17 -0500271 cmdline *cmd = user_data;
Norman James10ff6a32015-08-27 14:24:17 -0500272 manager = g_dbus_object_manager_server_new (dbus_object_path);
273 int i=0;
Norman James166acf42015-10-22 07:11:51 -0500274
275 //TODO: don't use fixed buffer
276 char flasher_path[512];
277 memset(flasher_path, '\0', sizeof(flasher_path));
278 bool found = false;
279 gchar *flasher_file;
280 int c = strlen(cmd->argv[0]);
281 while(c>0)
282 {
283 if (cmd->argv[0][c] == '/')
284 {
285 strncpy(flasher_path,cmd->argv[0],c);
286 flasher_file = g_strdup_printf ("%s/%s",flasher_path,FLASHER_BIN);
287 break;
288 }
289 c--;
290 }
291
292 const char* inst[] = {"bios","bmc"};
293 for (i=0;i<2;i++)
Norman James10ff6a32015-08-27 14:24:17 -0500294 {
Norman James166acf42015-10-22 07:11:51 -0500295 gchar* s;
296 s = g_strdup_printf ("%s/%s",dbus_object_path,inst[i]);
Norman James10ff6a32015-08-27 14:24:17 -0500297 object = object_skeleton_new (s);
298 g_free (s);
Norman Jamese2765102015-08-19 22:00:55 -0500299
Norman James10ff6a32015-08-27 14:24:17 -0500300 Flash* flash = flash_skeleton_new ();
301 object_skeleton_set_flash (object, flash);
302 g_object_unref (flash);
Norman Jamese2765102015-08-19 22:00:55 -0500303
Norman James18998182015-10-11 21:54:53 -0500304 SharedResource* lock = shared_resource_skeleton_new ();
305 object_skeleton_set_shared_resource (object, lock);
306 g_object_unref (lock);
307
308 shared_resource_set_lock(lock,false);
309 shared_resource_set_name(lock,"");
310
Norman James166acf42015-10-22 07:11:51 -0500311 flash_set_flasher_path(flash,flasher_file);
312 flash_set_flasher_name(flash,FLASHER_BIN);
313 flash_set_flasher_instance(flash,inst[i]);
314 //g_free (s);
Norman James18998182015-10-11 21:54:53 -0500315
316
Norman James10ff6a32015-08-27 14:24:17 -0500317 //define method callbacks here
Norman James18998182015-10-11 21:54:53 -0500318 g_signal_connect (lock,
319 "handle-lock",
320 G_CALLBACK (on_lock),
321 NULL); /* user_data */
322 g_signal_connect (lock,
323 "handle-unlock",
324 G_CALLBACK (on_unlock),
325 NULL); /* user_data */
326 g_signal_connect (lock,
327 "handle-is-locked",
328 G_CALLBACK (on_is_locked),
329 NULL); /* user_data */
330
Norman James10ff6a32015-08-27 14:24:17 -0500331 g_signal_connect (flash,
Norman James8c6d8382015-10-06 07:47:16 -0500332 "handle-update",
333 G_CALLBACK (on_update),
Norman James18998182015-10-11 21:54:53 -0500334 object); /* user_data */
Norman James166acf42015-10-22 07:11:51 -0500335
336 g_signal_connect (flash,
337 "handle-error",
338 G_CALLBACK (on_error),
339 object); /* user_data */
340
341 g_signal_connect (flash,
342 "handle-done",
343 G_CALLBACK (on_done),
344 object); /* user_data */
345
Norman Jamesf066e872015-10-07 15:29:51 -0500346 g_signal_connect (flash,
347 "handle-update-via-tftp",
348 G_CALLBACK (on_update_via_tftp),
Norman James18998182015-10-11 21:54:53 -0500349 object); /* user_data */
Norman Jamesf066e872015-10-07 15:29:51 -0500350
Norman James471ab592015-08-30 22:29:40 -0500351 g_signal_connect (flash,
352 "handle-init",
353 G_CALLBACK (on_init),
Norman James166acf42015-10-22 07:11:51 -0500354 object); /* user_data */
Norman James471ab592015-08-30 22:29:40 -0500355
Norman James166acf42015-10-22 07:11:51 -0500356 s = g_strdup_printf ("/org/openbmc/control/%s",inst[i]);
Norman James18998182015-10-11 21:54:53 -0500357 g_dbus_connection_signal_subscribe(connection,
358 NULL,
359 "org.openbmc.FlashControl",
360 "Progress",
361 s,
362 NULL,
363 G_DBUS_SIGNAL_FLAGS_NONE,
364 (GDBusSignalCallback) on_flash_progress,
365 object,
366 NULL );
367
368 g_free (s);
Norman Jamesf066e872015-10-07 15:29:51 -0500369
Norman James471ab592015-08-30 22:29:40 -0500370
Norman James18998182015-10-11 21:54:53 -0500371 flash_set_filename(flash,"");
Norman James10ff6a32015-08-27 14:24:17 -0500372 /* Export the object (@manager takes its own reference to @object) */
373 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
374 g_object_unref (object);
375 }
Norman James166acf42015-10-22 07:11:51 -0500376 g_free(flasher_file);
Norman James10ff6a32015-08-27 14:24:17 -0500377 /* Export all objects */
378 g_dbus_object_manager_server_set_connection (manager, connection);
Norman Jamese2765102015-08-19 22:00:55 -0500379}
380
381static void
382on_name_acquired (GDBusConnection *connection,
383 const gchar *name,
384 gpointer user_data)
385{
Norman James362a80f2015-09-14 14:04:39 -0500386// g_print ("Acquired the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500387}
388
389static void
390on_name_lost (GDBusConnection *connection,
391 const gchar *name,
392 gpointer user_data)
393{
Norman James362a80f2015-09-14 14:04:39 -0500394 //g_print ("Lost the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500395}
396
397gint
398main (gint argc, gchar *argv[])
399{
400 GMainLoop *loop;
Norman James952b38d2015-08-27 21:30:06 -0500401 cmdline cmd;
402 cmd.argc = argc;
403 cmd.argv = argv;
Norman Jamese2765102015-08-19 22:00:55 -0500404 guint id;
Norman Jamese2765102015-08-19 22:00:55 -0500405 loop = g_main_loop_new (NULL, FALSE);
406
Norman James5e792e32015-10-07 17:36:17 -0500407 id = g_bus_own_name (DBUS_TYPE,
Norman James26072c02015-08-25 07:14:29 -0500408 dbus_name,
Norman Jamese2765102015-08-19 22:00:55 -0500409 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
410 G_BUS_NAME_OWNER_FLAGS_REPLACE,
411 on_bus_acquired,
412 on_name_acquired,
413 on_name_lost,
Norman James952b38d2015-08-27 21:30:06 -0500414 &cmd,
Norman Jamese2765102015-08-19 22:00:55 -0500415 NULL);
416
417 g_main_loop_run (loop);
418
419 g_bus_unown_name (id);
420 g_main_loop_unref (loop);
421 return 0;
422}