blob: 765b7c2c91352c148053b50d5fd0da2e1bef5857 [file] [log] [blame]
Brad Bishop77390492016-04-13 10:47:19 -04001#include <stdio.h>
2#include <stdbool.h>
3#include <string.h>
Brad Bishop0c82c602016-04-13 13:36:49 -04004#include <sys/wait.h>
5#include <sys/types.h>
Brad Bishopf6c85682016-06-27 11:56:39 -04006#include <openbmc_intf.h>
7#include <openbmc.h>
Brad Bishop77390492016-04-13 10:47:19 -04008
9/* ------------------------------------------------------------------------- */
10static const gchar* dbus_object_path = "/org/openbmc/control/flash";
11static const gchar* dbus_name = "org.openbmc.control.Flash";
12static const gchar* FLASHER_BIN = "flasher.exe";
Brad Bishop77390492016-04-13 10:47:19 -040013
14static GDBusObjectManagerServer *manager = NULL;
15
16void
17catch_child(int sig_num)
18{
19 /* when we get here, we know there's a zombie child waiting */
20 int child_status;
21
22 wait(&child_status);
23 printf("flasher exited.\n");
24}
25
26int
27update(Flash* flash, const char* obj_path)
28{
29 pid_t pid;
30 int status=-1;
31 pid = fork();
32 if(pid == 0)
33 {
Brad Bishop77390492016-04-13 10:47:19 -040034 const gchar* name = flash_get_flasher_name(flash);
35 const gchar* inst = flash_get_flasher_instance(flash);
36 const gchar* filename = flash_get_filename(flash);
Adriana Kobylak0206be82017-09-07 14:34:27 -050037 status = execlp(name, name, inst, filename, obj_path, NULL);
Brad Bishop77390492016-04-13 10:47:19 -040038 return status;
39 }
40 return 0;
41}
42
43static gboolean
44on_init(Flash *f,
45 GDBusMethodInvocation *invocation,
46 gpointer user_data)
47{
48 flash_complete_init(f,invocation);
49
50 //tune flash
51 if(strcmp(flash_get_flasher_instance(f),"bios") == 0)
52 {
53 flash_set_filename(f,"");
54 const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data);
55 int rc = update(f,obj_path);
56 if(rc==-1)
57 {
58 printf("ERROR FlashControl: Unable to init\n");
59 }
60 sleep(3);
61 rc = update(f,obj_path);
62
63 }
64 return TRUE;
65}
66
67static gboolean
68on_lock(SharedResource *lock,
69 GDBusMethodInvocation *invocation,
70 gchar* name,
71 gpointer user_data)
72{
73 gboolean locked = shared_resource_get_lock(lock);
74 if(locked)
75 {
76 const gchar* name = shared_resource_get_name(lock);
77 printf("ERROR: BIOS Flash is already locked: %s\n",name);
78 }
79 else
80 {
81 printf("Locking BIOS Flash: %s\n",name);
82 shared_resource_set_lock(lock,true);
83 shared_resource_set_name(lock,name);
84 }
85 shared_resource_complete_lock(lock,invocation);
86 return TRUE;
87}
88
89static gboolean
90on_is_locked(SharedResource *lock,
91 GDBusMethodInvocation *invocation,
92 gpointer user_data)
93{
94 gboolean locked = shared_resource_get_lock(lock);
95 const gchar* name = shared_resource_get_name(lock);
96 shared_resource_complete_is_locked(lock,invocation,locked,name);
97 return TRUE;
98}
99
100static gboolean
101on_unlock(SharedResource *lock,
102 GDBusMethodInvocation *invocation,
103 gpointer user_data)
104{
105 printf("Unlocking BIOS Flash\n");
106 shared_resource_set_lock(lock,false);
107 shared_resource_set_name(lock,"");
108 shared_resource_complete_unlock(lock,invocation);
109 return TRUE;
110}
111
112static gboolean
113on_update_via_tftp(Flash *flash,
114 GDBusMethodInvocation *invocation,
115 gchar* url,
116 gchar* write_file,
117 gpointer user_data)
118{
119 SharedResource *lock = object_get_shared_resource((Object*)user_data);
120 gboolean locked = shared_resource_get_lock(lock);
121 flash_complete_update_via_tftp(flash,invocation);
122 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 TFTP: %s,%s\n",url,write_file);
130 flash_set_filename(flash,write_file);
131 flash_emit_download(flash,url,write_file);
132 flash_set_status(flash,"Downloading");
133 }
134 return TRUE;
135}
136
137static gboolean
138on_error(Flash *flash,
139 GDBusMethodInvocation *invocation,
140 gchar* error_msg,
141 gpointer user_data)
142{
Brad Bishop77390492016-04-13 10:47:19 -0400143 SharedResource *lock = object_get_shared_resource((Object*)user_data);
Brad Bishop0c82c602016-04-13 13:36:49 -0400144 shared_resource_get_lock(lock);
Brad Bishop77390492016-04-13 10:47:19 -0400145 flash_set_status(flash, error_msg);
146 flash_complete_error(flash,invocation);
147 printf("ERROR: %s. Clearing locks\n",error_msg);
148 shared_resource_set_lock(lock,false);
149 shared_resource_set_name(lock,"");
150
151 return TRUE;
152}
153
154static gboolean
155on_done(Flash *flash,
156 GDBusMethodInvocation *invocation,
157 gpointer user_data)
158{
159 int rc = 0;
160 SharedResource *lock = object_get_shared_resource((Object*)user_data);
Brad Bishop0c82c602016-04-13 13:36:49 -0400161 shared_resource_get_lock(lock);
Brad Bishop77390492016-04-13 10:47:19 -0400162 flash_set_status(flash, "Flash Done");
163 flash_complete_done(flash,invocation);
164 printf("Flash Done. Clearing locks\n");
165 shared_resource_set_lock(lock,false);
166 shared_resource_set_name(lock,"");
167 const gchar* filename = flash_get_filename(flash);
168 rc = unlink(filename);
169 if(rc != 0 )
170 {
171 printf("ERROR: Unable to delete file %s (%d)\n",filename,rc);
172 }
173
174 return TRUE;
175}
176
177static gboolean
178on_update(Flash *flash,
179 GDBusMethodInvocation *invocation,
180 gchar* write_file,
181 gpointer user_data)
182{
183 int rc = 0;
184 SharedResource *lock = object_get_shared_resource((Object*)user_data);
185 gboolean locked = shared_resource_get_lock(lock);
186 flash_set_status(flash,"Flashing");
187 flash_complete_update(flash,invocation);
188 if(locked)
189 {
190 const gchar* name = shared_resource_get_name(lock);
191 printf("BIOS Flash is locked: %s\n",name);
192 }
193 else
194 {
195 printf("Flashing BIOS from: %s\n",write_file);
196 flash_set_status(flash, "Flashing");
197 shared_resource_set_lock(lock,true);
198 shared_resource_set_name(lock,dbus_object_path);
199 flash_set_filename(flash,write_file);
200 const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data);
201 rc = update(flash,obj_path);
202 if(!rc)
203 {
204 shared_resource_set_lock(lock,false);
205 shared_resource_set_name(lock,"");
206 }
207 }
208 return TRUE;
209}
210
211static void
212on_flash_progress(GDBusConnection* connection,
213 const gchar* sender_name,
214 const gchar* object_path,
215 const gchar* interface_name,
216 const gchar* signal_name,
217 GVariant* parameters,
218 gpointer user_data)
219{
220 Flash *flash = object_get_flash((Object*)user_data);
Brad Bishop0c82c602016-04-13 13:36:49 -0400221 object_get_shared_resource((Object*)user_data);
Brad Bishop77390492016-04-13 10:47:19 -0400222 GVariantIter *iter = g_variant_iter_new(parameters);
Brad Bishop0c82c602016-04-13 13:36:49 -0400223 g_variant_iter_next_value(iter);
Brad Bishop77390492016-04-13 10:47:19 -0400224 GVariant* v_progress = g_variant_iter_next_value(iter);
225
226 uint8_t progress = g_variant_get_byte(v_progress);
227
228 gchar *s;
229 s = g_strdup_printf("Flashing: %d%%",progress);
230 flash_set_status(flash,s);
231 g_free(s);
232}
233
234static void
Brad Bishop77390492016-04-13 10:47:19 -0400235on_bus_acquired(GDBusConnection *connection,
236 const gchar *name,
237 gpointer user_data)
238{
239 ObjectSkeleton *object;
240 cmdline *cmd = user_data;
241 manager = g_dbus_object_manager_server_new(dbus_object_path);
242 int i=0;
243
Adriana Kobylak0206be82017-09-07 14:34:27 -0500244 gchar *flasher_file = g_strdup_printf("%s", FLASHER_BIN);
Brad Bishop77390492016-04-13 10:47:19 -0400245
246 const char* inst[] = {"bios"};
247 for(i=0;i<1;i++)
248 {
249 gchar* s;
250 s = g_strdup_printf("%s/%s",dbus_object_path,inst[i]);
251 object = object_skeleton_new(s);
252 g_free(s);
253
254 Flash* flash = flash_skeleton_new();
255 object_skeleton_set_flash(object, flash);
256 g_object_unref(flash);
257
258 SharedResource* lock = shared_resource_skeleton_new();
259 object_skeleton_set_shared_resource(object, lock);
260 g_object_unref(lock);
261
Brad Bishop77390492016-04-13 10:47:19 -0400262 shared_resource_set_lock(lock,false);
263 shared_resource_set_name(lock,"");
264
Brad Bishop77390492016-04-13 10:47:19 -0400265 flash_set_flasher_name(flash,FLASHER_BIN);
266 flash_set_flasher_instance(flash,inst[i]);
267 //g_free (s);
268
269
270 //define method callbacks here
271 g_signal_connect(lock,
272 "handle-lock",
273 G_CALLBACK(on_lock),
274 NULL); /* user_data */
275 g_signal_connect(lock,
276 "handle-unlock",
277 G_CALLBACK(on_unlock),
278 NULL); /* user_data */
279 g_signal_connect(lock,
280 "handle-is-locked",
281 G_CALLBACK(on_is_locked),
282 NULL); /* user_data */
283
284 g_signal_connect(flash,
285 "handle-update",
286 G_CALLBACK(on_update),
287 object); /* user_data */
288
289 g_signal_connect(flash,
290 "handle-error",
291 G_CALLBACK(on_error),
292 object); /* user_data */
293
294 g_signal_connect(flash,
295 "handle-done",
296 G_CALLBACK(on_done),
297 object); /* user_data */
298
299 g_signal_connect(flash,
300 "handle-update-via-tftp",
301 G_CALLBACK(on_update_via_tftp),
302 object); /* user_data */
303
304 g_signal_connect(flash,
305 "handle-init",
306 G_CALLBACK(on_init),
307 object); /* user_data */
308
309 s = g_strdup_printf("/org/openbmc/control/%s",inst[i]);
310 g_dbus_connection_signal_subscribe(connection,
311 NULL,
312 "org.openbmc.FlashControl",
313 "Progress",
314 s,
315 NULL,
316 G_DBUS_SIGNAL_FLAGS_NONE,
317 (GDBusSignalCallback) on_flash_progress,
318 object,
319 NULL );
320
321 g_free(s);
322
323
324 flash_set_filename(flash,"");
325 /* Export the object (@manager takes its own reference to @object) */
Brad Bishop58e694d2016-04-13 16:04:32 -0400326 g_dbus_object_manager_server_set_connection(manager, connection);
Brad Bishop77390492016-04-13 10:47:19 -0400327 g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object));
328 g_object_unref(object);
329 }
330 g_free(flasher_file);
Brad Bishop77390492016-04-13 10:47:19 -0400331}
332
333static void
334on_name_acquired(GDBusConnection *connection,
335 const gchar *name,
336 gpointer user_data)
337{
338 // g_print ("Acquired the name %s\n", name);
339}
340
341static void
342on_name_lost(GDBusConnection *connection,
343 const gchar *name,
344 gpointer user_data)
345{
346 //g_print ("Lost the name %s\n", name);
347}
348
349gint
350main(gint argc, gchar *argv[])
351{
352 GMainLoop *loop;
353 cmdline cmd;
354 cmd.argc = argc;
355 cmd.argv = argv;
356 guint id;
357 loop = g_main_loop_new(NULL, FALSE);
358
Brad Bishopdf32eea2016-09-08 09:23:19 -0400359 signal(SIGCHLD, catch_child);
Brad Bishop77390492016-04-13 10:47:19 -0400360 id = g_bus_own_name(DBUS_TYPE,
361 dbus_name,
362 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
363 G_BUS_NAME_OWNER_FLAGS_REPLACE,
364 on_bus_acquired,
365 on_name_acquired,
366 on_name_lost,
367 &cmd,
368 NULL);
369
370 g_main_loop_run(loop);
371
372 g_bus_unown_name(id);
373 g_main_loop_unref(loop);
374 return 0;
375}