blob: 928d11bddb3bcf99a73baab05b417d7d5842f4ef [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 Jamesf066e872015-10-07 15:29:51 -050027
Norman James18998182015-10-11 21:54:53 -050028 status = execl(path, name, inst, filename, NULL);
Norman Jamesf066e872015-10-07 15:29:51 -050029 }
Norman James18998182015-10-11 21:54:53 -050030 return status;
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{
56 printf("Locking BIOS Flash: %s\n",name);
57 shared_resource_set_lock(lock,true);
58 shared_resource_set_name(lock,name);
59 shared_resource_complete_lock(lock,invocation);
60 return TRUE;
61}
62static gboolean
63on_is_locked (SharedResource *lock,
64 GDBusMethodInvocation *invocation,
65 gpointer user_data)
66{
67 gboolean locked = shared_resource_get_lock(lock);
68 const gchar* name = shared_resource_get_name(lock);
69 shared_resource_complete_is_locked(lock,invocation,locked,name);
70 return TRUE;
71}
72
73
74static gboolean
75on_unlock (SharedResource *lock,
76 GDBusMethodInvocation *invocation,
77 gpointer user_data)
78{
79 printf("Unlocking BIOS Flash\n");
80 shared_resource_set_lock(lock,false);
81 shared_resource_set_name(lock,"");
82 shared_resource_complete_unlock(lock,invocation);
Norman James65a295a2015-09-26 22:21:10 -050083 return TRUE;
Norman James471ab592015-08-30 22:29:40 -050084}
85
86static gboolean
Norman Jamesf066e872015-10-07 15:29:51 -050087on_update_via_tftp (Flash *flash,
88 GDBusMethodInvocation *invocation,
89 gchar* url,
90 gchar* write_file,
91 gpointer user_data)
92{
Norman James18998182015-10-11 21:54:53 -050093 SharedResource *lock = object_get_shared_resource((Object*)user_data);
94 gboolean locked = shared_resource_get_lock(lock);
Norman Jamesf066e872015-10-07 15:29:51 -050095 flash_complete_update_via_tftp(flash,invocation);
Norman James18998182015-10-11 21:54:53 -050096 if (locked)
97 {
98 const gchar* name = shared_resource_get_name(lock);
99 printf("BIOS Flash is locked: %s\n",name);
100 }
101 else
102 {
103 printf("Flashing BIOS from TFTP: %s,%s\n",url,write_file);
104 shared_resource_set_lock(lock,true);
105 shared_resource_set_name(lock,dbus_object_path);
106 flash_set_filename(flash,write_file);
107 flash_emit_download(flash,url,write_file);
108 }
Norman Jamesf066e872015-10-07 15:29:51 -0500109 return TRUE;
110}
111
112static gboolean
113on_update (Flash *flash,
Norman Jamese2765102015-08-19 22:00:55 -0500114 GDBusMethodInvocation *invocation,
115 gchar* write_file,
116 gpointer user_data)
117{
Norman James18998182015-10-11 21:54:53 -0500118 int rc = 0;
119 SharedResource *lock = object_get_shared_resource((Object*)user_data);
120 gboolean locked = shared_resource_get_lock(lock);
Norman Jamesf066e872015-10-07 15:29:51 -0500121 flash_complete_update(flash,invocation);
Norman James18998182015-10-11 21:54:53 -0500122 if (locked)
123 {
124 const gchar* name = shared_resource_get_name(lock);
125 printf("BIOS Flash is locked: %s\n",name);
126 }
127 else
128 {
129 printf("Flashing BIOS from: %s\n",write_file);
130 shared_resource_set_lock(lock,true);
131 shared_resource_set_name(lock,dbus_object_path);
132 flash_set_filename(flash,write_file);
133 rc = update(flash);
134 if (!rc)
135 {
136 shared_resource_set_lock(lock,false);
137 shared_resource_set_name(lock,"");
138 }
139 }
Norman James068efb32015-10-06 16:52:28 -0500140 return TRUE;
Norman Jamese2765102015-08-19 22:00:55 -0500141}
142
Norman Jamesf066e872015-10-07 15:29:51 -0500143static void
144on_download_complete (GDBusConnection* connection,
145 const gchar* sender_name,
146 const gchar* object_path,
147 const gchar* interface_name,
148 const gchar* signal_name,
149 GVariant* parameters,
150 gpointer user_data)
151{
152 Flash *flash = object_get_flash((Object*)user_data);
Norman James18998182015-10-11 21:54:53 -0500153 SharedResource *lock = object_get_shared_resource((Object*)user_data);
154
Norman Jamesf066e872015-10-07 15:29:51 -0500155 GVariantIter *iter = g_variant_iter_new(parameters);
Norman James18998182015-10-11 21:54:53 -0500156 GVariant* v_fullname = g_variant_iter_next_value(iter);
Norman Jamesf066e872015-10-07 15:29:51 -0500157 gsize size;
Norman James18998182015-10-11 21:54:53 -0500158 const gchar* fullname = g_variant_get_string(v_fullname,&size);
159 int rc;
160 flash_set_filename(flash,fullname);
161 rc = update(flash);
162 if (!rc)
163 {
164 shared_resource_set_lock(lock,false);
165 shared_resource_set_name(lock,"");
166 }
167}
168
169static void
170on_flash_progress (GDBusConnection* connection,
171 const gchar* sender_name,
172 const gchar* object_path,
173 const gchar* interface_name,
174 const gchar* signal_name,
175 GVariant* parameters,
176 gpointer user_data)
177{
178 Flash *flash = object_get_flash((Object*)user_data);
179 SharedResource *lock = object_get_shared_resource((Object*)user_data);
180 GVariantIter *iter = g_variant_iter_new(parameters);
181 GVariant* v_filename = g_variant_iter_next_value(iter);
182 GVariant* v_progress = g_variant_iter_next_value(iter);
Norman Jamesf066e872015-10-07 15:29:51 -0500183
Norman James18998182015-10-11 21:54:53 -0500184 uint8_t progress = g_variant_get_byte(v_progress);
185 printf("Progress: %d\n",progress);
186}
187
188static void
189on_flash_done (GDBusConnection* connection,
190 const gchar* sender_name,
191 const gchar* object_path,
192 const gchar* interface_name,
193 const gchar* signal_name,
194 GVariant* parameters,
195 gpointer user_data)
196{
197 Flash *flash = object_get_flash((Object*)user_data);
198 SharedResource *lock = object_get_shared_resource((Object*)user_data);
199 printf("Flash succeeded; unlocking flash\n");
200 shared_resource_set_lock(lock,false);
201 shared_resource_set_name(lock,"");
202}
203
204static void
205on_flash_error (GDBusConnection* connection,
206 const gchar* sender_name,
207 const gchar* object_path,
208 const gchar* interface_name,
209 const gchar* signal_name,
210 GVariant* parameters,
211 gpointer user_data)
212{
213 Flash *flash = object_get_flash((Object*)user_data);
214 SharedResource *lock = object_get_shared_resource((Object*)user_data);
215 printf("Flash Error; unlocking flash\n");
216 shared_resource_set_lock(lock,false);
217 shared_resource_set_name(lock,"");
218}
219
220static void
221on_download_error (GDBusConnection* connection,
222 const gchar* sender_name,
223 const gchar* object_path,
224 const gchar* interface_name,
225 const gchar* signal_name,
226 GVariant* parameters,
227 gpointer user_data)
228{
229 Flash *flash = object_get_flash((Object*)user_data);
230 SharedResource *lock = object_get_shared_resource((Object*)user_data);
231 printf("ERROR: FlashBios: Download error; clearing flash lock\n");
232 shared_resource_set_lock(lock,false);
233 shared_resource_set_name(lock,"");
Norman Jamesf066e872015-10-07 15:29:51 -0500234}
235
Norman Jamese2765102015-08-19 22:00:55 -0500236static void
237on_bus_acquired (GDBusConnection *connection,
238 const gchar *name,
239 gpointer user_data)
240{
Norman James10ff6a32015-08-27 14:24:17 -0500241 ObjectSkeleton *object;
Norman James10ff6a32015-08-27 14:24:17 -0500242 cmdline *cmd = user_data;
243 if (cmd->argc < 2)
244 {
245 g_print("No objects created. Put object name(s) on command line\n");
246 return;
247 }
248 manager = g_dbus_object_manager_server_new (dbus_object_path);
249 int i=0;
250 for (i=1;i<cmd->argc;i++)
251 {
252 gchar *s;
253 s = g_strdup_printf ("%s/%s",dbus_object_path,cmd->argv[i]);
254 object = object_skeleton_new (s);
255 g_free (s);
Norman Jamese2765102015-08-19 22:00:55 -0500256
Norman James10ff6a32015-08-27 14:24:17 -0500257 Flash* flash = flash_skeleton_new ();
258 object_skeleton_set_flash (object, flash);
259 g_object_unref (flash);
Norman Jamese2765102015-08-19 22:00:55 -0500260
Norman James18998182015-10-11 21:54:53 -0500261 SharedResource* lock = shared_resource_skeleton_new ();
262 object_skeleton_set_shared_resource (object, lock);
263 g_object_unref (lock);
264
265 shared_resource_set_lock(lock,false);
266 shared_resource_set_name(lock,"");
267
268 int c = strlen(cmd->argv[0]);
269
270 //TODO: don't use fixed buffer
271 char buf[512];
272 memset(buf, '\0', sizeof(buf));
273 bool found = false;
274 while(c>0)
275 {
276 if (cmd->argv[0][c] == '/')
277 {
278 strncpy(buf,cmd->argv[0],c);
279 s = g_strdup_printf ("%s/%s",buf,FLASHER_BIN);
280 break;
281 }
282 c--;
283 }
284 if (c==0)
285 {
286 printf("ERROR FlashBios: Invalid Path = %s\n",cmd->argv[0]);
287 }
288 else
289 {
290 flash_set_flasher_path(flash,s);
291 flash_set_flasher_name(flash,FLASHER_BIN);
292 flash_set_flasher_instance(flash,cmd->argv[i]);
293 }
294 g_free (s);
295
296
Norman James10ff6a32015-08-27 14:24:17 -0500297 //define method callbacks here
Norman James18998182015-10-11 21:54:53 -0500298 g_signal_connect (lock,
299 "handle-lock",
300 G_CALLBACK (on_lock),
301 NULL); /* user_data */
302 g_signal_connect (lock,
303 "handle-unlock",
304 G_CALLBACK (on_unlock),
305 NULL); /* user_data */
306 g_signal_connect (lock,
307 "handle-is-locked",
308 G_CALLBACK (on_is_locked),
309 NULL); /* user_data */
310
Norman James10ff6a32015-08-27 14:24:17 -0500311 g_signal_connect (flash,
Norman James8c6d8382015-10-06 07:47:16 -0500312 "handle-update",
313 G_CALLBACK (on_update),
Norman James18998182015-10-11 21:54:53 -0500314 object); /* user_data */
Norman Jamesf066e872015-10-07 15:29:51 -0500315 g_signal_connect (flash,
316 "handle-update-via-tftp",
317 G_CALLBACK (on_update_via_tftp),
Norman James18998182015-10-11 21:54:53 -0500318 object); /* user_data */
Norman Jamesf066e872015-10-07 15:29:51 -0500319
Norman James471ab592015-08-30 22:29:40 -0500320 g_signal_connect (flash,
321 "handle-init",
322 G_CALLBACK (on_init),
323 NULL); /* user_data */
324
Norman Jamesf066e872015-10-07 15:29:51 -0500325 g_dbus_connection_signal_subscribe(connection,
Norman James18998182015-10-11 21:54:53 -0500326 DLOAD_BUS, DLOAD_BUS, "DownloadComplete",
327 DLOAD_OBJ,NULL,G_DBUS_SIGNAL_FLAGS_NONE,
Norman Jamesf066e872015-10-07 15:29:51 -0500328 (GDBusSignalCallback) on_download_complete,
329 object,
330 NULL );
Norman James18998182015-10-11 21:54:53 -0500331 g_dbus_connection_signal_subscribe(connection,
332 DLOAD_BUS, DLOAD_BUS, "DownloadError",
333 DLOAD_OBJ,NULL,G_DBUS_SIGNAL_FLAGS_NONE,
334 (GDBusSignalCallback) on_download_error,
335 object,
336 NULL );
337
338 s = g_strdup_printf ("/org/openbmc/control/%s",cmd->argv[i]);
339 g_dbus_connection_signal_subscribe(connection,
340 NULL,
341 "org.openbmc.FlashControl",
342 "Done",
343 s,
344 NULL,
345 G_DBUS_SIGNAL_FLAGS_NONE,
346 (GDBusSignalCallback) on_flash_done,
347 object,
348 NULL );
349 g_free(s);
350 s = g_strdup_printf ("/org/openbmc/control/%s\0",cmd->argv[i]);
351 g_dbus_connection_signal_subscribe(connection,
352 NULL,
353 "org.openbmc.FlashControl",
354 "Error",
355 s,
356 NULL,
357 G_DBUS_SIGNAL_FLAGS_NONE,
358 (GDBusSignalCallback) on_flash_error,
359 object,
360 NULL );
361
362 g_free(s);
363 s = g_strdup_printf ("/org/openbmc/control/%s",cmd->argv[i]);
364 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 Jamese2765102015-08-19 22:00:55 -0500383
Norman James10ff6a32015-08-27 14:24:17 -0500384 /* Export all objects */
385 g_dbus_object_manager_server_set_connection (manager, connection);
Norman Jamese2765102015-08-19 22:00:55 -0500386}
387
388static void
389on_name_acquired (GDBusConnection *connection,
390 const gchar *name,
391 gpointer user_data)
392{
Norman James362a80f2015-09-14 14:04:39 -0500393// g_print ("Acquired the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500394}
395
396static void
397on_name_lost (GDBusConnection *connection,
398 const gchar *name,
399 gpointer user_data)
400{
Norman James362a80f2015-09-14 14:04:39 -0500401 //g_print ("Lost the name %s\n", name);
Norman Jamese2765102015-08-19 22:00:55 -0500402}
403
404gint
405main (gint argc, gchar *argv[])
406{
407 GMainLoop *loop;
Norman James952b38d2015-08-27 21:30:06 -0500408 cmdline cmd;
409 cmd.argc = argc;
410 cmd.argv = argv;
Norman Jamese2765102015-08-19 22:00:55 -0500411 guint id;
Norman Jamese2765102015-08-19 22:00:55 -0500412 loop = g_main_loop_new (NULL, FALSE);
413
Norman James5e792e32015-10-07 17:36:17 -0500414 id = g_bus_own_name (DBUS_TYPE,
Norman James26072c02015-08-25 07:14:29 -0500415 dbus_name,
Norman Jamese2765102015-08-19 22:00:55 -0500416 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
417 G_BUS_NAME_OWNER_FLAGS_REPLACE,
418 on_bus_acquired,
419 on_name_acquired,
420 on_name_lost,
Norman James952b38d2015-08-27 21:30:06 -0500421 &cmd,
Norman Jamese2765102015-08-19 22:00:55 -0500422 NULL);
423
424 g_main_loop_run (loop);
425
426 g_bus_unown_name (id);
427 g_main_loop_unref (loop);
428 return 0;
429}