diff options
author | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2016-05-28 18:41:04 -0400 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2016-06-10 18:06:59 -0400 |
commit | 40a360c2a4feef97a8f7041e655b2a42e51e0224 (patch) | |
tree | 75dfea3064d7c3243788c72cb9f30e2ce6241dea /flashbios/flash_bios_obj.c | |
parent | a73122191a7aba80f97332687a2e03cfb0336981 (diff) | |
download | talos-skeleton-40a360c2a4feef97a8f7041e655b2a42e51e0224.tar.gz talos-skeleton-40a360c2a4feef97a8f7041e655b2a42e51e0224.zip |
Reorganize directory structure
Moving to directory per-application layout. This facilitates
building single applications which is useful in the Yocto build
environment since different applications satisfy different OpenBMC
build requirements.
A number of issues are also addressed:
- All applications were pulling in libsystemd and the gdbus libs
irrespective of whether or not they were needed.
- gpio.o duplicated in every application - moved to libopenbmc_intf
- Added install target
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Diffstat (limited to 'flashbios/flash_bios_obj.c')
-rw-r--r-- | flashbios/flash_bios_obj.c | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/flashbios/flash_bios_obj.c b/flashbios/flash_bios_obj.c new file mode 100644 index 0000000..f865be1 --- /dev/null +++ b/flashbios/flash_bios_obj.c @@ -0,0 +1,391 @@ +#include <stdio.h> +#include <stdbool.h> +#include <string.h> +#include <sys/wait.h> +#include <sys/types.h> +#include "interfaces/openbmc_intf.h" +#include "openbmc.h" + +/* ------------------------------------------------------------------------- */ +static const gchar* dbus_object_path = "/org/openbmc/control/flash"; +static const gchar* dbus_name = "org.openbmc.control.Flash"; +static const gchar* FLASHER_BIN = "flasher.exe"; + +static GDBusObjectManagerServer *manager = NULL; + +void +catch_child(int sig_num) +{ + /* when we get here, we know there's a zombie child waiting */ + int child_status; + + wait(&child_status); + printf("flasher exited.\n"); +} + +int +update(Flash* flash, const char* obj_path) +{ + pid_t pid; + int status=-1; + pid = fork(); + if(pid == 0) + { + const gchar* path = flash_get_flasher_path(flash); + const gchar* name = flash_get_flasher_name(flash); + const gchar* inst = flash_get_flasher_instance(flash); + const gchar* filename = flash_get_filename(flash); + status = execl(path, name, inst, filename, obj_path, NULL); + return status; + } + return 0; +} + +static gboolean +on_init(Flash *f, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + flash_complete_init(f,invocation); + + //tune flash + if(strcmp(flash_get_flasher_instance(f),"bios") == 0) + { + flash_set_filename(f,""); + const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data); + int rc = update(f,obj_path); + if(rc==-1) + { + printf("ERROR FlashControl: Unable to init\n"); + } + sleep(3); + rc = update(f,obj_path); + + } + return TRUE; +} + +static gboolean +on_lock(SharedResource *lock, + GDBusMethodInvocation *invocation, + gchar* name, + gpointer user_data) +{ + gboolean locked = shared_resource_get_lock(lock); + if(locked) + { + const gchar* name = shared_resource_get_name(lock); + printf("ERROR: BIOS Flash is already locked: %s\n",name); + } + else + { + printf("Locking BIOS Flash: %s\n",name); + shared_resource_set_lock(lock,true); + shared_resource_set_name(lock,name); + } + shared_resource_complete_lock(lock,invocation); + return TRUE; +} + +static gboolean +on_is_locked(SharedResource *lock, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + gboolean locked = shared_resource_get_lock(lock); + const gchar* name = shared_resource_get_name(lock); + shared_resource_complete_is_locked(lock,invocation,locked,name); + return TRUE; +} + +static gboolean +on_unlock(SharedResource *lock, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + printf("Unlocking BIOS Flash\n"); + shared_resource_set_lock(lock,false); + shared_resource_set_name(lock,""); + shared_resource_complete_unlock(lock,invocation); + return TRUE; +} + +static gboolean +on_update_via_tftp(Flash *flash, + GDBusMethodInvocation *invocation, + gchar* url, + gchar* write_file, + gpointer user_data) +{ + SharedResource *lock = object_get_shared_resource((Object*)user_data); + gboolean locked = shared_resource_get_lock(lock); + flash_complete_update_via_tftp(flash,invocation); + if(locked) + { + const gchar* name = shared_resource_get_name(lock); + printf("BIOS Flash is locked: %s\n",name); + } + else + { + printf("Flashing BIOS from TFTP: %s,%s\n",url,write_file); + flash_set_filename(flash,write_file); + flash_emit_download(flash,url,write_file); + flash_set_status(flash,"Downloading"); + } + return TRUE; +} + +static gboolean +on_error(Flash *flash, + GDBusMethodInvocation *invocation, + gchar* error_msg, + gpointer user_data) +{ + SharedResource *lock = object_get_shared_resource((Object*)user_data); + shared_resource_get_lock(lock); + flash_set_status(flash, error_msg); + flash_complete_error(flash,invocation); + printf("ERROR: %s. Clearing locks\n",error_msg); + shared_resource_set_lock(lock,false); + shared_resource_set_name(lock,""); + + return TRUE; +} + +static gboolean +on_done(Flash *flash, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + int rc = 0; + SharedResource *lock = object_get_shared_resource((Object*)user_data); + shared_resource_get_lock(lock); + flash_set_status(flash, "Flash Done"); + flash_complete_done(flash,invocation); + printf("Flash Done. Clearing locks\n"); + shared_resource_set_lock(lock,false); + shared_resource_set_name(lock,""); + const gchar* filename = flash_get_filename(flash); + rc = unlink(filename); + if(rc != 0 ) + { + printf("ERROR: Unable to delete file %s (%d)\n",filename,rc); + } + + return TRUE; +} + +static gboolean +on_update(Flash *flash, + GDBusMethodInvocation *invocation, + gchar* write_file, + gpointer user_data) +{ + int rc = 0; + SharedResource *lock = object_get_shared_resource((Object*)user_data); + gboolean locked = shared_resource_get_lock(lock); + flash_set_status(flash,"Flashing"); + flash_complete_update(flash,invocation); + if(locked) + { + const gchar* name = shared_resource_get_name(lock); + printf("BIOS Flash is locked: %s\n",name); + } + else + { + printf("Flashing BIOS from: %s\n",write_file); + flash_set_status(flash, "Flashing"); + shared_resource_set_lock(lock,true); + shared_resource_set_name(lock,dbus_object_path); + flash_set_filename(flash,write_file); + const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data); + rc = update(flash,obj_path); + if(!rc) + { + shared_resource_set_lock(lock,false); + shared_resource_set_name(lock,""); + } + } + return TRUE; +} + +static void +on_flash_progress(GDBusConnection* connection, + const gchar* sender_name, + const gchar* object_path, + const gchar* interface_name, + const gchar* signal_name, + GVariant* parameters, + gpointer user_data) +{ + Flash *flash = object_get_flash((Object*)user_data); + object_get_shared_resource((Object*)user_data); + GVariantIter *iter = g_variant_iter_new(parameters); + g_variant_iter_next_value(iter); + GVariant* v_progress = g_variant_iter_next_value(iter); + + uint8_t progress = g_variant_get_byte(v_progress); + + gchar *s; + s = g_strdup_printf("Flashing: %d%%",progress); + flash_set_status(flash,s); + g_free(s); +} + +static void +on_bus_acquired(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + ObjectSkeleton *object; + cmdline *cmd = user_data; + manager = g_dbus_object_manager_server_new(dbus_object_path); + int i=0; + + //TODO: don't use fixed buffer + char flasher_path[512]; + memset(flasher_path, '\0', sizeof(flasher_path)); + gchar *flasher_file = NULL; + int c = strlen(cmd->argv[0]); + while(c>0) + { + if(cmd->argv[0][c] == '/') + { + strncpy(flasher_path,cmd->argv[0],c); + flasher_file = g_strdup_printf("%s/%s",flasher_path,FLASHER_BIN); + break; + } + c--; + } + + const char* inst[] = {"bios"}; + for(i=0;i<1;i++) + { + gchar* s; + s = g_strdup_printf("%s/%s",dbus_object_path,inst[i]); + object = object_skeleton_new(s); + g_free(s); + + Flash* flash = flash_skeleton_new(); + object_skeleton_set_flash(object, flash); + g_object_unref(flash); + + SharedResource* lock = shared_resource_skeleton_new(); + object_skeleton_set_shared_resource(object, lock); + g_object_unref(lock); + + shared_resource_set_lock(lock,false); + shared_resource_set_name(lock,""); + + flash_set_flasher_path(flash,flasher_file); + flash_set_flasher_name(flash,FLASHER_BIN); + flash_set_flasher_instance(flash,inst[i]); + //g_free (s); + + + //define method callbacks here + g_signal_connect(lock, + "handle-lock", + G_CALLBACK(on_lock), + NULL); /* user_data */ + g_signal_connect(lock, + "handle-unlock", + G_CALLBACK(on_unlock), + NULL); /* user_data */ + g_signal_connect(lock, + "handle-is-locked", + G_CALLBACK(on_is_locked), + NULL); /* user_data */ + + g_signal_connect(flash, + "handle-update", + G_CALLBACK(on_update), + object); /* user_data */ + + g_signal_connect(flash, + "handle-error", + G_CALLBACK(on_error), + object); /* user_data */ + + g_signal_connect(flash, + "handle-done", + G_CALLBACK(on_done), + object); /* user_data */ + + g_signal_connect(flash, + "handle-update-via-tftp", + G_CALLBACK(on_update_via_tftp), + object); /* user_data */ + + g_signal_connect(flash, + "handle-init", + G_CALLBACK(on_init), + object); /* user_data */ + + s = g_strdup_printf("/org/openbmc/control/%s",inst[i]); + g_dbus_connection_signal_subscribe(connection, + NULL, + "org.openbmc.FlashControl", + "Progress", + s, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + (GDBusSignalCallback) on_flash_progress, + object, + NULL ); + + g_free(s); + + + flash_set_filename(flash,""); + /* Export the object (@manager takes its own reference to @object) */ + g_dbus_object_manager_server_set_connection(manager, connection); + g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object)); + g_object_unref(object); + } + g_free(flasher_file); +} + +static void +on_name_acquired(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + // g_print ("Acquired the name %s\n", name); +} + +static void +on_name_lost(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + //g_print ("Lost the name %s\n", name); +} + +gint +main(gint argc, gchar *argv[]) +{ + GMainLoop *loop; + cmdline cmd; + cmd.argc = argc; + cmd.argv = argv; + guint id; + loop = g_main_loop_new(NULL, FALSE); + + //signal(SIGCHLD, catch_child); + id = g_bus_own_name(DBUS_TYPE, + dbus_name, + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | + G_BUS_NAME_OWNER_FLAGS_REPLACE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + &cmd, + NULL); + + g_main_loop_run(loop); + + g_bus_unown_name(id); + g_main_loop_unref(loop); + return 0; +} |