diff options
Diffstat (limited to 'instr-daemon.c')
-rw-r--r-- | instr-daemon.c | 204 |
1 files changed, 139 insertions, 65 deletions
diff --git a/instr-daemon.c b/instr-daemon.c index ee77e82..e1d5c8e 100644 --- a/instr-daemon.c +++ b/instr-daemon.c @@ -10,25 +10,22 @@ #include "menus.h" #include "gpib.h" #include "parser.h" +#include "error_utils.h" #include <stdlib.h> #include <ctype.h> #include <glib.h> -<<<<<<< HEAD #include <unistd.h> -======= ->>>>>>> b2c2c72d381ab1b32fa5b5fc4e890fef6c2bf1e0 #include <fcntl.h> #define STDIN_BUF_SIZE 1024 static gboolean periodic_poll (void); +static gboolean finish_boot (void); int port=3333; //port to listen -int connections=0; -int maxConn=16; //max connections - 16 guint signalMyCb; //signal to register which is used in cbClientInput(), step 10 from requirements GAsyncQueue** stdinQueue=NULL; @@ -47,7 +44,7 @@ void send_message(gchar* message) } //send the final buffer to the queue - for(count=0; count<maxConn; count++) { + for(count=0; count<MAX_SESSIONS; count++) { //allocate on the heap and deallocate in response.c, cbClientOutput() char *toSend = realloc(NULL, size+1); memcpy(toSend, message, size+1); @@ -68,7 +65,7 @@ static int pullIndex(GThread* id) int i=0,ret=-1; static GStaticMutex mutex = G_STATIC_MUTEX_INIT; g_static_mutex_lock (&mutex); - for(i=0; i<maxConn; i++) + for(i=0; i<MAX_SESSIONS; i++) if(peers[i] == id) { peers[i] = (GThread*)0; ret=i; @@ -87,7 +84,7 @@ static int pushIndex(GThread* id) int i=0,ret=-1; static GStaticMutex mutex = G_STATIC_MUTEX_INIT; g_static_mutex_lock (&mutex); - for(i=0; i<maxConn; i++) + for(i=0; i<MAX_SESSIONS; i++) if(peers[i] == 0) { peers[i] = id; ret=i; @@ -105,11 +102,11 @@ incomingConnection (GSocketService *service, GSocketListener *listener, gpointer user_data) { - if(connections +1 > maxConn) { + if(globals.Remote.terminal_connections +1 > MAX_SESSIONS) { g_print_debug("Connection closed. Max reached\n"); return TRUE; } - connections++; + globals.Remote.terminal_connections++; g_print_debug("Incoming connection\n"); return FALSE; } @@ -130,7 +127,7 @@ handler (GThreadedSocketService *service, out = g_io_stream_get_output_stream (G_IO_STREAM (connection)); in = g_io_stream_get_input_stream (G_IO_STREAM (connection)); - g_print_debug("Handling, connections: %d\n", connections); + g_print_debug("Handling %d connections\n", globals.Remote.terminal_connections); //register ourselves in the peers vector, use the index obtained in the stdinQueue //should not get -1 @@ -186,12 +183,21 @@ handler (GThreadedSocketService *service, } g_print_debug("Thread end\n"); - connections--; //keep track of connections + globals.Remote.terminal_connections--; //keep track of connections g_async_queue_unref(queue); //unreference the queue pullIndex(g_thread_self()); //unregister from the peers vector return TRUE; } +extern void vxi_main (); + +static gpointer vxithreadfunc (gpointer data){ + vxi_main (); + return NULL; +} + + + int main(int argc, char **argv) { GSocketService *service = NULL; @@ -199,6 +205,7 @@ int main(int argc, char **argv) GIOChannel* stdinChannel = NULL; g_type_init (); + g_thread_init (NULL); bus_init(); @@ -235,35 +242,15 @@ int main(int argc, char **argv) GPIB_initialize(); IO_Setup_RS232( globals.Flash.baud, - globals.Flash.parity, - globals.Flash.stopbits, - globals.Flash.databits, globals.Flash.hardhand, - globals.Flash.echo, FALSE); /* start-up delay */ LCD_write(3,0,"Warming up, please wait... "); globals.Timers.startup_timer_value = sec_timer (); - long timer_count; - while ((timer_count=sec_timer()-globals.Timers.startup_timer_value) < (long)globals.Flash.turn_on_dly) { - message = g_strdup_printf ("%ld ", (long) globals.Flash.turn_on_dly - timer_count); - LCD_write(3,27,message); - g_free (message); - } - LCD_write(3,27,"OK"); - - I2C_Setup_Monitor(); Main_Rst(); - Menu_Update_Display(); - - // FIXME - self-cal here - or in thread beside user sessions? - - // FIXME - need auto-timer output-off somewhere - launch event from set_output? - - // FIXME - need main loops, checks monitors too //register stdin channel stdinChannel = g_io_channel_unix_new(0); @@ -274,17 +261,17 @@ int main(int argc, char **argv) int idx=0; - //allocate a maxConn queue on the heap - stdinQueue = malloc(sizeof(struct GAsyncQueue*) * maxConn); + //allocate a MAX_SESSIONS queue on the heap + stdinQueue = malloc(sizeof(struct GAsyncQueue*) * MAX_SESSIONS); //allocate peers vector on the heap - peers = malloc(sizeof(GThread*) * maxConn); - for(idx=0; idx<maxConn; idx++) { + peers = malloc(sizeof(GThread*) * MAX_SESSIONS); + for(idx=0; idx<MAX_SESSIONS; idx++) { peers[idx] = 0; stdinQueue[idx] = g_async_queue_new(); } //create a threaded service - service = g_threaded_socket_service_new (maxConn+1); + service = g_threaded_socket_service_new (MAX_SESSIONS+1); if (!g_socket_listener_add_inet_port (G_SOCKET_LISTENER (service), port, NULL, @@ -305,6 +292,11 @@ int main(int argc, char **argv) GMainLoop *loop = g_main_loop_new (NULL, FALSE); g_timeout_add (20, (GSourceFunc) periodic_poll, NULL); + g_timeout_add (100, (GSourceFunc) finish_boot, NULL); + + GThread *vxithread =g_thread_create(vxithreadfunc, NULL,false, NULL); + if(vxithread == NULL) + printf("Couldn't create vxi thread\n"); g_main_loop_run (loop); @@ -317,57 +309,139 @@ int main(int argc, char **argv) } +static gboolean finish_boot (void) +{ + +#define MIN_STARTUP_DELAY 2 +#define MAX_STARTUP_DELAY 120 + + long on_delay = (long)globals.Flash.turn_on_dly; + if (on_delay < MIN_STARTUP_DELAY) { + on_delay = MIN_STARTUP_DELAY; + } + if (on_delay > MAX_STARTUP_DELAY) { + on_delay = MAX_STARTUP_DELAY; + } + + long timer_count; + + if ((timer_count=sec_timer()-globals.Timers.startup_timer_value) < on_delay) { + gchar *message = g_strdup_printf ("%ld ", on_delay - timer_count); + LCD_write(3,27,message); + g_free (message); + return TRUE; // exit and call by timeout again + } + + LCD_write(3,27,"OK"); + + I2C_Setup_Monitor(); + + if (globals.Flash.self_cal && + globals.Flash.self_cal_interval && + (globals.Flash.self_cal_startups % globals.Flash.self_cal_interval) == 0 ) { + int error_num; + if (error_num=self_cal()) { + queue_and_broadcast_sensor_alarm(error_num); + } + } + + + globals.Sys.startup_complete = 1; + + Show_Main_Menu(); + + return FALSE; // no more calls to this function are needed +} + static gboolean periodic_poll (void) { - if (bus_getpin (POWER_FAIL)) { -<<<<<<< HEAD - //system ("/usr/bin/systemctl poweroff"); -======= + if (globals.HWDetect.beaglebone && bus_getpin (POWER_FAIL)) { - globals.Flags.shutdown_started = TRUE; + globals.Sys.shutdown_started = TRUE; - while (globals.Flags.flash_write_in_progress) { + while (globals.Sys.flash_write_in_progress) { g_usleep(1000); } LCD_clear(); - LCD_write(0,0,"Power failed. Shutdown."); ->>>>>>> b2c2c72d381ab1b32fa5b5fc4e890fef6c2bf1e0 + // 0123456789012345678901234567890123456789 + LCD_write(0,0,"PWR: Wait 10s. If still frozen, turn"); + LCD_write(1,0,"off 1min & retry."); // use plain old open to avoid any buffering etc - int enablefd = open("/proc/sys/kernel/sysrq", O_SYNC, O_RDWR); - int trgfd = open("/proc/sysrq-trigger", O_SYNC, O_RDWR); + int enablefd = open("/proc/sys/kernel/sysrq", O_SYNC | O_RDWR); + int trgfd = open("/proc/sysrq-trigger", O_SYNC | O_RDWR); // enable sysrq write(enablefd, "1\n", 2); - - // remount ro - write(trgfd, "u\n", 2); + close(enablefd); // sync disks write(trgfd, "s\n", 2); -<<<<<<< HEAD -======= + // remount ro + write(trgfd, "u\n", 2); + close(trgfd); + // poweroff system ("/usr/bin/systemctl poweroff -f"); ->>>>>>> b2c2c72d381ab1b32fa5b5fc4e890fef6c2bf1e0 + + exit(0); } - Menu_Check_Buttons (); - - // FIXME - gpib input - should have it's own thread? - // - // FIXME - comment out everything up to "return TRUE" if this section - // is crashing due to non-functional bus - GPIB_check_for_device_clear_signal(); - if (GPIB_check_for_messages(globals.Registers.gpib_buffer)) { - if (GPIB_handle_new_input(globals.Registers.gpib_buffer)) { - // FIXME check_for_ctrl_mode_changes(); - Parser_main(globals.Registers.gpib_buffer, 0, NULL, NULL); + if (globals.Sys.startup_complete) { + int i, output_on_time_so_far; + + for (i=0; i<(globals.Flash.ChanKey_output_state?globals.Flash.channels:1); ++i) { + output_on_time_so_far = (int) (sec_timer()-globals.Timers.last_activity_at[i]); + if ( (globals.Flash.output_timer[i]>0) && + (globals.Timers.last_activity_at[i]>0) && + (output_on_time_so_far > globals.Flash.output_timer[i])) { + Set_Output_State(i,output_off); + Show_Main_Menu(); + } } + + Update_Main_Menu_If_Visible(); + + Menu_Check_Buttons (); + + for (i=0; i<max_channels; i++) { + if (globals.Flash.monitor_enabled[i]) { + I2C_Check_Monitors(); + } + } + + Update_Main_Menu_If_Visible(); + + // don't check GPIB interface if a VXI interface is locked, + // or is currently handling a command + + if ((globals.VxiLocks.locked_network_server == NO_SERVER_LOCKED) && + (globals.VxiLocks.command_in_progress == FALSE)) { + + // tell VXI servers that the 4882 subsystem is busy + globals.VxiLocks.command_in_progress = TRUE; + + GPIB_check_for_device_clear_signal(); + + if (GPIB_check_for_messages(globals.Registers.gpib_input_buffer)) { + if (GPIB_handle_new_input(globals.Registers.gpib_input_buffer)) { + Parser_main(globals.Registers.gpib_input_buffer, 0, GPIB_and_VXI_start_query_response, NULL); + } + } + + // send response if appropriate + GPIB_finish_query_response(); + + GPIB_check_for_device_clear_signal(); + + // tell VXI servers that the 4882 subsystem is available again + globals.VxiLocks.command_in_progress = FALSE; + } + + Update_Main_Menu_If_Visible(); } - GPIB_check_for_device_clear_signal(); return TRUE; } |